summaryrefslogtreecommitdiff
path: root/apps/codecs/libm4a/m4a.c
diff options
context:
space:
mode:
Diffstat (limited to 'apps/codecs/libm4a/m4a.c')
-rw-r--r--apps/codecs/libm4a/m4a.c61
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,
230 return 0; 230 return 0;
231 } 231 }
232} 232}
233
234/* Seek to file_loc (or close to it). Return 1 on success (and
235 modify samplesdone and currentblock), 0 if failed
236
237 Seeking uses the following array:
238
239 the sample_byte_size array contains the length in bytes of
240 each block ("sample" in Applespeak).
241
242 So we just find the last block before (or at) the requested position.
243
244 Each ALAC block seems to be independent of all the others.
245 */
246
247unsigned int alac_seek_raw (demux_res_t* demux_res,
248 stream_t* stream,
249 unsigned int file_loc,
250 uint32_t* samplesdone, int* currentblock)
251{
252 unsigned int i;
253 unsigned int j;
254 unsigned int newblock;
255 unsigned int newsample;
256 unsigned int newpos;
257
258 /* First check we have the appropriate metadata - we should always
259 have it. */
260 if ((demux_res->num_time_to_samples==0) ||
261 (demux_res->num_sample_byte_sizes==0)) { return 0; }
262
263 /* Find the destination block from the sample_byte_size array. */
264 newpos=demux_res->mdat_offset;
265 for (i=0;(i<demux_res->num_sample_byte_sizes) &&
266 (newpos+demux_res->sample_byte_size[i]<=file_loc);i++) {
267 newpos+=demux_res->sample_byte_size[i];
268 }
269
270 newblock=i;
271 newsample=0;
272
273 /* Get the sample offset of the block */
274 for (i=0,j=0;(i<demux_res->num_time_to_samples) && (j<newblock);
275 i++,j+=demux_res->time_to_sample[i].sample_count) {
276 if (newblock-j < demux_res->time_to_sample[i].sample_count) {
277 newsample+=(newblock-j)*demux_res->time_to_sample[i].sample_duration;
278 break;
279 } else {
280 newsample+=(demux_res->time_to_sample[i].sample_duration
281 * demux_res->time_to_sample[i].sample_count);
282 }
283 }
284
285 /* We know the new file position, so let's try to seek to it */
286 if (stream->ci->seek_buffer(newpos)) {
287 *samplesdone=newsample;
288 *currentblock=newblock;
289 return 1;
290 } else {
291 return 0;
292 }
293}