From f0c6c88f6d6afef6fa8bba311ce1bcf1873f8a90 Mon Sep 17 00:00:00 2001 From: Mohamed Tarek Date: Sat, 3 Oct 2009 00:18:42 +0000 Subject: [PATCH] Smarter check for failed packet parsing in RM. Also fixes a bug in playback where sometimes "codec failure" is splashed at the end of playback. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@22880 a1c6a512-1295-4272-9138-f99709370657 --- apps/codecs/a52_rm.c | 19 +++++++++++++++---- apps/codecs/atrac3_rm.c | 27 ++++++++++++++++++++------- apps/codecs/raac.c | 28 +++++++++++++++++++++------- 3 files changed, 56 insertions(+), 18 deletions(-) diff --git a/apps/codecs/a52_rm.c b/apps/codecs/a52_rm.c index 50269aea9d..32b66d2826 100644 --- a/apps/codecs/a52_rm.c +++ b/apps/codecs/a52_rm.c @@ -130,7 +130,8 @@ enum codec_status codec_main(void) { size_t n; uint8_t *filebuf; - int retval, consumed, packet_offset; + int retval, consumed, packet_offset; + int playback_on = -1; /* Generic codec initialisation */ ci->configure(DSP_SET_STEREO_MODE, STEREO_NONINTERLEAVED); @@ -173,10 +174,20 @@ next_track: filebuf = ci->request_buffer(&n, rmctx.block_align + PACKET_HEADER_SIZE); consumed = rm_get_packet(&filebuf, &rmctx, &pkt); - if(consumed < 0) { - DEBUGF("rm_get_packet failed\n"); - return CODEC_ERROR; + + if(consumed < 0 && playback_on != 0) { + if(playback_on == -1) { + /* Error only if packet-parsing failed and playback hadn't started */ + DEBUGF("rm_get_packet failed\n"); + return CODEC_ERROR; + } + else { + retval = CODEC_OK; + goto exit; + } } + + playback_on = 1; a52_decode_data(filebuf, filebuf + rmctx.block_align); ci->advance_buffer(pkt.length); } diff --git a/apps/codecs/atrac3_rm.c b/apps/codecs/atrac3_rm.c index f3bfa2f801..75c0d1581b 100644 --- a/apps/codecs/atrac3_rm.c +++ b/apps/codecs/atrac3_rm.c @@ -44,6 +44,7 @@ enum codec_status codec_main(void) uint16_t fs,sps,h; uint32_t packet_count; int scrambling_unit_size, num_units, elapsed = 0; + int playback_on = -1; next_track: if (codec_init()) { @@ -88,9 +89,14 @@ seek_start : { 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; + if(consumed < 0 && playback_on != 0) { + if(playback_on == -1) { + /* Error only if packet-parsing failed and playback hadn't started */ + DEBUGF("rm_get_packet failed\n"); + return CODEC_ERROR; + } + else + goto done; } for(i = 0; i < rmctx.audio_pkt_cnt*(fs/sps) ; i++) @@ -123,10 +129,16 @@ seek_start : 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; - } + if(consumed < 0 && playback_on != 0) { + if(playback_on == -1) { + /* Error only if packet-parsing failed and playback hadn't started */ + DEBUGF("rm_get_packet failed\n"); + return CODEC_ERROR; + } + else + goto done; + } + 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) { @@ -155,6 +167,7 @@ seek_start : if(datasize) ci->pcmbuf_insert(q.outSamples, q.outSamples + 1024, q.samples_per_frame / rmctx.nb_channels); + playback_on = 1; elapsed = rmctx.audiotimestamp+(1000*8*sps/rmctx.bit_rate)*i; ci->set_elapsed(elapsed); rmctx.frame_number++; diff --git a/apps/codecs/raac.c b/apps/codecs/raac.c index db113b3494..b886136bd9 100644 --- a/apps/codecs/raac.c +++ b/apps/codecs/raac.c @@ -47,6 +47,8 @@ enum codec_status codec_main(void) int err, consumed, pkt_offset, skipped = 0; uint32_t s = 0; /* sample rate */ unsigned char c = 0; /* channels */ + int playback_on = -1; + /* Generic codec initialisation */ ci->configure(DSP_SET_STEREO_MODE, STEREO_INTERLEAVED); ci->configure(DSP_SET_SAMPLE_DEPTH, 16); @@ -123,9 +125,14 @@ seek_start: buffer = ci->request_buffer(&n,rmctx.audio_framesize + 1000); pkt_offset = skipped - pkt.length; consumed = rm_get_packet(&buffer, &rmctx, &pkt); - if(consumed < 0) { - DEBUGF("rm_get_packet failed\n"); - return CODEC_ERROR; + if(consumed < 0 && playback_on != 0) { + if(playback_on == -1) { + /* Error only if packet-parsing failed and playback hadn't started */ + DEBUGF("rm_get_packet failed\n"); + return CODEC_ERROR; + } + else + goto done; } skipped += pkt.length; if(pkt.timestamp > (unsigned)ci->seek_time) break; @@ -139,11 +146,18 @@ seek_start: /* Request the required number of bytes from the input buffer */ buffer=ci->request_buffer(&n,rmctx.audio_framesize + 1000); consumed = rm_get_packet(&buffer, &rmctx, &pkt); - if(consumed < 0) { - DEBUGF("rm_get_packet failed\n"); - return CODEC_ERROR; - } + if(consumed < 0 && playback_on != 0) { + if(playback_on == -1) { + /* Error only if packet-parsing failed and playback hadn't started */ + DEBUGF("rm_get_packet failed\n"); + return CODEC_ERROR; + } + else + goto done; + } + + playback_on = 1; if (pkt.timestamp >= ci->id3->length) goto done; /* Decode one block - returned samples will be host-endian */