#include "capture.h" #ifdef RVC_OS_WIN #include "stdafx.h" #include #include #include #include "videohorflip.h" #include #include "video_common/ffmpeg_api_cpp_adapter.h" #else #include "imediadeviceinfo.h" #include #endif // RVC_OS_WIN #include #include #include "y2k_time.h" #include "Event.h" using namespace MediaController; #ifndef av_always_inline #define av_always_inline __inline #endif // !av_always_inline #ifndef inline #define inline __inline #endif // !inline #ifndef RVC_AUDIO_BUFFER_LEN #define RVC_AUDIO_BUFFER_LEN 320 #endif #ifdef RVC_OS_WIN static void __dbg(const char *fmt, va_list arg) { int n = vsnprintf(NULL, 0, fmt, arg); if (n >= MAX_PATH) { char* buf = (char*)malloc((size_t)(n + 1)); vsnprintf(buf, n + 1, fmt, arg); DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("%s", buf); free(buf); } else{ char strlog[MAX_PATH] = {0}; vsnprintf(strlog, MAX_PATH, fmt, arg); DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("%s", strlog); } } #endif static void __logevent(int ilogtype, int idevid, const char* strmessage) { if (0 == ilogtype){ LogWarn(Severity_Low, Error_Debug, LOG_EVT_MEDIACONTROLLER_CAMERA_MATCHED_FORMAT, strmessage); } else if(1 == ilogtype){ LogWarn(Severity_Low, Error_Debug, LOG_EVT_MEDIACONTROLLER_CAMERA_OUTPUT_FORMAT, strmessage); } else if (2 == ilogtype) { LogWarn(Severity_Low, Error_Debug, LOG_EVT_MEDIACONTROLLER_CAMOPEN_FAILED_INFO, strmessage); } else if (3 == ilogtype) { LogEvent(Severity_Middle, LOG_EVT_MEDIACONTROLLER_NOMATCHED_RESOLUTION, CSimpleStringA::Format("%d", idevid).GetData()); } else{ DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("unknown type event."); } } static int Bin2Str(unsigned char *x, int xlen, char *str, int str_size) { static const char *hex2char = "0123456789ABCDEF"; int i, k = 0; if (str_size <= xlen * 2) return -1; for (i = 0; i < xlen; ++i) { int h = x[i] >> 4; int l = x[i] & 0xf; str[k++] = hex2char[h]; str[k++] = hex2char[l]; } str[k] = 0; return k; } #ifdef RVC_OS_LINUX static void __audiomgrlog(void* user_data, const char* fmt, va_list arg) { int n = vsnprintf(NULL, 0, fmt, arg); if (n >= MAX_PATH) { char* buf = (char*)malloc((size_t)(n + 1)); vsnprintf(buf, n + 1, fmt, arg); DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("%s", buf); free(buf); } else { char strlog[MAX_PATH] = { 0 }; vsnprintf(strlog, MAX_PATH, fmt, arg); DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("%s", strlog); } } #endif #ifdef RVC_OS_WIN static int translate_id(bool in_direction, int idx) { int i, n, ii; n = Pa_GetDeviceCount(); for (i = 0, ii = 0; i < n; ++i) { const PaDeviceInfo* info = Pa_GetDeviceInfo(i); if (in_direction) { if (info->maxInputChannels) { if (ii == idx) { return i; } ii++; } } else { if (info->maxOutputChannels) { if (ii == idx) { return i; } ii++; } } } return -1; } static int audio_get_dev_count(int* in_cnt, int* out_cnt) { int icnt = 0, ocnt = 0; int cnt = Pa_GetDeviceCount(); for (int i = 0; i < cnt; ++i) { const PaDeviceInfo* info = Pa_GetDeviceInfo(i); if (info->maxInputChannels) icnt++; if (info->maxOutputChannels) ocnt++; } if (in_cnt) *in_cnt = icnt; if (out_cnt) *out_cnt = ocnt; return 0; } static CSimpleStringA audio_get_dev_name(bool in_direction, int idx) { int cnt = Pa_GetDeviceCount(); int ii, i; for (i = 0, ii = 0; i < cnt; ++i) { const PaDeviceInfo* info = Pa_GetDeviceInfo(i); if (in_direction) { if (info->maxInputChannels) { if (idx == ii) { CSimpleStringA strInDevice = CSimpleStringA(info->name); return strInDevice; } ii++; } } else { if (info->maxOutputChannels) { if (idx == ii) { CSimpleStringA strOutDevice = CSimpleStringA(info->name); return strOutDevice; } ii++; } } } return CSimpleStringA(); } int capture_get_audio_device_id(bool in_direction, const char* dev_name) { if (NULL == dev_name) { return -1; } int cnt = Pa_GetDeviceCount(); int ii, i; for (i = 0, ii = 0; i < cnt; ++i) { const PaDeviceInfo* info = Pa_GetDeviceInfo(i); if (in_direction) { if (info->maxInputChannels) { if (strstr(info->name, dev_name) != NULL) { return ii; } ii++; } } else { if (info->maxOutputChannels) { if (strstr(info->name, dev_name) != NULL) { return ii; } ii++; } } } return -1; } static int StreamCallback(const void *input, void *output, unsigned long frameCount, const PaStreamCallbackTimeInfo* timeInfo, PaStreamCallbackFlags statusFlags, void *userData) { audio_capture_t *audio_cap = (audio_capture_t*)userData; if (input) { audio_frame frm; frm.bitspersample = 16; frm.format = 1; frm.data = (char*)const_cast(input); frm.framesize = frameCount << 1; frm.nchannels = 1; frm.samplespersec = CAPTURE_CLOCK; if (INT_MAX == audio_cap->iseriesnumber++) { audio_cap->iseriesnumber = 0; } frm.iseriesnumber = audio_cap->iseriesnumber; int unowtime = y2k_time_now(); if (!audio_cap->shm_queue->InsertAudio(&frm, unowtime)) { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("[StreamCallback] InsertAudio to shm_queue failed! frameCount:%d", frameCount); } //else { // DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("%s:%d InsertAudio to shm_queue success! and framesize is :%d, and shm_queue length is %d, frm.iseriesnumber = %d, and now time is %d.", __FUNCTION__, __LINE__, frm.framesize, audio_cap->shm_queue->GetAudioLens(), frm.iseriesnumber, unowtime); //} if (!audio_cap->salesol_shm_queue->InsertAudio(&frm)) { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("[StreamCallback] InsertAudio to salesol_shm_queue failed! frameCount:%d", frameCount); } //else { // DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("%s:%d InsertAudio to salesol_shm_queue success! and framesize is :%d, and salesol_shm_queue length is %d, frm.iseriesnumber = %d.", __FUNCTION__, __LINE__, frm.framesize, audio_cap->salesol_shm_queue->GetAudioLens(), frm.iseriesnumber); //} } if (output) { memset(output, 0, frameCount<<1); } return paContinue; } static int Sales_StreamCallback(const void *input, void *output, unsigned long frameCount, const PaStreamCallbackTimeInfo* timeInfo, PaStreamCallbackFlags statusFlags, void *userData) { rvc_audio_capture_t *audio_cap = (rvc_audio_capture_t*)userData; if ((NULL != audio_cap) && (NULL != audio_cap->audio_shm_queue) && (NULL != input)){ audio_frame frm; frm.bitspersample = 16; frm.format = 1; frm.data = (char*)const_cast(input); frm.framesize = frameCount << 1; frm.nchannels = 1; frm.samplespersec = audio_cap->iaudio_capture_samplerate; if (INT_MAX == audio_cap->iseriesnumber++){ audio_cap->iseriesnumber = 0; } frm.iseriesnumber = audio_cap->iseriesnumber; if (!audio_cap->audio_shm_queue->InsertAudio(&frm)) { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("[Sales_StreamCallback] InsertAudio failed! frameCount:%d", frameCount); } //else { // DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("%s:%d InsertAudio to audio_shm_queue success! and framesize is :%d, and shm_queue length is %d, frm.iseriesnumber = %d.", __FUNCTION__, __LINE__, frm.framesize, audio_cap->audio_shm_queue->GetAudioLens(), frm.iseriesnumber); //} } if (output) { memset(output, 0, frameCount<<1); } return paContinue; } static int portaudio_capture_start(audio_capture_t* audio_cap) { capture_t *cap = audio_cap->parent; PaStreamParameters inParam = {0}; PaStreamParameters salesInParam = {0}; PaStreamParameters outParam = {0}; PaError paError; const PaDeviceInfo *info; int nId = capture_get_audio_device_id(true, cap->config.strAudioIn.GetData()); if (nId == -1) { LogWarn(Severity_Middle, Error_Debug,ERROR_MOD_MEDIACONTROLLER_HANDFREEIN_INITFAIL,"hand free in device config error,please check"); return Error_AudioIN; } int in_dev_id = translate_id(true, nId); if (in_dev_id < 0) { DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("audio in device translate failed!"); return Error_AudioIN; } info = Pa_GetDeviceInfo(in_dev_id); if (!info) { DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("get device info failed!"); return Error_AudioIN; } inParam.channelCount = 1; inParam.device = in_dev_id; inParam.suggestedLatency = info->defaultLowInputLatency; inParam.sampleFormat = paInt16; inParam.hostApiSpecificStreamInfo = NULL; if (Pa_IsFormatSupported(&inParam, NULL, CAPTURE_CLOCK) != paNoError) { DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("audio capture create error, cannot open audio input device"); return Error_AudioIN; } nId = capture_get_audio_device_id(false, cap->config.strAudioOut.GetData()); if (nId == -1) { LogWarn(Severity_Middle, Error_Debug,ERROR_MOD_MEDIACONTROLLER_HANDFREEOUT_INITFAIL,"hand free out device config error,please check"); return Error_AudioOut; } int out_dev_id = translate_id(false, nId); if (out_dev_id < 0) { DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("audio out device translate failed!"); return Error_AudioOut; } info = Pa_GetDeviceInfo(out_dev_id); if (!info) { DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("get device info failed!"); return Error_AudioOut; } outParam.channelCount = 1; outParam.device = out_dev_id; outParam.suggestedLatency = info->defaultLowOutputLatency; outParam.sampleFormat = paInt16; outParam.hostApiSpecificStreamInfo = NULL; if (Pa_IsFormatSupported(NULL, &outParam, CAPTURE_CLOCK) != paNoError) { DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("audio capture create error, cannot open audio input device"); return Error_AudioOut; } paError = Pa_OpenStream(&audio_cap->stream, &inParam, NULL, CAPTURE_CLOCK, CAPTURE_FRAME_TIME * CAPTURE_CLOCK/1000, paClipOff|paDitherOff, &StreamCallback, audio_cap); if (paError != paNoError) { DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("port audio open stream failed! paError = %d", paError); return Error_AudioIN; } paError = Pa_StartStream(audio_cap->stream); if (paError != paNoError) { DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("port audio start stream failed! paError = %d", paError); return Error_AudioIN; } return Error_Succeed; } static void portaudio_capture_stop(audio_capture_t* audio_cap) { if (audio_cap->stream) { Pa_AbortStream(audio_cap->stream); Pa_CloseStream(audio_cap->stream); audio_cap->stream = NULL; } } static int record_portaudio_capture_start(rvc_audio_capture_t* audio_cap) { rvc_sales_audio_capture_t* cap = audio_cap->parent; PaStreamParameters salesInParam = { 0 }; PaError paError; const PaDeviceInfo* info; int nId = capture_get_audio_device_id(true, cap->rvc_audio_config.strAudioIn.GetData()); if (nId == -1) { LogWarn(Severity_Middle, Error_Debug,ERROR_MOD_MEDIACONTROLLER_HANDFREEIN_INITFAIL,"hand free in device config error,please check"); return Error_AudioIN; } int in_dev_id = translate_id(true, nId); if (in_dev_id < 0) { DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("sales audio in device translate failed!"); return Error_AudioIN; } info = Pa_GetDeviceInfo(in_dev_id); if (!info) { DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("get device info failed!"); return Error_AudioIN; } salesInParam.channelCount = 1; salesInParam.device = in_dev_id; salesInParam.suggestedLatency = info->defaultLowInputLatency; salesInParam.sampleFormat = paInt16; salesInParam.hostApiSpecificStreamInfo = NULL; if (Pa_IsFormatSupported(&salesInParam, NULL, audio_cap->iaudio_capture_samplerate) != paNoError) { DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("sales audio capture create error, cannot open audio input device, and current capture sample rate is %d.",audio_cap->iaudio_capture_samplerate); return Error_AudioIN; } paError = Pa_OpenStream(&audio_cap->stream, &salesInParam, NULL, audio_cap->iaudio_capture_samplerate, audio_cap->iaudio_capture_peroid * audio_cap->iaudio_capture_samplerate/1000, paClipOff|paDitherOff, &Sales_StreamCallback, audio_cap); if (paError != paNoError) { DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("port audio open sales stream failed! paError = %d", paError); return Error_AudioIN; } paError = Pa_StartStream(audio_cap->stream); if (paError != paNoError) { DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("port audio start sales stream failed! paError = %d", paError); return Error_AudioIN; } return Error_Succeed; } static void record_portaudio_capture_stop(rvc_audio_capture_t* audio_cap) { if (NULL != audio_cap) { if (audio_cap->stream) { PaError Error = Pa_AbortStream(audio_cap->stream); if (paNoError != Error) { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("Pa_AbortStream error."); } Error = Pa_CloseStream(audio_cap->stream); if (paNoError != Error) { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("Pa_CloseStream error."); } audio_cap->stream = NULL; } audio_cap->iseriesnumber = 0; } } #else static void audio_data_callback(const void* input, unsigned long audiolen, void* userdata) { audio_capture_t* audio_cap = (audio_capture_t*)userdata; if (input) { int ileft = audiolen; int index = 0; while (audio_cap->uaudiolen + ileft >= RVC_AUDIO_BUFFER_LEN) { int ineed = RVC_AUDIO_BUFFER_LEN - audio_cap->uaudiolen; memcpy(audio_cap->paudio_buffer + audio_cap->uaudiolen, input + index, ineed); ileft -= ineed; audio_cap->uaudiolen += ineed; index += ineed; audio_frame frm; frm.bitspersample = 16; frm.format = 1; frm.data = audio_cap->paudio_buffer; frm.framesize = RVC_AUDIO_BUFFER_LEN; frm.nchannels = 1; frm.samplespersec = 8000; if (INT_MAX == audio_cap->iseriesnumber++) { audio_cap->iseriesnumber = 0; } frm.iseriesnumber = audio_cap->iseriesnumber; int unowtime = y2k_time_now(); if (!audio_cap->shm_queue->InsertAudio(&frm, unowtime)) { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("%s:%d InsertAudio to shm_queue failed!", __FUNCTION__, __LINE__); } //else { // DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("%s:%d InsertAudio to shm_queue success! and framesize is :%d, and shm_queue length is %d, frm.iseriesnumber = %d, and now time is %d.", __FUNCTION__, __LINE__, frm.framesize, audio_cap->shm_queue->GetAudioLens(), frm.iseriesnumber, unowtime); //} audio_cap->uaudiolen -= RVC_AUDIO_BUFFER_LEN; } if (ileft > 0){ memcpy(audio_cap->paudio_buffer + audio_cap->uaudiolen, input + index, ileft); audio_cap->uaudiolen += ileft; } } return; } static int pulseaudio_capture_start(audio_capture_t* audio_cap) { int iret = -1; capture_t* cap = audio_cap->parent; if (NULL != audio_cap->paudiocap){ audiocap_param_t param = { 0 }; int nId = audio_cap->paudiocap->audio_get_device_id(cap->config.strAudioIn.GetData(), true); if (nId == -1) { LogWarn(Severity_Middle, Error_Debug, ERROR_MOD_MEDIACONTROLLER_HANDFREEIN_INITFAIL, "hand free in device config error,please check"); return Error_AudioIN; } param.ideviceid = nId; param.ichannels = 1; param.isampleformat = 3 /*PA_SAMPLE_S16LE*/; param.isamprate = 8000; param.flatency = 0.02; param.on_audio_callback = &audio_data_callback; param.user_data = audio_cap; audio_cap->paudiocap->set_audio_capture_params(¶m); iret = audio_cap->paudiocap->start_audio_capture(); } return iret; } static void pulseaudio_capture_stop(audio_capture_t* audio_cap) { if (audio_cap->paudiocap) { audio_cap->paudiocap->stop_audio_capture(); } } static void record_audio_data_callback(const void* input, unsigned long audiolen, void* userdata) { rvc_audio_capture_t* audio_cap = (rvc_audio_capture_t*)userdata; if (input) { int ileft = audiolen; int index = 0; while (audio_cap->uaudiolen + ileft >= RVC_AUDIO_BUFFER_LEN) { int ineed = RVC_AUDIO_BUFFER_LEN - audio_cap->uaudiolen; memcpy(audio_cap->paudio_buffer + audio_cap->uaudiolen, input + index, ineed); ileft -= ineed; audio_cap->uaudiolen += ineed; index += ineed; audio_frame frm; frm.bitspersample = 16; frm.format = 1; frm.data = audio_cap->paudio_buffer; frm.framesize = RVC_AUDIO_BUFFER_LEN; frm.nchannels = 1; frm.samplespersec = 8000; frm.iseriesnumber = audio_cap->iseriesnumber++; if (audio_cap->iseriesnumber >= INT_MAX) { audio_cap->iseriesnumber = 0; } if (!audio_cap->audio_shm_queue->InsertAudio(&frm)) { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("%s:%d InsertAudio to audio_shm_queue failed!", __FUNCTION__, __LINE__); } //else { // DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("%s:%d InsertAudio to audio_shm_queue success!", __FUNCTION__, __LINE__); //} audio_cap->uaudiolen -= RVC_AUDIO_BUFFER_LEN; } if (ileft > 0) { memcpy(audio_cap->paudio_buffer + audio_cap->uaudiolen, input + index, ileft); audio_cap->uaudiolen += ileft; } } return; } static int record_pulseaudio_capture_start(rvc_audio_capture_t* audio_cap) { int iret = -1; rvc_sales_audio_capture_t* cap = audio_cap->parent; if (NULL != audio_cap->paudiocap) { audiocap_param_t param = { 0 }; int nId = audio_cap->paudiocap->audio_get_device_id(cap->rvc_audio_config.strAudioIn.GetData(), true); if (nId == -1){ LogWarn(Severity_Middle, Error_Debug, ERROR_MOD_MEDIACONTROLLER_HANDFREEIN_INITFAIL, "hand free in device config error,please check"); return Error_AudioIN; } param.ideviceid = nId; param.ichannels = 1; param.isampleformat = 3 /*PA_SAMPLE_S16LE*/; param.isamprate = 8000; param.flatency = 0.02; param.on_audio_callback = &record_audio_data_callback; param.user_data = audio_cap; audio_cap->paudiocap->set_audio_capture_params(¶m); iret = audio_cap->paudiocap->start_audio_capture(); } return iret; } static void record_pulseaudio_capture_stop(rvc_audio_capture_t* audio_cap) { if (audio_cap->paudiocap) { audio_cap->paudiocap->stop_audio_capture(); } } #endif static rvc_audio_capture_t *salesrecord_audio_capture_create(rvc_sales_audio_capture_t *cap) { rvc_audio_capture_t *audio_cap = ZALLOC_T(rvc_audio_capture_t); if (audio_cap) { audio_cap->parent = cap; audio_cap->audio_shm_queue = new Clibaudioqueue(REC_COMMON_AUDIO_SALES_SHM_QUEUE); //audio_cap->remote_audio_queue = new Clibaudioqueue(REC_COMMON_REMOTEAUDIO_SHM_QUEUE); audio_cap->iseriesnumber = 0; } #ifdef RVC_OS_LINUX audio_cap->paudio_buffer = new char[RVC_AUDIO_BUFFER_LEN]; audio_cap->uaudiolen = 0; #endif return audio_cap; } static void salesrecord_audio_capture_destroy(rvc_audio_capture_t *audio_cap) { if (NULL != audio_cap){ if (NULL != audio_cap->audio_shm_queue){ delete audio_cap->audio_shm_queue; audio_cap->audio_shm_queue = NULL; } #ifdef RVC_OS_LINUX if (NULL != audio_cap->paudio_buffer){ delete audio_cap->paudio_buffer; audio_cap->paudio_buffer = NULL; audio_cap->uaudiolen = 0; } #endif FREE(audio_cap); } } static audio_capture_t *audio_capture_create(capture_t *cap) { audio_capture_t *audio_cap = ZALLOC_T(audio_capture_t); if (audio_cap) { audio_cap->parent = cap; audio_cap->shm_queue = new Clibaudioqueue(REC_COMMON_AUDIO_SHM_QUEUE); audio_cap->salesol_shm_queue = new Clibaudioqueue(REC_COMMON_AUDIO_SALESOL_SHM_QUEUE); audio_cap->iseriesnumber = 0; #ifdef RVC_OS_LINUX audio_cap->paudio_buffer = new char[RVC_AUDIO_BUFFER_LEN]; audio_cap->uaudiolen = 0; #endif } return audio_cap; } static void audio_capture_destroy(audio_capture_t *audio_cap) { delete audio_cap->shm_queue; audio_cap->shm_queue = NULL; delete audio_cap->salesol_shm_queue; audio_cap->salesol_shm_queue = NULL; #ifdef RVC_OS_LINUX if (NULL != audio_cap->paudio_buffer) { delete audio_cap->paudio_buffer; audio_cap->paudio_buffer = NULL; audio_cap->uaudiolen = 0; } #endif FREE(audio_cap); } static int audio_capture_start(audio_capture_t* audio_cap) { #ifdef RVC_OS_WIN return portaudio_capture_start(audio_cap); #else return pulseaudio_capture_start(audio_cap); #endif } static void audio_capture_stop(audio_capture_t* audio_cap) { #ifdef RVC_OS_WIN return portaudio_capture_stop(audio_cap); #else return pulseaudio_capture_stop(audio_cap); #endif } static int record_audio_capture_start(rvc_audio_capture_t* audio_cap) { #ifdef RVC_OS_WIN return record_portaudio_capture_start(audio_cap); #else return record_pulseaudio_capture_start(audio_cap); #endif } static void record_audio_capture_stop(rvc_audio_capture_t* audio_cap) { #ifdef RVC_OS_WIN return record_portaudio_capture_stop(audio_cap); #else return record_pulseaudio_capture_stop(audio_cap); #endif } static int calc_capture_mode(int width, int height, int *mode) { const struct { int mode; int width; int height; } modes [] = { {VIDEOCAP_FRAME_SQCIF, VIDEOCAP_SQCIF_WIDTH, VIDEOCAP_SQCIF_HEIGHT}, {VIDEOCAP_FRAME_QQVGA, VIDEOCAP_QQVGA_WIDTH, VIDEOCAP_QQVGA_HEIGHT}, {VIDEOCAP_FRAME_QCIF, VIDEOCAP_QCIF_WIDTH, VIDEOCAP_QCIF_HEIGHT}, {VIDEOCAP_FRAME_QVGA, VIDEOCAP_QVGA_WIDTH, VIDEOCAP_QVGA_HEIGHT}, {VIDEOCAP_FRAME_CIF, VIDEOCAP_CIF_WIDTH, VIDEOCAP_CIF_HEIGHT}, {VIDEOCAP_FRAME_VGA, VIDEOCAP_VGA_WIDTH, VIDEOCAP_VGA_HEIGHT}, {VIDEOCAP_FRAME_4CIF, VIDEOCAP_4CIF_WIDTH, VIDEOCAP_4CIF_HEIGHT}, {VIDEOCAP_FRAME_SVGA, VIDEOCAP_SVGA_WIDTH, VIDEOCAP_SVGA_HEIGHT}, {VIDEOCAP_FRAME_NHD, VIDEOCAP_NHD_WIDTH, VIDEOCAP_NHD_HEIGHT}, {VIDEOCAP_FRAME_SXGA, VIDEOCAP_SXGA_WIDTH, VIDEOCAP_SXGA_HEIGHT}, {VIDEOCAP_FRAME_720P, VIDEOCAP_720P_WIDTH, VIDEOCAP_720P_HEIGHT}, {VIDEOCAP_FRAME_1080P, VIDEOCAP_1080P_WIDTH, VIDEOCAP_1080P_HEIGHT}, }; int i; for (i = 0; i < array_size(modes); ++i) { if (modes[i].width == width && modes[i].height == height) { *mode = modes[i].mode; return 0; } } return Error_NotExist; } static int video_shm_enqueue(Clibvideoqueue *shm_queue, video_frame *frame, unsigned int ucaptime, int flags, int iframeid) { videoq_frame tmp_frm; tmp_frm.data = frame->data[0]; if (VIDEO_FORMAT_RGB24 == frame->format){ tmp_frm.framesize = frame->width * frame->height * 3; tmp_frm.format = VIDEOQ_FORMAT_RGB24; } else { tmp_frm.framesize = frame->width * frame->height * 3/2; tmp_frm.format = VIDEOQ_FORMAT_I420; } tmp_frm.width = frame->width; tmp_frm.height = frame->height; tmp_frm.iframeid = iframeid; //unsigned int nowtime = y2k_time_now(); if (!shm_queue->InsertVideo(&tmp_frm, flags, ucaptime)) { DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("caution: insert shm video failed!"); return Error_Unexpect; } else { //DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("insert shm video ok, and video frame id is %d.", tmp_frm.iframeid); return Error_Succeed; } } static void env_cap_on_frame(void *user_data, video_frame *frame) { video_capture_t *video_cap = (video_capture_t *)user_data; capture_t *cap = video_cap->parent; int rc; video_cap->frame_id++; video_cap->ulastcaptime = y2k_time_now(); //DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("******************* env on frame, id=%d, ulastcaptime=%u", video_cap->frame_id, video_cap->ulastcaptime); //IplImage*img = NULL; //img = cvCreateImage(cvSize(frame->width,frame->height),IPL_DEPTH_8U,3); //img->imageData = (char*)frame->data[0]; //cvSaveImage("./env.jpg", img, 0); //cvReleaseImageHeader(&img); rc = video_shm_enqueue(video_cap->snapshot_shm_queue, frame, video_cap->ulastcaptime, VIDEOQUEUE_FLAG_VERTICAL_FLIP, video_cap->frame_id); //static int isnapshot_shm_queue = 0; //if (isnapshot_shm_queue == 0) { // video_frame_save_bmpfile("snapshot_shm_queue_1.bmp", frame); // isnapshot_shm_queue++; //} #ifdef DEVOPS_ON_PRD #else #ifdef RVC_OS_WIN #else static int isnapshot_count = 0; if (video_cap->bsavephoto) { if ((video_cap->isaveinterval > 0) && (0 == video_cap->frame_id % (video_cap->isaveinterval * cap->config.video_env_fps))) { char strFileName[3 * MAX_PATH] = { 0 }; snprintf(strFileName, 3 * MAX_PATH, "%s%s_%d%s", video_cap->strsavedir, video_cap->strphotoname, isnapshot_count++, ".bmp"); video_frame_save_bmpfile(strFileName, frame); } } else { isnapshot_count = 0; } #endif #endif if (rc != Error_Succeed) { DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("env snapshot queue enqueue failed! Error = %d, camera_type=%d.", rc, video_cap->camera_type); } else { //DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("env snapshot queue enqueue[%d] success and camera_type=%d.", video_cap->frame_id, video_cap->camera_type); } // snapshot if (rc==Error_Succeed) { if (*cap->config.ref_env_capture_count) { #ifdef RVC_OS_WIN InterlockedDecrement(cap->config.ref_env_capture_count); #else pthread_mutex_lock(cap->config.env_mutex); *(cap->config.ref_env_capture_count) -= 1; pthread_mutex_unlock(cap->config.env_mutex); #endif LogEvent(Severity_Middle, MOD_EVENT_MEDIACONTROLLER_FINISHED_CAPTURE_ENV, "agent capture env ok, and capture env finished!"); } else if (*cap->config.ref_envopt_capture_count & 2) { #ifdef RVC_OS_WIN _InterlockedAnd(cap->config.ref_envopt_capture_count, 0xfffffffD); #else pthread_mutex_lock(cap->config.envopt_mutex); LONG lcount = *(cap->config.ref_envopt_capture_count); *(cap->config.ref_envopt_capture_count) = (lcount & 0xfffffffD); pthread_mutex_unlock(cap->config.envopt_mutex); #endif // RVC_OS_WIN if (*cap->config.ref_envopt_capture_count == 0) { LogEvent(Severity_Middle, MOD_EVENT_MEDIACONTROLLER_FINISHED_CAPTURE_ENVOPT, "agent capture env ok, and capture env opt finished!"); } } } // preview { video_frame preview_frame; video_frame_alloc(REC_COMMON_VIDEO_PREVIEW_WIDTH, REC_COMMON_VIDEO_PREVIEW_HEIGHT, VIDEO_FORMAT_RGB24, &preview_frame); uint8_t *src_data[4] = {frame->data[0] + 80*3, 0, 0, 0}; sws_scale(video_cap->preview_sws_ctx, src_data, frame->linesize, 0, frame->height, preview_frame.data, preview_frame.linesize); video_shm_enqueue(video_cap->preview_shm_queue, &preview_frame, video_cap->ulastcaptime, 0, video_cap->frame_id); if (rc != Error_Succeed){ DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("env preview_shm_queue enqueue failed, error = %d", rc); } else { //if (0 == video_cap->frame_id%10){ //DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("env preview_shm_queue enqueue[%d] success, and current video queue len is %d.", video_cap->frame_id, video_cap->preview_shm_queue->GetVideoLens()); //} } video_frame_free(&preview_frame); //static int ipreview_shm_queue = 0; //char strname[MAX_PATH] = { 0 }; //snprintf(strname, MAX_PATH, "env_preview_shm_queue_%d.bmp", ipreview_shm_queue++); //video_frame_save_bmpfile(strname, &preview_frame); } // rtp { video_frame rtp_frame; video_frame_alloc(REC_COMMON_VIDEO_RTP_ENV_WIDTH, REC_COMMON_VIDEO_RTP_ENV_HEIGHT, VIDEO_FORMAT_RGB24, &rtp_frame); uint8_t *src_data[4] = {frame->data[0] + (frame->height-1) * frame->linesize[0], 0, 0, 0}; int src_linesize[4] = {-frame->linesize[0], 0, 0, 0}; sws_scale(video_cap->rtp_sws_ctx, src_data, src_linesize, 0, frame->height, rtp_frame.data, rtp_frame.linesize); video_shm_enqueue(video_cap->rtp_shm_queue, &rtp_frame, video_cap->ulastcaptime, 0, video_cap->frame_id); if (rc != Error_Succeed) { DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("env rtp_shm_queue enqueue failed! Error = %d", rc); } else { //DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("env rtp_shm_queue enqueue[%d] success, and current video queue len is %d.", video_cap->frame_id, video_cap->rtp_shm_queue->GetVideoLens()); } //static int irtp_frame = 0; //if (irtp_frame == 0){ // video_frame_save_bmpfile("rtp_shm_queue.bmp", &rtp_frame); // irtp_frame++; //} #if 0 static int i = 0; if (i == 0) { video_frame tmp_frame; video_frame_alloc(REC_COMMON_VIDEO_RTP_ENV_WIDTH, REC_COMMON_VIDEO_RTP_ENV_HEIGHT, VIDEO_FORMAT_RGB24, &tmp_frame); video_frame_fill_black(&tmp_frame); videoq_frame frm; frm.data = tmp_frame.data[0]; video_cap->rtp_shm_queue->GetVideo(&frm, 0); video_frame_save_bmpfile("rtp_videoqueue_abc.bmp", &tmp_frame); video_frame_free(&tmp_frame); //video_frame_save_bmpfile("d:\\ab.bmp", &rtp_frame); i++; } #endif video_frame_free(&rtp_frame); } } static void opt_cap_on_frame(void *user_data, video_frame *frame) { video_capture_t *video_cap = (video_capture_t *)user_data; capture_t *cap = video_cap->parent; int rc; int rotate = 0; //DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("opt on frame!"); if (cap->config.video_opt_rotate == 90) { rotate = 1; } else if (cap->config.video_opt_rotate == 270) { rotate = -1; } else { //DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("video_opt_rotate is not 90 or 270 return."); return; } video_cap->frame_id++; video_cap->ulastcaptime = y2k_time_now(); #ifdef RVC_OS_WIN // use IPP, it's fast // prepare for rotation video_frame rframe; video_frame_alloc(frame->height, frame->width, frame->format, &rframe); { IppiSize srcSize; srcSize.width = frame->width; srcSize.height = frame->height; IppiRect srcROI; srcROI.width = frame->width; srcROI.height = frame->height; srcROI.x = 0; srcROI.y = 0; IppiRect dstROI; dstROI.width = frame->height; dstROI.height = frame->width; dstROI.x = 0; dstROI.y = 0; ippiTranspose_8u_C3R(frame->data[0], frame->linesize[0], rframe.data[0], rframe.linesize[0], srcSize); IppiAxis flip; IppiSize Size; Size.width = rframe.width; Size.height = rframe.height; if (rotate == 1) { flip = ippAxsHorizontal; ippiMirror_8u_C3IR(rframe.data[0], rframe.linesize[0], Size, flip); } else { flip = ippAxsVertical; ippiMirror_8u_C3IR(rframe.data[0], rframe.linesize[0], Size, flip); } } rc = video_shm_enqueue(video_cap->snapshot_shm_queue, &rframe, video_cap->ulastcaptime, 0, video_cap->frame_id); #else rc = video_shm_enqueue(video_cap->snapshot_shm_queue, frame, video_cap->ulastcaptime, 0, video_cap->frame_id); #endif if (rc != Error_Succeed) { DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("opt snapshot queue enqueue shm failed! Error = %d, camera_type=%d", rc, video_cap->camera_type); } else { //DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("opt snapshot queue enqueue[%d] success, and current video queue len is %d.", video_cap->frame_id, video_cap->snapshot_shm_queue->GetVideoLens()); } //static int isnapshot_shm_queue = 0; //if (isnapshot_shm_queue == 0) { // video_frame_save_bmpfile("opt_snapshot_shm_queue.bmp", &rframe); // isnapshot_shm_queue++; //} // snapshot if (rc==Error_Succeed) { if (*cap->config.ref_opt_capture_count) { #ifdef RVC_OS_WIN InterlockedDecrement(cap->config.ref_opt_capture_count); #else pthread_mutex_lock(cap->config.opt_mutex); *(cap->config.ref_opt_capture_count) -= 1; pthread_mutex_unlock(cap->config.opt_mutex); #endif LogEvent(Severity_Middle, MOD_EVENT_MEDIACONTROLLER_FINISHED_CAPTURE_OPT, "agent capture opt ok, and capture opt finished!"); } else if (*cap->config.ref_envopt_capture_count&1) { #ifdef RVC_OS_WIN if (InterlockedDecrement(cap->config.ref_envopt_capture_count) == 0) #else pthread_mutex_lock(cap->config.envopt_mutex); *(cap->config.ref_envopt_capture_count) -= 1; pthread_mutex_unlock(cap->config.envopt_mutex); if (0 == *cap->config.ref_envopt_capture_count) #endif { LogEvent(Severity_Middle, MOD_EVENT_MEDIACONTROLLER_FINISHED_CAPTURE_ENVOPT, "agent capture opt ok, and capture envopt finished!"); } } } // rtp { video_frame rtp_frame = {0}; video_frame_alloc(REC_COMMON_VIDEO_RTP_OPT_WIDTH, REC_COMMON_VIDEO_RTP_OPT_HEIGHT, VIDEO_FORMAT_RGB24, &rtp_frame); #ifdef RVC_OS_WIN sws_scale(video_cap->rtp_sws_ctx, rframe.data, rframe.linesize, 0, rframe.height, rtp_frame.data, rtp_frame.linesize); #else sws_scale(video_cap->rtp_sws_ctx, frame->data, frame->linesize, 0, frame->height, rtp_frame.data, rtp_frame.linesize); #endif rc = video_shm_enqueue(video_cap->rtp_shm_queue, &rtp_frame, video_cap->ulastcaptime, 0, video_cap->frame_id); if (rc != Error_Succeed){ DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("opt rtp_shm_queue enqueue shm failed! Error = %d, camera_type=%d", rc, video_cap->camera_type); } //static int irtp_frame = 0; //if (irtp_frame == 0){ // video_frame_save_bmpfile("opt_rtp_shm_queue.bmp", &rtp_frame); // irtp_frame++; //} video_frame_free(&rtp_frame); } // preview { video_frame preview_frame; video_frame_alloc(REC_COMMON_VIDEO_PREVIEW_HEIGHT, REC_COMMON_VIDEO_PREVIEW_WIDTH, VIDEO_FORMAT_RGB24, &preview_frame); #ifdef RVC_OS_WIN uint8_t *src_data[4] = {rframe.data[0] + rframe.linesize[0]*80, 0, 0, 0}; sws_scale(video_cap->preview_sws_ctx, src_data, rframe.linesize, 0, REC_COMMON_VIDEO_SNAPSHOT_PREVIEW_WIDTH, preview_frame.data, preview_frame.linesize); #else uint8_t* src_data[4] = { frame->data[0] + frame->linesize[0] * 80, 0, 0, 0 }; sws_scale(video_cap->preview_sws_ctx, src_data, frame->linesize, 0, REC_COMMON_VIDEO_SNAPSHOT_PREVIEW_WIDTH, preview_frame.data, preview_frame.linesize); #endif video_shm_enqueue(video_cap->preview_shm_queue, &preview_frame, video_cap->ulastcaptime, 1, video_cap->frame_id); //static int ipreview_shm_queue = 0; //char strname[MAX_PATH] = { 0 }; //snprintf(strname, MAX_PATH, "opt_preview_shm_queue_%d.bmp", ipreview_shm_queue++); //video_frame_save_bmpfile(strname, &preview_frame); video_frame_free(&preview_frame); } #ifdef RVC_OS_WIN video_frame_free(&rframe); #endif } static video_capture_t *video_capture_create(capture_t *cap, int camera_type) { video_capture_t *video_cap = ZALLOC_T(video_capture_t); if (video_cap) { video_cap->parent = cap; video_cap->camera_type = camera_type; video_cap->frame_id = 0; #ifdef DEVOPS_ON_PRD #else #ifdef RVC_OS_WIN #else video_cap->bsavephoto = false; memset(video_cap->strsavedir, 0, MAX_PATH); memset(video_cap->strphotoname, 0, MAX_PATH); video_cap->isaveinterval = 0; #endif #endif if (camera_type == CAMERA_TYPE_ENV) { video_cap->snapshot_shm_queue = new Clibvideoqueue(REC_COMMON_VIDEO_ENV_SHM_SNAPSHOT_QUEUE); video_cap->rtp_shm_queue = new Clibvideoqueue(REC_COMMON_VIDEO_ENV_SHM_RTP_QUEUE); video_cap->rtp_sws_ctx = sws_getContext(REC_COMMON_VIDEO_SNAPSHOT_WIDTH, REC_COMMON_VIDEO_SNAPSHOT_HEIGHT, AV_PIX_FMT_BGR24, REC_COMMON_VIDEO_RTP_ENV_WIDTH, REC_COMMON_VIDEO_RTP_ENV_HEIGHT, AV_PIX_FMT_BGR24, SWS_POINT, NULL, NULL, NULL); video_cap->preview_shm_queue = new Clibvideoqueue(REC_COMMON_VIDEO_ENV_SHM_PREVIEW_QUEUE); video_cap->preview_sws_ctx = sws_getContext(REC_COMMON_VIDEO_SNAPSHOT_PREVIEW_WIDTH, REC_COMMON_VIDEO_SNAPSHOT_PREVIEW_HEIGHT, AV_PIX_FMT_BGR24, REC_COMMON_VIDEO_PREVIEW_WIDTH, REC_COMMON_VIDEO_PREVIEW_HEIGHT, AV_PIX_FMT_BGR24, SWS_FAST_BILINEAR, NULL, NULL, NULL); } else { video_cap->snapshot_shm_queue = new Clibvideoqueue(REC_COMMON_VIDEO_OPT_SHM_SNAPSHOT_QUEUE); video_cap->rtp_shm_queue = new Clibvideoqueue(REC_COMMON_VIDEO_OPT_SHM_RTP_QUEUE); video_cap->rtp_sws_ctx = sws_getContext(REC_COMMON_VIDEO_SNAPSHOT_HEIGHT, REC_COMMON_VIDEO_SNAPSHOT_WIDTH, AV_PIX_FMT_BGR24, REC_COMMON_VIDEO_RTP_OPT_WIDTH, REC_COMMON_VIDEO_RTP_OPT_HEIGHT, AV_PIX_FMT_BGR24, SWS_POINT, NULL, NULL, NULL); video_cap->preview_shm_queue = new Clibvideoqueue(REC_COMMON_VIDEO_OPT_SHM_PREVIEW_QUEUE); video_cap->preview_sws_ctx = sws_getContext(REC_COMMON_VIDEO_SNAPSHOT_PREVIEW_HEIGHT, REC_COMMON_VIDEO_SNAPSHOT_PREVIEW_WIDTH, AV_PIX_FMT_BGR24, REC_COMMON_VIDEO_PREVIEW_HEIGHT, REC_COMMON_VIDEO_PREVIEW_WIDTH, AV_PIX_FMT_BGR24, SWS_FAST_BILINEAR, NULL, NULL, NULL); } } return video_cap; } static void video_capture_destroy(video_capture_t *video_cap) { if (video_cap) { if (video_cap->preview_sws_ctx) { sws_freeContext(video_cap->preview_sws_ctx); video_cap->preview_sws_ctx = NULL; } if (video_cap->rtp_sws_ctx) { sws_freeContext(video_cap->rtp_sws_ctx); video_cap->rtp_sws_ctx = NULL; } if (video_cap->snapshot_shm_queue) { delete video_cap->snapshot_shm_queue; video_cap->snapshot_shm_queue = NULL; } if (video_cap->rtp_shm_queue) { delete video_cap->rtp_shm_queue; video_cap->rtp_shm_queue = NULL; } if (video_cap->preview_shm_queue) { delete video_cap->preview_shm_queue; video_cap->preview_shm_queue = NULL; } FREE(video_cap); } } #ifdef RVC_OS_WIN #else static int get_video_capture_fps(int icapfps) { int ifps = REC_COMMON_VIDEO_RAW_FPS; if (icapfps <=30 && icapfps >=5){ ifps = icapfps; } return ifps; } #endif #ifdef RVC_OS_WIN static int video_capture_start_win(video_capture_t* video_cap) { if (NULL == video_cap) { return -1; } capture_config_t *conf = &video_cap->parent->config; if (NULL == conf) { return -1; } int dev_id; if (video_cap->camera_type == CAMERA_TYPE_ENV){ dev_id = capture_get_video_device_id(conf->strVideoEnv); if (dev_id == -1) { DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("No environment camera,please check config file or device!"); return -1; } } else{ dev_id = capture_get_video_device_id(conf->strVideoOpt); if (dev_id == -1) { DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("No operation camera,please check config file or device!"); return -1; } } videocap_param param = {0}; int cap_mode; int rc = -1; rc = calc_capture_mode(REC_COMMON_VIDEO_SNAPSHOT_WIDTH, REC_COMMON_VIDEO_SNAPSHOT_HEIGHT, &cap_mode); if (rc != 0) { DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("calc cap_mode failed!"); return rc; } param.cap_mode = cap_mode; param.dev_id = dev_id; param.frame_fmt = VIDEO_FORMAT_RGB24; param.cap_frame_format = VIDEO_FORMAT_YUY2; param.fps = REC_COMMON_VIDEO_RAW_FPS; param.on_frame = (video_cap->camera_type == CAMERA_TYPE_ENV ? &env_cap_on_frame : &opt_cap_on_frame); param.user_data = video_cap; param.option = 0; param.dbg = &__dbg; param.logevent = &__logevent; rc = videocap_create(&video_cap->cap, ¶m); if (rc != 0) { DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("videocap create failed!"); return rc; } rc = videocap_start(video_cap->cap); if (rc != 0) { DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("videocap start failed!"); videocap_destroy(video_cap->cap); video_cap->cap = NULL; return rc; } return 0; } #else static void __videocaplog(void* user_data, const char* fmt, va_list arg) { int n = vsnprintf(NULL, 0, fmt, arg); if (n >= MAX_PATH) { char* buf = (char*)malloc((size_t)(n + 1)); vsnprintf(buf, n + 1, fmt, arg); DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("%s", buf); free(buf); } else { char strlog[MAX_PATH] = { 0 }; vsnprintf(strlog, MAX_PATH, fmt, arg); DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("%s", strlog); } } static int video_capture_start_linux(video_capture_t* video_cap) { int iret = -1; capture_config_t* conf = &video_cap->parent->config; int dev_id = -1; if (video_cap->camera_type == CAMERA_TYPE_ENV){ dev_id = rvc_videocap_get_video_device_id(conf->strVideoEnv.GetData()); if (-1 == dev_id){ DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("No environment camera[%s], please check config file or device!", conf->strVideoEnv.GetData()); return iret; } } else{ dev_id = rvc_videocap_get_video_device_id(conf->strVideoOpt.GetData()); if (-1 == dev_id){ DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("No operation camera[%s], please check config file or device!", conf->strVideoOpt.GetData()); return iret; } } videocap_param_t t_param = { 0 }; int cap_mode; int rc = calc_capture_mode(REC_COMMON_VIDEO_SNAPSHOT_WIDTH, REC_COMMON_VIDEO_SNAPSHOT_HEIGHT, &cap_mode); if (rc != 0){ DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("calc cap_mode failed!"); return iret; } t_param.cap_mode = cap_mode; t_param.dev_id = dev_id; t_param.frame_fmt = VIDEO_FORMAT_RGB24; t_param.fps = get_video_capture_fps(video_cap->camera_type == CAMERA_TYPE_ENV ? conf->video_env_fps : conf->video_opt_fps); t_param.irotate = (video_cap->camera_type == CAMERA_TYPE_ENV ? conf->video_env_rotate : conf->video_opt_rotate); t_param.on_frame = (video_cap->camera_type == CAMERA_TYPE_ENV ? &env_cap_on_frame : &opt_cap_on_frame); //t_param.on_frame_i420 = (video_cap->camera_type == CAMERA_TYPE_ENV ? &env_cap_on_frame_i420 : &opt_cap_on_frame_i420); t_param.user_data = video_cap; t_param.option = 0; videocap_callback_t t_callback = { 0 }; t_callback.debug = &__videocaplog; t_callback.logevent = &__logevent; video_cap->pVideoCap = CreateVideoCaptureObj(&t_callback); if (NULL != video_cap->pVideoCap){ if (0 == video_cap->pVideoCap->VideoCaptureSetParam(&t_param)) { if (0 == video_cap->pVideoCap->StartVideoCapture()) { iret = 0; } else { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("VideoCap Start Video Capture failed!"); DestroyVideoCaptureObj(video_cap->pVideoCap); video_cap->pVideoCap = NULL; } } else { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("VideoCap Set Video Capture Param failed!"); DestroyVideoCaptureObj(video_cap->pVideoCap); video_cap->pVideoCap = NULL; } } else{ DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)(" Create Video Capture Obj failed!"); } return iret; } #endif // RVC_OS_WIN static int video_capture_start(video_capture_t *video_cap) { #ifdef RVC_OS_WIN return video_capture_start_win(video_cap); #else return video_capture_start_linux(video_cap); #endif } static void video_capture_stop(video_capture_t *video_cap) { #ifdef RVC_OS_WIN if (video_cap->cap) { videocap_stop(video_cap->cap); videocap_destroy(video_cap->cap); video_cap->cap = NULL; } #else if (video_cap->pVideoCap) { video_cap->pVideoCap->StopVideoCapture(); DestroyVideoCaptureObj(video_cap->pVideoCap); video_cap->pVideoCap = NULL; } #endif // RVC_OS_WIN } namespace MediaController { DeviceTypeEnum g_eDeviceType; int capture_create(const capture_config_t *config, capture_t **p_cap, bool bstartaudio) { capture_t *cap = ZALLOC_T(capture_t); cap->handfree_audio = NULL; cap->env_video = NULL; cap->opt_video = NULL; memcpy(&cap->config, config, sizeof(capture_config_t)); if (bstartaudio) { cap->handfree_audio = audio_capture_create(cap); if (!cap->handfree_audio) { DbgWithLink(LOG_LEVEL_ERROR, LOG_TYPE_SYSTEM)("create handfree audio capture object failed!"); return Error_Unexpect; } } int dev_id_env = capture_get_video_device_id(config->strVideoEnv); if (dev_id_env != -1) { cap->env_video = video_capture_create(cap, CAMERA_TYPE_ENV); if (!cap->env_video) { DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("create env video object failed!"); return Error_Unexpect; } } int dev_id_opt = -1; if (eStand2sType == g_eDeviceType){ dev_id_opt = capture_get_video_device_id(config->strVideoOpt); } if (dev_id_opt != -1){ cap->opt_video = video_capture_create(cap, CAMERA_TYPE_OPT); if (!cap->opt_video) { DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("create opt video object failed!"); return Error_Unexpect; } } if((dev_id_env == -1)&&(dev_id_opt == -1)){ DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("all camera device id error!"); capture_destroy(cap); return Error_AllCamera; } else{ *p_cap = cap; return Error_Succeed; } } ErrorCodeEnum capture_create(const capture_config_t *config, capture_t *cap, int nCamera) { int dev_id1 = capture_get_video_device_id(config->strVideoEnv); int dev_id2 = capture_get_video_device_id(config->strVideoOpt); if((dev_id1 != -1)&&(nCamera==ENVCAMERA)&&(cap->env_video == NULL)){ cap->env_video = video_capture_create(cap, CAMERA_TYPE_ENV); if (!cap->env_video){ DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("create env video object failed!"); return Error_Unexpect; } } else if((dev_id2 != -1)&&(nCamera == OPTCAMERA)&&(cap->opt_video == NULL)){ cap->opt_video = video_capture_create(cap, CAMERA_TYPE_OPT); if (!cap->opt_video) { DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("create opt video object failed!"); return Error_Unexpect; } } else{ return Error_Unexpect; } return Error_Succeed; } int salesaudio_capture_create(rvc_audio_capture_config_t *config, rvc_sales_audio_capture_t **p_cap) { rvc_sales_audio_capture_t *cap = ZALLOC_T(rvc_sales_audio_capture_t); cap->rvc_audio = NULL; memcpy(&cap->rvc_audio_config, config, sizeof(rvc_audio_capture_config_t)); cap->rvc_audio = salesrecord_audio_capture_create(cap); if (!cap->rvc_audio) { DbgWithLink(LOG_LEVEL_ERROR, LOG_TYPE_SYSTEM)("create sales record audio capture object failed!"); salesaudio_capture_destroy(cap); cap = NULL; return Error_Unexpect; } else { cap->rvc_audio->iaudio_capture_peroid = config->audio_capture_period; cap->rvc_audio->iaudio_capture_samplerate = config->audio_capture_samplerate; *p_cap = cap; return 0; } } void salesaudio_capture_destroy(rvc_sales_audio_capture_t *cap) { if (NULL != cap){ if (cap->rvc_audio) { salesrecord_audio_capture_destroy(cap->rvc_audio); cap->rvc_audio = NULL; } FREE(cap); } } void capture_destroy(capture_t *cap) { if (cap) { if (cap->env_video) { video_capture_destroy(cap->env_video); cap->env_video = NULL; } if (cap->opt_video) { video_capture_destroy(cap->opt_video); cap->opt_video = NULL; } if (cap->handfree_audio) { audio_capture_destroy(cap->handfree_audio); cap->handfree_audio = NULL; } FREE(cap); } } void capture_destroy(capture_t *cap,int nCamera) { if (cap) { if((cap->env_video)&&(nCamera == ENVCAMERA)) { video_capture_destroy(cap->env_video); cap->env_video = NULL; } else if((cap->opt_video)&&(nCamera==OPTCAMERA)) { video_capture_destroy(cap->opt_video); cap->opt_video = NULL; } } } ErrorCodeEnum start_audio_capture(audio_capture_t *paudio) { ErrorCodeEnum rslt = Error_Succeed; int rc = 0; if (NULL != paudio) { rc = audio_capture_start(paudio); if (rc != Error_Succeed) { rslt = (ErrorCodeEnum)rc; if (rslt == Error_AudioIN){ DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("start audio In object failed! rc:%d", rc); LogWarn(Severity_Middle, Error_Debug,ERROR_MOD_MEDIACONTROLLER_HANDFREE_OPENFAIL,"open audioIn device fail,please check device"); } else{ DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("start audio Out object failed! rc:%d", rc); LogWarn(Severity_Middle, Error_Debug,ERROR_MOD_MEDIACONTROLLER_HANDFREE_OPENFAIL,"open audioOut device fail,please check device"); } } } else{ rslt = Error_AudioIN; } return rslt; } static ErrorCodeEnum capture_start_envopt(capture_t *cap) { int rc = 0; if (cap->env_video) { rc = video_capture_start(cap->env_video); if (rc != Error_Succeed) { cap->env_video->ustarttime = 0; char strMessage[MAX_PATH*2] = {0}; get_camera_exception_message(strMessage, MAX_PATH*2, cap->config.strVideoEnv, "open environ camera fail, please check device."); LogWarn(Severity_Middle,Error_NotInit,ERROR_MOD_MEDIACONTROLLER_ENVCAM_OPEN,strMessage); if (cap->opt_video) { if (cap->env_video) { rvc_sleep(cap->config.uintervaltime); } rc = video_capture_start(cap->opt_video); if (rc != Error_Succeed) { cap->opt_video->ustarttime = 0; char stroptMessage[MAX_PATH*2] = {0}; get_camera_exception_message(stroptMessage, MAX_PATH*2, cap->config.strVideoOpt, "open operate camera fail, please check device."); LogWarn(Severity_Middle,Error_NotInit,ERROR_MOD_MEDIACONTROLLER_OPTCAM_OPEN, stroptMessage); return Error_AllCamera; } else { cap->opt_video->ustarttime = y2k_time_now(); DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("start optcam success."); return Error_EnvCamera; } } else { DbgWithLink(LOG_LEVEL_ERROR, LOG_TYPE_SYSTEM)("start all video capture object failed!"); return Error_AllCamera; } } else { cap->env_video->ustarttime = y2k_time_now(); DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("start envcam success."); if (cap->opt_video) { if (cap->env_video) { rvc_sleep(cap->config.uintervaltime); } rc = video_capture_start(cap->opt_video); if (rc != Error_Succeed) { cap->opt_video->ustarttime = 0; char strMsg[MAX_PATH*2] = {0}; get_camera_exception_message(strMsg, MAX_PATH*2, cap->config.strVideoOpt, "open operate camera fail, please check device."); LogWarn(Severity_Middle,Error_NotInit,ERROR_MOD_MEDIACONTROLLER_OPTCAM_OPEN, strMsg); return Error_OptCamera; } else { cap->opt_video->ustarttime = y2k_time_now(); DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("start optcam success."); return Error_Succeed; } } else { return Error_OptCamera; } } } else { if (cap->opt_video) { if (cap->env_video) { rvc_sleep(cap->config.uintervaltime); } rc = video_capture_start(cap->opt_video); if (rc != Error_Succeed) { cap->opt_video->ustarttime = 0; char stroptMsg[MAX_PATH*2] = {0}; get_camera_exception_message(stroptMsg, MAX_PATH*2, cap->config.strVideoOpt, "open operate camera fail, please check device."); LogWarn(Severity_Middle,Error_NotInit,ERROR_MOD_MEDIACONTROLLER_OPTCAM_OPEN, stroptMsg); return Error_AllCamera; } else { cap->opt_video->ustarttime = y2k_time_now(); DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("start optcam success."); return Error_EnvCamera; } } else { DbgWithLink(LOG_LEVEL_ERROR, LOG_TYPE_SYSTEM)("start env video Error_AllCamera"); return Error_AllCamera; } } } ErrorCodeEnum capture_start(capture_t *cap, bool bstartaudio) { int rc = 0; if (bstartaudio) { if ('N' == cap->config.strAudioState[0] || 'P' == cap->config.strAudioState[0]) { ErrorCodeEnum rslt = start_audio_capture(cap->handfree_audio); if (Error_Succeed != rslt) { //return rslt; DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("start handfree audio capture failed!"); } } else { DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("handfree audio is error, not start it."); } } return capture_start_envopt(cap); } ErrorCodeEnum capture_start(capture_t *cap,int nCamera) { int rc = 0; if (cap->env_video&&(nCamera==ENVCAMERA)) { rc = video_capture_start(cap->env_video); if (rc != Error_Succeed) { cap->env_video->ustarttime = 0; return Error_Hardware; } else{ cap->env_video->ustarttime = y2k_time_now(); DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("start envcam success."); return Error_Succeed; } } else if(cap->opt_video&&(nCamera==OPTCAMERA)) { rc = video_capture_start(cap->opt_video); if (rc != Error_Succeed){ cap->opt_video->ustarttime = 0; return Error_Hardware; } else{ cap->opt_video->ustarttime = y2k_time_now(); DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("start optcam success."); return Error_Succeed; } } else{ return Error_Unexpect; } } ErrorCodeEnum salesrecord_audio_capture_start(rvc_sales_audio_capture_t *cap) { auto rc = Error_Param; if (NULL == cap){ return rc; } if (cap->rvc_audio) { #ifdef RVC_OS_LINUX audiomgr_callback_t t_callback = { 0 }; t_callback.debug = &__audiomgrlog; cap->rvc_audio->paudiocap = CreateAudioMgrObj(&t_callback); if (0 != cap->rvc_audio->paudiocap->audio_mgr_initialize()) { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("audio manager initialize failed!"); return Error_Null; } #endif int rslt = record_audio_capture_start(cap->rvc_audio); if (rslt != Error_Succeed) { if (Error_AudioIN == rslt){ DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("start audio In object failed! rc:%d", rc); LogWarn(Severity_Middle, Error_Debug,ERROR_MOD_MEDIACONTROLLER_HANDFREE_OPENFAIL,"open audioIn device fail,please check device"); } rc = (ErrorCodeEnum)rslt; } else{ rc = Error_Succeed; } } return rc; } void salesrecord_audio_capture_stop(rvc_sales_audio_capture_t *cap) { if (NULL != cap){ if (cap->rvc_audio){ record_audio_capture_stop(cap->rvc_audio); #ifdef RVC_OS_LINUX if (NULL != cap->rvc_audio->paudiocap) { DestroyIAudioMgrObj(cap->rvc_audio->paudiocap); cap->rvc_audio->paudiocap = NULL; } #endif // RVC_OS_LINUX } } else{ DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("sales record audio capture stop failed for param error."); } } void capture_stop(capture_t *cap) { if (cap->handfree_audio) { audio_capture_stop(cap->handfree_audio); } if (cap->env_video) { if (0 != cap->env_video->ustarttime) { int ienvtime = y2k_time_now() - cap->env_video->ustarttime; //LogWarn(Severity_Low, Error_Debug, LOG_EVT_MEDIACONTROLLER_ENVCAM_CLOSE, CSimpleStringA::Format("stop envcam, and camera open time is %us.", ienvtime).GetData()); if (ienvtime >= 1) { float fenvframerate = (float)((float)cap->env_video->frame_id / (float)ienvtime); DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("env camera frame info is dest frame number is %d(%us), real frame number is %d, difference is %d, real frmerate is %.2ffps.", ienvtime * cap->config.video_env_fps, ienvtime, cap->env_video->frame_id, ienvtime * cap->config.video_env_fps - cap->env_video->frame_id, fenvframerate); } } video_capture_stop(cap->env_video); } if (cap->opt_video) { if (0 != cap->opt_video->ustarttime) { int iopttime = y2k_time_now() - cap->opt_video->ustarttime; //LogWarn(Severity_Low, Error_Debug, LOG_EVT_MEDIACONTROLLER_OPTCAM_CLOSE, CSimpleStringA::Format("stop optcam, and camera open time is %us.", iopttime).GetData()); if (iopttime >= 1) { float foptframerate = (float)((float)cap->opt_video->frame_id / (float)iopttime); DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("opt camera frame info is dest frame number is %d(%us), real frame number is %d, difference is %d, real frmerate is %.2ffps.", iopttime * cap->config.video_opt_fps, iopttime, cap->opt_video->frame_id, iopttime * cap->config.video_opt_fps - cap->opt_video->frame_id, foptframerate); } } video_capture_stop(cap->opt_video); } } int capture_detect_camera_bug(capture_t *cap, int *env_n, int *opt_n, bool bsinglecam) { *env_n = 0; *opt_n = 0; if (cap->env_video) { if (cap->env_video->rtp_shm_queue) { *env_n = cap->env_video->rtp_shm_queue->GetVideoLens(); } } else { *env_n = -1; } if (cap->opt_video) { if (cap->opt_video->rtp_shm_queue) { *opt_n = cap->opt_video->rtp_shm_queue->GetVideoLens(); } } else { if (!bsinglecam) { *opt_n = -1; } else { *opt_n = 1; } } return 0; } int capture_get_last_audio_frametime(capture_t* cap, unsigned int* handfreein_n) { *handfreein_n = 0; if (cap->handfree_audio) { if (cap->handfree_audio->shm_queue) { *handfreein_n = cap->handfree_audio->shm_queue->GetLastFrameTime(); } } return 0; } //摄像头没打开返回0,其他情况返回视频队列中最后一幅图像时间 int capture_get_last_frametime(capture_t *cap, unsigned int*env_n, unsigned int*opt_n) { *env_n = 0; *opt_n = 0; if (cap->env_video) { if (cap->env_video->rtp_shm_queue) { *env_n = cap->env_video->rtp_shm_queue->GetLastFrameTime(); } } if (cap->opt_video) { if (cap->opt_video->rtp_shm_queue) { *opt_n = cap->opt_video->rtp_shm_queue->GetLastFrameTime(); } } return 0; } int capture_get_video_device_id(const char *dev_name) { #ifdef RVC_OS_WIN int n = videocap_get_device_count(); for (int i = 0; i < n; ++i) { WCHAR tmp[MAX_PATH] = {0}; char t[MAX_PATH] = { 0 }; WCHAR tmp1[MAX_PATH] = { 0 }; char t1[MAX_PATH] = { 0 }; videocap_get_device_name(i, tmp, ARRAYSIZE(tmp)); WideCharToMultiByte(CP_ACP, 0, tmp, -1, t, sizeof(t), 0, NULL); videocap_get_device_path(i, tmp1, ARRAYSIZE(tmp1)); WideCharToMultiByte(CP_ACP, 0, tmp1, -1, t1, sizeof(t1), 0, NULL); char t2[MAX_PATH] = {0}; strcpy(t2, t1); for (int j = 0; j < strlen(t2); ++j) { t2[j] = toupper(t2[j]); if (t2[j] == '#') t2[j] = '\\'; } { unsigned char x[MD5_DIGESTSIZE]; md5_ctx_t ctx; md5_init(&ctx); md5(x, t1, strlen(t1)); Bin2Str(x, sizeof(x), t1, sizeof(t1)); } if (dev_name != NULL && strlen(dev_name) > 1 && strstr(dev_name, ";") == NULL) { //DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("[dbg] device_path: %s",t2); if (strstr(t2,dev_name) != NULL) { return i; } if (strcmp(dev_name, t) == 0) { return i; } } else { strcat(t, ";"); strcat(t, t1); if (strcmp(dev_name, t) == 0) { return i; } } } return -1; // not found #else return rvc_videocap_get_video_device_id(dev_name); #endif // RVC_OS_WIN } int capture_lib_init(int *ivideonum) { int icamnum = 0; CSimpleStringA strCamInfoJson(""); CSimpleStringA strCamListInfoJson(""); cJSON* array = cJSON_CreateArray(); cJSON* root = cJSON_CreateObject(); #ifdef RVC_OS_WIN HRESULT hr = CoInitialize(NULL); int rc; { HMODULE hModule = GetModuleHandleA("MSVCR100.dll"); if (hModule) { typedef char* (*f_setlocale)(int, const char*); f_setlocale f = (f_setlocale)GetProcAddress(hModule, "setlocale"); (*f)(LC_ALL, "chs"); } } if (SUCCEEDED(hr)) { PaError Error; Error = Pa_Initialize(); if (Error == paNoError) { rc = videoframework_init(); if (rc != 0) { DbgWithLink(LOG_LEVEL_ERROR, LOG_TYPE_SYSTEM)("videoframework_init failed, rc=%d", rc); return Error_Resource; } } else { DbgWithLink(LOG_LEVEL_ERROR, LOG_TYPE_SYSTEM)("PaInitialize failed, rc=%d", Error); return Error_Resource; } } else { DbgWithLink(LOG_LEVEL_ERROR, LOG_TYPE_SYSTEM)("coinitialze failed! hr:%d", hr); return Error_Resource; } { icamnum = videocap_get_device_count(); //DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("camera count is %d.", icamnum); for (int i = 0; i < icamnum; ++i) { WCHAR tmp[MAX_PATH] = {0}; char t[MAX_PATH] = {0}; WCHAR tmp1[MAX_PATH] ={0}; char t1[MAX_PATH] = {0}; WCHAR tmp2[MAX_PATH] = { 0 }; char t2[MAX_PATH] = { 0 }; videocap_get_device_name(i, tmp, ARRAYSIZE(tmp)); WideCharToMultiByte(CP_ACP, 0, tmp, -1, t, sizeof(t), 0, NULL); videocap_get_device_path(i, tmp1, ARRAYSIZE(tmp1)); WideCharToMultiByte(CP_ACP, 0, tmp1, -1, t1, sizeof(t1), 0, NULL); //videocap_get_device_instanceid(i, tmp2, ARRAYSIZE(tmp2)); //WideCharToMultiByte(CP_ACP, 0, tmp2, -1, t2, sizeof(t2), 0, NULL); cJSON* pobject = cJSON_CreateObject(); cJSON_AddItemToObject(pobject, "DevicePath", cJSON_CreateString(t1)); cJSON_AddItemToObject(pobject, "DeviceInstanceId", cJSON_CreateString(t2)); cJSON_AddItemToObject(pobject, "FriendlyName", cJSON_CreateString(t)); cJSON_AddItemToArray(array, pobject); { unsigned char x[MD5_DIGESTSIZE] = {0}; md5_ctx_t ctx; md5_init(&ctx); md5(x, t1, strlen(t1)); Bin2Str(x, sizeof(x), t1, sizeof(t1)); } //DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("%d = %s;%s", i, t, t1); strCamInfoJson += CSimpleStringA::Format("\"%d\":\"%s;%s\",", i, t, t1); } } { int icnt, ocnt; rc = audio_get_dev_count(&icnt, &ocnt); if (rc == 0) { int i; DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("audio input devices(%d):", icnt); for (i = 0; i < icnt; ++i) { CSimpleStringA str = audio_get_dev_name(true, i); DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("%d = %s", i, str.GetData()); } DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("audio output devices(%d):", ocnt); for (i = 0; i < ocnt; ++i) { CSimpleStringA str = audio_get_dev_name(false, i); DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("%d = %s", i, str.GetData()); } } } #else { int inumber = 0; icamnum = rvc_videocap_get_device_count(); //DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("camera count is %d.", icamnum); for (int i = 0; i < 64 && inumber < icamnum; ++i) { char strcamera[2 * MAX_PATH] = { 0 }; char strpath[MAX_PATH] = { 0 }; if (0 == rvc_videocap_get_device_fullpathname(i, strcamera, 2 * MAX_PATH)){ DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("%d = %s", inumber, strcamera); strCamInfoJson += CSimpleStringA::Format("\"%d\":\"%s\",", inumber, strcamera); inumber++; rvc_camera_info_t pcamerainfo; memset(&pcamerainfo, 0, sizeof(rvc_camera_info_t)); if (0 == rvc_videocap_get_camera_infos(i, &pcamerainfo)) { cJSON* pobject = cJSON_CreateObject(); cJSON_AddItemToObject(pobject, "driver", cJSON_CreateString(pcamerainfo.strdriver)); cJSON_AddItemToObject(pobject, "card", cJSON_CreateString(pcamerainfo.strcard)); cJSON_AddItemToObject(pobject, "bus_info", cJSON_CreateString(pcamerainfo.strbus_info)); cJSON_AddItemToArray(array, pobject); } } } } #endif // RVC_OS_WIN if (icamnum > 0) { DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("camera number is %d.", icamnum); if (strCamInfoJson.GetLength() > 0) { strCamInfoJson[strCamInfoJson.GetLength() - 1] = '\0'; } LogWarn(Severity_Low, Error_Debug, LOG_EVT_MEDIACONTROLLER_GETCAMERA_INFOS, CSimpleStringA::Format("[{%s}]", strCamInfoJson.GetData()).GetData()); cJSON_AddItemToObject(root, "CameraDevInfo", array); char* pjsonstr = cJSON_PrintUnformatted(root); strCamListInfoJson = pjsonstr; cJSON_free(pjsonstr); DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_USER).setLogCode("QLR0402208V1").setAPI("RvcMedia_GetCameraDevInfo")(CSimpleStringA::Format("%s", strCamListInfoJson.GetData()).GetData()); } else { cJSON_Delete(array); DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_USER).setLogCode("QLR0402208V1").setResultCode("RTA280A")("获取摄像头列表失败,找不到摄像头"); } *ivideonum = icamnum; cJSON_Delete(root); return Error_Succeed; } void capture_lib_term() { #ifdef RVC_OS_WIN Pa_Terminate(); videoframework_term(); CoUninitialize(); #else #endif // RVC_OS_WIN } bool capture_adj_brightness(capture_t *cap,int nvalue,ErrorCodeEnum nCode) { #ifdef RVC_OS_WIN HRESULT rst = S_OK; if (cap && cap->env_video&&(nCode!=Error_EnvCamera)&&(nCode!=Error_AllCamera)) { rst = videocap_adj_brightness(cap->env_video->cap,nvalue); } HRESULT rst2 = S_OK; if (cap && cap->opt_video&&(nCode!=Error_OptCamera)&&(nCode!=Error_AllCamera)) { rst2 = videocap_adj_brightness(cap->opt_video->cap,nvalue); } if (SUCCEEDED(rst) && SUCCEEDED(rst2)) { return true; } else { return false; } #else int ienv = -1; if (cap && cap->env_video && cap->env_video->pVideoCap && (nCode != Error_EnvCamera) && (nCode != Error_AllCamera)){ ienv = cap->env_video->pVideoCap->SetCamBrightness(nvalue, false); } int iopt = -1; if (cap && cap->opt_video && cap->opt_video->pVideoCap && (nCode != Error_OptCamera) && (nCode != Error_AllCamera)){ iopt = cap->opt_video->pVideoCap->SetCamBrightness(nvalue, false); } if (0 == ienv && 0 == iopt){ return true; } else{ return false; } #endif // RVC_OS_WIN } bool capture_set_autobrightness(capture_t *cap,ErrorCodeEnum nCode) { #ifdef RVC_OS_WIN HRESULT rst = S_OK; HRESULT rst2 = S_OK; if (cap && cap->env_video && (nCode != Error_EnvCamera) && (nCode != Error_AllCamera)){ rst = videocap_set_autobrightness(cap->env_video->cap); } if (cap && cap->opt_video && (nCode != Error_OptCamera) && (nCode != Error_AllCamera)){ rst2 = videocap_set_autobrightness(cap->opt_video->cap); } if (SUCCEEDED(rst) && SUCCEEDED(rst2)) { return true; } else { return false; } #else int ienv = -1; int iopt = -1; if (cap && cap->env_video && cap->env_video->pVideoCap && (nCode != Error_EnvCamera) && (nCode != Error_AllCamera)) { ienv = cap->env_video->pVideoCap->SetCamAutoBrightness(); } if (cap && cap->opt_video && cap->opt_video->pVideoCap && (nCode != Error_OptCamera) && (nCode != Error_AllCamera)) { iopt = cap->opt_video->pVideoCap->SetCamAutoBrightness(); } if (0 == ienv && 0 == iopt) { return true; } else { return false; } #endif // RVC_OS_WIN } int capture_get_brightness(capture_t *cap, ErrorCodeEnum nCode) { #ifdef RVC_OS_WIN int nValue1 = 0; int nValue2 = 0; HRESULT rst = S_OK; if (cap && cap->env_video && (nCode != Error_EnvCamera) && (nCode != Error_AllCamera)) { rst = videocap_get_brightness(cap->env_video->cap, &nValue1); } HRESULT rst2 = S_OK; if (cap && cap->opt_video && (nCode != Error_OptCamera) && (nCode != Error_AllCamera)) { rst2 = videocap_get_brightness(cap->opt_video->cap, &nValue2); } else { return -1; } if (cap && (cap->opt_video == NULL) && cap->env_video) { return nValue1; } else if (cap && (cap->env_video == NULL) && cap->opt_video) { return nValue2; } else { if (SUCCEEDED(rst) && SUCCEEDED(rst2)) { return (nValue1 <= nValue2) ? nValue1 : nValue2; } else { return -1; } } #else int nValue1 = 0; int nValue2 = 0; int ienv = -1; if (cap && cap->env_video && cap->env_video->pVideoCap && (nCode != Error_EnvCamera) && (nCode != Error_AllCamera)){ ienv = cap->env_video->pVideoCap->GetCamBrightness(&nValue1, false); } int iopt = -1; if (cap && cap->opt_video && cap->opt_video->pVideoCap && (nCode != Error_OptCamera) && (nCode != Error_AllCamera)){ iopt = cap->opt_video->pVideoCap->GetCamBrightness(&nValue2, false); } else{ return -1; } if (cap && (cap->opt_video == NULL) && cap->env_video) { return nValue1; } else if (cap && (cap->env_video == NULL) && cap->opt_video) { return nValue2; } else { if (0 == ienv && 0 == iopt) { return (nValue1 <= nValue2) ? nValue1 : nValue2; } else { return -1; } } #endif // RVC_OS_WIN } int capture_get_camera_brightness(int* ibrightness, capture_t* cap, ErrorCodeEnum nCode, int icameraid) { int iret = -1; #ifdef RVC_OS_WIN if (0 == icameraid) { if (cap && cap->env_video && (nCode != Error_EnvCamera) && (nCode != Error_AllCamera)){ if (S_OK == videocap_get_brightness(cap->env_video->cap, ibrightness)) { iret = 0; } } } else if (1 == icameraid) { if (cap && cap->opt_video && (nCode != Error_OptCamera) && (nCode != Error_AllCamera)){ if (S_OK == videocap_get_brightness(cap->opt_video->cap, ibrightness)) { iret = 0; } } } #else if (0 == icameraid) { if (cap && cap->env_video && cap->env_video->pVideoCap && (nCode != Error_EnvCamera) && (nCode != Error_AllCamera)) { iret = cap->env_video->pVideoCap->GetCamBrightness(ibrightness, false); } } else if(1 == icameraid){ if (cap && cap->opt_video && cap->opt_video->pVideoCap && (nCode != Error_OptCamera) && (nCode != Error_AllCamera)) { iret = cap->opt_video->pVideoCap->GetCamBrightness(ibrightness, false); } } #endif // RVC_OS_WIN return iret; } int capture_set_camera_brightness(int ibrightness, capture_t* cap, ErrorCodeEnum nCode, int icameraid) { int iret = -1; #ifdef RVC_OS_WIN if (0 == icameraid) { if (cap && cap->env_video && (nCode != Error_EnvCamera) && (nCode != Error_AllCamera)){ if (S_OK == videocap_adj_brightness(cap->env_video->cap, ibrightness)) { iret = 0; } } } else if (1 == icameraid) { if (cap && cap->opt_video && (nCode != Error_OptCamera) && (nCode != Error_AllCamera)){ if (S_OK == videocap_adj_brightness(cap->opt_video->cap, ibrightness)) { iret = 0; } } } #else if (0 == icameraid) { if (cap && cap->env_video && cap->env_video->pVideoCap && (nCode != Error_EnvCamera) && (nCode != Error_AllCamera)) { iret = cap->env_video->pVideoCap->SetCamBrightness(ibrightness, false); } } else if (1 == icameraid) { if (cap && cap->opt_video && cap->opt_video->pVideoCap && (nCode != Error_OptCamera) && (nCode != Error_AllCamera)) { iret = cap->opt_video->pVideoCap->SetCamBrightness(ibrightness, false); } } #endif // RVC_OS_WIN return iret; } int capture_get_env_rawbrightnessinfo(capture_t* cap, ErrorCodeEnum nCode, int* imin, int* imax) { int iret = -1; #ifdef RVC_OS_WIN #else if (cap && cap->env_video && cap->env_video->pVideoCap && (nCode != Error_EnvCamera) && (nCode != Error_AllCamera)) { if (cap->env_video->pVideoCap->GetCamRawBrightnessRange(imin, imax)) { //DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("min brightness is %d, max brightness is %d.", *imin, *imax); iret = 0; } } #endif // RVC_OS_WIN return iret; } int capture_set_env_rawbrightness(capture_t* cap, ErrorCodeEnum nCode, int ibrightness) { int iret = -1; #ifdef RVC_OS_WIN #else if (cap && cap->env_video && cap->env_video->pVideoCap && (nCode != Error_EnvCamera) && (nCode != Error_AllCamera)) { if (0 == cap->env_video->pVideoCap->SetCamBrightness(ibrightness, true)) { iret = 0; } } #endif // RVC_OS_WIN return iret; } int stopcamera(capture_t *cap,int nCamera) { if((nCamera == ENVCAMERA)&&cap->env_video) { video_capture_stop(cap->env_video); if (0 != cap->env_video->ustarttime) { int ienvtime = y2k_time_now() - cap->env_video->ustarttime; //LogWarn(Severity_Low, Error_Debug, LOG_EVT_MEDIACONTROLLER_ENVCAM_CLOSE, CSimpleStringA::Format("stop envcam, and camera open time is %us.", ienvtime).GetData()); DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("env camera frame info is dest frame number is %d(%us), real frame number is %d, difference is %d.", ienvtime * cap->config.video_env_fps, ienvtime, cap->env_video->frame_id, ienvtime * cap->config.video_env_fps - cap->env_video->frame_id); } video_capture_destroy(cap->env_video); cap->env_video = NULL; return 0; } else if((nCamera == OPTCAMERA)&&cap->opt_video) { video_capture_stop(cap->opt_video); if (0 != cap->opt_video->ustarttime) { int iopttime = y2k_time_now() - cap->opt_video->ustarttime; //LogWarn(Severity_Low, Error_Debug, LOG_EVT_MEDIACONTROLLER_OPTCAM_CLOSE, CSimpleStringA::Format("stop optcam, and camera open time is %us.", iopttime).GetData()); DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("opt camera frame info is dest frame number is %d(%us), real frame number is %d, difference is %d.", iopttime * cap->config.video_opt_fps, iopttime, cap->opt_video->frame_id, iopttime * cap->config.video_opt_fps - cap->opt_video->frame_id); } video_capture_destroy(cap->opt_video); cap->opt_video = NULL; return 0; } else { return -1; } } void capture_clearsnapshotvideo(capture_t *cap,int nCamera) { if((nCamera == ENVCAMERA)&&cap->env_video) { cap->env_video->snapshot_shm_queue->ClearVideoQueue(); return; } else if((nCamera == OPTCAMERA)&&cap->opt_video) { cap->opt_video->snapshot_shm_queue->ClearVideoQueue(); return; } else if(nCamera == AlLCAMERA) { if (cap->env_video) { cap->env_video->snapshot_shm_queue->ClearVideoQueue(); } if (cap->opt_video) { cap->opt_video->snapshot_shm_queue->ClearVideoQueue(); } return; } else { return ; } } int get_camera_exception_message(char* pBuffer, size_t uLen, CSimpleStringA strDeviceName, const char* strErrorMessage) { int iRet = 0; if (strDeviceName.GetLength() > 0){ const char* strCameraName = strDeviceName.GetData(); char strBuffer[MAX_PATH] = {0}; if (snprintf(strBuffer, MAX_PATH, "%s", strCameraName) > 0){ char *pIndex = NULL; if (pIndex = (char*)strstr(strBuffer, ";")){ *pIndex = '\0'; } } if (NULL != strErrorMessage){ size_t uDataLen = strlen(strBuffer); size_t uErrorLen = strlen(strErrorMessage); if (uLen > uDataLen + uErrorLen + 10){ iRet = snprintf(pBuffer, uLen, "[%s] %s", strBuffer, strErrorMessage); } } } if (0 == iRet){ if (NULL != strErrorMessage){ iRet = snprintf(pBuffer, uLen, "%s", strErrorMessage); } } return iRet; } int capture_get_audio_device_list(bool in_direction, CSimpleStringA& strdevicelist) { int iret = 0; #ifdef RVC_OS_WIN int icnt = 0, ocnt = 0; int rc = audio_get_dev_count(&icnt, &ocnt); if (rc == 0) { strdevicelist = "["; if (in_direction) { iret = icnt; for (int i = 0; i < icnt; ++i) { CSimpleStringA str = CSimpleStringA::Format("\"%s\"", audio_get_dev_name(true, i).GetData()); if (i > 0) { strdevicelist += ","; } strdevicelist += str; } } else { iret = ocnt; for (int i = 0; i < ocnt; ++i) { CSimpleStringA str = CSimpleStringA::Format("\"%s\"",audio_get_dev_name(false, i).GetData()); if (i > 0) { strdevicelist += ","; } strdevicelist += str; } } strdevicelist += "]"; } #endif return iret; } int capture_get_video_device_list(CSimpleStringA& strdevicelist) { int icount = 0; #ifdef RVC_OS_WIN strdevicelist = "["; icount = videocap_get_device_count(); for (int i = 0; i < icount; ++i) { wchar_t tmp[MAX_PATH] = { 0 }; char t[MAX_PATH] = { 0 }; wchar_t tmp1[MAX_PATH] = { 0 }; char t1[MAX_PATH] = { 0 }; videocap_get_device_name(i, tmp, ARRAYSIZE(tmp)); WideCharToMultiByte(CP_ACP, 0, tmp, -1, t, sizeof(t), 0, NULL); videocap_get_device_path(i, tmp1, ARRAYSIZE(tmp1)); WideCharToMultiByte(CP_ACP, 0, tmp1, -1, t1, sizeof(t1), 0, NULL); { unsigned char x[MD5_DIGESTSIZE] = {0}; md5_ctx_t ctx; md5_init(&ctx); md5(x, t1, strlen(t1)); Bin2Str(x, sizeof(x), t1, sizeof(t1)); } CSimpleStringA str = CSimpleStringA::Format("\"%s;%s\"", t, t1); if (i > 0) { strdevicelist += ","; } strdevicelist += str; } strdevicelist += "]"; #else int ifound = 0; strdevicelist = "["; icount = rvc_videocap_get_device_count(); for (int i = 0; i < 64 && ifound < icount; ++i) { char strcamera[2 * MAX_PATH] = { 0 }; if (0 == rvc_videocap_get_device_fullpathname(i, strcamera, 2 * MAX_PATH)) { CSimpleStringA str = CSimpleStringA::Format("\"%s\"", strcamera); if (ifound > 0) { strdevicelist += ","; } strdevicelist += str; ifound++; } } strdevicelist += "]"; #endif return icount; } }