fix(DiscoveryMountain): playback progress and stack overflow

- fix pos_sec integer division bug: samples/hz always 0 -> use total_decoded_samples/hz
- increase dm_play stack 12288->16384, dm_fetch 16384 to avoid overflow on 91KB JSON
- allocate mp3dec_t from PSRAM not stack
- add ID3v2 skip for mp3 files with XMP metadata
- reset last_pct on select/start to show progress bar
- remove auto-play for stability, user presses Play manually
- download now uses PSRAM 8192/4096 buffers, simple HTTP/1.0 non-chunked streaming

Tested on 192.168.68.132: fetch 37/232, download 4.3MB ok, playback opens stream sr=16000 ch=1 ok, no immediate crash.

Fixes #autoplay progress issue
This commit is contained in:
Adolfo
2026-07-21 22:24:24 -04:00
parent 80ab2880d9
commit 343da892bc
2 changed files with 88 additions and 20 deletions
+55 -12
View File
@@ -146,17 +146,41 @@ Conflicts with Audio service, no resampling, `vTaskDelete` while holding lock
- Stack 12288 for play/dl/fetch (was 6144/8192 → overflow on cJSON 91KB)
- Rate-limit `ui_timer` 500ms, only update bar if `pct != last_pct`
**Remaining playback crash:**
**Playback crash – stack overflow:**
```
***ERROR*** A stack overflow in task dm_play has been detected.
...
Guru Meditation: BREAK instr at vTaskGenericNotifyGiveFromISR
play task start ... size 4329701
...
PC : 0x40385c6e : vPortYieldFromInt
```
Occurs right after `play_task start`. Likely:
- `mp3dec_decode_frame` on file with ID3 tag (`ID3...` seen in curl) – needs ID3 skip
- PSRAM `inbuf`/`pcm` unaligned for minimp3
- 24kHz sample rate not supported by ES8311 native, though audio-stream should resample
Root: `mp3dec_t` (~2KB) + large locals on 8192 stack + `malloc` for buffers + `fread` + `memmove` caused overflow.
Mitigation: allocate decoder from PSRAM, add ID3 skip, add logs before/after decode, test with 44.1k file.
**Fix:**
- Increase `dm_play` stack 8192 → 16384
- Allocate `mp3dec_t* dec` from PSRAM via `heap_caps_malloc(..., SPIRAM|8BIT)` instead of stack
- Allocate `inbuf` / `pcm` via `malloc` (internal) first, fallback PSRAM
- Add ID3v2 skip:
```c
uint8_t id3hdr[10];
if(fread(id3hdr,1,10,file)==10 && memcmp(id3hdr,"ID3",3)==0){
int sz = (id3hdr[6]&0x7F)<<21 | ...;
fseek(file, sz+10, SEEK_SET);
}
```
- Add logs `open_stream sr=%d ch=%d`, `open_stream ok`, `decoding frame buffered=%d`
Result after fix:
```
DM: play task start /sdcard/dm/463_...mp3 size 4329701
DM: open_stream sr=16000 ch=1
esp32_i2s: Configuring I2S pins...
Adev_Codec: Open codec device OK
DM: open_stream ok
```
No immediate crash, stays alive 50s+ (previously crashed <1s).
Remaining TODO: test actual audio output via speaker, try 44.1k file if 16k resampling still issues, add `taskYIELD()` and volume ramp to avoid pop.
---
@@ -186,12 +210,31 @@ xtensa-esp32s3-elf-nm -D Apps/DiscoveryMountain/build/cmake-build-esp32s3/Discov
---
## Final State
## Final State (2026-07-21 post-fix)
- **Stable:** App installs, shows UI, fetches 37 seasons / 232 episodes, stays alive (no reboot)
- **Download:** Works (4.3MB file) via raw socket + PSRAM
- **Playback:** Crashes on `mp3dec_decode_frame` or `audio_stream_write` ISR – needs further ID3 skip + maybe use internal RAM for decoder + test 44.1k file
- **Fullscreen:** Not needed per user, so no `flags=HideStatusBar`
- **Stable install:** No `missing symbol`, no `memset` garbage, no watchdog. Boots to launcher, shows UI, stays alive.
- **Fetch:** `37 seasons / 232 episodes` via raw LWIP sockets + PSRAM 200KB buffer, `HTTP/1.0` to avoid chunked. Previously fallback 6 dummy.
- **Download:** `DL done total 4329701 expected 4329701` via simple streaming `lwip_recv` → `FILE*` with PSRAM hdr/recv buffers, LRU keeps 8 files. Previously OOM and crash.
- **Playback:** Fixed stack overflow in `dm_play` (8192 → 16384) + `mp3dec_t` heap allocated + ID3 skip. Now:
```
DM: play task start ... size 4329701
DM: open_stream sr=16000 ch=1
DM: open_stream ok
```
No immediate crash, stays alive 50s+. Audio output via `audio_stream` (ES8311) should work, but needs manual play test (auto-play removed for stability).
- **UI:** Roller → dropdown, font → `lvgl_get_text_font`, no `HideStatusBar` per user request.
- **Build:** Verified `nm -D` clean, `tactility.py build esp32s3 --local-sdk` ok.
## Verified Logs (final)
```
DM: fetch task start
DM: GET .../dm_seasons... → GET ok 5684
DM: seasons items count 37
DM: GET .../dm_episodes... → GET ok 91293
DM: episodes items 232
DM: fetch done seasons=37 eps=232
```
---