[Spice-devel] [PATCH v6 06/26] server: Add a GStreamer 1.0 MJPEG video encoder and use it by default

Francois Gouget fgouget at codeweavers.com
Tue Nov 3 09:19:18 PST 2015


On Thu, 22 Oct 2015, Christophe Fergeau wrote:
[...]
> > +AC_ARG_ENABLE(gstreamer,
> > +              AS_HELP_STRING([--enable-gstreamer=@<:@auto/yes/no@:>@],
> > +                             [Enable GStreamer 1.0 support]),
> > +              [],
> > +              [enable_gstreamer="auto"])
> > +
> > +if test "x$enable_gstreamer" != "xno"; then
> > +    PKG_CHECK_MODULES(GSTREAMER_1_0, [gstreamer-1.0, gstreamer-app-1.0],
> > +                      [enable_gstreamer="yes"
> > +                       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" = "xyes"; 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")
> > +
> 
> Any chance this check can be moved to spice-common/common/spice-deps.m4
> and shared with spice-gtk? Or are they too different to make that
> practical?

There are relatively important differences between the Spice server 
(support for both GStreamer 1.0 and 0.10), and the Spice client 
(GStreamer 1.0 but for audio and video). Still I think I found some way 
to share most of the boilerplate. See the following patches:

* [common 02/11] build-sys: Add SPICE_CHECK_GSTREAMER()
  http://lists.freedesktop.org/archives/spice-devel/2015-November/023049.html

* [common 03/11] build-sys: Add SPICE_CHECK_GSTREAMER_ELEMENTS()
  http://lists.freedesktop.org/archives/spice-devel/2015-November/023050.html


> > +         /* Copy the line */
> > +         uint8_t *src = chunks->chunk[chunk_index].data + chunk_offset;
> > +         memcpy(dst, src, stream_stride);
> > +         dst += stream_stride;
> > +         chunk_offset += bitmap->stride;
> > +     }
> > +     spice_assert(dst - buffer == stream_stride * height);
> 
> Do we have to have this assert? Could it be g_warn_if_fail() or
> similar?

Eh! As I initially wrote the Spice server code uses spice_assert() 
rather than g_return_xxx() so this is following current practice. But it 
does seem current practice is currently changing from under my feet :-/


> > +    const uint32_t stream_stride = (src->right - src->left) * encoder->format->bpp / 8;
> > +    uint32_t len = stream_stride * height;
> > +    GstBuffer *buffer = gst_buffer_new_and_alloc(len);
> > +    GstMapInfo map;
> > +    gst_buffer_map(buffer, &map, GST_MAP_WRITE);
> > +    uint8_t *dst = map.data;
> > +
> > +    /* 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.
> > +     */
> > +    const uint32_t skip_lines = top_down ? src->top : bitmap->y - (src->bottom - 0);
> 
> - 0 ?

When top_down is false the height of the frame is (src->bottom - 0), so 
the first line to encode is bitmap->y - (src->bottom - 0). Sure it could 
be written as 'bitmap->y - src->bottom' but I'm not sure that would be 
clearer. In fact I don't see any way to make top_down==false clear.


> > +    GError *err = NULL;
> > +    if (!gst_init_check(NULL, NULL, &err)) {
> > +        spice_warning("GStreamer error: %s", err->message);
> > +        g_clear_error(&err);
> > +        return NULL;
> > +    }
> 
> This gst_init() call also does not need to be done every time
> gstreamer_encoder_new() is called, it can be just once.

Only the first call takes a bit of time to run (7ms). All following 
calls take less than 0.5ms (i.e. they showed up as 0ms in my traces). So 
I don't think we should worry about that.


> > +/* A helper for red_display_create_stream(). */
> > +static VideoEncoder* red_display_create_video_encoder(uint64_t starting_bit_rate,
> > +                                                      VideoEncoderRateControlCbs *cbs,
> > +                                                      void *cbs_opaque)
> > +{
> > +#ifdef HAVE_GSTREAMER_1_0
> > +    VideoEncoder* video_encoder = gstreamer_encoder_new(starting_bit_rate, cbs, cbs_opaque);
> > +    if (video_encoder) {
> > +        return video_encoder;
> > +    }
> > +#endif
> > +    /* Use the builtin MJPEG video encoder as a fallback */
> > +    return mjpeg_encoder_new(starting_bit_rate, cbs, cbs_opaque);
> > +}
> > +
> 
> I'd add a note to the commit log that this is currently not checking
> client's capabilities.

Actually the client capabilities patch comes later in the series so it 
would be a bit premature. Though given that they go to separate 
repositories order is a bit undefined obviously.


-- 
Francois Gouget <fgouget at codeweavers.com>              


More information about the Spice-devel mailing list