Answers.Body: <p>Right now, the best I could find is:</p>
  <pre><code>$ ffmpeg -y -hide_banner -v info -i packed_bframes.avi -ss 0 -t 1 -an -c:v mpeg4 -f null /dev/null 2&gt;&amp;1 | grep mpeg4_unpack_bframes
  [mpeg4 @ 0x559262225100] Video uses a non-standard and wasteful way to store B-frames ('packed B-frames'). Consider using the mpeg4_unpack_bframes bitstream filter without encoding but stream copy to fix it.
  </code></pre>
  
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2020-11-20T13:08:19.697Z
Answers.LastActivityDate: 2020-11-20T13:55:00.553Z
Answers.LastEditDate: 2020-11-20T13:55:00.553Z
Answers.UserDisplayName: malat
Answers.Body: <p>I wanted to avoid <a href="https://video.stackexchange.com/a/32697/40480">grepping ffmpeg's warnings from stdout/stderr</a> in my own tools, so I looked for an alternative/stabler approach. The key to how ffmpeg detects packed B-frames is here:</p>
  <ol>
  <li><a href="https://github.com/FFmpeg/FFmpeg/blob/f4b4e16641184b2414e5822c49fa5f6f9a57f2fb/libavcodec/mpeg4videodec.c#L2949" rel="nofollow noreferrer">https://github.com/FFmpeg/FFmpeg/blob/f4b4e16641184b2414e5822c49fa5f6f9a57f2fb/libavcodec/mpeg4videodec.c#L2949</a></li>
  <li><a href="https://github.com/FFmpeg/FFmpeg/blob/f4b4e16641184b2414e5822c49fa5f6f9a57f2fb/libavcodec/mpeg4videodec.c#L3677" rel="nofollow noreferrer">https://github.com/FFmpeg/FFmpeg/blob/f4b4e16641184b2414e5822c49fa5f6f9a57f2fb/libavcodec/mpeg4videodec.c#L3677</a></li>
  </ol>
  <p>Unfortunately, <code>ffprobe</code> does not inform on the existence of packed B-frames and depending on your needs, implementing/linking an entire MPEG4 stream decoder might be overkill.</p>
  <p>Fortunately you can use <code>ffprobe</code> and little code to programmatically detect them:</p>
  <pre class="lang-sh prettyprint-override"><code>ffprobe -show_packets -select_streams v -read_intervals '%+#1' -show_entries packet=size,pos path/to/file.avi
  </code></pre>
  <p>Then open the AVI file, seek <code>pos</code>, read <code>size</code> bytes and Regex-search for <code>\x00\x00\x01\xB2DivX(\d+)b(\d+)p</code> or <code>\x00\x00\x01\xB2DivX(\d+)Build(\d+)p</code>. Here <code>\x00\x00\x01\xB2</code> stands for the MPEG4 &quot;User data&quot; magic sequence.</p>
  <p>You can see an example here: <a href="https://github.com/AlexAltea/curator/commit/f9b06146fde30dce0a422ca05a6ed7fa675da6ad" rel="nofollow noreferrer">https://github.com/AlexAltea/curator/commit/f9b06146fde30dce0a422ca05a6ed7fa675da6ad</a></p>
  <p>This should always correctly identify packed B-frames: when reformatting with <code>-bsf:v mpeg4_unpack_bframes</code> (or equivalent options in other tools), the <code>p</code> flag at the end of the DivX identifier gets removed.</p>
  <p>If you ever come across false postives (unpacked videos that still have the <code>p</code> flag), you can further improve by querying <code>ffprobe -show_frames</code>. I've noticed that packed B-frames always get reported as having <code>pkt_size == 8</code>.</p>
  
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2023-02-01T22:32:46.303Z
Answers.LastActivityDate: 2023-02-02T11:56:12.470Z
Answers.LastEditDate: 2023-02-02T11:56:12.470Z
Answers.UserDisplayName: Alexandro Sánchez
Body: <p>I have a set of old AVI files that I wish to fix using ffmpeg 'mpeg4_unpack_bframes' filter.</p>
  <p>I can manually detect them, simply running <code>ffplay</code> and I'll get a clear message:</p>
  <pre><code>[mpeg4 @ 0x55ef7bd90980] Video uses a non-standard and wasteful way to store B-frames ('packed B-frames'). Consider using the mpeg4_unpack_bframes bitstream filter without encoding but stream copy to fix it.
  </code></pre>
  <p>Then it is easy to fix using:</p>
  <pre><code>$ ffmpeg -i packed_bframes.avi -codec copy -bsf:v mpeg4_unpack_bframes unpacked_bframes.avi
  </code></pre>
  <p>My question is: what command line tool can I use on GNU/Linux (eg. Debian) to detect those files and only those (possibly without DISPLAY) ?</p>
  
