Skip to content

Commit

Permalink
Compute the bitrate on the host side for supported clients
Browse files Browse the repository at this point in the history
  • Loading branch information
cgutman authored and KuleRucket committed Jun 6, 2024
1 parent df1f852 commit 0cf8541
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 0 deletions.
2 changes: 2 additions & 0 deletions src/audio.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ namespace audio {

constexpr auto SAMPLE_RATE = 48000;

// NOTE: If you adjust the bitrates listed here, make sure to update the
// corresponding bitrate adjustment logic in rtsp_stream::cmd_announce()
opus_stream_config_t stream_configs[MAX_STREAM_CONFIG] {
{
SAMPLE_RATE,
Expand Down
30 changes: 30 additions & 0 deletions src/rtsp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -704,9 +704,11 @@ namespace rtsp_stream {
args.try_emplace("x-ml-general.featureFlags"sv, "0"sv);
args.try_emplace("x-nv-vqos[0].qosTrafficType"sv, "5"sv);
args.try_emplace("x-nv-aqos.qosTrafficType"sv, "4"sv);
args.try_emplace("x-ml-video.configuredBitrateKbps"sv, "0"sv);

stream::config_t config;

std::int64_t configuredBitrateKbps;
config.audio.flags[audio::config_t::HOST_AUDIO] = launch_session->host_audio;
try {
config.audio.channels = util::from_view(args.at("x-nv-audio.surround.numChannels"sv));
Expand All @@ -733,6 +735,8 @@ namespace rtsp_stream {
config.monitor.encoderCscMode = util::from_view(args.at("x-nv-video[0].encoderCscMode"sv));
config.monitor.videoFormat = util::from_view(args.at("x-nv-vqos[0].bitStreamFormat"sv));
config.monitor.dynamicRange = util::from_view(args.at("x-nv-video[0].dynamicRangeMode"sv));

configuredBitrateKbps = util::from_view(args.at("x-ml-video.configuredBitrateKbps"sv));
}
catch (std::out_of_range &) {
respond(sock, &option, 400, "BAD REQUEST", req->sequenceNumber, {});
Expand All @@ -752,6 +756,32 @@ namespace rtsp_stream {
}
}

// If the client sent a configured bitrate, we will choose the actual bitrate ourselves
// by using FEC percentage and audio quality settings. If the calculated bitrate ends up
// too low, we'll allow it to exceed the limits rather than reducing the encoding bitrate
// down to nearly nothing.
if (configuredBitrateKbps) {
BOOST_LOG(debug) << "Client configured bitrate is "sv << configuredBitrateKbps << " Kbps"sv;

// If the FEC percentage isn't too high, adjust the configured bitrate to ensure video
// traffic doesn't exceed the user's selected bitrate when the FEC shards are included.
if (config::stream.fec_percentage <= 80) {
configuredBitrateKbps /= 100.f / (100 - config::stream.fec_percentage);
}

// Adjust the bitrate to account for audio traffic bandwidth usage (capped at 20% reduction).
// The bitrate per channel is 256 Kbps for high quality mode and 96 Kbps for normal quality.
auto audioBitrateAdjustment = (config.audio.flags[audio::config_t::HIGH_QUALITY] ? 256 : 96) * config.audio.channels;
configuredBitrateKbps -= std::min((std::int64_t) audioBitrateAdjustment, configuredBitrateKbps / 5);

// Reduce it by another 500Kbps to account for A/V packet overhead and control data
// traffic (capped at 10% reduction).
configuredBitrateKbps -= std::min((std::int64_t) 500, configuredBitrateKbps / 10);

BOOST_LOG(debug) << "Final adjusted video encoding bitrate is "sv << configuredBitrateKbps << " Kbps"sv;
config.monitor.bitrate = configuredBitrateKbps;
}

if (config.monitor.videoFormat == 1 && video::active_hevc_mode == 1) {
BOOST_LOG(warning) << "HEVC is disabled, yet the client requested HEVC"sv;

Expand Down

0 comments on commit 0cf8541

Please sign in to comment.