gst/gstbuffer.c: Copy duration/offset_end/caps when creating a subbuffer of the compl...
authorWim Taymans <wim.taymans@gmail.com>
Mon, 21 Aug 2006 09:30:04 +0000 (09:30 +0000)
committerWim Taymans <wim.taymans@gmail.com>
Mon, 21 Aug 2006 09:30:04 +0000 (09:30 +0000)
Original commit message from CVS:
* gst/gstbuffer.c: (gst_buffer_make_metadata_writable),
(gst_buffer_create_sub):
Copy duration/offset_end/caps when creating a subbuffer of the
complete parent.
Make the subbuffer read-only when we make the metadata writable for
now. Fixes #351768.
* tests/check/gst/gstbuffer.c: (GST_START_TEST):
Added check for metadata copy when creating subbuffers.

ChangeLog
gst/gstbuffer.c
tests/check/gst/gstbuffer.c

index 145d6be..dd7aef8 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,15 @@
+2006-08-21  Wim Taymans  <wim@fluendo.com>
+
+       * gst/gstbuffer.c: (gst_buffer_make_metadata_writable),
+       (gst_buffer_create_sub):
+       Copy duration/offset_end/caps when creating a subbuffer of the
+       complete parent.
+       Make the subbuffer read-only when we make the metadata writable for
+       now. Fixes #351768.
+
+       * tests/check/gst/gstbuffer.c: (GST_START_TEST):
+       Added check for metadata copy when creating subbuffers.
+
 2006-08-21  Edward Hervey  <edward@fluendo.com>
 
        * libs/gst/base/gstbasetransform.c:
index ff8c368..2602809 100644 (file)
@@ -368,7 +368,8 @@ gst_buffer_is_metadata_writable (GstBuffer * buf)
  * is solely owned by the caller, by creating a subbuffer of the original
  * buffer if necessary.
  * 
- * After calling this function, @buf should not be referenced anymore.
+ * After calling this function, @buf should not be referenced anymore. The
+ * result of this function has guaranteed writable metadata.
  *
  * Returns: A new #GstBuffer with writable metadata.
  */
@@ -381,8 +382,13 @@ gst_buffer_make_metadata_writable (GstBuffer * buf)
     ret = buf;
   } else {
     ret = gst_buffer_create_sub (buf, 0, GST_BUFFER_SIZE (buf));
+
+    /* copy all the flags except IN_CAPS */
     GST_BUFFER_FLAGS (ret) = GST_BUFFER_FLAGS (buf);
     GST_BUFFER_FLAG_UNSET (ret, GST_BUFFER_FLAG_IN_CAPS);
+    /* data should always be set to READONLY */
+    GST_BUFFER_FLAG_SET (ret, GST_BUFFER_FLAG_READONLY);
+
     gst_buffer_unref (buf);
   }
 
@@ -472,8 +478,11 @@ gst_subbuffer_init (GTypeInstance * instance, gpointer g_class)
  * Creates a sub-buffer from @parent at @offset and @size.
  * This sub-buffer uses the actual memory space of the parent buffer.
  * This function will copy the offset and timestamp fields when the
- * offset is 0, else they are set to #GST_CLOCK_TIME_NONE/#GST_BUFFER_OFFSET_NONE.
- * The duration field of the new buffer is set to #GST_CLOCK_TIME_NONE.
+ * offset is 0. If not, they will be set to #GST_CLOCK_TIME_NONE and 
+ * #GST_BUFFER_OFFSET_NONE.
+ * If @offset equals 0 and @size equals the total size of @buffer, the
+ * duration and offset end fields are also copied. If not they will be set
+ * to #GST_CLOCK_TIME_NONE and #GST_BUFFER_OFFSET_NONE.
  *
  * MT safe.
  * Returns: the new #GstBuffer.
