Commit 839eb1c7 authored by Marton Balint's avatar Marton Balint

lavfi/select: add support for concatdec_select option

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.
Reviewed-by: 's avatarStefano Sabatini <stefasab@gmail.com>
Signed-off-by: 's avatarMarton Balint <cus@passwd.hu>
parent 65406b0b
......@@ -13196,6 +13196,25 @@ 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 can select only part of a concat input file by setting an
inpoint and an outpoint, but the output packets may not be entirely contained
in the selected interval. By using this variable, it is possible to skip frames
generated by the concat demuxer which are not exactly contained in the selected
interval.
This works by comparing the frame pts against the @var{lavf.concat.start_time}
and the @var{lavf.concat.duration} packet metadata values which are also
present in the decoded frames.
The @var{concatdec_select} variable is -1 if the frame pts is at least
start_time and either the duration metadata is missing or the frame pts is less
than start_time + duration, 0 otherwise, and NaN if the start_time metadata is
missing.
That basically means that an input frame is selected if its pts is within the
interval set by the concat demuxer.
@end table
The default value of the select expression is "1".
......@@ -13270,6 +13289,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 -segment_time_metadata 1 -i input.ffconcat -vf select=concatdec_select -af aselect=concatdec_select output.avi
@end example
@end itemize
@section selectivecolor
......
......@@ -82,6 +82,8 @@ static const char *const var_names[] = {
"scene",
"concatdec_select", ///< frame is within the interval set by the concat demuxer
NULL
};
......@@ -132,6 +134,8 @@ enum var_name {
VAR_SCENE,
VAR_CONCATDEC_SELECT,
VAR_VARS_NB
};
......@@ -278,6 +282,28 @@ 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 *start_time_entry = av_dict_get(metadata, "lavf.concatdec.start_time", NULL, 0);
AVDictionaryEntry *duration_entry = av_dict_get(metadata, "lavf.concatdec.duration", NULL, 0);
if (start_time_entry) {
int64_t start_time = strtoll(start_time_entry->value, NULL, 10);
if (pts >= start_time) {
if (duration_entry) {
int64_t duration = strtoll(duration_entry->value, NULL, 10);
if (pts < start_time + duration)
return -1;
else
return 0;
}
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 +323,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:
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment