fix(encode): use modern nvenc low-latency preset

This commit is contained in:
2026-03-11 00:37:46 +08:00
parent e16ceec647
commit f59abb2a32
3 changed files with 28 additions and 3 deletions
+3 -1
View File
@@ -7,6 +7,7 @@ SRS_ROOT="${SRS_ROOT:-$HOME/Code/srs}"
SRS_BIN="${SRS_BIN:-$SRS_ROOT/trunk/objs/srs}"
SRS_CONF="${SRS_CONF:-$SRS_ROOT/trunk/conf/srs.conf}"
FFPROBE_BIN="${FFPROBE_BIN:-ffprobe}"
ENCODER_DEVICE="${ENCODER_DEVICE:-software}"
wait_for_port() {
local host="$1"
@@ -48,7 +49,7 @@ wait_for_stream() {
run_case() {
local transport="$1"
local codec="$2"
local stream_name="cvmmap_${transport}_${codec}"
local stream_name="cvmmap_${transport}_${codec}_${ENCODER_DEVICE}"
local expected_codec="$codec"
if [[ "$codec" == "h265" ]]; then
expected_codec="hevc"
@@ -57,6 +58,7 @@ run_case() {
"${BUILD_DIR}/rtmp_output_tester" \
--transport "$transport" \
--codec "$codec" \
--encoder-device "$ENCODER_DEVICE" \
--rtmp-url "rtmp://127.0.0.1/live/${stream_name}" \
--frames 36 \
--frame-interval-ms 33 \
+1 -1
View File
@@ -345,7 +345,7 @@ private:
[[nodiscard]]
Status configure_codec(std::string_view encoder_name, const RuntimeConfig &config) {
av_opt_set(context_->priv_data, "preset", encoder_name.find("nvenc") != std::string_view::npos ? "llhq" : "veryfast", 0);
av_opt_set(context_->priv_data, "preset", encoder_name.find("nvenc") != std::string_view::npos ? "p1" : "veryfast", 0);
if (encoder_name.find("nvenc") != std::string_view::npos) {
av_opt_set(context_->priv_data, "tune", "ull", 0);
av_opt_set(context_->priv_data, "zerolatency", "1", 0);
+24 -1
View File
@@ -40,6 +40,7 @@ struct Config {
std::string rtmp_url{"rtmp://127.0.0.1/live/cvmmap_streamer_test"};
std::string transport{"libavformat"};
std::string codec{"h264"};
std::string encoder_device{"software"};
std::string ffmpeg_path{"ffmpeg"};
std::uint32_t frames{48};
std::uint32_t width{320};
@@ -57,6 +58,8 @@ std::expected<Config, int> parse_args(int argc, char **argv) {
->check(CLI::IsMember({"libavformat", "ffmpeg_process", "legacy_custom"}));
app.add_option("--codec", config.codec, "Video codec (h264|h265)")
->check(CLI::IsMember({"h264", "h265"}));
app.add_option("--encoder-device", config.encoder_device, "Encoder device (auto|nvidia|software)")
->check(CLI::IsMember({"auto", "nvidia", "software"}));
app.add_option("--ffmpeg-path", config.ffmpeg_path, "ffmpeg binary path for ffmpeg_process transport");
app.add_option("--frames", config.frames, "Number of frames to publish")->check(CLI::PositiveNumber);
app.add_option("--width", config.width, "Frame width")->check(CLI::PositiveNumber);
@@ -98,6 +101,20 @@ std::expected<cvmmap_streamer::RtmpTransportType, std::string> parse_transport(s
return std::unexpected("unsupported transport");
}
[[nodiscard]]
std::expected<cvmmap_streamer::EncoderDeviceType, std::string> parse_encoder_device(std::string_view raw) {
if (raw == "auto") {
return cvmmap_streamer::EncoderDeviceType::Auto;
}
if (raw == "nvidia") {
return cvmmap_streamer::EncoderDeviceType::Nvidia;
}
if (raw == "software") {
return cvmmap_streamer::EncoderDeviceType::Software;
}
return std::unexpected("unsupported encoder device");
}
void fill_pattern(std::vector<std::uint8_t> &buffer, std::uint32_t width, std::uint32_t height, std::uint32_t frame_index) {
for (std::uint32_t y = 0; y < height; ++y) {
for (std::uint32_t x = 0; x < width; ++x) {
@@ -129,9 +146,15 @@ int main(int argc, char **argv) {
return exit_code(TesterExitCode::InvalidArgument);
}
auto encoder_device = parse_encoder_device(args->encoder_device);
if (!encoder_device) {
spdlog::error("{}", encoder_device.error());
return exit_code(TesterExitCode::InvalidArgument);
}
cvmmap_streamer::RuntimeConfig config = cvmmap_streamer::RuntimeConfig::defaults();
config.encoder.backend = cvmmap_streamer::EncoderBackendType::FFmpeg;
config.encoder.device = cvmmap_streamer::EncoderDeviceType::Software;
config.encoder.device = *encoder_device;
config.encoder.codec = *codec;
config.encoder.gop = 15;
config.encoder.b_frames = 0;