[Spice-devel] [spice-gtk] gstreamer: Take into account stride information

Frediano Ziglio fziglio at redhat.com
Tue Jul 25 14:31:11 UTC 2017


Using hardware encoders/decoders is possible that the output
stride of the image cannot be computed with a fixed formula
(width * 4). GStreamer in this case should set GstVideoMeta
information with the correct stride value.
Consider this value if present.
This fix a problem using NvDec encoder and Intel decoder.

Signed-off-by: Frediano Ziglio <fziglio at redhat.com>
---
 src/channel-display-gst.c   | 9 ++++++++-
 src/channel-display-mjpeg.c | 2 +-
 src/channel-display-priv.h  | 2 +-
 src/channel-display.c       | 6 ++++--
 4 files changed, 14 insertions(+), 5 deletions(-)

diff --git a/src/channel-display-gst.c b/src/channel-display-gst.c
index 03c6044..0abe706 100644
--- a/src/channel-display-gst.c
+++ b/src/channel-display-gst.c
@@ -26,6 +26,7 @@
 #include <gst/gst.h>
 #include <gst/app/gstappsrc.h>
 #include <gst/app/gstappsink.h>
+#include <gst/video/gstvideometa.h>
 
 
 /* GStreamer decoder implementation */
@@ -102,6 +103,12 @@ static void free_gst_frame(SpiceGstFrame *gstframe)
 
 static void schedule_frame(SpiceGstDecoder *decoder);
 
+static int gst_buffer_get_stride(GstBuffer *buffer)
+{
+    GstVideoMeta *video = gst_buffer_get_video_meta(buffer);
+    return video ? video->stride[0] : 0;
+}
+
 /* main context */
 static gboolean display_frame(gpointer video_decoder)
 {
@@ -145,7 +152,7 @@ static gboolean display_frame(gpointer video_decoder)
     }
 
     stream_display_frame(decoder->base.stream, gstframe->frame,
-                         width, height, mapinfo.data);
+                         width, height, gst_buffer_get_stride(buffer), mapinfo.data);
     gst_buffer_unmap(buffer, &mapinfo);
 
  error:
diff --git a/src/channel-display-mjpeg.c b/src/channel-display-mjpeg.c
index 3ba098c..6082511 100644
--- a/src/channel-display-mjpeg.c
+++ b/src/channel-display-mjpeg.c
@@ -176,7 +176,7 @@ static gboolean mjpeg_decoder_decode_frame(gpointer video_decoder)
 
     /* Display the frame and dispose of it */
     stream_display_frame(decoder->base.stream, decoder->cur_frame,
-                         width, height, decoder->out_frame);
+                         width, height, 0, decoder->out_frame);
     free_spice_frame(decoder->cur_frame);
     decoder->cur_frame = NULL;
     decoder->timer_id = 0;
diff --git a/src/channel-display-priv.h b/src/channel-display-priv.h
index 04cb4d1..72e0840 100644
--- a/src/channel-display-priv.h
+++ b/src/channel-display-priv.h
@@ -192,7 +192,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);
+void stream_display_frame(display_stream *st, SpiceFrame *frame, uint32_t width, uint32_t height, int stride, uint8_t* data);
 gint64 get_stream_id_by_stream(SpiceChannel *channel, display_stream *st);
 
 
diff --git a/src/channel-display.c b/src/channel-display.c
index 06ed18a..4eb665f 100644
--- a/src/channel-display.c
+++ b/src/channel-display.c
@@ -1312,9 +1312,11 @@ void stream_dropped_frame_on_playback(display_stream *st)
 /* main context */
 G_GNUC_INTERNAL
 void stream_display_frame(display_stream *st, SpiceFrame *frame,
-                          uint32_t width, uint32_t height, uint8_t *data)
+                          uint32_t width, uint32_t height, int stride, uint8_t *data)
 {
-    int stride = width * sizeof(uint32_t);
+    if (stride == 0) {
+        stride = width * sizeof(uint32_t);
+    }
     if (!(st->flags & SPICE_STREAM_FLAGS_TOP_DOWN)) {
         data += stride * (height - 1);
         stride = -stride;
-- 
2.13.3



More information about the Spice-devel mailing list