[Spice-devel] [PATCH spice 10/12] server: Add GStreamer 1.0 support. (take 3b)
Francois Gouget
fgouget at codeweavers.com
Thu Jun 11 15:26:11 PDT 2015
Signed-off-by: Francois Gouget <fgouget at codeweavers.com>
---
Updated so it applies after the new VP8 patch.
diff --git a/configure.ac b/configure.ac
index ed3a337..6a5ddb9 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"])
@@ -386,7 +409,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 8fa9071..0743879 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,8 +225,13 @@ 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/ */
#ifdef HAVE_G_GET_NUMPROCESSORS
int core_count = g_get_num_processors();
@@ -219,13 +239,27 @@ static gboolean construct_pipeline(GstEncoder *encoder, const SpiceBitmap *bitma
int core_count = 1;
#endif
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", core_count - 1,
NULL);
- }
+ break;
+ }
+ default:
+ spice_warning("unknown encoder type %d", encoder->base.codec_type);
+ reset_pipeline(encoder);
+ return FALSE;
+ }
/* Set the source caps */
encoder->src_caps = NULL;
@@ -268,7 +302,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.
@@ -327,10 +368,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);
@@ -346,17 +390,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,
--
2.1.4
More information about the Spice-devel
mailing list