gst_plugins_good/gst/qtmux/descriptors.c
branchRCL_3
changeset 30 7e817e7e631c
parent 29 567bb019e3e3
equal deleted inserted replaced
29:567bb019e3e3 30:7e817e7e631c
     1 /* Quicktime muxer plugin for GStreamer
       
     2  * Copyright (C) 2008 Thiago Sousa Santos <thiagoss@embedded.ufcg.edu.br>
       
     3  *
       
     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.
       
     8  *
       
     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.
       
    13  *
       
    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.
       
    18  */
       
    19 /*
       
    20  * Unless otherwise indicated, Source Code is licensed under MIT license.
       
    21  * See further explanation attached in License Statement (distributed in the file
       
    22  * LICENSE).
       
    23  *
       
    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:
       
    30  *
       
    31  * The above copyright notice and this permission notice shall be included in all
       
    32  * copies or substantial portions of the Software.
       
    33  *
       
    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
       
    40  * SOFTWARE.
       
    41  */
       
    42 
       
    43 #include "descriptors.h"
       
    44 
       
    45 /**
       
    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.
       
    50  *
       
    51  * The next set of functions handle those values
       
    52  */
       
    53 
       
    54 /**
       
    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
       
    60  */
       
    61 static void
       
    62 expandable_size_parse (guint64 size, guint8 * ptr, guint32 array_size)
       
    63 {
       
    64   int index = 0;
       
    65 
       
    66   memset (ptr, 0, sizeof (array_size));
       
    67   while (size > 0 && index < array_size) {
       
    68     ptr[index++] = (size > 0x7F ? 0x80 : 0x0) | (size & 0x7F);
       
    69     size = size >> 7;
       
    70   }
       
    71 }
       
    72 
       
    73 /**
       
    74  * Gets how many positions in an array holding an 'expandable size'
       
    75  * are really used
       
    76  *
       
    77  * @ptr: the array with the 'expandable size'
       
    78  * @array_size: the size of ptr array
       
    79  *
       
    80  * Returns: the number of really used positions
       
    81  */
       
    82 static guint64
       
    83 expandable_size_get_length (guint8 * ptr, guint32 array_size)
       
    84 {
       
    85   gboolean next = TRUE;
       
    86   guint32 index = 0;
       
    87 
       
    88   while (next && index < array_size) {
       
    89     next = ((ptr[index] & 0x80) == 1);
       
    90     index++;
       
    91   }
       
    92   return index;
       
    93 }
       
    94 
       
    95 /*
       
    96  * Initializers below
       
    97  */
       
    98 
       
    99 static void
       
   100 desc_base_descriptor_init (BaseDescriptor * bd, guint8 tag, guint32 size)
       
   101 {
       
   102   bd->tag = tag;
       
   103   expandable_size_parse (size, bd->size, 4);
       
   104 }
       
   105 
       
   106 static void
       
   107 desc_dec_specific_info_init (DecoderSpecificInfoDescriptor * dsid)
       
   108 {
       
   109   desc_base_descriptor_init (&dsid->base, DECODER_SPECIFIC_INFO_TAG, 0);
       
   110   dsid->length = 0;
       
   111   dsid->data = NULL;
       
   112 }
       
   113 
       
   114 DecoderSpecificInfoDescriptor *
       
   115 desc_dec_specific_info_new ()
       
   116 {
       
   117   DecoderSpecificInfoDescriptor *desc =
       
   118       g_new0 (DecoderSpecificInfoDescriptor, 1);
       
   119   desc_dec_specific_info_init (desc);
       
   120   return desc;
       
   121 }
       
   122 
       
   123 static void
       
   124 desc_dec_conf_desc_init (DecoderConfigDescriptor * dcd)
       
   125 {
       
   126   desc_base_descriptor_init (&dcd->base, DECODER_CONFIG_DESC_TAG, 0);
       
   127   dcd->dec_specific_info = NULL;
       
   128 }
       
   129 
       
   130 static void
       
   131 desc_sl_conf_desc_init (SLConfigDescriptor * sl)
       
   132 {
       
   133   desc_base_descriptor_init (&sl->base, SL_CONFIG_DESC_TAG, 0);
       
   134   sl->predefined = 0x2;
       
   135 }
       
   136 
       
   137 void
       
   138 desc_es_init (ESDescriptor * es)
       
   139 {
       
   140   desc_base_descriptor_init (&es->base, ES_DESCRIPTOR_TAG, 0);
       
   141 
       
   142   es->id = 0;
       
   143   es->flags = 0;
       
   144   es->depends_on_es_id = 0;
       
   145   es->ocr_es_id = 0;
       
   146   es->url_length = 0;
       
   147   es->url_string = NULL;
       
   148 
       
   149   desc_dec_conf_desc_init (&es->dec_conf_desc);
       
   150   desc_sl_conf_desc_init (&es->sl_conf_desc);
       
   151 }
       
   152 
       
   153 ESDescriptor *
       
   154 desc_es_descriptor_new ()
       
   155 {
       
   156   ESDescriptor *es = g_new0 (ESDescriptor, 1);
       
   157 
       
   158   desc_es_init (es);
       
   159   return es;
       
   160 }
       
   161 
       
   162 /*
       
   163  * Deinitializers/Destructors below
       
   164  */
       
   165 
       
   166 static void
       
   167 desc_base_descriptor_clear (BaseDescriptor * base)
       
   168 {
       
   169 }
       
   170 
       
   171 void
       
   172 desc_dec_specific_info_free (DecoderSpecificInfoDescriptor * dsid)
       
   173 {
       
   174   desc_base_descriptor_clear (&dsid->base);
       
   175   if (dsid->data) {
       
   176     g_free (dsid->data);
       
   177     dsid->data = NULL;
       
   178   }
       
   179   g_free (dsid);
       
   180 }
       
   181 
       
   182 static void
       
   183 desc_dec_conf_desc_clear (DecoderConfigDescriptor * dec)
       
   184 {
       
   185   desc_base_descriptor_clear (&dec->base);
       
   186   if (dec->dec_specific_info) {
       
   187     desc_dec_specific_info_free (dec->dec_specific_info);
       
   188   }
       
   189 }
       
   190 
       
   191 static void
       
   192 desc_sl_config_descriptor_clear (SLConfigDescriptor * sl)
       
   193 {
       
   194   desc_base_descriptor_clear (&sl->base);
       
   195 }
       
   196 
       
   197 void
       
   198 desc_es_descriptor_clear (ESDescriptor * es)
       
   199 {
       
   200   desc_base_descriptor_clear (&es->base);
       
   201   if (es->url_string) {
       
   202     g_free (es->url_string);
       
   203     es->url_string = NULL;
       
   204   }
       
   205   desc_dec_conf_desc_clear (&es->dec_conf_desc);
       
   206   desc_sl_config_descriptor_clear (&es->sl_conf_desc);
       
   207 }
       
   208 
       
   209 void
       
   210 desc_es_descriptor_free (ESDescriptor * es)
       
   211 {
       
   212   desc_es_descriptor_clear (es);
       
   213   g_free (es);
       
   214 }
       
   215 
       
   216 /*
       
   217  * Size handling functions below
       
   218  */
       
   219 
       
   220 void
       
   221 desc_dec_specific_info_alloc_data (DecoderSpecificInfoDescriptor * dsid,
       
   222     guint32 size)
       
   223 {
       
   224   if (dsid->data) {
       
   225     g_free (dsid->data);
       
   226   }
       
   227   dsid->data = g_new0 (guint8, size);
       
   228   dsid->length = size;
       
   229 }
       
   230 
       
   231 static void
       
   232 desc_base_descriptor_set_size (BaseDescriptor * bd, guint32 size)
       
   233 {
       
   234   expandable_size_parse (size, bd->size, 4);
       
   235 }
       
   236 
       
   237 static guint64
       
   238 desc_base_descriptor_get_size (BaseDescriptor * bd)
       
   239 {
       
   240   guint64 size = 0;
       
   241 
       
   242   size += sizeof (guint8);
       
   243   size += expandable_size_get_length (bd->size, 4) * sizeof (guint8);
       
   244   return size;
       
   245 }
       
   246 
       
   247 static guint64
       
   248 desc_sl_config_descriptor_get_size (SLConfigDescriptor * sl_desc)
       
   249 {
       
   250   guint64 size = 0;
       
   251   guint64 extra_size = 0;
       
   252 
       
   253   size += desc_base_descriptor_get_size (&sl_desc->base);
       
   254   /* predefined */
       
   255   extra_size += sizeof (guint8);
       
   256 
       
   257   desc_base_descriptor_set_size (&sl_desc->base, extra_size);
       
   258 
       
   259   return size + extra_size;
       
   260 }
       
   261 
       
   262 static guint64
       
   263 desc_dec_specific_info_get_size (DecoderSpecificInfoDescriptor * dsid)
       
   264 {
       
   265   guint64 size = 0;
       
   266   guint64 extra_size = 0;
       
   267 
       
   268   size += desc_base_descriptor_get_size (&dsid->base);
       
   269   extra_size += sizeof (guint8) * dsid->length;
       
   270   desc_base_descriptor_set_size (&dsid->base, extra_size);
       
   271   return size + extra_size;
       
   272 }
       
   273 
       
   274 static guint64
       
   275 desc_dec_config_descriptor_get_size (DecoderConfigDescriptor * dec_desc)
       
   276 {
       
   277   guint64 size = 0;
       
   278   guint64 extra_size = 0;
       
   279 
       
   280   size += desc_base_descriptor_get_size (&dec_desc->base);
       
   281   /* object type */
       
   282   extra_size += sizeof (guint8);
       
   283   /* stream type */
       
   284   extra_size += sizeof (guint8);
       
   285   /* buffer size */
       
   286   extra_size += sizeof (guint8) * 3;
       
   287   /* max bitrate */
       
   288   extra_size += sizeof (guint32);
       
   289   /* avg bitrate */
       
   290   extra_size += sizeof (guint32);
       
   291   if (dec_desc->dec_specific_info) {
       
   292     extra_size += desc_dec_specific_info_get_size (dec_desc->dec_specific_info);
       
   293   }
       
   294 
       
   295   desc_base_descriptor_set_size (&dec_desc->base, extra_size);
       
   296   return size + extra_size;
       
   297 }
       
   298 
       
   299 static guint64
       
   300 desc_es_descriptor_get_size (ESDescriptor * es)
       
   301 {
       
   302   guint64 size = 0;
       
   303   guint64 extra_size = 0;
       
   304 
       
   305   size += desc_base_descriptor_get_size (&es->base);
       
   306   /* id */
       
   307   extra_size += sizeof (guint16);
       
   308   /* flags */
       
   309   extra_size += sizeof (guint8);
       
   310   /* depends_on_es_id */
       
   311   if (es->flags & 0x80) {
       
   312     extra_size += sizeof (guint16);
       
   313   }
       
   314   if (es->flags & 0x40) {
       
   315     /* url_length */
       
   316     extra_size += sizeof (guint8);
       
   317     /* url */
       
   318     extra_size += sizeof (gchar) * es->url_length;
       
   319   }
       
   320   if (es->flags & 0x20) {
       
   321     /* ocr_es_id */
       
   322     extra_size += sizeof (guint16);
       
   323   }
       
   324 
       
   325   extra_size += desc_dec_config_descriptor_get_size (&es->dec_conf_desc);
       
   326   extra_size += desc_sl_config_descriptor_get_size (&es->sl_conf_desc);
       
   327 
       
   328   desc_base_descriptor_set_size (&es->base, extra_size);
       
   329 
       
   330   return size + extra_size;
       
   331 }
       
   332 
       
   333 static gboolean
       
   334 desc_es_descriptor_check_stream_dependency (ESDescriptor * es)
       
   335 {
       
   336   return es->flags & 0x80;
       
   337 }
       
   338 
       
   339 static gboolean
       
   340 desc_es_descriptor_check_url_flag (ESDescriptor * es)
       
   341 {
       
   342   return es->flags & 0x40;
       
   343 }
       
   344 
       
   345 static gboolean
       
   346 desc_es_descriptor_check_ocr (ESDescriptor * es)
       
   347 {
       
   348   return es->flags & 0x20;
       
   349 }
       
   350 
       
   351 /* Copy/Serializations Functions below */
       
   352 
       
   353 static guint64
       
   354 desc_base_descriptor_copy_data (BaseDescriptor * desc, guint8 ** buffer,
       
   355     guint64 * size, guint64 * offset)
       
   356 {
       
   357   guint64 original_offset = *offset;
       
   358 
       
   359   prop_copy_uint8 (desc->tag, buffer, size, offset);
       
   360   prop_copy_uint8_array (desc->size, expandable_size_get_length (desc->size, 4),
       
   361       buffer, size, offset);
       
   362   return original_offset - *offset;
       
   363 }
       
   364 
       
   365 static guint64
       
   366 desc_sl_config_descriptor_copy_data (SLConfigDescriptor * desc,
       
   367     guint8 ** buffer, guint64 * size, guint64 * offset)
       
   368 {
       
   369   guint64 original_offset = *offset;
       
   370 
       
   371   if (!desc_base_descriptor_copy_data (&desc->base, buffer, size, offset)) {
       
   372     return 0;
       
   373   }
       
   374   /* predefined attribute */
       
   375   prop_copy_uint8 (desc->predefined, buffer, size, offset);
       
   376 
       
   377   return *offset - original_offset;
       
   378 }
       
   379 
       
   380 static guint64
       
   381 desc_dec_specific_info_copy_data (DecoderSpecificInfoDescriptor * desc,
       
   382     guint8 ** buffer, guint64 * size, guint64 * offset)
       
   383 {
       
   384   guint64 original_offset = *offset;
       
   385 
       
   386   if (!desc_base_descriptor_copy_data (&desc->base, buffer, size, offset)) {
       
   387     return 0;
       
   388   }
       
   389   prop_copy_uint8_array (desc->data, desc->length, buffer, size, offset);
       
   390 
       
   391   return *offset - original_offset;
       
   392 }
       
   393 
       
   394 static guint64
       
   395 desc_dec_config_descriptor_copy_data (DecoderConfigDescriptor * desc,
       
   396     guint8 ** buffer, guint64 * size, guint64 * offset)
       
   397 {
       
   398   guint64 original_offset = *offset;
       
   399 
       
   400   if (!desc_base_descriptor_copy_data (&desc->base, buffer, size, offset)) {
       
   401     return 0;
       
   402   }
       
   403 
       
   404   prop_copy_uint8 (desc->object_type, buffer, size, offset);
       
   405 
       
   406   prop_copy_uint8 (desc->stream_type, buffer, size, offset);
       
   407   prop_copy_uint8_array (desc->buffer_size_DB, 3, buffer, size, offset);
       
   408 
       
   409   prop_copy_uint32 (desc->max_bitrate, buffer, size, offset);
       
   410   prop_copy_uint32 (desc->avg_bitrate, buffer, size, offset);
       
   411 
       
   412   if (desc->dec_specific_info) {
       
   413     if (!desc_dec_specific_info_copy_data (desc->dec_specific_info, buffer,
       
   414             size, offset)) {
       
   415       return 0;
       
   416     }
       
   417   }
       
   418 
       
   419   return *offset - original_offset;
       
   420 }
       
   421 
       
   422 guint64
       
   423 desc_es_descriptor_copy_data (ESDescriptor * desc, guint8 ** buffer,
       
   424     guint64 * size, guint64 * offset)
       
   425 {
       
   426   guint64 desc_size;
       
   427   guint64 original_offset = *offset;
       
   428 
       
   429   /* must call this twice to have size fields of all contained descriptors set
       
   430    * correctly, and to have the size of the size fields taken into account */
       
   431   desc_size = desc_es_descriptor_get_size (desc);
       
   432   desc_size = desc_es_descriptor_get_size (desc);
       
   433 
       
   434   if (!desc_base_descriptor_copy_data (&desc->base, buffer, size, offset)) {
       
   435     return 0;
       
   436   }
       
   437   /* id and flags */
       
   438   prop_copy_uint16 (desc->id, buffer, size, offset);
       
   439   prop_copy_uint8 (desc->flags, buffer, size, offset);
       
   440 
       
   441   if (desc_es_descriptor_check_stream_dependency (desc)) {
       
   442     prop_copy_uint16 (desc->depends_on_es_id, buffer, size, offset);
       
   443   }
       
   444 
       
   445   if (desc_es_descriptor_check_url_flag (desc)) {
       
   446     prop_copy_size_string (desc->url_string, desc->url_length, buffer, size,
       
   447         offset);
       
   448   }
       
   449 
       
   450   if (desc_es_descriptor_check_ocr (desc)) {
       
   451     prop_copy_uint16 (desc->ocr_es_id, buffer, size, offset);
       
   452   }
       
   453 
       
   454   if (!desc_dec_config_descriptor_copy_data (&desc->dec_conf_desc, buffer, size,
       
   455           offset)) {
       
   456     return 0;
       
   457   }
       
   458 
       
   459   if (!desc_sl_config_descriptor_copy_data (&desc->sl_conf_desc, buffer, size,
       
   460           offset)) {
       
   461     return 0;
       
   462   }
       
   463 
       
   464   return *offset - original_offset;
       
   465 }