FFmpeg
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
hwcontext_amf.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 "buffer.h"
20 #include "common.h"
21 #include "hwcontext.h"
22 #include "hwcontext_amf.h"
23 #include "hwcontext_internal.h"
24 #include "hwcontext_amf_internal.h"
25 #if CONFIG_VULKAN
26 #include "hwcontext_vulkan.h"
27 #endif
28 #if CONFIG_D3D11VA
30 #endif
31 #if CONFIG_DXVA2
32 #define COBJMACROS
34 #endif
35 #include "mem.h"
36 #include "pixdesc.h"
37 #include "pixfmt.h"
38 #include "imgutils.h"
39 #include "libavutil/avassert.h"
40 #include <AMF/core/Surface.h>
41 #include <AMF/core/Trace.h>
42 #ifdef _WIN32
43 #include "compat/w32dlfcn.h"
44 #else
45 #include <dlfcn.h>
46 #endif
47 #define FFMPEG_AMF_WRITER_ID L"ffmpeg_amf"
48 
49 
50 typedef struct AmfTraceWriter {
51  AMFTraceWriterVtbl *vtblp;
52  void *avctx;
53  AMFTraceWriterVtbl vtbl;
55 
56 static void AMF_CDECL_CALL AMFTraceWriter_Write(AMFTraceWriter *pThis,
57  const wchar_t *scope, const wchar_t *message)
58 {
59  AmfTraceWriter *tracer = (AmfTraceWriter*)pThis;
60  av_log(tracer->avctx, AV_LOG_DEBUG, "%ls: %ls", scope, message); // \n is provided from AMF
61 }
62 
63 static void AMF_CDECL_CALL AMFTraceWriter_Flush(AMFTraceWriter *pThis)
64 {
65 }
66 
67 static AmfTraceWriter * amf_writer_alloc(void *avctx)
68 {
69  AmfTraceWriter * writer = av_mallocz(sizeof(AmfTraceWriter));
70  if (!writer)
71  return NULL;
72 
73  writer->vtblp = &writer->vtbl;
74  writer->vtblp->Write = AMFTraceWriter_Write;
75  writer->vtblp->Flush = AMFTraceWriter_Flush;
76  writer->avctx = avctx;
77 
78  return writer;
79 }
80 
81 static void amf_writer_free(void *opaque)
82 {
83  AmfTraceWriter *writer = (AmfTraceWriter *)opaque;
84  av_freep(&writer);
85 }
86 
87 /**
88  * We still need AVHWFramesContext to utilize our hardware memory
89  * otherwise, we will receive the error "HW format requires hw_frames_ctx to be non-NULL".
90  * (libavfilter\buffersrc.c function query_formats)
91 */
92 typedef struct {
93  void *dummy;
95 
96 typedef struct AVAMFFormatMap {
98  enum AMF_SURFACE_FORMAT amf_format;
99 } FormatMap;
100 
101 const FormatMap format_map[] =
102 {
103  { AV_PIX_FMT_NONE, AMF_SURFACE_UNKNOWN },
104  { AV_PIX_FMT_NV12, AMF_SURFACE_NV12 },
105  { AV_PIX_FMT_BGR0, AMF_SURFACE_BGRA },
106  { AV_PIX_FMT_RGB0, AMF_SURFACE_RGBA },
107  { AV_PIX_FMT_BGRA, AMF_SURFACE_BGRA },
108  { AV_PIX_FMT_ARGB, AMF_SURFACE_ARGB },
109  { AV_PIX_FMT_RGBA, AMF_SURFACE_RGBA },
110  { AV_PIX_FMT_GRAY8, AMF_SURFACE_GRAY8 },
111  { AV_PIX_FMT_YUV420P, AMF_SURFACE_YUV420P },
112  { AV_PIX_FMT_YUYV422, AMF_SURFACE_YUY2 },
113  { AV_PIX_FMT_P010, AMF_SURFACE_P010 },
114  { AV_PIX_FMT_X2BGR10, AMF_SURFACE_R10G10B10A2 },
115  { AV_PIX_FMT_RGBAF16, AMF_SURFACE_RGBA_F16},
116 };
117 
118 enum AMF_SURFACE_FORMAT av_av_to_amf_format(enum AVPixelFormat fmt)
119 {
120  int i;
121  for (i = 0; i < amf_countof(format_map); i++) {
122  if (format_map[i].av_format == fmt) {
123  return format_map[i].amf_format;
124  }
125  }
126  return AMF_SURFACE_UNKNOWN;
127 }
128 
129 enum AVPixelFormat av_amf_to_av_format(enum AMF_SURFACE_FORMAT fmt)
130 {
131  int i;
132  for (i = 0; i < amf_countof(format_map); i++) {
133  if (format_map[i].amf_format == fmt) {
134  return format_map[i].av_format;
135  }
136  }
137  return AMF_SURFACE_UNKNOWN;
138 }
139 
140 static const enum AVPixelFormat supported_formats[] = {
146 #if CONFIG_D3D11VA
148 #endif
149 #if CONFIG_DXVA2
151 #endif
152 };
153 
161 };
162 
164  const void *hwconfig,
165  AVHWFramesConstraints *constraints)
166 {
167  int i;
168 
170  sizeof(*constraints->valid_sw_formats));
171  if (!constraints->valid_sw_formats)
172  return AVERROR(ENOMEM);
173 
174  for (i = 0; i < FF_ARRAY_ELEMS(supported_formats); i++)
175  constraints->valid_sw_formats[i] = supported_formats[i];
177 
178  constraints->valid_hw_formats = av_malloc_array(2, sizeof(*constraints->valid_hw_formats));
179  if (!constraints->valid_hw_formats)
180  return AVERROR(ENOMEM);
181 
182  constraints->valid_hw_formats[0] = AV_PIX_FMT_AMF_SURFACE;
183  constraints->valid_hw_formats[1] = AV_PIX_FMT_NONE;
184 
185  return 0;
186 }
187 
188 static void amf_dummy_free(void *opaque, uint8_t *data)
189 {
190 
191 }
192 
193 static AVBufferRef *amf_pool_alloc(void *opaque, size_t size)
194 {
195  AVHWFramesContext *hwfc = (AVHWFramesContext *)opaque;
196  AVBufferRef *buf;
197 
199  if (!buf) {
200  av_log(hwfc, AV_LOG_ERROR, "Failed to create buffer for AMF context.\n");
201  return NULL;
202  }
203  return buf;
204 }
205 
207 {
208  int i;
209 
210  for (i = 0; i < FF_ARRAY_ELEMS(supported_formats); i++) {
211  if (ctx->sw_format == supported_formats[i])
212  break;
213  }
215  av_log(ctx, AV_LOG_ERROR, "Pixel format '%s' is not supported\n",
216  av_get_pix_fmt_name(ctx->sw_format));
217  return AVERROR(ENOSYS);
218  }
219 
221  av_buffer_pool_init2(sizeof(AMFSurface), ctx,
222  &amf_pool_alloc, NULL);
223 
224  return 0;
225 }
226 
227 
229 {
230  frame->buf[0] = av_buffer_pool_get(ctx->pool);
231  if (!frame->buf[0])
232  return AVERROR(ENOMEM);
233 
234  frame->data[0] = frame->buf[0]->data;
235  frame->format = AV_PIX_FMT_AMF_SURFACE;
236  frame->width = ctx->width;
237  frame->height = ctx->height;
238  return 0;
239 }
240 
243  enum AVPixelFormat **formats)
244 {
245  enum AVPixelFormat *fmts;
246  int i;
247 
249  if (!fmts)
250  return AVERROR(ENOMEM);
252  fmts[i] = supported_transfer_formats[i];
253 
254  *formats = fmts;
255 
256  return 0;
257 }
258 
259 static void amf_free_amfsurface(void *opaque, uint8_t *data)
260 {
261  if(!!data){
262  AMFSurface *surface = (AMFSurface*)(data);
263  surface->pVtbl->Release(surface);
264  }
265 }
266 
268  const AVFrame *src)
269 {
270  AMFSurface* surface = (AMFSurface*)dst->data[0];
271  AMFPlane *plane;
272  uint8_t *dst_data[4];
273  int dst_linesize[4];
274  int planes;
275  int i;
276  int res;
277  int w = FFMIN(dst->width, src->width);
278  int h = FFMIN(dst->height, src->height);
279 
280  if (dst->hw_frames_ctx->data != (uint8_t *)ctx || src->format != ctx->sw_format)
281  return AVERROR(EINVAL);
282 
283  if (!surface) {
284  AVHWDeviceContext *hwdev_ctx = ctx->device_ctx;
285  AVAMFDeviceContext *amf_device_ctx = (AVAMFDeviceContext *)hwdev_ctx->hwctx;
286  AMF_SURFACE_FORMAT format = av_av_to_amf_format(ctx->sw_format);
287  res = amf_device_ctx->context->pVtbl->AllocSurface(amf_device_ctx->context, AMF_MEMORY_HOST, format, dst->width, dst->height, &surface);
288  AMF_RETURN_IF_FALSE(ctx, res == AMF_OK, AVERROR(ENOMEM), "AllocSurface() failed with error %d\n", res);
289  dst->data[0] = (uint8_t *)surface;
290  dst->buf[1] = av_buffer_create((uint8_t *)surface, sizeof(surface),
292  NULL,
294  AMF_RETURN_IF_FALSE(ctx, !!dst->buf[1], AVERROR(ENOMEM), "av_buffer_create for amf surface failed.");
295  }
296 
297  planes = (int)surface->pVtbl->GetPlanesCount(surface);
298  av_assert0(planes < FF_ARRAY_ELEMS(dst_data));
299 
300  for (i = 0; i < planes; i++) {
301  plane = surface->pVtbl->GetPlaneAt(surface, i);
302  dst_data[i] = plane->pVtbl->GetNative(plane);
303  dst_linesize[i] = plane->pVtbl->GetHPitch(plane);
304  }
305  av_image_copy2(dst_data, dst_linesize,
306  src->data, src->linesize, src->format,
307  w, h);
308 
309  return 0;
310 }
311 
313  const AVFrame *src)
314 {
315  AMFSurface* surface = (AMFSurface*)src->data[0];
316  AMFPlane *plane;
317  uint8_t *src_data[4];
318  int src_linesize[4];
319  int planes;
320  int i;
321  int w = FFMIN(dst->width, src->width);
322  int h = FFMIN(dst->height, src->height);
323  int ret;
324 
325  if (src->hw_frames_ctx->data != (uint8_t *)ctx || dst->format != ctx->sw_format)
326  return AVERROR(EINVAL);
327 
328  ret = surface->pVtbl->Convert(surface, AMF_MEMORY_HOST);
329  AMF_RETURN_IF_FALSE(ctx, ret == AMF_OK, AVERROR_UNKNOWN, "Convert(amf::AMF_MEMORY_HOST) failed with error %d\n", AVERROR_UNKNOWN);
330 
331  planes = (int)surface->pVtbl->GetPlanesCount(surface);
332  av_assert0(planes < FF_ARRAY_ELEMS(src_data));
333 
334  for (i = 0; i < planes; i++) {
335  plane = surface->pVtbl->GetPlaneAt(surface, i);
336  src_data[i] = plane->pVtbl->GetNative(plane);
337  src_linesize[i] = plane->pVtbl->GetHPitch(plane);
338  }
339  av_image_copy2(dst->data, dst->linesize,
340  src_data, src_linesize, dst->format,
341  w, h);
342  return 0;
343 }
344 
345 
346 
347 static void amf_device_uninit(AVHWDeviceContext *device_ctx)
348 {
349  AVAMFDeviceContext *amf_ctx = device_ctx->hwctx;
350  AMF_RESULT res = AMF_NOT_INITIALIZED;
351  AMFTrace *trace;
352 
353  if (amf_ctx->context) {
354  amf_ctx->context->pVtbl->Terminate(amf_ctx->context);
355  amf_ctx->context->pVtbl->Release(amf_ctx->context);
356  amf_ctx->context = NULL;
357  }
358 
359  if (amf_ctx->factory)
360  res = amf_ctx->factory->pVtbl->GetTrace(amf_ctx->factory, &trace);
361 
362  if (res == AMF_OK) {
363  trace->pVtbl->UnregisterWriter(trace, FFMPEG_AMF_WRITER_ID);
364  }
365 
366  if(amf_ctx->library) {
367  dlclose(amf_ctx->library);
368  amf_ctx->library = NULL;
369  }
370  if (amf_ctx->trace_writer) {
371  amf_writer_free(amf_ctx->trace_writer);
372  }
373 
374  amf_ctx->version = 0;
375 }
376 
378 {
379  AVAMFDeviceContext *amf_ctx = ctx->hwctx;
380  AMFContext1 *context1 = NULL;
381  AMF_RESULT res;
382 
383 #ifdef _WIN32
384  res = amf_ctx->context->pVtbl->InitDX11(amf_ctx->context, NULL, AMF_DX11_1);
385  if (res == AMF_OK || res == AMF_ALREADY_INITIALIZED) {
386  av_log(ctx, AV_LOG_VERBOSE, "AMF initialisation succeeded via D3D11.\n");
387  } else {
388  res = amf_ctx->context->pVtbl->InitDX9(amf_ctx->context, NULL);
389  if (res == AMF_OK) {
390  av_log(ctx, AV_LOG_VERBOSE, "AMF initialisation succeeded via D3D9.\n");
391  } else {
392 #endif
393  AMFGuid guid = IID_AMFContext1();
394  res = amf_ctx->context->pVtbl->QueryInterface(amf_ctx->context, &guid, (void**)&context1);
395  AMF_RETURN_IF_FALSE(ctx, res == AMF_OK, AVERROR_UNKNOWN, "CreateContext1() failed with error %d\n", res);
396 
397  res = context1->pVtbl->InitVulkan(context1, NULL);
398  context1->pVtbl->Release(context1);
399  if (res != AMF_OK && res != AMF_ALREADY_INITIALIZED) {
400  if (res == AMF_NOT_SUPPORTED)
401  av_log(ctx, AV_LOG_ERROR, "AMF via Vulkan is not supported on the given device.\n");
402  else
403  av_log(ctx, AV_LOG_ERROR, "AMF failed to initialise on the given Vulkan device: %d.\n", res);
404  return AVERROR(ENOSYS);
405  }
406  av_log(ctx, AV_LOG_VERBOSE, "AMF initialisation succeeded via Vulkan.\n");
407 #ifdef _WIN32
408  }
409  }
410 #endif
411  return 0;
412 }
413 
414 static int amf_load_library(AVAMFDeviceContext* amf_ctx, void* avcl)
415 {
416  AMFInit_Fn init_fun;
417  AMFQueryVersion_Fn version_fun;
418  AMF_RESULT res;
419 
420  amf_ctx->library = dlopen(AMF_DLL_NAMEA, RTLD_NOW | RTLD_LOCAL);
421  AMF_RETURN_IF_FALSE(avcl, amf_ctx->library != NULL,
422  AVERROR_UNKNOWN, "DLL %s failed to open\n", AMF_DLL_NAMEA);
423 
424  init_fun = (AMFInit_Fn)dlsym(amf_ctx->library, AMF_INIT_FUNCTION_NAME);
425  AMF_RETURN_IF_FALSE(avcl, init_fun != NULL, AVERROR_UNKNOWN, "DLL %s failed to find function %s\n", AMF_DLL_NAMEA, AMF_INIT_FUNCTION_NAME);
426 
427  version_fun = (AMFQueryVersion_Fn)dlsym(amf_ctx->library, AMF_QUERY_VERSION_FUNCTION_NAME);
428  AMF_RETURN_IF_FALSE(avcl, version_fun != NULL, AVERROR_UNKNOWN, "DLL %s failed to find function %s\n", AMF_DLL_NAMEA, AMF_QUERY_VERSION_FUNCTION_NAME);
429 
430  res = version_fun(&amf_ctx->version);
431  AMF_RETURN_IF_FALSE(avcl, res == AMF_OK, AVERROR_UNKNOWN, "%s failed with error %d\n", AMF_QUERY_VERSION_FUNCTION_NAME, res);
432  res = init_fun(AMF_FULL_VERSION, &amf_ctx->factory);
433  AMF_RETURN_IF_FALSE(avcl, res == AMF_OK, AVERROR_UNKNOWN, "%s failed with error %d\n", AMF_INIT_FUNCTION_NAME, res);
434  return 0;
435 }
436 
437 static int amf_device_create(AVHWDeviceContext *device_ctx,
438  const char *device,
439  AVDictionary *opts, int flags)
440 {
441  AVAMFDeviceContext *ctx = device_ctx->hwctx;
442  AMFTrace *trace;
443  int ret;
444  if ((ret = amf_load_library(ctx, device_ctx)) == 0) {
445  ret = ctx->factory->pVtbl->GetTrace(ctx->factory, &trace);
446  if (ret == AMF_OK) {
447  int level_ff = av_log_get_level();
448  int level_amf = AMF_TRACE_TRACE;
449  amf_bool enable_log = true;
450  switch(level_ff)
451  {
452  case AV_LOG_QUIET:
453  level_amf = AMF_TRACE_ERROR;
454  enable_log = false;
455  break;
456  case AV_LOG_PANIC:
457  case AV_LOG_FATAL:
458  case AV_LOG_ERROR:
459  level_amf = AMF_TRACE_ERROR;
460  break;
461  case AV_LOG_WARNING:
462  case AV_LOG_INFO:
463  level_amf = AMF_TRACE_WARNING;
464  break;
465  case AV_LOG_VERBOSE:
466  level_amf = AMF_TRACE_INFO;
467  break;
468  case AV_LOG_DEBUG:
469  level_amf = AMF_TRACE_DEBUG;
470  break;
471  case AV_LOG_TRACE:
472  level_amf = AMF_TRACE_TRACE;
473  break;
474  }
475  if(ctx->version == AMF_MAKE_FULL_VERSION(1, 4, 35, 0)){// get around a bug in trace in AMF runtime driver 24.20
476  level_amf = AMF_TRACE_WARNING;
477  }
478 
479  trace->pVtbl->EnableWriter(trace, AMF_TRACE_WRITER_CONSOLE, 0);
480  trace->pVtbl->SetGlobalLevel(trace, level_amf);
481 
482  // connect AMF logger to av_log
483  ctx->trace_writer = amf_writer_alloc(device_ctx);
484  trace->pVtbl->RegisterWriter(trace, FFMPEG_AMF_WRITER_ID, (AMFTraceWriter*)ctx->trace_writer, 1);
485  trace->pVtbl->SetWriterLevel(trace, FFMPEG_AMF_WRITER_ID, level_amf);
486  trace->pVtbl->EnableWriter(trace, FFMPEG_AMF_WRITER_ID, enable_log);
487  trace->pVtbl->SetWriterLevel(trace, AMF_TRACE_WRITER_DEBUG_OUTPUT, level_amf);
488  trace->pVtbl->EnableWriter(trace, AMF_TRACE_WRITER_DEBUG_OUTPUT, enable_log);
489  }
490 
491 
492  ret = ctx->factory->pVtbl->CreateContext(ctx->factory, &ctx->context);
493  if (ret == AMF_OK)
494  return 0;
495  av_log(device_ctx, AV_LOG_ERROR, "CreateContext() failed with error %d.\n", ret);
496  }
497  amf_device_uninit(device_ctx);
498  return ret;
499 }
500 
501 #if CONFIG_DXVA2
502 static int amf_init_from_dxva2_device(AVAMFDeviceContext * amf_ctx, AVDXVA2DeviceContext *hwctx)
503 {
504  IDirect3DDevice9 *device;
505  HANDLE device_handle;
506  HRESULT hr;
507  AMF_RESULT res;
508  int ret;
509 
510  hr = IDirect3DDeviceManager9_OpenDeviceHandle(hwctx->devmgr, &device_handle);
511  if (FAILED(hr)) {
512  av_log(hwctx, AV_LOG_ERROR, "Failed to open device handle for Direct3D9 device: %lx.\n", (unsigned long)hr);
513  return AVERROR_EXTERNAL;
514  }
515 
516  hr = IDirect3DDeviceManager9_LockDevice(hwctx->devmgr, device_handle, &device, FALSE);
517  if (SUCCEEDED(hr)) {
518  IDirect3DDeviceManager9_UnlockDevice(hwctx->devmgr, device_handle, FALSE);
519  ret = 0;
520  } else {
521  av_log(hwctx, AV_LOG_ERROR, "Failed to lock device handle for Direct3D9 device: %lx.\n", (unsigned long)hr);
523  }
524 
525 
526  IDirect3DDeviceManager9_CloseDeviceHandle(hwctx->devmgr, device_handle);
527 
528  if (ret < 0)
529  return ret;
530 
531  res = amf_ctx->context->pVtbl->InitDX9(amf_ctx->context, device);
532 
533  IDirect3DDevice9_Release(device);
534 
535  if (res != AMF_OK && res != AMF_ALREADY_INITIALIZED) {
536  if (res == AMF_NOT_SUPPORTED)
537  av_log(hwctx, AV_LOG_ERROR, "AMF via D3D9 is not supported on the given device.\n");
538  else
539  av_log(hwctx, AV_LOG_ERROR, "AMF failed to initialise on given D3D9 device: %d.\n", res);
540  return AVERROR(ENODEV);
541  }
542  return 0;
543 }
544 #endif
545 
546 #if CONFIG_D3D11VA
547 static int amf_init_from_d3d11_device(AVAMFDeviceContext* amf_ctx, AVD3D11VADeviceContext *hwctx)
548 {
549  AMF_RESULT res;
550  res = amf_ctx->context->pVtbl->InitDX11(amf_ctx->context, hwctx->device, AMF_DX11_1);
551  if (res != AMF_OK && res != AMF_ALREADY_INITIALIZED) {
552  if (res == AMF_NOT_SUPPORTED)
553  av_log(hwctx, AV_LOG_ERROR, "AMF via D3D11 is not supported on the given device.\n");
554  else
555  av_log(hwctx, AV_LOG_ERROR, "AMF failed to initialise on the given D3D11 device: %d.\n", res);
556  return AVERROR(ENODEV);
557  }
558  return 0;
559 }
560 #endif
561 
562 static int amf_device_derive(AVHWDeviceContext *device_ctx,
563  AVHWDeviceContext *child_device_ctx, AVDictionary *opts,
564  int flags)
565 {
566 #if CONFIG_DXVA2 || CONFIG_D3D11VA
567  AVAMFDeviceContext *amf_ctx = device_ctx->hwctx;
568 #endif
569  int ret;
570 
571  ret = amf_device_create(device_ctx, "", opts, flags);
572  if(ret < 0)
573  return ret;
574 
575  switch (child_device_ctx->type) {
576 
577 #if CONFIG_DXVA2
578  case AV_HWDEVICE_TYPE_DXVA2: {
579  AVDXVA2DeviceContext *child_device_hwctx = child_device_ctx->hwctx;
580  return amf_init_from_dxva2_device(amf_ctx, child_device_hwctx);
581  }
582  break;
583 #endif
584 
585 #if CONFIG_D3D11VA
587  AVD3D11VADeviceContext *child_device_hwctx = child_device_ctx->hwctx;
588  return amf_init_from_d3d11_device(amf_ctx, child_device_hwctx);
589  }
590  break;
591 #endif
592  default: {
593  av_log(child_device_ctx, AV_LOG_ERROR, "AMF initialisation from a %s device is not supported.\n",
594  av_hwdevice_get_type_name(child_device_ctx->type));
595  return AVERROR(ENOSYS);
596  }
597  }
598  return 0;
599 }
600 
603  .name = "AMF",
604 
605  .device_hwctx_size = sizeof(AVAMFDeviceContext),
606  .frames_hwctx_size = sizeof(AMFFramesContext),
607 
608  .device_create = amf_device_create,
609  .device_derive = amf_device_derive,
610  .device_init = amf_device_init,
611  .device_uninit = amf_device_uninit,
612  .frames_get_constraints = amf_frames_get_constraints,
613  .frames_init = amf_frames_init,
614  .frames_get_buffer = amf_get_buffer,
615  .transfer_get_formats = amf_transfer_get_formats,
616  .transfer_data_to = amf_transfer_data_to,
617  .transfer_data_from = amf_transfer_data_from,
618 
619  .pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_AMF_SURFACE, AV_PIX_FMT_NONE },
620 };
flags
const SwsFlags flags[]
Definition: swscale.c:61
formats
formats
Definition: signature.h:47
AMFFramesContext::dummy
void * dummy
Definition: hwcontext_amf.c:93
AVHWDeviceContext::hwctx
void * hwctx
The format-specific data, allocated and freed by libavutil along with this context.
Definition: hwcontext.h:86
FFHWFramesContext::pool_internal
AVBufferPool * pool_internal
Definition: hwcontext_internal.h:101
AV_LOG_WARNING
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:215
AVPixelFormat
AVPixelFormat
Pixel format.
Definition: pixfmt.h:71
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
message
Definition: api-threadmessage-test.c:47
AV_LOG_QUIET
#define AV_LOG_QUIET
Print no output.
Definition: log.h:191
AV_LOG_PANIC
#define AV_LOG_PANIC
Something went really wrong and we will crash now.
Definition: log.h:196
amf_writer_alloc
static AmfTraceWriter * amf_writer_alloc(void *avctx)
Definition: hwcontext_amf.c:67
AVFrame
This structure describes decoded (raw) audio or video data.
Definition: frame.h:410
pixdesc.h
w
uint8_t w
Definition: llviddspenc.c:38
amf_dummy_free
static void amf_dummy_free(void *opaque, uint8_t *data)
Definition: hwcontext_amf.c:188
data
const char data[16]
Definition: mxf.c:149
amf_device_create
static int amf_device_create(AVHWDeviceContext *device_ctx, const char *device, AVDictionary *opts, int flags)
Definition: hwcontext_amf.c:437
AVDXVA2DeviceContext::devmgr
IDirect3DDeviceManager9 * devmgr
Definition: hwcontext_dxva2.h:40
AV_LOG_VERBOSE
#define AV_LOG_VERBOSE
Detailed information.
Definition: log.h:225
AMFTraceWriter_Write
static void AMF_CDECL_CALL AMFTraceWriter_Write(AMFTraceWriter *pThis, const wchar_t *scope, const wchar_t *message)
Definition: hwcontext_amf.c:56
AV_PIX_FMT_BGRA
@ AV_PIX_FMT_BGRA
packed BGRA 8:8:8:8, 32bpp, BGRABGRA...
Definition: pixfmt.h:102
AVDictionary
Definition: dict.c:32
AMF_RETURN_IF_FALSE
#define AMF_RETURN_IF_FALSE(avctx, exp, ret_value,...)
Error handling helper.
Definition: amfenc.h:164
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:447
AVERROR_UNKNOWN
#define AVERROR_UNKNOWN
Unknown error, typically from an external library.
Definition: error.h:73
planes
static const struct @487 planes[]
AVAMFFormatMap
Definition: hwcontext_amf.c:96
AV_PIX_FMT_AMF_SURFACE
@ AV_PIX_FMT_AMF_SURFACE
HW acceleration through AMF.
Definition: pixfmt.h:477
AVHWFramesConstraints
This struct describes the constraints on hardware frames attached to a given device with a hardware-s...
Definition: hwcontext.h:442
av_amf_to_av_format
enum AVPixelFormat av_amf_to_av_format(enum AMF_SURFACE_FORMAT fmt)
Definition: hwcontext_amf.c:129
AV_HWDEVICE_TYPE_D3D11VA
@ AV_HWDEVICE_TYPE_D3D11VA
Definition: hwcontext.h:35
av_buffer_pool_init2
AVBufferPool * av_buffer_pool_init2(size_t size, void *opaque, AVBufferRef *(*alloc)(void *opaque, size_t size), void(*pool_free)(void *opaque))
Allocate and initialize a buffer pool with a more complex allocator.
Definition: buffer.c:259
av_av_to_amf_format
enum AMF_SURFACE_FORMAT av_av_to_amf_format(enum AVPixelFormat fmt)
Definition: hwcontext_amf.c:118
AVAMFDeviceContext::context
AMFContext * context
Definition: hwcontext_amf.h:39
AVHWDeviceContext
This struct aggregates all the (hardware/vendor-specific) "high-level" state, i.e.
Definition: hwcontext.h:61
amf_transfer_get_formats
static int amf_transfer_get_formats(AVHWFramesContext *ctx, enum AVHWFrameTransferDirection dir, enum AVPixelFormat **formats)
Definition: hwcontext_amf.c:241
avassert.h
HWContextType::type
enum AVHWDeviceType type
Definition: hwcontext_internal.h:30
ffhwframesctx
static FFHWFramesContext * ffhwframesctx(AVHWFramesContext *ctx)
Definition: hwcontext_internal.h:115
AV_LOG_TRACE
#define AV_LOG_TRACE
Extremely verbose debugging, useful for libav* development.
Definition: log.h:235
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:209
FF_ARRAY_ELEMS
#define FF_ARRAY_ELEMS(a)
Definition: sinewin_tablegen.c:29
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:454
av_buffer_pool_get
AVBufferRef * av_buffer_pool_get(AVBufferPool *pool)
Allocate a new AVBuffer, reusing an old buffer from the pool when available.
Definition: buffer.c:390
AVAMFFormatMap::av_format
enum AVPixelFormat av_format
Definition: hwcontext_amf.c:97
AV_PIX_FMT_DXVA2_VLD
@ AV_PIX_FMT_DXVA2_VLD
HW decoding through DXVA2, Picture.data[3] contains a LPDIRECT3DSURFACE9 pointer.
Definition: pixfmt.h:134
amf_frames_get_constraints
static int amf_frames_get_constraints(AVHWDeviceContext *ctx, const void *hwconfig, AVHWFramesConstraints *constraints)
Definition: hwcontext_amf.c:163
AVD3D11VADeviceContext::device
ID3D11Device * device
Device used for texture creation and access.
Definition: hwcontext_d3d11va.h:56
AV_BUFFER_FLAG_READONLY
#define AV_BUFFER_FLAG_READONLY
Always treat the buffer as read-only, even when it has only one reference.
Definition: buffer.h:114
format
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 format(the sample packing is implied by the sample format) and sample rate. The lists are not just lists
AmfTraceWriter::vtblp
AMFTraceWriterVtbl * vtblp
Definition: hwcontext_amf.c:51
av_assert0
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition: avassert.h:40
amf_device_init
static int amf_device_init(AVHWDeviceContext *ctx)
Definition: hwcontext_amf.c:377
AV_HWDEVICE_TYPE_AMF
@ AV_HWDEVICE_TYPE_AMF
Definition: hwcontext.h:41
AV_LOG_DEBUG
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:230
amf_transfer_data_to
static int amf_transfer_data_to(AVHWFramesContext *ctx, AVFrame *dst, const AVFrame *src)
Definition: hwcontext_amf.c:267
ctx
AVFormatContext * ctx
Definition: movenc.c:49
FFMPEG_AMF_WRITER_ID
#define FFMPEG_AMF_WRITER_ID
Definition: hwcontext_amf.c:47
hwcontext_amf.h
AVAMFDeviceContext::version
int64_t version
version of AMF runtime
Definition: hwcontext_amf.h:38
amf_writer_free
static void amf_writer_free(void *opaque)
Definition: hwcontext_amf.c:81
av_hwdevice_get_type_name
const char * av_hwdevice_get_type_name(enum AVHWDeviceType type)
Get the string name of an AVHWDeviceType.
Definition: hwcontext.c:116
AV_PIX_FMT_YUV420P
@ AV_PIX_FMT_YUV420P
planar YUV 4:2:0, 12bpp, (1 Cr & Cb sample per 2x2 Y samples)
Definition: pixfmt.h:73
AV_PIX_FMT_RGBA
@ AV_PIX_FMT_RGBA
packed RGBA 8:8:8:8, 32bpp, RGBARGBA...
Definition: pixfmt.h:100
av_log_get_level
int av_log_get_level(void)
Get the current log level.
Definition: log.c:468
opts
AVDictionary * opts
Definition: movenc.c:51
NULL
#define NULL
Definition: coverity.c:32
amf_pool_alloc
static AVBufferRef * amf_pool_alloc(void *opaque, size_t size)
Definition: hwcontext_amf.c:193
AV_HWDEVICE_TYPE_DXVA2
@ AV_HWDEVICE_TYPE_DXVA2
Definition: hwcontext.h:32
AV_PIX_FMT_YUYV422
@ AV_PIX_FMT_YUYV422
packed YUV 4:2:2, 16bpp, Y0 Cb Y1 Cr
Definition: pixfmt.h:74
hwcontext_vulkan.h
AV_PIX_FMT_BGR0
@ AV_PIX_FMT_BGR0
packed BGR 8:8:8, 32bpp, BGRXBGRX... X=unused/undefined
Definition: pixfmt.h:265
AV_PIX_FMT_GRAY8
@ AV_PIX_FMT_GRAY8
Y , 8bpp.
Definition: pixfmt.h:81
AVAMFDeviceContext::trace_writer
void * trace_writer
Definition: hwcontext_amf.h:36
amf_get_buffer
static int amf_get_buffer(AVHWFramesContext *ctx, AVFrame *frame)
Definition: hwcontext_amf.c:228
AVAMFDeviceContext::library
void * library
Definition: hwcontext_amf.h:34
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
AmfTraceWriter
Definition: hwcontext_amf.c:50
AV_PIX_FMT_X2BGR10
#define AV_PIX_FMT_X2BGR10
Definition: pixfmt.h:597
hwcontext_dxva2.h
amf_free_amfsurface
static void amf_free_amfsurface(void *opaque, uint8_t *data)
Definition: hwcontext_amf.c:259
dst
uint8_t ptrdiff_t const uint8_t ptrdiff_t int intptr_t intptr_t int int16_t * dst
Definition: dsp.h:83
size
int size
Definition: twinvq_data.h:10344
AVAMFDeviceContext
This struct is allocated as AVHWDeviceContext.hwctx.
Definition: hwcontext_amf.h:33
ff_hwcontext_type_amf
const HWContextType ff_hwcontext_type_amf
Definition: hwcontext_amf.c:601
amf_device_uninit
static void amf_device_uninit(AVHWDeviceContext *device_ctx)
Definition: hwcontext_amf.c:347
AMFFramesContext
We still need AVHWFramesContext to utilize our hardware memory otherwise, we will receive the error "...
Definition: hwcontext_amf.c:92
buffer.h
AVERROR_EXTERNAL
#define AVERROR_EXTERNAL
Generic error in an external library.
Definition: error.h:59
AV_PIX_FMT_RGB0
@ AV_PIX_FMT_RGB0
packed RGB 8:8:8, 32bpp, RGBXRGBX... X=unused/undefined
Definition: pixfmt.h:263
AV_PIX_FMT_D3D11
@ AV_PIX_FMT_D3D11
Hardware surfaces for Direct3D11.
Definition: pixfmt.h:336
amf_frames_init
static int amf_frames_init(AVHWFramesContext *ctx)
Definition: hwcontext_amf.c:206
AV_LOG_INFO
#define AV_LOG_INFO
Standard information.
Definition: log.h:220
AV_PIX_FMT_ARGB
@ AV_PIX_FMT_ARGB
packed ARGB 8:8:8:8, 32bpp, ARGBARGB...
Definition: pixfmt.h:99
AVAMFFormatMap::amf_format
enum AMF_SURFACE_FORMAT amf_format
Definition: hwcontext_amf.c:98
AVAMFDeviceContext::factory
AMFFactory * factory
Definition: hwcontext_amf.h:35
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:256
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
AVD3D11VADeviceContext
This struct is allocated as AVHWDeviceContext.hwctx.
Definition: hwcontext_d3d11va.h:45
amf_transfer_data_from
static int amf_transfer_data_from(AVHWFramesContext *ctx, AVFrame *dst, const AVFrame *src)
Definition: hwcontext_amf.c:312
FFMIN
#define FFMIN(a, b)
Definition: macros.h:49
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:256
amf_device_derive
static int amf_device_derive(AVHWDeviceContext *device_ctx, AVHWDeviceContext *child_device_ctx, AVDictionary *opts, int flags)
Definition: hwcontext_amf.c:562
AVHWFrameTransferDirection
AVHWFrameTransferDirection
Definition: hwcontext.h:404
AVHWFramesContext
This struct describes a set or pool of "hardware" frames (i.e.
Definition: hwcontext.h:116
ret
ret
Definition: filter_design.txt:187
AV_LOG_FATAL
#define AV_LOG_FATAL
Something went wrong and recovery is not possible.
Definition: log.h:203
AVHWDeviceContext::type
enum AVHWDeviceType type
This field identifies the underlying API used for hardware access.
Definition: hwcontext.h:73
pixfmt.h
AV_PIX_FMT_NV12
@ AV_PIX_FMT_NV12
planar YUV 4:2:0, 12bpp, 1 plane for Y and 1 plane for the UV components, which are interleaved (firs...
Definition: pixfmt.h:96
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
supported_formats
static enum AVPixelFormat supported_formats[]
Definition: hwcontext_amf.c:140
hwcontext_amf_internal.h
amf_load_library
static int amf_load_library(AVAMFDeviceContext *amf_ctx, void *avcl)
Definition: hwcontext_amf.c:414
av_image_copy2
static void av_image_copy2(uint8_t *const dst_data[4], const int dst_linesizes[4], uint8_t *const src_data[4], const int src_linesizes[4], enum AVPixelFormat pix_fmt, int width, int height)
Wrapper around av_image_copy() to workaround the limitation that the conversion from uint8_t * const ...
Definition: imgutils.h:184
AV_PIX_FMT_NONE
@ AV_PIX_FMT_NONE
Definition: pixfmt.h:72
format_map
const FormatMap format_map[]
Definition: hwcontext_amf.c:101
AmfTraceWriter::avctx
void * avctx
Definition: hwcontext_amf.c:52
AV_PIX_FMT_P010
#define AV_PIX_FMT_P010
Definition: pixfmt.h:585
mem.h
AVBufferRef
A reference to a data buffer.
Definition: buffer.h:82
AmfTraceWriter::vtbl
AMFTraceWriterVtbl vtbl
Definition: hwcontext_amf.c:53
hwcontext_internal.h
AMFTraceWriter_Flush
static void AMF_CDECL_CALL AMFTraceWriter_Flush(AMFTraceWriter *pThis)
Definition: hwcontext_amf.c:63
AV_PIX_FMT_RGBAF16
#define AV_PIX_FMT_RGBAF16
Definition: pixfmt.h:607
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:35
imgutils.h
hwcontext.h
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:27
HWContextType
Definition: hwcontext_internal.h:29
h
h
Definition: vp9dsp_template.c:2070
hwcontext_d3d11va.h
src
#define src
Definition: vp8dsp.c:248
supported_transfer_formats
static enum AVPixelFormat supported_transfer_formats[]
Definition: hwcontext_amf.c:154
w32dlfcn.h
av_get_pix_fmt_name
const char * av_get_pix_fmt_name(enum AVPixelFormat pix_fmt)
Return the short name for a pixel format, NULL in case pix_fmt is unknown.
Definition: pixdesc.c:3261