]> git.sesse.net Git - vlc/commitdiff
* commit modules/demux/asf/*: load and parse the metadata object + coding style changes.
authorGildas Bazin <gbazin@videolan.org>
Fri, 10 Sep 2004 11:35:42 +0000 (11:35 +0000)
committerGildas Bazin <gbazin@videolan.org>
Fri, 10 Sep 2004 11:35:42 +0000 (11:35 +0000)
modules/demux/asf/libasf.c
modules/demux/asf/libasf.h

index ca86701f44ae8049d56774c2e5f52a4371b33142..94f625aaa83a9e5096ec08e344c320f6dbaa6c0f 100644 (file)
@@ -1,9 +1,11 @@
 /*****************************************************************************
- * libasf.c :
+ * libasf.c : asf stream demux module for vlc
  *****************************************************************************
  * Copyright (C) 2001-2003 VideoLAN
  * $Id$
+ *
  * Authors: Laurent Aimar <fenrir@via.ecp.fr>
+ *          Gildas Bazin <gbazin@videolan.org>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -44,9 +46,7 @@
 /****************************************************************************
  *
  ****************************************************************************/
-static int ASF_ReadObject( stream_t *,
-                           asf_object_t *p_obj,  asf_object_t *p_father );
-
+static int ASF_ReadObject( stream_t *, asf_object_t *,  asf_object_t * );
 
 /****************************************************************************
  * GUID functions
@@ -87,6 +87,7 @@ static int ASF_ReadObjectCommon( stream_t *s, asf_object_t *p_obj )
     p_common->i_object_size = GetQWLE( p_peek + 16 );
     p_common->i_object_pos  = stream_Tell( s );
     p_common->p_next = NULL;
+
 #ifdef ASF_DEBUG
     msg_Dbg( (vlc_object_t*)s,
              "found object guid: " GUID_FMT " size:"I64Fd,
@@ -113,9 +114,11 @@ static int ASF_NextObject( stream_t *s, asf_object_t *p_obj )
     {
         return VLC_EGENERIC;
     }
-    if( p_obj->common.p_father && p_obj->common.p_father->common.i_object_size != 0 )
+    if( p_obj->common.p_father &&
+        p_obj->common.p_father->common.i_object_size != 0 )
     {
-        if( p_obj->common.p_father->common.i_object_pos + p_obj->common.p_father->common.i_object_size <
+        if( p_obj->common.p_father->common.i_object_pos +
+            p_obj->common.p_father->common.i_object_size <
                 p_obj->common.i_object_pos + p_obj->common.i_object_size + 24 )
                                 /* 24 is min size of an object */
         {
@@ -124,9 +127,8 @@ static int ASF_NextObject( stream_t *s, asf_object_t *p_obj )
 
     }
 
-    return stream_Seek( s,
-                        p_obj->common.i_object_pos +
-                           p_obj->common.i_object_size );
+    return stream_Seek( s, p_obj->common.i_object_pos +
+                        p_obj->common.i_object_size );
 }
 
 static void ASF_FreeObject_Null( asf_object_t *pp_obj )
@@ -151,6 +153,7 @@ static int  ASF_ReadObject_Header( stream_t *s, asf_object_t *p_obj )
     p_hdr->i_reserved2 = p_peek[29];
     p_hdr->p_first = NULL;
     p_hdr->p_last  = NULL;
+
 #ifdef ASF_DEBUG
     msg_Dbg( (vlc_object_t*)s,
              "read \"header object\" subobj:%d, reserved1:%d, reserved2:%d",
@@ -158,16 +161,18 @@ static int  ASF_ReadObject_Header( stream_t *s, asf_object_t *p_obj )
              p_hdr->i_reserved1,
              p_hdr->i_reserved2 );
 #endif
-    /* Cannot failed as peek succeed */
+
+    /* Cannot fail as peek succeed */
     stream_Read( s, NULL, 30 );
 
     /* Now load sub object */
     for( ; ; )
     {
-        p_subobj  = malloc( sizeof( asf_object_t ) );
+        p_subobj = malloc( sizeof( asf_object_t ) );
 
         if( ASF_ReadObject( s, p_subobj, (asf_object_t*)p_hdr ) )
         {
+            free( p_subobj );
             break;
         }
         if( ASF_NextObject( s, p_subobj ) ) /* Go to the next object */
@@ -191,6 +196,7 @@ static int ASF_ReadObject_Data( stream_t *s, asf_object_t *p_obj )
     ASF_GetGUID( &p_data->i_file_id, p_peek + 24 );
     p_data->i_total_data_packets = GetQWLE( p_peek + 40 );
     p_data->i_reserved = GetWLE( p_peek + 48 );
+
 #ifdef ASF_DEBUG
     msg_Dbg( (vlc_object_t*)s,
              "read \"data object\" file_id:" GUID_FMT " total data packet:"
@@ -199,6 +205,7 @@ static int ASF_ReadObject_Data( stream_t *s, asf_object_t *p_obj )
              p_data->i_total_data_packets,
              p_data->i_reserved );
 #endif
+
     return VLC_SUCCESS;
 }
 
