> > This also fixes a memory leak of GstBuffer > > Signed-off-by: Snir Sheriber <ssheribe@xxxxxxxxxx> Acked > --- > Changes from v1: > -commit message > -Style > -- > src/gst-plugin.cpp | 36 +++++++++++++++++++++++------------- > 1 file changed, 23 insertions(+), 13 deletions(-) > > diff --git a/src/gst-plugin.cpp b/src/gst-plugin.cpp > index 0a1d041..4d17dbc 100644 > --- a/src/gst-plugin.cpp > +++ b/src/gst-plugin.cpp > @@ -67,6 +67,15 @@ struct GstSampleDeleter { > > using GstSampleUPtr = std::unique_ptr<GstSample, GstSampleDeleter>; > > +struct GstBufferDeleter { > + void operator()(GstBuffer* p) > + { > + gst_buffer_unref(p); > + } > +}; > + > +using GstBufferUPtr = std::unique_ptr<GstBuffer, GstBufferDeleter>; > + > class GstreamerFrameCapture final : public FrameCapture > { > public: > @@ -86,7 +95,6 @@ private: > Display *const dpy; > #if XLIB_CAPTURE > void xlib_capture(); > - XImage *image = nullptr; > #endif > GstObjectUPtr<GstElement> pipeline, capture, sink; > GstSampleUPtr sample; > @@ -306,12 +314,6 @@ void GstreamerFrameCapture::free_sample() > gst_buffer_unmap(gst_sample_get_buffer(sample.get()), &map); > sample.reset(); > } > -#if XLIB_CAPTURE > - if(image) { > - image->f.destroy_image(image); > - image = nullptr; > - } > -#endif > } > > GstreamerFrameCapture::~GstreamerFrameCapture() > @@ -327,6 +329,12 @@ void GstreamerFrameCapture::Reset() > } > > #if XLIB_CAPTURE > +void free_ximage(gpointer data) > +{ > + XImage *image = (XImage*)data; > + image->f.destroy_image(image); > +} > + > void GstreamerFrameCapture::xlib_capture() > { > int screen = XDefaultScreen(dpy); > @@ -349,14 +357,16 @@ void GstreamerFrameCapture::xlib_capture() > gst_element_set_state(pipeline.get(), GST_STATE_PLAYING); > } > > - image = XGetImage(dpy, win, 0, 0, > - cur_width, cur_height, AllPlanes, ZPixmap); > + XImage *image = XGetImage(dpy, win, 0, 0, > + cur_width, cur_height, AllPlanes, ZPixmap); > if (!image) { > throw std::runtime_error("Cannot capture from X"); > } > > - GstBuffer *buf; > - buf = gst_buffer_new_wrapped(image->data, image->height * > image->bytes_per_line); > + 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"); > } > @@ -368,8 +378,8 @@ void GstreamerFrameCapture::xlib_capture() > "framerate", GST_TYPE_FRACTION, > settings.fps, 1, > nullptr)); > > - // Push sample > - GstSampleUPtr appsrc_sample(gst_sample_new(buf, caps.get(), nullptr, > nullptr)); > + // Push sample (gst_app_src_push_sample does not take buffer ownership) > + GstSampleUPtr appsrc_sample(gst_sample_new(buf.get(), caps.get(), > nullptr, nullptr)); > if (gst_app_src_push_sample(GST_APP_SRC(capture.get()), > appsrc_sample.get()) != GST_FLOW_OK) { > throw std::runtime_error("gstramer appsrc element cannot push > sample"); > } _______________________________________________ Spice-devel mailing list Spice-devel@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/spice-devel