]> git.tuebingen.mpg.de Git - paraslash.git/commitdiff
mp3dec: Handle decode errors gracefully.
authorAndre Noll <maan@systemlinux.org>
Sun, 7 Aug 2011 10:33:03 +0000 (12:33 +0200)
committerAndre Noll <maan@systemlinux.org>
Tue, 9 Aug 2011 21:11:48 +0000 (23:11 +0200)
Currently decoding damaged mp3 files leads to very audible artefacts
even if only a single frame is corrupt. This patch instructs the mp3
decoder to synchronize the stream on decode errors and to continue the
decode process. Only on fatal errors the input buffer is discarded.

mp3dec_filter.c

index d262b2575c4f62760a93e0a8076b775d1dce2753..6982f264a8d866970cc80e960d79628a41c74101 100644 (file)
@@ -80,7 +80,7 @@ static void mp3dec_post_select(__a_unused struct sched *s, struct task *t)
        int i, ret;
        struct private_mp3dec_data *pmd = fn->private_data;
        struct btr_node *btrn = fn->btrn;
        int i, ret;
        struct private_mp3dec_data *pmd = fn->private_data;
        struct btr_node *btrn = fn->btrn;
-       size_t loaded, used, len, iqs;
+       size_t loaded = 0, used, len, iqs;
        char *inbuffer, *outbuffer;
 
 next_buffer:
        char *inbuffer, *outbuffer;
 
 next_buffer:
@@ -112,25 +112,27 @@ next_frame:
                                goto err;
                        }
                        fn->min_iqs += 100;
                                goto err;
                        }
                        fn->min_iqs += 100;
+               }
+               if (loaded == 0)
                        goto next_buffer;
                        goto next_buffer;
-               } else if (pmd->stream.error != MAD_ERROR_LOSTSYNC)
-                       PARA_DEBUG_LOG("header decode: %s\n",
-                               mad_stream_errorstr(&pmd->stream));
-               goto next_buffer;
+               return;
        }
        fn->min_iqs = 0;
        pmd->sample_rate = pmd->frame.header.samplerate;
        pmd->channels = MAD_NCHANNELS(&pmd->frame.header);
        }
        fn->min_iqs = 0;
        pmd->sample_rate = pmd->frame.header.samplerate;
        pmd->channels = MAD_NCHANNELS(&pmd->frame.header);
+decode:
        ret = mad_frame_decode(&pmd->frame, &pmd->stream);
        if (ret != 0) {
        ret = mad_frame_decode(&pmd->frame, &pmd->stream);
        if (ret != 0) {
-               PARA_INFO_LOG("frame decode: %s\n", mad_stream_errorstr(&pmd->stream));
-               used = used_mad_buffer_bytes(&pmd->stream, len);
                ret = handle_decode_error(pmd);
                ret = handle_decode_error(pmd);
-               btr_consume(btrn, used);
                if (ret < 0)
                        goto err;
                if (ret < 0)
                        goto err;
-               if (ret == 0)
-                       goto next_buffer;
+               mad_stream_sync(&pmd->stream);
+               if (pmd->stream.error == MAD_ERROR_BUFLEN)
+                       return;
+               if (pmd->stream.error != MAD_ERROR_BADDATAPTR)
+                       goto decode;
+               used = used_mad_buffer_bytes(&pmd->stream, len);
+               btr_consume(btrn, used);
                return;
        }
        mad_synth_frame(&pmd->synth, &pmd->frame);
                return;
        }
        mad_synth_frame(&pmd->synth, &pmd->frame);