Repository navigation
CarPToCarL 1.2.7 — 冻结自愈 + 帧率跟随车机
目标帧率改为跟随车机(同版本补充,包已重打)
车机在 /info displays[0].maxFPS 里本来就声明了自己的解码上限,以前一律按 60 发。
大屏车机常见 30,发 60 的结果是车机侧丢帧、解码队列堆积,严重时按超时拆链。车机既然报了,就没有理由跟它对着干。
carMaxFps > 0 → 按车机值出帧(夹在 24…120)
carMaxFps <= 0 → 按 60(车机没声明,沿用通用线一直以来的值)
两个保护:下限 24 防车机报 10、15 这类荒谬值(多半是字段解析错位);上限 120 防编码器与合成器跟着疯。
改动不只换了编码器参数——合成器的出帧节奏也跟着走。建屏发生在 AirPlay SETUP 之前,那时还不知道车机上限,所以先按 60 起,拿到 /info 后由会话层改。不同步的话,多出来的帧会白白送去编码再丢掉。
日志里能直接对账,三种来源分得清:
DISPLAY: 车机 1920×720(/info 通告)→ 流 1920×720(100%)@30fps(跟随车机 maxFPS=30)
DISPLAY: 车机 …@60fps(车机未声明 maxFPS,按 60 声明)
DISPLAY: 车机 …@24fps(车机报 10fps(低于下限),按 24 声明)
顺带修掉一个把来源搞混的旧兜底:/info 里没有 maxFPS 时,旧代码直接给 30,于是「车机要 30」和「车机什么都没说」在数据上再也分不开,上面这条规则会永远退化成按 30 发。现在未声明就是 0,SETUP 完成 那行也会照实写「车机未声明fps」。
没有设置项,也不需要用户配置:车机报 60 就是 60,报 30 就是 30。
进程被冻结不再靠猜:一秒定性,解冻后自己爬起来
「画面突然定住,一两分钟后车机把会话撤了」——这个现象在日志上几乎是灵异事件:整段空白、没有任何异常、没有崩溃。上一版透过一份实车日志(Xiaomi 13 Ultra,奥迪 MIB3)才确认:进程被系统冻结了 133 秒,冻结期间不发帧、不回 keepAlive,车机熬到超时就把 AirPlay 会话撤了。
以前只能靠三个旁证去推:日志整段消失、解冻瞬间帧率飙到 397fps、积压日志在同一毫秒涌入。本版把它变成一行确定的话,并让 App 在解冻后自己重建会话。
一、冻结监视(PROC 日志)
保活服务里每秒一次心跳,比对 elapsedRealtime()——这是单调时钟,进程被冻结时它照常走。所以解冻后第一次心跳就会看到「本该 1 秒前跑的那次现在才到」:
PROC: 进程被系统冻结 133 秒(心跳中断 134s)——冻结期间不发帧、不回 keepAlive,车机多半已按超时撤掉会话
阈值取 4 秒(3 秒容差),避开主线程跑重活造成的正常迟到。3~10 秒只记录不动作——抖动多半只是主线程被占,会话没受伤,重建反而多拆一次链。
二、解冻后自动恢复
冻结超过 10 秒才动手,流程:
PROC: 解冻 133s 自检——CarLife:7240=在监听,车机 AirPlay=不可达(多半已被车机撤掉会话),推流=已断
PROC: 重建会话 第 1/4 次(退避 3000ms · 端点 GeXu-Audi_5GHz)
PROC: ✓ 会话已自动恢复(第 1 次尝试)
- 先等 1.5 秒,让积压的帧与回调喘完,再判断现状
- 复核「是否真在推流」;还在推就只记一行收工,不做多余动作
- 自检 CarLife 7240 与车机 AirPlay 两个源,按 3 / 6 / 12 / 24 秒退避重建,每轮 8 秒观察窗,最多 4 轮
- 重建依赖最后一份可用端点快照——车机不会因为「手机刚解冻」再补发一遍交接报文
- 恢复线程互斥:冻结常常是「抖几下」,不互斥会叠出多轮并行重建互相拆台
判定用的是「用户是否想要会话」(点「启动连接」置真、「断开」置假),不是「连接是否被取消」——链路一断后者就会置真,而「链断了」正是冻结后的常态,用它等于永不恢复。
三、日志降噪
解冻瞬间积压的日志会把真正有用的信息冲走,本版限流三类高频行:
| 日志 | 之前 | 现在 |
|---|---|---|
媒体进度 xxxms |
每秒一条,解冻时 0.5 秒刷 100+ 条 | 10 秒一条 |
媒体信息(xxB)但解析为空 |
每次媒体变化一条 | 5 秒一条 |
通知监听器未被系统绑定——已请求重绑 |
每 10 秒一条(单机刷过 90+ 条) | 动作仍每 10 秒做,话 5 分钟说一次 |
已知局限
- 只覆盖「进程还活着」的冻结。被系统直接杀进程走的是「靠近车机自动拉起」路径(1.2.6 已有),不是这条。
- 冻结期间车机侧已经判死,恢复必然是一次完整重连(3~10 秒黑屏),做不到无缝。
- 若冻结时用户已经拔掉车机或走远,恢复会白跑四轮(约 45 秒 + 观察窗),最后落一行「自动恢复未成功」。
- 用户先按了「断开」再解冻,会明确跳过恢复并记一行
PROC: 解冻后用户已断开——不自动恢复。
安装
下载 CarPToCarL-1.2.7.apk 覆盖安装即可(versionCode 10207,可直接覆盖 1.2.6)。CarPToCarL-latest.apk 与它内容一致,保留这个固定名字方便直接取最新版。
本次是同版本重发:
1.2.7/10207没变,只多了「帧率跟随车机」那一节。装过旧 1.2.7 的可以直接覆盖,
系统不会因为「版本号没涨」拒装。
三项权限仍建议保持开启,否则后台链路会被系统拦掉:
- 忽略电池优化——冻结的主要成因,不给的话进程随时可能被挂起
- 显示在其他应用上层——不给的话,靠近车机时「后台打开界面」会被静默拦掉
- 自启动 / 关联启动(部分 ROM)——关掉的话靠近广播根本投不到本应用
测试
单元测试 270 例通过(本版新增 FreezeWatchTest 6 例、LogThrottleTest 4 例)。
文档
docs/process-freeze-recovery.md:PROC 日志样例、判定原理、恢复时序、三条边界、排查关键字。