New bytestream fileio style api has landed, along with some minor fixes:

Original commit message from CVS:
New bytestream fileio style api has landed, along with some minor fixes:
- implement gst_bytestream_tell
- prevent buffers from being gobbled after a seek
This commit is contained in:
Steve Baker 2002-05-15 18:52:08 +00:00
parent fbaeb5882f
commit 5484324b04
3 changed files with 85 additions and 37 deletions

View file

@ -205,10 +205,11 @@ gst_identity_loop (GstElement *element)
/* THIS IS THE BYTE BASED ONE*/
do {
for (i=0;i<identity->count;i++) {
guint8 *data;
buf = gst_buffer_new();
/* note that this is dangerous, as it does *NOT* refcount the data, it can go away!!! */
GST_BUFFER_DATA(buf) = gst_bytestream_peek_bytes(identity->bs,identity->byte_size);
GST_BUFFER_SIZE(buf) = identity->byte_size;
GST_BUFFER_SIZE(buf) = gst_bytestream_peek_bytes(identity->bs, &data, identity->byte_size);
GST_BUFFER_DATA(buf) = data;
GST_BUFFER_FLAG_SET(buf,GST_BUFFER_DONTFREE);
gst_pad_push(identity->srcpad,buf);
gst_bytestream_flush(identity->bs,identity->byte_size);

View file

@ -57,6 +57,7 @@ gst_bytestream_new (GstPad * pad)
bs->headbufavail = 0;
bs->listavail = 0;
bs->assembled = NULL;
bs->offset = 0LL;
return bs;
}
@ -118,7 +119,7 @@ gst_bytestream_destroy (GstByteStream * bs)
static gboolean
gst_bytestream_get_next_buf (GstByteStream * bs)
{
GstBuffer *nextbuf, *lastbuf;
GstBuffer *nextbuf, *lastbuf, *headbuf;
GSList *end;
g_assert (!bs->event);
@ -182,6 +183,12 @@ gst_bytestream_get_next_buf (GstByteStream * bs)
bs->headbufavail = GST_BUFFER_SIZE (nextbuf);
}
/* a zero offset is a indication that we might need to set the timestamp */
if (bs->offset == 0LL){
headbuf = GST_BUFFER (bs->buflist->data);
bs->offset = GST_BUFFER_OFFSET(headbuf);
}
return TRUE;
}
@ -199,21 +206,31 @@ gst_bytestream_fill_bytes (GstByteStream * bs, guint32 len)
}
GstBuffer *
gst_bytestream_peek (GstByteStream * bs, guint32 len)
guint32
gst_bytestream_peek (GstByteStream * bs, GstBuffer **buf, guint32 len)
{
GstBuffer *headbuf, *retbuf = NULL;
g_return_val_if_fail (bs != NULL, NULL);
g_return_val_if_fail (len > 0, NULL);
g_return_val_if_fail (bs != NULL, 0);
g_return_val_if_fail (len > 0, 0);
bs_print ("peek: asking for %d bytes\n", len);
/* 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;
if (!gst_bytestream_fill_bytes (bs, len)){
/* we must have an event coming up */
if (bs->listavail > 0){
/* we have some data left, len will be shrunk to the amount of data available */
len = bs->listavail;
}
else {
/* there is no data */
*buf = retbuf;
return 0;
}
}
bs_print ("peek: there are now %d bytes in the list\n", bs->listavail);
}
bs_status (bs);
@ -241,17 +258,17 @@ gst_bytestream_peek (GstByteStream * bs, guint32 len)
GST_BUFFER_OFFSET (retbuf) = GST_BUFFER_OFFSET (headbuf) + (GST_BUFFER_SIZE (headbuf) - bs->headbufavail);
}
return retbuf;
*buf = retbuf;
return len;
}
guint8 *
gst_bytestream_peek_bytes (GstByteStream * bs, guint32 len)
guint32
gst_bytestream_peek_bytes (GstByteStream * bs, guint8** data, 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, 0);
g_return_val_if_fail (len > 0, 0);
bs_print ("peek_bytes: asking for %d bytes\n", len);
if (bs->assembled) {
@ -262,8 +279,18 @@ gst_bytestream_peek_bytes (GstByteStream * bs, guint32 len)
/* 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;
if (!gst_bytestream_fill_bytes (bs, len)){
/* we must have an event coming up */
if (bs->listavail > 0){
/* we have some data left, len will be shrunk to the amount of data available */
len = bs->listavail;
}
else {
/* there is no data */
*data = NULL;
return 0;
}
}
bs_print ("peek_bytes: there are now %d bytes in the list\n", bs->listavail);
}
bs_status (bs);
@ -276,19 +303,19 @@ gst_bytestream_peek_bytes (GstByteStream * bs, guint32 len)
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);
*data = GST_BUFFER_DATA (headbuf) + (GST_BUFFER_SIZE (headbuf) - bs->headbufavail);
/* 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);
data = gst_bytestream_assemble (bs, len);
bs->assembled = data;
*data = gst_bytestream_assemble (bs, len);
bs->assembled = *data;
bs->assembled_len = len;
}
return data;
return len;
}
guint8 *
@ -356,6 +383,9 @@ gst_bytestream_flush_fast (GstByteStream * bs, guint32 len)
bs->assembled = NULL;
}
/* update the byte offset */
bs->offset += len;
/* repeat until we've flushed enough data */
while (len > 0) {
headbuf = GST_BUFFER (bs->buflist->data);
@ -402,16 +432,27 @@ gboolean
gst_bytestream_seek (GstByteStream *bs, GstSeekType type, gint64 offset)
{
GstRealPad *peer = GST_RPAD_PEER (bs->pad);
guint32 waiting;
GstEvent *event = NULL;
GstBuffer *headbuf;
if (gst_pad_send_event (GST_PAD (peer), gst_event_new_seek (type, offset, TRUE))) {
GstBuffer *nextbuf;
gst_bytestream_flush_fast (bs, bs->listavail);
do {
nextbuf = gst_pad_pull (bs->pad);
while (!gst_bytestream_get_next_buf(bs)) {
gst_bytestream_get_status(bs, &waiting, &event);
/* it is valid for a seek to cause eos, so lets say it succeeded */
if (GST_EVENT_TYPE(event) == GST_EVENT_EOS){
bs->offset = 0LL;
return TRUE;
}
}
while (!GST_IS_EVENT (nextbuf));
headbuf = GST_BUFFER (bs->buflist->data);
/* we have a new offset */
bs->offset = GST_BUFFER_OFFSET(headbuf);
return TRUE;
}
@ -421,19 +462,22 @@ gst_bytestream_seek (GstByteStream *bs, GstSeekType type, gint64 offset)
guint64
gst_bytestream_tell (GstByteStream *bs)
{
return 0;
g_return_val_if_fail (bs != NULL, 0);
return bs->offset;
}
GstBuffer *
gst_bytestream_read (GstByteStream * bs, guint32 len)
guint32
gst_bytestream_read (GstByteStream * bs, GstBuffer** buf, guint32 len)
{
GstBuffer *buf = gst_bytestream_peek (bs, len);
if (!buf)
return NULL;
guint32 len_peeked;
len_peeked = gst_bytestream_peek (bs, buf, len);
if (len_peeked == 0)
return 0;
gst_bytestream_flush_fast (bs, len);
gst_bytestream_flush_fast (bs, len_peeked);
return buf;
return len_peeked;
}

View file

@ -40,16 +40,19 @@ struct _GstByteStream {
/* we keep state of assembled pieces */
guint8 *assembled;
guint32 assembled_len;
/* this is needed for gst_bytestream_tell */
guint64 offset;
};
GstByteStream* gst_bytestream_new (GstPad *pad);
void gst_bytestream_destroy (GstByteStream *bs);
GstBuffer* gst_bytestream_read (GstByteStream *bs, guint32 len);
guint32 gst_bytestream_read (GstByteStream *bs, GstBuffer** buf, 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);
guint32 gst_bytestream_peek (GstByteStream *bs, GstBuffer** buf, guint32 len);
guint32 gst_bytestream_peek_bytes (GstByteStream *bs, guint8** data, guint32 len);
gboolean gst_bytestream_flush (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);