https://github.com/clydemcqueen/gscam2
ROS2 camera driver for GStreamer-based video streams, supports intra-process communication
https://github.com/clydemcqueen/gscam2
gstreamer ipc ros2
Last synced: 6 months ago
JSON representation
ROS2 camera driver for GStreamer-based video streams, supports intra-process communication
- Host: GitHub
- URL: https://github.com/clydemcqueen/gscam2
- Owner: clydemcqueen
- Created: 2019-12-13T00:08:45.000Z (over 6 years ago)
- Default Branch: main
- Last Pushed: 2025-11-27T21:16:13.000Z (8 months ago)
- Last Synced: 2025-11-30T12:06:39.649Z (8 months ago)
- Topics: gstreamer, ipc, ros2
- Language: C++
- Homepage:
- Size: 57.6 KB
- Stars: 110
- Watchers: 2
- Forks: 28
- Open Issues: 7
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# gscam2 
ROS2 port of [gscam](https://github.com/ros-drivers/gscam).
Supports [ROS2 intra-process comms](https://docs.ros.org/en/humble/Tutorials/Demos/Intra-Process-Communication.html).
> Update 15-Jun-22: [gscam](https://index.ros.org/p/gscam/github-ros-drivers-gscam/) has been released for ROS2. It does not support IPC.
> Update 16-Mar-21: the package name has been updated to match the repository name (gscam2)
## Install and build
Tested on ROS2 Humble, Jazzy and Kilted.
See the [Dockerfile](Dockerfile) for install and build instructions.
## Usage
Make sure your GStreamer pipeline runs successfully in gst-launch-1.0.
For example, here's a pipeline that works for the [Blue Robotics HD USB Camera](https://bluerobotics.com/store/sensors-sonars-cameras/cameras/cam-usb-low-light-r1/):
~~~
gst-launch-1.0 -v v4l2src device=/dev/video1 do-timestamp=true ! queue ! video/x-h264,width=1920,height=1080,framerate=30/1 ! h264parse ! queue ! avdec_h264 ! autovideosink
~~~
Here's the same pipeline in gscam2:
~~~
export GSCAM_CONFIG="v4l2src device=/dev/video1 do-timestamp=true ! queue ! video/x-h264,width=1920,height=1080,framerate=30/1 ! h264parse ! avdec_h264 ! videoconvert"
ros2 run gscam2 gscam_main
~~~
Here's an example with parameters:
~~~
ros2 run gscam2 gscam_main --ros-args --remap /image_raw:=/my_camera/image_raw --params-file gscam_params.yaml -p camera_info_url:=file://$PWD/my_camera_info.ini
~~~
... where gscam_params.yaml is:
~~~
gscam_publisher:
ros__parameters:
gscam_config: 'v4l2src device=/dev/video1 do-timestamp=true ! queue ! video/x-h264,width=1920,height=1080,framerate=30/1 ! h264parse ! avdec_h264 ! videoconvert'
preroll: True
use_gst_timestamps: True
camera_name: 'my_camera'
frame_id: 'my_camera_frame'
~~~
Here's an example that uses a GStreamer tee to split the stream, with one stream producing ROS images
and the second stream writing to MP4 files:
~~~
export GSCAM_CONFIG="v4l2src device=/dev/video1 do-timestamp=true ! queue ! video/x-h264,width=1920,height=1080,framerate=30/1 ! h264parse ! tee name=fork ! queue ! splitmuxsink location=video%02d.mov max-size-bytes=10000000 fork. ! avdec_h264 ! videoconvert"
ros2 run gscam2 gscam_main
~~~
There's a [bug](https://github.com/clydemcqueen/gscam2/issues/4) where the last MP4 file is not closed correctly.
### Intra-process comms
IPC test -- CLI composition:
~~~
# Create the container in the first shell; output will appear here as nodes are loaded:
export GSCAM_CONFIG="videotestsrc pattern=snow ! video/x-raw,width=1280,height=720 ! videoconvert"
ros2 run rclcpp_components component_container
# Add the nodes to the container in the second shell:
ros2 component load /ComponentManager gscam2 gscam2::ImageSubscriberNode -e use_intra_process_comms:=true
ros2 component load /ComponentManager gscam2 gscam2::GSCamNode -e use_intra_process_comms:=true
~~~
Launch file composition:
~~~
ros2 launch gscam2 composition_launch.py
~~~
Manual composition -- handy for debugging:
~~~
export GSCAM_CONFIG="videotestsrc pattern=snow ! video/x-raw,width=1280,height=720 ! videoconvert"
ros2 run gscam2 ipc_test_main
~~~
### Finding GStreamer plugins
GStreamer scans various paths for plugins and builds a plugin registry.
[The search process is described here](https://gstreamer.freedesktop.org/documentation/gstreamer/gstregistry.html?gi-language=c).
gscam uses a parameter `gst_plugin_path` instead than the commandline option `--gst-plugin-path`.
The paths in `gst_plugin_path` are searched last, not first.
If you have custom plugins you may need to override the plugin path. Here's an example showing how this works:
~~~
# Disable default locations
export GST_PLUGIN_PATH=""
export GST_PLUGIN_SYSTEM_PATH=""
# Provide the pipeline configuration
export GSCAM_CONFIG=videotestsrc pattern=snow ! video/x-raw,width=1280,height=720 ! videoconvert
# Run gscam_main, providing a custom plugin path
ros2 run gscam2 gscam_main --ros-args -p gst_plugin_path:="/home/me/myplugins"
~~~
## Parameters
| Parameter | Type | Default | Notes |
|---|---|---|---|
| `gst_plugin_path` | string | | Similar to `--gst-plugin-path`, searchs path for plugins |
| `gscam_config` | string | | GStreamer pipeline configuration |
| `sync_sink` | bool | True | Enable GstBaseSink synchronization |
| `preroll` | bool | False | Transition to GST_STATE_PLAYING twice |
| `use_gst_timestamps` | bool | False | Use gst time instead of ROS time |
| `image_encoding` | string | `sensor_msgs::image_encodings::RGB8` | ROS image encoding |
| `camera_info_url` | string | | URL to camera info file, e.g., `file:///path/to/file` |
| `camera_name` | string | | Replaces `${NAME}` in the URL |
| `frame_id` | string | camera_frame | Camera frame ID |
| `skip` | int | 0 | Skip n frames for each frame sent; useful for reducing frame rates |
## Topics
- `camera_info`
- `image_raw`
- `image_raw/compressed` - only if image is encoded as a jpeg stream
## Camera info file formats
Uses the [ROS standard camera calibration formats](http://wiki.ros.org/camera_calibration_parsers?distro=melodic).
Files must end in `.ini` or `.yaml`.