FFmpeg
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 {
77 
78  DXGI_FORMAT format;
79 
80  ID3D11Texture2D *staging_texture;
82 
83 static const struct {
84  DXGI_FORMAT d3d_format;
86 } supported_formats[] = {
87  { DXGI_FORMAT_NV12, AV_PIX_FMT_NV12 },
88  { DXGI_FORMAT_P010, AV_PIX_FMT_P010 },
89  // Special opaque formats. The pix_fmt is merely a place holder, as the
90  // opaque format cannot be accessed directly.
91  { DXGI_FORMAT_420_OPAQUE, AV_PIX_FMT_YUV420P },
92 };
93 
94 static void d3d11va_default_lock(void *ctx)
95 {
96  WaitForSingleObjectEx(ctx, INFINITE, FALSE);
97 }
98 
99 static void d3d11va_default_unlock(void *ctx)
100 {
101  ReleaseMutex(ctx);
102 }
103 
105 {
106  AVD3D11VAFramesContext *frames_hwctx = ctx->hwctx;
107  D3D11VAFramesContext *s = ctx->internal->priv;
108 
109  if (frames_hwctx->texture)
110  ID3D11Texture2D_Release(frames_hwctx->texture);
111  frames_hwctx->texture = NULL;
112 
113  if (s->staging_texture)
114  ID3D11Texture2D_Release(s->staging_texture);
115  s->staging_texture = NULL;
116 
117  av_freep(&frames_hwctx->texture_infos);
118 }
119 
121  const void *hwconfig,
122  AVHWFramesConstraints *constraints)
123 {
124  AVD3D11VADeviceContext *device_hwctx = ctx->hwctx;
125  int nb_sw_formats = 0;
126  HRESULT hr;
127  int i;
128 
130  sizeof(*constraints->valid_sw_formats));
131  if (!constraints->valid_sw_formats)
132  return AVERROR(ENOMEM);
133 
134  for (i = 0; i < FF_ARRAY_ELEMS(supported_formats); i++) {
135  UINT format_support = 0;
136  hr = ID3D11Device_CheckFormatSupport(device_hwctx->device, supported_formats[i].d3d_format, &format_support);
137  if (SUCCEEDED(hr) && (format_support & D3D11_FORMAT_SUPPORT_TEXTURE2D))
138  constraints->valid_sw_formats[nb_sw_formats++] = supported_formats[i].pix_fmt;
139  }
140  constraints->valid_sw_formats[nb_sw_formats] = AV_PIX_FMT_NONE;
141 
142  constraints->valid_hw_formats = av_malloc_array(2, sizeof(*constraints->valid_hw_formats));
143  if (!constraints->valid_hw_formats)
144  return AVERROR(ENOMEM);
145 
146  constraints->valid_hw_formats[0] = AV_PIX_FMT_D3D11;
147  constraints->valid_hw_formats[1] = AV_PIX_FMT_NONE;
148 
149  return 0;
150 }
151 
152 static void free_texture(void *opaque, uint8_t *data)
153 {
154  ID3D11Texture2D_Release((ID3D11Texture2D *)opaque);
155  av_free(data);
156 }
157 
158 static AVBufferRef *wrap_texture_buf(AVHWFramesContext *ctx, ID3D11Texture2D *tex, int index)
159 {
160  AVBufferRef *buf;
162  D3D11VAFramesContext *s = ctx->internal->priv;
163  AVD3D11VAFramesContext *frames_hwctx = ctx->hwctx;
164  if (!desc) {
165  ID3D11Texture2D_Release(tex);
166  return NULL;
167  }
168 
169  frames_hwctx->texture_infos[s->nb_surfaces_used].texture = tex;
170  frames_hwctx->texture_infos[s->nb_surfaces_used].index = index;
171  s->nb_surfaces_used++;
172 
173  desc->texture = tex;
174  desc->index = index;
175 
176  buf = av_buffer_create((uint8_t *)desc, sizeof(desc), free_texture, tex, 0);
177  if (!buf) {
178  ID3D11Texture2D_Release(tex);
179  av_free(desc);
180  return NULL;
181  }
182 
183  return buf;
184 }
185 
187 {
188  D3D11VAFramesContext *s = ctx->internal->priv;
189  AVD3D11VAFramesContext *hwctx = ctx->hwctx;
190  AVD3D11VADeviceContext *device_hwctx = ctx->device_ctx->hwctx;
191  HRESULT hr;
192  ID3D11Texture2D *tex;
193  D3D11_TEXTURE2D_DESC texDesc = {
194  .Width = ctx->width,
195  .Height = ctx->height,
196  .MipLevels = 1,
197  .Format = s->format,
198  .SampleDesc = { .Count = 1 },
199  .ArraySize = 1,
200  .Usage = D3D11_USAGE_DEFAULT,
201  .BindFlags = hwctx->BindFlags,
202  .MiscFlags = hwctx->MiscFlags,
203  };
204 
205  hr = ID3D11Device_CreateTexture2D(device_hwctx->device, &texDesc, NULL, &tex);
206  if (FAILED(hr)) {
207  av_log(ctx, AV_LOG_ERROR, "Could not create the texture (%lx)\n", (long)hr);
208  return NULL;
209  }
210 
211  return wrap_texture_buf(ctx, tex, 0);
212 }
213 
214 static AVBufferRef *d3d11va_pool_alloc(void *opaque, size_t size)
215 {
217  D3D11VAFramesContext *s = ctx->internal->priv;
218  AVD3D11VAFramesContext *hwctx = ctx->hwctx;
219  D3D11_TEXTURE2D_DESC texDesc;
220 
221  if (!hwctx->texture)
222  return d3d11va_alloc_single(ctx);
223 
224  ID3D11Texture2D_GetDesc(hwctx->texture, &texDesc);
225 
226  if (s->nb_surfaces_used >= texDesc.ArraySize) {
227  av_log(ctx, AV_LOG_ERROR, "Static surface pool size exceeded.\n");
228  return NULL;
229  }
230 
231  ID3D11Texture2D_AddRef(hwctx->texture);
232  return wrap_texture_buf(ctx, hwctx->texture, s->nb_surfaces_used);
233 }
234 
236 {
237  AVD3D11VAFramesContext *hwctx = ctx->hwctx;
238  AVD3D11VADeviceContext *device_hwctx = ctx->device_ctx->hwctx;
239  D3D11VAFramesContext *s = ctx->internal->priv;
240 
241  int i;
242  HRESULT hr;
243  D3D11_TEXTURE2D_DESC texDesc;
244 
245  for (i = 0; i < FF_ARRAY_ELEMS(supported_formats); i++) {
246  if (ctx->sw_format == supported_formats[i].pix_fmt) {
247  s->format = supported_formats[i].d3d_format;
248  break;
249  }
250  }
252  av_log(ctx, AV_LOG_ERROR, "Unsupported pixel format: %s\n",
253  av_get_pix_fmt_name(ctx->sw_format));
254  return AVERROR(EINVAL);
255  }
256 
257  texDesc = (D3D11_TEXTURE2D_DESC){
258  .Width = ctx->width,
259  .Height = ctx->height,
260  .MipLevels = 1,
261  .Format = s->format,
262  .SampleDesc = { .Count = 1 },
263  .ArraySize = ctx->initial_pool_size,
264  .Usage = D3D11_USAGE_DEFAULT,
265  .BindFlags = hwctx->BindFlags,
266  .MiscFlags = hwctx->MiscFlags,
267  };
268 
269  if (hwctx->texture) {
270  D3D11_TEXTURE2D_DESC texDesc2;
271  ID3D11Texture2D_GetDesc(hwctx->texture, &texDesc2);
272 
273  if (texDesc.Width != texDesc2.Width ||
274  texDesc.Height != texDesc2.Height ||
275  texDesc.Format != texDesc2.Format) {
276  av_log(ctx, AV_LOG_ERROR, "User-provided texture has mismatching parameters\n");
277  return AVERROR(EINVAL);
278  }
279  } else if (!(texDesc.BindFlags & D3D11_BIND_RENDER_TARGET) && texDesc.ArraySize > 0) {
280  hr = ID3D11Device_CreateTexture2D(device_hwctx->device, &texDesc, NULL, &hwctx->texture);
281  if (FAILED(hr)) {
282  av_log(ctx, AV_LOG_ERROR, "Could not create the texture (%lx)\n", (long)hr);
283  return AVERROR_UNKNOWN;
284  }
285  }
286 
287  hwctx->texture_infos = av_calloc(ctx->initial_pool_size, sizeof(*hwctx->texture_infos));
288  if (!hwctx->texture_infos)
289  return AVERROR(ENOMEM);
290  s->nb_surfaces = ctx->initial_pool_size;
291 
292  ctx->internal->pool_internal = av_buffer_pool_init2(sizeof(AVD3D11FrameDescriptor),
294  if (!ctx->internal->pool_internal)
295  return AVERROR(ENOMEM);
296 
297  return 0;
298 }
299 
301 {
303 
304  frame->buf[0] = av_buffer_pool_get(ctx->pool);
305  if (!frame->buf[0])
306  return AVERROR(ENOMEM);
307 
308  desc = (AVD3D11FrameDescriptor *)frame->buf[0]->data;
309 
310  frame->data[0] = (uint8_t *)desc->texture;
311  frame->data[1] = (uint8_t *)desc->index;
312  frame->format = AV_PIX_FMT_D3D11;
313  frame->width = ctx->width;
314  frame->height = ctx->height;
315 
316  return 0;
317 }
318 
321  enum AVPixelFormat **formats)
322 {
323  D3D11VAFramesContext *s = ctx->internal->priv;
324  enum AVPixelFormat *fmts;
325 
326  fmts = av_malloc_array(2, sizeof(*fmts));
327  if (!fmts)
328  return AVERROR(ENOMEM);
329 
330  fmts[0] = ctx->sw_format;
331  fmts[1] = AV_PIX_FMT_NONE;
332 
333  // Don't signal support for opaque formats. Actual access would fail.
334  if (s->format == DXGI_FORMAT_420_OPAQUE)
335  fmts[0] = AV_PIX_FMT_NONE;
336 
337  *formats = fmts;
338 
339  return 0;
340 }
341 
343 {
344  AVD3D11VADeviceContext *device_hwctx = ctx->device_ctx->hwctx;
345  D3D11VAFramesContext *s = ctx->internal->priv;
346  HRESULT hr;
347  D3D11_TEXTURE2D_DESC texDesc = {
348  .Width = ctx->width,
349  .Height = ctx->height,
350  .MipLevels = 1,
351  .Format = format,
352  .SampleDesc = { .Count = 1 },
353  .ArraySize = 1,
354  .Usage = D3D11_USAGE_STAGING,
355  .CPUAccessFlags = D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE,
356  };
357 
358  hr = ID3D11Device_CreateTexture2D(device_hwctx->device, &texDesc, NULL, &s->staging_texture);
359  if (FAILED(hr)) {
360  av_log(ctx, AV_LOG_ERROR, "Could not create the staging texture (%lx)\n", (long)hr);
361  return AVERROR_UNKNOWN;
362  }
363 
364  return 0;
365 }
366 
367 static void fill_texture_ptrs(uint8_t *data[4], int linesize[4],
369  D3D11_TEXTURE2D_DESC *desc,
370  D3D11_MAPPED_SUBRESOURCE *map)
371 {
372  int i;
373 
374  for (i = 0; i < 4; i++)
375  linesize[i] = map->RowPitch;
376 
377  av_image_fill_pointers(data, ctx->sw_format, desc->Height,
378  (uint8_t*)map->pData, linesize);
379 }
380 
382  const AVFrame *src)
383 {
384  AVD3D11VADeviceContext *device_hwctx = ctx->device_ctx->hwctx;
385  D3D11VAFramesContext *s = ctx->internal->priv;
386  int download = src->format == AV_PIX_FMT_D3D11;
387  const AVFrame *frame = download ? src : dst;
388  const AVFrame *other = download ? dst : src;
389  // (The interface types are compatible.)
390  ID3D11Resource *texture = (ID3D11Resource *)(ID3D11Texture2D *)frame->data[0];
391  int index = (intptr_t)frame->data[1];
392  ID3D11Resource *staging;
393  int w = FFMIN(dst->width, src->width);
394  int h = FFMIN(dst->height, src->height);
395  uint8_t *map_data[4];
396  int map_linesize[4];
397  D3D11_TEXTURE2D_DESC desc;
398  D3D11_MAPPED_SUBRESOURCE map;
399  HRESULT hr;
400 
401  if (frame->hw_frames_ctx->data != (uint8_t *)ctx || other->format != ctx->sw_format)
402  return AVERROR(EINVAL);
403 
404  device_hwctx->lock(device_hwctx->lock_ctx);
405 
406  if (!s->staging_texture) {
407  ID3D11Texture2D_GetDesc((ID3D11Texture2D *)texture, &desc);
408  int res = d3d11va_create_staging_texture(ctx, desc.Format);
409  if (res < 0)
410  return res;
411  }
412 
413  staging = (ID3D11Resource *)s->staging_texture;
414 
415  ID3D11Texture2D_GetDesc(s->staging_texture, &desc);
416 
417  if (download) {
418  ID3D11DeviceContext_CopySubresourceRegion(device_hwctx->device_context,
419  staging, 0, 0, 0, 0,
420  texture, index, NULL);
421 
422  hr = ID3D11DeviceContext_Map(device_hwctx->device_context,
423  staging, 0, D3D11_MAP_READ, 0, &map);
424  if (FAILED(hr))
425  goto map_failed;
426 
427  fill_texture_ptrs(map_data, map_linesize, ctx, &desc, &map);
428 
429  av_image_copy(dst->data, dst->linesize, (const uint8_t **)map_data, map_linesize,
430  ctx->sw_format, w, h);
431 
432  ID3D11DeviceContext_Unmap(device_hwctx->device_context, staging, 0);
433  } else {
434  hr = ID3D11DeviceContext_Map(device_hwctx->device_context,
435  staging, 0, D3D11_MAP_WRITE, 0, &map);
436  if (FAILED(hr))
437  goto map_failed;
438 
439  fill_texture_ptrs(map_data, map_linesize, ctx, &desc, &map);
440 
441  av_image_copy(map_data, map_linesize, (const uint8_t **)src->data, src->linesize,
442  ctx->sw_format, w, h);
443 
444  ID3D11DeviceContext_Unmap(device_hwctx->device_context, staging, 0);
445 
446  ID3D11DeviceContext_CopySubresourceRegion(device_hwctx->device_context,
447  texture, index, 0, 0, 0,
448  staging, 0, NULL);
449  }
450 
451  device_hwctx->unlock(device_hwctx->lock_ctx);
452  return 0;
453 
454 map_failed:
455  av_log(ctx, AV_LOG_ERROR, "Unable to lock D3D11VA surface (%lx)\n", (long)hr);
456  device_hwctx->unlock(device_hwctx->lock_ctx);
457  return AVERROR_UNKNOWN;
458 }
459 
461 {
462  AVD3D11VADeviceContext *device_hwctx = hwdev->hwctx;
463  HRESULT hr;
464 
465  if (!device_hwctx->lock) {
466  device_hwctx->lock_ctx = CreateMutex(NULL, 0, NULL);
467  if (device_hwctx->lock_ctx == INVALID_HANDLE_VALUE) {
468  av_log(NULL, AV_LOG_ERROR, "Failed to create a mutex\n");
469  return AVERROR(EINVAL);
470  }
471  device_hwctx->lock = d3d11va_default_lock;
472  device_hwctx->unlock = d3d11va_default_unlock;
473  }
474 
475  if (!device_hwctx->device_context) {
476  ID3D11Device_GetImmediateContext(device_hwctx->device, &device_hwctx->device_context);
477  if (!device_hwctx->device_context)
478  return AVERROR_UNKNOWN;
479  }
480 
481  if (!device_hwctx->video_device) {
482  hr = ID3D11DeviceContext_QueryInterface(device_hwctx->device, &IID_ID3D11VideoDevice,
483  (void **)&device_hwctx->video_device);
484  if (FAILED(hr))
485  return AVERROR_UNKNOWN;
486  }
487 
488  if (!device_hwctx->video_context) {
489  hr = ID3D11DeviceContext_QueryInterface(device_hwctx->device_context, &IID_ID3D11VideoContext,
490  (void **)&device_hwctx->video_context);
491  if (FAILED(hr))
492  return AVERROR_UNKNOWN;
493  }
494 
495  return 0;
496 }
497 
499 {
500  AVD3D11VADeviceContext *device_hwctx = hwdev->hwctx;
501 
502  if (device_hwctx->device) {
503  ID3D11Device_Release(device_hwctx->device);
504  device_hwctx->device = NULL;
505  }
506 
507  if (device_hwctx->device_context) {
508  ID3D11DeviceContext_Release(device_hwctx->device_context);
509  device_hwctx->device_context = NULL;
510  }
511 
512  if (device_hwctx->video_device) {
513  ID3D11VideoDevice_Release(device_hwctx->video_device);
514  device_hwctx->video_device = NULL;
515  }
516 
517  if (device_hwctx->video_context) {
518  ID3D11VideoContext_Release(device_hwctx->video_context);
519  device_hwctx->video_context = NULL;
520  }
521 
522  if (device_hwctx->lock == d3d11va_default_lock) {
523  CloseHandle(device_hwctx->lock_ctx);
524  device_hwctx->lock_ctx = INVALID_HANDLE_VALUE;
525  device_hwctx->lock = NULL;
526  }
527 }
528 
529 static int d3d11va_device_create(AVHWDeviceContext *ctx, const char *device,
530  AVDictionary *opts, int flags)
531 {
532  AVD3D11VADeviceContext *device_hwctx = ctx->hwctx;
533 
534  HRESULT hr;
535  IDXGIAdapter *pAdapter = NULL;
536  ID3D10Multithread *pMultithread;
537  UINT creationFlags = D3D11_CREATE_DEVICE_VIDEO_SUPPORT;
538  int is_debug = !!av_dict_get(opts, "debug", NULL, 0);
539  int ret;
540 
541  // (On UWP we can't check this.)
542 #if !HAVE_UWP
543  if (!LoadLibrary("d3d11_1sdklayers.dll"))
544  is_debug = 0;
545 #endif
546 
547  if (is_debug)
548  creationFlags |= D3D11_CREATE_DEVICE_DEBUG;
549 
551  return AVERROR_UNKNOWN;
553  av_log(ctx, AV_LOG_ERROR, "Failed to load D3D11 library or its functions\n");
554  return AVERROR_UNKNOWN;
555  }
556 
557  if (device) {
558  IDXGIFactory2 *pDXGIFactory;
559  hr = mCreateDXGIFactory(&IID_IDXGIFactory2, (void **)&pDXGIFactory);
560  if (SUCCEEDED(hr)) {
561  int adapter = atoi(device);
562  if (FAILED(IDXGIFactory2_EnumAdapters(pDXGIFactory, adapter, &pAdapter)))
563  pAdapter = NULL;
564  IDXGIFactory2_Release(pDXGIFactory);
565  }
566  }
567 
568  if (pAdapter) {
569  DXGI_ADAPTER_DESC desc;
570  hr = IDXGIAdapter2_GetDesc(pAdapter, &desc);
571  if (!FAILED(hr)) {
572  av_log(ctx, AV_LOG_INFO, "Using device %04x:%04x (%ls).\n",
573  desc.VendorId, desc.DeviceId, desc.Description);
574  }
575  }
576 
577  hr = mD3D11CreateDevice(pAdapter, pAdapter ? D3D_DRIVER_TYPE_UNKNOWN : D3D_DRIVER_TYPE_HARDWARE, NULL, creationFlags, NULL, 0,
578  D3D11_SDK_VERSION, &device_hwctx->device, NULL, NULL);
579  if (pAdapter)
580  IDXGIAdapter_Release(pAdapter);
581  if (FAILED(hr)) {
582  av_log(ctx, AV_LOG_ERROR, "Failed to create Direct3D device (%lx)\n", (long)hr);
583  return AVERROR_UNKNOWN;
584  }
585 
586  hr = ID3D11Device_QueryInterface(device_hwctx->device, &IID_ID3D10Multithread, (void **)&pMultithread);
587  if (SUCCEEDED(hr)) {
588  ID3D10Multithread_SetMultithreadProtected(pMultithread, TRUE);
589  ID3D10Multithread_Release(pMultithread);
590  }
591 
592 #if !HAVE_UWP && HAVE_DXGIDEBUG_H
593  if (is_debug) {
594  HANDLE dxgidebug_dll = LoadLibrary("dxgidebug.dll");
595  if (dxgidebug_dll) {
596  HRESULT (WINAPI * pf_DXGIGetDebugInterface)(const GUID *riid, void **ppDebug)
597  = (void *)GetProcAddress(dxgidebug_dll, "DXGIGetDebugInterface");
598  if (pf_DXGIGetDebugInterface) {
599  IDXGIDebug *dxgi_debug = NULL;
600  hr = pf_DXGIGetDebugInterface(&IID_IDXGIDebug, (void**)&dxgi_debug);
601  if (SUCCEEDED(hr) && dxgi_debug)
602  IDXGIDebug_ReportLiveObjects(dxgi_debug, DXGI_DEBUG_ALL, DXGI_DEBUG_RLO_ALL);
603  }
604  }
605  }
606 #endif
607 
608  return 0;
609 }
610 
613  .name = "D3D11VA",
614 
615  .device_hwctx_size = sizeof(AVD3D11VADeviceContext),
616  .frames_hwctx_size = sizeof(AVD3D11VAFramesContext),
617  .frames_priv_size = sizeof(D3D11VAFramesContext),
618 
619  .device_create = d3d11va_device_create,
621  .device_uninit = d3d11va_device_uninit,
622  .frames_get_constraints = d3d11va_frames_get_constraints,
623  .frames_init = d3d11va_frames_init,
624  .frames_uninit = d3d11va_frames_uninit,
625  .frames_get_buffer = d3d11va_get_buffer,
626  .transfer_get_formats = d3d11va_transfer_get_formats,
627  .transfer_data_to = d3d11va_transfer_data,
628  .transfer_data_from = d3d11va_transfer_data,
629 
631 };
d3d11va_alloc_single
static AVBufferRef * d3d11va_alloc_single(AVHWFramesContext *ctx)
Definition: hwcontext_d3d11va.c:186
formats
formats
Definition: signature.h:48
AVHWDeviceContext::hwctx
void * hwctx
The format-specific data, allocated and freed by libavutil along with this context.
Definition: hwcontext.h:92
AVPixelFormat
AVPixelFormat
Pixel format.
Definition: pixfmt.h:64
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
thread.h
d3d11va_transfer_get_formats
static int d3d11va_transfer_get_formats(AVHWFramesContext *ctx, enum AVHWFrameTransferDirection dir, enum AVPixelFormat **formats)
Definition: hwcontext_d3d11va.c:319
AVFrame
This structure describes decoded (raw) audio or video data.
Definition: frame.h:325
pixdesc.h
AVFrame::width
int width
Definition: frame.h:397
AVD3D11VAFramesContext::MiscFlags
UINT MiscFlags
D3D11_TEXTURE2D_DESC.MiscFlags used for texture creation.
Definition: hwcontext_d3d11va.h:166
w
uint8_t w
Definition: llviddspenc.c:38
data
const char data[16]
Definition: mxf.c:143
d3d11va_transfer_data
static int d3d11va_transfer_data(AVHWFramesContext *ctx, AVFrame *dst, const AVFrame *src)
Definition: hwcontext_d3d11va.c:381
AVDictionary
Definition: dict.c:30
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:458
AVERROR_UNKNOWN
#define AVERROR_UNKNOWN
Unknown error, typically from an external library.
Definition: error.h:73
fill_texture_ptrs
static void fill_texture_ptrs(uint8_t *data[4], int linesize[4], AVHWFramesContext *ctx, D3D11_TEXTURE2D_DESC *desc, D3D11_MAPPED_SUBRESOURCE *map)
Definition: hwcontext_d3d11va.c:367
PFN_CREATE_DXGI_FACTORY
HRESULT(WINAPI * PFN_CREATE_DXGI_FACTORY)(REFIID riid, void **ppFactory)
Definition: hwcontext_d3d11va.c:44
AVFrame::data
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition: frame.h:346
AVHWFramesConstraints
This struct describes the constraints on hardware frames attached to a given device with a hardware-s...
Definition: hwcontext.h:453
AVD3D11VAFramesContext::BindFlags
UINT BindFlags
D3D11_TEXTURE2D_DESC.BindFlags used for texture creation.
Definition: hwcontext_d3d11va.h:160
ff_hwcontext_type_d3d11va
const HWContextType ff_hwcontext_type_d3d11va
Definition: hwcontext_d3d11va.c:611
d3d11va_get_buffer
static int d3d11va_get_buffer(AVHWFramesContext *ctx, AVFrame *frame)
Definition: hwcontext_d3d11va.c:300
d3d_format
DXGI_FORMAT d3d_format
Definition: hwcontext_d3d11va.c:84
AVD3D11FrameDescriptor::texture
ID3D11Texture2D * texture
The texture in which the frame is located.
Definition: hwcontext_d3d11va.h:117
d3d11va_create_staging_texture
static int d3d11va_create_staging_texture(AVHWFramesContext *ctx, DXGI_FORMAT format)
Definition: hwcontext_d3d11va.c:342
D3D11VAFramesContext::format
DXGI_FORMAT format
Definition: hwcontext_d3d11va.c:78
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
d3d11va_frames_uninit
static void d3d11va_frames_uninit(AVHWFramesContext *ctx)
Definition: hwcontext_d3d11va.c:104
d3d11va_default_unlock
static void d3d11va_default_unlock(void *ctx)
Definition: hwcontext_d3d11va.c:99
D3D11VAFramesContext::nb_surfaces_used
int nb_surfaces_used
Definition: hwcontext_d3d11va.c:76
av_image_fill_pointers
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:145
d3d11va_frames_get_constraints
static int d3d11va_frames_get_constraints(AVHWDeviceContext *ctx, const void *hwconfig, AVHWFramesConstraints *constraints)
Definition: hwcontext_d3d11va.c:120
AVHWDeviceContext
This struct aggregates all the (hardware/vendor-specific) "high-level" state, i.e.
Definition: hwcontext.h:61
avassert.h
HWContextType::type
enum AVHWDeviceType type
Definition: hwcontext_internal.h:30
ff_thread_once
static int ff_thread_once(char *control, void(*routine)(void))
Definition: thread.h:179
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:180
FF_ARRAY_ELEMS
#define FF_ARRAY_ELEMS(a)
Definition: sinewin_tablegen.c:29
av_cold
#define av_cold
Definition: attributes.h:90
load_functions
static av_cold void load_functions(void)
Definition: hwcontext_d3d11va.c:51
device_init
static int device_init(AVFormatContext *ctx, int *width, int *height, uint32_t pixelformat)
Definition: v4l2.c:203
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:465
av_dict_get
AVDictionaryEntry * av_dict_get(const AVDictionary *m, const char *key, const AVDictionaryEntry *prev, int flags)
Get a dictionary entry with matching key.
Definition: dict.c:40
av_buffer_pool_get
AVBufferRef * av_buffer_pool_get(AVBufferPool *pool)
Allocate a new AVBuffer, reusing an old buffer from the pool when available.
Definition: buffer.c:387
AVD3D11VADeviceContext::video_context
ID3D11VideoContext * video_context
If unset, this will be set from the device_context field on init.
Definition: hwcontext_d3d11va.h:80
s
#define s(width, name)
Definition: cbs_vp9.c:256
AVD3D11VADeviceContext::device
ID3D11Device * device
Device used for texture creation and access.
Definition: hwcontext_d3d11va.h:56
d3d11va_device_create
static int d3d11va_device_create(AVHWDeviceContext *ctx, const char *device, AVDictionary *opts, int flags)
Definition: hwcontext_d3d11va.c:529
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
functions_loaded
static AVOnce functions_loaded
Definition: hwcontext_d3d11va.c:46
pix_fmts
static enum AVPixelFormat pix_fmts[]
Definition: libkvazaar.c:296
ctx
AVFormatContext * ctx
Definition: movenc.c:48
AV_PIX_FMT_YUV420P
@ AV_PIX_FMT_YUV420P
planar YUV 4:2:0, 12bpp, (1 Cr & Cb sample per 2x2 Y samples)
Definition: pixfmt.h:66
opts
AVDictionary * opts
Definition: movenc.c:50
D3D11VAFramesContext::nb_surfaces
int nb_surfaces
Definition: hwcontext_d3d11va.c:75
AV_ONCE_INIT
#define AV_ONCE_INIT
Definition: thread.h:177
AVD3D11VAFramesContext::texture_infos
AVD3D11FrameDescriptor * texture_infos
In case if texture structure member above is not NULL contains the same texture pointer for all eleme...
Definition: hwcontext_d3d11va.h:175
AVD3D11VADeviceContext::lock_ctx
void * lock_ctx
Definition: hwcontext_d3d11va.h:96
NULL
#define NULL
Definition: coverity.c:32
d3d11va_default_lock
static void d3d11va_default_lock(void *ctx)
Definition: hwcontext_d3d11va.c:94
AVD3D11VADeviceContext::video_device
ID3D11VideoDevice * video_device
If unset, this will be set from the device field on init.
Definition: hwcontext_d3d11va.h:72
wrap_texture_buf
static AVBufferRef * wrap_texture_buf(AVHWFramesContext *ctx, ID3D11Texture2D *tex, int index)
Definition: hwcontext_d3d11va.c:158
supported_formats
static const struct @304 supported_formats[]
AVOnce
#define AVOnce
Definition: thread.h:176
index
int index
Definition: gxfenc.c:89
AVD3D11VADeviceContext::unlock
void(* unlock)(void *lock_ctx)
Definition: hwcontext_d3d11va.h:95
AVD3D11VAFramesContext
This struct is allocated as AVHWFramesContext.hwctx.
Definition: hwcontext_d3d11va.h:131
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
size
int size
Definition: twinvq_data.h:10344
d3d11va_frames_init
static int d3d11va_frames_init(AVHWFramesContext *ctx)
Definition: hwcontext_d3d11va.c:235
mCreateDXGIFactory
static PFN_CREATE_DXGI_FACTORY mCreateDXGIFactory
Definition: hwcontext_d3d11va.c:48
AVFrame::format
int format
format of the frame, -1 if unknown or unset Values correspond to enum AVPixelFormat for video frames,...
Definition: frame.h:412
free_texture
static void free_texture(void *opaque, uint8_t *data)
Definition: hwcontext_d3d11va.c:152
AVD3D11VAFramesContext::texture
ID3D11Texture2D * texture
The canonical texture used for pool allocation.
Definition: hwcontext_d3d11va.h:152
AV_PIX_FMT_D3D11
@ AV_PIX_FMT_D3D11
Hardware surfaces for Direct3D11.
Definition: pixfmt.h:305
AV_LOG_INFO
#define AV_LOG_INFO
Standard information.
Definition: log.h:191
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:271
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
AVD3D11FrameDescriptor::index
intptr_t index
The index into the array texture element representing the frame, or 0 if the texture is not an array ...
Definition: hwcontext_d3d11va.h:125
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:264
av_calloc
void * av_calloc(size_t nmemb, size_t size)
Definition: mem.c:272
AVD3D11VADeviceContext::lock
void(* lock)(void *lock_ctx)
Callbacks for locking.
Definition: hwcontext_d3d11va.h:94
AVHWFrameTransferDirection
AVHWFrameTransferDirection
Definition: hwcontext.h:415
AVHWFramesContext
This struct describes a set or pool of "hardware" frames (i.e.
Definition: hwcontext.h:124
ret
ret
Definition: filter_design.txt:187
pixfmt.h
AV_PIX_FMT_NV12
@ AV_PIX_FMT_NV12
planar YUV 4:2:0, 12bpp, 1 plane for Y and 1 plane for the UV components, which are interleaved (firs...
Definition: pixfmt.h:89
frame
these buffered frames must be flushed immediately if a new input produces new the filter must not call request_frame to get more It must just process the frame or queue it The task of requesting more frames is left to the filter s request_frame method or the application If a filter has several the filter must be ready for frames arriving randomly on any input any filter with several inputs will most likely require some kind of queuing mechanism It is perfectly acceptable to have a limited queue and to drop frames when the inputs are too unbalanced request_frame For filters that do not use the this method is called when a frame is wanted on an output For a it should directly call filter_frame on the corresponding output For a if there are queued frames already one of these frames should be pushed If the filter should request a frame on one of its repeatedly until at least one frame has been pushed Return or at least make progress towards producing a frame
Definition: filter_design.txt:264
mD3D11CreateDevice
static PFN_D3D11_CREATE_DEVICE mD3D11CreateDevice
Definition: hwcontext_d3d11va.c:49
AVFrame::height
int height
Definition: frame.h:397
d3d11va_pool_alloc
static AVBufferRef * d3d11va_pool_alloc(void *opaque, size_t size)
Definition: hwcontext_d3d11va.c:214
av_image_copy
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
pix_fmt
enum AVPixelFormat pix_fmt
Definition: hwcontext_d3d11va.c:85
AV_PIX_FMT_NONE
@ AV_PIX_FMT_NONE
Definition: pixfmt.h:65
D3D11VAFramesContext
Definition: hwcontext_d3d11va.c:74
d3d11va_device_uninit
static void d3d11va_device_uninit(AVHWDeviceContext *hwdev)
Definition: hwcontext_d3d11va.c:498
D3D11VAFramesContext::staging_texture
ID3D11Texture2D * staging_texture
Definition: hwcontext_d3d11va.c:80
AV_PIX_FMT_P010
#define AV_PIX_FMT_P010
Definition: pixfmt.h:455
desc
const char * desc
Definition: libsvtav1.c:83
AVBufferRef
A reference to a data buffer.
Definition: buffer.h:82
d3d11va_device_init
static int d3d11va_device_init(AVHWDeviceContext *hwdev)
Definition: hwcontext_d3d11va.c:460
hwcontext_internal.h
map
const VDPAUPixFmtMap * map
Definition: hwcontext_vdpau.c:71
av_free
#define av_free(p)
Definition: tableprint_vlc.h:33
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:34
src
INIT_CLIP pixel * src
Definition: h264pred_template.c:418
AVD3D11FrameDescriptor
D3D11 frame descriptor for pool allocation.
Definition: hwcontext_d3d11va.h:109
imgutils.h
flags
#define flags(name, subs,...)
Definition: cbs_av1.c:561
hwcontext.h
AVFrame::linesize
int linesize[AV_NUM_DATA_POINTERS]
For video, a positive or negative value, which is typically indicating the size in bytes of each pict...
Definition: frame.h:370
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:27
HWContextType
Definition: hwcontext_internal.h:29
AVD3D11VADeviceContext::device_context
ID3D11DeviceContext * device_context
If unset, this will be set from the device field on init.
Definition: hwcontext_d3d11va.h:64
h
h
Definition: vp9dsp_template.c:2038
hwcontext_d3d11va.h
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:2582