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[] = {
57 #if CONFIG_VULKAN
59 #endif
60 };
61 
62 #define CHECK_CU(x) FF_CUDA_CHECK_DL(device_ctx, cu, x)
63 
65  const void *hwconfig,
66  AVHWFramesConstraints *constraints)
67 {
68  int i;
69 
71  sizeof(*constraints->valid_sw_formats));
72  if (!constraints->valid_sw_formats)
73  return AVERROR(ENOMEM);
74 
75  for (i = 0; i < FF_ARRAY_ELEMS(supported_formats); i++)
76  constraints->valid_sw_formats[i] = supported_formats[i];
78 
79  constraints->valid_hw_formats = av_malloc_array(2, sizeof(*constraints->valid_hw_formats));
80  if (!constraints->valid_hw_formats)
81  return AVERROR(ENOMEM);
82 
83  constraints->valid_hw_formats[0] = AV_PIX_FMT_CUDA;
84  constraints->valid_hw_formats[1] = AV_PIX_FMT_NONE;
85 
86  return 0;
87 }
88 
89 static void cuda_buffer_free(void *opaque, uint8_t *data)
90 {
91  AVHWFramesContext *ctx = opaque;
92  AVHWDeviceContext *device_ctx = ctx->device_ctx;
93  AVCUDADeviceContext *hwctx = device_ctx->hwctx;
94  CudaFunctions *cu = hwctx->internal->cuda_dl;
95 
96  CUcontext dummy;
97 
98  CHECK_CU(cu->cuCtxPushCurrent(hwctx->cuda_ctx));
99 
100  CHECK_CU(cu->cuMemFree((CUdeviceptr)data));
101 
102  CHECK_CU(cu->cuCtxPopCurrent(&dummy));
103 }
104 
105 static AVBufferRef *cuda_pool_alloc(void *opaque, size_t size)
106 {
107  AVHWFramesContext *ctx = opaque;
108  AVHWDeviceContext *device_ctx = ctx->device_ctx;
109  AVCUDADeviceContext *hwctx = device_ctx->hwctx;
110  CudaFunctions *cu = hwctx->internal->cuda_dl;
111 
112  AVBufferRef *ret = NULL;
113  CUcontext dummy = NULL;
114  CUdeviceptr data;
115  int err;
116 
117  err = CHECK_CU(cu->cuCtxPushCurrent(hwctx->cuda_ctx));
118  if (err < 0)
119  return NULL;
120 
121  err = CHECK_CU(cu->cuMemAlloc(&data, size));
122  if (err < 0)
123  goto fail;
124 
125  ret = av_buffer_create((uint8_t*)data, size, cuda_buffer_free, ctx, 0);
126  if (!ret) {
127  CHECK_CU(cu->cuMemFree(data));
128  goto fail;
129  }
130 
131 fail:
132  CHECK_CU(cu->cuCtxPopCurrent(&dummy));
133  return ret;
134 }
135 
137 {
138  AVHWDeviceContext *device_ctx = ctx->device_ctx;
139  AVCUDADeviceContext *hwctx = device_ctx->hwctx;
140  CUDAFramesContext *priv = ctx->hwctx;
141  CudaFunctions *cu = hwctx->internal->cuda_dl;
142  int err, i;
143 
144  for (i = 0; i < FF_ARRAY_ELEMS(supported_formats); i++) {
145  if (ctx->sw_format == supported_formats[i])
146  break;
147  }
149  av_log(ctx, AV_LOG_ERROR, "Pixel format '%s' is not supported\n",
150  av_get_pix_fmt_name(ctx->sw_format));
151  return AVERROR(ENOSYS);
152  }
153 
154  err = CHECK_CU(cu->cuDeviceGetAttribute(&priv->tex_alignment,
155  14 /* CU_DEVICE_ATTRIBUTE_TEXTURE_ALIGNMENT */,
156  hwctx->internal->cuda_device));
157  if (err < 0)
158  return err;
159 
160  av_log(ctx, AV_LOG_DEBUG, "CUDA texture alignment: %d\n", priv->tex_alignment);
161 
162  // YUV420P is a special case.
163  // Since nvenc expects the U/V planes to have half the linesize of the Y plane
164  // alignment has to be doubled to ensure the U/V planes still end up aligned.
165  if (ctx->sw_format == AV_PIX_FMT_YUV420P)
166  priv->tex_alignment *= 2;
167 
168  av_pix_fmt_get_chroma_sub_sample(ctx->sw_format, &priv->shift_width, &priv->shift_height);
169 
170  if (!ctx->pool) {
171  int size = av_image_get_buffer_size(ctx->sw_format, ctx->width, ctx->height, priv->tex_alignment);
172  if (size < 0)
173  return size;
174 
177  if (!ffhwframesctx(ctx)->pool_internal)
178  return AVERROR(ENOMEM);
179  }
180 
181  return 0;
182 }
183 
185 {
186  CUDAFramesContext *priv = ctx->hwctx;
187  int res;
188 
189  frame->buf[0] = av_buffer_pool_get(ctx->pool);
190  if (!frame->buf[0])
191  return AVERROR(ENOMEM);
192 
193  res = av_image_fill_arrays(frame->data, frame->linesize, frame->buf[0]->data,
194  ctx->sw_format, ctx->width, ctx->height, priv->tex_alignment);
195  if (res < 0)
196  return res;
197 
198  // YUV420P is a special case.
199  // Nvenc expects the U/V planes in swapped order from how ffmpeg expects them, also chroma is half-aligned
200  if (ctx->sw_format == AV_PIX_FMT_YUV420P) {
201  frame->linesize[1] = frame->linesize[2] = frame->linesize[0] / 2;
202  frame->data[2] = frame->data[1];
203  frame->data[1] = frame->data[2] + frame->linesize[2] * (ctx->height / 2);
204  }
205 
206  frame->format = AV_PIX_FMT_CUDA;
207  frame->width = ctx->width;
208  frame->height = ctx->height;
209 
210  return 0;
211 }
212 
215  enum AVPixelFormat **formats)
216 {
217  enum AVPixelFormat *fmts;
218 
219  fmts = av_malloc_array(2, sizeof(*fmts));
220  if (!fmts)
221  return AVERROR(ENOMEM);
222 
223  fmts[0] = ctx->sw_format;
224  fmts[1] = AV_PIX_FMT_NONE;
225 
226  *formats = fmts;
227 
228  return 0;
229 }
230 
232  const AVFrame *src)
233 {
234  CUDAFramesContext *priv = ctx->hwctx;
235  AVHWDeviceContext *device_ctx = ctx->device_ctx;
236  AVCUDADeviceContext *hwctx = device_ctx->hwctx;
237  CudaFunctions *cu = hwctx->internal->cuda_dl;
238 
239  CUcontext dummy;
240  int i, ret;
241 
242  if ((src->hw_frames_ctx && ((AVHWFramesContext*)src->hw_frames_ctx->data)->format != AV_PIX_FMT_CUDA) ||
243  (dst->hw_frames_ctx && ((AVHWFramesContext*)dst->hw_frames_ctx->data)->format != AV_PIX_FMT_CUDA))
244  return AVERROR(ENOSYS);
245 
246  ret = CHECK_CU(cu->cuCtxPushCurrent(hwctx->cuda_ctx));
247  if (ret < 0)
248  return ret;
249 
250  for (i = 0; i < FF_ARRAY_ELEMS(src->data) && src->data[i]; i++) {
251  CUDA_MEMCPY2D cpy = {
252  .srcPitch = src->linesize[i],
253  .dstPitch = dst->linesize[i],
254  .WidthInBytes = FFMIN(src->linesize[i], dst->linesize[i]),
255  .Height = src->height >> ((i == 0 || i == 3) ? 0 : priv->shift_height),
256  };
257 
258  if (src->hw_frames_ctx) {
259  cpy.srcMemoryType = CU_MEMORYTYPE_DEVICE;
260  cpy.srcDevice = (CUdeviceptr)src->data[i];
261  } else {
262  cpy.srcMemoryType = CU_MEMORYTYPE_HOST;
263  cpy.srcHost = src->data[i];
264  }
265 
266  if (dst->hw_frames_ctx) {
267  cpy.dstMemoryType = CU_MEMORYTYPE_DEVICE;
268  cpy.dstDevice = (CUdeviceptr)dst->data[i];
269  } else {
270  cpy.dstMemoryType = CU_MEMORYTYPE_HOST;
271  cpy.dstHost = dst->data[i];
272  }
273 
274  ret = CHECK_CU(cu->cuMemcpy2DAsync(&cpy, hwctx->stream));
275  if (ret < 0)
276  goto exit;
277  }
278 
279  if (!dst->hw_frames_ctx) {
280  ret = CHECK_CU(cu->cuStreamSynchronize(hwctx->stream));
281  if (ret < 0)
282  goto exit;
283  }
284 
285 exit:
286  CHECK_CU(cu->cuCtxPopCurrent(&dummy));
287 
288  return 0;
289 }
290 
291 static void cuda_device_uninit(AVHWDeviceContext *device_ctx)
292 {
293  CUDADeviceContext *hwctx = device_ctx->hwctx;
294 
295  if (hwctx->p.internal) {
296  CudaFunctions *cu = hwctx->internal.cuda_dl;
297 
298  if (hwctx->internal.is_allocated && hwctx->p.cuda_ctx) {
300  CHECK_CU(cu->cuDevicePrimaryCtxRelease(hwctx->internal.cuda_device));
301  else if (!(hwctx->internal.flags & AV_CUDA_USE_CURRENT_CONTEXT))
302  CHECK_CU(cu->cuCtxDestroy(hwctx->p.cuda_ctx));
303 
304  hwctx->p.cuda_ctx = NULL;
305  }
306 
307  cuda_free_functions(&hwctx->internal.cuda_dl);
308  memset(&hwctx->internal, 0, sizeof(hwctx->internal));
309  hwctx->p.internal = NULL;
310  }
311 }
312 
314 {
315  CUDADeviceContext *hwctx = ctx->hwctx;
316  int ret;
317 
318  hwctx->p.internal = &hwctx->internal;
319 
320  if (!hwctx->internal.cuda_dl) {
321  ret = cuda_load_functions(&hwctx->internal.cuda_dl, ctx);
322  if (ret < 0) {
323  av_log(ctx, AV_LOG_ERROR, "Could not dynamically load CUDA\n");
324  goto error;
325  }
326  }
327 
328  return 0;
329 
330 error:
332  return ret;
333 }
334 
335 static int cuda_context_init(AVHWDeviceContext *device_ctx, int flags) {
336  AVCUDADeviceContext *hwctx = device_ctx->hwctx;
337  CudaFunctions *cu;
338  CUcontext dummy;
339  int ret, dev_active = 0;
340  unsigned int dev_flags = 0;
341 
342  const unsigned int desired_flags = CU_CTX_SCHED_BLOCKING_SYNC;
343 
344  cu = hwctx->internal->cuda_dl;
345 
346  hwctx->internal->flags = flags;
347 
349  ret = CHECK_CU(cu->cuDevicePrimaryCtxGetState(hwctx->internal->cuda_device,
350  &dev_flags, &dev_active));
351  if (ret < 0)
352  return ret;
353 
354  if (dev_active && dev_flags != desired_flags) {
355  av_log(device_ctx, AV_LOG_ERROR, "Primary context already active with incompatible flags.\n");
356  return AVERROR(ENOTSUP);
357  } else if (dev_flags != desired_flags) {
358  ret = CHECK_CU(cu->cuDevicePrimaryCtxSetFlags(hwctx->internal->cuda_device,
359  desired_flags));
360  if (ret < 0)
361  return ret;
362  }
363 
364  ret = CHECK_CU(cu->cuDevicePrimaryCtxRetain(&hwctx->cuda_ctx,
365  hwctx->internal->cuda_device));
366  if (ret < 0)
367  return ret;
368  } else if (flags & AV_CUDA_USE_CURRENT_CONTEXT) {
369  ret = CHECK_CU(cu->cuCtxGetCurrent(&hwctx->cuda_ctx));
370  if (ret < 0)
371  return ret;
372  av_log(device_ctx, AV_LOG_INFO, "Using current CUDA context.\n");
373  } else {
374  ret = CHECK_CU(cu->cuCtxCreate(&hwctx->cuda_ctx, desired_flags,
375  hwctx->internal->cuda_device));
376  if (ret < 0)
377  return ret;
378 
379  CHECK_CU(cu->cuCtxPopCurrent(&dummy));
380  }
381 
382  hwctx->internal->is_allocated = 1;
383 
384  // Setting stream to NULL will make functions automatically use the default CUstream
385  hwctx->stream = NULL;
386 
387  return 0;
388 }
389 
391  AVDictionary *opts, int *flags)
392 {
393  AVDictionaryEntry *primary_ctx_opt = av_dict_get(opts, "primary_ctx", NULL, 0);
394  AVDictionaryEntry *current_ctx_opt = av_dict_get(opts, "current_ctx", NULL, 0);
395 
396  int use_primary_ctx = 0, use_current_ctx = 0;
397  if (primary_ctx_opt)
398  use_primary_ctx = strtol(primary_ctx_opt->value, NULL, 10);
399 
400  if (current_ctx_opt)
401  use_current_ctx = strtol(current_ctx_opt->value, NULL, 10);
402 
403  if (use_primary_ctx && use_current_ctx) {
404  av_log(device_ctx, AV_LOG_ERROR, "Requested both primary and current CUDA context simultaneously.\n");
405  return AVERROR(EINVAL);
406  }
407 
408  if (primary_ctx_opt && use_primary_ctx) {
409  av_log(device_ctx, AV_LOG_VERBOSE, "Using CUDA primary device context\n");
411  } else if (primary_ctx_opt) {
412  av_log(device_ctx, AV_LOG_VERBOSE, "Disabling use of CUDA primary device context\n");
414  }
415 
416  if (current_ctx_opt && use_current_ctx) {
417  av_log(device_ctx, AV_LOG_VERBOSE, "Using CUDA current device context\n");
419  } else if (current_ctx_opt) {
420  av_log(device_ctx, AV_LOG_VERBOSE, "Disabling use of CUDA current device context\n");
422  }
423 
424  return 0;
425 }
426 
427 static int cuda_device_create(AVHWDeviceContext *device_ctx,
428  const char *device,
429  AVDictionary *opts, int flags)
430 {
431  AVCUDADeviceContext *hwctx = device_ctx->hwctx;
432  CudaFunctions *cu;
433  int ret, device_idx = 0;
434 
435  ret = cuda_flags_from_opts(device_ctx, opts, &flags);
436  if (ret < 0)
437  goto error;
438 
439  if (device)
440  device_idx = strtol(device, NULL, 0);
441 
442  ret = cuda_device_init(device_ctx);
443  if (ret < 0)
444  goto error;
445 
446  cu = hwctx->internal->cuda_dl;
447 
448  ret = CHECK_CU(cu->cuInit(0));
449  if (ret < 0)
450  goto error;
451 
452  ret = CHECK_CU(cu->cuDeviceGet(&hwctx->internal->cuda_device, device_idx));
453  if (ret < 0)
454  goto error;
455 
456  ret = cuda_context_init(device_ctx, flags);
457  if (ret < 0)
458  goto error;
459 
460  return 0;
461 
462 error:
463  cuda_device_uninit(device_ctx);
464  return ret;
465 }
466 
467 static int cuda_device_derive(AVHWDeviceContext *device_ctx,
469  int flags) {
470  AVCUDADeviceContext *hwctx = device_ctx->hwctx;
471  CudaFunctions *cu;
472  const char *src_uuid = NULL;
473 #if CONFIG_VULKAN
474  VkPhysicalDeviceIDProperties vk_idp;
475 #endif
476  int ret, i, device_count;
477 
478  ret = cuda_flags_from_opts(device_ctx, opts, &flags);
479  if (ret < 0)
480  goto error;
481 
482 #if CONFIG_VULKAN
483  vk_idp = (VkPhysicalDeviceIDProperties) {
484  .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ID_PROPERTIES,
485  };
486 #endif
487 
488  switch (src_ctx->type) {
489 #if CONFIG_VULKAN
490 #define TYPE PFN_vkGetPhysicalDeviceProperties2
492  AVVulkanDeviceContext *vkctx = src_ctx->hwctx;
493  TYPE prop_fn = (TYPE)vkctx->get_proc_addr(vkctx->inst, "vkGetPhysicalDeviceProperties2");
494  VkPhysicalDeviceProperties2 vk_dev_props = {
495  .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2,
496  .pNext = &vk_idp,
497  };
498  prop_fn(vkctx->phys_dev, &vk_dev_props);
499  src_uuid = vk_idp.deviceUUID;
500  break;
501  }
502 #undef TYPE
503 #endif
504  default:
505  ret = AVERROR(ENOSYS);
506  goto error;
507  }
508 
509  if (!src_uuid) {
510  av_log(device_ctx, AV_LOG_ERROR,
511  "Failed to get UUID of source device.\n");
512  ret = AVERROR(EINVAL);
513  goto error;
514  }
515 
516  ret = cuda_device_init(device_ctx);
517  if (ret < 0)
518  goto error;
519 
520  cu = hwctx->internal->cuda_dl;
521 
522  ret = CHECK_CU(cu->cuInit(0));
523  if (ret < 0)
524  goto error;
525 
526  ret = CHECK_CU(cu->cuDeviceGetCount(&device_count));
527  if (ret < 0)
528  goto error;
529 
530  hwctx->internal->cuda_device = -1;
531  for (i = 0; i < device_count; i++) {
532  CUdevice dev;
533  CUuuid uuid;
534 
535  ret = CHECK_CU(cu->cuDeviceGet(&dev, i));
536  if (ret < 0)
537  goto error;
538 
539  ret = CHECK_CU(cu->cuDeviceGetUuid(&uuid, dev));
540  if (ret < 0)
541  goto error;
542 
543  if (memcmp(src_uuid, uuid.bytes, sizeof (uuid.bytes)) == 0) {
544  hwctx->internal->cuda_device = dev;
545  break;
546  }
547  }
548 
549  if (hwctx->internal->cuda_device == -1) {
550  av_log(device_ctx, AV_LOG_ERROR, "Could not derive CUDA device.\n");
551  goto error;
552  }
553 
554  ret = cuda_context_init(device_ctx, flags);
555  if (ret < 0)
556  goto error;
557 
558  return 0;
559 
560 error:
561  cuda_device_uninit(device_ctx);
562  return ret;
563 }
564 
567  .name = "CUDA",
568 
569  .device_hwctx_size = sizeof(CUDADeviceContext),
570  .frames_hwctx_size = sizeof(CUDAFramesContext),
571 
572  .device_create = cuda_device_create,
573  .device_derive = cuda_device_derive,
574  .device_init = cuda_device_init,
575  .device_uninit = cuda_device_uninit,
576  .frames_get_constraints = cuda_frames_get_constraints,
577  .frames_init = cuda_frames_init,
578  .frames_get_buffer = cuda_get_buffer,
579  .transfer_get_formats = cuda_transfer_get_formats,
580  .transfer_data_to = cuda_transfer_data,
581  .transfer_data_from = cuda_transfer_data,
582 
583  .pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_CUDA, AV_PIX_FMT_NONE },
584 };
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:86
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:335
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:467
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:213
AV_PIX_FMT_BGR32
#define AV_PIX_FMT_BGR32
Definition: pixfmt.h:490
cuda_flags_from_opts
static int cuda_flags_from_opts(AVHWDeviceContext *device_ctx, AVDictionary *opts, int *flags)
Definition: hwcontext_cuda.c:390
CUDAFramesContext
Definition: hwcontext_cuda.c:33
CHECK_CU
#define CHECK_CU(x)
Definition: hwcontext_cuda.c:62
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:410
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:149
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:447
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:442
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:193
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:3276
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:61
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:454
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:528
AV_PIX_FMT_0BGR32
#define AV_PIX_FMT_0BGR32
Definition: pixfmt.h:493
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:313
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:88
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:231
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:565
AV_PIX_FMT_NV16
@ AV_PIX_FMT_NV16
interleaved chroma YUV 4:2:2, 16bpp, (1 Cr & Cb sample per 2x1 Y samples)
Definition: pixfmt.h:198
buffer.h
AV_PIX_FMT_RGB32
#define AV_PIX_FMT_RGB32
Definition: pixfmt.h:488
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:291
AV_PIX_FMT_P016
#define AV_PIX_FMT_P016
Definition: pixfmt.h:570
AVHWFrameTransferDirection
AVHWFrameTransferDirection
Definition: hwcontext.h:404
AVHWFramesContext
This struct describes a set or pool of "hardware" frames (i.e.
Definition: hwcontext.h:116
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:73
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:492
cuda_check.h
cuda_buffer_free
static void cuda_buffer_free(void *opaque, uint8_t *data)
Definition: hwcontext_cuda.c:89
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:427
AV_PIX_FMT_P216LE
@ AV_PIX_FMT_P216LE
interleaved chroma YUV 4:2:2, 32bpp, little-endian
Definition: pixfmt.h:396
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:184
AV_PIX_FMT_P010
#define AV_PIX_FMT_P010
Definition: pixfmt.h:568
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:105
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:64
cuda_frames_init
static int cuda_frames_init(AVHWFramesContext *ctx)
Definition: hwcontext_cuda.c:136
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:3168