Index: apps/codecs/aac.c =================================================================== --- apps/codecs/aac.c (revision 29205) +++ apps/codecs/aac.c (working copy) @@ -221,7 +221,7 @@ * that an good question (but files with gaps do exist, so who * knows?), so we don't support that - for now, at least. */ - file_offset = get_sample_offset(&demux_res, i); + file_offset = get_sample_offset(&demux_res, i, false); if (file_offset > ci->curpos) { Index: apps/codecs/libm4a/m4a.c =================================================================== --- apps/codecs/libm4a/m4a.c (revision 29205) +++ apps/codecs/libm4a/m4a.c (working copy) @@ -157,7 +157,7 @@ return 1; } -unsigned int get_sample_offset(demux_res_t *demux_res, uint32_t sample) +unsigned int get_sample_offset(demux_res_t *demux_res, uint32_t sample, bool show) { uint32_t chunk = 1; uint32_t range_samples = 0; @@ -178,6 +178,8 @@ { return 0; } + + if (show) printf("== down_fac %d ==\n", demux_res->table_downfac); /* Locate the chunk containing the sample */ @@ -208,22 +210,31 @@ { chunk = 1; } + if (show) printf("-- prev %d %d %d\n", prev_chunk, chunk, prev_chunk_samples); /* Get sample of the first sample in the chunk */ - chunk_sample = total_samples + (chunk - prev_chunk) * prev_chunk_samples; + if (show) printf("-- chunk_sample %d %d\n", chunk_sample, chunk); + /* Get offset in file */ - - if (chunk > demux_res->num_chunk_offsets) + int idx = (chunk >= demux_res->table_downfac) ? chunk / demux_res->table_downfac : 1; + if (idx > demux_res->num_chunk_offsets) { - file_offset = demux_res->chunk_offset[demux_res->num_chunk_offsets - 1]; + idx = demux_res->num_chunk_offsets - 1; + file_offset = demux_res->chunk_offset[idx]; } else { - file_offset = demux_res->chunk_offset[chunk - 1]; + idx = (chunk-1) / demux_res->table_downfac; + file_offset = demux_res->chunk_offset[idx]; } + chunk_sample += (idx*demux_res->table_downfac + 1 - chunk) * prev_chunk_samples; + if (show) printf("-- diff %d %d %d\n", idx, idx*demux_res->table_downfac + 1, chunk); + chunk = idx*demux_res->table_downfac + 1; + if (show) printf("-- chunk %d %d\n", chunk, file_offset); + if (chunk_sample > sample) { return 0; @@ -233,12 +244,12 @@ { file_offset += demux_res->sample_byte_size[i]; } - + if (file_offset > demux_res->mdat_offset + demux_res->mdat_len) { return 0; } - + return file_offset; } @@ -280,7 +291,7 @@ { return 0; } - + /* Find the destination block from time_to_sample array */ time_to_sample_t *tab = demux_res->time_to_sample; while (i < demux_res->num_time_to_samples) @@ -301,7 +312,8 @@ } /* We know the new block, now calculate the file position. */ - new_pos = get_sample_offset(demux_res, new_sample); + new_pos = get_sample_offset(demux_res, new_sample, true); + printf("%d %d\n", new_pos, new_sample); /* We know the new file position, so let's try to seek to it */ if (stream->ci->seek_buffer(new_pos)) @@ -363,6 +375,9 @@ ++chunk; } new_pos = demux_res->chunk_offset[chunk > 0 ? chunk - 1 : 0]; + chunk *= demux_res->table_downfac; + + printf("seek_raw %d %d %d\n", file_loc, new_pos, chunk); /* Get the first sample of the chunk. */ i = 1; Index: apps/codecs/libm4a/demux.c =================================================================== --- apps/codecs/libm4a/demux.c (revision 29205) +++ apps/codecs/libm4a/demux.c (working copy) @@ -314,6 +314,7 @@ unsigned int i; uint32_t numentries; size_t size_remaining = chunk_len - 8; + printf("stts\n"); /* version */ stream_read_uint8(qtmovie->stream); @@ -357,6 +358,7 @@ unsigned int i; uint32_t numentries; size_t size_remaining = chunk_len - 8; + printf("stsz\n"); /* version */ stream_read_uint8(qtmovie->stream); @@ -417,6 +419,7 @@ unsigned int i; uint32_t numentries; size_t size_remaining = chunk_len - 8; + printf("stsc\n"); /* version + flags */ stream_read_uint32(qtmovie->stream); @@ -459,6 +462,7 @@ unsigned int i; uint32_t numentries; size_t size_remaining = chunk_len - 8; + printf("stco\n"); /* version + flags */ stream_read_uint32(qtmovie->stream); @@ -466,6 +470,21 @@ numentries = stream_read_uint32(qtmovie->stream); size_remaining -= 4; +#define DOWN_FAC 8 + uint32_t downfac; + if (numentries > DOWN_FAC) + { + printf("Downsized chunk_offset %d -> %d entries (saved %d KB)\n", + numentries, + numentries/DOWN_FAC, + (numentries - numentries/DOWN_FAC)*4/1024); + numentries /= DOWN_FAC; + qtmovie->res->table_downfac = downfac = DOWN_FAC; + } + else + { + qtmovie->res->table_downfac = downfac = 1; + } qtmovie->res->num_chunk_offsets = numentries; qtmovie->res->chunk_offset = malloc(numentries * @@ -481,12 +500,16 @@ { qtmovie->res->chunk_offset[i] = stream_read_uint32(qtmovie->stream); size_remaining -= 4; + /* Skip data if we reduce the table size (downfac > 1). */ + stream_skip(qtmovie->stream, (4 * (downfac-1))); + size_remaining -= (4 * (downfac-1)); } if (size_remaining) { - DEBUGF("ehm, size remianing?\n"); + printf("ehm, size remaining? %d\n", size_remaining); stream_skip(qtmovie->stream, size_remaining); + size_remaining = 0; } return true; Index: apps/codecs/libm4a/m4a.h =================================================================== --- apps/codecs/libm4a/m4a.h (revision 29205) +++ apps/codecs/libm4a/m4a.h (working copy) @@ -64,6 +64,8 @@ uint32_t sound_sample_rate; fourcc_t format; void *buf; + + uint32_t table_downfac; sample_to_chunk_t *sample_to_chunk; uint32_t num_sample_to_chunks; @@ -126,7 +128,7 @@ void stream_create(stream_t *stream,struct codec_api* ci); int get_sample_info(demux_res_t *demux_res, uint32_t sample, uint32_t *sample_duration, uint32_t *sample_byte_size); -unsigned int get_sample_offset(demux_res_t *demux_res, uint32_t sample); +unsigned int get_sample_offset(demux_res_t *demux_res, uint32_t sample, bool show); unsigned int alac_seek (demux_res_t* demux_res, stream_t* stream, uint32_t sound_sample_loc, uint32_t* sound_samples_done, int* current_sample);