FFmpeg
hwcontext_d3d12va.c
Go to the documentation of this file.
1 /*
2  * Direct3D 12 HW acceleration.
3  *
4  * copyright (c) 2022-2023 Wu Jianhua <toqsxw@outlook.com>
5  *
6  * This file is part of FFmpeg.
7  *
8  * FFmpeg is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Lesser General Public
10  * License as published by the Free Software Foundation; either
11  * version 2.1 of the License, or (at your option) any later version.
12  *
13  * FFmpeg is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16  * Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with FFmpeg; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21  */
22 
23 #include "config.h"
24 #include "common.h"
25 #include "hwcontext.h"
26 #include "hwcontext_internal.h"
28 #include "hwcontext_d3d12va.h"
29 #include "imgutils.h"
30 #include "mem.h"
31 #include "pixdesc.h"
32 #include "pixfmt.h"
33 #include "thread.h"
34 #include "compat/w32dlfcn.h"
35 #include <dxgi1_3.h>
36 
37 typedef HRESULT(WINAPI *PFN_CREATE_DXGI_FACTORY2)(UINT Flags, REFIID riid, void **ppFactory);
38 
39 typedef struct D3D12VAFramesContext {
40  /**
41  * The public AVD3D12VAFramesContext. See hwcontext_d3d12va.h for it.
42  */
44 
45  ID3D12Resource *staging_download_buffer;
46  ID3D12Resource *staging_upload_buffer;
47  ID3D12CommandQueue *command_queue;
48  ID3D12CommandAllocator *command_allocator;
49  ID3D12GraphicsCommandList *command_list;
54 
55 typedef struct D3D12VADevicePriv {
56  /**
57  * The public AVD3D12VADeviceContext. See hwcontext_d3d12va.h for it.
58  */
60  HANDLE d3d12lib;
61  HANDLE dxgilib;
63  PFN_D3D12_CREATE_DEVICE create_device;
64  PFN_D3D12_GET_DEBUG_INTERFACE get_debug_interface;
66 
67 static const struct {
68  DXGI_FORMAT d3d_format;
70 } supported_formats[] = {
71  { DXGI_FORMAT_NV12, AV_PIX_FMT_NV12 },
72  { DXGI_FORMAT_P010, AV_PIX_FMT_P010 },
73  { DXGI_FORMAT_P016, AV_PIX_FMT_P012 },
74 };
75 
76 static void d3d12va_default_lock(void *ctx)
77 {
78  WaitForSingleObjectEx(ctx, INFINITE, FALSE);
79 }
80 
81 static void d3d12va_default_unlock(void *ctx)
82 {
83  ReleaseMutex(ctx);
84 }
85 
87 {
88  uint64_t completion = ID3D12Fence_GetCompletedValue(psync_ctx->fence);
89  if (completion < psync_ctx->fence_value) {
90  if (FAILED(ID3D12Fence_SetEventOnCompletion(psync_ctx->fence, psync_ctx->fence_value, psync_ctx->event)))
91  return AVERROR(EINVAL);
92 
93  WaitForSingleObjectEx(psync_ctx->event, INFINITE, FALSE);
94  }
95 
96  return 0;
97 }
98 
99 static inline int d3d12va_wait_queue_idle(AVD3D12VASyncContext *psync_ctx, ID3D12CommandQueue *command_queue)
100 {
101  DX_CHECK(ID3D12CommandQueue_Signal(command_queue, psync_ctx->fence, ++psync_ctx->fence_value));
102  return d3d12va_fence_completion(psync_ctx);
103 
104 fail:
105  return AVERROR(EINVAL);
106 }
107 
108 static int d3d12va_create_staging_buffer_resource(AVHWFramesContext *ctx, D3D12_RESOURCE_STATES states,
109  ID3D12Resource **ppResource, int download)
110 {
111  AVD3D12VADeviceContext *device_hwctx = ctx->device_ctx->hwctx;
112  D3D12VAFramesContext *s = ctx->hwctx;
113  D3D12_HEAP_PROPERTIES props = { .Type = download ? D3D12_HEAP_TYPE_READBACK : D3D12_HEAP_TYPE_UPLOAD };
114  D3D12_RESOURCE_DESC desc = {
115  .Dimension = D3D12_RESOURCE_DIMENSION_BUFFER,
116  .Alignment = 0,
117  .Width = s->luma_component_size + (s->luma_component_size >> 1),
118  .Height = 1,
119  .DepthOrArraySize = 1,
120  .MipLevels = 1,
121  .Format = DXGI_FORMAT_UNKNOWN,
122  .SampleDesc = { .Count = 1, .Quality = 0 },
123  .Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR,
124  .Flags = D3D12_RESOURCE_FLAG_NONE,
125  };
126 
127  if (FAILED(ID3D12Device_CreateCommittedResource(device_hwctx->device, &props, D3D12_HEAP_FLAG_NONE, &desc,
128  states, NULL, &IID_ID3D12Resource, (void **)ppResource))) {
129  av_log(ctx, AV_LOG_ERROR, "Could not create the staging buffer resource\n");
130  return AVERROR_UNKNOWN;
131  }
132 
133  return 0;
134 }
135 
137 {
138  AVD3D12VADeviceContext *device_hwctx = ctx->device_ctx->hwctx;
139  D3D12VAFramesContext *s = ctx->hwctx;
140  AVD3D12VAFramesContext *frames_hwctx = &s->p;
141 
142  D3D12_COMMAND_QUEUE_DESC queue_desc = {
143  .Type = D3D12_COMMAND_LIST_TYPE_COPY,
144  .Priority = 0,
145  .NodeMask = 0,
146  };
147 
148  s->luma_component_size = FFALIGN(ctx->width * (frames_hwctx->format != DXGI_FORMAT_NV12 ? 2 : 1),
149  D3D12_TEXTURE_DATA_PITCH_ALIGNMENT) * ctx->height;
150 
151  DX_CHECK(ID3D12Device_CreateFence(device_hwctx->device, 0, D3D12_FENCE_FLAG_NONE,
152  &IID_ID3D12Fence, (void **)&s->sync_ctx.fence));
153 
154  s->sync_ctx.event = CreateEvent(NULL, FALSE, FALSE, NULL);
155  if (!s->sync_ctx.event)
156  goto fail;
157 
158  DX_CHECK(ID3D12Device_CreateCommandQueue(device_hwctx->device, &queue_desc,
159  &IID_ID3D12CommandQueue, (void **)&s->command_queue));
160 
161  DX_CHECK(ID3D12Device_CreateCommandAllocator(device_hwctx->device, queue_desc.Type,
162  &IID_ID3D12CommandAllocator, (void **)&s->command_allocator));
163 
164  DX_CHECK(ID3D12Device_CreateCommandList(device_hwctx->device, 0, queue_desc.Type,
165  s->command_allocator, NULL, &IID_ID3D12GraphicsCommandList, (void **)&s->command_list));
166 
167  DX_CHECK(ID3D12GraphicsCommandList_Close(s->command_list));
168 
169  ID3D12CommandQueue_ExecuteCommandLists(s->command_queue, 1, (ID3D12CommandList **)&s->command_list);
170 
171  return d3d12va_wait_queue_idle(&s->sync_ctx, s->command_queue);
172 
173 fail:
174  return AVERROR(EINVAL);
175 }
176 
178 {
179  D3D12VAFramesContext *s = ctx->hwctx;
180  AVD3D12VAFramesContext *hwctx = ctx->hwctx;
181 
182  D3D12_OBJECT_RELEASE(s->sync_ctx.fence);
183  if (s->sync_ctx.event)
184  CloseHandle(s->sync_ctx.event);
185 
186  D3D12_OBJECT_RELEASE(s->staging_download_buffer);
187  D3D12_OBJECT_RELEASE(s->staging_upload_buffer);
188  D3D12_OBJECT_RELEASE(s->command_allocator);
189  D3D12_OBJECT_RELEASE(s->command_list);
190  D3D12_OBJECT_RELEASE(s->command_queue);
191 
192  if (hwctx->texture_array)
194 }
195 
196 static int d3d12va_frames_get_constraints(AVHWDeviceContext *ctx, const void *hwconfig, AVHWFramesConstraints *constraints)
197 {
198  HRESULT hr;
199  int nb_sw_formats = 0;
200  AVD3D12VADeviceContext *device_hwctx = ctx->hwctx;
201 
203  sizeof(*constraints->valid_sw_formats));
204  if (!constraints->valid_sw_formats)
205  return AVERROR(ENOMEM);
206 
207  for (int i = 0; i < FF_ARRAY_ELEMS(supported_formats); i++) {
208  D3D12_FEATURE_DATA_FORMAT_SUPPORT format_support = { supported_formats[i].d3d_format };
209  hr = ID3D12Device_CheckFeatureSupport(device_hwctx->device, D3D12_FEATURE_FORMAT_SUPPORT, &format_support, sizeof(format_support));
210  if (SUCCEEDED(hr) && (format_support.Support1 & D3D12_FORMAT_SUPPORT1_TEXTURE2D))
211  constraints->valid_sw_formats[nb_sw_formats++] = supported_formats[i].pix_fmt;
212  }
213  constraints->valid_sw_formats[nb_sw_formats] = AV_PIX_FMT_NONE;
214 
215  constraints->valid_hw_formats = av_malloc_array(2, sizeof(*constraints->valid_hw_formats));
216  if (!constraints->valid_hw_formats)
217  return AVERROR(ENOMEM);
218 
219  constraints->valid_hw_formats[0] = AV_PIX_FMT_D3D12;
220  constraints->valid_hw_formats[1] = AV_PIX_FMT_NONE;
221 
222  return 0;
223 }
224 
225 static void free_texture(void *opaque, uint8_t *data)
226 {
228 
230  D3D12_OBJECT_RELEASE(frame->texture);
231 
232  D3D12_OBJECT_RELEASE(frame->sync_ctx.fence);
233  if (frame->sync_ctx.event)
234  CloseHandle(frame->sync_ctx.event);
235 
236  av_freep(&data);
237 }
238 
240 {
241  AVD3D12VAFrame *frame = av_mallocz(sizeof(*frame));
242  D3D12VAFramesContext *s = ctx->hwctx;
243  AVD3D12VAFramesContext *hwctx = ctx->hwctx;
244  AVD3D12VADeviceContext *device_hwctx = ctx->device_ctx->hwctx;
245  AVBufferRef *buf;
246 
248 
249  DX_CHECK(ID3D12Device_CreateFence(device_hwctx->device, 0, D3D12_FENCE_FLAG_NONE,
250  &IID_ID3D12Fence, (void **)&frame->sync_ctx.fence));
251  frame->sync_ctx.event = CreateEvent(NULL, FALSE, FALSE, NULL);
252  if (!frame->sync_ctx.event)
253  goto fail;
254 
255  if (s->nb_surfaces_used >= ctx->initial_pool_size) {
256  av_log(ctx, AV_LOG_ERROR, "Static surface pool size exceeded.\n");
257  goto fail;
258  }
259 
260  frame->texture = hwctx->texture_array;
261  frame->subresource_index = s->nb_surfaces_used;
262 
263  buf = av_buffer_create((uint8_t *)frame, sizeof(*frame), free_texture, NULL, 0);
264 
265  if (!buf)
266  goto fail;
267 
268  s->nb_surfaces_used++;
269  return buf;
270 fail:
271  free_texture(NULL, (uint8_t *)frame);
272  return NULL;
273 }
274 
275 static AVBufferRef *d3d12va_pool_alloc(void *opaque, size_t size)
276 {
278  AVD3D12VAFramesContext *hwctx = ctx->hwctx;
279  AVD3D12VADeviceContext *device_hwctx = ctx->device_ctx->hwctx;
280 
281  AVBufferRef *buf;
283 
284  if (ctx->initial_pool_size > 0 && hwctx->flags & AV_D3D12VA_FRAME_FLAG_TEXTURE_ARRAY)
286 
287  D3D12_HEAP_PROPERTIES props = { .Type = D3D12_HEAP_TYPE_DEFAULT };
288  D3D12_RESOURCE_DESC desc = {
289  .Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D,
290  .Alignment = 0,
291  .Width = ctx->width,
292  .Height = ctx->height,
293  .DepthOrArraySize = 1,
294  .MipLevels = 1,
295  .Format = hwctx->format,
296  .SampleDesc = {.Count = 1, .Quality = 0 },
297  .Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN,
298  .Flags = hwctx->resource_flags,
299  };
300 
301  frame = av_mallocz(sizeof(AVD3D12VAFrame));
302  if (!frame)
303  return NULL;
304 
305  if (FAILED(ID3D12Device_CreateCommittedResource(device_hwctx->device, &props, hwctx->heap_flags, &desc,
306  D3D12_RESOURCE_STATE_COMMON, NULL, &IID_ID3D12Resource, (void **)&frame->texture))) {
307  av_log(ctx, AV_LOG_ERROR, "Could not create the texture\n");
308  goto fail;
309  }
310 
311  DX_CHECK(ID3D12Device_CreateFence(device_hwctx->device, 0, D3D12_FENCE_FLAG_NONE,
312  &IID_ID3D12Fence, (void **)&frame->sync_ctx.fence));
313 
314  frame->sync_ctx.event = CreateEvent(NULL, FALSE, FALSE, NULL);
315  if (!frame->sync_ctx.event)
316  goto fail;
317 
318  buf = av_buffer_create((uint8_t *)frame, sizeof(*frame), free_texture, NULL, 0);
319  if (!buf)
320  goto fail;
321 
322  return buf;
323 
324 fail:
325  free_texture(NULL, (uint8_t *)frame);
326  return NULL;
327 }
328 
330 {
331  AVD3D12VAFramesContext *hwctx = ctx->hwctx;
332  AVD3D12VADeviceContext *device_hwctx = ctx->device_ctx->hwctx;
333 
334  D3D12_HEAP_PROPERTIES props = { .Type = D3D12_HEAP_TYPE_DEFAULT };
335 
336  D3D12_RESOURCE_DESC desc = {
337  .Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D,
338  .Alignment = 0,
339  .Width = ctx->width,
340  .Height = ctx->height,
341  .DepthOrArraySize = ctx->initial_pool_size,
342  .MipLevels = 1,
343  .Format = hwctx->format,
344  .SampleDesc = {.Count = 1, .Quality = 0 },
345  .Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN,
346  .Flags = hwctx->resource_flags,
347  };
348 
349  if (FAILED(ID3D12Device_CreateCommittedResource(device_hwctx->device, &props, hwctx->heap_flags, &desc,
350  D3D12_RESOURCE_STATE_COMMON, NULL, &IID_ID3D12Resource, (void **)&hwctx->texture_array))) {
351  av_log(ctx, AV_LOG_ERROR, "Could not create the texture array\n");
352  return AVERROR(EINVAL);
353  }
354  return 0;
355 }
356 
358 {
359  AVD3D12VAFramesContext *hwctx = ctx->hwctx;
360  AVD3D12VADeviceContext *device_hwctx = ctx->device_ctx->hwctx;
361  int i;
362 
363  for (i = 0; i < FF_ARRAY_ELEMS(supported_formats); i++) {
364  if (ctx->sw_format == supported_formats[i].pix_fmt) {
365  if (hwctx->format != DXGI_FORMAT_UNKNOWN &&
366  hwctx->format != supported_formats[i].d3d_format)
367  av_log(ctx, AV_LOG_WARNING, "Incompatible DXGI format provided by user, will be overided\n");
368  hwctx->format = supported_formats[i].d3d_format;
369  break;
370  }
371  }
372 
374  av_log(ctx, AV_LOG_ERROR, "Unsupported pixel format: %s\n",
375  av_get_pix_fmt_name(ctx->sw_format));
376  return AVERROR(EINVAL);
377  }
378 
379  hwctx->resource_flags |= device_hwctx->resource_flags;
380  hwctx->heap_flags |= device_hwctx->heap_flags;
381 
382  if (ctx->initial_pool_size > 0 && hwctx->flags & AV_D3D12VA_FRAME_FLAG_TEXTURE_ARRAY) {
383  int err = d3d12va_texture_array_init(ctx);
384  if (err < 0)
385  return err;
386  }
387 
390 
391  if (!ffhwframesctx(ctx)->pool_internal)
392  return AVERROR(ENOMEM);
393 
394  return 0;
395 }
396 
398 {
399  int ret;
400 
401  frame->buf[0] = av_buffer_pool_get(ctx->pool);
402  if (!frame->buf[0])
403  return AVERROR(ENOMEM);
404 
405  ret = av_image_fill_arrays(frame->data, frame->linesize, NULL,
406  ctx->sw_format, ctx->width, ctx->height,
407  D3D12_TEXTURE_DATA_PITCH_ALIGNMENT);
408  if (ret < 0)
409  return ret;
410 
411  frame->data[0] = frame->buf[0]->data;
412  frame->format = AV_PIX_FMT_D3D12;
413  frame->width = ctx->width;
414  frame->height = ctx->height;
415 
416  return 0;
417 }
418 
421  enum AVPixelFormat **formats)
422 {
423  enum AVPixelFormat *fmts;
424 
425  fmts = av_malloc_array(2, sizeof(*fmts));
426  if (!fmts)
427  return AVERROR(ENOMEM);
428 
429  fmts[0] = ctx->sw_format;
430  fmts[1] = AV_PIX_FMT_NONE;
431 
432  *formats = fmts;
433 
434  return 0;
435 }
436 
438  const AVFrame *src)
439 {
440  AVD3D12VADeviceContext *hwctx = ctx->device_ctx->hwctx;
441  D3D12VAFramesContext *s = ctx->hwctx;
442  AVD3D12VAFramesContext *frames_hwctx = &s->p;
443 
444  int ret;
445  int download = src->format == AV_PIX_FMT_D3D12;
446  const AVFrame *frame = download ? src : dst;
447  const AVFrame *other = download ? dst : src;
448 
449  AVD3D12VAFrame *f = (AVD3D12VAFrame *)frame->data[0];
450  ID3D12Resource *texture = (ID3D12Resource *)f->texture;
451 
452  uint8_t *mapped_data;
453  uint8_t *data[4];
454  int linesizes[4];
455 
456  D3D12_TEXTURE_COPY_LOCATION staging_y_location = { 0 };
457  D3D12_TEXTURE_COPY_LOCATION staging_uv_location = { 0 };
458 
459  D3D12_TEXTURE_COPY_LOCATION texture_y_location = {
460  .pResource = texture,
461  .Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX,
462  .SubresourceIndex = 0,
463  };
464 
465  D3D12_TEXTURE_COPY_LOCATION texture_uv_location = {
466  .pResource = texture,
467  .Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX,
468  .SubresourceIndex = 1,
469  };
470 
471  D3D12_RESOURCE_BARRIER barrier = {
472  .Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION,
473  .Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE,
474  .Transition = {
475  .pResource = texture,
476  .StateBefore = D3D12_RESOURCE_STATE_COMMON,
477  .StateAfter = download ? D3D12_RESOURCE_STATE_COPY_SOURCE : D3D12_RESOURCE_STATE_COPY_DEST,
478  .Subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES,
479  },
480  };
481 
482  if (frame->hw_frames_ctx->data != (uint8_t *)ctx || other->format != ctx->sw_format)
483  return AVERROR(EINVAL);
484 
485  hwctx->lock(hwctx->lock_ctx);
486 
487  if (!s->command_queue) {
489  if (ret < 0)
490  goto fail;
491  }
492 
493  for (int i = 0; i < 4; i++)
494  linesizes[i] = FFALIGN(frame->width * (frames_hwctx->format != DXGI_FORMAT_NV12 ? 2 : 1),
495  D3D12_TEXTURE_DATA_PITCH_ALIGNMENT);
496 
497  staging_y_location = (D3D12_TEXTURE_COPY_LOCATION) {
498  .Type = D3D12_TEXTURE_COPY_TYPE_PLACED_FOOTPRINT,
499  .PlacedFootprint = {
500  .Offset = 0,
501  .Footprint = {
502  .Format = frames_hwctx->format != DXGI_FORMAT_NV12 ?
503  DXGI_FORMAT_R16_UNORM : DXGI_FORMAT_R8_UNORM,
504  .Width = ctx->width,
505  .Height = ctx->height,
506  .Depth = 1,
507  .RowPitch = linesizes[0],
508  },
509  },
510  };
511 
512  staging_uv_location = (D3D12_TEXTURE_COPY_LOCATION) {
513  .Type = D3D12_TEXTURE_COPY_TYPE_PLACED_FOOTPRINT,
514  .PlacedFootprint = {
515  .Offset = s->luma_component_size,
516  .Footprint = {
517  .Format = frames_hwctx->format != DXGI_FORMAT_NV12 ?
518  DXGI_FORMAT_R16G16_UNORM : DXGI_FORMAT_R8G8_UNORM,
519  .Width = ctx->width >> 1,
520  .Height = ctx->height >> 1,
521  .Depth = 1,
522  .RowPitch = linesizes[0],
523  },
524  },
525  };
526 
527  DX_CHECK(ID3D12CommandAllocator_Reset(s->command_allocator));
528 
529  DX_CHECK(ID3D12GraphicsCommandList_Reset(s->command_list, s->command_allocator, NULL));
530 
531  if (download) {
532  if (!s->staging_download_buffer) {
533  ret = d3d12va_create_staging_buffer_resource(ctx, D3D12_RESOURCE_STATE_COPY_DEST,
534  &s->staging_download_buffer, 1);
535  if (ret < 0) {
536  goto fail;
537  }
538  }
539 
540  staging_y_location.pResource = staging_uv_location.pResource = s->staging_download_buffer;
541 
542  ID3D12GraphicsCommandList_ResourceBarrier(s->command_list, 1, &barrier);
543 
544  ID3D12GraphicsCommandList_CopyTextureRegion(s->command_list,
545  &staging_y_location, 0, 0, 0,
546  &texture_y_location, NULL);
547 
548  ID3D12GraphicsCommandList_CopyTextureRegion(s->command_list,
549  &staging_uv_location, 0, 0, 0,
550  &texture_uv_location, NULL);
551 
552  barrier.Transition.StateBefore = barrier.Transition.StateAfter;
553  barrier.Transition.StateAfter = D3D12_RESOURCE_STATE_COMMON;
554  ID3D12GraphicsCommandList_ResourceBarrier(s->command_list, 1, &barrier);
555 
556  DX_CHECK(ID3D12GraphicsCommandList_Close(s->command_list));
557 
558  DX_CHECK(ID3D12CommandQueue_Wait(s->command_queue, f->sync_ctx.fence, f->sync_ctx.fence_value));
559 
560  ID3D12CommandQueue_ExecuteCommandLists(s->command_queue, 1, (ID3D12CommandList **)&s->command_list);
561 
562  ret = d3d12va_wait_queue_idle(&s->sync_ctx, s->command_queue);
563  if (ret < 0)
564  goto fail;
565 
566  DX_CHECK(ID3D12Resource_Map(s->staging_download_buffer, 0, NULL, (void **)&mapped_data));
567  av_image_fill_pointers(data, ctx->sw_format, ctx->height, mapped_data, linesizes);
568 
569  av_image_copy2(dst->data, dst->linesize, data, linesizes,
570  ctx->sw_format, ctx->width, ctx->height);
571 
572  ID3D12Resource_Unmap(s->staging_download_buffer, 0, NULL);
573  } else {
574  if (!s->staging_upload_buffer) {
575  ret = d3d12va_create_staging_buffer_resource(ctx, D3D12_RESOURCE_STATE_GENERIC_READ,
576  &s->staging_upload_buffer, 0);
577  if (ret < 0) {
578  goto fail;
579  }
580  }
581 
582  staging_y_location.pResource = staging_uv_location.pResource = s->staging_upload_buffer;
583 
584  DX_CHECK(ID3D12Resource_Map(s->staging_upload_buffer, 0, NULL, (void **)&mapped_data));
585  av_image_fill_pointers(data, ctx->sw_format, ctx->height, mapped_data, linesizes);
586 
587  av_image_copy2(data, linesizes, src->data, src->linesize,
588  ctx->sw_format, ctx->width, ctx->height);
589 
590  ID3D12Resource_Unmap(s->staging_upload_buffer, 0, NULL);
591 
592  ID3D12GraphicsCommandList_ResourceBarrier(s->command_list, 1, &barrier);
593 
594  ID3D12GraphicsCommandList_CopyTextureRegion(s->command_list,
595  &texture_y_location, 0, 0, 0,
596  &staging_y_location, NULL);
597 
598  ID3D12GraphicsCommandList_CopyTextureRegion(s->command_list,
599  &texture_uv_location, 0, 0, 0,
600  &staging_uv_location, NULL);
601 
602  barrier.Transition.StateBefore = barrier.Transition.StateAfter;
603  barrier.Transition.StateAfter = D3D12_RESOURCE_STATE_COMMON;
604  ID3D12GraphicsCommandList_ResourceBarrier(s->command_list, 1, &barrier);
605 
606  DX_CHECK(ID3D12GraphicsCommandList_Close(s->command_list));
607 
608  ID3D12CommandQueue_ExecuteCommandLists(s->command_queue, 1, (ID3D12CommandList **)&s->command_list);
609 
610  ret = d3d12va_wait_queue_idle(&s->sync_ctx, s->command_queue);
611  if (ret < 0)
612  goto fail;
613  }
614 
615  hwctx->unlock(hwctx->lock_ctx);
616 
617  return 0;
618 
619 fail:
620  hwctx->unlock(hwctx->lock_ctx);
621  return AVERROR(EINVAL);
622 }
623 
625 {
626  D3D12VADevicePriv *priv = hwdev->hwctx;
627 
628 #if !HAVE_UWP
629  priv->d3d12lib = dlopen("d3d12.dll", 0);
630  priv->dxgilib = dlopen("dxgi.dll", 0);
631 
632  if (!priv->d3d12lib || !priv->dxgilib)
633  goto fail;
634 
635  priv->create_device = (PFN_D3D12_CREATE_DEVICE)GetProcAddress(priv->d3d12lib, "D3D12CreateDevice");
636  if (!priv->create_device)
637  goto fail;
638 
639  priv->create_dxgi_factory2 = (PFN_CREATE_DXGI_FACTORY2)GetProcAddress(priv->dxgilib, "CreateDXGIFactory2");
640  if (!priv->create_dxgi_factory2)
641  goto fail;
642 
643  priv->get_debug_interface = (PFN_D3D12_GET_DEBUG_INTERFACE)GetProcAddress(priv->d3d12lib, "D3D12GetDebugInterface");
644 #else
645  priv->create_device = (PFN_D3D12_CREATE_DEVICE) D3D12CreateDevice;
646  priv->create_dxgi_factory2 = (PFN_CREATE_DXGI_FACTORY2) CreateDXGIFactory2;
647  priv->get_debug_interface = (PFN_D3D12_GET_DEBUG_INTERFACE) D3D12GetDebugInterface;
648 #endif
649  return 0;
650 
651 fail:
652  av_log(hwdev, AV_LOG_ERROR, "Failed to load D3D12 library or its functions\n");
653  return AVERROR_UNKNOWN;
654 }
655 
657 {
658  D3D12VADevicePriv *priv = hwdev->hwctx;
659  AVD3D12VADeviceContext *ctx = &priv->p;
660 
661  D3D12_OBJECT_RELEASE(ctx->device);
662 
663  if (priv->d3d12lib)
664  dlclose(priv->d3d12lib);
665 
666  if (priv->dxgilib)
667  dlclose(priv->dxgilib);
668 }
669 
671 {
672  AVD3D12VADeviceContext *ctx = hwdev->hwctx;
673 
674  if (!ctx->lock) {
675  ctx->lock_ctx = CreateMutex(NULL, 0, NULL);
676  if (ctx->lock_ctx == INVALID_HANDLE_VALUE) {
677  av_log(NULL, AV_LOG_ERROR, "Failed to create a mutex\n");
678  return AVERROR(EINVAL);
679  }
680  ctx->lock = d3d12va_default_lock;
681  ctx->unlock = d3d12va_default_unlock;
682  }
683 
684  if (!ctx->video_device)
685  DX_CHECK(ID3D12Device_QueryInterface(ctx->device, &IID_ID3D12VideoDevice, (void **)&ctx->video_device));
686 
687  return 0;
688 
689 fail:
690  return AVERROR(EINVAL);
691 }
692 
694 {
695  AVD3D12VADeviceContext *device_hwctx = hwdev->hwctx;
696 
697  D3D12_OBJECT_RELEASE(device_hwctx->video_device);
698 
699  if (device_hwctx->lock == d3d12va_default_lock) {
700  CloseHandle(device_hwctx->lock_ctx);
701  device_hwctx->lock_ctx = INVALID_HANDLE_VALUE;
702  device_hwctx->lock = NULL;
703  }
704 }
705 
706 static int d3d12va_device_create(AVHWDeviceContext *hwdev, const char *device,
707  AVDictionary *opts, int flags)
708 {
709  D3D12VADevicePriv *priv = hwdev->hwctx;
710  AVD3D12VADeviceContext *ctx = &priv->p;
711 
712  HRESULT hr;
713  UINT create_flags = 0;
714  IDXGIAdapter *pAdapter = NULL;
715 
716  int ret;
717  int is_debug = !!av_dict_get(opts, "debug", NULL, 0);
718 
719  hwdev->free = d3d12va_device_free;
720 
721  ret = d3d12va_load_functions(hwdev);
722  if (ret < 0)
723  return ret;
724 
725  if (is_debug) {
726  ID3D12Debug *pDebug;
727  if (priv->get_debug_interface && SUCCEEDED(priv->get_debug_interface(&IID_ID3D12Debug, (void **)&pDebug))) {
728  create_flags |= DXGI_CREATE_FACTORY_DEBUG;
729  ID3D12Debug_EnableDebugLayer(pDebug);
730  D3D12_OBJECT_RELEASE(pDebug);
731  av_log(hwdev, AV_LOG_INFO, "D3D12 debug layer is enabled!\n");
732  }
733  }
734 
735  if (!ctx->device) {
736  IDXGIFactory2 *pDXGIFactory = NULL;
737 
738  hr = priv->create_dxgi_factory2(create_flags, &IID_IDXGIFactory2, (void **)&pDXGIFactory);
739  if (SUCCEEDED(hr)) {
740  int adapter = device ? atoi(device) : 0;
741  if (FAILED(IDXGIFactory2_EnumAdapters(pDXGIFactory, adapter, &pAdapter)))
742  pAdapter = NULL;
743  IDXGIFactory2_Release(pDXGIFactory);
744  }
745 
746  if (pAdapter) {
747  DXGI_ADAPTER_DESC desc;
748  hr = IDXGIAdapter2_GetDesc(pAdapter, &desc);
749  if (!FAILED(hr)) {
750  av_log(hwdev, AV_LOG_INFO, "Using device %04x:%04x (%ls).\n",
751  desc.VendorId, desc.DeviceId, desc.Description);
752  }
753  }
754 
755  hr = priv->create_device((IUnknown *)pAdapter, D3D_FEATURE_LEVEL_12_0, &IID_ID3D12Device, (void **)&ctx->device);
756  D3D12_OBJECT_RELEASE(pAdapter);
757  if (FAILED(hr)) {
758  av_log(hwdev, AV_LOG_ERROR, "Failed to create Direct 3D 12 device (%lx)\n", (long)hr);
759  return AVERROR_UNKNOWN;
760  }
761  }
762 
763  if (av_dict_get(opts, "UAV", NULL, 0))
764  ctx->resource_flags |= D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS;
765 
766  if (av_dict_get(opts, "RTV", NULL, 0))
767  ctx->resource_flags |= D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET;
768 
769  if (av_dict_get(opts, "SHARED", NULL, 0))
770  ctx->heap_flags |= D3D12_HEAP_FLAG_SHARED;
771 
772  return 0;
773 }
774 
777  .name = "D3D12VA",
778 
779  .device_hwctx_size = sizeof(D3D12VADevicePriv),
780  .frames_hwctx_size = sizeof(D3D12VAFramesContext),
781 
782  .device_create = d3d12va_device_create,
783  .device_init = d3d12va_device_init,
784  .device_uninit = d3d12va_device_uninit,
785  .frames_get_constraints = d3d12va_frames_get_constraints,
786  .frames_init = d3d12va_frames_init,
787  .frames_uninit = d3d12va_frames_uninit,
788  .frames_get_buffer = d3d12va_get_buffer,
789  .transfer_get_formats = d3d12va_transfer_get_formats,
790  .transfer_data_to = d3d12va_transfer_data,
791  .transfer_data_from = d3d12va_transfer_data,
792 
793  .pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_D3D12, AV_PIX_FMT_NONE },
794 };
formats
formats
Definition: signature.h:47
AVHWDeviceContext::hwctx
void * hwctx
The format-specific data, allocated and freed by libavutil along with this context.
Definition: hwcontext.h:88
FFHWFramesContext::pool_internal
AVBufferPool * pool_internal
Definition: hwcontext_internal.h:101
AVD3D12VADeviceContext::device
ID3D12Device * device
Device used for objects creation and access.
Definition: hwcontext_d3d12va.h:54
AVD3D12VAFramesContext::flags
AVD3D12VAFrameFlags flags
A combination of AVD3D12VAFrameFlags.
Definition: hwcontext_d3d12va.h:206
AV_LOG_WARNING
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:216
d3d12va_transfer_data
static int d3d12va_transfer_data(AVHWFramesContext *ctx, AVFrame *dst, const AVFrame *src)
Definition: hwcontext_d3d12va.c:437
AVPixelFormat
AVPixelFormat
Pixel format.
Definition: pixfmt.h:71
AVERROR
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later. That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another. Frame references ownership and permissions
supported_formats
static const struct @546 supported_formats[]
AVD3D12VADeviceContext::lock_ctx
void * lock_ctx
Definition: hwcontext_d3d12va.h:77
thread.h
d3d12va_frames_get_constraints
static int d3d12va_frames_get_constraints(AVHWDeviceContext *ctx, const void *hwconfig, AVHWFramesConstraints *constraints)
Definition: hwcontext_d3d12va.c:196
AVD3D12VADeviceContext::heap_flags
D3D12_HEAP_FLAGS heap_flags
Heap flags to be applied to D3D12 resources allocated for frames using this device context.
Definition: hwcontext_d3d12va.h:97
AVFrame
This structure describes decoded (raw) audio or video data.
Definition: frame.h:472
pixdesc.h
D3D12VADevicePriv
Definition: hwcontext_d3d12va.c:55
data
const char data[16]
Definition: mxf.c:149
d3d12va_device_create
static int d3d12va_device_create(AVHWDeviceContext *hwdev, const char *device, AVDictionary *opts, int flags)
Definition: hwcontext_d3d12va.c:706
D3D12VAFramesContext::sync_ctx
AVD3D12VASyncContext sync_ctx
Definition: hwcontext_d3d12va.c:50
AVDictionary
Definition: dict.c:32
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:449
AVERROR_UNKNOWN
#define AVERROR_UNKNOWN
Unknown error, typically from an external library.
Definition: error.h:73
D3D12VAFramesContext::staging_download_buffer
ID3D12Resource * staging_download_buffer
Definition: hwcontext_d3d12va.c:45
d3d_format
DXGI_FORMAT d3d_format
Definition: hwcontext_d3d12va.c:68
AVHWFramesConstraints
This struct describes the constraints on hardware frames attached to a given device with a hardware-s...
Definition: hwcontext.h:444
D3D12VADevicePriv::d3d12lib
HANDLE d3d12lib
Definition: hwcontext_d3d12va.c:60
AVHWDeviceContext::free
void(* free)(struct AVHWDeviceContext *ctx)
This field may be set by the caller before calling av_hwdevice_ctx_init().
Definition: hwcontext.h:100
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
D3D12VADevicePriv::get_debug_interface
PFN_D3D12_GET_DEBUG_INTERFACE get_debug_interface
Definition: hwcontext_d3d12va.c:64
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
d3d12va_default_unlock
static void d3d12va_default_unlock(void *ctx)
Definition: hwcontext_d3d12va.c:81
d3d12va_texture_array_init
static int d3d12va_texture_array_init(AVHWFramesContext *ctx)
Definition: hwcontext_d3d12va.c:329
AVHWDeviceContext
This struct aggregates all the (hardware/vendor-specific) "high-level" state, i.e.
Definition: hwcontext.h:63
HWContextType::type
enum AVHWDeviceType type
Definition: hwcontext_internal.h:30
ffhwframesctx
static FFHWFramesContext * ffhwframesctx(AVHWFramesContext *ctx)
Definition: hwcontext_internal.h:115
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:210
FF_ARRAY_ELEMS
#define FF_ARRAY_ELEMS(a)
Definition: sinewin_tablegen.c:29
AVHWFramesConstraints::valid_sw_formats
enum AVPixelFormat * valid_sw_formats
A list of possible values for sw_format in the hw_frames_ctx, terminated by AV_PIX_FMT_NONE.
Definition: hwcontext.h:456
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:60
av_buffer_pool_get
AVBufferRef * av_buffer_pool_get(AVBufferPool *pool)
Allocate a new AVBuffer, reusing an old buffer from the pool when available.
Definition: buffer.c:390
flags
#define flags(name, subs,...)
Definition: cbs_av1.c:504
d3d12va_device_init
static int d3d12va_device_init(AVHWDeviceContext *hwdev)
Definition: hwcontext_d3d12va.c:670
D3D12_OBJECT_RELEASE
#define D3D12_OBJECT_RELEASE(pInterface)
A release macro used by D3D12 objects highly frequently.
Definition: hwcontext_d3d12va_internal.h:51
d3d12va_pool_alloc
static AVBufferRef * d3d12va_pool_alloc(void *opaque, size_t size)
Definition: hwcontext_d3d12va.c:275
AVD3D12VADeviceContext::unlock
void(* unlock)(void *lock_ctx)
Definition: hwcontext_d3d12va.h:76
AVD3D12VAFramesContext::texture_array
ID3D12Resource * texture_array
In texture array mode, the D3D12 uses the same texture array (resource)for all pictures.
Definition: hwcontext_d3d12va.h:199
ctx
static AVFormatContext * ctx
Definition: movenc.c:49
AVD3D12VASyncContext
This struct is used to sync d3d12 execution.
Definition: hwcontext_d3d12va.h:104
av_mallocz
#define av_mallocz(s)
Definition: tableprint_vlc.h:31
AVD3D12VASyncContext::fence
ID3D12Fence * fence
D3D12 fence object.
Definition: hwcontext_d3d12va.h:108
fail
#define fail
Definition: test.h:478
opts
static AVDictionary * opts
Definition: movenc.c:51
D3D12VAFramesContext::staging_upload_buffer
ID3D12Resource * staging_upload_buffer
Definition: hwcontext_d3d12va.c:46
d3d12va_pool_alloc_texture_array
static AVBufferRef * d3d12va_pool_alloc_texture_array(AVHWFramesContext *ctx)
Definition: hwcontext_d3d12va.c:239
NULL
#define NULL
Definition: coverity.c:32
AVD3D12VAFramesContext::heap_flags
D3D12_HEAP_FLAGS heap_flags
Options for working with heaps allocation when creating resources.
Definition: hwcontext_d3d12va.h:193
d3d12va_device_free
static void d3d12va_device_free(AVHWDeviceContext *hwdev)
Definition: hwcontext_d3d12va.c:656
AVD3D12VAFramesContext
This struct is allocated as AVHWFramesContext.hwctx.
Definition: hwcontext_d3d12va.h:172
AV_PIX_FMT_D3D12
@ AV_PIX_FMT_D3D12
Hardware surfaces for Direct3D 12.
Definition: pixfmt.h:440
hwcontext_d3d12va.h
AVD3D12VAFramesContext::resource_flags
D3D12_RESOURCE_FLAGS resource_flags
Options for working with resources.
Definition: hwcontext_d3d12va.h:185
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
AVD3D12VADeviceContext::video_device
ID3D12VideoDevice * video_device
If unset, this will be set from the device field on init.
Definition: hwcontext_d3d12va.h:62
f
f
Definition: af_crystalizer.c:122
AV_HWDEVICE_TYPE_D3D12VA
@ AV_HWDEVICE_TYPE_D3D12VA
Definition: hwcontext.h:40
av_image_fill_arrays
int av_image_fill_arrays(uint8_t *dst_data[4], int dst_linesize[4], const uint8_t *src, enum AVPixelFormat pix_fmt, int width, int height, int align)
Setup the data pointers and linesizes based on the specified image parameters and the provided array.
Definition: imgutils.c:446
AV_PIX_FMT_P012
#define AV_PIX_FMT_P012
Definition: pixfmt.h:609
dst
uint8_t ptrdiff_t const uint8_t ptrdiff_t int intptr_t intptr_t int int16_t * dst
Definition: dsp.h:87
i
#define i(width, name, range_min, range_max)
Definition: cbs_h264.c:63
d3d12va_fence_completion
static int d3d12va_fence_completion(AVD3D12VASyncContext *psync_ctx)
Definition: hwcontext_d3d12va.c:86
size
int size
Definition: twinvq_data.h:10344
free_texture
static void free_texture(void *opaque, uint8_t *data)
Definition: hwcontext_d3d12va.c:225
D3D12VAFramesContext::p
AVD3D12VAFramesContext p
The public AVD3D12VAFramesContext.
Definition: hwcontext_d3d12va.c:43
AVFrame::format
int format
format of the frame, -1 if unknown or unset Values correspond to enum AVPixelFormat for video frames,...
Definition: frame.h:559
D3D12VADevicePriv::p
AVD3D12VADeviceContext p
The public AVD3D12VADeviceContext.
Definition: hwcontext_d3d12va.c:59
d3d12va_frames_init
static int d3d12va_frames_init(AVHWFramesContext *ctx)
Definition: hwcontext_d3d12va.c:357
D3D12VAFramesContext::nb_surfaces_used
int nb_surfaces_used
Definition: hwcontext_d3d12va.c:52
AVD3D12VAFrame
D3D12VA frame descriptor for pool allocation.
Definition: hwcontext_d3d12va.h:138
AV_LOG_INFO
#define AV_LOG_INFO
Standard information.
Definition: log.h:221
D3D12VADevicePriv::create_dxgi_factory2
PFN_CREATE_DXGI_FACTORY2 create_dxgi_factory2
Definition: hwcontext_d3d12va.c:62
d3d12va_load_functions
static int d3d12va_load_functions(AVHWDeviceContext *hwdev)
Definition: hwcontext_d3d12va.c:624
D3D12VAFramesContext::command_allocator
ID3D12CommandAllocator * command_allocator
Definition: hwcontext_d3d12va.c:48
AVD3D12VADeviceContext
This struct is allocated as AVHWDeviceContext.hwctx.
Definition: hwcontext_d3d12va.h:43
AV_D3D12VA_FRAME_FLAG_TEXTURE_ARRAY
@ AV_D3D12VA_FRAME_FLAG_TEXTURE_ARRAY
Indicates that frame data should be allocated using a texture array resource.
Definition: hwcontext_d3d12va.h:131
av_malloc_array
#define av_malloc_array(a, b)
Definition: tableprint_vlc.h:32
common.h
s
uint8_t s
Definition: llvidencdsp.c:39
d3d12va_frames_uninit
static void d3d12va_frames_uninit(AVHWFramesContext *ctx)
Definition: hwcontext_d3d12va.c:177
AVHWFrameTransferDirection
AVHWFrameTransferDirection
Definition: hwcontext.h:406
d3d12va_default_lock
static void d3d12va_default_lock(void *ctx)
Definition: hwcontext_d3d12va.c:76
AVD3D12VAFramesContext::format
DXGI_FORMAT format
DXGI_FORMAT format.
Definition: hwcontext_d3d12va.h:177
AVHWFramesContext
This struct describes a set or pool of "hardware" frames (i.e.
Definition: hwcontext.h:118
D3D12VADevicePriv::create_device
PFN_D3D12_CREATE_DEVICE create_device
Definition: hwcontext_d3d12va.c:63
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:96
frame
these buffered frames must be flushed immediately if a new input produces new the filter must not call request_frame to get more It must just process the frame or queue it The task of requesting more frames is left to the filter s request_frame method or the application If a filter has several the filter must be ready for frames arriving randomly on any input any filter with several inputs will most likely require some kind of queuing mechanism It is perfectly acceptable to have a limited queue and to drop frames when the inputs are too unbalanced request_frame For filters that do not use the this method is called when a frame is wanted on an output For a it should directly call filter_frame on the corresponding output For a if there are queued frames already one of these frames should be pushed If the filter should request a frame on one of its repeatedly until at least one frame has been pushed Return or at least make progress towards producing a frame
Definition: filter_design.txt:265
D3D12VADevicePriv::dxgilib
HANDLE dxgilib
Definition: hwcontext_d3d12va.c:61
d3d12va_wait_queue_idle
static int d3d12va_wait_queue_idle(AVD3D12VASyncContext *psync_ctx, ID3D12CommandQueue *command_queue)
Definition: hwcontext_d3d12va.c:99
d3d12va_get_buffer
static int d3d12va_get_buffer(AVHWFramesContext *ctx, AVFrame *frame)
Definition: hwcontext_d3d12va.c:397
ff_hwcontext_type_d3d12va
const HWContextType ff_hwcontext_type_d3d12va
Definition: hwcontext_d3d12va.c:775
AVD3D12VASyncContext::event
HANDLE event
A handle to the event object that's raised when the fence reaches a certain value.
Definition: hwcontext_d3d12va.h:114
D3D12VAFramesContext
Definition: hwcontext_d3d12va.c:39
D3D12VAFramesContext::command_list
ID3D12GraphicsCommandList * command_list
Definition: hwcontext_d3d12va.c:49
av_image_copy2
static void av_image_copy2(uint8_t *const dst_data[4], const int dst_linesizes[4], uint8_t *const src_data[4], const int src_linesizes[4], enum AVPixelFormat pix_fmt, int width, int height)
Wrapper around av_image_copy() to workaround the limitation that the conversion from uint8_t * const ...
Definition: imgutils.h:184
AV_PIX_FMT_NONE
@ AV_PIX_FMT_NONE
Definition: pixfmt.h:72
d3d12va_create_staging_buffer_resource
static int d3d12va_create_staging_buffer_resource(AVHWFramesContext *ctx, D3D12_RESOURCE_STATES states, ID3D12Resource **ppResource, int download)
Definition: hwcontext_d3d12va.c:108
pix_fmt
enum AVPixelFormat pix_fmt
Definition: hwcontext_d3d12va.c:69
AVD3D12VADeviceContext::lock
void(* lock)(void *lock_ctx)
Callbacks for locking.
Definition: hwcontext_d3d12va.h:75
AV_PIX_FMT_P010
#define AV_PIX_FMT_P010
Definition: pixfmt.h:608
D3D12VAFramesContext::luma_component_size
UINT luma_component_size
Definition: hwcontext_d3d12va.c:51
desc
const char * desc
Definition: libsvtav1.c:83
mem.h
AVBufferRef
A reference to a data buffer.
Definition: buffer.h:82
hwcontext_internal.h
FFALIGN
#define FFALIGN(x, a)
Definition: macros.h:78
PFN_CREATE_DXGI_FACTORY2
HRESULT(WINAPI * PFN_CREATE_DXGI_FACTORY2)(UINT Flags, REFIID riid, void **ppFactory)
Definition: hwcontext_d3d12va.c:37
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:35
imgutils.h
hwcontext.h
DX_CHECK
#define DX_CHECK(hr)
A check macro used by D3D12 functions highly frequently.
Definition: hwcontext_d3d12va_internal.h:40
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:27
HWContextType
Definition: hwcontext_internal.h:29
AVD3D12VASyncContext::fence_value
uint64_t fence_value
The fence value used for sync.
Definition: hwcontext_d3d12va.h:119
D3D12VAFramesContext::command_queue
ID3D12CommandQueue * command_queue
Definition: hwcontext_d3d12va.c:47
hwcontext_d3d12va_internal.h
d3d12va_create_helper_objects
static int d3d12va_create_helper_objects(AVHWFramesContext *ctx)
Definition: hwcontext_d3d12va.c:136
src
#define src
Definition: vp8dsp.c:248
d3d12va_transfer_get_formats
static int d3d12va_transfer_get_formats(AVHWFramesContext *ctx, enum AVHWFrameTransferDirection dir, enum AVPixelFormat **formats)
Definition: hwcontext_d3d12va.c:419
w32dlfcn.h
d3d12va_device_uninit
static void d3d12va_device_uninit(AVHWDeviceContext *hwdev)
Definition: hwcontext_d3d12va.c:693
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:3380
AVD3D12VADeviceContext::resource_flags
D3D12_RESOURCE_FLAGS resource_flags
Resource flags to be applied to D3D12 resources allocated for frames using this device context.
Definition: hwcontext_d3d12va.h:87