video_session.cpp 56 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942
  1. #include "stdafx.h"
  2. #include "SpBase.h"
  3. #include "video_session.h"
  4. #include "videoframework.h"
  5. #include "memutil.h"
  6. #include "libvideoqueue.h"
  7. #include "rvc_media_common.h"
  8. #include "common_video/videocommon.h"
  9. #include "videoutil.h"
  10. #include "videortp.h"
  11. #include "videoclock.h"
  12. #include "fileutil.h"
  13. #include "Event.h"
  14. #ifdef RVC_OS_WIN
  15. #include "videoplayer.h"
  16. #include "videocap.h"
  17. #include <ipp.h>
  18. #include <io.h>
  19. #include <DbgHelp.h>
  20. #else
  21. #include "ivideorenderinterface.h"
  22. #include "ivideocaptureinterface.h"
  23. #include <signal.h>
  24. #include <semaphore.h>
  25. #include <time.h>
  26. #endif // RVC_OS_WIN
  27. #include "cv.h"
  28. #include "highgui.h"
  29. #include "y2k_time.h"
  30. #define av_always_inline __inline
  31. #define inline __inline
  32. #ifndef INT64_C
  33. #define INT64_C(c) (c##LL)
  34. #define UINT64_C(c) (c##UL)
  35. #endif
  36. #include <stdint.h>
  37. extern "C"
  38. {
  39. #include <libavutil/avutil.h>
  40. #include <libavcodec/avcodec.h>
  41. #include <libswscale/swscale.h>
  42. }
  43. #include "video_common/ffmpeg_api_cpp_adapter.h"
  44. #define WNDCLS_NAME "sipmedia_video"
  45. #define MAX_PATH_SIZE 256
  46. #ifndef RVC_DBRECORD_VIDEO_BASE
  47. #define RVC_DBRECORD_VIDEO_BASE 1000
  48. #endif // !RVC_DBRECORD_VIDEO_BASE
  49. struct video_session_t
  50. {
  51. video_session_conf_t conf;
  52. Clibvideoqueue *video_shm_q_env;// env rtp queue
  53. Clibvideoqueue *video_shm_q_opt;// opt rtp queue
  54. Clibvideoqueue *video_shm_q_preview; // preview queue
  55. Clibvideoqueue *video_shm_q_remote; // preview queue
  56. videoq_frame *video_error;
  57. videortp_t *rtp;
  58. videoclock_t local_clock;
  59. struct SwsContext *local_encode_sws_ctx_env;
  60. struct SwsContext *local_encode_sws_ctx_opt;
  61. IplImage*personimage;
  62. IplImage*personmask;
  63. IplImage*recordareaimage;
  64. IplImage*recordareamask;
  65. int irecv_frameid;
  66. #ifdef RVC_OS_WIN
  67. videoplayer_t* local_player;
  68. videoplayer_t* remote_player;
  69. HANDLE ui_thread;
  70. HANDLE ui_event;
  71. HWND local_hwnd; // preview window
  72. HWND remote_hwnd; // remote window
  73. picture_record_t* pic_record;
  74. #endif // RVC_OS_WIN
  75. bool bvideorecved;
  76. volatile bool blocalrender;
  77. volatile bool bremoterender;
  78. bool bcamera_error_posted;
  79. };
  80. static void __dbg(void *user_data, const char *fmt, va_list arg)
  81. {
  82. int n = vsnprintf(NULL, 0, fmt, arg);
  83. if (n >= MAX_PATH) {
  84. char* buf = (char*)malloc((size_t)(n + 1));
  85. vsnprintf(buf, n + 1, fmt, arg);
  86. DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("%s", buf);
  87. free(buf);
  88. }
  89. else {
  90. char strlog[MAX_PATH] = { 0 };
  91. vsnprintf(strlog, MAX_PATH, fmt, arg);
  92. DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("%s", strlog);
  93. }
  94. }
  95. static void __logevent(void* user_data, int itype, const char* strmessage)
  96. {
  97. if (0 == itype) {
  98. LogWarn(Severity_Low, Error_Debug, EVENT_MOD_SIP_VIDEO_RTP_CREATE, strmessage);
  99. }
  100. else {
  101. LogWarn(Severity_Low, Error_Debug, EVENT_MOD_SIP_VIDEO_RTP_DESTROY, strmessage);
  102. }
  103. }
  104. static bool __camera_error_event(bool bhaspost, int icameraid)
  105. {
  106. bool bret = false;
  107. if (false == bhaspost){
  108. if (0 == icameraid){
  109. LogWarn(Severity_Middle, Error_Debug, ERROR_MOD_SIP_GET_ENV_VIDEO_FAILED, "get video from env queue failed!");
  110. }
  111. else{
  112. LogWarn(Severity_Middle, Error_Debug, ERROR_MOD_SIP_GET_OPT_VIDEO_FAILED, "get video from opt queue failed!");
  113. }
  114. LogEvent(Severity_Middle, EVENT_MOD_SIP_GET_VIDEO_FAILED, "connected and get video failed!");
  115. DbgWithLink(LOG_LEVEL_ERROR, LOG_TYPE_SYSTEM).setResultCode("RTA3119")("接通坐席后本地视频回显异常");
  116. bret = true;
  117. }
  118. return bret;
  119. }
  120. static int translate_image_resolution(video_frame** dstframe,const int iwidth, const int iheight, const video_frame* psrcframe)
  121. {
  122. int i = -1;
  123. if (iwidth == psrcframe->width && iheight == psrcframe->height){
  124. return i;
  125. }
  126. video_frame* pframe = video_frame_new(iwidth, iheight,VIDEO_FORMAT_RGB24);
  127. video_frame_fill_black(pframe);
  128. SwsContext* sws = sws_getCachedContext(NULL, psrcframe->width, psrcframe->height,
  129. PIX_FMT_BGR24,
  130. iwidth,
  131. iheight,
  132. PIX_FMT_BGR24,
  133. SWS_LANCZOS,
  134. NULL,
  135. NULL,
  136. NULL);
  137. sws_scale(sws, psrcframe->data, psrcframe->linesize, 0, psrcframe->height, pframe->data, pframe->linesize);
  138. sws_freeContext(sws);
  139. *dstframe = pframe;
  140. i = 0;
  141. return i;
  142. }
  143. static int calc_capture_mode(int width, int height, int *mode)
  144. {
  145. const struct {
  146. int mode;
  147. int width;
  148. int height;
  149. } modes [] = {
  150. {VIDEOCAP_FRAME_SQCIF, VIDEOCAP_SQCIF_WIDTH, VIDEOCAP_SQCIF_HEIGHT},
  151. {VIDEOCAP_FRAME_QQVGA, VIDEOCAP_QQVGA_WIDTH, VIDEOCAP_QQVGA_HEIGHT},
  152. {VIDEOCAP_FRAME_QCIF, VIDEOCAP_QCIF_WIDTH, VIDEOCAP_QCIF_HEIGHT},
  153. {VIDEOCAP_FRAME_QVGA, VIDEOCAP_QVGA_WIDTH, VIDEOCAP_QVGA_HEIGHT},
  154. {VIDEOCAP_FRAME_CIF, VIDEOCAP_CIF_WIDTH, VIDEOCAP_CIF_HEIGHT},
  155. {VIDEOCAP_FRAME_VGA, VIDEOCAP_VGA_WIDTH, VIDEOCAP_VGA_HEIGHT},
  156. {VIDEOCAP_FRAME_4CIF, VIDEOCAP_4CIF_WIDTH, VIDEOCAP_4CIF_HEIGHT},
  157. {VIDEOCAP_FRAME_SVGA, VIDEOCAP_SVGA_WIDTH, VIDEOCAP_SVGA_HEIGHT},
  158. {VIDEOCAP_FRAME_NHD, VIDEOCAP_NHD_WIDTH, VIDEOCAP_NHD_HEIGHT},
  159. {VIDEOCAP_FRAME_SXGA, VIDEOCAP_SXGA_WIDTH, VIDEOCAP_SXGA_HEIGHT},
  160. {VIDEOCAP_FRAME_720P, VIDEOCAP_720P_WIDTH, VIDEOCAP_720P_HEIGHT},
  161. {VIDEOCAP_FRAME_1080P, VIDEOCAP_1080P_WIDTH, VIDEOCAP_1080P_HEIGHT},
  162. };
  163. int i;
  164. for (i = 0; i < array_size(modes); ++i) {
  165. if (modes[i].width == width && modes[i].height == height) {
  166. *mode = modes[i].mode;
  167. return 0;
  168. }
  169. }
  170. return Error_NotExist;
  171. }
  172. #ifdef RVC_OS_WIN
  173. static void __delete_frame(videoplayer_t *player, void *user_data, video_frame *frame)
  174. {
  175. video_frame_delete(frame);
  176. }
  177. #endif
  178. static int video_shm_enqueue(Clibvideoqueue *shm_queue, video_frame *frame, int flags, int iframeid)
  179. {
  180. videoq_frame tmp_frm;
  181. tmp_frm.data = frame->data[0];
  182. tmp_frm.framesize = frame->width * frame->height * 3;
  183. tmp_frm.format = VIDEOQ_FORMAT_RGB24;
  184. tmp_frm.width = frame->width;
  185. tmp_frm.height = frame->height;
  186. tmp_frm.iframeid = iframeid;
  187. unsigned int nowtime = y2k_time_now();
  188. if (!shm_queue->InsertVideo(&tmp_frm, flags,nowtime))
  189. {
  190. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("caution: shm_queue video insert shm video failed!");
  191. return Error_Unexpect;
  192. }
  193. else
  194. {
  195. return Error_Succeed;
  196. }
  197. }
  198. static inline Clibvideoqueue *get_active_videoqueue(video_session_t *session)
  199. {
  200. int agent_option = *session->conf.ref_camera_switch;
  201. int facetracking_option = *session->conf.ref_active_camera;
  202. int camera_state = *session->conf.ref_camera_state;
  203. Clibvideoqueue *active = NULL;
  204. if (agent_option == CAMERA_TYPE_ENV)
  205. {
  206. if((camera_state!=CAMERA_TYPE_ENV)&&(camera_state!=CAMERA_TYPE_AUTO))
  207. {
  208. active = NULL;
  209. }
  210. else
  211. {
  212. active = session->video_shm_q_env;
  213. }
  214. }
  215. else if (agent_option == CAMERA_TYPE_OPT)
  216. {
  217. if((camera_state!=CAMERA_TYPE_OPT)&&(camera_state!=CAMERA_TYPE_AUTO))
  218. {
  219. active = NULL;
  220. }
  221. else
  222. {
  223. active = session->video_shm_q_opt;
  224. }
  225. }
  226. else if(agent_option == CAMERA_TYPE_ERROR)
  227. {
  228. active = NULL;
  229. }
  230. else
  231. { // auto
  232. if (camera_state == CAMERA_TYPE_AUTO)
  233. {
  234. if (facetracking_option == CAMERA_TYPE_ENV)
  235. {
  236. active = session->video_shm_q_env;
  237. }
  238. else
  239. { // opt
  240. active = session->video_shm_q_opt;
  241. }
  242. }
  243. else if (camera_state == CAMERA_TYPE_ENV)
  244. {
  245. active = session->video_shm_q_env;
  246. }
  247. else if (camera_state == CAMERA_TYPE_OPT)
  248. {
  249. active = session->video_shm_q_opt;
  250. }
  251. else if (camera_state == CAMERA_TYPE_ERROR)
  252. {
  253. active = NULL;
  254. }
  255. }
  256. return active;
  257. }
  258. static void local_get_frame(void *user_data, video_frame *frame)
  259. {
  260. video_session_t *session = (video_session_t*)user_data;
  261. Clibvideoqueue *q = get_active_videoqueue(session);
  262. if (q)
  263. {
  264. videoq_frame frm;
  265. frm.data = frame->data[0];
  266. if (q->GetVideo(&frm, 0))
  267. {
  268. //video_frame_fill_black(frame);
  269. frame->width = frm.width;
  270. frame->height = frm.height;
  271. frame->linesize[0] = frm.width * 3;
  272. }
  273. }
  274. else
  275. {
  276. //video_frame_fill_black(frame);
  277. //贴图
  278. DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("get active cam is null, load error img.");
  279. if (session->video_error != NULL)
  280. {
  281. frame->width = session->video_error->width;
  282. frame->height = session->video_error->height;
  283. frame->linesize[0] = session->video_error->width * 3;
  284. memcpy(frame->data[0],session->video_error->data,frame->width*frame->height*3);
  285. }
  286. else
  287. {
  288. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("video error img is null");
  289. }
  290. }
  291. }
  292. static void local_put_frame(void *user_data, video_frame *frame)
  293. {
  294. video_session_t *session = (video_session_t*)user_data;
  295. video_frame *tmp_frame_encode = NULL;
  296. // send out
  297. {
  298. tmp_frame_encode = video_frame_new(REC_COMMON_VIDEO_RTP_WIDTH, REC_COMMON_VIDEO_RTP_HEIGHT, VIDEO_FORMAT_I420);
  299. video_frame_fill_black(tmp_frame_encode);
  300. if (frame->width == REC_COMMON_VIDEO_RTP_ENV_WIDTH && frame->height == REC_COMMON_VIDEO_RTP_ENV_HEIGHT) { // env
  301. int offset = (REC_COMMON_VIDEO_RTP_HEIGHT - REC_COMMON_VIDEO_RTP_ENV_HEIGHT) / 2;
  302. unsigned char *dst_data[4] = {tmp_frame_encode->data[0], tmp_frame_encode->data[1], tmp_frame_encode->data[2], NULL};
  303. dst_data[0] += offset * tmp_frame_encode->linesize[0];
  304. dst_data[1] += offset / 2 * tmp_frame_encode->linesize[1];
  305. dst_data[2] += offset / 2 * tmp_frame_encode->linesize[2];
  306. sws_scale(session->local_encode_sws_ctx_env, frame->data, frame->linesize, 0, frame->height, dst_data, tmp_frame_encode->linesize);
  307. } else if (frame->width == REC_COMMON_VIDEO_RTP_OPT_WIDTH && frame->height == REC_COMMON_VIDEO_RTP_OPT_HEIGHT) { // opt
  308. video_frame tt;
  309. video_frame_alloc(REC_COMMON_VIDEO_RTP_WIDTH, REC_COMMON_VIDEO_RTP_HEIGHT, VIDEO_FORMAT_RGB24, &tt);
  310. video_frame_fill_black(&tt);
  311. {
  312. int offset = (REC_COMMON_VIDEO_RTP_WIDTH - REC_COMMON_VIDEO_RTP_OPT_WIDTH) / 2;
  313. unsigned char *dst_data[4] = {tt.data[0], 0, 0, 0};
  314. dst_data[0] += offset * 3;
  315. #ifdef RVC_OS_WIN
  316. IppiSize size;
  317. size.width = frame->width;
  318. size.height = frame->height;
  319. ippiCopy_8u_C3R(frame->data[0], frame->linesize[0], tt.data[0] + offset * 3, tt.linesize[0], size);
  320. #else
  321. for (int i = 0; i < frame->height; i++){
  322. memcpy(dst_data[0] + i*tt.linesize[0] , frame->data[0] + i*frame->width*3, frame->width*3);
  323. }
  324. #endif // RVC_OS_WIN
  325. }
  326. sws_scale(session->local_encode_sws_ctx_opt, tt.data, tt.linesize, 0, tt.height, tmp_frame_encode->data, tmp_frame_encode->linesize);
  327. video_frame_free(&tt);
  328. }
  329. if (session->conf.local_pt == REC_COMMON_VIDEO_PT){
  330. videortp_send_frame(session->rtp, tmp_frame_encode);
  331. }
  332. else{
  333. videortp_send_yuvframe(session->rtp, tmp_frame_encode);
  334. }
  335. }
  336. if (tmp_frame_encode) {
  337. video_frame_delete(tmp_frame_encode);
  338. }
  339. }
  340. static int on_rx_frame(video_frame *frame, void *user_data)
  341. {
  342. video_session_t *session = (video_session_t *)user_data;
  343. session->irecv_frameid++;
  344. if (DOUBLERECORD_CALLTYPE == session->conf.nCallType) {
  345. if (false == session->bremoterender) {
  346. session->conf.video_render_cb.on_stop_remote_video_render(session->conf.video_render_cb.user_data);
  347. }
  348. if (eStand2sType == session->conf.eDeviceType || eStand1SPlusType == session->conf.eDeviceType) {
  349. //大机对远端视频进行缩放匹配
  350. video_frame* recordframe = NULL;
  351. if (0 == translate_image_resolution(&recordframe, REC_COMMON_VIDEO_SNAPSHOT_PREVIEW_WIDTH, REC_COMMON_VIDEO_SNAPSHOT_PREVIEW_HEIGHT, frame)) {
  352. int rc = video_shm_enqueue(session->video_shm_q_remote, recordframe, VIDEOQUEUE_FLAG_VERTICAL_FLIP, session->irecv_frameid);
  353. if (rc != Error_Succeed) {
  354. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("eStand2sType record call mod insert remote video to queue failed.");
  355. }
  356. //else {
  357. // DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("%s:%d video frame (session->irecv_frameid = %d) video_shm_enqueue success.", __FUNCTION__, __LINE__, session->irecv_frameid);
  358. //}
  359. video_frame_delete(recordframe);
  360. recordframe = NULL;
  361. }
  362. }
  363. else {
  364. int rc = video_shm_enqueue(session->video_shm_q_remote, frame, VIDEOQUEUE_FLAG_VERTICAL_FLIP, session->irecv_frameid);
  365. if (rc != Error_Succeed) {
  366. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("not eStand2sType record call mod insert remote video to queue.");
  367. }
  368. }
  369. }
  370. int used = 0;
  371. #ifdef RVC_OS_WIN
  372. if (session->remote_player)
  373. {
  374. int rc = videoplayer_queue_frame(session->remote_player, frame, &__delete_frame, NULL);
  375. if (rc == 0) {
  376. used = 1;
  377. }
  378. }
  379. #else
  380. session->conf.video_render_cb.on_remote_video_render(frame, session->conf.video_render_cb.user_data);
  381. used = 1;
  382. if (false == session->bremoterender) {
  383. LogWarn(Severity_Low, Error_Debug, EVENT_MOD_SIP_REMOTE_VIDEO_RENDER_STARTED, "start remote video render.");
  384. session->bremoterender = true;
  385. }
  386. #endif
  387. return used;
  388. }
  389. static void on_rx_udp(const char* buf, int size, void* user_data)
  390. {
  391. video_session_t* session = (video_session_t*)user_data;
  392. if (false == session->bvideorecved) {
  393. //char strmsg[MAX_PATH] = { 0 };
  394. //snprintf(strmsg, MAX_PATH, "received first video packet, and packet size is %d.", size);
  395. //LogWarn(Severity_Low, Error_Debug, EVENT_MOD_SIP_VIDEO_STREAM_RECEIVED, strmsg);
  396. session->bvideorecved = true;
  397. }
  398. }
  399. #ifdef RVC_OS_WIN
  400. int GetCurrentRunPath(char* pPath)
  401. {
  402. char* pBuf = new char[MAX_PATH_SIZE];
  403. if (pBuf == NULL)
  404. return -1;
  405. ZeroMemory(pBuf, MAX_PATH_SIZE);
  406. GetModuleFileName(NULL, pBuf, MAX_PATH_SIZE);
  407. int len = strnlen_s(pBuf, MAX_PATH_SIZE);
  408. if (len <= 0)
  409. {
  410. delete[]pBuf;
  411. return -2;
  412. }
  413. char* pch;
  414. pch = strstr(pBuf, "bin");
  415. if (pch == NULL)
  416. return -3;
  417. int lenDel = strnlen_s(pch, MAX_PATH_SIZE);
  418. if (len <= 0)
  419. {
  420. delete[]pBuf;
  421. return -3;
  422. }
  423. strncpy_s(pPath, MAX_PATH_SIZE, pBuf, len - lenDel);
  424. delete[]pBuf;
  425. return strnlen_s(pPath, MAX_PATH_SIZE);
  426. }
  427. //远端视频窗口状态回调
  428. static int on_remoteWinstate(videoplayer_t *player, void *user_data, video_frame **frame)
  429. {
  430. video_session_t *session = (video_session_t*)user_data;
  431. return *session->conf.ref_window_state ;
  432. }
  433. //本地回显回调
  434. static int on_pull(videoplayer_t *player, void *user_data, video_frame **frame)
  435. {
  436. video_session_t *session = (video_session_t*)user_data;
  437. video_frame *tmp_frame_preview;
  438. //DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("ref_active_img %d,ref_Is_ActiveInspect %d,ref_camera_switch %d",*session->conf.ref_active_img,*session->conf.ref_Is_ActiveInspect,*session->conf.ref_camera_switch);
  439. if((session->conf.ref_active_img == NULL)&&(session->conf.ref_Is_ActiveInspect == NULL))
  440. {
  441. tmp_frame_preview = video_frame_new(REC_COMMON_VIDEO_PREVIEW_WIDTH, REC_COMMON_VIDEO_PREVIEW_HEIGHT, VIDEO_FORMAT_RGB24);
  442. videoq_frame frm;
  443. frm.data = tmp_frame_preview->data[0];
  444. BOOL result = session->video_shm_q_preview->GetVideo(&frm, VIDEOQUEUE_FLAG_HORIZONTAL_FLIP);
  445. //人形框融合处理
  446. if (result&&session->personimage!=NULL&&session->personmask!=NULL&&*session->conf.ref_Is_showPersonArea==1)
  447. {
  448. IplImage*img = cvCreateImageHeader(cvSize(frm.width,frm.height),IPL_DEPTH_8U,3);
  449. img->imageData = (char*)frm.data;
  450. if (frm.width!=session->personimage->width)
  451. {
  452. IplImage*tmp = cvCreateImage(cvSize(frm.width,frm.height),IPL_DEPTH_8U,3);
  453. IplImage*tmpmask = cvCreateImage(cvSize(frm.width,frm.height),IPL_DEPTH_8U,1);
  454. cvResize(session->personimage,tmp);
  455. cvResize(session->personmask,tmpmask);
  456. cvAdd(img,tmp,img,tmpmask);
  457. cvReleaseImage(&tmp);
  458. cvReleaseImage(&tmpmask);
  459. }
  460. else
  461. {
  462. cvAdd(img,session->personimage,img,session->personmask);
  463. }
  464. cvReleaseImageHeader(&img);
  465. }
  466. }
  467. else
  468. {
  469. if (*session->conf.ref_active_img == 1)
  470. {
  471. tmp_frame_preview = video_frame_new(REC_COMMON_VIDEO_SNAPSHOT_WIDTH, REC_COMMON_VIDEO_SNAPSHOT_WIDTH, VIDEO_FORMAT_RGB24);
  472. video_frame_fill_black(tmp_frame_preview);
  473. if (session->video_error == NULL)
  474. {
  475. char strPath[MAX_PATH_SIZE] = {0};
  476. #ifdef RVC_OS_WIN
  477. GetCurrentRunPath(strPath);
  478. sprintf(strPath, "%s\\bin\\looklowerscreen.jpg", strPath);
  479. #else
  480. #endif // RVC_OS_WIN
  481. if (ExistsFile(strPath))
  482. {
  483. IplImage*img = cvLoadImage(strPath,1);
  484. if (img != NULL)
  485. {
  486. session->video_error = new videoq_frame;
  487. session->video_error->format = VIDEOQ_FORMAT_RGB24;
  488. session->video_error->framesize = img->imageSize;
  489. session->video_error->height = img->width;
  490. session->video_error->width = img->height;
  491. session->video_error->data = new unsigned char[img->imageSize];
  492. memcpy(session->video_error->data,img->imageData,img->imageSize);
  493. cvReleaseImage(&img);
  494. }
  495. }
  496. }
  497. if (session->video_error != NULL)
  498. {
  499. SwsContext*sws = sws_getContext(session->video_error->width, session->video_error->height,PIX_FMT_BGR24,
  500. REC_COMMON_VIDEO_SNAPSHOT_WIDTH,
  501. REC_COMMON_VIDEO_SNAPSHOT_WIDTH,
  502. PIX_FMT_BGR24,
  503. SWS_POINT, NULL, NULL, NULL);
  504. uint8_t *src_data[4] = {(unsigned char*)session->video_error->data+(session->video_error->height-1)*session->video_error->width*3,NULL,NULL,NULL};
  505. int src_linesize[4] = {-session->video_error->width*3,0,0,0};
  506. unsigned char *dst[4] = {tmp_frame_preview->data[0],NULL,NULL,NULL};
  507. int dst_linesize[4] = {tmp_frame_preview->linesize[0],0,0,0};
  508. sws_scale(sws, src_data, src_linesize, 0, session->video_error->height, dst, dst_linesize);
  509. sws_freeContext(sws);
  510. }
  511. }
  512. else if (*session->conf.ref_Is_ActiveInspect == 1)
  513. {
  514. if((session->conf.eDeviceType == eMobilePadType)||(session->conf.eDeviceType == ePadtype)||(session->conf.eDeviceType == eDesk2SType)||(session->conf.eDeviceType == eDesk1SType)||(session->conf.eDeviceType == eDesk2SIntegratedType))
  515. {
  516. tmp_frame_preview = video_frame_new(REC_COMMON_VIDEO_PREVIEW_WIDTH, REC_COMMON_VIDEO_PREVIEW_HEIGHT, VIDEO_FORMAT_RGB24);
  517. videoq_frame frm;
  518. frm.data = tmp_frame_preview->data[0];
  519. session->video_shm_q_preview->GetVideo(&frm, VIDEOQUEUE_FLAG_HORIZONTAL_FLIP);
  520. }
  521. else
  522. {
  523. tmp_frame_preview = video_frame_new(REC_COMMON_VIDEO_SNAPSHOT_WIDTH, REC_COMMON_VIDEO_SNAPSHOT_WIDTH, VIDEO_FORMAT_RGB24);
  524. video_frame_fill_black(tmp_frame_preview);
  525. if ((*session->conf.ref_camera_switch == CAMERA_TYPE_ENV)||(*session->conf.ref_camera_switch == CAMERA_TYPE_AUTO))//显示上摄像头
  526. {
  527. if (session->video_shm_q_env)
  528. {
  529. videoq_frame frm;
  530. int offset = (REC_COMMON_VIDEO_SNAPSHOT_WIDTH - REC_COMMON_VIDEO_SNAPSHOT_HEIGHT) / 2;
  531. frm.data = tmp_frame_preview->data[0] + offset * tmp_frame_preview->linesize[0];
  532. session->video_shm_q_env->GetVideo(&frm, VIDEOQUEUE_FLAG_VERTICAL_FLIP);
  533. }
  534. }
  535. else if (*session->conf.ref_camera_switch == CAMERA_TYPE_OPT)//显示下摄像头
  536. {
  537. if (session->video_shm_q_opt)
  538. {
  539. video_frame tt = {0};
  540. int offset = (REC_COMMON_VIDEO_SNAPSHOT_WIDTH-REC_COMMON_VIDEO_SNAPSHOT_HEIGHT) / 2;
  541. tt.data[0] = tmp_frame_preview->data[0] + offset *3;
  542. tt.format = tmp_frame_preview->format;
  543. tt.linesize[0] = tmp_frame_preview->linesize[0];
  544. tt.width = REC_COMMON_VIDEO_SNAPSHOT_HEIGHT;
  545. tt.height = REC_COMMON_VIDEO_SNAPSHOT_WIDTH;
  546. session->video_shm_q_opt->GetVideo2(&tt, VIDEOQUEUE_FLAG_VERTICAL_FLIP);
  547. }
  548. }
  549. }
  550. }
  551. else
  552. {
  553. tmp_frame_preview = video_frame_new(REC_COMMON_VIDEO_PREVIEW_WIDTH, REC_COMMON_VIDEO_PREVIEW_HEIGHT, VIDEO_FORMAT_RGB24);
  554. videoq_frame frm;
  555. frm.data = tmp_frame_preview->data[0];
  556. BOOL result = session->video_shm_q_preview->GetVideo(&frm, VIDEOQUEUE_FLAG_HORIZONTAL_FLIP);
  557. //人形框融合处理
  558. if (result&&session->personimage!=NULL&&session->personmask!=NULL&&*session->conf.ref_Is_showPersonArea==1)
  559. {
  560. IplImage*img = cvCreateImageHeader(cvSize(frm.width,frm.height),IPL_DEPTH_8U,3);
  561. img->imageData = (char*)frm.data;
  562. if (frm.width!=session->personimage->width)
  563. {
  564. IplImage*tmp = cvCreateImage(cvSize(frm.width,frm.height),IPL_DEPTH_8U,3);
  565. IplImage*tmpmask = cvCreateImage(cvSize(frm.width,frm.height),IPL_DEPTH_8U,1);
  566. cvResize(session->personimage,tmp);
  567. cvResize(session->personmask,tmpmask);
  568. cvAdd(img,tmp,img,tmpmask);
  569. cvReleaseImage(&tmp);
  570. cvReleaseImage(&tmpmask);
  571. }
  572. else
  573. {
  574. cvAdd(img,session->personimage,img,session->personmask);
  575. }
  576. cvReleaseImageHeader(&img);
  577. }
  578. //双录人形位置框融合处理
  579. if (result&&session->recordareaimage!=NULL&&session->recordareamask!=NULL&&*session->conf.ref_Is_showRecordArea==1)
  580. {
  581. IplImage*img = cvCreateImageHeader(cvSize(frm.width,frm.height),IPL_DEPTH_8U,3);
  582. img->imageData = (char*)frm.data;
  583. if (frm.width!=session->recordareaimage->width)
  584. {
  585. IplImage*tmp = cvCreateImage(cvSize(frm.width,frm.height),IPL_DEPTH_8U,3);
  586. IplImage*tmpmask = cvCreateImage(cvSize(frm.width,frm.height),IPL_DEPTH_8U,1);
  587. cvResize(session->recordareaimage,tmp);
  588. cvResize(session->recordareamask,tmpmask);
  589. cvAdd(img,tmp,img,tmpmask);
  590. cvReleaseImage(&tmp);
  591. cvReleaseImage(&tmpmask);
  592. }
  593. else
  594. {
  595. cvAdd(img,session->recordareaimage,img,session->recordareamask);
  596. }
  597. cvReleaseImageHeader(&img);
  598. }
  599. }
  600. }
  601. *frame = tmp_frame_preview;
  602. //if (*session->conf.ref_window_state == 1)
  603. //{
  604. // return 1;
  605. //}
  606. //else if (*session->conf.ref_window_state == 2)
  607. //{
  608. // return 2;
  609. //}
  610. //else
  611. //{
  612. // return 0;
  613. //}
  614. return *session->conf.ref_window_state;
  615. }
  616. static void free_frame(videoplayer_t *player, void *user_data, video_frame *frame)
  617. {
  618. video_frame_delete(frame);
  619. }
  620. #else
  621. //视频窗口显示状态,0:正常大小显示,1:放大一倍显示,2:隐藏全部窗口,3:从隐藏状态恢复为全部显示,4:显示远程窗口,隐藏本地窗口, 5:缩放显示
  622. int set_video_windows(video_session_t* psession, int iwindowstate)
  623. {
  624. int iret = -1;
  625. if (NULL == psession){
  626. return iret;
  627. }
  628. return iret;
  629. }
  630. //本地回显回调
  631. static int get_local_video_frame(void* user_data, video_frame** frame)
  632. {
  633. video_session_t* session = (video_session_t*)user_data;
  634. video_frame* tmp_frame_preview = NULL;
  635. //DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("ref_active_img %d,ref_Is_ActiveInspect %d,ref_camera_switch %d",*session->conf.ref_active_img,*session->conf.ref_Is_ActiveInspect,*session->conf.ref_camera_switch);
  636. if ((session->conf.ref_active_img == NULL) && (session->conf.ref_Is_ActiveInspect == NULL))
  637. {
  638. tmp_frame_preview = video_frame_new(REC_COMMON_VIDEO_PREVIEW_WIDTH, REC_COMMON_VIDEO_PREVIEW_HEIGHT, VIDEO_FORMAT_RGB24);
  639. videoq_frame frm;
  640. frm.data = tmp_frame_preview->data[0];
  641. BOOL result = session->video_shm_q_preview->GetVideo(&frm, VIDEOQUEUE_FLAG_HORIZONTAL_FLIP);
  642. //人形框融合处理
  643. if (result){
  644. if (session->personimage != NULL && session->personmask != NULL && *session->conf.ref_Is_showPersonArea == 1)
  645. {
  646. IplImage* img = cvCreateImageHeader(cvSize(frm.width, frm.height), IPL_DEPTH_8U, 3);
  647. img->imageData = (char*)frm.data;
  648. if (frm.width != session->personimage->width){
  649. IplImage* tmp = cvCreateImage(cvSize(frm.width, frm.height), IPL_DEPTH_8U, 3);
  650. IplImage* tmpmask = cvCreateImage(cvSize(frm.width, frm.height), IPL_DEPTH_8U, 1);
  651. cvResize(session->personimage, tmp);
  652. cvResize(session->personmask, tmpmask);
  653. cvAdd(img, tmp, img, tmpmask);
  654. cvReleaseImage(&tmp);
  655. cvReleaseImage(&tmpmask);
  656. }
  657. else{
  658. cvAdd(img, session->personimage, img, session->personmask);
  659. }
  660. cvReleaseImageHeader(&img);
  661. }
  662. }
  663. else {
  664. video_frame_fill_black(tmp_frame_preview);
  665. if (__camera_error_event(session->bcamera_error_posted, 0)) {
  666. session->bcamera_error_posted = true;
  667. }
  668. }
  669. }
  670. else
  671. {
  672. if (*session->conf.ref_active_img == 1)
  673. {
  674. tmp_frame_preview = video_frame_new(REC_COMMON_VIDEO_SNAPSHOT_WIDTH, REC_COMMON_VIDEO_SNAPSHOT_WIDTH, VIDEO_FORMAT_RGB24);
  675. video_frame_fill_black(tmp_frame_preview);
  676. if (session->video_error == NULL)
  677. {
  678. char strPath[MAX_PATH_SIZE] = { 0 };
  679. snprintf(strPath, MAX_PATH_SIZE, "%s", "./bin/looklowerscreen.jpg");
  680. if (ExistsFile(strPath))
  681. {
  682. IplImage* img = cvLoadImage(strPath, 1);
  683. if (img != NULL)
  684. {
  685. session->video_error = new videoq_frame;
  686. session->video_error->format = VIDEOQ_FORMAT_RGB24;
  687. session->video_error->framesize = img->imageSize;
  688. session->video_error->height = img->width;
  689. session->video_error->width = img->height;
  690. session->video_error->data = new unsigned char[img->imageSize];
  691. memcpy(session->video_error->data, img->imageData, img->imageSize);
  692. cvReleaseImage(&img);
  693. }
  694. }
  695. }
  696. if (session->video_error != NULL)
  697. {
  698. SwsContext* sws = sws_getContext(session->video_error->width, session->video_error->height, PIX_FMT_BGR24,
  699. REC_COMMON_VIDEO_SNAPSHOT_WIDTH,
  700. REC_COMMON_VIDEO_SNAPSHOT_WIDTH,
  701. PIX_FMT_BGR24,
  702. SWS_POINT, NULL, NULL, NULL);
  703. uint8_t* src_data[4] = { (unsigned char*)session->video_error->data + (session->video_error->height - 1) * session->video_error->width * 3,NULL,NULL,NULL };
  704. int src_linesize[4] = { -session->video_error->width * 3,0,0,0 };
  705. unsigned char* dst[4] = { tmp_frame_preview->data[0],NULL,NULL,NULL };
  706. int dst_linesize[4] = { tmp_frame_preview->linesize[0],0,0,0 };
  707. sws_scale(sws, src_data, src_linesize, 0, session->video_error->height, dst, dst_linesize);
  708. sws_freeContext(sws);
  709. }
  710. }
  711. else if (*session->conf.ref_Is_ActiveInspect == 1)
  712. {
  713. tmp_frame_preview = video_frame_new(REC_COMMON_VIDEO_SNAPSHOT_WIDTH, REC_COMMON_VIDEO_SNAPSHOT_WIDTH, VIDEO_FORMAT_RGB24);
  714. video_frame_fill_black(tmp_frame_preview);
  715. if ((*session->conf.ref_camera_switch == CAMERA_TYPE_ENV) || (*session->conf.ref_camera_switch == CAMERA_TYPE_AUTO))//显示上摄像头
  716. {
  717. if (session->video_shm_q_env)
  718. {
  719. videoq_frame frm;
  720. int offset = (REC_COMMON_VIDEO_SNAPSHOT_WIDTH - REC_COMMON_VIDEO_SNAPSHOT_HEIGHT) / 2;
  721. frm.data = tmp_frame_preview->data[0] + offset * tmp_frame_preview->linesize[0];
  722. if (FALSE == session->video_shm_q_env->GetVideo(&frm, VIDEOQUEUE_FLAG_VERTICAL_FLIP)){
  723. if (__camera_error_event(session->bcamera_error_posted, 0)) {
  724. session->bcamera_error_posted = true;
  725. }
  726. }
  727. }
  728. }
  729. else if (*session->conf.ref_camera_switch == CAMERA_TYPE_OPT)//显示下摄像头
  730. {
  731. if (session->video_shm_q_opt)
  732. {
  733. video_frame tt = { 0 };
  734. int offset = (REC_COMMON_VIDEO_SNAPSHOT_WIDTH - REC_COMMON_VIDEO_SNAPSHOT_HEIGHT) / 2;
  735. tt.data[0] = tmp_frame_preview->data[0] + offset * 3;
  736. tt.format = tmp_frame_preview->format;
  737. tt.linesize[0] = tmp_frame_preview->linesize[0];
  738. tt.width = REC_COMMON_VIDEO_SNAPSHOT_HEIGHT;
  739. tt.height = REC_COMMON_VIDEO_SNAPSHOT_WIDTH;
  740. if (FALSE == session->video_shm_q_opt->GetVideo2(&tt, VIDEOQUEUE_FLAG_VERTICAL_FLIP)) {
  741. if (__camera_error_event(session->bcamera_error_posted, 1)) {
  742. session->bcamera_error_posted = true;
  743. }
  744. }
  745. }
  746. }
  747. }
  748. else
  749. {
  750. tmp_frame_preview = video_frame_new(REC_COMMON_VIDEO_PREVIEW_WIDTH, REC_COMMON_VIDEO_PREVIEW_HEIGHT, VIDEO_FORMAT_RGB24);
  751. videoq_frame frm;
  752. frm.data = tmp_frame_preview->data[0];
  753. BOOL result = session->video_shm_q_preview->GetVideo(&frm, VIDEOQUEUE_FLAG_HORIZONTAL_FLIP);
  754. if (result){
  755. //人形框融合处理
  756. if (session->personimage != NULL && session->personmask != NULL && *session->conf.ref_Is_showPersonArea == 1)
  757. {
  758. IplImage* img = cvCreateImageHeader(cvSize(frm.width, frm.height), IPL_DEPTH_8U, 3);
  759. img->imageData = (char*)frm.data;
  760. if (frm.width != session->personimage->width)
  761. {
  762. IplImage* tmp = cvCreateImage(cvSize(frm.width, frm.height), IPL_DEPTH_8U, 3);
  763. IplImage* tmpmask = cvCreateImage(cvSize(frm.width, frm.height), IPL_DEPTH_8U, 1);
  764. cvResize(session->personimage, tmp);
  765. cvResize(session->personmask, tmpmask);
  766. cvAdd(img, tmp, img, tmpmask);
  767. cvReleaseImage(&tmp);
  768. cvReleaseImage(&tmpmask);
  769. }
  770. else
  771. {
  772. cvAdd(img, session->personimage, img, session->personmask);
  773. }
  774. cvReleaseImageHeader(&img);
  775. }
  776. //双录人形位置框融合处理
  777. if (session->recordareaimage != NULL && session->recordareamask != NULL && *session->conf.ref_Is_showRecordArea == 1)
  778. {
  779. IplImage* img = cvCreateImageHeader(cvSize(frm.width, frm.height), IPL_DEPTH_8U, 3);
  780. img->imageData = (char*)frm.data;
  781. if (frm.width != session->recordareaimage->width)
  782. {
  783. IplImage* tmp = cvCreateImage(cvSize(frm.width, frm.height), IPL_DEPTH_8U, 3);
  784. IplImage* tmpmask = cvCreateImage(cvSize(frm.width, frm.height), IPL_DEPTH_8U, 1);
  785. cvResize(session->recordareaimage, tmp);
  786. cvResize(session->recordareamask, tmpmask);
  787. cvAdd(img, tmp, img, tmpmask);
  788. cvReleaseImage(&tmp);
  789. cvReleaseImage(&tmpmask);
  790. }
  791. else
  792. {
  793. cvAdd(img, session->recordareaimage, img, session->recordareamask);
  794. }
  795. cvReleaseImageHeader(&img);
  796. }
  797. }
  798. else {
  799. video_frame_fill_black(tmp_frame_preview);
  800. if (__camera_error_event(session->bcamera_error_posted, 0)) {
  801. session->bcamera_error_posted = true;
  802. }
  803. }
  804. }
  805. }
  806. *frame = tmp_frame_preview;
  807. return *session->conf.ref_window_state;
  808. }
  809. #endif // RVC_OS_WIN
  810. static int start_video_rtpsession(video_session_t* session)
  811. {
  812. int rc = -1;
  813. videortp_config_t config = { 0 };
  814. config.fps_den = REC_COMMON_VIDEO_FPS_DEN;
  815. config.fps_num = REC_COMMON_VIDEO_FPS_NUM;
  816. config.capture_height = -1; // not use
  817. config.capture_width = -1; // not use
  818. config.dir = 3;
  819. config.tx_width = REC_COMMON_VIDEO_RTP_WIDTH;
  820. config.tx_height = REC_COMMON_VIDEO_RTP_HEIGHT;
  821. config.rx_width = session->conf.remote_video_width;
  822. config.rx_height = session->conf.remote_video_height;
  823. config.local_ip = session->conf.local_rtp_ip;
  824. config.local_pt = session->conf.local_pt;
  825. config.remote_pt = session->conf.local_pt;
  826. config.local_rtp_port = session->conf.local_rtp_port;
  827. config.mtu = session->conf.mtu;
  828. config.quant = session->conf.video_quant;
  829. config.remote_ip = session->conf.remote_rtp_ip;
  830. config.remote_rtp_port = session->conf.remote_rtp_port;
  831. config.user_data = session;
  832. config.bit_rate = session->conf.bit_rate;
  833. config.on_rx_frame = &on_rx_frame;
  834. config.on_rx_udp = &on_rx_udp;
  835. config.dbg = &__dbg;
  836. config.logevent = &__logevent;
  837. if (0 != videortp_create(&config, &session->rtp)) {
  838. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("videortp create failed!");
  839. }
  840. rc = videortp_start(session->rtp);
  841. if (rc != 0)
  842. {
  843. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("start video rtp failed!");
  844. videortp_destroy(session->rtp);
  845. session->rtp = NULL;
  846. }
  847. return rc;
  848. }
  849. static int start_local_video_clock(video_session_t* session)
  850. {
  851. int rc = -1;
  852. rc = videoclock_create(REC_COMMON_VIDEO_FPS_NUM, REC_COMMON_VIDEO_FPS_DEN,
  853. REC_COMMON_VIDEO_RTP_WIDTH, REC_COMMON_VIDEO_RTP_HEIGHT, VIDEO_FORMAT_RGB24,
  854. &local_put_frame, session, &local_get_frame, session, &session->local_clock, session->conf.ref_Up_Fps, &__dbg);
  855. if (0 == rc) {
  856. rc = videoclock_start(session->local_clock);
  857. if (rc != 0) {
  858. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("start video clock failed!");
  859. videoclock_destroy(session->local_clock);
  860. session->local_clock = NULL;
  861. }
  862. }
  863. else {
  864. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("create video clock failed!");
  865. }
  866. return rc;
  867. }
  868. static int start_video(video_session_t *session)
  869. {
  870. int rc = -1;
  871. if (session->video_shm_q_env)
  872. {
  873. session->local_encode_sws_ctx_env = sws_getContext(
  874. REC_COMMON_VIDEO_RTP_ENV_WIDTH, REC_COMMON_VIDEO_RTP_ENV_HEIGHT, PIX_FMT_BGR24,
  875. REC_COMMON_VIDEO_RTP_ENV_WIDTH, REC_COMMON_VIDEO_RTP_ENV_HEIGHT, PIX_FMT_YUV420P,
  876. SWS_POINT, NULL, NULL, NULL);
  877. if (!session->local_encode_sws_ctx_env) {
  878. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("get session->local_encode_sws_ctx_env failed.");
  879. goto on_error;
  880. }
  881. }
  882. else{
  883. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("session->video_shm_q_env is NULL.");
  884. }
  885. if (session->video_shm_q_opt)
  886. {
  887. session->local_encode_sws_ctx_opt = sws_getContext(
  888. REC_COMMON_VIDEO_RTP_WIDTH, REC_COMMON_VIDEO_RTP_HEIGHT, PIX_FMT_BGR24,
  889. REC_COMMON_VIDEO_RTP_WIDTH, REC_COMMON_VIDEO_RTP_HEIGHT, PIX_FMT_YUV420P,
  890. SWS_POINT, NULL, NULL, NULL);
  891. if (!session->local_encode_sws_ctx_opt) {
  892. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("get session->local_encode_sws_ctx_opt failed.");
  893. goto on_error;
  894. }
  895. }
  896. else{
  897. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("session->video_shm_q_opt is NULL.");
  898. }
  899. #ifdef RVC_OS_WIN
  900. if (DOUBLERECORD_CALLTYPE != session->conf.nCallType){
  901. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("create new remote video player");
  902. if (session->remote_hwnd)
  903. {
  904. if (session->conf.eDeviceType == eMobilePadType)
  905. {
  906. rc = videoplayer_create(session->remote_hwnd,
  907. 0,
  908. 0,
  909. session->conf.remote_video_view_cx,
  910. session->conf.remote_video_view_cy,
  911. REC_COMMON_VIDEO_FPS_MOBILE_AGENT,
  912. REC_COMMON_VIDEO_FPS_DEN,
  913. session->conf.remote_video_width,
  914. session->conf.remote_video_height,
  915. //*VIDEOPLAYER_FLAG_DOUBLESIZE|*/VIDEOPLAYER_FLAG_PUSH|VIDEOPLAYER_FLAG_CHECKTOP,
  916. session->conf.iremote_wind_flags,
  917. "remote",
  918. on_remoteWinstate,
  919. NULL,
  920. session,
  921. &session->remote_player);
  922. if (rc != 0)
  923. {
  924. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("create remote video player failed!");
  925. goto on_error;
  926. }
  927. else{
  928. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("create remote video player suc!");
  929. }
  930. }
  931. else if((session->conf.eDeviceType == ePadtype)||(session->conf.eDeviceType == eDesk2SType)||(session->conf.eDeviceType == eDesk1SType)||(session->conf.eDeviceType == eDesk2SIntegratedType))
  932. {
  933. rc = videoplayer_create(session->remote_hwnd,
  934. 0,
  935. 0,
  936. session->conf.remote_video_view_cx,
  937. session->conf.remote_video_view_cy,
  938. REC_COMMON_VIDEO_FPS_MOBILE,
  939. REC_COMMON_VIDEO_FPS_DEN,
  940. session->conf.remote_video_width,
  941. session->conf.remote_video_height,
  942. //*VIDEOPLAYER_FLAG_DOUBLESIZE|*/VIDEOPLAYER_FLAG_PUSH|VIDEOPLAYER_FLAG_CHECKTOP,
  943. session->conf.iremote_wind_flags,
  944. "remote",
  945. on_remoteWinstate,
  946. NULL,
  947. session,
  948. &session->remote_player);
  949. if (rc != 0) {
  950. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("create remote video player failed!");
  951. goto on_error;
  952. }
  953. else{
  954. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("create remote video player suc!");
  955. }
  956. }
  957. else if(session->conf.eDeviceType == eStand2sType)
  958. {
  959. rc = videoplayer_create(session->remote_hwnd,
  960. 0,
  961. 0,
  962. session->conf.remote_video_view_cx,
  963. session->conf.remote_video_view_cy,
  964. REC_COMMON_VIDEO_FPS_NUM,
  965. REC_COMMON_VIDEO_FPS_DEN,
  966. session->conf.remote_video_width,
  967. session->conf.remote_video_height,
  968. //*VIDEOPLAYER_FLAG_DOUBLESIZE|*/VIDEOPLAYER_FLAG_PUSH|VIDEOPLAYER_FLAG_CHECKTOP,
  969. session->conf.iremote_wind_flags,
  970. "remote",
  971. on_remoteWinstate,
  972. NULL,
  973. session,
  974. &session->remote_player);
  975. if (rc != 0)
  976. {
  977. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("create remote video player failed!");
  978. goto on_error;
  979. }
  980. else{
  981. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("create remote video player suc remote_video_width = %d,remote_video_height = %d.", session->conf.remote_video_width, session->conf.remote_video_height);
  982. }
  983. }
  984. }
  985. else
  986. {
  987. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("remote_hwnd == Null");
  988. }
  989. }
  990. else{
  991. if (NULL != pg_last_session){
  992. session->remote_player = pg_last_session->remote_player;
  993. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("double record call remote_player reuse.");
  994. }
  995. else{
  996. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("pg_last_session is NULL, and call type is %d.", session->conf.nCallType);
  997. }
  998. }
  999. BOOL bIsActiveInspect = FALSE;
  1000. if (session->conf.ref_Is_ActiveInspect != NULL){
  1001. if (*session->conf.ref_Is_ActiveInspect == 1){
  1002. bIsActiveInspect = TRUE;
  1003. }
  1004. else{
  1005. bIsActiveInspect = FALSE;
  1006. }
  1007. }
  1008. else{
  1009. bIsActiveInspect = FALSE;
  1010. }
  1011. if (DOUBLERECORD_CALLTYPE != session->conf.nCallType){
  1012. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("create new local video player");
  1013. if (session->conf.eDeviceType == eMobilePadType)
  1014. {
  1015. rc = videoplayer_create(session->local_hwnd,
  1016. 0,
  1017. 0,
  1018. session->conf.local_video_view_cx,
  1019. session->conf.local_video_view_cy,
  1020. REC_COMMON_VIDEO_FPS_MOBILE,
  1021. REC_COMMON_VIDEO_FPS_DEN,
  1022. REC_COMMON_VIDEO_PREVIEW_WIDTH,
  1023. REC_COMMON_VIDEO_PREVIEW_HEIGHT,
  1024. //*VIDEOPLAYER_FLAG_DOUBLESIZE|*/VIDEOPLAYER_FLAG_PULL|VIDEOPLAYER_FLAG_CHECKTOP,
  1025. session->conf.ilocal_wind_flags,
  1026. "local",
  1027. on_pull, free_frame, session,
  1028. &session->local_player);
  1029. if (rc != 0)
  1030. {
  1031. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("create local video player failed!");
  1032. goto on_error;
  1033. }
  1034. else{
  1035. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("create local video player suc!");
  1036. }
  1037. }
  1038. else if((session->conf.eDeviceType == ePadtype)||(session->conf.eDeviceType == eDesk2SType)||(session->conf.eDeviceType == eDesk1SType)||(session->conf.eDeviceType == eDesk2SIntegratedType))
  1039. {
  1040. rc = videoplayer_create(session->local_hwnd,
  1041. 0,
  1042. 0,
  1043. session->conf.local_video_view_cx,
  1044. session->conf.local_video_view_cy,
  1045. REC_COMMON_VIDEO_FPS_MOBILE,
  1046. REC_COMMON_VIDEO_FPS_DEN,
  1047. REC_COMMON_VIDEO_PREVIEW_WIDTH,
  1048. REC_COMMON_VIDEO_PREVIEW_HEIGHT,
  1049. //*VIDEOPLAYER_FLAG_DOUBLESIZE|*/VIDEOPLAYER_FLAG_PULL|VIDEOPLAYER_FLAG_CHECKTOP,
  1050. session->conf.ilocal_wind_flags,
  1051. "local",
  1052. on_pull, free_frame, session,
  1053. &session->local_player);
  1054. if (rc != 0)
  1055. {
  1056. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("create local video player failed!");
  1057. goto on_error;
  1058. }
  1059. else{
  1060. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("create local video player suc!");
  1061. }
  1062. }
  1063. else if(session->conf.eDeviceType == eStand2sType)
  1064. {
  1065. rc = videoplayer_create(session->local_hwnd,
  1066. 0,
  1067. 0,
  1068. session->conf.local_video_view_cx,
  1069. session->conf.local_video_view_cy,
  1070. REC_COMMON_VIDEO_FPS_NUM,
  1071. REC_COMMON_VIDEO_FPS_DEN,
  1072. bIsActiveInspect?REC_COMMON_VIDEO_SNAPSHOT_WIDTH:REC_COMMON_VIDEO_PREVIEW_WIDTH,
  1073. bIsActiveInspect?REC_COMMON_VIDEO_SNAPSHOT_WIDTH:REC_COMMON_VIDEO_PREVIEW_HEIGHT,
  1074. //*VIDEOPLAYER_FLAG_DOUBLESIZE|*/VIDEOPLAYER_FLAG_PULL|VIDEOPLAYER_FLAG_CHECKTOP,
  1075. session->conf.ilocal_wind_flags,
  1076. "local",
  1077. on_pull, free_frame, session,
  1078. &session->local_player);
  1079. if (rc != 0)
  1080. {
  1081. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("create local video player failed!");
  1082. goto on_error;
  1083. }
  1084. else{
  1085. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("create local video player suc!");
  1086. }
  1087. }
  1088. }
  1089. else{
  1090. if (NULL != pg_last_session){
  1091. session->local_player = pg_last_session->local_player;
  1092. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("double record call local player reuse.");
  1093. }
  1094. }
  1095. if (session->remote_hwnd)
  1096. {
  1097. if (0 != session->conf.remote_rtp_port)
  1098. {
  1099. if (0 != start_video_rtpsession(session)) {
  1100. goto on_error;
  1101. }
  1102. if (DOUBLERECORD_CALLTYPE == session->conf.nCallType){
  1103. if (NULL != pg_last_session){
  1104. pg_last_session->rtp = session->rtp;
  1105. }
  1106. }
  1107. if (0 != start_local_video_clock(session)) {
  1108. goto on_error;
  1109. }
  1110. }
  1111. else{
  1112. pg_last_session = session; //保存session信息
  1113. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("begin show agent static picture.");
  1114. show_remote_agnet_picture(session);
  1115. }
  1116. }
  1117. #else
  1118. rc = start_video_rtpsession(session);
  1119. if (0 != rc) {
  1120. goto on_error;
  1121. }
  1122. rc = start_local_video_clock(session);
  1123. if (0 != rc) {
  1124. goto on_error;
  1125. }
  1126. #endif // RVC_OS_WIN
  1127. on_error:
  1128. return rc;
  1129. }
  1130. static void stop_video(video_session_t *session)
  1131. {
  1132. #ifdef RVC_OS_WIN
  1133. if (session->local_clock && session->remote_hwnd)
  1134. {
  1135. videoclock_stop(session->local_clock);
  1136. videoclock_destroy(session->local_clock);
  1137. session->local_clock = NULL;
  1138. pg_remote_hwnd = NULL;
  1139. pg_local_hwnd = NULL;
  1140. }
  1141. #else
  1142. if (session->local_clock)
  1143. {
  1144. videoclock_stop(session->local_clock);
  1145. videoclock_destroy(session->local_clock);
  1146. session->local_clock = NULL;
  1147. }
  1148. #endif // RVC_OS_WIN
  1149. if (session->rtp){
  1150. videortp_stop(session->rtp);
  1151. videortp_destroy(session->rtp);
  1152. session->rtp = NULL;
  1153. }
  1154. else {
  1155. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("session->rtp == null");
  1156. }
  1157. #ifdef RVC_OS_WIN
  1158. if (session->local_player) {
  1159. videoplayer_destroy(session->local_player);
  1160. session->local_player = NULL;
  1161. }
  1162. if (session->remote_player && session->remote_hwnd)
  1163. {
  1164. videoplayer_destroy(session->remote_player);
  1165. session->remote_player = NULL;
  1166. }
  1167. #else
  1168. #endif
  1169. if (session->local_encode_sws_ctx_env) {
  1170. sws_freeContext(session->local_encode_sws_ctx_env);
  1171. session->local_encode_sws_ctx_env = NULL;
  1172. }
  1173. if (session->local_encode_sws_ctx_opt) {
  1174. sws_freeContext(session->local_encode_sws_ctx_opt);
  1175. session->local_encode_sws_ctx_opt = NULL;
  1176. }
  1177. }
  1178. #ifdef RVC_OS_WIN
  1179. static bool ReMoveOutOfScreenVideoWindow(HWND hWnd, RECT rect)
  1180. {
  1181. bool bret = false;
  1182. int iScreenWidth = GetSystemMetrics(SM_CXSCREEN);
  1183. int iScreenHight = GetSystemMetrics(SM_CYSCREEN);
  1184. int iVideoWidth = rect.right - rect.left;
  1185. int iVideoHight = rect.bottom - rect.top;
  1186. if (rect.left < 0) {
  1187. if (rect.bottom <= iScreenHight) {
  1188. MoveWindow(hWnd, 0, rect.top, iVideoWidth, iVideoHight, TRUE);
  1189. }
  1190. else {
  1191. MoveWindow(hWnd, 0, iScreenHight - iVideoHight, iVideoWidth, iVideoHight, TRUE);
  1192. }
  1193. bret = true;
  1194. }
  1195. if (rect.right > iScreenWidth) {
  1196. if (rect.bottom <= iScreenHight) {
  1197. MoveWindow(hWnd, iScreenWidth - iVideoWidth, rect.top, iVideoWidth, iVideoHight, TRUE);
  1198. }
  1199. else {
  1200. MoveWindow(hWnd, iScreenWidth - iVideoWidth, iScreenHight - iVideoHight, iVideoWidth, iVideoHight, TRUE);
  1201. }
  1202. bret = true;
  1203. }
  1204. if (rect.bottom > iScreenHight) {
  1205. if (rect.left >= 0 && rect.right <= iScreenWidth) {
  1206. MoveWindow(hWnd, rect.left, iScreenHight - iVideoHight, iVideoWidth, iVideoHight, TRUE);
  1207. bret = true;
  1208. }
  1209. }
  1210. return bret;
  1211. }
  1212. static bool ReMoveCenterOtherVideoWindow(HWND hWnd, RECT rect, RECT otherect)
  1213. {
  1214. bool bret = false;
  1215. int iVideoWidth = rect.right - rect.left;
  1216. int iVideoHight = rect.bottom - rect.top;
  1217. int iOtherVideoWidth = otherect.right - otherect.left;
  1218. int iOtherVideoHight = otherect.bottom - otherect.top;
  1219. if (iVideoWidth > iOtherVideoHight || iVideoHight > iOtherVideoHight) {
  1220. return bret;
  1221. }
  1222. if (rect.left > otherect.left + iVideoWidth && rect.right < otherect.right) {
  1223. if (rect.top > otherect.top && rect.bottom < otherect.bottom) {
  1224. if (otherect.right - rect.right <= rect.left - otherect.left) {
  1225. MoveWindow(hWnd, otherect.right - iVideoWidth, rect.top, iVideoWidth, iVideoHight, TRUE);
  1226. }
  1227. else {
  1228. MoveWindow(hWnd, otherect.left, rect.top, iVideoWidth, iVideoHight, TRUE);
  1229. }
  1230. bret = true;
  1231. }
  1232. }
  1233. if (rect.right < otherect.right - iVideoWidth && rect.left > otherect.left) {
  1234. if (rect.top > otherect.top && rect.bottom < otherect.bottom) {
  1235. if (otherect.right - rect.right <= rect.left - otherect.left) {
  1236. MoveWindow(hWnd, otherect.right - iVideoWidth, rect.top, iVideoWidth, iVideoHight, TRUE);
  1237. }
  1238. else {
  1239. MoveWindow(hWnd, otherect.left, rect.top, iVideoWidth, iVideoHight, TRUE);
  1240. }
  1241. bret = true;
  1242. }
  1243. }
  1244. return bret;
  1245. }
  1246. static bool ReMoveVideoWindow(HWND hWnd, RECT rect, RECT otherect)
  1247. {
  1248. bool bret = false;
  1249. bret = ReMoveOutOfScreenVideoWindow(hWnd, rect);
  1250. bret = ReMoveCenterOtherVideoWindow(hWnd, rect, otherect);
  1251. return bret;
  1252. }
  1253. static int HandleVideoMoveEvent(int iMessageType, HWND hWnd, video_session_t* pSession)
  1254. {
  1255. int iRet = -1;
  1256. if (NULL == pSession || NULL == hWnd) {
  1257. return iRet;
  1258. }
  1259. HWND hOtherWnd = NULL;
  1260. //本地和远端标识 1为本地,2为远端
  1261. int iVideoType = 2;
  1262. if (hWnd == pSession->local_hwnd) {
  1263. iVideoType = 1;
  1264. hOtherWnd = pSession->remote_hwnd;
  1265. }
  1266. else {
  1267. hOtherWnd = pSession->local_hwnd;
  1268. }
  1269. if (NULL == hOtherWnd) {
  1270. return iRet;
  1271. }
  1272. bool bMoved = false;
  1273. RECT rect;
  1274. GetWindowRect(hWnd, &rect);
  1275. RECT otherect;
  1276. GetWindowRect(hOtherWnd, &otherect);
  1277. bMoved = ReMoveVideoWindow(hWnd, rect, otherect);
  1278. if (bMoved) {
  1279. GetWindowRect(hWnd, &rect);
  1280. }
  1281. if (NULL != pSession->conf.video_echo_cb && NULL != pSession->conf.video_echo_cb->on_video_box_move) {
  1282. pSession->conf.video_echo_cb->on_video_box_move(iMessageType, iVideoType, rect.left, rect.bottom, pSession->conf.video_echo_cb->user_data);
  1283. iRet = 0;
  1284. }
  1285. return iRet;
  1286. }
  1287. #else
  1288. #endif // RVC_OS_WIN
  1289. #ifdef RVC_OS_WIN
  1290. static LRESULT WINAPI WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
  1291. {
  1292. video_session_t* session = (video_session_t*)GetWindowLongPtrA(hWnd, GWLP_USERDATA);
  1293. switch (msg) {
  1294. case WM_DESTROY:
  1295. if (session->local_hwnd == hWnd) {
  1296. session->local_hwnd = 0;
  1297. }
  1298. else if (session->remote_hwnd == hWnd) {
  1299. session->remote_hwnd = 0;
  1300. }
  1301. if (session->local_hwnd == 0 && session->remote_hwnd == 0) {
  1302. PostQuitMessage(0);
  1303. }
  1304. return 0;
  1305. case WM_NCHITTEST:
  1306. if (((session->local_hwnd == hWnd) && (0 != session->conf.local_move)) || ((session->remote_hwnd == hWnd) && (0 != session->conf.remote_move))) {
  1307. return HTCAPTION;
  1308. }
  1309. else {
  1310. break;
  1311. }
  1312. case WM_ACTIVATE:
  1313. case WM_TOUCH:
  1314. case WM_GESTURE:
  1315. ReleaseCapture();
  1316. return 0;
  1317. #if 1
  1318. case WM_WINDOWPOSCHANGED:
  1319. {
  1320. LPWINDOWPOS pPos = (LPWINDOWPOS)lParam;
  1321. if (pPos->hwndInsertAfter != HWND_TOPMOST && pPos->hwndInsertAfter != HWND_TOP) {
  1322. //BringWindowToTop(hWnd);
  1323. SetWindowPos(hWnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
  1324. }
  1325. else {
  1326. return DefWindowProc(hWnd, msg, wParam, lParam);
  1327. }
  1328. }
  1329. return 0;
  1330. //return DefWindowProc(hWnd, msg, wParam, lParam);
  1331. #endif
  1332. case WM_MBUTTONDOWN:
  1333. case WM_MBUTTONUP:
  1334. case WM_MBUTTONDBLCLK:
  1335. case WM_LBUTTONDBLCLK:
  1336. case WM_LBUTTONDOWN:
  1337. case WM_LBUTTONUP:
  1338. if (session) {
  1339. if (session->local_hwnd) {
  1340. //ReleaseCapture();
  1341. }
  1342. }
  1343. return 0;
  1344. case WM_CLOSE:
  1345. stop_video(session);
  1346. //SetEvent(session->ui_thread);
  1347. DestroyWindow(session->local_hwnd);
  1348. DestroyWindow(session->remote_hwnd);
  1349. return 0;
  1350. case WM_MOVE:
  1351. break;
  1352. case WM_ENTERSIZEMOVE:
  1353. {
  1354. HandleVideoMoveEvent(0, hWnd, session);
  1355. }
  1356. break;
  1357. case WM_EXITSIZEMOVE:
  1358. {
  1359. HandleVideoMoveEvent(1, hWnd, session);
  1360. }
  1361. break;
  1362. default:
  1363. return DefWindowProc(hWnd, msg, wParam, lParam);
  1364. }
  1365. return 0;
  1366. }
  1367. #endif //
  1368. #ifdef RVC_OS_WIN
  1369. static unsigned int __stdcall ui_proc(void *arg)
  1370. {
  1371. video_session_t *session = (video_session_t*)arg;
  1372. WNDCLASSA wc = {0};
  1373. ATOM a = 0;
  1374. HWND hWnd = NULL;
  1375. MSG msg;
  1376. HINSTANCE hInst = ModuleBase::GetModuleBase()->GetInstance();
  1377. bool breuse_local_wnd = false;
  1378. bool breuse_remote_wnd = false;
  1379. DWORD dLocal_style = WS_EX_TOOLWINDOW | WS_EX_TOPMOST | WS_EX_NOACTIVATE;
  1380. DWORD dRemote_style = WS_EX_TOOLWINDOW | WS_EX_TOPMOST | WS_EX_NOACTIVATE;
  1381. //双录两阶段视频窗口复用
  1382. if (NULL != pg_local_hwnd){
  1383. session->local_hwnd = pg_local_hwnd;
  1384. //SetWindowLongPtrA(session->local_hwnd, GWLP_USERDATA, (LONG_PTR)session);
  1385. breuse_local_wnd = true;
  1386. }
  1387. else{
  1388. if (0 != session->conf.local_move){
  1389. dLocal_style -= WS_EX_NOACTIVATE;
  1390. }
  1391. if (0 != session->conf.remote_move){
  1392. dRemote_style -= WS_EX_NOACTIVATE;
  1393. }
  1394. CoInitialize(0);
  1395. wc.cbClsExtra = 0;
  1396. wc.cbWndExtra = 0;
  1397. wc.hInstance = hInst;
  1398. wc.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
  1399. wc.hCursor = NULL;
  1400. wc.hIcon = NULL;
  1401. wc.lpfnWndProc = &WndProc;
  1402. wc.lpszClassName = WNDCLS_NAME;
  1403. wc.style = CS_HREDRAW | CS_OWNDC | CS_VREDRAW;
  1404. a = RegisterClassA(&wc);
  1405. if (a == 0)
  1406. return 0;
  1407. session->local_hwnd = CreateWindowExA(dLocal_style,
  1408. WNDCLS_NAME, NULL, WS_POPUP|WS_VISIBLE,
  1409. session->conf.local_video_view_x, session->conf.local_video_view_y, session->conf.local_video_view_cx, session->conf.local_video_view_cy,
  1410. NULL, NULL, hInst, NULL);
  1411. if (session->local_hwnd) {
  1412. SetWindowLongPtrA(session->local_hwnd, GWLP_USERDATA, (LONG_PTR)session);
  1413. if (0 == session->conf.local_move){
  1414. SetWindowPos(session->local_hwnd, HWND_TOP, 0, 0, 0, 0, SWP_NOSIZE|SWP_NOMOVE);
  1415. }
  1416. pg_local_hwnd = session->local_hwnd;
  1417. //LogWarn(Severity_Low, Error_Debug, EVENT_MOD_SIP_LOCAL_WINDOW_CREATE_SUCCESS, "create local window success and restore local video hwnd.");
  1418. }
  1419. else{
  1420. char strinfo[MAX_PATH] = {0};
  1421. _snprintf(strinfo, MAX_PATH, "%s%d", "create local window failed and last error is ", GetLastError());
  1422. LogWarn(Severity_Middle, Error_Debug, EVENT_MOD_SIP_LOCAL_WINDOW_CREATE_FAILED, strinfo);
  1423. //return -1;
  1424. }
  1425. }
  1426. if(session->conf.remote_video_view_x||session->conf.remote_video_view_y||session->conf.remote_video_view_cx||session->conf.remote_video_view_cy)
  1427. {
  1428. if (NULL != pg_remote_hwnd){
  1429. session->remote_hwnd = pg_remote_hwnd;
  1430. breuse_remote_wnd = true;
  1431. if (NULL != pg_last_session){
  1432. record_agent_picture_show_session_destory(pg_last_session);
  1433. }
  1434. }
  1435. else{
  1436. session->remote_hwnd = CreateWindowExA(dRemote_style,
  1437. WNDCLS_NAME, NULL, WS_POPUP|WS_VISIBLE,
  1438. session->conf.remote_video_view_x, session->conf.remote_video_view_y, session->conf.remote_video_view_cx, session->conf.remote_video_view_cy,
  1439. NULL, NULL, hInst, NULL);
  1440. if (session->remote_hwnd) {
  1441. SetWindowLongPtrA(session->remote_hwnd, GWLP_USERDATA, (LONG_PTR)session);
  1442. if (0 == session->conf.remote_move){
  1443. SetWindowPos(session->remote_hwnd, HWND_TOP, 0, 0, 0, 0, SWP_NOSIZE|SWP_NOMOVE);
  1444. }
  1445. pg_remote_hwnd = session->remote_hwnd;
  1446. //LogWarn(Severity_Low, Error_Debug, EVENT_MOD_SIP_REMOTE_WINDOW_CREATE_SUCCESS, "create remote window success and restore remote video hwnd.");
  1447. }
  1448. else{
  1449. char strinfo[MAX_PATH] = {0};
  1450. _snprintf(strinfo, MAX_PATH, "%s%d", "create remote window failed and last error is ", GetLastError());
  1451. LogWarn(Severity_Middle, Error_Debug, EVENT_MOD_SIP_REMOTE_WINDOW_CREATE_FAILED, strinfo);
  1452. //return -1;
  1453. }
  1454. }
  1455. }
  1456. else
  1457. {
  1458. session->remote_hwnd = NULL;
  1459. }
  1460. if (session->local_hwnd/* && session->remote_hwnd*/)
  1461. {
  1462. int rc = 0;
  1463. ShowCursor(FALSE);
  1464. SetEvent(session->ui_event);
  1465. rc = start_video(session);
  1466. if (rc != 0) {
  1467. LogWarn(Severity_Middle, Error_Debug, ERROR_MOD_SIP_START_VIDEO_FAILED, "start video failed!");
  1468. }
  1469. if (!breuse_local_wnd && !breuse_remote_wnd)
  1470. {
  1471. while (GetMessageA(&msg, NULL, NULL, NULL))
  1472. {
  1473. if (msg.message == WM_CLOSE) {
  1474. }
  1475. TranslateMessage(&msg);
  1476. DispatchMessageA(&msg);
  1477. }
  1478. SetEvent(session->ui_event);
  1479. }
  1480. }
  1481. if (a)
  1482. UnregisterClassA(WNDCLS_NAME, hInst);
  1483. CoUninitialize();
  1484. return 0;
  1485. }
  1486. #else
  1487. static void __video_render_log(render_loglevel elevel, void* user_data, const char* fmt, va_list arg)
  1488. {
  1489. int n = vsnprintf(NULL, 0, fmt, arg);
  1490. if (n >= MAX_PATH) {
  1491. char* buf = (char*)malloc((size_t)(n + 1));
  1492. vsnprintf(buf, n + 1, fmt, arg);
  1493. DbgWithLink((LOG_LEVEL_E)elevel, LOG_TYPE_SYSTEM)("%s", buf);
  1494. free(buf);
  1495. }
  1496. else {
  1497. char strlog[MAX_PATH] = { 0 };
  1498. vsnprintf(strlog, MAX_PATH, fmt, arg);
  1499. DbgWithLink((LOG_LEVEL_E)elevel, LOG_TYPE_SYSTEM)("%s", strlog);
  1500. }
  1501. }
  1502. #endif // RVC_OS_WIN
  1503. static int start_ui(video_session_t *session)
  1504. {
  1505. #ifdef RVC_OS_WIN
  1506. session->ui_event = CreateEventA(NULL, FALSE, FALSE, NULL);
  1507. if (!session->ui_event) {
  1508. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("phonemedia_start create ui event failed!");
  1509. return Error_Resource;
  1510. }
  1511. session->ui_thread = (HANDLE)_beginthreadex(NULL, 0, &ui_proc, session, 0, NULL);
  1512. if (!session->ui_thread) {
  1513. CloseHandle(session->ui_event);
  1514. session->ui_event = NULL;
  1515. return Error_Resource;
  1516. }
  1517. {
  1518. HANDLE hs[] = {session->ui_event, session->ui_thread};
  1519. DWORD dwRet = WaitForMultipleObjects(array_size(hs), hs, FALSE, INFINITE);
  1520. if (dwRet == WAIT_OBJECT_0) { //
  1521. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("wait for ui ready event ok!");
  1522. } else if (dwRet == WAIT_OBJECT_0 + 1) { // thread exit
  1523. CloseHandle(session->ui_thread);
  1524. session->ui_thread = NULL;
  1525. CloseHandle(session->ui_event);
  1526. session->ui_event = NULL;
  1527. return Error_Resource;
  1528. }
  1529. }
  1530. return 0;
  1531. #endif // RVC_OS_WIN
  1532. }
  1533. static void stop_ui(video_session_t *session)
  1534. {
  1535. #ifdef RVC_OS_WIN
  1536. if (DOUBLERECORD_CALLTYPE == session->conf.nCallType) {
  1537. if (NULL != pg_last_session) {
  1538. pg_last_session->rtp = session->rtp;
  1539. pg_last_session->local_clock = session->local_clock;
  1540. CloseHandle(session->ui_thread);
  1541. session->ui_thread = NULL;
  1542. CloseHandle(session->ui_event);
  1543. session->ui_event = NULL;
  1544. session = pg_last_session;
  1545. }
  1546. }
  1547. if (NULL != session->pic_record) {
  1548. if (NULL != session->pic_record->work_thread) {
  1549. SetEvent(session->pic_record->evt);
  1550. CloseHandle(session->pic_record->work_thread);
  1551. session->pic_record->work_thread = NULL;
  1552. CloseHandle(session->pic_record->evt);
  1553. session->pic_record->evt = NULL;
  1554. }
  1555. }
  1556. if (session->local_hwnd) {
  1557. BOOL bRet = PostMessageA(session->local_hwnd, WM_CLOSE, 0, 0);
  1558. DWORD dCode = WaitForSingleObject(session->ui_thread, INFINITE);
  1559. CloseHandle(session->ui_thread);
  1560. session->ui_thread = NULL;
  1561. CloseHandle(session->ui_event);
  1562. session->ui_event = NULL;
  1563. }
  1564. pg_last_session = NULL;
  1565. pg_local_hwnd = NULL;
  1566. pg_remote_hwnd = NULL;
  1567. #endif
  1568. }
  1569. int video_session_create(const video_session_conf_t *conf, video_session_t **p_session)
  1570. {
  1571. video_session_t *session = ZALLOC_T(video_session_t);
  1572. if (session)
  1573. {
  1574. memcpy(&session->conf, conf, sizeof(video_session_conf_t));
  1575. //session->bshow_remote = false;
  1576. //session->ilast_windstae = 0;
  1577. session->video_shm_q_env = new Clibvideoqueue(REC_COMMON_VIDEO_ENV_SHM_RTP_QUEUE);
  1578. session->video_shm_q_remote = new Clibvideoqueue(REC_COMMON_VIDEO_REMOTE_SHM_RTP_QUEUE);
  1579. session->video_shm_q_preview = new Clibvideoqueue(REC_COMMON_VIDEO_ENV_SHM_PREVIEW_QUEUE);
  1580. char strPath[MAX_PATH_SIZE]={0};
  1581. char strImgPath[MAX_PATH_SIZE]={0};
  1582. #ifdef RVC_OS_WIN
  1583. GetCurrentRunPath(strPath);
  1584. sprintf(strImgPath, "%s\\bin\\error.jpg", strPath);
  1585. #else
  1586. snprintf(strImgPath, MAX_PATH_SIZE, "%s", "./bin/error.jpg");
  1587. #endif // RVC_OS_WIN
  1588. if (ExistsFile(strImgPath))
  1589. {
  1590. IplImage*img = cvLoadImage(strImgPath,1);
  1591. if (img != NULL)
  1592. {
  1593. session->video_error = new videoq_frame;
  1594. session->video_error->format = VIDEOQ_FORMAT_RGB24;
  1595. session->video_error->framesize = 320*180*3;
  1596. session->video_error->height = 180;
  1597. session->video_error->width = 320;
  1598. session->video_error->data = new unsigned char[320*180*3];
  1599. memcpy(session->video_error->data,img->imageData,320*180*3);
  1600. cvReleaseImage(&img);
  1601. }
  1602. }
  1603. else
  1604. {
  1605. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("Load error img Fail");
  1606. session->video_error = NULL;
  1607. }
  1608. //加载人形背景框
  1609. char strPersonPath[MAX_PATH_SIZE] = {0};
  1610. #ifdef RVC_OS_WIN
  1611. sprintf(strPersonPath, "%s\\bin\\rxk.jpg", strPath);
  1612. #else
  1613. snprintf(strPersonPath, MAX_PATH_SIZE, "./bin/rxk.jpg");
  1614. #endif // RVC_OS_WIN
  1615. if (ExistsFile(strPersonPath))
  1616. {
  1617. if (session->personimage == NULL)
  1618. {
  1619. session->personimage = cvLoadImage(strPersonPath);
  1620. }
  1621. if (session->personmask == NULL )
  1622. {
  1623. session->personmask = cvLoadImage(strPersonPath,0);
  1624. }
  1625. //IplImage*persongrey = cvLoadImage(strPersonPath,CV_LOAD_IMAGE_GRAYSCALE);
  1626. //二值化提取人形框掩码
  1627. //cvThreshold(persongrey,session->personmask,150, 255, CV_THRESH_BINARY);
  1628. }
  1629. else
  1630. {
  1631. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("Load person img Fail");
  1632. session->personimage = NULL;
  1633. session->personmask = NULL;
  1634. }
  1635. #if 0
  1636. video_frame frame;
  1637. video_frame_alloc(320, 180, VIDEO_FORMAT_RGB24, &frame);
  1638. video_frame_fill_black(&frame);
  1639. videoq_frame frm;
  1640. frm.data = frame.data[0];
  1641. session->video_shm_q_env->GetVideo(&frm, 0);
  1642. video_frame_save_bmpfile("d:\\a.bmp", &frame);
  1643. #endif
  1644. if (conf->camera_count == 2) {
  1645. session->video_shm_q_opt = new Clibvideoqueue(REC_COMMON_VIDEO_OPT_SHM_RTP_QUEUE);
  1646. }
  1647. session->bvideorecved = false;
  1648. session->blocalrender = false;
  1649. session->bremoterender = false;
  1650. *p_session = session;
  1651. }
  1652. return 0;
  1653. }
  1654. int video_session_start(video_session_t *session)
  1655. {
  1656. int rc = -1;
  1657. #ifdef RVC_OS_WIN
  1658. rc = start_ui(session);
  1659. #else
  1660. rc = start_video(session);
  1661. #endif // RVC_OS_WIN
  1662. return rc;
  1663. }
  1664. void video_session_stop(video_session_t *session)
  1665. {
  1666. #ifdef RVC_OS_WIN
  1667. stop_ui(session);
  1668. #else
  1669. stop_video(session);
  1670. #endif
  1671. }
  1672. void video_session_destroy(video_session_t *session)
  1673. {
  1674. if (session->video_error){
  1675. delete session->video_error->data;
  1676. delete session->video_error;
  1677. }
  1678. if (session->video_shm_q_remote) {
  1679. delete session->video_shm_q_remote;
  1680. session->video_shm_q_remote = NULL;
  1681. }
  1682. if (session->personimage){
  1683. cvReleaseImage(&session->personimage);
  1684. }
  1685. if (session->personmask){
  1686. cvReleaseImage(&session->personmask);
  1687. }
  1688. if (session->recordareaimage){
  1689. cvReleaseImage(&session->recordareaimage);
  1690. }
  1691. if (session->recordareamask){
  1692. cvReleaseImage(&session->recordareamask);
  1693. }
  1694. free(session);
  1695. }
  1696. void av_log_cb(void*ptr, int level, const char*fmt, va_list list)
  1697. {
  1698. int n = vsnprintf(NULL, 0, fmt, list);
  1699. if (n >= MAX_PATH) {
  1700. char* buf = (char*)malloc((size_t)(n + 1));
  1701. vsnprintf(buf, n + 1, fmt, list);
  1702. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("%s", buf);
  1703. free(buf);
  1704. }
  1705. else {
  1706. char strlog[MAX_PATH] = { 0 };
  1707. vsnprintf(strlog, MAX_PATH, fmt, list);
  1708. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("%s", strlog);
  1709. }
  1710. }
  1711. int video_lib_init()
  1712. {
  1713. #ifdef RVC_OS_WIN
  1714. videoframework_init();
  1715. av_log_set_callback(&av_log_cb);
  1716. //av_log_set_level(AV_LOG_DEBUG);
  1717. av_log_set_level(AV_LOG_QUIET);
  1718. #else
  1719. videoframework_init();
  1720. if (0 != VideoRender_Init()){
  1721. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("sdl init failed.");
  1722. }
  1723. //av_log_set_callback(&av_log_cb);
  1724. //av_log_set_level(AV_LOG_TRACE);
  1725. //av_log_set_level(AV_LOG_QUIET);
  1726. #endif // RVC_OS_WIN
  1727. return 0;
  1728. }
  1729. void video_lib_deinit()
  1730. {
  1731. #ifdef RVC_OS_WIN
  1732. CoUninitialize();
  1733. #else
  1734. #endif // RVC_OS_WIN
  1735. videoframework_term();
  1736. VideoRender_Term();
  1737. }