背景
Hub 已切到新协议(601–609)+ KMFUTranLib DataBridge 投屏。链路大致是:
MirrorCaptureCoordinator → ScreenCaptureEncoder → MirrorSenderController → MirrorVideoSendPump → USB/asyncWriteData → Win 解码回显
表面现象都是「Win 端花屏」,但根因并不止一种。早期容易把「采集没对齐 Line」「USB 坏了」「解码器问题」混在一起。
第一阶段:先对齐 Line,再谈花屏
最初方向是:Hub 自研采集是否该更像 Line。
- 结论是:协议不动;真正差在采集策略,不是
protocol包。 - 做法是把硬编码
LINE_MATCH_ENCODER做成调试开关(HubSettings+ Debug 页),默认开,方便 A/B。 - 同时明确:不整段移植 Line
RecordService,帧出口仍走 Hub 新协议。
这一步解决的是「行为可控可比」,还没直接钉死花屏根因。
第二阶段:用 dump 分层,先排除「传输损坏」
花屏出现后,没有先改代码,而是把链路切成可回放的切片:
| 落盘 | 含义 |
|---|---|
*_encoder_out.h264 | MediaCodec 刚读出 |
*_android_h264.h264 | 入队发往 Win 成功 |
*_pre/post_chunk.h264 | USB 切片前/后 |
Win 侧 *_win_h264.h264 | 对端收到 |
对照后先排除了两类误判:
- USB 分包损坏 — 切片前后一致、
USB_WRITE_FAIL基本为 0 - DataBridge sync/async 写模式本身 — 不是主因
也澄清了几个「假象」:
encoder_out单独播可能缺 SPS,看起来「坏」,不等于编码出口真坏- PotPlayer 竖窗横条,有时是多分辨率拼进同一文件 + 转屏 mid-stream SPS,属于播放假象,不等于当场花屏机制
方法论上的转折点:花屏要对齐「同一会话、同一时间窗」的多层 dump + 日志,而不是只看 Win 画面。
第三阶段:发现其实是两类花屏
A. 结构性花屏(缺 SPS / 过小首 I)
样本 20260914_135559 一带:
- 前 2MB 没有 SPS/PPS
- 首枚 IDR 只有约 2KB(正常常是几十~上百 KB)
- 随后一串极小 P 帧
关键认知纠正:
- Line 也是「编码器吐什么发什么」,不会手动拼 SPS/PPS
- Hub 在
LINE_MATCH=开时其实已经从MediaFormat缓存了 csd,但故意不拼到 I 帧前 - 一旦编码器先吐出「无参数集 + 过小 KEY」,就会把坏参考直送 Win,花到下一枚正常 IDR
对应修复思路(已合入 LINE_MATCH 补丁方向):
- 首 KEY 前 prepend csd(SPS/PPS)
- 挡住过小首 I(如 <4KB)
B. 丢帧型花屏(巨 P / 中途静默丢 P)
样本 _blur_1612 一带更关键:
encoder_out清晰android_h264花- 对帧发现少了若干 P,日志里
paceDrop次数对得上
根因不是编码坏了,而是发送侧 shouldPaceDrop 静默丢掉中途 P(不断 I):
- 参考链断了 → 解码器宏块 conceal → 看起来像花屏
- 表现很像「传输花了」,但 dump 证明:坏在 Android 入队前就被策略丢掉了
对应修复:
ENABLE_USB_WRITE_PACE_DROP = false- 真积压仍走「清队 + 催 I」,不再静默丢中途 P
另:转屏曾试验过严格 hold(ORIENTATION_STRICT_HOLD),后为对齐 Line 又改回 false(简单开推)。
第四阶段:收口成可提测版本
调试手段(多层 dump、AgentDebugNdjson、KMFU debug、巨 P/USB_WRITE 刷屏日志)在定位阶段很有用,但会干扰提测:
- 全部默认关掉
- 默认仍
lineMatch=true - 打出
1.0.32release 包给同事测稳态花屏 + 横竖屏切换
心路历程一句话
先以为是「没对齐 Line / USB 坏了」→ dump 证明传输大体健康 → 再拆成「参数集/首 I 结构问题」和「策略静默丢 P」两条线 → 用 encoder vs android_h264 对帧把后者坐实 → 关掉 paceDrop,并给 LINE_MATCH 补上必要的 SPS/小 I 防护 → 清调试后出提测包。
经验沉淀(以后再遇花屏可直接用)
- 先分层 dump,再改策略;不要一上来调码率/协议。
- encoder 清晰、android_h264 花 → 优先查发送队列丢帧(尤其 paceDrop)。
- 本机播 android_h264 就花/解不开 → 优先查 SPS/PPS 与首 KEY 体积。
- Win 独花、Android dump 正常 → 再对 Win dump / 解码侧。
- 转屏花屏要单独看:mid-stream SPS + 分辨率切换,别和稳态丢 P 混为一谈。