FFmpeg
vf_scale_npp.c
Go to the documentation of this file.
1 /*
2  * This file is part of FFmpeg.
3  *
4  * FFmpeg is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * FFmpeg is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with FFmpeg; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17  */
18 
19 /**
20  * @file
21  * scale video filter
22  */
23 
24 #include <nppi.h>
25 #include <stdio.h>
26 #include <string.h>
27 
28 #include "libavutil/hwcontext.h"
30 #include "libavutil/cuda_check.h"
31 #include "libavutil/internal.h"
32 #include "libavutil/mem.h"
33 #include "libavutil/opt.h"
34 #include "libavutil/parseutils.h"
35 #include "libavutil/eval.h"
36 #include "libavutil/pixdesc.h"
37 
38 #include "avfilter.h"
39 #include "filters.h"
40 #include "formats.h"
41 #include "scale_eval.h"
42 #include "video.h"
43 
44 #define CHECK_CU(x) FF_CUDA_CHECK_DL(ctx, device_hwctx->internal->cuda_dl, x)
45 
46 static const enum AVPixelFormat supported_formats[] = {
51 };
52 
53 static const enum AVPixelFormat deinterleaved_formats[][2] = {
55 };
56 
57 enum ScaleStage {
62 };
63 
64 typedef struct NPPScaleStageContext {
68 
69  struct {
70  int width;
71  int height;
72  } planes_in[4], planes_out[4];
73 
77 
78 static const char *const var_names[] = {
79  "in_w", "iw",
80  "in_h", "ih",
81  "out_w", "ow",
82  "out_h", "oh",
83  "a",
84  "sar",
85  "dar",
86  "n",
87  "t",
88  "main_w",
89  "main_h",
90  "main_a",
91  "main_sar",
92  "main_dar", "mdar",
93  "main_n",
94  "main_t",
95  NULL
96 };
97 
98 enum var_name {
116 };
117 
118 enum EvalMode {
122 };
123 
124 typedef struct NPPScaleContext {
125  const AVClass *class;
126 
130 
132 
133  /**
134  * New dimensions. Special values are:
135  * 0 = original width/height
136  * -1 = keep original aspect
137  */
138  int w, h;
139 
140  /**
141  * Output sw format. AV_PIX_FMT_NONE for no conversion.
142  */
144 
145  char *w_expr; ///< width expression string
146  char *h_expr; ///< height expression string
147  char *format_str;
148 
152 
154 
155  char* size_str;
156 
159 
161 
164 
166 #define IS_SCALE2REF(ctx) ((ctx)->filter == &ff_vf_scale2ref_npp.p)
167 
168 static int config_props(AVFilterLink *outlink);
169 
171 {
172  NPPScaleContext* scale = ctx->priv;
173  unsigned vars_w[VARS_NB] = {0}, vars_h[VARS_NB] = {0};
174 
175  if (!scale->w_pexpr && !scale->h_pexpr)
176  return AVERROR(EINVAL);
177 
178  if (scale->w_pexpr)
179  av_expr_count_vars(scale->w_pexpr, vars_w, VARS_NB);
180  if (scale->h_pexpr)
181  av_expr_count_vars(scale->h_pexpr, vars_h, VARS_NB);
182 
183  if (vars_w[VAR_OUT_W] || vars_w[VAR_OW]) {
184  av_log(ctx, AV_LOG_ERROR, "Width expression cannot be self-referencing: '%s'.\n", scale->w_expr);
185  return AVERROR(EINVAL);
186  }
187 
188  if (vars_h[VAR_OUT_H] || vars_h[VAR_OH]) {
189  av_log(ctx, AV_LOG_ERROR, "Height expression cannot be self-referencing: '%s'.\n", scale->h_expr);
190  return AVERROR(EINVAL);
191  }
192 
193  if ((vars_w[VAR_OUT_H] || vars_w[VAR_OH]) &&
194  (vars_h[VAR_OUT_W] || vars_h[VAR_OW])) {
195  av_log(ctx, AV_LOG_WARNING, "Circular references detected for width '%s' and height '%s' - possibly invalid.\n", scale->w_expr, scale->h_expr);
196  }
197 
198  if (!IS_SCALE2REF(ctx) &&
199  (vars_w[VAR_S2R_MAIN_W] || vars_h[VAR_S2R_MAIN_W] ||
200  vars_w[VAR_S2R_MAIN_H] || vars_h[VAR_S2R_MAIN_H] ||
201  vars_w[VAR_S2R_MAIN_A] || vars_h[VAR_S2R_MAIN_A] ||
202  vars_w[VAR_S2R_MAIN_SAR] || vars_h[VAR_S2R_MAIN_SAR] ||
203  vars_w[VAR_S2R_MAIN_DAR] || vars_h[VAR_S2R_MAIN_DAR] ||
204  vars_w[VAR_S2R_MDAR] || vars_h[VAR_S2R_MDAR] ||
205  vars_w[VAR_S2R_MAIN_N] || vars_h[VAR_S2R_MAIN_N] ||
206  vars_w[VAR_S2R_MAIN_T] || vars_h[VAR_S2R_MAIN_T])) {
207  av_log(ctx, AV_LOG_ERROR, "Expressions with scale2ref_npp variables are not valid in scale_npp filter.\n");
208  return AVERROR(EINVAL);
209  }
210 
211  if (scale->eval_mode == EVAL_MODE_INIT &&
212  (vars_w[VAR_N] || vars_h[VAR_N] ||
213  vars_w[VAR_T] || vars_h[VAR_T] ||
214  vars_w[VAR_S2R_MAIN_N] || vars_h[VAR_S2R_MAIN_N] ||
215  vars_w[VAR_S2R_MAIN_T] || vars_h[VAR_S2R_MAIN_T])) {
216  av_log(ctx, AV_LOG_ERROR, "Expressions with frame variables 'n', 't', are not valid in init eval_mode.\n");
217  return AVERROR(EINVAL);
218  }
219 
220  return 0;
221 }
222 
223 static int nppscale_parse_expr(AVFilterContext* ctx, char* str_expr,
224  AVExpr** pexpr_ptr, const char* var,
225  const char* args)
226 {
227  NPPScaleContext* scale = ctx->priv;
228  int ret, is_inited = 0;
229  char* old_str_expr = NULL;
230  AVExpr* old_pexpr = NULL;
231 
232  if (str_expr) {
233  old_str_expr = av_strdup(str_expr);
234  if (!old_str_expr)
235  return AVERROR(ENOMEM);
236  av_opt_set(scale, var, args, 0);
237  }
238 
239  if (*pexpr_ptr) {
240  old_pexpr = *pexpr_ptr;
241  *pexpr_ptr = NULL;
242  is_inited = 1;
243  }
244 
245  ret = av_expr_parse(pexpr_ptr, args, var_names, NULL, NULL, NULL, NULL, 0,
246  ctx);
247  if (ret < 0) {
248  av_log(ctx, AV_LOG_ERROR, "Cannot parse expression for %s: '%s'\n", var,
249  args);
250  goto revert;
251  }
252 
253  ret = check_exprs(ctx);
254  if (ret < 0)
255  goto revert;
256 
257  if (is_inited && (ret = config_props(ctx->outputs[0])) < 0)
258  goto revert;
259 
260  av_expr_free(old_pexpr);
261  old_pexpr = NULL;
262  av_freep(&old_str_expr);
263 
264  return 0;
265 
266 revert:
267  av_expr_free(*pexpr_ptr);
268  *pexpr_ptr = NULL;
269  if (old_str_expr) {
270  av_opt_set(scale, var, old_str_expr, 0);
271  av_free(old_str_expr);
272  }
273  if (old_pexpr)
274  *pexpr_ptr = old_pexpr;
275 
276  return ret;
277 }
278 
280 {
281  NPPScaleContext* scale = ctx->priv;
282  int i, ret;
283 
284  av_log(ctx, AV_LOG_WARNING, "The libnpp based filters are deprecated.\n");
285 
286  if (!strcmp(scale->format_str, "same")) {
287  scale->format = AV_PIX_FMT_NONE;
288  } else {
289  scale->format = av_get_pix_fmt(scale->format_str);
290  if (scale->format == AV_PIX_FMT_NONE) {
291  av_log(ctx, AV_LOG_ERROR, "Unrecognized pixel format: %s\n", scale->format_str);
292  return AVERROR(EINVAL);
293  }
294  }
295 
296  if (scale->size_str && (scale->w_expr || scale->h_expr)) {
298  "Size and width/height exprs cannot be set at the same time.\n");
299  return AVERROR(EINVAL);
300  }
301 
302  if (scale->w_expr && !scale->h_expr)
303  FFSWAP(char*, scale->w_expr, scale->size_str);
304 
305  if (scale->size_str) {
306  char buf[32];
307  ret = av_parse_video_size(&scale->w, &scale->h, scale->size_str);
308  if (0 > ret) {
309  av_log(ctx, AV_LOG_ERROR, "Invalid size '%s'\n", scale->size_str);
310  return ret;
311  }
312 
313  snprintf(buf, sizeof(buf) - 1, "%d", scale->w);
314  ret = av_opt_set(scale, "w", buf, 0);
315  if (ret < 0)
316  return ret;
317 
318  snprintf(buf, sizeof(buf) - 1, "%d", scale->h);
319  ret = av_opt_set(scale, "h", buf, 0);
320  if (ret < 0)
321  return ret;
322  }
323 
324  if (!scale->w_expr) {
325  ret = av_opt_set(scale, "w", "iw", 0);
326  if (ret < 0)
327  return ret;
328  }
329 
330  if (!scale->h_expr) {
331  ret = av_opt_set(scale, "h", "ih", 0);
332  if (ret < 0)
333  return ret;
334  }
335 
336  ret = nppscale_parse_expr(ctx, NULL, &scale->w_pexpr, "width", scale->w_expr);
337  if (ret < 0)
338  return ret;
339 
340  ret = nppscale_parse_expr(ctx, NULL, &scale->h_pexpr, "height", scale->h_expr);
341  if (ret < 0)
342  return ret;
343 
344  for (i = 0; i < FF_ARRAY_ELEMS(scale->stages); i++) {
345  scale->stages[i].frame = av_frame_alloc();
346  if (!scale->stages[i].frame)
347  return AVERROR(ENOMEM);
348  }
349  scale->tmp_frame = av_frame_alloc();
350  if (!scale->tmp_frame)
351  return AVERROR(ENOMEM);
352 
353  return 0;
354 }
355 
357 {
358  NPPScaleContext* scale = ctx->priv;
359  const char scale2ref = IS_SCALE2REF(ctx);
360  const AVFilterLink* inlink = ctx->inputs[scale2ref ? 1 : 0];
361  char* expr;
362  int eval_w, eval_h;
363  int ret;
364  double res;
365 
366  scale->var_values[VAR_IN_W] = scale->var_values[VAR_IW] = inlink->w;
367  scale->var_values[VAR_IN_H] = scale->var_values[VAR_IH] = inlink->h;
368  scale->var_values[VAR_OUT_W] = scale->var_values[VAR_OW] = NAN;
369  scale->var_values[VAR_OUT_H] = scale->var_values[VAR_OH] = NAN;
370  scale->var_values[VAR_A] = (double)inlink->w / inlink->h;
371  scale->var_values[VAR_SAR] = inlink->sample_aspect_ratio.num ?
372  (double)inlink->sample_aspect_ratio.num / inlink->sample_aspect_ratio.den : 1;
373  scale->var_values[VAR_DAR] = scale->var_values[VAR_A] * scale->var_values[VAR_SAR];
374 
375  if (scale2ref) {
376  const AVFilterLink* main_link = ctx->inputs[0];
377 
378  scale->var_values[VAR_S2R_MAIN_W] = main_link->w;
379  scale->var_values[VAR_S2R_MAIN_H] = main_link->h;
380  scale->var_values[VAR_S2R_MAIN_A] = (double)main_link->w / main_link->h;
381  scale->var_values[VAR_S2R_MAIN_SAR] = main_link->sample_aspect_ratio.num ?
382  (double)main_link->sample_aspect_ratio.num / main_link->sample_aspect_ratio.den : 1;
383  scale->var_values[VAR_S2R_MAIN_DAR] = scale->var_values[VAR_S2R_MDAR] =
384  scale->var_values[VAR_S2R_MAIN_A] * scale->var_values[VAR_S2R_MAIN_SAR];
385  }
386 
387  res = av_expr_eval(scale->w_pexpr, scale->var_values, NULL);
388  eval_w = scale->var_values[VAR_OUT_W] = scale->var_values[VAR_OW] = (int)res == 0 ? inlink->w : (int)res;
389 
390  res = av_expr_eval(scale->h_pexpr, scale->var_values, NULL);
391  if (isnan(res)) {
392  expr = scale->h_expr;
393  ret = AVERROR(EINVAL);
394  goto fail;
395  }
396  eval_h = scale->var_values[VAR_OUT_H] = scale->var_values[VAR_OH] = (int)res == 0 ? inlink->h : (int)res;
397 
398  res = av_expr_eval(scale->w_pexpr, scale->var_values, NULL);
399  if (isnan(res)) {
400  expr = scale->w_expr;
401  ret = AVERROR(EINVAL);
402  goto fail;
403  }
404  eval_w = scale->var_values[VAR_OUT_W] = scale->var_values[VAR_OW] = (int)res == 0 ? inlink->w : (int)res;
405 
406  scale->w = eval_w;
407  scale->h = eval_h;
408 
409  return 0;
410 
411 fail:
412  av_log(ctx, AV_LOG_ERROR, "Error when evaluating the expression '%s'.\n",
413  expr);
414  return ret;
415 }
416 
418 {
419  NPPScaleContext *s = ctx->priv;
420  int i;
421 
422  for (i = 0; i < FF_ARRAY_ELEMS(s->stages); i++) {
423  av_frame_free(&s->stages[i].frame);
424  av_buffer_unref(&s->stages[i].frames_ctx);
425  }
426  av_frame_free(&s->tmp_frame);
427 
428  av_expr_free(s->w_pexpr);
429  av_expr_free(s->h_pexpr);
430  s->w_pexpr = s->h_pexpr = NULL;
431 }
432 
433 static int init_stage(NPPScaleStageContext *stage, AVBufferRef *device_ctx)
434 {
435  AVBufferRef *out_ref = NULL;
436  AVHWFramesContext *out_ctx;
437  int in_sw, in_sh, out_sw, out_sh;
438  int ret, i;
439 
440  av_pix_fmt_get_chroma_sub_sample(stage->in_fmt, &in_sw, &in_sh);
441  av_pix_fmt_get_chroma_sub_sample(stage->out_fmt, &out_sw, &out_sh);
442  if (!stage->planes_out[0].width) {
443  stage->planes_out[0].width = stage->planes_in[0].width;
444  stage->planes_out[0].height = stage->planes_in[0].height;
445  }
446 
447  for (i = 1; i < FF_ARRAY_ELEMS(stage->planes_in); i++) {
448  stage->planes_in[i].width = stage->planes_in[0].width >> in_sw;
449  stage->planes_in[i].height = stage->planes_in[0].height >> in_sh;
450  stage->planes_out[i].width = stage->planes_out[0].width >> out_sw;
451  stage->planes_out[i].height = stage->planes_out[0].height >> out_sh;
452  }
453 
454  if (AV_PIX_FMT_YUVA420P == stage->in_fmt) {
455  stage->planes_in[3].width = stage->planes_in[0].width;
456  stage->planes_in[3].height = stage->planes_in[0].height;
457  stage->planes_out[3].width = stage->planes_out[0].width;
458  stage->planes_out[3].height = stage->planes_out[0].height;
459  }
460 
461  out_ref = av_hwframe_ctx_alloc(device_ctx);
462  if (!out_ref)
463  return AVERROR(ENOMEM);
464  out_ctx = (AVHWFramesContext*)out_ref->data;
465 
466  out_ctx->format = AV_PIX_FMT_CUDA;
467  out_ctx->sw_format = stage->out_fmt;
468  out_ctx->width = FFALIGN(stage->planes_out[0].width, 32);
469  out_ctx->height = FFALIGN(stage->planes_out[0].height, 32);
470 
471  ret = av_hwframe_ctx_init(out_ref);
472  if (ret < 0)
473  goto fail;
474 
475  av_frame_unref(stage->frame);
476  ret = av_hwframe_get_buffer(out_ref, stage->frame, 0);
477  if (ret < 0)
478  goto fail;
479 
480  stage->frame->width = stage->planes_out[0].width;
481  stage->frame->height = stage->planes_out[0].height;
482 
483  av_buffer_unref(&stage->frames_ctx);
484  stage->frames_ctx = out_ref;
485 
486  return 0;
487 fail:
488  av_buffer_unref(&out_ref);
489  return ret;
490 }
491 
492 static int format_is_supported(enum AVPixelFormat fmt)
493 {
494  int i;
495 
496  for (i = 0; i < FF_ARRAY_ELEMS(supported_formats); i++)
497  if (supported_formats[i] == fmt)
498  return 1;
499  return 0;
500 }
501 
503 {
505  int i, planes;
506 
508  if (planes == desc->nb_components)
509  return fmt;
510  for (i = 0; i < FF_ARRAY_ELEMS(deinterleaved_formats); i++)
511  if (deinterleaved_formats[i][0] == fmt)
512  return deinterleaved_formats[i][1];
513  return AV_PIX_FMT_NONE;
514 }
515 
516 static int init_processing_chain(AVFilterContext *ctx, int in_width, int in_height,
517  int out_width, int out_height)
518 {
519  NPPScaleContext *s = ctx->priv;
520  FilterLink *inl = ff_filter_link(ctx->inputs[0]);
521  FilterLink *outl = ff_filter_link(ctx->outputs[0]);
522 
523  AVHWFramesContext *in_frames_ctx;
524 
525  enum AVPixelFormat in_format;
526  enum AVPixelFormat out_format;
527  enum AVPixelFormat in_deinterleaved_format;
528  enum AVPixelFormat out_deinterleaved_format;
529 
530  int i, ret, last_stage = -1;
531 
532  /* check that we have a hw context */
533  if (!inl->hw_frames_ctx) {
534  av_log(ctx, AV_LOG_ERROR, "No hw context provided on input\n");
535  return AVERROR(EINVAL);
536  }
537  in_frames_ctx = (AVHWFramesContext*)inl->hw_frames_ctx->data;
538  in_format = in_frames_ctx->sw_format;
539  out_format = (s->format == AV_PIX_FMT_NONE) ? in_format : s->format;
540 
541  if (!format_is_supported(in_format)) {
542  av_log(ctx, AV_LOG_ERROR, "Unsupported input format: %s\n",
543  av_get_pix_fmt_name(in_format));
544  return AVERROR(ENOSYS);
545  }
546  if (!format_is_supported(out_format)) {
547  av_log(ctx, AV_LOG_ERROR, "Unsupported output format: %s\n",
548  av_get_pix_fmt_name(out_format));
549  return AVERROR(ENOSYS);
550  }
551 
552  in_deinterleaved_format = get_deinterleaved_format(in_format);
553  out_deinterleaved_format = get_deinterleaved_format(out_format);
554  if (in_deinterleaved_format == AV_PIX_FMT_NONE ||
555  out_deinterleaved_format == AV_PIX_FMT_NONE)
556  return AVERROR_BUG;
557 
558  /* figure out which stages need to be done */
559  if (in_width != out_width || in_height != out_height ||
560  in_deinterleaved_format != out_deinterleaved_format) {
561  s->stages[STAGE_RESIZE].stage_needed = 1;
562 
563  if (s->interp_algo == NPPI_INTER_SUPER &&
564  (out_width > in_width && out_height > in_height)) {
565  s->interp_algo = NPPI_INTER_LANCZOS;
566  av_log(ctx, AV_LOG_WARNING, "super-sampling not supported for output dimensions, using lanczos instead.\n");
567  }
568  if (s->interp_algo == NPPI_INTER_SUPER &&
569  !(out_width < in_width && out_height < in_height)) {
570  s->interp_algo = NPPI_INTER_CUBIC;
571  av_log(ctx, AV_LOG_WARNING, "super-sampling not supported for output dimensions, using cubic instead.\n");
572  }
573  }
574 
575  if (!s->stages[STAGE_RESIZE].stage_needed && in_format == out_format)
576  s->passthrough = 1;
577 
578  if (!s->passthrough) {
579  if (in_format != in_deinterleaved_format)
580  s->stages[STAGE_DEINTERLEAVE].stage_needed = 1;
581  if (out_format != out_deinterleaved_format)
582  s->stages[STAGE_INTERLEAVE].stage_needed = 1;
583  }
584 
585  s->stages[STAGE_DEINTERLEAVE].in_fmt = in_format;
586  s->stages[STAGE_DEINTERLEAVE].out_fmt = in_deinterleaved_format;
587  s->stages[STAGE_DEINTERLEAVE].planes_in[0].width = in_width;
588  s->stages[STAGE_DEINTERLEAVE].planes_in[0].height = in_height;
589 
590  s->stages[STAGE_RESIZE].in_fmt = in_deinterleaved_format;
591  s->stages[STAGE_RESIZE].out_fmt = out_deinterleaved_format;
592  s->stages[STAGE_RESIZE].planes_in[0].width = in_width;
593  s->stages[STAGE_RESIZE].planes_in[0].height = in_height;
594  s->stages[STAGE_RESIZE].planes_out[0].width = out_width;
595  s->stages[STAGE_RESIZE].planes_out[0].height = out_height;
596 
597  s->stages[STAGE_INTERLEAVE].in_fmt = out_deinterleaved_format;
598  s->stages[STAGE_INTERLEAVE].out_fmt = out_format;
599  s->stages[STAGE_INTERLEAVE].planes_in[0].width = out_width;
600  s->stages[STAGE_INTERLEAVE].planes_in[0].height = out_height;
601 
602  /* init the hardware contexts */
603  for (i = 0; i < FF_ARRAY_ELEMS(s->stages); i++) {
604  if (!s->stages[i].stage_needed)
605  continue;
606 
607  ret = init_stage(&s->stages[i], in_frames_ctx->device_ref);
608  if (ret < 0)
609  return ret;
610 
611  last_stage = i;
612  }
613 
614  if (last_stage >= 0)
615  outl->hw_frames_ctx = av_buffer_ref(s->stages[last_stage].frames_ctx);
616  else
618 
619  if (!outl->hw_frames_ctx)
620  return AVERROR(ENOMEM);
621 
622  return 0;
623 }
624 
625 static int config_props(AVFilterLink *outlink)
626 {
627  AVFilterContext *ctx = outlink->src;
628  AVFilterLink *inlink0 = outlink->src->inputs[0];
630  outlink->src->inputs[1] :
631  outlink->src->inputs[0];
632  NPPScaleContext *s = ctx->priv;
633  double w_adj = 1.0;
634  int ret;
635 
636  if ((ret = nppscale_eval_dimensions(ctx)) < 0)
637  goto fail;
638 
639  if (s->reset_sar)
640  w_adj = IS_SCALE2REF(ctx) ? s->var_values[VAR_S2R_MAIN_SAR] :
641  s->var_values[VAR_SAR];
642 
644  s->force_original_aspect_ratio,
645  s->force_divisible_by, w_adj);
646  if (ret < 0)
647  goto fail;
648 
649  if (s->w > INT_MAX || s->h > INT_MAX ||
650  (s->h * inlink->w) > INT_MAX ||
651  (s->w * inlink->h) > INT_MAX)
652  av_log(ctx, AV_LOG_ERROR, "Rescaled value for width or height is too big.\n");
653 
654  outlink->w = s->w;
655  outlink->h = s->h;
656 
657  ret = init_processing_chain(ctx, inlink0->w, inlink0->h, outlink->w, outlink->h);
658  if (ret < 0)
659  return ret;
660 
661  av_log(ctx, AV_LOG_VERBOSE, "w:%d h:%d -> w:%d h:%d\n",
662  inlink->w, inlink->h, outlink->w, outlink->h);
663 
664  if (s->reset_sar)
665  outlink->sample_aspect_ratio = (AVRational){1, 1};
666  else if (inlink->sample_aspect_ratio.num)
667  outlink->sample_aspect_ratio = av_mul_q((AVRational){outlink->h*inlink->w,
668  outlink->w*inlink->h},
669  inlink->sample_aspect_ratio);
670  else
671  outlink->sample_aspect_ratio = inlink->sample_aspect_ratio;
672 
673  return 0;
674 
675 fail:
676  return ret;
677 }
678 
679 static int config_props_ref(AVFilterLink *outlink)
680 {
681  FilterLink *outl = ff_filter_link(outlink);
682  AVFilterLink *inlink = outlink->src->inputs[1];
684  FilterLink *ol = ff_filter_link(outlink);
685 
686  outlink->w = inlink->w;
687  outlink->h = inlink->h;
688  outlink->sample_aspect_ratio = inlink->sample_aspect_ratio;
689  outlink->time_base = inlink->time_base;
690  ol->frame_rate = inl->frame_rate;
691 
693 
694  return 0;
695 }
696 
698  AVFrame *out, AVFrame *in)
699 {
700  AVHWFramesContext *in_frames_ctx = (AVHWFramesContext*)in->hw_frames_ctx->data;
701  NppStatus err;
702 
703  switch (in_frames_ctx->sw_format) {
704  case AV_PIX_FMT_NV12:
705  err = nppiYCbCr420_8u_P2P3R(in->data[0], in->linesize[0],
706  in->data[1], in->linesize[1],
707  out->data, out->linesize,
708  (NppiSize){ in->width, in->height });
709  break;
710  default:
711  return AVERROR_BUG;
712  }
713  if (err != NPP_SUCCESS) {
714  av_log(ctx, AV_LOG_ERROR, "NPP deinterleave error: %d\n", err);
715  return AVERROR_UNKNOWN;
716  }
717 
718  return 0;
719 }
720 
722  AVFrame *out, AVFrame *in)
723 {
724  NPPScaleContext *s = ctx->priv;
725  NppStatus err;
726  int i;
727 
728  for (i = 0; i < FF_ARRAY_ELEMS(stage->planes_in) && i < FF_ARRAY_ELEMS(in->data) && in->data[i]; i++) {
729  int iw = stage->planes_in[i].width;
730  int ih = stage->planes_in[i].height;
731  int ow = stage->planes_out[i].width;
732  int oh = stage->planes_out[i].height;
733 
734  err = nppiResizeSqrPixel_8u_C1R(in->data[i], (NppiSize){ iw, ih },
735  in->linesize[i], (NppiRect){ 0, 0, iw, ih },
736  out->data[i], out->linesize[i],
737  (NppiRect){ 0, 0, ow, oh },
738  (double)ow / iw, (double)oh / ih,
739  0.0, 0.0, s->interp_algo);
740  if (err != NPP_SUCCESS) {
741  av_log(ctx, AV_LOG_ERROR, "NPP resize error: %d\n", err);
742  return AVERROR_UNKNOWN;
743  }
744  }
745 
746  return 0;
747 }
748 
750  AVFrame *out, AVFrame *in)
751 {
752  AVHWFramesContext *out_frames_ctx = (AVHWFramesContext*)out->hw_frames_ctx->data;
753  NppStatus err;
754 
755  switch (out_frames_ctx->sw_format) {
756  case AV_PIX_FMT_NV12:
757  err = nppiYCbCr420_8u_P3P2R((const uint8_t**)in->data,
758  in->linesize,
759  out->data[0], out->linesize[0],
760  out->data[1], out->linesize[1],
761  (NppiSize){ in->width, in->height });
762  break;
763  default:
764  return AVERROR_BUG;
765  }
766  if (err != NPP_SUCCESS) {
767  av_log(ctx, AV_LOG_ERROR, "NPP deinterleave error: %d\n", err);
768  return AVERROR_UNKNOWN;
769  }
770 
771  return 0;
772 }
773 
775  AVFrame *out, AVFrame *in) = {
779 };
780 
782 {
784  AVFilterContext *ctx = link->dst;
785  NPPScaleContext *s = ctx->priv;
786  AVFilterLink *outlink = ctx->outputs[0];
787  AVFrame *src = in;
788  char buf[32];
789  int i, ret, last_stage = -1;
790  int frame_changed;
791 
792  frame_changed = in->width != link->w ||
793  in->height != link->h ||
794  in->format != link->format ||
797 
798  if (s->eval_mode == EVAL_MODE_FRAME || frame_changed) {
799  unsigned vars_w[VARS_NB] = { 0 }, vars_h[VARS_NB] = { 0 };
800 
801  av_expr_count_vars(s->w_pexpr, vars_w, VARS_NB);
802  av_expr_count_vars(s->h_pexpr, vars_h, VARS_NB);
803 
804  if (s->eval_mode == EVAL_MODE_FRAME && !frame_changed && !IS_SCALE2REF(ctx) &&
805  !(vars_w[VAR_N] || vars_w[VAR_T]) &&
806  !(vars_h[VAR_N] || vars_h[VAR_T]) && s->w && s->h)
807  goto scale;
808 
809  if (s->eval_mode == EVAL_MODE_INIT) {
810  snprintf(buf, sizeof(buf)-1, "%d", outlink->w);
811  av_opt_set(s, "w", buf, 0);
812  snprintf(buf, sizeof(buf)-1, "%d", outlink->h);
813  av_opt_set(s, "h", buf, 0);
814 
815  ret = nppscale_parse_expr(ctx, NULL, &s->w_pexpr, "width", s->w_expr);
816  if (ret < 0)
817  return ret;
818 
819  ret = nppscale_parse_expr(ctx, NULL, &s->h_pexpr, "height", s->h_expr);
820  if (ret < 0)
821  return ret;
822  }
823 
824  if (IS_SCALE2REF(ctx)) {
825  s->var_values[VAR_S2R_MAIN_N] = inl->frame_count_out;
826  s->var_values[VAR_S2R_MAIN_T] = TS2T(in->pts, link->time_base);
827  } else {
828  s->var_values[VAR_N] = inl->frame_count_out;
829  s->var_values[VAR_T] = TS2T(in->pts, link->time_base);
830  }
831 
832  link->format = in->format;
833  link->w = in->width;
834  link->h = in->height;
835 
838 
839  if ((ret = config_props(outlink)) < 0)
840  return ret;
841  }
842 
843 scale:
844  for (i = 0; i < FF_ARRAY_ELEMS(s->stages); i++) {
845  if (!s->stages[i].stage_needed)
846  continue;
847 
848  ret = nppscale_process[i](ctx, &s->stages[i], s->stages[i].frame, src);
849  if (ret < 0)
850  return ret;
851 
852  src = s->stages[i].frame;
853  last_stage = i;
854  }
855  if (last_stage < 0)
856  return AVERROR_BUG;
857 
858  ret = av_hwframe_get_buffer(src->hw_frames_ctx, s->tmp_frame, 0);
859  if (ret < 0)
860  return ret;
861 
862  s->tmp_frame->width = src->width;
863  s->tmp_frame->height = src->height;
864 
866  av_frame_move_ref(src, s->tmp_frame);
867 
868  ret = av_frame_copy_props(out, in);
869  if (ret < 0)
870  return ret;
871 
872  if (out->width != in->width || out->height != in->height) {
873  av_frame_side_data_remove_by_props(&out->side_data, &out->nb_side_data,
875  }
876 
877  return 0;
878 }
879 
881 {
882  AVFilterContext *ctx = link->dst;
883  NPPScaleContext *s = ctx->priv;
884  AVFilterLink *outlink = ctx->outputs[0];
885  FilterLink *l = ff_filter_link(outlink);
887  AVCUDADeviceContext *device_hwctx = frames_ctx->device_ctx->hwctx;
888 
889  AVFrame *out = NULL;
890  CUcontext dummy;
891  int ret = 0;
892 
893  if (s->passthrough)
894  return ff_filter_frame(outlink, in);
895 
896  out = av_frame_alloc();
897  if (!out) {
898  ret = AVERROR(ENOMEM);
899  goto fail;
900  }
901 
902  ret = CHECK_CU(device_hwctx->internal->cuda_dl->cuCtxPushCurrent(device_hwctx->cuda_ctx));
903  if (ret < 0)
904  goto fail;
905 
906  ret = nppscale_scale(link, out, in);
907 
908  CHECK_CU(device_hwctx->internal->cuda_dl->cuCtxPopCurrent(&dummy));
909  if (ret < 0)
910  goto fail;
911 
912  av_reduce(&out->sample_aspect_ratio.num, &out->sample_aspect_ratio.den,
913  (int64_t)in->sample_aspect_ratio.num * outlink->h * link->w,
914  (int64_t)in->sample_aspect_ratio.den * outlink->w * link->h,
915  INT_MAX);
916 
917  av_frame_free(&in);
918  return ff_filter_frame(outlink, out);
919 fail:
920  av_frame_free(&in);
921  av_frame_free(&out);
922  return ret;
923 }
924 
926 {
928  NPPScaleContext *scale = link->dst->priv;
929  AVFilterLink *outlink = link->dst->outputs[1];
930  int frame_changed;
931 
932  frame_changed = in->width != link->w ||
933  in->height != link->h ||
934  in->format != link->format ||
937 
938  if (frame_changed) {
939  link->format = in->format;
940  link->w = in->width;
941  link->h = in->height;
944 
945  config_props_ref(outlink);
946  }
947 
948  if (scale->eval_mode == EVAL_MODE_FRAME) {
949  scale->var_values[VAR_N] = inl->frame_count_out;
950  scale->var_values[VAR_T] = TS2T(in->pts, link->time_base);
951  }
952 
953  return ff_filter_frame(outlink, in);
954 }
955 
956 static int request_frame(AVFilterLink *outlink)
957 {
958  return ff_request_frame(outlink->src->inputs[0]);
959 }
960 
961 static int request_frame_ref(AVFilterLink *outlink)
962 {
963  return ff_request_frame(outlink->src->inputs[1]);
964 }
965 
966 #define OFFSET(x) offsetof(NPPScaleContext, x)
967 #define FLAGS (AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM)
968 static const AVOption options[] = {
969  { "w", "Output video width", OFFSET(w_expr), AV_OPT_TYPE_STRING, .flags = FLAGS },
970  { "h", "Output video height", OFFSET(h_expr), AV_OPT_TYPE_STRING, .flags = FLAGS },
971  { "format", "Output pixel format", OFFSET(format_str), AV_OPT_TYPE_STRING, { .str = "same" }, .flags = FLAGS },
972  { "s", "Output video size", OFFSET(size_str), AV_OPT_TYPE_STRING, { .str = NULL }, .flags = FLAGS },
973 
974  { "interp_algo", "Interpolation algorithm used for resizing", OFFSET(interp_algo), AV_OPT_TYPE_INT, { .i64 = NPPI_INTER_CUBIC }, 0, INT_MAX, FLAGS, .unit = "interp_algo" },
975  { "nn", "nearest neighbour", 0, AV_OPT_TYPE_CONST, { .i64 = NPPI_INTER_NN }, 0, 0, FLAGS, .unit = "interp_algo" },
976  { "linear", "linear", 0, AV_OPT_TYPE_CONST, { .i64 = NPPI_INTER_LINEAR }, 0, 0, FLAGS, .unit = "interp_algo" },
977  { "cubic", "cubic", 0, AV_OPT_TYPE_CONST, { .i64 = NPPI_INTER_CUBIC }, 0, 0, FLAGS, .unit = "interp_algo" },
978  { "cubic2p_bspline", "2-parameter cubic (B=1, C=0)", 0, AV_OPT_TYPE_CONST, { .i64 = NPPI_INTER_CUBIC2P_BSPLINE }, 0, 0, FLAGS, .unit = "interp_algo" },
979  { "cubic2p_catmullrom", "2-parameter cubic (B=0, C=1/2)", 0, AV_OPT_TYPE_CONST, { .i64 = NPPI_INTER_CUBIC2P_CATMULLROM }, 0, 0, FLAGS, .unit = "interp_algo" },
980  { "cubic2p_b05c03", "2-parameter cubic (B=1/2, C=3/10)", 0, AV_OPT_TYPE_CONST, { .i64 = NPPI_INTER_CUBIC2P_B05C03 }, 0, 0, FLAGS, .unit = "interp_algo" },
981  { "super", "supersampling", 0, AV_OPT_TYPE_CONST, { .i64 = NPPI_INTER_SUPER }, 0, 0, FLAGS, .unit = "interp_algo" },
982  { "lanczos", "Lanczos", 0, AV_OPT_TYPE_CONST, { .i64 = NPPI_INTER_LANCZOS }, 0, 0, FLAGS, .unit = "interp_algo" },
983  { "force_original_aspect_ratio", "decrease or increase w/h if necessary to keep the original AR", OFFSET(force_original_aspect_ratio), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, SCALE_FORCE_OAR_NB-1, FLAGS, .unit = "force_oar" },
984  { "disable", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = SCALE_FORCE_OAR_DISABLE }, 0, 0, FLAGS, .unit = "force_oar" },
985  { "decrease", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = SCALE_FORCE_OAR_DECREASE }, 0, 0, FLAGS, .unit = "force_oar" },
986  { "increase", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = SCALE_FORCE_OAR_INCREASE }, 0, 0, FLAGS, .unit = "force_oar" },
987  { "force_divisible_by", "enforce that the output resolution is divisible by a defined integer when force_original_aspect_ratio is used", OFFSET(force_divisible_by), AV_OPT_TYPE_INT, { .i64 = 1 }, 1, 256, FLAGS },
988  { "reset_sar", "reset SAR to 1 and scale to square pixels if scaling proportionally", OFFSET(reset_sar), AV_OPT_TYPE_BOOL, { .i64 = 0}, 0, 1, FLAGS },
989  { "eval", "specify when to evaluate expressions", OFFSET(eval_mode), AV_OPT_TYPE_INT, { .i64 = EVAL_MODE_INIT }, 0, EVAL_MODE_NB-1, FLAGS, .unit = "eval" },
990  { "init", "eval expressions once during initialization", 0, AV_OPT_TYPE_CONST, { .i64 = EVAL_MODE_INIT }, 0, 0, FLAGS, .unit = "eval" },
991  { "frame", "eval expressions during initialization and per-frame", 0, AV_OPT_TYPE_CONST, { .i64 = EVAL_MODE_FRAME }, 0, 0, FLAGS, .unit = "eval" },
992  { NULL },
993 };
994 
995 static const AVClass nppscale_class = {
996  .class_name = "nppscale",
997  .item_name = av_default_item_name,
998  .option = options,
999  .version = LIBAVUTIL_VERSION_INT,
1000  .category = AV_CLASS_CATEGORY_FILTER,
1001 };
1002 
1003 static const AVFilterPad nppscale_inputs[] = {
1004  {
1005  .name = "default",
1006  .type = AVMEDIA_TYPE_VIDEO,
1007  .filter_frame = nppscale_filter_frame,
1008  }
1009 };
1010 
1011 static const AVFilterPad nppscale_outputs[] = {
1012  {
1013  .name = "default",
1014  .type = AVMEDIA_TYPE_VIDEO,
1015  .config_props = config_props,
1016  }
1017 };
1018 
1020  .p.name = "scale_npp",
1021  .p.description = NULL_IF_CONFIG_SMALL("NVIDIA Performance Primitives video "
1022  "scaling and format conversion"),
1023  .p.priv_class = &nppscale_class,
1024 
1025  .init = nppscale_init,
1026  .uninit = nppscale_uninit,
1027 
1028  .priv_size = sizeof(NPPScaleContext),
1029 
1032 
1034 
1035  .flags_internal = FF_FILTER_FLAG_HWFRAME_AWARE,
1036 };
1037 
1039  {
1040  .name = "default",
1041  .type = AVMEDIA_TYPE_VIDEO,
1042  .filter_frame = nppscale_filter_frame,
1043  },
1044  {
1045  .name = "ref",
1046  .type = AVMEDIA_TYPE_VIDEO,
1047  .filter_frame = nppscale_filter_frame_ref,
1048  }
1049 };
1050 
1052  {
1053  .name = "default",
1054  .type = AVMEDIA_TYPE_VIDEO,
1055  .config_props = config_props,
1056  .request_frame= request_frame,
1057  },
1058  {
1059  .name = "ref",
1060  .type = AVMEDIA_TYPE_VIDEO,
1061  .config_props = config_props_ref,
1062  .request_frame= request_frame_ref,
1063  }
1064 };
1065 
1067  .p.name = "scale2ref_npp",
1068  .p.description = NULL_IF_CONFIG_SMALL("NVIDIA Performance Primitives video "
1069  "scaling and format conversion to the "
1070  "given reference."),
1071  .p.priv_class = &nppscale_class,
1072 
1073  .init = nppscale_init,
1074  .uninit = nppscale_uninit,
1075 
1076  .priv_size = sizeof(NPPScaleContext),
1077 
1080 
1082 
1083  .flags_internal = FF_FILTER_FLAG_HWFRAME_AWARE,
1084 };
format_is_supported
static int format_is_supported(enum AVPixelFormat fmt)
Definition: vf_scale_npp.c:492
AVHWDeviceContext::hwctx
void * hwctx
The format-specific data, allocated and freed by libavutil along with this context.
Definition: hwcontext.h:88
NPPScaleContext::passthrough
int passthrough
Definition: vf_scale_npp.c:129
AV_LOG_WARNING
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:216
AV_PIX_FMT_CUDA
@ AV_PIX_FMT_CUDA
HW acceleration through CUDA.
Definition: pixfmt.h:260
AVPixelFormat
AVPixelFormat
Pixel format.
Definition: pixfmt.h:71
ff_vf_scale_npp
const FFFilter ff_vf_scale_npp
Definition: vf_scale_npp.c:1019
VAR_OW
@ VAR_OW
Definition: vf_scale_npp.c:101
nppscale_inputs
static const AVFilterPad nppscale_inputs[]
Definition: vf_scale_npp.c:1003
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
nppscale2ref_inputs
static const AVFilterPad nppscale2ref_inputs[]
Definition: vf_scale_npp.c:1038
opt.h
var_name
var_name
Definition: noise.c:46
hwcontext_cuda_internal.h
out
static FILE * out
Definition: movenc.c:55
NPPScaleContext::h_pexpr
AVExpr * h_pexpr
Definition: vf_scale_npp.c:158
ff_filter_frame
int ff_filter_frame(AVFilterLink *link, AVFrame *frame)
Send a frame of data to the next filter.
Definition: avfilter.c:1067
av_pix_fmt_desc_get
const AVPixFmtDescriptor * av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt)
Definition: pixdesc.c:3456
AVBufferRef::data
uint8_t * data
The data buffer.
Definition: buffer.h:90
CHECK_CU
#define CHECK_CU(x)
Definition: vf_scale_npp.c:44
AVHWFramesContext::format
enum AVPixelFormat format
The pixel format identifying the underlying HW surface type.
Definition: hwcontext.h:200
int64_t
long long int64_t
Definition: coverity.c:34
inlink
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
Definition: filter_design.txt:212
ScaleStage
ScaleStage
Definition: vf_scale_npp.c:57
FF_FILTER_FLAG_HWFRAME_AWARE
#define FF_FILTER_FLAG_HWFRAME_AWARE
The filter is aware of hardware frames, and any hardware frame context should not be automatically pr...
Definition: filters.h:208
nppscale_class
static const AVClass nppscale_class
Definition: vf_scale_npp.c:995
VAR_S2R_MAIN_N
@ VAR_S2R_MAIN_N
Definition: vf_scale_npp.c:113
av_frame_free
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition: frame.c:64
SCALE_FORCE_OAR_DECREASE
@ SCALE_FORCE_OAR_DECREASE
Definition: scale_eval.h:26
av_hwframe_ctx_init
int av_hwframe_ctx_init(AVBufferRef *ref)
Finalize the context before use.
Definition: hwcontext.c:337
AVFrame
This structure describes decoded (raw) audio or video data.
Definition: frame.h:434
pixdesc.h
AVFrame::pts
int64_t pts
Presentation timestamp in time_base units (time when frame should be shown to user).
Definition: frame.h:536
AVFrame::width
int width
Definition: frame.h:506
av_hwframe_ctx_alloc
AVBufferRef * av_hwframe_ctx_alloc(AVBufferRef *device_ref_in)
Allocate an AVHWFramesContext tied to a given device context.
Definition: hwcontext.c:263
NPPScaleStageContext::stage_needed
int stage_needed
Definition: vf_scale_npp.c:65
VAR_A
@ VAR_A
Definition: vf_scale_npp.c:103
NPPScaleStageContext::planes_in
struct NPPScaleStageContext::@434 planes_in[4]
AVOption
AVOption.
Definition: opt.h:429
FILTER_SINGLE_PIXFMT
#define FILTER_SINGLE_PIXFMT(pix_fmt_)
Definition: filters.h:254
filters.h
ff_request_frame
int ff_request_frame(AVFilterLink *link)
Request an input frame from the filter at the other end of the link.
Definition: avfilter.c:483
supported_formats
static enum AVPixelFormat supported_formats[]
Definition: vf_scale_npp.c:46
AV_LOG_VERBOSE
#define AV_LOG_VERBOSE
Detailed information.
Definition: log.h:226
STAGE_NB
@ STAGE_NB
Definition: vf_scale_npp.c:61
VAR_SAR
@ VAR_SAR
Definition: vf_scale_npp.c:104
av_buffer_ref
AVBufferRef * av_buffer_ref(const AVBufferRef *buf)
Create a new reference to an AVBuffer.
Definition: buffer.c:103
AVFilter::name
const char * name
Filter name.
Definition: avfilter.h:220
VAR_S2R_MAIN_T
@ VAR_S2R_MAIN_T
Definition: vf_scale_npp.c:114
AVERROR_UNKNOWN
#define AVERROR_UNKNOWN
Unknown error, typically from an external library.
Definition: error.h:73
AVHWFramesContext::width
int width
The allocated dimensions of the frames in this pool.
Definition: hwcontext.h:220
video.h
NPPScaleStageContext::frame
AVFrame * frame
Definition: vf_scale_npp.c:75
VAR_OH
@ VAR_OH
Definition: vf_scale_npp.c:102
dummy
static int dummy
Definition: ffplay.c:3751
NPPScaleContext::size_str
char * size_str
Definition: vf_scale_npp.c:155
AVFrame::data
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition: frame.h:455
formats.h
av_expr_parse
int av_expr_parse(AVExpr **expr, const char *s, const char *const *const_names, const char *const *func1_names, double(*const *funcs1)(void *, double), const char *const *func2_names, double(*const *funcs2)(void *, double, double), int log_offset, void *log_ctx)
Parse an expression.
Definition: eval.c:735
av_pix_fmt_count_planes
int av_pix_fmt_count_planes(enum AVPixelFormat pix_fmt)
Definition: pixdesc.c:3496
IS_SCALE2REF
#define IS_SCALE2REF(ctx)
Definition: vf_scale_npp.c:166
fail
#define fail()
Definition: checkasm.h:224
get_deinterleaved_format
static enum AVPixelFormat get_deinterleaved_format(enum AVPixelFormat fmt)
Definition: vf_scale_npp.c:502
STAGE_RESIZE
@ STAGE_RESIZE
Definition: vf_scale_npp.c:59
NPPScaleContext::tmp_frame
AVFrame * tmp_frame
Definition: vf_scale_npp.c:128
av_pix_fmt_get_chroma_sub_sample
int av_pix_fmt_get_chroma_sub_sample(enum AVPixelFormat pix_fmt, int *h_shift, int *v_shift)
Utility function to access log2_chroma_w log2_chroma_h from the pixel format AVPixFmtDescriptor.
Definition: pixdesc.c:3484
av_opt_set
int av_opt_set(void *obj, const char *name, const char *val, int search_flags)
Definition: opt.c:825
av_reduce
int av_reduce(int *dst_num, int *dst_den, int64_t num, int64_t den, int64_t max)
Reduce a fraction.
Definition: rational.c:35
NPPScaleContext::shift_width
int shift_width
Definition: vf_scale_npp.c:131
av_expr_free
void av_expr_free(AVExpr *e)
Free a parsed expression previously created with av_expr_parse().
Definition: eval.c:368
AVRational::num
int num
Numerator.
Definition: rational.h:59
AV_SIDE_DATA_PROP_SIZE_DEPENDENT
@ AV_SIDE_DATA_PROP_SIZE_DEPENDENT
Side data depends on the video dimensions.
Definition: frame.h:316
AVFilterPad
A filter pad used for either input or output.
Definition: filters.h:40
av_frame_alloc
AVFrame * av_frame_alloc(void)
Allocate an AVFrame and set its fields to default values.
Definition: frame.c:52
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:210
FF_ARRAY_ELEMS
#define FF_ARRAY_ELEMS(a)
Definition: sinewin_tablegen.c:29
av_cold
#define av_cold
Definition: attributes.h:119
VAR_IH
@ VAR_IH
Definition: vf_scale_npp.c:100
AVHWFramesContext::height
int height
Definition: hwcontext.h:220
FFFilter
Definition: filters.h:267
s
#define s(width, name)
Definition: cbs_vp9.c:198
FILTER_OUTPUTS
#define FILTER_OUTPUTS(array)
Definition: filters.h:265
AV_PIX_FMT_YUVA420P
@ AV_PIX_FMT_YUVA420P
planar YUV 4:2:0, 20bpp, (1 Cr & Cb sample per 2x2 Y & A samples)
Definition: pixfmt.h:108
nppscale_uninit
static void nppscale_uninit(AVFilterContext *ctx)
Definition: vf_scale_npp.c:417
ff_filter_link
static FilterLink * ff_filter_link(AVFilterLink *link)
Definition: filters.h:199
av_expr_count_vars
int av_expr_count_vars(AVExpr *e, unsigned *counter, int size)
Track the presence of variables and their number of occurrences in a parsed expression.
Definition: eval.c:814
NPPScaleContext::stages
NPPScaleStageContext stages[STAGE_NB]
Definition: vf_scale_npp.c:127
config_props
static int config_props(AVFilterLink *outlink)
Definition: vf_scale_npp.c:625
NPPScaleContext::eval_mode
int eval_mode
Definition: vf_scale_npp.c:162
nppscale_eval_dimensions
static int nppscale_eval_dimensions(AVFilterContext *ctx)
Definition: vf_scale_npp.c:356
ctx
static AVFormatContext * ctx
Definition: movenc.c:49
av_expr_eval
double av_expr_eval(AVExpr *e, const double *const_values, void *opaque)
Evaluate a previously parsed expression.
Definition: eval.c:824
NPPScaleContext::force_original_aspect_ratio
int force_original_aspect_ratio
Definition: vf_scale_npp.c:149
AVExpr
Definition: eval.c:171
SCALE_FORCE_OAR_INCREASE
@ SCALE_FORCE_OAR_INCREASE
Definition: scale_eval.h:27
AV_PIX_FMT_YUV420P
@ AV_PIX_FMT_YUV420P
planar YUV 4:2:0, 12bpp, (1 Cr & Cb sample per 2x2 Y samples)
Definition: pixfmt.h:73
check_exprs
static int check_exprs(AVFilterContext *ctx)
Definition: vf_scale_npp.c:170
NAN
#define NAN
Definition: mathematics.h:115
nppscale2ref_outputs
static const AVFilterPad nppscale2ref_outputs[]
Definition: vf_scale_npp.c:1051
link
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a link
Definition: filter_design.txt:23
nppscale_scale
static int nppscale_scale(AVFilterLink *link, AVFrame *out, AVFrame *in)
Definition: vf_scale_npp.c:781
request_frame_ref
static int request_frame_ref(AVFilterLink *outlink)
Definition: vf_scale_npp.c:961
NPPScaleContext
Definition: vf_scale_npp.c:124
if
if(ret)
Definition: filter_design.txt:179
FLAGS
#define FLAGS
Definition: vf_scale_npp.c:967
var_names
static const char *const var_names[]
Definition: vf_scale_npp.c:78
init_stage
static int init_stage(NPPScaleStageContext *stage, AVBufferRef *device_ctx)
Definition: vf_scale_npp.c:433
LIBAVUTIL_VERSION_INT
#define LIBAVUTIL_VERSION_INT
Definition: version.h:85
AVClass
Describe the class of an AVClass context structure.
Definition: log.h:76
nppscale_interleave
static int nppscale_interleave(AVFilterContext *ctx, NPPScaleStageContext *stage, AVFrame *out, AVFrame *in)
Definition: vf_scale_npp.c:749
NULL
#define NULL
Definition: coverity.c:32
AVHWFramesContext::sw_format
enum AVPixelFormat sw_format
The pixel format identifying the actual data layout of the hardware frames.
Definition: hwcontext.h:213
av_frame_copy_props
int av_frame_copy_props(AVFrame *dst, const AVFrame *src)
Copy only "metadata" fields from src to dst.
Definition: frame.c:599
av_buffer_unref
void av_buffer_unref(AVBufferRef **buf)
Free a given reference and automatically free the buffer if there are no more references to it.
Definition: buffer.c:139
AVRational
Rational number (pair of numerator and denominator).
Definition: rational.h:58
AVHWFramesContext::device_ref
AVBufferRef * device_ref
A reference to the parent AVHWDeviceContext.
Definition: hwcontext.h:129
isnan
#define isnan(x)
Definition: libm.h:342
SCALE_FORCE_OAR_NB
@ SCALE_FORCE_OAR_NB
Definition: scale_eval.h:28
AVFilterContext::inputs
AVFilterLink ** inputs
array of pointers to input links
Definition: avfilter.h:282
EVAL_MODE_INIT
@ EVAL_MODE_INIT
Definition: vf_scale_npp.c:119
VAR_IW
@ VAR_IW
Definition: vf_scale_npp.c:99
av_default_item_name
const char * av_default_item_name(void *ptr)
Return the context name.
Definition: log.c:242
parseutils.h
options
Definition: swscale.c:45
request_frame
static int request_frame(AVFilterLink *outlink)
Definition: vf_scale_npp.c:956
NPPScaleContext::h_expr
char * h_expr
height expression string
Definition: vf_scale_npp.c:146
double
double
Definition: af_crystalizer.c:132
AV_CLASS_CATEGORY_FILTER
@ AV_CLASS_CATEGORY_FILTER
Definition: log.h:36
nppscale_parse_expr
static int nppscale_parse_expr(AVFilterContext *ctx, char *str_expr, AVExpr **pexpr_ptr, const char *var, const char *args)
Definition: vf_scale_npp.c:223
NPPScaleContext::shift_height
int shift_height
Definition: vf_scale_npp.c:131
NPPScaleStageContext::height
int height
Definition: vf_scale_npp.c:71
TS2T
#define TS2T(ts, tb)
Definition: filters.h:483
VAR_IN_H
@ VAR_IN_H
Definition: vf_scale_npp.c:100
VAR_S2R_MAIN_H
@ VAR_S2R_MAIN_H
Definition: vf_scale_npp.c:109
eval.h
VAR_S2R_MAIN_A
@ VAR_S2R_MAIN_A
Definition: vf_scale_npp.c:110
NULL_IF_CONFIG_SMALL
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification.
Definition: internal.h:94
NPPScaleStageContext::out_fmt
enum AVPixelFormat out_fmt
Definition: vf_scale_npp.c:67
OFFSET
#define OFFSET(x)
Definition: vf_scale_npp.c:966
i
#define i(width, name, range_min, range_max)
Definition: cbs_h264.c:63
NPPScaleStageContext::frames_ctx
AVBufferRef * frames_ctx
Definition: vf_scale_npp.c:74
NPPScaleStageContext::planes_out
struct NPPScaleStageContext::@434 planes_out[4]
AVFrame::time_base
AVRational time_base
Time base for the timestamps in this frame.
Definition: frame.h:551
nppscale_filter_frame_ref
static int nppscale_filter_frame_ref(AVFilterLink *link, AVFrame *in)
Definition: vf_scale_npp.c:925
nppscale_filter_frame
static int nppscale_filter_frame(AVFilterLink *link, AVFrame *in)
Definition: vf_scale_npp.c:880
AVFrame::format
int format
format of the frame, -1 if unknown or unset Values correspond to enum AVPixelFormat for video frames,...
Definition: frame.h:521
VAR_IN_W
@ VAR_IN_W
Definition: vf_scale_npp.c:99
scale_eval.h
init_processing_chain
static int init_processing_chain(AVFilterContext *ctx, int in_width, int in_height, int out_width, int out_height)
Definition: vf_scale_npp.c:516
VARS_NB
@ VARS_NB
Definition: vf_scale_npp.c:115
planes
static const struct @585 planes[]
av_parse_video_size
int av_parse_video_size(int *width_ptr, int *height_ptr, const char *str)
Parse str and put in width_ptr and height_ptr the detected values.
Definition: parseutils.c:150
av_frame_side_data_remove_by_props
void av_frame_side_data_remove_by_props(AVFrameSideData ***sd, int *nb_sd, int props)
Remove and free all side data instances that match any of the given side data properties.
Definition: side_data.c:118
VAR_S2R_MAIN_W
@ VAR_S2R_MAIN_W
Definition: vf_scale_npp.c:108
VAR_OUT_W
@ VAR_OUT_W
Definition: vf_scale_npp.c:101
nppscale_resize
static int nppscale_resize(AVFilterContext *ctx, NPPScaleStageContext *stage, AVFrame *out, AVFrame *in)
Definition: vf_scale_npp.c:721
VAR_S2R_MAIN_DAR
@ VAR_S2R_MAIN_DAR
Definition: vf_scale_npp.c:112
VAR_S2R_MAIN_SAR
@ VAR_S2R_MAIN_SAR
Definition: vf_scale_npp.c:111
NPPScaleContext::h
int h
Definition: vf_scale_npp.c:138
internal.h
EvalMode
EvalMode
Definition: af_volume.h:39
EVAL_MODE_FRAME
@ EVAL_MODE_FRAME
Definition: vf_scale_npp.c:120
av_frame_move_ref
void av_frame_move_ref(AVFrame *dst, AVFrame *src)
Move everything contained in src to dst and reset src.
Definition: frame.c:523
av_frame_unref
void av_frame_unref(AVFrame *frame)
Unreference all the buffers referenced by frame and reset the frame fields.
Definition: frame.c:496
AVFilterPad::name
const char * name
Pad name.
Definition: filters.h:46
NPPScaleContext::w
int w
New dimensions.
Definition: vf_scale_npp.c:138
AVHWFramesContext
This struct describes a set or pool of "hardware" frames (i.e.
Definition: hwcontext.h:118
AVCUDADeviceContext
This struct is allocated as AVHWDeviceContext.hwctx.
Definition: hwcontext_cuda.h:42
SCALE_FORCE_OAR_DISABLE
@ SCALE_FORCE_OAR_DISABLE
Definition: scale_eval.h:25
config_props_ref
static int config_props_ref(AVFilterLink *outlink)
Definition: vf_scale_npp.c:679
ret
ret
Definition: filter_design.txt:187
NPPScaleContext::format
enum AVPixelFormat format
Output sw format.
Definition: vf_scale_npp.c:143
AV_PIX_FMT_NV12
@ AV_PIX_FMT_NV12
planar YUV 4:2:0, 12bpp, 1 plane for Y and 1 plane for the UV components, which are interleaved (firs...
Definition: pixfmt.h:96
FFSWAP
#define FFSWAP(type, a, b)
Definition: macros.h:52
AVClass::class_name
const char * class_name
The name of the class; usually it is the same name as the context structure type to which the AVClass...
Definition: log.h:81
AVHWFramesContext::device_ctx
AVHWDeviceContext * device_ctx
The parent AVHWDeviceContext.
Definition: hwcontext.h:137
cuda_check.h
NPPScaleContext::interp_algo
int interp_algo
Definition: vf_scale_npp.c:153
FILTER_INPUTS
#define FILTER_INPUTS(array)
Definition: filters.h:264
AVFrame::sample_aspect_ratio
AVRational sample_aspect_ratio
Sample aspect ratio for the video frame, 0/1 if unknown/unspecified.
Definition: frame.h:531
NPPScaleContext::w_expr
char * w_expr
width expression string
Definition: vf_scale_npp.c:145
av_get_pix_fmt
enum AVPixelFormat av_get_pix_fmt(const char *name)
Return the pixel format corresponding to name.
Definition: pixdesc.c:3388
NPPScaleStageContext::in_fmt
enum AVPixelFormat in_fmt
Definition: vf_scale_npp.c:66
AVFrame::hw_frames_ctx
AVBufferRef * hw_frames_ctx
For hwaccel-format frames, this should be a reference to the AVHWFramesContext describing the frame.
Definition: frame.h:731
nppscale_init
static av_cold int nppscale_init(AVFilterContext *ctx)
Definition: vf_scale_npp.c:279
ff_vf_scale2ref_npp
const FFFilter ff_vf_scale2ref_npp
Definition: vf_scale_npp.c:165
AVFrame::height
int height
Definition: frame.h:506
EVAL_MODE_NB
@ EVAL_MODE_NB
Definition: vf_scale_npp.c:121
NPPScaleContext::format_str
char * format_str
Definition: vf_scale_npp.c:147
VAR_DAR
@ VAR_DAR
Definition: vf_scale_npp.c:105
STAGE_INTERLEAVE
@ STAGE_INTERLEAVE
Definition: vf_scale_npp.c:60
AVRational::den
int den
Denominator.
Definition: rational.h:60
AV_PIX_FMT_NONE
@ AV_PIX_FMT_NONE
Definition: pixfmt.h:72
AV_OPT_TYPE_INT
@ AV_OPT_TYPE_INT
Underlying C type is int.
Definition: opt.h:259
avfilter.h
nppscale_process
static int(*const nppscale_process[])(AVFilterContext *ctx, NPPScaleStageContext *stage, AVFrame *out, AVFrame *in)
Definition: vf_scale_npp.c:774
nppscale_outputs
static const AVFilterPad nppscale_outputs[]
Definition: vf_scale_npp.c:1011
NPPScaleContext::force_divisible_by
int force_divisible_by
Definition: vf_scale_npp.c:150
av_mul_q
AVRational av_mul_q(AVRational b, AVRational c)
Multiply two rationals.
Definition: rational.c:80
NPPScaleStageContext::width
int width
Definition: vf_scale_npp.c:70
AV_PIX_FMT_YUV444P
@ AV_PIX_FMT_YUV444P
planar YUV 4:4:4, 24bpp, (1 Cr & Cb sample per 1x1 Y samples)
Definition: pixfmt.h:78
VAR_S2R_MDAR
@ VAR_S2R_MDAR
Definition: vf_scale_npp.c:112
NPPScaleStageContext
Definition: vf_scale_npp.c:64
AVFilterContext
An instance of a filter.
Definition: avfilter.h:274
STAGE_DEINTERLEAVE
@ STAGE_DEINTERLEAVE
Definition: vf_scale_npp.c:58
VAR_T
@ VAR_T
Definition: vf_scale_npp.c:107
desc
const char * desc
Definition: libsvtav1.c:83
AVMEDIA_TYPE_VIDEO
@ AVMEDIA_TYPE_VIDEO
Definition: avutil.h:200
FFFilter::p
AVFilter p
The public AVFilter.
Definition: filters.h:271
mem.h
AVBufferRef
A reference to a data buffer.
Definition: buffer.h:82
options
static const AVOption options[]
Definition: vf_scale_npp.c:968
av_strdup
#define av_strdup(s)
Definition: ops_asmgen.c:47
nppscale_deinterleave
static int nppscale_deinterleave(AVFilterContext *ctx, NPPScaleStageContext *stage, AVFrame *out, AVFrame *in)
Definition: vf_scale_npp.c:697
VAR_OUT_H
@ VAR_OUT_H
Definition: vf_scale_npp.c:102
AVPixFmtDescriptor
Descriptor that unambiguously describes how the bits of a pixel are stored in the up to 4 data planes...
Definition: pixdesc.h:69
av_free
#define av_free(p)
Definition: tableprint_vlc.h:34
scale
static void scale(int *out, const int *in, const int w, const int h, const int shift)
Definition: intra.c:278
FFALIGN
#define FFALIGN(x, a)
Definition: macros.h:78
AV_OPT_TYPE_BOOL
@ AV_OPT_TYPE_BOOL
Underlying C type is int.
Definition: opt.h:327
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:35
deinterleaved_formats
static enum AVPixelFormat deinterleaved_formats[][2]
Definition: vf_scale_npp.c:53
NPPScaleContext::reset_sar
int reset_sar
Definition: vf_scale_npp.c:151
hwcontext.h
AVERROR_BUG
#define AVERROR_BUG
Internal bug, also see AVERROR_BUG2.
Definition: error.h:52
AVFrame::linesize
int linesize[AV_NUM_DATA_POINTERS]
For video, a positive or negative value, which is typically indicating the size in bytes of each pict...
Definition: frame.h:479
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:27
NPPScaleContext::var_values
double var_values[VARS_NB]
Definition: vf_scale_npp.c:160
AV_OPT_TYPE_STRING
@ AV_OPT_TYPE_STRING
Underlying C type is a uint8_t* that is either NULL or points to a C string allocated with the av_mal...
Definition: opt.h:276
av_hwframe_get_buffer
int av_hwframe_get_buffer(AVBufferRef *hwframe_ref, AVFrame *frame, int flags)
Allocate a new frame attached to the given AVHWFramesContext.
Definition: hwcontext.c:506
AV_OPT_TYPE_CONST
@ AV_OPT_TYPE_CONST
Special option type for declaring named constants.
Definition: opt.h:299
snprintf
#define snprintf
Definition: snprintf.h:34
NPPScaleContext::w_pexpr
AVExpr * w_pexpr
Definition: vf_scale_npp.c:157
ff_scale_adjust_dimensions
int ff_scale_adjust_dimensions(AVFilterLink *inlink, int *ret_w, int *ret_h, int force_original_aspect_ratio, int force_divisible_by, double w_adj)
Transform evaluated width and height obtained from ff_scale_eval_dimensions into actual target width ...
Definition: scale_eval.c:123
src
#define src
Definition: vp8dsp.c:248
av_get_pix_fmt_name
const char * av_get_pix_fmt_name(enum AVPixelFormat pix_fmt)
Return the short name for a pixel format, NULL in case pix_fmt is unknown.
Definition: pixdesc.c:3376
VAR_N
@ VAR_N
Definition: vf_scale_npp.c:106