Add hardware encoding
This commit is contained in:
parent
047f42084c
commit
ac36d5eee6
|
|
@ -60,6 +60,11 @@ sudo apt-get install libgstreamer-plugins-base1.0-dev libgstreamer-plugins-good1
|
|||
# False = rtsp://0.0.0.0:portAndMountpoint (The stream is accessible from the outside)
|
||||
# For example, to access the stream running on the machine with IP = 192.168.20.20,
|
||||
# use rtsp://192.186.20.20:portAndMountpoint
|
||||
encoder: "software" # Which encoder to use, "hardware" automatically selects an available hardware encoder.
|
||||
# Use "nvidia", "intel" or "amd" to force an encoder if available.
|
||||
# Use "software" to force the software encoder.
|
||||
# Always falls back to software if a hardware encoder can't be found.
|
||||
# Defaults to "software".
|
||||
- Save your configuration and navigate to `ros2_ws` colcon root, source and build the package:
|
||||
```bashrc
|
||||
cd ~/ros2_ws/
|
||||
|
|
|
|||
|
|
@ -19,3 +19,4 @@
|
|||
# False = rtsp://0.0.0.0:portAndMountpoint (The stream is accessible from the outside)
|
||||
# For example, to access the stream running on the machine with IP = 192.168.20.20,
|
||||
# use rtsp://192.186.20.20:portAndMountpoint
|
||||
encoder: "software"
|
||||
|
|
|
|||
|
|
@ -28,8 +28,10 @@ private:
|
|||
string pipeline_tail;
|
||||
bool local_only;
|
||||
bool camera;
|
||||
string encoder;
|
||||
GstAppSrc *appsrc;
|
||||
|
||||
std::string get_encoder_pipeline();
|
||||
void video_mainloop_start();
|
||||
void rtsp_server_add_url(const char *url, const char *sPipeline, GstElement **appsrc);
|
||||
void topic_callback(const sensor_msgs::msg::Image::SharedPtr msg);
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ Image2rtsp::Image2rtsp() : Node("image2rtsp"){
|
|||
this->declare_parameter("port", "8554");
|
||||
this->declare_parameter("local_only", true);
|
||||
this->declare_parameter("camera", false);
|
||||
this->declare_parameter("encoder", "software");
|
||||
|
||||
source = this->get_parameter("source").as_string();
|
||||
topic = this->get_parameter("topic").as_string();
|
||||
|
|
@ -30,6 +31,7 @@ Image2rtsp::Image2rtsp() : Node("image2rtsp"){
|
|||
port = this->get_parameter("port").as_string();
|
||||
local_only = this->get_parameter("local_only").as_bool();
|
||||
camera = this->get_parameter("camera").as_bool();
|
||||
encoder = this->get_parameter("encoder").as_string();
|
||||
|
||||
// Start the subscription
|
||||
subscription_ = this->create_subscription<sensor_msgs::msg::Image>(topic, 10, std::bind(&Image2rtsp::topic_callback, this, _1));
|
||||
|
|
@ -39,11 +41,17 @@ Image2rtsp::Image2rtsp() : Node("image2rtsp"){
|
|||
rtsp_server = rtsp_server_create(port, local_only);
|
||||
appsrc = NULL;
|
||||
// Setup the pipeline
|
||||
pipeline_tail = " key-int-max=30 ! video/x-h264, profile=baseline ! rtph264pay name=pay0 pt=96 )";
|
||||
pipeline_tail = " ! video/x-h264,profile=constrained-baseline ! rtph264pay name=pay0 pt=96 "
|
||||
"config-interval=1 aggregate-mode=zero-latency ! "
|
||||
"application/x-rtp,media=video )";
|
||||
auto encoder = get_encoder_pipeline();
|
||||
if (camera == false){
|
||||
pipeline_head = "( appsrc name=imagesrc do-timestamp=true min-latency=0 max-latency=0 max-bytes=1000 is-live=true ! videoconvert ! videoscale ! ";
|
||||
pipeline = pipeline_head + caps_1 + framerate + caps_2 + " ! x264enc tune=zerolatency bitrate=" + bitrate + pipeline_tail;
|
||||
pipeline_head = "( appsrc name=imagesrc do-timestamp=true min-latency=0 "
|
||||
"max-latency=0 max-bytes=2000000 is-live=true ! queue max-size-buffers=1 leaky=downstream ! videoconvert ! videoscale ! ";
|
||||
pipeline = pipeline_head + caps_1 + framerate + caps_2 +
|
||||
" ! " + encoder + " bitrate=" + bitrate + pipeline_tail;
|
||||
rtsp_server_add_url(mountpoint.c_str(), pipeline.c_str(), (GstElement **)&(appsrc));
|
||||
RCLCPP_INFO(this->get_logger(), "pipeline: %s", pipeline.c_str());
|
||||
}
|
||||
else {
|
||||
pipeline = "( " + source + " ! videoconvert ! videoscale ! " + caps_1 + framerate + caps_2 + " ! x264enc tune=zerolatency bitrate=" + bitrate + pipeline_tail;
|
||||
|
|
@ -52,6 +60,38 @@ Image2rtsp::Image2rtsp() : Node("image2rtsp"){
|
|||
RCLCPP_INFO(this->get_logger(), "Stream available at rtsp://%s:%s%s", gst_rtsp_server_get_address(rtsp_server), port.c_str(), mountpoint.c_str());
|
||||
}
|
||||
|
||||
std::string Image2rtsp::get_encoder_pipeline() {
|
||||
GstElementFactory* factory;
|
||||
|
||||
// Check for NVIDIA encoder
|
||||
factory = gst_element_factory_find("nvh264enc");
|
||||
if (factory && (encoder == "hardware" || encoder == "nvidia")) {
|
||||
gst_object_unref(factory);
|
||||
RCLCPP_INFO(this->get_logger(), "Using NVIDIA hardware encoder");
|
||||
return "nvh264enc preset=low-latency-hp rc-mode=cbr-ld-hq zerolatency=true";
|
||||
}
|
||||
|
||||
// Check for VA-API encoder
|
||||
factory = gst_element_factory_find("vaapih264enc");
|
||||
if (factory && (encoder == "hardware" || encoder == "intel")) {
|
||||
gst_object_unref(factory);
|
||||
RCLCPP_INFO(this->get_logger(), "Using VA-API hardware encoder");
|
||||
return "vaapipostproc ! vaapih264enc rate-control=cbr quality-level=7";
|
||||
}
|
||||
|
||||
// Check for AMD encoder
|
||||
factory = gst_element_factory_find("amfh264enc");
|
||||
if (factory && (encoder == "hardware" || encoder == "amd")) {
|
||||
gst_object_unref(factory);
|
||||
RCLCPP_INFO(this->get_logger(), "Using AMD hardware encoder");
|
||||
return "amfh264enc usage=ultra-low-latency";
|
||||
}
|
||||
|
||||
// Fallback to software encoder
|
||||
RCLCPP_INFO(this->get_logger(), "Using software encoder");
|
||||
return "x264enc tune=zerolatency speed-preset=ultrafast";
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]){
|
||||
rclcpp::init(argc, argv);
|
||||
auto node = std::make_shared<Image2rtsp>();
|
||||
|
|
|
|||
Loading…
Reference in New Issue