2 * Copyright (C) 2001 Erik Walthinsen <omega@temple-baptist.com>
4 * gstbytestream.c: adds a convenient bytestream based API to a pad.
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
16 * You should have received a copy of the GNU Library General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 * Boston, MA 02111-1307, USA.
30 #include <gst/gstinfo.h>
31 #include <gst/gstbytestream.h>
33 GST_DEBUG_CATEGORY_STATIC(debug_bs);
34 #define GST_CAT_DEFAULT debug_bs
36 static guint8 *gst_bytestream_assemble (GstByteStream * bs, guint32 len);
39 gst_bytestream_init (GstByteStream *bs)
50 gst_bytestream_exit (GstByteStream *bs)
55 gst_event_unref (bs->event);
59 gst_buffer_unref (GST_BUFFER (walk->data));
60 walk = g_slist_next (walk);
62 g_slist_free (bs->buflist);
64 g_free (bs->assembled);
68 * @pad: the pad to attach the bytestream to
70 * creates a bytestream from the given pad
72 * Returns: a new #GstByteStream object
75 gst_bytestream_new (GstPad * pad)
77 GstByteStream *bs = g_new (GstByteStream, 1);
79 GST_DEBUG_CATEGORY_INIT (debug_bs, "bytestream", 0, "bytestream library");
82 gst_bytestream_init (bs);
88 * gst_bytestream_destroy:
89 * @bs: the bytestream object to destroy
91 * destroy the bytestream object and free its resources.
94 gst_bytestream_destroy (GstByteStream * bs)
96 gst_bytestream_exit (bs);
100 gst_bytestream_reset (GstByteStream *bs)
103 gst_bytestream_exit (bs);
104 /* reset data to clean state */
105 gst_bytestream_init (bs);
109 * The fundamental structure is a singly-linked list of buffers. The
110 * buffer on the front is the oldest, and thus the first to read data
111 * from. The number of bytes left to be read in this buffer is stored
112 * in bs->headbufavail. The number of bytes available in the entire
113 * list (including the head buffer) is in bs->listavail.
115 * When a request is made for data (peek), _fill_bytes is called with
116 * the number of bytes needed, but only if the listavail indicates
117 * that there aren't already enough. This calls _get_next_buf until
118 * the listavail is sufficient to satisfy the demand.
120 * _get_next_buf pulls a buffer from the pad the bytestream is attached
121 * to, and shoves it in the list. There are actually two things it can
122 * do. If there's already a buffer in the list, and the _is_span_fast()
123 * test returns true, it will merge it with that last buffer. Otherwise
124 * it will simply tack it onto the end of the list.
126 * The _peek itself first checks the simple case of the request fitting
127 * within the head buffer, and if so creates a subbuffer and returns.
128 * Otherwise, it creates a new buffer and allocates space for the request
129 * and calls _assemble to fill it. We know we have to copy because this
130 * case only happens when the _merge wasn't feasible during _get_next_buf.
132 * The _flush method repeatedly inspects the head buffer and flushes as
133 * much data from it as it needs to, up to the size of the buffer. If
134 * the flush decimates the buffer, it's stripped, unref'd, and removed.
138 /* get the next buffer
139 * if the buffer can be merged with the head buffer, do so
140 * else add it onto the head of the
143 gst_bytestream_get_next_buf (GstByteStream *bs)
145 GstBuffer *nextbuf, *lastbuf, *headbuf;
148 /* if there is an event pending, return FALSE */
152 GST_DEBUG ("get_next_buf: pulling buffer");
153 nextbuf = gst_pad_pull (bs->pad);
158 if (GST_IS_EVENT (nextbuf)) {
159 bs->event = GST_EVENT (nextbuf);
163 if (GST_BUFFER_TIMESTAMP_IS_VALID (nextbuf))
164 bs->last_ts = GST_BUFFER_TIMESTAMP (nextbuf);
166 GST_DEBUG ("get_next_buf: got buffer of %d bytes", GST_BUFFER_SIZE (nextbuf));
168 /* first see if there are any buffers in the list at all */
170 GST_DEBUG ("gst_next_buf: there is at least one buffer in the list");
171 /* now find the end of the list */
172 end = g_slist_last (bs->buflist);
173 /* get the buffer that's there */
174 lastbuf = GST_BUFFER (end->data);
176 /* see if we can marge cheaply */
177 if (gst_buffer_is_span_fast (lastbuf, nextbuf)) {
178 GST_DEBUG ("get_next_buf: merging new buffer with last buf on list");
179 /* it is, let's merge them (this is really an append, but...) */
180 end->data = gst_buffer_merge (lastbuf, nextbuf);
181 /* add to the length of the list */
182 bs->listavail += GST_BUFFER_SIZE (nextbuf);
184 /* have to check to see if we merged with the head buffer */
185 if (end == bs->buflist) {
186 bs->headbufavail += GST_BUFFER_SIZE (nextbuf);
189 gst_buffer_unref (lastbuf);
190 gst_buffer_unref (nextbuf);
192 /* if we can't, we just append this buffer */
195 GST_DEBUG ("get_next_buf: adding new buffer to the end of the list");
196 end = g_slist_append (end, nextbuf);
197 /* also need to increment length of list and buffer count */
198 bs->listavail += GST_BUFFER_SIZE (nextbuf);
201 /* if there are no buffers in the list */
204 GST_DEBUG ("get_next_buf: buflist is empty, adding new buffer to list");
205 /* put this on the end of the list */
206 bs->buflist = g_slist_append (bs->buflist, nextbuf);
207 /* and increment the number of bytes in the list */
208 bs->listavail = GST_BUFFER_SIZE (nextbuf);
209 /* set the head buffer avail to the size */
210 bs->headbufavail = GST_BUFFER_SIZE (nextbuf);
213 /* a zero offset is a indication that we might need to set the timestamp */
214 if (bs->offset == 0LL){
215 headbuf = GST_BUFFER (bs->buflist->data);
216 bs->offset = GST_BUFFER_OFFSET(headbuf);
223 gst_bytestream_fill_bytes (GstByteStream *bs, guint32 len)
225 /* as long as we don't have enough, we get more buffers */
226 while (bs->listavail < len) {
227 GST_DEBUG ("fill_bytes: there are %d bytes in the list, we need %d", bs->listavail, len);
228 if (!gst_bytestream_get_next_buf (bs))
236 * gst_bytestream_peek:
237 * @bs: the bytestream to peek
238 * @buf: pointer to a variable that can hold a buffer pointer.
239 * @len: the number of bytes to peek
241 * Peeks len bytes into the bytestream, the result is returned as
242 * a #GstBuffer. Unref the buffer after usage.
243 * This function can return less bytes than requested. In that case,
244 * an event might have happened which you can retrieve with
245 * gst_bytestream_get_status().
247 * Returns: The number of bytes successfully peeked.
250 gst_bytestream_peek (GstByteStream *bs, GstBuffer **buf, guint32 len)
252 GstBuffer *headbuf, *retbuf = NULL;
254 g_return_val_if_fail (bs != NULL, 0);
255 g_return_val_if_fail (len > 0, 0);
257 GST_DEBUG ("peek: asking for %d bytes", len);
259 /* make sure we have enough */
260 GST_DEBUG ("peek: there are %d bytes in the list", bs->listavail);
261 if (len > bs->listavail) {
262 if (!gst_bytestream_fill_bytes (bs, len)) {
263 /* we must have an event coming up */
264 if (bs->listavail > 0) {
265 /* we have some data left, len will be shrunk to the amount of data available */
269 /* there is no data */
274 GST_DEBUG ("peek: there are now %d bytes in the list", bs->listavail);
276 gst_bytestream_print_status (bs);
278 /* extract the head buffer */
279 headbuf = GST_BUFFER (bs->buflist->data);
281 /* if the requested bytes are in the current buffer */
282 GST_DEBUG ("peek: headbufavail is %d", bs->headbufavail);
283 if (len <= bs->headbufavail) {
284 GST_DEBUG ("peek: there are enough bytes in headbuf (need %d, have %d)", len, bs->headbufavail);
285 /* create a sub-buffer of the headbuf */
286 retbuf = gst_buffer_create_sub (headbuf, GST_BUFFER_SIZE (headbuf) - bs->headbufavail, len);
287 GST_BUFFER_OFFSET (retbuf) = GST_BUFFER_OFFSET (headbuf) + GST_BUFFER_SIZE (headbuf) - bs->headbufavail;
290 /* otherwise we need to figure out how to assemble one */
292 GST_DEBUG ("peek: current buffer is not big enough for len %d", len);
294 retbuf = gst_buffer_new ();
295 GST_BUFFER_SIZE (retbuf) = len;
296 GST_BUFFER_DATA (retbuf) = gst_bytestream_assemble (bs, len);
297 GST_BUFFER_TIMESTAMP (retbuf) = bs->last_ts;
305 * gst_bytestream_peek_bytes:
306 * @bs: the bytestream to peek
307 * @data: pointer to a variable that can hold a guint8 pointer.
308 * @len: the number of bytes to peek
310 * Peeks len bytes into the bytestream, the result is returned as
311 * a pointer to a guint8*. The data pointed to be data should not
312 * be freed and will become invalid after performing the next bytestream
314 * This function can return less bytes than requested. In that case,
315 * an event might have happened which you can retrieve with
316 * gst_bytestream_get_status().
318 * Returns: The number of bytes successfully peeked.
321 gst_bytestream_peek_bytes (GstByteStream *bs, guint8** data, guint32 len)
325 g_return_val_if_fail (bs != NULL, 0);
326 g_return_val_if_fail (len > 0, 0);
328 GST_DEBUG ("peek_bytes: asking for %d bytes", len);
330 if (bs->assembled_len >= len) {
331 *data = bs->assembled;
334 g_free (bs->assembled);
335 bs->assembled = NULL;
338 /* make sure we have enough */
339 GST_DEBUG ("peek_bytes: there are %d bytes in the list", bs->listavail);
340 if (len > bs->listavail) {
341 if (!gst_bytestream_fill_bytes (bs, len)){
342 /* we must have an event coming up */
343 if (bs->listavail > 0){
344 /* we have some data left, len will be shrunk to the amount of data available */
348 /* there is no data */
353 GST_DEBUG ("peek_bytes: there are now %d bytes in the list", bs->listavail);
355 gst_bytestream_print_status (bs);
357 /* extract the head buffer */
358 headbuf = GST_BUFFER (bs->buflist->data);
360 /* if the requested bytes are in the current buffer */
361 GST_DEBUG ("peek_bytes: headbufavail is %d", bs->headbufavail);
362 if (len <= bs->headbufavail) {
363 GST_DEBUG ("peek_bytes: there are enough bytes in headbuf (need %d, have %d)", len, bs->headbufavail);
364 /* create a sub-buffer of the headbuf */
365 *data = GST_BUFFER_DATA (headbuf) + (GST_BUFFER_SIZE (headbuf) - bs->headbufavail);
368 /* otherwise we need to figure out how to assemble one */
370 GST_DEBUG ("peek_bytes: current buffer is not big enough for len %d", len);
372 *data = gst_bytestream_assemble (bs, len);
373 bs->assembled = *data;
374 bs->assembled_len = len;
381 gst_bytestream_assemble (GstByteStream *bs, guint32 len)
383 guint8 *data = g_malloc (len);
388 /* copy the data from the curbuf */
389 buf = GST_BUFFER (bs->buflist->data);
390 GST_DEBUG ("assemble: copying %d bytes from curbuf at %d to *data", bs->headbufavail,
391 GST_BUFFER_SIZE (buf) - bs->headbufavail);
392 memcpy (data, GST_BUFFER_DATA (buf) + GST_BUFFER_SIZE (buf) - bs->headbufavail, bs->headbufavail);
393 copied += bs->headbufavail;
395 /* asumption is made that the buffers all exist in the list */
396 walk = g_slist_next (bs->buflist);
397 while (copied < len) {
398 buf = GST_BUFFER (walk->data);
399 if (GST_BUFFER_SIZE (buf) < (len - copied)) {
400 GST_DEBUG ("assemble: copying %d bytes from buf to output offset %d", GST_BUFFER_SIZE (buf), copied);
401 memcpy (data + copied, GST_BUFFER_DATA (buf), GST_BUFFER_SIZE (buf));
402 copied += GST_BUFFER_SIZE (buf);
405 GST_DEBUG ("assemble: copying %d bytes from buf to output offset %d", len - copied, copied);
406 memcpy (data + copied, GST_BUFFER_DATA (buf), len - copied);
409 walk = g_slist_next (walk);
416 * gst_bytestream_flush:
417 * @bs: the bytestream to flush
418 * @len: the number of bytes to flush
420 * Flush len bytes from the bytestream.
421 * This function can return FALSE when the number of
422 * bytes could not be flushed due to an event. In that case,
423 * you can get the number of available bytes before the event
424 * with gst_bytestream_get_status().
426 * Returns: TRUE if the number of bytes could be flushed.
429 gst_bytestream_flush (GstByteStream *bs, guint32 len)
431 GST_DEBUG ("flush: flushing %d bytes", len);
436 /* make sure we have enough */
437 GST_DEBUG ("flush: there are %d bytes in the list", bs->listavail);
438 if (len > bs->listavail) {
439 if (!gst_bytestream_fill_bytes (bs, len)) {
442 GST_DEBUG ("flush: there are now %d bytes in the list", bs->listavail);
445 gst_bytestream_flush_fast (bs, len);
451 * gst_bytestream_flush_fast:
452 * @bs: the bytestream to flush
453 * @len: the number of bytes to flush
455 * Flushes len bytes from the bytestream. This function
456 * is faster than gst_bytestream_flush() but only works
457 * when you have recently peeked no less than len bytes
458 * with gst_bytestream_peek() or gst_bytestream_peek_bytes().
461 gst_bytestream_flush_fast (GstByteStream *bs, guint32 len)
468 g_assert (len <= bs->listavail);
471 g_free (bs->assembled);
472 bs->assembled = NULL;
475 /* update the byte offset */
478 /* repeat until we've flushed enough data */
480 headbuf = GST_BUFFER (bs->buflist->data);
482 GST_DEBUG ("flush: analyzing buffer that's %d bytes long, offset %" G_GUINT64_FORMAT, GST_BUFFER_SIZE (headbuf),
483 GST_BUFFER_OFFSET (headbuf));
485 /* if there's enough to complete the flush */
486 if (bs->headbufavail > len) {
487 /* just trim it off */
488 GST_DEBUG ("flush: trimming %d bytes off end of headbuf", len);
489 bs->headbufavail -= len;
490 bs->listavail -= len;
493 /* otherwise we have to trim the whole buffer */
496 GST_DEBUG ("flush: removing head buffer completely");
497 /* remove it from the list */
498 bs->buflist = g_slist_delete_link (bs->buflist, bs->buflist);
499 /* trim it from the avail size */
500 bs->listavail -= bs->headbufavail;
501 /* record that we've trimmed this many bytes */
502 len -= bs->headbufavail;
504 gst_buffer_unref (headbuf);
506 /* record the new headbufavail */
508 bs->headbufavail = GST_BUFFER_SIZE (GST_BUFFER (bs->buflist->data));
509 GST_DEBUG ("flush: next headbuf is %d bytes", bs->headbufavail);
512 GST_DEBUG ("flush: no more bytes at all");
516 GST_DEBUG ("flush: bottom of while(), len is now %d", len);
521 * gst_bytestream_seek:
522 * @bs: the bytestream to seek
523 * @offset: the byte offset to seek to
524 * @method: the seek method.
526 * Perform a seek on the bytestream to the given offset.
527 * The method can be one of GST_SEEK_METHOD_CUR, GST_SEEK_METHOD_SET,
528 * GST_SEEK_METHOD_END.
529 * This seek will also flush any pending data in the bytestream or
532 * Returns: TRUE when the seek succeeded.
535 gst_bytestream_seek (GstByteStream *bs, gint64 offset, GstSeekType method)
539 g_return_val_if_fail (bs != NULL, FALSE);
541 peer = GST_RPAD_PEER (bs->pad);
543 GST_DEBUG ("bs: send event\n");
544 if (gst_pad_send_event (GST_PAD (peer), gst_event_new_seek (
546 (method & GST_SEEK_METHOD_MASK) |
547 GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_ACCURATE,
550 gst_bytestream_flush_fast (bs, bs->listavail);
552 /* we set the seek flag here. We cannot pull the pad here
553 * bacause a seek might occur outisde of the pads cothread context */
558 GST_DEBUG ("bs: send event failed\n");
563 * gst_bytestream_tell
566 * Get the current byteoffset in the bytestream.
568 * Returns: the offset or -1 on error.
571 gst_bytestream_tell (GstByteStream *bs)
576 g_return_val_if_fail (bs != NULL, -1);
578 format = GST_FORMAT_BYTES;
580 if (gst_pad_query (GST_PAD_PEER (bs->pad), GST_QUERY_POSITION, &format, &value)) {
581 return value - bs->listavail;
588 * gst_bytestream_length
591 * Get the total length of the bytestream.
593 * Returns: the total length or -1 on error.
596 gst_bytestream_length (GstByteStream *bs)
601 g_return_val_if_fail (bs != NULL, -1);
603 format = GST_FORMAT_BYTES;
605 if (gst_pad_query (GST_PAD_PEER (bs->pad), GST_QUERY_TOTAL, &format, &value))
612 * gst_bytestream_read:
613 * @bs: the bytestream to read
614 * @buf: pointer to a variable that can hold a buffer pointer.
615 * @len: the number of bytes to read
617 * Read len bytes from the bytestream, the result is returned as
618 * a #GstBuffer. Unref the buffer after usage.
619 * This function can return less bytes than requested. In that case,
620 * an event might have happened which you can retrieve with
621 * gst_bytestream_get_status().
623 * Returns: The number of bytes successfully read.
626 gst_bytestream_read (GstByteStream *bs, GstBuffer** buf, guint32 len)
630 g_return_val_if_fail (bs != NULL, -1);
632 len_peeked = gst_bytestream_peek (bs, buf, len);
636 gst_bytestream_flush_fast (bs, len_peeked);
642 * gst_bytestream_size_hint
644 * @size: the size to hint
646 * Give a hint that we are going to read chunks of the given size.
647 * Giving size hints to the peer element might improve performance
648 * since less buffers need to be merged.
650 * Returns: TRUE if the hint was accepted
653 gst_bytestream_size_hint (GstByteStream *bs, guint32 size)
657 g_return_val_if_fail (bs != NULL, FALSE);
659 event = gst_event_new_size (GST_FORMAT_BYTES, size);
661 return gst_pad_send_event (GST_PAD_PEER (bs->pad), event);
665 * gst_bytestream_get_status
667 * @avail_out: total number of bytes buffered
668 * @event_out: an event
670 * When an event occurs, the bytestream operations return a value less
671 * than the requested length. You must retrieve the event using this API
672 * before reading more bytes from the stream.
675 gst_bytestream_get_status (GstByteStream *bs,
677 GstEvent **event_out)
680 *avail_out = bs->listavail;
683 *event_out = bs->event;
689 * gst_bytestream_get_timestamp
692 * Get the timestamp of the first data in the bytestream. If no data
693 * exists 1 byte is read to load a new buffer.
695 * This function will not check input buffer boundries. It is possible
696 * the next read could span two or more input buffers with different
699 * Returns: a timestamp
702 gst_bytestream_get_timestamp (GstByteStream *bs)
706 g_return_val_if_fail (bs != NULL, 0);
708 GST_DEBUG ("get_timestamp: getting timestamp");
710 /* make sure we have a buffer */
711 if (bs->listavail == 0) {
712 GST_DEBUG ("gst_timestamp: fetching a buffer");
713 if (!gst_bytestream_fill_bytes (bs, 1))
717 /* extract the head buffer */
718 headbuf = GST_BUFFER (bs->buflist->data);
720 return GST_BUFFER_TIMESTAMP (headbuf);
724 * gst_bytestream_print_status
727 * Print the current status of the bytestream object. mainly
728 * used for debugging purposes.
731 gst_bytestream_print_status (GstByteStream * bs)
736 GST_DEBUG ("STATUS: head buffer has %d bytes available", bs->headbufavail);
737 GST_DEBUG ("STATUS: list has %d bytes available", bs->listavail);
740 buf = GST_BUFFER (walk->data);
741 walk = g_slist_next (walk);
743 GST_DEBUG ("STATUS: buffer starts at %" G_GUINT64_FORMAT " and is %d bytes long",
744 GST_BUFFER_OFFSET (buf), GST_BUFFER_SIZE (buf));