mirror of
https://github.com/Rockbox/rockbox.git
synced 2025-10-14 02:27:39 -04:00
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
This commit is contained in:
parent
e01055a287
commit
57409f52d5
3 changed files with 25 additions and 6 deletions
|
@ -400,7 +400,8 @@ static bool read_chunk_stsz(qtmovie_t *qtmovie, size_t chunk_len)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
DEBUGF("stsz too large, ignoring it\n");
|
qtmovie->res->sample_byte_sizes_offset = stream_tell(qtmovie->stream);
|
||||||
|
DEBUGF("stsz too large: %u, save sample_byte_sizes_offset\n", numsizes);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (size_remaining)
|
if (size_remaining)
|
||||||
|
@ -481,6 +482,14 @@ static bool read_chunk_stco(qtmovie_t *qtmovie, size_t chunk_len)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Reading sample_byte_sizes data on seek can lead to additional re-buffering.
|
||||||
|
// So skip it if we have good enough seek accuracy via lookup_table (3000 ms)
|
||||||
|
if (qtmovie->res->sample_byte_sizes_offset && ci->id3->length / fit_numentries <= 3000)
|
||||||
|
{
|
||||||
|
qtmovie->res->sample_byte_sizes_offset = 0;
|
||||||
|
DEBUGF("lookup_table seek accuracy %ld ms, ignoring sample_byte_sizes_offset \n", ci->id3->length / fit_numentries);
|
||||||
|
}
|
||||||
|
|
||||||
/* Build up lookup table. The lookup table contains the sample index and
|
/* Build up lookup table. The lookup table contains the sample index and
|
||||||
* byte position in the file for each chunk. This table is used to seek
|
* byte position in the file for each chunk. This table is used to seek
|
||||||
* and resume (see m4a_seek() and m4a_seek_raw() in libm4a/m4a.c) and
|
* and resume (see m4a_seek() and m4a_seek_raw() in libm4a/m4a.c) and
|
||||||
|
|
|
@ -211,11 +211,13 @@ unsigned int m4a_seek(demux_res_t* demux_res, stream_t* stream,
|
||||||
sound_sample_i += time_cnt * time_dur;
|
sound_sample_i += time_cnt * time_dur;
|
||||||
}
|
}
|
||||||
|
|
||||||
DEBUGF("seek chunk=%lu, sample=%lu, soundsample=%lu, offset=%lu\n",
|
if (demux_res->sample_byte_sizes_offset)
|
||||||
(unsigned long)chunk, (unsigned long)chunk_first_sample,
|
{
|
||||||
sound_sample_i, (unsigned long)offset);
|
stream->ci->seek_buffer(demux_res->sample_byte_sizes_offset + chunk_first_sample * 4);
|
||||||
|
}
|
||||||
|
|
||||||
if (tsz_tab) {
|
if (tsz_tab || demux_res->sample_byte_sizes_offset)
|
||||||
|
{
|
||||||
/* We have a sample-to-bytes table available so we can do accurate
|
/* We have a sample-to-bytes table available so we can do accurate
|
||||||
* seeking. Move one sample at a time and update the file offset and
|
* seeking. Move one sample at a time and update the file offset and
|
||||||
* PCM sample offset as we go. */
|
* PCM sample offset as we go. */
|
||||||
|
@ -229,7 +231,7 @@ unsigned int m4a_seek(demux_res_t* demux_res, stream_t* stream,
|
||||||
time_dur = tts_tab[time].sample_duration;
|
time_dur = tts_tab[time].sample_duration;
|
||||||
}
|
}
|
||||||
|
|
||||||
offset += tsz_tab[i];
|
offset += tsz_tab ? tsz_tab[i] : stream_read_uint32(stream);
|
||||||
sound_sample_i += time_dur;
|
sound_sample_i += time_dur;
|
||||||
time_cnt--;
|
time_cnt--;
|
||||||
}
|
}
|
||||||
|
@ -239,6 +241,13 @@ unsigned int m4a_seek(demux_res_t* demux_res, stream_t* stream,
|
||||||
sample_i = chunk_first_sample;
|
sample_i = chunk_first_sample;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DEBUGF("seek chunk=%lu, chunk_first_sample=%lu, sample_i=%u, soundsample=%lu, offset=%lu\n",
|
||||||
|
(unsigned long)chunk,
|
||||||
|
(unsigned long)chunk_first_sample,
|
||||||
|
sample_i,
|
||||||
|
(unsigned long)sound_sample_i,
|
||||||
|
(unsigned long)offset);
|
||||||
|
|
||||||
if (stream->ci->seek_buffer(offset))
|
if (stream->ci->seek_buffer(offset))
|
||||||
{
|
{
|
||||||
*sound_samples_done = sound_sample_i;
|
*sound_samples_done = sound_sample_i;
|
||||||
|
|
|
@ -82,6 +82,7 @@ typedef struct
|
||||||
|
|
||||||
uint32_t *sample_byte_sizes;
|
uint32_t *sample_byte_sizes;
|
||||||
uint32_t num_sample_byte_sizes;
|
uint32_t num_sample_byte_sizes;
|
||||||
|
int32_t sample_byte_sizes_offset;
|
||||||
|
|
||||||
uint32_t codecdata_len;
|
uint32_t codecdata_len;
|
||||||
uint8_t codecdata[MAX_CODECDATA_SIZE];
|
uint8_t codecdata[MAX_CODECDATA_SIZE];
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue