Introduction to H.264: (2) SODB vs RBSP vs EBSP

Reference from 14496-10

[7.4.1 NAL unit semantics]

RBSP

The RBSP contains an SODB as follows:

  • If the SODB is empty (i.e., zero bits in length), the RBSP is also empty.
  • Otherwise, the RBSP contains the SODB as follows:
    1. The first byte of the RBSP contains the (most significant, left-most) eight bits of the SODB; the next byte of the RBSP contains the next eight bits of the SODB, etc., until fewer than eight bits of the SODB remain.
    2. rbsp_trailing_bits( ) are present after the SODB as follows:
      i)  The first (most significant, left-most) bits of the final RBSP byte contains the remaining bits of the SODB (if any).
      ii)  The next bit consists of a single rbsp_stop_one_bit equal to 1.
      iii) When the rbsp_stop_one_bit is not the last bit of a byte-aligned byte, one or more rbsp_alignment_zero_bit is present to result in byte alignment.
    3. One or more cabac_zero_word 16-bit syntax elements equal to 0x0000 may be present in some RBSPs after the rbsp_trailing_bits( ) at the end of the RBSP.

Syntax structures having these RBSP properties are denoted in the syntax tables using an “_rbsp” suffix. These structures shall be carried within NAL units as the content of the rbsp_byte[i] data bytes. The association of the RBSP syntax structures to the NAL units shall be as specified in Table 7-1.

NOTE 6 – When the boundaries of the RBSP are known, the decoder can extract the SODB from the RBSP by concatenating the bits of the bytes of the RBSP and discarding the rbsp_stop_one_bit, which is the last (least significant, right-most) bit equalto 1, and discarding any following (less significant, farther to the right) bits that follow it, which are equal to 0. The data necessary for the decoding process is contained in the SODB part of the RBSP.

Note: In the syntax table, rbsp_byte[i] means the i-th byte of an RBSP.

EBSP

emulation_prevention_three_byte is a byte equal to 0x03. When an emulation_prevention_three_byte is present in the NAL unit, it shall be discarded by the decoding process. The last byte of the NAL unit shall not be equal to 0x00. Within the NAL unit, the following three-byte sequences shall not occur at any byte-aligned position:

– 0x000000
– 0x000001
– 0x000002
Within the NAL unit, any four-byte sequence that starts with 0x000003 other than the following sequences shall not occur at any byte-aligned position:
– 0x00000300
– 0x00000301
– 0x00000302
– 0x00000303
NOTE 7 – When nal_unit_type is equal to 0, particular care must be exercised in the design of encoders to avoid the presence of the above-listed three-byte and four-byte patterns at the beginning of the NAL unit syntax structure, as the syntax element emulation_prevention_three_byte cannot be the third byte of a NAL unit.

Comments

comments

