Merge branch 'master' into zma_to_thread
This commit is contained in:
commit
3641797500
|
@ -20,18 +20,16 @@ sub START {
|
||||||
sub Subscribe {
|
sub Subscribe {
|
||||||
my ($self, $body, $header) = @_;
|
my ($self, $body, $header) = @_;
|
||||||
die "Subscribe must be called as object method (\$self is <$self>)" if not blessed($self);
|
die "Subscribe must be called as object method (\$self is <$self>)" if not blessed($self);
|
||||||
|
#print " proxy/lib/WSNotification/Interfaces/WSBaseNotificationSender/NotificationProducerPort.pm Subscribe\n";
|
||||||
return $self->SUPER::call({
|
return $self->SUPER::call({
|
||||||
operation => 'Subscribe',
|
operation => 'Subscribe',
|
||||||
soap_action => 'http://docs.oasis-open.org/wsn/bw-2/Subscribe',
|
soap_action => 'http://docs.oasis-open.org/wsn/bw-2/Subscribe',
|
||||||
style => 'document',
|
style => 'document',
|
||||||
body => {
|
body => {
|
||||||
|
use => 'literal',
|
||||||
|
|
||||||
'use' => 'literal',
|
|
||||||
namespace => 'http://schemas.xmlsoap.org/wsdl/soap/',
|
namespace => 'http://schemas.xmlsoap.org/wsdl/soap/',
|
||||||
encodingStyle => '',
|
encodingStyle => '',
|
||||||
parts => [qw( WSNotification::Elements::Subscribe )],
|
parts => [qw( WSNotification::Elements::Subscribe )],
|
||||||
|
|
||||||
},
|
},
|
||||||
header => {
|
header => {
|
||||||
|
|
||||||
|
@ -42,7 +40,6 @@ sub Subscribe {
|
||||||
}, $body, $header);
|
}, $body, $header);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
sub GetCurrentMessage {
|
sub GetCurrentMessage {
|
||||||
my ($self, $body, $header) = @_;
|
my ($self, $body, $header) = @_;
|
||||||
die "GetCurrentMessage must be called as object method (\$self is <$self>)" if not blessed($self);
|
die "GetCurrentMessage must be called as object method (\$self is <$self>)" if not blessed($self);
|
||||||
|
@ -51,9 +48,7 @@ sub GetCurrentMessage {
|
||||||
soap_action => 'http://docs.oasis-open.org/wsn/bw-2/GetCurrentMessage',
|
soap_action => 'http://docs.oasis-open.org/wsn/bw-2/GetCurrentMessage',
|
||||||
style => 'document',
|
style => 'document',
|
||||||
body => {
|
body => {
|
||||||
|
use => 'literal',
|
||||||
|
|
||||||
'use' => 'literal',
|
|
||||||
namespace => 'http://schemas.xmlsoap.org/wsdl/soap/',
|
namespace => 'http://schemas.xmlsoap.org/wsdl/soap/',
|
||||||
encodingStyle => '',
|
encodingStyle => '',
|
||||||
parts => [qw( WSNotification::Elements::GetCurrentMessage )],
|
parts => [qw( WSNotification::Elements::GetCurrentMessage )],
|
||||||
|
@ -68,13 +63,7 @@ sub GetCurrentMessage {
|
||||||
}, $body, $header);
|
}, $body, $header);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
1;
|
1;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
__END__
|
__END__
|
||||||
|
|
||||||
=pod
|
=pod
|
||||||
|
|
111
src/zm_event.cpp
111
src/zm_event.cpp
|
@ -91,7 +91,7 @@ Event::Event(
|
||||||
"INSERT INTO `Events` "
|
"INSERT INTO `Events` "
|
||||||
"( `MonitorId`, `StorageId`, `Name`, `StartTime`, `Width`, `Height`, `Cause`, `Notes`, `StateId`, `Orientation`, `Videoed`, `DefaultVideo`, `SaveJPEGs`, `Scheme` )"
|
"( `MonitorId`, `StorageId`, `Name`, `StartTime`, `Width`, `Height`, `Cause`, `Notes`, `StateId`, `Orientation`, `Videoed`, `DefaultVideo`, `SaveJPEGs`, `Scheme` )"
|
||||||
" VALUES "
|
" VALUES "
|
||||||
"( %d, %d, 'New Event', from_unixtime( %ld ), %d, %d, '%s', '%s', %d, %d, %d, '', %d, '%s' )",
|
"( %d, %d, 'New Event', from_unixtime( %ld ), %d, %d, '%s', '%s', %d, %d, %d, '%s', %d, '%s' )",
|
||||||
monitor->Id(),
|
monitor->Id(),
|
||||||
storage->Id(),
|
storage->Id(),
|
||||||
start_time.tv_sec,
|
start_time.tv_sec,
|
||||||
|
@ -102,6 +102,7 @@ Event::Event(
|
||||||
state_id,
|
state_id,
|
||||||
monitor->getOrientation(),
|
monitor->getOrientation(),
|
||||||
( monitor->GetOptVideoWriter() != 0 ? 1 : 0 ),
|
( monitor->GetOptVideoWriter() != 0 ? 1 : 0 ),
|
||||||
|
( monitor->GetOptVideoWriter() != 0 ? "video.mp4" : "" ),
|
||||||
monitor->GetOptSaveJPEGs(),
|
monitor->GetOptSaveJPEGs(),
|
||||||
storage->SchemeString().c_str()
|
storage->SchemeString().c_str()
|
||||||
);
|
);
|
||||||
|
@ -113,23 +114,7 @@ Event::Event(
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
id = mysql_insert_id(&dbconn);
|
id = mysql_insert_id(&dbconn);
|
||||||
//
|
|
||||||
|
|
||||||
/* Update event record with DefaultVideo name if possible so image.php can extract frames
|
|
||||||
if needed, while recording is in progress */
|
|
||||||
if ( monitor->GetOptVideoWriter() != 0 ) {
|
|
||||||
video_name[0] = 0;
|
|
||||||
snprintf(video_name, sizeof(video_name), "%" PRIu64 "-%s", id, "video.mp4");
|
|
||||||
Debug(1, "Updating inserted event with DefaultVideo=%s",video_name);
|
|
||||||
snprintf(sql, sizeof(sql), "UPDATE Events SET DefaultVideo = '%s' WHERE Id=%" PRIu64, video_name,id);
|
|
||||||
if ( mysql_query(&dbconn, sql) ) {
|
|
||||||
Error("Can't update event: %s. sql was (%s)", mysql_error(&dbconn), sql);
|
|
||||||
db_mutex.unlock();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
Debug (1, "GetOptVideoWriter() returned 0, not updating DefaultVideo");
|
|
||||||
}
|
|
||||||
db_mutex.unlock();
|
db_mutex.unlock();
|
||||||
if ( untimedEvent ) {
|
if ( untimedEvent ) {
|
||||||
Warning("Event %d has zero time, setting to current", id);
|
Warning("Event %d has zero time, setting to current", id);
|
||||||
|
@ -143,12 +128,13 @@ Event::Event(
|
||||||
alarm_frame_written = false;
|
alarm_frame_written = false;
|
||||||
|
|
||||||
struct tm *stime = localtime(&start_time.tv_sec);
|
struct tm *stime = localtime(&start_time.tv_sec);
|
||||||
|
std::string id_file;
|
||||||
|
|
||||||
path = stringtf("%s/%d", storage->Path(), monitor->Id());
|
path = stringtf("%s/%d", storage->Path(), monitor->Id());
|
||||||
// Try to make the Monitor Dir. Normally this would exist, but in odd cases might not.
|
// Try to make the Monitor Dir. Normally this would exist, but in odd cases might not.
|
||||||
if ( mkdir(path.c_str(), 0755) ) {
|
if ( mkdir(path.c_str(), 0755) ) {
|
||||||
if ( errno != EEXIST )
|
if ( errno != EEXIST )
|
||||||
Error("Can't mkdir %s: %s", path, strerror(errno));
|
Error("Can't mkdir %s: %s", path.c_str(), strerror(errno));
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( storage->Scheme() == Storage::DEEP ) {
|
if ( storage->Scheme() == Storage::DEEP ) {
|
||||||
|
@ -160,27 +146,26 @@ Event::Event(
|
||||||
dt_parts[4] = stime->tm_min;
|
dt_parts[4] = stime->tm_min;
|
||||||
dt_parts[5] = stime->tm_sec;
|
dt_parts[5] = stime->tm_sec;
|
||||||
|
|
||||||
char date_path[PATH_MAX] = "";
|
std::string date_path;
|
||||||
char time_path[PATH_MAX] = "";
|
std::string time_path;
|
||||||
char *time_path_ptr = time_path;
|
|
||||||
for ( unsigned int i = 0; i < sizeof(dt_parts)/sizeof(*dt_parts); i++ ) {
|
for ( unsigned int i = 0; i < sizeof(dt_parts)/sizeof(*dt_parts); i++ ) {
|
||||||
path += stringtf("/%02d", dt_parts[i]);
|
path += stringtf("/%02d", dt_parts[i]);
|
||||||
|
|
||||||
errno = 0;
|
|
||||||
if ( mkdir(path.c_str(), 0755) ) {
|
if ( mkdir(path.c_str(), 0755) ) {
|
||||||
// FIXME This should not be fatal. Should probably move to a different storage area.
|
// FIXME This should not be fatal. Should probably move to a different storage area.
|
||||||
if ( errno != EEXIST )
|
if ( errno != EEXIST )
|
||||||
Error("Can't mkdir %s: %s", path.c_str(), strerror(errno));
|
Error("Can't mkdir %s: %s", path.c_str(), strerror(errno));
|
||||||
}
|
}
|
||||||
if ( i == 2 )
|
if ( i == 2 )
|
||||||
strncpy(date_path, path.c_str(), sizeof(date_path));
|
date_path = path;
|
||||||
else if ( i >= 3 )
|
|
||||||
time_path_ptr += snprintf(time_path_ptr, sizeof(time_path)-(time_path_ptr-time_path), "%s%02d", i>3?"/":"", dt_parts[i]);
|
|
||||||
}
|
}
|
||||||
|
time_path = stringtf("%02d/%02d/%02d", stime->tm_hour, stime->tm_min, stime->tm_sec);
|
||||||
|
|
||||||
// Create event id symlink
|
// Create event id symlink
|
||||||
std::string id_file = stringtf("%s/.%" PRIu64, date_path, id);
|
id_file = stringtf("%s/.%" PRIu64, date_path.c_str(), id);
|
||||||
if ( symlink(time_path, id_file.c_str()) < 0 )
|
if ( symlink(time_path.c_str(), id_file.c_str()) < 0 )
|
||||||
Error("Can't symlink %s -> %s: %s", id_file.c_str(), path.c_str(), strerror(errno));
|
Error("Can't symlink %s -> %s: %s", id_file.c_str(), time_path.c_str(), strerror(errno));
|
||||||
} else if ( storage->Scheme() == Storage::MEDIUM ) {
|
} else if ( storage->Scheme() == Storage::MEDIUM ) {
|
||||||
path += stringtf("/%04d-%02d-%02d",
|
path += stringtf("/%04d-%02d-%02d",
|
||||||
stime->tm_year+1900, stime->tm_mon+1, stime->tm_mday
|
stime->tm_year+1900, stime->tm_mon+1, stime->tm_mday
|
||||||
|
@ -202,18 +187,19 @@ Event::Event(
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create empty id tag file
|
// Create empty id tag file
|
||||||
std::string id_file = stringtf("%s/.%" PRIu64, path.c_str(), id);
|
id_file = stringtf("%s/.%" PRIu64, path.c_str(), id);
|
||||||
if ( FILE *id_fp = fopen(id_file.c_str(), "w") )
|
if ( FILE *id_fp = fopen(id_file.c_str(), "w") ) {
|
||||||
fclose(id_fp);
|
fclose(id_fp);
|
||||||
else
|
} else {
|
||||||
Error("Can't fopen %s: %s", id_file.c_str(), strerror(errno));
|
Error("Can't fopen %s: %s", id_file.c_str(), strerror(errno));
|
||||||
|
}
|
||||||
} // deep storage or not
|
} // deep storage or not
|
||||||
|
|
||||||
Debug(2, "Created event %d at %s", id, path.c_str());
|
Debug(2, "Created event %d at %s", id, path.c_str());
|
||||||
|
|
||||||
last_db_frame = 0;
|
last_db_frame = 0;
|
||||||
|
|
||||||
video_name[0] = 0;
|
video_name = "";
|
||||||
|
|
||||||
snapshot_file = path + "/snapshot.jpg";
|
snapshot_file = path + "/snapshot.jpg";
|
||||||
alarm_file = path + "/alarm.jpg";
|
alarm_file = path + "/alarm.jpg";
|
||||||
|
@ -221,7 +207,6 @@ Event::Event(
|
||||||
/* Save as video */
|
/* Save as video */
|
||||||
|
|
||||||
if ( monitor->GetOptVideoWriter() != 0 ) {
|
if ( monitor->GetOptVideoWriter() != 0 ) {
|
||||||
Debug(2,"Video writer was %d", monitor->GetOptVideoWriter());
|
|
||||||
std::string container = monitor->OutputContainer();
|
std::string container = monitor->OutputContainer();
|
||||||
if ( container == "auto" || container == "" ) {
|
if ( container == "auto" || container == "" ) {
|
||||||
if ( monitor->OutputCodec() == AV_CODEC_ID_H264 ) {
|
if ( monitor->OutputCodec() == AV_CODEC_ID_H264 ) {
|
||||||
|
@ -231,33 +216,37 @@ Event::Event(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
snprintf(video_name, sizeof(video_name), "%" PRIu64 "-%s.%s", id, "video", container.c_str());
|
video_name = stringtf("%" PRIu64 "-%s.%s", id, "video", container.c_str());
|
||||||
snprintf(video_file, sizeof(video_file), staticConfig.video_file_format, path.c_str(), video_name);
|
snprintf(sql, sizeof(sql), "UPDATE Events SET DefaultVideo = '%s' WHERE Id=%" PRIu64, video_name.c_str(), id);
|
||||||
Debug(1,"Writing video file to %s", video_file);
|
if ( mysql_query(&dbconn, sql) ) {
|
||||||
|
Error("Can't update event: %s. sql was (%s)", mysql_error(&dbconn), sql);
|
||||||
|
db_mutex.unlock();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
video_file = path + "/" + video_name;
|
||||||
|
Debug(1,"Writing video file to %s", video_file.c_str());
|
||||||
Camera * camera = monitor->getCamera();
|
Camera * camera = monitor->getCamera();
|
||||||
videoStore = new VideoStore(
|
videoStore = new VideoStore(
|
||||||
video_file,
|
video_file.c_str(),
|
||||||
container.c_str(),
|
container.c_str(),
|
||||||
camera->get_VideoStream(),
|
camera->get_VideoStream(),
|
||||||
( monitor->RecordAudio() ? camera->get_AudioStream() : NULL ),
|
( monitor->RecordAudio() ? camera->get_AudioStream() : NULL ),
|
||||||
monitor );
|
monitor );
|
||||||
|
|
||||||
if ( ! videoStore->open() ) {
|
if ( !videoStore->open() ) {
|
||||||
delete videoStore;
|
delete videoStore;
|
||||||
videoStore = NULL;
|
videoStore = NULL;
|
||||||
save_jpegs |= 1; // Turn on jpeg storage
|
save_jpegs |= 1; // Turn on jpeg storage
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} // Event::Event( Monitor *p_monitor, struct timeval p_start_time, const std::string &p_cause, const StringSetMap &p_noteSetMap, bool p_videoEvent )
|
} // Event::Event( Monitor *p_monitor, struct timeval p_start_time, const std::string &p_cause, const StringSetMap &p_noteSetMap, bool p_videoEvent )
|
||||||
|
|
||||||
Event::~Event() {
|
Event::~Event() {
|
||||||
|
|
||||||
// We close the videowriter first, because if we finish the event, we might try to view the file, but we aren't done writing it yet.
|
// We close the videowriter first, because if we finish the event, we might try to view the file, but we aren't done writing it yet.
|
||||||
|
|
||||||
/* Close the video file */
|
/* Close the video file */
|
||||||
if ( videoStore ) {
|
if ( videoStore ) {
|
||||||
Debug(2,"Deleting video store");
|
Debug(2, "Deleting video store");
|
||||||
delete videoStore;
|
delete videoStore;
|
||||||
videoStore = NULL;
|
videoStore = NULL;
|
||||||
}
|
}
|
||||||
|
@ -279,13 +268,12 @@ Event::~Event() {
|
||||||
// update frame deltas to refer to video start time which may be a few frames before event start
|
// update frame deltas to refer to video start time which may be a few frames before event start
|
||||||
struct timeval video_offset = {0};
|
struct timeval video_offset = {0};
|
||||||
struct timeval video_start_time = monitor->GetVideoWriterStartTime();
|
struct timeval video_start_time = monitor->GetVideoWriterStartTime();
|
||||||
if (video_start_time.tv_sec > 0) {
|
if ( video_start_time.tv_sec > 0 ) {
|
||||||
timersub(&video_start_time, &start_time, &video_offset);
|
timersub(&video_start_time, &start_time, &video_offset);
|
||||||
Debug(1, "Updating frames delta by %d sec %d usec",
|
Debug(1, "Updating frames delta by %d sec %d usec",
|
||||||
video_offset.tv_sec, video_offset.tv_usec);
|
video_offset.tv_sec, video_offset.tv_usec);
|
||||||
UpdateFramesDelta(video_offset.tv_sec + video_offset.tv_usec*1e-6);
|
UpdateFramesDelta(video_offset.tv_sec + video_offset.tv_usec*1e-6);
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
Debug(3, "Video start_time %d sec %d usec not valid -- frame deltas not updated",
|
Debug(3, "Video start_time %d sec %d usec not valid -- frame deltas not updated",
|
||||||
video_start_time.tv_sec, video_start_time.tv_usec);
|
video_start_time.tv_sec, video_start_time.tv_usec);
|
||||||
}
|
}
|
||||||
|
@ -293,12 +281,12 @@ Event::~Event() {
|
||||||
// Should not be static because we might be multi-threaded
|
// Should not be static because we might be multi-threaded
|
||||||
char sql[ZM_SQL_LGE_BUFSIZ];
|
char sql[ZM_SQL_LGE_BUFSIZ];
|
||||||
snprintf(sql, sizeof(sql),
|
snprintf(sql, sizeof(sql),
|
||||||
"UPDATE Events SET Name='%s %" PRIu64 "', EndTime = from_unixtime( %ld ), Length = %s%ld.%02ld, Frames = %d, AlarmFrames = %d, TotScore = %d, AvgScore = %d, MaxScore = %d, DefaultVideo = '%s' WHERE Id = %" PRIu64,
|
"UPDATE Events SET Name='%s %" PRIu64 "', EndTime = from_unixtime(%ld), Length = %s%ld.%02ld, Frames = %d, AlarmFrames = %d, TotScore = %d, AvgScore = %d, MaxScore = %d WHERE Id = %" PRIu64,
|
||||||
monitor->EventPrefix(), id, end_time.tv_sec,
|
monitor->EventPrefix(), id, end_time.tv_sec,
|
||||||
delta_time.positive?"":"-", delta_time.sec, delta_time.fsec,
|
delta_time.positive?"":"-", delta_time.sec, delta_time.fsec,
|
||||||
frames, alarm_frames,
|
frames, alarm_frames,
|
||||||
tot_score, (int)(alarm_frames?(tot_score/alarm_frames):0), max_score,
|
tot_score, (int)(alarm_frames?(tot_score/alarm_frames):0), max_score,
|
||||||
video_name, id );
|
id);
|
||||||
db_mutex.lock();
|
db_mutex.lock();
|
||||||
while ( mysql_query(&dbconn, sql) && !zm_terminate ) {
|
while ( mysql_query(&dbconn, sql) && !zm_terminate ) {
|
||||||
db_mutex.unlock();
|
db_mutex.unlock();
|
||||||
|
@ -307,7 +295,6 @@ Event::~Event() {
|
||||||
db_mutex.lock();
|
db_mutex.lock();
|
||||||
}
|
}
|
||||||
db_mutex.unlock();
|
db_mutex.unlock();
|
||||||
|
|
||||||
} // Event::~Event()
|
} // Event::~Event()
|
||||||
|
|
||||||
void Event::createNotes(std::string ¬es) {
|
void Event::createNotes(std::string ¬es) {
|
||||||
|
@ -336,7 +323,7 @@ bool Event::WriteFrameImage(
|
||||||
|
|
||||||
int thisquality =
|
int thisquality =
|
||||||
(alarm_frame && (config.jpeg_alarm_file_quality > config.jpeg_file_quality)) ?
|
(alarm_frame && (config.jpeg_alarm_file_quality > config.jpeg_file_quality)) ?
|
||||||
config.jpeg_alarm_file_quality : 0 ; // quality to use, zero is default
|
config.jpeg_alarm_file_quality : 0; // quality to use, zero is default
|
||||||
|
|
||||||
bool rc;
|
bool rc;
|
||||||
|
|
||||||
|
@ -493,10 +480,9 @@ void Event::AddFramesInternal(int n_frames, int start_frame, Image **images, str
|
||||||
frames++;
|
frames++;
|
||||||
|
|
||||||
if ( save_jpegs & 1 ) {
|
if ( save_jpegs & 1 ) {
|
||||||
static char event_file[PATH_MAX];
|
std::string event_file = stringtf(staticConfig.capture_file_format, path.c_str(), frames);
|
||||||
snprintf(event_file, sizeof(event_file), staticConfig.capture_file_format, path.c_str(), frames);
|
|
||||||
Debug(1, "Writing pre-capture frame %d", frames);
|
Debug(1, "Writing pre-capture frame %d", frames);
|
||||||
WriteFrameImage(images[i], *(timestamps[i]), event_file);
|
WriteFrameImage(images[i], *(timestamps[i]), event_file.c_str());
|
||||||
}
|
}
|
||||||
//If this is the first frame, we should add a thumbnail to the event directory
|
//If this is the first frame, we should add a thumbnail to the event directory
|
||||||
// ICON: We are working through the pre-event frames so this snapshot won't
|
// ICON: We are working through the pre-event frames so this snapshot won't
|
||||||
|
@ -588,14 +574,14 @@ void Event::WriteDbFrames() {
|
||||||
void Event::UpdateFramesDelta(double offset) {
|
void Event::UpdateFramesDelta(double offset) {
|
||||||
char sql[ZM_SQL_MED_BUFSIZ];
|
char sql[ZM_SQL_MED_BUFSIZ];
|
||||||
|
|
||||||
if (offset == 0.0) return;
|
if ( offset == 0.0 ) return;
|
||||||
// the table is set to auto update timestamp so we force it to keep current value
|
// the table is set to auto update timestamp so we force it to keep current value
|
||||||
snprintf(sql, sizeof(sql),
|
snprintf(sql, sizeof(sql),
|
||||||
"UPDATE Frames SET timestamp = timestamp, Delta = Delta - (%.4f) WHERE EventId = %" PRIu64,
|
"UPDATE Frames SET timestamp = timestamp, Delta = Delta - (%.4f) WHERE EventId = %" PRIu64,
|
||||||
offset, id);
|
offset, id);
|
||||||
|
|
||||||
db_mutex.lock();
|
db_mutex.lock();
|
||||||
if (mysql_query(&dbconn, sql)) {
|
if ( mysql_query(&dbconn, sql) ) {
|
||||||
db_mutex.unlock();
|
db_mutex.unlock();
|
||||||
Error("Can't update frames: %s, sql was %s", mysql_error(&dbconn), sql);
|
Error("Can't update frames: %s, sql was %s", mysql_error(&dbconn), sql);
|
||||||
return;
|
return;
|
||||||
|
@ -604,7 +590,6 @@ void Event::UpdateFramesDelta(double offset) {
|
||||||
Info("Updating frames delta by %0.2f sec to match video file", offset);
|
Info("Updating frames delta by %0.2f sec to match video file", offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Event::AddFrame(Image *image, struct timeval timestamp, int score, Image *alarm_image) {
|
void Event::AddFrame(Image *image, struct timeval timestamp, int score, Image *alarm_image) {
|
||||||
if ( !timestamp.tv_sec ) {
|
if ( !timestamp.tv_sec ) {
|
||||||
Debug(1, "Not adding new frame, zero timestamp");
|
Debug(1, "Not adding new frame, zero timestamp");
|
||||||
|
@ -616,10 +601,9 @@ void Event::AddFrame(Image *image, struct timeval timestamp, int score, Image *a
|
||||||
bool write_to_db = false;
|
bool write_to_db = false;
|
||||||
|
|
||||||
if ( save_jpegs & 1 ) {
|
if ( save_jpegs & 1 ) {
|
||||||
static char event_file[PATH_MAX];
|
std::string event_file = stringtf(staticConfig.capture_file_format, path.c_str(), frames);
|
||||||
snprintf(event_file, sizeof(event_file), staticConfig.capture_file_format, path, frames);
|
Debug(1, "Writing capture frame %d to %s", frames, event_file.c_str());
|
||||||
Debug(1, "Writing capture frame %d to %s", frames, event_file);
|
if ( !WriteFrameImage(image, timestamp, event_file.c_str()) ) {
|
||||||
if ( !WriteFrameImage(image, timestamp, event_file) ) {
|
|
||||||
Error("Failed to write frame image");
|
Error("Failed to write frame image");
|
||||||
}
|
}
|
||||||
} // end if save_jpegs
|
} // end if save_jpegs
|
||||||
|
@ -651,10 +635,9 @@ void Event::AddFrame(Image *image, struct timeval timestamp, int score, Image *a
|
||||||
|
|
||||||
if ( alarm_image ) {
|
if ( alarm_image ) {
|
||||||
if ( save_jpegs & 2 ) {
|
if ( save_jpegs & 2 ) {
|
||||||
static char event_file[PATH_MAX];
|
std::string event_file = stringtf(staticConfig.analyse_file_format, path.c_str(), frames);
|
||||||
snprintf(event_file, sizeof(event_file), staticConfig.analyse_file_format, path.c_str(), frames);
|
|
||||||
Debug(1, "Writing analysis frame %d", frames);
|
Debug(1, "Writing analysis frame %d", frames);
|
||||||
if ( ! WriteFrameImage(alarm_image, timestamp, event_file, true) ) {
|
if ( ! WriteFrameImage(alarm_image, timestamp, event_file.c_str(), true) ) {
|
||||||
Error("Failed to write analysis frame image");
|
Error("Failed to write analysis frame image");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -670,10 +653,12 @@ void Event::AddFrame(Image *image, struct timeval timestamp, int score, Image *a
|
||||||
|
|
||||||
// The idea is to write out 1/sec
|
// The idea is to write out 1/sec
|
||||||
frame_data.push(new Frame(id, frames, frame_type, timestamp, delta_time, score));
|
frame_data.push(new Frame(id, frames, frame_type, timestamp, delta_time, score));
|
||||||
if ( write_to_db || (frame_data.size() > (int)monitor->get_capture_fps()) ) {
|
if ( write_to_db || (frame_data.size() > (unsigned int)monitor->get_capture_fps()) ) {
|
||||||
Debug(1, "Adding %d frames to DB", frame_data.size());
|
Debug(1, "Adding %d frames to DB because write_to_db:%d or frames > fps %d",
|
||||||
|
frame_data.size(), write_to_db, (unsigned int)monitor->get_capture_fps());
|
||||||
WriteDbFrames();
|
WriteDbFrames();
|
||||||
last_db_frame = frames;
|
last_db_frame = frames;
|
||||||
|
Debug(1, "Adding %d frames to DB, done", frame_data.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
// We are writing a Bulk frame
|
// We are writing a Bulk frame
|
||||||
|
|
|
@ -96,8 +96,8 @@ class Event {
|
||||||
VideoStore *videoStore;
|
VideoStore *videoStore;
|
||||||
|
|
||||||
VideoWriter* videowriter;
|
VideoWriter* videowriter;
|
||||||
char video_name[PATH_MAX];
|
std::string video_name;
|
||||||
char video_file[PATH_MAX];
|
std::string video_file;
|
||||||
int last_db_frame;
|
int last_db_frame;
|
||||||
bool have_video_keyframe; // a flag to tell us if we have had a video keyframe when writing an mp4. The first frame SHOULD be a video keyframe.
|
bool have_video_keyframe; // a flag to tell us if we have had a video keyframe when writing an mp4. The first frame SHOULD be a video keyframe.
|
||||||
Storage::Schemes scheme;
|
Storage::Schemes scheme;
|
||||||
|
@ -140,15 +140,15 @@ class Event {
|
||||||
public:
|
public:
|
||||||
static const char *getSubPath( struct tm *time ) {
|
static const char *getSubPath( struct tm *time ) {
|
||||||
static char subpath[PATH_MAX] = "";
|
static char subpath[PATH_MAX] = "";
|
||||||
snprintf( subpath, sizeof(subpath), "%02d/%02d/%02d/%02d/%02d/%02d", time->tm_year-100, time->tm_mon+1, time->tm_mday, time->tm_hour, time->tm_min, time->tm_sec );
|
snprintf(subpath, sizeof(subpath), "%02d/%02d/%02d/%02d/%02d/%02d", time->tm_year-100, time->tm_mon+1, time->tm_mday, time->tm_hour, time->tm_min, time->tm_sec);
|
||||||
return( subpath );
|
return subpath;
|
||||||
}
|
}
|
||||||
static const char *getSubPath( time_t *time ) {
|
static const char *getSubPath( time_t *time ) {
|
||||||
return Event::getSubPath( localtime( time ) );
|
return Event::getSubPath( localtime( time ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
char* getEventFile(void) {
|
const char* getEventFile(void) {
|
||||||
return video_file;
|
return video_file.c_str();
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -156,27 +156,36 @@ class Event {
|
||||||
return pre_alarm_count;
|
return pre_alarm_count;
|
||||||
}
|
}
|
||||||
static void EmptyPreAlarmFrames() {
|
static void EmptyPreAlarmFrames() {
|
||||||
if ( pre_alarm_count > 0 ) {
|
while ( pre_alarm_count > 0 ) {
|
||||||
for ( int i = 0; i < MAX_PRE_ALARM_FRAMES; i++ ) {
|
int i = pre_alarm_count - 1;
|
||||||
|
Debug(1, "EmptyreAlarmFrame: %d", i);
|
||||||
delete pre_alarm_data[i].image;
|
delete pre_alarm_data[i].image;
|
||||||
|
pre_alarm_data[i].image = NULL;
|
||||||
|
if ( pre_alarm_data[i].alarm_frame ) {
|
||||||
delete pre_alarm_data[i].alarm_frame;
|
delete pre_alarm_data[i].alarm_frame;
|
||||||
|
pre_alarm_data[i].alarm_frame = NULL;
|
||||||
}
|
}
|
||||||
memset( pre_alarm_data, 0, sizeof(pre_alarm_data) );
|
pre_alarm_count--;
|
||||||
}
|
}
|
||||||
pre_alarm_count = 0;
|
pre_alarm_count = 0;
|
||||||
}
|
}
|
||||||
static void AddPreAlarmFrame( Image *image, struct timeval timestamp, int score=0, Image *alarm_frame=NULL ) {
|
static void AddPreAlarmFrame(Image *image, struct timeval timestamp, int score=0, Image *alarm_frame=NULL) {
|
||||||
pre_alarm_data[pre_alarm_count].image = new Image( *image );
|
pre_alarm_data[pre_alarm_count].image = new Image(*image);
|
||||||
pre_alarm_data[pre_alarm_count].timestamp = timestamp;
|
pre_alarm_data[pre_alarm_count].timestamp = timestamp;
|
||||||
pre_alarm_data[pre_alarm_count].score = score;
|
pre_alarm_data[pre_alarm_count].score = score;
|
||||||
if ( alarm_frame ) {
|
if ( alarm_frame ) {
|
||||||
pre_alarm_data[pre_alarm_count].alarm_frame = new Image( *alarm_frame );
|
pre_alarm_data[pre_alarm_count].alarm_frame = new Image(*alarm_frame);
|
||||||
}
|
}
|
||||||
pre_alarm_count++;
|
pre_alarm_count++;
|
||||||
}
|
}
|
||||||
void SavePreAlarmFrames() {
|
void SavePreAlarmFrames() {
|
||||||
|
Debug(1, "SavePreAlarmFrame: %d", pre_alarm_count);
|
||||||
for ( int i = 0; i < pre_alarm_count; i++ ) {
|
for ( int i = 0; i < pre_alarm_count; i++ ) {
|
||||||
AddFrame( pre_alarm_data[i].image, pre_alarm_data[i].timestamp, pre_alarm_data[i].score, pre_alarm_data[i].alarm_frame );
|
AddFrame(
|
||||||
|
pre_alarm_data[i].image,
|
||||||
|
pre_alarm_data[i].timestamp,
|
||||||
|
pre_alarm_data[i].score,
|
||||||
|
pre_alarm_data[i].alarm_frame);
|
||||||
}
|
}
|
||||||
EmptyPreAlarmFrames();
|
EmptyPreAlarmFrames();
|
||||||
}
|
}
|
||||||
|
|
|
@ -270,28 +270,20 @@ Image::~Image() {
|
||||||
/* Should be called as part of program shutdown to free everything */
|
/* Should be called as part of program shutdown to free everything */
|
||||||
void Image::Deinitialise() {
|
void Image::Deinitialise() {
|
||||||
if ( !initialised ) return;
|
if ( !initialised ) return;
|
||||||
/*
|
|
||||||
delete[] y_table;
|
|
||||||
delete[] uv_table;
|
|
||||||
delete[] r_v_table;
|
|
||||||
delete[] g_v_table;
|
|
||||||
delete[] g_u_table;
|
|
||||||
delete[] b_u_table;
|
|
||||||
*/
|
|
||||||
initialised = false;
|
initialised = false;
|
||||||
if ( readjpg_dcinfo ) {
|
if ( readjpg_dcinfo ) {
|
||||||
jpeg_destroy_decompress( readjpg_dcinfo );
|
jpeg_destroy_decompress(readjpg_dcinfo);
|
||||||
delete readjpg_dcinfo;
|
delete readjpg_dcinfo;
|
||||||
readjpg_dcinfo = 0;
|
readjpg_dcinfo = NULL;
|
||||||
}
|
}
|
||||||
if ( decodejpg_dcinfo ) {
|
if ( decodejpg_dcinfo ) {
|
||||||
jpeg_destroy_decompress( decodejpg_dcinfo );
|
jpeg_destroy_decompress(decodejpg_dcinfo);
|
||||||
delete decodejpg_dcinfo;
|
delete decodejpg_dcinfo;
|
||||||
decodejpg_dcinfo = 0;
|
decodejpg_dcinfo = NULL;
|
||||||
}
|
}
|
||||||
for ( unsigned int quality=0; quality <= 100; quality += 1 ) {
|
for ( unsigned int quality=0; quality <= 100; quality += 1 ) {
|
||||||
if ( writejpg_ccinfo[quality] ) {
|
if ( writejpg_ccinfo[quality] ) {
|
||||||
jpeg_destroy_compress( writejpg_ccinfo[quality] );
|
jpeg_destroy_compress(writejpg_ccinfo[quality]);
|
||||||
delete writejpg_ccinfo[quality];
|
delete writejpg_ccinfo[quality];
|
||||||
writejpg_ccinfo[quality] = NULL;
|
writejpg_ccinfo[quality] = NULL;
|
||||||
}
|
}
|
||||||
|
@ -993,14 +985,12 @@ bool Image::WriteJpeg(const char *filename, int quality_override, struct timeval
|
||||||
struct jpeg_compress_struct *cinfo = writejpg_ccinfo[quality];
|
struct jpeg_compress_struct *cinfo = writejpg_ccinfo[quality];
|
||||||
FILE *outfile = NULL;
|
FILE *outfile = NULL;
|
||||||
static int raw_fd = 0;
|
static int raw_fd = 0;
|
||||||
bool need_create_comp = false;
|
|
||||||
raw_fd = 0;
|
raw_fd = 0;
|
||||||
|
|
||||||
if ( !cinfo ) {
|
if ( !cinfo ) {
|
||||||
cinfo = writejpg_ccinfo[quality] = new jpeg_compress_struct;
|
cinfo = writejpg_ccinfo[quality] = new jpeg_compress_struct;
|
||||||
cinfo->err = jpeg_std_error(&jpg_err.pub);
|
cinfo->err = jpeg_std_error(&jpg_err.pub);
|
||||||
jpeg_create_compress(cinfo);
|
jpeg_create_compress(cinfo);
|
||||||
need_create_comp = true;
|
|
||||||
}
|
}
|
||||||
if ( !on_blocking_abort ) {
|
if ( !on_blocking_abort ) {
|
||||||
jpg_err.pub.error_exit = zm_jpeg_error_exit;
|
jpg_err.pub.error_exit = zm_jpeg_error_exit;
|
||||||
|
@ -1018,8 +1008,6 @@ bool Image::WriteJpeg(const char *filename, int quality_override, struct timeval
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ( need_create_comp )
|
|
||||||
jpeg_create_compress(cinfo);
|
|
||||||
|
|
||||||
if ( !on_blocking_abort ) {
|
if ( !on_blocking_abort ) {
|
||||||
if ( (outfile = fopen(filename, "wb")) == NULL ) {
|
if ( (outfile = fopen(filename, "wb")) == NULL ) {
|
||||||
|
@ -2842,7 +2830,6 @@ void Image::Deinterlace_Discard() {
|
||||||
} else {
|
} else {
|
||||||
Error("Deinterlace called with unexpected colours: %d", colours);
|
Error("Deinterlace called with unexpected colours: %d", colours);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Image::Deinterlace_Linear() {
|
void Image::Deinterlace_Linear() {
|
||||||
|
|
|
@ -272,7 +272,7 @@ public:
|
||||||
//Image *Delta( const Image &image ) const;
|
//Image *Delta( const Image &image ) const;
|
||||||
void Delta( const Image &image, Image* targetimage) const;
|
void Delta( const Image &image, Image* targetimage) const;
|
||||||
|
|
||||||
const Coord centreCoord( const char *text ) const;
|
const Coord centreCoord(const char *p_text) const;
|
||||||
void MaskPrivacy( const unsigned char *p_bitmask, const Rgb pixel_colour=0x00222222 );
|
void MaskPrivacy( const unsigned char *p_bitmask, const Rgb pixel_colour=0x00222222 );
|
||||||
void Annotate( const char *p_text, const Coord &coord, const unsigned int size=1, const Rgb fg_colour=RGB_WHITE, const Rgb bg_colour=RGB_BLACK );
|
void Annotate( const char *p_text, const Coord &coord, const unsigned int size=1, const Rgb fg_colour=RGB_WHITE, const Rgb bg_colour=RGB_BLACK );
|
||||||
Image *HighlightEdges( Rgb colour, unsigned int p_colours, unsigned int p_subpixelorder, const Box *limits=0 );
|
Image *HighlightEdges( Rgb colour, unsigned int p_colours, unsigned int p_subpixelorder, const Box *limits=0 );
|
||||||
|
|
|
@ -779,7 +779,7 @@ void LocalCamera::Initialise() {
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if ( vidioctl(vid_fd, VIDIOC_S_FMT, &v4l2_data.fmt) < 0 ) {
|
if ( vidioctl(vid_fd, VIDIOC_S_FMT, &v4l2_data.fmt) < 0 ) {
|
||||||
Fatal("Failed to set video format: %s", strerror(errno));
|
Error("Failed to set video format: %s", strerror(errno));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -350,7 +350,7 @@ Monitor::Monitor()
|
||||||
else
|
else
|
||||||
event_close_mode = CLOSE_IDLE;
|
event_close_mode = CLOSE_IDLE;
|
||||||
|
|
||||||
start_time = last_fps_time = time( 0 );
|
start_time = last_fps_time = time(0);
|
||||||
event = 0;
|
event = 0;
|
||||||
last_section_mod = 0;
|
last_section_mod = 0;
|
||||||
|
|
||||||
|
@ -416,7 +416,7 @@ void Monitor::Load(MYSQL_ROW dbrow, bool load_zones=true, Purpose p = QUERY) {
|
||||||
capture_delay = (dbrow[col]&&atof(dbrow[col])>0.0)?int(DT_PREC_3/atof(dbrow[col])):0; col++;
|
capture_delay = (dbrow[col]&&atof(dbrow[col])>0.0)?int(DT_PREC_3/atof(dbrow[col])):0; col++;
|
||||||
alarm_capture_delay = (dbrow[col]&&atof(dbrow[col])>0.0)?int(DT_PREC_3/atof(dbrow[col])):0; col++;
|
alarm_capture_delay = (dbrow[col]&&atof(dbrow[col])>0.0)?int(DT_PREC_3/atof(dbrow[col])):0; col++;
|
||||||
|
|
||||||
if (analysis_fps > 0.0) {
|
if ( analysis_fps > 0.0 ) {
|
||||||
uint64_t usec = round(1000000*pre_event_count/analysis_fps);
|
uint64_t usec = round(1000000*pre_event_count/analysis_fps);
|
||||||
video_buffer_duration.tv_sec = usec/1000000;
|
video_buffer_duration.tv_sec = usec/1000000;
|
||||||
video_buffer_duration.tv_usec = usec % 1000000;
|
video_buffer_duration.tv_usec = usec % 1000000;
|
||||||
|
@ -590,16 +590,15 @@ void Monitor::Load(MYSQL_ROW dbrow, bool load_zones=true, Purpose p = QUERY) {
|
||||||
|
|
||||||
// maybe unneeded
|
// maybe unneeded
|
||||||
// Should maybe store this for later use
|
// Should maybe store this for later use
|
||||||
char monitor_dir[PATH_MAX];
|
std::string monitor_dir = stringtf("%s/%d", storage->Path(), id);
|
||||||
snprintf(monitor_dir, sizeof(monitor_dir), "%s/%d", storage->Path(), id);
|
|
||||||
if ( purpose == CAPTURE ) {
|
if ( purpose == CAPTURE ) {
|
||||||
if ( mkdir(monitor_dir, 0755) && ( errno != EEXIST ) ) {
|
if ( mkdir(monitor_dir.c_str(), 0755) && ( errno != EEXIST ) ) {
|
||||||
Error("Can't mkdir %s: %s", monitor_dir, strerror(errno));
|
Error("Can't mkdir %s: %s", monitor_dir.c_str(), strerror(errno));
|
||||||
}
|
}
|
||||||
} else if ( purpose == ANALYSIS ) {
|
} else if ( purpose == ANALYSIS ) {
|
||||||
if ( config.record_diag_images ) {
|
if ( config.record_diag_images ) {
|
||||||
diag_path_r = stringtf("%s/%d/diag-r.jpg", storage->Path(), id);
|
diag_path_r = monitor_dir + "/diag-r.jpg";
|
||||||
diag_path_d = stringtf("%s/%d/diag-d.jpg", storage->Path(), id);
|
diag_path_d = monitor_dir + "/diag-d.jpg";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1106,7 +1105,7 @@ Monitor::State Monitor::GetState() const {
|
||||||
return (State)shared_data->state;
|
return (State)shared_data->state;
|
||||||
}
|
}
|
||||||
|
|
||||||
int Monitor::GetImage( int index, int scale ) {
|
int Monitor::GetImage(int index, int scale) {
|
||||||
if ( index < 0 || index > image_buffer_count ) {
|
if ( index < 0 || index > image_buffer_count ) {
|
||||||
index = shared_data->last_write_index;
|
index = shared_data->last_write_index;
|
||||||
}
|
}
|
||||||
|
@ -1875,13 +1874,14 @@ bool Monitor::Analyse() {
|
||||||
&& (!event->AlarmFrames())
|
&& (!event->AlarmFrames())
|
||||||
&& (event_close_mode == CLOSE_ALARM)
|
&& (event_close_mode == CLOSE_ALARM)
|
||||||
&& ( ( timestamp->tv_sec - video_store_data->recording.tv_sec ) >= min_section_length )
|
&& ( ( timestamp->tv_sec - video_store_data->recording.tv_sec ) >= min_section_length )
|
||||||
|
&& ( (!pre_event_count) || (Event::PreAlarmCount() >= alarm_frame_count-1) )
|
||||||
) {
|
) {
|
||||||
Info("%s: %03d - Closing event %" PRIu64 ", continuous end, alarm begins",
|
Info("%s: %03d - Closing event %" PRIu64 ", continuous end, alarm begins",
|
||||||
name, image_count, event->Id());
|
name, image_count, event->Id());
|
||||||
closeEvent();
|
closeEvent();
|
||||||
} else if ( event ) {
|
} else if ( event ) {
|
||||||
// This is so if we need more than 1 alarm frame before going into alarm, so it is basically if we have enough alarm frames
|
// This is so if we need more than 1 alarm frame before going into alarm, so it is basically if we have enough alarm frames
|
||||||
Debug(3, "pre-alarm-count in event %d, event frames %d, alarm frames %d event length %d >=? %d",
|
Debug(3, "pre-alarm-count in event %d, event frames %d, alarm frames %d event length %d >=? %d min",
|
||||||
Event::PreAlarmCount(), event->Frames(), event->AlarmFrames(),
|
Event::PreAlarmCount(), event->Frames(), event->AlarmFrames(),
|
||||||
( timestamp->tv_sec - video_store_data->recording.tv_sec ), min_section_length
|
( timestamp->tv_sec - video_store_data->recording.tv_sec ), min_section_length
|
||||||
);
|
);
|
||||||
|
@ -1911,9 +1911,9 @@ bool Monitor::Analyse() {
|
||||||
shared_data->state = state = ALARM;
|
shared_data->state = state = ALARM;
|
||||||
|
|
||||||
Info("%s: %03d - Opening new event %" PRIu64 ", alarm start", name, image_count, event->Id());
|
Info("%s: %03d - Opening new event %" PRIu64 ", alarm start", name, image_count, event->Id());
|
||||||
|
|
||||||
}
|
}
|
||||||
if ( alarm_frame_count ) {
|
if ( alarm_frame_count ) {
|
||||||
|
Debug(1, "alarm frame count so SavePreAlarmFrames");
|
||||||
event->SavePreAlarmFrames();
|
event->SavePreAlarmFrames();
|
||||||
}
|
}
|
||||||
} else if ( state != PREALARM ) {
|
} else if ( state != PREALARM ) {
|
||||||
|
@ -2305,7 +2305,7 @@ int Monitor::Capture() {
|
||||||
captureResult = camera->Capture(*packet);
|
captureResult = camera->Capture(*packet);
|
||||||
gettimeofday(packet->timestamp, NULL);
|
gettimeofday(packet->timestamp, NULL);
|
||||||
if ( captureResult < 0 ) {
|
if ( captureResult < 0 ) {
|
||||||
Debug(2,"failed capture");
|
Debug(2, "failed capture");
|
||||||
// Unable to capture image for temporary reason
|
// Unable to capture image for temporary reason
|
||||||
// Fake a signal loss image
|
// Fake a signal loss image
|
||||||
Rgb signalcolor;
|
Rgb signalcolor;
|
||||||
|
@ -2392,6 +2392,7 @@ int Monitor::Capture() {
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( orientation != ROTATE_0 ) {
|
if ( orientation != ROTATE_0 ) {
|
||||||
|
Debug(2, "Doing rotation");
|
||||||
switch ( orientation ) {
|
switch ( orientation ) {
|
||||||
case ROTATE_0 :
|
case ROTATE_0 :
|
||||||
// No action required
|
// No action required
|
||||||
|
@ -2412,13 +2413,16 @@ int Monitor::Capture() {
|
||||||
capture_image->MaskPrivacy(privacy_bitmask);
|
capture_image->MaskPrivacy(privacy_bitmask);
|
||||||
|
|
||||||
if ( config.timestamp_on_capture ) {
|
if ( config.timestamp_on_capture ) {
|
||||||
|
Debug(1, "Timestamping");
|
||||||
TimestampImage(capture_image, packet->timestamp);
|
TimestampImage(capture_image, packet->timestamp);
|
||||||
}
|
}
|
||||||
|
|
||||||
shared_data->signal = signal_check_points ? CheckSignal(capture_image) : true;
|
shared_data->signal = signal_check_points ? CheckSignal(capture_image) : true;
|
||||||
|
Debug(1, "signal check points? %d", signal_check_points);
|
||||||
shared_data->last_write_index = index;
|
shared_data->last_write_index = index;
|
||||||
shared_data->last_write_time = image_buffer[index].timestamp->tv_sec;
|
shared_data->last_write_time = image_buffer[index].timestamp->tv_sec;
|
||||||
image_count++;
|
image_count++;
|
||||||
|
Debug(2, "Unlocking packet");
|
||||||
packet->unlock();
|
packet->unlock();
|
||||||
|
|
||||||
if ( fps_report_interval && ( !(image_count%fps_report_interval) || image_count == 5 ) ) {
|
if ( fps_report_interval && ( !(image_count%fps_report_interval) || image_count == 5 ) ) {
|
||||||
|
@ -2478,13 +2482,13 @@ int Monitor::Capture() {
|
||||||
return captureResult;
|
return captureResult;
|
||||||
} // end Monitor::Capture
|
} // end Monitor::Capture
|
||||||
|
|
||||||
void Monitor::TimestampImage( Image *ts_image, const struct timeval *ts_time ) const {
|
void Monitor::TimestampImage(Image *ts_image, const struct timeval *ts_time) const {
|
||||||
if ( !label_format[0] )
|
if ( !label_format[0] )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Expand the strftime macros first
|
// Expand the strftime macros first
|
||||||
char label_time_text[256];
|
char label_time_text[256];
|
||||||
strftime( label_time_text, sizeof(label_time_text), label_format, localtime( &ts_time->tv_sec ) );
|
strftime(label_time_text, sizeof(label_time_text), label_format, localtime(&ts_time->tv_sec));
|
||||||
|
|
||||||
char label_text[1024];
|
char label_text[1024];
|
||||||
const char *s_ptr = label_time_text;
|
const char *s_ptr = label_time_text;
|
||||||
|
@ -2494,15 +2498,15 @@ void Monitor::TimestampImage( Image *ts_image, const struct timeval *ts_time ) c
|
||||||
bool found_macro = false;
|
bool found_macro = false;
|
||||||
switch ( *(s_ptr+1) ) {
|
switch ( *(s_ptr+1) ) {
|
||||||
case 'N' :
|
case 'N' :
|
||||||
d_ptr += snprintf( d_ptr, sizeof(label_text)-(d_ptr-label_text), "%s", name );
|
d_ptr += snprintf(d_ptr, sizeof(label_text)-(d_ptr-label_text), "%s", name);
|
||||||
found_macro = true;
|
found_macro = true;
|
||||||
break;
|
break;
|
||||||
case 'Q' :
|
case 'Q' :
|
||||||
d_ptr += snprintf( d_ptr, sizeof(label_text)-(d_ptr-label_text), "%s", trigger_data->trigger_showtext );
|
d_ptr += snprintf(d_ptr, sizeof(label_text)-(d_ptr-label_text), "%s", trigger_data->trigger_showtext);
|
||||||
found_macro = true;
|
found_macro = true;
|
||||||
break;
|
break;
|
||||||
case 'f' :
|
case 'f' :
|
||||||
d_ptr += snprintf( d_ptr, sizeof(label_text)-(d_ptr-label_text), "%02ld", ts_time->tv_usec/10000 );
|
d_ptr += snprintf(d_ptr, sizeof(label_text)-(d_ptr-label_text), "%02ld", ts_time->tv_usec/10000);
|
||||||
found_macro = true;
|
found_macro = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -2514,7 +2518,9 @@ void Monitor::TimestampImage( Image *ts_image, const struct timeval *ts_time ) c
|
||||||
*d_ptr++ = *s_ptr++;
|
*d_ptr++ = *s_ptr++;
|
||||||
} // end while
|
} // end while
|
||||||
*d_ptr = '\0';
|
*d_ptr = '\0';
|
||||||
|
Debug(2, "annotating %s", label_text);
|
||||||
ts_image->Annotate(label_text, label_coord, label_size);
|
ts_image->Annotate(label_text, label_coord, label_size);
|
||||||
|
Debug(2, "done annotating %s", label_text);
|
||||||
} // end void Monitor::TimestampImage
|
} // end void Monitor::TimestampImage
|
||||||
|
|
||||||
bool Monitor::closeEvent() {
|
bool Monitor::closeEvent() {
|
||||||
|
|
|
@ -78,7 +78,9 @@ bool zm_packetqueue::queuePacket(ZMPacket* zm_packet) {
|
||||||
// We signal on every packet because someday we may analyze sound
|
// We signal on every packet because someday we may analyze sound
|
||||||
Debug(2,"Signalling");
|
Debug(2,"Signalling");
|
||||||
condition->signal();
|
condition->signal();
|
||||||
|
Debug(2," after Signalling");
|
||||||
mutex.unlock();
|
mutex.unlock();
|
||||||
|
Debug(2," after unlock");
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
} // end bool zm_packetqueue::queuePacket(ZMPacket* zm_packet)
|
} // end bool zm_packetqueue::queuePacket(ZMPacket* zm_packet)
|
||||||
|
|
|
@ -48,18 +48,18 @@ while (my $line = <F>) {
|
||||||
$in_head-- if $line =~ /^$/ and $in_head;
|
$in_head-- if $line =~ /^$/ and $in_head;
|
||||||
next while $in_head;
|
next while $in_head;
|
||||||
unless ($line =~ /^\s+(0x..), \/\* (........)/) {
|
unless ($line =~ /^\s+(0x..), \/\* (........)/) {
|
||||||
$line =~ s/static unsigned char fontdata/static unsigned int bigfontdata/;
|
#$line =~ s/static unsigned char fontdata/static unsigned int bigfontdata/;
|
||||||
print $line;
|
print $line;
|
||||||
next;
|
next;
|
||||||
}
|
}
|
||||||
my $code = $1;
|
my $code = $1;
|
||||||
my $bincode = $2;
|
my $bincode = $2;
|
||||||
$bincode = "$1$1$2$2$3$3$4$4$5$5$6$6$7$7$8$8" if $bincode =~ /(.)(.)(.)(.)(.)(.)(.)(.)$/;
|
$bincode = "$1$1$2$2$3$3$4$4$5$5$6$6$7$7$8$8" if $bincode =~ /(.)(.)(.)(.)(.)(.)(.)(.)$/;
|
||||||
$bincode =~ s/ /1/g;
|
#$bincode =~ s/ /1/g;
|
||||||
my $intcode = unpack("N", pack("B32", substr("0" x 32 . $bincode, -32)));
|
#my $intcode = unpack("N", pack("B32", substr("0" x 32 . $bincode, -32)));
|
||||||
my $hexcode = sprintf("%#x", $intcode);
|
#my $hexcode = sprintf("%#x", $intcode);
|
||||||
$hexcode =~ s/^0$/0x0/;
|
#$hexcode =~ s/^0$/0x0/;
|
||||||
$bincode =~ s/1/ /g;
|
#$bincode =~ s/1/ /g;
|
||||||
print sprintf("\t%10s, /* %s */\n", $hexcode, $bincode);
|
print sprintf("\t%10s, /* %s */\n", $hexcode, $bincode);
|
||||||
print sprintf("\t%10s, /* %s */\n", $hexcode, $bincode);
|
print sprintf("\t%10s, /* %s */\n", $hexcode, $bincode);
|
||||||
}
|
}
|
||||||
|
|
|
@ -842,9 +842,15 @@ function daemonStatus($daemon, $args=false) {
|
||||||
initDaemonStatus();
|
initDaemonStatus();
|
||||||
|
|
||||||
$string = $daemon;
|
$string = $daemon;
|
||||||
if ( $args )
|
if ( $args ) {
|
||||||
|
if ( is_array($args) ) {
|
||||||
|
$string .= join(' ', $args);
|
||||||
|
ZM\Warning("daemonStatus args: $string");
|
||||||
|
} else {
|
||||||
$string .= ' ' . $args;
|
$string .= ' ' . $args;
|
||||||
return( strpos($daemon_status, "'$string' running") !== false );
|
}
|
||||||
|
}
|
||||||
|
return ( strpos($daemon_status, "'$string' running") !== false );
|
||||||
}
|
}
|
||||||
|
|
||||||
function zmcStatus($monitor) {
|
function zmcStatus($monitor) {
|
||||||
|
|
Loading…
Reference in New Issue