You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1163 lines
55KB

  1. /*
  2. * Copyright (c) 2010 Stefano Sabatini
  3. * Copyright (c) 2010 Baptiste Coudurier
  4. * Copyright (c) 2007 Bobby Bingham
  5. *
  6. * This file is part of FFmpeg.
  7. *
  8. * FFmpeg is free software; you can redistribute it and/or
  9. * modify it under the terms of the GNU Lesser General Public
  10. * License as published by the Free Software Foundation; either
  11. * version 2.1 of the License, or (at your option) any later version.
  12. *
  13. * FFmpeg is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  16. * Lesser General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU Lesser General Public
  19. * License along with FFmpeg; if not, write to the Free Software
  20. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  21. */
  22. /**
  23. * @file
  24. * overlay one video on top of another
  25. */
  26. #include "avfilter.h"
  27. #include "formats.h"
  28. #include "libavutil/common.h"
  29. #include "libavutil/eval.h"
  30. #include "libavutil/avstring.h"
  31. #include "libavutil/pixdesc.h"
  32. #include "libavutil/imgutils.h"
  33. #include "libavutil/mathematics.h"
  34. #include "libavutil/opt.h"
  35. #include "libavutil/timestamp.h"
  36. #include "internal.h"
  37. #include "drawutils.h"
  38. #include "framesync.h"
  39. #include "video.h"
  40. #include "vf_overlay.h"
  41. typedef struct ThreadData {
  42. AVFrame *dst, *src;
  43. } ThreadData;
  44. static const char *const var_names[] = {
  45. "main_w", "W", ///< width of the main video
  46. "main_h", "H", ///< height of the main video
  47. "overlay_w", "w", ///< width of the overlay video
  48. "overlay_h", "h", ///< height of the overlay video
  49. "hsub",
  50. "vsub",
  51. "x",
  52. "y",
  53. "n", ///< number of frame
  54. "pos", ///< position in the file
  55. "t", ///< timestamp expressed in seconds
  56. NULL
  57. };
  58. #define MAIN 0
  59. #define OVERLAY 1
  60. #define R 0
  61. #define G 1
  62. #define B 2
  63. #define A 3
  64. #define Y 0
  65. #define U 1
  66. #define V 2
  67. enum EvalMode {
  68. EVAL_MODE_INIT,
  69. EVAL_MODE_FRAME,
  70. EVAL_MODE_NB
  71. };
  72. static av_cold void uninit(AVFilterContext *ctx)
  73. {
  74. OverlayContext *s = ctx->priv;
  75. ff_framesync_uninit(&s->fs);
  76. av_expr_free(s->x_pexpr); s->x_pexpr = NULL;
  77. av_expr_free(s->y_pexpr); s->y_pexpr = NULL;
  78. }
  79. static inline int normalize_xy(double d, int chroma_sub)
  80. {
  81. if (isnan(d))
  82. return INT_MAX;
  83. return (int)d & ~((1 << chroma_sub) - 1);
  84. }
  85. static void eval_expr(AVFilterContext *ctx)
  86. {
  87. OverlayContext *s = ctx->priv;
  88. s->var_values[VAR_X] = av_expr_eval(s->x_pexpr, s->var_values, NULL);
  89. s->var_values[VAR_Y] = av_expr_eval(s->y_pexpr, s->var_values, NULL);
  90. /* It is necessary if x is expressed from y */
  91. s->var_values[VAR_X] = av_expr_eval(s->x_pexpr, s->var_values, NULL);
  92. s->x = normalize_xy(s->var_values[VAR_X], s->hsub);
  93. s->y = normalize_xy(s->var_values[VAR_Y], s->vsub);
  94. }
  95. static int set_expr(AVExpr **pexpr, const char *expr, const char *option, void *log_ctx)
  96. {
  97. int ret;
  98. AVExpr *old = NULL;
  99. if (*pexpr)
  100. old = *pexpr;
  101. ret = av_expr_parse(pexpr, expr, var_names,
  102. NULL, NULL, NULL, NULL, 0, log_ctx);
  103. if (ret < 0) {
  104. av_log(log_ctx, AV_LOG_ERROR,
  105. "Error when evaluating the expression '%s' for %s\n",
  106. expr, option);
  107. *pexpr = old;
  108. return ret;
  109. }
  110. av_expr_free(old);
  111. return 0;
  112. }
  113. static int process_command(AVFilterContext *ctx, const char *cmd, const char *args,
  114. char *res, int res_len, int flags)
  115. {
  116. OverlayContext *s = ctx->priv;
  117. int ret;
  118. if (!strcmp(cmd, "x"))
  119. ret = set_expr(&s->x_pexpr, args, cmd, ctx);
  120. else if (!strcmp(cmd, "y"))
  121. ret = set_expr(&s->y_pexpr, args, cmd, ctx);
  122. else
  123. ret = AVERROR(ENOSYS);
  124. if (ret < 0)
  125. return ret;
  126. if (s->eval_mode == EVAL_MODE_INIT) {
  127. eval_expr(ctx);
  128. av_log(ctx, AV_LOG_VERBOSE, "x:%f xi:%d y:%f yi:%d\n",
  129. s->var_values[VAR_X], s->x,
  130. s->var_values[VAR_Y], s->y);
  131. }
  132. return ret;
  133. }
  134. static const enum AVPixelFormat alpha_pix_fmts[] = {
  135. AV_PIX_FMT_YUVA420P, AV_PIX_FMT_YUVA422P, AV_PIX_FMT_YUVA444P,
  136. AV_PIX_FMT_YUVA420P10, AV_PIX_FMT_YUVA422P10,
  137. AV_PIX_FMT_ARGB, AV_PIX_FMT_ABGR, AV_PIX_FMT_RGBA,
  138. AV_PIX_FMT_BGRA, AV_PIX_FMT_GBRAP, AV_PIX_FMT_NONE
  139. };
  140. static int query_formats(AVFilterContext *ctx)
  141. {
  142. OverlayContext *s = ctx->priv;
  143. /* overlay formats contains alpha, for avoiding conversion with alpha information loss */
  144. static const enum AVPixelFormat main_pix_fmts_yuv420[] = {
  145. AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUVJ420P, AV_PIX_FMT_YUVA420P,
  146. AV_PIX_FMT_NV12, AV_PIX_FMT_NV21,
  147. AV_PIX_FMT_NONE
  148. };
  149. static const enum AVPixelFormat overlay_pix_fmts_yuv420[] = {
  150. AV_PIX_FMT_YUVA420P, AV_PIX_FMT_NONE
  151. };
  152. static const enum AVPixelFormat main_pix_fmts_yuv420p10[] = {
  153. AV_PIX_FMT_YUV420P10, AV_PIX_FMT_YUVA420P10,
  154. AV_PIX_FMT_NONE
  155. };
  156. static const enum AVPixelFormat overlay_pix_fmts_yuv420p10[] = {
  157. AV_PIX_FMT_YUVA420P10, AV_PIX_FMT_NONE
  158. };
  159. static const enum AVPixelFormat main_pix_fmts_yuv422[] = {
  160. AV_PIX_FMT_YUV422P, AV_PIX_FMT_YUVJ422P, AV_PIX_FMT_YUVA422P, AV_PIX_FMT_NONE
  161. };
  162. static const enum AVPixelFormat overlay_pix_fmts_yuv422[] = {
  163. AV_PIX_FMT_YUVA422P, AV_PIX_FMT_NONE
  164. };
  165. static const enum AVPixelFormat main_pix_fmts_yuv422p10[] = {
  166. AV_PIX_FMT_YUV422P10, AV_PIX_FMT_YUVA422P10, AV_PIX_FMT_NONE
  167. };
  168. static const enum AVPixelFormat overlay_pix_fmts_yuv422p10[] = {
  169. AV_PIX_FMT_YUVA422P10, AV_PIX_FMT_NONE
  170. };
  171. static const enum AVPixelFormat main_pix_fmts_yuv444[] = {
  172. AV_PIX_FMT_YUV444P, AV_PIX_FMT_YUVJ444P, AV_PIX_FMT_YUVA444P, AV_PIX_FMT_NONE
  173. };
  174. static const enum AVPixelFormat overlay_pix_fmts_yuv444[] = {
  175. AV_PIX_FMT_YUVA444P, AV_PIX_FMT_NONE
  176. };
  177. static const enum AVPixelFormat main_pix_fmts_gbrp[] = {
  178. AV_PIX_FMT_GBRP, AV_PIX_FMT_GBRAP, AV_PIX_FMT_NONE
  179. };
  180. static const enum AVPixelFormat overlay_pix_fmts_gbrp[] = {
  181. AV_PIX_FMT_GBRAP, AV_PIX_FMT_NONE
  182. };
  183. static const enum AVPixelFormat main_pix_fmts_rgb[] = {
  184. AV_PIX_FMT_ARGB, AV_PIX_FMT_RGBA,
  185. AV_PIX_FMT_ABGR, AV_PIX_FMT_BGRA,
  186. AV_PIX_FMT_RGB24, AV_PIX_FMT_BGR24,
  187. AV_PIX_FMT_NONE
  188. };
  189. static const enum AVPixelFormat overlay_pix_fmts_rgb[] = {
  190. AV_PIX_FMT_ARGB, AV_PIX_FMT_RGBA,
  191. AV_PIX_FMT_ABGR, AV_PIX_FMT_BGRA,
  192. AV_PIX_FMT_NONE
  193. };
  194. AVFilterFormats *main_formats = NULL;
  195. AVFilterFormats *overlay_formats = NULL;
  196. int ret;
  197. switch (s->format) {
  198. case OVERLAY_FORMAT_YUV420:
  199. if (!(main_formats = ff_make_format_list(main_pix_fmts_yuv420)) ||
  200. !(overlay_formats = ff_make_format_list(overlay_pix_fmts_yuv420))) {
  201. ret = AVERROR(ENOMEM);
  202. goto fail;
  203. }
  204. break;
  205. case OVERLAY_FORMAT_YUV420P10:
  206. if (!(main_formats = ff_make_format_list(main_pix_fmts_yuv420p10)) ||
  207. !(overlay_formats = ff_make_format_list(overlay_pix_fmts_yuv420p10))) {
  208. ret = AVERROR(ENOMEM);
  209. goto fail;
  210. }
  211. break;
  212. case OVERLAY_FORMAT_YUV422:
  213. if (!(main_formats = ff_make_format_list(main_pix_fmts_yuv422)) ||
  214. !(overlay_formats = ff_make_format_list(overlay_pix_fmts_yuv422))) {
  215. ret = AVERROR(ENOMEM);
  216. goto fail;
  217. }
  218. break;
  219. case OVERLAY_FORMAT_YUV422P10:
  220. if (!(main_formats = ff_make_format_list(main_pix_fmts_yuv422p10)) ||
  221. !(overlay_formats = ff_make_format_list(overlay_pix_fmts_yuv422p10))) {
  222. ret = AVERROR(ENOMEM);
  223. goto fail;
  224. }
  225. break;
  226. case OVERLAY_FORMAT_YUV444:
  227. if (!(main_formats = ff_make_format_list(main_pix_fmts_yuv444)) ||
  228. !(overlay_formats = ff_make_format_list(overlay_pix_fmts_yuv444))) {
  229. ret = AVERROR(ENOMEM);
  230. goto fail;
  231. }
  232. break;
  233. case OVERLAY_FORMAT_RGB:
  234. if (!(main_formats = ff_make_format_list(main_pix_fmts_rgb)) ||
  235. !(overlay_formats = ff_make_format_list(overlay_pix_fmts_rgb))) {
  236. ret = AVERROR(ENOMEM);
  237. goto fail;
  238. }
  239. break;
  240. case OVERLAY_FORMAT_GBRP:
  241. if (!(main_formats = ff_make_format_list(main_pix_fmts_gbrp)) ||
  242. !(overlay_formats = ff_make_format_list(overlay_pix_fmts_gbrp))) {
  243. ret = AVERROR(ENOMEM);
  244. goto fail;
  245. }
  246. break;
  247. case OVERLAY_FORMAT_AUTO:
  248. if (!(main_formats = ff_make_format_list(alpha_pix_fmts))) {
  249. ret = AVERROR(ENOMEM);
  250. goto fail;
  251. }
  252. break;
  253. default:
  254. av_assert0(0);
  255. }
  256. if (s->format == OVERLAY_FORMAT_AUTO) {
  257. ret = ff_set_common_formats(ctx, main_formats);
  258. if (ret < 0)
  259. goto fail;
  260. } else {
  261. if ((ret = ff_formats_ref(main_formats , &ctx->inputs[MAIN]->out_formats )) < 0 ||
  262. (ret = ff_formats_ref(overlay_formats, &ctx->inputs[OVERLAY]->out_formats)) < 0 ||
  263. (ret = ff_formats_ref(main_formats , &ctx->outputs[MAIN]->in_formats )) < 0)
  264. goto fail;
  265. }
  266. return 0;
  267. fail:
  268. if (main_formats)
  269. av_freep(&main_formats->formats);
  270. av_freep(&main_formats);
  271. if (overlay_formats)
  272. av_freep(&overlay_formats->formats);
  273. av_freep(&overlay_formats);
  274. return ret;
  275. }
  276. static int config_input_overlay(AVFilterLink *inlink)
  277. {
  278. AVFilterContext *ctx = inlink->dst;
  279. OverlayContext *s = inlink->dst->priv;
  280. int ret;
  281. const AVPixFmtDescriptor *pix_desc = av_pix_fmt_desc_get(inlink->format);
  282. av_image_fill_max_pixsteps(s->overlay_pix_step, NULL, pix_desc);
  283. /* Finish the configuration by evaluating the expressions
  284. now when both inputs are configured. */
  285. s->var_values[VAR_MAIN_W ] = s->var_values[VAR_MW] = ctx->inputs[MAIN ]->w;
  286. s->var_values[VAR_MAIN_H ] = s->var_values[VAR_MH] = ctx->inputs[MAIN ]->h;
  287. s->var_values[VAR_OVERLAY_W] = s->var_values[VAR_OW] = ctx->inputs[OVERLAY]->w;
  288. s->var_values[VAR_OVERLAY_H] = s->var_values[VAR_OH] = ctx->inputs[OVERLAY]->h;
  289. s->var_values[VAR_HSUB] = 1<<pix_desc->log2_chroma_w;
  290. s->var_values[VAR_VSUB] = 1<<pix_desc->log2_chroma_h;
  291. s->var_values[VAR_X] = NAN;
  292. s->var_values[VAR_Y] = NAN;
  293. s->var_values[VAR_N] = 0;
  294. s->var_values[VAR_T] = NAN;
  295. s->var_values[VAR_POS] = NAN;
  296. if ((ret = set_expr(&s->x_pexpr, s->x_expr, "x", ctx)) < 0 ||
  297. (ret = set_expr(&s->y_pexpr, s->y_expr, "y", ctx)) < 0)
  298. return ret;
  299. s->overlay_is_packed_rgb =
  300. ff_fill_rgba_map(s->overlay_rgba_map, inlink->format) >= 0;
  301. s->overlay_has_alpha = ff_fmt_is_in(inlink->format, alpha_pix_fmts);
  302. if (s->eval_mode == EVAL_MODE_INIT) {
  303. eval_expr(ctx);
  304. av_log(ctx, AV_LOG_VERBOSE, "x:%f xi:%d y:%f yi:%d\n",
  305. s->var_values[VAR_X], s->x,
  306. s->var_values[VAR_Y], s->y);
  307. }
  308. av_log(ctx, AV_LOG_VERBOSE,
  309. "main w:%d h:%d fmt:%s overlay w:%d h:%d fmt:%s\n",
  310. ctx->inputs[MAIN]->w, ctx->inputs[MAIN]->h,
  311. av_get_pix_fmt_name(ctx->inputs[MAIN]->format),
  312. ctx->inputs[OVERLAY]->w, ctx->inputs[OVERLAY]->h,
  313. av_get_pix_fmt_name(ctx->inputs[OVERLAY]->format));
  314. return 0;
  315. }
  316. static int config_output(AVFilterLink *outlink)
  317. {
  318. AVFilterContext *ctx = outlink->src;
  319. OverlayContext *s = ctx->priv;
  320. int ret;
  321. if ((ret = ff_framesync_init_dualinput(&s->fs, ctx)) < 0)
  322. return ret;
  323. outlink->w = ctx->inputs[MAIN]->w;
  324. outlink->h = ctx->inputs[MAIN]->h;
  325. outlink->time_base = ctx->inputs[MAIN]->time_base;
  326. return ff_framesync_configure(&s->fs);
  327. }
  328. // divide by 255 and round to nearest
  329. // apply a fast variant: (X+127)/255 = ((X+127)*257+257)>>16 = ((X+128)*257)>>16
  330. #define FAST_DIV255(x) ((((x) + 128) * 257) >> 16)
  331. // calculate the unpremultiplied alpha, applying the general equation:
  332. // alpha = alpha_overlay / ( (alpha_main + alpha_overlay) - (alpha_main * alpha_overlay) )
  333. // (((x) << 16) - ((x) << 9) + (x)) is a faster version of: 255 * 255 * x
  334. // ((((x) + (y)) << 8) - ((x) + (y)) - (y) * (x)) is a faster version of: 255 * (x + y)
  335. #define UNPREMULTIPLY_ALPHA(x, y) ((((x) << 16) - ((x) << 9) + (x)) / ((((x) + (y)) << 8) - ((x) + (y)) - (y) * (x)))
  336. /**
  337. * Blend image in src to destination buffer dst at position (x, y).
  338. */
  339. static av_always_inline void blend_slice_packed_rgb(AVFilterContext *ctx,
  340. AVFrame *dst, const AVFrame *src,
  341. int main_has_alpha, int x, int y,
  342. int is_straight, int jobnr, int nb_jobs)
  343. {
  344. OverlayContext *s = ctx->priv;
  345. int i, imax, j, jmax;
  346. const int src_w = src->width;
  347. const int src_h = src->height;
  348. const int dst_w = dst->width;
  349. const int dst_h = dst->height;
  350. uint8_t alpha; ///< the amount of overlay to blend on to main
  351. const int dr = s->main_rgba_map[R];
  352. const int dg = s->main_rgba_map[G];
  353. const int db = s->main_rgba_map[B];
  354. const int da = s->main_rgba_map[A];
  355. const int dstep = s->main_pix_step[0];
  356. const int sr = s->overlay_rgba_map[R];
  357. const int sg = s->overlay_rgba_map[G];
  358. const int sb = s->overlay_rgba_map[B];
  359. const int sa = s->overlay_rgba_map[A];
  360. const int sstep = s->overlay_pix_step[0];
  361. int slice_start, slice_end;
  362. uint8_t *S, *sp, *d, *dp;
  363. i = FFMAX(-y, 0);
  364. imax = FFMIN3(-y + dst_h, FFMIN(src_h, dst_h), y + src_h);
  365. slice_start = i + (imax * jobnr) / nb_jobs;
  366. slice_end = i + (imax * (jobnr+1)) / nb_jobs;
  367. sp = src->data[0] + (slice_start) * src->linesize[0];
  368. dp = dst->data[0] + (y + slice_start) * dst->linesize[0];
  369. for (i = slice_start; i < slice_end; i++) {
  370. j = FFMAX(-x, 0);
  371. S = sp + j * sstep;
  372. d = dp + (x+j) * dstep;
  373. for (jmax = FFMIN(-x + dst_w, src_w); j < jmax; j++) {
  374. alpha = S[sa];
  375. // if the main channel has an alpha channel, alpha has to be calculated
  376. // to create an un-premultiplied (straight) alpha value
  377. if (main_has_alpha && alpha != 0 && alpha != 255) {
  378. uint8_t alpha_d = d[da];
  379. alpha = UNPREMULTIPLY_ALPHA(alpha, alpha_d);
  380. }
  381. switch (alpha) {
  382. case 0:
  383. break;
  384. case 255:
  385. d[dr] = S[sr];
  386. d[dg] = S[sg];
  387. d[db] = S[sb];
  388. break;
  389. default:
  390. // main_value = main_value * (1 - alpha) + overlay_value * alpha
  391. // since alpha is in the range 0-255, the result must divided by 255
  392. d[dr] = is_straight ? FAST_DIV255(d[dr] * (255 - alpha) + S[sr] * alpha) :
  393. FFMIN(FAST_DIV255(d[dr] * (255 - alpha)) + S[sr], 255);
  394. d[dg] = is_straight ? FAST_DIV255(d[dg] * (255 - alpha) + S[sg] * alpha) :
  395. FFMIN(FAST_DIV255(d[dg] * (255 - alpha)) + S[sg], 255);
  396. d[db] = is_straight ? FAST_DIV255(d[db] * (255 - alpha) + S[sb] * alpha) :
  397. FFMIN(FAST_DIV255(d[db] * (255 - alpha)) + S[sb], 255);
  398. }
  399. if (main_has_alpha) {
  400. switch (alpha) {
  401. case 0:
  402. break;
  403. case 255:
  404. d[da] = S[sa];
  405. break;
  406. default:
  407. // apply alpha compositing: main_alpha += (1-main_alpha) * overlay_alpha
  408. d[da] += FAST_DIV255((255 - d[da]) * S[sa]);
  409. }
  410. }
  411. d += dstep;
  412. S += sstep;
  413. }
  414. dp += dst->linesize[0];
  415. sp += src->linesize[0];
  416. }
  417. }
  418. #define DEFINE_BLEND_PLANE(depth, nbits) \
  419. static av_always_inline void blend_plane_##depth##_##nbits##bits(AVFilterContext *ctx, \
  420. AVFrame *dst, const AVFrame *src, \
  421. int src_w, int src_h, \
  422. int dst_w, int dst_h, \
  423. int i, int hsub, int vsub, \
  424. int x, int y, \
  425. int main_has_alpha, \
  426. int dst_plane, \
  427. int dst_offset, \
  428. int dst_step, \
  429. int straight, \
  430. int yuv, \
  431. int jobnr, \
  432. int nb_jobs) \
  433. { \
  434. OverlayContext *octx = ctx->priv; \
  435. int src_wp = AV_CEIL_RSHIFT(src_w, hsub); \
  436. int src_hp = AV_CEIL_RSHIFT(src_h, vsub); \
  437. int dst_wp = AV_CEIL_RSHIFT(dst_w, hsub); \
  438. int dst_hp = AV_CEIL_RSHIFT(dst_h, vsub); \
  439. int yp = y>>vsub; \
  440. int xp = x>>hsub; \
  441. uint##depth##_t *s, *sp, *d, *dp, *dap, *a, *da, *ap; \
  442. int jmax, j, k, kmax; \
  443. int slice_start, slice_end; \
  444. const uint##depth##_t max = (1 << nbits) - 1; \
  445. const uint##depth##_t mid = (1 << (nbits -1)) ; \
  446. int bytes = depth / 8; \
  447. \
  448. dst_step /= bytes; \
  449. j = FFMAX(-yp, 0); \
  450. jmax = FFMIN3(-yp + dst_hp, FFMIN(src_hp, dst_hp), yp + src_hp); \
  451. \
  452. slice_start = j + (jmax * jobnr) / nb_jobs; \
  453. slice_end = j + (jmax * (jobnr+1)) / nb_jobs; \
  454. \
  455. sp = (uint##depth##_t *)(src->data[i] + (slice_start) * src->linesize[i]); \
  456. dp = (uint##depth##_t *)(dst->data[dst_plane] \
  457. + (yp + slice_start) * dst->linesize[dst_plane] \
  458. + dst_offset); \
  459. ap = (uint##depth##_t *)(src->data[3] + (slice_start << vsub) * src->linesize[3]); \
  460. dap = (uint##depth##_t *)(dst->data[3] + ((yp + slice_start) << vsub) * dst->linesize[3]); \
  461. \
  462. for (j = slice_start; j < slice_end; j++) { \
  463. k = FFMAX(-xp, 0); \
  464. d = dp + (xp+k) * dst_step; \
  465. s = sp + k; \
  466. a = ap + (k<<hsub); \
  467. da = dap + ((xp+k) << hsub); \
  468. kmax = FFMIN(-xp + dst_wp, src_wp); \
  469. \
  470. if (nbits == 8 && ((vsub && j+1 < src_hp) || !vsub) && octx->blend_row[i]) { \
  471. int c = octx->blend_row[i]((uint8_t*)d, (uint8_t*)da, (uint8_t*)s, \
  472. (uint8_t*)a, kmax - k, src->linesize[3]); \
  473. \
  474. s += c; \
  475. d += dst_step * c; \
  476. da += (1 << hsub) * c; \
  477. a += (1 << hsub) * c; \
  478. k += c; \
  479. } \
  480. for (; k < kmax; k++) { \
  481. int alpha_v, alpha_h, alpha; \
  482. \
  483. /* average alpha for color components, improve quality */ \
  484. if (hsub && vsub && j+1 < src_hp && k+1 < src_wp) { \
  485. alpha = (a[0] + a[src->linesize[3]] + \
  486. a[1] + a[src->linesize[3]+1]) >> 2; \
  487. } else if (hsub || vsub) { \
  488. alpha_h = hsub && k+1 < src_wp ? \
  489. (a[0] + a[1]) >> 1 : a[0]; \
  490. alpha_v = vsub && j+1 < src_hp ? \
  491. (a[0] + a[src->linesize[3]]) >> 1 : a[0]; \
  492. alpha = (alpha_v + alpha_h) >> 1; \
  493. } else \
  494. alpha = a[0]; \
  495. /* if the main channel has an alpha channel, alpha has to be calculated */ \
  496. /* to create an un-premultiplied (straight) alpha value */ \
  497. if (main_has_alpha && alpha != 0 && alpha != max) { \
  498. /* average alpha for color components, improve quality */ \
  499. uint8_t alpha_d; \
  500. if (hsub && vsub && j+1 < src_hp && k+1 < src_wp) { \
  501. alpha_d = (da[0] + da[dst->linesize[3]] + \
  502. da[1] + da[dst->linesize[3]+1]) >> 2; \
  503. } else if (hsub || vsub) { \
  504. alpha_h = hsub && k+1 < src_wp ? \
  505. (da[0] + da[1]) >> 1 : da[0]; \
  506. alpha_v = vsub && j+1 < src_hp ? \
  507. (da[0] + da[dst->linesize[3]]) >> 1 : da[0]; \
  508. alpha_d = (alpha_v + alpha_h) >> 1; \
  509. } else \
  510. alpha_d = da[0]; \
  511. alpha = UNPREMULTIPLY_ALPHA(alpha, alpha_d); \
  512. } \
  513. if (straight) { \
  514. if (nbits > 8) \
  515. *d = (*d * (max - alpha) + *s * alpha) / max; \
  516. else \
  517. *d = FAST_DIV255(*d * (255 - alpha) + *s * alpha); \
  518. } else { \
  519. if (nbits > 8) { \
  520. if (i && yuv) \
  521. *d = av_clip((*d * (max - alpha) + *s * alpha) / max + *s - mid, -mid, mid) + mid; \
  522. else \
  523. *d = FFMIN((*d * (max - alpha) + *s * alpha) / max + *s, max); \
  524. } else { \
  525. if (i && yuv) \
  526. *d = av_clip(FAST_DIV255((*d - mid) * (max - alpha)) + *s - mid, -mid, mid) + mid; \
  527. else \
  528. *d = FFMIN(FAST_DIV255(*d * (max - alpha)) + *s, max); \
  529. } \
  530. } \
  531. s++; \
  532. d += dst_step; \
  533. da += 1 << hsub; \
  534. a += 1 << hsub; \
  535. } \
  536. dp += dst->linesize[dst_plane] / bytes; \
  537. sp += src->linesize[i] / bytes; \
  538. ap += (1 << vsub) * src->linesize[3] / bytes; \
  539. dap += (1 << vsub) * dst->linesize[3] / bytes; \
  540. } \
  541. }
  542. DEFINE_BLEND_PLANE(8, 8)
  543. DEFINE_BLEND_PLANE(16, 10)
  544. #define DEFINE_ALPHA_COMPOSITE(depth, nbits) \
  545. static inline void alpha_composite_##depth##_##nbits##bits(const AVFrame *src, const AVFrame *dst, \
  546. int src_w, int src_h, \
  547. int dst_w, int dst_h, \
  548. int x, int y, \
  549. int jobnr, int nb_jobs) \
  550. { \
  551. uint##depth##_t alpha; /* the amount of overlay to blend on to main */ \
  552. uint##depth##_t *s, *sa, *d, *da; \
  553. int i, imax, j, jmax; \
  554. int slice_start, slice_end; \
  555. const uint##depth##_t max = (1 << nbits) - 1; \
  556. int bytes = depth / 8; \
  557. \
  558. imax = FFMIN(-y + dst_h, src_h); \
  559. slice_start = (imax * jobnr) / nb_jobs; \
  560. slice_end = ((imax * (jobnr+1)) / nb_jobs); \
  561. \
  562. i = FFMAX(-y, 0); \
  563. sa = (uint##depth##_t *)(src->data[3] + (i + slice_start) * src->linesize[3]); \
  564. da = (uint##depth##_t *)(dst->data[3] + (y + i + slice_start) * dst->linesize[3]); \
  565. \
  566. for (i = i + slice_start; i < slice_end; i++) { \
  567. j = FFMAX(-x, 0); \
  568. s = sa + j; \
  569. d = da + x+j; \
  570. \
  571. for (jmax = FFMIN(-x + dst_w, src_w); j < jmax; j++) { \
  572. alpha = *s; \
  573. if (alpha != 0 && alpha != max) { \
  574. uint8_t alpha_d = *d; \
  575. alpha = UNPREMULTIPLY_ALPHA(alpha, alpha_d); \
  576. } \
  577. if (alpha == max) \
  578. *d = *s; \
  579. else if (alpha > 0) { \
  580. /* apply alpha compositing: main_alpha += (1-main_alpha) * overlay_alpha */ \
  581. if (nbits > 8) \
  582. *d += (max - *d) * *s / max; \
  583. else \
  584. *d += FAST_DIV255((max - *d) * *s); \
  585. } \
  586. d += 1; \
  587. s += 1; \
  588. } \
  589. da += dst->linesize[3] / bytes; \
  590. sa += src->linesize[3] / bytes; \
  591. } \
  592. }
  593. DEFINE_ALPHA_COMPOSITE(8, 8)
  594. DEFINE_ALPHA_COMPOSITE(16, 10)
  595. #define DEFINE_BLEND_SLICE_YUV(depth, nbits) \
  596. static av_always_inline void blend_slice_yuv_##depth##_##nbits##bits(AVFilterContext *ctx, \
  597. AVFrame *dst, const AVFrame *src, \
  598. int hsub, int vsub, \
  599. int main_has_alpha, \
  600. int x, int y, \
  601. int is_straight, \
  602. int jobnr, int nb_jobs) \
  603. { \
  604. OverlayContext *s = ctx->priv; \
  605. const int src_w = src->width; \
  606. const int src_h = src->height; \
  607. const int dst_w = dst->width; \
  608. const int dst_h = dst->height; \
  609. \
  610. blend_plane_##depth##_##nbits##bits(ctx, dst, src, src_w, src_h, dst_w, dst_h, 0, 0, 0, \
  611. x, y, main_has_alpha, s->main_desc->comp[0].plane, s->main_desc->comp[0].offset, \
  612. s->main_desc->comp[0].step, is_straight, 1, jobnr, nb_jobs); \
  613. blend_plane_##depth##_##nbits##bits(ctx, dst, src, src_w, src_h, dst_w, dst_h, 1, hsub, vsub, \
  614. x, y, main_has_alpha, s->main_desc->comp[1].plane, s->main_desc->comp[1].offset, \
  615. s->main_desc->comp[1].step, is_straight, 1, jobnr, nb_jobs); \
  616. blend_plane_##depth##_##nbits##bits(ctx, dst, src, src_w, src_h, dst_w, dst_h, 2, hsub, vsub, \
  617. x, y, main_has_alpha, s->main_desc->comp[2].plane, s->main_desc->comp[2].offset, \
  618. s->main_desc->comp[2].step, is_straight, 1, jobnr, nb_jobs); \
  619. \
  620. if (main_has_alpha) \
  621. alpha_composite_##depth##_##nbits##bits(src, dst, src_w, src_h, dst_w, dst_h, x, y, \
  622. jobnr, nb_jobs); \
  623. }
  624. DEFINE_BLEND_SLICE_YUV(8, 8)
  625. DEFINE_BLEND_SLICE_YUV(16, 10)
  626. static av_always_inline void blend_slice_planar_rgb(AVFilterContext *ctx,
  627. AVFrame *dst, const AVFrame *src,
  628. int hsub, int vsub,
  629. int main_has_alpha,
  630. int x, int y,
  631. int is_straight,
  632. int jobnr,
  633. int nb_jobs)
  634. {
  635. OverlayContext *s = ctx->priv;
  636. const int src_w = src->width;
  637. const int src_h = src->height;
  638. const int dst_w = dst->width;
  639. const int dst_h = dst->height;
  640. blend_plane_8_8bits(ctx, dst, src, src_w, src_h, dst_w, dst_h, 0, 0, 0, x, y, main_has_alpha,
  641. s->main_desc->comp[1].plane, s->main_desc->comp[1].offset, s->main_desc->comp[1].step, is_straight, 0,
  642. jobnr, nb_jobs);
  643. blend_plane_8_8bits(ctx, dst, src, src_w, src_h, dst_w, dst_h, 1, hsub, vsub, x, y, main_has_alpha,
  644. s->main_desc->comp[2].plane, s->main_desc->comp[2].offset, s->main_desc->comp[2].step, is_straight, 0,
  645. jobnr, nb_jobs);
  646. blend_plane_8_8bits(ctx, dst, src, src_w, src_h, dst_w, dst_h, 2, hsub, vsub, x, y, main_has_alpha,
  647. s->main_desc->comp[0].plane, s->main_desc->comp[0].offset, s->main_desc->comp[0].step, is_straight, 0,
  648. jobnr, nb_jobs);
  649. if (main_has_alpha)
  650. alpha_composite_8_8bits(src, dst, src_w, src_h, dst_w, dst_h, x, y, jobnr, nb_jobs);
  651. }
  652. static int blend_slice_yuv420(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
  653. {
  654. OverlayContext *s = ctx->priv;
  655. ThreadData *td = arg;
  656. blend_slice_yuv_8_8bits(ctx, td->dst, td->src, 1, 1, 0, s->x, s->y, 1, jobnr, nb_jobs);
  657. return 0;
  658. }
  659. static int blend_slice_yuva420(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
  660. {
  661. OverlayContext *s = ctx->priv;
  662. ThreadData *td = arg;
  663. blend_slice_yuv_8_8bits(ctx, td->dst, td->src, 1, 1, 1, s->x, s->y, 1, jobnr, nb_jobs);
  664. return 0;
  665. }
  666. static int blend_slice_yuv420p10(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
  667. {
  668. OverlayContext *s = ctx->priv;
  669. ThreadData *td = arg;
  670. blend_slice_yuv_16_10bits(ctx, td->dst, td->src, 1, 1, 0, s->x, s->y, 1, jobnr, nb_jobs);
  671. return 0;
  672. }
  673. static int blend_slice_yuva420p10(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
  674. {
  675. OverlayContext *s = ctx->priv;
  676. ThreadData *td = arg;
  677. blend_slice_yuv_16_10bits(ctx, td->dst, td->src, 1, 1, 1, s->x, s->y, 1, jobnr, nb_jobs);
  678. return 0;
  679. }
  680. static int blend_slice_yuv422p10(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
  681. {
  682. OverlayContext *s = ctx->priv;
  683. ThreadData *td = arg;
  684. blend_slice_yuv_16_10bits(ctx, td->dst, td->src, 1, 0, 0, s->x, s->y, 1, jobnr, nb_jobs);
  685. return 0;
  686. }
  687. static int blend_slice_yuva422p10(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
  688. {
  689. OverlayContext *s = ctx->priv;
  690. ThreadData *td = arg;
  691. blend_slice_yuv_16_10bits(ctx, td->dst, td->src, 1, 0, 1, s->x, s->y, 1, jobnr, nb_jobs);
  692. return 0;
  693. }
  694. static int blend_slice_yuv422(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
  695. {
  696. OverlayContext *s = ctx->priv;
  697. ThreadData *td = arg;
  698. blend_slice_yuv_8_8bits(ctx, td->dst, td->src, 1, 0, 0, s->x, s->y, 1, jobnr, nb_jobs);
  699. return 0;
  700. }
  701. static int blend_slice_yuva422(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
  702. {
  703. OverlayContext *s = ctx->priv;
  704. ThreadData *td = arg;
  705. blend_slice_yuv_8_8bits(ctx, td->dst, td->src, 1, 0, 1, s->x, s->y, 1, jobnr, nb_jobs);
  706. return 0;
  707. }
  708. static int blend_slice_yuv444(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
  709. {
  710. OverlayContext *s = ctx->priv;
  711. ThreadData *td = arg;
  712. blend_slice_yuv_8_8bits(ctx, td->dst, td->src, 0, 0, 0, s->x, s->y, 1, jobnr, nb_jobs);
  713. return 0;
  714. }
  715. static int blend_slice_yuva444(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
  716. {
  717. OverlayContext *s = ctx->priv;
  718. ThreadData *td = arg;
  719. blend_slice_yuv_8_8bits(ctx, td->dst, td->src, 0, 0, 1, s->x, s->y, 1, jobnr, nb_jobs);
  720. return 0;
  721. }
  722. static int blend_slice_gbrp(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
  723. {
  724. OverlayContext *s = ctx->priv;
  725. ThreadData *td = arg;
  726. blend_slice_planar_rgb(ctx, td->dst, td->src, 0, 0, 0, s->x, s->y, 1, jobnr, nb_jobs);
  727. return 0;
  728. }
  729. static int blend_slice_gbrap(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
  730. {
  731. OverlayContext *s = ctx->priv;
  732. ThreadData *td = arg;
  733. blend_slice_planar_rgb(ctx, td->dst, td->src, 0, 0, 1, s->x, s->y, 1, jobnr, nb_jobs);
  734. return 0;
  735. }
  736. static int blend_slice_yuv420_pm(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
  737. {
  738. OverlayContext *s = ctx->priv;
  739. ThreadData *td = arg;
  740. blend_slice_yuv_8_8bits(ctx, td->dst, td->src, 1, 1, 0, s->x, s->y, 0, jobnr, nb_jobs);
  741. return 0;
  742. }
  743. static int blend_slice_yuva420_pm(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
  744. {
  745. OverlayContext *s = ctx->priv;
  746. ThreadData *td = arg;
  747. blend_slice_yuv_8_8bits(ctx, td->dst, td->src, 1, 1, 1, s->x, s->y, 0, jobnr, nb_jobs);
  748. return 0;
  749. }
  750. static int blend_slice_yuv422_pm(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
  751. {
  752. OverlayContext *s = ctx->priv;
  753. ThreadData *td = arg;
  754. blend_slice_yuv_8_8bits(ctx, td->dst, td->src, 1, 0, 0, s->x, s->y, 0, jobnr, nb_jobs);
  755. return 0;
  756. }
  757. static int blend_slice_yuva422_pm(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
  758. {
  759. OverlayContext *s = ctx->priv;
  760. ThreadData *td = arg;
  761. blend_slice_yuv_8_8bits(ctx, td->dst, td->src, 1, 0, 1, s->x, s->y, 0, jobnr, nb_jobs);
  762. return 0;
  763. }
  764. static int blend_slice_yuv444_pm(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
  765. {
  766. OverlayContext *s = ctx->priv;
  767. ThreadData *td = arg;
  768. blend_slice_yuv_8_8bits(ctx, td->dst, td->src, 0, 0, 0, s->x, s->y, 0, jobnr, nb_jobs);
  769. return 0;
  770. }
  771. static int blend_slice_yuva444_pm(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
  772. {
  773. OverlayContext *s = ctx->priv;
  774. ThreadData *td = arg;
  775. blend_slice_yuv_8_8bits(ctx, td->dst, td->src, 0, 0, 1, s->x, s->y, 0, jobnr, nb_jobs);
  776. return 0;
  777. }
  778. static int blend_slice_gbrp_pm(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
  779. {
  780. OverlayContext *s = ctx->priv;
  781. ThreadData *td = arg;
  782. blend_slice_planar_rgb(ctx, td->dst, td->src, 0, 0, 0, s->x, s->y, 0, jobnr, nb_jobs);
  783. return 0;
  784. }
  785. static int blend_slice_gbrap_pm(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
  786. {
  787. OverlayContext *s = ctx->priv;
  788. ThreadData *td = arg;
  789. blend_slice_planar_rgb(ctx, td->dst, td->src, 0, 0, 1, s->x, s->y, 0, jobnr, nb_jobs);
  790. return 0;
  791. }
  792. static int blend_slice_rgb(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
  793. {
  794. OverlayContext *s = ctx->priv;
  795. ThreadData *td = arg;
  796. blend_slice_packed_rgb(ctx, td->dst, td->src, 0, s->x, s->y, 1, jobnr, nb_jobs);
  797. return 0;
  798. }
  799. static int blend_slice_rgba(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
  800. {
  801. OverlayContext *s = ctx->priv;
  802. ThreadData *td = arg;
  803. blend_slice_packed_rgb(ctx, td->dst, td->src, 1, s->x, s->y, 1, jobnr, nb_jobs);
  804. return 0;
  805. }
  806. static int blend_slice_rgb_pm(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
  807. {
  808. OverlayContext *s = ctx->priv;
  809. ThreadData *td = arg;
  810. blend_slice_packed_rgb(ctx, td->dst, td->src, 0, s->x, s->y, 0, jobnr, nb_jobs);
  811. return 0;
  812. }
  813. static int blend_slice_rgba_pm(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
  814. {
  815. OverlayContext *s = ctx->priv;
  816. ThreadData *td = arg;
  817. blend_slice_packed_rgb(ctx, td->dst, td->src, 1, s->x, s->y, 0, jobnr, nb_jobs);
  818. return 0;
  819. }
  820. static int config_input_main(AVFilterLink *inlink)
  821. {
  822. OverlayContext *s = inlink->dst->priv;
  823. const AVPixFmtDescriptor *pix_desc = av_pix_fmt_desc_get(inlink->format);
  824. av_image_fill_max_pixsteps(s->main_pix_step, NULL, pix_desc);
  825. s->hsub = pix_desc->log2_chroma_w;
  826. s->vsub = pix_desc->log2_chroma_h;
  827. s->main_desc = pix_desc;
  828. s->main_is_packed_rgb =
  829. ff_fill_rgba_map(s->main_rgba_map, inlink->format) >= 0;
  830. s->main_has_alpha = ff_fmt_is_in(inlink->format, alpha_pix_fmts);
  831. switch (s->format) {
  832. case OVERLAY_FORMAT_YUV420:
  833. s->blend_slice = s->main_has_alpha ? blend_slice_yuva420 : blend_slice_yuv420;
  834. break;
  835. case OVERLAY_FORMAT_YUV420P10:
  836. s->blend_slice = s->main_has_alpha ? blend_slice_yuva420p10 : blend_slice_yuv420p10;
  837. break;
  838. case OVERLAY_FORMAT_YUV422:
  839. s->blend_slice = s->main_has_alpha ? blend_slice_yuva422 : blend_slice_yuv422;
  840. break;
  841. case OVERLAY_FORMAT_YUV422P10:
  842. s->blend_slice = s->main_has_alpha ? blend_slice_yuva422p10 : blend_slice_yuv422p10;
  843. break;
  844. case OVERLAY_FORMAT_YUV444:
  845. s->blend_slice = s->main_has_alpha ? blend_slice_yuva444 : blend_slice_yuv444;
  846. break;
  847. case OVERLAY_FORMAT_RGB:
  848. s->blend_slice = s->main_has_alpha ? blend_slice_rgba : blend_slice_rgb;
  849. break;
  850. case OVERLAY_FORMAT_GBRP:
  851. s->blend_slice = s->main_has_alpha ? blend_slice_gbrap : blend_slice_gbrp;
  852. break;
  853. case OVERLAY_FORMAT_AUTO:
  854. switch (inlink->format) {
  855. case AV_PIX_FMT_YUVA420P:
  856. s->blend_slice = blend_slice_yuva420;
  857. break;
  858. case AV_PIX_FMT_YUVA420P10:
  859. s->blend_slice = blend_slice_yuva420p10;
  860. break;
  861. case AV_PIX_FMT_YUVA422P:
  862. s->blend_slice = blend_slice_yuva422;
  863. break;
  864. case AV_PIX_FMT_YUVA422P10:
  865. s->blend_slice = blend_slice_yuva422p10;
  866. break;
  867. case AV_PIX_FMT_YUVA444P:
  868. s->blend_slice = blend_slice_yuva444;
  869. break;
  870. case AV_PIX_FMT_ARGB:
  871. case AV_PIX_FMT_RGBA:
  872. case AV_PIX_FMT_BGRA:
  873. case AV_PIX_FMT_ABGR:
  874. s->blend_slice = blend_slice_rgba;
  875. break;
  876. case AV_PIX_FMT_GBRAP:
  877. s->blend_slice = blend_slice_gbrap;
  878. break;
  879. default:
  880. av_assert0(0);
  881. break;
  882. }
  883. break;
  884. }
  885. if (!s->alpha_format)
  886. goto end;
  887. switch (s->format) {
  888. case OVERLAY_FORMAT_YUV420:
  889. s->blend_slice = s->main_has_alpha ? blend_slice_yuva420_pm : blend_slice_yuv420_pm;
  890. break;
  891. case OVERLAY_FORMAT_YUV422:
  892. s->blend_slice = s->main_has_alpha ? blend_slice_yuva422_pm : blend_slice_yuv422_pm;
  893. break;
  894. case OVERLAY_FORMAT_YUV444:
  895. s->blend_slice = s->main_has_alpha ? blend_slice_yuva444_pm : blend_slice_yuv444_pm;
  896. break;
  897. case OVERLAY_FORMAT_RGB:
  898. s->blend_slice = s->main_has_alpha ? blend_slice_rgba_pm : blend_slice_rgb_pm;
  899. break;
  900. case OVERLAY_FORMAT_GBRP:
  901. s->blend_slice = s->main_has_alpha ? blend_slice_gbrap_pm : blend_slice_gbrp_pm;
  902. break;
  903. case OVERLAY_FORMAT_AUTO:
  904. switch (inlink->format) {
  905. case AV_PIX_FMT_YUVA420P:
  906. s->blend_slice = blend_slice_yuva420_pm;
  907. break;
  908. case AV_PIX_FMT_YUVA422P:
  909. s->blend_slice = blend_slice_yuva422_pm;
  910. break;
  911. case AV_PIX_FMT_YUVA444P:
  912. s->blend_slice = blend_slice_yuva444_pm;
  913. break;
  914. case AV_PIX_FMT_ARGB:
  915. case AV_PIX_FMT_RGBA:
  916. case AV_PIX_FMT_BGRA:
  917. case AV_PIX_FMT_ABGR:
  918. s->blend_slice = blend_slice_rgba_pm;
  919. break;
  920. case AV_PIX_FMT_GBRAP:
  921. s->blend_slice = blend_slice_gbrap_pm;
  922. break;
  923. default:
  924. av_assert0(0);
  925. break;
  926. }
  927. break;
  928. }
  929. end:
  930. if (ARCH_X86)
  931. ff_overlay_init_x86(s, s->format, inlink->format,
  932. s->alpha_format, s->main_has_alpha);
  933. return 0;
  934. }
  935. static int do_blend(FFFrameSync *fs)
  936. {
  937. AVFilterContext *ctx = fs->parent;
  938. AVFrame *mainpic, *second;
  939. OverlayContext *s = ctx->priv;
  940. AVFilterLink *inlink = ctx->inputs[0];
  941. int ret;
  942. ret = ff_framesync_dualinput_get_writable(fs, &mainpic, &second);
  943. if (ret < 0)
  944. return ret;
  945. if (!second)
  946. return ff_filter_frame(ctx->outputs[0], mainpic);
  947. if (s->eval_mode == EVAL_MODE_FRAME) {
  948. int64_t pos = mainpic->pkt_pos;
  949. s->var_values[VAR_N] = inlink->frame_count_out;
  950. s->var_values[VAR_T] = mainpic->pts == AV_NOPTS_VALUE ?
  951. NAN : mainpic->pts * av_q2d(inlink->time_base);
  952. s->var_values[VAR_POS] = pos == -1 ? NAN : pos;
  953. s->var_values[VAR_OVERLAY_W] = s->var_values[VAR_OW] = second->width;
  954. s->var_values[VAR_OVERLAY_H] = s->var_values[VAR_OH] = second->height;
  955. s->var_values[VAR_MAIN_W ] = s->var_values[VAR_MW] = mainpic->width;
  956. s->var_values[VAR_MAIN_H ] = s->var_values[VAR_MH] = mainpic->height;
  957. eval_expr(ctx);
  958. av_log(ctx, AV_LOG_DEBUG, "n:%f t:%f pos:%f x:%f xi:%d y:%f yi:%d\n",
  959. s->var_values[VAR_N], s->var_values[VAR_T], s->var_values[VAR_POS],
  960. s->var_values[VAR_X], s->x,
  961. s->var_values[VAR_Y], s->y);
  962. }
  963. if (s->x < mainpic->width && s->x + second->width >= 0 &&
  964. s->y < mainpic->height && s->y + second->height >= 0) {
  965. ThreadData td;
  966. td.dst = mainpic;
  967. td.src = second;
  968. ctx->internal->execute(ctx, s->blend_slice, &td, NULL, FFMIN(FFMAX(1, FFMIN3(s->y + second->height, FFMIN(second->height, mainpic->height), mainpic->height - s->y)),
  969. ff_filter_get_nb_threads(ctx)));
  970. }
  971. return ff_filter_frame(ctx->outputs[0], mainpic);
  972. }
  973. static av_cold int init(AVFilterContext *ctx)
  974. {
  975. OverlayContext *s = ctx->priv;
  976. s->fs.on_event = do_blend;
  977. return 0;
  978. }
  979. static int activate(AVFilterContext *ctx)
  980. {
  981. OverlayContext *s = ctx->priv;
  982. return ff_framesync_activate(&s->fs);
  983. }
  984. #define OFFSET(x) offsetof(OverlayContext, x)
  985. #define FLAGS AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_FILTERING_PARAM
  986. static const AVOption overlay_options[] = {
  987. { "x", "set the x expression", OFFSET(x_expr), AV_OPT_TYPE_STRING, {.str = "0"}, 0, 0, FLAGS },
  988. { "y", "set the y expression", OFFSET(y_expr), AV_OPT_TYPE_STRING, {.str = "0"}, 0, 0, FLAGS },
  989. { "eof_action", "Action to take when encountering EOF from secondary input ",
  990. OFFSET(fs.opt_eof_action), AV_OPT_TYPE_INT, { .i64 = EOF_ACTION_REPEAT },
  991. EOF_ACTION_REPEAT, EOF_ACTION_PASS, .flags = FLAGS, "eof_action" },
  992. { "repeat", "Repeat the previous frame.", 0, AV_OPT_TYPE_CONST, { .i64 = EOF_ACTION_REPEAT }, .flags = FLAGS, "eof_action" },
  993. { "endall", "End both streams.", 0, AV_OPT_TYPE_CONST, { .i64 = EOF_ACTION_ENDALL }, .flags = FLAGS, "eof_action" },
  994. { "pass", "Pass through the main input.", 0, AV_OPT_TYPE_CONST, { .i64 = EOF_ACTION_PASS }, .flags = FLAGS, "eof_action" },
  995. { "eval", "specify when to evaluate expressions", OFFSET(eval_mode), AV_OPT_TYPE_INT, {.i64 = EVAL_MODE_FRAME}, 0, EVAL_MODE_NB-1, FLAGS, "eval" },
  996. { "init", "eval expressions once during initialization", 0, AV_OPT_TYPE_CONST, {.i64=EVAL_MODE_INIT}, .flags = FLAGS, .unit = "eval" },
  997. { "frame", "eval expressions per-frame", 0, AV_OPT_TYPE_CONST, {.i64=EVAL_MODE_FRAME}, .flags = FLAGS, .unit = "eval" },
  998. { "shortest", "force termination when the shortest input terminates", OFFSET(fs.opt_shortest), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, FLAGS },
  999. { "format", "set output format", OFFSET(format), AV_OPT_TYPE_INT, {.i64=OVERLAY_FORMAT_YUV420}, 0, OVERLAY_FORMAT_NB-1, FLAGS, "format" },
  1000. { "yuv420", "", 0, AV_OPT_TYPE_CONST, {.i64=OVERLAY_FORMAT_YUV420}, .flags = FLAGS, .unit = "format" },
  1001. { "yuv420p10", "", 0, AV_OPT_TYPE_CONST, {.i64=OVERLAY_FORMAT_YUV420P10}, .flags = FLAGS, .unit = "format" },
  1002. { "yuv422", "", 0, AV_OPT_TYPE_CONST, {.i64=OVERLAY_FORMAT_YUV422}, .flags = FLAGS, .unit = "format" },
  1003. { "yuv422p10", "", 0, AV_OPT_TYPE_CONST, {.i64=OVERLAY_FORMAT_YUV422P10}, .flags = FLAGS, .unit = "format" },
  1004. { "yuv444", "", 0, AV_OPT_TYPE_CONST, {.i64=OVERLAY_FORMAT_YUV444}, .flags = FLAGS, .unit = "format" },
  1005. { "rgb", "", 0, AV_OPT_TYPE_CONST, {.i64=OVERLAY_FORMAT_RGB}, .flags = FLAGS, .unit = "format" },
  1006. { "gbrp", "", 0, AV_OPT_TYPE_CONST, {.i64=OVERLAY_FORMAT_GBRP}, .flags = FLAGS, .unit = "format" },
  1007. { "auto", "", 0, AV_OPT_TYPE_CONST, {.i64=OVERLAY_FORMAT_AUTO}, .flags = FLAGS, .unit = "format" },
  1008. { "repeatlast", "repeat overlay of the last overlay frame", OFFSET(fs.opt_repeatlast), AV_OPT_TYPE_BOOL, {.i64=1}, 0, 1, FLAGS },
  1009. { "alpha", "alpha format", OFFSET(alpha_format), AV_OPT_TYPE_INT, {.i64=0}, 0, 1, FLAGS, "alpha_format" },
  1010. { "straight", "", 0, AV_OPT_TYPE_CONST, {.i64=0}, .flags = FLAGS, .unit = "alpha_format" },
  1011. { "premultiplied", "", 0, AV_OPT_TYPE_CONST, {.i64=1}, .flags = FLAGS, .unit = "alpha_format" },
  1012. { NULL }
  1013. };
  1014. FRAMESYNC_DEFINE_CLASS(overlay, OverlayContext, fs);
  1015. static const AVFilterPad avfilter_vf_overlay_inputs[] = {
  1016. {
  1017. .name = "main",
  1018. .type = AVMEDIA_TYPE_VIDEO,
  1019. .config_props = config_input_main,
  1020. },
  1021. {
  1022. .name = "overlay",
  1023. .type = AVMEDIA_TYPE_VIDEO,
  1024. .config_props = config_input_overlay,
  1025. },
  1026. { NULL }
  1027. };
  1028. static const AVFilterPad avfilter_vf_overlay_outputs[] = {
  1029. {
  1030. .name = "default",
  1031. .type = AVMEDIA_TYPE_VIDEO,
  1032. .config_props = config_output,
  1033. },
  1034. { NULL }
  1035. };
  1036. AVFilter ff_vf_overlay = {
  1037. .name = "overlay",
  1038. .description = NULL_IF_CONFIG_SMALL("Overlay a video source on top of the input."),
  1039. .preinit = overlay_framesync_preinit,
  1040. .init = init,
  1041. .uninit = uninit,
  1042. .priv_size = sizeof(OverlayContext),
  1043. .priv_class = &overlay_class,
  1044. .query_formats = query_formats,
  1045. .activate = activate,
  1046. .process_command = process_command,
  1047. .inputs = avfilter_vf_overlay_inputs,
  1048. .outputs = avfilter_vf_overlay_outputs,
  1049. .flags = AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL |
  1050. AVFILTER_FLAG_SLICE_THREADS,
  1051. };