1. 程式人生 > >ffmpeg 原始碼學習 -- 之命令列引數解析

ffmpeg 原始碼學習 -- 之命令列引數解析

ffmpeg 原始碼學習

-- 之ffmpeg命令列引數解析

大家通過git在安裝好cygwin之後,下載原始碼到(cygwin)home目錄,通過./configure  ...... ,可以新增一堆引數選項,執行可以生成config.mk等編譯使用的檔案,通過命令對工程編譯進行配置可以達到一些裁剪功能,去掉不需要的部分。然後make之後會生成fserver.exe ,ffmpeg.exe , ffprobe.exe , ffplayer.exe幾個可以供使用者使用的工具。

ffmpeg是一個命令列工具,主要將一個多媒體檔案不同格式之間進行轉換;ffserver是一個多媒體流伺服器,主要用於實時廣播;ffplay是一個小型的每天播放器,基於SDL和ffmpeg庫生成;最後ffprobe是一個簡單的流分析儀。

另外這些工具都支援哪些命令引數,怎麼使用,這個網上搜索很方便。但是要整體蒐集的話,有很好的方法。如:ffserver -help 就可以全部打印出來

$ ffserver.exe -h ffserver version N-57325-gf94124c Copyright (c) 2000-2013 the FFmpeg developers built on Oct 23 2013 02:17:58 with gcc 3.4.4 (GCC) (cygming special, gdc 0.12, using dmd 0.125) configuration: libavutil 52. 47.101 / 52. 47.101 libavcodec 55. 37.102 / 55. 37.102 libavformat 55. 19.103 / 55. 19.103 libavdevice 55. 4.100 / 55. 4.100 libavfilter 3. 89.100 / 3. 89.100 libswscale 2. 5.101 / 2. 5.101 libswresample 0. 17.104 / 0. 17.104 usage: ffserver [options] Hyper fast multi format Audio/Video streaming server Main options: -L show license -h topic show help -? topic show help -help topic show help --help topic show help -version show version -formats show available formats -codecs show available codecs -decoders show available decoders -encoders show available encoders -bsfs show available bit stream filters -protocols show available protocols -filters show available filters -pix_fmts show available pixel formats -layouts show standard channel layouts -sample_fmts show available audio sample formats -loglevel loglevel set logging level -v loglevel set logging level -report generate a report -max_alloc bytes set maximum size of a single allocated block -cpuflags flags force specific cpu flags -n enable no-launch mode -d enable debug mode -f configfile use configfile instead of /etc/ffserver.conf 想ffmpeg就可以支援的選項特別多,可以ffmpeg -help > ffmpeg_option.txt重定向到一個檔案裡,然後可以自己慢慢研究。 順便說明一下,該組織提供幾個供開發者使用的靜態庫: 1.libavformat用於各種音視訊格式的封裝和解析,獲取解碼需要的資訊以生成上下文結構讀取音視訊幀的功能; 2.libavcodec用於各種型別聲音/影象的編解碼; 3.libavutil公共模組提供一些公共工具函式; 4.libswscale用於視訊場景比例縮放,色彩對映轉換等等; 5.libpostproc用於後期效果處理 ffmpeg的命令引數如下: 1.獲取視訊的資訊 ffmpeg -i video.avi 2.將圖片序列合成視訊 ffmpeg -f image2 -i image%d.jpg video.mpg 上面的命令會把當前目錄下的圖片(名字如:image1.jpg. image2.jpg. 等...)合併成video.mpg 3.將視訊分解成圖片序列 ffmpeg -i video.mpg image%d.jpg 上面的命令會生成image1.jpg. image2.jpg. ... 支援的圖片格式有:PGM. PPM. PAM. PGMYUV. JPEG. GIF. PNG. TIFF. SGI 詳細可以參考官網:
http://ffmpeg.org/ffmpeg.html
這裡就詳細瞭解一下我們在使用ffmpeg工具時,傳入的引數是如何透傳下去的。 ffmpeg的命令列語法規則:ffmpeg [global_options] {[input_file_options] -i ‘input_file’} ... {[output_file_options] ‘output_file’} ... 在ffmpeg.c 檔案中,我們可以從main()中,
int main(int argc, char **argv)
{
    int ret;
    int64_t ti;

    register_exit(ffmpeg_cleanup);

    setvbuf(stderr,NULL,_IONBF,0); /* win32 runtime needs this */

    av_log_set_flags(AV_LOG_SKIP_REPEATED);
    parse_loglevel(argc, argv, options);

    if(argc>1 && !strcmp(argv[1], "-d")){
        run_as_daemon=1;
        av_log_set_callback(log_callback_null);
        argc--;
        argv++;
    }

    avcodec_register_all();
#if CONFIG_AVDEVICE
    avdevice_register_all();
#endif
    avfilter_register_all();
    av_register_all();
    avformat_network_init();

    show_banner(argc, argv, options);

    term_init();

    /* parse options and open all input/output files */
    ret = ffmpeg_parse_options(argc, argv);
    if (ret < 0)
        exit_program(1);

    if (nb_output_files <= 0 && nb_input_files == 0) {
        show_usage();
        av_log(NULL, AV_LOG_WARNING, "Use -h to get full help or, even better, run 'man %s'\n", program_name);
        exit_program(1);
    }

    /* file converter / grab */
    if (nb_output_files <= 0) {
        av_log(NULL, AV_LOG_FATAL, "At least one output file must be specified\n");
        exit_program(1);
    }

//     if (nb_input_files == 0) {
//         av_log(NULL, AV_LOG_FATAL, "At least one input file must be specified\n");
//         exit_program(1);
//     }

    current_time = ti = getutime();
    if (transcode() < 0)
        exit_program(1);
    ti = getutime() - ti;
    if (do_benchmark) {
        printf("bench: utime=%0.3fs\n", ti / 1000000.0);
    }
    av_log(NULL, AV_LOG_DEBUG, "%"PRIu64" frames successfully decoded, %"PRIu64" decoding errors\n",
           decode_error_stat[0], decode_error_stat[1]);
    if ((decode_error_stat[0] + decode_error_stat[1]) * max_error_rate < decode_error_stat[1])
        exit_program(69);

    exit_program(received_nb_signals ? 255 : 0);
    return 0;
}

可以看到,主要做了三件事:(1)註冊各類(de)muxer , (de)codec , portocol 等;(2)ffmpeg_parse_options解析解析輸入的引數項並開啟輸入輸出檔案;(3)transcode()函式開始檔案格式轉換 本篇主要看ffmpeg_parse_options,其在ffmpeg_opt.c檔案中定義 (1)從命令引數引數裡面分成三個部分,全域性選項引數 , 輸入檔案及其選項,輸出檔案及其選項; (2)ffmpeg_parse_options也主要按照引數的語法規則來,逐步操作; (3)分解命令列引數split_commandline (4)解析全域性的引數parse_optgroup (5)open_files開啟輸入,輸出檔案; (6)ffmpeg_opt.c檔案中全域性變數options包含所有命令及其關聯的操作符,詳看OptionDef結構體 關於ffmpeg和其他模組的關係,下次整理。