diff --git a/src/libguac/user-handlers.c b/src/libguac/user-handlers.c index 9cd558c1..4f1f59b0 100644 --- a/src/libguac/user-handlers.c +++ b/src/libguac/user-handlers.c @@ -95,30 +95,35 @@ int __guac_handle_sync(guac_user* user, int argc, char** argv) { if (timestamp > user->client->last_sent_timestamp) return -1; - /* Update stored timestamp */ - user->last_received_timestamp = timestamp; + /* Only update lag calculations if timestamp is sane */ + if (timestamp >= user->last_received_timestamp) { - /* Calculate length of frame, including network and processing lag */ - frame_duration = current - timestamp; + /* Update stored timestamp */ + user->last_received_timestamp = timestamp; - /* Update lag statistics if at least one frame has been rendered */ - if (user->last_frame_duration != 0) { + /* Calculate length of frame, including network and processing lag */ + frame_duration = current - timestamp; - /* Approximate processing lag by summing the frame duration deltas */ - int processing_lag = user->processing_lag + frame_duration - - user->last_frame_duration; + /* Update lag statistics if at least one frame has been rendered */ + if (user->last_frame_duration != 0) { - /* Adjust back to zero if cumulative error leads to a negative value */ - if (processing_lag < 0) - processing_lag = 0; + /* Calculate lag using the previous frame as a baseline */ + int processing_lag = frame_duration - user->last_frame_duration; - user->processing_lag = processing_lag; + /* Adjust back to zero if cumulative error leads to a negative + * value */ + if (processing_lag < 0) + processing_lag = 0; + + user->processing_lag = processing_lag; + + } + + /* Record baseline duration of frame by excluding lag */ + user->last_frame_duration = frame_duration - user->processing_lag; } - /* Record duration of frame */ - user->last_frame_duration = frame_duration; - if (user->sync_handler) return user->sync_handler(user, timestamp); return 0; diff --git a/src/protocols/rdp/rdp.c b/src/protocols/rdp/rdp.c index 893fde5e..389c7049 100644 --- a/src/protocols/rdp/rdp.c +++ b/src/protocols/rdp/rdp.c @@ -832,6 +832,13 @@ static int guac_rdp_handle_connection(guac_client* client) { break; } while (wait_result > 0); + + /* Record end of frame, excluding server-side rendering time (we + * assume server-side rendering time will be consistent between any + * two subsequent frames, and that this time should thus be + * excluded from the required wait period of the next frame). */ + last_frame_end = frame_start; + } /* If an error occurred, fail */ @@ -839,14 +846,11 @@ static int guac_rdp_handle_connection(guac_client* client) { guac_client_abort(client, GUAC_PROTOCOL_STATUS_UPSTREAM_ERROR, "Connection closed."); - /* End of frame */ + /* Flush frame */ guac_common_display_flush(rdp_client->display); guac_client_end_frame(client); guac_socket_flush(client->socket); - /* Record end of frame */ - last_frame_end = guac_timestamp_current(); - } pthread_mutex_lock(&(rdp_client->rdp_lock)); diff --git a/src/protocols/vnc/vnc.c b/src/protocols/vnc/vnc.c index 992933d0..9b0bd769 100644 --- a/src/protocols/vnc/vnc.c +++ b/src/protocols/vnc/vnc.c @@ -380,6 +380,12 @@ void* guac_vnc_client_thread(void* data) { } while (wait_result > 0); + /* Record end of frame, excluding server-side rendering time (we + * assume server-side rendering time will be consistent between any + * two subsequent frames, and that this time should thus be + * excluded from the required wait period of the next frame). */ + last_frame_end = frame_start; + } /* If an error occurs, log it and fail */ @@ -391,9 +397,6 @@ void* guac_vnc_client_thread(void* data) { guac_client_end_frame(client); guac_socket_flush(client->socket); - /* Record end of frame */ - last_frame_end = guac_timestamp_current(); - } /* Kill client and finish connection */