@@ -484,6 +493,7 @@ gst_buffer_create_sub (GstBuffer * buffer, guint offset, guint size)
 {
   GstSubBuffer *subbuffer;
   GstBuffer *parent;
+  gboolean complete;
 
   g_return_val_if_fail (buffer != NULL, NULL);
   g_return_val_if_fail (buffer->mini_object.refcount > 0, NULL);
@@ -513,16 +523,28 @@ gst_buffer_create_sub (GstBuffer * buffer, guint offset, guint size)
   if (offset == 0) {
     GST_BUFFER_TIMESTAMP (subbuffer) = GST_BUFFER_TIMESTAMP (buffer);
     GST_BUFFER_OFFSET (subbuffer) = GST_BUFFER_OFFSET (buffer);
+    complete = (buffer->size == size);
   } else {
     GST_BUFFER_TIMESTAMP (subbuffer) = GST_CLOCK_TIME_NONE;
     GST_BUFFER_OFFSET (subbuffer) = GST_BUFFER_OFFSET_NONE;
+    complete = FALSE;
   }
 
-  GST_BUFFER_DURATION (subbuffer) = GST_CLOCK_TIME_NONE;
-  GST_BUFFER_OFFSET_END (subbuffer) = GST_BUFFER_OFFSET_NONE;
-
-  GST_BUFFER_CAPS (subbuffer) = NULL;
+  if (complete) {
+    GstCaps *caps;
 
+    /* if we copied the complete buffer we can copy the duration,
+     * offset_end and caps as well */
+    GST_BUFFER_DURATION (subbuffer) = GST_BUFFER_DURATION (buffer);
+    GST_BUFFER_OFFSET_END (subbuffer) = GST_BUFFER_OFFSET_END (buffer);
+    if ((caps = GST_BUFFER_CAPS (buffer)))
+      gst_caps_ref (caps);
+    GST_BUFFER_CAPS (subbuffer) = caps;
+  } else {
+    GST_BUFFER_DURATION (subbuffer) = GST_CLOCK_TIME_NONE;
+    GST_BUFFER_OFFSET_END (subbuffer) = GST_BUFFER_OFFSET_NONE;
+    GST_BUFFER_CAPS (subbuffer) = NULL;
+  }
   return GST_BUFFER_CAST (subbuffer);
 }
 
index 105d0d7..7be0c52 100644 (file)
@@ -72,6 +72,11 @@ GST_START_TEST (test_subbuffer)
 
   buffer = gst_buffer_new_and_alloc (4);
   memset (GST_BUFFER_DATA (buffer), 0, 4);
+  /* set some metadata */
+  GST_BUFFER_TIMESTAMP (buffer) = 1;
+  GST_BUFFER_DURATION (buffer) = 2;
+  GST_BUFFER_OFFSET (buffer) = 3;
+  GST_BUFFER_OFFSET_END (buffer) = 4;
 
   sub = gst_buffer_create_sub (buffer, 1, 2);
   fail_if (sub == NULL, "create_sub of buffer returned NULL");
@@ -80,7 +85,12 @@ GST_START_TEST (test_subbuffer)
           2) == 0, "subbuffer contains the wrong data");
   ASSERT_BUFFER_REFCOUNT (buffer, "parent", 2);
   ASSERT_BUFFER_REFCOUNT (sub, "subbuffer", 1);
-
+  fail_unless (GST_BUFFER_TIMESTAMP (sub) == -1,
+      "subbuffer has wrong timestamp");
+  fail_unless (GST_BUFFER_DURATION (sub) == -1, "subbuffer has wrong duration");
+  fail_unless (GST_BUFFER_OFFSET (sub) == -1, "subbuffer has wrong offset");
+  fail_unless (GST_BUFFER_OFFSET_END (sub) == -1,
+      "subbuffer has wrong offset end");
   gst_buffer_unref (sub);
 
   /* create a subbuffer of size 0 */
@@ -91,6 +101,32 @@ GST_START_TEST (test_subbuffer)
           0) == 0, "subbuffer contains the wrong data");
   ASSERT_BUFFER_REFCOUNT (buffer, "parent", 2);
   ASSERT_BUFFER_REFCOUNT (sub, "subbuffer", 1);
+  gst_buffer_unref (sub);
+
+  /* test if metadata is coppied, not a complete buffer copy so only the
+   * timestamp and offset fields are copied. */
+  sub = gst_buffer_create_sub (buffer, 0, 1);
+  fail_if (sub == NULL, "create_sub of buffer returned NULL");
+  fail_unless (GST_BUFFER_SIZE (sub) == 1, "subbuffer has wrong size");
+  fail_unless (GST_BUFFER_TIMESTAMP (sub) == 1,
+      "subbuffer has wrong timestamp");
+  fail_unless (GST_BUFFER_OFFSET (sub) == 3, "subbuffer has wrong offset");
+  fail_unless (GST_BUFFER_DURATION (sub) == -1, "subbuffer has wrong duration");
+  fail_unless (GST_BUFFER_OFFSET_END (sub) == -1,
+      "subbuffer has wrong offset end");
+  gst_buffer_unref (sub);
+
+  /* test if metadata is coppied, a complete buffer is copied so all the timing
+   * fields should be copied. */
+  sub = gst_buffer_create_sub (buffer, 0, 4);
+  fail_if (sub == NULL, "create_sub of buffer returned NULL");
+  fail_unless (GST_BUFFER_SIZE (sub) == 4, "subbuffer has wrong size");
+  fail_unless (GST_BUFFER_TIMESTAMP (sub) == 1,
+      "subbuffer has wrong timestamp");
+  fail_unless (GST_BUFFER_DURATION (sub) == 2, "subbuffer has wrong duration");
+  fail_unless (GST_BUFFER_OFFSET (sub) == 3, "subbuffer has wrong offset");
+  fail_unless (GST_BUFFER_OFFSET_END (sub) == 4,
+      "subbuffer has wrong offset end");
 
   /* clean up */
   gst_buffer_unref (sub);