使用ffmpeg、x264库强制编出关键帧(I帧)
背景
当h264数据在使用udp传输时,丢包是一件很常见的事情,当接收端丢包发生后,应该通知发送端,让发送端立刻重新发送一个关键帧。此时就需要编码器无视关键帧间隔立刻编出一个关键帧。
那么怎么让编码器立刻编出关键帧呢?接下来就列举常用的两种编码器ffmpeg、x264重编出关键帧的方法。
编码库的使用方法在网上有很多文章。本文假设读者已经了解编码库的使用,不再赘述编码库的使用。仅描述关键部分。
编码
x264
_pic->i_type = X264_TYPE_KEYFRAME;
x264_encoder_encode(_encoder, &nal, &i_nal,_pic, &pic_out);
在使用x264编码器的x264_encoder_encode
函数时,第四个参数存储要编码的YUV数据。其中有个成员i_type
表示要求编码器编出的帧类型。通常我们默认会将这个i_type
成员设为X264_TYPE_AUTO
,表示由编码器自动选择类型。当我们想要强制编码出关键帧时,只要将这个i_type
成员设为X264_TYPE_KEYFRAME
即可,之后恢复为X264_TYPE_AUTO
。
ffmpeg
pFrame->pict_type = AV_PICTURE_TYPE_I;
avcodec_encode_video2(pCodecCtx, &pkt,pFrame, &got_picture);
在使用ffmpeg编码器的avcodec_encode_video2
函数时,第三个参数存储要编码的YUV数据。其中有个成员pict_type
表示要求编码器编出的帧类型。通常我们默认不会设置这个pict_type
,由编码器自动选择类型。当我们想要强制编码出关键帧时,只要将这个pict_type
成员设为AV_PICTURE_TYPE_I
即可,之后恢复为AV_PICTURE_TYPE_NONE
。
总结
使用h264编码器强制编出关键帧,是实时视频传输中的一个关键的技术点,但是网上的博客只有ffmpeg的旧版本的方法,对于新版ffmpeg和x264库根本没有提及。所以我在此篇文章中将此技术点记录下来。