mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-04-26 06:54:49 +00:00
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:
parent
fbaeb5882f
commit
5484324b04
3 changed files with 85 additions and 37 deletions
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
Loading…
Reference in a new issue