国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

FFmpeg aresample_swr_opts的解析

這篇具有很好參考價(jià)值的文章主要介紹了FFmpeg aresample_swr_opts的解析。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問(wèn)。

ffmpeg option的解析

aresample_swr_opts是AVFilterGraph中的option。

static const AVOption filtergraph_options[] = {
    { "thread_type", "Allowed thread types", OFFSET(thread_type), AV_OPT_TYPE_FLAGS,
        { .i64 = AVFILTER_THREAD_SLICE }, 0, INT_MAX, F|V|A, "thread_type" },
        { "slice", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AVFILTER_THREAD_SLICE }, .flags = F|V|A, .unit = "thread_type" },
    { "threads",     "Maximum number of threads", OFFSET(nb_threads), AV_OPT_TYPE_INT,
        { .i64 = 0 }, 0, INT_MAX, F|V|A, "threads"},
        {"auto", "autodetect a suitable number of threads to use", 0, AV_OPT_TYPE_CONST, {.i64 = 0 }, .flags = F|V|A, .unit = "threads"},
    {"scale_sws_opts"       , "default scale filter options"        , OFFSET(scale_sws_opts)        ,
        AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, F|V },
    {"aresample_swr_opts"   , "default aresample filter options"    , OFFSET(aresample_swr_opts)    ,
        AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, F|A },
    { NULL },
};

因?yàn)槭莖ption,所以就想能不能將這個(gè)option配置到graph里面,分析代碼發(fā)現(xiàn),AVFilterGraph::aresample_swr_opts在graph解析的時(shí)候不能當(dāng)做filter的option解析。

因?yàn)間raph load的在解析graph文本的過(guò)程,option來(lái)自filter的option,aresample_swr_opts是AVFilterGraph的option,而AVFilterGraph不在filter的list中,所以graph解析并不能識(shí)別aresample_swr_opts。

但是aresample_swr_opts從名字來(lái)看,就是為了給swresample用的,所以,先看下命令行是怎么用的。

命令行支持,并不是直接用aresample_swr_opts指定swresample的option,而是不用寫(xiě)成這樣aresample=resampler=swr:filter_size=16,即用filter帶option的寫(xiě)法,直接寫(xiě)option也能解析。

如下:

ffmpeg -y -i test.wav -filter_size 16 -phase_shift 6 -ar 48000 out.wav

其中filter_sizephase_shift會(huì)在解析的時(shí)候讀取swr class的option,匹配成功后,拼接成swr_opts字符串,最后將swr_opts設(shè)置到graph->aresample_swr_opts上。avfiltergraph中協(xié)商如果convert_needed大于0,就會(huì)創(chuàng)建對(duì)應(yīng)的swresample,將aresample_swr_opts中的option作為swresample的option參數(shù)傳入。

其中-filter_size 16,-phase_shift 6是被當(dāng)做option解析的,會(huì)進(jìn)入opt_default函數(shù),因?yàn)檫@兩個(gè)參數(shù)是swresample的,所以對(duì)應(yīng)代碼是:

#if CONFIG_SWRESAMPLE
    if (!consumed && (o=opt_find(&swr_class, opt, NULL, 0,
                                    AV_OPT_SEARCH_CHILDREN | AV_OPT_SEARCH_FAKE_OBJ))) {
        av_dict_set(&swr_opts, opt, arg, FLAGS);
        consumed = 1;
    }
#endif

解析后會(huì)把這兩個(gè)option設(shè)置到swr_opts上。

然后進(jìn)入configure_filtergraph函數(shù),會(huì)將這個(gè)option設(shè)置到aresample_swr_opts

while ((e = av_dict_get(ost->swr_opts, "", e,
                        AV_DICT_IGNORE_SUFFIX))) {
    av_strlcatf(args, sizeof(args), "%s=%s:", e->key, e->value);
}
if (strlen(args))
    args[strlen(args)-1] = 0;
av_opt_set(fg->graph, "aresample_swr_opts", args, 0);

然后在avfiltergraph的query_formats函數(shù)中,創(chuàng)建convert filter的時(shí)候?qū)ption傳進(jìn)去:

snprintf(inst_name, sizeof(inst_name), "auto_%s_%d",
         neg->conversion_filter, converter_count++);
opts = FF_FIELD_AT(char *, neg->conversion_opts_offset, *graph);
ret = avfilter_graph_create_filter(&convert, filter, inst_name, opts, NULL, graph);

其中,graph參數(shù)中,可以看到aresample_swr_opts就是"filter_size=16:phase_shift=6"。

FFmpeg aresample_swr_opts的解析,ffmpeg

graph中解析swr option

