On Wed, 27 May 2015 16:41:10 +0100
Vittorio Giovara <[email protected]> wrote:

> From: wm4 <[email protected]>
> 
> Apparently it can happen that a mp3 file has junk data between id3 tag
> and actual mp3 data. Skip this to avoid outputting nonsense timestamps.
> (Two packets had the same timestamps, because the mp3 parser failed to
> compute a frame duration.)
> 
> In this case, the junk consisted of 1044 bytes of zero, which
> incidentally is the same size as normal mp3 frames in this stream. I
> suspect the mp3 was edited with some tool which wiped the Xing/LAME
> headers. Data near the end of the file suggests it was encoded with
> "LAME3.97", but the normal Xing/LAME headers are missing. So this could
> be "normal". mpg123 also attempts to skip at least 64KB of junk data by
> scanning for headers.
> ---
> This assumes the stream buffer is not smaller than 64KB + max. mp3 frame
> size, or the seeks could turn into a problem.
> ---
>  libavformat/mp3dec.c | 12 ++++++++++++
>  1 file changed, 12 insertions(+)
> 
> diff --git a/libavformat/mp3dec.c b/libavformat/mp3dec.c
> index abd7fc0..a5374a1 100644
> --- a/libavformat/mp3dec.c
> +++ b/libavformat/mp3dec.c
> @@ -54,6 +54,8 @@ typedef struct {
>      int is_cbr;
>  } MP3DecContext;
> 
> +static int check(AVFormatContext *s, int64_t pos);
> +
>  /* mp3 read */
> 
>  static int mp3_read_probe(AVProbeData *p)
> @@ -370,6 +372,16 @@ static int mp3_read_header(AVFormatContext *s)
>      if (ret < 0)
>          return ret;
> 
> +    off = avio_tell(s->pb);
> +    for (i = 0; i < 64 * 1024; i++) {
> +        if (check(s, off + i) >= 0) {
> +            av_log(s, AV_LOG_INFO, "Skipping %d bytes of junk at
> %lld.\n", i, (long long)off);
> +            avio_seek(s->pb, off + i, SEEK_SET);
> +            break;
> +        }
> +        avio_seek(s->pb, off, SEEK_SET);
> +    }
> +
>      // the seek index is relative to the end of the xing vbr headers
>      for (i = 0; i < st->nb_index_entries; i++)
>          st->index_entries[i].pos += avio_tell(s->pb);
> --
> 2.1.4
> _______________________________________________

See also:

http://git.videolan.org/?p=ffmpeg.git;a=blobdiff;f=libavformat/mp3dec.c;h=07d7f543453a3e930a35141454c1ca710b3f839e;hp=a5374a1037d06d046a04147a6c4cdc4e86f4dd45;hb=f722009ad99733e619273372ade56c4c1b9c3b02;hpb=2b3e9bbfb529e6bde238aeb511b55ebe461664c8

(Although there could probably be even better reliable ways to make
seeking back in the failure case work.)

Also, your patch misses the check() function, which FFmpeg uses for
seeking. I suggest just adding the check() function, and ignore the
stuff about seeking; instead remove everything about seeking and enable
AVFMT_GENERIC_INDEX.
_______________________________________________
libav-devel mailing list
[email protected]
https://lists.libav.org/mailman/listinfo/libav-devel

Reply via email to