|
@@ -4,6 +4,7 @@
|
|
|
#include "../../Other/libvideoframework/videoutil.h"
|
|
|
#include "../../Other/libvideoqueue/libvideoqueue.h"
|
|
|
#include "../../Other/rvcmediacommon/rvc_media_common.h"
|
|
|
+#include "fileutil.h"
|
|
|
|
|
|
extern "C"
|
|
|
{
|
|
@@ -13,6 +14,8 @@ extern "C"
|
|
|
}
|
|
|
#include "../../Other/libvideoframework/video_common/ffmpeg_api_cpp_adapter.h"
|
|
|
|
|
|
+#include "cv.h"
|
|
|
+#include "highgui.h"
|
|
|
|
|
|
static int translate_image_resolution(video_frame** dstframe, const int iwidth, const int iheight, const video_frame* psrcframe)
|
|
|
{
|
|
@@ -58,6 +61,31 @@ static int get_local_video_frame(Clibvideoqueue* local_video_queue, video_frame*
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
+
|
|
|
+int rvc_start_remote_video_render(rvc_video_render_t* prender, void* videoframe)
|
|
|
+{
|
|
|
+ if (NULL != prender->premote_render) {
|
|
|
+ video_frame* echoframe = NULL;
|
|
|
+ if (0 == translate_image_resolution(&echoframe, prender->location_param.iremote_view_cx, prender->location_param.iremote_view_cy, (const video_frame*)videoframe)) {
|
|
|
+ prender->premote_render->RenderVideoFrame(echoframe, RVC_FLIP_VERTICAL);
|
|
|
+ //session->bshow_remote = true;
|
|
|
+ video_frame_delete(echoframe);
|
|
|
+ echoframe = NULL;
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ prender->premote_render->RenderVideoFrame((video_frame*)videoframe, RVC_FLIP_VERTICAL);
|
|
|
+ //session->bshow_remote = true;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ //if (false == session->bremoterender) {
|
|
|
+ // LogWarn(Severity_Middle, Error_Debug, EVENT_MOD_SIP_REMOTE_VIDEO_RENDER_STARTED, "start remote video render.");
|
|
|
+ // session->bremoterender = true;
|
|
|
+ //}
|
|
|
+
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
void* rvc_videorender_func(void* arg)
|
|
|
{
|
|
|
LOG_FUNCTION();
|
|
@@ -164,14 +192,103 @@ void* rvc_videorender_func(void* arg)
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
+
|
|
|
+void* rvc_remote_videorender_func(void* arg)
|
|
|
+{
|
|
|
+ LOG_FUNCTION();
|
|
|
+
|
|
|
+ rvc_video_render_t* param = (rvc_video_render_t*)arg;
|
|
|
+ int iremote_video_fresh_time = param->location_param.iremote_fresh_time;
|
|
|
+ char strImgPath[MAX_PATH] = { 0 };
|
|
|
+ int irecord_video_frame_width = REC_COMMON_VIDEO_SNAPSHOT_PREVIEW_WIDTH;
|
|
|
+ int irecord_video_frame_heigt = REC_COMMON_VIDEO_SNAPSHOT_PREVIEW_HEIGHT;
|
|
|
+
|
|
|
+ _snprintf(strImgPath, MAX_PATH, "%s", "./bin/agent.jpg");
|
|
|
+
|
|
|
+ video_frame* remote_frame = video_frame_new(irecord_video_frame_width, irecord_video_frame_heigt, VIDEO_FORMAT_RGB24);
|
|
|
+ video_frame_fill_black(remote_frame);
|
|
|
+
|
|
|
+ if (ExistsFile(strImgPath))
|
|
|
+ {
|
|
|
+ IplImage* img = cvLoadImage(strImgPath, 1);
|
|
|
+ videoq_frame* vframe = new videoq_frame;
|
|
|
+ if (NULL != img) {
|
|
|
+ Dbg("load img success");
|
|
|
+ vframe->format = VIDEOQ_FORMAT_RGB24;
|
|
|
+ vframe->framesize = img->imageSize;
|
|
|
+ vframe->width = img->width;
|
|
|
+ vframe->height = img->height;
|
|
|
+ vframe->data = new unsigned char[img->imageSize];
|
|
|
+ memcpy(vframe->data, img->imageData, img->imageSize);
|
|
|
+ cvReleaseImage(&img);
|
|
|
+ }
|
|
|
+
|
|
|
+ SwsContext* sws = sws_getContext(vframe->width, vframe->height, PIX_FMT_BGR24,
|
|
|
+ irecord_video_frame_width,
|
|
|
+ irecord_video_frame_heigt,
|
|
|
+ PIX_FMT_BGR24,
|
|
|
+ SWS_POINT, NULL, NULL, NULL);
|
|
|
+
|
|
|
+ uint8_t* src_data[4] = { (unsigned char*)vframe->data + (vframe->height - 1) * vframe->width * 3, NULL, NULL, NULL };
|
|
|
+ int src_linesize[4] = { -vframe->width * 3,0,0,0 };
|
|
|
+ unsigned char* dst[4] = { remote_frame->data[0],NULL,NULL,NULL };
|
|
|
+ int dst_linesize[4] = { remote_frame->linesize[0],0,0,0 };
|
|
|
+ sws_scale(sws, src_data, src_linesize, 0, vframe->height, dst, dst_linesize);
|
|
|
+ sws_freeContext(sws);
|
|
|
+
|
|
|
+ if (vframe) {
|
|
|
+ delete vframe->data;
|
|
|
+ delete vframe;
|
|
|
+ vframe = NULL;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ //if (NULL != t_session->video_shm_q_remote)
|
|
|
+ //{
|
|
|
+ // int rc = video_shm_enqueue(t_session->video_shm_q_remote, remote_frame, VIDEOQUEUE_FLAG_VERTICAL_FLIP);
|
|
|
+ // if (rc != Error_Succeed)
|
|
|
+ // {
|
|
|
+ // Dbg("insert agent picture to remote video queue.");
|
|
|
+ // }
|
|
|
+ //}
|
|
|
+
|
|
|
+ video_frame* showframe = NULL;
|
|
|
+ if (-1 == translate_image_resolution(&showframe, param->location_param.iremote_view_cx, param->location_param.iremote_view_cy, remote_frame)) {
|
|
|
+ showframe = video_frame_new(param->location_param.iremote_view_cx, param->location_param.iremote_view_cy, VIDEO_FORMAT_RGB24);
|
|
|
+ video_frame_fill_black(showframe);
|
|
|
+ video_frame_copy(showframe, remote_frame);
|
|
|
+ }
|
|
|
+
|
|
|
+ for (; ; ) {
|
|
|
+ struct timespec ts;
|
|
|
+ clock_gettime(CLOCK_REALTIME, &ts);
|
|
|
+ long unsec = ts.tv_nsec + (1000 * 1000 * iremote_video_fresh_time);
|
|
|
+ ts.tv_sec += (unsec / 1000000000);
|
|
|
+ ts.tv_nsec = (unsec % 1000000000);
|
|
|
+ if (0 != sem_timedwait(¶m->remote_render_stop_sem, &ts) && (ETIMEDOUT == errno)){
|
|
|
+ rvc_start_remote_video_render(param, showframe);
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ Dbg("%s:%d record remote video render_func exit!", __FUNCTION__, __LINE__);
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ video_frame_delete(showframe);
|
|
|
+ showframe = NULL;
|
|
|
+
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
int rvc_start_video_render(rvc_video_render_t* prender, rvc_video_box_move_callback_t* cb)
|
|
|
{
|
|
|
- if (0 != sem_init(&prender->ui_stop_sem, 0, 0)) {
|
|
|
- Dbg("%s:%d create ui stop event failed!", __FUNCTION__, __LINE__);
|
|
|
+ if (0 != sem_init(&prender->ui_stop_sem, 0, 0) || 0 != sem_init(&prender->remote_render_stop_sem, 0, 0)) {
|
|
|
+ Dbg("%s:%d create stop sem failed!", __FUNCTION__, __LINE__);
|
|
|
return Error_Resource;
|
|
|
}
|
|
|
else {
|
|
|
- Dbg("%s:%d create ui stop event success!", __FUNCTION__, __LINE__);
|
|
|
+ Dbg("%s:%d create stop sem success!", __FUNCTION__, __LINE__);
|
|
|
}
|
|
|
|
|
|
int err = pthread_create(&prender->ui_threadid, NULL, rvc_videorender_func, prender);
|
|
@@ -183,6 +300,15 @@ int rvc_start_video_render(rvc_video_render_t* prender, rvc_video_box_move_callb
|
|
|
return Error_Resource;
|
|
|
}
|
|
|
|
|
|
+ err = pthread_create(&prender->remote_render_threadid, NULL, rvc_remote_videorender_func, prender);
|
|
|
+ if (Error_Succeed == err) {
|
|
|
+ Dbg("create video render thread success, thread id is %u.", prender->ui_threadid);
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ Dbg("create video render thread failed.");
|
|
|
+ return Error_Resource;
|
|
|
+ }
|
|
|
+
|
|
|
return err;
|
|
|
}
|
|
|
|
|
@@ -190,6 +316,9 @@ int rvc_start_video_render(rvc_video_render_t* prender, rvc_video_box_move_callb
|
|
|
int rvc_stop_video_render(rvc_video_render_t* prender)
|
|
|
{
|
|
|
sem_post(&prender->ui_stop_sem);
|
|
|
+
|
|
|
+ rvc_stop_remote_video_render(prender);
|
|
|
+
|
|
|
if (prender->ui_threadid > 0) {
|
|
|
if (0 == pthread_join(prender->ui_threadid, NULL)) {
|
|
|
Dbg("video render thread %u pthread join success.", prender->ui_threadid);
|
|
@@ -205,29 +334,19 @@ int rvc_stop_video_render(rvc_video_render_t* prender)
|
|
|
return Error_Succeed;
|
|
|
}
|
|
|
|
|
|
-
|
|
|
-int rvc_start_remote_video_render(rvc_video_render_t* prender, void* videoframe)
|
|
|
+int rvc_stop_remote_video_render(rvc_video_render_t* prender)
|
|
|
{
|
|
|
- LOG_FUNCTION();
|
|
|
- if (NULL != prender->premote_render) {
|
|
|
- Dbg("session plocal_render RenderVideoFrame");
|
|
|
- video_frame* echoframe = NULL;
|
|
|
- if (0 == translate_image_resolution(&echoframe, prender->location_param.iremote_view_cx, prender->location_param.iremote_view_cy, (const video_frame*)videoframe)) {
|
|
|
- prender->premote_render->RenderVideoFrame(echoframe, RVC_FLIP_VERTICAL);
|
|
|
- //session->bshow_remote = true;
|
|
|
- video_frame_delete(echoframe);
|
|
|
- echoframe = NULL;
|
|
|
+ if (prender->remote_render_threadid > 0) {
|
|
|
+ sem_post(&prender->remote_render_stop_sem);
|
|
|
+ if (0 == pthread_join(prender->remote_render_threadid, NULL)) {
|
|
|
+ Dbg("remote video render thread %u pthread join success.", prender->remote_render_threadid);
|
|
|
+ prender->remote_render_threadid = 0;
|
|
|
}
|
|
|
else {
|
|
|
- prender->premote_render->RenderVideoFrame((video_frame*)videoframe, RVC_FLIP_VERTICAL);
|
|
|
- //session->bshow_remote = true;
|
|
|
+ Dbg("remote video render thread pthread join error for %s.", strerror(errno));
|
|
|
}
|
|
|
+ Dbg("remote video render thread exit!");
|
|
|
}
|
|
|
|
|
|
- //if (false == session->bremoterender) {
|
|
|
- // LogWarn(Severity_Middle, Error_Debug, EVENT_MOD_SIP_REMOTE_VIDEO_RENDER_STARTED, "start remote video render.");
|
|
|
- // session->bremoterender = true;
|
|
|
- //}
|
|
|
-
|
|
|
- return 0;
|
|
|
+ return Error_Succeed;
|
|
|
}
|