Capturing h.264 stream from camera with Gstreamer

s.webbandit picture s.webbandit · Apr 3, 2013 · Viewed 41.3k times · Source

I'm trying to capture H264 stream from locally installed Logitech C920 camera from /dev/video0 with Gstreamer 1.0 v4l2src element.

v4l2-ctl --list-formats shows that camera is capable to give H264 video format:

# v4l2-ctl --list-formats
ioctl: VIDIOC_ENUM_FMT
        ...

        Index       : 1
        Type        : Video Capture
        Pixel Format: 'H264' (compressed)
        Name        : H.264

        ...

But pipeline

# gst-launch-1.0 -vvv v4l2src device=/dev/video0 ! video/x-h264, width=800, height=448, framerate=30/1 ! fakesink

keeps giving me not-negotiated (-4) error:

/GstPipeline:pipeline0/GstV4l2Src:v4l2src0.GstPad:src: caps = video/x-h264, width=(int)800, height=(int)448, interlace-mode=(string)progressive, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction)30/1
/GstPipeline:pipeline0/GstCapsFilter:capsfilter0.GstPad:src: caps = video/x-h264, width=(int)800, height=(int)448, interlace-mode=(string)progressive, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction)30/1
/GstPipeline:pipeline0/GstFakeSink:fakesink0.GstPad:sink: caps = video/x-h264, width=(int)800, height=(int)448, interlace-mode=(string)progressive, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction)30/1
/GstPipeline:pipeline0/GstCapsFilter:capsfilter0.GstPad:sink: caps = video/x-h264, width=(int)800, height=(int)448, interlace-mode=(string)progressive, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction)30/1
ERROR: from element /GstPipeline:pipeline0/GstV4l2Src:v4l2src0: Internal data flow error.
Additional debug info:
gstbasesrc.c(2809): gst_base_src_loop (): /GstPipeline:pipeline0/GstV4l2Src:v4l2src0:
streaming task paused, reason not-negotiated (-4)
Execution ended after 67687169 ns.

Any help!

Answer

Vincent Hiribarren picture Vincent Hiribarren · Apr 8, 2013

Is gstreamer mandatory for your needs? I also have lots of problems with the Logitech C920 in H264 mode and gstreamer. But I managed to use VLC as a RTSP server to use the C920 with H264:

$ cvlc -v v4l2:///dev/video0:chroma="H264":width=1024:height=570:fps=30 \
       --sout="#rtp{sdp=rtsp://:8554/live}"

Then I can connect with another VLC to the URI rtsp://localhost:8554/live

If GStreamer is mandatory for you, I only managed to use it with a capture utility that you can find here: https://github.com/csete/bonecam - directory "capture"

You have to compile it, but if you have some programming skills it shoud be very easy as there is only one C file and a script to help. Just pass "host" as a parameter to the script :

# Get the bonecam/capture content or git clone the directory, and then
$ cd bonecam/capture
$ ./build host

You can use the "capture" utility with something like that :

$ v4l2-ctl -d /dev/video0 --set-fmt-video=width=1024,height=570,pixelformat=1
$ v4l2-ctl -d /dev/video0 --set-parm=30
$ ./bonecam/capture/capture -d /dev/video0 -c 100000 -o | \
      gst-launch -e filesrc location=/dev/fd/0 ! legacyh264parse ! rtph264pay ! udpsink host=10.0.0.42 port=5000

If you do not like to specify the number of frame to get ("-c" parameter with "capture"), there is a fork to this utility that you can find here: https://github.com/DeLaGuardo/bonecam

I know there is a plugin categorized as "bad", called uvch264 for gstreamer 0.10, that should work with the C920. But I do not know for gstreamer 1.0, and I could not test it.

UPD:

Don't forget to add --rtsp-timeout=-1 to cvlc command line like

$ cvlc -v v4l2:///dev/video0:chroma="H264":width=1024:height=570:fps=30 \
       --sout="#rtp{sdp=rtsp://:8554/live}" --rtsp-timeout=-1

Without this option streaming only lasts for 60 seconds by default.