Fetching the dimensions of a H264Video stream
Asked Answered
M

4

29

I am trying to fetch the dimensions (Height and width) from a H264 stream. I know that to fetch the same details from a mpeg2 stream you have to look at the four bytes following the sequence header start code ((01B3)). Will the same logic work for H264? Would appreciate any help I get..

Mckinleymckinney answered 18/6, 2011 at 8:42 Comment(1)
Use this link for C source code of this problem https://mcmap.net/q/501330/-get-the-width-height-of-the-video-from-h-264-naluChavey
D
51

NO!!!

You must run a complex function to extract video dimensions from Sequence Parameter Sets. How to do this? Well first you must write your own Exp-Golomb decoder, or find one online... in live555 source code somewhere there is one for example...

Then you must get one SPS frame. It has NAL=0x67 (NAL is the first byte in a H.264 frame) and you can find it as Base64 encoded string in SDP under sprop-parameter-sets its the first Base64 string before the first comma. Other comma separated strings there are Picture Parameter Sets... This is one SPS from SDP Z0KAKYiLQDIBL0IAAB1MAAK/IAg= you need to decode something like this from Base64 into a byte array.

Then you must extract RAW BYTE SEQUENCE PAYLOAD that is followed by NAL UNIT HEADER in that byte array!!! It is usually one byte long, but read on just to be sure... RBSP contains the bytes needed to run the seq_parameter_set_data( ) function. So you need to strip off the NAL UNIT HEADER first (one or more bytes).

Here it is the function that extracts RBSP bytes from SPS NAL UNIT:

NAL UNIT

Then when you have SPS (RBSP bytes) you need to perform a function that parses bits in this byte array. Here's the function with all the parameters parsed there (whole document can be found here: http://www.itu.int/rec/T-REC-H.264-201003-I/en and its free): How to decode SPS

There you can see some strange stuff... first, your video dimensions are calculated like this:

Width = ((pic_width_in_mbs_minus1 +1)*16) - frame_crop_right_offset*2 - frame_crop_left_offset*2;
Height = ((2 - frame_mbs_only_flag)* (pic_height_in_map_units_minus1 +1) * 16) - (frame_crop_top_offset * 2) - (frame_crop_bottom_offset * 2);

Second, and most important, in DESCRIPTOR column of this code table, is stated what you should do to read the bold text parameter in the first column. This is what values in there mean:

  • u(N) - Read an unsigned number which is N bits long
  • s(N) - Read a signed number which is N bits long
  • ue(v) - Read an unsigned Exp-Golomb number (v is for variable length, so its same as ue())
  • se(v) - Read a signed Exp-Golomb number

This is where your Exp-Golomb decoder comes in handy...

So, implement this function, parse SPS, and you will get your Width and Height. Enjoy... :)

Deadening answered 25/6, 2011 at 12:14 Comment(8)
What are those ScalingList4x4[], DefaultScalingMatrix4x4Flag[], UseDefaultScalingMatrix8x8Flag[] arrays? Are they defined as a constant values?Boylston
I really don't know, but in that document I provided, you can probably see what are those... :/ UPDATE: It looks like that document is not public any more... you will have to login as I see...Deadening
Well i find a public one... www-ee.uta.edu/Dip/Courses/EE5359/H.264%20Standard2007.pdf but not usefull info about those...Boylston
Sorry, but I can't help you... ask a new question about that?!Deadening
do you know where I can find info about how to encode sps/pps from decimal to base64? couldnt find it in the specBootless
That is the standard Base64 encoding! Just google for the sample code for your programming language there are MANY samples, like this one for C++ (adp-gmbh.ch/cpp/common/base64.html), or ask a question here...Deadening
I don't know where you get Base64 from, that's not used anywhere in H.264. Everything in the SPS is Exp-Golomb coded. You must be looking at some software that parses it to Base64 for convenience.Adenine
Where would the * 2 for the cropping values come from? In the H264 ITU 7.4.2.1.1 SPS semantics, you can read that you multiply the crop value by CropUnitX and CropUnitY. If ChromaArrayType is - than CropUnitX is 1 and CropUnitY is 2-frame_mbs_only_flag. So I see no reason to have a hard set 2* here... thanksMeyeroff
L
22

The size calculations are wrong unfortunatly and should be:

width = ((pic_width_in_mbs_minus1 +1)*16) - frame_crop_left_offset*2 - frame_crop_right_offset*2;
height= ((2 - frame_mbs_only_flag)* (pic_height_in_map_units_minus1 +1) * 16) - (frame_crop_top_offset * 2) - (frame_crop_bottom_offset * 2);
Lastditch answered 6/7, 2012 at 5:24 Comment(1)
Why the 2 on the frame_cop__offset ?Meyeroff
C
6

Actually cropping parameters should be used only when [frame_cropping_flag] is enabled in SPS. Enjoy H.264!

Conrad answered 29/8, 2012 at 8:58 Comment(0)
C
3

Regarding frame size calculation, the above formula is not correct.

When chroma_format_idc is present, then we have to extract it from the SPS. When chroma_format_idc is not present, it shall be inferred to be equal to 1 (4:2:0 chroma format). In that case the separate_color_plane_flag is not set. That means that chromaArrayType = chroma_format_idc and subWidthC and subHeightC are uqual to 2.

The variables cropUnitX and cropUnitY are derived as follows:

  • If chromaArrayType is equal to 0, cropUnitX and cropUnitY are derived as:

    cropUnitX = 1
    cropUnitY = 2 - frame_mbs_only_flag
    
  • Otherwise (chromaArrayType is equal to 1, 2, or 3), cropUnitX and cropUnitY are derived as:

    cropUnitX = subWidthC
    cropUnitY = subHeightC * ( 2 - frame_mbs_only_flag )
    

Now you can use cropUnitX and cropUnitY in the above formula to get the correct values for frame size.

Cervix answered 13/7, 2016 at 7:37 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.