2 * (c) 2003 Ronald Bultje <rbultje@ronald.bitfreak.net>
3 * (c) 2005 Michal Benes <michal.benes@xeris.cz>
5 * ebml-write.c: write EBML data to file/stream
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Library General Public
9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Library General Public License for more details.
17 * You should have received a copy of the GNU Library General Public
18 * License along with this library; if not, write to the
19 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20 * Boston, MA 02111-1307, USA.
29 #include "ebml-write.h"
33 GST_DEBUG_CATEGORY_STATIC (gst_ebml_write_debug);
34 #define GST_CAT_DEFAULT gst_ebml_write_debug
36 #define _do_init(thing) \
37 GST_DEBUG_CATEGORY_INIT (gst_ebml_write_debug, "GstEbmlWrite", 0, "Write EBML structured data")
38 GST_BOILERPLATE_FULL (GstEbmlWrite, gst_ebml_write, GstObject, GST_TYPE_OBJECT,
41 static void gst_ebml_write_finalize (GObject * object);
44 static void gst_ebml_write_base_init (gpointer g_class)
49 gst_ebml_write_class_init (GstEbmlWriteClass * klass)
51 GObjectClass *object = G_OBJECT_CLASS (klass);
53 object->finalize = gst_ebml_write_finalize;
57 gst_ebml_write_init (GstEbmlWrite * ebml, GstEbmlWriteClass * klass)
67 gst_ebml_write_finalize (GObject * object)
69 GstEbmlWrite *ebml = GST_EBML_WRITE (object);
71 gst_object_unref (ebml->srcpad);
73 GST_CALL_PARENT (G_OBJECT_CLASS, finalize, (object));
79 * @srcpad: Source pad to which the output will be pushed.
81 * Creates a new #GstEbmlWrite.
83 * Returns: a new #GstEbmlWrite
86 gst_ebml_write_new (GstPad * srcpad)
89 GST_EBML_WRITE (g_object_new (GST_TYPE_EBML_WRITE, NULL));
91 ebml->srcpad = gst_object_ref (srcpad);
92 ebml->timestamp = GST_CLOCK_TIME_NONE;
94 gst_ebml_write_reset (ebml);
101 * gst_ebml_write_reset:
102 * @ebml: a #GstEbmlWrite.
104 * Reset internal state of #GstEbmlWrite.
107 gst_ebml_write_reset (GstEbmlWrite * ebml)
112 gst_buffer_unref (ebml->cache);
115 ebml->cache_size = 0;
116 ebml->last_write_result = GST_FLOW_OK;
117 ebml->timestamp = GST_CLOCK_TIME_NONE;
122 * gst_ebml_last_write_result:
123 * @ebml: a #GstEbmlWrite.
125 * Returns: GST_FLOW_OK if there was not write error since the last call of
126 * gst_ebml_last_write_result or code of the error.
129 gst_ebml_last_write_result (GstEbmlWrite * ebml)
131 GstFlowReturn res = ebml->last_write_result;
133 ebml->last_write_result = GST_FLOW_OK;
140 * gst_ebml_write_set_cache:
141 * @ebml: a #GstEbmlWrite.
142 * @size: size of the cache.
145 * The idea is that you use this for writing a lot
146 * of small elements. This will just "queue" all of
147 * them and they'll be pushed to the next element all
148 * at once. This saves memory and time for buffer
149 * allocation and init, and it looks better.
152 gst_ebml_write_set_cache (GstEbmlWrite * ebml, guint size)
154 /* This is currently broken. I don't know why yet. */
157 g_return_if_fail (ebml->cache == NULL);
159 ebml->cache = gst_buffer_new_and_alloc (size);
160 ebml->cache_size = size;
161 GST_BUFFER_SIZE (ebml->cache) = 0;
162 GST_BUFFER_OFFSET (ebml->cache) = ebml->pos;
167 * gst_ebml_write_flush_cache:
168 * @ebml: a #GstEbmlWrite.
173 gst_ebml_write_flush_cache (GstEbmlWrite * ebml)
178 /* this is very important. It may fail, in which case the client
179 * programmer didn't use the cache somewhere. That's fatal. */
180 g_assert (ebml->handled == GST_BUFFER_SIZE (ebml->cache));
181 g_assert (GST_BUFFER_SIZE (ebml->cache) +
182 GST_BUFFER_OFFSET (ebml->cache) == ebml->pos);
184 if (ebml->last_write_result == GST_FLOW_OK)
185 ebml->last_write_result = gst_pad_push (ebml->srcpad, ebml->cache);
188 ebml->cache_size = 0;
194 * gst_ebml_write_element_new:
195 * @ebml: a #GstEbmlWrite.
196 * @size: size of the requested buffer.
198 * Create a buffer for one element. If there is
199 * a cache, use that instead.
201 * Returns: A new #GstBuffer.
204 gst_ebml_write_element_new (GstEbmlWrite * ebml, guint size)
206 /* Create new buffer of size + ID + length */
214 if (ebml->cache_size - GST_BUFFER_SIZE (ebml->cache) < size) {
215 GST_LOG ("Cache available, but too small. Clearing...");
216 gst_ebml_write_flush_cache (ebml);
222 /* else, use a one-element buffer. This is slower */
223 buf = gst_buffer_new_and_alloc (size);
224 GST_BUFFER_SIZE (buf) = 0;
225 GST_BUFFER_TIMESTAMP (buf) = ebml->timestamp;
232 * gst_ebml_write_element_id:
233 * @buf: Buffer to which id should be written.
234 * @id: Element ID that should be written.
236 * Write element ID into a buffer.
239 gst_ebml_write_element_id (GstBuffer * buf, guint32 id)
241 guint8 *data = GST_BUFFER_DATA (buf) + GST_BUFFER_SIZE (buf);
242 guint bytes = 4, mask = 0x10;
245 while (!(id & (mask << ((bytes - 1) * 8))) && bytes > 0) {
250 /* if invalid ID, use dummy */
252 GST_WARNING ("Invalid ID, voiding");
254 id = GST_EBML_ID_VOID;
258 GST_BUFFER_SIZE (buf) += bytes;
260 data[bytes] = id & 0xff;
267 * gst_ebml_write_element_size:
268 * @buf: #GstBuffer to which size should be written.
269 * @size: Element length.
271 * Write element length into a buffer.
274 gst_ebml_write_element_size (GstBuffer * buf, guint64 size)
276 guint8 *data = GST_BUFFER_DATA (buf) + GST_BUFFER_SIZE (buf);
277 guint bytes = 1, mask = 0x80;
279 if (size != GST_EBML_SIZE_UNKNOWN) {
280 /* how many bytes? - use mask-1 because an all-1 bitset is not allowed */
281 while ((size >> ((bytes - 1) * 8)) >= (mask - 1) && bytes <= 8) {
286 /* if invalid size, use max. */
288 GST_WARNING ("Invalid size, writing size unknown");
291 /* Now here's a real FIXME: we cannot read those yet! */
292 size = GST_EBML_SIZE_UNKNOWN;
299 /* write out, BE, with length size marker */
300 GST_BUFFER_SIZE (buf) += bytes;
301 while (bytes-- > 0) {
302 data[bytes] = size & 0xff;
311 * gst_ebml_write_element_data:
312 * @buf: #GstBuffer to which data should be written.
313 * @write: Data that should be written.
314 * @length: Length of the data.
316 * Write element data into a buffer.
319 gst_ebml_write_element_data (GstBuffer * buf, guint8 * write, guint64 length)
321 guint8 *data = GST_BUFFER_DATA (buf) + GST_BUFFER_SIZE (buf);
323 memcpy (data, write, length);
324 GST_BUFFER_SIZE (buf) += length;
329 * gst_ebml_write_element_push:
330 * @ebml: #GstEbmlWrite
331 * @buf: #GstBuffer to be written.
333 * Write out buffer by moving it to the next element.
336 gst_ebml_write_element_push (GstEbmlWrite * ebml, GstBuffer * buf)
338 guint data_size = GST_BUFFER_SIZE (buf) - ebml->handled;
340 ebml->pos += data_size;
341 if (buf == ebml->cache) {
342 ebml->handled += data_size;
345 /* if there's no cache, then don't push it! */
347 g_assert (buf == ebml->cache);
351 if (ebml->last_write_result == GST_FLOW_OK)
352 ebml->last_write_result = gst_pad_push (ebml->srcpad, buf);
357 * gst_ebml_write_seek:
358 * @ebml: #GstEbmlWrite
359 * @pos: Seek position.
364 gst_ebml_write_seek (GstEbmlWrite * ebml, guint64 pos)
369 /* Cache seeking. A bit dangerous, we assume the client writer
370 * knows what he's doing... */
373 if (pos >= GST_BUFFER_OFFSET (ebml->cache) &&
374 pos < GST_BUFFER_OFFSET (ebml->cache) + ebml->cache_size) {
375 GST_BUFFER_SIZE (ebml->cache) = pos - GST_BUFFER_OFFSET (ebml->cache);
377 ebml->handled -= ebml->pos - pos;
379 ebml->handled += pos - ebml->pos;
382 GST_LOG ("Seek outside cache range. Clearing...");
383 gst_ebml_write_flush_cache (ebml);
387 seek = gst_event_new_new_segment (FALSE, 1.0, GST_FORMAT_BYTES, pos, -1, 0);
388 peer_pad = GST_PAD_PEER (ebml->srcpad);
390 gst_pad_send_event (peer_pad, seek);
392 GST_WARNING_OBJECT (ebml, "Can not seek: no peer pad");
400 * gst_ebml_write_get_uint_size:
401 * @num: Number to be encoded.
403 * Get number of bytes needed to write a uint.
405 * Returns: Encoded uint length.
408 gst_ebml_write_get_uint_size (guint64 num)
413 while (num >= (G_GINT64_CONSTANT (1) << (size * 8)) && size < 8) {
422 * gst_ebml_write_set_uint:
423 * @buf: #GstBuffer to which ithe number should be written.
424 * @num: Number to be written.
425 * @size: Encoded number length.
427 * Write an uint into a buffer.
430 gst_ebml_write_set_uint (GstBuffer * buf, guint64 num, guint size)
434 data = GST_BUFFER_DATA (buf) + GST_BUFFER_SIZE (buf);
435 GST_BUFFER_SIZE (buf) += size;
437 data[size] = num & 0xff;
444 * gst_ebml_write_uint:
445 * @ebml: #GstEbmlWrite
447 * @num: Number to be written.
449 * Write uint element.
452 gst_ebml_write_uint (GstEbmlWrite * ebml, guint32 id, guint64 num)
454 GstBuffer *buf = gst_ebml_write_element_new (ebml, sizeof (num));
455 guint size = gst_ebml_write_get_uint_size (num);
458 gst_ebml_write_element_id (buf, id);
459 gst_ebml_write_element_size (buf, size);
460 gst_ebml_write_set_uint (buf, num, size);
461 gst_ebml_write_element_push (ebml, buf);
466 * gst_ebml_write_sint:
467 * @ebml: #GstEbmlWrite
469 * @num: Number to be written.
471 * Write sint element.
474 gst_ebml_write_sint (GstEbmlWrite * ebml, guint32 id, gint64 num)
476 GstBuffer *buf = gst_ebml_write_element_new (ebml, sizeof (num));
478 /* if the signed number is on the edge of a extra-byte,
479 * then we'll fall over when detecting it. Example: if I
480 * have a number (-)0x8000 (G_MINSHORT), then my abs()<<1
481 * will be 0x10000; this is G_MAXUSHORT+1! So: if (<0) -1. */
482 guint64 unum = (num < 0 ? (-num - 1) << 1 : num << 1);
483 guint size = gst_ebml_write_get_uint_size (unum);
489 unum = 0x80 << (size - 1);
491 unum |= 0x80 << (size - 1);
495 gst_ebml_write_element_id (buf, id);
496 gst_ebml_write_element_size (buf, size);
497 gst_ebml_write_set_uint (buf, unum, size);
498 gst_ebml_write_element_push (ebml, buf);
503 * gst_ebml_write_float:
504 * @ebml: #GstEbmlWrite
506 * @num: Number to be written.
508 * Write float element.
511 gst_ebml_write_float (GstEbmlWrite * ebml, guint32 id, gdouble num)
513 #if (G_BYTE_ORDER == G_LITTLE_ENDIAN)
516 GstBuffer *buf = gst_ebml_write_element_new (ebml, sizeof (num));
518 gst_ebml_write_element_id (buf, id);
519 gst_ebml_write_element_size (buf, 8);
520 #if (G_BYTE_ORDER == G_LITTLE_ENDIAN)
521 for (n = 0; n < 8; n++) {
522 GST_BUFFER_DATA (buf)[GST_BUFFER_SIZE (buf)] = ((guint8 *) & num)[7 - n];
523 GST_BUFFER_SIZE (buf) += 1;
526 gst_ebml_write_element_data (buf, (guint8 *) & num, 8);
528 gst_ebml_write_element_push (ebml, buf);
533 * gst_ebml_write_ascii:
534 * @ebml: #GstEbmlWrite
536 * @str: String to be written.
538 * Write string element.
541 gst_ebml_write_ascii (GstEbmlWrite * ebml, guint32 id, const gchar * str)
543 gint len = strlen (str) + 1; /* add trailing '\0' */
544 GstBuffer *buf = gst_ebml_write_element_new (ebml, len);
546 gst_ebml_write_element_id (buf, id);
547 gst_ebml_write_element_size (buf, len);
548 gst_ebml_write_element_data (buf, (guint8 *) str, len);
549 gst_ebml_write_element_push (ebml, buf);
554 * gst_ebml_write_utf8:
555 * @ebml: #GstEbmlWrite
557 * @str: String to be written.
559 * Write utf8 encoded string element.
562 gst_ebml_write_utf8 (GstEbmlWrite * ebml, guint32 id, const gchar * str)
564 gst_ebml_write_ascii (ebml, id, str);
569 * gst_ebml_write_date:
570 * @ebml: #GstEbmlWrite
572 * @date: Date in seconds since the unix epoch.
574 * Write date element.
577 gst_ebml_write_date (GstEbmlWrite * ebml, guint32 id, gint64 date)
579 gst_ebml_write_sint (ebml, id, (date - GST_EBML_DATE_OFFSET) * GST_SECOND);
583 * gst_ebml_write_master_start:
584 * @ebml: #GstEbmlWrite
587 * Start wiriting mater element.
589 * Master writing is annoying. We use a size marker of
590 * the max. allowed length, so that we can later fill it
593 * Returns: Master starting position.
596 gst_ebml_write_master_start (GstEbmlWrite * ebml, guint32 id)
598 guint64 pos = ebml->pos, t;
599 GstBuffer *buf = gst_ebml_write_element_new (ebml, 0);
601 t = GST_BUFFER_SIZE (buf);
602 gst_ebml_write_element_id (buf, id);
603 pos += GST_BUFFER_SIZE (buf) - t;
604 gst_ebml_write_element_size (buf, GST_EBML_SIZE_UNKNOWN);
605 gst_ebml_write_element_push (ebml, buf);
612 * gst_ebml_write_master_finish:
613 * @ebml: #GstEbmlWrite
614 * @startpos: Master starting position.
616 * Finish writing master element.
619 gst_ebml_write_master_finish (GstEbmlWrite * ebml, guint64 startpos)
621 guint64 pos = ebml->pos;
624 gst_ebml_write_seek (ebml, startpos);
625 buf = gst_ebml_write_element_new (ebml, 0);
627 GUINT64_TO_BE ((G_GINT64_CONSTANT (1) << 56) | (pos - startpos - 8));
628 memcpy (GST_BUFFER_DATA (buf) + GST_BUFFER_SIZE (buf), (guint8 *) & startpos,
630 GST_BUFFER_SIZE (buf) += 8;
631 gst_ebml_write_element_push (ebml, buf);
632 gst_ebml_write_seek (ebml, pos);
637 * gst_ebml_write_binary:
638 * @ebml: #GstEbmlWrite
640 * @binary: Data to be written.
641 * @length: Length of the data
643 * Write an element with binary data.
646 gst_ebml_write_binary (GstEbmlWrite * ebml,
647 guint32 id, guint8 * binary, guint64 length)
649 GstBuffer *buf = gst_ebml_write_element_new (ebml, length);
651 gst_ebml_write_element_id (buf, id);
652 gst_ebml_write_element_size (buf, length);
653 gst_ebml_write_element_data (buf, binary, length);
654 gst_ebml_write_element_push (ebml, buf);
659 * gst_ebml_write_buffer_header:
660 * @ebml: #GstEbmlWrite
662 * @length: Length of the data
664 * Write header of the binary element (use with gst_ebml_write_buffer function).
666 * For things like video frames and audio samples,
667 * you want to use this function, as it doesn't have
668 * the overhead of memcpy() that other functions
669 * such as write_binary() do have.
672 gst_ebml_write_buffer_header (GstEbmlWrite * ebml, guint32 id, guint64 length)
674 GstBuffer *buf = gst_ebml_write_element_new (ebml, 0);
676 gst_ebml_write_element_id (buf, id);
677 gst_ebml_write_element_size (buf, length);
678 gst_ebml_write_element_push (ebml, buf);
683 * gst_ebml_write_buffer:
684 * @ebml: #GstEbmlWrite
685 * @data: #GstBuffer cointaining the data.
687 * Write binary element (see gst_ebml_write_buffer_header).
690 gst_ebml_write_buffer (GstEbmlWrite * ebml, GstBuffer * data)
692 gst_ebml_write_element_push (ebml, data);
697 * gst_ebml_replace_uint:
698 * @ebml: #GstEbmlWrite
699 * @pos: Position of the uint that should be replaced.
702 * Replace uint with a new value.
704 * When replacing a uint, we assume that it is *always*
705 * 8-byte, since that's the safest guess we can do. This
706 * is just for simplicity.
708 * FIXME: this function needs to be replaced with something
709 * proper. This is a crude hack.
712 gst_ebml_replace_uint (GstEbmlWrite * ebml, guint64 pos, guint64 num)
714 guint64 oldpos = ebml->pos;
715 GstBuffer *buf = gst_buffer_new_and_alloc (8);
717 gst_ebml_write_seek (ebml, pos);
718 GST_BUFFER_SIZE (buf) = 0;
719 gst_ebml_write_set_uint (buf, num, 8);
720 gst_ebml_write_element_push (ebml, buf);
721 gst_ebml_write_seek (ebml, oldpos);
725 * gst_ebml_write_header:
726 * @ebml: #GstEbmlWrite
727 * @doctype: Document type.
728 * @version: Document type version.
733 gst_ebml_write_header (GstEbmlWrite * ebml, gchar * doctype, guint version)
737 /* write the basic EBML header */
738 gst_ebml_write_set_cache (ebml, 0x40);
739 pos = gst_ebml_write_master_start (ebml, GST_EBML_ID_HEADER);
740 #if (GST_EBML_VERSION != 1)
741 gst_ebml_write_uint (ebml, GST_EBML_ID_EBMLVERSION, GST_EBML_VERSION);
742 gst_ebml_write_uint (ebml, GST_EBML_ID_EBMLREADVERSION, GST_EBML_VERSION);
745 /* we don't write these until they're "non-default" (never!) */
746 gst_ebml_write_uint (ebml, GST_EBML_ID_EBMLMAXIDLENGTH, sizeof (guint32));
747 gst_ebml_write_uint (ebml, GST_EBML_ID_EBMLMAXSIZELENGTH, sizeof (guint64));
749 gst_ebml_write_ascii (ebml, GST_EBML_ID_DOCTYPE, doctype);
750 gst_ebml_write_uint (ebml, GST_EBML_ID_DOCTYPEVERSION, version);
751 gst_ebml_write_uint (ebml, GST_EBML_ID_DOCTYPEREADVERSION, version);
752 gst_ebml_write_master_finish (ebml, pos);
753 gst_ebml_write_flush_cache (ebml);