1 /* Quicktime muxer plugin for GStreamer
2 * Copyright (C) 2008 Thiago Sousa Santos <thiagoss@embedded.ufcg.edu.br>
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Library General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Library General Public License for more details.
14 * You should have received a copy of the GNU Library General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
17 * Boston, MA 02110-1301, USA.
20 * Unless otherwise indicated, Source Code is licensed under MIT license.
21 * See further explanation attached in License Statement (distributed in the file
24 * Permission is hereby granted, free of charge, to any person obtaining a copy of
25 * this software and associated documentation files (the "Software"), to deal in
26 * the Software without restriction, including without limitation the rights to
27 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
28 * of the Software, and to permit persons to whom the Software is furnished to do
29 * so, subject to the following conditions:
31 * The above copyright notice and this permission notice shall be included in all
32 * copies or substantial portions of the Software.
34 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
35 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
36 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
37 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
38 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
39 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
43 #include "descriptors.h"
46 * Some mp4 structures (descriptors) use a coding scheme for
47 * representing its size.
48 * It is grouped in bytes. The 1st bit set to 1 means we need another byte,
49 * 0 otherwise. The remaining 7 bits are the useful values.
51 * The next set of functions handle those values
55 * Gets an unsigned integer and packs it into a 'expandable size' format
56 * (as used by mp4 descriptors)
57 * @size: the integer to be parsed
58 * @ptr: the array to place the result
59 * @array_size: the size of ptr array
62 expandable_size_parse (guint64 size, guint8 * ptr, guint32 array_size)
66 memset (ptr, 0, sizeof (array_size));
67 while (size > 0 && index < array_size) {
68 ptr[index++] = (size > 0x7F ? 0x80 : 0x0) | (size & 0x7F);
74 * Gets how many positions in an array holding an 'expandable size'
77 * @ptr: the array with the 'expandable size'
78 * @array_size: the size of ptr array
80 * Returns: the number of really used positions
83 expandable_size_get_length (guint8 * ptr, guint32 array_size)
88 while (next && index < array_size) {
89 next = (ptr[index] & 0x80);
100 desc_base_descriptor_init (BaseDescriptor * bd, guint8 tag, guint32 size)
103 expandable_size_parse (size, bd->size, 4);
107 desc_dec_specific_info_init (DecoderSpecificInfoDescriptor * dsid)
109 desc_base_descriptor_init (&dsid->base, DECODER_SPECIFIC_INFO_TAG, 0);
114 DecoderSpecificInfoDescriptor *
115 desc_dec_specific_info_new (void)
117 DecoderSpecificInfoDescriptor *desc =
118 g_new0 (DecoderSpecificInfoDescriptor, 1);
119 desc_dec_specific_info_init (desc);
124 desc_dec_conf_desc_init (DecoderConfigDescriptor * dcd)
126 desc_base_descriptor_init (&dcd->base, DECODER_CONFIG_DESC_TAG, 0);
127 dcd->dec_specific_info = NULL;
131 desc_sl_conf_desc_init (SLConfigDescriptor * sl)
133 desc_base_descriptor_init (&sl->base, SL_CONFIG_DESC_TAG, 0);
134 sl->predefined = 0x2;
138 desc_es_init (ESDescriptor * es)
140 desc_base_descriptor_init (&es->base, ES_DESCRIPTOR_TAG, 0);
144 es->depends_on_es_id = 0;
147 es->url_string = NULL;
149 desc_dec_conf_desc_init (&es->dec_conf_desc);
150 desc_sl_conf_desc_init (&es->sl_conf_desc);
154 desc_es_descriptor_new (void)
156 ESDescriptor *es = g_new0 (ESDescriptor, 1);
163 * Deinitializers/Destructors below
167 desc_base_descriptor_clear (BaseDescriptor * base)
172 desc_dec_specific_info_free (DecoderSpecificInfoDescriptor * dsid)
174 desc_base_descriptor_clear (&dsid->base);
183 desc_dec_conf_desc_clear (DecoderConfigDescriptor * dec)
185 desc_base_descriptor_clear (&dec->base);
186 if (dec->dec_specific_info) {
187 desc_dec_specific_info_free (dec->dec_specific_info);
192 desc_sl_config_descriptor_clear (SLConfigDescriptor * sl)
194 desc_base_descriptor_clear (&sl->base);
198 desc_es_descriptor_clear (ESDescriptor * es)
200 desc_base_descriptor_clear (&es->base);
201 if (es->url_string) {
202 g_free (es->url_string);
203 es->url_string = NULL;
205 desc_dec_conf_desc_clear (&es->dec_conf_desc);
206 desc_sl_config_descriptor_clear (&es->sl_conf_desc);
210 * Size handling functions below
214 desc_dec_specific_info_alloc_data (DecoderSpecificInfoDescriptor * dsid,
220 dsid->data = g_new0 (guint8, size);
225 desc_base_descriptor_set_size (BaseDescriptor * bd, guint32 size)
227 expandable_size_parse (size, bd->size, 4);
231 desc_base_descriptor_get_size (BaseDescriptor * bd)
235 size += sizeof (guint8);
236 size += expandable_size_get_length (bd->size, 4) * sizeof (guint8);
241 desc_sl_config_descriptor_get_size (SLConfigDescriptor * sl_desc)
244 guint64 extra_size = 0;
246 size += desc_base_descriptor_get_size (&sl_desc->base);
248 extra_size += sizeof (guint8);
250 desc_base_descriptor_set_size (&sl_desc->base, extra_size);
252 return size + extra_size;
256 desc_dec_specific_info_get_size (DecoderSpecificInfoDescriptor * dsid)
259 guint64 extra_size = 0;
261 size += desc_base_descriptor_get_size (&dsid->base);
262 extra_size += sizeof (guint8) * dsid->length;
263 desc_base_descriptor_set_size (&dsid->base, extra_size);
264 return size + extra_size;
268 desc_dec_config_descriptor_get_size (DecoderConfigDescriptor * dec_desc)
271 guint64 extra_size = 0;
273 size += desc_base_descriptor_get_size (&dec_desc->base);
275 extra_size += sizeof (guint8);
277 extra_size += sizeof (guint8);
279 extra_size += sizeof (guint8) * 3;
281 extra_size += sizeof (guint32);
283 extra_size += sizeof (guint32);
284 if (dec_desc->dec_specific_info) {
285 extra_size += desc_dec_specific_info_get_size (dec_desc->dec_specific_info);
288 desc_base_descriptor_set_size (&dec_desc->base, extra_size);
289 return size + extra_size;
293 desc_es_descriptor_get_size (ESDescriptor * es)
296 guint64 extra_size = 0;
298 size += desc_base_descriptor_get_size (&es->base);
300 extra_size += sizeof (guint16);
302 extra_size += sizeof (guint8);
303 /* depends_on_es_id */
304 if (es->flags & 0x80) {
305 extra_size += sizeof (guint16);
307 if (es->flags & 0x40) {
309 extra_size += sizeof (guint8);
311 extra_size += sizeof (gchar) * es->url_length;
313 if (es->flags & 0x20) {
315 extra_size += sizeof (guint16);
318 extra_size += desc_dec_config_descriptor_get_size (&es->dec_conf_desc);
319 extra_size += desc_sl_config_descriptor_get_size (&es->sl_conf_desc);
321 desc_base_descriptor_set_size (&es->base, extra_size);
323 return size + extra_size;
327 desc_es_descriptor_check_stream_dependency (ESDescriptor * es)
329 return es->flags & 0x80;
333 desc_es_descriptor_check_url_flag (ESDescriptor * es)
335 return es->flags & 0x40;
339 desc_es_descriptor_check_ocr (ESDescriptor * es)
341 return es->flags & 0x20;
344 /* Copy/Serializations Functions below */
347 desc_base_descriptor_copy_data (BaseDescriptor * desc, guint8 ** buffer,
348 guint64 * size, guint64 * offset)
350 guint64 original_offset = *offset;
352 prop_copy_uint8 (desc->tag, buffer, size, offset);
353 prop_copy_uint8_array (desc->size, expandable_size_get_length (desc->size, 4),
354 buffer, size, offset);
355 return original_offset - *offset;
359 desc_sl_config_descriptor_copy_data (SLConfigDescriptor * desc,
360 guint8 ** buffer, guint64 * size, guint64 * offset)
362 guint64 original_offset = *offset;
364 if (!desc_base_descriptor_copy_data (&desc->base, buffer, size, offset)) {
367 /* predefined attribute */
368 prop_copy_uint8 (desc->predefined, buffer, size, offset);
370 return *offset - original_offset;
374 desc_dec_specific_info_copy_data (DecoderSpecificInfoDescriptor * desc,
375 guint8 ** buffer, guint64 * size, guint64 * offset)
377 guint64 original_offset = *offset;
379 if (!desc_base_descriptor_copy_data (&desc->base, buffer, size, offset)) {
382 prop_copy_uint8_array (desc->data, desc->length, buffer, size, offset);
384 return *offset - original_offset;
388 desc_dec_config_descriptor_copy_data (DecoderConfigDescriptor * desc,
389 guint8 ** buffer, guint64 * size, guint64 * offset)
391 guint64 original_offset = *offset;
393 if (!desc_base_descriptor_copy_data (&desc->base, buffer, size, offset)) {
397 prop_copy_uint8 (desc->object_type, buffer, size, offset);
399 prop_copy_uint8 (desc->stream_type, buffer, size, offset);
400 prop_copy_uint8_array (desc->buffer_size_DB, 3, buffer, size, offset);
402 prop_copy_uint32 (desc->max_bitrate, buffer, size, offset);
403 prop_copy_uint32 (desc->avg_bitrate, buffer, size, offset);
405 if (desc->dec_specific_info) {
406 if (!desc_dec_specific_info_copy_data (desc->dec_specific_info, buffer,
412 return *offset - original_offset;
416 desc_es_descriptor_copy_data (ESDescriptor * desc, guint8 ** buffer,
417 guint64 * size, guint64 * offset)
419 guint64 original_offset = *offset;
421 /* must call this twice to have size fields of all contained descriptors set
422 * correctly, and to have the size of the size fields taken into account */
423 desc_es_descriptor_get_size (desc);
424 desc_es_descriptor_get_size (desc);
426 if (!desc_base_descriptor_copy_data (&desc->base, buffer, size, offset)) {
430 prop_copy_uint16 (desc->id, buffer, size, offset);
431 prop_copy_uint8 (desc->flags, buffer, size, offset);
433 if (desc_es_descriptor_check_stream_dependency (desc)) {
434 prop_copy_uint16 (desc->depends_on_es_id, buffer, size, offset);
437 if (desc_es_descriptor_check_url_flag (desc)) {
438 prop_copy_size_string (desc->url_string, desc->url_length, buffer, size,
442 if (desc_es_descriptor_check_ocr (desc)) {
443 prop_copy_uint16 (desc->ocr_es_id, buffer, size, offset);
446 if (!desc_dec_config_descriptor_copy_data (&desc->dec_conf_desc, buffer, size,
451 if (!desc_sl_config_descriptor_copy_data (&desc->sl_conf_desc, buffer, size,
456 return *offset - original_offset;