@@ -228,8 +235,10 @@ static int ASF_ReadObject_Index( stream_t *s, asf_object_t *p_obj )
             p_index->i_max_packet_count,
             (long int)p_index->i_index_entry_count );
 #endif
+
     return VLC_SUCCESS;
 }
+
 static void ASF_FreeObject_Index( asf_object_t *p_obj )
 {
     asf_object_index_t *p_index = (asf_object_index_t*)p_obj;
@@ -266,24 +275,140 @@ static int ASF_ReadObject_file_properties( stream_t *s, asf_object_t *p_obj )
             I64Fd" play_duration:"I64Fd" send_duration:"I64Fd" preroll:"
             I64Fd" flags:%d min_data_packet_size:%d max_data_packet_size:%d "
             "max_bitrate:%d",
-            GUID_PRINT( p_fp->i_file_id ),
-            p_fp->i_file_size,
-            p_fp->i_creation_date,
-            p_fp->i_data_packets_count,
-            p_fp->i_play_duration,
-            p_fp->i_send_duration,
-            p_fp->i_preroll,
-            p_fp->i_flags,
-            p_fp->i_min_data_packet_size,
-            p_fp->i_max_data_packet_size,
+            GUID_PRINT( p_fp->i_file_id ), p_fp->i_file_size,
+            p_fp->i_creation_date, p_fp->i_data_packets_count,
+            p_fp->i_play_duration, p_fp->i_send_duration,
+            p_fp->i_preroll, p_fp->i_flags,
+            p_fp->i_min_data_packet_size, p_fp->i_max_data_packet_size,
             p_fp->i_max_bitrate );
 #endif
+
     return VLC_SUCCESS;
 }
 
-static int ASF_ReadObject_header_extention( stream_t *s, asf_object_t *p_obj )
+static void ASF_FreeObject_metadata( asf_object_t *p_obj )
+{
+    asf_object_metadata_t *p_meta =
+        (asf_object_metadata_t *)p_obj;
+    unsigned int i;
+
+    for( i = 0; i < p_meta->i_record_entries_count; i++ )
+    {
+        if( p_meta->record[i].psz_name ) free( p_meta->record[i].psz_name );
+        if( p_meta->record[i].p_data ) free( p_meta->record[i].p_data );
+    }
+    if( p_meta->record ) free( p_meta->record );
+}
+
+static int ASF_ReadObject_metadata( stream_t *s, asf_object_t *p_obj )
 {
-    asf_object_header_extention_t *p_he = (asf_object_header_extention_t*)p_obj;
+    asf_object_metadata_t *p_meta =
+        (asf_object_metadata_t *)p_obj;
+
+    int i_peek, i_entries, i;
+    uint8_t *p_peek;
+
+    p_meta->i_record_entries_count = 0;
+    p_meta->record = 0;
+
+    if( stream_Peek( s, &p_peek, p_meta->i_object_size ) <
+        (int)p_meta->i_object_size )
+    {
+       return VLC_EGENERIC;
+    }
+
+    i_peek = 24;
+    i_entries = GetWLE( p_peek + i_peek ); i_peek += 2;
+    for( i = 0; i < i_entries && i_peek < (int)p_meta->i_object_size -12; i++ )
+    {
+        asf_metadata_record_t record;
+        int i_name, i_data, j;
+
+        if( GetWLE( p_peek + i_peek ) != 0 )
+        {
+            ASF_FreeObject_metadata( p_obj );
+            return VLC_EGENERIC;
+        }
+
+        i_peek += 2;
+        record.i_stream = GetWLE( p_peek + i_peek ); i_peek += 2;
+        i_name = GetWLE( p_peek + i_peek ); i_peek += 2;
+        record.i_type = GetWLE( p_peek + i_peek ); i_peek += 2;
+        i_data = GetDWLE( p_peek + i_peek ); i_peek += 4;
+
+        if( record.i_type > ASF_METADATA_TYPE_WORD ||
+            i_peek + i_data + i_name > (int)p_meta->i_object_size )
+        {
+            ASF_FreeObject_metadata( p_obj );
+            return VLC_EGENERIC;
+        }
+
+        record.i_val = 0;
+        record.i_data = 0;
+        record.p_data = 0;
+
+        /* get name */
+        record.psz_name = malloc( i_name/2 );
+        for( j = 0; j < i_name/2; j++ )
+        {
+            record.psz_name[j] = GetWLE( p_peek + i_peek ); i_peek += 2;
+        }
+
+        /* get data */
+        if( record.i_type == ASF_METADATA_TYPE_STRING )
+        {
+            record.p_data = malloc( i_data/2 );
+            record.i_data = i_data/2;
+            for( j = 0; j < i_data/2; j++ )
+            {
+                record.p_data[j] = GetWLE( p_peek + i_peek ); i_peek += 2;
+            }
+
+            msg_Dbg( s, "metadata: %s=%s", record.psz_name, record.p_data );
+        }
+        else if( record.i_type == ASF_METADATA_TYPE_BYTE )
+        {
+            record.p_data = malloc( i_data );
+            record.i_data = i_data;
+            memcpy( record.p_data, p_peek + i_peek, i_data );
+            p_peek += i_data;
+
+            msg_Dbg( s, "metadata: %s (%i bytes)", record.psz_name,
+                     record.i_data );
+        }
+        else
+        {
+            if( record.i_type == ASF_METADATA_TYPE_QWORD )
+            {
+                record.i_val = GetQWLE( p_peek + i_peek ); i_peek += 8;
+            }
+            else if( record.i_type == ASF_METADATA_TYPE_DWORD )
+            {
+                record.i_val = GetDWLE( p_peek + i_peek ); i_peek += 4;
+            }
+            else
+            {
+                record.i_val = GetWLE( p_peek + i_peek ); i_peek += 2;
+            }
+
+            msg_Dbg( s, "metadata: %s=%i", record.psz_name, record.i_val );
+        }
+
+        p_meta->i_record_entries_count++;
+        p_meta->record =
+            realloc( p_meta->record, p_meta->i_record_entries_count *
+                     sizeof(asf_metadata_record_t) );
+        memcpy( &p_meta->record[p_meta->i_record_entries_count-1],
+                &record, sizeof(asf_metadata_record_t) );
+    }
+
+    return VLC_SUCCESS;
+}
+
+static int ASF_ReadObject_header_extension( stream_t *s, asf_object_t *p_obj )
+{
+    asf_object_header_extension_t *p_he =
+        (asf_object_header_extension_t *)p_obj;
     int     i_peek;
     uint8_t *p_peek;
 
@@ -293,32 +418,56 @@ static int ASF_ReadObject_header_extention( stream_t *s, asf_object_t *p_obj )
     }
     ASF_GetGUID( &p_he->i_reserved1, p_peek + 24 );
     p_he->i_reserved2 = GetWLE( p_peek + 40 );
