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
This commit is contained in:
Nicolas Dufresne 2015-02-03 17:44:34 -05:00
parent e9c1d64895
commit bd5e9a5442
3 changed files with 30 additions and 14 deletions

View file

@ -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

View file

@ -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);

View file

@ -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;