avcodec_send_frame 函数传入空 frame进行 flush 操作

 

         在跟着夏老师学习ffmpeg时遇到一个地方不太懂,就是自己手写生成了500帧AVFrame数据,然后每次write进ofstream绑定的文件时进行一个count计数,

	for (int i = 0; i < 500; i++)
	{
		//生成avframe数据

		for (int y = 0; y < c->height; y++)
		{
			for (int x = 0; x < c->width; x++)
			{
				frame->data[0][y * frame->linesize[0] + x] = x + y + i * 3;
			}
		}
		for (int y = 0; y < c->height / 2; y++)
		{
			for (int x = 0; x < c->width / 2; x++)
			{
				frame->data[1][y * frame->linesize[1] + x] = 128 + y + i * 2;
				frame->data[2][y * frame->linesize[2] + x] = 64 + x + i * 5;

			}
		}
		frame->pts = i;//显示的时间

		auto pkt = en.Encode(frame);//接收成功的话这里返回了一个AVPacket,不会调用到Encode里的av_packet_free
		if (pkt)
		{
			count++;
			ofs.write((char*)pkt->data, pkt->size);//把pkt->data里size大小的内容写到ofs关联的文件里
			av_packet_free(&pkt);
		}
	}

        按照这个思路执行下来count应该等于500 但是运行后结果只有440

        在课上夏老师说要在结束以后再传个空frame,来释放剩下的缓冲数据,

std::vector<AVPacket*> XEncode::End()
{
	std::vector<AVPacket*> res;
	unique_lock<mutex>lock(mux_);
	if (!c_)return res;

	auto re = avcodec_send_frame(c_, NULL);//!!!!!!!!!!!!
	if (re!= 0)return res;
	while (re >= 0 )
	{
		auto pkt = av_packet_alloc();
		re = avcodec_receive_packet(c_, pkt);
		if (re != 0)
		{
			av_packet_free(&pkt);
			break;
		}
		res.push_back(pkt);
	}
	return res;
}

        在所有的帧都已经被输入后,加上这个传空frame的函数以后,最终的count计数能够到500

	auto pkts = en.End();
	for (auto pkt : pkts)
	{
		count++;
		ofs.write((char*)pkt->data, pkt->size);
		av_packet_free(&pkt);
	}
	ofs.close();

        但是为什么呢,这个空frame到底有什么用呢,还是说只要是传输完所有帧以后固定加上一段通过avcodec_send_frame 函数向编码器传入空 frame的操作就好了?

 

        在找了许多文章以后了解到

        当 avcodec_send_frame 函数传入空 frame 时,它会设置一个标志位。这个标志位的作用非常重要。它表示当前是最后一帧数据,后续的数据将无效。在 FFmpeg 的编码过程中,这个标志位可以让编码器知道当前的状态,以便采取相应的行动。 例如,编码器可以根据这个标志位判断是否需要进行 flush 操作,将剩余的帧压缩成 AVPacket。 如果标志位被设置,编码器会进入一种特殊的模式,处理剩余的数据并输出最后的编码结果。在实际应用中,这个标志位可以用于控制编码的结束时机。比如,当我们处理一个视频文件时,可以在确定所有的帧都已经被输入后,传入一个空 frame,触发编码器的结束操作。这意味着编码器应该将其内部缓冲区中的剩余数据全部编码并输出。这种机制在一些特定的场景下非常有用,比如在编码过程结束时,确保所有的数据都被处理完毕。通过传入空 frame,用户可以明确地告诉编码器已经没有更多的数据输入,让编码器将缓冲区中的数据全部处理掉,从而保证编码结果的完整性。同时,这也有助于在一些实时编码的场景中,及时处理剩余的数据,避免数据的积压和丢失!!!!

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值