FFmpeg  4.2.1
vf_procamp_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 // ProcAmp Min/Max/Default Values
31 #define BRIGHTNESS_MIN -100.0F
32 #define BRIGHTNESS_MAX 100.0F
33 #define BRIGHTNESS_DEFAULT 0.0F
34 
35 #define CONTRAST_MIN 0.0F
36 #define CONTRAST_MAX 10.0F
37 #define CONTRAST_DEFAULT 1.0F
38 
39 #define HUE_MIN -180.0F
40 #define HUE_MAX 180.0F
41 #define HUE_DEFAULT 0.0F
42 
43 #define SATURATION_MIN 0.0F
44 #define SATURATION_MAX 10.0F
45 #define SATURATION_DEFAULT 1.0F
46 
47 typedef struct ProcampVAAPIContext {
48  VAAPIVPPContext vpp_ctx; // must be the first field
49 
50  float bright;
51  float hue;
52  float saturation;
53  float contrast;
55 
56 static float map(float x, float in_min, float in_max, float out_min, float out_max)
57 {
58  double slope, output;
59 
60  slope = 1.0 * (out_max - out_min) / (in_max - in_min);
61  output = out_min + slope * (x - in_min);
62 
63  return (float)output;
64 }
65 
67 {
68  VAAPIVPPContext *vpp_ctx = avctx->priv;
69  ProcampVAAPIContext *ctx = avctx->priv;
70  VAStatus vas;
71  VAProcFilterParameterBufferColorBalance procamp_params[4];
72  VAProcFilterCapColorBalance procamp_caps[VAProcColorBalanceCount];
73  int num_caps;
74  int i = 0;
75 
76  memset(&procamp_params, 0, sizeof(procamp_params));
77  memset(&procamp_caps, 0, sizeof(procamp_caps));
78 
79  num_caps = VAProcColorBalanceCount;
80  vas = vaQueryVideoProcFilterCaps(vpp_ctx->hwctx->display, vpp_ctx->va_context,
81  VAProcFilterColorBalance, &procamp_caps, &num_caps);
82 
83  if (vas != VA_STATUS_SUCCESS) {
84  av_log(avctx, AV_LOG_ERROR, "Failed to query procamp "
85  "filter caps: %d (%s).\n", vas, vaErrorStr(vas));
86  return AVERROR(EIO);
87  }
88 
89  /* brightness */
90  procamp_params[i].type = VAProcFilterColorBalance;
91  procamp_params[i].attrib = VAProcColorBalanceBrightness;
92  procamp_params[i].value = map(ctx->bright, BRIGHTNESS_MIN, BRIGHTNESS_MAX,
93  procamp_caps[VAProcColorBalanceBrightness-1].range.min_value,
94  procamp_caps[VAProcColorBalanceBrightness-1].range.max_value);
95  i++;
96 
97  /* contrast */
98  procamp_params[i].type = VAProcFilterColorBalance;
99  procamp_params[i].attrib = VAProcColorBalanceContrast;
100  procamp_params[i].value = map(ctx->contrast, CONTRAST_MIN, CONTRAST_MAX,
101  procamp_caps[VAProcColorBalanceContrast-1].range.min_value,
102  procamp_caps[VAProcColorBalanceContrast-1].range.max_value);
103  i++;
104 
105  /* hue */
106  procamp_params[i].type = VAProcFilterColorBalance;
107  procamp_params[i].attrib = VAProcColorBalanceHue;
108  procamp_params[i].value = map(ctx->hue, HUE_MIN, HUE_MAX,
109  procamp_caps[VAProcColorBalanceHue-1].range.min_value,
110  procamp_caps[VAProcColorBalanceHue-1].range.max_value);
111  i++;
112 
113  /* saturation */
114  procamp_params[i].type = VAProcFilterColorBalance;
115  procamp_params[i].attrib = VAProcColorBalanceSaturation;
116  procamp_params[i].value = map(ctx->saturation, SATURATION_MIN, SATURATION_MAX,
117  procamp_caps[VAProcColorBalanceSaturation-1].range.min_value,
118  procamp_caps[VAProcColorBalanceSaturation-1].range.max_value);
119  i++;
120 
121  return ff_vaapi_vpp_make_param_buffers(avctx,
122  VAProcFilterParameterBufferType,
123  &procamp_params,
124  sizeof(procamp_params[0]),
125  i);
126 }
127 
128 static int procamp_vaapi_filter_frame(AVFilterLink *inlink, AVFrame *input_frame)
129 {
130  AVFilterContext *avctx = inlink->dst;
131  AVFilterLink *outlink = avctx->outputs[0];
132  VAAPIVPPContext *vpp_ctx = avctx->priv;
134  VAProcPipelineParameterBuffer params;
135  int err;
136 
137  av_log(avctx, AV_LOG_DEBUG, "Filter input: %s, %ux%u (%"PRId64").\n",
138  av_get_pix_fmt_name(input_frame->format),
139  input_frame->width, input_frame->height, input_frame->pts);
140 
141  if (vpp_ctx->va_context == VA_INVALID_ID)
142  return AVERROR(EINVAL);
143 
144  output_frame = ff_get_video_buffer(outlink, vpp_ctx->output_width,
145  vpp_ctx->output_height);
146  if (!output_frame) {
147  err = AVERROR(ENOMEM);
148  goto fail;
149  }
150 
151  err = av_frame_copy_props(output_frame, input_frame);
152  if (err < 0)
153  return err;
154 
155  err = ff_vaapi_vpp_init_params(avctx, &params,
156  input_frame, output_frame);
157  if (err < 0)
158  goto fail;
159 
160  params.filters = &vpp_ctx->filter_buffers[0];
161  params.num_filters = 1;
162 
163  err = ff_vaapi_vpp_render_picture(avctx, &params, output_frame);
164  if (err < 0)
165  goto fail;
166 
167  av_frame_free(&input_frame);
168 
169  av_log(avctx, AV_LOG_DEBUG, "Filter output: %s, %ux%u (%"PRId64").\n",
170  av_get_pix_fmt_name(output_frame->format),
171  output_frame->width, output_frame->height, output_frame->pts);
172 
173  return ff_filter_frame(outlink, output_frame);
174 
175 fail:
176  av_frame_free(&input_frame);
177  av_frame_free(&output_frame);
178  return err;
179 }
180 
182 {
183  VAAPIVPPContext *vpp_ctx = avctx->priv;
184 
185  ff_vaapi_vpp_ctx_init(avctx);
188  vpp_ctx->output_format = AV_PIX_FMT_NONE;
189 
190  return 0;
191 }
192 
193 #define OFFSET(x) offsetof(ProcampVAAPIContext, x)
194 #define FLAGS (AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_FILTERING_PARAM)
195 static const AVOption procamp_vaapi_options[] = {
196  { "b", "Output video brightness",
198  { "brightness", "Output video brightness",
200  { "s", "Output video saturation",
202  { "saturatio", "Output video saturation",
204  { "c", "Output video contrast",
206  { "contrast", "Output video contrast",
208  { "h", "Output video hue",
209  OFFSET(hue), AV_OPT_TYPE_FLOAT, { .dbl = HUE_DEFAULT }, HUE_MIN, HUE_MAX, .flags = FLAGS },
210  { "hue", "Output video hue",
211  OFFSET(hue), AV_OPT_TYPE_FLOAT, { .dbl = HUE_DEFAULT }, HUE_MIN, HUE_MAX, .flags = FLAGS },
212  { NULL },
213 };
214 
215 AVFILTER_DEFINE_CLASS(procamp_vaapi);
216 
218  {
219  .name = "default",
220  .type = AVMEDIA_TYPE_VIDEO,
221  .filter_frame = &procamp_vaapi_filter_frame,
222  .config_props = &ff_vaapi_vpp_config_input,
223  },
224  { NULL }
225 };
226 
228  {
229  .name = "default",
230  .type = AVMEDIA_TYPE_VIDEO,
231  .config_props = &ff_vaapi_vpp_config_output,
232  },
233  { NULL }
234 };
235 
237  .name = "procamp_vaapi",
238  .description = NULL_IF_CONFIG_SMALL("ProcAmp (color balance) adjustments for hue, saturation, brightness, contrast"),
239  .priv_size = sizeof(ProcampVAAPIContext),
243  .inputs = procamp_vaapi_inputs,
244  .outputs = procamp_vaapi_outputs,
245  .priv_class = &procamp_vaapi_class,
246  .flags_internal = FF_FILTER_FLAG_HWFRAME_AWARE,
247 };
#define NULL
Definition: coverity.c:32
#define CONTRAST_DEFAULT
#define HUE_MIN
#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
This structure describes decoded (raw) audio or video data.
Definition: frame.h:295
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.
#define HUE_DEFAULT
int ff_vaapi_vpp_config_output(AVFilterLink *outlink)
Definition: vaapi_vpp.c:95
static av_cold int init(AVCodecContext *avctx)
Definition: avrndec.c:35
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
#define OFFSET(x)
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
static int procamp_vaapi_build_filter_params(AVFilterContext *avctx)
#define av_cold
Definition: attributes.h:82
static av_cold int uninit(AVCodecContext *avctx)
Definition: crystalhd.c:279
AVOptions.
#define HUE_MAX
int64_t pts
Presentation timestamp in time_base units (time when frame should be shown to user).
Definition: frame.h:388
static float map(float x, float in_min, float in_max, float out_min, float out_max)
#define CONTRAST_MIN
#define BRIGHTNESS_MAX
#define av_log(a,...)
A filter pad used for either input or output.
Definition: internal.h:54
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:259
int width
Definition: frame.h:353
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:176
static int procamp_vaapi_filter_frame(AVFilterLink *inlink, AVFrame *input_frame)
#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
#define SATURATION_MIN
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
#define SATURATION_MAX
simple assert() macros that are a bit more flexible than ISO C assert().
static av_cold int procamp_vaapi_init(AVFilterContext *avctx)
#define BRIGHTNESS_DEFAULT
int ff_vaapi_vpp_make_param_buffers(AVFilterContext *avctx, int type, const void *data, size_t size, int count)
Definition: vaapi_vpp.c:563
#define fail()
Definition: checkasm.h:120
AVFilter ff_vf_procamp_vaapi
VAAPIVPPContext vpp_ctx
static const AVOption procamp_vaapi_options[]
void ff_vaapi_vpp_pipeline_uninit(AVFilterContext *avctx)
Definition: vaapi_vpp.c:44
static const AVFilterPad procamp_vaapi_outputs[]
AVFormatContext * ctx
Definition: movenc.c:48
AVFILTER_DEFINE_CLASS(procamp_vaapi)
static const AVFilterPad inputs[]
Definition: af_acontrast.c:193
#define CONTRAST_MAX
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:368
#define FLAGS
VABufferID filter_buffers[VAProcFilterCount]
Definition: vaapi_vpp.h:51
static int output_frame(H264Context *h, AVFrame *dst, H264Picture *srcp)
Definition: h264dec.c:837
Filter definition.
Definition: avfilter.h:144
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:41
enum AVPixelFormat output_format
Definition: vaapi_vpp.h:47
AVVAAPIDeviceContext * hwctx
Definition: vaapi_vpp.h:36
int ff_vaapi_vpp_render_picture(AVFilterContext *avctx, VAProcPipelineParameterBuffer *params, AVFrame *output_frame)
Definition: vaapi_vpp.c:592
const char const char * params
Definition: avisynth_c.h:867
#define SATURATION_DEFAULT
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
static const AVFilterPad procamp_vaapi_inputs[]
An instance of a filter.
Definition: avfilter.h:338
int height
Definition: frame.h:353
int ff_vaapi_vpp_init_params(AVFilterContext *avctx, VAProcPipelineParameterBuffer *params, const AVFrame *input_frame, AVFrame *output_frame)
Definition: vaapi_vpp.c:515
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
int(* build_filter_params)(AVFilterContext *avctx)
Definition: vaapi_vpp.h:54
internal API functions
#define BRIGHTNESS_MIN
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