FFmpeg
hwcontext_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 #include <stdatomic.h>
20 #include <stdint.h>
21 #include <string.h>
22 
23 #include <mfxvideo.h>
24 
25 #include "config.h"
26 
27 #if HAVE_PTHREADS
28 #include <pthread.h>
29 #endif
30 
31 #define COBJMACROS
32 #if CONFIG_VAAPI
33 #include "hwcontext_vaapi.h"
34 #endif
35 #if CONFIG_D3D11VA
36 #include "hwcontext_d3d11va.h"
37 #endif
38 #if CONFIG_DXVA2
39 #include <initguid.h>
40 #include "hwcontext_dxva2.h"
41 #endif
42 
43 #include "buffer.h"
44 #include "common.h"
45 #include "hwcontext.h"
46 #include "hwcontext_internal.h"
47 #include "hwcontext_qsv.h"
48 #include "mem.h"
49 #include "pixfmt.h"
50 #include "pixdesc.h"
51 #include "time.h"
52 #include "imgutils.h"
53 #include "avassert.h"
54 
55 #define QSV_VERSION_ATLEAST(MAJOR, MINOR) \
56  (MFX_VERSION_MAJOR > (MAJOR) || \
57  MFX_VERSION_MAJOR == (MAJOR) && MFX_VERSION_MINOR >= (MINOR))
58 
59 #define QSV_RUNTIME_VERSION_ATLEAST(MFX_VERSION, MAJOR, MINOR) \
60  ((MFX_VERSION.Major > (MAJOR)) || \
61  (MFX_VERSION.Major == (MAJOR) && MFX_VERSION.Minor >= (MINOR)))
62 
63 #define MFX_IMPL_VIA_MASK(impl) (0x0f00 & (impl))
64 #define QSV_ONEVPL QSV_VERSION_ATLEAST(2, 0)
65 #define QSV_HAVE_OPAQUE !QSV_ONEVPL
66 
67 #if QSV_ONEVPL
68 #include <mfxdispatcher.h>
69 #else
70 #define MFXUnload(a) do { } while(0)
71 #endif
72 
73 typedef struct QSVDevicePriv {
76 
77 typedef struct QSVDeviceContext {
78  /**
79  * The public AVQSVDeviceContext. See hwcontext_qsv.h for it.
80  */
82 
83  mfxHDL handle;
84  mfxHandleType handle_type;
85  mfxVersion ver;
86  mfxIMPL impl;
87 
91 
92 typedef struct QSVFramesContext {
93  /**
94  * The public AVQSVFramesContext. See hwcontext_qsv.h for it.
95  */
97 
98  mfxSession session_download;
100  mfxSession session_upload;
102 #if HAVE_PTHREADS
103  pthread_mutex_t session_lock;
104 #endif
105 
107  mfxFrameSurface1 *surfaces_internal;
110 
111  // used in the frame allocator for non-opaque surfaces
112  mfxMemId *mem_ids;
113 #if QSV_HAVE_OPAQUE
114  // used in the opaque alloc request for opaque surfaces
115  mfxFrameSurface1 **surface_ptrs;
116 
117  mfxExtOpaqueSurfaceAlloc opaque_alloc;
118  mfxExtBuffer *ext_buffers[1];
119 #endif
123 
124 static const struct {
126  uint32_t fourcc;
127  uint16_t mfx_shift;
129  { AV_PIX_FMT_NV12, MFX_FOURCC_NV12, 0 },
130  { AV_PIX_FMT_BGRA, MFX_FOURCC_RGB4, 0 },
131  { AV_PIX_FMT_P010, MFX_FOURCC_P010, 1 },
132  { AV_PIX_FMT_PAL8, MFX_FOURCC_P8, 0 },
134  MFX_FOURCC_YUY2, 0 },
135 #if CONFIG_VAAPI
137  MFX_FOURCC_UYVY, 0 },
138 #endif
139  { AV_PIX_FMT_Y210,
140  MFX_FOURCC_Y210, 1 },
141  // VUYX is used for VAAPI child device,
142  // the SDK only delares support for AYUV
143  { AV_PIX_FMT_VUYX,
144  MFX_FOURCC_AYUV, 0 },
145  // XV30 is used for VAAPI child device,
146  // the SDK only delares support for Y410
147  { AV_PIX_FMT_XV30,
148  MFX_FOURCC_Y410, 0 },
149 #if QSV_VERSION_ATLEAST(1, 31)
150  // P012 is used for VAAPI child device,
151  // the SDK only delares support for P016
152  { AV_PIX_FMT_P012,
153  MFX_FOURCC_P016, 1 },
154  // Y212 is used for VAAPI child device,
155  // the SDK only delares support for Y216
156  { AV_PIX_FMT_Y212,
157  MFX_FOURCC_Y216, 1 },
158  // XV36 is used for VAAPI child device,
159  // the SDK only delares support for Y416
160  { AV_PIX_FMT_XV36,
161  MFX_FOURCC_Y416, 1 },
162 #endif
163 };
164 
165 extern int ff_qsv_get_surface_base_handle(mfxFrameSurface1 *surf,
166  enum AVHWDeviceType base_dev_type,
167  void **base_handle);
168 
169 /**
170  * Caller needs to allocate enough space for base_handle pointer.
171  **/
172 int ff_qsv_get_surface_base_handle(mfxFrameSurface1 *surf,
173  enum AVHWDeviceType base_dev_type,
174  void **base_handle)
175 {
176  mfxHDLPair *handle_pair;
177  handle_pair = surf->Data.MemId;
178  switch (base_dev_type) {
179 #if CONFIG_VAAPI
181  base_handle[0] = handle_pair->first;
182  return 0;
183 #endif
184 #if CONFIG_D3D11VA
186  base_handle[0] = handle_pair->first;
187  base_handle[1] = handle_pair->second;
188  return 0;
189 #endif
190 #if CONFIG_DXVA2
192  base_handle[0] = handle_pair->first;
193  return 0;
194 #endif
195  }
196  return AVERROR(EINVAL);
197 }
198 
200 {
201  int i;
202  for (i = 0; i < FF_ARRAY_ELEMS(supported_pixel_formats); i++) {
204  return supported_pixel_formats[i].fourcc;
205  }
206  return 0;
207 }
208 
210 {
211  for (int i = 0; i < FF_ARRAY_ELEMS(supported_pixel_formats); i++) {
213  return supported_pixel_formats[i].mfx_shift;
214  }
215 
216  return 0;
217 }
218 
219 #if CONFIG_D3D11VA
220 static uint32_t qsv_get_d3d11va_bind_flags(int mem_type)
221 {
222  uint32_t bind_flags = 0;
223 
224  if ((mem_type & MFX_MEMTYPE_VIDEO_MEMORY_ENCODER_TARGET) && (mem_type & MFX_MEMTYPE_INTERNAL_FRAME))
225  bind_flags = D3D11_BIND_DECODER | D3D11_BIND_VIDEO_ENCODER;
226  else
227  bind_flags = D3D11_BIND_DECODER;
228 
229  if ((MFX_MEMTYPE_FROM_VPPOUT & mem_type) || (MFX_MEMTYPE_VIDEO_MEMORY_PROCESSOR_TARGET & mem_type))
230  bind_flags = D3D11_BIND_RENDER_TARGET;
231 
232  return bind_flags;
233 }
234 #endif
235 
236 static int qsv_fill_border(AVFrame *dst, const AVFrame *src)
237 {
238  const AVPixFmtDescriptor *desc;
239  int i, planes_nb = 0;
240  if (dst->format != src->format)
241  return AVERROR(EINVAL);
242 
244 
245  for (i = 0; i < desc->nb_components; i++)
246  planes_nb = FFMAX(planes_nb, desc->comp[i].plane + 1);
247 
248  for (i = 0; i < planes_nb; i++) {
249  int sheight, dheight, y;
250  ptrdiff_t swidth = av_image_get_linesize(src->format,
251  src->width,
252  i);
253  ptrdiff_t dwidth = av_image_get_linesize(dst->format,
254  dst->width,
255  i);
256  const AVComponentDescriptor comp = desc->comp[i];
257  if (swidth < 0 || dwidth < 0) {
258  av_log(NULL, AV_LOG_ERROR, "av_image_get_linesize failed\n");
259  return AVERROR(EINVAL);
260  }
261  sheight = src->height;
262  dheight = dst->height;
263  if (i) {
264  sheight = AV_CEIL_RSHIFT(src->height, desc->log2_chroma_h);
265  dheight = AV_CEIL_RSHIFT(dst->height, desc->log2_chroma_h);
266  }
267  //fill right padding
268  for (y = 0; y < sheight; y++) {
269  void *line_ptr = dst->data[i] + y*dst->linesize[i] + swidth;
270  av_memcpy_backptr(line_ptr,
271  comp.depth > 8 ? 2 : 1,
272  dwidth - swidth);
273  }
274  //fill bottom padding
275  for (y = sheight; y < dheight; y++) {
276  memcpy(dst->data[i]+y*dst->linesize[i],
277  dst->data[i]+(sheight-1)*dst->linesize[i],
278  dwidth);
279  }
280  }
281  return 0;
282 }
283 
285 {
286  QSVDeviceContext *s = ctx->hwctx;
287  AVQSVDeviceContext *hwctx = &s->p;
288  int hw_handle_supported = 0;
289  mfxHandleType handle_type;
290  enum AVHWDeviceType device_type;
291  enum AVPixelFormat pix_fmt;
292  mfxStatus err;
293 
294  err = MFXQueryIMPL(hwctx->session, &s->impl);
295  if (err == MFX_ERR_NONE)
296  err = MFXQueryVersion(hwctx->session, &s->ver);
297  if (err != MFX_ERR_NONE) {
298  av_log(ctx, AV_LOG_ERROR, "Error querying the session attributes\n");
299  return AVERROR_UNKNOWN;
300  }
301 
302  if (MFX_IMPL_VIA_VAAPI == MFX_IMPL_VIA_MASK(s->impl)) {
303 #if CONFIG_VAAPI
304  handle_type = MFX_HANDLE_VA_DISPLAY;
305  device_type = AV_HWDEVICE_TYPE_VAAPI;
307  hw_handle_supported = 1;
308 #endif
309  } else if (MFX_IMPL_VIA_D3D11 == MFX_IMPL_VIA_MASK(s->impl)) {
310 #if CONFIG_D3D11VA
311  handle_type = MFX_HANDLE_D3D11_DEVICE;
312  device_type = AV_HWDEVICE_TYPE_D3D11VA;
314  hw_handle_supported = 1;
315 #endif
316  } else if (MFX_IMPL_VIA_D3D9 == MFX_IMPL_VIA_MASK(s->impl)) {
317 #if CONFIG_DXVA2
318  handle_type = MFX_HANDLE_D3D9_DEVICE_MANAGER;
319  device_type = AV_HWDEVICE_TYPE_DXVA2;
321  hw_handle_supported = 1;
322 #endif
323  }
324 
325  if (hw_handle_supported) {
326  err = MFXVideoCORE_GetHandle(hwctx->session, handle_type, &s->handle);
327  if (err == MFX_ERR_NONE) {
328  s->handle_type = handle_type;
329  s->child_device_type = device_type;
330  s->child_pix_fmt = pix_fmt;
331  }
332  }
333  if (!s->handle) {
334  av_log(ctx, AV_LOG_VERBOSE, "No supported hw handle could be retrieved "
335  "from the session\n");
336  }
337  return 0;
338 }
339 
341 {
342  QSVFramesContext *s = ctx->hwctx;
343 
344  if (s->session_download) {
345  MFXVideoVPP_Close(s->session_download);
346  MFXClose(s->session_download);
347  }
348  s->session_download = NULL;
349  s->session_download_init = 0;
350 
351  if (s->session_upload) {
352  MFXVideoVPP_Close(s->session_upload);
353  MFXClose(s->session_upload);
354  }
355  s->session_upload = NULL;
356  s->session_upload_init = 0;
357 
358 #if HAVE_PTHREADS
359  pthread_mutex_destroy(&s->session_lock);
360 #endif
361 
362  av_freep(&s->mem_ids);
363 #if QSV_HAVE_OPAQUE
364  av_freep(&s->surface_ptrs);
365 #endif
366  av_freep(&s->surfaces_internal);
367  av_freep(&s->handle_pairs_internal);
368  av_frame_unref(&s->realigned_upload_frame);
369  av_frame_unref(&s->realigned_download_frame);
370  av_buffer_unref(&s->child_frames_ref);
371 }
372 
373 static void qsv_pool_release_dummy(void *opaque, uint8_t *data)
374 {
375 }
376 
377 static AVBufferRef *qsv_pool_alloc(void *opaque, size_t size)
378 {
380  QSVFramesContext *s = ctx->hwctx;
381  AVQSVFramesContext *hwctx = &s->p;
382 
383  if (s->nb_surfaces_used < hwctx->nb_surfaces) {
384  s->nb_surfaces_used++;
385  return av_buffer_create((uint8_t*)(s->surfaces_internal + s->nb_surfaces_used - 1),
386  sizeof(*hwctx->surfaces), qsv_pool_release_dummy, NULL, 0);
387  }
388 
389  return NULL;
390 }
391 
393 {
394  QSVDeviceContext *device_priv = ctx->device_ctx->hwctx;
395  QSVFramesContext *s = ctx->hwctx;
396  AVQSVFramesContext *hwctx = &s->p;
397 
398  AVBufferRef *child_device_ref = NULL;
399  AVBufferRef *child_frames_ref = NULL;
400 
401  AVHWDeviceContext *child_device_ctx;
402  AVHWFramesContext *child_frames_ctx;
403 
404  int i, ret = 0;
405 
406  if (!device_priv->handle) {
408  "Cannot create a non-opaque internal surface pool without "
409  "a hardware handle\n");
410  return AVERROR(EINVAL);
411  }
412 
413  child_device_ref = av_hwdevice_ctx_alloc(device_priv->child_device_type);
414  if (!child_device_ref)
415  return AVERROR(ENOMEM);
416  child_device_ctx = (AVHWDeviceContext*)child_device_ref->data;
417 
418 #if CONFIG_VAAPI
419  if (child_device_ctx->type == AV_HWDEVICE_TYPE_VAAPI) {
420  AVVAAPIDeviceContext *child_device_hwctx = child_device_ctx->hwctx;
421  child_device_hwctx->display = (VADisplay)device_priv->handle;
422  }
423 #endif
424 #if CONFIG_D3D11VA
425  if (child_device_ctx->type == AV_HWDEVICE_TYPE_D3D11VA) {
426  AVD3D11VADeviceContext *child_device_hwctx = child_device_ctx->hwctx;
427  ID3D11Device_AddRef((ID3D11Device*)device_priv->handle);
428  child_device_hwctx->device = (ID3D11Device*)device_priv->handle;
429  }
430 #endif
431 #if CONFIG_DXVA2
432  if (child_device_ctx->type == AV_HWDEVICE_TYPE_DXVA2) {
433  AVDXVA2DeviceContext *child_device_hwctx = child_device_ctx->hwctx;
434  child_device_hwctx->devmgr = (IDirect3DDeviceManager9*)device_priv->handle;
435  }
436 #endif
437 
438  ret = av_hwdevice_ctx_init(child_device_ref);
439  if (ret < 0) {
440  av_log(ctx, AV_LOG_ERROR, "Error initializing a child device context\n");
441  goto fail;
442  }
443 
444  child_frames_ref = av_hwframe_ctx_alloc(child_device_ref);
445  if (!child_frames_ref) {
446  ret = AVERROR(ENOMEM);
447  goto fail;
448  }
449  child_frames_ctx = (AVHWFramesContext*)child_frames_ref->data;
450 
451  child_frames_ctx->format = device_priv->child_pix_fmt;
452  child_frames_ctx->sw_format = ctx->sw_format;
453  child_frames_ctx->initial_pool_size = ctx->initial_pool_size;
454  child_frames_ctx->width = FFALIGN(ctx->width, 16);
455  child_frames_ctx->height = FFALIGN(ctx->height, 16);
456 
457 #if CONFIG_D3D11VA
458  if (child_device_ctx->type == AV_HWDEVICE_TYPE_D3D11VA) {
459  AVD3D11VAFramesContext *child_frames_hwctx = child_frames_ctx->hwctx;
460  if (hwctx->frame_type == 0)
461  hwctx->frame_type = MFX_MEMTYPE_VIDEO_MEMORY_PROCESSOR_TARGET;
462  if (hwctx->frame_type & MFX_MEMTYPE_SHARED_RESOURCE)
463  child_frames_hwctx->MiscFlags = D3D11_RESOURCE_MISC_SHARED;
464  child_frames_hwctx->BindFlags = qsv_get_d3d11va_bind_flags(hwctx->frame_type);
465  }
466 #endif
467 #if CONFIG_DXVA2
468  if (child_device_ctx->type == AV_HWDEVICE_TYPE_DXVA2) {
469  AVDXVA2FramesContext *child_frames_hwctx = child_frames_ctx->hwctx;
470  if (hwctx->frame_type & MFX_MEMTYPE_VIDEO_MEMORY_PROCESSOR_TARGET)
471  child_frames_hwctx->surface_type = DXVA2_VideoProcessorRenderTarget;
472  else
473  child_frames_hwctx->surface_type = DXVA2_VideoDecoderRenderTarget;
474  }
475 #endif
476 
477  ret = av_hwframe_ctx_init(child_frames_ref);
478  if (ret < 0) {
479  av_log(ctx, AV_LOG_ERROR, "Error initializing a child frames context\n");
480  goto fail;
481  }
482 
483 #if CONFIG_VAAPI
484  if (child_device_ctx->type == AV_HWDEVICE_TYPE_VAAPI) {
485  AVVAAPIFramesContext *child_frames_hwctx = child_frames_ctx->hwctx;
486  for (i = 0; i < ctx->initial_pool_size; i++) {
487  s->handle_pairs_internal[i].first = child_frames_hwctx->surface_ids + i;
488  s->handle_pairs_internal[i].second = (mfxMemId)MFX_INFINITE;
489  s->surfaces_internal[i].Data.MemId = (mfxMemId)&s->handle_pairs_internal[i];
490  }
491  hwctx->frame_type = MFX_MEMTYPE_VIDEO_MEMORY_DECODER_TARGET;
492  }
493 #endif
494 #if CONFIG_D3D11VA
495  if (child_device_ctx->type == AV_HWDEVICE_TYPE_D3D11VA) {
496  AVD3D11VAFramesContext *child_frames_hwctx = child_frames_ctx->hwctx;
497  for (i = 0; i < ctx->initial_pool_size; i++) {
498  s->handle_pairs_internal[i].first = (mfxMemId)child_frames_hwctx->texture_infos[i].texture;
499  if(child_frames_hwctx->BindFlags & D3D11_BIND_RENDER_TARGET) {
500  s->handle_pairs_internal[i].second = (mfxMemId)MFX_INFINITE;
501  } else {
502  s->handle_pairs_internal[i].second = (mfxMemId)child_frames_hwctx->texture_infos[i].index;
503  }
504  s->surfaces_internal[i].Data.MemId = (mfxMemId)&s->handle_pairs_internal[i];
505  }
506  if (child_frames_hwctx->BindFlags & D3D11_BIND_RENDER_TARGET) {
507  hwctx->frame_type |= MFX_MEMTYPE_VIDEO_MEMORY_PROCESSOR_TARGET;
508  } else {
509  hwctx->frame_type |= MFX_MEMTYPE_VIDEO_MEMORY_DECODER_TARGET;
510  }
511  }
512 #endif
513 #if CONFIG_DXVA2
514  if (child_device_ctx->type == AV_HWDEVICE_TYPE_DXVA2) {
515  AVDXVA2FramesContext *child_frames_hwctx = child_frames_ctx->hwctx;
516  for (i = 0; i < ctx->initial_pool_size; i++) {
517  s->handle_pairs_internal[i].first = (mfxMemId)child_frames_hwctx->surfaces[i];
518  s->handle_pairs_internal[i].second = (mfxMemId)MFX_INFINITE;
519  s->surfaces_internal[i].Data.MemId = (mfxMemId)&s->handle_pairs_internal[i];
520  }
521  if (child_frames_hwctx->surface_type == DXVA2_VideoProcessorRenderTarget)
522  hwctx->frame_type = MFX_MEMTYPE_VIDEO_MEMORY_PROCESSOR_TARGET;
523  else
524  hwctx->frame_type = MFX_MEMTYPE_VIDEO_MEMORY_DECODER_TARGET;
525  }
526 #endif
527 
528  s->child_frames_ref = child_frames_ref;
529  child_frames_ref = NULL;
530 
531 fail:
532  av_buffer_unref(&child_device_ref);
533  av_buffer_unref(&child_frames_ref);
534  return ret;
535 }
536 
537 static int qsv_init_surface(AVHWFramesContext *ctx, mfxFrameSurface1 *surf)
538 {
539  const AVPixFmtDescriptor *desc;
540  uint32_t fourcc;
541 
542  desc = av_pix_fmt_desc_get(ctx->sw_format);
543  if (!desc)
544  return AVERROR(EINVAL);
545 
546  fourcc = qsv_fourcc_from_pix_fmt(ctx->sw_format);
547  if (!fourcc)
548  return AVERROR(EINVAL);
549 
550  surf->Info.BitDepthLuma = desc->comp[0].depth;
551  surf->Info.BitDepthChroma = desc->comp[0].depth;
552  surf->Info.Shift = qsv_shift_from_pix_fmt(ctx->sw_format);
553 
554  if (desc->log2_chroma_w && desc->log2_chroma_h)
555  surf->Info.ChromaFormat = MFX_CHROMAFORMAT_YUV420;
556  else if (desc->log2_chroma_w)
557  surf->Info.ChromaFormat = MFX_CHROMAFORMAT_YUV422;
558  else
559  surf->Info.ChromaFormat = MFX_CHROMAFORMAT_YUV444;
560 
561  surf->Info.FourCC = fourcc;
562  surf->Info.Width = FFALIGN(ctx->width, 16);
563  surf->Info.CropW = ctx->width;
564  surf->Info.Height = FFALIGN(ctx->height, 16);
565  surf->Info.CropH = ctx->height;
566  surf->Info.FrameRateExtN = 25;
567  surf->Info.FrameRateExtD = 1;
568  surf->Info.PicStruct = MFX_PICSTRUCT_PROGRESSIVE;
569 
570  return 0;
571 }
572 
574 {
575  QSVFramesContext *s = ctx->hwctx;
576  AVQSVFramesContext *frames_hwctx = &s->p;
577 
578  int i, ret = 0;
579 
580  if (ctx->initial_pool_size <= 0) {
581  av_log(ctx, AV_LOG_ERROR, "QSV requires a fixed frame pool size\n");
582  return AVERROR(EINVAL);
583  }
584 
585  s->handle_pairs_internal = av_calloc(ctx->initial_pool_size,
586  sizeof(*s->handle_pairs_internal));
587  if (!s->handle_pairs_internal)
588  return AVERROR(ENOMEM);
589 
590  s->surfaces_internal = av_calloc(ctx->initial_pool_size,
591  sizeof(*s->surfaces_internal));
592  if (!s->surfaces_internal)
593  return AVERROR(ENOMEM);
594 
595  for (i = 0; i < ctx->initial_pool_size; i++) {
596  ret = qsv_init_surface(ctx, &s->surfaces_internal[i]);
597  if (ret < 0)
598  return ret;
599  }
600 
601 #if QSV_HAVE_OPAQUE
602  if (!(frames_hwctx->frame_type & MFX_MEMTYPE_OPAQUE_FRAME)) {
604  if (ret < 0)
605  return ret;
606  }
607 #else
609  if (ret < 0)
610  return ret;
611 #endif
612 
613  ffhwframesctx(ctx)->pool_internal = av_buffer_pool_init2(sizeof(mfxFrameSurface1),
615  if (!ffhwframesctx(ctx)->pool_internal)
616  return AVERROR(ENOMEM);
617 
618  frames_hwctx->surfaces = s->surfaces_internal;
619  frames_hwctx->nb_surfaces = ctx->initial_pool_size;
620 
621  return 0;
622 }
623 
624 static mfxStatus frame_alloc(mfxHDL pthis, mfxFrameAllocRequest *req,
625  mfxFrameAllocResponse *resp)
626 {
627  AVHWFramesContext *ctx = pthis;
628  QSVFramesContext *s = ctx->hwctx;
629  AVQSVFramesContext *hwctx = &s->p;
630  mfxFrameInfo *i = &req->Info;
631  mfxFrameInfo *i1 = &hwctx->surfaces[0].Info;
632 
633  if (!(req->Type & MFX_MEMTYPE_VIDEO_MEMORY_PROCESSOR_TARGET) ||
634  !(req->Type & (MFX_MEMTYPE_FROM_VPPIN | MFX_MEMTYPE_FROM_VPPOUT)) ||
635  !(req->Type & MFX_MEMTYPE_EXTERNAL_FRAME))
636  return MFX_ERR_UNSUPPORTED;
637  if (i->Width > i1->Width || i->Height > i1->Height ||
638  i->FourCC != i1->FourCC || i->ChromaFormat != i1->ChromaFormat) {
639  av_log(ctx, AV_LOG_ERROR, "Mismatching surface properties in an "
640  "allocation request: %dx%d %d %d vs %dx%d %d %d\n",
641  i->Width, i->Height, i->FourCC, i->ChromaFormat,
642  i1->Width, i1->Height, i1->FourCC, i1->ChromaFormat);
643  return MFX_ERR_UNSUPPORTED;
644  }
645 
646  resp->mids = s->mem_ids;
647  resp->NumFrameActual = hwctx->nb_surfaces;
648 
649  return MFX_ERR_NONE;
650 }
651 
652 static mfxStatus frame_free(mfxHDL pthis, mfxFrameAllocResponse *resp)
653 {
654  return MFX_ERR_NONE;
655 }
656 
657 static mfxStatus frame_lock(mfxHDL pthis, mfxMemId mid, mfxFrameData *ptr)
658 {
659  return MFX_ERR_UNSUPPORTED;
660 }
661 
662 static mfxStatus frame_unlock(mfxHDL pthis, mfxMemId mid, mfxFrameData *ptr)
663 {
664  return MFX_ERR_UNSUPPORTED;
665 }
666 
667 static mfxStatus frame_get_hdl(mfxHDL pthis, mfxMemId mid, mfxHDL *hdl)
668 {
669  mfxHDLPair *pair_dst = (mfxHDLPair*)hdl;
670  mfxHDLPair *pair_src = (mfxHDLPair*)mid;
671 
672  pair_dst->first = pair_src->first;
673 
674  if (pair_src->second != (mfxMemId)MFX_INFINITE)
675  pair_dst->second = pair_src->second;
676  return MFX_ERR_NONE;
677 }
678 
679 #if QSV_ONEVPL
680 
681 static int qsv_d3d11_update_config(void *ctx, mfxHDL handle, mfxConfig cfg)
682 {
683  int ret = AVERROR_UNKNOWN;
684 #if CONFIG_D3D11VA
685  mfxStatus sts;
686  IDXGIAdapter *pDXGIAdapter;
687  DXGI_ADAPTER_DESC adapterDesc;
688  IDXGIDevice *pDXGIDevice = NULL;
689  HRESULT hr;
690  ID3D11Device *device = handle;
691  mfxVariant impl_value = {0};
692 
693  hr = ID3D11Device_QueryInterface(device, &IID_IDXGIDevice, (void**)&pDXGIDevice);
694  if (SUCCEEDED(hr)) {
695  hr = IDXGIDevice_GetAdapter(pDXGIDevice, &pDXGIAdapter);
696  if (FAILED(hr)) {
697  av_log(ctx, AV_LOG_ERROR, "Error IDXGIDevice_GetAdapter %d\n", hr);
698  IDXGIDevice_Release(pDXGIDevice);
699  return ret;
700  }
701 
702  hr = IDXGIAdapter_GetDesc(pDXGIAdapter, &adapterDesc);
703  if (FAILED(hr)) {
704  av_log(ctx, AV_LOG_ERROR, "Error IDXGIAdapter_GetDesc %d\n", hr);
705  goto fail;
706  }
707  } else {
708  av_log(ctx, AV_LOG_ERROR, "Error ID3D11Device_QueryInterface %d\n", hr);
709  return ret;
710  }
711 
712  impl_value.Type = MFX_VARIANT_TYPE_U16;
713  impl_value.Data.U16 = adapterDesc.DeviceId;
714  sts = MFXSetConfigFilterProperty(cfg,
715  (const mfxU8 *)"mfxExtendedDeviceId.DeviceID", impl_value);
716  if (sts != MFX_ERR_NONE) {
717  av_log(ctx, AV_LOG_ERROR, "Error adding a MFX configuration"
718  "DeviceID property: %d.\n", sts);
719  goto fail;
720  }
721 
722  impl_value.Type = MFX_VARIANT_TYPE_PTR;
723  impl_value.Data.Ptr = &adapterDesc.AdapterLuid;
724  sts = MFXSetConfigFilterProperty(cfg,
725  (const mfxU8 *)"mfxExtendedDeviceId.DeviceLUID", impl_value);
726  if (sts != MFX_ERR_NONE) {
727  av_log(ctx, AV_LOG_ERROR, "Error adding a MFX configuration"
728  "DeviceLUID property: %d.\n", sts);
729  goto fail;
730  }
731 
732  impl_value.Type = MFX_VARIANT_TYPE_U32;
733  impl_value.Data.U32 = 0x0001;
734  sts = MFXSetConfigFilterProperty(cfg,
735  (const mfxU8 *)"mfxExtendedDeviceId.LUIDDeviceNodeMask", impl_value);
736  if (sts != MFX_ERR_NONE) {
737  av_log(ctx, AV_LOG_ERROR, "Error adding a MFX configuration"
738  "LUIDDeviceNodeMask property: %d.\n", sts);
739  goto fail;
740  }
741 
742  ret = 0;
743 
744 fail:
745  IDXGIAdapter_Release(pDXGIAdapter);
746  IDXGIDevice_Release(pDXGIDevice);
747 #endif
748  return ret;
749 }
750 
751 static int qsv_d3d9_update_config(void *ctx, mfxHDL handle, mfxConfig cfg)
752 {
753  int ret = AVERROR_UNKNOWN;
754 #if CONFIG_DXVA2
755  mfxStatus sts;
756  IDirect3DDeviceManager9* devmgr = handle;
757  IDirect3DDevice9 *device = NULL;
758  IDirect3DDevice9Ex *device_ex = NULL;
759  HANDLE device_handle = 0;
760  IDirect3D9Ex *d3d9ex = NULL;
761  IDirect3D9 *d3d9 = NULL;
762  LUID luid;
763  D3DDEVICE_CREATION_PARAMETERS params;
764  HRESULT hr;
765  mfxVariant impl_value = {0};
766 
767  hr = IDirect3DDeviceManager9_OpenDeviceHandle(devmgr, &device_handle);
768  if (FAILED(hr)) {
769  av_log(ctx, AV_LOG_ERROR, "Error OpenDeviceHandle %d\n", hr);
770  goto fail;
771  }
772 
773  hr = IDirect3DDeviceManager9_LockDevice(devmgr, device_handle, &device, TRUE);
774  if (FAILED(hr)) {
775  av_log(ctx, AV_LOG_ERROR, "Error LockDevice %d\n", hr);
776  IDirect3DDeviceManager9_CloseDeviceHandle(devmgr, device_handle);
777  goto fail;
778  }
779  hr = IDirect3DDevice9_QueryInterface(device, &IID_IDirect3DDevice9Ex, (void **)&device_ex);
780  IDirect3DDevice9_Release(device);
781  if (FAILED(hr)) {
782  av_log(ctx, AV_LOG_ERROR, "Error IDirect3DDevice9_QueryInterface %d\n", hr);
783  goto unlock;
784  }
785 
786  hr = IDirect3DDevice9Ex_GetCreationParameters(device_ex, &params);
787  if (FAILED(hr)) {
788  av_log(ctx, AV_LOG_ERROR, "Error IDirect3DDevice9_GetCreationParameters %d\n", hr);
789  IDirect3DDevice9Ex_Release(device_ex);
790  goto unlock;
791  }
792 
793  hr = IDirect3DDevice9Ex_GetDirect3D(device_ex, &d3d9);
794  if (FAILED(hr)) {
795  av_log(ctx, AV_LOG_ERROR, "Error IDirect3DDevice9Ex_GetDirect3D %d\n", hr);
796  IDirect3DDevice9Ex_Release(device_ex);
797  goto unlock;
798  }
799  hr = IDirect3D9_QueryInterface(d3d9, &IID_IDirect3D9Ex, (void **)&d3d9ex);
800  IDirect3D9_Release(d3d9);
801  if (FAILED(hr)) {
802  av_log(ctx, AV_LOG_ERROR, "Error IDirect3D9_QueryInterface3D %d\n", hr);
803  IDirect3DDevice9Ex_Release(device_ex);
804  goto unlock;
805  }
806 
807  hr = IDirect3D9Ex_GetAdapterLUID(d3d9ex, params.AdapterOrdinal, &luid);
808  if (FAILED(hr)) {
809  av_log(ctx, AV_LOG_ERROR, "Error IDirect3DDevice9Ex_GetAdapterLUID %d\n", hr);
810  goto release;
811  }
812 
813  impl_value.Type = MFX_VARIANT_TYPE_PTR;
814  impl_value.Data.Ptr = &luid;
815  sts = MFXSetConfigFilterProperty(cfg,
816  (const mfxU8 *)"mfxExtendedDeviceId.DeviceLUID", impl_value);
817  if (sts != MFX_ERR_NONE) {
818  av_log(ctx, AV_LOG_ERROR, "Error adding a MFX configuration"
819  "DeviceLUID property: %d.\n", sts);
820  goto release;
821  }
822 
823  ret = 0;
824 
825 release:
826  IDirect3D9Ex_Release(d3d9ex);
827  IDirect3DDevice9Ex_Release(device_ex);
828 
829 unlock:
830  IDirect3DDeviceManager9_UnlockDevice(devmgr, device_handle, FALSE);
831  IDirect3DDeviceManager9_CloseDeviceHandle(devmgr, device_handle);
832 fail:
833 #endif
834  return ret;
835 }
836 
837 static int qsv_va_update_config(void *ctx, mfxHDL handle, mfxConfig cfg)
838 {
839 #if CONFIG_VAAPI
840 #if VA_CHECK_VERSION(1, 15, 0)
841  mfxStatus sts;
842  VADisplay dpy = handle;
843  VAStatus vas;
844  VADisplayAttribute attr = {
845  .type = VADisplayPCIID,
846  };
847  mfxVariant impl_value = {0};
848 
849  vas = vaGetDisplayAttributes(dpy, &attr, 1);
850  if (vas == VA_STATUS_SUCCESS && attr.flags != VA_DISPLAY_ATTRIB_NOT_SUPPORTED) {
851  impl_value.Type = MFX_VARIANT_TYPE_U16;
852  impl_value.Data.U16 = (attr.value & 0xFFFF);
853  sts = MFXSetConfigFilterProperty(cfg,
854  (const mfxU8 *)"mfxImplDescription.mfxDeviceDescription.DeviceID", impl_value);
855  if (sts != MFX_ERR_NONE) {
856  av_log(ctx, AV_LOG_ERROR, "Error adding a MFX configuration"
857  "DeviceID property: %d.\n", sts);
858  goto fail;
859  }
860  } else {
861  av_log(ctx, AV_LOG_ERROR, "libva: Failed to get device id from the driver. Please "
862  "consider to upgrade the driver to support VA-API 1.15.0\n");
863  goto fail;
864  }
865 
866  return 0;
867 
868 fail:
869 #else
870  av_log(ctx, AV_LOG_ERROR, "libva: This version of libva doesn't support retrieving "
871  "the device information from the driver. Please consider to upgrade libva to "
872  "support VA-API 1.15.0\n");
873 #endif
874 #endif
875  return AVERROR_UNKNOWN;
876 }
877 
878 static int qsv_new_mfx_loader(void *ctx,
879  mfxHDL handle,
880  mfxHandleType handle_type,
881  mfxIMPL implementation,
882  mfxVersion *pver,
883  void **ploader)
884 {
885  mfxStatus sts;
886  mfxLoader loader = NULL;
887  mfxConfig cfg;
888  mfxVariant impl_value = {0};
889 
890  *ploader = NULL;
891  loader = MFXLoad();
892  if (!loader) {
893  av_log(ctx, AV_LOG_ERROR, "Error creating a MFX loader\n");
894  goto fail;
895  }
896 
897  /* Create configurations for implementation */
898  cfg = MFXCreateConfig(loader);
899  if (!cfg) {
900  av_log(ctx, AV_LOG_ERROR, "Error creating a MFX configuration\n");
901  goto fail;
902  }
903 
904  impl_value.Type = MFX_VARIANT_TYPE_U32;
905  impl_value.Data.U32 = (implementation == MFX_IMPL_SOFTWARE) ?
906  MFX_IMPL_TYPE_SOFTWARE : MFX_IMPL_TYPE_HARDWARE;
907  sts = MFXSetConfigFilterProperty(cfg,
908  (const mfxU8 *)"mfxImplDescription.Impl", impl_value);
909  if (sts != MFX_ERR_NONE) {
910  av_log(ctx, AV_LOG_ERROR, "Error adding a MFX configuration "
911  "property: %d.\n", sts);
912  goto fail;
913  }
914 
915  impl_value.Type = MFX_VARIANT_TYPE_U32;
916  impl_value.Data.U32 = pver->Version;
917  sts = MFXSetConfigFilterProperty(cfg,
918  (const mfxU8 *)"mfxImplDescription.ApiVersion.Version",
919  impl_value);
920  if (sts != MFX_ERR_NONE) {
921  av_log(ctx, AV_LOG_ERROR, "Error adding a MFX configuration "
922  "property: %d.\n", sts);
923  goto fail;
924  }
925 
926  impl_value.Type = MFX_VARIANT_TYPE_U32;
927  impl_value.Data.U32 = 0x8086; // Intel device only
928  sts = MFXSetConfigFilterProperty(cfg,
929  (const mfxU8 *)"mfxImplDescription.VendorID", impl_value);
930  if (sts != MFX_ERR_NONE) {
931  av_log(ctx, AV_LOG_ERROR, "Error adding a MFX configuration"
932  "VendorID property: %d.\n", sts);
933  goto fail;
934  }
935 
936  if (MFX_HANDLE_VA_DISPLAY == handle_type) {
937  if (handle && qsv_va_update_config(ctx, handle, cfg))
938  goto fail;
939 
940  impl_value.Data.U32 = MFX_ACCEL_MODE_VIA_VAAPI;
941  } else if (MFX_HANDLE_D3D9_DEVICE_MANAGER == handle_type) {
942  if (handle && qsv_d3d9_update_config(ctx, handle, cfg))
943  goto fail;
944 
945  impl_value.Data.U32 = MFX_ACCEL_MODE_VIA_D3D9;
946  } else {
947  if (handle && qsv_d3d11_update_config(ctx, handle, cfg))
948  goto fail;
949 
950  impl_value.Data.U32 = MFX_ACCEL_MODE_VIA_D3D11;
951  }
952 
953  impl_value.Type = MFX_VARIANT_TYPE_U32;
954  sts = MFXSetConfigFilterProperty(cfg,
955  (const mfxU8 *)"mfxImplDescription.AccelerationMode", impl_value);
956  if (sts != MFX_ERR_NONE) {
957  av_log(ctx, AV_LOG_ERROR, "Error adding a MFX configuration"
958  "AccelerationMode property: %d.\n", sts);
959  goto fail;
960  }
961 
962  *ploader = loader;
963 
964  return 0;
965 
966 fail:
967  if (loader)
968  MFXUnload(loader);
969 
970  return AVERROR_UNKNOWN;
971 }
972 
973 static int qsv_create_mfx_session_from_loader(void *ctx, mfxLoader loader, mfxSession *psession)
974 {
975  mfxStatus sts;
976  mfxSession session = NULL;
977  uint32_t impl_idx = 0;
978  mfxVersion ver;
979 
980  while (1) {
981  /* Enumerate all implementations */
982  mfxImplDescription *impl_desc;
983 
984  sts = MFXEnumImplementations(loader, impl_idx,
985  MFX_IMPLCAPS_IMPLDESCSTRUCTURE,
986  (mfxHDL *)&impl_desc);
987  /* Failed to find an available implementation */
988  if (sts == MFX_ERR_NOT_FOUND)
989  break;
990  else if (sts != MFX_ERR_NONE) {
991  impl_idx++;
992  continue;
993  }
994 
995  sts = MFXCreateSession(loader, impl_idx, &session);
996  MFXDispReleaseImplDescription(loader, impl_desc);
997  if (sts == MFX_ERR_NONE)
998  break;
999 
1000  impl_idx++;
1001  }
1002 
1003  if (sts != MFX_ERR_NONE) {
1004  av_log(ctx, AV_LOG_ERROR, "Error creating a MFX session: %d.\n", sts);
1005  goto fail;
1006  }
1007 
1008  sts = MFXQueryVersion(session, &ver);
1009  if (sts != MFX_ERR_NONE) {
1010  av_log(ctx, AV_LOG_ERROR, "Error querying a MFX session: %d.\n", sts);
1011  goto fail;
1012  }
1013 
1014  av_log(ctx, AV_LOG_VERBOSE, "Initialize MFX session: implementation "
1015  "version is %d.%d\n", ver.Major, ver.Minor);
1016 
1017  *psession = session;
1018 
1019  return 0;
1020 
1021 fail:
1022  if (session)
1023  MFXClose(session);
1024 
1025  return AVERROR_UNKNOWN;
1026 }
1027 
1028 static int qsv_create_mfx_session(void *ctx,
1029  mfxHDL handle,
1030  mfxHandleType handle_type,
1031  mfxIMPL implementation,
1032  mfxVersion *pver,
1033  mfxSession *psession,
1034  void **ploader)
1035 {
1036  mfxLoader loader = NULL;
1037 
1039  "Use Intel(R) oneVPL to create MFX session, API version is "
1040  "%d.%d, the required implementation version is %d.%d\n",
1041  MFX_VERSION_MAJOR, MFX_VERSION_MINOR, pver->Major, pver->Minor);
1042 
1043  if (handle_type != MFX_HANDLE_VA_DISPLAY &&
1044  handle_type != MFX_HANDLE_D3D9_DEVICE_MANAGER &&
1045  handle_type != MFX_HANDLE_D3D11_DEVICE) {
1047  "Invalid MFX device handle type\n");
1048  return AVERROR(EXDEV);
1049  }
1050 
1051  *psession = NULL;
1052 
1053  if (!*ploader) {
1054  if (qsv_new_mfx_loader(ctx, handle, handle_type, implementation, pver, (void **)&loader))
1055  goto fail;
1056 
1057  av_assert0(loader);
1058  } else
1059  loader = *ploader; // Use the input mfxLoader to create mfx session
1060 
1061  if (qsv_create_mfx_session_from_loader(ctx, loader, psession))
1062  goto fail;
1063 
1064  if (!*ploader)
1065  *ploader = loader;
1066 
1067  return 0;
1068 
1069 fail:
1070  if (!*ploader && loader)
1071  MFXUnload(loader);
1072 
1073  return AVERROR_UNKNOWN;
1074 }
1075 
1076 #else
1077 
1078 static int qsv_create_mfx_session(void *ctx,
1079  mfxHDL handle,
1080  mfxHandleType handle_type,
1081  mfxIMPL implementation,
1082  mfxVersion *pver,
1083  mfxSession *psession,
1084  void **ploader)
1085 {
1086  mfxVersion ver;
1087  mfxStatus sts;
1088  mfxSession session = NULL;
1089 
1091  "Use Intel(R) Media SDK to create MFX session, API version is "
1092  "%d.%d, the required implementation version is %d.%d\n",
1093  MFX_VERSION_MAJOR, MFX_VERSION_MINOR, pver->Major, pver->Minor);
1094 
1095  *ploader = NULL;
1096  *psession = NULL;
1097  ver = *pver;
1098  sts = MFXInit(implementation, &ver, &session);
1099  if (sts != MFX_ERR_NONE) {
1100  av_log(ctx, AV_LOG_ERROR, "Error initializing an MFX session: "
1101  "%d.\n", sts);
1102  goto fail;
1103  }
1104 
1105  sts = MFXQueryVersion(session, &ver);
1106  if (sts != MFX_ERR_NONE) {
1107  av_log(ctx, AV_LOG_ERROR, "Error querying an MFX session: "
1108  "%d.\n", sts);
1109  goto fail;
1110  }
1111 
1112  av_log(ctx, AV_LOG_VERBOSE, "Initialize MFX session: implementation "
1113  "version is %d.%d\n", ver.Major, ver.Minor);
1114 
1115  MFXClose(session);
1116 
1117  sts = MFXInit(implementation, &ver, &session);
1118  if (sts != MFX_ERR_NONE) {
1119  av_log(ctx, AV_LOG_ERROR, "Error initializing an MFX session: "
1120  "%d.\n", sts);
1121  goto fail;
1122  }
1123 
1124  *psession = session;
1125 
1126  return 0;
1127 
1128 fail:
1129  if (session)
1130  MFXClose(session);
1131 
1132  return AVERROR_UNKNOWN;
1133 }
1134 
1135 #endif
1136 
1138  mfxSession *session, int upload)
1139 {
1140  QSVFramesContext *s = ctx->hwctx;
1141  AVQSVFramesContext *frames_hwctx = &s->p;
1142  QSVDeviceContext *device_priv = ctx->device_ctx->hwctx;
1143  AVQSVDeviceContext *hwctx = &device_priv->p;
1144  int opaque = 0;
1145 
1146  mfxFrameAllocator frame_allocator = {
1147  .pthis = ctx,
1148  .Alloc = frame_alloc,
1149  .Lock = frame_lock,
1150  .Unlock = frame_unlock,
1151  .GetHDL = frame_get_hdl,
1152  .Free = frame_free,
1153  };
1154 
1155  mfxVideoParam par;
1156  mfxStatus err;
1157  int ret = AVERROR_UNKNOWN;
1158  /* hwctx->loader is non-NULL for oneVPL user and NULL for non-oneVPL user */
1159  void **loader = &hwctx->loader;
1160  mfxSession parent_session = hwctx->session;
1161  mfxIMPL impl;
1162  mfxVersion ver;
1163 
1164  err = MFXQueryIMPL(parent_session, &impl);
1165  if (err == MFX_ERR_NONE)
1166  err = MFXQueryVersion(parent_session, &ver);
1167  if (err != MFX_ERR_NONE) {
1168  av_log(ctx, AV_LOG_ERROR, "Error querying the session attributes.\n");
1169  return AVERROR_UNKNOWN;
1170  }
1171 
1172 #if QSV_HAVE_OPAQUE
1173  opaque = !!(frames_hwctx->frame_type & MFX_MEMTYPE_OPAQUE_FRAME);
1174 #endif
1175 
1176  ret = qsv_create_mfx_session(ctx, device_priv->handle, device_priv->handle_type,
1177  device_priv->impl, &device_priv->ver, session, loader);
1178  if (ret)
1179  goto fail;
1180 
1181  if (device_priv->handle) {
1182  err = MFXVideoCORE_SetHandle(*session, device_priv->handle_type,
1183  device_priv->handle);
1184  if (err != MFX_ERR_NONE) {
1185  ret = AVERROR_UNKNOWN;
1186  goto fail;
1187  }
1188  }
1189 
1190  if (QSV_RUNTIME_VERSION_ATLEAST(ver, 1, 25)) {
1191  err = MFXJoinSession(parent_session, *session);
1192  if (err != MFX_ERR_NONE) {
1193  av_log(ctx, AV_LOG_ERROR, "Error joining session.\n");
1194  ret = AVERROR_UNKNOWN;
1195  goto fail;
1196  }
1197  }
1198 
1199  if (!opaque) {
1200  err = MFXVideoCORE_SetFrameAllocator(*session, &frame_allocator);
1201  if (err != MFX_ERR_NONE) {
1202  ret = AVERROR_UNKNOWN;
1203  goto fail;
1204  }
1205  }
1206 
1207  memset(&par, 0, sizeof(par));
1208 
1209  if (!opaque) {
1210  par.IOPattern = upload ? MFX_IOPATTERN_OUT_VIDEO_MEMORY :
1211  MFX_IOPATTERN_IN_VIDEO_MEMORY;
1212  }
1213 #if QSV_HAVE_OPAQUE
1214  else {
1215  par.ExtParam = s->ext_buffers;
1216  par.NumExtParam = FF_ARRAY_ELEMS(s->ext_buffers);
1217  par.IOPattern = upload ? MFX_IOPATTERN_OUT_OPAQUE_MEMORY :
1218  MFX_IOPATTERN_IN_OPAQUE_MEMORY;
1219  }
1220 #endif
1221 
1222  par.IOPattern |= upload ? MFX_IOPATTERN_IN_SYSTEM_MEMORY :
1223  MFX_IOPATTERN_OUT_SYSTEM_MEMORY;
1224  par.AsyncDepth = 1;
1225 
1226  par.vpp.In = frames_hwctx->surfaces[0].Info;
1227 
1228  /* Apparently VPP requires the frame rate to be set to some value, otherwise
1229  * init will fail (probably for the framerate conversion filter). Since we
1230  * are only doing data upload/download here, we just invent an arbitrary
1231  * value */
1232  par.vpp.In.FrameRateExtN = 25;
1233  par.vpp.In.FrameRateExtD = 1;
1234  par.vpp.Out = par.vpp.In;
1235 
1236  err = MFXVideoVPP_Init(*session, &par);
1237  if (err != MFX_ERR_NONE) {
1238  av_log(ctx, AV_LOG_VERBOSE, "Error opening the internal VPP session."
1239  "Surface upload/download will not be possible\n");
1240 
1241  ret = AVERROR_UNKNOWN;
1242  goto fail;
1243  }
1244 
1245  return 0;
1246 
1247 fail:
1248  if (*session)
1249  MFXClose(*session);
1250 
1251  *session = NULL;
1252 
1253  return ret;
1254 }
1255 
1257 {
1258  QSVFramesContext *s = ctx->hwctx;
1259  AVQSVFramesContext *frames_hwctx = &s->p;
1260 
1261  int opaque = 0;
1262 
1263  uint32_t fourcc;
1264  int i, ret;
1265 
1266 #if QSV_HAVE_OPAQUE
1267  opaque = !!(frames_hwctx->frame_type & MFX_MEMTYPE_OPAQUE_FRAME);
1268 #endif
1269 
1270  fourcc = qsv_fourcc_from_pix_fmt(ctx->sw_format);
1271  if (!fourcc) {
1272  av_log(ctx, AV_LOG_ERROR, "Unsupported pixel format\n");
1273  return AVERROR(ENOSYS);
1274  }
1275 
1276  if (!ctx->pool) {
1278  if (ret < 0) {
1279  av_log(ctx, AV_LOG_ERROR, "Error creating an internal frame pool\n");
1280  return ret;
1281  }
1282  }
1283 
1284  if (!opaque) {
1285  s->mem_ids = av_calloc(frames_hwctx->nb_surfaces, sizeof(*s->mem_ids));
1286  if (!s->mem_ids)
1287  return AVERROR(ENOMEM);
1288 
1289  for (i = 0; i < frames_hwctx->nb_surfaces; i++)
1290  s->mem_ids[i] = frames_hwctx->surfaces[i].Data.MemId;
1291  }
1292 #if QSV_HAVE_OPAQUE
1293  else {
1294  s->surface_ptrs = av_calloc(frames_hwctx->nb_surfaces,
1295  sizeof(*s->surface_ptrs));
1296  if (!s->surface_ptrs)
1297  return AVERROR(ENOMEM);
1298 
1299  for (i = 0; i < frames_hwctx->nb_surfaces; i++)
1300  s->surface_ptrs[i] = frames_hwctx->surfaces + i;
1301 
1302  s->opaque_alloc.In.Surfaces = s->surface_ptrs;
1303  s->opaque_alloc.In.NumSurface = frames_hwctx->nb_surfaces;
1304  s->opaque_alloc.In.Type = frames_hwctx->frame_type;
1305 
1306  s->opaque_alloc.Out = s->opaque_alloc.In;
1307 
1308  s->opaque_alloc.Header.BufferId = MFX_EXTBUFF_OPAQUE_SURFACE_ALLOCATION;
1309  s->opaque_alloc.Header.BufferSz = sizeof(s->opaque_alloc);
1310 
1311  s->ext_buffers[0] = (mfxExtBuffer*)&s->opaque_alloc;
1312  }
1313 #endif
1314 
1315  s->session_download = NULL;
1316  s->session_upload = NULL;
1317 
1318  s->session_download_init = 0;
1319  s->session_upload_init = 0;
1320 
1321 #if HAVE_PTHREADS
1322  pthread_mutex_init(&s->session_lock, NULL);
1323 #endif
1324 
1325  return 0;
1326 }
1327 
1329 {
1330  frame->buf[0] = av_buffer_pool_get(ctx->pool);
1331  if (!frame->buf[0])
1332  return AVERROR(ENOMEM);
1333 
1334  frame->data[3] = frame->buf[0]->data;
1336  frame->width = ctx->width;
1337  frame->height = ctx->height;
1338 
1339  return 0;
1340 }
1341 
1343  enum AVHWFrameTransferDirection dir,
1344  enum AVPixelFormat **formats)
1345 {
1346  enum AVPixelFormat *fmts;
1347 
1348  fmts = av_malloc_array(2, sizeof(*fmts));
1349  if (!fmts)
1350  return AVERROR(ENOMEM);
1351 
1352  fmts[0] = ctx->sw_format;
1353  fmts[1] = AV_PIX_FMT_NONE;
1354 
1355  *formats = fmts;
1356 
1357  return 0;
1358 }
1359 
1361  AVHWFramesContext *src_ctx, int flags)
1362 {
1363  AVQSVFramesContext *src_hwctx = src_ctx->hwctx;
1364  int i;
1365 
1366  switch (dst_ctx->device_ctx->type) {
1367 #if CONFIG_VAAPI
1369  {
1370  AVVAAPIFramesContext *dst_hwctx = dst_ctx->hwctx;
1371  dst_hwctx->surface_ids = av_calloc(src_hwctx->nb_surfaces,
1372  sizeof(*dst_hwctx->surface_ids));
1373  if (!dst_hwctx->surface_ids)
1374  return AVERROR(ENOMEM);
1375  for (i = 0; i < src_hwctx->nb_surfaces; i++) {
1376  mfxHDLPair *pair = (mfxHDLPair*)src_hwctx->surfaces[i].Data.MemId;
1377  dst_hwctx->surface_ids[i] = *(VASurfaceID*)pair->first;
1378  }
1379  dst_hwctx->nb_surfaces = src_hwctx->nb_surfaces;
1380  }
1381  break;
1382 #endif
1383 #if CONFIG_D3D11VA
1385  {
1386  D3D11_TEXTURE2D_DESC texDesc;
1387  AVD3D11VAFramesContext *dst_hwctx;
1388  dst_ctx->initial_pool_size = src_ctx->initial_pool_size;
1389  dst_hwctx = dst_ctx->hwctx;
1390  dst_hwctx->texture_infos = av_calloc(src_hwctx->nb_surfaces,
1391  sizeof(*dst_hwctx->texture_infos));
1392  if (!dst_hwctx->texture_infos)
1393  return AVERROR(ENOMEM);
1394  if (src_hwctx->frame_type & MFX_MEMTYPE_SHARED_RESOURCE)
1395  dst_hwctx->MiscFlags = D3D11_RESOURCE_MISC_SHARED;
1396  for (i = 0; i < src_hwctx->nb_surfaces; i++) {
1397  mfxHDLPair *pair = (mfxHDLPair*)src_hwctx->surfaces[i].Data.MemId;
1398  dst_hwctx->texture_infos[i].texture = (ID3D11Texture2D*)pair->first;
1399  dst_hwctx->texture_infos[i].index = pair->second == (mfxMemId)MFX_INFINITE ? (intptr_t)0 : (intptr_t)pair->second;
1400  }
1401  ID3D11Texture2D_GetDesc(dst_hwctx->texture_infos[0].texture, &texDesc);
1402  dst_hwctx->BindFlags = texDesc.BindFlags;
1403  }
1404  break;
1405 #endif
1406 #if CONFIG_DXVA2
1408  {
1409  AVDXVA2FramesContext *dst_hwctx = dst_ctx->hwctx;
1410  dst_hwctx->surfaces = av_calloc(src_hwctx->nb_surfaces,
1411  sizeof(*dst_hwctx->surfaces));
1412  if (!dst_hwctx->surfaces)
1413  return AVERROR(ENOMEM);
1414  for (i = 0; i < src_hwctx->nb_surfaces; i++) {
1415  mfxHDLPair *pair = (mfxHDLPair*)src_hwctx->surfaces[i].Data.MemId;
1416  dst_hwctx->surfaces[i] = (IDirect3DSurface9*)pair->first;
1417  }
1418  dst_hwctx->nb_surfaces = src_hwctx->nb_surfaces;
1419  if (src_hwctx->frame_type == MFX_MEMTYPE_VIDEO_MEMORY_DECODER_TARGET)
1420  dst_hwctx->surface_type = DXVA2_VideoDecoderRenderTarget;
1421  else
1422  dst_hwctx->surface_type = DXVA2_VideoProcessorRenderTarget;
1423  }
1424  break;
1425 #endif
1426  default:
1427  return AVERROR(ENOSYS);
1428  }
1429 
1430  return 0;
1431 }
1432 
1434  AVFrame *dst, const AVFrame *src, int flags)
1435 {
1436  QSVFramesContext *s = ctx->hwctx;
1437  mfxFrameSurface1 *surf = (mfxFrameSurface1*)src->data[3];
1438  AVHWFramesContext *child_frames_ctx;
1439  const AVPixFmtDescriptor *desc;
1440  uint8_t *child_data;
1441  AVFrame *dummy;
1442  int ret = 0;
1443 
1444  if (!s->child_frames_ref)
1445  return AVERROR(ENOSYS);
1446  child_frames_ctx = (AVHWFramesContext*)s->child_frames_ref->data;
1447 
1448  switch (child_frames_ctx->device_ctx->type) {
1449 #if CONFIG_VAAPI
1451  {
1452  mfxHDLPair *pair = (mfxHDLPair*)surf->Data.MemId;
1453  /* pair->first is *VASurfaceID while data[3] in vaapi frame is VASurfaceID, so
1454  * we need this casting for vaapi.
1455  * Add intptr_t to force cast from VASurfaceID(uint) type to pointer(long) type
1456  * to avoid compile warning */
1457  child_data = (uint8_t*)(intptr_t)*(VASurfaceID*)pair->first;
1458  break;
1459  }
1460 #endif
1461 #if CONFIG_D3D11VA
1463  {
1464  mfxHDLPair *pair = (mfxHDLPair*)surf->Data.MemId;
1465  child_data = pair->first;
1466  break;
1467  }
1468 #endif
1469 #if CONFIG_DXVA2
1471  {
1472  mfxHDLPair *pair = (mfxHDLPair*)surf->Data.MemId;
1473  child_data = pair->first;
1474  break;
1475  }
1476 #endif
1477  default:
1478  return AVERROR(ENOSYS);
1479  }
1480 
1481  if (dst->format == child_frames_ctx->format) {
1482  ret = ff_hwframe_map_create(s->child_frames_ref,
1483  dst, src, NULL, NULL);
1484  if (ret < 0)
1485  return ret;
1486 
1487  dst->width = src->width;
1488  dst->height = src->height;
1489 
1490  if (child_frames_ctx->device_ctx->type == AV_HWDEVICE_TYPE_D3D11VA) {
1491  mfxHDLPair *pair = (mfxHDLPair*)surf->Data.MemId;
1492  dst->data[0] = pair->first;
1493  dst->data[1] = pair->second == (mfxMemId)MFX_INFINITE ? (uint8_t *)0 : pair->second;
1494  } else {
1495  dst->data[3] = child_data;
1496  }
1497 
1498  return 0;
1499  }
1500 
1502  if (desc && desc->flags & AV_PIX_FMT_FLAG_HWACCEL) {
1503  // This only supports mapping to software.
1504  return AVERROR(ENOSYS);
1505  }
1506 
1507  dummy = av_frame_alloc();
1508  if (!dummy)
1509  return AVERROR(ENOMEM);
1510 
1511  dummy->buf[0] = av_buffer_ref(src->buf[0]);
1512  dummy->hw_frames_ctx = av_buffer_ref(s->child_frames_ref);
1513  if (!dummy->buf[0] || !dummy->hw_frames_ctx)
1514  goto fail;
1515 
1516  dummy->format = child_frames_ctx->format;
1517  dummy->width = src->width;
1518  dummy->height = src->height;
1519 
1520  if (child_frames_ctx->device_ctx->type == AV_HWDEVICE_TYPE_D3D11VA) {
1521  mfxHDLPair *pair = (mfxHDLPair*)surf->Data.MemId;
1522  dummy->data[0] = pair->first;
1523  dummy->data[1] = pair->second == (mfxMemId)MFX_INFINITE ? (uint8_t *)0 : pair->second;
1524  } else {
1525  dummy->data[3] = child_data;
1526  }
1527 
1528  ret = av_hwframe_map(dst, dummy, flags);
1529 
1530 fail:
1531  av_frame_free(&dummy);
1532 
1533  return ret;
1534 }
1535 
1537  const AVFrame *src)
1538 {
1539  QSVFramesContext *s = ctx->hwctx;
1540  AVHWFramesContext *child_frames_ctx = (AVHWFramesContext*)s->child_frames_ref->data;
1541  int download = !!src->hw_frames_ctx;
1542  mfxFrameSurface1 *surf = (mfxFrameSurface1*)(download ? src->data[3] : dst->data[3]);
1543 
1544  AVFrame *dummy;
1545  int ret;
1546 
1547  dummy = av_frame_alloc();
1548  if (!dummy)
1549  return AVERROR(ENOMEM);
1550 
1551  dummy->format = child_frames_ctx->format;
1552  dummy->width = src->width;
1553  dummy->height = src->height;
1554  dummy->buf[0] = download ? src->buf[0] : dst->buf[0];
1555  dummy->data[3] = surf->Data.MemId;
1556  dummy->hw_frames_ctx = s->child_frames_ref;
1557 
1558  ret = download ? av_hwframe_transfer_data(dst, dummy, 0) :
1560 
1561  dummy->buf[0] = NULL;
1562  dummy->data[3] = NULL;
1563  dummy->hw_frames_ctx = NULL;
1564 
1565  av_frame_free(&dummy);
1566 
1567  return ret;
1568 }
1569 
1570 static int map_frame_to_surface(const AVFrame *frame, mfxFrameSurface1 *surface)
1571 {
1572  switch (frame->format) {
1573  case AV_PIX_FMT_NV12:
1574  case AV_PIX_FMT_P010:
1575  case AV_PIX_FMT_P012:
1576  surface->Data.Y = frame->data[0];
1577  surface->Data.UV = frame->data[1];
1578  break;
1579 
1580  case AV_PIX_FMT_YUV420P:
1581  surface->Data.Y = frame->data[0];
1582  surface->Data.U = frame->data[1];
1583  surface->Data.V = frame->data[2];
1584  break;
1585 
1586  case AV_PIX_FMT_BGRA:
1587  surface->Data.B = frame->data[0];
1588  surface->Data.G = frame->data[0] + 1;
1589  surface->Data.R = frame->data[0] + 2;
1590  surface->Data.A = frame->data[0] + 3;
1591  break;
1592  case AV_PIX_FMT_YUYV422:
1593  surface->Data.Y = frame->data[0];
1594  surface->Data.U = frame->data[0] + 1;
1595  surface->Data.V = frame->data[0] + 3;
1596  break;
1597 
1598  case AV_PIX_FMT_Y210:
1599  case AV_PIX_FMT_Y212:
1600  surface->Data.Y16 = (mfxU16 *)frame->data[0];
1601  surface->Data.U16 = (mfxU16 *)frame->data[0] + 1;
1602  surface->Data.V16 = (mfxU16 *)frame->data[0] + 3;
1603  break;
1604  case AV_PIX_FMT_VUYX:
1605  surface->Data.V = frame->data[0];
1606  surface->Data.U = frame->data[0] + 1;
1607  surface->Data.Y = frame->data[0] + 2;
1608  // Only set Data.A to a valid address, the SDK doesn't
1609  // use the value from the frame.
1610  surface->Data.A = frame->data[0] + 3;
1611  break;
1612  case AV_PIX_FMT_XV30:
1613  surface->Data.U = frame->data[0];
1614  break;
1615  case AV_PIX_FMT_XV36:
1616  surface->Data.U = frame->data[0];
1617  surface->Data.Y = frame->data[0] + 2;
1618  surface->Data.V = frame->data[0] + 4;
1619  // Only set Data.A to a valid address, the SDK doesn't
1620  // use the value from the frame.
1621  surface->Data.A = frame->data[0] + 6;
1622  break;
1623 #if CONFIG_VAAPI
1624  case AV_PIX_FMT_UYVY422:
1625  surface->Data.Y = frame->data[0] + 1;
1626  surface->Data.U = frame->data[0];
1627  surface->Data.V = frame->data[0] + 2;
1628  break;
1629 #endif
1630  default:
1631  return MFX_ERR_UNSUPPORTED;
1632  }
1633  surface->Data.Pitch = frame->linesize[0];
1634  surface->Data.TimeStamp = frame->pts;
1635 
1636  return 0;
1637 }
1638 
1640 {
1641  QSVFramesContext *s = ctx->hwctx;
1642  atomic_int *inited = upload ? &s->session_upload_init : &s->session_download_init;
1643  mfxSession *session = upload ? &s->session_upload : &s->session_download;
1644  int ret = 0;
1645 
1646  if (atomic_load(inited))
1647  return 0;
1648 
1649 #if HAVE_PTHREADS
1650  pthread_mutex_lock(&s->session_lock);
1651 #endif
1652 
1653  if (!atomic_load(inited)) {
1654  ret = qsv_init_internal_session(ctx, session, upload);
1655  atomic_store(inited, 1);
1656  }
1657 
1658 #if HAVE_PTHREADS
1659  pthread_mutex_unlock(&s->session_lock);
1660 #endif
1661 
1662  return ret;
1663 }
1664 
1666  const AVFrame *src)
1667 {
1668  QSVFramesContext *s = ctx->hwctx;
1669  mfxFrameSurface1 out = {{ 0 }};
1670  mfxFrameSurface1 *in = (mfxFrameSurface1*)src->data[3];
1671 
1672  mfxSyncPoint sync = NULL;
1673  mfxStatus err;
1674  int ret = 0;
1675  /* download to temp frame if the output is not padded as libmfx requires */
1676  AVFrame *tmp_frame = &s->realigned_download_frame;
1677  AVFrame *dst_frame;
1678  int realigned = 0;
1679 
1681  if (ret < 0)
1682  return ret;
1683 
1684  /* According to MSDK spec for mfxframeinfo, "Width must be a multiple of 16.
1685  * Height must be a multiple of 16 for progressive frame sequence and a
1686  * multiple of 32 otherwise.", so allign all frames to 16 before downloading. */
1687  if (dst->height & 15 || dst->linesize[0] & 15) {
1688  realigned = 1;
1689  if (tmp_frame->format != dst->format ||
1690  tmp_frame->width != FFALIGN(dst->linesize[0], 16) ||
1691  tmp_frame->height != FFALIGN(dst->height, 16)) {
1692  av_frame_unref(tmp_frame);
1693 
1694  tmp_frame->format = dst->format;
1695  tmp_frame->width = FFALIGN(dst->linesize[0], 16);
1696  tmp_frame->height = FFALIGN(dst->height, 16);
1697  ret = av_frame_get_buffer(tmp_frame, 0);
1698  if (ret < 0)
1699  return ret;
1700  }
1701  }
1702 
1703  dst_frame = realigned ? tmp_frame : dst;
1704 
1705  if (!s->session_download) {
1706  if (s->child_frames_ref)
1707  return qsv_transfer_data_child(ctx, dst_frame, src);
1708 
1709  av_log(ctx, AV_LOG_ERROR, "Surface download not possible\n");
1710  return AVERROR(ENOSYS);
1711  }
1712 
1713  out.Info = in->Info;
1714  map_frame_to_surface(dst_frame, &out);
1715 
1716  do {
1717  err = MFXVideoVPP_RunFrameVPPAsync(s->session_download, in, &out, NULL, &sync);
1718  if (err == MFX_WRN_DEVICE_BUSY)
1719  av_usleep(1);
1720  } while (err == MFX_WRN_DEVICE_BUSY);
1721 
1722  if (err < 0 || !sync) {
1723  av_log(ctx, AV_LOG_ERROR, "Error downloading the surface\n");
1724  return AVERROR_UNKNOWN;
1725  }
1726 
1727  do {
1728  err = MFXVideoCORE_SyncOperation(s->session_download, sync, 1000);
1729  } while (err == MFX_WRN_IN_EXECUTION);
1730  if (err < 0) {
1731  av_log(ctx, AV_LOG_ERROR, "Error synchronizing the operation: %d\n", err);
1732  return AVERROR_UNKNOWN;
1733  }
1734 
1735  if (realigned) {
1736  tmp_frame->width = dst->width;
1737  tmp_frame->height = dst->height;
1738  ret = av_frame_copy(dst, tmp_frame);
1739  tmp_frame->width = FFALIGN(dst->linesize[0], 16);
1740  tmp_frame->height = FFALIGN(dst->height, 16);
1741  if (ret < 0)
1742  return ret;
1743  }
1744 
1745  return 0;
1746 }
1747 
1749  const AVFrame *src)
1750 {
1751  QSVFramesContext *s = ctx->hwctx;
1752  mfxFrameSurface1 in = {{ 0 }};
1753  mfxFrameSurface1 *out = (mfxFrameSurface1*)dst->data[3];
1754  mfxFrameInfo tmp_info;
1755 
1756  mfxSyncPoint sync = NULL;
1757  mfxStatus err;
1758  int ret = 0;
1759  /* make a copy if the input is not padded as libmfx requires */
1760  AVFrame *tmp_frame = &s->realigned_upload_frame;
1761  const AVFrame *src_frame;
1762  int realigned = 0;
1763 
1765  if (ret < 0)
1766  return ret;
1767 
1768  /* According to MSDK spec for mfxframeinfo, "Width must be a multiple of 16.
1769  * Height must be a multiple of 16 for progressive frame sequence and a
1770  * multiple of 32 otherwise.", so allign all frames to 16 before uploading. */
1771  if (src->height & 15 || src->linesize[0] & 15) {
1772  realigned = 1;
1773  if (tmp_frame->format != src->format ||
1774  tmp_frame->width != FFALIGN(src->width, 16) ||
1775  tmp_frame->height != FFALIGN(src->height, 16)) {
1776  av_frame_unref(tmp_frame);
1777 
1778  tmp_frame->format = src->format;
1779  tmp_frame->width = FFALIGN(src->width, 16);
1780  tmp_frame->height = FFALIGN(src->height, 16);
1781  ret = av_frame_get_buffer(tmp_frame, 0);
1782  if (ret < 0)
1783  return ret;
1784  }
1785  ret = av_frame_copy(tmp_frame, src);
1786  if (ret < 0) {
1787  av_frame_unref(tmp_frame);
1788  return ret;
1789  }
1790  ret = qsv_fill_border(tmp_frame, src);
1791  if (ret < 0) {
1792  av_frame_unref(tmp_frame);
1793  return ret;
1794  }
1795 
1796  tmp_info = out->Info;
1797  out->Info.CropW = FFMIN(out->Info.Width, tmp_frame->width);
1798  out->Info.CropH = FFMIN(out->Info.Height, tmp_frame->height);
1799  }
1800 
1801  src_frame = realigned ? tmp_frame : src;
1802 
1803  if (!s->session_upload) {
1804  if (s->child_frames_ref)
1805  return qsv_transfer_data_child(ctx, dst, src_frame);
1806 
1807  av_log(ctx, AV_LOG_ERROR, "Surface upload not possible\n");
1808  return AVERROR(ENOSYS);
1809  }
1810 
1811  in.Info = out->Info;
1812  map_frame_to_surface(src_frame, &in);
1813 
1814  do {
1815  err = MFXVideoVPP_RunFrameVPPAsync(s->session_upload, &in, out, NULL, &sync);
1816  if (err == MFX_WRN_DEVICE_BUSY)
1817  av_usleep(1);
1818  } while (err == MFX_WRN_DEVICE_BUSY);
1819 
1820  if (err < 0 || !sync) {
1821  av_log(ctx, AV_LOG_ERROR, "Error uploading the surface\n");
1822  return AVERROR_UNKNOWN;
1823  }
1824 
1825  do {
1826  err = MFXVideoCORE_SyncOperation(s->session_upload, sync, 1000);
1827  } while (err == MFX_WRN_IN_EXECUTION);
1828  if (err < 0) {
1829  av_log(ctx, AV_LOG_ERROR, "Error synchronizing the operation\n");
1830  return AVERROR_UNKNOWN;
1831  }
1832 
1833  if (realigned) {
1834  out->Info.CropW = tmp_info.CropW;
1835  out->Info.CropH = tmp_info.CropH;
1836  }
1837 
1838  return 0;
1839 }
1840 
1842  AVHWFramesContext *src_ctx, int flags)
1843 {
1844  QSVFramesContext *s = dst_ctx->hwctx;
1845  AVQSVFramesContext *dst_hwctx = &s->p;
1846  int i;
1847 
1848  if (src_ctx->initial_pool_size == 0) {
1849  av_log(dst_ctx, AV_LOG_ERROR, "Only fixed-size pools can be "
1850  "mapped to QSV frames.\n");
1851  return AVERROR(EINVAL);
1852  }
1853 
1854  switch (src_ctx->device_ctx->type) {
1855 #if CONFIG_VAAPI
1857  {
1858  AVVAAPIFramesContext *src_hwctx = src_ctx->hwctx;
1859  s->handle_pairs_internal = av_calloc(src_ctx->initial_pool_size,
1860  sizeof(*s->handle_pairs_internal));
1861  if (!s->handle_pairs_internal)
1862  return AVERROR(ENOMEM);
1863  s->surfaces_internal = av_calloc(src_hwctx->nb_surfaces,
1864  sizeof(*s->surfaces_internal));
1865  if (!s->surfaces_internal)
1866  return AVERROR(ENOMEM);
1867  for (i = 0; i < src_hwctx->nb_surfaces; i++) {
1868  qsv_init_surface(dst_ctx, &s->surfaces_internal[i]);
1869  s->handle_pairs_internal[i].first = src_hwctx->surface_ids + i;
1870  s->handle_pairs_internal[i].second = (mfxMemId)MFX_INFINITE;
1871  s->surfaces_internal[i].Data.MemId = (mfxMemId)&s->handle_pairs_internal[i];
1872  }
1873  dst_hwctx->nb_surfaces = src_hwctx->nb_surfaces;
1874  dst_hwctx->frame_type = MFX_MEMTYPE_VIDEO_MEMORY_DECODER_TARGET;
1875  }
1876  break;
1877 #endif
1878 #if CONFIG_D3D11VA
1880  {
1881  AVD3D11VAFramesContext *src_hwctx = src_ctx->hwctx;
1882  s->handle_pairs_internal = av_calloc(src_ctx->initial_pool_size,
1883  sizeof(*s->handle_pairs_internal));
1884  if (!s->handle_pairs_internal)
1885  return AVERROR(ENOMEM);
1886  s->surfaces_internal = av_calloc(src_ctx->initial_pool_size,
1887  sizeof(*s->surfaces_internal));
1888  if (!s->surfaces_internal)
1889  return AVERROR(ENOMEM);
1890  for (i = 0; i < src_ctx->initial_pool_size; i++) {
1891  qsv_init_surface(dst_ctx, &s->surfaces_internal[i]);
1892  s->handle_pairs_internal[i].first = (mfxMemId)src_hwctx->texture_infos[i].texture;
1893  if (src_hwctx->BindFlags & D3D11_BIND_RENDER_TARGET) {
1894  s->handle_pairs_internal[i].second = (mfxMemId)MFX_INFINITE;
1895  } else {
1896  s->handle_pairs_internal[i].second = (mfxMemId)src_hwctx->texture_infos[i].index;
1897  }
1898  s->surfaces_internal[i].Data.MemId = (mfxMemId)&s->handle_pairs_internal[i];
1899  }
1900  dst_hwctx->nb_surfaces = src_ctx->initial_pool_size;
1901  if (src_hwctx->BindFlags & D3D11_BIND_RENDER_TARGET) {
1902  dst_hwctx->frame_type |= MFX_MEMTYPE_VIDEO_MEMORY_PROCESSOR_TARGET;
1903  } else {
1904  dst_hwctx->frame_type |= MFX_MEMTYPE_VIDEO_MEMORY_DECODER_TARGET;
1905  }
1906  }
1907  break;
1908 #endif
1909 #if CONFIG_DXVA2
1911  {
1912  AVDXVA2FramesContext *src_hwctx = src_ctx->hwctx;
1913  s->handle_pairs_internal = av_calloc(src_ctx->initial_pool_size,
1914  sizeof(*s->handle_pairs_internal));
1915  if (!s->handle_pairs_internal)
1916  return AVERROR(ENOMEM);
1917  s->surfaces_internal = av_calloc(src_hwctx->nb_surfaces,
1918  sizeof(*s->surfaces_internal));
1919  if (!s->surfaces_internal)
1920  return AVERROR(ENOMEM);
1921  for (i = 0; i < src_hwctx->nb_surfaces; i++) {
1922  qsv_init_surface(dst_ctx, &s->surfaces_internal[i]);
1923  s->handle_pairs_internal[i].first = (mfxMemId)src_hwctx->surfaces[i];
1924  s->handle_pairs_internal[i].second = (mfxMemId)MFX_INFINITE;
1925  s->surfaces_internal[i].Data.MemId = (mfxMemId)&s->handle_pairs_internal[i];
1926  }
1927  dst_hwctx->nb_surfaces = src_hwctx->nb_surfaces;
1928  if (src_hwctx->surface_type == DXVA2_VideoProcessorRenderTarget)
1929  dst_hwctx->frame_type = MFX_MEMTYPE_VIDEO_MEMORY_PROCESSOR_TARGET;
1930  else
1931  dst_hwctx->frame_type = MFX_MEMTYPE_VIDEO_MEMORY_DECODER_TARGET;
1932  }
1933  break;
1934 #endif
1935  default:
1936  return AVERROR(ENOSYS);
1937  }
1938 
1939  dst_hwctx->surfaces = s->surfaces_internal;
1940 
1941  return 0;
1942 }
1943 
1944 static int qsv_map_to(AVHWFramesContext *dst_ctx,
1945  AVFrame *dst, const AVFrame *src, int flags)
1946 {
1947  AVQSVFramesContext *hwctx = dst_ctx->hwctx;
1948  int i, err, index = -1;
1949 
1950  for (i = 0; i < hwctx->nb_surfaces && index < 0; i++) {
1951  switch(src->format) {
1952 #if CONFIG_VAAPI
1953  case AV_PIX_FMT_VAAPI:
1954  {
1955  mfxHDLPair *pair = (mfxHDLPair*)hwctx->surfaces[i].Data.MemId;
1956  if (*(VASurfaceID*)pair->first == (VASurfaceID)(uintptr_t)src->data[3]) {
1957  index = i;
1958  break;
1959  }
1960  }
1961 #endif
1962 #if CONFIG_D3D11VA
1963  case AV_PIX_FMT_D3D11:
1964  {
1965  mfxHDLPair *pair = (mfxHDLPair*)hwctx->surfaces[i].Data.MemId;
1966  if (pair->first == src->data[0]
1967  && (pair->second == src->data[1]
1968  || (pair->second == (mfxMemId)MFX_INFINITE && src->data[1] == (uint8_t *)0))) {
1969  index = i;
1970  break;
1971  }
1972  }
1973 #endif
1974 #if CONFIG_DXVA2
1975  case AV_PIX_FMT_DXVA2_VLD:
1976  {
1977  mfxHDLPair *pair = (mfxHDLPair*)hwctx->surfaces[i].Data.MemId;
1978  if (pair->first == src->data[3]) {
1979  index = i;
1980  break;
1981  }
1982  }
1983 #endif
1984  }
1985  }
1986  if (index < 0) {
1987  av_log(dst_ctx, AV_LOG_ERROR, "Trying to map from a surface which "
1988  "is not in the mapped frames context.\n");
1989  return AVERROR(EINVAL);
1990  }
1991 
1993  dst, src, NULL, NULL);
1994  if (err)
1995  return err;
1996 
1997  dst->width = src->width;
1998  dst->height = src->height;
1999  dst->data[3] = (uint8_t*)&hwctx->surfaces[index];
2000 
2001  return 0;
2002 }
2003 
2005  const void *hwconfig,
2006  AVHWFramesConstraints *constraints)
2007 {
2008  int i;
2009 
2011  sizeof(*constraints->valid_sw_formats));
2012  if (!constraints->valid_sw_formats)
2013  return AVERROR(ENOMEM);
2014 
2015  for (i = 0; i < FF_ARRAY_ELEMS(supported_pixel_formats); i++)
2016  constraints->valid_sw_formats[i] = supported_pixel_formats[i].pix_fmt;
2018 
2019  constraints->valid_hw_formats = av_malloc_array(2, sizeof(*constraints->valid_hw_formats));
2020  if (!constraints->valid_hw_formats)
2021  return AVERROR(ENOMEM);
2022 
2023  constraints->valid_hw_formats[0] = AV_PIX_FMT_QSV;
2024  constraints->valid_hw_formats[1] = AV_PIX_FMT_NONE;
2025 
2026  return 0;
2027 }
2028 
2030 {
2031  AVQSVDeviceContext *hwctx = ctx->hwctx;
2032  QSVDevicePriv *priv = ctx->user_opaque;
2033 
2034  if (hwctx->session)
2035  MFXClose(hwctx->session);
2036 
2037  if (hwctx->loader)
2038  MFXUnload(hwctx->loader);
2040  av_freep(&priv);
2041 }
2042 
2043 static mfxIMPL choose_implementation(const char *device, enum AVHWDeviceType child_device_type)
2044 {
2045  static const struct {
2046  const char *name;
2047  mfxIMPL impl;
2048  } impl_map[] = {
2049  { "auto", MFX_IMPL_AUTO },
2050  { "sw", MFX_IMPL_SOFTWARE },
2051  { "hw", MFX_IMPL_HARDWARE },
2052  { "auto_any", MFX_IMPL_AUTO_ANY },
2053  { "hw_any", MFX_IMPL_HARDWARE_ANY },
2054  { "hw2", MFX_IMPL_HARDWARE2 },
2055  { "hw3", MFX_IMPL_HARDWARE3 },
2056  { "hw4", MFX_IMPL_HARDWARE4 },
2057  };
2058 
2059  mfxIMPL impl = MFX_IMPL_AUTO_ANY;
2060  int i;
2061 
2062  if (device) {
2063  for (i = 0; i < FF_ARRAY_ELEMS(impl_map); i++)
2064  if (!strcmp(device, impl_map[i].name)) {
2065  impl = impl_map[i].impl;
2066  break;
2067  }
2068  if (i == FF_ARRAY_ELEMS(impl_map))
2069  impl = strtol(device, NULL, 0);
2070  }
2071 
2072  if (impl != MFX_IMPL_SOFTWARE) {
2073  if (child_device_type == AV_HWDEVICE_TYPE_D3D11VA)
2074  impl |= MFX_IMPL_VIA_D3D11;
2075  else if (child_device_type == AV_HWDEVICE_TYPE_DXVA2)
2076  impl |= MFX_IMPL_VIA_D3D9;
2077  }
2078 
2079  return impl;
2080 }
2081 
2083  mfxIMPL implementation,
2084  AVHWDeviceContext *child_device_ctx,
2085  int flags)
2086 {
2087  AVQSVDeviceContext *hwctx = ctx->hwctx;
2088 
2089  mfxVersion ver = { { 3, 1 } };
2090  mfxHDL handle;
2091  mfxHandleType handle_type;
2092  mfxStatus err;
2093  int ret;
2094 
2095  switch (child_device_ctx->type) {
2096 #if CONFIG_VAAPI
2098  {
2099  AVVAAPIDeviceContext *child_device_hwctx = child_device_ctx->hwctx;
2100  handle_type = MFX_HANDLE_VA_DISPLAY;
2101  handle = (mfxHDL)child_device_hwctx->display;
2102  }
2103  break;
2104 #endif
2105 #if CONFIG_D3D11VA
2107  {
2108  AVD3D11VADeviceContext *child_device_hwctx = child_device_ctx->hwctx;
2109  handle_type = MFX_HANDLE_D3D11_DEVICE;
2110  handle = (mfxHDL)child_device_hwctx->device;
2111  }
2112  break;
2113 #endif
2114 #if CONFIG_DXVA2
2116  {
2117  AVDXVA2DeviceContext *child_device_hwctx = child_device_ctx->hwctx;
2118  handle_type = MFX_HANDLE_D3D9_DEVICE_MANAGER;
2119  handle = (mfxHDL)child_device_hwctx->devmgr;
2120  }
2121  break;
2122 #endif
2123  default:
2124  ret = AVERROR(ENOSYS);
2125  goto fail;
2126  }
2127 
2128  ret = qsv_create_mfx_session(ctx, handle, handle_type, implementation, &ver,
2129  &hwctx->session, &hwctx->loader);
2130  if (ret)
2131  goto fail;
2132 
2133  err = MFXVideoCORE_SetHandle(hwctx->session, handle_type, handle);
2134  if (err != MFX_ERR_NONE) {
2135  av_log(ctx, AV_LOG_ERROR, "Error setting child device handle: "
2136  "%d\n", err);
2137  ret = AVERROR_UNKNOWN;
2138  goto fail;
2139  }
2140 
2141  return 0;
2142 
2143 fail:
2144  if (hwctx->session)
2145  MFXClose(hwctx->session);
2146 
2147  if (hwctx->loader)
2148  MFXUnload(hwctx->loader);
2149 
2150  hwctx->session = NULL;
2151  hwctx->loader = NULL;
2152  return ret;
2153 }
2154 
2156  AVHWDeviceContext *child_device_ctx,
2157  AVDictionary *opts, int flags)
2158 {
2159  mfxIMPL impl;
2160  QSVDevicePriv *priv;
2161 
2162  priv = av_mallocz(sizeof(*priv));
2163  if (!priv)
2164  return AVERROR(ENOMEM);
2165 
2166  ctx->user_opaque = priv;
2167  ctx->free = qsv_device_free;
2168 
2169  impl = choose_implementation("hw_any", child_device_ctx->type);
2170  return qsv_device_derive_from_child(ctx, impl,
2171  child_device_ctx, flags);
2172 }
2173 
2174 static int qsv_device_create(AVHWDeviceContext *ctx, const char *device,
2175  AVDictionary *opts, int flags)
2176 {
2177  QSVDevicePriv *priv;
2178  enum AVHWDeviceType child_device_type;
2179  AVHWDeviceContext *child_device;
2180  AVDictionary *child_device_opts;
2181  AVDictionaryEntry *e;
2182 
2183  mfxIMPL impl;
2184  int ret;
2185 
2186  priv = av_mallocz(sizeof(*priv));
2187  if (!priv)
2188  return AVERROR(ENOMEM);
2189 
2190  ctx->user_opaque = priv;
2191  ctx->free = qsv_device_free;
2192 
2193  e = av_dict_get(opts, "child_device_type", NULL, 0);
2194  if (e) {
2195  child_device_type = av_hwdevice_find_type_by_name(e->value);
2196  if (child_device_type == AV_HWDEVICE_TYPE_NONE) {
2197  av_log(ctx, AV_LOG_ERROR, "Unknown child device type "
2198  "\"%s\".\n", e->value);
2199  return AVERROR(EINVAL);
2200  }
2201 #if QSV_ONEVPL
2202  } else if (CONFIG_D3D11VA) { // Use D3D11 by default if d3d11va is enabled
2204  "Defaulting child_device_type to AV_HWDEVICE_TYPE_D3D11VA for oneVPL."
2205  "Please explicitly set child device type via \"-init_hw_device\" "
2206  "option if needed.\n");
2207  child_device_type = AV_HWDEVICE_TYPE_D3D11VA;
2208  } else if (CONFIG_DXVA2) {
2209  child_device_type = AV_HWDEVICE_TYPE_DXVA2;
2210 #else
2211  } else if (CONFIG_DXVA2) {
2213  "WARNING: defaulting child_device_type to AV_HWDEVICE_TYPE_DXVA2 for compatibility "
2214  "with old commandlines. This behaviour will be removed "
2215  "in the future. Please explicitly set device type via \"-init_hw_device\" option.\n");
2216  child_device_type = AV_HWDEVICE_TYPE_DXVA2;
2217  } else if (CONFIG_D3D11VA) {
2218  child_device_type = AV_HWDEVICE_TYPE_D3D11VA;
2219 #endif
2220  } else if (CONFIG_VAAPI) {
2221  child_device_type = AV_HWDEVICE_TYPE_VAAPI;
2222  } else {
2223  av_log(ctx, AV_LOG_ERROR, "No supported child device type is enabled\n");
2224  return AVERROR(ENOSYS);
2225  }
2226 
2227 #if CONFIG_VAAPI && defined(_WIN32)
2228  /* AV_HWDEVICE_TYPE_VAAPI on Windows/Libva-win32 not supported */
2229  /* Reject user specified child_device_type or CONFIG_VAAPI on Windows */
2230  if (child_device_type == AV_HWDEVICE_TYPE_VAAPI) {
2231  av_log(ctx, AV_LOG_ERROR, "VAAPI child device type not supported for oneVPL on Windows"
2232  "\"%s\".\n", e->value);
2233  return AVERROR(EINVAL);
2234  }
2235 #endif
2236 
2237  child_device_opts = NULL;
2238  switch (child_device_type) {
2239 #if CONFIG_VAAPI
2241  {
2242  // libmfx does not actually implement VAAPI properly, rather it
2243  // depends on the specific behaviour of a matching iHD driver when
2244  // used on recent Intel hardware. Set options to the VAAPI device
2245  // creation so that we should pick a usable setup by default if
2246  // possible, even when multiple devices and drivers are available.
2247  av_dict_set(&child_device_opts, "kernel_driver", "i915", 0);
2248  av_dict_set(&child_device_opts, "driver", "iHD", 0);
2249  }
2250  break;
2251 #endif
2252 #if CONFIG_D3D11VA
2254  {
2255  // Make sure the hardware vendor is Intel when multiple devices are
2256  // available, it will be ignored if user specifies the child device
2257  // explicitly
2258  av_dict_set(&child_device_opts, "vendor_id", "0x8086", 0);
2259  }
2260  break;
2261 #endif
2262 #if CONFIG_DXVA2
2264 #if QSV_ONEVPL
2265  {
2267  "d3d11va is not available or child device type is set to dxva2 "
2268  "explicitly for oneVPL.\n");
2269  }
2270 #endif
2271  break;
2272 #endif
2273  default:
2274  {
2275  av_log(ctx, AV_LOG_ERROR, "No supported child device type is enabled\n");
2276  return AVERROR(ENOSYS);
2277  }
2278  break;
2279  }
2280 
2281  e = av_dict_get(opts, "child_device", NULL, 0);
2282  ret = av_hwdevice_ctx_create(&priv->child_device_ctx, child_device_type,
2283  e ? e->value : NULL, child_device_opts, 0);
2284 
2285  av_dict_free(&child_device_opts);
2286  if (ret < 0)
2287  return ret;
2288 
2289  child_device = (AVHWDeviceContext*)priv->child_device_ctx->data;
2290 
2291  impl = choose_implementation(device, child_device_type);
2292 
2293  return qsv_device_derive_from_child(ctx, impl, child_device, 0);
2294 }
2295 
2298  .name = "QSV",
2299 
2300  .device_hwctx_size = sizeof(QSVDeviceContext),
2301  .frames_hwctx_size = sizeof(QSVFramesContext),
2302 
2303  .device_create = qsv_device_create,
2304  .device_derive = qsv_device_derive,
2305  .device_init = qsv_device_init,
2306  .frames_get_constraints = qsv_frames_get_constraints,
2307  .frames_init = qsv_frames_init,
2308  .frames_uninit = qsv_frames_uninit,
2309  .frames_get_buffer = qsv_get_buffer,
2310  .transfer_get_formats = qsv_transfer_get_formats,
2311  .transfer_data_to = qsv_transfer_data_to,
2312  .transfer_data_from = qsv_transfer_data_from,
2313  .map_to = qsv_map_to,
2314  .map_from = qsv_map_from,
2315  .frames_derive_to = qsv_frames_derive_to,
2316  .frames_derive_from = qsv_frames_derive_from,
2317 
2318  .pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_QSV, AV_PIX_FMT_NONE },
2319 };
formats
formats
Definition: signature.h:48
pthread_mutex_t
_fmutex pthread_mutex_t
Definition: os2threads.h:53
AVHWDeviceContext::hwctx
void * hwctx
The format-specific data, allocated and freed by libavutil along with this context.
Definition: hwcontext.h:85
FFHWFramesContext::pool_internal
AVBufferPool * pool_internal
Definition: hwcontext_internal.h:101
qsv_transfer_data_child
static int qsv_transfer_data_child(AVHWFramesContext *ctx, AVFrame *dst, const AVFrame *src)
Definition: hwcontext_qsv.c:1536
AVQSVFramesContext::frame_type
int frame_type
A combination of MFX_MEMTYPE_* describing the frame pool.
Definition: hwcontext_qsv.h:60
AV_LOG_WARNING
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:186
AVPixelFormat
AVPixelFormat
Pixel format.
Definition: pixfmt.h:71
name
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it vf default minimum maximum flags name is the option name
Definition: writing_filters.txt:88
atomic_store
#define atomic_store(object, desired)
Definition: stdatomic.h:85
AVERROR
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
out
FILE * out
Definition: movenc.c:54
av_frame_get_buffer
int av_frame_get_buffer(AVFrame *frame, int align)
Allocate new buffer(s) for audio or video data.
Definition: frame.c:258
comp
static void comp(unsigned char *dst, ptrdiff_t dst_stride, unsigned char *src, ptrdiff_t src_stride, int add)
Definition: eamad.c:80
QSVFramesContext::child_frames_ref
AVBufferRef * child_frames_ref
Definition: hwcontext_qsv.c:106
qsv_transfer_data_to
static int qsv_transfer_data_to(AVHWFramesContext *ctx, AVFrame *dst, const AVFrame *src)
Definition: hwcontext_qsv.c:1748
av_pix_fmt_desc_get
const AVPixFmtDescriptor * av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt)
Definition: pixdesc.c:2962
AVBufferRef::data
uint8_t * data
The data buffer.
Definition: buffer.h:90
pthread_mutex_init
static av_always_inline int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr)
Definition: os2threads.h:104
qsv_map_from
static int qsv_map_from(AVHWFramesContext *ctx, AVFrame *dst, const AVFrame *src, int flags)
Definition: hwcontext_qsv.c:1433
qsv_fourcc_from_pix_fmt
static uint32_t qsv_fourcc_from_pix_fmt(enum AVPixelFormat pix_fmt)
Definition: hwcontext_qsv.c:199
AVHWFramesContext::format
enum AVPixelFormat format
The pixel format identifying the underlying HW surface type.
Definition: hwcontext.h:197
QSVDeviceContext::p
AVQSVDeviceContext p
The public AVQSVDeviceContext.
Definition: hwcontext_qsv.c:81
qsv_fill_border
static int qsv_fill_border(AVFrame *dst, const AVFrame *src)
Definition: hwcontext_qsv.c:236
av_frame_free
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition: frame.c:130
QSVDeviceContext::ver
mfxVersion ver
Definition: hwcontext_qsv.c:85
av_hwframe_ctx_init
int av_hwframe_ctx_init(AVBufferRef *ref)
Finalize the context before use.
Definition: hwcontext.c:322
AVFrame
This structure describes decoded (raw) audio or video data.
Definition: frame.h:344
pixdesc.h
AVFrame::pts
int64_t pts
Presentation timestamp in time_base units (time when frame should be shown to user).
Definition: frame.h:456
AVFrame::width
int width
Definition: frame.h:416
AVQSVDeviceContext
This struct is allocated as AVHWDeviceContext.hwctx.
Definition: hwcontext_qsv.h:35
AVD3D11VAFramesContext::MiscFlags
UINT MiscFlags
D3D11_TEXTURE2D_DESC.MiscFlags used for texture creation.
Definition: hwcontext_d3d11va.h:166
av_hwframe_ctx_alloc
AVBufferRef * av_hwframe_ctx_alloc(AVBufferRef *device_ref_in)
Allocate an AVHWFramesContext tied to a given device context.
Definition: hwcontext.c:248
qsv_device_derive
static int qsv_device_derive(AVHWDeviceContext *ctx, AVHWDeviceContext *child_device_ctx, AVDictionary *opts, int flags)
Definition: hwcontext_qsv.c:2155
AVDXVA2FramesContext
This struct is allocated as AVHWFramesContext.hwctx.
Definition: hwcontext_dxva2.h:46
qsv_frames_derive_from
static int qsv_frames_derive_from(AVHWFramesContext *dst_ctx, AVHWFramesContext *src_ctx, int flags)
Definition: hwcontext_qsv.c:1360
AV_HWDEVICE_TYPE_NONE
@ AV_HWDEVICE_TYPE_NONE
Definition: hwcontext.h:28
av_hwframe_map
int av_hwframe_map(AVFrame *dst, const AVFrame *src, int flags)
Map a hardware frame.
Definition: hwcontext.c:778
qsv_init_surface
static int qsv_init_surface(AVHWFramesContext *ctx, mfxFrameSurface1 *surf)
Definition: hwcontext_qsv.c:537
data
const char data[16]
Definition: mxf.c:148
atomic_int
intptr_t atomic_int
Definition: stdatomic.h:55
choose_implementation
static mfxIMPL choose_implementation(const char *device, enum AVHWDeviceType child_device_type)
Definition: hwcontext_qsv.c:2043
QSVDeviceContext
Definition: hwcontext_qsv.c:77
av_hwdevice_find_type_by_name
enum AVHWDeviceType av_hwdevice_find_type_by_name(const char *name)
Look up an AVHWDeviceType by name.
Definition: hwcontext.c:102
AV_PIX_FMT_XV30
#define AV_PIX_FMT_XV30
Definition: pixfmt.h:534
AVDXVA2DeviceContext::devmgr
IDirect3DDeviceManager9 * devmgr
Definition: hwcontext_dxva2.h:40
AV_LOG_VERBOSE
#define AV_LOG_VERBOSE
Detailed information.
Definition: log.h:196
AVVAAPIDeviceContext::display
VADisplay display
The VADisplay handle, to be filled by the user.
Definition: hwcontext_vaapi.h:72
AV_PIX_FMT_BGRA
@ AV_PIX_FMT_BGRA
packed BGRA 8:8:8:8, 32bpp, BGRABGRA...
Definition: pixfmt.h:102
AVDictionary
Definition: dict.c:34
ff_hwframe_map_create
int ff_hwframe_map_create(AVBufferRef *hwframe_ref, AVFrame *dst, const AVFrame *src, void(*unmap)(AVHWFramesContext *ctx, HWMapDescriptor *hwmap), void *priv)
Definition: hwcontext.c:726
FFMAX
#define FFMAX(a, b)
Definition: macros.h:47
av_buffer_ref
AVBufferRef * av_buffer_ref(const AVBufferRef *buf)
Create a new reference to an AVBuffer.
Definition: buffer.c:103
AVHWFramesConstraints::valid_hw_formats
enum AVPixelFormat * valid_hw_formats
A list of possible values for format in the hw_frames_ctx, terminated by AV_PIX_FMT_NONE.
Definition: hwcontext.h:446
AVERROR_UNKNOWN
#define AVERROR_UNKNOWN
Unknown error, typically from an external library.
Definition: error.h:73
AVHWFramesContext::width
int width
The allocated dimensions of the frames in this pool.
Definition: hwcontext.h:217
fourcc
uint32_t fourcc
Definition: hwcontext_qsv.c:126
av_hwdevice_ctx_init
int av_hwdevice_ctx_init(AVBufferRef *ref)
Finalize the device context before use.
Definition: hwcontext.c:208
AVFrame::buf
AVBufferRef * buf[AV_NUM_DATA_POINTERS]
AVBuffer references backing the data for this frame.
Definition: frame.h:557
QSVDeviceContext::handle_type
mfxHandleType handle_type
Definition: hwcontext_qsv.c:84
qsv_transfer_data_from
static int qsv_transfer_data_from(AVHWFramesContext *ctx, AVFrame *dst, const AVFrame *src)
Definition: hwcontext_qsv.c:1665
AVFrame::data
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition: frame.h:365
AVHWFramesConstraints
This struct describes the constraints on hardware frames attached to a given device with a hardware-s...
Definition: hwcontext.h:441
QSVDevicePriv
Definition: hwcontext_qsv.c:73
AVD3D11VAFramesContext::BindFlags
UINT BindFlags
D3D11_TEXTURE2D_DESC.BindFlags used for texture creation.
Definition: hwcontext_d3d11va.h:160
AVVAAPIFramesContext::surface_ids
VASurfaceID * surface_ids
The surfaces IDs of all surfaces in the pool after creation.
Definition: hwcontext_vaapi.h:101
AVD3D11FrameDescriptor::texture
ID3D11Texture2D * texture
The texture in which the frame is located.
Definition: hwcontext_d3d11va.h:117
QSVDeviceContext::child_device_type
enum AVHWDeviceType child_device_type
Definition: hwcontext_qsv.c:88
qsv_init_child_ctx
static int qsv_init_child_ctx(AVHWFramesContext *ctx)
Definition: hwcontext_qsv.c:392
fail
#define fail()
Definition: checkasm.h:179
AV_PIX_FMT_FLAG_HWACCEL
#define AV_PIX_FMT_FLAG_HWACCEL
Pixel format is an HW accelerated format.
Definition: pixdesc.h:128
dummy
int dummy
Definition: motion.c:66
AV_HWDEVICE_TYPE_D3D11VA
@ AV_HWDEVICE_TYPE_D3D11VA
Definition: hwcontext.h:35
qsv_frames_get_constraints
static int qsv_frames_get_constraints(AVHWDeviceContext *ctx, const void *hwconfig, AVHWFramesConstraints *constraints)
Definition: hwcontext_qsv.c:2004
av_buffer_pool_init2
AVBufferPool * av_buffer_pool_init2(size_t size, void *opaque, AVBufferRef *(*alloc)(void *opaque, size_t size), void(*pool_free)(void *opaque))
Allocate and initialize a buffer pool with a more complex allocator.
Definition: buffer.c:259
QSVFramesContext::session_download_init
atomic_int session_download_init
Definition: hwcontext_qsv.c:99
qsv_frames_derive_to
static int qsv_frames_derive_to(AVHWFramesContext *dst_ctx, AVHWFramesContext *src_ctx, int flags)
Definition: hwcontext_qsv.c:1841
QSV_RUNTIME_VERSION_ATLEAST
#define QSV_RUNTIME_VERSION_ATLEAST(MFX_VERSION, MAJOR, MINOR)
Definition: hwcontext_qsv.c:59
AVHWDeviceContext
This struct aggregates all the (hardware/vendor-specific) "high-level" state, i.e.
Definition: hwcontext.h:60
av_frame_alloc
AVFrame * av_frame_alloc(void)
Allocate an AVFrame and set its fields to default values.
Definition: frame.c:118
frame_free
static mfxStatus frame_free(mfxHDL pthis, mfxFrameAllocResponse *resp)
Definition: hwcontext_qsv.c:652
AV_PIX_FMT_Y210
#define AV_PIX_FMT_Y210
Definition: pixfmt.h:532
avassert.h
HWContextType::type
enum AVHWDeviceType type
Definition: hwcontext_internal.h:30
ffhwframesctx
static FFHWFramesContext * ffhwframesctx(AVHWFramesContext *ctx)
Definition: hwcontext_internal.h:115
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:180
FF_ARRAY_ELEMS
#define FF_ARRAY_ELEMS(a)
Definition: sinewin_tablegen.c:29
AVHWFramesContext::height
int height
Definition: hwcontext.h:217
av_hwdevice_ctx_alloc
AVBufferRef * av_hwdevice_ctx_alloc(enum AVHWDeviceType type)
Allocate an AVHWDeviceContext for a given hardware type.
Definition: hwcontext.c:161
AVHWFramesConstraints::valid_sw_formats
enum AVPixelFormat * valid_sw_formats
A list of possible values for sw_format in the hw_frames_ctx, terminated by AV_PIX_FMT_NONE.
Definition: hwcontext.h:453
QSVFramesContext::ext_buffers
mfxExtBuffer * ext_buffers[1]
Definition: hwcontext_qsv.c:118
QSVFramesContext::session_upload_init
atomic_int session_upload_init
Definition: hwcontext_qsv.c:101
frame_alloc
static mfxStatus frame_alloc(mfxHDL pthis, mfxFrameAllocRequest *req, mfxFrameAllocResponse *resp)
Definition: hwcontext_qsv.c:624
av_dict_get
AVDictionaryEntry * av_dict_get(const AVDictionary *m, const char *key, const AVDictionaryEntry *prev, int flags)
Get a dictionary entry with matching key.
Definition: dict.c:62
av_memcpy_backptr
void av_memcpy_backptr(uint8_t *dst, int back, int cnt)
Overlapping memcpy() implementation.
Definition: mem.c:445
av_buffer_pool_get
AVBufferRef * av_buffer_pool_get(AVBufferPool *pool)
Allocate a new AVBuffer, reusing an old buffer from the pool when available.
Definition: buffer.c:390
QSVDevicePriv::child_device_ctx
AVBufferRef * child_device_ctx
Definition: hwcontext_qsv.c:74
AV_PIX_FMT_DXVA2_VLD
@ AV_PIX_FMT_DXVA2_VLD
HW decoding through DXVA2, Picture.data[3] contains a LPDIRECT3DSURFACE9 pointer.
Definition: pixfmt.h:134
s
#define s(width, name)
Definition: cbs_vp9.c:198
AVD3D11VADeviceContext::device
ID3D11Device * device
Device used for texture creation and access.
Definition: hwcontext_d3d11va.h:56
AV_CEIL_RSHIFT
#define AV_CEIL_RSHIFT(a, b)
Definition: common.h:58
av_assert0
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition: avassert.h:40
AVHWDeviceType
AVHWDeviceType
Definition: hwcontext.h:27
QSVDeviceContext::handle
mfxHDL handle
Definition: hwcontext_qsv.c:83
QSVFramesContext::mem_ids
mfxMemId * mem_ids
Definition: hwcontext_qsv.c:112
ctx
AVFormatContext * ctx
Definition: movenc.c:48
AVDXVA2FramesContext::nb_surfaces
int nb_surfaces
Definition: hwcontext_dxva2.h:59
AV_PIX_FMT_YUV420P
@ AV_PIX_FMT_YUV420P
planar YUV 4:2:0, 12bpp, (1 Cr & Cb sample per 2x2 Y samples)
Definition: pixfmt.h:73
av_usleep
int av_usleep(unsigned usec)
Sleep for a period of time.
Definition: time.c:84
atomic_load
#define atomic_load(object)
Definition: stdatomic.h:93
MFXUnload
#define MFXUnload(a)
Definition: hwcontext_qsv.c:70
frame
static AVFrame * frame
Definition: demux_decode.c:54
if
if(ret)
Definition: filter_design.txt:179
ff_hwcontext_type_qsv
const HWContextType ff_hwcontext_type_qsv
Definition: hwcontext_qsv.c:2296
qsv_create_mfx_session
static int qsv_create_mfx_session(void *ctx, mfxHDL handle, mfxHandleType handle_type, mfxIMPL implementation, mfxVersion *pver, mfxSession *psession, void **ploader)
Definition: hwcontext_qsv.c:1078
opts
AVDictionary * opts
Definition: movenc.c:50
AVD3D11VAFramesContext::texture_infos
AVD3D11FrameDescriptor * texture_infos
In case if texture structure member above is not NULL contains the same texture pointer for all eleme...
Definition: hwcontext_d3d11va.h:175
AVQSVFramesContext::surfaces
mfxFrameSurface1 * surfaces
Definition: hwcontext_qsv.h:54
NULL
#define NULL
Definition: coverity.c:32
AVHWFramesContext::sw_format
enum AVPixelFormat sw_format
The pixel format identifying the actual data layout of the hardware frames.
Definition: hwcontext.h:210
qsv_frames_uninit
static void qsv_frames_uninit(AVHWFramesContext *ctx)
Definition: hwcontext_qsv.c:340
av_buffer_unref
void av_buffer_unref(AVBufferRef **buf)
Free a given reference and automatically free the buffer if there are no more references to it.
Definition: buffer.c:139
AVComponentDescriptor
Definition: pixdesc.h:30
AV_HWDEVICE_TYPE_DXVA2
@ AV_HWDEVICE_TYPE_DXVA2
Definition: hwcontext.h:32
AV_PIX_FMT_YUYV422
@ AV_PIX_FMT_YUYV422
packed YUV 4:2:2, 16bpp, Y0 Cb Y1 Cr
Definition: pixfmt.h:74
MFX_IMPL_VIA_MASK
#define MFX_IMPL_VIA_MASK(impl)
Definition: hwcontext_qsv.c:63
qsv_internal_session_check_init
static int qsv_internal_session_check_init(AVHWFramesContext *ctx, int upload)
Definition: hwcontext_qsv.c:1639
qsv_frames_init
static int qsv_frames_init(AVHWFramesContext *ctx)
Definition: hwcontext_qsv.c:1256
time.h
AV_PIX_FMT_QSV
@ AV_PIX_FMT_QSV
HW acceleration through QSV, data[3] contains a pointer to the mfxFrameSurface1 structure.
Definition: pixfmt.h:247
map_frame_to_surface
static int map_frame_to_surface(const AVFrame *frame, mfxFrameSurface1 *surface)
Definition: hwcontext_qsv.c:1570
frame_unlock
static mfxStatus frame_unlock(mfxHDL pthis, mfxMemId mid, mfxFrameData *ptr)
Definition: hwcontext_qsv.c:662
index
int index
Definition: gxfenc.c:89
pthread_mutex_unlock
#define pthread_mutex_unlock(a)
Definition: ffprobe.c:81
AVD3D11VAFramesContext
This struct is allocated as AVHWFramesContext.hwctx.
Definition: hwcontext_d3d11va.h:131
av_buffer_create
AVBufferRef * av_buffer_create(uint8_t *data, size_t size, void(*free)(void *opaque, uint8_t *data), void *opaque, int flags)
Create an AVBuffer from an existing array.
Definition: buffer.c:55
QSVFramesContext::realigned_upload_frame
AVFrame realigned_upload_frame
Definition: hwcontext_qsv.c:120
qsv_init_internal_session
static int qsv_init_internal_session(AVHWFramesContext *ctx, mfxSession *session, int upload)
Definition: hwcontext_qsv.c:1137
hwcontext_dxva2.h
QSVFramesContext::opaque_alloc
mfxExtOpaqueSurfaceAlloc opaque_alloc
Definition: hwcontext_qsv.c:117
qsv_get_buffer
static int qsv_get_buffer(AVHWFramesContext *ctx, AVFrame *frame)
Definition: hwcontext_qsv.c:1328
AV_PIX_FMT_P012
#define AV_PIX_FMT_P012
Definition: pixfmt.h:529
AVDXVA2FramesContext::surface_type
DWORD surface_type
The surface type (e.g.
Definition: hwcontext_dxva2.h:51
av_frame_copy
int av_frame_copy(AVFrame *dst, const AVFrame *src)
Copy the frame data from src to dst.
Definition: frame.c:890
size
int size
Definition: twinvq_data.h:10344
QSVFramesContext::nb_surfaces_used
int nb_surfaces_used
Definition: hwcontext_qsv.c:109
qsv_device_free
static void qsv_device_free(AVHWDeviceContext *ctx)
Definition: hwcontext_qsv.c:2029
AVFrame::format
int format
format of the frame, -1 if unknown or unset Values correspond to enum AVPixelFormat for video frames,...
Definition: frame.h:431
ff_qsv_get_surface_base_handle
int ff_qsv_get_surface_base_handle(mfxFrameSurface1 *surf, enum AVHWDeviceType base_dev_type, void **base_handle)
Caller needs to allocate enough space for base_handle pointer.
Definition: hwcontext_qsv.c:172
qsv_transfer_get_formats
static int qsv_transfer_get_formats(AVHWFramesContext *ctx, enum AVHWFrameTransferDirection dir, enum AVPixelFormat **formats)
Definition: hwcontext_qsv.c:1342
buffer.h
AV_PIX_FMT_Y212
#define AV_PIX_FMT_Y212
Definition: pixfmt.h:533
qsv_device_derive_from_child
static int qsv_device_derive_from_child(AVHWDeviceContext *ctx, mfxIMPL implementation, AVHWDeviceContext *child_device_ctx, int flags)
Definition: hwcontext_qsv.c:2082
supported_pixel_formats
static const struct @370 supported_pixel_formats[]
AVQSVDeviceContext::loader
void * loader
The mfxLoader handle used for mfxSession creation.
Definition: hwcontext_qsv.h:47
AV_PIX_FMT_D3D11
@ AV_PIX_FMT_D3D11
Hardware surfaces for Direct3D11.
Definition: pixfmt.h:336
av_dict_free
void av_dict_free(AVDictionary **pm)
Free all the memory allocated for an AVDictionary struct and all keys and values.
Definition: dict.c:223
AVQSVFramesContext::nb_surfaces
int nb_surfaces
Definition: hwcontext_qsv.h:55
frame_get_hdl
static mfxStatus frame_get_hdl(mfxHDL pthis, mfxMemId mid, mfxHDL *hdl)
Definition: hwcontext_qsv.c:667
AV_PIX_FMT_VAAPI
@ AV_PIX_FMT_VAAPI
Hardware acceleration through VA-API, data[3] contains a VASurfaceID.
Definition: pixfmt.h:126
AV_HWDEVICE_TYPE_VAAPI
@ AV_HWDEVICE_TYPE_VAAPI
Definition: hwcontext.h:31
pthread_mutex_destroy
static av_always_inline int pthread_mutex_destroy(pthread_mutex_t *mutex)
Definition: os2threads.h:112
av_image_get_linesize
int av_image_get_linesize(enum AVPixelFormat pix_fmt, int width, int plane)
Compute the size of an image line with format pix_fmt and width width for the plane plane.
Definition: imgutils.c:76
hwcontext_qsv.h
qsv_device_init
static int qsv_device_init(AVHWDeviceContext *ctx)
Definition: hwcontext_qsv.c:284
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:255
AVDXVA2DeviceContext
This struct is allocated as AVHWDeviceContext.hwctx.
Definition: hwcontext_dxva2.h:39
av_malloc_array
#define av_malloc_array(a, b)
Definition: tableprint_vlc.h:31
common.h
AVD3D11VADeviceContext
This struct is allocated as AVHWDeviceContext.hwctx.
Definition: hwcontext_d3d11va.h:45
QSVFramesContext::handle_pairs_internal
mfxHDLPair * handle_pairs_internal
Definition: hwcontext_qsv.c:108
AVD3D11FrameDescriptor::index
intptr_t index
The index into the array texture element representing the frame, or 0 if the texture is not an array ...
Definition: hwcontext_d3d11va.h:125
FFMIN
#define FFMIN(a, b)
Definition: macros.h:49
QSVFramesContext::surface_ptrs
mfxFrameSurface1 ** surface_ptrs
Definition: hwcontext_qsv.c:115
av_frame_unref
void av_frame_unref(AVFrame *frame)
Unreference all the buffers referenced by frame and reset the frame fields.
Definition: frame.c:576
av_mallocz
void * av_mallocz(size_t size)
Allocate a memory block with alignment suitable for all memory accesses (including vectors if availab...
Definition: mem.c:254
QSVFramesContext::session_download
mfxSession session_download
Definition: hwcontext_qsv.c:98
AVDXVA2FramesContext::surfaces
IDirect3DSurface9 ** surfaces
The surface pool.
Definition: hwcontext_dxva2.h:58
av_calloc
void * av_calloc(size_t nmemb, size_t size)
Definition: mem.c:262
AVHWFrameTransferDirection
AVHWFrameTransferDirection
Definition: hwcontext.h:403
AVHWFramesContext
This struct describes a set or pool of "hardware" frames (i.e.
Definition: hwcontext.h:115
hwcontext_vaapi.h
qsv_map_to
static int qsv_map_to(AVHWFramesContext *dst_ctx, AVFrame *dst, const AVFrame *src, int flags)
Definition: hwcontext_qsv.c:1944
AV_PIX_FMT_PAL8
@ AV_PIX_FMT_PAL8
8 bits with AV_PIX_FMT_RGB32 palette
Definition: pixfmt.h:84
ret
ret
Definition: filter_design.txt:187
pix_fmt
enum AVPixelFormat pix_fmt
Definition: hwcontext_qsv.c:125
AVHWDeviceContext::type
enum AVHWDeviceType type
This field identifies the underlying API used for hardware access.
Definition: hwcontext.h:72
pixfmt.h
AV_PIX_FMT_NV12
@ AV_PIX_FMT_NV12
planar YUV 4:2:0, 12bpp, 1 plane for Y and 1 plane for the UV components, which are interleaved (firs...
Definition: pixfmt.h:96
AVHWFramesContext::device_ctx
AVHWDeviceContext * device_ctx
The parent AVHWDeviceContext.
Definition: hwcontext.h:134
AVHWFramesContext::hwctx
void * hwctx
The format-specific data, allocated and freed automatically along with this context.
Definition: hwcontext.h:150
av_hwdevice_ctx_create
int av_hwdevice_ctx_create(AVBufferRef **pdevice_ref, enum AVHWDeviceType type, const char *device, AVDictionary *opts, int flags)
Open a device of the specified type and create an AVHWDeviceContext for it.
Definition: hwcontext.c:600
QSVDeviceContext::impl
mfxIMPL impl
Definition: hwcontext_qsv.c:86
QSVFramesContext::realigned_download_frame
AVFrame realigned_download_frame
Definition: hwcontext_qsv.c:121
av_hwframe_transfer_data
int av_hwframe_transfer_data(AVFrame *dst, const AVFrame *src, int flags)
Copy data to or from a hw surface.
Definition: hwcontext.c:433
frame_lock
static mfxStatus frame_lock(mfxHDL pthis, mfxMemId mid, mfxFrameData *ptr)
Definition: hwcontext_qsv.c:657
AV_PIX_FMT_UYVY422
@ AV_PIX_FMT_UYVY422
packed YUV 4:2:2, 16bpp, Cb Y0 Cr Y1
Definition: pixfmt.h:88
AVFrame::hw_frames_ctx
AVBufferRef * hw_frames_ctx
For hwaccel-format frames, this should be a reference to the AVHWFramesContext describing the frame.
Definition: frame.h:695
AV_HWDEVICE_TYPE_QSV
@ AV_HWDEVICE_TYPE_QSV
Definition: hwcontext.h:33
qsv_pool_release_dummy
static void qsv_pool_release_dummy(void *opaque, uint8_t *data)
Definition: hwcontext_qsv.c:373
AVFrame::height
int height
Definition: frame.h:416
QSVDeviceContext::child_pix_fmt
enum AVPixelFormat child_pix_fmt
Definition: hwcontext_qsv.c:89
AVVAAPIFramesContext::nb_surfaces
int nb_surfaces
Definition: hwcontext_vaapi.h:102
AVQSVDeviceContext::session
mfxSession session
Definition: hwcontext_qsv.h:36
AV_PIX_FMT_NONE
@ AV_PIX_FMT_NONE
Definition: pixfmt.h:72
QSVFramesContext::session_upload
mfxSession session_upload
Definition: hwcontext_qsv.c:100
qsv_device_create
static int qsv_device_create(AVHWDeviceContext *ctx, const char *device, AVDictionary *opts, int flags)
Definition: hwcontext_qsv.c:2174
AV_PIX_FMT_P010
#define AV_PIX_FMT_P010
Definition: pixfmt.h:528
AVQSVFramesContext
This struct is allocated as AVHWFramesContext.hwctx.
Definition: hwcontext_qsv.h:53
AVHWFramesContext::initial_pool_size
int initial_pool_size
Initial size of the frame pool.
Definition: hwcontext.h:187
desc
const char * desc
Definition: libsvtav1.c:75
mem.h
AVBufferRef
A reference to a data buffer.
Definition: buffer.h:82
mfx_shift
uint16_t mfx_shift
Definition: hwcontext_qsv.c:127
qsv_shift_from_pix_fmt
static uint16_t qsv_shift_from_pix_fmt(enum AVPixelFormat pix_fmt)
Definition: hwcontext_qsv.c:209
AVPixFmtDescriptor
Descriptor that unambiguously describes how the bits of a pixel are stored in the up to 4 data planes...
Definition: pixdesc.h:69
hwcontext_internal.h
AVVAAPIFramesContext
VAAPI-specific data associated with a frame pool.
Definition: hwcontext_vaapi.h:88
QSVFramesContext::surfaces_internal
mfxFrameSurface1 * surfaces_internal
Definition: hwcontext_qsv.c:107
AVDictionaryEntry
Definition: dict.h:89
FFALIGN
#define FFALIGN(x, a)
Definition: macros.h:78
QSVFramesContext
Definition: qsv_internal.h:114
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:34
av_dict_set
int av_dict_set(AVDictionary **pm, const char *key, const char *value, int flags)
Set the given entry in *pm, overwriting an existing entry.
Definition: dict.c:88
src
INIT_CLIP pixel * src
Definition: h264pred_template.c:418
imgutils.h
AV_PIX_FMT_XV36
#define AV_PIX_FMT_XV36
Definition: pixfmt.h:535
flags
#define flags(name, subs,...)
Definition: cbs_av1.c:482
hwcontext.h
AVFrame::linesize
int linesize[AV_NUM_DATA_POINTERS]
For video, a positive or negative value, which is typically indicating the size in bytes of each pict...
Definition: frame.h:389
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:27
HWContextType
Definition: hwcontext_internal.h:29
qsv_pool_alloc
static AVBufferRef * qsv_pool_alloc(void *opaque, size_t size)
Definition: hwcontext_qsv.c:377
ID3D11Device
void ID3D11Device
Definition: nvenc.h:28
AVVAAPIDeviceContext
VAAPI connection details.
Definition: hwcontext_vaapi.h:68
AVDictionaryEntry::value
char * value
Definition: dict.h:91
AV_PIX_FMT_VUYX
@ AV_PIX_FMT_VUYX
packed VUYX 4:4:4, 32bpp, Variant of VUYA where alpha channel is left undefined
Definition: pixfmt.h:406
hwcontext_d3d11va.h
qsv_init_pool
static int qsv_init_pool(AVHWFramesContext *ctx, uint32_t fourcc)
Definition: hwcontext_qsv.c:573
QSVFramesContext::p
AVQSVFramesContext p
The public AVQSVFramesContext.
Definition: hwcontext_qsv.c:96
pthread_mutex_lock
#define pthread_mutex_lock(a)
Definition: ffprobe.c:77