FFmpeg  4.0
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  char *w_expr; // width expression string
39  char *h_expr; // height expression string
41 
43 {
44  AVFilterLink *inlink = outlink->src->inputs[0];
45  AVFilterContext *avctx = outlink->src;
46  VAAPIVPPContext *vpp_ctx = avctx->priv;
47  ScaleVAAPIContext *ctx = avctx->priv;
48  int err;
49 
50  if ((err = ff_scale_eval_dimensions(ctx,
51  ctx->w_expr, ctx->h_expr,
52  inlink, outlink,
53  &vpp_ctx->output_width, &vpp_ctx->output_height)) < 0)
54  return err;
55 
56  err = ff_vaapi_vpp_config_output(outlink);
57  if (err < 0)
58  return err;
59 
60  if (inlink->sample_aspect_ratio.num)
61  outlink->sample_aspect_ratio = av_mul_q((AVRational){outlink->h * inlink->w, outlink->w * inlink->h}, inlink->sample_aspect_ratio);
62  else
63  outlink->sample_aspect_ratio = inlink->sample_aspect_ratio;
64 
65  return 0;
66 }
67 
68 static int scale_vaapi_filter_frame(AVFilterLink *inlink, AVFrame *input_frame)
69 {
70  AVFilterContext *avctx = inlink->dst;
71  AVFilterLink *outlink = avctx->outputs[0];
72  VAAPIVPPContext *vpp_ctx = avctx->priv;
74  VASurfaceID input_surface, output_surface;
75  VAProcPipelineParameterBuffer params;
76  VARectangle input_region;
77  int err;
78 
79  av_log(avctx, AV_LOG_DEBUG, "Filter input: %s, %ux%u (%"PRId64").\n",
80  av_get_pix_fmt_name(input_frame->format),
81  input_frame->width, input_frame->height, input_frame->pts);
82 
83  if (vpp_ctx->va_context == VA_INVALID_ID)
84  return AVERROR(EINVAL);
85 
86  input_surface = (VASurfaceID)(uintptr_t)input_frame->data[3];
87  av_log(avctx, AV_LOG_DEBUG, "Using surface %#x for scale input.\n",
88  input_surface);
89 
90  output_frame = ff_get_video_buffer(outlink, vpp_ctx->output_width,
91  vpp_ctx->output_height);
92  if (!output_frame) {
93  err = AVERROR(ENOMEM);
94  goto fail;
95  }
96 
97  output_surface = (VASurfaceID)(uintptr_t)output_frame->data[3];
98  av_log(avctx, AV_LOG_DEBUG, "Using surface %#x for scale output.\n",
99  output_surface);
100 
101  memset(&params, 0, sizeof(params));
102 
103  input_region = (VARectangle) {
104  .x = input_frame->crop_left,
105  .y = input_frame->crop_top,
106  .width = input_frame->width -
107  (input_frame->crop_left + input_frame->crop_right),
108  .height = input_frame->height -
109  (input_frame->crop_top + input_frame->crop_bottom),
110  };
111 
112  params.surface = input_surface;
113  params.surface_region = &input_region;
114  params.surface_color_standard =
116 
117  params.output_region = 0;
118  params.output_background_color = 0xff000000;
119  params.output_color_standard = params.surface_color_standard;
120 
121  params.pipeline_flags = 0;
122  params.filter_flags = VA_FILTER_SCALING_HQ;
123 
124  err = ff_vaapi_vpp_render_picture(avctx, &params, output_surface);
125  if (err < 0)
126  goto fail;
127 
128  err = av_frame_copy_props(output_frame, input_frame);
129  if (err < 0)
130  goto fail;
131 
132  av_frame_free(&input_frame);
133 
134  av_log(avctx, AV_LOG_DEBUG, "Filter output: %s, %ux%u (%"PRId64").\n",
135  av_get_pix_fmt_name(output_frame->format),
136  output_frame->width, output_frame->height, output_frame->pts);
137 
138  return ff_filter_frame(outlink, output_frame);
139 
140 fail:
141  av_frame_free(&input_frame);
142  av_frame_free(&output_frame);
143  return err;
144 }
145 
147 {
148  VAAPIVPPContext *vpp_ctx = avctx->priv;
149  ScaleVAAPIContext *ctx = avctx->priv;
150 
151  ff_vaapi_vpp_ctx_init(avctx);
153 
154  if (ctx->output_format_string) {
156  if (vpp_ctx->output_format == AV_PIX_FMT_NONE) {
157  av_log(avctx, AV_LOG_ERROR, "Invalid output format.\n");
158  return AVERROR(EINVAL);
159  }
160  } else {
161  // Use the input format once that is configured.
162  vpp_ctx->output_format = AV_PIX_FMT_NONE;
163  }
164 
165  return 0;
166 }
167 
168 #define OFFSET(x) offsetof(ScaleVAAPIContext, x)
169 #define FLAGS (AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM)
170 static const AVOption scale_vaapi_options[] = {
171  { "w", "Output video width",
172  OFFSET(w_expr), AV_OPT_TYPE_STRING, {.str = "iw"}, .flags = FLAGS },
173  { "h", "Output video height",
174  OFFSET(h_expr), AV_OPT_TYPE_STRING, {.str = "ih"}, .flags = FLAGS },
175  { "format", "Output video format (software format of hardware frames)",
177  { NULL },
178 };
179 
180 AVFILTER_DEFINE_CLASS(scale_vaapi);
181 
182 static const AVFilterPad scale_vaapi_inputs[] = {
183  {
184  .name = "default",
185  .type = AVMEDIA_TYPE_VIDEO,
186  .filter_frame = &scale_vaapi_filter_frame,
187  .config_props = &ff_vaapi_vpp_config_input,
188  },
189  { NULL }
190 };
191 
193  {
194  .name = "default",
195  .type = AVMEDIA_TYPE_VIDEO,
196  .config_props = &scale_vaapi_config_output,
197  },
198  { NULL }
199 };
200 
202  .name = "scale_vaapi",
203  .description = NULL_IF_CONFIG_SMALL("Scale to/from VAAPI surfaces."),
204  .priv_size = sizeof(ScaleVAAPIContext),
208  .inputs = scale_vaapi_inputs,
209  .outputs = scale_vaapi_outputs,
210  .priv_class = &scale_vaapi_class,
211  .flags_internal = FF_FILTER_FLAG_HWFRAME_AWARE,
212 };
#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:218
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
size_t crop_bottom
Definition: frame.h:578
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 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.
size_t crop_left
Definition: frame.h:579
int64_t pts
Presentation timestamp in time_base units (time when frame should be shown to user).
Definition: frame.h:311
#define height
#define av_log(a,...)
int ff_vaapi_vpp_render_picture(AVFilterContext *avctx, VAProcPipelineParameterBuffer *params, VASurfaceID output_surface)
Definition: vaapi_vpp.c:280
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:276
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:176
#define AVERROR(e)
Definition: error.h:43
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
#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:474
simple assert() macros that are a bit more flexible than ISO C assert().
static const AVFilterPad scale_vaapi_inputs[]
#define fail()
Definition: checkasm.h:116
size_t crop_top
Definition: frame.h:577
void ff_vaapi_vpp_pipeline_uninit(AVFilterContext *avctx)
Definition: vaapi_vpp.c:44
AVFormatContext * ctx
Definition: movenc.c:48
static const AVFilterPad inputs[]
Definition: af_acontrast.c:193
static const AVFilterPad outputs[]
Definition: af_acontrast.c:203
int format
format of the frame, -1 if unknown or unset Values correspond to enum AVPixelFormat for video frames...
Definition: frame.h:291
#define FLAGS
size_t crop_right
Definition: frame.h:580
static int output_frame(H264Context *h, AVFrame *dst, H264Picture *srcp)
Definition: h264dec.c:836
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
AVFilterLink ** outputs
array of pointers to output links
Definition: avfilter.h:350
VAContextID va_context
Definition: vaapi_vpp.h:38
enum AVPixelFormat output_format
Definition: vaapi_vpp.h:43
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition: frame.h:232
const char const char * params
Definition: avisynth_c.h:775
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:351
int ff_vaapi_vpp_colour_standard(enum AVColorSpace av_cs)
Definition: vaapi_vpp.c:237
#define OFFSET(x)
An instance of a filter.
Definition: avfilter.h:338
AVRational av_mul_q(AVRational b, AVRational c)
Multiply two rationals.
Definition: rational.c:80
int height
Definition: frame.h:276
enum AVPixelFormat av_get_pix_fmt(const char *name)
Return the pixel format corresponding to name.
Definition: pixdesc.c:2291
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:2279
internal API functions
static int scale_vaapi_filter_frame(AVFilterLink *inlink, AVFrame *input_frame)
void(* pipeline_uninit)(AVFilterContext *avctx)
Definition: vaapi_vpp.h:52
void ff_vaapi_vpp_ctx_uninit(AVFilterContext *avctx)
Definition: vaapi_vpp.c:365
int av_frame_copy_props(AVFrame *dst, const AVFrame *src)
Copy only "metadata" fields from src to dst.
Definition: frame.c:652