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.

867 lines
28KB

  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, AV_PIX_FMT_GBRPF32,
  68. AV_PIX_FMT_GRAY8, AV_PIX_FMT_GRAY9, AV_PIX_FMT_GRAY10, AV_PIX_FMT_GRAY12, AV_PIX_FMT_GRAY14, 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_YUVA444P12, AV_PIX_FMT_YUVA444P16,
  74. AV_PIX_FMT_GBRAP,
  75. AV_PIX_FMT_GBRAP10, AV_PIX_FMT_GBRAP12, AV_PIX_FMT_GBRAP16, AV_PIX_FMT_GBRAPF32,
  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) * (int64_t)(((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) * (int64_t)(((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 premultiplyf32(const uint8_t *mmsrc, const uint8_t *aasrc,
  192. uint8_t *ddst,
  193. ptrdiff_t mlinesize, ptrdiff_t alinesize,
  194. ptrdiff_t dlinesize,
  195. int w, int h,
  196. int half, int shift, int offset)
  197. {
  198. const float *msrc = (const float *)mmsrc;
  199. const float *asrc = (const float *)aasrc;
  200. float *dst = (float *)ddst;
  201. int x, y;
  202. for (y = 0; y < h; y++) {
  203. for (x = 0; x < w; x++) {
  204. dst[x] = msrc[x] * asrc[x];
  205. }
  206. dst += dlinesize / 4;
  207. msrc += mlinesize / 4;
  208. asrc += alinesize / 4;
  209. }
  210. }
  211. static void premultiplyf32offset(const uint8_t *mmsrc, const uint8_t *aasrc,
  212. uint8_t *ddst,
  213. ptrdiff_t mlinesize, ptrdiff_t alinesize,
  214. ptrdiff_t dlinesize,
  215. int w, int h,
  216. int half, int shift, int offset)
  217. {
  218. const float *msrc = (const float *)mmsrc;
  219. const float *asrc = (const float *)aasrc;
  220. float *dst = (float *)ddst;
  221. int x, y;
  222. float offsetf = offset / 65535.0f;
  223. for (y = 0; y < h; y++) {
  224. for (x = 0; x < w; x++) {
  225. dst[x] = ((msrc[x] - offsetf) * asrc[x]) + offsetf;
  226. }
  227. dst += dlinesize / 4;
  228. msrc += mlinesize / 4;
  229. asrc += alinesize / 4;
  230. }
  231. }
  232. static void unpremultiply8(const uint8_t *msrc, const uint8_t *asrc,
  233. uint8_t *dst,
  234. ptrdiff_t mlinesize, ptrdiff_t alinesize,
  235. ptrdiff_t dlinesize,
  236. int w, int h,
  237. int half, int max, int offset)
  238. {
  239. int x, y;
  240. for (y = 0; y < h; y++) {
  241. for (x = 0; x < w; x++) {
  242. if (asrc[x] > 0 && asrc[x] < 255)
  243. dst[x] = FFMIN(msrc[x] * 255 / asrc[x], 255);
  244. else
  245. dst[x] = msrc[x];
  246. }
  247. dst += dlinesize;
  248. msrc += mlinesize;
  249. asrc += alinesize;
  250. }
  251. }
  252. static void unpremultiply8yuv(const uint8_t *msrc, const uint8_t *asrc,
  253. uint8_t *dst,
  254. ptrdiff_t mlinesize, ptrdiff_t alinesize,
  255. ptrdiff_t dlinesize,
  256. int w, int h,
  257. int half, int max, int offset)
  258. {
  259. int x, y;
  260. for (y = 0; y < h; y++) {
  261. for (x = 0; x < w; x++) {
  262. if (asrc[x] > 0 && asrc[x] < 255)
  263. dst[x] = FFMIN((msrc[x] - 128) * 255 / asrc[x] + 128, 255);
  264. else
  265. dst[x] = msrc[x];
  266. }
  267. dst += dlinesize;
  268. msrc += mlinesize;
  269. asrc += alinesize;
  270. }
  271. }
  272. static void unpremultiply8offset(const uint8_t *msrc, const uint8_t *asrc,
  273. uint8_t *dst,
  274. ptrdiff_t mlinesize, ptrdiff_t alinesize,
  275. ptrdiff_t dlinesize,
  276. int w, int h,
  277. int half, int max, int offset)
  278. {
  279. int x, y;
  280. for (y = 0; y < h; y++) {
  281. for (x = 0; x < w; x++) {
  282. if (asrc[x] > 0 && asrc[x] < 255)
  283. dst[x] = FFMIN(FFMAX(msrc[x] - offset, 0) * 255 / asrc[x] + offset, 255);
  284. else
  285. dst[x] = msrc[x];
  286. }
  287. dst += dlinesize;
  288. msrc += mlinesize;
  289. asrc += alinesize;
  290. }
  291. }
  292. static void unpremultiply16(const uint8_t *mmsrc, const uint8_t *aasrc,
  293. uint8_t *ddst,
  294. ptrdiff_t mlinesize, ptrdiff_t alinesize,
  295. ptrdiff_t dlinesize,
  296. int w, int h,
  297. int half, int max, int offset)
  298. {
  299. const uint16_t *msrc = (const uint16_t *)mmsrc;
  300. const uint16_t *asrc = (const uint16_t *)aasrc;
  301. uint16_t *dst = (uint16_t *)ddst;
  302. int x, y;
  303. for (y = 0; y < h; y++) {
  304. for (x = 0; x < w; x++) {
  305. if (asrc[x] > 0 && asrc[x] < max)
  306. dst[x] = FFMIN(msrc[x] * (unsigned)max / asrc[x], max);
  307. else
  308. dst[x] = msrc[x];
  309. }
  310. dst += dlinesize / 2;
  311. msrc += mlinesize / 2;
  312. asrc += alinesize / 2;
  313. }
  314. }
  315. static void unpremultiply16yuv(const uint8_t *mmsrc, const uint8_t *aasrc,
  316. uint8_t *ddst,
  317. ptrdiff_t mlinesize, ptrdiff_t alinesize,
  318. ptrdiff_t dlinesize,
  319. int w, int h,
  320. int half, int max, int offset)
  321. {
  322. const uint16_t *msrc = (const uint16_t *)mmsrc;
  323. const uint16_t *asrc = (const uint16_t *)aasrc;
  324. uint16_t *dst = (uint16_t *)ddst;
  325. int x, y;
  326. for (y = 0; y < h; y++) {
  327. for (x = 0; x < w; x++) {
  328. if (asrc[x] > 0 && asrc[x] < max)
  329. dst[x] = FFMAX(FFMIN((msrc[x] - half) * max / asrc[x], half - 1), -half) + half;
  330. else
  331. dst[x] = msrc[x];
  332. }
  333. dst += dlinesize / 2;
  334. msrc += mlinesize / 2;
  335. asrc += alinesize / 2;
  336. }
  337. }
  338. static void unpremultiply16offset(const uint8_t *mmsrc, const uint8_t *aasrc,
  339. uint8_t *ddst,
  340. ptrdiff_t mlinesize, ptrdiff_t alinesize,
  341. ptrdiff_t dlinesize,
  342. int w, int h,
  343. int half, int max, int offset)
  344. {
  345. const uint16_t *msrc = (const uint16_t *)mmsrc;
  346. const uint16_t *asrc = (const uint16_t *)aasrc;
  347. uint16_t *dst = (uint16_t *)ddst;
  348. int x, y;
  349. for (y = 0; y < h; y++) {
  350. for (x = 0; x < w; x++) {
  351. if (asrc[x] > 0 && asrc[x] < max)
  352. dst[x] = FFMAX(FFMIN(FFMAX(msrc[x] - offset, 0) * (unsigned)max / asrc[x] + offset, max), 0);
  353. else
  354. dst[x] = msrc[x];
  355. }
  356. dst += dlinesize / 2;
  357. msrc += mlinesize / 2;
  358. asrc += alinesize / 2;
  359. }
  360. }
  361. static void unpremultiplyf32(const uint8_t *mmsrc, const uint8_t *aasrc,
  362. uint8_t *ddst,
  363. ptrdiff_t mlinesize, ptrdiff_t alinesize,
  364. ptrdiff_t dlinesize,
  365. int w, int h,
  366. int half, int max, int offset)
  367. {
  368. const float *msrc = (const float *)mmsrc;
  369. const float *asrc = (const float *)aasrc;
  370. float *dst = (float *)ddst;
  371. int x, y;
  372. for (y = 0; y < h; y++) {
  373. for (x = 0; x < w; x++) {
  374. if (asrc[x] > 0.0f)
  375. dst[x] = msrc[x] / asrc[x];
  376. else
  377. dst[x] = msrc[x];
  378. }
  379. dst += dlinesize / 4;
  380. msrc += mlinesize / 4;
  381. asrc += alinesize / 4;
  382. }
  383. }
  384. static void unpremultiplyf32offset(const uint8_t *mmsrc, const uint8_t *aasrc,
  385. uint8_t *ddst,
  386. ptrdiff_t mlinesize, ptrdiff_t alinesize,
  387. ptrdiff_t dlinesize,
  388. int w, int h,
  389. int half, int max, int offset)
  390. {
  391. const float *msrc = (const float *)mmsrc;
  392. const float *asrc = (const float *)aasrc;
  393. float *dst = (float *)ddst;
  394. int x, y;
  395. float offsetf = offset / 65535.0f;
  396. for (y = 0; y < h; y++) {
  397. for (x = 0; x < w; x++) {
  398. if (asrc[x] > 0.0f)
  399. dst[x] = (msrc[x] - offsetf) / asrc[x] + offsetf;
  400. else
  401. dst[x] = msrc[x];
  402. }
  403. dst += dlinesize / 4;
  404. msrc += mlinesize / 4;
  405. asrc += alinesize / 4;
  406. }
  407. }
  408. static int premultiply_slice(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
  409. {
  410. PreMultiplyContext *s = ctx->priv;
  411. ThreadData *td = arg;
  412. AVFrame *out = td->d;
  413. AVFrame *alpha = td->a;
  414. AVFrame *base = td->m;
  415. int p;
  416. for (p = 0; p < s->nb_planes; p++) {
  417. const int slice_start = (s->height[p] * jobnr) / nb_jobs;
  418. const int slice_end = (s->height[p] * (jobnr+1)) / nb_jobs;
  419. if (!((1 << p) & s->planes) || p == 3) {
  420. av_image_copy_plane(out->data[p] + slice_start * out->linesize[p],
  421. out->linesize[p],
  422. base->data[p] + slice_start * base->linesize[p],
  423. base->linesize[p],
  424. s->linesize[p], slice_end - slice_start);
  425. continue;
  426. }
  427. s->premultiply[p](base->data[p] + slice_start * base->linesize[p],
  428. s->inplace ? alpha->data[3] + slice_start * alpha->linesize[3] :
  429. alpha->data[0] + slice_start * alpha->linesize[0],
  430. out->data[p] + slice_start * out->linesize[p],
  431. base->linesize[p], s->inplace ? alpha->linesize[3] : alpha->linesize[0],
  432. out->linesize[p],
  433. s->width[p], slice_end - slice_start,
  434. s->half, s->inverse ? s->max : s->depth, s->offset);
  435. }
  436. return 0;
  437. }
  438. static int filter_frame(AVFilterContext *ctx,
  439. AVFrame **out, AVFrame *base, AVFrame *alpha)
  440. {
  441. PreMultiplyContext *s = ctx->priv;
  442. AVFilterLink *outlink = ctx->outputs[0];
  443. if (ctx->is_disabled) {
  444. *out = av_frame_clone(base);
  445. if (!*out)
  446. return AVERROR(ENOMEM);
  447. } else {
  448. ThreadData td;
  449. int full, limited;
  450. *out = ff_get_video_buffer(outlink, outlink->w, outlink->h);
  451. if (!*out)
  452. return AVERROR(ENOMEM);
  453. av_frame_copy_props(*out, base);
  454. full = base->color_range == AVCOL_RANGE_JPEG;
  455. limited = base->color_range == AVCOL_RANGE_MPEG;
  456. if (s->inverse) {
  457. switch (outlink->format) {
  458. case AV_PIX_FMT_YUV444P:
  459. case AV_PIX_FMT_YUVA444P:
  460. s->premultiply[0] = full ? unpremultiply8 : unpremultiply8offset;
  461. s->premultiply[1] = s->premultiply[2] = unpremultiply8yuv;
  462. break;
  463. case AV_PIX_FMT_YUVJ444P:
  464. s->premultiply[0] = unpremultiply8;
  465. s->premultiply[1] = s->premultiply[2] = unpremultiply8yuv;
  466. break;
  467. case AV_PIX_FMT_GBRP:
  468. case AV_PIX_FMT_GBRAP:
  469. s->premultiply[0] = s->premultiply[1] = s->premultiply[2] = limited ? unpremultiply8offset : unpremultiply8;
  470. break;
  471. case AV_PIX_FMT_YUV444P9:
  472. case AV_PIX_FMT_YUVA444P9:
  473. case AV_PIX_FMT_YUV444P10:
  474. case AV_PIX_FMT_YUVA444P10:
  475. case AV_PIX_FMT_YUV444P12:
  476. case AV_PIX_FMT_YUVA444P12:
  477. case AV_PIX_FMT_YUV444P14:
  478. case AV_PIX_FMT_YUV444P16:
  479. case AV_PIX_FMT_YUVA444P16:
  480. s->premultiply[0] = full ? unpremultiply16 : unpremultiply16offset;
  481. s->premultiply[1] = s->premultiply[2] = unpremultiply16yuv;
  482. break;
  483. case AV_PIX_FMT_GBRP9:
  484. case AV_PIX_FMT_GBRP10:
  485. case AV_PIX_FMT_GBRAP10:
  486. case AV_PIX_FMT_GBRP12:
  487. case AV_PIX_FMT_GBRAP12:
  488. case AV_PIX_FMT_GBRP14:
  489. case AV_PIX_FMT_GBRP16:
  490. case AV_PIX_FMT_GBRAP16:
  491. s->premultiply[0] = s->premultiply[1] = s->premultiply[2] = limited ? unpremultiply16offset : unpremultiply16;
  492. break;
  493. case AV_PIX_FMT_GBRPF32:
  494. case AV_PIX_FMT_GBRAPF32:
  495. s->premultiply[0] = s->premultiply[1] = s->premultiply[2] = limited ? unpremultiplyf32offset : unpremultiplyf32;
  496. break;
  497. case AV_PIX_FMT_GRAY8:
  498. s->premultiply[0] = limited ? unpremultiply8offset : unpremultiply8;
  499. break;
  500. case AV_PIX_FMT_GRAY9:
  501. case AV_PIX_FMT_GRAY10:
  502. case AV_PIX_FMT_GRAY12:
  503. case AV_PIX_FMT_GRAY14:
  504. case AV_PIX_FMT_GRAY16:
  505. s->premultiply[0] = limited ? unpremultiply16offset : unpremultiply16;
  506. break;
  507. }
  508. } else {
  509. switch (outlink->format) {
  510. case AV_PIX_FMT_YUV444P:
  511. case AV_PIX_FMT_YUVA444P:
  512. s->premultiply[0] = full ? premultiply8 : premultiply8offset;
  513. s->premultiply[1] = s->premultiply[2] = premultiply8yuv;
  514. break;
  515. case AV_PIX_FMT_YUVJ444P:
  516. s->premultiply[0] = premultiply8;
  517. s->premultiply[1] = s->premultiply[2] = premultiply8yuv;
  518. break;
  519. case AV_PIX_FMT_GBRP:
  520. case AV_PIX_FMT_GBRAP:
  521. s->premultiply[0] = s->premultiply[1] = s->premultiply[2] = limited ? premultiply8offset : premultiply8;
  522. break;
  523. case AV_PIX_FMT_YUV444P9:
  524. case AV_PIX_FMT_YUVA444P9:
  525. case AV_PIX_FMT_YUV444P10:
  526. case AV_PIX_FMT_YUVA444P10:
  527. case AV_PIX_FMT_YUV444P12:
  528. case AV_PIX_FMT_YUVA444P12:
  529. case AV_PIX_FMT_YUV444P14:
  530. case AV_PIX_FMT_YUV444P16:
  531. case AV_PIX_FMT_YUVA444P16:
  532. s->premultiply[0] = full ? premultiply16 : premultiply16offset;
  533. s->premultiply[1] = s->premultiply[2] = premultiply16yuv;
  534. break;
  535. case AV_PIX_FMT_GBRP9:
  536. case AV_PIX_FMT_GBRP10:
  537. case AV_PIX_FMT_GBRAP10:
  538. case AV_PIX_FMT_GBRP12:
  539. case AV_PIX_FMT_GBRAP12:
  540. case AV_PIX_FMT_GBRP14:
  541. case AV_PIX_FMT_GBRP16:
  542. case AV_PIX_FMT_GBRAP16:
  543. s->premultiply[0] = s->premultiply[1] = s->premultiply[2] = limited ? premultiply16offset : premultiply16;
  544. break;
  545. case AV_PIX_FMT_GBRPF32:
  546. case AV_PIX_FMT_GBRAPF32:
  547. s->premultiply[0] = s->premultiply[1] = s->premultiply[2] = limited ? premultiplyf32offset: premultiplyf32;
  548. break;
  549. case AV_PIX_FMT_GRAY8:
  550. s->premultiply[0] = limited ? premultiply8offset : premultiply8;
  551. break;
  552. case AV_PIX_FMT_GRAY9:
  553. case AV_PIX_FMT_GRAY10:
  554. case AV_PIX_FMT_GRAY12:
  555. case AV_PIX_FMT_GRAY14:
  556. case AV_PIX_FMT_GRAY16:
  557. s->premultiply[0] = limited ? premultiply16offset : premultiply16;
  558. break;
  559. }
  560. }
  561. td.d = *out;
  562. td.a = alpha;
  563. td.m = base;
  564. ctx->internal->execute(ctx, premultiply_slice, &td, NULL, FFMIN(s->height[0],
  565. ff_filter_get_nb_threads(ctx)));
  566. }
  567. return 0;
  568. }
  569. static int process_frame(FFFrameSync *fs)
  570. {
  571. AVFilterContext *ctx = fs->parent;
  572. PreMultiplyContext *s = fs->opaque;
  573. AVFilterLink *outlink = ctx->outputs[0];
  574. AVFrame *out = NULL, *base, *alpha;
  575. int ret;
  576. if ((ret = ff_framesync_get_frame(&s->fs, 0, &base, 0)) < 0 ||
  577. (ret = ff_framesync_get_frame(&s->fs, 1, &alpha, 0)) < 0)
  578. return ret;
  579. if ((ret = filter_frame(ctx, &out, base, alpha)) < 0)
  580. return ret;
  581. out->pts = av_rescale_q(base->pts, s->fs.time_base, outlink->time_base);
  582. return ff_filter_frame(outlink, out);
  583. }
  584. static int config_input(AVFilterLink *inlink)
  585. {
  586. AVFilterContext *ctx = inlink->dst;
  587. PreMultiplyContext *s = ctx->priv;
  588. const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(inlink->format);
  589. int vsub, hsub, ret;
  590. s->nb_planes = av_pix_fmt_count_planes(inlink->format);
  591. if ((ret = av_image_fill_linesizes(s->linesize, inlink->format, inlink->w)) < 0)
  592. return ret;
  593. hsub = desc->log2_chroma_w;
  594. vsub = desc->log2_chroma_h;
  595. s->height[1] = s->height[2] = AV_CEIL_RSHIFT(inlink->h, vsub);
  596. s->height[0] = s->height[3] = inlink->h;
  597. s->width[1] = s->width[2] = AV_CEIL_RSHIFT(inlink->w, hsub);
  598. s->width[0] = s->width[3] = inlink->w;
  599. s->depth = desc->flags & AV_PIX_FMT_FLAG_FLOAT ? 16 : desc->comp[0].depth;
  600. s->max = (1 << s->depth) - 1;
  601. s->half = (1 << s->depth) / 2;
  602. s->offset = 16 << (s->depth - 8);
  603. return 0;
  604. }
  605. static int config_output(AVFilterLink *outlink)
  606. {
  607. AVFilterContext *ctx = outlink->src;
  608. PreMultiplyContext *s = ctx->priv;
  609. AVFilterLink *base = ctx->inputs[0];
  610. AVFilterLink *alpha;
  611. FFFrameSyncIn *in;
  612. int ret;
  613. if (!s->inplace) {
  614. alpha = ctx->inputs[1];
  615. if (base->format != alpha->format) {
  616. av_log(ctx, AV_LOG_ERROR, "inputs must be of same pixel format\n");
  617. return AVERROR(EINVAL);
  618. }
  619. if (base->w != alpha->w ||
  620. base->h != alpha->h) {
  621. av_log(ctx, AV_LOG_ERROR, "First input link %s parameters "
  622. "(size %dx%d) do not match the corresponding "
  623. "second input link %s parameters (%dx%d) ",
  624. ctx->input_pads[0].name, base->w, base->h,
  625. ctx->input_pads[1].name, alpha->w, alpha->h);
  626. return AVERROR(EINVAL);
  627. }
  628. }
  629. outlink->w = base->w;
  630. outlink->h = base->h;
  631. outlink->time_base = base->time_base;
  632. outlink->sample_aspect_ratio = base->sample_aspect_ratio;
  633. outlink->frame_rate = base->frame_rate;
  634. if (s->inplace)
  635. return 0;
  636. if ((ret = ff_framesync_init(&s->fs, ctx, 2)) < 0)
  637. return ret;
  638. in = s->fs.in;
  639. in[0].time_base = base->time_base;
  640. in[1].time_base = alpha->time_base;
  641. in[0].sync = 1;
  642. in[0].before = EXT_STOP;
  643. in[0].after = EXT_INFINITY;
  644. in[1].sync = 1;
  645. in[1].before = EXT_STOP;
  646. in[1].after = EXT_INFINITY;
  647. s->fs.opaque = s;
  648. s->fs.on_event = process_frame;
  649. return ff_framesync_configure(&s->fs);
  650. }
  651. static int activate(AVFilterContext *ctx)
  652. {
  653. PreMultiplyContext *s = ctx->priv;
  654. if (s->inplace) {
  655. AVFrame *frame = NULL;
  656. AVFrame *out = NULL;
  657. int ret, status;
  658. int64_t pts;
  659. FF_FILTER_FORWARD_STATUS_BACK_ALL(ctx->outputs[0], ctx);
  660. if ((ret = ff_inlink_consume_frame(ctx->inputs[0], &frame)) > 0) {
  661. ret = filter_frame(ctx, &out, frame, frame);
  662. av_frame_free(&frame);
  663. if (ret < 0)
  664. return ret;
  665. ret = ff_filter_frame(ctx->outputs[0], out);
  666. }
  667. if (ret < 0) {
  668. return ret;
  669. } else if (ff_inlink_acknowledge_status(ctx->inputs[0], &status, &pts)) {
  670. ff_outlink_set_status(ctx->outputs[0], status, pts);
  671. return 0;
  672. } else {
  673. if (ff_outlink_frame_wanted(ctx->outputs[0]))
  674. ff_inlink_request_frame(ctx->inputs[0]);
  675. return 0;
  676. }
  677. } else {
  678. return ff_framesync_activate(&s->fs);
  679. }
  680. }
  681. static av_cold int init(AVFilterContext *ctx)
  682. {
  683. PreMultiplyContext *s = ctx->priv;
  684. AVFilterPad pad = { 0 };
  685. int ret;
  686. if (!strcmp(ctx->filter->name, "unpremultiply"))
  687. s->inverse = 1;
  688. pad.type = AVMEDIA_TYPE_VIDEO;
  689. pad.name = "main";
  690. pad.config_props = config_input;
  691. if ((ret = ff_insert_inpad(ctx, 0, &pad)) < 0)
  692. return ret;
  693. if (!s->inplace) {
  694. pad.type = AVMEDIA_TYPE_VIDEO;
  695. pad.name = "alpha";
  696. pad.config_props = NULL;
  697. if ((ret = ff_insert_inpad(ctx, 1, &pad)) < 0)
  698. return ret;
  699. }
  700. return 0;
  701. }
  702. static av_cold void uninit(AVFilterContext *ctx)
  703. {
  704. PreMultiplyContext *s = ctx->priv;
  705. if (!s->inplace)
  706. ff_framesync_uninit(&s->fs);
  707. }
  708. static const AVFilterPad premultiply_outputs[] = {
  709. {
  710. .name = "default",
  711. .type = AVMEDIA_TYPE_VIDEO,
  712. .config_props = config_output,
  713. },
  714. { NULL }
  715. };
  716. #if CONFIG_PREMULTIPLY_FILTER
  717. AVFilter ff_vf_premultiply = {
  718. .name = "premultiply",
  719. .description = NULL_IF_CONFIG_SMALL("PreMultiply first stream with first plane of second stream."),
  720. .priv_size = sizeof(PreMultiplyContext),
  721. .init = init,
  722. .uninit = uninit,
  723. .query_formats = query_formats,
  724. .activate = activate,
  725. .inputs = NULL,
  726. .outputs = premultiply_outputs,
  727. .priv_class = &premultiply_class,
  728. .flags = AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL |
  729. AVFILTER_FLAG_DYNAMIC_INPUTS |
  730. AVFILTER_FLAG_SLICE_THREADS,
  731. };
  732. #endif /* CONFIG_PREMULTIPLY_FILTER */
  733. #if CONFIG_UNPREMULTIPLY_FILTER
  734. #define unpremultiply_options options
  735. AVFILTER_DEFINE_CLASS(unpremultiply);
  736. AVFilter ff_vf_unpremultiply = {
  737. .name = "unpremultiply",
  738. .description = NULL_IF_CONFIG_SMALL("UnPreMultiply first stream with first plane of second stream."),
  739. .priv_size = sizeof(PreMultiplyContext),
  740. .init = init,
  741. .uninit = uninit,
  742. .query_formats = query_formats,
  743. .activate = activate,
  744. .inputs = NULL,
  745. .outputs = premultiply_outputs,
  746. .priv_class = &unpremultiply_class,
  747. .flags = AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL |
  748. AVFILTER_FLAG_DYNAMIC_INPUTS |
  749. AVFILTER_FLAG_SLICE_THREADS,
  750. };
  751. #endif /* CONFIG_UNPREMULTIPLY_FILTER */