28

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

4

4 回答 4

49

不!!!

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

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

然后,您必须提取 RAW BYTE SEQUENCE PAYLOAD,然后在该字节数组中提取 NAL UNIT HEADER !!!它通常是一个字节长,但请继续阅读以确保... RBSP 包含运行该seq_parameter_set_data( )函数所需的字节。所以你需要先去掉 NAL UNIT HEADER(一个或多个字节)。

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

最终单元

然后,当您有 SPS(RBSP 字节)时,您需要执行一个函数来解析此字节数组中的位。这是在那里解析所有参数的函数(整个文档可以在这里找到:http ://www.itu.int/rec/T-REC-H.264-201003-I/en及其免费): 如何解码 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,你会得到你的宽度和高度。享受... :)

于 2011-06-25T12:14:56.443 回答
22

不幸的是,尺寸计算是错误的,应该是:

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);
于 2012-07-06T05:24:29.923 回答
6

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

于 2012-08-29T08:58:11.763 回答
3

关于帧大小的计算,上面的公式是不正确的。

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

变量cropUnitX 和cropUnitY 派生如下:

  • 如果chromaArrayType等于0cropUnitX并且cropUnitY导出为:

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

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

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

于 2016-07-13T07:37:15.390 回答