kerberos-io / machinery

(DEPRECATED) An open source image processing framework, which uses your USB-, IP- or RPi-camera to recognize events (e.g. motion).
https://www.kerberos.io
490 stars 104 forks source link

VideoCapture and USBCamera segfault: "terminate called after throwing an instance of 'std::out_of_range'" #111

Open chrbayer84 opened 6 years ago

chrbayer84 commented 6 years ago

I installed kerberosio v2.3.0 machinery on Armbian but it segfaults on startup:

# kerberosio
16/11/2017 23:06:08.476 INFO  [trivial] Logging is written to: /etc/opt/kerberosio/logs/log.stash
16/11/2017 23:06:08.477 INFO  [trivial] Parameters passed from commandline:
16/11/2017 23:06:08.501 INFO  [trivial] Reading configuration file: /etc/opt/kerberosio/config/config.xml
16/11/2017 23:06:08.515 INFO  [trivial] Final configuration:
- algorithm = DifferentialCollins
- algorithms.BackgroundSubtraction.dilate = 7
- algorithms.BackgroundSubtraction.erode = 5
- algorithms.BackgroundSubtraction.history = 15
- algorithms.BackgroundSubtraction.nmixtures = 5
- algorithms.BackgroundSubtraction.ratio = 1
- algorithms.BackgroundSubtraction.shadows = false
- algorithms.BackgroundSubtraction.threshold = 10
- algorithms.DifferentialCollins.erode = 5
- algorithms.DifferentialCollins.threshold = 15
- capture = VideoCapture
- captures.IPCamera.angle = 0
- captures.IPCamera.delay = 500
- captures.IPCamera.frameHeight = 720
- captures.IPCamera.frameWidth = 960
- captures.IPCamera.url = rtsp://admin:888888@192.168.0.13/tcp/av0_1
- captures.RaspiCamera.angle = 0
- captures.RaspiCamera.brightness = 50
- captures.RaspiCamera.contrast = 0
- captures.RaspiCamera.delay = 500
- captures.RaspiCamera.frameHeight = 480
- captures.RaspiCamera.frameWidth = 640
- captures.RaspiCamera.framerate = 20
- captures.RaspiCamera.saturation = 0
- captures.RaspiCamera.sharpness = 0
- captures.USBCamera.angle = 0
- captures.USBCamera.delay = 500
- captures.USBCamera.deviceNumber = 0
- captures.USBCamera.frameHeight = 720
- captures.USBCamera.frameWidth = 960
- captures.VideoCapture.angle = 0
- captures.VideoCapture.delay = 500
- captures.VideoCapture.frameHeight = 720
- captures.VideoCapture.frameWidth = 960
- captures.VideoCapture.path = /dev/video0
- cloud = S3
- clouds.S3.bucket =
- clouds.S3.folder =
- clouds.S3.privateKey =
- clouds.S3.publicKey =
- condition = Enabled
- conditions.Enabled.active = true
- conditions.Enabled.delay = 5000
- conditions.Time.delay = 10000
- conditions.Time.times = 0:01,23:59-0:01,23:59-0:01,23:59-0:01,23:59-0:01,23:59-0:01,23:59-0:01,23:59
- configuration = /etc/opt/kerberosio/config/config.xml
- expositor = Hull
- expositors.Hull.region = 779,588|781,28|588,48|377,31|208,63|32,45|33,625|191,591|347,600|456,572|556,601|659,629
- expositors.Rectangle.region.x1 = 0
- expositors.Rectangle.region.x2 = 800
- expositors.Rectangle.region.y1 = 0
- expositors.Rectangle.region.y2 = 600
- heuristic = Sequence
- heuristics.Counter.appearance = 3
- heuristics.Counter.markers = 100,100|100,200|200,100|200,200
- heuristics.Counter.maxDistance = 140
- heuristics.Counter.minArea = 200
- heuristics.Counter.minimumChanges = 20
- heuristics.Counter.noMotionDelayTime = 100
- heuristics.Counter.onlyTrueWhenCounted = true
- heuristics.Sequence.minimumChanges = 20
- heuristics.Sequence.minimumDuration = 2
- heuristics.Sequence.noMotionDelayTime = 1000
- io = Video
- ios.Disk.directory = /etc/opt/kerberosio/capture/
- ios.Disk.fileFormat = timestamp_microseconds_instanceName_regionCoordinates_numberOfChanges_token.jpg
- ios.Disk.markWithTimestamp = false
- ios.Disk.privacy = false
- ios.Disk.timestampColor = white
- ios.GPIO.periodTime = 100000
- ios.GPIO.periods = 1
- ios.GPIO.pin = 17
- ios.Script.path = /etc/opt/kerberosio/scripts/run.sh
- ios.TCPSocket.message = motion-detected
- ios.TCPSocket.port = 1337
- ios.TCPSocket.server = 127.0.0.1
- ios.Video.codec = h264
- ios.Video.directory = /etc/opt/kerberosio/capture/
- ios.Video.enableHardwareEncoding = true
- ios.Video.extension = mp4
- ios.Video.fileFormat = timestamp_microseconds_instanceName_regionCoordinates_numberOfChanges_token
- ios.Video.fps = 3
- ios.Video.hardwareDirectory = /etc/opt/kerberosio/h264/
- ios.Video.markWithTimestamp = false
- ios.Video.maxDuration = 30
- ios.Video.privacy = false
- ios.Video.recordAfter = 5
- ios.Video.timestampColor = white
- ios.Webhook.url = http://localhost/api/v1/webhook
- logging = false
- name = frontdoor
- stream = MJPG
- streams.MJPG.enabled = true
- streams.MJPG.fps = 15
- streams.MJPG.password =
- streams.MJPG.quality = 75
- streams.MJPG.streamPort = 8889
- streams.MJPG.username =
- timezone = Europe-Brussels
16/11/2017 23:06:08.516 INFO  [trivial] Logging is set to info
16/11/2017 23:06:08.519 INFO  [trivial] Starting capture device: VideoCapture
terminate called after throwing an instance of 'std::out_of_range'
  what():  map::at
