首页 > 代码库 > FFmpeg 学习之 定时器解码两路视频并进行对比<2>

FFmpeg 学习之 定时器解码两路视频并进行对比<2>

前面写过一篇关于视频对比的文章,后来又做了一些修缮,用代码实现了一遍。

//定时器,解码
void Cvideo4Dlg::OnTimer(UINT nIDEvent)
{
	//输出视频解码
	WaitForSingleObject(AfxBeginThread(Decode_out_Thread, this), INFINITE);
	//输入视频解码
	WaitForSingleObject(AfxBeginThread(Decode_in_Thread, this), INFINITE);	
	//当前帧开始检测
	if(frame_test_over)
	{
		//备份被检测帧必要参数
		if(current_frame_number != pCodecCtx_out->frame_number)
		{	
			//为FALSE时,表示线程执行中,暂不开启新线程
			frame_test_over = FALSE;
			Sleep(5);
			current_frame_number = pCodecCtx_out->frame_number;
			CString frame_number_str_in;
			CString frame_number_str_out;
			frame_number_str_in.Format("src_%d.jpg", current_frame_number);
			cvSaveImage(frame_number_str_in, Image_in);	
			frame_number_str_out.Format("dst_%d.jpg", current_frame_number);
			cvSaveImage(frame_number_str_out, Image_out);
			//开启检测线程
			WaitForSingleObject(AfxBeginThread(Compare_Thread, this), INFINITE);
		}
		//帧号不再变化,则认为解码结束
		else if(current_frame_number && (!encoder_over))
		{
			//为FALSE时,表示线程执行中,暂不开启新线程
			frame_test_over = FALSE;
			encoder_over = 1;
			//开启检测线程
			WaitForSingleObject(AfxBeginThread(Compare_Thread, this), INFINITE);
			KillTimer(1);
			//system_clear();
			GetDlgItem(IDC_BTN_CHECK)->EnableWindow(TRUE);
		}		
	}
}

current_frame_number 为当前被测帧号,当检测线程开启的时候,传送过去,因为frame_number在线程开启的时候,,未必等于保存的图像的帧号。

frame_test_over 线程运行标志。为FALSE 时表示线程正在运行,不会开启新的检测线程。待检测线程结束后,该标志位会复位。<pre name="code" class="cpp">

利用 MediaInfo 读取视频帧数,当frame_number == 总帧数时,可认为解码结束,encoder_over 复位。执行统计线程。
<pre name="code" class="cpp">
//输入视频解码线程
UINT Decode_in_Thread(LPVOID lpParam)
{
	Cvideo4Dlg * dlg = (Cvideo4Dlg *)lpParam;
	
	if((dlg->pCodecCtx_in->frame_number) <= (dlg->pCodecCtx_out->frame_number))
	{
          。。。
        }
}

//输出视频解码线程
UINT Decode_out_Thread(LPVOID lpParam)
{
	Cvideo4Dlg * dlg = (Cvideo4Dlg *)lpParam;
	
	if(av_read_frame(dlg->pFormatCtx_out, dlg->packet_out)>=0) 
	{
          。。。
        }
}

接收端解码成功之后,视频源再解码,确保同步。


FFmpeg 学习之 定时器解码两路视频并进行对比<2>