40 #if !NVDECAPI_CHECK_VERSION(9, 0)
41 #define cudaVideoSurfaceFormat_YUV444 2
42 #define cudaVideoSurfaceFormat_YUV444_16Bit 3
104 #define CHECK_CU(x) FF_CUDA_CHECK_DL(avctx, ctx->cudl, x)
111 CUVIDDECODECAPS *caps =
NULL;
112 CUVIDDECODECREATEINFO cuinfo;
116 int old_width = avctx->
width;
117 int old_height = avctx->
height;
125 memset(&cuinfo, 0,
sizeof(cuinfo));
127 ctx->internal_error = 0;
129 avctx->coded_width = cuinfo.ulWidth =
format->coded_width;
130 avctx->coded_height = cuinfo.ulHeight =
format->coded_height;
133 cuinfo.display_area.left =
format->display_area.left +
ctx->crop.left;
134 cuinfo.display_area.top =
format->display_area.top +
ctx->crop.top;
135 cuinfo.display_area.right =
format->display_area.right -
ctx->crop.right;
136 cuinfo.display_area.bottom =
format->display_area.bottom -
ctx->crop.bottom;
139 if (
ctx->resize_expr) {
140 avctx->width =
ctx->resize.width;
141 avctx->height =
ctx->resize.height;
143 avctx->width = cuinfo.display_area.right - cuinfo.display_area.left;
144 avctx->height = cuinfo.display_area.bottom - cuinfo.display_area.top;
148 cuinfo.ulTargetWidth = avctx->width = (avctx->width + 1) & ~1;
149 cuinfo.ulTargetHeight = avctx->height = (avctx->height + 1) & ~1;
152 cuinfo.target_rect.left = 0;
153 cuinfo.target_rect.top = 0;
154 cuinfo.target_rect.right = cuinfo.ulTargetWidth;
155 cuinfo.target_rect.bottom = cuinfo.ulTargetHeight;
157 chroma_444 =
format->chroma_format == cudaVideoChromaFormat_444;
159 switch (
format->bit_depth_luma_minus8) {
176 if (!caps || !caps->bIsSupported) {
178 format->bit_depth_luma_minus8 + 8);
184 if (surface_fmt < 0) {
195 avctx->pix_fmt = surface_fmt;
198 if (avctx->hw_frames_ctx) {
214 ctx->deint_mode_current =
format->progressive_sequence
215 ? cudaVideoDeinterlaceMode_Weave
218 ctx->progressive_sequence =
format->progressive_sequence;
220 if (!
format->progressive_sequence &&
ctx->deint_mode_current == cudaVideoDeinterlaceMode_Weave)
225 if (
format->video_signal_description.video_full_range_flag)
231 avctx->color_trc =
format->video_signal_description.transfer_characteristics;
235 avctx->bit_rate =
format->bitrate;
237 if (
format->frame_rate.numerator &&
format->frame_rate.denominator) {
238 avctx->framerate.num =
format->frame_rate.numerator;
239 avctx->framerate.den =
format->frame_rate.denominator;
243 && avctx->coded_width ==
format->coded_width
244 && avctx->coded_height ==
format->coded_height
245 && avctx->
width == old_width
246 && avctx->height == old_height
247 &&
ctx->chroma_format ==
format->chroma_format
251 if (
ctx->cudecoder) {
254 if (
ctx->internal_error < 0)
259 if (hwframe_ctx->pool && (
260 hwframe_ctx->width < avctx->width ||
261 hwframe_ctx->height < avctx->height ||
263 hwframe_ctx->sw_format != avctx->sw_pix_fmt)) {
264 av_log(avctx,
AV_LOG_ERROR,
"AVHWFramesContext is already initialized with incompatible parameters\n");
266 av_log(avctx,
AV_LOG_DEBUG,
"height: %d <-> %d\n", hwframe_ctx->height, avctx->height);
274 ctx->chroma_format =
format->chroma_format;
276 cuinfo.CodecType =
ctx->codec_type =
format->codec;
277 cuinfo.ChromaFormat =
format->chroma_format;
279 switch (avctx->sw_pix_fmt) {
281 cuinfo.OutputFormat = cudaVideoSurfaceFormat_NV12;
285 cuinfo.OutputFormat = cudaVideoSurfaceFormat_P016;
300 cuinfo.ulNumDecodeSurfaces =
ctx->nb_surfaces;
301 cuinfo.ulNumOutputSurfaces = 1;
302 cuinfo.ulCreationFlags = cudaVideoCreate_PreferCUVID;
303 cuinfo.bitDepthMinus8 =
format->bit_depth_luma_minus8;
304 cuinfo.DeinterlaceMode =
ctx->deint_mode_current;
306 if (
ctx->deint_mode_current != cudaVideoDeinterlaceMode_Weave && !
ctx->drop_second_field)
309 ctx->internal_error =
CHECK_CU(
ctx->cvdl->cuvidCreateDecoder(&
ctx->cudecoder, &cuinfo));
310 if (
ctx->internal_error < 0)
313 if (!hwframe_ctx->pool) {
315 hwframe_ctx->sw_format = avctx->sw_pix_fmt;
316 hwframe_ctx->width = avctx->width;
317 hwframe_ctx->height = avctx->height;
335 ctx->key_frame[picparams->CurrPicIdx] = picparams->intra_pic_flag;
337 ctx->internal_error =
CHECK_CU(
ctx->cvdl->cuvidDecodePicture(
ctx->cudecoder, picparams));
338 if (
ctx->internal_error < 0)
351 ctx->internal_error = 0;
354 parsed_frame.
dispinfo.progressive_frame =
ctx->progressive_sequence;
356 if (
ctx->deint_mode_current == cudaVideoDeinterlaceMode_Weave) {
361 if (!
ctx->drop_second_field) {
374 int delay =
ctx->cuparseinfo.ulMaxDisplayDelay;
375 if (
ctx->deint_mode != cudaVideoDeinterlaceMode_Weave && !
ctx->drop_second_field)
386 CUcontext
dummy, cuda_ctx = device_hwctx->cuda_ctx;
387 CUVIDSOURCEDATAPACKET cupkt;
388 int ret = 0, eret = 0, is_flush =
ctx->decoder_flushing;
392 if (is_flush && avpkt && avpkt->
size)
403 memset(&cupkt, 0,
sizeof(cupkt));
405 if (avpkt && avpkt->
size) {
406 cupkt.payload_size = avpkt->
size;
407 cupkt.payload = avpkt->
data;
410 cupkt.flags = CUVID_PKT_TIMESTAMP;
414 cupkt.timestamp = avpkt->
pts;
417 cupkt.flags = CUVID_PKT_ENDOFSTREAM;
418 ctx->decoder_flushing = 1;
427 if (
ctx->internal_error) {
429 ret =
ctx->internal_error;
451 CUcontext
dummy, cuda_ctx = device_hwctx->cuda_ctx;
452 CUdeviceptr mapped_frame = 0;
453 int ret = 0, eret = 0;
457 if (
ctx->decoder_flushing) {
484 CUVIDPROCPARAMS params;
485 unsigned int pitch = 0;
491 memset(¶ms, 0,
sizeof(params));
492 params.progressive_frame = parsed_frame.
dispinfo.progressive_frame;
494 params.top_field_first = parsed_frame.
dispinfo.top_field_first;
496 ret =
CHECK_CU(
ctx->cvdl->cuvidMapVideoFrame(
ctx->cudecoder, parsed_frame.
dispinfo.picture_index, &mapped_frame, &pitch, ¶ms));
517 CUDA_MEMCPY2D cpy = {
518 .srcMemoryType = CU_MEMORYTYPE_DEVICE,
519 .dstMemoryType = CU_MEMORYTYPE_DEVICE,
520 .srcDevice = mapped_frame,
521 .dstDevice = (CUdeviceptr)
frame->data[
i],
523 .dstPitch =
frame->linesize[
i],
529 ret =
CHECK_CU(
ctx->cudl->cuMemcpy2DAsync(&cpy, device_hwctx->stream));
594 if (
ctx->prev_pts == INT64_MIN) {
598 int pts_diff = (
frame->pts -
ctx->prev_pts) / 2;
600 frame->pts += pts_diff;
613 frame->pkt_duration = 0;
614 frame->pkt_size = -1;
618 if (
frame->interlaced_frame)
619 frame->top_field_first = parsed_frame.
dispinfo.top_field_first;
620 }
else if (
ctx->decoder_flushing) {
628 eret =
CHECK_CU(
ctx->cvdl->cuvidUnmapVideoFrame(
ctx->cudecoder, mapped_frame));
646 if (
ctx->deint_mode_current != cudaVideoDeinterlaceMode_Weave) {
651 if (!
ctx->decoder_flushing) {
660 }
else if (
ret < 0) {
676 ctx->cvdl->cuvidDestroyVideoParser(
ctx->cuparser);
679 ctx->cvdl->cuvidDestroyDecoder(
ctx->cudecoder);
689 cuvid_free_functions(&
ctx->cvdl);
695 const CUVIDPARSERPARAMS *cuparseinfo,
701 CUVIDDECODECAPS *caps;
702 int res8 = 0, res10 = 0, res12 = 0;
704 if (!
ctx->cvdl->cuvidGetDecoderCaps) {
705 av_log(avctx,
AV_LOG_WARNING,
"Used Nvidia driver is too old to perform a capability check.\n");
707 #
if defined(_WIN32) || defined(__CYGWIN__)
712 ". Continuing blind.\n");
713 ctx->caps8.bIsSupported =
ctx->caps10.bIsSupported = 1;
715 ctx->caps12.bIsSupported = 0;
719 ctx->caps8.eCodecType =
ctx->caps10.eCodecType =
ctx->caps12.eCodecType
720 = cuparseinfo->CodecType;
721 ctx->caps8.eChromaFormat =
ctx->caps10.eChromaFormat =
ctx->caps12.eChromaFormat
722 = cudaVideoChromaFormat_420;
724 ctx->caps8.nBitDepthMinus8 = 0;
725 ctx->caps10.nBitDepthMinus8 = 2;
726 ctx->caps12.nBitDepthMinus8 = 4;
733 av_log(avctx,
AV_LOG_VERBOSE,
"8 bit: supported: %d, min_width: %d, max_width: %d, min_height: %d, max_height: %d\n",
734 ctx->caps8.bIsSupported,
ctx->caps8.nMinWidth,
ctx->caps8.nMaxWidth,
ctx->caps8.nMinHeight,
ctx->caps8.nMaxHeight);
735 av_log(avctx,
AV_LOG_VERBOSE,
"10 bit: supported: %d, min_width: %d, max_width: %d, min_height: %d, max_height: %d\n",
736 ctx->caps10.bIsSupported,
ctx->caps10.nMinWidth,
ctx->caps10.nMaxWidth,
ctx->caps10.nMinHeight,
ctx->caps10.nMaxHeight);
737 av_log(avctx,
AV_LOG_VERBOSE,
"12 bit: supported: %d, min_width: %d, max_width: %d, min_height: %d, max_height: %d\n",
738 ctx->caps12.bIsSupported,
ctx->caps12.nMinWidth,
ctx->caps12.nMaxWidth,
ctx->caps12.nMinHeight,
ctx->caps12.nMaxHeight);
757 if (!
ctx->caps8.bIsSupported) {
762 if (!caps->bIsSupported) {
767 if (probed_width > caps->nMaxWidth || probed_width < caps->nMinWidth) {
769 probed_width, caps->nMinWidth, caps->nMaxWidth);
773 if (probed_height > caps->nMaxHeight || probed_height < caps->nMinHeight) {
775 probed_height, caps->nMinHeight, caps->nMaxHeight);
779 if ((probed_width * probed_height) / 256 > caps->nMaxMBCount) {
781 (
int)(probed_width * probed_height) / 256, caps->nMaxMBCount);
794 CUVIDSOURCEDATAPACKET seq_pkt;
795 CUcontext cuda_ctx =
NULL;
807 int probed_bit_depth = 8;
811 probed_bit_depth = probe_desc->
comp[0].
depth;
824 if (
ctx->resize_expr && sscanf(
ctx->resize_expr,
"%dx%d",
825 &
ctx->resize.width, &
ctx->resize.height) != 2) {
831 if (
ctx->crop_expr && sscanf(
ctx->crop_expr,
"%dx%dx%dx%d",
832 &
ctx->crop.top, &
ctx->crop.bottom,
833 &
ctx->crop.left, &
ctx->crop.right) != 4) {
839 ret = cuvid_load_functions(&
ctx->cvdl, avctx);
846 if (!
ctx->frame_queue) {
861 if (!
ctx->hwdevice) {
868 if (!
ctx->hwdevice) {
889 device_hwctx = device_ctx->
hwctx;
894 memset(&
ctx->cuparseinfo, 0,
sizeof(
ctx->cuparseinfo));
895 memset(&seq_pkt, 0,
sizeof(seq_pkt));
898 #if CONFIG_H264_CUVID_DECODER
900 ctx->cuparseinfo.CodecType = cudaVideoCodec_H264;
903 #if CONFIG_HEVC_CUVID_DECODER
905 ctx->cuparseinfo.CodecType = cudaVideoCodec_HEVC;
908 #if CONFIG_MJPEG_CUVID_DECODER
910 ctx->cuparseinfo.CodecType = cudaVideoCodec_JPEG;
913 #if CONFIG_MPEG1_CUVID_DECODER
915 ctx->cuparseinfo.CodecType = cudaVideoCodec_MPEG1;
918 #if CONFIG_MPEG2_CUVID_DECODER
920 ctx->cuparseinfo.CodecType = cudaVideoCodec_MPEG2;
923 #if CONFIG_MPEG4_CUVID_DECODER
925 ctx->cuparseinfo.CodecType = cudaVideoCodec_MPEG4;
928 #if CONFIG_VP8_CUVID_DECODER
930 ctx->cuparseinfo.CodecType = cudaVideoCodec_VP8;
933 #if CONFIG_VP9_CUVID_DECODER
935 ctx->cuparseinfo.CodecType = cudaVideoCodec_VP9;
938 #if CONFIG_VC1_CUVID_DECODER
940 ctx->cuparseinfo.CodecType = cudaVideoCodec_VC1;
958 +
FFMAX(extradata_size - (
int)
sizeof(
ctx->cuparse_ext->raw_seqhdr_data), 0));
959 if (!
ctx->cuparse_ext) {
964 if (extradata_size > 0)
965 memcpy(
ctx->cuparse_ext->raw_seqhdr_data, extradata, extradata_size);
966 ctx->cuparse_ext->format.seqhdr_data_length = extradata_size;
968 ctx->cuparseinfo.pExtVideoInfo =
ctx->cuparse_ext;
971 if (!
ctx->key_frame) {
976 ctx->cuparseinfo.ulMaxNumDecodeSurfaces =
ctx->nb_surfaces;
977 ctx->cuparseinfo.ulMaxDisplayDelay = 4;
978 ctx->cuparseinfo.pUserData = avctx;
998 seq_pkt.payload =
ctx->cuparse_ext->raw_seqhdr_data;
999 seq_pkt.payload_size =
ctx->cuparse_ext->format.seqhdr_data_length;
1001 if (seq_pkt.payload && seq_pkt.payload_size) {
1011 ctx->prev_pts = INT64_MIN;
1028 CUcontext
dummy, cuda_ctx = device_hwctx->cuda_ctx;
1029 CUVIDSOURCEDATAPACKET seq_pkt = { 0 };
1039 if (!
ctx->frame_queue) {
1044 if (
ctx->cudecoder) {
1045 ctx->cvdl->cuvidDestroyDecoder(
ctx->cudecoder);
1049 if (
ctx->cuparser) {
1050 ctx->cvdl->cuvidDestroyVideoParser(
ctx->cuparser);
1058 seq_pkt.payload =
ctx->cuparse_ext->raw_seqhdr_data;
1059 seq_pkt.payload_size =
ctx->cuparse_ext->format.seqhdr_data_length;
1061 if (seq_pkt.payload && seq_pkt.payload_size) {
1071 ctx->prev_pts = INT64_MIN;
1072 ctx->decoder_flushing = 0;
1079 #define OFFSET(x) offsetof(CuvidContext, x)
1080 #define VD AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM
1082 {
"deint",
"Set deinterlacing mode",
OFFSET(deint_mode),
AV_OPT_TYPE_INT, { .i64 = cudaVideoDeinterlaceMode_Weave }, cudaVideoDeinterlaceMode_Weave, cudaVideoDeinterlaceMode_Adaptive,
VD,
"deint" },
1083 {
"weave",
"Weave deinterlacing (do nothing)", 0,
AV_OPT_TYPE_CONST, { .i64 = cudaVideoDeinterlaceMode_Weave }, 0, 0,
VD,
"deint" },
1084 {
"bob",
"Bob deinterlacing", 0,
AV_OPT_TYPE_CONST, { .i64 = cudaVideoDeinterlaceMode_Bob }, 0, 0,
VD,
"deint" },
1085 {
"adaptive",
"Adaptive deinterlacing", 0,
AV_OPT_TYPE_CONST, { .i64 = cudaVideoDeinterlaceMode_Adaptive }, 0, 0,
VD,
"deint" },
1087 {
"surfaces",
"Maximum surfaces to be used for decoding",
OFFSET(nb_surfaces),
AV_OPT_TYPE_INT, { .i64 = 25 }, 0, INT_MAX,
VD },
1088 {
"drop_second_field",
"Drop second field when deinterlacing",
OFFSET(drop_second_field),
AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1,
VD },
1107 #define DEFINE_CUVID_CODEC(x, X, bsf_name) \
1108 static const AVClass x##_cuvid_class = { \
1109 .class_name = #x "_cuvid", \
1110 .item_name = av_default_item_name, \
1111 .option = options, \
1112 .version = LIBAVUTIL_VERSION_INT, \
1114 AVCodec ff_##x##_cuvid_decoder = { \
1115 .name = #x "_cuvid", \
1116 .long_name = NULL_IF_CONFIG_SMALL("Nvidia CUVID " #X " decoder"), \
1117 .type = AVMEDIA_TYPE_VIDEO, \
1118 .id = AV_CODEC_ID_##X, \
1119 .priv_data_size = sizeof(CuvidContext), \
1120 .priv_class = &x##_cuvid_class, \
1121 .init = cuvid_decode_init, \
1122 .close = cuvid_decode_end, \
1123 .decode = cuvid_decode_frame, \
1124 .receive_frame = cuvid_output_frame, \
1125 .flush = cuvid_flush, \
1127 .capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_AVOID_PROBING | AV_CODEC_CAP_HARDWARE, \
1128 .pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_CUDA, \
1132 AV_PIX_FMT_NONE }, \
1133 .hw_configs = cuvid_hw_configs, \
1134 .wrapper_name = "cuvid", \
1137 #if CONFIG_HEVC_CUVID_DECODER
1141 #if CONFIG_H264_CUVID_DECODER
1145 #if CONFIG_MJPEG_CUVID_DECODER
1149 #if CONFIG_MPEG1_CUVID_DECODER
1153 #if CONFIG_MPEG2_CUVID_DECODER
1157 #if CONFIG_MPEG4_CUVID_DECODER
1161 #if CONFIG_VP8_CUVID_DECODER
1165 #if CONFIG_VP9_CUVID_DECODER
1169 #if CONFIG_VC1_CUVID_DECODER