Aborted

I tried changing the input to USBCamera which should also open /dev/video0 if I understand it correctly. It segfaults the same way:

[...]
16/11/2017 23:08:09.855 INFO  [trivial] Logging is set to info
16/11/2017 23:08:09.857 INFO  [trivial] Starting capture device: USBCamera
terminate called after throwing an instance of 'std::out_of_range'
  what():  map::at
Aborted

Is there a way to enable debug symbols or to compile it myself to see where the error occurs? When pointing VideoCapture to a normal file (like ~/snap.jpg) it will report an ioctl error (since the file is not a video device I assume).

I'm using a UVC camera, Logitech QuickCam Pro 9000:

# lsusb
[...]
Bus 002 Device 002: ID 046d:0990 Logitech, Inc. QuickCam Pro 9000
[...]

Uvccapture works fine:

Using videodevice: /dev/video0
Saving images to: snap.jpg
Image size: 1280x720
Taking snapshot every 0 seconds
Taking images using mmap
 format asked unavailable get width 960 height 720
Resetting camera settings
Setting camera brightness to 20
Setting camera contrast to 30
Setting camera saturation to 40
Setting camera gain to 80
Saving image to: snap.jpg

And the image file contains what you would expect.

Any help is appreciated.

cedricve commented 6 years ago

Hey there, did you removed something from the config file? Looks like something is missing. Kerberos.io tries to read an attribute which isn't available.

chrbayer84 commented 6 years ago

I'm not aware I removed something. But, I also couldn't make the UI store my settings (so I started editing the config files manually). I upgraded to 2.3.1 and it magically started working (with the unchanged config). I bet the storing of the config files not working is a permissions issue. I suppose the owner must be whatever nginx is running as? www-data on debian would that be but that also doesn't seem to work.

