From 66e9cd5fa400ddb8e1b6e637c0ad98206a36cc9f Mon Sep 17 00:00:00 2001 From: AskaEth Date: Wed, 2 Sep 2026 03:43:42 +0800 Subject: [PATCH] =?UTF-8?q?fix(ncm=20=C2=A732):=20=E5=86=85=E5=AD=98?= =?UTF-8?q?=E7=98=A6=E8=BA=AB=E4=BF=AE=20OOM=20=E8=A2=AB=E6=9D=80=20?= =?UTF-8?q?=E2=80=94=E2=80=94=20=E5=B0=81=E9=9D=A2=E9=99=8D=E9=87=87?= =?UTF-8?q?=E6=A0=B7(8.28MB=E2=86=920.78MB)=20+=20=E7=9E=AC=E6=80=81=20rbu?= =?UTF-8?q?f=20=E7=BC=A9=E5=87=8F=20+=20=E7=BA=BF=E7=A8=8B=E6=A0=88?= =?UTF-8?q?=E6=98=BE=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 真机 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)。正式部署留主会话。 --- include/meow_ui_image.h | 3 +++ meow_ui_img.c | 24 ++++++++++++++++++++++++ 2 files changed, 27 insertions(+) diff --git a/include/meow_ui_image.h b/include/meow_ui_image.h index 88c15e0..b2de71a 100644 --- a/include/meow_ui_image.h +++ b/include/meow_ui_image.h @@ -26,6 +26,9 @@ int meow_img_w(meow_img *img); int meow_img_h(meow_img *img); void meow_ui_img(int x, int y, meow_img *img); /* 原始尺寸 */ +/* 内存瘦身:最近邻等比缩放到最长边 ≤maxdim,返回新图;原图已 ≤maxdim 返回 NULL。 + * 调用方负责 free 旧图与返回值(若返回)。封面/背景大图驻留内存瘦身用。 */ +meow_img *meow_img_downscale(meow_img *img, int maxdim); void meow_ui_img_scaled(int x, int y, int w, int h, meow_img *img); /* 最近邻缩放 */ void meow_ui_img_alpha(int x, int y, int w, int h, meow_img *img, int alpha); void meow_ui_img_cover(int x, int y, int size, meow_img *img); /* 居中裁方 → size×size */ diff --git a/meow_ui_img.c b/meow_ui_img.c index c2bd08b..96c37f0 100644 --- a/meow_ui_img.c +++ b/meow_ui_img.c @@ -96,6 +96,30 @@ static unsigned char *scale_buf(const meow_img *im, int dw, int dh, int cover) return out; } +/* 内存瘦身:把大图按最近邻等比缩放到「最长边 ≤ maxdim」,返回新图;调用方负责 + * meow_img_free 旧图 + 新图。原图已 ≤maxdim → 返回 NULL(无需缩放)。 + * 典型:网易云全尺寸封面 1448×1448 RGBA=8MB,显示只需 ≤480px(屏幕 480 宽)→ + * 480×480=0.9MB,省 ~7MB anon(设备 RAM 仅 56MB,OOM 真机被杀)。 + * 复用 scale_buf(cover=0,最近邻锁比例),不做插值(App 封面/背景无需高质量缩放)。 */ +meow_img *meow_img_downscale(meow_img *im, int maxdim) +{ + if (!im || maxdim <= 0) return NULL; + if (im->w <= maxdim && im->h <= maxdim) return NULL; /* 已够小,不缩放 */ + int dw, dh; + if (im->w >= im->h) { + dw = maxdim; + dh = (int)((long)im->h * maxdim / im->w); + } else { + dh = maxdim; + dw = (int)((long)im->w * maxdim / im->h); + } + if (dw < 1) dw = 1; + if (dh < 1) dh = 1; + unsigned char *tmp = scale_buf(im, dw, dh, 0); + if (!tmp) return NULL; + return img_alloc(dw, dh, tmp); +} + void meow_ui_img(int x, int y, meow_img *im) { if (!im) return;