22 #include "config_components.h"
24 #include <stdatomic.h>
47 #if !NVDECAPI_CHECK_VERSION(9, 0)
48 #define cudaVideoSurfaceFormat_YUV444 2
49 #define cudaVideoSurfaceFormat_YUV444_16Bit 3
52 #if NVDECAPI_CHECK_VERSION(11, 0)
53 #define CUVID_HAS_AV1_SUPPORT
56 #ifdef NVDEC_HAVE_OPAQUE_OUTPUT_SUPPORT
57 typedef struct CuvidDecoderCleanup {
58 CUvideodecoder cudecoder;
59 CUarray *cuarray_surfaces;
60 int cuarray_num_surfaces;
63 } CuvidDecoderCleanup;
126 #ifdef NVDEC_HAVE_OPAQUE_OUTPUT_SUPPORT
127 CUarray *cuarray_surfaces;
128 int cuarray_num_surfaces;
131 CuvidDecoderCleanup *decoder_cleanup;
142 #define CHECK_CU(x) FF_CUDA_CHECK_DL(avctx, ctx->cudl, x)
145 #define CUVID_MAX_DISPLAY_DELAY (4)
148 #define CUVID_DEFAULT_NUM_SURFACES (CUVID_MAX_DISPLAY_DELAY + 1)
160 "zero_copy requires cuarray output format; "
161 "overriding -output_format %s -> cuarray\n",
170 #ifdef NVDEC_HAVE_OPAQUE_OUTPUT_SUPPORT
174 "CUARRAY output requires Video Codec SDK 13.1 or later\n");
179 "Unsupported cuvid output format: %s\n",
198 #ifdef NVDEC_HAVE_OPAQUE_OUTPUT_SUPPORT
199 typedef struct CuvidSurfaceRelease {
202 } CuvidSurfaceRelease;
204 static void cuvid_cuarray_buf_free(
void *opaque, uint8_t *
data)
206 CuvidSurfaceRelease *rel = opaque;
213 static void cuvid_decoder_cleanup_free(
void *opaque, uint8_t *
data)
215 CuvidDecoderCleanup *
cleanup = opaque;
220 CudaFunctions *cudl = device_hwctx->internal->cuda_dl;
223 cudl->cuCtxPushCurrent(device_hwctx->cuda_ctx);
228 if (
cleanup->cuarray_surfaces) {
229 for (
int i = 0;
i <
cleanup->cuarray_num_surfaces;
i++)
230 cudl->cuArrayDestroy(
cleanup->cuarray_surfaces[
i]);
233 cudl->cuCtxPopCurrent(&
dummy);
239 cuvid_free_functions(&
cleanup->cvdl);
253 CUVIDDECODECAPS *caps =
NULL;
254 CUVIDDECODECREATEINFO cuinfo;
257 int old_nb_surfaces, fifo_size_inc, fifo_size_mul = 1;
260 int old_width = avctx->
width;
261 int old_height = avctx->
height;
267 memset(&cuinfo, 0,
sizeof(cuinfo));
269 ctx->internal_error = 0;
272 if (surface_fmt < 0) {
273 ctx->internal_error = surface_fmt;
281 cuinfo.display_area.left =
format->display_area.left +
ctx->crop.left;
282 cuinfo.display_area.top =
format->display_area.top +
ctx->crop.top;
283 cuinfo.display_area.right =
format->display_area.right -
ctx->crop.right;
284 cuinfo.display_area.bottom =
format->display_area.bottom -
ctx->crop.bottom;
287 if (
ctx->resize_expr) {
291 avctx->
width = cuinfo.display_area.right - cuinfo.display_area.left;
292 avctx->
height = cuinfo.display_area.bottom - cuinfo.display_area.top;
299 cuinfo.ulTargetWidth = (avctx->
width + 1) & ~1;
300 cuinfo.ulTargetHeight = (avctx->
height + 1) & ~1;
301 if (
format->chroma_format == cudaVideoChromaFormat_420 ||
302 format->chroma_format == cudaVideoChromaFormat_422) {
303 avctx->
width = cuinfo.ulTargetWidth;
304 avctx->
height = cuinfo.ulTargetHeight;
308 cuinfo.target_rect.left = 0;
309 cuinfo.target_rect.top = 0;
310 cuinfo.target_rect.right = cuinfo.ulTargetWidth;
311 cuinfo.target_rect.bottom = cuinfo.ulTargetHeight;
313 chroma_444 =
format->chroma_format == cudaVideoChromaFormat_444;
315 switch (
format->bit_depth_luma_minus8) {
319 #ifdef NVDEC_HAVE_422_SUPPORT
320 }
else if (
format->chroma_format == cudaVideoChromaFormat_422) {
331 #ifdef NVDEC_HAVE_422_SUPPORT
332 }
else if (
format->chroma_format == cudaVideoChromaFormat_422) {
343 #ifdef NVDEC_HAVE_422_SUPPORT
344 }
else if (
format->chroma_format == cudaVideoChromaFormat_422) {
356 if (!caps || !caps->bIsSupported) {
358 format->bit_depth_luma_minus8 + 8);
366 if (surface_fmt < 0) {
374 "ff_get_format returned %s, overriding to %s\n",
377 surface_fmt = requested_hw_format;
388 if (
ctx->opaque_output) {
414 ctx->deint_mode_current =
format->progressive_sequence
415 ? cudaVideoDeinterlaceMode_Weave
418 ctx->progressive_sequence =
format->progressive_sequence;
420 if (!
format->progressive_sequence &&
ctx->deint_mode_current == cudaVideoDeinterlaceMode_Weave)
425 if (
format->video_signal_description.video_full_range_flag)
430 if (
format->video_signal_description.color_primaries)
432 if (
format->video_signal_description.transfer_characteristics)
433 avctx->
color_trc =
format->video_signal_description.transfer_characteristics;
434 if (
format->video_signal_description.matrix_coefficients)
440 if (
format->frame_rate.numerator &&
format->frame_rate.denominator) {
448 && avctx->
width == old_width
449 && avctx->
height == old_height
450 &&
ctx->chroma_format ==
format->chroma_format
454 if (
ctx->cudecoder) {
457 if (
ctx->internal_error < 0)
462 if (hwframe_ctx->
pool && (
467 av_log(avctx,
AV_LOG_ERROR,
"AVHWFramesContext is already initialized with incompatible parameters\n");
478 ctx->chroma_format =
format->chroma_format;
480 cuinfo.CodecType =
ctx->codec_type =
format->codec;
481 cuinfo.ChromaFormat =
format->chroma_format;
485 cuinfo.OutputFormat = cudaVideoSurfaceFormat_NV12;
490 cuinfo.OutputFormat = cudaVideoSurfaceFormat_P016;
492 #ifdef NVDEC_HAVE_422_SUPPORT
494 cuinfo.OutputFormat = cudaVideoSurfaceFormat_NV16;
499 cuinfo.OutputFormat = cudaVideoSurfaceFormat_P216;
521 #ifdef NVDEC_HAVE_OPAQUE_OUTPUT_SUPPORT
522 if (
ctx->opaque_output) {
523 switch (cuinfo.OutputFormat) {
524 case cudaVideoSurfaceFormat_NV12: cuinfo.OutputFormat = cudaVideoSurfaceFormat_NV12_Opaque;
break;
525 case cudaVideoSurfaceFormat_P016: cuinfo.OutputFormat = cudaVideoSurfaceFormat_P016_Opaque;
break;
526 #ifdef NVDEC_HAVE_422_SUPPORT
527 case cudaVideoSurfaceFormat_NV16: cuinfo.OutputFormat = cudaVideoSurfaceFormat_NV16_Opaque;
break;
528 case cudaVideoSurfaceFormat_P216: cuinfo.OutputFormat = cudaVideoSurfaceFormat_P216_Opaque;
break;
537 if (
ctx->deint_mode_current != cudaVideoDeinterlaceMode_Weave && !
ctx->drop_second_field) {
542 old_nb_surfaces =
ctx->nb_surfaces;
546 #ifdef NVDEC_HAVE_OPAQUE_OUTPUT_SUPPORT
547 if (
ctx->opaque_output &&
ctx->zero_copy)
549 MAX_NUM_REGISTERED_DECODE_SURFACES);
553 if (fifo_size_inc > 0 &&
av_fifo_grow2(
ctx->frame_queue, fifo_size_inc) < 0) {
554 av_log(avctx,
AV_LOG_ERROR,
"Failed to grow frame queue on video sequence callback\n");
560 av_log(avctx,
AV_LOG_ERROR,
"Failed to grow key frame array on video sequence callback\n");
565 cuinfo.ulNumDecodeSurfaces =
ctx->nb_surfaces;
566 cuinfo.ulNumOutputSurfaces =
ctx->opaque_output ? 0 : 1;
567 cuinfo.ulCreationFlags = cudaVideoCreate_PreferCUVID;
568 cuinfo.bitDepthMinus8 =
format->bit_depth_luma_minus8;
569 cuinfo.DeinterlaceMode =
ctx->deint_mode_current;
571 ctx->internal_error =
CHECK_CU(
ctx->cvdl->cuvidCreateDecoder(&
ctx->cudecoder, &cuinfo));
572 if (
ctx->internal_error < 0)
575 #ifdef NVDEC_HAVE_OPAQUE_OUTPUT_SUPPORT
576 if (
ctx->opaque_output) {
577 CUDA_ARRAY3D_DESCRIPTOR arr_desc;
578 CUVIDREGISTERDECODESURFACESINFO reg_info;
582 ff_nvdec_fill_cuarray_desc(&arr_desc, avctx, cuinfo.OutputFormat);
584 if (
ctx->cuarray_surfaces) {
585 if (
ctx->decoder_cleanup) {
586 ctx->decoder_cleanup->cuarray_surfaces =
NULL;
587 ctx->decoder_cleanup->cuarray_num_surfaces = 0;
588 ctx->decoder_cleanup->cudecoder =
NULL;
591 for (
i = 0;
i <
ctx->cuarray_num_surfaces;
i++)
592 ctx->cudl->cuArrayDestroy(
ctx->cuarray_surfaces[
i]);
597 ctx->cuarray_num_surfaces =
ctx->nb_surfaces;
598 ctx->cuarray_surfaces =
av_calloc(
ctx->cuarray_num_surfaces,
sizeof(CUarray));
599 if (!
ctx->cuarray_surfaces) {
610 if (
ctx->zero_copy) {
620 (uint8_t *)
flags,
ctx->cuarray_num_surfaces *
sizeof(*
flags),
623 if (!
ctx->surface_in_use_ref) {
633 for (
i = 0;
i <
ctx->cuarray_num_surfaces;
i++) {
635 &
ctx->cuarray_surfaces[
i], &arr_desc));
636 if (
ctx->internal_error < 0) {
637 for (
int j = 0; j <
i; j++)
638 ctx->cudl->cuArrayDestroy(
ctx->cuarray_surfaces[j]);
642 ctx->cuarray_num_surfaces = 0;
652 dev_hwctx->cuda_ctx));
654 if (
ctx->internal_error < 0)
657 memset(®_info, 0,
sizeof(reg_info));
658 reg_info.ulNumDecodeSurfaces =
ctx->cuarray_num_surfaces;
659 reg_info.pDecodeSurfaces =
ctx->cuarray_surfaces;
661 if (
ctx->cvdl->cuvidRegisterDecodeSurfaces) {
663 ctx->cvdl->cuvidRegisterDecodeSurfaces(
664 ctx->cudecoder, ®_info));
666 av_log(avctx,
AV_LOG_ERROR,
"cuvidRegisterDecodeSurfaces not available in loaded driver\n");
670 if (
ctx->internal_error < 0)
673 if (
ctx->decoder_cleanup) {
674 ctx->decoder_cleanup->cudecoder =
ctx->cudecoder;
675 ctx->decoder_cleanup->cuarray_surfaces =
ctx->cuarray_surfaces;
676 ctx->decoder_cleanup->cuarray_num_surfaces =
ctx->cuarray_num_surfaces;
681 if (!hwframe_ctx->
pool) {
687 #ifdef NVDEC_HAVE_OPAQUE_OUTPUT_SUPPORT
690 ff_nvdec_fill_cuarray_desc(&cuda_hwctx->
cuarray_desc, avctx, cuinfo.OutputFormat);
700 if(
ctx->cuparseinfo.ulMaxNumDecodeSurfaces != cuinfo.ulNumDecodeSurfaces) {
701 ctx->cuparseinfo.ulMaxNumDecodeSurfaces = cuinfo.ulNumDecodeSurfaces;
702 return cuinfo.ulNumDecodeSurfaces;
718 if(picparams->intra_pic_flag)
719 ctx->key_frame[picparams->CurrPicIdx] = picparams->intra_pic_flag;
721 #ifdef NVDEC_HAVE_OPAQUE_OUTPUT_SUPPORT
722 if (
ctx->opaque_output) {
723 if (
ctx->surface_in_use &&
725 memory_order_acquire)) {
727 "CUARRAY surface %d still in use by the encoder. "
728 "Increase surfaces with -extra_hw_frames or reduce "
729 "encoder buffering (disable lookahead, reduce B-frames).\n",
730 picparams->CurrPicIdx);
735 if (
ctx->cvdl->cuvidDecodePictureAsync)
736 ctx->internal_error =
CHECK_CU(
ctx->cvdl->cuvidDecodePictureAsync(
737 ctx->cudecoder, picparams,
ctx->cuda_stream));
739 ctx->internal_error =
CHECK_CU(
ctx->cvdl->cuvidDecodePicture(
ctx->cudecoder, picparams));
742 ctx->internal_error =
CHECK_CU(
ctx->cvdl->cuvidDecodePicture(
ctx->cudecoder, picparams));
743 if (
ctx->internal_error < 0)
760 ctx->internal_error = 0;
763 parsed_frame.
dispinfo.progressive_frame =
ctx->progressive_sequence;
765 if (
ctx->deint_mode_current == cudaVideoDeinterlaceMode_Weave) {
775 if (!
ctx->drop_second_field) {
791 if (
ctx->deint_mode != cudaVideoDeinterlaceMode_Weave && !
ctx->drop_second_field)
803 CUcontext
dummy, cuda_ctx = device_hwctx->cuda_ctx;
804 CUVIDSOURCEDATAPACKET cupkt;
805 int ret = 0, eret = 0, is_flush =
ctx->decoder_flushing;
812 if (is_flush && avpkt && avpkt->
size)
823 memset(&cupkt, 0,
sizeof(cupkt));
825 if (avpkt && avpkt->
size) {
826 cupkt.payload_size = avpkt->
size;
827 cupkt.payload = avpkt->
data;
830 cupkt.flags = CUVID_PKT_TIMESTAMP;
834 cupkt.timestamp = avpkt->
pts;
837 cupkt.flags = CUVID_PKT_ENDOFSTREAM;
838 ctx->decoder_flushing = 1;
852 if (
ctx->internal_error) {
854 ret =
ctx->internal_error;
876 CUcontext
dummy, cuda_ctx = device_hwctx->cuda_ctx;
878 CUdeviceptr mapped_frame = 0;
879 int ret = 0, eret = 0;
884 if (
ctx->decoder_flushing) {
911 CUVIDPROCPARAMS params;
912 unsigned int pitch = 0;
916 memset(¶ms, 0,
sizeof(params));
917 params.progressive_frame = parsed_frame.dispinfo.progressive_frame;
918 params.second_field = parsed_frame.second_field;
919 params.top_field_first = parsed_frame.dispinfo.top_field_first;
921 #ifdef NVDEC_HAVE_OPAQUE_OUTPUT_SUPPORT
923 if (
ctx->zero_copy) {
924 int idx = parsed_frame.dispinfo.picture_index;
926 if (idx < 0 || idx >=
ctx->cuarray_num_surfaces) {
928 idx,
ctx->cuarray_num_surfaces);
940 if (!
frame->hw_frames_ctx) {
946 CuvidSurfaceRelease *rel =
av_malloc(
sizeof(*rel));
952 if (!rel->in_use_ref) {
959 memory_order_release);
961 (uint8_t *)
ctx->cuarray_surfaces[idx], 0,
962 cuvid_cuarray_buf_free, rel,
964 if (!
frame->buf[0]) {
966 memory_order_release);
974 frame->data[0] = (uint8_t *)
ctx->cuarray_surfaces[idx];
978 CUDA_ARRAY3D_DESCRIPTOR plane_desc = { 0 };
981 CUresult cures =
ctx->cudl->cuArrayGetPlane(
982 &plane_array,
ctx->cuarray_surfaces[idx],
p);
983 if (cures == CUDA_ERROR_INVALID_VALUE)
985 if (cures != CUDA_SUCCESS) {
991 &plane_desc, plane_array));
996 if (elem_size <= 0) {
998 "Unknown CUarray element format %d on plane %d\n",
999 plane_desc.Format,
p);
1004 frame->linesize[
p] = plane_desc.Width *
1005 plane_desc.NumChannels * elem_size;
1008 int src_idx = parsed_frame.dispinfo.picture_index;
1011 if (src_idx < 0 || src_idx >=
ctx->cuarray_num_surfaces) {
1012 av_log(avctx,
AV_LOG_ERROR,
"CUARRAY source surface index %d out of range [0, %d)\n",
1013 src_idx,
ctx->cuarray_num_surfaces);
1030 memset(&tmp_frame, 0,
sizeof(tmp_frame));
1032 tmp_frame.
data[0] = (uint8_t *)
ctx->cuarray_surfaces[src_idx];
1047 ret =
CHECK_CU(
ctx->cvdl->cuvidMapVideoFrame(
ctx->cudecoder, parsed_frame.dispinfo.picture_index, &mapped_frame, &pitch, ¶ms));
1068 CUDA_MEMCPY2D cpy = {
1069 .srcMemoryType = CU_MEMORYTYPE_DEVICE,
1070 .dstMemoryType = CU_MEMORYTYPE_DEVICE,
1071 .srcDevice = mapped_frame,
1072 .dstDevice = (CUdeviceptr)
frame->data[
i],
1074 .dstPitch =
frame->linesize[
i],
1080 ret =
CHECK_CU(
ctx->cudl->cuMemcpy2DAsync(&cpy, device_hwctx->stream));
1090 #ifdef NVDEC_HAVE_422_SUPPORT
1127 tmp_frame->
data[
i] = (uint8_t*)mapped_frame +
offset;
1152 if (
ctx->key_frame[parsed_frame.dispinfo.picture_index])
1156 ctx->key_frame[parsed_frame.dispinfo.picture_index] = 0;
1163 frame->pts = parsed_frame.dispinfo.timestamp;
1165 if (parsed_frame.second_field) {
1166 if (
ctx->prev_pts == INT64_MIN) {
1170 int pts_diff = (
frame->pts -
ctx->prev_pts) / 2;
1172 frame->pts += pts_diff;
1179 frame->duration = 0;
1181 if (!parsed_frame.is_deinterlacing && !parsed_frame.dispinfo.progressive_frame)
1186 }
else if (
ctx->decoder_flushing ||
1198 eret =
CHECK_CU(
ctx->cvdl->cuvidUnmapVideoFrame(
ctx->cudecoder, mapped_frame));
1213 CUcontext
dummy, cuda_ctx = device_hwctx ? device_hwctx->cuda_ctx :
NULL;
1220 ctx->cudl->cuCtxPushCurrent(cuda_ctx);
1222 #ifdef NVDEC_HAVE_OPAQUE_OUTPUT_SUPPORT
1223 if (
ctx->opaque_output)
1224 ctx->cudl->cuCtxSynchronize();
1228 ctx->cvdl->cuvidDestroyVideoParser(
ctx->cuparser);
1229 #ifdef NVDEC_HAVE_OPAQUE_OUTPUT_SUPPORT
1230 if (
ctx->decoder_cleanup) {
1232 ctx->decoder_cleanup->cvdl =
ctx->cvdl;
1236 ctx->cuarray_num_surfaces = 0;
1244 ctx->cvdl->cuvidDestroyDecoder(
ctx->cudecoder);
1246 #ifdef NVDEC_HAVE_OPAQUE_OUTPUT_SUPPORT
1247 if (
ctx->cuarray_surfaces) {
1248 for (
int i = 0;
i <
ctx->cuarray_num_surfaces;
i++)
1249 ctx->cudl->cuArrayDestroy(
ctx->cuarray_surfaces[
i]);
1253 ctx->cuarray_num_surfaces = 0;
1258 ctx->cudl->cuCtxPopCurrent(&
dummy);
1269 cuvid_free_functions(&
ctx->cvdl);
1275 const CUVIDPARSERPARAMS *cuparseinfo,
1278 int bit_depth,
int is_yuv422,
int is_yuv444)
1281 CUVIDDECODECAPS *caps;
1282 int res8 = 0, res10 = 0, res12 = 0;
1284 if (!
ctx->cvdl->cuvidGetDecoderCaps) {
1285 av_log(avctx,
AV_LOG_WARNING,
"Used Nvidia driver is too old to perform a capability check.\n");
1287 #
if defined(_WIN32) || defined(__CYGWIN__)
1292 ". Continuing blind.\n");
1293 ctx->caps8.bIsSupported =
ctx->caps10.bIsSupported = 1;
1295 ctx->caps12.bIsSupported = 0;
1299 ctx->caps8.eCodecType =
ctx->caps10.eCodecType =
ctx->caps12.eCodecType
1300 = cuparseinfo->CodecType;
1302 ctx->caps8.eChromaFormat =
ctx->caps10.eChromaFormat =
ctx->caps12.eChromaFormat
1303 = is_yuv444 ? cudaVideoChromaFormat_444 :
1304 #ifdef NVDEC_HAVE_422_SUPPORT
1305 (is_yuv422 ? cudaVideoChromaFormat_422 : cudaVideoChromaFormat_420);
1307 cudaVideoChromaFormat_420;
1310 ctx->caps8.nBitDepthMinus8 = 0;
1311 ctx->caps10.nBitDepthMinus8 = 2;
1312 ctx->caps12.nBitDepthMinus8 = 4;
1319 av_log(avctx,
AV_LOG_VERBOSE,
"8 bit: supported: %d, min_width: %d, max_width: %d, min_height: %d, max_height: %d\n",
1320 ctx->caps8.bIsSupported,
ctx->caps8.nMinWidth,
ctx->caps8.nMaxWidth,
ctx->caps8.nMinHeight,
ctx->caps8.nMaxHeight);
1321 av_log(avctx,
AV_LOG_VERBOSE,
"10 bit: supported: %d, min_width: %d, max_width: %d, min_height: %d, max_height: %d\n",
1322 ctx->caps10.bIsSupported,
ctx->caps10.nMinWidth,
ctx->caps10.nMaxWidth,
ctx->caps10.nMinHeight,
ctx->caps10.nMaxHeight);
1323 av_log(avctx,
AV_LOG_VERBOSE,
"12 bit: supported: %d, min_width: %d, max_width: %d, min_height: %d, max_height: %d\n",
1324 ctx->caps12.bIsSupported,
ctx->caps12.nMinWidth,
ctx->caps12.nMaxWidth,
ctx->caps12.nMinHeight,
ctx->caps12.nMaxHeight);
1328 caps = &
ctx->caps10;
1333 caps = &
ctx->caps12;
1343 if (!
ctx->caps8.bIsSupported) {
1348 if (!caps->bIsSupported) {
1353 if (probed_width > caps->nMaxWidth || probed_width < caps->nMinWidth) {
1355 probed_width, caps->nMinWidth, caps->nMaxWidth);
1359 if (probed_height > caps->nMaxHeight || probed_height < caps->nMinHeight) {
1361 probed_height, caps->nMinHeight, caps->nMaxHeight);
1365 if ((probed_width * probed_height) / 256 > caps->nMaxMBCount) {
1367 (
int)(probed_width * probed_height) / 256, caps->nMaxMBCount);
1380 CUVIDSOURCEDATAPACKET seq_pkt;
1381 CUcontext cuda_ctx =
NULL;
1392 int probed_bit_depth = 8, is_yuv444 = 0, is_yuv422 = 0;
1396 probed_bit_depth = probe_desc->
comp[0].
depth;
1401 #ifdef NVDEC_HAVE_422_SUPPORT
1411 switch (probed_bit_depth) {
1438 "ff_get_format returned %s, overriding to %s\n",
1441 ret = requested_hw_format;
1447 if (
ctx->opaque_output) {
1456 if (
ctx->resize_expr && sscanf(
ctx->resize_expr,
"%dx%d",
1457 &
ctx->resize.width, &
ctx->resize.height) != 2) {
1463 if (
ctx->crop_expr && sscanf(
ctx->crop_expr,
"%dx%dx%dx%d",
1464 &
ctx->crop.top, &
ctx->crop.bottom,
1465 &
ctx->crop.left, &
ctx->crop.right) != 4) {
1471 if (
ctx->opaque_output) {
1472 if (
ctx->crop_expr) {
1474 "Cropping is not supported with cuarray output; "
1475 "crop option will be ignored\n");
1476 memset(&
ctx->crop, 0,
sizeof(
ctx->crop));
1478 if (
ctx->resize_expr) {
1480 "Resizing is not supported with cuarray output; "
1481 "resize option will be ignored\n");
1484 if (
ctx->deint_mode != cudaVideoDeinterlaceMode_Weave) {
1486 "Deinterlacing is not supported with cuarray output; "
1487 "deint mode will be forced to weave\n");
1488 ctx->deint_mode = cudaVideoDeinterlaceMode_Weave;
1492 ret = cuvid_load_functions(&
ctx->cvdl, avctx);
1499 if(
ctx->nb_surfaces < 0)
1503 if (!
ctx->frame_queue) {
1510 if (!
ctx->hwframe) {
1518 if (!
ctx->hwdevice) {
1525 if (!
ctx->hwdevice) {
1536 if (!
ctx->hwframe) {
1546 device_hwctx = device_ctx->
hwctx;
1551 ctx->cuda_stream = device_hwctx->
stream;
1553 memset(&
ctx->cuparseinfo, 0,
sizeof(
ctx->cuparseinfo));
1554 memset(&seq_pkt, 0,
sizeof(seq_pkt));
1557 #if CONFIG_H264_CUVID_DECODER
1559 ctx->cuparseinfo.CodecType = cudaVideoCodec_H264;
1562 #if CONFIG_HEVC_CUVID_DECODER
1564 ctx->cuparseinfo.CodecType = cudaVideoCodec_HEVC;
1567 #if CONFIG_MJPEG_CUVID_DECODER
1569 ctx->cuparseinfo.CodecType = cudaVideoCodec_JPEG;
1572 #if CONFIG_MPEG1_CUVID_DECODER
1574 ctx->cuparseinfo.CodecType = cudaVideoCodec_MPEG1;
1577 #if CONFIG_MPEG2_CUVID_DECODER
1579 ctx->cuparseinfo.CodecType = cudaVideoCodec_MPEG2;
1582 #if CONFIG_MPEG4_CUVID_DECODER
1584 ctx->cuparseinfo.CodecType = cudaVideoCodec_MPEG4;
1587 #if CONFIG_VP8_CUVID_DECODER
1589 ctx->cuparseinfo.CodecType = cudaVideoCodec_VP8;
1592 #if CONFIG_VP9_CUVID_DECODER
1594 ctx->cuparseinfo.CodecType = cudaVideoCodec_VP9;
1597 #if CONFIG_VC1_CUVID_DECODER
1599 ctx->cuparseinfo.CodecType = cudaVideoCodec_VC1;
1602 #if CONFIG_AV1_CUVID_DECODER && defined(CUVID_HAS_AV1_SUPPORT)
1604 ctx->cuparseinfo.CodecType = cudaVideoCodec_AV1;
1625 extradata_size >= 4 &&
1626 extradata[0] & 0x80) {
1628 extradata_size -= 4;
1632 +
FFMAX(extradata_size - (
int)
sizeof(
ctx->cuparse_ext->raw_seqhdr_data), 0));
1633 if (!
ctx->cuparse_ext) {
1638 if (extradata_size > 0)
1639 memcpy(
ctx->cuparse_ext->raw_seqhdr_data, extradata, extradata_size);
1640 ctx->cuparse_ext->format.seqhdr_data_length = extradata_size;
1642 ctx->cuparseinfo.pExtVideoInfo =
ctx->cuparse_ext;
1645 if (!
ctx->key_frame) {
1650 ctx->cuparseinfo.ulMaxNumDecodeSurfaces = 1;
1652 ctx->cuparseinfo.pUserData = avctx;
1664 probed_bit_depth, is_yuv422, is_yuv444);
1672 seq_pkt.payload =
ctx->cuparse_ext->raw_seqhdr_data;
1673 seq_pkt.payload_size =
ctx->cuparse_ext->format.seqhdr_data_length;
1675 if (seq_pkt.payload && seq_pkt.payload_size) {
1685 ctx->prev_pts = INT64_MIN;
1702 CUcontext
dummy, cuda_ctx = device_hwctx->cuda_ctx;
1703 CUVIDSOURCEDATAPACKET seq_pkt = { 0 };
1712 if (
ctx->cudecoder) {
1713 ctx->cvdl->cuvidDestroyDecoder(
ctx->cudecoder);
1717 if (
ctx->cuparser) {
1718 ctx->cvdl->cuvidDestroyVideoParser(
ctx->cuparser);
1726 seq_pkt.payload =
ctx->cuparse_ext->raw_seqhdr_data;
1727 seq_pkt.payload_size =
ctx->cuparse_ext->format.seqhdr_data_length;
1729 if (seq_pkt.payload && seq_pkt.payload_size) {
1739 ctx->prev_pts = INT64_MIN;
1740 ctx->decoder_flushing = 0;
1747 #define OFFSET(x) offsetof(CuvidContext, x)
1748 #define VD AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM
1750 {
"deint",
"Set deinterlacing mode",
OFFSET(deint_mode),
AV_OPT_TYPE_INT, { .i64 = cudaVideoDeinterlaceMode_Weave }, cudaVideoDeinterlaceMode_Weave, cudaVideoDeinterlaceMode_Adaptive,
VD, .unit =
"deint" },
1751 {
"weave",
"Weave deinterlacing (do nothing)", 0,
AV_OPT_TYPE_CONST, { .i64 = cudaVideoDeinterlaceMode_Weave }, 0, 0,
VD, .unit =
"deint" },
1752 {
"bob",
"Bob deinterlacing", 0,
AV_OPT_TYPE_CONST, { .i64 = cudaVideoDeinterlaceMode_Bob }, 0, 0,
VD, .unit =
"deint" },
1753 {
"adaptive",
"Adaptive deinterlacing", 0,
AV_OPT_TYPE_CONST, { .i64 = cudaVideoDeinterlaceMode_Adaptive }, 0, 0,
VD, .unit =
"deint" },
1756 {
"drop_second_field",
"Drop second field when deinterlacing",
OFFSET(drop_second_field),
AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1,
VD },
1761 #ifdef NVDEC_HAVE_OPAQUE_OUTPUT_SUPPORT
1763 {
"zero_copy",
"Enable zero-copy opaque decode output (forces output_format=cuarray)",
OFFSET(zero_copy),
AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1,
VD },
1779 #ifdef NVDEC_HAVE_OPAQUE_OUTPUT_SUPPORT
1794 #define DEFINE_CUVID_CODEC(x, X, bsf_name) \
1795 static const AVClass x##_cuvid_class = { \
1796 .class_name = #x "_cuvid", \
1797 .item_name = av_default_item_name, \
1798 .option = options, \
1799 .version = LIBAVUTIL_VERSION_INT, \
1801 const FFCodec ff_##x##_cuvid_decoder = { \
1802 .p.name = #x "_cuvid", \
1803 CODEC_LONG_NAME("Nvidia CUVID " #X " decoder"), \
1804 .p.type = AVMEDIA_TYPE_VIDEO, \
1805 .p.id = AV_CODEC_ID_##X, \
1806 .priv_data_size = sizeof(CuvidContext), \
1807 .p.priv_class = &x##_cuvid_class, \
1808 .init = cuvid_decode_init, \
1809 .close = cuvid_decode_end, \
1810 FF_CODEC_RECEIVE_FRAME_CB(cuvid_output_frame), \
1811 .flush = cuvid_flush, \
1813 .p.capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_AVOID_PROBING | AV_CODEC_CAP_HARDWARE, \
1814 .caps_internal = FF_CODEC_CAP_NOT_INIT_THREADSAFE | \
1815 FF_CODEC_CAP_SETS_FRAME_PROPS, \
1816 .hw_configs = cuvid_hw_configs, \
1817 .p.wrapper_name = "cuvid", \
1820 #if CONFIG_AV1_CUVID_DECODER && defined(CUVID_HAS_AV1_SUPPORT)
1824 #if CONFIG_HEVC_CUVID_DECODER
1828 #if CONFIG_H264_CUVID_DECODER
1832 #if CONFIG_MJPEG_CUVID_DECODER
1836 #if CONFIG_MPEG1_CUVID_DECODER
1840 #if CONFIG_MPEG2_CUVID_DECODER
1844 #if CONFIG_MPEG4_CUVID_DECODER
1848 #if CONFIG_VP8_CUVID_DECODER
1852 #if CONFIG_VP9_CUVID_DECODER
1856 #if CONFIG_VC1_CUVID_DECODER