+ AVFilterContext *ctx = fs->parent;
+ AlphaMergeContext *s = ctx->priv;
+ AVFrame *main_buf, *alpha_buf;
+ int ret;
+
+ ret = ff_framesync_dualinput_get_writable(fs, &main_buf, &alpha_buf);
+ if (ret < 0)
+ return ret;
+ if (!alpha_buf)
+ return ff_filter_frame(ctx->outputs[0], main_buf);
+
+ if (s->is_packed_rgb) {
+ int x, y;
+ uint8_t *pin, *pout;
+ for (y = 0; y < main_buf->height; y++) {
+ pin = alpha_buf->data[0] + y * alpha_buf->linesize[0];
+ pout = main_buf->data[0] + y * main_buf->linesize[0] + s->rgba_map[A];
+ for (x = 0; x < main_buf->width; x++) {
+ *pout = *pin;
+ pin += 1;
+ pout += 4;
+ }
+ }
+ } else {
+ const int main_linesize = main_buf->linesize[A];
+ const int alpha_linesize = alpha_buf->linesize[Y];
+ av_image_copy_plane(main_buf->data[A], main_linesize,
+ alpha_buf->data[Y], alpha_linesize,
+ FFMIN(main_linesize, alpha_linesize), alpha_buf->height);
+ }
+
+ return ff_filter_frame(ctx->outputs[0], main_buf);
+}
+
+static av_cold int init(AVFilterContext *ctx)
+{
+ AlphaMergeContext *s = ctx->priv;
+
+ s->fs.on_event = do_alphamerge;
+ return 0;