FFmpeg
vf_scale_qsv.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 - QSV
22  */
23 
24 #include <mfx/mfxvideo.h>
25 
26 #include <stdio.h>
27 #include <string.h>
28 
29 #include "libavutil/avstring.h"
30 #include "libavutil/common.h"
31 #include "libavutil/eval.h"
32 #include "libavutil/hwcontext.h"
34 #include "libavutil/internal.h"
35 #include "libavutil/mathematics.h"
36 #include "libavutil/opt.h"
37 #include "libavutil/pixdesc.h"
38 #include "libavutil/time.h"
39 #include "libavfilter/qsvvpp.h"
40 
41 #include "avfilter.h"
42 #include "formats.h"
43 #include "internal.h"
44 #include "video.h"
45 
46 static const char *const var_names[] = {
47  "PI",
48  "PHI",
49  "E",
50  "in_w", "iw",
51  "in_h", "ih",
52  "out_w", "ow",
53  "out_h", "oh",
54  "a", "dar",
55  "sar",
56  NULL
57 };
58 
59 enum var_name {
70 };
71 
72 typedef struct QSVScaleContext {
73  const AVClass *class;
74 
75  /* a clone of the main session, used internally for scaling */
76  mfxSession session;
77 
78  mfxMemId *mem_ids_in;
80 
81  mfxMemId *mem_ids_out;
83 
84  mfxFrameSurface1 **surface_ptrs_in;
86 
87  mfxFrameSurface1 **surface_ptrs_out;
89 
90  mfxExtOpaqueSurfaceAlloc opaque_alloc;
91  mfxExtBuffer *ext_buffers[1];
92 
94 
95  /**
96  * New dimensions. Special values are:
97  * 0 = original width/height
98  * -1 = keep original aspect
99  */
100  int w, h;
101 
102  /**
103  * Output sw format. AV_PIX_FMT_NONE for no conversion.
104  */
106 
107  char *w_expr; ///< width expression string
108  char *h_expr; ///< height expression string
109  char *format_str;
111 
113 {
114  QSVScaleContext *s = ctx->priv;
115 
116  if (!strcmp(s->format_str, "same")) {
117  s->format = AV_PIX_FMT_NONE;
118  } else {
120  if (s->format == AV_PIX_FMT_NONE) {
121  av_log(ctx, AV_LOG_ERROR, "Unrecognized pixel format: %s\n", s->format_str);
122  return AVERROR(EINVAL);
123  }
124  }
125 
126  return 0;
127 }
128 
130 {
131  QSVScaleContext *s = ctx->priv;
132 
133  if (s->session) {
134  MFXClose(s->session);
135  s->session = NULL;
136  }
137 
138  av_freep(&s->mem_ids_in);
139  av_freep(&s->mem_ids_out);
140  s->nb_mem_ids_in = 0;
141  s->nb_mem_ids_out = 0;
142 
145  s->nb_surface_ptrs_in = 0;
146  s->nb_surface_ptrs_out = 0;
147 }
148 
150 {
151  static const enum AVPixelFormat pixel_formats[] = {
153  };
154  AVFilterFormats *pix_fmts = ff_make_format_list(pixel_formats);
155  int ret;
156 
157  if ((ret = ff_set_common_formats(ctx, pix_fmts)) < 0)
158  return ret;
159 
160  return 0;
161 }
162 
164  int out_width, int out_height)
165 {
166  QSVScaleContext *s = ctx->priv;
167  AVFilterLink *outlink = ctx->outputs[0];
168 
169  AVHWFramesContext *in_frames_ctx;
170  AVHWFramesContext *out_frames_ctx;
171  AVQSVFramesContext *in_frames_hwctx;
172  AVQSVFramesContext *out_frames_hwctx;
173  enum AVPixelFormat in_format;
174  enum AVPixelFormat out_format;
175  int i, ret;
176 
177  /* check that we have a hw context */
178  if (!ctx->inputs[0]->hw_frames_ctx) {
179  av_log(ctx, AV_LOG_ERROR, "No hw context provided on input\n");
180  return AVERROR(EINVAL);
181  }
182  in_frames_ctx = (AVHWFramesContext*)ctx->inputs[0]->hw_frames_ctx->data;
183  in_frames_hwctx = in_frames_ctx->hwctx;
184 
185  in_format = in_frames_ctx->sw_format;
186  out_format = (s->format == AV_PIX_FMT_NONE) ? in_format : s->format;
187 
188  outlink->hw_frames_ctx = av_hwframe_ctx_alloc(in_frames_ctx->device_ref);
189  if (!outlink->hw_frames_ctx)
190  return AVERROR(ENOMEM);
191  out_frames_ctx = (AVHWFramesContext*)outlink->hw_frames_ctx->data;
192  out_frames_hwctx = out_frames_ctx->hwctx;
193 
194  out_frames_ctx->format = AV_PIX_FMT_QSV;
195  out_frames_ctx->width = FFALIGN(out_width, 32);
196  out_frames_ctx->height = FFALIGN(out_height, 32);
197  out_frames_ctx->sw_format = out_format;
198  out_frames_ctx->initial_pool_size = 4;
199 
200  out_frames_hwctx->frame_type = in_frames_hwctx->frame_type;
201 
202  ret = ff_filter_init_hw_frames(ctx, outlink, 32);
203  if (ret < 0)
204  return ret;
205 
206  ret = av_hwframe_ctx_init(outlink->hw_frames_ctx);
207  if (ret < 0)
208  return ret;
209 
210  for (i = 0; i < out_frames_hwctx->nb_surfaces; i++) {
211  mfxFrameInfo *info = &out_frames_hwctx->surfaces[i].Info;
212  info->CropW = out_width;
213  info->CropH = out_height;
214  }
215 
216  return 0;
217 }
218 
219 static mfxStatus frame_alloc(mfxHDL pthis, mfxFrameAllocRequest *req,
220  mfxFrameAllocResponse *resp)
221 {
222  AVFilterContext *ctx = pthis;
223  QSVScaleContext *s = ctx->priv;
224 
225  if (!(req->Type & MFX_MEMTYPE_VIDEO_MEMORY_PROCESSOR_TARGET) ||
226  !(req->Type & (MFX_MEMTYPE_FROM_VPPIN | MFX_MEMTYPE_FROM_VPPOUT)) ||
227  !(req->Type & MFX_MEMTYPE_EXTERNAL_FRAME))
228  return MFX_ERR_UNSUPPORTED;
229 
230  if (req->Type & MFX_MEMTYPE_FROM_VPPIN) {
231  resp->mids = s->mem_ids_in;
232  resp->NumFrameActual = s->nb_mem_ids_in;
233  } else {
234  resp->mids = s->mem_ids_out;
235  resp->NumFrameActual = s->nb_mem_ids_out;
236  }
237 
238  return MFX_ERR_NONE;
239 }
240 
241 static mfxStatus frame_free(mfxHDL pthis, mfxFrameAllocResponse *resp)
242 {
243  return MFX_ERR_NONE;
244 }
245 
246 static mfxStatus frame_lock(mfxHDL pthis, mfxMemId mid, mfxFrameData *ptr)
247 {
248  return MFX_ERR_UNSUPPORTED;
249 }
250 
251 static mfxStatus frame_unlock(mfxHDL pthis, mfxMemId mid, mfxFrameData *ptr)
252 {
253  return MFX_ERR_UNSUPPORTED;
254 }
255 
256 static mfxStatus frame_get_hdl(mfxHDL pthis, mfxMemId mid, mfxHDL *hdl)
257 {
258  *hdl = mid;
259  return MFX_ERR_NONE;
260 }
261 
262 static const mfxHandleType handle_types[] = {
263  MFX_HANDLE_VA_DISPLAY,
264  MFX_HANDLE_D3D9_DEVICE_MANAGER,
265  MFX_HANDLE_D3D11_DEVICE,
266 };
267 
269 {
270 
271  QSVScaleContext *s = ctx->priv;
272  AVHWFramesContext *in_frames_ctx = (AVHWFramesContext*)ctx->inputs[0]->hw_frames_ctx->data;
273  AVHWFramesContext *out_frames_ctx = (AVHWFramesContext*)ctx->outputs[0]->hw_frames_ctx->data;
274  AVQSVFramesContext *in_frames_hwctx = in_frames_ctx->hwctx;
275  AVQSVFramesContext *out_frames_hwctx = out_frames_ctx->hwctx;
276  AVQSVDeviceContext *device_hwctx = in_frames_ctx->device_ctx->hwctx;
277 
278  int opaque = !!(in_frames_hwctx->frame_type & MFX_MEMTYPE_OPAQUE_FRAME);
279 
280  mfxHDL handle = NULL;
281  mfxHandleType handle_type;
282  mfxVersion ver;
283  mfxIMPL impl;
284  mfxVideoParam par;
285  mfxStatus err;
286  int i;
287 
288  /* extract the properties of the "master" session given to us */
289  err = MFXQueryIMPL(device_hwctx->session, &impl);
290  if (err == MFX_ERR_NONE)
291  err = MFXQueryVersion(device_hwctx->session, &ver);
292  if (err != MFX_ERR_NONE) {
293  av_log(ctx, AV_LOG_ERROR, "Error querying the session attributes\n");
294  return AVERROR_UNKNOWN;
295  }
296 
297  for (i = 0; i < FF_ARRAY_ELEMS(handle_types); i++) {
298  err = MFXVideoCORE_GetHandle(device_hwctx->session, handle_types[i], &handle);
299  if (err == MFX_ERR_NONE) {
300  handle_type = handle_types[i];
301  break;
302  }
303  }
304 
305  if (err != MFX_ERR_NONE) {
306  av_log(ctx, AV_LOG_ERROR, "Error getting the session handle\n");
307  return AVERROR_UNKNOWN;
308  }
309 
310  /* create a "slave" session with those same properties, to be used for
311  * actual scaling */
312  err = MFXInit(impl, &ver, &s->session);
313  if (err != MFX_ERR_NONE) {
314  av_log(ctx, AV_LOG_ERROR, "Error initializing a session for scaling\n");
315  return AVERROR_UNKNOWN;
316  }
317 
318  if (handle) {
319  err = MFXVideoCORE_SetHandle(s->session, handle_type, handle);
320  if (err != MFX_ERR_NONE)
321  return AVERROR_UNKNOWN;
322  }
323 
324  if (QSV_RUNTIME_VERSION_ATLEAST(ver, 1, 25)) {
325  err = MFXJoinSession(device_hwctx->session, s->session);
326  if (err != MFX_ERR_NONE)
327  return AVERROR_UNKNOWN;
328  }
329 
330  memset(&par, 0, sizeof(par));
331 
332  if (opaque) {
333  s->surface_ptrs_in = av_mallocz_array(in_frames_hwctx->nb_surfaces,
334  sizeof(*s->surface_ptrs_in));
335  if (!s->surface_ptrs_in)
336  return AVERROR(ENOMEM);
337  for (i = 0; i < in_frames_hwctx->nb_surfaces; i++)
338  s->surface_ptrs_in[i] = in_frames_hwctx->surfaces + i;
339  s->nb_surface_ptrs_in = in_frames_hwctx->nb_surfaces;
340 
341  s->surface_ptrs_out = av_mallocz_array(out_frames_hwctx->nb_surfaces,
342  sizeof(*s->surface_ptrs_out));
343  if (!s->surface_ptrs_out)
344  return AVERROR(ENOMEM);
345  for (i = 0; i < out_frames_hwctx->nb_surfaces; i++)
346  s->surface_ptrs_out[i] = out_frames_hwctx->surfaces + i;
347  s->nb_surface_ptrs_out = out_frames_hwctx->nb_surfaces;
348 
349  s->opaque_alloc.In.Surfaces = s->surface_ptrs_in;
350  s->opaque_alloc.In.NumSurface = s->nb_surface_ptrs_in;
351  s->opaque_alloc.In.Type = in_frames_hwctx->frame_type;
352 
353  s->opaque_alloc.Out.Surfaces = s->surface_ptrs_out;
354  s->opaque_alloc.Out.NumSurface = s->nb_surface_ptrs_out;
355  s->opaque_alloc.Out.Type = out_frames_hwctx->frame_type;
356 
357  s->opaque_alloc.Header.BufferId = MFX_EXTBUFF_OPAQUE_SURFACE_ALLOCATION;
358  s->opaque_alloc.Header.BufferSz = sizeof(s->opaque_alloc);
359 
360  s->ext_buffers[0] = (mfxExtBuffer*)&s->opaque_alloc;
361 
362  par.ExtParam = s->ext_buffers;
363  par.NumExtParam = FF_ARRAY_ELEMS(s->ext_buffers);
364 
365  par.IOPattern = MFX_IOPATTERN_IN_OPAQUE_MEMORY | MFX_IOPATTERN_OUT_OPAQUE_MEMORY;
366  } else {
367  mfxFrameAllocator frame_allocator = {
368  .pthis = ctx,
369  .Alloc = frame_alloc,
370  .Lock = frame_lock,
371  .Unlock = frame_unlock,
372  .GetHDL = frame_get_hdl,
373  .Free = frame_free,
374  };
375 
376  s->mem_ids_in = av_mallocz_array(in_frames_hwctx->nb_surfaces,
377  sizeof(*s->mem_ids_in));
378  if (!s->mem_ids_in)
379  return AVERROR(ENOMEM);
380  for (i = 0; i < in_frames_hwctx->nb_surfaces; i++)
381  s->mem_ids_in[i] = in_frames_hwctx->surfaces[i].Data.MemId;
382  s->nb_mem_ids_in = in_frames_hwctx->nb_surfaces;
383 
384  s->mem_ids_out = av_mallocz_array(out_frames_hwctx->nb_surfaces,
385  sizeof(*s->mem_ids_out));
386  if (!s->mem_ids_out)
387  return AVERROR(ENOMEM);
388  for (i = 0; i < out_frames_hwctx->nb_surfaces; i++)
389  s->mem_ids_out[i] = out_frames_hwctx->surfaces[i].Data.MemId;
390  s->nb_mem_ids_out = out_frames_hwctx->nb_surfaces;
391 
392  err = MFXVideoCORE_SetFrameAllocator(s->session, &frame_allocator);
393  if (err != MFX_ERR_NONE)
394  return AVERROR_UNKNOWN;
395 
396  par.IOPattern = MFX_IOPATTERN_IN_VIDEO_MEMORY | MFX_IOPATTERN_OUT_VIDEO_MEMORY;
397  }
398 
399  par.AsyncDepth = 1; // TODO async
400 
401  par.vpp.In = in_frames_hwctx->surfaces[0].Info;
402  par.vpp.Out = out_frames_hwctx->surfaces[0].Info;
403 
404  /* Apparently VPP requires the frame rate to be set to some value, otherwise
405  * init will fail (probably for the framerate conversion filter). Since we
406  * are only doing scaling here, we just invent an arbitrary
407  * value */
408  par.vpp.In.FrameRateExtN = 25;
409  par.vpp.In.FrameRateExtD = 1;
410  par.vpp.Out.FrameRateExtN = 25;
411  par.vpp.Out.FrameRateExtD = 1;
412 
413  err = MFXVideoVPP_Init(s->session, &par);
414  if (err != MFX_ERR_NONE) {
415  av_log(ctx, AV_LOG_ERROR, "Error opening the VPP for scaling\n");
416  return AVERROR_UNKNOWN;
417  }
418 
419  return 0;
420 }
421 
422 static int init_scale_session(AVFilterContext *ctx, int in_width, int in_height,
423  int out_width, int out_height)
424 {
425  int ret;
426 
427  qsvscale_uninit(ctx);
428 
429  ret = init_out_pool(ctx, out_width, out_height);
430  if (ret < 0)
431  return ret;
432 
433  ret = init_out_session(ctx);
434  if (ret < 0)
435  return ret;
436 
437  return 0;
438 }
439 
441 {
442  AVFilterContext *ctx = outlink->src;
443  AVFilterLink *inlink = outlink->src->inputs[0];
444  QSVScaleContext *s = ctx->priv;
445  int64_t w, h;
446  double var_values[VARS_NB], res;
447  char *expr;
448  int ret;
449 
450  var_values[VAR_PI] = M_PI;
451  var_values[VAR_PHI] = M_PHI;
452  var_values[VAR_E] = M_E;
453  var_values[VAR_IN_W] = var_values[VAR_IW] = inlink->w;
454  var_values[VAR_IN_H] = var_values[VAR_IH] = inlink->h;
455  var_values[VAR_OUT_W] = var_values[VAR_OW] = NAN;
456  var_values[VAR_OUT_H] = var_values[VAR_OH] = NAN;
457  var_values[VAR_A] = (double) inlink->w / inlink->h;
458  var_values[VAR_SAR] = inlink->sample_aspect_ratio.num ?
459  (double) inlink->sample_aspect_ratio.num / inlink->sample_aspect_ratio.den : 1;
460  var_values[VAR_DAR] = var_values[VAR_A] * var_values[VAR_SAR];
461 
462  /* evaluate width and height */
463  av_expr_parse_and_eval(&res, (expr = s->w_expr),
464  var_names, var_values,
465  NULL, NULL, NULL, NULL, NULL, 0, ctx);
466  s->w = var_values[VAR_OUT_W] = var_values[VAR_OW] = res;
467  if ((ret = av_expr_parse_and_eval(&res, (expr = s->h_expr),
468  var_names, var_values,
469  NULL, NULL, NULL, NULL, NULL, 0, ctx)) < 0)
470  goto fail;
471  s->h = var_values[VAR_OUT_H] = var_values[VAR_OH] = res;
472  /* evaluate again the width, as it may depend on the output height */
473  if ((ret = av_expr_parse_and_eval(&res, (expr = s->w_expr),
474  var_names, var_values,
475  NULL, NULL, NULL, NULL, NULL, 0, ctx)) < 0)
476  goto fail;
477  s->w = res;
478 
479  w = s->w;
480  h = s->h;
481 
482  /* sanity check params */
483  if (w < -1 || h < -1) {
484  av_log(ctx, AV_LOG_ERROR, "Size values less than -1 are not acceptable.\n");
485  return AVERROR(EINVAL);
486  }
487  if (w == -1 && h == -1)
488  s->w = s->h = 0;
489 
490  if (!(w = s->w))
491  w = inlink->w;
492  if (!(h = s->h))
493  h = inlink->h;
494  if (w == -1)
495  w = av_rescale(h, inlink->w, inlink->h);
496  if (h == -1)
497  h = av_rescale(w, inlink->h, inlink->w);
498 
499  if (w > INT_MAX || h > INT_MAX ||
500  (h * inlink->w) > INT_MAX ||
501  (w * inlink->h) > INT_MAX)
502  av_log(ctx, AV_LOG_ERROR, "Rescaled value for width or height is too big.\n");
503 
504  outlink->w = w;
505  outlink->h = h;
506 
507  ret = init_scale_session(ctx, inlink->w, inlink->h, w, h);
508  if (ret < 0)
509  return ret;
510 
511  av_log(ctx, AV_LOG_VERBOSE, "w:%d h:%d -> w:%d h:%d\n",
512  inlink->w, inlink->h, outlink->w, outlink->h);
513 
514  if (inlink->sample_aspect_ratio.num)
515  outlink->sample_aspect_ratio = av_mul_q((AVRational){outlink->h*inlink->w,
516  outlink->w*inlink->h},
517  inlink->sample_aspect_ratio);
518  else
519  outlink->sample_aspect_ratio = inlink->sample_aspect_ratio;
520 
521  return 0;
522 
523 fail:
525  "Error when evaluating the expression '%s'\n", expr);
526  return ret;
527 }
528 
530 {
531  AVFilterContext *ctx = link->dst;
532  QSVScaleContext *s = ctx->priv;
533  AVFilterLink *outlink = ctx->outputs[0];
534 
535  mfxSyncPoint sync = NULL;
536  mfxStatus err;
537 
538  AVFrame *out = NULL;
539  int ret = 0;
540 
541  out = ff_get_video_buffer(outlink, outlink->w, outlink->h);
542  if (!out) {
543  ret = AVERROR(ENOMEM);
544  goto fail;
545  }
546 
547  do {
548  err = MFXVideoVPP_RunFrameVPPAsync(s->session,
549  (mfxFrameSurface1*)in->data[3],
550  (mfxFrameSurface1*)out->data[3],
551  NULL, &sync);
552  if (err == MFX_WRN_DEVICE_BUSY)
553  av_usleep(1);
554  } while (err == MFX_WRN_DEVICE_BUSY);
555 
556  if (err < 0 || !sync) {
557  av_log(ctx, AV_LOG_ERROR, "Error during scaling\n");
558  ret = AVERROR_UNKNOWN;
559  goto fail;
560  }
561 
562  do {
563  err = MFXVideoCORE_SyncOperation(s->session, sync, 1000);
564  } while (err == MFX_WRN_IN_EXECUTION);
565  if (err < 0) {
566  av_log(ctx, AV_LOG_ERROR, "Error synchronizing the operation: %d\n", err);
567  ret = AVERROR_UNKNOWN;
568  goto fail;
569  }
570 
571  ret = av_frame_copy_props(out, in);
572  if (ret < 0)
573  goto fail;
574 
575  out->width = outlink->w;
576  out->height = outlink->h;
577 
579  (int64_t)in->sample_aspect_ratio.num * outlink->h * link->w,
580  (int64_t)in->sample_aspect_ratio.den * outlink->w * link->h,
581  INT_MAX);
582 
583  av_frame_free(&in);
584  return ff_filter_frame(outlink, out);
585 fail:
586  av_frame_free(&in);
587  av_frame_free(&out);
588  return ret;
589 }
590 
591 #define OFFSET(x) offsetof(QSVScaleContext, x)
592 #define FLAGS AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_FILTERING_PARAM
593 static const AVOption options[] = {
594  { "w", "Output video width", OFFSET(w_expr), AV_OPT_TYPE_STRING, { .str = "iw" }, .flags = FLAGS },
595  { "h", "Output video height", OFFSET(h_expr), AV_OPT_TYPE_STRING, { .str = "ih" }, .flags = FLAGS },
596  { "format", "Output pixel format", OFFSET(format_str), AV_OPT_TYPE_STRING, { .str = "same" }, .flags = FLAGS },
597 
598  { NULL },
599 };
600 
601 static const AVClass qsvscale_class = {
602  .class_name = "qsvscale",
603  .item_name = av_default_item_name,
604  .option = options,
605  .version = LIBAVUTIL_VERSION_INT,
606 };
607 
608 static const AVFilterPad qsvscale_inputs[] = {
609  {
610  .name = "default",
611  .type = AVMEDIA_TYPE_VIDEO,
612  .filter_frame = qsvscale_filter_frame,
613  },
614  { NULL }
615 };
616 
617 static const AVFilterPad qsvscale_outputs[] = {
618  {
619  .name = "default",
620  .type = AVMEDIA_TYPE_VIDEO,
621  .config_props = qsvscale_config_props,
622  },
623  { NULL }
624 };
625 
627  .name = "scale_qsv",
628  .description = NULL_IF_CONFIG_SMALL("QuickSync video scaling and format conversion"),
629 
630  .init = qsvscale_init,
631  .uninit = qsvscale_uninit,
632  .query_formats = qsvscale_query_formats,
633 
634  .priv_size = sizeof(QSVScaleContext),
635  .priv_class = &qsvscale_class,
636 
637  .inputs = qsvscale_inputs,
638  .outputs = qsvscale_outputs,
639 
640  .flags_internal = FF_FILTER_FLAG_HWFRAME_AWARE,
641 };
static const AVClass qsvscale_class
Definition: vf_scale_qsv.c:601
#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 mfxStatus frame_alloc(mfxHDL pthis, mfxFrameAllocRequest *req, mfxFrameAllocResponse *resp)
Definition: vf_scale_qsv.c:219
This structure describes decoded (raw) audio or video data.
Definition: frame.h:268
enum AVPixelFormat format
Output sw format.
Definition: vf_scale_qsv.c:105
AVOption.
Definition: opt.h:246
int frame_type
A combination of MFX_MEMTYPE_* describing the frame pool.
Definition: hwcontext_qsv.h:49
#define LIBAVUTIL_VERSION_INT
Definition: version.h:85
Main libavfilter public API header.
#define OFFSET(x)
Definition: vf_scale_qsv.c:591
mfxHandleType handle_type
Definition: hwcontext_qsv.c:85
This struct is allocated as AVHWFramesContext.hwctx.
Definition: hwcontext_qsv.h:42
int num
Numerator.
Definition: rational.h:59
const char * av_default_item_name(void *ptr)
Return the context name.
Definition: log.c:191
int width
The allocated dimensions of the frames in this pool.
Definition: hwcontext.h:228
#define QSV_RUNTIME_VERSION_ATLEAST(MFX_VERSION, MAJOR, MINOR)
Definition: qsv_internal.h:41
enum AVPixelFormat format
The pixel format identifying the underlying HW surface type.
Definition: hwcontext.h:208
int av_usleep(unsigned usec)
Sleep for a period of time.
Definition: time.c:84
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
static int qsvscale_query_formats(AVFilterContext *ctx)
Definition: vf_scale_qsv.c:149
AVFilterFormats * ff_make_format_list(const int *fmts)
Create a list of supported formats.
Definition: formats.c:283
const char * name
Pad name.
Definition: internal.h:60
const char * class_name
The name of the class; usually it is the same name as the context structure type to which the AVClass...
Definition: log.h:72
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
AVOptions.
void * hwctx
The format-specific data, allocated and freed by libavutil along with this context.
Definition: hwcontext.h:91
#define AV_LOG_VERBOSE
Detailed information.
Definition: log.h:192
static mfxStatus frame_free(mfxHDL pthis, mfxFrameAllocResponse *resp)
Definition: vf_scale_qsv.c:241
static mfxStatus frame_unlock(mfxHDL pthis, mfxMemId mid, mfxFrameData *ptr)
Definition: vf_scale_qsv.c:251
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
static int qsvscale_config_props(AVFilterLink *outlink)
Definition: vf_scale_qsv.c:440
AVFilter ff_vf_scale_qsv
Definition: vf_scale_qsv.c:626
#define FFALIGN(x, a)
Definition: macros.h:48
#define av_log(a,...)
static const AVFilterPad qsvscale_outputs[]
Definition: vf_scale_qsv.c:617
mfxExtOpaqueSurfaceAlloc opaque_alloc
Definition: vf_scale_qsv.c:90
This struct is allocated as AVHWDeviceContext.hwctx.
Definition: hwcontext_qsv.h:35
A filter pad used for either input or output.
Definition: internal.h:54
int av_expr_parse_and_eval(double *d, const char *s, const char *const *const_names, const double *const_values, const char *const *func1_names, double(*const *funcs1)(void *, double), const char *const *func2_names, double(*const *funcs2)(void *, double, double), void *opaque, int log_offset, void *log_ctx)
Parse and evaluate an expression.
Definition: eval.c:744
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:260
static const AVOption options[]
Definition: vf_scale_qsv.c:593
int width
Definition: frame.h:326
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:176
int ff_set_common_formats(AVFilterContext *ctx, AVFilterFormats *formats)
A helper for query_formats() which sets all links to the same list of formats.
Definition: formats.c:568
mfxMemId * mem_ids_in
Definition: vf_scale_qsv.c:78
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition: frame.c:202
#define M_E
Definition: mathematics.h:37
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification. ...
Definition: internal.h:186
static int qsvscale_filter_frame(AVFilterLink *link, AVFrame *in)
Definition: vf_scale_qsv.c:529
void * priv
private data for use by the filter
Definition: avfilter.h:353
static av_cold void qsvscale_uninit(AVFilterContext *ctx)
Definition: vf_scale_qsv.c:129
int av_hwframe_ctx_init(AVBufferRef *ref)
Finalize the context before use.
Definition: hwcontext.c:329
#define fail()
Definition: checkasm.h:120
var_name
Definition: aeval.c:46
static int init_scale_session(AVFilterContext *ctx, int in_width, int in_height, int out_width, int out_height)
Definition: vf_scale_qsv.c:422
common internal API header
int initial_pool_size
Initial size of the frame pool.
Definition: hwcontext.h:198
MIPS optimizations info
Definition: mips.txt:2
int64_t av_rescale(int64_t a, int64_t b, int64_t c)
Rescale a 64-bit integer with rounding to nearest.
Definition: mathematics.c:129
#define NAN
Definition: mathematics.h:64
AVHWDeviceContext * device_ctx
The parent AVHWDeviceContext.
Definition: hwcontext.h:148
static mfxStatus frame_get_hdl(mfxHDL pthis, mfxMemId mid, mfxHDL *hdl)
Definition: vf_scale_qsv.c:256
static int init_out_session(AVFilterContext *ctx)
Definition: vf_scale_qsv.c:268
AVFormatContext * ctx
Definition: movenc.c:48
#define s(width, name)
Definition: cbs_vp9.c:257
int w
New dimensions.
Definition: vf_scale_qsv.c:100
static const AVFilterPad outputs[]
Definition: af_acontrast.c:203
#define FF_ARRAY_ELEMS(a)
mfxSession session
Definition: hwcontext_qsv.h:36
mfxFrameSurface1 * surfaces
Definition: hwcontext_qsv.h:43
uint8_t * data
The data buffer.
Definition: buffer.h:89
AVRational sample_aspect_ratio
Sample aspect ratio for the video frame, 0/1 if unknown/unspecified.
Definition: frame.h:356
void * hwctx
The format-specific data, allocated and freed automatically along with this context.
Definition: hwcontext.h:161
these buffered frames must be flushed immediately if a new input produces new the filter must not call request_frame to get more It must just process the frame or queue it The task of requesting more frames is left to the filter s request_frame method or the application If a filter has several inputs
uint8_t pi<< 24) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_U8, uint8_t,(*(const uint8_t *) pi-0x80)*(1.0f/(1<< 7))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_U8, uint8_t,(*(const uint8_t *) pi-0x80)*(1.0/(1<< 7))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S16, int16_t,(*(const int16_t *) pi >> 8)+0x80) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S16, int16_t,*(const int16_t *) pi *(1.0f/(1<< 15))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S16, int16_t,*(const int16_t *) pi *(1.0/(1<< 15))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S32, int32_t,(*(const int32_t *) pi >> 24)+0x80) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S32, int32_t,*(const int32_t *) pi *(1.0f/(1U<< 31))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S32, int32_t,*(const int32_t *) pi *(1.0/(1U<< 31))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_FLT, float, av_clip_uint8(lrintf(*(const float *) pi *(1<< 7))+0x80)) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_FLT, float, av_clip_int16(lrintf(*(const float *) pi *(1<< 15)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_FLT, float, av_clipl_int32(llrintf(*(const float *) pi *(1U<< 31)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_DBL, double, av_clip_uint8(lrint(*(const double *) pi *(1<< 7))+0x80)) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_DBL, double, av_clip_int16(lrint(*(const double *) pi *(1<< 15)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_DBL, double, av_clipl_int32(llrint(*(const double *) pi *(1U<< 31))))#define SET_CONV_FUNC_GROUP(ofmt, ifmt) static void set_generic_function(AudioConvert *ac){}void ff_audio_convert_free(AudioConvert **ac){if(!*ac) return;ff_dither_free(&(*ac) ->dc);av_freep(ac);}AudioConvert *ff_audio_convert_alloc(AVAudioResampleContext *avr, enum AVSampleFormat out_fmt, enum AVSampleFormat in_fmt, int channels, int sample_rate, int apply_map){AudioConvert *ac;int in_planar, out_planar;ac=av_mallocz(sizeof(*ac));if(!ac) return NULL;ac->avr=avr;ac->out_fmt=out_fmt;ac->in_fmt=in_fmt;ac->channels=channels;ac->apply_map=apply_map;if(avr->dither_method!=AV_RESAMPLE_DITHER_NONE &&av_get_packed_sample_fmt(out_fmt)==AV_SAMPLE_FMT_S16 &&av_get_bytes_per_sample(in_fmt) > 2){ac->dc=ff_dither_alloc(avr, out_fmt, in_fmt, channels, sample_rate, apply_map);if(!ac->dc){av_free(ac);return NULL;}return ac;}in_planar=ff_sample_fmt_is_planar(in_fmt, channels);out_planar=ff_sample_fmt_is_planar(out_fmt, channels);if(in_planar==out_planar){ac->func_type=CONV_FUNC_TYPE_FLAT;ac->planes=in_planar?ac->channels:1;}else if(in_planar) ac->func_type=CONV_FUNC_TYPE_INTERLEAVE;else ac->func_type=CONV_FUNC_TYPE_DEINTERLEAVE;set_generic_function(ac);if(ARCH_AARCH64) ff_audio_convert_init_aarch64(ac);if(ARCH_ARM) ff_audio_convert_init_arm(ac);if(ARCH_X86) ff_audio_convert_init_x86(ac);return ac;}int ff_audio_convert(AudioConvert *ac, AudioData *out, AudioData *in){int use_generic=1;int len=in->nb_samples;int p;if(ac->dc){av_log(ac->avr, AV_LOG_TRACE,"%d samples - audio_convert: %s to %s (dithered)\n", len, av_get_sample_fmt_name(ac->in_fmt), av_get_sample_fmt_name(ac->out_fmt));return ff_convert_dither(ac-> in
Describe the class of an AVClass context structure.
Definition: log.h:67
Filter definition.
Definition: avfilter.h:144
Rational number (pair of numerator and denominator).
Definition: rational.h:58
This struct describes a set or pool of "hardware" frames (i.e.
Definition: hwcontext.h:123
#define M_PHI
Definition: mathematics.h:49
HW acceleration through QSV, data[3] contains a pointer to the mfxFrameSurface1 structure.
Definition: pixfmt.h:222
const char * name
Filter name.
Definition: avfilter.h:148
static const AVFilterPad qsvscale_inputs[]
Definition: vf_scale_qsv.c:608
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a link
mfxFrameSurface1 ** surface_ptrs_in
Definition: vf_scale_qsv.c:84
static av_cold int qsvscale_init(AVFilterContext *ctx)
Definition: vf_scale_qsv.c:112
AVFilterLink ** outputs
array of pointers to output links
Definition: avfilter.h:350
mfxSession session
Definition: vf_scale_qsv.c:76
static enum AVPixelFormat pix_fmts[]
Definition: libkvazaar.c:275
mfxFrameSurface1 ** surface_ptrs_out
Definition: vf_scale_qsv.c:87
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition: frame.h:282
AVBufferRef * device_ref
A reference to the parent AVHWDeviceContext.
Definition: hwcontext.h:140
The exact code depends on how similar the blocks are and how related they are to the and needs to apply these operations to the correct inlink or outlink if there are several Macros are available to factor that when no extra processing is inlink
common internal and external API header
AVBufferRef * av_hwframe_ctx_alloc(AVBufferRef *device_ref_in)
Allocate an AVHWFramesContext tied to a given device context.
Definition: hwcontext.c:243
mfxMemId * mem_ids_out
Definition: vf_scale_qsv.c:81
int ff_filter_init_hw_frames(AVFilterContext *avctx, AVFilterLink *link, int default_pool_size)
Perform any additional setup required for hardware frames.
Definition: avfilter.c:1640
int den
Denominator.
Definition: rational.h:60
#define AVERROR_UNKNOWN
Unknown error, typically from an external library.
Definition: error.h:71
static int init_out_pool(AVFilterContext *ctx, int out_width, int out_height)
Definition: vf_scale_qsv.c:163
static const mfxHandleType handle_types[]
Definition: vf_scale_qsv.c:262
mfxExtBuffer * ext_buffers[1]
Definition: vf_scale_qsv.c:91
char * h_expr
height expression string
Definition: vf_scale_qsv.c:108
A list of supported formats for one end of a filter link.
Definition: formats.h:64
static mfxStatus frame_lock(mfxHDL pthis, mfxMemId mid, mfxFrameData *ptr)
Definition: vf_scale_qsv.c:246
An instance of a filter.
Definition: avfilter.h:338
AVRational av_mul_q(AVRational b, AVRational c)
Multiply two rationals.
Definition: rational.c:80
Intel Quick Sync Video VPP base function.
int height
Definition: frame.h:326
FILE * out
Definition: movenc.c:54
#define av_freep(p)
static const char *const var_names[]
Definition: vf_scale_qsv.c:46
An API-specific header for AV_HWDEVICE_TYPE_QSV.
#define M_PI
Definition: mathematics.h:52
char * w_expr
width expression string
Definition: vf_scale_qsv.c:107
enum AVPixelFormat av_get_pix_fmt(const char *name)
Return the pixel format corresponding to name.
Definition: pixdesc.c:2450
internal API functions
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later.That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another.Frame references ownership and permissions
#define FLAGS
Definition: vf_scale_qsv.c:592
enum AVPixelFormat sw_format
The pixel format identifying the actual data layout of the hardware frames.
Definition: hwcontext.h:221
AVPixelFormat
Pixel format.
Definition: pixfmt.h:64
int av_frame_copy_props(AVFrame *dst, const AVFrame *src)
Copy only "metadata" fields from src to dst.
Definition: frame.c:654
simple arithmetic expression evaluator
void * av_mallocz_array(size_t nmemb, size_t size)
Definition: mem.c:191