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 // Include thread.h before redefining _WIN32_WINNT, to get
24 // the right implementation for AVOnce
25 #include "thread.h"
26 
27 #if !defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0600
28 #undef _WIN32_WINNT
29 #define _WIN32_WINNT 0x0600
30 #endif
31 #define COBJMACROS
32 
33 #include <initguid.h>
34 #include <d3d11.h>
35 #include <dxgi1_2.h>
36 
37 #if HAVE_DXGIDEBUG_H
38 #include <dxgidebug.h>
39 #endif
40 
41 #include "avassert.h"
42 #include "common.h"
43 #include "hwcontext.h"
44 #include "hwcontext_d3d11va.h"
45 #include "hwcontext_internal.h"
46 #include "imgutils.h"
47 #include "pixdesc.h"
48 #include "pixfmt.h"
49 
50 typedef HRESULT(WINAPI *PFN_CREATE_DXGI_FACTORY)(REFIID riid, void **ppFactory);
51 
53 
55 static PFN_D3D11_CREATE_DEVICE mD3D11CreateDevice;
56 
57 static av_cold void load_functions(void)
58 {
59 #if !HAVE_UWP
60  // We let these "leak" - this is fine, as unloading has no great benefit, and
61  // Windows will mark a DLL as loaded forever if its internal refcount overflows
62  // from too many LoadLibrary calls.
63  HANDLE d3dlib, dxgilib;
64 
65  d3dlib = LoadLibrary("d3d11.dll");
66  dxgilib = LoadLibrary("dxgi.dll");
67  if (!d3dlib || !dxgilib)
68  return;
69 
70  mD3D11CreateDevice = (PFN_D3D11_CREATE_DEVICE) GetProcAddress(d3dlib, "D3D11CreateDevice");
71  mCreateDXGIFactory = (PFN_CREATE_DXGI_FACTORY) GetProcAddress(dxgilib, "CreateDXGIFactory");
72 #else
73  // In UWP (which lacks LoadLibrary), CreateDXGIFactory isn't available,
74  // only CreateDXGIFactory1
75  mD3D11CreateDevice = (PFN_D3D11_CREATE_DEVICE) D3D11CreateDevice;
76  mCreateDXGIFactory = (PFN_CREATE_DXGI_FACTORY) CreateDXGIFactory1;
77 #endif
78 }
79 
80 typedef struct D3D11VAFramesContext {
82 
83  DXGI_FORMAT format;
84 
85  ID3D11Texture2D *staging_texture;
87 
88 static const struct {
89  DXGI_FORMAT d3d_format;
91 } supported_formats[] = {
92  { DXGI_FORMAT_NV12, AV_PIX_FMT_NV12 },
93  { DXGI_FORMAT_P010, AV_PIX_FMT_P010 },
94  // Special opaque formats. The pix_fmt is merely a place holder, as the
95  // opaque format cannot be accessed directly.
96  { DXGI_FORMAT_420_OPAQUE, AV_PIX_FMT_YUV420P },
97 };
98 
99 static void d3d11va_default_lock(void *ctx)
100 {
101  WaitForSingleObjectEx(ctx, INFINITE, FALSE);
102 }
103 
104 static void d3d11va_default_unlock(void *ctx)
105 {
106  ReleaseMutex(ctx);
107 }
108 
110 {
111  AVD3D11VAFramesContext *frames_hwctx = ctx->hwctx;
113 
114  if (frames_hwctx->texture)
115  ID3D11Texture2D_Release(frames_hwctx->texture);
116  frames_hwctx->texture = NULL;
117 
118  if (s->staging_texture)
119  ID3D11Texture2D_Release(s->staging_texture);
120  s->staging_texture = NULL;
121 }
122 
123 static void free_texture(void *opaque, uint8_t *data)
124 {
125  ID3D11Texture2D_Release((ID3D11Texture2D *)opaque);
126 }
127 
128 static AVBufferRef *wrap_texture_buf(ID3D11Texture2D *tex, int index)
129 {
130  AVBufferRef *buf;
131  AVD3D11FrameDescriptor *desc = av_mallocz(sizeof(*desc));
132  if (!desc) {
133  ID3D11Texture2D_Release(tex);
134  return NULL;
135  }
136 
137  desc->texture = tex;
138  desc->index = index;
139 
140  buf = av_buffer_create((uint8_t *)desc, sizeof(desc), free_texture, tex, 0);
141  if (!buf) {
142  ID3D11Texture2D_Release(tex);
143  av_free(desc);
144  return NULL;
145  }
146 
147  return buf;
148 }
149 
151 {
153  AVD3D11VAFramesContext *hwctx = ctx->hwctx;
154  AVD3D11VADeviceContext *device_hwctx = ctx->device_ctx->hwctx;
155  HRESULT hr;
156  ID3D11Texture2D *tex;
157  D3D11_TEXTURE2D_DESC texDesc = {
158  .Width = ctx->width,
159  .Height = ctx->height,
160  .MipLevels = 1,
161  .Format = s->format,
162  .SampleDesc = { .Count = 1 },
163  .ArraySize = 1,
164  .Usage = D3D11_USAGE_DEFAULT,
165  .BindFlags = hwctx->BindFlags,
166  .MiscFlags = hwctx->MiscFlags,
167  };
168 
169  hr = ID3D11Device_CreateTexture2D(device_hwctx->device, &texDesc, NULL, &tex);
170  if (FAILED(hr)) {
171  av_log(ctx, AV_LOG_ERROR, "Could not create the texture (%lx)\n", (long)hr);
172  return NULL;
173  }
174 
175  return wrap_texture_buf(tex, 0);
176 }
177 
178 static AVBufferRef *d3d11va_pool_alloc(void *opaque, int size)
179 {
182  AVD3D11VAFramesContext *hwctx = ctx->hwctx;
183  D3D11_TEXTURE2D_DESC texDesc;
184 
185  if (!hwctx->texture)
186  return d3d11va_alloc_single(ctx);
187 
188  ID3D11Texture2D_GetDesc(hwctx->texture, &texDesc);
189 
190  if (s->nb_surfaces_used >= texDesc.ArraySize) {
191  av_log(ctx, AV_LOG_ERROR, "Static surface pool size exceeded.\n");
192  return NULL;
193  }
194 
195  ID3D11Texture2D_AddRef(hwctx->texture);
196  return wrap_texture_buf(hwctx->texture, s->nb_surfaces_used++);
197 }
198 
200 {
201  AVD3D11VAFramesContext *hwctx = ctx->hwctx;
202  AVD3D11VADeviceContext *device_hwctx = ctx->device_ctx->hwctx;
204 
205  int i;
206  HRESULT hr;
207  D3D11_TEXTURE2D_DESC texDesc;
208 
209  for (i = 0; i < FF_ARRAY_ELEMS(supported_formats); i++) {
210  if (ctx->sw_format == supported_formats[i].pix_fmt) {
211  s->format = supported_formats[i].d3d_format;
212  break;
213  }
214  }
215  if (i == FF_ARRAY_ELEMS(supported_formats)) {
216  av_log(ctx, AV_LOG_ERROR, "Unsupported pixel format: %s\n",
218  return AVERROR(EINVAL);
219  }
220 
221  texDesc = (D3D11_TEXTURE2D_DESC){
222  .Width = ctx->width,
223  .Height = ctx->height,
224  .MipLevels = 1,
225  .Format = s->format,
226  .SampleDesc = { .Count = 1 },
227  .ArraySize = ctx->initial_pool_size,
228  .Usage = D3D11_USAGE_DEFAULT,
229  .BindFlags = hwctx->BindFlags,
230  .MiscFlags = hwctx->MiscFlags,
231  };
232 
233  if (hwctx->texture) {
234  D3D11_TEXTURE2D_DESC texDesc2;
235  ID3D11Texture2D_GetDesc(hwctx->texture, &texDesc2);
236 
237  if (texDesc.Width != texDesc2.Width ||
238  texDesc.Height != texDesc2.Height ||
239  texDesc.Format != texDesc2.Format) {
240  av_log(ctx, AV_LOG_ERROR, "User-provided texture has mismatching parameters\n");
241  return AVERROR(EINVAL);
242  }
243  } else if (texDesc.ArraySize > 0) {
244  hr = ID3D11Device_CreateTexture2D(device_hwctx->device, &texDesc, NULL, &hwctx->texture);
245  if (FAILED(hr)) {
246  av_log(ctx, AV_LOG_ERROR, "Could not create the texture (%lx)\n", (long)hr);
247  return AVERROR_UNKNOWN;
248  }
249  }
250 
252  ctx, d3d11va_pool_alloc, NULL);
253  if (!ctx->internal->pool_internal)
254  return AVERROR(ENOMEM);
255 
256  return 0;
257 }
258 
260 {
262 
263  frame->buf[0] = av_buffer_pool_get(ctx->pool);
264  if (!frame->buf[0])
265  return AVERROR(ENOMEM);
266 
267  desc = (AVD3D11FrameDescriptor *)frame->buf[0]->data;
268 
269  frame->data[0] = (uint8_t *)desc->texture;
270  frame->data[1] = (uint8_t *)desc->index;
271  frame->format = AV_PIX_FMT_D3D11;
272  frame->width = ctx->width;
273  frame->height = ctx->height;
274 
275  return 0;
276 }
277 
280  enum AVPixelFormat **formats)
281 {
283  enum AVPixelFormat *fmts;
284 
285  fmts = av_malloc_array(2, sizeof(*fmts));
286  if (!fmts)
287  return AVERROR(ENOMEM);
288 
289  fmts[0] = ctx->sw_format;
290  fmts[1] = AV_PIX_FMT_NONE;
291 
292  // Don't signal support for opaque formats. Actual access would fail.
293  if (s->format == DXGI_FORMAT_420_OPAQUE)
294  fmts[0] = AV_PIX_FMT_NONE;
295 
296  *formats = fmts;
297 
298  return 0;
299 }
300 
302 {
303  AVD3D11VADeviceContext *device_hwctx = ctx->device_ctx->hwctx;
305  HRESULT hr;
306  D3D11_TEXTURE2D_DESC texDesc = {
307  .Width = ctx->width,
308  .Height = ctx->height,
309  .MipLevels = 1,
310  .Format = s->format,
311  .SampleDesc = { .Count = 1 },
312  .ArraySize = 1,
313  .Usage = D3D11_USAGE_STAGING,
314  .CPUAccessFlags = D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE,
315  };
316 
317  hr = ID3D11Device_CreateTexture2D(device_hwctx->device, &texDesc, NULL, &s->staging_texture);
318  if (FAILED(hr)) {
319  av_log(ctx, AV_LOG_ERROR, "Could not create the staging texture (%lx)\n", (long)hr);
320  return AVERROR_UNKNOWN;
321  }
322 
323  return 0;
324 }
325 
326 static void fill_texture_ptrs(uint8_t *data[4], int linesize[4],
328  D3D11_TEXTURE2D_DESC *desc,
329  D3D11_MAPPED_SUBRESOURCE *map)
330 {
331  int i;
332 
333  for (i = 0; i < 4; i++)
334  linesize[i] = map->RowPitch;
335 
336  av_image_fill_pointers(data, ctx->sw_format, desc->Height,
337  (uint8_t*)map->pData, linesize);
338 }
339 
341  const AVFrame *src)
342 {
343  AVD3D11VADeviceContext *device_hwctx = ctx->device_ctx->hwctx;
345  int download = src->format == AV_PIX_FMT_D3D11;
346  const AVFrame *frame = download ? src : dst;
347  const AVFrame *other = download ? dst : src;
348  // (The interface types are compatible.)
349  ID3D11Resource *texture = (ID3D11Resource *)(ID3D11Texture2D *)frame->data[0];
350  int index = (intptr_t)frame->data[1];
351  ID3D11Resource *staging;
352  int w = FFMIN(dst->width, src->width);
353  int h = FFMIN(dst->height, src->height);
354  uint8_t *map_data[4];
355  int map_linesize[4];
356  D3D11_TEXTURE2D_DESC desc;
357  D3D11_MAPPED_SUBRESOURCE map;
358  HRESULT hr;
359 
360  if (frame->hw_frames_ctx->data != (uint8_t *)ctx || other->format != ctx->sw_format)
361  return AVERROR(EINVAL);
362 
363  device_hwctx->lock(device_hwctx->lock_ctx);
364 
365  if (!s->staging_texture) {
366  int res = d3d11va_create_staging_texture(ctx);
367  if (res < 0)
368  return res;
369  }
370 
371  staging = (ID3D11Resource *)s->staging_texture;
372 
373  ID3D11Texture2D_GetDesc(s->staging_texture, &desc);
374 
375  if (download) {
376  ID3D11DeviceContext_CopySubresourceRegion(device_hwctx->device_context,
377  staging, 0, 0, 0, 0,
378  texture, index, NULL);
379 
380  hr = ID3D11DeviceContext_Map(device_hwctx->device_context,
381  staging, 0, D3D11_MAP_READ, 0, &map);
382  if (FAILED(hr))
383  goto map_failed;
384 
385  fill_texture_ptrs(map_data, map_linesize, ctx, &desc, &map);
386 
387  av_image_copy(dst->data, dst->linesize, map_data, map_linesize,
388  ctx->sw_format, w, h);
389 
390  ID3D11DeviceContext_Unmap(device_hwctx->device_context, staging, 0);
391  } else {
392  hr = ID3D11DeviceContext_Map(device_hwctx->device_context,
393  staging, 0, D3D11_MAP_WRITE, 0, &map);
394  if (FAILED(hr))
395  goto map_failed;
396 
397  fill_texture_ptrs(map_data, map_linesize, ctx, &desc, &map);
398 
399  av_image_copy(map_data, map_linesize, src->data, src->linesize,
400  ctx->sw_format, w, h);
401 
402  ID3D11DeviceContext_Unmap(device_hwctx->device_context, staging, 0);
403 
404  ID3D11DeviceContext_CopySubresourceRegion(device_hwctx->device_context,
405  texture, index, 0, 0, 0,
406  staging, 0, NULL);
407  }
408 
409  device_hwctx->unlock(device_hwctx->lock_ctx);
410  return 0;
411 
412 map_failed:
413  av_log(ctx, AV_LOG_ERROR, "Unable to lock D3D11VA surface (%lx)\n", (long)hr);
414  device_hwctx->unlock(device_hwctx->lock_ctx);
415  return AVERROR_UNKNOWN;
416 }
417 
419 {
420  AVD3D11VADeviceContext *device_hwctx = hwdev->hwctx;
421  HRESULT hr;
422 
423  if (!device_hwctx->lock) {
424  device_hwctx->lock_ctx = CreateMutex(NULL, 0, NULL);
425  if (device_hwctx->lock_ctx == INVALID_HANDLE_VALUE) {
426  av_log(NULL, AV_LOG_ERROR, "Failed to create a mutex\n");
427  return AVERROR(EINVAL);
428  }
429  device_hwctx->lock = d3d11va_default_lock;
430  device_hwctx->unlock = d3d11va_default_unlock;
431  }
432 
433  if (!device_hwctx->device_context) {
434  ID3D11Device_GetImmediateContext(device_hwctx->device, &device_hwctx->device_context);
435  if (!device_hwctx->device_context)
436  return AVERROR_UNKNOWN;
437  }
438 
439  if (!device_hwctx->video_device) {
440  hr = ID3D11DeviceContext_QueryInterface(device_hwctx->device, &IID_ID3D11VideoDevice,
441  (void **)&device_hwctx->video_device);
442  if (FAILED(hr))
443  return AVERROR_UNKNOWN;
444  }
445 
446  if (!device_hwctx->video_context) {
447  hr = ID3D11DeviceContext_QueryInterface(device_hwctx->device_context, &IID_ID3D11VideoContext,
448  (void **)&device_hwctx->video_context);
449  if (FAILED(hr))
450  return AVERROR_UNKNOWN;
451  }
452 
453  return 0;
454 }
455 
457 {
458  AVD3D11VADeviceContext *device_hwctx = hwdev->hwctx;
459 
460  if (device_hwctx->device)
461  ID3D11Device_Release(device_hwctx->device);
462 
463  if (device_hwctx->device_context)
464  ID3D11DeviceContext_Release(device_hwctx->device_context);
465 
466  if (device_hwctx->video_device)
467  ID3D11VideoDevice_Release(device_hwctx->video_device);
468 
469  if (device_hwctx->video_context)
470  ID3D11VideoContext_Release(device_hwctx->video_context);
471 
472  if (device_hwctx->lock == d3d11va_default_lock)
473  CloseHandle(device_hwctx->lock_ctx);
474 }
475 
476 static int d3d11va_device_create(AVHWDeviceContext *ctx, const char *device,
477  AVDictionary *opts, int flags)
478 {
479  AVD3D11VADeviceContext *device_hwctx = ctx->hwctx;
480 
481  HRESULT hr;
482  IDXGIAdapter *pAdapter = NULL;
483  ID3D10Multithread *pMultithread;
484  UINT creationFlags = D3D11_CREATE_DEVICE_VIDEO_SUPPORT;
485  int is_debug = !!av_dict_get(opts, "debug", NULL, 0);
486  int ret;
487 
488  // (On UWP we can't check this.)
489 #if !HAVE_UWP
490  if (!LoadLibrary("d3d11_1sdklayers.dll"))
491  is_debug = 0;
492 #endif
493 
494  if (is_debug)
495  creationFlags |= D3D11_CREATE_DEVICE_DEBUG;
496 
497  if ((ret = ff_thread_once(&functions_loaded, load_functions)) != 0)
498  return AVERROR_UNKNOWN;
500  av_log(ctx, AV_LOG_ERROR, "Failed to load D3D11 library or its functions\n");
501  return AVERROR_UNKNOWN;
502  }
503 
504  if (device) {
505  IDXGIFactory2 *pDXGIFactory;
506  hr = mCreateDXGIFactory(&IID_IDXGIFactory2, (void **)&pDXGIFactory);
507  if (SUCCEEDED(hr)) {
508  int adapter = atoi(device);
509  if (FAILED(IDXGIFactory2_EnumAdapters(pDXGIFactory, adapter, &pAdapter)))
510  pAdapter = NULL;
511  IDXGIFactory2_Release(pDXGIFactory);
512  }
513  }
514 
515  hr = mD3D11CreateDevice(pAdapter, pAdapter ? D3D_DRIVER_TYPE_UNKNOWN : D3D_DRIVER_TYPE_HARDWARE, NULL, creationFlags, NULL, 0,
516  D3D11_SDK_VERSION, &device_hwctx->device, NULL, NULL);
517  if (pAdapter)
518  IDXGIAdapter_Release(pAdapter);
519  if (FAILED(hr)) {
520  av_log(ctx, AV_LOG_ERROR, "Failed to create Direct3D device (%lx)\n", (long)hr);
521  return AVERROR_UNKNOWN;
522  }
523 
524  hr = ID3D11Device_QueryInterface(device_hwctx->device, &IID_ID3D10Multithread, (void **)&pMultithread);
525  if (SUCCEEDED(hr)) {
526  ID3D10Multithread_SetMultithreadProtected(pMultithread, TRUE);
527  ID3D10Multithread_Release(pMultithread);
528  }
529 
530 #if !HAVE_UWP && HAVE_DXGIDEBUG_H
531  if (is_debug) {
532  HANDLE dxgidebug_dll = LoadLibrary("dxgidebug.dll");
533  if (dxgidebug_dll) {
534  HRESULT (WINAPI * pf_DXGIGetDebugInterface)(const GUID *riid, void **ppDebug)
535  = (void *)GetProcAddress(dxgidebug_dll, "DXGIGetDebugInterface");
536  if (pf_DXGIGetDebugInterface) {
537  IDXGIDebug *dxgi_debug = NULL;
538  hr = pf_DXGIGetDebugInterface(&IID_IDXGIDebug, (void**)&dxgi_debug);
539  if (SUCCEEDED(hr) && dxgi_debug)
540  IDXGIDebug_ReportLiveObjects(dxgi_debug, DXGI_DEBUG_ALL, DXGI_DEBUG_RLO_ALL);
541  }
542  }
543  }
544 #endif
545 
546  return 0;
547 }
548 
551  .name = "D3D11VA",
552 
553  .device_hwctx_size = sizeof(AVD3D11VADeviceContext),
554  .frames_hwctx_size = sizeof(AVD3D11VAFramesContext),
555  .frames_priv_size = sizeof(D3D11VAFramesContext),
556 
557  .device_create = d3d11va_device_create,
559  .device_uninit = d3d11va_device_uninit,
560  .frames_init = d3d11va_frames_init,
561  .frames_uninit = d3d11va_frames_uninit,
562  .frames_get_buffer = d3d11va_get_buffer,
563  .transfer_get_formats = d3d11va_transfer_get_formats,
564  .transfer_data_to = d3d11va_transfer_data,
565  .transfer_data_from = d3d11va_transfer_data,
566 
568 };
This struct aggregates all the (hardware/vendor-specific) "high-level" state, i.e.
Definition: hwcontext.h:58
static AVOnce functions_loaded
static int d3d11va_create_staging_texture(AVHWFramesContext *ctx)
#define NULL
Definition: coverity.c:32
const char * s
Definition: avisynth_c.h:768
This structure describes decoded (raw) audio or video data.
Definition: frame.h:201
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:393
const char * desc
Definition: nvenc.c:60
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:226
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:222
#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:538
#define AV_PIX_FMT_P010
Definition: pixfmt.h:424
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_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:89
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.
static int flags
Definition: log.c:57
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:157
#define av_log(a,...)
DXGI_FORMAT d3d_format
int width
Definition: frame.h:259
#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:90
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:385
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:196
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:146
PVOID HANDLE
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
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:274
void(* unlock)(void *lock_ctx)
static const struct @242 supported_formats[]
#define AV_ONCE_INIT
Definition: thread.h:158
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
int linesize[AV_NUM_DATA_POINTERS]
For video, size in bytes of each picture line.
Definition: frame.h:232
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:159
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:121
const VDPAUPixFmtMap * map
AVHWFramesInternal * internal
Private data used internally by libavutil.
Definition: hwcontext.h:131
static enum AVPixelFormat pix_fmts[]
Definition: libkvazaar.c:266
This struct is allocated as AVHWFramesContext.hwctx.
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:215
Hardware surfaces for Direct3D11.
Definition: pixfmt.h:327
#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:62
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:392
pixel format definitions
AVBufferPool * pool
A pool from which the frames are allocated by av_hwframe_get_buffer().
Definition: hwcontext.h:187
#define av_free(p)
static int ff_thread_once(char *control, void(*routine)(void))
Definition: thread.h:160
This struct is allocated as AVHWDeviceContext.hwctx.
void(* lock)(void *lock_ctx)
Callbacks for locking.
int height
Definition: frame.h:259
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:2335
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:219
AVPixelFormat
Pixel format.
Definition: pixfmt.h:60
static PFN_CREATE_DXGI_FACTORY mCreateDXGIFactory
ID3D11DeviceContext * device_context
If unset, this will be set from the device field on init.