Right now it incorrectly assumes that the frames are sent in the proper
order, which worked with old ffmpeg and avconv versions by accident.
---
libavfilter/vf_overlay.c | 207 +-
1 file changed, 115 insertions(+), 92 deletions(-)
diff --git a/libavfilter/vf_overlay.c b/libavfilter/vf_overlay.c
index 74c356e..e2d34a7 100644
--- a/libavfilter/vf_overlay.c
+++ b/libavfilter/vf_overlay.c
@@ -30,6 +30,7 @@
#include "libavutil/common.h"
#include "libavutil/eval.h"
#include "libavutil/avstring.h"
+#include "libavutil/avassert.h"
#include "libavutil/pixdesc.h"
#include "libavutil/imgutils.h"
#include "libavutil/mathematics.h"
@@ -64,12 +65,13 @@ enum var_name {
typedef struct {
int x, y; ///< position of overlayed picture
-AVFilterBufferRef *overpicref;
-
int max_plane_step[4]; ///< steps per pixel for each plane
int hsub, vsub; ///< chroma subsampling values
char x_expr[256], y_expr[256];
+
+AVFilterBufferRef *main;
+AVFilterBufferRef *over_prev, *over_next;
} OverlayContext;
static av_cold int init(AVFilterContext *ctx, const char *args)
@@ -87,9 +89,11 @@ static av_cold int init(AVFilterContext *ctx, const char
*args)
static av_cold void uninit(AVFilterContext *ctx)
{
-OverlayContext *over = ctx->priv;
+OverlayContext *s = ctx->priv;
-avfilter_unref_bufferp(&over->overpicref);
+avfilter_unref_bufferp(&s->main);
+avfilter_unref_bufferp(&s->over_prev);
+avfilter_unref_bufferp(&s->over_next);
}
static int query_formats(AVFilterContext *ctx)
@@ -189,62 +193,19 @@ static int config_output(AVFilterLink *outlink)
return 0;
}
-static AVFilterBufferRef *get_video_buffer(AVFilterLink *link, int perms, int
w, int h)
-{
-return ff_get_video_buffer(link->dst->outputs[0], perms, w, h);
-}
-
-static int start_frame(AVFilterLink *inlink, AVFilterBufferRef *inpicref)
-{
-AVFilterBufferRef *outpicref = avfilter_ref_buffer(inpicref, ~0);
-AVFilterContext *ctx = inlink->dst;
-OverlayContext *over = ctx->priv;
-
-if (!outpicref)
-return AVERROR(ENOMEM);
-
-if (!over->overpicref ||
-av_compare_ts(over->overpicref->pts, inlink->time_base,
- outpicref->pts, ctx->inputs[OVERLAY]->time_base) < 0) {
-AVFilterBufferRef *old = over->overpicref;
-over->overpicref = NULL;
-ff_request_frame(ctx->inputs[OVERLAY]);
-if (over->overpicref) {
-if (old)
-avfilter_unref_buffer(old);
-} else
-over->overpicref = old;
-}
-
-return ff_start_frame(inlink->dst->outputs[0], outpicref);
-}
-
-static int start_frame_overlay(AVFilterLink *inlink, AVFilterBufferRef
*inpicref)
-{
-AVFilterContext *ctx = inlink->dst;
-OverlayContext *over = ctx->priv;
-
-inlink->cur_buf = NULL;
-avfilter_unref_bufferp(&over->overpicref);
-over->overpicref = inpicref;
-return 0;
-}
-
-static void blend_slice(AVFilterContext *ctx,
+static void blend_frame(AVFilterContext *ctx,
AVFilterBufferRef *dst, AVFilterBufferRef *src,
-int x, int y, int w, int h,
-int slice_y, int slice_w, int slice_h)
+int x, int y)
{
OverlayContext *over = ctx->priv;
int i, j, k;
int width, height;
-int overlay_end_y = y+h;
-int slice_end_y = slice_y+slice_h;
+int overlay_end_y = y + src->video->h;
int end_y, start_y;
-width = FFMIN(slice_w - x, w);
-end_y = FFMIN(slice_end_y, overlay_end_y);
-start_y = FFMAX(y, slice_y);
+width = FFMIN(dst->video->w - x, src->video->w);
+end_y = FFMIN(dst->video->h, overlay_end_y);
+start_y = FFMAX(y, 0);
height = end_y - start_y;
if (dst->format == PIX_FMT_BGR24 || dst->format == PIX_FMT_RGB24) {
@@ -252,8 +213,8 @@ static void blend_slice(AVFilterContext *ctx,
uint8_t *sp = src->data[0];
int b = dst->format == PIX_FMT_BGR24 ? 2 : 0;
int r = dst->format == PIX_FMT_BGR24 ? 0 : 2;
-if (slice_y > y)
-sp += (slice_y - y) * src->linesize[0];
+if (y < 0)
+sp += -y * src->linesize[0];
for (i = 0; i < height; i++) {
uint8_t *d = dp, *s = sp;
for (j = 0; j < width; j++) {
@@ -276,9 +237,9 @@ static void blend_slice(AVFilterContext *ctx,
uint8_t *ap = src->data[3];
int wp = FFALIGN(width, 1<> hsub;
int hp = FFALIGN(height, 1<> vsub;
-if (slice_y > y) {
-sp += ((slice_y - y) >> vsub) * src->linesize[i];
-ap += (slice_y - y) * src->linesize[3];
+if (y < 0) {
+sp += ((-y) >> vsub) * src->linesize[i];
+ap += -y * src->linesize[3];
}
for (j = 0; j < hp; j++) {
uint8_t *d = dp, *s = sp, *a = ap;
@@ -308,48 +269,1