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