This is a quarter-continuation from this post : How To : Stream A Webcam From The Raspberry Pi
I had a look at the settings that I was using to stream from my Raspberry Pi as I had it doing other things for a while, and I was using 320×240 @ 10fps. Some people were having some issues where the streaming would either not start, or would stop very quickly.
I bumped up the resolution to 640×480 and I started having the same issue. I was getting errors like the one below –
[video4linux2,v4l2 @ 0x1d4e520] The v4l2 frame is 40588 bytes, but 614400 bytes are expected
After some looking around, I found some utilities that I could use to glean some more information about my webcam.
v4l2-ctl could show the capabilities of the webcam itself. I installed some other v4l utilities while I was at it in case I needed them later.
apt-get install v4l-utils v4l-conf
After I installed it, I could check to see whether my webcam could stream in mjpeg format directly.
root@raspbian:~# v4l2-ctl --list-formats
ioctl: VIDIOC_ENUM_FMT
Index : 0
Type : Video Capture
Pixel Format: 'YUYV'
Name : YUV 4:2:2 (YUYV)
Alas, it seems like mine can’t. So I’ll have to find out why the frames are getting cut short.
Lowering the resolution to 160×120 helps but that’s not really an ideal solution.
I had a spare webcam to try out, and the spare webcam worked on 640×480 without any tweaking.
Seems that some webcams just can’t do what we want them to do !
For now, I have another webcam streaming 640×480 @ 7fps and it seems to be working. I’ll report back on results soon !
Nice work, how about 720p and 30fps?
Thanks π
I don’t have a webcam capable of that resolution so I can’t say for sure, but I doubt the Pi can encode 720p at 30 fps at the moment. If the cam can record straight into mjpeg then possibly, but otherwise I wouldn’t bet on it for a little while.
The Pi Foundation just released news that the Pi supports H.264 encoding in hardware, so I’ll see if ffmpeg can use that to encode.
my webcam is able to output mjpeg directly. How do I activate this? in the output of the webcam.sh script it says that it converts raw to mjpeg…
I don’t have a webcam capable of outputting mjpeg, so I can’t test this, but try adding -vcodec mjpeg to the arguments after size and see how you go.
[…] Pi How To : Stream A Webcam From The Raspberry Pi Β» The Rantings and Ravings of a Madman How To : Stream A Webcam From The Raspberry Pi Part 2 Β» The Rantings and Ravings of a Madman tsuki_chama: Raspberry Tank Day 14: Video Streaming Webcam streaming with Raspberry […]
Cool tutorial(s)! I got my pair of R-PIs with the intention of replacing my ancient Debian box, and this pretty much covers the webcam portion. Still have some tweaks to try as I did have motion detection working on the old server using Motion.
Thanks for reading !
Hopefully it all goes well π
mine says:
ioctl: VIDIOC_ENUM_FMT
Index : 0
Type : Video Capture
Pixel Format: ‘JPEG’ (compressed)
Name : JPEG
so can i stream mjpeg directly?
It looks like you’d be able to stream mjpeg directly.
Only one way to find out π
Btw, if you put in gibberish like alsfdka@sdfsdf.com for an email, my spam filter will think you are a spammer and not tell me you commented.
I think uvcdynctrl can be far more helpful. In my case that tool helped be realize that my MS Lifecam HD-5000 (045e:076d) can only do 30fps 720p using MJPG pixel format.
pi@picam:~$ uvcdynctrl -f
Listing available frame formats for device video0:
Pixel format: YUYV (YUV 4:2:2 (YUYV); MIME type: video/x-raw-yuv)
Frame size: 640x480
Frame intervals: 1/30, 1/20, 1/15, 1/10, 2/15
Frame size: 1280x720
Frame intervals: 1/10, 2/15
Frame size: 960x544
Frame intervals: 1/15, 1/10, 2/15
Frame size: 800x448
Frame intervals: 1/20, 1/15, 1/10, 2/15
Frame size: 640x360
Frame intervals: 1/30, 1/20, 1/15, 1/10, 2/15
Frame size: 424x240
Frame intervals: 1/30, 1/20, 1/15, 1/10, 2/15
Frame size: 352x288
Frame intervals: 1/30, 1/20, 1/15, 1/10, 2/15
Frame size: 320x240
Frame intervals: 1/30, 1/20, 1/15, 1/10, 2/15
Frame size: 800x600
Frame intervals: 1/15, 1/10, 2/15
Frame size: 176x144
Frame intervals: 1/30, 1/20, 1/15, 1/10, 2/15
Frame size: 160x120
Frame intervals: 1/30, 1/20, 1/15, 1/10, 2/15
Frame size: 1280x800
Frame rates: 10
Pixel format: MJPG (MJPEG; MIME type: image/jpeg)
Frame size: 640x480
Frame intervals: 1/30, 1/20, 1/15, 1/10, 2/15
Frame size: 1280x720
Frame intervals: 1/30, 1/20, 1/15, 1/10, 2/15
Frame size: 960x544
Frame intervals: 1/30, 1/20, 1/15, 1/10, 2/15
Frame size: 800x448
Frame intervals: 1/30, 1/20, 1/15, 1/10, 2/15
Frame size: 640x360
Frame intervals: 1/30, 1/20, 1/15, 1/10, 2/15
Frame size: 800x600
Frame intervals: 1/30, 1/20, 1/15, 1/10, 2/15
Frame size: 416x240
Frame intervals: 1/30, 1/20, 1/15, 1/10, 2/15
Frame size: 352x288
Frame intervals: 1/30, 1/20, 1/15, 1/10, 2/15
Frame size: 176x144
Frame intervals: 1/30, 1/20, 1/15, 1/10, 2/15
Frame size: 320x240
Frame intervals: 1/30, 1/20, 1/15, 1/10, 2/15
Frame size: 160x120
Frame intervals: 1/30, 1/20, 1/15, 1/10, 2/15
Thanks for the tip π
I’ll need to keep that on my list of useful tools π
Maybe your transport stream is using UDP instead of TCP somewhere…and you could switch it to use TCP?
Unfortunately it’s ffmpeg that is having the issue and not the networking part of things.
I’ve ran into this issue before as well and have had a chance to get a pretty crude workaround.
Run the ffmpeg command again and make sure to CTRL+C _before_ you see this error.
Now, run the command once more and it should start streaming flawlessly. Seems like the CTRL+C clears some state somewhere in v4l2 and then the next run is able to start cleanly.
I’ve not had the chance to debug this inside the code itself though.
Yes I’ve also noticed that behaviour, however it still doesn’t run forever Unfortunately. Eventually the error comes again.
Thanks for the tutorial.
I had to change the port (to 8001) because I got a “bind(port 80): Address already in use” error. Same if I used 8000.
When I run it I get the output below. Everything looks good until the HTTP error and the I/O error.
Any hints as to where I should look to resolve these?
markamos@raspberrypi /usr/sbin $ sudo webcam.sh
ffserver version 1.0 Copyright (c) 2000-2012 the FFmpeg developers
ffmpeg version 1.0 Copyright (c) 2000-2012 the FFmpeg developers
built on Nov 14 2012 21:26:23 with gcc 4.6 (Debian 4.6.3-8+rpi1)
configuration:
built on Nov 14 2012 21:26:23 with gcc 4.6 (Debian 4.6.3-8+rpi1)
configuration:
libavutil 51. 73.101 / 51. 73.101
libavcodec 54. 59.100 / 54. 59.100
libavformat 54. 29.104 / 54. 29.104
libavdevice 54. 2.101 / 54. 2.101
libavfilter 3. 17.100 / 3. 17.100
libavutil 51. 73.101 / 51. 73.101
libavcodec 54. 59.100 / 54. 59.100
libavformat 54. 29.104 / 54. 29.104
libavdevice 54. 2.101 / 54. 2.101
libavfilter 3. 17.100 / 3. 17.100
libswscale 2. 1.101 / 2. 1.101
libswscale 2. 1.101 / 2. 1.101
libswresample 0. 15.100 / 0. 15.100
libswresample 0. 15.100 / 0. 15.100
[video4linux2,v4l2 @ 0x1ae1620] [3]Capabilities: 4000001
[video4linux2,v4l2 @ 0x1ae1620] The driver changed the time per frame from 1/5 to 2/15
[video4linux2,v4l2 @ 0x1ae1620] Estimating duration from bitrate, this may be inaccurate
Input #0, video4linux2,v4l2, from ‘/dev/video0’:
Duration: N/A, start: 88542.945206, bitrate: 36864 kb/s
Stream #0:0: Video: rawvideo (YUY2 / 0x32595559), yuyv422, 640×480, 36864 kb/s, 7.50 tbr, 1000k tbn, 7.50 tbc
[http @ 0x1ae1d30] HTTP error 404 Not Found
http://localhost/webcam.ffm: Input/output error
Hope the tutorial helped π
That error at the end is because ffmpeg is looking for webcam.ffm on port 80.
If you change the port that ffserver runs on, you need to direct ffmpeg to the new port In webcam.sh.
If you change http://localhost/webcam.ffm to http://localhost:8001/webcam.ffm then it should work.
Hi.
Thanks for your tutorial. However I can’t stream my webcam. I think it’s because ffserver try to stream the stream #0 which is a YUYV one. Hox can I tell to ffserver to stream the stream #1, which is a mjpeg one ?
Here is wy cebcam capabilities (a Logitech c270)
root@raspberrypi:~# v4l2-ctl --list-formats
ioctl: VIDIOC_ENUM_FMT
Index : 0
Type : Video Capture
Pixel Format: 'YUYV'
Name : YUV 4:2:2 (YUYV)
Index : 1
Type : Video Capture
Pixel Format: 'MJPG' (compressed)
Name : MJPEG
Try adding -map 1 to the command line
Thanks for your idea. But I’ve this error message :
Invalid input file index: 1.
I’ve also try -map 0, -map 0:1 and -map 1:1, doesn’t work too. My poor english slow my understaning of ffmpeg’s man page so I can’t find any other solution. If you have any other idea i’ll try it π
KaitoKito.
Have you tried using -vcodec mjpeg ?
It doesn’t work. According to the error message, it’s the same problem. I’ve read the man page of ffmpeg about the -map option but I can’t see anything new. Maybe ffmpeg see my webcam streams differently. Do you know another way than using “v4l2-ctl –list-formats” command line to know my webcam streams?
Here’s the new error message :
[video4linux2,v4l2 @ 0x1a28690] The v4l2 frame is 2289 bytes, but 76800 bytes are expected
[video4linux2,v4l2 @ 0x1a28690] Could not find codec parameters for stream 0 (Video: mjpeg, 320x240, 3072 kb/s): unspecified pixel format
Consider increasing the value for the 'analyzeduration' and 'probesize' options
[video4linux2,v4l2 @ 0x1a28690] Estimating duration from bitrate, this may be inaccurate
/dev/video0: could not find codec parameters
root@raspberrypi:~#
Try using -vcodec mjpeg as well as -map 1 and see if that works ?
In order to use the mpjeg video capture you have to use this command : v4l2-ctl -d /dev/video0 -v width=640,height=480,pixelformat=MJPG
root@domo7:~# v4l2-ctl --all
Driver Info (not using libv4l2):
Driver name : uvcvideo
Card type : UVC Camera (046d:0819)
Bus info : usb-bcm2708_usb-1.3
Driver version: 3.6.11
Capabilities : 0x04000001
Video Capture
Streaming
Format Video Capture:
Width/Height : 640/480
Pixel Format : 'YUYV'
Field : None
Bytes per Line: 1280
Size Image : 614400
Colorspace : SRGB
Crop Capability Video Capture:
Bounds : Left 0, Top 0, Width 640, Height 480
Default : Left 0, Top 0, Width 640, Height 480
Pixel Aspect: 1/1
Video input : 0 (Camera 1: ok)
Streaming Parameters Video Capture:
Capabilities : timeperframe
Frames per second: 30.000 (30/1)
Read buffers : 0
root@domo7:~# v4l2-ctl -d /dev/video0 -v width=640,height=480,pixelformat=MJPG
root@domo7:~# v4l2-ctl --all
Driver Info (not using libv4l2):
Driver name : uvcvideo
Card type : UVC Camera (046d:0819)
Bus info : usb-bcm2708_usb-1.3
Driver version: 3.6.11
Capabilities : 0x04000001
Video Capture
Streaming
Format Video Capture:
Width/Height : 640/480
Pixel Format : 'MJPG'
Field : None
Bytes per Line: 0
Size Image : 213333
Colorspace : SRGB
Crop Capability Video Capture:
Bounds : Left 0, Top 0, Width 640, Height 480
Default : Left 0, Top 0, Width 640, Height 480
Pixel Aspect: 1/1
Video input : 0 (Camera 1: ok)
Streaming Parameters Video Capture:
Capabilities : timeperframe
Frames per second: 30.000 (30/1)
Read buffers : 0
JPG
Thanks for the tip !
I didn’t have to do that with mine, but I guess it depends on the webcam π
Does anyone know how to crop the webcam image?
I’ve tried playing with ffmpeg’s crop commands: -vf crop=w:h:x:y but it has no efect on the stream.
I basically just want to crop the top and bottom of my webcam image.
I also found that the problem of “cut short frames” also appears when you capture from a digitizing stick like the Easycap /Mumbi stk1160 based ones, and have a VHS source hooked up.
Whenever one recording stops and another one starts on the VHS tape, and the short burst of noise gets captured, as it seems, you get these half frames. So this might be a good way to find breaks between recordings on tape, but that avconv / ffmpeg chokes on these is not so nice… Someone filed a bug that avconv should silently ignore these, like mencoder, but the devs ignored it so far…