refactor(streamer): remove gstreamer and legacy rtmp paths

This commit is contained in:
2026-03-11 16:43:29 +08:00
parent ed3f32ff6e
commit 782af9481c
22 changed files with 817 additions and 3339 deletions
+22 -73
View File
@@ -14,10 +14,6 @@
#include <utility>
#include <vector>
#ifndef CVMMAP_STREAMER_HAS_GSTREAMER
#define CVMMAP_STREAMER_HAS_GSTREAMER 0
#endif
namespace cvmmap_streamer {
namespace {
@@ -36,10 +32,16 @@ std::string trim_copy(std::string value) {
}
std::string normalize_cli_error(std::string raw_message) {
if (raw_message.find("The following argument was not expected:") != std::string::npos) {
if (
raw_message.find("The following argument was not expected:") != std::string::npos ||
raw_message.find("The following arguments were not expected:") != std::string::npos) {
const auto pos = raw_message.find(':');
if (pos != std::string::npos && pos + 1 < raw_message.size()) {
return "unknown argument: " + trim_copy(raw_message.substr(pos + 1));
const auto argument = trim_copy(raw_message.substr(pos + 1));
if (argument.rfind("--rtmp-mode", 0) == 0) {
return "unknown argument: --rtmp-mode (removed; RTMP always uses enhanced mode)";
}
return "unknown argument: " + argument;
}
return "unknown argument";
}
@@ -113,16 +115,6 @@ std::expected<RunMode, std::string> parse_run_mode(std::string_view raw) {
return std::unexpected("invalid run mode: '" + std::string(raw) + "' (expected: pipeline|ingest)");
}
std::expected<RtmpMode, std::string> parse_rtmp_mode(std::string_view raw) {
if (raw == "enhanced") {
return RtmpMode::Enhanced;
}
if (raw == "domestic") {
return RtmpMode::Domestic;
}
return std::unexpected("invalid rtmp mode: '" + std::string(raw) + "' (expected: enhanced|domestic)");
}
std::expected<RtmpTransportType, std::string> parse_rtmp_transport(std::string_view raw) {
if (raw == "libavformat") {
return RtmpTransportType::Libavformat;
@@ -131,10 +123,10 @@ std::expected<RtmpTransportType, std::string> parse_rtmp_transport(std::string_v
return RtmpTransportType::FfmpegProcess;
}
if (raw == "legacy_custom" || raw == "legacy-custom") {
return RtmpTransportType::LegacyCustom;
return std::unexpected(
"invalid rtmp transport: '" + std::string(raw) + "' was removed; use libavformat or ffmpeg_process");
}
return std::unexpected(
"invalid rtmp transport: '" + std::string(raw) + "' (expected: libavformat|ffmpeg_process|legacy_custom)");
return std::unexpected("invalid rtmp transport: '" + std::string(raw) + "' (expected: libavformat|ffmpeg_process)");
}
std::expected<EncoderBackendType, std::string> parse_encoder_backend(std::string_view raw) {
@@ -145,9 +137,9 @@ std::expected<EncoderBackendType, std::string> parse_encoder_backend(std::string
return EncoderBackendType::FFmpeg;
}
if (raw == "gstreamer_legacy" || raw == "gstreamer-legacy") {
return EncoderBackendType::GStreamerLegacy;
return std::unexpected("invalid encoder backend: '" + std::string(raw) + "' was removed; use ffmpeg");
}
return std::unexpected("invalid encoder backend: '" + std::string(raw) + "' (expected: auto|ffmpeg|gstreamer_legacy)");
return std::unexpected("invalid encoder backend: '" + std::string(raw) + "' (expected: auto|ffmpeg)");
}
std::expected<EncoderDeviceType, std::string> parse_encoder_device(std::string_view raw) {
@@ -352,13 +344,9 @@ std::expected<void, std::string> apply_toml_file(RuntimeConfig &config, const st
if (auto value = toml_value<std::string>(table, "outputs.rtmp.ffmpeg_path")) {
config.outputs.rtmp.ffmpeg_path = *value;
}
if (auto value = toml_value<std::string>(table, "outputs.rtmp.mode")) {
auto parsed = parse_rtmp_mode(*value);
if (!parsed) {
return std::unexpected(parsed.error());
if (auto value = toml_value<std::string>(table, "outputs.rtmp.mode")) {
return std::unexpected("invalid RTMP config: outputs.rtmp.mode was removed; RTMP always uses enhanced mode");
}
config.outputs.rtmp.mode = *parsed;
}
if (auto value = toml_value<bool>(table, "record.mcap.enabled")) {
config.record.mcap.enabled = *value;
}
@@ -502,8 +490,6 @@ std::string_view to_string(RtmpMode mode) {
switch (mode) {
case RtmpMode::Enhanced:
return "enhanced";
case RtmpMode::Domestic:
return "domestic";
}
return "unknown";
}
@@ -514,8 +500,6 @@ std::string_view to_string(RtmpTransportType transport) {
return "libavformat";
case RtmpTransportType::FfmpegProcess:
return "ffmpeg_process";
case RtmpTransportType::LegacyCustom:
return "legacy_custom";
}
return "unknown";
}
@@ -526,8 +510,6 @@ std::string_view to_string(EncoderBackendType backend) {
return "auto";
case EncoderBackendType::FFmpeg:
return "ffmpeg";
case EncoderBackendType::GStreamerLegacy:
return "gstreamer_legacy";
}
return "unknown";
}
@@ -565,7 +547,6 @@ std::expected<RuntimeConfig, std::string> parse_runtime_config(int argc, char **
std::string codec_raw{};
std::string encoder_backend_raw{};
std::string encoder_device_raw{};
std::string rtmp_mode_raw{};
std::string rtmp_transport_raw{};
std::string rtmp_ffmpeg_path_raw{};
std::vector<std::string> rtmp_urls_raw{};
@@ -605,7 +586,6 @@ std::expected<RuntimeConfig, std::string> parse_runtime_config(int argc, char **
app.add_option("--rtmp-url", rtmp_urls_raw);
app.add_option("--rtmp-transport", rtmp_transport_raw);
app.add_option("--rtmp-ffmpeg", rtmp_ffmpeg_path_raw);
app.add_option("--rtmp-mode", rtmp_mode_raw);
app.add_flag("--rtp", rtp_enabled);
app.add_option("--rtp-endpoint", rtp_endpoint_raw);
app.add_option("--rtp-payload-type", rtp_payload_type_raw);
@@ -692,14 +672,6 @@ std::expected<RuntimeConfig, std::string> parse_runtime_config(int argc, char **
if (!rtmp_ffmpeg_path_raw.empty()) {
config.outputs.rtmp.ffmpeg_path = rtmp_ffmpeg_path_raw;
}
if (!rtmp_mode_raw.empty()) {
auto parsed = parse_rtmp_mode(rtmp_mode_raw);
if (!parsed) {
return std::unexpected(parsed.error());
}
config.outputs.rtmp.mode = *parsed;
}
config.outputs.rtp.enabled = config.outputs.rtp.enabled || rtp_enabled;
if (!rtp_endpoint_raw.empty()) {
config.outputs.rtp.enabled = true;
@@ -831,27 +803,14 @@ std::expected<void, std::string> validate_runtime_config(const RuntimeConfig &co
return std::unexpected("invalid RTMP config: URL must not be empty");
}
}
if (config.encoder.backend == EncoderBackendType::GStreamerLegacy && config.record.mcap.enabled) {
return std::unexpected("invalid backend/output matrix: MCAP recording requires the ffmpeg encoded access-unit path");
}
if (config.outputs.rtmp.enabled) {
if (config.outputs.rtmp.transport == RtmpTransportType::LegacyCustom) {
if (config.outputs.rtmp.mode == RtmpMode::Domestic && config.encoder.codec != CodecType::H265) {
return std::unexpected("invalid mode matrix: domestic RTMP mode requires codec h265");
}
if (config.encoder.backend != EncoderBackendType::GStreamerLegacy) {
return std::unexpected("invalid backend/output matrix: legacy_custom RTMP requires encoder.backend=gstreamer_legacy");
}
} else {
if (config.outputs.rtmp.mode != RtmpMode::Enhanced) {
return std::unexpected("invalid RTMP config: non-legacy RTMP transports only support rtmp.mode=enhanced");
}
if (config.encoder.backend != EncoderBackendType::FFmpeg) {
return std::unexpected("invalid backend/output matrix: RTMP transports libavformat and ffmpeg_process require encoder.backend=ffmpeg");
}
if (config.outputs.rtmp.transport == RtmpTransportType::FfmpegProcess && config.outputs.rtmp.ffmpeg_path.empty()) {
return std::unexpected("invalid RTMP config: ffmpeg_process transport requires a non-empty ffmpeg path");
}
if (config.encoder.backend == EncoderBackendType::Auto) {
// auto resolves to FFmpeg; nothing else is supported.
} else if (config.encoder.backend != EncoderBackendType::FFmpeg) {
return std::unexpected("invalid backend/output matrix: RTMP requires encoder.backend=ffmpeg or auto");
}
if (config.outputs.rtmp.transport == RtmpTransportType::FfmpegProcess && config.outputs.rtmp.ffmpeg_path.empty()) {
return std::unexpected("invalid RTMP config: ffmpeg_process transport requires a non-empty ffmpeg path");
}
}
@@ -891,15 +850,6 @@ std::expected<void, std::string> validate_runtime_config(const RuntimeConfig &co
return std::unexpected("invalid ingest config: ingest_idle_timeout_ms must be >= 1");
}
#if !CVMMAP_STREAMER_HAS_GSTREAMER
if (config.encoder.backend == EncoderBackendType::GStreamerLegacy) {
return std::unexpected("invalid backend config: gstreamer_legacy backend requested but GStreamer support is not compiled");
}
if (config.outputs.rtmp.enabled && config.outputs.rtmp.transport == RtmpTransportType::LegacyCustom) {
return std::unexpected("invalid output config: legacy_custom RTMP requires GStreamer support, which is not compiled");
}
#endif
return {};
}
@@ -914,7 +864,6 @@ std::string summarize_runtime_config(const RuntimeConfig &config) {
ss << ", encoder.b_frames=" << config.encoder.b_frames;
ss << ", rtmp.enabled=" << (config.outputs.rtmp.enabled ? "true" : "false");
ss << ", rtmp.transport=" << to_string(config.outputs.rtmp.transport);
ss << ", rtmp.mode=" << to_string(config.outputs.rtmp.mode);
ss << ", rtmp.urls=" << config.outputs.rtmp.urls.size();
ss << ", rtp.enabled=" << (config.outputs.rtp.enabled ? "true" : "false");
ss << ", rtp.endpoint=" << (config.outputs.rtp.endpoint ? *config.outputs.rtp.endpoint : "<unset>");