Merge branch 'master' into zma_to_thread

This commit is contained in:
Isaac Connor
2020-07-21 17:38:32 -04:00
210 changed files with 3521 additions and 4636 deletions

View File

@@ -330,14 +330,16 @@ bool MonitorStream::sendFrame(const char *filepath, struct timeval *timestamp) {
struct timeval frameStartTime;
gettimeofday(&frameStartTime, NULL);
fputs("--ZoneMinderFrame\r\nContent-Type: image/jpeg\r\n", stdout);
fprintf(stdout, "Content-Length: %d\r\n\r\n", img_buffer_size);
fputs("--" BOUNDARY "\r\nContent-Type: image/jpeg\r\n", stdout);
fprintf(stdout, "Content-Length: %d\r\n"
"X-Timestamp: %d.%06d\r\n"
"\r\n", img_buffer_size, (int)timestamp->tv_sec, (int)timestamp->tv_usec);
if ( fwrite(img_buffer, img_buffer_size, 1, stdout) != 1 ) {
if ( !zm_terminate )
Warning("Unable to send stream frame: %s", strerror(errno));
return false;
}
fputs("\r\n\r\n", stdout);
fputs("\r\n", stdout);
fflush(stdout);
struct timeval frameEndTime;
@@ -361,6 +363,7 @@ bool MonitorStream::sendFrame(Image *image, struct timeval *timestamp) {
if ( !config.timestamp_on_capture && timestamp )
monitor->TimestampImage(send_image, timestamp);
fputs("--" BOUNDARY "\r\n", stdout);
#if HAVE_LIBAVCODEC
if ( type == STREAM_MPEG ) {
if ( !vid_stream ) {
@@ -386,7 +389,6 @@ bool MonitorStream::sendFrame(Image *image, struct timeval *timestamp) {
struct timeval frameStartTime;
gettimeofday(&frameStartTime, NULL);
fputs("--ZoneMinderFrame\r\n", stdout);
switch( type ) {
case STREAM_JPEG :
send_image->EncodeJpeg(img_buffer, &img_buffer_size);
@@ -404,15 +406,17 @@ bool MonitorStream::sendFrame(Image *image, struct timeval *timestamp) {
send_image->Zip(img_buffer, &zip_buffer_size);
img_buffer_size = zip_buffer_size;
#else
Error("zlib is required for zipped images. Falling back to raw image");
type = STREAM_RAW;
Error("zlib is required for zipped images. Falling back to raw image");
type = STREAM_RAW;
#endif // HAVE_ZLIB_H
break;
default :
Error("Unexpected frame type %d", type);
return false;
}
fprintf(stdout, "Content-Length: %d\r\n\r\n", img_buffer_size);
fprintf(stdout, "Content-Length: %d\r\n"
"X-Timestamp: %d.%06d\r\n"
"\r\n", img_buffer_size, (int)timestamp->tv_sec, (int)timestamp->tv_usec);
if ( fwrite(img_buffer, img_buffer_size, 1, stdout) != 1 ) {
if ( !zm_terminate ) {
// If the pipe was closed, we will get signalled SIGPIPE to exit, which will set zm_terminate
@@ -420,7 +424,7 @@ bool MonitorStream::sendFrame(Image *image, struct timeval *timestamp) {
}
return false;
}
fputs("\r\n\r\n", stdout);
fputs("\r\n", stdout);
fflush(stdout);
struct timeval frameEndTime;
@@ -454,7 +458,7 @@ void MonitorStream::runStream() {
updateFrameRate(monitor->GetFPS());
if ( type == STREAM_JPEG )
fputs("Content-Type: multipart/x-mixed-replace;boundary=ZoneMinderFrame\r\n\r\n", stdout);
fputs("Content-Type: multipart/x-mixed-replace; boundary=" BOUNDARY "\r\n\r\n", stdout);
// point to end which is theoretically not a valid value because all indexes are % image_buffer_count
unsigned int last_read_index = monitor->image_buffer_count;
@@ -520,7 +524,6 @@ void MonitorStream::runStream() {
Debug(2, "Not using playback_buffer");
} // end if connkey & playback_buffer
float max_secs_since_last_sent_frame = 10.0; //should be > keep alive amount (5 secs)
// if MaxFPS < 0 as in 1/60 = 0.017 then we won't get another frame for 60 sec.
double capture_fps = monitor->GetFPS();
double capture_max_fps = monitor->GetCaptureMaxFPS();
@@ -529,15 +532,6 @@ void MonitorStream::runStream() {
capture_fps = capture_max_fps;
}
if ( capture_fps < 1 ) {
max_secs_since_last_sent_frame = 10/capture_fps;
Debug(1, "Adjusting max_secs_since_last_sent_frame to %.2f from current fps %.2f",
max_secs_since_last_sent_frame, monitor->GetFPS());
} else {
Debug(1, "Not Adjusting max_secs_since_last_sent_frame to %.2f from current fps %.2f",
max_secs_since_last_sent_frame, monitor->GetFPS());
}
while ( !zm_terminate ) {
bool got_command = false;
if ( feof(stdout) ) {
@@ -673,7 +667,7 @@ void MonitorStream::runStream() {
if ( (frame_mod == 1) || ((frame_count%frame_mod) == 0) ) {
if ( !paused && !delayed ) {
last_read_index = monitor->shared_data->last_write_index;
Debug(2, "index: %d: frame_mod: %d frame count: %d paused(%d) delayed(%d)",
Debug(2, "Sending frame index: %d: frame_mod: %d frame count: %d paused(%d) delayed(%d)",
index, frame_mod, frame_count, paused, delayed);
// Send the next frame
//
@@ -688,6 +682,15 @@ void MonitorStream::runStream() {
// Perhaps we should use NOW instead.
last_frame_timestamp = *timestamp;
//frame_sent = true;
//
if ( frame_count == 0 ) {
// Chrome will not display the first frame until it receives another.
// Firefox is fine. So just send the first frame twice.
if ( !sendFrame(snap->image, snap->timestamp) ) {
Debug(2, "sendFrame failed, quiting.");
zm_terminate = true;
}
}
temp_read_index = temp_write_index;
} else {
@@ -756,13 +759,13 @@ void MonitorStream::runStream() {
} // end if ( (unsigned int)last_read_index != monitor->shared_data->last_write_index )
unsigned long sleep_time = (unsigned long)((1000000 * ZM_RATE_BASE)/((base_fps?base_fps:1)*abs(replay_rate*2)));
Debug(3, "Sleeping for (%d)", sleep_time);
if ( sleep_time > MAX_SLEEP_USEC ) {
// Shouldn't sleep for long because we need to check command queue, etc.
sleep_time = MAX_SLEEP_USEC;
Debug(3, "Sleeping for MAX_SLEEP_USEC %dus", sleep_time);
} else {
Debug(3, "Sleeping for %dus", sleep_time);
}
Debug(3, "Sleeping for %dus", sleep_time);
usleep(sleep_time);
if ( ttl ) {
if ( (now.tv_sec - stream_start_time) > ttl ) {
@@ -775,14 +778,6 @@ void MonitorStream::runStream() {
last_frame_sent = now.tv_sec;
Warning("no last_frame_sent. Shouldn't happen. frame_mod was (%d) frame_count (%d)",
frame_mod, frame_count);
} else if (
(!paused)
&&
( (TV_2_FLOAT(now) - last_frame_sent) > max_secs_since_last_sent_frame )
) {
Error("Terminating, last frame sent time %f secs more than maximum of %f",
TV_2_FLOAT(now) - last_frame_sent, max_secs_since_last_sent_frame);
break;
}
} // end while