多线程,偶尔崩溃
要么就一直都正常运行,要么就是一开始就崩溃。各位大侠看看是不是多线程部分哪里写的不对,尤其是m_pProcessDll
// ----------------------------------------------------------------------
// 函数名: CVideoProcessDlgProvider::VideoProcess
// 作者:
// 描述: 对视频进行增强处理 采用多线程
// 返回值:
// [BOOL]
// 参数:
// [const string& command]
// [const string& video_path]
// ----------------------------------------------------------------------
int CVideoProcessDlgProvider::VideoProcess(const string& command, CWnd * wnd)
{
SYSTEM_INFO SystemInfo;
GetSystemInfo(&SystemInfo);
//1核的电脑创建一个线程0,两核创建两个线程,4核及以上,创建N-1个线程
HANDLE ThreadHandle[64];
if (SystemInfo.dwNumberOfProcessors<4 )
SystemInfo.dwNumberOfProcessors=SystemInfo.dwNumberOfProcessors;
else
SystemInfo.dwNumberOfProcessors=SystemInfo.dwNumberOfProcessors-1;
#ifdef _DEBUG
std::string dll_name = "ImageProcess\\" + command + "D.dll";
#else
std::string dll_name = "ImageProcess\\" + command + ".dll";
#endif
std::map<std::string, std::string> task_context;
task_context["Command"] = command;
if (m_pProcessDll != NULL)
{
delete m_pProcessDll;
m_pProcessDll = NULL;
}
// 创建视频处理dll指针
m_pProcessDll = new CImageProcessDll(dll_name);
if (!m_pProcessDll->IsActive())
{
delete m_pProcessDll;
m_pProcessDll = NULL;
return FAIL_STATE;
}
if (!m_pProcessDll->Init(task_context))
{
delete m_pProcessDll;
m_pProcessDll = NULL;
return FAIL_STATE;
}
if (!m_pProcessDll->Option(m_VideoImage.GetImage()))
{
delete m_pProcessDll;
m_pProcessDll = NULL;
return CANCEL_STATE;
}
// 获取视频总帧数,用于进度条
int frame_count=0;
for(DWORD i = 0; i < SystemInfo.dwNumberOfProcessors ; i++)
{
//打开视频文件
CvCapture * capture_ptr = NULL;
if (m_ProcessCount > 0)
{
capture_ptr = cvCaptureFromFile(m_DestVideo.c_str());
}
else
{
capture_ptr = cvCaptureFromFile(m_VideoPath.c_str());
}
if (!capture_ptr)
{
return FAIL_STATE;
}
frame_count = (int)cvGetCaptureProperty(capture_ptr, CV_CAP_PROP_FRAME_COUNT);
cvSetCaptureProperty(capture_ptr, CV_CAP_PROP_POS_FRAMES, i * frame_count/SystemInfo.dwNumberOfProcessors);
IplImage* src_image = cvQueryFrame(capture_ptr);
stParamVideoProcess* stParam = new stParamVideoProcess;
stParam->pThis= this;
stParam->capture_ptr = capture_ptr;
stParam->frame_count = frame_count/SystemInfo.dwNumberOfProcessors;
stParam->nProcessIndex = i;
ThreadHandle[i] = CreateThread(NULL, 0, VideoThreadProc, stParam, 0, NULL);
assert(ThreadHandle != INVALID_HANDLE_VALUE);
}
//CProgressWnd ProgressWnd(wnd, "进度", TRUE);//有取消
CProgressWnd ProgressWnd(wnd, "进度", FALSE);//没有取消
ProgressWnd.GoModal();
ProgressWnd.SetRange(0, frame_count);
ProgressWnd.SetText("正在进行视频增强处理。请稍候...");
int a=0;
while(1)
{
a=0;
int s=0;//处理了几个线程
for (int i=0;i<SystemInfo.dwNumberOfProcessors;i++)
{
a=a+num[i];
if (startprocess[i]==1)
s++;
}
ProgressWnd.SetPos(a);
ProgressWnd.PeekAndPump(FALSE);
if (s==SystemInfo.dwNumberOfProcessors)//判断几个线程是否执行完
break;
}
for (int b=0;b<SystemInfo.dwNumberOfProcessors;b++)
{
startprocess[b]=0;
num[b]=0;
}
//上面都是进度条的东西
WaitForMultipleObjects(SystemInfo.dwNumberOfProcessors, ThreadHandle, TRUE, INFINITE);
delete m_pProcessDll;
m_pProcessDll=NULL;//两个线程处理完以后删除指针
for (int i = 0; i < SystemInfo.dwNumberOfProcessors; i++)
{
CloseHandle(ThreadHandle[i]);
}
if (ProgressWnd.Cancelled())
{
return CANCEL_STATE;
}
m_ProcessCount++;
m_DestVideo = BuildDestVideo(m_ProcessCount);
return SUCCESS_STATE;
}
DWORD WINAPI CVideoProcessDlgProvider:: VideoThreadProc( LPVOID lpParameter)
{
stParamVideoProcess* stParam = (stParamVideoProcess*)lpParameter;
stParam->pThis->_VideoProcess2(stParam->capture_ptr,stParam->frame_count, stParam->nProcessIndex);
delete stParam;
return 0;
}
//线程
int CVideoProcessDlgProvider::_VideoProcess2(CvCapture * capture_ptr,
int frame_count, int nProcessIndex)
{
// 获取视频宽度
int frame_width = (int)cvGetCaptureProperty(capture_ptr, CV_CAP_PROP_FRAME_WIDTH);
// 获取视频高度
int frame_height = (int)cvGetCaptureProperty(capture_ptr, CV_CAP_PROP_FRAME_HEIGHT);
// 获取视频总帧数
//int frame_count = (int)cvGetCaptureProperty(capture_ptr, CV_CAP_PROP_FRAME_COUNT);
// 获取视频帧率
int fps = (int)cvGetCaptureProperty(capture_ptr, CV_CAP_PROP_FPS);
std::string temp_dest_video;
string tempIndex;
ostringstream oss;
oss<<nProcessIndex;
tempIndex=oss.str();
temp_dest_video = temp_dir + "\\Processed"+tempIndex+".avi";
//如果是镜头畸变校正,需要增大目标图像缓存区
CvSize video_size;
CvVideoWriter * video_writer;
video_size = cvSize(frame_width, frame_height);
video_writer = cvCreateVideoWriter(temp_dest_video.c_str(), CV_FOURCC('X', 'V', 'I', 'D'), fps, video_size);
if (!video_writer)
{
cvReleaseCapture(&capture_ptr);
return FAIL_STATE;
}
// 循环处理,对每一帧图像进行视频增强
int cur_frame = 0;
BOOL break_flag = FALSE;
IplImage * dst_image = NULL;
IplImage* src_image=NULL;
num[nProcessIndex]=0;
while (cur_frame < frame_count)
{
src_image = cvQueryFrame(capture_ptr);
cur_frame++;
num[nProcessIndex]++;//把每个线程处理了多少帧,传出去
if (!src_image)
{
break;
}
if (!dst_image)
{
dst_image = cvCreateImage(video_size, src_image->depth, src_image->nChannels);
}
if (m_pProcessDll->Process(src_image, dst_image))
{
// 视频增强结果输出
cvWriteFrame(video_writer, dst_image);
}
}
if (dst_image)
{
cvReleaseImage(&dst_image);
}
cvReleaseVideoWriter(&video_writer);
cvReleaseCapture(&capture_ptr);
m_tempDestVideo = BuildtempDestVideo(nProcessIndex);
::MoveFile(temp_dest_video.c_str(), m_tempDestVideo.c_str());
startprocess[nProcessIndex]=1;
return SUCCESS_STATE;
}