FFmpeg
qsv.c
Go to the documentation of this file.
1 /*
2  * Intel MediaSDK QSV encoder/decoder shared code
3  *
4  * This file is part of FFmpeg.
5  *
6  * FFmpeg is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * FFmpeg is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with FFmpeg; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19  */
20 
21 #include <mfx/mfxvideo.h>
22 #include <mfx/mfxplugin.h>
23 #include <mfx/mfxjpeg.h>
24 
25 #include <stdio.h>
26 #include <string.h>
27 
28 #include "libavutil/avstring.h"
29 #include "libavutil/common.h"
30 #include "libavutil/error.h"
31 #include "libavutil/hwcontext.h"
33 #include "libavutil/imgutils.h"
34 #include "libavutil/avassert.h"
35 
36 #include "avcodec.h"
37 #include "qsv_internal.h"
38 
39 #define MFX_IMPL_VIA_MASK(impl) (0x0f00 & (impl))
40 
41 #if QSV_VERSION_ATLEAST(1, 12)
42 #include "mfx/mfxvp8.h"
43 #endif
44 
46 {
47  switch (codec_id) {
48  case AV_CODEC_ID_H264:
49  return MFX_CODEC_AVC;
50 #if QSV_VERSION_ATLEAST(1, 8)
51  case AV_CODEC_ID_HEVC:
52  return MFX_CODEC_HEVC;
53 #endif
56  return MFX_CODEC_MPEG2;
57  case AV_CODEC_ID_VC1:
58  return MFX_CODEC_VC1;
59 #if QSV_VERSION_ATLEAST(1, 12)
60  case AV_CODEC_ID_VP8:
61  return MFX_CODEC_VP8;
62 #endif
63  case AV_CODEC_ID_MJPEG:
64  return MFX_CODEC_JPEG;
65 #if QSV_VERSION_ATLEAST(1, 19)
66  case AV_CODEC_ID_VP9:
67  return MFX_CODEC_VP9;
68 #endif
69 #if QSV_VERSION_ATLEAST(1, 34)
70  case AV_CODEC_ID_AV1:
71  return MFX_CODEC_AV1;
72 #endif
73 
74  default:
75  break;
76  }
77 
78  return AVERROR(ENOSYS);
79 }
80 
81 static const struct {
83  const char *desc;
84 } qsv_iopatterns[] = {
85  {MFX_IOPATTERN_IN_VIDEO_MEMORY, "input is video memory surface" },
86  {MFX_IOPATTERN_IN_SYSTEM_MEMORY, "input is system memory surface" },
87  {MFX_IOPATTERN_IN_OPAQUE_MEMORY, "input is opaque memory surface" },
88  {MFX_IOPATTERN_OUT_VIDEO_MEMORY, "output is video memory surface" },
89  {MFX_IOPATTERN_OUT_SYSTEM_MEMORY, "output is system memory surface" },
90  {MFX_IOPATTERN_OUT_OPAQUE_MEMORY, "output is opaque memory surface" },
91 };
92 
93 int ff_qsv_print_iopattern(void *log_ctx, int mfx_iopattern,
94  const char *extra_string)
95 {
96  const char *desc = NULL;
97 
98  for (int i = 0; i < FF_ARRAY_ELEMS(qsv_iopatterns); i++) {
100  desc = qsv_iopatterns[i].desc;
101  }
102  }
103  if (!desc)
104  desc = "unknown iopattern";
105 
106  av_log(log_ctx, AV_LOG_VERBOSE, "%s: %s\n", extra_string, desc);
107  return 0;
108 }
109 
110 static const struct {
111  mfxStatus mfxerr;
112  int averr;
113  const char *desc;
114 } qsv_errors[] = {
115  { MFX_ERR_NONE, 0, "success" },
116  { MFX_ERR_UNKNOWN, AVERROR_UNKNOWN, "unknown error" },
117  { MFX_ERR_NULL_PTR, AVERROR(EINVAL), "NULL pointer" },
118  { MFX_ERR_UNSUPPORTED, AVERROR(ENOSYS), "unsupported" },
119  { MFX_ERR_MEMORY_ALLOC, AVERROR(ENOMEM), "failed to allocate memory" },
120  { MFX_ERR_NOT_ENOUGH_BUFFER, AVERROR(ENOMEM), "insufficient input/output buffer" },
121  { MFX_ERR_INVALID_HANDLE, AVERROR(EINVAL), "invalid handle" },
122  { MFX_ERR_LOCK_MEMORY, AVERROR(EIO), "failed to lock the memory block" },
123  { MFX_ERR_NOT_INITIALIZED, AVERROR_BUG, "not initialized" },
124  { MFX_ERR_NOT_FOUND, AVERROR(ENOSYS), "specified object was not found" },
125  /* the following 3 errors should always be handled explicitly, so those "mappings"
126  * are for completeness only */
127  { MFX_ERR_MORE_DATA, AVERROR_UNKNOWN, "expect more data at input" },
128  { MFX_ERR_MORE_SURFACE, AVERROR_UNKNOWN, "expect more surface at output" },
129  { MFX_ERR_MORE_BITSTREAM, AVERROR_UNKNOWN, "expect more bitstream at output" },
130  { MFX_ERR_ABORTED, AVERROR_UNKNOWN, "operation aborted" },
131  { MFX_ERR_DEVICE_LOST, AVERROR(EIO), "device lost" },
132  { MFX_ERR_INCOMPATIBLE_VIDEO_PARAM, AVERROR(EINVAL), "incompatible video parameters" },
133  { MFX_ERR_INVALID_VIDEO_PARAM, AVERROR(EINVAL), "invalid video parameters" },
134  { MFX_ERR_UNDEFINED_BEHAVIOR, AVERROR_BUG, "undefined behavior" },
135  { MFX_ERR_DEVICE_FAILED, AVERROR(EIO), "device failed" },
136  { MFX_ERR_INCOMPATIBLE_AUDIO_PARAM, AVERROR(EINVAL), "incompatible audio parameters" },
137  { MFX_ERR_INVALID_AUDIO_PARAM, AVERROR(EINVAL), "invalid audio parameters" },
138 
139  { MFX_WRN_IN_EXECUTION, 0, "operation in execution" },
140  { MFX_WRN_DEVICE_BUSY, 0, "device busy" },
141  { MFX_WRN_VIDEO_PARAM_CHANGED, 0, "video parameters changed" },
142  { MFX_WRN_PARTIAL_ACCELERATION, 0, "partial acceleration" },
143  { MFX_WRN_INCOMPATIBLE_VIDEO_PARAM, 0, "incompatible video parameters" },
144  { MFX_WRN_VALUE_NOT_CHANGED, 0, "value is saturated" },
145  { MFX_WRN_OUT_OF_RANGE, 0, "value out of range" },
146  { MFX_WRN_FILTER_SKIPPED, 0, "filter skipped" },
147  { MFX_WRN_INCOMPATIBLE_AUDIO_PARAM, 0, "incompatible audio parameters" },
148 };
149 
150 /**
151  * Convert a libmfx error code into an FFmpeg error code.
152  */
153 static int qsv_map_error(mfxStatus mfx_err, const char **desc)
154 {
155  int i;
156  for (i = 0; i < FF_ARRAY_ELEMS(qsv_errors); i++) {
157  if (qsv_errors[i].mfxerr == mfx_err) {
158  if (desc)
159  *desc = qsv_errors[i].desc;
160  return qsv_errors[i].averr;
161  }
162  }
163  if (desc)
164  *desc = "unknown error";
165  return AVERROR_UNKNOWN;
166 }
167 
168 int ff_qsv_print_error(void *log_ctx, mfxStatus err,
169  const char *error_string)
170 {
171  const char *desc;
172  int ret = qsv_map_error(err, &desc);
173  av_log(log_ctx, AV_LOG_ERROR, "%s: %s (%d)\n", error_string, desc, err);
174  return ret;
175 }
176 
177 int ff_qsv_print_warning(void *log_ctx, mfxStatus err,
178  const char *warning_string)
179 {
180  const char *desc;
181  int ret = qsv_map_error(err, &desc);
182  av_log(log_ctx, AV_LOG_WARNING, "%s: %s (%d)\n", warning_string, desc, err);
183  return ret;
184 }
185 
187 {
188  switch (fourcc) {
189  case MFX_FOURCC_NV12: return AV_PIX_FMT_NV12;
190  case MFX_FOURCC_P010: return AV_PIX_FMT_P010;
191  case MFX_FOURCC_P8: return AV_PIX_FMT_PAL8;
192 #if CONFIG_VAAPI
193  case MFX_FOURCC_YUY2: return AV_PIX_FMT_YUYV422;
194 #if QSV_VERSION_ATLEAST(1, 27)
195  case MFX_FOURCC_Y210: return AV_PIX_FMT_Y210;
196 #endif
197 #endif
198  }
199  return AV_PIX_FMT_NONE;
200 }
201 
203 {
204  switch (format) {
205  case AV_PIX_FMT_YUV420P:
206  case AV_PIX_FMT_YUVJ420P:
207  case AV_PIX_FMT_NV12:
208  *fourcc = MFX_FOURCC_NV12;
209  return AV_PIX_FMT_NV12;
211  case AV_PIX_FMT_P010:
212  *fourcc = MFX_FOURCC_P010;
213  return AV_PIX_FMT_P010;
214 #if CONFIG_VAAPI
215  case AV_PIX_FMT_YUV422P:
216  case AV_PIX_FMT_YUYV422:
217  *fourcc = MFX_FOURCC_YUY2;
218  return AV_PIX_FMT_YUYV422;
219 #if QSV_VERSION_ATLEAST(1, 27)
221  case AV_PIX_FMT_Y210:
222  *fourcc = MFX_FOURCC_Y210;
223  return AV_PIX_FMT_Y210;
224 #endif
225 #endif
226  default:
227  return AVERROR(ENOSYS);
228  }
229 }
230 
232 {
233  int i;
234  for (i = 0; i < ctx->nb_mids; i++) {
235  QSVMid *mid = &ctx->mids[i];
236  mfxHDLPair *pair = (mfxHDLPair*)frame->surface.Data.MemId;
237  if ((mid->handle_pair->first == pair->first) &&
238  (mid->handle_pair->second == pair->second))
239  return i;
240  }
241  return AVERROR_BUG;
242 }
243 
244 enum AVFieldOrder ff_qsv_map_picstruct(int mfx_pic_struct)
245 {
247  switch (mfx_pic_struct & 0xF) {
248  case MFX_PICSTRUCT_PROGRESSIVE:
250  break;
251  case MFX_PICSTRUCT_FIELD_TFF:
252  field = AV_FIELD_TT;
253  break;
254  case MFX_PICSTRUCT_FIELD_BFF:
255  field = AV_FIELD_BB;
256  break;
257  }
258 
259  return field;
260 }
261 
262 enum AVPictureType ff_qsv_map_pictype(int mfx_pic_type)
263 {
264  enum AVPictureType type;
265  switch (mfx_pic_type & 0x7) {
266  case MFX_FRAMETYPE_I:
267  if (mfx_pic_type & MFX_FRAMETYPE_S)
269  else
271  break;
272  case MFX_FRAMETYPE_B:
274  break;
275  case MFX_FRAMETYPE_P:
276  if (mfx_pic_type & MFX_FRAMETYPE_S)
278  else
280  break;
281  case MFX_FRAMETYPE_UNKNOWN:
283  break;
284  default:
285  av_assert0(0);
286  }
287 
288  return type;
289 }
290 
291 static int qsv_load_plugins(mfxSession session, const char *load_plugins,
292  void *logctx)
293 {
294  if (!load_plugins || !*load_plugins)
295  return 0;
296 
297  while (*load_plugins) {
298  mfxPluginUID uid;
299  mfxStatus ret;
300  int i, err = 0;
301 
302  char *plugin = av_get_token(&load_plugins, ":");
303  if (!plugin)
304  return AVERROR(ENOMEM);
305  if (strlen(plugin) != 2 * sizeof(uid.Data)) {
306  av_log(logctx, AV_LOG_ERROR, "Invalid plugin UID length\n");
307  err = AVERROR(EINVAL);
308  goto load_plugin_fail;
309  }
310 
311  for (i = 0; i < sizeof(uid.Data); i++) {
312  err = sscanf(plugin + 2 * i, "%2hhx", uid.Data + i);
313  if (err != 1) {
314  av_log(logctx, AV_LOG_ERROR, "Invalid plugin UID\n");
315  err = AVERROR(EINVAL);
316  goto load_plugin_fail;
317  }
318 
319  }
320 
321  ret = MFXVideoUSER_Load(session, &uid, 1);
322  if (ret < 0) {
323  char errorbuf[128];
324  snprintf(errorbuf, sizeof(errorbuf),
325  "Could not load the requested plugin '%s'", plugin);
326  err = ff_qsv_print_error(logctx, ret, errorbuf);
327  goto load_plugin_fail;
328  }
329 
330  if (*load_plugins)
331  load_plugins++;
332 load_plugin_fail:
333  av_freep(&plugin);
334  if (err < 0)
335  return err;
336  }
337 
338  return 0;
339 
340 }
341 
342 //This code is only required for Linux since a display handle is required.
343 //For Windows the session is complete and ready to use.
344 
345 #ifdef AVCODEC_QSV_LINUX_SESSION_HANDLE
346 static int ff_qsv_set_display_handle(AVCodecContext *avctx, QSVSession *qs)
347 {
348  AVDictionary *child_device_opts = NULL;
349  AVVAAPIDeviceContext *hwctx;
350  int ret;
351 
352  av_dict_set(&child_device_opts, "kernel_driver", "i915", 0);
353  av_dict_set(&child_device_opts, "driver", "iHD", 0);
354 
355  ret = av_hwdevice_ctx_create(&qs->va_device_ref, AV_HWDEVICE_TYPE_VAAPI, NULL, child_device_opts, 0);
356  av_dict_free(&child_device_opts);
357  if (ret < 0) {
358  av_log(avctx, AV_LOG_ERROR, "Failed to create a VAAPI device.\n");
359  return ret;
360  } else {
361  qs->va_device_ctx = (AVHWDeviceContext*)qs->va_device_ref->data;
362  hwctx = qs->va_device_ctx->hwctx;
363 
364  ret = MFXVideoCORE_SetHandle(qs->session,
365  (mfxHandleType)MFX_HANDLE_VA_DISPLAY, (mfxHDL)hwctx->display);
366  if (ret < 0) {
367  return ff_qsv_print_error(avctx, ret, "Error during set display handle\n");
368  }
369  }
370 
371  return 0;
372 }
373 #endif //AVCODEC_QSV_LINUX_SESSION_HANDLE
374 
376  const char *load_plugins, int gpu_copy)
377 {
378 #if CONFIG_D3D11VA
379  mfxIMPL impl = MFX_IMPL_AUTO_ANY | MFX_IMPL_VIA_D3D11;
380 #else
381  mfxIMPL impl = MFX_IMPL_AUTO_ANY;
382 #endif
383  mfxVersion ver = { { QSV_VERSION_MINOR, QSV_VERSION_MAJOR } };
384  mfxInitParam init_par = { MFX_IMPL_AUTO_ANY };
385 
386  const char *desc;
387  int ret;
388 
389 #if QSV_VERSION_ATLEAST(1, 16)
390  init_par.GPUCopy = gpu_copy;
391 #endif
392  init_par.Implementation = impl;
393  init_par.Version = ver;
394  ret = MFXInitEx(init_par, &qs->session);
395  if (ret < 0)
396  return ff_qsv_print_error(avctx, ret,
397  "Error initializing an internal MFX session");
398 
399 #ifdef AVCODEC_QSV_LINUX_SESSION_HANDLE
400  ret = ff_qsv_set_display_handle(avctx, qs);
401  if (ret < 0)
402  return ret;
403 #endif
404 
405  ret = qsv_load_plugins(qs->session, load_plugins, avctx);
406  if (ret < 0) {
407  av_log(avctx, AV_LOG_ERROR, "Error loading plugins\n");
408  return ret;
409  }
410 
411  MFXQueryIMPL(qs->session, &impl);
412 
413  switch (MFX_IMPL_BASETYPE(impl)) {
414  case MFX_IMPL_SOFTWARE:
415  desc = "software";
416  break;
417  case MFX_IMPL_HARDWARE:
418  case MFX_IMPL_HARDWARE2:
419  case MFX_IMPL_HARDWARE3:
420  case MFX_IMPL_HARDWARE4:
421  desc = "hardware accelerated";
422  break;
423  default:
424  desc = "unknown";
425  }
426 
427  av_log(avctx, AV_LOG_VERBOSE,
428  "Initialized an internal MFX session using %s implementation\n",
429  desc);
430 
431  return 0;
432 }
433 
434 static void mids_buf_free(void *opaque, uint8_t *data)
435 {
436  AVBufferRef *hw_frames_ref = opaque;
437  av_buffer_unref(&hw_frames_ref);
438  av_freep(&data);
439 }
440 
441 static AVBufferRef *qsv_create_mids(AVBufferRef *hw_frames_ref)
442 {
443  AVHWFramesContext *frames_ctx = (AVHWFramesContext*)hw_frames_ref->data;
444  AVQSVFramesContext *frames_hwctx = frames_ctx->hwctx;
445  int nb_surfaces = frames_hwctx->nb_surfaces;
446 
447  AVBufferRef *mids_buf, *hw_frames_ref1;
448  QSVMid *mids;
449  int i;
450 
451  hw_frames_ref1 = av_buffer_ref(hw_frames_ref);
452  if (!hw_frames_ref1)
453  return NULL;
454 
455  mids = av_calloc(nb_surfaces, sizeof(*mids));
456  if (!mids) {
457  av_buffer_unref(&hw_frames_ref1);
458  return NULL;
459  }
460 
461  mids_buf = av_buffer_create((uint8_t*)mids, nb_surfaces * sizeof(*mids),
462  mids_buf_free, hw_frames_ref1, 0);
463  if (!mids_buf) {
464  av_buffer_unref(&hw_frames_ref1);
465  av_freep(&mids);
466  return NULL;
467  }
468 
469  for (i = 0; i < nb_surfaces; i++) {
470  QSVMid *mid = &mids[i];
471  mid->handle_pair = (mfxHDLPair*)frames_hwctx->surfaces[i].Data.MemId;
472  mid->hw_frames_ref = hw_frames_ref1;
473  }
474 
475  return mids_buf;
476 }
477 
478 static int qsv_setup_mids(mfxFrameAllocResponse *resp, AVBufferRef *hw_frames_ref,
479  AVBufferRef *mids_buf)
480 {
481  AVHWFramesContext *frames_ctx = (AVHWFramesContext*)hw_frames_ref->data;
482  AVQSVFramesContext *frames_hwctx = frames_ctx->hwctx;
483  QSVMid *mids = (QSVMid*)mids_buf->data;
484  int nb_surfaces = frames_hwctx->nb_surfaces;
485  int i;
486 
487  // the allocated size of the array is two larger than the number of
488  // surfaces, we store the references to the frames context and the
489  // QSVMid array there
490  resp->mids = av_calloc(nb_surfaces + 2, sizeof(*resp->mids));
491  if (!resp->mids)
492  return AVERROR(ENOMEM);
493 
494  for (i = 0; i < nb_surfaces; i++)
495  resp->mids[i] = &mids[i];
496  resp->NumFrameActual = nb_surfaces;
497 
498  resp->mids[resp->NumFrameActual] = (mfxMemId)av_buffer_ref(hw_frames_ref);
499  if (!resp->mids[resp->NumFrameActual]) {
500  av_freep(&resp->mids);
501  return AVERROR(ENOMEM);
502  }
503 
504  resp->mids[resp->NumFrameActual + 1] = av_buffer_ref(mids_buf);
505  if (!resp->mids[resp->NumFrameActual + 1]) {
506  av_buffer_unref((AVBufferRef**)&resp->mids[resp->NumFrameActual]);
507  av_freep(&resp->mids);
508  return AVERROR(ENOMEM);
509  }
510 
511  return 0;
512 }
513 
514 static mfxStatus qsv_frame_alloc(mfxHDL pthis, mfxFrameAllocRequest *req,
515  mfxFrameAllocResponse *resp)
516 {
517  QSVFramesContext *ctx = pthis;
518  int ret;
519 
520  /* this should only be called from an encoder or decoder and
521  * only allocates video memory frames */
522  if (!(req->Type & (MFX_MEMTYPE_VIDEO_MEMORY_DECODER_TARGET |
523  MFX_MEMTYPE_VIDEO_MEMORY_PROCESSOR_TARGET)) ||
524  !(req->Type & (MFX_MEMTYPE_FROM_DECODE | MFX_MEMTYPE_FROM_ENCODE)))
525  return MFX_ERR_UNSUPPORTED;
526 
527  if (req->Type & MFX_MEMTYPE_EXTERNAL_FRAME) {
528  /* external frames -- fill from the caller-supplied frames context */
529  AVHWFramesContext *frames_ctx = (AVHWFramesContext*)ctx->hw_frames_ctx->data;
530  AVQSVFramesContext *frames_hwctx = frames_ctx->hwctx;
531  mfxFrameInfo *i = &req->Info;
532  mfxFrameInfo *i1 = &frames_hwctx->surfaces[0].Info;
533 
534  if (i->Width > i1->Width || i->Height > i1->Height ||
535  i->FourCC != i1->FourCC || i->ChromaFormat != i1->ChromaFormat) {
536  av_log(ctx->logctx, AV_LOG_ERROR, "Mismatching surface properties in an "
537  "allocation request: %dx%d %d %d vs %dx%d %d %d\n",
538  i->Width, i->Height, i->FourCC, i->ChromaFormat,
539  i1->Width, i1->Height, i1->FourCC, i1->ChromaFormat);
540  return MFX_ERR_UNSUPPORTED;
541  }
542 
543  ret = qsv_setup_mids(resp, ctx->hw_frames_ctx, ctx->mids_buf);
544  if (ret < 0) {
545  av_log(ctx->logctx, AV_LOG_ERROR,
546  "Error filling an external frame allocation request\n");
547  return MFX_ERR_MEMORY_ALLOC;
548  }
549  } else if (req->Type & MFX_MEMTYPE_INTERNAL_FRAME) {
550  /* internal frames -- allocate a new hw frames context */
551  AVHWFramesContext *ext_frames_ctx = (AVHWFramesContext*)ctx->hw_frames_ctx->data;
552  mfxFrameInfo *i = &req->Info;
553 
554  AVBufferRef *frames_ref, *mids_buf;
555  AVHWFramesContext *frames_ctx;
556  AVQSVFramesContext *frames_hwctx;
557 
558  frames_ref = av_hwframe_ctx_alloc(ext_frames_ctx->device_ref);
559  if (!frames_ref)
560  return MFX_ERR_MEMORY_ALLOC;
561 
562  frames_ctx = (AVHWFramesContext*)frames_ref->data;
563  frames_hwctx = frames_ctx->hwctx;
564 
565  frames_ctx->format = AV_PIX_FMT_QSV;
566  frames_ctx->sw_format = ff_qsv_map_fourcc(i->FourCC);
567  frames_ctx->width = i->Width;
568  frames_ctx->height = i->Height;
569  frames_ctx->initial_pool_size = req->NumFrameSuggested;
570 
571  frames_hwctx->frame_type = req->Type;
572 
573  ret = av_hwframe_ctx_init(frames_ref);
574  if (ret < 0) {
575  av_log(ctx->logctx, AV_LOG_ERROR,
576  "Error initializing a frames context for an internal frame "
577  "allocation request\n");
578  av_buffer_unref(&frames_ref);
579  return MFX_ERR_MEMORY_ALLOC;
580  }
581 
582  mids_buf = qsv_create_mids(frames_ref);
583  if (!mids_buf) {
584  av_buffer_unref(&frames_ref);
585  return MFX_ERR_MEMORY_ALLOC;
586  }
587 
588  ret = qsv_setup_mids(resp, frames_ref, mids_buf);
589  av_buffer_unref(&mids_buf);
590  av_buffer_unref(&frames_ref);
591  if (ret < 0) {
592  av_log(ctx->logctx, AV_LOG_ERROR,
593  "Error filling an internal frame allocation request\n");
594  return MFX_ERR_MEMORY_ALLOC;
595  }
596  } else {
597  return MFX_ERR_UNSUPPORTED;
598  }
599 
600  return MFX_ERR_NONE;
601 }
602 
603 static mfxStatus qsv_frame_free(mfxHDL pthis, mfxFrameAllocResponse *resp)
604 {
605  av_buffer_unref((AVBufferRef**)&resp->mids[resp->NumFrameActual]);
606  av_buffer_unref((AVBufferRef**)&resp->mids[resp->NumFrameActual + 1]);
607  av_freep(&resp->mids);
608  return MFX_ERR_NONE;
609 }
610 
611 static mfxStatus qsv_frame_lock(mfxHDL pthis, mfxMemId mid, mfxFrameData *ptr)
612 {
613  QSVMid *qsv_mid = mid;
614  AVHWFramesContext *hw_frames_ctx = (AVHWFramesContext*)qsv_mid->hw_frames_ref->data;
615  AVQSVFramesContext *hw_frames_hwctx = hw_frames_ctx->hwctx;
616  int ret;
617 
618  if (qsv_mid->locked_frame)
619  return MFX_ERR_UNDEFINED_BEHAVIOR;
620 
621  /* Allocate a system memory frame that will hold the mapped data. */
622  qsv_mid->locked_frame = av_frame_alloc();
623  if (!qsv_mid->locked_frame)
624  return MFX_ERR_MEMORY_ALLOC;
625  qsv_mid->locked_frame->format = hw_frames_ctx->sw_format;
626 
627  /* wrap the provided handle in a hwaccel AVFrame */
628  qsv_mid->hw_frame = av_frame_alloc();
629  if (!qsv_mid->hw_frame)
630  goto fail;
631 
632  qsv_mid->hw_frame->data[3] = (uint8_t*)&qsv_mid->surf;
633  qsv_mid->hw_frame->format = AV_PIX_FMT_QSV;
634 
635  // doesn't really matter what buffer is used here
636  qsv_mid->hw_frame->buf[0] = av_buffer_alloc(1);
637  if (!qsv_mid->hw_frame->buf[0])
638  goto fail;
639 
640  qsv_mid->hw_frame->width = hw_frames_ctx->width;
641  qsv_mid->hw_frame->height = hw_frames_ctx->height;
642 
643  qsv_mid->hw_frame->hw_frames_ctx = av_buffer_ref(qsv_mid->hw_frames_ref);
644  if (!qsv_mid->hw_frame->hw_frames_ctx)
645  goto fail;
646 
647  qsv_mid->surf.Info = hw_frames_hwctx->surfaces[0].Info;
648  qsv_mid->surf.Data.MemId = qsv_mid->handle_pair;
649 
650  /* map the data to the system memory */
651  ret = av_hwframe_map(qsv_mid->locked_frame, qsv_mid->hw_frame,
653  if (ret < 0)
654  goto fail;
655 
656  ptr->Pitch = qsv_mid->locked_frame->linesize[0];
657  ptr->Y = qsv_mid->locked_frame->data[0];
658  ptr->U = qsv_mid->locked_frame->data[1];
659  ptr->V = qsv_mid->locked_frame->data[1] + 1;
660 
661  return MFX_ERR_NONE;
662 fail:
663  av_frame_free(&qsv_mid->hw_frame);
664  av_frame_free(&qsv_mid->locked_frame);
665  return MFX_ERR_MEMORY_ALLOC;
666 }
667 
668 static mfxStatus qsv_frame_unlock(mfxHDL pthis, mfxMemId mid, mfxFrameData *ptr)
669 {
670  QSVMid *qsv_mid = mid;
671 
672  av_frame_free(&qsv_mid->locked_frame);
673  av_frame_free(&qsv_mid->hw_frame);
674 
675  return MFX_ERR_NONE;
676 }
677 
678 static mfxStatus qsv_frame_get_hdl(mfxHDL pthis, mfxMemId mid, mfxHDL *hdl)
679 {
680  QSVMid *qsv_mid = (QSVMid*)mid;
681  mfxHDLPair *pair_dst = (mfxHDLPair*)hdl;
682  mfxHDLPair *pair_src = (mfxHDLPair*)qsv_mid->handle_pair;
683 
684  pair_dst->first = pair_src->first;
685 
686  if (pair_src->second != (mfxMemId)MFX_INFINITE)
687  pair_dst->second = pair_src->second;
688  return MFX_ERR_NONE;
689 }
690 
691 int ff_qsv_init_session_device(AVCodecContext *avctx, mfxSession *psession,
692  AVBufferRef *device_ref, const char *load_plugins,
693  int gpu_copy)
694 {
695  AVHWDeviceContext *device_ctx = (AVHWDeviceContext*)device_ref->data;
696  AVQSVDeviceContext *device_hwctx = device_ctx->hwctx;
697  mfxSession parent_session = device_hwctx->session;
698  mfxInitParam init_par = { MFX_IMPL_AUTO_ANY };
699  mfxHDL handle = NULL;
700  int hw_handle_supported = 0;
701 
702  mfxSession session;
703  mfxVersion ver;
704  mfxIMPL impl;
705  mfxHandleType handle_type;
706  mfxStatus err;
707  int ret;
708 
709  err = MFXQueryIMPL(parent_session, &impl);
710  if (err == MFX_ERR_NONE)
711  err = MFXQueryVersion(parent_session, &ver);
712  if (err != MFX_ERR_NONE)
713  return ff_qsv_print_error(avctx, err,
714  "Error querying the session attributes");
715 
716  if (MFX_IMPL_VIA_VAAPI == MFX_IMPL_VIA_MASK(impl)) {
717  handle_type = MFX_HANDLE_VA_DISPLAY;
718  hw_handle_supported = 1;
719  } else if (MFX_IMPL_VIA_D3D11 == MFX_IMPL_VIA_MASK(impl)) {
720  handle_type = MFX_HANDLE_D3D11_DEVICE;
721  hw_handle_supported = 1;
722  } else if (MFX_IMPL_VIA_D3D9 == MFX_IMPL_VIA_MASK(impl)) {
723  handle_type = MFX_HANDLE_D3D9_DEVICE_MANAGER;
724  hw_handle_supported = 1;
725  }
726 
727  if (hw_handle_supported) {
728  err = MFXVideoCORE_GetHandle(parent_session, handle_type, &handle);
729  if (err != MFX_ERR_NONE) {
730  return ff_qsv_print_error(avctx, err,
731  "Error getting handle session");
732  }
733  }
734  if (!handle) {
735  av_log(avctx, AV_LOG_VERBOSE, "No supported hw handle could be retrieved "
736  "from the session\n");
737  }
738 
739 #if QSV_VERSION_ATLEAST(1, 16)
740  init_par.GPUCopy = gpu_copy;
741 #endif
742  init_par.Implementation = impl;
743  init_par.Version = ver;
744  err = MFXInitEx(init_par, &session);
745  if (err != MFX_ERR_NONE)
746  return ff_qsv_print_error(avctx, err,
747  "Error initializing a child MFX session");
748 
749  if (handle) {
750  err = MFXVideoCORE_SetHandle(session, handle_type, handle);
751  if (err != MFX_ERR_NONE)
752  return ff_qsv_print_error(avctx, err,
753  "Error setting a HW handle");
754  }
755 
756  if (QSV_RUNTIME_VERSION_ATLEAST(ver, 1, 25)) {
757  err = MFXJoinSession(parent_session, session);
758  if (err != MFX_ERR_NONE)
759  return ff_qsv_print_error(avctx, err,
760  "Error joining session");
761  }
762 
763  ret = qsv_load_plugins(session, load_plugins, avctx);
764  if (ret < 0) {
765  av_log(avctx, AV_LOG_ERROR, "Error loading plugins\n");
766  return ret;
767  }
768 
769  *psession = session;
770  return 0;
771 }
772 
773 int ff_qsv_init_session_frames(AVCodecContext *avctx, mfxSession *psession,
774  QSVFramesContext *qsv_frames_ctx,
775  const char *load_plugins, int opaque, int gpu_copy)
776 {
777  mfxFrameAllocator frame_allocator = {
778  .pthis = qsv_frames_ctx,
779  .Alloc = qsv_frame_alloc,
780  .Lock = qsv_frame_lock,
781  .Unlock = qsv_frame_unlock,
782  .GetHDL = qsv_frame_get_hdl,
783  .Free = qsv_frame_free,
784  };
785 
786  AVHWFramesContext *frames_ctx = (AVHWFramesContext*)qsv_frames_ctx->hw_frames_ctx->data;
787  AVQSVFramesContext *frames_hwctx = frames_ctx->hwctx;
788 
789  mfxSession session;
790  mfxStatus err;
791 
792  int ret;
793 
794  ret = ff_qsv_init_session_device(avctx, &session,
795  frames_ctx->device_ref, load_plugins, gpu_copy);
796  if (ret < 0)
797  return ret;
798 
799  if (!opaque) {
800  qsv_frames_ctx->logctx = avctx;
801 
802  /* allocate the memory ids for the external frames */
803  av_buffer_unref(&qsv_frames_ctx->mids_buf);
804  qsv_frames_ctx->mids_buf = qsv_create_mids(qsv_frames_ctx->hw_frames_ctx);
805  if (!qsv_frames_ctx->mids_buf)
806  return AVERROR(ENOMEM);
807  qsv_frames_ctx->mids = (QSVMid*)qsv_frames_ctx->mids_buf->data;
808  qsv_frames_ctx->nb_mids = frames_hwctx->nb_surfaces;
809 
810  err = MFXVideoCORE_SetFrameAllocator(session, &frame_allocator);
811  if (err != MFX_ERR_NONE)
812  return ff_qsv_print_error(avctx, err,
813  "Error setting a frame allocator");
814  }
815 
816  *psession = session;
817  return 0;
818 }
819 
821 {
822  if (qs->session) {
823  MFXClose(qs->session);
824  qs->session = NULL;
825  }
826 #ifdef AVCODEC_QSV_LINUX_SESSION_HANDLE
827  av_buffer_unref(&qs->va_device_ref);
828 #endif
829  return 0;
830 }
AVHWDeviceContext::hwctx
void * hwctx
The format-specific data, allocated and freed by libavutil along with this context.
Definition: hwcontext.h:92
qsv_frame_unlock
static mfxStatus qsv_frame_unlock(mfxHDL pthis, mfxMemId mid, mfxFrameData *ptr)
Definition: qsv.c:668
AV_LOG_WARNING
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:186
AVPixelFormat
AVPixelFormat
Pixel format.
Definition: pixfmt.h:64
QSVFramesContext::nb_mids
int nb_mids
Definition: qsv_internal.h:103
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
uid
UID uid
Definition: mxfenc.c:2204
QSV_VERSION_MAJOR
#define QSV_VERSION_MAJOR
Definition: qsv_internal.h:48
QSVFramesContext::hw_frames_ctx
AVBufferRef * hw_frames_ctx
Definition: qsv_internal.h:94
av_get_token
char * av_get_token(const char **buf, const char *term)
Unescape the given string until a non escaped terminating char, and return the token corresponding to...
Definition: avstring.c:151
averr
int averr
Definition: qsv.c:112
QSVMid::locked_frame
AVFrame * locked_frame
Definition: qsv_internal.h:67
AVBufferRef::data
uint8_t * data
The data buffer.
Definition: buffer.h:90
AVPictureType
AVPictureType
Definition: avutil.h:272
av_frame_free
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition: frame.c:112
av_hwframe_ctx_init
int av_hwframe_ctx_init(AVBufferRef *ref)
Finalize the context before use.
Definition: hwcontext.c:333
ff_qsv_close_internal_session
int ff_qsv_close_internal_session(QSVSession *qs)
Definition: qsv.c:820
ff_qsv_map_pictype
enum AVPictureType ff_qsv_map_pictype(int mfx_pic_type)
Definition: qsv.c:262
AVFrame::width
int width
Definition: frame.h:361
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:247
av_hwframe_map
int av_hwframe_map(AVFrame *dst, const AVFrame *src, int flags)
Map a hardware frame.
Definition: hwcontext.c:789
ff_qsv_find_surface_idx
int ff_qsv_find_surface_idx(QSVFramesContext *ctx, QSVFrame *frame)
Definition: qsv.c:231
data
const char data[16]
Definition: mxf.c:143
AV_PIX_FMT_YUV420P10
#define AV_PIX_FMT_YUV420P10
Definition: pixfmt.h:391
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
AVDictionary
Definition: dict.c:30
av_buffer_ref
AVBufferRef * av_buffer_ref(const AVBufferRef *buf)
Create a new reference to an AVBuffer.
Definition: buffer.c:103
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:229
AVFrame::buf
AVBufferRef * buf[AV_NUM_DATA_POINTERS]
AVBuffer references backing the data for this frame.
Definition: frame.h:477
AVFrame::data
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition: frame.h:317
ff_qsv_init_session_device
int ff_qsv_init_session_device(AVCodecContext *avctx, mfxSession *psession, AVBufferRef *device_ref, const char *load_plugins, int gpu_copy)
Definition: qsv.c:691
AV_FIELD_TT
@ AV_FIELD_TT
Definition: codec_par.h:39
fail
#define fail()
Definition: checkasm.h:127
qsv_load_plugins
static int qsv_load_plugins(mfxSession session, const char *load_plugins, void *logctx)
Definition: qsv.c:291
type
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 type
Definition: writing_filters.txt:86
desc
const char * desc
Definition: qsv.c:83
qsv_internal.h
AV_HWFRAME_MAP_DIRECT
@ AV_HWFRAME_MAP_DIRECT
The mapping must be direct.
Definition: hwcontext.h:540
AVHWDeviceContext
This struct aggregates all the (hardware/vendor-specific) "high-level" state, i.e.
Definition: hwcontext.h:61
av_frame_alloc
AVFrame * av_frame_alloc(void)
Allocate an AVFrame and set its fields to default values.
Definition: frame.c:99
AV_PIX_FMT_Y210
#define AV_PIX_FMT_Y210
Definition: pixfmt.h:443
avassert.h
qsv_errors
static const struct @111 qsv_errors[]
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:180
ff_qsv_print_warning
int ff_qsv_print_warning(void *log_ctx, mfxStatus err, const char *warning_string)
Definition: qsv.c:177
FF_ARRAY_ELEMS
#define FF_ARRAY_ELEMS(a)
Definition: sinewin_tablegen.c:29
AVHWFramesContext::height
int height
Definition: hwcontext.h:229
QSV_VERSION_MINOR
#define QSV_VERSION_MINOR
Definition: qsv_internal.h:49
QSVMid::hw_frame
AVFrame * hw_frame
Definition: qsv_internal.h:68
AV_CODEC_ID_VP9
@ AV_CODEC_ID_VP9
Definition: codec_id.h:218
QSV_RUNTIME_VERSION_ATLEAST
#define QSV_RUNTIME_VERSION_ATLEAST(MFX_VERSION, MAJOR, MINOR)
Definition: qsv_internal.h:59
qsv_iopatterns
static const struct @110 qsv_iopatterns[]
av_assert0
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition: avassert.h:37
AV_FIELD_UNKNOWN
@ AV_FIELD_UNKNOWN
Definition: codec_par.h:37
ctx
AVFormatContext * ctx
Definition: movenc.c:48
field
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 field
Definition: writing_filters.txt:78
codec_id
enum AVCodecID codec_id
Definition: vaapi_decode.c:369
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_CODEC_ID_H264
@ AV_CODEC_ID_H264
Definition: codec_id.h:77
if
if(ret)
Definition: filter_design.txt:179
mids_buf_free
static void mids_buf_free(void *opaque, uint8_t *data)
Definition: qsv.c:434
ff_qsv_init_session_frames
int ff_qsv_init_session_frames(AVCodecContext *avctx, mfxSession *psession, QSVFramesContext *qsv_frames_ctx, const char *load_plugins, int opaque, int gpu_copy)
Definition: qsv.c:773
QSVFrame
Definition: qsv_internal.h:72
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:222
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
AV_CODEC_ID_AV1
@ AV_CODEC_ID_AV1
Definition: codec_id.h:279
AV_PIX_FMT_YUYV422
@ AV_PIX_FMT_YUYV422
packed YUV 4:2:2, 16bpp, Y0 Cb Y1 Cr
Definition: pixfmt.h:67
AVHWFramesContext::device_ref
AVBufferRef * device_ref
A reference to the parent AVHWDeviceContext.
Definition: hwcontext.h:141
AV_PIX_FMT_YUVJ420P
@ AV_PIX_FMT_YUVJ420P
planar YUV 4:2:0, 12bpp, full scale (JPEG), deprecated in favor of AV_PIX_FMT_YUV420P and setting col...
Definition: pixfmt.h:78
AV_PICTURE_TYPE_SI
@ AV_PICTURE_TYPE_SI
Switching Intra.
Definition: avutil.h:278
AV_PICTURE_TYPE_I
@ AV_PICTURE_TYPE_I
Intra.
Definition: avutil.h:274
ff_qsv_print_iopattern
int ff_qsv_print_iopattern(void *log_ctx, int mfx_iopattern, const char *extra_string)
Definition: qsv.c:93
QSVFramesContext::mids_buf
AVBufferRef * mids_buf
Definition: qsv_internal.h:101
AV_PIX_FMT_YUV422P10
#define AV_PIX_FMT_YUV422P10
Definition: pixfmt.h:392
AV_PIX_FMT_QSV
@ AV_PIX_FMT_QSV
HW acceleration through QSV, data[3] contains a pointer to the mfxFrameSurface1 structure.
Definition: pixfmt.h:212
AV_PICTURE_TYPE_SP
@ AV_PICTURE_TYPE_SP
Switching Predicted.
Definition: avutil.h:279
AV_CODEC_ID_MPEG1VIDEO
@ AV_CODEC_ID_MPEG1VIDEO
Definition: codec_id.h:51
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
error.h
AVCodecID
AVCodecID
Identify the syntax and semantics of the bitstream.
Definition: codec_id.h:47
ff_qsv_map_pixfmt
int ff_qsv_map_pixfmt(enum AVPixelFormat format, uint32_t *fourcc)
Definition: qsv.c:202
mfxerr
mfxStatus mfxerr
Definition: qsv.c:111
QSVMid::hw_frames_ref
AVBufferRef * hw_frames_ref
Definition: qsv_internal.h:64
AVFrame::format
int format
format of the frame, -1 if unknown or unset Values correspond to enum AVPixelFormat for video frames,...
Definition: frame.h:376
AV_PICTURE_TYPE_NONE
@ AV_PICTURE_TYPE_NONE
Undefined.
Definition: avutil.h:273
mfx_iopattern
int mfx_iopattern
Definition: qsv.c:82
QSVMid::handle_pair
mfxHDLPair * handle_pair
Definition: qsv_internal.h:65
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:203
av_buffer_alloc
AVBufferRef * av_buffer_alloc(size_t size)
Allocate an AVBuffer of the given size using av_malloc().
Definition: buffer.c:77
QSVFramesContext::mids
QSVMid * mids
Definition: qsv_internal.h:102
AV_HWDEVICE_TYPE_VAAPI
@ AV_HWDEVICE_TYPE_VAAPI
Definition: hwcontext.h:31
AV_FIELD_BB
@ AV_FIELD_BB
Definition: codec_par.h:40
AV_CODEC_ID_MJPEG
@ AV_CODEC_ID_MJPEG
Definition: codec_id.h:57
hwcontext_qsv.h
ff_qsv_map_picstruct
enum AVFieldOrder ff_qsv_map_picstruct(int mfx_pic_struct)
Definition: qsv.c:244
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:271
common.h
AV_CODEC_ID_HEVC
@ AV_CODEC_ID_HEVC
Definition: codec_id.h:224
QSVMid::surf
mfxFrameSurface1 surf
Definition: qsv_internal.h:69
AV_CODEC_ID_VC1
@ AV_CODEC_ID_VC1
Definition: codec_id.h:120
qsv_map_error
static int qsv_map_error(mfxStatus mfx_err, const char **desc)
Convert a libmfx error code into an FFmpeg error code.
Definition: qsv.c:153
av_calloc
void * av_calloc(size_t nmemb, size_t size)
Definition: mem.c:271
avcodec.h
AVHWFramesContext
This struct describes a set or pool of "hardware" frames (i.e.
Definition: hwcontext.h:124
qsv_frame_free
static mfxStatus qsv_frame_free(mfxHDL pthis, mfxFrameAllocResponse *resp)
Definition: qsv.c:603
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
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
QSVSession
Definition: qsv_internal.h:85
AVHWFramesContext::hwctx
void * hwctx
The format-specific data, allocated and freed automatically along with this context.
Definition: hwcontext.h:162
ff_qsv_codec_id_to_mfx
int ff_qsv_codec_id_to_mfx(enum AVCodecID codec_id)
Definition: qsv.c:45
qsv_frame_get_hdl
static mfxStatus qsv_frame_get_hdl(mfxHDL pthis, mfxMemId mid, mfxHDL *hdl)
Definition: qsv.c:678
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:610
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:607
AVCodecContext
main external API structure.
Definition: avcodec.h:383
AVFrame::height
int height
Definition: frame.h:361
qsv_frame_alloc
static mfxStatus qsv_frame_alloc(mfxHDL pthis, mfxFrameAllocRequest *req, mfxFrameAllocResponse *resp)
Definition: qsv.c:514
AV_PICTURE_TYPE_B
@ AV_PICTURE_TYPE_B
Bi-dir predicted.
Definition: avutil.h:276
AV_PIX_FMT_NONE
@ AV_PIX_FMT_NONE
Definition: pixfmt.h:65
MFX_IMPL_VIA_MASK
#define MFX_IMPL_VIA_MASK(impl)
Definition: qsv.c:39
QSVSession::session
mfxSession session
Definition: qsv_internal.h:86
ff_qsv_map_fourcc
enum AVPixelFormat ff_qsv_map_fourcc(uint32_t fourcc)
Definition: qsv.c:186
AV_PIX_FMT_P010
#define AV_PIX_FMT_P010
Definition: pixfmt.h:440
AVQSVFramesContext
This struct is allocated as AVHWFramesContext.hwctx.
Definition: hwcontext_qsv.h:42
AV_PICTURE_TYPE_P
@ AV_PICTURE_TYPE_P
Predicted.
Definition: avutil.h:275
AV_PIX_FMT_YUV422P
@ AV_PIX_FMT_YUV422P
planar YUV 4:2:2, 16bpp, (1 Cr & Cb sample per 2x1 Y samples)
Definition: pixfmt.h:70
AVBufferRef
A reference to a data buffer.
Definition: buffer.h:82
AV_FIELD_PROGRESSIVE
@ AV_FIELD_PROGRESSIVE
Definition: codec_par.h:38
qsv_setup_mids
static int qsv_setup_mids(mfxFrameAllocResponse *resp, AVBufferRef *hw_frames_ref, AVBufferRef *mids_buf)
Definition: qsv.c:478
QSVFramesContext::logctx
void * logctx
Definition: qsv_internal.h:95
AVFieldOrder
AVFieldOrder
Definition: codec_par.h:36
QSVFramesContext
Definition: qsv_internal.h:93
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
format
fg outputs[0] format
Definition: ffmpeg_filter.c:175
qsv_create_mids
static AVBufferRef * qsv_create_mids(AVBufferRef *hw_frames_ref)
Definition: qsv.c:441
imgutils.h
AV_CODEC_ID_VP8
@ AV_CODEC_ID_VP8
Definition: codec_id.h:190
hwcontext.h
AVERROR_BUG
#define AVERROR_BUG
Internal bug, also see AVERROR_BUG2.
Definition: error.h:52
AVFrame::linesize
int linesize[AV_NUM_DATA_POINTERS]
For video, size in bytes of each picture line.
Definition: frame.h:334
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:28
AVVAAPIDeviceContext
VAAPI connection details.
Definition: hwcontext_vaapi.h:68
avstring.h
AV_CODEC_ID_MPEG2VIDEO
@ AV_CODEC_ID_MPEG2VIDEO
preferred ID for MPEG-1/2 video decoding
Definition: codec_id.h:52
QSVMid
Definition: qsv_internal.h:63
ff_qsv_print_error
int ff_qsv_print_error(void *log_ctx, mfxStatus err, const char *error_string)
Definition: qsv.c:168
fourcc
uint32_t fourcc
Definition: vaapi_decode.c:239
ff_qsv_init_internal_session
int ff_qsv_init_internal_session(AVCodecContext *avctx, QSVSession *qs, const char *load_plugins, int gpu_copy)
Definition: qsv.c:375
snprintf
#define snprintf
Definition: snprintf.h:34
qsv_frame_lock
static mfxStatus qsv_frame_lock(mfxHDL pthis, mfxMemId mid, mfxFrameData *ptr)
Definition: qsv.c:611