create a simple Frame class. Add a queue of Frames to the Event. When we get 10 of them write them out to the db.

This commit is contained in:
Isaac Connor 2018-12-05 13:18:21 -05:00
parent 9ffd77428a
commit ab9081e1bf
5 changed files with 124 additions and 19 deletions

View File

@ -4,7 +4,7 @@
configure_file(zm_config.h.in "${CMAKE_CURRENT_BINARY_DIR}/zm_config.h" @ONLY)
# Group together all the source files that are used by all the binaries (zmc, zma, zmu, zms etc)
set(ZM_BIN_SRC_FILES zm_box.cpp zm_buffer.cpp zm_camera.cpp zm_comms.cpp zm_config.cpp zm_coord.cpp zm_curl_camera.cpp zm.cpp zm_db.cpp zm_logger.cpp zm_event.cpp zm_eventstream.cpp zm_exception.cpp zm_file_camera.cpp zm_ffmpeg_input.cpp zm_ffmpeg_camera.cpp zm_group.cpp zm_image.cpp zm_jpeg.cpp zm_libvlc_camera.cpp zm_local_camera.cpp zm_monitor.cpp zm_monitorstream.cpp zm_ffmpeg.cpp zm_mpeg.cpp zm_packet.cpp zm_packetqueue.cpp zm_poly.cpp zm_regexp.cpp zm_remote_camera.cpp zm_remote_camera_http.cpp zm_remote_camera_nvsocket.cpp zm_remote_camera_rtsp.cpp zm_rtp.cpp zm_rtp_ctrl.cpp zm_rtp_data.cpp zm_rtp_source.cpp zm_rtsp.cpp zm_rtsp_auth.cpp zm_sdp.cpp zm_signal.cpp zm_stream.cpp zm_swscale.cpp zm_thread.cpp zm_time.cpp zm_timer.cpp zm_user.cpp zm_utils.cpp zm_video.cpp zm_videostore.cpp zm_zone.cpp zm_storage.cpp)
set(ZM_BIN_SRC_FILES zm_box.cpp zm_buffer.cpp zm_camera.cpp zm_comms.cpp zm_config.cpp zm_coord.cpp zm_curl_camera.cpp zm.cpp zm_db.cpp zm_logger.cpp zm_event.cpp zm_frame.cpp zm_eventstream.cpp zm_exception.cpp zm_file_camera.cpp zm_ffmpeg_input.cpp zm_ffmpeg_camera.cpp zm_group.cpp zm_image.cpp zm_jpeg.cpp zm_libvlc_camera.cpp zm_local_camera.cpp zm_monitor.cpp zm_monitorstream.cpp zm_ffmpeg.cpp zm_mpeg.cpp zm_packet.cpp zm_packetqueue.cpp zm_poly.cpp zm_regexp.cpp zm_remote_camera.cpp zm_remote_camera_http.cpp zm_remote_camera_nvsocket.cpp zm_remote_camera_rtsp.cpp zm_rtp.cpp zm_rtp_ctrl.cpp zm_rtp_data.cpp zm_rtp_source.cpp zm_rtsp.cpp zm_rtsp_auth.cpp zm_sdp.cpp zm_signal.cpp zm_stream.cpp zm_swscale.cpp zm_thread.cpp zm_time.cpp zm_timer.cpp zm_user.cpp zm_utils.cpp zm_video.cpp zm_videostore.cpp zm_zone.cpp zm_storage.cpp)
# A fix for cmake recompiling the source files for every target.
add_library(zm STATIC ${ZM_BIN_SRC_FILES})

View File