-    p_he->i_header_extention_size = GetDWLE( p_peek + 42 );
-    if( p_he->i_header_extention_size )
+    p_he->i_header_extension_size = GetDWLE( p_peek + 42 );
+    if( p_he->i_header_extension_size )
     {
-        p_he->p_header_extention_data = malloc( p_he->i_header_extention_size );
-        memcpy( p_he->p_header_extention_data,
-                p_peek + 46,
-                p_he->i_header_extention_size );
+        p_he->p_header_extension_data =
+            malloc( p_he->i_header_extension_size );
+        memcpy( p_he->p_header_extension_data, p_peek + 46,
+                p_he->i_header_extension_size );
     }
     else
     {
-        p_he->p_header_extention_data = NULL;
+        p_he->p_header_extension_data = NULL;
     }
+
 #ifdef ASF_DEBUG
     msg_Dbg( (vlc_object_t*)s,
-            "read \"header extention object\" reserved1:" GUID_FMT " reserved2:%d header_extention_size:%d",
-            GUID_PRINT( p_he->i_reserved1 ),
-            p_he->i_reserved2,
-            p_he->i_header_extention_size );
+            "read \"header extension object\" reserved1:" GUID_FMT
+            " reserved2:%d header_extension_size:%d",
+            GUID_PRINT( p_he->i_reserved1 ), p_he->i_reserved2,
+            p_he->i_header_extension_size );
 #endif
+
+    if( !p_he->i_header_extension_size ) return VLC_SUCCESS;
+
+    /* Read the extension objects */
+    stream_Read( s, NULL, 46 );
+    for( ; ; )
+    {
+        asf_object_t *p_obj = malloc( sizeof( asf_object_t ) );
+
+        if( ASF_ReadObject( s, p_obj, (asf_object_t*)p_he ) )
+        {
+            free( p_obj );
+            break;
+        }
+
+        if( ASF_NextObject( s, p_obj ) ) /* Go to the next object */
+        {
+            break;
+        }
+    }
+
     return VLC_SUCCESS;
 }
-static void ASF_FreeObject_header_extention( asf_object_t *p_obj )
+
+static void ASF_FreeObject_header_extension( asf_object_t *p_obj )
 {
-    asf_object_header_extention_t *p_he = (asf_object_header_extention_t*)p_obj;
+    asf_object_header_extension_t *p_he =
+        (asf_object_header_extension_t *)p_obj;
 
-    FREE( p_he->p_header_extention_data );
+    FREE( p_he->p_header_extension_data );
 }
 
 static int ASF_ReadObject_stream_properties( stream_t *s, asf_object_t *p_obj )
