Fix play from pause when not buffering. When change of zoom, send two paused images so that response is instant. Fix some misplaced line feeds.

This commit is contained in:
Isaac Connor 2019-09-26 13:51:13 -04:00
parent 675db328e7
commit b787682fa9
1 changed files with 39 additions and 22 deletions

View File

@ -328,10 +328,10 @@ bool MonitorStream::sendFrame(const char *filepath, struct timeval *timestamp) {
struct timeval frameStartTime; struct timeval frameStartTime;
gettimeofday(&frameStartTime, NULL); gettimeofday(&frameStartTime, NULL);
fputs("--ZoneMinderFrame\r\nContent-Type: image/jpeg\r\n\r\n", stdout ); fputs("--ZoneMinderFrame\r\nContent-Type: image/jpeg\r\n", stdout);
fprintf(stdout, "Content-Length: %d\r\n", img_buffer_size); fprintf(stdout, "Content-Length: %d\r\n\r\n", img_buffer_size);
if ( fwrite(img_buffer, img_buffer_size, 1, stdout) != 1 ) { if ( fwrite(img_buffer, img_buffer_size, 1, stdout) != 1 ) {
if ( ! zm_terminate ) if ( !zm_terminate )
Warning("Unable to send stream frame: %s", strerror(errno)); Warning("Unable to send stream frame: %s", strerror(errno));
return false; return false;
} }
@ -397,7 +397,7 @@ bool MonitorStream::sendFrame(Image *image, struct timeval *timestamp) {
break; break;
case STREAM_ZIP : case STREAM_ZIP :
#if HAVE_ZLIB_H #if HAVE_ZLIB_H
fputs("Content-Type: image/x-rgbz\r\n",stdout); fputs("Content-Type: image/x-rgbz\r\n", stdout);
unsigned long zip_buffer_size; unsigned long zip_buffer_size;
send_image->Zip(img_buffer, &zip_buffer_size); send_image->Zip(img_buffer, &zip_buffer_size);
img_buffer_size = zip_buffer_size; img_buffer_size = zip_buffer_size;
@ -412,7 +412,7 @@ bool MonitorStream::sendFrame(Image *image, struct timeval *timestamp) {
} }
fprintf(stdout, "Content-Length: %d\r\n\r\n", img_buffer_size); fprintf(stdout, "Content-Length: %d\r\n\r\n", img_buffer_size);
if ( fwrite(img_buffer, img_buffer_size, 1, stdout) != 1 ) { if ( fwrite(img_buffer, img_buffer_size, 1, stdout) != 1 ) {
if ( !zm_terminate ){ if ( !zm_terminate ) {
// If the pipe was closed, we will get signalled SIGPIPE to exit, which will set zm_terminate // If the pipe was closed, we will get signalled SIGPIPE to exit, which will set zm_terminate
Warning("Unable to send stream frame: %s", strerror(errno)); Warning("Unable to send stream frame: %s", strerror(errno));
} }
@ -657,11 +657,11 @@ void MonitorStream::runStream() {
if ( last_read_index != monitor->shared_data->last_write_index ) { if ( last_read_index != monitor->shared_data->last_write_index ) {
// 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
if ( (frame_mod == 1) || ((frame_count%frame_mod) == 0) ) {
if ( !paused && !delayed ) {
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)", Debug(2, "index: %d: frame_mod: %d frame count: %d paused(%d) delayed(%d)",
index, frame_mod, frame_count, paused, delayed ); index, frame_mod, frame_count, paused, delayed );
if ( (frame_mod == 1) || ((frame_count%frame_mod) == 0) ) {
if ( !paused && !delayed ) {
// Send the next frame // Send the next frame
Monitor::Snapshot *snap = &monitor->image_buffer[index]; Monitor::Snapshot *snap = &monitor->image_buffer[index];
@ -676,20 +676,32 @@ 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); if ( delayed && !buffered_playback ) {
Debug(2, "Can't delay when not buffering.");
delayed = false;
}
if ( last_zoom != zoom ) {
Debug(2, "Sending 2 frames because change in zoom %d ?= %d", last_zoom, zoom);
if ( !sendFrame(paused_image, &paused_timestamp) )
zm_terminate = true;
if ( !sendFrame(paused_image, &paused_timestamp) )
zm_terminate = true;
} else {
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 because delta time %.2f > 5", actual_delta_time); 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 actual_delta_time > 5
} } // end if change in zoom
} // end if paused or not
} // end if should send frame } // end if should send frame
if ( buffered_playback && !paused ) { if ( buffered_playback && !paused ) {
@ -698,7 +710,12 @@ void MonitorStream::runStream() {
int temp_index = temp_write_index%temp_image_buffer_count; int temp_index = temp_write_index%temp_image_buffer_count;
Debug(2, "Storing frame %d", temp_index); Debug(2, "Storing frame %d", temp_index);
if ( !temp_image_buffer[temp_index].valid ) { if ( !temp_image_buffer[temp_index].valid ) {
snprintf( temp_image_buffer[temp_index].file_name, sizeof(temp_image_buffer[0].file_name), "%s/zmswap-i%05d.jpg", swap_path.c_str(), temp_index ); snprintf(
temp_image_buffer[temp_index].file_name,
sizeof(temp_image_buffer[0].file_name),
"%s/zmswap-i%05d.jpg",
swap_path.c_str(),
temp_index);
temp_image_buffer[temp_index].valid = true; temp_image_buffer[temp_index].valid = true;
} }
memcpy( &(temp_image_buffer[temp_index].timestamp), monitor->image_buffer[index].timestamp, sizeof(temp_image_buffer[0].timestamp) ); memcpy( &(temp_image_buffer[temp_index].timestamp), monitor->image_buffer[index].timestamp, sizeof(temp_image_buffer[0].timestamp) );