Commit 6c84da28 authored by Gildas Bazin's avatar Gildas Bazin

* commit modules/demux/asf/*: load and parse the metadata object + coding style changes.

parent 55cab795
/***************************************************************************** /*****************************************************************************
* libasf.c : * libasf.c : asf stream demux module for vlc
***************************************************************************** *****************************************************************************
* Copyright (C) 2001-2003 VideoLAN * Copyright (C) 2001-2003 VideoLAN
* $Id$ * $Id$
*
* Authors: Laurent Aimar <fenrir@via.ecp.fr> * Authors: Laurent Aimar <fenrir@via.ecp.fr>
* Gildas Bazin <gbazin@videolan.org>
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
...@@ -44,9 +46,7 @@ ...@@ -44,9 +46,7 @@
/**************************************************************************** /****************************************************************************
* *
****************************************************************************/ ****************************************************************************/
static int ASF_ReadObject( stream_t *, static int ASF_ReadObject( stream_t *, asf_object_t *, asf_object_t * );
asf_object_t *p_obj, asf_object_t *p_father );
/**************************************************************************** /****************************************************************************
* GUID functions * GUID functions
...@@ -87,6 +87,7 @@ static int ASF_ReadObjectCommon( stream_t *s, asf_object_t *p_obj ) ...@@ -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_size = GetQWLE( p_peek + 16 );
p_common->i_object_pos = stream_Tell( s ); p_common->i_object_pos = stream_Tell( s );
p_common->p_next = NULL; p_common->p_next = NULL;
#ifdef ASF_DEBUG #ifdef ASF_DEBUG
msg_Dbg( (vlc_object_t*)s, msg_Dbg( (vlc_object_t*)s,
"found object guid: " GUID_FMT " size:"I64Fd, "found object guid: " GUID_FMT " size:"I64Fd,
...@@ -113,9 +114,11 @@ static int ASF_NextObject( stream_t *s, asf_object_t *p_obj ) ...@@ -113,9 +114,11 @@ static int ASF_NextObject( stream_t *s, asf_object_t *p_obj )
{ {
return VLC_EGENERIC; 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 ) p_obj->common.i_object_pos + p_obj->common.i_object_size + 24 )
/* 24 is min size of an object */ /* 24 is min size of an object */
{ {
...@@ -124,9 +127,8 @@ static int ASF_NextObject( stream_t *s, asf_object_t *p_obj ) ...@@ -124,9 +127,8 @@ static int ASF_NextObject( stream_t *s, asf_object_t *p_obj )
} }
return stream_Seek( s, return stream_Seek( s, p_obj->common.i_object_pos +
p_obj->common.i_object_pos + p_obj->common.i_object_size );
p_obj->common.i_object_size );
} }
static void ASF_FreeObject_Null( asf_object_t *pp_obj ) 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 ) ...@@ -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->i_reserved2 = p_peek[29];
p_hdr->p_first = NULL; p_hdr->p_first = NULL;
p_hdr->p_last = NULL; p_hdr->p_last = NULL;
#ifdef ASF_DEBUG #ifdef ASF_DEBUG
msg_Dbg( (vlc_object_t*)s, msg_Dbg( (vlc_object_t*)s,
"read \"header object\" subobj:%d, reserved1:%d, reserved2:%d", "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 ) ...@@ -158,16 +161,18 @@ static int ASF_ReadObject_Header( stream_t *s, asf_object_t *p_obj )
p_hdr->i_reserved1, p_hdr->i_reserved1,
p_hdr->i_reserved2 ); p_hdr->i_reserved2 );
#endif #endif
/* Cannot failed as peek succeed */
/* Cannot fail as peek succeed */
stream_Read( s, NULL, 30 ); stream_Read( s, NULL, 30 );
/* Now load sub object */ /* Now load sub object */
for( ; ; ) 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 ) ) if( ASF_ReadObject( s, p_subobj, (asf_object_t*)p_hdr ) )
{ {
free( p_subobj );
break; break;
} }
if( ASF_NextObject( s, p_subobj ) ) /* Go to the next object */ 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 ) ...@@ -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 ); ASF_GetGUID( &p_data->i_file_id, p_peek + 24 );
p_data->i_total_data_packets = GetQWLE( p_peek + 40 ); p_data->i_total_data_packets = GetQWLE( p_peek + 40 );
p_data->i_reserved = GetWLE( p_peek + 48 ); p_data->i_reserved = GetWLE( p_peek + 48 );
#ifdef ASF_DEBUG #ifdef ASF_DEBUG
msg_Dbg( (vlc_object_t*)s, msg_Dbg( (vlc_object_t*)s,
"read \"data object\" file_id:" GUID_FMT " total data packet:" "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 ) ...@@ -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_total_data_packets,
p_data->i_reserved ); p_data->i_reserved );
#endif #endif
return VLC_SUCCESS; return VLC_SUCCESS;
} }
...@@ -228,8 +235,10 @@ static int ASF_ReadObject_Index( stream_t *s, asf_object_t *p_obj ) ...@@ -228,8 +235,10 @@ static int ASF_ReadObject_Index( stream_t *s, asf_object_t *p_obj )
p_index->i_max_packet_count, p_index->i_max_packet_count,
(long int)p_index->i_index_entry_count ); (long int)p_index->i_index_entry_count );
#endif #endif
return VLC_SUCCESS; return VLC_SUCCESS;
} }
static void ASF_FreeObject_Index( asf_object_t *p_obj ) static void ASF_FreeObject_Index( asf_object_t *p_obj )
{ {
asf_object_index_t *p_index = (asf_object_index_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 ) ...@@ -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" play_duration:"I64Fd" send_duration:"I64Fd" preroll:"
I64Fd" flags:%d min_data_packet_size:%d max_data_packet_size:%d " I64Fd" flags:%d min_data_packet_size:%d max_data_packet_size:%d "
"max_bitrate:%d", "max_bitrate:%d",
GUID_PRINT( p_fp->i_file_id ), GUID_PRINT( p_fp->i_file_id ), p_fp->i_file_size,
p_fp->i_file_size, p_fp->i_creation_date, p_fp->i_data_packets_count,
p_fp->i_creation_date, p_fp->i_play_duration, p_fp->i_send_duration,
p_fp->i_data_packets_count, p_fp->i_preroll, p_fp->i_flags,
p_fp->i_play_duration, p_fp->i_min_data_packet_size, p_fp->i_max_data_packet_size,
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 ); p_fp->i_max_bitrate );
#endif #endif
return VLC_SUCCESS; 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; int i_peek;
uint8_t *p_peek; uint8_t *p_peek;
...@@ -293,32 +418,56 @@ static int ASF_ReadObject_header_extention( stream_t *s, asf_object_t *p_obj ) ...@@ -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 ); ASF_GetGUID( &p_he->i_reserved1, p_peek + 24 );
p_he->i_reserved2 = GetWLE( p_peek + 40 ); p_he->i_reserved2 = GetWLE( p_peek + 40 );
p_he->i_header_extention_size = GetDWLE( p_peek + 42 ); p_he->i_header_extension_size = GetDWLE( p_peek + 42 );
if( p_he->i_header_extention_size ) if( p_he->i_header_extension_size )
{ {
p_he->p_header_extention_data = malloc( p_he->i_header_extention_size ); p_he->p_header_extension_data =
memcpy( p_he->p_header_extention_data, malloc( p_he->i_header_extension_size );
p_peek + 46, memcpy( p_he->p_header_extension_data, p_peek + 46,
p_he->i_header_extention_size ); p_he->i_header_extension_size );
} }
else else
{ {
p_he->p_header_extention_data = NULL; p_he->p_header_extension_data = NULL;
} }
#ifdef ASF_DEBUG #ifdef ASF_DEBUG
msg_Dbg( (vlc_object_t*)s, msg_Dbg( (vlc_object_t*)s,
"read \"header extention object\" reserved1:" GUID_FMT " reserved2:%d header_extention_size:%d", "read \"header extension object\" reserved1:" GUID_FMT
GUID_PRINT( p_he->i_reserved1 ), " reserved2:%d header_extension_size:%d",
p_he->i_reserved2, GUID_PRINT( p_he->i_reserved1 ), p_he->i_reserved2,
p_he->i_header_extention_size ); p_he->i_header_extension_size );
#endif #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; 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 ) 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 ) ...@@ -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 ); p_sp->i_reserved = GetDWLE( p_peek + 74 );
if( p_sp->i_type_specific_data_length ) if( p_sp->i_type_specific_data_length )
{ {
p_sp->p_type_specific_data = malloc( p_sp->i_type_specific_data_length ); p_sp->p_type_specific_data =
memcpy( p_sp->p_type_specific_data, malloc( p_sp->i_type_specific_data_length );
p_peek + 78, memcpy( p_sp->p_type_specific_data, p_peek + 78,
p_sp->i_type_specific_data_length ); p_sp->i_type_specific_data_length );
} }
else else
...@@ -353,7 +502,8 @@ static int ASF_ReadObject_stream_properties( stream_t *s, asf_object_t *p_obj ) ...@@ -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 ) 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, memcpy( p_sp->p_error_correction_data,
p_peek + 78 + p_sp->i_type_specific_data_length, p_peek + 78 + p_sp->i_type_specific_data_length,
p_sp->i_error_correction_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 ) ...@@ -462,23 +612,24 @@ static int ASF_ReadObject_codec_list( stream_t *s, asf_object_t *p_obj )
} }
#ifdef ASF_DEBUG #ifdef ASF_DEBUG
msg_Dbg( (vlc_object_t*)s, msg_Dbg( s, "read \"codec list object\" reserved_guid:" GUID_FMT
"read \"codec list object\" reserved_guid:" GUID_FMT " codec_entries_count:%d", " codec_entries_count:%d",
GUID_PRINT( p_cl->i_reserved ), GUID_PRINT( p_cl->i_reserved ), p_cl->i_codec_entries_count );
p_cl->i_codec_entries_count );
for( i_codec = 0; i_codec < p_cl->i_codec_entries_count; i_codec++ ) for( i_codec = 0; i_codec < p_cl->i_codec_entries_count; i_codec++ )
{ {
#define codec p_cl->codec[i_codec] #define codec p_cl->codec[i_codec]
msg_Dbg( (vlc_object_t*)s, msg_Dbg( s, "read \"codec list object\" codec[%d] %s name:\"%s\" "
"read \"codec list object\" codec[%d] %s name:\"%s\" description:\"%s\" information_length:%d", "description:\"%s\" information_length:%d",
i_codec, i_codec, ( codec.i_type == ASF_CODEC_TYPE_VIDEO ) ?
( codec.i_type == ASF_CODEC_TYPE_VIDEO ) ? "video" : ( ( codec.i_type == ASF_CODEC_TYPE_AUDIO ) ? "audio" : "unknown" ), "video" : ( ( codec.i_type == ASF_CODEC_TYPE_AUDIO ) ?
codec.psz_name, "audio" : "unknown" ),
codec.psz_description, codec.psz_name, codec.psz_description,
codec.i_information_length ); codec.i_information_length );
#undef codec
} }
#endif #endif
return VLC_SUCCESS; return VLC_SUCCESS;
} }
...@@ -493,7 +644,6 @@ static void ASF_FreeObject_codec_list( asf_object_t *p_obj ) ...@@ -493,7 +644,6 @@ static void ASF_FreeObject_codec_list( asf_object_t *p_obj )
FREE( codec.psz_name ); FREE( codec.psz_name );
FREE( codec.psz_description ); FREE( codec.psz_description );
FREE( codec.p_information ); FREE( codec.p_information );
#undef codec #undef codec
} }
FREE( p_cl->codec ); FREE( p_cl->codec );
...@@ -504,16 +654,10 @@ static void ASF_FreeObject_codec_list( asf_object_t *p_obj ) ...@@ -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) 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_cd =
(asf_object_content_description_t*)p_obj; (asf_object_content_description_t *)p_obj;
int i_peek;
uint8_t *p_peek, *p_data; uint8_t *p_peek, *p_data;
int i_peek;
int i_len; int i_len, i_title, i_author, i_copyright, i_description, i_rating;
int i_title;
int i_author;
int i_copyright;
int i_description;
int i_rating;
#define GETSTRINGW( psz_str, i_size ) \ #define GETSTRINGW( psz_str, i_size ) \
psz_str = calloc( i_size/2 + 1, sizeof( char ) ); \ 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) ...@@ -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) static void ASF_FreeObject_content_description( asf_object_t *p_obj)
{ {
asf_object_content_description_t *p_cd = 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_title );
FREE( p_cd->psz_author ); FREE( p_cd->psz_author );
...@@ -574,31 +718,41 @@ static struct ...@@ -574,31 +718,41 @@ static struct
int i_type; int i_type;
int (*ASF_ReadObject_function)( stream_t *, asf_object_t *p_obj ); int (*ASF_ReadObject_function)( stream_t *, asf_object_t *p_obj );
void (*ASF_FreeObject_function)( asf_object_t *p_obj ); void (*ASF_FreeObject_function)( asf_object_t *p_obj );
} ASF_Object_Function [] = } ASF_Object_Function [] =
{ {
{ &asf_object_header_guid, ASF_OBJECT_TYPE_HEADER, ASF_ReadObject_Header, ASF_FreeObject_Null }, { &asf_object_header_guid, ASF_OBJECT_TYPE_HEADER,
{ &asf_object_data_guid, ASF_OBJECT_TYPE_DATA, ASF_ReadObject_Data, ASF_FreeObject_Null }, ASF_ReadObject_Header, ASF_FreeObject_Null },
{ &asf_object_index_guid, ASF_OBJECT_TYPE_INDEX, ASF_ReadObject_Index, ASF_FreeObject_Index }, { &asf_object_data_guid, ASF_OBJECT_TYPE_DATA,
{ &asf_object_file_properties_guid, ASF_OBJECT_TYPE_FILE_PROPERTIES, ASF_ReadObject_file_properties, ASF_FreeObject_Null }, ASF_ReadObject_Data, ASF_FreeObject_Null },
{ &asf_object_stream_properties_guid, ASF_OBJECT_TYPE_STREAM_PROPERTIES, ASF_ReadObject_stream_properties,ASF_FreeObject_stream_properties }, { &asf_object_index_guid, ASF_OBJECT_TYPE_INDEX,
{ &asf_object_header_extention_guid, ASF_OBJECT_TYPE_EXTENTION_HEADER, ASF_ReadObject_header_extention, ASF_FreeObject_header_extention}, ASF_ReadObject_Index, ASF_FreeObject_Index },
{ &asf_object_codec_list_guid, ASF_OBJECT_TYPE_CODEC_LIST, ASF_ReadObject_codec_list, ASF_FreeObject_codec_list }, { &asf_object_file_properties_guid, ASF_OBJECT_TYPE_FILE_PROPERTIES,
{ &asf_object_marker_guid, ASF_OBJECT_TYPE_MARKER, NULL, NULL }, ASF_ReadObject_file_properties, ASF_FreeObject_Null },
{ &asf_object_content_description_guid, ASF_OBJECT_TYPE_CONTENT_DESCRIPTION, ASF_ReadObject_content_description, ASF_FreeObject_content_description }, { &asf_object_stream_properties_guid, ASF_OBJECT_TYPE_STREAM_PROPERTIES,
ASF_ReadObject_stream_properties,ASF_FreeObject_stream_properties },
{ &asf_object_null_guid, 0, NULL, NULL } { &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, static int ASF_ReadObject( stream_t *s, asf_object_t *p_obj,
asf_object_t *p_obj, asf_object_t *p_father ) asf_object_t *p_father )
{ {
int i_result; int i_result;
int i_index; int i_index;
if( !p_obj ) if( !p_obj ) return( 0 );
{
return( 0 );
}
if( ASF_ReadObjectCommon( s, p_obj ) ) if( ASF_ReadObjectCommon( s, p_obj ) )
{ {
msg_Warn( (vlc_object_t*)s, "cannot read one asf object" ); msg_Warn( (vlc_object_t*)s, "cannot read one asf object" );
...@@ -609,19 +763,19 @@ static int ASF_ReadObject( stream_t *s, ...@@ -609,19 +763,19 @@ static int ASF_ReadObject( stream_t *s,
p_obj->common.p_next = NULL; p_obj->common.p_next = NULL;
p_obj->common.p_last = NULL; p_obj->common.p_last = NULL;
if( p_obj->common.i_object_size < 24 ) if( p_obj->common.i_object_size < 24 )
{ {
msg_Warn( (vlc_object_t*)s, "found a corrupted asf object (size<24)" ); msg_Warn( (vlc_object_t*)s, "found a corrupted asf object (size<24)" );
return VLC_EGENERIC; return VLC_EGENERIC;
} }
/* find this object */ /* find this object */
for( i_index = 0; ; i_index++ ) for( i_index = 0; ; i_index++ )
{ {
if( ASF_CmpGUID( ASF_Object_Function[i_index].p_id, 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_CmpGUID( ASF_Object_Function[i_index].p_id,
&asf_object_null_guid ) ) &asf_object_null_guid ) )
{ {
break; break;
} }
...@@ -663,10 +817,7 @@ static void ASF_FreeObject( stream_t *s, asf_object_t *p_obj ) ...@@ -663,10 +817,7 @@ static void ASF_FreeObject( stream_t *s, asf_object_t *p_obj )
int i_index; int i_index;
asf_object_t *p_child; asf_object_t *p_child;
if( !p_obj ) if( !p_obj ) return;
{
return;
}
/* Free all child object */ /* Free all child object */
p_child = p_obj->common.p_first; p_child = p_obj->common.p_first;
...@@ -729,13 +880,16 @@ asf_object_root_t *ASF_ReadObjectRoot( stream_t *s, int b_seekable ) ...@@ -729,13 +880,16 @@ asf_object_root_t *ASF_ReadObjectRoot( stream_t *s, int b_seekable )
p_root->p_data = NULL; p_root->p_data = NULL;
p_root->p_fp = NULL; p_root->p_fp = NULL;
p_root->p_index = NULL; p_root->p_index = NULL;
p_root->p_hdr_ext = NULL;
p_root->p_metadata = NULL;
for( ; ; ) 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 ) ) if( ASF_ReadObject( s, p_obj, (asf_object_t*)p_root ) )
{ {
free( p_obj );
break; break;
} }
switch( p_obj->common.i_type ) switch( p_obj->common.i_type )
...@@ -749,6 +903,9 @@ asf_object_root_t *ASF_ReadObjectRoot( stream_t *s, int b_seekable ) ...@@ -749,6 +903,9 @@ asf_object_root_t *ASF_ReadObjectRoot( stream_t *s, int b_seekable )
case( ASF_OBJECT_TYPE_INDEX ): case( ASF_OBJECT_TYPE_INDEX ):
p_root->p_index = (asf_object_index_t*)p_obj; p_root->p_index = (asf_object_index_t*)p_obj;
break; break;
case( ASF_OBJECT_TYPE_HEADER_EXTENSION ):
p_root->p_hdr_ext = (asf_object_header_extension_t*)p_obj;
break;
default: default:
msg_Warn( (vlc_object_t*)s, "unknow object found" ); msg_Warn( (vlc_object_t*)s, "unknow object found" );
break; break;
...@@ -761,7 +918,7 @@ asf_object_root_t *ASF_ReadObjectRoot( stream_t *s, int b_seekable ) ...@@ -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 ) 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; break;
} }
...@@ -778,6 +935,14 @@ asf_object_root_t *ASF_ReadObjectRoot( stream_t *s, int b_seekable ) ...@@ -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_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; return p_root;
} }
msg_Warn( (vlc_object_t*)s, "cannot find file properties object" ); 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 ) ...@@ -808,10 +973,7 @@ int __ASF_CountObject( asf_object_t *p_obj, const guid_t *p_guid )
int i_count; int i_count;
asf_object_t *p_child; asf_object_t *p_child;
if( !p_obj ) if( !p_obj ) return( 0 );
{
return( 0 );
}
i_count = 0; i_count = 0;
p_child = p_obj->common.p_first; p_child = p_obj->common.p_first;
...@@ -826,7 +988,8 @@ int __ASF_CountObject( asf_object_t *p_obj, const guid_t *p_guid ) ...@@ -826,7 +988,8 @@ int __ASF_CountObject( asf_object_t *p_obj, const guid_t *p_guid )
return( i_count ); 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; 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 ...@@ -848,4 +1011,3 @@ void *__ASF_FindObject( asf_object_t *p_obj, const guid_t *p_guid, int i_number
} }
return( NULL ); return( NULL );
} }
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* libasf.h : * libasf.h :
***************************************************************************** *****************************************************************************
* Copyright (C) 2001-2003 VideoLAN * 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> * Authors: Laurent Aimar <fenrir@via.ecp.fr>
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
...@@ -39,10 +39,11 @@ typedef struct guid_s ...@@ -39,10 +39,11 @@ typedef struct guid_s
#define ASF_OBJECT_TYPE_INDEX 0x0004 #define ASF_OBJECT_TYPE_INDEX 0x0004
#define ASF_OBJECT_TYPE_FILE_PROPERTIES 0x0005 #define ASF_OBJECT_TYPE_FILE_PROPERTIES 0x0005
#define ASF_OBJECT_TYPE_STREAM_PROPERTIES 0x0006 #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_CODEC_LIST 0x0008
#define ASF_OBJECT_TYPE_MARKER 0x0009 #define ASF_OBJECT_TYPE_MARKER 0x0009
#define ASF_OBJECT_TYPE_CONTENT_DESCRIPTION 0x000a #define ASF_OBJECT_TYPE_CONTENT_DESCRIPTION 0x000a
#define ASF_OBJECT_TYPE_METADATA 0x000b
static const guid_t asf_object_null_guid = static const guid_t asf_object_null_guid =
{ {
...@@ -53,110 +54,49 @@ 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 = 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 = 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 = 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 = 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 = 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 = 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 = static const guid_t asf_object_header_extension_guid =
{ {0x5FBF03B5, 0xA92E, 0x11CF, {0x8E, 0xE3, 0x00, 0xC0, 0x0C, 0x20, 0x53, 0x65}};
0x5FBF03B5,
0xA92E, static const guid_t asf_object_metadata_guid =
0x11CF, {0xC5F8CBEA, 0x5BAF, 0x4877, {0x84, 0x67, 0xAA, 0x8C, 0x44, 0xFA, 0x4C, 0xCA}};
{ 0x8E,0xE3, 0x00,0xC0,0x0C,0x20,0x53,0x65 }
};
static const guid_t asf_object_codec_list_guid = 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 = 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 = 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 = 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 = 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 \ #define ASF_OBJECT_COMMON \
int i_type; \ int i_type; \
guid_t i_object_id; \ guid_t i_object_id; \
uint64_t i_object_size; \ uint64_t i_object_size; \
uint64_t i_object_pos; \ uint64_t i_object_pos; \
union asf_object_u *p_father; \ union asf_object_u *p_father; \
union asf_object_u *p_first; \ union asf_object_u *p_first; \
union asf_object_u *p_last; \ union asf_object_u *p_last; \
...@@ -253,16 +193,44 @@ typedef struct asf_object_stream_properties_s ...@@ -253,16 +193,44 @@ typedef struct asf_object_stream_properties_s
uint8_t *p_error_correction_data; uint8_t *p_error_correction_data;
} asf_object_stream_properties_t; } asf_object_stream_properties_t;
typedef struct asf_object_header_extention_s typedef struct asf_object_header_extension_s
{ {
ASF_OBJECT_COMMON ASF_OBJECT_COMMON
guid_t i_reserved1; guid_t i_reserved1;
uint16_t i_reserved2; uint16_t i_reserved2;
uint32_t i_header_extention_size; uint32_t i_header_extension_size;
uint8_t *p_header_extention_data; 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 typedef struct asf_objec_content_description_s
{ {
...@@ -280,6 +248,7 @@ typedef struct string16_s ...@@ -280,6 +248,7 @@ typedef struct string16_s
{ {
uint16_t i_length; uint16_t i_length;
uint16_t *i_char; uint16_t *i_char;
} string16_t; } string16_t;
#define ASF_CODEC_TYPE_VIDEO 0x0001 #define ASF_CODEC_TYPE_VIDEO 0x0001
...@@ -339,10 +308,14 @@ typedef struct asf_object_root_s ...@@ -339,10 +308,14 @@ typedef struct asf_object_root_s
asf_object_data_t *p_data; asf_object_data_t *p_data;
/* could be NULL if !b_seekable or not-present */ /* could be NULL if !b_seekable or not-present */
asf_object_index_t *p_index; asf_object_index_t *p_index;
asf_object_header_extension_t *p_hdr_ext;
/* from asf_object_header_t */ /* from asf_object_header_t */
asf_object_file_properties_t *p_fp; asf_object_file_properties_t *p_fp;
/* from asf_object_header_extension_t */
asf_object_metadata_t *p_metadata;
} asf_object_root_t; } asf_object_root_t;
/**************************************************************************** /****************************************************************************
...@@ -357,23 +330,22 @@ typedef union asf_object_u ...@@ -357,23 +330,22 @@ typedef union asf_object_u
asf_object_root_t root; asf_object_root_t root;
asf_object_file_properties_t file_properties; asf_object_file_properties_t file_properties;
asf_object_stream_properties_t stream_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_codec_list_t codec_list;
asf_object_marker_t marker; asf_object_marker_t marker;
} asf_object_t; } asf_object_t;
void ASF_GetGUID( guid_t *p_guid, uint8_t *p_data );
void ASF_GetGUID ( guid_t *p_guid, uint8_t *p_data ); int ASF_CmpGUID( const guid_t *p_guid1, const guid_t *p_guid2 );
int ASF_CmpGUID ( const guid_t *p_guid1, const guid_t *p_guid2 );
asf_object_root_t *ASF_ReadObjectRoot( stream_t *, int b_seekable ); 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 ) #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 ) #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 );
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment