OLIMEX OLinuXino A10 Lime with H264 IP Camera

Software configuration

ffmpeg –> 2.4.3

python –> 2.7.8

opencv (python) –> 2.4.9.1

Camera description

i use IP ONVIF compatible camera, available for few euros, this kind of camera is able to generate a H264 stream up to 1280x720p at 25fps stream, over RTSP

a secondary low resolution H264 stream  is available 352×288 at 30fps on another RTSP channel

in_0001

Architecture :

the camera is connected to the A10lime throught switch/router using wired ethernet link all the IP are fixed using MAC mapping inside the router

First FFMPEG tests :

first i use the folowing command line to save the h264 primary stream in jpg stills

ffmpeg -i rtsp://A.B.C.D/live0.264  in_%04d.jpg

ffmpeg display the folowing message :

Guessed Channel Layout for  Input Stream #0.1 : mono
Input #0, rtsp, from 'rtsp://A.B.C.D/live0.264':
  Metadata:
    title           : Session streamed by "rtspServerForJovision"
    comment         : live0.264
  Duration: N/A, start: 47721.859375, bitrate: 64 kb/s
    Stream #0:0: Video: h264 (Main), yuv420p, 768x432, 10 fps, 10 tbr, 90k tbn, 180k tbc
    Stream #0:1: Audio: pcm_mulaw, 8000 Hz, 1 channels, s16, 64 kb/s
[swscaler @ 0x130a5a0] deprecated pixel format used, make sure you did set range correctly
Output #0, image2, to 'in_%04d.jpg':
  Metadata:
    title           : Session streamed by "rtspServerForJovision"
    comment         : live0.264
    encoder         : Lavf56.4.101
    Stream #0:0: Video: mjpeg, yuvj420p, 768x432, q=2-31, 200 kb/s, 10 fps, 10 tbn, 10 tbc
    Metadata:
      encoder         : Lavc56.1.100 mjpeg
Stream mapping:
  Stream #0:0 -> #0:0 (h264 (native) -> mjpeg (native))
Press [q] to stop, [?] for help
[NULL @ 0x13136b0] RTP: missed 144 packets0:00:04.00 bitrate=N/A dup=2 drop=9
[NULL @ 0x13136b0] RTP: missed 1 packets

10fps is correct, i configure the camera with this configuration ,  but we get some error message :
[NULL @ 0x16d86b0] RTP: missed 1593 packets00:06.00 bitrate=N/A dup=13 drop=2
and the folowing info message :
 frame=   12 fps=4.4 q=22.9 size=N/A time=00:00:01.19 bitrate=N/A

10fps is correct, i configure the camera with this configuration ,  but we get some error message :

[NULL @ 0x16d86b0] RTP: missed 1593 packets00:06.00 bitrate=N/A dup=13 drop=2

and the folowing info message :

frame=   12 fps=4.4 q=22.9 size=N/A time=00:00:01.19 bitrate=N/A

only 6fps is reached and the time code progress slower than real time : for 47s of execution we get 338 frame so an average of 7fps , not so bad but if we observe the time stamp into the image (generated by the camera) there is a problem :
so for 47s of real time on 31s is recorded !!!. for a long time record , this difference will growth , this time bias shall be minimized if we upload the jpg to a web server for real time monitoring

We also get a lot of frame corrupted, for example :
in_0490

it’s link to the protocol used be default , RTSP over UDP , we can force it using ffmpeg option

force  TCP mode for FFMPEG and suppress the drift :

after research on the web , we can force the RTSP in tcp mode, it give good result for my camera
for example , to record a copy of the stream :

ffmpeg -rtsp_transport tcp -i rtsp://A.B.C.D/live0.264 -vcodec copy enreg.ts

success @10fps (fixed in the camera) in TS format but doesn’t work with matroska format (timecode incorrect)
if we try to record the stream in jpeg , there is still a    drift between the recorded frame and the real time.
A rtsp stream shall be limited in ffmpeg, after many test , i get good result with video filter and fps option
here we will record jpg at 5fps (shall be adapted to the limited A10 computing resource)

ffmpeg -i rtsp://A.B.C.D/live0.264 -rtsp_transport tcp -an -vf fps=fps=5 in5_%07d.jpg

here we will record jpg at 1 frame every 5s

ffmpeg -i rtsp://A.B.C.D/live0.264 -rtsp_transport tcp -an -vf fps=fps=1/5 in_%07d.jpg

the result of the folowing command

time ffmpeg -i rtsp://A.B.C.D/live1.264 -rtsp_transport tcp -an -vf fps=fps=1 in5_%07d.jpg

