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

View file

@ -57,6 +57,7 @@ gst_bytestream_new (GstPad * pad)
bs->headbufavail = 0; bs->headbufavail = 0;
bs->listavail = 0; bs->listavail = 0;
bs->assembled = NULL; bs->assembled = NULL;
bs->offset = 0LL;
return bs; return bs;
} }
@ -118,7 +119,7 @@ gst_bytestream_destroy (GstByteStream * bs)
static gboolean static gboolean
gst_bytestream_get_next_buf (GstByteStream * bs) gst_bytestream_get_next_buf (GstByteStream * bs)
{ {
GstBuffer *nextbuf, *lastbuf; GstBuffer *nextbuf, *lastbuf, *headbuf;
GSList *end; GSList *end;
g_assert (!bs->event); g_assert (!bs->event);
@ -182,6 +183,12 @@ gst_bytestream_get_next_buf (GstByteStream * bs)
bs->headbufavail = GST_BUFFER_SIZE (nextbuf); 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; return TRUE;
} }
@ -199,21 +206,31 @@ gst_bytestream_fill_bytes (GstByteStream * bs, guint32 len)
} }
GstBuffer * guint32
gst_bytestream_peek (GstByteStream * bs, guint32 len) gst_bytestream_peek (GstByteStream * bs, GstBuffer **buf, guint32 len)
{ {
GstBuffer *headbuf, *retbuf = NULL; GstBuffer *headbuf, *retbuf = NULL;
g_return_val_if_fail (bs != NULL, NULL); g_return_val_if_fail (bs != NULL, 0);
g_return_val_if_fail (len > 0, NULL); g_return_val_if_fail (len > 0, 0);
bs_print ("peek: asking for %d bytes\n", 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); bs_print ("peek: there are %d bytes in the list\n", bs->listavail);
if (len > bs->listavail) { if (len > bs->listavail) {
if (!gst_bytestream_fill_bytes (bs, len)) if (!gst_bytestream_fill_bytes (bs, len)){
return NULL; /* 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_print ("peek: there are now %d bytes in the list\n", bs->listavail);
} }
bs_status (bs); 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); GST_BUFFER_OFFSET (retbuf) = GST_BUFFER_OFFSET (headbuf) + (GST_BUFFER_SIZE (headbuf) - bs->headbufavail);
} }
return retbuf; *buf = retbuf;
return len;
} }
guint8 * guint32
gst_bytestream_peek_bytes (GstByteStream * bs, guint32 len) gst_bytestream_peek_bytes (GstByteStream * bs, guint8** data, guint32 len)
{ {
GstBuffer *headbuf; GstBuffer *headbuf;
guint8 *data = NULL;
g_return_val_if_fail (bs != NULL, NULL); g_return_val_if_fail (bs != NULL, 0);
g_return_val_if_fail (len > 0, NULL); g_return_val_if_fail (len > 0, 0);
bs_print ("peek_bytes: asking for %d bytes\n", len); bs_print ("peek_bytes: asking for %d bytes\n", len);
if (bs->assembled) { if (bs->assembled) {
@ -262,8 +279,18 @@ gst_bytestream_peek_bytes (GstByteStream * bs, guint32 len)
/* make sure we have enough */ /* make sure we have enough */
bs_print ("peek_bytes: there are %d bytes in the list\n", bs->listavail); bs_print ("peek_bytes: there are %d bytes in the list\n", bs->listavail);
if (len > bs->listavail) { if (len > bs->listavail) {
if (!gst_bytestream_fill_bytes (bs, len)) if (!gst_bytestream_fill_bytes (bs, len)){
return NULL; /* 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_print ("peek_bytes: there are now %d bytes in the list\n", bs->listavail);
} }
bs_status (bs); bs_status (bs);
@ -276,19 +303,19 @@ gst_bytestream_peek_bytes (GstByteStream * bs, guint32 len)
if (len <= bs->headbufavail) { if (len <= bs->headbufavail) {
bs_print ("peek_bytes: there are enough bytes in headbuf (need %d, have %d)\n", 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); *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 { else {
bs_print ("peek_bytes: current buffer is not big enough for len %d\n", len); bs_print ("peek_bytes: current buffer is not big enough for len %d\n", len);
data = gst_bytestream_assemble (bs, len); *data = gst_bytestream_assemble (bs, len);
bs->assembled = data; bs->assembled = *data;
bs->assembled_len = len; bs->assembled_len = len;
} }
return data; return len;
} }
guint8 * guint8 *
@ -356,6 +383,9 @@ gst_bytestream_flush_fast (GstByteStream * bs, guint32 len)
bs->assembled = NULL; bs->assembled = NULL;
} }
/* update the byte offset */
bs->offset += len;
/* repeat until we've flushed enough data */ /* repeat until we've flushed enough data */
while (len > 0) { while (len > 0) {
headbuf = GST_BUFFER (bs->buflist->data); headbuf = GST_BUFFER (bs->buflist->data);
@ -402,16 +432,27 @@ gboolean
gst_bytestream_seek (GstByteStream *bs, GstSeekType type, gint64 offset) gst_bytestream_seek (GstByteStream *bs, GstSeekType type, gint64 offset)
{ {
GstRealPad *peer = GST_RPAD_PEER (bs->pad); 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))) { if (gst_pad_send_event (GST_PAD (peer), gst_event_new_seek (type, offset, TRUE))) {
GstBuffer *nextbuf;
gst_bytestream_flush_fast (bs, bs->listavail); gst_bytestream_flush_fast (bs, bs->listavail);
do { while (!gst_bytestream_get_next_buf(bs)) {
nextbuf = gst_pad_pull (bs->pad); 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; return TRUE;
} }
@ -421,19 +462,22 @@ gst_bytestream_seek (GstByteStream *bs, GstSeekType type, gint64 offset)
guint64 guint64
gst_bytestream_tell (GstByteStream *bs) gst_bytestream_tell (GstByteStream *bs)
{ {
return 0; g_return_val_if_fail (bs != NULL, 0);
return bs->offset;
} }
GstBuffer * guint32
gst_bytestream_read (GstByteStream * bs, guint32 len) gst_bytestream_read (GstByteStream * bs, GstBuffer** buf, guint32 len)
{ {
GstBuffer *buf = gst_bytestream_peek (bs, len); guint32 len_peeked;
if (!buf)
return NULL; 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 */ /* we keep state of assembled pieces */
guint8 *assembled; guint8 *assembled;
guint32 assembled_len; guint32 assembled_len;
/* this is needed for gst_bytestream_tell */
guint64 offset;
}; };
GstByteStream* gst_bytestream_new (GstPad *pad); GstByteStream* gst_bytestream_new (GstPad *pad);
void gst_bytestream_destroy (GstByteStream *bs); 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); guint64 gst_bytestream_tell (GstByteStream *bs);
gboolean gst_bytestream_seek (GstByteStream *bs, GstSeekType type, gint64 offset); gboolean gst_bytestream_seek (GstByteStream *bs, GstSeekType type, gint64 offset);
GstBuffer* gst_bytestream_peek (GstByteStream *bs, guint32 len); guint32 gst_bytestream_peek (GstByteStream *bs, GstBuffer** buf, guint32 len);
guint8* gst_bytestream_peek_bytes (GstByteStream *bs, guint32 len); guint32 gst_bytestream_peek_bytes (GstByteStream *bs, guint8** data, guint32 len);
gboolean gst_bytestream_flush (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_get_status (GstByteStream *bs, guint32 *avail_out, GstEvent **event_out);