13 Comments

  1. Frederico Cengarle

    Hi Yumi,

    I’m having issues with some x264 streams that I’ve created. When analyzing them, I get some RBSP error “Invalid rbsp_trailing_bits() in slice_layer_without_partitioning_rbsp()”

    To be honest, I don’t have near the knowledge that you seem to have regarding H264 structure 🙂 and I was hoping that you could help me with this. Are these error critical? What can be causing this and is there a way to fix it? Finally, what’s the use of rbsp trailing bits?
    Kindly regards,
    Frederico

    Reply
    1. Yumi Chan (Post author)

      Hi Frederico, thank you for visiting my blog. Could you explain more about how you create the h264 streams?

      rbsp_trailing_bits are just some bits append at the end of a SODB (bitstream of coded raw H.264 data) to make it byte-aligned. And these bits start with a bit of 1, followed by some 0s, which are the red and yellow parts of the image on my post above.

      Regards,
      Yumi

      Reply
      1. Frederico Cengarle

        Hi Yumi,

        thanks for the reply,

        basically, we’re using a x264 build running under Simple x264 GUI to produce some raw h264 file that we then mix in a Transport Stream. The whole purpose is to play those files in a MediaRoom system. The files seems to play fine but my client recently raised this issue where my files where analyzing the files, he got some “Invalid rbsp_trailing_bits() in slice_layer_without_partitioning_rbsp()” message.

        After some tests, I check the mix process and noticed that it was not the cause of the issue (the issue seems to come from the raw x264 stream). Now, like I said, this does’t really seem to affect the playback but my client is wondering why my files seems to have invalid tbsp (and so do I :-)) And I was wondering if there is a way to make sure that RBSP are correct.

        Once again thanks a lot
        Fred

        Reply
        1. Yumi Chan (Post author)

          Hi,

          I am sorry that I haven’t encountered such problem but I will try to help. You said you mixed the generated raw h264 files in a transport stream. And you said it seems to be the raw h264 streams’ problem. So, could you ensure the raw h264 files are the same on the client side? Are you two using the same decoder? If not, can you try to use the same decoder? Can you make sure that whether the problem comes from the raw stream / data or there is some other causes?

          If you ensure it comes from the raw streams, have you checked what the current rbsp_trailing_bits are?

          Yumi

          Reply
  2. cheng

    Thank you for your Blog.
    Do SODB have some end mark bits? it is said in blog that “it does not include the 3-byte / 4-byte start code” . so, what is the mark bits in SODB ? thanks!

    Reply
    1. Yumi Chan (Post author)

      Hi,
      SODB does not contain any starting / ending bits. It is just the raw data of h.264.
      If you add a stopping bit 1 at the end (and some 0s to align), it is called RBSP.
      If you also add the NALU header & start code, it is called NAL unit.
      The start code you mentioned is used to differentiate a NAL unit from another NAL unit.

      Reply
      1. cheng

        got it. thank you. I’m studying h264 due to work needs.

        Reply
      2. Cloudsdale

        So how are these NAL Units encapsulated in a sample that is found in the “mdat” box inside an MP4 file? Is the first NALU prefixed with the Start Code as well? Or just when we want to start the next NALU after the first one inside the same sample?
        I see some samples starting with 0x0000 with the next byte not being any of these “starting” bytes (0x00, 0x01, 0x02, 0x03). How should I interpret those?

        Reply
  3. cheng

    the question is about slice header. how to get the slice_type from bit streams ? thank you !

    Reply
    1. Yumi Chan (Post author)

      Sorry for late reply!
      Do you mean byte stream? If yes, there are lots of slices inside a byte stream. You have to identify the NAL Units (while 1 NAL unit contains 1 slice) in a byte stream first. This article shows you how to identify a nal unit.

      After finding a nal unit, you may check this article: http://yumichan.net/video-processing/video-compression/introduction-to-h264-nal-unit/

      it tells you how to find the nal_unit_type which also stands for the slice type in that nal unit.

      Reply
  4. Robin

    Hi,
    I’m trying to construct an annex B stream from what I think is an avcC stream. At the start of the stream I get the codec info and a NAL unit length of 3 along with the SPS and PPS data.

    From then on all the packets are the raw video data frames. To convert this to an annexB stream I thought it would be just [0001]+[SPS]+[0001]+[PPS]+dataByte[] but I’m missing the NAL so clearly this isn’t right. Could you point me in the right direction?

    Reply
  5. Farley Lai

    Hi,

    Regarding the emulation_prevention_three_byte, I recently encounter an edge case where the trailing byte of PPS is 0x00 followed by the start code 0x00000001 of the next IDR, giving four consecutive zeros. Is this is allowed or actually something wrong on the encoder side?
    FFMPEG is fine with decoding the bitstream though.

    Reply
  6. Cloudsdale

    According to the spec, an RBSP sequence cannot end with 0x00 byte. If that’s the case, a 0x03 byte should be appended.
    If your encoder doesn’t do that, then it probably does something wrong.
    However, in MP4 files, NAL Unit lengths are encoded externally, and only one NAL Unit is allowed per sample, which also means that Start Code prefixes are not used. My guess is that from the same reasons, a sequence ending in 0x00 also shouldn’t cause any problems, because it could only cause a problem if it got conflated with the Start Code prefix of the next NALU (which doesn’t exist in this case).

    Reply

Leave a Reply to Frederico Cengarle Cancel reply

Your email address will not be published. Required fields are marked *