diff options
author | Michael Sevakis <jethead71@rockbox.org> | 2011-04-27 03:08:23 +0000 |
---|---|---|
committer | Michael Sevakis <jethead71@rockbox.org> | 2011-04-27 03:08:23 +0000 |
commit | c537d5958e8b421ac4f9bef6c8b9e7425a6cf167 (patch) | |
tree | 7ed36518fb6524da7bbd913ba7619b85b5d15d23 /apps/codecs/cook.c | |
parent | dcf0f8de4a37ff1d2ea510aef75fa67977a8bdcc (diff) | |
download | rockbox-c537d5958e8b421ac4f9bef6c8b9e7425a6cf167.tar.gz rockbox-c537d5958e8b421ac4f9bef6c8b9e7425a6cf167.zip |
Commit FS#12069 - Playback rework - first stages. Gives as thorough as possible a treatment of codec management, track change and metadata logic as possible while maintaining fairly narrow focus and not rewriting everything all at once. Please see the rockbox-dev mail archive on 2011-04-25 (Playback engine rework) for a more thorough manifest of what was addressed. Plugins and codecs become incompatible.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@29785 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'apps/codecs/cook.c')
-rw-r--r-- | apps/codecs/cook.c | 63 |
1 files changed, 33 insertions, 30 deletions
diff --git a/apps/codecs/cook.c b/apps/codecs/cook.c index 015618986c..a6b4a1153e 100644 --- a/apps/codecs/cook.c +++ b/apps/codecs/cook.c | |||
@@ -38,9 +38,9 @@ static void init_rm(RMContext *rmctx) | |||
38 | memcpy(rmctx, (void*)(( (intptr_t)ci->id3->id3v2buf + 3 ) &~ 3), sizeof(RMContext)); | 38 | memcpy(rmctx, (void*)(( (intptr_t)ci->id3->id3v2buf + 3 ) &~ 3), sizeof(RMContext)); |
39 | } | 39 | } |
40 | 40 | ||
41 | /* this is the codec entry point */ | 41 | /* this is called for each file to process */ |
42 | enum codec_status codec_main(void) | 42 | enum codec_status codec_run(void) |
43 | { | 43 | { |
44 | static size_t buff_size; | 44 | static size_t buff_size; |
45 | int datasize, res, consumed, i, time_offset; | 45 | int datasize, res, consumed, i, time_offset; |
46 | uint8_t *bit_buffer; | 46 | uint8_t *bit_buffer; |
@@ -48,16 +48,14 @@ enum codec_status codec_main(void) | |||
48 | uint32_t packet_count; | 48 | uint32_t packet_count; |
49 | int scrambling_unit_size, num_units; | 49 | int scrambling_unit_size, num_units; |
50 | size_t resume_offset; | 50 | size_t resume_offset; |
51 | intptr_t param = 0; | ||
52 | enum codec_command_action action = CODEC_ACTION_NULL; | ||
51 | 53 | ||
52 | next_track: | ||
53 | if (codec_init()) { | 54 | if (codec_init()) { |
54 | DEBUGF("codec init failed\n"); | 55 | DEBUGF("codec init failed\n"); |
55 | return CODEC_ERROR; | 56 | return CODEC_ERROR; |
56 | } | 57 | } |
57 | 58 | ||
58 | if (codec_wait_taginfo() != 0) | ||
59 | goto done; | ||
60 | |||
61 | resume_offset = ci->id3->offset; | 59 | resume_offset = ci->id3->offset; |
62 | 60 | ||
63 | codec_set_replaygain(ci->id3); | 61 | codec_set_replaygain(ci->id3); |
@@ -65,6 +63,8 @@ next_track: | |||
65 | ci->memset(&pkt,0,sizeof(RMPacket)); | 63 | ci->memset(&pkt,0,sizeof(RMPacket)); |
66 | ci->memset(&q,0,sizeof(COOKContext)); | 64 | ci->memset(&q,0,sizeof(COOKContext)); |
67 | 65 | ||
66 | ci->seek_buffer(0); | ||
67 | |||
68 | init_rm(&rmctx); | 68 | init_rm(&rmctx); |
69 | 69 | ||
70 | ci->configure(DSP_SET_FREQUENCY, ci->id3->frequency); | 70 | ci->configure(DSP_SET_FREQUENCY, ci->id3->frequency); |
@@ -87,20 +87,21 @@ next_track: | |||
87 | DEBUGF("failed to initialize cook decoder\n"); | 87 | DEBUGF("failed to initialize cook decoder\n"); |
88 | return CODEC_ERROR; | 88 | return CODEC_ERROR; |
89 | } | 89 | } |
90 | 90 | ||
91 | /* check for a mid-track resume and force a seek time accordingly */ | 91 | /* check for a mid-track resume and force a seek time accordingly */ |
92 | if(resume_offset > rmctx.data_offset + DATA_HEADER_SIZE) { | 92 | if(resume_offset > rmctx.data_offset + DATA_HEADER_SIZE) { |
93 | resume_offset -= rmctx.data_offset + DATA_HEADER_SIZE; | 93 | resume_offset -= rmctx.data_offset + DATA_HEADER_SIZE; |
94 | num_units = (int)resume_offset / scrambling_unit_size; | 94 | num_units = (int)resume_offset / scrambling_unit_size; |
95 | /* put number of subpackets to skip in resume_offset */ | 95 | /* put number of subpackets to skip in resume_offset */ |
96 | resume_offset /= (sps + PACKET_HEADER_SIZE); | 96 | resume_offset /= (sps + PACKET_HEADER_SIZE); |
97 | ci->seek_time = (int)resume_offset * ((sps * 8 * 1000)/rmctx.bit_rate); | 97 | param = (int)resume_offset * ((sps * 8 * 1000)/rmctx.bit_rate); |
98 | action = CODEC_ACTION_SEEK_TIME; | ||
98 | } | 99 | } |
99 | 100 | ||
100 | ci->set_elapsed(0); | 101 | ci->set_elapsed(0); |
101 | ci->advance_buffer(rmctx.data_offset + DATA_HEADER_SIZE); | 102 | ci->advance_buffer(rmctx.data_offset + DATA_HEADER_SIZE); |
102 | 103 | ||
103 | /* The main decoder loop */ | 104 | /* The main decoder loop */ |
104 | seek_start : | 105 | seek_start : |
105 | while(packet_count) | 106 | while(packet_count) |
106 | { | 107 | { |
@@ -112,18 +113,19 @@ seek_start : | |||
112 | } | 113 | } |
113 | 114 | ||
114 | for(i = 0; i < rmctx.audio_pkt_cnt*(fs/sps) ; i++) | 115 | for(i = 0; i < rmctx.audio_pkt_cnt*(fs/sps) ; i++) |
115 | { | 116 | { |
116 | ci->yield(); | 117 | if (action == CODEC_ACTION_NULL) |
117 | if (ci->stop_codec || ci->new_track) | 118 | action = ci->get_command(¶m); |
118 | goto done; | ||
119 | 119 | ||
120 | if (ci->seek_time) { | 120 | if (action == CODEC_ACTION_HALT) |
121 | ci->set_elapsed(ci->seek_time); | 121 | return CODEC_OK; |
122 | 122 | ||
123 | if (action == CODEC_ACTION_SEEK_TIME) { | ||
123 | /* Do not allow seeking beyond the file's length */ | 124 | /* Do not allow seeking beyond the file's length */ |
124 | if ((unsigned) ci->seek_time > ci->id3->length) { | 125 | if ((unsigned) param > ci->id3->length) { |
126 | ci->set_elapsed(ci->id3->length); | ||
125 | ci->seek_complete(); | 127 | ci->seek_complete(); |
126 | goto done; | 128 | return CODEC_OK; |
127 | } | 129 | } |
128 | 130 | ||
129 | ci->seek_buffer(rmctx.data_offset + DATA_HEADER_SIZE); | 131 | ci->seek_buffer(rmctx.data_offset + DATA_HEADER_SIZE); |
@@ -132,22 +134,24 @@ seek_start : | |||
132 | rmctx.frame_number = 0; | 134 | rmctx.frame_number = 0; |
133 | 135 | ||
134 | /* Seek to the start of the track */ | 136 | /* Seek to the start of the track */ |
135 | if (ci->seek_time == 1) { | 137 | if (param == 0) { |
136 | ci->set_elapsed(0); | 138 | ci->set_elapsed(0); |
137 | ci->seek_complete(); | 139 | ci->seek_complete(); |
140 | action = CODEC_ACTION_NULL; | ||
138 | goto seek_start; | 141 | goto seek_start; |
139 | } | 142 | } |
140 | num_units = ((ci->seek_time)/(sps*1000*8/rmctx.bit_rate))/(h*(fs/sps)); | 143 | num_units = (param/(sps*1000*8/rmctx.bit_rate))/(h*(fs/sps)); |
141 | ci->seek_buffer(rmctx.data_offset + DATA_HEADER_SIZE + consumed * num_units); | 144 | ci->seek_buffer(rmctx.data_offset + DATA_HEADER_SIZE + consumed * num_units); |
142 | bit_buffer = (uint8_t *) ci->request_buffer(&buff_size, scrambling_unit_size); | 145 | bit_buffer = (uint8_t *) ci->request_buffer(&buff_size, scrambling_unit_size); |
143 | consumed = rm_get_packet(&bit_buffer, &rmctx, &pkt); | 146 | consumed = rm_get_packet(&bit_buffer, &rmctx, &pkt); |
144 | if(consumed < 0) { | 147 | if(consumed < 0) { |
145 | DEBUGF("rm_get_packet failed\n"); | 148 | DEBUGF("rm_get_packet failed\n"); |
146 | return CODEC_ERROR; | 149 | ci->seek_complete(); |
150 | return CODEC_ERROR; | ||
147 | } | 151 | } |
148 | packet_count = rmctx.nb_packets - rmctx.audio_pkt_cnt * num_units; | 152 | packet_count = rmctx.nb_packets - rmctx.audio_pkt_cnt * num_units; |
149 | rmctx.frame_number = ((ci->seek_time)/(sps*1000*8/rmctx.bit_rate)); | 153 | rmctx.frame_number = (param/(sps*1000*8/rmctx.bit_rate)); |
150 | while(rmctx.audiotimestamp > (unsigned) ci->seek_time) { | 154 | while(rmctx.audiotimestamp > (unsigned) param) { |
151 | rmctx.audio_pkt_cnt = 0; | 155 | rmctx.audio_pkt_cnt = 0; |
152 | ci->seek_buffer(rmctx.data_offset + DATA_HEADER_SIZE + consumed * (num_units-1)); | 156 | ci->seek_buffer(rmctx.data_offset + DATA_HEADER_SIZE + consumed * (num_units-1)); |
153 | bit_buffer = (uint8_t *) ci->request_buffer(&buff_size, scrambling_unit_size); | 157 | bit_buffer = (uint8_t *) ci->request_buffer(&buff_size, scrambling_unit_size); |
@@ -155,11 +159,14 @@ seek_start : | |||
155 | packet_count += rmctx.audio_pkt_cnt; | 159 | packet_count += rmctx.audio_pkt_cnt; |
156 | num_units--; | 160 | num_units--; |
157 | } | 161 | } |
158 | time_offset = ci->seek_time - rmctx.audiotimestamp; | 162 | time_offset = param - rmctx.audiotimestamp; |
159 | i = (time_offset/((sps * 8 * 1000)/rmctx.bit_rate)); | 163 | i = (time_offset/((sps * 8 * 1000)/rmctx.bit_rate)); |
160 | ci->set_elapsed(rmctx.audiotimestamp+(1000*8*sps/rmctx.bit_rate)*i); | 164 | ci->set_elapsed(rmctx.audiotimestamp+(1000*8*sps/rmctx.bit_rate)*i); |
161 | ci->seek_complete(); | 165 | ci->seek_complete(); |
162 | } | 166 | } |
167 | |||
168 | action = CODEC_ACTION_NULL; | ||
169 | |||
163 | res = cook_decode_frame(&rmctx,&q, rm_outbuf, &datasize, pkt.frames[i], rmctx.block_align); | 170 | res = cook_decode_frame(&rmctx,&q, rm_outbuf, &datasize, pkt.frames[i], rmctx.block_align); |
164 | rmctx.frame_number++; | 171 | rmctx.frame_number++; |
165 | 172 | ||
@@ -181,9 +188,5 @@ seek_start : | |||
181 | ci->advance_buffer(consumed); | 188 | ci->advance_buffer(consumed); |
182 | } | 189 | } |
183 | 190 | ||
184 | done : | 191 | return CODEC_OK; |
185 | if (ci->request_next_track()) | ||
186 | goto next_track; | ||
187 | |||
188 | return CODEC_OK; | ||
189 | } | 192 | } |