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