FFmpeg libswscale源码分析2-转码命令行与滤镜图

作者:叶余

来源:https://www.cnblogs.com/leisure_chn/p/14355015.html


libswscale 源码分析系列文章:

[1]. FFmpeg libswscale源码分析1-API介绍

[2]. FFmpeg libswscale源码分析2-转码命令行与滤镜图

[3]. FFmpeg libswscale源码分析3-scale滤镜源码分析

[4]. FFmpeg libswscale源码分析4-libswscale源码分析

源码分析基于 FFmpeg 4.1 版本。

2. 转码命令行与滤镜图

本节从 ffmpeg 转码命令开始,引入一个完整的示例:hevc yuv422p10le 源软解硬编为 hevc yuv420p10le 视频。

第 2 节、第 3 节、第 4 节是由上到下分层的关系。第 2 节介绍命令行,通过命令行调用 ffmpeg 进程。第 3 节介绍 scale 滤镜,ffmpeg 进程使用了 scale 滤镜,scale 滤镜中会调用 libswscale 库。第 4 节介绍 libswscale 库。

查看 ffmpeg 中 hevc_nvenc 支持的像素格式:

[root@node0 ~]# ffmpeg -hide_banner -h encoder=hevc_nvenc | grep "pixel formats" 
    Supported pixel formats: yuv420p nv12 p010le yuv444p p016le yuv444p16le bgr0 rgb0 cuda

在如下代码 for 循环处打断点,分析滤镜图中的各个滤镜输入输出像素格式:

static int graph_config_links(AVFilterGraph *graph, AVClass *log_ctx)
{
    AVFilterContext *filt;
    int i, ret;

    for (i = 0; i < graph->nb_filters; i++) {
        filt = graph->filters[i];

        if (!filt->nb_outputs) {
            if ((ret = avfilter_config_links(filt)))
                return ret;
        }
    }

    return 0;
}

不显式指定滤镜的转码命令:

ffmpeg -hide_banner -y -re -i ./hevc_4k_422_10b_5994_60m_vibe.ts 
-c:v hevc_nvenc -preset fast -profile:v main10 -c:a aac -f mpegts /dev/null

滤镜图如下:

         yuv422p10le   yuv422p10le    yuv444p16le     yuv444p16le
[buffer] -----> [null] -----> [scale] -----> [format] -----> [buffersink]

ffmpeg 自动插入滤镜,协商滤镜格式。buffer 滤镜输出的格式是 ffmpeg hevc 解码器解码输出的图像像素格式,是 yuv422p10le。buffersink 滤镜的输入格式,是 ffmpeg 在 buffersink 滤镜前插入 format 滤镜,在执行 format 滤镜初始化时,从 hevc_nvenc 编码器支持的像素格式列表中,选定了 yuv444p16le,作为编码器的输入格式。由 scale 滤镜执行像素格式转换操作:yuv422p10le 转为 yuv444p16le。

通过滤镜指定格式 yuv420p10le:

ffmpeg -hide_banner -y -re -i ./hevc_4k_422_10b_5994_60m_vibe.ts -vf format=yuv420p10le 
-c:v hevc_nvenc -preset fast -profile:v main10 -c:a aac -f mpegts /dev/null

滤镜图如下:

         yuv422p10le     yuv420p10le      yuv420p10le     p010le           p010le
[buffer] ------> [scale] ------> [format] ------> [scale] ------> [format] ------> [buffersink]

第三个滤镜 format 是我们在命令行中给出的滤镜。第五个滤镜 format 是编码器输入格式滤镜,是 ffmpeg 在滤镜图与编码器间进行像素格式协商时,在 hevc_nvenc 编码器支持的像素格式列表中,选择了 p010le 像素格式作为编码器的输入格式,并在此 format 滤镜前自动插入一个 scale 滤镜执行像素格式转换。

可以看到,一个像素格式转换,在命令行中是由一个 scale 滤镜紧跟一个 format 滤镜实现的,scale + format 滤镜可由用户在命令中显式给出,ffmpeg 也会根据实际情况按需插入。

通过滤镜指定格式 p010le:

ffmpeg -hide_banner -y -re -i ./hevc_4k_422_10b_5994_60m_vibe.ts -vf format=p010le 
-c:v hevc_nvenc -preset fast -profile:v main10 -c:a aac -f mpegts /dev/null

滤镜图如下:

         yuv422p10le     p010le           p010le           p010le
[buffer] ------> [scale] ------> [format] ------> [format] ------> [buffersink]

第三个滤镜 format 是我们在命令行中给出的滤镜。第四个滤镜 format 是编码器输入格式滤镜,是 ffmpeg 在滤镜图与编码器间进行像素格式协商时,在 hevc_nvenc 编码器支持的像素格式列表中,选择了 p010le 像素格式作为编码器的输入格式。第二个滤镜 scale 执行实际的像素格式转换操作:yuv422p10le 转 p010le。


「视频云技术」你最值得关注的音视频技术公众号,每周推送来自阿里云一线的实践技术文章,在这里与音视频领域一流工程师交流切磋。

FFmpeg libswscale源码分析2-转码命令行与滤镜图

上一篇:app获取定位


下一篇:真机运行 vue axios 在ios 中不执行回调