fix(ncm): 歌单切换两bug — ①暂停态跨歌单点歌旧信息(play同曲护栏改按曲目id判同曲而非裸队列下标,切歌单后同下标换歌被吞play→修play_is_same_song) ②切歌单封面残留(playlist_tick补cover_changed/ack+invalidate重画头块);附带占位行cover_request野id修复;宿主P15/covswitch PASS,热更ncm
This commit is contained in:
1 parent
62ec405dca
commit
6eccb17f9b
5 files changed
+150
-17
No files matched your search
@@ -16,6 +16,9 @@
|
||||
* 修后 seq 变化即重启换档,状态回 PLAYING、新档位下载、eff_level 回填。
|
||||
* P13 陈旧 hires.mp3(flac 门禁前静默降级产物,hires 键下存 mp3):song_local_file
|
||||
* 迁移重命名到 exhigh 键(song_<id>_exhigh.mp3)+ 本档视为 miss 走下载(§NEW 任务2)。
|
||||
* P14 歌单里点「正在播的同曲」→ 只聚焦不重播(任务3 re-entry,同曲 id 判据)。
|
||||
* P15 跨歌单切换后同一队列下标点歌 → 不被同曲护栏吞,起播(Bug2 回归:真机日志
|
||||
* `play: re-enter current idx=0 state=2 -> no restart`,新歌永不播)。
|
||||
*
|
||||
* 编译(宿主,ncm_app 目录下):
|
||||
* gcc -O2 -ffunction-sections -DJSMN_HEADER -I. -I../sdk -I../meow_launcherd \
|
||||
@@ -61,13 +64,16 @@ void meow_audio_on_preempt(meow_audio_preempt_fn cb, void *ctx) { (void)cb; (voi
|
||||
/* core/ncm_common.c 提供 ncm_now_ms(墙钟毫秒);本 sim 不链 ncm_common.o,提供同语义桩。 */
|
||||
int64_t ncm_now_ms(void) { struct timespec ts; clock_gettime(CLOCK_MONOTONIC, &ts); return (int64_t)ts.tv_sec*1000 + ts.tv_nsec/1000000; }
|
||||
|
||||
/* ---- appstate stub:窗内全命中,id=1000+idx;fee 可注入(§20 P8) ---- */
|
||||
/* ---- appstate stub:窗内全命中,id=g_song_base+1000+idx;fee 可注入(§20 P8)----
|
||||
* g_song_base 模拟「播放队列内容变化」:P14 跨歌单切换后,同一队列下标指向另一首歌
|
||||
* (base 0→5000,idx=0 由 id=1000 变 id=6000),用于回归 Bug2 的同曲重入护栏。 */
|
||||
static int g_song_base = 0;
|
||||
static int g_fee = 0;
|
||||
int appstate_song_copy(int gidx, ncm_song_t *out)
|
||||
{
|
||||
if (gidx < 0 || gidx >= g_st.track_ids_count) return -1;
|
||||
memset(out, 0, sizeof *out);
|
||||
snprintf(out->id, sizeof out->id, "%d", 1000 + gidx);
|
||||
snprintf(out->id, sizeof out->id, "%d", g_song_base + 1000 + gidx);
|
||||
snprintf(out->name, sizeof out->name, "Song%d", gidx);
|
||||
out->duration_ms = 180000;
|
||||
out->fee = g_fee;
|
||||
@@ -77,6 +83,10 @@ int appstate_song_fetch(int gidx, ncm_song_t *out) { return appstate_song_copy(g
|
||||
/* §23:player_manager 改走 appstate_queue_*(队列来源)——sim 恒 PLAYLAST 队列 = 窗口 */
|
||||
int appstate_queue_count(void) { return g_st.track_ids_count; }
|
||||
int appstate_queue_song(int idx, ncm_song_t *out) { return appstate_song_copy(idx, out); }
|
||||
/* P14 相关:player_manager_play 的同曲护栏(play_is_same_song)会读队列来源 + 搜索数组;
|
||||
* sim 恒歌单窗口队列、搜索数组为空。appstate.c 未链入,两符号此处提供桩。 */
|
||||
int appstate_get_queue(void) { return NCM_QUEUE_PLAYLIST; }
|
||||
int appstate_search_song(int i, ncm_song_t *out) { (void)i; (void)out; return NCM_ERR_ARG; }
|
||||
|
||||
/* ---- 缓存/网络 stub ----
|
||||
* g_cache_ok=1 → lookup 命中(给真实存在的 /tmp 文件,免下载);
|
||||
@@ -650,6 +660,36 @@ int main(void)
|
||||
|
||||
usleep(200 * 1000);
|
||||
player_manager_stop_thread();
|
||||
|
||||
printf("== P15: 跨歌单切换后同 idx 点歌不被「同曲只聚焦」吞(Bug2 回归)==\n");
|
||||
/* 线程已停 → 纯逻辑判护栏(无竞态)。手工造「歌单 A 的歌停在 idx=0(id=1000)」的
|
||||
* 播放快照态;然后模拟切到歌单 B(g_song_base 0→5000:同一队列下标 idx=0 现指向 id=6000
|
||||
* 的另一首歌——真机日志实锤 `play: re-enter current idx=0 state=2 -> no restart`:新歌
|
||||
* 永不起播、播放页停在上首+暂停)。护栏改按曲目 id 判同曲后,跨歌单同下标点歌必须起播。 */
|
||||
pthread_mutex_lock(&g_play.mu);
|
||||
g_play.cur_song = 0;
|
||||
g_play.state = NCM_PC_PAUSED;
|
||||
g_play.play_song_valid = 1;
|
||||
memset(&g_play.play_song, 0, sizeof g_play.play_song);
|
||||
snprintf(g_play.play_song.id, sizeof g_play.play_song.id, "1000");
|
||||
g_play.seq = 90; g_play.pos_ms = 1000; g_play.err = 0;
|
||||
g_play.dl_done = 0; g_play.dl_total = 0;
|
||||
pthread_mutex_unlock(&g_play.mu);
|
||||
int seq_before = g_play.seq; /* 线程已停,无锁读安全 */
|
||||
|
||||
/* (a) 同歌单点「正在播的同曲」(同下标、同 id)→ 护栏放行:确证同曲 → 只聚焦不重播 */
|
||||
g_song_base = 0;
|
||||
player_manager_play(0);
|
||||
CHECK(player_manager_state() == NCM_PC_PAUSED && player_manager_playing_song() == 0 &&
|
||||
g_play.seq == seq_before,
|
||||
"same-playlist re-tap -> PAUSED/cur=0/seq=%d (expect 不重播)", g_play.seq);
|
||||
|
||||
/* (b) 切到歌单 B:队列内容变化(idx=0 现为 id=6000 的另一首)→ 同 idx 点歌必须起播 */
|
||||
g_song_base = 5000;
|
||||
player_manager_play(0);
|
||||
CHECK(player_manager_state() == NCM_PC_BUFFER && g_play.seq == seq_before + 1,
|
||||
"cross-playlist idx=0 tap -> BUFFER/seq=%d (expect 起播,不被吞)", g_play.seq);
|
||||
|
||||
printf(g_fail ? "== PLAYER FLOW SIM: FAIL ==\n" : "== PLAYER FLOW SIM: ALL PASS ==\n");
|
||||
return g_fail;
|
||||
}
|
||||
Reference in new issue
Block a user