Key Points
- 研究表明,H.266 VVC 可以在 MPEG2-TS 流中传输,DVB 标准将其流类型定义为 0x2c。
- 编写 Wireshark LUA 插件需要解析 TS 包、重组 PES 包,并提取 H.266 NAL 单元进行分析。
- 实现可能复杂,需处理 NAL 单元的跨包重组,建议参考 Wireshark 现有 H.264 解码器。
背景
H.266 VVC(多功能视频编码)是继 H.265 HEVC 后的最新视频压缩标准,旨在提供更高的压缩效率,特别适用于 4K 和 8K 视频流。MPEG2-TS(MPEG-2 传输流)是一种用于数字电视广播的容器格式,常用于地面或卫星传输。Wireshark 是一个网络协议分析工具,支持通过 LUA 脚本扩展功能,以分析特定协议或数据流。
实现步骤
要编写支持在 MPEG2-TS 中分析 H.266 VVC 的 Wireshark LUA 插件,需要以下步骤:
- 注册解码器:在 Wireshark 的 "ts.stream_type" 解码器表中,为流类型 0x2c 注册 H.266 解码器,这是 DVB 标准为 H.266 定义的流类型。
- 解析 TS 包:从 TS 包中提取基本流数据,处理可能的适应字段,确保获取到 PES(分组基本流)数据。
- 重组 PES 包:由于 PES 包可能跨多个 TS 包,需维护缓冲区按 PID(包标识符)累积数据,重组完整的 PES 包。
- 提取 H.266 位流:从 PES 包中提取 H.266 位流,识别以 0x00 0x00 0x01 开头的 NAL(网络抽象层)单元。
- 解析 NAL 单元:解析每个 NAL 单元的头部(2 字节),提取 nu_type(NAL 单元类型)、nu_layer_id(层 ID)等信息,并在 Wireshark 中显示。
注意事项
- H.266 在 MPEG2-TS 中的支持较新,流类型 0x2c 的定义基于 DVB 标准,可能在某些系统中未广泛实现,需验证实际流是否符合。
- NAL 单元可能跨多个 PES 包,需通过缓冲区处理部分 NAL 单元的累积和重组,类似 Wireshark 中 H.264 解码器的实现。
- 建议参考 Wireshark 开发者文档,了解 LUA 脚本的 API 和现有解码器的实现方式。
详细报告
引言
H.266 VVC(多功能视频编码)是 2020 年 7 月 6 日由联合视频专家组(JVET) finalized 的视频压缩标准,旨在提供比 H.265 HEVC 更高的压缩效率,平均可节省 50% 的比特率,同时支持 4K、8K 等高分辨率视频流 Versatile Video Coding - Wikipedia。MPEG2-TS(MPEG-2 传输流)是一种标准数字容器格式,广泛用于数字电视广播,如 DVB、ATSC 和 IPTV 系统 MPEG transport stream - Wikipedia。Wireshark 是一个开源的网络协议分析工具,支持通过 LUA 脚本扩展功能,以分析特定协议或数据流。本报告详细探讨如何编写 Wireshark LUA 插件,支持在 MPEG2-TS 中分析 H.266 VVC。
H.266 VVC 在 MPEG2-TS 中的传输
研究表明,H.266 VVC 可以封装在 MPEG2-TS 流中,主要通过 DVB(数字视频广播)标准支持。DVB 项目已将 VVC(H.266)纳入其核心规范,用于广播和宽带应用,特别是在支持 4K 和 8K 视频的场景中 Next-gen video codec VVC (H.266) added to DVB tuner specification - FlatpanelsHD。具体而言,DVB 标准在文档 "DVB Commercial Module A155: Implementation guidelines for the use of VVC in DVB systems" 中定义,H.266 的流类型(stream_type)为 0x2c,这与 MPEG2-TS 中 PMT(程序映射表)中用于标识基本流的字段相对应。
MPEG2-TS 的结构包括固定长度的 188 字节包,每个包包含 4 字节的头部和 184 字节的有效载荷。头部包括同步字节(0x47)、PID(包标识符,13 位)等信息,而有效载荷可能包含适应字段(adaptation field)或基本流数据。对于视频流,基本流通常以 PES(分组基本流)包形式传输,PES 包可能跨多个 TS 包,需要重组才能获取完整的 H.266 位流 MPEG-2: Understanding the Transport Stream Structure | by Amitdogra | Medium。
H.266 位流的结构
H.266 位流由 NAL(网络抽象层)单元组成,类似于 H.264 和 H.265。在字节流格式中,NAL 单元以起始码 0x00 0x00 0x01 开头,后面跟随 NAL 单元头部(2 字节)和有效载荷。NAL 单元头部定义如下:
- 第一个字节:
- 位 0-4:nu_type(NAL 单元类型,5 位)
- 位 5:nu_reserved_bit(1 位,必须为 0)
- 位 6-7:nu_reserved_two_bits(2 位,必须为 0)
- 第二个字节:
- 位 0-5:nu_layer_id(层 ID,6 位)
- 位 6-7:nu_temporal_id(时间 ID,2 位)
这与 H.264 和 H.265 的 NAL 单元头部类似,但 H.266 引入了更多支持多层和时间层级的功能 Everything You Need to Know about H.266/VVC - VideoProc。
Wireshark LUA 插件的实现
编写 Wireshark LUA 插件以分析 MPEG2-TS 中的 H.266 VVC 涉及以下步骤:
1. 注册解码器
在 Wireshark 中,TS 解码器使用 "ts.stream_type" 解码器表,根据 PMT 中的 stream_type 调用相应的子解码器。对于 H.266,stream_type 为 0x2c,因此需要在 LUA 脚本中注册:
local h266_proto = Proto("h266", "H.266 VVC Protocol")
-- 注册到 ts.stream_type 表,值为 0x2c
dissector_table = DissectorTable.get("ts.stream_type")
dissector_table:add(0x2c, h266_proto)这确保当 TS 解码器遇到 stream_type 为 0x2c 的 PID 时,会调用我们的 H.266 解码器。
2. 维护缓冲区以处理跨包数据
由于 PES 包可能跨多个 TS 包,H.266 的 NAL 单元也可能不完整地分布在多个 TS 包中。需要为每个 PID 维护一个缓冲区,累积数据以重组完整的 NAL 单元。使用 LUA 全局表实现:
h266_buffers = h266_buffers or {} -- 初始化缓冲区表在解码器函数中,根据 pinfo.ts_pid 获取对应 PID 的缓冲区:
local pid = pinfo.ts_pid
local buffer = h266_buffers[pid] or ByteArray.new()
buffer:append(buf) -- 追加当前 TS 包的有效载荷
h266_buffers[pid] = buffer3. 提取和解析 NAL 单元
从缓冲区中搜索起始码 0x00 0x00 0x01,提取完整的 NAL 单元。假设缓冲区内容为字节数组,搜索起始码的位置:
- 找到所有起始码位置,例如使用
string.find或手动遍历。 - 对于每个起始码,NAL 单元数据从起始码后的第 3 字节开始,到下一个起始码前的字节结束。
- 解析 NAL 单元头部(2 字节),提取 nu_type、nu_layer_id 等字段。
例如,假设找到起始码位置 pos1 和 pos2:
- 第一个 NAL 单元数据为 buffer[pos1+3, pos2-1]。
- 解析头部,显示在 Wireshark 树中:
local subtree = tree:add(h266_proto, buf, "H.266 NAL Unit")
local nu_type = bit.rshift(bit.band(buffer:raw(0,1), 0x1F), 0) -- 提取 nu_type
subtree:add(f_nu_type, buffer(0,1), nu_type)需要定义字段:
f_nu_type = ProtoField.uint8("h266.nu_type", "NAL Unit Type", base.DEC)
h266_proto.fields = {f_nu_type, ...}4. 处理部分 NAL 单元
处理缓冲区中不完整的 NAL 单元:
- 如果缓冲区开头没有起始码,可能是前一个 NAL 单元的延续,保留在缓冲区。
- 处理完所有完整 NAL 单元后,缓冲区中剩余数据(最后一个起始码后的数据)是新 NAL 单元的开头,保留为下次处理。
例如,假设处理后剩余数据为 10 字节,更新 h266_buffers[pid]:
h266_buffers[pid] = buffer:range(last_pos, buffer:len()-last_pos)挑战与注意事项
- 流类型确认:H.266 的 stream_type 为 0x2c 基于 DVB 标准,但可能在某些非 DVB 系统未实现,需验证实际流是否符合。
- 跨包重组:NAL 单元可能跨多个 PES 包,需确保缓冲区机制能正确累积和解析,类似 Wireshark 中 H.264 解码器的实现。
- 性能考虑:对于高比特率流,频繁的缓冲区操作可能影响性能,建议优化搜索起始码的算法。
参考实现
建议参考 Wireshark 现有 H.264 解码器实现,特别是在 TS 流中的处理方式 Wireshark 开发者文档。此外,可使用工具如 FFmpeg 生成包含 H.266 的 TS 文件进行测试 FFmpeg - Unknown key_frame and pict_type of encoded H.266 video stream - Stack Overflow。
结论
通过在 Wireshark LUA 脚本中注册 stream_type 为 0x2c 的 H.266 解码器,并实现缓冲区机制以处理 NAL 单元的跨包重组,可以成功分析 MPEG2-TS 中的 H.266 VVC 流。尽管实现复杂,参考现有解码器和 DVB 标准可有效推进开发。
表 1:H.266 NAL 单元头部字段
字段名称 | 位数 | 描述 |
nu_type | 5 | NAL 单元类型 |
nu_reserved_bit | 1 | 保留位,必须为 0 |
nu_reserved_two_bits | 2 | 保留位,必须为 0 |
nu_layer_id | 6 | 层 ID |
nu_temporal_id | 2 | 时间 ID |
表 2:常见视频流类型
流类型 (Hex) | 描述 | 标准 |
0x01 | MPEG-1 视频 | ISO/IEC 11172-2 |
0x02 | MPEG-2 视频 | ISO/IEC 13818-2 |
0x1b | H.264/AVC 视频 | ISO/IEC 14496-10 |
0x24 | H.265/HEVC 视频 | ISO/IEC 23008-2 |
0x2c | H.266/VVC 视频 | DVB A155 (推测) |
Key Citations
- Versatile Video Coding - Wikipedia
- MPEG transport stream - Wikipedia
- Next-gen video codec VVC (H.266) added to DVB tuner specification - FlatpanelsHD
- MPEG-2: Understanding the Transport Stream Structure | by Amitdogra | Medium
- Everything You Need to Know about H.266/VVC - VideoProc
- Wireshark 开发者文档
- FFmpeg - Unknown key_frame and pict_type of encoded H.266 video stream - Stack Overflow
















