1. 程式人生 > >FFmpeg 自定義命令列引數

FFmpeg 自定義命令列引數

我們在使用 FFmpeg 的時候,會發現 FFmpeg 有些庫的效能並不是特別的好,可能就想要使用其他效能更好的第三方SDK 或 自己開發的SDK來替換。這時可能 FFmpeg 的預設命令列引數並不能我們的需求,就需要自定義命令列引數。那麼如何來自定義命令列引數達到我們的需求呢?

此次我們在 FFmpeg 中增加了 libyuv 的影象縮放演算法,那麼就可以在 swscale_options[](FFmpeg 內建 swscale 過濾器相關引數陣列) 中新增一個 “scale_method” 用來選擇影象縮放演算法。

新增引數前,需要先做一些前置動作

  • 定義 scale_method 引數

    在 swscale_internal.h 的 SwsContext 結構體中新增一個屬性 int scale_method;

    FFmpeg 接收引數後進行解析,並將使用者傳入的值賦值給對應結構體內的屬性。

  • 定義引數選項

    在 swscale.h 中定義:

    // libyuv 的 scale 方法
    #define SWS_SCALE             1
    #define LIB_YUV_NONE          2
    #define LIB_YUV_BILINEAR      3
    #define LIB_YUV_BOX           4
    

新增前面的定義後,就可以新增自定義引數了

​ 在 libswscale/options.c 檔案中的 swscale_options[] 陣列中新增:

{ "scale_method",    "choice swscale or libyuv to scale", OFFSET(scale_method), AV_OPT_TYPE_FLAGS,  { .i64 = SWS_SCALE          },  1,       2,              VE, "scale_method"},
    { "swscale",         "use swscale to scale",              0
, AV_OPT_TYPE_CONST, { .i64 = SWS_SCALE }, INT_MIN, INT_MAX, VE, "scale_method"}, { "libyuv_none", "use libyuv KFilterNone scale", 0, AV_OPT_TYPE_CONST, { .i64 = LIB_YUV_NONE }, INT_MIN, INT_MAX, VE, "scale_method" }, { "libyuv_bilinear", "use libyuv KFilterBilinear scale", 0, AV_OPT_TYPE_CONST, { .i64 = LIB_YUV_BILINEAR }, INT_MIN, INT_MAX, VE, "scale_method" }, { "libyuv_box", "use libyuv KFilterBox scale", 0, AV_OPT_TYPE_CONST, { .i64 = LIB_YUV_BOX }, INT_MIN, INT_MAX, VE, "scale_method" },

對應各個變數的定義如下:

{名稱, 簡介,相對結構體首部地址的偏移量,選項的型別,選項的預設值,選項的最小值,選項的最大值,標記,所屬的邏輯單元(可為空)}

  • 新增完自定義引數後就可以在需要更改的地方獲取引數,然後進行相應的邏輯更改

    int scale_method = sws->scale_method;
        if (scale_method == LIB_YUV_BILINEAR || scale_method == LIB_YUV_BOX || scale_method == LIB_YUV_NONE) {
            enum FilterMode mode =  kFilterNone;
            switch (scale_method)
            {
                case LIB_YUV_BILINEAR :
                    mode = kFilterBilinear;
                    break;
                case LIB_YUV_BOX :
                    mode = kFilterBox;
                    break;
                default:
                    break;
            }
            // 使用 libyuv 的 scale 方法
            return I420Scale(in[0], in_stride[0], in[1], in_stride[1], in[2], in_stride[2], 
                    cur_pic->width, cur_pic->height, 
                    out[0], out_stride[0], out[1], out_stride[1], out[2], out_stride[2], 
                    out_buf->width, out_buf->height, mode);
        } 
        else
        {
            // 使用 sws_scale
            return sws_scale(sws, in, in_stride, y/mul, h,
                              out,out_stride);
        }
    

新增完自定義引數後,就可以通過傳入 "-scale_method","libyuv_none" 來選擇 KFilterNone 影象縮放演算法.

其他的引數也可參照著去更改

  • 首先定位需要修改的地方

  • 然後根據業務找到引數定義的位置(預設引數或 avcodec_options、avformat_options、avresample_options等專屬引數)

  • 在對應引數陣列中新增自定義引數&對應結構體的屬性

  • 獲取結構體屬性進行相應邏輯更改。