From 84c812725e5322c87a0428fec83704580098e52d Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Mon, 14 Jan 2019 14:00:45 -0500 Subject: [PATCH 001/214] spacing, improve debug. WHen looking for starting keyframe in packetqueue, use <= instead of <. --- src/zm_ffmpeg_camera.cpp | 2 +- src/zm_packetqueue.cpp | 17 +++++++++++------ src/zm_stream.cpp | 6 +++--- 3 files changed, 15 insertions(+), 10 deletions(-) diff --git a/src/zm_ffmpeg_camera.cpp b/src/zm_ffmpeg_camera.cpp index ef61afc09..390f347de 100644 --- a/src/zm_ffmpeg_camera.cpp +++ b/src/zm_ffmpeg_camera.cpp @@ -721,7 +721,7 @@ int FfmpegCamera::CaptureAndRecord( Image &image, timeval recording, char* event //Video recording if ( keyframe && recording.tv_sec ) { - uint32_t last_event_id = monitor->GetLastEventId() ; + uint32_t last_event_id = monitor->GetLastEventId(); uint32_t video_writer_event_id = monitor->GetVideoWriterEventId(); if ( last_event_id != video_writer_event_id ) { diff --git a/src/zm_packetqueue.cpp b/src/zm_packetqueue.cpp index 850e482fb..44bc35c0b 100644 --- a/src/zm_packetqueue.cpp +++ b/src/zm_packetqueue.cpp @@ -144,7 +144,7 @@ void zm_packetqueue::clear_unwanted_packets( timeval *recording_started, int mVi // Step 2 - pop packets until we get to the packet in step 2 std::list::reverse_iterator it; - Debug(3, "Looking for keyframe after start recording stream id (%d)", mVideoStreamId ); + Debug(3, "Looking for keyframe after start recording stream id (%d)", mVideoStreamId); for ( it = pktQueue.rbegin(); it != pktQueue.rend(); ++ it ) { ZMPacket *zm_packet = *it; AVPacket *av_packet = &(zm_packet->packet); @@ -153,9 +153,12 @@ void zm_packetqueue::clear_unwanted_packets( timeval *recording_started, int mVi && ( av_packet->stream_index == mVideoStreamId ) && - timercmp( &(zm_packet->timestamp), recording_started, < ) + timercmp( &(zm_packet->timestamp), recording_started, <= ) ) { - Debug(3, "Found keyframe before start with stream index (%d) with keyframe (%d)", av_packet->stream_index, ( av_packet->flags & AV_PKT_FLAG_KEY ) ); + Debug(3, "Found keyframe before start with stream index %d at %d.%d", + av_packet->stream_index, + zm_packet->timestamp.tv_sec, + zm_packet->timestamp.tv_usec ); break; } } @@ -174,7 +177,7 @@ void zm_packetqueue::clear_unwanted_packets( timeval *recording_started, int mVi unsigned int deleted_frames = 0; ZMPacket *packet = NULL; - while ( distance( it, pktQueue.rend() ) > 1 ) { + while ( distance(it, pktQueue.rend()) > 1 ) { //while ( pktQueue.rend() != it ) { packet = pktQueue.front(); pktQueue.pop_front(); @@ -185,8 +188,10 @@ void zm_packetqueue::clear_unwanted_packets( timeval *recording_started, int mVi zm_packet = pktQueue.front(); av_packet = &(zm_packet->packet); if ( ( ! ( av_packet->flags & AV_PKT_FLAG_KEY ) ) || ( av_packet->stream_index != mVideoStreamId ) ) { - Error( "Done looking for keyframe. Deleted %d frames. Remaining frames in queue: %d stream of head packet is (%d), keyframe (%d), distance(%d), packets(%d)", deleted_frames, pktQueue.size(), av_packet->stream_index, ( av_packet->flags & AV_PKT_FLAG_KEY ), distance( it, pktQueue.rend() ), pktQueue.size() ); + Error( "Done looking for keyframe. Deleted %d frames. Remaining frames in queue: %d stream of head packet is (%d), keyframe (%d), distance(%d), packets(%d)", + deleted_frames, pktQueue.size(), av_packet->stream_index, ( av_packet->flags & AV_PKT_FLAG_KEY ), distance( it, pktQueue.rend() ), pktQueue.size() ); } else { - Debug(1, "Done looking for keyframe. Deleted %d frames. Remaining frames in queue: %d stream of head packet is (%d), keyframe (%d), distance(%d), packets(%d)", deleted_frames, pktQueue.size(), av_packet->stream_index, ( av_packet->flags & AV_PKT_FLAG_KEY ), distance( it, pktQueue.rend() ), pktQueue.size() ); + Debug(1, "Done looking for keyframe. Deleted %d frames. Remaining frames in queue: %d stream of head packet is (%d), keyframe (%d), distance(%d), packets(%d)", + deleted_frames, pktQueue.size(), av_packet->stream_index, ( av_packet->flags & AV_PKT_FLAG_KEY ), distance( it, pktQueue.rend() ), pktQueue.size() ); } } diff --git a/src/zm_stream.cpp b/src/zm_stream.cpp index 8602fa88a..357d23ed7 100644 --- a/src/zm_stream.cpp +++ b/src/zm_stream.cpp @@ -54,7 +54,7 @@ bool StreamBase::loadMonitor(int monitor_id) { bool StreamBase::checkInitialised() { if ( !monitor ) { - Fatal( "Cannot stream, not initialised" ); + Fatal("Cannot stream, not initialised"); return false; } return true; @@ -67,10 +67,10 @@ void StreamBase::updateFrameRate(double fps) { Debug(3, "FPS:%.2f, MaxFPS:%.2f, BaseFPS:%.2f, EffectiveFPS:%.2f, FrameMod:%d, replay_rate(%d)", fps, maxfps, base_fps, effective_fps, frame_mod, replay_rate); // Min frame repeat? - while( effective_fps > maxfps ) { + while ( effective_fps > maxfps ) { effective_fps /= 2.0; frame_mod *= 2; - Debug(3, "EffectiveFPS:%.2f, FrameMod:%d", effective_fps, frame_mod); + Debug(3, "Changing fps to be < max %.2f EffectiveFPS:%.2f, FrameMod:%d", maxfps, effective_fps, frame_mod); } } From 6608cb4e35159e552415b86d7b562ea2ddf92438 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Tue, 15 Jan 2019 11:25:22 -0500 Subject: [PATCH 002/214] use frame delta to determine how much to sleep --- src/zm_eventstream.cpp | 28 +++++++++++++++++++++++----- 1 file changed, 23 insertions(+), 5 deletions(-) diff --git a/src/zm_eventstream.cpp b/src/zm_eventstream.cpp index 91d3dfeb4..f390a8c03 100644 --- a/src/zm_eventstream.cpp +++ b/src/zm_eventstream.cpp @@ -145,7 +145,7 @@ bool EventStream::loadEventData(uint64_t event_id) { event_data->storage_id = dbrow[1] ? atoi( dbrow[1] ) : 0; event_data->frame_count = dbrow[2] == NULL ? 0 : atoi(dbrow[2]); event_data->start_time = atoi(dbrow[3]); - event_data->duration = atof(dbrow[4]); + event_data->duration = dbrow[4] ? atof(dbrow[4]) : 0.0; strncpy( event_data->video_file, dbrow[5], sizeof(event_data->video_file)-1 ); std::string scheme_str = std::string(dbrow[6]); if ( scheme_str == "Deep" ) { @@ -762,7 +762,7 @@ Debug(1, "Loading image"); } last_frame_sent = TV_2_FLOAT(now); return true; -} +} // sendFrame(int delta_us) void EventStream::runStream() { openComms(); @@ -780,11 +780,12 @@ void EventStream::runStream() { Debug(3, "frame rate is: (%f)", (double)event_data->frame_count/event_data->duration); updateFrameRate((double)event_data->frame_count/event_data->duration); + gettimeofday(&start, NULL); while( !zm_terminate ) { gettimeofday(&now, NULL); - unsigned int delta_us = 0; + int delta_us = 0; send_frame = false; // commands may set send_frame to true @@ -850,6 +851,7 @@ Debug(3,"cur_frame_id (%d-1) mod frame_mod(%d)",curr_frame_id, frame_mod); Debug(3,"delta %u = base_fps(%f)/effective fps(%f)", delta_us, base_fps, effective_fps); // but must not exceed maxfps delta_us = max(delta_us, 1000000 / maxfps); + Debug(3,"delta %u = base_fps(%f)/effective fps(%f)", delta_us, base_fps, effective_fps); send_frame = true; } } else if ( step != 0 ) { @@ -870,18 +872,34 @@ Debug(3,"cur_frame_id (%d-1) mod frame_mod(%d)",curr_frame_id, frame_mod); if ( !sendFrame(delta_us) ) zm_terminate = true; + curr_stream_time = frame_data->timestamp; if ( !paused ) { curr_frame_id += (replay_rate>0) ? 1 : -1; + + + if ( (mode == MODE_SINGLE) && ((unsigned int)curr_frame_id == event_data->frame_count) ) { Debug(2, "Have mode==MODE_SINGLE and at end of event, looping back to start"); curr_frame_id = 1; } + frame_data = &event_data->frames[curr_frame_id-1]; + + uint64_t now_usec = (now.tv_sec * 1000000 + now.tv_usec); + uint64_t start_usec = (start.tv_sec * 1000000 + start.tv_usec); + uint64_t frame_delta = frame_data->delta*1000000; + + delta_us = frame_delta - (now_usec - start_usec); + Debug(2, "New delta_us now %" PRIu64 " - start %" PRIu64 " = %d - frame %" PRIu64 " = %d", + now_usec, start_usec, now_usec-start_usec, frame_delta, + delta_us); + if ( send_frame && type != STREAM_MPEG ) { - Debug( 3, "dUs: %d", delta_us ); - if ( delta_us ) + if ( delta_us > 0 ) { + Debug( 3, "dUs: %d", delta_us ); usleep( delta_us ); + } } } else { usleep( (unsigned long)((1000000 * ZM_RATE_BASE)/((base_fps?base_fps:1)*abs(replay_rate*2))) ); From 8c53f778b696914e854607cb1da8567d620aa527 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Tue, 15 Jan 2019 11:32:44 -0500 Subject: [PATCH 003/214] Start and stop events not just on keyframe. This means we must always queue packets --- src/zm_ffmpeg_camera.cpp | 54 ++++++++++++++++++++-------------------- 1 file changed, 27 insertions(+), 27 deletions(-) diff --git a/src/zm_ffmpeg_camera.cpp b/src/zm_ffmpeg_camera.cpp index 390f347de..940fa3fd2 100644 --- a/src/zm_ffmpeg_camera.cpp +++ b/src/zm_ffmpeg_camera.cpp @@ -718,15 +718,15 @@ int FfmpegCamera::CaptureAndRecord( Image &image, timeval recording, char* event bytes += packet.size; dumpPacket(mFormatContext->streams[packet.stream_index], &packet, "Captured"); - //Video recording - if ( keyframe && recording.tv_sec ) { + // Video recording + if ( recording.tv_sec ) { uint32_t last_event_id = monitor->GetLastEventId(); uint32_t video_writer_event_id = monitor->GetVideoWriterEventId(); if ( last_event_id != video_writer_event_id ) { Debug(2, "Have change of event. last_event(%d), our current (%d)", - last_event_id, video_writer_event_id); + last_event_id, video_writer_event_id); if ( videoStore ) { Info("Re-starting video storage module"); @@ -800,7 +800,8 @@ int FfmpegCamera::CaptureAndRecord( Image &image, timeval recording, char* event packet_count += 1; //Write the packet to our video store - Debug(2, "Writing queued packet stream: %d KEY %d, remaining (%d)", avp->stream_index, avp->flags & AV_PKT_FLAG_KEY, packetqueue.size() ); + Debug(2, "Writing queued packet stream: %d KEY %d, remaining (%d)", + avp->stream_index, avp->flags & AV_PKT_FLAG_KEY, packetqueue.size() ); if ( avp->stream_index == mVideoStreamId ) { ret = videoStore->writeVideoFramePacket( avp ); have_video_keyframe = true; @@ -822,36 +823,35 @@ int FfmpegCamera::CaptureAndRecord( Image &image, timeval recording, char* event } else { // Not recording - if ( videoStore && keyframe ) { - Info("Deleting videoStore instance"); + if ( videoStore ) { + Debug(1,"Deleting videoStore instance"); delete videoStore; videoStore = NULL; have_video_keyframe = false; monitor->SetVideoWriterEventId(0); } - if ( ! videoStore ) { - // Buffer video packets, since we are not recording. - // All audio packets are keyframes, so only if it's a video keyframe - if ( packet.stream_index == mVideoStreamId ) { - if ( keyframe ) { - packetqueue.clearQueue(monitor->GetPreEventCount(), mVideoStreamId); - packetqueue.queuePacket(&packet); - } else if ( packetqueue.size() ) { - Debug(3, "queue has %d", packetqueue.size()); - // it's a keyframe or we already have something in the queue - packetqueue.queuePacket(&packet); - } - } else if ( packet.stream_index == mAudioStreamId ) { - // The following lines should ensure that the queue always begins with a video keyframe - //Debug(2, "Have audio packet, reocrd_audio is (%d) and packetqueue.size is (%d)", record_audio, packetqueue.size() ); - if ( record_audio && packetqueue.size() ) { - // if it's audio, and we are doing audio, and there is already something in the queue - packetqueue.queuePacket(&packet); - } - } - } } // end if recording or not + // Buffer video packets, we need to always have from the last keyframe buffered + // All audio packets are keyframes, so only if it's a video keyframe + if ( packet.stream_index == mVideoStreamId ) { + if ( keyframe ) { + packetqueue.clearQueue(monitor->GetPreEventCount(), mVideoStreamId); + packetqueue.queuePacket(&packet); + } else if ( packetqueue.size() ) { + Debug(3, "queue has %d", packetqueue.size()); + // it's a keyframe or we already have something in the queue + packetqueue.queuePacket(&packet); + } + } else if ( packet.stream_index == mAudioStreamId ) { + // The following lines should ensure that the queue always begins with a video keyframe + //Debug(2, "Have audio packet, reocrd_audio is (%d) and packetqueue.size is (%d)", record_audio, packetqueue.size() ); + if ( record_audio && packetqueue.size() ) { + // if it's audio, and we are doing audio, and there is already something in the queue + packetqueue.queuePacket(&packet); + } + } + if ( packet.stream_index == mVideoStreamId ) { // only do decode if we have had a keyframe, should save a few cycles. if ( have_video_keyframe || keyframe ) { From d068d019fba6112532fd5d154dbde819b53a1cce Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Tue, 15 Jan 2019 11:34:17 -0500 Subject: [PATCH 004/214] turn section_length into seconds instead of frames --- src/zm_monitor.cpp | 35 ++++++++--------------------------- 1 file changed, 8 insertions(+), 27 deletions(-) diff --git a/src/zm_monitor.cpp b/src/zm_monitor.cpp index ef6a35367..284ec3d11 100644 --- a/src/zm_monitor.cpp +++ b/src/zm_monitor.cpp @@ -1347,8 +1347,6 @@ bool Monitor::Analyse() { auto_resume_time = 0; } - static int last_section_mod = 0; - if ( Enabled() ) { bool signal = shared_data->signal; bool signal_change = (signal != last_signal); @@ -1384,7 +1382,6 @@ bool Monitor::Analyse() { if ( event && !signal ) { Info( "%s: %03d - Closing event %" PRIu64 ", signal loss", name, image_count, event->Id() ); closeEvent(); - last_section_mod = 0; } if ( !event ) { if ( cause.length() ) @@ -1455,29 +1452,14 @@ bool Monitor::Analyse() { if ( event ) { Debug(3, "Have signal and recording with open event at (%d.%d)", timestamp->tv_sec, timestamp->tv_usec); - if ( section_length && ( timestamp->tv_sec >= section_length ) ) { - // TODO: Wouldn't this be clearer if we just did something like if now - event->start > section_length ? - int section_mod = timestamp->tv_sec % section_length; - Debug(3, - "Section length (%d) Last Section Mod(%d), new section mod(%d)", - section_length, last_section_mod, section_mod + if ( section_length && ( ( timestamp->tv_sec - video_store_data->recording.tv_sec ) >= section_length ) ) { + Info( "%s: %03d - Closing event %" PRIu64 ", section end forced %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 ); - if ( section_mod < last_section_mod ) { - //if ( state == IDLE || state == TAPE || event_close_mode == CLOSE_TIME ) { - //if ( state == TAPE ) { - //shared_data->state = state = IDLE; - //Info( "%s: %03d - Closing event %d, section end", name, image_count, event->Id() ) - //} else { - Info( "%s: %03d - Closing event %" PRIu64 ", section end forced ", name, image_count, event->Id() ); - //} - closeEvent(); - last_section_mod = 0; - //} else { - //Debug( 2, "Time to close event, but state (%d) is not IDLE or TAPE and event_close_mode is not CLOSE_TIME (%d)", state, event_close_mode ); - //} - } else { - last_section_mod = section_mod; - } + closeEvent(); } // end if section_length } // end if event @@ -1737,11 +1719,10 @@ Error("Creating new event when one exists"); } } else { if ( event ) { - Info( "%s: %03d - Closing event %" PRIu64 ", trigger off", name, image_count, event->Id() ); + Info("%s: %03d - Closing event %" PRIu64 ", trigger off", name, image_count, event->Id()); closeEvent(); } shared_data->state = state = IDLE; - last_section_mod = 0; trigger_data->trigger_state = TRIGGER_CANCEL; } // end if ( trigger_data->trigger_state != TRIGGER_OFF ) From 5f6bcec4ca42baf69f0402d312f99a858e8b843d Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Tue, 15 Jan 2019 11:35:37 -0500 Subject: [PATCH 005/214] Use start_pts instead of start_dts when calculating output pkt.dts. Because start_dts is often lower than start_pts, we can get into a situation where we calculate a dts that is > pts. --- src/zm_videostore.cpp | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/src/zm_videostore.cpp b/src/zm_videostore.cpp index 6d728cf3c..e28ce6b59 100644 --- a/src/zm_videostore.cpp +++ b/src/zm_videostore.cpp @@ -815,34 +815,38 @@ int VideoStore::writeVideoFramePacket(AVPacket *ipkt) { } // Just because the in stream wraps, doesn't mean the out needs to. Really, if we are limiting ourselves to 10min segments I can't imagine every wrapping in the out. So need to handle in wrap, without causing out wrap. if ( ipkt->dts != AV_NOPTS_VALUE ) { +#if 0 if ( (!video_first_dts) && ( ipkt->dts >= 0 ) ) { // This is the first packet. opkt.dts = 0; Debug(1, "Starting video first_dts will become (%" PRId64 ")", ipkt->dts); video_first_dts = ipkt->dts; } else { +#endif opkt.dts = av_rescale_q( - ipkt->dts - video_first_dts, + ipkt->dts - video_first_pts, video_in_stream->time_base, video_out_stream->time_base ); - Debug(3, "opkt.dts = %" PRId64 " from ipkt.dts(%" PRId64 ") - first_dts(%" PRId64 ")", - opkt.dts, ipkt->dts, video_first_dts); + Debug(3, "opkt.dts = %" PRId64 " from ipkt.dts(%" PRId64 ") - first_pts(%" PRId64 ")", + opkt.dts, ipkt->dts, video_first_pts); video_last_dts = ipkt->dts; +#if 0 } - } else { - Debug(3, "opkt.dts = undef"); - opkt.dts = AV_NOPTS_VALUE; - } - - if ( opkt.dts > opkt.pts ) { - Debug(1, +#endif + if ( opkt.dts > opkt.pts ) { + Debug(1, "opkt.dts(%" PRId64 ") must be <= opkt.pts(%" PRId64 "). Decompression must happen " "before presentation.", opkt.dts, opkt.pts); - opkt.dts = opkt.pts; + opkt.dts = opkt.pts; + } + } else { + Debug(3, "opkt.dts = undef"); + opkt.dts = 0; } + opkt.flags = ipkt->flags; opkt.pos = -1; opkt.data = ipkt->data; From 92066aaf4f4ab6b62448e766233842d65e74fc74 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Tue, 15 Jan 2019 16:33:27 -0500 Subject: [PATCH 006/214] add stream start timeval --- src/zm_stream.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/zm_stream.h b/src/zm_stream.h index f9364bbef..92fb591b8 100644 --- a/src/zm_stream.h +++ b/src/zm_stream.h @@ -85,6 +85,7 @@ protected: int step; struct timeval now; + struct timeval start; // clock time when started the event struct timeval last_comm_update; double base_fps; From 345e2fef0fed3ea0c981adb96e743f8b7b119c19 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Tue, 15 Jan 2019 16:44:58 -0500 Subject: [PATCH 007/214] start only used in eventstream --- src/zm_eventstream.h | 2 +- src/zm_stream.h | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/src/zm_eventstream.h b/src/zm_eventstream.h index 0c9ee0db3..792473c4a 100644 --- a/src/zm_eventstream.h +++ b/src/zm_eventstream.h @@ -78,6 +78,7 @@ class EventStream : public StreamBase { int curr_frame_id; double curr_stream_time; bool send_frame; + struct timeval start; // clock time when started the event EventData *event_data; FFmpeg_Input *ffmpeg_input; @@ -108,7 +109,6 @@ class EventStream : public StreamBase { input_codec = 0; ffmpeg_input = NULL; - } void setStreamStart( uint64_t init_event_id, unsigned int init_frame_id ); void setStreamStart( int monitor_id, time_t event_time ); diff --git a/src/zm_stream.h b/src/zm_stream.h index 92fb591b8..f9364bbef 100644 --- a/src/zm_stream.h +++ b/src/zm_stream.h @@ -85,7 +85,6 @@ protected: int step; struct timeval now; - struct timeval start; // clock time when started the event struct timeval last_comm_update; double base_fps; From a39b92154cc62ea66af7c6160bc4ceb39efaeb89 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Thu, 17 Jan 2019 08:49:48 -0500 Subject: [PATCH 008/214] wip --- src/zm_ffmpeg_camera.cpp | 3 ++- src/zm_videostore.cpp | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/zm_ffmpeg_camera.cpp b/src/zm_ffmpeg_camera.cpp index 13cbde10d..0cfa53b82 100644 --- a/src/zm_ffmpeg_camera.cpp +++ b/src/zm_ffmpeg_camera.cpp @@ -362,6 +362,7 @@ int FfmpegCamera::OpenFfmpeg() { } else { Warning("Unknown method (%s)", method.c_str() ); } +//#av_dict_set(&opts, "timeout", "10000000", 0); // in microseconds. if ( ret < 0 ) { Warning("Could not set rtsp_transport method '%s'\n", method.c_str()); @@ -1039,7 +1040,7 @@ int FfmpegCamera::CaptureAndRecord( Image &image, timeval recording, char* event int FfmpegCamera::FfmpegInterruptCallback(void *ctx) { //FfmpegCamera* camera = reinterpret_cast(ctx); - + Debug(4, "FfmpegInterruptCallback"); return zm_terminate; } diff --git a/src/zm_videostore.cpp b/src/zm_videostore.cpp index 8af95e616..79b084912 100644 --- a/src/zm_videostore.cpp +++ b/src/zm_videostore.cpp @@ -100,6 +100,7 @@ VideoStore::VideoStore( } // Since we are not re-encoding, all we have to do is copy the parameters video_out_ctx = video_out_stream->codec; + video_out_ctx->time_base = video_in_ctx->time_base; #if LIBAVCODEC_VERSION_CHECK(57, 64, 0, 64, 0) // Copy params from instream to ctx From 7026ebaface44bd9d496a6aefbd6527be427b2b6 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Tue, 22 Jan 2019 16:45:38 -0500 Subject: [PATCH 009/214] Make ajax/stream wait longer for zms. On pi can take up to 3 seconds. Also for php < 5.6, we need to fake 64bit unpack support --- web/ajax/stream.php | 47 +++++++++++++++++++-------------------------- 1 file changed, 20 insertions(+), 27 deletions(-) diff --git a/web/ajax/stream.php b/web/ajax/stream.php index 356227529..e8e7aca7f 100644 --- a/web/ajax/stream.php +++ b/web/ajax/stream.php @@ -26,7 +26,7 @@ if ( sem_acquire($semaphore,1) !== false ) { Warning("sock file $localSocketFile already exists?! Is someone else talking to zms?"); // They could be. We can maybe have concurrent requests from a browser. } - if ( ! socket_bind( $socket, $localSocketFile ) ) { + if ( !socket_bind( $socket, $localSocketFile ) ) { ajaxError("socket_bind( $localSocketFile ) failed: ".socket_strerror(socket_last_error()) ); } @@ -52,12 +52,14 @@ if ( sem_acquire($semaphore,1) !== false ) { $msg = pack( 'lcN', MSG_CMD, $_REQUEST['command'], $_REQUEST['offset'] ); break; default : + Logger::Debug("Sending command " . $_REQUEST['command']); $msg = pack( 'lc', MSG_CMD, $_REQUEST['command'] ); break; } $remSockFile = ZM_PATH_SOCKS.'/zms-'.sprintf('%06d',$_REQUEST['connkey']).'s.sock'; - $max_socket_tries = 10; + // Pi can take up to 3 seconds for zms to start up. + $max_socket_tries = 1000; // FIXME This should not exceed web_ajax_timeout while ( !file_exists($remSockFile) && $max_socket_tries-- ) { //sometimes we are too fast for our own good, if it hasn't been setup yet give it a second. // WHY? We will just send another one... @@ -92,39 +94,31 @@ if ( sem_acquire($semaphore,1) !== false ) { } else if ( $numSockets == 0 ) { Error( "Timed out waiting for msg $remSockFile" ); socket_Set_nonblock($socket); - #ajaxError( "Timed out waiting for msg $remSockFile" ); + #ajaxError("Timed out waiting for msg $remSockFile"); } else if ( $numSockets > 0 ) { if ( count($rSockets) != 1 ) { - Error( 'Bogus return from select, '.count($rSockets).' sockets available' ); - ajaxError( 'Bogus return from select, '.count($rSockets).' sockets available' ); + Error('Bogus return from select, '.count($rSockets).' sockets available'); + ajaxError('Bogus return from select, '.count($rSockets).' sockets available'); } } switch( $nbytes = @socket_recvfrom( $socket, $msg, MSG_DATA_SIZE, 0, $remSockFile ) ) { case -1 : - { - ajaxError( "socket_recvfrom( $remSockFile ) failed: ".socket_strerror(socket_last_error()) ); + ajaxError("socket_recvfrom( $remSockFile ) failed: ".socket_strerror(socket_last_error())); break; - } case 0 : - { - ajaxError( 'No data to read from socket' ); + ajaxError('No data to read from socket'); break; - } default : - { if ( $nbytes != MSG_DATA_SIZE ) - ajaxError( "Got unexpected message size, got $nbytes, expected ".MSG_DATA_SIZE ); + ajaxError("Got unexpected message size, got $nbytes, expected ".MSG_DATA_SIZE); break; } - } - - $data = unpack( 'ltype', $msg ); + $data = unpack('ltype', $msg); switch ( $data['type'] ) { case MSG_DATA_WATCH : - { - $data = unpack( "ltype/imonitor/istate/dfps/ilevel/irate/ddelay/izoom/Cdelayed/Cpaused/Cenabled/Cforced", $msg ); + $data = unpack('ltype/imonitor/istate/dfps/ilevel/irate/ddelay/izoom/Cdelayed/Cpaused/Cenabled/Cforced', $msg); Logger::Debug("FPS: " . $data['fps'] ); $data['fps'] = round( $data['fps'], 2 ); Logger::Debug("FPS: " . $data['fps'] ); @@ -140,11 +134,13 @@ if ( sem_acquire($semaphore,1) !== false ) { } ajaxResponse( array( 'status'=>$data ) ); break; - } case MSG_DATA_EVENT : - { - $data = unpack( "ltype/Pevent/iprogress/irate/izoom/Cpaused", $msg ); - //$data['progress'] = sprintf( "%.2f", $data['progress'] ); + if ( version_compare( phpversion(), '5.6.0', '>') ) { + $data = unpack('ltype/ieventlow/ieventhigh/iprogress/irate/izoom/Cpaused', $msg); + $data['event'] = $data['eventhigh'] << 32 | $data['eventlow']; + } else { + $data = unpack('ltype/Qevent/iprogress/irate/izoom/Cpaused', $msg); + } $data['rate'] /= RATE_BASE; $data['zoom'] = round( $data['zoom']/SCALE_BASE, 1 ); if ( ZM_OPT_USE_AUTH && ZM_AUTH_RELAY == 'hashed' ) { @@ -154,13 +150,10 @@ if ( sem_acquire($semaphore,1) !== false ) { $data['auth'] = generateAuthHash(ZM_AUTH_HASH_IPS); } } - ajaxResponse( array( 'status'=>$data ) ); + ajaxResponse(array('status'=>$data)); break; - } default : - { - ajaxError( "Unexpected received message type '$type'" ); - } + ajaxError("Unexpected received message type '$type'"); } sem_release($semaphore); } else { From 2563951c1fbc0e67c34ba8499951cd6c2e97f896 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Wed, 13 Feb 2019 11:32:34 -0500 Subject: [PATCH 010/214] comment out the signal blocking. I still can't figure out why we would want it --- src/zmc.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/zmc.cpp b/src/zmc.cpp index 9270c75cd..88a9807b2 100644 --- a/src/zmc.cpp +++ b/src/zmc.cpp @@ -276,7 +276,7 @@ int main(int argc, char *argv[]) { struct timeval now; struct DeltaTimeval delta_time; while ( !zm_terminate ) { - sigprocmask(SIG_BLOCK, &block_set, 0); + //sigprocmask(SIG_BLOCK, &block_set, 0); for ( int i = 0; i < n_monitors; i++ ) { long min_delay = MAXINT; @@ -333,7 +333,7 @@ int main(int argc, char *argv[]) { } // end if next_delay <= min_delay || next_delays[i] <= 0 ) } // end foreach n_monitors - sigprocmask(SIG_UNBLOCK, &block_set, 0); + //sigprocmask(SIG_UNBLOCK, &block_set, 0); if ( zm_reload ) { for ( int i = 0; i < n_monitors; i++ ) { monitors[i]->Reload(); From 31a11a69922e883f204340c0beb4a78fc23a7c84 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Wed, 13 Feb 2019 11:34:47 -0500 Subject: [PATCH 011/214] init log earlier in zms --- src/zms.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/zms.cpp b/src/zms.cpp index a5fef0134..cf3265fd0 100644 --- a/src/zms.cpp +++ b/src/zms.cpp @@ -85,6 +85,9 @@ int main( int argc, const char *argv[] ) { } zmLoadConfig(); + char log_id_string[32] = "zms"; + logInit( log_id_string ); + Debug(1,"rate %d", rate); const char *query = getenv("QUERY_STRING"); if ( query ) { @@ -95,7 +98,7 @@ int main( int argc, const char *argv[] ) { char *q_ptr = temp_query; char *parms[16]; // Shouldn't be more than this int parm_no = 0; - while( (parm_no < 16) && (parms[parm_no] = strtok(q_ptr, "&")) ) { + while ( (parm_no < 16) && (parms[parm_no] = strtok(q_ptr, "&")) ) { parm_no++; q_ptr = NULL; } @@ -130,6 +133,7 @@ int main( int argc, const char *argv[] ) { scale = atoi( value ); } else if ( !strcmp( name, "rate" ) ) { rate = atoi( value ); + Debug(2,"Setting rate to %d from %s", rate, value); } else if ( !strcmp( name, "maxfps" ) ) { maxfps = atof( value ); } else if ( !strcmp( name, "bitrate" ) ) { @@ -177,9 +181,10 @@ int main( int argc, const char *argv[] ) { } } } // end foreach parm + } else { + Fatal("No query string."); } // end if query - char log_id_string[32] = "zms"; if ( monitor_id ) { snprintf(log_id_string, sizeof(log_id_string), "zms_m%d", monitor_id); } else { From 9477ebad5d5f2a7839af1e35b2dc0f34abaedc49 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Fri, 22 Feb 2019 09:35:42 -0500 Subject: [PATCH 012/214] update to php namespace --- web/includes/session.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/includes/session.php b/web/includes/session.php index 8f9c90e66..7da3ee4fb 100644 --- a/web/includes/session.php +++ b/web/includes/session.php @@ -8,7 +8,7 @@ function zm_session_start() { $currentCookieParams = session_get_cookie_params(); $currentCookieParams['lifetime'] = ZM_COOKIE_LIFETIME; - Logger::Debug('Setting cookie parameters to lifetime('.$currentCookieParams['lifetime'].') path('.$currentCookieParams['path'].') domain ('.$currentCookieParams['domain'].') secure('.$currentCookieParams['secure'].') httpOnly(1)'); + ZM\Logger::Debug('Setting cookie parameters to lifetime('.$currentCookieParams['lifetime'].') path('.$currentCookieParams['path'].') domain ('.$currentCookieParams['domain'].') secure('.$currentCookieParams['secure'].') httpOnly(1)'); session_set_cookie_params( $currentCookieParams['lifetime'], $currentCookieParams['path'], From 46c6735311c3bc1bff503fa2eea6d91d74ce6488 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Sun, 24 Feb 2019 10:02:49 -0500 Subject: [PATCH 013/214] Missing namespace on filter. Fixes #2541 --- web/includes/actions/filter.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/includes/actions/filter.php b/web/includes/actions/filter.php index a89938697..6b3019ee5 100644 --- a/web/includes/actions/filter.php +++ b/web/includes/actions/filter.php @@ -81,7 +81,7 @@ if ( isset($_REQUEST['object']) and ( $_REQUEST['object'] == 'filter' ) ) { } else { dbQuery('INSERT INTO Filters SET'.$sql); $_REQUEST['Id'] = dbInsertId(); - $filter = new Filter($_REQUEST['Id']); + $filter = new ZM\Filter($_REQUEST['Id']); } if ( !empty($_REQUEST['filter']['Background']) ) $filter->control('start'); From dd590aa729ceea396f18352761e0e9caca0247ac Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Sun, 24 Feb 2019 10:05:45 -0500 Subject: [PATCH 014/214] remove warning when QUERY_STRING is not set --- web/skins/classic/views/login.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/skins/classic/views/login.php b/web/skins/classic/views/login.php index c75c9b602..42a4090fc 100644 --- a/web/skins/classic/views/login.php +++ b/web/skins/classic/views/login.php @@ -7,7 +7,7 @@ xhtmlHeaders(__FILE__, translate('Login') );
- +