Tags: <ffmpeg>
Title: Programmatically detect 'packed B-frames' AVI files
UserDisplayName: malat
ThreadText: # Programmatically detect 'packed B-frames' AVI files
  
  (Asked by: username_0 on 2020-11-20)
  
  I have a set of old AVI files that I wish to fix using ffmpeg 'mpeg4\_unpack\_bframes' filter.
  
  I can manually detect them, simply running `ffplay` and I'll get a clear message:
  
  ```
  [mpeg4 @ 0x55ef7bd90980] Video uses a non-standard and wasteful way to store B-frames ('packed B-frames'). Consider using the mpeg4_unpack_bframes bitstream filter without encoding but stream copy to fix it.
  
  ```
  
  Then it is easy to fix using:
  
  ```
  $ ffmpeg -i packed_bframes.avi -codec copy -bsf:v mpeg4_unpack_bframes unpacked_bframes.avi
  
  ```
  
  My question is: what command line tool can I use on GNU/Linux (eg. Debian) to detect those files and only those (possibly without DISPLAY) ?
  
  **Tags:** ffmpeg
  
  
  ---
  
  ## 2 answers
  
  ### Answer by username_0 on 2020-11-20. Score: 0 | Accepted answer
  
  Right now, the best I could find is:
  
  ```
  $ ffmpeg -y -hide_banner -v info -i packed_bframes.avi -ss 0 -t 1 -an -c:v mpeg4 -f null /dev/null 2>&1 | grep mpeg4_unpack_bframes
  [mpeg4 @ 0x559262225100] Video uses a non-standard and wasteful way to store B-frames ('packed B-frames'). Consider using the mpeg4_unpack_bframes bitstream filter without encoding but stream copy to fix it.
  
  ```
  
  
  ---
  
  ### Answer by username_1 on 2023-02-01. Score: 2
  
  I wanted to avoid [grepping ffmpeg's warnings from stdout/stderr](https://video.stackexchange.com/a/32697/40480) in my own tools, so I looked for an alternative/stabler approach. The key to how ffmpeg detects packed B-frames is here:
  
  1. <https://github.com/FFmpeg/FFmpeg/blob/f4b4e16641184b2414e5822c49fa5f6f9a57f2fb/libavcodec/mpeg4videodec.c#L2949>
  2. <https://github.com/FFmpeg/FFmpeg/blob/f4b4e16641184b2414e5822c49fa5f6f9a57f2fb/libavcodec/mpeg4videodec.c#L3677>
  
  Unfortunately, `ffprobe` does not inform on the existence of packed B-frames and depending on your needs, implementing/linking an entire MPEG4 stream decoder might be overkill.
  
  Fortunately you can use `ffprobe` and little code to programmatically detect them:
  
  ```sh
  ffprobe -show_packets -select_streams v -read_intervals '%+#1' -show_entries packet=size,pos path/to/file.avi
  
  ```
  
  Then open the AVI file, seek `pos`, read `size` bytes and Regex-search for `\x00\x00\x01\xB2DivX(\d+)b(\d+)p` or `\x00\x00\x01\xB2DivX(\d+)Build(\d+)p`. Here `\x00\x00\x01\xB2` stands for the MPEG4 "User data" magic sequence.
  
  You can see an example here: <https://github.com/AlexAltea/curator/commit/f9b06146fde30dce0a422ca05a6ed7fa675da6ad>
  
  This should always correctly identify packed B-frames: when reformatting with `-bsf:v mpeg4_unpack_bframes` (or equivalent options in other tools), the `p` flag at the end of the DivX identifier gets removed.
  
  If you ever come across false postives (unpacked videos that still have the `p` flag), you can further improve by querying `ffprobe -show_frames`. I've noticed that packed B-frames always get reported as having `pkt_size == 8`.
  
  
  ---
  
  