guysoft / OctoPi

Scripts to build OctoPi, a Raspberry PI distro for controlling 3D printers over the web
GNU General Public License v3.0
2.49k stars 368 forks source link

Add automatic switch to YUV in case mjpg webcam mode fails #15

Open guysoft opened 11 years ago

guysoft commented 11 years ago

Continuing from this issue OctoPi should be able to try and switch to YUV video protocol if mjpg fails on first attempt. This would bring OctoPrint webcam abilities running out of the box to even more cameras

CptanPanic commented 10 years ago

So I tried hooking up my cheap webcam, and it doesn't support mjpg only YUV, so I updated the webcam script, and thought it worked great. But then I realized that the raspi was running very slow, and looked at top, and mjpg_streamer was running from 70-100% cpu. I looked around and it seems that this is because of running in YUV video mode. If this is correct, I don't think you should try to support this, as I think it will mess things up as it makes the raspi work too hard.

guysoft commented 10 years ago

Hey, It works in some cameras, its probable that your camera has some other problem that causes it to hog the CPU. Might be some bug with mjpg_streamer as well.

CptanPanic commented 10 years ago

So looking the code in mjpg_streamer, i see:

        /*
* If capturing in YUV mode convert to JPEG now.
* This compression requires many CPU cycles, so try to avoid YUV format.
* Getting JPEGs straight from the webcam, is one of the major advantages of
* Linux-UVC compatible devices.
*/
#ifndef NO_LIBJPEG
        if ((pcontext->videoIn->formatIn == V4L2_PIX_FMT_YUYV) || (pcontext->videoIn->formatIn == V4L2_PIX_FMT_RGB565)) {
            DBG("compressing frame from input: %d\n", (int)pcontext->id);
            pglobal->in[pcontext->id].size = compress_image_to_jpeg(pcontext->videoIn, pglobal->in[pcontext->id].buf, pcontext->videoIn->framesizeIn, gquality);
        } else {
            DBG("copying frame from input: %d\n", (int)pcontext->id);
            pglobal->in[pcontext->id].size = memcpy_picture(pglobal->in[pcontext->id].buf, pcontext->videoIn->tmpbuffer, pcontext->videoIn->buf.bytesused);
#ifndef NO_LIBJPEG
        }
#endif

Do you know if the version on octopi is using LIBJPEG?

CptanPanic commented 10 years ago

So I followed the guide here: http://blog.miguelgrinberg.com/post/how-to-build-and-run-mjpg-streamer-on-the-raspberry-pi to build new mjpg-streamer and without changing any settings it runs 20-25% vs. 60-80%.

guysoft commented 10 years ago

@jacksonliam Is this because we are using your version of mjpg-streamer?

jacksonliam commented 10 years ago

It should be trivial to port my plugin to a different version of mjpg streamer, it's built as a lib so just copypasata the folder and add it to the makefile. If they've changed the plugin API it won't work though, obviously. It's not really 'my' version, it's one of the mjpg streamer versions which I used to dev the plugin :-)

However, it might be better for octopi to switch to using the 'new' official v4l2 driver for the pi cam rather than my plugin. Performance should only be a tiny bit worse and 'new is always better' :-)

http://www.raspberrypi.org/forums/viewtopic.php?f=43&t=62364&sid=08c7d629b7608001d7169e9e7d45552c

Config is slightly different (using v4l2-ctl) but might lend itself to custom buttons (https://github.com/foosel/OctoPrint/wiki/Cookbook:-Custom-Controls) rather than requiring editing of config files.

guysoft commented 10 years ago

@jacksonliam Would this work?

Also in the link you provided ( https://github.com/foosel/OctoPrint/wiki/Cookbook:-Custom-Controls ) I can't see anything about how the configuration should be set up, can you be more specific?

git clone git://git.linuxtv.org/v4l-utils.git
sudo apt-get install autoconf gettext libtool libjpeg62-dev
cd v4l-utils
autoreconf -vfi
./configure
make
sudo make install
foosel commented 9 years ago

I'd actually vote against such an automatic failover. Due to the way higher load that yuv mode causes people should always be aware when they run that (and be encouraged to switch to a camera that natively supports mjpg streamer). If you make it an automatic failover, you sacrifice reliability for instant gratification.

jacksonliam commented 9 years ago

Woah this issue is a year old?

I looked into using v4l2, but it had a few issues which probably makes my plugin the better choice for mjpg. But I wonder if octoprint could support different types of streams? As mjpg isn't a very efficient codec. Gstreamer supports the pi's hardware encoders IIRC.

Was it ever conclusive that another version of mjpg streamer could help with the yuv to mjpg transcoding? If so does someone have a link to the specific code I should be porting my plugin to?

I guess I'm wondering about your thoughts of how the webcam stuff should work going forward, e.g are you considering breaking that functionality out into a plugin?

Cheers, Liam.

foosel commented 9 years ago

Sorry, I just though it was time for some spring cleaning and took the liberty to go through all the old tickets, chiming in where I though I had to add something ;)

I have actually thought about enabling other video formats through plugins in OctoPrint. That would first require a modularization of how things work right now, and an idea how to best handle the snapshot stuff for timelapsing. Mjpg streamer now does both good enough and to be honest I never looked into if other tools for video streaming would also offer to capture snapshots. That video stuff is all just black magic for me ;) But people have been crying for rtsp and h.264 support, so it definitely would make sense to open up OctoPrint in that regard.