跟蹤程序運(yùn)行過(guò)程,在不走ffmpeg命令行程序的時(shí)候,像前面,直接設(shè)置在avfilter里面類(lèi)似cmdutils.c里面的邏輯,添加對(duì)swr的處理,就可以在自定義程序中l(wèi)oad graph的時(shí)候如同命令行程序一樣,解析swr的option。

最終實(shí)現(xiàn)如下:

+#include "libswresample/swresample.h"

 #define FF_INTERNAL_FIELDS 1
 #include "framequeue.h"
@@ -951,6 +952,10 @@ static int process_options(AVFilterContext *ctx, AVDictionary **options,
     char *av_uninit(parsed_key), *av_uninit(value);
     const char *key;
     int offset= -1;
+#if CONFIG_SWRESAMPLE
+    char swr_opts[256] = { 0 };
+    const AVClass *swr_class = swr_get_class();
+#endif

     if (!args)
         return 0;
@@ -995,24 +1000,31 @@ static int process_options(AVFilterContext *ctx, AVDictionary **options,
                 av_free(parsed_key);
                 return ret;
             }
-        } else {
-            o = av_opt_find(ctx->priv, key, NULL, 0,
-                            AV_OPT_SEARCH_CHILDREN | AV_OPT_SEARCH_FAKE_OBJ);
-            if (!o) {
-                av_log(ctx, AV_LOG_ERROR, "Option '%s' not found\n", key);
-                av_free(value);
-                av_free(parsed_key);
-                return AVERROR_OPTION_NOT_FOUND;
-            }
+        } else if (o = av_opt_find(ctx->priv, key, NULL, 0,
+                            AV_OPT_SEARCH_CHILDREN | AV_OPT_SEARCH_FAKE_OBJ)) {
             av_dict_set(options, key, value,
                         (o->type == AV_OPT_TYPE_FLAGS &&
                          (value[0] == '-' || value[0] == '+')) ? AV_DICT_APPEND : 0);
+#if CONFIG_SWRESAMPLE
+        } else if (o = av_opt_find(&swr_class, key, NULL, 0, 0)) {
+            av_strlcatf(swr_opts, sizeof(swr_opts), "%s=%s:", key, value);
+#endif
+        } else {
+            av_log(ctx, AV_LOG_ERROR, "Option '%s' not found\n", key);
+            av_free(value);
+            av_free(parsed_key);
+            return AVERROR_OPTION_NOT_FOUND;
         }

         av_free(value);
         av_free(parsed_key);
     }

+    if (strlen(swr_opts)) {
+        swr_opts[strlen(swr_opts) - 1] = 0;
+        av_opt_set(ctx->graph, "aresample_swr_opts", swr_opts, 0);
+    }
+

這樣,在graph中配置上filter_size=16:phase_shift=6,然后,load graph的時(shí)候并不會(huì)在avfiltergraph里面進(jìn)行解析,播放的時(shí)候,調(diào)用avfilter_graph_reconfig,調(diào)用棧如下:

query_formats(AVFilterGraph * graph, void * log_ctx) (ffmpeg/libavfilter/avfiltergraph.c:747)
graph_config_formats(AVFilterGraph * graph, void * log_ctx) (ffmpeg/libavfilter/avfiltergraph.c:1373)
avfilter_graph_reconfig(AVFilterGraph * graphctx, void * log_ctx) (ffmpeg/libavfilter/avfiltergraph.c:1519)
movie_async_activate(AVFilterContext * ctx) (ffmpeg/libavfilter/src_movie_async.c:1254)
ff_filter_activate(AVFilterContext * filter) (ffmpeg/libavfilter/avfilter.c:1565)
ff_filter_graph_run_all(AVFilterGraph * graph) (ffmpeg/libavfilter/avfiltergraph.c:1718)

進(jìn)入query_formats之后,獲取opts,就是前面在graph中配置的opts:

opts = FF_FIELD_AT(char *, neg->conversion_opts_offset, *graph);
if (link->type == AVMEDIA_TYPE_AUDIO) {
    snprintf(inst_opts, sizeof(inst_opts), "converter=%d:%s", convert_needed, opts ? opts : "");
    opts = inst_opts;
}
snprintf(inst_name, sizeof(inst_name), "auto_%s", neg->conversion_filter);
ret = avfilter_graph_create_filter(&convert, filter, inst_name, opts, NULL, graph);
if (ret < 0)
    return ret;
if ((ret = avfilter_insert_filter(link, convert, 0, 0)) < 0)
    return ret;

最后創(chuàng)建filter的時(shí)候,就會(huì)將這些options設(shè)置到fitler上。

附:ffmpeg help命令的解析

