diff options
author | Thiago Sousa Santos <thiagossantos@gmail.com> | 2008-11-08 02:00:58 +0000 |
---|---|---|
committer | David Schleef <ds@schleef.org> | 2008-11-08 02:00:58 +0000 |
commit | e8d0f5e3b34d1657a0afe7af421d349faca216ee (patch) | |
tree | 06964dc59f8be5bea086a5c98a9183a002e0174d /gst/qtmux/descriptors.c | |
parent | 5e8f80a9f5d1a9528ff016f05ef62da24f2b546a (diff) | |
download | gst-plugins-bad-e8d0f5e3b34d1657a0afe7af421d349faca216ee.tar.gz gst-plugins-bad-e8d0f5e3b34d1657a0afe7af421d349faca216ee.tar.bz2 gst-plugins-bad-e8d0f5e3b34d1657a0afe7af421d349faca216ee.zip |
Copy qtmux from revision 148 of the gst-qtmux repository.
Original commit message from CVS:
patch by: Thiago Sousa Santos <thiagossantos@gmail.com>
* configure.ac:
* gst/qtmux/Makefile.am:
* gst/qtmux/atoms.c:
* gst/qtmux/atoms.h:
* gst/qtmux/descriptors.c:
* gst/qtmux/descriptors.h:
* gst/qtmux/fourcc.h:
* gst/qtmux/ftypcc.h:
* gst/qtmux/gstqtmux.c:
* gst/qtmux/gstqtmux.h:
* gst/qtmux/gstqtmuxmap.c:
* gst/qtmux/gstqtmuxmap.h:
* gst/qtmux/properties.c:
* gst/qtmux/properties.h:
Copy qtmux from revision 148 of the gst-qtmux repository.
Fixes #550280.
Diffstat (limited to 'gst/qtmux/descriptors.c')
-rw-r--r-- | gst/qtmux/descriptors.c | 442 |
1 files changed, 442 insertions, 0 deletions
diff --git a/gst/qtmux/descriptors.c b/gst/qtmux/descriptors.c new file mode 100644 index 00000000..edb6b196 --- /dev/null +++ b/gst/qtmux/descriptors.c @@ -0,0 +1,442 @@ +/* Quicktime muxer plugin for GStreamer + * Copyright (C) 2008 Thiago Sousa Santos <thiagoss@embedded.ufcg.edu.br> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include "descriptors.h" + +/** + * Some mp4 structures (descriptors) use a coding scheme for + * representing its size. + * It is grouped in bytes. The 1st bit set to 1 means we need another byte, + * 0 otherwise. The remaining 7 bits are the useful values. + * + * The next set of functions handle those values + */ + +/** + * Gets an unsigned integer and packs it into a 'expandable size' format + * (as used by mp4 descriptors) + * @size: the integer to be parsed + * @ptr: the array to place the result + * @array_size: the size of ptr array + */ +static void +expandable_size_parse (guint64 size, guint8 * ptr, guint32 array_size) +{ + int index = 0; + + memset (ptr, 0, sizeof (array_size)); + while (size > 0 && index < array_size) { + ptr[index++] = (size > 0x7F ? 0x80 : 0x0) | (size & 0x7F); + size = size >> 7; + } +} + +/** + * Gets how many positions in an array holding an 'expandable size' + * are really used + * + * @ptr: the array with the 'expandable size' + * @array_size: the size of ptr array + * + * Returns: the number of really used positions + */ +static guint64 +expandable_size_get_length (guint8 * ptr, guint32 array_size) +{ + gboolean next = TRUE; + guint32 index = 0; + + while (next && index < array_size) { + next = ((ptr[index] & 0x80) == 1); + index++; + } + return index; +} + +/* + * Initializers below + */ + +static void +desc_base_descriptor_init (BaseDescriptor * bd, guint8 tag, guint32 size) +{ + bd->tag = tag; + expandable_size_parse (size, bd->size, 4); +} + +static void +desc_dec_specific_info_init (DecoderSpecificInfoDescriptor * dsid) +{ + desc_base_descriptor_init (&dsid->base, DECODER_SPECIFIC_INFO_TAG, 0); + dsid->length = 0; + dsid->data = NULL; +} + +DecoderSpecificInfoDescriptor * +desc_dec_specific_info_new () +{ + DecoderSpecificInfoDescriptor *desc = + g_new0 (DecoderSpecificInfoDescriptor, 1); + desc_dec_specific_info_init (desc); + return desc; +} + +static void +desc_dec_conf_desc_init (DecoderConfigDescriptor * dcd) +{ + desc_base_descriptor_init (&dcd->base, DECODER_CONFIG_DESC_TAG, 0); + dcd->dec_specific_info = NULL; +} + +static void +desc_sl_conf_desc_init (SLConfigDescriptor * sl) +{ + desc_base_descriptor_init (&sl->base, SL_CONFIG_DESC_TAG, 0); + sl->predefined = 0x2; +} + +void +desc_es_init (ESDescriptor * es) +{ + desc_base_descriptor_init (&es->base, ES_DESCRIPTOR_TAG, 0); + + es->id = 0; + es->flags = 0; + es->depends_on_es_id = 0; + es->ocr_es_id = 0; + es->url_length = 0; + es->url_string = NULL; + + desc_dec_conf_desc_init (&es->dec_conf_desc); + desc_sl_conf_desc_init (&es->sl_conf_desc); +} + +ESDescriptor * +desc_es_descriptor_new () +{ + ESDescriptor *es = g_new0 (ESDescriptor, 1); + + desc_es_init (es); + return es; +} + +/* + * Deinitializers/Destructors below + */ + +static void +desc_base_descriptor_clear (BaseDescriptor * base) +{ +} + +void +desc_dec_specific_info_free (DecoderSpecificInfoDescriptor * dsid) +{ + desc_base_descriptor_clear (&dsid->base); + if (dsid->data) { + g_free (dsid->data); + dsid->data = NULL; + } + g_free (dsid); +} + +static void +desc_dec_conf_desc_clear (DecoderConfigDescriptor * dec) +{ + desc_base_descriptor_clear (&dec->base); + if (dec->dec_specific_info) { + desc_dec_specific_info_free (dec->dec_specific_info); + } +} + +static void +desc_sl_config_descriptor_clear (SLConfigDescriptor * sl) +{ + desc_base_descriptor_clear (&sl->base); +} + +void +desc_es_descriptor_clear (ESDescriptor * es) +{ + desc_base_descriptor_clear (&es->base); + if (es->url_string) { + g_free (es->url_string); + es->url_string = NULL; + } + desc_dec_conf_desc_clear (&es->dec_conf_desc); + desc_sl_config_descriptor_clear (&es->sl_conf_desc); +} + +void +desc_es_descriptor_free (ESDescriptor * es) +{ + desc_es_descriptor_clear (es); + g_free (es); +} + +/* + * Size handling functions below + */ + +void +desc_dec_specific_info_alloc_data (DecoderSpecificInfoDescriptor * dsid, + guint32 size) +{ + if (dsid->data) { + g_free (dsid->data); + } + dsid->data = g_new0 (guint8, size); + dsid->length = size; +} + +static void +desc_base_descriptor_set_size (BaseDescriptor * bd, guint32 size) +{ + expandable_size_parse (size, bd->size, 4); +} + +static guint64 +desc_base_descriptor_get_size (BaseDescriptor * bd) +{ + guint64 size = 0; + + size += sizeof (guint8); + size += expandable_size_get_length (bd->size, 4) * sizeof (guint8); + return size; +} + +static guint64 +desc_sl_config_descriptor_get_size (SLConfigDescriptor * sl_desc) +{ + guint64 size = 0; + guint64 extra_size = 0; + + size += desc_base_descriptor_get_size (&sl_desc->base); + /* predefined */ + extra_size += sizeof (guint8); + + desc_base_descriptor_set_size (&sl_desc->base, extra_size); + + return size + extra_size; +} + +static guint64 +desc_dec_specific_info_get_size (DecoderSpecificInfoDescriptor * dsid) +{ + guint64 size = 0; + guint64 extra_size = 0; + + size += desc_base_descriptor_get_size (&dsid->base); + extra_size += sizeof (guint8) * dsid->length; + desc_base_descriptor_set_size (&dsid->base, extra_size); + return size + extra_size; +} + +static guint64 +desc_dec_config_descriptor_get_size (DecoderConfigDescriptor * dec_desc) +{ + guint64 size = 0; + guint64 extra_size = 0; + + size += desc_base_descriptor_get_size (&dec_desc->base); + /* object type */ + extra_size += sizeof (guint8); + /* stream type */ + extra_size += sizeof (guint8); + /* buffer size */ + extra_size += sizeof (guint8) * 3; + /* max bitrate */ + extra_size += sizeof (guint32); + /* avg bitrate */ + extra_size += sizeof (guint32); + if (dec_desc->dec_specific_info) { + extra_size += desc_dec_specific_info_get_size (dec_desc->dec_specific_info); + } + + desc_base_descriptor_set_size (&dec_desc->base, extra_size); + return size + extra_size; +} + +static guint64 +desc_es_descriptor_get_size (ESDescriptor * es) +{ + guint64 size = 0; + guint64 extra_size = 0; + + size += desc_base_descriptor_get_size (&es->base); + /* id */ + extra_size += sizeof (guint16); + /* flags */ + extra_size += sizeof (guint8); + /* depends_on_es_id */ + if (es->flags & 0x80) { + extra_size += sizeof (guint16); + } + if (es->flags & 0x40) { + /* url_length */ + extra_size += sizeof (guint8); + /* url */ + extra_size += sizeof (gchar) * es->url_length; + } + if (es->flags & 0x20) { + /* ocr_es_id */ + extra_size += sizeof (guint16); + } + + extra_size += desc_dec_config_descriptor_get_size (&es->dec_conf_desc); + extra_size += desc_sl_config_descriptor_get_size (&es->sl_conf_desc); + + desc_base_descriptor_set_size (&es->base, extra_size); + + return size + extra_size; +} + +static gboolean +desc_es_descriptor_check_stream_dependency (ESDescriptor * es) +{ + return es->flags & 0x80; +} + +static gboolean +desc_es_descriptor_check_url_flag (ESDescriptor * es) +{ + return es->flags & 0x40; +} + +static gboolean +desc_es_descriptor_check_ocr (ESDescriptor * es) +{ + return es->flags & 0x20; +} + +/* Copy/Serializations Functions below */ + +static guint64 +desc_base_descriptor_copy_data (BaseDescriptor * desc, guint8 ** buffer, + guint64 * size, guint64 * offset) +{ + guint64 original_offset = *offset; + + prop_copy_uint8 (desc->tag, buffer, size, offset); + prop_copy_uint8_array (desc->size, expandable_size_get_length (desc->size, 4), + buffer, size, offset); + return original_offset - *offset; +} + +static guint64 +desc_sl_config_descriptor_copy_data (SLConfigDescriptor * desc, + guint8 ** buffer, guint64 * size, guint64 * offset) +{ + guint64 original_offset = *offset; + + if (!desc_base_descriptor_copy_data (&desc->base, buffer, size, offset)) { + return 0; + } + /* predefined attribute */ + prop_copy_uint8 (desc->predefined, buffer, size, offset); + + return *offset - original_offset; +} + +static guint64 +desc_dec_specific_info_copy_data (DecoderSpecificInfoDescriptor * desc, + guint8 ** buffer, guint64 * size, guint64 * offset) +{ + guint64 original_offset = *offset; + + if (!desc_base_descriptor_copy_data (&desc->base, buffer, size, offset)) { + return 0; + } + prop_copy_uint8_array (desc->data, desc->length, buffer, size, offset); + + return *offset - original_offset; +} + +static guint64 +desc_dec_config_descriptor_copy_data (DecoderConfigDescriptor * desc, + guint8 ** buffer, guint64 * size, guint64 * offset) +{ + guint64 original_offset = *offset; + + if (!desc_base_descriptor_copy_data (&desc->base, buffer, size, offset)) { + return 0; + } + + prop_copy_uint8 (desc->object_type, buffer, size, offset); + + prop_copy_uint8 (desc->stream_type, buffer, size, offset); + prop_copy_uint8_array (desc->buffer_size_DB, 3, buffer, size, offset); + + prop_copy_uint32 (desc->max_bitrate, buffer, size, offset); + prop_copy_uint32 (desc->avg_bitrate, buffer, size, offset); + + if (desc->dec_specific_info) { + if (!desc_dec_specific_info_copy_data (desc->dec_specific_info, buffer, + size, offset)) { + return 0; + } + } + + return *offset - original_offset; +} + +guint64 +desc_es_descriptor_copy_data (ESDescriptor * desc, guint8 ** buffer, + guint64 * size, guint64 * offset) +{ + guint64 desc_size; + guint64 original_offset = *offset; + + /* must call this twice to have size fields of all contained descriptors set + * correctly, and to have the size of the size fields taken into account */ + desc_size = desc_es_descriptor_get_size (desc); + desc_size = desc_es_descriptor_get_size (desc); + + if (!desc_base_descriptor_copy_data (&desc->base, buffer, size, offset)) { + return 0; + } + /* id and flags */ + prop_copy_uint16 (desc->id, buffer, size, offset); + prop_copy_uint8 (desc->flags, buffer, size, offset); + + if (desc_es_descriptor_check_stream_dependency (desc)) { + prop_copy_uint16 (desc->depends_on_es_id, buffer, size, offset); + } + + if (desc_es_descriptor_check_url_flag (desc)) { + prop_copy_size_string (desc->url_string, desc->url_length, buffer, size, + offset); + } + + if (desc_es_descriptor_check_ocr (desc)) { + prop_copy_uint16 (desc->ocr_es_id, buffer, size, offset); + } + + if (!desc_dec_config_descriptor_copy_data (&desc->dec_conf_desc, buffer, size, + offset)) { + return 0; + } + + if (!desc_sl_config_descriptor_copy_data (&desc->sl_conf_desc, buffer, size, + offset)) { + return 0; + } + + return *offset - original_offset; +} |