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:
parent
9ffd77428a
commit
ab9081e1bf
|
@ -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})
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 ) {
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
}
|
|
@ -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
|
Loading…
Reference in New Issue