@@ -342,9 +491,9 @@ static int ASF_ReadObject_stream_properties( stream_t *s, asf_object_t *p_obj )
     p_sp->i_reserved = GetDWLE( p_peek + 74 );
     if( p_sp->i_type_specific_data_length )
     {
-        p_sp->p_type_specific_data = malloc( p_sp->i_type_specific_data_length );
-        memcpy( p_sp->p_type_specific_data,
-                p_peek + 78,
+        p_sp->p_type_specific_data =
+            malloc( p_sp->i_type_specific_data_length );
+        memcpy( p_sp->p_type_specific_data, p_peek + 78,
                 p_sp->i_type_specific_data_length );
     }
     else
@@ -353,7 +502,8 @@ static int ASF_ReadObject_stream_properties( stream_t *s, asf_object_t *p_obj )
     }
     if( p_sp->i_error_correction_data_length )
     {
-        p_sp->p_error_correction_data = malloc( p_sp->i_error_correction_data_length );
+        p_sp->p_error_correction_data =
+            malloc( p_sp->i_error_correction_data_length );
         memcpy( p_sp->p_error_correction_data,
                 p_peek + 78 + p_sp->i_type_specific_data_length,
                 p_sp->i_error_correction_data_length );
@@ -462,23 +612,24 @@ static int ASF_ReadObject_codec_list( stream_t *s, asf_object_t *p_obj )
     }
 
 #ifdef ASF_DEBUG
-    msg_Dbg( (vlc_object_t*)s,
-            "read \"codec list object\" reserved_guid:" GUID_FMT " codec_entries_count:%d",
-            GUID_PRINT( p_cl->i_reserved ),
-            p_cl->i_codec_entries_count );
+    msg_Dbg( s, "read \"codec list object\" reserved_guid:" GUID_FMT
+             " codec_entries_count:%d",
+            GUID_PRINT( p_cl->i_reserved ), p_cl->i_codec_entries_count );
 
     for( i_codec = 0; i_codec < p_cl->i_codec_entries_count; i_codec++ )
     {
 #define codec p_cl->codec[i_codec]
-        msg_Dbg( (vlc_object_t*)s,
-                 "read \"codec list object\" codec[%d] %s name:\"%s\" description:\"%s\" information_length:%d",
-                 i_codec,
-                 ( codec.i_type == ASF_CODEC_TYPE_VIDEO ) ? "video" : ( ( codec.i_type == ASF_CODEC_TYPE_AUDIO ) ? "audio" : "unknown" ),
-                 codec.psz_name,
-                 codec.psz_description,
+        msg_Dbg( s, "read \"codec list object\" codec[%d] %s name:\"%s\" "
+                 "description:\"%s\" information_length:%d",
+                 i_codec, ( codec.i_type == ASF_CODEC_TYPE_VIDEO ) ?
+                 "video" : ( ( codec.i_type == ASF_CODEC_TYPE_AUDIO ) ?
+                 "audio" : "unknown" ),
+                 codec.psz_name, codec.psz_description,
                  codec.i_information_length );
+#undef  codec
     }
 #endif
+
     return VLC_SUCCESS;
 }
 
@@ -493,7 +644,6 @@ static void ASF_FreeObject_codec_list( asf_object_t *p_obj )
         FREE( codec.psz_name );
         FREE( codec.psz_description );
         FREE( codec.p_information );
-
 #undef  codec
     }
     FREE( p_cl->codec );
