ncm 三期三批: 歌曲对象瘦身(1324→608B)+滑动窗口(NCM_SONG_WINDOW=256, 取消1000截断支撑任意长度歌单)+播放快照解耦 — agent-251
- core/ncm_api.h: ncm_song_t 瘦身 id24/name128/art96/al96/pic256/dt int32 (1324B→608B) - appstate.c 滑动窗口: song_ids 全量 trackIds 索引(16384) + songs[256] 窗口感知 (song_valid 位图/window_base/滑窗 memmove 保留重叠), ensure_range 批网格(100)对齐 预取, songmeta.c 盘缓存 <cache_dir>/meta/<id>.bin (回滚/二次进入 0 网络请求) - playlist.c 触底分页退役→视口 ensure(±24 行), 占位行可直点(播放线程 fetch 物化), footer 改视口区间/总数 - 播放兼容: g_play.play_song 快照(mu), run_song 起播物化后全链路(下载/歌词/IPC META/ 播放页 UI)读快照——窗口滑出当前播放曲不崩; 边界 song_count→track_ids_count - 验证(0 真实请求): pagination_sim 全 PASS(5191 无截断/52 批); window_sim 6000 首 全程下滚 750 步视口全物化/song_detail 恰 60 次/回滚+0 请求/播放 fetch 不滑窗; core 宿主+qemu 全 PASS; mipsel -Wall -Wextra 0 warning, bss 2052068→1080900(-47%) - 未部署真机(设备音频线排查中, 部署留主会话)
This commit is contained in:
1 parent
d8898afa09
commit
997f89f879
18 files changed
+987
-209
No files matched your search
@@ -41,15 +41,17 @@
|
||||
|
||||
/* ---- 数据规模(内存纪律:歌单/歌曲大列表虚拟化显示,数组有界;硬约束 R3P2 ~14MB)---- */
|
||||
#define NCM_PLAYLIST_MAX 120 /* 我的歌单上限 */
|
||||
/* 单个歌单曲目上限 = 分页驱动下的「单页渲染上限」(REPORT §14,三期第一批):
|
||||
* detail(/v6/playlist/detail, n=1)取回全量 trackIds 入 song_ids[](≤ NCM_SONG_MAX);
|
||||
* song_detail 按 NCM_SONG_BATCH 分批拉歌词对象,列表触底自动加载下一页,直到
|
||||
* song_count == track_ids_count(歌单尾部)或 == NCM_SONG_MAX(内存上限,footer 显示 x/总数)。
|
||||
* 不再硬截断 256(NCM_SONG_MAX 从 256 提升到 1000,约 1.32KB/首 → 歌曲数组 ~1.37MB,14MB 内安全)。
|
||||
* 数值权衡见 REPORT §14.8(可再上调,代价是 bss 线性增长:每 +100 首 ≈ +132KB)。 */
|
||||
#define NCM_SONG_MAX 1000 /* 歌单曲目/歌曲对象上限(append-only 分页加载) */
|
||||
/* 滑动窗口(REPORT §17,三期第三批,取代 §14 的 NCM_SONG_MAX=1000 硬截断):
|
||||
* song_ids[NCM_TRACKID_MAX] = detail(/v6/playlist/detail, n=1)取回的全量 trackIds
|
||||
* (int64×16384=128KB bss,支撑任意长度歌单,不再 1000 截断);
|
||||
* songs[NCM_SONG_WINDOW] = 物化滑动窗口(256 首 × ~608B ≈ 152KB bss,与歌单长度无关);
|
||||
* song_valid[NCM_SONG_WINDOW]= 槽位有效位图(songs[i] ↔ 全局下标 window_base+i);
|
||||
* 滚动出窗的槽位失效(数据已序列化到 <cache_dir>/meta/<id>.bin),入窗经 song_detail 按需
|
||||
* 拉取(盘缓存命中免请求)。列表 count = track_ids_count(全量),占位行驱动后台 ensure。 */
|
||||
#define NCM_TRACKID_MAX 16384 /* 全量 trackIds 索引上限(128KB bss) */
|
||||
#define NCM_SONG_WINDOW 256 /* 滑动窗口大小(内存物化歌曲对象数上限) */
|
||||
#define NCM_SONG_BATCH 100 /* song_detail 分批每批条数(≤500 安全窗内取保守 100;
|
||||
* 同时作「下一页」加载粒度;c 数组缓冲 clist[4096] 装 100 首 ≈2KB */
|
||||
* 窗口补载粒度;c 数组缓冲 clist[4096] 装 100 首 ≈2KB) */
|
||||
#define NCM_LYRIC_LINES 600 /* 歌词行上限 */
|
||||
#define NCM_COVER_MAX 288*1024 /* 封面下载限幅 ~288KB */
|
||||
#define NCM_SEARCH_MAX 32 /* 搜索结果上限(v1 只显示前 32 条,无大缓冲) */
|
||||
@@ -84,6 +86,10 @@ typedef struct ncm_play_run {
|
||||
int err; /* 最近一次播放错误(0=无) */
|
||||
char errmsg[96];
|
||||
int has_track; /* 当前是否有可播曲目(含 url 获取中) */
|
||||
/* 播放曲快照(REPORT §17):run_song 起播时把歌曲对象整体拷入(mu 保护),
|
||||
* 之后播放/歌词/IPC/UI 全读快照而非窗口——窗口滑出当前播放曲也不影响播放。 */
|
||||
ncm_song_t play_song;
|
||||
int play_song_valid; /* 1=快照有效(stop 清 0) */
|
||||
} ncm_play_run_t;
|
||||
|
||||
/* ---- 音质档位字符串(设置页 + 持久化用)---- */
|
||||
@@ -113,14 +119,19 @@ typedef struct ncm_app_state {
|
||||
int active_playlist; /* 当前打开歌单的下标;-1=无 */
|
||||
|
||||
/* 当前歌单曲目(id 用 int64_t:网易云歌曲 id 可 >2^31,MIPS32 long 溢出)。
|
||||
* song_ids[] = detail 返回的全量 trackIds(≤ NCM_SONG_MAX,分页索引);
|
||||
* songs[] = 已物化的歌曲对象(append-only,与 song_ids[] 前 song_count 首一一对应);
|
||||
* song_count = 已物化数(列表 count = song_count);track_ids_count = trackIds 总数(≥ song_count,
|
||||
* 其差值 = 仍有「下一页」待 song_detail 分批拉取)。 */
|
||||
int64_t song_ids[NCM_SONG_MAX];
|
||||
ncm_song_t songs[NCM_SONG_MAX];
|
||||
* 滑动窗口模型(REPORT §17):
|
||||
* song_ids[] = detail 返回的全量 trackIds(≤ NCM_TRACKID_MAX,全局下标索引);
|
||||
* songs[] = 物化滑动窗口,songs[i] ↔ 全局下标 window_base+i;
|
||||
* song_valid[] = 槽位有效位图(出窗=失效,入窗=物化后置位);
|
||||
* window_base = 窗口起始全局下标;song_count = 窗口内有效槽位数(≤ NCM_SONG_WINDOW);
|
||||
* track_ids_count = trackIds 总数(列表 count = track_ids_count,任意长度无截断)。
|
||||
* 窗口读写由 appstate.c 内 g_song_mu 保护;外部一律走 appstate_song_copy/ensure_range。 */
|
||||
int64_t song_ids[NCM_TRACKID_MAX];
|
||||
ncm_song_t songs[NCM_SONG_WINDOW];
|
||||
uint8_t song_valid[NCM_SONG_WINDOW];
|
||||
int window_base;
|
||||
int song_count;
|
||||
int track_ids_count; /* detail 取回的 trackIds 总数(≤ NCM_SONG_MAX) */
|
||||
int track_ids_count; /* detail 取回的 trackIds 总数(≤ NCM_TRACKID_MAX) */
|
||||
|
||||
/* 播放页视图态 */
|
||||
int playing_song; /* 正在播放歌曲在 songs[] 下标(UI 侧缓存);-1=无 */
|
||||
@@ -258,12 +269,24 @@ void appstate_set_logged_in(const char *uid, const char *nickname);
|
||||
void appstate_logout(void);
|
||||
int appstate_ensure_uid(void); /* 若 uid 缺失则 login_status_check 取回;0=成功 */
|
||||
int appstate_load_playlists(void); /* 拉我的歌单 */
|
||||
int appstate_load_playlist_songs(int idx); /* 兼容:整批载入(内部走分页循环) */
|
||||
int appstate_load_playlist_songs(int idx); /* 兼容:载索引 + 首个窗口(内部走 ensure) */
|
||||
int appstate_load_playlist_songs_page(int idx, int offset, int limit);
|
||||
/* detail(全量 trackIds)后按页拉 song_detail:
|
||||
* offset=0 重头(重建 song_ids[]/track_ids_count,清空后载第 0 页);
|
||||
* offset>0 追加第 offset 页到 g_st.songs[offset..];
|
||||
* 写 g_st.song_count(=offset+本页实际数)。 */
|
||||
/* 兼容入口(滑动窗口语义,REPORT §17):
|
||||
* offset=0 重头(detail 全量 trackIds 重建索引、清窗口、
|
||||
* 物化 [0,limit));offset>0 = 物化 [offset,offset+limit)
|
||||
* (滑窗+盘缓存+song_detail 补载,内部 ensure_range)。 */
|
||||
int appstate_song_ensure_range(int lo, int hi);
|
||||
/* 滑动窗口核心:确保全局下标 [lo,hi) 已物化。
|
||||
* 窗口未覆盖先滑窗(重叠区保留,出窗槽位失效);
|
||||
* 缺失槽位先读盘缓存(<cache_dir>/meta/<id>.bin),
|
||||
* miss 攒批 ≤NCM_SONG_BATCH 走 song_detail,成功落盘。
|
||||
* worker 线程调用(含网络);返回 NCM_OK/负错误码。 */
|
||||
int appstate_range_loaded(int lo, int hi); /* 1=[lo,hi) 全部在窗内且有效(UI 判是否需 ensure) */
|
||||
int appstate_song_copy(int gidx, ncm_song_t *out); /* 锁内读窗:0=已物化拷出;-1=窗外/未物化 */
|
||||
int appstate_song_fetch(int gidx, ncm_song_t *out); /* 任意全局下标物化(窗→盘→song_detail 单曲),
|
||||
* 不滑窗(播放线程用,避免与浏览视口抢窗口) */
|
||||
void appstate_adopt_songs(int n); /* 收编外部已填的 songs[0..n)(搜索结果)为窗口 base=0,
|
||||
* 同步 song_ids/track_ids_count(播放上下文) */
|
||||
void appstate_apply_playlist_cover(int idx);
|
||||
void appstate_set_playing_song(int idx, const char *cover_url);
|
||||
int appstate_current_playing(void); /* 返回当前播放歌曲下标(UI) */
|
||||
@@ -311,6 +334,12 @@ int64_t player_manager_pos_ms(void);
|
||||
int64_t player_manager_dur_ms(void);
|
||||
int player_manager_load_lyric(void); /* 为当前曲目拉歌词并解析 */
|
||||
int player_manager_error(void);
|
||||
int player_manager_current_song(ncm_song_t *out); /* 播放曲快照锁内拷贝;0=有效 -1=无(REPORT §17) */
|
||||
|
||||
/* songmeta(app/logic/songmeta.c):歌曲元数据本地缓存(<cache_dir>/meta/<id>.bin),
|
||||
* 拉过的 song_detail 结果序列化落盘,再次入窗免重复请求(REPORT §17)。 */
|
||||
int songmeta_load(const char *cache_dir, const char *song_id, ncm_song_t *out); /* NCM_OK / NCM_ERR_NOENT */
|
||||
int songmeta_save(const char *cache_dir, const char *song_id, const ncm_song_t *s);
|
||||
|
||||
/* ipc_media:媒体会话上报/收指令 */
|
||||
int ipc_media_start(void); /* 起 IPC 线程;0=成功 */
|
||||
|
||||
Reference in new issue
Block a user