FFmpeg
d3d12va_encode.c
Go to the documentation of this file.
1 /*
2  * Direct3D 12 HW acceleration video encoder
3  *
4  * Copyright (c) 2024 Intel Corporation
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 "libavutil/avassert.h"
24 #include "libavutil/common.h"
25 #include "libavutil/internal.h"
26 #include "libavutil/log.h"
27 #include "libavutil/mem.h"
28 #include "libavutil/pixdesc.h"
31 
32 #include "avcodec.h"
33 #include "d3d12va_encode.h"
34 #include "encode.h"
35 
37  HW_CONFIG_ENCODER_FRAMES(D3D12, D3D12VA),
38  NULL,
39 };
40 
42 {
43  uint64_t completion = ID3D12Fence_GetCompletedValue(psync_ctx->fence);
44  if (completion < psync_ctx->fence_value) {
45  if (FAILED(ID3D12Fence_SetEventOnCompletion(psync_ctx->fence, psync_ctx->fence_value, psync_ctx->event)))
46  return AVERROR(EINVAL);
47 
48  WaitForSingleObjectEx(psync_ctx->event, INFINITE, FALSE);
49  }
50 
51  return 0;
52 }
53 
55 {
57 
58  DX_CHECK(ID3D12CommandQueue_Signal(ctx->command_queue, ctx->sync_ctx.fence, ++ctx->sync_ctx.fence_value));
59  return d3d12va_fence_completion(&ctx->sync_ctx);
60 
61 fail:
62  return AVERROR(EINVAL);
63 }
64 
65 typedef struct CommandAllocator {
66  ID3D12CommandAllocator *command_allocator;
67  uint64_t fence_value;
69 
70 static int d3d12va_get_valid_command_allocator(AVCodecContext *avctx, ID3D12CommandAllocator **ppAllocator)
71 {
72  HRESULT hr;
74  CommandAllocator allocator;
75 
76  if (av_fifo_peek(ctx->allocator_queue, &allocator, 1, 0) >= 0) {
77  uint64_t completion = ID3D12Fence_GetCompletedValue(ctx->sync_ctx.fence);
78  if (completion >= allocator.fence_value) {
79  *ppAllocator = allocator.command_allocator;
80  av_fifo_read(ctx->allocator_queue, &allocator, 1);
81  return 0;
82  }
83  }
84 
85  hr = ID3D12Device_CreateCommandAllocator(ctx->hwctx->device, D3D12_COMMAND_LIST_TYPE_VIDEO_ENCODE,
86  &IID_ID3D12CommandAllocator, (void **)ppAllocator);
87  if (FAILED(hr)) {
88  av_log(avctx, AV_LOG_ERROR, "Failed to create a new command allocator!\n");
89  return AVERROR(EINVAL);
90  }
91 
92  return 0;
93 }
94 
95 static int d3d12va_discard_command_allocator(AVCodecContext *avctx, ID3D12CommandAllocator *pAllocator, uint64_t fence_value)
96 {
98 
99  CommandAllocator allocator = {
100  .command_allocator = pAllocator,
101  .fence_value = fence_value,
102  };
103 
104  av_fifo_write(ctx->allocator_queue, &allocator, 1);
105 
106  return 0;
107 }
108 
110  FFHWBaseEncodePicture *base_pic)
111 {
113  D3D12VAEncodePicture *pic = base_pic->priv;
114  uint64_t completion;
115 
116  av_assert0(base_pic->encode_issued);
117 
118  if (base_pic->encode_complete) {
119  // Already waited for this picture.
120  return 0;
121  }
122 
123  completion = ID3D12Fence_GetCompletedValue(ctx->sync_ctx.fence);
124  if (completion < pic->fence_value) {
125  if (FAILED(ID3D12Fence_SetEventOnCompletion(ctx->sync_ctx.fence, pic->fence_value,
126  ctx->sync_ctx.event)))
127  return AVERROR(EINVAL);
128 
129  WaitForSingleObjectEx(ctx->sync_ctx.event, INFINITE, FALSE);
130  }
131 
132  av_log(avctx, AV_LOG_DEBUG, "Sync to pic %"PRId64"/%"PRId64" "
133  "(input surface %p).\n", base_pic->display_order,
134  base_pic->encode_order, pic->input_surface->texture);
135 
136  av_frame_free(&base_pic->input_image);
137 
138  base_pic->encode_complete = 1;
139  return 0;
140 }
141 
144 {
146  int width = sizeof(D3D12_VIDEO_ENCODER_OUTPUT_METADATA) + sizeof(D3D12_VIDEO_ENCODER_FRAME_SUBREGION_METADATA);
147  D3D12_HEAP_PROPERTIES encoded_meta_props = { .Type = D3D12_HEAP_TYPE_DEFAULT }, resolved_meta_props;
148  D3D12_HEAP_TYPE resolved_heap_type = D3D12_HEAP_TYPE_READBACK;
149  HRESULT hr;
150 
151  D3D12_RESOURCE_DESC meta_desc = {
152  .Dimension = D3D12_RESOURCE_DIMENSION_BUFFER,
153  .Alignment = 0,
154  .Width = ctx->req.MaxEncoderOutputMetadataBufferSize,
155  .Height = 1,
156  .DepthOrArraySize = 1,
157  .MipLevels = 1,
158  .Format = DXGI_FORMAT_UNKNOWN,
159  .SampleDesc = { .Count = 1, .Quality = 0 },
160  .Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR,
161  .Flags = D3D12_RESOURCE_FLAG_NONE,
162  };
163 
164  hr = ID3D12Device_CreateCommittedResource(ctx->hwctx->device, &encoded_meta_props, D3D12_HEAP_FLAG_NONE,
165  &meta_desc, D3D12_RESOURCE_STATE_COMMON, NULL,
166  &IID_ID3D12Resource, (void **)&pic->encoded_metadata);
167  if (FAILED(hr)) {
168  av_log(avctx, AV_LOG_ERROR, "Failed to create metadata buffer.\n");
169  return AVERROR_UNKNOWN;
170  }
171 
172  ctx->hwctx->device->lpVtbl->GetCustomHeapProperties(ctx->hwctx->device, &resolved_meta_props, 0, resolved_heap_type);
173 
174  meta_desc.Width = width;
175 
176  hr = ID3D12Device_CreateCommittedResource(ctx->hwctx->device, &resolved_meta_props, D3D12_HEAP_FLAG_NONE,
177  &meta_desc, D3D12_RESOURCE_STATE_COMMON, NULL,
178  &IID_ID3D12Resource, (void **)&pic->resolved_metadata);
179 
180  if (FAILED(hr)) {
181  av_log(avctx, AV_LOG_ERROR, "Failed to create output metadata buffer.\n");
182  return AVERROR_UNKNOWN;
183  }
184 
185  return 0;
186 }
187 
189  FFHWBaseEncodePicture *base_pic)
190 {
191  FFHWBaseEncodeContext *base_ctx = avctx->priv_data;
193  D3D12VAEncodePicture *pic = base_pic->priv;
194  AVD3D12VAFramesContext *frames_hwctx = base_ctx->input_frames->hwctx;
195  int err, i, j;
196  HRESULT hr;
198  void *ptr;
199  size_t bit_len;
200  ID3D12CommandAllocator *command_allocator = NULL;
201  ID3D12VideoEncodeCommandList2 *cmd_list = ctx->command_list;
202  D3D12_RESOURCE_BARRIER barriers[32] = { 0 };
203  D3D12_VIDEO_ENCODE_REFERENCE_FRAMES d3d12_refs = { 0 };
204  int barriers_ref_index = 0;
205  D3D12_RESOURCE_BARRIER *barriers_ref = NULL;
206 
207  D3D12_VIDEO_ENCODER_ENCODEFRAME_INPUT_ARGUMENTS input_args = {
208  .SequenceControlDesc = {
209  .Flags = D3D12_VIDEO_ENCODER_SEQUENCE_CONTROL_FLAG_NONE,
210  .IntraRefreshConfig = { 0 },
211  .RateControl = ctx->rc,
212  .PictureTargetResolution = ctx->resolution,
213  .SelectedLayoutMode = D3D12_VIDEO_ENCODER_FRAME_SUBREGION_LAYOUT_MODE_FULL_FRAME,
214  .FrameSubregionsLayoutData = { 0 },
215  .CodecGopSequence = ctx->gop,
216  },
217  .pInputFrame = pic->input_surface->texture,
218  .InputFrameSubresource = 0,
219  };
220 
221  D3D12_VIDEO_ENCODER_ENCODEFRAME_OUTPUT_ARGUMENTS output_args = { 0 };
222 
223  D3D12_VIDEO_ENCODER_RESOLVE_METADATA_INPUT_ARGUMENTS input_metadata = {
224  .EncoderCodec = ctx->codec->d3d12_codec,
225  .EncoderProfile = ctx->profile->d3d12_profile,
226  .EncoderInputFormat = frames_hwctx->format,
227  .EncodedPictureEffectiveResolution = ctx->resolution,
228  };
229 
230  D3D12_VIDEO_ENCODER_RESOLVE_METADATA_OUTPUT_ARGUMENTS output_metadata = { 0 };
231 
232  memset(data, 0, sizeof(data));
233 
234  av_log(avctx, AV_LOG_DEBUG, "Issuing encode for pic %"PRId64"/%"PRId64" "
235  "as type %s.\n", base_pic->display_order, base_pic->encode_order,
237  if (base_pic->nb_refs[0] == 0 && base_pic->nb_refs[1] == 0) {
238  av_log(avctx, AV_LOG_DEBUG, "No reference pictures.\n");
239  } else {
240  av_log(avctx, AV_LOG_DEBUG, "L0 refers to");
241  for (i = 0; i < base_pic->nb_refs[0]; i++) {
242  av_log(avctx, AV_LOG_DEBUG, " %"PRId64"/%"PRId64,
243  base_pic->refs[0][i]->display_order, base_pic->refs[0][i]->encode_order);
244  }
245  av_log(avctx, AV_LOG_DEBUG, ".\n");
246 
247  if (base_pic->nb_refs[1]) {
248  av_log(avctx, AV_LOG_DEBUG, "L1 refers to");
249  for (i = 0; i < base_pic->nb_refs[1]; i++) {
250  av_log(avctx, AV_LOG_DEBUG, " %"PRId64"/%"PRId64,
251  base_pic->refs[1][i]->display_order, base_pic->refs[1][i]->encode_order);
252  }
253  av_log(avctx, AV_LOG_DEBUG, ".\n");
254  }
255  }
256 
257  av_assert0(!base_pic->encode_issued);
258  for (i = 0; i < base_pic->nb_refs[0]; i++) {
259  av_assert0(base_pic->refs[0][i]);
260  av_assert0(base_pic->refs[0][i]->encode_issued);
261  }
262  for (i = 0; i < base_pic->nb_refs[1]; i++) {
263  av_assert0(base_pic->refs[1][i]);
264  av_assert0(base_pic->refs[1][i]->encode_issued);
265  }
266 
267  av_log(avctx, AV_LOG_DEBUG, "Input surface is %p.\n", pic->input_surface->texture);
268 
269  pic->recon_surface = (AVD3D12VAFrame *)base_pic->recon_image->data[0];
270  av_log(avctx, AV_LOG_DEBUG, "Recon surface is %p.\n",
271  pic->recon_surface->texture);
272 
273  pic->subresource_index = ctx->is_texture_array ? pic->recon_surface->subresource_index : 0;
274 
275  pic->output_buffer_ref = av_buffer_pool_get(ctx->output_buffer_pool);
276  if (!pic->output_buffer_ref) {
277  err = AVERROR(ENOMEM);
278  goto fail;
279  }
280  pic->output_buffer = (ID3D12Resource *)pic->output_buffer_ref->data;
281  av_log(avctx, AV_LOG_DEBUG, "Output buffer is %p.\n",
282  pic->output_buffer);
283 
284  err = d3d12va_encode_create_metadata_buffers(avctx, pic);
285  if (err < 0)
286  goto fail;
287 
288  if (ctx->codec->init_picture_params) {
289  err = ctx->codec->init_picture_params(avctx, base_pic);
290  if (err < 0) {
291  av_log(avctx, AV_LOG_ERROR, "Failed to initialise picture "
292  "parameters: %d.\n", err);
293  goto fail;
294  }
295  }
296 
297  if (base_pic->type == FF_HW_PICTURE_TYPE_IDR) {
298  if (ctx->codec->write_sequence_header) {
299  bit_len = 8 * sizeof(data);
300  err = ctx->codec->write_sequence_header(avctx, data, &bit_len);
301  if (err < 0) {
302  av_log(avctx, AV_LOG_ERROR, "Failed to write per-sequence "
303  "header: %d.\n", err);
304  goto fail;
305  }
306  pic->header_size = (int)bit_len / 8;
307  pic->aligned_header_size = pic->header_size % ctx->req.CompressedBitstreamBufferAccessAlignment ?
308  FFALIGN(pic->header_size, ctx->req.CompressedBitstreamBufferAccessAlignment) :
309  pic->header_size;
310 
311  hr = ID3D12Resource_Map(pic->output_buffer, 0, NULL, (void **)&ptr);
312  if (FAILED(hr)) {
313  err = AVERROR_UNKNOWN;
314  goto fail;
315  }
316 
317  memcpy(ptr, data, pic->aligned_header_size);
318  ID3D12Resource_Unmap(pic->output_buffer, 0, NULL);
319  }
320  }
321 
322  d3d12_refs.NumTexture2Ds = base_pic->nb_refs[0] + base_pic->nb_refs[1];
323  if (d3d12_refs.NumTexture2Ds) {
324  d3d12_refs.ppTexture2Ds = av_calloc(d3d12_refs.NumTexture2Ds,
325  sizeof(*d3d12_refs.ppTexture2Ds));
326  if (!d3d12_refs.ppTexture2Ds) {
327  err = AVERROR(ENOMEM);
328  goto fail;
329  }
330 
331  if (ctx->is_texture_array) {
332  d3d12_refs.pSubresources = av_calloc(d3d12_refs.NumTexture2Ds,
333  sizeof(*d3d12_refs.pSubresources));
334  if (!d3d12_refs.pSubresources) {
335  err = AVERROR(ENOMEM);
336  goto fail;
337  }
338  }
339 
340  i = 0;
341  for (j = 0; j < base_pic->nb_refs[0]; j++) {
342  d3d12_refs.ppTexture2Ds[i] = ((D3D12VAEncodePicture *)base_pic->refs[0][j]->priv)->recon_surface->texture;
343  if (ctx->is_texture_array)
344  d3d12_refs.pSubresources[i] = ((D3D12VAEncodePicture *)base_pic->refs[0][j]->priv)->subresource_index;
345  i++;
346  }
347  for (j = 0; j < base_pic->nb_refs[1]; j++) {
348  d3d12_refs.ppTexture2Ds[i] = ((D3D12VAEncodePicture *)base_pic->refs[1][j]->priv)->recon_surface->texture;
349  if (ctx->is_texture_array)
350  d3d12_refs.pSubresources[i] = ((D3D12VAEncodePicture *)base_pic->refs[1][j]->priv)->subresource_index;
351  i++;
352  }
353  }
354 
355  input_args.PictureControlDesc.IntraRefreshFrameIndex = 0;
356  if (base_pic->is_reference)
357  input_args.PictureControlDesc.Flags |= D3D12_VIDEO_ENCODER_PICTURE_CONTROL_FLAG_USED_AS_REFERENCE_PICTURE;
358 
359  input_args.PictureControlDesc.PictureControlCodecData = pic->pic_ctl;
360  input_args.PictureControlDesc.ReferenceFrames = d3d12_refs;
361  input_args.CurrentFrameBitstreamMetadataSize = pic->aligned_header_size;
362 
363  output_args.Bitstream.pBuffer = pic->output_buffer;
364  output_args.Bitstream.FrameStartOffset = pic->aligned_header_size;
365  output_args.ReconstructedPicture.pReconstructedPicture = pic->recon_surface->texture;
366  output_args.ReconstructedPicture.ReconstructedPictureSubresource = ctx->is_texture_array ? pic->subresource_index : 0;
367  output_args.EncoderOutputMetadata.pBuffer = pic->encoded_metadata;
368  output_args.EncoderOutputMetadata.Offset = 0;
369 
370  input_metadata.HWLayoutMetadata.pBuffer = pic->encoded_metadata;
371  input_metadata.HWLayoutMetadata.Offset = 0;
372 
373  output_metadata.ResolvedLayoutMetadata.pBuffer = pic->resolved_metadata;
374  output_metadata.ResolvedLayoutMetadata.Offset = 0;
375 
376  err = d3d12va_get_valid_command_allocator(avctx, &command_allocator);
377  if (err < 0)
378  goto fail;
379 
380  hr = ID3D12CommandAllocator_Reset(command_allocator);
381  if (FAILED(hr)) {
382  err = AVERROR_UNKNOWN;
383  goto fail;
384  }
385 
386  hr = ID3D12VideoEncodeCommandList2_Reset(cmd_list, command_allocator);
387  if (FAILED(hr)) {
388  err = AVERROR_UNKNOWN;
389  goto fail;
390  }
391 
392 #define TRANSITION_BARRIER(res, subres, before, after) \
393  (D3D12_RESOURCE_BARRIER) { \
394  .Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION, \
395  .Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE, \
396  .Transition = { \
397  .pResource = res, \
398  .Subresource = subres, \
399  .StateBefore = before, \
400  .StateAfter = after, \
401  }, \
402  }
403 
404  barriers[0] = TRANSITION_BARRIER(pic->input_surface->texture,
405  D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES,
406  D3D12_RESOURCE_STATE_COMMON,
407  D3D12_RESOURCE_STATE_VIDEO_ENCODE_READ);
408  barriers[1] = TRANSITION_BARRIER(pic->output_buffer,
409  D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES,
410  D3D12_RESOURCE_STATE_COMMON,
411  D3D12_RESOURCE_STATE_VIDEO_ENCODE_WRITE);
412  barriers[2] = TRANSITION_BARRIER(pic->encoded_metadata,
413  D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES,
414  D3D12_RESOURCE_STATE_COMMON,
415  D3D12_RESOURCE_STATE_VIDEO_ENCODE_WRITE);
416  barriers[3] = TRANSITION_BARRIER(pic->resolved_metadata,
417  D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES,
418  D3D12_RESOURCE_STATE_COMMON,
419  D3D12_RESOURCE_STATE_VIDEO_ENCODE_WRITE);
420 
421  ID3D12VideoEncodeCommandList2_ResourceBarrier(cmd_list, 4, barriers);
422 
423  if (ctx->is_texture_array)
424  barriers_ref = av_calloc(base_ctx->recon_frames->initial_pool_size * ctx->plane_count,
425  sizeof(D3D12_RESOURCE_BARRIER));
426  else
427  barriers_ref = av_calloc(MAX_DPB_SIZE, sizeof(D3D12_RESOURCE_BARRIER));
428 
429  if (ctx->is_texture_array) {
430  D3D12_RESOURCE_DESC references_tex_array_desc = { 0 };
431  pic->recon_surface->texture->lpVtbl->GetDesc(pic->recon_surface->texture, &references_tex_array_desc);
432 
433  for (uint32_t reference_subresource = 0; reference_subresource < references_tex_array_desc.DepthOrArraySize;
434  reference_subresource++) {
435 
436  uint32_t array_size = references_tex_array_desc.DepthOrArraySize;
437  uint32_t mip_slice = reference_subresource % references_tex_array_desc.MipLevels;
438  uint32_t array_slice = (reference_subresource / references_tex_array_desc.MipLevels) % array_size;
439 
440  for (uint32_t plane_slice = 0; plane_slice < ctx->plane_count; plane_slice++) {
441  uint32_t outputSubresource = mip_slice + array_slice * references_tex_array_desc.MipLevels +
442  plane_slice * references_tex_array_desc.MipLevels * array_size;
443  if (reference_subresource == pic->subresource_index) {
444  barriers_ref[barriers_ref_index++] = TRANSITION_BARRIER(pic->recon_surface->texture, outputSubresource,
445  D3D12_RESOURCE_STATE_COMMON,
446  D3D12_RESOURCE_STATE_VIDEO_ENCODE_WRITE);
447  } else {
448  barriers_ref[barriers_ref_index++] = TRANSITION_BARRIER(pic->recon_surface->texture, outputSubresource,
449  D3D12_RESOURCE_STATE_COMMON,
450  D3D12_RESOURCE_STATE_VIDEO_ENCODE_READ);
451  }
452  }
453  }
454  } else {
455  barriers_ref[barriers_ref_index++] = TRANSITION_BARRIER(pic->recon_surface->texture,
456  D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES,
457  D3D12_RESOURCE_STATE_COMMON,
458  D3D12_RESOURCE_STATE_VIDEO_ENCODE_WRITE);
459 
460  if (d3d12_refs.NumTexture2Ds) {
461  for (i = 0; i < d3d12_refs.NumTexture2Ds; i++)
462  barriers_ref[barriers_ref_index++] = TRANSITION_BARRIER(d3d12_refs.ppTexture2Ds[i],
463  D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES,
464  D3D12_RESOURCE_STATE_COMMON,
465  D3D12_RESOURCE_STATE_VIDEO_ENCODE_READ);
466  }
467  }
468  ID3D12VideoEncodeCommandList2_ResourceBarrier(cmd_list, barriers_ref_index, barriers_ref);
469 
470  ID3D12VideoEncodeCommandList2_EncodeFrame(cmd_list, ctx->encoder, ctx->encoder_heap,
471  &input_args, &output_args);
472 
473  barriers[3] = TRANSITION_BARRIER(pic->encoded_metadata,
474  D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES,
475  D3D12_RESOURCE_STATE_VIDEO_ENCODE_WRITE,
476  D3D12_RESOURCE_STATE_VIDEO_ENCODE_READ);
477 
478  ID3D12VideoEncodeCommandList2_ResourceBarrier(cmd_list, 1, &barriers[3]);
479 
480  ID3D12VideoEncodeCommandList2_ResolveEncoderOutputMetadata(cmd_list, &input_metadata, &output_metadata);
481 
482  if (barriers_ref_index > 0) {
483  for (i = 0; i < barriers_ref_index; i++)
484  FFSWAP(D3D12_RESOURCE_STATES, barriers_ref[i].Transition.StateBefore, barriers_ref[i].Transition.StateAfter);
485 
486  ID3D12VideoEncodeCommandList2_ResourceBarrier(cmd_list, barriers_ref_index,
487  barriers_ref);
488  }
489 
490  barriers[0] = TRANSITION_BARRIER(pic->input_surface->texture,
491  D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES,
492  D3D12_RESOURCE_STATE_VIDEO_ENCODE_READ,
493  D3D12_RESOURCE_STATE_COMMON);
494  barriers[1] = TRANSITION_BARRIER(pic->output_buffer,
495  D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES,
496  D3D12_RESOURCE_STATE_VIDEO_ENCODE_WRITE,
497  D3D12_RESOURCE_STATE_COMMON);
498  barriers[2] = TRANSITION_BARRIER(pic->encoded_metadata,
499  D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES,
500  D3D12_RESOURCE_STATE_VIDEO_ENCODE_READ,
501  D3D12_RESOURCE_STATE_COMMON);
502  barriers[3] = TRANSITION_BARRIER(pic->resolved_metadata,
503  D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES,
504  D3D12_RESOURCE_STATE_VIDEO_ENCODE_WRITE,
505  D3D12_RESOURCE_STATE_COMMON);
506 
507  ID3D12VideoEncodeCommandList2_ResourceBarrier(cmd_list, 4, barriers);
508 
509  hr = ID3D12VideoEncodeCommandList2_Close(cmd_list);
510  if (FAILED(hr)) {
511  err = AVERROR_UNKNOWN;
512  goto fail;
513  }
514 
515  hr = ID3D12CommandQueue_Wait(ctx->command_queue, pic->input_surface->sync_ctx.fence,
517  if (FAILED(hr)) {
518  err = AVERROR_UNKNOWN;
519  goto fail;
520  }
521 
522  ID3D12CommandQueue_ExecuteCommandLists(ctx->command_queue, 1, (ID3D12CommandList **)&ctx->command_list);
523 
524  hr = ID3D12CommandQueue_Signal(ctx->command_queue, pic->input_surface->sync_ctx.fence,
526  if (FAILED(hr)) {
527  err = AVERROR_UNKNOWN;
528  goto fail;
529  }
530 
531  hr = ID3D12CommandQueue_Signal(ctx->command_queue, ctx->sync_ctx.fence, ++ctx->sync_ctx.fence_value);
532  if (FAILED(hr)) {
533  err = AVERROR_UNKNOWN;
534  goto fail;
535  }
536 
537  err = d3d12va_discard_command_allocator(avctx, command_allocator, ctx->sync_ctx.fence_value);
538  if (err < 0)
539  goto fail;
540 
541  pic->fence_value = ctx->sync_ctx.fence_value;
542 
543  if (d3d12_refs.ppTexture2Ds)
544  av_freep(&d3d12_refs.ppTexture2Ds);
545 
546  if (ctx->is_texture_array && d3d12_refs.pSubresources)
547  av_freep(&d3d12_refs.pSubresources);
548 
549  if (barriers_ref)
550  av_freep(&barriers_ref);
551 
552  return 0;
553 
554 fail:
555  if (command_allocator)
556  d3d12va_discard_command_allocator(avctx, command_allocator, ctx->sync_ctx.fence_value);
557 
558  if (d3d12_refs.ppTexture2Ds)
559  av_freep(&d3d12_refs.ppTexture2Ds);
560 
561  if (ctx->is_texture_array && d3d12_refs.pSubresources)
562  av_freep(&d3d12_refs.pSubresources);
563 
564  if (barriers_ref)
565  av_freep(&barriers_ref);
566 
567  if (ctx->codec->free_picture_params)
568  ctx->codec->free_picture_params(pic);
569 
571  pic->output_buffer = NULL;
574  return err;
575 }
576 
578  FFHWBaseEncodePicture *base_pic)
579 {
580  D3D12VAEncodePicture *pic = base_pic->priv;
581 
582  d3d12va_encode_wait(avctx, base_pic);
583 
584  if (pic->output_buffer_ref) {
585  av_log(avctx, AV_LOG_DEBUG, "Discard output for pic "
586  "%"PRId64"/%"PRId64".\n",
587  base_pic->display_order, base_pic->encode_order);
588 
590  pic->output_buffer = NULL;
591  }
592 
595 
596  return 0;
597 }
598 
600 {
602 
603  switch (ctx->rc.Mode)
604  {
605  case D3D12_VIDEO_ENCODER_RATE_CONTROL_MODE_CQP:
606  av_freep(&ctx->rc.ConfigParams.pConfiguration_CQP);
607  break;
608  case D3D12_VIDEO_ENCODER_RATE_CONTROL_MODE_CBR:
609  av_freep(&ctx->rc.ConfigParams.pConfiguration_CBR);
610  break;
611  case D3D12_VIDEO_ENCODER_RATE_CONTROL_MODE_VBR:
612  av_freep(&ctx->rc.ConfigParams.pConfiguration_VBR);
613  break;
614  case D3D12_VIDEO_ENCODER_RATE_CONTROL_MODE_QVBR:
615  av_freep(&ctx->rc.ConfigParams.pConfiguration_QVBR);
616  break;
617  default:
618  break;
619  }
620 
621  return 0;
622 }
623 
625 {
627  D3D12VAEncodePicture *priv = pic->priv;
628  AVFrame *frame = pic->input_image;
629 
630  if (ctx->codec->picture_priv_data_size > 0) {
631  pic->codec_priv = av_mallocz(ctx->codec->picture_priv_data_size);
632  if (!pic->codec_priv)
633  return AVERROR(ENOMEM);
634  }
635 
636  priv->input_surface = (AVD3D12VAFrame *)frame->data[0];
637 
638  return 0;
639 }
640 
642 {
644  D3D12VAEncodePicture *priv = pic->priv;
645 
646  if (pic->encode_issued)
647  d3d12va_encode_discard(avctx, pic);
648 
649  if (ctx->codec->free_picture_params)
650  ctx->codec->free_picture_params(priv);
651 
652  return 0;
653 }
654 
656  D3D12VAEncodePicture *pic, size_t *size)
657 {
658  D3D12_VIDEO_ENCODER_OUTPUT_METADATA *meta = NULL;
659  uint8_t *data;
660  HRESULT hr;
661  int err;
662 
663  hr = ID3D12Resource_Map(pic->resolved_metadata, 0, NULL, (void **)&data);
664  if (FAILED(hr)) {
665  err = AVERROR_UNKNOWN;
666  return err;
667  }
668 
669  meta = (D3D12_VIDEO_ENCODER_OUTPUT_METADATA *)data;
670 
671  if (meta->EncodeErrorFlags != D3D12_VIDEO_ENCODER_ENCODE_ERROR_FLAG_NO_ERROR) {
672  av_log(avctx, AV_LOG_ERROR, "Encode failed %"PRIu64"\n", meta->EncodeErrorFlags);
673  err = AVERROR(EINVAL);
674  return err;
675  }
676 
677  if (meta->EncodedBitstreamWrittenBytesCount == 0) {
678  av_log(avctx, AV_LOG_ERROR, "No bytes were written to encoded bitstream\n");
679  err = AVERROR(EINVAL);
680  return err;
681  }
682 
683  *size = meta->EncodedBitstreamWrittenBytesCount;
684 
685  ID3D12Resource_Unmap(pic->resolved_metadata, 0, NULL);
686 
687  return 0;
688 }
689 
692 {
693  int err;
694  uint8_t *ptr, *mapped_data;
695  size_t total_size = 0;
696  HRESULT hr;
697 
698  err = d3d12va_encode_get_buffer_size(avctx, pic, &total_size);
699  if (err < 0)
700  goto end;
701 
702  total_size += pic->header_size;
703  av_log(avctx, AV_LOG_DEBUG, "Output buffer size %"SIZE_SPECIFIER"\n", total_size);
704 
705  hr = ID3D12Resource_Map(pic->output_buffer, 0, NULL, (void **)&mapped_data);
706  if (FAILED(hr)) {
707  err = AVERROR_UNKNOWN;
708  goto end;
709  }
710 
711  err = ff_get_encode_buffer(avctx, pkt, total_size, 0);
712  if (err < 0)
713  goto end;
714  ptr = pkt->data;
715 
716  memcpy(ptr, mapped_data, pic->header_size);
717 
718  ptr += pic->header_size;
719  mapped_data += pic->aligned_header_size;
720  total_size -= pic->header_size;
721 
722  memcpy(ptr, mapped_data, total_size);
723 
724  ID3D12Resource_Unmap(pic->output_buffer, 0, NULL);
725 
726 end:
728  pic->output_buffer = NULL;
729  return err;
730 }
731 
733  FFHWBaseEncodePicture *base_pic, AVPacket *pkt)
734 {
735  FFHWBaseEncodeContext *base_ctx = avctx->priv_data;
736  D3D12VAEncodePicture *pic = base_pic->priv;
737  AVPacket *pkt_ptr = pkt;
738  int err;
739 
740  err = d3d12va_encode_wait(avctx, base_pic);
741  if (err < 0)
742  return err;
743 
744  err = d3d12va_encode_get_coded_data(avctx, pic, pkt);
745  if (err < 0)
746  return err;
747 
748  av_log(avctx, AV_LOG_DEBUG, "Output read for pic %"PRId64"/%"PRId64".\n",
749  base_pic->display_order, base_pic->encode_order);
750 
752  pkt_ptr, 0);
753 
754  return 0;
755 }
756 
758 {
759  FFHWBaseEncodeContext *base_ctx = avctx->priv_data;
762  const AVPixFmtDescriptor *desc;
763  int i, depth;
764 
766  if (!desc) {
767  av_log(avctx, AV_LOG_ERROR, "Invalid input pixfmt (%d).\n",
768  base_ctx->input_frames->sw_format);
769  return AVERROR(EINVAL);
770  }
771 
772  depth = desc->comp[0].depth;
773  for (i = 1; i < desc->nb_components; i++) {
774  if (desc->comp[i].depth != depth) {
775  av_log(avctx, AV_LOG_ERROR, "Invalid input pixfmt (%s).\n",
776  desc->name);
777  return AVERROR(EINVAL);
778  }
779  }
780  av_log(avctx, AV_LOG_VERBOSE, "Input surface format is %s.\n",
781  desc->name);
782 
783  av_assert0(ctx->codec->profiles);
784  for (i = 0; (ctx->codec->profiles[i].av_profile !=
785  AV_PROFILE_UNKNOWN); i++) {
786  profile = &ctx->codec->profiles[i];
787  if (depth != profile->depth ||
788  desc->nb_components != profile->nb_components)
789  continue;
790  if (desc->nb_components > 1 &&
791  (desc->log2_chroma_w != profile->log2_chroma_w ||
792  desc->log2_chroma_h != profile->log2_chroma_h))
793  continue;
794  if (avctx->profile != profile->av_profile &&
795  avctx->profile != AV_PROFILE_UNKNOWN)
796  continue;
797 
798  ctx->profile = profile;
799  break;
800  }
801  if (!ctx->profile) {
802  av_log(avctx, AV_LOG_ERROR, "No usable encoding profile found.\n");
803  return AVERROR(ENOSYS);
804  }
805 
806  avctx->profile = profile->av_profile;
807  return 0;
808 }
809 
811  // Bitrate Quality
812  // | Maxrate | HRD/VBV
813  { 0 }, // | | | |
814  { RC_MODE_CQP, "CQP", 0, 0, 1, 0, D3D12_VIDEO_ENCODER_RATE_CONTROL_MODE_CQP },
815  { RC_MODE_CBR, "CBR", 1, 0, 0, 1, D3D12_VIDEO_ENCODER_RATE_CONTROL_MODE_CBR },
816  { RC_MODE_VBR, "VBR", 1, 1, 0, 1, D3D12_VIDEO_ENCODER_RATE_CONTROL_MODE_VBR },
817  { RC_MODE_QVBR, "QVBR", 1, 1, 1, 1, D3D12_VIDEO_ENCODER_RATE_CONTROL_MODE_QVBR },
818 };
819 
821 {
822  HRESULT hr;
824  D3D12_FEATURE_DATA_VIDEO_ENCODER_RATE_CONTROL_MODE d3d12_rc_mode = {
825  .Codec = ctx->codec->d3d12_codec,
826  };
827 
828  if (!rc_mode->d3d12_mode)
829  return 0;
830 
831  d3d12_rc_mode.IsSupported = 0;
832  d3d12_rc_mode.RateControlMode = rc_mode->d3d12_mode;
833 
834  hr = ID3D12VideoDevice3_CheckFeatureSupport(ctx->video_device3,
835  D3D12_FEATURE_VIDEO_ENCODER_RATE_CONTROL_MODE,
836  &d3d12_rc_mode, sizeof(d3d12_rc_mode));
837  if (FAILED(hr)) {
838  av_log(avctx, AV_LOG_ERROR, "Failed to check rate control support.\n");
839  return 0;
840  }
841 
842  return d3d12_rc_mode.IsSupported;
843 }
844 
846 {
848  int64_t rc_target_bitrate;
849  int64_t rc_peak_bitrate;
850  int rc_quality;
851  int64_t hrd_buffer_size;
852  int64_t hrd_initial_buffer_fullness;
853  int fr_num, fr_den;
855 
856  // Rate control mode selection:
857  // * If the user has set a mode explicitly with the rc_mode option,
858  // use it and fail if it is not available.
859  // * If an explicit QP option has been set, use CQP.
860  // * If the codec is CQ-only, use CQP.
861  // * If the QSCALE avcodec option is set, use CQP.
862  // * If bitrate and quality are both set, try QVBR.
863  // * If quality is set, try CQP.
864  // * If bitrate and maxrate are set and have the same value, try CBR.
865  // * If a bitrate is set, try VBR, then CBR.
866  // * If no bitrate is set, try CQP.
867 
868 #define TRY_RC_MODE(mode, fail) do { \
869  rc_mode = &d3d12va_encode_rc_modes[mode]; \
870  if (!(rc_mode->d3d12_mode && check_rate_control_support(avctx, rc_mode))) { \
871  if (fail) { \
872  av_log(avctx, AV_LOG_ERROR, "Driver does not support %s " \
873  "RC mode.\n", rc_mode->name); \
874  return AVERROR(EINVAL); \
875  } \
876  av_log(avctx, AV_LOG_DEBUG, "Driver does not support %s " \
877  "RC mode.\n", rc_mode->name); \
878  rc_mode = NULL; \
879  } else { \
880  goto rc_mode_found; \
881  } \
882  } while (0)
883 
884  if (ctx->explicit_rc_mode)
885  TRY_RC_MODE(ctx->explicit_rc_mode, 1);
886 
887  if (ctx->explicit_qp)
889 
892 
893  if (avctx->flags & AV_CODEC_FLAG_QSCALE)
895 
896  if (avctx->bit_rate > 0 && avctx->global_quality > 0)
898 
899  if (avctx->global_quality > 0) {
901  }
902 
903  if (avctx->bit_rate > 0 && avctx->rc_max_rate == avctx->bit_rate)
905 
906  if (avctx->bit_rate > 0) {
909  } else {
911  }
912 
913  av_log(avctx, AV_LOG_ERROR, "Driver does not support any "
914  "RC mode compatible with selected options.\n");
915  return AVERROR(EINVAL);
916 
917 rc_mode_found:
918  if (rc_mode->bitrate) {
919  if (avctx->bit_rate <= 0) {
920  av_log(avctx, AV_LOG_ERROR, "Bitrate must be set for %s "
921  "RC mode.\n", rc_mode->name);
922  return AVERROR(EINVAL);
923  }
924 
925  if (rc_mode->maxrate) {
926  if (avctx->rc_max_rate > 0) {
927  if (avctx->rc_max_rate < avctx->bit_rate) {
928  av_log(avctx, AV_LOG_ERROR, "Invalid bitrate settings: "
929  "bitrate (%"PRId64") must not be greater than "
930  "maxrate (%"PRId64").\n", avctx->bit_rate,
931  avctx->rc_max_rate);
932  return AVERROR(EINVAL);
933  }
934  rc_target_bitrate = avctx->bit_rate;
935  rc_peak_bitrate = avctx->rc_max_rate;
936  } else {
937  // We only have a target bitrate, but this mode requires
938  // that a maximum rate be supplied as well. Since the
939  // user does not want this to be a constraint, arbitrarily
940  // pick a maximum rate of double the target rate.
941  rc_target_bitrate = avctx->bit_rate;
942  rc_peak_bitrate = 2 * avctx->bit_rate;
943  }
944  } else {
945  if (avctx->rc_max_rate > avctx->bit_rate) {
946  av_log(avctx, AV_LOG_WARNING, "Max bitrate is ignored "
947  "in %s RC mode.\n", rc_mode->name);
948  }
949  rc_target_bitrate = avctx->bit_rate;
950  rc_peak_bitrate = 0;
951  }
952  } else {
953  rc_target_bitrate = 0;
954  rc_peak_bitrate = 0;
955  }
956 
957  if (rc_mode->quality) {
958  if (ctx->explicit_qp) {
959  rc_quality = ctx->explicit_qp;
960  } else if (avctx->global_quality > 0) {
961  if (avctx->flags & AV_CODEC_FLAG_QSCALE)
962  rc_quality = avctx->global_quality / FF_QP2LAMBDA;
963  else
964  rc_quality = avctx->global_quality;
965  } else {
966  rc_quality = ctx->codec->default_quality;
967  av_log(avctx, AV_LOG_WARNING, "No quality level set; "
968  "using default (%d).\n", rc_quality);
969  }
970  } else {
971  rc_quality = 0;
972  }
973 
974  if (rc_mode->hrd) {
975  if (avctx->rc_buffer_size)
976  hrd_buffer_size = avctx->rc_buffer_size;
977  else if (avctx->rc_max_rate > 0)
978  hrd_buffer_size = avctx->rc_max_rate;
979  else
980  hrd_buffer_size = avctx->bit_rate;
981  if (avctx->rc_initial_buffer_occupancy) {
982  if (avctx->rc_initial_buffer_occupancy > hrd_buffer_size) {
983  av_log(avctx, AV_LOG_ERROR, "Invalid RC buffer settings: "
984  "must have initial buffer size (%d) <= "
985  "buffer size (%"PRId64").\n",
986  avctx->rc_initial_buffer_occupancy, hrd_buffer_size);
987  return AVERROR(EINVAL);
988  }
989  hrd_initial_buffer_fullness = avctx->rc_initial_buffer_occupancy;
990  } else {
991  hrd_initial_buffer_fullness = hrd_buffer_size * 3 / 4;
992  }
993  } else {
994  if (avctx->rc_buffer_size || avctx->rc_initial_buffer_occupancy) {
995  av_log(avctx, AV_LOG_WARNING, "Buffering settings are ignored "
996  "in %s RC mode.\n", rc_mode->name);
997  }
998 
999  hrd_buffer_size = 0;
1000  hrd_initial_buffer_fullness = 0;
1001  }
1002 
1003  if (rc_target_bitrate > UINT32_MAX ||
1004  hrd_buffer_size > UINT32_MAX ||
1005  hrd_initial_buffer_fullness > UINT32_MAX) {
1006  av_log(avctx, AV_LOG_ERROR, "RC parameters of 2^32 or "
1007  "greater are not supported by D3D12.\n");
1008  return AVERROR(EINVAL);
1009  }
1010 
1011  ctx->rc_quality = rc_quality;
1012 
1013  av_log(avctx, AV_LOG_VERBOSE, "RC mode: %s.\n", rc_mode->name);
1014 
1015  if (rc_mode->quality)
1016  av_log(avctx, AV_LOG_VERBOSE, "RC quality: %d.\n", rc_quality);
1017 
1018  if (rc_mode->hrd) {
1019  av_log(avctx, AV_LOG_VERBOSE, "RC buffer: %"PRId64" bits, "
1020  "initial fullness %"PRId64" bits.\n",
1021  hrd_buffer_size, hrd_initial_buffer_fullness);
1022  }
1023 
1024  if (avctx->framerate.num > 0 && avctx->framerate.den > 0)
1025  av_reduce(&fr_num, &fr_den,
1026  avctx->framerate.num, avctx->framerate.den, 65535);
1027  else
1028  av_reduce(&fr_num, &fr_den,
1029  avctx->time_base.den, avctx->time_base.num, 65535);
1030 
1031  av_log(avctx, AV_LOG_VERBOSE, "RC framerate: %d/%d (%.2f fps).\n",
1032  fr_num, fr_den, (double)fr_num / fr_den);
1033 
1034  ctx->rc.Flags = D3D12_VIDEO_ENCODER_RATE_CONTROL_FLAG_NONE;
1035  ctx->rc.TargetFrameRate.Numerator = fr_num;
1036  ctx->rc.TargetFrameRate.Denominator = fr_den;
1037  ctx->rc.Mode = rc_mode->d3d12_mode;
1038 
1039  switch (rc_mode->mode) {
1040  case RC_MODE_CQP:
1041  // cqp ConfigParams will be updated in ctx->codec->configure.
1042  break;
1043  case RC_MODE_CBR: {
1044  D3D12_VIDEO_ENCODER_RATE_CONTROL_CBR *cbr_ctl;
1045 
1046  ctx->rc.ConfigParams.DataSize = sizeof(D3D12_VIDEO_ENCODER_RATE_CONTROL_CBR);
1047  cbr_ctl = av_mallocz(ctx->rc.ConfigParams.DataSize);
1048  if (!cbr_ctl)
1049  return AVERROR(ENOMEM);
1050 
1051  cbr_ctl->TargetBitRate = rc_target_bitrate;
1052  cbr_ctl->VBVCapacity = hrd_buffer_size;
1053  cbr_ctl->InitialVBVFullness = hrd_initial_buffer_fullness;
1054  ctx->rc.Flags |= D3D12_VIDEO_ENCODER_RATE_CONTROL_FLAG_ENABLE_VBV_SIZES;
1055 
1056  if (avctx->qmin > 0 || avctx->qmax > 0) {
1057  cbr_ctl->MinQP = avctx->qmin;
1058  cbr_ctl->MaxQP = avctx->qmax;
1059  ctx->rc.Flags |= D3D12_VIDEO_ENCODER_RATE_CONTROL_FLAG_ENABLE_QP_RANGE;
1060  }
1061 
1062  if (ctx->max_frame_size > 0) {
1063  cbr_ctl->MaxFrameBitSize = ctx->max_frame_size * 8;
1064  ctx->rc.Flags |= D3D12_VIDEO_ENCODER_RATE_CONTROL_FLAG_ENABLE_MAX_FRAME_SIZE;
1065  }
1066 
1067  ctx->rc.ConfigParams.pConfiguration_CBR = cbr_ctl;
1068  break;
1069  }
1070  case RC_MODE_VBR: {
1071  D3D12_VIDEO_ENCODER_RATE_CONTROL_VBR *vbr_ctl;
1072 
1073  ctx->rc.ConfigParams.DataSize = sizeof(D3D12_VIDEO_ENCODER_RATE_CONTROL_VBR);
1074  vbr_ctl = av_mallocz(ctx->rc.ConfigParams.DataSize);
1075  if (!vbr_ctl)
1076  return AVERROR(ENOMEM);
1077 
1078  vbr_ctl->TargetAvgBitRate = rc_target_bitrate;
1079  vbr_ctl->PeakBitRate = rc_peak_bitrate;
1080  vbr_ctl->VBVCapacity = hrd_buffer_size;
1081  vbr_ctl->InitialVBVFullness = hrd_initial_buffer_fullness;
1082  ctx->rc.Flags |= D3D12_VIDEO_ENCODER_RATE_CONTROL_FLAG_ENABLE_VBV_SIZES;
1083 
1084  if (avctx->qmin > 0 || avctx->qmax > 0) {
1085  vbr_ctl->MinQP = avctx->qmin;
1086  vbr_ctl->MaxQP = avctx->qmax;
1087  ctx->rc.Flags |= D3D12_VIDEO_ENCODER_RATE_CONTROL_FLAG_ENABLE_QP_RANGE;
1088  }
1089 
1090  if (ctx->max_frame_size > 0) {
1091  vbr_ctl->MaxFrameBitSize = ctx->max_frame_size * 8;
1092  ctx->rc.Flags |= D3D12_VIDEO_ENCODER_RATE_CONTROL_FLAG_ENABLE_MAX_FRAME_SIZE;
1093  }
1094 
1095  ctx->rc.ConfigParams.pConfiguration_VBR = vbr_ctl;
1096  break;
1097  }
1098  case RC_MODE_QVBR: {
1099  D3D12_VIDEO_ENCODER_RATE_CONTROL_QVBR *qvbr_ctl;
1100 
1101  ctx->rc.ConfigParams.DataSize = sizeof(D3D12_VIDEO_ENCODER_RATE_CONTROL_QVBR);
1102  qvbr_ctl = av_mallocz(ctx->rc.ConfigParams.DataSize);
1103  if (!qvbr_ctl)
1104  return AVERROR(ENOMEM);
1105 
1106  qvbr_ctl->TargetAvgBitRate = rc_target_bitrate;
1107  qvbr_ctl->PeakBitRate = rc_peak_bitrate;
1108  qvbr_ctl->ConstantQualityTarget = rc_quality;
1109 
1110  if (avctx->qmin > 0 || avctx->qmax > 0) {
1111  qvbr_ctl->MinQP = avctx->qmin;
1112  qvbr_ctl->MaxQP = avctx->qmax;
1113  ctx->rc.Flags |= D3D12_VIDEO_ENCODER_RATE_CONTROL_FLAG_ENABLE_QP_RANGE;
1114  }
1115 
1116  if (ctx->max_frame_size > 0) {
1117  qvbr_ctl->MaxFrameBitSize = ctx->max_frame_size * 8;
1118  ctx->rc.Flags |= D3D12_VIDEO_ENCODER_RATE_CONTROL_FLAG_ENABLE_MAX_FRAME_SIZE;
1119  }
1120 
1121  ctx->rc.ConfigParams.pConfiguration_QVBR = qvbr_ctl;
1122  break;
1123  }
1124  default:
1125  break;
1126  }
1127  return 0;
1128 }
1129 
1131 {
1132  FFHWBaseEncodeContext *base_ctx = avctx->priv_data;
1134  uint32_t ref_l0, ref_l1;
1135  int err;
1136  HRESULT hr;
1137  D3D12_FEATURE_DATA_VIDEO_ENCODER_CODEC_PICTURE_CONTROL_SUPPORT support;
1138  union {
1139  D3D12_VIDEO_ENCODER_CODEC_PICTURE_CONTROL_SUPPORT_H264 h264;
1140  D3D12_VIDEO_ENCODER_CODEC_PICTURE_CONTROL_SUPPORT_HEVC hevc;
1141  } codec_support;
1142 
1143  support.NodeIndex = 0;
1144  support.Codec = ctx->codec->d3d12_codec;
1145  support.Profile = ctx->profile->d3d12_profile;
1146 
1147  switch (ctx->codec->d3d12_codec) {
1148  case D3D12_VIDEO_ENCODER_CODEC_H264:
1149  support.PictureSupport.DataSize = sizeof(codec_support.h264);
1150  support.PictureSupport.pH264Support = &codec_support.h264;
1151  break;
1152 
1153  case D3D12_VIDEO_ENCODER_CODEC_HEVC:
1154  support.PictureSupport.DataSize = sizeof(codec_support.hevc);
1155  support.PictureSupport.pHEVCSupport = &codec_support.hevc;
1156  break;
1157 
1158  default:
1159  av_assert0(0);
1160  }
1161 
1162  hr = ID3D12VideoDevice3_CheckFeatureSupport(ctx->video_device3, D3D12_FEATURE_VIDEO_ENCODER_CODEC_PICTURE_CONTROL_SUPPORT,
1163  &support, sizeof(support));
1164  if (FAILED(hr))
1165  return AVERROR(EINVAL);
1166 
1167  if (support.IsSupported) {
1168  switch (ctx->codec->d3d12_codec) {
1169  case D3D12_VIDEO_ENCODER_CODEC_H264:
1170  ref_l0 = FFMIN(support.PictureSupport.pH264Support->MaxL0ReferencesForP,
1171  support.PictureSupport.pH264Support->MaxL1ReferencesForB ?
1172  support.PictureSupport.pH264Support->MaxL1ReferencesForB : UINT_MAX);
1173  ref_l1 = support.PictureSupport.pH264Support->MaxL1ReferencesForB;
1174  break;
1175 
1176  case D3D12_VIDEO_ENCODER_CODEC_HEVC:
1177  ref_l0 = FFMIN(support.PictureSupport.pHEVCSupport->MaxL0ReferencesForP,
1178  support.PictureSupport.pHEVCSupport->MaxL1ReferencesForB ?
1179  support.PictureSupport.pHEVCSupport->MaxL1ReferencesForB : UINT_MAX);
1180  ref_l1 = support.PictureSupport.pHEVCSupport->MaxL1ReferencesForB;
1181  break;
1182 
1183  default:
1184  av_assert0(0);
1185  }
1186  } else {
1187  ref_l0 = ref_l1 = 0;
1188  }
1189 
1190  if (ref_l0 > 0 && ref_l1 > 0 && ctx->bi_not_empty) {
1191  base_ctx->p_to_gpb = 1;
1192  av_log(avctx, AV_LOG_VERBOSE, "Driver does not support P-frames, "
1193  "replacing them with B-frames.\n");
1194  }
1195 
1196  err = ff_hw_base_init_gop_structure(base_ctx, avctx, ref_l0, ref_l1, ctx->codec->flags, 0);
1197  if (err < 0)
1198  return err;
1199 
1200  return 0;
1201 }
1202 
1204 {
1205  FFHWBaseEncodeContext *base_ctx = avctx->priv_data;
1207  AVD3D12VAFramesContext *frames_hwctx = base_ctx->input_frames->hwctx;
1208  HRESULT hr;
1209 
1210  D3D12_VIDEO_ENCODER_DESC desc = {
1211  .NodeMask = 0,
1212  .Flags = D3D12_VIDEO_ENCODER_FLAG_NONE,
1213  .EncodeCodec = ctx->codec->d3d12_codec,
1214  .EncodeProfile = ctx->profile->d3d12_profile,
1215  .InputFormat = frames_hwctx->format,
1216  .CodecConfiguration = ctx->codec_conf,
1217  .MaxMotionEstimationPrecision = D3D12_VIDEO_ENCODER_MOTION_ESTIMATION_PRECISION_MODE_MAXIMUM,
1218  };
1219 
1220  hr = ID3D12VideoDevice3_CreateVideoEncoder(ctx->video_device3, &desc, &IID_ID3D12VideoEncoder,
1221  (void **)&ctx->encoder);
1222  if (FAILED(hr)) {
1223  av_log(avctx, AV_LOG_ERROR, "Failed to create encoder.\n");
1224  return AVERROR(EINVAL);
1225  }
1226 
1227  return 0;
1228 }
1229 
1231 {
1233  HRESULT hr;
1234 
1235  D3D12_VIDEO_ENCODER_HEAP_DESC desc = {
1236  .NodeMask = 0,
1237  .Flags = D3D12_VIDEO_ENCODER_HEAP_FLAG_NONE,
1238  .EncodeCodec = ctx->codec->d3d12_codec,
1239  .EncodeProfile = ctx->profile->d3d12_profile,
1240  .EncodeLevel = ctx->level,
1241  .ResolutionsListCount = 1,
1242  .pResolutionList = &ctx->resolution,
1243  };
1244 
1245  hr = ID3D12VideoDevice3_CreateVideoEncoderHeap(ctx->video_device3, &desc,
1246  &IID_ID3D12VideoEncoderHeap, (void **)&ctx->encoder_heap);
1247  if (FAILED(hr)) {
1248  av_log(avctx, AV_LOG_ERROR, "Failed to create encoder heap.\n");
1249  return AVERROR(EINVAL);
1250  }
1251 
1252  return 0;
1253 }
1254 
1255 static void d3d12va_encode_free_buffer(void *opaque, uint8_t *data)
1256 {
1257  ID3D12Resource *pResource;
1258 
1259  pResource = (ID3D12Resource *)data;
1260  D3D12_OBJECT_RELEASE(pResource);
1261 }
1262 
1264 {
1265  AVCodecContext *avctx = opaque;
1266  FFHWBaseEncodeContext *base_ctx = avctx->priv_data;
1268  ID3D12Resource *pResource = NULL;
1269  HRESULT hr;
1270  AVBufferRef *ref;
1271  D3D12_HEAP_PROPERTIES heap_props;
1272  D3D12_HEAP_TYPE heap_type = D3D12_HEAP_TYPE_READBACK;
1273 
1274  D3D12_RESOURCE_DESC desc = {
1275  .Dimension = D3D12_RESOURCE_DIMENSION_BUFFER,
1276  .Alignment = 0,
1277  .Width = FFALIGN(3 * base_ctx->surface_width * base_ctx->surface_height + (1 << 16),
1278  D3D12_TEXTURE_DATA_PLACEMENT_ALIGNMENT),
1279  .Height = 1,
1280  .DepthOrArraySize = 1,
1281  .MipLevels = 1,
1282  .Format = DXGI_FORMAT_UNKNOWN,
1283  .SampleDesc = { .Count = 1, .Quality = 0 },
1284  .Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR,
1285  .Flags = D3D12_RESOURCE_FLAG_NONE,
1286  };
1287 
1288  ctx->hwctx->device->lpVtbl->GetCustomHeapProperties(ctx->hwctx->device, &heap_props, 0, heap_type);
1289 
1290  hr = ID3D12Device_CreateCommittedResource(ctx->hwctx->device, &heap_props, D3D12_HEAP_FLAG_NONE,
1291  &desc, D3D12_RESOURCE_STATE_COMMON, NULL, &IID_ID3D12Resource,
1292  (void **)&pResource);
1293 
1294  if (FAILED(hr)) {
1295  av_log(avctx, AV_LOG_ERROR, "Failed to create d3d12 buffer.\n");
1296  return NULL;
1297  }
1298 
1299  ref = av_buffer_create((uint8_t *)(uintptr_t)pResource,
1300  sizeof(pResource),
1302  avctx, AV_BUFFER_FLAG_READONLY);
1303  if (!ref) {
1304  D3D12_OBJECT_RELEASE(pResource);
1305  return NULL;
1306  }
1307 
1308  return ref;
1309 }
1310 
1312 {
1313  FFHWBaseEncodeContext *base_ctx = avctx->priv_data;
1315  AVD3D12VAFramesContext *frames_ctx = base_ctx->input_frames->hwctx;
1316  HRESULT hr;
1317 
1318  ctx->req.NodeIndex = 0;
1319  ctx->req.Codec = ctx->codec->d3d12_codec;
1320  ctx->req.Profile = ctx->profile->d3d12_profile;
1321  ctx->req.InputFormat = frames_ctx->format;
1322  ctx->req.PictureTargetResolution = ctx->resolution;
1323 
1324  hr = ID3D12VideoDevice3_CheckFeatureSupport(ctx->video_device3,
1325  D3D12_FEATURE_VIDEO_ENCODER_RESOURCE_REQUIREMENTS,
1326  &ctx->req, sizeof(ctx->req));
1327  if (FAILED(hr)) {
1328  av_log(avctx, AV_LOG_ERROR, "Failed to check encoder resource requirements support.\n");
1329  return AVERROR(EINVAL);
1330  }
1331 
1332  if (!ctx->req.IsSupported) {
1333  av_log(avctx, AV_LOG_ERROR, "Encoder resource requirements unsupported.\n");
1334  return AVERROR(EINVAL);
1335  }
1336 
1337  ctx->output_buffer_pool = av_buffer_pool_init2(sizeof(ID3D12Resource *), avctx,
1339  if (!ctx->output_buffer_pool)
1340  return AVERROR(ENOMEM);
1341 
1342  return 0;
1343 }
1344 
1346 {
1348  ID3D12CommandAllocator *command_allocator = NULL;
1349  int err = AVERROR_UNKNOWN;
1350  HRESULT hr;
1351 
1352  D3D12_COMMAND_QUEUE_DESC queue_desc = {
1353  .Type = D3D12_COMMAND_LIST_TYPE_VIDEO_ENCODE,
1354  .Priority = 0,
1355  .Flags = D3D12_COMMAND_QUEUE_FLAG_NONE,
1356  .NodeMask = 0,
1357  };
1358 
1361  if (!ctx->allocator_queue)
1362  return AVERROR(ENOMEM);
1363 
1364  hr = ID3D12Device_CreateFence(ctx->hwctx->device, 0, D3D12_FENCE_FLAG_NONE,
1365  &IID_ID3D12Fence, (void **)&ctx->sync_ctx.fence);
1366  if (FAILED(hr)) {
1367  av_log(avctx, AV_LOG_ERROR, "Failed to create fence(%lx)\n", (long)hr);
1368  err = AVERROR_UNKNOWN;
1369  goto fail;
1370  }
1371 
1372  ctx->sync_ctx.event = CreateEvent(NULL, FALSE, FALSE, NULL);
1373  if (!ctx->sync_ctx.event)
1374  goto fail;
1375 
1376  err = d3d12va_get_valid_command_allocator(avctx, &command_allocator);
1377  if (err < 0)
1378  goto fail;
1379 
1380  hr = ID3D12Device_CreateCommandQueue(ctx->hwctx->device, &queue_desc,
1381  &IID_ID3D12CommandQueue, (void **)&ctx->command_queue);
1382  if (FAILED(hr)) {
1383  av_log(avctx, AV_LOG_ERROR, "Failed to create command queue(%lx)\n", (long)hr);
1384  err = AVERROR_UNKNOWN;
1385  goto fail;
1386  }
1387 
1388  hr = ID3D12Device_CreateCommandList(ctx->hwctx->device, 0, queue_desc.Type,
1389  command_allocator, NULL, &IID_ID3D12CommandList,
1390  (void **)&ctx->command_list);
1391  if (FAILED(hr)) {
1392  av_log(avctx, AV_LOG_ERROR, "Failed to create command list(%lx)\n", (long)hr);
1393  err = AVERROR_UNKNOWN;
1394  goto fail;
1395  }
1396 
1397  hr = ID3D12VideoEncodeCommandList2_Close(ctx->command_list);
1398  if (FAILED(hr)) {
1399  av_log(avctx, AV_LOG_ERROR, "Failed to close the command list(%lx)\n", (long)hr);
1400  err = AVERROR_UNKNOWN;
1401  goto fail;
1402  }
1403 
1404  ID3D12CommandQueue_ExecuteCommandLists(ctx->command_queue, 1, (ID3D12CommandList **)&ctx->command_list);
1405 
1406  err = d3d12va_sync_with_gpu(avctx);
1407  if (err < 0)
1408  goto fail;
1409 
1410  err = d3d12va_discard_command_allocator(avctx, command_allocator, ctx->sync_ctx.fence_value);
1411  if (err < 0)
1412  goto fail;
1413 
1414  return 0;
1415 
1416 fail:
1417  D3D12_OBJECT_RELEASE(command_allocator);
1418  return err;
1419 }
1420 
1422 {
1423  FFHWBaseEncodeContext *base_ctx = avctx->priv_data;
1425  AVD3D12VAFramesContext *hwctx;
1426  enum AVPixelFormat recon_format;
1427  int err;
1428 
1429  err = ff_hw_base_get_recon_format(base_ctx, NULL, &recon_format);
1430  if (err < 0)
1431  return err;
1432 
1433  base_ctx->recon_frames_ref = av_hwframe_ctx_alloc(base_ctx->device_ref);
1434  if (!base_ctx->recon_frames_ref)
1435  return AVERROR(ENOMEM);
1436 
1437  base_ctx->recon_frames = (AVHWFramesContext *)base_ctx->recon_frames_ref->data;
1438  hwctx = (AVD3D12VAFramesContext *)base_ctx->recon_frames->hwctx;
1439 
1440  base_ctx->recon_frames->format = AV_PIX_FMT_D3D12;
1441  base_ctx->recon_frames->sw_format = recon_format;
1442  base_ctx->recon_frames->width = base_ctx->surface_width;
1443  base_ctx->recon_frames->height = base_ctx->surface_height;
1444 
1445  hwctx->resource_flags = D3D12_RESOURCE_FLAG_VIDEO_ENCODE_REFERENCE_ONLY |
1446  D3D12_RESOURCE_FLAG_DENY_SHADER_RESOURCE;
1447  if (ctx->is_texture_array) {
1448  base_ctx->recon_frames->initial_pool_size = MAX_DPB_SIZE + 1;
1450  }
1451 
1452  err = av_hwframe_ctx_init(base_ctx->recon_frames_ref);
1453  if (err < 0) {
1454  av_log(avctx, AV_LOG_ERROR, "Failed to initialise reconstructed "
1455  "frame context: %d.\n", err);
1456  return err;
1457  }
1458 
1459  return 0;
1460 }
1461 
1463  .priv_size = sizeof(D3D12VAEncodePicture),
1464 
1466 
1467  .issue = &d3d12va_encode_issue,
1468 
1470 
1471  .free = &d3d12va_encode_free,
1472 };
1473 
1475 {
1476  return ff_hw_base_encode_receive_packet(avctx->priv_data, avctx, pkt);
1477 }
1478 
1480 {
1481  FFHWBaseEncodeContext *base_ctx = avctx->priv_data;
1483  D3D12_FEATURE_DATA_VIDEO_FEATURE_AREA_SUPPORT support = { 0 };
1484  D3D12_FEATURE_DATA_FORMAT_INFO format_info = { 0 };
1485  int err;
1486  HRESULT hr;
1487 
1488  err = ff_hw_base_encode_init(avctx, base_ctx);
1489  if (err < 0)
1490  goto fail;
1491 
1492  base_ctx->op = &d3d12va_type;
1493 
1494  ctx->hwctx = base_ctx->device->hwctx;
1495 
1496  ctx->resolution.Width = base_ctx->input_frames->width;
1497  ctx->resolution.Height = base_ctx->input_frames->height;
1498 
1499  hr = ID3D12Device_QueryInterface(ctx->hwctx->device, &IID_ID3D12Device3, (void **)&ctx->device3);
1500  if (FAILED(hr)) {
1501  av_log(avctx, AV_LOG_ERROR, "ID3D12Device3 interface is not supported.\n");
1502  err = AVERROR_UNKNOWN;
1503  goto fail;
1504  }
1505 
1506  hr = ID3D12Device3_QueryInterface(ctx->device3, &IID_ID3D12VideoDevice3, (void **)&ctx->video_device3);
1507  if (FAILED(hr)) {
1508  av_log(avctx, AV_LOG_ERROR, "ID3D12VideoDevice3 interface is not supported.\n");
1509  err = AVERROR_UNKNOWN;
1510  goto fail;
1511  }
1512 
1513  if (FAILED(ID3D12VideoDevice3_CheckFeatureSupport(ctx->video_device3, D3D12_FEATURE_VIDEO_FEATURE_AREA_SUPPORT,
1514  &support, sizeof(support))) && !support.VideoEncodeSupport) {
1515  av_log(avctx, AV_LOG_ERROR, "D3D12 video device has no video encoder support.\n");
1516  err = AVERROR(EINVAL);
1517  goto fail;
1518  }
1519 
1520  format_info.Format = ((AVD3D12VAFramesContext *)base_ctx->input_frames->hwctx)->format;
1521  if (FAILED(ID3D12VideoDevice_CheckFeatureSupport(ctx->hwctx->device, D3D12_FEATURE_FORMAT_INFO,
1522  &format_info, sizeof(format_info)))) {
1523  av_log(avctx, AV_LOG_ERROR, "Failed to query format plane count: 0x%x\n", hr);
1524  err = AVERROR_EXTERNAL;
1525  goto fail;
1526  }
1527  ctx->plane_count = format_info.PlaneCount;
1528 
1529  err = d3d12va_encode_set_profile(avctx);
1530  if (err < 0)
1531  goto fail;
1532 
1533  err = d3d12va_encode_init_rate_control(avctx);
1534  if (err < 0)
1535  goto fail;
1536 
1537  if (ctx->codec->get_encoder_caps) {
1538  err = ctx->codec->get_encoder_caps(avctx);
1539  if (err < 0)
1540  goto fail;
1541  }
1542 
1543  err = d3d12va_encode_init_gop_structure(avctx);
1544  if (err < 0)
1545  goto fail;
1546 
1547  if (!(ctx->codec->flags & FF_HW_FLAG_SLICE_CONTROL) && avctx->slices > 0) {
1548  av_log(avctx, AV_LOG_WARNING, "Multiple slices were requested "
1549  "but this codec does not support controlling slices.\n");
1550  }
1551 
1553  if (err < 0)
1554  goto fail;
1555 
1557  if (err < 0)
1558  goto fail;
1559 
1560  if (ctx->codec->configure) {
1561  err = ctx->codec->configure(avctx);
1562  if (err < 0)
1563  goto fail;
1564  }
1565 
1566  if (ctx->codec->init_sequence_params) {
1567  err = ctx->codec->init_sequence_params(avctx);
1568  if (err < 0) {
1569  av_log(avctx, AV_LOG_ERROR, "Codec sequence initialisation "
1570  "failed: %d.\n", err);
1571  goto fail;
1572  }
1573  }
1574 
1575  if (ctx->codec->set_level) {
1576  err = ctx->codec->set_level(avctx);
1577  if (err < 0)
1578  goto fail;
1579  }
1580 
1582  if (err < 0)
1583  goto fail;
1584 
1585  base_ctx->output_delay = base_ctx->b_per_p;
1586  base_ctx->decode_delay = base_ctx->max_b_depth;
1587 
1588  err = d3d12va_create_encoder(avctx);
1589  if (err < 0)
1590  goto fail;
1591 
1592  err = d3d12va_create_encoder_heap(avctx);
1593  if (err < 0)
1594  goto fail;
1595 
1596  base_ctx->async_encode = 1;
1597  base_ctx->encode_fifo = av_fifo_alloc2(base_ctx->async_depth,
1598  sizeof(D3D12VAEncodePicture *), 0);
1599  if (!base_ctx->encode_fifo)
1600  return AVERROR(ENOMEM);
1601 
1602  return 0;
1603 
1604 fail:
1605  return err;
1606 }
1607 
1609 {
1610  int num_allocator = 0;
1611  FFHWBaseEncodeContext *base_ctx = avctx->priv_data;
1613  FFHWBaseEncodePicture *pic, *next;
1614  CommandAllocator allocator;
1615 
1616  if (!base_ctx->frame)
1617  return 0;
1618 
1619  for (pic = base_ctx->pic_start; pic; pic = next) {
1620  next = pic->next;
1621  d3d12va_encode_free(avctx, pic);
1622  }
1623 
1625 
1626  av_buffer_pool_uninit(&ctx->output_buffer_pool);
1627 
1628  D3D12_OBJECT_RELEASE(ctx->command_list);
1629  D3D12_OBJECT_RELEASE(ctx->command_queue);
1630 
1631  if (ctx->allocator_queue) {
1632  while (av_fifo_read(ctx->allocator_queue, &allocator, 1) >= 0) {
1633  num_allocator++;
1635  }
1636 
1637  av_log(avctx, AV_LOG_VERBOSE, "Total number of command allocators reused: %d\n", num_allocator);
1638  }
1639 
1640  av_fifo_freep2(&ctx->allocator_queue);
1641 
1642  D3D12_OBJECT_RELEASE(ctx->sync_ctx.fence);
1643  if (ctx->sync_ctx.event)
1644  CloseHandle(ctx->sync_ctx.event);
1645 
1646  D3D12_OBJECT_RELEASE(ctx->encoder_heap);
1647  D3D12_OBJECT_RELEASE(ctx->encoder);
1648  D3D12_OBJECT_RELEASE(ctx->video_device3);
1649  D3D12_OBJECT_RELEASE(ctx->device3);
1650 
1651  ff_hw_base_encode_close(base_ctx);
1652 
1653  return 0;
1654 }
FFHWBaseEncodeContext::output_delay
int64_t output_delay
Definition: hw_base_encode.h:169
AVHWDeviceContext::hwctx
void * hwctx
The format-specific data, allocated and freed by libavutil along with this context.
Definition: hwcontext.h:88
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
AVPixelFormat
AVPixelFormat
Pixel format.
Definition: pixfmt.h:71
FFHWBaseEncodeContext::recon_frames_ref
AVBufferRef * recon_frames_ref
Definition: hw_base_encode.h:156
FFHWBaseEncodePicture::next
struct FFHWBaseEncodePicture * next
Definition: hw_base_encode.h:67
d3d12va_encode_set_profile
static int d3d12va_encode_set_profile(AVCodecContext *avctx)
Definition: d3d12va_encode.c:757
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
FFHWBaseEncodePicture::priv
void * priv
Definition: hw_base_encode.h:63
FFHWBaseEncodePicture::codec_priv
void * codec_priv
Definition: hw_base_encode.h:65
av_pix_fmt_desc_get
const AVPixFmtDescriptor * av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt)
Definition: pixdesc.c:3447
AVBufferRef::data
uint8_t * data
The data buffer.
Definition: buffer.h:90
AVHWFramesContext::format
enum AVPixelFormat format
The pixel format identifying the underlying HW surface type.
Definition: hwcontext.h:200
AV_CODEC_FLAG_QSCALE
#define AV_CODEC_FLAG_QSCALE
Use fixed qscale.
Definition: avcodec.h:213
int64_t
long long int64_t
Definition: coverity.c:34
output
filter_frame For filters that do not use the this method is called when a frame is pushed to the filter s input It can be called at any time except in a reentrant way If the input frame is enough to produce output
Definition: filter_design.txt:226
d3d12va_encode_create_recon_frames
static int d3d12va_encode_create_recon_frames(AVCodecContext *avctx)
Definition: d3d12va_encode.c:1421
av_frame_free
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition: frame.c:64
av_fifo_peek
int av_fifo_peek(const AVFifo *f, void *buf, size_t nb_elems, size_t offset)
Read data from a FIFO without modifying FIFO state.
Definition: fifo.c:255
av_hwframe_ctx_init
int av_hwframe_ctx_init(AVBufferRef *ref)
Finalize the context before use.
Definition: hwcontext.c:337
AVFrame
This structure describes decoded (raw) audio or video data.
Definition: frame.h:427
pixdesc.h
D3D12VAEncodePicture::input_surface
AVD3D12VAFrame * input_surface
Definition: d3d12va_encode.h:46
av_hwframe_ctx_alloc
AVBufferRef * av_hwframe_ctx_alloc(AVBufferRef *device_ref_in)
Allocate an AVHWFramesContext tied to a given device context.
Definition: hwcontext.c:263
AVPacket::data
uint8_t * data
Definition: packet.h:558
ff_hw_base_encode_init
int ff_hw_base_encode_init(AVCodecContext *avctx, FFHWBaseEncodeContext *ctx)
Definition: hw_base_encode.c:781
encode.h
d3d12va_encode.h
d3d12va_encode_get_coded_data
static int d3d12va_encode_get_coded_data(AVCodecContext *avctx, D3D12VAEncodePicture *pic, AVPacket *pkt)
Definition: d3d12va_encode.c:690
data
const char data[16]
Definition: mxf.c:149
FFHWBaseEncodePicture::recon_image
AVFrame * recon_image
Definition: hw_base_encode.h:84
AV_LOG_VERBOSE
#define AV_LOG_VERBOSE
Detailed information.
Definition: log.h:226
AVERROR_UNKNOWN
#define AVERROR_UNKNOWN
Unknown error, typically from an external library.
Definition: error.h:73
AVHWFramesContext::width
int width
The allocated dimensions of the frames in this pool.
Definition: hwcontext.h:220
AVCodecContext::qmax
int qmax
maximum quantizer
Definition: avcodec.h:1241
AVFrame::data
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition: frame.h:448
D3D12VAEncodePicture::resolved_metadata
ID3D12Resource * resolved_metadata
Definition: d3d12va_encode.h:53
FFHWBaseEncodeContext
Definition: hw_base_encode.h:122
AVCodecContext::framerate
AVRational framerate
Definition: avcodec.h:551
d3d12va_encode_output
static int d3d12va_encode_output(AVCodecContext *avctx, FFHWBaseEncodePicture *base_pic, AVPacket *pkt)
Definition: d3d12va_encode.c:732
ff_d3d12va_encode_hw_configs
const AVCodecHWConfigInternal *const ff_d3d12va_encode_hw_configs[]
Definition: d3d12va_encode.c:36
D3D12VAEncodePicture::output_buffer_ref
AVBufferRef * output_buffer_ref
Definition: d3d12va_encode.h:49
d3d12va_encode_free
static int d3d12va_encode_free(AVCodecContext *avctx, FFHWBaseEncodePicture *pic)
Definition: d3d12va_encode.c:641
d3d12va_sync_with_gpu
static int d3d12va_sync_with_gpu(AVCodecContext *avctx)
Definition: d3d12va_encode.c:54
FFHWBaseEncodePicture::type
int type
Definition: hw_base_encode.h:78
ff_hw_base_encode_close
int ff_hw_base_encode_close(FFHWBaseEncodeContext *ctx)
Definition: hw_base_encode.c:814
FFHWBaseEncodePicture::is_reference
int is_reference
Definition: hw_base_encode.h:87
fail
#define fail()
Definition: checkasm.h:200
av_fifo_write
int av_fifo_write(AVFifo *f, const void *buf, size_t nb_elems)
Write data into a FIFO.
Definition: fifo.c:188
D3D12VAEncodePicture::output_buffer
ID3D12Resource * output_buffer
Definition: d3d12va_encode.h:50
CommandAllocator::command_allocator
ID3D12CommandAllocator * command_allocator
Definition: d3d12va_encode.c:66
D3D12VAEncodePicture::recon_surface
AVD3D12VAFrame * recon_surface
Definition: d3d12va_encode.h:47
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
AVCodecContext::flags
int flags
AV_CODEC_FLAG_*.
Definition: avcodec.h:488
FFHWBaseEncodePicture::input_image
AVFrame * input_image
Definition: hw_base_encode.h:83
CommandAllocator::fence_value
uint64_t fence_value
Definition: d3d12va_encode.c:67
ff_hw_base_init_gop_structure
int ff_hw_base_init_gop_structure(FFHWBaseEncodeContext *ctx, AVCodecContext *avctx, uint32_t ref_l0, uint32_t ref_l1, int flags, int prediction_pre_only)
Definition: hw_base_encode.c:662
av_reduce
int av_reduce(int *dst_num, int *dst_den, int64_t num, int64_t den, int64_t max)
Reduce a fraction.
Definition: rational.c:35
AVRational::num
int num
Numerator.
Definition: rational.h:59
FFHWBaseEncodeContext::device
AVHWDeviceContext * device
Definition: hw_base_encode.h:149
avassert.h
d3d12va_encode_rc_modes
static const D3D12VAEncodeRCMode d3d12va_encode_rc_modes[]
Definition: d3d12va_encode.c:810
check_rate_control_support
static int check_rate_control_support(AVCodecContext *avctx, const D3D12VAEncodeRCMode *rc_mode)
Definition: d3d12va_encode.c:820
ff_hw_base_get_recon_format
int ff_hw_base_get_recon_format(FFHWBaseEncodeContext *ctx, const void *hwconfig, enum AVPixelFormat *fmt)
Definition: hw_base_encode.c:723
d3d12va_encode_get_buffer_size
static int d3d12va_encode_get_buffer_size(AVCodecContext *avctx, D3D12VAEncodePicture *pic, size_t *size)
Definition: d3d12va_encode.c:655
pkt
AVPacket * pkt
Definition: movenc.c:60
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:210
AV_PROFILE_UNKNOWN
#define AV_PROFILE_UNKNOWN
Definition: defs.h:65
d3d12va_encode_wait
static int d3d12va_encode_wait(AVCodecContext *avctx, FFHWBaseEncodePicture *base_pic)
Definition: d3d12va_encode.c:109
av_fifo_read
int av_fifo_read(AVFifo *f, void *buf, size_t nb_elems)
Read data from a FIFO.
Definition: fifo.c:240
AVCodecContext::rc_initial_buffer_occupancy
int rc_initial_buffer_occupancy
Number of bits which should be loaded into the rc buffer before decoding starts.
Definition: avcodec.h:1298
AVHWFramesContext::height
int height
Definition: hwcontext.h:220
d3d12va_encode_issue
static int d3d12va_encode_issue(AVCodecContext *avctx, FFHWBaseEncodePicture *base_pic)
Definition: d3d12va_encode.c:188
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
AVCodecContext::global_quality
int global_quality
Global quality for codecs which cannot change it per frame.
Definition: avcodec.h:1217
D3D12_OBJECT_RELEASE
#define D3D12_OBJECT_RELEASE(pInterface)
A release macro used by D3D12 objects highly frequently.
Definition: hwcontext_d3d12va_internal.h:51
D3D12VAEncodePicture::header_size
int header_size
Definition: d3d12va_encode.h:43
AV_BUFFER_FLAG_READONLY
#define AV_BUFFER_FLAG_READONLY
Always treat the buffer as read-only, even when it has only one reference.
Definition: buffer.h:114
AVFormatContext::flags
int flags
Flags modifying the (de)muxer behaviour.
Definition: avformat.h:1415
FFHWBaseEncodeContext::max_b_depth
int max_b_depth
Definition: hw_base_encode.h:188
FFHWBaseEncodeContext::async_encode
int async_encode
Definition: hw_base_encode.h:216
AVD3D12VAFrame::sync_ctx
AVD3D12VASyncContext sync_ctx
The sync context for the texture.
Definition: hwcontext_d3d12va.h:159
av_assert0
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition: avassert.h:41
d3d12va_create_encoder_heap
static int d3d12va_create_encoder_heap(AVCodecContext *avctx)
Definition: d3d12va_encode.c:1230
AV_LOG_DEBUG
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:231
ctx
AVFormatContext * ctx
Definition: movenc.c:49
D3D12VAEncodePicture::pic_ctl
D3D12_VIDEO_ENCODER_PICTURE_CONTROL_CODEC_DATA pic_ctl
Definition: d3d12va_encode.h:57
AVD3D12VASyncContext
This struct is used to sync d3d12 execution.
Definition: hwcontext_d3d12va.h:104
d3d12va_encode_discard
static int d3d12va_encode_discard(AVCodecContext *avctx, FFHWBaseEncodePicture *base_pic)
Definition: d3d12va_encode.c:577
AVCodecContext::rc_max_rate
int64_t rc_max_rate
maximum bitrate
Definition: avcodec.h:1270
AVD3D12VASyncContext::fence
ID3D12Fence * fence
D3D12 fence object.
Definition: hwcontext_d3d12va.h:108
D3D12VAEncodeRCMode
Definition: d3d12va_encode.h:104
FFHWBaseEncodeContext::pic_start
FFHWBaseEncodePicture * pic_start
Definition: hw_base_encode.h:160
FFHWBaseEncodeContext::b_per_p
int b_per_p
Definition: hw_base_encode.h:189
AVCodecContext::rc_buffer_size
int rc_buffer_size
decoder bitstream buffer size
Definition: avcodec.h:1255
d3d12va_discard_command_allocator
static int d3d12va_discard_command_allocator(AVCodecContext *avctx, ID3D12CommandAllocator *pAllocator, uint64_t fence_value)
Definition: d3d12va_encode.c:95
D3D12VAEncodePicture::fence_value
int fence_value
Definition: d3d12va_encode.h:59
NULL
#define NULL
Definition: coverity.c:32
AVHWFramesContext::sw_format
enum AVPixelFormat sw_format
The pixel format identifying the actual data layout of the hardware frames.
Definition: hwcontext.h:213
MAX_PARAM_BUFFER_SIZE
@ MAX_PARAM_BUFFER_SIZE
Definition: vaapi_encode.h:47
av_buffer_unref
void av_buffer_unref(AVBufferRef **buf)
Free a given reference and automatically free the buffer if there are no more references to it.
Definition: buffer.c:139
AVCodecContext::bit_rate
int64_t bit_rate
the average bitrate
Definition: avcodec.h:481
D3D12VAEncodePicture::subresource_index
int subresource_index
Definition: d3d12va_encode.h:55
av_buffer_pool_uninit
void av_buffer_pool_uninit(AVBufferPool **ppool)
Mark the pool as being available for freeing.
Definition: buffer.c:328
FFHWEncodePictureOperation
Definition: hw_base_encode.h:109
AVD3D12VAFramesContext
This struct is allocated as AVHWFramesContext.hwctx.
Definition: hwcontext_d3d12va.h:172
FF_HW_FLAG_CONSTANT_QUALITY_ONLY
@ FF_HW_FLAG_CONSTANT_QUALITY_ONLY
Definition: hw_base_encode.h:49
AV_PIX_FMT_D3D12
@ AV_PIX_FMT_D3D12
Hardware surfaces for Direct3D 12.
Definition: pixfmt.h:440
AVD3D12VAFrame::texture
ID3D12Resource * texture
The texture in which the frame is located.
Definition: hwcontext_d3d12va.h:144
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
AVCodecContext::time_base
AVRational time_base
This is the fundamental unit of time (in seconds) in terms of which frame timestamps are represented.
Definition: avcodec.h:535
ff_hw_base_encode_set_output_property
int ff_hw_base_encode_set_output_property(FFHWBaseEncodeContext *ctx, AVCodecContext *avctx, FFHWBaseEncodePicture *pic, AVPacket *pkt, int flag_no_delay)
Definition: hw_base_encode.c:519
d3d12va_encode_free_buffer
static void d3d12va_encode_free_buffer(void *opaque, uint8_t *data)
Definition: d3d12va_encode.c:1255
FFHWEncodePictureOperation::priv_size
size_t priv_size
Definition: hw_base_encode.h:111
d3d12va_encode_create_metadata_buffers
static int d3d12va_encode_create_metadata_buffers(AVCodecContext *avctx, D3D12VAEncodePicture *pic)
Definition: d3d12va_encode.c:142
FFHWBaseEncodeContext::frame
AVFrame * frame
Definition: hw_base_encode.h:211
init
int(* init)(AVBSFContext *ctx)
Definition: dts2pts.c:368
d3d12va_get_valid_command_allocator
static int d3d12va_get_valid_command_allocator(AVCodecContext *avctx, ID3D12CommandAllocator **ppAllocator)
Definition: d3d12va_encode.c:70
d3d12va_encode_create_command_objects
static int d3d12va_encode_create_command_objects(AVCodecContext *avctx)
Definition: d3d12va_encode.c:1345
ff_d3d12va_encode_init
int ff_d3d12va_encode_init(AVCodecContext *avctx)
Definition: d3d12va_encode.c:1479
FFHWBaseEncodePicture::nb_refs
int nb_refs[MAX_REFERENCE_LIST_NUM]
Definition: hw_base_encode.h:97
CommandAllocator
Definition: d3d12va_encode.c:65
d3d12va_type
static const FFHWEncodePictureOperation d3d12va_type
Definition: d3d12va_encode.c:1462
MAX_DPB_SIZE
#define MAX_DPB_SIZE
Definition: hw_base_encode.h:26
D3D12VAEncodeProfile
Definition: d3d12va_encode.h:62
FFHWBaseEncodeContext::decode_delay
int64_t decode_delay
Definition: hw_base_encode.h:173
size
int size
Definition: twinvq_data.h:10344
ff_hw_base_encode_receive_packet
int ff_hw_base_encode_receive_packet(FFHWBaseEncodeContext *ctx, AVCodecContext *avctx, AVPacket *pkt)
Definition: hw_base_encode.c:558
AVCodecHWConfigInternal
Definition: hwconfig.h:25
FFHWBaseEncodeContext::p_to_gpb
int p_to_gpb
Definition: hw_base_encode.h:194
FF_HW_FLAG_SLICE_CONTROL
@ FF_HW_FLAG_SLICE_CONTROL
Definition: hw_base_encode.h:47
FFHWBaseEncodePicture::encode_order
int64_t encode_order
Definition: hw_base_encode.h:70
AVERROR_EXTERNAL
#define AVERROR_EXTERNAL
Generic error in an external library.
Definition: error.h:59
AVD3D12VAFrame
D3D12VA frame descriptor for pool allocation.
Definition: hwcontext_d3d12va.h:138
RC_MODE_QVBR
@ RC_MODE_QVBR
Definition: d3d12va_encode.h:99
D3D12VA_VIDEO_ENC_ASYNC_DEPTH
#define D3D12VA_VIDEO_ENC_ASYNC_DEPTH
Definition: d3d12va_encode.h:40
D3D12VAEncodePicture::encoded_metadata
ID3D12Resource * encoded_metadata
Definition: d3d12va_encode.h:52
D3D12VAEncodePicture
Definition: d3d12va_encode.h:42
d3d12va_encode_alloc_output_buffer
static AVBufferRef * d3d12va_encode_alloc_output_buffer(void *opaque, size_t size)
Definition: d3d12va_encode.c:1263
HW_CONFIG_ENCODER_FRAMES
#define HW_CONFIG_ENCODER_FRAMES(format, device_type_)
Definition: hwconfig.h:98
d3d12va_encode_init
static int d3d12va_encode_init(AVCodecContext *avctx, FFHWBaseEncodePicture *pic)
Definition: d3d12va_encode.c:624
log.h
FFHWBaseEncodeContext::op
const struct FFHWEncodePictureOperation * op
Definition: hw_base_encode.h:127
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
internal.h
TRY_RC_MODE
#define TRY_RC_MODE(mode, fail)
RC_MODE_VBR
@ RC_MODE_VBR
Definition: d3d12va_encode.h:98
common.h
FFMIN
#define FFMIN(a, b)
Definition: macros.h:49
FFHWBaseEncodePicture::refs
struct FFHWBaseEncodePicture * refs[MAX_REFERENCE_LIST_NUM][MAX_PICTURE_REFERENCES]
Definition: hw_base_encode.h:98
d3d12va_fence_completion
static int d3d12va_fence_completion(AVD3D12VASyncContext *psync_ctx)
Definition: d3d12va_encode.c:41
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
profile
int profile
Definition: mxfenc.c:2278
av_calloc
void * av_calloc(size_t nmemb, size_t size)
Definition: mem.c:264
d3d12va_create_encoder
static int d3d12va_create_encoder(AVCodecContext *avctx)
Definition: d3d12va_encode.c:1203
avcodec.h
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
d3d12va_encode_init_rate_control
static int d3d12va_encode_init_rate_control(AVCodecContext *avctx)
Definition: d3d12va_encode.c:845
FFHWBaseEncodePicture
Definition: hw_base_encode.h:61
FFSWAP
#define FFSWAP(type, a, b)
Definition: macros.h:52
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
AVHWFramesContext::hwctx
void * hwctx
The format-specific data, allocated and freed automatically along with this context.
Definition: hwcontext.h:153
D3D12VAEncodeContext
Definition: d3d12va_encode.h:146
FFHWBaseEncodeContext::device_ref
AVBufferRef * device_ref
Definition: hw_base_encode.h:148
FFHWBaseEncodeContext::encode_fifo
AVFifo * encode_fifo
Definition: hw_base_encode.h:219
av_fifo_alloc2
AVFifo * av_fifo_alloc2(size_t nb_elems, size_t elem_size, unsigned int flags)
Allocate and initialize an AVFifo with a given element size.
Definition: fifo.c:47
SIZE_SPECIFIER
#define SIZE_SPECIFIER
Definition: internal.h:129
ff_hw_base_encode_get_pictype_name
static const char * ff_hw_base_encode_get_pictype_name(const int type)
Definition: hw_base_encode.h:32
d3d12va_encode_prepare_output_buffers
static int d3d12va_encode_prepare_output_buffers(AVCodecContext *avctx)
Definition: d3d12va_encode.c:1311
FFHWBaseEncodeContext::surface_height
int surface_height
Definition: hw_base_encode.h:141
FFHWBaseEncodeContext::async_depth
int async_depth
Definition: hw_base_encode.h:221
AVCodecContext
main external API structure.
Definition: avcodec.h:431
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
ff_get_encode_buffer
int ff_get_encode_buffer(AVCodecContext *avctx, AVPacket *avpkt, int64_t size, int flags)
Get a buffer for a packet.
Definition: encode.c:104
AVCodecContext::qmin
int qmin
minimum quantizer
Definition: avcodec.h:1234
AVRational::den
int den
Denominator.
Definition: rational.h:60
AVCodecContext::profile
int profile
profile
Definition: avcodec.h:1618
d3d12va_encode_free_rc_params
static int d3d12va_encode_free_rc_params(AVCodecContext *avctx)
Definition: d3d12va_encode.c:599
D3D12VAEncodePicture::aligned_header_size
int aligned_header_size
Definition: d3d12va_encode.h:44
ref
static int ref[MAX_W *MAX_W]
Definition: jpeg2000dwt.c:117
FFHWBaseEncodeContext::input_frames
AVHWFramesContext * input_frames
Definition: hw_base_encode.h:153
FFHWBaseEncodeContext::surface_width
int surface_width
Definition: hw_base_encode.h:140
AVHWFramesContext::initial_pool_size
int initial_pool_size
Initial size of the frame pool.
Definition: hwcontext.h:190
desc
const char * desc
Definition: libsvtav1.c:79
FF_HW_PICTURE_TYPE_IDR
@ FF_HW_PICTURE_TYPE_IDR
Definition: hw_base_encode.h:39
FFHWBaseEncodePicture::encode_complete
int encode_complete
Definition: hw_base_encode.h:81
mem.h
AVBufferRef
A reference to a data buffer.
Definition: buffer.h:82
AVPixFmtDescriptor
Descriptor that unambiguously describes how the bits of a pixel are stored in the up to 4 data planes...
Definition: pixdesc.h:69
ff_d3d12va_encode_close
int ff_d3d12va_encode_close(AVCodecContext *avctx)
Definition: d3d12va_encode.c:1608
FFALIGN
#define FFALIGN(x, a)
Definition: macros.h:78
AVCodecContext::slices
int slices
Number of slices.
Definition: avcodec.h:1021
ff_d3d12va_encode_receive_packet
int ff_d3d12va_encode_receive_packet(AVCodecContext *avctx, AVPacket *pkt)
Definition: d3d12va_encode.c:1474
AVPacket
This structure stores compressed data.
Definition: packet.h:535
AVCodecContext::priv_data
void * priv_data
Definition: avcodec.h:458
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:35
d3d12va_encode_init_gop_structure
static int d3d12va_encode_init_gop_structure(AVCodecContext *avctx)
Definition: d3d12va_encode.c:1130
FFHWBaseEncodeContext::recon_frames
AVHWFramesContext * recon_frames
Definition: hw_base_encode.h:157
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
av_fifo_freep2
void av_fifo_freep2(AVFifo **f)
Free an AVFifo and reset pointer to NULL.
Definition: fifo.c:286
AVD3D12VASyncContext::fence_value
uint64_t fence_value
The fence value used for sync.
Definition: hwcontext_d3d12va.h:119
FFHWBaseEncodePicture::encode_issued
int encode_issued
Definition: hw_base_encode.h:80
width
#define width
Definition: dsp.h:89
FF_QP2LAMBDA
#define FF_QP2LAMBDA
factor to convert from H.263 QP to lambda
Definition: avutil.h:226
rc_mode
mfxU16 rc_mode
Definition: qsvenc.c:143
hwcontext_d3d12va_internal.h
FFHWBaseEncodePicture::display_order
int64_t display_order
Definition: hw_base_encode.h:69
AV_FIFO_FLAG_AUTO_GROW
#define AV_FIFO_FLAG_AUTO_GROW
Automatically resize the FIFO on writes, so that the data fits.
Definition: fifo.h:63
AVD3D12VAFrame::subresource_index
int subresource_index
Index of the subresource within the texture.
Definition: hwcontext_d3d12va.h:152
RC_MODE_CQP
@ RC_MODE_CQP
Definition: d3d12va_encode.h:96
TRANSITION_BARRIER
#define TRANSITION_BARRIER(res, subres, before, after)
RC_MODE_CBR
@ RC_MODE_CBR
Definition: d3d12va_encode.h:97