FFmpeg
drawutils.c
Go to the documentation of this file.
1 /*
2  * Copyright 2011 Stefano Sabatini <stefano.sabatini-lala poste it>
3  * Copyright 2012 Nicolas George <nicolas.george normalesup org>
4  *
5  * This file is part of FFmpeg.
6  *
7  * FFmpeg is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * FFmpeg is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with FFmpeg; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20  */
21 
22 #include <string.h>
23 
24 #include "libavutil/avassert.h"
25 #include "libavutil/avutil.h"
26 #include "libavutil/csp.h"
27 #include "libavutil/intreadwrite.h"
28 #include "libavutil/pixdesc.h"
29 #include "colorspace.h"
30 #include "drawutils.h"
31 #include "formats.h"
32 
33 enum { RED = 0, GREEN, BLUE, ALPHA };
34 
35 static int fill_map(const AVPixFmtDescriptor *desc, uint8_t *map)
36 {
39  return AVERROR(EINVAL);
40  av_assert0(desc->nb_components == 3 + !!(desc->flags & AV_PIX_FMT_FLAG_ALPHA));
41  if (desc->flags & AV_PIX_FMT_FLAG_PLANAR) {
43  return AVERROR(EINVAL);
44  map[RED] = desc->comp[0].plane;
45  map[GREEN] = desc->comp[1].plane;
46  map[BLUE] = desc->comp[2].plane;
47  map[ALPHA] = (desc->flags & AV_PIX_FMT_FLAG_ALPHA) ? desc->comp[3].plane : 3;
48  } else {
49  int had0 = 0;
50  unsigned depthb = 0;
51  for (unsigned i = 0; i < desc->nb_components; i++) {
52  /* all components must have same depth in bytes */
53  unsigned db = (desc->comp[i].depth + 7) / 8;
54  unsigned pos = desc->comp[i].offset / db;
55  if (depthb && (depthb != db))
56  return AVERROR(ENOSYS);
57 
58  if (desc->comp[i].offset % db)
59  return AVERROR(ENOSYS);
60 
61  had0 |= pos == 0;
62  map[i] = pos;
63  depthb = db;
64  }
65 
66  if (desc->nb_components == 3)
67  map[ALPHA] = had0 ? 3 : 0;
68  }
69 
70  av_assert0(map[RED] != map[GREEN]);
71  av_assert0(map[GREEN] != map[BLUE]);
72  av_assert0(map[BLUE] != map[RED]);
73  av_assert0(map[RED] != map[ALPHA]);
75  av_assert0(map[BLUE] != map[ALPHA]);
76 
77  return 0;
78 }
79 
80 int ff_fill_rgba_map(uint8_t *rgba_map, enum AVPixelFormat pix_fmt)
81 {
83  if (!(desc->flags & AV_PIX_FMT_FLAG_RGB))
84  return AVERROR(EINVAL);
85  return fill_map(desc, rgba_map);
86 }
87 
88 int ff_fill_ayuv_map(uint8_t *ayuv_map, enum AVPixelFormat pix_fmt)
89 {
91  if (desc->flags & AV_PIX_FMT_FLAG_RGB)
92  return AVERROR(EINVAL);
93  return fill_map(desc, ayuv_map);
94 }
95 
97  enum AVColorRange range, enum AVAlphaMode alpha, unsigned flags)
98 {
100  const AVLumaCoefficients *luma = NULL;
101  const AVComponentDescriptor *c;
102  unsigned nb_planes = 0;
103  int pixelstep[MAX_PLANES] = { 0 };
104  int depthb = 0;
105 
106  if (!desc || !desc->name)
107  return AVERROR(EINVAL);
108  if (desc->flags & AV_PIX_FMT_FLAG_BE)
109  return AVERROR(ENOSYS);
111  return AVERROR(ENOSYS);
112  if (csp == AVCOL_SPC_UNSPECIFIED)
114  if (!(desc->flags & AV_PIX_FMT_FLAG_RGB) && !(luma = av_csp_luma_coeffs_from_avcsp(csp)))
115  return AVERROR(EINVAL);
122  return AVERROR(EINVAL);
123  for (unsigned i = 0; i < desc->nb_components; i++) {
124  int db;
125  c = &desc->comp[i];
126  /* for now, only 8-16 bits formats */
127  if (c->depth < 8 || c->depth > 16)
128  return AVERROR(ENOSYS);
129  if (c->plane >= MAX_PLANES)
130  return AVERROR(ENOSYS);
131  /* data must either be in the high or low bits, never middle */
132  if (c->shift && ((c->shift + c->depth) & 0x7))
133  return AVERROR(ENOSYS);
134  /* mixed >8 and <=8 depth */
135  db = (c->depth + 7) / 8;
136  if (depthb && (depthb != db))
137  return AVERROR(ENOSYS);
138  depthb = db;
139  if (db * (c->offset + 1) > 16)
140  return AVERROR(ENOSYS);
141  if (c->offset % db)
142  return AVERROR(ENOSYS);
143  /* strange interleaving */
144  if (pixelstep[c->plane] != 0 &&
145  pixelstep[c->plane] != c->step)
146  return AVERROR(ENOSYS);
147  pixelstep[c->plane] = c->step;
148  if (pixelstep[c->plane] >= 8)
149  return AVERROR(ENOSYS);
150  nb_planes = FFMAX(nb_planes, c->plane + 1);
151  }
152  memset(draw, 0, sizeof(*draw));
153  draw->desc = desc;
154  draw->format = format;
155  draw->nb_planes = nb_planes;
156  draw->range = range;
157  draw->csp = csp;
158  draw->alpha = alpha;
159  draw->flags = flags;
160  if (luma)
161  ff_fill_rgb2yuv_table(luma, draw->rgb2yuv);
162  memcpy(draw->pixelstep, pixelstep, sizeof(draw->pixelstep));
163  draw->hsub[1] = draw->hsub[2] = draw->hsub_max = desc->log2_chroma_w;
164  draw->vsub[1] = draw->vsub[2] = draw->vsub_max = desc->log2_chroma_h;
165  return 0;
166 }
167 
169  unsigned flags)
170 {
172 }
173 
175 {
177 }
178 
179 void ff_draw_color(FFDrawContext *draw, FFDrawColor *color, const uint8_t rgba[4])
180 {
181  double yuvad[4];
182  double rgbad[4];
183  const AVPixFmtDescriptor *desc = draw->desc;
184 
185  if (rgba != color->rgba)
186  memcpy(color->rgba, rgba, sizeof(color->rgba));
187 
188  memset(color->comp, 0, sizeof(color->comp));
189 
190  for (int i = 0; i < 4; i++)
191  rgbad[i] = color->rgba[i] / 255.;
192 
193  if (draw->alpha == AVALPHA_MODE_PREMULTIPLIED) {
194  for (int i = 0; i < 3; i++)
195  rgbad[i] *= rgbad[3];
196  }
197 
198  if (draw->desc->flags & AV_PIX_FMT_FLAG_RGB)
199  memcpy(yuvad, rgbad, sizeof(double) * 3);
200  else
201  ff_matrix_mul_3x3_vec(yuvad, rgbad, draw->rgb2yuv);
202 
203  yuvad[3] = rgbad[3];
204 
205  for (int i = 0; i < 3; i++) {
206  int chroma = (!(draw->desc->flags & AV_PIX_FMT_FLAG_RGB) && i > 0);
207  if (draw->range == AVCOL_RANGE_MPEG) {
208  yuvad[i] *= (chroma ? 224. : 219.) / 255.;
209  yuvad[i] += (chroma ? 128. : 16.) / 255.;
210  } else if (chroma) {
211  yuvad[i] += 0.5;
212  }
213  }
214 
215  // Ensure we place the alpha appropriately for gray formats
216  if (desc->nb_components <= 2)
217  yuvad[1] = yuvad[3];
218 
219  for (unsigned i = 0; i < desc->nb_components; i++) {
220  unsigned val = yuvad[i] * ((1 << (draw->desc->comp[i].depth + draw->desc->comp[i].shift)) - 1) + 0.5;
221  if (desc->comp[i].depth > 8)
222  color->comp[desc->comp[i].plane].u16[desc->comp[i].offset / 2] = val;
223  else
224  color->comp[desc->comp[i].plane].u8[desc->comp[i].offset] = val;
225  }
226 }
227 
228 static uint8_t *pointer_at(FFDrawContext *draw, uint8_t *data[], int linesize[],
229  int plane, int x, int y)
230 {
231  return data[plane] +
232  (y >> draw->vsub[plane]) * linesize[plane] +
233  (x >> draw->hsub[plane]) * draw->pixelstep[plane];
234 }
235 
237  uint8_t *dst[], int dst_linesize[],
238  uint8_t *src[], int src_linesize[],
239  int dst_x, int dst_y, int src_x, int src_y,
240  int w, int h)
241 {
242  int wp, hp;
243  uint8_t *p, *q;
244 
245  for (int plane = 0; plane < draw->nb_planes; plane++) {
246  p = pointer_at(draw, src, src_linesize, plane, src_x, src_y);
247  q = pointer_at(draw, dst, dst_linesize, plane, dst_x, dst_y);
248  wp = AV_CEIL_RSHIFT(w, draw->hsub[plane]) * draw->pixelstep[plane];
249  hp = AV_CEIL_RSHIFT(h, draw->vsub[plane]);
250  for (int y = 0; y < hp; y++) {
251  memcpy(q, p, wp);
252  p += src_linesize[plane];
253  q += dst_linesize[plane];
254  }
255  }
256 }
257 
259  uint8_t *dst[], int dst_linesize[],
260  int dst_x, int dst_y, int w, int h)
261 {
262  int wp, hp;
263  uint8_t *p0, *p;
264  FFDrawColor color_tmp = *color;
265 
266  for (int plane = 0; plane < draw->nb_planes; plane++) {
267  p0 = pointer_at(draw, dst, dst_linesize, plane, dst_x, dst_y);
268  wp = AV_CEIL_RSHIFT(w, draw->hsub[plane]);
269  hp = AV_CEIL_RSHIFT(h, draw->vsub[plane]);
270  if (!hp)
271  return;
272  p = p0;
273 
274  if (HAVE_BIGENDIAN && draw->desc->comp[0].depth > 8) {
275  for (int x = 0; 2*x < draw->pixelstep[plane]; x++)
276  color_tmp.comp[plane].u16[x] = av_bswap16(color_tmp.comp[plane].u16[x]);
277  }
278 
279  /* copy first line from color */
280  for (int x = 0; x < wp; x++) {
281  memcpy(p, color_tmp.comp[plane].u8, draw->pixelstep[plane]);
282  p += draw->pixelstep[plane];
283  }
284  wp *= draw->pixelstep[plane];
285  /* copy next lines from first line */
286  p = p0 + dst_linesize[plane];
287  for (int y = 1; y < hp; y++) {
288  memcpy(p, p0, wp);
289  p += dst_linesize[plane];
290  }
291  }
292 }
293 
294 /**
295  * Clip interval [x; x+w[ within [0; wmax[.
296  * The resulting w may be negative if the final interval is empty.
297  * dx, if not null, return the difference between in and out value of x.
298  */
299 static void clip_interval(int wmax, int *x, int *w, int *dx)
300 {
301  if (dx)
302  *dx = 0;
303  if (*x < 0) {
304  if (dx)
305  *dx = -*x;
306  *w += *x;
307  *x = 0;
308  }
309  if (*x + *w > wmax)
310  *w = wmax - *x;
311 }
312 
313 /**
314  * Decompose w pixels starting at x
315  * into start + (w starting at x) + end
316  * with x and w aligned on multiples of 1<<sub.
317  */
318 static void subsampling_bounds(int sub, int *x, int *w, int *start, int *end)
319 {
320  int mask = (1 << sub) - 1;
321 
322  *start = (-*x) & mask;
323  *x += *start;
324  *start = FFMIN(*start, *w);
325  *w -= *start;
326  *end = *w & mask;
327  *w >>= sub;
328 }
329 
330 /* If alpha is in the [ 0 ; 0x1010101 ] range,
331  then alpha * value is in the [ 0 ; 0xFFFFFFFF ] range,
332  and >> 24 gives a correct rounding. */
333 static void blend_line(uint8_t *dst, unsigned src, unsigned alpha,
334  int dx, int w, unsigned hsub, int left, int right)
335 {
336  unsigned asrc = alpha * src;
337  unsigned tau = 0x1010101 - alpha;
338 
339  if (left) {
340  unsigned suba = (left * alpha) >> hsub;
341  *dst = (*dst * (0x1010101 - suba) + src * suba) >> 24;
342  dst += dx;
343  }
344  for (int x = 0; x < w; x++) {
345  *dst = (*dst * tau + asrc) >> 24;
346  dst += dx;
347  }
348  if (right) {
349  unsigned suba = (right * alpha) >> hsub;
350  *dst = (*dst * (0x1010101 - suba) + src * suba) >> 24;
351  }
352 }
353 
354 static void blend_line16(uint8_t *dst, unsigned src, unsigned alpha,
355  int dx, int w, unsigned hsub, int left, int right)
356 {
357  unsigned asrc = alpha * src;
358  unsigned tau = 0x10001 - alpha;
359 
360  if (left) {
361  unsigned suba = (left * alpha) >> hsub;
362  uint16_t value = AV_RL16(dst);
363  AV_WL16(dst, (value * (0x10001 - suba) + src * suba) >> 16);
364  dst += dx;
365  }
366  for (int x = 0; x < w; x++) {
367  uint16_t value = AV_RL16(dst);
368  AV_WL16(dst, (value * tau + asrc) >> 16);
369  dst += dx;
370  }
371  if (right) {
372  unsigned suba = (right * alpha) >> hsub;
373  uint16_t value = AV_RL16(dst);
374  AV_WL16(dst, (value * (0x10001 - suba) + src * suba) >> 16);
375  }
376 }
377 
379  uint8_t *dst[], int dst_linesize[],
380  int dst_w, int dst_h,
381  int x0, int y0, int w, int h)
382 {
383  unsigned alpha, nb_planes, nb_comp;
384  int w_sub, h_sub, x_sub, y_sub, left, right, top, bottom;
385  uint8_t *p0, *p;
386 
387  nb_comp = draw->desc->nb_components -
388  !!(draw->desc->flags & AV_PIX_FMT_FLAG_ALPHA && !(draw->flags & FF_DRAW_PROCESS_ALPHA));
389 
390  /* TODO optimize if alpha = 0xFF */
391  clip_interval(dst_w, &x0, &w, NULL);
392  clip_interval(dst_h, &y0, &h, NULL);
393  if (w <= 0 || h <= 0 || !color->rgba[3])
394  return;
395  if (draw->desc->comp[0].depth <= 8) {
396  /* 0x10203 * alpha + 2 is in the [ 2 ; 0x1010101 - 2 ] range */
397  alpha = 0x10203 * color->rgba[3] + 0x2;
398  } else {
399  /* 0x101 * alpha is in the [ 2 ; 0x1001] range */
400  alpha = 0x101 * color->rgba[3] + 0x2;
401  }
402  nb_planes = draw->nb_planes - !!(draw->desc->flags & AV_PIX_FMT_FLAG_ALPHA && !(draw->flags & FF_DRAW_PROCESS_ALPHA));
403  nb_planes += !nb_planes;
404  for (unsigned plane = 0; plane < nb_planes; plane++) {
405  p0 = pointer_at(draw, dst, dst_linesize, plane, x0, y0);
406  w_sub = w;
407  h_sub = h;
408  x_sub = x0;
409  y_sub = y0;
410  subsampling_bounds(draw->hsub[plane], &x_sub, &w_sub, &left, &right);
411  subsampling_bounds(draw->vsub[plane], &y_sub, &h_sub, &top, &bottom);
412  for (unsigned comp = 0; comp < nb_comp; comp++) {
413  const int depth = draw->desc->comp[comp].depth;
414  const int offset = draw->desc->comp[comp].offset;
415  const int index = offset / ((depth + 7) / 8);
416 
417  if (draw->desc->comp[comp].plane != plane)
418  continue;
419  p = p0 + offset;
420  if (top) {
421  if (depth <= 8) {
422  blend_line(p, color->comp[plane].u8[index], alpha >> 1,
423  draw->pixelstep[plane], w_sub,
424  draw->hsub[plane], left, right);
425  } else {
426  blend_line16(p, color->comp[plane].u16[index], alpha >> 1,
427  draw->pixelstep[plane], w_sub,
428  draw->hsub[plane], left, right);
429  }
430  p += dst_linesize[plane];
431  }
432  if (depth <= 8) {
433  for (int y = 0; y < h_sub; y++) {
434  blend_line(p, color->comp[plane].u8[index], alpha,
435  draw->pixelstep[plane], w_sub,
436  draw->hsub[plane], left, right);
437  p += dst_linesize[plane];
438  }
439  } else {
440  for (int y = 0; y < h_sub; y++) {
441  blend_line16(p, color->comp[plane].u16[index], alpha,
442  draw->pixelstep[plane], w_sub,
443  draw->hsub[plane], left, right);
444  p += dst_linesize[plane];
445  }
446  }
447  if (bottom) {
448  if (depth <= 8) {
449  blend_line(p, color->comp[plane].u8[index], alpha >> 1,
450  draw->pixelstep[plane], w_sub,
451  draw->hsub[plane], left, right);
452  } else {
453  blend_line16(p, color->comp[plane].u16[index], alpha >> 1,
454  draw->pixelstep[plane], w_sub,
455  draw->hsub[plane], left, right);
456  }
457  }
458  }
459  }
460 }
461 
462 static void blend_pixel16(uint8_t *dst, unsigned src, unsigned alpha,
463  const uint8_t *mask, int mask_linesize, int l2depth,
464  unsigned w, unsigned h, unsigned shift, unsigned xm0)
465 {
466  unsigned t = 0;
467  unsigned xmshf = 3 - l2depth;
468  unsigned xmmod = 7 >> l2depth;
469  unsigned mbits = (1 << (1 << l2depth)) - 1;
470  unsigned mmult = 255 / mbits;
471  uint16_t value = AV_RL16(dst);
472 
473  for (unsigned y = 0; y < h; y++) {
474  unsigned xm = xm0;
475  for (unsigned x = 0; x < w; x++) {
476  t += ((mask[xm >> xmshf] >> ((~xm & xmmod) << l2depth)) & mbits)
477  * mmult;
478  xm++;
479  }
480  mask += mask_linesize;
481  }
482  alpha = (t >> shift) * alpha;
483  AV_WL16(dst, ((0x10001 - alpha) * value + alpha * src) >> 16);
484 }
485 
486 static void blend_pixel(uint8_t *dst, unsigned src, unsigned alpha,
487  const uint8_t *mask, int mask_linesize, int l2depth,
488  unsigned w, unsigned h, unsigned shift, unsigned xm0)
489 {
490  unsigned t = 0;
491  unsigned xmshf = 3 - l2depth;
492  unsigned xmmod = 7 >> l2depth;
493  unsigned mbits = (1 << (1 << l2depth)) - 1;
494  unsigned mmult = 255 / mbits;
495 
496  for (unsigned y = 0; y < h; y++) {
497  unsigned xm = xm0;
498  for (unsigned x = 0; x < w; x++) {
499  t += ((mask[xm >> xmshf] >> ((~xm & xmmod) << l2depth)) & mbits)
500  * mmult;
501  xm++;
502  }
503  mask += mask_linesize;
504  }
505  alpha = (t >> shift) * alpha;
506  *dst = ((0x1010101 - alpha) * *dst + alpha * src) >> 24;
507 }
508 
509 static void blend_line_hv16(uint8_t *dst, int dst_delta,
510  unsigned src, unsigned alpha,
511  const uint8_t *mask, int mask_linesize, int l2depth, int w,
512  unsigned hsub, unsigned vsub,
513  int xm, int left, int right, int hband)
514 {
515 
516  if (left) {
517  blend_pixel16(dst, src, alpha, mask, mask_linesize, l2depth,
518  left, hband, hsub + vsub, xm);
519  dst += dst_delta;
520  xm += left;
521  }
522  for (int x = 0; x < w; x++) {
523  blend_pixel16(dst, src, alpha, mask, mask_linesize, l2depth,
524  1 << hsub, hband, hsub + vsub, xm);
525  dst += dst_delta;
526  xm += 1 << hsub;
527  }
528  if (right)
529  blend_pixel16(dst, src, alpha, mask, mask_linesize, l2depth,
530  right, hband, hsub + vsub, xm);
531 }
532 
533 static void blend_line_hv(uint8_t *dst, int dst_delta,
534  unsigned src, unsigned alpha,
535  const uint8_t *mask, int mask_linesize, int l2depth, int w,
536  unsigned hsub, unsigned vsub,
537  int xm, int left, int right, int hband)
538 {
539 
540  if (left) {
541  blend_pixel(dst, src, alpha, mask, mask_linesize, l2depth,
542  left, hband, hsub + vsub, xm);
543  dst += dst_delta;
544  xm += left;
545  }
546  for (int x = 0; x < w; x++) {
547  blend_pixel(dst, src, alpha, mask, mask_linesize, l2depth,
548  1 << hsub, hband, hsub + vsub, xm);
549  dst += dst_delta;
550  xm += 1 << hsub;
551  }
552  if (right)
553  blend_pixel(dst, src, alpha, mask, mask_linesize, l2depth,
554  right, hband, hsub + vsub, xm);
555 }
556 
558  uint8_t *dst[], int dst_linesize[], int dst_w, int dst_h,
559  const uint8_t *mask, int mask_linesize, int mask_w, int mask_h,
560  int l2depth, unsigned endianness, int x0, int y0)
561 {
562  unsigned alpha, nb_planes, nb_comp;
563  int xm0, ym0, w_sub, h_sub, x_sub, y_sub, left, right, top, bottom;
564  uint8_t *p;
565  const uint8_t *m;
566 
567  nb_comp = draw->desc->nb_components -
568  !!(draw->desc->flags & AV_PIX_FMT_FLAG_ALPHA && !(draw->flags & FF_DRAW_PROCESS_ALPHA));
569 
570  clip_interval(dst_w, &x0, &mask_w, &xm0);
571  clip_interval(dst_h, &y0, &mask_h, &ym0);
572  mask += ym0 * mask_linesize;
573  if (mask_w <= 0 || mask_h <= 0 || !color->rgba[3])
574  return;
575  if (draw->desc->comp[0].depth <= 8) {
576  /* alpha is in the [ 0 ; 0x10203 ] range,
577  alpha * mask is in the [ 0 ; 0x1010101 - 4 ] range */
578  alpha = (0x10307 * color->rgba[3] + 0x3) >> 8;
579  } else {
580  alpha = (0x101 * color->rgba[3] + 0x2) >> 8;
581  }
582  nb_planes = draw->nb_planes - !!(draw->desc->flags & AV_PIX_FMT_FLAG_ALPHA && !(draw->flags & FF_DRAW_PROCESS_ALPHA));
583  nb_planes += !nb_planes;
584  for (unsigned plane = 0; plane < nb_planes; plane++) {
585  uint8_t *p0 = pointer_at(draw, dst, dst_linesize, plane, x0, y0);
586  w_sub = mask_w;
587  h_sub = mask_h;
588  x_sub = x0;
589  y_sub = y0;
590  subsampling_bounds(draw->hsub[plane], &x_sub, &w_sub, &left, &right);
591  subsampling_bounds(draw->vsub[plane], &y_sub, &h_sub, &top, &bottom);
592  for (unsigned comp = 0; comp < nb_comp; comp++) {
593  const int depth = draw->desc->comp[comp].depth;
594  const int offset = draw->desc->comp[comp].offset;
595  const int index = offset / ((depth + 7) / 8);
596 
597  if (draw->desc->comp[comp].plane != plane)
598  continue;
599  p = p0 + offset;
600  m = mask;
601  if (top) {
602  if (depth <= 8) {
603  blend_line_hv(p, draw->pixelstep[plane],
604  color->comp[plane].u8[index], alpha,
605  m, mask_linesize, l2depth, w_sub,
606  draw->hsub[plane], draw->vsub[plane],
607  xm0, left, right, top);
608  } else {
609  blend_line_hv16(p, draw->pixelstep[plane],
610  color->comp[plane].u16[index], alpha,
611  m, mask_linesize, l2depth, w_sub,
612  draw->hsub[plane], draw->vsub[plane],
613  xm0, left, right, top);
614  }
615  p += dst_linesize[plane];
616  m += top * mask_linesize;
617  }
618  if (depth <= 8) {
619  for (int y = 0; y < h_sub; y++) {
620  blend_line_hv(p, draw->pixelstep[plane],
621  color->comp[plane].u8[index], alpha,
622  m, mask_linesize, l2depth, w_sub,
623  draw->hsub[plane], draw->vsub[plane],
624  xm0, left, right, 1 << draw->vsub[plane]);
625  p += dst_linesize[plane];
626  m += mask_linesize << draw->vsub[plane];
627  }
628  } else {
629  for (int y = 0; y < h_sub; y++) {
630  blend_line_hv16(p, draw->pixelstep[plane],
631  color->comp[plane].u16[index], alpha,
632  m, mask_linesize, l2depth, w_sub,
633  draw->hsub[plane], draw->vsub[plane],
634  xm0, left, right, 1 << draw->vsub[plane]);
635  p += dst_linesize[plane];
636  m += mask_linesize << draw->vsub[plane];
637  }
638  }
639  if (bottom) {
640  if (depth <= 8) {
641  blend_line_hv(p, draw->pixelstep[plane],
642  color->comp[plane].u8[index], alpha,
643  m, mask_linesize, l2depth, w_sub,
644  draw->hsub[plane], draw->vsub[plane],
645  xm0, left, right, bottom);
646  } else {
647  blend_line_hv16(p, draw->pixelstep[plane],
648  color->comp[plane].u16[index], alpha,
649  m, mask_linesize, l2depth, w_sub,
650  draw->hsub[plane], draw->vsub[plane],
651  xm0, left, right, bottom);
652  }
653  }
654  }
655  }
656 }
657 
658 int ff_draw_round_to_sub(FFDrawContext *draw, int sub_dir, int round_dir,
659  int value)
660 {
661  unsigned shift = sub_dir ? draw->vsub_max : draw->hsub_max;
662 
663  if (!shift)
664  return value;
665  if (round_dir >= 0)
666  value += round_dir ? (1 << shift) - 1 : 1 << (shift - 1);
667  return (value >> shift) << shift;
668 }
669 
671 {
673  AVFilterFormats *fmts = NULL;
674  int ret;
675 
676  for (enum AVPixelFormat i = 0; av_pix_fmt_desc_get(i); i++)
677  if (ff_draw_init(&draw, i, flags) >= 0 &&
678  (ret = ff_add_format(&fmts, i)) < 0)
679  return NULL;
680  return fmts;
681 }
flags
const SwsFlags flags[]
Definition: swscale.c:61
AVFrame::color_range
enum AVColorRange color_range
MPEG vs JPEG YUV range.
Definition: frame.h:678
FFDrawColor
Definition: drawutils.h:52
AVPixelFormat
AVPixelFormat
Pixel format.
Definition: pixfmt.h:71
AVERROR
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later. That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another. Frame references ownership and permissions
AVALPHA_MODE_PREMULTIPLIED
@ AVALPHA_MODE_PREMULTIPLIED
Alpha channel is multiplied into color values.
Definition: pixfmt.h:802
color
Definition: vf_paletteuse.c:513
comp
static void comp(unsigned char *dst, ptrdiff_t dst_stride, unsigned char *src, ptrdiff_t src_stride, int add)
Definition: eamad.c:79
av_pix_fmt_desc_get
const AVPixFmtDescriptor * av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt)
Definition: pixdesc.c:3447
fill_map
static int fill_map(const AVPixFmtDescriptor *desc, uint8_t *map)
Definition: drawutils.c:35
subsampling_bounds
static void subsampling_bounds(int sub, int *x, int *w, int *start, int *end)
Decompose w pixels starting at x into start + (w starting at x) + end with x and w aligned on multipl...
Definition: drawutils.c:318
mask
int mask
Definition: mediacodecdec_common.c:154
AVFrame::colorspace
enum AVColorSpace colorspace
YUV colorspace type.
Definition: frame.h:689
pixdesc.h
w
uint8_t w
Definition: llviddspenc.c:38
AVCOL_RANGE_JPEG
@ AVCOL_RANGE_JPEG
Full range content.
Definition: pixfmt.h:767
FFDrawColor::u16
uint16_t u16[8]
Definition: drawutils.h:56
av_csp_luma_coeffs_from_avcsp
const struct AVLumaCoefficients * av_csp_luma_coeffs_from_avcsp(enum AVColorSpace csp)
Retrieves the Luma coefficients necessary to construct a conversion matrix from an enum constant desc...
Definition: csp.c:58
chroma
static av_always_inline void chroma(WaveformContext *s, AVFrame *in, AVFrame *out, int component, int intensity, int offset_y, int offset_x, int column, int mirror, int jobnr, int nb_jobs)
Definition: vf_waveform.c:1639
data
const char data[16]
Definition: mxf.c:149
blend_pixel16
static void blend_pixel16(uint8_t *dst, unsigned src, unsigned alpha, const uint8_t *mask, int mask_linesize, int l2depth, unsigned w, unsigned h, unsigned shift, unsigned xm0)
Definition: drawutils.c:462
AVCOL_SPC_RGB
@ AVCOL_SPC_RGB
order of coefficients is actually GBR, also IEC 61966-2-1 (sRGB), YZX and ST 428-1
Definition: pixfmt.h:691
AVLumaCoefficients
Struct containing luma coefficients to be used for RGB to YUV/YCoCg, or similar calculations.
Definition: csp.h:48
FFMAX
#define FFMAX(a, b)
Definition: macros.h:47
hsub
static void hsub(htype *dst, const htype *src, int bins)
Definition: vf_median.c:74
AVFilterFormats
A list of supported formats for one end of a filter link.
Definition: formats.h:64
formats.h
av_pix_fmt_count_planes
int av_pix_fmt_count_planes(enum AVPixelFormat pix_fmt)
Definition: pixdesc.c:3487
AV_PIX_FMT_FLAG_HWACCEL
#define AV_PIX_FMT_FLAG_HWACCEL
Pixel format is an HW accelerated format.
Definition: pixdesc.h:128
colorspace.h
ALPHA
@ ALPHA
Definition: drawutils.c:33
AVFrame::alpha_mode
enum AVAlphaMode alpha_mode
Indicates how the alpha channel of the video is to be handled.
Definition: frame.h:782
val
static double val(void *priv, double ch)
Definition: aeval.c:77
ff_blend_mask
void ff_blend_mask(FFDrawContext *draw, FFDrawColor *color, uint8_t *dst[], int dst_linesize[], int dst_w, int dst_h, const uint8_t *mask, int mask_linesize, int mask_w, int mask_h, int l2depth, unsigned endianness, int x0, int y0)
Blend an alpha mask with an uniform color.
Definition: drawutils.c:557
AV_PIX_FMT_YUVJ411P
@ AV_PIX_FMT_YUVJ411P
planar YUV 4:1:1, 12bpp, (1 Cr & Cb sample per 4x1 Y samples) full scale (JPEG), deprecated in favor ...
Definition: pixfmt.h:283
avassert.h
ff_draw_init2
int ff_draw_init2(FFDrawContext *draw, enum AVPixelFormat format, enum AVColorSpace csp, enum AVColorRange range, enum AVAlphaMode alpha, unsigned flags)
Init a draw context.
Definition: drawutils.c:96
AV_PIX_FMT_YUVJ422P
@ AV_PIX_FMT_YUVJ422P
planar YUV 4:2:2, 16bpp, full scale (JPEG), deprecated in favor of AV_PIX_FMT_YUV422P and setting col...
Definition: pixfmt.h:86
intreadwrite.h
MAX_PLANES
#define MAX_PLANES
Definition: ffv1.h:44
AV_CEIL_RSHIFT
#define AV_CEIL_RSHIFT(a, b)
Definition: common.h:60
AVCOL_SPC_SMPTE170M
@ AVCOL_SPC_SMPTE170M
also ITU-R BT601-6 525 / ITU-R BT1358 525 / ITU-R BT1700 NTSC / functionally identical to above
Definition: pixfmt.h:697
pix_fmt
static enum AVPixelFormat pix_fmt
Definition: demux_decode.c:41
ff_copy_rectangle2
void ff_copy_rectangle2(FFDrawContext *draw, uint8_t *dst[], int dst_linesize[], uint8_t *src[], int src_linesize[], int dst_x, int dst_y, int src_x, int src_y, int w, int h)
Copy a rectangle from an image to another.
Definition: drawutils.c:236
FF_DRAW_PROCESS_ALPHA
#define FF_DRAW_PROCESS_ALPHA
Process alpha pixel component.
Definition: drawutils.h:64
blend_line_hv16
static void blend_line_hv16(uint8_t *dst, int dst_delta, unsigned src, unsigned alpha, const uint8_t *mask, int mask_linesize, int l2depth, int w, unsigned hsub, unsigned vsub, int xm, int left, int right, int hband)
Definition: drawutils.c:509
av_assert0
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition: avassert.h:41
AV_PIX_FMT_FLAG_ALPHA
#define AV_PIX_FMT_FLAG_ALPHA
The pixel format has an alpha channel.
Definition: pixdesc.h:147
AV_RL16
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_WL32 unsigned int_TMPL AV_WL24 unsigned int_TMPL AV_RL16
Definition: bytestream.h:94
GREEN
@ GREEN
Definition: drawutils.c:33
ff_draw_init
int ff_draw_init(FFDrawContext *draw, enum AVPixelFormat format, unsigned flags)
Definition: drawutils.c:174
ff_matrix_mul_3x3_vec
void ff_matrix_mul_3x3_vec(double dst[3], const double vec[3], const double mat[3][3])
Definition: colorspace.c:66
link
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a link
Definition: filter_design.txt:23
AV_PIX_FMT_YUVJ444P
@ AV_PIX_FMT_YUVJ444P
planar YUV 4:4:4, 24bpp, full scale (JPEG), deprecated in favor of AV_PIX_FMT_YUV444P and setting col...
Definition: pixfmt.h:87
if
if(ret)
Definition: filter_design.txt:179
RED
@ RED
Definition: drawutils.c:33
NULL
#define NULL
Definition: coverity.c:32
format
New swscale design to change SwsGraph is what coordinates multiple passes These can include cascaded scaling error diffusion and so on Or we could have separate passes for the vertical and horizontal scaling In between each SwsPass lies a fully allocated image buffer Graph passes may have different levels of e g we can have a single threaded error diffusion pass following a multi threaded scaling pass SwsGraph is internally recreated whenever the image format
Definition: swscale-v2.txt:14
AVComponentDescriptor
Definition: pixdesc.h:30
AV_PIX_FMT_YUVJ420P
@ AV_PIX_FMT_YUVJ420P
planar YUV 4:2:0, 12bpp, full scale (JPEG), deprecated in favor of AV_PIX_FMT_YUV420P and setting col...
Definition: pixfmt.h:85
ff_add_format
int ff_add_format(AVFilterFormats **avff, int64_t fmt)
Add fmt to the list of media formats contained in *avff.
Definition: formats.c:520
ff_fill_ayuv_map
int ff_fill_ayuv_map(uint8_t *ayuv_map, enum AVPixelFormat pix_fmt)
Definition: drawutils.c:88
FFDrawColor::u8
uint8_t u8[16]
Definition: drawutils.h:57
clip_interval
static void clip_interval(int wmax, int *x, int *w, int *dx)
Clip interval [x; x+w[ within [0; wmax[.
Definition: drawutils.c:299
AVCOL_RANGE_UNSPECIFIED
@ AVCOL_RANGE_UNSPECIFIED
Definition: pixfmt.h:733
index
int index
Definition: gxfenc.c:90
c
Undefined Behavior In the C some operations are like signed integer dereferencing freed accessing outside allocated Undefined Behavior must not occur in a C it is not safe even if the output of undefined operations is unused The unsafety may seem nit picking but Optimizing compilers have in fact optimized code on the assumption that no undefined Behavior occurs Optimizing code based on wrong assumptions can and has in some cases lead to effects beyond the output of computations The signed integer overflow problem in speed critical code Code which is highly optimized and works with signed integers sometimes has the problem that often the output of the computation does not c
Definition: undefined.txt:32
AVAlphaMode
AVAlphaMode
Correlation between the alpha channel and color values.
Definition: pixfmt.h:800
AV_PIX_FMT_FLAG_RGB
#define AV_PIX_FMT_FLAG_RGB
The pixel format contains RGB-like data (as opposed to YUV/grayscale).
Definition: pixdesc.h:136
shift
static int shift(int a, int b)
Definition: bonk.c:261
dst
uint8_t ptrdiff_t const uint8_t ptrdiff_t int intptr_t intptr_t int int16_t * dst
Definition: dsp.h:87
ff_blend_rectangle
void ff_blend_rectangle(FFDrawContext *draw, FFDrawColor *color, uint8_t *dst[], int dst_linesize[], int dst_w, int dst_h, int x0, int y0, int w, int h)
Blend a rectangle with an uniform color.
Definition: drawutils.c:378
color
static const uint32_t color[16+AV_CLASS_CATEGORY_NB]
Definition: log.c:97
ff_fill_rectangle
void ff_fill_rectangle(FFDrawContext *draw, FFDrawColor *color, uint8_t *dst[], int dst_linesize[], int dst_x, int dst_y, int w, int h)
Fill a rectangle with an uniform color.
Definition: drawutils.c:258
AV_PIX_FMT_FLAG_BITSTREAM
#define AV_PIX_FMT_FLAG_BITSTREAM
All values of a component are bit-wise packed end to end.
Definition: pixdesc.h:124
AVFrame::format
int format
format of the frame, -1 if unknown or unset Values correspond to enum AVPixelFormat for video frames,...
Definition: frame.h:514
range
enum AVColorRange range
Definition: mediacodec_wrapper.c:2594
AV_WL16
#define AV_WL16(p, v)
Definition: intreadwrite.h:408
csp.h
offset
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it vf offset
Definition: writing_filters.txt:86
av_pix_fmt_desc_get_id
enum AVPixelFormat av_pix_fmt_desc_get_id(const AVPixFmtDescriptor *desc)
Definition: pixdesc.c:3466
draw
static int draw(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
Definition: avf_showcwt.c:440
AV_PIX_FMT_FLAG_BAYER
#define AV_PIX_FMT_FLAG_BAYER
The pixel format is following a Bayer pattern.
Definition: pixdesc.h:152
endianness
Definition: ircamdec.c:42
ff_fill_rgb2yuv_table
void ff_fill_rgb2yuv_table(const AVLumaCoefficients *coeffs, double rgb2yuv[3][3])
Definition: colorspace.c:125
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:256
ff_draw_supported_pixel_formats
AVFilterFormats * ff_draw_supported_pixel_formats(unsigned flags)
Return the list of pixel formats supported by the draw functions.
Definition: drawutils.c:670
AVColorSpace
AVColorSpace
YUV colorspace type.
Definition: pixfmt.h:690
ff_draw_round_to_sub
int ff_draw_round_to_sub(FFDrawContext *draw, int sub_dir, int round_dir, int value)
Round a dimension according to subsampling.
Definition: drawutils.c:658
value
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it vf default value
Definition: writing_filters.txt:86
FFMIN
#define FFMIN(a, b)
Definition: macros.h:49
AV_PIX_FMT_FLAG_BE
#define AV_PIX_FMT_FLAG_BE
Pixel format is big-endian.
Definition: pixdesc.h:116
AV_PIX_FMT_YUVJ440P
@ AV_PIX_FMT_YUVJ440P
planar YUV 4:4:0 full scale (JPEG), deprecated in favor of AV_PIX_FMT_YUV440P and setting color_range
Definition: pixfmt.h:107
FFDrawContext
Definition: drawutils.h:36
AVCOL_SPC_UNSPECIFIED
@ AVCOL_SPC_UNSPECIFIED
Definition: pixfmt.h:693
AVCOL_RANGE_MPEG
@ AVCOL_RANGE_MPEG
Narrow or limited range content.
Definition: pixfmt.h:750
ff_draw_color
void ff_draw_color(FFDrawContext *draw, FFDrawColor *color, const uint8_t rgba[4])
Prepare a color.
Definition: drawutils.c:179
ret
ret
Definition: filter_design.txt:187
AVALPHA_MODE_UNSPECIFIED
@ AVALPHA_MODE_UNSPECIFIED
Unknown alpha handling, or no alpha channel.
Definition: pixfmt.h:801
blend_pixel
static void blend_pixel(uint8_t *dst, unsigned src, unsigned alpha, const uint8_t *mask, int mask_linesize, int l2depth, unsigned w, unsigned h, unsigned shift, unsigned xm0)
Definition: drawutils.c:486
BLUE
@ BLUE
Definition: drawutils.c:33
pos
unsigned int pos
Definition: spdifenc.c:414
left
Tag MUST be and< 10hcoeff half pel interpolation filter coefficients, hcoeff[0] are the 2 middle coefficients[1] are the next outer ones and so on, resulting in a filter like:...eff[2], hcoeff[1], hcoeff[0], hcoeff[0], hcoeff[1], hcoeff[2] ... the sign of the coefficients is not explicitly stored but alternates after each coeff and coeff[0] is positive, so ...,+,-,+,-,+,+,-,+,-,+,... hcoeff[0] is not explicitly stored but found by subtracting the sum of all stored coefficients with signs from 32 hcoeff[0]=32 - hcoeff[1] - hcoeff[2] - ... a good choice for hcoeff and htaps is htaps=6 hcoeff={40,-10, 2} an alternative which requires more computations at both encoder and decoder side and may or may not be better is htaps=8 hcoeff={42,-14, 6,-2}ref_frames minimum of the number of available reference frames and max_ref_frames for example the first frame after a key frame always has ref_frames=1spatial_decomposition_type wavelet type 0 is a 9/7 symmetric compact integer wavelet 1 is a 5/3 symmetric compact integer wavelet others are reserved stored as delta from last, last is reset to 0 if always_reset||keyframeqlog quality(logarithmic quantizer scale) stored as delta from last, last is reset to 0 if always_reset||keyframemv_scale stored as delta from last, last is reset to 0 if always_reset||keyframe FIXME check that everything works fine if this changes between framesqbias dequantization bias stored as delta from last, last is reset to 0 if always_reset||keyframeblock_max_depth maximum depth of the block tree stored as delta from last, last is reset to 0 if always_reset||keyframequant_table quantization tableHighlevel bitstream structure:==============================--------------------------------------------|Header|--------------------------------------------|------------------------------------|||Block0||||split?||||yes no||||......... intra?||||:Block01 :yes no||||:Block02 :....... ..........||||:Block03 ::y DC ::ref index:||||:Block04 ::cb DC ::motion x :||||......... :cr DC ::motion y :||||....... ..........|||------------------------------------||------------------------------------|||Block1|||...|--------------------------------------------|------------ ------------ ------------|||Y subbands||Cb subbands||Cr subbands||||--- ---||--- ---||--- ---|||||LL0||HL0||||LL0||HL0||||LL0||HL0|||||--- ---||--- ---||--- ---||||--- ---||--- ---||--- ---|||||LH0||HH0||||LH0||HH0||||LH0||HH0|||||--- ---||--- ---||--- ---||||--- ---||--- ---||--- ---|||||HL1||LH1||||HL1||LH1||||HL1||LH1|||||--- ---||--- ---||--- ---||||--- ---||--- ---||--- ---|||||HH1||HL2||||HH1||HL2||||HH1||HL2|||||...||...||...|||------------ ------------ ------------|--------------------------------------------Decoding process:=================------------|||Subbands|------------||||------------|Intra DC||||LL0 subband prediction ------------|\ Dequantization ------------------- \||Reference frames|\ IDWT|------- -------|Motion \|||Frame 0||Frame 1||Compensation . OBMC v -------|------- -------|--------------. \------> Frame n output Frame Frame<----------------------------------/|...|------------------- Range Coder:============Binary Range Coder:------------------- The implemented range coder is an adapted version based upon "Range encoding: an algorithm for removing redundancy from a digitised message." by G. N. N. Martin. The symbols encoded by the Snow range coder are bits(0|1). The associated probabilities are not fix but change depending on the symbol mix seen so far. bit seen|new state ---------+----------------------------------------------- 0|256 - state_transition_table[256 - old_state];1|state_transition_table[old_state];state_transition_table={ 0, 0, 0, 0, 0, 0, 0, 0, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 190, 191, 192, 194, 194, 195, 196, 197, 198, 199, 200, 201, 202, 202, 204, 205, 206, 207, 208, 209, 209, 210, 211, 212, 213, 215, 215, 216, 217, 218, 219, 220, 220, 222, 223, 224, 225, 226, 227, 227, 229, 229, 230, 231, 232, 234, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 248, 0, 0, 0, 0, 0, 0, 0};FIXME Range Coding of integers:------------------------- FIXME Neighboring Blocks:===================left and top are set to the respective blocks unless they are outside of the image in which case they are set to the Null block top-left is set to the top left block unless it is outside of the image in which case it is set to the left block if this block has no larger parent block or it is at the left side of its parent block and the top right block is not outside of the image then the top right block is used for top-right else the top-left block is used Null block y, cb, cr are 128 level, ref, mx and my are 0 Motion Vector Prediction:=========================1. the motion vectors of all the neighboring blocks are scaled to compensate for the difference of reference frames scaled_mv=(mv *(256 *(current_reference+1)/(mv.reference+1))+128)> the median of the scaled left
Definition: snow.txt:386
AV_PIX_FMT_FLAG_XYZ
#define AV_PIX_FMT_FLAG_XYZ
The pixel format contains XYZ-like data (as opposed to YUV/RGB/grayscale).
Definition: pixdesc.h:163
blend_line
static void blend_line(uint8_t *dst, unsigned src, unsigned alpha, int dx, int w, unsigned hsub, int left, int right)
Definition: drawutils.c:333
AV_PIX_FMT_FLAG_PLANAR
#define AV_PIX_FMT_FLAG_PLANAR
At least one pixel component is not in the first data plane.
Definition: pixdesc.h:132
ff_draw_init_from_link
int ff_draw_init_from_link(FFDrawContext *draw, const AVFilterLink *link, unsigned flags)
Init a draw context, taking the format, colorspace and range from the given filter link.
Definition: drawutils.c:168
desc
const char * desc
Definition: libsvtav1.c:79
avutil.h
AVPixFmtDescriptor
Descriptor that unambiguously describes how the bits of a pixel are stored in the up to 4 data planes...
Definition: pixdesc.h:69
map
const VDPAUPixFmtMap * map
Definition: hwcontext_vdpau.c:71
alpha
static const int16_t alpha[]
Definition: ilbcdata.h:55
pointer_at
static uint8_t * pointer_at(FFDrawContext *draw, uint8_t *data[], int linesize[], int plane, int x, int y)
Definition: drawutils.c:228
ff_fill_rgba_map
int ff_fill_rgba_map(uint8_t *rgba_map, enum AVPixelFormat pix_fmt)
Definition: drawutils.c:80
blend_line_hv
static void blend_line_hv(uint8_t *dst, int dst_delta, unsigned src, unsigned alpha, const uint8_t *mask, int mask_linesize, int l2depth, int w, unsigned hsub, unsigned vsub, int xm, int left, int right, int hband)
Definition: drawutils.c:533
blend_line16
static void blend_line16(uint8_t *dst, unsigned src, unsigned alpha, int dx, int w, unsigned hsub, int left, int right)
Definition: drawutils.c:354
FFDrawColor::comp
union FFDrawColor::@353 comp[MAX_PLANES]
h
h
Definition: vp9dsp_template.c:2070
drawutils.h
av_bswap16
#define av_bswap16
Definition: bswap.h:28
AVColorRange
AVColorRange
Visual content value range.
Definition: pixfmt.h:732
AV_PIX_FMT_FLAG_PAL
#define AV_PIX_FMT_FLAG_PAL
Pixel format has a palette in data[1], values are indexes in this palette.
Definition: pixdesc.h:120
src
#define src
Definition: vp8dsp.c:248