Update frame deltas in the database to be relative to the video start time
Currenltly the frames written to database have delta time measured from the event start time. As these deltas are also used to generate any frame on the fly from the recorded video, these should be relative to the video start time. Adjust by subtracting the offset of the video start from event start. Done when the event is closed. If video is not stored, this has no effect. Signed-off-by: Selva Nair <selva.nair@gmail.com>
This commit is contained in:
parent
dd31279ca3
commit
5260563ec4
|
@ -256,6 +256,20 @@ Event::~Event() {
|
|||
if ( frame_data.size() )
|
||||
WriteDbFrames();
|
||||
|
||||
// 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_start_time = monitor->GetVideoWriterStartTime();
|
||||
if (video_start_time.tv_sec > 0) {
|
||||
timersub(&video_start_time, &start_time, &video_offset);
|
||||
Debug(1, "Updating frames delta by %d sec %d usec",
|
||||
video_offset.tv_sec, video_offset.tv_usec);
|
||||
UpdateFramesDelta(video_offset.tv_sec + video_offset.tv_usec*1e-6);
|
||||
}
|
||||
else {
|
||||
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);
|
||||
}
|
||||
|
||||
// Should not be static because we might be multi-threaded
|
||||
char sql[ZM_SQL_LGE_BUFSIZ];
|
||||
snprintf(sql, sizeof(sql),
|
||||
|
@ -554,6 +568,27 @@ void Event::WriteDbFrames() {
|
|||
db_mutex.unlock();
|
||||
} // end void Event::WriteDbFrames()
|
||||
|
||||
// Subtract an offset time from frames deltas to match with video start time
|
||||
void Event::UpdateFramesDelta(double offset) {
|
||||
char sql[ZM_SQL_MED_BUFSIZ];
|
||||
|
||||
if (offset == 0.0) return;
|
||||
// the table is set to auto update timestamp so we force it to keep current value
|
||||
snprintf(sql, sizeof(sql),
|
||||
"UPDATE Frames SET timestamp = timestamp, Delta = Delta - (%.4f) WHERE EventId = %" PRIu64,
|
||||
offset, id);
|
||||
|
||||
db_mutex.lock();
|
||||
if (mysql_query(&dbconn, sql)) {
|
||||
db_mutex.unlock();
|
||||
Error("Can't update frames: %s, sql was %s", mysql_error(&dbconn), sql);
|
||||
return;
|
||||
}
|
||||
db_mutex.unlock();
|
||||
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) {
|
||||
if ( !timestamp.tv_sec ) {
|
||||
Debug(1, "Not adding new frame, zero timestamp");
|
||||
|
|
|
@ -132,6 +132,7 @@ class Event {
|
|||
private:
|
||||
void AddFramesInternal( int n_frames, int start_frame, Image **images, struct timeval **timestamps );
|
||||
void WriteDbFrames();
|
||||
void UpdateFramesDelta(double offset);
|
||||
|
||||
public:
|
||||
static const char *getSubPath( struct tm *time ) {
|
||||
|
|
|
@ -872,6 +872,7 @@ int FfmpegCamera::CaptureAndRecord(
|
|||
// since the last keyframe.
|
||||
unsigned int packet_count = 0;
|
||||
ZMPacket *queued_packet;
|
||||
struct timeval video_offset = {0};
|
||||
|
||||
// Clear all packets that predate the moment when the recording began
|
||||
packetqueue->clear_unwanted_packets(
|
||||
|
@ -880,6 +881,14 @@ int FfmpegCamera::CaptureAndRecord(
|
|||
while ( (queued_packet = packetqueue->popPacket()) ) {
|
||||
AVPacket *avp = queued_packet->av_packet();
|
||||
|
||||
// compute time offset between event start and first frame in video
|
||||
if (packet_count == 0){
|
||||
monitor->SetVideoWriterStartTime(queued_packet->timestamp);
|
||||
timersub(&queued_packet->timestamp, &recording, &video_offset);
|
||||
Info("Event video offset is %.3f sec (<0 means video starts early)",
|
||||
video_offset.tv_sec + video_offset.tv_usec*1e-6);
|
||||
}
|
||||
|
||||
packet_count += 1;
|
||||
// Write the packet to our video store
|
||||
Debug(2, "Writing queued packet stream: %d KEY %d, remaining (%d)",
|
||||
|
|
|
@ -466,6 +466,8 @@ public:
|
|||
const std::vector<EncoderParameter_t>* GetOptEncoderParams() const { return &encoderparamsvec; }
|
||||
uint64_t GetVideoWriterEventId() const { return video_store_data->current_event; }
|
||||
void SetVideoWriterEventId( unsigned long long p_event_id ) { video_store_data->current_event = p_event_id; }
|
||||
struct timeval GetVideoWriterStartTime() const { return video_store_data->recording; }
|
||||
void SetVideoWriterStartTime(struct timeval &t) { video_store_data->recording = t; }
|
||||
|
||||
unsigned int GetPreEventCount() const { return pre_event_count; };
|
||||
struct timeval GetVideoBufferDuration() const { return video_buffer_duration; };
|
||||
|
|
Loading…
Reference in New Issue