Sunshine/src/nvenc/nvenc_base.h
Cameron Gutman d1a635809a Implement backwards compatibility for NVENC APIs back to Video Codec SDK v11.0
This allows NVENC on drivers 456.71 (October 2020) and later.
2024-02-16 22:31:48 -06:00

93 lines
2.7 KiB
C++

#pragma once
#include "nvenc_colorspace.h"
#include "nvenc_config.h"
#include "nvenc_encoded_frame.h"
#include "src/stat_trackers.h"
#include "src/video.h"
#include <ffnvcodec/nvEncodeAPI.h>
namespace nvenc {
class nvenc_base {
public:
nvenc_base(NV_ENC_DEVICE_TYPE device_type, void *device);
virtual ~nvenc_base();
nvenc_base(const nvenc_base &) = delete;
nvenc_base &
operator=(const nvenc_base &) = delete;
bool
create_encoder(const nvenc_config &config, const video::config_t &client_config, const nvenc_colorspace_t &colorspace, NV_ENC_BUFFER_FORMAT buffer_format);
void
destroy_encoder();
nvenc_encoded_frame
encode_frame(uint64_t frame_index, bool force_idr);
bool
invalidate_ref_frames(uint64_t first_frame, uint64_t last_frame);
protected:
virtual bool
init_library() = 0;
virtual bool
create_and_register_input_buffer() = 0;
virtual bool
wait_for_async_event(uint32_t timeout_ms) { return false; }
bool
nvenc_failed(NVENCSTATUS status);
/**
* @brief This function returns the corresponding struct version for the minimum API required by the codec.
* @details Reducing the struct versions maximizes driver compatibility by avoiding needless API breaks.
* @param version The raw structure version from `NVENCAPI_STRUCT_VERSION()`.
* @param v11_struct_version Optionally specifies the struct version to use with v11 SDK major versions.
* @param v12_struct_version Optionally specifies the struct version to use with v12 SDK major versions.
* @return A suitable struct version for the active codec.
*/
uint32_t
min_struct_version(uint32_t version, uint32_t v11_struct_version = 0, uint32_t v12_struct_version = 0);
const NV_ENC_DEVICE_TYPE device_type;
void *const device;
std::unique_ptr<NV_ENCODE_API_FUNCTION_LIST> nvenc;
void *encoder = nullptr;
struct {
uint32_t width = 0;
uint32_t height = 0;
NV_ENC_BUFFER_FORMAT buffer_format = NV_ENC_BUFFER_FORMAT_UNDEFINED;
uint32_t ref_frames_in_dpb = 0;
bool rfi = false;
} encoder_params;
// Derived classes set these variables
NV_ENC_REGISTERED_PTR registered_input_buffer = nullptr;
void *async_event_handle = nullptr;
std::string last_error_string;
private:
NV_ENC_OUTPUT_PTR output_bitstream = nullptr;
uint32_t minimum_api_version = 0;
struct {
uint64_t last_encoded_frame_index = 0;
bool rfi_needs_confirmation = false;
std::pair<uint64_t, uint64_t> last_rfi_range;
stat_trackers::min_max_avg_tracker<float> frame_size_tracker;
} encoder_state;
};
} // namespace nvenc