[FFmpeg-devel] [PATCH 4/4] lavf/concatdec: support seeking.

Stefano Sabatini stefasab at gmail.com
Fri Feb 22 15:56:15 CET 2013


On date Thursday 2013-02-14 16:30:59 +0100, Nicolas George encoded:
> 
> Signed-off-by: Nicolas George <nicolas.george at normalesup.org>
> ---
>  doc/demuxers.texi       |    3 ++
>  libavformat/concatdec.c |   98 ++++++++++++++++++++++++++++++++++++++++++++++-
>  2 files changed, 99 insertions(+), 2 deletions(-)
> 
> 
> Seeking works with ffplay.
> Nothing works with mplayer, since it uses lavf for demuxing but nut
> protocol, and tries to do smart things at the stream level, which fail
> spectacularly in this case.
> 
> 
> diff --git a/doc/demuxers.texi b/doc/demuxers.texi
> index c8eec21..d887c46 100644
> --- a/doc/demuxers.texi
> +++ b/doc/demuxers.texi
> @@ -71,6 +71,9 @@ Duration of the file. This information can be specified from the file;
>  specifying it here may be more efficient or help if the information from the
>  file is not available or accurate.
>  
> +If the duration is set for all files, then it is possible to seek in the
> +whole concatenated video.
> +
>  @end table
>  
>  @subsection Options
> diff --git a/libavformat/concatdec.c b/libavformat/concatdec.c
> index a9fcc76..675445e 100644
> --- a/libavformat/concatdec.c
> +++ b/libavformat/concatdec.c
> @@ -37,6 +37,7 @@ typedef struct {
>      unsigned nb_files;
>      AVFormatContext *avf;
>      int safe;
> +    int seekable;
>  } ConcatContext;
>  
>  static int concat_probe(AVProbeData *probe)
> @@ -122,6 +123,8 @@ static int open_file(AVFormatContext *avf, unsigned fileno)
>      ConcatFile *file = &cat->files[fileno];
>      int ret;
>  
> +    if (cat->avf)
> +        avformat_close_input(&cat->avf);

Is this related?

>      if ((ret = avformat_open_input(&cat->avf, file->url, NULL, NULL)) < 0 ||
>          (ret = avformat_find_stream_info(cat->avf, NULL)) < 0) {
>          av_log(avf, AV_LOG_ERROR, "Impossible to open '%s'\n", file->url);
> @@ -217,8 +220,10 @@ static int concat_read_header(AVFormatContext *avf)
>              break;
>          time += cat->files[i].duration;
>      }
> -    if (i == cat->nb_files)
> +    if (i == cat->nb_files) {
>          avf->duration = time;
> +        cat->seekable = 1;
> +    }
>  
>      if ((ret = open_file(avf, 0)) < 0)
>          FAIL(ret);
[...]
> +static int concat_seek(AVFormatContext *avf, int stream,
> +                       int64_t min_ts, int64_t ts, int64_t max_ts, int flags)
> +{
> +    ConcatContext *cat = avf->priv_data;
> +    ConcatFile *cur_file_saved = cat->cur_file;
> +    AVFormatContext *cur_avf_saved = cat->avf;
> +    int ret;
> +
> +    if (!cat->seekable)
> +        return AVERROR(ESPIPE); /* XXX: can we use it? */

http://pubs.opengroup.org/onlinepubs/009604599/functions/xsh_chap02_03.html

[ESPIPE]
Invalid seek. An attempt was made to access the file offset associated with a pipe or FIFO.

so no it doesn't seem very suitable to me (no pipe of FIFO here).

What we used in other cases:
[ENOSYS]
Function not implemented. An attempt was made to use a function that is not available in this implementation.

but even this use is quite stretched, and honestly I don't know what
to suggest.

A generic AVERROR with an explaining log message may be useful in this
case.

[...]

And I have no expertise at all with seeking, so I'd prefer someone
else to have a look at this.
-- 
FFmpeg = Fostering and Free MultiPurpose Erratic God


More information about the ffmpeg-devel mailing list