logo

Demystifying RTP Payload's profile-level-id

Posted on 22-6-2021

I have been encountering this parameter a lot since I started to working with WebRTC. Its purpose is to signal the codec profile and level used for the H.264 encoded video stream. The parameter is exchanged between WebRTC peers during the signaling phase. Different browsers and different devices return a variety of profile level-ids and I was curious what their meaning was.

If you are curious about WebRTC in general, I can recommend the following excellent resource: WebRTC For The Curious.

The profile-level-id's has a total of 24 bits of information. It is divided into 3 categories with each category having 8 bits:

  1. profile_idc
  2. profile-iop
  3. level_idc

In the context of WebRTC, the above information is often presented in hexadecimal form. To match the information below for profile_idc, we need to convert the first 8 bits to decimal. For the flags, we need to convert to binary and read it from left to right. Finally, to level_idc we do the same as for profile_idc.

profile_idc

The H.264 encoder has a many different features. Each profile supports a subset of these features. Some features are more efficient at encoding but require more resources to decode. The 8 bits of information indicate what profile is being used by the encoder. This does not mean that the video stream uses all of the capabilities of the profile. Here is a list of profiles:

Profileprofile_idc
Baseline66
Constrained Baseline66
Main77
Extended88
High100

There are a number of higher quality profiles available. However, since they are not commonly used yet in an WebRTC environment, I will skip those. Note that certain constraint flags are backward compatible but this depends on the constraint flags (profile-iop) set.

profile-iop

This is a collection of flags that indicate whether all features of a profile are supported or only a subset. Currently, there are a total of 6 flags and 2 reserve bits for possible future use. The 6 flags are:

  1. constraint_set0_flag: Indicates that the bitstream conforms to the baseline profile.
  2. constraint_set1_flag: Indicates main profile conformity.
  3. constraint_set2_flag: Signals extended profile support.
  4. constraint_set3_flag: The flag's meaning is different based on the profile_idc value. For levels 66, 77, and 88 specifically it signals level 1b support.
  5. constraint_set4_flag: For profile 77, 88, and 100, when set to 1 it means the frame_mbs_only_flag is set to 1.
  6. constraint_set5_flag: Also related to profiles 77, 88, and 100. When set to 0 it means there might be B slice types present.

You can find specifics about these flags in the ITU-T document linked below under section: 7.4.2.1.1

level_idc

Levels help us understand limits of certain codec parameters such as block sizes or sample sizes. A higher level typically indicates a higher quality but also means higher amounts of needed processing capabilities. The following levels are currently defined: 1, 1b, 1.1, 1.2, 1.3, 2, 2.1, 2.2, 3, 3.1, 3.2, 4, 4.1, 4.2, 5, 5.1, 5.2, 6, 6.1, 6.2. For an overview of what each level is capable of I found the H.264 profiles and level post helpful.

To read the level just take the level_idc decimal and divide it by 10. So 11 becomes 1.1 and 13 becomes 1.3. If level_idc is 11 and constraint_set3_flag equal 1 then the level is 1b.

Useful resources