fix(ncm): META 改「变化+低频心跳」,不再每 100ms 刷 launcher(M10)

根因:ipc_media 主循环 `if (now - last_meta >= 1000)` 同样依赖 meow_ui_time_ms()
的坏 64 位值(REPORT §42)→ 条件恒真 → 每个 IPC 轮次都发 MSG_META。
launcher 日志 meow_20261105_122541.log:单次启动 21016 条
`ipc: META app=dev.player.ncm state=0 pos=0/0 -> ACK`,间隔 ~100ms,且全是
无变化的静止帧;launcher 每帧写 2 行日志+归并会话,SD 写放大到整机卡死。

修复:
- 新增 app/play/meta_gate.{h,c}(纯逻辑):状态/时长/标题/歌手/专辑/封面/歌词
  标志变化 → 立即报;播放中位置偏移 ≥5s 重锚(launcher 自己按 last_active 外推);
  心跳播放中 5s / 非播放 30s;硬下限 250ms(任何路径 ≤4 帧/秒);时钟回退不下溢;
  字符串按发送侧截断长度比较(超长标题不得恒判「变了」)。
- ipc_media.send_meta 改为「组快照 → 闸判定 → 才发」,删除 1s 定时器;
  时间改 ncm_monotonic_ms();首帧仍必发(注册媒体源);发送走 DEBUG 日志。
This commit is contained in:
AskaEth committed 2026-11-05 13:00:28 +08:00
1 parent 35a636ef42
commit 7f4e18b0ed
3 files changed
+175 -13

No files matched your search

+66
View File
@@ -0,0 +1,66 @@
/* play/meta_gate.h — 媒体会话 META 上报闸(M10:META 洪泛修复点;纯逻辑,宿主可驱动)。
*
* 背景(真机证据):launcher meow_20261105_122541.log 里 21016 条 `ipc: META app=dev.player.ncm
* state=0 pos=0/0 rc=0 -> ACK`,间隔 ~100ms(每次 launcher 收帧都要写日志+归并会话)。
* 旧 ipc_media 的节奏是 `if (now - last_meta >= 1000)`,同样依赖 meow_ui_time_ms() 的 64 位差值;
* 真机该值高 32 位是垃圾(REPORT §42)→ 条件几乎恒真 → 每个 IPC 轮次都发 META,
* 1s 心跳退化成 10Hz 洪泛,把 launcher 的 SD 写/会话归并拖满,整机卡死。
*
* 修复后的上报策略(不再是定时器,而是「变化 + 低频心跳」):
* - 状态/时长/标题/歌手/专辑/封面/歌词标志变化 → 立即上报(用户操作要即时可见);
* - 播放中位置相对上次上报偏移 ≥ 5s(含 seek 前后跳)→ 上报,给 launcher 重锚进度
* (launcher meow_media_display_pos 会按 last_active 自行外推,5s 足够);
* - 心跳:播放中 5s、非播放 30s(保活会话/防 launcher 会话超时清理);
* - 硬下限 250ms:任何路径(含状态抖动)都不快于 4 帧/秒。
* 时间基准由调用方给单调钟(ipc_media 传 core 的 ncm_monotonic_ms())。
*/
#ifndef NCM_META_GATE_H
#define NCM_META_GATE_H
#include <stdint.h>
/* 与 meow_ipc.h 的 m_meta_t.state 同口径(MF_PLAYBACK 会话状态)。 */
enum {
NCM_META_ST_STOPPED = 0,
NCM_META_ST_PLAYING = 1,
NCM_META_ST_PAUSED = 2,
NCM_META_ST_BUFFER = 3,
};
/* 一次上报快照(字符串由调用方持有,本模块只拷贝比较,不接管所有权)。 */
typedef struct {
int state; /* NCM_META_ST_* */
int pos_ms;
int dur_ms;
int flags; /* MF_ART/MF_COVER/MF_LYRIC 位 */
const char *title;
const char *artist;
const char *album;
const char *artwork;
} ncm_meta_snap;
typedef struct {
int inited;
int state;
int dur_ms;
int flags;
int last_pos_ms; /* 上次上报时的播放位置(判进度偏移/seek) */
int64_t last_send_ms; /* 上次上报的单调毫秒 */
char title[128];
char artist[128];
char album[128];
char artwork[192];
} ncm_meta_gate;
#define NCM_META_POS_RESEND_MS 5000 /* 播放中位置偏移(ms)触发重报 */
#define NCM_META_HB_PLAY_MS 5000 /* 播放中心跳 */
#define NCM_META_HB_IDLE_MS 30000 /* 非播放心跳 */
#define NCM_META_MIN_GAP_MS 250 /* 硬下限:任何情况下 ≤ 4 帧/秒 */
void ncm_meta_gate_init(ncm_meta_gate *g);
/* 返回 1=现在应当发送(内部已把本次快照记为「已上报」);0=不必发。
* now_ms=单调毫秒(建议 ncm_monotonic_ms())。未初始化时首调必发(注册媒体源)。 */
int ncm_meta_gate_should_send(ncm_meta_gate *g, const ncm_meta_snap *s, int64_t now_ms);
#endif /* NCM_META_GATE_H */