vf_premultiply.c 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758
  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_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_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_GRAY14:
  411. case AV_PIX_FMT_GRAY16:
  412. s->premultiply[0] = limited ? unpremultiply16offset : unpremultiply16;
  413. break;
  414. }
  415. } else {
  416. switch (outlink->format) {
  417. case AV_PIX_FMT_YUV444P:
  418. case AV_PIX_FMT_YUVA444P:
  419. s->premultiply[0] = full ? premultiply8 : premultiply8offset;
  420. s->premultiply[1] = s->premultiply[2] = premultiply8yuv;
  421. break;
  422. case AV_PIX_FMT_YUVJ444P:
  423. s->premultiply[0] = premultiply8;
  424. s->premultiply[1] = s->premultiply[2] = premultiply8yuv;
  425. break;
  426. case AV_PIX_FMT_GBRP:
  427. case AV_PIX_FMT_GBRAP:
  428. s->premultiply[0] = s->premultiply[1] = s->premultiply[2] = limited ? premultiply8offset : premultiply8;
  429. break;
  430. case AV_PIX_FMT_YUV444P9:
  431. case AV_PIX_FMT_YUVA444P9:
  432. case AV_PIX_FMT_YUV444P10:
  433. case AV_PIX_FMT_YUVA444P10:
  434. case AV_PIX_FMT_YUV444P12:
  435. case AV_PIX_FMT_YUV444P14:
  436. case AV_PIX_FMT_YUV444P16:
  437. case AV_PIX_FMT_YUVA444P16:
  438. s->premultiply[0] = full ? premultiply16 : premultiply16offset;
  439. s->premultiply[1] = s->premultiply[2] = premultiply16yuv;
  440. break;
  441. case AV_PIX_FMT_GBRP9:
  442. case AV_PIX_FMT_GBRP10:
  443. case AV_PIX_FMT_GBRAP10:
  444. case AV_PIX_FMT_GBRP12:
  445. case AV_PIX_FMT_GBRAP12:
  446. case AV_PIX_FMT_GBRP14:
  447. case AV_PIX_FMT_GBRP16:
  448. case AV_PIX_FMT_GBRAP16:
  449. s->premultiply[0] = s->premultiply[1] = s->premultiply[2] = limited ? premultiply16offset : premultiply16;
  450. break;
  451. case AV_PIX_FMT_GRAY8:
  452. s->premultiply[0] = limited ? premultiply8offset : premultiply8;
  453. break;
  454. case AV_PIX_FMT_GRAY9:
  455. case AV_PIX_FMT_GRAY10:
  456. case AV_PIX_FMT_GRAY12:
  457. case AV_PIX_FMT_GRAY14:
  458. case AV_PIX_FMT_GRAY16:
  459. s->premultiply[0] = limited ? premultiply16offset : premultiply16;
  460. break;
  461. }
  462. }
  463. td.d = *out;
  464. td.a = alpha;
  465. td.m = base;
  466. ctx->internal->execute(ctx, premultiply_slice, &td, NULL, FFMIN(s->height[0],
  467. ff_filter_get_nb_threads(ctx)));
  468. }
  469. return 0;
  470. }
  471. static int process_frame(FFFrameSync *fs)
  472. {
  473. AVFilterContext *ctx = fs->parent;
  474. PreMultiplyContext *s = fs->opaque;
  475. AVFilterLink *outlink = ctx->outputs[0];
  476. AVFrame *out = NULL, *base, *alpha;
  477. int ret;
  478. if ((ret = ff_framesync_get_frame(&s->fs, 0, &base, 0)) < 0 ||
  479. (ret = ff_framesync_get_frame(&s->fs, 1, &alpha, 0)) < 0)
  480. return ret;
  481. if ((ret = filter_frame(ctx, &out, base, alpha)) < 0)
  482. return ret;
  483. out->pts = av_rescale_q(base->pts, s->fs.time_base, outlink->time_base);
  484. return ff_filter_frame(outlink, out);
  485. }
  486. static int config_input(AVFilterLink *inlink)
  487. {
  488. AVFilterContext *ctx = inlink->dst;
  489. PreMultiplyContext *s = ctx->priv;
  490. const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(inlink->format);
  491. int vsub, hsub, ret;
  492. s->nb_planes = av_pix_fmt_count_planes(inlink->format);
  493. if ((ret = av_image_fill_linesizes(s->linesize, inlink->format, inlink->w)) < 0)
  494. return ret;
  495. hsub = desc->log2_chroma_w;
  496. vsub = desc->log2_chroma_h;
  497. s->height[1] = s->height[2] = AV_CEIL_RSHIFT(inlink->h, vsub);
  498. s->height[0] = s->height[3] = inlink->h;
  499. s->width[1] = s->width[2] = AV_CEIL_RSHIFT(inlink->w, hsub);
  500. s->width[0] = s->width[3] = inlink->w;
  501. s->depth = desc->comp[0].depth;
  502. s->max = (1 << s->depth) - 1;
  503. s->half = (1 << s->depth) / 2;
  504. s->offset = 16 << (s->depth - 8);
  505. return 0;
  506. }
  507. static int config_output(AVFilterLink *outlink)
  508. {
  509. AVFilterContext *ctx = outlink->src;
  510. PreMultiplyContext *s = ctx->priv;
  511. AVFilterLink *base = ctx->inputs[0];
  512. AVFilterLink *alpha;
  513. FFFrameSyncIn *in;
  514. int ret;
  515. if (!s->inplace) {
  516. alpha = ctx->inputs[1];
  517. if (base->format != alpha->format) {
  518. av_log(ctx, AV_LOG_ERROR, "inputs must be of same pixel format\n");
  519. return AVERROR(EINVAL);
  520. }
  521. if (base->w != alpha->w ||
  522. base->h != alpha->h) {
  523. av_log(ctx, AV_LOG_ERROR, "First input link %s parameters "
  524. "(size %dx%d) do not match the corresponding "
  525. "second input link %s parameters (%dx%d) ",
  526. ctx->input_pads[0].name, base->w, base->h,
  527. ctx->input_pads[1].name, alpha->w, alpha->h);
  528. return AVERROR(EINVAL);
  529. }
  530. }
  531. outlink->w = base->w;
  532. outlink->h = base->h;
  533. outlink->time_base = base->time_base;
  534. outlink->sample_aspect_ratio = base->sample_aspect_ratio;
  535. outlink->frame_rate = base->frame_rate;
  536. if (s->inplace)
  537. return 0;
  538. if ((ret = ff_framesync_init(&s->fs, ctx, 2)) < 0)
  539. return ret;
  540. in = s->fs.in;
  541. in[0].time_base = base->time_base;
  542. in[1].time_base = alpha->time_base;
  543. in[0].sync = 1;
  544. in[0].before = EXT_STOP;
  545. in[0].after = EXT_INFINITY;
  546. in[1].sync = 1;
  547. in[1].before = EXT_STOP;
  548. in[1].after = EXT_INFINITY;
  549. s->fs.opaque = s;
  550. s->fs.on_event = process_frame;
  551. return ff_framesync_configure(&s->fs);
  552. }
  553. static int activate(AVFilterContext *ctx)
  554. {
  555. PreMultiplyContext *s = ctx->priv;
  556. if (s->inplace) {
  557. AVFrame *frame = NULL;
  558. AVFrame *out = NULL;
  559. int ret, status;
  560. int64_t pts;
  561. if ((ret = ff_inlink_consume_frame(ctx->inputs[0], &frame)) > 0) {
  562. ret = filter_frame(ctx, &out, frame, frame);
  563. av_frame_free(&frame);
  564. if (ret < 0)
  565. return ret;
  566. ret = ff_filter_frame(ctx->outputs[0], out);
  567. }
  568. if (ret < 0) {
  569. return ret;
  570. } else if (ff_inlink_acknowledge_status(ctx->inputs[0], &status, &pts)) {
  571. ff_outlink_set_status(ctx->outputs[0], status, pts);
  572. return 0;
  573. } else {
  574. if (ff_outlink_frame_wanted(ctx->outputs[0]))
  575. ff_inlink_request_frame(ctx->inputs[0]);
  576. return 0;
  577. }
  578. } else {
  579. return ff_framesync_activate(&s->fs);
  580. }
  581. }
  582. static av_cold int init(AVFilterContext *ctx)
  583. {
  584. PreMultiplyContext *s = ctx->priv;
  585. AVFilterPad pad = { 0 };
  586. int ret;
  587. if (!strcmp(ctx->filter->name, "unpremultiply"))
  588. s->inverse = 1;
  589. pad.type = AVMEDIA_TYPE_VIDEO;
  590. pad.name = av_strdup("main");
  591. pad.config_props = config_input;
  592. if (!pad.name)
  593. return AVERROR(ENOMEM);
  594. if ((ret = ff_insert_inpad(ctx, 0, &pad)) < 0) {
  595. av_freep(&pad.name);
  596. return ret;
  597. }
  598. if (!s->inplace) {
  599. pad.type = AVMEDIA_TYPE_VIDEO;
  600. pad.name = av_strdup("alpha");
  601. pad.config_props = NULL;
  602. if (!pad.name)
  603. return AVERROR(ENOMEM);
  604. if ((ret = ff_insert_inpad(ctx, 1, &pad)) < 0) {
  605. av_freep(&pad.name);
  606. return ret;
  607. }
  608. }
  609. return 0;
  610. }
  611. static av_cold void uninit(AVFilterContext *ctx)
  612. {
  613. PreMultiplyContext *s = ctx->priv;
  614. if (!s->inplace)
  615. ff_framesync_uninit(&s->fs);
  616. }
  617. static const AVFilterPad premultiply_outputs[] = {
  618. {
  619. .name = "default",
  620. .type = AVMEDIA_TYPE_VIDEO,
  621. .config_props = config_output,
  622. },
  623. { NULL }
  624. };
  625. #if CONFIG_PREMULTIPLY_FILTER
  626. AVFilter ff_vf_premultiply = {
  627. .name = "premultiply",
  628. .description = NULL_IF_CONFIG_SMALL("PreMultiply first stream with first plane of second stream."),
  629. .priv_size = sizeof(PreMultiplyContext),
  630. .init = init,
  631. .uninit = uninit,
  632. .query_formats = query_formats,
  633. .activate = activate,
  634. .inputs = NULL,
  635. .outputs = premultiply_outputs,
  636. .priv_class = &premultiply_class,
  637. .flags = AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL |
  638. AVFILTER_FLAG_DYNAMIC_INPUTS |
  639. AVFILTER_FLAG_SLICE_THREADS,
  640. };
  641. #endif /* CONFIG_PREMULTIPLY_FILTER */
  642. #if CONFIG_UNPREMULTIPLY_FILTER
  643. #define unpremultiply_options options
  644. AVFILTER_DEFINE_CLASS(unpremultiply);
  645. AVFilter ff_vf_unpremultiply = {
  646. .name = "unpremultiply",
  647. .description = NULL_IF_CONFIG_SMALL("UnPreMultiply first stream with first plane of second stream."),
  648. .priv_size = sizeof(PreMultiplyContext),
  649. .init = init,
  650. .uninit = uninit,
  651. .query_formats = query_formats,
  652. .activate = activate,
  653. .inputs = NULL,
  654. .outputs = premultiply_outputs,
  655. .priv_class = &unpremultiply_class,
  656. .flags = AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL |
  657. AVFILTER_FLAG_DYNAMIC_INPUTS |
  658. AVFILTER_FLAG_SLICE_THREADS,
  659. };
  660. #endif /* CONFIG_UNPREMULTIPLY_FILTER */