-
Notifications
You must be signed in to change notification settings - Fork 1
Rtp Streaming #79
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Rtp Streaming #79
Changes from all commits
Commits
Show all changes
3 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
28 changes: 28 additions & 0 deletions
28
src/Cameras/video_streaming/include/video_streaming/rtp_client_node.hpp
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,28 @@ | ||
| #pragma once | ||
|
|
||
| #include "base_video_node.hpp" | ||
|
|
||
| #include <gst/gst.h> | ||
| #include <rcl_interfaces/msg/set_parameters_result.hpp> | ||
| #include <rclcpp/node_options.hpp> | ||
| #include <rclcpp/rclcpp.hpp> | ||
|
|
||
| namespace video_streaming { | ||
|
|
||
| class RtpClientNode : public BaseVideoNode { | ||
| public: | ||
| explicit RtpClientNode(const rclcpp::NodeOptions &options); | ||
|
|
||
| protected: | ||
| bool create_pipeline() override; | ||
|
|
||
| private: | ||
| rcl_interfaces::msg::SetParametersResult | ||
| on_parameter_change(const std::vector<rclcpp::Parameter> ¶meters); | ||
| std::string get_pipeline_description(); | ||
| OnSetParametersCallbackHandle::SharedPtr param_callback_handle_; | ||
| uint16_t dest_port_; | ||
| int latency_ms_; | ||
| }; | ||
|
|
||
| } // namespace video_streaming |
49 changes: 49 additions & 0 deletions
49
src/Cameras/video_streaming/include/video_streaming/rtp_node.hpp
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,49 @@ | ||
| #pragma once | ||
|
|
||
| #include "base_video_node.hpp" | ||
|
|
||
| #include <gst/gst.h> | ||
| #include <rcl_interfaces/msg/set_parameters_result.hpp> | ||
| #include <rclcpp/node_options.hpp> | ||
| #include <rclcpp/rclcpp.hpp> | ||
| #include <std_msgs/msg/empty.hpp> | ||
| #include <std_msgs/msg/int32.hpp> | ||
|
|
||
| namespace video_streaming { | ||
|
|
||
| class RtpNode : public BaseVideoNode { | ||
| public: | ||
| explicit RtpNode(const rclcpp::NodeOptions &options); | ||
| ~RtpNode() override; | ||
|
|
||
| protected: | ||
| bool create_pipeline() override; | ||
|
|
||
| private: | ||
| rcl_interfaces::msg::SetParametersResult | ||
| on_parameter_change(const std::vector<rclcpp::Parameter> ¶meters); | ||
|
|
||
| void set_bitrate(int32_t bitrate); | ||
| void set_resolution(int width, int height); | ||
| void on_iframe_trigger(const std_msgs::msg::Empty::SharedPtr msg); | ||
| std::string get_pipeline_description(); | ||
|
|
||
| int target_framerate_; | ||
| int bitrate_; | ||
| int fec_; | ||
| int dest_port_; | ||
| int width_; | ||
| int height_; | ||
|
|
||
| std::string dest_ip_; | ||
|
|
||
| GstElement *h265_encoder_{nullptr}; | ||
|
|
||
| rclcpp::Subscription<std_msgs::msg::Int32>::SharedPtr bitrate_sub_; | ||
| rclcpp::Subscription<std_msgs::msg::Empty>::SharedPtr iframe_sub_; | ||
| rclcpp::Publisher<std_msgs::msg::Empty>::SharedPtr restart_pub_; | ||
|
|
||
| OnSetParametersCallbackHandle::SharedPtr param_callback_handle_; | ||
| }; | ||
|
|
||
| } // namespace video_streaming |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,88 @@ | ||
| #include "rtp_client_node.hpp" | ||
| #include <rclcpp_components/register_node_macro.hpp> | ||
| namespace video_streaming { | ||
| RtpClientNode::RtpClientNode(const rclcpp::NodeOptions &options) | ||
| : BaseVideoNode("rtp_client_node", options) { | ||
| RCLCPP_INFO(this->get_logger(), "Initializing RtpClientNode..."); | ||
|
|
||
| this->declare_parameter<int>("port", 7001); | ||
| this->declare_parameter<int>("latency_ms", 200); | ||
| dest_port_ = this->get_parameter("port").as_int(); | ||
| latency_ms_ = this->get_parameter("latency_ms").as_int(); | ||
| param_callback_handle_ = this->add_on_set_parameters_callback(std::bind( | ||
| &RtpClientNode::on_parameter_change, this, std::placeholders::_1)); | ||
| if (!start_pipeline()) { | ||
| RCLCPP_FATAL(get_logger(), "RtpClientNode: failed to start pipeline."); | ||
| throw std::runtime_error("RtpClientNode: pipeline start failed"); | ||
| } | ||
| RCLCPP_INFO(get_logger(), "RtpClientNode constructed and pipeline started."); | ||
| } | ||
|
|
||
| std::string RtpClientNode::get_pipeline_description() { | ||
| std::stringstream desc; | ||
| desc << "udpsrc port=" << dest_port_ << " caps=" | ||
| << "\"application/x-rtp,media=video,encoding-name=H265,payload=96, " | ||
| << "clock-rate=90000\" ! rtpjitterbuffer mode=4 latency=" << latency_ms_ | ||
| << " drop-on-latency=true ! rtpulpfecdec ! rtph265depay ! h265parse ! " | ||
| << "nvv4l2decoder ! nvvidconv ! nveglglessink sync=false"; | ||
| return desc.str(); | ||
| } | ||
|
|
||
| bool RtpClientNode::create_pipeline() { | ||
| std::string desc = get_pipeline_description(); | ||
| RCLCPP_INFO(this->get_logger(), "Pipeline description: %s", desc.c_str()); | ||
|
|
||
| GError *err = nullptr; | ||
| GstElement *p = gst_parse_launch(desc.c_str(), &err); | ||
|
|
||
| if (err || !p) { | ||
| RCLCPP_ERROR(get_logger(), "gst_parse_launch failed: %s", | ||
| err ? err->message : "unknown"); | ||
| if (err) { | ||
| g_error_free(err); | ||
| } | ||
| return false; | ||
| } | ||
| if (!GST_IS_PIPELINE(p)) { | ||
| RCLCPP_ERROR(get_logger(), "Parsed element is not a pipeline."); | ||
| gst_object_unref(p); | ||
| return false; | ||
| } | ||
| pipeline_ = p; | ||
|
|
||
| RCLCPP_INFO(this->get_logger(), "Pipeline parsed successfully."); | ||
| return true; | ||
| } | ||
| rcl_interfaces::msg::SetParametersResult RtpClientNode::on_parameter_change( | ||
| const std::vector<rclcpp::Parameter> ¶meters) { | ||
| rcl_interfaces::msg::SetParametersResult result; | ||
| result.successful = true; | ||
| result.reason = "success"; | ||
| bool needs_restart = false; | ||
| for (const auto ¶m : parameters) { | ||
| const std::string &name = param.get_name(); | ||
|
|
||
| // Destination Port | ||
| if (name == "port") { | ||
| dest_port_ = param.as_int(); | ||
| RCLCPP_INFO(this->get_logger(), "Param Update: port = %d", dest_port_); | ||
| needs_restart = true; | ||
| continue; | ||
| } | ||
| // Latency | ||
| if (name == "latency_ms") { | ||
| latency_ms_ = param.as_int(); | ||
| RCLCPP_INFO(this->get_logger(), "Param Update: latency_ms = %d", | ||
| latency_ms_); | ||
| needs_restart = true; | ||
| continue; | ||
| } | ||
| } | ||
| if (needs_restart) { | ||
| stop_pipeline(); | ||
| start_pipeline(); | ||
| } | ||
| return result; | ||
| } | ||
| RCLCPP_COMPONENTS_REGISTER_NODE(video_streaming::RtpClientNode); | ||
| } // namespace video_streaming | ||
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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.