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
25
35
43
44 #if !NVDECAPI_CHECK_VERSION(9, 0)
45 #define cudaVideoSurfaceFormat_YUV444 2
46 #define cudaVideoSurfaceFormat_YUV444_16Bit 3
47 #endif
48
49 #if NVDECAPI_CHECK_VERSION(11, 0)
50 #define CUVID_HAS_AV1_SUPPORT
51 #endif
52
54 {
56
59
60 /* This packet coincides with AVCodecInternal.in_pkt
61 * and is not owned by us. */
63
69
70 struct {
76
77 struct {
81
84
86
91
94
96
99
101
104
108
110 {
115
116 #define CHECK_CU(x) FF_CUDA_CHECK_DL(avctx, ctx->cudl, x)
117
119 {
123 CUVIDDECODECAPS *caps =
NULL;
124 CUVIDDECODECREATEINFO cuinfo;
125 int surface_fmt;
126 int chroma_444;
127
128 int old_width = avctx->
width;
129 int old_height = avctx->
height;
130
134
136
137 memset(&cuinfo, 0, sizeof(cuinfo));
138
139 ctx->internal_error = 0;
140
141 avctx->coded_width = cuinfo.ulWidth =
format->coded_width;
142 avctx->coded_height = cuinfo.ulHeight =
format->coded_height;
143
144 // apply cropping
145 cuinfo.display_area.left =
format->display_area.left +
ctx->crop.left;
146 cuinfo.display_area.top =
format->display_area.top +
ctx->crop.top;
147 cuinfo.display_area.right =
format->display_area.right -
ctx->crop.right;
148 cuinfo.display_area.bottom =
format->display_area.bottom -
ctx->crop.bottom;
149
150 // width and height need to be set before calling ff_get_format
151 if (
ctx->resize_expr) {
152 avctx->width =
ctx->resize.width;
153 avctx->height =
ctx->resize.height;
154 } else {
155 avctx->width = cuinfo.display_area.right - cuinfo.display_area.left;
156 avctx->height = cuinfo.display_area.bottom - cuinfo.display_area.top;
157 }
158
159 // target width/height need to be multiples of two
160 cuinfo.ulTargetWidth = avctx->width = (avctx->width + 1) & ~1;
161 cuinfo.ulTargetHeight = avctx->height = (avctx->height + 1) & ~1;
162
163 // aspect ratio conversion, 1:1, depends on scaled resolution
164 cuinfo.target_rect.left = 0;
165 cuinfo.target_rect.top = 0;
166 cuinfo.target_rect.right = cuinfo.ulTargetWidth;
167 cuinfo.target_rect.bottom = cuinfo.ulTargetHeight;
168
169 chroma_444 =
format->chroma_format == cudaVideoChromaFormat_444;
170
171 switch (
format->bit_depth_luma_minus8) {
172 case 0: // 8-bit
175 break;
176 case 2: // 10-bit
179 break;
180 case 4: // 12-bit
183 break;
184 default:
185 break;
186 }
187
188 if (!caps || !caps->bIsSupported) {
190 format->bit_depth_luma_minus8 + 8);
192 return 0;
193 }
194
196 if (surface_fmt < 0) {
199 return 0;
200 }
201
206
207 avctx->pix_fmt = surface_fmt;
208
209 // Update our hwframe ctx, as the get_format callback might have refreshed it!
210 if (avctx->hw_frames_ctx) {
212
216 return 0;
217 }
218
220 }
221
225
226 ctx->deint_mode_current =
format->progressive_sequence
227 ? cudaVideoDeinterlaceMode_Weave
229
230 ctx->progressive_sequence =
format->progressive_sequence;
231
232 if (!
format->progressive_sequence &&
ctx->deint_mode_current == cudaVideoDeinterlaceMode_Weave)
234 else
236
237 if (
format->video_signal_description.video_full_range_flag)
239 else
241
243 avctx->color_trc =
format->video_signal_description.transfer_characteristics;
245
247 avctx->bit_rate =
format->bitrate;
248
249 if (
format->frame_rate.numerator &&
format->frame_rate.denominator) {
250 avctx->framerate.num =
format->frame_rate.numerator;
251 avctx->framerate.den =
format->frame_rate.denominator;
252 }
253
255 && avctx->coded_width ==
format->coded_width
256 && avctx->coded_height ==
format->coded_height
257 && avctx->
width == old_width
258 && avctx->height == old_height
259 &&
ctx->chroma_format ==
format->chroma_format
261 return 1;
262
263 if (
ctx->cudecoder) {
266 if (
ctx->internal_error < 0)
267 return 0;
269 }
270
271 if (hwframe_ctx->pool && (
272 hwframe_ctx->width < avctx->width ||
273 hwframe_ctx->height < avctx->height ||
275 hwframe_ctx->sw_format != avctx->sw_pix_fmt)) {
276 av_log(avctx,
AV_LOG_ERROR,
"AVHWFramesContext is already initialized with incompatible parameters\n");
278 av_log(avctx,
AV_LOG_DEBUG,
"height: %d <-> %d\n", hwframe_ctx->height, avctx->height);
283 return 0;
284 }
285
286 ctx->chroma_format =
format->chroma_format;
287
288 cuinfo.CodecType =
ctx->codec_type =
format->codec;
289 cuinfo.ChromaFormat =
format->chroma_format;
290
291 switch (avctx->sw_pix_fmt) {
293 cuinfo.OutputFormat = cudaVideoSurfaceFormat_NV12;
294 break;
297 cuinfo.OutputFormat = cudaVideoSurfaceFormat_P016;
298 break;
301 break;
304 break;
305 default:
309 return 0;
310 }
311
312 cuinfo.ulNumDecodeSurfaces =
ctx->nb_surfaces;
313 cuinfo.ulNumOutputSurfaces = 1;
314 cuinfo.ulCreationFlags = cudaVideoCreate_PreferCUVID;
315 cuinfo.bitDepthMinus8 =
format->bit_depth_luma_minus8;
316 cuinfo.DeinterlaceMode =
ctx->deint_mode_current;
317
318 if (
ctx->deint_mode_current != cudaVideoDeinterlaceMode_Weave && !
ctx->drop_second_field)
320
321 ctx->internal_error =
CHECK_CU(
ctx->cvdl->cuvidCreateDecoder(&
ctx->cudecoder, &cuinfo));
322 if (
ctx->internal_error < 0)
323 return 0;
324
325 if (!hwframe_ctx->pool) {
327 hwframe_ctx->sw_format = avctx->sw_pix_fmt;
328 hwframe_ctx->width = avctx->width;
329 hwframe_ctx->height = avctx->height;
330
333 return 0;
334 }
335 }
336
337 return 1;
338 }
339
341 {
344
346
347 if(picparams->intra_pic_flag)
348 ctx->key_frame[picparams->CurrPicIdx] = picparams->intra_pic_flag;
349
350 ctx->internal_error =
CHECK_CU(
ctx->cvdl->cuvidDecodePicture(
ctx->cudecoder, picparams));
351 if (
ctx->internal_error < 0)
352 return 0;
353
354 return 1;
355 }
356
358 {
362
364 ctx->internal_error = 0;
365
366 // For some reason, dispinfo->progressive_frame is sometimes wrong.
367 parsed_frame.
dispinfo.progressive_frame =
ctx->progressive_sequence;
368
369 if (
ctx->deint_mode_current == cudaVideoDeinterlaceMode_Weave) {
371 } else {
374 if (!
ctx->drop_second_field) {
377 }
378 }
379
380 return 1;
381 }
382
384 {
386
387 int delay =
ctx->cuparseinfo.ulMaxDisplayDelay;
388 if (
ctx->deint_mode != cudaVideoDeinterlaceMode_Weave && !
ctx->drop_second_field)
389 delay *= 2;
390
392 }
393
395 {
399 CUcontext
dummy, cuda_ctx = device_hwctx->cuda_ctx;
400 CUVIDSOURCEDATAPACKET cupkt;
401 int ret = 0, eret = 0, is_flush =
ctx->decoder_flushing;
402
404
405 if (is_flush && avpkt && avpkt->
size)
407
410
414 }
415
416 memset(&cupkt, 0, sizeof(cupkt));
417
418 if (avpkt && avpkt->
size) {
419 cupkt.payload_size = avpkt->
size;
420 cupkt.payload = avpkt->
data;
421
423 cupkt.flags = CUVID_PKT_TIMESTAMP;
426 else
427 cupkt.timestamp = avpkt->
pts;
428 }
429 } else {
430 cupkt.flags = CUVID_PKT_ENDOFSTREAM;
431 ctx->decoder_flushing = 1;
432 }
433
435
438
439 // cuvidParseVideoData doesn't return an error just because stuff failed...
440 if (
ctx->internal_error) {
442 ret =
ctx->internal_error;
444 }
445
448
449 if (eret < 0)
450 return eret;
453 else if (is_flush)
455 else
456 return 0;
457 }
458
460 {
464 CUcontext
dummy, cuda_ctx = device_hwctx->cuda_ctx;
466 CUdeviceptr mapped_frame = 0;
467 int ret = 0, eret = 0;
468
470
471 if (
ctx->decoder_flushing) {
475 }
476
484 // cuvid_is_buffer_full() should avoid this.
489 }
490
494
497 CUVIDPROCPARAMS params;
498 unsigned int pitch = 0;
501
502 memset(¶ms, 0, sizeof(params));
503 params.progressive_frame = parsed_frame.dispinfo.progressive_frame;
504 params.second_field = parsed_frame.second_field;
505 params.top_field_first = parsed_frame.dispinfo.top_field_first;
506
507 ret =
CHECK_CU(
ctx->cvdl->cuvidMapVideoFrame(
ctx->cudecoder, parsed_frame.dispinfo.picture_index, &mapped_frame, &pitch, ¶ms));
510
516 }
517
522 }
523
525
528 CUDA_MEMCPY2D cpy = {
529 .srcMemoryType = CU_MEMORYTYPE_DEVICE,
530 .dstMemoryType = CU_MEMORYTYPE_DEVICE,
531 .srcDevice = mapped_frame,
532 .dstDevice = (CUdeviceptr)
frame->data[
i],
533 .srcPitch = pitch,
534 .dstPitch =
frame->linesize[
i],
538 };
539
540 ret =
CHECK_CU(
ctx->cudl->cuMemcpy2DAsync(&cpy, device_hwctx->stream));
543
545 }
553 if (!tmp_frame) {
557 }
558
560
567 }
568
571
572 /*
573 * Note that the following logic would not work for three plane
574 * YUV420 because the pitch value is different for the chroma
575 * planes.
576 */
578 tmp_frame->
data[
i] = (uint8_t*)mapped_frame +
offset;
581 }
582
588 }
589
595 }
597 } else {
600 }
601
602 frame->key_frame =
ctx->key_frame[parsed_frame.dispinfo.picture_index];
603 ctx->key_frame[parsed_frame.dispinfo.picture_index] = 0;
604
609 else
610 frame->pts = parsed_frame.dispinfo.timestamp;
611
612 if (parsed_frame.second_field) {
613 if (
ctx->prev_pts == INT64_MIN) {
616 } else {
617 int pts_diff = (
frame->pts -
ctx->prev_pts) / 2;
619 frame->pts += pts_diff;
620 }
621 }
622
623 /* CUVIDs opaque reordering breaks the internal pkt logic.
624 * So set pkt_pts and clear all the other pkt_ fields.
625 */
627 frame->pkt_duration = 0;
628 frame->pkt_size = -1;
629
630 frame->interlaced_frame = !parsed_frame.is_deinterlacing && !parsed_frame.dispinfo.progressive_frame;
631
632 if (
frame->interlaced_frame)
633 frame->top_field_first = parsed_frame.dispinfo.top_field_first;
634 }
else if (
ctx->decoder_flushing) {
636 } else {
638 }
639
643
644 if (mapped_frame)
645 eret =
CHECK_CU(
ctx->cvdl->cuvidUnmapVideoFrame(
ctx->cudecoder, mapped_frame));
646
648
649 if (eret < 0)
650 return eret;
651 else
653 }
654
656 {
660 CUcontext
dummy, cuda_ctx = device_hwctx ? device_hwctx->cuda_ctx :
NULL;
661
663
664 if (cuda_ctx) {
665 ctx->cudl->cuCtxPushCurrent(cuda_ctx);
666
668 ctx->cvdl->cuvidDestroyVideoParser(
ctx->cuparser);
669
671 ctx->cvdl->cuvidDestroyDecoder(
ctx->cudecoder);
672
674 }
675
677
680
683
684 cuvid_free_functions(&
ctx->cvdl);
685
686 return 0;
687 }
688
690 const CUVIDPARSERPARAMS *cuparseinfo,
691 int probed_width,
692 int probed_height,
694 {
696 CUVIDDECODECAPS *caps;
697 int res8 = 0, res10 = 0, res12 = 0;
698
699 if (!
ctx->cvdl->cuvidGetDecoderCaps) {
700 av_log(avctx,
AV_LOG_WARNING,
"Used Nvidia driver is too old to perform a capability check.\n");
702 #if defined(_WIN32) || defined(__CYGWIN__)
703 "378.66"
704 #else
705 "378.13"
706 #endif
707 ". Continuing blind.\n");
708 ctx->caps8.bIsSupported =
ctx->caps10.bIsSupported = 1;
709 // 12 bit was not supported before the capability check was introduced, so disable it.
710 ctx->caps12.bIsSupported = 0;
711 return 0;
712 }
713
714 ctx->caps8.eCodecType =
ctx->caps10.eCodecType =
ctx->caps12.eCodecType
715 = cuparseinfo->CodecType;
716 ctx->caps8.eChromaFormat =
ctx->caps10.eChromaFormat =
ctx->caps12.eChromaFormat
717 = cudaVideoChromaFormat_420;
718
719 ctx->caps8.nBitDepthMinus8 = 0;
720 ctx->caps10.nBitDepthMinus8 = 2;
721 ctx->caps12.nBitDepthMinus8 = 4;
722
726
728 av_log(avctx,
AV_LOG_VERBOSE,
"8 bit: supported: %d, min_width: %d, max_width: %d, min_height: %d, max_height: %d\n",
729 ctx->caps8.bIsSupported,
ctx->caps8.nMinWidth,
ctx->caps8.nMaxWidth,
ctx->caps8.nMinHeight,
ctx->caps8.nMaxHeight);
730 av_log(avctx,
AV_LOG_VERBOSE,
"10 bit: supported: %d, min_width: %d, max_width: %d, min_height: %d, max_height: %d\n",
731 ctx->caps10.bIsSupported,
ctx->caps10.nMinWidth,
ctx->caps10.nMaxWidth,
ctx->caps10.nMinHeight,
ctx->caps10.nMaxHeight);
732 av_log(avctx,
AV_LOG_VERBOSE,
"12 bit: supported: %d, min_width: %d, max_width: %d, min_height: %d, max_height: %d\n",
733 ctx->caps12.bIsSupported,
ctx->caps12.nMinWidth,
ctx->caps12.nMaxWidth,
ctx->caps12.nMinHeight,
ctx->caps12.nMaxHeight);
734
736 case 10:
738 if (res10 < 0)
739 return res10;
740 break;
741 case 12:
743 if (res12 < 0)
744 return res12;
745 break;
746 default:
748 if (res8 < 0)
749 return res8;
750 }
751
752 if (!
ctx->caps8.bIsSupported) {
755 }
756
757 if (!caps->bIsSupported) {
760 }
761
762 if (probed_width > caps->nMaxWidth || probed_width < caps->nMinWidth) {
764 probed_width, caps->nMinWidth, caps->nMaxWidth);
766 }
767
768 if (probed_height > caps->nMaxHeight || probed_height < caps->nMinHeight) {
770 probed_height, caps->nMinHeight, caps->nMaxHeight);
772 }
773
774 if ((probed_width * probed_height) / 256 > caps->nMaxMBCount) {
776 (int)(probed_width * probed_height) / 256, caps->nMaxMBCount);
778 }
779
780 return 0;
781 }
782
784 {
789 CUVIDSOURCEDATAPACKET seq_pkt;
790 CUcontext cuda_ctx =
NULL;
792 uint8_t *extradata;
793 int extradata_size;
795
799
802 int probed_bit_depth = 8;
803
806 probed_bit_depth = probe_desc->
comp[0].
depth;
807
809 // Accelerated transcoding scenarios with 'ffmpeg' require that the
810 // pix_fmt be set to AV_PIX_FMT_CUDA early. The sw_pix_fmt, and the
811 // pix_fmt for non-accelerated transcoding, do not need to be correct
812 // but need to be set to something. We arbitrarily pick NV12.
817 }
819
820 if (
ctx->resize_expr && sscanf(
ctx->resize_expr,
"%dx%d",
821 &
ctx->resize.width, &
ctx->resize.height) != 2) {
825 }
826
827 if (
ctx->crop_expr && sscanf(
ctx->crop_expr,
"%dx%dx%dx%d",
828 &
ctx->crop.top, &
ctx->crop.bottom,
829 &
ctx->crop.left, &
ctx->crop.right) != 4) {
833 }
834
835 ret = cuvid_load_functions(&
ctx->cvdl, avctx);
839 }
840
842 if (!
ctx->frame_queue) {
845 }
846
852 }
853
855
857 if (!
ctx->hwdevice) {
860 }
861 } else {
864 if (!
ctx->hwdevice) {
867 }
868 } else {
872 }
873
879 }
880
882 }
883
885 device_hwctx = device_ctx->
hwctx;
886
889
890 memset(&
ctx->cuparseinfo, 0,
sizeof(
ctx->cuparseinfo));
891 memset(&seq_pkt, 0, sizeof(seq_pkt));
892
894 #if CONFIG_H264_CUVID_DECODER
896 ctx->cuparseinfo.CodecType = cudaVideoCodec_H264;
897 break;
898 #endif
899 #if CONFIG_HEVC_CUVID_DECODER
901 ctx->cuparseinfo.CodecType = cudaVideoCodec_HEVC;
902 break;
903 #endif
904 #if CONFIG_MJPEG_CUVID_DECODER
906 ctx->cuparseinfo.CodecType = cudaVideoCodec_JPEG;
907 break;
908 #endif
909 #if CONFIG_MPEG1_CUVID_DECODER
911 ctx->cuparseinfo.CodecType = cudaVideoCodec_MPEG1;
912 break;
913 #endif
914 #if CONFIG_MPEG2_CUVID_DECODER
916 ctx->cuparseinfo.CodecType = cudaVideoCodec_MPEG2;
917 break;
918 #endif
919 #if CONFIG_MPEG4_CUVID_DECODER
921 ctx->cuparseinfo.CodecType = cudaVideoCodec_MPEG4;
922 break;
923 #endif
924 #if CONFIG_VP8_CUVID_DECODER
926 ctx->cuparseinfo.CodecType = cudaVideoCodec_VP8;
927 break;
928 #endif
929 #if CONFIG_VP9_CUVID_DECODER
931 ctx->cuparseinfo.CodecType = cudaVideoCodec_VP9;
932 break;
933 #endif
934 #if CONFIG_VC1_CUVID_DECODER
936 ctx->cuparseinfo.CodecType = cudaVideoCodec_VC1;
937 break;
938 #endif
939 #if CONFIG_AV1_CUVID_DECODER && defined(CUVID_HAS_AV1_SUPPORT)
941 ctx->cuparseinfo.CodecType = cudaVideoCodec_AV1;
942 break;
943 #endif
944 default:
947 }
948
953 } else {
956 }
957
958 // Check first bit to determine whether it's AV1CodecConfigurationRecord.
959 // Skip first 4 bytes of AV1CodecConfigurationRecord to keep configOBUs
960 // only, otherwise cuvidParseVideoData report unknown error.
962 extradata_size > 4 &&
963 extradata[0] & 0x80) {
964 extradata += 4;
965 extradata_size -= 4;
966 }
967
969 +
FFMAX(extradata_size - (
int)
sizeof(
ctx->cuparse_ext->raw_seqhdr_data), 0));
970 if (!
ctx->cuparse_ext) {
973 }
974
975 if (extradata_size > 0)
976 memcpy(
ctx->cuparse_ext->raw_seqhdr_data, extradata, extradata_size);
977 ctx->cuparse_ext->format.seqhdr_data_length = extradata_size;
978
979 ctx->cuparseinfo.pExtVideoInfo =
ctx->cuparse_ext;
980
982 if (!
ctx->key_frame) {
985 }
986
987 ctx->cuparseinfo.ulMaxNumDecodeSurfaces =
ctx->nb_surfaces;
989 ctx->cuparseinfo.pUserData = avctx;
993
997
999 probed_width,
1000 probed_height,
1001 probed_bit_depth);
1004
1008
1009 seq_pkt.payload =
ctx->cuparse_ext->raw_seqhdr_data;
1010 seq_pkt.payload_size =
ctx->cuparse_ext->format.seqhdr_data_length;
1011
1012 if (seq_pkt.payload && seq_pkt.payload_size) {
1016 }
1017
1021
1022 ctx->prev_pts = INT64_MIN;
1023
1026
1027 return 0;
1028
1032 }
1033
1035 {
1039 CUcontext
dummy, cuda_ctx = device_hwctx->cuda_ctx;
1040 CUVIDSOURCEDATAPACKET seq_pkt = { 0 };
1042
1046
1048
1049 if (
ctx->cudecoder) {
1050 ctx->cvdl->cuvidDestroyDecoder(
ctx->cudecoder);
1052 }
1053
1054 if (
ctx->cuparser) {
1055 ctx->cvdl->cuvidDestroyVideoParser(
ctx->cuparser);
1057 }
1058
1062
1063 seq_pkt.payload =
ctx->cuparse_ext->raw_seqhdr_data;
1064 seq_pkt.payload_size =
ctx->cuparse_ext->format.seqhdr_data_length;
1065
1066 if (seq_pkt.payload && seq_pkt.payload_size) {
1070 }
1071
1075
1076 ctx->prev_pts = INT64_MIN;
1077 ctx->decoder_flushing = 0;
1078
1079 return;
1082 }
1083
1084 #define OFFSET(x) offsetof(CuvidContext, x)
1085 #define VD AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM
1087 {
"deint",
"Set deinterlacing mode",
OFFSET(deint_mode),
AV_OPT_TYPE_INT, { .i64 = cudaVideoDeinterlaceMode_Weave }, cudaVideoDeinterlaceMode_Weave, cudaVideoDeinterlaceMode_Adaptive,
VD,
"deint" },
1088 {
"weave",
"Weave deinterlacing (do nothing)", 0,
AV_OPT_TYPE_CONST, { .i64 = cudaVideoDeinterlaceMode_Weave }, 0, 0,
VD,
"deint" },
1089 {
"bob",
"Bob deinterlacing", 0,
AV_OPT_TYPE_CONST, { .i64 = cudaVideoDeinterlaceMode_Bob }, 0, 0,
VD,
"deint" },
1090 {
"adaptive",
"Adaptive deinterlacing", 0,
AV_OPT_TYPE_CONST, { .i64 = cudaVideoDeinterlaceMode_Adaptive }, 0, 0,
VD,
"deint" },
1092 {
"surfaces",
"Maximum surfaces to be used for decoding",
OFFSET(nb_surfaces),
AV_OPT_TYPE_INT, { .i64 = 25 }, 0, INT_MAX,
VD },
1093 {
"drop_second_field",
"Drop second field when deinterlacing",
OFFSET(drop_second_field),
AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1,
VD },
1097 };
1098
1106 },
1108 },
1110 };
1111
1112 #define DEFINE_CUVID_CODEC(x, X, bsf_name) \
1113 static const AVClass x##_cuvid_class = { \
1114 .class_name = #x "_cuvid", \
1115 .item_name = av_default_item_name, \
1116 .option = options, \
1117 .version = LIBAVUTIL_VERSION_INT, \
1118 }; \
1119 const FFCodec ff_##x##_cuvid_decoder = { \
1120 .p.name = #x "_cuvid", \
1121 .p.long_name = NULL_IF_CONFIG_SMALL("Nvidia CUVID " #X " decoder"), \
1122 .p.type = AVMEDIA_TYPE_VIDEO, \
1123 .p.id = AV_CODEC_ID_##X, \
1124 .priv_data_size = sizeof(CuvidContext), \
1125 .p.priv_class = &x##_cuvid_class, \
1126 .init = cuvid_decode_init, \
1127 .close = cuvid_decode_end, \
1128 FF_CODEC_RECEIVE_FRAME_CB(cuvid_output_frame), \
1129 .flush = cuvid_flush, \
1130 .bsfs = bsf_name, \
1131 .p.capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_AVOID_PROBING | AV_CODEC_CAP_HARDWARE, \
1132 .caps_internal = FF_CODEC_CAP_SETS_FRAME_PROPS, \
1133 .p.pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_CUDA, \
1134 AV_PIX_FMT_NV12, \
1135 AV_PIX_FMT_P010, \
1136 AV_PIX_FMT_P016, \
1137 AV_PIX_FMT_NONE }, \
1138 .hw_configs = cuvid_hw_configs, \
1139 .p.wrapper_name = "cuvid", \
1140 };
1141
1142 #if CONFIG_AV1_CUVID_DECODER && defined(CUVID_HAS_AV1_SUPPORT)
1144 #endif
1145
1146 #if CONFIG_HEVC_CUVID_DECODER
1148 #endif
1149
1150 #if CONFIG_H264_CUVID_DECODER
1152 #endif
1153
1154 #if CONFIG_MJPEG_CUVID_DECODER
1156 #endif
1157
1158 #if CONFIG_MPEG1_CUVID_DECODER
1160 #endif
1161
1162 #if CONFIG_MPEG2_CUVID_DECODER
1164 #endif
1165
1166 #if CONFIG_MPEG4_CUVID_DECODER
1168 #endif
1169
1170 #if CONFIG_VP8_CUVID_DECODER
1172 #endif
1173
1174 #if CONFIG_VP9_CUVID_DECODER
1176 #endif
1177
1178 #if CONFIG_VC1_CUVID_DECODER
1180 #endif