获取H264Video流的尺寸

时间:2011-06-18 08:42:21

标签: video video-processing h.264 mpeg-4 mpeg-2

我正在尝试从H264流中获取尺寸(高度和宽度)。我知道要从mpeg2流中获取相同的详细信息,您必须查看序列头开始代码后面的四个字节((01B3))。 H264的逻辑是否相同?非常感谢我得到的任何帮助..

4 个答案:

答案 0 :(得分:46)

否!!!

您必须运行复杂函数才能从序列参数集中提取视频尺寸。这该怎么做?首先,你必须编写自己的Exp-Golomb解码器,或者在线找到一个...在live555源代码的某处,例如有一个......

然后你必须得到一个SPS帧。它有NAL=0x67(NAL是H.264帧中的第一个字节),您可以在sprop-parameter-sets下的SDP中找到它作为Base64编码的字符串,它是第一个逗号之前的第一个Base64字符串。其他逗号分隔的字符串有图片参数集...这是SDP Z0KAKYiLQDIBL0IAAB1MAAK/IAg=中的一个SPS,你需要从Base64解码为字节数组。

然后你必须提取RAW BYTE SEQUENCE PAYLOAD ,然后在该字节数组中提取NAL UNIT HEADER!它通常是一个字节长,但读取只是为了确保... RBSP包含运行seq_parameter_set_data( )函数所需的字节。因此,您需要首先剥离NAL UNIT HEADER(一个或多个字节)。

这是从SPS NAL UNIT中提取RBSP字节的函数:

NAL UNIT

然后,当你有SPS(RBSP字节)时,你需要执行一个解析这个字节数组中的位的函数。这是在那里解析所有参数的函数(整个文档可以在这里找到:http://www.itu.int/rec/T-REC-H.264-201003-I/en及其免费): How to decode SPS

在那里你可以看到一些奇怪的东西......首先,你的视频尺寸计算如下:

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);

其次,最重要的是,在此代码表的DESCRIPTOR列中,说明了您应该如何阅读第一列中的粗体文本参数。这就是那里的价值观:

  • u(N) - 读取一个N位长的无符号数
  • s(N) - 读取一个长度为N位的有符号数字
  • ue(v) - 读取无符号的Exp-Golomb数字(v表示可变长度,因此与ue()相同)
  • se(v) - 阅读已签名的Exp-Golomb号码

这是你的Exp-Golomb解码器派上用场的地方......

因此,实现此功能,解析SPS,您将获得您的宽度和高度。享受...... :)。

答案 1 :(得分:21)

不幸的是,大小计算是错误的,应该是:

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);

答案 2 :(得分:5)

实际上,只有在SPS中启用[frame_cropping_flag]时才应使用裁剪参数。 享受H.264!

答案 3 :(得分:2)

关于帧大小计算,上述公式不正确。

当存在chroma_format_idc时,我们必须从SPS中提取它。 当chroma_format_idc不存在时,应推断其等于1(4:2:0色度格式)。在这种情况下,separate_color_plane_flag未设置。这意味着chromaArrayType = chroma_format_idcsubWidthC以及subHeightC等于2。

变量cropUnitX和cropUnitY的推导如下:

  • 如果chromaArrayType等于0,则cropUnitXcropUnitY派生为:

    cropUnitX = 1
    cropUnitY = 2 - frame_mbs_only_flag
    
  • 否则(chromaArrayType等于123),cropUnitXcropUnitY派生为:

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

现在,您可以在上面的公式中使用cropUnitXcropUnitY来获取正确的帧大小值。