Go语言下SDT写入ts文件时CRC-32校验值计算问题
解决SDT包CRC-32校验值计算问题(Go语言)
核心规则明确
SDT属于MPEG-TS的PSI/SI section,其末尾的4字节CRC-32必须遵循MPEG-2 CRC标准计算,且仅针对section的特定范围:
- 计算范围:从section header的
section_length字段之后的第一个字节,到CRC字段之前的最后一个字节(即排除section header前3字节,以及最后4字节的CRC本身)。 - CRC参数:多项式
0x04C11DB7,初始值0xFFFFFFFF,最终结果需反转比特后异或0xFFFFFFFF。
Go语言实现代码
直接基于标准库hash/crc32实现符合要求的计算逻辑:
package main import ( "hash/crc32" ) // 预生成MPEG-2 CRC-32的计算表(多项式与IEEE相同,但处理逻辑不同) var mpeg2CRCTable = crc32.MakeTable(crc32.IEEE) // CalculateSDTCRC 计算SDT section的CRC-32校验值 // sectionBytes: 完整的SDT section字节流(已剥离TS头) func CalculateSDTCRC(sectionBytes []byte) uint32 { // 确定CRC计算的有效数据范围:跳过前3字节的section header,排除最后4字节的CRC字段 if len(sectionBytes) <= 7 { return 0 // 数据长度不足,无效 } dataToCheck := sectionBytes[3 : len(sectionBytes)-4] // 初始值为0xFFFFFFFF,更新计算CRC crc := crc32.Update(0xFFFFFFFF, mpeg2CRCTable, dataToCheck) // 反转比特并异或0xFFFFFFFF得到最终结果 crc = ^crc32.ReverseBits(crc) return crc }
常见错误排查
- 错误计算范围:不要把TS包的4字节同步头包含进来,必须先剥离TS头,只处理SDT的section payload;也不要把CRC字段本身加入计算。
- CRC规则误用:不要直接使用
crc32.ChecksumIEEE,它的初始值是0,输出也没有反转异或,不符合MPEG-2标准。 - 字节顺序混淆:计算时保持原始字节流顺序,无需反转字节,仅在最后处理CRC结果的比特顺序。
内容的提问来源于stack exchange,提问作者Kseniya Chapygova
相关产品推荐
相关产品推荐

