FFmpeg
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 };
115 
116 enum AMF_SURFACE_FORMAT av_av_to_amf_format(enum AVPixelFormat fmt)
117 {
118  int i;
119  for (i = 0; i < amf_countof(format_map); i++) {
120  if (format_map[i].av_format == fmt) {
121  return format_map[i].amf_format;
122  }
123  }
124  return AMF_SURFACE_UNKNOWN;
125 }
126 
127 enum AVPixelFormat av_amf_to_av_format(enum AMF_SURFACE_FORMAT fmt)
128 {
129  int i;
130  for (i = 0; i < amf_countof(format_map); i++) {
131  if (format_map[i].amf_format == fmt) {
132  return format_map[i].av_format;
133  }
134  }
135  return AMF_SURFACE_UNKNOWN;
136 }
137 
138 static const enum AVPixelFormat supported_formats[] = {
144 #if CONFIG_D3D11VA
146 #endif
147 #if CONFIG_DXVA2
149 #endif
150 };
151 
159 };
160 
162  const void *hwconfig,
163  AVHWFramesConstraints *constraints)
164 {
165  int i;
166 
168  sizeof(*constraints->valid_sw_formats));
169  if (!constraints->valid_sw_formats)
170  return AVERROR(ENOMEM);
171 
172  for (i = 0; i < FF_ARRAY_ELEMS(supported_formats); i++)
173  constraints->valid_sw_formats[i] = supported_formats[i];
175 
176  constraints->valid_hw_formats = av_malloc_array(2, sizeof(*constraints->valid_hw_formats));
177  if (!constraints->valid_hw_formats)
178  return AVERROR(ENOMEM);
179 
180  constraints->valid_hw_formats[0] = AV_PIX_FMT_AMF_SURFACE;
181  constraints->valid_hw_formats[1] = AV_PIX_FMT_NONE;
182 
183  return 0;
184 }
185 
186 static void amf_dummy_free(void *opaque, uint8_t *data)
187 {
188 
189 }
190 
191 static AVBufferRef *amf_pool_alloc(void *opaque, size_t size)
192 {
193  AVHWFramesContext *hwfc = (AVHWFramesContext *)opaque;
194  AVBufferRef *buf;
195 
197  if (!buf) {
198  av_log(hwfc, AV_LOG_ERROR, "Failed to create buffer for AMF context.\n");
199  return NULL;
200  }
201  return buf;
202 }
203 
205 {
206  int i;
207 
208  for (i = 0; i < FF_ARRAY_ELEMS(supported_formats); i++) {
209  if (ctx->sw_format == supported_formats[i])
210  break;
211  }
213  av_log(ctx, AV_LOG_ERROR, "Pixel format '%s' is not supported\n",
214  av_get_pix_fmt_name(ctx->sw_format));
215  return AVERROR(ENOSYS);
216  }
217 
219  av_buffer_pool_init2(sizeof(AMFSurface), ctx,
220  &amf_pool_alloc, NULL);
221 
222  return 0;
223 }
224 
225 
227 {
228  frame->buf[0] = av_buffer_pool_get(ctx->pool);
229  if (!frame->buf[0])
230  return AVERROR(ENOMEM);
231 
232  frame->data[0] = frame->buf[0]->data;
233  frame->format = AV_PIX_FMT_AMF_SURFACE;
234  frame->width = ctx->width;
235  frame->height = ctx->height;
236  return 0;
237 }
238 
241  enum AVPixelFormat **formats)
242 {
243  enum AVPixelFormat *fmts;
244  int i;
245 
247  if (!fmts)
248  return AVERROR(ENOMEM);
250  fmts[i] = supported_transfer_formats[i];
251 
252  *formats = fmts;
253 
254  return 0;
255 }
256 
257 static void amf_free_amfsurface(void *opaque, uint8_t *data)
258 {
259  if(!!data){
260  AMFSurface *surface = (AMFSurface*)(data);
261  surface->pVtbl->Release(surface);
262  }
263 }
264 
266  const AVFrame *src)
267 {
268  AMFSurface* surface = (AMFSurface*)dst->data[0];
269  AMFPlane *plane;
270  uint8_t *dst_data[4];
271  int dst_linesize[4];
272  int planes;
273  int i;
274  int res;
275  int w = FFMIN(dst->width, src->width);
276  int h = FFMIN(dst->height, src->height);
277 
278  if (!surface) {
279  AVHWDeviceContext *hwdev_ctx = ctx->device_ctx;
280  AVAMFDeviceContext *amf_device_ctx = (AVAMFDeviceContext *)hwdev_ctx->hwctx;
281  AMF_SURFACE_FORMAT format = av_av_to_amf_format(ctx->sw_format);
282  res = amf_device_ctx->context->pVtbl->AllocSurface(amf_device_ctx->context, AMF_MEMORY_HOST, format, dst->width, dst->height, &surface);
283  AMF_RETURN_IF_FALSE(ctx, res == AMF_OK, AVERROR(ENOMEM), "AllocSurface() failed with error %d\n", res);
284  dst->data[0] = (uint8_t *)surface;
285  dst->buf[1] = av_buffer_create((uint8_t *)surface, sizeof(surface),
287  NULL,
289  AMF_RETURN_IF_FALSE(ctx, !!dst->buf[1], AVERROR(ENOMEM), "av_buffer_create for amf surface failed.");
290  }
291 
292  planes = (int)surface->pVtbl->GetPlanesCount(surface);
293  av_assert0(planes < FF_ARRAY_ELEMS(dst_data));
294 
295  for (i = 0; i < planes; i++) {
296  plane = surface->pVtbl->GetPlaneAt(surface, i);
297  dst_data[i] = plane->pVtbl->GetNative(plane);
298  dst_linesize[i] = plane->pVtbl->GetHPitch(plane);
299  }
300  av_image_copy2(dst_data, dst_linesize,
301  src->data, src->linesize, src->format,
302  w, h);
303 
304  return 0;
305 }
306 
308  const AVFrame *src)
309 {
310  AMFSurface* surface = (AMFSurface*)src->data[0];
311  AMFPlane *plane;
312  uint8_t *src_data[4];
313  int src_linesize[4];
314  int planes;
315  int i;
316  int w = FFMIN(dst->width, src->width);
317  int h = FFMIN(dst->height, src->height);
318  int ret;
319 
320  ret = surface->pVtbl->Convert(surface, AMF_MEMORY_HOST);
321  AMF_RETURN_IF_FALSE(ctx, ret == AMF_OK, AVERROR_UNKNOWN, "Convert(amf::AMF_MEMORY_HOST) failed with error %d\n", AVERROR_UNKNOWN);
322 
323  planes = (int)surface->pVtbl->GetPlanesCount(surface);
324  av_assert0(planes < FF_ARRAY_ELEMS(src_data));
325 
326  for (i = 0; i < planes; i++) {
327  plane = surface->pVtbl->GetPlaneAt(surface, i);
328  src_data[i] = plane->pVtbl->GetNative(plane);
329  src_linesize[i] = plane->pVtbl->GetHPitch(plane);
330  }
331  av_image_copy2(dst->data, dst->linesize,
332  src_data, src_linesize, dst->format,
333  w, h);
334  return 0;
335 }
336 
337 
338 
339 static void amf_device_uninit(AVHWDeviceContext *device_ctx)
340 {
341  AVAMFDeviceContext *amf_ctx = device_ctx->hwctx;
342  AMF_RESULT res;
343  AMFTrace *trace;
344 
345  if (amf_ctx->context) {
346  amf_ctx->context->pVtbl->Terminate(amf_ctx->context);
347  amf_ctx->context->pVtbl->Release(amf_ctx->context);
348  amf_ctx->context = NULL;
349  }
350 
351  res = amf_ctx->factory->pVtbl->GetTrace(amf_ctx->factory, &trace);
352  if (res == AMF_OK) {
353  trace->pVtbl->UnregisterWriter(trace, FFMPEG_AMF_WRITER_ID);
354  }
355 
356  if(amf_ctx->library) {
357  dlclose(amf_ctx->library);
358  amf_ctx->library = NULL;
359  }
360  if (amf_ctx->trace_writer) {
361  amf_writer_free(amf_ctx->trace_writer);
362  }
363 
364  amf_ctx->version = 0;
365 }
366 
368 {
369  AVAMFDeviceContext *amf_ctx = ctx->hwctx;
370  AMFContext1 *context1 = NULL;
371  AMF_RESULT res;
372 
373 #ifdef _WIN32
374  res = amf_ctx->context->pVtbl->InitDX11(amf_ctx->context, NULL, AMF_DX11_1);
375  if (res == AMF_OK || res == AMF_ALREADY_INITIALIZED) {
376  av_log(ctx, AV_LOG_VERBOSE, "AMF initialisation succeeded via D3D11.\n");
377  } else {
378  res = amf_ctx->context->pVtbl->InitDX9(amf_ctx->context, NULL);
379  if (res == AMF_OK) {
380  av_log(ctx, AV_LOG_VERBOSE, "AMF initialisation succeeded via D3D9.\n");
381  } else {
382 #endif
383  AMFGuid guid = IID_AMFContext1();
384  res = amf_ctx->context->pVtbl->QueryInterface(amf_ctx->context, &guid, (void**)&context1);
385  AMF_RETURN_IF_FALSE(ctx, res == AMF_OK, AVERROR_UNKNOWN, "CreateContext1() failed with error %d\n", res);
386 
387  res = context1->pVtbl->InitVulkan(context1, NULL);
388  context1->pVtbl->Release(context1);
389  if (res != AMF_OK && res != AMF_ALREADY_INITIALIZED) {
390  if (res == AMF_NOT_SUPPORTED)
391  av_log(ctx, AV_LOG_ERROR, "AMF via Vulkan is not supported on the given device.\n");
392  else
393  av_log(ctx, AV_LOG_ERROR, "AMF failed to initialise on the given Vulkan device: %d.\n", res);
394  return AVERROR(ENOSYS);
395  }
396  av_log(ctx, AV_LOG_VERBOSE, "AMF initialisation succeeded via Vulkan.\n");
397 #ifdef _WIN32
398  }
399  }
400 #endif
401  return 0;
402 }
403 
404 static int amf_load_library(AVAMFDeviceContext* amf_ctx, void* avcl)
405 {
406  AMFInit_Fn init_fun;
407  AMFQueryVersion_Fn version_fun;
408  AMF_RESULT res;
409 
410  amf_ctx->library = dlopen(AMF_DLL_NAMEA, RTLD_NOW | RTLD_LOCAL);
411  AMF_RETURN_IF_FALSE(avcl, amf_ctx->library != NULL,
412  AVERROR_UNKNOWN, "DLL %s failed to open\n", AMF_DLL_NAMEA);
413 
414  init_fun = (AMFInit_Fn)dlsym(amf_ctx->library, AMF_INIT_FUNCTION_NAME);
415  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);
416 
417  version_fun = (AMFQueryVersion_Fn)dlsym(amf_ctx->library, AMF_QUERY_VERSION_FUNCTION_NAME);
418  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);
419 
420  res = version_fun(&amf_ctx->version);
421  AMF_RETURN_IF_FALSE(avcl, res == AMF_OK, AVERROR_UNKNOWN, "%s failed with error %d\n", AMF_QUERY_VERSION_FUNCTION_NAME, res);
422  res = init_fun(AMF_FULL_VERSION, &amf_ctx->factory);
423  AMF_RETURN_IF_FALSE(avcl, res == AMF_OK, AVERROR_UNKNOWN, "%s failed with error %d\n", AMF_INIT_FUNCTION_NAME, res);
424  return 0;
425 }
426 
427 static int amf_device_create(AVHWDeviceContext *device_ctx,
428  const char *device,
429  AVDictionary *opts, int flags)
430 {
431  AVAMFDeviceContext *ctx = device_ctx->hwctx;
432  AMFTrace *trace;
433  int ret;
434  if ((ret = amf_load_library(ctx, device_ctx)) == 0) {
435  ret = ctx->factory->pVtbl->GetTrace(ctx->factory, &trace);
436  if (ret == AMF_OK) {
437  int level_ff = av_log_get_level();
438  int level_amf = AMF_TRACE_TRACE;
439  amf_bool enable_log = true;
440  switch(level_ff)
441  {
442  case AV_LOG_QUIET:
443  level_amf = AMF_TRACE_ERROR;
444  enable_log = false;
445  break;
446  case AV_LOG_PANIC:
447  case AV_LOG_FATAL:
448  case AV_LOG_ERROR:
449  level_amf = AMF_TRACE_ERROR;
450  break;
451  case AV_LOG_WARNING:
452  case AV_LOG_INFO:
453  level_amf = AMF_TRACE_WARNING;
454  break;
455  case AV_LOG_VERBOSE:
456  level_amf = AMF_TRACE_INFO;
457  break;
458  case AV_LOG_DEBUG:
459  level_amf = AMF_TRACE_DEBUG;
460  break;
461  case AV_LOG_TRACE:
462  level_amf = AMF_TRACE_TRACE;
463  break;
464  }
465  if(ctx->version == AMF_MAKE_FULL_VERSION(1, 4, 35, 0)){// get around a bug in trace in AMF runtime driver 24.20
466  level_amf = AMF_TRACE_WARNING;
467  }
468 
469  trace->pVtbl->EnableWriter(trace, AMF_TRACE_WRITER_CONSOLE, 0);
470  trace->pVtbl->SetGlobalLevel(trace, level_amf);
471 
472  // connect AMF logger to av_log
473  ctx->trace_writer = amf_writer_alloc(device_ctx);
474  trace->pVtbl->RegisterWriter(trace, FFMPEG_AMF_WRITER_ID, (AMFTraceWriter*)ctx->trace_writer, 1);
475  trace->pVtbl->SetWriterLevel(trace, FFMPEG_AMF_WRITER_ID, level_amf);
476  trace->pVtbl->EnableWriter(trace, FFMPEG_AMF_WRITER_ID, enable_log);
477  trace->pVtbl->SetWriterLevel(trace, AMF_TRACE_WRITER_DEBUG_OUTPUT, level_amf);
478  trace->pVtbl->EnableWriter(trace, AMF_TRACE_WRITER_DEBUG_OUTPUT, enable_log);
479  }
480 
481 
482  ret = ctx->factory->pVtbl->CreateContext(ctx->factory, &ctx->context);
483  if (ret == AMF_OK)
484  return 0;
485  av_log(device_ctx, AV_LOG_ERROR, "CreateContext() failed with error %d.\n", ret);
486  }
487  amf_device_uninit(device_ctx);
488  return ret;
489 }
490 
491 #if CONFIG_DXVA2
492 static int amf_init_from_dxva2_device(AVAMFDeviceContext * amf_ctx, AVDXVA2DeviceContext *hwctx)
493 {
494  IDirect3DDevice9 *device;
495  HANDLE device_handle;
496  HRESULT hr;
497  AMF_RESULT res;
498  int ret;
499 
500  hr = IDirect3DDeviceManager9_OpenDeviceHandle(hwctx->devmgr, &device_handle);
501  if (FAILED(hr)) {
502  av_log(hwctx, AV_LOG_ERROR, "Failed to open device handle for Direct3D9 device: %lx.\n", (unsigned long)hr);
503  return AVERROR_EXTERNAL;
504  }
505 
506  hr = IDirect3DDeviceManager9_LockDevice(hwctx->devmgr, device_handle, &device, FALSE);
507  if (SUCCEEDED(hr)) {
508  IDirect3DDeviceManager9_UnlockDevice(hwctx->devmgr, device_handle, FALSE);
509  ret = 0;
510  } else {
511  av_log(hwctx, AV_LOG_ERROR, "Failed to lock device handle for Direct3D9 device: %lx.\n", (unsigned long)hr);
513  }
514 
515 
516  IDirect3DDeviceManager9_CloseDeviceHandle(hwctx->devmgr, device_handle);
517 
518  if (ret < 0)
519  return ret;
520 
521  res = amf_ctx->context->pVtbl->InitDX9(amf_ctx->context, device);
522 
523  IDirect3DDevice9_Release(device);
524 
525  if (res != AMF_OK && res != AMF_ALREADY_INITIALIZED) {
526  if (res == AMF_NOT_SUPPORTED)
527  av_log(hwctx, AV_LOG_ERROR, "AMF via D3D9 is not supported on the given device.\n");
528  else
529  av_log(hwctx, AV_LOG_ERROR, "AMF failed to initialise on given D3D9 device: %d.\n", res);
530  return AVERROR(ENODEV);
531  }
532  return 0;
533 }
534 #endif
535 
536 #if CONFIG_D3D11VA
537 static int amf_init_from_d3d11_device(AVAMFDeviceContext* amf_ctx, AVD3D11VADeviceContext *hwctx)
538 {
539  AMF_RESULT res;
540  res = amf_ctx->context->pVtbl->InitDX11(amf_ctx->context, hwctx->device, AMF_DX11_1);
541  if (res != AMF_OK && res != AMF_ALREADY_INITIALIZED) {
542  if (res == AMF_NOT_SUPPORTED)
543  av_log(hwctx, AV_LOG_ERROR, "AMF via D3D11 is not supported on the given device.\n");
544  else
545  av_log(hwctx, AV_LOG_ERROR, "AMF failed to initialise on the given D3D11 device: %d.\n", res);
546  return AVERROR(ENODEV);
547  }
548  return 0;
549 }
550 #endif
551 
552 static int amf_device_derive(AVHWDeviceContext *device_ctx,
553  AVHWDeviceContext *child_device_ctx, AVDictionary *opts,
554  int flags)
555 {
556 #if CONFIG_DXVA2 || CONFIG_D3D11VA
557  AVAMFDeviceContext *amf_ctx = device_ctx->hwctx;
558 #endif
559  int ret;
560 
561  ret = amf_device_create(device_ctx, "", opts, flags);
562  if(ret < 0)
563  return ret;
564 
565  switch (child_device_ctx->type) {
566 
567 #if CONFIG_DXVA2
568  case AV_HWDEVICE_TYPE_DXVA2: {
569  AVDXVA2DeviceContext *child_device_hwctx = child_device_ctx->hwctx;
570  return amf_init_from_dxva2_device(amf_ctx, child_device_hwctx);
571  }
572  break;
573 #endif
574 
575 #if CONFIG_D3D11VA
577  AVD3D11VADeviceContext *child_device_hwctx = child_device_ctx->hwctx;
578  return amf_init_from_d3d11_device(amf_ctx, child_device_hwctx);
579  }
580  break;
581 #endif
582  default: {
583  av_log(child_device_ctx, AV_LOG_ERROR, "AMF initialisation from a %s device is not supported.\n",
584  av_hwdevice_get_type_name(child_device_ctx->type));
585  return AVERROR(ENOSYS);
586  }
587  }
588  return 0;
589 }
590 
593  .name = "AMF",
594 
595  .device_hwctx_size = sizeof(AVAMFDeviceContext),
596  .frames_hwctx_size = sizeof(AMFFramesContext),
597 
598  .device_create = amf_device_create,
599  .device_derive = amf_device_derive,
600  .device_init = amf_device_init,
601  .device_uninit = amf_device_uninit,
602  .frames_get_constraints = amf_frames_get_constraints,
603  .frames_init = amf_frames_init,
604  .frames_get_buffer = amf_get_buffer,
605  .transfer_get_formats = amf_transfer_get_formats,
606  .transfer_data_to = amf_transfer_data_to,
607  .transfer_data_from = amf_transfer_data_from,
608 
609  .pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_AMF_SURFACE, AV_PIX_FMT_NONE },
610 };
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:186
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:427
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:34
AMF_RETURN_IF_FALSE
#define AMF_RETURN_IF_FALSE(avctx, exp, ret_value,...)
Error handling helper.
Definition: amfenc.h:162
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
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:127
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:116
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:239
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:161
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:367
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:265
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:442
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:191
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:226
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
hwcontext_dxva2.h
amf_free_amfsurface
static void amf_free_amfsurface(void *opaque, uint8_t *data)
Definition: hwcontext_amf.c:257
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:591
amf_device_uninit
static void amf_device_uninit(AVHWDeviceContext *device_ctx)
Definition: hwcontext_amf.c:339
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:204
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:31
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:307
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:552
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:138
planes
static const struct @473 planes[]
hwcontext_amf_internal.h
amf_load_library
static int amf_load_library(AVAMFDeviceContext *amf_ctx, void *avcl)
Definition: hwcontext_amf.c:404
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:568
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_freep
#define av_freep(p)
Definition: tableprint_vlc.h:34
imgutils.h
flags
#define flags(name, subs,...)
Definition: cbs_av1.c:482
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:152
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:3168