FFmpeg
hwcontext_cuda.c
Go to the documentation of this file.
1 /*
2  * This file is part of FFmpeg.
3  *
4  * FFmpeg is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * FFmpeg is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with FFmpeg; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17  */
18 
19 #include "buffer.h"
20 #include "common.h"
21 #include "hwcontext.h"
22 #include "hwcontext_internal.h"
24 #if CONFIG_VULKAN
25 #include "hwcontext_vulkan.h"
26 #endif
27 #include "cuda_check.h"
28 #include "mem.h"
29 #include "pixdesc.h"
30 #include "pixfmt.h"
31 #include "imgutils.h"
32 
33 typedef struct CUDAFramesContext {
37 
38 typedef struct CUDADeviceContext {
42 
43 static const enum AVPixelFormat supported_formats[] = {
55 #if CONFIG_VULKAN
57 #endif
58 };
59 
60 #define CHECK_CU(x) FF_CUDA_CHECK_DL(device_ctx, cu, x)
61 
63  const void *hwconfig,
64  AVHWFramesConstraints *constraints)
65 {
66  int i;
67 
69  sizeof(*constraints->valid_sw_formats));
70  if (!constraints->valid_sw_formats)
71  return AVERROR(ENOMEM);
72 
73  for (i = 0; i < FF_ARRAY_ELEMS(supported_formats); i++)
74  constraints->valid_sw_formats[i] = supported_formats[i];
76 
77  constraints->valid_hw_formats = av_malloc_array(2, sizeof(*constraints->valid_hw_formats));
78  if (!constraints->valid_hw_formats)
79  return AVERROR(ENOMEM);
80 
81  constraints->valid_hw_formats[0] = AV_PIX_FMT_CUDA;
82  constraints->valid_hw_formats[1] = AV_PIX_FMT_NONE;
83 
84  return 0;
85 }
86 
87 static void cuda_buffer_free(void *opaque, uint8_t *data)
88 {
89  AVHWFramesContext *ctx = opaque;
90  AVHWDeviceContext *device_ctx = ctx->device_ctx;
91  AVCUDADeviceContext *hwctx = device_ctx->hwctx;
92  CudaFunctions *cu = hwctx->internal->cuda_dl;
93 
94  CUcontext dummy;
95 
96  CHECK_CU(cu->cuCtxPushCurrent(hwctx->cuda_ctx));
97 
98  CHECK_CU(cu->cuMemFree((CUdeviceptr)data));
99 
100  CHECK_CU(cu->cuCtxPopCurrent(&dummy));
101 }
102 
103 static AVBufferRef *cuda_pool_alloc(void *opaque, size_t size)
104 {
105  AVHWFramesContext *ctx = opaque;
106  AVHWDeviceContext *device_ctx = ctx->device_ctx;
107  AVCUDADeviceContext *hwctx = device_ctx->hwctx;
108  CudaFunctions *cu = hwctx->internal->cuda_dl;
109 
110  AVBufferRef *ret = NULL;
111  CUcontext dummy = NULL;
112  CUdeviceptr data;
113  int err;
114 
115  err = CHECK_CU(cu->cuCtxPushCurrent(hwctx->cuda_ctx));
116  if (err < 0)
117  return NULL;
118 
119  err = CHECK_CU(cu->cuMemAlloc(&data, size));
120  if (err < 0)
121  goto fail;
122 
123  ret = av_buffer_create((uint8_t*)data, size, cuda_buffer_free, ctx, 0);
124  if (!ret) {
125  CHECK_CU(cu->cuMemFree(data));
126  goto fail;
127  }
128 
129 fail:
130  CHECK_CU(cu->cuCtxPopCurrent(&dummy));
131  return ret;
132 }
133 
135 {
136  AVHWDeviceContext *device_ctx = ctx->device_ctx;
137  AVCUDADeviceContext *hwctx = device_ctx->hwctx;
138  CUDAFramesContext *priv = ctx->hwctx;
139  CudaFunctions *cu = hwctx->internal->cuda_dl;
140  int err, i;
141 
142  for (i = 0; i < FF_ARRAY_ELEMS(supported_formats); i++) {
143  if (ctx->sw_format == supported_formats[i])
144  break;
145  }
147  av_log(ctx, AV_LOG_ERROR, "Pixel format '%s' is not supported\n",
148  av_get_pix_fmt_name(ctx->sw_format));
149  return AVERROR(ENOSYS);
150  }
151 
152  err = CHECK_CU(cu->cuDeviceGetAttribute(&priv->tex_alignment,
153  14 /* CU_DEVICE_ATTRIBUTE_TEXTURE_ALIGNMENT */,
154  hwctx->internal->cuda_device));
155  if (err < 0)
156  return err;
157 
158  av_log(ctx, AV_LOG_DEBUG, "CUDA texture alignment: %d\n", priv->tex_alignment);
159 
160  // YUV420P is a special case.
161  // Since nvenc expects the U/V planes to have half the linesize of the Y plane
162  // alignment has to be doubled to ensure the U/V planes still end up aligned.
163  if (ctx->sw_format == AV_PIX_FMT_YUV420P)
164  priv->tex_alignment *= 2;
165 
166  av_pix_fmt_get_chroma_sub_sample(ctx->sw_format, &priv->shift_width, &priv->shift_height);
167 
168  if (!ctx->pool) {
169  int size = av_image_get_buffer_size(ctx->sw_format, ctx->width, ctx->height, priv->tex_alignment);
170  if (size < 0)
171  return size;
172 
175  if (!ffhwframesctx(ctx)->pool_internal)
176  return AVERROR(ENOMEM);
177  }
178 
179  return 0;
180 }
181 
183 {
184  CUDAFramesContext *priv = ctx->hwctx;
185  int res;
186 
187  frame->buf[0] = av_buffer_pool_get(ctx->pool);
188  if (!frame->buf[0])
189  return AVERROR(ENOMEM);
190 
191  res = av_image_fill_arrays(frame->data, frame->linesize, frame->buf[0]->data,
192  ctx->sw_format, ctx->width, ctx->height, priv->tex_alignment);
193  if (res < 0)
194  return res;
195 
196  // YUV420P is a special case.
197  // Nvenc expects the U/V planes in swapped order from how ffmpeg expects them, also chroma is half-aligned
198  if (ctx->sw_format == AV_PIX_FMT_YUV420P) {
199  frame->linesize[1] = frame->linesize[2] = frame->linesize[0] / 2;
200  frame->data[2] = frame->data[1];
201  frame->data[1] = frame->data[2] + frame->linesize[2] * (ctx->height / 2);
202  }
203 
204  frame->format = AV_PIX_FMT_CUDA;
205  frame->width = ctx->width;
206  frame->height = ctx->height;
207 
208  return 0;
209 }
210 
213  enum AVPixelFormat **formats)
214 {
215  enum AVPixelFormat *fmts;
216 
217  fmts = av_malloc_array(2, sizeof(*fmts));
218  if (!fmts)
219  return AVERROR(ENOMEM);
220 
221  fmts[0] = ctx->sw_format;
222  fmts[1] = AV_PIX_FMT_NONE;
223 
224  *formats = fmts;
225 
226  return 0;
227 }
228 
230  const AVFrame *src)
231 {
232  CUDAFramesContext *priv = ctx->hwctx;
233  AVHWDeviceContext *device_ctx = ctx->device_ctx;
234  AVCUDADeviceContext *hwctx = device_ctx->hwctx;
235  CudaFunctions *cu = hwctx->internal->cuda_dl;
236 
237  CUcontext dummy;
238  int i, ret;
239 
240  if ((src->hw_frames_ctx && ((AVHWFramesContext*)src->hw_frames_ctx->data)->format != AV_PIX_FMT_CUDA) ||
241  (dst->hw_frames_ctx && ((AVHWFramesContext*)dst->hw_frames_ctx->data)->format != AV_PIX_FMT_CUDA))
242  return AVERROR(ENOSYS);
243 
244  ret = CHECK_CU(cu->cuCtxPushCurrent(hwctx->cuda_ctx));
245  if (ret < 0)
246  return ret;
247 
248  for (i = 0; i < FF_ARRAY_ELEMS(src->data) && src->data[i]; i++) {
249  CUDA_MEMCPY2D cpy = {
250  .srcPitch = src->linesize[i],
251  .dstPitch = dst->linesize[i],
252  .WidthInBytes = FFMIN(src->linesize[i], dst->linesize[i]),
253  .Height = src->height >> ((i == 0 || i == 3) ? 0 : priv->shift_height),
254  };
255 
256  if (src->hw_frames_ctx) {
257  cpy.srcMemoryType = CU_MEMORYTYPE_DEVICE;
258  cpy.srcDevice = (CUdeviceptr)src->data[i];
259  } else {
260  cpy.srcMemoryType = CU_MEMORYTYPE_HOST;
261  cpy.srcHost = src->data[i];
262  }
263 
264  if (dst->hw_frames_ctx) {
265  cpy.dstMemoryType = CU_MEMORYTYPE_DEVICE;
266  cpy.dstDevice = (CUdeviceptr)dst->data[i];
267  } else {
268  cpy.dstMemoryType = CU_MEMORYTYPE_HOST;
269  cpy.dstHost = dst->data[i];
270  }
271 
272  ret = CHECK_CU(cu->cuMemcpy2DAsync(&cpy, hwctx->stream));
273  if (ret < 0)
274  goto exit;
275  }
276 
277  if (!dst->hw_frames_ctx) {
278  ret = CHECK_CU(cu->cuStreamSynchronize(hwctx->stream));
279  if (ret < 0)
280  goto exit;
281  }
282 
283 exit:
284  CHECK_CU(cu->cuCtxPopCurrent(&dummy));
285 
286  return 0;
287 }
288 
289 static void cuda_device_uninit(AVHWDeviceContext *device_ctx)
290 {
291  CUDADeviceContext *hwctx = device_ctx->hwctx;
292 
293  if (hwctx->p.internal) {
294  CudaFunctions *cu = hwctx->internal.cuda_dl;
295 
296  if (hwctx->internal.is_allocated && hwctx->p.cuda_ctx) {
298  CHECK_CU(cu->cuDevicePrimaryCtxRelease(hwctx->internal.cuda_device));
299  else if (!(hwctx->internal.flags & AV_CUDA_USE_CURRENT_CONTEXT))
300  CHECK_CU(cu->cuCtxDestroy(hwctx->p.cuda_ctx));
301 
302  hwctx->p.cuda_ctx = NULL;
303  }
304 
305  cuda_free_functions(&hwctx->internal.cuda_dl);
306  memset(&hwctx->internal, 0, sizeof(hwctx->internal));
307  hwctx->p.internal = NULL;
308  }
309 }
310 
312 {
313  CUDADeviceContext *hwctx = ctx->hwctx;
314  int ret;
315 
316  hwctx->p.internal = &hwctx->internal;
317 
318  if (!hwctx->internal.cuda_dl) {
319  ret = cuda_load_functions(&hwctx->internal.cuda_dl, ctx);
320  if (ret < 0) {
321  av_log(ctx, AV_LOG_ERROR, "Could not dynamically load CUDA\n");
322  goto error;
323  }
324  }
325 
326  return 0;
327 
328 error:
330  return ret;
331 }
332 
333 static int cuda_context_init(AVHWDeviceContext *device_ctx, int flags) {
334  AVCUDADeviceContext *hwctx = device_ctx->hwctx;
335  CudaFunctions *cu;
336  CUcontext dummy;
337  int ret, dev_active = 0;
338  unsigned int dev_flags = 0;
339 
340  const unsigned int desired_flags = CU_CTX_SCHED_BLOCKING_SYNC;
341 
342  cu = hwctx->internal->cuda_dl;
343 
344  hwctx->internal->flags = flags;
345 
347  ret = CHECK_CU(cu->cuDevicePrimaryCtxGetState(hwctx->internal->cuda_device,
348  &dev_flags, &dev_active));
349  if (ret < 0)
350  return ret;
351 
352  if (dev_active && dev_flags != desired_flags) {
353  av_log(device_ctx, AV_LOG_ERROR, "Primary context already active with incompatible flags.\n");
354  return AVERROR(ENOTSUP);
355  } else if (dev_flags != desired_flags) {
356  ret = CHECK_CU(cu->cuDevicePrimaryCtxSetFlags(hwctx->internal->cuda_device,
357  desired_flags));
358  if (ret < 0)
359  return ret;
360  }
361 
362  ret = CHECK_CU(cu->cuDevicePrimaryCtxRetain(&hwctx->cuda_ctx,
363  hwctx->internal->cuda_device));
364  if (ret < 0)
365  return ret;
366  } else if (flags & AV_CUDA_USE_CURRENT_CONTEXT) {
367  ret = CHECK_CU(cu->cuCtxGetCurrent(&hwctx->cuda_ctx));
368  if (ret < 0)
369  return ret;
370  av_log(device_ctx, AV_LOG_INFO, "Using current CUDA context.\n");
371  } else {
372  ret = CHECK_CU(cu->cuCtxCreate(&hwctx->cuda_ctx, desired_flags,
373  hwctx->internal->cuda_device));
374  if (ret < 0)
375  return ret;
376 
377  CHECK_CU(cu->cuCtxPopCurrent(&dummy));
378  }
379 
380  hwctx->internal->is_allocated = 1;
381 
382  // Setting stream to NULL will make functions automatically use the default CUstream
383  hwctx->stream = NULL;
384 
385  return 0;
386 }
387 
389  AVDictionary *opts, int *flags)
390 {
391  AVDictionaryEntry *primary_ctx_opt = av_dict_get(opts, "primary_ctx", NULL, 0);
392  AVDictionaryEntry *current_ctx_opt = av_dict_get(opts, "current_ctx", NULL, 0);
393 
394  int use_primary_ctx = 0, use_current_ctx = 0;
395  if (primary_ctx_opt)
396  use_primary_ctx = strtol(primary_ctx_opt->value, NULL, 10);
397 
398  if (current_ctx_opt)
399  use_current_ctx = strtol(current_ctx_opt->value, NULL, 10);
400 
401  if (use_primary_ctx && use_current_ctx) {
402  av_log(device_ctx, AV_LOG_ERROR, "Requested both primary and current CUDA context simultaneously.\n");
403  return AVERROR(EINVAL);
404  }
405 
406  if (primary_ctx_opt && use_primary_ctx) {
407  av_log(device_ctx, AV_LOG_VERBOSE, "Using CUDA primary device context\n");
409  } else if (primary_ctx_opt) {
410  av_log(device_ctx, AV_LOG_VERBOSE, "Disabling use of CUDA primary device context\n");
412  }
413 
414  if (current_ctx_opt && use_current_ctx) {
415  av_log(device_ctx, AV_LOG_VERBOSE, "Using CUDA current device context\n");
417  } else if (current_ctx_opt) {
418  av_log(device_ctx, AV_LOG_VERBOSE, "Disabling use of CUDA current device context\n");
420  }
421 
422  return 0;
423 }
424 
425 static int cuda_device_create(AVHWDeviceContext *device_ctx,
426  const char *device,
427  AVDictionary *opts, int flags)
428 {
429  AVCUDADeviceContext *hwctx = device_ctx->hwctx;
430  CudaFunctions *cu;
431  int ret, device_idx = 0;
432 
433  ret = cuda_flags_from_opts(device_ctx, opts, &flags);
434  if (ret < 0)
435  goto error;
436 
437  if (device)
438  device_idx = strtol(device, NULL, 0);
439 
440  ret = cuda_device_init(device_ctx);
441  if (ret < 0)
442  goto error;
443 
444  cu = hwctx->internal->cuda_dl;
445 
446  ret = CHECK_CU(cu->cuInit(0));
447  if (ret < 0)
448  goto error;
449 
450  ret = CHECK_CU(cu->cuDeviceGet(&hwctx->internal->cuda_device, device_idx));
451  if (ret < 0)
452  goto error;
453 
454  ret = cuda_context_init(device_ctx, flags);
455  if (ret < 0)
456  goto error;
457 
458  return 0;
459 
460 error:
461  cuda_device_uninit(device_ctx);
462  return ret;
463 }
464 
465 static int cuda_device_derive(AVHWDeviceContext *device_ctx,
467  int flags) {
468  AVCUDADeviceContext *hwctx = device_ctx->hwctx;
469  CudaFunctions *cu;
470  const char *src_uuid = NULL;
471 #if CONFIG_VULKAN
472  VkPhysicalDeviceIDProperties vk_idp;
473 #endif
474  int ret, i, device_count;
475 
476  ret = cuda_flags_from_opts(device_ctx, opts, &flags);
477  if (ret < 0)
478  goto error;
479 
480 #if CONFIG_VULKAN
481  vk_idp = (VkPhysicalDeviceIDProperties) {
482  .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ID_PROPERTIES,
483  };
484 #endif
485 
486  switch (src_ctx->type) {
487 #if CONFIG_VULKAN
488 #define TYPE PFN_vkGetPhysicalDeviceProperties2
490  AVVulkanDeviceContext *vkctx = src_ctx->hwctx;
491  TYPE prop_fn = (TYPE)vkctx->get_proc_addr(vkctx->inst, "vkGetPhysicalDeviceProperties2");
492  VkPhysicalDeviceProperties2 vk_dev_props = {
493  .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2,
494  .pNext = &vk_idp,
495  };
496  prop_fn(vkctx->phys_dev, &vk_dev_props);
497  src_uuid = vk_idp.deviceUUID;
498  break;
499  }
500 #undef TYPE
501 #endif
502  default:
503  ret = AVERROR(ENOSYS);
504  goto error;
505  }
506 
507  if (!src_uuid) {
508  av_log(device_ctx, AV_LOG_ERROR,
509  "Failed to get UUID of source device.\n");
510  ret = AVERROR(EINVAL);
511  goto error;
512  }
513 
514  ret = cuda_device_init(device_ctx);
515  if (ret < 0)
516  goto error;
517 
518  cu = hwctx->internal->cuda_dl;
519 
520  ret = CHECK_CU(cu->cuInit(0));
521  if (ret < 0)
522  goto error;
523 
524  ret = CHECK_CU(cu->cuDeviceGetCount(&device_count));
525  if (ret < 0)
526  goto error;
527 
528  hwctx->internal->cuda_device = -1;
529  for (i = 0; i < device_count; i++) {
530  CUdevice dev;
531  CUuuid uuid;
532 
533  ret = CHECK_CU(cu->cuDeviceGet(&dev, i));
534  if (ret < 0)
535  goto error;
536 
537  ret = CHECK_CU(cu->cuDeviceGetUuid(&uuid, dev));
538  if (ret < 0)
539  goto error;
540 
541  if (memcmp(src_uuid, uuid.bytes, sizeof (uuid.bytes)) == 0) {
542  hwctx->internal->cuda_device = dev;
543  break;
544  }
545  }
546 
547  if (hwctx->internal->cuda_device == -1) {
548  av_log(device_ctx, AV_LOG_ERROR, "Could not derive CUDA device.\n");
549  goto error;
550  }
551 
552  ret = cuda_context_init(device_ctx, flags);
553  if (ret < 0)
554  goto error;
555 
556  return 0;
557 
558 error:
559  cuda_device_uninit(device_ctx);
560  return ret;
561 }
562 
565  .name = "CUDA",
566 
567  .device_hwctx_size = sizeof(CUDADeviceContext),
568  .frames_hwctx_size = sizeof(CUDAFramesContext),
569 
570  .device_create = cuda_device_create,
571  .device_derive = cuda_device_derive,
572  .device_init = cuda_device_init,
573  .device_uninit = cuda_device_uninit,
574  .frames_get_constraints = cuda_frames_get_constraints,
575  .frames_init = cuda_frames_init,
576  .frames_get_buffer = cuda_get_buffer,
577  .transfer_get_formats = cuda_transfer_get_formats,
578  .transfer_data_to = cuda_transfer_data,
579  .transfer_data_from = cuda_transfer_data,
580 
581  .pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_CUDA, AV_PIX_FMT_NONE },
582 };
error
static void error(const char *err)
Definition: target_bsf_fuzzer.c:32
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:85
FFHWFramesContext::pool_internal
AVBufferPool * pool_internal
Definition: hwcontext_internal.h:101
AVVulkanDeviceContext::phys_dev
VkPhysicalDevice phys_dev
Physical device.
Definition: hwcontext_vulkan.h:79
AV_PIX_FMT_CUDA
@ AV_PIX_FMT_CUDA
HW acceleration through CUDA.
Definition: pixfmt.h:260
AVPixelFormat
AVPixelFormat
Pixel format.
Definition: pixfmt.h:71
AVCUDADeviceContextInternal
Definition: hwcontext_cuda_internal.h:31
cuda_context_init
static int cuda_context_init(AVHWDeviceContext *device_ctx, int flags)
Definition: hwcontext_cuda.c:333
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
cuda_device_derive
static int cuda_device_derive(AVHWDeviceContext *device_ctx, AVHWDeviceContext *src_ctx, AVDictionary *opts, int flags)
Definition: hwcontext_cuda.c:465
hwcontext_cuda_internal.h
cuda_transfer_get_formats
static int cuda_transfer_get_formats(AVHWFramesContext *ctx, enum AVHWFrameTransferDirection dir, enum AVPixelFormat **formats)
Definition: hwcontext_cuda.c:211
AV_PIX_FMT_BGR32
#define AV_PIX_FMT_BGR32
Definition: pixfmt.h:453
cuda_flags_from_opts
static int cuda_flags_from_opts(AVHWDeviceContext *device_ctx, AVDictionary *opts, int *flags)
Definition: hwcontext_cuda.c:388
CUDAFramesContext
Definition: hwcontext_cuda.c:33
CHECK_CU
#define CHECK_CU(x)
Definition: hwcontext_cuda.c:60
AVCUDADeviceContextInternal::is_allocated
int is_allocated
Definition: hwcontext_cuda_internal.h:33
AVFrame
This structure describes decoded (raw) audio or video data.
Definition: frame.h:389
pixdesc.h
CUDADeviceContext::internal
AVCUDADeviceContextInternal internal
Definition: hwcontext_cuda.c:40
AVVulkanDeviceContext::get_proc_addr
PFN_vkGetInstanceProcAddr get_proc_addr
Pointer to a vkGetInstanceProcAddr loading function.
Definition: hwcontext_vulkan.h:69
data
const char data[16]
Definition: mxf.c:148
AVVulkanDeviceContext::inst
VkInstance inst
Vulkan instance.
Definition: hwcontext_vulkan.h:74
AV_LOG_VERBOSE
#define AV_LOG_VERBOSE
Detailed information.
Definition: log.h:225
AVDictionary
Definition: dict.c:34
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:446
AV_PIX_FMT_VULKAN
@ AV_PIX_FMT_VULKAN
Vulkan hardware images.
Definition: pixfmt.h:379
AV_HWDEVICE_TYPE_VULKAN
@ AV_HWDEVICE_TYPE_VULKAN
Definition: hwcontext.h:39
AVHWFramesConstraints
This struct describes the constraints on hardware frames attached to a given device with a hardware-s...
Definition: hwcontext.h:441
CUDADeviceContext::p
AVCUDADeviceContext p
Definition: hwcontext_cuda.c:39
AV_HWDEVICE_TYPE_CUDA
@ AV_HWDEVICE_TYPE_CUDA
Definition: hwcontext.h:30
fail
#define fail()
Definition: checkasm.h:188
dummy
int dummy
Definition: motion.c:66
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
AVCUDADeviceContextInternal::cuda_device
CUdevice cuda_device
Definition: hwcontext_cuda_internal.h:34
av_pix_fmt_get_chroma_sub_sample
int av_pix_fmt_get_chroma_sub_sample(enum AVPixelFormat pix_fmt, int *h_shift, int *v_shift)
Utility function to access log2_chroma_w log2_chroma_h from the pixel format AVPixFmtDescriptor.
Definition: pixdesc.c:2993
AVCUDADeviceContext::cuda_ctx
CUcontext cuda_ctx
Definition: hwcontext_cuda.h:43
AVHWDeviceContext
This struct aggregates all the (hardware/vendor-specific) "high-level" state, i.e.
Definition: hwcontext.h:60
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:209
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:453
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:62
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
AV_PIX_FMT_YUVA420P
@ AV_PIX_FMT_YUVA420P
planar YUV 4:2:0, 20bpp, (1 Cr & Cb sample per 2x2 Y & A samples)
Definition: pixfmt.h:108
AV_PIX_FMT_YUV444P16
#define AV_PIX_FMT_YUV444P16
Definition: pixfmt.h:491
AV_PIX_FMT_0BGR32
#define AV_PIX_FMT_0BGR32
Definition: pixfmt.h:456
AV_LOG_DEBUG
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:230
ctx
AVFormatContext * ctx
Definition: movenc.c:49
cuda_device_init
static int cuda_device_init(AVHWDeviceContext *ctx)
Definition: hwcontext_cuda.c:311
AV_PIX_FMT_YUV420P
@ AV_PIX_FMT_YUV420P
planar YUV 4:2:0, 12bpp, (1 Cr & Cb sample per 2x2 Y samples)
Definition: pixfmt.h:73
AVVulkanDeviceContext
Main Vulkan context, allocated as AVHWDeviceContext.hwctx.
Definition: hwcontext_vulkan.h:59
opts
AVDictionary * opts
Definition: movenc.c:51
TYPE
#define TYPE
Definition: ffv1dec.c:116
AV_CUDA_USE_CURRENT_CONTEXT
#define AV_CUDA_USE_CURRENT_CONTEXT
Use current device context instead of creating a new one.
Definition: hwcontext_cuda.h:68
NULL
#define NULL
Definition: coverity.c:32
AVCUDADeviceContextInternal::flags
int flags
Definition: hwcontext_cuda_internal.h:35
hwcontext_vulkan.h
CUDAFramesContext::shift_width
int shift_width
Definition: hwcontext_cuda.c:34
cuda_transfer_data
static int cuda_transfer_data(AVHWFramesContext *ctx, AVFrame *dst, const AVFrame *src)
Definition: hwcontext_cuda.c:229
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
AVCUDADeviceContext::stream
CUstream stream
Definition: hwcontext_cuda.h:44
AVCUDADeviceContext::internal
AVCUDADeviceContextInternal * internal
Definition: hwcontext_cuda.h:45
CUDAFramesContext::tex_alignment
int tex_alignment
Definition: hwcontext_cuda.c:35
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:83
CUDAFramesContext::shift_height
int shift_height
Definition: hwcontext_cuda.c:34
size
int size
Definition: twinvq_data.h:10344
ff_hwcontext_type_cuda
const HWContextType ff_hwcontext_type_cuda
Definition: hwcontext_cuda.c:563
buffer.h
AV_PIX_FMT_RGB32
#define AV_PIX_FMT_RGB32
Definition: pixfmt.h:451
av_image_get_buffer_size
int av_image_get_buffer_size(enum AVPixelFormat pix_fmt, int width, int height, int align)
Return the size in bytes of the amount of data required to store an image with the given parameters.
Definition: imgutils.c:466
AV_LOG_INFO
#define AV_LOG_INFO
Standard information.
Definition: log.h:220
AVCUDADeviceContextInternal::cuda_dl
CudaFunctions * cuda_dl
Definition: hwcontext_cuda_internal.h:32
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:256
av_malloc_array
#define av_malloc_array(a, b)
Definition: tableprint_vlc.h:31
common.h
FFMIN
#define FFMIN(a, b)
Definition: macros.h:49
cuda_device_uninit
static void cuda_device_uninit(AVHWDeviceContext *device_ctx)
Definition: hwcontext_cuda.c:289
AV_PIX_FMT_P016
#define AV_PIX_FMT_P016
Definition: pixfmt.h:530
AVHWFrameTransferDirection
AVHWFrameTransferDirection
Definition: hwcontext.h:403
AVHWFramesContext
This struct describes a set or pool of "hardware" frames (i.e.
Definition: hwcontext.h:115
AVCUDADeviceContext
This struct is allocated as AVHWDeviceContext.hwctx.
Definition: hwcontext_cuda.h:42
ret
ret
Definition: filter_design.txt:187
AVHWDeviceContext::type
enum AVHWDeviceType type
This field identifies the underlying API used for hardware access.
Definition: hwcontext.h:72
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:264
AV_PIX_FMT_0RGB32
#define AV_PIX_FMT_0RGB32
Definition: pixfmt.h:455
cuda_check.h
cuda_buffer_free
static void cuda_buffer_free(void *opaque, uint8_t *data)
Definition: hwcontext_cuda.c:87
AV_CUDA_USE_PRIMARY_CONTEXT
#define AV_CUDA_USE_PRIMARY_CONTEXT
Use primary device context instead of creating a new one.
Definition: hwcontext_cuda.h:63
AV_PIX_FMT_NONE
@ AV_PIX_FMT_NONE
Definition: pixfmt.h:72
cuda_device_create
static int cuda_device_create(AVHWDeviceContext *device_ctx, const char *device, AVDictionary *opts, int flags)
Definition: hwcontext_cuda.c:425
supported_formats
static enum AVPixelFormat supported_formats[]
Definition: hwcontext_cuda.c:43
AV_PIX_FMT_YUV444P
@ AV_PIX_FMT_YUV444P
planar YUV 4:4:4, 24bpp, (1 Cr & Cb sample per 1x1 Y samples)
Definition: pixfmt.h:78
cuda_get_buffer
static int cuda_get_buffer(AVHWFramesContext *ctx, AVFrame *frame)
Definition: hwcontext_cuda.c:182
AV_PIX_FMT_P010
#define AV_PIX_FMT_P010
Definition: pixfmt.h:528
mem.h
AVBufferRef
A reference to a data buffer.
Definition: buffer.h:82
cuda_pool_alloc
static AVBufferRef * cuda_pool_alloc(void *opaque, size_t size)
Definition: hwcontext_cuda.c:103
hwcontext_internal.h
AVDictionaryEntry
Definition: dict.h:89
imgutils.h
flags
#define flags(name, subs,...)
Definition: cbs_av1.c:482
hwcontext.h
CUDADeviceContext
Definition: hwcontext_cuda.c:38
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:27
HWContextType
Definition: hwcontext_internal.h:29
cuda_frames_get_constraints
static int cuda_frames_get_constraints(AVHWDeviceContext *ctx, const void *hwconfig, AVHWFramesConstraints *constraints)
Definition: hwcontext_cuda.c:62
cuda_frames_init
static int cuda_frames_init(AVHWFramesContext *ctx)
Definition: hwcontext_cuda.c:134
AVDictionaryEntry::value
char * value
Definition: dict.h:91
src
#define src
Definition: vp8dsp.c:248
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:2885