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