[Spice-devel] [PATCH][spice-gtk] Add GStreamer 1.0 support

Alon Levy alon at pobox.com
Thu Oct 30 09:49:18 PDT 2014


On 10/30/2014 06:39 PM, vtosodec at redhat.com wrote:
> From: Christophe Fergeau <cfergeau at redhat.com>
> 
> This commit adds GStreamer 1.0 support.
> To enable GStreamer 1.0: --with-audio=gstreamer1

commit first line should say audio somewhere.

> 
> There is only a few changes between those versions, worth mentioning:
> - audio capabilities "audio/x-raw,format=..." instead of
>   "audio/x-raw-int,..."
> - appsink signal for new data changed from "new-buffer" to "new-sample"
> ---
>  configure.ac         | 17 +++++++++++---
>  gtk/spice-audio.c    |  4 ++--
>  gtk/spice-gstaudio.c | 64 +++++++++++++++++++++++++++++++++++++++++++++++++++-
>  3 files changed, 79 insertions(+), 6 deletions(-)
> 
> diff --git a/configure.ac b/configure.ac
> index 0d65823..17680e6 100644
> --- a/configure.ac
> +++ b/configure.ac
> @@ -288,7 +288,7 @@ AS_IF([test "x$have_phodav" = "xyes"],
>         AC_DEFINE(USE_PHODAV, [1], [Define if supporting phodav]))
>  
>  AC_ARG_WITH([audio],
> -  AS_HELP_STRING([--with-audio=@<:@gstreamer/pulse/auto/no@:>@], [Select audio backend @<:@default=auto@:>@]),
> +  AS_HELP_STRING([--with-audio=@<:@gstreamer/gstreamer1/pulse/auto/no@:>@], [Select audio backend @<:@default=auto@:>@]),
>    [],
>    [with_audio="auto"])
>  
> @@ -297,7 +297,7 @@ AS_IF([test "x$with_audio" = "xauto"], [
>  ])
>  
>  case "$with_audio" in
> -  gstreamer|pulse|no*)
> +  gstreamer|gstreamer1|pulse|no*)
>      ;;
>    *) AC_MSG_ERROR(Unsupported audio backend)
>  esac
> @@ -326,7 +326,18 @@ AS_IF([test "x$have_gst" = "xyes"],
>               [AC_MSG_ERROR([GStreamer requested but not found])
>        ])
>  ])
> -AM_CONDITIONAL([WITH_GSTAUDIO], [test "x$have_gst" = "xyes"])
> +
> +AS_IF([test "x$with_audio" = "xgstreamer1"],
> +      [PKG_CHECK_MODULES(GST, gstreamer-1.0 gstreamer-base-1.0 gstreamer-app-1.0 gstreamer-audio-1.0, [have_gst1=yes], [have_gst1=no])],
> +      [have_gst1=no])
> +
> +AS_IF([test "x$have_gst1" = "xyes"],
> +      [AC_DEFINE([WITH_GST1AUDIO], 1, [Have GStreamer 1.0?])],
> +      [AS_IF([test "x$with_audio" = "xgstreamer1"],
> +             [AC_MSG_ERROR([GStreamer 1.0 requested but not found])
> +      ])
> +])
> +AM_CONDITIONAL([WITH_GSTAUDIO], [test "x$have_gst" = "xyes" -o "x$have_gst1" = "xyes"])
>  AC_SUBST(GST_CFLAGS)
>  AC_SUBST(GST_LIBS)
>  
> diff --git a/gtk/spice-audio.c b/gtk/spice-audio.c
> index dbd3a8b..34c1b69 100644
> --- a/gtk/spice-audio.c
> +++ b/gtk/spice-audio.c
> @@ -47,7 +47,7 @@
>  #ifdef WITH_PULSE
>  #include "spice-pulse.h"
>  #endif
> -#ifdef WITH_GSTAUDIO
> +#if defined(WITH_GSTAUDIO) || defined(WITH_GST1AUDIO)
>  #include "spice-gstaudio.h"
>  #endif
>  
> @@ -219,7 +219,7 @@ SpiceAudio *spice_audio_new(SpiceSession *session, GMainContext *context,
>  #ifdef WITH_PULSE
>      self = SPICE_AUDIO(spice_pulse_new(session, context, name));
>  #endif
> -#ifdef WITH_GSTAUDIO
> +#if defined(WITH_GSTAUDIO) || defined(WITH_GST1AUDIO)
>      self = SPICE_AUDIO(spice_gstaudio_new(session, context, name));
>  #endif
>      if (!self)
> diff --git a/gtk/spice-gstaudio.c b/gtk/spice-gstaudio.c
> index faa0c74..d3c091a 100644
> --- a/gtk/spice-gstaudio.c
> +++ b/gtk/spice-gstaudio.c
> @@ -21,9 +21,13 @@
>  
>  #include <gst/gst.h>
>  #include <gst/app/gstappsrc.h>
> -#include <gst/app/gstappbuffer.h>
>  #include <gst/app/gstappsink.h>
> +#ifdef WITH_GST1AUDIO
> +#include <gst/audio/streamvolume.h>
> +#else
> +#include <gst/app/gstappbuffer.h>
>  #include <gst/interfaces/streamvolume.h>
> +#endif
>  
>  #include "spice-gstaudio.h"
>  #include "spice-common.h"
> @@ -133,7 +137,12 @@ static void record_new_buffer(GstAppSink *appsink, gpointer data)
>  
>      g_return_if_fail(p != NULL);
>  
> +#ifdef WITH_GST1AUDIO
> +    msg = gst_message_new_application(GST_OBJECT(p->record.pipe),
> +                                      gst_structure_new_empty ("new-sample"));
> +#else
>      msg = gst_message_new_application(GST_OBJECT(p->record.pipe), NULL);
> +#endif
>      gst_element_post_message(p->record.pipe, msg);
>  }
>  
> @@ -155,6 +164,38 @@ static gboolean record_bus_cb(GstBus *bus, GstMessage *msg, gpointer data)
>      g_return_val_if_fail(p != NULL, FALSE);
>  
>      switch (GST_MESSAGE_TYPE(msg)) {
> +#ifdef WITH_GST1AUDIO
> +    case GST_MESSAGE_APPLICATION: {
> +        GstSample *s;
> +        GstBuffer *buffer;
> +        GstMapInfo mapping;
> +
> +        s = gst_app_sink_pull_sample(GST_APP_SINK(p->record.sink));
> +        if (!s) {
> +            if (!gst_app_sink_is_eos(GST_APP_SINK(p->record.sink)))
> +                g_warning("eos not reached, but can't pull new sample");
> +            return TRUE;
> +        }
> +
> +        buffer = gst_sample_get_buffer(s);
> +        if (!buffer) {
> +            if (!gst_app_sink_is_eos(GST_APP_SINK(p->record.sink)))
> +                g_warning("eos not reached, but can't pull new buffer");
> +            return TRUE;
> +        }
> +        if (!gst_buffer_map(buffer, &mapping, GST_MAP_READ)) {
> +            return TRUE;
> +        }
> +
> +        spice_record_send_data(SPICE_RECORD_CHANNEL(p->rchannel),
> +                               /* FIXME: server side doesn't care about ts?
> +                                  what is the unit? ms apparently */
> +                               mapping.data, mapping.size, 0);
> +        gst_buffer_unmap(buffer, &mapping);
> +        gst_sample_unref(s);
> +        break;
> +    }
> +#else
>      case GST_MESSAGE_APPLICATION: {
>          GstBuffer *b;
>  
> @@ -171,6 +212,7 @@ static gboolean record_bus_cb(GstBus *bus, GstMessage *msg, gpointer data)
>                                 GST_BUFFER_DATA(b), GST_BUFFER_SIZE(b), 0);
>          break;
>      }
> +#endif
>      default:
>          break;
>      }
> @@ -198,9 +240,15 @@ static void record_start(SpiceRecordChannel *channel, gint format, gint channels
>      if (!p->record.pipe) {
>          GError *error = NULL;
>          GstBus *bus;
> +#ifdef WITH_GST1AUDIO
> +        gchar *audio_caps =
> +            g_strdup_printf("audio/x-raw,format=\"S16LE\",channels=%d,rate=%d,"
> +                            "layout=interleaved", channels, frequency);
> +#else
>          gchar *audio_caps =
>              g_strdup_printf("audio/x-raw-int,channels=%d,rate=%d,signed=(boolean)true,"
>                              "width=16,depth=16,endianness=1234", channels, frequency);
> +#endif
>          gchar *pipeline =
>              g_strdup_printf("autoaudiosrc name=audiosrc ! queue ! audioconvert ! audioresample ! "
>                              "appsink caps=\"%s\" name=appsink", audio_caps);
> @@ -221,8 +269,13 @@ static void record_start(SpiceRecordChannel *channel, gint format, gint channels
>          p->record.channels = channels;
>  
>          gst_app_sink_set_emit_signals(GST_APP_SINK(p->record.sink), TRUE);
> +#ifdef WITH_GST1AUDIO
> +        spice_g_signal_connect_object(p->record.sink, "new-sample",
> +                                      G_CALLBACK(record_new_buffer), gstaudio, 0);
> +#else
>          spice_g_signal_connect_object(p->record.sink, "new-buffer",
>                                        G_CALLBACK(record_new_buffer), gstaudio, 0);
> +#endif
>  
>  lerr:
>          g_clear_error(&error);
> @@ -313,8 +366,13 @@ static void playback_start(SpicePlaybackChannel *channel, gint format, gint chan
>      if (!p->playback.pipe) {
>          GError *error = NULL;
>          gchar *audio_caps =
> +#ifdef WITH_GST1AUDIO
> +            g_strdup_printf("audio/x-raw,format=\"S16LE\",channels=%d,rate=%d,"
> +                            "layout=interleaved", channels, frequency);
> +#else
>              g_strdup_printf("audio/x-raw-int,channels=%d,rate=%d,signed=(boolean)true,"
>                              "width=16,depth=16,endianness=1234", channels, frequency);
> +#endif
>          gchar *pipeline = g_strdup (g_getenv("SPICE_GST_AUDIOSINK"));
>          if (pipeline == NULL)
>              pipeline = g_strdup_printf("appsrc is-live=1 do-timestamp=0 caps=\"%s\" name=\"appsrc\" ! queue ! "
> @@ -356,7 +414,11 @@ static void playback_data(SpicePlaybackChannel *channel,
>      g_return_if_fail(p != NULL);
>  
>      audio = g_memdup(audio, size); /* TODO: try to avoid memory copy */
> +#ifdef WITH_GST1AUDIO
> +    buf = gst_buffer_new_wrapped(audio, size);
> +#else
>      buf = gst_app_buffer_new(audio, size, g_free, audio);
> +#endif
>      gst_app_src_push_buffer(GST_APP_SRC(p->playback.src), buf);
>  }
>  
> 



More information about the Spice-devel mailing list