I am trying to use the ROS GSCam package in a Docker container to read from a camera stream and publish to a ROS topic. Using GStreamer via gst-launch
works fine in the container. For example, running
gst-launch-1.0 -v tcpclientsrc host=10.0.0.20 port=7001 ! decodebin ! filesink location= xyz.flv
in the container successfully saves the camera stream to the xyz.flv
file. When I try to use GSCam using the following commands
roscd gscam
mkdir bin
cd bin
export GSCAM_CONFIG="tcpclientsrc host=10.0.0.20 port=7001 ! decodebin ! ffmpegcolorspace"
rosrun gscam gscam
the camera stream is published to a ROS topics if these commands are run outside the container, but when run inside the container they result in the following output:
[ INFO] [1625351876.482947987]: Using GStreamer config from env: "tcpclientsrc host=10.0.0.20 port=7001 ! decodebin ! ffmpegcolorspace"
[ INFO] [1625351876.486672898]: using default calibration URL
[ INFO] [1625351876.486702714]: camera calibration URL: file:///root/.ros/camera_info/camera.yaml
[ INFO] [1625351876.486735225]: Unable to open camera calibration file [/root/.ros/camera_info/camera.yaml]
[ WARN] [1625351876.486750795]: Camera calibration file /root/.ros/camera_info/camera.yaml not found.
[ INFO] [1625351876.486759250]: Loaded camera calibration from
[ INFO] [1625351876.502708790]: Time offset: 1625351189.738
[FATAL] [1625351876.519311654]: Failed to PAUSE stream, check your GStreamer configuration.
[FATAL] [1625351876.519330710]: Failed to initialize GSCam stream!
What can I do to fix this?
EDIT. The problem seems to come from this piece of the code:
gst_element_set_state(pipeline_, GST_STATE_PAUSED);
if (gst_element_get_state(pipeline_, NULL, NULL, -1) == GST_STATE_CHANGE_FAILURE) {
ROS_FATAL("Failed to PAUSE stream, check your gstreamer configuration.");
return false;
}
Using code from here, I can see that the return value of gst_element_set_state()
is SUCCESS
, as is the return value of gst_element_get_state()
for each element of the pipeline (tcpclientsrc0, decodebin0, and appsink0). Strangely however, the output of gst_element_get_state(pipeline_, NULL, NULL, -1)
is FAILURE
, which doesn't seem to make sense. What am I missing? Can a pipeline state change fail despite all its elements changing state successfully? or does the pipeline have some other (perhaps hidden) element that fails to change state?
From the answer given here I realized that my problem stemmed from the fact that the common ROS GSCam package (downloaded via ppa) uses GStreamer0.10, but because I was building the package from source inside the Docker image it used GStreamer1.0. Changing the build dependencies to
<build_depend>libgstreamer0.10-dev</build_depend>
<build_depend>libgstreamer-plugins-base0.10-dev</build_depend>
in the package.xml
file solved the problem.