|
|
@@ -2,22 +2,13 @@
|
|
|
//
|
|
|
|
|
|
#include "libwmvrecord.h"
|
|
|
-#include <winpr/thread.h>
|
|
|
-#include <winpr/string.h>
|
|
|
-#include <winpr/file.h>
|
|
|
-
|
|
|
-//#include "stdafx.h"
|
|
|
-//#include <windowsx.h>
|
|
|
-//#include <windows.h> //包含头文件 windows.h
|
|
|
-//#include <mmsystem.h> //包含头文件mmsystem.h
|
|
|
-//#include <mmreg.h> // Multimedia registration多媒体注册
|
|
|
-//#include <msacm.h> // Audio Compression Manager音频压缩管理器
|
|
|
-//#include "winmedia.h"
|
|
|
-//#include <Vfw.h>
|
|
|
+
|
|
|
#ifdef RVC_OS_WIN
|
|
|
#include "io.h"
|
|
|
#include <process.h>
|
|
|
#include <windows.h> //包含头文件 windows.h
|
|
|
+#else
|
|
|
+#include <pthread.h>
|
|
|
#endif
|
|
|
|
|
|
#include <dirent.h>
|
|
|
@@ -36,6 +27,7 @@
|
|
|
#include <speex/speex_resampler.h>
|
|
|
#include "iaudionsinterface.h"
|
|
|
#include "libaudiotransqueue.h"
|
|
|
+#include <semaphore.h>
|
|
|
|
|
|
#define SLASH '/'
|
|
|
#define BACK_SLASH '\\'
|
|
|
@@ -144,13 +136,8 @@ public:
|
|
|
memset(audioframe,0,sizeof(audio_frame));
|
|
|
m_hRecordThread = NULL;
|
|
|
m_nRecordthreadId = 0;
|
|
|
- m_hEventWait= ::CreateEventA(NULL, TRUE, 0, 0);
|
|
|
- if (!m_hEventWait)
|
|
|
- {
|
|
|
- *m_bResult = FALSE;
|
|
|
- m_pHostApi->Debug("create hEventWait failed!");
|
|
|
- return;
|
|
|
- }
|
|
|
+ sem_init(&m_semt, 0, 0);
|
|
|
+
|
|
|
m_pAudioBufferTmp = NULL; //音频录制拼接BUFFER
|
|
|
m_iAudioBufferSize = 0;
|
|
|
memset(m_FileName,0,MAX_PATH);
|
|
|
@@ -294,7 +281,7 @@ public:
|
|
|
}
|
|
|
|
|
|
private:
|
|
|
- HANDLE m_hEventWait; // CreateEvent
|
|
|
+ sem_t m_semt;
|
|
|
BOOL m_bStopRecord;
|
|
|
eRvcRecordType m_eRecordType; //录制双向的视频类型,0:单向录制,1:手机<->pad双录,2:坐席<->pad双录,3:坐席<->大机双录
|
|
|
eAudioOutPutType m_eAudioType;
|
|
|
@@ -330,8 +317,8 @@ private:
|
|
|
|
|
|
Clibaudiotransqueue *m_salestransqueue;
|
|
|
|
|
|
- HANDLE m_hRecordThread;
|
|
|
- DWORD m_nRecordthreadId;
|
|
|
+ pthread_t m_hRecordThread;
|
|
|
+ pthread_t m_nRecordthreadId;
|
|
|
char m_FileName[MAX_PATH];
|
|
|
char m_PathName[MAX_PATH];
|
|
|
char m_WmvFileName[MAX_PATH];
|
|
|
@@ -415,9 +402,17 @@ private:
|
|
|
|
|
|
void FSleep(int ms)
|
|
|
{
|
|
|
- DWORD dwRet = WaitForSingleObject(m_hEventWait, ms);
|
|
|
- if (dwRet == WAIT_OBJECT_0)
|
|
|
- {
|
|
|
+ struct timespec ts;
|
|
|
+ clock_gettime(CLOCK_REALTIME, &ts);
|
|
|
+ long unsec = ts.tv_nsec + (1000 * 1000 * ms);
|
|
|
+ ts.tv_sec += (unsec / 1000000000);
|
|
|
+ ts.tv_nsec = (unsec % 1000000000);
|
|
|
+ if (-1 == sem_timedwait(&m_semt, &ts)) {
|
|
|
+ if (ETIMEDOUT == errno) {
|
|
|
+
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else {
|
|
|
throw std::exception();
|
|
|
}
|
|
|
}
|
|
|
@@ -436,7 +431,6 @@ private:
|
|
|
//开始录制视频
|
|
|
BOOL StartRecord()
|
|
|
{
|
|
|
- ResetEvent(m_hEventWait);
|
|
|
m_pWriter = new FFmpegWmvWriter(this);
|
|
|
if (m_bIsAudioNsOn){
|
|
|
audions_callback_t t_callback = { 0 };
|
|
|
@@ -444,7 +438,13 @@ private:
|
|
|
t_callback.user_data = this;
|
|
|
m_pAudioNsObj = CreateIAudioNsObj(&t_callback);
|
|
|
}
|
|
|
- m_hRecordThread = (HANDLE)_beginthreadex(NULL, 0, VideoRecordThread, (LPVOID)this, 0, (unsigned int*)&m_nRecordthreadId);
|
|
|
+
|
|
|
+ if (0 == pthread_create(&m_nRecordthreadId, NULL, VideoRecordThread, (void*)this)) {
|
|
|
+ m_pHostApi->Debug("create video record thread and thread id is %u.", m_nRecordthreadId);
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ m_pHostApi->Debug("create video record thread failed.");
|
|
|
+ }
|
|
|
return TRUE;
|
|
|
}
|
|
|
|
|
|
@@ -766,9 +766,18 @@ private:
|
|
|
nOffset = 25*Video->width*3;
|
|
|
}
|
|
|
|
|
|
- for (int i= 0;i<localtmp_frm.height && i<Video->height;i++)
|
|
|
- {
|
|
|
- memcpy(Video->data+nOffset+i*Video->width*3,localtmp_frm.data[0]+i*localtmp_frm.linesize[0],localtmp_frm.linesize[0]);
|
|
|
+ int imaxheight = localtmp_frm.height > Video->height ? Video->height : localtmp_frm.height;
|
|
|
+ if (0 == nActiveCam) {
|
|
|
+ for (int i = imaxheight - 1, j = 0; i >= 0 && j < imaxheight; i--, j++)
|
|
|
+ {
|
|
|
+ memcpy(Video->data + nOffset + j * Video->width * 3, localtmp_frm.data[0] + i * localtmp_frm.linesize[0], localtmp_frm.linesize[0]);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ for (int i = 0; i < imaxheight; i++)
|
|
|
+ {
|
|
|
+ memcpy(Video->data + nOffset + i * Video->width * 3, localtmp_frm.data[0] + i * localtmp_frm.linesize[0], localtmp_frm.linesize[0]);
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
delete localtmp_frm.data[0];
|
|
|
@@ -790,9 +799,10 @@ private:
|
|
|
// record_type_table[m_eRecordType], tmp_frm.format, tmp_frm.width, tmp_frm.height);
|
|
|
if (bGetRemotevideo)
|
|
|
{
|
|
|
- for (int i= 0;i<tmp_frm.height&&i<Video->height;i++)
|
|
|
+ int imaxheight = tmp_frm.height > Video->height ? Video->height : tmp_frm.height;
|
|
|
+ for (int i = imaxheight - 1, j = 0; i >= 0 && j < imaxheight; i--, j++)
|
|
|
{
|
|
|
- memcpy(Video->data+((Video->height-tmp_frm.height)/2+i)*Video->width*3+640*3,tmp_frm.data[0]+i*tmp_frm.linesize[0],tmp_frm.linesize[0]);
|
|
|
+ memcpy(Video->data+((Video->height-tmp_frm.height)/2+j)*Video->width*3+640*3,tmp_frm.data[0]+i*tmp_frm.linesize[0],tmp_frm.linesize[0]);
|
|
|
}
|
|
|
}
|
|
|
delete tmp_frm.data[0];
|
|
|
@@ -1386,7 +1396,7 @@ private:
|
|
|
DWORD nStartTime = timeGetTime();
|
|
|
IplImage *pImg = cvCreateImage(cvSize(nWidth, nHeight), IPL_DEPTH_8U, 3);
|
|
|
memcpy(pImg->imageData, videoframe->data, nVideoFrameSize);
|
|
|
- cvFlip(pImg); // 先把图像翻转
|
|
|
+ //cvFlip(pImg); // 先把图像翻转
|
|
|
if (strlen(m_SubtitleParam.topSubtitleData) <= 0)
|
|
|
{
|
|
|
if (m_SubtitleParam.bSubtitleSection)
|
|
|
@@ -1428,7 +1438,7 @@ private:
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- cvFlip(pImg); // 添完字幕再翻转
|
|
|
+ //cvFlip(pImg); // 添完字幕再翻转
|
|
|
memcpy(videoframe->data, pImg->imageData, nVideoFrameSize);
|
|
|
cvReleaseImage(&pImg);
|
|
|
nSubTitleTime += (timeGetTime()- nStartTime);
|
|
|
@@ -1976,9 +1986,9 @@ private:
|
|
|
#endif
|
|
|
|
|
|
//视频录制线程
|
|
|
- static unsigned int __stdcall VideoRecordThread(LPVOID n)
|
|
|
+ static void* VideoRecordThread(void* pParam)
|
|
|
{
|
|
|
- libwmvrecord_impl* WmvRecord = (libwmvrecord_impl*)n;
|
|
|
+ libwmvrecord_impl* WmvRecord = (libwmvrecord_impl*)pParam;
|
|
|
int iRet = -1;
|
|
|
|
|
|
#ifdef _WIN32
|
|
|
@@ -1993,7 +2003,7 @@ private:
|
|
|
iRet = WmvRecord->VideoRecord();
|
|
|
#endif
|
|
|
|
|
|
- return iRet;
|
|
|
+ return &iRet;
|
|
|
}
|
|
|
public:
|
|
|
//开始录制 ly@2018/06/05
|
|
|
@@ -2108,10 +2118,14 @@ public:
|
|
|
BOOL StopWmvRecord() //退出
|
|
|
{
|
|
|
m_bStopRecord = TRUE;
|
|
|
- SetEvent(m_hEventWait);
|
|
|
- WaitForSingleObject(m_hRecordThread, INFINITE);
|
|
|
- CloseHandle(m_hRecordThread);
|
|
|
- m_hRecordThread = NULL;
|
|
|
+ sem_post(&m_semt);
|
|
|
+ if (0 == pthread_join(m_nRecordthreadId, NULL)) {
|
|
|
+ m_pHostApi->Debug("thread join video record thread %u success!", m_nRecordthreadId);
|
|
|
+ m_nRecordthreadId = 0;
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ m_pHostApi->Debug("thread join video record thread failed!");
|
|
|
+ }
|
|
|
m_eRecordType = eSingleSide;
|
|
|
return TRUE;
|
|
|
}
|