Rockbox open source high quality audio player as a Music Player Daemon
mpris rockbox mpd libadwaita audio rust zig deno
2
fork

Configure Feed

Select the types of activity you want to include in your feed.

Codecs: mp4: Accurate seek in large files with small lookup_table

Read sample_byte_sizes table on demand when it can't be cached

Change-Id: I2191be63ceebfd8b16e1e973e13c5b51986b6564

+25 -6
+10 -1
lib/rbcodec/codecs/libm4a/demux.c
··· 400 400 } 401 401 else 402 402 { 403 - DEBUGF("stsz too large, ignoring it\n"); 403 + qtmovie->res->sample_byte_sizes_offset = stream_tell(qtmovie->stream); 404 + DEBUGF("stsz too large: %u, save sample_byte_sizes_offset\n", numsizes); 404 405 } 405 406 406 407 if (size_remaining) ··· 479 480 { 480 481 DEBUGF("stco too large to allocate lookup_table[]\n"); 481 482 return false; 483 + } 484 + 485 + // Reading sample_byte_sizes data on seek can lead to additional re-buffering. 486 + // So skip it if we have good enough seek accuracy via lookup_table (3000 ms) 487 + if (qtmovie->res->sample_byte_sizes_offset && ci->id3->length / fit_numentries <= 3000) 488 + { 489 + qtmovie->res->sample_byte_sizes_offset = 0; 490 + DEBUGF("lookup_table seek accuracy %ld ms, ignoring sample_byte_sizes_offset \n", ci->id3->length / fit_numentries); 482 491 } 483 492 484 493 /* Build up lookup table. The lookup table contains the sample index and
+14 -5
lib/rbcodec/codecs/libm4a/m4a.c
··· 211 211 sound_sample_i += time_cnt * time_dur; 212 212 } 213 213 214 - DEBUGF("seek chunk=%lu, sample=%lu, soundsample=%lu, offset=%lu\n", 215 - (unsigned long)chunk, (unsigned long)chunk_first_sample, 216 - sound_sample_i, (unsigned long)offset); 214 + if (demux_res->sample_byte_sizes_offset) 215 + { 216 + stream->ci->seek_buffer(demux_res->sample_byte_sizes_offset + chunk_first_sample * 4); 217 + } 217 218 218 - if (tsz_tab) { 219 + if (tsz_tab || demux_res->sample_byte_sizes_offset) 220 + { 219 221 /* We have a sample-to-bytes table available so we can do accurate 220 222 * seeking. Move one sample at a time and update the file offset and 221 223 * PCM sample offset as we go. */ ··· 229 231 time_dur = tts_tab[time].sample_duration; 230 232 } 231 233 232 - offset += tsz_tab[i]; 234 + offset += tsz_tab ? tsz_tab[i] : stream_read_uint32(stream); 233 235 sound_sample_i += time_dur; 234 236 time_cnt--; 235 237 } ··· 238 240 * start of a chunk, which is often much lower resolution. */ 239 241 sample_i = chunk_first_sample; 240 242 } 243 + 244 + DEBUGF("seek chunk=%lu, chunk_first_sample=%lu, sample_i=%u, soundsample=%lu, offset=%lu\n", 245 + (unsigned long)chunk, 246 + (unsigned long)chunk_first_sample, 247 + sample_i, 248 + (unsigned long)sound_sample_i, 249 + (unsigned long)offset); 241 250 242 251 if (stream->ci->seek_buffer(offset)) 243 252 {
+1
lib/rbcodec/codecs/libm4a/m4a.h
··· 82 82 83 83 uint32_t *sample_byte_sizes; 84 84 uint32_t num_sample_byte_sizes; 85 + int32_t sample_byte_sizes_offset; 85 86 86 87 uint32_t codecdata_len; 87 88 uint8_t codecdata[MAX_CODECDATA_SIZE];