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