gst/gstbuffer.c: Copy duration/offset_end/caps when creating a subbuffer of the complete parent.

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.
This commit is contained in:
Wim Taymans 2006-08-21 09:30:04 +00:00
parent 4abd3fb116
commit 87a78cc03d
3 changed files with 78 additions and 8 deletions

View file

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

View 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);
}

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