This commit adds support for 4:2:2 decoding for HEVC and H.264 on NVIDIA Blackwell GPUs. Additionally, it supports 10-bit decoding for H.264 on Blackwell GPUs.
Unified · Split
| @@ -807,6 +807,9 @@ static enum AVPixelFormat get_pixel_format(H264Context *h, int force_callback) · 806 unmodified lines | ||
| 807 | 807 | #endif |
| 808 | 808 | #if CONFIG_H264_VULKAN_HWACCEL |
| 809 | 809 | *fmt++ = AV_PIX_FMT_VULKAN; |
| 810 | +#endif | |
| 811 | +#if CONFIG_H264_NVDEC_HWACCEL | |
| 812 | + *fmt++ = AV_PIX_FMT_CUDA; | |
| 810 | 813 | #endif |
| 811 | 814 | if (CHROMA444(h)) { |
| 812 | 815 | if (h->avctx->colorspace == AVCOL_SPC_RGB) { |
| @@ -626,6 +626,9 @@ static enum AVPixelFormat get_format(HEVCContext *s, const HEVCSPS *sps) · 625 unmodified lines | ||
| 626 | 626 | #endif |
| 627 | 627 | #if CONFIG_HEVC_VULKAN_HWACCEL |
| 628 | 628 | *fmt++ = AV_PIX_FMT_VULKAN; |
| 629 | +#endif | |
| 630 | +#if CONFIG_HEVC_NVDEC_HWACCEL | |
| 631 | + *fmt++ = AV_PIX_FMT_CUDA; | |
| 629 | 632 | #endif |
| 630 | 633 | break; |
| 631 | 634 | case AV_PIX_FMT_YUV444P10: |
| @@ -654,6 +657,9 @@ static enum AVPixelFormat get_format(HEVCContext *s, const HEVCSPS *sps) · 22 unmodified lines | ||
| 654 | 657 | #endif |
| 655 | 658 | #if CONFIG_HEVC_VULKAN_HWACCEL |
| 656 | 659 | *fmt++ = AV_PIX_FMT_VULKAN; |
| 660 | +#endif | |
| 661 | +#if CONFIG_HEVC_NVDEC_HWACCEL | |
| 662 | + *fmt++ = AV_PIX_FMT_CUDA; | |
| 657 | 663 | #endif |
| 658 | 664 | break; |
| 659 | 665 | } |
| @@ -375,13 +375,27 @@ int ff_nvdec_decode_init(AVCodecContext *avctx) · 374 unmodified lines | ||
| 375 | 375 | |
| 376 | 376 | switch (sw_desc->comp[0].depth) { |
| 377 | 377 | case 8: |
| 378 | − output_format = chroma_444 ? cudaVideoSurfaceFormat_YUV444 : | |
| 379 | − cudaVideoSurfaceFormat_NV12; | |
| 378 | + if (chroma_444) { | |
| 379 | + output_format = cudaVideoSurfaceFormat_YUV444; | |
| 380 | +#ifdef NVDEC_HAVE_422_SUPPORT | |
| 381 | + } else if (cuvid_chroma_format == cudaVideoChromaFormat_422) { | |
| 382 | + output_format = cudaVideoSurfaceFormat_NV16; | |
| 383 | +#endif | |
| 384 | + } else { | |
| 385 | + output_format = cudaVideoSurfaceFormat_NV12; | |
| 386 | + } | |
| 380 | 387 | break; |
| 381 | 388 | case 10: |
| 382 | 389 | case 12: |
| 383 | − output_format = chroma_444 ? cudaVideoSurfaceFormat_YUV444_16Bit : | |
| 384 | − cudaVideoSurfaceFormat_P016; | |
| 390 | + if (chroma_444) { | |
| 391 | + output_format = cudaVideoSurfaceFormat_YUV444_16Bit; | |
| 392 | +#ifdef NVDEC_HAVE_422_SUPPORT | |
| 393 | + } else if (cuvid_chroma_format == cudaVideoChromaFormat_422) { | |
| 394 | + output_format = cudaVideoSurfaceFormat_P216; | |
| 395 | +#endif | |
| 396 | + } else { | |
| 397 | + output_format = cudaVideoSurfaceFormat_P016; | |
| 398 | + } | |
| 385 | 399 | break; |
| 386 | 400 | default: |
| 387 | 401 | av_log(avctx, AV_LOG_ERROR, "Unsupported bit depth\n"); |
| @@ -729,13 +743,27 @@ int ff_nvdec_frame_params(AVCodecContext *avctx, · 341 unmodified lines | ||
| 729 | 743 | |
| 730 | 744 | switch (sw_desc->comp[0].depth) { |
| 731 | 745 | case 8: |
| 732 | − frames_ctx->sw_format = chroma_444 ? AV_PIX_FMT_YUV444P : AV_PIX_FMT_NV12; | |
| 746 | + if (chroma_444) { | |
| 747 | + frames_ctx->sw_format = AV_PIX_FMT_YUV444P; | |
| 748 | +#ifdef NVDEC_HAVE_422_SUPPORT | |
| 749 | + } else if (cuvid_chroma_format == cudaVideoChromaFormat_422) { | |
| 750 | + frames_ctx->sw_format = AV_PIX_FMT_NV16; | |
| 751 | +#endif | |
| 752 | + } else { | |
| 753 | + frames_ctx->sw_format = AV_PIX_FMT_NV12; | |
| 754 | + } | |
| 733 | 755 | break; |
| 734 | 756 | case 10: |
| 735 | − frames_ctx->sw_format = chroma_444 ? AV_PIX_FMT_YUV444P16 : AV_PIX_FMT_P010; | |
| 736 | − break; | |
| 737 | 757 | case 12: |
| 738 | − frames_ctx->sw_format = chroma_444 ? AV_PIX_FMT_YUV444P16 : AV_PIX_FMT_P016; | |
| 758 | + if (chroma_444) { | |
| 759 | + frames_ctx->sw_format = AV_PIX_FMT_YUV444P16; | |
| 760 | +#ifdef NVDEC_HAVE_422_SUPPORT | |
| 761 | + } else if (cuvid_chroma_format == cudaVideoChromaFormat_422) { | |
| 762 | + frames_ctx->sw_format = AV_PIX_FMT_P216LE; | |
| 763 | +#endif | |
| 764 | + } else { | |
| 765 | + frames_ctx->sw_format = AV_PIX_FMT_P016LE; | |
| 766 | + } | |
| 739 | 767 | break; |
| 740 | 768 | default: |
| 741 | 769 | return AVERROR(EINVAL); |
| @@ -41,6 +41,11 @@ · 40 unmodified lines | ||
| 41 | 41 | ((major) < 8 || ((major) == 8 && (minor) <= 0)) |
| 42 | 42 | #endif |
| 43 | 43 | |
| 44 | +// SDK 13.0 compile time feature checks | |
| 45 | +#if NVDECAPI_CHECK_VERSION(13, 0) | |
| 46 | +#define NVDEC_HAVE_422_SUPPORT | |
| 47 | +#endif | |
| 48 | + | |
| 44 | 49 | typedef struct NVDECFrame { |
| 45 | 50 | unsigned int idx; |
| 46 | 51 | unsigned int ref_idx; |
| @@ -97,7 +97,7 @@ static int nvdec_h264_start_frame(AVCodecContext *avctx, · 96 unmodified lines | ||
| 97 | 97 | .num_ref_idx_l1_active_minus1 = pps->ref_count[1] - 1, |
| 98 | 98 | .weighted_pred_flag = pps->weighted_pred, |
| 99 | 99 | .weighted_bipred_idc = pps->weighted_bipred_idc, |
| 100 | − .pic_init_qp_minus26 = pps->init_qp - 26, | |
| 100 | + .pic_init_qp_minus26 = pps->init_qp - 26 - 6 * (sps->bit_depth_luma - 8), | |
| 101 | 101 | .deblocking_filter_control_present_flag = pps->deblocking_filter_parameters_present, |
| 102 | 102 | .redundant_pic_cnt_present_flag = pps->redundant_pic_cnt_present, |
| 103 | 103 | .transform_8x8_mode_flag = pps->transform_8x8_mode, |