FFmpeg
Loading...
Searching...
No Matches
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"
30#include "libavutil/hwcontext.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
57typedef 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
66typedef 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;
82
83 struct {
84 int left;
85 int top;
86 int right;
87 int bottom;
89
90 struct {
91 int width;
92 int height;
94
97
99
104
108
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
134
135typedef 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;
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
199typedef struct CuvidSurfaceRelease {
200 AVBufferRef *in_use_ref;
201 int idx;
202} CuvidSurfaceRelease;
203
204static 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
213static 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);
241 }
242
243 av_free(data);
244}
245
246#endif
247
248static 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;
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)
427 else
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),
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
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);
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
708static 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
749static 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
798static 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
858error:
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))
899 ret = AVERROR_EXTERNAL;
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)
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
1193error:
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;
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
1692error:
1693 cuvid_decode_end(avctx);
1694 return ret;
1695}
1696
1697static 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
1749static 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 = {
1771 .pix_fmt = AV_PIX_FMT_CUDA,
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)
1821DEFINE_CUVID_CODEC(av1, AV1, NULL)
1822#endif
1823
1824#if CONFIG_HEVC_CUVID_DECODER
1825DEFINE_CUVID_CODEC(hevc, HEVC, "hevc_mp4toannexb")
1826#endif
1827
1828#if CONFIG_H264_CUVID_DECODER
1829DEFINE_CUVID_CODEC(h264, H264, "h264_mp4toannexb")
1830#endif
1831
1832#if CONFIG_MJPEG_CUVID_DECODER
1833DEFINE_CUVID_CODEC(mjpeg, MJPEG, NULL)
1834#endif
1835
1836#if CONFIG_MPEG1_CUVID_DECODER
1837DEFINE_CUVID_CODEC(mpeg1, MPEG1VIDEO, NULL)
1838#endif
1839
1840#if CONFIG_MPEG2_CUVID_DECODER
1841DEFINE_CUVID_CODEC(mpeg2, MPEG2VIDEO, NULL)
1842#endif
1843
1844#if CONFIG_MPEG4_CUVID_DECODER
1845DEFINE_CUVID_CODEC(mpeg4, MPEG4, NULL)
1846#endif
1847
1848#if CONFIG_VP8_CUVID_DECODER
1849DEFINE_CUVID_CODEC(vp8, VP8, NULL)
1850#endif
1851
1852#if CONFIG_VP9_CUVID_DECODER
1853DEFINE_CUVID_CODEC(vp9, VP9, NULL)
1854#endif
1855
1856#if CONFIG_VC1_CUVID_DECODER
1857DEFINE_CUVID_CODEC(vc1, VC1, NULL)
1858#endif
SwsAArch64OpImplParams params
Definition ops.c:51
static const char *const format[]
Definition af_aiir.c:444
static void bit_depth(AudioStatsContext *s, const uint64_t *const mask, uint8_t *depth)
Definition af_astats.c:246
#define VD
Definition amfdec.c:787
Libavcodec external API header.
refcounted data buffer API
#define flags(name, subs,...)
Definition cbs_h264.c:74
#define i(width, name, range_min, range_max)
Definition cbs_h264.c:63
static av_always_inline const FFCodec * ffcodec(const AVCodec *codec)
#define NULL
Definition coverity.c:32
long long int64_t
Definition coverity.c:34
static int cuvid_decode_packet(AVCodecContext *avctx, const AVPacket *avpkt)
Definition cuviddec.c:798
static int CUDAAPI cuvid_handle_picture_decode(void *opaque, CUVIDPICPARAMS *picparams)
Definition cuviddec.c:708
static const AVCodecHWConfigInternal *const cuvid_hw_configs[]
Definition cuviddec.c:1768
static int cuvid_output_frame(AVCodecContext *avctx, AVFrame *frame)
Definition cuviddec.c:871
static av_cold int cuvid_decode_end(AVCodecContext *avctx)
Definition cuviddec.c:1208
#define CUVID_MAX_DISPLAY_DELAY
Definition cuviddec.c:145
#define cudaVideoSurfaceFormat_YUV444
Definition cuviddec.c:48
static void cuvid_prepare_format_list(enum AVPixelFormat *pix_fmts, enum AVPixelFormat hw_format, enum AVPixelFormat sw_format)
Definition cuviddec.c:188
static int CUDAAPI cuvid_handle_picture_display(void *opaque, CUVIDPARSERDISPINFO *dispinfo)
Definition cuviddec.c:749
static int cuvid_get_requested_hw_format(AVCodecContext *avctx, CuvidContext *ctx, enum AVPixelFormat *fmt)
Definition cuviddec.c:150
#define CHECK_CU(x)
Definition cuviddec.c:142
static int CUDAAPI cuvid_handle_video_sequence(void *opaque, CUVIDEOFORMAT *format)
Definition cuviddec.c:248
static av_cold int cuvid_decode_init(AVCodecContext *avctx)
Definition cuviddec.c:1374
#define OFFSET(x)
Definition cuviddec.c:1747
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
#define DEFINE_CUVID_CODEC(x, X, bsf_name)
Definition cuviddec.c:1794
#define CUVID_DEFAULT_NUM_SURFACES
Definition cuviddec.c:148
#define cudaVideoSurfaceFormat_YUV444_16Bit
Definition cuviddec.c:49
static int cuvid_is_buffer_full(AVCodecContext *avctx)
Definition cuviddec.c:786
static void cuvid_flush(AVCodecContext *avctx)
Definition cuviddec.c:1697
int ff_get_buffer(AVCodecContext *avctx, AVFrame *frame, int flags)
Get a buffer for a frame.
Definition decode.c:1777
int ff_decode_frame_props(AVCodecContext *avctx, AVFrame *frame)
Set various frame properties from the codec context / packet data.
Definition decode.c:1598
int ff_decode_get_packet(AVCodecContext *avctx, AVPacket *pkt)
Called by decoders to get the next packet for decoding.
Definition decode.c:254
int ff_get_format(AVCodecContext *avctx, const enum AVPixelFormat *fmt)
Select the (possibly hardware accelerated) pixel format.
Definition decode.c:1229
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
static AVPacket * pkt
static AVFrame * frame
intptr_t atomic_int
Definition stdatomic.h:55
#define atomic_load_explicit(object, order)
Definition stdatomic.h:96
#define atomic_store_explicit(object, desired, order)
Definition stdatomic.h:90
static int dummy
Definition ffplay.c:3754
static char * output_format
Definition ffprobe.c:145
A generic FIFO API.
static av_cold void cleanup(FlashSV2Context *s)
#define AV_OPT_FLAG_DEPRECATED
Set if option is deprecated, users should refer to AVOption.help text for more information.
Definition opt.h:385
@ AV_OPT_TYPE_CONST
Special option type for declaring named constants.
Definition opt.h:298
@ AV_OPT_TYPE_INT
Underlying C type is int.
Definition opt.h:258
@ AV_OPT_TYPE_BOOL
Underlying C type is int.
Definition opt.h:326
@ 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
#define AV_CODEC_FLAG_INTERLACED_DCT
Use interlaced DCT.
Definition avcodec.h:310
#define AV_CODEC_FLAG_LOW_DELAY
Force low delay.
Definition avcodec.h:314
@ AV_CODEC_HW_CONFIG_METHOD_HW_FRAMES_CTX
The codec supports this format via the hw_frames_ctx interface.
Definition codec.h:295
@ AV_CODEC_HW_CONFIG_METHOD_HW_DEVICE_CTX
The codec supports this format via the hw_device_ctx interface.
Definition codec.h:282
@ AV_CODEC_HW_CONFIG_METHOD_INTERNAL
The codec supports this format by some internal method.
Definition codec.h:302
@ AV_CODEC_ID_H264
Definition codec_id.h:77
@ AV_CODEC_ID_AV1
Definition codec_id.h:275
@ AV_CODEC_ID_VC1
Definition codec_id.h:120
@ AV_CODEC_ID_VP8
Definition codec_id.h:190
@ AV_CODEC_ID_HEVC
Definition codec_id.h:223
@ AV_CODEC_ID_MPEG4
Definition codec_id.h:62
@ AV_CODEC_ID_MJPEG
Definition codec_id.h:57
@ AV_CODEC_ID_VP9
Definition codec_id.h:217
@ AV_CODEC_ID_MPEG1VIDEO
Definition codec_id.h:51
@ AV_CODEC_ID_MPEG2VIDEO
preferred ID for MPEG-1/2 video decoding
Definition codec_id.h:52
void av_packet_unref(AVPacket *pkt)
Wipe the packet.
Definition packet.c:434
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
AVBufferRef * av_buffer_ref(const AVBufferRef *buf)
Create a new reference to an AVBuffer.
Definition buffer.c:103
#define AV_BUFFER_FLAG_READONLY
Always treat the buffer as read-only, even when it has only one reference.
Definition buffer.h:114
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
#define AVERROR_EXTERNAL
Generic error in an external library.
Definition error.h:59
#define AVERROR_BUG
Internal bug, also see AVERROR_BUG2.
Definition error.h:52
#define AVERROR_EOF
End of file.
Definition error.h:57
#define AVERROR(e)
Definition error.h:45
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
void av_fifo_freep2(AVFifo **f)
Free an AVFifo and reset pointer to NULL.
Definition fifo.c:286
void av_fifo_reset2(AVFifo *f)
Definition fifo.c:280
size_t av_fifo_can_write(const AVFifo *f)
Definition fifo.c:94
size_t av_fifo_can_read(const AVFifo *f)
Definition fifo.c:87
int av_fifo_grow2(AVFifo *f, size_t inc)
Enlarge an AVFifo.
Definition fifo.c:99
int av_fifo_write(AVFifo *f, const void *buf, size_t nb_elems)
Write data into a FIFO.
Definition fifo.c:188
int av_fifo_read(AVFifo *f, void *buf, size_t nb_elems)
Read data from a FIFO.
Definition fifo.c:240
#define AV_FRAME_FLAG_INTERLACED
A flag to mark frames whose content is interlaced.
Definition frame.h:695
#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
#define AV_FRAME_FLAG_KEY
A flag to mark frames that are keyframes.
Definition frame.h:687
void av_frame_unref(AVFrame *frame)
Unreference all the buffers referenced by frame and reset the frame fields.
Definition frame.c:496
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition frame.c:64
AVFrame * av_frame_alloc(void)
Allocate an AVFrame and set its fields to default values.
Definition frame.c:52
#define AV_LOG_TRACE
Extremely verbose debugging, useful for libav* development.
Definition log.h:236
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition log.h:231
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition log.h:216
#define AV_LOG_VERBOSE
Detailed information.
Definition log.h:226
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition log.h:210
AVRational av_mul_q(AVRational b, AVRational c)
Multiply two rationals.
Definition rational.c:80
AVRational av_div_q(AVRational b, AVRational c)
Divide one rational by another.
Definition rational.c:88
int64_t av_rescale_q(int64_t a, AVRational bq, AVRational cq)
Rescale a 64-bit integer by 2 rational numbers.
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
#define AV_NOPTS_VALUE
Undefined timestamp value.
Definition avutil.h:247
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
int av_hwframe_ctx_init(AVBufferRef *ref)
Finalize the context before use.
Definition hwcontext.c:337
AVBufferRef * av_hwframe_ctx_alloc(AVBufferRef *device_ref_in)
Allocate an AVHWFramesContext tied to a given device context.
Definition hwcontext.c:263
int av_hwframe_transfer_data(AVFrame *dst, const AVFrame *src, int flags)
Copy data to or from a hw surface.
Definition hwcontext.c:448
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_HWDEVICE_TYPE_CUDA
Definition hwcontext.h:30
FFmpeg internal API for CUDA.
static int ff_cuda_cuarray_elem_size(CUarray_format fmt)
Return the element size in bytes for a CUarray_format, or 0 for unknown.
unsigned offset
Definition libaomenc.c:763
static int shift(int a, int b)
Definition bonk.c:261
common internal api header.
#define av_cold
Definition attributes.h:117
static enum AVPixelFormat pix_fmts[]
Definition libkvazaar.c:296
#define FFMIN(a, b)
Definition macros.h:49
#define FFMAX(a, b)
Definition macros.h:47
void * av_calloc(size_t nmemb, size_t size)
Definition mem.c:264
Memory handling functions.
const char data[16]
Definition mxf.c:149
#define av_malloc(s)
Definition ops_static.c:52
AVOptions.
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
const AVPixFmtDescriptor * av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt)
Definition pixdesc.c:3460
#define AV_PIX_FMT_P212
Definition pixfmt.h:624
#define AV_PIX_FMT_P412
Definition pixfmt.h:625
@ AVCOL_RANGE_MPEG
Narrow or limited range content.
Definition pixfmt.h:766
@ AVCOL_RANGE_JPEG
Full range content.
Definition pixfmt.h:783
#define AV_PIX_FMT_P210
Definition pixfmt.h:622
#define AV_PIX_FMT_P012
Definition pixfmt.h:609
#define AV_PIX_FMT_P216
Definition pixfmt.h:626
#define AV_PIX_FMT_P010
Definition pixfmt.h:608
#define AV_PIX_FMT_P016
Definition pixfmt.h:610
#define AV_PIX_FMT_YUV444P12MSB
Definition pixfmt.h:561
#define AV_PIX_FMT_P410
Definition pixfmt.h:623
AVPixelFormat
Pixel format.
Definition pixfmt.h:71
@ 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
@ AV_PIX_FMT_NONE
Definition pixfmt.h:72
@ AV_PIX_FMT_CUDA
HW acceleration through CUDA.
Definition pixfmt.h:260
@ 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
@ AV_PIX_FMT_NV16
interleaved chroma YUV 4:2:2, 16bpp, (1 Cr & Cb sample per 2x1 Y samples)
Definition pixfmt.h:198
@ 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_CUARRAY
hardware decoding through openharmony
Definition pixfmt.h:506
#define AV_PIX_FMT_P416
Definition pixfmt.h:627
#define AV_PIX_FMT_YUV444P16
Definition pixfmt.h:558
#define AV_PIX_FMT_YUV444P10MSB
Definition pixfmt.h:560
#define FF_ARRAY_ELEMS(a)
AVCodecParameters * par_out
Parameters of the output stream.
Definition bsf.h:96
A reference to a data buffer.
Definition buffer.h:82
This struct is allocated as AVHWDeviceContext.hwctx.
AVCUDADeviceContextInternal * internal
This struct is allocated as AVHWFramesContext.hwctx.
CUDA_ARRAY3D_DESCRIPTOR cuarray_desc
CUDA_ARRAY3D_DESCRIPTOR CUarrays will be initialized with.
Describe the class of an AVClass context structure.
Definition log.h:76
main external API structure.
Definition avcodec.h:443
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
Definition avcodec.h:643
int width
picture width / height.
Definition avcodec.h:604
enum AVPixelFormat sw_pix_fmt
Nominal unaccelerated pixel format, see AV_PIX_FMT_xxx.
Definition avcodec.h:650
enum AVColorRange color_range
MPEG vs JPEG YUV range.
Definition avcodec.h:681
AVRational pkt_timebase
Timebase in which pkt_dts/pts and AVPacket.dts/pts are expressed.
Definition avcodec.h:554
enum AVColorPrimaries color_primaries
Chromaticity coordinates of the source primaries.
Definition avcodec.h:657
AVBufferRef * hw_frames_ctx
A reference to the AVHWFramesContext describing the input (for encoding) or output (decoding) frames.
Definition avcodec.h:1471
AVRational framerate
Definition avcodec.h:563
int64_t bit_rate
the average bitrate
Definition avcodec.h:493
const struct AVCodec * codec
Definition avcodec.h:452
enum AVColorSpace colorspace
YUV colorspace type.
Definition avcodec.h:671
enum AVColorTransferCharacteristic color_trc
Color Transfer Characteristic.
Definition avcodec.h:664
int flags
AV_CODEC_FLAG_*.
Definition avcodec.h:500
uint8_t * extradata
Out-of-band global headers that may be used by some codecs.
Definition avcodec.h:526
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
int extra_hw_frames
Video decoding only.
Definition avcodec.h:1516
int extradata_size
Definition avcodec.h:527
int coded_width
Bitstream width / height, may be different from width/height e.g.
Definition avcodec.h:619
struct AVCodecInternal * internal
Private context used for internal data.
Definition avcodec.h:478
void * priv_data
Definition avcodec.h:470
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
struct AVBSFContext * bsf
Definition internal.h:84
This struct describes the properties of an encoded stream.
Definition codec_par.h:49
int extradata_size
Size of the extradata content in bytes.
Definition codec_par.h:75
uint8_t * extradata
Extra binary data needed for initializing the decoder, codec-dependent.
Definition codec_par.h:71
enum AVCodecID id
Definition codec.h:189
const char * name
Name of the codec implementation.
Definition codec.h:182
int depth
Number of bits in the component.
Definition pixdesc.h:57
Definition fifo.c:35
This structure describes decoded (raw) audio or video data.
Definition frame.h:472
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition frame.h:493
int width
Definition frame.h:544
AVBufferRef * hw_frames_ctx
For hwaccel-format frames, this should be a reference to the AVHWFramesContext describing the frame.
Definition frame.h:769
int height
Definition frame.h:544
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
int format
format of the frame, -1 if unknown or unset Values correspond to enum AVPixelFormat for video frames,...
Definition frame.h:559
This struct aggregates all the (hardware/vendor-specific) "high-level" state, i.e.
Definition hwcontext.h:63
void * hwctx
The format-specific data, allocated and freed by libavutil along with this context.
Definition hwcontext.h:88
This struct describes a set or pool of "hardware" frames (i.e.
Definition hwcontext.h:118
enum AVPixelFormat format
The pixel format identifying the underlying HW surface type.
Definition hwcontext.h:200
AVBufferRef * device_ref
A reference to the parent AVHWDeviceContext.
Definition hwcontext.h:129
void * hwctx
The format-specific data, allocated and freed automatically along with this context.
Definition hwcontext.h:153
enum AVPixelFormat sw_format
The pixel format identifying the actual data layout of the hardware frames.
Definition hwcontext.h:213
int width
The allocated dimensions of the frames in this pool.
Definition hwcontext.h:220
AVHWDeviceContext * device_ctx
The parent AVHWDeviceContext.
Definition hwcontext.h:137
AVBufferPool * pool
A pool from which the frames are allocated by av_hwframe_get_buffer().
Definition hwcontext.h:181
AVOption.
Definition opt.h:428
This structure stores compressed data.
Definition packet.h:580
int size
Definition packet.h:604
int64_t pts
Presentation timestamp in AVStream->time_base units; the time at which the decompressed packet will b...
Definition packet.h:596
uint8_t * data
Definition packet.h:603
Descriptor that unambiguously describes how the bits of a pixel are stored in the up to 4 data planes...
Definition pixdesc.h:69
AVComponentDescriptor comp[4]
Parameters that describe how pixels are packed.
Definition pixdesc.h:105
uint8_t log2_chroma_w
Amount to shift the luma width right to find the chroma width.
Definition pixdesc.h:80
uint8_t log2_chroma_h
Amount to shift the luma height right to find the chroma height.
Definition pixdesc.h:89
uint8_t nb_components
The number of components each pixel has, (1-4)
Definition pixdesc.h:71
Rational number (pair of numerator and denominator).
Definition rational.h:58
int num
Numerator.
Definition rational.h:59
int den
Denominator.
Definition rational.h:60
int drop_second_field
Definition cuviddec.c:79
int * key_frame
Definition cuviddec.c:109
char * crop_expr
Definition cuviddec.c:80
AVFifo * frame_queue
Definition cuviddec.c:98
CUVIDDECODECAPS caps12
Definition cuviddec.c:114
CUvideodecoder cudecoder
Definition cuviddec.c:70
CUvideoparser cuparser
Definition cuviddec.c:71
char * resize_expr
Definition cuviddec.c:81
atomic_int abort_decode
Definition cuviddec.c:107
int deint_mode_current
Definition cuviddec.c:101
int64_t prev_pts
Definition cuviddec.c:102
CudaFunctions * cudl
Definition cuviddec.c:119
struct CuvidContext::@006255247064232322304150030351010216270027246216 resize
enum AVPixelFormat output_format
Definition cuviddec.c:122
CuvidFunctions * cvdl
Definition cuviddec.c:120
int decoder_flushing
Definition cuviddec.c:106
AVBufferRef * hwdevice
Definition cuviddec.c:95
AVClass * avclass
Definition cuviddec.c:68
cudaVideoCodec codec_type
Definition cuviddec.c:111
char * cu_gpu
Definition cuviddec.c:77
AVPacket * pkt
Definition cuviddec.c:75
int nb_surfaces
Definition cuviddec.c:78
CUstream cuda_stream
Definition cuviddec.c:125
cudaVideoChromaFormat chroma_format
Definition cuviddec.c:112
AVBufferRef * hwframe
Definition cuviddec.c:96
CUVIDDECODECAPS caps8
Definition cuviddec.c:114
int internal_error
Definition cuviddec.c:105
struct CuvidContext::@133300314247370073362260244350264314175314272354 crop
CUVIDPARSERPARAMS cuparseinfo
Definition cuviddec.c:116
CUVIDDECODECAPS caps10
Definition cuviddec.c:114
int progressive_sequence
Definition cuviddec.c:103
CUVIDEOFORMATEX * cuparse_ext
Definition cuviddec.c:117
int opaque_output
Definition cuviddec.c:124
CUVIDPARSERDISPINFO dispinfo
Definition cuviddec.c:137
const char * bsfs
Decoding only, a comma-separated list of bitstream filters to apply to packets before decoding.
#define av_free(p)
#define av_mallocz(s)
#define av_freep(p)
#define av_log(a,...)
static void error(const char *err)
static AVFormatContext * ctx
Definition movenc.c:49
#define height
Definition dsp.h:89