[Spice-devel] Adjust JPEG Quality according to Bandwidth
Victor Toso
victortoso at redhat.com
Mon Mar 23 09:07:58 PDT 2015
Hey,
Thanks for your time and interest in spice,
On Sat, Mar 21, 2015 at 11:38:33AM +0100, Flavio G. wrote:
> Hi,
>
> my name is Flavio (deano in IRC). Because I want to get more practice in C
> Programming and Programming generally and because I like spice very much I
> started reading source code of spice server and already written a very
> little patch. Maybe you could tell me if I am on the right track or if it
> is garbage what I do :)
IMHO, you are in the right track regarding the jpeg compression. The
main issue I think is that the bandwidth is only calculated once, right?
I guess it should be dynamic.
I believe someone more knowledgeable about the server can give you better
feedback.
> So: I am using wireless LAN and the access point is relativly far away. So
> I just get ca. 8-9 Megabit per seconds. When using LibreOffice for example
> on the VM it runs smoothly. But when opening a website for example with
> Pictures, Flash animations and maybe ads the connection is more or less
> unusable (at 100MBit Ethernet performance is absolute adequate). I saw that
> JPEG compression is "hard coded" to 85.
> My idea is to classify the available bandwidth (enum Bandwidth) and based
> on the classification adjust the JPEG compression level.
> The values for the JPEG level are orientated on the examples from
> http://regex.info/blog/lightroom-goodies/jpeg-quality
> I don't know if a connection 4 Megabit is very realistic. But the Jump from
> 85 to 54 saves some bandwidth for me in WLAN and I can Browse better.
> Adjusting the compression level to 7 lets play youtube videos very good but
> they are fairly ugly.
>
> Greetings, Flavio
There is also a bandwidth monitoring RFE open if you are interesting in
that, feel free to comment o the bug report.
https://bugs.freedesktop.org/show_bug.cgi?id=87324
> ---
>
> server/main_channel.c | 16 ++++++++++++++++
> server/main_channel.h | 10 ++++++++++
> server/red_worker.c | 22 ++++++++++++++++++++--
> 3 files changed, 46 insertions(+), 2 deletions(-)
>
>
> diff --git a/server/main_channel.h b/server/main_channel.h
> index c8e9ade..f956778 100644
> --- a/server/main_channel.h
> +++ b/server/main_channel.h
> @@ -40,6 +40,14 @@ typedef struct MainChannel {
> int num_clients_mig_wait;
> } MainChannel;
>
> +typedef enum Bandwidth {
> + LAN,
> + WAN,
> + EIGHT_MBPS,
> + FOUR_MBPS,
> + VERY_LOW
> +} Bandwidth;
>
> MainChannel *main_channel_init(void);
> RedClient *main_channel_get_client_by_link_id(MainChannel *main_chan,
> uint32_t link_id);
> @@ -76,6 +84,8 @@ int
> main_channel_client_is_low_bandwidth(MainChannelClient *mcc);
> uint64_t main_channel_client_get_bitrate_per_sec(MainChannelClient *mcc);
> uint64_t main_channel_client_get_roundtrip_ms(MainChannelClient *mcc);
>
> +Bandwidth main_channel_client_get_bandwidth_type(MainChannelClient *mcc);
> +
> int main_channel_is_connected(MainChannel *main_chan);
> RedChannelClient* main_channel_client_get_base(MainChannelClient* mcc);
>
>
>
> diff --git a/server/main_channel.c b/server/main_channel.c
> index 54718ba..c656820 100644
> --- a/server/main_channel.c
> +++ b/server/main_channel.c
> @@ -1171,6 +1171,22 @@ int
> main_channel_client_is_low_bandwidth(MainChannelClient *mcc)
> return mcc->bitrate_per_sec < 10 * 1024 * 1024;
> }
>
> +Bandwidth main_channel_client_get_bandwidth_type(MainChannelClient *mcc)
> +{
> + int mbps = mcc->bitrate_per_sec / (1024*1024);
> +
> + if(mbps > 10)
> + return LAN;
> + else if(mbps <= 10 && mbps > 8)
> + return WAN;
> + else if(mbps <= 8 && mbps > 6)
> + return EIGHT_MBPS;
> + else if(mbps <= 6 && mbps > 3)
> + return FOUR_MBPS;
> +
> + return VERY_LOW;
> +}
> +
> uint64_t main_channel_client_get_bitrate_per_sec(MainChannelClient *mcc)
> {
> return mcc->bitrate_per_sec;
>
>
>
> diff --git a/server/red_worker.c b/server/red_worker.c
> index 5deb30b..7448232 100644
> --- a/server/red_worker.c
> +++ b/server/red_worker.c
> @@ -680,6 +680,7 @@ typedef struct CommonChannelClient {
> uint32_t id;
> struct RedWorker *worker;
> int is_low_bandwidth;
> + Bandwidth bandwidth_type;
> } CommonChannelClient;
>
> /* Each drawable can refer to at most 3 images: src, brush and mask */
> @@ -10318,6 +10319,7 @@ static int
> common_channel_config_socket(RedChannelClient *rcc)
>
> // TODO - this should be dynamic, not one time at channel creation
> ccc->is_low_bandwidth = main_channel_client_is_low_bandwidth(mcc);
> + ccc->bandwidth_type = main_channel_client_get_bandwidth_type(mcc);
> delay_val = ccc->is_low_bandwidth ? 0 : 1;
> /* FIXME: Using Nagle's Algorithm can lead to apparent delays,
> depending
> * on the delayed ack timeout on the other side.
> @@ -10803,9 +10805,25 @@ static void handle_new_display_channel(RedWorker
> *worker, RedClient *client, Red
> } else {
> display_channel->enable_jpeg = (worker->jpeg_state ==
> SPICE_WAN_COMPRESSION_ALWAYS);
> }
> -
> // todo: tune quality according to bandwidth
> - display_channel->jpeg_quality = 85;
> +
> + switch(dcc->common.bandwidth_type) {
> + case LAN:
> + display_channel->jpeg_quality = 85;
> + break;
> + case WAN:
> + display_channel->jpeg_quality = 54;
> + break;
> + case EIGHT_MBPS:
> + display_channel->jpeg_quality = 39;
> + break;
> + case FOUR_MBPS:
> + display_channel->jpeg_quality = 16;
> + break;
> + default:
> + // very bad performance and very bad quality
> + display_channel->jpeg_quality = 7;
> + }
>
> if (worker->zlib_glz_state == SPICE_WAN_COMPRESSION_AUTO) {
> display_channel->enable_zlib_glz_wrap =
> dcc->common.is_low_bandwidth;
> _______________________________________________
> Spice-devel mailing list
> Spice-devel at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/spice-devel
More information about the Spice-devel
mailing list