FFmpeg  4.2.3
vf_scale_vaapi.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 #include <string.h>
20 
21 #include "libavutil/avassert.h"
22 #include "libavutil/mem.h"
23 #include "libavutil/opt.h"
24 #include "libavutil/pixdesc.h"
25 
26 #include "avfilter.h"
27 #include "formats.h"
28 #include "internal.h"
29 #include "scale.h"
30 #include "video.h"
31 #include "vaapi_vpp.h"
32 
33 typedef struct ScaleVAAPIContext {
34  VAAPIVPPContext vpp_ctx; // must be the first field
35 
37 
38  int mode;
39 
40  char *w_expr; // width expression string
41  char *h_expr; // height expression string
42 
48 
54 
55 static const char *scale_vaapi_mode_name(int mode)
56 {
57  switch (mode) {
58 #define D(name) case VA_FILTER_SCALING_ ## name: return #name
59  D(DEFAULT);
60  D(FAST);
61  D(HQ);
62  D(NL_ANAMORPHIC);
63 #undef D
64  default:
65  return "Invalid";
66  }
67 }
68 
69 
71 {
72  AVFilterLink *inlink = outlink->src->inputs[0];
73  AVFilterContext *avctx = outlink->src;
74  VAAPIVPPContext *vpp_ctx = avctx->priv;
75  ScaleVAAPIContext *ctx = avctx->priv;
76  int err;
77 
78  if ((err = ff_scale_eval_dimensions(ctx,
79  ctx->w_expr, ctx->h_expr,
80  inlink, outlink,
81  &vpp_ctx->output_width, &vpp_ctx->output_height)) < 0)
82  return err;
83 
84  err = ff_vaapi_vpp_config_output(outlink);
85  if (err < 0)
86  return err;
87 
88  if (inlink->sample_aspect_ratio.num)
89  outlink->sample_aspect_ratio = av_mul_q((AVRational){outlink->h * inlink->w, outlink->w * inlink->h}, inlink->sample_aspect_ratio);
90  else
91  outlink->sample_aspect_ratio = inlink->sample_aspect_ratio;
92 
93  return 0;
94 }
95 
96 static int scale_vaapi_filter_frame(AVFilterLink *inlink, AVFrame *input_frame)
97 {
98  AVFilterContext *avctx = inlink->dst;
99  AVFilterLink *outlink = avctx->outputs[0];
100  VAAPIVPPContext *vpp_ctx = avctx->priv;
101  ScaleVAAPIContext *ctx = avctx->priv;
103  VAProcPipelineParameterBuffer params;
104  int err;
105 
106  av_log(avctx, AV_LOG_DEBUG, "Filter input: %s, %ux%u (%"PRId64").\n",
107  av_get_pix_fmt_name(input_frame->format),
108  input_frame->width, input_frame->height, input_frame->pts);
109 
110  if (vpp_ctx->va_context == VA_INVALID_ID)
111  return AVERROR(EINVAL);
112 
113  output_frame = ff_get_video_buffer(outlink, vpp_ctx->output_width,
114  vpp_ctx->output_height);
115  if (!output_frame) {
116  err = AVERROR(ENOMEM);
117  goto fail;
118  }
119 
120  err = av_frame_copy_props(output_frame, input_frame);
121  if (err < 0)
122  return err;
123 
125  output_frame->color_primaries = ctx->colour_primaries;
127  output_frame->color_trc = ctx->colour_transfer;
129  output_frame->colorspace = ctx->colour_matrix;
131  output_frame->color_range = ctx->colour_range;
133  output_frame->chroma_location = ctx->chroma_location;
134 
135  err = ff_vaapi_vpp_init_params(avctx, &params,
136  input_frame, output_frame);
137  if (err < 0)
138  goto fail;
139 
140  params.filter_flags |= ctx->mode;
141 
142  err = ff_vaapi_vpp_render_picture(avctx, &params, output_frame);
143  if (err < 0)
144  goto fail;
145 
146  av_frame_free(&input_frame);
147 
148  av_log(avctx, AV_LOG_DEBUG, "Filter output: %s, %ux%u (%"PRId64"), mode: %s.\n",
149  av_get_pix_fmt_name(output_frame->format),
150  output_frame->width, output_frame->height, output_frame->pts,
152 
153  return ff_filter_frame(outlink, output_frame);
154 
155 fail:
156  av_frame_free(&input_frame);
157  av_frame_free(&output_frame);
158  return err;
159 }
160 
162 {
163  VAAPIVPPContext *vpp_ctx = avctx->priv;
164  ScaleVAAPIContext *ctx = avctx->priv;
165 
166  ff_vaapi_vpp_ctx_init(avctx);
168 
169  if (ctx->output_format_string) {
171  if (vpp_ctx->output_format == AV_PIX_FMT_NONE) {
172  av_log(avctx, AV_LOG_ERROR, "Invalid output format.\n");
173  return AVERROR(EINVAL);
174  }
175  } else {
176  // Use the input format once that is configured.
177  vpp_ctx->output_format = AV_PIX_FMT_NONE;
178  }
179 
180 #define STRING_OPTION(var_name, func_name, default_value) do { \
181  if (ctx->var_name ## _string) { \
182  int var = av_ ## func_name ## _from_name(ctx->var_name ## _string); \
183  if (var < 0) { \
184  av_log(avctx, AV_LOG_ERROR, "Invalid %s.\n", #var_name); \
185  return AVERROR(EINVAL); \
186  } \
187  ctx->var_name = var; \
188  } else { \
189  ctx->var_name = default_value; \
190  } \
191  } while (0)
192 
197 
198  return 0;
199 }
200 
201 #define OFFSET(x) offsetof(ScaleVAAPIContext, x)
202 #define FLAGS (AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM)
203 static const AVOption scale_vaapi_options[] = {
204  { "w", "Output video width",
205  OFFSET(w_expr), AV_OPT_TYPE_STRING, {.str = "iw"}, .flags = FLAGS },
206  { "h", "Output video height",
207  OFFSET(h_expr), AV_OPT_TYPE_STRING, {.str = "ih"}, .flags = FLAGS },
208  { "format", "Output video format (software format of hardware frames)",
210  { "mode", "Scaling mode",
211  OFFSET(mode), AV_OPT_TYPE_INT, { .i64 = VA_FILTER_SCALING_HQ },
212  0, VA_FILTER_SCALING_NL_ANAMORPHIC, FLAGS, "mode" },
213  { "default", "Use the default (depend on the driver) scaling algorithm",
214  0, AV_OPT_TYPE_CONST, { .i64 = VA_FILTER_SCALING_DEFAULT }, 0, 0, FLAGS, "mode" },
215  { "fast", "Use fast scaling algorithm",
216  0, AV_OPT_TYPE_CONST, { .i64 = VA_FILTER_SCALING_FAST }, 0, 0, FLAGS, "mode" },
217  { "hq", "Use high quality scaling algorithm",
218  0, AV_OPT_TYPE_CONST, { .i64 = VA_FILTER_SCALING_HQ }, 0, 0, FLAGS, "mode" },
219  { "nl_anamorphic", "Use nolinear anamorphic scaling algorithm",
220  0, AV_OPT_TYPE_CONST, { .i64 = VA_FILTER_SCALING_NL_ANAMORPHIC }, 0, 0, FLAGS, "mode" },
221 
222  // These colour properties match the ones of the same name in vf_scale.
223  { "out_color_matrix", "Output colour matrix coefficient set",
224  OFFSET(colour_matrix_string), AV_OPT_TYPE_STRING, { .str = NULL }, .flags = FLAGS },
225  { "out_range", "Output colour range",
228  { "full", "Full range",
229  0, AV_OPT_TYPE_CONST, { .i64 = AVCOL_RANGE_JPEG }, 0, 0, FLAGS, "range" },
230  { "limited", "Limited range",
231  0, AV_OPT_TYPE_CONST, { .i64 = AVCOL_RANGE_MPEG }, 0, 0, FLAGS, "range" },
232  { "jpeg", "Full range",
233  0, AV_OPT_TYPE_CONST, { .i64 = AVCOL_RANGE_JPEG }, 0, 0, FLAGS, "range" },
234  { "mpeg", "Limited range",
235  0, AV_OPT_TYPE_CONST, { .i64 = AVCOL_RANGE_MPEG }, 0, 0, FLAGS, "range" },
236  { "tv", "Limited range",
237  0, AV_OPT_TYPE_CONST, { .i64 = AVCOL_RANGE_MPEG }, 0, 0, FLAGS, "range" },
238  { "pc", "Full range",
239  0, AV_OPT_TYPE_CONST, { .i64 = AVCOL_RANGE_JPEG }, 0, 0, FLAGS, "range" },
240  // These colour properties are new here.
241  { "out_color_primaries", "Output colour primaries",
243  { .str = NULL }, .flags = FLAGS },
244  { "out_color_transfer", "Output colour transfer characteristics",
246  { .str = NULL }, .flags = FLAGS },
247  { "out_chroma_location", "Output chroma sample location",
249  { .str = NULL }, .flags = FLAGS },
250 
251  { NULL },
252 };
253 
254 AVFILTER_DEFINE_CLASS(scale_vaapi);
255 
256 static const AVFilterPad scale_vaapi_inputs[] = {
257  {
258  .name = "default",
259  .type = AVMEDIA_TYPE_VIDEO,
260  .filter_frame = &scale_vaapi_filter_frame,
261  .config_props = &ff_vaapi_vpp_config_input,
262  },
263  { NULL }
264 };
265 
267  {
268  .name = "default",
269  .type = AVMEDIA_TYPE_VIDEO,
270  .config_props = &scale_vaapi_config_output,
271  },
272  { NULL }
273 };
274 
276  .name = "scale_vaapi",
277  .description = NULL_IF_CONFIG_SMALL("Scale to/from VAAPI surfaces."),
278  .priv_size = sizeof(ScaleVAAPIContext),
282  .inputs = scale_vaapi_inputs,
283  .outputs = scale_vaapi_outputs,
284  .priv_class = &scale_vaapi_class,
285  .flags_internal = FF_FILTER_FLAG_HWFRAME_AWARE,
286 };
#define NULL
Definition: coverity.c:32
#define FF_FILTER_FLAG_HWFRAME_AWARE
The filter is aware of hardware frames, and any hardware frame context should not be automatically pr...
Definition: internal.h:385
int ff_scale_eval_dimensions(void *log_ctx, const char *w_expr, const char *h_expr, AVFilterLink *inlink, AVFilterLink *outlink, int *ret_w, int *ret_h)
Definition: scale.c:106
This structure describes decoded (raw) audio or video data.
Definition: frame.h:295
char * output_format_string
int ff_vaapi_vpp_config_input(AVFilterLink *inlink)
Definition: vaapi_vpp.c:70
AVOption.
Definition: opt.h:246
Main libavfilter public API header.
Memory handling functions.
int ff_vaapi_vpp_config_output(AVFilterLink *outlink)
Definition: vaapi_vpp.c:95
static av_cold int init(AVCodecContext *avctx)
Definition: avrndec.c:35
int num
Numerator.
Definition: rational.h:59
AVFILTER_DEFINE_CLASS(scale_vaapi)
AVFrame * ff_get_video_buffer(AVFilterLink *link, int w, int h)
Request a picture buffer with a specific set of permissions.
Definition: video.c:99
AVColorTransferCharacteristic
Color Transfer Characteristic.
Definition: pixfmt.h:467
const char * name
Pad name.
Definition: internal.h:60
AVFilterLink ** inputs
array of pointers to input links
Definition: avfilter.h:346
int ff_filter_frame(AVFilterLink *link, AVFrame *frame)
Send a frame of data to the next filter.
Definition: avfilter.c:1080
#define DEFAULT
Definition: avdct.c:28
#define av_cold
Definition: attributes.h:82
VAAPIVPPContext vpp_ctx
static av_cold int uninit(AVCodecContext *avctx)
Definition: crystalhd.c:279
AVFilter ff_vf_scale_vaapi
AVOptions.
AVColorSpace
YUV colorspace type.
Definition: pixfmt.h:496
int64_t pts
Presentation timestamp in time_base units (time when frame should be shown to user).
Definition: frame.h:388
AVColorPrimaries
Chromaticity coordinates of the source primaries.
Definition: pixfmt.h:443
#define av_log(a,...)
static const AVOption scale_vaapi_options[]
A filter pad used for either input or output.
Definition: internal.h:54
static av_cold int scale_vaapi_init(AVFilterContext *avctx)
int width
Definition: frame.h:353
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:176
#define AVERROR(e)
Definition: error.h:43
char * colour_primaries_string
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition: frame.c:202
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification. ...
Definition: internal.h:186
static int scale_vaapi_config_output(AVFilterLink *outlink)
void * priv
private data for use by the filter
Definition: avfilter.h:353
enum AVColorRange color_range
MPEG vs JPEG YUV range.
Definition: frame.h:539
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:197
enum AVColorSpace colorspace
YUV colorspace type.
Definition: frame.h:550
simple assert() macros that are a bit more flexible than ISO C assert().
char * colour_transfer_string
static const AVFilterPad scale_vaapi_inputs[]
#define fail()
Definition: checkasm.h:120
static const char * scale_vaapi_mode_name(int mode)
char * chroma_location_string
void ff_vaapi_vpp_pipeline_uninit(AVFilterContext *avctx)
Definition: vaapi_vpp.c:44
enum AVColorPrimaries colour_primaries
static const struct ColorPrimaries color_primaries[AVCOL_PRI_NB]
AVFormatContext * ctx
Definition: movenc.c:48
enum AVChromaLocation chroma_location
char * colour_matrix_string
static const AVFilterPad inputs[]
Definition: af_acontrast.c:193
static const AVFilterPad outputs[]
Definition: af_acontrast.c:203
the normal 2^n-1 "JPEG" YUV ranges
Definition: pixfmt.h:522
int format
format of the frame, -1 if unknown or unset Values correspond to enum AVPixelFormat for video frames...
Definition: frame.h:368
enum AVColorTransferCharacteristic colour_transfer
#define FLAGS
#define STRING_OPTION(var_name, func_name, default_value)
static int output_frame(H264Context *h, AVFrame *dst, H264Picture *srcp)
Definition: h264dec.c:837
Filter definition.
Definition: avfilter.h:144
Rational number (pair of numerator and denominator).
Definition: rational.h:58
static const AVFilterPad scale_vaapi_outputs[]
const char * name
Filter name.
Definition: avfilter.h:148
enum AVChromaLocation chroma_location
Definition: frame.h:552
#define D(name)
AVFilterLink ** outputs
array of pointers to output links
Definition: avfilter.h:350
VAContextID va_context
Definition: vaapi_vpp.h:41
enum AVPixelFormat output_format
Definition: vaapi_vpp.h:47
int ff_vaapi_vpp_render_picture(AVFilterContext *avctx, VAProcPipelineParameterBuffer *params, AVFrame *output_frame)
Definition: vaapi_vpp.c:592
the normal 219*2^(n-8) "MPEG" YUV ranges
Definition: pixfmt.h:521
const char const char * params
Definition: avisynth_c.h:867
int ff_vaapi_vpp_query_formats(AVFilterContext *avctx)
Definition: vaapi_vpp.c:27
static int query_formats(AVFilterContext *ctx)
Definition: aeval.c:244
void ff_vaapi_vpp_ctx_init(AVFilterContext *avctx)
Definition: vaapi_vpp.c:666
#define OFFSET(x)
enum AVColorPrimaries color_primaries
Definition: frame.h:541
An instance of a filter.
Definition: avfilter.h:338
AVRational av_mul_q(AVRational b, AVRational c)
Multiply two rationals.
Definition: rational.c:80
enum AVColorSpace colour_matrix
int height
Definition: frame.h:353
AVChromaLocation
Location of chroma samples.
Definition: pixfmt.h:541
enum AVColorTransferCharacteristic color_trc
Definition: frame.h:543
int ff_vaapi_vpp_init_params(AVFilterContext *avctx, VAProcPipelineParameterBuffer *params, const AVFrame *input_frame, AVFrame *output_frame)
Definition: vaapi_vpp.c:515
enum AVPixelFormat av_get_pix_fmt(const char *name)
Return the pixel format corresponding to name.
Definition: pixdesc.c:2450
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:2438
internal API functions
static int scale_vaapi_filter_frame(AVFilterLink *inlink, AVFrame *input_frame)
mode
Use these values in ebur128_init (or&#39;ed).
Definition: ebur128.h:83
void(* pipeline_uninit)(AVFilterContext *avctx)
Definition: vaapi_vpp.h:56
void ff_vaapi_vpp_ctx_uninit(AVFilterContext *avctx)
Definition: vaapi_vpp.c:680
int av_frame_copy_props(AVFrame *dst, const AVFrame *src)
Copy only "metadata" fields from src to dst.
Definition: frame.c:654