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 <stdint.h>
20 #include <string.h>
21 
22 #include <mfx/mfxvideo.h>
23 
24 #include "config.h"
25 
26 #if HAVE_PTHREADS
27 #include <pthread.h>
28 #endif
29 
30 #if CONFIG_VAAPI
31 #include "hwcontext_vaapi.h"
32 #endif
33 #if CONFIG_DXVA2
34 #include "hwcontext_dxva2.h"
35 #endif
36 
37 #include "buffer.h"
38 #include "common.h"
39 #include "hwcontext.h"
40 #include "hwcontext_internal.h"
41 #include "hwcontext_qsv.h"
42 #include "mem.h"
43 #include "pixfmt.h"
44 #include "pixdesc.h"
45 #include "time.h"
46 
47 typedef struct QSVDevicePriv {
50 
51 typedef struct QSVDeviceContext {
52  mfxHDL handle;
53  mfxHandleType handle_type;
54  mfxVersion ver;
55  mfxIMPL impl;
56 
60 
61 typedef struct QSVFramesContext {
62  mfxSession session_download;
64  mfxSession session_upload;
66 #if HAVE_PTHREADS
67  pthread_mutex_t session_lock;
68  pthread_cond_t session_cond;
69 #endif
70 
72  mfxFrameSurface1 *surfaces_internal;
74 
75  // used in the frame allocator for non-opaque surfaces
76  mfxMemId *mem_ids;
77  // used in the opaque alloc request for opaque surfaces
78  mfxFrameSurface1 **surface_ptrs;
79 
80  mfxExtOpaqueSurfaceAlloc opaque_alloc;
81  mfxExtBuffer *ext_buffers[1];
83 
84 static const struct {
85  mfxHandleType handle_type;
89 #if CONFIG_VAAPI
90  { MFX_HANDLE_VA_DISPLAY, AV_HWDEVICE_TYPE_VAAPI, AV_PIX_FMT_VAAPI },
91 #endif
92 #if CONFIG_DXVA2
93  { MFX_HANDLE_D3D9_DEVICE_MANAGER, AV_HWDEVICE_TYPE_DXVA2, AV_PIX_FMT_DXVA2_VLD },
94 #endif
95  { 0 },
96 };
97 
98 static const struct {
100  uint32_t fourcc;
102  { AV_PIX_FMT_NV12, MFX_FOURCC_NV12 },
103  { AV_PIX_FMT_BGRA, MFX_FOURCC_RGB4 },
104  { AV_PIX_FMT_P010, MFX_FOURCC_P010 },
105  { AV_PIX_FMT_PAL8, MFX_FOURCC_P8 },
106 };
107 
109 {
110  int i;
111  for (i = 0; i < FF_ARRAY_ELEMS(supported_pixel_formats); i++) {
113  return supported_pixel_formats[i].fourcc;
114  }
115  return 0;
116 }
117 
119 {
120  AVQSVDeviceContext *hwctx = ctx->hwctx;
121  QSVDeviceContext *s = ctx->internal->priv;
122 
123  mfxStatus err;
124  int i;
125 
126  for (i = 0; supported_handle_types[i].handle_type; i++) {
127  err = MFXVideoCORE_GetHandle(hwctx->session, supported_handle_types[i].handle_type,
128  &s->handle);
129  if (err == MFX_ERR_NONE) {
130  s->handle_type = supported_handle_types[i].handle_type;
131  s->child_device_type = supported_handle_types[i].device_type;
132  s->child_pix_fmt = supported_handle_types[i].pix_fmt;
133  break;
134  }
135  }
136  if (!s->handle) {
137  av_log(ctx, AV_LOG_VERBOSE, "No supported hw handle could be retrieved "
138  "from the session\n");
139  }
140 
141  err = MFXQueryIMPL(hwctx->session, &s->impl);
142  if (err == MFX_ERR_NONE)
143  err = MFXQueryVersion(hwctx->session, &s->ver);
144  if (err != MFX_ERR_NONE) {
145  av_log(ctx, AV_LOG_ERROR, "Error querying the session attributes\n");
146  return AVERROR_UNKNOWN;
147  }
148 
149  return 0;
150 }
151 
153 {
154  QSVFramesContext *s = ctx->internal->priv;
155 
156  if (s->session_download) {
157  MFXVideoVPP_Close(s->session_download);
158  MFXClose(s->session_download);
159  }
160  s->session_download = NULL;
161  s->session_download_init = 0;
162 
163  if (s->session_upload) {
164  MFXVideoVPP_Close(s->session_upload);
165  MFXClose(s->session_upload);
166  }
167  s->session_upload = NULL;
168  s->session_upload_init = 0;
169 
170 #if HAVE_PTHREADS
171  pthread_mutex_destroy(&s->session_lock);
172  pthread_cond_destroy(&s->session_cond);
173 #endif
174 
175  av_freep(&s->mem_ids);
176  av_freep(&s->surface_ptrs);
177  av_freep(&s->surfaces_internal);
178  av_buffer_unref(&s->child_frames_ref);
179 }
180 
181 static void qsv_pool_release_dummy(void *opaque, uint8_t *data)
182 {
183 }
184 
185 static AVBufferRef *qsv_pool_alloc(void *opaque, int size)
186 {
188  QSVFramesContext *s = ctx->internal->priv;
189  AVQSVFramesContext *hwctx = ctx->hwctx;
190 
191  if (s->nb_surfaces_used < hwctx->nb_surfaces) {
192  s->nb_surfaces_used++;
193  return av_buffer_create((uint8_t*)(s->surfaces_internal + s->nb_surfaces_used - 1),
194  sizeof(*hwctx->surfaces), qsv_pool_release_dummy, NULL, 0);
195  }
196 
197  return NULL;
198 }
199 
201 {
202  AVQSVFramesContext *hwctx = ctx->hwctx;
203  QSVFramesContext *s = ctx->internal->priv;
204  QSVDeviceContext *device_priv = ctx->device_ctx->internal->priv;
205 
206  AVBufferRef *child_device_ref = NULL;
207  AVBufferRef *child_frames_ref = NULL;
208 
209  AVHWDeviceContext *child_device_ctx;
210  AVHWFramesContext *child_frames_ctx;
211 
212  int i, ret = 0;
213 
214  if (!device_priv->handle) {
216  "Cannot create a non-opaque internal surface pool without "
217  "a hardware handle\n");
218  return AVERROR(EINVAL);
219  }
220 
221  child_device_ref = av_hwdevice_ctx_alloc(device_priv->child_device_type);
222  if (!child_device_ref)
223  return AVERROR(ENOMEM);
224  child_device_ctx = (AVHWDeviceContext*)child_device_ref->data;
225 
226 #if CONFIG_VAAPI
227  if (child_device_ctx->type == AV_HWDEVICE_TYPE_VAAPI) {
228  AVVAAPIDeviceContext *child_device_hwctx = child_device_ctx->hwctx;
229  child_device_hwctx->display = (VADisplay)device_priv->handle;
230  }
231 #endif
232 #if CONFIG_DXVA2
233  if (child_device_ctx->type == AV_HWDEVICE_TYPE_DXVA2) {
234  AVDXVA2DeviceContext *child_device_hwctx = child_device_ctx->hwctx;
235  child_device_hwctx->devmgr = (IDirect3DDeviceManager9*)device_priv->handle;
236  }
237 #endif
238 
239  ret = av_hwdevice_ctx_init(child_device_ref);
240  if (ret < 0) {
241  av_log(ctx, AV_LOG_ERROR, "Error initializing a child device context\n");
242  goto fail;
243  }
244 
245  child_frames_ref = av_hwframe_ctx_alloc(child_device_ref);
246  if (!child_frames_ref) {
247  ret = AVERROR(ENOMEM);
248  goto fail;
249  }
250  child_frames_ctx = (AVHWFramesContext*)child_frames_ref->data;
251 
252  child_frames_ctx->format = device_priv->child_pix_fmt;
253  child_frames_ctx->sw_format = ctx->sw_format;
254  child_frames_ctx->initial_pool_size = ctx->initial_pool_size;
255  child_frames_ctx->width = FFALIGN(ctx->width, 16);
256  child_frames_ctx->height = FFALIGN(ctx->height, 16);
257 
258 #if CONFIG_DXVA2
259  if (child_device_ctx->type == AV_HWDEVICE_TYPE_DXVA2) {
260  AVDXVA2FramesContext *child_frames_hwctx = child_frames_ctx->hwctx;
261  if (hwctx->frame_type & MFX_MEMTYPE_VIDEO_MEMORY_PROCESSOR_TARGET)
262  child_frames_hwctx->surface_type = DXVA2_VideoProcessorRenderTarget;
263  else
264  child_frames_hwctx->surface_type = DXVA2_VideoDecoderRenderTarget;
265  }
266 #endif
267 
268  ret = av_hwframe_ctx_init(child_frames_ref);
269  if (ret < 0) {
270  av_log(ctx, AV_LOG_ERROR, "Error initializing a child frames context\n");
271  goto fail;
272  }
273 
274 #if CONFIG_VAAPI
275  if (child_device_ctx->type == AV_HWDEVICE_TYPE_VAAPI) {
276  AVVAAPIFramesContext *child_frames_hwctx = child_frames_ctx->hwctx;
277  for (i = 0; i < ctx->initial_pool_size; i++)
278  s->surfaces_internal[i].Data.MemId = child_frames_hwctx->surface_ids + i;
279  hwctx->frame_type = MFX_MEMTYPE_VIDEO_MEMORY_DECODER_TARGET;
280  }
281 #endif
282 #if CONFIG_DXVA2
283  if (child_device_ctx->type == AV_HWDEVICE_TYPE_DXVA2) {
284  AVDXVA2FramesContext *child_frames_hwctx = child_frames_ctx->hwctx;
285  for (i = 0; i < ctx->initial_pool_size; i++)
286  s->surfaces_internal[i].Data.MemId = (mfxMemId)child_frames_hwctx->surfaces[i];
287  if (child_frames_hwctx->surface_type == DXVA2_VideoProcessorRenderTarget)
288  hwctx->frame_type = MFX_MEMTYPE_VIDEO_MEMORY_PROCESSOR_TARGET;
289  else
290  hwctx->frame_type = MFX_MEMTYPE_VIDEO_MEMORY_DECODER_TARGET;
291  }
292 #endif
293 
294  s->child_frames_ref = child_frames_ref;
295  child_frames_ref = NULL;
296 
297 fail:
298  av_buffer_unref(&child_device_ref);
299  av_buffer_unref(&child_frames_ref);
300  return ret;
301 }
302 
303 static int qsv_init_surface(AVHWFramesContext *ctx, mfxFrameSurface1 *surf)
304 {
305  const AVPixFmtDescriptor *desc;
306  uint32_t fourcc;
307 
308  desc = av_pix_fmt_desc_get(ctx->sw_format);
309  if (!desc)
310  return AVERROR(EINVAL);
311 
312  fourcc = qsv_fourcc_from_pix_fmt(ctx->sw_format);
313  if (!fourcc)
314  return AVERROR(EINVAL);
315 
316  surf->Info.BitDepthLuma = desc->comp[0].depth;
317  surf->Info.BitDepthChroma = desc->comp[0].depth;
318  surf->Info.Shift = desc->comp[0].depth > 8;
319 
320  if (desc->log2_chroma_w && desc->log2_chroma_h)
321  surf->Info.ChromaFormat = MFX_CHROMAFORMAT_YUV420;
322  else if (desc->log2_chroma_w)
323  surf->Info.ChromaFormat = MFX_CHROMAFORMAT_YUV422;
324  else
325  surf->Info.ChromaFormat = MFX_CHROMAFORMAT_YUV444;
326 
327  surf->Info.FourCC = fourcc;
328  surf->Info.Width = FFALIGN(ctx->width, 16);
329  surf->Info.CropW = ctx->width;
330  surf->Info.Height = FFALIGN(ctx->height, 16);
331  surf->Info.CropH = ctx->height;
332  surf->Info.FrameRateExtN = 25;
333  surf->Info.FrameRateExtD = 1;
334  surf->Info.PicStruct = MFX_PICSTRUCT_PROGRESSIVE;
335 
336  return 0;
337 }
338 
340 {
341  QSVFramesContext *s = ctx->internal->priv;
342  AVQSVFramesContext *frames_hwctx = ctx->hwctx;
343 
344  int i, ret = 0;
345 
346  if (ctx->initial_pool_size <= 0) {
347  av_log(ctx, AV_LOG_ERROR, "QSV requires a fixed frame pool size\n");
348  return AVERROR(EINVAL);
349  }
350 
351  s->surfaces_internal = av_mallocz_array(ctx->initial_pool_size,
352  sizeof(*s->surfaces_internal));
353  if (!s->surfaces_internal)
354  return AVERROR(ENOMEM);
355 
356  for (i = 0; i < ctx->initial_pool_size; i++) {
357  ret = qsv_init_surface(ctx, &s->surfaces_internal[i]);
358  if (ret < 0)
359  return ret;
360  }
361 
362  if (!(frames_hwctx->frame_type & MFX_MEMTYPE_OPAQUE_FRAME)) {
364  if (ret < 0)
365  return ret;
366  }
367 
368  ctx->internal->pool_internal = av_buffer_pool_init2(sizeof(mfxFrameSurface1),
370  if (!ctx->internal->pool_internal)
371  return AVERROR(ENOMEM);
372 
373  frames_hwctx->surfaces = s->surfaces_internal;
374  frames_hwctx->nb_surfaces = ctx->initial_pool_size;
375 
376  return 0;
377 }
378 
379 static mfxStatus frame_alloc(mfxHDL pthis, mfxFrameAllocRequest *req,
380  mfxFrameAllocResponse *resp)
381 {
382  AVHWFramesContext *ctx = pthis;
383  QSVFramesContext *s = ctx->internal->priv;
384  AVQSVFramesContext *hwctx = ctx->hwctx;
385  mfxFrameInfo *i = &req->Info;
386  mfxFrameInfo *i1 = &hwctx->surfaces[0].Info;
387 
388  if (!(req->Type & MFX_MEMTYPE_VIDEO_MEMORY_PROCESSOR_TARGET) ||
389  !(req->Type & (MFX_MEMTYPE_FROM_VPPIN | MFX_MEMTYPE_FROM_VPPOUT)) ||
390  !(req->Type & MFX_MEMTYPE_EXTERNAL_FRAME))
391  return MFX_ERR_UNSUPPORTED;
392  if (i->Width > i1->Width || i->Height > i1->Height ||
393  i->FourCC != i1->FourCC || i->ChromaFormat != i1->ChromaFormat) {
394  av_log(ctx, AV_LOG_ERROR, "Mismatching surface properties in an "
395  "allocation request: %dx%d %d %d vs %dx%d %d %d\n",
396  i->Width, i->Height, i->FourCC, i->ChromaFormat,
397  i1->Width, i1->Height, i1->FourCC, i1->ChromaFormat);
398  return MFX_ERR_UNSUPPORTED;
399  }
400 
401  resp->mids = s->mem_ids;
402  resp->NumFrameActual = hwctx->nb_surfaces;
403 
404  return MFX_ERR_NONE;
405 }
406 
407 static mfxStatus frame_free(mfxHDL pthis, mfxFrameAllocResponse *resp)
408 {
409  return MFX_ERR_NONE;
410 }
411 
412 static mfxStatus frame_lock(mfxHDL pthis, mfxMemId mid, mfxFrameData *ptr)
413 {
414  return MFX_ERR_UNSUPPORTED;
415 }
416 
417 static mfxStatus frame_unlock(mfxHDL pthis, mfxMemId mid, mfxFrameData *ptr)
418 {
419  return MFX_ERR_UNSUPPORTED;
420 }
421 
422 static mfxStatus frame_get_hdl(mfxHDL pthis, mfxMemId mid, mfxHDL *hdl)
423 {
424  *hdl = mid;
425  return MFX_ERR_NONE;
426 }
427 
429  mfxSession *session, int upload)
430 {
431  QSVFramesContext *s = ctx->internal->priv;
432  AVQSVFramesContext *frames_hwctx = ctx->hwctx;
433  QSVDeviceContext *device_priv = ctx->device_ctx->internal->priv;
434  int opaque = !!(frames_hwctx->frame_type & MFX_MEMTYPE_OPAQUE_FRAME);
435 
436  mfxFrameAllocator frame_allocator = {
437  .pthis = ctx,
438  .Alloc = frame_alloc,
439  .Lock = frame_lock,
440  .Unlock = frame_unlock,
441  .GetHDL = frame_get_hdl,
442  .Free = frame_free,
443  };
444 
445  mfxVideoParam par;
446  mfxStatus err;
447 
448  err = MFXInit(device_priv->impl, &device_priv->ver, session);
449  if (err != MFX_ERR_NONE) {
450  av_log(ctx, AV_LOG_ERROR, "Error initializing an internal session\n");
451  return AVERROR_UNKNOWN;
452  }
453 
454  if (device_priv->handle) {
455  err = MFXVideoCORE_SetHandle(*session, device_priv->handle_type,
456  device_priv->handle);
457  if (err != MFX_ERR_NONE)
458  return AVERROR_UNKNOWN;
459  }
460 
461  if (!opaque) {
462  err = MFXVideoCORE_SetFrameAllocator(*session, &frame_allocator);
463  if (err != MFX_ERR_NONE)
464  return AVERROR_UNKNOWN;
465  }
466 
467  memset(&par, 0, sizeof(par));
468 
469  if (opaque) {
470  par.ExtParam = s->ext_buffers;
471  par.NumExtParam = FF_ARRAY_ELEMS(s->ext_buffers);
472  par.IOPattern = upload ? MFX_IOPATTERN_OUT_OPAQUE_MEMORY :
473  MFX_IOPATTERN_IN_OPAQUE_MEMORY;
474  } else {
475  par.IOPattern = upload ? MFX_IOPATTERN_OUT_VIDEO_MEMORY :
476  MFX_IOPATTERN_IN_VIDEO_MEMORY;
477  }
478 
479  par.IOPattern |= upload ? MFX_IOPATTERN_IN_SYSTEM_MEMORY :
480  MFX_IOPATTERN_OUT_SYSTEM_MEMORY;
481  par.AsyncDepth = 1;
482 
483  par.vpp.In = frames_hwctx->surfaces[0].Info;
484 
485  /* Apparently VPP requires the frame rate to be set to some value, otherwise
486  * init will fail (probably for the framerate conversion filter). Since we
487  * are only doing data upload/download here, we just invent an arbitrary
488  * value */
489  par.vpp.In.FrameRateExtN = 25;
490  par.vpp.In.FrameRateExtD = 1;
491  par.vpp.Out = par.vpp.In;
492 
493  err = MFXVideoVPP_Init(*session, &par);
494  if (err != MFX_ERR_NONE) {
495  av_log(ctx, AV_LOG_VERBOSE, "Error opening the internal VPP session."
496  "Surface upload/download will not be possible\n");
497  MFXClose(*session);
498  *session = NULL;
499  }
500 
501  return 0;
502 }
503 
505 {
506  QSVFramesContext *s = ctx->internal->priv;
507  AVQSVFramesContext *frames_hwctx = ctx->hwctx;
508 
509  int opaque = !!(frames_hwctx->frame_type & MFX_MEMTYPE_OPAQUE_FRAME);
510 
511  uint32_t fourcc;
512  int i, ret;
513 
514  fourcc = qsv_fourcc_from_pix_fmt(ctx->sw_format);
515  if (!fourcc) {
516  av_log(ctx, AV_LOG_ERROR, "Unsupported pixel format\n");
517  return AVERROR(ENOSYS);
518  }
519 
520  if (!ctx->pool) {
522  if (ret < 0) {
523  av_log(ctx, AV_LOG_ERROR, "Error creating an internal frame pool\n");
524  return ret;
525  }
526  }
527 
528  if (opaque) {
529  s->surface_ptrs = av_mallocz_array(frames_hwctx->nb_surfaces,
530  sizeof(*s->surface_ptrs));
531  if (!s->surface_ptrs)
532  return AVERROR(ENOMEM);
533 
534  for (i = 0; i < frames_hwctx->nb_surfaces; i++)
535  s->surface_ptrs[i] = frames_hwctx->surfaces + i;
536 
537  s->opaque_alloc.In.Surfaces = s->surface_ptrs;
538  s->opaque_alloc.In.NumSurface = frames_hwctx->nb_surfaces;
539  s->opaque_alloc.In.Type = frames_hwctx->frame_type;
540 
541  s->opaque_alloc.Out = s->opaque_alloc.In;
542 
543  s->opaque_alloc.Header.BufferId = MFX_EXTBUFF_OPAQUE_SURFACE_ALLOCATION;
544  s->opaque_alloc.Header.BufferSz = sizeof(s->opaque_alloc);
545 
546  s->ext_buffers[0] = (mfxExtBuffer*)&s->opaque_alloc;
547  } else {
548  s->mem_ids = av_mallocz_array(frames_hwctx->nb_surfaces, sizeof(*s->mem_ids));
549  if (!s->mem_ids)
550  return AVERROR(ENOMEM);
551 
552  for (i = 0; i < frames_hwctx->nb_surfaces; i++)
553  s->mem_ids[i] = frames_hwctx->surfaces[i].Data.MemId;
554  }
555 
556  s->session_download = NULL;
557  s->session_upload = NULL;
558 
559  s->session_download_init = 0;
560  s->session_upload_init = 0;
561 
562 #if HAVE_PTHREADS
563  pthread_mutex_init(&s->session_lock, NULL);
564  pthread_cond_init(&s->session_cond, NULL);
565 #endif
566 
567  return 0;
568 }
569 
571 {
572  frame->buf[0] = av_buffer_pool_get(ctx->pool);
573  if (!frame->buf[0])
574  return AVERROR(ENOMEM);
575 
576  frame->data[3] = frame->buf[0]->data;
577  frame->format = AV_PIX_FMT_QSV;
578  frame->width = ctx->width;
579  frame->height = ctx->height;
580 
581  return 0;
582 }
583 
586  enum AVPixelFormat **formats)
587 {
588  enum AVPixelFormat *fmts;
589 
590  fmts = av_malloc_array(2, sizeof(*fmts));
591  if (!fmts)
592  return AVERROR(ENOMEM);
593 
594  fmts[0] = ctx->sw_format;
595  fmts[1] = AV_PIX_FMT_NONE;
596 
597  *formats = fmts;
598 
599  return 0;
600 }
601 
603  AVHWFramesContext *src_ctx, int flags)
604 {
605  AVQSVFramesContext *src_hwctx = src_ctx->hwctx;
606  int i;
607 
608  switch (dst_ctx->device_ctx->type) {
609 #if CONFIG_VAAPI
611  {
612  AVVAAPIFramesContext *dst_hwctx = dst_ctx->hwctx;
613  dst_hwctx->surface_ids = av_mallocz_array(src_hwctx->nb_surfaces,
614  sizeof(*dst_hwctx->surface_ids));
615  if (!dst_hwctx->surface_ids)
616  return AVERROR(ENOMEM);
617  for (i = 0; i < src_hwctx->nb_surfaces; i++)
618  dst_hwctx->surface_ids[i] =
619  *(VASurfaceID*)src_hwctx->surfaces[i].Data.MemId;
620  dst_hwctx->nb_surfaces = src_hwctx->nb_surfaces;
621  }
622  break;
623 #endif
624 #if CONFIG_DXVA2
626  {
627  AVDXVA2FramesContext *dst_hwctx = dst_ctx->hwctx;
628  dst_hwctx->surfaces = av_mallocz_array(src_hwctx->nb_surfaces,
629  sizeof(*dst_hwctx->surfaces));
630  if (!dst_hwctx->surfaces)
631  return AVERROR(ENOMEM);
632  for (i = 0; i < src_hwctx->nb_surfaces; i++)
633  dst_hwctx->surfaces[i] =
634  (IDirect3DSurface9*)src_hwctx->surfaces[i].Data.MemId;
635  dst_hwctx->nb_surfaces = src_hwctx->nb_surfaces;
636  if (src_hwctx->frame_type == MFX_MEMTYPE_VIDEO_MEMORY_DECODER_TARGET)
637  dst_hwctx->surface_type = DXVA2_VideoDecoderRenderTarget;
638  else
639  dst_hwctx->surface_type = DXVA2_VideoProcessorRenderTarget;
640  }
641  break;
642 #endif
643  default:
644  return AVERROR(ENOSYS);
645  }
646 
647  return 0;
648 }
649 
651  AVFrame *dst, const AVFrame *src, int flags)
652 {
653  QSVFramesContext *s = ctx->internal->priv;
654  mfxFrameSurface1 *surf = (mfxFrameSurface1*)src->data[3];
655  AVHWFramesContext *child_frames_ctx;
656  const AVPixFmtDescriptor *desc;
657  uint8_t *child_data;
658  AVFrame *dummy;
659  int ret = 0;
660 
661  if (!s->child_frames_ref)
662  return AVERROR(ENOSYS);
663  child_frames_ctx = (AVHWFramesContext*)s->child_frames_ref->data;
664 
665  switch (child_frames_ctx->device_ctx->type) {
666 #if CONFIG_VAAPI
668  child_data = (uint8_t*)(intptr_t)*(VASurfaceID*)surf->Data.MemId;
669  break;
670 #endif
671 #if CONFIG_DXVA2
673  child_data = surf->Data.MemId;
674  break;
675 #endif
676  default:
677  return AVERROR(ENOSYS);
678  }
679 
680  if (dst->format == child_frames_ctx->format) {
681  ret = ff_hwframe_map_create(s->child_frames_ref,
682  dst, src, NULL, NULL);
683  if (ret < 0)
684  return ret;
685 
686  dst->width = src->width;
687  dst->height = src->height;
688  dst->data[3] = child_data;
689 
690  return 0;
691  }
692 
694  if (desc && desc->flags & AV_PIX_FMT_FLAG_HWACCEL) {
695  // This only supports mapping to software.
696  return AVERROR(ENOSYS);
697  }
698 
699  dummy = av_frame_alloc();
700  if (!dummy)
701  return AVERROR(ENOMEM);
702 
703  dummy->buf[0] = av_buffer_ref(src->buf[0]);
704  dummy->hw_frames_ctx = av_buffer_ref(s->child_frames_ref);
705  if (!dummy->buf[0] || !dummy->hw_frames_ctx)
706  goto fail;
707 
708  dummy->format = child_frames_ctx->format;
709  dummy->width = src->width;
710  dummy->height = src->height;
711  dummy->data[3] = child_data;
712 
713  ret = av_hwframe_map(dst, dummy, flags);
714 
715 fail:
717 
718  return ret;
719 }
720 
722  const AVFrame *src)
723 {
724  QSVFramesContext *s = ctx->internal->priv;
725  AVHWFramesContext *child_frames_ctx = (AVHWFramesContext*)s->child_frames_ref->data;
726  int download = !!src->hw_frames_ctx;
727  mfxFrameSurface1 *surf = (mfxFrameSurface1*)(download ? src->data[3] : dst->data[3]);
728 
729  AVFrame *dummy;
730  int ret;
731 
732  dummy = av_frame_alloc();
733  if (!dummy)
734  return AVERROR(ENOMEM);
735 
736  dummy->format = child_frames_ctx->format;
737  dummy->width = src->width;
738  dummy->height = src->height;
739  dummy->buf[0] = download ? src->buf[0] : dst->buf[0];
740  dummy->data[3] = surf->Data.MemId;
741  dummy->hw_frames_ctx = s->child_frames_ref;
742 
743  ret = download ? av_hwframe_transfer_data(dst, dummy, 0) :
745 
746  dummy->buf[0] = NULL;
747  dummy->data[3] = NULL;
748  dummy->hw_frames_ctx = NULL;
749 
751 
752  return ret;
753 }
754 
755 static int map_frame_to_surface(const AVFrame *frame, mfxFrameSurface1 *surface)
756 {
757  switch (frame->format) {
758  case AV_PIX_FMT_NV12:
759  case AV_PIX_FMT_P010:
760  surface->Data.Y = frame->data[0];
761  surface->Data.UV = frame->data[1];
762  break;
763 
764  case AV_PIX_FMT_YUV420P:
765  surface->Data.Y = frame->data[0];
766  surface->Data.U = frame->data[1];
767  surface->Data.V = frame->data[2];
768  break;
769 
770  case AV_PIX_FMT_BGRA:
771  surface->Data.B = frame->data[0];
772  surface->Data.G = frame->data[0] + 1;
773  surface->Data.R = frame->data[0] + 2;
774  surface->Data.A = frame->data[0] + 3;
775  break;
776 
777  default:
778  return MFX_ERR_UNSUPPORTED;
779  }
780  surface->Data.Pitch = frame->linesize[0];
781  surface->Data.TimeStamp = frame->pts;
782 
783  return 0;
784 }
785 
787  const AVFrame *src)
788 {
789  QSVFramesContext *s = ctx->internal->priv;
790  mfxFrameSurface1 out = {{ 0 }};
791  mfxFrameSurface1 *in = (mfxFrameSurface1*)src->data[3];
792 
793  mfxSyncPoint sync = NULL;
794  mfxStatus err;
795  int ret = 0;
796 
797  while (!s->session_download_init && !s->session_download && !ret) {
798 #if HAVE_PTHREADS
799  if (pthread_mutex_trylock(&s->session_lock) == 0) {
800 #endif
801  if (!s->session_download_init) {
802  ret = qsv_init_internal_session(ctx, &s->session_download, 0);
803  if (s->session_download)
804  s->session_download_init = 1;
805  }
806 #if HAVE_PTHREADS
807  pthread_mutex_unlock(&s->session_lock);
808  pthread_cond_signal(&s->session_cond);
809  } else {
810  pthread_mutex_lock(&s->session_lock);
811  while (!s->session_download_init && !s->session_download) {
812  pthread_cond_wait(&s->session_cond, &s->session_lock);
813  }
814  pthread_mutex_unlock(&s->session_lock);
815  }
816 #endif
817  }
818 
819  if (ret < 0)
820  return ret;
821 
822  if (!s->session_download) {
823  if (s->child_frames_ref)
824  return qsv_transfer_data_child(ctx, dst, src);
825 
826  av_log(ctx, AV_LOG_ERROR, "Surface download not possible\n");
827  return AVERROR(ENOSYS);
828  }
829 
830  out.Info = in->Info;
831  map_frame_to_surface(dst, &out);
832 
833  do {
834  err = MFXVideoVPP_RunFrameVPPAsync(s->session_download, in, &out, NULL, &sync);
835  if (err == MFX_WRN_DEVICE_BUSY)
836  av_usleep(1);
837  } while (err == MFX_WRN_DEVICE_BUSY);
838 
839  if (err < 0 || !sync) {
840  av_log(ctx, AV_LOG_ERROR, "Error downloading the surface\n");
841  return AVERROR_UNKNOWN;
842  }
843 
844  do {
845  err = MFXVideoCORE_SyncOperation(s->session_download, sync, 1000);
846  } while (err == MFX_WRN_IN_EXECUTION);
847  if (err < 0) {
848  av_log(ctx, AV_LOG_ERROR, "Error synchronizing the operation: %d\n", err);
849  return AVERROR_UNKNOWN;
850  }
851 
852  return 0;
853 }
854 
856  const AVFrame *src)
857 {
858  QSVFramesContext *s = ctx->internal->priv;
859  mfxFrameSurface1 in = {{ 0 }};
860  mfxFrameSurface1 *out = (mfxFrameSurface1*)dst->data[3];
861 
862  mfxSyncPoint sync = NULL;
863  mfxStatus err;
864  int ret = 0;
865  /* make a copy if the input is not padded as libmfx requires */
866  AVFrame tmp_frame;
867  const AVFrame *src_frame;
868  int realigned = 0;
869 
870 
871  while (!s->session_upload_init && !s->session_upload && !ret) {
872 #if HAVE_PTHREADS
873  if (pthread_mutex_trylock(&s->session_lock) == 0) {
874 #endif
875  if (!s->session_upload_init) {
876  ret = qsv_init_internal_session(ctx, &s->session_upload, 1);
877  if (s->session_upload)
878  s->session_upload_init = 1;
879  }
880 #if HAVE_PTHREADS
881  pthread_mutex_unlock(&s->session_lock);
882  pthread_cond_signal(&s->session_cond);
883  } else {
884  pthread_mutex_lock(&s->session_lock);
885  while (!s->session_upload_init && !s->session_upload) {
886  pthread_cond_wait(&s->session_cond, &s->session_lock);
887  }
888  pthread_mutex_unlock(&s->session_lock);
889  }
890 #endif
891  }
892  if (ret < 0)
893  return ret;
894 
895  if (src->height & 15 || src->linesize[0] & 15) {
896  realigned = 1;
897  memset(&tmp_frame, 0, sizeof(tmp_frame));
898  tmp_frame.format = src->format;
899  tmp_frame.width = FFALIGN(src->width, 16);
900  tmp_frame.height = FFALIGN(src->height, 16);
901  ret = av_frame_get_buffer(&tmp_frame, 32);
902  if (ret < 0)
903  return ret;
904 
905  ret = av_frame_copy(&tmp_frame, src);
906  if (ret < 0) {
907  av_frame_unref(&tmp_frame);
908  return ret;
909  }
910  }
911 
912  src_frame = realigned ? &tmp_frame : src;
913 
914  if (!s->session_upload) {
915  if (s->child_frames_ref)
916  return qsv_transfer_data_child(ctx, dst, src_frame);
917 
918  av_log(ctx, AV_LOG_ERROR, "Surface upload not possible\n");
919  return AVERROR(ENOSYS);
920  }
921 
922  in.Info = out->Info;
923  map_frame_to_surface(src_frame, &in);
924 
925  do {
926  err = MFXVideoVPP_RunFrameVPPAsync(s->session_upload, &in, out, NULL, &sync);
927  if (err == MFX_WRN_DEVICE_BUSY)
928  av_usleep(1);
929  } while (err == MFX_WRN_DEVICE_BUSY);
930 
931  if (err < 0 || !sync) {
932  av_log(ctx, AV_LOG_ERROR, "Error uploading the surface\n");
933  return AVERROR_UNKNOWN;
934  }
935 
936  do {
937  err = MFXVideoCORE_SyncOperation(s->session_upload, sync, 1000);
938  } while (err == MFX_WRN_IN_EXECUTION);
939  if (err < 0) {
940  av_log(ctx, AV_LOG_ERROR, "Error synchronizing the operation\n");
941  return AVERROR_UNKNOWN;
942  }
943 
944  if (realigned)
945  av_frame_unref(&tmp_frame);
946 
947  return 0;
948 }
949 
951  AVHWFramesContext *src_ctx, int flags)
952 {
953  QSVFramesContext *s = dst_ctx->internal->priv;
954  AVQSVFramesContext *dst_hwctx = dst_ctx->hwctx;
955  int i;
956 
957  switch (src_ctx->device_ctx->type) {
958 #if CONFIG_VAAPI
960  {
961  AVVAAPIFramesContext *src_hwctx = src_ctx->hwctx;
962  s->surfaces_internal = av_mallocz_array(src_hwctx->nb_surfaces,
963  sizeof(*s->surfaces_internal));
964  if (!s->surfaces_internal)
965  return AVERROR(ENOMEM);
966  for (i = 0; i < src_hwctx->nb_surfaces; i++) {
967  qsv_init_surface(dst_ctx, &s->surfaces_internal[i]);
968  s->surfaces_internal[i].Data.MemId = src_hwctx->surface_ids + i;
969  }
970  dst_hwctx->nb_surfaces = src_hwctx->nb_surfaces;
971  dst_hwctx->frame_type = MFX_MEMTYPE_VIDEO_MEMORY_DECODER_TARGET;
972  }
973  break;
974 #endif
975 #if CONFIG_DXVA2
977  {
978  AVDXVA2FramesContext *src_hwctx = src_ctx->hwctx;
979  s->surfaces_internal = av_mallocz_array(src_hwctx->nb_surfaces,
980  sizeof(*s->surfaces_internal));
981  if (!s->surfaces_internal)
982  return AVERROR(ENOMEM);
983  for (i = 0; i < src_hwctx->nb_surfaces; i++) {
984  qsv_init_surface(dst_ctx, &s->surfaces_internal[i]);
985  s->surfaces_internal[i].Data.MemId = (mfxMemId)src_hwctx->surfaces[i];
986  }
987  dst_hwctx->nb_surfaces = src_hwctx->nb_surfaces;
988  if (src_hwctx->surface_type == DXVA2_VideoProcessorRenderTarget)
989  dst_hwctx->frame_type = MFX_MEMTYPE_VIDEO_MEMORY_PROCESSOR_TARGET;
990  else
991  dst_hwctx->frame_type = MFX_MEMTYPE_VIDEO_MEMORY_DECODER_TARGET;
992  }
993  break;
994 #endif
995  default:
996  return AVERROR(ENOSYS);
997  }
998 
999  dst_hwctx->surfaces = s->surfaces_internal;
1000 
1001  return 0;
1002 }
1003 
1004 static int qsv_map_to(AVHWFramesContext *dst_ctx,
1005  AVFrame *dst, const AVFrame *src, int flags)
1006 {
1007  AVQSVFramesContext *hwctx = dst_ctx->hwctx;
1008  int i, err;
1009 
1010  for (i = 0; i < hwctx->nb_surfaces; i++) {
1011 #if CONFIG_VAAPI
1012  if (*(VASurfaceID*)hwctx->surfaces[i].Data.MemId ==
1013  (VASurfaceID)(uintptr_t)src->data[3])
1014  break;
1015 #endif
1016 #if CONFIG_DXVA2
1017  if ((IDirect3DSurface9*)hwctx->surfaces[i].Data.MemId ==
1018  (IDirect3DSurface9*)(uintptr_t)src->data[3])
1019  break;
1020 #endif
1021  }
1022  if (i >= hwctx->nb_surfaces) {
1023  av_log(dst_ctx, AV_LOG_ERROR, "Trying to map from a surface which "
1024  "is not in the mapped frames context.\n");
1025  return AVERROR(EINVAL);
1026  }
1027 
1029  dst, src, NULL, NULL);
1030  if (err)
1031  return err;
1032 
1033  dst->width = src->width;
1034  dst->height = src->height;
1035  dst->data[3] = (uint8_t*)&hwctx->surfaces[i];
1036 
1037  return 0;
1038 }
1039 
1041  const void *hwconfig,
1042  AVHWFramesConstraints *constraints)
1043 {
1044  int i;
1045 
1047  sizeof(*constraints->valid_sw_formats));
1048  if (!constraints->valid_sw_formats)
1049  return AVERROR(ENOMEM);
1050 
1051  for (i = 0; i < FF_ARRAY_ELEMS(supported_pixel_formats); i++)
1052  constraints->valid_sw_formats[i] = supported_pixel_formats[i].pix_fmt;
1054 
1055  constraints->valid_hw_formats = av_malloc_array(2, sizeof(*constraints->valid_hw_formats));
1056  if (!constraints->valid_hw_formats)
1057  return AVERROR(ENOMEM);
1058 
1059  constraints->valid_hw_formats[0] = AV_PIX_FMT_QSV;
1060  constraints->valid_hw_formats[1] = AV_PIX_FMT_NONE;
1061 
1062  return 0;
1063 }
1064 
1066 {
1067  AVQSVDeviceContext *hwctx = ctx->hwctx;
1068  QSVDevicePriv *priv = ctx->user_opaque;
1069 
1070  if (hwctx->session)
1071  MFXClose(hwctx->session);
1072 
1074  av_freep(&priv);
1075 }
1076 
1077 static mfxIMPL choose_implementation(const char *device)
1078 {
1079  static const struct {
1080  const char *name;
1081  mfxIMPL impl;
1082  } impl_map[] = {
1083  { "auto", MFX_IMPL_AUTO },
1084  { "sw", MFX_IMPL_SOFTWARE },
1085  { "hw", MFX_IMPL_HARDWARE },
1086  { "auto_any", MFX_IMPL_AUTO_ANY },
1087  { "hw_any", MFX_IMPL_HARDWARE_ANY },
1088  { "hw2", MFX_IMPL_HARDWARE2 },
1089  { "hw3", MFX_IMPL_HARDWARE3 },
1090  { "hw4", MFX_IMPL_HARDWARE4 },
1091  };
1092 
1093  mfxIMPL impl = MFX_IMPL_AUTO_ANY;
1094  int i;
1095 
1096  if (device) {
1097  for (i = 0; i < FF_ARRAY_ELEMS(impl_map); i++)
1098  if (!strcmp(device, impl_map[i].name)) {
1099  impl = impl_map[i].impl;
1100  break;
1101  }
1102  if (i == FF_ARRAY_ELEMS(impl_map))
1103  impl = strtol(device, NULL, 0);
1104  }
1105 
1106  return impl;
1107 }
1108 
1110  mfxIMPL implementation,
1111  AVHWDeviceContext *child_device_ctx,
1112  int flags)
1113 {
1114  AVQSVDeviceContext *hwctx = ctx->hwctx;
1115 
1116  mfxVersion ver = { { 3, 1 } };
1117  mfxHDL handle;
1118  mfxHandleType handle_type;
1119  mfxStatus err;
1120  int ret;
1121 
1122  switch (child_device_ctx->type) {
1123 #if CONFIG_VAAPI
1125  {
1126  AVVAAPIDeviceContext *child_device_hwctx = child_device_ctx->hwctx;
1127  handle_type = MFX_HANDLE_VA_DISPLAY;
1128  handle = (mfxHDL)child_device_hwctx->display;
1129  }
1130  break;
1131 #endif
1132 #if CONFIG_DXVA2
1134  {
1135  AVDXVA2DeviceContext *child_device_hwctx = child_device_ctx->hwctx;
1136  handle_type = MFX_HANDLE_D3D9_DEVICE_MANAGER;
1137  handle = (mfxHDL)child_device_hwctx->devmgr;
1138  }
1139  break;
1140 #endif
1141  default:
1142  ret = AVERROR(ENOSYS);
1143  goto fail;
1144  }
1145 
1146  err = MFXInit(implementation, &ver, &hwctx->session);
1147  if (err != MFX_ERR_NONE) {
1148  av_log(ctx, AV_LOG_ERROR, "Error initializing an MFX session: "
1149  "%d.\n", err);
1150  ret = AVERROR_UNKNOWN;
1151  goto fail;
1152  }
1153 
1154  err = MFXQueryVersion(hwctx->session, &ver);
1155  if (err != MFX_ERR_NONE) {
1156  av_log(ctx, AV_LOG_ERROR, "Error querying an MFX session: %d.\n", err);
1157  ret = AVERROR_UNKNOWN;
1158  goto fail;
1159  }
1160 
1162  "Initialize MFX session: API version is %d.%d, implementation version is %d.%d\n",
1163  MFX_VERSION_MAJOR, MFX_VERSION_MINOR, ver.Major, ver.Minor);
1164 
1165  MFXClose(hwctx->session);
1166 
1167  err = MFXInit(implementation, &ver, &hwctx->session);
1168  if (err != MFX_ERR_NONE) {
1170  "Error initializing an MFX session: %d.\n", err);
1171  ret = AVERROR_UNKNOWN;
1172  goto fail;
1173  }
1174 
1175  err = MFXVideoCORE_SetHandle(hwctx->session, handle_type, handle);
1176  if (err != MFX_ERR_NONE) {
1177  av_log(ctx, AV_LOG_ERROR, "Error setting child device handle: "
1178  "%d\n", err);
1179  ret = AVERROR_UNKNOWN;
1180  goto fail;
1181  }
1182 
1183  ret = MFXQueryVersion(hwctx->session,&ver);
1184  if (ret == MFX_ERR_NONE) {
1185  av_log(ctx, AV_LOG_VERBOSE, "MFX compile/runtime API: %d.%d/%d.%d\n",
1186  MFX_VERSION_MAJOR, MFX_VERSION_MINOR, ver.Major, ver.Minor);
1187  }
1188  return 0;
1189 
1190 fail:
1191  if (hwctx->session)
1192  MFXClose(hwctx->session);
1193  return ret;
1194 }
1195 
1197  AVHWDeviceContext *child_device_ctx, int flags)
1198 {
1199  return qsv_device_derive_from_child(ctx, MFX_IMPL_HARDWARE_ANY,
1200  child_device_ctx, flags);
1201 }
1202 
1203 static int qsv_device_create(AVHWDeviceContext *ctx, const char *device,
1204  AVDictionary *opts, int flags)
1205 {
1206  QSVDevicePriv *priv;
1207  enum AVHWDeviceType child_device_type;
1208  AVHWDeviceContext *child_device;
1209  AVDictionary *child_device_opts;
1210  AVDictionaryEntry *e;
1211 
1212  mfxIMPL impl;
1213  int ret;
1214 
1215  priv = av_mallocz(sizeof(*priv));
1216  if (!priv)
1217  return AVERROR(ENOMEM);
1218 
1219  ctx->user_opaque = priv;
1220  ctx->free = qsv_device_free;
1221 
1222  e = av_dict_get(opts, "child_device", NULL, 0);
1223 
1224  child_device_opts = NULL;
1225  if (CONFIG_VAAPI) {
1226  child_device_type = AV_HWDEVICE_TYPE_VAAPI;
1227  // libmfx does not actually implement VAAPI properly, rather it
1228  // depends on the specific behaviour of a matching iHD driver when
1229  // used on recent Intel hardware. Set options to the VAAPI device
1230  // creation so that we should pick a usable setup by default if
1231  // possible, even when multiple devices and drivers are available.
1232  av_dict_set(&child_device_opts, "kernel_driver", "i915", 0);
1233  av_dict_set(&child_device_opts, "driver", "iHD", 0);
1234  } else if (CONFIG_DXVA2)
1235  child_device_type = AV_HWDEVICE_TYPE_DXVA2;
1236  else {
1237  av_log(ctx, AV_LOG_ERROR, "No supported child device type is enabled\n");
1238  return AVERROR(ENOSYS);
1239  }
1240 
1241  ret = av_hwdevice_ctx_create(&priv->child_device_ctx, child_device_type,
1242  e ? e->value : NULL, child_device_opts, 0);
1243  if (ret < 0)
1244  return ret;
1245 
1246  child_device = (AVHWDeviceContext*)priv->child_device_ctx->data;
1247 
1248  impl = choose_implementation(device);
1249 
1250  return qsv_device_derive_from_child(ctx, impl, child_device, 0);
1251 }
1252 
1255  .name = "QSV",
1256 
1257  .device_hwctx_size = sizeof(AVQSVDeviceContext),
1258  .device_priv_size = sizeof(QSVDeviceContext),
1259  .frames_hwctx_size = sizeof(AVQSVFramesContext),
1260  .frames_priv_size = sizeof(QSVFramesContext),
1261 
1262  .device_create = qsv_device_create,
1263  .device_derive = qsv_device_derive,
1264  .device_init = qsv_device_init,
1265  .frames_get_constraints = qsv_frames_get_constraints,
1266  .frames_init = qsv_frames_init,
1267  .frames_uninit = qsv_frames_uninit,
1268  .frames_get_buffer = qsv_get_buffer,
1269  .transfer_get_formats = qsv_transfer_get_formats,
1270  .transfer_data_to = qsv_transfer_data_to,
1271  .transfer_data_from = qsv_transfer_data_from,
1272  .map_to = qsv_map_to,
1273  .map_from = qsv_map_from,
1274  .frames_derive_to = qsv_frames_derive_to,
1275  .frames_derive_from = qsv_frames_derive_from,
1276 
1277  .pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_QSV, AV_PIX_FMT_NONE },
1278 };
formats
formats
Definition: signature.h:48
pthread_mutex_t
_fmutex pthread_mutex_t
Definition: os2threads.h:49
AVHWDeviceContext::hwctx
void * hwctx
The format-specific data, allocated and freed by libavutil along with this context.
Definition: hwcontext.h:91
qsv_transfer_data_child
static int qsv_transfer_data_child(AVHWFramesContext *ctx, AVFrame *dst, const AVFrame *src)
Definition: hwcontext_qsv.c:721
AVQSVFramesContext::frame_type
int frame_type
A combination of MFX_MEMTYPE_* describing the frame pool.
Definition: hwcontext_qsv.h:49
AVPixelFormat
AVPixelFormat
Pixel format.
Definition: pixfmt.h:64
qsv_device_derive
static int qsv_device_derive(AVHWDeviceContext *ctx, AVHWDeviceContext *child_device_ctx, int flags)
Definition: hwcontext_qsv.c:1196
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:324
QSVFramesContext::child_frames_ref
AVBufferRef * child_frames_ref
Definition: hwcontext_qsv.c:71
qsv_transfer_data_to
static int qsv_transfer_data_to(AVHWFramesContext *ctx, AVFrame *dst, const AVFrame *src)
Definition: hwcontext_qsv.c:855
av_pix_fmt_desc_get
const AVPixFmtDescriptor * av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt)
Definition: pixdesc.c:2522
AVBufferRef::data
uint8_t * data
The data buffer.
Definition: buffer.h:89
pthread_mutex_init
static av_always_inline int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr)
Definition: os2threads.h:100
qsv_map_from
static int qsv_map_from(AVHWFramesContext *ctx, AVFrame *dst, const AVFrame *src, int flags)
Definition: hwcontext_qsv.c:650
qsv_fourcc_from_pix_fmt
static uint32_t qsv_fourcc_from_pix_fmt(enum AVPixelFormat pix_fmt)
Definition: hwcontext_qsv.c:108
AVHWFramesContext::format
enum AVPixelFormat format
The pixel format identifying the underlying HW surface type.
Definition: hwcontext.h:208
av_frame_free
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition: frame.c:202
QSVDeviceContext::ver
mfxVersion ver
Definition: hwcontext_qsv.c:54
av_hwframe_ctx_init
int av_hwframe_ctx_init(AVBufferRef *ref)
Finalize the context before use.
Definition: hwcontext.c:329
AVFrame
This structure describes decoded (raw) audio or video data.
Definition: frame.h:295
pixdesc.h
AVFrame::width
int width
Definition: frame.h:353
AVQSVDeviceContext
This struct is allocated as AVHWDeviceContext.hwctx.
Definition: hwcontext_qsv.h:35
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:243
name
const char * name
Definition: avisynth_c.h:867
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:602
av_hwframe_map
int av_hwframe_map(AVFrame *dst, const AVFrame *src, int flags)
Map a hardware frame.
Definition: hwcontext.c:740
qsv_init_surface
static int qsv_init_surface(AVHWFramesContext *ctx, mfxFrameSurface1 *surf)
Definition: hwcontext_qsv.c:303
data
const char data[16]
Definition: mxf.c:91
QSVDeviceContext
Definition: hwcontext_qsv.c:51
av_mallocz_array
void * av_mallocz_array(size_t nmemb, size_t size)
Definition: mem.c:191
AVDXVA2DeviceContext::devmgr
IDirect3DDeviceManager9 * devmgr
Definition: hwcontext_dxva2.h:40
AV_LOG_VERBOSE
#define AV_LOG_VERBOSE
Detailed information.
Definition: log.h:192
AVVAAPIDeviceContext::display
VADisplay display
The VADisplay handle, to be filled by the user.
Definition: hwcontext_vaapi.h:72
av_buffer_create
AVBufferRef * av_buffer_create(uint8_t *data, int size, void(*free)(void *opaque, uint8_t *data), void *opaque, int flags)
Create an AVBuffer from an existing array.
Definition: buffer.c:28
AV_PIX_FMT_BGRA
@ AV_PIX_FMT_BGRA
packed BGRA 8:8:8:8, 32bpp, BGRABGRA...
Definition: pixfmt.h:95
AVHWFramesContext::internal
AVHWFramesInternal * internal
Private data used internally by libavutil.
Definition: hwcontext.h:133
AVDictionary
Definition: dict.c:30
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:688
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:437
AVERROR_UNKNOWN
#define AVERROR_UNKNOWN
Unknown error, typically from an external library.
Definition: error.h:71
AVHWFramesContext::width
int width
The allocated dimensions of the frames in this pool.
Definition: hwcontext.h:228
fourcc
uint32_t fourcc
Definition: hwcontext_qsv.c:100
av_hwdevice_ctx_init
int av_hwdevice_ctx_init(AVBufferRef *ref)
Finalize the device context before use.
Definition: hwcontext.c:196
AVFrame::buf
AVBufferRef * buf[AV_NUM_DATA_POINTERS]
AVBuffer references backing the data for this frame.
Definition: frame.h:486
AVFormatContext::internal
AVFormatInternal * internal
An opaque field for libavformat internal usage.
Definition: avformat.h:1795
QSVDeviceContext::handle_type
mfxHandleType handle_type
Definition: hwcontext_qsv.c:53
qsv_transfer_data_from
static int qsv_transfer_data_from(AVHWFramesContext *ctx, AVFrame *dst, const AVFrame *src)
Definition: hwcontext_qsv.c:786
AVFrame::data
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition: frame.h:309
AVHWFramesConstraints
This struct describes the constraints on hardware frames attached to a given device with a hardware-s...
Definition: hwcontext.h:432
QSVDevicePriv
Definition: hwcontext_qsv.c:47
AVVAAPIFramesContext::surface_ids
VASurfaceID * surface_ids
The surfaces IDs of all surfaces in the pool after creation.
Definition: hwcontext_vaapi.h:101
AVHWFramesInternal::priv
void * priv
Definition: hwcontext_internal.h:115
QSVDeviceContext::child_device_type
enum AVHWDeviceType child_device_type
Definition: hwcontext_qsv.c:57
qsv_init_child_ctx
static int qsv_init_child_ctx(AVHWFramesContext *ctx)
Definition: hwcontext_qsv.c:200
supported_handle_types
static const struct @298 supported_handle_types[]
fail
#define fail()
Definition: checkasm.h:120
AV_PIX_FMT_FLAG_HWACCEL
#define AV_PIX_FMT_FLAG_HWACCEL
Pixel format is an HW accelerated format.
Definition: pixdesc.h:140
qsv_frames_get_constraints
static int qsv_frames_get_constraints(AVHWDeviceContext *ctx, const void *hwconfig, AVHWFramesConstraints *constraints)
Definition: hwcontext_qsv.c:1040
src
#define src
Definition: vp8dsp.c:254
handle_type
mfxHandleType handle_type
Definition: hwcontext_qsv.c:85
qsv_frames_derive_to
static int qsv_frames_derive_to(AVHWFramesContext *dst_ctx, AVHWFramesContext *src_ctx, int flags)
Definition: hwcontext_qsv.c:950
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:189
frame_free
static mfxStatus frame_free(mfxHDL pthis, mfxFrameAllocResponse *resp)
Definition: hwcontext_qsv.c:407
HWContextType::type
enum AVHWDeviceType type
Definition: hwcontext_internal.h:30
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:176
AVHWFramesContext::height
int height
Definition: hwcontext.h:228
av_hwdevice_ctx_alloc
AVBufferRef * av_hwdevice_ctx_alloc(enum AVHWDeviceType type)
Allocate an AVHWDeviceContext for a given hardware type.
Definition: hwcontext.c:138
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:444
QSVFramesContext::ext_buffers
mfxExtBuffer * ext_buffers[1]
Definition: hwcontext_qsv.c:81
frame_alloc
static mfxStatus frame_alloc(mfxHDL pthis, mfxFrameAllocRequest *req, mfxFrameAllocResponse *resp)
Definition: hwcontext_qsv.c:379
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:40
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:334
QSVDevicePriv::child_device_ctx
AVBufferRef * child_device_ctx
Definition: hwcontext_qsv.c:48
AV_PIX_FMT_DXVA2_VLD
@ AV_PIX_FMT_DXVA2_VLD
HW decoding through DXVA2, Picture.data[3] contains a LPDIRECT3DSURFACE9 pointer.
Definition: pixfmt.h:137
s
#define s(width, name)
Definition: cbs_vp9.c:257
AVHWDeviceType
AVHWDeviceType
Definition: hwcontext.h:27
QSVDeviceContext::handle
mfxHDL handle
Definition: hwcontext_qsv.c:52
QSVFramesContext::mem_ids
mfxMemId * mem_ids
Definition: hwcontext_qsv.c:76
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:66
av_usleep
int av_usleep(unsigned usec)
Sleep for a period of time.
Definition: time.c:84
if
if(ret)
Definition: filter_design.txt:179
ff_hwcontext_type_qsv
const HWContextType ff_hwcontext_type_qsv
Definition: hwcontext_qsv.c:1253
opts
AVDictionary * opts
Definition: movenc.c:50
AVQSVFramesContext::surfaces
mfxFrameSurface1 * surfaces
Definition: hwcontext_qsv.h:43
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:221
qsv_frames_uninit
static void qsv_frames_uninit(AVHWFramesContext *ctx)
Definition: hwcontext_qsv.c:152
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:125
AV_HWDEVICE_TYPE_DXVA2
@ AV_HWDEVICE_TYPE_DXVA2
Definition: hwcontext.h:32
qsv_frames_init
static int qsv_frames_init(AVHWFramesContext *ctx)
Definition: hwcontext_qsv.c:504
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:222
map_frame_to_surface
static int map_frame_to_surface(const AVFrame *frame, mfxFrameSurface1 *surface)
Definition: hwcontext_qsv.c:755
frame_unlock
static mfxStatus frame_unlock(mfxHDL pthis, mfxMemId mid, mfxFrameData *ptr)
Definition: hwcontext_qsv.c:417
pthread_mutex_unlock
#define pthread_mutex_unlock(a)
Definition: ffprobe.c:65
qsv_init_internal_session
static int qsv_init_internal_session(AVHWFramesContext *ctx, mfxSession *session, int upload)
Definition: hwcontext_qsv.c:428
hwcontext_dxva2.h
QSVFramesContext::opaque_alloc
mfxExtOpaqueSurfaceAlloc opaque_alloc
Definition: hwcontext_qsv.c:80
desc
const char * desc
Definition: nvenc.c:68
QSVFramesContext::session_upload_init
int session_upload_init
Definition: hwcontext_qsv.c:65
qsv_get_buffer
static int qsv_get_buffer(AVHWFramesContext *ctx, AVFrame *frame)
Definition: hwcontext_qsv.c:570
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:792
QSVFramesContext::session_download_init
int session_download_init
Definition: hwcontext_qsv.c:63
device_type
enum AVHWDeviceType device_type
Definition: hwcontext_qsv.c:86
size
int size
Definition: twinvq_data.h:11134
QSVFramesContext::nb_surfaces_used
int nb_surfaces_used
Definition: hwcontext_qsv.c:73
qsv_device_free
static void qsv_device_free(AVHWDeviceContext *ctx)
Definition: hwcontext_qsv.c:1065
AVFrame::format
int format
format of the frame, -1 if unknown or unset Values correspond to enum AVPixelFormat for video frames,...
Definition: frame.h:368
qsv_pool_alloc
static AVBufferRef * qsv_pool_alloc(void *opaque, int size)
Definition: hwcontext_qsv.c:185
qsv_transfer_get_formats
static int qsv_transfer_get_formats(AVHWFramesContext *ctx, enum AVHWFrameTransferDirection dir, enum AVPixelFormat **formats)
Definition: hwcontext_qsv.c:584
buffer.h
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:1109
AVQSVFramesContext::nb_surfaces
int nb_surfaces
Definition: hwcontext_qsv.h:44
frame_get_hdl
static mfxStatus frame_get_hdl(mfxHDL pthis, mfxMemId mid, mfxHDL *hdl)
Definition: hwcontext_qsv.c:422
AV_PIX_FMT_VAAPI
@ AV_PIX_FMT_VAAPI
Definition: pixfmt.h:122
pthread_cond_destroy
static av_always_inline int pthread_cond_destroy(pthread_cond_t *cond)
Definition: os2threads.h:140
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:108
in
uint8_t pi<< 24) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_U8, uint8_t,(*(const uint8_t *) pi - 0x80) *(1.0f/(1<< 7))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_U8, uint8_t,(*(const uint8_t *) pi - 0x80) *(1.0/(1<< 7))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S16, int16_t,(*(const int16_t *) pi >> 8)+0x80) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S16, int16_t, *(const int16_t *) pi *(1.0f/(1<< 15))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S16, int16_t, *(const int16_t *) pi *(1.0/(1<< 15))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S32, int32_t,(*(const int32_t *) pi >> 24)+0x80) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S32, int32_t, *(const int32_t *) pi *(1.0f/(1U<< 31))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S32, int32_t, *(const int32_t *) pi *(1.0/(1U<< 31))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_FLT, float, av_clip_uint8(lrintf(*(const float *) pi *(1<< 7))+0x80)) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_FLT, float, av_clip_int16(lrintf(*(const float *) pi *(1<< 15)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_FLT, float, av_clipl_int32(llrintf(*(const float *) pi *(1U<< 31)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_DBL, double, av_clip_uint8(lrint(*(const double *) pi *(1<< 7))+0x80)) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_DBL, double, av_clip_int16(lrint(*(const double *) pi *(1<< 15)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_DBL, double, av_clipl_int32(llrint(*(const double *) pi *(1U<< 31)))) #define SET_CONV_FUNC_GROUP(ofmt, ifmt) static void set_generic_function(AudioConvert *ac) { } void ff_audio_convert_free(AudioConvert **ac) { if(! *ac) return;ff_dither_free(&(*ac) ->dc);av_freep(ac);} AudioConvert *ff_audio_convert_alloc(AVAudioResampleContext *avr, enum AVSampleFormat out_fmt, enum AVSampleFormat in_fmt, int channels, int sample_rate, int apply_map) { AudioConvert *ac;int in_planar, out_planar;ac=av_mallocz(sizeof(*ac));if(!ac) return NULL;ac->avr=avr;ac->out_fmt=out_fmt;ac->in_fmt=in_fmt;ac->channels=channels;ac->apply_map=apply_map;if(avr->dither_method !=AV_RESAMPLE_DITHER_NONE &&av_get_packed_sample_fmt(out_fmt)==AV_SAMPLE_FMT_S16 &&av_get_bytes_per_sample(in_fmt) > 2) { ac->dc=ff_dither_alloc(avr, out_fmt, in_fmt, channels, sample_rate, apply_map);if(!ac->dc) { av_free(ac);return NULL;} return ac;} in_planar=ff_sample_fmt_is_planar(in_fmt, channels);out_planar=ff_sample_fmt_is_planar(out_fmt, channels);if(in_planar==out_planar) { ac->func_type=CONV_FUNC_TYPE_FLAT;ac->planes=in_planar ? ac->channels :1;} else if(in_planar) ac->func_type=CONV_FUNC_TYPE_INTERLEAVE;else ac->func_type=CONV_FUNC_TYPE_DEINTERLEAVE;set_generic_function(ac);if(ARCH_AARCH64) ff_audio_convert_init_aarch64(ac);if(ARCH_ARM) ff_audio_convert_init_arm(ac);if(ARCH_X86) ff_audio_convert_init_x86(ac);return ac;} int ff_audio_convert(AudioConvert *ac, AudioData *out, AudioData *in) { int use_generic=1;int len=in->nb_samples;int p;if(ac->dc) { av_log(ac->avr, AV_LOG_TRACE, "%d samples - audio_convert: %s to %s (dithered)\n", len, av_get_sample_fmt_name(ac->in_fmt), av_get_sample_fmt_name(ac->out_fmt));return ff_convert_dither(ac-> in
Definition: audio_convert.c:326
hwcontext_qsv.h
qsv_device_init
static int qsv_device_init(AVHWDeviceContext *ctx)
Definition: hwcontext_qsv.c:118
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:259
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:32
common.h
QSVFramesContext::surface_ptrs
mfxFrameSurface1 ** surface_ptrs
Definition: hwcontext_qsv.c:78
uint8_t
uint8_t
Definition: audio_convert.c:194
av_frame_unref
void av_frame_unref(AVFrame *frame)
Unreference all the buffers referenced by frame and reset the frame fields.
Definition: frame.c:553
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:236
QSVFramesContext::session_download
mfxSession session_download
Definition: hwcontext_qsv.c:62
AVDXVA2FramesContext::surfaces
IDirect3DSurface9 ** surfaces
The surface pool.
Definition: hwcontext_dxva2.h:58
av_buffer_pool_init2
AVBufferPool * av_buffer_pool_init2(int size, void *opaque, AVBufferRef *(*alloc)(void *opaque, int size), void(*pool_free)(void *opaque))
Allocate and initialize a buffer pool with a more complex allocator.
Definition: buffer.c:218
pthread_cond_t
Definition: os2threads.h:54
AVHWFrameTransferDirection
AVHWFrameTransferDirection
Definition: hwcontext.h:394
AVHWFramesContext
This struct describes a set or pool of "hardware" frames (i.e.
Definition: hwcontext.h:123
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:1004
AV_PIX_FMT_PAL8
@ AV_PIX_FMT_PAL8
8 bits with AV_PIX_FMT_RGB32 palette
Definition: pixfmt.h:77
ret
ret
Definition: filter_design.txt:187
pix_fmt
enum AVPixelFormat pix_fmt
Definition: hwcontext_qsv.c:87
AVHWDeviceContext::type
enum AVHWDeviceType type
This field identifies the underlying API used for hardware access.
Definition: hwcontext.h:78
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:89
frame
these buffered frames must be flushed immediately if a new input produces new the filter must not call request_frame to get more It must just process the frame or queue it The task of requesting more frames is left to the filter s request_frame method or the application If a filter has several the filter must be ready for frames arriving randomly on any input any filter with several inputs will most likely require some kind of queuing mechanism It is perfectly acceptable to have a limited queue and to drop frames when the inputs are too unbalanced request_frame For filters that do not use the this method is called when a frame is wanted on an output For a it should directly call filter_frame on the corresponding output For a if there are queued frames already one of these frames should be pushed If the filter should request a frame on one of its repeatedly until at least one frame has been pushed Return or at least make progress towards producing a frame
Definition: filter_design.txt:264
AVHWFramesContext::device_ctx
AVHWDeviceContext * device_ctx
The parent AVHWDeviceContext.
Definition: hwcontext.h:148
AVHWFramesContext::hwctx
void * hwctx
The format-specific data, allocated and freed automatically along with this context.
Definition: hwcontext.h:161
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:571
QSVDeviceContext::impl
mfxIMPL impl
Definition: hwcontext_qsv.c:55
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:439
pthread_cond_signal
static av_always_inline int pthread_cond_signal(pthread_cond_t *cond)
Definition: os2threads.h:148
frame_lock
static mfxStatus frame_lock(mfxHDL pthis, mfxMemId mid, mfxFrameData *ptr)
Definition: hwcontext_qsv.c:412
FF_ARRAY_ELEMS
#define FF_ARRAY_ELEMS(a)
Definition: sinewin_tablegen_template.c:38
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:634
supported_pixel_formats
static const struct @299 supported_pixel_formats[]
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:181
AVFrame::height
int height
Definition: frame.h:353
QSVDeviceContext::child_pix_fmt
enum AVPixelFormat child_pix_fmt
Definition: hwcontext_qsv.c:58
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:65
config.h
dummy
int dummy
Definition: motion.c:64
QSVFramesContext::session_upload
mfxSession session_upload
Definition: hwcontext_qsv.c:64
av_buffer_ref
AVBufferRef * av_buffer_ref(AVBufferRef *buf)
Create a new reference to an AVBuffer.
Definition: buffer.c:93
qsv_device_create
static int qsv_device_create(AVHWDeviceContext *ctx, const char *device, AVDictionary *opts, int flags)
Definition: hwcontext_qsv.c:1203
pthread_cond_wait
static av_always_inline int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex)
Definition: os2threads.h:166
AV_PIX_FMT_P010
#define AV_PIX_FMT_P010
Definition: pixfmt.h:436
AVQSVFramesContext
This struct is allocated as AVHWFramesContext.hwctx.
Definition: hwcontext_qsv.h:42
AVHWFramesContext::initial_pool_size
int initial_pool_size
Initial size of the frame pool.
Definition: hwcontext.h:198
mem.h
AVBufferRef
A reference to a data buffer.
Definition: buffer.h:81
choose_implementation
static mfxIMPL choose_implementation(const char *device)
Definition: hwcontext_qsv.c:1077
AVPixFmtDescriptor
Descriptor that unambiguously describes how the bits of a pixel are stored in the up to 4 data planes...
Definition: pixdesc.h:81
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:72
AVDictionaryEntry
Definition: dict.h:81
FFALIGN
#define FFALIGN(x, a)
Definition: macros.h:48
QSVFramesContext
Definition: qsv_internal.h:67
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:35
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:70
flags
#define flags(name, subs,...)
Definition: cbs_av1.c:565
hwcontext.h
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:28
HWContextType
Definition: hwcontext_internal.h:29
pthread_cond_init
static av_always_inline int pthread_cond_init(pthread_cond_t *cond, const pthread_condattr_t *attr)
Definition: os2threads.h:129
AVVAAPIDeviceContext
VAAPI connection details.
Definition: hwcontext_vaapi.h:68
AVDictionaryEntry::value
char * value
Definition: dict.h:83
qsv_init_pool
static int qsv_init_pool(AVHWFramesContext *ctx, uint32_t fourcc)
Definition: hwcontext_qsv.c:339
pthread_mutex_lock
#define pthread_mutex_lock(a)
Definition: ffprobe.c:61