FFmpeg
cuviddec.c
Go to the documentation of this file.
1 /*
2  * Nvidia CUVID decoder
3  * Copyright (c) 2016 Timo Rothenpieler <timo@rothenpieler.org>
4  *
5  * This file is part of FFmpeg.
6  *
7  * FFmpeg is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * FFmpeg is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with FFmpeg; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20  */
21 
22 #include "config_components.h"
23 
24 #include <stdatomic.h>
25 
27 
28 #include "libavutil/buffer.h"
29 #include "libavutil/mathematics.h"
30 #include "libavutil/hwcontext.h"
32 #include "libavutil/cuda_check.h"
33 #include "libavutil/fifo.h"
34 #include "libavutil/log.h"
35 #include "libavutil/mem.h"
36 #include "libavutil/opt.h"
37 #include "libavutil/pixdesc.h"
38 
39 #include "avcodec.h"
40 #include "bsf.h"
41 #include "codec_internal.h"
42 #include "decode.h"
43 #include "hwconfig.h"
44 #include "nvdec.h"
45 #include "internal.h"
46 
47 #if !NVDECAPI_CHECK_VERSION(9, 0)
48 #define cudaVideoSurfaceFormat_YUV444 2
49 #define cudaVideoSurfaceFormat_YUV444_16Bit 3
50 #endif
51 
52 #if NVDECAPI_CHECK_VERSION(11, 0)
53 #define CUVID_HAS_AV1_SUPPORT
54 #endif
55 
56 #ifdef NVDEC_HAVE_OPAQUE_OUTPUT_SUPPORT
57 typedef struct CuvidDecoderCleanup {
58  CUvideodecoder cudecoder;
59  CUarray *cuarray_surfaces;
60  int cuarray_num_surfaces;
61  AVBufferRef *hwdevice;
62  CuvidFunctions *cvdl;
63 } CuvidDecoderCleanup;
64 #endif
65 
66 typedef struct CuvidContext
67 {
69 
70  CUvideodecoder cudecoder;
71  CUvideoparser cuparser;
72 
73  /* This packet coincides with AVCodecInternal.in_pkt
74  * and is not owned by us. */
76 
77  char *cu_gpu;
80  char *crop_expr;
81  char *resize_expr;
82 
83  struct {
84  int left;
85  int top;
86  int right;
87  int bottom;
88  } crop;
89 
90  struct {
91  int width;
92  int height;
93  } resize;
94 
97 
99 
104 
108 
109  int *key_frame;
110 
111  cudaVideoCodec codec_type;
112  cudaVideoChromaFormat chroma_format;
113 
114  CUVIDDECODECAPS caps8, caps10, caps12;
115 
116  CUVIDPARSERPARAMS cuparseinfo;
117  CUVIDEOFORMATEX *cuparse_ext;
118 
119  CudaFunctions *cudl;
120  CuvidFunctions *cvdl;
121 
125  CUstream cuda_stream;
126 #ifdef NVDEC_HAVE_OPAQUE_OUTPUT_SUPPORT
127  CUarray *cuarray_surfaces;
128  int cuarray_num_surfaces;
129  AVBufferRef *surface_in_use_ref;
130  atomic_int *surface_in_use;
131  CuvidDecoderCleanup *decoder_cleanup;
132 #endif
133 } CuvidContext;
134 
135 typedef struct CuvidParsedFrame
136 {
137  CUVIDPARSERDISPINFO dispinfo;
141 
142 #define CHECK_CU(x) FF_CUDA_CHECK_DL(avctx, ctx->cudl, x)
143 
144 // NV recommends [2;4] range
145 #define CUVID_MAX_DISPLAY_DELAY (4)
146 
147 // Actual pool size will be determined by parser.
148 #define CUVID_DEFAULT_NUM_SURFACES (CUVID_MAX_DISPLAY_DELAY + 1)
149 
151  enum AVPixelFormat *fmt)
152 {
153  enum AVPixelFormat requested = ctx->output_format;
154 
155  if (requested == AV_PIX_FMT_NONE)
156  requested = AV_PIX_FMT_CUDA;
157 
158  if (ctx->zero_copy && requested != AV_PIX_FMT_CUARRAY) {
159  av_log(avctx, AV_LOG_WARNING,
160  "zero_copy requires cuarray output format; "
161  "overriding -output_format %s -> cuarray\n",
162  av_get_pix_fmt_name(requested) ? av_get_pix_fmt_name(requested) : "unknown");
163  requested = AV_PIX_FMT_CUARRAY;
164  }
165 
166  switch (requested) {
167  case AV_PIX_FMT_CUDA:
168  break;
169  case AV_PIX_FMT_CUARRAY:
170 #ifdef NVDEC_HAVE_OPAQUE_OUTPUT_SUPPORT
171  break;
172 #else
173  av_log(avctx, AV_LOG_ERROR,
174  "CUARRAY output requires Video Codec SDK 13.1 or later\n");
175  return AVERROR(ENOSYS);
176 #endif
177  default:
178  av_log(avctx, AV_LOG_ERROR,
179  "Unsupported cuvid output format: %s\n",
180  av_get_pix_fmt_name(requested) ? av_get_pix_fmt_name(requested) : "unknown");
181  return AVERROR(EINVAL);
182  }
183 
184  *fmt = requested;
185  return 0;
186 }
187 
189  enum AVPixelFormat hw_format,
190  enum AVPixelFormat sw_format)
191 {
192  pix_fmts[0] = hw_format;
193  pix_fmts[1] = sw_format;
196 }
197 
198 #ifdef NVDEC_HAVE_OPAQUE_OUTPUT_SUPPORT
199 typedef struct CuvidSurfaceRelease {
200  AVBufferRef *in_use_ref;
201  int idx;
202 } CuvidSurfaceRelease;
203 
204 static void cuvid_cuarray_buf_free(void *opaque, uint8_t *data)
205 {
206  CuvidSurfaceRelease *rel = opaque;
207  atomic_int *flags = (atomic_int *)rel->in_use_ref->data;
208  atomic_store_explicit(&flags[rel->idx], 0, memory_order_release);
209  av_buffer_unref(&rel->in_use_ref);
210  av_free(rel);
211 }
212 
213 static void cuvid_decoder_cleanup_free(void *opaque, uint8_t *data)
214 {
215  CuvidDecoderCleanup *cleanup = opaque;
216 
217  if (cleanup && cleanup->hwdevice) {
218  AVHWDeviceContext *device_ctx = (AVHWDeviceContext *)cleanup->hwdevice->data;
219  AVCUDADeviceContext *device_hwctx = device_ctx->hwctx;
220  CudaFunctions *cudl = device_hwctx->internal->cuda_dl;
221  CUcontext dummy;
222 
223  cudl->cuCtxPushCurrent(device_hwctx->cuda_ctx);
224 
225  if (cleanup->cudecoder && cleanup->cvdl)
226  cleanup->cvdl->cuvidDestroyDecoder(cleanup->cudecoder);
227 
228  if (cleanup->cuarray_surfaces) {
229  for (int i = 0; i < cleanup->cuarray_num_surfaces; i++)
230  cudl->cuArrayDestroy(cleanup->cuarray_surfaces[i]);
231  }
232 
233  cudl->cuCtxPopCurrent(&dummy);
234  av_buffer_unref(&cleanup->hwdevice);
235  }
236 
237  if (cleanup) {
238  av_freep(&cleanup->cuarray_surfaces);
239  cuvid_free_functions(&cleanup->cvdl);
240  av_free(cleanup);
241  }
242 
243  av_free(data);
244 }
245 
246 #endif
247 
248 static int CUDAAPI cuvid_handle_video_sequence(void *opaque, CUVIDEOFORMAT* format)
249 {
250  AVCodecContext *avctx = opaque;
251  CuvidContext *ctx = avctx->priv_data;
252  AVHWFramesContext *hwframe_ctx = (AVHWFramesContext*)ctx->hwframe->data;
253  CUVIDDECODECAPS *caps = NULL;
254  CUVIDDECODECREATEINFO cuinfo;
255  int surface_fmt;
256  int chroma_444;
257  int old_nb_surfaces, fifo_size_inc, fifo_size_mul = 1;
258  enum AVPixelFormat requested_hw_format;
259 
260  int old_width = avctx->width;
261  int old_height = avctx->height;
262 
263  enum AVPixelFormat pix_fmts[4];
264 
265  av_log(avctx, AV_LOG_TRACE, "pfnSequenceCallback, progressive_sequence=%d\n", format->progressive_sequence);
266 
267  memset(&cuinfo, 0, sizeof(cuinfo));
268 
269  ctx->internal_error = 0;
270 
271  surface_fmt = cuvid_get_requested_hw_format(avctx, ctx, &requested_hw_format);
272  if (surface_fmt < 0) {
273  ctx->internal_error = surface_fmt;
274  return 0;
275  }
276 
277  avctx->coded_width = cuinfo.ulWidth = format->coded_width;
278  avctx->coded_height = cuinfo.ulHeight = format->coded_height;
279 
280  // apply cropping
281  cuinfo.display_area.left = format->display_area.left + ctx->crop.left;
282  cuinfo.display_area.top = format->display_area.top + ctx->crop.top;
283  cuinfo.display_area.right = format->display_area.right - ctx->crop.right;
284  cuinfo.display_area.bottom = format->display_area.bottom - ctx->crop.bottom;
285 
286  // width and height need to be set before calling ff_get_format
287  if (ctx->resize_expr) {
288  avctx->width = ctx->resize.width;
289  avctx->height = ctx->resize.height;
290  } else {
291  avctx->width = cuinfo.display_area.right - cuinfo.display_area.left;
292  avctx->height = cuinfo.display_area.bottom - cuinfo.display_area.top;
293  }
294 
295  // NVDEC target dimensions must be even-aligned for internal surface allocation.
296  // For chroma-subsampled formats (420/422), the output dimensions must also be
297  // even. For monochrome/444, keep the original output dimensions and only
298  // even-align the NVDEC target — the frame copy will crop to avctx dimensions.
299  cuinfo.ulTargetWidth = (avctx->width + 1) & ~1;
300  cuinfo.ulTargetHeight = (avctx->height + 1) & ~1;
301  if (format->chroma_format == cudaVideoChromaFormat_420 ||
302  format->chroma_format == cudaVideoChromaFormat_422) {
303  avctx->width = cuinfo.ulTargetWidth;
304  avctx->height = cuinfo.ulTargetHeight;
305  }
306 
307  // aspect ratio conversion, 1:1, depends on scaled resolution
308  cuinfo.target_rect.left = 0;
309  cuinfo.target_rect.top = 0;
310  cuinfo.target_rect.right = cuinfo.ulTargetWidth;
311  cuinfo.target_rect.bottom = cuinfo.ulTargetHeight;
312 
313  chroma_444 = format->chroma_format == cudaVideoChromaFormat_444;
314 
315  switch (format->bit_depth_luma_minus8) {
316  case 0: // 8-bit
317  if (chroma_444) {
319 #ifdef NVDEC_HAVE_422_SUPPORT
320  } else if (format->chroma_format == cudaVideoChromaFormat_422) {
322 #endif
323  } else {
325  }
326  caps = &ctx->caps8;
327  break;
328  case 2: // 10-bit
329  if (chroma_444) {
331 #ifdef NVDEC_HAVE_422_SUPPORT
332  } else if (format->chroma_format == cudaVideoChromaFormat_422) {
334 #endif
335  } else {
337  }
338  caps = &ctx->caps10;
339  break;
340  case 4: // 12-bit
341  if (chroma_444) {
343 #ifdef NVDEC_HAVE_422_SUPPORT
344  } else if (format->chroma_format == cudaVideoChromaFormat_422) {
346 #endif
347  } else {
349  }
350  caps = &ctx->caps12;
351  break;
352  default:
353  break;
354  }
355 
356  if (!caps || !caps->bIsSupported) {
357  av_log(avctx, AV_LOG_ERROR, "unsupported bit depth: %d\n",
358  format->bit_depth_luma_minus8 + 8);
359  ctx->internal_error = AVERROR(EINVAL);
360  return 0;
361  }
362 
363  cuvid_prepare_format_list(pix_fmts, requested_hw_format, pix_fmts[1]);
364 
365  surface_fmt = ff_get_format(avctx, pix_fmts);
366  if (surface_fmt < 0) {
367  av_log(avctx, AV_LOG_ERROR, "ff_get_format failed: %d\n", surface_fmt);
368  ctx->internal_error = AVERROR(EINVAL);
369  return 0;
370  }
371 
372  if (surface_fmt != AV_PIX_FMT_CUDA && surface_fmt != AV_PIX_FMT_CUARRAY) {
373  av_log(avctx, AV_LOG_VERBOSE,
374  "ff_get_format returned %s, overriding to %s\n",
375  av_get_pix_fmt_name(surface_fmt),
376  av_get_pix_fmt_name(requested_hw_format));
377  surface_fmt = requested_hw_format;
378  }
379 
380  av_log(avctx, AV_LOG_VERBOSE, "Formats: Original: %s | HW: %s | SW: %s\n",
382  av_get_pix_fmt_name(surface_fmt),
384 
385  ctx->opaque_output = (surface_fmt == AV_PIX_FMT_CUARRAY);
386  avctx->pix_fmt = surface_fmt;
387 
388  if (ctx->opaque_output) {
389  switch (avctx->sw_pix_fmt) {
390  case AV_PIX_FMT_YUV444P: avctx->sw_pix_fmt = AV_PIX_FMT_NV24; break;
391  case AV_PIX_FMT_YUV444P10MSB: avctx->sw_pix_fmt = AV_PIX_FMT_P410; break;
392  case AV_PIX_FMT_YUV444P12MSB: avctx->sw_pix_fmt = AV_PIX_FMT_P412; break;
393  default: break;
394  }
395  }
396 
397  // Update our hwframe ctx, as the get_format callback might have refreshed it!
398  if (avctx->hw_frames_ctx) {
399  av_buffer_unref(&ctx->hwframe);
400 
401  ctx->hwframe = av_buffer_ref(avctx->hw_frames_ctx);
402  if (!ctx->hwframe) {
403  ctx->internal_error = AVERROR(ENOMEM);
404  return 0;
405  }
406 
407  hwframe_ctx = (AVHWFramesContext*)ctx->hwframe->data;
408  }
409 
410  ff_set_sar(avctx, av_div_q(
411  (AVRational){ format->display_aspect_ratio.x, format->display_aspect_ratio.y },
412  (AVRational){ avctx->width, avctx->height }));
413 
414  ctx->deint_mode_current = format->progressive_sequence
415  ? cudaVideoDeinterlaceMode_Weave
416  : ctx->deint_mode;
417 
418  ctx->progressive_sequence = format->progressive_sequence;
419 
420  if (!format->progressive_sequence && ctx->deint_mode_current == cudaVideoDeinterlaceMode_Weave)
422  else
424 
425  if (format->video_signal_description.video_full_range_flag)
426  avctx->color_range = AVCOL_RANGE_JPEG;
427  else
428  avctx->color_range = AVCOL_RANGE_MPEG;
429 
430  if (format->video_signal_description.color_primaries)
431  avctx->color_primaries = format->video_signal_description.color_primaries;
432  if (format->video_signal_description.transfer_characteristics)
433  avctx->color_trc = format->video_signal_description.transfer_characteristics;
434  if (format->video_signal_description.matrix_coefficients)
435  avctx->colorspace = format->video_signal_description.matrix_coefficients;
436 
437  if (format->bitrate)
438  avctx->bit_rate = format->bitrate;
439 
440  if (format->frame_rate.numerator && format->frame_rate.denominator) {
441  avctx->framerate.num = format->frame_rate.numerator;
442  avctx->framerate.den = format->frame_rate.denominator;
443  }
444 
445  if (ctx->cudecoder
446  && avctx->coded_width == format->coded_width
447  && avctx->coded_height == format->coded_height
448  && avctx->width == old_width
449  && avctx->height == old_height
450  && ctx->chroma_format == format->chroma_format
451  && ctx->codec_type == format->codec)
452  return 1;
453 
454  if (ctx->cudecoder) {
455  av_log(avctx, AV_LOG_TRACE, "Re-initializing decoder\n");
456  ctx->internal_error = CHECK_CU(ctx->cvdl->cuvidDestroyDecoder(ctx->cudecoder));
457  if (ctx->internal_error < 0)
458  return 0;
459  ctx->cudecoder = NULL;
460  }
461 
462  if (hwframe_ctx->pool && (
463  hwframe_ctx->width < avctx->width ||
464  hwframe_ctx->height < avctx->height ||
465  (hwframe_ctx->format != AV_PIX_FMT_CUDA && hwframe_ctx->format != AV_PIX_FMT_CUARRAY) ||
466  hwframe_ctx->sw_format != avctx->sw_pix_fmt)) {
467  av_log(avctx, AV_LOG_ERROR, "AVHWFramesContext is already initialized with incompatible parameters\n");
468  av_log(avctx, AV_LOG_DEBUG, "width: %d <-> %d\n", hwframe_ctx->width, avctx->width);
469  av_log(avctx, AV_LOG_DEBUG, "height: %d <-> %d\n", hwframe_ctx->height, avctx->height);
470  av_log(avctx, AV_LOG_DEBUG, "format: %s <-> %s\n", av_get_pix_fmt_name(hwframe_ctx->format),
471  av_get_pix_fmt_name(avctx->pix_fmt));
472  av_log(avctx, AV_LOG_DEBUG, "sw_format: %s <-> %s\n",
474  ctx->internal_error = AVERROR(EINVAL);
475  return 0;
476  }
477 
478  ctx->chroma_format = format->chroma_format;
479 
480  cuinfo.CodecType = ctx->codec_type = format->codec;
481  cuinfo.ChromaFormat = format->chroma_format;
482 
483  switch (avctx->sw_pix_fmt) {
484  case AV_PIX_FMT_NV12:
485  cuinfo.OutputFormat = cudaVideoSurfaceFormat_NV12;
486  break;
487  case AV_PIX_FMT_P010:
488  case AV_PIX_FMT_P012:
489  case AV_PIX_FMT_P016:
490  cuinfo.OutputFormat = cudaVideoSurfaceFormat_P016;
491  break;
492 #ifdef NVDEC_HAVE_422_SUPPORT
493  case AV_PIX_FMT_NV16:
494  cuinfo.OutputFormat = cudaVideoSurfaceFormat_NV16;
495  break;
496  case AV_PIX_FMT_P210:
497  case AV_PIX_FMT_P212:
498  case AV_PIX_FMT_P216:
499  cuinfo.OutputFormat = cudaVideoSurfaceFormat_P216;
500  break;
501 #endif
502  case AV_PIX_FMT_YUV444P:
503  case AV_PIX_FMT_NV24:
504  cuinfo.OutputFormat = cudaVideoSurfaceFormat_YUV444;
505  break;
509  case AV_PIX_FMT_P410:
510  case AV_PIX_FMT_P412:
511  case AV_PIX_FMT_P416:
512  cuinfo.OutputFormat = cudaVideoSurfaceFormat_YUV444_16Bit;
513  break;
514  default:
515  av_log(avctx, AV_LOG_ERROR, "Unsupported output format: %s\n",
517  ctx->internal_error = AVERROR(EINVAL);
518  return 0;
519  }
520 
521 #ifdef NVDEC_HAVE_OPAQUE_OUTPUT_SUPPORT
522  if (ctx->opaque_output) {
523  switch (cuinfo.OutputFormat) {
524  case cudaVideoSurfaceFormat_NV12: cuinfo.OutputFormat = cudaVideoSurfaceFormat_NV12_Opaque; break;
525  case cudaVideoSurfaceFormat_P016: cuinfo.OutputFormat = cudaVideoSurfaceFormat_P016_Opaque; break;
526 #ifdef NVDEC_HAVE_422_SUPPORT
527  case cudaVideoSurfaceFormat_NV16: cuinfo.OutputFormat = cudaVideoSurfaceFormat_NV16_Opaque; break;
528  case cudaVideoSurfaceFormat_P216: cuinfo.OutputFormat = cudaVideoSurfaceFormat_P216_Opaque; break;
529 #endif
530  case cudaVideoSurfaceFormat_YUV444: cuinfo.OutputFormat = cudaVideoSurfaceFormat_YUV444_Opaque; break;
531  case cudaVideoSurfaceFormat_YUV444_16Bit: cuinfo.OutputFormat = cudaVideoSurfaceFormat_YUV444_16Bit_Opaque; break;
532  default: break;
533  }
534  }
535 #endif
536 
537  if (ctx->deint_mode_current != cudaVideoDeinterlaceMode_Weave && !ctx->drop_second_field) {
538  avctx->framerate = av_mul_q(avctx->framerate, (AVRational){2, 1});
539  fifo_size_mul = 2;
540  }
541 
542  old_nb_surfaces = ctx->nb_surfaces;
543  ctx->nb_surfaces = FFMAX(ctx->nb_surfaces, format->min_num_decode_surfaces + 3);
544  if (avctx->extra_hw_frames > 0)
545  ctx->nb_surfaces += avctx->extra_hw_frames;
546 #ifdef NVDEC_HAVE_OPAQUE_OUTPUT_SUPPORT
547  if (ctx->opaque_output && ctx->zero_copy)
548  ctx->nb_surfaces = FFMIN(FFMAX(ctx->nb_surfaces, format->min_num_decode_surfaces + 16),
549  MAX_NUM_REGISTERED_DECODE_SURFACES);
550 #endif
551 
552  fifo_size_inc = ctx->nb_surfaces * fifo_size_mul - av_fifo_can_read(ctx->frame_queue) - av_fifo_can_write(ctx->frame_queue);
553  if (fifo_size_inc > 0 && av_fifo_grow2(ctx->frame_queue, fifo_size_inc) < 0) {
554  av_log(avctx, AV_LOG_ERROR, "Failed to grow frame queue on video sequence callback\n");
555  ctx->internal_error = AVERROR(ENOMEM);
556  return 0;
557  }
558 
559  if (ctx->nb_surfaces > old_nb_surfaces && av_reallocp_array(&ctx->key_frame, ctx->nb_surfaces, sizeof(int)) < 0) {
560  av_log(avctx, AV_LOG_ERROR, "Failed to grow key frame array on video sequence callback\n");
561  ctx->internal_error = AVERROR(ENOMEM);
562  return 0;
563  }
564 
565  cuinfo.ulNumDecodeSurfaces = ctx->nb_surfaces;
566  cuinfo.ulNumOutputSurfaces = ctx->opaque_output ? 0 : 1;
567  cuinfo.ulCreationFlags = cudaVideoCreate_PreferCUVID;
568  cuinfo.bitDepthMinus8 = format->bit_depth_luma_minus8;
569  cuinfo.DeinterlaceMode = ctx->deint_mode_current;
570 
571  ctx->internal_error = CHECK_CU(ctx->cvdl->cuvidCreateDecoder(&ctx->cudecoder, &cuinfo));
572  if (ctx->internal_error < 0)
573  return 0;
574 
575 #ifdef NVDEC_HAVE_OPAQUE_OUTPUT_SUPPORT
576  if (ctx->opaque_output) {
577  CUDA_ARRAY3D_DESCRIPTOR arr_desc;
578  CUVIDREGISTERDECODESURFACESINFO reg_info;
579  CUcontext dummy;
580  int i;
581 
582  ff_nvdec_fill_cuarray_desc(&arr_desc, avctx, cuinfo.OutputFormat);
583 
584  if (ctx->cuarray_surfaces) {
585  if (ctx->decoder_cleanup) {
586  ctx->decoder_cleanup->cuarray_surfaces = NULL;
587  ctx->decoder_cleanup->cuarray_num_surfaces = 0;
588  ctx->decoder_cleanup->cudecoder = NULL;
589  ctx->decoder_cleanup = NULL;
590  }
591  for (i = 0; i < ctx->cuarray_num_surfaces; i++)
592  ctx->cudl->cuArrayDestroy(ctx->cuarray_surfaces[i]);
593  av_freep(&ctx->cuarray_surfaces);
594  av_buffer_unref(&ctx->surface_in_use_ref);
595  ctx->surface_in_use = NULL;
596  }
597  ctx->cuarray_num_surfaces = ctx->nb_surfaces;
598  ctx->cuarray_surfaces = av_calloc(ctx->cuarray_num_surfaces, sizeof(CUarray));
599  if (!ctx->cuarray_surfaces) {
600  ctx->internal_error = AVERROR(ENOMEM);
601  return 0;
602  }
603  {
604  atomic_int *flags = av_calloc(ctx->cuarray_num_surfaces, sizeof(*flags));
605  CuvidDecoderCleanup *cleanup = NULL;
606  if (!flags) {
607  ctx->internal_error = AVERROR(ENOMEM);
608  return 0;
609  }
610  if (ctx->zero_copy) {
611  cleanup = av_mallocz(sizeof(*cleanup));
612  if (!cleanup) {
613  av_free((void *)flags);
614  ctx->internal_error = AVERROR(ENOMEM);
615  return 0;
616  }
617  ctx->decoder_cleanup = cleanup;
618  }
619  ctx->surface_in_use_ref = av_buffer_create(
620  (uint8_t *)flags, ctx->cuarray_num_surfaces * sizeof(*flags),
621  cleanup ? cuvid_decoder_cleanup_free : NULL,
622  cleanup, 0);
623  if (!ctx->surface_in_use_ref) {
624  av_free((void *)flags);
625  av_free(cleanup);
626  ctx->decoder_cleanup = NULL;
627  ctx->internal_error = AVERROR(ENOMEM);
628  return 0;
629  }
630  ctx->surface_in_use = flags;
631  }
632 
633  for (i = 0; i < ctx->cuarray_num_surfaces; i++) {
634  ctx->internal_error = CHECK_CU(ctx->cudl->cuArray3DCreate(
635  &ctx->cuarray_surfaces[i], &arr_desc));
636  if (ctx->internal_error < 0) {
637  for (int j = 0; j < i; j++)
638  ctx->cudl->cuArrayDestroy(ctx->cuarray_surfaces[j]);
639  av_freep(&ctx->cuarray_surfaces);
640  av_buffer_unref(&ctx->surface_in_use_ref);
641  ctx->surface_in_use = NULL;
642  ctx->cuarray_num_surfaces = 0;
643  return 0;
644  }
645  }
646 
647  {
648  AVHWDeviceContext *dev_ctx =
649  (AVHWDeviceContext *)ctx->hwdevice->data;
650  AVCUDADeviceContext *dev_hwctx = dev_ctx->hwctx;
651  ctx->internal_error = CHECK_CU(ctx->cudl->cuCtxPushCurrent(
652  dev_hwctx->cuda_ctx));
653  }
654  if (ctx->internal_error < 0)
655  return 0;
656 
657  memset(&reg_info, 0, sizeof(reg_info));
658  reg_info.ulNumDecodeSurfaces = ctx->cuarray_num_surfaces;
659  reg_info.pDecodeSurfaces = ctx->cuarray_surfaces;
660 
661  if (ctx->cvdl->cuvidRegisterDecodeSurfaces) {
662  ctx->internal_error = CHECK_CU(
663  ctx->cvdl->cuvidRegisterDecodeSurfaces(
664  ctx->cudecoder, &reg_info));
665  } else {
666  av_log(avctx, AV_LOG_ERROR, "cuvidRegisterDecodeSurfaces not available in loaded driver\n");
667  ctx->internal_error = AVERROR(ENOSYS);
668  }
669  CHECK_CU(ctx->cudl->cuCtxPopCurrent(&dummy));
670  if (ctx->internal_error < 0)
671  return 0;
672 
673  if (ctx->decoder_cleanup) {
674  ctx->decoder_cleanup->cudecoder = ctx->cudecoder;
675  ctx->decoder_cleanup->cuarray_surfaces = ctx->cuarray_surfaces;
676  ctx->decoder_cleanup->cuarray_num_surfaces = ctx->cuarray_num_surfaces;
677  }
678  }
679 #endif
680 
681  if (!hwframe_ctx->pool) {
682  hwframe_ctx->format = avctx->pix_fmt;
683  hwframe_ctx->sw_format = avctx->sw_pix_fmt;
684  hwframe_ctx->width = avctx->width;
685  hwframe_ctx->height = avctx->height;
686 
687 #ifdef NVDEC_HAVE_OPAQUE_OUTPUT_SUPPORT
688  if (hwframe_ctx->format == AV_PIX_FMT_CUARRAY) {
689  AVCUDAFramesContext *cuda_hwctx = hwframe_ctx->hwctx;
690  ff_nvdec_fill_cuarray_desc(&cuda_hwctx->cuarray_desc, avctx, cuinfo.OutputFormat);
691  }
692 #endif
693 
694  if ((ctx->internal_error = av_hwframe_ctx_init(ctx->hwframe)) < 0) {
695  av_log(avctx, AV_LOG_ERROR, "av_hwframe_ctx_init failed\n");
696  return 0;
697  }
698  }
699 
700  if(ctx->cuparseinfo.ulMaxNumDecodeSurfaces != cuinfo.ulNumDecodeSurfaces) {
701  ctx->cuparseinfo.ulMaxNumDecodeSurfaces = cuinfo.ulNumDecodeSurfaces;
702  return cuinfo.ulNumDecodeSurfaces;
703  }
704 
705  return 1;
706 }
707 
708 static int CUDAAPI cuvid_handle_picture_decode(void *opaque, CUVIDPICPARAMS* picparams)
709 {
710  AVCodecContext *avctx = opaque;
711  CuvidContext *ctx = avctx->priv_data;
712 
713  av_log(avctx, AV_LOG_TRACE, "pfnDecodePicture\n");
714 
715  if (atomic_load_explicit(&ctx->abort_decode, memory_order_acquire))
716  return 0;
717 
718  if(picparams->intra_pic_flag)
719  ctx->key_frame[picparams->CurrPicIdx] = picparams->intra_pic_flag;
720 
721 #ifdef NVDEC_HAVE_OPAQUE_OUTPUT_SUPPORT
722  if (ctx->opaque_output) {
723  if (ctx->surface_in_use &&
724  atomic_load_explicit(&ctx->surface_in_use[picparams->CurrPicIdx],
725  memory_order_acquire)) {
726  av_log(avctx, AV_LOG_ERROR,
727  "CUARRAY surface %d still in use by the encoder. "
728  "Increase surfaces with -extra_hw_frames or reduce "
729  "encoder buffering (disable lookahead, reduce B-frames).\n",
730  picparams->CurrPicIdx);
731  ctx->internal_error = AVERROR_EXTERNAL;
732  atomic_store_explicit(&ctx->abort_decode, 1, memory_order_release);
733  return 0;
734  }
735  if (ctx->cvdl->cuvidDecodePictureAsync)
736  ctx->internal_error = CHECK_CU(ctx->cvdl->cuvidDecodePictureAsync(
737  ctx->cudecoder, picparams, ctx->cuda_stream));
738  else
739  ctx->internal_error = CHECK_CU(ctx->cvdl->cuvidDecodePicture(ctx->cudecoder, picparams));
740  } else
741 #endif
742  ctx->internal_error = CHECK_CU(ctx->cvdl->cuvidDecodePicture(ctx->cudecoder, picparams));
743  if (ctx->internal_error < 0)
744  return 0;
745 
746  return 1;
747 }
748 
749 static int CUDAAPI cuvid_handle_picture_display(void *opaque, CUVIDPARSERDISPINFO* dispinfo)
750 {
751  AVCodecContext *avctx = opaque;
752  CuvidContext *ctx = avctx->priv_data;
753  CuvidParsedFrame parsed_frame = { { 0 } };
754  int ret;
755 
756  if (atomic_load_explicit(&ctx->abort_decode, memory_order_acquire))
757  return 0;
758 
759  parsed_frame.dispinfo = *dispinfo;
760  ctx->internal_error = 0;
761 
762  // For some reason, dispinfo->progressive_frame is sometimes wrong.
763  parsed_frame.dispinfo.progressive_frame = ctx->progressive_sequence;
764 
765  if (ctx->deint_mode_current == cudaVideoDeinterlaceMode_Weave) {
766  ret = av_fifo_write(ctx->frame_queue, &parsed_frame, 1);
767  if (ret < 0)
768  av_log(avctx, AV_LOG_ERROR, "Writing frame to fifo failed!\n");
769  } else {
770  parsed_frame.is_deinterlacing = 1;
771  ret = av_fifo_write(ctx->frame_queue, &parsed_frame, 1);
772  if (ret < 0)
773  av_log(avctx, AV_LOG_ERROR, "Writing first frame to fifo failed!\n");
774 
775  if (!ctx->drop_second_field) {
776  parsed_frame.second_field = 1;
777  ret = av_fifo_write(ctx->frame_queue, &parsed_frame, 1);
778  if (ret < 0)
779  av_log(avctx, AV_LOG_ERROR, "Writing second frame to fifo failed!\n");
780  }
781  }
782 
783  return 1;
784 }
785 
787 {
788  CuvidContext *ctx = avctx->priv_data;
789 
790  int shift = 0;
791  if (ctx->deint_mode != cudaVideoDeinterlaceMode_Weave && !ctx->drop_second_field)
792  shift = 1;
793 
794  // shift/divide frame count to ensure the buffer is still signalled full if one half-frame has already been returned when deinterlacing.
795  return ((av_fifo_can_read(ctx->frame_queue) + shift) >> shift) + ctx->cuparseinfo.ulMaxDisplayDelay >= ctx->nb_surfaces;
796 }
797 
798 static int cuvid_decode_packet(AVCodecContext *avctx, const AVPacket *avpkt)
799 {
800  CuvidContext *ctx = avctx->priv_data;
801  AVHWDeviceContext *device_ctx = (AVHWDeviceContext*)ctx->hwdevice->data;
802  AVCUDADeviceContext *device_hwctx = device_ctx->hwctx;
803  CUcontext dummy, cuda_ctx = device_hwctx->cuda_ctx;
804  CUVIDSOURCEDATAPACKET cupkt;
805  int ret = 0, eret = 0, is_flush = ctx->decoder_flushing;
806 
807  av_log(avctx, AV_LOG_TRACE, "cuvid_decode_packet\n");
808 
809  if (atomic_load_explicit(&ctx->abort_decode, memory_order_acquire))
810  return ctx->internal_error ? ctx->internal_error : AVERROR_EXTERNAL;
811 
812  if (is_flush && avpkt && avpkt->size)
813  return AVERROR_EOF;
814 
815  if (cuvid_is_buffer_full(avctx) && avpkt && avpkt->size)
816  return AVERROR(EAGAIN);
817 
818  ret = CHECK_CU(ctx->cudl->cuCtxPushCurrent(cuda_ctx));
819  if (ret < 0) {
820  return ret;
821  }
822 
823  memset(&cupkt, 0, sizeof(cupkt));
824 
825  if (avpkt && avpkt->size) {
826  cupkt.payload_size = avpkt->size;
827  cupkt.payload = avpkt->data;
828 
829  if (avpkt->pts != AV_NOPTS_VALUE) {
830  cupkt.flags = CUVID_PKT_TIMESTAMP;
831  if (avctx->pkt_timebase.num && avctx->pkt_timebase.den)
832  cupkt.timestamp = av_rescale_q(avpkt->pts, avctx->pkt_timebase, (AVRational){1, 10000000});
833  else
834  cupkt.timestamp = avpkt->pts;
835  }
836  } else {
837  cupkt.flags = CUVID_PKT_ENDOFSTREAM;
838  ctx->decoder_flushing = 1;
839  }
840 
841  // When flushing, only actually flush cuvid when the output buffer has been fully emptied.
842  // CUVID happily dumps out a ton of frames with no regard for its own available surfaces.
843  if (!ctx->decoder_flushing || (ctx->decoder_flushing && !av_fifo_can_read(ctx->frame_queue)))
844  ret = CHECK_CU(ctx->cvdl->cuvidParseVideoData(ctx->cuparser, &cupkt));
845  else
846  ret = 0;
847 
848  if (ret < 0)
849  goto error;
850 
851  // cuvidParseVideoData doesn't return an error just because stuff failed...
852  if (ctx->internal_error) {
853  av_log(avctx, AV_LOG_ERROR, "cuvid decode callback error\n");
854  ret = ctx->internal_error;
855  goto error;
856  }
857 
858 error:
859  eret = CHECK_CU(ctx->cudl->cuCtxPopCurrent(&dummy));
860 
861  if (eret < 0)
862  return eret;
863  else if (ret < 0)
864  return ret;
865  else if (is_flush)
866  return AVERROR_EOF;
867  else
868  return 0;
869 }
870 
872 {
873  CuvidContext *ctx = avctx->priv_data;
874  AVHWDeviceContext *device_ctx = (AVHWDeviceContext*)ctx->hwdevice->data;
875  AVCUDADeviceContext *device_hwctx = device_ctx->hwctx;
876  CUcontext dummy, cuda_ctx = device_hwctx->cuda_ctx;
877  CuvidParsedFrame parsed_frame;
878  CUdeviceptr mapped_frame = 0;
879  int ret = 0, eret = 0;
880 
881  av_log(avctx, AV_LOG_TRACE, "cuvid_output_frame\n");
882 
883  if (!atomic_load_explicit(&ctx->abort_decode, memory_order_acquire)) {
884  if (ctx->decoder_flushing) {
885  ret = cuvid_decode_packet(avctx, NULL);
886  if (ret < 0 && ret != AVERROR_EOF)
887  return ret;
888  }
889 
890  if (!cuvid_is_buffer_full(avctx)) {
891  AVPacket *const pkt = ctx->pkt;
892  ret = ff_decode_get_packet(avctx, pkt);
893  if (ret < 0 && ret != AVERROR_EOF)
894  return ret;
895  ret = cuvid_decode_packet(avctx, pkt);
897  // cuvid_is_buffer_full() should avoid this.
898  if (ret == AVERROR(EAGAIN))
900  if (ret < 0 && ret != AVERROR_EOF)
901  return ret;
902  }
903  }
904 
905  ret = CHECK_CU(ctx->cudl->cuCtxPushCurrent(cuda_ctx));
906  if (ret < 0)
907  return ret;
908 
909  if (av_fifo_read(ctx->frame_queue, &parsed_frame, 1) >= 0) {
910  const AVPixFmtDescriptor *pixdesc;
911  CUVIDPROCPARAMS params;
912  unsigned int pitch = 0;
913  int offset = 0;
914  int i;
915 
916  memset(&params, 0, sizeof(params));
917  params.progressive_frame = parsed_frame.dispinfo.progressive_frame;
918  params.second_field = parsed_frame.second_field;
919  params.top_field_first = parsed_frame.dispinfo.top_field_first;
920 
921 #ifdef NVDEC_HAVE_OPAQUE_OUTPUT_SUPPORT
922  if (avctx->pix_fmt == AV_PIX_FMT_CUARRAY) {
923  if (ctx->zero_copy) {
924  int idx = parsed_frame.dispinfo.picture_index;
925 
926  if (idx < 0 || idx >= ctx->cuarray_num_surfaces) {
927  av_log(avctx, AV_LOG_ERROR, "CUARRAY surface index %d out of range [0, %d)\n",
928  idx, ctx->cuarray_num_surfaces);
929  ret = AVERROR_BUG;
930  goto error;
931  }
932 
933  ret = ff_decode_frame_props(avctx, frame);
934  if (ret < 0) {
935  av_log(avctx, AV_LOG_ERROR, "ff_decode_frame_props failed\n");
936  goto error;
937  }
938 
939  frame->hw_frames_ctx = av_buffer_ref(ctx->hwframe);
940  if (!frame->hw_frames_ctx) {
941  ret = AVERROR(ENOMEM);
942  goto error;
943  }
944 
945  {
946  CuvidSurfaceRelease *rel = av_malloc(sizeof(*rel));
947  if (!rel) {
948  ret = AVERROR(ENOMEM);
949  goto error;
950  }
951  rel->in_use_ref = av_buffer_ref(ctx->surface_in_use_ref);
952  if (!rel->in_use_ref) {
953  av_free(rel);
954  ret = AVERROR(ENOMEM);
955  goto error;
956  }
957  rel->idx = idx;
958  atomic_store_explicit(&ctx->surface_in_use[idx], 1,
959  memory_order_release);
960  frame->buf[0] = av_buffer_create(
961  (uint8_t *)ctx->cuarray_surfaces[idx], 0,
962  cuvid_cuarray_buf_free, rel,
964  if (!frame->buf[0]) {
965  atomic_store_explicit(&ctx->surface_in_use[idx], 0,
966  memory_order_release);
967  av_buffer_unref(&rel->in_use_ref);
968  av_free(rel);
969  ret = AVERROR(ENOMEM);
970  goto error;
971  }
972  }
973 
974  frame->data[0] = (uint8_t *)ctx->cuarray_surfaces[idx];
975  frame->format = AV_PIX_FMT_CUARRAY;
976 
977  for (int p = 0; p < FF_ARRAY_ELEMS(frame->linesize); p++) {
978  CUDA_ARRAY3D_DESCRIPTOR plane_desc = { 0 };
979  CUarray plane_array;
980  int elem_size;
981  CUresult cures = ctx->cudl->cuArrayGetPlane(
982  &plane_array, ctx->cuarray_surfaces[idx], p);
983  if (cures == CUDA_ERROR_INVALID_VALUE)
984  break;
985  if (cures != CUDA_SUCCESS) {
986  ret = CHECK_CU(cures);
987  goto error;
988  }
989 
990  ret = CHECK_CU(ctx->cudl->cuArray3DGetDescriptor(
991  &plane_desc, plane_array));
992  if (ret < 0)
993  goto error;
994 
995  elem_size = ff_cuda_cuarray_elem_size(plane_desc.Format);
996  if (elem_size <= 0) {
997  av_log(avctx, AV_LOG_ERROR,
998  "Unknown CUarray element format %d on plane %d\n",
999  plane_desc.Format, p);
1000  ret = AVERROR_BUG;
1001  goto error;
1002  }
1003 
1004  frame->linesize[p] = plane_desc.Width *
1005  plane_desc.NumChannels * elem_size;
1006  }
1007  } else {
1008  int src_idx = parsed_frame.dispinfo.picture_index;
1009  AVFrame tmp_frame;
1010 
1011  if (src_idx < 0 || src_idx >= ctx->cuarray_num_surfaces) {
1012  av_log(avctx, AV_LOG_ERROR, "CUARRAY source surface index %d out of range [0, %d)\n",
1013  src_idx, ctx->cuarray_num_surfaces);
1014  ret = AVERROR_BUG;
1015  goto error;
1016  }
1017 
1018  ret = av_hwframe_get_buffer(ctx->hwframe, frame, 0);
1019  if (ret < 0) {
1020  av_log(avctx, AV_LOG_ERROR, "av_hwframe_get_buffer failed\n");
1021  goto error;
1022  }
1023 
1024  ret = ff_decode_frame_props(avctx, frame);
1025  if (ret < 0) {
1026  av_log(avctx, AV_LOG_ERROR, "ff_decode_frame_props failed\n");
1027  goto error;
1028  }
1029 
1030  memset(&tmp_frame, 0, sizeof(tmp_frame));
1031  tmp_frame.format = AV_PIX_FMT_CUARRAY;
1032  tmp_frame.data[0] = (uint8_t *)ctx->cuarray_surfaces[src_idx];
1033  tmp_frame.width = frame->width;
1034  tmp_frame.height = frame->height;
1035  tmp_frame.hw_frames_ctx = ctx->hwframe;
1036  memcpy(tmp_frame.linesize, frame->linesize, sizeof(tmp_frame.linesize));
1037 
1038  ret = av_hwframe_transfer_data(frame, &tmp_frame, 0);
1039  if (ret < 0) {
1040  av_log(avctx, AV_LOG_ERROR, "CUARRAY transfer failed\n");
1041  goto error;
1042  }
1043  }
1044  } else
1045 #endif
1046  {
1047  ret = CHECK_CU(ctx->cvdl->cuvidMapVideoFrame(ctx->cudecoder, parsed_frame.dispinfo.picture_index, &mapped_frame, &pitch, &params));
1048  if (ret < 0)
1049  goto error;
1050 
1051  if (avctx->pix_fmt == AV_PIX_FMT_CUDA) {
1052  ret = av_hwframe_get_buffer(ctx->hwframe, frame, 0);
1053  if (ret < 0) {
1054  av_log(avctx, AV_LOG_ERROR, "av_hwframe_get_buffer failed\n");
1055  goto error;
1056  }
1057 
1058  ret = ff_decode_frame_props(avctx, frame);
1059  if (ret < 0) {
1060  av_log(avctx, AV_LOG_ERROR, "ff_decode_frame_props failed\n");
1061  goto error;
1062  }
1063 
1064  pixdesc = av_pix_fmt_desc_get(avctx->sw_pix_fmt);
1065 
1066  for (i = 0; i < pixdesc->nb_components; i++) {
1067  int height = avctx->height >> (i ? pixdesc->log2_chroma_h : 0);
1068  CUDA_MEMCPY2D cpy = {
1069  .srcMemoryType = CU_MEMORYTYPE_DEVICE,
1070  .dstMemoryType = CU_MEMORYTYPE_DEVICE,
1071  .srcDevice = mapped_frame,
1072  .dstDevice = (CUdeviceptr)frame->data[i],
1073  .srcPitch = pitch,
1074  .dstPitch = frame->linesize[i],
1075  .srcY = offset,
1076  .WidthInBytes = FFMIN(pitch, frame->linesize[i]),
1077  .Height = height,
1078  };
1079 
1080  ret = CHECK_CU(ctx->cudl->cuMemcpy2DAsync(&cpy, device_hwctx->stream));
1081  if (ret < 0)
1082  goto error;
1083 
1084  offset += height;
1085  }
1086  } else if (avctx->pix_fmt == AV_PIX_FMT_NV12 ||
1087  avctx->pix_fmt == AV_PIX_FMT_P010 ||
1088  avctx->pix_fmt == AV_PIX_FMT_P012 ||
1089  avctx->pix_fmt == AV_PIX_FMT_P016 ||
1090 #ifdef NVDEC_HAVE_422_SUPPORT
1091  avctx->pix_fmt == AV_PIX_FMT_NV16 ||
1092  avctx->pix_fmt == AV_PIX_FMT_P210 ||
1093  avctx->pix_fmt == AV_PIX_FMT_P212 ||
1094  avctx->pix_fmt == AV_PIX_FMT_P216 ||
1095 #endif
1096  avctx->pix_fmt == AV_PIX_FMT_YUV444P ||
1097  avctx->pix_fmt == AV_PIX_FMT_YUV444P10MSB ||
1098  avctx->pix_fmt == AV_PIX_FMT_YUV444P12MSB ||
1099  avctx->pix_fmt == AV_PIX_FMT_YUV444P16) {
1100  unsigned int offset = 0;
1101  AVFrame *tmp_frame = av_frame_alloc();
1102  if (!tmp_frame) {
1103  av_log(avctx, AV_LOG_ERROR, "av_frame_alloc failed\n");
1104  ret = AVERROR(ENOMEM);
1105  goto error;
1106  }
1107 
1108  pixdesc = av_pix_fmt_desc_get(avctx->sw_pix_fmt);
1109 
1110  tmp_frame->format = AV_PIX_FMT_CUDA;
1111  tmp_frame->hw_frames_ctx = av_buffer_ref(ctx->hwframe);
1112  if (!tmp_frame->hw_frames_ctx) {
1113  ret = AVERROR(ENOMEM);
1114  av_frame_free(&tmp_frame);
1115  goto error;
1116  }
1117 
1118  tmp_frame->width = avctx->width;
1119  tmp_frame->height = avctx->height;
1120 
1121  /*
1122  * Note that the following logic would not work for three plane
1123  * YUV420 because the pitch value is different for the chroma
1124  * planes.
1125  */
1126  for (i = 0; i < pixdesc->nb_components; i++) {
1127  tmp_frame->data[i] = (uint8_t*)mapped_frame + offset;
1128  tmp_frame->linesize[i] = pitch;
1129  offset += pitch * (avctx->height >> (i ? pixdesc->log2_chroma_h : 0));
1130  }
1131 
1132  ret = ff_get_buffer(avctx, frame, 0);
1133  if (ret < 0) {
1134  av_log(avctx, AV_LOG_ERROR, "ff_get_buffer failed\n");
1135  av_frame_free(&tmp_frame);
1136  goto error;
1137  }
1138 
1139  ret = av_hwframe_transfer_data(frame, tmp_frame, 0);
1140  if (ret) {
1141  av_log(avctx, AV_LOG_ERROR, "av_hwframe_transfer_data failed\n");
1142  av_frame_free(&tmp_frame);
1143  goto error;
1144  }
1145  av_frame_free(&tmp_frame);
1146  } else {
1147  ret = AVERROR_BUG;
1148  goto error;
1149  }
1150  }
1151 
1152  if (ctx->key_frame[parsed_frame.dispinfo.picture_index])
1153  frame->flags |= AV_FRAME_FLAG_KEY;
1154  else
1155  frame->flags &= ~AV_FRAME_FLAG_KEY;
1156  ctx->key_frame[parsed_frame.dispinfo.picture_index] = 0;
1157 
1158  frame->width = avctx->width;
1159  frame->height = avctx->height;
1160  if (avctx->pkt_timebase.num && avctx->pkt_timebase.den)
1161  frame->pts = av_rescale_q(parsed_frame.dispinfo.timestamp, (AVRational){1, 10000000}, avctx->pkt_timebase);
1162  else
1163  frame->pts = parsed_frame.dispinfo.timestamp;
1164 
1165  if (parsed_frame.second_field) {
1166  if (ctx->prev_pts == INT64_MIN) {
1167  ctx->prev_pts = frame->pts;
1168  frame->pts += (avctx->pkt_timebase.den * avctx->framerate.den) / (avctx->pkt_timebase.num * avctx->framerate.num);
1169  } else {
1170  int pts_diff = (frame->pts - ctx->prev_pts) / 2;
1171  ctx->prev_pts = frame->pts;
1172  frame->pts += pts_diff;
1173  }
1174  }
1175 
1176  /* CUVIDs opaque reordering breaks the internal pkt logic.
1177  * So set pkt_pts and clear all the other pkt_ fields.
1178  */
1179  frame->duration = 0;
1180 
1181  if (!parsed_frame.is_deinterlacing && !parsed_frame.dispinfo.progressive_frame)
1182  frame->flags |= AV_FRAME_FLAG_INTERLACED;
1183 
1184  if ((frame->flags & AV_FRAME_FLAG_INTERLACED) && parsed_frame.dispinfo.top_field_first)
1186  } else if (ctx->decoder_flushing ||
1187  atomic_load_explicit(&ctx->abort_decode, memory_order_acquire)) {
1188  ret = AVERROR_EOF;
1189  } else {
1190  ret = AVERROR(EAGAIN);
1191  }
1192 
1193 error:
1194  if (ret < 0)
1196 
1197  if (mapped_frame)
1198  eret = CHECK_CU(ctx->cvdl->cuvidUnmapVideoFrame(ctx->cudecoder, mapped_frame));
1199 
1200  eret = CHECK_CU(ctx->cudl->cuCtxPopCurrent(&dummy));
1201 
1202  if (eret < 0)
1203  return eret;
1204  else
1205  return ret;
1206 }
1207 
1209 {
1210  CuvidContext *ctx = avctx->priv_data;
1211  AVHWDeviceContext *device_ctx = ctx->hwdevice ? (AVHWDeviceContext *)ctx->hwdevice->data : NULL;
1212  AVCUDADeviceContext *device_hwctx = device_ctx ? device_ctx->hwctx : NULL;
1213  CUcontext dummy, cuda_ctx = device_hwctx ? device_hwctx->cuda_ctx : NULL;
1214 
1215  atomic_store_explicit(&ctx->abort_decode, 1, memory_order_release);
1216 
1217  av_fifo_freep2(&ctx->frame_queue);
1218 
1219  if (cuda_ctx) {
1220  ctx->cudl->cuCtxPushCurrent(cuda_ctx);
1221 
1222 #ifdef NVDEC_HAVE_OPAQUE_OUTPUT_SUPPORT
1223  if (ctx->opaque_output)
1224  ctx->cudl->cuCtxSynchronize();
1225 #endif
1226 
1227  if (ctx->cuparser)
1228  ctx->cvdl->cuvidDestroyVideoParser(ctx->cuparser);
1229 #ifdef NVDEC_HAVE_OPAQUE_OUTPUT_SUPPORT
1230  if (ctx->decoder_cleanup) {
1231  ctx->decoder_cleanup->hwdevice = av_buffer_ref(ctx->hwdevice);
1232  ctx->decoder_cleanup->cvdl = ctx->cvdl;
1233  ctx->cvdl = NULL;
1234  ctx->cudecoder = NULL;
1235  ctx->cuarray_surfaces = NULL;
1236  ctx->cuarray_num_surfaces = 0;
1237  av_buffer_unref(&ctx->surface_in_use_ref);
1238  ctx->surface_in_use = NULL;
1239  ctx->decoder_cleanup = NULL;
1240  } else
1241 #endif
1242  {
1243  if (ctx->cudecoder)
1244  ctx->cvdl->cuvidDestroyDecoder(ctx->cudecoder);
1245 
1246 #ifdef NVDEC_HAVE_OPAQUE_OUTPUT_SUPPORT
1247  if (ctx->cuarray_surfaces) {
1248  for (int i = 0; i < ctx->cuarray_num_surfaces; i++)
1249  ctx->cudl->cuArrayDestroy(ctx->cuarray_surfaces[i]);
1250  av_freep(&ctx->cuarray_surfaces);
1251  av_buffer_unref(&ctx->surface_in_use_ref);
1252  ctx->surface_in_use = NULL;
1253  ctx->cuarray_num_surfaces = 0;
1254  }
1255 #endif
1256  }
1257 
1258  ctx->cudl->cuCtxPopCurrent(&dummy);
1259  }
1260 
1261  ctx->cudl = NULL;
1262 
1263  av_buffer_unref(&ctx->hwframe);
1264  av_buffer_unref(&ctx->hwdevice);
1265 
1266  av_freep(&ctx->key_frame);
1267  av_freep(&ctx->cuparse_ext);
1268 
1269  cuvid_free_functions(&ctx->cvdl);
1270 
1271  return 0;
1272 }
1273 
1275  const CUVIDPARSERPARAMS *cuparseinfo,
1276  int probed_width,
1277  int probed_height,
1278  int bit_depth, int is_yuv422, int is_yuv444)
1279 {
1280  CuvidContext *ctx = avctx->priv_data;
1281  CUVIDDECODECAPS *caps;
1282  int res8 = 0, res10 = 0, res12 = 0;
1283 
1284  if (!ctx->cvdl->cuvidGetDecoderCaps) {
1285  av_log(avctx, AV_LOG_WARNING, "Used Nvidia driver is too old to perform a capability check.\n");
1286  av_log(avctx, AV_LOG_WARNING, "The minimum required version is "
1287 #if defined(_WIN32) || defined(__CYGWIN__)
1288  "378.66"
1289 #else
1290  "378.13"
1291 #endif
1292  ". Continuing blind.\n");
1293  ctx->caps8.bIsSupported = ctx->caps10.bIsSupported = 1;
1294  // 12 bit was not supported before the capability check was introduced, so disable it.
1295  ctx->caps12.bIsSupported = 0;
1296  return 0;
1297  }
1298 
1299  ctx->caps8.eCodecType = ctx->caps10.eCodecType = ctx->caps12.eCodecType
1300  = cuparseinfo->CodecType;
1301 
1302  ctx->caps8.eChromaFormat = ctx->caps10.eChromaFormat = ctx->caps12.eChromaFormat
1303  = is_yuv444 ? cudaVideoChromaFormat_444 :
1304 #ifdef NVDEC_HAVE_422_SUPPORT
1305  (is_yuv422 ? cudaVideoChromaFormat_422 : cudaVideoChromaFormat_420);
1306 #else
1307  cudaVideoChromaFormat_420;
1308 #endif
1309 
1310  ctx->caps8.nBitDepthMinus8 = 0;
1311  ctx->caps10.nBitDepthMinus8 = 2;
1312  ctx->caps12.nBitDepthMinus8 = 4;
1313 
1314  res8 = CHECK_CU(ctx->cvdl->cuvidGetDecoderCaps(&ctx->caps8));
1315  res10 = CHECK_CU(ctx->cvdl->cuvidGetDecoderCaps(&ctx->caps10));
1316  res12 = CHECK_CU(ctx->cvdl->cuvidGetDecoderCaps(&ctx->caps12));
1317 
1318  av_log(avctx, AV_LOG_VERBOSE, "CUVID capabilities for %s:\n", avctx->codec->name);
1319  av_log(avctx, AV_LOG_VERBOSE, "8 bit: supported: %d, min_width: %d, max_width: %d, min_height: %d, max_height: %d\n",
1320  ctx->caps8.bIsSupported, ctx->caps8.nMinWidth, ctx->caps8.nMaxWidth, ctx->caps8.nMinHeight, ctx->caps8.nMaxHeight);
1321  av_log(avctx, AV_LOG_VERBOSE, "10 bit: supported: %d, min_width: %d, max_width: %d, min_height: %d, max_height: %d\n",
1322  ctx->caps10.bIsSupported, ctx->caps10.nMinWidth, ctx->caps10.nMaxWidth, ctx->caps10.nMinHeight, ctx->caps10.nMaxHeight);
1323  av_log(avctx, AV_LOG_VERBOSE, "12 bit: supported: %d, min_width: %d, max_width: %d, min_height: %d, max_height: %d\n",
1324  ctx->caps12.bIsSupported, ctx->caps12.nMinWidth, ctx->caps12.nMaxWidth, ctx->caps12.nMinHeight, ctx->caps12.nMaxHeight);
1325 
1326  switch (bit_depth) {
1327  case 10:
1328  caps = &ctx->caps10;
1329  if (res10 < 0)
1330  return res10;
1331  break;
1332  case 12:
1333  caps = &ctx->caps12;
1334  if (res12 < 0)
1335  return res12;
1336  break;
1337  default:
1338  caps = &ctx->caps8;
1339  if (res8 < 0)
1340  return res8;
1341  }
1342 
1343  if (!ctx->caps8.bIsSupported) {
1344  av_log(avctx, AV_LOG_ERROR, "Codec %s is not supported with this chroma format.\n", avctx->codec->name);
1345  return AVERROR(EINVAL);
1346  }
1347 
1348  if (!caps->bIsSupported) {
1349  av_log(avctx, AV_LOG_ERROR, "Bit depth %d with this chroma format is not supported.\n", bit_depth);
1350  return AVERROR(EINVAL);
1351  }
1352 
1353  if (probed_width > caps->nMaxWidth || probed_width < caps->nMinWidth) {
1354  av_log(avctx, AV_LOG_ERROR, "Video width %d not within range from %d to %d\n",
1355  probed_width, caps->nMinWidth, caps->nMaxWidth);
1356  return AVERROR(EINVAL);
1357  }
1358 
1359  if (probed_height > caps->nMaxHeight || probed_height < caps->nMinHeight) {
1360  av_log(avctx, AV_LOG_ERROR, "Video height %d not within range from %d to %d\n",
1361  probed_height, caps->nMinHeight, caps->nMaxHeight);
1362  return AVERROR(EINVAL);
1363  }
1364 
1365  if ((probed_width * probed_height) / 256 > caps->nMaxMBCount) {
1366  av_log(avctx, AV_LOG_ERROR, "Video macroblock count %d exceeds maximum of %d\n",
1367  (int)(probed_width * probed_height) / 256, caps->nMaxMBCount);
1368  return AVERROR(EINVAL);
1369  }
1370 
1371  return 0;
1372 }
1373 
1375 {
1376  CuvidContext *ctx = avctx->priv_data;
1377  AVCUDADeviceContext *device_hwctx;
1378  AVHWDeviceContext *device_ctx;
1379  AVHWFramesContext *hwframe_ctx;
1380  CUVIDSOURCEDATAPACKET seq_pkt;
1381  CUcontext cuda_ctx = NULL;
1382  CUcontext dummy;
1383  uint8_t *extradata;
1384  int extradata_size;
1385  int ret = 0;
1386  enum AVPixelFormat requested_hw_format;
1387 
1388  enum AVPixelFormat pix_fmts[4];
1389 
1390  int probed_width = avctx->coded_width ? avctx->coded_width : 1280;
1391  int probed_height = avctx->coded_height ? avctx->coded_height : 720;
1392  int probed_bit_depth = 8, is_yuv444 = 0, is_yuv422 = 0;
1393 
1394  const AVPixFmtDescriptor *probe_desc = av_pix_fmt_desc_get(avctx->pix_fmt);
1395  if (probe_desc && probe_desc->nb_components)
1396  probed_bit_depth = probe_desc->comp[0].depth;
1397 
1398  if (probe_desc && probe_desc->nb_components > 1 && !probe_desc->log2_chroma_w && !probe_desc->log2_chroma_h)
1399  is_yuv444 = 1;
1400 
1401 #ifdef NVDEC_HAVE_422_SUPPORT
1402  if (probe_desc && probe_desc->log2_chroma_w && !probe_desc->log2_chroma_h)
1403  is_yuv422 = 1;
1404 #endif
1405 
1406  ret = cuvid_get_requested_hw_format(avctx, ctx, &requested_hw_format);
1407  if (ret < 0)
1408  return ret;
1409 
1410  // Pick pixel format based on bit depth and chroma sampling.
1411  switch (probed_bit_depth) {
1412  case 10:
1413  pix_fmts[1] = is_yuv444 ? AV_PIX_FMT_YUV444P10MSB : (is_yuv422 ? AV_PIX_FMT_P210 : AV_PIX_FMT_P010);
1414  break;
1415  case 12:
1416  pix_fmts[1] = is_yuv444 ? AV_PIX_FMT_YUV444P12MSB : (is_yuv422 ? AV_PIX_FMT_P212 : AV_PIX_FMT_P012);
1417  break;
1418  default:
1419  pix_fmts[1] = is_yuv444 ? AV_PIX_FMT_YUV444P : (is_yuv422 ? AV_PIX_FMT_NV16 : AV_PIX_FMT_NV12);
1420  break;
1421  }
1422 
1423  ctx->pkt = avctx->internal->in_pkt;
1424  // Accelerated transcoding scenarios with 'ffmpeg' require that the
1425  // requested hardware pix_fmt be set early. The sw_pix_fmt, and the
1426  // pix_fmt for non-accelerated transcoding, do not need to be correct
1427  // but need to be set to something.
1428  cuvid_prepare_format_list(pix_fmts, requested_hw_format, pix_fmts[1]);
1429 
1430  ret = ff_get_format(avctx, pix_fmts);
1431  if (ret < 0) {
1432  av_log(avctx, AV_LOG_ERROR, "ff_get_format failed: %d\n", ret);
1433  return ret;
1434  }
1435 
1436  if (ret != AV_PIX_FMT_CUDA && ret != AV_PIX_FMT_CUARRAY) {
1437  av_log(avctx, AV_LOG_VERBOSE,
1438  "ff_get_format returned %s, overriding to %s\n",
1440  av_get_pix_fmt_name(requested_hw_format));
1441  ret = requested_hw_format;
1442  }
1443 
1444  ctx->opaque_output = (ret == AV_PIX_FMT_CUARRAY);
1445  avctx->pix_fmt = ret;
1446 
1447  if (ctx->opaque_output) {
1448  switch (avctx->sw_pix_fmt) {
1449  case AV_PIX_FMT_YUV444P: avctx->sw_pix_fmt = AV_PIX_FMT_NV24; break;
1450  case AV_PIX_FMT_YUV444P10MSB: avctx->sw_pix_fmt = AV_PIX_FMT_P410; break;
1451  case AV_PIX_FMT_YUV444P12MSB: avctx->sw_pix_fmt = AV_PIX_FMT_P412; break;
1452  default: break;
1453  }
1454  }
1455 
1456  if (ctx->resize_expr && sscanf(ctx->resize_expr, "%dx%d",
1457  &ctx->resize.width, &ctx->resize.height) != 2) {
1458  av_log(avctx, AV_LOG_ERROR, "Invalid resize expressions\n");
1459  ret = AVERROR(EINVAL);
1460  goto error;
1461  }
1462 
1463  if (ctx->crop_expr && sscanf(ctx->crop_expr, "%dx%dx%dx%d",
1464  &ctx->crop.top, &ctx->crop.bottom,
1465  &ctx->crop.left, &ctx->crop.right) != 4) {
1466  av_log(avctx, AV_LOG_ERROR, "Invalid cropping expressions\n");
1467  ret = AVERROR(EINVAL);
1468  goto error;
1469  }
1470 
1471  if (ctx->opaque_output) {
1472  if (ctx->crop_expr) {
1473  av_log(avctx, AV_LOG_WARNING,
1474  "Cropping is not supported with cuarray output; "
1475  "crop option will be ignored\n");
1476  memset(&ctx->crop, 0, sizeof(ctx->crop));
1477  }
1478  if (ctx->resize_expr) {
1479  av_log(avctx, AV_LOG_WARNING,
1480  "Resizing is not supported with cuarray output; "
1481  "resize option will be ignored\n");
1482  av_freep(&ctx->resize_expr);
1483  }
1484  if (ctx->deint_mode != cudaVideoDeinterlaceMode_Weave) {
1485  av_log(avctx, AV_LOG_WARNING,
1486  "Deinterlacing is not supported with cuarray output; "
1487  "deint mode will be forced to weave\n");
1488  ctx->deint_mode = cudaVideoDeinterlaceMode_Weave;
1489  }
1490  }
1491 
1492  ret = cuvid_load_functions(&ctx->cvdl, avctx);
1493  if (ret < 0) {
1494  av_log(avctx, AV_LOG_ERROR, "Failed loading nvcuvid.\n");
1495  goto error;
1496  }
1497 
1498  // respect the deprecated "surfaces" option if non-default value is given by user;
1499  if(ctx->nb_surfaces < 0)
1500  ctx->nb_surfaces = CUVID_DEFAULT_NUM_SURFACES;
1501 
1502  ctx->frame_queue = av_fifo_alloc2(ctx->nb_surfaces, sizeof(CuvidParsedFrame), 0);
1503  if (!ctx->frame_queue) {
1504  ret = AVERROR(ENOMEM);
1505  goto error;
1506  }
1507 
1508  if (avctx->hw_frames_ctx) {
1509  ctx->hwframe = av_buffer_ref(avctx->hw_frames_ctx);
1510  if (!ctx->hwframe) {
1511  ret = AVERROR(ENOMEM);
1512  goto error;
1513  }
1514 
1515  hwframe_ctx = (AVHWFramesContext*)ctx->hwframe->data;
1516 
1517  ctx->hwdevice = av_buffer_ref(hwframe_ctx->device_ref);
1518  if (!ctx->hwdevice) {
1519  ret = AVERROR(ENOMEM);
1520  goto error;
1521  }
1522  } else {
1523  if (avctx->hw_device_ctx) {
1524  ctx->hwdevice = av_buffer_ref(avctx->hw_device_ctx);
1525  if (!ctx->hwdevice) {
1526  ret = AVERROR(ENOMEM);
1527  goto error;
1528  }
1529  } else {
1530  ret = av_hwdevice_ctx_create(&ctx->hwdevice, AV_HWDEVICE_TYPE_CUDA, ctx->cu_gpu, NULL, 0);
1531  if (ret < 0)
1532  goto error;
1533  }
1534 
1535  ctx->hwframe = av_hwframe_ctx_alloc(ctx->hwdevice);
1536  if (!ctx->hwframe) {
1537  av_log(avctx, AV_LOG_ERROR, "av_hwframe_ctx_alloc failed\n");
1538  ret = AVERROR(ENOMEM);
1539  goto error;
1540  }
1541 
1542  hwframe_ctx = (AVHWFramesContext*)ctx->hwframe->data;
1543  }
1544 
1545  device_ctx = hwframe_ctx->device_ctx;
1546  device_hwctx = device_ctx->hwctx;
1547 
1548  cuda_ctx = device_hwctx->cuda_ctx;
1549  ctx->cudl = device_hwctx->internal->cuda_dl;
1550 
1551  ctx->cuda_stream = device_hwctx->stream;
1552 
1553  memset(&ctx->cuparseinfo, 0, sizeof(ctx->cuparseinfo));
1554  memset(&seq_pkt, 0, sizeof(seq_pkt));
1555 
1556  switch (avctx->codec->id) {
1557 #if CONFIG_H264_CUVID_DECODER
1558  case AV_CODEC_ID_H264:
1559  ctx->cuparseinfo.CodecType = cudaVideoCodec_H264;
1560  break;
1561 #endif
1562 #if CONFIG_HEVC_CUVID_DECODER
1563  case AV_CODEC_ID_HEVC:
1564  ctx->cuparseinfo.CodecType = cudaVideoCodec_HEVC;
1565  break;
1566 #endif
1567 #if CONFIG_MJPEG_CUVID_DECODER
1568  case AV_CODEC_ID_MJPEG:
1569  ctx->cuparseinfo.CodecType = cudaVideoCodec_JPEG;
1570  break;
1571 #endif
1572 #if CONFIG_MPEG1_CUVID_DECODER
1574  ctx->cuparseinfo.CodecType = cudaVideoCodec_MPEG1;
1575  break;
1576 #endif
1577 #if CONFIG_MPEG2_CUVID_DECODER
1579  ctx->cuparseinfo.CodecType = cudaVideoCodec_MPEG2;
1580  break;
1581 #endif
1582 #if CONFIG_MPEG4_CUVID_DECODER
1583  case AV_CODEC_ID_MPEG4:
1584  ctx->cuparseinfo.CodecType = cudaVideoCodec_MPEG4;
1585  break;
1586 #endif
1587 #if CONFIG_VP8_CUVID_DECODER
1588  case AV_CODEC_ID_VP8:
1589  ctx->cuparseinfo.CodecType = cudaVideoCodec_VP8;
1590  break;
1591 #endif
1592 #if CONFIG_VP9_CUVID_DECODER
1593  case AV_CODEC_ID_VP9:
1594  ctx->cuparseinfo.CodecType = cudaVideoCodec_VP9;
1595  break;
1596 #endif
1597 #if CONFIG_VC1_CUVID_DECODER
1598  case AV_CODEC_ID_VC1:
1599  ctx->cuparseinfo.CodecType = cudaVideoCodec_VC1;
1600  break;
1601 #endif
1602 #if CONFIG_AV1_CUVID_DECODER && defined(CUVID_HAS_AV1_SUPPORT)
1603  case AV_CODEC_ID_AV1:
1604  ctx->cuparseinfo.CodecType = cudaVideoCodec_AV1;
1605  break;
1606 #endif
1607  default:
1608  av_log(avctx, AV_LOG_ERROR, "Invalid CUVID codec!\n");
1609  return AVERROR_BUG;
1610  }
1611 
1612  if (ffcodec(avctx->codec)->bsfs) {
1613  const AVCodecParameters *par = avctx->internal->bsf->par_out;
1614  extradata = par->extradata;
1615  extradata_size = par->extradata_size;
1616  } else {
1617  extradata = avctx->extradata;
1618  extradata_size = avctx->extradata_size;
1619  }
1620 
1621  // Check first bit to determine whether it's AV1CodecConfigurationRecord.
1622  // Skip first 4 bytes of AV1CodecConfigurationRecord to keep configOBUs
1623  // only, otherwise cuvidParseVideoData report unknown error.
1624  if (avctx->codec->id == AV_CODEC_ID_AV1 &&
1625  extradata_size >= 4 &&
1626  extradata[0] & 0x80) {
1627  extradata += 4;
1628  extradata_size -= 4;
1629  }
1630 
1631  ctx->cuparse_ext = av_mallocz(sizeof(*ctx->cuparse_ext)
1632  + FFMAX(extradata_size - (int)sizeof(ctx->cuparse_ext->raw_seqhdr_data), 0));
1633  if (!ctx->cuparse_ext) {
1634  ret = AVERROR(ENOMEM);
1635  goto error;
1636  }
1637 
1638  if (extradata_size > 0)
1639  memcpy(ctx->cuparse_ext->raw_seqhdr_data, extradata, extradata_size);
1640  ctx->cuparse_ext->format.seqhdr_data_length = extradata_size;
1641 
1642  ctx->cuparseinfo.pExtVideoInfo = ctx->cuparse_ext;
1643 
1644  ctx->key_frame = av_mallocz(ctx->nb_surfaces * sizeof(int));
1645  if (!ctx->key_frame) {
1646  ret = AVERROR(ENOMEM);
1647  goto error;
1648  }
1649 
1650  ctx->cuparseinfo.ulMaxNumDecodeSurfaces = 1;
1651  ctx->cuparseinfo.ulMaxDisplayDelay = (avctx->flags & AV_CODEC_FLAG_LOW_DELAY) ? 0 : CUVID_MAX_DISPLAY_DELAY;
1652  ctx->cuparseinfo.pUserData = avctx;
1653  ctx->cuparseinfo.pfnSequenceCallback = cuvid_handle_video_sequence;
1654  ctx->cuparseinfo.pfnDecodePicture = cuvid_handle_picture_decode;
1655  ctx->cuparseinfo.pfnDisplayPicture = cuvid_handle_picture_display;
1656 
1657  ret = CHECK_CU(ctx->cudl->cuCtxPushCurrent(cuda_ctx));
1658  if (ret < 0)
1659  goto error;
1660 
1661  ret = cuvid_test_capabilities(avctx, &ctx->cuparseinfo,
1662  probed_width,
1663  probed_height,
1664  probed_bit_depth, is_yuv422, is_yuv444);
1665  if (ret < 0)
1666  goto error;
1667 
1668  ret = CHECK_CU(ctx->cvdl->cuvidCreateVideoParser(&ctx->cuparser, &ctx->cuparseinfo));
1669  if (ret < 0)
1670  goto error;
1671 
1672  seq_pkt.payload = ctx->cuparse_ext->raw_seqhdr_data;
1673  seq_pkt.payload_size = ctx->cuparse_ext->format.seqhdr_data_length;
1674 
1675  if (seq_pkt.payload && seq_pkt.payload_size) {
1676  ret = CHECK_CU(ctx->cvdl->cuvidParseVideoData(ctx->cuparser, &seq_pkt));
1677  if (ret < 0)
1678  goto error;
1679  }
1680 
1681  ret = CHECK_CU(ctx->cudl->cuCtxPopCurrent(&dummy));
1682  if (ret < 0)
1683  goto error;
1684 
1685  ctx->prev_pts = INT64_MIN;
1686 
1687  if (!avctx->pkt_timebase.num || !avctx->pkt_timebase.den)
1688  av_log(avctx, AV_LOG_WARNING, "Invalid pkt_timebase, passing timestamps as-is.\n");
1689 
1690  return 0;
1691 
1692 error:
1693  cuvid_decode_end(avctx);
1694  return ret;
1695 }
1696 
1697 static void cuvid_flush(AVCodecContext *avctx)
1698 {
1699  CuvidContext *ctx = avctx->priv_data;
1700  AVHWDeviceContext *device_ctx = (AVHWDeviceContext*)ctx->hwdevice->data;
1701  AVCUDADeviceContext *device_hwctx = device_ctx->hwctx;
1702  CUcontext dummy, cuda_ctx = device_hwctx->cuda_ctx;
1703  CUVIDSOURCEDATAPACKET seq_pkt = { 0 };
1704  int ret;
1705 
1706  ret = CHECK_CU(ctx->cudl->cuCtxPushCurrent(cuda_ctx));
1707  if (ret < 0)
1708  goto error;
1709 
1710  av_fifo_reset2(ctx->frame_queue);
1711 
1712  if (ctx->cudecoder) {
1713  ctx->cvdl->cuvidDestroyDecoder(ctx->cudecoder);
1714  ctx->cudecoder = NULL;
1715  }
1716 
1717  if (ctx->cuparser) {
1718  ctx->cvdl->cuvidDestroyVideoParser(ctx->cuparser);
1719  ctx->cuparser = NULL;
1720  }
1721 
1722  ret = CHECK_CU(ctx->cvdl->cuvidCreateVideoParser(&ctx->cuparser, &ctx->cuparseinfo));
1723  if (ret < 0)
1724  goto error;
1725 
1726  seq_pkt.payload = ctx->cuparse_ext->raw_seqhdr_data;
1727  seq_pkt.payload_size = ctx->cuparse_ext->format.seqhdr_data_length;
1728 
1729  if (seq_pkt.payload && seq_pkt.payload_size) {
1730  ret = CHECK_CU(ctx->cvdl->cuvidParseVideoData(ctx->cuparser, &seq_pkt));
1731  if (ret < 0)
1732  goto error;
1733  }
1734 
1735  ret = CHECK_CU(ctx->cudl->cuCtxPopCurrent(&dummy));
1736  if (ret < 0)
1737  goto error;
1738 
1739  ctx->prev_pts = INT64_MIN;
1740  ctx->decoder_flushing = 0;
1741 
1742  return;
1743  error:
1744  av_log(avctx, AV_LOG_ERROR, "CUDA reinit on flush failed\n");
1745 }
1746 
1747 #define OFFSET(x) offsetof(CuvidContext, x)
1748 #define VD AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM
1749 static const AVOption options[] = {
1750  { "deint", "Set deinterlacing mode", OFFSET(deint_mode), AV_OPT_TYPE_INT, { .i64 = cudaVideoDeinterlaceMode_Weave }, cudaVideoDeinterlaceMode_Weave, cudaVideoDeinterlaceMode_Adaptive, VD, .unit = "deint" },
1751  { "weave", "Weave deinterlacing (do nothing)", 0, AV_OPT_TYPE_CONST, { .i64 = cudaVideoDeinterlaceMode_Weave }, 0, 0, VD, .unit = "deint" },
1752  { "bob", "Bob deinterlacing", 0, AV_OPT_TYPE_CONST, { .i64 = cudaVideoDeinterlaceMode_Bob }, 0, 0, VD, .unit = "deint" },
1753  { "adaptive", "Adaptive deinterlacing", 0, AV_OPT_TYPE_CONST, { .i64 = cudaVideoDeinterlaceMode_Adaptive }, 0, 0, VD, .unit = "deint" },
1754  { "gpu", "GPU to be used for decoding", OFFSET(cu_gpu), AV_OPT_TYPE_STRING, { .str = NULL }, 0, 0, VD },
1755  { "surfaces", "Maximum surfaces to be used for decoding", OFFSET(nb_surfaces), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, INT_MAX, VD | AV_OPT_FLAG_DEPRECATED },
1756  { "drop_second_field", "Drop second field when deinterlacing", OFFSET(drop_second_field), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, VD },
1757  { "crop", "Crop (top)x(bottom)x(left)x(right)", OFFSET(crop_expr), AV_OPT_TYPE_STRING, { .str = NULL }, 0, 0, VD },
1758  { "resize", "Resize (width)x(height)", OFFSET(resize_expr), AV_OPT_TYPE_STRING, { .str = NULL }, 0, 0, VD },
1759  { "output_format", "Hardware output format", OFFSET(output_format), AV_OPT_TYPE_INT, { .i64 = AV_PIX_FMT_CUDA }, 0, INT_MAX, VD, .unit = "output_format" },
1760  { "cuda", "CUDA pitch-linear output", 0, AV_OPT_TYPE_CONST, { .i64 = AV_PIX_FMT_CUDA }, 0, 0, VD, .unit = "output_format" },
1761 #ifdef NVDEC_HAVE_OPAQUE_OUTPUT_SUPPORT
1762  { "cuarray", "CUDA block-linear opaque output", 0, AV_OPT_TYPE_CONST, { .i64 = AV_PIX_FMT_CUARRAY }, 0, 0, VD, .unit = "output_format" },
1763  { "zero_copy", "Enable zero-copy opaque decode output (forces output_format=cuarray)", OFFSET(zero_copy), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, VD },
1764 #endif
1765  { NULL }
1766 };
1767 
1769  &(const AVCodecHWConfigInternal) {
1770  .public = {
1775  .device_type = AV_HWDEVICE_TYPE_CUDA
1776  },
1777  .hwaccel = NULL,
1778  },
1779 #ifdef NVDEC_HAVE_OPAQUE_OUTPUT_SUPPORT
1780  &(const AVCodecHWConfigInternal) {
1781  .public = {
1782  .pix_fmt = AV_PIX_FMT_CUARRAY,
1786  .device_type = AV_HWDEVICE_TYPE_CUDA
1787  },
1788  .hwaccel = NULL,
1789  },
1790 #endif
1791  NULL
1792 };
1793 
1794 #define DEFINE_CUVID_CODEC(x, X, bsf_name) \
1795  static const AVClass x##_cuvid_class = { \
1796  .class_name = #x "_cuvid", \
1797  .item_name = av_default_item_name, \
1798  .option = options, \
1799  .version = LIBAVUTIL_VERSION_INT, \
1800  }; \
1801  const FFCodec ff_##x##_cuvid_decoder = { \
1802  .p.name = #x "_cuvid", \
1803  CODEC_LONG_NAME("Nvidia CUVID " #X " decoder"), \
1804  .p.type = AVMEDIA_TYPE_VIDEO, \
1805  .p.id = AV_CODEC_ID_##X, \
1806  .priv_data_size = sizeof(CuvidContext), \
1807  .p.priv_class = &x##_cuvid_class, \
1808  .init = cuvid_decode_init, \
1809  .close = cuvid_decode_end, \
1810  FF_CODEC_RECEIVE_FRAME_CB(cuvid_output_frame), \
1811  .flush = cuvid_flush, \
1812  .bsfs = bsf_name, \
1813  .p.capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_AVOID_PROBING | AV_CODEC_CAP_HARDWARE, \
1814  .caps_internal = FF_CODEC_CAP_NOT_INIT_THREADSAFE | \
1815  FF_CODEC_CAP_SETS_FRAME_PROPS, \
1816  .hw_configs = cuvid_hw_configs, \
1817  .p.wrapper_name = "cuvid", \
1818  };
1819 
1820 #if CONFIG_AV1_CUVID_DECODER && defined(CUVID_HAS_AV1_SUPPORT)
1821 DEFINE_CUVID_CODEC(av1, AV1, NULL)
1822 #endif
1823 
1824 #if CONFIG_HEVC_CUVID_DECODER
1825 DEFINE_CUVID_CODEC(hevc, HEVC, "hevc_mp4toannexb")
1826 #endif
1827 
1828 #if CONFIG_H264_CUVID_DECODER
1829 DEFINE_CUVID_CODEC(h264, H264, "h264_mp4toannexb")
1830 #endif
1831 
1832 #if CONFIG_MJPEG_CUVID_DECODER
1833 DEFINE_CUVID_CODEC(mjpeg, MJPEG, NULL)
1834 #endif
1835 
1836 #if CONFIG_MPEG1_CUVID_DECODER
1837 DEFINE_CUVID_CODEC(mpeg1, MPEG1VIDEO, NULL)
1838 #endif
1839 
1840 #if CONFIG_MPEG2_CUVID_DECODER
1841 DEFINE_CUVID_CODEC(mpeg2, MPEG2VIDEO, NULL)
1842 #endif
1843 
1844 #if CONFIG_MPEG4_CUVID_DECODER
1845 DEFINE_CUVID_CODEC(mpeg4, MPEG4, NULL)
1846 #endif
1847 
1848 #if CONFIG_VP8_CUVID_DECODER
1849 DEFINE_CUVID_CODEC(vp8, VP8, NULL)
1850 #endif
1851 
1852 #if CONFIG_VP9_CUVID_DECODER
1853 DEFINE_CUVID_CODEC(vp9, VP9, NULL)
1854 #endif
1855 
1856 #if CONFIG_VC1_CUVID_DECODER
1857 DEFINE_CUVID_CODEC(vc1, VC1, NULL)
1858 #endif
error
static void error(const char *err)
Definition: target_bsf_fuzzer.c:32
hwconfig.h
AVHWDeviceContext::hwctx
void * hwctx
The format-specific data, allocated and freed by libavutil along with this context.
Definition: hwcontext.h:88
av_packet_unref
void av_packet_unref(AVPacket *pkt)
Wipe the packet.
Definition: packet.c:434
ff_decode_get_packet
int ff_decode_get_packet(AVCodecContext *avctx, AVPacket *pkt)
Called by decoders to get the next packet for decoding.
Definition: decode.c:254
AV_LOG_WARNING
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:216
ff_cuda_cuarray_elem_size
static int ff_cuda_cuarray_elem_size(CUarray_format fmt)
Return the element size in bytes for a CUarray_format, or 0 for unknown.
Definition: hwcontext_cuda_internal.h:44
AV_PIX_FMT_CUDA
@ AV_PIX_FMT_CUDA
HW acceleration through CUDA.
Definition: pixfmt.h:260
AVCodecParameters::extradata
uint8_t * extradata
Extra binary data needed for initializing the decoder, codec-dependent.
Definition: codec_par.h:71
AVPixelFormat
AVPixelFormat
Pixel format.
Definition: pixfmt.h:71
av_fifo_can_write
size_t av_fifo_can_write(const AVFifo *f)
Definition: fifo.c:94
CuvidContext::opaque_output
int opaque_output
Definition: cuviddec.c:124
cuvid_handle_picture_display
static int CUDAAPI cuvid_handle_picture_display(void *opaque, CUVIDPARSERDISPINFO *dispinfo)
Definition: cuviddec.c:749
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
opt.h
CuvidContext::bottom
int bottom
Definition: cuviddec.c:87
AVCodecContext::colorspace
enum AVColorSpace colorspace
YUV colorspace type.
Definition: avcodec.h:671
hwcontext_cuda_internal.h
CuvidContext::decoder_flushing
int decoder_flushing
Definition: cuviddec.c:106
ff_get_format
int ff_get_format(AVCodecContext *avctx, const enum AVPixelFormat *fmt)
Select the (possibly hardware accelerated) pixel format.
Definition: decode.c:1229
AVCodecParameters
This struct describes the properties of an encoded stream.
Definition: codec_par.h:49
av_pix_fmt_desc_get
const AVPixFmtDescriptor * av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt)
Definition: pixdesc.c:3460
AVERROR_EOF
#define AVERROR_EOF
End of file.
Definition: error.h:57
av_div_q
AVRational av_div_q(AVRational b, AVRational c)
Divide one rational by another.
Definition: rational.c:88
AVHWFramesContext::format
enum AVPixelFormat format
The pixel format identifying the underlying HW surface type.
Definition: hwcontext.h:200
av_cold
#define av_cold
Definition: attributes.h:119
int64_t
long long int64_t
Definition: coverity.c:34
AV_PIX_FMT_YUV444P10MSB
#define AV_PIX_FMT_YUV444P10MSB
Definition: pixfmt.h:560
CuvidContext::resize
struct CuvidContext::@123 resize
AV_CODEC_ID_MPEG4
@ AV_CODEC_ID_MPEG4
Definition: codec_id.h:62
av_frame_free
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition: frame.c:64
CuvidParsedFrame::is_deinterlacing
int is_deinterlacing
Definition: cuviddec.c:139
av_hwframe_ctx_init
int av_hwframe_ctx_init(AVBufferRef *ref)
Finalize the context before use.
Definition: hwcontext.c:337
AVFrame
This structure describes decoded (raw) audio or video data.
Definition: frame.h:472
pixdesc.h
cleanup
static av_cold void cleanup(FlashSV2Context *s)
Definition: flashsv2enc.c:130
AVCodecContext::color_trc
enum AVColorTransferCharacteristic color_trc
Color Transfer Characteristic.
Definition: avcodec.h:664
AVFrame::width
int width
Definition: frame.h:544
AVCOL_RANGE_JPEG
@ AVCOL_RANGE_JPEG
Full range content.
Definition: pixfmt.h:783
cuvid_output_frame
static int cuvid_output_frame(AVCodecContext *avctx, AVFrame *frame)
Definition: cuviddec.c:871
av_hwframe_ctx_alloc
AVBufferRef * av_hwframe_ctx_alloc(AVBufferRef *device_ref_in)
Allocate an AVHWFramesContext tied to a given device context.
Definition: hwcontext.c:263
internal.h
AVPacket::data
uint8_t * data
Definition: packet.h:603
AVComponentDescriptor::depth
int depth
Number of bits in the component.
Definition: pixdesc.h:57
CuvidContext::avclass
AVClass * avclass
Definition: cuviddec.c:68
AVOption
AVOption.
Definition: opt.h:428
CuvidContext::chroma_format
cudaVideoChromaFormat chroma_format
Definition: cuviddec.c:112
data
const char data[16]
Definition: mxf.c:149
CuvidContext::progressive_sequence
int progressive_sequence
Definition: cuviddec.c:103
atomic_int
intptr_t atomic_int
Definition: stdatomic.h:55
CuvidContext::cudl
CudaFunctions * cudl
Definition: cuviddec.c:119
AV_LOG_VERBOSE
#define AV_LOG_VERBOSE
Detailed information.
Definition: log.h:226
mathematics.h
FFMAX
#define FFMAX(a, b)
Definition: macros.h:47
av_buffer_ref
AVBufferRef * av_buffer_ref(const AVBufferRef *buf)
Create a new reference to an AVBuffer.
Definition: buffer.c:103
AVHWFramesContext::width
int width
The allocated dimensions of the frames in this pool.
Definition: hwcontext.h:220
bit_depth
static void bit_depth(AudioStatsContext *s, const uint64_t *const mask, uint8_t *depth)
Definition: af_astats.c:246
dummy
static int dummy
Definition: ffplay.c:3751
CuvidContext::caps12
CUVIDDECODECAPS caps12
Definition: cuviddec.c:114
AV_PIX_FMT_P212
#define AV_PIX_FMT_P212
Definition: pixfmt.h:624
AV_PIX_FMT_YUV444P12MSB
#define AV_PIX_FMT_YUV444P12MSB
Definition: pixfmt.h:561
AVFrame::data
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition: frame.h:493
cuvid_test_capabilities
static int cuvid_test_capabilities(AVCodecContext *avctx, const CUVIDPARSERPARAMS *cuparseinfo, int probed_width, int probed_height, int bit_depth, int is_yuv422, int is_yuv444)
Definition: cuviddec.c:1274
AV_FRAME_FLAG_TOP_FIELD_FIRST
#define AV_FRAME_FLAG_TOP_FIELD_FIRST
A flag to mark frames where the top field is displayed first if the content is interlaced.
Definition: frame.h:700
AV_CODEC_HW_CONFIG_METHOD_INTERNAL
@ AV_CODEC_HW_CONFIG_METHOD_INTERNAL
The codec supports this format by some internal method.
Definition: codec.h:296
AV_HWDEVICE_TYPE_CUDA
@ AV_HWDEVICE_TYPE_CUDA
Definition: hwcontext.h:30
AVCodecContext::framerate
AVRational framerate
Definition: avcodec.h:563
fifo.h
bsf.h
AVCodecContext::codec
const struct AVCodec * codec
Definition: avcodec.h:452
av_fifo_write
int av_fifo_write(AVFifo *f, const void *buf, size_t nb_elems)
Write data into a FIFO.
Definition: fifo.c:188
CuvidParsedFrame
Definition: cuviddec.c:135
av_fifo_grow2
int av_fifo_grow2(AVFifo *f, size_t inc)
Enlarge an AVFifo.
Definition: fifo.c:99
AVCodecContext::flags
int flags
AV_CODEC_FLAG_*.
Definition: avcodec.h:500
CuvidContext::height
int height
Definition: cuviddec.c:92
AV_CODEC_FLAG_LOW_DELAY
#define AV_CODEC_FLAG_LOW_DELAY
Force low delay.
Definition: avcodec.h:314
AVCodecContext::coded_height
int coded_height
Definition: avcodec.h:619
CuvidContext::nb_surfaces
int nb_surfaces
Definition: cuviddec.c:78
AVBSFContext::par_out
AVCodecParameters * par_out
Parameters of the output stream.
Definition: bsf.h:96
AVCUDADeviceContext::cuda_ctx
CUcontext cuda_ctx
Definition: hwcontext_cuda.h:45
AVRational::num
int num
Numerator.
Definition: rational.h:59
CuvidContext::frame_queue
AVFifo * frame_queue
Definition: cuviddec.c:98
AV_CODEC_FLAG_INTERLACED_DCT
#define AV_CODEC_FLAG_INTERLACED_DCT
Use interlaced DCT.
Definition: avcodec.h:310
AVHWDeviceContext
This struct aggregates all the (hardware/vendor-specific) "high-level" state, i.e.
Definition: hwcontext.h:63
av_frame_alloc
AVFrame * av_frame_alloc(void)
Allocate an AVFrame and set its fields to default values.
Definition: frame.c:52
CuvidContext
Definition: cuviddec.c:66
CuvidContext::cuparse_ext
CUVIDEOFORMATEX * cuparse_ext
Definition: cuviddec.c:117
AVCodecContext::color_primaries
enum AVColorPrimaries color_primaries
Chromaticity coordinates of the source primaries.
Definition: avcodec.h:657
AV_LOG_TRACE
#define AV_LOG_TRACE
Extremely verbose debugging, useful for libav* development.
Definition: log.h:236
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
av_fifo_read
int av_fifo_read(AVFifo *f, void *buf, size_t nb_elems)
Read data from a FIFO.
Definition: fifo.c:240
CuvidContext::output_format
enum AVPixelFormat output_format
Definition: cuviddec.c:122
AVHWFramesContext::height
int height
Definition: hwcontext.h:220
AV_FRAME_FLAG_KEY
#define AV_FRAME_FLAG_KEY
A flag to mark frames that are keyframes.
Definition: frame.h:687
AVHWFramesContext::pool
AVBufferPool * pool
A pool from which the frames are allocated by av_hwframe_get_buffer().
Definition: hwcontext.h:181
flags
#define flags(name, subs,...)
Definition: cbs_av1.c:504
AVCodecContext::extradata_size
int extradata_size
Definition: avcodec.h:527
CuvidContext::right
int right
Definition: cuviddec.c:86
cuvid_hw_configs
static const AVCodecHWConfigInternal *const cuvid_hw_configs[]
Definition: cuviddec.c:1768
AV_PIX_FMT_YUV444P16
#define AV_PIX_FMT_YUV444P16
Definition: pixfmt.h:558
CuvidContext::crop
struct CuvidContext::@122 crop
AV_BUFFER_FLAG_READONLY
#define AV_BUFFER_FLAG_READONLY
Always treat the buffer as read-only, even when it has only one reference.
Definition: buffer.h:114
cuvid_handle_picture_decode
static int CUDAAPI cuvid_handle_picture_decode(void *opaque, CUVIDPICPARAMS *picparams)
Definition: cuviddec.c:708
AV_CODEC_ID_VP9
@ AV_CODEC_ID_VP9
Definition: codec_id.h:217
CuvidContext::caps10
CUVIDDECODECAPS caps10
Definition: cuviddec.c:114
CUVID_MAX_DISPLAY_DELAY
#define CUVID_MAX_DISPLAY_DELAY
Definition: cuviddec.c:145
DEFINE_CUVID_CODEC
#define DEFINE_CUVID_CODEC(x, X, bsf_name)
Definition: cuviddec.c:1794
pix_fmts
static enum AVPixelFormat pix_fmts[]
Definition: libkvazaar.c:296
AV_LOG_DEBUG
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:231
ctx
static AVFormatContext * ctx
Definition: movenc.c:49
decode.h
CuvidContext::cuparseinfo
CUVIDPARSERPARAMS cuparseinfo
Definition: cuviddec.c:116
av_rescale_q
int64_t av_rescale_q(int64_t a, AVRational bq, AVRational cq)
Rescale a 64-bit integer by 2 rational numbers.
Definition: mathematics.c:142
AVCodecHWConfig::pix_fmt
enum AVPixelFormat pix_fmt
For decoders, a hardware pixel format which that decoder may be able to decode to if suitable hardwar...
Definition: codec.h:317
AVPixFmtDescriptor::log2_chroma_w
uint8_t log2_chroma_w
Amount to shift the luma width right to find the chroma width.
Definition: pixdesc.h:80
av_mallocz
#define av_mallocz(s)
Definition: tableprint_vlc.h:31
AV_CODEC_ID_H264
@ AV_CODEC_ID_H264
Definition: codec_id.h:77
if
if(ret)
Definition: filter_design.txt:179
cuvid_decode_packet
static int cuvid_decode_packet(AVCodecContext *avctx, const AVPacket *avpkt)
Definition: cuviddec.c:798
CuvidContext::codec_type
cudaVideoCodec codec_type
Definition: cuviddec.c:111
AVClass
Describe the class of an AVClass context structure.
Definition: log.h:76
NULL
#define NULL
Definition: coverity.c:32
AVHWFramesContext::sw_format
enum AVPixelFormat sw_format
The pixel format identifying the actual data layout of the hardware frames.
Definition: hwcontext.h:213
format
New swscale design to change SwsGraph is what coordinates multiple passes These can include cascaded scaling error diffusion and so on Or we could have separate passes for the vertical and horizontal scaling In between each SwsPass lies a fully allocated image buffer Graph passes may have different levels of e g we can have a single threaded error diffusion pass following a multi threaded scaling pass SwsGraph is internally recreated whenever the image format
Definition: swscale-v2.txt:14
AVCodecContext::color_range
enum AVColorRange color_range
MPEG vs JPEG YUV range.
Definition: avcodec.h:681
av_buffer_unref
void av_buffer_unref(AVBufferRef **buf)
Free a given reference and automatically free the buffer if there are no more references to it.
Definition: buffer.c:139
AV_CODEC_ID_AV1
@ AV_CODEC_ID_AV1
Definition: codec_id.h:275
AVPixFmtDescriptor::nb_components
uint8_t nb_components
The number of components each pixel has, (1-4)
Definition: pixdesc.h:71
CuvidContext::crop_expr
char * crop_expr
Definition: cuviddec.c:80
VD
#define VD
Definition: cuviddec.c:1748
AVRational
Rational number (pair of numerator and denominator).
Definition: rational.h:58
AVHWFramesContext::device_ref
AVBufferRef * device_ref
A reference to the parent AVHWDeviceContext.
Definition: hwcontext.h:129
CuvidContext::internal_error
int internal_error
Definition: cuviddec.c:105
AVCodecContext::internal
struct AVCodecInternal * internal
Private context used for internal data.
Definition: avcodec.h:478
AVCodecContext::bit_rate
int64_t bit_rate
the average bitrate
Definition: avcodec.h:493
AV_PIX_FMT_P410
#define AV_PIX_FMT_P410
Definition: pixfmt.h:623
av_fifo_can_read
size_t av_fifo_can_read(const AVFifo *f)
Definition: fifo.c:87
ff_set_sar
int ff_set_sar(AVCodecContext *avctx, AVRational sar)
Check that the provided sample aspect ratio is valid and set it on the codec context.
Definition: utils.c:106
options
Definition: swscale.c:50
CuvidContext::width
int width
Definition: cuviddec.c:91
CuvidContext::cvdl
CuvidFunctions * cvdl
Definition: cuviddec.c:120
cuvid_is_buffer_full
static int cuvid_is_buffer_full(AVCodecContext *avctx)
Definition: cuviddec.c:786
atomic_load_explicit
#define atomic_load_explicit(object, order)
Definition: stdatomic.h:96
AV_CODEC_ID_MPEG1VIDEO
@ AV_CODEC_ID_MPEG1VIDEO
Definition: codec_id.h:51
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
AVCodecParameters::extradata_size
int extradata_size
Size of the extradata content in bytes.
Definition: codec_par.h:75
AV_CODEC_HW_CONFIG_METHOD_HW_DEVICE_CTX
@ AV_CODEC_HW_CONFIG_METHOD_HW_DEVICE_CTX
The codec supports this format via the hw_device_ctx interface.
Definition: codec.h:276
av_fifo_reset2
void av_fifo_reset2(AVFifo *f)
Definition: fifo.c:280
cuvid_decode_init
static av_cold int cuvid_decode_init(AVCodecContext *avctx)
Definition: cuviddec.c:1374
AVCUDADeviceContext::stream
CUstream stream
Definition: hwcontext_cuda.h:46
AVCUDADeviceContext::internal
AVCUDADeviceContextInternal * internal
Definition: hwcontext_cuda.h:47
ff_get_buffer
int ff_get_buffer(AVCodecContext *avctx, AVFrame *frame, int flags)
Get a buffer for a frame.
Definition: decode.c:1777
AVPacket::size
int size
Definition: packet.h:604
AVFifo
Definition: fifo.c:35
height
#define height
Definition: dsp.h:89
AVCodecContext::extra_hw_frames
int extra_hw_frames
Video decoding only.
Definition: avcodec.h:1516
codec_internal.h
AV_PIX_FMT_P012
#define AV_PIX_FMT_P012
Definition: pixfmt.h:609
shift
static int shift(int a, int b)
Definition: bonk.c:261
i
#define i(width, name, range_min, range_max)
Definition: cbs_h264.c:63
for
for(k=2;k<=8;++k)
Definition: h264pred_template.c:424
AVCodecInternal::bsf
struct AVBSFContext * bsf
Definition: internal.h:84
AVCodecContext::pkt_timebase
AVRational pkt_timebase
Timebase in which pkt_dts/pts and AVPacket.dts/pts are expressed.
Definition: avcodec.h:554
CuvidContext::drop_second_field
int drop_second_field
Definition: cuviddec.c:79
cuvid_decode_end
static av_cold int cuvid_decode_end(AVCodecContext *avctx)
Definition: cuviddec.c:1208
AV_NOPTS_VALUE
#define AV_NOPTS_VALUE
Undefined timestamp value.
Definition: avutil.h:247
CuvidContext::prev_pts
int64_t prev_pts
Definition: cuviddec.c:102
ffcodec
static const av_always_inline FFCodec * ffcodec(const AVCodec *codec)
Definition: codec_internal.h:307
AVFrame::format
int format
format of the frame, -1 if unknown or unset Values correspond to enum AVPixelFormat for video frames,...
Definition: frame.h:559
AVCodecHWConfigInternal
Definition: hwconfig.h:25
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_reallocp_array
int av_reallocp_array(void *ptr, size_t nmemb, size_t size)
Allocate, reallocate an array through a pointer to a pointer.
Definition: mem.c:225
AVERROR_EXTERNAL
#define AVERROR_EXTERNAL
Generic error in an external library.
Definition: error.h:59
offset
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it vf offset
Definition: writing_filters.txt:86
cudaVideoSurfaceFormat_YUV444_16Bit
#define cudaVideoSurfaceFormat_YUV444_16Bit
Definition: cuviddec.c:49
CuvidContext::abort_decode
atomic_int abort_decode
Definition: cuviddec.c:107
nvdec.h
AV_PIX_FMT_P216
#define AV_PIX_FMT_P216
Definition: pixfmt.h:626
CHECK_CU
#define CHECK_CU(x)
Definition: cuviddec.c:142
AV_PIX_FMT_P210
#define AV_PIX_FMT_P210
Definition: pixfmt.h:622
AVCodec::id
enum AVCodecID id
Definition: codec.h:183
AV_CODEC_ID_MJPEG
@ AV_CODEC_ID_MJPEG
Definition: codec_id.h:57
CuvidContext::cuparser
CUvideoparser cuparser
Definition: cuviddec.c:71
AV_OPT_FLAG_DEPRECATED
#define AV_OPT_FLAG_DEPRECATED
Set if option is deprecated, users should refer to AVOption.help text for more information.
Definition: opt.h:385
AVCUDADeviceContextInternal::cuda_dl
CudaFunctions * cuda_dl
Definition: hwcontext_cuda_internal.h:32
log.h
av_malloc
#define av_malloc(s)
Definition: ops_asmgen.c:44
AVCUDAFramesContext
This struct is allocated as AVHWFramesContext.hwctx.
Definition: hwcontext_cuda.h:79
AVPacket::pts
int64_t pts
Presentation timestamp in AVStream->time_base units; the time at which the decompressed packet will b...
Definition: packet.h:596
CuvidContext::top
int top
Definition: cuviddec.c:85
AVCodecContext::extradata
uint8_t * extradata
Out-of-band global headers that may be used by some codecs.
Definition: avcodec.h:526
AV_PIX_FMT_CUARRAY
@ AV_PIX_FMT_CUARRAY
hardware decoding through openharmony
Definition: pixfmt.h:506
CuvidParsedFrame::dispinfo
CUVIDPARSERDISPINFO dispinfo
Definition: cuviddec.c:137
AV_PIX_FMT_NV24
@ AV_PIX_FMT_NV24
planar YUV 4:4:4, 24bpp, 1 plane for Y and 1 plane for the UV components, which are interleaved (firs...
Definition: pixfmt.h:371
AVCodecInternal::in_pkt
AVPacket * in_pkt
This packet is used to hold the packet given to decoders implementing the .decode API; it is unused b...
Definition: internal.h:83
atomic_store_explicit
#define atomic_store_explicit(object, desired, order)
Definition: stdatomic.h:90
AV_CODEC_ID_HEVC
@ AV_CODEC_ID_HEVC
Definition: codec_id.h:223
FFMIN
#define FFMIN(a, b)
Definition: macros.h:49
CuvidContext::cuda_stream
CUstream cuda_stream
Definition: cuviddec.c:125
av_frame_unref
void av_frame_unref(AVFrame *frame)
Unreference all the buffers referenced by frame and reset the frame fields.
Definition: frame.c:496
AVCodec::name
const char * name
Name of the codec implementation.
Definition: codec.h:176
AVCodecContext::hw_device_ctx
AVBufferRef * hw_device_ctx
A reference to the AVHWDeviceContext describing the device which will be used by a hardware encoder/d...
Definition: avcodec.h:1493
AV_CODEC_ID_VC1
@ AV_CODEC_ID_VC1
Definition: codec_id.h:120
CuvidContext::resize_expr
char * resize_expr
Definition: cuviddec.c:81
AVCodecContext::height
int height
Definition: avcodec.h:604
AVCodecContext::pix_fmt
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
Definition: avcodec.h:643
CuvidContext::left
int left
Definition: cuviddec.c:84
AV_FRAME_FLAG_INTERLACED
#define AV_FRAME_FLAG_INTERLACED
A flag to mark frames whose content is interlaced.
Definition: frame.h:695
AVCOL_RANGE_MPEG
@ AVCOL_RANGE_MPEG
Narrow or limited range content.
Definition: pixfmt.h:766
av_calloc
void * av_calloc(size_t nmemb, size_t size)
Definition: mem.c:264
AV_PIX_FMT_P016
#define AV_PIX_FMT_P016
Definition: pixfmt.h:610
AVCodecContext::hw_frames_ctx
AVBufferRef * hw_frames_ctx
A reference to the AVHWFramesContext describing the input (for encoding) or output (decoding) frames.
Definition: avcodec.h:1471
avcodec.h
AVHWFramesContext
This struct describes a set or pool of "hardware" frames (i.e.
Definition: hwcontext.h:118
AVCUDADeviceContext
This struct is allocated as AVHWDeviceContext.hwctx.
Definition: hwcontext_cuda.h:44
ret
ret
Definition: filter_design.txt:187
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
AVHWFramesContext::device_ctx
AVHWDeviceContext * device_ctx
The parent AVHWDeviceContext.
Definition: hwcontext.h:137
cuda_check.h
AVHWFramesContext::hwctx
void * hwctx
The format-specific data, allocated and freed automatically along with this context.
Definition: hwcontext.h:153
CuvidContext::deint_mode_current
int deint_mode_current
Definition: cuviddec.c:101
av_hwdevice_ctx_create
int av_hwdevice_ctx_create(AVBufferRef **pdevice_ref, enum AVHWDeviceType type, const char *device, AVDictionary *opts, int flags)
Open a device of the specified type and create an AVHWDeviceContext for it.
Definition: hwcontext.c:615
av_fifo_alloc2
AVFifo * av_fifo_alloc2(size_t nb_elems, size_t elem_size, unsigned int flags)
Allocate and initialize an AVFifo with a given element size.
Definition: fifo.c:47
av_hwframe_transfer_data
int av_hwframe_transfer_data(AVFrame *dst, const AVFrame *src, int flags)
Copy data to or from a hw surface.
Definition: hwcontext.c:448
cudaVideoSurfaceFormat_YUV444
#define cudaVideoSurfaceFormat_YUV444
Definition: cuviddec.c:48
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:769
ff_decode_frame_props
int ff_decode_frame_props(AVCodecContext *avctx, AVFrame *frame)
Set various frame properties from the codec context / packet data.
Definition: decode.c:1598
AVCodecContext
main external API structure.
Definition: avcodec.h:443
AVFrame::height
int height
Definition: frame.h:544
CuvidContext::cudecoder
CUvideodecoder cudecoder
Definition: cuviddec.c:70
AVRational::den
int den
Denominator.
Definition: rational.h:60
AV_PIX_FMT_NONE
@ AV_PIX_FMT_NONE
Definition: pixfmt.h:72
AV_CODEC_HW_CONFIG_METHOD_HW_FRAMES_CTX
@ AV_CODEC_HW_CONFIG_METHOD_HW_FRAMES_CTX
The codec supports this format via the hw_frames_ctx interface.
Definition: codec.h:289
AV_OPT_TYPE_INT
@ AV_OPT_TYPE_INT
Underlying C type is int.
Definition: opt.h:258
CuvidContext::hwdevice
AVBufferRef * hwdevice
Definition: cuviddec.c:95
output_format
static char * output_format
Definition: ffprobe.c:145
AVPixFmtDescriptor::comp
AVComponentDescriptor comp[4]
Parameters that describe how pixels are packed.
Definition: pixdesc.h:105
CuvidParsedFrame::second_field
int second_field
Definition: cuviddec.c:138
Windows::Graphics::DirectX::Direct3D11::p
IDirect3DDxgiInterfaceAccess _COM_Outptr_ void ** p
Definition: vsrc_gfxcapture_winrt.hpp:53
OFFSET
#define OFFSET(x)
Definition: cuviddec.c:1747
av_mul_q
AVRational av_mul_q(AVRational b, AVRational c)
Multiply two rationals.
Definition: rational.c:80
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
AV_PIX_FMT_P010
#define AV_PIX_FMT_P010
Definition: pixfmt.h:608
FFCodec::bsfs
const char * bsfs
Decoding only, a comma-separated list of bitstream filters to apply to packets before decoding.
Definition: codec_internal.h:261
AVCodecContext::coded_width
int coded_width
Bitstream width / height, may be different from width/height e.g.
Definition: avcodec.h:619
CuvidContext::hwframe
AVBufferRef * hwframe
Definition: cuviddec.c:96
cuvid_flush
static void cuvid_flush(AVCodecContext *avctx)
Definition: cuviddec.c:1697
mem.h
AVBufferRef
A reference to a data buffer.
Definition: buffer.h:82
AVPixFmtDescriptor
Descriptor that unambiguously describes how the bits of a pixel are stored in the up to 4 data planes...
Definition: pixdesc.h:69
av_free
#define av_free(p)
Definition: tableprint_vlc.h:34
AVCodecContext::priv_data
void * priv_data
Definition: avcodec.h:470
AVPacket
This structure stores compressed data.
Definition: packet.h:580
AV_PIX_FMT_P416
#define AV_PIX_FMT_P416
Definition: pixfmt.h:627
AV_OPT_TYPE_BOOL
@ AV_OPT_TYPE_BOOL
Underlying C type is int.
Definition: opt.h:326
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:35
AVCodecContext::width
int width
picture width / height.
Definition: avcodec.h:604
CuvidContext::caps8
CUVIDDECODECAPS caps8
Definition: cuviddec.c:114
AV_CODEC_ID_VP8
@ AV_CODEC_ID_VP8
Definition: codec_id.h:190
hwcontext.h
AVERROR_BUG
#define AVERROR_BUG
Internal bug, also see AVERROR_BUG2.
Definition: error.h:52
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:517
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:27
av_fifo_freep2
void av_fifo_freep2(AVFifo **f)
Free an AVFifo and reset pointer to NULL.
Definition: fifo.c:286
cuvid_get_requested_hw_format
static int cuvid_get_requested_hw_format(AVCodecContext *avctx, CuvidContext *ctx, enum AVPixelFormat *fmt)
Definition: cuviddec.c:150
AV_PIX_FMT_P412
#define AV_PIX_FMT_P412
Definition: pixfmt.h:625
CuvidContext::pkt
AVPacket * pkt
Definition: cuviddec.c:75
AVCodecContext::sw_pix_fmt
enum AVPixelFormat sw_pix_fmt
Nominal unaccelerated pixel format, see AV_PIX_FMT_xxx.
Definition: avcodec.h:650
pkt
static AVPacket * pkt
Definition: demux_decode.c:55
AV_OPT_TYPE_STRING
@ AV_OPT_TYPE_STRING
Underlying C type is a uint8_t* that is either NULL or points to a C string allocated with the av_mal...
Definition: opt.h:275
CuvidContext::zero_copy
int zero_copy
Definition: cuviddec.c:123
AVCodecHWConfigInternal::public
AVCodecHWConfig public
This is the structure which will be returned to the user by avcodec_get_hw_config().
Definition: hwconfig.h:30
AV_CODEC_ID_MPEG2VIDEO
@ AV_CODEC_ID_MPEG2VIDEO
preferred ID for MPEG-1/2 video decoding
Definition: codec_id.h:52
CuvidContext::deint_mode
int deint_mode
Definition: cuviddec.c:100
av_hwframe_get_buffer
int av_hwframe_get_buffer(AVBufferRef *hwframe_ref, AVFrame *frame, int flags)
Allocate a new frame attached to the given AVHWFramesContext.
Definition: hwcontext.c:506
AV_OPT_TYPE_CONST
@ AV_OPT_TYPE_CONST
Special option type for declaring named constants.
Definition: opt.h:298
AVCUDAFramesContext::cuarray_desc
CUDA_ARRAY3D_DESCRIPTOR cuarray_desc
CUDA_ARRAY3D_DESCRIPTOR CUarrays will be initialized with.
Definition: hwcontext_cuda.h:89
CuvidContext::key_frame
int * key_frame
Definition: cuviddec.c:109
CuvidContext::cu_gpu
char * cu_gpu
Definition: cuviddec.c:77
AVPixFmtDescriptor::log2_chroma_h
uint8_t log2_chroma_h
Amount to shift the luma height right to find the chroma height.
Definition: pixdesc.h:89
cuvid_prepare_format_list
static void cuvid_prepare_format_list(enum AVPixelFormat *pix_fmts, enum AVPixelFormat hw_format, enum AVPixelFormat sw_format)
Definition: cuviddec.c:188
CUVID_DEFAULT_NUM_SURFACES
#define CUVID_DEFAULT_NUM_SURFACES
Definition: cuviddec.c:148
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:3380
cuvid_handle_video_sequence
static int CUDAAPI cuvid_handle_video_sequence(void *opaque, CUVIDEOFORMAT *format)
Definition: cuviddec.c:248