mirror of
https://github.com/ZoneMinder/zoneminder.git
synced 2026-04-04 06:02:27 -04:00
Merge branch 'master' into rtsp_server
Cleanup Analysis a bit. We can't skip packets just because they are audio. Clean up the state machine transitions a bit to make them a little more readable. Change logic of PrimeCapture, success MUST return 1. 0 means no error but also no success. Debugging and braces improvements in local_camera.
This commit is contained in:
@@ -47,10 +47,14 @@ public:
|
||||
|
||||
inline const Coord &Lo() const { return lo; }
|
||||
inline int LoX() const { return lo.X(); }
|
||||
inline int LoX(int p_lo_x) { return lo.X(p_lo_x); }
|
||||
inline int LoY() const { return lo.Y(); }
|
||||
inline int LoY(int p_lo_y) { return lo.Y(p_lo_y); }
|
||||
inline const Coord &Hi() const { return hi; }
|
||||
inline int HiX() const { return hi.X(); }
|
||||
inline int HiX(int p_hi_x) { return hi.X(p_hi_x); }
|
||||
inline int HiY() const { return hi.Y(); }
|
||||
inline int HiY(int p_hi_y) { return hi.Y(p_hi_y); }
|
||||
inline const Coord &Size() const { return size; }
|
||||
inline int Width() const { return size.X(); }
|
||||
inline int Height() const { return size.Y(); }
|
||||
|
||||
@@ -38,14 +38,14 @@ public:
|
||||
y = coord.y;
|
||||
return *this;
|
||||
}
|
||||
inline int &X() { return( x ); }
|
||||
inline const int &X() const { return( x ); }
|
||||
inline int &Y() { return( y ); }
|
||||
inline const int &Y() const { return( y ); }
|
||||
inline int &X(int p_x) { x=p_x; return x; }
|
||||
inline const int &X() const { return x; }
|
||||
inline int &Y(int p_y) { y=p_y; return y; }
|
||||
inline const int &Y() const { return y; }
|
||||
|
||||
inline static Coord Range( const Coord &coord1, const Coord &coord2 ) {
|
||||
Coord result( (coord1.x-coord2.x)+1, (coord1.y-coord2.y)+1 );
|
||||
return( result );
|
||||
return result;
|
||||
}
|
||||
|
||||
inline bool operator==( const Coord &coord ) const { return( x == coord.x && y == coord.y ); }
|
||||
|
||||
@@ -178,6 +178,7 @@ class Event {
|
||||
return pre_alarm_count;
|
||||
}
|
||||
static void EmptyPreAlarmFrames() {
|
||||
#if 0
|
||||
while ( pre_alarm_count > 0 ) {
|
||||
int i = pre_alarm_count - 1;
|
||||
delete pre_alarm_data[i].image;
|
||||
@@ -188,6 +189,7 @@ class Event {
|
||||
}
|
||||
pre_alarm_count--;
|
||||
}
|
||||
#endif
|
||||
pre_alarm_count = 0;
|
||||
}
|
||||
static void AddPreAlarmFrame(
|
||||
@@ -196,15 +198,18 @@ class Event {
|
||||
int score=0,
|
||||
Image *alarm_frame=nullptr
|
||||
) {
|
||||
#if 0
|
||||
pre_alarm_data[pre_alarm_count].image = new Image(*image);
|
||||
pre_alarm_data[pre_alarm_count].timestamp = timestamp;
|
||||
pre_alarm_data[pre_alarm_count].score = score;
|
||||
if ( alarm_frame ) {
|
||||
pre_alarm_data[pre_alarm_count].alarm_frame = new Image(*alarm_frame);
|
||||
}
|
||||
#endif
|
||||
pre_alarm_count++;
|
||||
}
|
||||
void SavePreAlarmFrames() {
|
||||
#if 0
|
||||
for ( int i = 0; i < pre_alarm_count; i++ ) {
|
||||
AddFrame(
|
||||
pre_alarm_data[i].image,
|
||||
@@ -212,6 +217,7 @@ class Event {
|
||||
pre_alarm_data[i].score,
|
||||
pre_alarm_data[i].alarm_frame);
|
||||
}
|
||||
#endif
|
||||
EmptyPreAlarmFrames();
|
||||
}
|
||||
};
|
||||
|
||||
@@ -207,7 +207,7 @@ int FfmpegCamera::PrimeCapture() {
|
||||
mAudioStreamId = -1;
|
||||
Debug(1, "Priming capture from %s", mPath.c_str());
|
||||
|
||||
return ! OpenFfmpeg();
|
||||
return OpenFfmpeg();
|
||||
}
|
||||
|
||||
int FfmpegCamera::PreCapture() {
|
||||
|
||||
@@ -17,26 +17,10 @@ FFmpeg_Input::~FFmpeg_Input() {
|
||||
if ( input_format_context ) {
|
||||
Close();
|
||||
}
|
||||
if ( streams ) {
|
||||
for ( unsigned int i = 0; i < input_format_context->nb_streams; i += 1 ) {
|
||||
avcodec_close(streams[i].context);
|
||||
avcodec_free_context(&streams[i].context);
|
||||
}
|
||||
delete[] streams;
|
||||
streams = nullptr;
|
||||
}
|
||||
if ( frame ) {
|
||||
av_frame_free(&frame);
|
||||
frame = nullptr;
|
||||
}
|
||||
if ( input_format_context ) {
|
||||
#if !LIBAVFORMAT_VERSION_CHECK(53, 17, 0, 25, 0)
|
||||
av_close_input_file(input_format_context);
|
||||
#else
|
||||
avformat_close_input(&input_format_context);
|
||||
#endif
|
||||
input_format_context = nullptr;
|
||||
}
|
||||
} // end ~FFmpeg_Input()
|
||||
|
||||
int FFmpeg_Input::Open(
|
||||
@@ -137,14 +121,16 @@ int FFmpeg_Input::Open(const char *filepath) {
|
||||
} // end int FFmpeg_Input::Open( const char * filepath )
|
||||
|
||||
int FFmpeg_Input::Close( ) {
|
||||
for ( unsigned int i = 0; i < input_format_context->nb_streams; i += 1 ) {
|
||||
if ( streams[i].context ) {
|
||||
if ( streams ) {
|
||||
for ( unsigned int i = 0; i < input_format_context->nb_streams; i += 1 ) {
|
||||
avcodec_close(streams[i].context);
|
||||
#if LIBAVCODEC_VERSION_CHECK(57, 64, 0, 64, 0)
|
||||
avcodec_free_context(&streams[i].context);
|
||||
streams[i].context = nullptr;
|
||||
#endif
|
||||
streams[i].context = NULL;
|
||||
}
|
||||
delete[] streams;
|
||||
streams = nullptr;
|
||||
}
|
||||
|
||||
if ( input_format_context ) {
|
||||
@@ -153,7 +139,7 @@ int FFmpeg_Input::Close( ) {
|
||||
#else
|
||||
avformat_close_input(&input_format_context);
|
||||
#endif
|
||||
input_format_context = NULL;
|
||||
input_format_context = nullptr;
|
||||
}
|
||||
return 1;
|
||||
} // end int FFmpeg_Input::Close()
|
||||
@@ -164,7 +150,6 @@ AVFrame *FFmpeg_Input::get_frame(int stream_id) {
|
||||
av_init_packet(&packet);
|
||||
|
||||
while ( !frameComplete ) {
|
||||
|
||||
int ret = av_read_frame(input_format_context, &packet);
|
||||
if ( ret < 0 ) {
|
||||
if (
|
||||
@@ -184,33 +169,33 @@ AVFrame *FFmpeg_Input::get_frame(int stream_id) {
|
||||
|
||||
if ( (stream_id >= 0) && (packet.stream_index != stream_id) ) {
|
||||
Debug(1,"Packet is not for our stream (%d)", packet.stream_index );
|
||||
return NULL;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
AVCodecContext *context = streams[packet.stream_index].context;
|
||||
|
||||
if ( frame ) {
|
||||
av_frame_free(&frame);
|
||||
frame = zm_av_frame_alloc();
|
||||
if ( frame ) {
|
||||
av_frame_free(&frame);
|
||||
frame = zm_av_frame_alloc();
|
||||
} else {
|
||||
frame = zm_av_frame_alloc();
|
||||
}
|
||||
ret = zm_send_packet_receive_frame(context, frame, packet);
|
||||
if ( ret < 0 ) {
|
||||
Error("Unable to decode frame at frame %d: %d %s, continuing",
|
||||
streams[packet.stream_index].frame_count, ret, av_make_error_string(ret).c_str());
|
||||
zm_av_packet_unref(&packet);
|
||||
av_frame_free(&frame);
|
||||
continue;
|
||||
} else {
|
||||
if ( is_video_stream(input_format_context->streams[packet.stream_index]) ) {
|
||||
zm_dump_video_frame(frame, "resulting video frame");
|
||||
} else {
|
||||
frame = zm_av_frame_alloc();
|
||||
}
|
||||
ret = zm_send_packet_receive_frame(context, frame, packet);
|
||||
if ( ret < 0 ) {
|
||||
Error("Unable to decode frame at frame %d: %d %s, continuing",
|
||||
streams[packet.stream_index].frame_count, ret, av_make_error_string(ret).c_str());
|
||||
zm_av_packet_unref(&packet);
|
||||
av_frame_free(&frame);
|
||||
continue;
|
||||
} else {
|
||||
if ( is_video_stream(input_format_context->streams[packet.stream_index]) ) {
|
||||
zm_dump_video_frame(frame, "resulting video frame");
|
||||
} else {
|
||||
zm_dump_frame(frame, "resulting frame");
|
||||
}
|
||||
zm_dump_frame(frame, "resulting frame");
|
||||
}
|
||||
}
|
||||
|
||||
frameComplete = 1;
|
||||
frameComplete = 1;
|
||||
|
||||
zm_av_packet_unref(&packet);
|
||||
|
||||
|
||||
@@ -447,7 +447,7 @@ LocalCamera::LocalCamera(
|
||||
#if HAVE_LIBSWSCALE
|
||||
/* Try using swscale for the conversion */
|
||||
conversion_type = 1;
|
||||
Debug(2,"Using swscale for image conversion");
|
||||
Debug(2, "Using swscale for image conversion");
|
||||
if ( colours == ZM_COLOUR_RGB32 ) {
|
||||
subpixelorder = ZM_SUBPIX_ORDER_RGBA;
|
||||
imagePixFormat = AV_PIX_FMT_RGBA;
|
||||
@@ -650,7 +650,7 @@ LocalCamera::LocalCamera(
|
||||
|
||||
#if HAVE_LIBSWSCALE
|
||||
/* Initialize swscale stuff */
|
||||
if ( capture && conversion_type == 1 ) {
|
||||
if ( capture and (conversion_type == 1) ) {
|
||||
#if LIBAVCODEC_VERSION_CHECK(55, 28, 1, 45, 101)
|
||||
tmpPicture = av_frame_alloc();
|
||||
#else
|
||||
@@ -680,7 +680,7 @@ LocalCamera::LocalCamera(
|
||||
#endif
|
||||
mVideoStreamId = 0;
|
||||
mAudioStreamId = -1;
|
||||
video_stream = NULL;
|
||||
video_stream = nullptr;
|
||||
} // end LocalCamera::LocalCamera
|
||||
|
||||
LocalCamera::~LocalCamera() {
|
||||
@@ -689,7 +689,7 @@ LocalCamera::~LocalCamera() {
|
||||
|
||||
#if HAVE_LIBSWSCALE
|
||||
/* Clean up swscale stuff */
|
||||
if ( capture && conversion_type == 1 ) {
|
||||
if ( capture && (conversion_type == 1) ) {
|
||||
sws_freeContext(imgConversionContext);
|
||||
imgConversionContext = nullptr;
|
||||
|
||||
@@ -699,13 +699,6 @@ LocalCamera::~LocalCamera() {
|
||||
} // end LocalCamera::~LocalCamera
|
||||
|
||||
void LocalCamera::Initialise() {
|
||||
#if HAVE_LIBSWSCALE
|
||||
if ( logDebugging() )
|
||||
av_log_set_level(AV_LOG_DEBUG);
|
||||
else
|
||||
av_log_set_level(AV_LOG_QUIET);
|
||||
#endif // HAVE_LIBSWSCALE
|
||||
|
||||
Debug(3, "Opening video device %s", device.c_str());
|
||||
//if ( (vid_fd = open( device.c_str(), O_RDWR|O_NONBLOCK, 0 )) < 0 )
|
||||
if ( (vid_fd = open(device.c_str(), O_RDWR, 0)) < 0 )
|
||||
@@ -2021,12 +2014,12 @@ int LocalCamera::PrimeCapture() {
|
||||
#endif // ZM_HAS_V4L1
|
||||
mVideoStreamId = 0;
|
||||
|
||||
return 0;
|
||||
return 1;
|
||||
} // end LocalCamera::PrimeCapture
|
||||
|
||||
int LocalCamera::PreCapture() {
|
||||
//Debug(5, "Pre-capturing");
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int LocalCamera::Capture(ZMPacket &zm_packet) {
|
||||
@@ -2124,12 +2117,13 @@ int LocalCamera::Capture(ZMPacket &zm_packet) {
|
||||
} /* prime capture */
|
||||
|
||||
if ( ! zm_packet.image ) {
|
||||
Debug(1, "Allocating image");
|
||||
zm_packet.image = new Image(width, height, colours, subpixelorder);
|
||||
}
|
||||
|
||||
if ( conversion_type != 0 ) {
|
||||
|
||||
Debug(3, "Performing format conversion");
|
||||
Debug(3, "Performing format conversion %d", conversion_type);
|
||||
|
||||
/* Request a writeable buffer of the target image */
|
||||
uint8_t *directbuffer = zm_packet.image->WriteBuffer(width, height, colours, subpixelorder);
|
||||
|
||||
@@ -333,8 +333,8 @@ Monitor::Monitor()
|
||||
purpose(QUERY),
|
||||
auto_resume_time(0),
|
||||
last_motion_score(0),
|
||||
camera(0),
|
||||
event(0),
|
||||
camera(nullptr),
|
||||
event(nullptr),
|
||||
n_zones(0),
|
||||
zones(nullptr),
|
||||
timestamps(0),
|
||||
@@ -1768,14 +1768,6 @@ bool Monitor::Analyse() {
|
||||
packets_processed += 1;
|
||||
packetqueue->increment_analysis_it();
|
||||
|
||||
if ( snap->packet.stream_index != video_stream_id ) {
|
||||
snap->unlock();
|
||||
Debug(2, "skipping because audio");
|
||||
continue;
|
||||
}
|
||||
|
||||
struct timeval *timestamp = snap->timestamp;
|
||||
Image *snap_image = snap->image;
|
||||
|
||||
// signal is set by capture
|
||||
bool signal = shared_data->signal;
|
||||
@@ -1820,7 +1812,6 @@ bool Monitor::Analyse() {
|
||||
signalText = "Reacquired";
|
||||
score += 100;
|
||||
}
|
||||
Warning("%s: %s", SIGNAL_CAUSE, signalText);
|
||||
if ( event && !signal ) {
|
||||
Info("%s: %03d - Closing event %" PRIu64 ", signal loss", name, image_count, event->Id());
|
||||
closeEvent();
|
||||
@@ -1835,20 +1826,25 @@ bool Monitor::Analyse() {
|
||||
noteSetMap[SIGNAL_CAUSE] = noteSet;
|
||||
shared_data->state = state = IDLE;
|
||||
shared_data->active = signal;
|
||||
ref_image.Assign(*snap_image);
|
||||
ref_image.Assign(*(snap->image));
|
||||
}// else
|
||||
|
||||
if ( signal ) {
|
||||
if ( snap->packet.stream_index == video_stream_id ) {
|
||||
struct timeval *timestamp = snap->timestamp;
|
||||
|
||||
if ( Active() && (function == MODECT || function == MOCORD) ) {
|
||||
Debug(3, "signal and active and modect");
|
||||
Event::StringSet zoneSet;
|
||||
|
||||
int motion_score = last_motion_score;
|
||||
if ( !(analysis_image_count % (motion_frame_skip+1) ) ) {
|
||||
if ( snap->image ) {
|
||||
// Get new score.
|
||||
motion_score = DetectMotion(*snap_image, zoneSet);
|
||||
motion_score = DetectMotion(*(snap->image), zoneSet);
|
||||
|
||||
Debug(3, "After motion detection, last_motion_score(%d), new motion score(%d)", last_motion_score, motion_score);
|
||||
Debug(3, "After motion detection, score:%d last_motion_score(%d), new motion score(%d)",
|
||||
score, last_motion_score, motion_score);
|
||||
} else {
|
||||
Warning("No image in snap");
|
||||
}
|
||||
@@ -1862,7 +1858,6 @@ bool Monitor::Analyse() {
|
||||
cause += MOTION_CAUSE;
|
||||
noteSetMap[MOTION_CAUSE] = zoneSet;
|
||||
} // end if motion_score
|
||||
//shared_data->active = signal; // unneccessary active gets set on signal change
|
||||
} // end if active and doing motion detection
|
||||
|
||||
// Check to see if linked monitors are triggering.
|
||||
@@ -2028,45 +2023,69 @@ bool Monitor::Analyse() {
|
||||
// Back to IDLE
|
||||
shared_data->state = state = function != MOCORD ? IDLE : TAPE;
|
||||
} else {
|
||||
Debug(1, "Not leaving ALERT beacuse image_count(%d)-last_alarm_count(%d) > post_event_count(%d) and timestamp.tv_sec(%d) - recording.tv_src(%d) >= min_section_length(%d)", image_count, last_alarm_count, post_event_count, timestamp->tv_sec, video_store_data->recording.tv_sec, min_section_length);
|
||||
Debug(1, "State %d ALERT beacuse image_count(%d)-last_alarm_count(%d) > post_event_count(%d) and timestamp.tv_sec(%d) - recording.tv_src(%d) >= min_section_length(%d)",
|
||||
state, analysis_image_count, last_alarm_count, post_event_count,
|
||||
timestamp->tv_sec, video_store_data->recording.tv_sec, min_section_length);
|
||||
}
|
||||
if ( Event::PreAlarmCount() )
|
||||
Event::EmptyPreAlarmFrames();
|
||||
} // end if score or not
|
||||
|
||||
// Flag the packet so we don't analyse it again
|
||||
Debug(1, "Scoring packet");
|
||||
snap->score = score;
|
||||
|
||||
if ( state == PREALARM || state == ALARM ) {
|
||||
if ( state == PREALARM ) {
|
||||
// Generate analysis images if necessary
|
||||
if ( savejpegs > 1 ) {
|
||||
bool got_anal_image = false;
|
||||
Image *anal_image = new Image( *snap_image );
|
||||
//alarm_image.Assign( *snap_image );
|
||||
for( int i = 0; i < n_zones; i++ ) {
|
||||
for ( int i = 0; i < n_zones; i++ ) {
|
||||
if ( zones[i]->Alarmed() ) {
|
||||
if ( zones[i]->AlarmImage() ) {
|
||||
anal_image->Overlay( *(zones[i]->AlarmImage()) );
|
||||
got_anal_image = true;
|
||||
if ( ! snap->analysis_image )
|
||||
snap->analysis_image = new Image(*(snap->image));
|
||||
snap->analysis_image->Overlay( *(zones[i]->AlarmImage()) );
|
||||
}
|
||||
if ( config.record_event_stats && (state == ALARM) )
|
||||
} // end if zone is alarmed
|
||||
} // end foreach zone
|
||||
} // end if savejpegs
|
||||
|
||||
// incremement pre alarm image count
|
||||
//have_pre_alarmed_frames ++;
|
||||
Event::AddPreAlarmFrame(snap->image, *timestamp, score, nullptr);
|
||||
} else if ( state == ALARM ) {
|
||||
if ( savejpegs > 1 ) {
|
||||
for ( int i = 0; i < n_zones; i++ ) {
|
||||
if ( zones[i]->Alarmed() ) {
|
||||
if ( zones[i]->AlarmImage() ) {
|
||||
if ( ! snap->analysis_image )
|
||||
snap->analysis_image = new Image(*(snap->image));
|
||||
snap->analysis_image->Overlay(*(zones[i]->AlarmImage()));
|
||||
}
|
||||
if ( config.record_event_stats )
|
||||
zones[i]->RecordStats(event);
|
||||
} // end if zone is alarmed
|
||||
} // end foreach zone
|
||||
if ( got_anal_image ) {
|
||||
snap->analysis_image = anal_image;
|
||||
} else {
|
||||
delete anal_image;
|
||||
}
|
||||
} else if ( config.record_event_stats && state == ALARM ) {
|
||||
for ( int i = 0; i < n_zones; i++ ) {
|
||||
if ( zones[i]->Alarmed() ) {
|
||||
zones[i]->RecordStats(event);
|
||||
}
|
||||
} // end foreach zone
|
||||
} // analsys_images or record stats
|
||||
|
||||
}
|
||||
if ( noteSetMap.size() > 0 )
|
||||
event->updateNotes( noteSetMap );
|
||||
event->updateNotes(noteSetMap);
|
||||
if ( section_length
|
||||
&& ( ( timestamp->tv_sec - video_store_data->recording.tv_sec ) >= section_length )
|
||||
&& ! (image_count % fps_report_interval)
|
||||
) {
|
||||
Warning("%s: %03d - event %" PRIu64 ", has exceeded desired section length. %d - %d = %d >= %d",
|
||||
name, image_count, event->Id(),
|
||||
timestamp->tv_sec, video_store_data->recording.tv_sec,
|
||||
timestamp->tv_sec - video_store_data->recording.tv_sec,
|
||||
section_length
|
||||
);
|
||||
closeEvent();
|
||||
event = new Event(this, *timestamp, cause, noteSetMap);
|
||||
shared_data->last_event_id = event->Id();
|
||||
//set up video store data
|
||||
snprintf(video_store_data->event_file, sizeof(video_store_data->event_file), "%s", event->getEventFile());
|
||||
video_store_data->recording = event->StartTime();
|
||||
}
|
||||
|
||||
} else if ( state == ALERT ) {
|
||||
// Alert means this frame has no motion, but we were alarmed and are still recording.
|
||||
if ( noteSetMap.size() > 0 )
|
||||
@@ -2079,11 +2098,14 @@ bool Monitor::Analyse() {
|
||||
//event->AddFrame( snap_image, *timestamp );
|
||||
//}
|
||||
//}
|
||||
}
|
||||
if ( function == MODECT || function == MOCORD ) {
|
||||
ref_image.Blend( *snap_image, ( state==ALARM ? alarm_ref_blend_perc : ref_blend_perc ) );
|
||||
}
|
||||
last_signal = signal;
|
||||
} // end if state machine
|
||||
|
||||
if ( function == MODECT || function == MOCORD ) {
|
||||
ref_image.Blend(*(snap->image), ( state==ALARM ? alarm_ref_blend_perc : ref_blend_perc ));
|
||||
}
|
||||
last_signal = signal;
|
||||
|
||||
} // end if videostream
|
||||
} // end if signal
|
||||
|
||||
} else {
|
||||
@@ -2826,7 +2848,7 @@ unsigned int Monitor::SubpixelOrder() const { return camera->SubpixelOrder(); }
|
||||
|
||||
int Monitor::PrimeCapture() {
|
||||
int ret = camera->PrimeCapture();
|
||||
if ( ret == 0 ) {
|
||||
if ( ret > 0 ) {
|
||||
if ( packetqueue )
|
||||
delete packetqueue;
|
||||
video_stream_id = camera->get_VideoStreamId();
|
||||
@@ -2835,14 +2857,13 @@ int Monitor::PrimeCapture() {
|
||||
Debug(2, "Video stream id is %d, audio is %d, minimum_packets to keep in buffer %d",
|
||||
video_stream_id, audio_stream_id, pre_event_buffer_count);
|
||||
} else {
|
||||
Debug(2, "Not Video stream id is %d, audio is %d, minimum_packets to keep in buffer %d",
|
||||
video_stream_id, audio_stream_id, pre_event_buffer_count);
|
||||
Debug(2, "Failed to prime %d", ret);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int Monitor::PreCapture() const { return camera->PreCapture(); }
|
||||
int Monitor::PostCapture() const { return camera->PostCapture() ; }
|
||||
int Monitor::PostCapture() const { return camera->PostCapture(); }
|
||||
int Monitor::Close() {
|
||||
if ( packetqueue ) {
|
||||
delete packetqueue;
|
||||
|
||||
@@ -100,9 +100,13 @@ public:
|
||||
|
||||
inline const Box &Extent() const { return extent; }
|
||||
inline int LoX() const { return extent.LoX(); }
|
||||
inline int LoX(int p_lo_x) { return extent.LoX(p_lo_x); }
|
||||
inline int HiX() const { return extent.HiX(); }
|
||||
inline int HiX(int p_hi_x) { return extent.HiX(p_hi_x); }
|
||||
inline int LoY() const { return extent.LoY(); }
|
||||
inline int LoY(int p_lo_y) { return extent.LoY(p_lo_y); }
|
||||
inline int HiY() const { return extent.HiY(); }
|
||||
inline int HiY(int p_hi_y) { return extent.HiY(p_hi_y); }
|
||||
inline int Width() const { return extent.Width(); }
|
||||
inline int Height() const { return extent.Height(); }
|
||||
|
||||
|
||||
@@ -269,9 +269,9 @@ void *Thread::mThreadFunc( void *arg ) {
|
||||
}
|
||||
|
||||
void Thread::start() {
|
||||
Debug( 1, "Starting thread" );
|
||||
Debug(4, "Starting thread" );
|
||||
if ( isThread() )
|
||||
throw ThreadException( "Can't self start thread" );
|
||||
throw ThreadException("Can't self start thread");
|
||||
mThreadMutex.lock();
|
||||
if ( !mStarted ) {
|
||||
pthread_attr_t threadAttrs;
|
||||
@@ -287,11 +287,11 @@ void Thread::start() {
|
||||
}
|
||||
mThreadCondition.wait();
|
||||
mThreadMutex.unlock();
|
||||
Debug( 1, "Started thread %d", mPid );
|
||||
Debug(4, "Started thread %d", mPid);
|
||||
}
|
||||
|
||||
void Thread::join() {
|
||||
Debug( 1, "Joining thread %d", mPid );
|
||||
Debug(1, "Joining thread %d", mPid);
|
||||
if ( isThread() )
|
||||
throw ThreadException( "Can't self join thread" );
|
||||
mThreadMutex.lock();
|
||||
|
||||
@@ -148,14 +148,14 @@ bool VideoStore::open() {
|
||||
int wanted_codec = monitor->OutputCodec();
|
||||
if ( !wanted_codec ) {
|
||||
// default to h264
|
||||
Debug(2, "Defaulting to H264");
|
||||
wanted_codec = AV_CODEC_ID_H264;
|
||||
//Debug(2, "Defaulting to H264");
|
||||
//wanted_codec = AV_CODEC_ID_H264;
|
||||
} else {
|
||||
Debug(2, "Codec is %d, wanted %d", video_in_ctx->codec_id, wanted_codec);
|
||||
}
|
||||
|
||||
// FIXME Should check that we are set to passthrough. Might be same codec, but want privacy overlays
|
||||
if ( video_in_ctx->codec_id == wanted_codec ) {
|
||||
if ( (!wanted_codec) or (video_in_ctx->codec_id == wanted_codec) ) {
|
||||
// Copy params from instream to ctx
|
||||
#if LIBAVCODEC_VERSION_CHECK(57, 64, 0, 64, 0)
|
||||
ret = avcodec_parameters_to_context(video_out_ctx, video_in_stream->codecpar);
|
||||
@@ -235,6 +235,8 @@ bool VideoStore::open() {
|
||||
|
||||
AVDictionary *opts = 0;
|
||||
std::string Options = monitor->GetEncoderOptions();
|
||||
Debug(2, "Options?");
|
||||
Debug(2, "Options? %s", Options.c_str());
|
||||
ret = av_dict_parse_string(&opts, Options.c_str(), "=", ",#\n", 0);
|
||||
if ( ret < 0 ) {
|
||||
Warning("Could not parse ffmpeg encoder options list '%s'\n", Options.c_str());
|
||||
|
||||
@@ -891,10 +891,12 @@ int Zone::Load(Monitor *monitor, Zone **&zones) {
|
||||
|
||||
if ( polygon.LoX() < 0 || polygon.HiX() >= (int)monitor->Width()
|
||||
|| polygon.LoY() < 0 || polygon.HiY() >= (int)monitor->Height() ) {
|
||||
Error("Zone %d/%s for monitor %s extends outside of image dimensions, (%d,%d), (%d,%d), ignoring",
|
||||
Error("Zone %d/%s for monitor %s extends outside of image dimensions, (%d,%d), (%d,%d), fixing",
|
||||
Id, Name, monitor->Name(), polygon.LoX(), polygon.LoY(), polygon.HiX(), polygon.HiY());
|
||||
n_zones -= 1;
|
||||
continue;
|
||||
if ( polygon.LoX() < 0 ) polygon.LoX(0);
|
||||
if ( polygon.HiX() >= (int)monitor->Width()) polygon.HiX((int)monitor->Width());
|
||||
if ( polygon.LoY() < 0 ) polygon.LoY(0);
|
||||
if ( polygon.HiY() >= (int)monitor->Height() ) polygon.HiY((int)monitor->Height());
|
||||
}
|
||||
|
||||
if ( false && !strcmp( Units, "Percent" ) ) {
|
||||
|
||||
10
src/zmc.cpp
10
src/zmc.cpp
@@ -269,15 +269,18 @@ int main(int argc, char *argv[]) {
|
||||
} // end foreach monitor
|
||||
|
||||
// Outer primary loop, handles connection to camera
|
||||
if ( monitors[0]->PrimeCapture() < 0 ) {
|
||||
if ( monitors[0]->PrimeCapture() <= 0 ) {
|
||||
if ( prime_capture_log_count % 60 ) {
|
||||
Error("Failed to prime capture of initial monitor");
|
||||
} else {
|
||||
Debug(1, "Failed to prime capture of initial monitor");
|
||||
}
|
||||
prime_capture_log_count ++;
|
||||
if ( !zm_terminate )
|
||||
sleep(10);
|
||||
monitors[0]->disconnect();
|
||||
if ( !zm_terminate ) {
|
||||
Debug(1, "Sleeping");
|
||||
sleep(5);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
for ( int i = 0; i < n_monitors; i++ ) {
|
||||
@@ -415,6 +418,7 @@ int main(int argc, char *argv[]) {
|
||||
delete [] monitors;
|
||||
|
||||
Image::Deinitialise();
|
||||
Debug(1,"terminating");
|
||||
logTerm();
|
||||
zmDbClose();
|
||||
|
||||
|
||||
@@ -296,50 +296,44 @@ function getCollapsedNavBarHTML($running, $user, $bandwidth_options, $view, $ski
|
||||
|
||||
?>
|
||||
<div class="fixed-top container-fluid p-0">
|
||||
<nav class="navbar navbar-dark bg-dark px-1 flex-nowrap">
|
||||
<nav class="navbar navbar-dark bg-dark px-1 flex-nowrap">
|
||||
|
||||
<div class="navbar-brand align-self-start px-0">
|
||||
<?php echo getNavBrandHTML() ?>
|
||||
</div>
|
||||
|
||||
<nav class="navbar navbar-expand-md align-self-start px-0">
|
||||
<ul class="nav navbar-nav list-group px-0">
|
||||
<?php
|
||||
<div class="navbar-brand align-self-start px-0">
|
||||
<?php echo getNavBrandHTML() ?>
|
||||
</div>
|
||||
|
||||
<nav class="navbar navbar-expand-md align-self-start px-0">
|
||||
<?php
|
||||
// *** Build the statistics shown on the navigation bar ***
|
||||
if ( (!ZM_OPT_USE_AUTH) or $user ) {
|
||||
?>
|
||||
<div id="reload" class="collapse navbar-collapse px-0">
|
||||
?>
|
||||
<div id="reload" class="collapse navbar-collapse px-0">
|
||||
|
||||
<ul id="Version" class="pr-2">
|
||||
<?php echo getZMVersionHTML() ?>
|
||||
</ul>
|
||||
|
||||
<ul id="Bandwidth" class="px-2">
|
||||
<?php echo getBandwidthHTML($bandwidth_options, $user) ?>
|
||||
</ul>
|
||||
|
||||
<?php
|
||||
echo getSysLoadHTML();
|
||||
echo getDbConHTML();
|
||||
echo getStorageHTML();
|
||||
echo getShmHTML();
|
||||
echo getLogIconHTML();
|
||||
?>
|
||||
|
||||
</div>
|
||||
<ul id="Version" class="pr-2">
|
||||
<?php echo getZMVersionHTML() ?>
|
||||
</ul>
|
||||
|
||||
<ul id="Bandwidth" class="px-2">
|
||||
<?php echo getBandwidthHTML($bandwidth_options, $user) ?>
|
||||
</ul>
|
||||
<?php
|
||||
echo getSysLoadHTML();
|
||||
echo getDbConHTML();
|
||||
echo getStorageHTML();
|
||||
echo getShmHTML();
|
||||
echo getLogIconHTML();
|
||||
?>
|
||||
</div>
|
||||
<?php
|
||||
} // end if (!ZM_OPT_USE_AUTH) or $user )
|
||||
?>
|
||||
</nav>
|
||||
</nav>
|
||||
|
||||
<ul class="list-group list-group-horizontal ml-auto">
|
||||
<ul class="list-group list-group-horizontal ml-auto">
|
||||
<?php
|
||||
echo getAcctCircleHTML($skin, $user);
|
||||
echo getStatusBtnHTML($status);
|
||||
?>
|
||||
</ul>
|
||||
</ul>
|
||||
|
||||
<!-- the Navigation Bar Hamburger Button -->
|
||||
@@ -350,30 +344,30 @@ function getCollapsedNavBarHTML($running, $user, $bandwidth_options, $view, $ski
|
||||
</button>
|
||||
<?php } ?>
|
||||
|
||||
<div style="background-color:#485460" class="dropdown-menu dropdown-menu-right px-3" id="main-header-nav">
|
||||
<?php
|
||||
if ( $user and $user['Username'] ) {
|
||||
echo '<ul class="navbar-nav">';
|
||||
echo getConsoleHTML();
|
||||
echo getOptionsHTML();
|
||||
echo getLogHTML();
|
||||
echo getDevicesHTML();
|
||||
echo getGroupsHTML($view);
|
||||
echo getFilterHTML($view);
|
||||
echo getCycleHTML($view);
|
||||
echo getMontageHTML($view);
|
||||
echo getMontageReviewHTML($view);
|
||||
echo getRprtEvntAuditHTML($view);
|
||||
echo '</ul>';
|
||||
}
|
||||
?>
|
||||
</div>
|
||||
<div style="background-color:#485460" class="dropdown-menu dropdown-menu-right px-3" id="main-header-nav">
|
||||
<?php
|
||||
if ( $user and $user['Username'] ) {
|
||||
echo '<ul class="navbar-nav">';
|
||||
echo getConsoleHTML();
|
||||
echo getOptionsHTML();
|
||||
echo getLogHTML();
|
||||
echo getDevicesHTML();
|
||||
echo getGroupsHTML($view);
|
||||
echo getFilterHTML($view);
|
||||
echo getCycleHTML($view);
|
||||
echo getMontageHTML($view);
|
||||
echo getMontageReviewHTML($view);
|
||||
echo getRprtEvntAuditHTML($view);
|
||||
echo '</ul>';
|
||||
}
|
||||
?>
|
||||
</div>
|
||||
|
||||
</nav><!-- End First Navbar -->
|
||||
</nav><!-- End First Navbar -->
|
||||
|
||||
<nav class="navbar navbar-expand-md bg-dark justify-content-center p-0">
|
||||
<?php echo getConsoleBannerHTML() ?>
|
||||
</nav><!-- End Second Navbar -->
|
||||
<nav class="navbar navbar-expand-md bg-dark justify-content-center p-0">
|
||||
<?php echo getConsoleBannerHTML() ?>
|
||||
</nav><!-- End Second Navbar -->
|
||||
</div>
|
||||
|
||||
<?php
|
||||
|
||||
Reference in New Issue
Block a user