* Change MaxFPS to DECIMAL(5,3) to handle values like 1/60 = 0.017

* When fps < 1 we may need to wait longer than 10s.  Also, we cannot sleep for a long time, because we may need to send a keep alive or check the command queue. So limit the sleep to 1s

* Bump version

* Update MaxFPS to Decimal(5,3)

* Fix missing ;
This commit is contained in:
Isaac Connor 2019-07-31 11:42:38 -04:00 committed by GitHub
parent 48ad8d47fc
commit 90cb5d018a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 68 additions and 28 deletions

View File

@ -413,7 +413,7 @@ CREATE TABLE `MonitorPresets` (
`Width` smallint(5) unsigned default NULL, `Width` smallint(5) unsigned default NULL,
`Height` smallint(5) unsigned default NULL, `Height` smallint(5) unsigned default NULL,
`Palette` int(10) unsigned default NULL, `Palette` int(10) unsigned default NULL,
`MaxFPS` decimal(5,2) default NULL, `MaxFPS` decimal(5,3) default NULL,
`Controllable` tinyint(3) unsigned NOT NULL default '0', `Controllable` tinyint(3) unsigned NOT NULL default '0',
`ControlId` varchar(16) default NULL, `ControlId` varchar(16) default NULL,
`ControlDevice` varchar(255) default NULL, `ControlDevice` varchar(255) default NULL,

6
db/zm_update-1.33.13.sql Normal file
View File

@ -0,0 +1,6 @@
--
-- Add primary keys for Logs and Stats tables
--
SELECT "Modifying Monitors MaxFPS to DECIMAL(5,3)";
ALTER TABLE `Monitors` MODIFY `MaxFPS` decimal(5,3) default NULL;

View File

@ -27,6 +27,8 @@
#include <arpa/inet.h> #include <arpa/inet.h>
#include <glob.h> #include <glob.h>
const int MAX_SLEEP_USEC=1000000; // 1 sec
bool MonitorStream::checkSwapPath(const char *path, bool create_path) { bool MonitorStream::checkSwapPath(const char *path, bool create_path) {
struct stat stat_buf; struct stat stat_buf;
@ -416,20 +418,21 @@ bool MonitorStream::sendFrame(Image *image, struct timeval *timestamp) {
} }
return false; return false;
} }
fputs("\r\n\r\n",stdout); fputs("\r\n\r\n", stdout);
fflush( stdout ); fflush(stdout);
struct timeval frameEndTime; struct timeval frameEndTime;
gettimeofday( &frameEndTime, NULL ); gettimeofday(&frameEndTime, NULL);
int frameSendTime = tvDiffMsec( frameStartTime, frameEndTime ); int frameSendTime = tvDiffMsec(frameStartTime, frameEndTime);
if ( frameSendTime > 1000/maxfps ) { if ( frameSendTime > 1000/maxfps ) {
maxfps /= 1.5; maxfps /= 1.5;
Warning("Frame send time %d msec too slow, throttling maxfps to %.2f", frameSendTime, maxfps); Warning("Frame send time %d msec too slow, throttling maxfps to %.2f",
frameSendTime, maxfps);
} }
} }
last_frame_sent = TV_2_FLOAT( now ); last_frame_sent = TV_2_FLOAT(now);
return( true ); return true;
} // end bool MonitorStream::sendFrame( Image *image, struct timeval *timestamp ) } // end bool MonitorStream::sendFrame( Image *image, struct timeval *timestamp )
void MonitorStream::runStream() { void MonitorStream::runStream() {
@ -515,16 +518,33 @@ void MonitorStream::runStream() {
} // end if connkey & playback_buffer } // end if connkey & playback_buffer
float max_secs_since_last_sent_frame = 10.0; //should be > keep alive amount (5 secs) 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();
if ( capture_max_fps && ( capture_fps > capture_max_fps ) ) {
Debug(1, "Using %.3f for fps instead of current fps %.3f", capture_max_fps, capture_fps);
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 ) { while ( !zm_terminate ) {
bool got_command = false; bool got_command = false;
if ( feof(stdout) ) { if ( feof(stdout) ) {
Debug(2,"feof stdout"); Debug(2, "feof stdout");
break; break;
} else if ( ferror(stdout) ) { } else if ( ferror(stdout) ) {
Debug(2,"ferror stdout"); Debug(2, "ferror stdout");
break; break;
} else if ( !monitor->ShmValid() ) { } else if ( !monitor->ShmValid() ) {
Debug(2,"monitor not valid.... maybe we should wait until it comes back."); Debug(2, "monitor not valid.... maybe we should wait until it comes back.");
break; break;
} }
@ -547,12 +567,12 @@ void MonitorStream::runStream() {
if ( paused ) { if ( paused ) {
if ( !was_paused ) { if ( !was_paused ) {
int index = monitor->shared_data->last_write_index % monitor->image_buffer_count; int index = monitor->shared_data->last_write_index % monitor->image_buffer_count;
Debug(1,"Saving paused image from index %d",index); Debug(1, "Saving paused image from index %d",index);
paused_image = new Image( *monitor->image_buffer[index].image ); paused_image = new Image(*monitor->image_buffer[index].image);
paused_timestamp = *(monitor->image_buffer[index].timestamp); paused_timestamp = *(monitor->image_buffer[index].timestamp);
} }
} else if ( paused_image ) { } else if ( paused_image ) {
Debug(1,"Clearing paused_image"); Debug(1, "Clearing paused_image");
delete paused_image; delete paused_image;
paused_image = NULL; paused_image = NULL;
} }
@ -560,7 +580,7 @@ void MonitorStream::runStream() {
if ( buffered_playback && delayed ) { if ( buffered_playback && delayed ) {
if ( temp_read_index == temp_write_index ) { if ( temp_read_index == temp_write_index ) {
// Go back to live viewing // Go back to live viewing
Debug( 1, "Exceeded temporary streaming buffer" ); Debug(1, "Exceeded temporary streaming buffer");
// Clear paused flag // Clear paused flag
paused = false; paused = false;
// Clear delayed_play flag // Clear delayed_play flag
@ -611,10 +631,10 @@ void MonitorStream::runStream() {
//paused? //paused?
int temp_index = MOD_ADD(temp_read_index, 0, temp_image_buffer_count); int temp_index = MOD_ADD(temp_read_index, 0, temp_image_buffer_count);
double actual_delta_time = TV_2_FLOAT( now ) - last_frame_sent; double actual_delta_time = TV_2_FLOAT( now ) - last_frame_sent;
if ( got_command || actual_delta_time > 5 ) { if ( got_command || actual_delta_time > 5 ) {
// Send keepalive // Send keepalive
Debug( 2, "Sending keepalive frame %d", temp_index ); Debug(2, "Sending keepalive frame %d", temp_index);
// Send the next frame // Send the next frame
if ( !sendFrame( temp_image_buffer[temp_index].file_name, &temp_image_buffer[temp_index].timestamp ) ) if ( !sendFrame( temp_image_buffer[temp_index].file_name, &temp_image_buffer[temp_index].timestamp ) )
zm_terminate = true; zm_terminate = true;
@ -625,7 +645,7 @@ void MonitorStream::runStream() {
if ( temp_read_index == temp_write_index ) { if ( temp_read_index == temp_write_index ) {
// Go back to live viewing // Go back to live viewing
Warning( "Rewound over write index, resuming live play" ); Warning("Rewound over write index, resuming live play");
// Clear paused flag // Clear paused flag
paused = false; paused = false;
// Clear delayed_play flag // Clear delayed_play flag
@ -638,7 +658,8 @@ void MonitorStream::runStream() {
// have a new image to send // have a new image to send
int index = monitor->shared_data->last_write_index % monitor->image_buffer_count; // % shouldn't be neccessary int index = monitor->shared_data->last_write_index % monitor->image_buffer_count; // % shouldn't be neccessary
last_read_index = monitor->shared_data->last_write_index; last_read_index = monitor->shared_data->last_write_index;
Debug( 2, "index: %d: frame_mod: %d frame count: %d paused(%d) delayed(%d)", index, frame_mod, frame_count, paused, delayed ); Debug(2, "index: %d: frame_mod: %d frame count: %d paused(%d) delayed(%d)",
index, frame_mod, frame_count, paused, delayed );
if ( (frame_mod == 1) || ((frame_count%frame_mod) == 0) ) { if ( (frame_mod == 1) || ((frame_count%frame_mod) == 0) ) {
if ( !paused && !delayed ) { if ( !paused && !delayed ) {
// Send the next frame // Send the next frame
@ -655,18 +676,19 @@ void MonitorStream::runStream() {
temp_read_index = temp_write_index; temp_read_index = temp_write_index;
} else { } else {
Debug(2, "Paused %d, delayed %d", paused, delayed);
double actual_delta_time = TV_2_FLOAT(now) - last_frame_sent; double actual_delta_time = TV_2_FLOAT(now) - last_frame_sent;
if ( actual_delta_time > 5 ) { if ( actual_delta_time > 5 ) {
if ( paused_image ) { if ( paused_image ) {
// Send keepalive // Send keepalive
Debug(2, "Sending keepalive frame "); Debug(2, "Sending keepalive frame because delta time %.2f > 5", actual_delta_time);
// Send the next frame // Send the next frame
if ( !sendFrame(paused_image, &paused_timestamp) ) if ( !sendFrame(paused_image, &paused_timestamp) )
zm_terminate = true; zm_terminate = true;
} else { } else {
Debug(2, "Would have sent keepalive frame, but had no paused_image "); Debug(2, "Would have sent keepalive frame, but had no paused_image ");
} }
} }
} }
} // end if should send frame } // end if should send frame
@ -698,11 +720,17 @@ void MonitorStream::runStream() {
} // end if buffered playback } // end if buffered playback
frame_count++; frame_count++;
} else { } else {
Debug(4,"Waiting for capture last_write_index=%u", monitor->shared_data->last_write_index); Debug(3, "Waiting for capture last_write_index=%u", monitor->shared_data->last_write_index);
} // end if ( (unsigned int)last_read_index != monitor->shared_data->last_write_index ) } // 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))); unsigned long sleep_time = (unsigned long)((1000000 * ZM_RATE_BASE)/((base_fps?base_fps:1)*abs(replay_rate*2)));
Debug(4, "Sleeping for (%d)", sleep_time); 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 %dus", sleep_time);
usleep(sleep_time); usleep(sleep_time);
if ( ttl ) { if ( ttl ) {
if ( (now.tv_sec - stream_start_time) > ttl ) { if ( (now.tv_sec - stream_start_time) > ttl ) {
@ -713,9 +741,15 @@ void MonitorStream::runStream() {
if ( ! last_frame_sent ) { if ( ! last_frame_sent ) {
// If we didn't capture above, because frame_mod was bad? Then last_frame_sent will not have a value. // If we didn't capture above, because frame_mod was bad? Then last_frame_sent will not have a value.
last_frame_sent = now.tv_sec; 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 ); Warning("no last_frame_sent. Shouldn't happen. frame_mod was (%d) frame_count (%d) ",
} else if ( (!paused) && ( (TV_2_FLOAT( now ) - last_frame_sent) > max_secs_since_last_sent_frame ) ) { frame_mod, frame_count);
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 ); } 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; break;
} }
} // end while } // end while

View File

@ -1 +1 @@
1.33.12 1.33.13