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/avutil.h"
25 #include "libavutil/colorspace.h"
26 #include "libavutil/intreadwrite.h"
27 #include "libavutil/pixdesc.h"
28 #include "drawutils.h"
29 #include "formats.h"
30 
31 enum { RED = 0, GREEN, BLUE, ALPHA };
32 
33 int ff_fill_rgba_map(uint8_t *rgba_map, enum AVPixelFormat pix_fmt)
34 {
35  switch (pix_fmt) {
36  case AV_PIX_FMT_0RGB:
37  case AV_PIX_FMT_ARGB: rgba_map[ALPHA] = 0; rgba_map[RED ] = 1; rgba_map[GREEN] = 2; rgba_map[BLUE ] = 3; break;
38  case AV_PIX_FMT_0BGR:
39  case AV_PIX_FMT_ABGR: rgba_map[ALPHA] = 0; rgba_map[BLUE ] = 1; rgba_map[GREEN] = 2; rgba_map[RED ] = 3; break;
40  case AV_PIX_FMT_RGB48LE:
41  case AV_PIX_FMT_RGB48BE:
44  case AV_PIX_FMT_RGB0:
45  case AV_PIX_FMT_RGBA:
46  case AV_PIX_FMT_RGB24: rgba_map[RED ] = 0; rgba_map[GREEN] = 1; rgba_map[BLUE ] = 2; rgba_map[ALPHA] = 3; break;
47  case AV_PIX_FMT_BGR48LE:
48  case AV_PIX_FMT_BGR48BE:
51  case AV_PIX_FMT_BGRA:
52  case AV_PIX_FMT_BGR0:
53  case AV_PIX_FMT_BGR24: rgba_map[BLUE ] = 0; rgba_map[GREEN] = 1; rgba_map[RED ] = 2; rgba_map[ALPHA] = 3; break;
54  case AV_PIX_FMT_GBRP9LE:
55  case AV_PIX_FMT_GBRP9BE:
64  case AV_PIX_FMT_GBRAP:
75  case AV_PIX_FMT_GBRP: rgba_map[GREEN] = 0; rgba_map[BLUE ] = 1; rgba_map[RED ] = 2; rgba_map[ALPHA] = 3; break;
76  default: /* unsupported */
77  return AVERROR(EINVAL);
78  }
79  return 0;
80 }
81 
83 {
85  const AVComponentDescriptor *c;
86  unsigned i, nb_planes = 0;
87  int pixelstep[MAX_PLANES] = { 0 };
88  int full_range = 0;
89 
90  if (!desc || !desc->name)
91  return AVERROR(EINVAL);
93  return AVERROR(ENOSYS);
95  return AVERROR(ENOSYS);
98  full_range = 1;
99  for (i = 0; i < desc->nb_components; i++) {
100  c = &desc->comp[i];
101  /* for now, only 8-16 bits formats */
102  if (c->depth < 8 || c->depth > 16)
103  return AVERROR(ENOSYS);
104  if (desc->flags & AV_PIX_FMT_FLAG_BE)
105  return AVERROR(ENOSYS);
106  if (c->plane >= MAX_PLANES)
107  return AVERROR(ENOSYS);
108  /* strange interleaving */
109  if (pixelstep[c->plane] != 0 &&
110  pixelstep[c->plane] != c->step)
111  return AVERROR(ENOSYS);
112  if (pixelstep[c->plane] == 6 &&
113  c->depth == 16)
114  return AVERROR(ENOSYS);
115  pixelstep[c->plane] = c->step;
116  if (pixelstep[c->plane] >= 8)
117  return AVERROR(ENOSYS);
118  nb_planes = FFMAX(nb_planes, c->plane + 1);
119  }
120  memset(draw, 0, sizeof(*draw));
121  draw->desc = desc;
122  draw->format = format;
123  draw->nb_planes = nb_planes;
124  draw->flags = flags;
125  draw->full_range = full_range;
126  memcpy(draw->pixelstep, pixelstep, sizeof(draw->pixelstep));
127  draw->hsub[1] = draw->hsub[2] = draw->hsub_max = desc->log2_chroma_w;
128  draw->vsub[1] = draw->vsub[2] = draw->vsub_max = desc->log2_chroma_h;
129  for (i = 0; i < (desc->nb_components - !!(desc->flags & AV_PIX_FMT_FLAG_ALPHA && !(flags & FF_DRAW_PROCESS_ALPHA))); i++)
130  draw->comp_mask[desc->comp[i].plane] |=
131  1 << desc->comp[i].offset;
132  return 0;
133 }
134 
135 void ff_draw_color(FFDrawContext *draw, FFDrawColor *color, const uint8_t rgba[4])
136 {
137  unsigned i;
138  uint8_t rgba_map[4];
139 
140  if (rgba != color->rgba)
141  memcpy(color->rgba, rgba, sizeof(color->rgba));
142  if ((draw->desc->flags & AV_PIX_FMT_FLAG_RGB) &&
143  ff_fill_rgba_map(rgba_map, draw->format) >= 0) {
144  if (draw->nb_planes == 1) {
145  for (i = 0; i < 4; i++) {
146  color->comp[0].u8[rgba_map[i]] = rgba[i];
147  if (draw->desc->comp[rgba_map[i]].depth > 8) {
148  color->comp[0].u16[rgba_map[i]] = color->comp[0].u8[rgba_map[i]] << 8;
149  }
150  }
151  } else {
152  for (i = 0; i < 4; i++) {
153  color->comp[rgba_map[i]].u8[0] = rgba[i];
154  if (draw->desc->comp[rgba_map[i]].depth > 8)
155  color->comp[rgba_map[i]].u16[0] = color->comp[rgba_map[i]].u8[0] << (draw->desc->comp[rgba_map[i]].depth - 8);
156  }
157  }
158  } else if (draw->nb_planes >= 2) {
159  /* assume YUV */
160  const AVPixFmtDescriptor *desc = draw->desc;
161  color->comp[desc->comp[0].plane].u8[desc->comp[0].offset] = draw->full_range ? RGB_TO_Y_JPEG(rgba[0], rgba[1], rgba[2]) : RGB_TO_Y_CCIR(rgba[0], rgba[1], rgba[2]);
162  color->comp[desc->comp[1].plane].u8[desc->comp[1].offset] = draw->full_range ? RGB_TO_U_JPEG(rgba[0], rgba[1], rgba[2]) : RGB_TO_U_CCIR(rgba[0], rgba[1], rgba[2], 0);
163  color->comp[desc->comp[2].plane].u8[desc->comp[2].offset] = draw->full_range ? RGB_TO_V_JPEG(rgba[0], rgba[1], rgba[2]) : RGB_TO_V_CCIR(rgba[0], rgba[1], rgba[2], 0);
164  color->comp[3].u8[0] = rgba[3];
165 #define EXPAND(compn) \
166  if (desc->comp[compn].depth > 8) \
167  color->comp[desc->comp[compn].plane].u16[desc->comp[compn].offset] = \
168  color->comp[desc->comp[compn].plane].u8[desc->comp[compn].offset] << \
169  (draw->desc->comp[compn].depth + draw->desc->comp[compn].shift - 8)
170  EXPAND(3);
171  EXPAND(2);
172  EXPAND(1);
173  EXPAND(0);
174  } else if (draw->format == AV_PIX_FMT_GRAY8 || draw->format == AV_PIX_FMT_GRAY8A ||
175  draw->format == AV_PIX_FMT_GRAY16LE || draw->format == AV_PIX_FMT_YA16LE ||
176  draw->format == AV_PIX_FMT_GRAY9LE ||
177  draw->format == AV_PIX_FMT_GRAY10LE ||
178  draw->format == AV_PIX_FMT_GRAY12LE ||
179  draw->format == AV_PIX_FMT_GRAY14LE) {
180  const AVPixFmtDescriptor *desc = draw->desc;
181  color->comp[0].u8[0] = RGB_TO_Y_CCIR(rgba[0], rgba[1], rgba[2]);
182  EXPAND(0);
183  color->comp[1].u8[0] = rgba[3];
184  EXPAND(1);
185  } else {
187  "Color conversion not implemented for %s\n", draw->desc->name);
188  memset(color, 128, sizeof(*color));
189  }
190 }
191 
192 static uint8_t *pointer_at(FFDrawContext *draw, uint8_t *data[], int linesize[],
193  int plane, int x, int y)
194 {
195  return data[plane] +
196  (y >> draw->vsub[plane]) * linesize[plane] +
197  (x >> draw->hsub[plane]) * draw->pixelstep[plane];
198 }
199 
201  uint8_t *dst[], int dst_linesize[],
202  uint8_t *src[], int src_linesize[],
203  int dst_x, int dst_y, int src_x, int src_y,
204  int w, int h)
205 {
206  int plane, y, wp, hp;
207  uint8_t *p, *q;
208 
209  for (plane = 0; plane < draw->nb_planes; plane++) {
210  p = pointer_at(draw, src, src_linesize, plane, src_x, src_y);
211  q = pointer_at(draw, dst, dst_linesize, plane, dst_x, dst_y);
212  wp = AV_CEIL_RSHIFT(w, draw->hsub[plane]) * draw->pixelstep[plane];
213  hp = AV_CEIL_RSHIFT(h, draw->vsub[plane]);
214  for (y = 0; y < hp; y++) {
215  memcpy(q, p, wp);
216  p += src_linesize[plane];
217  q += dst_linesize[plane];
218  }
219  }
220 }
221 
223  uint8_t *dst[], int dst_linesize[],
224  int dst_x, int dst_y, int w, int h)
225 {
226  int plane, x, y, wp, hp;
227  uint8_t *p0, *p;
228  FFDrawColor color_tmp = *color;
229 
230  for (plane = 0; plane < draw->nb_planes; plane++) {
231  p0 = pointer_at(draw, dst, dst_linesize, plane, dst_x, dst_y);
232  wp = AV_CEIL_RSHIFT(w, draw->hsub[plane]);
233  hp = AV_CEIL_RSHIFT(h, draw->vsub[plane]);
234  if (!hp)
235  return;
236  p = p0;
237 
238  if (HAVE_BIGENDIAN && draw->desc->comp[0].depth > 8) {
239  for (x = 0; 2*x < draw->pixelstep[plane]; x++)
240  color_tmp.comp[plane].u16[x] = av_bswap16(color_tmp.comp[plane].u16[x]);
241  }
242 
243  /* copy first line from color */
244  for (x = 0; x < wp; x++) {
245  memcpy(p, color_tmp.comp[plane].u8, draw->pixelstep[plane]);
246  p += draw->pixelstep[plane];
247  }
248  wp *= draw->pixelstep[plane];
249  /* copy next lines from first line */
250  p = p0 + dst_linesize[plane];
251  for (y = 1; y < hp; y++) {
252  memcpy(p, p0, wp);
253  p += dst_linesize[plane];
254  }
255  }
256 }
257 
258 /**
259  * Clip interval [x; x+w[ within [0; wmax[.
260  * The resulting w may be negative if the final interval is empty.
261  * dx, if not null, return the difference between in and out value of x.
262  */
263 static void clip_interval(int wmax, int *x, int *w, int *dx)
264 {
265  if (dx)
266  *dx = 0;
267  if (*x < 0) {
268  if (dx)
269  *dx = -*x;
270  *w += *x;
271  *x = 0;
272  }
273  if (*x + *w > wmax)
274  *w = wmax - *x;
275 }
276 
277 /**
278  * Decompose w pixels starting at x
279  * into start + (w starting at x) + end
280  * with x and w aligned on multiples of 1<<sub.
281  */
282 static void subsampling_bounds(int sub, int *x, int *w, int *start, int *end)
283 {
284  int mask = (1 << sub) - 1;
285 
286  *start = (-*x) & mask;
287  *x += *start;
288  *start = FFMIN(*start, *w);
289  *w -= *start;
290  *end = *w & mask;
291  *w >>= sub;
292 }
293 
294 static int component_used(FFDrawContext *draw, int plane, int comp)
295 {
296  return (draw->comp_mask[plane] >> comp) & 1;
297 }
298 
299 /* If alpha is in the [ 0 ; 0x1010101 ] range,
300  then alpha * value is in the [ 0 ; 0xFFFFFFFF ] range,
301  and >> 24 gives a correct rounding. */
302 static void blend_line(uint8_t *dst, unsigned src, unsigned alpha,
303  int dx, int w, unsigned hsub, int left, int right)
304 {
305  unsigned asrc = alpha * src;
306  unsigned tau = 0x1010101 - alpha;
307  int x;
308 
309  if (left) {
310  unsigned suba = (left * alpha) >> hsub;
311  *dst = (*dst * (0x1010101 - suba) + src * suba) >> 24;
312  dst += dx;
313  }
314  for (x = 0; x < w; x++) {
315  *dst = (*dst * tau + asrc) >> 24;
316  dst += dx;
317  }
318  if (right) {
319  unsigned suba = (right * alpha) >> hsub;
320  *dst = (*dst * (0x1010101 - suba) + src * suba) >> 24;
321  }
322 }
323 
324 static void blend_line16(uint8_t *dst, unsigned src, unsigned alpha,
325  int dx, int w, unsigned hsub, int left, int right)
326 {
327  unsigned asrc = alpha * src;
328  unsigned tau = 0x10001 - alpha;
329  int x;
330 
331  if (left) {
332  unsigned suba = (left * alpha) >> hsub;
333  uint16_t value = AV_RL16(dst);
334  AV_WL16(dst, (value * (0x10001 - suba) + src * suba) >> 16);
335  dst += dx;
336  }
337  for (x = 0; x < w; x++) {
338  uint16_t value = AV_RL16(dst);
339  AV_WL16(dst, (value * tau + asrc) >> 16);
340  dst += dx;
341  }
342  if (right) {
343  unsigned suba = (right * alpha) >> hsub;
344  uint16_t value = AV_RL16(dst);
345  AV_WL16(dst, (value * (0x10001 - suba) + src * suba) >> 16);
346  }
347 }
348 
350  uint8_t *dst[], int dst_linesize[],
351  int dst_w, int dst_h,
352  int x0, int y0, int w, int h)
353 {
354  unsigned alpha, nb_planes, nb_comp, plane, comp;
355  int w_sub, h_sub, x_sub, y_sub, left, right, top, bottom, y;
356  uint8_t *p0, *p;
357 
358  /* TODO optimize if alpha = 0xFF */
359  clip_interval(dst_w, &x0, &w, NULL);
360  clip_interval(dst_h, &y0, &h, NULL);
361  if (w <= 0 || h <= 0 || !color->rgba[3])
362  return;
363  if (draw->desc->comp[0].depth <= 8) {
364  /* 0x10203 * alpha + 2 is in the [ 2 ; 0x1010101 - 2 ] range */
365  alpha = 0x10203 * color->rgba[3] + 0x2;
366  } else {
367  /* 0x101 * alpha is in the [ 2 ; 0x1001] range */
368  alpha = 0x101 * color->rgba[3] + 0x2;
369  }
370  nb_planes = draw->nb_planes - !!(draw->desc->flags & AV_PIX_FMT_FLAG_ALPHA && !(draw->flags & FF_DRAW_PROCESS_ALPHA));
371  nb_planes += !nb_planes;
372  for (plane = 0; plane < nb_planes; plane++) {
373  nb_comp = draw->pixelstep[plane];
374  p0 = pointer_at(draw, dst, dst_linesize, plane, x0, y0);
375  w_sub = w;
376  h_sub = h;
377  x_sub = x0;
378  y_sub = y0;
379  subsampling_bounds(draw->hsub[plane], &x_sub, &w_sub, &left, &right);
380  subsampling_bounds(draw->vsub[plane], &y_sub, &h_sub, &top, &bottom);
381  for (comp = 0; comp < nb_comp; comp++) {
382  const int depth = draw->desc->comp[comp].depth;
383 
384  if (!component_used(draw, plane, comp))
385  continue;
386  p = p0 + comp;
387  if (top) {
388  if (depth <= 8) {
389  blend_line(p, color->comp[plane].u8[comp], alpha >> 1,
390  draw->pixelstep[plane], w_sub,
391  draw->hsub[plane], left, right);
392  } else {
393  blend_line16(p, color->comp[plane].u16[comp], alpha >> 1,
394  draw->pixelstep[plane], w_sub,
395  draw->hsub[plane], left, right);
396  }
397  p += dst_linesize[plane];
398  }
399  if (depth <= 8) {
400  for (y = 0; y < h_sub; y++) {
401  blend_line(p, color->comp[plane].u8[comp], alpha,
402  draw->pixelstep[plane], w_sub,
403  draw->hsub[plane], left, right);
404  p += dst_linesize[plane];
405  }
406  } else {
407  for (y = 0; y < h_sub; y++) {
408  blend_line16(p, color->comp[plane].u16[comp], alpha,
409  draw->pixelstep[plane], w_sub,
410  draw->hsub[plane], left, right);
411  p += dst_linesize[plane];
412  }
413  }
414  if (bottom) {
415  if (depth <= 8) {
416  blend_line(p, color->comp[plane].u8[comp], alpha >> 1,
417  draw->pixelstep[plane], w_sub,
418  draw->hsub[plane], left, right);
419  } else {
420  blend_line16(p, color->comp[plane].u16[comp], alpha >> 1,
421  draw->pixelstep[plane], w_sub,
422  draw->hsub[plane], left, right);
423  }
424  }
425  }
426  }
427 }
428 
429 static void blend_pixel16(uint8_t *dst, unsigned src, unsigned alpha,
430  const uint8_t *mask, int mask_linesize, int l2depth,
431  unsigned w, unsigned h, unsigned shift, unsigned xm0)
432 {
433  unsigned xm, x, y, t = 0;
434  unsigned xmshf = 3 - l2depth;
435  unsigned xmmod = 7 >> l2depth;
436  unsigned mbits = (1 << (1 << l2depth)) - 1;
437  unsigned mmult = 255 / mbits;
438  uint16_t value = AV_RL16(dst);
439 
440  for (y = 0; y < h; y++) {
441  xm = xm0;
442  for (x = 0; x < w; x++) {
443  t += ((mask[xm >> xmshf] >> ((~xm & xmmod) << l2depth)) & mbits)
444  * mmult;
445  xm++;
446  }
447  mask += mask_linesize;
448  }
449  alpha = (t >> shift) * alpha;
450  AV_WL16(dst, ((0x10001 - alpha) * value + alpha * src) >> 16);
451 }
452 
453 static void blend_pixel(uint8_t *dst, unsigned src, unsigned alpha,
454  const uint8_t *mask, int mask_linesize, int l2depth,
455  unsigned w, unsigned h, unsigned shift, unsigned xm0)
456 {
457  unsigned xm, x, y, t = 0;
458  unsigned xmshf = 3 - l2depth;
459  unsigned xmmod = 7 >> l2depth;
460  unsigned mbits = (1 << (1 << l2depth)) - 1;
461  unsigned mmult = 255 / mbits;
462 
463  for (y = 0; y < h; y++) {
464  xm = xm0;
465  for (x = 0; x < w; x++) {
466  t += ((mask[xm >> xmshf] >> ((~xm & xmmod) << l2depth)) & mbits)
467  * mmult;
468  xm++;
469  }
470  mask += mask_linesize;
471  }
472  alpha = (t >> shift) * alpha;
473  *dst = ((0x1010101 - alpha) * *dst + alpha * src) >> 24;
474 }
475 
476 static void blend_line_hv16(uint8_t *dst, int dst_delta,
477  unsigned src, unsigned alpha,
478  const uint8_t *mask, int mask_linesize, int l2depth, int w,
479  unsigned hsub, unsigned vsub,
480  int xm, int left, int right, int hband)
481 {
482  int x;
483 
484  if (left) {
485  blend_pixel16(dst, src, alpha, mask, mask_linesize, l2depth,
486  left, hband, hsub + vsub, xm);
487  dst += dst_delta;
488  xm += left;
489  }
490  for (x = 0; x < w; x++) {
491  blend_pixel16(dst, src, alpha, mask, mask_linesize, l2depth,
492  1 << hsub, hband, hsub + vsub, xm);
493  dst += dst_delta;
494  xm += 1 << hsub;
495  }
496  if (right)
497  blend_pixel16(dst, src, alpha, mask, mask_linesize, l2depth,
498  right, hband, hsub + vsub, xm);
499 }
500 
501 static void blend_line_hv(uint8_t *dst, int dst_delta,
502  unsigned src, unsigned alpha,
503  const uint8_t *mask, int mask_linesize, int l2depth, int w,
504  unsigned hsub, unsigned vsub,
505  int xm, int left, int right, int hband)
506 {
507  int x;
508 
509  if (left) {
510  blend_pixel(dst, src, alpha, mask, mask_linesize, l2depth,
511  left, hband, hsub + vsub, xm);
512  dst += dst_delta;
513  xm += left;
514  }
515  for (x = 0; x < w; x++) {
516  blend_pixel(dst, src, alpha, mask, mask_linesize, l2depth,
517  1 << hsub, hband, hsub + vsub, xm);
518  dst += dst_delta;
519  xm += 1 << hsub;
520  }
521  if (right)
522  blend_pixel(dst, src, alpha, mask, mask_linesize, l2depth,
523  right, hband, hsub + vsub, xm);
524 }
525 
527  uint8_t *dst[], int dst_linesize[], int dst_w, int dst_h,
528  const uint8_t *mask, int mask_linesize, int mask_w, int mask_h,
529  int l2depth, unsigned endianness, int x0, int y0)
530 {
531  unsigned alpha, nb_planes, nb_comp, plane, comp;
532  int xm0, ym0, w_sub, h_sub, x_sub, y_sub, left, right, top, bottom, y;
533  uint8_t *p0, *p;
534  const uint8_t *m;
535 
536  clip_interval(dst_w, &x0, &mask_w, &xm0);
537  clip_interval(dst_h, &y0, &mask_h, &ym0);
538  mask += ym0 * mask_linesize;
539  if (mask_w <= 0 || mask_h <= 0 || !color->rgba[3])
540  return;
541  if (draw->desc->comp[0].depth <= 8) {
542  /* alpha is in the [ 0 ; 0x10203 ] range,
543  alpha * mask is in the [ 0 ; 0x1010101 - 4 ] range */
544  alpha = (0x10307 * color->rgba[3] + 0x3) >> 8;
545  } else {
546  alpha = (0x101 * color->rgba[3] + 0x2) >> 8;
547  }
548  nb_planes = draw->nb_planes - !!(draw->desc->flags & AV_PIX_FMT_FLAG_ALPHA && !(draw->flags & FF_DRAW_PROCESS_ALPHA));
549  nb_planes += !nb_planes;
550  for (plane = 0; plane < nb_planes; plane++) {
551  nb_comp = draw->pixelstep[plane];
552  p0 = pointer_at(draw, dst, dst_linesize, plane, x0, y0);
553  w_sub = mask_w;
554  h_sub = mask_h;
555  x_sub = x0;
556  y_sub = y0;
557  subsampling_bounds(draw->hsub[plane], &x_sub, &w_sub, &left, &right);
558  subsampling_bounds(draw->vsub[plane], &y_sub, &h_sub, &top, &bottom);
559  for (comp = 0; comp < nb_comp; comp++) {
560  const int depth = draw->desc->comp[comp].depth;
561 
562  if (!component_used(draw, plane, comp))
563  continue;
564  p = p0 + comp;
565  m = mask;
566  if (top) {
567  if (depth <= 8) {
568  blend_line_hv(p, draw->pixelstep[plane],
569  color->comp[plane].u8[comp], alpha,
570  m, mask_linesize, l2depth, w_sub,
571  draw->hsub[plane], draw->vsub[plane],
572  xm0, left, right, top);
573  } else {
574  blend_line_hv16(p, draw->pixelstep[plane],
575  color->comp[plane].u16[comp], alpha,
576  m, mask_linesize, l2depth, w_sub,
577  draw->hsub[plane], draw->vsub[plane],
578  xm0, left, right, top);
579  }
580  p += dst_linesize[plane];
581  m += top * mask_linesize;
582  }
583  if (depth <= 8) {
584  for (y = 0; y < h_sub; y++) {
585  blend_line_hv(p, draw->pixelstep[plane],
586  color->comp[plane].u8[comp], alpha,
587  m, mask_linesize, l2depth, w_sub,
588  draw->hsub[plane], draw->vsub[plane],
589  xm0, left, right, 1 << draw->vsub[plane]);
590  p += dst_linesize[plane];
591  m += mask_linesize << draw->vsub[plane];
592  }
593  } else {
594  for (y = 0; y < h_sub; y++) {
595  blend_line_hv16(p, draw->pixelstep[plane],
596  color->comp[plane].u16[comp], alpha,
597  m, mask_linesize, l2depth, w_sub,
598  draw->hsub[plane], draw->vsub[plane],
599  xm0, left, right, 1 << draw->vsub[plane]);
600  p += dst_linesize[plane];
601  m += mask_linesize << draw->vsub[plane];
602  }
603  }
604  if (bottom) {
605  if (depth <= 8) {
606  blend_line_hv(p, draw->pixelstep[plane],
607  color->comp[plane].u8[comp], alpha,
608  m, mask_linesize, l2depth, w_sub,
609  draw->hsub[plane], draw->vsub[plane],
610  xm0, left, right, bottom);
611  } else {
612  blend_line_hv16(p, draw->pixelstep[plane],
613  color->comp[plane].u16[comp], alpha,
614  m, mask_linesize, l2depth, w_sub,
615  draw->hsub[plane], draw->vsub[plane],
616  xm0, left, right, bottom);
617  }
618  }
619  }
620  }
621 }
622 
623 int ff_draw_round_to_sub(FFDrawContext *draw, int sub_dir, int round_dir,
624  int value)
625 {
626  unsigned shift = sub_dir ? draw->vsub_max : draw->hsub_max;
627 
628  if (!shift)
629  return value;
630  if (round_dir >= 0)
631  value += round_dir ? (1 << shift) - 1 : 1 << (shift - 1);
632  return (value >> shift) << shift;
633 }
634 
636 {
637  enum AVPixelFormat i;
638  FFDrawContext draw;
639  AVFilterFormats *fmts = NULL;
640  int ret;
641 
642  for (i = 0; av_pix_fmt_desc_get(i); i++)
643  if (ff_draw_init(&draw, i, flags) >= 0 &&
644  (ret = ff_add_format(&fmts, i)) < 0)
645  return NULL;
646  return fmts;
647 }
AV_LOG_WARNING
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:186
FFDrawColor
Definition: drawutils.h:49
AVPixelFormat
AVPixelFormat
Pixel format.
Definition: pixfmt.h:64
AV_PIX_FMT_BGR48LE
@ AV_PIX_FMT_BGR48LE
packed RGB 16:16:16, 48bpp, 16B, 16G, 16R, the 2-byte value for each R/G/B component is stored as lit...
Definition: pixfmt.h:139
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
RGB_TO_U_JPEG
#define RGB_TO_U_JPEG(r1, g1, b1)
Definition: colorspace.h:114
AV_PIX_FMT_BGRA64BE
@ AV_PIX_FMT_BGRA64BE
packed RGBA 16:16:16:16, 64bpp, 16B, 16G, 16R, 16A, the 2-byte value for each R/G/B/A component is st...
Definition: pixfmt.h:197
color
Definition: vf_paletteuse.c:587
comp
static void comp(unsigned char *dst, ptrdiff_t dst_stride, unsigned char *src, ptrdiff_t src_stride, int add)
Definition: eamad.c:85
AV_PIX_FMT_GBRP16BE
@ AV_PIX_FMT_GBRP16BE
planar GBR 4:4:4 48bpp, big-endian
Definition: pixfmt.h:164
sub
static float sub(float src0, float src1)
Definition: dnn_backend_native_layer_mathbinary.c:31
AV_PIX_FMT_GBRP10BE
@ AV_PIX_FMT_GBRP10BE
planar GBR 4:4:4 30bpp, big-endian
Definition: pixfmt.h:162
av_pix_fmt_desc_get
const AVPixFmtDescriptor * av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt)
Definition: pixdesc.c:2540
RGB_TO_U_CCIR
#define RGB_TO_U_CCIR(r1, g1, b1, shift)
Definition: colorspace.h:102
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:282
FFDrawColor::comp
union FFDrawColor::@200 comp[MAX_PLANES]
pixdesc.h
FFDrawContext::hsub_max
uint8_t hsub_max
Definition: drawutils.h:43
AV_PIX_FMT_RGBA64BE
@ AV_PIX_FMT_RGBA64BE
packed RGBA 16:16:16:16, 64bpp, 16R, 16G, 16B, 16A, the 2-byte value for each R/G/B/A component is st...
Definition: pixfmt.h:195
FFDrawContext::desc
const struct AVPixFmtDescriptor * desc
Definition: drawutils.h:36
AV_PIX_FMT_GBRAPF32LE
@ AV_PIX_FMT_GBRAPF32LE
IEEE-754 single precision planar GBRA 4:4:4:4, 128bpp, little-endian.
Definition: pixfmt.h:311
w
uint8_t w
Definition: llviddspenc.c:38
AV_PIX_FMT_GBRPF32BE
@ AV_PIX_FMT_GBRPF32BE
IEEE-754 single precision planar GBR 4:4:4, 96bpp, big-endian.
Definition: pixfmt.h:308
FFDrawColor::u16
uint16_t u16[8]
Definition: drawutils.h:53
AVComponentDescriptor::depth
int depth
Number of bits in the component.
Definition: pixdesc.h:57
AVPixFmtDescriptor::name
const char * name
Definition: pixdesc.h:70
data
const char data[16]
Definition: mxf.c:143
AV_PIX_FMT_P010BE
@ AV_PIX_FMT_P010BE
like NV12, with 10bpp per component, data in the high bits, zeros in the low bits,...
Definition: pixfmt.h:275
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:429
AV_PIX_FMT_GBRP14BE
@ AV_PIX_FMT_GBRP14BE
planar GBR 4:4:4 42bpp, big-endian
Definition: pixfmt.h:246
AV_PIX_FMT_BGR24
@ AV_PIX_FMT_BGR24
packed RGB 8:8:8, 24bpp, BGRBGR...
Definition: pixfmt.h:69
AV_PIX_FMT_BGRA
@ AV_PIX_FMT_BGRA
packed BGRA 8:8:8:8, 32bpp, BGRABGRA...
Definition: pixfmt.h:95
FFMAX
#define FFMAX(a, b)
Definition: macros.h:47
FFDrawContext::nb_planes
unsigned nb_planes
Definition: drawutils.h:38
AV_PIX_FMT_GRAY10LE
@ AV_PIX_FMT_GRAY10LE
Y , 10bpp, little-endian.
Definition: pixfmt.h:288
FFDrawContext::pixelstep
int pixelstep[MAX_PLANES]
Definition: drawutils.h:39
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_GBRAP12LE
@ AV_PIX_FMT_GBRAP12LE
planar GBR 4:4:4:4 48bpp, little-endian
Definition: pixfmt.h:278
FFDrawContext::vsub_max
uint8_t vsub_max
Definition: drawutils.h:44
AV_PIX_FMT_GBRAP
@ AV_PIX_FMT_GBRAP
planar GBRA 4:4:4:4 32bpp
Definition: pixfmt.h:205
AV_PIX_FMT_GRAY9LE
@ AV_PIX_FMT_GRAY9LE
Y , 9bpp, little-endian.
Definition: pixfmt.h:306
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:526
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:248
colorspace.h
RED
@ RED
Definition: drawutils.c:31
RGB_TO_V_JPEG
#define RGB_TO_V_JPEG(r1, g1, b1)
Definition: colorspace.h:118
mask
static const uint16_t mask[17]
Definition: lzw.c:38
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:79
AV_PIX_FMT_GBRAP16BE
@ AV_PIX_FMT_GBRAP16BE
planar GBRA 4:4:4:4 64bpp, big-endian
Definition: pixfmt.h:206
full_range
bool full_range
Definition: hwcontext_videotoolbox.c:42
intreadwrite.h
MAX_PLANES
#define MAX_PLANES
Definition: ffv1.h:48
AV_PIX_FMT_GBRP16LE
@ AV_PIX_FMT_GBRP16LE
planar GBR 4:4:4 48bpp, little-endian
Definition: pixfmt.h:165
AV_CEIL_RSHIFT
#define AV_CEIL_RSHIFT(a, b)
Definition: common.h:51
FFDrawContext::vsub
uint8_t vsub[MAX_PLANES]
Definition: drawutils.h:42
RGB_TO_Y_CCIR
#define RGB_TO_Y_CCIR(r, g, b)
Definition: colorspace.h:98
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:200
AV_PIX_FMT_P016BE
@ AV_PIX_FMT_P016BE
like NV12, with 16bpp per component, big-endian
Definition: pixfmt.h:291
FF_DRAW_PROCESS_ALPHA
#define FF_DRAW_PROCESS_ALPHA
Process alpha pixel component.
Definition: drawutils.h:61
AV_PIX_FMT_GBRP12LE
@ AV_PIX_FMT_GBRP12LE
planar GBR 4:4:4 36bpp, little-endian
Definition: pixfmt.h:245
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:476
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
pix_fmt
static enum AVPixelFormat pix_fmt
Definition: demuxing_decoding.c:41
ff_draw_init
int ff_draw_init(FFDrawContext *draw, enum AVPixelFormat format, unsigned flags)
Init a draw context.
Definition: drawutils.c:82
AV_PIX_FMT_GBRP10LE
@ AV_PIX_FMT_GBRP10LE
planar GBR 4:4:4 30bpp, little-endian
Definition: pixfmt.h:163
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:80
AV_PIX_FMT_RGBA
@ AV_PIX_FMT_RGBA
packed RGBA 8:8:8:8, 32bpp, RGBARGBA...
Definition: pixfmt.h:93
AV_PIX_FMT_GRAY8A
@ AV_PIX_FMT_GRAY8A
alias for AV_PIX_FMT_YA8
Definition: pixfmt.h:136
AV_PIX_FMT_GBRAPF32BE
@ AV_PIX_FMT_GBRAPF32BE
IEEE-754 single precision planar GBRA 4:4:4:4, 128bpp, big-endian.
Definition: pixfmt.h:310
AV_PIX_FMT_GBRAP12BE
@ AV_PIX_FMT_GBRAP12BE
planar GBR 4:4:4:4 48bpp, big-endian
Definition: pixfmt.h:277
NULL
#define NULL
Definition: coverity.c:32
AVComponentDescriptor
Definition: pixdesc.h:30
AV_PIX_FMT_RGB48LE
@ AV_PIX_FMT_RGB48LE
packed RGB 16:16:16, 48bpp, 16R, 16G, 16B, the 2-byte value for each R/G/B component is stored as lit...
Definition: pixfmt.h:103
AV_PIX_FMT_YA16LE
@ AV_PIX_FMT_YA16LE
16 bits gray, 16 bits alpha (little-endian)
Definition: pixfmt.h:203
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:78
RGB_TO_V_CCIR
#define RGB_TO_V_CCIR(r1, g1, b1, shift)
Definition: colorspace.h:106
AV_PIX_FMT_RGBA64LE
@ AV_PIX_FMT_RGBA64LE
packed RGBA 16:16:16:16, 64bpp, 16R, 16G, 16B, 16A, the 2-byte value for each R/G/B/A component is st...
Definition: pixfmt.h:196
src
#define src
Definition: vp8dsp.c:255
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:419
AV_PIX_FMT_BGR0
@ AV_PIX_FMT_BGR0
packed BGR 8:8:8, 32bpp, BGRXBGRX... X=unused/undefined
Definition: pixfmt.h:230
FFDrawColor::u8
uint8_t u8[16]
Definition: drawutils.h:54
AV_PIX_FMT_GRAY8
@ AV_PIX_FMT_GRAY8
Y , 8bpp.
Definition: pixfmt.h:74
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:263
AVPixFmtDescriptor::flags
uint64_t flags
Combination of AV_PIX_FMT_FLAG_...
Definition: pixdesc.h:94
AV_PIX_FMT_ABGR
@ AV_PIX_FMT_ABGR
packed ABGR 8:8:8:8, 32bpp, ABGRABGR...
Definition: pixfmt.h:94
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
AV_PIX_FMT_RGB24
@ AV_PIX_FMT_RGB24
packed RGB 8:8:8, 24bpp, RGBRGB...
Definition: pixfmt.h:68
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
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:349
FFDrawContext::format
enum AVPixelFormat format
Definition: drawutils.h:37
color
static const uint32_t color[16+AV_CLASS_CATEGORY_NB]
Definition: log.c:92
AV_PIX_FMT_GRAY12LE
@ AV_PIX_FMT_GRAY12LE
Y , 12bpp, little-endian.
Definition: pixfmt.h:286
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:222
AV_PIX_FMT_GBRP9BE
@ AV_PIX_FMT_GBRP9BE
planar GBR 4:4:4 27bpp, big-endian
Definition: pixfmt.h:160
FFDrawContext::comp_mask
uint8_t comp_mask[MAX_PLANES]
Definition: drawutils.h:40
component_used
static int component_used(FFDrawContext *draw, int plane, int comp)
Definition: drawutils.c:294
BLUE
@ BLUE
Definition: drawutils.c:31
AV_PIX_FMT_GBRP9LE
@ AV_PIX_FMT_GBRP9LE
planar GBR 4:4:4 27bpp, little-endian
Definition: pixfmt.h:161
AV_WL16
#define AV_WL16(p, v)
Definition: intreadwrite.h:412
AV_PIX_FMT_GBRAP10LE
@ AV_PIX_FMT_GBRAP10LE
planar GBR 4:4:4:4 40bpp, little-endian
Definition: pixfmt.h:281
av_bswap16
#define av_bswap16
Definition: bswap.h:31
AV_PIX_FMT_RGB0
@ AV_PIX_FMT_RGB0
packed RGB 8:8:8, 32bpp, RGBXRGBX... X=unused/undefined
Definition: pixfmt.h:228
AV_PIX_FMT_ARGB
@ AV_PIX_FMT_ARGB
packed ARGB 8:8:8:8, 32bpp, ARGBARGB...
Definition: pixfmt.h:92
AV_PIX_FMT_BGRA64LE
@ AV_PIX_FMT_BGRA64LE
packed RGBA 16:16:16:16, 64bpp, 16B, 16G, 16R, 16A, the 2-byte value for each R/G/B/A component is st...
Definition: pixfmt.h:198
ALPHA
@ ALPHA
Definition: drawutils.c:31
i
int i
Definition: input.c:406
AV_PIX_FMT_RGB48BE
@ AV_PIX_FMT_RGB48BE
packed RGB 16:16:16, 48bpp, 16R, 16G, 16B, the 2-byte value for each R/G/B component is stored as big...
Definition: pixfmt.h:102
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:635
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:623
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:100
FFDrawContext
Definition: drawutils.h:35
AV_PIX_FMT_GBRPF32LE
@ AV_PIX_FMT_GBRPF32LE
IEEE-754 single precision planar GBR 4:4:4, 96bpp, little-endian.
Definition: pixfmt.h:309
ff_draw_color
void ff_draw_color(FFDrawContext *draw, FFDrawColor *color, const uint8_t rgba[4])
Prepare a color.
Definition: drawutils.c:135
AV_PIX_FMT_GBRAP16LE
@ AV_PIX_FMT_GBRAP16LE
planar GBRA 4:4:4:4 64bpp, little-endian
Definition: pixfmt.h:207
ret
ret
Definition: filter_design.txt:187
AV_PIX_FMT_0BGR
@ AV_PIX_FMT_0BGR
packed BGR 8:8:8, 32bpp, XBGRXBGR... X=unused/undefined
Definition: pixfmt.h:229
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:453
AV_PIX_FMT_P016LE
@ AV_PIX_FMT_P016LE
like NV12, with 16bpp per component, little-endian
Definition: pixfmt.h:290
FFDrawContext::hsub
uint8_t hsub[MAX_PLANES]
Definition: drawutils.h:41
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_GBRP12BE
@ AV_PIX_FMT_GBRP12BE
planar GBR 4:4:4 36bpp, big-endian
Definition: pixfmt.h:244
EXPAND
#define EXPAND(compn)
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:302
AVPixFmtDescriptor::comp
AVComponentDescriptor comp[4]
Parameters that describe how pixels are packed.
Definition: pixdesc.h:105
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
shift
static int shift(int a, int b)
Definition: sonic.c:83
AV_PIX_FMT_GBRP
@ AV_PIX_FMT_GBRP
planar GBR 4:4:4 24bpp
Definition: pixfmt.h:158
desc
const char * desc
Definition: libsvtav1.c:79
AV_PIX_FMT_GRAY16LE
@ AV_PIX_FMT_GRAY16LE
Y , 16bpp, little-endian.
Definition: pixfmt.h:98
avutil.h
AV_PIX_FMT_P010LE
@ AV_PIX_FMT_P010LE
like NV12, with 10bpp per component, data in the high bits, zeros in the low bits,...
Definition: pixfmt.h:274
AVPixFmtDescriptor
Descriptor that unambiguously describes how the bits of a pixel are stored in the up to 4 data planes...
Definition: pixdesc.h:69
alpha
static const int16_t alpha[]
Definition: ilbcdata.h:55
AV_PIX_FMT_GRAY14LE
@ AV_PIX_FMT_GRAY14LE
Y , 14bpp, little-endian.
Definition: pixfmt.h:328
pointer_at
static uint8_t * pointer_at(FFDrawContext *draw, uint8_t *data[], int linesize[], int plane, int x, int y)
Definition: drawutils.c:192
format
fg outputs[0] format
Definition: ffmpeg_filter.c:175
FFDrawContext::flags
unsigned flags
Definition: drawutils.h:46
ff_fill_rgba_map
int ff_fill_rgba_map(uint8_t *rgba_map, enum AVPixelFormat pix_fmt)
Definition: drawutils.c:33
AV_PIX_FMT_GBRP14LE
@ AV_PIX_FMT_GBRP14LE
planar GBR 4:4:4 42bpp, little-endian
Definition: pixfmt.h:247
flags
#define flags(name, subs,...)
Definition: cbs_av1.c:561
AV_PIX_FMT_0RGB
@ AV_PIX_FMT_0RGB
packed RGB 8:8:8, 32bpp, XRGBXRGB... X=unused/undefined
Definition: pixfmt.h:227
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:501
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:28
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:324
AV_PIX_FMT_GBRAP10BE
@ AV_PIX_FMT_GBRAP10BE
planar GBR 4:4:4:4 40bpp, big-endian
Definition: pixfmt.h:280
h
h
Definition: vp9dsp_template.c:2038
drawutils.h
RGB_TO_Y_JPEG
#define RGB_TO_Y_JPEG(r, g, b)
Definition: colorspace.h:110
GREEN
@ GREEN
Definition: drawutils.c:31
FFDrawContext::full_range
int full_range
Definition: drawutils.h:45
AV_PIX_FMT_BGR48BE
@ AV_PIX_FMT_BGR48BE
packed RGB 16:16:16, 48bpp, 16B, 16G, 16R, the 2-byte value for each R/G/B component is stored as big...
Definition: pixfmt.h:138