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., 59 Temple Place - Suite 330,
17 * Boston, MA 02111-1307, USA.
20 #include "descriptors.h"
23 * Some mp4 structures (descriptors) use a coding scheme for
24 * representing its size.
25 * It is grouped in bytes. The 1st bit set to 1 means we need another byte,
26 * 0 otherwise. The remaining 7 bits are the useful values.
28 * The next set of functions handle those values
32 * Gets an unsigned integer and packs it into a 'expandable size' format
33 * (as used by mp4 descriptors)
34 * @size: the integer to be parsed
35 * @ptr: the array to place the result
36 * @array_size: the size of ptr array
39 expandable_size_parse (guint64 size, guint8 * ptr, guint32 array_size)
43 memset (ptr, 0, sizeof (array_size));
44 while (size > 0 && index < array_size) {
45 ptr[index++] = (size > 0x7F ? 0x80 : 0x0) | (size & 0x7F);
51 * Gets how many positions in an array holding an 'expandable size'
54 * @ptr: the array with the 'expandable size'
55 * @array_size: the size of ptr array
57 * Returns: the number of really used positions
60 expandable_size_get_length (guint8 * ptr, guint32 array_size)
65 while (next && index < array_size) {
66 next = ((ptr[index] & 0x80) == 1);
77 desc_base_descriptor_init (BaseDescriptor * bd, guint8 tag, guint32 size)
80 expandable_size_parse (size, bd->size, 4);
84 desc_dec_specific_info_init (DecoderSpecificInfoDescriptor * dsid)
86 desc_base_descriptor_init (&dsid->base, DECODER_SPECIFIC_INFO_TAG, 0);
91 DecoderSpecificInfoDescriptor *
92 desc_dec_specific_info_new ()
94 DecoderSpecificInfoDescriptor *desc =
95 g_new0 (DecoderSpecificInfoDescriptor, 1);
96 desc_dec_specific_info_init (desc);
101 desc_dec_conf_desc_init (DecoderConfigDescriptor * dcd)
103 desc_base_descriptor_init (&dcd->base, DECODER_CONFIG_DESC_TAG, 0);
104 dcd->dec_specific_info = NULL;
108 desc_sl_conf_desc_init (SLConfigDescriptor * sl)
110 desc_base_descriptor_init (&sl->base, SL_CONFIG_DESC_TAG, 0);
111 sl->predefined = 0x2;
115 desc_es_init (ESDescriptor * es)
117 desc_base_descriptor_init (&es->base, ES_DESCRIPTOR_TAG, 0);
121 es->depends_on_es_id = 0;
124 es->url_string = NULL;
126 desc_dec_conf_desc_init (&es->dec_conf_desc);
127 desc_sl_conf_desc_init (&es->sl_conf_desc);
131 desc_es_descriptor_new ()
133 ESDescriptor *es = g_new0 (ESDescriptor, 1);
140 * Deinitializers/Destructors below
144 desc_base_descriptor_clear (BaseDescriptor * base)
149 desc_dec_specific_info_free (DecoderSpecificInfoDescriptor * dsid)
151 desc_base_descriptor_clear (&dsid->base);
160 desc_dec_conf_desc_clear (DecoderConfigDescriptor * dec)
162 desc_base_descriptor_clear (&dec->base);
163 if (dec->dec_specific_info) {
164 desc_dec_specific_info_free (dec->dec_specific_info);
169 desc_sl_config_descriptor_clear (SLConfigDescriptor * sl)
171 desc_base_descriptor_clear (&sl->base);
175 desc_es_descriptor_clear (ESDescriptor * es)
177 desc_base_descriptor_clear (&es->base);
178 if (es->url_string) {
179 g_free (es->url_string);
180 es->url_string = NULL;
182 desc_dec_conf_desc_clear (&es->dec_conf_desc);
183 desc_sl_config_descriptor_clear (&es->sl_conf_desc);
187 desc_es_descriptor_free (ESDescriptor * es)
189 desc_es_descriptor_clear (es);
194 * Size handling functions below
198 desc_dec_specific_info_alloc_data (DecoderSpecificInfoDescriptor * dsid,
204 dsid->data = g_new0 (guint8, size);
209 desc_base_descriptor_set_size (BaseDescriptor * bd, guint32 size)
211 expandable_size_parse (size, bd->size, 4);
215 desc_base_descriptor_get_size (BaseDescriptor * bd)
219 size += sizeof (guint8);
220 size += expandable_size_get_length (bd->size, 4) * sizeof (guint8);
225 desc_sl_config_descriptor_get_size (SLConfigDescriptor * sl_desc)
228 guint64 extra_size = 0;
230 size += desc_base_descriptor_get_size (&sl_desc->base);
232 extra_size += sizeof (guint8);
234 desc_base_descriptor_set_size (&sl_desc->base, extra_size);
236 return size + extra_size;
240 desc_dec_specific_info_get_size (DecoderSpecificInfoDescriptor * dsid)
243 guint64 extra_size = 0;
245 size += desc_base_descriptor_get_size (&dsid->base);
246 extra_size += sizeof (guint8) * dsid->length;
247 desc_base_descriptor_set_size (&dsid->base, extra_size);
248 return size + extra_size;
252 desc_dec_config_descriptor_get_size (DecoderConfigDescriptor * dec_desc)
255 guint64 extra_size = 0;
257 size += desc_base_descriptor_get_size (&dec_desc->base);
259 extra_size += sizeof (guint8);
261 extra_size += sizeof (guint8);
263 extra_size += sizeof (guint8) * 3;
265 extra_size += sizeof (guint32);
267 extra_size += sizeof (guint32);
268 if (dec_desc->dec_specific_info) {
269 extra_size += desc_dec_specific_info_get_size (dec_desc->dec_specific_info);
272 desc_base_descriptor_set_size (&dec_desc->base, extra_size);
273 return size + extra_size;
277 desc_es_descriptor_get_size (ESDescriptor * es)
280 guint64 extra_size = 0;
282 size += desc_base_descriptor_get_size (&es->base);
284 extra_size += sizeof (guint16);
286 extra_size += sizeof (guint8);
287 /* depends_on_es_id */
288 if (es->flags & 0x80) {
289 extra_size += sizeof (guint16);
291 if (es->flags & 0x40) {
293 extra_size += sizeof (guint8);
295 extra_size += sizeof (gchar) * es->url_length;
297 if (es->flags & 0x20) {
299 extra_size += sizeof (guint16);
302 extra_size += desc_dec_config_descriptor_get_size (&es->dec_conf_desc);
303 extra_size += desc_sl_config_descriptor_get_size (&es->sl_conf_desc);
305 desc_base_descriptor_set_size (&es->base, extra_size);
307 return size + extra_size;
311 desc_es_descriptor_check_stream_dependency (ESDescriptor * es)
313 return es->flags & 0x80;
317 desc_es_descriptor_check_url_flag (ESDescriptor * es)
319 return es->flags & 0x40;
323 desc_es_descriptor_check_ocr (ESDescriptor * es)
325 return es->flags & 0x20;
328 /* Copy/Serializations Functions below */
331 desc_base_descriptor_copy_data (BaseDescriptor * desc, guint8 ** buffer,
332 guint64 * size, guint64 * offset)
334 guint64 original_offset = *offset;
336 prop_copy_uint8 (desc->tag, buffer, size, offset);
337 prop_copy_uint8_array (desc->size, expandable_size_get_length (desc->size, 4),
338 buffer, size, offset);
339 return original_offset - *offset;
343 desc_sl_config_descriptor_copy_data (SLConfigDescriptor * desc,
344 guint8 ** buffer, guint64 * size, guint64 * offset)
346 guint64 original_offset = *offset;
348 if (!desc_base_descriptor_copy_data (&desc->base, buffer, size, offset)) {
351 /* predefined attribute */
352 prop_copy_uint8 (desc->predefined, buffer, size, offset);
354 return *offset - original_offset;
358 desc_dec_specific_info_copy_data (DecoderSpecificInfoDescriptor * desc,
359 guint8 ** buffer, guint64 * size, guint64 * offset)
361 guint64 original_offset = *offset;
363 if (!desc_base_descriptor_copy_data (&desc->base, buffer, size, offset)) {
366 prop_copy_uint8_array (desc->data, desc->length, buffer, size, offset);
368 return *offset - original_offset;
372 desc_dec_config_descriptor_copy_data (DecoderConfigDescriptor * desc,
373 guint8 ** buffer, guint64 * size, guint64 * offset)
375 guint64 original_offset = *offset;
377 if (!desc_base_descriptor_copy_data (&desc->base, buffer, size, offset)) {
381 prop_copy_uint8 (desc->object_type, buffer, size, offset);
383 prop_copy_uint8 (desc->stream_type, buffer, size, offset);
384 prop_copy_uint8_array (desc->buffer_size_DB, 3, buffer, size, offset);
386 prop_copy_uint32 (desc->max_bitrate, buffer, size, offset);
387 prop_copy_uint32 (desc->avg_bitrate, buffer, size, offset);
389 if (desc->dec_specific_info) {
390 if (!desc_dec_specific_info_copy_data (desc->dec_specific_info, buffer,
396 return *offset - original_offset;
400 desc_es_descriptor_copy_data (ESDescriptor * desc, guint8 ** buffer,
401 guint64 * size, guint64 * offset)
404 guint64 original_offset = *offset;
406 /* must call this twice to have size fields of all contained descriptors set
407 * correctly, and to have the size of the size fields taken into account */
408 desc_size = desc_es_descriptor_get_size (desc);
409 desc_size = desc_es_descriptor_get_size (desc);
411 if (!desc_base_descriptor_copy_data (&desc->base, buffer, size, offset)) {
415 prop_copy_uint16 (desc->id, buffer, size, offset);
416 prop_copy_uint8 (desc->flags, buffer, size, offset);
418 if (desc_es_descriptor_check_stream_dependency (desc)) {
419 prop_copy_uint16 (desc->depends_on_es_id, buffer, size, offset);
422 if (desc_es_descriptor_check_url_flag (desc)) {
423 prop_copy_size_string (desc->url_string, desc->url_length, buffer, size,
427 if (desc_es_descriptor_check_ocr (desc)) {
428 prop_copy_uint16 (desc->ocr_es_id, buffer, size, offset);
431 if (!desc_dec_config_descriptor_copy_data (&desc->dec_conf_desc, buffer, size,
436 if (!desc_sl_config_descriptor_copy_data (&desc->sl_conf_desc, buffer, size,
441 return *offset - original_offset;