ews_capture.cpp 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017
  1. #include "stdafx.h"
  2. #include "SpBase.h"
  3. #include <locale.h>
  4. #include <portaudio.h>
  5. #include <memutil.h>
  6. #include <md5.h>
  7. #include <ipp.h>
  8. #include <intrin.h>
  9. #include "videoframework.h"
  10. #include "y2k_time.h"
  11. #include "libaudioqueue.h"
  12. #include "libvideoqueue.h"
  13. #include "rec_common.h"
  14. #include "ews_capture.h"
  15. #include "videohorflip.h"
  16. #include "Event.h"
  17. #include "EventCode.h"
  18. #include <cv.h>
  19. #include <cxcore.h>
  20. #include <highgui.h>
  21. #define av_always_inline __inline
  22. #define inline __inline
  23. #ifndef INT64_C
  24. #define INT64_C(c) (c##LL)
  25. #define UINT64_C(c) (c##UL)
  26. #endif
  27. #include <stdint.h>
  28. extern "C"
  29. {
  30. #include <libavutil\avutil.h>
  31. #include <libavcodec\avcodec.h>
  32. #include <libswscale\swscale.h>
  33. }
  34. #include "video_common/ffmpeg_api_cpp_adapter.h"
  35. #define CAPTURE_FRAME_TIME 20 // 20ms per frame
  36. #define CAPTURE_CLOCK 8000
  37. DeviceTypeEnum g_eDeviceType;
  38. typedef struct ews_audio_capture_t {
  39. PaStream *stream;
  40. Clibaudioqueue *shm_queue;
  41. ews_capture_t *parent;
  42. }ews_audio_capture_t;
  43. typedef struct ews_video_capture_t {
  44. videocap_t cap;
  45. Clibvideoqueue *snapshot_shm_queue;
  46. Clibvideoqueue *preview_shm_queue;
  47. Clibvideoqueue *rtp_shm_queue;
  48. Clibvideoqueue *sales_shm_queue;
  49. ews_capture_t *parent;
  50. int camera_type; // CAMERA_TYPE_xxx
  51. int frame_id;
  52. struct SwsContext *preview_sws_ctx;
  53. struct SwsContext *rtp_sws_ctx;
  54. }ews_video_capture_t;
  55. struct ews_capture_t
  56. {
  57. ews_capture_config_t config;
  58. ews_audio_capture_t *audio;
  59. ews_video_capture_t *video;
  60. };
  61. static int Bin2Str(unsigned char *x, int xlen, char *str, int str_size)
  62. {
  63. static const char *hex2char = "0123456789ABCDEF";
  64. int i, k = 0;
  65. if (str_size <= xlen * 2)
  66. return -1;
  67. for (i = 0; i < xlen; ++i) {
  68. int h = x[i] >> 4;
  69. int l = x[i] & 0xf;
  70. str[k++] = hex2char[h];
  71. str[k++] = hex2char[l];
  72. }
  73. str[k] = 0;
  74. return k;
  75. }
  76. static int translate_id(int in_direction, int idx)
  77. {
  78. int i, n, ii;
  79. n = Pa_GetDeviceCount();
  80. for (i = 0, ii = 0; i < n; ++i) {
  81. const PaDeviceInfo *info = Pa_GetDeviceInfo(i);
  82. if (in_direction) {
  83. if (info->maxInputChannels) {
  84. if (ii == idx) {
  85. return i;
  86. }
  87. ii++;
  88. }
  89. } else {
  90. if (info->maxOutputChannels) {
  91. if (ii == idx) {
  92. return i;
  93. }
  94. ii++;
  95. }
  96. }
  97. }
  98. return -1;
  99. }
  100. static int StreamCallback(const void *input,
  101. void *output,
  102. unsigned long frameCount,
  103. const PaStreamCallbackTimeInfo* timeInfo,
  104. PaStreamCallbackFlags statusFlags,
  105. void *userData)
  106. {
  107. ews_audio_capture_t *audio_cap = (ews_audio_capture_t*)userData;
  108. if (input) {
  109. audio_frame frm;
  110. frm.bitspersample = 16;
  111. frm.format = 1;
  112. frm.data = (char*)const_cast<void*>(input);
  113. frm.framesize = frameCount << 1;
  114. frm.nchannels = 1;
  115. frm.samplespersec = audio_cap->parent->config.iaudiosamplerate;
  116. frm.iseriesnumber = 0;
  117. if (audio_cap && audio_cap->shm_queue){
  118. if (!audio_cap->shm_queue->InsertAudio(&frm)) {
  119. Dbg("Insert audio for surveillance record failed! frameCount:%d", frameCount);
  120. }
  121. }
  122. }
  123. if (output) {
  124. memset(output, 0, frameCount<<1);
  125. }
  126. return paContinue;
  127. }
  128. static ews_audio_capture_t *ews_audio_capture_create(ews_capture_t *cap)
  129. {
  130. ews_audio_capture_t *audio_cap = ZALLOC_T(ews_audio_capture_t);
  131. if (audio_cap) {
  132. audio_cap->parent = cap;
  133. audio_cap->shm_queue = new Clibaudioqueue(REC_COMMON_AUDIO_EWS_SHM_QUEUE);
  134. }
  135. return audio_cap;
  136. }
  137. static void ews_audio_capture_destroy(ews_audio_capture_t *audio_cap)
  138. {
  139. delete audio_cap->shm_queue;
  140. free(audio_cap);
  141. }
  142. static int ews_audio_capture_start(ews_audio_capture_t *audio_cap)
  143. {
  144. ews_capture_t *cap = audio_cap->parent;
  145. PaStreamParameters inParam = {0};
  146. PaStreamParameters outParam = {0};
  147. PaError paError;
  148. const PaDeviceInfo *info;
  149. int nId = ews_capture_get_audio_device_id(true, cap->config.strAudioIn);
  150. if (nId == -1)
  151. {
  152. return Error_AudioIN;
  153. }
  154. int in_dev_id = translate_id(TRUE, nId);
  155. if (in_dev_id < 0) {
  156. Dbg("audio in dev translate failed!");
  157. return Error_AudioIN;
  158. }
  159. info = Pa_GetDeviceInfo(in_dev_id);
  160. if (!info) {
  161. Dbg("get device info failed!");
  162. return Error_AudioIN;
  163. }
  164. inParam.channelCount = 1;
  165. inParam.device = in_dev_id;
  166. inParam.suggestedLatency = info->defaultLowInputLatency;
  167. inParam.sampleFormat = paInt16;
  168. inParam.hostApiSpecificStreamInfo = NULL;
  169. int iAudioCaptureSampleRate = cap->config.iaudiosamplerate;
  170. if (Pa_IsFormatSupported(&inParam, NULL, iAudioCaptureSampleRate) != paNoError) {
  171. Dbg("audio capture create error, cannot open audio input device, and current capture sample rate is %d.", iAudioCaptureSampleRate);
  172. return Error_AudioIN;
  173. }
  174. //打开流设备,可以用以下代码替换paError = Pa_OpenStream(&audio_cap->stream, &inParam, &outParam, CAPTURE_CLOCK,
  175. //CAPTURE_FRAME_TIME * CAPTURE_CLOCK/1000, paClipOff|paDitherOff, &StreamCallback, audio_cap);
  176. paError = Pa_OpenStream(&audio_cap->stream, &inParam, NULL, iAudioCaptureSampleRate,
  177. CAPTURE_FRAME_TIME * iAudioCaptureSampleRate/1000, paClipOff|paDitherOff, &StreamCallback, audio_cap);
  178. if (paError != paNoError) {
  179. Dbg("portaudio open stream failed! paError = %d", paError);
  180. return Error_AudioIN;
  181. }
  182. paError = Pa_StartStream(audio_cap->stream);
  183. if (paError != paNoError) {
  184. Dbg("portaudio start stream failed! paError = %d", paError);
  185. return Error_AudioIN;
  186. }
  187. return Error_Succeed;
  188. }
  189. static void ews_audio_capture_stop(ews_audio_capture_t *audio_cap)
  190. {
  191. if (audio_cap->stream) {
  192. Pa_AbortStream(audio_cap->stream);
  193. Pa_CloseStream(audio_cap->stream);
  194. audio_cap->stream = NULL;
  195. }
  196. }
  197. static int calc_capture_mode(int width, int height, int *mode)
  198. {
  199. const struct {
  200. int mode;
  201. int width;
  202. int height;
  203. } modes [] = {
  204. {VIDEOCAP_FRAME_SQCIF, VIDEOCAP_SQCIF_WIDTH, VIDEOCAP_SQCIF_HEIGHT},
  205. {VIDEOCAP_FRAME_QQVGA, VIDEOCAP_QQVGA_WIDTH, VIDEOCAP_QQVGA_HEIGHT},
  206. {VIDEOCAP_FRAME_QCIF, VIDEOCAP_QCIF_WIDTH, VIDEOCAP_QCIF_HEIGHT},
  207. {VIDEOCAP_FRAME_QVGA, VIDEOCAP_QVGA_WIDTH, VIDEOCAP_QVGA_HEIGHT},
  208. {VIDEOCAP_FRAME_CIF, VIDEOCAP_CIF_WIDTH, VIDEOCAP_CIF_HEIGHT},
  209. {VIDEOCAP_FRAME_VGA, VIDEOCAP_VGA_WIDTH, VIDEOCAP_VGA_HEIGHT},
  210. {VIDEOCAP_FRAME_4CIF, VIDEOCAP_4CIF_WIDTH, VIDEOCAP_4CIF_HEIGHT},
  211. {VIDEOCAP_FRAME_SVGA, VIDEOCAP_SVGA_WIDTH, VIDEOCAP_SVGA_HEIGHT},
  212. {VIDEOCAP_FRAME_NHD, VIDEOCAP_NHD_WIDTH, VIDEOCAP_NHD_HEIGHT},
  213. {VIDEOCAP_FRAME_SXGA, VIDEOCAP_SXGA_WIDTH, VIDEOCAP_SXGA_HEIGHT},
  214. {VIDEOCAP_FRAME_720P, VIDEOCAP_720P_WIDTH, VIDEOCAP_720P_HEIGHT},
  215. {VIDEOCAP_FRAME_1080P, VIDEOCAP_1080P_WIDTH, VIDEOCAP_1080P_HEIGHT},
  216. };
  217. int i;
  218. for (i = 0; i < array_size(modes); ++i) {
  219. if (modes[i].width == width && modes[i].height == height) {
  220. *mode = modes[i].mode;
  221. return 0;
  222. }
  223. }
  224. return Error_NotExist;
  225. }
  226. static int video_shm_enqueue(Clibvideoqueue *shm_queue, video_frame *frame, int flags)
  227. {
  228. videoq_frame tmp_frm;
  229. tmp_frm.data = frame->data[0];
  230. tmp_frm.framesize = frame->width * frame->height * 3;
  231. tmp_frm.format = VIDEOQ_FORMAT_RGB24;
  232. tmp_frm.width = frame->width;
  233. tmp_frm.height = frame->height;
  234. unsigned int nowtime = y2k_time_now();
  235. if (!shm_queue->InsertVideo(&tmp_frm, flags,nowtime)) {
  236. Dbg("caution: insert shm video failed!");
  237. return Error_Unexpect;
  238. } else {
  239. //Dbg("insert shm video ok!");
  240. return Error_Succeed;
  241. }
  242. }
  243. static void ews_cap_on_frame(void *user_data, video_frame *frame)
  244. {
  245. ews_video_capture_t *video_cap = (ews_video_capture_t *)user_data;
  246. ews_capture_t *cap = video_cap->parent;
  247. int rc;
  248. int flip = -1;
  249. if (cap->config.video_rotate == 0){
  250. flip = 0;
  251. }
  252. else if (cap->config.video_rotate == 180){
  253. flip = (VIDEOQUEUE_FLAG_VERTICAL_FLIP|VIDEOQUEUE_FLAG_HORIZONTAL_FLIP);
  254. }
  255. else {
  256. return;
  257. }
  258. video_cap->frame_id++;
  259. //Dbg("start ews on frame, id=%d, tick=%d", video_cap->frame_id, GetTickCount());
  260. //IplImage*img = NULL;
  261. //img = cvCreateImage(cvSize(frame->width,frame->height),IPL_DEPTH_8U,3);
  262. //img->imageData = (char*)frame->data[0];
  263. //cvSaveImage("c:\\ews.jpg", img,0);
  264. //cvReleaseImageHeader(&img);
  265. rc = video_shm_enqueue(video_cap->snapshot_shm_queue, frame, flip==0?VIDEOQUEUE_FLAG_VERTICAL_FLIP:VIDEOQUEUE_FLAG_HORIZONTAL_FLIP);
  266. if (rc != Error_Succeed)
  267. {
  268. Dbg("ews snapshot queue enqueue shm failed! Error = %d, camera_type=%d", rc, video_cap->camera_type);
  269. }
  270. //// snapshot
  271. //if (rc==Error_Succeed)
  272. //{
  273. // if (*cap->config.ref_ews_capture_count)
  274. // {
  275. // Dbg("ews camera ref_env_capture_count=%d",*cap->config.ref_ews_capture_count);
  276. // InterlockedDecrement(cap->config.ref_ews_capture_count);
  277. // LogEvent(Severity_Middle, MOD_EVENT_MEDIACONTROLLER_FINISHED_CAPTURE_ENV, "agent capture env ok, and capture env finished!");
  278. // }
  279. //}
  280. // preview 320x240
  281. {
  282. video_frame preview_frame;
  283. video_frame_alloc(REC_COMMON_VIDEO_PREVIEW_WIDTH, REC_COMMON_VIDEO_PREVIEW_HEIGHT, VIDEO_FORMAT_RGB24, &preview_frame);
  284. memset(preview_frame.data[0], 0, preview_frame.height*preview_frame.linesize[0]);
  285. //uint8_t *src_data[4] = {frame->data[0] + 80*3, 0, 0, 0}; // cut for 480x360
  286. //sws_scale(video_cap->preview_sws_ctx, src_data, frame->linesize, 0, frame->height, preview_frame.data, preview_frame.linesize);
  287. uint8_t *dst_data[4] = {preview_frame.data[0] + 30 * preview_frame.linesize[0], 0, 0, 0}; // 320x180 paste to 320x240
  288. sws_scale(video_cap->preview_sws_ctx, frame->data, frame->linesize, 0, frame->height, dst_data, preview_frame.linesize);
  289. video_shm_enqueue(video_cap->preview_shm_queue, &preview_frame, flip);
  290. video_frame_free(&preview_frame);
  291. }
  292. // rtp 320x180
  293. {
  294. video_frame rtp_frame;
  295. video_frame_alloc(REC_COMMON_VIDEO_RTP_EWS_WIDTH, REC_COMMON_VIDEO_RTP_EWS_HEIGHT, VIDEO_FORMAT_RGB24, &rtp_frame);
  296. uint8_t *src_data[4] = {frame->data[0] + (frame->height-1) * frame->linesize[0], 0, 0, 0};
  297. int src_linesize[4] = {-frame->linesize[0], 0, 0, 0}; // 上下翻转并缩放
  298. sws_scale(video_cap->rtp_sws_ctx, src_data, src_linesize, 0, frame->height, rtp_frame.data, rtp_frame.linesize);
  299. video_shm_enqueue(video_cap->rtp_shm_queue, &rtp_frame, flip);
  300. video_shm_enqueue(video_cap->sales_shm_queue, &rtp_frame, flip);
  301. #if 0
  302. static int i = 0;
  303. if (i == 0 && 0) {
  304. video_frame tmp_frame;
  305. video_frame_alloc(320, 180, VIDEO_FORMAT_RGB24, &tmp_frame);
  306. video_frame_fill_black(&tmp_frame);
  307. videoq_frame frm;
  308. frm.data = tmp_frame.data[0];
  309. video_cap->rtp_shm_queue->GetVideo(&frm, 0);
  310. video_frame_save_bmpfile("d:\\abc.bmp", &tmp_frame);
  311. video_frame_free(&tmp_frame);
  312. //video_frame_save_bmpfile("d:\\ab.bmp", &rtp_frame);
  313. }
  314. #endif
  315. video_frame_free(&rtp_frame);
  316. }
  317. //Dbg("end ews on frame, id=%d, tick=%d", video_cap->frame_id, GetTickCount());;
  318. }
  319. static ews_video_capture_t *ews_video_capture_create(ews_capture_t *cap, int camera_type)
  320. {
  321. ews_video_capture_t *video_cap = ZALLOC_T(ews_video_capture_t);
  322. if (video_cap) {
  323. video_cap->parent = cap;
  324. video_cap->camera_type = camera_type;
  325. video_cap->frame_id = 0;
  326. if (camera_type == CAMERA_TYPE_EWS) { // need to be edited
  327. video_cap->snapshot_shm_queue = new Clibvideoqueue(REC_COMMON_VIDEO_EWS_SHM_SNAPSHOT_QUEUE);
  328. video_cap->rtp_shm_queue = new Clibvideoqueue(REC_COMMON_VIDEO_EWS_SHM_RTP_QUEUE);
  329. video_cap->sales_shm_queue = new Clibvideoqueue(REC_COMMON_VIDEO_SALES_EWS_SHM_RTP_QUEUE);
  330. video_cap->rtp_sws_ctx = sws_getContext(REC_COMMON_VIDEO_SNAPSHOT_WIDTH,
  331. REC_COMMON_VIDEO_SNAPSHOT_HEIGHT,
  332. PIX_FMT_BGR24,
  333. REC_COMMON_VIDEO_RTP_EWS_WIDTH,
  334. REC_COMMON_VIDEO_RTP_EWS_HEIGHT,
  335. PIX_FMT_BGR24,
  336. SWS_POINT, NULL, NULL, NULL);
  337. video_cap->preview_shm_queue = new Clibvideoqueue(REC_COMMON_VIDEO_EWS_SHM_PREVIEW_QUEUE);
  338. /*video_cap->preview_sws_ctx = sws_getContext(REC_COMMON_VIDEO_SNAPSHOT_PREVIEW_WIDTH,
  339. REC_COMMON_VIDEO_SNAPSHOT_PREVIEW_HEIGHT,
  340. PIX_FMT_BGR24,
  341. REC_COMMON_VIDEO_PREVIEW_WIDTH,
  342. REC_COMMON_VIDEO_PREVIEW_HEIGHT,
  343. PIX_FMT_BGR24,
  344. SWS_FAST_BILINEAR, NULL, NULL, NULL);*/
  345. video_cap->preview_sws_ctx = sws_getContext(REC_COMMON_VIDEO_SNAPSHOT_WIDTH,
  346. REC_COMMON_VIDEO_SNAPSHOT_HEIGHT,
  347. PIX_FMT_BGR24,
  348. REC_COMMON_VIDEO_RTP_EWS_WIDTH,
  349. REC_COMMON_VIDEO_RTP_EWS_HEIGHT,
  350. PIX_FMT_BGR24,
  351. SWS_FAST_BILINEAR, NULL, NULL, NULL);
  352. }
  353. }
  354. return video_cap;
  355. }
  356. static void ews_video_capture_destroy(ews_video_capture_t *video_cap)
  357. {
  358. if (video_cap) {
  359. if (video_cap->preview_sws_ctx) {
  360. sws_freeContext(video_cap->preview_sws_ctx);
  361. video_cap->preview_sws_ctx = NULL;
  362. }
  363. if (video_cap->rtp_sws_ctx) {
  364. sws_freeContext(video_cap->rtp_sws_ctx);
  365. video_cap->rtp_sws_ctx = NULL;
  366. }
  367. if (video_cap->snapshot_shm_queue) {
  368. delete video_cap->snapshot_shm_queue;
  369. video_cap->snapshot_shm_queue = NULL;
  370. }
  371. if (video_cap->rtp_shm_queue) {
  372. delete video_cap->rtp_shm_queue;
  373. video_cap->rtp_shm_queue = NULL;
  374. }
  375. if (video_cap->sales_shm_queue) {
  376. delete video_cap->sales_shm_queue;
  377. video_cap->sales_shm_queue = NULL;
  378. }
  379. if (video_cap->preview_shm_queue) {
  380. delete video_cap->preview_shm_queue;
  381. video_cap->preview_shm_queue = NULL;
  382. }
  383. free(video_cap);
  384. }
  385. }
  386. static int ews_video_capture_start(ews_video_capture_t *video_cap)
  387. {
  388. ews_capture_config_t *conf = &video_cap->parent->config;
  389. int dev_id;
  390. if (video_cap->camera_type == CAMERA_TYPE_EWS)
  391. {
  392. CSimpleStringA tmp;
  393. dev_id = ews_capture_get_video_device_id(conf->strVideo,tmp);
  394. if (dev_id == -1)
  395. {
  396. Dbg("No ews camera,please check config file or device!");
  397. return -1;
  398. }
  399. }
  400. videocap_param param = {0};
  401. int cap_mode;
  402. int rc = -1;
  403. rc = calc_capture_mode(REC_COMMON_VIDEO_SNAPSHOT_WIDTH, REC_COMMON_VIDEO_SNAPSHOT_HEIGHT, &cap_mode);
  404. if (rc != 0)
  405. {
  406. Dbg("calc cap_mode failed!");
  407. return rc;
  408. }
  409. param.cap_mode = cap_mode;
  410. param.dev_id = dev_id;
  411. param.frame_fmt = VIDEO_FORMAT_RGB24;
  412. if ((ePadtype == g_eDeviceType)||(eDesk2SType == g_eDeviceType))
  413. {
  414. param.fps = REC_COMMON_VIDEO_FPS_MOBILE;
  415. }
  416. else
  417. {
  418. param.fps = REC_COMMON_VIDEO_RAW_FPS;
  419. }
  420. param.on_frame = &ews_cap_on_frame;
  421. param.user_data = video_cap;
  422. param.option = 0;
  423. rc = videocap_create(&video_cap->cap, &param);
  424. if (rc != 0)
  425. {
  426. Dbg("videocap create failed!");
  427. return rc;
  428. }
  429. rc = videocap_start(video_cap->cap);
  430. if (rc != 0)
  431. {
  432. Dbg("videocap start failed!");
  433. videocap_destroy(video_cap->cap);
  434. video_cap->cap = NULL;
  435. return rc;
  436. }
  437. return 0;
  438. }
  439. static void ews_video_capture_stop(ews_video_capture_t *video_cap)
  440. {
  441. if (video_cap->cap) {
  442. videocap_stop(video_cap->cap);
  443. videocap_destroy(video_cap->cap);
  444. video_cap->cap = NULL;
  445. }
  446. }
  447. int ews_capture_create( const ews_capture_config_t *config, ews_capture_t **p_cap )
  448. {
  449. ews_capture_t *cap = ZALLOC_T(ews_capture_t);
  450. cap->audio = NULL;
  451. cap->video = NULL;
  452. memcpy(&cap->config, config, sizeof(ews_capture_config_t));
  453. cap->audio = ews_audio_capture_create(cap);
  454. if (!cap->audio) {
  455. Dbg("create audio capture object failed!");
  456. return Error_Unexpect;
  457. }
  458. CSimpleStringA tmp;
  459. int dev_id = ews_capture_get_video_device_id(config->strVideo,tmp);
  460. if (dev_id != -1)
  461. {
  462. cap->video = ews_video_capture_create(cap, CAMERA_TYPE_EWS);
  463. if (!cap->video) {
  464. Dbg("create ews video object failed!");
  465. return Error_Unexpect;
  466. }
  467. }
  468. if(dev_id == -1)
  469. {
  470. Dbg("ews camera device id error!");
  471. ews_capture_destroy(cap);
  472. return Error_Unexpect;
  473. }
  474. else
  475. {
  476. *p_cap = cap;
  477. Dbg("create surveillance record audio capture object(%0x) success, capture sample rate is %d, and audio in device name is %s.",
  478. cap, cap->config.iaudiosamplerate, cap->config.strAudioIn.GetData());
  479. return 0;
  480. }
  481. }
  482. // 重启摄像头用到
  483. ErrorCodeEnum ews_capture_create( const ews_capture_config_t *config,ews_capture_t *cap )
  484. {
  485. CSimpleStringA tmp;
  486. int dev_id = ews_capture_get_video_device_id(config->strVideo,tmp);
  487. if((dev_id != -1)&&(cap->video == NULL))
  488. {
  489. cap->video = ews_video_capture_create(cap, CAMERA_TYPE_EWS);
  490. if (!cap->video)
  491. {
  492. Dbg("create ews video object failed!");
  493. return Error_Unexpect;
  494. }
  495. }
  496. else
  497. {
  498. return Error_Unexpect;
  499. }
  500. return Error_Succeed;
  501. }
  502. void ews_capture_destroy( ews_capture_t *cap )
  503. {
  504. if (cap) {
  505. if (cap->video) {
  506. ews_video_capture_destroy(cap->video);
  507. cap->video = NULL;
  508. }
  509. if (cap->audio) {
  510. ews_audio_capture_destroy(cap->audio);
  511. cap->audio = NULL;
  512. }
  513. free(cap);
  514. }
  515. }
  516. ErrorCodeEnum ews_capture_start( ews_capture_t *cap )
  517. {
  518. int rc = 0;
  519. if (cap->audio)
  520. {
  521. rc = ews_audio_capture_start(cap->audio);
  522. if (rc != Error_Succeed)
  523. {
  524. ErrorCodeEnum rslt = (ErrorCodeEnum)rc;
  525. if (rslt == Error_AudioIN)
  526. {
  527. Dbg("start audio In object failed! rc:%d", rc);
  528. }
  529. return rslt;
  530. }
  531. }
  532. else
  533. {
  534. Dbg("start ews audio Error_Unexpect");
  535. return Error_Unexpect;
  536. }
  537. if (cap->video)
  538. {
  539. rc = ews_video_capture_start(cap->video);
  540. if (rc != Error_Succeed)
  541. {
  542. Dbg("start ews video capture object failed! rc:%d", rc);
  543. CSimpleStringA strCamFriendlyName;
  544. ews_capture_get_video_device_id(cap->config.strVideo.GetData(),strCamFriendlyName);
  545. char strMessage[MAX_PATH*2] = {0};
  546. get_external_camera_exception_message(strMessage, MAX_PATH*2, strCamFriendlyName, "open ews camera fail,please check device");
  547. LogError(Severity_Middle,Error_NotInit,ERROR_MOD_SURVEILLANCERECORDER_EWSCAM_OPEN,strMessage);
  548. return Error_EwsCamera;
  549. }
  550. }
  551. else
  552. {
  553. Dbg("start ews video Error_Unexpect");
  554. return Error_Unexpect;
  555. }
  556. return (ErrorCodeEnum)rc;
  557. }
  558. void ews_capture_stop( ews_capture_t *cap )
  559. {
  560. if (cap->audio) {
  561. ews_audio_capture_stop(cap->audio);
  562. }
  563. if (cap->video) {
  564. ews_video_capture_stop(cap->video);
  565. }
  566. }
  567. int ews_capture_detect_camera_bug( ews_capture_t *cap, int *ews_n )
  568. {
  569. *ews_n = 0;
  570. if (cap->video)
  571. {
  572. if (cap->video->rtp_shm_queue)
  573. {
  574. *ews_n = cap->video->rtp_shm_queue->GetVideoLens();
  575. }
  576. }
  577. else
  578. {
  579. *ews_n = -1;
  580. }
  581. return 0;
  582. }
  583. int ews_capture_get_last_frametime( ews_capture_t *cap, DWORD *ews_n )
  584. {
  585. *ews_n = 0;
  586. if (cap->video)
  587. {
  588. if (cap->video->rtp_shm_queue)
  589. {
  590. *ews_n = cap->video->rtp_shm_queue->GetLastFrameTime();
  591. }
  592. }
  593. else
  594. {
  595. *ews_n = 0;
  596. }
  597. return 0;
  598. }
  599. static int ews_audio_get_dev_count(int *in_cnt, int *out_cnt)
  600. {
  601. int icnt = 0, ocnt = 0;
  602. int cnt = Pa_GetDeviceCount();
  603. for (int i = 0; i < cnt; ++i) {
  604. const PaDeviceInfo *info = Pa_GetDeviceInfo(i);
  605. if (info->maxInputChannels)
  606. icnt ++;
  607. if (info->maxOutputChannels)
  608. ocnt ++;
  609. }
  610. if (in_cnt)
  611. *in_cnt = icnt;
  612. if (out_cnt)
  613. *out_cnt = ocnt;
  614. return 0;
  615. }
  616. static CSimpleStringA ews_audio_get_dev_name(bool in_direction, int idx)
  617. {
  618. int cnt = Pa_GetDeviceCount();
  619. int ii, i;
  620. for (i = 0, ii = 0; i < cnt; ++i) {
  621. const PaDeviceInfo *info = Pa_GetDeviceInfo(i);
  622. if (in_direction) {
  623. if (info->maxInputChannels) {
  624. if (idx == ii) {
  625. return CSimpleStringA(info->name);
  626. }
  627. ii++;
  628. }
  629. } else {
  630. if (info->maxOutputChannels) {
  631. if (idx == ii) {
  632. return CSimpleStringA(info->name);
  633. }
  634. ii++;
  635. }
  636. }
  637. }
  638. return CSimpleStringA();
  639. }
  640. int ews_capture_lib_init()
  641. {
  642. HRESULT hr = CoInitialize(NULL);
  643. int rc;
  644. {
  645. HMODULE hModule = GetModuleHandleA("MSVCR100.dll");
  646. if (hModule) {
  647. typedef char *(*f_setlocale)(int, const char*);
  648. f_setlocale f = (f_setlocale)GetProcAddress(hModule, "setlocale");
  649. (*f)(LC_ALL, "chs");
  650. }
  651. }
  652. if (SUCCEEDED(hr)) {
  653. PaError Error;
  654. Error = Pa_Initialize();
  655. if (Error == paNoError) {
  656. rc = videoframework_init();
  657. if (rc != 0) {
  658. Dbg("videoframework_init failed, rc=%d", rc);
  659. return Error_Resource;
  660. }
  661. } else {
  662. Dbg("PaInitialize failed, rc=%d", Error);
  663. return Error_Resource;
  664. }
  665. } else {
  666. Dbg("coinitialze failed! hr:%d", hr);
  667. return Error_Resource;
  668. }
  669. {
  670. int i, n;
  671. n = videocap_get_device_count();
  672. for (i = 0; i < n; ++i) {
  673. WCHAR tmp[256];
  674. char t[256];
  675. WCHAR tmp1[256];
  676. char t1[256];
  677. videocap_get_device_name(i, tmp, ARRAYSIZE(tmp));
  678. WideCharToMultiByte(CP_ACP, 0, tmp, -1, t, sizeof(t), 0, NULL);
  679. videocap_get_device_path(i, tmp1, ARRAYSIZE(tmp1));
  680. WideCharToMultiByte(CP_ACP, 0, tmp1, -1, t1, sizeof(t1), 0, NULL);
  681. {
  682. unsigned char x[MD5_DIGESTSIZE];
  683. md5_ctx_t ctx;
  684. md5_init(&ctx);
  685. md5(x, t1, strlen(t1));
  686. Bin2Str(x, sizeof(x), t1, sizeof(t1));
  687. }
  688. Dbg("%d = %s;%s", i, t, t1);
  689. }
  690. }
  691. {
  692. int icnt, ocnt;
  693. rc = ews_audio_get_dev_count(&icnt, &ocnt);
  694. if (rc == 0) {
  695. int i;
  696. Dbg("audio input devices(%d):", icnt);
  697. for (i = 0; i < icnt; ++i) {
  698. CSimpleStringA str = ews_audio_get_dev_name(true, i);
  699. Dbg("%d = %s", i, (LPCSTR)str);
  700. }
  701. Dbg("audio output devices(%d):", ocnt);
  702. for (i = 0; i < ocnt; ++i) {
  703. CSimpleStringA str = ews_audio_get_dev_name(false, i);
  704. Dbg("%d = %s", i, (LPCSTR)str);
  705. }
  706. }
  707. }
  708. return Error_Succeed;
  709. }
  710. void ews_capture_lib_term()
  711. {
  712. videoframework_term();
  713. Pa_Terminate();
  714. CoUninitialize();
  715. }
  716. int ews_capture_get_audio_device_id( bool in_direction, const char *dev_name )
  717. {
  718. int cnt = Pa_GetDeviceCount();
  719. int ii, i;
  720. for (i = 0, ii = 0; i < cnt; ++i) {
  721. const PaDeviceInfo *info = Pa_GetDeviceInfo(i);
  722. if (in_direction) {
  723. if (info->maxInputChannels) {
  724. if (strstr(info->name, dev_name) != NULL) {
  725. return ii;
  726. }
  727. ii++;
  728. }
  729. } else {
  730. if (info->maxOutputChannels) {
  731. if (strstr(info->name, dev_name) != NULL) {
  732. return ii;
  733. }
  734. ii++;
  735. }
  736. }
  737. }
  738. return -1;
  739. }
  740. //int ews_capture_get_video_device_id( const char *dev_name )
  741. //{
  742. // int i, n;
  743. //
  744. // n = videocap_get_device_count();
  745. // for (i = 0; i < n; ++i) {
  746. // WCHAR tmp[256];
  747. // char t[256];
  748. // WCHAR tmp1[256];
  749. // char t1[256];
  750. // videocap_get_device_name(i, tmp, ARRAYSIZE(tmp));
  751. // WideCharToMultiByte(CP_ACP, 0, tmp, -1, t, sizeof(t), 0, NULL);
  752. // videocap_get_device_path(i, tmp1, ARRAYSIZE(tmp1));
  753. // WideCharToMultiByte(CP_ACP, 0, tmp1, -1, t1, sizeof(t1), 0, NULL);
  754. // {
  755. // unsigned char x[MD5_DIGESTSIZE];
  756. // md5_ctx_t ctx;
  757. // md5_init(&ctx);
  758. // md5(x, t1, strlen(t1));
  759. // Bin2Str(x, sizeof(x), t1, sizeof(t1));
  760. // }
  761. // strcat(t, ";");
  762. // strcat(t, t1);
  763. // if (strcmp(dev_name, t) == 0)
  764. // return i;
  765. // }
  766. // return -1; // not found
  767. //}
  768. int ews_capture_get_video_device_id(const char *dev_inst_path, CSimpleStringA &ews_name)
  769. {
  770. int i, n;
  771. n = videocap_get_device_count();
  772. for (i = 0; i < n; ++i) {
  773. WCHAR tmp1[256];
  774. char t1[256];
  775. videocap_get_device_path(i, tmp1, ARRAYSIZE(tmp1));
  776. WideCharToMultiByte(CP_ACP, 0, tmp1, -1, t1, sizeof(t1), 0, NULL);
  777. // save DevicePath
  778. for (int j = 0; j < strlen(t1); ++j)
  779. {
  780. t1[j] = toupper(t1[j]);
  781. if (t1[j] == '#') t1[j] = '\\';
  782. }
  783. if (strstr(t1,dev_inst_path) != NULL)
  784. {
  785. WCHAR tmp[256]={0};
  786. char t[256]={0};
  787. videocap_get_device_name(i, tmp, ARRAYSIZE(tmp));
  788. WideCharToMultiByte(CP_ACP, 0, tmp, -1, t, sizeof(t), 0, NULL);
  789. ews_name = t;
  790. Dbg("matched ews camera device: [%d] %s.", i, t1);
  791. return i;
  792. }
  793. else{
  794. WCHAR tmp[256] = {0};
  795. char t[256] = {0};
  796. videocap_get_device_name(i, tmp, ARRAYSIZE(tmp));
  797. WideCharToMultiByte(CP_ACP, 0, tmp, -1, t, sizeof(t), 0, NULL);
  798. Dbg("device list: [%d] %s.", i, t1);
  799. }
  800. }
  801. return -1; // not found
  802. }
  803. bool ews_capture_check_video_device_match( const char *dev_name, const char*dev_inst_path )
  804. {
  805. int i, n;
  806. n = videocap_get_device_count();
  807. for (i = 0; i < n; ++i) {
  808. WCHAR tmp[256];
  809. char t[256];
  810. WCHAR tmp1[256];
  811. char t1[256];
  812. videocap_get_device_name(i, tmp, ARRAYSIZE(tmp));
  813. WideCharToMultiByte(CP_ACP, 0, tmp, -1, t, sizeof(t), 0, NULL);
  814. videocap_get_device_path(i, tmp1, ARRAYSIZE(tmp1));
  815. WideCharToMultiByte(CP_ACP, 0, tmp1, -1, t1, sizeof(t1), 0, NULL);
  816. // save DevicePath (add by ly at 20160725)
  817. char t2[256];
  818. strcpy(t2,t1);
  819. for (int j = 0; j < strlen(t2); ++j)
  820. {
  821. t2[j] = toupper(t2[j]);
  822. if (t2[j] == '#') t2[j] = '\\';
  823. }
  824. {
  825. unsigned char x[MD5_DIGESTSIZE];
  826. md5_ctx_t ctx;
  827. md5_init(&ctx);
  828. md5(x, t1, strlen(t1));
  829. Bin2Str(x, sizeof(x), t1, sizeof(t1));
  830. }
  831. strcat(t, ";");
  832. strcat(t, t1);
  833. if (strstr(t2,dev_inst_path) != NULL)
  834. {
  835. Dbg("[dbg] %s founded in %d cameras.", dev_inst_path, n);
  836. if (strcmp(dev_name, t) == 0)
  837. return true;
  838. }
  839. }
  840. return false; // not match
  841. }
  842. bool ews_capture_adj_brightness( ews_capture_t *cap,int nvalue,ErrorCodeEnum nCode )
  843. {
  844. HRESULT rst = S_OK;
  845. if (cap->video&&(nCode!=Error_EwsCamera)&&(nCode!=Error_AllCamera))
  846. {
  847. rst = videocap_adj_brightness(cap->video->cap,nvalue);
  848. }
  849. if (SUCCEEDED(rst))
  850. return true;
  851. return false;
  852. }
  853. bool ews_capture_set_autobrightness( ews_capture_t *cap,ErrorCodeEnum nCode )
  854. {
  855. HRESULT rst = S_OK;
  856. if (cap->video&&(nCode!=Error_EwsCamera)&&(nCode!=Error_AllCamera))
  857. {
  858. rst = videocap_set_autobrightness(cap->video->cap);
  859. }
  860. if (SUCCEEDED(rst))
  861. return true;
  862. return false;
  863. }
  864. int ews_capture_get_brightness( ews_capture_t *cap,ErrorCodeEnum nCode )
  865. {
  866. int nValue=0;
  867. HRESULT rst = S_OK;
  868. if (cap->video&&(nCode!=Error_EwsCamera)&&(nCode!=Error_AllCamera))
  869. {
  870. HRESULT rst = videocap_get_brightness(cap->video->cap,&nValue);
  871. }
  872. else
  873. {
  874. return -1;
  875. }
  876. if (SUCCEEDED(rst))
  877. {
  878. return nValue;
  879. }
  880. else
  881. {
  882. return -1;
  883. }
  884. }
  885. int ews_stop_camera( ews_capture_t *cap )
  886. {
  887. if (cap->video)
  888. {
  889. ews_video_capture_stop(cap->video);
  890. ews_video_capture_destroy(cap->video);
  891. cap->video = NULL;
  892. return 0;
  893. }
  894. else
  895. {
  896. return -1;
  897. }
  898. }
  899. int get_external_camera_exception_message(char* pBuffer, size_t uLen, CSimpleStringA strDeviceName, const char* strErrorMessage)
  900. {
  901. int iRet = 0;
  902. if (strDeviceName.GetLength() > 0){
  903. const char* strCameraName = strDeviceName.GetData();
  904. char strBuffer[MAX_PATH] = {0};
  905. if (sprintf_s(strBuffer, MAX_PATH, "%s", strCameraName) > 0){
  906. char *pIndex = NULL;
  907. if (pIndex = (char*)strstr(strBuffer, ";")){
  908. *pIndex = '\0';
  909. }
  910. }
  911. if (NULL != strErrorMessage){
  912. size_t uDataLen = strlen(strBuffer);
  913. size_t uErrorLen = strlen(strErrorMessage);
  914. if (uLen > uDataLen + uErrorLen + 10){
  915. iRet = sprintf_s(pBuffer, uLen, "[%s] %s", strBuffer, strErrorMessage);
  916. }
  917. }
  918. }
  919. if (0 == iRet){
  920. if (NULL != strErrorMessage){
  921. iRet = sprintf_s(pBuffer, uLen, "%s", strErrorMessage);
  922. }
  923. }
  924. return iRet;
  925. }