【问题标题】:Fetching the dimensions of a H264Video stream获取 H264Video 流的尺寸
【发布时间】:2011-09-17 16:51:05
【问题描述】:

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

【问题讨论】:

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


【解决方案1】:

不!!!

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

那么你必须得到一个 SPS 帧。它具有NAL=0x67(NAL 是 H.264 帧中的第一个字节),您可以在 SDP 中的sprop-parameter-sets 下找到它作为 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 字节的函数:

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

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

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,你会得到你的宽度和高度。享受... :)

【讨论】:

  • 什么是 ScalingList4x4[]、DefaultScalingMatrix4x4Flag[]、UseDefaultScalingMatrix8x8Flag[] 数组?它们是否定义为常量值?
  • 我真的不知道,但是在我提供的那个文件中,你可能会看到那些是什么......:/更新:看起来那个文件不再公开......你如我所见,必须登录...
  • 好吧,我找到了一个公开的... www-ee.uta.edu/Dip/Courses/EE5359/H.264%20Standard2007.pdf 但没有关于这些的有用信息...
  • 抱歉,我帮不了你...问个新问题?!
  • 我不知道你从哪里得到 Base64,它在 H.264 中的任何地方都没有使用。 SPS 中的所有内容都是 Exp-Golomb 编码的。为了方便起见,您一定正在查看一些将其解析为 Base64 的软件。
【解决方案2】:

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

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 在 frame_cop__offset 上?
【解决方案3】:

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

【讨论】:

    【解决方案4】:

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

    chroma_format_idc 存在时,我们必须从SPS 中提取它。 当chroma_format_idc 不存在时,应推断为等于1(4:2:0 色度格式)。在这种情况下,separate_color_plane_flag 未设置。这意味着chromaArrayType = chroma_format_idcsubWidthCsubHeightC 不等于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 来获得正确的帧大小值。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-01-16
      • 1970-01-01
      • 1970-01-01
      • 2012-11-12
      • 2010-12-15
      相关资源
      最近更新 更多