Re: [client v2 5/5] streaming: Separate the network code from the display_stream management

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Mon, 24 Apr 2017, Christophe Fergeau wrote:
[...]
> > +    c->streams[op->id] = display_stream_create(channel, op->surface_id, op->flags, op->codec_type);
> > +    if (c->streams[op->id] == NULL) {
> > +        spice_printerr("could not create the %u video stream", op->id);
> >          destroy_stream(channel, op->id);
> >          report_invalid_stream(channel, op->id);
> > +    } else {
> > +        c->streams[op->id]->dest = op->dest;
> > +        c->streams[op->id]->clip = op->clip;
> 
> Any reason why you initialize everything in display_stream_create()
> except these SpiceRect/SpiceClip instances? I'd just squash this in:

There's no big reason.
 * Concerning dest, setting it is required for the stream to work so 
   it could make sense to set it up in display_stream_create().
 * But one does not need to set an explicit clip region to use the 
   stream and as is it defaults to SPICE_CLIP_TYPE_NONE which I think 
   makes sense. So I'd leave setting it up to the caller so it is 
   optional.

So I'd propose another variant where display_stream_create() takes a 
rect parameter but leaves clip to its default. See the attached patch. 
Feel free to pick any of the three variants.


I have a use case here where I need to create a stream before I have 
received the rect and where I don't use clipping at all which is why I 
naturally made these optional. But that code is not public (yet anyway) 
and one could argue that the rect should be known at stream creation 
time. In any case it would be trivial to initialize local variables to 
dummy values and pass them to display_stream_create() so any variant 
would be easy for me to adjust to.

(And I apologize for the delay, my Internet connection broke down last 
week and then I was away for the extended week-end)

-- 
Francois Gouget <fgouget@xxxxxxxxxxxxxxx>              
commit 6a3bd17fa881c3d95c3c3e923161137e147660b6
Author: Francois Gouget <fgouget@xxxxxxxxxxxxxxx>
Date:   Fri May 20 19:32:42 2016 +0200

    streaming: Separate the network code from the display_stream management
    
    This makes it easier to reuse display_streams for other types of
    video streams should the need arise.
    
    Signed-off-by: Francois Gouget <fgouget@xxxxxxxxxxxxxxx>

diff --git a/src/channel-display.c b/src/channel-display.c
index 00b54406..c129e3ba 100644
--- a/src/channel-display.c
+++ b/src/channel-display.c
@@ -109,7 +109,7 @@ static display_surface *find_surface(SpiceDisplayChannelPrivate *c, guint32 surf
 static void spice_display_channel_reset(SpiceChannel *channel, gboolean migrating);
 static void spice_display_channel_reset_capabilities(SpiceChannel *channel);
 static void destroy_canvas(display_surface *surface);
-static void destroy_stream(SpiceChannel *channel, int id);
+static void destroy_display_stream(display_stream *st, int id);
 static void display_session_mm_time_reset_cb(SpiceSession *session, gpointer data);
 static SpiceGlScanout* spice_gl_scanout_copy(const SpiceGlScanout *scanout);
 
@@ -1168,11 +1168,59 @@ static display_stream *get_stream_by_id(SpiceChannel *channel, uint32_t id)
 }
 
 /* coroutine context */
+static display_stream *display_stream_create(SpiceChannel *channel, uint32_t surface_id, uint32_t flags, uint32_t codec_type, const SpiceRect *dest)
+{
+    SpiceDisplayChannelPrivate *c = SPICE_DISPLAY_CHANNEL(channel)->priv;
+    display_stream *st = g_new0(display_stream, 1);
+
+    st->flags = flags;
+    st->dest = *dest;
+    /* st->clip defaults to SPICE_CLIP_TYPE_NONE */
+    st->surface = find_surface(c, surface_id);
+    st->channel = channel;
+    st->drops_seqs_stats_arr = g_array_new(FALSE, FALSE, sizeof(drops_sequence_stats));
+
+    region_init(&st->region);
+    display_update_stream_region(st);
+
+    switch (codec_type) {
+#ifdef HAVE_BUILTIN_MJPEG
+    case SPICE_VIDEO_CODEC_TYPE_MJPEG:
+        st->video_decoder = create_mjpeg_decoder(codec_type, st);
+        break;
+#endif
+    default:
+#ifdef HAVE_GSTVIDEO
+        st->video_decoder = create_gstreamer_decoder(codec_type, st);
+#endif
+        break;
+    }
+    if (st->video_decoder == NULL) {
+        spice_printerr("could not create a video decoder for codec %u", codec_type);
+        destroy_display_stream(st, 0);
+        st = NULL;
+    }
+    return st;
+}
+
+static void destroy_stream(SpiceChannel *channel, int id)
+{
+    SpiceDisplayChannelPrivate *c = SPICE_DISPLAY_CHANNEL(channel)->priv;
+
+    g_return_if_fail(c != NULL);
+    g_return_if_fail(c->streams != NULL);
+    g_return_if_fail(c->nstreams > id);
+
+    if (c->streams[id]) {
+        destroy_display_stream(c->streams[id], id);
+        c->streams[id] = NULL;
+    }
+}
+
 static void display_handle_stream_create(SpiceChannel *channel, SpiceMsgIn *in)
 {
     SpiceDisplayChannelPrivate *c = SPICE_DISPLAY_CHANNEL(channel)->priv;
     SpiceMsgDisplayStreamCreate *op = spice_msg_in_parsed(in);
-    display_stream *st;
 
     CHANNEL_DEBUG(channel, "%s: id %u", __FUNCTION__, op->id);
 
@@ -1188,36 +1236,14 @@ static void display_handle_stream_create(SpiceChannel *channel, SpiceMsgIn *in)
         memset(c->streams + n, 0, (c->nstreams - n) * sizeof(c->streams[0]));
     }
     g_return_if_fail(c->streams[op->id] == NULL);
-    c->streams[op->id] = g_new0(display_stream, 1);
-    st = c->streams[op->id];
-
-    st->flags = op->flags;
-    st->dest = op->dest;
-    st->clip = op->clip;
-    st->surface = find_surface(c, op->surface_id);
-    st->channel = channel;
-    st->drops_seqs_stats_arr = g_array_new(FALSE, FALSE, sizeof(drops_sequence_stats));
 
-    region_init(&st->region);
-    display_update_stream_region(st);
-
-    switch (op->codec_type) {
-#ifdef HAVE_BUILTIN_MJPEG
-    case SPICE_VIDEO_CODEC_TYPE_MJPEG:
-        st->video_decoder = create_mjpeg_decoder(op->codec_type, st);
-        break;
-#endif
-    default:
-#ifdef HAVE_GSTVIDEO
-        st->video_decoder = create_gstreamer_decoder(op->codec_type, st);
-#else
-        st->video_decoder = NULL;
-#endif
-    }
-    if (st->video_decoder == NULL) {
-        spice_printerr("could not create a video decoder for codec %u", op->codec_type);
+    c->streams[op->id] = display_stream_create(channel, op->surface_id, op->flags, op->codec_type, &op->dest);
+    if (c->streams[op->id] == NULL) {
+        spice_printerr("could not create the %u video stream", op->id);
         destroy_stream(channel, op->id);
         report_invalid_stream(channel, op->id);
+    } else {
+        c->streams[op->id]->clip = op->clip;
     }
 }
 
@@ -1503,24 +1529,14 @@ static void display_handle_stream_clip(SpiceChannel *channel, SpiceMsgIn *in)
     display_update_stream_region(st);
 }
 
