FFmpeg
Loading...
Searching...
No Matches
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"
31#include "libavutil/internal.h"
32#include "libavutil/mem.h"
33#include "libavutil/opt.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
52
56
63
77
78static 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
117
123
124typedef 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
148
152
154
155 char* size_str;
156
159
161
164
166#define IS_SCALE2REF(ctx) ((ctx)->filter == &ff_vf_scale2ref_npp.p)
167
168static 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
223static 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
266revert:
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 ?
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
411fail:
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
433static 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
484 stage->frames_ctx = out_ref;
485
486 return 0;
487fail:
488 av_buffer_unref(&out_ref);
489 return ret;
490}
491
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
516static 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
625static int config_props(AVFilterLink *outlink)
626{
627 AVFilterContext *ctx = outlink->src;
628 AVFilterLink *inlink0 = outlink->src->inputs[0];
629 AVFilterLink *inlink = IS_SCALE2REF(ctx) ?
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
643 ret = ff_scale_adjust_dimensions(inlink, &s->w, &s->h,
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
675fail:
676 return ret;
677}
678
679static int config_props_ref(AVFilterLink *outlink)
680{
681 FilterLink *outl = ff_filter_link(outlink);
682 AVFilterLink *inlink = outlink->src->inputs[1];
683 FilterLink *inl = ff_filter_link(inlink);
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{
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
780
782{
783 FilterLink *inl = ff_filter_link(link);
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
843scale:
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
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);
919fail:
920 av_frame_free(&in);
922 return ret;
923}
924
926{
927 FilterLink *inl = ff_filter_link(link);
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
956static int request_frame(AVFilterLink *outlink)
957{
958 return ff_request_frame(outlink->src->inputs[0]);
959}
960
961static 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)
968static 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
995static 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
1004 {
1005 .name = "default",
1006 .type = AVMEDIA_TYPE_VIDEO,
1007 .filter_frame = nppscale_filter_frame,
1008 }
1009};
1010
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};
@ VAR_T
Definition aeval.c:53
static int request_frame(AVFilterLink *outlink)
Definition af_aecho.c:272
EvalMode
Definition af_volume.h:39
@ EVAL_MODE_NB
Definition af_volume.h:42
@ EVAL_MODE_FRAME
Definition af_volume.h:41
int ff_filter_frame(AVFilterLink *link, AVFrame *frame)
Send a frame of data to the next filter.
Definition avfilter.c:1068
int ff_request_frame(AVFilterLink *link)
Request an input frame from the filter at the other end of the link.
Definition avfilter.c:483
Main libavfilter public API header.
@ VARS_NB
Definition boxblur.c:43
#define i(width, name, range_min, range_max)
Definition cbs_h264.c:63
#define s(width, name)
Definition cbs_vp9.c:198
#define FLAGS
Definition cmdutils.c:598
#define NULL
Definition coverity.c:32
long long int64_t
Definition coverity.c:34
void av_expr_free(AVExpr *e)
Free a parsed expression previously created with av_expr_parse().
Definition eval.c:368
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
double av_expr_eval(AVExpr *e, const double *const_values, void *opaque)
Evaluate a previously parsed expression.
Definition eval.c:824
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
simple arithmetic expression evaluator
@ VAR_IW
Definition f_select.c:147
@ VAR_IH
Definition f_select.c:146
static int dummy
Definition ffplay.c:3754
#define fail
Definition test.h:479
@ AV_OPT_TYPE_CONST
Special option type for declaring named constants.
Definition opt.h:298
@ AV_OPT_TYPE_INT
Underlying C type is int.
Definition opt.h:258
@ AV_OPT_TYPE_BOOL
Underlying C type is int.
Definition opt.h:326
@ 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:275
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
AVBufferRef * av_buffer_ref(const AVBufferRef *buf)
Create a new reference to an AVBuffer.
Definition buffer.c:103
#define AVERROR_UNKNOWN
Unknown error, typically from an external library.
Definition error.h:73
#define AVERROR_BUG
Internal bug, also see AVERROR_BUG2.
Definition error.h:52
#define AVERROR(e)
Definition error.h:45
void av_frame_unref(AVFrame *frame)
Unreference all the buffers referenced by frame and reset the frame fields.
Definition frame.c:496
void av_frame_move_ref(AVFrame *dst, AVFrame *src)
Move everything contained in src to dst and reset src.
Definition frame.c:523
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:123
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition frame.c:64
int av_frame_copy_props(AVFrame *dst, const AVFrame *src)
Copy only "metadata" fields from src to dst.
Definition frame.c:599
AVFrame * av_frame_alloc(void)
Allocate an AVFrame and set its fields to default values.
Definition frame.c:52
@ AV_SIDE_DATA_PROP_SIZE_DEPENDENT
Side data depends on the video dimensions.
Definition frame.h:354
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition log.h:216
#define AV_LOG_VERBOSE
Detailed information.
Definition log.h:226
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition log.h:210
const char * av_default_item_name(void *ptr)
Return the context name.
Definition log.c:241
AVRational av_mul_q(AVRational b, AVRational c)
Multiply two rationals.
Definition rational.c:80
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
@ AVMEDIA_TYPE_VIDEO
Definition avutil.h:200
#define LIBAVUTIL_VERSION_INT
Definition version.h:85
int av_opt_set(void *obj, const char *name, const char *val, int search_flags)
Definition opt.c:887
int av_hwframe_ctx_init(AVBufferRef *ref)
Finalize the context before use.
Definition hwcontext.c:337
AVBufferRef * av_hwframe_ctx_alloc(AVBufferRef *device_ref_in)
Allocate an AVHWFramesContext tied to a given device context.
Definition hwcontext.c:263
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
FFmpeg internal API for CUDA.
static void scale(int *out, const int *in, const int w, const int h, const int shift)
Definition intra.c:278
#define FILTER_INPUTS(array)
Definition filters.h:264
#define FILTER_OUTPUTS(array)
Definition filters.h:265
#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
#define TS2T(ts, tb)
Definition filters.h:483
static FilterLink * ff_filter_link(AVFilterLink *link)
Definition filters.h:199
#define FILTER_SINGLE_PIXFMT(pix_fmt_)
Definition filters.h:254
#define av_cold
Definition attributes.h:117
common internal API header
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification.
Definition internal.h:88
#define isnan(x)
Definition libm.h:342
const char * desc
Definition libsvtav1.c:83
static const struct @257111027162314367033347246032313251342043035002 planes[]
@ AV_CLASS_CATEGORY_FILTER
Definition log.h:36
#define FFSWAP(type, a, b)
Definition macros.h:52
#define FFALIGN(x, a)
Definition macros.h:78
#define NAN
Memory handling functions.
var_name
Definition noise.c:46
@ VAR_N
Definition noise.c:47
static const char *const var_names[]
Definition noise.c:30
#define av_strdup(s)
Definition ops_static.c:55
AVOptions.
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
misc parsing utilities
int av_pix_fmt_count_planes(enum AVPixelFormat pix_fmt)
Definition pixdesc.c:3500
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:3488
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:3380
enum AVPixelFormat av_get_pix_fmt(const char *name)
Return the pixel format corresponding to name.
Definition pixdesc.c:3392
const AVPixFmtDescriptor * av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt)
Definition pixdesc.c:3460
AVPixelFormat
Pixel format.
Definition pixfmt.h:71
@ 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
@ AV_PIX_FMT_NONE
Definition pixfmt.h:72
@ AV_PIX_FMT_YUV420P
planar YUV 4:2:0, 12bpp, (1 Cr & Cb sample per 2x2 Y samples)
Definition pixfmt.h:73
@ AV_PIX_FMT_YUVA420P
planar YUV 4:2:0, 20bpp, (1 Cr & Cb sample per 2x2 Y & A samples)
Definition pixfmt.h:108
@ AV_PIX_FMT_CUDA
HW acceleration through CUDA.
Definition pixfmt.h:260
@ AV_PIX_FMT_YUV444P
planar YUV 4:4:4, 24bpp, (1 Cr & Cb sample per 1x1 Y samples)
Definition pixfmt.h:78
@ VAR_OUT_H
Definition scale_eval.c:47
@ VAR_SAR
Definition scale_eval.c:49
@ VAR_OH
Definition scale_eval.c:47
@ VAR_IN_W
Definition scale_eval.c:44
@ VAR_OW
Definition scale_eval.c:46
@ VAR_A
Definition scale_eval.c:48
@ VAR_OUT_W
Definition scale_eval.c:46
@ VAR_IN_H
Definition scale_eval.c:45
@ VAR_DAR
Definition scale_eval.c:50
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
@ SCALE_FORCE_OAR_DISABLE
Definition scale_eval.h:25
@ SCALE_FORCE_OAR_NB
Definition scale_eval.h:28
@ SCALE_FORCE_OAR_INCREASE
Definition scale_eval.h:27
@ SCALE_FORCE_OAR_DECREASE
Definition scale_eval.h:26
#define FF_ARRAY_ELEMS(a)
#define snprintf
Definition snprintf.h:34
static int config_props(AVBitStreamFilterLink *link)
Definition source.c:181
A reference to a data buffer.
Definition buffer.h:82
uint8_t * data
The data buffer.
Definition buffer.h:90
This struct is allocated as AVHWDeviceContext.hwctx.
AVCUDADeviceContextInternal * internal
Describe the class of an AVClass context structure.
Definition log.h:76
Definition eval.c:171
An instance of a filter.
Definition avfilter.h:273
AVFilterLink ** inputs
array of pointers to input links
Definition avfilter.h:281
void * priv
private data for use by the filter
Definition avfilter.h:288
AVFilterLink ** outputs
array of pointers to output links
Definition avfilter.h:285
A filter pad used for either input or output.
Definition filters.h:40
This structure describes decoded (raw) audio or video data.
Definition frame.h:472
int64_t pts
Presentation timestamp in time_base units (time when frame should be shown to user).
Definition frame.h:574
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition frame.h:493
int width
Definition frame.h:544
AVBufferRef * hw_frames_ctx
For hwaccel-format frames, this should be a reference to the AVHWFramesContext describing the frame.
Definition frame.h:769
int height
Definition frame.h:544
AVRational sample_aspect_ratio
Sample aspect ratio for the video frame, 0/1 if unknown/unspecified.
Definition frame.h:569
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:517
int format
format of the frame, -1 if unknown or unset Values correspond to enum AVPixelFormat for video frames,...
Definition frame.h:559
void * hwctx
The format-specific data, allocated and freed by libavutil along with this context.
Definition hwcontext.h:88
This struct describes a set or pool of "hardware" frames (i.e.
Definition hwcontext.h:118
enum AVPixelFormat format
The pixel format identifying the underlying HW surface type.
Definition hwcontext.h:200
AVBufferRef * device_ref
A reference to the parent AVHWDeviceContext.
Definition hwcontext.h:129
enum AVPixelFormat sw_format
The pixel format identifying the actual data layout of the hardware frames.
Definition hwcontext.h:213
int width
The allocated dimensions of the frames in this pool.
Definition hwcontext.h:220
AVHWDeviceContext * device_ctx
The parent AVHWDeviceContext.
Definition hwcontext.h:137
AVOption.
Definition opt.h:428
Descriptor that unambiguously describes how the bits of a pixel are stored in the up to 4 data planes...
Definition pixdesc.h:69
Rational number (pair of numerator and denominator).
Definition rational.h:58
int num
Numerator.
Definition rational.h:59
int den
Denominator.
Definition rational.h:60
int force_original_aspect_ratio
double var_values[VARS_NB]
NPPScaleStageContext stages[STAGE_NB]
char * w_expr
width expression string
AVFrame * tmp_frame
enum AVPixelFormat format
Output sw format.
int w
New dimensions.
char * h_expr
height expression string
enum AVPixelFormat in_fmt
AVBufferRef * frames_ctx
enum AVPixelFormat out_fmt
struct NPPScaleStageContext::@344171316067121270005364033201134017260314124266 planes_out[4]
struct NPPScaleStageContext::@344171316067121270005364033201134017260314124266 planes_in[4]
#define av_free(p)
#define av_freep(p)
#define av_log(a,...)
#define src
Definition vp8dsp.c:248
static FILE * out
Definition movenc.c:55
static AVFormatContext * ctx
Definition movenc.c:49
static enum AVPixelFormat supported_formats[]
@ EVAL_MODE_INIT
Definition vf_fftfilt.c:41
@ VAR_S2R_MAIN_SAR
Definition vf_scale.c:111
@ VAR_S2R_MAIN_H
Definition vf_scale.c:109
@ VAR_S2R_MAIN_W
Definition vf_scale.c:108
@ VAR_S2R_MAIN_N
Definition vf_scale.c:115
@ VAR_S2R_MAIN_DAR
Definition vf_scale.c:112
@ VAR_S2R_MAIN_T
Definition vf_scale.c:116
@ VAR_S2R_MAIN_A
Definition vf_scale.c:110
@ VAR_S2R_MDAR
Definition vf_scale.c:112
static int request_frame_ref(AVFilterLink *outlink)
Definition vf_scale.c:738
static int config_props_ref(AVFilterLink *outlink)
Definition vf_scale.c:716
#define IS_SCALE2REF(ctx)
Definition vf_scale.c:180
@ VARS_NB
static const AVFilterPad nppscale2ref_inputs[]
static int config_props(AVFilterLink *outlink)
static int request_frame_ref(AVFilterLink *outlink)
static enum AVPixelFormat deinterleaved_formats[][2]
const FFFilter ff_vf_scale2ref_npp
static int init_stage(NPPScaleStageContext *stage, AVBufferRef *device_ctx)
static int nppscale_scale(AVFilterLink *link, AVFrame *out, AVFrame *in)
static const AVFilterPad nppscale_inputs[]
static const AVClass nppscale_class
static int request_frame(AVFilterLink *outlink)
const FFFilter ff_vf_scale_npp
static int config_props_ref(AVFilterLink *outlink)
static int nppscale_filter_frame(AVFilterLink *link, AVFrame *in)
ScaleStage
@ STAGE_RESIZE
@ STAGE_NB
@ STAGE_DEINTERLEAVE
@ STAGE_INTERLEAVE
static enum AVPixelFormat get_deinterleaved_format(enum AVPixelFormat fmt)
static void nppscale_uninit(AVFilterContext *ctx)
static int nppscale_resize(AVFilterContext *ctx, NPPScaleStageContext *stage, AVFrame *out, AVFrame *in)
static const AVFilterPad nppscale2ref_outputs[]
static av_cold int nppscale_init(AVFilterContext *ctx)
static int format_is_supported(enum AVPixelFormat fmt)
#define CHECK_CU(x)
static int nppscale_parse_expr(AVFilterContext *ctx, char *str_expr, AVExpr **pexpr_ptr, const char *var, const char *args)
static const AVFilterPad nppscale_outputs[]
static int check_exprs(AVFilterContext *ctx)
#define IS_SCALE2REF(ctx)
#define OFFSET(x)
static int nppscale_filter_frame_ref(AVFilterLink *link, AVFrame *in)
static int nppscale_interleave(AVFilterContext *ctx, NPPScaleStageContext *stage, AVFrame *out, AVFrame *in)
static int nppscale_eval_dimensions(AVFilterContext *ctx)
static int(*const nppscale_process[])(AVFilterContext *ctx, NPPScaleStageContext *stage, AVFrame *out, AVFrame *in)
static int init_processing_chain(AVFilterContext *ctx, int in_width, int in_height, int out_width, int out_height)
static int nppscale_deinterleave(AVFilterContext *ctx, NPPScaleStageContext *stage, AVFrame *out, AVFrame *in)