├── .gitignore ├── .indent.pro ├── client ├── audio_client_opus.sh ├── audio_client_raw.sh ├── audio_client_vorbis.sh └── video_client.sh ├── doc ├── create_image.txt └── quickref.txt ├── hardware ├── power │ └── oki-78sr.pdf └── servo │ ├── bpt-ns_assy.pdf │ ├── hs422-daatasheet.pdf │ ├── hs422-manual.pdf │ ├── servo_ctl_pololu.py │ ├── servo_ctl_sscii.py │ └── ssc03a_guide.pdf ├── legacy ├── angstrom │ ├── README │ ├── bonecam-image.bb │ └── gst-plugins-bad_0.10.23.bb ├── camctl │ ├── README │ ├── build │ └── camctl.c ├── capture │ ├── build │ └── capture.c ├── scripts │ ├── bonecam.sdp │ ├── video-client │ ├── video-server │ ├── voip-client │ └── voip-server ├── systemd │ ├── autostart-voip.sh │ └── bonecam-voip.service └── vidsrv │ ├── build │ ├── config.c │ ├── config.h │ ├── license.txt │ ├── main.c │ ├── readme.txt │ ├── socket_handler.c │ ├── socket_handler.h │ ├── video_server.c │ └── video_server.h ├── readme.txt ├── server ├── audiosrv.sh └── videosrv.sh └── systemd ├── bonecam-app.service ├── bonecam-app.sh └── readme.txt /.gitignore: -------------------------------------------------------------------------------- 1 | vidsrv/vidsrv 2 | legacy/capture/capture 3 | legacy/camctl/cam 4 | *~ 5 | 6 | -------------------------------------------------------------------------------- /.indent.pro: -------------------------------------------------------------------------------- 1 | -kr -i4 --no-tabs --line-length79 -di16 2 | --braces-after-if-line --brace-indent0 --dont-cuddle-else --cuddle-do-while 3 | --blank-lines-after-declarations --blank-lines-after-procedures 4 | --break-after-boolean-operator 5 | --no-space-after-casts 6 | --else-endif-column0 7 | 8 | -------------------------------------------------------------------------------- /client/audio_client_opus.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | usage () 4 | { 5 | echo "Usage: audio-client " 6 | } 7 | 8 | 9 | if [ $# -ne 1 ]; then 10 | usage 11 | exit 0 12 | fi 13 | 14 | gst-launch-1.0 -v udpsrc port=$1 ! \ 15 | application/x-rtp, media=audio, clock-rate=48000, payload=96, encoding-name=X-GST-OPUS-DRAFT-SPITTKA-00 ! \ 16 | rtpopusdepay ! opusdec ! alsasink device=plughw:0 sync=false 17 | 18 | -------------------------------------------------------------------------------- /client/audio_client_raw.sh: -------------------------------------------------------------------------------- 1 | # 2 | # Host side audio receiver for raw TCP stream. 3 | # 4 | 5 | gst-launch-1.0 -e -v tcpserversrc host=0.0.0.0 port=9100 ! audio/x-raw,format=\(string\)S16LE,rate=48000,channels=1 ! autoaudiosink 6 | 7 | -------------------------------------------------------------------------------- /client/audio_client_vorbis.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | usage () 4 | { 5 | echo "Usage: audio-client " 6 | } 7 | 8 | 9 | if [ $# -ne 1 ]; then 10 | usage 11 | exit 0 12 | fi 13 | 14 | 15 | ## 44.1 kHz mono, or else update the config string 16 | gst-launch-1.0 -v udpsrc port=$1 caps="application/x-rtp, media=(string)audio, clock-rate=(int)44100, encoding-name=(string)VORBIS, encoding-params=(string)1, configuration=(string)\"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\\=\\=\", payload=(int)96" ! rtpvorbisdepay ! vorbisdec ! audioconvert ! autoaudiosink sync=false 17 | 18 | -------------------------------------------------------------------------------- /client/video_client.sh: -------------------------------------------------------------------------------- 1 | gst-launch-1.0 -v udpsrc port=9040 caps='application/x-rtp, media=(string)video, clock-rate=(int)90000, encoding-name=(string)H264' ! rtph264depay ! avdec_h264 ! fpsdisplaysink fps-update-interval=5000 sync=false 2 | -------------------------------------------------------------------------------- /doc/create_image.txt: -------------------------------------------------------------------------------- 1 | Bonecam v2.1 image 2 | 3 | Create an SD card based on: 4 | http://elinux.org/Beagleboard:BeagleBoneBlack_Debian 5 | Tested: 6 | * 2014-11-11 7 | 8 | Update: 9 | /etc/hostname 10 | /etc/hosts 11 | /etc/issue 12 | /etc/issue.net 13 | /home/debian/.bashrc 14 | /root/.bashrc 15 | 16 | Create /etc/apt/apt.conf containing: 17 | APT::Install-Recommends "0"; 18 | APT::Install-Suggests "0"; 19 | 20 | sudo apt-get update 21 | sudo apt-get upgrade 22 | sudo apt-get install ntp time 23 | sudo apt-get install vim make gcc g++ pkg-config python ccache 24 | sudo apt-get install autoconf automake libtool intltool autopoint bison flex 25 | sudo apt-get install libglib2.0-dev libvorbis-dev libv4l-dev v4l-utils 26 | sudo apt-get install gtk-doc-tools alsa-utils libasound2-dev libjpeg-dev libpng12-dev 27 | 28 | For uvch264src: 29 | sudo apt-get install libusb-1.0-0-dev libgudev-1.0-dev 30 | 31 | 32 | Create the set_env.sh: 33 | PFX=/opt/bonecam 34 | export PATH=$PATH:$PFX/bin 35 | export LD_RUN_PATH=$LD_RUN_PATH:$PFX/lib 36 | export PKG_CONFIG_PATH=$PKG_CONFIG_PATH:$PFX/lib/pkgconfig 37 | export GST_PLUGIN_PATH=$PFX/lib/gstreamer-1.0 38 | 39 | 40 | Build and install ORC: 41 | http://gstreamer.freedesktop.org/src/orc/ 42 | 43 | Build and install Opus: 44 | http://downloads.xiph.org/releases/opus/opus-1.1.tar.gz 45 | 46 | Build and install 47 | gstreamer 48 | gst-plugins-base 49 | gst-plugins-good 50 | gst-plugins-bad 51 | 52 | --prefix=/opt/bonecam --enable-gtk-doc=no --enable-gtk-doc-html=no --enable-gtk-doc-pdf=no 53 | -------------------------------------------------------------------------------- /doc/quickref.txt: -------------------------------------------------------------------------------- 1 | Bonecam v2.1 quick reference 2 | 3 | Login through ssh or serial console. 4 | Username: debian 5 | Password: temppwd 6 | 7 | Network settings: 8 | /etc/network/interfaces 9 | /etc/hostname 10 | /etc/hosts 11 | 12 | Camera application is started using a systemd service: 13 | /etc/systemd/system/bonecam-app.service 14 | 15 | sudo systemctl --system daemon-reload 16 | sudo systemctl start bonecam-app.service 17 | sudo systemctl stop bonecam-app.service 18 | sudo systemctl enable bonecam-app.service 19 | sudo systemctl disable bonecam-app.service 20 | 21 | The bonecam-app.service executes the /opt/bonecam/bin/bonecam-app.sh script. 22 | This is the script that launches gstreamer pipelines, applications, etc. 23 | 24 | /opt/bonecam is also the prefix where gstreamer is installed. 25 | /opt/bonecam/set_env.sh can be sourced if any on-target devlopment or testing 26 | is to be performed. 27 | 28 | The sources are located in /home/debian 29 | -------------------------------------------------------------------------------- /hardware/power/oki-78sr.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/csete/bonecam/d38586b7bf92e955caad061c869cb0efd82048e9/hardware/power/oki-78sr.pdf -------------------------------------------------------------------------------- /hardware/servo/bpt-ns_assy.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/csete/bonecam/d38586b7bf92e955caad061c869cb0efd82048e9/hardware/servo/bpt-ns_assy.pdf -------------------------------------------------------------------------------- /hardware/servo/hs422-daatasheet.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/csete/bonecam/d38586b7bf92e955caad061c869cb0efd82048e9/hardware/servo/hs422-daatasheet.pdf -------------------------------------------------------------------------------- /hardware/servo/hs422-manual.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/csete/bonecam/d38586b7bf92e955caad061c869cb0efd82048e9/hardware/servo/hs422-manual.pdf -------------------------------------------------------------------------------- /hardware/servo/servo_ctl_pololu.py: -------------------------------------------------------------------------------- 1 | # Interface to Pololu SSC03A servo controller using the Pololu protocol. 2 | # Based on code from: 3 | # http://dmt195.wordpress.com/2009/01/19/python-to-interface-with-the-pololu-8-channel-servo-controller/ 4 | 5 | import serial 6 | import sys 7 | #set up the serial port for action 8 | ser=serial.Serial('/dev/ttyUSB0') 9 | ser.baudrate=9600 10 | def setspeed(n,speed): 11 | #Quick check that things are in range 12 | if speed > 127 or speed <0: 13 | speed=1 14 | print "WARNING: Speed should be between 0 and 127. Setting speed to 1..." 15 | print "Setting servo "+str(n)+" speed to "+str(speed)+" out of 127." 16 | speed=int(speed) 17 | #set speed (needs 0x80 as first byte, 0x01 as the second, 0x01 is for speed, 0 for servo 0, and 127 for max speed) 18 | bud=chr(0x80)+chr(0x01)+chr(0x01)+chr(n)+chr(speed) 19 | ser.write(bud) 20 | 21 | def setpos(n,angle): 22 | #Check that things are in range 23 | if angle > 180 or angle <0: 24 | angle=90 25 | print "WARNING: Angle range should be between 0 and 180. Setting angle to 90 degrees to be safe..." 26 | print "moving servo "+str(n)+" to "+str(angle)+" degrees." 27 | 28 | #Valid range is 500-5500 29 | offyougo=int(5000*angle/180)+500 30 | #Get the lowest 7 bits 31 | byteone=offyougo&127 32 | #Get the highest 7 bits 33 | bytetwo=(offyougo-(offyougo&127))/128 34 | #move to an absolute position in 8-bit mode (0x04 for the mode, 0 for the servo, 0-255 for the position (spread over two bytes)) 35 | bud=chr(0x80)+chr(0x01)+chr(0x04)+chr(n)+chr(bytetwo)+chr(byteone) 36 | ser.write(bud) 37 | 38 | mode=sys.argv[1] 39 | n=int(sys.argv[2]) 40 | m=int(sys.argv[3]) 41 | if mode=='speed': 42 | setspeed(n,m) 43 | elif mode=='pos': 44 | setpos(n,m) 45 | else: 46 | print "No commands given.\nUsage: servo_ctl_pololu.py speed , or\n servo_ctl_pololu.py pos " 47 | -------------------------------------------------------------------------------- /hardware/servo/servo_ctl_sscii.py: -------------------------------------------------------------------------------- 1 | # Interface to Pololu SSC03A servo controller running in Mini SSC II Mode. 2 | # Based on code from: 3 | # http://dmt195.wordpress.com/2009/01/19/python-to-interface-with-the-pololu-8-channel-servo-controller/ 4 | 5 | import serial 6 | import sys 7 | #set up the serial port for action (0==COM1==ttyS0) 8 | ser=serial.Serial('/dev/ttyUSB0') 9 | ser.baudrate=9600 10 | 11 | def setpos(n,angle): 12 | #Quick check that things are in range 13 | if angle > 180 or angle <0: 14 | angle=90 15 | print "WARNING: Angle range should be between 0 and 180. Setting angle to 90 degrees to be safe..." 16 | print "moving servo "+str(n)+" to "+str(angle)+" degrees." 17 | 18 | byteone=int(254*angle/180) 19 | #move to an absolute position in 8-bit mode (0x04 for the mode, 0 for the servo, 0-255 for the position (spread over two bytes)) 20 | bud=chr(0xFF)+chr(n)+chr(byteone) 21 | ser.write(bud) 22 | 23 | mode=sys.argv[1] 24 | n=int(sys.argv[2]) 25 | m=int(sys.argv[3]) 26 | 27 | if mode=='pos': 28 | setpos(n,m) 29 | else: 30 | print "No commands given.\nUsage: servo_ctl_sscii.py pos " 31 | 32 | -------------------------------------------------------------------------------- /hardware/servo/ssc03a_guide.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/csete/bonecam/d38586b7bf92e955caad061c869cb0efd82048e9/hardware/servo/ssc03a_guide.pdf -------------------------------------------------------------------------------- /legacy/angstrom/README: -------------------------------------------------------------------------------- 1 | A few sketchy instructions for building my "bonecam image". 2 | 3 | Start by checking out the Ångstrom setup scripts according to the instructions here: 4 | http://www.angstrom-distribution.org/building-angstrom 5 | 6 | Perform the config and update from Step 2. 7 | You can now apply my pseudo-patches as follows: 8 | 9 | (1) Copy bonecam-image.bb to sources/meta-ti/recipes-misc/images/ 10 | (2) Copy gst-plugins-bad_0.10.23.bb to sources/openembedded-core/meta/recipes-multimedia/gstreamer/ 11 | 12 | You can now try to build the bonecam-image: 13 | 14 | MACHINE=beaglebone ./oebb.sh bitbake bonecam-image 15 | 16 | I realize these are not the right way to do things; however, until I have time to properly understand Ångstrom and Openembedded they will have to do. 17 | 18 | -------------------------------------------------------------------------------- /legacy/angstrom/bonecam-image.bb: -------------------------------------------------------------------------------- 1 | # Image for bonecam 2 | 3 | require ti-hw-bringup-image.bb 4 | 5 | ROOTFSTYPE_beaglebone = "ext4" 6 | 7 | IMAGE_INSTALL += " \ 8 | systemd-analyze \ 9 | task-sdk-target \ 10 | vim vim-vimrc \ 11 | procps \ 12 | screen \ 13 | minicom \ 14 | git \ 15 | led-config \ 16 | opencv-dev \ 17 | cronie-systemd ntpdate \ 18 | nano \ 19 | gateone \ 20 | tar \ 21 | gdb gdbserver \ 22 | tslib-tests tslib-calibrate \ 23 | iproute2 canutils \ 24 | connman-tests \ 25 | rsync \ 26 | media-ctl yavta \ 27 | v4l-utils \ 28 | gstreamer \ 29 | gst-plugins-base \ 30 | gst-plugins-good \ 31 | gst-plugins-bad \ 32 | " 33 | 34 | export IMAGE_BASENAME = "Bonecam" 35 | 36 | -------------------------------------------------------------------------------- /legacy/angstrom/gst-plugins-bad_0.10.23.bb: -------------------------------------------------------------------------------- 1 | require gst-plugins.inc 2 | 3 | LICENSE = "GPLv2+ & LGPLv2+ & LGPLv2.1+ " 4 | LIC_FILES_CHKSUM = "file://COPYING;md5=0636e73ff0215e8d672dc4c32c317bb3 \ 5 | file://gst/tta/filters.h;beginline=12;endline=29;md5=629b0c7a665d155a6677778f4460ec06 \ 6 | file://COPYING.LIB;md5=55ca817ccb7d5b5b66355690e9abc605 \ 7 | file://gst/tta/crc32.h;beginline=12;endline=29;md5=71a904d99ce7ae0c1cf129891b98145c" 8 | 9 | DEPENDS += "gst-plugins-base libmusicbrainz tremor librsvg curl" 10 | 11 | PR = "r2" 12 | 13 | inherit gettext 14 | 15 | EXTRA_OECONF += "--disable-examples --disable-experimental --disable-sdl --disable-cdaudio --disable-directfb \ 16 | --with-plugins=musicbrainz,wavpack,ivorbis,mpegvideoparse,h264parse --disable-vdpau --disable-apexsink \ 17 | --disable-orc" 18 | 19 | ARM_INSTRUCTION_SET = "arm" 20 | 21 | do_configure_prepend() { 22 | # This m4 file contains nastiness which conflicts with libtool 2.2.2 23 | rm ${S}/m4/lib-link.m4 || true 24 | } 25 | 26 | SRC_URI[md5sum] = "fcb09798114461955260e4d940db5987" 27 | SRC_URI[sha256sum] = "0eae7d1a1357ae8377fded6a1b42e663887beabe0e6cc336e2ef9ada42e11491" 28 | -------------------------------------------------------------------------------- /legacy/camctl/README: -------------------------------------------------------------------------------- 1 | camctl is the command line interface for controlling the camera. This inscludes v4l2 settings as well as pan/tilt/zoom. 2 | 3 | -------------------------------------------------------------------------------- /legacy/camctl/build: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | bld="TARGET" 4 | 5 | if [ $# -eq 1 ] && [ "$1" == "host" ]; then 6 | bld="HOST" 7 | fi 8 | 9 | if [ $bld == "HOST" ]; then 10 | gcc -O2 -Wall `pkg-config --cflags --libs libv4l2` camctl.c -o cam 11 | else 12 | gcc -O2 -Wall -marm -mfloat-abi=softfp `pkg-config --cflags --libs libv4l2` camctl.c -o cam 13 | fi 14 | 15 | -------------------------------------------------------------------------------- /legacy/camctl/camctl.c: -------------------------------------------------------------------------------- 1 | /* Simple bonecam control interface. 2 | * 3 | * Copyright 2012 Alexandru Csete 4 | * 5 | * May be (ab)used under GNU GPL v3 6 | * 7 | */ 8 | 9 | #include 10 | #include 11 | #include 12 | 13 | /* defaults */ 14 | #define DEFAULT_TTY "/dev/ttyO1" 15 | #define DEFAULT_CLIENT "192.168.254.141" 16 | #define DEFAULT_PORT "4000" 17 | #define DEFAULT_WIDTH 1024 18 | #define DEFAULT_HEIGHT 576 19 | #define DEFAULT_FPS 24 20 | 21 | /* servo numbers */ 22 | #define AZI 0 23 | #define ELE 1 24 | 25 | typedef struct _servo_limit { 26 | int min; 27 | int max; 28 | } servo_limit_t; 29 | 30 | static servo_limit_t srv_lim[] = { 31 | { 0, 180}, /* AZI */ 32 | { 60, 130 } /* ELE */ 33 | }; 34 | 35 | typedef struct _v4l2ctl { 36 | char cli; /* camctl cli command */ 37 | char *cmd; /* v4l2-ctl command */ 38 | int min; /* minimum value */ 39 | int max; /* max valiue */ 40 | int step; /* step size */ 41 | int def; /* default value */ 42 | char *cmd_auto; /* command to enable/disable auto mode */ 43 | int cmd_auto_off; /* value that disable auto mode */ 44 | int cmd_auto_on; /* value that enables auto mode */ 45 | } v4l2ctl_t; 46 | 47 | /* C920 command table */ 48 | static v4l2ctl_t ctltab[] = { 49 | { 'b', "brightness", 0, 255, 1, 128, NULL, 0, 0}, 50 | { 'c', "contrast", 0, 255, 1, 128, NULL, 0, 0}, 51 | { 's', "saturation", 0, 255, 1, 128, NULL, 0, 0}, 52 | { 'h', "sharpness", 0, 255, 1, 128, NULL, 0, 0}, 53 | { 'o', "backlight_compensation", 0, 1, 1, 0, NULL, 0, 0}, 54 | { 'l', "power_line_frequency", 0, 2, 1, 1, NULL, 0, 0}, 55 | { 'g', "gain", 0, 255, 1, 0, NULL, 0, 0 }, 56 | { 'x', "exposure_auto_priority", 0, 1, 1, 1, NULL, 0, 0}, 57 | { 'z', "zoom_absolute", 100, 500, 1, 100, NULL, 0, 0}, 58 | { 'w', "white_balance_temperature", 2000, 6500, 1, 4000, "white_balance_temperature_auto", 0, 1}, 59 | { 'f', "focus_absolute", 0, 250, 5, 0, "focus_auto", 0, 1}, 60 | { 'e', "exposure_absolute", 0, 2047, 1, 250, "exposure_auto", 1, 3}, 61 | { 0, NULL, 0, 0, 0, 0, NULL, 0, 0} /* used to find end of array */ 62 | }; 63 | 64 | 65 | #define VIDEO_SERVER_CMD "/home/root/bin/video-server" 66 | 67 | static void init_servos(); 68 | static void init_camera(unsigned int w, unsigned int h, unsigned int fps); 69 | static void start_camera(const char *client, const char *port); 70 | static void stop_camera(); 71 | static void get_camera_ctl(const char *ctl); 72 | static void set_camera_ctl(const char *ctl, int val); 73 | static void set_speed(int servo, int speed); 74 | static void set_angle(int servo, int angle); 75 | static void write_tty(const char *tty, const char *data, int len); 76 | static int chr2idx(char c); 77 | static void show_help(); 78 | 79 | 80 | int main(int argc, char *argv[]) 81 | { 82 | int rc = 0; 83 | int idx = -1; 84 | 85 | 86 | if (argc == 1) 87 | { 88 | show_help(); 89 | return 1; 90 | } 91 | 92 | /* first check whether we have init/start/stop */ 93 | if (!strcmp(argv[1], "init")) 94 | { 95 | int w = DEFAULT_WIDTH; 96 | int h = DEFAULT_HEIGHT; 97 | int fps = DEFAULT_FPS; 98 | 99 | if (argc > 2) 100 | w = atoi(argv[2]); 101 | 102 | if (argc > 3) 103 | h = atoi(argv[3]); 104 | 105 | if (argc > 4) 106 | fps = atoi(argv[4]); 107 | 108 | init_camera(w, h, fps); 109 | init_servos(); 110 | 111 | goto done; 112 | } 113 | else if (!strcmp(argv[1], "start")) 114 | { 115 | switch (argc) 116 | { 117 | case 2: 118 | /* Use default IP and port */ 119 | start_camera(DEFAULT_CLIENT, DEFAULT_PORT); 120 | break; 121 | case 3: 122 | /* IP given; use default port */ 123 | start_camera(argv[2], DEFAULT_PORT); 124 | break; 125 | case 4: 126 | /* both IP and port givem */ 127 | start_camera(argv[2], argv[3]); 128 | break; 129 | default: 130 | show_help(); 131 | break; 132 | } 133 | goto done; 134 | } 135 | else if (!strcmp(argv[1], "stop")) 136 | { 137 | stop_camera(); 138 | goto done; 139 | } 140 | else if (!strcmp(argv[1], "status")) 141 | { 142 | printf("cam status not implemented\n"); 143 | goto done; 144 | } 145 | 146 | /* now check for p, s, m ... commands */ 147 | char *s = argv[1]; 148 | 149 | switch (*s) 150 | { 151 | case 'p': 152 | switch (*++s) 153 | { 154 | case 0: 155 | if (argc < 4) 156 | { 157 | show_help(); 158 | } 159 | else 160 | { 161 | set_angle(AZI, atoi(argv[2])); 162 | set_angle(ELE, atoi(argv[3])); 163 | } 164 | break; 165 | case 'a': 166 | if (argc < 3) 167 | show_help(); 168 | else 169 | set_angle(AZI, atoi(argv[2])); 170 | break; 171 | case 'e': 172 | if (argc < 3) 173 | show_help(); 174 | else 175 | set_angle(ELE, atoi(argv[2])); 176 | break; 177 | default: 178 | show_help(); 179 | goto done; 180 | } 181 | break; 182 | 183 | case 'r': 184 | switch (*++s) 185 | { 186 | case 0: 187 | if (argc < 4) 188 | { 189 | show_help(); 190 | } 191 | else 192 | { 193 | set_speed(AZI, atoi(argv[2])); 194 | set_speed(ELE, atoi(argv[3])); 195 | } 196 | break; 197 | case 'a': 198 | if (argc < 3) 199 | show_help(); 200 | else 201 | set_speed(AZI, atoi(argv[2])); 202 | break; 203 | case 'e': 204 | if (argc < 3) 205 | show_help(); 206 | else 207 | set_speed(ELE, atoi(argv[2])); 208 | break; 209 | default: 210 | show_help(); 211 | goto done; 212 | } 213 | break; 214 | 215 | case 'm': 216 | switch (*++s) 217 | { 218 | case 0: 219 | if (argc < 5) 220 | { 221 | show_help(); 222 | } 223 | else 224 | { 225 | set_speed(AZI, atoi(argv[4])); 226 | set_speed(ELE, atoi(argv[4])); 227 | set_angle(AZI, atoi(argv[2])); 228 | set_angle(ELE, atoi(argv[3])); 229 | } 230 | break; 231 | case 'a': 232 | if (argc < 4) 233 | { 234 | show_help(); 235 | } 236 | else 237 | { 238 | set_speed(AZI, atoi(argv[3])); 239 | set_angle(AZI, atoi(argv[2])); 240 | } 241 | break; 242 | case 'e': 243 | if (argc < 4) 244 | { 245 | show_help(); 246 | } 247 | else 248 | { 249 | set_speed(ELE, atoi(argv[3])); 250 | set_angle(ELE, atoi(argv[2])); 251 | } 252 | break; 253 | default: 254 | show_help(); 255 | goto done; 256 | } 257 | break; 258 | 259 | case 'z': 260 | switch (*++s) 261 | { 262 | case 0: 263 | if (argc < 3) 264 | { 265 | /* read current value */ 266 | get_camera_ctl("zoom_absolute"); 267 | } 268 | else 269 | { 270 | /* set new value */ 271 | int val = atoi(argv[2]); 272 | if ((val >= 100) && (val <= 500)) 273 | set_camera_ctl("zoom_absolute", val); 274 | } 275 | break; 276 | case 'r': 277 | /* reset zoom */ 278 | set_camera_ctl("zoom_absolute", 100); 279 | set_camera_ctl("tilt_absolute", 0); 280 | set_camera_ctl("pan_absolute", 0); 281 | break; 282 | case 'p': 283 | if (argc < 3) 284 | { 285 | /* read current value */ 286 | get_camera_ctl("pan_absolute"); 287 | } 288 | else 289 | { 290 | /* set new value */ 291 | int val = atoi(argv[2]); 292 | if ((val >= -10) && (val <= +10)) 293 | set_camera_ctl("pan_absolute", 3600*val); 294 | } 295 | break; 296 | case 't': 297 | if (argc < 3) 298 | { 299 | /* read current value */ 300 | get_camera_ctl("tilt_absolute"); 301 | } 302 | else 303 | { 304 | /* set new value */ 305 | int val = atoi(argv[2]); 306 | if ((val >= -10) && (val <= +10)) 307 | set_camera_ctl("tilt_absolute", 3600*val); 308 | } 309 | break; 310 | default: 311 | show_help(); 312 | goto done; 313 | } 314 | break; 315 | 316 | /* camera controls listed in ctltab */ 317 | case 'b': 318 | case 'c': 319 | case 's': 320 | case 'h': 321 | case 'o': 322 | case 'l': 323 | case 'g': 324 | case 'x': 325 | case 'w': 326 | case 'f': 327 | case 'e': 328 | idx = chr2idx(*s); 329 | if (idx == -1) 330 | { 331 | printf("Internal error (v4l2ctl: %c idx:-1)\n", *s); 332 | goto done; 333 | } 334 | 335 | switch (*++s) 336 | { 337 | case 'r': 338 | /* if ctl has 'auto' setting set to manual */ 339 | if (ctltab[idx].cmd_auto != NULL) 340 | set_camera_ctl(ctltab[idx].cmd_auto, ctltab[idx].cmd_auto_off); 341 | 342 | /* reset control to its default value */ 343 | set_camera_ctl(ctltab[idx].cmd, ctltab[idx].def); 344 | break; 345 | case 0: 346 | if (argc < 3) 347 | { 348 | /* read current value */ 349 | get_camera_ctl(ctltab[idx].cmd); 350 | if (ctltab[idx].cmd_auto != NULL) 351 | get_camera_ctl(ctltab[idx].cmd_auto); 352 | } 353 | else 354 | { 355 | /* set new value */ 356 | int val = atoi(argv[2]); 357 | if (val == -1) 358 | { 359 | /* use auto setting if we have that */ 360 | if (ctltab[idx].cmd_auto != NULL) 361 | { 362 | set_camera_ctl(ctltab[idx].cmd_auto, ctltab[idx].cmd_auto_on); 363 | } 364 | else 365 | { 366 | printf("Command %s does not have 'auto' setting.\n", 367 | ctltab[idx].cmd); 368 | } 369 | } 370 | else if ((val >= ctltab[idx].min) && (val <= ctltab[idx].max)) 371 | { 372 | /* if cmd has 'auto' setting reset it to manual */ 373 | if (ctltab[idx].cmd_auto != NULL) 374 | set_camera_ctl(ctltab[idx].cmd_auto, ctltab[idx].cmd_auto_off); 375 | 376 | set_camera_ctl(ctltab[idx].cmd, val); 377 | } 378 | } 379 | break; 380 | } 381 | break; 382 | 383 | default: 384 | show_help(); 385 | break; 386 | } 387 | 388 | done: 389 | return rc; 390 | } 391 | 392 | /* Initialise servo interface and controller */ 393 | static void init_servos() 394 | { 395 | int rc; 396 | 397 | /* setup TTY */ 398 | rc = system("echo 20 > /sys/kernel/debug/omap_mux/uart1_rxd"); 399 | rc = system("echo 0 > /sys/kernel/debug/omap_mux/uart1_txd"); 400 | 401 | if (rc) 402 | printf("Error (%d) setting up UART.\n", rc); 403 | 404 | /* set servos to speed 5 */ 405 | set_speed(AZI, 5); 406 | set_speed(ELE, 5); 407 | 408 | /* set angles */ 409 | set_angle(AZI, 90); 410 | set_angle(ELE, 90); 411 | } 412 | 413 | /* Set servo angle */ 414 | static void set_angle(int servo, int angle) 415 | { 416 | char cmd[7]; 417 | int data1=0, data2=0; 418 | 419 | /* clamp angles to current physical limits */ 420 | if (angle > srv_lim[servo].max) 421 | angle = srv_lim[servo].max; 422 | else if (angle < srv_lim[servo].min) 423 | angle = srv_lim[servo].min; 424 | 425 | /* The angle goes from 0 to 180: 426 | 0x00 0x00 - 0 degrees 427 | 0x01 0x00 - 90 degrees 428 | 0x01 0x7F - 180 degrees 429 | */ 430 | if (angle >= 90) 431 | { 432 | data1 = 1; 433 | angle -= 90; 434 | } 435 | data2 = (angle * 127) / 90; 436 | 437 | sprintf(cmd, "%c%c%c%c%c%c", 0x80, 0x01, 0x03, servo, data1, data2); 438 | write_tty(DEFAULT_TTY, cmd, 6); 439 | } 440 | 441 | /* Set servo speed 0..15 */ 442 | static void set_speed(int servo, int speed) 443 | { 444 | char cmd[6]; 445 | sprintf(cmd, "%c%c%c%c%c", 0x80, 0x01, 0x01, servo, speed); 446 | write_tty(DEFAULT_TTY, cmd, 5); 447 | } 448 | 449 | /* Write data to character device. */ 450 | static void write_tty(const char *tty, const char *data, int len) 451 | { 452 | /* note: data must be 0-terminated */ 453 | FILE *fp = fopen(tty, "w"); 454 | 455 | if (!fp) 456 | { 457 | printf("Error opening %s\n", tty); 458 | return; 459 | } 460 | fwrite(data, 1, len, fp); 461 | fclose(fp); 462 | } 463 | 464 | /* Initialise camera to given frame size and frame rate */ 465 | static void init_camera(unsigned int w, unsigned int h, unsigned int fps) 466 | { 467 | int rc; 468 | char cmd[100]; 469 | 470 | printf("Initialising camera to %ux%u @ %u fps\n", w, h, fps); 471 | 472 | /* frame size and format */ 473 | sprintf(cmd,"v4l2-ctl --set-fmt-video=width=%u,height=%u,pixelformat=1", 474 | w, h); 475 | rc = system(cmd); 476 | printf(" Set frame size: %s\n", rc ? "Not ok" : "Ok"); 477 | 478 | /* frame rate */ 479 | sprintf(cmd, "v4l2-ctl --set-parm=%u", fps); 480 | rc = system(cmd); 481 | printf(" Set frame rate: %s\n", rc ? "Not ok" : "Ok"); 482 | 483 | set_camera_ctl("power_line_frequency", 1); 484 | set_camera_ctl("zoom_absolute", 100); 485 | } 486 | 487 | /* satart camera server process */ 488 | static void start_camera(const char *client, const char *port) 489 | { 490 | char cmd[250]; 491 | int rc; 492 | 493 | /* create command that will detach from current PTS */ 494 | sprintf(cmd, "%s %s %s > /dev/null 2>&1 < /dev/null &", 495 | VIDEO_SERVER_CMD, client, port); 496 | 497 | rc = system(cmd); 498 | printf("Start video streaming to %s:%s : %s\n", client, port, 499 | rc ? "Not ok" : "Ok"); 500 | 501 | } 502 | 503 | /* stop camera */ 504 | static void stop_camera() 505 | { 506 | /* This should kill everything */ 507 | int rc = system("pkill capture"); 508 | printf("Stop camera: %s\n", rc ? "Not ok" : "Ok"); 509 | } 510 | 511 | /* Set camera parameter (see v4l2-ctl -l) */ 512 | static void set_camera_ctl(const char *ctl, int val) 513 | { 514 | int rc; 515 | char cmd[100]; 516 | 517 | sprintf(cmd, "v4l2-ctl --set-ctrl=%s=%d", ctl, val); 518 | rc = system(cmd); 519 | printf(" Set camera ctrl (%s=%d): %s\n", 520 | ctl, val,rc ? "Not ok" : "Ok"); 521 | } 522 | 523 | /* Get camera parameter (see v4l2-ctl -l) */ 524 | static void get_camera_ctl(const char *ctl) 525 | { 526 | int rc; 527 | char cmd[100]; 528 | 529 | sprintf(cmd, "v4l2-ctl --get-ctrl=%s", ctl); 530 | rc = system(cmd); 531 | if (rc) 532 | printf("Get camera ctrl (%s): Not ok\n", ctl); 533 | } 534 | 535 | /* Given a character c (cli command) find its corresponding 536 | index in ctltab */ 537 | static int chr2idx(char c) 538 | { 539 | int idx = -1; 540 | int i = 0; 541 | 542 | while (ctltab[i].cli != 0) 543 | { 544 | if (ctltab[i].cli == c) 545 | { 546 | idx = i; 547 | break; 548 | } 549 | i++; 550 | } 551 | 552 | return idx; 553 | } 554 | 555 | /* Show help text. */ 556 | static void show_help() 557 | { 558 | const char *help_msg = { 559 | "Bonecam controller built on " __DATE__ " " __TIME__ "\n" 560 | "\n" 561 | "Usage: cam command ...\n" 562 | "\n" 563 | " cam init [w] [h] [fps] Initialize camera\n" 564 | " cam start [ip] [port] Start streaming\n" 565 | " cam stop Stop streaming\n" 566 | " cam status Show camera status\n" 567 | "\n" 568 | " cam p Set azi and ele angles\n" 569 | " cam pa Set azi angle\n" 570 | " cam pe Set ele angle\n" 571 | "\n" 572 | " cam r Set azi and ele rates\n" 573 | " cam ra Set azi rotation rate\n" 574 | " cam re Set ele rotation rate\n" 575 | "\n" 576 | " cam m Move to pos. (azi,ele) at speed sp\n" 577 | " cam ma Move to azi at speed sp\n" 578 | " cam me Move to ele at speed sp\n" 579 | "\n" 580 | "Get/set image options. Use 'r' to reset (e.g. br, cr, ...):\n" 581 | " cam b [val] Brightness 0..255 (128)\n" 582 | " cam c [val] Contrast 0..255 (128)\n" 583 | " cam s [val] Saturation 0..255 (128)\n" 584 | " cam h [val] Sharpness 0..255 (128)\n" 585 | " cam o [0|1] Backlight compensation {0,1} (0)\n" 586 | " cam l [val] Power line freq. 0..2 (1 ~ 50Hz)\n" 587 | " cam g [val] Gain 0..255 (0)\n" 588 | " cam x [0|1] Exposure auto priority {0,1} (1)\n" 589 | "\n" 590 | "Following commands can be set to 'auto' using val=-1:\n" 591 | " cam w [val] White balance 2000..6500 (4000)\n" 592 | " cam f [val] Focus 0..250 (0)\n" 593 | " cam e [val] Exposure 3..2047 (250)\n" 594 | "\n" 595 | "Digital zoom, pan and tilt:\n" 596 | " cam z [val] Zoom 100 ... 500 (100)\n" 597 | " cam zp [val] Pan -10 ... +10 (0)\n" 598 | " cam zt [val] Tilt -10 ... +10 (0)\n" 599 | " cam zr Reset digital zoom, pan and tilt\n" 600 | "\n" 601 | "Misc video options:\n" 602 | " cam v Video options\n" 603 | " cam vs Set video frame size\n" 604 | " cam vr Set video frame rate for fps.\n" 605 | }; 606 | 607 | printf("%s\n", help_msg); 608 | } 609 | 610 | 611 | -------------------------------------------------------------------------------- /legacy/capture/build: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | gcc -O2 -Wall `pkg-config --cflags --libs libv4l2` capture.c -o capture 4 | 5 | -------------------------------------------------------------------------------- /legacy/capture/capture.c: -------------------------------------------------------------------------------- 1 | /* 2 | * V4L2 video capture example 3 | * 4 | * This program can be used and distributed without restrictions. 5 | * 6 | * This program is provided with the V4L2 API 7 | * see http://linuxtv.org/docs.php for more information 8 | */ 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | #include /* getopt_long() */ 16 | 17 | #include /* low-level i/o */ 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | 26 | #include 27 | 28 | #define CLEAR(x) memset(&(x), 0, sizeof(x)) 29 | 30 | #ifndef V4L2_PIX_FMT_H264 31 | #define V4L2_PIX_FMT_H264 v4l2_fourcc('H', '2', '6', '4') /* H264 with start codes */ 32 | #endif 33 | 34 | enum io_method { 35 | IO_METHOD_READ, 36 | IO_METHOD_MMAP, 37 | IO_METHOD_USERPTR, 38 | }; 39 | 40 | struct buffer { 41 | void *start; 42 | size_t length; 43 | }; 44 | 45 | static char *dev_name; 46 | static enum io_method io = IO_METHOD_MMAP; 47 | static int fd = -1; 48 | struct buffer *buffers; 49 | static unsigned int n_buffers; 50 | static int out_buf; 51 | static int force_format; 52 | static int frame_count = 200; 53 | static int frame_number = 0; 54 | 55 | static void errno_exit(const char *s) 56 | { 57 | fprintf(stderr, "%s error %d, %s\n", s, errno, strerror(errno)); 58 | exit(EXIT_FAILURE); 59 | } 60 | 61 | static int xioctl(int fh, int request, void *arg) 62 | { 63 | int r; 64 | 65 | do { 66 | r = ioctl(fh, request, arg); 67 | } while (-1 == r && EINTR == errno); 68 | 69 | return r; 70 | } 71 | 72 | static void process_image(const void *p, int size) 73 | { 74 | frame_number++; 75 | char filename[15]; 76 | //sprintf(filename, "frame-%d.raw", frame_number); 77 | //FILE *fp=fopen(filename,"wb"); 78 | 79 | if (out_buf==0) 80 | { 81 | /* write to file */ 82 | FILE *fp=fopen("video.raw","ab"); 83 | fwrite(p, size, 1, fp); 84 | fflush(fp); 85 | fclose(fp); 86 | } 87 | else 88 | { 89 | /* write to stdout */ 90 | write(1, p, size); 91 | } 92 | } 93 | 94 | static int read_frame(void) 95 | { 96 | struct v4l2_buffer buf; 97 | unsigned int i; 98 | 99 | switch (io) { 100 | case IO_METHOD_READ: 101 | if (-1 == read(fd, buffers[0].start, buffers[0].length)) { 102 | switch (errno) { 103 | case EAGAIN: 104 | return 0; 105 | 106 | case EIO: 107 | /* Could ignore EIO, see spec. */ 108 | 109 | /* fall through */ 110 | 111 | default: 112 | errno_exit("read"); 113 | } 114 | } 115 | 116 | process_image(buffers[0].start, buffers[0].length); 117 | break; 118 | 119 | case IO_METHOD_MMAP: 120 | CLEAR(buf); 121 | 122 | buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 123 | buf.memory = V4L2_MEMORY_MMAP; 124 | 125 | if (-1 == xioctl(fd, VIDIOC_DQBUF, &buf)) { 126 | switch (errno) { 127 | case EAGAIN: 128 | return 0; 129 | 130 | case EIO: 131 | /* Could ignore EIO, see spec. */ 132 | 133 | /* fall through */ 134 | 135 | default: 136 | errno_exit("VIDIOC_DQBUF"); 137 | } 138 | } 139 | 140 | assert(buf.index < n_buffers); 141 | 142 | process_image(buffers[buf.index].start, buf.bytesused); 143 | 144 | if (-1 == xioctl(fd, VIDIOC_QBUF, &buf)) 145 | errno_exit("VIDIOC_QBUF"); 146 | break; 147 | 148 | case IO_METHOD_USERPTR: 149 | CLEAR(buf); 150 | 151 | buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 152 | buf.memory = V4L2_MEMORY_USERPTR; 153 | 154 | if (-1 == xioctl(fd, VIDIOC_DQBUF, &buf)) { 155 | switch (errno) { 156 | case EAGAIN: 157 | return 0; 158 | 159 | case EIO: 160 | /* Could ignore EIO, see spec. */ 161 | 162 | /* fall through */ 163 | 164 | default: 165 | errno_exit("VIDIOC_DQBUF"); 166 | } 167 | } 168 | 169 | for (i = 0; i < n_buffers; ++i) 170 | if (buf.m.userptr == (unsigned long)buffers[i].start 171 | && buf.length == buffers[i].length) 172 | break; 173 | 174 | assert(i < n_buffers); 175 | 176 | process_image((void *)buf.m.userptr, buf.bytesused); 177 | 178 | if (-1 == xioctl(fd, VIDIOC_QBUF, &buf)) 179 | errno_exit("VIDIOC_QBUF"); 180 | break; 181 | } 182 | 183 | return 1; 184 | } 185 | 186 | static void mainloop(void) 187 | { 188 | unsigned int count; 189 | 190 | count = frame_count; 191 | 192 | while (count-- > 0) { 193 | for (;; ) { 194 | fd_set fds; 195 | struct timeval tv; 196 | int r; 197 | 198 | FD_ZERO(&fds); 199 | FD_SET(fd, &fds); 200 | 201 | /* Timeout. */ 202 | tv.tv_sec = 2; 203 | tv.tv_usec = 0; 204 | 205 | r = select(fd + 1, &fds, NULL, NULL, &tv); 206 | 207 | if (-1 == r) { 208 | if (EINTR == errno) 209 | continue; 210 | errno_exit("select"); 211 | } 212 | 213 | if (0 == r) { 214 | fprintf(stderr, "select timeout\n"); 215 | exit(EXIT_FAILURE); 216 | } 217 | 218 | if (read_frame()) 219 | break; 220 | /* EAGAIN - continue select loop. */ 221 | } 222 | } 223 | } 224 | 225 | static void stop_capturing(void) 226 | { 227 | enum v4l2_buf_type type; 228 | 229 | switch (io) { 230 | case IO_METHOD_READ: 231 | /* Nothing to do. */ 232 | break; 233 | 234 | case IO_METHOD_MMAP: 235 | case IO_METHOD_USERPTR: 236 | type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 237 | if (-1 == xioctl(fd, VIDIOC_STREAMOFF, &type)) 238 | errno_exit("VIDIOC_STREAMOFF"); 239 | break; 240 | } 241 | } 242 | 243 | static void start_capturing(void) 244 | { 245 | unsigned int i; 246 | enum v4l2_buf_type type; 247 | 248 | switch (io) { 249 | case IO_METHOD_READ: 250 | /* Nothing to do. */ 251 | break; 252 | 253 | case IO_METHOD_MMAP: 254 | for (i = 0; i < n_buffers; ++i) { 255 | struct v4l2_buffer buf; 256 | 257 | CLEAR(buf); 258 | buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 259 | buf.memory = V4L2_MEMORY_MMAP; 260 | buf.index = i; 261 | 262 | if (-1 == xioctl(fd, VIDIOC_QBUF, &buf)) 263 | errno_exit("VIDIOC_QBUF"); 264 | } 265 | type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 266 | if (-1 == xioctl(fd, VIDIOC_STREAMON, &type)) 267 | errno_exit("VIDIOC_STREAMON"); 268 | break; 269 | 270 | case IO_METHOD_USERPTR: 271 | for (i = 0; i < n_buffers; ++i) { 272 | struct v4l2_buffer buf; 273 | 274 | CLEAR(buf); 275 | buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 276 | buf.memory = V4L2_MEMORY_USERPTR; 277 | buf.index = i; 278 | buf.m.userptr = (unsigned long)buffers[i].start; 279 | buf.length = buffers[i].length; 280 | 281 | if (-1 == xioctl(fd, VIDIOC_QBUF, &buf)) 282 | errno_exit("VIDIOC_QBUF"); 283 | } 284 | type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 285 | if (-1 == xioctl(fd, VIDIOC_STREAMON, &type)) 286 | errno_exit("VIDIOC_STREAMON"); 287 | break; 288 | } 289 | } 290 | 291 | static void uninit_device(void) 292 | { 293 | unsigned int i; 294 | 295 | switch (io) { 296 | case IO_METHOD_READ: 297 | free(buffers[0].start); 298 | break; 299 | 300 | case IO_METHOD_MMAP: 301 | for (i = 0; i < n_buffers; ++i) 302 | if (-1 == munmap(buffers[i].start, buffers[i].length)) 303 | errno_exit("munmap"); 304 | break; 305 | 306 | case IO_METHOD_USERPTR: 307 | for (i = 0; i < n_buffers; ++i) 308 | free(buffers[i].start); 309 | break; 310 | } 311 | 312 | free(buffers); 313 | } 314 | 315 | static void init_read(unsigned int buffer_size) 316 | { 317 | buffers = calloc(1, sizeof(*buffers)); 318 | 319 | if (!buffers) { 320 | fprintf(stderr, "Out of memory\n"); 321 | exit(EXIT_FAILURE); 322 | } 323 | 324 | buffers[0].length = buffer_size; 325 | buffers[0].start = malloc(buffer_size); 326 | 327 | if (!buffers[0].start) { 328 | fprintf(stderr, "Out of memory\n"); 329 | exit(EXIT_FAILURE); 330 | } 331 | } 332 | 333 | static void init_mmap(void) 334 | { 335 | struct v4l2_requestbuffers req; 336 | 337 | CLEAR(req); 338 | 339 | req.count = 4; 340 | req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 341 | req.memory = V4L2_MEMORY_MMAP; 342 | 343 | if (-1 == xioctl(fd, VIDIOC_REQBUFS, &req)) { 344 | if (EINVAL == errno) { 345 | fprintf(stderr, "%s does not support " 346 | "memory mapping\n", dev_name); 347 | exit(EXIT_FAILURE); 348 | } else { 349 | errno_exit("VIDIOC_REQBUFS"); 350 | } 351 | } 352 | 353 | if (req.count < 2) { 354 | fprintf(stderr, "Insufficient buffer memory on %s\n", 355 | dev_name); 356 | exit(EXIT_FAILURE); 357 | } 358 | 359 | buffers = calloc(req.count, sizeof(*buffers)); 360 | 361 | if (!buffers) { 362 | fprintf(stderr, "Out of memory\n"); 363 | exit(EXIT_FAILURE); 364 | } 365 | 366 | for (n_buffers = 0; n_buffers < req.count; ++n_buffers) { 367 | struct v4l2_buffer buf; 368 | 369 | CLEAR(buf); 370 | 371 | buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 372 | buf.memory = V4L2_MEMORY_MMAP; 373 | buf.index = n_buffers; 374 | 375 | if (-1 == xioctl(fd, VIDIOC_QUERYBUF, &buf)) 376 | errno_exit("VIDIOC_QUERYBUF"); 377 | 378 | buffers[n_buffers].length = buf.length; 379 | buffers[n_buffers].start = 380 | mmap(NULL /* start anywhere */, 381 | buf.length, 382 | PROT_READ | PROT_WRITE /* required */, 383 | MAP_SHARED /* recommended */, 384 | fd, buf.m.offset); 385 | 386 | if (MAP_FAILED == buffers[n_buffers].start) 387 | errno_exit("mmap"); 388 | } 389 | } 390 | 391 | static void init_userp(unsigned int buffer_size) 392 | { 393 | struct v4l2_requestbuffers req; 394 | 395 | CLEAR(req); 396 | 397 | req.count = 4; 398 | req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 399 | req.memory = V4L2_MEMORY_USERPTR; 400 | 401 | if (-1 == xioctl(fd, VIDIOC_REQBUFS, &req)) { 402 | if (EINVAL == errno) { 403 | fprintf(stderr, "%s does not support " 404 | "user pointer i/o\n", dev_name); 405 | exit(EXIT_FAILURE); 406 | } else { 407 | errno_exit("VIDIOC_REQBUFS"); 408 | } 409 | } 410 | 411 | buffers = calloc(4, sizeof(*buffers)); 412 | 413 | if (!buffers) { 414 | fprintf(stderr, "Out of memory\n"); 415 | exit(EXIT_FAILURE); 416 | } 417 | 418 | for (n_buffers = 0; n_buffers < 4; ++n_buffers) { 419 | buffers[n_buffers].length = buffer_size; 420 | buffers[n_buffers].start = malloc(buffer_size); 421 | 422 | if (!buffers[n_buffers].start) { 423 | fprintf(stderr, "Out of memory\n"); 424 | exit(EXIT_FAILURE); 425 | } 426 | } 427 | } 428 | 429 | static void init_device(void) 430 | { 431 | struct v4l2_capability cap; 432 | struct v4l2_cropcap cropcap; 433 | struct v4l2_crop crop; 434 | struct v4l2_format fmt; 435 | unsigned int min; 436 | 437 | if (-1 == xioctl(fd, VIDIOC_QUERYCAP, &cap)) { 438 | if (EINVAL == errno) { 439 | fprintf(stderr, "%s is no V4L2 device\n", 440 | dev_name); 441 | exit(EXIT_FAILURE); 442 | } else { 443 | errno_exit("VIDIOC_QUERYCAP"); 444 | } 445 | } 446 | 447 | if (!(cap.capabilities & V4L2_CAP_VIDEO_CAPTURE)) { 448 | fprintf(stderr, "%s is no video capture device\n", 449 | dev_name); 450 | exit(EXIT_FAILURE); 451 | } 452 | 453 | switch (io) { 454 | case IO_METHOD_READ: 455 | if (!(cap.capabilities & V4L2_CAP_READWRITE)) { 456 | fprintf(stderr, "%s does not support read i/o\n", 457 | dev_name); 458 | exit(EXIT_FAILURE); 459 | } 460 | break; 461 | 462 | case IO_METHOD_MMAP: 463 | case IO_METHOD_USERPTR: 464 | if (!(cap.capabilities & V4L2_CAP_STREAMING)) { 465 | fprintf(stderr, "%s does not support streaming i/o\n", 466 | dev_name); 467 | exit(EXIT_FAILURE); 468 | } 469 | break; 470 | } 471 | 472 | 473 | /* Select video input, video standard and tune here. */ 474 | 475 | 476 | CLEAR(cropcap); 477 | 478 | cropcap.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 479 | 480 | if (0 == xioctl(fd, VIDIOC_CROPCAP, &cropcap)) { 481 | crop.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 482 | crop.c = cropcap.defrect; /* reset to default */ 483 | 484 | if (-1 == xioctl(fd, VIDIOC_S_CROP, &crop)) { 485 | switch (errno) { 486 | case EINVAL: 487 | /* Cropping not supported. */ 488 | break; 489 | default: 490 | /* Errors ignored. */ 491 | break; 492 | } 493 | } 494 | } else { 495 | /* Errors ignored. */ 496 | } 497 | 498 | 499 | CLEAR(fmt); 500 | 501 | fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 502 | if (force_format) { 503 | fprintf(stderr, "Set H264\r\n"); 504 | fmt.fmt.pix.width = 640; //replace 505 | fmt.fmt.pix.height = 480; //replace 506 | fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_H264; //replace 507 | fmt.fmt.pix.field = V4L2_FIELD_ANY; 508 | 509 | if (-1 == xioctl(fd, VIDIOC_S_FMT, &fmt)) 510 | errno_exit("VIDIOC_S_FMT"); 511 | 512 | /* Note VIDIOC_S_FMT may change width and height. */ 513 | } else { 514 | /* Preserve original settings as set by v4l2-ctl for example */ 515 | if (-1 == xioctl(fd, VIDIOC_G_FMT, &fmt)) 516 | errno_exit("VIDIOC_G_FMT"); 517 | } 518 | 519 | /* Buggy driver paranoia. */ 520 | min = fmt.fmt.pix.width * 2; 521 | if (fmt.fmt.pix.bytesperline < min) 522 | fmt.fmt.pix.bytesperline = min; 523 | min = fmt.fmt.pix.bytesperline * fmt.fmt.pix.height; 524 | if (fmt.fmt.pix.sizeimage < min) 525 | fmt.fmt.pix.sizeimage = min; 526 | 527 | switch (io) { 528 | case IO_METHOD_READ: 529 | init_read(fmt.fmt.pix.sizeimage); 530 | break; 531 | 532 | case IO_METHOD_MMAP: 533 | init_mmap(); 534 | break; 535 | 536 | case IO_METHOD_USERPTR: 537 | init_userp(fmt.fmt.pix.sizeimage); 538 | break; 539 | } 540 | } 541 | 542 | static void close_device(void) 543 | { 544 | if (-1 == close(fd)) 545 | errno_exit("close"); 546 | 547 | fd = -1; 548 | } 549 | 550 | static void open_device(void) 551 | { 552 | struct stat st; 553 | 554 | if (-1 == stat(dev_name, &st)) { 555 | fprintf(stderr, "Cannot identify '%s': %d, %s\n", 556 | dev_name, errno, strerror(errno)); 557 | exit(EXIT_FAILURE); 558 | } 559 | 560 | if (!S_ISCHR(st.st_mode)) { 561 | fprintf(stderr, "%s is no device\n", dev_name); 562 | exit(EXIT_FAILURE); 563 | } 564 | 565 | fd = open(dev_name, O_RDWR /* required */ | O_NONBLOCK, 0); 566 | 567 | if (-1 == fd) { 568 | fprintf(stderr, "Cannot open '%s': %d, %s\n", 569 | dev_name, errno, strerror(errno)); 570 | exit(EXIT_FAILURE); 571 | } 572 | } 573 | 574 | static void usage(FILE *fp, int argc, char **argv) 575 | { 576 | fprintf(fp, 577 | "Usage: %s [options]\n\n" 578 | "Version 1.3\n" 579 | "Options:\n" 580 | "-d | --device name Video device name [%s]\n" 581 | "-h | --help Print this message\n" 582 | "-m | --mmap Use memory mapped buffers [default]\n" 583 | "-r | --read Use read() calls\n" 584 | "-u | --userp Use application allocated buffers\n" 585 | "-o | --output Outputs stream to stdout\n" 586 | "-f | --format Force format to 640x480 H264\n" 587 | "-c | --count Number of frames to grab [%i]\n" 588 | "", 589 | argv[0], dev_name, frame_count); 590 | } 591 | 592 | static const char short_options[] = "d:hmruofc:"; 593 | 594 | static const struct option 595 | long_options[] = { 596 | { "device", required_argument, NULL, 'd' }, 597 | { "help", no_argument, NULL, 'h' }, 598 | { "mmap", no_argument, NULL, 'm' }, 599 | { "read", no_argument, NULL, 'r' }, 600 | { "userp", no_argument, NULL, 'u' }, 601 | { "output", no_argument, NULL, 'o' }, 602 | { "format", no_argument, NULL, 'f' }, 603 | { "count", required_argument, NULL, 'c' }, 604 | { 0, 0, 0, 0 } 605 | }; 606 | 607 | int main(int argc, char **argv) 608 | { 609 | dev_name = "/dev/video0"; 610 | 611 | for (;; ) { 612 | int idx; 613 | int c; 614 | 615 | c = getopt_long(argc, argv, 616 | short_options, long_options, &idx); 617 | 618 | if (-1 == c) 619 | break; 620 | 621 | switch (c) { 622 | case 0: /* getopt_long() flag */ 623 | break; 624 | 625 | case 'd': 626 | dev_name = optarg; 627 | break; 628 | 629 | case 'h': 630 | usage(stdout, argc, argv); 631 | exit(EXIT_SUCCESS); 632 | 633 | case 'm': 634 | io = IO_METHOD_MMAP; 635 | break; 636 | 637 | case 'r': 638 | io = IO_METHOD_READ; 639 | break; 640 | 641 | case 'u': 642 | io = IO_METHOD_USERPTR; 643 | break; 644 | 645 | case 'o': 646 | out_buf++; 647 | break; 648 | 649 | case 'f': 650 | force_format++; 651 | break; 652 | 653 | case 'c': 654 | errno = 0; 655 | frame_count = strtol(optarg, NULL, 0); 656 | if (errno) 657 | errno_exit(optarg); 658 | break; 659 | 660 | default: 661 | usage(stderr, argc, argv); 662 | exit(EXIT_FAILURE); 663 | } 664 | } 665 | 666 | open_device(); 667 | init_device(); 668 | start_capturing(); 669 | mainloop(); 670 | stop_capturing(); 671 | uninit_device(); 672 | close_device(); 673 | fprintf(stderr, "\n"); 674 | return 0; 675 | } 676 | -------------------------------------------------------------------------------- /legacy/scripts/bonecam.sdp: -------------------------------------------------------------------------------- 1 | v=0 2 | o=- 1188340656180883 1 IN IP4 127.0.0.1 3 | s=Bonecam streamed by GStreamer 4 | i=bonecam 5 | t=0 0 6 | a=tool:GStreamer 7 | a=type:broadcast 8 | m=video 4000 RTP/AVP 96 9 | c=IN IP4 127.0.0.1 10 | a=rtpmap:96 H264/90000 11 | -------------------------------------------------------------------------------- /legacy/scripts/video-client: -------------------------------------------------------------------------------- 1 | gst-launch -v udpsrc port=4000 caps='application/x-rtp, media=(string)video, clock-rate=(int)90000, encoding-name=(string)H264' ! rtph264depay ! ffdec_h264 ! fpsdisplaysink fps-update-interval=5000 sync=false 2 | 3 | -------------------------------------------------------------------------------- /legacy/scripts/video-server: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | usage () 4 | { 5 | echo "Usage: server " 6 | } 7 | 8 | 9 | if [ $# -ne 2 ]; then 10 | usage 11 | exit 0 12 | fi 13 | 14 | echo "Starting streaming server to $1:$2" 15 | 16 | ../capture/capture -c 10000000 -o | gst-launch -v -e filesrc location=/dev/fd/0 ! legacyh264parse ! rtph264pay ! udpsink host=$1 port=$2 17 | 18 | -------------------------------------------------------------------------------- /legacy/scripts/voip-client: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # 4 | # Play 24 kHz stereo audio streamed from the C920 camera. 5 | # 6 | 7 | usage () 8 | { 9 | echo "Usage: voip-client " 10 | } 11 | 12 | 13 | if [ $# -ne 1 ]; then 14 | usage 15 | exit 0 16 | fi 17 | 18 | # For the 24 kHz stereo, otherwise update with string from server 19 | 20 | gst-launch -v udpsrc port=$1 caps='application/x-rtp, media=(string)audio, clock-rate=(int)24000, encoding-name=(string)VORBIS, encoding-params=(string)2, configuration=(string)\"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\\=\\=\", payload=(int)96' ! rtpvorbisdepay ! vorbisdec ! audioconvert ! alsasink device="plughw:1,0" sync=false 21 | -------------------------------------------------------------------------------- /legacy/scripts/voip-server: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # 4 | # Streams 24 kHz stereo from USB headset. At this rate the Beaglebone 5 | # CPU load will stay at acceptable level. 6 | # 7 | 8 | usage () 9 | { 10 | echo "Usage: voip-server " 11 | } 12 | 13 | 14 | if [ $# -ne 2 ]; then 15 | usage 16 | exit 0 17 | fi 18 | 19 | echo "Starting audio streaming server to $1:$2" 20 | 21 | ## Vorbis encoded audio 22 | gst-launch -v -e alsasrc device="plughw:1,0" ! audio/x-raw-int,signed=true,rate=24000,channels=2 ! audioconvert ! vorbisenc ! rtpvorbispay ! udpsink host=$1 port=$2 23 | 24 | ## Raw audio via tcp 25 | #while true; do 26 | # gst-launch -v -e alsasrc ! audio/x-raw-int,endianness=1234,signed=true,width=16,depth=16,rate=48000,channels=1 ! tcpclientsink host=$1 port=$2 sync=true 27 | # sleep 5 28 | #done 29 | 30 | -------------------------------------------------------------------------------- /legacy/systemd/autostart-voip.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # start server 4 | /home/root/bin/voip-server 192.168.1.100 3002 > /dev/null 2>&1 & 5 | 6 | # start client 7 | exec /home/root/bin/voip-client 3000 > /dev/null 2>&1 8 | -------------------------------------------------------------------------------- /legacy/systemd/bonecam-voip.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=Run the Bonecam intercom client/server 3 | After=network.target multi-user.target 4 | 5 | [Service] 6 | Type=simple 7 | ExecStart=/home/root/bin/autostart-voip.sh 8 | 9 | [Install] 10 | #WantedBy=multi-user.target 11 | 12 | -------------------------------------------------------------------------------- /legacy/vidsrv/build: -------------------------------------------------------------------------------- 1 | gcc -O3 -Wall main.c config.c socket_handler.c video_server.c -o vidsrv \ 2 | $(pkg-config --cflags --libs gstreamer-1.0 gio-2.0) 3 | -------------------------------------------------------------------------------- /legacy/vidsrv/config.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014 Alexandru Csete 3 | * 4 | * All rights reserved. 5 | * 6 | * This Software is released under the "Simplified BSD License", see 7 | * license.txt for details 8 | */ 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include "config.h" 14 | 15 | 16 | static void show_help() 17 | { 18 | static const char *help_message = 19 | "\n" 20 | "Video server options:\n\n" 21 | " -d Camera device. Default is /dev/video0.\n" 22 | " -s Image size in WxH format e.g. 1280x720 (default).\n" 23 | " -f Frames per second. Range 5 - 30. Default is 24.\n" 24 | " -b Bitrate in kilobits / sec. Range 50 - 15000. Default is 3000.\n" 25 | " -i I-frame period in ms. Range 1000 - 60000. Default is 10000.\n" 26 | " -a Hostname or IP address of the mixer. Default is localhost.\n" 27 | " -p UDP port on the mixer number to stream to. Default is 4000.\n" 28 | " -c TCP command port number. Default is 4242.\n" 29 | " -h This help message.\n" 30 | "\n" 31 | "Use v4l2-ctl to set brightness, contrast, focus, etc.\n" 32 | "For example:\n" 33 | " v4l2-ctl --set-ctrl=focus_auto=0\n" 34 | " v4l2-ctl --set-ctrl=focus_absolute=0\n" 35 | "\n" "Use 'v4l2-ctl -l' for a list of supported settings\n"; 36 | 37 | fprintf(stderr, "%s", help_message); 38 | } 39 | 40 | /* Check is requested frame size is supported by C920. 41 | * We only support down to 640x360 42 | */ 43 | static int size_is_ok(guint64 width, guint64 height) 44 | { 45 | int sizeok = 0; 46 | 47 | switch (width) 48 | { 49 | case 1920: 50 | if (height == 1080) 51 | sizeok = 1; 52 | break; 53 | 54 | case 1600: 55 | if (height == 896) 56 | sizeok = 1; 57 | break; 58 | 59 | case 1280: 60 | if (height == 720) 61 | sizeok = 1; 62 | break; 63 | 64 | case 1024: 65 | if (height == 576) 66 | sizeok = 1; 67 | break; 68 | 69 | case 960: 70 | if (height == 720) 71 | sizeok = 1; 72 | break; 73 | 74 | case 864: 75 | if (height == 480) 76 | sizeok = 1; 77 | break; 78 | 79 | case 800: 80 | if (height == 600 || height == 448) 81 | sizeok = 1; 82 | break; 83 | 84 | case 640: 85 | if (height == 360) 86 | sizeok = 1; 87 | break; 88 | 89 | default: 90 | sizeok = 0; 91 | break; 92 | } 93 | 94 | return sizeok; 95 | } 96 | 97 | /* Extract frame size from string in the format 1280x720 */ 98 | void get_frame_size(const gchar * optarg, config_t * conf) 99 | { 100 | gchar **size_vec = g_strsplit(optarg, "x", 0); 101 | 102 | guint64 w = g_ascii_strtoull(size_vec[0], NULL, 0); 103 | guint64 h = g_ascii_strtoull(size_vec[1], NULL, 0); 104 | 105 | if (size_is_ok(w, h)) 106 | { 107 | conf->width = (unsigned int)w; 108 | conf->height = (unsigned int)h; 109 | } 110 | 111 | g_strfreev(size_vec); 112 | } 113 | 114 | unsigned int get_closest_framerate(int val) 115 | { 116 | unsigned int fps = 24; 117 | 118 | if (val < 8) 119 | fps = 5; 120 | else if (val < 13) 121 | fps = 10; 122 | else if (val < 18) 123 | fps = 15; 124 | else if (val < 22) 125 | fps = 20; 126 | else if (val < 27) 127 | fps = 24; 128 | else if (val < 33) 129 | fps = 30; 130 | 131 | return fps; 132 | } 133 | 134 | config_t *config_create(int argc, char *argv[]) 135 | { 136 | config_t *conf = malloc(sizeof(config_t)); 137 | 138 | /* add sensible defaults */ 139 | conf->device = g_strdup("/dev/video0"); 140 | conf->width = 1280; 141 | conf->height = 720; 142 | conf->framerate = 24; 143 | conf->bitrate = 3000; 144 | conf->iframe_period = 10000; 145 | conf->udp_host = g_strdup("localhost"); 146 | conf->udp_port = 4000; 147 | conf->cmd_port = 4242; 148 | 149 | /* parse command line options */ 150 | int opt, val; 151 | 152 | while ((opt = getopt(argc, argv, "d:s:f:b:i:a:p:h")) != -1) 153 | { 154 | switch (opt) 155 | { 156 | case 'd': 157 | g_free(conf->device); 158 | conf->device = g_strdup(optarg); 159 | break; 160 | case 's': 161 | get_frame_size(optarg, conf); 162 | break; 163 | case 'f': 164 | val = atoi(optarg); 165 | conf->framerate = get_closest_framerate(val); 166 | break; 167 | case 'b': 168 | val = atoi(optarg); 169 | if (val >= 50 && val <= 15000) 170 | conf->bitrate = val; 171 | else 172 | goto help; 173 | break; 174 | case 'i': 175 | val = atoi(optarg); 176 | if (val >= 1000 && val <= 60000) 177 | conf->iframe_period = val; 178 | else 179 | goto help; 180 | break; 181 | case 'a': 182 | g_free(conf->udp_host); 183 | conf->udp_host = g_strdup(optarg); 184 | break; 185 | case 'p': 186 | val = atoi(optarg); 187 | if (val >= 0 && val <= 65535) 188 | conf->udp_port = val; 189 | else 190 | goto help; 191 | break; 192 | case 'c': 193 | val = atoi(optarg); 194 | if (val >= 0 && val <= 65535) 195 | conf->cmd_port = val; 196 | else 197 | goto help; 198 | case 'h': 199 | goto help; 200 | break; 201 | default: 202 | break; 203 | } 204 | } 205 | 206 | return conf; 207 | 208 | help: 209 | show_help(); 210 | config_destroy(conf); 211 | exit(EXIT_FAILURE); 212 | } 213 | 214 | 215 | void config_destroy(config_t * conf) 216 | { 217 | if (conf->device != NULL) 218 | g_free(conf->device); 219 | 220 | if (conf->udp_host != NULL) 221 | g_free(conf->udp_host); 222 | 223 | free(conf); 224 | conf = NULL; 225 | } 226 | -------------------------------------------------------------------------------- /legacy/vidsrv/config.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014 Alexandru Csete 3 | * 4 | * All rights reserved. 5 | * 6 | * This Software is released under the "Simplified BSD License", see 7 | * license.txt for details 8 | */ 9 | #ifndef CONFIG_H 10 | #define CONFIG_H 11 | 12 | #include 13 | 14 | typedef struct { 15 | /* camera settings */ 16 | gchar *device; 17 | unsigned int width; /* pixels */ 18 | unsigned int height; /* pixels */ 19 | unsigned int framerate; /* frames / second */ 20 | unsigned int bitrate; /* kilobits / second */ 21 | unsigned int iframe_period; /* keyframe period in milliseconds. */ 22 | 23 | /* network settings */ 24 | gchar *udp_host; 25 | unsigned int udp_port; 26 | unsigned int cmd_port; 27 | } config_t; 28 | 29 | 30 | config_t *config_create(int argc, char *argv[]); 31 | void config_destroy(config_t * conf); 32 | 33 | void get_frame_size(const gchar * optarg, config_t * conf); 34 | unsigned int get_closest_framerate(int val); 35 | 36 | #endif 37 | -------------------------------------------------------------------------------- /legacy/vidsrv/license.txt: -------------------------------------------------------------------------------- 1 | Bonecam vidsrv is written by Alexandru Csete and is licensed under the 2 | Simplified BSD License. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are met: 6 | 7 | 1. Redistributions of source code must retain the above copyright notice, this 8 | list of conditions and the following disclaimer. 9 | 2. Redistributions in binary form must reproduce the above copyright notice, 10 | this list of conditions and the following disclaimer in the documentation 11 | and/or other materials provided with the distribution. 12 | 13 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 14 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 15 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 16 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 17 | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 18 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 19 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 20 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 21 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 22 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 23 | 24 | The views and conclusions contained in the software and documentation are those 25 | of the authors and should not be interpreted as representing official policies, 26 | either expressed or implied, of the project. 27 | -------------------------------------------------------------------------------- /legacy/vidsrv/main.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014 Alexandru Csete 3 | * 4 | * All rights reserved. 5 | * 6 | * This Software is released under the "Simplified BSD License", see 7 | * license.txt for details 8 | */ 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | #include "config.h" 15 | #include "socket_handler.h" 16 | #include "video_server.h" 17 | 18 | 19 | /* callback to manage GST messages on D-BUS */ 20 | static gboolean bus_cb(GstBus * bus, GstMessage * msg, gpointer data) 21 | { 22 | GError *error; 23 | gchar *debug; 24 | GMainLoop *loop = (GMainLoop *) data; 25 | 26 | switch (GST_MESSAGE_TYPE(msg)) 27 | { 28 | case GST_MESSAGE_EOS: 29 | g_print("End of stream\n"); 30 | g_main_loop_quit(loop); 31 | break; 32 | 33 | case GST_MESSAGE_ERROR: 34 | gst_message_parse_error(msg, &error, &debug); 35 | g_free(debug); 36 | 37 | g_printerr("Error: %s\n", error->message); 38 | g_error_free(error); 39 | 40 | g_main_loop_quit(loop); 41 | break; 42 | 43 | default: 44 | break; 45 | } 46 | 47 | return TRUE; 48 | } 49 | 50 | 51 | /* unix signal handler */ 52 | static gboolean signal_handler(gpointer data) 53 | { 54 | fprintf(stderr, "Received termination signal\n"); 55 | g_main_loop_quit((GMainLoop *) data); 56 | 57 | return FALSE; 58 | } 59 | 60 | 61 | int main(int argc, char *argv[]) 62 | { 63 | GMainLoop *main_loop; 64 | GSocketService *socket; 65 | GError *error = NULL; 66 | 67 | GstBus *bus; 68 | guint bus_watch_id; 69 | 70 | config_t *conf; 71 | video_server_t *server; 72 | 73 | guint major = glib_major_version; 74 | guint minor = glib_minor_version; 75 | guint micro = glib_micro_version; 76 | guint nano = 0; 77 | 78 | fprintf(stderr, "Glib version %d.%d.%d\n", major, minor, micro); 79 | 80 | /* initialise gsatreamer */ 81 | gst_init(&argc, &argv); 82 | gst_version(&major, &minor, µ, &nano); 83 | fprintf(stderr, "GStreamer version %d.%d.%d (%d)\n", 84 | major, minor, micro, nano); 85 | 86 | conf = config_create(argc, argv); 87 | server = video_server_create(conf); 88 | main_loop = g_main_loop_new(NULL, FALSE); 89 | g_unix_signal_add(SIGHUP, signal_handler, main_loop); 90 | g_unix_signal_add(SIGTERM, signal_handler, main_loop); 91 | g_unix_signal_add(SIGINT, signal_handler, main_loop); 92 | 93 | /* Message handler */ 94 | bus = gst_pipeline_get_bus(GST_PIPELINE(server->pipeline)); 95 | bus_watch_id = gst_bus_add_watch(bus, bus_cb, main_loop); 96 | gst_object_unref(bus); 97 | 98 | /* command socket */ 99 | socket = g_socket_service_new(); 100 | g_socket_listener_add_inet_port((GSocketListener *) socket, 101 | conf->cmd_port, NULL, &error); 102 | if (error != NULL) 103 | fprintf(stderr, "%s\n", error->message); 104 | 105 | g_signal_connect(socket, "incoming", G_CALLBACK(socket_callback), server); 106 | g_socket_service_start(socket); 107 | 108 | /* Set the pipeline to "playing" state */ 109 | fprintf(stderr, "Video server playing\n"); 110 | gst_element_set_state(server->pipeline, GST_STATE_PLAYING); 111 | 112 | /* Iterate */ 113 | fprintf(stderr, "Running...\n"); 114 | g_main_loop_run(main_loop); 115 | 116 | 117 | /* Stop */ 118 | fprintf(stderr, "Stopping video server\n"); 119 | gst_element_set_state(server->pipeline, GST_STATE_NULL); 120 | 121 | fprintf(stderr, "Deleting pipeline\n"); 122 | 123 | video_server_delete(server); 124 | 125 | g_source_remove(bus_watch_id); 126 | g_main_loop_unref(main_loop); 127 | 128 | return 0; 129 | } 130 | -------------------------------------------------------------------------------- /legacy/vidsrv/readme.txt: -------------------------------------------------------------------------------- 1 | Vidsrv is a simple Gstreamer 1.2 application to capture H.264 video from a 2 | Logitech C920 camera and stream it to a network host using RTP/UDP. 3 | 4 | The following command line options are available: 5 | 6 | -d Camera device. Default is /dev/video0. 7 | -s Image size in WxH format e.g. 1280x720 (default). 8 | -f Frames per second. Range 5 - 30. Default is 24. 9 | -b Bitrate in kilobits / sec. Range 50 - 15000. Default is 3000. 10 | -i I-frame period in ms. Range 1000 - 60000. Default is 10000. 11 | -a Hostname or IP address of the mixer. Default is localhost. 12 | -p UDP port on the mixer number to stream to. Default is 4000. 13 | -c TCP command port number. Default is 4242. 14 | -h This help message. 15 | 16 | Other settings such as contrast or brightness can be adsjusted using the 17 | v4l2-ctl application. 18 | 19 | When the application is running, you can adjust some parameters by sending 20 | simple test commands over TCP to the command port, e.g. by using netcat. 21 | Following commands are savaialble: 22 | 23 | "b 5000" set bitrate to 5 Mbps 24 | "i 3000" set I-frame interval in msec 25 | "f 30" set framerate in frames/sec 26 | "s 640x360" set frame size 27 | 28 | Supported frame sizes: 1920x1080, 1600x896, 1280x720, 1024x576, 960x720, 29 | 864x480, 800x600, 800x448 and 640x360. 30 | 31 | All resolutions support frame rates: 5, 10, 15, 20, 24, 30. 32 | -------------------------------------------------------------------------------- /legacy/vidsrv/socket_handler.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014 Alexandru Csete 3 | * 4 | * All rights reserved. 5 | * 6 | * This Software is released under the "Simplified BSD License", see 7 | * license.txt for details 8 | */ 9 | #include 10 | #include 11 | #include "socket_handler.h" 12 | #include "video_server.h" 13 | 14 | 15 | /* command socket callback */ 16 | gboolean socket_callback(GSocketService * service, GSocketConnection * conn, 17 | GObject * source_object, gpointer user_data) 18 | { 19 | video_server_t *server = (video_server_t *) user_data; 20 | gchar message[128]; 21 | guint64 value; 22 | 23 | GInputStream *istream = g_io_stream_get_input_stream(G_IO_STREAM(conn)); 24 | 25 | g_input_stream_read(istream, message, 128, NULL, NULL); 26 | 27 | /* Supported commands: 28 | * 29 | * "b 5000" set bitrate to 5 Mbps 30 | * "i 3000" set I-frame interval in msec 31 | * "f 30" set framerate in frames/sec 32 | * "s 640x360" set frame size 33 | */ 34 | gchar **cmd_str = g_strsplit(message, " ", 0); 35 | 36 | if (g_strv_length(cmd_str) != 2) 37 | { 38 | fprintf(stderr, "Incorrect command syntax: %s", message); 39 | return FALSE; 40 | } 41 | 42 | switch (cmd_str[0][0]) 43 | { 44 | case 'b': 45 | value = g_ascii_strtoull(cmd_str[1], NULL, 0); 46 | video_server_set_bitrate(server, (unsigned int)value); 47 | break; 48 | case 'i': 49 | value = g_ascii_strtoull(cmd_str[1], NULL, 0); 50 | video_server_set_iframe_period(server, (unsigned int)value); 51 | break; 52 | case 'f': 53 | value = g_ascii_strtoull(cmd_str[1], NULL, 0); 54 | video_server_set_framerate(server, (unsigned int)value); 55 | break; 56 | case 's': 57 | get_frame_size(cmd_str[1], server->conf); 58 | video_server_reset_frame_size(server); 59 | break; 60 | } 61 | 62 | g_strfreev(cmd_str); 63 | 64 | return FALSE; 65 | } 66 | -------------------------------------------------------------------------------- /legacy/vidsrv/socket_handler.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014 Alexandru Csete 3 | * 4 | * All rights reserved. 5 | * 6 | * This Software is released under the "Simplified BSD License", see 7 | * license.txt for details 8 | */ 9 | #ifndef SOCKET_HANDLER_H 10 | #define SOCKET_HANDLER_H 11 | 12 | #include 13 | 14 | gboolean socket_callback(GSocketService * service, 15 | GSocketConnection * connection, 16 | GObject * source_object, gpointer user_data); 17 | 18 | #endif 19 | -------------------------------------------------------------------------------- /legacy/vidsrv/video_server.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014 Alexandru Csete 3 | * 4 | * All rights reserved. 5 | * 6 | * This Software is released under the "Simplified BSD License", see 7 | * license.txt for details 8 | */ 9 | #include 10 | #include 11 | #include 12 | #include "video_server.h" 13 | 14 | 15 | /* Creates the uvch264src element */ 16 | static void create_input_source(video_server_t * server, const config_t * conf) 17 | { 18 | server->source = gst_element_factory_make("uvch264src", "video-source"); 19 | 20 | if (!server->source) 21 | return; 22 | 23 | if (conf->device != NULL) 24 | g_object_set(G_OBJECT(server->source), "device", conf->device, NULL); 25 | 26 | /* bitrate and I-frame interval */ 27 | g_object_set(G_OBJECT(server->source), 28 | "initial-bitrate", 1000 * conf->bitrate, 29 | "average-bitrate", 1000 * conf->bitrate, 30 | "iframe-period", conf->iframe_period, NULL); 31 | 32 | /* misc settings */ 33 | g_object_set(G_OBJECT(server->source), "auto-start", TRUE, NULL); 34 | 35 | } 36 | 37 | /* Creates the UDP sink */ 38 | static void create_udp_sink(video_server_t * server, const config_t * conf) 39 | { 40 | server->udpsink = gst_element_factory_make("udpsink", "video-udpsink"); 41 | if (conf->udp_host != NULL) 42 | g_object_set(G_OBJECT(server->udpsink), 43 | "host", conf->udp_host, "port", conf->udp_port, NULL); 44 | else 45 | g_object_set(G_OBJECT(server->udpsink), 46 | "host", "localhost", "port", conf->udp_port, NULL); 47 | } 48 | 49 | static void create_h264_caps(video_server_t * server, const config_t * conf) 50 | { 51 | server->h264caps = gst_caps_new_simple("video/x-h264", 52 | "width", G_TYPE_INT, conf->width, 53 | "height", G_TYPE_INT, conf->height, 54 | "framerate", GST_TYPE_FRACTION, 55 | conf->framerate, 1, NULL); 56 | } 57 | 58 | video_server_t *video_server_create(config_t * conf) 59 | { 60 | video_server_t *server = (video_server_t *) malloc(sizeof(video_server_t)); 61 | 62 | 63 | /* Create gstreamer elements */ 64 | server->pipeline = gst_pipeline_new("bonecam-video"); 65 | 66 | create_input_source(server, conf); 67 | create_h264_caps(server, conf); 68 | 69 | server->vqueue = gst_element_factory_make("queue", "video-queue"); 70 | server->parser = gst_element_factory_make("h264parse", "video-parser"); 71 | server->payloader = gst_element_factory_make("rtph264pay", "video-rtppay"); 72 | 73 | create_udp_sink(server, conf); 74 | 75 | 76 | if (!server->pipeline || !server->source || !server->parser || 77 | !server->vqueue || !server->payloader || !server->udpsink) 78 | { 79 | fprintf(stderr, "%s: At least one element could not be created.\n", 80 | __func__); 81 | } 82 | 83 | /* Add elements to pipeline */ 84 | gst_bin_add_many(GST_BIN(server->pipeline), 85 | server->source, server->vqueue, server->parser, 86 | server->payloader, server->udpsink, NULL); 87 | 88 | /* Link elements */ 89 | gst_element_link_pads(server->source, "vidsrc", server->vqueue, "sink"); 90 | 91 | if (!gst_element_link_filtered(server->vqueue, 92 | server->parser, server->h264caps)) 93 | { 94 | fprintf(stderr, "%s: Failed to link elements\n", __func__); 95 | } 96 | 97 | gst_caps_unref(server->h264caps); 98 | 99 | if (!gst_element_link_many(server->parser, server->payloader, 100 | server->udpsink, NULL)) 101 | fprintf(stderr, "%s: Failed to link elements\n", __func__); 102 | 103 | /* keep reference to config */ 104 | server->conf = conf; 105 | 106 | return server; 107 | } 108 | 109 | 110 | void video_server_delete(video_server_t * server) 111 | { 112 | /* FIXME: Does this unref child elements? */ 113 | gst_object_unref(GST_OBJECT(server->pipeline)); 114 | 115 | g_free(server); 116 | } 117 | 118 | void video_server_set_bitrate(video_server_t * server, unsigned int value) 119 | { 120 | if (value >= 50 && value <= 15000) 121 | { 122 | fprintf(stderr, "New video bitrate: %d kbps\n", value); 123 | server->conf->bitrate = value; 124 | g_object_set(G_OBJECT(server->source), 125 | "initial-bitrate", 1000 * value, 126 | "average-bitrate", 1000 * value, NULL); 127 | } 128 | } 129 | 130 | void video_server_set_iframe_period(video_server_t * server, 131 | unsigned int value) 132 | { 133 | if (value >= 1000 && value <= 60000) 134 | { 135 | server->conf->iframe_period = value; 136 | fprintf(stderr, "Video server playing -> ready\n"); 137 | gst_element_set_state(server->pipeline, GST_STATE_READY); 138 | fprintf(stderr, "New video I-frame period: %d ms\n", value); 139 | g_object_set(G_OBJECT(server->source), 140 | "initial-bitrate", 1000 * server->conf->bitrate, 141 | "average-bitrate", 1000 * server->conf->bitrate, 142 | "iframe-period", value, NULL); 143 | fprintf(stderr, "Video server ready -> playing\n"); 144 | gst_element_set_state(server->pipeline, GST_STATE_PLAYING); 145 | } 146 | } 147 | 148 | void video_server_set_framerate(video_server_t * server, unsigned int value) 149 | { 150 | server->conf->framerate = get_closest_framerate(value); 151 | 152 | fprintf(stderr, "Video server playing -> ready\n"); 153 | gst_element_set_state(server->pipeline, GST_STATE_READY); 154 | fprintf(stderr, "New video framerate: %d fps\n", server->conf->framerate); 155 | gst_caps_set_simple(GST_CAPS(server->h264caps), 156 | "framerate", GST_TYPE_FRACTION, 157 | server->conf->framerate, 1, NULL); 158 | fprintf(stderr, "Video server ready -> playing\n"); 159 | gst_element_set_state(server->pipeline, GST_STATE_PLAYING); 160 | 161 | } 162 | 163 | /* reset video frame size to what is stored in server->conf */ 164 | void video_server_reset_frame_size(video_server_t * server) 165 | { 166 | fprintf(stderr, "Video server playing -> ready\n"); 167 | gst_element_set_state(server->pipeline, GST_STATE_READY); 168 | fprintf(stderr, "New video frame size: %dx%d\n", 169 | server->conf->width, server->conf->height); 170 | gst_caps_set_simple(GST_CAPS(server->h264caps), 171 | "width", G_TYPE_INT, server->conf->width, 172 | "height", G_TYPE_INT, server->conf->height, NULL); 173 | fprintf(stderr, "Video server ready -> playing\n"); 174 | gst_element_set_state(server->pipeline, GST_STATE_PLAYING); 175 | } 176 | -------------------------------------------------------------------------------- /legacy/vidsrv/video_server.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014 Alexandru Csete 3 | * 4 | * All rights reserved. 5 | * 6 | * This Software is released under the "Simplified BSD License", see 7 | * license.txt for details 8 | */ 9 | #ifndef VIDEO_SERVER_H 10 | #define VIDEO_SERVER_H 11 | 12 | #include 13 | #include "config.h" 14 | 15 | typedef struct { 16 | config_t *conf; 17 | GstElement *pipeline; 18 | GstElement *source; 19 | GstElement *vqueue; 20 | GstElement *parser; 21 | GstElement *payloader; 22 | GstElement *udpsink; 23 | GstCaps *h264caps; 24 | } video_server_t; 25 | 26 | 27 | video_server_t *video_server_create(config_t * conf); 28 | void video_server_delete(video_server_t * server); 29 | void video_server_set_bitrate(video_server_t * server, 30 | unsigned int value); 31 | void video_server_set_iframe_period(video_server_t * server, 32 | unsigned int value); 33 | void video_server_set_framerate(video_server_t * server, 34 | unsigned int value); 35 | void video_server_reset_frame_size(video_server_t * server); 36 | 37 | #endif 38 | -------------------------------------------------------------------------------- /readme.txt: -------------------------------------------------------------------------------- 1 | IP camera based on Logitech webcam, Beaglebone and gstreamer. 2 | 3 | The present v2.1 uses uvch264src for C920 video and works with recent 4 | Beaglebone Debian images and gstreamer 1.4 or later compiled from source 5 | or installed from a Debian testing repository, see for example: 6 | http://www.oz9aec.net/index.php/beaglebone/505-gstreamer-14-on-the-beaglebone. 7 | 8 | The gstreamer and systemd scripts assume that gstreamer has been 9 | installed from source using /opt/bonecam/ prefix. 10 | 11 | 12 | You can still get the old v1.1 image developed in 2012 for the original 13 | Beaglebone running Ångstom by checking out the v1.1 tag. 14 | 15 | -------------------------------------------------------------------------------- /server/audiosrv.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Streams 44.1 kHz mono, vorbis encoded audio. 4 | # CPU load ~ 50%. 5 | # CPU load could be reduced by using the native sample rate of the card. 6 | # 7 | # Otherwise one can use raw audio through TCP connection which uses low CPU 8 | # but high bitrate. 9 | # 10 | # NB: Check the audio device number before running the script! 11 | # 12 | 13 | usage () 14 | { 15 | echo "Usage: audiosrv " 16 | } 17 | 18 | 19 | if [ $# -ne 2 ]; then 20 | usage 21 | exit 0 22 | fi 23 | 24 | echo "Starting audio streaming server to $1:$2" 25 | 26 | ## Opus encoded audio (C920 does 1 channel 32 kHz) 27 | /opt/bonecam/bin/gst-launch-1.0 -v -e alsasrc device="plughw:1" ! \ 28 | audio/x-raw, format=\(string\)S16LE, rate=32000, channels=1 ! \ 29 | audioresample ! \ 30 | audio/x-raw, format=\(string\)S16LE, rate=48000, channels=1 ! \ 31 | opusenc bandwidth=1103 bitrate=32000 frame-size=40 complexity=3 ! \ 32 | rtpopuspay ! udpsink host=$1 port=$2 33 | 34 | ## Vorbis encoded audio 35 | #/opt/bonecam/bin/gst-launch-1.0 -v -e alsasrc device="plughw:1" ! \ 36 | # audio/x-raw,format=\(string\)S16LE,rate=44100,channels=1 ! \ 37 | # audioconvert ! vorbisenc ! rtpvorbispay ! udpsink host=$1 port=$2 38 | 39 | -------------------------------------------------------------------------------- /server/videosrv.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Streams H.264 encoded video iver RTP/UDP. 4 | # CPU load on BBB < 10%. 5 | 6 | usage () 7 | { 8 | echo "Usage: vidsrv " 9 | } 10 | 11 | 12 | if [ $# -ne 2 ]; then 13 | usage 14 | exit 0 15 | fi 16 | 17 | echo "Starting video streaming server to $1:$2" 18 | 19 | # Logitech C920 20 | /opt/bonecam/bin/gst-launch-1.0 -v -e \ 21 | uvch264src initial-bitrate=3000000 average-bitrate=3000000 \ 22 | iframe-period=5000 device=/dev/video0 name=src auto-start=true src.vidsrc ! \ 23 | video/x-h264,width=1280,height=720,framerate=30/1 ! h264parse ! \ 24 | rtph264pay ! udpsink host=$1 port=$2 25 | 26 | # Haupauge HD-PVR 27 | #cat /dev/video0 | /opt/bonecam/bin/gst-launch-1.0 -v -e fdsrc fd=0 ! \ 28 | # tsparse ! tsdemux ! h264parse ! rtph264pay ! \ 29 | # tee name=t1 ! queue ! udpsink host=192.168.10.50 port=9056 \ 30 | # t1. ! queue ! udpsink host=192.168.10.52 port=9056 31 | 32 | -------------------------------------------------------------------------------- /systemd/bonecam-app.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=Bonecam A/V server 3 | After=network-online.target 4 | 5 | [Service] 6 | Type=simple 7 | ExecStart=/opt/bonecam/bin/bonecam-app.sh 8 | StandardOutput=syslog 9 | StandardError=syslog 10 | SyslogIdentifier=bonecam 11 | Restart=on-failure 12 | RestartSec=10 13 | 14 | [Install] 15 | WantedBy=multi-user.target 16 | -------------------------------------------------------------------------------- /systemd/bonecam-app.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | DEST=192.168.1.1 4 | VPORT=40000 5 | APORT=41000 6 | 7 | # start video server 8 | /opt/bonecam/bin/videosrv.sh $DEST $VPORT & 9 | # NB: Remove the trailing "&" above if the audio is disabled 10 | 11 | # start audio 12 | exec /opt/bonecam/bin/audiosrv.sh $DEST $APORT 13 | 14 | -------------------------------------------------------------------------------- /systemd/readme.txt: -------------------------------------------------------------------------------- 1 | Systemd files to start the camera software automatically. 2 | 3 | Assuming that the vidsrv and audiosrv applications are located in 4 | /opt/bonecam/bin/ 5 | 6 | Copy bonecam-app.sh to /opt/bonecam/bin/ 7 | Copy bonecam-app.service to /etc/systemd/system/ 8 | 9 | Reload the systemd service database: 10 | 11 | systemctl daemon-reload 12 | 13 | You can now use: 14 | systemctl start bonecam-app.service 15 | systemctl stop bonecam-app.service 16 | systemctl enable bonecam-app.service 17 | systemctl disable bonecam-app.service 18 | 19 | Enabling the service wil lensure that it is started automatically at boot. 20 | Disabling it will prevent the service to be started at boot. 21 | --------------------------------------------------------------------------------