[FFmpeg-devel] [PATCH] avformat/flacdec: support fast-seek

Michael Niedermayer michaelni at gmx.at
Sun Oct 4 01:37:27 CEST 2015


On Sat, Oct 03, 2015 at 01:14:26AM +0800, Ching-Yi Chan wrote:
> Here is a new patch:
> 
> 1. fix compilation warning
> 2. remove ff_ prefix on my patch
> 3. toggle AVFMT_FLAG_FAST_SEEK when no seektalbe in the flac metadata (this
> will disable flac_seek when no seekpoint)

>  flacdec.c |   59 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++--
>  1 file changed, 57 insertions(+), 2 deletions(-)
> caa7d32b430da96d0dc377dbe7fe8518e872d132  0001-avformat-flacdec-support-fast-seek.patch
> From ac4c0a99f87c31ac510772172fc13ad82955c0d6 Mon Sep 17 00:00:00 2001
> From: "Ching Yi, Chan" <chingyichan.tw at gmail.com>
> Date: Thu, 24 Sep 2015 13:04:40 +0800
> Subject: [PATCH] avformat/flacdec: support fast-seek
> 
> ---
>  libavformat/flacdec.c |   59 +++++++++++++++++++++++++++++++++++++++++++++++-
>  1 files changed, 57 insertions(+), 2 deletions(-)
> 
> diff --git a/libavformat/flacdec.c b/libavformat/flacdec.c
> index 4c1f943..3fdbccc 100644
> --- a/libavformat/flacdec.c
> +++ b/libavformat/flacdec.c
> @@ -28,9 +28,20 @@
>  #include "vorbiscomment.h"
>  #include "replaygain.h"
>  
> +#define SEEKPOINT_SIZE 18
> +
> +static void reset_index_position(int64_t metadata_head_size, AVStream *st)
> +{
> +    /* the real seek index offset should be the size of metadata blocks with the offset in the frame blocks */
> +    int i;
> +    for(i=0; i<st->nb_index_entries; i++) {
> +        st->index_entries[i].pos += metadata_head_size;
> +    }
> +}
> +
>  static int flac_read_header(AVFormatContext *s)
>  {
> -    int ret, metadata_last=0, metadata_type, metadata_size, found_streaminfo=0;
> +    int ret, metadata_last=0, metadata_type, metadata_size, found_streaminfo=0, found_seektable=0;
>      uint8_t header[4];
>      uint8_t *buffer=NULL;
>      AVStream *st = avformat_new_stream(s, NULL);
> @@ -58,6 +69,7 @@ static int flac_read_header(AVFormatContext *s)
>          case FLAC_METADATA_TYPE_CUESHEET:
>          case FLAC_METADATA_TYPE_PICTURE:
>          case FLAC_METADATA_TYPE_VORBIS_COMMENT:
> +        case FLAC_METADATA_TYPE_SEEKTABLE:
>              buffer = av_mallocz(metadata_size + AV_INPUT_BUFFER_PADDING_SIZE);
>              if (!buffer) {
>                  return AVERROR(ENOMEM);
> @@ -132,7 +144,23 @@ static int flac_read_header(AVFormatContext *s)
>                  av_log(s, AV_LOG_ERROR, "Error parsing attached picture.\n");
>                  return ret;
>              }
> -        } else {
> +        } else if (metadata_type == FLAC_METADATA_TYPE_SEEKTABLE) {
> +            const uint8_t *seekpoint = buffer;
> +            int i, seek_point_count = metadata_size/SEEKPOINT_SIZE;
> +            found_seektable = 1;
> +            if ((s->flags&AVFMT_FLAG_FAST_SEEK)) {
> +                for(i=0; i<seek_point_count; i++) {
> +                    int64_t timestamp = bytestream_get_be64(&seekpoint);
> +                    int64_t pos = bytestream_get_be64(&seekpoint);
> +                    /* skip number of samples */
> +                    bytestream_get_be16(&seekpoint);
> +                    av_add_index_entry(st, pos, timestamp, 0, 0, AVINDEX_KEYFRAME);
> +                }
> +            }
> +            av_freep(&buffer);
> +        }
> +        else {
> +
>              /* STREAMINFO must be the first block */
>              if (!found_streaminfo) {
>                  RETURN_ERROR(AVERROR_INVALIDDATA);

> @@ -169,6 +197,12 @@ static int flac_read_header(AVFormatContext *s)
>      if (ret < 0)
>          return ret;
>  
> +    if (!found_seektable) {
> +        s->flags &= ~AVFMT_FLAG_FAST_SEEK;
> +        av_log(s, AV_LOG_WARNING, "seektable not found, disable AVFMT_FLAG_FAST_SEEK flag\n");
> +    }

iam not sure changing the format flags is a great idea, i think no
other demuxer does that
that said, the documentation does not say that only the user can
change them so this is more a note that this looks a bit odd not that
it is wrong


> +
> +    reset_index_position(avio_tell(s->pb), st);
>      return 0;
>  
>  fail:
> @@ -249,12 +283,33 @@ static av_unused int64_t flac_read_timestamp(AVFormatContext *s, int stream_inde
>      return pts;
>  }
>  
> +static int flac_seek(AVFormatContext *s, int stream_index, int64_t timestamp, int flags) {
> +    int index;
> +    int64_t pos;
> +    AVIndexEntry e;
> +    if (!(s->flags&AVFMT_FLAG_FAST_SEEK)) {
> +        return -1;
> +    }
> +
> +    index = av_index_search_timestamp(s->streams[0], timestamp, flags);
> +    if(index<0 || index >= s->streams[0]->nb_index_entries)
> +        return -1;
> +
> +    e = s->streams[0]->index_entries[index];
> +    pos = avio_seek(s->pb, e.pos, SEEK_SET);
> +    if (pos >= 0) {

> +        return pos;

if pos is larger than INT_MAX the this can overflow and be interpreted
as an error by the caller


> +    }
> +    return -1;
> +}
> +
>  AVInputFormat ff_flac_demuxer = {
>      .name           = "flac",
>      .long_name      = NULL_IF_CONFIG_SMALL("raw FLAC"),
>      .read_probe     = flac_probe,
>      .read_header    = flac_read_header,
>      .read_packet    = ff_raw_read_partial_packet,
> +    .read_seek      = flac_seek,
>      .read_timestamp = flac_read_timestamp,
>      .flags          = AVFMT_GENERIC_INDEX,
>      .extensions     = "flac",
> -- 
> 1.7.7
> 

> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel at ffmpeg.org
> http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


-- 
Michael     GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB

Observe your enemies, for they first find out your faults. -- Antisthenes
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 181 bytes
Desc: Digital signature
URL: <http://ffmpeg.org/pipermail/ffmpeg-devel/attachments/20151004/fce5890a/attachment.sig>


More information about the ffmpeg-devel mailing list