--- src/Makefile.am | 2 ++ src/gst-plugin.cpp | 43 +++++++++++++++++++------------------------ 2 files changed, 21 insertions(+), 24 deletions(-) diff --git a/src/Makefile.am b/src/Makefile.am index 31b8af1..1de8f9a 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -98,6 +98,8 @@ gst_plugin_la_LIBADD = \ gst_plugin_la_SOURCES = \ gst-plugin.cpp \ + xlib-capture.cpp \ + xlib-capture.hpp \ $(NULL) gst_plugin_la_CPPFLAGS = \ diff --git a/src/gst-plugin.cpp b/src/gst-plugin.cpp index 70bc6c8..83a54d5 100644 --- a/src/gst-plugin.cpp +++ b/src/gst-plugin.cpp @@ -17,6 +17,7 @@ #define XLIB_CAPTURE 1 #if XLIB_CAPTURE #include <gst/app/gstappsrc.h> +#include "xlib-capture.hpp" #endif #include <spice-streaming-agent/plugin.hpp> @@ -71,6 +72,7 @@ private: Display *const dpy; #if XLIB_CAPTURE void xlib_capture(); + XlibCapture *xc; #endif GstElementUPtr pipeline, capture, sink; GstSampleUPtr sample; @@ -281,6 +283,7 @@ GstreamerFrameCapture::GstreamerFrameCapture(const GstreamerEncoderSettings &set if (!dpy) { throw std::runtime_error("Unable to initialize X11"); } + xc = new XlibCapture(dpy); pipeline_init(settings); } @@ -296,6 +299,7 @@ GstreamerFrameCapture::~GstreamerFrameCapture() { free_sample(); gst_element_set_state(pipeline.get(), GST_STATE_NULL); + delete xc; XCloseDisplay(dpy); } @@ -305,27 +309,23 @@ void GstreamerFrameCapture::Reset() } #if XLIB_CAPTURE -void free_ximage(gpointer data) +void free_ximg(gpointer data) { - XImage *image = (XImage*)data; - image->f.destroy_image(image); + delete (XImg *) data; } void GstreamerFrameCapture::xlib_capture() { - int screen = XDefaultScreen(dpy); - Window win = RootWindow(dpy, screen); - XWindowAttributes win_info; - XGetWindowAttributes(dpy, win, &win_info); + XImg *image = xc->capture(); + if (!image) { + throw std::runtime_error("Cannot capture from X"); + } /* Some encoders cannot handle odd resolution make sure it's even number of pixels */ - cur_width = win_info.width - win_info.width % 2; - cur_height = win_info.height - win_info.height % 2; - - if (cur_width != last_width || cur_height != last_height) { - last_width = cur_width; - last_height = cur_height; + if (image->new_resolution()) { + last_width = cur_width = image->width(); // TODO: drop? + last_height = cur_height = image->height(); is_first = true; gst_app_src_end_of_stream(GST_APP_SRC(capture.get())); @@ -333,24 +333,19 @@ void GstreamerFrameCapture::xlib_capture() gst_element_set_state(pipeline.get(), GST_STATE_PLAYING); } - XImage *image = XGetImage(dpy, win, 0, 0, - cur_width, cur_height, AllPlanes, ZPixmap); - if (!image) { - throw std::runtime_error("Cannot capture from X"); - } + GstBufferUPtr buf(gst_buffer_new_wrapped_full(GST_MEMORY_FLAG_PHYSICALLY_CONTIGUOUS, image->get_data(), + image->data_size(), 0, + image->data_size(), image, + free_ximg)); - GstBufferUPtr buf(gst_buffer_new_wrapped_full(GST_MEMORY_FLAG_PHYSICALLY_CONTIGUOUS, image->data, - image->height * image->bytes_per_line, 0, - image->height * image->bytes_per_line, image, - free_ximage)); if (!buf) { throw std::runtime_error("Failed to wrap image in gstreamer buffer"); } GstCapsUPtr caps(gst_caps_new_simple("video/x-raw", "format", G_TYPE_STRING, "BGRx", - "width", G_TYPE_INT, image->width, - "height", G_TYPE_INT, image->height, + "width", G_TYPE_INT, image->width(), + "height", G_TYPE_INT, image->height(), "framerate", GST_TYPE_FRACTION, settings.fps, 1, nullptr)); -- 2.21.0 _______________________________________________ Spice-devel mailing list Spice-devel@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/spice-devel