GUACAMOLE-632: Dynamically scale JPEG/WebP quality depending on measured processing lag.
This commit is contained in:
parent
54fda21366
commit
45e8503ead
@ -78,13 +78,6 @@
|
|||||||
#define cairo_format_stride_for_width(format, width) (width*4)
|
#define cairo_format_stride_for_width(format, width) (width*4)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
|
||||||
* The JPEG image quality ('quantization') setting to use. Range 0-100 where
|
|
||||||
* 100 is the highest quality/largest file size, and 0 is the lowest
|
|
||||||
* quality/smallest file size.
|
|
||||||
*/
|
|
||||||
#define GUAC_SURFACE_JPEG_IMAGE_QUALITY 90
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The framerate which, if exceeded, indicates that JPEG is preferred.
|
* The framerate which, if exceeded, indicates that JPEG is preferred.
|
||||||
*/
|
*/
|
||||||
@ -96,13 +89,6 @@
|
|||||||
*/
|
*/
|
||||||
#define GUAC_SURFACE_JPEG_MIN_BITMAP_SIZE 4096
|
#define GUAC_SURFACE_JPEG_MIN_BITMAP_SIZE 4096
|
||||||
|
|
||||||
/**
|
|
||||||
* The WebP image quality ('quantization') setting to use. Range 0-100 where
|
|
||||||
* 100 is the highest quality/largest file size, and 0 is the lowest
|
|
||||||
* quality/smallest file size.
|
|
||||||
*/
|
|
||||||
#define GUAC_SURFACE_WEBP_IMAGE_QUALITY 90
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The JPEG compression min block size. This defines the optimal rectangle block
|
* The JPEG compression min block size. This defines the optimal rectangle block
|
||||||
* size factor for JPEG compression. Usually 8x8 would suffice, but use 16 to
|
* size factor for JPEG compression. Usually 8x8 would suffice, but use 16 to
|
||||||
@ -1666,6 +1652,36 @@ static void __guac_common_surface_flush_to_png(guac_common_surface* surface,
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns an appropriate quality between 0 and 100 for lossy encoding
|
||||||
|
* depending on the current processing lag calculated for the given client.
|
||||||
|
*
|
||||||
|
* @param client
|
||||||
|
* The client for which the lossy quality is being calculated.
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
* A value between 0 and 100 inclusive which seems appropriate for the
|
||||||
|
* client based on lag measurements.
|
||||||
|
*/
|
||||||
|
static int guac_common_surface_suggest_quality(guac_client* client) {
|
||||||
|
|
||||||
|
int lag = guac_client_get_processing_lag(client);
|
||||||
|
|
||||||
|
/* Scale quality linearly from 90 to 30 as lag varies from 20ms to 80ms */
|
||||||
|
int quality = 90 - (lag - 20);
|
||||||
|
|
||||||
|
/* Do not exceed 90 for quality */
|
||||||
|
if (quality > 90)
|
||||||
|
return 90;
|
||||||
|
|
||||||
|
/* Do not go below 30 for quality */
|
||||||
|
if (quality < 30)
|
||||||
|
return 30;
|
||||||
|
|
||||||
|
return quality;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Flushes the bitmap update currently described by the dirty rectangle within
|
* Flushes the bitmap update currently described by the dirty rectangle within
|
||||||
* the given surface directly via an "img" instruction as JPEG data. The
|
* the given surface directly via an "img" instruction as JPEG data. The
|
||||||
@ -1702,7 +1718,7 @@ static void __guac_common_surface_flush_to_jpeg(guac_common_surface* surface) {
|
|||||||
/* Send JPEG for rect */
|
/* Send JPEG for rect */
|
||||||
guac_client_stream_jpeg(surface->client, socket, GUAC_COMP_OVER, layer,
|
guac_client_stream_jpeg(surface->client, socket, GUAC_COMP_OVER, layer,
|
||||||
surface->dirty_rect.x, surface->dirty_rect.y, rect,
|
surface->dirty_rect.x, surface->dirty_rect.y, rect,
|
||||||
GUAC_SURFACE_JPEG_IMAGE_QUALITY);
|
guac_common_surface_suggest_quality(surface->client));
|
||||||
|
|
||||||
cairo_surface_destroy(rect);
|
cairo_surface_destroy(rect);
|
||||||
surface->realized = 1;
|
surface->realized = 1;
|
||||||
@ -1764,7 +1780,7 @@ static void __guac_common_surface_flush_to_webp(guac_common_surface* surface,
|
|||||||
/* Send WebP for rect */
|
/* Send WebP for rect */
|
||||||
guac_client_stream_webp(surface->client, socket, GUAC_COMP_OVER, layer,
|
guac_client_stream_webp(surface->client, socket, GUAC_COMP_OVER, layer,
|
||||||
surface->dirty_rect.x, surface->dirty_rect.y, rect,
|
surface->dirty_rect.x, surface->dirty_rect.y, rect,
|
||||||
GUAC_SURFACE_WEBP_IMAGE_QUALITY, 0);
|
guac_common_surface_suggest_quality(surface->client), 0);
|
||||||
|
|
||||||
cairo_surface_destroy(rect);
|
cairo_surface_destroy(rect);
|
||||||
surface->realized = 1;
|
surface->realized = 1;
|
||||||
|
Loading…
Reference in New Issue
Block a user