當(dāng)用戶在命令行中輸入ffmpeg -hffmpeg -help時(shí),show_help_default函數(shù)會(huì)被調(diào)用,輸出幫助信息。該函數(shù)還可以在其他情況下被調(diào)用,例如當(dāng)用戶輸入無(wú)效的命令行選項(xiàng)時(shí),或者當(dāng)用戶輸入ffmpeg -h <選項(xiàng)>時(shí),顯示特定選項(xiàng)的幫助信息。

ffmpeg --help full

如果是help full,會(huì)有這樣的調(diào)用層次,并且show_avoptions和show_advanced都被賦值為1:

show_help
- show_help_default
	- show_help_options

在show_help_options中:

    if (opt && *opt) {
        if (!strcmp(opt, "long"))
            show_advanced = 1;
        else if (!strcmp(opt, "full"))
            show_advanced = show_avoptions = 1;
        else
            av_log(NULL, AV_LOG_ERROR, "Unknown help option '%s'.\n", opt);
    }

show_avoptions的分支中:

    if (show_avoptions) {
        int flags = AV_OPT_FLAG_DECODING_PARAM | AV_OPT_FLAG_ENCODING_PARAM;
        show_help_children(avcodec_get_class(), flags);
        show_help_children(avformat_get_class(), flags);
#if CONFIG_SWSCALE
        show_help_children(sws_get_class(), flags);
#endif
#if CONFIG_SWRESAMPLE
        show_help_children(swr_get_class(), AV_OPT_FLAG_AUDIO_PARAM);
#endif
        show_help_children(avfilter_get_class(), AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_FILTERING_PARAM);
        show_help_children(av_bsf_get_class(), AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_BSF_PARAM);
    }

這里,會(huì)遍歷avcodec,avformatsws,swr,avfilter,av_bsf的class,將其children class對(duì)應(yīng)的option全部顯示出來(lái)。文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-615690.html

