[FFmpeg-devel] [PATCH 2/2] lavf/concatdec: add outpoint_interleave_delay option

Nicolas George george at nsup.org
Fri Jan 8 14:45:50 CET 2016


Le decadi 10 nivôse, an CCXXIV, Marton Balint a écrit :
> Wait at most outpoint_interleave_delay at outpoint before considering it an
> end of file condition.
> 
> Signed-off-by: Marton Balint <cus at passwd.hu>
> ---
>  doc/demuxers.texi       | 20 ++++++++++++++++----
>  libavformat/concatdec.c | 13 ++++++++++---
>  2 files changed, 26 insertions(+), 7 deletions(-)
> 
> diff --git a/doc/demuxers.texi b/doc/demuxers.texi
> index fb1e4fb..b178195 100644
> --- a/doc/demuxers.texi
> +++ b/doc/demuxers.texi
> @@ -137,8 +137,7 @@ may overlap between two concatenated files.
>  
>  @item @code{outpoint @var{timestamp}}
>  Out point of the file. When the demuxer reaches the specified decoding
> -timestamp in any of the streams, it handles it as an end of file condition and
> -skips the current and all the remaining packets from all streams.
> +timestamp it drops the current and all the remaining packets in the stream.
>  
>  Out point is exclusive, which means that the demuxer will not output packets
>  with a decoding timestamp greater or equal to Out point.
> @@ -148,12 +147,25 @@ are tightly interleaved. For non-intra frame codecs you will usually get
>  additional packets with presentation timestamp after Out point therefore the
>  decoded content will most likely contain frames after Out point too. If your
>  streams are not tightly interleaved you may not get all the packets from all
> -streams before Out point and you may only will be able to decode the earliest
> -stream until Out point.
> +streams before Out point, see @code{outpoint_interleave_delay}.
>  
>  The duration of the files (if not specified by the @code{duration}
>  directive) will be reduced based on their specified Out point.
>  
> + at item @code{outpoint_interleave_delay @var{dur}}
> +With this directive you can specify how long the demuxer should wait before it
> +assumes that packets with timestamps before outpoint have appeared form all
> +streams, so there is no need to read the remaining packets from the input.
> +
> +If an Out point is specified and a packet timestamp is greater or equal to
> + at code{outpoint} plus the specified @code{outpoint_interleave_delay} in any of
> +the streams, the demuxer handles it as an end of file condition and skips the
> +current and all the remaining packets from all streams.
> +
> +The default value is 0. If your streams are not tightly interleaved, you should
> +increase this, otherwise you will only be able to decode the earliest stream
> +until Out point.
> +
>  @item @code{file_packet_metadata @var{key=value}}
>  Metadata of the packets of the file. The specified metadata will be set for
>  each file packet. You can specify this directive multiple times to add multiple
> diff --git a/libavformat/concatdec.c b/libavformat/concatdec.c
> index d226e15..afa822d 100644
> --- a/libavformat/concatdec.c
> +++ b/libavformat/concatdec.c
> @@ -48,6 +48,7 @@ typedef struct {
>      int64_t inpoint;
>      int64_t outpoint;
>      AVDictionary *metadata;
> +    int64_t outpoint_interleave_delay;
>      int nb_streams;
>  } ConcatFile;
>  
> @@ -378,7 +379,7 @@ static int concat_read_header(AVFormatContext *avf)
>              }
>              if ((ret = add_file(avf, filename, &file, &nb_files_alloc)) < 0)
>                  goto fail;
> -        } else if (!strcmp(keyword, "duration") || !strcmp(keyword, "inpoint") || !strcmp(keyword, "outpoint")) {
> +        } else if (!strcmp(keyword, "duration") || !strcmp(keyword, "inpoint") || !strcmp(keyword, "outpoint") || !strcmp(keyword, "outpoint_interleave_delay")) {
>              char *dur_str = get_keyword(&cursor);
>              int64_t dur;
>              if (!file) {
> @@ -397,6 +398,8 @@ static int concat_read_header(AVFormatContext *avf)
>                  file->inpoint = dur;
>              else if (!strcmp(keyword, "outpoint"))
>                  file->outpoint = dur;
> +            else if (!strcmp(keyword, "outpoint_interleave_delay"))
> +                file->outpoint_interleave_delay = dur;
>          } else if (!strcmp(keyword, "file_packet_metadata")) {
>              char *metadata;
>              if (!file) {
> @@ -567,9 +570,13 @@ static int concat_read_packet(AVFormatContext *avf, AVPacket *pkt)
>              return ret;
>          }
>          if (packet_after_outpoint(cat, pkt)) {

> +            int after_max_delay = av_compare_ts(pkt->dts, cat->avf->streams[pkt->stream_index]->time_base,
> +                                                cat->cur_file->outpoint + cat->cur_file->outpoint_interleave_delay, AV_TIME_BASE_Q) >= 0;

I suggest to pre-compute cat->cur_file->outpoint +
cat->cur_file->outpoint_interleave_delay.

>              av_packet_unref(pkt);
> -            if ((ret = open_next_file(avf)) < 0)
> -                return ret;
> +            if (after_max_delay) {
> +                if ((ret = open_next_file(avf)) < 0)
> +                    return ret;
> +            }

Unless I am mistaken, this logic will wait outpoint_interleave_delay even if
all streams are already beyond outpoint. For slow sources, this may be a
problem. Unfortunately, I see no way of avoiding that except a per-stream
flag.

>              continue;
>          }
>          cs = &cat->cur_file->streams[pkt->stream_index];

Regards,

-- 
  Nicolas George
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://ffmpeg.org/pipermail/ffmpeg-devel/attachments/20160108/14cd4ea2/attachment.sig>


More information about the ffmpeg-devel mailing list