Signed-off-by: Francois Gouget <fgouget@xxxxxxxxxxxxxxx> --- configure.ac | 2 +- server/dcc.c | 5 ++++- server/dcc.h | 2 +- server/stream.c | 41 +++++++++++++++++++++++++++++------------ 4 files changed, 35 insertions(+), 15 deletions(-) diff --git a/configure.ac b/configure.ac index f80178e..174f01f 100644 --- a/configure.ac +++ b/configure.ac @@ -123,7 +123,7 @@ AS_IF([test x"$have_smartcard" = "xyes"], [ AS_VAR_APPEND([SPICE_REQUIRES], [" libcacard >= 0.1.2"]) ]) -SPICE_PROTOCOL_MIN_VER=0.12.10 +SPICE_PROTOCOL_MIN_VER=0.12.11 PKG_CHECK_MODULES([SPICE_PROTOCOL], [spice-protocol >= $SPICE_PROTOCOL_MIN_VER]) AC_SUBST([SPICE_PROTOCOL_MIN_VER]) diff --git a/server/dcc.c b/server/dcc.c index 21e91c0..ed4598f 100644 --- a/server/dcc.c +++ b/server/dcc.c @@ -407,7 +407,10 @@ static void dcc_create_all_streams(DisplayChannelClient *dcc) while ((item = ring_next(ring, item))) { Stream *stream = SPICE_CONTAINEROF(item, Stream, link); - dcc_create_stream(dcc, stream); + if (!dcc_create_stream(dcc, stream)) { + stream_stop(DCC_TO_DC(dcc), stream); + return; + } } } diff --git a/server/dcc.h b/server/dcc.h index b510254..34ca346 100644 --- a/server/dcc.h +++ b/server/dcc.h @@ -173,7 +173,7 @@ void dcc_destroy_surface (DisplayCha uint32_t surface_id); void dcc_stream_agent_clip (DisplayChannelClient* dcc, StreamAgent *agent); -void dcc_create_stream (DisplayChannelClient *dcc, +gboolean dcc_create_stream (DisplayChannelClient *dcc, Stream *stream); void dcc_create_surface (DisplayChannelClient *dcc, int surface_id); diff --git a/server/stream.c b/server/stream.c index 9c335b6..bbc7003 100644 --- a/server/stream.c +++ b/server/stream.c @@ -440,7 +440,12 @@ static void display_channel_create_stream(DisplayChannel *display, Drawable *dra display->streams_size_total += stream->width * stream->height; display->stream_count++; FOREACH_DCC(display, dcc_ring_item, next, dcc) { - dcc_create_stream(dcc, stream); + if (!dcc_create_stream(dcc, stream)) { + drawable->stream = NULL; + stream->current = NULL; + stream_stop(display, stream); + return; + } } spice_debug("stream %d %dx%d (%d, %d) (%d, %d) %u fps", (int)(stream - display->streams_buf), stream->width, @@ -695,25 +700,32 @@ static void update_client_playback_delay(void *opaque, uint32_t delay_ms) } /* A helper for dcc_create_stream(). */ -static VideoEncoder* dcc_create_video_encoder(uint64_t starting_bit_rate, +static VideoEncoder* dcc_create_video_encoder(DisplayChannelClient *dcc, + uint64_t starting_bit_rate, VideoEncoderRateControlCbs *cbs, void *cbs_opaque) { + RedChannelClient *rcc = RED_CHANNEL_CLIENT(dcc); + int client_has_multi_codec = red_channel_client_test_remote_cap(rcc, SPICE_DISPLAY_CAP_MULTI_CODEC); + if (!client_has_multi_codec || red_channel_client_test_remote_cap(rcc, SPICE_DISPLAY_CAP_CODEC_MJPEG)) { #ifdef HAVE_GSTREAMER_1_0 - VideoEncoder* video_encoder = gstreamer_encoder_new(starting_bit_rate, cbs, cbs_opaque); - if (video_encoder) { - return video_encoder; - } + VideoEncoder* video_encoder = gstreamer_encoder_new(starting_bit_rate, cbs, cbs_opaque); + if (video_encoder) { + return video_encoder; + } #endif - /* Use the builtin MJPEG video encoder as a fallback */ - return mjpeg_encoder_new(starting_bit_rate, cbs, cbs_opaque); + /* Use the builtin MJPEG video encoder as a fallback */ + return mjpeg_encoder_new(starting_bit_rate, cbs, cbs_opaque); + } + + return NULL; } -void dcc_create_stream(DisplayChannelClient *dcc, Stream *stream) +gboolean dcc_create_stream(DisplayChannelClient *dcc, Stream *stream) { StreamAgent *agent = &dcc->stream_agents[get_stream_id(DCC_TO_DC(dcc), stream)]; - spice_return_if_fail(region_is_empty(&agent->vis_region)); + spice_return_val_if_fail(region_is_empty(&agent->vis_region), FALSE); stream->refs++; if (stream->current) { @@ -736,9 +748,13 @@ void dcc_create_stream(DisplayChannelClient *dcc, Stream *stream) video_cbs.update_client_playback_delay = update_client_playback_delay; initial_bit_rate = get_initial_bit_rate(dcc, stream); - agent->video_encoder = dcc_create_video_encoder(initial_bit_rate, &video_cbs, agent); + agent->video_encoder = dcc_create_video_encoder(dcc, initial_bit_rate, &video_cbs, agent); } else { - agent->video_encoder = dcc_create_video_encoder(0, NULL, NULL); + agent->video_encoder = dcc_create_video_encoder(dcc, 0, NULL, NULL); + } + if (agent->video_encoder == NULL) { + stream->refs--; + return FALSE; } red_channel_client_pipe_add(RED_CHANNEL_CLIENT(dcc), &agent->create_item); @@ -757,6 +773,7 @@ void dcc_create_stream(DisplayChannelClient *dcc, Stream *stream) agent->stats.start = stream->current->red_drawable->mm_time; } #endif + return TRUE; } void stream_agent_stop(StreamAgent *agent) -- 2.6.4 _______________________________________________ Spice-devel mailing list Spice-devel@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/spice-devel