<div dir="ltr"><div class="gmail_quote"><div dir="ltr"><div>Hi,</div><div><br></div><div>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 :)</div><div><br></div><div>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. </div><div>My idea is to classify the available bandwidth (enum Bandwidth) and based on the classification adjust the JPEG compression level.</div><div>The values for the JPEG level are orientated on the examples from <a href="http://regex.info/blog/lightroom-goodies/jpeg-quality" target="_blank">http://regex.info/blog/lightroom-goodies/jpeg-quality</a> </div><div>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.</div><div>Adjusting the compression level to 7 lets play youtube videos very good but they are fairly ugly.</div><div><br></div><div>Greetings, Flavio</div><div><br></div><div>---</div><div><br></div><div>server/main_channel.c | 16 ++++++++++++++++</div><div>server/main_channel.h | 10 ++++++++++</div><div>server/red_worker.c | 22 ++++++++++++++++++++--</div><div>3 files changed, 46 insertions(+), 2 deletions(-)</div><div><br></div><div><br></div><div>diff --git a/server/main_channel.h b/server/main_channel.h</div><div>index c8e9ade..f956778 100644</div><div>--- a/server/main_channel.h</div><div>+++ b/server/main_channel.h</div><div>@@ -40,6 +40,14 @@ typedef struct MainChannel {</div><div> int num_clients_mig_wait;</div><div> } MainChannel;</div><div> </div><div>+typedef enum Bandwidth {</div><div>+<span style="white-space:pre-wrap"> </span>LAN,</div><div>+<span style="white-space:pre-wrap"> </span>WAN,</div><div>+<span style="white-space:pre-wrap"> </span>EIGHT_MBPS,</div><div>+<span style="white-space:pre-wrap"> </span>FOUR_MBPS,</div><div>+<span style="white-space:pre-wrap"> </span>VERY_LOW</div><div>+} Bandwidth;</div><div> </div><div> MainChannel *main_channel_init(void);</div><div> RedClient *main_channel_get_client_by_link_id(MainChannel *main_chan, uint32_t link_id);</div><div>@@ -76,6 +84,8 @@ int main_channel_client_is_low_bandwidth(MainChannelClient *mcc);</div><div> uint64_t main_channel_client_get_bitrate_per_sec(MainChannelClient *mcc);</div><div> uint64_t main_channel_client_get_roundtrip_ms(MainChannelClient *mcc);</div><div> </div><div>+Bandwidth main_channel_client_get_bandwidth_type(MainChannelClient *mcc);</div><div>+</div><div> int main_channel_is_connected(MainChannel *main_chan);</div><div> RedChannelClient* main_channel_client_get_base(MainChannelClient* mcc);</div><div> </div><div><br></div><div><br></div><div>diff --git a/server/main_channel.c b/server/main_channel.c</div><div>index 54718ba..c656820 100644</div><div>--- a/server/main_channel.c</div><div>+++ b/server/main_channel.c</div><div>@@ -1171,6 +1171,22 @@ int main_channel_client_is_low_bandwidth(MainChannelClient *mcc)</div><div> return mcc->bitrate_per_sec < 10 * 1024 * 1024;</div><div> }</div><div> </div><div>+Bandwidth main_channel_client_get_bandwidth_type(MainChannelClient *mcc)</div><div>+{</div><div>+ int mbps = mcc->bitrate_per_sec / (1024*1024);</div><div>+</div><div>+ if(mbps > 10)</div><div>+<span style="white-space:pre-wrap"> </span>return LAN;</div><div>+ else if(mbps <= 10 && mbps > 8)</div><div>+<span style="white-space:pre-wrap"> </span>return WAN;</div><div>+ else if(mbps <= 8 && mbps > 6)</div><div>+ return EIGHT_MBPS;</div><div>+ else if(mbps <= 6 && mbps > 3) </div><div>+ return FOUR_MBPS;</div><div>+</div><div>+ return VERY_LOW;</div><div>+}</div><div>+</div><div> uint64_t main_channel_client_get_bitrate_per_sec(MainChannelClient *mcc)</div><div> {</div><div> return mcc->bitrate_per_sec;</div><div><br></div><div><br></div><div><br></div><div>diff --git a/server/red_worker.c b/server/red_worker.c</div><div>index 5deb30b..7448232 100644</div><div>--- a/server/red_worker.c</div><div>+++ b/server/red_worker.c</div><div>@@ -680,6 +680,7 @@ typedef struct CommonChannelClient {</div><div> uint32_t id;</div><div> struct RedWorker *worker;</div><div> int is_low_bandwidth;</div><div>+ Bandwidth bandwidth_type;</div><div> } CommonChannelClient;</div><div> </div><div> /* Each drawable can refer to at most 3 images: src, brush and mask */</div><div>@@ -10318,6 +10319,7 @@ static int common_channel_config_socket(RedChannelClient *rcc)</div><div> </div><div> // TODO - this should be dynamic, not one time at channel creation</div><div> ccc->is_low_bandwidth = main_channel_client_is_low_bandwidth(mcc);</div><div>+ ccc->bandwidth_type = main_channel_client_get_bandwidth_type(mcc);</div><div> delay_val = ccc->is_low_bandwidth ? 0 : 1;</div><div> /* FIXME: Using Nagle's Algorithm can lead to apparent delays, depending</div><div> * on the delayed ack timeout on the other side.</div><div>@@ -10803,9 +10805,25 @@ static void handle_new_display_channel(RedWorker *worker, RedClient *client, Red</div><div> } else {</div><div> display_channel->enable_jpeg = (worker->jpeg_state == SPICE_WAN_COMPRESSION_ALWAYS);</div><div> }</div><div>-</div><div> // todo: tune quality according to bandwidth</div><div>- display_channel->jpeg_quality = 85;</div><div>+</div><div>+ switch(dcc->common.bandwidth_type) {</div><div>+ case LAN:</div><div>+ display_channel->jpeg_quality = 85;</div><div>+ break;</div><div>+ case WAN:</div><div>+ display_channel->jpeg_quality = 54;</div><div>+ break;</div><div>+ case EIGHT_MBPS:</div><div>+ display_channel->jpeg_quality = 39;</div><div>+ break;</div><div>+ case FOUR_MBPS:</div><div>+ display_channel->jpeg_quality = 16;</div><div>+ break;</div><div>+ default:</div><div>+ // very bad performance and very bad quality</div><div>+ display_channel->jpeg_quality = 7;</div><div>+ }</div><div> </div><div> if (worker->zlib_glz_state == SPICE_WAN_COMPRESSION_AUTO) {</div><div> display_channel->enable_zlib_glz_wrap = dcc->common.is_low_bandwidth;</div><div><br></div></div>
</div><br></div>