is 2m18s of running and 138 frame recorded and 136 seconds between the first and the last frame :
all is ok

Advanced use of FFMPEG, use hardware to decode

if you install the vdpau support for cedarx, you can use the hardware acceleration to decode the stream

this command can be launched in a terminal (not root!!) after

  • configuration of the X server to accept connection (remove no listen option)
  • be sure that autologin is activated
  • export display
export DISPLAY=:0.0
./ffmpeg -hwaccel vdpau -i ../big_buck_bunny_1080p_H264_AAC_25fps_7200K.MP4 -f image2pipe -pix_fmt yuv420p -vcodec rawvideo - > /dev/null
 

for an ip camera the command shall be


FFmpeg-Cedrus/ffmpeg -rtsp_transport tcp -an -hwaccel vdpau -i rtsp://X.Y.Z.A/live0.264 -f image2pipe -pix_fmt yuv420p -vcodec rawvideo - > /dev/null
 

Advanced use of FFMPEG , stream to a python script

it is possible to call ffmpeg from a python script and process the image using pyopencv. Here is an example which acquire 2 stream from one camera and save stills in jpg format. This use pipe method between ffmpeg & python

#!/usr/bin/env python2
import numpy as np
import cv2

import ftplib
import threading

from datetime import datetime
import time
import sys
import StringIO
import os
import subprocess as sp
import fcntl

FFMPEG_BIN = "ffmpeg" 

class thread_video(threading.Thread):
    def __init__(self,name_input,pipe,size_x,size_y):
        super(thread_video, self).__init__()
        self.quit = False
        self.name_input = name_input
        self.pipe = pipe
        self.size_x = size_x
        self.size_y = size_y

    def run(self):

        encode_param=[int(cv2.IMWRITE_JPEG_QUALITY),90]
        while True:
            current_time = datetime.now()
            filename = current_time.strftime(self.name_input+"_input_%b-%d_%H:%M:%S:%f")+".jpg"
            raw_image = self.pipe.stdout.read(self.size_x*self.size_y*3)
            self.pipe.stdout.flush()
            # transform the byte read into a numpy array
            image =  np.fromstring(raw_image, dtype='uint8')
            image_input = image.reshape((self.size_y,self.size_x,3))
            cv2.imwrite(filename, image_input,encode_param)

class App:
    def run(self):
        period=20

        start_time=time.time()
        nb_frame = 0
        fps=1
        command1 = [ FFMPEG_BIN,
                    '-rtsp_transport','tcp',
                    '-i', "rtsp://A.B.C.D/live0.264",
                    '-f', 'image2pipe',
                   '-vf', 'fps=fps=1',
                    '-pix_fmt', 'rgb24',
                    '-vcodec', 'rawvideo', '-']
        pipe1 = sp.Popen(command1, stdout = sp.PIPE, bufsize=10**8)
        size_raw_x1=768
        size_raw_y1=432

        command2 = [ FFMPEG_BIN,
                    '-rtsp_transport','tcp',
                    '-i', "rtsp://A.B.C.D/live1.264",
                    '-f', 'image2pipe',
                   '-vf', 'fps=fps=5',
                    '-pix_fmt', 'rgb24',
                    '-vcodec', 'rawvideo', '-']
        pipe2 = sp.Popen(command2, stdout = sp.PIPE, bufsize=10**8)
        size_raw_x2=352
        size_raw_y2=288

        self.thread_acq1=thread_video("1",pipe1,size_raw_x1,size_raw_y1)
        self.thread_acq1.start()
        self.thread_acq2=thread_video("2",pipe2,size_raw_x2,size_raw_y2)
        self.thread_acq2.start()
        self.thread_acq2.join()
        self.thread_acq1.join()

if __name__ == '__main__':

        try:
            App().run()
        except:
            raise
            print "Except"

Une réflexion sur “OLIMEX OLinuXino A10 Lime with H264 IP Camera

  1. Pingback: using olinuxino A10 card in CCTV with people detection | Yoann's Blog

Laisser un commentaire

Entrez vos coordonnées ci-dessous ou cliquez sur une icône pour vous connecter:

Logo WordPress.com

Vous commentez à l'aide de votre compte WordPress.com. Déconnexion / Changer )

Image Twitter

Vous commentez à l'aide de votre compte Twitter. Déconnexion / Changer )

Photo Facebook

Vous commentez à l'aide de votre compte Facebook. Déconnexion / Changer )

Photo Google+

Vous commentez à l'aide de votre compte Google+. Déconnexion / Changer )

Connexion à %s