diff options
author | Mohamed Tarek <mt@rockbox.org> | 2009-07-13 10:06:19 +0000 |
---|---|---|
committer | Mohamed Tarek <mt@rockbox.org> | 2009-07-13 10:06:19 +0000 |
commit | b5b9cb031d0b1b3c802fde2f33e27ecf7d166778 (patch) | |
tree | 069111df1ac53ac7a46efaacefe94a7750265373 /apps | |
parent | f35db90efac68d17e413dae3e90c13f432ae0740 (diff) | |
download | rockbox-b5b9cb031d0b1b3c802fde2f33e27ecf7d166778.tar.gz rockbox-b5b9cb031d0b1b3c802fde2f33e27ecf7d166778.zip |
Modified the code for seeking to speed it up a bit. Instead of searching
the file for the required timestamp, we seek directly to a calcualted
position. If we go to a point beyond the desired seek_time, we seek back
in blocks (normally one or two blocks to the back) to get the required
block.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@21836 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'apps')
-rw-r--r-- | apps/codecs/cook.c | 70 |
1 files changed, 34 insertions, 36 deletions
diff --git a/apps/codecs/cook.c b/apps/codecs/cook.c index 5efb797fdd..fe818be905 100644 --- a/apps/codecs/cook.c +++ b/apps/codecs/cook.c | |||
@@ -41,12 +41,12 @@ static void init_rm(RMContext *rmctx) | |||
41 | enum codec_status codec_main(void) | 41 | enum codec_status codec_main(void) |
42 | { | 42 | { |
43 | static size_t buff_size; | 43 | static size_t buff_size; |
44 | int datasize, res, consumed, i, j, time_offset; | 44 | int datasize, res, consumed, i, time_offset; |
45 | uint8_t *bit_buffer; | 45 | uint8_t *bit_buffer; |
46 | int16_t outbuf[2048] __attribute__((aligned(32))); | 46 | int16_t outbuf[2048] __attribute__((aligned(32))); |
47 | uint16_t fs,sps,h; | 47 | uint16_t fs,sps,h; |
48 | uint32_t packet_count; | 48 | uint32_t packet_count; |
49 | int scrambling_unit_size, flag_seek_block = 0; | 49 | int scrambling_unit_size, num_units; |
50 | 50 | ||
51 | next_track: | 51 | next_track: |
52 | if (codec_init()) { | 52 | if (codec_init()) { |
@@ -102,51 +102,49 @@ seek_start : | |||
102 | if (ci->stop_codec || ci->new_track) | 102 | if (ci->stop_codec || ci->new_track) |
103 | goto done; | 103 | goto done; |
104 | 104 | ||
105 | if (ci->seek_time) { | 105 | if (ci->seek_time) { |
106 | ci->set_elapsed(ci->seek_time); | ||
107 | |||
108 | /* Do not allow seeking beyond the file's length */ | ||
109 | if ((unsigned) ci->seek_time > ci->id3->length) { | ||
110 | ci->seek_complete(); | ||
111 | goto done; | ||
112 | } | ||
113 | |||
106 | ci->seek_buffer(rmctx.data_offset + DATA_HEADER_SIZE); | 114 | ci->seek_buffer(rmctx.data_offset + DATA_HEADER_SIZE); |
107 | packet_count = rmctx.nb_packets; | 115 | packet_count = rmctx.nb_packets; |
108 | rmctx.audio_pkt_cnt = 0; | 116 | rmctx.audio_pkt_cnt = 0; |
109 | rmctx.frame_number = 0; | 117 | rmctx.frame_number = 0; |
118 | |||
119 | /* Seek to the start of the track */ | ||
110 | if (ci->seek_time == 1) { | 120 | if (ci->seek_time == 1) { |
111 | ci->set_elapsed(0); | 121 | ci->set_elapsed(0); |
112 | ci->seek_complete(); | 122 | ci->seek_complete(); |
113 | goto seek_start; | 123 | goto seek_start; |
114 | } | 124 | } |
115 | j = 0; | 125 | num_units = ((ci->seek_time)/(sps*1000*8/rmctx.bit_rate))/(h*(fs/sps)); |
116 | while(1) { | 126 | ci->seek_buffer(rmctx.data_offset + DATA_HEADER_SIZE + consumed * num_units); |
127 | bit_buffer = (uint8_t *) ci->request_buffer(&buff_size, scrambling_unit_size); | ||
128 | consumed = rm_get_packet(&bit_buffer, &rmctx, &pkt); | ||
129 | if(consumed < 0) { | ||
130 | DEBUGF("rm_get_packet failed\n"); | ||
131 | return CODEC_ERROR; | ||
132 | } | ||
133 | packet_count = rmctx.nb_packets - rmctx.audio_pkt_cnt * num_units; | ||
134 | rmctx.frame_number = ((ci->seek_time)/(sps*1000*8/rmctx.bit_rate)); | ||
135 | while(rmctx.audiotimestamp > (unsigned) ci->seek_time) { | ||
117 | rmctx.audio_pkt_cnt = 0; | 136 | rmctx.audio_pkt_cnt = 0; |
118 | bit_buffer = (uint8_t *) ci->request_buffer(&buff_size, scrambling_unit_size); | 137 | ci->seek_buffer(rmctx.data_offset + DATA_HEADER_SIZE + consumed * (num_units-1)); |
119 | consumed = rm_get_packet(&bit_buffer, &rmctx, &pkt); | 138 | bit_buffer = (uint8_t *) ci->request_buffer(&buff_size, scrambling_unit_size); |
120 | if(consumed < 0) { | 139 | consumed = rm_get_packet(&bit_buffer, &rmctx, &pkt); |
121 | DEBUGF("rm_get_packet failed\n"); | ||
122 | return CODEC_ERROR; | ||
123 | } | ||
124 | if(rmctx.audiotimestamp < (unsigned) ci->seek_time) { | ||
125 | ci->advance_buffer(consumed); | ||
126 | packet_count -= rmctx.audio_pkt_cnt; | ||
127 | rmctx.frame_number += h*(fs/sps); | ||
128 | j+= consumed; | ||
129 | } | ||
130 | if(rmctx.audiotimestamp > (unsigned) ci->seek_time) { | ||
131 | flag_seek_block = 1; | ||
132 | rmctx.audio_pkt_cnt = 0; | ||
133 | break; | ||
134 | } | ||
135 | } | ||
136 | |||
137 | if(flag_seek_block) { | ||
138 | ci->seek_buffer(rmctx.data_offset + DATA_HEADER_SIZE + j - consumed); | ||
139 | bit_buffer = (uint8_t *) ci->request_buffer(&buff_size, scrambling_unit_size); | ||
140 | consumed = rm_get_packet(&bit_buffer, &rmctx, &pkt); | ||
141 | packet_count += rmctx.audio_pkt_cnt; | 140 | packet_count += rmctx.audio_pkt_cnt; |
142 | rmctx.frame_number -= h*(fs/sps); | 141 | num_units--; |
143 | time_offset = ci->seek_time - rmctx.audiotimestamp; | ||
144 | i = (time_offset/((sps * 8 * 1000)/rmctx.bit_rate)); | ||
145 | flag_seek_block = 0; | ||
146 | ci->set_elapsed(rmctx.audiotimestamp+(1000*8*sps/rmctx.bit_rate)*i); | ||
147 | ci->seek_complete(); | ||
148 | } | 142 | } |
149 | } | 143 | time_offset = ci->seek_time - rmctx.audiotimestamp; |
144 | i = (time_offset/((sps * 8 * 1000)/rmctx.bit_rate)); | ||
145 | ci->set_elapsed(rmctx.audiotimestamp+(1000*8*sps/rmctx.bit_rate)*i); | ||
146 | ci->seek_complete(); | ||
147 | } | ||
150 | res = cook_decode_frame(&rmctx,&q, outbuf, &datasize, pkt.frames[i], rmctx.block_align); | 148 | res = cook_decode_frame(&rmctx,&q, outbuf, &datasize, pkt.frames[i], rmctx.block_align); |
151 | rmctx.frame_number++; | 149 | rmctx.frame_number++; |
152 | 150 | ||