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");
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);
{
GstFileSrc *src;
GstBuffer *buf = NULL, *map;
- size_t readsize;
+ size_t readsize, mapsize;
off_t readend,mapstart,mapend;
GstFileSrcRegion region;
int i;
/* calculate end pointers so we don't have to do so repeatedly later */
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 */
+ mapstart = GST_BUFFER_OFFSET (src->mapbuf);
+ 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) {
/* ('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;
/* 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;
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 {
/* subbuffer it */
buf = gst_buffer_create_sub (src->mapbuf, src->curoffset - nextmap, readsize);
+ GST_BUFFER_OFFSET (buf) = mapstart + src->curoffset - nextmap;
}
}
}
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;
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;
}
/**
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;
}
/**
*
* 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.
*/
{
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);
/* 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);
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;
}
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)) {
/* 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) {
+ 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);
}
- /* if the offset is 0, the new buffer has the same timestamp as buf1 */
- if (offset == 0)
- GST_BUFFER_TIMESTAMP (newbuf) = GST_BUFFER_TIMESTAMP (buf1);
return newbuf;
}
#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,
/* 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) */
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);
/* 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);
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");
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);
{
GstFileSrc *src;
GstBuffer *buf = NULL, *map;
- size_t readsize;
+ size_t readsize, mapsize;
off_t readend,mapstart,mapend;
GstFileSrcRegion region;
int i;
/* calculate end pointers so we don't have to do so repeatedly later */
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 */
+ mapstart = GST_BUFFER_OFFSET (src->mapbuf);
+ 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) {
/* ('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;
/* 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;
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 {
/* subbuffer it */
buf = gst_buffer_create_sub (src->mapbuf, src->curoffset - nextmap, readsize);
+ GST_BUFFER_OFFSET (buf) = mapstart + src->curoffset - nextmap;
}
}
}