bpwain
Posts: 9
Joined: Tue Nov 05, 2013 9:41 pm
Location: Cheshire- UK

Capturing pre-trigger

Wed Jan 08, 2014 12:37 pm

Hello folks.
I'm hoping someone may be able to give me a suggestion or two to try...

I've already developed a python script that triggers raspistill as a subprocess once GPIO pin 12 is pulled to ground, and this could easily be altered to call raspivid instead. However, what I would like to do is record (for example) 10 seconds before the trigger and then 10 seconds after. Is there a way to do this with raspivid or such like? I can't seem to find anything along these lines from looking at previous posts, so thought I'd ask the question.

Many thanks,
Ben

jamesh
Raspberry Pi Engineer & Forum Moderator
Raspberry Pi Engineer & Forum Moderator
Posts: 27021
Joined: Sat Jul 30, 2011 7:41 pm

Re: Capturing pre-trigger

Wed Jan 08, 2014 12:46 pm

There was a recent change to the raspivid code to something just like this. Download the latest version and take a look - I didn't do it so don't know what specifically it does, or how to work it I'm afraid.
Principal Software Engineer at Raspberry Pi (Trading) Ltd.
Contrary to popular belief, humorous signatures are allowed.
I've been saying "Mucho" to my Spanish friend a lot more lately. It means a lot to him.

dqpi
Posts: 33
Joined: Fri May 24, 2013 12:22 pm

Re: Capturing pre-trigger

Wed Jan 08, 2014 11:58 pm

If you find a way to do this could you report back? I would be very interested

User avatar
jbeale
Posts: 3709
Joined: Tue Nov 22, 2011 11:51 pm
Contact: Website

Re: Capturing pre-trigger

Thu Jan 09, 2014 6:36 am

Hey, I didn't know about that, very interesting! Apparently there is a circular buffer mode (-circular) in the newest raspivid code, from ghollingsworth 18 days ago, and committed by popcornmix 5 days ago. You can browse the relevant code at https://raw.github.com/raspberrypi/user ... RaspiVid.c

Looks like the -timeout command sets the length of the circular buffer, and it must be used with either keypress (-k) or signal (-s) to trigger the saveout of the previous N seconds of video. I don't think it saves forward in time as well, so if you need (T-20)...(T+20) you'd have to set the buffer to 40 seconds and then wait 20 seconds after the trigger to send the actual signal. However there must be some limit to the available memory = time, not sure how long that is. Depends on your bitrate, no doubt. The video buffer is surely in RAM and not on flash due to the wearout cycle issue.

Commands available for raspivid (note at the end of this list):

Code: Select all

