Answers.Body: <p>The issue was caused by ffmpeg/libavformat/movenc.c::mov_write_esds_tag, it can't find max_bitrate. To solve it you should specify audio bitrate <code>-b:a 128k</code> along with <code>-vbr 4</code>. Then mp4's ESDescriptor would have info about <code>max_bitrate</code> and <code>mediainfo</code> and decoders would know that audio stream has variable bitrate mode.</p>
  
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2020-12-27T02:01:22.643Z
Answers.LastActivityDate: 2020-12-27T02:01:22.643Z
Answers.UserDisplayName: Andrew Trofimov
Answers.Body: <p>Currently only the 'aac_low' profile supports VBR encoding.</p>
  
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2021-01-28T17:22:59.980Z
Answers.LastActivityDate: 2021-01-28T17:22:59.980Z
Answers.UserDisplayName: user33714
Body: <p>I'm trying to encode sample video clip or audio track with <code>ffmpeg</code> and <code>libfdk_aac</code> with variable bitrate mode<code>-vbr 3</code>:</p>
  <pre class="lang-bash prettyprint-override"><code>ffmpeg -i sample.mp4 -crf 21 -vcodec h264 -acodec libfdk_aac -vbr 3 -ac 2 out.mp4
  ffmpeg -i sample.mp3 -acodec libfdk_aac -vbr 3 -ac 2 out.m4a
  </code></pre>
  <p><code>mediainfo</code> always shows</p>
  <pre><code>Bit rate mode                            : Constant
  </code></pre>
  <p>It sounds like a bug, isn't it?</p>
  <p>Also, Mp4info looks like</p>
  <pre><code>File:
    major brand:      M4A 
    minor version:    200
    compatible brand: M4A 
    compatible brand: isom
    compatible brand: iso2
    fast start:       no
  
  Movie:
    duration:   229042 ms
    time scale: 1000
    fragments:  no
  
  Found 1 Tracks
  Track 1:
    flags:        3 ENABLED IN-MOVIE
    id:           1
    type:         Audio
    duration: 229042 ms
    language: und
    media:
      sample count: 9864
      timescale:    44100
      duration:     10100736 (media timescale units)
      duration:     229042 (ms)
      bitrate (computed): 88.674 Kbps
    Sample Description 0
      Coding:      mp4a (MPEG-4 Audio)
      Stream Type: Audio
      Object Type: MPEG-4 Audio
      Max Bitrate: 88674
      Avg Bitrate: 88674
      Buffer Size: 0
      Codecs String: mp4a.40.2
      MPEG-4 Audio Object Type: 2 (AAC Low Complexity)
      MPEG-4 Audio Decoder Config:
        Sampling Frequency: 44100
        Channels: 2
      Sample Rate: 44100
      Sample Size: 16
      Channels:    2
  </code></pre>
  <p>How <code>mediainfo</code> recognizes <code>Bit rate mode</code> for <code>mp4</code> \ <code>m4a</code> ? And is there any way to correct it to <code>Variable</code> ?
  <a href="https://i.sstatic.net/MEkSY.png" rel="nofollow noreferrer"><img src="https://i.sstatic.net/MEkSY.png" alt="enter image description here" /></a></p>
  <p>P.S.:
  Bitrate's plot show that <code>libfdk_aac</code> works fine, but output metadata is incorrect - it can't be CBR. Here's example for CBR below (with option <code>-vbr 0</code>):</p>
  <p><a href="https://i.sstatic.net/Rmrtm.png" rel="nofollow noreferrer"><img src="https://i.sstatic.net/Rmrtm.png" alt="enter image description here" /></a></p>
  <p><strong>UPDATE:</strong>
  After an hour of digging this issue I noticed that issue could be solved by editing ESDescriptor.
  Here's sample's ESDescriptor that ffmpeg produces:</p>
  <pre><code>[ESDescriptor] size=5+34
    es_id = 2
    stream_priority = 0
    [DecoderConfig] size=5+20
      stream_type = 5
      object_type = 64
      up_stream = 0
      buffer_size = 0
      max_bitrate = 151870
      avg_bitrate = 151870
      DecoderSpecificInfo = 11 90 
    [Descriptor:06] size=5+1
  </code></pre>
  <p>Well, if you set <code>max_bitrate</code> and <code>avg_bitrate</code> to <code>0</code> - <code>Bit rate mode</code> magically switches to correct value <code>VBR</code> as it is.
  So the problem could be solved by using <code>mp4edit</code> or by patching ffmpeg (libavformat/movenc.c::mov_write_esds_tag)</p>
  <p>Out of curiosity, I checked youtube's videos' ESDescriptor, they also has <code>max_bitrate</code> and <code>avg_bitrate</code> set to <code>0</code>.</p>
  
Comments.ContentLicense: CC BY-SA 4.0
Comments.CreationDate: 2020-12-26T16:36:29.843Z
Comments.Text: 0 isn't valid value for those fields. Ideal would to calculate actual max bitrate.
Comments.UserDisplayName: Gyan
Comments.ContentLicense: CC BY-SA 4.0
Comments.CreationDate: 2020-12-26T17:24:55.063Z
Comments.Text: Yeah, I noticed that ffmpeg has a bug while writing esds: it writes avg_bitrate instead of max_bitrate which cause decoders think it's CBR audio stream. Somehow if set to 0 works fine everywhere and decoders detect it as VBR. I'm not sure about old ones, but yeah, to be sure every decoder read an audio correctly - better calc actual size.
Comments.UserDisplayName: Andrew Trofimov
Comments.ContentLicense: CC BY-SA 4.0
Comments.CreationDate: 2020-12-26T19:26:13.333Z
Comments.Text: As long as the buffer size, when specified, is accurate, what difference does it make?
Comments.UserDisplayName: Gyan
Comments.ContentLicense: CC BY-SA 4.0
Comments.CreationDate: 2024-11-23T21:26:13.977Z
Comments.Text: Fixed now in https://github.com/FFmpeg/FFmpeg/commit/46c6ca3ed1651c67faf899776f1922c108093a44
Comments.UserDisplayName: Валерий Заподовников
Tags: <ffmpeg><audio><bitrate>
Title: ffmpeg + libfdk_aac + vbr => wrong "BitRate_Mode"
UserDisplayName: Andrew Trofimov
ThreadText: # ffmpeg + libfdk_aac + vbr => wrong "BitRate_Mode"
  
  (Asked by: username_0 on 2020-12-26)
  
  I'm trying to encode sample video clip or audio track with `ffmpeg` and `libfdk_aac` with variable bitrate mode`-vbr 3`:
  
  ```bash
  ffmpeg -i sample.mp4 -crf 21 -vcodec h264 -acodec libfdk_aac -vbr 3 -ac 2 out.mp4
  ffmpeg -i sample.mp3 -acodec libfdk_aac -vbr 3 -ac 2 out.m4a
  
  ```
  
  `mediainfo` always shows
  
  ```
  Bit rate mode                            : Constant
  
  ```
  
  It sounds like a bug, isn't it?
  
  Also, Mp4info looks like
  
  ```
  File:
    major brand:      M4A 
    minor version:    200
    compatible brand: M4A 
    compatible brand: isom
    compatible brand: iso2
    fast start:       no
  
  Movie:
    duration:   229042 ms
    time scale: 1000
    fragments:  no
  
  Found 1 Tracks
  Track 1:
    flags:        3 ENABLED IN-MOVIE
    id:           1
    type:         Audio
    duration: 229042 ms
    language: und
    media:
      sample count: 9864
      timescale:    44100
      duration:     10100736 (media timescale units)
      duration:     229042 (ms)
      bitrate (computed): 88.674 Kbps
    Sample Description 0
      Coding:      mp4a (MPEG-4 Audio)
      Stream Type: Audio
      Object Type: MPEG-4 Audio
      Max Bitrate: 88674
      Avg Bitrate: 88674
      Buffer Size: 0
      Codecs String: mp4a.40.2
      MPEG-4 Audio Object Type: 2 (AAC Low Complexity)
      MPEG-4 Audio Decoder Config:
        Sampling Frequency: 44100
        Channels: 2
      Sample Rate: 44100
      Sample Size: 16
      Channels:    2
  
  ```
  
  How `mediainfo` recognizes `Bit rate mode` for `mp4` \ `m4a` ? And is there any way to correct it to `Variable` ?
  [![enter image description here](https://i.sstatic.net/MEkSY.png)](https://i.sstatic.net/MEkSY.png)
  
  P.S.:
  Bitrate's plot show that `libfdk_aac` works fine, but output metadata is incorrect - it can't be CBR. Here's example for CBR below (with option `-vbr 0`):
  
  [![enter image description here](https://i.sstatic.net/Rmrtm.png)](https://i.sstatic.net/Rmrtm.png)
  
  **UPDATE:**
  After an hour of digging this issue I noticed that issue could be solved by editing ESDescriptor.
  Here's sample's ESDescriptor that ffmpeg produces:
  
  ```
  [ESDescriptor] size=5+34
    es_id = 2
    stream_priority = 0
    [DecoderConfig] size=5+20
      stream_type = 5
      object_type = 64
      up_stream = 0
      buffer_size = 0
      max_bitrate = 151870
      avg_bitrate = 151870
      DecoderSpecificInfo = 11 90 
    [Descriptor:06] size=5+1
  
  ```
  
  Well, if you set `max_bitrate` and `avg_bitrate` to `0` - `Bit rate mode` magically switches to correct value `VBR` as it is.
  So the problem could be solved by using `mp4edit` or by patching ffmpeg (libavformat/movenc.c::mov\_write\_esds\_tag)
  
  Out of curiosity, I checked youtube's videos' ESDescriptor, they also has `max_bitrate` and `avg_bitrate` set to `0`.
  
  **Tags:** ffmpeg, audio, bitrate
  
  > **Comments:**
  > **username_1**: 0 isn't valid value for those fields. Ideal would to calculate actual max bitrate.  
  > **username_0**: Yeah, I noticed that ffmpeg has a bug while writing esds: it writes avg_bitrate instead of max_bitrate which cause decoders think it's CBR audio stream. Somehow if set to 0 works fine everywhere and decoders detect it as VBR. I'm not sure about old ones, but yeah, to be sure every decoder read an audio correctly - better calc actual size.  
  > **username_1**: As long as the buffer size, when specified, is accurate, what difference does it make?  
  > **username_2**: Fixed now in https://github.com/FFmpeg/FFmpeg/commit/46c6ca3ed1651c67faf899776f1922c108093a44  
  
  ---
  
  ## 2 answers
  
  ### Answer by username_0 on 2020-12-27. Score: 2
  
  The issue was caused by ffmpeg/libavformat/movenc.c::mov\_write\_esds\_tag, it can't find max\_bitrate. To solve it you should specify audio bitrate `-b:a 128k` along with `-vbr 4`. Then mp4's ESDescriptor would have info about `max_bitrate` and `mediainfo` and decoders would know that audio stream has variable bitrate mode.
  
  
  ---
  
  ### Answer by username_3 on 2021-01-28. Score: 0
  
  Currently only the 'aac\_low' profile supports VBR encoding.
  
  
  ---
  
  