[Spice-devel] [PATCH spice-server 08/15] Move dcc_create_stream() to dcc
Jonathon Jongsma
jjongsma at redhat.com
Fri Oct 20 21:13:13 UTC 2017
The declaration is already in dcc.h. Also move helper functions.
Signed-off-by: Jonathon Jongsma <jjongsma at redhat.com>
---
server/dcc.c | 186 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
server/stream.c | 186 --------------------------------------------------------
2 files changed, 186 insertions(+), 186 deletions(-)
diff --git a/server/dcc.c b/server/dcc.c
index 6e64f44d3..00bc28b92 100644
--- a/server/dcc.c
+++ b/server/dcc.c
@@ -1546,3 +1546,189 @@ RedPipeItem *stream_destroy_item_new(StreamAgent *agent)
return stream_create_destroy_item_new(agent, RED_PIPE_ITEM_TYPE_STREAM_DESTROY);
}
+static uint64_t get_initial_bit_rate(DisplayChannelClient *dcc, Stream *stream)
+{
+ char *env_bit_rate_str;
+ uint64_t bit_rate = 0;
+
+ env_bit_rate_str = getenv("SPICE_BIT_RATE");
+ if (env_bit_rate_str != NULL) {
+ double env_bit_rate;
+
+ errno = 0;
+ env_bit_rate = strtod(env_bit_rate_str, NULL);
+ if (errno == 0) {
+ bit_rate = env_bit_rate * 1024 * 1024;
+ } else {
+ spice_warning("error parsing SPICE_BIT_RATE: %s", strerror(errno));
+ }
+ }
+
+ if (!bit_rate) {
+ MainChannelClient *mcc;
+ uint64_t net_test_bit_rate;
+
+ mcc = red_client_get_main(red_channel_client_get_client(RED_CHANNEL_CLIENT(dcc)));
+ net_test_bit_rate = main_channel_client_is_network_info_initialized(mcc) ?
+ main_channel_client_get_bitrate_per_sec(mcc) :
+ 0;
+ bit_rate = MAX(dcc_get_max_stream_bit_rate(dcc), net_test_bit_rate);
+ if (bit_rate == 0) {
+ /*
+ * In case we are after a spice session migration,
+ * the low_bandwidth flag is retrieved from migration data.
+ * If the network info is not initialized due to another reason,
+ * the low_bandwidth flag is FALSE.
+ */
+ bit_rate = dcc_is_low_bandwidth(dcc) ?
+ RED_STREAM_DEFAULT_LOW_START_BIT_RATE :
+ RED_STREAM_DEFAULT_HIGH_START_BIT_RATE;
+ }
+ }
+
+ spice_debug("base-bit-rate %.2f (Mbps)", bit_rate / 1024.0 / 1024.0);
+ /* 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 * bit_rate *
+ stream->width * stream->height) / DCC_TO_DC(dcc)->priv->streams_size_total;
+}
+
+static uint32_t get_roundtrip_ms(void *opaque)
+{
+ StreamAgent *agent = opaque;
+ int roundtrip;
+ RedChannelClient *rcc = RED_CHANNEL_CLIENT(agent->dcc);
+
+ roundtrip = red_channel_client_get_roundtrip_ms(rcc);
+ if (roundtrip < 0) {
+ MainChannelClient *mcc = red_client_get_main(red_channel_client_get_client(rcc));
+
+ /*
+ * the main channel client roundtrip might not have been
+ * calculated (e.g., after migration). In such case,
+ * main_channel_client_get_roundtrip_ms returns 0.
+ */
+ roundtrip = main_channel_client_get_roundtrip_ms(mcc);
+ }
+
+ return roundtrip;
+}
+
+static uint32_t get_source_fps(void *opaque)
+{
+ StreamAgent *agent = opaque;
+
+ return agent->stream->input_fps;
+}
+
+static void update_client_playback_delay(void *opaque, uint32_t delay_ms)
+{
+ StreamAgent *agent = opaque;
+ DisplayChannelClient *dcc = agent->dcc;
+ RedChannel *channel = red_channel_client_get_channel(RED_CHANNEL_CLIENT(dcc));
+ RedClient *client = red_channel_client_get_client(RED_CHANNEL_CLIENT(dcc));
+ RedsState *reds = red_channel_get_server(channel);
+
+ dcc_update_streams_max_latency(dcc, agent);
+
+ agent->client_required_latency = delay_ms;
+ if (delay_ms > dcc_get_max_stream_latency(dcc)) {
+ dcc_set_max_stream_latency(dcc, delay_ms);
+ }
+ spice_debug("resetting client latency: %u", dcc_get_max_stream_latency(dcc));
+ main_dispatcher_set_mm_time_latency(reds_get_main_dispatcher(reds),
+ client,
+ dcc_get_max_stream_latency(agent->dcc));
+}
+
+static void bitmap_ref(gpointer data)
+{
+ RedDrawable *red_drawable = (RedDrawable*)data;
+ red_drawable_ref(red_drawable);
+}
+
+static void bitmap_unref(gpointer data)
+{
+ RedDrawable *red_drawable = (RedDrawable*)data;
+ red_drawable_unref(red_drawable);
+}
+
+/* A helper for dcc_create_stream(). */
+static VideoEncoder* dcc_create_video_encoder(DisplayChannelClient *dcc,
+ uint64_t starting_bit_rate,
+ VideoEncoderRateControlCbs *cbs)
+{
+ RedChannelClient *rcc = RED_CHANNEL_CLIENT(dcc);
+ bool client_has_multi_codec = red_channel_client_test_remote_cap(rcc, SPICE_DISPLAY_CAP_MULTI_CODEC);
+ int i;
+ GArray *video_codecs;
+
+ video_codecs = dcc_get_preferred_video_codecs_for_encoding(dcc);
+ for (i = 0; i < video_codecs->len; i++) {
+ RedVideoCodec* video_codec = &g_array_index (video_codecs, RedVideoCodec, i);
+
+ if (!client_has_multi_codec &&
+ video_codec->type != SPICE_VIDEO_CODEC_TYPE_MJPEG) {
+ /* Old clients only support MJPEG */
+ continue;
+ }
+ if (client_has_multi_codec &&
+ !red_channel_client_test_remote_cap(rcc, video_codec->cap)) {
+ /* The client is recent but does not support this codec */
+ continue;
+ }
+
+ VideoEncoder* video_encoder = video_codec->create(video_codec->type, starting_bit_rate, cbs, bitmap_ref, bitmap_unref);
+ if (video_encoder) {
+ return video_encoder;
+ }
+ }
+
+ /* Try to use the builtin MJPEG video encoder as a fallback */
+ if (!client_has_multi_codec || red_channel_client_test_remote_cap(rcc, SPICE_DISPLAY_CAP_CODEC_MJPEG)) {
+ return mjpeg_encoder_new(SPICE_VIDEO_CODEC_TYPE_MJPEG, starting_bit_rate, cbs, bitmap_ref, bitmap_unref);
+ }
+
+ return NULL;
+}
+
+void dcc_create_stream(DisplayChannelClient *dcc, Stream *stream)
+{
+ StreamAgent *agent = dcc_get_stream_agent(dcc, display_channel_get_stream_id(DCC_TO_DC(dcc), stream));
+
+ spice_return_if_fail(region_is_empty(&agent->vis_region));
+
+ if (stream->current) {
+ region_clone(&agent->vis_region, &stream->current->tree_item.base.rgn);
+ region_clone(&agent->clip, &agent->vis_region);
+ }
+ agent->fps = MAX_FPS;
+ agent->dcc = dcc;
+
+ VideoEncoderRateControlCbs video_cbs;
+ video_cbs.opaque = agent;
+ video_cbs.get_roundtrip_ms = get_roundtrip_ms;
+ video_cbs.get_source_fps = get_source_fps;
+ video_cbs.update_client_playback_delay = update_client_playback_delay;
+
+ uint64_t initial_bit_rate = get_initial_bit_rate(dcc, stream);
+ agent->video_encoder = dcc_create_video_encoder(dcc, initial_bit_rate, &video_cbs);
+ red_channel_client_pipe_add(RED_CHANNEL_CLIENT(dcc), stream_create_item_new(agent));
+
+ if (red_channel_client_test_remote_cap(RED_CHANNEL_CLIENT(dcc), SPICE_DISPLAY_CAP_STREAM_REPORT)) {
+ RedStreamActivateReportItem *report_pipe_item = g_new0(RedStreamActivateReportItem, 1);
+
+ agent->report_id = rand();
+ red_pipe_item_init(&report_pipe_item->pipe_item,
+ RED_PIPE_ITEM_TYPE_STREAM_ACTIVATE_REPORT);
+ report_pipe_item->stream_id = display_channel_get_stream_id(DCC_TO_DC(dcc), stream);
+ red_channel_client_pipe_add(RED_CHANNEL_CLIENT(dcc), &report_pipe_item->pipe_item);
+ }
+#ifdef STREAM_STATS
+ memset(&agent->stats, 0, sizeof(StreamStats));
+ if (stream->current) {
+ agent->stats.start = stream->current->red_drawable->mm_time;
+ }
+#endif
+}
+
diff --git a/server/stream.c b/server/stream.c
index 6b585f653..f45a92feb 100644
--- a/server/stream.c
+++ b/server/stream.c
@@ -499,192 +499,6 @@ void stream_maintenance(DisplayChannel *display,
}
}
-static uint64_t get_initial_bit_rate(DisplayChannelClient *dcc, Stream *stream)
-{
- char *env_bit_rate_str;
- uint64_t bit_rate = 0;
-
- env_bit_rate_str = getenv("SPICE_BIT_RATE");
- if (env_bit_rate_str != NULL) {
- double env_bit_rate;
-
- errno = 0;
- env_bit_rate = strtod(env_bit_rate_str, NULL);
- if (errno == 0) {
- bit_rate = env_bit_rate * 1024 * 1024;
- } else {
- spice_warning("error parsing SPICE_BIT_RATE: %s", strerror(errno));
- }
- }
-
- if (!bit_rate) {
- MainChannelClient *mcc;
- uint64_t net_test_bit_rate;
-
- mcc = red_client_get_main(red_channel_client_get_client(RED_CHANNEL_CLIENT(dcc)));
- net_test_bit_rate = main_channel_client_is_network_info_initialized(mcc) ?
- main_channel_client_get_bitrate_per_sec(mcc) :
- 0;
- bit_rate = MAX(dcc_get_max_stream_bit_rate(dcc), net_test_bit_rate);
- if (bit_rate == 0) {
- /*
- * In case we are after a spice session migration,
- * the low_bandwidth flag is retrieved from migration data.
- * If the network info is not initialized due to another reason,
- * the low_bandwidth flag is FALSE.
- */
- bit_rate = dcc_is_low_bandwidth(dcc) ?
- RED_STREAM_DEFAULT_LOW_START_BIT_RATE :
- RED_STREAM_DEFAULT_HIGH_START_BIT_RATE;
- }
- }
-
- spice_debug("base-bit-rate %.2f (Mbps)", bit_rate / 1024.0 / 1024.0);
- /* 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 * bit_rate *
- stream->width * stream->height) / DCC_TO_DC(dcc)->priv->streams_size_total;
-}
-
-static uint32_t get_roundtrip_ms(void *opaque)
-{
- StreamAgent *agent = opaque;
- int roundtrip;
- RedChannelClient *rcc = RED_CHANNEL_CLIENT(agent->dcc);
-
- roundtrip = red_channel_client_get_roundtrip_ms(rcc);
- if (roundtrip < 0) {
- MainChannelClient *mcc = red_client_get_main(red_channel_client_get_client(rcc));
-
- /*
- * the main channel client roundtrip might not have been
- * calculated (e.g., after migration). In such case,
- * main_channel_client_get_roundtrip_ms returns 0.
- */
- roundtrip = main_channel_client_get_roundtrip_ms(mcc);
- }
-
- return roundtrip;
-}
-
-static uint32_t get_source_fps(void *opaque)
-{
- StreamAgent *agent = opaque;
-
- return agent->stream->input_fps;
-}
-
-static void update_client_playback_delay(void *opaque, uint32_t delay_ms)
-{
- StreamAgent *agent = opaque;
- DisplayChannelClient *dcc = agent->dcc;
- RedChannel *channel = red_channel_client_get_channel(RED_CHANNEL_CLIENT(dcc));
- RedClient *client = red_channel_client_get_client(RED_CHANNEL_CLIENT(dcc));
- RedsState *reds = red_channel_get_server(channel);
-
- dcc_update_streams_max_latency(dcc, agent);
-
- agent->client_required_latency = delay_ms;
- if (delay_ms > dcc_get_max_stream_latency(dcc)) {
- dcc_set_max_stream_latency(dcc, delay_ms);
- }
- spice_debug("resetting client latency: %u", dcc_get_max_stream_latency(dcc));
- main_dispatcher_set_mm_time_latency(reds_get_main_dispatcher(reds),
- client,
- dcc_get_max_stream_latency(agent->dcc));
-}
-
-static void bitmap_ref(gpointer data)
-{
- RedDrawable *red_drawable = (RedDrawable*)data;
- red_drawable_ref(red_drawable);
-}
-
-static void bitmap_unref(gpointer data)
-{
- RedDrawable *red_drawable = (RedDrawable*)data;
- red_drawable_unref(red_drawable);
-}
-
-/* A helper for dcc_create_stream(). */
-static VideoEncoder* dcc_create_video_encoder(DisplayChannelClient *dcc,
- uint64_t starting_bit_rate,
- VideoEncoderRateControlCbs *cbs)
-{
- RedChannelClient *rcc = RED_CHANNEL_CLIENT(dcc);
- bool client_has_multi_codec = red_channel_client_test_remote_cap(rcc, SPICE_DISPLAY_CAP_MULTI_CODEC);
- int i;
- GArray *video_codecs;
-
- video_codecs = dcc_get_preferred_video_codecs_for_encoding(dcc);
- for (i = 0; i < video_codecs->len; i++) {
- RedVideoCodec* video_codec = &g_array_index (video_codecs, RedVideoCodec, i);
-
- if (!client_has_multi_codec &&
- video_codec->type != SPICE_VIDEO_CODEC_TYPE_MJPEG) {
- /* Old clients only support MJPEG */
- continue;
- }
- if (client_has_multi_codec &&
- !red_channel_client_test_remote_cap(rcc, video_codec->cap)) {
- /* The client is recent but does not support this codec */
- continue;
- }
-
- VideoEncoder* video_encoder = video_codec->create(video_codec->type, starting_bit_rate, cbs, bitmap_ref, bitmap_unref);
- if (video_encoder) {
- return video_encoder;
- }
- }
-
- /* Try to use the builtin MJPEG video encoder as a fallback */
- if (!client_has_multi_codec || red_channel_client_test_remote_cap(rcc, SPICE_DISPLAY_CAP_CODEC_MJPEG)) {
- return mjpeg_encoder_new(SPICE_VIDEO_CODEC_TYPE_MJPEG, starting_bit_rate, cbs, bitmap_ref, bitmap_unref);
- }
-
- return NULL;
-}
-
-void dcc_create_stream(DisplayChannelClient *dcc, Stream *stream)
-{
- StreamAgent *agent = dcc_get_stream_agent(dcc, display_channel_get_stream_id(DCC_TO_DC(dcc), stream));
-
- spice_return_if_fail(region_is_empty(&agent->vis_region));
-
- if (stream->current) {
- region_clone(&agent->vis_region, &stream->current->tree_item.base.rgn);
- region_clone(&agent->clip, &agent->vis_region);
- }
- agent->fps = MAX_FPS;
- agent->dcc = dcc;
-
- VideoEncoderRateControlCbs video_cbs;
- video_cbs.opaque = agent;
- video_cbs.get_roundtrip_ms = get_roundtrip_ms;
- video_cbs.get_source_fps = get_source_fps;
- video_cbs.update_client_playback_delay = update_client_playback_delay;
-
- uint64_t initial_bit_rate = get_initial_bit_rate(dcc, stream);
- agent->video_encoder = dcc_create_video_encoder(dcc, initial_bit_rate, &video_cbs);
- red_channel_client_pipe_add(RED_CHANNEL_CLIENT(dcc), stream_create_item_new(agent));
-
- if (red_channel_client_test_remote_cap(RED_CHANNEL_CLIENT(dcc), SPICE_DISPLAY_CAP_STREAM_REPORT)) {
- RedStreamActivateReportItem *report_pipe_item = g_new0(RedStreamActivateReportItem, 1);
-
- agent->report_id = rand();
- red_pipe_item_init(&report_pipe_item->pipe_item,
- RED_PIPE_ITEM_TYPE_STREAM_ACTIVATE_REPORT);
- report_pipe_item->stream_id = display_channel_get_stream_id(DCC_TO_DC(dcc), stream);
- red_channel_client_pipe_add(RED_CHANNEL_CLIENT(dcc), &report_pipe_item->pipe_item);
- }
-#ifdef STREAM_STATS
- memset(&agent->stats, 0, sizeof(StreamStats));
- if (stream->current) {
- agent->stats.start = stream->current->red_drawable->mm_time;
- }
-#endif
-}
-
void stream_agent_stop(StreamAgent *agent)
{
DisplayChannelClient *dcc = agent->dcc;
--
2.13.6
More information about the Spice-devel
mailing list