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

简介: libswscale 是 FFmpeg 中完成图像尺寸缩放和像素格式转换的库。

作者:叶余

来源: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。


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

阿里云视频云@凡科快图.png

相关文章
|
7月前
|
编解码
项目实战——Qt实现FFmpeg音视频转码器(二)
项目实战——Qt实现FFmpeg音视频转码器(二)
142 0
|
7月前
|
编解码 编译器
项目实战——Qt实现FFmpeg音视频转码器(一)
项目实战——Qt实现FFmpeg音视频转码器(一)
219 0
|
存储 Cloud Native Linux
音视频 FFmpeg命令行搭建
音视频 FFmpeg命令行搭建
|
4月前
|
编解码 NoSQL Java
使用Spring Boot + Redis 队列实现视频文件上传及FFmpeg转码的技术分享
【8月更文挑战第30天】在当前的互联网应用中,视频内容的处理与分发已成为不可或缺的一部分。对于视频平台而言,高效、稳定地处理用户上传的视频文件,并对其进行转码以适应不同设备的播放需求,是提升用户体验的关键。本文将围绕使用Spring Boot结合Redis队列技术来实现视频文件上传及FFmpeg转码的过程,分享一系列技术干货。
254 3
|
4月前
|
编解码 Linux
CentOS安装ffmpeg并转码视频为mp4
CentOS安装ffmpeg并转码视频为mp4
158 0
|
6月前
|
编解码
FFmpeg之转码
FFmpeg之转码
|
7月前
|
机器学习/深度学习 编解码 API
FFmpeg命令行解析
FFmpeg命令行解析
445 1
|
7月前
|
编解码 开发工具
获取ffmpeg转码的实时进度
获取ffmpeg转码的实时进度
252 0
|
7月前
|
编解码 vr&ar 内存技术
FFmpeg常用命令行讲解及实战一(三)
FFmpeg常用命令行讲解及实战一
354 0
|
7月前
|
编解码
FFmpeg常用命令行讲解及实战一(二)
FFmpeg常用命令行讲解及实战一
82 0