Re: [FFmpeg-devel] [PATCH v3 8/9] avcodec: add D3D12VA hardware HEVC encoder

2024-02-07 Thread Wu, Tong1
>> From: Tong Wu 
>>
>> This implementation is based on D3D12 Video Encoding Spec:
>> https://microsoft.github.io/DirectX-Specs/d3d/D3D12VideoEncoding.html
>>
>> Sample command line for transcoding:
>> ffmpeg.exe -hwaccel d3d12va -hwaccel_output_format d3d12 -i input.mp4
>> -c:v hevc_d3d12va output.mp4
>>
>> Signed-off-by: Tong Wu 
>> ---
>> configure|6 +
>> libavcodec/Makefile  |4 +-
>> libavcodec/allcodecs.c   |1 +
>> libavcodec/d3d12va_encode.c  | 1441 ++
>> libavcodec/d3d12va_encode.h  |  275 ++
>> libavcodec/d3d12va_encode_hevc.c | 1011 +
>> libavcodec/hw_base_encode.h  |2 +-
>> 7 files changed, 2738 insertions(+), 2 deletions(-)
>> create mode 100644 libavcodec/d3d12va_encode.c
>> create mode 100644 libavcodec/d3d12va_encode.h
>> create mode 100644 libavcodec/d3d12va_encode_hevc.c
>>
>>
>>+min_cu_size = d3d12va_encode_hevc_map_cusize(ctx-
>>codec_conf.pHEVCConfig->MinLumaCodingUnitSize);
>>+max_cu_size = d3d12va_encode_hevc_map_cusize(ctx-
>>codec_conf.pHEVCConfig->MaxLumaCodingUnitSize);
>>+min_tu_size = d3d12va_encode_hevc_map_tusize(ctx-
>>codec_conf.pHEVCConfig->MinLumaTransformUnitSize);
>>+max_tu_size = d3d12va_encode_hevc_map_tusize(ctx-
>>codec_conf.pHEVCConfig->MaxLumaTransformUnitSize);
>>+
>>+// VPS
>>+
>>+vps->nal_unit_header = (H265RawNALUnitHeader) {
>
>Should this blank line be removed, because the comment is for the codes
>below?
>
>> +vps->vps_timing_info_present_flag = 0;
>> +
>> +// SPS
>> +
>> +sps->nal_unit_header = (H265RawNALUnitHeader) {
>> +.nal_unit_type = HEVC_NAL_SPS,
>> +.nuh_layer_id  = 0,
>> +.nuh_temporal_id_plus1 = 1,
>> +};
>The same as above.
>
>> +static uint8_t
>d3d12va_encode_hevc_map_cusize(D3D12_VIDEO_ENCODER_CODEC_CONFI
>GURATION_HEVC_CUSIZE cusize)
>> +{
>> +switch (cusize) {
>> +case
>D3D12_VIDEO_ENCODER_CODEC_CONFIGURATION_HEVC_CUSIZE_8x8:
>return 8;
>> +case
>D3D12_VIDEO_ENCODER_CODEC_CONFIGURATION_HEVC_CUSIZE_16x16:
>return 16;
>> +case
>D3D12_VIDEO_ENCODER_CODEC_CONFIGURATION_HEVC_CUSIZE_32x32:
>return 32;
>> +case
>D3D12_VIDEO_ENCODER_CODEC_CONFIGURATION_HEVC_CUSIZE_64x64:
>return 64;
>> +}
>> +return 0;
>> +}
>> +
>> +static uint8_t
>d3d12va_encode_hevc_map_tusize(D3D12_VIDEO_ENCODER_CODEC_CONFI
>GURATION_HEVC_TUSIZE tusize)
>> +{
>> +switch (tusize) {
>> +case
>D3D12_VIDEO_ENCODER_CODEC_CONFIGURATION_HEVC_TUSIZE_4x4:
>return 4;
>> +case
>D3D12_VIDEO_ENCODER_CODEC_CONFIGURATION_HEVC_TUSIZE_8x8:
>return 8;
>> +case
>D3D12_VIDEO_ENCODER_CODEC_CONFIGURATION_HEVC_TUSIZE_16x16:
>return 16;
>> +case
>D3D12_VIDEO_ENCODER_CODEC_CONFIGURATION_HEVC_TUSIZE_32x32:
>return 32;
>> +}
>> +return 0;
>> +}
>
>A default branch is needed or we can use 8 << cusize and 4 << tusize for
>simplification.
>
>> +hr = ID3D12Device3_QueryInterface(ctx->device3,
>&IID_ID3D12VideoDevice3, (void **)&ctx->video_device3);
>> +if (FAILED(hr)) {
>> +err = AVERROR_UNKNOWN;
>> +goto fail;
>> +}
>> +
>> +if (FAILED(ID3D12VideoDevice3_CheckFeatureSupport(ctx-
>>video_device3, D3D12_FEATURE_VIDEO_FEATURE_AREA_SUPPORT,
>> +  &support, 
>> sizeof(support)))
>&& !support.VideoEncodeSupport) {
>> +av_log(avctx, AV_LOG_ERROR, "D3D12 video device has no video
>encoder support");
>> +err = AVERROR(EINVAL);
>> +goto fail;
>> +}
>
>We need to output the log for the ID3D12Device3_QueryInterface call, or the
>user will not know the error is resulting from that,
>the OS and the driver don't support the ID3D12VideoDevice3 interface.

Have updated in v4. Thanks for the review.

BRs,
Tong

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


[FFmpeg-devel] [PATCH v3 8/9] avcodec: add D3D12VA hardware HEVC encoder

2024-02-02 Thread tong1 . wu-at-intel . com
From: Tong Wu 

This implementation is based on D3D12 Video Encoding Spec:
https://microsoft.github.io/DirectX-Specs/d3d/D3D12VideoEncoding.html

Sample command line for transcoding:
ffmpeg.exe -hwaccel d3d12va -hwaccel_output_format d3d12 -i input.mp4
-c:v hevc_d3d12va output.mp4

Signed-off-by: Tong Wu 
---
 configure|6 +
 libavcodec/Makefile  |4 +-
 libavcodec/allcodecs.c   |1 +
 libavcodec/d3d12va_encode.c  | 1441 ++
 libavcodec/d3d12va_encode.h  |  275 ++
 libavcodec/d3d12va_encode_hevc.c | 1011 +
 libavcodec/hw_base_encode.h  |2 +-
 7 files changed, 2738 insertions(+), 2 deletions(-)
 create mode 100644 libavcodec/d3d12va_encode.c
 create mode 100644 libavcodec/d3d12va_encode.h
 create mode 100644 libavcodec/d3d12va_encode_hevc.c

diff --git a/configure b/configure
index 68f675a4bc..0d6f5b3e2e 100755
--- a/configure
+++ b/configure
@@ -2561,6 +2561,7 @@ CONFIG_EXTRA="
 tpeldsp
 vaapi_1
 vaapi_encode
+d3d12va_encode
 vc1dsp
 videodsp
 vp3dsp
@@ -3205,6 +3206,7 @@ wmv3_vaapi_hwaccel_select="vc1_vaapi_hwaccel"
 wmv3_vdpau_hwaccel_select="vc1_vdpau_hwaccel"
 
 # hardware-accelerated codecs
+d3d12va_encode_deps="d3d12va ID3D12VideoEncoder d3d12_encoder_feature"
 mediafoundation_deps="mftransform_h MFCreateAlignedMemoryBuffer"
 omx_deps="libdl pthreads"
 omx_rpi_select="omx"
@@ -3272,6 +3274,7 @@ h264_v4l2m2m_encoder_deps="v4l2_m2m h264_v4l2_m2m"
 hevc_amf_encoder_deps="amf"
 hevc_cuvid_decoder_deps="cuvid"
 hevc_cuvid_decoder_select="hevc_mp4toannexb_bsf"
+hevc_d3d12va_encoder_select="atsc_a53 cbs_h265 d3d12va_encode"
 hevc_mediacodec_decoder_deps="mediacodec"
 hevc_mediacodec_decoder_select="hevc_mp4toannexb_bsf hevc_parser"
 hevc_mediacodec_encoder_deps="mediacodec"
@@ -6613,6 +6616,9 @@ check_type "windows.h d3d11.h" "ID3D11VideoDecoder"
 check_type "windows.h d3d11.h" "ID3D11VideoContext"
 check_type "windows.h d3d12.h" "ID3D12Device"
 check_type "windows.h d3d12video.h" "ID3D12VideoDecoder"
+check_type "windows.h d3d12video.h" "ID3D12VideoEncoder"
+test_code cc "windows.h d3d12video.h" "D3D12_FEATURE_VIDEO feature = 
D3D12_FEATURE_VIDEO_ENCODER_CODEC" && \
+test_code cc "windows.h d3d12video.h" 
"D3D12_FEATURE_DATA_VIDEO_ENCODER_RESOURCE_REQUIREMENTS req" && enable 
d3d12_encoder_feature
 check_type "windows.h" "DPI_AWARENESS_CONTEXT" -D_WIN32_WINNT=0x0A00
 check_type "d3d9.h dxva2api.h" DXVA2_ConfigPictureDecode -D_WIN32_WINNT=0x0602
 check_func_headers mfapi.h MFCreateAlignedMemoryBuffer -lmfplat
diff --git a/libavcodec/Makefile b/libavcodec/Makefile
index 23946f6ea3..50590b34f4 100644
--- a/libavcodec/Makefile
+++ b/libavcodec/Makefile
@@ -86,6 +86,7 @@ OBJS-$(CONFIG_CBS_MPEG2)   += cbs_mpeg2.o
 OBJS-$(CONFIG_CBS_VP8) += cbs_vp8.o vp8data.o
 OBJS-$(CONFIG_CBS_VP9) += cbs_vp9.o
 OBJS-$(CONFIG_CRYSTALHD)   += crystalhd.o
+OBJS-$(CONFIG_D3D12VA_ENCODE)  += d3d12va_encode.o hw_base_encode.o
 OBJS-$(CONFIG_DEFLATE_WRAPPER) += zlib_wrapper.o
 OBJS-$(CONFIG_DOVI_RPU)+= dovi_rpu.o
 OBJS-$(CONFIG_ERROR_RESILIENCE)+= error_resilience.o
@@ -437,6 +438,7 @@ OBJS-$(CONFIG_HEVC_DECODER)+= hevcdec.o 
hevc_mvs.o \
   h274.o
 OBJS-$(CONFIG_HEVC_AMF_ENCODER)+= amfenc_hevc.o
 OBJS-$(CONFIG_HEVC_CUVID_DECODER)  += cuviddec.o
+OBJS-$(CONFIG_HEVC_D3D12VA_ENCODER)+= d3d12va_encode_hevc.o
 OBJS-$(CONFIG_HEVC_MEDIACODEC_DECODER) += mediacodecdec.o
 OBJS-$(CONFIG_HEVC_MEDIACODEC_ENCODER) += mediacodecenc.o
 OBJS-$(CONFIG_HEVC_MF_ENCODER) += mfenc.o mf_utils.o
@@ -1267,7 +1269,7 @@ SKIPHEADERS+= %_tablegen.h
  \
 
 SKIPHEADERS-$(CONFIG_AMF)  += amfenc.h
 SKIPHEADERS-$(CONFIG_D3D11VA)  += d3d11va.h dxva2_internal.h
-SKIPHEADERS-$(CONFIG_D3D12VA)  += d3d12va_decode.h
+SKIPHEADERS-$(CONFIG_D3D12VA)  += d3d12va_decode.h d3d12va_encode.h
 SKIPHEADERS-$(CONFIG_DXVA2)+= dxva2.h dxva2_internal.h
 SKIPHEADERS-$(CONFIG_JNI)  += ffjni.h
 SKIPHEADERS-$(CONFIG_LCMS2)+= fflcms2.h
diff --git a/libavcodec/allcodecs.c b/libavcodec/allcodecs.c
index ef8c3a6d7d..9a34974141 100644
--- a/libavcodec/allcodecs.c
+++ b/libavcodec/allcodecs.c
@@ -865,6 +865,7 @@ extern const FFCodec ff_h264_vaapi_encoder;
 extern const FFCodec ff_h264_videotoolbox_encoder;
 extern const FFCodec ff_hevc_amf_encoder;
 extern const FFCodec ff_hevc_cuvid_decoder;
+extern const FFCodec ff_hevc_d3d12va_encoder;
 extern const FFCodec ff_hevc_mediacodec_decoder;
 extern const FFCodec ff_hevc_mediacodec_encoder;
 extern const FFCodec ff_hevc_mf_encoder;
diff --git a/libavcodec/d3d12va_encode.c b/libavcodec/d3d12va_encode.c
new file mode 100644
index 00..28fa1dcc69
--- /dev/null
+++ b/libavcodec/d3d12va_encode.c
@@ -0,0 +1,1441 @@
+/*