summaryrefslogtreecommitdiffstats
path: root/server
diff options
context:
space:
mode:
authorYonit Halperin <yhalperi@redhat.com>2013-02-18 18:55:03 -0500
committerYonit Halperin <yhalperi@redhat.com>2013-04-22 16:30:55 -0400
commit4c79f325e2b2f1355850a70cee68d613346a2cbf (patch)
tree9a44ab1acad9d77e903d46981c311aa867b76aad /server
parentbf9e210b21a66210b19f69fcaa4542b393b7dc22 (diff)
downloadspice-4c79f325e2b2f1355850a70cee68d613346a2cbf.tar.gz
spice-4c79f325e2b2f1355850a70cee68d613346a2cbf.tar.xz
spice-4c79f325e2b2f1355850a70cee68d613346a2cbf.zip
server/red_worker.c: use the bit rate of old streams as a start point for new streams
mjpeg_encoder modify the initial bit we supply it, according to the client feedback. If it reaches a bit rate which is higher than the initial one, we use the higher bit rate as the new bit rate estimation.
Diffstat (limited to 'server')
-rw-r--r--server/mjpeg_encoder.c5
-rw-r--r--server/mjpeg_encoder.h2
-rw-r--r--server/red_worker.c16
3 files changed, 22 insertions, 1 deletions
diff --git a/server/mjpeg_encoder.c b/server/mjpeg_encoder.c
index 7328ea26..b1010e0d 100644
--- a/server/mjpeg_encoder.c
+++ b/server/mjpeg_encoder.c
@@ -1247,3 +1247,8 @@ static void mjpeg_encoder_process_server_drops(MJpegEncoder *encoder)
server_state->num_frames_encoded = 0;
server_state->num_frames_dropped = 0;
}
+
+uint64_t mjpeg_encoder_get_bit_rate(MJpegEncoder *encoder)
+{
+ return encoder->rate_control.byte_rate * 8;
+}
diff --git a/server/mjpeg_encoder.h b/server/mjpeg_encoder.h
index 0ee2e962..310d2892 100644
--- a/server/mjpeg_encoder.h
+++ b/server/mjpeg_encoder.h
@@ -102,4 +102,6 @@ void mjpeg_encoder_client_stream_report(MJpegEncoder *encoder,
*/
void mjpeg_encoder_notify_server_frame_drop(MJpegEncoder *encoder);
+uint64_t mjpeg_encoder_get_bit_rate(MJpegEncoder *encoder);
+
#endif
diff --git a/server/red_worker.c b/server/red_worker.c
index f96ff076..8e30ef38 100644
--- a/server/red_worker.c
+++ b/server/red_worker.c
@@ -693,6 +693,7 @@ struct DisplayChannelClient {
StreamAgent stream_agents[NUM_STREAMS];
int use_mjpeg_encoder_rate_control;
uint32_t streams_max_latency;
+ uint64_t streams_max_bit_rate;
};
struct DisplayChannel {
@@ -2616,6 +2617,16 @@ static void red_stop_stream(RedWorker *worker, Stream *stream)
region_clear(&stream_agent->vis_region);
region_clear(&stream_agent->clip);
spice_assert(!pipe_item_is_linked(&stream_agent->destroy_item));
+ if (stream_agent->mjpeg_encoder && dcc->use_mjpeg_encoder_rate_control) {
+ uint64_t stream_bit_rate = mjpeg_encoder_get_bit_rate(stream_agent->mjpeg_encoder);
+
+ if (stream_bit_rate > dcc->streams_max_bit_rate) {
+ spice_debug("old max-bit-rate=%.2f new=%.2f",
+ dcc->streams_max_bit_rate / 8.0 / 1024.0 / 1024.0,
+ stream_bit_rate / 8.0 / 1024.0 / 1024.0);
+ dcc->streams_max_bit_rate = stream_bit_rate;
+ }
+ }
stream->refs++;
red_channel_client_pipe_add(&dcc->common.base, &stream_agent->destroy_item);
}
@@ -2874,10 +2885,13 @@ static uint64_t red_stream_get_initial_bit_rate(DisplayChannelClient *dcc,
mcc = red_client_get_main(dcc->common.base.client);
max_bit_rate = main_channel_client_get_bitrate_per_sec(mcc);
+ if (max_bit_rate > dcc->streams_max_bit_rate) {
+ dcc->streams_max_bit_rate = max_bit_rate;
+ }
/* dividing the available bandwidth among the active streams, and saving
* (1-RED_STREAM_CHANNEL_CAPACITY) of it for other messages */
- return (RED_STREAM_CHANNEL_CAPACITY * max_bit_rate *
+ return (RED_STREAM_CHANNEL_CAPACITY * dcc->streams_max_bit_rate *
stream->width * stream->height) / dcc->common.worker->streams_size_total;
}