到了這里,關(guān)于FFmpeg aresample_swr_opts的解析的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來(lái)自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • ffmpeg中filter_query_formats函數(shù)解析

    ffmpeg中filter_query_formats函數(shù)解析

    ffmpeg中filter_query_formats主要起一個(gè)pix fmt引用指定的功能。 下下結(jié)論: 先看幾個(gè)結(jié)構(gòu)體定義: 結(jié)構(gòu)體: AVFilterFormatsConfig 再來(lái)看函數(shù): 核心函數(shù): ff_set_common_formats 看宏定義: 接著看ref 主要看關(guān)鍵的三行代碼: 這就是最開(kāi)始圖片指示的互相引用。

    2024年02月16日
    瀏覽(15)
  • 用ffmpeg解析mp4文件得到時(shí)長(zhǎng)、比特率、音視頻信息

    以下是使用C++語(yǔ)言調(diào)用FFmpeg獲取視頻流和音頻流信息的示例代碼: 上述代碼通過(guò) AVFormatContext 結(jié)構(gòu)體和FFmpeg庫(kù)函數(shù) avformat_open_input 、 avformat_find_stream_info 等,獲取MP4文件的視頻流和音頻流信息,并將結(jié)果存儲(chǔ)到 MediaInfo 類(lèi)中。在實(shí)際應(yīng)用中,可以將上述代碼封裝成一個(gè)函數(shù),

    2024年02月12日
    瀏覽(96)
  • 音視頻項(xiàng)目—基于FFmpeg和SDL的音視頻播放器解析(三)

    介紹 在本系列,我打算花大篇幅講解我的 gitee 項(xiàng)目音視頻播放器,在這個(gè)項(xiàng)目,您可以學(xué)到音視頻解封裝,解碼,SDL渲染相關(guān)的知識(shí)。您對(duì)源代碼感興趣的話,請(qǐng)查看基于FFmpeg和SDL的音視頻播放器 如果您不理解本文,可參考我的前一篇文章音視頻項(xiàng)目—基于FFmpeg和SDL的音視

    2024年02月05日
    瀏覽(106)
  • 音視頻項(xiàng)目—基于FFmpeg和SDL的音視頻播放器解析(二十一)

    介紹 在本系列,我打算花大篇幅講解我的 gitee 項(xiàng)目音視頻播放器,在這個(gè)項(xiàng)目,您可以學(xué)到音視頻解封裝,解碼,SDL渲染相關(guān)的知識(shí)。您對(duì)源代碼感興趣的話,請(qǐng)查看基于FFmpeg和SDL的音視頻播放器 如果您不理解本文,可參考我的前一篇文章音視頻項(xiàng)目—基于FFmpeg和SDL的音視

    2024年02月02日
    瀏覽(101)
  • FFmpeg 解析Glide 緩存下的圖片文件報(bào)錯(cuò)(Impossible to open xxx)

    FFmpeg 解析Glide 緩存下的圖片文件報(bào)錯(cuò)(Impossible to open xxx)

    簡(jiǎn)單介紹下背景 我們業(yè)務(wù)有個(gè)功能把圖片放到一個(gè)文件中,統(tǒng)一進(jìn)行播放 ,但是遇到一個(gè)棘手問(wèn)題,某一個(gè)情況下 的圖片 就是打不開(kāi) 就是報(bào)錯(cuò)。以為是編譯參數(shù) 。哪些格式?jīng)]有加上。但經(jīng)過(guò)測(cè)試 該加的都加了。 所以 不是編譯參數(shù)的問(wèn)題。 Impossible to open \\\'/data/user/0/com.x

    2024年02月08日
    瀏覽(24)
  • DXGI高幀率屏幕錄像軟件源碼解析(聲音捕獲,抓屏,ffmpeg錄像,MP4錄像,flv錄像,麥克風(fēng)采集)(第4篇編碼,錄像部分)

    DXGI高幀率屏幕錄像軟件源碼解析(聲音捕獲,抓屏,ffmpeg錄像,MP4錄像,flv錄像,麥克風(fēng)采集)(第4篇編碼,錄像部分)

    本文DEMO源碼下載: https://download.csdn.net/download/xjb2006/85109025 dxgi桌面屏幕錄像(windows屏幕錄像,硬件編碼,聲音捕獲,音視頻同步) 由于篇幅有限,分為4篇發(fā)表: 1、SDK接口一覽: 2、聲音采集部分: 3、屏幕捕獲部分: 4、編碼,錄像部分: 距離上篇文章已經(jīng)過(guò)了快1年了,才

    2023年04月17日
    瀏覽(20)
  • [FFmpeg] 常用ffmpeg命令

    去水印 ?ffmpeg -i water.jpeg -strict -2 -vf delogo=x=300:y=250:w=56:h=18:show=0 no_water.jpeg 打時(shí)間戳 ffmpeg -i perf_60Hz_Raw.mp4 -vf \\\"drawtext=fontsize=160:fontcolor=red:text=\\\'%{pts:hms}\\\'\\\" -c:v libx264 -an -f mp4 perf_output.mp4 -y ffmpeg -i perf_8k.mp4 -vf \\\"drawtext=fontsize=160:fontcolor=red:text=\\\'%{pts:hms}\\\'\\\" -c:v libx264 -an -f mp4 perf_outpu

    2024年02月10日
    瀏覽(15)
  • 【ffmpeg基礎(chǔ)】ffmpeg視頻編碼

    通過(guò)-s來(lái)指定輸入yuv的分辨率(需要先指定分辨率); 通過(guò)-pix_fmt來(lái)指定輸入yuv的像素格式; 通過(guò)-i來(lái)指定輸入yuv的路徑和名稱(chēng); 通過(guò)-r 來(lái)指定要編碼的幀率; 通過(guò)-vcodec來(lái)指定視頻編碼的編碼器為libx264 通過(guò)-an參數(shù)來(lái)去掉輸入input.mp4中的音頻,并通過(guò)-vcodec libx264將輸入的視頻進(jìn)

    2024年02月14日
    瀏覽(21)
  • 【ffmpeg基礎(chǔ)】ffmpeg的下載安裝

    【ffmpeg基礎(chǔ)】ffmpeg的下載安裝

    1、ffmpeg github下載路徑:https://github.com/FFmpeg/FFmpeg.git 在ffmpeg的github上可以下載任意版本的源碼,比如最新的matser上的源碼,以及各個(gè)分支上(如ffmpeg的5.1版本)的源碼,如下圖。 2、ffmpeg官方網(wǎng)站:https://www.ffmpeg.org/ ;在官方網(wǎng)站內(nèi)也可以下載ffmpeg的源碼以及ffmpeg編譯好的庫(kù)文件

    2024年02月04日
    瀏覽(21)
  • Linux系統(tǒng)安裝ffmpeg & 升級(jí)ffmpeg

    一、介紹 多媒體視頻處理工具FFmpeg有非常強(qiáng)大的功能,包括視頻采集功能、視頻格式轉(zhuǎn)換、視頻抓圖、給視頻加水印等。由于最近要處理音視頻格式轉(zhuǎn)換問(wèn)題,因此需要安裝、升級(jí)ffmpeg,下面來(lái)記錄一下踩坑過(guò)程。 二、安裝?ffmpeg 1、下載并解壓ffmpeg 2、指定安裝路徑(/usr

    2024年01月20日
    瀏覽(17)

覺(jué)得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包