[FFmpeg-devel] [PATCH 5/5] lavfi/select: add support for concatdec_select option

Marton Balint cus at passwd.hu
Sat Oct 24 22:42:16 CEST 2015


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 <cus at 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)
 
+ at item concatdec_select
+The concat demuxer sets the @var{lavf.concat.start_time} and the
+ at 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
+
+ at item
+Select useful frames from an ffconcat file which is using inpoints and
+outpoints but where the source files are not intra frame only.
+ at example
+ffmpeg -copyts -vsync 0 -i input.ffconcat -vf select=concatdec_select -af aselect=concatdec_select output.avi
+ at 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



More information about the ffmpeg-devel mailing list