-static void destroy_stream(SpiceChannel *channel, int id)
+static void destroy_display_stream(display_stream *st, int id)
 {
-    SpiceDisplayChannelPrivate *c = SPICE_DISPLAY_CHANNEL(channel)->priv;
-    display_stream *st;
     int i;
 
-    g_return_if_fail(c != NULL);
-    g_return_if_fail(c->streams != NULL);
-    g_return_if_fail(c->nstreams > id);
-
-    st = c->streams[id];
-    if (!st)
-        return;
-
     if (st->num_input_frames > 0) {
         guint64 drops_duration_total = 0;
         guint32 num_out_frames = st->num_input_frames - st->arrive_late_count - st->num_drops_on_playback;
-        CHANNEL_DEBUG(channel, "%s: id=%d #in-frames=%u out/in=%.2f "
+        CHANNEL_DEBUG(st->channel, "%s: id=%d #in-frames=%u out/in=%.2f "
             "#drops-on-receive=%u avg-late-time(ms)=%.2f "
             "#drops-on-playback=%u", __FUNCTION__,
             id,
@@ -1530,20 +1546,20 @@ static void destroy_stream(SpiceChannel *channel, int id)
             st->arrive_late_count ? st->arrive_late_time / ((double)st->arrive_late_count): 0,
             st->num_drops_on_playback);
         if (st->num_drops_seqs) {
-            CHANNEL_DEBUG(channel, "%s: #drops-sequences=%u ==>", __FUNCTION__, st->num_drops_seqs);
+            CHANNEL_DEBUG(st->channel, "%s: #drops-sequences=%u ==>", __FUNCTION__, st->num_drops_seqs);
         }
         for (i = 0; i < st->num_drops_seqs; i++) {
             drops_sequence_stats *stats = &g_array_index(st->drops_seqs_stats_arr,
                                                          drops_sequence_stats,
                                                          i);
             drops_duration_total += stats->duration;
-            CHANNEL_DEBUG(channel, "%s: \t len=%u start-ms=%u duration-ms=%u", __FUNCTION__,
-                                   stats->len,
-                                   stats->start_mm_time - st->first_frame_mm_time,
-                                   stats->duration);
+            CHANNEL_DEBUG(st->channel, "%s: \t len=%u start-ms=%u duration-ms=%u", __FUNCTION__,
+                          stats->len,
+                          stats->start_mm_time - st->first_frame_mm_time,
+                          stats->duration);
         }
         if (st->num_drops_seqs) {
-            CHANNEL_DEBUG(channel, "%s: drops-total-duration=%"G_GUINT64_FORMAT" ==>", __FUNCTION__, drops_duration_total);
+            CHANNEL_DEBUG(st->channel, "%s: drops-total-duration=%"G_GUINT64_FORMAT" ==>", __FUNCTION__, drops_duration_total);
         }
     }
 
@@ -1554,7 +1570,6 @@ static void destroy_stream(SpiceChannel *channel, int id)
     }
 
     g_free(st);
-    c->streams[id] = NULL;
 }
 
 static void clear_streams(SpiceChannel *channel)
_______________________________________________
Spice-devel mailing list
Spice-devel@xxxxxxxxxxxxxxxxxxxxx
https://lists.freedesktop.org/mailman/listinfo/spice-devel

[Index of Archives]     [Linux ARM Kernel]     [Linux ARM]     [Linux Omap]     [Fedora ARM]     [IETF Annouce]     [Security]     [Bugtraq]     [Linux]     [Linux OMAP]     [Linux MIPS]     [ECOS]     [Asterisk Internet PBX]     [Linux API]     [Monitors]