-
Notifications
You must be signed in to change notification settings - Fork 7
Install
sgjava edited this page Apr 20, 2014
·
36 revisions
You assume all the risks that come with flashing an Android device. It's very painless and hard to screw up, but if you do brick your Mini PC you are on your own!
I had problems using mjpg-streamer, uvccapture, fswebcam which return VIDIOC_DQBUF: Invalid argument or something similar. Cheese, gstreamer and vlc player (cvlc) worked. gstreamer worked the best, so that's what we are going to use here.
- Test USB camera under the original ROM
- Boot up Mini PC with original ROM and configure your Google account
- Download camera app if your ROM doesn't have one
- Plug in your camera and take a picture
- If that worked then there's a good chance it will work under Linux!
- Install Finless 1.7 ROM on MK808. If you have another Mini PC model check
for Finless on that model (you can skip to step 3, but Finless makes the
reboot process easier) For RK3188 devices install a NEOTV ROM.
- MK808 "all models" Finless 1.7
- NEOTV CROM 1.9 MK802IV Old Wifi,MK809III,UG007B,QC802,Cloudnet Go CR9
- Neomode Custom Rom MK802IV / MK809III 2.1 BETA RK3188-T and RK3188
- Pick another compatible ROM for your particular mini PC
- Extract zip file on Windows PC and read README FIRST.TXT (if it exists)
- Install Ubuntu
- My project Ubuntu Mini will let you build kernels and Ubuntu distribution
- PicUntu
- Some other Ubuntu based distribution.
- When complete reboot using terminal with original ROM or Reboot app in Finless Rom (use bootloader option)
- If using a RK3188 you have to create an init.d script as detailed in Flash kernel
- Make sure networking is working (ping gateway, etc.)
- Test camera
- SSH into Mini PC as root/12qwaszx (for PicUntu or whatever user you created)
sudo apt-get install usbutils
-
lsusb
- You should see something like:
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub Bus 002 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub Bus 002 Device 002: ID 03f0:a707 Hewlett-Packard
- Note "Hewlett-Packard" is my camera
- Add non-privileged user
adduser <username>
adduser <username> sudo
usermod -a -G video <username>
- Install gstreamer
apt-get install python-gi python3-gi \ gstreamer1.0-tools \ gir1.2-gstreamer-1.0 \ gir1.2-gst-plugins-base-1.0 \ gstreamer1.0-plugins-good \ gstreamer1.0-plugins-ugly \ gstreamer1.0-plugins-bad \ gstreamer1.0-libav
- Install uvcdynctrl
apt-get install uvcdynctrl
- reboot
- SSH in as user you just created
- Get camera information
export GST_DEBUG="*v4l2*:5"
gst-launch-1.0 -v v4l2src num-buffers=1 ! fakesink&>debug.txt
nano debug.txt
- Find out what formats are supported (MJPG support, excellent, no encoding required for gstreamer):
getting src format enumerations got 6 format(s): YUYV MJPG YU12 (emulated) YV12 (emulated) BGR3 (emulated) RGB3 (emulated)
- Find resolutions, frame rates, etc. in debug.txt
probed caps: video/x-raw, format=(string)YUY2, width=(int)1280, height=(int)720, interlace-mode=(string)progressive, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction){ 15/2, 5/1 }; video/x-raw, format=(string)YUY2, width=(int)800, height=(int)600, interlace-mode=(string)progressive, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction){ 15/1, 10/1, 5/1 }; video/x-raw, format=(string)YUY2, width=(int)640, height=(int)480, interlace-mode=(string)progressive, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction){ 30/1, 25/1, 20/1, 15/1, 10/1, 5/1 }; video/x-raw, format=(string)YUY2, width=(int)352, height=(int)288, interlace-mode=(string)progressive, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction){ 30/1, 25/1, 20/1, 15/1, 10/1, 5/1 }; video/x-raw, format=(string)YUY2, width=(int)320, height=(int)240, interlace-mode=(string)progressive, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction){ 30/1, 25/1, 20/1, 15/1, 10/1, 5/1 }; video/x-raw, format=(string)YUY2, width=(int)176, height=(int)144, interlace-mode=(string)progressive, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction){ 30/1, 25/1, 20/1, 15/1, 10/1, 5/1 }; video/x-raw, format=(string)YUY2, width=(int)160, height=(int)120, interlace-mode=(string)progressive, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction){ 30/1, 25/1, 20/1, 15/1, 10/1, 5/1 }; image/jpeg, width=(int)1280, height=(int)720, interlace-mode=(string)progressive, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction){ 30/1, 25/1, 20/1, 15/1, 10/1, 5/1 }; image/jpeg, width=(int)800, height=(int)600, interlace-mode=(string)progressive, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction){ 30/1, 25/1, 20/1, 15/1, 10/1, 5/1 }; image/jpeg, width=(int)640, height=(int)480, interlace-mode=(string)progressive, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction){ 30/1, 25/1, 20/1, 15/1, 10/1, 5/1 }; image/jpeg, width=(int)352, height=(int)288, interlace-mode=(string)progressive, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction){ 30/1, 25/1, 20/1, 15/1, 10/1, 5/1 }; image/jpeg, width=(int)320, height=(int)240, interlace-mode=(string)progressive, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction){ 30/1, 25/1, 20/1, 15/1, 10/1, 5/1 }; image/jpeg, width=(int)176, height=(int)144, interlace-mode=(string)progressive, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction){ 30/1, 25/1, 20/1, 15/1, 10/1, 5/1 }; image/jpeg, width=(int)160, height=(int)120, interlace-mode=(string)progressive, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction){ 30/1, 25/1, 20/1, 15/1, 10/1, 5/1 }; video/x-raw, format=(string)I420, width=(int)1280, height=(int)720, interlace-mode=(string)progressive, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction){ 30/1, 25/1, 20/1, 15/1, 10/1, 5/1 }; video/x-raw, format=(string)I420, width=(int)800, height=(int)600, interlace-mode=(string)progressive, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction){ 30/1, 25/1, 20/1, 15/1, 10/1, 5/1 }; video/x-raw, format=(string)I420, width=(int)640, height=(int)480, interlace-mode=(string)progressive, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction){ 30/1, 25/1, 20/1, 15/1, 10/1, 5/1 }; video/x-raw, format=(string)I420, width=(int)352, height=(int)288, interlace-mode=(string)progressive, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction){ 30/1, 25/1, 20/1, 15/1, 10/1, 5/1 }; video/x-raw, format=(string)I420, width=(int)320, height=(int)240, interlace-mode=(string)progressive, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction){ 30/1, 25/1, 20/1, 15/1, 10/1, 5/1 }; video/x-raw, format=(string)I420, width=(int)176, height=(int)144, interlace-mode=(string)progressive, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction){ 30/1, 25/1, 20/1, 15/1, 10/1, 5/1 }; video/x-raw, format=(string)I420, width=(int)160, height=(int)120, interlace-mode=(string)progressive, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction){ 30/1, 25/1, 20/1, 15/1, 10/1, 5/1 }; video/x-raw, format=(string)YV12, width=(int)1280, height=(int)720, interlace-mode=(string)progressive, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction){ 30/1, 25/1, 20/1, 15/1, 10/1, 5/1 }; video/x-raw, format=(string)YV12, width=(int)800, height=(int)600, interlace-mode=(string)progressive, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction){ 30/1, 25/1, 20/1, 15/1, 10/1, 5/1 }; video/x-raw, format=(string)YV12, width=(int)640, height=(int)480, interlace-mode=(string)progressive, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction){ 30/1, 25/1, 20/1, 15/1, 10/1, 5/1 }; video/x-raw, format=(string)YV12, width=(int)352, height=(int)288, interlace-mode=(string)progressive, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction){ 30/1, 25/1, 20/1, 15/1, 10/1, 5/1 }; video/x-raw, format=(string)YV12, width=(int)320, height=(int)240, interlace-mode=(string)progressive, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction){ 30/1, 25/1, 20/1, 15/1, 10/1, 5/1 }; video/x-raw, format=(string)YV12, width=(int)176, height=(int)144, interlace-mode=(string)progressive, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction){ 30/1, 25/1, 20/1, 15/1, 10/1, 5/1 }; video/x-raw, format=(string)YV12, width=(int)160, height=(int)120, interlace-mode=(string)progressive, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction){ 30/1, 25/1, 20/1, 15/1, 10/1, 5/1 }; video/x-raw, format=(string)BGR, width=(int)1280, height=(int)720, interlace-mode=(string)progressive, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction){ 30/1, 25/1, 20/1, 15/1, 10/1, 5/1 }; video/x-raw, format=(string)BGR, width=(int)800, height=(int)600, interlace-mode=(string)progressive, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction){ 30/1, 25/1, 20/1, 15/1, 10/1, 5/1 }; video/x-raw, format=(string)BGR, width=(int)640, height=(int)480, interlace-mode=(string)progressive, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction){ 30/1, 25/1, 20/1, 15/1, 10/1, 5/1 }; video/x-raw, format=(string)BGR, width=(int)352, height=(int)288, interlace-mode=(string)progressive, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction){ 30/1, 25/1, 20/1, 15/1, 10/1, 5/1 }; video/x-raw, format=(string)BGR, width=(int)320, height=(int)240, interlace-mode=(string)progressive, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction){ 30/1, 25/1, 20/1, 15/1, 10/1, 5/1 }; video/x-raw, format=(string)BGR, width=(int)176, height=(int)144, interlace-mode=(string)progressive, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction){ 30/1, 25/1, 20/1, 15/1, 10/1, 5/1 }; video/x-raw, format=(string)BGR, width=(int)160, height=(int)120, interlace-mode=(string)progressive, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction){ 30/1, 25/1, 20/1, 15/1, 10/1, 5/1 }; video/x-raw, format=(string)RGB, width=(int)1280, height=(int)720, interlace-mode=(string)progressive, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction){ 30/1, 25/1, 20/1, 15/1, 10/1, 5/1 }; video/x-raw, format=(string)RGB, width=(int)800, height=(int)600, interlace-mode=(string)progressive, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction){ 30/1, 25/1, 20/1, 15/1, 10/1, 5/1 }; video/x-raw, format=(string)RGB, width=(int)640, height=(int)480, interlace-mode=(string)progressive, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction){ 30/1, 25/1, 20/1, 15/1, 10/1, 5/1 }; video/x-raw, format=(string)RGB, width=(int)352, height=(int)288, interlace-mode=(string)progressive, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction){ 30/1, 25/1, 20/1, 15/1, 10/1, 5/1 }; video/x-raw, format=(string)RGB, width=(int)320, height=(int)240, interlace-mode=(string)progressive, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction){ 30/1, 25/1, 20/1, 15/1, 10/1, 5/1 }; video/x-raw, format=(string)RGB, width=(int)176, height=(int)144, interlace-mode=(string)progressive, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction){ 30/1, 25/1, 20/1, 15/1, 10/1, 5/1 }; video/x-raw, format=(string)RGB, width=(int)160, height=(int)120, interlace-mode=(string)progressive, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction){ 30/1, 25/1, 20/1, 15/1, 10/1, 5/1 }
- For a more consice list use
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 rates: 30, 25, 20, 15, 10, 5 Frame size: 352x288 Frame rates: 30, 25, 20, 15, 10, 5 Frame size: 320x240 Frame rates: 30, 25, 20, 15, 10, 5 Frame size: 176x144 Frame rates: 30, 25, 20, 15, 10, 5 Frame size: 160x120 Frame rates: 30, 25, 20, 15, 10, 5 Frame size: 800x600 Frame rates: 15, 10, 5 Frame size: 1280x720 Frame intervals: 2/15, 1/5 Pixel format: MJPG (MJPEG; MIME type: image/jpeg) Frame size: 640x480 Frame rates: 30, 25, 20, 15, 10, 5 Frame size: 352x288 Frame rates: 30, 25, 20, 15, 10, 5 Frame size: 320x240 Frame rates: 30, 25, 20, 15, 10, 5 Frame size: 176x144 Frame rates: 30, 25, 20, 15, 10, 5 Frame size: 160x120 Frame rates: 30, 25, 20, 15, 10, 5 Frame size: 800x600 Frame rates: 30, 25, 20, 15, 10, 5 Frame size: 1280x720 Frame rates: 30, 25, 20, 15, 10, 5
- Let's see if we can record a 500 frame video
export GST_DEBUG="*v4l2*:0"
gst-launch-1.0 v4l2src num-buffers=500 ! image/jpeg ! avimux ! filesink location=video.avi
- Don't worry about libv4l2: error dequeuing buf: Success messages since we will mute those later on
- SCP video to your desktop PC and see if it recorded correctly
- Test streaming over HTTP
- Run GStreamerMjpeg Python class
- Copy streamer package to your home dir
export PYTHONPATH=/home/<username>/streamer
python -u /home/<username>/streamer/GStreamerMjpeg.py
Launching camera server on port 1337 Launch input stream thread Httpd serve foreverWaiting for input stream from gstreamer...
- Start another SSH session and run gstreamer pipeline
gst-launch-1.0 v4l2src, timeout=5 ! image/jpeg, framerate=30/1, width=320, height=240 ! multipartmux boundary=cvp ! tcpclientsink port=9999&>/dev/null
Accepted input stream from ('127.0.0.1', 39999)
- Go to http://192.168.1.69:1337 (change to the IP address to that of the Mini PC)
192.168.1.106 - - [22/May/2013 22:19:21] "GET / HTTP/1.1" 200 166
- At this point you have a streaming MJPEG webcam. You can stop here or you can proceed to step 6 to make your Mini PC an intelligent camera system.
- Run GStreamerMjpeg Python class
- Add network checking script. Since wifi connections will have connectivity problems for a number of reasons it's
prudent to monitor the connection from the device. Checking every five minutes will usually be enough for most
scenarios. You can go down to every minute resolution with Cron. Using this script has made my BYOC cameras as or
more reliable than my stand alone network cameras.
sudo su -
wget https://raw.github.com/sgjava/byoc/master/scripts/checknet.sh
mkdir -p /opt/scripts
cp checknet.sh /opt/scripts/checknet.sh
chmod a+x /opt/scripts/checknet.sh
crontab -e
- Add
*/5 * * * * bash /opt/scripts/checknet.sh
- Exit/save from editor
-
CVP is a Python based system that takes
input from video sources such as network cameras, web cams, files, etc. and
makes intelligent decisions based on analyzing each frame.
- Follow CVP install directions.
- Make copies of linuxroot sd (this will save a huge amount of time). Note that this will only work on similar Mini PC hardware. You
can also make a base install to revert back to in case you screw it up some how.
Compress with permissions:
-
sudo tar -pzcf /home/<username>/linuxroot.tar.gz -C /media/linuxroot .
- Change and SDHC location as needed. Extract with permissions:
-
sudo tar -pzxf /home/<username>/linuxroot.tar.gz -C /media/linuxroot
- Change and SDHC location as needed.
-
- If you flashed Finless ROM you can reboot into recovery which will cause PicUntu to boot instead of Android. You will not be able to get back to Android again without reflashing (pressing the reset button on MK808). Otherwise you should reboot into bootloader until you are ready for PicUntu only.