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

Michael Niedermayer michaelni at gmx.at
Fri Sep 25 04:37:17 CEST 2015


On Fri, Sep 25, 2015 at 09:22:41AM +0800, Ching-Yi Chan wrote:
> I do it with AVFMT_FLAG_FAST_SEEK flag.
> 
> 
> 2015-09-24 23:47 GMT+08:00 wm4 <nfxjfg at googlemail.com>:
> 
> > On Thu, 24 Sep 2015 23:41:03 +0800
> > Ching-Yi Chan <chingyichan.tw at gmail.com> wrote:
> >
> > > Is it acceptable to provide an option for different methods
> > > between accuracy seek and fast but inaccurate.
> > >
> > > For example, mp3dec having "usetoc" option to seek by toc.
> >
> > You could use the AVFMT_FLAG_FAST_SEEK flag. (It's a flag set on the
> > format context.)
> > _______________________________________________
> > ffmpeg-devel mailing list
> > ffmpeg-devel at ffmpeg.org
> > http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
> >

>  flacdec.c |   43 ++++++++++++++++++++++++++++++++++++++++++-
>  1 file changed, 42 insertions(+), 1 deletion(-)
> 980c23fbd623f488c24194ec92d75aebe5e183f8  0001-avformat-flacdec-support-fast-seek.patch
> From 2e1d69e0a24455136d1a5dcc0898eac1bb2cb602 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 |   43 ++++++++++++++++++++++++++++++++++++++++++-
>  1 files changed, 42 insertions(+), 1 deletions(-)
> 
> diff --git a/libavformat/flacdec.c b/libavformat/flacdec.c
> index 4c1f943..3e4d867 100644
> --- a/libavformat/flacdec.c
> +++ b/libavformat/flacdec.c
> @@ -28,11 +28,14 @@
>  #include "vorbiscomment.h"
>  #include "replaygain.h"
>  
> +#define SEEKPOINT_SIZE 18
> +
>  static int flac_read_header(AVFormatContext *s)
>  {
>      int ret, metadata_last=0, metadata_type, metadata_size, found_streaminfo=0;
>      uint8_t header[4];
>      uint8_t *buffer=NULL;
> +
>      AVStream *st = avformat_new_stream(s, NULL);
>      if (!st)
>          return AVERROR(ENOMEM);
> @@ -58,6 +61,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 +136,20 @@ 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;
> +            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 +186,12 @@ static int flac_read_header(AVFormatContext *s)
>      if (ret < 0)
>          return ret;
>  
> +    /* the real seek index offset should be the size of metadata blocks with the offset in the frame blocks */
> +    int metadata_head_size = avio_tell(s->pb);

this should be int64_t probably
also declarations and statments should not be mixed


> +    int i;
> +    for(i=0; i<st->nb_index_entries; i++) {
> +        st->index_entries[i].pos += metadata_head_size;
> +    }
>      return 0;
>  
>  fail:
> @@ -249,12 +272,30 @@ 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) {
> +    if (!(s->flags&AVFMT_FLAG_FAST_SEEK)) {
> +        return -1;
> +    }
> +
> +    int index = av_index_search_timestamp(s->streams[0], timestamp, flags);
> +    if(index<0 || index >= s->streams[0]->nb_index_entries)
> +        return -1;
> +
> +    AVIndexEntry e = s->streams[0]->index_entries[index];

> +    int ret = avio_seek(s->pb, e.pos, SEEK_SET);

int64_t

what level of accuracy is this code intended to have ?

seek-acodec-flac would differ by the amounts listed below if the code
would be enabled and not depend on AVFMT_FLAG_FAST_SEEK

--- ./tests/ref/seek/acodec-flac        2015-09-25 03:40:06.793930465 +0200
+++ tests/data/fate/seek-acodec-flac    2015-09-25 04:22:51.565984498 +0200
@@ -2,7 +2,7 @@
 ret: 0         st:-1 flags:0  ts:-1.000000
 ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:   8256 size:   614
 ret: 0         st:-1 flags:1  ts: 1.894167
-ret: 0         st: 0 flags:1 dts: 1.880816 pts: 1.880816 pos:  86742 size:  2191
+ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:   8256 size:   614
 ret: 0         st: 0 flags:0  ts: 0.788345
 ret: 0         st: 0 flags:1 dts: 0.809796 pts: 0.809796 pos:  27366 size:   615
 ret: 0         st: 0 flags:1  ts:-0.317506
@@ -10,44 +10,44 @@
 ret: 0         st:-1 flags:0  ts: 2.576668
 ret: 0         st: 0 flags:1 dts: 2.586122 pts: 2.586122 pos: 145606 size:  2384
 ret: 0         st:-1 flags:1  ts: 1.470835
-ret: 0         st: 0 flags:1 dts: 1.462857 pts: 1.462857 pos:  53388 size:  1851
+ret: 0         st: 0 flags:1 dts: 0.809796 pts: 0.809796 pos:  27366 size:   615
 ret: 0         st: 0 flags:0  ts: 0.365011
-ret: 0         st: 0 flags:1 dts: 0.365714 pts: 0.365714 pos:  16890 size:   614
+ret: 0         st: 0 flags:1 dts: 0.809796 pts: 0.809796 pos:  27366 size:   615
 ret: 0         st: 0 flags:1  ts:-0.740839
 ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:   8256 size:   614
 ret: 0         st:-1 flags:0  ts: 2.153336
-ret: 0         st: 0 flags:1 dts: 2.168163 pts: 2.168163 pos: 110531 size:  2143
+ret: 0         st: 0 flags:1 dts: 2.586122 pts: 2.586122 pos: 145606 size:  2384
 ret: 0         st:-1 flags:1  ts: 1.047503
-ret: 0         st: 0 flags:1 dts: 1.044898 pts: 1.044898 pos:  32880 size:   579
+ret: 0         st: 0 flags:1 dts: 0.809796 pts: 0.809796 pos:  27366 size:   615
 ret: 0         st: 0 flags:0  ts:-0.058322
 ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:   8256 size:   614
 ret: 0         st: 0 flags:1  ts: 2.835828
-ret: 0         st: 0 flags:1 dts: 2.821224 pts: 2.821224 pos: 167112 size:  2391
+ret: 0         st: 0 flags:1 dts: 2.586122 pts: 2.586122 pos: 145606 size:  2384
 ret: 0         st:-1 flags:0  ts: 1.730004
-ret: 0         st: 0 flags:1 dts: 1.750204 pts: 1.750204 pos:  75788 size:  2191
+ret: 0         st: 0 flags:1 dts: 2.586122 pts: 2.586122 pos: 145606 size:  2384
 ret: 0         st:-1 flags:1  ts: 0.624171
-ret: 0         st: 0 flags:1 dts: 0.600816 pts: 0.600816 pos:  22446 size:   616
+ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:   8256 size:   614
 ret: 0         st: 0 flags:0  ts:-0.481655
 ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:   8256 size:   614
 ret: 0         st: 0 flags:1  ts: 2.412494
-ret: 0         st: 0 flags:1 dts: 2.403265 pts: 2.403265 pos: 129793 size:  2138
+ret: 0         st: 0 flags:1 dts: 0.809796 pts: 0.809796 pos:  27366 size:   615
 ret: 0         st:-1 flags:0  ts: 1.306672
-ret: 0         st: 0 flags:1 dts: 1.332245 pts: 1.332245 pos:  44812 size:  1609
+ret: 0         st: 0 flags:1 dts: 2.586122 pts: 2.586122 pos: 145606 size:  2384
 ret: 0         st:-1 flags:1  ts: 0.200839
-ret: 0         st: 0 flags:1 dts: 0.182857 pts: 0.182857 pos:  12572 size:   628
+ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:   8256 size:   614
 ret: 0         st: 0 flags:0  ts:-0.904989
 ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:   8256 size:   614
 ret: 0         st: 0 flags:1  ts: 1.989184
-ret: 0         st: 0 flags:1 dts: 1.985306 pts: 1.985306 pos:  95508 size:  2169
+ret: 0         st: 0 flags:1 dts: 0.809796 pts: 0.809796 pos:  27366 size:   615
 ret: 0         st:-1 flags:0  ts: 0.883340
-ret: 0         st: 0 flags:1 dts: 0.888163 pts: 0.888163 pos:  29211 size:   620
+ret: 0         st: 0 flags:1 dts: 2.586122 pts: 2.586122 pos: 145606 size:  2384
 ret: 0         st:-1 flags:1  ts:-0.222493
 ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:   8256 size:   614
 ret: 0         st: 0 flags:0  ts: 2.671678
 ret: 0         st: 0 flags:1 dts: 2.690612 pts: 2.690612 pos: 155154 size:  2394
 ret: 0         st: 0 flags:1  ts: 1.565850
-ret: 0         st: 0 flags:1 dts: 1.541224 pts: 1.541224 pos:  59082 size:  1974
+ret: 0         st: 0 flags:1 dts: 0.809796 pts: 0.809796 pos:  27366 size:   615
 ret: 0         st:-1 flags:0  ts: 0.460008
-ret: 0         st: 0 flags:1 dts: 0.470204 pts: 0.470204 pos:  19353 size:   608
+ret: 0         st: 0 flags:1 dts: 0.809796 pts: 0.809796 pos:  27366 size:   615
 ret: 0         st:-1 flags:1  ts:-0.645825
 ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:   8256 size:   614




> +    if (ret >= 0) {
> +        return ret;
> +    }
> +    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

Those who are best at talking, realize last or never when they are wrong.
-------------- 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/20150925/5d25426f/attachment.sig>


More information about the ffmpeg-devel mailing list