@ -238,6 +238,9 @@ Event::~Event() {
videowriter = NULL;
}
if ( frame_data.size() )
WriteDbFrames();
// Should not be static because we are multi-threaded
char sql[ZM_SQL_MED_BUFSIZ];
struct DeltaTimeval delta_time;
@ -260,7 +263,11 @@ Event::~Event() {
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,
monitor->EventPrefix(), id, end_time.tv_sec, delta_time.positive?"":"-", delta_time.sec, delta_time.fsec, frames, alarm_frames, tot_score, (int)(alarm_frames?(tot_score/alarm_frames):0), max_score, video_name, id );
monitor->EventPrefix(), id, end_time.tv_sec,
delta_time.positive?"":"-", delta_time.sec, delta_time.fsec,
frames, alarm_frames,
tot_score, (int)(alarm_frames?(tot_score/alarm_frames):0), max_score,
video_name, id );
db_mutex.lock();
while ( mysql_query(&dbconn, sql) && !zm_terminate ) {
Error("Can't update event: %s reason: %s", sql, mysql_error(&dbconn));
@ -376,7 +383,7 @@ void Event::updateNotes( const StringSetMap &newNoteSetMap ) {
createNotes( notes );
Debug( 2, "Updating notes for event %d, '%s'", id, notes.c_str() );
static char sql[ZM_SQL_MED_BUFSIZ];
static char sql[ZM_SQL_LGE_BUFSIZ];
#if USE_PREPARED_SQL
static MYSQL_STMT *stmt = 0;
@ -504,6 +511,35 @@ void Event::AddFramesInternal( int n_frames, int start_frame, Image **images, st
}
}
void Event::WriteDbFrames() {
static char sql[ZM_SQL_LGE_BUFSIZ];
char * sql_ptr = (char *)&sql;
sql_ptr += snprintf(sql, sizeof(sql),
"INSERT INTO Frames ( EventId, FrameId, Type, TimeStamp, Delta, Score ) VALUES "
);
while ( frame_data.size() ) {
Frame *frame = frame_data.front();
frame_data.pop();
sql_ptr += snprintf(sql_ptr, sizeof(sql)-(sql_ptr-(char *)&sql), "( %" PRIu64 ", %d, '%s', from_unixtime( %ld ), %s%ld.%02ld, %d ), ",
id, frame->frame_id, frame_type_names[frame->type],
frame->timestamp.tv_sec,
frame->delta.positive?"":"-",
frame->delta.sec,
frame->delta.fsec,
frame->score);
delete frame;
}
*(sql_ptr-2) = '\0';
db_mutex.lock();
if ( mysql_query(&dbconn, sql) ) {
Error("Can't insert frames: %s", mysql_error(&dbconn));
Error("SQL was %s", sql);
db_mutex.unlock();
return;
}
db_mutex.unlock();
}
void Event::AddFrame(Image *image, struct timeval timestamp, int score, Image *alarm_image) {
if ( !timestamp.tv_sec ) {
Debug(1, "Not adding new frame, zero timestamp");
@ -543,22 +579,14 @@ Debug(3, "Writing video");
bool db_frame = ( frame_type != BULK ) || (!frames) || ((frames%config.bulk_frame_interval)==0) ;
if ( db_frame ) {
Debug( 1, "Adding frame %d of type \"%s\" to DB", frames, Event::frame_type_names[frame_type] );
static char sql[ZM_SQL_MED_BUFSIZ];
snprintf(sql, sizeof(sql),
"INSERT INTO Frames ( EventId, FrameId, Type, TimeStamp, Delta, Score )"
" VALUES ( %" PRIu64 ", %d, '%s', from_unixtime( %ld ), %s%ld.%02ld, %d )",
id, frames, frame_type_names[frame_type], timestamp.tv_sec, delta_time.positive?"":"-", delta_time.sec, delta_time.fsec, score);
db_mutex.lock();
if ( mysql_query(&dbconn, sql) ) {
Error("Can't insert frame: %s", mysql_error(&dbconn));
Error("SQL was %s", sql);
db_mutex.unlock();
return;
}
db_mutex.unlock();
frame_data.push( new Frame(id, frames, frame_type, timestamp, delta_time, score ) );
if ( frame_data.size() > 10 ) {
WriteDbFrames();
Debug(1, "Adding 10 frames to DB");
last_db_frame = frames;
}
// We are writing a Bulk frame
if ( frame_type == BULK ) {
@ -581,7 +609,7 @@ Debug(3, "Writing video");
db_mutex.lock();
}
db_mutex.unlock();
}
} // end if frame_type == BULK
} // end if db_frame
end_time = timestamp;

View File

@ -33,6 +33,7 @@
#include <set>
#include <map>
#include <queue>
#include "zm.h"
#include "zm_image.h"
@ -45,7 +46,10 @@ class Monitor;
class EventStream;
#define MAX_PRE_ALARM_FRAMES 16 // Maximum number of prealarm frames that can be stored
typedef uint64_t event_id_t;
typedef enum { NORMAL=0, BULK, ALARM } FrameType;
#include "zm_frame.h"
//
// Class describing events, i.e. captured periods of activity.
//
@ -60,7 +64,6 @@ class Event {
typedef std::map<std::string,StringSet> StringSetMap;
protected:
typedef enum { NORMAL=0, BULK, ALARM } FrameType;
static const char * frame_type_names[3];
struct PreAlarmData {
@ -69,6 +72,7 @@ class Event {
unsigned int score;
Image *alarm_frame;
};
std::queue<Frame*> frame_data;
static int pre_alarm_count;
static PreAlarmData pre_alarm_data[MAX_PRE_ALARM_FRAMES];
@ -124,6 +128,7 @@ class Event {
private:
void AddFramesInternal( int n_frames, int start_frame, Image **images, struct timeval **timestamps );
void WriteDbFrames();
public:
static const char *getSubPath( struct tm *time ) {

18
src/zm_frame.cpp Normal file
View File

@ -0,0 +1,18 @@
#include "zm_frame.h"
Frame::Frame(
event_id_t p_event_id,
int p_frame_id,
FrameType p_type,
struct timeval p_timestamp,
struct DeltaTimeval p_delta,
int p_score
) :
event_id(p_event_id),
frame_id(p_frame_id),
type(p_type),
timestamp(p_timestamp),
delta(p_delta),
score(p_score)
{
}

54
src/zm_frame.h Normal file
View File

@ -0,0 +1,54 @@
//
// ZoneMinder Frame Class Interfaces, $Date$, $Revision$
// Copyright (C) 2001-2008 Philip Coombes
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
//
#ifndef ZM_FRAME_H
#define ZM_FRAME_H
#include <sys/time.h>
#include <sys/types.h>
class Frame;
#include "zm_event.h"
#include "zm_time.h"
//
// This describes a frame record
//
class Frame {
public:
Frame(
event_id_t p_event_id,
int p_frame_id,
FrameType p_type,
struct timeval p_timestamp,
struct DeltaTimeval p_delta,
int p_score
);
event_id_t event_id;
int frame_id;
FrameType type;
struct timeval timestamp;
struct DeltaTimeval delta;
int score;
};
#endif // ZM_FRAME_H