mod_recorder.cpp 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473
  1. #include "stdafx.h"
  2. #include "SpBase.h"
  3. #include "SpIni.h"
  4. #include "libwmvrecord.h"
  5. #include "../../Other/rvcmediacommon/rvc_media_common.h"
  6. #include "fileutil.h"
  7. #include "array.h"
  8. #include <memutil.h>
  9. #include <algorithm>
  10. #include "mod_customeraware/Event.h"
  11. #include "mod_facetracking/sysvar.h"
  12. #include <assert.h>
  13. #include "EventCode.h"
  14. extern "C"
  15. {
  16. #include <libavutil/avutil.h>
  17. }
  18. #define LOG_EVT_UI_RETURNMENU 0x30B00006 //退出到主菜单
  19. #define LOG_EVT_RECORDFAILED 0x31200001 //录像失败
  20. static void logCallbacks(void* ptr, int level, const char* fmt, va_list list)
  21. {
  22. int n = _vscprintf(fmt, list);
  23. if (n >= MAX_PATH) {
  24. char* buf = (char*)malloc((size_t)(n + 1));
  25. vsnprintf(buf, n + 1, fmt, list);
  26. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("%s", buf);
  27. free(buf);
  28. }
  29. else {
  30. char strlog[MAX_PATH] = { 0 };
  31. vsnprintf(strlog, MAX_PATH, fmt, list);
  32. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("%s", strlog);
  33. }
  34. }
  35. class CRecorderEntity : public CEntityBase, public CWmvHostApi, public ILogListener,public ISysVarListener
  36. {
  37. public:
  38. CRecorderEntity(): m_bStarted(FALSE), m_pRecorder(NULL) {}
  39. virtual ~CRecorderEntity() {}
  40. virtual const char *GetEntityName() const { return "Recorder"; }
  41. virtual void OnPreStart(CAutoArray<CSimpleStringA> strArgs,CSmartPointer<ITransactionContext> pTransactionContext)
  42. {
  43. ErrorCodeEnum Error = __OnStart(Error_Succeed);
  44. pTransactionContext->SendAnswer(Error);
  45. }
  46. virtual void OnPreClose(EntityCloseCauseEnum eCloseCause,CSmartPointer<ITransactionContext> pTransactionContext)
  47. {
  48. ErrorCodeEnum Error = __OnClose(Error_Succeed);
  49. pTransactionContext->SendAnswer(Error);
  50. }
  51. BOOL InitRecorder()
  52. {
  53. BOOL bRet = FALSE;
  54. if ((ePadtype == m_eDeviceType) || (eMobilePadType == m_eDeviceType) || (eDesk2SType == m_eDeviceType))
  55. {
  56. //pad 版增加远端视频队列
  57. m_pRecorder = new Clibwmvrecord(&bRet, this, REC_COMMON_AUDIO_SHM_QUEUE,
  58. REC_COMMON_VIDEO_ENV_SHM_RTP_QUEUE, NULL);
  59. }
  60. else
  61. {
  62. // == 2
  63. m_pRecorder = new Clibwmvrecord(&bRet, this, REC_COMMON_AUDIO_SHM_QUEUE,
  64. REC_COMMON_VIDEO_ENV_SHM_RTP_QUEUE, REC_COMMON_VIDEO_OPT_SHM_RTP_QUEUE);
  65. }
  66. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("init libwmvrecord success!");
  67. return bRet;
  68. }
  69. BOOL ReleaseRecorder()
  70. {
  71. if (m_pRecorder) {
  72. delete m_pRecorder;
  73. m_pRecorder = NULL;
  74. }
  75. }
  76. ErrorCodeEnum __OnStart(ErrorCodeEnum preOperationError)
  77. {
  78. LOG_FUNCTION();
  79. //MessageBoxA(0,0,0,0);
  80. m_eDeviceType = eStand2sType;
  81. //is Pad Version
  82. CSmartPointer<IEntityFunction> spFunction = GetFunction();
  83. CSystemStaticInfo stStaticinfo;
  84. spFunction->GetSystemStaticInfo(stStaticinfo);
  85. if (stricmp(stStaticinfo.strMachineType,"RVC.PAD")==0)
  86. {
  87. if (stricmp(stStaticinfo.strSite,"CMB.FLB")==0)
  88. {
  89. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("the type is mobile pad");
  90. m_eDeviceType = eMobilePadType;
  91. }
  92. else
  93. {
  94. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("the type is pad");
  95. m_eDeviceType = ePadtype;
  96. }
  97. }
  98. else if (stricmp(stStaticinfo.strMachineType,"RPM.Stand1S")==0)
  99. {
  100. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("the type is rpm.stand1s");
  101. m_eDeviceType = eRpm1sType;
  102. }
  103. else if (stricmp(stStaticinfo.strMachineType,"RVC.Desk2S")==0)
  104. {
  105. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("the type is Desk2S");
  106. m_eDeviceType = eDesk2SType;
  107. }
  108. else
  109. {
  110. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("the type is standard");
  111. m_eDeviceType = eStand2sType;
  112. }
  113. m_terminalNo = stStaticinfo.strTerminalID;
  114. if (preOperationError != Error_Succeed)
  115. return preOperationError;
  116. ErrorCodeEnum Error = Error_Succeed;
  117. nActiveCamera = CAMERA_TYPE_ENV;
  118. m_iCameraState = 'N';
  119. //int nCameraCount = 0;
  120. //Error = DecideCameraCount(nCameraCount);
  121. //if (Error != Error_Succeed || nCameraCount < 0 || nCameraCount > 2) {
  122. // LOG_TRACE("decide camera count failed!");
  123. // return Error;
  124. //}
  125. InitRecorder();
  126. GetFunction()->SubscribeLog(m_SubIDStartRecord, this, Log_Event, Severity_Middle, Error_IgnoreAll, EVENT_MOD_BEGIN_RECORD, NULL, false);
  127. GetFunction()->SubscribeLog(m_SubIDStopRecord, this, Log_Event, Severity_Middle, Error_IgnoreAll, EVENT_MOD_END_RECORD, NULL, false);
  128. GetFunction()->SubscribeLog(m_SubIDReturnMenu, this, Log_Event, Severity_None, Error_IgnoreAll, LOG_EVT_UI_RETURNMENU, NULL, false);
  129. GetFunction()->RegistSysVarEvent(SYSVAR_ACTIVETRACKINGCAMERA,this);
  130. GetFunction()->RegistSysVarEvent(SYSVAR_CAMERASTATE,this);
  131. CSimpleStringA strValue;
  132. GetFunction()->GetSysVar(SYSVAR_CAMERASTATE, strValue);
  133. m_iCameraState = strValue[0];
  134. if (strValue[0] == 'E')
  135. {
  136. nActiveCamera = CAMERA_TYPE_OPT;
  137. }
  138. else if (strValue[0] == 'O')
  139. {
  140. nActiveCamera = CAMERA_TYPE_ENV;
  141. }
  142. else if(strValue[0] == 'B') ///////显示贴图
  143. {
  144. nActiveCamera = CAMERA_TYPE_ERROR;
  145. }
  146. else if (strValue[0] == 'N')
  147. {
  148. nActiveCamera = CAMERA_TYPE_ENV;
  149. }
  150. Error = GetFunction()->RegistSysVarEvent("SessionID", this);
  151. if (Error != Error_Succeed)
  152. {
  153. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("register sysvar %s failed!", "SessionID");
  154. }
  155. // add by ly 2018/02/13
  156. Error = GetFunction()->GetPath("Temp", m_TempDir);
  157. if (Error != Error_Succeed) {
  158. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("get global record temp path failed!");
  159. }
  160. if (m_TempDir.GetLength() > 0 && m_TempDir[m_TempDir.GetLength()-1] != SPLIT_SLASH) {
  161. m_TempDir += SPLIT_SLASH_STR;
  162. }
  163. Error = GetFunction()->GetPath("UploadVideo", m_RecordSaveDir);
  164. if (Error != Error_Succeed) {
  165. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("get global record save path failed!");
  166. }
  167. if (m_RecordSaveDir.GetLength() > 0 && m_RecordSaveDir[m_RecordSaveDir.GetLength()-1] != SPLIT_SLASH) {
  168. m_RecordSaveDir += SPLIT_SLASH_STR;
  169. }
  170. //av_log_set_level(AV_LOG_DEBUG);
  171. //av_log_set_callback(logCallbacks);
  172. return Error;
  173. }
  174. ErrorCodeEnum __OnClose(ErrorCodeEnum preOperationError)
  175. {
  176. LOG_FUNCTION();
  177. if (preOperationError != Error_Succeed)
  178. return preOperationError;
  179. GetFunction()->UnsubscribeLog(m_SubIDStopRecord);
  180. GetFunction()->UnsubscribeLog(m_SubIDStartRecord);
  181. GetFunction()->UnsubscribeLog(m_SubIDReturnMenu);
  182. GetFunction()->UnregistSysVarEvent(SYSVAR_ACTIVETRACKINGCAMERA);
  183. GetFunction()->UnregistSysVarEvent(SYSVAR_CAMERASTATE);
  184. StopRecord();
  185. //av_log_set_callback(NULL);
  186. return Error_Succeed;
  187. }
  188. // CAviHostAPI
  189. virtual void Debug(record_loglevel elevel, const char *fmt, ...)
  190. {
  191. if (RECORD_LOG_INFO <= elevel) {
  192. va_list arg;
  193. va_start(arg, fmt);
  194. int n = _vscprintf(fmt, arg);
  195. if (n >= MAX_PATH) {
  196. char* buf = (char*)malloc((size_t)(n + 1));
  197. vsnprintf(buf, n + 1, fmt, arg);
  198. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("%s", buf);
  199. free(buf);
  200. }
  201. else {
  202. char strlog[MAX_PATH] = { 0 };
  203. vsnprintf(strlog, MAX_PATH, fmt, arg);
  204. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("%s", strlog);
  205. }
  206. va_end(arg);
  207. }
  208. }
  209. virtual void vDebug(record_loglevel elevel, const char* str, va_list list)
  210. {
  211. if (RECORD_LOG_INFO <= elevel) {
  212. int n = _vscprintf(str, list);
  213. if (n >= MAX_PATH) {
  214. char* buf = (char*)malloc((size_t)(n + 1));
  215. vsnprintf(buf, n + 1, str, list);
  216. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("%s", buf);
  217. free(buf);
  218. }
  219. else {
  220. char strlog[MAX_PATH] = { 0 };
  221. vsnprintf(strlog, MAX_PATH, str, list);
  222. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("%s", strlog);
  223. }
  224. }
  225. }
  226. // CWmpHostAPI
  227. virtual void WmpDebug(const char *fmt, ...)
  228. {
  229. va_list arg;
  230. va_start(arg, fmt);
  231. int n = _vscprintf(fmt, arg);
  232. if (n >= MAX_PATH) {
  233. char* buf = (char*)malloc((size_t)(n + 1));
  234. vsnprintf(buf, n + 1, fmt, arg);
  235. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("%s", buf);
  236. free(buf);
  237. }
  238. else {
  239. char strlog[MAX_PATH] = { 0 };
  240. vsnprintf(strlog, MAX_PATH, fmt, arg);
  241. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("%s", strlog);
  242. }
  243. va_end(arg);
  244. }
  245. virtual int GetActiveCamera()
  246. {
  247. //Debug("get camera = %d",nActiveCamera);
  248. return nActiveCamera;
  249. }
  250. virtual int GetCameraState()
  251. {
  252. return m_iCameraState;
  253. }
  254. virtual void OnRecordFailed(eRvcRecordFailedCase eCase, const char* pszMessage, bool bRecordDevFault)
  255. {
  256. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("OnRecordFailed!");
  257. if (!bRecordDevFault)
  258. {
  259. LogEvent(Severity_Middle,LOG_EVT_RECORDFAILED,"0");
  260. }
  261. else
  262. {
  263. LogEvent(Severity_Middle,LOG_EVT_RECORDFAILED,"1");
  264. }
  265. }
  266. virtual void OnRecordEntityExcption()
  267. {
  268. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("OnRecordEntityExcption!");
  269. }
  270. virtual void OnRecordFinished()
  271. {
  272. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("OnRecordFinished!");
  273. }
  274. virtual void OnLog(const CAutoArray<CUUID> &SubIDs, const CUUID nLogID,const LogTypeEnum eLogType, const SeverityLevelEnum eLevel,
  275. const DWORD dwSysError,const DWORD dwUserCode,const DWORD dwEntityInstanceID, const WORD wEntityDevelID,
  276. const CAutoArray<DWORD> &Param, const char *pszEntityName, const char *pszModuleName,const char *pszMessage, const linkContext& pLinkInfo)
  277. {
  278. if (/*(dwUserCode == EVENT_MOD_CUSTOMERAWARE_BEGIN)||*/(dwUserCode == EVENT_MOD_BEGIN_RECORD))
  279. {
  280. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("start record!");
  281. StartRecord(pszMessage);
  282. }
  283. else if (/*(dwUserCode == EVENT_MOD_CUSTOMERAWARE_END)||*/(dwUserCode == EVENT_MOD_END_RECORD))
  284. {
  285. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("stop record!");
  286. StopRecord();
  287. //ReleaseRecorder();
  288. }
  289. else if (dwUserCode == LOG_EVT_UI_RETURNMENU) // 返回主菜单
  290. {
  291. //本地录像,退回到首页关闭当前文件,重新开始录制
  292. if (m_bStarted&&m_pRecorder)
  293. {
  294. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("return menu,close video file!");
  295. m_pRecorder->CloseVideoFile();
  296. }
  297. }
  298. }
  299. private:
  300. virtual void OnSysVarEvent(const char *pszKey, const char *pszValue,const char *pszOldValue,const char *pszEntityName)
  301. {
  302. if (_stricmp(pszKey, SYSVAR_CAMERASTATE) == 0)
  303. {
  304. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("camera state from : %c to %c", pszOldValue[0], pszValue[0]);
  305. m_iCameraState = pszValue[0];
  306. if (pszValue[0] == 'E')
  307. {
  308. nActiveCamera = CAMERA_TYPE_OPT;
  309. }
  310. else if (pszValue[0] == 'O')
  311. {
  312. nActiveCamera = CAMERA_TYPE_ENV;
  313. }
  314. else if(pszValue[0] == 'B') ///////显示贴图
  315. {
  316. nActiveCamera = CAMERA_TYPE_ERROR;
  317. }
  318. else if (pszValue[0] == 'N')
  319. {
  320. nActiveCamera = CAMERA_TYPE_AUTO;
  321. }
  322. }
  323. else if (_stricmp(pszKey, SYSVAR_ACTIVETRACKINGCAMERA) == 0)
  324. {
  325. if (m_iCameraState == 'N')
  326. {
  327. if (pszValue[0] == 'E')
  328. {
  329. nActiveCamera = CAMERA_TYPE_ENV;
  330. }
  331. else if (pszValue[0] == 'O')
  332. {
  333. nActiveCamera = CAMERA_TYPE_OPT;
  334. }
  335. }
  336. }
  337. else if(_stricmp(pszKey,"SessionID")==0)
  338. {
  339. CSimpleStringA strSessionID;
  340. GetFunction()->GetSysVar("SessionID",strSessionID);
  341. //如果sessionid改变且不为空,切换录像文件
  342. if(_stricmp(strSessionID,"N")!=0)
  343. {
  344. if (m_bStarted)
  345. {
  346. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("Sessionid change to %s,close record and start new video file",strSessionID.GetData());
  347. m_pRecorder->ReNameVideoFile(strSessionID);
  348. }
  349. }
  350. }
  351. }
  352. virtual void OnSelfTest(EntityTestEnum eTestType,CSmartPointer<ITransactionContext> pTransactionContext)
  353. {
  354. if (Test_ShakeHand == eTestType)
  355. {
  356. pTransactionContext->SendAnswer(Error_Succeed);
  357. }
  358. }
  359. // edit by ly@2018/06/07
  360. void StartRecord(const char *wmvfilename)
  361. {
  362. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("wmvfilename = %s", wmvfilename);
  363. //Dbg("strPath = %s", (LPCSTR)m_RecordSaveDir);
  364. int fps = 5;
  365. Rvc_RecordAudioParam_t tAudioParams;
  366. tAudioParams.eRecordType = eSingleSide;
  367. tAudioParams.eOutPutType = eLowDefinition;
  368. tAudioParams.bIsNsOn = true;
  369. tAudioParams.iNsPolicy = 2;
  370. tAudioParams.iAudioOutBitRate = 8;
  371. tAudioParams.bIsTransOn = false;
  372. if (m_pRecorder->StartWmvRecord(fps, 75, &tAudioParams, NULL, FALSE, TRUE, (LPCSTR)m_RecordSaveDir, m_RecordSaveDir.GetLength(), wmvfilename, strlen(wmvfilename)))
  373. {
  374. m_bStarted = TRUE;
  375. }
  376. }
  377. // we use root.ini Video section config to decide camera count
  378. ErrorCodeEnum DecideCameraCount(int &nCount)
  379. {
  380. CSmartPointer<IEntityFunction> spFunction = GetFunction();
  381. CSmartPointer<IConfigInfo> spConfig;
  382. ErrorCodeEnum Error = spFunction->OpenConfig(Config_Root, spConfig);
  383. if (Error == Error_Succeed) {
  384. CSimpleStringA strVideoEnv;
  385. CSimpleStringA strVideoOpt;
  386. SpIniMappingTable table;
  387. nCount = 0;
  388. table.AddEntryString("Video", "EnvCamera", strVideoEnv, "$");
  389. table.AddEntryString("Video", "OptCamera", strVideoOpt, "$");
  390. Error = table.Load(spConfig);
  391. if (Error == Error_Succeed) {
  392. if (strVideoEnv.GetLength() > 1)
  393. nCount++;
  394. if (strVideoOpt.GetLength() > 1)
  395. nCount++;
  396. }
  397. }
  398. return Error;
  399. }
  400. void StopRecord()
  401. {
  402. if (m_bStarted)
  403. {
  404. m_pRecorder->StopWmvRecord();
  405. m_bStarted = FALSE;
  406. }
  407. }
  408. DeviceTypeEnum m_eDeviceType;
  409. int nActiveCamera;
  410. int m_iCameraState;
  411. CUUID m_SubIDStartRecord;
  412. CUUID m_SubIDStopRecord;
  413. CUUID m_SubIDReturnMenu;
  414. BOOL m_bStarted;
  415. Clibwmvrecord *m_pRecorder;
  416. CSimpleStringA m_terminalNo; // 设备终端号 add by ly 20180213
  417. CSimpleStringA m_TempDir; // 录像临时目录 add by ly 20180213
  418. CSimpleStringA m_RecordSaveDir; // 录像上传目录 add by ly 20180213
  419. };
  420. SP_BEGIN_ENTITY_MAP()
  421. SP_ENTITY(CRecorderEntity)
  422. SP_END_ENTITY_MAP()