fix(ncm §32): 内存瘦身修 OOM 被杀 —— 封面降采样(8.28MB→0.78MB) + 瞬态 rbuf 缩减 + 线程栈显式

真机 dmesg 实锤:OOM Kill ncm (score 460, anon-rss 26.9MB, 设备 56MB)。
画像:封面全分辨率 RGBA 8.28MB(1448x1448 原生解码驻留) 是最大可控块。

瘦身(按收益排序):
1. sdk meow_ui_img 新增纯增量 meow_img_downscale + cover.c cover_cap(≤480px)
   → 封面 8.28MB→0.78MB,-7.65MB(mem_sim 实测 PASS)。
2. ncm_api.c 瞬态响应 rbuf:song_url→64KB、lyric/song_detail/cloudsearch/user_playlist→256KB
   (detail/track_all 保 1MB)。
3. ncm_app_internal.h 新增 ncm_thread_create(显式 128KB 栈),替换全部 14 处 pthread_create。
4. 滑动窗口/meta 复核零回退(window_sim:608B/首,6000 首 280KB 恒定)。

验证:mem_sim 封面收益 PASS + host home/player 渲染 OK + stream_sim/player_flow_sim/
window_sim/search_sim/cache_evict_sim 全 PASS + test_ncm_core host+mipsel(qemu) PASS
+ build_ncm.sh -Wall -Wextra 0 warning。真机 scp 播放在跑确认(缓存曲,0 播放请求)。

新 ncm md5 44fa16fe(text 1015150/bss 1362500)。正式部署留主会话。
This commit is contained in:
AskaEth committed 2026-09-02 03:43:42 +08:00
1 parent 202caaf66b
commit 68ce46a5d8
19 files changed
+368 -19

No files matched your search

+3 -3
View File
@@ -369,7 +369,7 @@ static int song_download_attempt(const ncm_song_t *s, int idx, int seq, const ch
size_t cap = (ext[0] == 'f') ? (1024u << 20) : (64u << 20);
ss->maxb = (u.size > 0 && (uint64_t)u.size < cap) ? (size_t)u.size : cap;
ncm_strlcpy(ss->url, u.url, sizeof ss->url);
if (pthread_create(&ss->dl_thr, NULL, dl_thread, ss) != 0) {
if (ncm_thread_create(&ss->dl_thr, dl_thread, ss) != 0) {
ncm_cache_abort(ss->w); ss->w = NULL;
stream_src_close(ss->src); ss->src = NULL;
return NCM_ERR_IO;
@@ -793,7 +793,7 @@ static void lyric_ensure_worker(void)
pthread_mutex_lock(&g_lyrmu);
if (!g_lyr_thr_on) {
g_lyr_thr_on = 1;
if (pthread_create(&g_lyr_thr, NULL, lyric_worker, NULL) == 0) pthread_detach(g_lyr_thr);
if (ncm_thread_create(&g_lyr_thr, lyric_worker, NULL) == 0) pthread_detach(g_lyr_thr);
else g_lyr_thr_on = 0;
}
pthread_mutex_unlock(&g_lyrmu);
@@ -825,7 +825,7 @@ int player_manager_start(void)
g_cache_gb = g_st.cache_limit_gb;
pthread_mutex_init(&g_play.mu, NULL);
meow_audio_on_preempt(on_audio_preempt, NULL); /* 被抢占 → 暂停(SDK 读线程分发) */
if (pthread_create(&g_thr, NULL, player_thread, NULL) != 0) return -1;
if (ncm_thread_create(&g_thr, player_thread, NULL) != 0) return -1;
g_thr_on = 1;
return 0;
}