@@ -504,16 +654,10 @@ static void ASF_FreeObject_codec_list( asf_object_t *p_obj )
 static int ASF_ReadObject_content_description(stream_t *s, asf_object_t *p_obj)
 {
     asf_object_content_description_t *p_cd =
-                                    (asf_object_content_description_t*)p_obj;
-    int     i_peek;
+        (asf_object_content_description_t *)p_obj;
     uint8_t *p_peek, *p_data;
-
-    int i_len;
-    int i_title;
-    int i_author;
-    int i_copyright;
-    int i_description;
-    int i_rating;
+    int i_peek;
+    int i_len, i_title, i_author, i_copyright, i_description, i_rating;
 
 #define GETSTRINGW( psz_str, i_size ) \
    psz_str = calloc( i_size/2 + 1, sizeof( char ) ); \
@@ -559,7 +703,7 @@ static int ASF_ReadObject_content_description(stream_t *s, asf_object_t *p_obj)
 static void ASF_FreeObject_content_description( asf_object_t *p_obj)
 {
     asf_object_content_description_t *p_cd =
-                                    (asf_object_content_description_t*)p_obj;
+        (asf_object_content_description_t *)p_obj;
 
     FREE( p_cd->psz_title );
     FREE( p_cd->psz_author );
@@ -574,31 +718,41 @@ static struct
     int     i_type;
     int     (*ASF_ReadObject_function)( stream_t *, asf_object_t *p_obj );
     void    (*ASF_FreeObject_function)( asf_object_t *p_obj );
+
 } ASF_Object_Function [] =
 {
-    { &asf_object_header_guid,            ASF_OBJECT_TYPE_HEADER,             ASF_ReadObject_Header, ASF_FreeObject_Null },
-    { &asf_object_data_guid,              ASF_OBJECT_TYPE_DATA,               ASF_ReadObject_Data,   ASF_FreeObject_Null },
-    { &asf_object_index_guid,             ASF_OBJECT_TYPE_INDEX,              ASF_ReadObject_Index,  ASF_FreeObject_Index },
-    { &asf_object_file_properties_guid,   ASF_OBJECT_TYPE_FILE_PROPERTIES,    ASF_ReadObject_file_properties,  ASF_FreeObject_Null },
-    { &asf_object_stream_properties_guid, ASF_OBJECT_TYPE_STREAM_PROPERTIES,  ASF_ReadObject_stream_properties,ASF_FreeObject_stream_properties },
-    { &asf_object_header_extention_guid,  ASF_OBJECT_TYPE_EXTENTION_HEADER,   ASF_ReadObject_header_extention, ASF_FreeObject_header_extention},
-    { &asf_object_codec_list_guid,        ASF_OBJECT_TYPE_CODEC_LIST,         ASF_ReadObject_codec_list,       ASF_FreeObject_codec_list },
-    { &asf_object_marker_guid,            ASF_OBJECT_TYPE_MARKER,             NULL,                  NULL },
-    { &asf_object_content_description_guid, ASF_OBJECT_TYPE_CONTENT_DESCRIPTION, ASF_ReadObject_content_description, ASF_FreeObject_content_description },
-
-    { &asf_object_null_guid,   0,                      NULL,                  NULL }
+    { &asf_object_header_guid, ASF_OBJECT_TYPE_HEADER,
+      ASF_ReadObject_Header, ASF_FreeObject_Null },
+    { &asf_object_data_guid, ASF_OBJECT_TYPE_DATA,
+      ASF_ReadObject_Data, ASF_FreeObject_Null },
+    { &asf_object_index_guid, ASF_OBJECT_TYPE_INDEX,
+      ASF_ReadObject_Index, ASF_FreeObject_Index },
+    { &asf_object_file_properties_guid, ASF_OBJECT_TYPE_FILE_PROPERTIES,
+      ASF_ReadObject_file_properties, ASF_FreeObject_Null },
+    { &asf_object_stream_properties_guid, ASF_OBJECT_TYPE_STREAM_PROPERTIES,
+      ASF_ReadObject_stream_properties,ASF_FreeObject_stream_properties },
+    { &asf_object_header_extension_guid, ASF_OBJECT_TYPE_HEADER_EXTENSION,
+      ASF_ReadObject_header_extension, ASF_FreeObject_header_extension},
+    { &asf_object_metadata_guid, ASF_OBJECT_TYPE_METADATA,
+      ASF_ReadObject_metadata, ASF_FreeObject_metadata},
+    { &asf_object_codec_list_guid, ASF_OBJECT_TYPE_CODEC_LIST,
+      ASF_ReadObject_codec_list, ASF_FreeObject_codec_list },
+    { &asf_object_marker_guid, ASF_OBJECT_TYPE_MARKER,
+      NULL, NULL },
+    { &asf_object_content_description_guid, ASF_OBJECT_TYPE_CONTENT_DESCRIPTION,
+      ASF_ReadObject_content_description, ASF_FreeObject_content_description },
+
+    { &asf_object_null_guid, 0, NULL, NULL }
 };
 
-static int ASF_ReadObject( stream_t *s,
-                           asf_object_t *p_obj, asf_object_t *p_father )
+static int ASF_ReadObject( stream_t *s, asf_object_t *p_obj,
+                           asf_object_t *p_father )
 {
     int i_result;
     int i_index;
 
-    if( !p_obj )
-    {
-        return( 0 );
-    }
+    if( !p_obj ) return( 0 );
+
     if( ASF_ReadObjectCommon( s, p_obj ) )
     {
         msg_Warn( (vlc_object_t*)s, "cannot read one asf object" );
@@ -609,19 +763,19 @@ static int ASF_ReadObject( stream_t *s,
     p_obj->common.p_next = NULL;
     p_obj->common.p_last = NULL;
 
-
     if( p_obj->common.i_object_size < 24 )
     {
         msg_Warn( (vlc_object_t*)s, "found a corrupted asf object (size<24)" );
         return VLC_EGENERIC;
     }
+
     /* find this object */
     for( i_index = 0; ; i_index++ )
     {
         if( ASF_CmpGUID( ASF_Object_Function[i_index].p_id,
-                     &p_obj->common.i_object_id )||
+                         &p_obj->common.i_object_id ) ||
             ASF_CmpGUID( ASF_Object_Function[i_index].p_id,
-                     &asf_object_null_guid ) )
+                         &asf_object_null_guid ) )
         {
             break;
         }
@@ -663,10 +817,7 @@ static void ASF_FreeObject( stream_t *s, asf_object_t *p_obj )
     int i_index;
     asf_object_t *p_child;
 
-    if( !p_obj )
-    {
-        return;
-    }
+    if( !p_obj ) return;
 
     /* Free all child object */
     p_child = p_obj->common.p_first;
@@ -729,13 +880,16 @@ asf_object_root_t *ASF_ReadObjectRoot( stream_t *s, int b_seekable )
     p_root->p_data  = NULL;
     p_root->p_fp    = NULL;
     p_root->p_index = NULL;
+    p_root->p_hdr_ext = NULL;
+    p_root->p_metadata = NULL;
 
     for( ; ; )
     {
-        p_obj  = malloc( sizeof( asf_object_t ) );
+        p_obj = malloc( sizeof( asf_object_t ) );
 
         if( ASF_ReadObject( s, p_obj, (asf_object_t*)p_root ) )
         {
+            free( p_obj );
             break;
         }
         switch( p_obj->common.i_type )
@@ -749,6 +903,9 @@ asf_object_root_t *ASF_ReadObjectRoot( stream_t *s, int b_seekable )
             case( ASF_OBJECT_TYPE_INDEX ):
                 p_root->p_index = (asf_object_index_t*)p_obj;
                 break;
+            case( ASF_OBJECT_TYPE_HEADER_EXTENSION ):
+                p_root->p_hdr_ext = (asf_object_header_extension_t*)p_obj;
+                break;
             default:
                 msg_Warn( (vlc_object_t*)s, "unknow object found" );
                 break;
@@ -761,7 +918,7 @@ asf_object_root_t *ASF_ReadObjectRoot( stream_t *s, int b_seekable )
         }
         if( !b_seekable && p_root->p_hdr && p_root->p_data )
         {
-            /* For unseekable stream it's enouth to play */
+            /* For unseekable stream it's enough to play */
             break;
         }
 
@@ -778,6 +935,14 @@ asf_object_root_t *ASF_ReadObjectRoot( stream_t *s, int b_seekable )
 
         if( p_root->p_fp )
         {
+
+            if( p_root->p_hdr_ext != NULL )
+            {
+                p_root->p_metadata =
+                    ASF_FindObject( p_root->p_hdr_ext,
+                                    &asf_object_metadata_guid, 0 );
+            }
+
             return p_root;
         }
         msg_Warn( (vlc_object_t*)s, "cannot find file properties object" );
@@ -808,10 +973,7 @@ int  __ASF_CountObject( asf_object_t *p_obj, const guid_t *p_guid )
     int i_count;
     asf_object_t *p_child;
 
-    if( !p_obj )
-    {
-        return( 0 );
-    }
+    if( !p_obj ) return( 0 );
 
     i_count = 0;
     p_child = p_obj->common.p_first;
@@ -826,7 +988,8 @@ int  __ASF_CountObject( asf_object_t *p_obj, const guid_t *p_guid )
     return( i_count );
 }
 
-void *__ASF_FindObject( asf_object_t *p_obj, const guid_t *p_guid, int i_number )
+void *__ASF_FindObject( asf_object_t *p_obj, const guid_t *p_guid,
+                        int i_number )
 {
     asf_object_t *p_child;
 
@@ -848,4 +1011,3 @@ void *__ASF_FindObject( asf_object_t *p_obj, const guid_t *p_guid, int i_number
     }
     return( NULL );
 }
-
index 6277c4a59c0f21353963ac696466afab12126e4c..2161b2b6a57d51f3032ba4f8767a30ac345dee9b 100644 (file)
@@ -2,7 +2,7 @@
  * libasf.h :
  *****************************************************************************
  * Copyright (C) 2001-2003 VideoLAN
- * $Id: libasf.h,v 1.8 2004/01/25 20:05:28 hartman Exp $
+ * $Id$
  * Authors: Laurent Aimar <fenrir@via.ecp.fr>
  *
  * This program is free software; you can redistribute it and/or modify
@@ -39,10 +39,11 @@ typedef struct guid_s
 #define ASF_OBJECT_TYPE_INDEX     0x0004
 #define ASF_OBJECT_TYPE_FILE_PROPERTIES     0x0005
 #define ASF_OBJECT_TYPE_STREAM_PROPERTIES   0x0006
-#define ASF_OBJECT_TYPE_EXTENTION_HEADER    0x0007
+#define ASF_OBJECT_TYPE_HEADER_EXTENSION    0x0007
 #define ASF_OBJECT_TYPE_CODEC_LIST          0x0008
 #define ASF_OBJECT_TYPE_MARKER              0x0009
 #define ASF_OBJECT_TYPE_CONTENT_DESCRIPTION 0x000a
+#define ASF_OBJECT_TYPE_METADATA            0x000b
 
 static const guid_t asf_object_null_guid =
 {
@@ -53,110 +54,49 @@ static const guid_t asf_object_null_guid =
 };
 
 static const guid_t asf_object_header_guid =
-{
-    0x75B22630,
-    0x668E,
-    0x11CF,
-    { 0xA6,0xD9, 0x00,0xAA,0x00,0x62,0xCE,0x6C }
-};
+{0x75B22630, 0x668E, 0x11CF, {0xA6, 0xD9, 0x00, 0xAA, 0x00, 0x62, 0xCE, 0x6C}};
 
 static const guid_t asf_object_data_guid =
-{
-    0x75B22636,
-    0x668E,
-    0x11CF,
-    { 0xA6,0xD9, 0x00,0xAA,0x00,0x62,0xCE,0x6C }
-};
-
-
+{0x75B22636, 0x668E, 0x11CF, {0xA6, 0xD9, 0x00, 0xAA, 0x00, 0x62, 0xCE, 0x6C}};
 
 static const guid_t asf_object_index_guid =
-{
-    0x33000890,
-    0xE5B1,
-    0x11CF,
-    { 0x89,0xF4, 0x00,0xA0,0xC9,0x03,0x49,0xCB }
-};
+{0x33000890, 0xE5B1, 0x11CF, {0x89, 0xF4, 0x00, 0xA0, 0xC9, 0x03, 0x49, 0xCB}};
 
 static const guid_t asf_object_file_properties_guid =
-{
-    0x8cabdca1,
-    0xa947,
-    0x11cf,
-    { 0x8e,0xe4, 0x00,0xC0,0x0C,0x20,0x53,0x65 }
+{0x8cabdca1, 0xa947, 0x11cf, {0x8e, 0xe4, 0x00, 0xC0, 0x0C, 0x20, 0x53, 0x65}};
 
-};
 static const guid_t asf_object_stream_properties_guid =
-{
-    0xB7DC0791,
-    0xA9B7,
-    0x11CF,
-    { 0x8E,0xE6, 0x00,0xC0,0x0C,0x20,0x53,0x65 }
-
-};
+{0xB7DC0791, 0xA9B7, 0x11CF, {0x8E, 0xE6, 0x00, 0xC0, 0x0C, 0x20, 0x53, 0x65}};
 
 static const guid_t asf_object_content_description_guid =
-{
-    0x75B22633,
-    0x668E,
-    0x11CF,
-    { 0xa6, 0xd9, 0x00, 0xaa, 0x00, 0x62, 0xce, 0x6c }
-};
+{0x75B22633, 0x668E, 0x11CF, {0xa6, 0xd9, 0x00, 0xaa, 0x00, 0x62, 0xce, 0x6c}};
 
-static const guid_t asf_object_header_extention_guid =
-{
-   0x5FBF03B5,
-   0xA92E,
-   0x11CF,
-   { 0x8E,0xE3, 0x00,0xC0,0x0C,0x20,0x53,0x65 }
-};
+static const guid_t asf_object_header_extension_guid =
+{0x5FBF03B5, 0xA92E, 0x11CF, {0x8E, 0xE3, 0x00, 0xC0, 0x0C, 0x20, 0x53, 0x65}};
+
+static const guid_t asf_object_metadata_guid =
+{0xC5F8CBEA, 0x5BAF, 0x4877, {0x84, 0x67, 0xAA, 0x8C, 0x44, 0xFA, 0x4C, 0xCA}};
 
 static const guid_t asf_object_codec_list_guid =
-{
-    0x86D15240,
-    0x311D,
-    0x11D0,
-    { 0xA3,0xA4, 0x00,0xA0,0xC9,0x03,0x48,0xF6 }
-};
+{0x86D15240, 0x311D, 0x11D0, {0xA3, 0xA4, 0x00, 0xA0, 0xC9, 0x03, 0x48, 0xF6}};
 
 static const guid_t asf_object_marker_guid =
-{
-    0xF487CD01,
-    0xA951,
-    0x11CF,
-    { 0x8E,0xE6, 0x00,0xC0,0x0C,0x20,0x53,0x65 }
-
-};
+{0xF487CD01, 0xA951, 0x11CF, {0x8E, 0xE6, 0x00, 0xC0, 0x0C, 0x20, 0x53, 0x65}};
 
 static const guid_t asf_object_stream_type_audio =
-{
-    0xF8699E40,
-    0x5B4D,
-    0x11CF,
-    { 0xA8,0xFD, 0x00,0x80,0x5F,0x5C,0x44,0x2B }
-};
+{0xF8699E40, 0x5B4D, 0x11CF, {0xA8, 0xFD, 0x00, 0x80, 0x5F, 0x5C, 0x44, 0x2B}};
 
 static const guid_t asf_object_stream_type_video =
-{
-    0xbc19efc0,
-    0x5B4D,
-    0x11CF,
-    { 0xA8,0xFD, 0x00,0x80,0x5F,0x5C,0x44,0x2B }
-};
+{0xbc19efc0, 0x5B4D, 0x11CF, {0xA8, 0xFD, 0x00, 0x80, 0x5F, 0x5C, 0x44, 0x2B}};
 
 static const guid_t asf_object_stream_type_command =
-{
-    0x59DACFC0,
-    0x59E6,
-    0x11D0,
-    { 0xA3,0xAC, 0x00,0xA0,0xC9,0x03,0x48,0xF6 }
-};
+{0x59DACFC0, 0x59E6, 0x11D0, {0xA3, 0xAC, 0x00, 0xA0, 0xC9, 0x03, 0x48, 0xF6}};
 
-#define ASF_OBJECT_COMMON           \
-    int          i_type;            \
-    guid_t       i_object_id;       \
-    uint64_t     i_object_size;     \
-    uint64_t     i_object_pos;      \
+#define ASF_OBJECT_COMMON          \
+    int          i_type;           \
+    guid_t       i_object_id;      \
+    uint64_t     i_object_size;    \
+    uint64_t     i_object_pos;     \
     union asf_object_u *p_father;  \
     union asf_object_u *p_first;   \
     union asf_object_u *p_last;    \
@@ -253,16 +193,44 @@ typedef struct asf_object_stream_properties_s
     uint8_t     *p_error_correction_data;
 } asf_object_stream_properties_t;
 
