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.

757 lines
25KB

  1. /*
  2. * Copyright (c) 2016 Paul B Mahol
  3. *
  4. * This file is part of FFmpeg.
  5. *
  6. * FFmpeg is free software; you can redistribute it and/or
  7. * modify it under the terms of the GNU Lesser General Public
  8. * License as published by the Free Software Foundation; either
  9. * version 2.1 of the License, or (at your option) any later version.
  10. *
  11. * FFmpeg is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  14. * Lesser General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU Lesser General Public
  17. * License along with FFmpeg; if not, write to the Free Software
  18. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  19. */
  20. #include "libavutil/imgutils.h"
  21. #include "libavutil/pixdesc.h"
  22. #include "libavutil/opt.h"
  23. #include "avfilter.h"
  24. #include "filters.h"
  25. #include "formats.h"
  26. #include "framesync.h"
  27. #include "internal.h"
  28. #include "video.h"
  29. typedef struct ThreadData {
  30. AVFrame *m, *a, *d;
  31. } ThreadData;
  32. typedef struct PreMultiplyContext {
  33. const AVClass *class;
  34. int width[4], height[4];
  35. int linesize[4];
  36. int nb_planes;
  37. int planes;
  38. int inverse;
  39. int inplace;
  40. int half, depth, offset, max;
  41. FFFrameSync fs;
  42. void (*premultiply[4])(const uint8_t *msrc, const uint8_t *asrc,
  43. uint8_t *dst,
  44. ptrdiff_t mlinesize, ptrdiff_t alinesize,
  45. ptrdiff_t dlinesize,
  46. int w, int h,
  47. int half, int shift, int offset);
  48. } PreMultiplyContext;
  49. #define OFFSET(x) offsetof(PreMultiplyContext, x)
  50. #define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM
  51. static const AVOption options[] = {
  52. { "planes", "set planes", OFFSET(planes), AV_OPT_TYPE_INT, {.i64=0xF}, 0, 0xF, FLAGS },
  53. { "inplace","enable inplace mode", OFFSET(inplace), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS },
  54. { NULL }
  55. };
  56. #define premultiply_options options
  57. AVFILTER_DEFINE_CLASS(premultiply);
  58. static int query_formats(AVFilterContext *ctx)
  59. {
  60. PreMultiplyContext *s = ctx->priv;
  61. static const enum AVPixelFormat no_alpha_pix_fmts[] = {
  62. AV_PIX_FMT_YUV444P, AV_PIX_FMT_YUVJ444P,
  63. AV_PIX_FMT_YUV444P9, AV_PIX_FMT_YUV444P10,
  64. AV_PIX_FMT_YUV444P12, AV_PIX_FMT_YUV444P14,
  65. AV_PIX_FMT_YUV444P16,
  66. AV_PIX_FMT_GBRP, AV_PIX_FMT_GBRP9, AV_PIX_FMT_GBRP10,
  67. AV_PIX_FMT_GBRP12, AV_PIX_FMT_GBRP14, AV_PIX_FMT_GBRP16,
  68. AV_PIX_FMT_GRAY8, AV_PIX_FMT_GRAY9, AV_PIX_FMT_GRAY10, AV_PIX_FMT_GRAY12, AV_PIX_FMT_GRAY16,
  69. AV_PIX_FMT_NONE
  70. };
  71. static const enum AVPixelFormat alpha_pix_fmts[] = {
  72. AV_PIX_FMT_YUVA444P,
  73. AV_PIX_FMT_YUVA444P9, AV_PIX_FMT_YUVA444P10, AV_PIX_FMT_YUVA444P16,
  74. AV_PIX_FMT_GBRAP,
  75. AV_PIX_FMT_GBRAP10, AV_PIX_FMT_GBRAP12, AV_PIX_FMT_GBRAP16,
  76. AV_PIX_FMT_NONE
  77. };
  78. return ff_set_common_formats(ctx, ff_make_format_list(s->inplace ? alpha_pix_fmts : no_alpha_pix_fmts));
  79. }
  80. static void premultiply8(const uint8_t *msrc, const uint8_t *asrc,
  81. uint8_t *dst,
  82. ptrdiff_t mlinesize, ptrdiff_t alinesize,
  83. ptrdiff_t dlinesize,
  84. int w, int h,
  85. int half, int shift, int offset)
  86. {
  87. int x, y;
  88. for (y = 0; y < h; y++) {
  89. for (x = 0; x < w; x++) {
  90. dst[x] = ((msrc[x] * (((asrc[x] >> 1) & 1) + asrc[x])) + 128) >> 8;
  91. }
  92. dst += dlinesize;
  93. msrc += mlinesize;
  94. asrc += alinesize;
  95. }
  96. }
  97. static void premultiply8yuv(const uint8_t *msrc, const uint8_t *asrc,
  98. uint8_t *dst,
  99. ptrdiff_t mlinesize, ptrdiff_t alinesize,
  100. ptrdiff_t dlinesize,
  101. int w, int h,
  102. int half, int shift, int offset)
  103. {
  104. int x, y;
  105. for (y = 0; y < h; y++) {
  106. for (x = 0; x < w; x++) {
  107. dst[x] = ((((msrc[x] - 128) * (((asrc[x] >> 1) & 1) + asrc[x]))) >> 8) + 128;
  108. }
  109. dst += dlinesize;
  110. msrc += mlinesize;
  111. asrc += alinesize;
  112. }
  113. }
  114. static void premultiply8offset(const uint8_t *msrc, const uint8_t *asrc,
  115. uint8_t *dst,
  116. ptrdiff_t mlinesize, ptrdiff_t alinesize,
  117. ptrdiff_t dlinesize,
  118. int w, int h,
  119. int half, int shift, int offset)
  120. {
  121. int x, y;
  122. for (y = 0; y < h; y++) {
  123. for (x = 0; x < w; x++) {
  124. dst[x] = ((((msrc[x] - offset) * (((asrc[x] >> 1) & 1) + asrc[x])) + 128) >> 8) + offset;
  125. }
  126. dst += dlinesize;
  127. msrc += mlinesize;
  128. asrc += alinesize;
  129. }
  130. }
  131. static void premultiply16(const uint8_t *mmsrc, const uint8_t *aasrc,
  132. uint8_t *ddst,
  133. ptrdiff_t mlinesize, ptrdiff_t alinesize,
  134. ptrdiff_t dlinesize,
  135. int w, int h,
  136. int half, int shift, int offset)
  137. {
  138. const uint16_t *msrc = (const uint16_t *)mmsrc;
  139. const uint16_t *asrc = (const uint16_t *)aasrc;
  140. uint16_t *dst = (uint16_t *)ddst;
  141. int x, y;
  142. for (y = 0; y < h; y++) {
  143. for (x = 0; x < w; x++) {
  144. dst[x] = ((msrc[x] * (((asrc[x] >> 1) & 1) + asrc[x])) + half) >> shift;
  145. }
  146. dst += dlinesize / 2;
  147. msrc += mlinesize / 2;
  148. asrc += alinesize / 2;
  149. }
  150. }
  151. static void premultiply16yuv(const uint8_t *mmsrc, const uint8_t *aasrc,
  152. uint8_t *ddst,
  153. ptrdiff_t mlinesize, ptrdiff_t alinesize,
  154. ptrdiff_t dlinesize,
  155. int w, int h,
  156. int half, int shift, int offset)
  157. {
  158. const uint16_t *msrc = (const uint16_t *)mmsrc;
  159. const uint16_t *asrc = (const uint16_t *)aasrc;
  160. uint16_t *dst = (uint16_t *)ddst;
  161. int x, y;
  162. for (y = 0; y < h; y++) {
  163. for (x = 0; x < w; x++) {
  164. dst[x] = ((((msrc[x] - half) * (((asrc[x] >> 1) & 1) + asrc[x]))) >> shift) + half;
  165. }
  166. dst += dlinesize / 2;
  167. msrc += mlinesize / 2;
  168. asrc += alinesize / 2;
  169. }
  170. }
  171. static void premultiply16offset(const uint8_t *mmsrc, const uint8_t *aasrc,
  172. uint8_t *ddst,
  173. ptrdiff_t mlinesize, ptrdiff_t alinesize,
  174. ptrdiff_t dlinesize,
  175. int w, int h,
  176. int half, int shift, int offset)
  177. {
  178. const uint16_t *msrc = (const uint16_t *)mmsrc;
  179. const uint16_t *asrc = (const uint16_t *)aasrc;
  180. uint16_t *dst = (uint16_t *)ddst;
  181. int x, y;
  182. for (y = 0; y < h; y++) {
  183. for (x = 0; x < w; x++) {
  184. dst[x] = ((((msrc[x] - offset) * (((asrc[x] >> 1) & 1) + asrc[x])) + half) >> shift) + offset;
  185. }
  186. dst += dlinesize / 2;
  187. msrc += mlinesize / 2;
  188. asrc += alinesize / 2;
  189. }
  190. }
  191. static void unpremultiply8(const uint8_t *msrc, const uint8_t *asrc,
  192. uint8_t *dst,
  193. ptrdiff_t mlinesize, ptrdiff_t alinesize,
  194. ptrdiff_t dlinesize,
  195. int w, int h,
  196. int half, int max, int offset)
  197. {
  198. int x, y;
  199. for (y = 0; y < h; y++) {
  200. for (x = 0; x < w; x++) {
  201. if (asrc[x] > 0 && asrc[x] < 255)
  202. dst[x] = FFMIN(msrc[x] * 255 / asrc[x], 255);
  203. else
  204. dst[x] = msrc[x];
  205. }
  206. dst += dlinesize;
  207. msrc += mlinesize;
  208. asrc += alinesize;
  209. }
  210. }
  211. static void unpremultiply8yuv(const uint8_t *msrc, const uint8_t *asrc,
  212. uint8_t *dst,
  213. ptrdiff_t mlinesize, ptrdiff_t alinesize,
  214. ptrdiff_t dlinesize,
  215. int w, int h,
  216. int half, int max, int offset)
  217. {
  218. int x, y;
  219. for (y = 0; y < h; y++) {
  220. for (x = 0; x < w; x++) {
  221. if (asrc[x] > 0 && asrc[x] < 255)
  222. dst[x] = FFMIN((msrc[x] - 128) * 255 / asrc[x] + 128, 255);
  223. else
  224. dst[x] = msrc[x];
  225. }
  226. dst += dlinesize;
  227. msrc += mlinesize;
  228. asrc += alinesize;
  229. }
  230. }
  231. static void unpremultiply8offset(const uint8_t *msrc, const uint8_t *asrc,
  232. uint8_t *dst,
  233. ptrdiff_t mlinesize, ptrdiff_t alinesize,
  234. ptrdiff_t dlinesize,
  235. int w, int h,
  236. int half, int max, int offset)
  237. {
  238. int x, y;
  239. for (y = 0; y < h; y++) {
  240. for (x = 0; x < w; x++) {
  241. if (asrc[x] > 0 && asrc[x] < 255)
  242. dst[x] = FFMIN(FFMAX(msrc[x] - offset, 0) * 255 / asrc[x] + offset, 255);
  243. else
  244. dst[x] = msrc[x];
  245. }
  246. dst += dlinesize;
  247. msrc += mlinesize;
  248. asrc += alinesize;
  249. }
  250. }
  251. static void unpremultiply16(const uint8_t *mmsrc, const uint8_t *aasrc,
  252. uint8_t *ddst,
  253. ptrdiff_t mlinesize, ptrdiff_t alinesize,
  254. ptrdiff_t dlinesize,
  255. int w, int h,
  256. int half, int max, int offset)
  257. {
  258. const uint16_t *msrc = (const uint16_t *)mmsrc;
  259. const uint16_t *asrc = (const uint16_t *)aasrc;
  260. uint16_t *dst = (uint16_t *)ddst;
  261. int x, y;
  262. for (y = 0; y < h; y++) {
  263. for (x = 0; x < w; x++) {
  264. if (asrc[x] > 0 && asrc[x] < max)
  265. dst[x] = FFMIN(msrc[x] * (unsigned)max / asrc[x], max);
  266. else
  267. dst[x] = msrc[x];
  268. }
  269. dst += dlinesize / 2;
  270. msrc += mlinesize / 2;
  271. asrc += alinesize / 2;
  272. }
  273. }
  274. static void unpremultiply16yuv(const uint8_t *mmsrc, const uint8_t *aasrc,
  275. uint8_t *ddst,
  276. ptrdiff_t mlinesize, ptrdiff_t alinesize,
  277. ptrdiff_t dlinesize,
  278. int w, int h,
  279. int half, int max, int offset)
  280. {
  281. const uint16_t *msrc = (const uint16_t *)mmsrc;
  282. const uint16_t *asrc = (const uint16_t *)aasrc;
  283. uint16_t *dst = (uint16_t *)ddst;
  284. int x, y;
  285. for (y = 0; y < h; y++) {
  286. for (x = 0; x < w; x++) {
  287. if (asrc[x] > 0 && asrc[x] < max)
  288. dst[x] = FFMAX(FFMIN((msrc[x] - half) * max / asrc[x], half - 1), -half) + half;
  289. else
  290. dst[x] = msrc[x];
  291. }
  292. dst += dlinesize / 2;
  293. msrc += mlinesize / 2;
  294. asrc += alinesize / 2;
  295. }
  296. }
  297. static void unpremultiply16offset(const uint8_t *mmsrc, const uint8_t *aasrc,
  298. uint8_t *ddst,
  299. ptrdiff_t mlinesize, ptrdiff_t alinesize,
  300. ptrdiff_t dlinesize,
  301. int w, int h,
  302. int half, int max, int offset)
  303. {
  304. const uint16_t *msrc = (const uint16_t *)mmsrc;
  305. const uint16_t *asrc = (const uint16_t *)aasrc;
  306. uint16_t *dst = (uint16_t *)ddst;
  307. int x, y;
  308. for (y = 0; y < h; y++) {
  309. for (x = 0; x < w; x++) {
  310. if (asrc[x] > 0 && asrc[x] < max)
  311. dst[x] = FFMAX(FFMIN(FFMAX(msrc[x] - offset, 0) * (unsigned)max / asrc[x] + offset, max), 0);
  312. else
  313. dst[x] = msrc[x];
  314. }
  315. dst += dlinesize / 2;
  316. msrc += mlinesize / 2;
  317. asrc += alinesize / 2;
  318. }
  319. }
  320. static int premultiply_slice(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
  321. {
  322. PreMultiplyContext *s = ctx->priv;
  323. ThreadData *td = arg;
  324. AVFrame *out = td->d;
  325. AVFrame *alpha = td->a;
  326. AVFrame *base = td->m;
  327. int p;
  328. for (p = 0; p < s->nb_planes; p++) {
  329. const int slice_start = (s->height[p] * jobnr) / nb_jobs;
  330. const int slice_end = (s->height[p] * (jobnr+1)) / nb_jobs;
  331. if (!((1 << p) & s->planes) || p == 3) {
  332. av_image_copy_plane(out->data[p] + slice_start * out->linesize[p],
  333. out->linesize[p],
  334. base->data[p] + slice_start * base->linesize[p],
  335. base->linesize[p],
  336. s->linesize[p], slice_end - slice_start);
  337. continue;
  338. }
  339. s->premultiply[p](base->data[p] + slice_start * base->linesize[p],
  340. s->inplace ? alpha->data[3] + slice_start * alpha->linesize[3] :
  341. alpha->data[0] + slice_start * alpha->linesize[0],
  342. out->data[p] + slice_start * out->linesize[p],
  343. base->linesize[p], s->inplace ? alpha->linesize[3] : alpha->linesize[0],
  344. out->linesize[p],
  345. s->width[p], slice_end - slice_start,
  346. s->half, s->inverse ? s->max : s->depth, s->offset);
  347. }
  348. return 0;
  349. }
  350. static int filter_frame(AVFilterContext *ctx,
  351. AVFrame **out, AVFrame *base, AVFrame *alpha)
  352. {
  353. PreMultiplyContext *s = ctx->priv;
  354. AVFilterLink *outlink = ctx->outputs[0];
  355. if (ctx->is_disabled) {
  356. *out = av_frame_clone(base);
  357. if (!*out)
  358. return AVERROR(ENOMEM);
  359. } else {
  360. ThreadData td;
  361. int full, limited;
  362. *out = ff_get_video_buffer(outlink, outlink->w, outlink->h);
  363. if (!*out)
  364. return AVERROR(ENOMEM);
  365. av_frame_copy_props(*out, base);
  366. full = base->color_range == AVCOL_RANGE_JPEG;
  367. limited = base->color_range == AVCOL_RANGE_MPEG;
  368. if (s->inverse) {
  369. switch (outlink->format) {
  370. case AV_PIX_FMT_YUV444P:
  371. case AV_PIX_FMT_YUVA444P:
  372. s->premultiply[0] = full ? unpremultiply8 : unpremultiply8offset;
  373. s->premultiply[1] = s->premultiply[2] = unpremultiply8yuv;
  374. break;
  375. case AV_PIX_FMT_YUVJ444P:
  376. s->premultiply[0] = unpremultiply8;
  377. s->premultiply[1] = s->premultiply[2] = unpremultiply8yuv;
  378. break;
  379. case AV_PIX_FMT_GBRP:
  380. case AV_PIX_FMT_GBRAP:
  381. s->premultiply[0] = s->premultiply[1] = s->premultiply[2] = limited ? unpremultiply8offset : unpremultiply8;
  382. break;
  383. case AV_PIX_FMT_YUV444P9:
  384. case AV_PIX_FMT_YUVA444P9:
  385. case AV_PIX_FMT_YUV444P10:
  386. case AV_PIX_FMT_YUVA444P10:
  387. case AV_PIX_FMT_YUV444P12:
  388. case AV_PIX_FMT_YUV444P14:
  389. case AV_PIX_FMT_YUV444P16:
  390. case AV_PIX_FMT_YUVA444P16:
  391. s->premultiply[0] = full ? unpremultiply16 : unpremultiply16offset;
  392. s->premultiply[1] = s->premultiply[2] = unpremultiply16yuv;
  393. break;
  394. case AV_PIX_FMT_GBRP9:
  395. case AV_PIX_FMT_GBRP10:
  396. case AV_PIX_FMT_GBRAP10:
  397. case AV_PIX_FMT_GBRP12:
  398. case AV_PIX_FMT_GBRAP12:
  399. case AV_PIX_FMT_GBRP14:
  400. case AV_PIX_FMT_GBRP16:
  401. case AV_PIX_FMT_GBRAP16:
  402. s->premultiply[0] = s->premultiply[1] = s->premultiply[2] = limited ? unpremultiply16offset : unpremultiply16;
  403. break;
  404. case AV_PIX_FMT_GRAY8:
  405. s->premultiply[0] = limited ? unpremultiply8offset : unpremultiply8;
  406. break;
  407. case AV_PIX_FMT_GRAY9:
  408. case AV_PIX_FMT_GRAY10:
  409. case AV_PIX_FMT_GRAY12:
  410. case AV_PIX_FMT_GRAY16:
  411. s->premultiply[0] = limited ? unpremultiply16offset : unpremultiply16;
  412. break;
  413. }
  414. } else {
  415. switch (outlink->format) {
  416. case AV_PIX_FMT_YUV444P:
  417. case AV_PIX_FMT_YUVA444P:
  418. s->premultiply[0] = full ? premultiply8 : premultiply8offset;
  419. s->premultiply[1] = s->premultiply[2] = premultiply8yuv;
  420. break;
  421. case AV_PIX_FMT_YUVJ444P:
  422. s->premultiply[0] = premultiply8;
  423. s->premultiply[1] = s->premultiply[2] = premultiply8yuv;
  424. break;
  425. case AV_PIX_FMT_GBRP:
  426. case AV_PIX_FMT_GBRAP:
  427. s->premultiply[0] = s->premultiply[1] = s->premultiply[2] = limited ? premultiply8offset : premultiply8;
  428. break;
  429. case AV_PIX_FMT_YUV444P9:
  430. case AV_PIX_FMT_YUVA444P9:
  431. case AV_PIX_FMT_YUV444P10:
  432. case AV_PIX_FMT_YUVA444P10:
  433. case AV_PIX_FMT_YUV444P12:
  434. case AV_PIX_FMT_YUV444P14:
  435. case AV_PIX_FMT_YUV444P16:
  436. case AV_PIX_FMT_YUVA444P16:
  437. s->premultiply[0] = full ? premultiply16 : premultiply16offset;
  438. s->premultiply[1] = s->premultiply[2] = premultiply16yuv;
  439. break;
  440. case AV_PIX_FMT_GBRP9:
  441. case AV_PIX_FMT_GBRP10:
  442. case AV_PIX_FMT_GBRAP10:
  443. case AV_PIX_FMT_GBRP12:
  444. case AV_PIX_FMT_GBRAP12:
  445. case AV_PIX_FMT_GBRP14:
  446. case AV_PIX_FMT_GBRP16:
  447. case AV_PIX_FMT_GBRAP16:
  448. s->premultiply[0] = s->premultiply[1] = s->premultiply[2] = limited ? premultiply16offset : premultiply16;
  449. break;
  450. case AV_PIX_FMT_GRAY8:
  451. s->premultiply[0] = limited ? premultiply8offset : premultiply8;
  452. break;
  453. case AV_PIX_FMT_GRAY9:
  454. case AV_PIX_FMT_GRAY10:
  455. case AV_PIX_FMT_GRAY12:
  456. case AV_PIX_FMT_GRAY16:
  457. s->premultiply[0] = limited ? premultiply16offset : premultiply16;
  458. break;
  459. }
  460. }
  461. td.d = *out;
  462. td.a = alpha;
  463. td.m = base;
  464. ctx->internal->execute(ctx, premultiply_slice, &td, NULL, FFMIN(s->height[0],
  465. ff_filter_get_nb_threads(ctx)));
  466. }
  467. return 0;
  468. }
  469. static int process_frame(FFFrameSync *fs)
  470. {
  471. AVFilterContext *ctx = fs->parent;
  472. PreMultiplyContext *s = fs->opaque;
  473. AVFilterLink *outlink = ctx->outputs[0];
  474. AVFrame *out = NULL, *base, *alpha;
  475. int ret;
  476. if ((ret = ff_framesync_get_frame(&s->fs, 0, &base, 0)) < 0 ||
  477. (ret = ff_framesync_get_frame(&s->fs, 1, &alpha, 0)) < 0)
  478. return ret;
  479. if ((ret = filter_frame(ctx, &out, base, alpha)) < 0)
  480. return ret;
  481. out->pts = av_rescale_q(base->pts, s->fs.time_base, outlink->time_base);
  482. return ff_filter_frame(outlink, out);
  483. }
  484. static int config_input(AVFilterLink *inlink)
  485. {
  486. AVFilterContext *ctx = inlink->dst;
  487. PreMultiplyContext *s = ctx->priv;
  488. const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(inlink->format);
  489. int vsub, hsub, ret;
  490. s->nb_planes = av_pix_fmt_count_planes(inlink->format);
  491. if ((ret = av_image_fill_linesizes(s->linesize, inlink->format, inlink->w)) < 0)
  492. return ret;
  493. hsub = desc->log2_chroma_w;
  494. vsub = desc->log2_chroma_h;
  495. s->height[1] = s->height[2] = AV_CEIL_RSHIFT(inlink->h, vsub);
  496. s->height[0] = s->height[3] = inlink->h;
  497. s->width[1] = s->width[2] = AV_CEIL_RSHIFT(inlink->w, hsub);
  498. s->width[0] = s->width[3] = inlink->w;
  499. s->depth = desc->comp[0].depth;
  500. s->max = (1 << s->depth) - 1;
  501. s->half = (1 << s->depth) / 2;
  502. s->offset = 16 << (s->depth - 8);
  503. return 0;
  504. }
  505. static int config_output(AVFilterLink *outlink)
  506. {
  507. AVFilterContext *ctx = outlink->src;
  508. PreMultiplyContext *s = ctx->priv;
  509. AVFilterLink *base = ctx->inputs[0];
  510. AVFilterLink *alpha;
  511. FFFrameSyncIn *in;
  512. int ret;
  513. if (!s->inplace) {
  514. alpha = ctx->inputs[1];
  515. if (base->format != alpha->format) {
  516. av_log(ctx, AV_LOG_ERROR, "inputs must be of same pixel format\n");
  517. return AVERROR(EINVAL);
  518. }
  519. if (base->w != alpha->w ||
  520. base->h != alpha->h) {
  521. av_log(ctx, AV_LOG_ERROR, "First input link %s parameters "
  522. "(size %dx%d) do not match the corresponding "
  523. "second input link %s parameters (%dx%d) ",
  524. ctx->input_pads[0].name, base->w, base->h,
  525. ctx->input_pads[1].name, alpha->w, alpha->h);
  526. return AVERROR(EINVAL);
  527. }
  528. }
  529. outlink->w = base->w;
  530. outlink->h = base->h;
  531. outlink->time_base = base->time_base;
  532. outlink->sample_aspect_ratio = base->sample_aspect_ratio;
  533. outlink->frame_rate = base->frame_rate;
  534. if (s->inplace)
  535. return 0;
  536. if ((ret = ff_framesync_init(&s->fs, ctx, 2)) < 0)
  537. return ret;
  538. in = s->fs.in;
  539. in[0].time_base = base->time_base;
  540. in[1].time_base = alpha->time_base;
  541. in[0].sync = 1;
  542. in[0].before = EXT_STOP;
  543. in[0].after = EXT_INFINITY;
  544. in[1].sync = 1;
  545. in[1].before = EXT_STOP;
  546. in[1].after = EXT_INFINITY;
  547. s->fs.opaque = s;
  548. s->fs.on_event = process_frame;
  549. return ff_framesync_configure(&s->fs);
  550. }
  551. static int activate(AVFilterContext *ctx)
  552. {
  553. PreMultiplyContext *s = ctx->priv;
  554. if (s->inplace) {
  555. AVFrame *frame = NULL;
  556. AVFrame *out = NULL;
  557. int ret, status;
  558. int64_t pts;
  559. if ((ret = ff_inlink_consume_frame(ctx->inputs[0], &frame)) > 0) {
  560. ret = filter_frame(ctx, &out, frame, frame);
  561. av_frame_free(&frame);
  562. if (ret < 0)
  563. return ret;
  564. ret = ff_filter_frame(ctx->outputs[0], out);
  565. }
  566. if (ret < 0) {
  567. return ret;
  568. } else if (ff_inlink_acknowledge_status(ctx->inputs[0], &status, &pts)) {
  569. ff_outlink_set_status(ctx->outputs[0], status, pts);
  570. return 0;
  571. } else {
  572. if (ff_outlink_frame_wanted(ctx->outputs[0]))
  573. ff_inlink_request_frame(ctx->inputs[0]);
  574. return 0;
  575. }
  576. } else {
  577. return ff_framesync_activate(&s->fs);
  578. }
  579. }
  580. static av_cold int init(AVFilterContext *ctx)
  581. {
  582. PreMultiplyContext *s = ctx->priv;
  583. AVFilterPad pad = { 0 };
  584. int ret;
  585. if (!strcmp(ctx->filter->name, "unpremultiply"))
  586. s->inverse = 1;
  587. pad.type = AVMEDIA_TYPE_VIDEO;
  588. pad.name = av_strdup("main");
  589. pad.config_props = config_input;
  590. if (!pad.name)
  591. return AVERROR(ENOMEM);
  592. if ((ret = ff_insert_inpad(ctx, 0, &pad)) < 0) {
  593. av_freep(&pad.name);
  594. return ret;
  595. }
  596. if (!s->inplace) {
  597. pad.type = AVMEDIA_TYPE_VIDEO;
  598. pad.name = av_strdup("alpha");
  599. pad.config_props = NULL;
  600. if (!pad.name)
  601. return AVERROR(ENOMEM);
  602. if ((ret = ff_insert_inpad(ctx, 1, &pad)) < 0) {
  603. av_freep(&pad.name);
  604. return ret;
  605. }
  606. }
  607. return 0;
  608. }
  609. static av_cold void uninit(AVFilterContext *ctx)
  610. {
  611. PreMultiplyContext *s = ctx->priv;
  612. if (!s->inplace)
  613. ff_framesync_uninit(&s->fs);
  614. }
  615. static const AVFilterPad premultiply_outputs[] = {
  616. {
  617. .name = "default",
  618. .type = AVMEDIA_TYPE_VIDEO,
  619. .config_props = config_output,
  620. },
  621. { NULL }
  622. };
  623. #if CONFIG_PREMULTIPLY_FILTER
  624. AVFilter ff_vf_premultiply = {
  625. .name = "premultiply",
  626. .description = NULL_IF_CONFIG_SMALL("PreMultiply first stream with first plane of second stream."),
  627. .priv_size = sizeof(PreMultiplyContext),
  628. .init = init,
  629. .uninit = uninit,
  630. .query_formats = query_formats,
  631. .activate = activate,
  632. .inputs = NULL,
  633. .outputs = premultiply_outputs,
  634. .priv_class = &premultiply_class,
  635. .flags = AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL |
  636. AVFILTER_FLAG_DYNAMIC_INPUTS |
  637. AVFILTER_FLAG_SLICE_THREADS,
  638. };
  639. #endif /* CONFIG_PREMULTIPLY_FILTER */
  640. #if CONFIG_UNPREMULTIPLY_FILTER
  641. #define unpremultiply_options options
  642. AVFILTER_DEFINE_CLASS(unpremultiply);
  643. AVFilter ff_vf_unpremultiply = {
  644. .name = "unpremultiply",
  645. .description = NULL_IF_CONFIG_SMALL("UnPreMultiply first stream with first plane of second stream."),
  646. .priv_size = sizeof(PreMultiplyContext),
  647. .init = init,
  648. .uninit = uninit,
  649. .query_formats = query_formats,
  650. .activate = activate,
  651. .inputs = NULL,
  652. .outputs = premultiply_outputs,
  653. .priv_class = &unpremultiply_class,
  654. .flags = AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL |
  655. AVFILTER_FLAG_DYNAMIC_INPUTS |
  656. AVFILTER_FLAG_SLICE_THREADS,
  657. };
  658. #endif /* CONFIG_UNPREMULTIPLY_FILTER */