[gst-devel] non-leaky bytestream
vishnu at pobox.com
vishnu at pobox.com
Fri Sep 28 17:48:03 CEST 2001
OK to commit?
--
Victory to the Divine Mother!!
http://sahajayoga.org
-------------- next part --------------
? bs
Index: gstbytestream.c
===================================================================
RCS file: /cvsroot/gstreamer/gstreamer/libs/bytestream/Attic/gstbytestream.c,v
retrieving revision 1.1.2.13
diff -u -p -r1.1.2.13 gstbytestream.c
--- gstbytestream.c 2001/09/28 22:58:38 1.1.2.13
+++ gstbytestream.c 2001/09/29 00:45:45
@@ -37,8 +37,28 @@
#endif
//static void gst_bytestream_print_status(GstByteStream *bs);
-guint8 *gst_bytestream_assemble (GstByteStream * bs, guint32 len);
+struct _GstByteStream {
+ GstPad *pad;
+
+ GSList *buflist;
+ guint32 listavail; // sum of bytes - flushed
+ guint32 flushed; // offset to first byte in first buffer
+};
+
+static inline GstBuffer *
+_headbuf (GstByteStream *bs)
+{
+ return GST_BUFFER (bs->buflist->data);
+}
+
+static inline guint32
+_headbufavail (GstByteStream *bs)
+{
+ g_return_val_if_fail (bs->buflist, 0);
+ return GST_BUFFER_SIZE (_headbuf(bs)) - bs->flushed;
+}
+
/**
* gst_bytestream_new:
* @pad: the pad to attach the bytestream to
@@ -55,7 +75,6 @@ gst_bytestream_new (GstPad * pad)
bs->pad = pad; // need to refcnt?
bs->buflist = NULL;
- bs->headbufavail = 0;
bs->listavail = 0;
return bs;
@@ -169,11 +188,6 @@ gst_bytestream_get_next_buf (GstByteStre
// add to the length of the list
bs->listavail += GST_BUFFER_SIZE (nextbuf);
- // have to check to see if we merged with the head buffer
- if (end == bs->buflist) {
- bs->headbufavail += GST_BUFFER_SIZE (nextbuf);
- }
-
gst_buffer_unref (lastbuf);
gst_buffer_unref (nextbuf);
@@ -194,8 +208,7 @@ gst_bytestream_get_next_buf (GstByteStre
bs->buflist = g_slist_append (bs->buflist, nextbuf);
// and increment the number of bytes in the list
bs->listavail = GST_BUFFER_SIZE (nextbuf);
- // set the head buffer avail to the size
- bs->headbufavail = GST_BUFFER_SIZE (nextbuf);
+ bs->flushed = 0;
}
return TRUE;
@@ -214,139 +227,118 @@ gst_bytestream_fill_bytes (GstByteStream
return TRUE;
}
-
-GstBuffer *
-gst_bytestream_peek_loc (GST_WHERE_ARGS_ GstByteStream * bs, guint32 len)
+static inline void
+gst_bytestream_assemble (GstByteStream * bs, guint32 len)
{
- GstBuffer *headbuf, *retbuf = NULL;
+ guint32 maxsize;
+ guint8 *data;
+ guint32 copied;
+ GstBuffer *headbuf;
+ GSList *elem;
+ gint64 timestamp;
- g_return_val_if_fail (bs != NULL, NULL);
- g_return_val_if_fail (len > 0, NULL);
+ g_assert (len <= bs->listavail);
+ g_assert (len > _headbufavail(bs));
- bs_print ("peek: asking for %d bytes\n", len);
+ maxsize = _headbufavail (bs);
+ elem = g_slist_next (bs->buflist);
+ while (maxsize < len) {
+ g_assert (elem);
- // make sure we have enough
- bs_print ("peek: there are %d bytes in the list\n", bs->listavail);
- if (len > bs->listavail) {
- if (!gst_bytestream_fill_bytes (bs, len))
- return NULL;
- bs_print ("peek: there are now %d bytes in the list\n", bs->listavail);
+ maxsize += GST_BUFFER_SIZE (elem->data);
+ elem = g_slist_next (elem);
}
- bs_status (bs);
- // extract the head buffer
- headbuf = GST_BUFFER (bs->buflist->data);
+ data = g_malloc (maxsize);
- // if the requested bytes are in the current buffer
- bs_print ("peek: headbufavail is %d\n", bs->headbufavail);
- if (len <= bs->headbufavail) {
- bs_print ("peek: there are enough bytes in headbuf (need %d, have %d)\n", len, bs->headbufavail);
- // create a sub-buffer of the headbuf
- retbuf = gst_buffer_create_sub_loc (GST_WHERE_VARS_ headbuf, GST_BUFFER_SIZE (headbuf) - bs->headbufavail, len);
+ headbuf = _headbuf (bs);
+ timestamp = GST_BUFFER_TIMESTAMP (headbuf);
+ copied = _headbufavail (bs);
+ memcpy (data, GST_BUFFER_DATA (headbuf) + bs->flushed, copied);
- // otherwise we need to figure out how to assemble one
- }
- else {
- bs_print ("peek: current buffer is not big enough for len %d\n", len);
+ bs->buflist = g_slist_delete_link (bs->buflist, bs->buflist);
+ gst_buffer_unref (headbuf);
- retbuf = gst_buffer_new_loc (GST_WHERE_VARS);
- GST_BUFFER_SIZE (retbuf) = len;
- GST_BUFFER_DATA (retbuf) = gst_bytestream_assemble (bs, len);
- if (GST_BUFFER_OFFSET (headbuf) != -1)
- GST_BUFFER_OFFSET (retbuf) = GST_BUFFER_OFFSET (headbuf) + (GST_BUFFER_SIZE (headbuf) - bs->headbufavail);
- }
+ // Assemble doesn't change listavail, but it does
+ // really flush out any bytes marked flushed.
+
+ bs->flushed = 0;
- return retbuf;
+ // enough buffers must exist in the list
+
+ while (copied < len) {
+ headbuf = GST_BUFFER (bs->buflist->data);
+ g_assert (headbuf);
+
+ bs_print ("assemble: copying %d bytes from buf to output offset %d\n", GST_BUFFER_SIZE (headbuf), copied);
+
+ memcpy (data + copied,
+ GST_BUFFER_DATA (headbuf),
+ GST_BUFFER_SIZE (headbuf));
+ copied += GST_BUFFER_SIZE (headbuf);
+
+ bs->buflist = g_slist_delete_link (bs->buflist, bs->buflist);
+ gst_buffer_unref (headbuf);
+ }
+
+ headbuf = gst_buffer_new ();
+ GST_BUFFER_DATA (headbuf) = data;
+ GST_BUFFER_SIZE (headbuf) = copied;
+ GST_BUFFER_MAXSIZE (headbuf) = maxsize;
+ GST_BUFFER_TIMESTAMP (headbuf) = timestamp;
+
+ bs->buflist = g_slist_prepend (bs->buflist, headbuf);
}
-guint8 *
-gst_bytestream_peek_bytes (GstByteStream * bs, guint32 len)
+static inline gboolean
+_gst_bytestream_peek (GstByteStream * bs, guint32 len)
{
- GstBuffer *headbuf;
- guint8 *data = NULL;
-
- g_return_val_if_fail (bs != NULL, NULL);
- g_return_val_if_fail (len > 0, NULL);
+ g_return_val_if_fail (bs != NULL, FALSE);
+ g_return_val_if_fail (len > 0, FALSE);
- bs_print ("peek_bytes: asking for %d bytes\n", len);
+ bs_print ("peek: asking for %d of %d bytes\n", len, bs->listavail);
// make sure we have enough
- bs_print ("peek_bytes: there are %d bytes in the list\n", bs->listavail);
if (len > bs->listavail) {
if (!gst_bytestream_fill_bytes (bs, len))
- return NULL;
- bs_print ("peek_bytes: there are now %d bytes in the list\n", bs->listavail);
+ return FALSE;
+ bs_print ("peek: there are now %d bytes in the list\n", bs->listavail);
}
bs_status (bs);
- // extract the head buffer
- headbuf = GST_BUFFER (bs->buflist->data);
+ if (len > _headbufavail (bs))
+ gst_bytestream_assemble (bs, len);
- // if the requested bytes are in the current buffer
- bs_print ("peek_bytes: headbufavail is %d\n", bs->headbufavail);
- if (len <= bs->headbufavail) {
- bs_print ("peek_bytes: there are enough bytes in headbuf (need %d, have %d)\n", len, bs->headbufavail);
- // create a sub-buffer of the headbuf
- data = GST_BUFFER_DATA (headbuf) + (GST_BUFFER_SIZE (headbuf) - bs->headbufavail);
+ g_assert (len <= _headbufavail (bs));
- // otherwise we need to figure out how to assemble one
- }
- else {
- bs_print ("peek_bytes: current buffer is not big enough for len %d\n", len);
+ return TRUE;
+}
- data = gst_bytestream_assemble (bs, len);
- }
+GstBuffer *
+gst_bytestream_peek_loc (GST_WHERE_ARGS_ GstByteStream * bs, guint32 len)
+{
+ if (!_gst_bytestream_peek (bs, len))
+ return NULL;
- return data;
+ return gst_buffer_create_sub_loc (GST_WHERE_VARS_
+ _headbuf(bs), bs->flushed, len);
}
guint8 *
-gst_bytestream_assemble (GstByteStream * bs, guint32 len)
+gst_bytestream_peek_bytes (GstByteStream * bs, guint32 len)
{
- guint8 *data = g_malloc (len);
- GSList *walk;
- guint32 copied = 0;
- GstBuffer *buf;
+ if (!_gst_bytestream_peek (bs, len))
+ return NULL;
- g_assert (len <= bs->listavail);
-
- // copy the data from the curbuf
- buf = GST_BUFFER (bs->buflist->data);
- bs_print ("assemble: copying %d bytes from curbuf at %d to *data\n", bs->headbufavail,
- GST_BUFFER_SIZE (buf) - bs->headbufavail);
- memcpy (data, GST_BUFFER_DATA (buf) + GST_BUFFER_SIZE (buf) - bs->headbufavail, bs->headbufavail);
- copied += bs->headbufavail;
-
- // asumption is made that the buffers all exist in the list
- walk = g_slist_next (bs->buflist);
- while (copied < len) {
- g_assert (walk);
-
- buf = GST_BUFFER (walk->data);
- if (GST_BUFFER_SIZE (buf) < (len - copied)) {
- bs_print ("assemble: copying %d bytes from buf to output offset %d\n", GST_BUFFER_SIZE (buf), copied);
- memcpy (data + copied, GST_BUFFER_DATA (buf), GST_BUFFER_SIZE (buf));
- copied += GST_BUFFER_SIZE (buf);
- }
- else {
- bs_print ("assemble: copying %d bytes from buf to output offset %d\n", len - copied, copied);
- memcpy (data + copied, GST_BUFFER_DATA (buf), len - copied);
- copied = len;
- }
- walk = g_slist_next (walk);
- }
-
- return data;
+ return GST_BUFFER_DATA (GST_BUFFER (bs->buflist->data)) + bs->flushed;
}
gboolean
gst_bytestream_flush (GstByteStream * bs, guint32 len)
{
- bs_print ("flush: flushing %d bytes\n", len);
+ bs_print ("flush: flushing %d of %d bytes\n", len, bs->listavail);
- // make sure we have enough
- bs_print ("flush: there are %d bytes in the list\n", bs->listavail);
if (len > bs->listavail) {
if (!gst_bytestream_fill_bytes (bs, len))
{
@@ -374,36 +366,28 @@ gst_bytestream_flush_fast (GstByteStream
bs_print ("flush: analyzing buffer that's %d bytes long, offset %d\n", GST_BUFFER_SIZE (headbuf),
GST_BUFFER_OFFSET (headbuf));
+
+ if (_headbufavail (bs) > len) {
+ // if there's enough to complete the flush
- // if there's enough to complete the flush
- if (bs->headbufavail > len) {
- // just trim it off
bs_print ("flush: trimming %d bytes off end of headbuf\n", len);
- bs->headbufavail -= len;
bs->listavail -= len;
- len = 0;
+ bs->flushed += len;
+ return;
+
+ } else {
// otherwise we have to trim the whole buffer
- }
- else {
+
bs_print ("flush: removing head buffer completely\n");
- // remove it from the list
+
+ bs->listavail -= _headbufavail (bs);
+ len -= _headbufavail (bs);
+
bs->buflist = g_slist_delete_link (bs->buflist, bs->buflist);
- // trim it from the avail size
- bs->listavail -= bs->headbufavail;
- // record that we've trimmed this many bytes
- len -= bs->headbufavail;
- // unref it
gst_buffer_unref (headbuf);
- // record the new headbufavail
- if (bs->buflist) {
- bs->headbufavail = GST_BUFFER_SIZE (GST_BUFFER (bs->buflist->data));
- bs_print ("flush: next headbuf is %d bytes\n", bs->headbufavail);
- }
- else {
- bs_print ("flush: no more bytes at all\n");
- }
+ bs->flushed = 0;
}
bs_print ("flush: bottom of while(), len is now %d\n", len);
@@ -425,7 +409,7 @@ gst_bytestream_print_status (GstByteStre
GSList *walk;
GstBuffer *buf;
- bs_print ("STATUS: head buffer has %d bytes available\n", bs->headbufavail);
+ bs_print ("STATUS: head buffer has %d bytes available\n", _headbufavail(bs));
bs_print ("STATUS: list has %d bytes available\n", bs->listavail);
walk = bs->buflist;
while (walk) {
Index: gstbytestream.h
===================================================================
RCS file: /cvsroot/gstreamer/gstreamer/libs/bytestream/Attic/gstbytestream.h,v
retrieving revision 1.1.2.8
diff -u -p -r1.1.2.8 gstbytestream.h
--- gstbytestream.h 2001/09/28 22:58:38 1.1.2.8
+++ gstbytestream.h 2001/09/29 00:45:45
@@ -28,14 +28,6 @@ extern "C" {
typedef struct _GstByteStream GstByteStream;
-struct _GstByteStream {
- GstPad *pad;
-
- GSList *buflist;
- guint32 headbufavail;
- guint32 listavail;
-};
-
GstByteStream* gst_bytestream_new (GstPad *pad);
void gst_bytestream_destroy (GstByteStream *bs);
More information about the gstreamer-devel
mailing list