diff options
author | Solomon Peachy <pizza@shaftnet.org> | 2018-12-15 19:27:20 -0500 |
---|---|---|
committer | Solomon Peachy <pizza@shaftnet.org> | 2018-12-22 19:54:40 -0500 |
commit | b51995942e412358cc0e47a0d5971290c469ccca (patch) | |
tree | 29ca7a525dca73e36514b63b53ee8c412615b6cd /lib | |
parent | d258edbb4fef8a187ad4ef8c3d2c072f9ccad83a (diff) | |
download | rockbox-b51995942e412358cc0e47a0d5971290c469ccca.tar.gz rockbox-b51995942e412358cc0e47a0d5971290c469ccca.zip |
Improved seeking in a52 codec
(Patch by Igor Poretsky)
Change-Id: I0cdc2021b44f6cd6e76def190d9f04733b922454
Diffstat (limited to 'lib')
-rw-r--r-- | lib/rbcodec/codecs/a52.c | 37 |
1 files changed, 28 insertions, 9 deletions
diff --git a/lib/rbcodec/codecs/a52.c b/lib/rbcodec/codecs/a52.c index 3d7e56df03..5094913259 100644 --- a/lib/rbcodec/codecs/a52.c +++ b/lib/rbcodec/codecs/a52.c | |||
@@ -36,6 +36,14 @@ static unsigned long frequency; | |||
36 | 36 | ||
37 | /* used outside liba52 */ | 37 | /* used outside liba52 */ |
38 | static uint8_t buf[3840] IBSS_ATTR; | 38 | static uint8_t buf[3840] IBSS_ATTR; |
39 | static uint8_t *bufptr = buf; | ||
40 | static uint8_t *bufpos = buf + 7; | ||
41 | |||
42 | static void a52_decoder_reset(void) | ||
43 | { | ||
44 | bufptr = buf; | ||
45 | bufpos = buf + 7; | ||
46 | } | ||
39 | 47 | ||
40 | static inline void output_audio(sample_t *samples) | 48 | static inline void output_audio(sample_t *samples) |
41 | { | 49 | { |
@@ -43,10 +51,8 @@ static inline void output_audio(sample_t *samples) | |||
43 | ci->pcmbuf_insert(&samples[0], &samples[256], 256); | 51 | ci->pcmbuf_insert(&samples[0], &samples[256], 256); |
44 | } | 52 | } |
45 | 53 | ||
46 | static void a52_decode_data(uint8_t *start, uint8_t *end) | 54 | static size_t a52_decode_data(uint8_t *start, uint8_t *end) |
47 | { | 55 | { |
48 | static uint8_t *bufptr = buf; | ||
49 | static uint8_t *bufpos = buf + 7; | ||
50 | /* | 56 | /* |
51 | * sample_rate and flags are static because this routine could | 57 | * sample_rate and flags are static because this routine could |
52 | * exit between the a52_syncinfo() and the ao_setup(), and we want | 58 | * exit between the a52_syncinfo() and the ao_setup(), and we want |
@@ -56,6 +62,7 @@ static void a52_decode_data(uint8_t *start, uint8_t *end) | |||
56 | static int flags; | 62 | static int flags; |
57 | int bit_rate; | 63 | int bit_rate; |
58 | int len; | 64 | int len; |
65 | size_t consumed = 0; | ||
59 | 66 | ||
60 | while (1) { | 67 | while (1) { |
61 | len = end - start; | 68 | len = end - start; |
@@ -66,6 +73,7 @@ static void a52_decode_data(uint8_t *start, uint8_t *end) | |||
66 | memcpy(bufptr, start, len); | 73 | memcpy(bufptr, start, len); |
67 | bufptr += len; | 74 | bufptr += len; |
68 | start += len; | 75 | start += len; |
76 | consumed += len; | ||
69 | if (bufptr == bufpos) { | 77 | if (bufptr == bufpos) { |
70 | if (bufpos == buf + 7) { | 78 | if (bufpos == buf + 7) { |
71 | int length; | 79 | int length; |
@@ -105,7 +113,7 @@ static void a52_decode_data(uint8_t *start, uint8_t *end) | |||
105 | ci->set_elapsed(samplesdone/(frequency/1000)); | 113 | ci->set_elapsed(samplesdone/(frequency/1000)); |
106 | bufptr = buf; | 114 | bufptr = buf; |
107 | bufpos = buf + 7; | 115 | bufpos = buf + 7; |
108 | continue; | 116 | break; |
109 | error: | 117 | error: |
110 | //logf("Error decoding A52 stream\n"); | 118 | //logf("Error decoding A52 stream\n"); |
111 | bufptr = buf; | 119 | bufptr = buf; |
@@ -113,6 +121,7 @@ static void a52_decode_data(uint8_t *start, uint8_t *end) | |||
113 | } | 121 | } |
114 | } | 122 | } |
115 | } | 123 | } |
124 | return consumed; | ||
116 | } | 125 | } |
117 | 126 | ||
118 | /* this is the codec entry point */ | 127 | /* this is the codec entry point */ |
@@ -134,7 +143,7 @@ enum codec_status codec_main(enum codec_entry_call_reason reason) | |||
134 | /* this is called for each file to process */ | 143 | /* this is called for each file to process */ |
135 | enum codec_status codec_run(void) | 144 | enum codec_status codec_run(void) |
136 | { | 145 | { |
137 | size_t n; | 146 | size_t n, consumed = 0, rest = 0; |
138 | unsigned char *filebuf; | 147 | unsigned char *filebuf; |
139 | int sample_loc; | 148 | int sample_loc; |
140 | intptr_t param; | 149 | intptr_t param; |
@@ -145,7 +154,7 @@ enum codec_status codec_run(void) | |||
145 | ci->configure(DSP_SET_FREQUENCY, ci->id3->frequency); | 154 | ci->configure(DSP_SET_FREQUENCY, ci->id3->frequency); |
146 | codec_set_replaygain(ci->id3); | 155 | codec_set_replaygain(ci->id3); |
147 | 156 | ||
148 | /* Intialise the A52 decoder and check for success */ | 157 | /* Initialise the A52 decoder and check for success */ |
149 | state = a52_init(0); | 158 | state = a52_init(0); |
150 | 159 | ||
151 | samplesdone = 0; | 160 | samplesdone = 0; |
@@ -187,15 +196,25 @@ enum codec_status codec_run(void) | |||
187 | ci->set_elapsed(samplesdone/(ci->id3->frequency/1000)); | 196 | ci->set_elapsed(samplesdone/(ci->id3->frequency/1000)); |
188 | } | 197 | } |
189 | ci->seek_complete(); | 198 | ci->seek_complete(); |
199 | a52_decoder_reset(); | ||
190 | } | 200 | } |
191 | 201 | ||
192 | filebuf = ci->request_buffer(&n, BUFFER_SIZE); | 202 | filebuf = ci->request_buffer(&n, BUFFER_SIZE); |
193 | 203 | ||
194 | if (n == 0) /* End of Stream */ | 204 | if (n == 0) /* End of Stream */ |
205 | { | ||
206 | filebuf += consumed; | ||
207 | for (n = ci->curpos + consumed; rest; rest -= consumed, n += consumed) | ||
208 | { | ||
209 | ci->set_offset(n); | ||
210 | consumed = a52_decode_data(filebuf, filebuf + rest); | ||
211 | } | ||
195 | break; | 212 | break; |
196 | 213 | } | |
197 | a52_decode_data(filebuf, filebuf + n); | 214 | |
198 | ci->advance_buffer(n); | 215 | consumed = a52_decode_data(filebuf, filebuf + n); |
216 | rest = n - consumed; | ||
217 | ci->advance_buffer(consumed); | ||
199 | } | 218 | } |
200 | 219 | ||
201 | return CODEC_OK; | 220 | return CODEC_OK; |