PR #23367 opened by Edison Ling (edisonling) URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/23367 Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/23367.patch
Add parameter `constrained_intra_pred` for users to enable constrained intra prediction (as opposed to default unconstrained) in D3D12 H264 and HEVC encoding. Usage: false (default): `-constrained_intra_pred false` or `-constrained_intra_pred 0` true: `-constrained_intra_pred true` or `-constrained_intra_pred 1` Sample command line: ``` ffmpeg.exe -hwaccel d3d12va -hwaccel_output_format d3d12 -i input.mp4 -c:v h264_d3d12va -constrained_intra_pred true -y output.mp4 ffmpeg.exe -hwaccel d3d12va -hwaccel_output_format d3d12 -i input.mp4 -c:v hevc_d3d12va -constrained_intra_pred true -y output.mp4 ``` ### Purpose Constrained intra prediction restricts intra-coded blocks to only reference neighbouring blocks that were also intra-coded. Neighbours that were inter-predicted from another frame can no longer be used, preventing inter-predicted regions/blocks from bleeding to adjacent intra blocks. Useful for error resilience to prevent spreading temporal error propagation to other regions during streaming and live broadcasting. ### Testing PPS `constrained_intra_pred_flag` verified and output size and content verified. - **AMD (RX 7600M & RX 9070):** H264 and HEVC both correct. `constrained_intra_pred_flag` is `0` when off/default and `1` when enabled, and size changes as expected. Tiny +/- file size difference, and slight quality drop when enabled. - **Intel (Arc B580):** driver does not advertise H264 constrained-intra support, so the soft-fallback is exercised. `"Constrained intra prediction is not supported by the driver, disabling."` is logged, the flag stays `0`, and encoding completes normally. (HEVC is supported and verified, H264 was not able to be tested due to issues with base DX12 encoding) - **NVIDIA (RTX 5070 Ti):** not tested. D3D12 hardware encoding is not working for me (fails regardless of `-constrained_intra_pred` setting, as well as with official FFmpeg 8.1.1), so the feature could not be tested. _D3D12 AV1 encoding API has no constrained-intra-prediction flag_ >From 11972491aeaa8c7ad002782db2b844ba76bb9c22 Mon Sep 17 00:00:00 2001 From: "Ling, Edison" <[email protected]> Date: Fri, 5 Jun 2026 10:04:23 -0400 Subject: [PATCH] avcodec/d3d12va_encode: Add H264/HEVC constrained intra prediction parameter support Add parameter `constrained_intra_pred` for users to enable constrained intra prediction (as opposed to default unconstrained) in D3D12 H264 and HEVC encoding. Usage: false (default): `-constrained_intra_pred false` or `-constrained_intra_pred 0` true: `-constrained_intra_pred true` or `-constrained_intra_pred 1` Sample command line: ``` ffmpeg.exe -hwaccel d3d12va -hwaccel_output_format d3d12 -i input.mp4 -c:v h264_d3d12va -constrained_intra_pred true -y output.mp4 ffmpeg.exe -hwaccel d3d12va -hwaccel_output_format d3d12 -i input.mp4 -c:v hevc_d3d12va -constrained_intra_pred true -y output.mp4 ``` --- libavcodec/d3d12va_encode_h264.c | 15 +++++++++++++++ libavcodec/d3d12va_encode_hevc.c | 16 ++++++++++++++++ 2 files changed, 31 insertions(+) diff --git a/libavcodec/d3d12va_encode_h264.c b/libavcodec/d3d12va_encode_h264.c index 47c6953d1b..55ed249064 100644 --- a/libavcodec/d3d12va_encode_h264.c +++ b/libavcodec/d3d12va_encode_h264.c @@ -45,6 +45,7 @@ typedef struct D3D12VAEncodeH264Context { int profile; int level; int deblock; + int constrained_intra_pred; int idr_pic_id; // Writer structures. @@ -258,6 +259,7 @@ static int d3d12va_encode_h264_init_sequence_params(AVCodecContext *avctx) sps->log2_max_frame_num_minus4 = FFMAX(av_ceil_log2(base_ctx->gop_size) - 4, 0); ctx->gop.pH264GroupOfPictures->log2_max_frame_num_minus4 = sps->log2_max_frame_num_minus4; pps->deblocking_filter_control_present_flag = 1; + pps->constrained_intra_pred_flag = priv->constrained_intra_pred; return 0; } @@ -321,6 +323,16 @@ static int d3d12va_encode_h264_get_encoder_caps(AVCodecContext *avctx) } } + // Constrained intra prediction configuration + if (priv->constrained_intra_pred) { + if (h264_caps.SupportFlags & D3D12_VIDEO_ENCODER_CODEC_CONFIGURATION_SUPPORT_H264_FLAG_CONSTRAINED_INTRAPREDICTION_SUPPORT) { + config->ConfigurationFlags |= D3D12_VIDEO_ENCODER_CODEC_CONFIGURATION_H264_FLAG_USE_CONSTRAINED_INTRAPREDICTION; + } else { + av_log(avctx, AV_LOG_WARNING, "Constrained intra prediction is not supported by the driver, disabling.\n"); + priv->constrained_intra_pred = 0; + } + } + base_ctx->surface_width = FFALIGN(avctx->width, 16); base_ctx->surface_height = FFALIGN(avctx->height, 16); @@ -653,6 +665,9 @@ static const AVOption d3d12va_encode_h264_options[] = { { "cavlc", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 0 }, INT_MIN, INT_MAX, FLAGS, "coder" }, { "cabac", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 1 }, INT_MIN, INT_MAX, FLAGS, "coder" }, + { "constrained_intra_pred", "Constrained intra prediction (constrained_intra_pred_flag)", + OFFSET(constrained_intra_pred), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, FLAGS }, + { NULL }, }; diff --git a/libavcodec/d3d12va_encode_hevc.c b/libavcodec/d3d12va_encode_hevc.c index 8cae7a8b66..d2a862ac8b 100644 --- a/libavcodec/d3d12va_encode_hevc.c +++ b/libavcodec/d3d12va_encode_hevc.c @@ -46,6 +46,7 @@ typedef struct D3D12VAEncodeHEVCContext { int qp; int profile; int level; + int constrained_intra_pred; // Writer structures. FFHWBaseEncodeH265 units; @@ -376,6 +377,7 @@ static int d3d12va_encode_hevc_init_sequence_params(AVCodecContext *avctx) D3D12_VIDEO_ENCODER_CODEC_CONFIGURATION_HEVC_FLAG_DISABLE_LOOP_FILTER_ACROSS_SLICES); pps->deblocking_filter_control_present_flag = 1; + pps->constrained_intra_pred_flag = priv->constrained_intra_pred; return 0; } @@ -387,6 +389,7 @@ static int d3d12va_encode_hevc_get_encoder_caps(AVCodecContext *avctx) uint8_t min_cu_size, max_cu_size; FFHWBaseEncodeContext *base_ctx = avctx->priv_data; D3D12VAEncodeContext *ctx = avctx->priv_data; + D3D12VAEncodeHEVCContext *priv = avctx->priv_data; D3D12_VIDEO_ENCODER_CODEC_CONFIGURATION_HEVC *config; D3D12_VIDEO_ENCODER_CODEC_CONFIGURATION_SUPPORT_HEVC hevc_caps; @@ -439,6 +442,16 @@ static int d3d12va_encode_hevc_get_encoder_caps(AVCodecContext *avctx) if (hevc_caps.SupportFlags & D3D12_VIDEO_ENCODER_CODEC_CONFIGURATION_SUPPORT_HEVC_FLAG_TRANSFORM_SKIP_SUPPORT) config->ConfigurationFlags |= D3D12_VIDEO_ENCODER_CODEC_CONFIGURATION_HEVC_FLAG_ENABLE_TRANSFORM_SKIPPING; + // Constrained intra prediction configuration + if (priv->constrained_intra_pred) { + if (hevc_caps.SupportFlags & D3D12_VIDEO_ENCODER_CODEC_CONFIGURATION_SUPPORT_HEVC_FLAG_CONSTRAINED_INTRAPREDICTION_SUPPORT) { + config->ConfigurationFlags |= D3D12_VIDEO_ENCODER_CODEC_CONFIGURATION_HEVC_FLAG_USE_CONSTRAINED_INTRAPREDICTION; + } else { + av_log(avctx, AV_LOG_WARNING, "Constrained intra prediction is not supported by the driver, disabling.\n"); + priv->constrained_intra_pred = 0; + } + } + if (hevc_caps.SupportFlags & D3D12_VIDEO_ENCODER_CODEC_CONFIGURATION_SUPPORT_HEVC_FLAG_P_FRAMES_IMPLEMENTED_AS_LOW_DELAY_B_FRAMES) ctx->bi_not_empty = 1; @@ -780,6 +793,9 @@ static const AVOption d3d12va_encode_hevc_options[] = { { LEVEL("6.2", 186) }, #undef LEVEL + { "constrained_intra_pred", "Constrained intra prediction (constrained_intra_pred_flag)", + OFFSET(constrained_intra_pred), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, FLAGS }, + { NULL }, }; -- 2.52.0 _______________________________________________ ffmpeg-devel mailing list -- [email protected] To unsubscribe send an email to [email protected]
