FFmpeg
vf_nnedi.c
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2010-2011 Kevin Stone
3  * Copyright (C) 2016 Paul B Mahol
4  *
5  * This file is part of FFmpeg.
6  *
7  * FFmpeg is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * (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
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License along
18  * with FFmpeg; if not, write to the Free Software Foundation, Inc.,
19  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20  */
21 
22 #include <float.h>
23 
24 #include "libavutil/common.h"
25 #include "libavutil/float_dsp.h"
26 #include "libavutil/imgutils.h"
27 #include "libavutil/mem_internal.h"
28 #include "libavutil/opt.h"
29 #include "libavutil/pixdesc.h"
30 #include "avfilter.h"
31 #include "formats.h"
32 #include "internal.h"
33 #include "video.h"
34 
35 static const size_t NNEDI_WEIGHTS_SIZE = 13574928;
36 static const uint8_t NNEDI_XDIM[] = { 8, 16, 32, 48, 8, 16, 32 };
37 static const uint8_t NNEDI_YDIM[] = { 6, 6, 6, 6, 4, 4, 4 };
38 static const uint16_t NNEDI_NNS[] = { 16, 32, 64, 128, 256 };
39 
41  DECLARE_ALIGNED(32, float, kernel_l0)[4][14 * 4];
42  DECLARE_ALIGNED(32, float, bias_l0)[4];
43 
44  DECLARE_ALIGNED(32, float, kernel_l1)[4][4];
45  DECLARE_ALIGNED(32, float, bias_l1)[4];
46 
47  DECLARE_ALIGNED(32, float, kernel_l2)[4][8];
48  DECLARE_ALIGNED(32, float, bias_l2)[4];
50 
52  DECLARE_ALIGNED(32, float, kernel_l0)[4][16 * 4];
53  DECLARE_ALIGNED(32, float, bias_l0)[4];
54 
55  DECLARE_ALIGNED(32, float, kernel_l1)[4][4];
56  DECLARE_ALIGNED(32, float, bias_l1)[4];
58 
59 typedef struct PredictorCoefficients {
60  int xdim, ydim, nns, nsize;
61  float *data;
62  float *softmax_q1;
63  float *elliott_q1;
66  float *softmax_q2;
67  float *elliott_q2;
71 
72 typedef struct NNEDIContext {
73  const AVClass *class;
74 
75  char *weights_file;
76 
80  int eof;
81  int64_t cur_pts;
82 
84  int depth;
85  int nb_planes;
87  int linesize[4];
88  int planewidth[4];
89  int planeheight[4];
90  int field_n;
91 
93  PrescreenerNewCoefficients prescreener_new[3];
94  PredictorCoefficients coeffs[2][5][7];
95 
96  float half;
97  float in_scale;
98  float out_scale;
99 
100  // Parameters
101  int deint;
102  int field;
104  int nsize;
105  int nnsparam;
106  int qual;
107  int etype;
108  int pscrn;
109 
112  float *input_buf;
113  float *output_buf;
114 
115  void (*read)(const uint8_t *src, float *dst,
116  int src_stride, int dst_stride,
117  int width, int height, float scale);
118  void (*write)(const float *src, uint8_t *dst,
119  int src_stride, int dst_stride,
120  int width, int height, int depth, float scale);
121  void (*prescreen[2])(AVFilterContext *ctx,
122  const void *src, ptrdiff_t src_stride,
123  uint8_t *prescreen, int N, void *data);
124 } NNEDIContext;
125 
126 #define OFFSET(x) offsetof(NNEDIContext, x)
127 #define RFLAGS AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_RUNTIME_PARAM
128 #define FLAGS AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_FILTERING_PARAM
129 
130 static const AVOption nnedi_options[] = {
131  {"weights", "set weights file", OFFSET(weights_file), AV_OPT_TYPE_STRING, {.str="nnedi3_weights.bin"}, 0, 0, FLAGS },
132  {"deint", "set which frames to deinterlace", OFFSET(deint), AV_OPT_TYPE_INT, {.i64=0}, 0, 1, RFLAGS, "deint" },
133  {"all", "deinterlace all frames", 0, AV_OPT_TYPE_CONST, {.i64=0}, 0, 0, RFLAGS, "deint" },
134  {"interlaced", "only deinterlace frames marked as interlaced", 0, AV_OPT_TYPE_CONST, {.i64=1}, 0, 0, RFLAGS, "deint" },
135  {"field", "set mode of operation", OFFSET(field), AV_OPT_TYPE_INT, {.i64=-1}, -2, 3, RFLAGS, "field" },
136  {"af", "use frame flags, both fields", 0, AV_OPT_TYPE_CONST, {.i64=-2}, 0, 0, RFLAGS, "field" },
137  {"a", "use frame flags, single field", 0, AV_OPT_TYPE_CONST, {.i64=-1}, 0, 0, RFLAGS, "field" },
138  {"t", "use top field only", 0, AV_OPT_TYPE_CONST, {.i64=0}, 0, 0, RFLAGS, "field" },
139  {"b", "use bottom field only", 0, AV_OPT_TYPE_CONST, {.i64=1}, 0, 0, RFLAGS, "field" },
140  {"tf", "use both fields, top first", 0, AV_OPT_TYPE_CONST, {.i64=2}, 0, 0, RFLAGS, "field" },
141  {"bf", "use both fields, bottom first", 0, AV_OPT_TYPE_CONST, {.i64=3}, 0, 0, RFLAGS, "field" },
142  {"planes", "set which planes to process", OFFSET(process_plane), AV_OPT_TYPE_INT, {.i64=7}, 0, 15, RFLAGS },
143  {"nsize", "set size of local neighborhood around each pixel, used by the predictor neural network", OFFSET(nsize), AV_OPT_TYPE_INT, {.i64=6}, 0, 6, RFLAGS, "nsize" },
144  {"s8x6", NULL, 0, AV_OPT_TYPE_CONST, {.i64=0}, 0, 0, RFLAGS, "nsize" },
145  {"s16x6", NULL, 0, AV_OPT_TYPE_CONST, {.i64=1}, 0, 0, RFLAGS, "nsize" },
146  {"s32x6", NULL, 0, AV_OPT_TYPE_CONST, {.i64=2}, 0, 0, RFLAGS, "nsize" },
147  {"s48x6", NULL, 0, AV_OPT_TYPE_CONST, {.i64=3}, 0, 0, RFLAGS, "nsize" },
148  {"s8x4", NULL, 0, AV_OPT_TYPE_CONST, {.i64=4}, 0, 0, RFLAGS, "nsize" },
149  {"s16x4", NULL, 0, AV_OPT_TYPE_CONST, {.i64=5}, 0, 0, RFLAGS, "nsize" },
150  {"s32x4", NULL, 0, AV_OPT_TYPE_CONST, {.i64=6}, 0, 0, RFLAGS, "nsize" },
151  {"nns", "set number of neurons in predictor neural network", OFFSET(nnsparam), AV_OPT_TYPE_INT, {.i64=1}, 0, 4, RFLAGS, "nns" },
152  {"n16", NULL, 0, AV_OPT_TYPE_CONST, {.i64=0}, 0, 0, RFLAGS, "nns" },
153  {"n32", NULL, 0, AV_OPT_TYPE_CONST, {.i64=1}, 0, 0, RFLAGS, "nns" },
154  {"n64", NULL, 0, AV_OPT_TYPE_CONST, {.i64=2}, 0, 0, RFLAGS, "nns" },
155  {"n128", NULL, 0, AV_OPT_TYPE_CONST, {.i64=3}, 0, 0, RFLAGS, "nns" },
156  {"n256", NULL, 0, AV_OPT_TYPE_CONST, {.i64=4}, 0, 0, RFLAGS, "nns" },
157  {"qual", "set quality", OFFSET(qual), AV_OPT_TYPE_INT, {.i64=1}, 1, 2, RFLAGS, "qual" },
158  {"fast", NULL, 0, AV_OPT_TYPE_CONST, {.i64=1}, 0, 0, RFLAGS, "qual" },
159  {"slow", NULL, 0, AV_OPT_TYPE_CONST, {.i64=2}, 0, 0, RFLAGS, "qual" },
160  {"etype", "set which set of weights to use in the predictor", OFFSET(etype), AV_OPT_TYPE_INT, {.i64=0}, 0, 1, RFLAGS, "etype" },
161  {"a", "weights trained to minimize absolute error", 0, AV_OPT_TYPE_CONST, {.i64=0}, 0, 0, RFLAGS, "etype" },
162  {"abs","weights trained to minimize absolute error", 0, AV_OPT_TYPE_CONST, {.i64=0}, 0, 0, RFLAGS, "etype" },
163  {"s", "weights trained to minimize squared error", 0, AV_OPT_TYPE_CONST, {.i64=1}, 0, 0, RFLAGS, "etype" },
164  {"mse","weights trained to minimize squared error", 0, AV_OPT_TYPE_CONST, {.i64=1}, 0, 0, RFLAGS, "etype" },
165  {"pscrn", "set prescreening", OFFSET(pscrn), AV_OPT_TYPE_INT, {.i64=2}, 0, 4, RFLAGS, "pscrn" },
166  {"none", NULL, 0, AV_OPT_TYPE_CONST, {.i64=0}, 0, 0, RFLAGS, "pscrn" },
167  {"original", NULL, 0, AV_OPT_TYPE_CONST, {.i64=1}, 0, 0, RFLAGS, "pscrn" },
168  {"new", NULL, 0, AV_OPT_TYPE_CONST, {.i64=2}, 0, 0, RFLAGS, "pscrn" },
169  {"new2", NULL, 0, AV_OPT_TYPE_CONST, {.i64=3}, 0, 0, RFLAGS, "pscrn" },
170  {"new3", NULL, 0, AV_OPT_TYPE_CONST, {.i64=4}, 0, 0, RFLAGS, "pscrn" },
171  { NULL }
172 };
173 
174 AVFILTER_DEFINE_CLASS(nnedi);
175 
176 static int config_output(AVFilterLink *outlink)
177 {
178  AVFilterContext *ctx = outlink->src;
179 
180  outlink->time_base.num = ctx->inputs[0]->time_base.num;
181  outlink->time_base.den = ctx->inputs[0]->time_base.den * 2;
182  outlink->w = ctx->inputs[0]->w;
183  outlink->h = ctx->inputs[0]->h;
184 
185  outlink->frame_rate = av_mul_q(ctx->inputs[0]->frame_rate,
186  (AVRational){2, 1});
187 
188  return 0;
189 }
190 
192 {
193  static const enum AVPixelFormat pix_fmts[] = {
217  };
218 
219  AVFilterFormats *fmts_list = ff_make_format_list(pix_fmts);
220  if (!fmts_list)
221  return AVERROR(ENOMEM);
222  return ff_set_common_formats(ctx, fmts_list);
223 }
224 
225 static float dot_dsp(NNEDIContext *s, const float *kernel, const float *input,
226  int n, float scale, float bias)
227 {
228  float sum;
229 
230  sum = s->fdsp->scalarproduct_float(kernel, input, n);
231 
232  return sum * scale + bias;
233 }
234 
235 static float elliott(float x)
236 {
237  return x / (1.0f + fabsf(x));
238 }
239 
240 static void transform_elliott(float *input, int size)
241 {
242  for (int i = 0; i < size; i++)
243  input[i] = elliott(input[i]);
244 }
245 
247  const void *src, ptrdiff_t src_stride,
248  uint8_t *prescreen, int N,
249  void *data)
250 {
251  NNEDIContext *s = ctx->priv;
252  const PrescreenerOldCoefficients *const m_data = data;
253  const float *src_p = src;
254 
255  // Adjust source pointer to point to top-left of filter window.
256  const float *window = src_p - 2 * src_stride - 5;
257 
258  for (int j = 0; j < N; j++) {
259  LOCAL_ALIGNED_32(float, input, [48]);
260  float state[12];
261 
262  for (int i = 0; i < 4; i++)
263  memcpy(input + i * 12, window + i * src_stride + j, 12 * sizeof(float));
264 
265  // Layer 0.
266  for (int n = 0; n < 4; n++)
267  state[n] = dot_dsp(s, m_data->kernel_l0[n], input, 48, 1.0f, m_data->bias_l0[n]);
268  transform_elliott(state + 1, 3);
269 
270  // Layer 1.
271  for (int n = 0; n < 4; n++)
272  state[n + 4] = dot_dsp(s, m_data->kernel_l1[n], state, 4, 1.0f, m_data->bias_l1[n]);
273  transform_elliott(state + 4, 3);
274 
275  // Layer 2.
276  for (int n = 0; n < 4; n++)
277  state[n + 8] = dot_dsp(s, m_data->kernel_l2[n], state, 8, 1.0f, m_data->bias_l2[n]);
278 
279  prescreen[j] = FFMAX(state[10], state[11]) <= FFMAX(state[8], state[9]) ? 255 : 0;
280  }
281 }
282 
284  const void *src, ptrdiff_t src_stride,
285  uint8_t *prescreen, int N,
286  void *data)
287 {
288  NNEDIContext *s = ctx->priv;
289  const PrescreenerNewCoefficients *const m_data = data;
290  const float *src_p = src;
291 
292  // Adjust source pointer to point to top-left of filter window.
293  const float *window = src_p - 2 * src_stride - 6;
294 
295  for (int j = 0; j < N; j += 4) {
296  LOCAL_ALIGNED_32(float, input, [64]);
297  float state[8];
298 
299  for (int i = 0; i < 4; i++)
300  memcpy(input + i * 16, window + i * src_stride + j, 16 * sizeof(float));
301 
302  for (int n = 0; n < 4; n++)
303  state[n] = dot_dsp(s, m_data->kernel_l0[n], input, 64, 1.0f, m_data->bias_l0[n]);
304  transform_elliott(state, 4);
305 
306  for (int n = 0; n < 4; n++)
307  state[n + 4] = dot_dsp(s, m_data->kernel_l1[n], state, 4, 1.0f, m_data->bias_l1[n]);
308 
309  for (int n = 0; n < 4; n++)
310  prescreen[j + n] = state[n + 4] > 0.f;
311  }
312 }
313 
314 static int filter_offset(int nn, const PredictorCoefficients *const model)
315 {
316  return nn * model->nsize;
317 }
318 
319 static const float *softmax_q1_filter(int nn,
320  const PredictorCoefficients *const model)
321 {
322  return model->softmax_q1 + filter_offset(nn, model);
323 }
324 
325 static const float *elliott_q1_filter(int nn,
326  const PredictorCoefficients *const model)
327 {
328  return model->elliott_q1 + filter_offset(nn, model);
329 }
330 
331 static const float *softmax_q2_filter(int nn,
332  const PredictorCoefficients *const model)
333 {
334  return model->softmax_q2 + filter_offset(nn, model);
335 }
336 
337 static const float *elliott_q2_filter(int nn,
338  const PredictorCoefficients *const model)
339 {
340  return model->elliott_q2 + filter_offset(nn, model);
341 }
342 
343 static void gather_input(const float *src, ptrdiff_t src_stride,
344  float *buf, float mstd[4],
345  const PredictorCoefficients *const model)
346 {
347  float sum = 0;
348  float sum_sq = 0;
349  float tmp;
350 
351  for (int i = 0; i < model->ydim; i++) {
352  memcpy(buf, src, model->xdim * sizeof(float));
353 
354  for (int j = 0; j < model->xdim; j++) {
355  const float val = src[j];
356 
357  sum += val;
358  sum_sq += val * val;
359  }
360 
361  src += src_stride;
362  buf += model->xdim;
363  }
364 
365  mstd[0] = sum / model->nsize;
366  mstd[3] = 0.f;
367 
368  tmp = sum_sq / model->nsize - mstd[0] * mstd[0];
369  if (tmp < FLT_EPSILON) {
370  mstd[1] = 0.0f;
371  mstd[2] = 0.0f;
372  } else {
373  mstd[1] = sqrtf(tmp);
374  mstd[2] = 1.0f / mstd[1];
375  }
376 }
377 
378 static float softmax_exp(float x)
379 {
380  return expf(av_clipf(x, -80.f, 80.f));
381 }
382 
383 static void transform_softmax_exp(float *input, int size)
384 {
385  for (int i = 0; i < size; i++)
386  input[i] = softmax_exp(input[i]);
387 }
388 
389 static void wae5(const float *softmax, const float *el,
390  int n, float mstd[4])
391 {
392  float vsum = 0.0f, wsum = 0.0f;
393 
394  for (int i = 0; i < n; i++) {
395  vsum += softmax[i] * elliott(el[i]);
396  wsum += softmax[i];
397  }
398 
399  if (wsum > 1e-10f)
400  mstd[3] += (5.0f * vsum) / wsum * mstd[1] + mstd[0];
401  else
402  mstd[3] += mstd[0];
403 }
404 
406  const void *src, ptrdiff_t src_stride, void *dst,
407  const uint8_t *prescreen, int N,
408  void *data, int use_q2)
409 {
410  NNEDIContext *s = ctx->priv;
411  const PredictorCoefficients *const model = data;
412  const float *src_p = src;
413  float *dst_p = dst;
414 
415  // Adjust source pointer to point to top-left of filter window.
416  const float *window = src_p - (model->ydim / 2) * src_stride - (model->xdim / 2 - 1);
417  int filter_size = model->nsize;
418  int nns = model->nns;
419 
420  for (int i = 0; i < N; i++) {
421  LOCAL_ALIGNED_32(float, input, [48 * 6]);
422  float activation[256 * 2];
423  float mstd[4];
424  float scale;
425 
426  if (prescreen[i])
427  continue;
428 
429  gather_input(window + i, src_stride, input, mstd, model);
430  scale = mstd[2];
431 
432  for (int nn = 0; nn < nns; nn++)
433  activation[nn] = dot_dsp(s, softmax_q1_filter(nn, model), input, filter_size, scale, model->softmax_bias_q1[nn]);
434 
435  for (int nn = 0; nn < nns; nn++)
436  activation[model->nns + nn] = dot_dsp(s, elliott_q1_filter(nn, model), input, filter_size, scale, model->elliott_bias_q1[nn]);
437 
438  transform_softmax_exp(activation, nns);
439  wae5(activation, activation + nns, nns, mstd);
440 
441  if (use_q2) {
442  for (int nn = 0; nn < nns; nn++)
443  activation[nn] = dot_dsp(s, softmax_q2_filter(nn, model), input, filter_size, scale, model->softmax_bias_q2[nn]);
444 
445  for (int nn = 0; nn < nns; nn++)
446  activation[nns + nn] = dot_dsp(s, elliott_q2_filter(nn, model), input, filter_size, scale, model->elliott_bias_q2[nn]);
447 
448  transform_softmax_exp(activation, nns);
449  wae5(activation, activation + nns, nns, mstd);
450  }
451 
452  dst_p[i] = mstd[3] / (use_q2 ? 2 : 1);
453  }
454 }
455 
456 static void read_bytes(const uint8_t *src, float *dst,
457  int src_stride, int dst_stride,
458  int width, int height, float scale)
459 {
460  for (int y = 0; y < height; y++) {
461  for (int x = 0; x < 32; x++)
462  dst[-x - 1] = src[x];
463 
464  for (int x = 0; x < width; x++)
465  dst[x] = src[x];
466 
467  for (int x = 0; x < 32; x++)
468  dst[width + x] = src[width - x - 1];
469 
470  dst += dst_stride;
471  src += src_stride;
472  }
473 }
474 
475 static void read_words(const uint8_t *srcp, float *dst,
476  int src_stride, int dst_stride,
477  int width, int height, float scale)
478 {
479  const uint16_t *src = (const uint16_t *)srcp;
480 
481  src_stride /= 2;
482 
483  for (int y = 0; y < height; y++) {
484  for (int x = 0; x < 32; x++)
485  dst[-x - 1] = src[x] * scale;
486 
487  for (int x = 0; x < width; x++)
488  dst[x] = src[x] * scale;
489 
490  for (int x = 0; x < 32; x++)
491  dst[width + x] = src[width - x - 1] * scale;
492 
493  dst += dst_stride;
494  src += src_stride;
495  }
496 }
497 
498 static void write_bytes(const float *src, uint8_t *dst,
499  int src_stride, int dst_stride,
500  int width, int height, int depth,
501  float scale)
502 {
503  for (int y = 0; y < height; y++) {
504  for (int x = 0; x < width; x++)
505  dst[x] = av_clip_uint8(src[x]);
506 
507  dst += dst_stride;
508  src += src_stride;
509  }
510 }
511 
512 static void write_words(const float *src, uint8_t *dstp,
513  int src_stride, int dst_stride,
514  int width, int height, int depth,
515  float scale)
516 {
517  uint16_t *dst = (uint16_t *)dstp;
518 
519  dst_stride /= 2;
520 
521  for (int y = 0; y < height; y++) {
522  for (int x = 0; x < width; x++)
523  dst[x] = av_clip_uintp2_c(src[x] * scale, depth);
524 
525  dst += dst_stride;
526  src += src_stride;
527  }
528 }
529 
530 static void interpolation(const void *src, ptrdiff_t src_stride,
531  void *dst, const uint8_t *prescreen, int n)
532 {
533  const float *src_p = src;
534  float *dst_p = dst;
535  const float *window = src_p - 2 * src_stride;
536 
537  for (int i = 0; i < n; i++) {
538  float accum = 0.0f;
539 
540  if (!prescreen[i])
541  continue;
542 
543  accum += (-3.0f / 32.0f) * window[0 * src_stride + i];
544  accum += (19.0f / 32.0f) * window[1 * src_stride + i];
545  accum += (19.0f / 32.0f) * window[2 * src_stride + i];
546  accum += (-3.0f / 32.0f) * window[3 * src_stride + i];
547 
548  dst_p[i] = accum;
549  }
550 }
551 
552 static int filter_slice(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
553 {
554  NNEDIContext *s = ctx->priv;
555  AVFrame *out = s->dst;
556  AVFrame *in = s->src;
557  const float in_scale = s->in_scale;
558  const float out_scale = s->out_scale;
559  const int depth = s->depth;
560  const int interlaced = in->interlaced_frame;
561  const int tff = s->field_n == (s->field < 0 ? interlaced ? in->top_field_first : 1 :
562  (s->field & 1) ^ 1);
563 
564 
565  for (int p = 0; p < s->nb_planes; p++) {
566  const int height = s->planeheight[p];
567  const int width = s->planewidth[p];
568  const int slice_start = 2 * ((height / 2 * jobnr) / nb_jobs);
569  const int slice_end = 2 * ((height / 2 * (jobnr+1)) / nb_jobs);
570  const uint8_t *src_data = in->data[p];
571  uint8_t *dst_data = out->data[p];
572  uint8_t *dst = out->data[p] + slice_start * out->linesize[p];
573  const int src_linesize = in->linesize[p];
574  const int dst_linesize = out->linesize[p];
575  uint8_t *prescreen_buf = s->prescreen_buf + s->planewidth[0] * jobnr;
576  float *srcbuf = s->input_buf + s->input_size * jobnr;
577  const int srcbuf_stride = width + 64;
578  float *dstbuf = s->output_buf + s->input_size * jobnr;
579  const int dstbuf_stride = width;
580  const int slice_height = (slice_end - slice_start) / 2;
581  const int last_slice = slice_end == height;
582  const uint8_t *in_line;
583  uint8_t *out_line;
584  int y_out;
585 
586  if (!(s->process_plane & (1 << p))) {
587  av_image_copy_plane(dst, out->linesize[p],
588  in->data[p] + slice_start * in->linesize[p],
589  in->linesize[p],
590  s->linesize[p], slice_end - slice_start);
591  continue;
592  }
593 
594  y_out = slice_start + (tff ^ (slice_start & 1));
595  in_line = src_data + (y_out * src_linesize);
596  out_line = dst_data + (y_out * dst_linesize);
597 
598  while (y_out < slice_end) {
599  memcpy(out_line, in_line, s->linesize[p]);
600  y_out += 2;
601  in_line += src_linesize * 2;
602  out_line += dst_linesize * 2;
603  }
604 
605  y_out = slice_start + ((!tff) ^ (slice_start & 1));
606 
607  s->read(src_data + FFMAX(y_out - 5, tff) * src_linesize,
608  srcbuf + 32,
609  src_linesize * 2, srcbuf_stride,
610  width, 1, in_scale);
611  srcbuf += srcbuf_stride;
612 
613  s->read(src_data + FFMAX(y_out - 3, tff) * src_linesize,
614  srcbuf + 32,
615  src_linesize * 2, srcbuf_stride,
616  width, 1, in_scale);
617  srcbuf += srcbuf_stride;
618 
619  s->read(src_data + FFMAX(y_out - 1, tff) * src_linesize,
620  srcbuf + 32,
621  src_linesize * 2, srcbuf_stride,
622  width, 1, in_scale);
623  srcbuf += srcbuf_stride;
624 
625  in_line = src_data + FFMIN(y_out + 1, height - 1 - !tff) * src_linesize;
626  out_line = dst_data + (y_out * dst_linesize);
627 
628  s->read(in_line, srcbuf + 32, src_linesize * 2, srcbuf_stride,
629  width, slice_height - last_slice, in_scale);
630 
631  y_out += (slice_height - last_slice) * 2;
632 
633  s->read(src_data + FFMIN(y_out + 1, height - 1 - !tff) * src_linesize,
634  srcbuf + 32 + srcbuf_stride * (slice_height - last_slice),
635  src_linesize * 2, srcbuf_stride,
636  width, 1, in_scale);
637 
638  s->read(src_data + FFMIN(y_out + 3, height - 1 - !tff) * src_linesize,
639  srcbuf + 32 + srcbuf_stride * (slice_height + 1 - last_slice),
640  src_linesize * 2, srcbuf_stride,
641  width, 1, in_scale);
642 
643  s->read(src_data + FFMIN(y_out + 5, height - 1 - !tff) * src_linesize,
644  srcbuf + 32 + srcbuf_stride * (slice_height + 2 - last_slice),
645  src_linesize * 2, srcbuf_stride,
646  width, 1, in_scale);
647 
648  for (int y = 0; y < slice_end - slice_start; y += 2) {
649  if (s->pscrn > 1) {
650  s->prescreen[1](ctx, srcbuf + (y / 2) * srcbuf_stride + 32,
651  srcbuf_stride, prescreen_buf, width,
652  &s->prescreener_new[s->pscrn - 2]);
653  } else if (s->pscrn == 1) {
654  s->prescreen[0](ctx, srcbuf + (y / 2) * srcbuf_stride + 32,
655  srcbuf_stride, prescreen_buf, width,
656  &s->prescreener_old);
657  }
658 
659  predictor(ctx,
660  srcbuf + (y / 2) * srcbuf_stride + 32,
661  srcbuf_stride,
662  dstbuf + (y / 2) * dstbuf_stride,
663  prescreen_buf, width,
664  &s->coeffs[s->etype][s->nnsparam][s->nsize], s->qual == 2);
665 
666  if (s->prescreen > 0)
667  interpolation(srcbuf + (y / 2) * srcbuf_stride + 32,
668  srcbuf_stride,
669  dstbuf + (y / 2) * dstbuf_stride,
670  prescreen_buf, width);
671  }
672 
673  s->write(dstbuf, out_line, dstbuf_stride, dst_linesize * 2,
674  width, slice_height, depth, out_scale);
675  }
676 
677  return 0;
678 }
679 
680 static int get_frame(AVFilterContext *ctx, int is_second)
681 {
682  NNEDIContext *s = ctx->priv;
683  AVFilterLink *outlink = ctx->outputs[0];
684  AVFrame *src = s->src;
685 
686  s->dst = ff_get_video_buffer(outlink, outlink->w, outlink->h);
687  if (!s->dst)
688  return AVERROR(ENOMEM);
689  av_frame_copy_props(s->dst, src);
690  s->dst->interlaced_frame = 0;
691 
692  ctx->internal->execute(ctx, filter_slice, NULL, NULL, FFMIN(s->planeheight[1] / 2, s->nb_threads));
693 
694  if (s->field == -2 || s->field > 1)
695  s->field_n = !s->field_n;
696 
697  return 0;
698 }
699 
701 {
702  AVFilterContext *ctx = inlink->dst;
703  AVFilterLink *outlink = ctx->outputs[0];
704  NNEDIContext *s = ctx->priv;
705  int ret;
706 
707  if ((s->field > 1 ||
708  s->field == -2) && !s->second) {
709  goto second;
710  } else if (s->field > 1 ||
711  s->field == -2) {
712  AVFrame *dst;
713 
714  s->src = s->second;
715  ret = get_frame(ctx, 1);
716  if (ret < 0) {
717  av_frame_free(&s->dst);
718  av_frame_free(&s->second);
719  s->src = NULL;
720  return ret;
721  }
722  dst = s->dst;
723 
724  if (src->pts != AV_NOPTS_VALUE &&
725  dst->pts != AV_NOPTS_VALUE)
726  dst->pts += src->pts;
727  else
728  dst->pts = AV_NOPTS_VALUE;
729 
730  ret = ff_filter_frame(outlink, dst);
731  if (ret < 0)
732  return ret;
733  if (s->eof)
734  return 0;
735  s->cur_pts = s->second->pts;
736  av_frame_free(&s->second);
737 second:
738  if ((s->deint && src->interlaced_frame &&
739  !ctx->is_disabled) ||
740  (!s->deint && !ctx->is_disabled)) {
741  s->second = src;
742  }
743  }
744 
745  if ((s->deint && !src->interlaced_frame) || ctx->is_disabled) {
746  AVFrame *dst = av_frame_clone(src);
747  if (!dst) {
748  av_frame_free(&src);
749  av_frame_free(&s->second);
750  return AVERROR(ENOMEM);
751  }
752 
753  if (s->field > 1 || s->field == -2) {
754  av_frame_free(&s->second);
755  if ((s->deint && src->interlaced_frame) ||
756  (!s->deint))
757  s->second = src;
758  } else {
759  av_frame_free(&src);
760  }
761  if (dst->pts != AV_NOPTS_VALUE)
762  dst->pts *= 2;
763  return ff_filter_frame(outlink, dst);
764  }
765 
766  s->src = src;
767  ret = get_frame(ctx, 0);
768  if (ret < 0) {
769  av_frame_free(&s->dst);
770  av_frame_free(&s->src);
771  av_frame_free(&s->second);
772  return ret;
773  }
774 
775  if (src->pts != AV_NOPTS_VALUE)
776  s->dst->pts = src->pts * 2;
777  if (s->field <= 1 && s->field > -2) {
778  av_frame_free(&src);
779  s->src = NULL;
780  }
781 
782  return ff_filter_frame(outlink, s->dst);
783 }
784 
786 {
787  AVFilterContext *ctx = link->src;
788  NNEDIContext *s = ctx->priv;
789  int ret;
790 
791  if (s->eof)
792  return AVERROR_EOF;
793 
794  ret = ff_request_frame(ctx->inputs[0]);
795 
796  if (ret == AVERROR_EOF && s->second) {
797  AVFrame *next = av_frame_clone(s->second);
798 
799  if (!next)
800  return AVERROR(ENOMEM);
801 
802  next->pts = s->second->pts * 2 - s->cur_pts;
803  s->eof = 1;
804 
805  filter_frame(ctx->inputs[0], next);
806  } else if (ret < 0) {
807  return ret;
808  }
809 
810  return 0;
811 }
812 
813 static void copy_weights(float *dst, int n, const float **data)
814 {
815  memcpy(dst, *data, n * sizeof(float));
816  *data += n;
817 }
818 
819 static float *allocate(float **ptr, int size)
820 {
821  float *ret = *ptr;
822 
823  *ptr += size;
824 
825  return ret;
826 }
827 
828 static int allocate_model(PredictorCoefficients *coeffs, int xdim, int ydim, int nns)
829 {
830  int filter_size = nns * xdim * ydim;
831  int bias_size = nns;
832  float *data;
833 
834  data = av_malloc_array(filter_size + bias_size, 4 * sizeof(float));
835  if (!data)
836  return AVERROR(ENOMEM);
837 
838  coeffs->data = data;
839  coeffs->xdim = xdim;
840  coeffs->ydim = ydim;
841  coeffs->nsize = xdim * ydim;
842  coeffs->nns = nns;
843 
844  coeffs->softmax_q1 = allocate(&data, filter_size);
845  coeffs->elliott_q1 = allocate(&data, filter_size);
846  coeffs->softmax_bias_q1 = allocate(&data, bias_size);
847  coeffs->elliott_bias_q1 = allocate(&data, bias_size);
848 
849  coeffs->softmax_q2 = allocate(&data, filter_size);
850  coeffs->elliott_q2 = allocate(&data, filter_size);
851  coeffs->softmax_bias_q2 = allocate(&data, bias_size);
852  coeffs->elliott_bias_q2 = allocate(&data, bias_size);
853 
854  return 0;
855 }
856 
857 static int read_weights(AVFilterContext *ctx, const float *bdata)
858 {
859  NNEDIContext *s = ctx->priv;
860  int ret;
861 
862  copy_weights(&s->prescreener_old.kernel_l0[0][0], 4 * 48, &bdata);
863  copy_weights(s->prescreener_old.bias_l0, 4, &bdata);
864 
865  copy_weights(&s->prescreener_old.kernel_l1[0][0], 4 * 4, &bdata);
866  copy_weights(s->prescreener_old.bias_l1, 4, &bdata);
867 
868  copy_weights(&s->prescreener_old.kernel_l2[0][0], 4 * 8, &bdata);
869  copy_weights(s->prescreener_old.bias_l2, 4, &bdata);
870 
871  for (int i = 0; i < 3; i++) {
873  float kernel_l0_shuffled[4 * 64];
874  float kernel_l1_shuffled[4 * 4];
875 
876  copy_weights(kernel_l0_shuffled, 4 * 64, &bdata);
877  copy_weights(data->bias_l0, 4, &bdata);
878 
879  copy_weights(kernel_l1_shuffled, 4 * 4, &bdata);
880  copy_weights(data->bias_l1, 4, &bdata);
881 
882  for (int n = 0; n < 4; n++) {
883  for (int k = 0; k < 64; k++)
884  data->kernel_l0[n][k] = kernel_l0_shuffled[(k / 8) * 32 + n * 8 + k % 8];
885  for (int k = 0; k < 4; k++)
886  data->kernel_l1[n][k] = kernel_l1_shuffled[k * 4 + n];
887  }
888  }
889 
890  for (int m = 0; m < 2; m++) {
891  // Grouping by neuron count.
892  for (int i = 0; i < 5; i++) {
893  int nns = NNEDI_NNS[i];
894 
895  // Grouping by window size.
896  for (int j = 0; j < 7; j++) {
897  PredictorCoefficients *model = &s->coeffs[m][i][j];
898  int xdim = NNEDI_XDIM[j];
899  int ydim = NNEDI_YDIM[j];
900  int filter_size = xdim * ydim;
901 
902  ret = allocate_model(model, xdim, ydim, nns);
903  if (ret < 0)
904  return ret;
905 
906  // Quality 1 model. NNS[i] * (XDIM[j] * YDIM[j]) * 2 coefficients.
907  copy_weights(model->softmax_q1, nns * filter_size, &bdata);
908  copy_weights(model->elliott_q1, nns * filter_size, &bdata);
909 
910  // Quality 1 model bias. NNS[i] * 2 coefficients.
911  copy_weights(model->softmax_bias_q1, nns, &bdata);
912  copy_weights(model->elliott_bias_q1, nns, &bdata);
913 
914  // Quality 2 model. NNS[i] * (XDIM[j] * YDIM[j]) * 2 coefficients.
915  copy_weights(model->softmax_q2, nns * filter_size, &bdata);
916  copy_weights(model->elliott_q2, nns * filter_size, &bdata);
917 
918  // Quality 2 model bias. NNS[i] * 2 coefficients.
919  copy_weights(model->softmax_bias_q2, nns, &bdata);
920  copy_weights(model->elliott_bias_q2, nns, &bdata);
921  }
922  }
923  }
924 
925  return 0;
926 }
927 
928 static float mean(const float *input, int size)
929 {
930  float sum = 0.;
931 
932  for (int i = 0; i < size; i++)
933  sum += input[i];
934 
935  return sum / size;
936 }
937 
938 static void transform(float *input, int size, float mean, float half)
939 {
940  for (int i = 0; i < size; i++)
941  input[i] = (input[i] - mean) / half;
942 }
943 
945 {
946  for (int n = 0; n < 4; n++) {
947  float m = mean(coeffs->kernel_l0[n], 48);
948 
949  transform(coeffs->kernel_l0[n], 48, m, half);
950  }
951 }
952 
954 {
955  for (int n = 0; n < 4; n++) {
956  float m = mean(coeffs->kernel_l0[n], 64);
957 
958  transform(coeffs->kernel_l0[n], 64, m, half);
959  }
960 }
961 
963 {
964  int filter_size = model->nsize;
965  int nns = model->nns;
966 
967  float softmax_means[256]; // Average of individual softmax filters.
968  float elliott_means[256]; // Average of individual elliott filters.
969  float mean_filter[48 * 6]; // Pointwise average of all softmax filters.
970  float mean_bias;
971 
972  // Quality 1.
973  for (int nn = 0; nn < nns; nn++) {
974  softmax_means[nn] = mean(model->softmax_q1 + nn * filter_size, filter_size);
975  elliott_means[nn] = mean(model->elliott_q1 + nn * filter_size, filter_size);
976 
977  for (int k = 0; k < filter_size; k++)
978  mean_filter[k] += model->softmax_q1[nn * filter_size + k] - softmax_means[nn];
979  }
980 
981  for (int k = 0; k < filter_size; k++)
982  mean_filter[k] /= nns;
983 
984  mean_bias = mean(model->softmax_bias_q1, nns);
985 
986  for (int nn = 0; nn < nns; nn++) {
987  for (int k = 0; k < filter_size; k++) {
988  model->softmax_q1[nn * filter_size + k] -= softmax_means[nn] + mean_filter[k];
989  model->elliott_q1[nn * filter_size + k] -= elliott_means[nn];
990  }
991  model->softmax_bias_q1[nn] -= mean_bias;
992  }
993 
994  // Quality 2.
995  memset(mean_filter, 0, 48 * 6 * sizeof(float));
996 
997  for (int nn = 0; nn < nns; nn++) {
998  softmax_means[nn] = mean(model->softmax_q2 + nn * filter_size, filter_size);
999  elliott_means[nn] = mean(model->elliott_q2 + nn * filter_size, filter_size);
1000 
1001  for (int k = 0; k < filter_size; k++) {
1002  mean_filter[k] += model->softmax_q2[nn * filter_size + k] - softmax_means[nn];
1003  }
1004  }
1005 
1006  for (int k = 0; k < filter_size; k++)
1007  mean_filter[k] /= nns;
1008 
1009  mean_bias = mean(model->softmax_bias_q2, nns);
1010 
1011  for (int nn = 0; nn < nns; nn++) {
1012  for (int k = 0; k < filter_size; k++) {
1013  model->softmax_q2[nn * filter_size + k] -= softmax_means[nn] + mean_filter[k];
1014  model->elliott_q2[nn * filter_size + k] -= elliott_means[nn];
1015  }
1016 
1017  model->softmax_bias_q2[nn] -= mean_bias;
1018  }
1019 }
1020 
1022 {
1023  NNEDIContext *s = ctx->priv;
1024  FILE *weights_file = NULL;
1025  int64_t weights_size;
1026  float *bdata;
1027  size_t bytes_read;
1028  int ret = 0;
1029 
1030  weights_file = av_fopen_utf8(s->weights_file, "rb");
1031  if (!weights_file) {
1032  av_log(ctx, AV_LOG_ERROR, "No weights file provided, aborting!\n");
1033  return AVERROR(EINVAL);
1034  }
1035 
1036  if (fseek(weights_file, 0, SEEK_END)) {
1037  av_log(ctx, AV_LOG_ERROR, "Couldn't seek to the end of weights file.\n");
1038  fclose(weights_file);
1039  return AVERROR(EINVAL);
1040  }
1041 
1042  weights_size = ftell(weights_file);
1043 
1044  if (weights_size == -1) {
1045  fclose(weights_file);
1046  av_log(ctx, AV_LOG_ERROR, "Couldn't get size of weights file.\n");
1047  return AVERROR(EINVAL);
1048  } else if (weights_size != NNEDI_WEIGHTS_SIZE) {
1049  fclose(weights_file);
1050  av_log(ctx, AV_LOG_ERROR, "Unexpected weights file size.\n");
1051  return AVERROR(EINVAL);
1052  }
1053 
1054  if (fseek(weights_file, 0, SEEK_SET)) {
1055  fclose(weights_file);
1056  av_log(ctx, AV_LOG_ERROR, "Couldn't seek to the start of weights file.\n");
1057  return AVERROR(EINVAL);
1058  }
1059 
1060  bdata = av_malloc(NNEDI_WEIGHTS_SIZE);
1061  if (!bdata) {
1062  fclose(weights_file);
1063  return AVERROR(ENOMEM);
1064  }
1065 
1066  bytes_read = fread(bdata, 1, NNEDI_WEIGHTS_SIZE, weights_file);
1067  if (bytes_read != NNEDI_WEIGHTS_SIZE) {
1068  fclose(weights_file);
1069  ret = AVERROR_INVALIDDATA;
1070  av_log(ctx, AV_LOG_ERROR, "Couldn't read weights file.\n");
1071  goto fail;
1072  }
1073 
1074  fclose(weights_file);
1075 
1076  s->fdsp = avpriv_float_dsp_alloc(0);
1077  if (!s->fdsp) {
1078  ret = AVERROR(ENOMEM);
1079  goto fail;
1080  }
1081 
1082  ret = read_weights(ctx, bdata);
1083  if (ret < 0)
1084  goto fail;
1085 
1086 fail:
1087  av_free(bdata);
1088  return ret;
1089 }
1090 
1092 {
1093  AVFilterContext *ctx = inlink->dst;
1094  NNEDIContext *s = ctx->priv;
1096  int ret;
1097 
1098  s->depth = desc->comp[0].depth;
1101  if ((ret = av_image_fill_linesizes(s->linesize, inlink->format, inlink->w)) < 0)
1102  return ret;
1103 
1104  s->planewidth[1] = s->planewidth[2] = AV_CEIL_RSHIFT(inlink->w, desc->log2_chroma_w);
1105  s->planewidth[0] = s->planewidth[3] = inlink->w;
1106  s->planeheight[1] = s->planeheight[2] = AV_CEIL_RSHIFT(inlink->h, desc->log2_chroma_h);
1107  s->planeheight[0] = s->planeheight[3] = inlink->h;
1108 
1109  s->half = ((1 << 8) - 1) / 2.f;
1110  s->out_scale = 1 << (s->depth - 8);
1111  s->in_scale = 1.f / s->out_scale;
1112 
1113  switch (s->depth) {
1114  case 8:
1115  s->read = read_bytes;
1116  s->write = write_bytes;
1117  break;
1118  default:
1119  s->read = read_words;
1120  s->write = write_words;
1121  break;
1122  }
1123 
1128 
1129  s->prescreen[0] = process_old;
1130  s->prescreen[1] = process_new;
1131 
1132  for (int i = 0; i < 2; i++) {
1133  for (int j = 0; j < 5; j++) {
1134  for (int k = 0; k < 7; k++)
1135  subtract_mean_predictor(&s->coeffs[i][j][k]);
1136  }
1137  }
1138 
1139  s->prescreen_buf = av_calloc(s->nb_threads * s->planewidth[0], sizeof(*s->prescreen_buf));
1140  if (!s->prescreen_buf)
1141  return AVERROR(ENOMEM);
1142 
1143  s->input_size = (s->planewidth[0] + 64) * (s->planeheight[0] + 6);
1144  s->input_buf = av_calloc(s->nb_threads * s->input_size, sizeof(*s->input_buf));
1145  if (!s->input_buf)
1146  return AVERROR(ENOMEM);
1147 
1148  s->output_buf = av_calloc(s->nb_threads * s->input_size, sizeof(*s->output_buf));
1149  if (!s->output_buf)
1150  return AVERROR(ENOMEM);
1151 
1152  return 0;
1153 }
1154 
1156 {
1157  NNEDIContext *s = ctx->priv;
1158 
1159  av_freep(&s->prescreen_buf);
1160  av_freep(&s->input_buf);
1161  av_freep(&s->output_buf);
1162  av_freep(&s->fdsp);
1163 
1164  for (int i = 0; i < 2; i++) {
1165  for (int j = 0; j < 5; j++) {
1166  for (int k = 0; k < 7; k++) {
1167  av_freep(&s->coeffs[i][j][k].data);
1168  }
1169  }
1170  }
1171 
1172  av_frame_free(&s->second);
1173 }
1174 
1175 static const AVFilterPad inputs[] = {
1176  {
1177  .name = "default",
1178  .type = AVMEDIA_TYPE_VIDEO,
1179  .filter_frame = filter_frame,
1180  .config_props = config_input,
1181  },
1182  { NULL }
1183 };
1184 
1185 static const AVFilterPad outputs[] = {
1186  {
1187  .name = "default",
1188  .type = AVMEDIA_TYPE_VIDEO,
1189  .config_props = config_output,
1190  .request_frame = request_frame,
1191  },
1192  { NULL }
1193 };
1194 
1196  .name = "nnedi",
1197  .description = NULL_IF_CONFIG_SMALL("Apply neural network edge directed interpolation intra-only deinterlacer."),
1198  .priv_size = sizeof(NNEDIContext),
1199  .priv_class = &nnedi_class,
1200  .init = init,
1201  .uninit = uninit,
1203  .inputs = inputs,
1204  .outputs = outputs,
1207 };
static int filter_frame(AVFilterLink *inlink, AVFrame *src)
Definition: vf_nnedi.c:700
#define FLAGS
Definition: vf_nnedi.c:128
static void read_words(const uint8_t *srcp, float *dst, int src_stride, int dst_stride, int width, int height, float scale)
Definition: vf_nnedi.c:475
static void process_old(AVFilterContext *ctx, const void *src, ptrdiff_t src_stride, uint8_t *prescreen, int N, void *data)
Definition: vf_nnedi.c:246
float(* scalarproduct_float)(const float *v1, const float *v2, int len)
Calculate the scalar product of two vectors of floats.
Definition: float_dsp.h:175
#define NULL
Definition: coverity.c:32
int64_t cur_pts
Definition: vf_nnedi.c:81
#define AV_PIX_FMT_YUVA422P16
Definition: pixfmt.h:442
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition: error.h:59
float half
Definition: vf_nnedi.c:96
#define AV_PIX_FMT_YUV440P10
Definition: pixfmt.h:401
#define AV_PIX_FMT_YUVA422P9
Definition: pixfmt.h:434
const AVPixFmtDescriptor * av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt)
Definition: pixdesc.c:2573
This structure describes decoded (raw) audio or video data.
Definition: frame.h:314
AVOption.
Definition: opt.h:248
ptrdiff_t const GLvoid * data
Definition: opengl_enc.c:100
#define AV_PIX_FMT_YUVA420P10
Definition: pixfmt.h:436
static void transform_elliott(float *input, int size)
Definition: vf_nnedi.c:240
#define AV_PIX_FMT_YUV444P14
Definition: pixfmt.h:409
#define AV_PIX_FMT_GBRAP10
Definition: pixfmt.h:419
float * output_buf
Definition: vf_nnedi.c:113
static int config_input(AVFilterLink *inlink)
Definition: vf_nnedi.c:1091
#define AV_PIX_FMT_YUVA422P10
Definition: pixfmt.h:437
const char * desc
Definition: libsvtav1.c:79
planar YUV 4:4:4, 24bpp, (1 Cr & Cb sample per 1x1 Y samples)
Definition: pixfmt.h:71
misc image utilities
int av_pix_fmt_count_planes(enum AVPixelFormat pix_fmt)
Definition: pixdesc.c:2613
static const uint8_t NNEDI_YDIM[]
Definition: vf_nnedi.c:37
Main libavfilter public API header.
char * weights_file
Definition: vf_nnedi.c:75
static void process_new(AVFilterContext *ctx, const void *src, ptrdiff_t src_stride, uint8_t *prescreen, int N, void *data)
Definition: vf_nnedi.c:283
FILE * av_fopen_utf8(const char *path, const char *mode)
Open a file using a UTF-8 filename.
Definition: file_open.c:158
planar GBR 4:4:4 24bpp
Definition: pixfmt.h:168
float * input_buf
Definition: vf_nnedi.c:112
int num
Numerator.
Definition: rational.h:59
PrescreenerNewCoefficients prescreener_new[3]
Definition: vf_nnedi.c:93
int planewidth[4]
Definition: vf_nnedi.c:88
#define AV_PIX_FMT_GBRP10
Definition: pixfmt.h:415
float * elliott_bias_q2
Definition: vf_nnedi.c:69
static const uint16_t NNEDI_NNS[]
Definition: vf_nnedi.c:38
PredictorCoefficients coeffs[2][5][7]
Definition: vf_nnedi.c:94
AVFrame * second
Definition: vf_nnedi.c:78
static int read_weights(AVFilterContext *ctx, const float *bdata)
Definition: vf_nnedi.c:857
#define AV_PIX_FMT_GRAY9
Definition: pixfmt.h:379
#define AV_PIX_FMT_YUV420P12
Definition: pixfmt.h:403
AVFrame * ff_get_video_buffer(AVFilterLink *link, int w, int h)
Request a picture buffer with a specific set of permissions.
Definition: video.c:99
void(* read)(const uint8_t *src, float *dst, int src_stride, int dst_stride, int width, int height, float scale)
Definition: vf_nnedi.c:115
int is_disabled
the enabled state from the last expression evaluation
Definition: avfilter.h:388
uint8_t log2_chroma_w
Amount to shift the luma width right to find the chroma width.
Definition: pixdesc.h:92
#define N
Definition: af_mcompand.c:54
static int allocate_model(PredictorCoefficients *coeffs, int xdim, int ydim, int nns)
Definition: vf_nnedi.c:828
void * av_calloc(size_t nmemb, size_t size)
Non-inlined equivalent of av_mallocz_array().
Definition: mem.c:245
AVFilterFormats * ff_make_format_list(const int *fmts)
Create a list of supported formats.
Definition: formats.c:287
#define AV_PIX_FMT_GRAY10
Definition: pixfmt.h:380
static void transform_softmax_exp(float *input, int size)
Definition: vf_nnedi.c:383
int input_size
Definition: vf_nnedi.c:110
const char * name
Pad name.
Definition: internal.h:60
#define AV_PIX_FMT_GRAY12
Definition: pixfmt.h:381
AVFilterLink ** inputs
array of pointers to input links
Definition: avfilter.h:349
static int request_frame(AVFilterLink *link)
Definition: vf_nnedi.c:785
int ff_filter_frame(AVFilterLink *link, AVFrame *frame)
Send a frame of data to the next filter.
Definition: avfilter.c:1091
planar YUV 4:2:0, 20bpp, (1 Cr & Cb sample per 2x2 Y & A samples)
Definition: pixfmt.h:101
AVComponentDescriptor comp[4]
Parameters that describe how pixels are packed.
Definition: pixdesc.h:117
uint8_t
#define av_cold
Definition: attributes.h:88
#define av_malloc(s)
AVOptions.
static int filter_offset(int nn, const PredictorCoefficients *const model)
Definition: vf_nnedi.c:314
#define f(width, name)
Definition: cbs_vp9.c:255
AVFrame * src
Definition: vf_nnedi.c:77
#define LOCAL_ALIGNED_32(t, v,...)
Definition: mem_internal.h:136
static const AVFilterPad outputs[]
Definition: vf_nnedi.c:1185
int64_t pts
Presentation timestamp in time_base units (time when frame should be shown to user).
Definition: frame.h:407
int process_plane
Definition: vf_nnedi.c:103
#define AV_PIX_FMT_YUVA420P9
Definition: pixfmt.h:433
#define AV_PIX_FMT_GBRP9
Definition: pixfmt.h:414
int nb_threads
Definition: vf_nnedi.c:86
static void subtract_mean_old(PrescreenerOldCoefficients *coeffs, float half)
Definition: vf_nnedi.c:944
#define DECLARE_ALIGNED(n, t, v)
Declare a variable that is aligned in memory.
Definition: mem.h:117
#define height
planar YUV 4:4:0 full scale (JPEG), deprecated in favor of AV_PIX_FMT_YUV440P and setting color_range...
Definition: pixfmt.h:100
planar YUV 4:2:2, 16bpp, full scale (JPEG), deprecated in favor of AV_PIX_FMT_YUV422P and setting col...
Definition: pixfmt.h:79
#define AVERROR_EOF
End of file.
Definition: error.h:55
#define AV_PIX_FMT_YUV444P16
Definition: pixfmt.h:412
int interlaced_frame
The content of the picture is interlaced.
Definition: frame.h:461
static av_cold void uninit(AVFilterContext *ctx)
Definition: vf_nnedi.c:1155
ptrdiff_t size
Definition: opengl_enc.c:100
#define AV_PIX_FMT_YUV422P12
Definition: pixfmt.h:404
#define AV_PIX_FMT_YUVA420P16
Definition: pixfmt.h:441
static __device__ float fabsf(float a)
Definition: cuda_runtime.h:181
#define av_log(a,...)
static void copy_weights(float *dst, int n, const float **data)
Definition: vf_nnedi.c:813
static void write_bytes(const float *src, uint8_t *dst, int src_stride, int dst_stride, int width, int height, int depth, float scale)
Definition: vf_nnedi.c:498
A filter pad used for either input or output.
Definition: internal.h:54
#define expf(x)
Definition: libm.h:283
#define src
Definition: vp8dsp.c:255
AVFILTER_DEFINE_CLASS(nnedi)
planar YUV 4:2:2 24bpp, (1 Cr & Cb sample per 2x1 Y & A samples)
Definition: pixfmt.h:176
#define OFFSET(x)
Definition: vf_nnedi.c:126
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:194
int ff_set_common_formats(AVFilterContext *ctx, AVFilterFormats *formats)
A helper for query_formats() which sets all links to the same list of formats.
Definition: formats.c:588
uint8_t log2_chroma_h
Amount to shift the luma height right to find the chroma height.
Definition: pixdesc.h:101
AVFloatDSPContext * fdsp
Definition: vf_nnedi.c:83
av_cold AVFloatDSPContext * avpriv_float_dsp_alloc(int bit_exact)
Allocate a float DSP context.
Definition: float_dsp.c:135
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition: frame.c:203
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 field
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification. ...
Definition: internal.h:115
int ff_filter_process_command(AVFilterContext *ctx, const char *cmd, const char *arg, char *res, int res_len, int flags)
Generic processing of user supplied commands that are set in the same way as the filter options...
Definition: avfilter.c:885
static void predictor(AVFilterContext *ctx, const void *src, ptrdiff_t src_stride, void *dst, const uint8_t *prescreen, int N, void *data, int use_q2)
Definition: vf_nnedi.c:405
void * priv
private data for use by the filter
Definition: avfilter.h:356
#define AVFILTER_FLAG_SLICE_THREADS
The filter supports multithreading by splitting frames into multiple parts and processing them concur...
Definition: avfilter.h:117
static void transform(float *input, int size, float mean, float half)
Definition: vf_nnedi.c:938
#define AV_PIX_FMT_YUVA444P16
Definition: pixfmt.h:443
const char * arg
Definition: jacosubdec.c:66
static void interpolation(const void *src, ptrdiff_t src_stride, void *dst, const uint8_t *prescreen, int n)
Definition: vf_nnedi.c:530
#define AV_PIX_FMT_GBRAP12
Definition: pixfmt.h:420
#define AV_PIX_FMT_YUV444P10
Definition: pixfmt.h:402
#define FFMAX(a, b)
Definition: common.h:94
#define fail()
Definition: checkasm.h:123
static float mean(const float *input, int size)
Definition: vf_nnedi.c:928
#define AV_PIX_FMT_GBRAP16
Definition: pixfmt.h:421
static int get_frame(AVFilterContext *ctx, int is_second)
Definition: vf_nnedi.c:680
static const float * elliott_q2_filter(int nn, const PredictorCoefficients *const model)
Definition: vf_nnedi.c:337
planar YUV 4:2:2, 16bpp, (1 Cr & Cb sample per 2x1 Y samples)
Definition: pixfmt.h:70
float * elliott_bias_q1
Definition: vf_nnedi.c:65
#define AV_PIX_FMT_YUV422P9
Definition: pixfmt.h:397
static SDL_Window * window
Definition: ffplay.c:368
static int query_formats(AVFilterContext *ctx)
Definition: vf_nnedi.c:191
static void subtract_mean_new(PrescreenerNewCoefficients *coeffs, float half)
Definition: vf_nnedi.c:953
#define AV_PIX_FMT_GBRP16
Definition: pixfmt.h:418
int ff_filter_get_nb_threads(AVFilterContext *ctx)
Get number of threads for current filter instance.
Definition: avfilter.c:800
#define AV_PIX_FMT_GRAY16
Definition: pixfmt.h:383
static const uint8_t NNEDI_XDIM[]
Definition: vf_nnedi.c:36
#define FFMIN(a, b)
Definition: common.h:96
planar YUV 4:2:0, 12bpp, full scale (JPEG), deprecated in favor of AV_PIX_FMT_YUV420P and setting col...
Definition: pixfmt.h:78
uint8_t interlaced
Definition: mxfenc.c:2167
int nnsparam
Definition: vf_nnedi.c:105
#define AV_PIX_FMT_YUVA444P12
Definition: pixfmt.h:440
#define width
static void read_bytes(const uint8_t *src, float *dst, int src_stride, int dst_stride, int width, int height, float scale)
Definition: vf_nnedi.c:456
typedef void(APIENTRY *FF_PFNGLACTIVETEXTUREPROC)(GLenum texture)
static int filter_slice(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
Definition: vf_nnedi.c:552
static const AVFilterPad inputs[]
Definition: vf_nnedi.c:1175
float * softmax_bias_q2
Definition: vf_nnedi.c:68
float * softmax_bias_q1
Definition: vf_nnedi.c:64
AVFormatContext * ctx
Definition: movenc.c:48
AVFilter ff_vf_nnedi
Definition: vf_nnedi.c:1195
static void gather_input(const float *src, ptrdiff_t src_stride, float *buf, float mstd[4], const PredictorCoefficients *const model)
Definition: vf_nnedi.c:343
#define s(width, name)
Definition: cbs_vp9.c:257
#define AV_PIX_FMT_YUVA444P10
Definition: pixfmt.h:438
static const float * elliott_q1_filter(int nn, const PredictorCoefficients *const model)
Definition: vf_nnedi.c:325
uint8_t * prescreen_buf
Definition: vf_nnedi.c:111
#define AV_PIX_FMT_YUV444P9
Definition: pixfmt.h:398
#define AV_PIX_FMT_GBRP14
Definition: pixfmt.h:417
AVFrame * av_frame_clone(const AVFrame *src)
Create a new frame that references the same data as src.
Definition: frame.c:540
float kernel_l0[4][14 *4]
Definition: vf_nnedi.c:41
#define AV_PIX_FMT_YUV420P16
Definition: pixfmt.h:410
static void wae5(const float *softmax, const float *el, int n, float mstd[4])
Definition: vf_nnedi.c:389
#define AV_PIX_FMT_YUV420P14
Definition: pixfmt.h:407
int linesize[AV_NUM_DATA_POINTERS]
For video, size in bytes of each picture line.
Definition: frame.h:345
planar YUV 4:4:4 32bpp, (1 Cr & Cb sample per 1x1 Y & A samples)
Definition: pixfmt.h:177
Descriptor that unambiguously describes how the bits of a pixel are stored in the up to 4 data planes...
Definition: pixdesc.h:81
#define AV_PIX_FMT_GRAY14
Definition: pixfmt.h:382
uint8_t pi<< 24) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_U8, uint8_t,(*(const uint8_t *) pi-0x80)*(1.0f/(1<< 7))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_U8, uint8_t,(*(const uint8_t *) pi-0x80)*(1.0/(1<< 7))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S16, int16_t,(*(const int16_t *) pi >> 8)+0x80) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S16, int16_t,*(const int16_t *) pi *(1.0f/(1<< 15))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S16, int16_t,*(const int16_t *) pi *(1.0/(1<< 15))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S32, int32_t,(*(const int32_t *) pi >> 24)+0x80) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S32, int32_t,*(const int32_t *) pi *(1.0f/(1U<< 31))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S32, int32_t,*(const int32_t *) pi *(1.0/(1U<< 31))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_FLT, float, av_clip_uint8(lrintf(*(const float *) pi *(1<< 7))+0x80)) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_FLT, float, av_clip_int16(lrintf(*(const float *) pi *(1<< 15)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_FLT, float, av_clipl_int32(llrintf(*(const float *) pi *(1U<< 31)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_DBL, double, av_clip_uint8(lrint(*(const double *) pi *(1<< 7))+0x80)) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_DBL, double, av_clip_int16(lrint(*(const double *) pi *(1<< 15)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_DBL, double, av_clipl_int32(llrint(*(const double *) pi *(1U<< 31))))#define SET_CONV_FUNC_GROUP(ofmt, ifmt) static void set_generic_function(AudioConvert *ac){}void ff_audio_convert_free(AudioConvert **ac){if(!*ac) return;ff_dither_free(&(*ac) ->dc);av_freep(ac);}AudioConvert *ff_audio_convert_alloc(AVAudioResampleContext *avr, enum AVSampleFormat out_fmt, enum AVSampleFormat in_fmt, int channels, int sample_rate, int apply_map){AudioConvert *ac;int in_planar, out_planar;ac=av_mallocz(sizeof(*ac));if(!ac) return NULL;ac->avr=avr;ac->out_fmt=out_fmt;ac->in_fmt=in_fmt;ac->channels=channels;ac->apply_map=apply_map;if(avr->dither_method!=AV_RESAMPLE_DITHER_NONE &&av_get_packed_sample_fmt(out_fmt)==AV_SAMPLE_FMT_S16 &&av_get_bytes_per_sample(in_fmt) > 2){ac->dc=ff_dither_alloc(avr, out_fmt, in_fmt, channels, sample_rate, apply_map);if(!ac->dc){av_free(ac);return NULL;}return ac;}in_planar=ff_sample_fmt_is_planar(in_fmt, channels);out_planar=ff_sample_fmt_is_planar(out_fmt, channels);if(in_planar==out_planar){ac->func_type=CONV_FUNC_TYPE_FLAT;ac->planes=in_planar?ac->channels:1;}else if(in_planar) ac->func_type=CONV_FUNC_TYPE_INTERLEAVE;else ac->func_type=CONV_FUNC_TYPE_DEINTERLEAVE;set_generic_function(ac);if(ARCH_AARCH64) ff_audio_convert_init_aarch64(ac);if(ARCH_ARM) ff_audio_convert_init_arm(ac);if(ARCH_X86) ff_audio_convert_init_x86(ac);return ac;}int ff_audio_convert(AudioConvert *ac, AudioData *out, AudioData *in){int use_generic=1;int len=in->nb_samples;int p;if(ac->dc){av_log(ac->avr, AV_LOG_TRACE,"%d samples - audio_convert: %s to %s (dithered)\n", len, av_get_sample_fmt_name(ac->in_fmt), av_get_sample_fmt_name(ac->out_fmt));return ff_convert_dither(ac-> in
#define AV_PIX_FMT_YUV420P10
Definition: pixfmt.h:399
planar YUV 4:1:0, 9bpp, (1 Cr & Cb sample per 4x4 Y samples)
Definition: pixfmt.h:72
Describe the class of an AVClass context structure.
Definition: log.h:67
Filter definition.
Definition: avfilter.h:145
int av_image_fill_linesizes(int linesizes[4], enum AVPixelFormat pix_fmt, int width)
Fill plane linesizes for an image with pixel format pix_fmt and width width.
Definition: imgutils.c:89
Rational number (pair of numerator and denominator).
Definition: rational.h:58
static float dot_dsp(NNEDIContext *s, const float *kernel, const float *input, int n, float scale, float bias)
Definition: vf_nnedi.c:225
static void write_words(const float *src, uint8_t *dstp, int src_stride, int dst_stride, int width, int height, int depth, float scale)
Definition: vf_nnedi.c:512
const char * name
Filter name.
Definition: avfilter.h:149
#define AV_PIX_FMT_YUV440P12
Definition: pixfmt.h:405
and forward the test the status of outputs and forward it to the corresponding return FFERROR_NOT_READY If the filters stores internally one or a few frame for some input
#define AV_PIX_FMT_YUV420P9
Definition: pixfmt.h:396
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
#define AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL
Same as AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC, except that the filter will have its filter_frame() c...
Definition: avfilter.h:134
PrescreenerOldCoefficients prescreener_old
Definition: vf_nnedi.c:92
AVFilterLink ** outputs
array of pointers to output links
Definition: avfilter.h:353
static enum AVPixelFormat pix_fmts[]
Definition: libkvazaar.c:303
#define RFLAGS
Definition: vf_nnedi.c:127
AVFrame * dst
Definition: vf_nnedi.c:79
#define AV_PIX_FMT_YUV422P14
Definition: pixfmt.h:408
#define AV_PIX_FMT_GBRP12
Definition: pixfmt.h:416
#define flags(name, subs,...)
Definition: cbs_av1.c:561
AVFilterInternal * internal
An opaque struct for libavfilter internal use.
Definition: avfilter.h:381
#define AV_PIX_FMT_YUV422P10
Definition: pixfmt.h:400
#define AV_PIX_FMT_YUV444P12
Definition: pixfmt.h:406
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition: frame.h:328
The exact code depends on how similar the blocks are and how related they are to the and needs to apply these operations to the correct inlink or outlink if there are several Macros are available to factor that when no extra processing is inlink
planar YUV 4:2:0, 12bpp, (1 Cr & Cb sample per 2x2 Y samples)
Definition: pixfmt.h:66
Y , 8bpp.
Definition: pixfmt.h:74
int field_n
Definition: vf_nnedi.c:90
static int process_command(AVFilterContext *ctx, const char *cmd, const char *args, char *res, int res_len, int flags)
Definition: af_adenorm.c:275
common internal and external API header
static struct @323 state
planar GBRA 4:4:4:4 32bpp
Definition: pixfmt.h:215
static int config_output(AVFilterLink *outlink)
Definition: vf_nnedi.c:176
#define AV_PIX_FMT_YUVA444P9
Definition: pixfmt.h:435
planar YUV 4:4:4, 24bpp, full scale (JPEG), deprecated in favor of AV_PIX_FMT_YUV444P and setting col...
Definition: pixfmt.h:80
static void subtract_mean_predictor(PredictorCoefficients *model)
Definition: vf_nnedi.c:962
planar YUV 4:1:1, 12bpp, (1 Cr & Cb sample per 4x1 Y samples)
Definition: pixfmt.h:73
int den
Denominator.
Definition: rational.h:60
int nb_planes
Definition: vf_nnedi.c:85
avfilter_execute_func * execute
Definition: internal.h:136
static int slice_end(AVCodecContext *avctx, AVFrame *pict)
Handle slice ends.
Definition: mpeg12dec.c:2035
int linesize[4]
Definition: vf_nnedi.c:87
void(* prescreen[2])(AVFilterContext *ctx, const void *src, ptrdiff_t src_stride, uint8_t *prescreen, int N, void *data)
Definition: vf_nnedi.c:121
static const float * softmax_q2_filter(int nn, const PredictorCoefficients *const model)
Definition: vf_nnedi.c:331
static float softmax_exp(float x)
Definition: vf_nnedi.c:378
#define av_free(p)
float kernel_l0[4][16 *4]
Definition: vf_nnedi.c:52
static const float * softmax_q1_filter(int nn, const PredictorCoefficients *const model)
Definition: vf_nnedi.c:319
int top_field_first
If the content is interlaced, is top field displayed first.
Definition: frame.h:466
static av_cold int init(AVFilterContext *ctx)
Definition: vf_nnedi.c:1021
int planeheight[4]
Definition: vf_nnedi.c:89
float in_scale
Definition: vf_nnedi.c:97
A list of supported formats for one end of a filter link.
Definition: formats.h:65
planar YUV 4:1:1, 12bpp, (1 Cr & Cb sample per 4x1 Y samples) full scale (JPEG), deprecated in favor ...
Definition: pixfmt.h:258
float out_scale
Definition: vf_nnedi.c:98
static float * allocate(float **ptr, int size)
Definition: vf_nnedi.c:819
static uint8_t half(int a, int b)
Definition: mobiclip.c:540
An instance of a filter.
Definition: avfilter.h:341
AVRational av_mul_q(AVRational b, AVRational c)
Multiply two rationals.
Definition: rational.c:80
static const AVOption nnedi_options[]
Definition: vf_nnedi.c:130
FILE * out
Definition: movenc.c:54
#define av_freep(p)
planar YUV 4:4:0 (1 Cr & Cb sample per 1x2 Y samples)
Definition: pixfmt.h:99
#define av_malloc_array(a, b)
int ff_request_frame(AVFilterLink *link)
Request an input frame from the filter at the other end of the link.
Definition: avfilter.c:407
void av_image_copy_plane(uint8_t *dst, int dst_linesize, const uint8_t *src, int src_linesize, int bytewidth, int height)
Copy image plane from src to dst.
Definition: imgutils.c:373
void(* write)(const float *src, uint8_t *dst, int src_stride, int dst_stride, int width, int height, int depth, float scale)
Definition: vf_nnedi.c:118
internal API functions
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
int depth
Number of bits in the component.
Definition: pixdesc.h:58
AVPixelFormat
Pixel format.
Definition: pixfmt.h:64
static double val(void *priv, double ch)
Definition: aeval.c:76
#define AV_PIX_FMT_YUV422P16
Definition: pixfmt.h:411
static const size_t NNEDI_WEIGHTS_SIZE
Definition: vf_nnedi.c:35
static float elliott(float x)
Definition: vf_nnedi.c:235
int av_frame_copy_props(AVFrame *dst, const AVFrame *src)
Copy only "metadata" fields from src to dst.
Definition: frame.c:658
int i
Definition: input.c:407
#define AV_NOPTS_VALUE
Undefined timestamp value.
Definition: avutil.h:248
#define AV_PIX_FMT_YUVA422P12
Definition: pixfmt.h:439
#define AV_CEIL_RSHIFT(a, b)
Definition: common.h:58
static av_always_inline av_const unsigned av_clip_uintp2_c(int a, int p)
Clip a signed integer to an unsigned power of two range.
Definition: common.h:229
static uint8_t tmp[11]
Definition: aes_ctr.c:27