[Spice-devel] [PATCH spice-gtk 2/2] display-gst: Debug video pipeline on stream-start message

Victor Toso victortoso at redhat.com
Mon Jul 10 15:52:07 UTC 2017


From: Victor Toso <me at victortoso.com>

On GST_MESSAGE_STREAM_START our stream is about to start and it seems
a good moment to debug GStreamer pipeline if requested.

That we can do with GST_DEBUG_BIN_TO_DOT_FILE() which iterates
recursively in the whole pipeline and generates a dot file with all
the information, the filename is 'spice-gtk-gst-pipeline-debug.dot'.

One can generate png image out of this dot file with the command:
  dot -Tpng -oimage.png spice-gtk-gst-pipeline-debug.dot

Not that GST_DEBUG_BIN_TO_DOT_FILE() will only work if Gstreamer was
configured with --gst-enable-gst-debug and the environment variable
GST_DEBUG_DUMP_DOT_DIR was properly set.

Full example:

1) GST_DEBUG_DUMP_DOT_DIR=/tmp remote-viewer ...
2) dot -Tpng -oimage.png spice-gtk-gst-pipeline-debug.dot

Signed-off-by: Victor Toso <victortoso at redhat.com>
---
 src/channel-display-gst.c  | 21 ++++++++++++++++++++-
 src/channel-display-priv.h |  1 +
 src/channel-display.c      | 17 +++++++++++++++++
 3 files changed, 38 insertions(+), 1 deletion(-)

diff --git a/src/channel-display-gst.c b/src/channel-display-gst.c
index acea4a2..ef63078 100644
--- a/src/channel-display-gst.c
+++ b/src/channel-display-gst.c
@@ -265,7 +265,8 @@ static gboolean handle_pipeline_message(GstBus *bus, GstMessage *msg, gpointer v
 {
     SpiceGstDecoder *decoder = video_decoder;
 
-    if (GST_MESSAGE_TYPE(msg) == GST_MESSAGE_ERROR) {
+    switch(GST_MESSAGE_TYPE(msg)) {
+    case GST_MESSAGE_ERROR: {
         GError *err = NULL;
         gchar *debug_info = NULL;
         gst_message_parse_error(msg, &err, &debug_info);
@@ -279,6 +280,24 @@ static gboolean handle_pipeline_message(GstBus *bus, GstMessage *msg, gpointer v
 
         /* We won't be able to process any more frame anyway */
         free_pipeline(decoder);
+        break;
+    }
+    case GST_MESSAGE_STREAM_START: {
+        gchar *filename = g_strdup_printf("spice-gtk-gst-pipeline-debug-%ld-%s",
+                                          get_stream_id_by_stream(decoder->base.stream->channel,
+                                                                  decoder->base.stream),
+                                          gst_opts[decoder->base.codec_type].name);
+        GST_DEBUG_BIN_TO_DOT_FILE(GST_BIN(decoder->pipeline),
+                                  GST_DEBUG_GRAPH_SHOW_ALL
+                                    | GST_DEBUG_GRAPH_SHOW_FULL_PARAMS
+                                    | GST_DEBUG_GRAPH_SHOW_STATES,
+                                    filename);
+        g_free(filename);
+        break;
+    }
+    default:
+        /* not being handled */
+        break;
     }
     return TRUE;
 }
diff --git a/src/channel-display-priv.h b/src/channel-display-priv.h
index 00f71f8..407145f 100644
--- a/src/channel-display-priv.h
+++ b/src/channel-display-priv.h
@@ -196,6 +196,7 @@ G_STATIC_ASSERT(G_N_ELEMENTS(gst_opts) <= SPICE_VIDEO_CODEC_TYPE_ENUM_END);
 guint32 stream_get_time(display_stream *st);
 void stream_dropped_frame_on_playback(display_stream *st);
 void stream_display_frame(display_stream *st, SpiceFrame *frame, uint32_t width, uint32_t height, uint8_t* data);
+gint64 get_stream_id_by_stream(SpiceChannel *channel, display_stream *st);
 
 
 G_END_DECLS
diff --git a/src/channel-display.c b/src/channel-display.c
index e51064a..f226988 100644
--- a/src/channel-display.c
+++ b/src/channel-display.c
@@ -1164,6 +1164,23 @@ static display_stream *get_stream_by_id(SpiceChannel *channel, uint32_t id)
     return NULL;
 }
 
+G_GNUC_INTERNAL
+gint64 get_stream_id_by_stream(SpiceChannel *channel, display_stream *st)
+{
+    SpiceDisplayChannelPrivate *c = SPICE_DISPLAY_CHANNEL(channel)->priv;
+    guint i;
+
+    g_return_val_if_fail(c->streams != NULL, -1);
+    g_return_val_if_fail(c->nstreams != 0, -1);
+
+    for (i = 0; i < c->nstreams; i++) {
+        if (c->streams[i] == st)
+            return i;
+    }
+
+    return -1;
+}
+
 /* coroutine context */
 static display_stream *display_stream_create(SpiceChannel *channel, uint32_t surface_id,
                                              uint32_t flags, uint32_t codec_type,
-- 
2.13.0



More information about the Spice-devel mailing list