mirror of
https://git.ffmpeg.org/ffmpeg.git
synced 2026-06-16 04:32:47 +02:00
avcodec/d3d12va_encode: D3D12 AV1 encoding support
Implement AV1 hardware encoding using Direct3D 12 Video API (D3D12VA).
This commit is contained in:
@@ -10,6 +10,7 @@ version <next>:
|
||||
- D3D12 H.264 encoder
|
||||
- drawvg filter via libcairo
|
||||
- ffmpeg CLI tiled HEIF support
|
||||
- D3D12 AV1 encoder
|
||||
|
||||
|
||||
version 8.0:
|
||||
|
||||
@@ -3444,6 +3444,8 @@ amrwb_mediacodec_decoder_select="amr_parser"
|
||||
av1_amf_encoder_deps="amf"
|
||||
av1_amf_decoder_deps="amf"
|
||||
av1_cuvid_decoder_deps="cuvid CUVIDAV1PICPARAMS"
|
||||
av1_d3d12va_encoder_deps="d3d12va d3d12va_av1_headers"
|
||||
av1_d3d12va_encoder_select="cbs_av1 d3d12va_encode"
|
||||
av1_mediacodec_decoder_deps="mediacodec"
|
||||
av1_mediacodec_encoder_deps="mediacodec"
|
||||
av1_mediacodec_encoder_select="extract_extradata_bsf"
|
||||
@@ -6958,6 +6960,7 @@ 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
|
||||
test_code cc "windows.h d3d12video.h" "D3D12_VIDEO_ENCODER_CODEC c = D3D12_VIDEO_ENCODER_CODEC_AV1; (void)c;" && enable d3d12va_av1_headers
|
||||
check_type "windows.h" "DPI_AWARENESS_CONTEXT" -D_WIN32_WINNT=0x0A00
|
||||
check_type "windows.h security.h schnlsp.h" SecPkgContext_KeyingMaterialInfo -DSECURITY_WIN32
|
||||
check_type "d3d9.h dxva2api.h" DXVA2_ConfigPictureDecode -D_WIN32_WINNT=0x0602
|
||||
|
||||
@@ -274,6 +274,7 @@ OBJS-$(CONFIG_AURA_DECODER) += cyuv.o
|
||||
OBJS-$(CONFIG_AURA2_DECODER) += aura.o
|
||||
OBJS-$(CONFIG_AV1_DECODER) += av1dec.o av1_parse.o
|
||||
OBJS-$(CONFIG_AV1_CUVID_DECODER) += cuviddec.o
|
||||
OBJS-$(CONFIG_AV1_D3D12VA_ENCODER) += d3d12va_encode_av1.o av1_levels.o
|
||||
OBJS-$(CONFIG_AV1_MEDIACODEC_DECODER) += mediacodecdec.o
|
||||
OBJS-$(CONFIG_AV1_MEDIACODEC_ENCODER) += mediacodecenc.o
|
||||
OBJS-$(CONFIG_AV1_NVENC_ENCODER) += nvenc_av1.o nvenc.o
|
||||
|
||||
@@ -855,6 +855,7 @@ extern const FFCodec ff_libaom_av1_decoder;
|
||||
/* hwaccel hooks only, so prefer external decoders */
|
||||
extern const FFCodec ff_av1_decoder;
|
||||
extern const FFCodec ff_av1_cuvid_decoder;
|
||||
extern const FFCodec ff_av1_d3d12va_encoder;
|
||||
extern const FFCodec ff_av1_mediacodec_decoder;
|
||||
extern const FFCodec ff_av1_mediacodec_encoder;
|
||||
extern const FFCodec ff_av1_nvenc_encoder;
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
#include "libavutil/hwcontext_d3d12va_internal.h"
|
||||
#include "libavutil/hwcontext_d3d12va.h"
|
||||
|
||||
#include "config_components.h"
|
||||
#include "avcodec.h"
|
||||
#include "d3d12va_encode.h"
|
||||
#include "encode.h"
|
||||
@@ -144,6 +145,12 @@ static int d3d12va_encode_create_metadata_buffers(AVCodecContext *avctx,
|
||||
{
|
||||
D3D12VAEncodeContext *ctx = avctx->priv_data;
|
||||
int width = sizeof(D3D12_VIDEO_ENCODER_OUTPUT_METADATA) + sizeof(D3D12_VIDEO_ENCODER_FRAME_SUBREGION_METADATA);
|
||||
#if CONFIG_AV1_D3D12VA_ENCODER
|
||||
if (ctx->codec->d3d12_codec == D3D12_VIDEO_ENCODER_CODEC_AV1) {
|
||||
width += sizeof(D3D12_VIDEO_ENCODER_AV1_PICTURE_CONTROL_SUBREGIONS_LAYOUT_DATA_TILES)
|
||||
+ sizeof(D3D12_VIDEO_ENCODER_AV1_POST_ENCODE_VALUES);
|
||||
}
|
||||
#endif
|
||||
D3D12_HEAP_PROPERTIES encoded_meta_props = { .Type = D3D12_HEAP_TYPE_DEFAULT }, resolved_meta_props;
|
||||
D3D12_HEAP_TYPE resolved_heap_type = D3D12_HEAP_TYPE_READBACK;
|
||||
HRESULT hr;
|
||||
@@ -211,7 +218,7 @@ static int d3d12va_encode_issue(AVCodecContext *avctx,
|
||||
.RateControl = ctx->rc,
|
||||
.PictureTargetResolution = ctx->resolution,
|
||||
.SelectedLayoutMode = D3D12_VIDEO_ENCODER_FRAME_SUBREGION_LAYOUT_MODE_FULL_FRAME,
|
||||
.FrameSubregionsLayoutData = { 0 },
|
||||
.FrameSubregionsLayoutData = ctx->subregions_layout,
|
||||
.CodecGopSequence = ctx->gop,
|
||||
},
|
||||
.pInputFrame = pic->input_surface->texture,
|
||||
@@ -732,16 +739,21 @@ end:
|
||||
static int d3d12va_encode_output(AVCodecContext *avctx,
|
||||
FFHWBaseEncodePicture *base_pic, AVPacket *pkt)
|
||||
{
|
||||
D3D12VAEncodeContext *ctx = avctx->priv_data;
|
||||
FFHWBaseEncodeContext *base_ctx = avctx->priv_data;
|
||||
D3D12VAEncodePicture *pic = base_pic->priv;
|
||||
AVPacket *pkt_ptr = pkt;
|
||||
int err;
|
||||
D3D12VAEncodePicture *pic = base_pic->priv;
|
||||
AVPacket *pkt_ptr = pkt;
|
||||
int err = 0;
|
||||
|
||||
err = d3d12va_encode_wait(avctx, base_pic);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
err = d3d12va_encode_get_coded_data(avctx, pic, pkt);
|
||||
if (ctx->codec->get_coded_data)
|
||||
err = ctx->codec->get_coded_data(avctx, pic, pkt);
|
||||
else
|
||||
err = d3d12va_encode_get_coded_data(avctx, pic, pkt);
|
||||
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
@@ -1129,6 +1141,9 @@ static int d3d12va_encode_init_gop_structure(AVCodecContext *avctx)
|
||||
union {
|
||||
D3D12_VIDEO_ENCODER_CODEC_PICTURE_CONTROL_SUPPORT_H264 h264;
|
||||
D3D12_VIDEO_ENCODER_CODEC_PICTURE_CONTROL_SUPPORT_HEVC hevc;
|
||||
#if CONFIG_AV1_D3D12VA_ENCODER
|
||||
D3D12_VIDEO_ENCODER_CODEC_AV1_PICTURE_CONTROL_SUPPORT av1;
|
||||
#endif
|
||||
} codec_support;
|
||||
|
||||
support.NodeIndex = 0;
|
||||
@@ -1146,6 +1161,13 @@ static int d3d12va_encode_init_gop_structure(AVCodecContext *avctx)
|
||||
support.PictureSupport.pHEVCSupport = &codec_support.hevc;
|
||||
break;
|
||||
|
||||
#if CONFIG_AV1_D3D12VA_ENCODER
|
||||
case D3D12_VIDEO_ENCODER_CODEC_AV1:
|
||||
memset(&codec_support.av1, 0, sizeof(codec_support.av1));
|
||||
support.PictureSupport.DataSize = sizeof(codec_support.av1);
|
||||
support.PictureSupport.pAV1Support = &codec_support.av1;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
av_assert0(0);
|
||||
}
|
||||
@@ -1171,6 +1193,13 @@ static int d3d12va_encode_init_gop_structure(AVCodecContext *avctx)
|
||||
ref_l1 = support.PictureSupport.pHEVCSupport->MaxL1ReferencesForB;
|
||||
break;
|
||||
|
||||
#if CONFIG_AV1_D3D12VA_ENCODER
|
||||
case D3D12_VIDEO_ENCODER_CODEC_AV1:
|
||||
ref_l0 = support.PictureSupport.pAV1Support->MaxUniqueReferencesPerFrame;
|
||||
// AV1 doesn't use traditional L1 references like H.264/HEVC
|
||||
ref_l1 = 0;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
av_assert0(0);
|
||||
}
|
||||
@@ -1521,6 +1550,12 @@ int ff_d3d12va_encode_init(AVCodecContext *avctx)
|
||||
if (err < 0)
|
||||
goto fail;
|
||||
|
||||
if (ctx->codec->set_tile) {
|
||||
err = ctx->codec->set_tile(avctx);
|
||||
if (err < 0)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
err = d3d12va_encode_init_rate_control(avctx);
|
||||
if (err < 0)
|
||||
goto fail;
|
||||
|
||||
@@ -264,6 +264,8 @@ typedef struct D3D12VAEncodeContext {
|
||||
D3D12_VIDEO_ENCODER_SEQUENCE_GOP_STRUCTURE gop;
|
||||
|
||||
D3D12_VIDEO_ENCODER_LEVEL_SETTING level;
|
||||
|
||||
D3D12_VIDEO_ENCODER_PICTURE_CONTROL_SUBREGIONS_LAYOUT_DATA subregions_layout;
|
||||
} D3D12VAEncodeContext;
|
||||
|
||||
typedef struct D3D12VAEncodeType {
|
||||
@@ -306,6 +308,11 @@ typedef struct D3D12VAEncodeType {
|
||||
*/
|
||||
int (*set_level)(AVCodecContext *avctx);
|
||||
|
||||
/**
|
||||
* Set codec-specific tile setting.
|
||||
*/
|
||||
int (*set_tile)(AVCodecContext *avctx);
|
||||
|
||||
/**
|
||||
* The size of any private data structure associated with each
|
||||
* picture (can be zero if not required).
|
||||
@@ -327,6 +334,12 @@ typedef struct D3D12VAEncodeType {
|
||||
*/
|
||||
int (*write_sequence_header)(AVCodecContext *avctx,
|
||||
char *data, size_t *data_len);
|
||||
|
||||
/**
|
||||
* Fill the coded data into AVPacket
|
||||
*/
|
||||
int (*get_coded_data)(AVCodecContext *avctx,
|
||||
D3D12VAEncodePicture *pic, AVPacket *pkt);
|
||||
} D3D12VAEncodeType;
|
||||
|
||||
int ff_d3d12va_encode_receive_packet(AVCodecContext *avctx, AVPacket *pkt);
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user