bufferpool: only release buffers with writable memory
authorWim Taymans <wtaymans@redhat.com>
Thu, 27 Feb 2014 15:40:34 +0000 (16:40 +0100)
committerWim Taymans <wtaymans@redhat.com>
Thu, 27 Feb 2014 15:40:34 +0000 (16:40 +0100)
Check if the memory is writable before releasing the buffer into the
pool again.
Add unit test for this scenario.

gst/gstbufferpool.c
tests/check/gst/gstbufferpool.c

index 0f03753..0c28337 100644 (file)
@@ -1135,12 +1135,24 @@ default_release_buffer (GstBufferPool * pool, GstBuffer * buffer)
   GST_LOG_OBJECT (pool, "released buffer %p %d", buffer,
       GST_MINI_OBJECT_FLAGS (buffer));
 
-  if (GST_BUFFER_FLAG_IS_SET (buffer, GST_BUFFER_FLAG_TAG_MEMORY)) {
-    /* keep it around in our queue */
-    gst_atomic_queue_push (pool->priv->queue, buffer);
-    gst_poll_write_control (pool->priv->poll);
-  } else {
+  /* memory should be untouched */
+  if (!GST_BUFFER_FLAG_IS_SET (buffer, GST_BUFFER_FLAG_TAG_MEMORY))
+    goto discard;
+
+  /* all memory should be exclusive to this buffer (and thus be writable) */
+  if (!gst_buffer_is_all_memory_writable (buffer))
+    goto discard;
+
+  /* keep it around in our queue */
+  gst_atomic_queue_push (pool->priv->queue, buffer);
+  gst_poll_write_control (pool->priv->poll);
+
+  return;
+
+discard:
+  {
     do_free_buffer (pool, buffer);
+    return;
   }
 }
 
index fd201b4..b60f9da 100644 (file)
@@ -157,9 +157,15 @@ GST_START_TEST (test_buffer_modify_discard)
   gst_buffer_pool_acquire_buffer (pool, &buf, NULL);
   fail_unless (buf == prev, "got a fresh buffer instead of previous");
   mem = gst_buffer_get_memory (buf, 0);
-
+  /* exclusive lock so pool should not reuse this buffer */
+  gst_memory_lock (mem, GST_LOCK_FLAG_EXCLUSIVE);
   gst_buffer_unref (buf);
+  gst_memory_unlock (mem, GST_LOCK_FLAG_EXCLUSIVE);
+  gst_memory_unref (mem);
 
+  gst_buffer_pool_acquire_buffer (pool, &buf, NULL);
+  fail_if (buf == prev, "got a reused buffer instead of new one");
+  gst_buffer_unref (buf);
   gst_buffer_pool_set_active (pool, FALSE);
   gst_object_unref (pool);
 }