mirror of
https://git.ffmpeg.org/ffmpeg.git
synced 2025-02-19 21:36:54 +00:00
avcodec: add D3D12VA hardware HEVC encoder
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 <tong1.wu@intel.com>
This commit is contained in:
parent
d822146f4f
commit
ba0c14e6bf
6
configure
vendored
6
configure
vendored
@ -2547,6 +2547,7 @@ CONFIG_EXTRA="
|
||||
cbs_mpeg2
|
||||
cbs_vp8
|
||||
cbs_vp9
|
||||
d3d12va_encode
|
||||
deflate_wrapper
|
||||
dirac_parse
|
||||
dnn
|
||||
@ -3283,6 +3284,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"
|
||||
@ -3350,6 +3352,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="cbs_h265 d3d12va_encode"
|
||||
hevc_mediacodec_decoder_deps="mediacodec"
|
||||
hevc_mediacodec_decoder_select="hevc_mp4toannexb_bsf hevc_parser"
|
||||
hevc_mediacodec_encoder_deps="mediacodec"
|
||||
@ -6692,6 +6695,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
|
||||
|
@ -87,6 +87,7 @@ OBJS-$(CONFIG_CBS_JPEG) += cbs_jpeg.o
|
||||
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_D3D12VA_ENCODE) += d3d12va_encode.o hw_base_encode.o
|
||||
OBJS-$(CONFIG_DEFLATE_WRAPPER) += zlib_wrapper.o
|
||||
OBJS-$(CONFIG_DOVI_RPUDEC) += dovi_rpu.o dovi_rpudec.o
|
||||
OBJS-$(CONFIG_DOVI_RPUENC) += dovi_rpu.o dovi_rpuenc.o
|
||||
@ -433,6 +434,8 @@ OBJS-$(CONFIG_HDR_ENCODER) += hdrenc.o
|
||||
OBJS-$(CONFIG_HEVC_DECODER) += aom_film_grain.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 h265_profile_level.o \
|
||||
h2645data.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
|
||||
@ -1262,7 +1265,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
|
||||
|
@ -849,6 +849,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;
|
||||
|
1558
libavcodec/d3d12va_encode.c
Normal file
1558
libavcodec/d3d12va_encode.c
Normal file
File diff suppressed because it is too large
Load Diff
334
libavcodec/d3d12va_encode.h
Normal file
334
libavcodec/d3d12va_encode.h
Normal file
@ -0,0 +1,334 @@
|
||||
/*
|
||||
* Direct3D 12 HW acceleration video encoder
|
||||
*
|
||||
* Copyright (c) 2024 Intel Corporation
|
||||
*
|
||||
* This file is part of FFmpeg.
|
||||
*
|
||||
* FFmpeg is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* FFmpeg is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with FFmpeg; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef AVCODEC_D3D12VA_ENCODE_H
|
||||
#define AVCODEC_D3D12VA_ENCODE_H
|
||||
|
||||
#include "libavutil/fifo.h"
|
||||
#include "libavutil/hwcontext.h"
|
||||
#include "libavutil/hwcontext_d3d12va_internal.h"
|
||||
#include "libavutil/hwcontext_d3d12va.h"
|
||||
#include "avcodec.h"
|
||||
#include "internal.h"
|
||||
#include "hwconfig.h"
|
||||
#include "hw_base_encode.h"
|
||||
|
||||
struct D3D12VAEncodeType;
|
||||
|
||||
extern const AVCodecHWConfigInternal *const ff_d3d12va_encode_hw_configs[];
|
||||
|
||||
#define MAX_PARAM_BUFFER_SIZE 4096
|
||||
#define D3D12VA_VIDEO_ENC_ASYNC_DEPTH 8
|
||||
|
||||
typedef struct D3D12VAEncodePicture {
|
||||
FFHWBaseEncodePicture base;
|
||||
|
||||
int header_size;
|
||||
|
||||
AVD3D12VAFrame *input_surface;
|
||||
AVD3D12VAFrame *recon_surface;
|
||||
|
||||
AVBufferRef *output_buffer_ref;
|
||||
ID3D12Resource *output_buffer;
|
||||
|
||||
ID3D12Resource *encoded_metadata;
|
||||
ID3D12Resource *resolved_metadata;
|
||||
|
||||
D3D12_VIDEO_ENCODER_PICTURE_CONTROL_CODEC_DATA pic_ctl;
|
||||
|
||||
int fence_value;
|
||||
} D3D12VAEncodePicture;
|
||||
|
||||
typedef struct D3D12VAEncodeProfile {
|
||||
/**
|
||||
* lavc profile value (AV_PROFILE_*).
|
||||
*/
|
||||
int av_profile;
|
||||
|
||||
/**
|
||||
* Supported bit depth.
|
||||
*/
|
||||
int depth;
|
||||
|
||||
/**
|
||||
* Number of components.
|
||||
*/
|
||||
int nb_components;
|
||||
|
||||
/**
|
||||
* Chroma subsampling in width dimension.
|
||||
*/
|
||||
int log2_chroma_w;
|
||||
|
||||
/**
|
||||
* Chroma subsampling in height dimension.
|
||||
*/
|
||||
int log2_chroma_h;
|
||||
|
||||
/**
|
||||
* D3D12 profile value.
|
||||
*/
|
||||
D3D12_VIDEO_ENCODER_PROFILE_DESC d3d12_profile;
|
||||
} D3D12VAEncodeProfile;
|
||||
|
||||
enum {
|
||||
RC_MODE_AUTO,
|
||||
RC_MODE_CQP,
|
||||
RC_MODE_CBR,
|
||||
RC_MODE_VBR,
|
||||
RC_MODE_QVBR,
|
||||
RC_MODE_MAX = RC_MODE_QVBR,
|
||||
};
|
||||
|
||||
|
||||
typedef struct D3D12VAEncodeRCMode {
|
||||
/**
|
||||
* Mode from above enum (RC_MODE_*).
|
||||
*/
|
||||
int mode;
|
||||
|
||||
/**
|
||||
* Name.
|
||||
*
|
||||
*/
|
||||
const char *name;
|
||||
|
||||
/**
|
||||
* Uses bitrate parameters.
|
||||
*
|
||||
*/
|
||||
int bitrate;
|
||||
|
||||
/**
|
||||
* Supports maxrate distinct from bitrate.
|
||||
*
|
||||
*/
|
||||
int maxrate;
|
||||
|
||||
/**
|
||||
* Uses quality value.
|
||||
*
|
||||
*/
|
||||
int quality;
|
||||
|
||||
/**
|
||||
* Supports HRD/VBV parameters.
|
||||
*
|
||||
*/
|
||||
int hrd;
|
||||
|
||||
/**
|
||||
* D3D12 mode value.
|
||||
*/
|
||||
D3D12_VIDEO_ENCODER_RATE_CONTROL_MODE d3d12_mode;
|
||||
} D3D12VAEncodeRCMode;
|
||||
|
||||
typedef struct D3D12VAEncodeContext {
|
||||
FFHWBaseEncodeContext base;
|
||||
|
||||
/**
|
||||
* Codec-specific hooks.
|
||||
*/
|
||||
const struct D3D12VAEncodeType *codec;
|
||||
|
||||
/**
|
||||
* Explicitly set RC mode (otherwise attempt to pick from
|
||||
* available modes).
|
||||
*/
|
||||
int explicit_rc_mode;
|
||||
|
||||
/**
|
||||
* Explicitly-set QP, for use with the "qp" options.
|
||||
* (Forces CQP mode when set, overriding everything else.)
|
||||
*/
|
||||
int explicit_qp;
|
||||
|
||||
/**
|
||||
* RC quality level - meaning depends on codec and RC mode.
|
||||
* In CQP mode this sets the fixed quantiser value.
|
||||
*/
|
||||
int rc_quality;
|
||||
|
||||
/**
|
||||
* Chosen encoding profile details.
|
||||
*/
|
||||
const D3D12VAEncodeProfile *profile;
|
||||
|
||||
AVD3D12VADeviceContext *hwctx;
|
||||
|
||||
/**
|
||||
* ID3D12Device3 interface.
|
||||
*/
|
||||
ID3D12Device3 *device3;
|
||||
|
||||
/**
|
||||
* ID3D12VideoDevice3 interface.
|
||||
*/
|
||||
ID3D12VideoDevice3 *video_device3;
|
||||
|
||||
/**
|
||||
* Pool of (reusable) bitstream output buffers.
|
||||
*/
|
||||
AVBufferPool *output_buffer_pool;
|
||||
|
||||
/**
|
||||
* D3D12 video encoder.
|
||||
*/
|
||||
AVBufferRef *encoder_ref;
|
||||
|
||||
ID3D12VideoEncoder *encoder;
|
||||
|
||||
/**
|
||||
* D3D12 video encoder heap.
|
||||
*/
|
||||
ID3D12VideoEncoderHeap *encoder_heap;
|
||||
|
||||
/**
|
||||
* A cached queue for reusing the D3D12 command allocators.
|
||||
*
|
||||
* @see https://learn.microsoft.com/en-us/windows/win32/direct3d12/recording-command-lists-and-bundles#id3d12commandallocator
|
||||
*/
|
||||
AVFifo *allocator_queue;
|
||||
|
||||
/**
|
||||
* D3D12 command queue.
|
||||
*/
|
||||
ID3D12CommandQueue *command_queue;
|
||||
|
||||
/**
|
||||
* D3D12 video encode command list.
|
||||
*/
|
||||
ID3D12VideoEncodeCommandList2 *command_list;
|
||||
|
||||
/**
|
||||
* The sync context used to sync command queue.
|
||||
*/
|
||||
AVD3D12VASyncContext sync_ctx;
|
||||
|
||||
/**
|
||||
* The bi_not_empty feature.
|
||||
*/
|
||||
int bi_not_empty;
|
||||
|
||||
/**
|
||||
* D3D12_FEATURE structures.
|
||||
*/
|
||||
D3D12_FEATURE_DATA_VIDEO_ENCODER_RESOURCE_REQUIREMENTS req;
|
||||
|
||||
D3D12_FEATURE_DATA_VIDEO_ENCODER_RESOLUTION_SUPPORT_LIMITS res_limits;
|
||||
|
||||
/**
|
||||
* D3D12_VIDEO_ENCODER structures.
|
||||
*/
|
||||
D3D12_VIDEO_ENCODER_PICTURE_RESOLUTION_DESC resolution;
|
||||
|
||||
D3D12_VIDEO_ENCODER_CODEC_CONFIGURATION codec_conf;
|
||||
|
||||
D3D12_VIDEO_ENCODER_RATE_CONTROL rc;
|
||||
|
||||
D3D12_VIDEO_ENCODER_SEQUENCE_GOP_STRUCTURE gop;
|
||||
|
||||
D3D12_VIDEO_ENCODER_LEVEL_SETTING level;
|
||||
} D3D12VAEncodeContext;
|
||||
|
||||
typedef struct D3D12VAEncodeType {
|
||||
/**
|
||||
* List of supported profiles.
|
||||
*/
|
||||
const D3D12VAEncodeProfile *profiles;
|
||||
|
||||
/**
|
||||
* D3D12 codec name.
|
||||
*/
|
||||
D3D12_VIDEO_ENCODER_CODEC d3d12_codec;
|
||||
|
||||
/**
|
||||
* Codec feature flags.
|
||||
*/
|
||||
int flags;
|
||||
|
||||
/**
|
||||
* Default quality for this codec - used as quantiser or RC quality
|
||||
* factor depending on RC mode.
|
||||
*/
|
||||
int default_quality;
|
||||
|
||||
/**
|
||||
* Query codec configuration and determine encode parameters like
|
||||
* block sizes for surface alignment and slices. If not set, assume
|
||||
* that all blocks are 16x16 and that surfaces should be aligned to match
|
||||
* this.
|
||||
*/
|
||||
int (*get_encoder_caps)(AVCodecContext *avctx);
|
||||
|
||||
/**
|
||||
* Perform any extra codec-specific configuration.
|
||||
*/
|
||||
int (*configure)(AVCodecContext *avctx);
|
||||
|
||||
/**
|
||||
* Set codec-specific level setting.
|
||||
*/
|
||||
int (*set_level)(AVCodecContext *avctx);
|
||||
|
||||
/**
|
||||
* The size of any private data structure associated with each
|
||||
* picture (can be zero if not required).
|
||||
*/
|
||||
size_t picture_priv_data_size;
|
||||
|
||||
/**
|
||||
* Fill the corresponding parameters.
|
||||
*/
|
||||
int (*init_sequence_params)(AVCodecContext *avctx);
|
||||
|
||||
int (*init_picture_params)(AVCodecContext *avctx,
|
||||
D3D12VAEncodePicture *pic);
|
||||
|
||||
void (*free_picture_params)(D3D12VAEncodePicture *pic);
|
||||
|
||||
/**
|
||||
* Write the packed header data to the provided buffer.
|
||||
*/
|
||||
int (*write_sequence_header)(AVCodecContext *avctx,
|
||||
char *data, size_t *data_len);
|
||||
} D3D12VAEncodeType;
|
||||
|
||||
int ff_d3d12va_encode_init(AVCodecContext *avctx);
|
||||
int ff_d3d12va_encode_close(AVCodecContext *avctx);
|
||||
|
||||
#define D3D12VA_ENCODE_RC_MODE(name, desc) \
|
||||
{ #name, desc, 0, AV_OPT_TYPE_CONST, { .i64 = RC_MODE_ ## name }, \
|
||||
0, 0, FLAGS, .unit = "rc_mode" }
|
||||
#define D3D12VA_ENCODE_RC_OPTIONS \
|
||||
{ "rc_mode",\
|
||||
"Set rate control mode", \
|
||||
OFFSET(common.explicit_rc_mode), AV_OPT_TYPE_INT, \
|
||||
{ .i64 = RC_MODE_AUTO }, RC_MODE_AUTO, RC_MODE_MAX, FLAGS, .unit = "rc_mode" }, \
|
||||
{ "auto", "Choose mode automatically based on other parameters", \
|
||||
0, AV_OPT_TYPE_CONST, { .i64 = RC_MODE_AUTO }, 0, 0, FLAGS, .unit = "rc_mode" }, \
|
||||
D3D12VA_ENCODE_RC_MODE(CQP, "Constant-quality"), \
|
||||
D3D12VA_ENCODE_RC_MODE(CBR, "Constant-bitrate"), \
|
||||
D3D12VA_ENCODE_RC_MODE(VBR, "Variable-bitrate"), \
|
||||
D3D12VA_ENCODE_RC_MODE(QVBR, "Quality-defined variable-bitrate")
|
||||
|
||||
#endif /* AVCODEC_D3D12VA_ENCODE_H */
|
1007
libavcodec/d3d12va_encode_hevc.c
Normal file
1007
libavcodec/d3d12va_encode_hevc.c
Normal file
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user