This option can be used to select useful frames from an ffconcat file which is using inpoints and outpoints but where the source files are not intra frame only.
Signed-off-by: Marton Balint <c...@passwd.hu> --- doc/filters.texi | 17 +++++++++++++++++ libavfilter/f_select.c | 20 ++++++++++++++++++++ 2 files changed, 37 insertions(+) diff --git a/doc/filters.texi b/doc/filters.texi index 5a35bde..093eec5 100644 --- a/doc/filters.texi +++ b/doc/filters.texi @@ -13160,6 +13160,16 @@ value between 0 and 1 to indicate a new scene; a low value reflects a low probability for the current frame to introduce a new scene, while a higher value means the current frame is more likely to be one (see the example below) +@item concatdec_select +The concat demuxer sets the @var{lavf.concat.start_time} and the +@var{lavf.concat.duration} packet metadata values which are also present in the +decoded frames. These metadata entries contain the start_time and the duration +of the respective file segments in the concatenated output. + +The @var{concatdec_select} variable is -1 if the frame pts is at least +start_time but less than start_time + duration, 0 otherwise, and NaN if the +mentioned metadata entires are not present. + @end table The default value of the select expression is "1". @@ -13234,6 +13244,13 @@ Send even and odd frames to separate outputs, and compose them: @example select=n=2:e='mod(n, 2)+1' [odd][even]; [odd] pad=h=2*ih [tmp]; [tmp][even] overlay=y=h @end example + +@item +Select useful frames from an ffconcat file which is using inpoints and +outpoints but where the source files are not intra frame only. +@example +ffmpeg -copyts -vsync 0 -i input.ffconcat -vf select=concatdec_select -af aselect=concatdec_select output.avi +@end example @end itemize @section selectivecolor diff --git a/libavfilter/f_select.c b/libavfilter/f_select.c index 2b926e1..d5f1470 100644 --- a/libavfilter/f_select.c +++ b/libavfilter/f_select.c @@ -82,6 +82,8 @@ static const char *const var_names[] = { "scene", + "concatdec_select", ///< frame usefulness based on pts and frame metadata originating from the concat demuxer + NULL }; @@ -132,6 +134,8 @@ enum var_name { VAR_SCENE, + VAR_CONCATDEC_SELECT, + VAR_VARS_NB }; @@ -278,6 +282,21 @@ static double get_scene_score(AVFilterContext *ctx, AVFrame *frame) return ret; } +static double get_concatdec_select(AVFrame *frame, int64_t pts) +{ + AVDictionary *metadata = av_frame_get_metadata(frame); + AVDictionaryEntry *e1 = av_dict_get(metadata, "lavf.concatdec.start_time", NULL, 0); + AVDictionaryEntry *e2 = av_dict_get(metadata, "lavf.concatdec.duration", NULL, 0); + if (e1 && e1->value && e2 && e2->value) { + int64_t start_time = strtoll(e1->value, NULL, 10); + int64_t duration = strtoll(e2->value, NULL, 10); + if (pts >= start_time && pts < start_time + duration) + return -1; + return 0; + } + return NAN; +} + #define D2TS(d) (isnan(d) ? AV_NOPTS_VALUE : (int64_t)(d)) #define TS2D(ts) ((ts) == AV_NOPTS_VALUE ? NAN : (double)(ts)) @@ -297,6 +316,7 @@ static void select_frame(AVFilterContext *ctx, AVFrame *frame) select->var_values[VAR_T ] = TS2D(frame->pts) * av_q2d(inlink->time_base); select->var_values[VAR_POS] = av_frame_get_pkt_pos(frame) == -1 ? NAN : av_frame_get_pkt_pos(frame); select->var_values[VAR_KEY] = frame->key_frame; + select->var_values[VAR_CONCATDEC_SELECT] = get_concatdec_select(frame, av_rescale_q(frame->pts, inlink->time_base, AV_TIME_BASE_Q)); switch (inlink->type) { case AVMEDIA_TYPE_AUDIO: -- 2.1.4 _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel