播放器实战08 打开AVCODEC

先来看两个编解码有关的数据结构:
AVCodec:包含了编解码器的一些方法,比如在解码时将packet发给解码器时的代码如下:

re = avcodec_send_packet(av, pkt);

将指向编解码器的指针与pkt一起给avcodec_send_packet函数
AVCodecContext:作为编解码器的上下文,包含了编解码器的环境,简单来说,AVCodec是说如何编解码,这个就是告诉他相应属性设置,如对应视频来说,长宽,以及编码相应设置是否包含B桢,GOP是多少等。

	///02找视频解码器,
	const AVCodec *vcodec=avcodec_find_decoder(ic->streams[videoindex]->codecpar->codec_id);
	if (!vcodec)
	{
		cout << "can't find the codec id" << ic->streams[videoindex]->codecpar->codec_id << endl;
		getchar();
		return -1;
	}
	cout<< " find the video codec id"<< ic->streams[videoindex]->codecpar->codec_id << endl;
	///03创建解码器上下文
	AVCodecContext *vc=avcodec_alloc_context3(vcodec);
	///04配置解码器上下文参数
	avcodec_parameters_to_context(vc, ic->streams[videoindex]->codecpar);
	//八线程解码
	vc->thread_count = 8;
	///05打开解码器上下文
	re = avcodec_open2(vc, 0, 0);
	if (re != 0)
	{
		char buf[1024] = { 0 };
		av_strerror(re, buf, sizeof(buf) - 1);
		cout << "open audio codec failed!" << buf << endl;
		getchar();
		return -1;
	}
	cout << "video codec success!" << endl;

01注册解码器

avcodec_register_all()也被弃用了,在新版ffmpeg中不需要注册

02找视频解码器

在读帧前进行该操作,可通过av_find_best_stream()来找:
在这里插入图片描述
先定义一个指向AVcodec的常量指针vcodec,
av_find_best_stream()的第五个参数为AVCodec的二级指针,用于改变vcodec的指向
但这样的话解码和解封装在一起,耦合度太大,这里用id号获取

const AVCodec *vcodec=avcodec_find_decoder(ic->streams[videoindex]->codecpar->codec_id);

但有可能找不到流中的解码器号,这里要做个判断看看是否找到解码器

if (!vcodec)
{
	cout << "can't find the codec id" << ic->streams[videoindex]->codecpar->codec_id << endl;
	getchar();
	return -1;
}

03创建解码器上下文

AVCodecContext *vc=avcodec_alloc_context3(vcodec);

将指向解码器的指针传入,开辟一块空间用于放置解码器相关的信息,该空间用vc标记

04配置解码器上下文参数

avcodec_parameters_to_context(vc, ic->streams[videoindex]->codecpar);

将流中的codec参数复制到解码器上下文中

05打开解码器上下文

re = avcodec_open2(vc, 0, 0);
第二个参数是解码器codec,但在03创建上下文的时候已经传进去了,这里就不用再传了,设为0就行了
if (re != 0)
{
	char buf[1024] = { 0 };
	av_strerror(re, buf, sizeof(buf) - 1);//用buf存放错误信息
	cout << "open audio codec failed!" << buf << endl;
	getchar();
	return -1;
}

打开音频解码同理,改下名字就行了:

///01注册解码器
	//avcodec_register_all()也被弃用了

	///02找视频解码器,在读帧前进行该操作,可通过av_find_best_stream()来找,但这样的话解码和解封装在一起,耦合度太大,这里用id号获取
	const AVCodec* acodec = avcodec_find_decoder(ic->streams[audioindex]->codecpar->codec_id);
	//有可能找不到流中的解码器号,这里要做个判断看看是否找到解码器
	if (!vcodec)
	{
		cout << "can't find the codec id" << ic->streams[audioindex]->codecpar->codec_id << endl;
		getchar();
		return -1;
	}
	cout << " find the audio codec id" << ic->streams[audioindex]->codecpar->codec_id << endl;
	///03创建解码器上下文
	AVCodecContext* ac = avcodec_alloc_context3(acodec);//将指向解码器的指针传入,开辟一块空间用于放置解码器相关的信息

	///04配置解码器上下文参数
	avcodec_parameters_to_context(ac, ic->streams[audioindex]->codecpar);//将流中的codec参数复制到解码器上下文中

	//八线程解码
	vc->thread_count = 8;

	///05打开解码器上下文
	re = avcodec_open2(ac, 0, 0);//第二个参数是解码器codec,但在创建上下文的时候已经传进去了,这里就不用再传了
	if (re != 0)
	{
		char buf[1024] = { 0 };
		av_strerror(re, buf, sizeof(buf) - 1);//用buf存放错误信息
		cout << "open audio codec failed!" << buf << endl;
		getchar();
		return -1;
	}
	cout << "video codec success!" << endl;
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值