-typedef struct asf_object_header_extention_s
+typedef struct asf_object_header_extension_s
 {
     ASF_OBJECT_COMMON
 
     guid_t      i_reserved1;
     uint16_t    i_reserved2;
-    uint32_t    i_header_extention_size;
-    uint8_t     *p_header_extention_data;
+    uint32_t    i_header_extension_size;
+    uint8_t     *p_header_extension_data;
+
+} asf_object_header_extension_t;
+
+#define ASF_METADATA_TYPE_STRING 0x0000
+#define ASF_METADATA_TYPE_BYTE   0x0001
+#define ASF_METADATA_TYPE_BOOL   0x0002
+#define ASF_METADATA_TYPE_DWORD  0x0003
+#define ASF_METADATA_TYPE_QWORD  0x0004
+#define ASF_METADATA_TYPE_WORD   0x0005
+
+typedef struct asf_metadata_record_s
+{
+    uint16_t    i_stream;
+    uint16_t    i_type;
+    char        *psz_name;
 
-} asf_object_header_extention_t;
+    int64_t i_val;
+    int i_data;
+    uint8_t *p_data;
+
+} asf_metadata_record_t;
+
+typedef struct asf_object_metadata_s
+{
+    ASF_OBJECT_COMMON
+
+    uint32_t i_record_entries_count;
+    asf_metadata_record_t *record;
+
+} asf_object_metadata_t;
 
 typedef struct asf_objec_content_description_s
 {
@@ -280,6 +248,7 @@ typedef struct string16_s
 {
     uint16_t i_length;
     uint16_t *i_char;
+
 } string16_t;
 
 #define ASF_CODEC_TYPE_VIDEO    0x0001
@@ -339,10 +308,14 @@ typedef struct asf_object_root_s
     asf_object_data_t   *p_data;
     /* could be NULL if !b_seekable or not-present */
     asf_object_index_t  *p_index;
+    asf_object_header_extension_t *p_hdr_ext;
 
     /* from asf_object_header_t */
     asf_object_file_properties_t *p_fp;
-    
+
+    /* from asf_object_header_extension_t */
+    asf_object_metadata_t *p_metadata;
+
 } asf_object_root_t;
 
 /****************************************************************************
@@ -357,23 +330,22 @@ typedef union asf_object_u
     asf_object_root_t   root;
     asf_object_file_properties_t    file_properties;
     asf_object_stream_properties_t  stream_properties;
-    asf_object_header_extention_t   header_extention;
+    asf_object_header_extension_t   header_extension;
+    asf_object_metadata_t           metadata;
     asf_object_codec_list_t         codec_list;
     asf_object_marker_t             marker;
 
 } asf_object_t;
 
 
-
-void ASF_GetGUID         ( guid_t *p_guid, uint8_t *p_data );
-int  ASF_CmpGUID         ( const guid_t *p_guid1, const guid_t *p_guid2 );
+void ASF_GetGUID( guid_t *p_guid, uint8_t *p_data );
+int  ASF_CmpGUID( const guid_t *p_guid1, const guid_t *p_guid2 );
 
 asf_object_root_t *ASF_ReadObjectRoot( stream_t *, int b_seekable );
-void               ASF_FreeObjectRoot  ( stream_t *, asf_object_root_t *p_root );
+void               ASF_FreeObjectRoot( stream_t *, asf_object_root_t *p_root );
 
 #define ASF_CountObject( a, b ) __ASF_CountObject( (asf_object_t*)(a), b )
-int  __ASF_CountObject   ( asf_object_t *p_obj, const guid_t *p_guid );
+int  __ASF_CountObject ( asf_object_t *p_obj, const guid_t *p_guid );
 
 #define ASF_FindObject( a, b, c )  __ASF_FindObject( (asf_object_t*)(a), b, c )
-void *__ASF_FindObject   ( asf_object_t *p_obj, const guid_t *p_guid, int i_number );
-
+void *__ASF_FindObject( asf_object_t *p_obj, const guid_t *p_guid, int i_number );