FFmpeg  4.0
vf_misc_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 #include <string.h>
19 
20 #include "libavutil/avassert.h"
21 #include "libavutil/mem.h"
22 #include "libavutil/opt.h"
23 #include "libavutil/pixdesc.h"
24 
25 #include "avfilter.h"
26 #include "formats.h"
27 #include "internal.h"
28 #include "vaapi_vpp.h"
29 
30 // Denoise min/max/default Values
31 #define DENOISE_MIN 0
32 #define DENOISE_MAX 64
33 #define DENOISE_DEFAULT 0
34 
35 // Sharpness min/max/default values
36 #define SHARPNESS_MIN 0
37 #define SHARPNESS_MAX 64
38 #define SHARPNESS_DEFAULT 44
39 
40 typedef struct DenoiseVAAPIContext {
41  VAAPIVPPContext vpp_ctx; // must be the first field
42 
43  int denoise; // enable denoise algo.
45 
46 typedef struct SharpnessVAAPIContext {
47  VAAPIVPPContext vpp_ctx; // must be the first field
48 
49  int sharpness; // enable sharpness.
51 
52 static float map(int x, int in_min, int in_max, float out_min, float out_max)
53 {
54  double slope, output;
55 
56  slope = 1.0 * (out_max - out_min) / (in_max - in_min);
57  output = out_min + slope * (x - in_min);
58 
59  return (float)output;
60 }
61 
63 {
64  VAAPIVPPContext *vpp_ctx = avctx->priv;
65  DenoiseVAAPIContext *ctx = avctx->priv;
66 
67  VAProcFilterCap caps;
68 
69  VAStatus vas;
70  uint32_t num_caps = 1;
71 
72  VAProcFilterParameterBuffer denoise;
73 
74  vas = vaQueryVideoProcFilterCaps(vpp_ctx->hwctx->display, vpp_ctx->va_context,
75  VAProcFilterNoiseReduction,
76  &caps, &num_caps);
77  if (vas != VA_STATUS_SUCCESS) {
78  av_log(avctx, AV_LOG_ERROR, "Failed to query denoise caps "
79  "context: %d (%s).\n", vas, vaErrorStr(vas));
80  return AVERROR(EIO);
81  }
82 
83  denoise.type = VAProcFilterNoiseReduction;
84  denoise.value = map(ctx->denoise, DENOISE_MIN, DENOISE_MAX,
85  caps.range.min_value,
86  caps.range.max_value);
87  ff_vaapi_vpp_make_param_buffers(avctx, VAProcFilterParameterBufferType,
88  &denoise, sizeof(denoise), 1);
89 
90  return 0;
91 }
92 
94 {
95  VAAPIVPPContext *vpp_ctx = avctx->priv;
96  SharpnessVAAPIContext *ctx = avctx->priv;
97 
98  VAProcFilterCap caps;
99 
100  VAStatus vas;
101  uint32_t num_caps = 1;
102 
103  VAProcFilterParameterBuffer sharpness;
104 
105  vas = vaQueryVideoProcFilterCaps(vpp_ctx->hwctx->display, vpp_ctx->va_context,
106  VAProcFilterSharpening,
107  &caps, &num_caps);
108  if (vas != VA_STATUS_SUCCESS) {
109  av_log(avctx, AV_LOG_ERROR, "Failed to query sharpness caps "
110  "context: %d (%s).\n", vas, vaErrorStr(vas));
111  return AVERROR(EIO);
112  }
113 
114  sharpness.type = VAProcFilterSharpening;
115  sharpness.value = map(ctx->sharpness,
117  caps.range.min_value,
118  caps.range.max_value);
120  VAProcFilterParameterBufferType,
121  &sharpness, sizeof(sharpness), 1);
122 
123  return 0;
124 }
125 
126 static int misc_vaapi_filter_frame(AVFilterLink *inlink, AVFrame *input_frame)
127 {
128  AVFilterContext *avctx = inlink->dst;
129  AVFilterLink *outlink = avctx->outputs[0];
130  VAAPIVPPContext *vpp_ctx = avctx->priv;
132  VASurfaceID input_surface, output_surface;
133  VARectangle input_region;
134 
135  VAProcPipelineParameterBuffer params;
136  int err;
137 
138  av_log(avctx, AV_LOG_DEBUG, "Filter input: %s, %ux%u (%"PRId64").\n",
139  av_get_pix_fmt_name(input_frame->format),
140  input_frame->width, input_frame->height, input_frame->pts);
141 
142  if (vpp_ctx->va_context == VA_INVALID_ID)
143  return AVERROR(EINVAL);
144 
145  input_surface = (VASurfaceID)(uintptr_t)input_frame->data[3];
146  av_log(avctx, AV_LOG_DEBUG, "Using surface %#x for misc vpp input.\n",
147  input_surface);
148 
149  output_frame = ff_get_video_buffer(outlink, vpp_ctx->output_width,
150  vpp_ctx->output_height);
151  if (!output_frame) {
152  err = AVERROR(ENOMEM);
153  goto fail;
154  }
155 
156  output_surface = (VASurfaceID)(uintptr_t)output_frame->data[3];
157  av_log(avctx, AV_LOG_DEBUG, "Using surface %#x for misc vpp output.\n",
158  output_surface);
159  memset(&params, 0, sizeof(params));
160  input_region = (VARectangle) {
161  .x = 0,
162  .y = 0,
163  .width = input_frame->width,
164  .height = input_frame->height,
165  };
166 
167  if (vpp_ctx->nb_filter_buffers) {
168  params.filters = &vpp_ctx->filter_buffers[0];
169  params.num_filters = vpp_ctx->nb_filter_buffers;
170  }
171  params.surface = input_surface;
172  params.surface_region = &input_region;
173  params.surface_color_standard =
175 
176  params.output_region = NULL;
177  params.output_background_color = 0xff000000;
178  params.output_color_standard = params.surface_color_standard;
179 
180  params.pipeline_flags = 0;
181  params.filter_flags = VA_FRAME_PICTURE;
182 
183  err = ff_vaapi_vpp_render_picture(avctx, &params, output_surface);
184  if (err < 0)
185  goto fail;
186 
187  err = av_frame_copy_props(output_frame, input_frame);
188  if (err < 0)
189  goto fail;
190  av_frame_free(&input_frame);
191 
192  av_log(avctx, AV_LOG_DEBUG, "Filter output: %s, %ux%u (%"PRId64").\n",
193  av_get_pix_fmt_name(output_frame->format),
194  output_frame->width, output_frame->height, output_frame->pts);
195 
196  return ff_filter_frame(outlink, output_frame);
197 
198 fail:
199  av_frame_free(&input_frame);
200  av_frame_free(&output_frame);
201  return err;
202 }
203 
205 {
206  VAAPIVPPContext *vpp_ctx = avctx->priv;
207 
208  ff_vaapi_vpp_ctx_init(avctx);
211  vpp_ctx->output_format = AV_PIX_FMT_NONE;
212 
213  return 0;
214 }
215 
217 {
218  VAAPIVPPContext *vpp_ctx = avctx->priv;
219 
220  ff_vaapi_vpp_ctx_init(avctx);
223  vpp_ctx->output_format = AV_PIX_FMT_NONE;
224 
225  return 0;
226 }
227 
228 #define DOFFSET(x) offsetof(DenoiseVAAPIContext, x)
229 #define FLAGS (AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_FILTERING_PARAM)
230 static const AVOption denoise_vaapi_options[] = {
231  { "denoise", "denoise level",
233  { NULL },
234 };
235 
236 #define SOFFSET(x) offsetof(SharpnessVAAPIContext, x)
238  { "sharpness", "sharpness level",
239  SOFFSET(sharpness), AV_OPT_TYPE_INT, { .i64 = SHARPNESS_DEFAULT }, SHARPNESS_MIN, SHARPNESS_MAX, .flags = FLAGS },
240  { NULL },
241 };
242 
243 AVFILTER_DEFINE_CLASS(denoise_vaapi);
244 AVFILTER_DEFINE_CLASS(sharpness_vaapi);
245 
246 static const AVFilterPad misc_vaapi_inputs[] = {
247  {
248  .name = "default",
249  .type = AVMEDIA_TYPE_VIDEO,
250  .filter_frame = &misc_vaapi_filter_frame,
251  .config_props = &ff_vaapi_vpp_config_input,
252  },
253  { NULL }
254 };
255 
256 static const AVFilterPad misc_vaapi_outputs[] = {
257  {
258  .name = "default",
259  .type = AVMEDIA_TYPE_VIDEO,
260  .config_props = &ff_vaapi_vpp_config_output,
261  },
262  { NULL }
263 };
264 
266  .name = "denoise_vaapi",
267  .description = NULL_IF_CONFIG_SMALL("VAAPI VPP for de-noise"),
268  .priv_size = sizeof(DenoiseVAAPIContext),
272  .inputs = misc_vaapi_inputs,
273  .outputs = misc_vaapi_outputs,
274  .priv_class = &denoise_vaapi_class,
275  .flags_internal = FF_FILTER_FLAG_HWFRAME_AWARE,
276 };
277 
279  .name = "sharpness_vaapi",
280  .description = NULL_IF_CONFIG_SMALL("VAAPI VPP for sharpness"),
281  .priv_size = sizeof(SharpnessVAAPIContext),
285  .inputs = misc_vaapi_inputs,
286  .outputs = misc_vaapi_outputs,
287  .priv_class = &sharpness_vaapi_class,
288  .flags_internal = FF_FILTER_FLAG_HWFRAME_AWARE,
289 };
#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
static const AVFilterPad misc_vaapi_inputs[]
This structure describes decoded (raw) audio or video data.
Definition: frame.h:218
int ff_vaapi_vpp_config_input(AVFilterLink *inlink)
Definition: vaapi_vpp.c:70
AVOption.
Definition: opt.h:246
#define SHARPNESS_DEFAULT
Definition: vf_misc_vaapi.c:38
VAAPIVPPContext vpp_ctx
Definition: vf_misc_vaapi.c:41
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 nb_filter_buffers
Definition: vaapi_vpp.h:48
static const AVOption sharpness_vaapi_options[]
static const AVFilterPad misc_vaapi_outputs[]
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
const char * name
Pad name.
Definition: internal.h:60
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
static av_cold int uninit(AVCodecContext *avctx)
Definition: crystalhd.c:279
AVOptions.
int64_t pts
Presentation timestamp in time_base units (time when frame should be shown to user).
Definition: frame.h:311
#define av_log(a,...)
int ff_vaapi_vpp_render_picture(AVFilterContext *avctx, VAProcPipelineParameterBuffer *params, VASurfaceID output_surface)
Definition: vaapi_vpp.c:280
#define DENOISE_DEFAULT
Definition: vf_misc_vaapi.c:33
A filter pad used for either input or output.
Definition: internal.h:54
#define SOFFSET(x)
#define DOFFSET(x)
int width
Definition: frame.h:276
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:176
#define DENOISE_MIN
Definition: vf_misc_vaapi.c:31
#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
static av_cold int sharpness_vaapi_init(AVFilterContext *avctx)
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification. ...
Definition: internal.h:186
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
AVFILTER_DEFINE_CLASS(denoise_vaapi)
enum AVColorSpace colorspace
YUV colorspace type.
Definition: frame.h:474
simple assert() macros that are a bit more flexible than ISO C assert().
int ff_vaapi_vpp_make_param_buffers(AVFilterContext *avctx, int type, const void *data, size_t size, int count)
Definition: vaapi_vpp.c:251
#define fail()
Definition: checkasm.h:116
static int misc_vaapi_filter_frame(AVFilterLink *inlink, AVFrame *input_frame)
AVFilter ff_vf_sharpness_vaapi
static av_cold int denoise_vaapi_init(AVFilterContext *avctx)
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
VADisplay display
The VADisplay handle, to be filled by the user.
int format
format of the frame, -1 if unknown or unset Values correspond to enum AVPixelFormat for video frames...
Definition: frame.h:291
VABufferID filter_buffers[VAProcFilterCount]
Definition: vaapi_vpp.h:47
static int output_frame(H264Context *h, AVFrame *dst, H264Picture *srcp)
Definition: h264dec.c:836
Filter definition.
Definition: avfilter.h:144
#define DENOISE_MAX
Definition: vf_misc_vaapi.c:32
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
AVVAAPIDeviceContext * hwctx
Definition: vaapi_vpp.h:33
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
#define SHARPNESS_MAX
Definition: vf_misc_vaapi.c:37
#define SHARPNESS_MIN
Definition: vf_misc_vaapi.c:36
static int query_formats(AVFilterContext *ctx)
Definition: aeval.c:244
void ff_vaapi_vpp_ctx_init(AVFilterContext *avctx)
Definition: vaapi_vpp.c:351
static int sharpness_vaapi_build_filter_params(AVFilterContext *avctx)
Definition: vf_misc_vaapi.c:93
VAAPIVPPContext vpp_ctx
Definition: vf_misc_vaapi.c:47
#define FLAGS
int ff_vaapi_vpp_colour_standard(enum AVColorSpace av_cs)
Definition: vaapi_vpp.c:237
static int denoise_vaapi_build_filter_params(AVFilterContext *avctx)
Definition: vf_misc_vaapi.c:62
static const AVOption denoise_vaapi_options[]
An instance of a filter.
Definition: avfilter.h:338
int height
Definition: frame.h:276
static float map(int x, int in_min, int in_max, float out_min, float out_max)
Definition: vf_misc_vaapi.c:52
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
int(* build_filter_params)(AVFilterContext *avctx)
Definition: vaapi_vpp.h:50
internal API functions
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
AVFilter ff_vf_denoise_vaapi