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