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