diff options
author | Magnus Holmgren <magnushol@gmail.com> | 2006-08-23 13:10:48 +0000 |
---|---|---|
committer | Magnus Holmgren <magnushol@gmail.com> | 2006-08-23 13:10:48 +0000 |
commit | 9f09a394368a8fb2fb0da7840535ce9cd5583ee0 (patch) | |
tree | 754bc12cd648709b36cd5d5939e9753acde04633 /apps/codecs/libm4a/m4a.c | |
parent | a04cef7adee7e79cdafcbf8efb5ee9110a8d4ab1 (diff) |
Add resume support to AAC files.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@10720 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'apps/codecs/libm4a/m4a.c')
-rw-r--r-- | apps/codecs/libm4a/m4a.c | 61 |
1 files changed, 61 insertions, 0 deletions
diff --git a/apps/codecs/libm4a/m4a.c b/apps/codecs/libm4a/m4a.c index c90fc2b85a..f914f4e4d1 100644 --- a/apps/codecs/libm4a/m4a.c +++ b/apps/codecs/libm4a/m4a.c @@ -230,3 +230,64 @@ unsigned int alac_seek (demux_res_t* demux_res, return 0; } } + +/* Seek to file_loc (or close to it). Return 1 on success (and + modify samplesdone and currentblock), 0 if failed + + Seeking uses the following array: + + the sample_byte_size array contains the length in bytes of + each block ("sample" in Applespeak). + + So we just find the last block before (or at) the requested position. + + Each ALAC block seems to be independent of all the others. + */ + +unsigned int alac_seek_raw (demux_res_t* demux_res, + stream_t* stream, + unsigned int file_loc, + uint32_t* samplesdone, int* currentblock) +{ + unsigned int i; + unsigned int j; + unsigned int newblock; + unsigned int newsample; + unsigned int newpos; + + /* First check we have the appropriate metadata - we should always + have it. */ + if ((demux_res->num_time_to_samples==0) || + (demux_res->num_sample_byte_sizes==0)) { return 0; } + + /* Find the destination block from the sample_byte_size array. */ + newpos=demux_res->mdat_offset; + for (i=0;(i<demux_res->num_sample_byte_sizes) && + (newpos+demux_res->sample_byte_size[i]<=file_loc);i++) { + newpos+=demux_res->sample_byte_size[i]; + } + + newblock=i; + newsample=0; + + /* Get the sample offset of the block */ + for (i=0,j=0;(i<demux_res->num_time_to_samples) && (j<newblock); + i++,j+=demux_res->time_to_sample[i].sample_count) { + if (newblock-j < demux_res->time_to_sample[i].sample_count) { + newsample+=(newblock-j)*demux_res->time_to_sample[i].sample_duration; + break; + } else { + newsample+=(demux_res->time_to_sample[i].sample_duration + * demux_res->time_to_sample[i].sample_count); + } + } + + /* We know the new file position, so let's try to seek to it */ + if (stream->ci->seek_buffer(newpos)) { + *samplesdone=newsample; + *currentblock=newblock; + return 1; + } else { + return 0; + } +} |