- First attempt at implementing #113180, this one also removes automatic (byte) offset calculations in the subbuffer ...

Original commit message from CVS:
- First attempt at implementing #113180, this one also removes
automatic (byte) offset calculations in the subbuffer code and moves
that logic to bytestream and filesrc. It will also update the offset
and duration fields in some special cases.
This commit is contained in:
Wim Taymans 2003-05-24 10:09:39 +00:00
parent c4e27d225a
commit 6ab1630c40
7 changed files with 107 additions and 53 deletions

View file

@ -291,9 +291,14 @@ gst_fakesink_chain (GstPad *pad, GstBuffer *buf)
if (!fakesink->silent) {
g_free (fakesink->last_message);
fakesink->last_message = g_strdup_printf ("chain ******* (%s:%s)< (%d bytes, %"
G_GINT64_FORMAT ", %d) %p",
GST_DEBUG_PAD_NAME (pad), GST_BUFFER_SIZE (buf), GST_BUFFER_TIMESTAMP (buf),
fakesink->last_message = g_strdup_printf ("chain ******* (%s:%s)< (%d bytes, timestamp: %"
G_GINT64_FORMAT ", duration: %"
G_GINT64_FORMAT ", offset: %"
G_GINT64_FORMAT ", flags: %d) %p",
GST_DEBUG_PAD_NAME (pad), GST_BUFFER_SIZE (buf),
GST_BUFFER_TIMESTAMP (buf),
GST_BUFFER_DURATION (buf),
GST_BUFFER_OFFSET (buf),
GST_BUFFER_FLAGS (buf), buf);
g_object_notify (G_OBJECT (fakesink), "last_message");

View file

@ -450,6 +450,7 @@ gst_filesrc_map_small_region (GstFileSrc *src, off_t offset, size_t size)
return NULL;
ret = gst_buffer_create_sub (map, offset - mapbase, size);
GST_BUFFER_OFFSET (ret) = GST_BUFFER_OFFSET (map) + offset - mapbase;
gst_buffer_unref (map);
@ -489,7 +490,7 @@ gst_filesrc_get (GstPad *pad)
{
GstFileSrc *src;
GstBuffer *buf = NULL, *map;
size_t readsize;
size_t readsize, mapsize;
off_t readend,mapstart,mapend;
GstFileSrcRegion region;
int i;
@ -527,7 +528,8 @@ gst_filesrc_get (GstPad *pad)
readsize = src->block_size;
readend = src->curoffset + src->block_size; /* note this is the byte *after* the read */
mapstart = GST_BUFFER_OFFSET (src->mapbuf);
mapend = mapstart + GST_BUFFER_SIZE(src->mapbuf); /* note this is the byte *after* the map */
mapsize = GST_BUFFER_SIZE (src->mapbuf);
mapend = mapstart + mapsize; /* note this is the byte *after* the map */
/* check to see if we're going to overflow the end of the file */
if (readend > src->filelen) {
@ -545,14 +547,15 @@ gst_filesrc_get (GstPad *pad)
/* ('cause by definition if readend is in the buffer, so's readstart) */
if (readend <= mapend) {
fs_print ("read buf %llu+%d lives in current mapbuf %lld+%d, creating subbuffer of mapbuf\n",
src->curoffset, readsize, mapstart, GST_BUFFER_SIZE(src->mapbuf));
buf = gst_buffer_create_sub (src->mapbuf, src->curoffset - GST_BUFFER_OFFSET(src->mapbuf),
src->curoffset, readsize, mapstart, mapsize);
buf = gst_buffer_create_sub (src->mapbuf, src->curoffset - mapstart,
readsize);
GST_BUFFER_OFFSET (buf) = src->curoffset;
/* if the start actually is within the current mmap region, map an overlap buffer */
} else if (src->curoffset < mapend) {
fs_print ("read buf %llu+%d starts in mapbuf %d+%d but ends outside, creating new mmap\n",
src->curoffset,readsize,GST_BUFFER_OFFSET(src->mapbuf),GST_BUFFER_SIZE(src->mapbuf));
src->curoffset, readsize, mapstart, mapsize);
buf = gst_filesrc_map_small_region (src, src->curoffset, readsize);
if (buf == NULL)
return NULL;
@ -567,7 +570,7 @@ gst_filesrc_get (GstPad *pad)
/* or the read buffer fully contains the current mmap region */
/* either way, it's really not relevant, we just create a new region anyway*/
fs_print ("read buf %llu+%d starts before mapbuf %d+%d, but overlaps it\n",
src->curoffset,readsize,GST_BUFFER_OFFSET(src->mapbuf),GST_BUFFER_SIZE(src->mapbuf));
src->curoffset,readsize, mapstart, mapsize);
buf = gst_filesrc_map_small_region (src, src->curoffset, readsize);
if (buf == NULL)
return NULL;
@ -587,6 +590,7 @@ gst_filesrc_get (GstPad *pad)
if (map != NULL) {
fs_print ("found mapbuf at %d+%d, creating subbuffer\n",GST_BUFFER_OFFSET(map),GST_BUFFER_SIZE(map));
buf = gst_buffer_create_sub (map, src->curoffset - GST_BUFFER_OFFSET(map), readsize);
GST_BUFFER_OFFSET (buf) = src->curoffset;
/* otherwise we need to create something out of thin air */
} else {
@ -621,6 +625,7 @@ gst_filesrc_get (GstPad *pad)
/* subbuffer it */
buf = gst_buffer_create_sub (src->mapbuf, src->curoffset - nextmap, readsize);
GST_BUFFER_OFFSET (buf) = mapstart + src->curoffset - nextmap;
}
}
}

View file

@ -165,8 +165,9 @@ gst_buffer_default_copy (GstBuffer *buffer)
GST_BUFFER_DATA (copy) = g_memdup (GST_BUFFER_DATA (buffer),
GST_BUFFER_SIZE (buffer));
GST_BUFFER_SIZE (copy) = GST_BUFFER_SIZE (buffer);
GST_BUFFER_MAXSIZE (copy) = GST_BUFFER_MAXSIZE (buffer);
GST_BUFFER_MAXSIZE (copy) = GST_BUFFER_SIZE (buffer);
GST_BUFFER_TIMESTAMP (copy) = GST_BUFFER_TIMESTAMP (buffer);
GST_BUFFER_DURATION (copy) = GST_BUFFER_DURATION (buffer);
GST_BUFFER_OFFSET (copy) = GST_BUFFER_OFFSET (buffer);
GST_BUFFER_BUFFERPOOL (copy) = NULL;
GST_BUFFER_POOL_PRIVATE (copy) = NULL;
@ -184,30 +185,31 @@ gst_buffer_default_copy (GstBuffer *buffer)
GstBuffer*
gst_buffer_new (void)
{
GstBuffer *buf;
GstBuffer *newbuf;
buf = gst_mem_chunk_alloc (chunk);
newbuf = gst_mem_chunk_alloc (chunk);
#ifndef GST_DISABLE_TRACE
gst_alloc_trace_new (_gst_buffer_trace, buf);
gst_alloc_trace_new (_gst_buffer_trace, newbuf);
#endif
GST_DEBUG (GST_CAT_BUFFER, "new %p", buf);
GST_DEBUG (GST_CAT_BUFFER, "new %p", newbuf);
_GST_DATA_INIT (GST_DATA (buf),
_GST_DATA_INIT (GST_DATA (newbuf),
_gst_buffer_type,
0,
(GstDataFreeFunction) gst_buffer_default_free,
(GstDataCopyFunction) gst_buffer_default_copy);
GST_BUFFER_DATA (buf) = NULL;
GST_BUFFER_SIZE (buf) = 0;
GST_BUFFER_MAXSIZE (buf) = 0;
GST_BUFFER_TIMESTAMP (buf) = GST_CLOCK_TIME_NONE;
GST_BUFFER_OFFSET (buf) = 0;
GST_BUFFER_BUFFERPOOL (buf) = NULL;
GST_BUFFER_POOL_PRIVATE (buf) = NULL;
GST_BUFFER_DATA (newbuf) = NULL;
GST_BUFFER_SIZE (newbuf) = 0;
GST_BUFFER_MAXSIZE (newbuf) = GST_BUFFER_MAXSIZE_NONE;
GST_BUFFER_TIMESTAMP (newbuf) = GST_CLOCK_TIME_NONE;
GST_BUFFER_DURATION (newbuf) = GST_CLOCK_TIME_NONE;
GST_BUFFER_OFFSET (newbuf) = GST_BUFFER_OFFSET_NONE;
GST_BUFFER_BUFFERPOOL (newbuf) = NULL;
GST_BUFFER_POOL_PRIVATE (newbuf) = NULL;
return buf;
return newbuf;
}
/**
@ -221,14 +223,15 @@ gst_buffer_new (void)
GstBuffer*
gst_buffer_new_and_alloc (guint size)
{
GstBuffer *new;
GstBuffer *newbuf;
new = gst_buffer_new ();
newbuf = gst_buffer_new ();
GST_BUFFER_DATA (new) = g_malloc (size);
GST_BUFFER_SIZE (new) = size;
GST_BUFFER_DATA (newbuf) = g_malloc (size);
GST_BUFFER_SIZE (newbuf) = size;
GST_BUFFER_MAXSIZE (newbuf) = size;
return new;
return newbuf;
}
/**
@ -275,6 +278,9 @@ gst_buffer_new_from_pool (GstBufferPool *pool,
*
* Creates a sub-buffer from the parent at a given offset.
* This sub-buffer uses the actual memory space of the parent buffer.
* This function will copy the offset and timestamp field when the
* offset is 0, else they are set to _NONE.
* The duration field of the new buffer are set to GST_CLOCK_TIME_NONE.
*
* Returns: the new #GstBuffer, or NULL if there was an error.
*/
@ -283,7 +289,6 @@ gst_buffer_create_sub (GstBuffer *parent, guint offset, guint size)
{
GstBuffer *buffer;
gpointer buffer_data;
guint64 parent_offset;
g_return_val_if_fail (parent != NULL, NULL);
g_return_val_if_fail (GST_BUFFER_REFCOUNT_VALUE (parent) > 0, NULL);
@ -292,7 +297,6 @@ gst_buffer_create_sub (GstBuffer *parent, guint offset, guint size)
/* remember the data for the new buffer */
buffer_data = parent->data + offset;
parent_offset = GST_BUFFER_OFFSET (parent);
/* make sure we're child not child from a child buffer */
while (GST_BUFFER_FLAG_IS_SET (parent, GST_BUFFER_SUBBUFFER)) {
parent = GST_BUFFER (parent->pool_private);
@ -323,10 +327,20 @@ gst_buffer_create_sub (GstBuffer *parent, guint offset, guint size)
GST_BUFFER_DATA (buffer) = buffer_data;
GST_BUFFER_SIZE (buffer) = size;
GST_BUFFER_MAXSIZE (buffer) = size;
GST_BUFFER_TIMESTAMP (buffer) = GST_CLOCK_TIME_NONE;
GST_BUFFER_OFFSET (buffer) = parent_offset + offset;
GST_BUFFER_BUFFERPOOL (buffer) = NULL;
GST_BUFFER_POOL_PRIVATE (buffer) = parent;
/* we can copy the timestamp and offset if the new buffer starts at
* offset 0 */
if (offset == 0) {
GST_BUFFER_TIMESTAMP (buffer) = GST_BUFFER_TIMESTAMP (parent);
GST_BUFFER_OFFSET (buffer) = GST_BUFFER_OFFSET (parent);
}
else {
GST_BUFFER_TIMESTAMP (buffer) = GST_CLOCK_TIME_NONE;
GST_BUFFER_OFFSET (buffer) = GST_BUFFER_OFFSET_NONE;
}
GST_BUFFER_DURATION (buffer) = GST_CLOCK_TIME_NONE;
return buffer;
}
@ -411,6 +425,7 @@ gst_buffer_span (GstBuffer *buf1, guint32 offset, GstBuffer *buf2, guint32 len)
g_return_val_if_fail (GST_BUFFER_REFCOUNT_VALUE (buf1) > 0, NULL);
g_return_val_if_fail (GST_BUFFER_REFCOUNT_VALUE (buf2) > 0, NULL);
g_return_val_if_fail (len > 0, NULL);
g_return_val_if_fail (len <= buf1->size + buf2->size - offset, NULL);
/* if the two buffers have the same parent and are adjacent */
if (gst_buffer_is_span_fast (buf1, buf2)) {
@ -425,18 +440,24 @@ gst_buffer_span (GstBuffer *buf1, guint32 offset, GstBuffer *buf2, guint32 len)
/* otherwise we simply have to brute-force copy the buffers */
newbuf = gst_buffer_new_and_alloc (len);
/* copy relevant stuff from data struct of buffer1 */
GST_BUFFER_OFFSET (newbuf) = GST_BUFFER_OFFSET (buf1) + offset;
/* copy the first buffer's data across */
memcpy (newbuf->data, buf1->data + offset, buf1->size - offset);
/* copy the second buffer's data across */
memcpy (newbuf->data + (buf1->size - offset), buf2->data,
len - (buf1->size - offset));
}
/* if the offset is 0, the new buffer has the same timestamp as buf1 */
if (offset == 0)
if (offset == 0) {
GST_BUFFER_OFFSET (newbuf) = GST_BUFFER_OFFSET (buf1);
GST_BUFFER_TIMESTAMP (newbuf) = GST_BUFFER_TIMESTAMP (buf1);
}
}
/* if we completely merged the two buffers (appended), we can
* calculate the duration too */
if (offset == 0 && buf1->size + buf2->size == len) {
/* add duration */
GST_BUFFER_DURATION (newbuf) = GST_BUFFER_DURATION (buf1) +
GST_BUFFER_DURATION (buf2);
}
return newbuf;
}

View file

@ -60,12 +60,18 @@ extern GType _gst_buffer_pool_type;
#define GST_BUFFER_SIZE(buf) (GST_BUFFER(buf)->size)
#define GST_BUFFER_MAXSIZE(buf) (GST_BUFFER(buf)->maxsize)
#define GST_BUFFER_TIMESTAMP(buf) (GST_BUFFER(buf)->timestamp)
#define GST_BUFFER_DURATION(buf) (GST_BUFFER(buf)->duration)
#define GST_BUFFER_FORMAT(buf) (GST_BUFFER(buf)->format)
#define GST_BUFFER_OFFSET(buf) (GST_BUFFER(buf)->offset)
#define GST_BUFFER_BUFFERPOOL(buf) (GST_BUFFER(buf)->pool)
#define GST_BUFFER_POOL_PRIVATE(buf) (GST_BUFFER(buf)->pool_private)
#define GST_BUFFER_OFFSET_NONE ((guint64)-1)
#define GST_BUFFER_MAXSIZE_NONE ((guint)0)
#define GST_BUFFER_TIMESTAMP_IS_VALID(buffer) (GST_CLOCK_TIME_IS_VALID (GST_BUFFER_TIMESTAMP (buffer)))
#define GST_BUFFER_OFFSET_IS_VALID(buffer) (GST_BUFFER_OFFSET (buffer) != GST_BUFFER_OFFSET_NONE)
#define GST_BUFFER_MAXSIZE_IS_VALID(buffer) (GST_BUFFER_MAXSIZE (buffer) != GST_BUFFER_MAXSIZE_NONE)
typedef enum {
GST_BUFFER_READONLY = GST_DATA_READONLY,
@ -84,11 +90,17 @@ struct _GstBuffer {
/* pointer to data and its size */
guint8 *data; /* pointer to buffer data */
guint size; /* size of buffer data */
guint64 maxsize; /* max size of this buffer */
guint maxsize; /* max size of this buffer */
/* timestamp */
GstClockTime timestamp;
/* media specific offset */
GstClockTime duration;
/* media specific offset
* for video frames, this could be the number of frames,
* for audio data, this could be the number of audio samples,
* for file data or compressed data, this could be the number of bytes
*/
guint64 offset;
/* this is a pointer to the buffer pool (if any) */

View file

@ -299,9 +299,10 @@ gst_bytestream_peek (GstByteStream *bs, GstBuffer **buf, guint32 len)
bs_print ("peek: there are enough bytes in headbuf (need %d, have %d)", len, bs->headbufavail);
/* create a sub-buffer of the headbuf */
retbuf = gst_buffer_create_sub (headbuf, GST_BUFFER_SIZE (headbuf) - bs->headbufavail, len);
GST_BUFFER_OFFSET (retbuf) = GST_BUFFER_OFFSET (headbuf) + GST_BUFFER_SIZE (headbuf) - bs->headbufavail;
/* otherwise we need to figure out how to assemble one */
}
/* otherwise we need to figure out how to assemble one */
else {
bs_print ("peek: current buffer is not big enough for len %d", len);
@ -380,8 +381,8 @@ gst_bytestream_peek_bytes (GstByteStream *bs, guint8** data, guint32 len)
/* create a sub-buffer of the headbuf */
*data = GST_BUFFER_DATA (headbuf) + (GST_BUFFER_SIZE (headbuf) - bs->headbufavail);
/* otherwise we need to figure out how to assemble one */
}
/* otherwise we need to figure out how to assemble one */
else {
bs_print ("peek_bytes: current buffer is not big enough for len %d", len);

View file

@ -291,9 +291,14 @@ gst_fakesink_chain (GstPad *pad, GstBuffer *buf)
if (!fakesink->silent) {
g_free (fakesink->last_message);
fakesink->last_message = g_strdup_printf ("chain ******* (%s:%s)< (%d bytes, %"
G_GINT64_FORMAT ", %d) %p",
GST_DEBUG_PAD_NAME (pad), GST_BUFFER_SIZE (buf), GST_BUFFER_TIMESTAMP (buf),
fakesink->last_message = g_strdup_printf ("chain ******* (%s:%s)< (%d bytes, timestamp: %"
G_GINT64_FORMAT ", duration: %"
G_GINT64_FORMAT ", offset: %"
G_GINT64_FORMAT ", flags: %d) %p",
GST_DEBUG_PAD_NAME (pad), GST_BUFFER_SIZE (buf),
GST_BUFFER_TIMESTAMP (buf),
GST_BUFFER_DURATION (buf),
GST_BUFFER_OFFSET (buf),
GST_BUFFER_FLAGS (buf), buf);
g_object_notify (G_OBJECT (fakesink), "last_message");

View file

@ -450,6 +450,7 @@ gst_filesrc_map_small_region (GstFileSrc *src, off_t offset, size_t size)
return NULL;
ret = gst_buffer_create_sub (map, offset - mapbase, size);
GST_BUFFER_OFFSET (ret) = GST_BUFFER_OFFSET (map) + offset - mapbase;
gst_buffer_unref (map);
@ -489,7 +490,7 @@ gst_filesrc_get (GstPad *pad)
{
GstFileSrc *src;
GstBuffer *buf = NULL, *map;
size_t readsize;
size_t readsize, mapsize;
off_t readend,mapstart,mapend;
GstFileSrcRegion region;
int i;
@ -527,7 +528,8 @@ gst_filesrc_get (GstPad *pad)
readsize = src->block_size;
readend = src->curoffset + src->block_size; /* note this is the byte *after* the read */
mapstart = GST_BUFFER_OFFSET (src->mapbuf);
mapend = mapstart + GST_BUFFER_SIZE(src->mapbuf); /* note this is the byte *after* the map */
mapsize = GST_BUFFER_SIZE (src->mapbuf);
mapend = mapstart + mapsize; /* note this is the byte *after* the map */
/* check to see if we're going to overflow the end of the file */
if (readend > src->filelen) {
@ -545,14 +547,15 @@ gst_filesrc_get (GstPad *pad)
/* ('cause by definition if readend is in the buffer, so's readstart) */
if (readend <= mapend) {
fs_print ("read buf %llu+%d lives in current mapbuf %lld+%d, creating subbuffer of mapbuf\n",
src->curoffset, readsize, mapstart, GST_BUFFER_SIZE(src->mapbuf));
buf = gst_buffer_create_sub (src->mapbuf, src->curoffset - GST_BUFFER_OFFSET(src->mapbuf),
src->curoffset, readsize, mapstart, mapsize);
buf = gst_buffer_create_sub (src->mapbuf, src->curoffset - mapstart,
readsize);
GST_BUFFER_OFFSET (buf) = src->curoffset;
/* if the start actually is within the current mmap region, map an overlap buffer */
} else if (src->curoffset < mapend) {
fs_print ("read buf %llu+%d starts in mapbuf %d+%d but ends outside, creating new mmap\n",
src->curoffset,readsize,GST_BUFFER_OFFSET(src->mapbuf),GST_BUFFER_SIZE(src->mapbuf));
src->curoffset, readsize, mapstart, mapsize);
buf = gst_filesrc_map_small_region (src, src->curoffset, readsize);
if (buf == NULL)
return NULL;
@ -567,7 +570,7 @@ gst_filesrc_get (GstPad *pad)
/* or the read buffer fully contains the current mmap region */
/* either way, it's really not relevant, we just create a new region anyway*/
fs_print ("read buf %llu+%d starts before mapbuf %d+%d, but overlaps it\n",
src->curoffset,readsize,GST_BUFFER_OFFSET(src->mapbuf),GST_BUFFER_SIZE(src->mapbuf));
src->curoffset,readsize, mapstart, mapsize);
buf = gst_filesrc_map_small_region (src, src->curoffset, readsize);
if (buf == NULL)
return NULL;
@ -587,6 +590,7 @@ gst_filesrc_get (GstPad *pad)
if (map != NULL) {
fs_print ("found mapbuf at %d+%d, creating subbuffer\n",GST_BUFFER_OFFSET(map),GST_BUFFER_SIZE(map));
buf = gst_buffer_create_sub (map, src->curoffset - GST_BUFFER_OFFSET(map), readsize);
GST_BUFFER_OFFSET (buf) = src->curoffset;
/* otherwise we need to create something out of thin air */
} else {
@ -621,6 +625,7 @@ gst_filesrc_get (GstPad *pad)
/* subbuffer it */
buf = gst_buffer_create_sub (src->mapbuf, src->curoffset - nextmap, readsize);
GST_BUFFER_OFFSET (buf) = mapstart + src->curoffset - nextmap;
}
}
}