第六章:ffmpeg和QT开发播放器之创建线程

写在前面:

    这部分对应视频课程中的4-3~4-4。主要创建了线程,将解码和转码分开,提高视频的流畅度,最后能够打开外部视频进行播放。


1、创建线程

       在这之前的代码编译运行之后,能够正常使用,但是没创建线程,所以应该将视频解码放在一个线程里。

                               第六章:ffmpeg和QT开发播放器之创建线程_第1张图片

       可以直接使用QT自带的线程,在线程中读取视频,并解码并且控制读取的速度。

       将之前在paintEvent中实现是读取视频、解码视频的函数逐步挪动到新创建的XVideoThread类中,同样的,如果有涉及到申请空间的就需要记得去释放空间。

       XFFmpeg::Get()->Decode(&pkt);解码完成之后,生成出来的yuv格式的数据,我们就需要将它转换成RGB格式的用于显示。转RGB的任务可以在该线程中直接做,然后需要用的时候直接将RGB数据copy过去。也可以在显示那边(paintEvent里面)做RGB转换再显示。

       这里我们选择将解码和转码分开来做,主要原因有:对于有些视频来说,解码就需要每一帧都解码,有些视频帧数又特别高,但是显示的时候不需要那么高的帧数。

       解码:需要控制解码的进度。每秒解码多少帧需要知道FPS。打开视频文件的时候可以获取到。
       转码:仅仅需要25帧就可以达到正常观看的效果了。

       在open视频的时候,先获取一下fps,以便于控制解码速率。

       fps = r2d(ic->streams[i]->avg_frame_rate);获取fps
       msleep(1000/XFFmpeg::Get()->fps);//每一帧的毫秒数

void XVideoThread::run()
{
	while (!isexit)
	{
		AVPacket pkt = XFFmpeg::Get()->Read(); //1、读取视频帧 
		if (pkt.size <= 0)
		{
			msleep(10);	//释放资源
			continue;
		}
		if (pkt.stream_index != XFFmpeg::Get()->videoStream)//如果是音频流,就先丢弃
		{
			av_packet_unref(&pkt);//释放空间
			continue;
		}

		XFFmpeg::Get()->Decode(&pkt);
		av_packet_unref(&pkt);//释放空间
		if(XFFmpeg::Get()->fps > 0)
			msleep(1000/XFFmpeg::Get()->fps);//每一帧的毫秒数
	}
}

2、修正ToRGB函数

       由于之前的torgb函数传入yuv参数,而yuv又是XFFmpeg里面的内部成员,所以在改动之后就不需要在多此一举了。
       更改前:bool ToRGB(const AVFrame *yuv,char *out,int outwidth, int outheight);
       更改后:bool ToRGB(char *out,int outwidth, int outheight);

3、通过QT打开外部视频

       打开qt编辑器,在工具栏中打开编辑信号槽,拖动之前创建的图标到右侧,会出现配置连接选项,在右侧栏点击编辑,创建一个open槽。点击左侧clicked后,选择右侧的open,这样就可以将点击事件和open函数绑定在一起了。

                           第六章:ffmpeg和QT开发播放器之创建线程_第2张图片

       之后在xplay.h中追加一个信号槽
public slots:

void open(); //当界面上按钮按下之后,就会执行事先绑定的open函数

void Xplay::open()
{
	QString name = QFileDialog::getOpenFileName(
		this, QString::fromLocal8Bit("选择视频文件"));
	
	if (name.isEmpty())//如果没有选择文件
		return;

	this->setWindowTitle(name);//窗口标题为我们选择的文件

	if(!XFFmpeg::Get()->Open(name.toLocal8Bit()))
	{
		QMessageBox::information(this,"Error","file open failed!");
	}
}

你可能感兴趣的:(第六章:ffmpeg和QT开发播放器之创建线程)