Signed-off-by: Paul B Mahol <one...@gmail.com> --- libavfilter/Makefile | 2 +- libavfilter/vf_alphamerge.c | 145 ++++++++++++++++++++++---------------------- 2 files changed, 72 insertions(+), 75 deletions(-)
diff --git a/libavfilter/Makefile b/libavfilter/Makefile index 058b9e9..c7337af 100644 --- a/libavfilter/Makefile +++ b/libavfilter/Makefile @@ -93,7 +93,7 @@ OBJS-$(CONFIG_ANULLSINK_FILTER) += asink_anullsink.o OBJS-$(CONFIG_ASS_FILTER) += vf_subtitles.o OBJS-$(CONFIG_ALPHAEXTRACT_FILTER) += vf_extractplanes.o -OBJS-$(CONFIG_ALPHAMERGE_FILTER) += vf_alphamerge.o +OBJS-$(CONFIG_ALPHAMERGE_FILTER) += vf_alphamerge.o framesync.o OBJS-$(CONFIG_BBOX_FILTER) += bbox.o vf_bbox.o OBJS-$(CONFIG_BLACKDETECT_FILTER) += vf_blackdetect.o OBJS-$(CONFIG_BLACKFRAME_FILTER) += vf_blackframe.o diff --git a/libavfilter/vf_alphamerge.c b/libavfilter/vf_alphamerge.c index 5f0da35..babbb1a 100644 --- a/libavfilter/vf_alphamerge.c +++ b/libavfilter/vf_alphamerge.c @@ -27,27 +27,25 @@ #include "libavutil/pixfmt.h" #include "avfilter.h" -#include "bufferqueue.h" #include "drawutils.h" #include "formats.h" #include "internal.h" +#include "framesync.h" #include "video.h" enum { Y, U, V, A }; typedef struct { - int frame_requested; int is_packed_rgb; uint8_t rgba_map[4]; - struct FFBufQueue queue_main; - struct FFBufQueue queue_alpha; + FFFrameSync fs; + FFFrameSyncIn fsin[1]; /* must be immediately after fs */ } AlphaMergeContext; static av_cold void uninit(AVFilterContext *ctx) { - AlphaMergeContext *merge = ctx->priv; - ff_bufqueue_discard_all(&merge->queue_main); - ff_bufqueue_discard_all(&merge->queue_alpha); + AlphaMergeContext *s = ctx->priv; + ff_framesync_uninit(&s->fs); } static int query_formats(AVFilterContext *ctx) @@ -74,11 +72,58 @@ static int config_input_main(AVFilterLink *inlink) return 0; } +static int draw_frame(FFFrameSync *fs) +{ + AVFilterContext *ctx = fs->parent; + AVFilterLink *outlink = ctx->outputs[0]; + AlphaMergeContext *s = ctx->priv; + AVFrame *alpha_buf = NULL, *main_buf = NULL; + int h, ret; + + if ((ret = ff_framesync_get_frame(&s->fs, 0, &main_buf, 1)) < 0 || + (ret = ff_framesync_get_frame(&s->fs, 1, &alpha_buf, 0)) < 0) { + av_frame_free(&main_buf); + return ret; + } + + main_buf->pts = av_rescale_q(main_buf->pts, s->fs.time_base, outlink->time_base); + if (alpha_buf && !ctx->is_disabled) { + h = main_buf->height; + if (s->is_packed_rgb) { + int x, y; + uint8_t *pin, *pout; + for (y = 0; y < h; 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 { + int y; + const int main_linesize = main_buf->linesize[A]; + const int alpha_linesize = alpha_buf->linesize[Y]; + for (y = 0; y < h && y < alpha_buf->height; y++) { + memcpy(main_buf->data[A] + y * main_linesize, + alpha_buf->data[Y] + y * alpha_linesize, + FFMIN(main_linesize, alpha_linesize)); + } + } + } + + return ff_filter_frame(outlink, main_buf); +} + static int config_output(AVFilterLink *outlink) { AVFilterContext *ctx = outlink->src; + AlphaMergeContext *s = ctx->priv; AVFilterLink *mainlink = ctx->inputs[0]; AVFilterLink *alphalink = ctx->inputs[1]; + FFFrameSyncIn *in = s->fs.in; + if (mainlink->w != alphalink->w || mainlink->h != alphalink->h) { av_log(ctx, AV_LOG_ERROR, "Input frame sizes do not match (%dx%d vs %dx%d).\n", @@ -92,82 +137,34 @@ static int config_output(AVFilterLink *outlink) outlink->time_base = mainlink->time_base; outlink->sample_aspect_ratio = mainlink->sample_aspect_ratio; outlink->frame_rate = mainlink->frame_rate; - return 0; -} -static void draw_frame(AVFilterContext *ctx, - AVFrame *main_buf, - AVFrame *alpha_buf) -{ - AlphaMergeContext *merge = ctx->priv; - int h = main_buf->height; - - if (merge->is_packed_rgb) { - int x, y; - uint8_t *pin, *pout; - for (y = 0; y < h; y++) { - pin = alpha_buf->data[0] + y * alpha_buf->linesize[0]; - pout = main_buf->data[0] + y * main_buf->linesize[0] + merge->rgba_map[A]; - for (x = 0; x < main_buf->width; x++) { - *pout = *pin; - pin += 1; - pout += 4; - } - } - } else { - int y; - const int main_linesize = main_buf->linesize[A]; - const int alpha_linesize = alpha_buf->linesize[Y]; - for (y = 0; y < h && y < alpha_buf->height; y++) { - memcpy(main_buf->data[A] + y * main_linesize, - alpha_buf->data[Y] + y * alpha_linesize, - FFMIN(main_linesize, alpha_linesize)); - } - } + ff_framesync_init(&s->fs, ctx, 2); + in = s->fs.in; + s->fs.opaque = s; + s->fs.on_event = draw_frame; + in[0].time_base = mainlink->time_base; + in[0].sync = 2; + in[0].before = EXT_STOP; + in[0].after = EXT_INFINITY; + + in[1].time_base = alphalink->time_base; + in[1].sync = 1; + in[1].before = EXT_STOP; + in[1].after = EXT_INFINITY; + + return ff_framesync_configure(&s->fs); } static int filter_frame(AVFilterLink *inlink, AVFrame *buf) { - AVFilterContext *ctx = inlink->dst; - AlphaMergeContext *merge = ctx->priv; - - int ret = 0; - int is_alpha = (inlink == ctx->inputs[1]); - struct FFBufQueue *queue = - (is_alpha ? &merge->queue_alpha : &merge->queue_main); - ff_bufqueue_add(ctx, queue, buf); - - do { - AVFrame *main_buf, *alpha_buf; - - if (!ff_bufqueue_peek(&merge->queue_main, 0) || - !ff_bufqueue_peek(&merge->queue_alpha, 0)) break; - - main_buf = ff_bufqueue_get(&merge->queue_main); - alpha_buf = ff_bufqueue_get(&merge->queue_alpha); - - merge->frame_requested = 0; - draw_frame(ctx, main_buf, alpha_buf); - ret = ff_filter_frame(ctx->outputs[0], main_buf); - av_frame_free(&alpha_buf); - } while (ret >= 0); - return ret; + AlphaMergeContext *s = inlink->dst->priv; + return ff_framesync_filter_frame(&s->fs, inlink, buf); } static int request_frame(AVFilterLink *outlink) { - AVFilterContext *ctx = outlink->src; - AlphaMergeContext *merge = ctx->priv; - int in, ret; - - merge->frame_requested = 1; - while (merge->frame_requested) { - in = ff_bufqueue_peek(&merge->queue_main, 0) ? 1 : 0; - ret = ff_request_frame(ctx->inputs[in]); - if (ret < 0) - return ret; - } - return 0; + AlphaMergeContext *s = outlink->src->priv; + return ff_framesync_request_frame(&s->fs, outlink); } static const AVFilterPad alphamerge_inputs[] = { -- 1.7.11.2 _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel