前面写过一篇关于视频对比的文章,后来又做了一些修缮,用代码实现了一遍。
//定时器,解码 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) { 。。。 } }
接收端解码成功之后,视频源再解码,确保同步。
时间: 2024-10-05 21:31:03