Skip to content

Commit

Permalink
fix: memory leak when pipeline is too slow
Browse files Browse the repository at this point in the history
  • Loading branch information
ABeltramo committed Jan 10, 2025
1 parent 89af343 commit 68bab4d
Show file tree
Hide file tree
Showing 5 changed files with 35 additions and 16 deletions.
21 changes: 20 additions & 1 deletion src/moonlight-server/state/configTOML.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ namespace state {
*/
constexpr char const *default_toml =
#include "default/config.include.toml"

;

using namespace std::literals;
Expand Down Expand Up @@ -131,7 +132,7 @@ Config load_or_default(const std::string &source,
if (default_gst_video_settings.default_source.find("appsrc") != std::string::npos) {
logs::log(logs::debug, "Found appsrc in default_source, migrating to interpipesrc");
default_gst_video_settings.default_source = "interpipesrc listen-to={session_id}_video is-live=true "
"stream-sync=restart-ts max-bytes=0 max-buffers=3 block=false";
"stream-sync=restart-ts max-buffers=1 block=false";
}

auto default_gst_audio_settings = cfg.gstreamer.audio;
Expand All @@ -140,7 +141,25 @@ Config load_or_default(const std::string &source,
default_gst_audio_settings.default_source = "interpipesrc listen-to={session_id}_audio is-live=true "
"stream-sync=restart-ts max-bytes=0 max-buffers=3 block=false";
}

auto default_gst_encoder_settings = default_gst_video_settings.defaults;
auto update_leaky_queue = [](std::string &pipeline) {
std::string old_str = "queue";
auto replace_pos = pipeline.find(old_str);
pipeline.replace(replace_pos, old_str.size(), "queue leaky=downstream max-size-buffers=1 ");
};
if (default_gst_encoder_settings["nvcodec"].video_params.find("queue !") != std::string::npos) {
logs::log(logs::debug, "Found leaky queue in nvcodec, migrating to queue leaky=downstream");
update_leaky_queue(default_gst_encoder_settings["nvcodec"].video_params);
}
if (default_gst_encoder_settings["vaapi"].video_params.find("queue !") != std::string::npos) {
logs::log(logs::debug, "Found leaky queue in vaapi, migrating to queue leaky=downstream");
update_leaky_queue(default_gst_encoder_settings["vaapi"].video_params);
}
if (default_gst_encoder_settings["qsv"].video_params.find("queue !") != std::string::npos) {
logs::log(logs::debug, "Found leaky queue in qsv, migrating to queue leaky=downstream");
update_leaky_queue(default_gst_encoder_settings["qsv"].video_params);
}

auto default_app_render_node = utils::get_env("WOLF_RENDER_NODE", "/dev/dri/renderD128");
auto default_gst_render_node = utils::get_env("WOLF_ENCODER_NODE", default_app_render_node);
Expand Down
2 changes: 1 addition & 1 deletion src/moonlight-server/state/data-structures.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,7 @@ static const audio::AudioMode &get_audio_mode(int channels, bool high_quality) {
base_index = 1;
} else if (channels == 8) {
base_index = 2;
} else {
} else if (channels != 2) {
logs::log(logs::warning, "Moonlight requested an impossible number of channels: {}", channels);
}

Expand Down
12 changes: 6 additions & 6 deletions src/moonlight-server/state/default/config.include.toml
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@ source = "audiotestsrc wave=ticks is-live=true"

[gstreamer.video]

default_source = "interpipesrc listen-to={session_id}_video is-live=true stream-sync=restart-ts max-bytes=0 max-buffers=3 block=false"
default_source = 'interpipesrc listen-to={session_id}_video is-live=true stream-sync=restart-ts max-buffers=1 block=false'
default_sink = """
rtpmoonlightpay_video name=moonlight_pay \
payload_size={payload_size} fec_percentage={fec_percentage} min_required_fec_packets={min_required_fec_packets} !
Expand All @@ -184,7 +184,7 @@ udpsink bind-port={host_port} host={client_ip} port={client_port} sync=true\
# To avoid repetition between H264, HEVC and AV1 encoders
[gstreamer.video.defaults.nvcodec]
video_params = """
queue !
queue leaky=downstream max-size-buffers=1 !
cudaupload !
cudaconvertscale !
video/x-raw(memory:CUDAMemory), width={width}, height={height}, \
Expand All @@ -193,14 +193,14 @@ chroma-site={color_range}, format=NV12, colorimetry={color_space}, pixel-aspect-

[gstreamer.video.defaults.qsv]
video_params = """
queue !
queue leaky=downstream max-size-buffers=1 !
videoconvertscale !
video/x-raw, chroma-site={color_range}, width={width}, height={height}, format=NV12, colorimetry={color_space}\
"""

[gstreamer.video.defaults.vaapi]
video_params = """
queue !
queue leaky=downstream max-size-buffers=1 !
videoconvertscale !
video/x-raw, chroma-site={color_range}, width={width}, height={height}, format=NV12, colorimetry={color_space}\
"""
Expand Down Expand Up @@ -342,7 +342,7 @@ video/x-av1, stream-format=obu-stream, alignment=frame, profile=main\
plugin_name = "vaapi"
check_elements = ["vaav1enc", "videoconvertscale"]
encoder_pipeline = """
vaav1enc gop-size=0 ref-frames=1 bitrate={bitrate} rate-control=cbr !
vaav1enc ref-frames=1 bitrate={bitrate} rate-control=cbr target-usage=6 !
av1parse !
video/x-av1, stream-format=obu-stream, alignment=frame, profile=main\
"""
Expand All @@ -351,7 +351,7 @@ video/x-av1, stream-format=obu-stream, alignment=frame, profile=main\
plugin_name = "vaapi"
check_elements = ["vaav1lpenc", "videoconvertscale"] # LP = Low Power
encoder_pipeline = """
vaav1lpenc gop-size=0 ref-frames=1 bitrate={bitrate} rate-control=cbr !
vaav1lpenc ref-frames=1 bitrate={bitrate} rate-control=cbr target-usage=6 !
av1parse !
video/x-av1, stream-format=obu-stream, alignment=frame, profile=main\
"""
Expand Down
8 changes: 4 additions & 4 deletions src/moonlight-server/state/default/config.v4.toml
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ source = "audiotestsrc wave=ticks is-live=true"

[gstreamer.video]

default_source = "interpipesrc listen-to={session_id}_video is-live=true stream-sync=restart-ts max-bytes=0 max-buffers=3 block=false"
default_source = 'interpipesrc listen-to={session_id}_video is-live=true stream-sync=restart-ts max-buffers=1 block=false'
default_sink = """
rtpmoonlightpay_video name=moonlight_pay \
payload_size={payload_size} fec_percentage={fec_percentage} min_required_fec_packets={min_required_fec_packets} !
Expand All @@ -183,7 +183,7 @@ udpsink bind-port={host_port} host={client_ip} port={client_port} sync=true\
# To avoid repetition between H264, HEVC and AV1 encoders
[gstreamer.video.defaults.nvcodec]
video_params = """
queue !
queue leaky=downstream max-size-buffers=1 !
cudaupload !
cudaconvertscale !
video/x-raw(memory:CUDAMemory), width={width}, height={height}, \
Expand All @@ -192,14 +192,14 @@ chroma-site={color_range}, format=NV12, colorimetry={color_space}, pixel-aspect-

[gstreamer.video.defaults.qsv]
video_params = """
queue !
queue leaky=downstream max-size-buffers=1 !
videoconvertscale !
video/x-raw, chroma-site={color_range}, width={width}, height={height}, format=NV12, colorimetry={color_space}\
"""

[gstreamer.video.defaults.vaapi]
video_params = """
queue !
queue leaky=downstream max-size-buffers=1 !
videoconvertscale !
video/x-raw, chroma-site={color_range}, width={width}, height={height}, format=NV12, colorimetry={color_space}\
"""
Expand Down
8 changes: 4 additions & 4 deletions src/moonlight-server/streaming/streaming.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -82,8 +82,8 @@ void start_video_producer(std::size_t session_id,
const std::shared_ptr<events::EventBusType> &event_bus) {
auto appsrc_state = streaming::custom_src::setup_app_src(display_mode, std::move(wl_state));
auto pipeline = fmt::format("appsrc is-live=true name=wolf_wayland_source ! " //
"queue ! " //
"interpipesink name={}_video sync=true async=false max-bytes=0 max-buffers=3", //
"queue leaky=downstream max-size-buffers=1 ! " //
"interpipesink name={}_video max-buffers=1", //
session_id);
logs::log(logs::debug, "[GSTREAMER] Starting video producer: {}", pipeline);
run_pipeline(pipeline, [=](auto pipeline, auto loop) {
Expand Down Expand Up @@ -132,8 +132,8 @@ void start_audio_producer(std::size_t session_id,
auto pipeline = fmt::format(
"pulsesrc device=\"{sink_name}\" server=\"{server_name}\" ! " //
"audio/x-raw, channels={channels}, rate=48000 ! " //
"queue ! " //
"interpipesink name=\"{session_id}_audio\" sync=true async=false max-bytes=0 max-buffers=3",
"queue leaky=downstream max-size-buffers=3 ! " //
"interpipesink name=\"{session_id}_audio\" sync=true async=false max-buffers=3",
fmt::arg("session_id", session_id),
fmt::arg("channels", channel_count),
fmt::arg("sink_name", sink_name),
Expand Down

0 comments on commit 68bab4d

Please sign in to comment.