static COMMAND_LIST cmdline_commands[] =
{
   { CommandHelp,          "-help",       "?",  "This help information", 0 },
   { CommandWidth,         "-width",      "w",  "Set image width <size>. Default 1920", 1 },
   { CommandHeight,        "-height",     "h",  "Set image height <size>. Default 1080", 1 },
   { CommandBitrate,       "-bitrate",    "b",  "Set bitrate. Use bits per second (e.g. 10MBits/s would be -b 10000000)", 1 },
   { CommandOutput,        "-output",     "o",  "Output filename <filename> (to write to stdout, use '-o -')", 1 },
   { CommandVerbose,       "-verbose",    "v",  "Output verbose information during run", 0 },
   { CommandTimeout,       "-timeout",    "t",  "Time (in ms) to capture for. If not specified, set to 5s. Zero to disable", 1 },
   { CommandDemoMode,      "-demo",       "d",  "Run a demo mode (cycle through range of camera options, no capture)", 1},
   { CommandFramerate,     "-framerate",  "fps","Specify the frames per second to record", 1},
   { CommandPreviewEnc,    "-penc",       "e",  "Display preview image *after* encoding (shows compression artifacts)", 0},
   { CommandIntraPeriod,   "-intra",      "g",  "Specify the intra refresh period (key frame rate/GoP size)", 1},
   { CommandProfile,       "-profile",    "pf", "Specify H264 profile to use for encoding", 1},
   { CommandTimed,         "-timed",      "td", "Cycle between capture and pause. -cycle on,off where on is record time and off is pause time in ms", 0},
   { CommandSignal,        "-signal",     "s",  "Cycle between capture and pause on Signal", 0},
   { CommandKeypress,      "-keypress",   "k",  "Cycle between capture and pause on ENTER", 0},
   { CommandInitialState,  "-initial",    "i",  "Initial state. Use 'record' or 'pause'. Default 'record'", 1},
   { CommandQP,            "-qp",         "qp", "Quantisation parameter. Use approximately 10-40. Default 0 (off)", 1},
   { CommandInlineHeaders, "-inline",     "ih", "Insert inline headers (SPS, PPS) to stream", 0},
   { CommandSegmentFile,   "-segment",    "sg", "Segment output file in to multiple files at specified interval <ms>", 1},
   { CommandSegmentWrap,   "-wrap",       "wr", "In segment mode, wrap any numbered filename back to 1 when reach number", 1},
   { CommandSegmentStart,  "-start",      "sn", "In segment mode, start with specified segment number", 1},
   { CommandSplitWait,     "-split",      "sp", "In wait mode, create new output file for each start event", 0},
   { CommandCircular,      "-circular",   "c",  "Run encoded data through circular buffer until triggered then save", 0},
};

User avatar
waveform80
Posts: 359
Joined: Mon Sep 23, 2013 1:28 pm
Location: Manchester, UK
Contact: Website Twitter

Re: Capturing pre-trigger

Thu Jan 09, 2014 9:36 pm

jbeale wrote:Hey, I didn't know about that, very interesting! Apparently there is a circular buffer mode (-circular) in the newest raspivid code, from ghollingsworth 18 days ago, and committed by popcornmix 5 days ago. You can browse the relevant code at https://raw.github.com/raspberrypi/user ... RaspiVid.c
Yup - it's very cool stuff. So cool in fact, I shamelessly stole the idea to squeeze into release 1.0 of picamera (#39; and here's a couple of recipes using it)

Dave (shamelessly plugging picamera yet again!)
Author of / contributor to a few pi related things (picamera, Sense HAT emulator, gpio-zero, piwheels, etc.), and currently a software engineer at Canonical responsible for Ubuntu Server and Core on the Raspberry Pi.

bpwain
Posts: 9
Joined: Tue Nov 05, 2013 9:41 pm
Location: Cheshire- UK

Re: Capturing pre-trigger

Fri Jan 10, 2014 9:21 am

Hi guys

Thanks for the info.
I won't be worrying about post-trigger for now, as like you say, I can always just add a buffer.

I have tried using -c, but I can't seem to get it to work. It seems to dislike anything that comes after the -c
For example, if i use

Code: Select all

#raspivid -vf -hf -o circ.h264 -c -k -t 6000
it returns;
"Invalid command line option (-k)"
but if I use

Code: Select all

#raspivid -vf -hf -o circ.h264 -c  -t 6000 -k
it returns;
"Invalid command line option (-t)"
Is there something that I need to have after -c perhaps?

In the meantime, I think I'll give picamera a go to see if I get more success. Thanks Dave ;-)

ethanol100
Posts: 650
Joined: Wed Oct 02, 2013 12:28 pm

Re: Capturing pre-trigger

Fri Jan 10, 2014 9:27 am

Can you check if you will find the option -c in the list, when you just execute raspivid without arguments? Are you sure your version of raspivid is new enough? Have you compiled raspivid from git. I think it is the usual behaviour if raspivid does not know an argument.

jamesh
Raspberry Pi Engineer & Forum Moderator
Raspberry Pi Engineer & Forum Moderator
Posts: 27021
Joined: Sat Jul 30, 2011 7:41 pm

Re: Capturing pre-trigger

