[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