返回

揭秘 H.264 解码器:从 SPS 中提取图像宽高

Android

各位热衷于视频解码的小伙伴们,欢迎回到我们自己动手写 H.264 解码器的系列文章。在上一期中,我们逐一解析了标准文档中的语法表格,从原始码流中提取出了一个个语法元素。

今天,我们将聚焦于一个关键步骤:从 SPS(序列参数集)中提取图像的宽高 。这个信息至关重要,因为它决定了解码后图像的大小。

从 SPS 中提取图像宽高

SPS 是 H.264 视频流中最重要的语法结构之一。它包含了整个视频序列的全局信息,包括图像的宽高。

具体来说,图像的宽高存储在 SPS 的以下字段中:

  • pic_width_in_mbs_minus1 :以宏块为单位的图像宽度减 1
  • pic_height_in_map_units_minus1 :以宏块为单位的图像高度减 1

需要注意的是,宏块是 H.264 视频编码中的一种基本单位,每个宏块由 16×16 个像素组成。因此,为了得到图像的实际像素宽度和高度,我们需要将宏块宽度和高度乘以 16。

代码示例

下面是一个从 SPS 中提取图像宽高的代码示例:

import struct

def extract_image_size(sps):
    """从 SPS 中提取图像宽高。

    Args:
        sps (bytes): SPS 字节数组。

    Returns:
        tuple(int, int): 图像宽度和高度。
    """

    # 解析 SPS 头部
    header = struct.unpack(">I", sps[:4])[0]
    nal_unit_type = (header >> 28) & 0x7

    # 确保是 SPS
    if nal_unit_type != 7:
        raise ValueError("无效的 SPS 字节数组。")

    # 解析图像宽度和高度
    pic_width_in_mbs_minus1 = (sps[4] >> 1) & 0x3FFF
    pic_height_in_map_units_minus1 = (sps[6] >> 1) & 0x3FFF

    # 计算图像的像素宽度和高度
    image_width = (pic_width_in_mbs_minus1 + 1) * 16
    image_height = (pic_height_in_map_units_minus1 + 1) * 16

    return image_width, image_height

总结

提取图像宽高是 H.264 解码器中一个至关重要的步骤。通过从 SPS 中解析相应的字段,我们可以准确地计算出解码后图像的大小。

在下一期文章中,我们将继续深入研究 H.264 解码器的实现,探讨如何从 PPS(图像参数集)中提取更多有用的信息。敬请期待!