6

I need to convert h264 stream from annex-b format to AVCC format.

I tried this to convert from h264 annex-b to AVCC: I extracted the SPS and PPS from the annex stream and created the Extra data. I then looked in the stream for 0x00 0x00 0x00 0x01 (which should be the start of each Nal) and continue looking for another 0x00 0x00 0x00 0x01 (which will be the end of the Nal) then did minus to get the Nal length, then replace the first 0x00 0x00 0x00 0x01 to 0x00 0x00 0x00 [NulSize] but seems that this does not produce valid stream. I then found out that NUL can starts/ends with 0x00 0x00 0x01 so i am little confused.

anyway, I hope someone will be able to write me function that convert from annex-b to AVCC.

Thanks.

user3592107
  • 61
  • 1
  • 1
  • 2

2 Answers2

15

NALU is basic unit.

Then,

annexb format:

([start code] NALU) | ( [start code] NALU) |

avcc format:

([extradata]) | ([length] NALU) | ([length] NALU) |

In annexb, [start code] may be 0x000001 or 0x00000001.

In avcc, the bytes of [length] depends on NALULengthSizeMinusOne in avcc extradata, the value of [length] depends on the size of following NALU and in both annexb and avcc format, the NALUs are no different.

Neels
  • 2,547
  • 6
  • 33
  • 40
waveacme
  • 311
  • 3
  • 4
  • 1
    Can ffmpeg decode NALUs in AVCC directly or does it internally convert the format before decoding? – Farley Jun 09 '20 at 00:24
6

Start codes are not a fixed size and can be 3 or 4 bytes. Read more here: https://stackoverflow.com/a/24890903/660982

szatmary
  • 29,969
  • 8
  • 44
  • 57
  • Already know that. This does not help. For example, if i see 0 0 1 and then try to covert that, but size is more than 3 bytes, what should i do? I can over write only 3 bytes in this case - should i add byte ? – user3592107 May 01 '14 at 18:40
  • Did you read the link? you need to write NALULengthSizeMinusOne+1 bytes before every NALU. So, yes. You may need to insert or remove bytes depending on what you set in NALULengthSizeMinusOne. – szatmary May 01 '14 at 18:54
  • This is not what i mean. The length i will write will be 4 byte for me always. now if i see 0x00 0x00 0x00 0x01 ... 4 bytes ... 0x00 0x00 0x00 0x01 Then i convert it to 0x00 0x00 0x00 0x04 ... 4 bytes ....0x00 0x00 0x00 0x01 right? I.E is this then only thing i need to do? – user3592107 May 01 '14 at 19:53
  • Yes, the only thing you need to do is replace start codes (no mater what the length of the start code) with a 32 bit big endian integer representing the length of the next NALU. – szatmary May 01 '14 at 20:10
  • The blog post is no longer available, but you can access it with the waybackmachine here: https://web.archive.org/web/20141002182039/http://www.szatmary.org:80/blog/25#more-25 Also it seems the content is more or less the same as this stackoverflow answer: https://stackoverflow.com/a/24890903/660982 – jpihl Jun 14 '17 at 07:55