user10558: 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) ?

user40480: I wanted to avoid grepping ffmpeg's warnings from stdout/stderr in my own tools, so I looked for an alternative/stabler approach. The key to how ffmpeg detects packed B-frames is here:

https://github.com/FFmpeg/FFmpeg/blob/f4b4e16641184b2414e5822c49fa5f6f9a57f2fb/libavcodec/mpeg4videodec.c#L2949
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:
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.

10558: <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>
 40480: <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>
