From c537d5958e8b421ac4f9bef6c8b9e7425a6cf167 Mon Sep 17 00:00:00 2001 From: Michael Sevakis Date: Wed, 27 Apr 2011 03:08:23 +0000 Subject: 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 --- apps/codecs/cook.c | 63 ++++++++++++++++++++++++++++-------------------------- 1 file changed, 33 insertions(+), 30 deletions(-) (limited to 'apps/codecs/cook.c') 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) memcpy(rmctx, (void*)(( (intptr_t)ci->id3->id3v2buf + 3 ) &~ 3), sizeof(RMContext)); } -/* this is the codec entry point */ -enum codec_status codec_main(void) -{ +/* this is called for each file to process */ +enum codec_status codec_run(void) +{ static size_t buff_size; int datasize, res, consumed, i, time_offset; uint8_t *bit_buffer; @@ -48,16 +48,14 @@ enum codec_status codec_main(void) uint32_t packet_count; int scrambling_unit_size, num_units; size_t resume_offset; + intptr_t param = 0; + enum codec_command_action action = CODEC_ACTION_NULL; -next_track: if (codec_init()) { DEBUGF("codec init failed\n"); return CODEC_ERROR; } - if (codec_wait_taginfo() != 0) - goto done; - resume_offset = ci->id3->offset; codec_set_replaygain(ci->id3); @@ -65,6 +63,8 @@ next_track: ci->memset(&pkt,0,sizeof(RMPacket)); ci->memset(&q,0,sizeof(COOKContext)); + ci->seek_buffer(0); + init_rm(&rmctx); ci->configure(DSP_SET_FREQUENCY, ci->id3->frequency); @@ -87,20 +87,21 @@ next_track: DEBUGF("failed to initialize cook decoder\n"); return CODEC_ERROR; } - + /* check for a mid-track resume and force a seek time accordingly */ if(resume_offset > rmctx.data_offset + DATA_HEADER_SIZE) { resume_offset -= rmctx.data_offset + DATA_HEADER_SIZE; num_units = (int)resume_offset / scrambling_unit_size; /* put number of subpackets to skip in resume_offset */ resume_offset /= (sps + PACKET_HEADER_SIZE); - ci->seek_time = (int)resume_offset * ((sps * 8 * 1000)/rmctx.bit_rate); + param = (int)resume_offset * ((sps * 8 * 1000)/rmctx.bit_rate); + action = CODEC_ACTION_SEEK_TIME; } ci->set_elapsed(0); ci->advance_buffer(rmctx.data_offset + DATA_HEADER_SIZE); - /* The main decoder loop */ + /* The main decoder loop */ seek_start : while(packet_count) { @@ -112,18 +113,19 @@ seek_start : } for(i = 0; i < rmctx.audio_pkt_cnt*(fs/sps) ; i++) - { - ci->yield(); - if (ci->stop_codec || ci->new_track) - goto done; + { + if (action == CODEC_ACTION_NULL) + action = ci->get_command(¶m); - if (ci->seek_time) { - ci->set_elapsed(ci->seek_time); + if (action == CODEC_ACTION_HALT) + return CODEC_OK; + if (action == CODEC_ACTION_SEEK_TIME) { /* Do not allow seeking beyond the file's length */ - if ((unsigned) ci->seek_time > ci->id3->length) { + if ((unsigned) param > ci->id3->length) { + ci->set_elapsed(ci->id3->length); ci->seek_complete(); - goto done; + return CODEC_OK; } ci->seek_buffer(rmctx.data_offset + DATA_HEADER_SIZE); @@ -132,22 +134,24 @@ seek_start : rmctx.frame_number = 0; /* Seek to the start of the track */ - if (ci->seek_time == 1) { + if (param == 0) { ci->set_elapsed(0); ci->seek_complete(); + action = CODEC_ACTION_NULL; goto seek_start; } - num_units = ((ci->seek_time)/(sps*1000*8/rmctx.bit_rate))/(h*(fs/sps)); + num_units = (param/(sps*1000*8/rmctx.bit_rate))/(h*(fs/sps)); ci->seek_buffer(rmctx.data_offset + DATA_HEADER_SIZE + consumed * num_units); bit_buffer = (uint8_t *) ci->request_buffer(&buff_size, scrambling_unit_size); consumed = rm_get_packet(&bit_buffer, &rmctx, &pkt); if(consumed < 0) { DEBUGF("rm_get_packet failed\n"); - return CODEC_ERROR; + ci->seek_complete(); + return CODEC_ERROR; } packet_count = rmctx.nb_packets - rmctx.audio_pkt_cnt * num_units; - rmctx.frame_number = ((ci->seek_time)/(sps*1000*8/rmctx.bit_rate)); - while(rmctx.audiotimestamp > (unsigned) ci->seek_time) { + rmctx.frame_number = (param/(sps*1000*8/rmctx.bit_rate)); + while(rmctx.audiotimestamp > (unsigned) param) { rmctx.audio_pkt_cnt = 0; ci->seek_buffer(rmctx.data_offset + DATA_HEADER_SIZE + consumed * (num_units-1)); bit_buffer = (uint8_t *) ci->request_buffer(&buff_size, scrambling_unit_size); @@ -155,11 +159,14 @@ seek_start : packet_count += rmctx.audio_pkt_cnt; num_units--; } - time_offset = ci->seek_time - rmctx.audiotimestamp; + time_offset = param - rmctx.audiotimestamp; i = (time_offset/((sps * 8 * 1000)/rmctx.bit_rate)); ci->set_elapsed(rmctx.audiotimestamp+(1000*8*sps/rmctx.bit_rate)*i); ci->seek_complete(); - } + } + + action = CODEC_ACTION_NULL; + res = cook_decode_frame(&rmctx,&q, rm_outbuf, &datasize, pkt.frames[i], rmctx.block_align); rmctx.frame_number++; @@ -181,9 +188,5 @@ seek_start : ci->advance_buffer(consumed); } - done : - if (ci->request_next_track()) - goto next_track; - - return CODEC_OK; + return CODEC_OK; } -- cgit v1.2.3