Fri Jan 10, 2014 9:31 am

Yes, you probably haven't updated to the latest version of the code.
Principal Software Engineer at Raspberry Pi (Trading) Ltd.
Contrary to popular belief, humorous signatures are allowed.
I've been saying "Mucho" to my Spanish friend a lot more lately. It means a lot to him.

bpwain
Posts: 9
Joined: Tue Nov 05, 2013 9:41 pm
Location: Cheshire- UK

Re: Capturing pre-trigger

Fri Jan 10, 2014 10:14 am

I always run "sudo apt-get update && sudo apt-get upgrade" every day as I start, so I always assumed this would keep me up to date. However -c is not showing as an option when I execute raspivid, so it looks like it is indeed not up to date.
How do I fix that then?
Cheers,
Ben

balamuralimanoghar
Posts: 13
Joined: Thu Jan 09, 2014 8:54 am

Re: Capturing pre-trigger

Fri Jan 10, 2014 10:20 am

jbeale wrote:Hey, I didn't know about that, very interesting! Apparently there is a circular buffer mode (-circular) in the newest raspivid code, from ghollingsworth 18 days ago, and committed by popcornmix 5 days ago. You can browse the relevant code at https://raw.github.com/raspberrypi/user ... RaspiVid.c

Looks like the -timeout command sets the length of the circular buffer, and it must be used with either keypress (-k) or signal (-s) to trigger the saveout of the previous N seconds of video. I don't think it saves forward in time as well, so if you need (T-20)...(T+20) you'd have to set the buffer to 40 seconds and then wait 20 seconds after the trigger to send the actual signal. However there must be some limit to the available memory = time, not sure how long that is. Depends on your bitrate, no doubt. The video buffer is surely in RAM and not on flash due to the wearout cycle issue.

Commands available for raspivid (note at the end of this list):

Code: Select all

static COMMAND_LIST cmdline_commands[] =
{
   { CommandHelp,          "-help",       "?",  "This help information", 0 },
   { CommandWidth,         "-width",      "w",  "Set image width <size>. Default 1920", 1 },
   { CommandHeight,        "-height",     "h",  "Set image height <size>. Default 1080", 1 },
   { CommandBitrate,       "-bitrate",    "b",  "Set bitrate. Use bits per second (e.g. 10MBits/s would be -b 10000000)", 1 },
   { CommandOutput,        "-output",     "o",  "Output filename <filename> (to write to stdout, use '-o -')", 1 },
   { CommandVerbose,       "-verbose",    "v",  "Output verbose information during run", 0 },
   { CommandTimeout,       "-timeout",    "t",  "Time (in ms) to capture for. If not specified, set to 5s. Zero to disable", 1 },
   { CommandDemoMode,      "-demo",       "d",  "Run a demo mode (cycle through range of camera options, no capture)", 1},
   { CommandFramerate,     "-framerate",  "fps","Specify the frames per second to record", 1},
   { CommandPreviewEnc,    "-penc",       "e",  "Display preview image *after* encoding (shows compression artifacts)", 0},
   { CommandIntraPeriod,   "-intra",      "g",  "Specify the intra refresh period (key frame rate/GoP size)", 1},
   { CommandProfile,       "-profile",    "pf", "Specify H264 profile to use for encoding", 1},
   { CommandTimed,         "-timed",      "td", "Cycle between capture and pause. -cycle on,off where on is record time and off is pause time in ms", 0},
   { CommandSignal,        "-signal",     "s",  "Cycle between capture and pause on Signal", 0},
   { CommandKeypress,      "-keypress",   "k",  "Cycle between capture and pause on ENTER", 0},
   { CommandInitialState,  "-initial",    "i",  "Initial state. Use 'record' or 'pause'. Default 'record'", 1},
   { CommandQP,            "-qp",         "qp", "Quantisation parameter. Use approximately 10-40. Default 0 (off)", 1},
   { CommandInlineHeaders, "-inline",     "ih", "Insert inline headers (SPS, PPS) to stream", 0},
   { CommandSegmentFile,   "-segment",    "sg", "Segment output file in to multiple files at specified interval <ms>", 1},
   { CommandSegmentWrap,   "-wrap",       "wr", "In segment mode, wrap any numbered filename back to 1 when reach number", 1},
   { CommandSegmentStart,  "-start",      "sn", "In segment mode, start with specified segment number", 1},
   { CommandSplitWait,     "-split",      "sp", "In wait mode, create new output file for each start event", 0},
   { CommandCircular,      "-circular",   "c",  "Run encoded data through circular buffer until triggered then save", 0},
};


Which key should be pressed??
where can i find the latest documentation?
is there an option to stop the camera capture in the middle?
is there an option to capture images when the video is capturing?
is there an option to change settings like ISO EXPOSURE etc.. when i run raspivid for infinite time??

thanks....

ethanol100
Posts: 650
Joined: Wed Oct 02, 2013 12:28 pm

Re: Capturing pre-trigger

Fri Jan 10, 2014 10:30 am

bpwain wrote:I always run "sudo apt-get update && sudo apt-get upgrade" every day as I start, so I always assumed this would keep me up to date. However -c is not showing as an option when I execute raspivid, so it looks like it is indeed not up to date.
How do I fix that then?
Cheers,
Ben
The circular buffer was just add recently, it is not yet in the firmware you could get with apt-get or "rpi-update", you need to wait until it will be included, or you need to compile it yourself.

Compiling is something like:

Code: Select all

git clone https://github.com/raspberrypi/userland.git
cd userland
./buildme

ethanol100
Posts: 650
Joined: Wed Oct 02, 2013 12:28 pm

Re: Capturing pre-trigger

Fri Jan 10, 2014 10:40 am

balamuralimanoghar wrote: Which key should be pressed??
I think Enter, you can run raspivid with the -v switch, then it will tell what you should press.
balamuralimanoghar wrote: where can i find the latest documentation?
On github: https://github.com/raspberrypi/userland ... amDocs.odt
balamuralimanoghar wrote: is there an option to stop the camera capture in the middle?
is there an option to capture images when the video is capturing?
is there an option to change settings like ISO EXPOSURE etc.. when i run raspivid for infinite time??

thanks....
The forum will give some answers to these points, but I would say no,no and no. Feel free to modify the code to your needs...

bpwain
Posts: 9
Joined: Tue Nov 05, 2013 9:41 pm
Location: Cheshire- UK

Re: Capturing pre-trigger

Fri Jan 10, 2014 10:54 am

ethanol100 wrote:
The circular buffer was just add recently, it is not yet in the firmware you could get with apt-get or "rpi-update", you need to wait until it will be included, or you need to compile it yourself.

Compiling is something like:

Code: Select all

git clone https://github.com/raspberrypi/userland.git
cd userland
./buildme
I also saw this on gsh's thread, so I've tried to do just that, but when I input "./buildme" I get the following;

~/userland/build/raspberry/release ~/userland
./buildme: line 7: cmake: command not found
make: ***No targets specified and no makefile found. Stop.
make: ***No rule to make target 'install'. Stop.
~/userland

ghans
Posts: 7883
Joined: Mon Dec 12, 2011 8:30 pm
Location: Germany

Re: Capturing pre-trigger

Fri Jan 10, 2014 10:57 am

sudo apt-get install cmake


ghans
• Don't like the board ? Missing features ? Change to the prosilver theme ! You can find it in your settings.
• Don't like to search the forum BEFORE posting 'cos it's useless ? Try googling : yoursearchtermshere site:raspberrypi.org

balamuralimanoghar
Posts: 13
Joined: Thu Jan 09, 2014 8:54 am

Re: Capturing pre-trigger

Fri Jan 10, 2014 11:19 am

ethanol100 wrote:
balamuralimanoghar wrote: Which key should be pressed??
I think Enter, you can run raspivid with the -v switch, then it will tell what you should press.
balamuralimanoghar wrote: is there an option to stop the camera capture in the middle?
is there an option to capture images when the video is capturing?
is there an option to change settings like ISO EXPOSURE etc.. when i run raspivid for infinite time??

thanks....
The forum will give some answers to these points, but I would say no,no and no. Feel free to modify the code to your needs...
can i stop the video capture and pause/resume in the middle by external trigger or bu sending ascii equivalent of "enter" and "x" through serial port??


thanks for reply "ethanol100"

ethanol100
Posts: 650
Joined: Wed Oct 02, 2013 12:28 pm

Re: Capturing pre-trigger

Fri Jan 10, 2014 11:35 am

balamuralimanoghar wrote: can i stop the video capture and pause/resume in the middle by external trigger?
It depends, not with the circular buffer, but with just the keypress or signal event.

If you use only -k it will toggle between capturing and not capturing. so you can i.e. hit the enter key after 5 sec, 10sec and 15 sec and the final video will contain the first 5 sec and the last 5 seconds. Note there is the this argument "-i, --initial : Initial state. Use 'record' or 'pause'. Default 'record'" to define the initial state of the toggle.

You can use the signal which then waits to receive a USR1 signal by kill, and you will need to write a helper script/programm, which would listen to the serial port and then sent a kill -USR1 to the raspivid process.

bpwain
Posts: 9
Joined: Tue Nov 05, 2013 9:41 pm
Location: Cheshire- UK

Re: Capturing pre-trigger

Fri Jan 10, 2014 1:54 pm

ghans wrote:sudo apt-get install cmake


ghans
Thanks ghans. That did the trick. Circular buffering now works on my pi :D

I'll post my full script once i get it fully working.
Thanks to you all once again!
Ben

User avatar
AndrewS
Posts: 3625
Joined: Sun Apr 22, 2012 4:50 pm
Location: Cambridge, UK
Contact: Website

Re: Capturing pre-trigger

Sat Jan 11, 2014 7:23 pm

There's more info about all this, in this thread http://www.raspberrypi.org/forum/viewto ... 43&t=65450

bpwain
Posts: 9
Joined: Tue Nov 05, 2013 9:41 pm
Location: Cheshire- UK

Re: Capturing pre-trigger

Tue Jan 21, 2014 4:34 pm

Hi folks,
I'm trying to get my script completed now.
How does the -s rather than -k work for triggering? Can I assign my GPIO input as the signal (-s) at the start of the script, then use it as the trigger? I can't seem to find any info on the -s feature, other than 'it's signal', but surely the 'signal' must be defined as something????

jamesh
Raspberry Pi Engineer & Forum Moderator
Raspberry Pi Engineer & Forum Moderator
Posts: 27021
Joined: Sat Jul 30, 2011 7:41 pm

Re: Capturing pre-trigger

Tue Jan 21, 2014 4:42 pm

signal is a Linux signal - you can send a signal from the command line to a running raspistill using the kill command (yes, its a daft name). man kill for more information. The signal it waits on is SIGUSR1

If you want to connect to a GPIO, write a program that monitors the GPIO, then sends the signal as required.
Principal Software Engineer at Raspberry Pi (Trading) Ltd.
Contrary to popular belief, humorous signatures are allowed.
I've been saying "Mucho" to my Spanish friend a lot more lately. It means a lot to him.

thegnnu
Posts: 157
Joined: Thu Oct 18, 2012 7:07 pm
Location: Bristol

Re: Capturing pre-trigger

Tue Nov 18, 2014 10:27 am

bpwain wrote:Hi folks,
I'm trying to get my script completed now.
How does the -s rather than -k work for triggering? Can I assign my GPIO input as the signal (-s) at the start of the script, then use it as the trigger? I can't seem to find any info on the -s feature, other than 'it's signal', but surely the 'signal' must be defined as something????
Hi Ben Just found this post did you every get the stop start by GPIO working
TerryR

bpwain
Posts: 9
Joined: Tue Nov 05, 2013 9:41 pm
Location: Cheshire- UK

Re: Capturing pre-trigger

Thu Nov 20, 2014 3:27 pm

Hi Terry,

Yeh, I got it to work, and it's proved to be invaluable for the test work that I do.
To be honest it doesn't exit from the script cleanly, but all the required functions are there.
I've set it so that once the script is started, it will run until a button connected to GPIO 12 is pressed.

Since I never posted my script, here it is for you all (I think this was my last saved version). Please feel free to comment on it so that I can improve it (and my programming skills!)
Also, if anyone uses or edits it for their own purposes, I'd love to know what for and how you've edited it. Thanks :D

Code: Select all

# Circular buffered pre-trigger video recording for Raspberry Pi
# Created by Ben Wain, Bentley Motors Ltd (Feb 2014)

# Uses GPIO 11 to trigger a save of 'x'seconds footage prior to the trigger happening (adjust 'x' to suit application)
# Each triggered save is indexed with trigger number
# Uses GPIO 12 to stop recording and exit programme

from __future__ import print_function
try:
    input = raw_input
except NameError:
    pass

import time
import io
import sys
import picamera
from select import select
import RPi.GPIO as GPIO
GPIO.setmode(GPIO.BOARD)
GPIO.setup(12, GPIO.IN)
GPIO.setup(11, GPIO.IN)


with picamera.PiCamera() as camera:
    camera.resolution = (1280, 720)
    camera.vflip = True
    camera.hflip = True
    camera.start_preview()
# Make preview window smaller to allow terminal text to be seen (shows no. of triggers)
# Preview window settings is as follows... (X offset, Y offset, Width, Hight)
    camera.preview_fullscreen = False
    camera.preview_window = (160, -110, 1105, 850)
# Adjust 'seconds' to suit
    stream = picamera.PiCameraCircularIO(camera, seconds=35)
    camera.start_recording(stream, format='h264')
    count = 1
    print('Test running. Camera monitoring of test cycles is now in progress')
    print('......Waiting for a cycle failure to trigger video file save.......................')
    while camera.recording:
        while count <= 100:
            camera.wait_recording(0.5)
            input_value12 = GPIO.input(12)
            if input_value12 == False:
                print('Exiting...')
                camera.stop_preview()
                camera.stop_recording()
                while input_value12 == False:
                    input_value12 = GPIO.input(12)


            input_value11 = GPIO.input(11)
            if input_value11 == False:
                print('********** Triggerred **********')
# Adjust sleep(seconds) to include post trigger recording NOTE:ALLOW FOR THIS IN 'SECONDS' ABOVE
                time.sleep(10)
                print('Writing the video...', end='')
                with stream.lock:
                    for frame in stream.frames:
                        if frame.header:
                            stream.seek(frame.position)
                            break
                    with io.open('fail_' '%d' '.h264' % (count), 'wb') as output:
                        while True:
                            buf = stream.read1()
                            if not buf:
                                break
                            output.write(buf)
                print('done')
                print('No. of failures detected = <...' '%d' '...>' % (count)) 
                print(' ')
                print('Recording active......Waiting for a cycle failure to trigger next video file save.......................')
                count += 1
                while input_value11 == False:
                    input_value11 = GPIO.input(11)
        else:
            print('Max triggers(' '%d' ') detected or GPIO 12 triggerred. Ending programme...' % (count))
            print('END' %c)
    GPIO.cleanup()

thegnnu
Posts: 157
Joined: Thu Oct 18, 2012 7:07 pm
Location: Bristol

Re: Capturing pre-trigger

Thu Nov 20, 2014 4:46 pm

Thanks Ben
Will take a look
Not seen to much on the pre-trigger option

TerryR

Return to “Camera board”