h264 inside AVI, MP4 and “Raw” h264 streams. Different format of NAL units (or ffmpeg bug)

前提是你 提交于 2019-11-30 21:40:22

"I want to read raw h264 streams from AVI files, even broken/incomplete."

"Almost everywhere told to me that the packet should start with a signature like :
00 00 01 or 00 00 00 01"

"...As you can see, here I have 00 00 24 A9 instead of 00 00 00 01"

Your H264 is in AVCC format which means it uses data sizes (instead of data start codes). It is only Annex-B that will have your mentioned signature as start code.

You seek frames, not by looking for start codes, but instead you just do skipping by frame sizes to reach the final correct offset of a (requested) frame...

AVI processing :

  • Read size (four) bytes (32-bit integer, Little Endian).

  • Extract the next following bytes up to size amount.

  • This is your H.264 frame (in AVCC format), decode the bytes to view image.

  • To convert into Annex-B, try replacing first 4 bytes of H.264 frame bytes with 00 00 00 01.

Consider your shown AVI bytes (see first picture) :

00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00     ................
00 00 00 00 4C 49 53 54 BA 24 00 00 6D 6F 76 69     ....LISTº$..movi
30 30 64 63 AD 24 00 00 00 00 24 A9 65 88 84 27     00dc.$....$©eˆ„'
C7 11 FE B3 C7 83 08 00 08 2A 7B 6E 59 B5 71 E1     Ç.þ³Çƒ...*{nYµqá
E3 9C 0E 73 E7 10 50 00 18 E9 25 F7 AA 7D 9C 30     ãœ.sç.P..é%÷ª}œ0
E6 2F 0F 20 00 3A 64 AA CA 5E 4F CA FF AE 20 04     æ/. .:dªÊ^OÊÿ® .
07 81 40 00 48 00 0A 28 71 21 84 48 06 18 90 0C     ..@.H..(q!„H....
31 14 57 9E 7A CD 63 A0 E0 9B 96 69 C5 18 AE F2     1.WžzÍc à›–iÅ.®ò
E6 07 02 29 01 20 10 70 A1 0F 8C BC 73 F0 78 FA     æ..). .p¡.Œ¼sðxú
9E 1D E1 C2 BF 8C 62 CE CE AC 14 5A A4 E1 45 44     ž.ῌbÎά.Z¤áED
38 38 85 DB 12 57 3E F6 E0 FB AE 03 04 21 62 8D     88…Û.W>öàû®..!b.
F6 F1 1E 37 1C A2 FF 75 1C F1 02 66 0C 92 07 06     öñ.7.¢ÿu.ñ.f.’..
15 7C 90 15 6F 7D FC BD 13 1E 2B 0C 14 3C 0C 00     .|..o}ü½..+..<..
B0 EA 6F 53 B4 98 D7 80 7A 68 3E 34 69 20 D2 FA     °êoS´˜×€zh>4i Òú
F0 91 FC 75 C6 00 01 18 C0 00 3B 9A C5 E2 7D BF     ð‘üuÆ...À.;šÅâ}¿

Some explanation :

  • Ignore leading multiple 00 bytes.

  • 4C 49 53 54 D6 3C 00 00 6D 6F 76 69 including 30 30 64 63 = AVI "List" header.

  • AD 24 00 00 == decimal 9389 is AVI's own size of H264 item (is read in Little Endian).

Notice that the AVI bytes include...
- a note of item's total size (AD 24 00 00... or reverse for Little Endian : 00 00 24 AD)
- followed by item data (00 00 24 A9 65 88 84 27 ... etc ... C5 E2 7D BF).

This size is both the AVI's four size bytes themselves + length of item's own bytes. or simply:
AVI_Item_Size = ( 4 + item_H264_Frame.length );

H.264 video frame bytes in AVI :

Next follows the item data, which is the H.264 video frame. By sheer coincidence of formats/bytes layout, it too holds a 4-byte entry for data's size (since your H264 is in AVCC format, if it was Annex-B then you would be seeing start code bytes here instead of size bytes). Unlike AVI, this size is written in Little Endian format.

  • 00 00 24 A9 = size of bytes for this video frame (instead of start code : 00 00 00 01).

  • 65 88 84 27 C7 11 FE B3 C7 = H.264 keyframe (always begins X5, where the X value is based on other settings).

  • Remember after four size bytes (or even start codes) if followed by...

    • byte X5 = keyframe (IDR), example byte 65.
    • byte X1 = P or B frame, example byte 41.
    • byte X6 = SEI (Supplemental Enhancement Information).
    • byte X7 = SPS (Sequence Parameter Set).
    • byte X8 = PPS (Picture Parameter Set).
    • bytes 00 00 00 X9 = Access unit delimiter.

You can find the H.264 if you search for exact same bytes within AVI file. See third picture, these are your H.264 bytes (they are cut & pasted into the AVI container).

Sometimes a frame is sliced into different NAL units. So if you extract a key frame and it only shows 1/2 or 1/3 instead of full image, just grab next one or two NAL and re-try the decode.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!