L'octidi 18 messidor, an CCXXIII, Marton Balint a écrit : > Signed-off-by: Marton Balint <c...@passwd.hu> > --- > doc/demuxers.texi | 13 +++++++++++++ > libavformat/concatdec.c | 22 ++++++++++++++++++++-- > 2 files changed, 33 insertions(+), 2 deletions(-) > > diff --git a/doc/demuxers.texi b/doc/demuxers.texi > index 4bad1c8..4ba797e 100644 > --- a/doc/demuxers.texi > +++ b/doc/demuxers.texi > @@ -129,6 +129,19 @@ directive) will be reduced based on their specified In > point. > Because of potential packets before the specified In point, packet timestamps > may overlap between two concatenated files. > > +@item @code{out @var{timestamp}} > +Out point of the file. When the demuxer reaches the specified timestamp in > any > +of the streams, it handles it as an end of file condition. Out point is > +exclusive, which means that the demuxer will not output packets which has a > +timestamp greater or equal to Out point. > + > +This directive works best with intra frame codecs, because for non-intra > frame > +ones you will usually not get enough packets to decode the last few frames > +before the specified Out point. > + > +The duration of the files (if not specified by the @code{duration} > +directive) will be reduced based on their specified Out point. > + > @item @code{stream} > Introduce a stream in the virtual file. > All subsequent stream-related directives apply to the last introduced > diff --git a/libavformat/concatdec.c b/libavformat/concatdec.c > index 11e6759..eaf34b0 100644 > --- a/libavformat/concatdec.c > +++ b/libavformat/concatdec.c > @@ -44,6 +44,7 @@ typedef struct { > int64_t duration; > ConcatStream *streams; > int64_t inpoint; > + int64_t outpoint; > int nb_streams; > } ConcatFile; > > @@ -145,6 +146,7 @@ static int add_file(AVFormatContext *avf, char *filename, > ConcatFile **rfile, > file->start_time = AV_NOPTS_VALUE; > file->duration = AV_NOPTS_VALUE; > file->inpoint = AV_NOPTS_VALUE; > + file->outpoint = AV_NOPTS_VALUE; > > return 0; > > @@ -360,7 +362,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, "in")) { > + } else if (!strcmp(keyword, "duration") || !strcmp(keyword, "in") || > !strcmp(keyword, "out")) { > char *dur_str = get_keyword(&cursor); > int64_t dur; > if (!file) { > @@ -377,6 +379,8 @@ static int concat_read_header(AVFormatContext *avf) > file->duration = dur; > else if (!strcmp(keyword, "in")) > file->inpoint = dur; > + else if (!strcmp(keyword, "out")) > + file->outpoint = dur; > } else if (!strcmp(keyword, "stream")) { > if (!avformat_new_stream(avf, NULL)) > FAIL(AVERROR(ENOMEM)); > @@ -443,6 +447,8 @@ static int open_next_file(AVFormatContext *avf) > cat->cur_file->duration = cat->avf->duration; > if (cat->cur_file->inpoint != AV_NOPTS_VALUE) > cat->cur_file->duration -= (cat->cur_file->inpoint - > file_start_time); > + if (cat->cur_file->outpoint != AV_NOPTS_VALUE) > + cat->cur_file->duration -= cat->avf->duration - > (cat->cur_file->outpoint - file_start_time); > } > > if (++fileno >= cat->nb_files) { > @@ -504,6 +510,16 @@ static int64_t get_cur_file_inpoint(ConcatContext *cat) > return file_inpoint; > } > > +/* Returns true if the packet pts is greater or equal to the specified > outpoint. */ > +static int packet_after_outpoint(ConcatContext *cat, AVPacket *pkt) > +{ > + if (cat->cur_file->outpoint != AV_NOPTS_VALUE && pkt->pts != > AV_NOPTS_VALUE) { > + return av_compare_ts(pkt->pts, > cat->avf->streams[pkt->stream_index]->time_base, > + cat->cur_file->outpoint, AV_TIME_BASE_Q) >= 0; > + } > + return 0; > +} > + > static int concat_read_packet(AVFormatContext *avf, AVPacket *pkt) > { > ConcatContext *cat = avf->priv_data; > @@ -520,7 +536,9 @@ static int concat_read_packet(AVFormatContext *avf, > AVPacket *pkt) > > while (1) { > ret = av_read_frame(cat->avf, pkt); > - if (ret == AVERROR_EOF) {
> + if (ret == AVERROR_EOF || packet_after_outpoint(cat, pkt)) { > + if (ret == 0) > + av_packet_unref(pkt); This will not work if the streams in the file are not exactly interleaved. Some formats store subtitles, and even audio, a few frames early, that will trigger EOF even though there may be frames below the outpoint still coming. At least, the documentation should have a warning about it. > if ((ret = open_next_file(avf)) < 0) > return ret; > continue; No other objection, but if you change the name of the inpoint option, maybe outpoint is no longer the best choice. Regards, -- Nicolas George
signature.asc
Description: Digital signature
_______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel