Quoting Luca Barbato (2015-07-11 17:41:52)
> Try to parse up to 4 packets to find the closest packet.
> 
> Reported-By: [email protected]
> ---
>  libavformat/mp3dec.c | 78 
> ++++++++++++++++++++++++++++++++++++++++++++--------
>  1 file changed, 67 insertions(+), 11 deletions(-)
> 
> diff --git a/libavformat/mp3dec.c b/libavformat/mp3dec.c
> index cba6778..94a6633 100644
> --- a/libavformat/mp3dec.c
> +++ b/libavformat/mp3dec.c
> @@ -366,6 +366,69 @@ static int mp3_read_packet(AVFormatContext *s, AVPacket 
> *pkt)
>      return ret;
>  }
>  
> +
> +#define SEEK_PACKETS 4
> +#define SEEK_WINDOW (SEEK_PACKETS * MP3_PACKET_SIZE)
> +
> +/* The toc entry can position to the wrong byte offset, try to pick
> + * the closest frame by probing the data in a window of 4 packets.
> + */
> +
> +static int check(AVIOContext *pb, int64_t pos, int64_t *out_pos)
> +{
> +    MPADecodeHeader mh = { 0 };
> +    int i;
> +    uint32_t header;
> +    int64_t off = 0;
> +
> +

Extra empty line.

> +    for (i = 0; i < SEEK_PACKETS; i++) {
> +        off = avio_seek(pb, pos + mh.frame_size, SEEK_SET);
> +        if (off < 0)
> +            break;
> +
> +        header = avio_rb32(pb);
> +
> +        if (ff_mpa_check_header(header) < 0 ||
> +            avpriv_mpegaudio_decode_header(&mh, header))
> +            break;
> +        out_pos[i] = off;
> +    }
> +
> +    return i;
> +}
> +
> +static int reposition(AVFormatContext *s, int64_t pos)
> +{
> +    int ret, best_valid = -1;
> +    int64_t p, best_pos = -1;
> +
> +    for (p = FFMAX(pos - SEEK_WINDOW / 2, 0); p < pos + SEEK_WINDOW / 2; 
> p++) {
> +        int64_t out_pos[SEEK_PACKETS];
> +        ret = check(s->pb, p, out_pos);
> +
> +        if (best_valid < ret) {
> +            int i;
> +            for (i = 0; i < ret; i++) {
> +                if (llabs(best_pos - pos) > llabs(out_pos[i] - pos)) {
> +                    best_pos   = out_pos[i];
> +                    best_valid = ret;
> +                }
> +            }
> +            if (best_pos == pos && best_valid == SEEK_PACKETS)
> +                break;
> +        }
> +    }
> +
> +    if (best_valid <= 0)
> +        return AVERROR(ENOSYS);
> +
> +    avio_seek(s->pb, best_pos, SEEK_SET);

Seeking errors are now silently ignored.

I'd appreciate it if you waited at least a full day before pushing
nontrivial patches.

-- 
Anton Khirnov
_______________________________________________
libav-devel mailing list
[email protected]
https://lists.libav.org/mailman/listinfo/libav-devel

Reply via email to