cedricve commented 6 years ago

Well indeed that might be the cause, can you confirm it keeps working after modifying it through the web?

chrbayer84 commented 6 years ago

No, whenever I change something through the web it just comes back to whatever is in the config file upon refresh. I changed all permissions to www-data and restarted nginx but still no avail. What user should it be?

cedricve commented 6 years ago

Hmm, still a weird issue. I would like to see the corrupted config files after you've modified a setting through the web interface.

leoribeiro commented 6 years ago

I have the same problem with my USB Camera. :(

razex2 commented 6 years ago

Same problem with IP camera

28/04/2018 17:35:39.685 INFO  [trivial] Logging is written to: /etc/opt/kerberosio/logs/log.stash
28/04/2018 17:35:39.688 INFO  [trivial] Parameters passed from commandline:
28/04/2018 17:35:39.700 INFO  [trivial] Reading configuration file: /etc/opt/kerberosio/config/config.xml
28/04/2018 17:35:39.713 INFO  [trivial] Final configuration:
- algorithm = DifferentialCollins
- algorithms.BackgroundSubtraction.dilate = 7
- algorithms.BackgroundSubtraction.erode = 5
- algorithms.BackgroundSubtraction.history = 15
- algorithms.BackgroundSubtraction.nmixtures = 5
- algorithms.BackgroundSubtraction.ratio = 1
- algorithms.BackgroundSubtraction.shadows = false
- algorithms.BackgroundSubtraction.threshold = 10
- algorithms.DifferentialCollins.erode = 5
- algorithms.DifferentialCollins.threshold = 15
- capture = IPCamera
- captures.IPCamera.angle = 0
- captures.IPCamera.delay = 500
- captures.IPCamera.frameHeight = 720
- captures.IPCamera.frameWidth = 1280
- captures.IPCamera.url = rtsp://admin:****@192.168.2.20:10554/udp/av0_0
- cloud = S3
- clouds.S3.bucket =
- clouds.S3.folder =
- clouds.S3.privateKey =
- clouds.S3.publicKey =
- condition = Enabled
- conditions.Enabled.active = true
- conditions.Enabled.delay = 5000
- conditions.Time.delay = 10000
- conditions.Time.times = 0:01,23:59-0:01,23:59-0:01,23:59-0:01,23:59-0:01,23:59-0:01,23:59-0:01,23:59
- configuration = /etc/opt/kerberosio/config/config.xml
- expositor = Hull
- expositors.Hull.region = 564,287|549,109|454,93|377,31|208,63|32,45|111,308|219,380|319,329|410,349|474,319|518,283
- expositors.Rectangle.region.x1 = 0
- expositors.Rectangle.region.x2 = 800
- expositors.Rectangle.region.y1 = 0
- expositors.Rectangle.region.y2 = 600
- heuristic = Sequence
- heuristics.Counter.appearance = 3
- heuristics.Counter.markers = 100,100|100,200|200,100|200,200
- heuristics.Counter.maxDistance = 140
- heuristics.Counter.minArea = 200
- heuristics.Counter.minimumChanges = 20
- heuristics.Counter.noMotionDelayTime = 100
- heuristics.Counter.onlyTrueWhenCounted = true
- heuristics.Sequence.minimumChanges = 20
- heuristics.Sequence.minimumDuration = 2
- heuristics.Sequence.noMotionDelayTime = 1000
- io = Disk
- ios.Disk.directory = /etc/opt/kerberosio/capture/
- ios.Disk.fileFormat = timestamp_microseconds_instanceName_regionCoordinates_numberOfChanges_token.jpg
- ios.Disk.markWithTimestamp = false
- ios.Disk.privacy = false
- ios.Disk.throttler = 0
- ios.Disk.timestampColor = none
- ios.GPIO.periodTime = 100000
- ios.GPIO.periods = 1
- ios.GPIO.pin = 17
- ios.GPIO.throttler = 0
- ios.MQTT.password =
- ios.MQTT.port = 1883
- ios.MQTT.secure = false
- ios.MQTT.server = 127.0.0.1
- ios.MQTT.throttler = 0
- ios.MQTT.topic = kios/mqtt
- ios.MQTT.username =
- ios.MQTT.verifycn = false
- ios.Pushbullet.throttler = 10
- ios.Pushbullet.token = o.mC5LPVCvPCphtSsEgWZQpFM86w9ciWQ3
- ios.Pushbullet.url = https://api.pushbullet.com
- ios.Script.path = /etc/opt/kerberosio/scripts/run.sh
- ios.Script.throttler = 0
- ios.TCPSocket.message = motion-detected
- ios.TCPSocket.port = 1337
- ios.TCPSocket.server = 127.0.0.1
- ios.TCPSocket.throttler = 0
- ios.Video.codec = h264
- ios.Video.directory = /etc/opt/kerberosio/capture/
- ios.Video.enableHardwareEncoding = false
- ios.Video.extension = mp4
- ios.Video.fileFormat = timestamp_microseconds_instanceName_regionCoordinates_numberOfChanges_token
- ios.Video.fps = 30
- ios.Video.hardwareDirectory = /etc/opt/kerberosio/h264/
- ios.Video.markWithTimestamp = false
- ios.Video.maxDuration = 30
- ios.Video.privacy = false
- ios.Video.recordAfter = 5
- ios.Video.throttler = 0
- ios.Video.timestampColor = none
- ios.Webhook.throttler = 0
- ios.Webhook.url = http://localhost/api/v1/webhook
- logging = true
- name = baby
- stream = Mjpg
- streams.Mjpg.enabled = true
- streams.Mjpg.fps = 15
- streams.Mjpg.password =
- streams.Mjpg.quality = 75
- streams.Mjpg.streamPort = 8889
- streams.Mjpg.username =
- timezone = Europe-Minsk
28/04/2018 17:35:39.726 INFO  [trivial] Logging is set to verbose
28/04/2018 17:35:39.730 INFO  [trivial] Starting capture device: IPCamera
28/04/2018 17:35:39.733 INFO  [trivial] Capture: Trying to open IP camera.
28/04/2018 17:35:39.735 INFO  [trivial] Capture: (Warning) You can change the capture device with the configuration files.
28/04/2018 17:35:41.841 INFO  [trivial] Capture: Succesfully opened IP camera.
28/04/2018 17:35:41.879 INFO  [trivial] Capture: Trying to open IP camera.
28/04/2018 17:35:41.881 INFO  [trivial] Capture: (Warning) You can change the capture device with the configuration files.
28/04/2018 17:35:43.950 INFO  [trivial] Capture: Succesfully opened IP camera.
28/04/2018 17:35:44.516 INFO  [trivial] Capture: Trying to open IP camera.
28/04/2018 17:35:44.518 INFO  [trivial] Capture: (Warning) You can change the capture device with the configuration files.
28/04/2018 17:35:46.610 INFO  [trivial] Capture: Succesfully opened IP camera.
28/04/2018 17:35:46.844 INFO  [trivial] Stream: Configured stream on port 8889 with quality: 75
28/04/2018 17:35:46.847 INFO  [business] Capture: checking health status of camera.
28/04/2018 17:35:46.849 INFO  [trivial] Starting cloud service: S3
terminate called after throwing an instance of 'std::out_of_range'
  what():  map::at
Aborted`
cedricve commented 6 years ago

We'll create a new package for the armbian users.

cosbill76 commented 5 years ago

So what's the fix? The same issue here.

rotragit commented 5 years ago

Ok, I had the same problem. But I was coming from a from source installation on a i386 pc and the problem arise when I tried to setup kerberosio on a amd64 pc using docker (for use with multiple ip camera). So I checked the configuration injected by dockeros and I found that in config.xml io for MQTT is enabled. Check in config.xml the line is like this if you don't have a MQTT server:

<io file="io.xml" type="multiple">Disk</io>

I can see that io.xml has the fragments:

`

false
    <verifycn type="bool">false</verifycn>
                            <server type="number">m23.cloudmqtt.com</server>
    <port type="number">10187</port>
                            <topic type="text">kios/mqtt</topic>
    <username type="text">xndxsbqn</username>
    <password type="text">Df0_9GBvGyNj</password>
                            <throttler type="number">10</throttler>
</MQTT>
<Pushbullet>
     <url type="text">https://api.pushbullet.com</url>
    <token type="text">o.mC5LPVCvPCphtSsEgWZQpFM86w9ciWQ3</token>
    <throttler type="number">10</throttler>
</Pushbullet>`

BTW: why not a docker container for i386? I have some Atom unused..

I guess somebody forgotten to cleanup the configs in dockeros first of injecting in the container.

cedricve commented 5 years ago

Hey @rotragit,

yes indeed, i'll fix it.

for i386 we didnt compiled it, if you have time you can contribute.

cedric

rotragit commented 5 years ago

Probably should be better to just rise a warn if the machinery is not able to connect to MQTT or cloud because wrong credential or anything else, instead of exit with an error. Even better if the web page display an alert (or an entry is put in the log).

I've never played with docker. I'll give a look. Thank you

rotragit commented 5 years ago

Here is the Dockerfile for base-linux-i386. I have used official i386/ubuntu (bionic LTS):

FROM i386/ubuntu

MAINTAINER "Cédric Verstraeten" <hello@cedric.ws>

#################################
# Surpress Upstart errors/warning

RUN dpkg-divert --local --rename --add /sbin/initctl
RUN ln -sf /bin/true /sbin/initctl

#############################################
# Let the container know that there is no tty
ENV DEBIAN_FRONTEND noninteractive

#########################################
# Update base image

# Add sources for latest nginx and cmake
# Install software requirements

RUN sed -i -e 's/us.archive.ubuntu.com/archive.ubuntu.com/g' /etc/apt/sources.list
RUN apt-get update && \
apt-get install -y software-properties-common && \
nginx=stable && \
add-apt-repository ppa:nginx/$nginx && \
apt-get update && \
apt-get upgrade -y
RUN apt-get -y install git supervisor curl subversion libcurl4-gnutls-dev cmake dh-autoreconf autotools-dev autoconf automake gcc build-essential libtool make nasm zlib1g-dev tar libx264. vim
RUN apt-add-repository ppa:ondrej/php
RUN apt-get update
RUN apt-get -y --force-yes install nginx nodejs npm php7.0-cli php7.0-gd php7.0-mcrypt php7.0-curl php7.0-mbstring php7.0-dom php7.0-zip php7.0-fpm pwgen

########################################
# fix ownership of sock file for php-fpm

RUN sed -i -e "s/;listen.mode = 0660/listen.mode = 0750/g" /etc/php/7.0/fpm/pool.d/www.conf && \
find /etc/php/7.0/cli/conf.d/ -name "*.ini" -exec sed -i -re 's/^(\s*)#(.*)/\1;\2/g' {} \;

########################################
# Force both nginx and PHP-FPM to run in the foreground
# This is a requirement for supervisor

RUN echo "daemon off;" >> /etc/nginx/nginx.conf
RUN sed -i -e "s/;daemonize\s*=\s*yes/daemonize = no/g" /etc/php/7.0/fpm/php-fpm.conf

Here is the Dockerfile:

FROM base-linux-i386

ARG APP_ENV=master
ENV APP_ENV ${APP_ENV}

MAINTAINER "Cédric Verstraeten" <hello@cedric.ws>

#################################
# Surpress Upstart errors/warning

RUN dpkg-divert --local --rename --add /sbin/initctl
RUN ln -sf /bin/true /sbin/initctl

#############################################
# Let the container know that there is no tty

ENV DEBIAN_FRONTEND noninteractive
RUN apt-get update && apt-get install -y libcurl4-openssl-dev libopencv-dev

############################
# Clone and build machinery
RUN     git clone https://github.com/kerberos-io/machinery /tmp/machinery && \
    cd /tmp/machinery && git checkout ${APP_ENV} && \
    mkdir build && cd build && \
    cmake .. && make && make check && make install && \
    rm -rf /tmp/machinery && \
    chown -Rf www-data.www-data /etc/opt/kerberosio && \
    chmod -Rf 777 /etc/opt/kerberosio/config

#####################
# Clone and build web
RUN curl -sL https://deb.nodesource.com/setup_9.x | bash - && apt-get install -y nodejs
RUN export COMPOSER_PROCESS_TIMEOUT=1200 && \
git clone https://github.com/kerberos-io/web /var/www/web && cd /var/www/web && git checkout ${APP_ENV} && \
chown -Rf www-data.www-data /var/www/web && curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer && \
cd /var/www/web && \
composer install --prefer-source && \
npm install -g bower && \
cd public && \
nodejs /usr/lib/node_modules/bower/bin/bower --allow-root install

RUN rm /var/www/web/public/capture && \
ln -s /etc/opt/kerberosio/capture/ /var/www/web/public/capture

# Fixes, because we are now combining the two docker images.
# Docker is aware of both web and machinery.
RUN sed -i -e "s/'insideDocker'/'insideDocker' => false,\/\//" /var/www/web/app/Http/Controllers/SystemController.php
# RUN sed -i -e "s/\$output \=/\$output \= '';\/\//" /var/www/web/app/Http/Controllers/SettingsController.php
RUN sed -i -e "s/service kerberosio status/supervisorctl status machinery \| grep \"RUNNING\"';\/\//" /var/www/web/app/Http/Repositories/System/OSSystem.php

###################
# nginx site conf

RUN rm -Rf /etc/nginx/conf.d/* && rm -Rf /etc/nginx/sites-available/default && rm -Rf /etc/nginx/sites-enabled/default && mkdir -p /etc/nginx/ssl
ADD ./web.conf /etc/nginx/sites-available/default.conf
RUN ln -s /etc/nginx/sites-available/default.conf /etc/nginx/sites-enabled/default.conf

##################################
# Fix PHP-FPM environment variables

RUN sed -i 's/"GPCS"/"EGPCS"/g' /etc/php/7.0/fpm/php.ini
RUN sed -i 's/"--daemonize/"--daemonize --allow-to-run-as-root/g' /etc/init.d/php7.0-fpm
RUN sed -i 's/www-data/root/g' /etc/php/7.0/fpm/pool.d/www.conf
RUN sed -i 's/www-data/root/g' /etc/nginx/nginx.conf

# Merged supervisord config of both web and machinery
ADD ./supervisord.conf /etc/supervisord.conf

# Merge the two run files.
ADD ./run.sh /runny.sh
RUN chmod 755 /runny.sh
RUN chmod +x /runny.sh
RUN sed -i -e 's/\r$//' /runny.sh

# remove orphan packages
RUN apt -y autoremove

# Exposing web on port 80 and livestreaming on port 8889
EXPOSE 8889
EXPOSE 80

# Make capture and config directory visible
VOLUME ["/etc/opt/kerberosio/capture"]
VOLUME ["/etc/opt/kerberosio/config"]
VOLUME ["/etc/opt/kerberosio/logs"]

# Make web config directory visible
VOLUME ["/var/www/web/config"]
# Start runner script when booting container
CMD ["/bin/bash", "/runny.sh"]

All is based on the Dockerfiles form amd64, with some corrections (f.e. sudo is not needed as docker build is always as sudo in the image creation). I'm not really sure libopencv-dev package is really necessary.

However I ended buying a used Intel i5 PC because the Atom PCs I have (ASUS eee box B202, Intel(R) Atom(TM) CPU N270 @ 1.60GHz) support only two cameras with docker, then they collapse....