Skip to content

NVENC AV1 support#1191

Open
chenosaurus wants to merge 7 commits into
mainfrom
dc/nvenc_av1
Open

NVENC AV1 support#1191
chenosaurus wants to merge 7 commits into
mainfrom
dc/nvenc_av1

Conversation

@chenosaurus

Copy link
Copy Markdown
Contributor
  • enable Nvidia GPU NVENC AV1 encoding

@github-actions

Copy link
Copy Markdown
Contributor

Changeset

The following package versions will be affected by this PR:

Package Bump
libwebrtc patch
livekit patch
livekit-ffi patch
webrtc-sys patch

{"packetization-mode", "1"},
};

supported_formats_.push_back(SdpVideoFormat("H264", highParameters));

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why these code is commented out ?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I removed it, we only support h264 baseline

NvidiaVideoEncoderFactory::~NvidiaVideoEncoderFactory() {}

bool NvidiaVideoEncoderFactory::IsSupported() {
const NvencProbeResult probe = ProbeNvencSupport();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

how about using function local to avoid calling ProbeNvencSupport() more than once ?
And log it regardless if it is available or not.

Function-local static (recommended)
bool NvidiaVideoEncoderFactory::IsSupported() {
static const NvencProbeResult probe = [] {
NvencProbeResult result = ProbeNvencSupport();
RTC_LOG(LS_INFO)
<< "NVIDIA NVENC hardware encoder "
<< (result.encoder_supported ? "is available." : "is not available.");

return result;

}();

return probe.encoder_supported;
}


bool supported = false;
NV_ENCODE_API_FUNCTION_LIST fnList = {NV_ENCODE_API_FUNCTION_LIST_VER};
CUcontext cuCtx = nullptr;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

preferably, in C++, the variables should be declared just right before they are used.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

they are outside of the do {} block so they can be cleaned up after

uint32_t written_format_count = 0;
nvStatus = fnList.nvEncGetInputFormats(
hEncoder, encodeGuid, formats.data(), format_count, &written_format_count);
if (nvStatus != NV_ENC_SUCCESS) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit, probably you want to add || written_format_count == 0 in this check ?

uint32_t written_guid_count = 0;
nvStatus = fnList.nvEncGetEncodeGUIDs(hEncoder, guids.data(), guid_count,
&written_guid_count);
if (nvStatus != NV_ENC_SUCCESS) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what should happen if written_guid_count is 0 here ?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

also add check for || written_guid_count == 0 to short circuit and return

EncoderInfo GetEncoderInfo() const override;

private:
int32_t ProcessEncodedFrame(std::vector<uint8_t>& packet,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit, is packet mutable ? if not, use const std::vector<uint8_t>& packet,

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

made it const

NV_ENC_TUNING_INFO_ULTRA_LOW_LATENCY);

nv_initialize_params_.frameRateNum =
static_cast<uint32_t>(configuration_.max_frame_rate);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is max_frame_rate guaranteed bigger than 1 ? otherwise it will be divided by 0

NV_ENC_TUNING_INFO_ULTRA_LOW_LATENCY);

nv_initialize_params_.frameRateNum =
static_cast<uint32_t>(configuration_.max_frame_rate);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe it is safer to do
nv_initialize_params_.frameRateNum =
std::max<uint32_t>(1, static_cast<uint32_t>(std::round(configuration_.max_frame_rate)));

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it's possible, this was carried over from the other encoder implementations. I've fixed it across av1, h264, & h265.

has_reported_init_ = true;
}

void NvidiaAV1EncoderImpl::ReportError() {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should ReportError() take the error as param and report the right errors?

return info;
}

void NvidiaAV1EncoderImpl::SetRates(

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks like SetRate() only set the local codec_ and configuration_ cache values.

Should it trigger encoder_->Reconfigure(... if encoder_is already running ? or that is not an supported use case

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is an existing problem in all of the nvenc encoder implementations, I will address in a different PR to fully wire up SetRate().

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants