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

Hendrik Leppkes h.leppkes at gmail.com
Sun Oct 4 02:02:12 CEST 2015


On Sun, Oct 4, 2015 at 1:37 AM, Michael Niedermayer <michaelni at gmx.at> wrote:
> 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)) {

Parsing the seektable should be independent of that flag, no?
Its surely still useful even if you do an accurate seek, is it not?

>> +                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
>
> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel at ffmpeg.org
> http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>


More information about the ffmpeg-devel mailing list