#ifndef MEDIA_GPU_WINDOWS_D3D12_VIDEO_ENCODE_AV1_DELEGATE_H_
#define MEDIA_GPU_WINDOWS_D3D12_VIDEO_ENCODE_AV1_DELEGATE_H_
#include "third_party/microsoft_dxheaders/src/include/directx/d3d12video.h"
#include "media/gpu/av1_builder.h"
#include "media/gpu/windows/d3d12_video_encode_delegate.h"
namespace aom {
class AV1RateControlRTC;
}
namespace media {
class MEDIA_GPU_EXPORT D3D12VideoEncodeAV1Delegate
: public D3D12VideoEncodeDelegate {
public:
struct PictureControlFlags {
bool allow_screen_content_tools = false;
bool allow_intrabc = false;
bool enable_auto_segmentation = false;
};
struct D3D12EncodingCapabilities {
D3D12_VIDEO_ENCODER_AV1_INTERPOLATION_FILTERS interpolation_filter;
D3D12_VIDEO_ENCODER_AV1_RESTORATION_CONFIG loop_restoration;
std::array<D3D12_VIDEO_ENCODER_AV1_TX_MODE, 2> tx_modes;
D3D12_VIDEO_ENCODER_AV1_POST_ENCODE_VALUES_FLAGS post_value_flags;
};
static std::vector<
std::pair<VideoCodecProfile, std::vector<VideoPixelFormat>>>
GetSupportedProfiles(ID3D12VideoDevice3* video_device);
explicit D3D12VideoEncodeAV1Delegate(
Microsoft::WRL::ComPtr<ID3D12VideoDevice3> video_device);
~D3D12VideoEncodeAV1Delegate() override;
size_t GetMaxNumOfRefFrames() const override;
size_t GetMaxNumOfManualRefBuffers() const override;
EncoderStatus EncodeImpl(ID3D12Resource* input_frame,
UINT input_frame_subresource,
const VideoEncoder::EncodeOptions& options,
const gfx::ColorSpace& input_color_space) override;
bool SupportsRateControlReconfiguration() const override;
bool UpdateRateControl(const VideoBitrateAllocation& bitrate_allocation,
uint32_t framerate) override;
bool ReportsAverageQp() const override;
private:
friend class D3D12VideoEncodeAV1DelegateTest;
EncoderStatus InitializeVideoEncoder(
const VideoEncodeAccelerator::Config& config) override;
EncoderStatus::Or<size_t> GetEncodedBitstreamWrittenBytesCount(
const ScopedD3D12ResourceMap& metadata) override;
void RefreshDPBAndDescriptors();
size_t PackAV1BitstreamHeader(
const AV1BitstreamBuilder::FrameHeader& frame_header,
size_t compressed_size,
base::span<uint8_t> bitstream_buffer);
EncoderStatus::Or<size_t> ReadbackBitstream(
base::span<uint8_t> bitstream_buffer) override;
void FillPictureControlParams(const VideoEncoder::EncodeOptions& options);
bool UpdateFrameHeaderPostEncode(
const D3D12_VIDEO_ENCODER_AV1_POST_ENCODE_VALUES_FLAGS& post_encode_flags,
const D3D12_VIDEO_ENCODER_AV1_POST_ENCODE_VALUES& post_encode_values,
AV1BitstreamBuilder::FrameHeader& frame_header);
bool IsKeyFrame() const { return picture_id_ == 0; }
uint32_t max_num_ref_frames_ = 0;
D3D12_VIDEO_ENCODER_ENCODEFRAME_INPUT_ARGUMENTS input_arguments_{};
D3D12_VIDEO_ENCODER_AV1_SEQUENCE_STRUCTURE gop_sequence_{};
D3D12_VIDEO_ENCODER_AV1_PICTURE_CONTROL_CODEC_DATA picture_params_{};
std::array<D3D12_VIDEO_ENCODER_AV1_REFERENCE_PICTURE_DESCRIPTOR, 8>
reference_descriptors_{};
std::unique_ptr<aom::AV1RateControlRTC> software_brc_;
D3D12EncodingCapabilities enc_caps_{};
D3D12_VIDEO_ENCODER_AV1_FEATURE_FLAGS enabled_features_{};
PictureControlFlags picture_ctrl_{};
D3D12_VIDEO_ENCODER_AV1_PICTURE_CONTROL_SUBREGIONS_LAYOUT_DATA_TILES
sub_layout_{};
bool is_screen_ = false;
AV1BitstreamBuilder::SequenceHeader sequence_header_;
D3D12VideoEncodeDecodedPictureBuffers<kAV1DPBMaxSize> dpb_;
int picture_id_ = -1;
D3D12VideoEncoderRateControl current_rate_control_;
};
}
#endif