From bd5e9a544229f6d1e0ee58dde1e24a2f7301f57e Mon Sep 17 00:00:00 2001 From: Nicolas Dufresne Date: Tue, 3 Feb 2015 17:44:34 -0500 Subject: [PATCH] ksvideosrc: Fix buffer handling The pseudo buffer pool code was using gst_buffer_is_writable() alone to try and figure-out if cached buffer could be reused. It needs to check for memory writability too. Also check map result and fix map flags. https://bugzilla.gnome.org/show_bug.cgi?id=734264 --- sys/winks/gstksvideodevice.c | 33 ++++++++++++++++++++++++--------- sys/winks/gstksvideodevice.h | 2 +- sys/winks/gstksvideosrc.c | 9 +++++---- 3 files changed, 30 insertions(+), 14 deletions(-) diff --git a/sys/winks/gstksvideodevice.c b/sys/winks/gstksvideodevice.c index 75940cb..95dec48 100644 --- a/sys/winks/gstksvideodevice.c +++ b/sys/winks/gstksvideodevice.c @@ -911,10 +911,12 @@ gst_ks_read_request_pick_buffer (GstKsVideoDevice * self, ReadRequest * req) gboolean buffer_found = FALSE; guint i; - buffer_found = gst_buffer_is_writable (req->buf); + buffer_found = gst_buffer_is_writable (req->buf) + && gst_buffer_is_all_memory_writable (req->buf); for (i = 0; !buffer_found && i < G_N_ELEMENTS (priv->spare_buffers); i++) { - if (gst_buffer_is_writable (priv->spare_buffers[i])) { + if (gst_buffer_is_writable (priv->spare_buffers[i]) + && gst_buffer_is_all_memory_writable (priv->spare_buffers[i])) { GstBuffer *hold; hold = req->buf; @@ -962,7 +964,9 @@ gst_ks_video_device_request_frame (GstKsVideoDevice * self, ReadRequest * req, params = &req->params; memset (params, 0, sizeof (KSSTREAM_READ_PARAMS)); - gst_buffer_map (req->buf, &info, GST_MAP_READ); + if (!gst_buffer_map (req->buf, &info, GST_MAP_WRITE)) + goto map_failed; + params->header.Size = sizeof (KSSTREAM_HEADER) + sizeof (KS_FRAME_INFO); params->header.PresentationTime.Numerator = 1; params->header.PresentationTime.Denominator = 1; @@ -993,6 +997,10 @@ error_ioctl: error_code, error_str); return FALSE; } +map_failed: + { + return FALSE; + } } GstFlowReturn @@ -1160,20 +1168,23 @@ error_get_result: } } -void -gst_ks_video_device_postprocess_frame (GstKsVideoDevice * self, - guint8 * buf, guint buf_size) +gboolean +gst_ks_video_device_postprocess_frame (GstKsVideoDevice * self, GstBuffer * buf) { GstKsVideoDevicePrivate *priv = GST_KS_VIDEO_DEVICE_GET_PRIVATE (self); /* If it's RGB we need to flip the image */ if (priv->rgb_swap_buf != NULL) { + GstMapInfo info; gint stride, line; guint8 *dst, *src; - stride = buf_size / priv->height; - dst = buf; - src = buf + buf_size - stride; + if (!gst_buffer_map (buf, &info, GST_MAP_READWRITE)) + return FALSE; + + stride = info.size / priv->height; + dst = info.data; + src = info.data + info.size - stride; for (line = 0; line < priv->height / 2; line++) { memcpy (priv->rgb_swap_buf, dst, stride); @@ -1184,7 +1195,11 @@ gst_ks_video_device_postprocess_frame (GstKsVideoDevice * self, dst += stride; src -= stride; } + + gst_buffer_unmap (buf, &info); } + + return TRUE; } void diff --git a/sys/winks/gstksvideodevice.h b/sys/winks/gstksvideodevice.h index d148f92..105b79d 100644 --- a/sys/winks/gstksvideodevice.h +++ b/sys/winks/gstksvideodevice.h @@ -77,7 +77,7 @@ GstClockTime gst_ks_video_device_get_duration (GstKsVideoDevice * self); gboolean gst_ks_video_device_get_latency (GstKsVideoDevice * self, GstClockTime * min_latency, GstClockTime * max_latency); GstFlowReturn gst_ks_video_device_read_frame (GstKsVideoDevice * self, GstBuffer ** buf, GstClockTime * presentation_time, gulong * error_code, gchar ** error_str); -void gst_ks_video_device_postprocess_frame (GstKsVideoDevice * self, guint8 * buf, guint buf_size); +gboolean gst_ks_video_device_postprocess_frame (GstKsVideoDevice * self, GstBuffer *buf); void gst_ks_video_device_cancel (GstKsVideoDevice * self); void gst_ks_video_device_cancel_stop (GstKsVideoDevice * self); diff --git a/sys/winks/gstksvideosrc.c b/sys/winks/gstksvideosrc.c index 2694ac7..cd61a99 100644 --- a/sys/winks/gstksvideosrc.c +++ b/sys/winks/gstksvideosrc.c @@ -950,7 +950,6 @@ gst_ks_video_src_create (GstPushSrc * pushsrc, GstBuffer ** buf) GstClockTime presentation_time; gulong error_code; gchar *error_str; - GstMapInfo info; g_assert (priv->device != NULL); @@ -987,9 +986,11 @@ gst_ks_video_src_create (GstPushSrc * pushsrc, GstBuffer ** buf) if (G_UNLIKELY (priv->do_stats)) gst_ks_video_src_update_statistics (self); - gst_buffer_map (*buf, &info, GST_MAP_WRITE); - gst_ks_video_device_postprocess_frame (priv->device, info.data, info.size); - gst_buffer_unmap (*buf, &info); + if (!gst_ks_video_device_postprocess_frame (priv->device, *buf)) { + GST_ELEMENT_ERROR (self, RESOURCE, FAILED, ("Postprocessing failed"), + ("Postprocessing failed")); + return GST_FLOW_ERROR; + } return GST_FLOW_OK; -- 2.7.4