rework locking to have a per-packet mutex
This commit is contained in:
commit
4d73ce4109
|
@ -65,6 +65,8 @@ set(CMAKE_C_FLAGS_DEBUG "-Wall -D__STDC_CONSTANT_MACROS -g")
|
|||
set(CMAKE_CXX_FLAGS_DEBUG "-Wall -D__STDC_CONSTANT_MACROS -g")
|
||||
set(CMAKE_INCLUDE_CURRENT_DIR ON)
|
||||
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/Modules/")
|
||||
set (CMAKE_CXX_STANDARD 11)
|
||||
|
||||
|
||||
# GCC below 6.0 doesn't support __target__("fpu=neon") attribute, required for compiling ARM Neon code, otherwise compilation fails.
|
||||
# Must use -mfpu=neon compiler flag instead, but only do that for processors that support neon, otherwise strip the neon code alltogether,
|
||||
|
|
|
@ -187,7 +187,12 @@ while( 1 ) {
|
|||
|
||||
if ( $restart ) {
|
||||
Info( "Restarting analysis daemon for $$monitor{Id} $$monitor{Name}\n");
|
||||
my $command = "zmdc.pl restart zmc -m ".$monitor->{Id};
|
||||
my $command;
|
||||
if ( $monitor->{Type} eq 'Local' ) {
|
||||
$command = "zmdc.pl restart zmc -d $monitor->{Device}";
|
||||
} else {
|
||||
$command = "zmdc.pl restart zmc -m $monitor->{Id}";
|
||||
}
|
||||
runCommand( $command );
|
||||
} # end if restart
|
||||
} # end if check analysis daemon
|
||||
|
|
|
@ -1243,17 +1243,15 @@ bool Monitor::Analyse() {
|
|||
Warning("SHouldn't be doing Analyze when not Enabled");
|
||||
return false;
|
||||
}
|
||||
GetLastEventId();
|
||||
|
||||
// if have event, sent frames until we find a video packet, at which point do analysis. Adaptive skip should only affect which frames we do analysis on.
|
||||
|
||||
// If do have an event, then analysis_it should point to the head of the queue, because we would have emptied it on event creation.
|
||||
unsigned int index = ( shared_data->last_read_index + 1 ) % image_buffer_count;
|
||||
|
||||
int packets_processed = 0;
|
||||
|
||||
ZMPacket *snap;
|
||||
while ( ( snap = packetqueue->get_analysis_packet() ) && ( snap->score == -1 ) ) {
|
||||
snap->lock();
|
||||
unsigned int index = snap->image_index;
|
||||
Debug(2, "Analysis index (%d), last_Write(%d)", index, shared_data->last_write_index);
|
||||
packets_processed += 1;
|
||||
|
||||
|
@ -1261,6 +1259,7 @@ bool Monitor::Analyse() {
|
|||
Image *snap_image = snap->image;
|
||||
Debug(2, "Analysing image (%d)", snap->image_index );
|
||||
if ( snap->image_index == -1 ) {
|
||||
snap->unlock();
|
||||
Debug(2, "skipping because audio");
|
||||
if ( ! packetqueue->increment_analysis_it() ) {
|
||||
Debug(2, "No more packets to analyse");
|
||||
|
@ -1411,8 +1410,12 @@ bool Monitor::Analyse() {
|
|||
Info( "%s: %03d - Gone into alarm state", name, analysis_image_count );
|
||||
shared_data->state = state = ALARM;
|
||||
if ( (function != MOCORD && state != ALERT) ) {
|
||||
if ( event ) {
|
||||
Error("Already ahve evnet!");
|
||||
} else {
|
||||
event = new Event( this, *timestamp, cause, noteSetMap );
|
||||
shared_data->last_event_id = event->Id();
|
||||
}
|
||||
}
|
||||
} else if ( state != PREALARM ) {
|
||||
Info( "%s: %03d - Gone into prealarm state", name, analysis_image_count );
|
||||
|
@ -1497,6 +1500,7 @@ bool Monitor::Analyse() {
|
|||
|
||||
} else {
|
||||
Debug(3,"Not ready?");
|
||||
snap->unlock();
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
|
@ -1510,25 +1514,40 @@ bool Monitor::Analyse() {
|
|||
} // end if ( trigger_data->trigger_state != TRIGGER_OFF )
|
||||
|
||||
if ( event ) {
|
||||
int last_write = shared_data->last_write_index;
|
||||
int written = 0;
|
||||
ZMPacket *queued_packet;
|
||||
//popPacket will increment analysis_it if neccessary, so this will write out all packets in queue
|
||||
// We can't just loop here forever, because we may be capturing just as fast, and never leave the loop.
|
||||
// Only loop until we hit the analysis index
|
||||
while ( ( queued_packet = packetqueue->popPacket() ) ) {
|
||||
Debug(2,"adding packet (%x) (%d)", queued_packet, queued_packet->image_index );
|
||||
event->AddPacket( queued_packet );
|
||||
Debug(2,"adding packet (%d) qp lwindex(%d), written(%d)", queued_packet->image_index, last_write, written );
|
||||
if ( snap == queued_packet ) {
|
||||
event->AddPacket( queued_packet );
|
||||
packetqueue->increment_analysis_it();
|
||||
break;
|
||||
} else {
|
||||
queued_packet->lock();
|
||||
Debug(2,"adding packet (%d) qp lwindex(%d), written(%d)", queued_packet->image_index, last_write, written );
|
||||
event->AddPacket( queued_packet );
|
||||
queued_packet->unlock();
|
||||
}
|
||||
written ++;
|
||||
if ( queued_packet->image_index == -1 ) {
|
||||
delete queued_packet;
|
||||
queued_packet = NULL;
|
||||
}
|
||||
}
|
||||
// encoding can take a long time, so
|
||||
shared_data->last_read_time = time(NULL);
|
||||
} // end while write out queued_packets
|
||||
queued_packet = NULL;
|
||||
} else {
|
||||
packetqueue->increment_analysis_it();
|
||||
}
|
||||
|
||||
shared_data->last_read_index = snap->image_index;
|
||||
struct timeval now;
|
||||
gettimeofday(&now, NULL);
|
||||
shared_data->last_read_time = now.tv_sec;
|
||||
shared_data->last_read_time = time(NULL);
|
||||
analysis_image_count++;
|
||||
snap->unlock();
|
||||
} // end while not at end of packetqueue
|
||||
if ( packets_processed > 0 )
|
||||
return true;
|
||||
|
@ -2760,7 +2779,7 @@ int Monitor::Capture() {
|
|||
}
|
||||
|
||||
ZMPacket *packet = &image_buffer[index];
|
||||
Debug(2,"Reset index(%d) of (%d)", index, image_buffer_count );
|
||||
packet->lock();
|
||||
packet->reset();
|
||||
Image* capture_image = packet->image;
|
||||
int captureResult = 0;
|
||||
|
@ -2781,7 +2800,6 @@ int Monitor::Capture() {
|
|||
}
|
||||
} else {
|
||||
captureResult = camera->Capture(*packet);
|
||||
Debug(2, "Reset timestamp");
|
||||
gettimeofday( packet->timestamp, NULL );
|
||||
if ( captureResult < 0 ) {
|
||||
// Unable to capture image for temporary reason
|
||||
|
@ -2791,6 +2809,7 @@ int Monitor::Capture() {
|
|||
signalcolor = rgb_convert(signal_check_colour, ZM_SUBPIX_ORDER_BGR);
|
||||
capture_image->Fill(signalcolor);
|
||||
shared_data->signal = false;
|
||||
packet->unlock();
|
||||
return -1;
|
||||
} else if ( captureResult > 0 ) {
|
||||
|
||||
|
@ -2814,11 +2833,12 @@ int Monitor::Capture() {
|
|||
}
|
||||
// Don't update last_write_index because that is used for live streaming
|
||||
//shared_data->last_write_time = image_buffer[index].timestamp->tv_sec;
|
||||
|
||||
mutex.unlock();
|
||||
packet->unlock();
|
||||
return 1;
|
||||
}
|
||||
|
||||
Debug(2, "Have video packet");
|
||||
#if LIBAVCODEC_VERSION_CHECK(57, 64, 0, 64, 0)
|
||||
packet->codec_type = camera->get_VideoStream()->codecpar->codec_type;
|
||||
#else
|
||||
|
@ -2834,8 +2854,10 @@ int Monitor::Capture() {
|
|||
// Have an av_packet,
|
||||
mutex.lock();
|
||||
if ( packetqueue->video_packet_count || packet->keyframe || event ) {
|
||||
//Debug(2, "Queueing video packet");
|
||||
Debug(2, "Have video packet for index (%d)", index );
|
||||
packetqueue->queuePacket( packet );
|
||||
} else {
|
||||
Debug(2, "Not queiing video packet for index (%d)", index );
|
||||
}
|
||||
mutex.unlock();
|
||||
} else {
|
||||
|
@ -2889,6 +2911,7 @@ int Monitor::Capture() {
|
|||
shared_data->last_write_index = index;
|
||||
shared_data->last_write_time = image_buffer[index].timestamp->tv_sec;
|
||||
image_count++;
|
||||
packet->unlock();
|
||||
|
||||
if ( fps_report_interval && !(image_count%fps_report_interval) ) {
|
||||
time_t now = image_buffer[index].timestamp->tv_sec;
|
||||
|
@ -3210,7 +3233,7 @@ int Monitor::PrimeCapture() {
|
|||
int ret = camera->PrimeCapture();
|
||||
if ( ret == 0 ) {
|
||||
video_stream_id = camera->get_VideoStreamId();
|
||||
packetqueue = new zm_packetqueue( pre_event_buffer_count, video_stream_id );
|
||||
packetqueue = new zm_packetqueue( image_buffer_count, video_stream_id );
|
||||
}
|
||||
Debug(2, "Video stream id is (%d), minimum_packets to keep in buffer(%d)", video_stream_id, pre_event_buffer_count );
|
||||
return ret;
|
||||
|
|
|
@ -29,10 +29,12 @@ extern "C" {
|
|||
#endif // __FreeBSD__
|
||||
|
||||
#include "zm_image.h"
|
||||
#include "zm_thread.h"
|
||||
|
||||
class ZMPacket {
|
||||
public:
|
||||
|
||||
Mutex mutex;
|
||||
int keyframe;
|
||||
AVPacket packet; // Input packet, undecoded
|
||||
AVFrame *in_frame; // Input image, decoded Theoretically only filled if needed.
|
||||
|
@ -59,6 +61,8 @@ class ZMPacket {
|
|||
explicit ZMPacket( ZMPacket &packet );
|
||||
ZMPacket();
|
||||
~ZMPacket();
|
||||
void lock() { mutex.lock(); };
|
||||
void unlock() { mutex.unlock(); };
|
||||
};
|
||||
|
||||
#endif /* ZM_PACKET_H */
|
||||
|
|
|
@ -183,6 +183,7 @@ int RemoteCameraNVSocket::PrimeCapture() {
|
|||
Disconnect();
|
||||
return -1;
|
||||
}
|
||||
mVideoStreamId=0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -207,6 +208,7 @@ int RemoteCameraNVSocket::Capture( ZMPacket &zm_packet ) {
|
|||
}
|
||||
|
||||
zm_packet.image->Assign( width, height, colours, subpixelorder, buffer, imagesize );
|
||||
zm_packet.keyframe = 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -232,9 +234,8 @@ AVStream *RemoteCameraNVSocket::get_VideoStream() {
|
|||
} else {
|
||||
Error("Can't create video stream");
|
||||
}
|
||||
} else {
|
||||
Debug(2,"Have videostream");
|
||||
} else {
|
||||
Debug(5,"Have videostream");
|
||||
}
|
||||
Debug(2,"Get videoStream");
|
||||
return video_stream;
|
||||
}
|
||||
|
|
|
@ -953,7 +953,9 @@ int VideoStore::writeVideoFramePacket( ZMPacket * zm_packet ) {
|
|||
out_frame->width = video_out_ctx->width;
|
||||
out_frame->height = video_out_ctx->height;
|
||||
out_frame->format = video_out_ctx->pix_fmt;
|
||||
out_frame->duration = 0;
|
||||
//out_frame->pkt_duration = 0;
|
||||
out_frame->coded_picture_number = frame_count;
|
||||
out_frame->display_picture_number = frame_count;
|
||||
|
||||
if ( ! zm_packet->in_frame ) {
|
||||
Debug(2,"Have no in_frame");
|
||||
|
@ -990,10 +992,20 @@ int VideoStore::writeVideoFramePacket( ZMPacket * zm_packet ) {
|
|||
|
||||
if ( ! video_last_pts ) {
|
||||
video_last_pts = zm_packet->timestamp->tv_sec*1000000 + zm_packet->timestamp->tv_usec;
|
||||
Debug(2, "No video_lsat_pts, set to (%d)", video_last_pts );
|
||||
Debug(2, "No video_lsat_pts, set to (%" PRId64 ") secs(%d) usecs(%d)",
|
||||
video_last_pts, zm_packet->timestamp->tv_sec, zm_packet->timestamp->tv_usec );
|
||||
zm_packet->out_frame->pts = 0;
|
||||
} else {
|
||||
zm_packet->out_frame->pts = ( zm_packet->timestamp->tv_sec*1000000 + zm_packet->timestamp->tv_usec ) - video_last_pts;
|
||||
Debug(2, " Setting pts, set to (%" PRId64 ") from (%" PRIu64 " - secs(%d) usecs(%d)",
|
||||
zm_packet->out_frame->pts, video_last_pts, zm_packet->timestamp->tv_sec, zm_packet->timestamp->tv_usec );
|
||||
}
|
||||
if ( zm_packet->keyframe ) {
|
||||
Debug(2, "Setting keyframe was (%d)", zm_packet->out_frame->key_frame );
|
||||
zm_packet->out_frame->key_frame = 1;
|
||||
Debug(2, "Setting keyframe (%d)", zm_packet->out_frame->key_frame );
|
||||
} else {
|
||||
Debug(2, "Not Setting keyframe");
|
||||
}
|
||||
|
||||
// Do this to allow the encoder to choose whether to use I/P/B frame
|
||||
|
@ -1035,8 +1047,6 @@ int VideoStore::writeVideoFramePacket( ZMPacket * zm_packet ) {
|
|||
}
|
||||
#endif
|
||||
opkt.dts = opkt.pts;
|
||||
if ( zm_packet->keyframe )
|
||||
opkt.flags |= AV_PKT_FLAG_KEY;
|
||||
opkt.duration = 0;
|
||||
|
||||
} else {
|
||||
|
@ -1084,7 +1094,7 @@ void VideoStore::write_video_packet( AVPacket &opkt ) {
|
|||
//av_packet_rescale_ts( &opkt, video_out_ctx->time_base, video_out_stream->time_base );
|
||||
|
||||
Debug(1,
|
||||
"writing video packet pts(%" PRId64 ") dts(%" PRId64 ") duration(%" PRId64 ") packet_count(%d)",
|
||||
"writing video packet pts(%" PRId64 ") dts(%" PRId64 ") duration(%" PRId64 ") packet_count(%u)",
|
||||
opkt.pts, opkt.dts, opkt.duration, packets_written );
|
||||
if ( (opkt.data == NULL) || (opkt.size < 1) ) {
|
||||
Warning("%s:%d: Mangled AVPacket: discarding frame", __FILE__, __LINE__);
|
||||
|
|
|
@ -222,7 +222,7 @@ Warning("Not Using snapshot" . $event->Path().'/snapshot.jpg' );
|
|||
$imgHtml = '<img id="thumbnail'.$event->id().'" src="'.$imgSrc.'" alt="'. validHtmlStr('Event '.$event->Id()) .'" style="width:'. validInt($thumbData['Width']) .'px;height:'. validInt( $thumbData['Height'] ).'px;" onmouseover="this.src=\''.$streamSrc.'\';" onmouseout="this.src=\''.$imgSrc.'\';"/>';
|
||||
|
||||
echo makePopupLink(
|
||||
'?view=frame&eid='.$event->Id().'&fid='.$thumbData['FrameId'],
|
||||
'?view=frame&eid='.$event->Id().'&fid='.( isset($thumbData['FrameId']) ? $thumbData['FrameId'] : 'snapshot' ),
|
||||
'zmImage',
|
||||
array( 'image', reScale( $event->Width(), $scale ), reScale( $event->Height(), $scale ) ),
|
||||
$imgHtml
|
||||
|
|
Loading…
Reference in New Issue