diff --git a/libs/gst/bytestream/bytestream.c b/libs/gst/bytestream/bytestream.c index 24ac4aaa23..8ab81ffa6c 100644 --- a/libs/gst/bytestream/bytestream.c +++ b/libs/gst/bytestream/bytestream.c @@ -26,7 +26,7 @@ #include #include -//#define BS_DEBUG +/*#define BS_DEBUG */ #ifdef BS_DEBUG # define bs_print(format,args...) GST_DEBUG (GST_CAT_BUFFER, format, ## args) @@ -80,39 +80,41 @@ gst_bytestream_destroy (GstByteStream * bs) g_free (bs); } -// HOW THIS WORKS: -// -// The fundamental structure is a singly-linked list of buffers. The -// buffer on the front is the oldest, and thus the first to read data -// from. The number of bytes left to be read in this buffer is stored -// in bs->headbufavail. The number of bytes available in the entire -// list (including the head buffer) is in bs->listavail. -// -// When a request is made for data (peek), _fill_bytes is called with -// the number of bytes needed, but only if the listavail indicates -// that there aren't already enough. This calls _get_next_buf until -// the listavail is sufficient to satisfy the demand. -// -// _get_next_buf pulls a buffer from the pad the bytestream is attached -// to, and shoves it in the list. There are actually two things it can -// do. If there's already a buffer in the list, and the _is_span_fast() -// test returns true, it will merge it with that last buffer. Otherwise -// it will simply tack it onto the end of the list. -// -// The _peek itself first checks the simple case of the request fitting -// within the head buffer, and if so creates a subbuffer and returns. -// Otherwise, it creates a new buffer and allocates space for the request -// and calls _assemble to fill it. We know we have to copy because this -// case only happens when the _merge wasn't feasible during _get_next_buf. -// -// The _flush method repeatedly inspects the head buffer and flushes as -// much data from it as it needs to, up to the size of the buffer. If -// the flush decimates the buffer, it's stripped, unref'd, and removed. +/* HOW THIS WORKS: + * + * The fundamental structure is a singly-linked list of buffers. The + * buffer on the front is the oldest, and thus the first to read data + * from. The number of bytes left to be read in this buffer is stored + * in bs->headbufavail. The number of bytes available in the entire + * list (including the head buffer) is in bs->listavail. + * + * When a request is made for data (peek), _fill_bytes is called with + * the number of bytes needed, but only if the listavail indicates + * that there aren't already enough. This calls _get_next_buf until + * the listavail is sufficient to satisfy the demand. + * + * _get_next_buf pulls a buffer from the pad the bytestream is attached + * to, and shoves it in the list. There are actually two things it can + * do. If there's already a buffer in the list, and the _is_span_fast() + * test returns true, it will merge it with that last buffer. Otherwise + * it will simply tack it onto the end of the list. + * + * The _peek itself first checks the simple case of the request fitting + * within the head buffer, and if so creates a subbuffer and returns. + * Otherwise, it creates a new buffer and allocates space for the request + * and calls _assemble to fill it. We know we have to copy because this + * case only happens when the _merge wasn't feasible during _get_next_buf. + * + * The _flush method repeatedly inspects the head buffer and flushes as + * much data from it as it needs to, up to the size of the buffer. If + * the flush decimates the buffer, it's stripped, unref'd, and removed. + */ -// get the next buffer -// if the buffer can be merged with the head buffer, do so -// else add it onto the head of the +/* get the next buffer + * if the buffer can be merged with the head buffer, do so + * else add it onto the head of the + */ static gboolean gst_bytestream_get_next_buf (GstByteStream * bs) { @@ -135,23 +137,23 @@ gst_bytestream_get_next_buf (GstByteStream * bs) bs_print ("get_next_buf: got buffer of %d bytes\n", GST_BUFFER_SIZE (nextbuf)); - // first see if there are any buffers in the list at all + /* first see if there are any buffers in the list at all */ if (bs->buflist) { bs_print ("gst_next_buf: there is at least one buffer in the list\n"); - // now find the end of the list + /* now find the end of the list */ end = g_slist_last (bs->buflist); - // get the buffer that's there + /* get the buffer that's there */ lastbuf = GST_BUFFER (end->data); - // see if we can marge cheaply + /* see if we can marge cheaply */ if (gst_buffer_is_span_fast (lastbuf, nextbuf)) { bs_print ("get_next_buf: merging new buffer with last buf on list\n"); - // it is, let's merge them (this is really an append, but...) + /* it is, let's merge them (this is really an append, but...) */ end->data = gst_buffer_merge (lastbuf, nextbuf); - // add to the length of the list + /* 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 + /* have to check to see if we merged with the head buffer */ if (end == bs->buflist) { bs->headbufavail += GST_BUFFER_SIZE (nextbuf); } @@ -159,24 +161,24 @@ gst_bytestream_get_next_buf (GstByteStream * bs) gst_buffer_unref (lastbuf); gst_buffer_unref (nextbuf); - // if we can't, we just append this buffer + /* if we can't, we just append this buffer */ } else { bs_print ("get_next_buf: adding new buffer to the end of the list\n"); end = g_slist_append (end, nextbuf); - // also need to increment length of list and buffer count + /* also need to increment length of list and buffer count */ bs->listavail += GST_BUFFER_SIZE (nextbuf); } - // if there are no buffers in the list + /* if there are no buffers in the list */ } else { bs_print ("get_next_buf: buflist is empty, adding new buffer to list\n"); - // put this on the end of the list + /* put this on the end of the list */ bs->buflist = g_slist_append (bs->buflist, nextbuf); - // and increment the number of bytes in the list + /* and increment the number of bytes in the list */ bs->listavail = GST_BUFFER_SIZE (nextbuf); - // set the head buffer avail to the size + /* set the head buffer avail to the size */ bs->headbufavail = GST_BUFFER_SIZE (nextbuf); } @@ -186,7 +188,7 @@ gst_bytestream_get_next_buf (GstByteStream * bs) static gboolean gst_bytestream_fill_bytes (GstByteStream * bs, guint32 len) { - // as long as we don't have enough, we get more buffers + /* as long as we don't have enough, we get more buffers */ while (bs->listavail < len) { bs_print ("fill_bytes: there are %d bytes in the list, we need %d\n", bs->listavail, len); if (!gst_bytestream_get_next_buf (bs)) @@ -207,7 +209,7 @@ gst_bytestream_peek (GstByteStream * bs, guint32 len) bs_print ("peek: asking for %d bytes\n", len); - // make sure we have enough + /* 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)) @@ -216,17 +218,17 @@ gst_bytestream_peek (GstByteStream * bs, guint32 len) } bs_status (bs); - // extract the head buffer + /* extract the head buffer */ headbuf = GST_BUFFER (bs->buflist->data); - // if the requested bytes are in the current buffer + /* 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 + /* create a sub-buffer of the headbuf */ retbuf = gst_buffer_create_sub (headbuf, GST_BUFFER_SIZE (headbuf) - bs->headbufavail, len); - // 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\n", len); @@ -256,7 +258,7 @@ gst_bytestream_peek_bytes (GstByteStream * bs, guint32 len) bs->assembled = NULL; } - // make sure we have enough + /* 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)) @@ -265,17 +267,17 @@ gst_bytestream_peek_bytes (GstByteStream * bs, guint32 len) } bs_status (bs); - // extract the head buffer + /* extract the head buffer */ headbuf = GST_BUFFER (bs->buflist->data); - // if the requested bytes are in the current buffer + /* 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 + /* 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\n", len); @@ -296,14 +298,14 @@ gst_bytestream_assemble (GstByteStream * bs, guint32 len) guint32 copied = 0; GstBuffer *buf; - // copy the data from the curbuf + /* 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 + /* asumption is made that the buffers all exist in the list */ walk = g_slist_next (bs->buflist); while (copied < len) { buf = GST_BUFFER (walk->data); @@ -328,7 +330,7 @@ gst_bytestream_flush (GstByteStream * bs, guint32 len) { bs_print ("flush: flushing %d bytes\n", len); - // make sure we have enough + /* 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)) @@ -353,35 +355,35 @@ gst_bytestream_flush_fast (GstByteStream * bs, guint32 len) bs->assembled = NULL; } - // repeat until we've flushed enough data + /* repeat until we've flushed enough data */ while (len > 0) { headbuf = GST_BUFFER (bs->buflist->data); bs_print ("flush: analyzing buffer that's %d bytes long, offset %d\n", GST_BUFFER_SIZE (headbuf), GST_BUFFER_OFFSET (headbuf)); - // if there's enough to complete the flush + /* if there's enough to complete the flush */ if (bs->headbufavail > len) { - // just trim it off + /* just trim it off */ bs_print ("flush: trimming %d bytes off end of headbuf\n", len); bs->headbufavail -= len; bs->listavail -= len; len = 0; - // otherwise we have to trim the whole buffer + /* otherwise we have to trim the whole buffer */ } else { bs_print ("flush: removing head buffer completely\n"); - // remove it from the list + /* remove it from the list */ bs->buflist = g_slist_delete_link (bs->buflist, bs->buflist); - // trim it from the avail size + /* trim it from the avail size */ bs->listavail -= bs->headbufavail; - // record that we've trimmed this many bytes + /* record that we've trimmed this many bytes */ len -= bs->headbufavail; - // unref it + /* unref it */ gst_buffer_unref (headbuf); - // record the new headbufavail + /* 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); @@ -395,6 +397,24 @@ gst_bytestream_flush_fast (GstByteStream * bs, guint32 len) } } +gboolean +gst_bytestream_seek (GstByteStream *bs, GstSeekType type, gint64 offset) +{ + GstRealPad *peer = GST_RPAD_PEER (bs->pad); + + if (gst_pad_send_event (GST_PAD (peer), gst_event_new_seek (type, offset, TRUE))) { + gst_bytestream_flush_fast (bs, bs->listavail); + return TRUE; + } + return FALSE; +} + +guint64 +gst_bytestream_tell (GstByteStream *bs) +{ + return 0; +} + GstBuffer * gst_bytestream_read (GstByteStream * bs, guint32 len) { diff --git a/libs/gst/bytestream/bytestream.h b/libs/gst/bytestream/bytestream.h index 3906b22a3f..ab4c9fe8e0 100644 --- a/libs/gst/bytestream/bytestream.h +++ b/libs/gst/bytestream/bytestream.h @@ -37,7 +37,7 @@ struct _GstByteStream { guint32 headbufavail; guint32 listavail; - // we keep state of assembled pieces + /* we keep state of assembled pieces */ guint8 *assembled; guint32 assembled_len; }; @@ -46,10 +46,12 @@ GstByteStream* gst_bytestream_new (GstPad *pad); void gst_bytestream_destroy (GstByteStream *bs); GstBuffer* gst_bytestream_read (GstByteStream *bs, guint32 len); +guint64 gst_bytestream_tell (GstByteStream *bs); +gboolean gst_bytestream_seek (GstByteStream *bs, GstSeekType type, gint64 offset); GstBuffer* gst_bytestream_peek (GstByteStream *bs, guint32 len); guint8* gst_bytestream_peek_bytes (GstByteStream *bs, guint32 len); gboolean gst_bytestream_flush (GstByteStream *bs, guint32 len); -void gst_bytestream_flush_fast (GstByteStream * bs, guint32 len); +void gst_bytestream_flush_fast (GstByteStream *bs, guint32 len); void gst_bytestream_get_status (GstByteStream *bs, guint32 *avail_out, GstEvent **event_out); void gst_bytestream_print_status (GstByteStream *bs);