[Spice-devel] [PATCH spice 10/12] server: Add GStreamer 1.0 support.
Fabio Fantoni
fantonifabio at tiscali.it
Thu Jun 11 07:02:50 PDT 2015
Il 10/06/2015 17:38, Francois Gouget ha scritto:
> Signed-off-by: Francois Gouget <fgouget at codeweavers.com>
> ---
>
> This adds GStreamer 1.0 support!
>
> By default GStreamer 1.0 is used if available, otherwise GStreamer 0.10
> is used and Spice is compiled without GStreamer support as a last
> resort. It's possible to explicitly require a specific Gstreamer version
> with --enable-gstreamer=1.0 and --enable-gstreamer=0.10, or for any
> version with --enable-gstreamer=yes.
>
> If you get an error while building the pipeline for MJPEG, then it
> probably means you need the fix for this bug:
> https://bugzilla.gnome.org/show_bug.cgi?id=750398
Probably another change in configure is needed to avoid this:
> /bin/bash ../../libtool --tag=CC --mode=link gcc -std=gnu99 -g -O2
> -fstack-protector --param=ssp-buffer-size=4 -Wformat
> -Werror=format-security -Wl,-z,relro -lm -o test_display_no_ssl
> basic_event_loop.o test_display_base.o test_display_no_ssl.o
> ../../spice-common/common/libspice-common.la
> ../../server/libspice-server.la -lglib-2.0
> libtool: link: gcc -std=gnu99 -g -O2 -fstack-protector
> --param=ssp-buffer-size=4 -Wformat -Werror=format-security -Wl,-z
> -Wl,relro -o .libs/test_display_no_ssl basic_event_loop.o
> test_display_base.o test_display_no_ssl.o
> ../../spice-common/common/.libs/libspice-common.a -lm -lpixman-1
> -lopus ../../server/.libs/libspice-server.so -lglib-2.0 -pthread
> ../../server/.libs/libspice-server.so: undefined reference to
> `g_get_num_processors'
toso in spice chat told that was added in glib 2.36....check pkg-config
--modversion glib-2.0 (this should probably bump the configure version
for glib tho)
>
>
> configure.ac | 35 +++++++++++++++++----
> server/Makefile.am | 12 ++++++--
> server/gstreamer_encoder.c | 77 ++++++++++++++++++++++++++++++++++++++++------
> server/red_dispatcher.c | 2 +-
> 4 files changed, 108 insertions(+), 18 deletions(-)
>
> diff --git a/configure.ac b/configure.ac
> index 34e1a4a..3fc46f9 100644
> --- a/configure.ac
> +++ b/configure.ac
> @@ -92,14 +92,32 @@ if test "x$enable_smartcard" = "xyes"; then
> fi
>
> AC_ARG_ENABLE(gstreamer,
> - AS_HELP_STRING([--enable-gstreamer=@<:@auto/yes/no@:>@],
> - [Enable GStreamer 0.10 support]),
> + AS_HELP_STRING([--enable-gstreamer=@<:@auto/0.10/1.0/yes/no@:>@],
> + [Enable GStreamer support]),
> [],
> [enable_gstreamer="auto"])
>
> -if test "x$enable_gstreamer" != "xno"; then
> +if test "x$enable_gstreamer" != "xno" && test "x$enable_gstreamer" != "x0.10"; then
> + PKG_CHECK_MODULES(GSTREAMER_1_0, [gstreamer-1.0, gstreamer-app-1.0],
> + [enable_gstreamer="1.0"
> + have_gstreamer_1_0="yes"],
> + [have_gstreamer_1_0="no"])
> + if test "x$have_gstreamer_1_0" = "xyes"; then
> + AC_SUBST(GSTREAMER_1_0_CFLAGS)
> + AC_SUBST(GSTREAMER_1_0_LIBS)
> + AS_VAR_APPEND([SPICE_REQUIRES], [" gstreamer-1.0 gstreamer-app-1.0"])
> + AC_DEFINE([HAVE_GSTREAMER_1_0], [1], [Define if supporting GStreamer 1.0])
> + elif test "x$enable_gstreamer" = "x1.0"; then
> + AC_MSG_ERROR([GStreamer 1.0 support requested but not found. You may set GSTREAMER_1_0_CFLAGS and GSTREAMER_1_0_LIBS to avoid the need to call pkg-config.])
> + fi
> +else
> + have_gstreamer_1_0="no"
> +fi
> +AM_CONDITIONAL(SUPPORT_GSTREAMER_1_0, test "x$have_gstreamer_1_0" = "xyes")
> +
> +if test "x$enable_gstreamer" != "xno" && test "x$enable_gstreamer" != "x1.0"; then
> PKG_CHECK_MODULES(GSTREAMER_0_10, [gstreamer-0.10, gstreamer-app-0.10],
> - [enable_gstreamer="yes"
> + [enable_gstreamer="0.10"
> have_gstreamer_0_10="yes"],
> [have_gstreamer_0_10="no"])
> if test "x$have_gstreamer_0_10" = "xyes"; then
> @@ -107,7 +125,7 @@ if test "x$enable_gstreamer" != "xno"; then
> AC_SUBST(GSTREAMER_0_10_LIBS)
> AS_VAR_APPEND([SPICE_REQUIRES], [" gstreamer-0.10 gstreamer-app-0.10"])
> AC_DEFINE([HAVE_GSTREAMER_0_10], [1], [Define if supporting GStreamer 0.10])
> - elif test "x$enable_gstreamer" = "xyes"; then
> + elif test "x$enable_gstreamer" = "x0.10"; then
> AC_MSG_ERROR([GStreamer 0.10 support requested but not found. You may set GSTREAMER_0_10_CFLAGS and GSTREAMER_0_10_LIBS to avoid the need to call pkg-config.])
> fi
> else
> @@ -115,6 +133,11 @@ else
> fi
> AM_CONDITIONAL(SUPPORT_GSTREAMER_0_10, test "x$have_gstreamer_0_10" = "xyes")
>
> +if test "x$enable_gstreamer" = "xyes"; then
> + AC_MSG_ERROR("GStreamer support requested but not found")
> +fi
> +AS_IF([test "x$enable_gstreamer" = "xauto"], [enable_gstreamer="no"])
> +
> AC_ARG_ENABLE(automated_tests,
> [ --enable-automated-tests Enable automated tests using spicy-screenshot (part of spice--gtk)],,
> [enable_automated_tests="no"])
> @@ -382,7 +405,7 @@ echo "
>
> Smartcard: ${enable_smartcard}
>
> - GStreamer 0.10: ${have_gstreamer_0_10}
> + GStreamer: ${enable_gstreamer}
>
> SASL support: ${enable_sasl}
>
> diff --git a/server/Makefile.am b/server/Makefile.am
> index 4921bc3..9fb0c8e 100644
> --- a/server/Makefile.am
> +++ b/server/Makefile.am
> @@ -12,6 +12,7 @@ AM_CPPFLAGS = \
> $(SLIRP_CFLAGS) \
> $(SMARTCARD_CFLAGS) \
> $(GSTREAMER_0_10_CFLAGS) \
> + $(GSTREAMER_1_0_CFLAGS) \
> $(SSL_CFLAGS) \
> $(VISIBILITY_HIDDEN_CFLAGS) \
> $(WARN_CFLAGS) \
> @@ -42,7 +43,8 @@ libspice_server_la_LIBADD = \
> $(PIXMAN_LIBS) \
> $(SASL_LIBS) \
> $(SLIRP_LIBS) \
> - $(GSTREAMER_0_10_LIBS) \
> + $(GSTREAMER_0_10_LIBS) \
> + $(GSTREAMER_1_0_LIBS) \
> $(SSL_LIBS) \
> $(Z_LIBS) \
> $(SPICE_NONPKGCONFIG_LIBS) \
> @@ -142,7 +144,13 @@ endif
>
> if SUPPORT_GSTREAMER_0_10
> libspice_server_la_SOURCES += \
> - gstreamer_encoder.c \
> + gstreamer_encoder.c \
> + $(NULL)
> +endif
> +
> +if SUPPORT_GSTREAMER_1_0
> +libspice_server_la_SOURCES += \
> + gstreamer_encoder.c \
> $(NULL)
> endif
>
> diff --git a/server/gstreamer_encoder.c b/server/gstreamer_encoder.c
> index e7c9a56..97e6e13 100644
> --- a/server/gstreamer_encoder.c
> +++ b/server/gstreamer_encoder.c
> @@ -152,7 +152,13 @@ static void adjust_bit_rate(GstEncoder *encoder)
>
> static gboolean set_appsrc_caps(GstEncoder *encoder)
> {
> - GstCaps *new_caps = gst_caps_new_simple("video/x-raw-rgb",
> + GstCaps *new_caps = gst_caps_new_simple(
> +#ifdef HAVE_GSTREAMER_0_10
> + "video/x-raw-rgb",
> +#else
> + "video/x-raw",
> + "format", G_TYPE_STRING, "BGRx",
> +#endif
> "bpp", G_TYPE_INT, encoder->format->bpp,
> "depth", G_TYPE_INT, encoder->format->depth,
> "width", G_TYPE_INT, encoder->width,
> @@ -183,8 +189,12 @@ static gboolean construct_pipeline(GstEncoder *encoder, const SpiceBitmap *bitma
> switch (encoder->base.codec_type)
> {
> case SPICE_VIDEO_CODEC_TYPE_MJPEG:
> +#ifdef HAVE_GSTREAMER_0_10
> gstenc_name = "ffenc_mjpeg";
> no_clock = TRUE;
> +#else
> + gstenc_name = "avenc_mjpeg";
> +#endif
> break;
> case SPICE_VIDEO_CODEC_TYPE_VP8:
> gstenc_name = "vp8enc";
> @@ -193,9 +203,14 @@ static gboolean construct_pipeline(GstEncoder *encoder, const SpiceBitmap *bitma
> spice_warning("unsupported codec type %d", encoder->base.codec_type);
> return FALSE;
> }
> +#ifdef HAVE_GSTREAMER_0_10
> + const gchar *converter = "ffmpegcolorspace";
> +#else
> + const gchar *converter = "videoconvert";
> +#endif
>
> GError *err = NULL;
> - gchar *desc = g_strdup_printf("appsrc name=src format=2 do-timestamp=true ! ffmpegcolorspace ! %s name=encoder ! appsink name=sink", gstenc_name);
> + gchar *desc = g_strdup_printf("appsrc name=src format=2 do-timestamp=true ! %s ! %s name=encoder ! appsink name=sink", converter, gstenc_name);
> spice_debug("GStreamer pipeline: %s", desc);
> encoder->pipeline = gst_parse_launch_full(desc, NULL, GST_PARSE_FLAG_FATAL_ERRORS, &err);
> g_free(desc);
> @@ -210,16 +225,34 @@ static gboolean construct_pipeline(GstEncoder *encoder, const SpiceBitmap *bitma
>
> /* Set the encoder initial bit rate, and ask for a low latency */
> adjust_bit_rate(encoder);
> - g_object_set(G_OBJECT(encoder->gstenc), "bitrate", encoder->bit_rate, NULL);
> - if (encoder->base.codec_type == SPICE_VIDEO_CODEC_TYPE_VP8) {
> + switch (encoder->base.codec_type) {
> + case SPICE_VIDEO_CODEC_TYPE_MJPEG:
> + g_object_set(G_OBJECT(encoder->gstenc),
> + "bitrate", encoder->bit_rate,
> + NULL);
> + break;
> + case SPICE_VIDEO_CODEC_TYPE_VP8:
> /* See http://www.webmproject.org/docs/encoder-parameters/ */
> g_object_set(G_OBJECT(encoder->gstenc),
> +#ifdef HAVE_GSTREAMER_0_10
> "mode", 1, /* CBR */
> + "bitrate", encoder->bit_rate,
> "max-latency", 0,
> "speed", 7,
> +#else
> + "end-usage", 1, /* CBR */
> + "target-bitrate", encoder->bit_rate,
> + "lag-in-frames", 0,
> + "deadline", GST_SECOND / get_source_fps(encoder) / 2,
> +#endif
> "resize-allowed", TRUE,
> "threads", g_get_num_processors() - 1,
> NULL);
> + break;
> + default:
> + spice_warning("unknown encoder type %d", encoder->base.codec_type);
> + reset_pipeline(encoder);
> + return FALSE;
> }
>
> /* Set the source caps */
> @@ -263,7 +296,14 @@ static int push_raw_frame(GstEncoder *encoder, const SpiceBitmap *bitmap,
> const uint32_t stream_stride = (src->right - src->left) * encoder->format->bpp / 8;
> uint32_t len = stream_stride * stream_height;
> GstBuffer *buffer = gst_buffer_new_and_alloc(len);
> - uint8_t *dst = GST_BUFFER_DATA(buffer);
> +#ifdef HAVE_GSTREAMER_0_10
> + uint8_t *b = GST_BUFFER_DATA(buffer);
> +#else
> + GstMapInfo map;
> + gst_buffer_map(buffer, &map, GST_MAP_WRITE);
> + uint8_t *b = map.data;
> +#endif
> + uint8_t *dst = b;
>
> /* Note that we should not reorder the lines, even if top_down is false.
> * It just changes the number of lines to skip at the start of the bitmap.
> @@ -322,10 +362,13 @@ static int push_raw_frame(GstEncoder *encoder, const SpiceBitmap *bitmap,
> dst += stream_stride;
> chunk_offset += bitmap->stride;
> }
> - spice_assert(dst - GST_BUFFER_DATA(buffer) == len);
> + spice_assert(dst - b == len);
> }
> -
> +#ifdef HAVE_GSTREAMER_0_10
> gst_buffer_set_caps(buffer, encoder->src_caps);
> +#else
> + gst_buffer_unmap(buffer, &map);
> +#endif
> GST_BUFFER_OFFSET(buffer) = encoder->frame++;
>
> GstFlowReturn ret = gst_app_src_push_buffer(encoder->appsrc, buffer);
> @@ -341,17 +384,33 @@ static int pull_compressed_buffer(GstEncoder *encoder,
> uint8_t **outbuf, size_t *outbuf_size,
> int *data_size)
> {
> - GstBuffer *buffer = gst_app_sink_pull_buffer(encoder->appsink);
> + GstBuffer *buffer;
> +
> +#ifdef HAVE_GSTREAMER_0_10
> + buffer = gst_app_sink_pull_buffer(encoder->appsink);
> +#else
> + GstSample *sample = gst_app_sink_pull_sample(encoder->appsink);
> + buffer = gst_sample_get_buffer(sample);
> +#endif
> if (buffer) {
> +#ifdef HAVE_GSTREAMER_0_10
> int len = GST_BUFFER_SIZE(buffer);
> +#else
> + int len = gst_buffer_get_size(buffer);
> +#endif
> spice_assert(outbuf && outbuf_size);
> if (!*outbuf || *outbuf_size < len) {
> *outbuf = spice_realloc(*outbuf, len);
> *outbuf_size = len;
> }
> /* TODO Try to avoid this copy by changing the GstBuffer handling */
> - memcpy(*outbuf, GST_BUFFER_DATA(buffer), len);
> +#ifdef HAVE_GSTREAMER_0_10
> + memcpy(*outbuf, GST_BUFFER_DATA(buffer), len);
> gst_buffer_unref(buffer);
> +#else
> + gst_buffer_extract(buffer, 0, *outbuf, len);
> + gst_sample_unref(sample);
> +#endif
> *data_size = len;
> return VIDEO_ENCODER_FRAME_ENCODE_DONE;
> }
> diff --git a/server/red_dispatcher.c b/server/red_dispatcher.c
> index 4330f2e..08623e2 100644
> --- a/server/red_dispatcher.c
> +++ b/server/red_dispatcher.c
> @@ -257,7 +257,7 @@ static const EnumNames video_encoder_names[] = {
>
> static create_video_encoder_proc video_encoder_procs[] = {
> &create_mjpeg_encoder,
> -#ifdef HAVE_GSTREAMER_0_10
> +#if defined(HAVE_GSTREAMER_0_10) || defined(HAVE_GSTREAMER_1_0)
> &create_gstreamer_encoder,
> #else
> NULL,
-------------- next part --------------
A non-text attachment was scrubbed...
Name: smime.p7s
Type: application/pkcs7-signature
Size: 4297 bytes
Desc: Firma crittografica S/MIME
URL: <http://lists.freedesktop.org/archives/spice-devel/attachments/20150611/a0fb7f86/attachment.bin>
More information about the Spice-devel
mailing list