简介这份 TR101290 总结文档面向数字电视与 MPEG-2 传输流初学者系统梳理 ES、PES、TS、PS 四种数据流层次并逐一讲解 PAT、PMT、CAT、NIT 等 PSI 表的 PID 取值与解析流程可帮助读者快速建立传输流复用与节目定位的整体框架适合从事 DVB、机顶盒或码流分析相关工作的人员参考。资源为 1 个 doc 文档压缩包大小约 1.11MB内容以文字描述为主包含传送流结构图示、PAT 与 PMT 关系图、保留 PID 值表格及实例分析便于对照学习与后续查阅。已有 278 人学习下载适合作为入门总结笔记或复习资料使用。1. 转 TR101290 总结从一屏错误计数器到能直接拍板的结论做数字电视信号监测的人每天都会面对类似画面码流分析仪上几十个计数器同时跳动TS_sync_loss、Continuity_count_error、PCR_error 全亮着但没有哪一行告诉你这路信号到底算不算“有病”。所谓“转 TR101290 总结”就是把这种原始监测数据转换成一份按 TR 101 290 三个优先级归好类的总结哪些错误会直接导致黑屏哪些只是影响画质哪些暂时不影响观看但需要留档观察。它不是一个新标准而是把标准变成可执行结论的最后一公里。“转”字可以理解为转换流程也可以理解为把 TS 流里散落的监测事件转写成标准化的分级记录。适合刚接触码流监测的人也适合手里有现成抓包日志、想批量生成报告的运维工程师。2. 理解 TR101290 监测参数的三级优先级转换前必须先分级直接把计数器抄进报告是最容易翻车的做法。TR 101 290 把错误分成三个优先级本质是按照“用户能不能正常收看”这个结果来排列的。转换脚本如果不知道每个错误属于哪一级输出的总结就是一张无意义的表格。先分级再谈怎么转。2.1 Priority 1同步、PAT/PMT、连续计数这些硬错误Priority 1 的错误有六个TS_sync_loss传输流同步丢失、Sync_byte_error同步字节错误、PAT_error节目关联表错误、Continuity_count_error连续计数错误、PMT_error节目映射表错误、PID_errorPID 错误。这些错误有一个共同点任何一个持续出现接收端的解复用器就没法可靠地锁定包边界或还原节目信息用户端表现为黑屏、无节目、反复马赛克。TS_sync_loss 放在第一位不是偶然。TS 包固定 188 字节同步字节固定是 0x47一旦连续几个包找不到这个同步头包边界就乱了后续 PAT/PMT 解析全部失去意义。工程上最常见的触发原因是信号电平过低、复用器输出抖动、或者切换主备路时出现瞬时中断。Sync_byte_error 和它类似区别在于同步位置找到了但不是 0x47往往发生在码流被二次封装或者传输过程丢字节后重新对齐时。PAT_error 和 PMT_error 属于 PSI 表层面的硬错误。PAT 固定占用 PID 0x0000PMT 的 PID 由 PAT 里的节目条目指定。如果 PAT 缺失、CRC 错误、或者重复间隔超过 100ms整个传输流里的节目就失去了索引PMT 错误则说明某个节目的音视频 PID 映射已经不可信。Continuity_count_error 是同一 PID 的 CC 字段不连续丢包、多播重复、网络乱序都会触发。PID_error 的含义要宽一些它既可以指 PID 在 PAT/PMT 中未被引用也可以指 PMT 中声明了某 PID 但码流里始终找不到。做转换总结时P1 这一节只做一件事把六个错误各自的出现次数、持续时间、首次/末次时间列出来并给出一个“是否持续”的判断。持续超过监测窗口 10% 的 P1 错误应该在报告里标注为“需要立即处理”。2.2 Priority 2PCR、CRC、CAT 这些能定位原因的中间层Priority 2 的错误不会直接让解码器失锁但会显著影响解码质量和排障效率。常见的有 Transport_error传输错误、CRC_errorCRC 校验错误、PCR_errorPCR 错误、PCR_accuracyPCR 精度错误、CAT_error条件接收表错误、TS_descriptor_error描述符错误。Transport_error 对应 TS 包头里的 TEI 位。TEI 置 1 通常意味着前级的 RS 解码已经判定这一包不可恢复网络丢包、调制误码、ASI 链路抖动都可能造成。CRC_error 出现在 PSI/SI 表的 CRC32 校验失败时和 Transport_error 经常同时出现但两者不能互相替代CRC_error 可能因为表正在更新、接收端恰好读到半包而 TEI 只标记传输层。PCR_error 和 PCR_accuracy 是 P2 里最值得深挖的两个。PCR_error 判定的是 PCR 间隔是否超过门限规范要求不超过 100msPCR_accuracy 判定的是 PCR 值本身的抖动是否超过 ±500ns。前者多半是复用器 PCR 插入周期配置问题后者多半是时钟源劣化或网络抖动引入的。CAT_error 针对 PID 0x0001 的 CAT 表条件接收场景下CAT 缺失会导致 CA 描述符拿不到机顶盒无法完成解扰授权。TS_descriptor_error 比较杂凡是 PSI/SI 里描述符长度、标签、语法不符合规范的地方都会归到这里。转换总结时P2 不要和 P1 混在一起排序否则 PCR_accuracy 的一个 600ns 抖动会被排到 PAT_error 前面阅读者会被带偏判断。2.3 Priority 3SI 重复率、NIT、缓冲问题——隐蔽的慢性病Priority 3 是容易被忽略的一组因为它通常不直接影响当前画面。NIT_error网络信息表错误、SI_repetition_errorSI 重复率错误、Buffer_error缓冲错误、Unreferenced_PID未引用 PID、SDT_error、EIT_error、RST_error、TDT_error、Empty_buffer_error、Data_delay_error 都归在这一级。SI 类错误里最典型的是 NIT、SDT、EIT 的重复间隔超时。DVB 规范里 NIT 建议不超过 10sSDT 不超过 2sEIT 不超过 25s。间隔超时不会让用户立刻黑屏但会导致 EPG 菜单显示缓慢、频道切换后信息加载变久。Buffer_error 和 Empty_buffer_error 指向 T-STD 缓冲模型当复用器的码率规划不合理时视频解码缓冲可能上溢或下溢最终表现为周期性卡顿但没有任何 P1 错误。Unreferenced_PID 需要小心解读。空包 PID 0x1FFF 和部分承载填充数据的 PID 会被一些设备统计为未引用 PID但它们在业务上是合法的。转换脚本必须先把 0x1FFF 和 PMT 里已声明的 PID 过滤掉再统计真正的漏报 PID。P3 的总结价值在于趋势而不是单次数值一次 5 分钟的监测里出现几次 EIT 超时没有实际意义连续几天同一时段出现才说明 EPG 注入器有问题。下表可以帮你快速建立三级的总体印象优先级典型错误用户可见影响定位难度Priority 1TS_sync_loss、PAT_error、Continuity_count_error黑屏、无节目、反复马赛克后果严重但定位路径短Priority 2PCR_error、CRC_error、CAT_error画质劣化、花屏、时钟不稳需要结合码流和网络两层判断Priority 3NIT_error、SI_repetition_error、Buffer_errorEPG 慢、偶尔卡顿、潜在风险需要长时间统计才看得清分级是转换的前提。到了写转换脚本这一步脑海里始终要有一条规则P1 决定报告值不值得看P2 决定问题出在哪P3 决定要不要继续投入时间观察。3. 把监测数据转成 TR101290 总结搭建一条可重复的转换链路分级理解了剩下的问题是怎么把原始数据变成一份报告。这一步没有统一的现成工具大多数团队都是自己拼链路先拿到原始监测数据再做归一化最后渲染成 Markdown 或 HTML 总结。3.1 原始数据的三种来源与选型常见的数据来源有三种。第一种是码流分析仪的导出日志这类设备把 TR101290 的参数都已经算好了输出通常是 CSV 或 XML问题在于不同设备的字段名不统一需要写适配器映射。第二种是抓包工具直接抓 TS 流比如 tshark 按 UDP 端口抓媒体流保存成原始 TS 文件然后用脚本自己解析优点是原始数据完整缺点是 PSI/SI 的表内容解析要自己补。第三种是自研解析器直接读 TS 文件算错误参数灵活性最高但开发量也最大。三者对比如下数据来源优点缺点适用场景码流分析仪日志TR101290 参数已算好格式稳定不同设备字段名不一致批量处理费劲单点短时监测、验收测试tshark 抓包能拿到完整原始 TS可回溯PSI/SI 解析不全需要自己补表解析排障时保留现场、交叉验证自研解析器字段完全可控可批量跑历史文件开发、维护成本高长期监测、自动巡检、回归测试我一般会先用码流分析仪导出一次完整日志同时用抓包工具存一份原始 TS 文件。转换脚本先用日志跑通再用原始 TS 文件里的数据交叉核对一遍两个来源对得上才敢把脚本放到自动巡检里。3.2 用脚本把原始错误计数归一化成标准分类无论数据源是什么转换链路的第一步都是把原始记录归一化成统一的错误名。下面这个脚本解析一个 188 字节的 TS 文件统计最基础的同步错误、传输错误和连续计数错误可以作为自研解析器的起点# parse_ts.py # 用法: python3 parse_ts.py input.ts # 只解析 188 字节 TS 包204 字节带 RS 码的变体不在本脚本范围 import sys from collections import Counter TS_LEN 188 SYNC 0x47 def parse_ts(path: str) - dict: pid_counter Counter() cc_map {} # 记录每个 PID 上一次的连续性计数器 errors Counter() total 0 offset 0 with open(path, rb) as f: data f.read() while offset TS_LEN len(data): if data[offset] ! SYNC: errors[sync_byte_error] 1 offset 1 continue pkt data[offset:offset TS_LEN] offset TS_LEN total 1 # TS 头结构: 首字节同步第二字节高5位是 PID 高5位 # 第三字节是 PID 低8位第四字节含 TEI、adaptation_field_control、CC b1 pkt[1] b2 pkt[2] b3 pkt[3] tei (b1 7) 0x01 pid ((b1 0x1F) 8) | b2 cc b3 0x0F afc (b3 4) 0x03 # adaptation_field_control if tei: errors[transport_error] 1 if afc 0: errors[invalid_afc] 1 # 只有当前包承载负载时才校验 CC 连续性 if afc in (1, 3): if pid in cc_map: expected (cc_map[pid] 1) 0x0F if cc ! expected: errors[continuity_count_error] 1 cc_map[pid] cc pid_counter[pid] 1 return {total_packets: total, pids: pid_counter, errors: errors} if __name__ __main__: if len(sys.argv) ! 2: print(usage: python3 parse_ts.py input.ts) sys.exit(1) result parse_ts(sys.argv[1]) print(total packets:, result[total_packets]) for err, cnt in result[errors].items(): print(f{err}: {cnt})这个脚本只做了最底层的包级统计重点在三个关键参数afcadaptation_field_control决定当前包是否携带负载CC 只在有负载的包上做连续性校验否则适配域里没有 payload 的包可能会被误判为丢包。tei 标志位需要保留单独计数因为它在 TR101290 里归到 P2不能和同步错误混在一起。真正的生产环境还要在此基础上补两块一是解析 PAT/PMT把 PID 与节目、音视频流、PCR_PID 对应起来二是解析 PCR 字段计算 PCR 间隔和精度。这两块代码量不小建议先只做包级错误再逐步加上去。3.3 输出 Markdown/HTML 总结报告包级统计完成之后下一步是把错误名映射到 TR101290 的三级分类并计算速率。下面这个脚本读取一个简单的 CSVerror_name,count按照优先级分组输出 Markdown 报告# summarize_tr101290.py # 用法: python3 summarize_tr101290.py --input errors.csv --window 60 # errors.csv 格式: error_name,count import csv import sys from collections import defaultdict # TR101290 错误分级映射按需扩充 P1 {ts_sync_loss, sync_byte_error, pat_error, pmt_error, continuity_count_error, pid_error} P2 {transport_error, crc_error, pcr_error, pcr_accuracy, cat_error, ts_descriptor_error} P3 {nit_error, si_repetition_error, buffer_error, unreferenced_pid, sdt_error, eit_error, rst_error, tdt_error, empty_buffer_error, data_delay_error} # 速率阈值: 每秒超过该值标记为需关注 THRESHOLD { ts_sync_loss: 1, sync_byte_error: 1, pat_error: 0.1, continuity_count_error: 1, pcr_error: 0.1, } def build_report(input_path: str, window: int) - None: bucket defaultdict(lambda: {count: 0, level: P3}) with open(input_path, newline) as f: for row in csv.DictReader(f): name row[error_name] count int(row[count]) bucket[name][count] count if name in P1: bucket[name][level] P1 elif name in P2: bucket[name][level] P2 lines [# TR101290 总结报告, f采样窗口: {window}s, ] for level in (P1, P2, P3): lines.append(f## {level}) for name, info in sorted(bucket.items()): if info[level] ! level: continue rate info[count] / window mark [需关注] if rate THRESHOLD.get(name, 999999) else lines.append(f- {name}: {info[count]} ({rate:.2f}/s){mark}) lines.append() with open(tr101290_summary.md, w, encodingutf-8) as f: f.write(\n.join(lines)) if __name__ __main__: if len(sys.argv) ! 5 or sys.argv[1] ! --input or sys.argv[3] ! --window: print(usage: python3 summarize_tr101290.py --input errors.csv --window 60) sys.exit(1) build_report(sys.argv[2], int(sys.argv[4]))这段脚本最核心的是分级映射表P1、P2、P3 的集合决定了输出报告的结构。window 参数要跟着真实监测窗口走否则速率算出来是错的。THRESHOLD 里的数值只是示例实际要根据历史数据校准不能拿标准值一刀切。输出报告按优先级分节P1 永远在最上面。4. 转换过程中的 5 个常见坑现象、原因、解决转换流程跑通不难难在跑出来的报告靠谱。下面五个坑都是实际排障时遇到过的每一条都按“现象、原因、解决”的顺序说清楚。4.1 坑一PCR 错误被重复统计现象同一路信号的 PCR_error 在一段时间内出现几千次但画面没有明显问题按速率算更是高得离谱。原因很多码流分析仪会把“PCR 间隔超时”和“PCR 不连续”分开计数导出日志时两个字段都叫 PCR_error另一些设备在窗口切换时不清空累计值导致跨窗口重复累加。解决转换脚本里对 PCR 类错误要按 PCR PID 维度去重同一个窗口内同一条 PCR 流只保留首次触发时间其余计数全部丢弃。窗口切换时强制重置计数器严禁跨窗口累加。4.2 坑二空包和填充包导致 PID 计数虚高现象总结报告里 Unreferenced_PID 数量巨大占了 P3 一节的大半篇幅但实际业务完全正常。原因PID 0x1FFF 是空包本来就允许存在部分复用器还会用携带适配域的填充包来对齐码率这些包在 PMT 里没有对应条目被统计成未引用 PID。解决在归一化步骤里先过滤 PID 0x1FFF再根据 PMT 解析结果建立一个合法的 PID 集合只统计“既不在 PMT 里也不等于 0x1FFF”的 PID。过滤逻辑要写在最前面否则后面所有统计都会被虚高数据带偏。4.3 坑三多节目流中 PMT 周期抖动被误判现象单节目流监测一切正常同一个 TS 文件切成多节目流之后PMT_error 偶发出现。原因多路节目共用一个传输流复用器在带宽紧张时会把 PSI/SI 的插入周期拉长。PMT 的 100ms 间隔是理论值实际复用器可以配置成 150ms 甚至更长并不影响接收机正常工作。解决转换脚本里不要用全局统一阈值去卡 PMT 间隔应该对每个 PMT PID 单独计时并把复用器里实际配置的 SI 周期作为参数传进来。报告里如果 PMT_error 触发要同时打印当前 PMT 的实际间隔和配置周期方便判断是配置问题还是真实故障。4.4 坑四时间窗口不统一报告之间无法对比现象同一条信号早上测错误率 0.5/s下午测变成 0.05/s结论完全相反。原因两次监测的窗口分别是 30 秒和 10 分钟。错误计数是累计值窗口拉长后平均速率自然下降直接比速率没有意义。解决所有报告统一使用固定窗口比如 60 秒。转换脚本的 window 参数在内部固定不随外部传入随意变化。报告头部必须写明采样起始和结束时间以及实际窗口长度方便后续人工对比。4.5 坑五把 Priority 3 当成 Priority 1 输出现象报告第一页列出了大量 P3 错误阅读者第一反应是信号已经崩了实际上画面一直正常。原因原始日志把所有错误混合排列转换脚本没有做分级映射直接按出现次数排序输出导致 NIT_error、SI_repetition_error 这类 P3 错误排到了 P1 前面。解决输出前强制走分级映射表P1、P2、P3 按固定顺序分节P1 里只允许出现六个硬错误。如果 P3 的计数异常高单独在报告末尾加一个“P3 异常提示”小节不要把它插入到 P1 区域。5. 参数怎么设监测时长、PCR 容限与 SI 超时阈值转换脚本里的阈值不是随便填的。TR101290 给出了基准值但工程上要结合监测目的微调。这里的参数直接影响报告里哪些条目会被标记为“需关注”设松了漏报设严了天天误报。5.1 监测时长与采样窗口单次监测至少覆盖 10 秒这是覆盖 PAT/PMT 100ms 周期的最短窗口。实际建议至少 60 秒因为 P3 里的 SI 重复率错误需要足够长的观察期才有统计意义。排障场景直接取 5 分钟既不会等太久也能覆盖大多数瞬时抖动。窗口长度还会影响速率的可信度。60 秒窗口里出现 60 次 Continuity_count_error和 10 分钟窗口里出现 60 次结论完全不同。转换脚本的报告头部必须把窗口写清楚建议把 window 参数做成配置项而不是硬编码每次调用都显式传入。采样窗口和错误计数之间还有一个关系要记住TS 流是恒定码率的窗口越长总包数越大但错误计数的绝对值不应该线性增长。如果脚本输出中某个错误计数随窗口线性膨胀先检查是不是统计逻辑没有做去重。5.2 PCR 容限与间隔PCR 相关参数是 P2 里最容易调错的。TR101290 对 PCR 间隔的基准值是 100ms对 PCR 精度的基准值是 ±500ns。工程上我一般会分成两档验收测试用标准值排障用严一格的值比如间隔按 40ms 卡精度按 300ns 卡。严一格的意义不是制造告警而是提前暴露问题。一些老编码器的 PCR 抖动在 400ns 左右标准值下不报错但如果换成 300ns 就能看到规律性抖动这在长时间运维中往往是时钟板老化的前兆。建议参数做成 profile验收 profile 和排障 profile 分开存。PCR_error 的判定还要注意 PCR PID 的选取。多节目流里每个节目都有自己的 PCR_PID脚本要按 PMT 里声明的 PCR_PID 分别计时不能拿一个全局 PCR 代替。否则某个节目没有 PCR 时会把另一个节目的 PCR 间隔错误地套到它头上。5.3 SI 超时阈值SI 表的重复间隔是优先级 3 判断的核心。常用参数如下表类型规范基准值工程建议值说明PAT100ms100ms超时直接报 P1PMT100ms100ms可放宽到复用器配置值多节目流按 PID 单独判断NIT10s10s超时报 P3SDT2s2s超时报 P3EIT25s25s超时报 P3连续监测可放宽TDT30s30s超时报 P3需要特别说明的是PMT 的阈值在实际工程里经常被放宽。复用器厂商的缺省配置可能就不是 100ms如果硬按 100ms 卡多节目流几乎每天都会误报。我的做法是把复用器的实际配置周期读出来写进脚本配置比基准值略宽松一点而不是直接固定死。SI 超时的统计要区分“首次出现”和“持续超时”。一次偶尔超时通常无害连续 5 个周期都超时才值得在报告里标记。转换脚本里加一个“连续超时次数”字段比单纯计数更能反映真实状态。6. 把总结做成能指导排障的东西趋势对比与根因判断固定窗口的总结报告适合单点验收但真正用于运维时还要往前再走一步把多份总结串成时间序列。我自己的做法是每小时生成一份 TR101290 总结文件名带时间戳然后用一个简单的脚本把所有报告的 P1、P2 计数提取出来画趋势图。P1 错误如果呈周期性出现大概率是前端切换或调度任务导致的如果是随机尖峰优先查网络抖动。PCR_error 还需要继续分把某段时间内所有 PCR 间隔偏差做直方图峰值集中在 100ms 附近说明是 PCR 插入周期配置问题偏差随机分散则更可能是网络抖动引入的。验证转换脚本本身也很重要。不要拿正常文件测要人为构造异常 TS 文件每隔 100 个包删掉一个脚本应该能准确检出 Continuity_count_error把同步字节改成 0x48应该能检出 Sync_byte_error。准备两个固定文件一个正常一个被破坏每次修改脚本后都跑一遍回归才能保证报告可信。我最开始做转换脚本时只按计数器名称排序列出所有错误报告发出去当天就被同事回信说第一页全是 P3 条目。后来强制先分级、再过滤、再计算速率报告才真正有人看。希望帮到你。本文还有配套的精品资源点击获取