看到某篇文章描述了一个“bug”:
ffmpeg -i ~/Movies/cctv.mp4 -an -pix_fmt nv12 -t 1 /tmp/test.mp4
ffprobe /tmp/test.mp4显示
Stream #0:0[0x1](und): Video: h264 (High) (avc1 / 0x31637661), yuv420p(progressive)
文章将其【错误的】解释为pixel_format设置没生效。
另一个常见的类似问题是:
- 为什么ffmpeg libfdk_aac编码器输入是AV_SAMPLE_FMT_S16,但是ffprobe编码输出的aac,还是显示为fltp?
伴随着的另一个问题是为什么(内置)aac编码器不支持S16?
这类问题涉及一个常见的误区,没搞清楚
编码器输入数据格式 != 码流中的“数据格式” != 解码输出的数据格式
首先说下码流中的“数据格式”。对于H.264、H.265等编码格式来说,码流中并不包含某个pixel format,它们包含的信息是:
- chroma下采样情况:400(黑白视频,只有Y)、420(4:1:1)、422(4:2:2)、444(4:4:4)
- bit depth:8比特、10比特等
码流中不存在pixel format,不区分YUV420、NV12、NV21还是什么。当然,像一些裸流封装格式如y4m是有明确的pixel format的。这里只针对常用的视频编码格式而言。音频编码我不熟悉,按我的理解,AAC编码标准是按照浮点来定义的,AAC码流中的“数据模型”始终是浮点类型。
其次说下编码器的输入数据格式。以libx264为例,libx264支持的pixel format很多:
static const enum AVPixelFormat pix_fmts_all[] = {
AV_PIX_FMT_YUV420P,
AV_PIX_FMT_YUVJ420P,
AV_PIX_FMT_YUV422P,
AV_PIX_FMT_YUVJ422P,
AV_PIX_FMT_YUV444P,
AV_PIX_FMT_YUVJ444P,
AV_PIX_FMT_NV12,
AV_PIX_FMT_NV16,
#ifdef X264_CSP_NV21
AV_PIX_FMT_NV21,
#endif
AV_PIX_FMT_YUV420P10,
AV_PIX_FMT_YUV422P10,
AV_PIX_FMT_YUV444P10,
AV_PIX_FMT_NV20,
#ifdef X264_CSP_I400
AV_PIX_FMT_GRAY8,
AV_PIX_FMT_GRAY10,
#endif
AV_PIX_FMT_NONE
}
这些pixel format中,有些因素影响编码输出的码流,例如:
- YUV420P和YUVJ420P影响VUI中色彩相关信息描述(limited range vs full range)
- YUV420P和YUV420P10产生8bit和10bit的差异
- YUV420P和YUV444P有chroma下采样的差异
但是,输入pixel format YUV420P、NV12、NV21等,输出码流是一样的。这些只有数据存储方式差异的pixel format影响libx264怎么读数据,不影响它的编码输出。
最后说下ffprobe展示的pixel format。ffprobe展示的pixel format是从demuxer、parser和decoder获取到的。ffprobe展示的pixel format与解码器具体实现有关:
- FFmpeg内置的H.264、H.265软件解码器代码实现上是输出YUV420P、YUV420P10等,所以ffprobe展示的pixel format是YUV420P;
- 假如禁用默认的解码器,有个第三方的解码器默认输出pixel format NV12,则ffprobe会展示nv12
码流中没有pixel format,但一般解码器设计实现上,输出pixel format与码流相关,所以ffprobe展示的结果“间接的“与码流有关。但也有一些例外,比如简化设计实现的解码器,一股脑用同一种pixel format输出也是存在的,不管8bit 10bit。某些第三方解码器存在这种情况。
作者:quink
来源:Fun With FFmpeg
原文:https://mp.weixin.qq.com/s/9muoiIk8A1-Us0uqzY9A_Q
版权声明:本文内容转自互联网,本文观点仅代表作者本人。本站仅提供信息存储空间服务,所有权归原作者所有。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至1393616908@qq.com 举报,一经查实,本站将立刻删除。