none
ffmpegライブラリを使ってプログラムから AVCodecContext.rc_max_rate/rc_min_rateの情報を取得したい RRS feed

  • 質問

  • 開発環境は VisualStudio2019 VC++ です。 (対象OSはWindows10以降)
    ffmpegは V4.3.1を使っています。

    タイトル通りなんですが、 MP4動画ファイルを読み込んで AVCodecContext.rc_max_rate/rc_min_rateの値を取得したいです。
    (最終目標はこの値を取って動画ファイルの CBR/VBRを区別したい)


    試した流れです。 (ここのMP4動画ファイルは ffprobeではmax_bit_rateに値が入っていました)
    ----------------------------------------------------------------------------
    av_register_all();
    AVFormatContext* fmt_ctx= avformat_open_input(&fmt_ctx, "MP4動画ファイルパス", 0, NULL);
    avformat_find_stream_info(fmt_ctx, NULL);
    AVStream* video_stream = fmt_ctx->streams[0];

    av_dump_format(fmt_ctx, 0, "MP4動画ファイルパス", 0); // これはコメントアウトもテスト

    // 以下はffprobe.cを参考にしました。
    AVCodec* codec = avcodec_find_decoder(video_stream->codecpar->codec_id)
    AVCodecContext* codec_context = avcodec_alloc_context3(codec);
    avcodec_parameters_to_context(codec_context, video_stream->codecpar)
    codec_context->pkt_timebase = video_stream->time_base;
    avcodec_open2(codec_context, codec, NULL )
    ----------------------------------------------------------------------------
    avcodec_open2の後
    codec_context.rc_max_rateに値が入るのでは と考えていたのですが、0になります。 (codec_nameや サイズなどいくつかの情報は取れています)


    ffmpegに関しては先週から初めて使いだしたので
    AVDictionaryに値をセットしてavcodec_open2を呼べばいいのか、そもそもdecodeでは取れないのか、現状判っていません。

    ffmpeg以外(MediaInfoとか)を使え というのは無しでお願いします

    幾つかのサイトに質問を出しているのですが、答える人が全くいないのでいつものここに助けを求めに来ました。
    よろしくお願いします。


    2022年5月29日 9:39

すべての返信

  • 小生もffmpegを知ったのは数週間前なのですが、AVCodeContext Struct Referenceの「RcOverride * rc_max_rate」の説明(の中のMore...をクリック)を見ると、

    int64_t AVCodeContext::rc_max_rate

      maximum bitrate

      ・encoding: Set by user

      ・decoding: Set by user, may be overwritten by libavcodec

    Definitions at 2398 of file avcodec.h

    Referenced by aom_init(), ff_mpv_encode_init(), ff_mpv_encode_picture(), ff_vbv_update(), libvorbis_setup(), modify_qscale(), qsv_retrieve_enc_parames(), and vpx_init()

    とあるので、rc_max_rateは出力パラメータではなく入力パラメータのように見えます。その値を参照する内部関数(と思う)が列挙されています。

    rc_min_rateも同様のようです(ただし、decoding: unusedとなっている)。

    2022年5月31日 8:42
  • 情報たいへんありがとうございます。

    なんとなくその情報は見た気がします。

    ffprobe.cのソースだと、 avcodec_find_decoderした後のAVCodecContextから得たrc_max_rateを表示しているように見えるので、まだ解読出来てない何かをしたらrc_max_rateが取れるのでは とも考えています。
    (ただこのソースだけだと見えてない変数や関数が幾つかあるので今一つ細かい処まで判っていません。
     見えてない箇所で、計算してrc_max_rateに値を入れている可能性もありそうです)


    2022年5月31日 10:38
  • ”そもそも論”ですが、対象のMP4ファイルにはmax_rate値が格納されていることは確かなのでしょうか?

    取得しているはずの値が0(想定値ではない)ということは、①:正しく取得できているが格納されている値がゼロ値、②:対応する項目名が見つからないまたは取得に失敗したので、ライブラリ関数またはffprobeがゼロ値を返していることが考えられます。

    たとえば、コマンドプロンプト画面(いわゆるDOS窓)で

    ffprobe -show_streams MP4ファイル

    を実行するなど、別の方法でMP4ファイル内の値を確認できないでしょうか?

    小生が手元の適当なMP4ファイルで試したところ、それらしい項目として「max_bit_rate=N/A」となっていました。

    小生のffprobeのバーションはN-106934-ge3580f6077-20220517です。

    なお、DOS窓ではffprobeからの出力はテキスト情報として画面に表示されてスクロールするので、DOS窓でスクロールさせて見るか、テキストファイル(拡張子はtxtとするのが便利)にリダイレクトすればいいと思います。

    2022年6月1日 10:33
  • ”ここのMP4動画ファイルは ffprobeではmax_bit_rateに値が入っていました"
    質問の文章です。 ffprobe -show_streams をやってmax_bit_rateに値が入っている事を確認しています。(この他にMediaInfoでも このMP4ファイルはVBR表示します。)



    ffprobe.c のソースで検索すると max_bit_rateは1箇所しかないのですが、取れてない場合は N/Aが表示され、取れていたら数値を表示しています。

    ffprobe.cソースの
        if (dec_ctx && dec_ctx->rc_max_rate > 0)
            print_val ("max_bit_rate", dec_ctx->rc_max_rate, unit_bit_per_second_str);
        else
            print_str_opt("max_bit_rate", "N/A");

    dec_ctxは質問のソースにあるcodec_context に相当する値です。

    2022年6月1日 11:05
  • 失礼しました。

    まさかとは思いますが、ffprobeと自作アプリは32ビット/64ビットの違いということはないですよね?

    (Cは長いこと書いていないので、想像(と経験)での発言で申し訳ありません。)

    2022年6月1日 12:00
  • 両方32bitでした。

    ちなみに ffprobe.cのソースは
    https://github.com/FFmpeg/FFmpeg/tree/master/fftools/ffprobe.c
    です。 
    大きいですが、probe_fileでファイルを読み込んで show_streamsで値を表示しているのが肝心の箇所となります。
    興味がありましたら覗いてください。

    2022年6月1日 12:26