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 };
74 
75 static void d3d12va_default_lock(void *ctx)
76 {
77  WaitForSingleObjectEx(ctx, INFINITE, FALSE);
78 }
79 
80 static void d3d12va_default_unlock(void *ctx)
81 {
82  ReleaseMutex(ctx);
83 }
84 
86 {
87  uint64_t completion = ID3D12Fence_GetCompletedValue(psync_ctx->fence);
88  if (completion < psync_ctx->fence_value) {
89  if (FAILED(ID3D12Fence_SetEventOnCompletion(psync_ctx->fence, psync_ctx->fence_value, psync_ctx->event)))
90  return AVERROR(EINVAL);
91 
92  WaitForSingleObjectEx(psync_ctx->event, INFINITE, FALSE);
93  }
94 
95  return 0;
96 }
97 
98 static inline int d3d12va_wait_queue_idle(AVD3D12VASyncContext *psync_ctx, ID3D12CommandQueue *command_queue)
99 {
100  DX_CHECK(ID3D12CommandQueue_Signal(command_queue, psync_ctx->fence, ++psync_ctx->fence_value));
101  return d3d12va_fence_completion(psync_ctx);
102 
103 fail:
104  return AVERROR(EINVAL);
105 }
106 
107 static int d3d12va_create_staging_buffer_resource(AVHWFramesContext *ctx, D3D12_RESOURCE_STATES states,
108  ID3D12Resource **ppResource, int download)
109 {
110  AVD3D12VADeviceContext *device_hwctx = ctx->device_ctx->hwctx;
111  D3D12VAFramesContext *s = ctx->hwctx;
112  D3D12_HEAP_PROPERTIES props = { .Type = download ? D3D12_HEAP_TYPE_READBACK : D3D12_HEAP_TYPE_UPLOAD };
113  D3D12_RESOURCE_DESC desc = {
114  .Dimension = D3D12_RESOURCE_DIMENSION_BUFFER,
115  .Alignment = 0,
116  .Width = s->luma_component_size + (s->luma_component_size >> 1),
117  .Height = 1,
118  .DepthOrArraySize = 1,
119  .MipLevels = 1,
120  .Format = DXGI_FORMAT_UNKNOWN,
121  .SampleDesc = { .Count = 1, .Quality = 0 },
122  .Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR,
123  .Flags = D3D12_RESOURCE_FLAG_NONE,
124  };
125 
126  if (FAILED(ID3D12Device_CreateCommittedResource(device_hwctx->device, &props, D3D12_HEAP_FLAG_NONE, &desc,
127  states, NULL, &IID_ID3D12Resource, (void **)ppResource))) {
128  av_log(ctx, AV_LOG_ERROR, "Could not create the staging buffer resource\n");
129  return AVERROR_UNKNOWN;
130  }
131 
132  return 0;
133 }
134 
136 {
137  AVD3D12VADeviceContext *device_hwctx = ctx->device_ctx->hwctx;
138  D3D12VAFramesContext *s = ctx->hwctx;
139  AVD3D12VAFramesContext *frames_hwctx = &s->p;
140 
141  D3D12_COMMAND_QUEUE_DESC queue_desc = {
142  .Type = D3D12_COMMAND_LIST_TYPE_COPY,
143  .Priority = 0,
144  .NodeMask = 0,
145  };
146 
147  s->luma_component_size = FFALIGN(ctx->width * (frames_hwctx->format == DXGI_FORMAT_P010 ? 2 : 1),
148  D3D12_TEXTURE_DATA_PITCH_ALIGNMENT) * ctx->height;
149 
150  DX_CHECK(ID3D12Device_CreateFence(device_hwctx->device, 0, D3D12_FENCE_FLAG_NONE,
151  &IID_ID3D12Fence, (void **)&s->sync_ctx.fence));
152 
153  s->sync_ctx.event = CreateEvent(NULL, FALSE, FALSE, NULL);
154  if (!s->sync_ctx.event)
155  goto fail;
156 
157  DX_CHECK(ID3D12Device_CreateCommandQueue(device_hwctx->device, &queue_desc,
158  &IID_ID3D12CommandQueue, (void **)&s->command_queue));
159 
160  DX_CHECK(ID3D12Device_CreateCommandAllocator(device_hwctx->device, queue_desc.Type,
161  &IID_ID3D12CommandAllocator, (void **)&s->command_allocator));
162 
163  DX_CHECK(ID3D12Device_CreateCommandList(device_hwctx->device, 0, queue_desc.Type,
164  s->command_allocator, NULL, &IID_ID3D12GraphicsCommandList, (void **)&s->command_list));
165 
166  DX_CHECK(ID3D12GraphicsCommandList_Close(s->command_list));
167 
168  ID3D12CommandQueue_ExecuteCommandLists(s->command_queue, 1, (ID3D12CommandList **)&s->command_list);
169 
170  return d3d12va_wait_queue_idle(&s->sync_ctx, s->command_queue);
171 
172 fail:
173  return AVERROR(EINVAL);
174 }
175 
177 {
178  D3D12VAFramesContext *s = ctx->hwctx;
179  AVD3D12VAFramesContext *hwctx = ctx->hwctx;
180 
181  D3D12_OBJECT_RELEASE(s->sync_ctx.fence);
182  if (s->sync_ctx.event)
183  CloseHandle(s->sync_ctx.event);
184 
185  D3D12_OBJECT_RELEASE(s->staging_download_buffer);
186  D3D12_OBJECT_RELEASE(s->staging_upload_buffer);
187  D3D12_OBJECT_RELEASE(s->command_allocator);
188  D3D12_OBJECT_RELEASE(s->command_list);
189  D3D12_OBJECT_RELEASE(s->command_queue);
190 
191  if (hwctx->texture_array)
193 }
194 
195 static int d3d12va_frames_get_constraints(AVHWDeviceContext *ctx, const void *hwconfig, AVHWFramesConstraints *constraints)
196 {
197  HRESULT hr;
198  int nb_sw_formats = 0;
199  AVD3D12VADeviceContext *device_hwctx = ctx->hwctx;
200 
202  sizeof(*constraints->valid_sw_formats));
203  if (!constraints->valid_sw_formats)
204  return AVERROR(ENOMEM);
205 
206  for (int i = 0; i < FF_ARRAY_ELEMS(supported_formats); i++) {
207  D3D12_FEATURE_DATA_FORMAT_SUPPORT format_support = { supported_formats[i].d3d_format };
208  hr = ID3D12Device_CheckFeatureSupport(device_hwctx->device, D3D12_FEATURE_FORMAT_SUPPORT, &format_support, sizeof(format_support));
209  if (SUCCEEDED(hr) && (format_support.Support1 & D3D12_FORMAT_SUPPORT1_TEXTURE2D))
210  constraints->valid_sw_formats[nb_sw_formats++] = supported_formats[i].pix_fmt;
211  }
212  constraints->valid_sw_formats[nb_sw_formats] = AV_PIX_FMT_NONE;
213 
214  constraints->valid_hw_formats = av_malloc_array(2, sizeof(*constraints->valid_hw_formats));
215  if (!constraints->valid_hw_formats)
216  return AVERROR(ENOMEM);
217 
218  constraints->valid_hw_formats[0] = AV_PIX_FMT_D3D12;
219  constraints->valid_hw_formats[1] = AV_PIX_FMT_NONE;
220 
221  return 0;
222 }
223 
224 static void free_texture(void *opaque, uint8_t *data)
225 {
227 
229  D3D12_OBJECT_RELEASE(frame->texture);
230 
231  D3D12_OBJECT_RELEASE(frame->sync_ctx.fence);
232  if (frame->sync_ctx.event)
233  CloseHandle(frame->sync_ctx.event);
234 
235  av_freep(&data);
236 }
237 
239 {
240  AVD3D12VAFrame *frame = av_mallocz(sizeof(*frame));
241  D3D12VAFramesContext *s = ctx->hwctx;
242  AVD3D12VAFramesContext *hwctx = ctx->hwctx;
243  AVD3D12VADeviceContext *device_hwctx = ctx->device_ctx->hwctx;
244  AVBufferRef *buf;
245 
247 
248  DX_CHECK(ID3D12Device_CreateFence(device_hwctx->device, 0, D3D12_FENCE_FLAG_NONE,
249  &IID_ID3D12Fence, (void **)&frame->sync_ctx.fence));
250  frame->sync_ctx.event = CreateEvent(NULL, FALSE, FALSE, NULL);
251  if (!frame->sync_ctx.event)
252  goto fail;
253 
254  if (s->nb_surfaces_used >= ctx->initial_pool_size) {
255  av_log(ctx, AV_LOG_ERROR, "Static surface pool size exceeded.\n");
256  goto fail;
257  }
258 
259  frame->texture = hwctx->texture_array;
260  frame->subresource_index = s->nb_surfaces_used;
261 
262  buf = av_buffer_create((uint8_t *)frame, sizeof(*frame), free_texture, NULL, 0);
263 
264  if (!buf)
265  goto fail;
266 
267  s->nb_surfaces_used++;
268  return buf;
269 fail:
270  free_texture(NULL, (uint8_t *)frame);
271  return NULL;
272 }
273 
274 static AVBufferRef *d3d12va_pool_alloc(void *opaque, size_t size)
275 {
277  AVD3D12VAFramesContext *hwctx = ctx->hwctx;
278  AVD3D12VADeviceContext *device_hwctx = ctx->device_ctx->hwctx;
279 
280  AVBufferRef *buf;
282 
283  if (ctx->initial_pool_size > 0 && hwctx->flags & AV_D3D12VA_FRAME_FLAG_TEXTURE_ARRAY)
285 
286  D3D12_HEAP_PROPERTIES props = { .Type = D3D12_HEAP_TYPE_DEFAULT };
287  D3D12_RESOURCE_DESC desc = {
288  .Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D,
289  .Alignment = 0,
290  .Width = ctx->width,
291  .Height = ctx->height,
292  .DepthOrArraySize = 1,
293  .MipLevels = 1,
294  .Format = hwctx->format,
295  .SampleDesc = {.Count = 1, .Quality = 0 },
296  .Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN,
297  .Flags = hwctx->resource_flags,
298  };
299 
300  frame = av_mallocz(sizeof(AVD3D12VAFrame));
301  if (!frame)
302  return NULL;
303 
304  if (FAILED(ID3D12Device_CreateCommittedResource(device_hwctx->device, &props, hwctx->heap_flags, &desc,
305  D3D12_RESOURCE_STATE_COMMON, NULL, &IID_ID3D12Resource, (void **)&frame->texture))) {
306  av_log(ctx, AV_LOG_ERROR, "Could not create the texture\n");
307  goto fail;
308  }
309 
310  DX_CHECK(ID3D12Device_CreateFence(device_hwctx->device, 0, D3D12_FENCE_FLAG_NONE,
311  &IID_ID3D12Fence, (void **)&frame->sync_ctx.fence));
312 
313  frame->sync_ctx.event = CreateEvent(NULL, FALSE, FALSE, NULL);
314  if (!frame->sync_ctx.event)
315  goto fail;
316 
317  buf = av_buffer_create((uint8_t *)frame, sizeof(frame), free_texture, NULL, 0);
318  if (!buf)
319  goto fail;
320 
321  return buf;
322 
323 fail:
324  free_texture(NULL, (uint8_t *)frame);
325  return NULL;
326 }
327 
329 {
330  AVD3D12VAFramesContext *hwctx = ctx->hwctx;
331  AVD3D12VADeviceContext *device_hwctx = ctx->device_ctx->hwctx;
332 
333  D3D12_HEAP_PROPERTIES props = { .Type = D3D12_HEAP_TYPE_DEFAULT };
334 
335  D3D12_RESOURCE_DESC desc = {
336  .Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D,
337  .Alignment = 0,
338  .Width = ctx->width,
339  .Height = ctx->height,
340  .DepthOrArraySize = ctx->initial_pool_size,
341  .MipLevels = 1,
342  .Format = hwctx->format,
343  .SampleDesc = {.Count = 1, .Quality = 0 },
344  .Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN,
345  .Flags = hwctx->resource_flags,
346  };
347 
348  if (FAILED(ID3D12Device_CreateCommittedResource(device_hwctx->device, &props, hwctx->heap_flags, &desc,
349  D3D12_RESOURCE_STATE_COMMON, NULL, &IID_ID3D12Resource, (void **)&hwctx->texture_array))) {
350  av_log(ctx, AV_LOG_ERROR, "Could not create the texture array\n");
351  return AVERROR(EINVAL);
352  }
353  return 0;
354 }
355 
357 {
358  AVD3D12VAFramesContext *hwctx = ctx->hwctx;
359  AVD3D12VADeviceContext *device_hwctx = ctx->device_ctx->hwctx;
360  int i;
361 
362  for (i = 0; i < FF_ARRAY_ELEMS(supported_formats); i++) {
363  if (ctx->sw_format == supported_formats[i].pix_fmt) {
364  if (hwctx->format != DXGI_FORMAT_UNKNOWN &&
365  hwctx->format != supported_formats[i].d3d_format)
366  av_log(ctx, AV_LOG_WARNING, "Incompatible DXGI format provided by user, will be overided\n");
367  hwctx->format = supported_formats[i].d3d_format;
368  break;
369  }
370  }
371 
373  av_log(ctx, AV_LOG_ERROR, "Unsupported pixel format: %s\n",
374  av_get_pix_fmt_name(ctx->sw_format));
375  return AVERROR(EINVAL);
376  }
377 
378  hwctx->resource_flags |= device_hwctx->resource_flags;
379  hwctx->heap_flags |= device_hwctx->heap_flags;
380 
381  if (ctx->initial_pool_size > 0 && hwctx->flags & AV_D3D12VA_FRAME_FLAG_TEXTURE_ARRAY) {
382  int err = d3d12va_texture_array_init(ctx);
383  if (err < 0)
384  return err;
385  }
386 
389 
390  if (!ffhwframesctx(ctx)->pool_internal)
391  return AVERROR(ENOMEM);
392 
393  return 0;
394 }
395 
397 {
398  int ret;
399 
400  frame->buf[0] = av_buffer_pool_get(ctx->pool);
401  if (!frame->buf[0])
402  return AVERROR(ENOMEM);
403 
404  ret = av_image_fill_arrays(frame->data, frame->linesize, NULL,
405  ctx->sw_format, ctx->width, ctx->height,
406  D3D12_TEXTURE_DATA_PITCH_ALIGNMENT);
407  if (ret < 0)
408  return ret;
409 
410  frame->data[0] = frame->buf[0]->data;
411  frame->format = AV_PIX_FMT_D3D12;
412  frame->width = ctx->width;
413  frame->height = ctx->height;
414 
415  return 0;
416 }
417 
420  enum AVPixelFormat **formats)
421 {
422  enum AVPixelFormat *fmts;
423 
424  fmts = av_malloc_array(2, sizeof(*fmts));
425  if (!fmts)
426  return AVERROR(ENOMEM);
427 
428  fmts[0] = ctx->sw_format;
429  fmts[1] = AV_PIX_FMT_NONE;
430 
431  *formats = fmts;
432 
433  return 0;
434 }
435 
437  const AVFrame *src)
438 {
439  AVD3D12VADeviceContext *hwctx = ctx->device_ctx->hwctx;
440  D3D12VAFramesContext *s = ctx->hwctx;
441  AVD3D12VAFramesContext *frames_hwctx = &s->p;
442 
443  int ret;
444  int download = src->format == AV_PIX_FMT_D3D12;
445  const AVFrame *frame = download ? src : dst;
446  const AVFrame *other = download ? dst : src;
447 
448  AVD3D12VAFrame *f = (AVD3D12VAFrame *)frame->data[0];
449  ID3D12Resource *texture = (ID3D12Resource *)f->texture;
450 
451  uint8_t *mapped_data;
452  uint8_t *data[4];
453  int linesizes[4];
454 
455  D3D12_TEXTURE_COPY_LOCATION staging_y_location = { 0 };
456  D3D12_TEXTURE_COPY_LOCATION staging_uv_location = { 0 };
457 
458  D3D12_TEXTURE_COPY_LOCATION texture_y_location = {
459  .pResource = texture,
460  .Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX,
461  .SubresourceIndex = 0,
462  };
463 
464  D3D12_TEXTURE_COPY_LOCATION texture_uv_location = {
465  .pResource = texture,
466  .Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX,
467  .SubresourceIndex = 1,
468  };
469 
470  D3D12_RESOURCE_BARRIER barrier = {
471  .Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION,
472  .Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE,
473  .Transition = {
474  .pResource = texture,
475  .StateBefore = D3D12_RESOURCE_STATE_COMMON,
476  .StateAfter = download ? D3D12_RESOURCE_STATE_COPY_SOURCE : D3D12_RESOURCE_STATE_COPY_DEST,
477  .Subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES,
478  },
479  };
480 
481  if (frame->hw_frames_ctx->data != (uint8_t *)ctx || other->format != ctx->sw_format)
482  return AVERROR(EINVAL);
483 
484  hwctx->lock(hwctx->lock_ctx);
485 
486  if (!s->command_queue) {
488  if (ret < 0)
489  goto fail;
490  }
491 
492  for (int i = 0; i < 4; i++)
493  linesizes[i] = FFALIGN(frame->width * (frames_hwctx->format == DXGI_FORMAT_P010 ? 2 : 1),
494  D3D12_TEXTURE_DATA_PITCH_ALIGNMENT);
495 
496  staging_y_location = (D3D12_TEXTURE_COPY_LOCATION) {
497  .Type = D3D12_TEXTURE_COPY_TYPE_PLACED_FOOTPRINT,
498  .PlacedFootprint = {
499  .Offset = 0,
500  .Footprint = {
501  .Format = frames_hwctx->format == DXGI_FORMAT_P010 ?
502  DXGI_FORMAT_R16_UNORM : DXGI_FORMAT_R8_UNORM,
503  .Width = ctx->width,
504  .Height = ctx->height,
505  .Depth = 1,
506  .RowPitch = linesizes[0],
507  },
508  },
509  };
510 
511  staging_uv_location = (D3D12_TEXTURE_COPY_LOCATION) {
512  .Type = D3D12_TEXTURE_COPY_TYPE_PLACED_FOOTPRINT,
513  .PlacedFootprint = {
514  .Offset = s->luma_component_size,
515  .Footprint = {
516  .Format = frames_hwctx->format == DXGI_FORMAT_P010 ?
517  DXGI_FORMAT_R16G16_UNORM : DXGI_FORMAT_R8G8_UNORM,
518  .Width = ctx->width >> 1,
519  .Height = ctx->height >> 1,
520  .Depth = 1,
521  .RowPitch = linesizes[0],
522  },
523  },
524  };
525 
526  DX_CHECK(ID3D12CommandAllocator_Reset(s->command_allocator));
527 
528  DX_CHECK(ID3D12GraphicsCommandList_Reset(s->command_list, s->command_allocator, NULL));
529 
530  if (download) {
531  if (!s->staging_download_buffer) {
532  ret = d3d12va_create_staging_buffer_resource(ctx, D3D12_RESOURCE_STATE_COPY_DEST,
533  &s->staging_download_buffer, 1);
534  if (ret < 0) {
535  goto fail;
536  }
537  }
538 
539  staging_y_location.pResource = staging_uv_location.pResource = s->staging_download_buffer;
540 
541  ID3D12GraphicsCommandList_ResourceBarrier(s->command_list, 1, &barrier);
542 
543  ID3D12GraphicsCommandList_CopyTextureRegion(s->command_list,
544  &staging_y_location, 0, 0, 0,
545  &texture_y_location, NULL);
546 
547  ID3D12GraphicsCommandList_CopyTextureRegion(s->command_list,
548  &staging_uv_location, 0, 0, 0,
549  &texture_uv_location, NULL);
550 
551  barrier.Transition.StateBefore = barrier.Transition.StateAfter;
552  barrier.Transition.StateAfter = D3D12_RESOURCE_STATE_COMMON;
553  ID3D12GraphicsCommandList_ResourceBarrier(s->command_list, 1, &barrier);
554 
555  DX_CHECK(ID3D12GraphicsCommandList_Close(s->command_list));
556 
557  DX_CHECK(ID3D12CommandQueue_Wait(s->command_queue, f->sync_ctx.fence, f->sync_ctx.fence_value));
558 
559  ID3D12CommandQueue_ExecuteCommandLists(s->command_queue, 1, (ID3D12CommandList **)&s->command_list);
560 
561  ret = d3d12va_wait_queue_idle(&s->sync_ctx, s->command_queue);
562  if (ret < 0)
563  goto fail;
564 
565  DX_CHECK(ID3D12Resource_Map(s->staging_download_buffer, 0, NULL, (void **)&mapped_data));
566  av_image_fill_pointers(data, ctx->sw_format, ctx->height, mapped_data, linesizes);
567 
568  av_image_copy2(dst->data, dst->linesize, data, linesizes,
569  ctx->sw_format, ctx->width, ctx->height);
570 
571  ID3D12Resource_Unmap(s->staging_download_buffer, 0, NULL);
572  } else {
573  if (!s->staging_upload_buffer) {
574  ret = d3d12va_create_staging_buffer_resource(ctx, D3D12_RESOURCE_STATE_GENERIC_READ,
575  &s->staging_upload_buffer, 0);
576  if (ret < 0) {
577  goto fail;
578  }
579  }
580 
581  staging_y_location.pResource = staging_uv_location.pResource = s->staging_upload_buffer;
582 
583  DX_CHECK(ID3D12Resource_Map(s->staging_upload_buffer, 0, NULL, (void **)&mapped_data));
584  av_image_fill_pointers(data, ctx->sw_format, ctx->height, mapped_data, linesizes);
585 
586  av_image_copy2(data, linesizes, src->data, src->linesize,
587  ctx->sw_format, ctx->width, ctx->height);
588 
589  ID3D12Resource_Unmap(s->staging_upload_buffer, 0, NULL);
590 
591  ID3D12GraphicsCommandList_ResourceBarrier(s->command_list, 1, &barrier);
592 
593  ID3D12GraphicsCommandList_CopyTextureRegion(s->command_list,
594  &texture_y_location, 0, 0, 0,
595  &staging_y_location, NULL);
596 
597  ID3D12GraphicsCommandList_CopyTextureRegion(s->command_list,
598  &texture_uv_location, 0, 0, 0,
599  &staging_uv_location, NULL);
600 
601  barrier.Transition.StateBefore = barrier.Transition.StateAfter;
602  barrier.Transition.StateAfter = D3D12_RESOURCE_STATE_COMMON;
603  ID3D12GraphicsCommandList_ResourceBarrier(s->command_list, 1, &barrier);
604 
605  DX_CHECK(ID3D12GraphicsCommandList_Close(s->command_list));
606 
607  ID3D12CommandQueue_ExecuteCommandLists(s->command_queue, 1, (ID3D12CommandList **)&s->command_list);
608 
609  ret = d3d12va_wait_queue_idle(&s->sync_ctx, s->command_queue);
610  if (ret < 0)
611  goto fail;
612  }
613 
614  hwctx->unlock(hwctx->lock_ctx);
615 
616  return 0;
617 
618 fail:
619  hwctx->unlock(hwctx->lock_ctx);
620  return AVERROR(EINVAL);
621 }
622 
624 {
625  D3D12VADevicePriv *priv = hwdev->hwctx;
626 
627 #if !HAVE_UWP
628  priv->d3d12lib = dlopen("d3d12.dll", 0);
629  priv->dxgilib = dlopen("dxgi.dll", 0);
630 
631  if (!priv->d3d12lib || !priv->dxgilib)
632  goto fail;
633 
634  priv->create_device = (PFN_D3D12_CREATE_DEVICE)GetProcAddress(priv->d3d12lib, "D3D12CreateDevice");
635  if (!priv->create_device)
636  goto fail;
637 
638  priv->create_dxgi_factory2 = (PFN_CREATE_DXGI_FACTORY2)GetProcAddress(priv->dxgilib, "CreateDXGIFactory2");
639  if (!priv->create_dxgi_factory2)
640  goto fail;
641 
642  priv->get_debug_interface = (PFN_D3D12_GET_DEBUG_INTERFACE)GetProcAddress(priv->d3d12lib, "D3D12GetDebugInterface");
643 #else
644  priv->create_device = (PFN_D3D12_CREATE_DEVICE) D3D12CreateDevice;
645  priv->create_dxgi_factory2 = (PFN_CREATE_DXGI_FACTORY2) CreateDXGIFactory2;
646  priv->get_debug_interface = (PFN_D3D12_GET_DEBUG_INTERFACE) D3D12GetDebugInterface;
647 #endif
648  return 0;
649 
650 fail:
651  av_log(hwdev, AV_LOG_ERROR, "Failed to load D3D12 library or its functions\n");
652  return AVERROR_UNKNOWN;
653 }
654 
656 {
657  D3D12VADevicePriv *priv = hwdev->hwctx;
658  AVD3D12VADeviceContext *ctx = &priv->p;
659 
660  D3D12_OBJECT_RELEASE(ctx->device);
661 
662  if (priv->d3d12lib)
663  dlclose(priv->d3d12lib);
664 
665  if (priv->dxgilib)
666  dlclose(priv->dxgilib);
667 }
668 
670 {
671  AVD3D12VADeviceContext *ctx = hwdev->hwctx;
672 
673  if (!ctx->lock) {
674  ctx->lock_ctx = CreateMutex(NULL, 0, NULL);
675  if (ctx->lock_ctx == INVALID_HANDLE_VALUE) {
676  av_log(NULL, AV_LOG_ERROR, "Failed to create a mutex\n");
677  return AVERROR(EINVAL);
678  }
679  ctx->lock = d3d12va_default_lock;
680  ctx->unlock = d3d12va_default_unlock;
681  }
682 
683  if (!ctx->video_device)
684  DX_CHECK(ID3D12Device_QueryInterface(ctx->device, &IID_ID3D12VideoDevice, (void **)&ctx->video_device));
685 
686  return 0;
687 
688 fail:
689  return AVERROR(EINVAL);
690 }
691 
693 {
694  AVD3D12VADeviceContext *device_hwctx = hwdev->hwctx;
695 
696  D3D12_OBJECT_RELEASE(device_hwctx->video_device);
697 
698  if (device_hwctx->lock == d3d12va_default_lock) {
699  CloseHandle(device_hwctx->lock_ctx);
700  device_hwctx->lock_ctx = INVALID_HANDLE_VALUE;
701  device_hwctx->lock = NULL;
702  }
703 }
704 
705 static int d3d12va_device_create(AVHWDeviceContext *hwdev, const char *device,
706  AVDictionary *opts, int flags)
707 {
708  D3D12VADevicePriv *priv = hwdev->hwctx;
709  AVD3D12VADeviceContext *ctx = &priv->p;
710 
711  HRESULT hr;
712  UINT create_flags = 0;
713  IDXGIAdapter *pAdapter = NULL;
714 
715  int ret;
716  int is_debug = !!av_dict_get(opts, "debug", NULL, 0);
717 
718  hwdev->free = d3d12va_device_free;
719 
720  ret = d3d12va_load_functions(hwdev);
721  if (ret < 0)
722  return ret;
723 
724  if (is_debug) {
725  ID3D12Debug *pDebug;
726  if (priv->get_debug_interface && SUCCEEDED(priv->get_debug_interface(&IID_ID3D12Debug, (void **)&pDebug))) {
727  create_flags |= DXGI_CREATE_FACTORY_DEBUG;
728  ID3D12Debug_EnableDebugLayer(pDebug);
729  D3D12_OBJECT_RELEASE(pDebug);
730  av_log(hwdev, AV_LOG_INFO, "D3D12 debug layer is enabled!\n");
731  }
732  }
733 
734  if (!ctx->device) {
735  IDXGIFactory2 *pDXGIFactory = NULL;
736 
737  hr = priv->create_dxgi_factory2(create_flags, &IID_IDXGIFactory2, (void **)&pDXGIFactory);
738  if (SUCCEEDED(hr)) {
739  int adapter = device ? atoi(device) : 0;
740  if (FAILED(IDXGIFactory2_EnumAdapters(pDXGIFactory, adapter, &pAdapter)))
741  pAdapter = NULL;
742  IDXGIFactory2_Release(pDXGIFactory);
743  }
744 
745  if (pAdapter) {
746  DXGI_ADAPTER_DESC desc;
747  hr = IDXGIAdapter2_GetDesc(pAdapter, &desc);
748  if (!FAILED(hr)) {
749  av_log(ctx, AV_LOG_INFO, "Using device %04x:%04x (%ls).\n",
750  desc.VendorId, desc.DeviceId, desc.Description);
751  }
752  }
753 
754  hr = priv->create_device((IUnknown *)pAdapter, D3D_FEATURE_LEVEL_12_0, &IID_ID3D12Device, (void **)&ctx->device);
755  D3D12_OBJECT_RELEASE(pAdapter);
756  if (FAILED(hr)) {
757  av_log(ctx, AV_LOG_ERROR, "Failed to create Direct 3D 12 device (%lx)\n", (long)hr);
758  return AVERROR_UNKNOWN;
759  }
760  }
761 
762  if (av_dict_get(opts, "UAV", NULL, 0))
763  ctx->resource_flags |= D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS;
764 
765  if (av_dict_get(opts, "RTV", NULL, 0))
766  ctx->resource_flags |= D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET;
767 
768  if (av_dict_get(opts, "SHARED", NULL, 0))
769  ctx->heap_flags |= D3D12_HEAP_FLAG_SHARED;
770 
771  return 0;
772 }
773 
776  .name = "D3D12VA",
777 
778  .device_hwctx_size = sizeof(D3D12VADevicePriv),
779  .frames_hwctx_size = sizeof(D3D12VAFramesContext),
780 
781  .device_create = d3d12va_device_create,
782  .device_init = d3d12va_device_init,
783  .device_uninit = d3d12va_device_uninit,
784  .frames_get_constraints = d3d12va_frames_get_constraints,
785  .frames_init = d3d12va_frames_init,
786  .frames_uninit = d3d12va_frames_uninit,
787  .frames_get_buffer = d3d12va_get_buffer,
788  .transfer_get_formats = d3d12va_transfer_get_formats,
789  .transfer_data_to = d3d12va_transfer_data,
790  .transfer_data_from = d3d12va_transfer_data,
791 
792  .pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_D3D12, AV_PIX_FMT_NONE },
793 };
flags
const SwsFlags flags[]
Definition: swscale.c:61
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:436
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
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:195
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:427
pixdesc.h
D3D12VADevicePriv
Definition: hwcontext_d3d12va.c:55
supported_formats
static const struct @499 supported_formats[]
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:705
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
fail
#define fail()
Definition: checkasm.h:206
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:80
d3d12va_texture_array_init
static int d3d12va_texture_array_init(AVHWFramesContext *ctx)
Definition: hwcontext_d3d12va.c:328
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
d3d12va_device_init
static int d3d12va_device_init(AVHWDeviceContext *hwdev)
Definition: hwcontext_d3d12va.c:669
s
#define s(width, name)
Definition: cbs_vp9.c:198
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:274
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
AVFormatContext * ctx
Definition: movenc.c:49
AVD3D12VASyncContext
This struct is used to sync d3d12 execution.
Definition: hwcontext_d3d12va.h:104
AVD3D12VASyncContext::fence
ID3D12Fence * fence
D3D12 fence object.
Definition: hwcontext_d3d12va.h:108
opts
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:238
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:655
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
dst
uint8_t ptrdiff_t const uint8_t ptrdiff_t int intptr_t intptr_t int int16_t * dst
Definition: dsp.h:87
d3d12va_fence_completion
static int d3d12va_fence_completion(AVD3D12VASyncContext *psync_ctx)
Definition: hwcontext_d3d12va.c:85
size
int size
Definition: twinvq_data.h:10344
free_texture
static void free_texture(void *opaque, uint8_t *data)
Definition: hwcontext_d3d12va.c:224
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:514
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:356
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:623
D3D12VAFramesContext::command_allocator
ID3D12CommandAllocator * command_allocator
Definition: hwcontext_d3d12va.c:48
AVD3D12VADeviceContext
This struct is allocated as AVHWDeviceContext.hwctx.
Definition: hwcontext_d3d12va.h:43
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:256
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
av_mallocz
void * av_mallocz(size_t size)
Allocate a memory block with alignment suitable for all memory accesses (including vectors if availab...
Definition: mem.c:256
d3d12va_frames_uninit
static void d3d12va_frames_uninit(AVHWFramesContext *ctx)
Definition: hwcontext_d3d12va.c:176
AVHWFrameTransferDirection
AVHWFrameTransferDirection
Definition: hwcontext.h:406
d3d12va_default_lock
static void d3d12va_default_lock(void *ctx)
Definition: hwcontext_d3d12va.c:75
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:98
d3d12va_get_buffer
static int d3d12va_get_buffer(AVHWFramesContext *ctx, AVFrame *frame)
Definition: hwcontext_d3d12va.c:396
ff_hwcontext_type_d3d12va
const HWContextType ff_hwcontext_type_d3d12va
Definition: hwcontext_d3d12va.c:774
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:107
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:621
D3D12VAFramesContext::luma_component_size
UINT luma_component_size
Definition: hwcontext_d3d12va.c:51
desc
const char * desc
Definition: libsvtav1.c:79
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:135
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:418
w32dlfcn.h
d3d12va_device_uninit
static void d3d12va_device_uninit(AVHWDeviceContext *hwdev)
Definition: hwcontext_d3d12va.c:692
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:3505
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