如何识别libavcodec解码输出的隔行视频场是顶场还是底场?
解决libavcodec解码隔行视频时的场类型识别问题
一、直接读取AVFrame字段判断场类型
libavcodec的AVFrame结构体里有几个关键字段能直接判断当前场的类型:
interlaced_frame:非0值说明当前是隔行场(不是逐行帧)top_field_first:当interlaced_frame为1时,这个字段非0就代表当前是顶场,0则是底场
把你的解码循环改成这样就能识别场类型:
while (ret >= 0) { ret = avcodec_receive_frame(mpDecContext, mpDecFrame); if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) { break; } if (ret < 0) { // 处理解码错误 break; } // 判断场类型 if (mpDecFrame->interlaced_frame) { if (mpDecFrame->top_field_first) { // 当前是顶场,做对应处理 } else { // 当前是底场,做对应处理 } } else { // 这是逐行帧,不用处理场合并 } /// 后续帧处理逻辑 /// }
二、让解码器直接输出合并后的逐行帧(可选)
要是不想手动合并两场,也可以让解码器自动完成去隔行,在调用avcodec_open2打开解码器之前,给AVCodecContext加个配置:
mpDecContext->flags2 |= AV_CODEC_FLAG2_DEINTERLACE;
设置后解码器会自动把两场合并成一个完整的逐行帧输出,省得你自己处理场合并。不过注意这个选项不是所有解码器都完美支持,建议实际测试下。
三、关于解码器日志的补充
你看到的HEVC日志里的“TOP Field”信息,解码器已经自动解析并填充到AVFrame的top_field_first字段里了,直接读这个字段就行,不用自己去解析SEI数据。
内容的提问来源于stack exchange,提问作者Danny
相关产品推荐
相关产品推荐

