... | ... |
@@ -1485,11 +1485,19 @@ Overlay one video on top of another. |
1485 | 1485 |
It takes two inputs and one output, the first input is the "main" |
1486 | 1486 |
video on which the second input is overlayed. |
1487 | 1487 |
|
1488 |
-It accepts the parameters: @var{x}:@var{y}. |
|
1488 |
+This filter accepts the following parameters: |
|
1489 |
+ |
|
1490 |
+@table @option |
|
1491 |
+ |
|
1492 |
+@item x |
|
1493 |
+The horizontal position of the left edge of the overlaid video on the main video. |
|
1494 |
+ |
|
1495 |
+@item y |
|
1496 |
+The vertical position of the top edge of the overlaid video on the main video. |
|
1497 |
+ |
|
1498 |
+@end table |
|
1489 | 1499 |
|
1490 |
-@var{x} is the x coordinate of the overlayed video on the main video, |
|
1491 |
-@var{y} is the y coordinate. The parameters are expressions containing |
|
1492 |
-the following parameters: |
|
1500 |
+The parameters are expressions containing the following parameters: |
|
1493 | 1501 |
|
1494 | 1502 |
@table @option |
1495 | 1503 |
@item main_w, main_h |
... | ... |
@@ -1515,15 +1523,15 @@ Follow some examples: |
1515 | 1515 |
@example |
1516 | 1516 |
# draw the overlay at 10 pixels from the bottom right |
1517 | 1517 |
# corner of the main video. |
1518 |
-overlay=main_w-overlay_w-10:main_h-overlay_h-10 |
|
1518 |
+overlay=x=main_w-overlay_w-10:y=main_h-overlay_h-10 |
|
1519 | 1519 |
|
1520 | 1520 |
# insert a transparent PNG logo in the bottom left corner of the input |
1521 |
-avconv -i input -i logo -filter_complex 'overlay=10:main_h-overlay_h-10' output |
|
1521 |
+avconv -i input -i logo -filter_complex 'overlay=x=10:y=main_h-overlay_h-10' output |
|
1522 | 1522 |
|
1523 | 1523 |
# insert 2 different transparent PNG logos (second logo on bottom |
1524 | 1524 |
# right corner): |
1525 | 1525 |
avconv -i input -i logo1 -i logo2 -filter_complex |
1526 |
-'overlay=10:H-h-10,overlay=W-w-10:H-h-10' output |
|
1526 |
+'overlay=x=10:y=H-h-10,overlay=x=W-w-10:y=H-h-10' output |
|
1527 | 1527 |
|
1528 | 1528 |
# add a transparent color layer on top of the main video, |
1529 | 1529 |
# WxH specifies the size of the main input to the overlay filter |
... | ... |
@@ -34,6 +34,7 @@ |
34 | 34 |
#include "libavutil/pixdesc.h" |
35 | 35 |
#include "libavutil/imgutils.h" |
36 | 36 |
#include "libavutil/mathematics.h" |
37 |
+#include "libavutil/opt.h" |
|
37 | 38 |
#include "internal.h" |
38 | 39 |
#include "video.h" |
39 | 40 |
|
... | ... |
@@ -63,30 +64,18 @@ enum var_name { |
63 | 63 |
#define OVERLAY 1 |
64 | 64 |
|
65 | 65 |
typedef struct { |
66 |
+ const AVClass *class; |
|
66 | 67 |
int x, y; ///< position of overlayed picture |
67 | 68 |
|
68 | 69 |
int max_plane_step[4]; ///< steps per pixel for each plane |
69 | 70 |
int hsub, vsub; ///< chroma subsampling values |
70 | 71 |
|
71 |
- char x_expr[256], y_expr[256]; |
|
72 |
+ char *x_expr, *y_expr; |
|
72 | 73 |
|
73 | 74 |
AVFrame *main; |
74 | 75 |
AVFrame *over_prev, *over_next; |
75 | 76 |
} OverlayContext; |
76 | 77 |
|
77 |
-static av_cold int init(AVFilterContext *ctx, const char *args) |
|
78 |
-{ |
|
79 |
- OverlayContext *over = ctx->priv; |
|
80 |
- |
|
81 |
- av_strlcpy(over->x_expr, "0", sizeof(over->x_expr)); |
|
82 |
- av_strlcpy(over->y_expr, "0", sizeof(over->y_expr)); |
|
83 |
- |
|
84 |
- if (args) |
|
85 |
- sscanf(args, "%255[^:]:%255[^:]", over->x_expr, over->y_expr); |
|
86 |
- |
|
87 |
- return 0; |
|
88 |
-} |
|
89 |
- |
|
90 | 78 |
static av_cold void uninit(AVFilterContext *ctx) |
91 | 79 |
{ |
92 | 80 |
OverlayContext *s = ctx->priv; |
... | ... |
@@ -358,6 +347,23 @@ static int request_frame(AVFilterLink *outlink) |
358 | 358 |
return output_frame(ctx); |
359 | 359 |
} |
360 | 360 |
|
361 |
+#define OFFSET(x) offsetof(OverlayContext, x) |
|
362 |
+#define FLAGS AV_OPT_FLAG_VIDEO_PARAM |
|
363 |
+static const AVOption options[] = { |
|
364 |
+ { "x", "Horizontal position of the left edge of the overlaid video on the " |
|
365 |
+ "main video.", OFFSET(x_expr), AV_OPT_TYPE_STRING, { .str = "0" }, .flags = FLAGS }, |
|
366 |
+ { "y", "Vertical position of the top edge of the overlaid video on the " |
|
367 |
+ "main video.", OFFSET(y_expr), AV_OPT_TYPE_STRING, { .str = "0" }, .flags = FLAGS }, |
|
368 |
+ { NULL }, |
|
369 |
+}; |
|
370 |
+ |
|
371 |
+static const AVClass overlay_class = { |
|
372 |
+ .class_name = "overlay", |
|
373 |
+ .item_name = av_default_item_name, |
|
374 |
+ .option = options, |
|
375 |
+ .version = LIBAVUTIL_VERSION_INT, |
|
376 |
+}; |
|
377 |
+ |
|
361 | 378 |
static const AVFilterPad avfilter_vf_overlay_inputs[] = { |
362 | 379 |
{ |
363 | 380 |
.name = "main", |
... | ... |
@@ -391,10 +397,10 @@ AVFilter avfilter_vf_overlay = { |
391 | 391 |
.name = "overlay", |
392 | 392 |
.description = NULL_IF_CONFIG_SMALL("Overlay a video source on top of the input."), |
393 | 393 |
|
394 |
- .init = init, |
|
395 | 394 |
.uninit = uninit, |
396 | 395 |
|
397 | 396 |
.priv_size = sizeof(OverlayContext), |
397 |
+ .priv_class = &overlay_class, |
|
398 | 398 |
|
399 | 399 |
.query_formats = query_formats, |
400 | 400 |
|