FFmpeg  4.4.6
hwcontext_d3d11va.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 "config.h"
20 
21 #include <windows.h>
22 
23 #define COBJMACROS
24 
25 #include <initguid.h>
26 #include <d3d11.h>
27 #include <dxgi1_2.h>
28 
29 #if HAVE_DXGIDEBUG_H
30 #include <dxgidebug.h>
31 #endif
32 
33 #include "avassert.h"
34 #include "common.h"
35 #include "hwcontext.h"
36 #include "hwcontext_d3d11va.h"
37 #include "hwcontext_internal.h"
38 #include "imgutils.h"
39 #include "pixdesc.h"
40 #include "pixfmt.h"
41 #include "thread.h"
42 #include "compat/w32dlfcn.h"
43 
44 typedef HRESULT(WINAPI *PFN_CREATE_DXGI_FACTORY)(REFIID riid, void **ppFactory);
45 
47 
49 static PFN_D3D11_CREATE_DEVICE mD3D11CreateDevice;
50 
51 static av_cold void load_functions(void)
52 {
53 #if !HAVE_UWP
54  // We let these "leak" - this is fine, as unloading has no great benefit, and
55  // Windows will mark a DLL as loaded forever if its internal refcount overflows
56  // from too many LoadLibrary calls.
57  HANDLE d3dlib, dxgilib;
58 
59  d3dlib = dlopen("d3d11.dll", 0);
60  dxgilib = dlopen("dxgi.dll", 0);
61  if (!d3dlib || !dxgilib)
62  return;
63 
64  mD3D11CreateDevice = (PFN_D3D11_CREATE_DEVICE) GetProcAddress(d3dlib, "D3D11CreateDevice");
65  mCreateDXGIFactory = (PFN_CREATE_DXGI_FACTORY) GetProcAddress(dxgilib, "CreateDXGIFactory");
66 #else
67  // In UWP (which lacks LoadLibrary), CreateDXGIFactory isn't available,
68  // only CreateDXGIFactory1
69  mD3D11CreateDevice = (PFN_D3D11_CREATE_DEVICE) D3D11CreateDevice;
70  mCreateDXGIFactory = (PFN_CREATE_DXGI_FACTORY) CreateDXGIFactory1;
71 #endif
72 }
73 
74 typedef struct D3D11VAFramesContext {
76 
77  DXGI_FORMAT format;
78 
79  ID3D11Texture2D *staging_texture;
81 
82 static const struct {
83  DXGI_FORMAT d3d_format;
85 } supported_formats[] = {
86  { DXGI_FORMAT_NV12, AV_PIX_FMT_NV12 },
87  { DXGI_FORMAT_P010, AV_PIX_FMT_P010 },
88  // Special opaque formats. The pix_fmt is merely a place holder, as the
89  // opaque format cannot be accessed directly.
90  { DXGI_FORMAT_420_OPAQUE, AV_PIX_FMT_YUV420P },
91 };
92 
93 static void d3d11va_default_lock(void *ctx)
94 {
95  WaitForSingleObjectEx(ctx, INFINITE, FALSE);
96 }
97 
98 static void d3d11va_default_unlock(void *ctx)
99 {
100  ReleaseMutex(ctx);
101 }
102 
104 {
105  AVD3D11VAFramesContext *frames_hwctx = ctx->hwctx;
107 
108  if (frames_hwctx->texture)
109  ID3D11Texture2D_Release(frames_hwctx->texture);
110  frames_hwctx->texture = NULL;
111 
112  if (s->staging_texture)
113  ID3D11Texture2D_Release(s->staging_texture);
114  s->staging_texture = NULL;
115 }
116 
118  const void *hwconfig,
119  AVHWFramesConstraints *constraints)
120 {
121  AVD3D11VADeviceContext *device_hwctx = ctx->hwctx;
122  int nb_sw_formats = 0;
123  HRESULT hr;
124  int i;
125 
127  sizeof(*constraints->valid_sw_formats));
128  if (!constraints->valid_sw_formats)
129  return AVERROR(ENOMEM);
130 
131  for (i = 0; i < FF_ARRAY_ELEMS(supported_formats); i++) {
132  UINT format_support = 0;
133  hr = ID3D11Device_CheckFormatSupport(device_hwctx->device, supported_formats[i].d3d_format, &format_support);
134  if (SUCCEEDED(hr) && (format_support & D3D11_FORMAT_SUPPORT_TEXTURE2D))
135  constraints->valid_sw_formats[nb_sw_formats++] = supported_formats[i].pix_fmt;
136  }
137  constraints->valid_sw_formats[nb_sw_formats] = AV_PIX_FMT_NONE;
138 
139  constraints->valid_hw_formats = av_malloc_array(2, sizeof(*constraints->valid_hw_formats));
140  if (!constraints->valid_hw_formats)
141  return AVERROR(ENOMEM);
142 
143  constraints->valid_hw_formats[0] = AV_PIX_FMT_D3D11;
144  constraints->valid_hw_formats[1] = AV_PIX_FMT_NONE;
145 
146  return 0;
147 }
148 
149 static void free_texture(void *opaque, uint8_t *data)
150 {
151  ID3D11Texture2D_Release((ID3D11Texture2D *)opaque);
152  av_free(data);
153 }
154 
155 static AVBufferRef *wrap_texture_buf(ID3D11Texture2D *tex, int index)
156 {
157  AVBufferRef *buf;
159  if (!desc) {
160  ID3D11Texture2D_Release(tex);
161  return NULL;
162  }
163 
164  desc->texture = tex;
165  desc->index = index;
166 
167  buf = av_buffer_create((uint8_t *)desc, sizeof(*desc), free_texture, tex, 0);
168  if (!buf) {
169  ID3D11Texture2D_Release(tex);
170  av_free(desc);
171  return NULL;
172  }
173 
174  return buf;
175 }
176 
178 {
180  AVD3D11VAFramesContext *hwctx = ctx->hwctx;
181  AVD3D11VADeviceContext *device_hwctx = ctx->device_ctx->hwctx;
182  HRESULT hr;
183  ID3D11Texture2D *tex;
184  D3D11_TEXTURE2D_DESC texDesc = {
185  .Width = ctx->width,
186  .Height = ctx->height,
187  .MipLevels = 1,
188  .Format = s->format,
189  .SampleDesc = { .Count = 1 },
190  .ArraySize = 1,
191  .Usage = D3D11_USAGE_DEFAULT,
192  .BindFlags = hwctx->BindFlags,
193  .MiscFlags = hwctx->MiscFlags,
194  };
195 
196  hr = ID3D11Device_CreateTexture2D(device_hwctx->device, &texDesc, NULL, &tex);
197  if (FAILED(hr)) {
198  av_log(ctx, AV_LOG_ERROR, "Could not create the texture (%lx)\n", (long)hr);
199  return NULL;
200  }
201 
202  return wrap_texture_buf(tex, 0);
203 }
204 
206 {
209  AVD3D11VAFramesContext *hwctx = ctx->hwctx;
210  D3D11_TEXTURE2D_DESC texDesc;
211 
212  if (!hwctx->texture)
213  return d3d11va_alloc_single(ctx);
214 
215  ID3D11Texture2D_GetDesc(hwctx->texture, &texDesc);
216 
217  if (s->nb_surfaces_used >= texDesc.ArraySize) {
218  av_log(ctx, AV_LOG_ERROR, "Static surface pool size exceeded.\n");
219  return NULL;
220  }
221 
222  ID3D11Texture2D_AddRef(hwctx->texture);
223  return wrap_texture_buf(hwctx->texture, s->nb_surfaces_used++);
224 }
225 
227 {
228  AVD3D11VAFramesContext *hwctx = ctx->hwctx;
229  AVD3D11VADeviceContext *device_hwctx = ctx->device_ctx->hwctx;
231 
232  int i;
233  HRESULT hr;
234  D3D11_TEXTURE2D_DESC texDesc;
235 
236  for (i = 0; i < FF_ARRAY_ELEMS(supported_formats); i++) {
237  if (ctx->sw_format == supported_formats[i].pix_fmt) {
238  s->format = supported_formats[i].d3d_format;
239  break;
240  }
241  }
243  av_log(ctx, AV_LOG_ERROR, "Unsupported pixel format: %s\n",
244  av_get_pix_fmt_name(ctx->sw_format));
245  return AVERROR(EINVAL);
246  }
247 
248  texDesc = (D3D11_TEXTURE2D_DESC){
249  .Width = ctx->width,
250  .Height = ctx->height,
251  .MipLevels = 1,
252  .Format = s->format,
253  .SampleDesc = { .Count = 1 },
254  .ArraySize = ctx->initial_pool_size,
255  .Usage = D3D11_USAGE_DEFAULT,
256  .BindFlags = hwctx->BindFlags,
257  .MiscFlags = hwctx->MiscFlags,
258  };
259 
260  if (hwctx->texture) {
261  D3D11_TEXTURE2D_DESC texDesc2;
262  ID3D11Texture2D_GetDesc(hwctx->texture, &texDesc2);
263 
264  if (texDesc.Width != texDesc2.Width ||
265  texDesc.Height != texDesc2.Height ||
266  texDesc.Format != texDesc2.Format) {
267  av_log(ctx, AV_LOG_ERROR, "User-provided texture has mismatching parameters\n");
268  return AVERROR(EINVAL);
269  }
270  } else if (texDesc.ArraySize > 0) {
271  hr = ID3D11Device_CreateTexture2D(device_hwctx->device, &texDesc, NULL, &hwctx->texture);
272  if (FAILED(hr)) {
273  av_log(ctx, AV_LOG_ERROR, "Could not create the texture (%lx)\n", (long)hr);
274  return AVERROR_UNKNOWN;
275  }
276  }
277 
278  ctx->internal->pool_internal = av_buffer_pool_init2(sizeof(AVD3D11FrameDescriptor),
280  if (!ctx->internal->pool_internal)
281  return AVERROR(ENOMEM);
282 
283  return 0;
284 }
285 
287 {
289 
290  frame->buf[0] = av_buffer_pool_get(ctx->pool);
291  if (!frame->buf[0])
292  return AVERROR(ENOMEM);
293 
295 
296  frame->data[0] = (uint8_t *)desc->texture;
297  frame->data[1] = (uint8_t *)desc->index;
299  frame->width = ctx->width;
300  frame->height = ctx->height;
301 
302  return 0;
303 }
304 
307  enum AVPixelFormat **formats)
308 {
310  enum AVPixelFormat *fmts;
311 
312  fmts = av_malloc_array(2, sizeof(*fmts));
313  if (!fmts)
314  return AVERROR(ENOMEM);
315 
316  fmts[0] = ctx->sw_format;
317  fmts[1] = AV_PIX_FMT_NONE;
318 
319  // Don't signal support for opaque formats. Actual access would fail.
320  if (s->format == DXGI_FORMAT_420_OPAQUE)
321  fmts[0] = AV_PIX_FMT_NONE;
322 
323  *formats = fmts;
324 
325  return 0;
326 }
327 
329 {
330  AVD3D11VADeviceContext *device_hwctx = ctx->device_ctx->hwctx;
332  HRESULT hr;
333  D3D11_TEXTURE2D_DESC texDesc = {
334  .Width = ctx->width,
335  .Height = ctx->height,
336  .MipLevels = 1,
337  .Format = s->format,
338  .SampleDesc = { .Count = 1 },
339  .ArraySize = 1,
340  .Usage = D3D11_USAGE_STAGING,
341  .CPUAccessFlags = D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE,
342  };
343 
344  hr = ID3D11Device_CreateTexture2D(device_hwctx->device, &texDesc, NULL, &s->staging_texture);
345  if (FAILED(hr)) {
346  av_log(ctx, AV_LOG_ERROR, "Could not create the staging texture (%lx)\n", (long)hr);
347  return AVERROR_UNKNOWN;
348  }
349 
350  return 0;
351 }
352 
353 static void fill_texture_ptrs(uint8_t *data[4], int linesize[4],
355  D3D11_TEXTURE2D_DESC *desc,
356  D3D11_MAPPED_SUBRESOURCE *map)
357 {
358  int i;
359 
360  for (i = 0; i < 4; i++)
361  linesize[i] = map->RowPitch;
362 
363  av_image_fill_pointers(data, ctx->sw_format, desc->Height,
364  (uint8_t*)map->pData, linesize);
365 }
366 
368  const AVFrame *src)
369 {
370  AVD3D11VADeviceContext *device_hwctx = ctx->device_ctx->hwctx;
372  int download = src->format == AV_PIX_FMT_D3D11;
373  const AVFrame *frame = download ? src : dst;
374  const AVFrame *other = download ? dst : src;
375  // (The interface types are compatible.)
376  ID3D11Resource *texture = (ID3D11Resource *)(ID3D11Texture2D *)frame->data[0];
377  int index = (intptr_t)frame->data[1];
378  ID3D11Resource *staging;
379  int w = FFMIN(dst->width, src->width);
380  int h = FFMIN(dst->height, src->height);
381  uint8_t *map_data[4];
382  int map_linesize[4];
383  D3D11_TEXTURE2D_DESC desc;
384  D3D11_MAPPED_SUBRESOURCE map;
385  HRESULT hr;
386 
387  if (frame->hw_frames_ctx->data != (uint8_t *)ctx || other->format != ctx->sw_format)
388  return AVERROR(EINVAL);
389 
390  device_hwctx->lock(device_hwctx->lock_ctx);
391 
392  if (!s->staging_texture) {
394  if (res < 0)
395  return res;
396  }
397 
398  staging = (ID3D11Resource *)s->staging_texture;
399 
400  ID3D11Texture2D_GetDesc(s->staging_texture, &desc);
401 
402  if (download) {
403  ID3D11DeviceContext_CopySubresourceRegion(device_hwctx->device_context,
404  staging, 0, 0, 0, 0,
405  texture, index, NULL);
406 
407  hr = ID3D11DeviceContext_Map(device_hwctx->device_context,
408  staging, 0, D3D11_MAP_READ, 0, &map);
409  if (FAILED(hr))
410  goto map_failed;
411 
412  fill_texture_ptrs(map_data, map_linesize, ctx, &desc, &map);
413 
414  av_image_copy(dst->data, dst->linesize, (const uint8_t **)map_data, map_linesize,
415  ctx->sw_format, w, h);
416 
417  ID3D11DeviceContext_Unmap(device_hwctx->device_context, staging, 0);
418  } else {
419  hr = ID3D11DeviceContext_Map(device_hwctx->device_context,
420  staging, 0, D3D11_MAP_WRITE, 0, &map);
421  if (FAILED(hr))
422  goto map_failed;
423 
424  fill_texture_ptrs(map_data, map_linesize, ctx, &desc, &map);
425 
426  av_image_copy(map_data, map_linesize, (const uint8_t **)src->data, src->linesize,
427  ctx->sw_format, w, h);
428 
429  ID3D11DeviceContext_Unmap(device_hwctx->device_context, staging, 0);
430 
431  ID3D11DeviceContext_CopySubresourceRegion(device_hwctx->device_context,
432  texture, index, 0, 0, 0,
433  staging, 0, NULL);
434  }
435 
436  device_hwctx->unlock(device_hwctx->lock_ctx);
437  return 0;
438 
439 map_failed:
440  av_log(ctx, AV_LOG_ERROR, "Unable to lock D3D11VA surface (%lx)\n", (long)hr);
441  device_hwctx->unlock(device_hwctx->lock_ctx);
442  return AVERROR_UNKNOWN;
443 }
444 
446 {
447  AVD3D11VADeviceContext *device_hwctx = hwdev->hwctx;
448  HRESULT hr;
449 
450  if (!device_hwctx->lock) {
451  device_hwctx->lock_ctx = CreateMutex(NULL, 0, NULL);
452  if (device_hwctx->lock_ctx == INVALID_HANDLE_VALUE) {
453  av_log(NULL, AV_LOG_ERROR, "Failed to create a mutex\n");
454  return AVERROR(EINVAL);
455  }
456  device_hwctx->lock = d3d11va_default_lock;
457  device_hwctx->unlock = d3d11va_default_unlock;
458  }
459 
460  if (!device_hwctx->device_context) {
461  ID3D11Device_GetImmediateContext(device_hwctx->device, &device_hwctx->device_context);
462  if (!device_hwctx->device_context)
463  return AVERROR_UNKNOWN;
464  }
465 
466  if (!device_hwctx->video_device) {
467  hr = ID3D11DeviceContext_QueryInterface(device_hwctx->device, &IID_ID3D11VideoDevice,
468  (void **)&device_hwctx->video_device);
469  if (FAILED(hr))
470  return AVERROR_UNKNOWN;
471  }
472 
473  if (!device_hwctx->video_context) {
474  hr = ID3D11DeviceContext_QueryInterface(device_hwctx->device_context, &IID_ID3D11VideoContext,
475  (void **)&device_hwctx->video_context);
476  if (FAILED(hr))
477  return AVERROR_UNKNOWN;
478  }
479 
480  return 0;
481 }
482 
484 {
485  AVD3D11VADeviceContext *device_hwctx = hwdev->hwctx;
486 
487  if (device_hwctx->device) {
488  ID3D11Device_Release(device_hwctx->device);
489  device_hwctx->device = NULL;
490  }
491 
492  if (device_hwctx->device_context) {
493  ID3D11DeviceContext_Release(device_hwctx->device_context);
494  device_hwctx->device_context = NULL;
495  }
496 
497  if (device_hwctx->video_device) {
498  ID3D11VideoDevice_Release(device_hwctx->video_device);
499  device_hwctx->video_device = NULL;
500  }
501 
502  if (device_hwctx->video_context) {
503  ID3D11VideoContext_Release(device_hwctx->video_context);
504  device_hwctx->video_context = NULL;
505  }
506 
507  if (device_hwctx->lock == d3d11va_default_lock) {
508  CloseHandle(device_hwctx->lock_ctx);
509  device_hwctx->lock_ctx = INVALID_HANDLE_VALUE;
510  device_hwctx->lock = NULL;
511  }
512 }
513 
514 static int d3d11va_device_create(AVHWDeviceContext *ctx, const char *device,
515  AVDictionary *opts, int flags)
516 {
517  AVD3D11VADeviceContext *device_hwctx = ctx->hwctx;
518 
519  HRESULT hr;
520  IDXGIAdapter *pAdapter = NULL;
521  ID3D10Multithread *pMultithread;
522  UINT creationFlags = D3D11_CREATE_DEVICE_VIDEO_SUPPORT;
523  int is_debug = !!av_dict_get(opts, "debug", NULL, 0);
524  int ret;
525 
526  // (On UWP we can't check this.)
527 #if !HAVE_UWP
528  if (!LoadLibrary("d3d11_1sdklayers.dll"))
529  is_debug = 0;
530 #endif
531 
532  if (is_debug)
533  creationFlags |= D3D11_CREATE_DEVICE_DEBUG;
534 
535  if ((ret = ff_thread_once(&functions_loaded, load_functions)) != 0)
536  return AVERROR_UNKNOWN;
538  av_log(ctx, AV_LOG_ERROR, "Failed to load D3D11 library or its functions\n");
539  return AVERROR_UNKNOWN;
540  }
541 
542  if (device) {
543  IDXGIFactory2 *pDXGIFactory;
544  hr = mCreateDXGIFactory(&IID_IDXGIFactory2, (void **)&pDXGIFactory);
545  if (SUCCEEDED(hr)) {
546  int adapter = atoi(device);
547  if (FAILED(IDXGIFactory2_EnumAdapters(pDXGIFactory, adapter, &pAdapter)))
548  pAdapter = NULL;
549  IDXGIFactory2_Release(pDXGIFactory);
550  }
551  }
552 
553  if (pAdapter) {
554  DXGI_ADAPTER_DESC desc;
555  hr = IDXGIAdapter2_GetDesc(pAdapter, &desc);
556  if (!FAILED(hr)) {
557  av_log(ctx, AV_LOG_INFO, "Using device %04x:%04x (%ls).\n",
558  desc.VendorId, desc.DeviceId, desc.Description);
559  }
560  }
561 
562  hr = mD3D11CreateDevice(pAdapter, pAdapter ? D3D_DRIVER_TYPE_UNKNOWN : D3D_DRIVER_TYPE_HARDWARE, NULL, creationFlags, NULL, 0,
563  D3D11_SDK_VERSION, &device_hwctx->device, NULL, NULL);
564  if (pAdapter)
565  IDXGIAdapter_Release(pAdapter);
566  if (FAILED(hr)) {
567  av_log(ctx, AV_LOG_ERROR, "Failed to create Direct3D device (%lx)\n", (long)hr);
568  return AVERROR_UNKNOWN;
569  }
570 
571  hr = ID3D11Device_QueryInterface(device_hwctx->device, &IID_ID3D10Multithread, (void **)&pMultithread);
572  if (SUCCEEDED(hr)) {
573  ID3D10Multithread_SetMultithreadProtected(pMultithread, TRUE);
574  ID3D10Multithread_Release(pMultithread);
575  }
576 
577 #if !HAVE_UWP && HAVE_DXGIDEBUG_H
578  if (is_debug) {
579  HANDLE dxgidebug_dll = LoadLibrary("dxgidebug.dll");
580  if (dxgidebug_dll) {
581  HRESULT (WINAPI * pf_DXGIGetDebugInterface)(const GUID *riid, void **ppDebug)
582  = (void *)GetProcAddress(dxgidebug_dll, "DXGIGetDebugInterface");
583  if (pf_DXGIGetDebugInterface) {
584  IDXGIDebug *dxgi_debug = NULL;
585  hr = pf_DXGIGetDebugInterface(&IID_IDXGIDebug, (void**)&dxgi_debug);
586  if (SUCCEEDED(hr) && dxgi_debug)
587  IDXGIDebug_ReportLiveObjects(dxgi_debug, DXGI_DEBUG_ALL, DXGI_DEBUG_RLO_ALL);
588  }
589  }
590  }
591 #endif
592 
593  return 0;
594 }
595 
598  .name = "D3D11VA",
599 
600  .device_hwctx_size = sizeof(AVD3D11VADeviceContext),
601  .frames_hwctx_size = sizeof(AVD3D11VAFramesContext),
602  .frames_priv_size = sizeof(D3D11VAFramesContext),
603 
604  .device_create = d3d11va_device_create,
606  .device_uninit = d3d11va_device_uninit,
607  .frames_get_constraints = d3d11va_frames_get_constraints,
608  .frames_init = d3d11va_frames_init,
609  .frames_uninit = d3d11va_frames_uninit,
610  .frames_get_buffer = d3d11va_get_buffer,
611  .transfer_get_formats = d3d11va_transfer_get_formats,
612  .transfer_data_to = d3d11va_transfer_data,
613  .transfer_data_from = d3d11va_transfer_data,
614 
616 };
#define av_cold
Definition: attributes.h:88
uint8_t
simple assert() macros that are a bit more flexible than ISO C assert().
#define flags(name, subs,...)
Definition: cbs_av1.c:572
#define s(width, name)
Definition: cbs_vp9.c:257
common internal and external API header
#define FFMIN(a, b)
Definition: common.h:105
#define NULL
Definition: coverity.c:32
static AVFrame * frame
AVBufferRef * av_buffer_create(uint8_t *data, buffer_size_t size, void(*free)(void *opaque, uint8_t *data), void *opaque, int flags)
Create an AVBuffer from an existing array.
Definition: buffer.c:29
AVBufferRef * av_buffer_pool_get(AVBufferPool *pool)
Allocate a new AVBuffer, reusing an old buffer from the pool when available.
Definition: buffer.c:379
AVBufferPool * av_buffer_pool_init2(buffer_size_t size, void *opaque, AVBufferRef *(*alloc)(void *opaque, buffer_size_t size), void(*pool_free)(void *opaque))
Allocate and initialize a buffer pool with a more complex allocator.
Definition: buffer.c:245
AVDictionaryEntry * av_dict_get(const AVDictionary *m, const char *key, const AVDictionaryEntry *prev, int flags)
Get a dictionary entry with matching key.
Definition: dict.c:40
#define AVERROR_UNKNOWN
Unknown error, typically from an external library.
Definition: error.h:71
#define AVERROR(e)
Definition: error.h:43
#define AV_LOG_INFO
Standard information.
Definition: log.h:205
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:194
void * av_mallocz(size_t size)
Allocate a memory block with alignment suitable for all memory accesses (including vectors if availab...
Definition: mem.c:237
int av_image_fill_pointers(uint8_t *data[4], enum AVPixelFormat pix_fmt, int height, uint8_t *ptr, const int linesizes[4])
Fill plane data pointers for an image with pixel format pix_fmt and height height.
Definition: imgutils.c:146
void av_image_copy(uint8_t *dst_data[4], int dst_linesizes[4], const uint8_t *src_data[4], const int src_linesizes[4], enum AVPixelFormat pix_fmt, int width, int height)
Copy image in src_data to dst_data.
Definition: imgutils.c:422
int index
Definition: gxfenc.c:89
AVHWFrameTransferDirection
Definition: hwcontext.h:415
@ AV_HWDEVICE_TYPE_D3D11VA
Definition: hwcontext.h:35
static void d3d11va_default_lock(void *ctx)
static const struct @298 supported_formats[]
static void free_texture(void *opaque, uint8_t *data)
static int d3d11va_get_buffer(AVHWFramesContext *ctx, AVFrame *frame)
static int d3d11va_device_init(AVHWDeviceContext *hwdev)
static int d3d11va_create_staging_texture(AVHWFramesContext *ctx)
static PFN_D3D11_CREATE_DEVICE mD3D11CreateDevice
static int d3d11va_device_create(AVHWDeviceContext *ctx, const char *device, AVDictionary *opts, int flags)
static av_cold void load_functions(void)
static int d3d11va_transfer_data(AVHWFramesContext *ctx, AVFrame *dst, const AVFrame *src)
static int d3d11va_frames_init(AVHWFramesContext *ctx)
enum AVPixelFormat pix_fmt
HRESULT(WINAPI * PFN_CREATE_DXGI_FACTORY)(REFIID riid, void **ppFactory)
DXGI_FORMAT d3d_format
static AVBufferRef * d3d11va_alloc_single(AVHWFramesContext *ctx)
static void fill_texture_ptrs(uint8_t *data[4], int linesize[4], AVHWFramesContext *ctx, D3D11_TEXTURE2D_DESC *desc, D3D11_MAPPED_SUBRESOURCE *map)
static AVBufferRef * wrap_texture_buf(ID3D11Texture2D *tex, int index)
static AVOnce functions_loaded
static void d3d11va_default_unlock(void *ctx)
static AVBufferRef * d3d11va_pool_alloc(void *opaque, buffer_size_t size)
static void d3d11va_frames_uninit(AVHWFramesContext *ctx)
static int d3d11va_frames_get_constraints(AVHWDeviceContext *ctx, const void *hwconfig, AVHWFramesConstraints *constraints)
const HWContextType ff_hwcontext_type_d3d11va
static PFN_CREATE_DXGI_FACTORY mCreateDXGIFactory
static int d3d11va_transfer_get_formats(AVHWFramesContext *ctx, enum AVHWFrameTransferDirection dir, enum AVPixelFormat **formats)
static void d3d11va_device_uninit(AVHWDeviceContext *hwdev)
An API-specific header for AV_HWDEVICE_TYPE_D3D11VA.
const VDPAUPixFmtMap * map
misc image utilities
int i
Definition: input.c:407
int buffer_size_t
Definition: internal.h:306
#define AVOnce
Definition: thread.h:172
static int ff_thread_once(char *control, void(*routine)(void))
Definition: thread.h:175
#define AV_ONCE_INIT
Definition: thread.h:173
static enum AVPixelFormat pix_fmts[]
Definition: libkvazaar.c:309
const char * desc
Definition: libsvtav1.c:79
uint8_t w
Definition: llviddspenc.c:39
const char data[16]
Definition: mxf.c:142
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:2489
pixel format definitions
#define AV_PIX_FMT_P010
Definition: pixfmt.h:448
AVPixelFormat
Pixel format.
Definition: pixfmt.h:64
@ 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
@ AV_PIX_FMT_NONE
Definition: pixfmt.h:65
@ AV_PIX_FMT_YUV420P
planar YUV 4:2:0, 12bpp, (1 Cr & Cb sample per 2x2 Y samples)
Definition: pixfmt.h:66
@ AV_PIX_FMT_D3D11
Hardware surfaces for Direct3D11.
Definition: pixfmt.h:313
formats
Definition: signature.h:48
#define FF_ARRAY_ELEMS(a)
A reference to a data buffer.
Definition: buffer.h:84
uint8_t * data
The data buffer.
Definition: buffer.h:92
D3D11 frame descriptor for pool allocation.
This struct is allocated as AVHWDeviceContext.hwctx.
void(* lock)(void *lock_ctx)
Callbacks for locking.
void(* unlock)(void *lock_ctx)
ID3D11VideoContext * video_context
If unset, this will be set from the device_context field on init.
ID3D11Device * device
Device used for texture creation and access.
ID3D11DeviceContext * device_context
If unset, this will be set from the device field on init.
ID3D11VideoDevice * video_device
If unset, this will be set from the device field on init.
This struct is allocated as AVHWFramesContext.hwctx.
UINT MiscFlags
D3D11_TEXTURE2D_DESC.MiscFlags used for texture creation.
ID3D11Texture2D * texture
The canonical texture used for pool allocation.
UINT BindFlags
D3D11_TEXTURE2D_DESC.BindFlags used for texture creation.
AVFormatInternal * internal
An opaque field for libavformat internal usage.
Definition: avformat.h:1699
This structure describes decoded (raw) audio or video data.
Definition: frame.h:318
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition: frame.h:332
int width
Definition: frame.h:376
AVBufferRef * hw_frames_ctx
For hwaccel-format frames, this should be a reference to the AVHWFramesContext describing the frame.
Definition: frame.h:657
int height
Definition: frame.h:376
AVBufferRef * buf[AV_NUM_DATA_POINTERS]
AVBuffer references backing the data for this frame.
Definition: frame.h:509
int linesize[AV_NUM_DATA_POINTERS]
For video, size in bytes of each picture line.
Definition: frame.h:349
int format
format of the frame, -1 if unknown or unset Values correspond to enum AVPixelFormat for video frames,...
Definition: frame.h:391
This struct aggregates all the (hardware/vendor-specific) "high-level" state, i.e.
Definition: hwcontext.h:61
void * hwctx
The format-specific data, allocated and freed by libavutil along with this context.
Definition: hwcontext.h:92
This struct describes the constraints on hardware frames attached to a given device with a hardware-s...
Definition: hwcontext.h:453
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:458
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:465
This struct describes a set or pool of "hardware" frames (i.e.
Definition: hwcontext.h:124
ID3D11Texture2D * staging_texture
enum AVHWDeviceType type
#define av_free(p)
#define av_malloc_array(a, b)
#define av_log(a,...)
#define src
Definition: vp8dsp.c:255
AVFormatContext * ctx
Definition: movenc.c:48
AVDictionary * opts
Definition: movenc.c:50
int size
static int device_init(AVFormatContext *ctx, int *width, int *height, uint32_t pixelformat)
Definition: v4l2.c:192