最近在研究如如何播放多个摄像头数据,在查找资料的过程中发现了这篇文章《MFC中如何利用ffmpeg和SDL2.0多线程多窗口播放摄像头的视频》,使用这篇文章的代码。博主对每个部分介绍还是比较清楚的,中间省略了一些代码,还得需要自己调整。本文主要记录在调用过程中遇到的一些问题。
这个是我调用的地方
void CMultithreadedMultiWindowCamerasDlg::OnBnClickedButton1()
{
//1、获取设备列表
HRESULT hrrst;
GUID guid = CLSID_VideoInputDeviceCategory;
std::vector<TDeviceInfo> videoDeviceVec;
hrrst = DsGetAudioVideoInputDevices(videoDeviceVec, guid);
//2.打开设备(这里我有两个摄像头,所以打开了两个)
CWnd* pWnd1 = this->GetDlgItem(IDC_STATIC1);//IDC_PIC_1就是图像控件的ID
HWND handle1 = pWnd1->GetSafeHwnd(); //获取图像控件的句柄
CWnd* pWnd2 = this->GetDlgItem(IDC_STATIC2);//IDC_PIC_1就是图像控件的ID
HWND handle2 = pWnd2->GetSafeHwnd(); //获取图像控件的句柄
Video video1;
videoDeviceVec[0].Index = 0;
video1.mainHandle = handle1;//screen;
video1.mainWindow = new Window(0, 0);
video1.Init(videoDeviceVec[0], videoDeviceVec[0].Params[1], 0);
video1.mainWindow->Init(handle1, video1.width, video1.height);
SDL_Thread *video_tid1 = SDL_CreateThread(SDL_Play_Thread, "sdl", (void *)&video1);
Video video2;
videoDeviceVec[1].Index = 0;
video2.mainHandle = handle2;//screen;
video2.mainWindow = new Window(0, 0);
video2.Init(videoDeviceVec[1], videoDeviceVec[1].Params[3], 1);
video2.mainWindow->Init(handle2, video2.width, video2.height);
SDL_Thread *video_tid2 = SDL_CreateThread(SDL_Play_Thread, "sdl", (void *)&video2);
}
没有播放摄像视频数据,调试发现这个接口Play()的大的while循环没有被执行
int Video::Play() {
//.....此处省略了一些代码
while (!isStop) {
if (isPause) {
SDL_Delay(20);
continue;
}
//av_init_packet(packet);
bool getData = true;
while (1) {
if (av_read_frame(pFormatCtx, packet) < 0) {
getData = false;
break;
}
if (packet->stream_index == videoIndex) {
getData = true;
break;
}
}
if (!getData) {
break;
}
//....此处省略了一些代码
}
sws_freeContext(img_convert_ctx);
SDL_Quit();
av_free(out_buffer);
av_free(pFrameYUV);
return 0;
}
而Play()是在SDL线程中被调用 的
//线程函数
static int SDL_Play_Thread(void* param) {
Video* video = (Video*)param;
video->Play();
video->AddList(video->listHandle);
return 0;
}
isStop的莫名其妙的改变了
在SDL线程中赋值的时候,isStop的变量没有改变
进到Play()的时候,isStop的值变成了true(204)
查找资料这是未初始化的状态。
找了半天,猜想void CMultithreadedMultiWindowCamerasDlg::OnBnClickedButton1()这个接口已经执行结束,相应的video1这个对象也被释放掉,但是SDL_Play_Thread这个线程函数还在执行,它所访问的isStop变量是处于未初始化状态。
void CMultithreadedMultiWindowCamerasDlg::OnBnClickedButton1()
{
//.........
SDL_Thread *video_tid1 = SDL_CreateThread(SDL_Play_Thread, "sdl", (void *)&video1);
//.........
}
于是在线程函数中修改如下,问题解决
//线程函数
int SDL_Play_Thread(void* param) {
Video* video = new Video();
//video=(Video*)param;
//++++++++++++++++++++++++++++++++++++++++++++++++
video->width = ((Video*)param)->width;
video->height = ((Video*)param)->height;
video->listHandle = ((Video*)param)->listHandle;
video->mainHandle = ((Video*)param)->mainHandle;
video->mainWindow = ((Video*)param)->mainWindow;
video->listWindow = ((Video*)param)->listWindow;
video->pCodec = ((Video*)param)->pCodec;
video->pCodecCtx = ((Video*)param)->pCodecCtx;
video->pFormatCtx = ((Video*)param)->pFormatCtx;
video->thread = ((Video*)param)->thread;
video->videoIndex = ((Video*)param)->videoIndex;
video->isPause = ((Video*)param)->isPause;
video->isStopp = ((Video*)param)->isStopp;
//++++++++++++++++++++++++++++++++++++++++++++++++++
video->Play();
video->AddList(video->listHandle);
delete video;
return 0;
}
参考文章:
bool类型未初始化的产生的奇怪现象
https://blog.youkuaiyun.com/lanlongtu/article/details/102328025?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-2.control&dist_request_id=1328689.10311.16165855629799887&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-2.control