OVERLAY_FORMAT_YUV444,
OVERLAY_FORMAT_RGB,
OVERLAY_FORMAT_GBRP,
+ OVERLAY_FORMAT_AUTO,
OVERLAY_FORMAT_NB
};
const AVClass *class;
int x, y; ///< position of overlaid picture
- int allow_packed_rgb;
uint8_t main_is_packed_rgb;
uint8_t main_rgba_map[4];
uint8_t main_has_alpha;
return ret;
}
+static const enum AVPixelFormat alpha_pix_fmts[] = {
+ AV_PIX_FMT_YUVA420P, AV_PIX_FMT_YUVA422P, AV_PIX_FMT_YUVA444P,
+ AV_PIX_FMT_ARGB, AV_PIX_FMT_ABGR, AV_PIX_FMT_RGBA,
+ AV_PIX_FMT_BGRA, AV_PIX_FMT_GBRAP, AV_PIX_FMT_NONE
+};
+
static int query_formats(AVFilterContext *ctx)
{
OverlayContext *s = ctx->priv;
goto fail;
}
break;
+ case OVERLAY_FORMAT_AUTO:
+ if (!(main_formats = ff_make_format_list(alpha_pix_fmts))) {
+ ret = AVERROR(ENOMEM);
+ goto fail;
+ }
+ break;
default:
av_assert0(0);
}
- if ((ret = ff_formats_ref(main_formats , &ctx->inputs[MAIN]->out_formats )) < 0 ||
- (ret = ff_formats_ref(overlay_formats, &ctx->inputs[OVERLAY]->out_formats)) < 0 ||
- (ret = ff_formats_ref(main_formats , &ctx->outputs[MAIN]->in_formats )) < 0)
+ if (s->format == OVERLAY_FORMAT_AUTO) {
+ ret = ff_set_common_formats(ctx, main_formats);
+ if (ret < 0)
goto fail;
+ } else {
+ if ((ret = ff_formats_ref(main_formats , &ctx->inputs[MAIN]->out_formats )) < 0 ||
+ (ret = ff_formats_ref(overlay_formats, &ctx->inputs[OVERLAY]->out_formats)) < 0 ||
+ (ret = ff_formats_ref(main_formats , &ctx->outputs[MAIN]->in_formats )) < 0)
+ goto fail;
+ }
return 0;
fail:
return ret;
}
-static const enum AVPixelFormat alpha_pix_fmts[] = {
- AV_PIX_FMT_YUVA420P, AV_PIX_FMT_YUVA422P, AV_PIX_FMT_YUVA444P,
- AV_PIX_FMT_ARGB, AV_PIX_FMT_ABGR, AV_PIX_FMT_RGBA,
- AV_PIX_FMT_BGRA, AV_PIX_FMT_GBRAP, AV_PIX_FMT_NONE
-};
-
static int config_input_overlay(AVFilterLink *inlink)
{
AVFilterContext *ctx = inlink->dst;
static void blend_image_packed_rgb(AVFilterContext *ctx,
AVFrame *dst, const AVFrame *src,
- int x, int y)
+ int main_has_alpha, int x, int y)
{
OverlayContext *s = ctx->priv;
int i, imax, j, jmax;
const int sb = s->overlay_rgba_map[B];
const int sa = s->overlay_rgba_map[A];
const int sstep = s->overlay_pix_step[0];
- const int main_has_alpha = s->main_has_alpha;
uint8_t *S, *sp, *d, *dp;
i = FFMAX(-y, 0);
s->main_desc->comp[2].plane, s->main_desc->comp[2].offset, s->main_desc->comp[2].step);
}
-static av_always_inline void blend_image_rgb(AVFilterContext *ctx,
- AVFrame *dst, const AVFrame *src,
- int hsub, int vsub,
- int main_has_alpha,
- int x, int y)
+static av_always_inline void blend_image_planar_rgb(AVFilterContext *ctx,
+ AVFrame *dst, const AVFrame *src,
+ int hsub, int vsub,
+ int main_has_alpha,
+ int x, int y)
{
OverlayContext *s = ctx->priv;
const int src_w = src->width;
static void blend_image_yuv420(AVFilterContext *ctx, AVFrame *dst, const AVFrame *src, int x, int y)
{
- OverlayContext *s = ctx->priv;
+ blend_image_yuv(ctx, dst, src, 1, 1, 0, x, y);
+}
- blend_image_yuv(ctx, dst, src, 1, 1, s->main_has_alpha, x, y);
+static void blend_image_yuva420(AVFilterContext *ctx, AVFrame *dst, const AVFrame *src, int x, int y)
+{
+ blend_image_yuv(ctx, dst, src, 1, 1, 1, x, y);
}
static void blend_image_yuv422(AVFilterContext *ctx, AVFrame *dst, const AVFrame *src, int x, int y)
{
- OverlayContext *s = ctx->priv;
+ blend_image_yuv(ctx, dst, src, 1, 0, 0, x, y);
+}
- blend_image_yuv(ctx, dst, src, 1, 0, s->main_has_alpha, x, y);
+static void blend_image_yuva422(AVFilterContext *ctx, AVFrame *dst, const AVFrame *src, int x, int y)
+{
+ blend_image_yuv(ctx, dst, src, 1, 0, 1, x, y);
}
static void blend_image_yuv444(AVFilterContext *ctx, AVFrame *dst, const AVFrame *src, int x, int y)
{
- OverlayContext *s = ctx->priv;
+ blend_image_yuv(ctx, dst, src, 0, 0, 0, x, y);
+}
- blend_image_yuv(ctx, dst, src, 0, 0, s->main_has_alpha, x, y);
+static void blend_image_yuva444(AVFilterContext *ctx, AVFrame *dst, const AVFrame *src, int x, int y)
+{
+ blend_image_yuv(ctx, dst, src, 0, 0, 1, x, y);
}
static void blend_image_gbrp(AVFilterContext *ctx, AVFrame *dst, const AVFrame *src, int x, int y)
{
- OverlayContext *s = ctx->priv;
+ blend_image_planar_rgb(ctx, dst, src, 0, 0, 0, x, y);
+}
+
+static void blend_image_gbrap(AVFilterContext *ctx, AVFrame *dst, const AVFrame *src, int x, int y)
+{
+ blend_image_planar_rgb(ctx, dst, src, 0, 0, 1, x, y);
+}
- blend_image_rgb(ctx, dst, src, 0, 0, s->main_has_alpha, x, y);
+static void blend_image_rgb(AVFilterContext *ctx, AVFrame *dst, const AVFrame *src, int x, int y)
+{
+ blend_image_packed_rgb(ctx, dst, src, 0, x, y);
+}
+
+static void blend_image_rgba(AVFilterContext *ctx, AVFrame *dst, const AVFrame *src, int x, int y)
+{
+ blend_image_packed_rgb(ctx, dst, src, 1, x, y);
}
static int config_input_main(AVFilterLink *inlink)
s->main_has_alpha = ff_fmt_is_in(inlink->format, alpha_pix_fmts);
switch (s->format) {
case OVERLAY_FORMAT_YUV420:
- s->blend_image = blend_image_yuv420;
+ s->blend_image = s->main_has_alpha ? blend_image_yuva420 : blend_image_yuv420;
break;
case OVERLAY_FORMAT_YUV422:
- s->blend_image = blend_image_yuv422;
+ s->blend_image = s->main_has_alpha ? blend_image_yuva422 : blend_image_yuv422;
break;
case OVERLAY_FORMAT_YUV444:
- s->blend_image = blend_image_yuv444;
+ s->blend_image = s->main_has_alpha ? blend_image_yuva444 : blend_image_yuv444;
break;
case OVERLAY_FORMAT_RGB:
- s->blend_image = blend_image_packed_rgb;
+ s->blend_image = s->main_has_alpha ? blend_image_rgba : blend_image_rgb;
break;
case OVERLAY_FORMAT_GBRP:
- s->blend_image = blend_image_gbrp;
+ s->blend_image = s->main_has_alpha ? blend_image_gbrap : blend_image_gbrp;
+ break;
+ case OVERLAY_FORMAT_AUTO:
+ switch (inlink->format) {
+ case AV_PIX_FMT_YUVA420P:
+ s->blend_image = blend_image_yuva420;
+ break;
+ case AV_PIX_FMT_YUVA422P:
+ s->blend_image = blend_image_yuva422;
+ break;
+ case AV_PIX_FMT_YUVA444P:
+ s->blend_image = blend_image_yuva444;
+ break;
+ case AV_PIX_FMT_ARGB:
+ case AV_PIX_FMT_RGBA:
+ case AV_PIX_FMT_BGRA:
+ case AV_PIX_FMT_ABGR:
+ s->blend_image = blend_image_rgba;
+ break;
+ case AV_PIX_FMT_GBRAP:
+ s->blend_image = blend_image_gbrap;
+ break;
+ default:
+ av_assert0(0);
+ break;
+ }
break;
}
return 0;
{
OverlayContext *s = ctx->priv;
- if (s->allow_packed_rgb) {
- av_log(ctx, AV_LOG_WARNING,
- "The rgb option is deprecated and is overriding the format option, use format instead\n");
- s->format = OVERLAY_FORMAT_RGB;
- }
if (!s->dinput.repeatlast || s->eof_action == EOF_ACTION_PASS) {
s->dinput.repeatlast = 0;
s->eof_action = EOF_ACTION_PASS;
{ "eval", "specify when to evaluate expressions", OFFSET(eval_mode), AV_OPT_TYPE_INT, {.i64 = EVAL_MODE_FRAME}, 0, EVAL_MODE_NB-1, FLAGS, "eval" },
{ "init", "eval expressions once during initialization", 0, AV_OPT_TYPE_CONST, {.i64=EVAL_MODE_INIT}, .flags = FLAGS, .unit = "eval" },
{ "frame", "eval expressions per-frame", 0, AV_OPT_TYPE_CONST, {.i64=EVAL_MODE_FRAME}, .flags = FLAGS, .unit = "eval" },
- { "rgb", "force packed RGB in input and output (deprecated)", OFFSET(allow_packed_rgb), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS },
{ "shortest", "force termination when the shortest input terminates", OFFSET(dinput.shortest), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, FLAGS },
{ "format", "set output format", OFFSET(format), AV_OPT_TYPE_INT, {.i64=OVERLAY_FORMAT_YUV420}, 0, OVERLAY_FORMAT_NB-1, FLAGS, "format" },
{ "yuv420", "", 0, AV_OPT_TYPE_CONST, {.i64=OVERLAY_FORMAT_YUV420}, .flags = FLAGS, .unit = "format" },
{ "yuv444", "", 0, AV_OPT_TYPE_CONST, {.i64=OVERLAY_FORMAT_YUV444}, .flags = FLAGS, .unit = "format" },
{ "rgb", "", 0, AV_OPT_TYPE_CONST, {.i64=OVERLAY_FORMAT_RGB}, .flags = FLAGS, .unit = "format" },
{ "gbrp", "", 0, AV_OPT_TYPE_CONST, {.i64=OVERLAY_FORMAT_GBRP}, .flags = FLAGS, .unit = "format" },
+ { "auto", "", 0, AV_OPT_TYPE_CONST, {.i64=OVERLAY_FORMAT_AUTO}, .flags = FLAGS, .unit = "format" },
{ "repeatlast", "repeat overlay of the last overlay frame", OFFSET(dinput.repeatlast), AV_OPT_TYPE_BOOL, {.i64=1}, 0, 1, FLAGS },
{ NULL }
};