lavfi/overlay: implement shortest option
Force termination when the overlay stream ends. Simplify scripting logic, for example when an infinite source is used to generate a background for a composite video.
This commit is contained in:
parent
7f07c61c2f
commit
3d77a27548
@ -3881,6 +3881,10 @@ same as @var{overlay_w} and @var{overlay_h}
|
|||||||
@item rgb
|
@item rgb
|
||||||
If set to 1, force the filter to accept inputs in the RGB
|
If set to 1, force the filter to accept inputs in the RGB
|
||||||
color space. Default value is 0.
|
color space. Default value is 0.
|
||||||
|
|
||||||
|
@item shortest
|
||||||
|
If set to 1, force the output to terminate when the shortest input
|
||||||
|
terminates. Default value is 0.
|
||||||
@end table
|
@end table
|
||||||
|
|
||||||
Be aware that frames are taken from each input video in timestamp
|
Be aware that frames are taken from each input video in timestamp
|
||||||
@ -3940,6 +3944,18 @@ The above command is the same as:
|
|||||||
ffplay input.avi -vf 'split[b], pad=iw*2[src], [b]deshake, [src]overlay=w'
|
ffplay input.avi -vf 'split[b], pad=iw*2[src], [b]deshake, [src]overlay=w'
|
||||||
@end example
|
@end example
|
||||||
|
|
||||||
|
@item
|
||||||
|
Compose output by putting two input videos side to side:
|
||||||
|
@example
|
||||||
|
ffmpeg -i left.avi -i right.avi -filter_complex "
|
||||||
|
nullsrc=size=200x100 [background];
|
||||||
|
[0:v] setpts=PTS-STARTPTS, scale=100x100 [left];
|
||||||
|
[1:v] setpts=PTS-STARTPTS, scale=100x100 [right];
|
||||||
|
[background][left] overlay=shortest=1 [background+left];
|
||||||
|
[background+left][right] overlay=shortest=1:x=100 [left+right]
|
||||||
|
"
|
||||||
|
@end example
|
||||||
|
|
||||||
@item
|
@item
|
||||||
Chain several overlays in cascade:
|
Chain several overlays in cascade:
|
||||||
@example
|
@example
|
||||||
|
@ -30,7 +30,7 @@
|
|||||||
|
|
||||||
#define LIBAVFILTER_VERSION_MAJOR 3
|
#define LIBAVFILTER_VERSION_MAJOR 3
|
||||||
#define LIBAVFILTER_VERSION_MINOR 38
|
#define LIBAVFILTER_VERSION_MINOR 38
|
||||||
#define LIBAVFILTER_VERSION_MICRO 104
|
#define LIBAVFILTER_VERSION_MICRO 105
|
||||||
|
|
||||||
#define LIBAVFILTER_VERSION_INT AV_VERSION_INT(LIBAVFILTER_VERSION_MAJOR, \
|
#define LIBAVFILTER_VERSION_INT AV_VERSION_INT(LIBAVFILTER_VERSION_MAJOR, \
|
||||||
LIBAVFILTER_VERSION_MINOR, \
|
LIBAVFILTER_VERSION_MINOR, \
|
||||||
|
@ -91,6 +91,7 @@ typedef struct {
|
|||||||
int main_pix_step[4]; ///< steps per pixel for each plane of the main output
|
int main_pix_step[4]; ///< steps per pixel for each plane of the main output
|
||||||
int overlay_pix_step[4]; ///< steps per pixel for each plane of the overlay
|
int overlay_pix_step[4]; ///< steps per pixel for each plane of the overlay
|
||||||
int hsub, vsub; ///< chroma subsampling values
|
int hsub, vsub; ///< chroma subsampling values
|
||||||
|
int shortest; ///< terminate stream when the shortest input terminates
|
||||||
|
|
||||||
char *x_expr, *y_expr;
|
char *x_expr, *y_expr;
|
||||||
} OverlayContext;
|
} OverlayContext;
|
||||||
@ -102,6 +103,7 @@ static const AVOption overlay_options[] = {
|
|||||||
{ "x", "set the x expression", OFFSET(x_expr), AV_OPT_TYPE_STRING, {.str = "0"}, CHAR_MIN, CHAR_MAX, FLAGS },
|
{ "x", "set the x expression", OFFSET(x_expr), AV_OPT_TYPE_STRING, {.str = "0"}, CHAR_MIN, CHAR_MAX, FLAGS },
|
||||||
{ "y", "set the y expression", OFFSET(y_expr), AV_OPT_TYPE_STRING, {.str = "0"}, CHAR_MIN, CHAR_MAX, FLAGS },
|
{ "y", "set the y expression", OFFSET(y_expr), AV_OPT_TYPE_STRING, {.str = "0"}, CHAR_MIN, CHAR_MAX, FLAGS },
|
||||||
{"rgb", "force packed RGB in input and output", OFFSET(allow_packed_rgb), AV_OPT_TYPE_INT, {.i64=0}, 0, 1, FLAGS },
|
{"rgb", "force packed RGB in input and output", OFFSET(allow_packed_rgb), AV_OPT_TYPE_INT, {.i64=0}, 0, 1, FLAGS },
|
||||||
|
{ "shortest", "force termination when the shortest input terminates", OFFSET(shortest), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, FLAGS },
|
||||||
{NULL},
|
{NULL},
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -560,6 +562,8 @@ static int request_frame(AVFilterLink *outlink)
|
|||||||
/* EOF on main is reported immediately */
|
/* EOF on main is reported immediately */
|
||||||
if (ret == AVERROR_EOF && input == OVERLAY) {
|
if (ret == AVERROR_EOF && input == OVERLAY) {
|
||||||
over->overlay_eof = 1;
|
over->overlay_eof = 1;
|
||||||
|
if (over->shortest)
|
||||||
|
return ret;
|
||||||
if ((ret = try_filter_next_frame(ctx)) != AVERROR(EAGAIN))
|
if ((ret = try_filter_next_frame(ctx)) != AVERROR(EAGAIN))
|
||||||
return ret;
|
return ret;
|
||||||
ret = 0; /* continue requesting frames on main */
|
ret = 0; /* continue requesting frames on main */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user