Skip to content

Rtp Streaming#79

Merged
ConnorNeed merged 3 commits intomainfrom
rtp_start
Mar 20, 2026
Merged

Rtp Streaming#79
ConnorNeed merged 3 commits intomainfrom
rtp_start

Conversation

@ConnorNeed
Copy link
Member

This pull request introduces RTP (Real-time Transport Protocol) streaming support to the video streaming package, alongside improvements to the pipeline management and launch configuration. The main changes add new RTP nodes for both server and client functionality, update launch files to use these nodes, and enhance dynamic parameter handling and pipeline control.

RTP Streaming Support

  • Added new RtpNode and RtpClientNode classes for RTP server and client functionality, including pipeline creation, parameter handling, and dynamic bitrate/resolution adjustment (src/Cameras/video_streaming/include/video_streaming/rtp_node.hpp, src/Cameras/video_streaming/include/video_streaming/rtp_client_node.hpp, src/Cameras/video_streaming/src/rtp_node.cpp, src/Cameras/video_streaming/src/rtp_client_node.cpp). [1] [2] [3] [4]
  • Registered the new RTP nodes in the build system and component registration macros (src/Cameras/video_streaming/CMakeLists.txt). [1] [2]

Launch Configuration

  • Updated launch files to use RTP nodes instead of SRT nodes, including renaming and parameter adjustments for RTP-specific settings (src/Cameras/video_streaming/launch/rtp_client.launch.py, src/Cameras/video_streaming/launch/video_streaming.launch.py). [1] [2] [3]

Dynamic Pipeline and Parameter Handling

  • Implemented dynamic parameter updates for RTP nodes, allowing changes to streaming settings (such as bitrate, resolution, FEC, and latency) at runtime, with pipeline restart or element update as needed (src/Cameras/video_streaming/src/rtp_node.cpp, src/Cameras/video_streaming/src/rtp_client_node.cpp). [1] [2]

Input Node Improvements

  • Enhanced the InputNode to track the current video request and ensure proper callback invocation when the pipeline is created or successfully started (src/Cameras/video_streaming/include/video_streaming/input_node.hpp, src/Cameras/video_streaming/src/input_node.cpp). [1] [2] [3]

@ConnorNeed ConnorNeed requested a review from jujuz455 March 18, 2026 15:16
Copy link

@noodlekid noodlekid left a comment

Choose a reason for hiding this comment

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

First glance review.

Comment on lines +81 to +84
if (needs_restart && result.successful) {
stop_pipeline();
start_pipeline();
}

Choose a reason for hiding this comment

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

If we do need a restart, but "result.successful" is false, we ignore the restart?

Choose a reason for hiding this comment

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

Also, result.successful is never modified and is set to true at the start of this function call? Do we even need to check it?

Comment on lines +191 to +199
int bits_per_frame = video_bitrate / target_framerate_;
if (bits_per_frame < 50000) {
set_resolution(640, 360);
} else if (bits_per_frame < 100000) {
set_resolution(854, 480);
} else if (bits_per_frame < 200000) {
set_resolution(1280, 720);
} else {
set_resolution(1920, 1080);

Choose a reason for hiding this comment

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

Consider parameterizing this and allowing the "resolution-bitrate ramp" to be defined at runtime.

Copy link
Member Author

Choose a reason for hiding this comment

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

Yeah I am probably changing this whole setup. bits_per_frame is a terrible measurement for h265. Lower framerates compress way worse per frame than higher framerates. Also I don't like hard lines that it might bounce back and forth over. I would say overall this simple logic is fine for the next few weeks of testing.

GError *err = nullptr;
GstElement *p = gst_parse_launch(desc.c_str(), &err);

if (err || !p) {

Choose a reason for hiding this comment

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

It might be standard to do nullptr checks like this in modern C++, IDK. But I think explicitly presenting the comparison is generally better.

i.e.
p == nullptr

Copy link
Member Author

Choose a reason for hiding this comment

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

Modern C++ you typically explicitly compare to nullptr. This is very much a c idiom. This whole node follows the c style since gstreamer is a c library.


void RtpNode::on_iframe_trigger(const std_msgs::msg::Empty::SharedPtr msg) {
(void)msg;
if (h265_encoder_) {

Choose a reason for hiding this comment

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

If casting to void to avoid compiler warning, C++17 lets you do the following,

void RtpNode::on_iframe_trigger([[maybe_unused]] const std_msgs::msg::Empty::SharedPtr msg)

Or just omitting the parameter name and inline commenting it, (pretty much any C++ version)
void RtpNode::on_iframe_trigger(const std_msgs::msg::Empty::SharedPtr /*msg*/)

Doing the void cast is an old way to do it i guess.

Copy link
Member Author

Choose a reason for hiding this comment

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

void cast is again a c idiom which is just kind of habit for me at this point. I spend most of my day in c and rust. I'll switch to [[maybe_unused]] since we are using c++17.

@ConnorNeed ConnorNeed merged commit ef054a6 into main Mar 20, 2026
1 of 4 checks passed
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.

3 participants