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。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM