Merge branch 'storageareas' into add_export_to_filter

This commit is contained in:
Isaac Connor 2018-07-25 17:08:20 -04:00
commit bb4861bb8c
6 changed files with 67 additions and 51 deletions

View File

@ -617,8 +617,13 @@ bool Monitor::connect() {
pre_event_buffer = new Snapshot[pre_event_buffer_count]; pre_event_buffer = new Snapshot[pre_event_buffer_count];
for ( int i = 0; i < pre_event_buffer_count; i++ ) { for ( int i = 0; i < pre_event_buffer_count; i++ ) {
pre_event_buffer[i].timestamp = new struct timeval; pre_event_buffer[i].timestamp = new struct timeval;
*pre_event_buffer[i].timestamp = {0,0};
pre_event_buffer[i].image = new Image( width, height, camera->Colours(), camera->SubpixelOrder()); pre_event_buffer[i].image = new Image( width, height, camera->Colours(), camera->SubpixelOrder());
} }
timestamps = new struct timeval *[pre_event_count];
images = new Image *[pre_event_count];
last_signal = shared_data->signal;
} }
Debug(3, "Success connecting"); Debug(3, "Success connecting");
return true; return true;
@ -1261,6 +1266,7 @@ bool Monitor::Analyse() {
int index; int index;
if ( adaptive_skip ) { if ( adaptive_skip ) {
// I think the idea behind adaptive skip is if we are falling behind, then skip a bunch, but not all
int read_margin = shared_data->last_read_index - shared_data->last_write_index; int read_margin = shared_data->last_read_index - shared_data->last_write_index;
if ( read_margin < 0 ) read_margin += image_buffer_count; if ( read_margin < 0 ) read_margin += image_buffer_count;
@ -1274,7 +1280,10 @@ bool Monitor::Analyse() {
int pending_frames = shared_data->last_write_index - shared_data->last_read_index; int pending_frames = shared_data->last_write_index - shared_data->last_read_index;
if ( pending_frames < 0 ) pending_frames += image_buffer_count; if ( pending_frames < 0 ) pending_frames += image_buffer_count;
Debug( 4, "ReadIndex:%d, WriteIndex: %d, PendingFrames = %d, ReadMargin = %d, Step = %d", shared_data->last_read_index, shared_data->last_write_index, pending_frames, read_margin, step ); Debug(4,
"ReadIndex:%d, WriteIndex: %d, PendingFrames = %d, ReadMargin = %d, Step = %d",
shared_data->last_read_index, shared_data->last_write_index, pending_frames, read_margin, step
);
if ( step <= pending_frames ) { if ( step <= pending_frames ) {
index = (shared_data->last_read_index+step)%image_buffer_count; index = (shared_data->last_read_index+step)%image_buffer_count;
} else { } else {
@ -1294,17 +1303,17 @@ bool Monitor::Analyse() {
if ( shared_data->action ) { if ( shared_data->action ) {
// Can there be more than 1 bit set in the action? Shouldn't these be elseifs? // Can there be more than 1 bit set in the action? Shouldn't these be elseifs?
if ( shared_data->action & RELOAD ) { if ( shared_data->action & RELOAD ) {
Info( "Received reload indication at count %d", image_count ); Info("Received reload indication at count %d", image_count);
shared_data->action &= ~RELOAD; shared_data->action &= ~RELOAD;
Reload(); Reload();
} }
if ( shared_data->action & SUSPEND ) { if ( shared_data->action & SUSPEND ) {
if ( Active() ) { if ( Active() ) {
Info( "Received suspend indication at count %d", image_count ); Info("Received suspend indication at count %d", image_count);
shared_data->active = false; shared_data->active = false;
//closeEvent(); //closeEvent();
} else { } else {
Info( "Received suspend indication at count %d, but wasn't active", image_count ); Info("Received suspend indication at count %d, but wasn't active", image_count);
} }
if ( config.max_suspend_time ) { if ( config.max_suspend_time ) {
auto_resume_time = now.tv_sec + config.max_suspend_time; auto_resume_time = now.tv_sec + config.max_suspend_time;
@ -1313,7 +1322,7 @@ bool Monitor::Analyse() {
} }
if ( shared_data->action & RESUME ) { if ( shared_data->action & RESUME ) {
if ( Enabled() && !Active() ) { if ( Enabled() && !Active() ) {
Info( "Received resume indication at count %d", image_count ); Info("Received resume indication at count %d", image_count);
shared_data->active = true; shared_data->active = true;
ref_image = *snap_image; ref_image = *snap_image;
ready_count = image_count+(warmup_count/2); ready_count = image_count+(warmup_count/2);
@ -1324,24 +1333,14 @@ bool Monitor::Analyse() {
} // end if shared_data->action } // end if shared_data->action
if ( auto_resume_time && (now.tv_sec >= auto_resume_time) ) { if ( auto_resume_time && (now.tv_sec >= auto_resume_time) ) {
Info( "Auto resuming at count %d", image_count ); Info("Auto resuming at count %d", image_count);
shared_data->active = true; shared_data->active = true;
ref_image = *snap_image; ref_image = *snap_image;
ready_count = image_count+(warmup_count/2); ready_count = image_count+(warmup_count/2);
auto_resume_time = 0; auto_resume_time = 0;
} }
static bool static_undef = true;
static int last_section_mod = 0; static int last_section_mod = 0;
static bool last_signal;
if ( static_undef ) {
// Sure would be nice to be able to assume that these were already initialized. It's just 1 compare/branch, but really not neccessary.
static_undef = false;
timestamps = new struct timeval *[pre_event_count];
images = new Image *[pre_event_count];
last_signal = shared_data->signal;
}
if ( Enabled() ) { if ( Enabled() ) {
bool signal = shared_data->signal; bool signal = shared_data->signal;
@ -1394,27 +1393,24 @@ bool Monitor::Analyse() {
} else if ( signal && Active() && (function == MODECT || function == MOCORD) ) { } else if ( signal && Active() && (function == MODECT || function == MOCORD) ) {
Event::StringSet zoneSet; Event::StringSet zoneSet;
int motion_score = last_motion_score;
if ( !(image_count % (motion_frame_skip+1) ) ) { if ( !(image_count % (motion_frame_skip+1) ) ) {
// Get new score. // Get new score.
motion_score = DetectMotion(*snap_image, zoneSet); int new_motion_score = DetectMotion(*snap_image, zoneSet);
Debug(3, Debug(3,
"After motion detection, last_motion_score(%d), new motion score(%d)", "After motion detection, last_motion_score(%d), new motion score(%d)",
last_motion_score, motion_score last_motion_score, new_motion_score
); );
// Why are we updating the last_motion_score too? last_motion_score = new_motion_score;
last_motion_score = motion_score;
} }
//int motion_score = DetectBlack( *snap_image, zoneSet ); if ( last_motion_score ) {
if ( motion_score ) {
if ( !event ) { if ( !event ) {
score += motion_score; score += last_motion_score;
if ( cause.length() ) if ( cause.length() )
cause += ", "; cause += ", ";
cause += MOTION_CAUSE; cause += MOTION_CAUSE;
} else { } else {
score += motion_score; score += last_motion_score;
} }
noteSetMap[MOTION_CAUSE] = zoneSet; noteSetMap[MOTION_CAUSE] = zoneSet;
} // end if motion_score } // end if motion_score
@ -1436,7 +1432,7 @@ bool Monitor::Analyse() {
first_link = false; first_link = false;
} }
} }
noteSet.insert( linked_monitors[i]->Name() ); noteSet.insert(linked_monitors[i]->Name());
score += 50; score += 50;
} }
} else { } else {
@ -1450,14 +1446,15 @@ bool Monitor::Analyse() {
//TODO: What happens is the event closes and sets recording to false then recording to true again so quickly that our capture daemon never picks it up. Maybe need a refresh flag? //TODO: What happens is the event closes and sets recording to false then recording to true again so quickly that our capture daemon never picks it up. Maybe need a refresh flag?
if ( (!signal_change && signal) && (function == RECORD || function == MOCORD) ) { if ( (!signal_change && signal) && (function == RECORD || function == MOCORD) ) {
if ( event ) { if ( event ) {
//TODO: We shouldn't have to do this every time. Not sure why it clears itself if this isn't here?? Debug(3, "Detected new event at (%d.%d)", timestamp->tv_sec, timestamp->tv_usec);
//snprintf(video_store_data->event_file, sizeof(video_store_data->event_file), "%s", event->getEventFile());
Debug( 3, "Detected new event at (%d.%d)", timestamp->tv_sec,timestamp->tv_usec );
if ( section_length && ( timestamp->tv_sec >= section_length ) ) { if ( section_length && ( timestamp->tv_sec >= section_length ) ) {
// TODO: Wouldn't this be clearer if we just did something like if now - event->start > section_length ? // TODO: Wouldn't this be clearer if we just did something like if now - event->start > section_length ?
int section_mod = timestamp->tv_sec % section_length; int section_mod = timestamp->tv_sec % section_length;
Debug( 3, "Section length (%d) Last Section Mod(%d), new section mod(%d)", section_length, last_section_mod, section_mod ); Debug(3,
"Section length (%d) Last Section Mod(%d), new section mod(%d)",
section_length, last_section_mod, section_mod
);
if ( section_mod < last_section_mod ) { if ( section_mod < last_section_mod ) {
//if ( state == IDLE || state == TAPE || event_close_mode == CLOSE_TIME ) { //if ( state == IDLE || state == TAPE || event_close_mode == CLOSE_TIME ) {
//if ( state == TAPE ) { //if ( state == TAPE ) {
@ -1480,7 +1477,7 @@ bool Monitor::Analyse() {
if ( ! event ) { if ( ! event ) {
// Create event // Create event
event = new Event( this, *timestamp, "Continuous", noteSetMap, videoRecording ); event = new Event(this, *timestamp, "Continuous", noteSetMap, videoRecording);
shared_data->last_event = event->Id(); shared_data->last_event = event->Id();
//set up video store data //set up video store data
snprintf(video_store_data->event_file, sizeof(video_store_data->event_file), "%s", event->getEventFile()); snprintf(video_store_data->event_file, sizeof(video_store_data->event_file), "%s", event->getEventFile());
@ -1554,6 +1551,10 @@ bool Monitor::Analyse() {
int pre_index; int pre_index;
int pre_event_images = pre_event_count; int pre_event_images = pre_event_count;
if ( event ) {
// SHouldn't be able to happen because
Error("Creating new event when one exists");
}
if ( analysis_fps && pre_event_count ) { if ( analysis_fps && pre_event_count ) {
// If analysis fps is set, // If analysis fps is set,
// compute the index for pre event images in the dedicated buffer // compute the index for pre event images in the dedicated buffer

View File

@ -288,6 +288,8 @@ protected:
Rgb signal_check_colour; // The colour that the camera will emit when no video signal detected Rgb signal_check_colour; // The colour that the camera will emit when no video signal detected
bool embed_exif; // Whether to embed Exif data into each image frame or not bool embed_exif; // Whether to embed Exif data into each image frame or not
bool last_signal;
double fps; double fps;
unsigned int last_camera_bytes; unsigned int last_camera_bytes;

View File

@ -58,7 +58,7 @@ public:
int Capture( Image &image ); int Capture( Image &image );
int PostCapture(); int PostCapture();
int CaptureAndRecord( Image &image, timeval recording, char* event_directory ) {return 0;}; int CaptureAndRecord( Image &image, timeval recording, char* event_directory ) {return 0;};
int Close() { return 0; }; int Close() { Disconnect(); return 0; };
}; };
#endif // ZM_REMOTE_CAMERA_HTTP_H #endif // ZM_REMOTE_CAMERA_HTTP_H

View File

@ -524,7 +524,10 @@ bool VideoStore::setup_resampler() {
audio_out_ctx->channels = audio_in_ctx->channels; audio_out_ctx->channels = audio_in_ctx->channels;
audio_out_ctx->channel_layout = audio_in_ctx->channel_layout; audio_out_ctx->channel_layout = audio_in_ctx->channel_layout;
audio_out_ctx->sample_fmt = audio_in_ctx->sample_fmt; audio_out_ctx->sample_fmt = audio_in_ctx->sample_fmt;
#if LIBAVCODEC_VERSION_CHECK(57, 64, 0, 64, 0)
#else
audio_out_ctx->refcounted_frames = 1; audio_out_ctx->refcounted_frames = 1;
#endif
if (audio_out_codec->supported_samplerates) { if (audio_out_codec->supported_samplerates) {
int found = 0; int found = 0;

View File

@ -268,17 +268,17 @@ function exportEventImages($event, $exportDetail, $exportFrames, $myfilelist) {
} else { // end if DefaultVideo } else { // end if DefaultVideo
?> ?>
<ilayer id="slidensmain" width=&{slidewidth}; height=&{slideheight}; bgColor=&{slidebgcolor}; visibility=hide> <ilayer id="slidensmain" width=&{slidewidth}; height=&{slideheight}; bgColor=&{slidebgcolor}; visibility=hide>
<layer id="slidenssub" width=&{slidewidth}; left=auto top=auto></layer> <layer id="slidenssub" width="&{slidewidth};" left="auto" top="auto"></layer>
</ilayer> </ilayer>
<div id="imagevideo" align="center"></div> <div id="imagevideo" align="center"></div>
<br> <br>
<div align="center"> <div align="center">
<button onclick="stepbackward()">&lt; Step</button> <button type="button" onclick="stepbackward()">&lt; Step</button>
<button id="btnrwd" onclick="rewind()" >Rwd</button> <button type="button" id="btnrwd" onclick="rewind()" >Rwd</button>
<button id="btnplay" onclick="playstop()">Stop</button> <button type="button" id="btnplay" onclick="playstop()">Stop</button>
<button onclick="stepforward()">Step &gt;</button> <button type="button" onclick="stepforward()">Step &gt;</button>
<button id="btnspeedup" onclick="speedup()">speedup</button> <button type="button" id="btnspeedup" onclick="speedup()">speedup</button>
<button id="btnspeeddown" onclick="speeddown()">slowdown</button> <button type="button" id="btnspeeddown" onclick="speeddown()">slowdown</button>
</div> </div>
<div align="center"><div class="horizontal_track" > <div align="center"><div class="horizontal_track" >
<div class="horizontal_slit" >&nbsp;</div> <div class="horizontal_slit" >&nbsp;</div>
@ -303,7 +303,7 @@ var variableslide=[<?php echo $slides?>];
//configure the below 3 variables to set the dimension/background color of the slideshow //configure the below 3 variables to set the dimension/background color of the slideshow
var slidewidth=eventWidth+'px'; //set to width of LARGEST image in your slideshow var slidewidth=eventWidth+'px'; //set to width of LARGEST image in your slideshow
var slideheight=eventHeight+'px'; //set to height of LARGEST iamge in your slideshow, plus any text description var slideheight=eventHeight+'px'; //set to height of LARGEST image in your slideshow, plus any text description
var slidebgcolor='#ffffff'; var slidebgcolor='#ffffff';
//configure the below variable to determine the delay between image rotations (in miliseconds) //configure the below variable to determine the delay between image rotations (in miliseconds)
@ -324,7 +324,7 @@ var currentslide = -1;
var mytimer = null; var mytimer = null;
//if (ie||dom) document.write('<div id="slidedom" style="width:'+slidewidth+'px;height:'+slideheight+'; background-color:'+slidebgcolor+'"></div>'); //if (ie||dom) document.write('<div id="slidedom" style="width:'+slidewidth+'px;height:'+slideheight+'; background-color:'+slidebgcolor+'"></div>');
if (ie||dom) document.getElementById('imagevideo').innerHTML = '<div id="slidedom" style="width:'+slidewidth+'px;height:'+slideheight+'; background-color:'+slidebgcolor+'"><img src="" name="imageslideframe"></div>'; if (ie||dom) document.getElementById('imagevideo').innerHTML = '<div id="slidedom" style="width:'+slidewidth+';height:'+slideheight+'; background-color:'+slidebgcolor+'"><img src="" name="imageslideframe"></div>';
function rotateimages(){ function rotateimages(){
if (currentslide==variableslide.length-1) currentslide=0; if (currentslide==variableslide.length-1) currentslide=0;
@ -378,7 +378,6 @@ function stepforward() {
else currentslide++; else currentslide++;
changeimage(); changeimage();
} }
function stepbackward() { function stepbackward() {
@ -867,11 +866,16 @@ function exportEvents(
} }
foreach ( $eids as $eid ) { foreach ( $eids as $eid ) {
$event = new Event($eid); $event = new Event($eid);
if ( !mkdir($export_dir.'/'.$event->Id()) ) $event_dir = $export_dir.'/'.$event->Id();
Error("Can't mkdir $export_dir/".$event->Id()); if ( !mkdir($event_dir) )
$exportFileList = array_merge($exportFileList, exportFileList($event, $exportDetail, $exportFrames, $exportImages, $exportVideo, $exportMisc)); Error("Can't mkdir $event_dir");
foreach ( $exportFileList as $file ) { $event_exportFileList = exportFileList($event, $exportDetail, $exportFrames, $exportImages, $exportVideo, $exportMisc);
exec('cp -as '.$event->Path().'/../'.$file." $export_dir/$file"); $exportFileList = array_merge($exportFileList,$event_exportFileList);
foreach ( $event_exportFileList as $file ) {
if ( preg_match('/\.html$/', $file ) )
continue;
Logger::Debug('cp -as '.$event->Path().'/../'.$file.' '.$export_dir.'/'.$file);
exec('cp -as '.$event->Path().'/../'.$file.' '.$export_dir.'/'.$file);
} }
} }
@ -905,11 +909,11 @@ function exportEvents(
fwrite($fp, "$listFile\n"); fwrite($fp, "$listFile\n");
fclose($fp); fclose($fp);
chdir(ZM_DIR_EXPORTS);
$archive = ''; $archive = '';
if ( $exportFormat == 'tar' ) { if ( $exportFormat == 'tar' ) {
$archive = ZM_DIR_EXPORTS.'/'.$export_root.($connkey?'_'.$connkey:'').'.tar.gz'; $archive = ZM_DIR_EXPORTS.'/'.$export_root.($connkey?'_'.$connkey:'').'.tar.gz';
@unlink($archive); @unlink($archive);
chdir(ZM_DIR_EXPORTS);
$command = 'nice -10 tar --create --gzip --dereference --file='.escapeshellarg($archive).' zmExport_'.$connkey.'/'; $command = 'nice -10 tar --create --gzip --dereference --file='.escapeshellarg($archive).' zmExport_'.$connkey.'/';
#$command = 'nice -10 tar --create --gzip --file='.escapeshellarg($archive).' --files-from='.escapeshellarg($listFile); #$command = 'nice -10 tar --create --gzip --file='.escapeshellarg($archive).' --files-from='.escapeshellarg($listFile);
if ( $exportStructure == 'flat' ) { if ( $exportStructure == 'flat' ) {
@ -920,17 +924,17 @@ function exportEvents(
$archive = ZM_DIR_EXPORTS.'/'.$export_root.($connkey?'_'.$connkey:'').'.zip'; $archive = ZM_DIR_EXPORTS.'/'.$export_root.($connkey?'_'.$connkey:'').'.zip';
@unlink($archive); @unlink($archive);
if ( $exportStructure == 'flat' ) { if ( $exportStructure == 'flat' ) {
$command = 'nice -10 zip -q -j '.escapeshellarg($archive).' ' . $export_dir; $command = 'nice -10 zip -j '.escapeshellarg($archive).' zmExport_'.$connkey.'/';
#$command = 'cat '.escapeshellarg($listFile).' | nice -10 zip -q -j '.escapeshellarg($archive).' -@'; #$command = 'cat '.escapeshellarg($listFile).' | nice -10 zip -q -j '.escapeshellarg($archive).' -@';
} else { } else {
$command = 'nice -10 zip -q '.escapeshellarg($archive).' ' . $export_dir; $command = 'nice -10 zip -r '.escapeshellarg($archive).' zmExport_' . $connkey.'/';
#$command = 'cat '.escapeshellarg($listFile).' | nice -10 zip -q '.escapeshellarg($archive).' -@'; #$command = 'cat '.escapeshellarg($listFile).' | nice -10 zip -q '.escapeshellarg($archive).' -@';
} }
} else { } else {
Error("No exportFormat specified."); Error("No exportFormat specified.");
return false; return false;
} // if $exportFormat } // if $exportFormat
Logger::Debug("Command is $command");
exec($command, $output, $status); exec($command, $output, $status);
if ( $status ) { if ( $status ) {
Error("Command '$command' returned with status $status"); Error("Command '$command' returned with status $status");

View File

@ -36,6 +36,12 @@ if ( isset($_SESSION['export']) ) {
$_REQUEST['exportMisc'] = $_SESSION['export']['misc']; $_REQUEST['exportMisc'] = $_SESSION['export']['misc'];
if ( isset($_SESSION['export']['format']) ) if ( isset($_SESSION['export']['format']) )
$_REQUEST['exportFormat'] = $_SESSION['export']['format']; $_REQUEST['exportFormat'] = $_SESSION['export']['format'];
} else {
$_REQUEST['exportDetail'] =
$_REQUEST['exportFrames'] =
$_REQUEST['exportImages'] =
$_REQUEST['exportVideo'] =
$_REQUEST['exportMisc'] = 1;
} }
$focusWindow = true; $focusWindow = true;