Commit d10ad52f authored by Laurent Aimar's avatar Laurent Aimar

* asf: clean up + use stream_* (It's not yet well tested)

parent c95c5508
SOURCES_asf = \ SOURCES_asf = \
asf.c \ asf.c \
asf.h \
libasf.c \ libasf.c \
libasf.h \ libasf.h \
$(NULL) $(NULL)
/***************************************************************************** /*****************************************************************************
* asf.c : ASFv01 file input module for vlc * asf.c : ASFv01 file input module for vlc
***************************************************************************** *****************************************************************************
* Copyright (C) 2001 VideoLAN * Copyright (C) 2002-2003 VideoLAN
* $Id: asf.c,v 1.33 2003/08/18 00:17:44 fenrir Exp $ * $Id: asf.c,v 1.34 2003/08/18 19:18:47 fenrir Exp $
*
* 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
...@@ -27,10 +28,10 @@ ...@@ -27,10 +28,10 @@
#include <vlc/vlc.h> #include <vlc/vlc.h>
#include <vlc/input.h> #include <vlc/input.h>
#include "ninput.h"
#include "codecs.h" /* BITMAPINFOHEADER, WAVEFORMATEX */ #include "codecs.h" /* BITMAPINFOHEADER, WAVEFORMATEX */
#include "libasf.h" #include "libasf.h"
#include "asf.h"
/***************************************************************************** /*****************************************************************************
* Module descriptor * Module descriptor
...@@ -51,6 +52,35 @@ vlc_module_end(); ...@@ -51,6 +52,35 @@ vlc_module_end();
*****************************************************************************/ *****************************************************************************/
static int Demux ( input_thread_t * ); static int Demux ( input_thread_t * );
typedef struct asf_stream_s
{
int i_cat;
es_descriptor_t *p_es;
asf_object_stream_properties_t *p_sp;
mtime_t i_time;
pes_packet_t *p_pes; /* used to keep uncomplete frames */
} asf_stream_t;
struct demux_sys_t
{
mtime_t i_time; /* s */
mtime_t i_length; /* length of file file */
asf_object_root_t *p_root;
asf_object_file_properties_t *p_fp;
unsigned int i_streams;
asf_stream_t *stream[128];
int64_t i_data_begin;
int64_t i_data_end;
stream_t *s;
};
static mtime_t GetMoviePTS( demux_sys_t * ); static mtime_t GetMoviePTS( demux_sys_t * );
static int DemuxPacket( input_thread_t *, vlc_bool_t b_play_audio ); static int DemuxPacket( input_thread_t *, vlc_bool_t b_play_audio );
...@@ -61,10 +91,13 @@ static int Open( vlc_object_t * p_this ) ...@@ -61,10 +91,13 @@ static int Open( vlc_object_t * p_this )
{ {
input_thread_t *p_input = (input_thread_t *)p_this; input_thread_t *p_input = (input_thread_t *)p_this;
uint8_t *p_peek; uint8_t *p_peek;
guid_t guid; guid_t guid;
demux_sys_t *p_demux; demux_sys_t *p_sys;
int i_stream; unsigned int i_stream;
unsigned int i;
asf_object_content_description_t *p_cd;
vlc_bool_t b_seekable; vlc_bool_t b_seekable;
...@@ -85,54 +118,46 @@ static int Open( vlc_object_t * p_this ) ...@@ -85,54 +118,46 @@ static int Open( vlc_object_t * p_this )
/* Set p_input field */ /* Set p_input field */
p_input->pf_demux = Demux; p_input->pf_demux = Demux;
p_input->p_demux_data = p_demux = malloc( sizeof( demux_sys_t ) ); p_input->p_demux_data = p_sys = malloc( sizeof( demux_sys_t ) );
memset( p_demux, 0, sizeof( demux_sys_t ) ); memset( p_sys, 0, sizeof( demux_sys_t ) );
p_demux->i_time = -1; p_sys->i_time = -1;
p_sys->i_length = 0;
/* Now load all object ( except raw data ) */
b_seekable = p_input->stream.b_seekable &&
p_input->stream.i_method == INPUT_METHOD_FILE;
if( !ASF_ReadObjectRoot( p_input, &p_demux->root, b_seekable ) ) /* Create stream facilities */
if( ( p_sys->s = stream_OpenInput( p_input ) ) == NULL )
{ {
msg_Warn( p_input, "ASF plugin discarded (not a valid file)" ); msg_Err( p_input, "cannot create stream" );
free( p_demux ); free( p_sys );
return VLC_EGENERIC; return VLC_EGENERIC;
} }
/* Check if we have found all mandatory asf object */
if( !p_demux->root.p_hdr || !p_demux->root.p_data )
{
msg_Warn( p_input, "ASF plugin discarded (not a valid file)" );
goto error;
}
if( !( p_demux->p_fp = ASF_FindObject( p_demux->root.p_hdr, /* Now load all object ( except raw data ) */
&asf_object_file_properties_guid, 0 ) ) ) stream_Control( p_sys->s, STREAM_CAN_FASTSEEK, &b_seekable );
if( (p_sys->p_root = ASF_ReadObjectRoot( p_sys->s, b_seekable )) == NULL )
{ {
msg_Warn( p_input, msg_Warn( p_input, "ASF plugin discarded (not a valid file)" );
"ASF plugin discarded (missing file_properties object)" ); stream_Release( p_sys->s );
goto error; free( p_sys );
return VLC_EGENERIC;
} }
p_sys->p_fp = p_sys->p_root->p_fp;
if( p_demux->p_fp->i_min_data_packet_size != p_demux->p_fp->i_max_data_packet_size ) if( p_sys->p_fp->i_min_data_packet_size != p_sys->p_fp->i_max_data_packet_size )
{ {
msg_Warn( p_input, msg_Warn( p_input,
"ASF plugin discarded (invalid file_properties object)" ); "ASF plugin discarded (invalid file_properties object)" );
goto error; goto error;
} }
p_demux->i_streams = ASF_CountObject( p_demux->root.p_hdr, p_sys->i_streams = ASF_CountObject( p_sys->p_root->p_hdr,
&asf_object_stream_properties_guid ); &asf_object_stream_properties_guid );
if( !p_demux->i_streams ) if( !p_sys->i_streams )
{ {
msg_Warn( p_input, "ASF plugin discarded (cannot find any stream!)" ); msg_Warn( p_input, "ASF plugin discarded (cannot find any stream!)" );
goto error; goto error;
} }
msg_Dbg( p_input, "found %d streams", p_demux->i_streams ); msg_Dbg( p_input, "found %d streams", p_sys->i_streams );
p_cat = input_InfoCategory( p_input, "Asf" );
input_AddInfo( p_cat, _("Number of streams"), "%d" , p_demux->i_streams );
/* create one program */ /* create one program */
vlc_mutex_lock( &p_input->stream.stream_lock ); vlc_mutex_lock( &p_input->stream.stream_lock );
...@@ -152,30 +177,24 @@ static int Open( vlc_object_t * p_this ) ...@@ -152,30 +177,24 @@ static int Open( vlc_object_t * p_this )
p_input->stream.i_mux_rate = 0 ; /* updated later */ p_input->stream.i_mux_rate = 0 ; /* updated later */
vlc_mutex_unlock( &p_input->stream.stream_lock ); vlc_mutex_unlock( &p_input->stream.stream_lock );
for( i_stream = 0; i_stream < p_demux->i_streams; i_stream ++ ) for( i_stream = 0; i_stream < p_sys->i_streams; i_stream ++ )
{ {
asf_stream_t *p_stream; asf_stream_t *p_stream;
asf_object_stream_properties_t *p_sp; asf_object_stream_properties_t *p_sp;
char psz_cat[sizeof("Stream ")+10];
sprintf( psz_cat, "Stream %d", i_stream );
p_cat = input_InfoCategory( p_input, psz_cat);
p_sp = ASF_FindObject( p_demux->root.p_hdr, p_sp = ASF_FindObject( p_sys->p_root->p_hdr,
&asf_object_stream_properties_guid, &asf_object_stream_properties_guid,
i_stream ); i_stream );
p_stream = p_stream =
p_demux->stream[p_sp->i_stream_number] = p_sys->stream[p_sp->i_stream_number] =
malloc( sizeof( asf_stream_t ) ); malloc( sizeof( asf_stream_t ) );
memset( p_stream, 0, sizeof( asf_stream_t ) ); memset( p_stream, 0, sizeof( asf_stream_t ) );
p_stream->i_time = -1; p_stream->i_time = -1;
p_stream->p_sp = p_sp; p_stream->p_sp = p_sp;
vlc_mutex_lock( &p_input->stream.stream_lock );
p_stream->p_es = NULL; p_stream->p_es = NULL;
vlc_mutex_unlock( &p_input->stream.stream_lock );
if( ASF_CmpGUID( &p_sp->i_stream_type, &asf_object_stream_type_audio ) ) if( ASF_CmpGUID( &p_sp->i_stream_type, &asf_object_stream_type_audio ) )
{ {
int i_codec; int i_codec;
...@@ -193,13 +212,11 @@ static int Open( vlc_object_t * p_this ) ...@@ -193,13 +212,11 @@ static int Open( vlc_object_t * p_this )
p_input->stream.p_selected_program, p_input->stream.p_selected_program,
p_sp->i_stream_number, AUDIO_ES, NULL, 0 ); p_sp->i_stream_number, AUDIO_ES, NULL, 0 );
input_AddInfo( p_cat, _("Type"), _("Audio") );
msg_Dbg( p_input, msg_Dbg( p_input,
"adding new audio stream(codec:0x%x,ID:%d)", "adding new audio stream(codec:0x%x,ID:%d)",
i_codec, i_codec,
p_sp->i_stream_number ); p_sp->i_stream_number );
wf_tag_to_fourcc( i_codec, &p_stream->p_es->i_fourcc, NULL ); wf_tag_to_fourcc( i_codec, &p_stream->p_es->i_fourcc, NULL );
input_AddInfo( p_cat, _("Codec"), "%.4s", (char*)&p_stream->p_es->i_fourcc );
if( p_sp->i_type_specific_data_length > 0 ) if( p_sp->i_type_specific_data_length > 0 )
{ {
...@@ -215,14 +232,10 @@ static int Open( vlc_object_t * p_this ) ...@@ -215,14 +232,10 @@ static int Open( vlc_object_t * p_this )
p_wf->wFormatTag = GetWLE( p_data ); p_wf->wFormatTag = GetWLE( p_data );
p_wf->nChannels = GetWLE( p_data + 2 ); p_wf->nChannels = GetWLE( p_data + 2 );
input_AddInfo( p_cat, _("Channels"), "%d", p_wf->nChannels );
p_wf->nSamplesPerSec = GetDWLE( p_data + 4 ); p_wf->nSamplesPerSec = GetDWLE( p_data + 4 );
input_AddInfo( p_cat, _("Sample Rate"), "%d", p_wf->nSamplesPerSec );
p_wf->nAvgBytesPerSec = GetDWLE( p_data + 8 ); p_wf->nAvgBytesPerSec = GetDWLE( p_data + 8 );
input_AddInfo( p_cat, _("Avg. byterate"), "%d", p_wf->nAvgBytesPerSec );
p_wf->nBlockAlign = GetWLE( p_data + 12 ); p_wf->nBlockAlign = GetWLE( p_data + 12 );
p_wf->wBitsPerSample = GetWLE( p_data + 14 ); p_wf->wBitsPerSample = GetWLE( p_data + 14 );
input_AddInfo( p_cat, _("Bits Per Sample"), "%d", p_wf->wBitsPerSample );
p_wf->cbSize = __MIN( GetWLE( p_data + 16 ), i_size - sizeof( WAVEFORMATEX )); p_wf->cbSize = __MIN( GetWLE( p_data + 16 ), i_size - sizeof( WAVEFORMATEX ));
if( p_wf->cbSize > 0 ) if( p_wf->cbSize > 0 )
{ {
...@@ -238,7 +251,6 @@ static int Open( vlc_object_t * p_this ) ...@@ -238,7 +251,6 @@ static int Open( vlc_object_t * p_this )
p_input->stream.p_selected_program, p_input->stream.p_selected_program,
p_sp->i_stream_number, VIDEO_ES, NULL, 0 ); p_sp->i_stream_number, VIDEO_ES, NULL, 0 );
input_AddInfo( p_cat, _("Type"), _("Video") );
msg_Dbg( p_input, "adding new video stream(ID:%d)", msg_Dbg( p_input, "adding new video stream(ID:%d)",
p_sp->i_stream_number ); p_sp->i_stream_number );
if( p_sp->p_type_specific_data ) if( p_sp->p_type_specific_data )
...@@ -254,7 +266,6 @@ static int Open( vlc_object_t * p_this ) ...@@ -254,7 +266,6 @@ static int Open( vlc_object_t * p_this )
p_stream->p_es->i_fourcc = p_stream->p_es->i_fourcc =
VLC_FOURCC( 'u','n','d','f' ); VLC_FOURCC( 'u','n','d','f' );
} }
input_AddInfo( p_cat, _("Codec"), "%.4s", (char*)&p_stream->p_es->i_fourcc );
if( p_sp->i_type_specific_data_length > 11 ) if( p_sp->i_type_specific_data_length > 11 )
{ {
BITMAPINFOHEADER *p_bih; BITMAPINFOHEADER *p_bih;
...@@ -268,27 +279,20 @@ static int Open( vlc_object_t * p_this ) ...@@ -268,27 +279,20 @@ static int Open( vlc_object_t * p_this )
p_data = p_sp->p_type_specific_data + 11; p_data = p_sp->p_type_specific_data + 11;
p_bih->biSize = GetDWLE( p_data ); p_bih->biSize = GetDWLE( p_data );
input_AddInfo( p_cat, _("Size"), "%d", p_bih->biSize );
p_bih->biWidth = GetDWLE( p_data + 4 ); p_bih->biWidth = GetDWLE( p_data + 4 );
p_bih->biHeight = GetDWLE( p_data + 8 ); p_bih->biHeight = GetDWLE( p_data + 8 );
input_AddInfo( p_cat, _("Resolution"), "%dx%d", p_bih->biWidth, p_bih->biHeight );
p_bih->biPlanes = GetDWLE( p_data + 12 ); p_bih->biPlanes = GetDWLE( p_data + 12 );
input_AddInfo( p_cat, _("Planes"), "%d", p_bih->biPlanes );
p_bih->biBitCount = GetDWLE( p_data + 14 ); p_bih->biBitCount = GetDWLE( p_data + 14 );
input_AddInfo( p_cat, _("Bits Per Pixel"), "%d", p_bih->biBitCount );
p_bih->biCompression= GetDWLE( p_data + 16 ); p_bih->biCompression= GetDWLE( p_data + 16 );
p_bih->biSizeImage = GetDWLE( p_data + 20 ); p_bih->biSizeImage = GetDWLE( p_data + 20 );
input_AddInfo( p_cat, _("Image Size"), "%d", p_bih->biSizeImage );
p_bih->biXPelsPerMeter = GetDWLE( p_data + 24 ); p_bih->biXPelsPerMeter = GetDWLE( p_data + 24 );
input_AddInfo( p_cat, _("X pixels per meter"), "%d", p_bih->biXPelsPerMeter );
p_bih->biYPelsPerMeter = GetDWLE( p_data + 28 ); p_bih->biYPelsPerMeter = GetDWLE( p_data + 28 );
input_AddInfo( p_cat, _("Y pixels per meter"), "%d", p_bih->biYPelsPerMeter );
p_bih->biClrUsed = GetDWLE( p_data + 32 ); p_bih->biClrUsed = GetDWLE( p_data + 32 );
p_bih->biClrImportant = GetDWLE( p_data + 36 ); p_bih->biClrImportant = GetDWLE( p_data + 36 );
if( i_size > sizeof( BITMAPINFOHEADER ) ) if( i_size > sizeof( BITMAPINFOHEADER ) )
{ {
memcpy( (uint8_t*)p_bih + sizeof( BITMAPINFOHEADER ), memcpy( &p_bih[1],
p_data + sizeof( BITMAPINFOHEADER ), p_data + sizeof( BITMAPINFOHEADER ),
i_size - sizeof( BITMAPINFOHEADER ) ); i_size - sizeof( BITMAPINFOHEADER ) );
} }
...@@ -311,61 +315,141 @@ static int Open( vlc_object_t * p_this ) ...@@ -311,61 +315,141 @@ static int Open( vlc_object_t * p_this )
} }
p_demux->i_data_begin = p_demux->root.p_data->i_object_pos + 50; p_sys->i_data_begin = p_sys->p_root->p_data->i_object_pos + 50;
if( p_demux->root.p_data->i_object_size != 0 ) if( p_sys->p_root->p_data->i_object_size != 0 )
{ // local file { // local file
p_demux->i_data_end = p_demux->root.p_data->i_object_pos + p_sys->i_data_end = p_sys->p_root->p_data->i_object_pos +
p_demux->root.p_data->i_object_size; p_sys->p_root->p_data->i_object_size;
} }
else else
{ // live/broacast { // live/broacast
p_demux->i_data_end = -1; p_sys->i_data_end = -1;
} }
// go to first packet // go to first packet
ASF_SeekAbsolute( p_input, p_demux->i_data_begin ); stream_Control( p_sys->s, STREAM_SET_POSITION, (int64_t)p_sys->i_data_begin );
vlc_mutex_lock( &p_input->stream.stream_lock );
/* try to calculate movie time */ /* try to calculate movie time */
if( p_demux->p_fp->i_data_packets_count > 0 ) if( p_sys->p_fp->i_data_packets_count > 0 )
{ {
int64_t i_count; int64_t i_count;
mtime_t i_length; int64_t i_size;
stream_Control( p_sys->s, STREAM_GET_SIZE, &i_size );
if( p_sys->i_data_end > 0 && i_size > p_sys->i_data_end )
{
i_size = p_sys->i_data_end;
}
/* real number of packets */ /* real number of packets */
i_count = ( p_input->stream.p_selected_area->i_size - i_count = ( i_size - p_sys->i_data_begin ) /
p_demux->i_data_begin ) / p_sys->p_fp->i_min_data_packet_size;
p_demux->p_fp->i_min_data_packet_size;
/* calculate the time duration in s */ /* calculate the time duration in micro-s */
i_length = (mtime_t)p_demux->p_fp->i_play_duration / 10 * p_sys->i_length = (mtime_t)p_sys->p_fp->i_play_duration / 10 *
(mtime_t)i_count / (mtime_t)i_count /
(mtime_t)p_demux->p_fp->i_data_packets_count / (mtime_t)p_sys->p_fp->i_data_packets_count;
(mtime_t)1000000;
if( i_length > 0 ) if( p_sys->i_length > 0 )
{ {
p_input->stream.i_mux_rate = p_input->stream.i_mux_rate =
p_input->stream.p_selected_area->i_size / 50 / i_length; i_size / 50 * (int64_t)1000000 / p_sys->i_length;
} }
else
{
p_input->stream.i_mux_rate = 0;
}
}
else
{
/* cannot known */
p_input->stream.i_mux_rate = 0;
} }
vlc_mutex_lock( &p_input->stream.stream_lock );
p_input->stream.p_selected_program->b_is_ok = 1; p_input->stream.p_selected_program->b_is_ok = 1;
vlc_mutex_unlock( &p_input->stream.stream_lock ); vlc_mutex_unlock( &p_input->stream.stream_lock );
/* We add all info about this stream */
p_cat = input_InfoCategory( p_input, "Asf" );
if( p_sys->i_length > 0 )
{
int64_t i_second = p_sys->i_length / (int64_t)1000000;
input_AddInfo( p_cat, _("Length"), "%d:%d:%d",
(int)(i_second / 36000),
(int)(( i_second / 60 ) % 60),
(int)(i_second % 60) );
}
input_AddInfo( p_cat, _("Number of streams"), "%d" , p_sys->i_streams );
if( ( p_cd = ASF_FindObject( p_sys->p_root->p_hdr,
&asf_object_content_description_guid, 0 ) ) )
{
if( *p_cd->psz_title )
input_AddInfo( p_cat, _("Title"), p_cd->psz_title );
if( p_cd->psz_author )
input_AddInfo( p_cat, _("Author"), p_cd->psz_author );
if( p_cd->psz_copyright )
input_AddInfo( p_cat, _("Copyright"), p_cd->psz_copyright );
if( *p_cd->psz_description )
input_AddInfo( p_cat, _("Description"), p_cd->psz_description );
if( *p_cd->psz_rating )
input_AddInfo( p_cat, _("Rating"), p_cd->psz_rating );
}
for( i_stream = 0, i = 0; i < 128; i++ )
{
asf_stream_t *tk = p_sys->stream[i];
asf_object_codec_list_t *p_cl =
ASF_FindObject( p_sys->p_root->p_hdr,
&asf_object_codec_list_guid, 0 );
char psz_cat[sizeof(_("Stream "))+10];
if( p_sys->stream[i] == NULL )
{
continue;
}
sprintf( psz_cat, _("Stream %d"), i_stream );
p_cat = input_InfoCategory( p_input, psz_cat);
input_AddInfo( p_cat, _("Type"),
( tk->i_cat == AUDIO_ES ? _("Audio") : _("Video") ) );
input_AddInfo( p_cat, _("Codec"), "%.4s",
(char*)&tk->p_es->i_fourcc );
if( p_cl && i_stream < p_cl->i_codec_entries_count )
{
input_AddInfo( p_cat, _("Codec name"),
p_cl->codec[i_stream].psz_name );
input_AddInfo( p_cat, _("Codec description"),
p_cl->codec[i_stream].psz_description );
}
if( tk->i_cat == AUDIO_ES && tk->p_es->p_waveformatex )
{
WAVEFORMATEX *p_wf = tk->p_es->p_waveformatex;
input_AddInfo( p_cat, _("Channels"), "%d", p_wf->nChannels );
input_AddInfo( p_cat, _("Sample Rate"), "%d", p_wf->nSamplesPerSec );
input_AddInfo( p_cat, _("Avg. byterate"), "%d", p_wf->nAvgBytesPerSec );
input_AddInfo( p_cat, _("Bits Per Sample"), "%d", p_wf->wBitsPerSample );
}
else if( tk->i_cat == VIDEO_ES && tk->p_es->p_bitmapinfoheader )
{
BITMAPINFOHEADER *p_bih = tk->p_es->p_bitmapinfoheader;
input_AddInfo( p_cat, _("Resolution"), "%dx%d",
p_bih->biWidth, p_bih->biHeight );
input_AddInfo( p_cat, _("Planes"), "%d", p_bih->biPlanes );
input_AddInfo( p_cat, _("Bits Per Pixel"), "%d", p_bih->biBitCount );
input_AddInfo( p_cat, _("Image Size"), "%d", p_bih->biSizeImage );
input_AddInfo( p_cat, _("X pixels per meter"), "%d",
p_bih->biXPelsPerMeter );
input_AddInfo( p_cat, _("Y pixels per meter"), "%d",
p_bih->biYPelsPerMeter );
}
i_stream++;
}
return VLC_SUCCESS; return VLC_SUCCESS;
error: error:
ASF_FreeObjectRoot( p_input, &p_demux->root ); ASF_FreeObjectRoot( p_sys->s, p_sys->p_root );
free( p_demux ); stream_Release( p_sys->s );
free( p_sys );
return VLC_EGENERIC; return VLC_EGENERIC;
} }
...@@ -375,7 +459,7 @@ error: ...@@ -375,7 +459,7 @@ error:
*****************************************************************************/ *****************************************************************************/
static int Demux( input_thread_t *p_input ) static int Demux( input_thread_t *p_input )
{ {
demux_sys_t *p_demux = p_input->p_demux_data; demux_sys_t *p_sys = p_input->p_demux_data;
vlc_bool_t b_play_audio; vlc_bool_t b_play_audio;
int i; int i;
vlc_bool_t b_stream; vlc_bool_t b_stream;
...@@ -383,9 +467,9 @@ static int Demux( input_thread_t *p_input ) ...@@ -383,9 +467,9 @@ static int Demux( input_thread_t *p_input )
b_stream = VLC_FALSE; b_stream = VLC_FALSE;
for( i = 0; i < 128; i++ ) for( i = 0; i < 128; i++ )
{ {
if( p_demux->stream[i] && if( p_sys->stream[i] &&
p_demux->stream[i]->p_es && p_sys->stream[i]->p_es &&
p_demux->stream[i]->p_es->p_decoder_fifo ) p_sys->stream[i]->p_es->p_decoder_fifo )
{ {
b_stream = VLC_TRUE; b_stream = VLC_TRUE;
} }
...@@ -399,23 +483,32 @@ static int Demux( input_thread_t *p_input ) ...@@ -399,23 +483,32 @@ static int Demux( input_thread_t *p_input )
/* catch seek from user */ /* catch seek from user */
if( p_input->stream.p_selected_program->i_synchro_state == SYNCHRO_REINIT ) if( p_input->stream.p_selected_program->i_synchro_state == SYNCHRO_REINIT )
{ {
off_t i_offset; int64_t i_offset;
msleep( p_input->i_pts_delay ); msleep( p_input->i_pts_delay );
i_offset = ASF_TellAbsolute( p_input ) - p_demux->i_data_begin;
stream_Control( p_sys->s, STREAM_GET_POSITION, &i_offset );
i_offset -= p_sys->i_data_begin;
if( i_offset < 0 ) if( i_offset < 0 )
{ {
i_offset = 0; i_offset = 0;
} }
i_offset += p_demux->p_fp->i_min_data_packet_size - if( i_offset % p_sys->p_fp->i_min_data_packet_size > 0 )
i_offset % p_demux->p_fp->i_min_data_packet_size; {
ASF_SeekAbsolute( p_input, p_demux->i_data_begin + i_offset ); i_offset -= i_offset % p_sys->p_fp->i_min_data_packet_size;
}
i_offset += p_sys->i_data_begin;
p_demux->i_time = -1; if( stream_Control( p_sys->s, STREAM_SET_POSITION, i_offset ) )
{
msg_Warn( p_input, "cannot resynch after seek (EOF?)" );
return -1;
}
p_sys->i_time = -1;
for( i = 0; i < 128 ; i++ ) for( i = 0; i < 128 ; i++ )
{ {
#define p_stream p_demux->stream[i] #define p_stream p_sys->stream[i]
if( p_stream ) if( p_stream )
{ {
p_stream->i_time = -1; p_stream->i_time = -1;
...@@ -430,7 +523,7 @@ static int Demux( input_thread_t *p_input ) ...@@ -430,7 +523,7 @@ static int Demux( input_thread_t *p_input )
for( ;; ) for( ;; )
{ {
mtime_t i_length; mtime_t i_length;
mtime_t i_time_begin = GetMoviePTS( p_demux ); mtime_t i_time_begin = GetMoviePTS( p_sys );
int i_result; int i_result;
if( p_input->b_die ) if( p_input->b_die )
...@@ -444,11 +537,11 @@ static int Demux( input_thread_t *p_input ) ...@@ -444,11 +537,11 @@ static int Demux( input_thread_t *p_input )
} }
if( i_time_begin == -1 ) if( i_time_begin == -1 )
{ {
i_time_begin = GetMoviePTS( p_demux ); i_time_begin = GetMoviePTS( p_sys );
} }
else else
{ {
i_length = GetMoviePTS( p_demux ) - i_time_begin; i_length = GetMoviePTS( p_sys ) - i_time_begin;
if( i_length < 0 || i_length >= 40 * 1000 ) if( i_length < 0 || i_length >= 40 * 1000 )
{ {
break; break;
...@@ -456,12 +549,12 @@ static int Demux( input_thread_t *p_input ) ...@@ -456,12 +549,12 @@ static int Demux( input_thread_t *p_input )
} }
} }
p_demux->i_time = GetMoviePTS( p_demux ); p_sys->i_time = GetMoviePTS( p_sys );
if( p_demux->i_time >= 0 ) if( p_sys->i_time >= 0 )
{ {
input_ClockManageRef( p_input, input_ClockManageRef( p_input,
p_input->stream.p_selected_program, p_input->stream.p_selected_program,
p_demux->i_time * 9 / 100 ); p_sys->i_time * 9 / 100 );
} }
return( 1 ); return( 1 );
...@@ -478,7 +571,7 @@ static void Close( vlc_object_t * p_this ) ...@@ -478,7 +571,7 @@ static void Close( vlc_object_t * p_this )
msg_Dbg( p_input, "Freeing all memory" ); msg_Dbg( p_input, "Freeing all memory" );
ASF_FreeObjectRoot( p_input, &p_sys->root ); ASF_FreeObjectRoot( p_sys->s, p_sys->p_root );
for( i_stream = 0; i_stream < 128; i_stream++ ) for( i_stream = 0; i_stream < 128; i_stream++ )
{ {
#define p_stream p_sys->stream[i_stream] #define p_stream p_sys->stream[i_stream]
...@@ -492,6 +585,7 @@ static void Close( vlc_object_t * p_this ) ...@@ -492,6 +585,7 @@ static void Close( vlc_object_t * p_this )
} }
#undef p_stream #undef p_stream
} }
stream_Release( p_sys->s );
free( p_sys ); free( p_sys );
} }
...@@ -499,7 +593,7 @@ static void Close( vlc_object_t * p_this ) ...@@ -499,7 +593,7 @@ static void Close( vlc_object_t * p_this )
/***************************************************************************** /*****************************************************************************
* *
*****************************************************************************/ *****************************************************************************/
static mtime_t GetMoviePTS( demux_sys_t *p_demux ) static mtime_t GetMoviePTS( demux_sys_t *p_sys )
{ {
mtime_t i_time; mtime_t i_time;
int i_stream; int i_stream;
...@@ -507,7 +601,7 @@ static mtime_t GetMoviePTS( demux_sys_t *p_demux ) ...@@ -507,7 +601,7 @@ static mtime_t GetMoviePTS( demux_sys_t *p_demux )
i_time = -1; i_time = -1;
for( i_stream = 0; i_stream < 128 ; i_stream++ ) for( i_stream = 0; i_stream < 128 ; i_stream++ )
{ {
#define p_stream p_demux->stream[i_stream] #define p_stream p_sys->stream[i_stream]
if( p_stream && p_stream->p_es && p_stream->p_es->p_decoder_fifo && p_stream->i_time > 0) if( p_stream && p_stream->p_es && p_stream->p_es->p_decoder_fifo && p_stream->i_time > 0)
{ {
if( i_time < 0 ) if( i_time < 0 )
...@@ -537,8 +631,8 @@ static mtime_t GetMoviePTS( demux_sys_t *p_demux ) ...@@ -537,8 +631,8 @@ static mtime_t GetMoviePTS( demux_sys_t *p_demux )
static int DemuxPacket( input_thread_t *p_input, vlc_bool_t b_play_audio ) static int DemuxPacket( input_thread_t *p_input, vlc_bool_t b_play_audio )
{ {
demux_sys_t *p_demux = p_input->p_demux_data; demux_sys_t *p_sys = p_input->p_demux_data;
int i_data_packet_min = p_demux->p_fp->i_min_data_packet_size; int i_data_packet_min = p_sys->p_fp->i_min_data_packet_size;
uint8_t *p_peek; uint8_t *p_peek;
int i_skip; int i_skip;
...@@ -558,7 +652,7 @@ static int DemuxPacket( input_thread_t *p_input, vlc_bool_t b_play_audio ) ...@@ -558,7 +652,7 @@ static int DemuxPacket( input_thread_t *p_input, vlc_bool_t b_play_audio )
int i_payload_length_type; int i_payload_length_type;
if( input_Peek( p_input, &p_peek, i_data_packet_min ) < i_data_packet_min ) if( stream_Peek( p_sys->s, &p_peek, i_data_packet_min ) < i_data_packet_min )
{ {
// EOF ? // EOF ?
msg_Warn( p_input, "cannot peek while getting new packet, EOF ?" ); msg_Warn( p_input, "cannot peek while getting new packet, EOF ?" );
...@@ -687,7 +781,7 @@ static int DemuxPacket( input_thread_t *p_input, vlc_bool_t b_play_audio ) ...@@ -687,7 +781,7 @@ static int DemuxPacket( input_thread_t *p_input, vlc_bool_t b_play_audio )
i_media_object_offset = i_tmp; i_media_object_offset = i_tmp;
} }
i_pts = __MAX( i_pts - p_demux->p_fp->i_preroll * 1000, 0 ); i_pts = __MAX( i_pts - p_sys->p_fp->i_preroll * 1000, 0 );
if( b_packet_multiple_payload ) if( b_packet_multiple_payload )
{ {
GETVALUE2b( i_payload_length_type, i_payload_data_length, 0 ); GETVALUE2b( i_payload_length_type, i_payload_data_length, 0 );
...@@ -715,7 +809,7 @@ static int DemuxPacket( input_thread_t *p_input, vlc_bool_t b_play_audio ) ...@@ -715,7 +809,7 @@ static int DemuxPacket( input_thread_t *p_input, vlc_bool_t b_play_audio )
i_payload_data_length ); i_payload_data_length );
#endif #endif
if( !( p_stream = p_demux->stream[i_stream_number] ) ) if( !( p_stream = p_sys->stream[i_stream_number] ) )
{ {
msg_Warn( p_input, msg_Warn( p_input,
"undeclared stream[Id 0x%x]", i_stream_number ); "undeclared stream[Id 0x%x]", i_stream_number );
...@@ -790,7 +884,7 @@ static int DemuxPacket( input_thread_t *p_input, vlc_bool_t b_play_audio ) ...@@ -790,7 +884,7 @@ static int DemuxPacket( input_thread_t *p_input, vlc_bool_t b_play_audio )
} }
i_read = i_sub_payload_data_length + i_skip; i_read = i_sub_payload_data_length + i_skip;
if( input_SplitBuffer( p_input, &p_data, i_read ) < i_read ) if((p_data = stream_DataPacket( p_sys->s,i_read,VLC_TRUE)) == NULL)
{ {
msg_Warn( p_input, "cannot read data" ); msg_Warn( p_input, "cannot read data" );
return( 0 ); return( 0 );
...@@ -814,7 +908,7 @@ static int DemuxPacket( input_thread_t *p_input, vlc_bool_t b_play_audio ) ...@@ -814,7 +908,7 @@ static int DemuxPacket( input_thread_t *p_input, vlc_bool_t b_play_audio )
i_skip = 0; i_skip = 0;
if( i_packet_size_left > 0 ) if( i_packet_size_left > 0 )
{ {
if( input_Peek( p_input, &p_peek, i_packet_size_left ) < i_packet_size_left ) if( stream_Peek( p_sys->s, &p_peek, i_packet_size_left ) < i_packet_size_left )
{ {
// EOF ? // EOF ?
msg_Warn( p_input, "cannot peek, EOF ?" ); msg_Warn( p_input, "cannot peek, EOF ?" );
...@@ -826,7 +920,7 @@ static int DemuxPacket( input_thread_t *p_input, vlc_bool_t b_play_audio ) ...@@ -826,7 +920,7 @@ static int DemuxPacket( input_thread_t *p_input, vlc_bool_t b_play_audio )
if( i_packet_size_left > 0 ) if( i_packet_size_left > 0 )
{ {
if( !ASF_SkipBytes( p_input, i_packet_size_left ) ) if( stream_Read( p_sys->s, NULL, i_packet_size_left ) < i_packet_size_left )
{ {
msg_Warn( p_input, "cannot skip data, EOF ?" ); msg_Warn( p_input, "cannot skip data, EOF ?" );
return( 0 ); return( 0 );
...@@ -837,12 +931,12 @@ static int DemuxPacket( input_thread_t *p_input, vlc_bool_t b_play_audio ) ...@@ -837,12 +931,12 @@ static int DemuxPacket( input_thread_t *p_input, vlc_bool_t b_play_audio )
loop_error_recovery: loop_error_recovery:
msg_Warn( p_input, "unsupported packet header" ); msg_Warn( p_input, "unsupported packet header" );
if( p_demux->p_fp->i_min_data_packet_size != p_demux->p_fp->i_max_data_packet_size ) if( p_sys->p_fp->i_min_data_packet_size != p_sys->p_fp->i_max_data_packet_size )
{ {
msg_Err( p_input, "unsupported packet header, fatal error" ); msg_Err( p_input, "unsupported packet header, fatal error" );
return( -1 ); return( -1 );
} }
ASF_SkipBytes( p_input, i_data_packet_min ); stream_Read( p_sys->s, NULL, i_data_packet_min );
return( 1 ); return( 1 );
} }
......
/*****************************************************************************
* asf.h : ASFv01 file input module for vlc
*****************************************************************************
* Copyright (C) 2001 VideoLAN
* $Id: asf.h,v 1.4 2003/08/17 23:42:37 fenrir Exp $
* Authors: Laurent Aimar <fenrir@via.ecp.fr>
*
* 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
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
*****************************************************************************/
typedef struct asf_stream_s
{
int i_cat;
es_descriptor_t *p_es;
asf_object_stream_properties_t *p_sp;
mtime_t i_time;
pes_packet_t *p_pes; // used to keep uncomplete frames
} asf_stream_t;
struct demux_sys_t
{
mtime_t i_time; // µs
asf_object_root_t root;
asf_object_file_properties_t *p_fp;
int i_streams;
asf_stream_t *stream[128];
off_t i_data_begin;
off_t i_data_end;
};
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* libasf.c : * libasf.c :
***************************************************************************** *****************************************************************************
* Copyright (C) 2001 VideoLAN * Copyright (C) 2001 VideoLAN
* $Id: libasf.c,v 1.14 2003/08/17 23:42:37 fenrir Exp $ * $Id: libasf.c,v 1.15 2003/08/18 19:18:47 fenrir Exp $
* 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
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
#include <vlc/vlc.h> #include <vlc/vlc.h>
#include <vlc/input.h> #include <vlc/input.h>
#include "ninput.h"
#include "codecs.h" /* BITMAPINFOHEADER, WAVEFORMATEX */ #include "codecs.h" /* BITMAPINFOHEADER, WAVEFORMATEX */
#include "libasf.h" #include "libasf.h"
...@@ -41,6 +42,16 @@ ...@@ -41,6 +42,16 @@
(guid).v4[0],(guid).v4[1],(guid).v4[2],(guid).v4[3], \ (guid).v4[0],(guid).v4[1],(guid).v4[2],(guid).v4[3], \
(guid).v4[4],(guid).v4[5],(guid).v4[6],(guid).v4[7] (guid).v4[4],(guid).v4[5],(guid).v4[6],(guid).v4[7]
/****************************************************************************
*
****************************************************************************/
static int ASF_ReadObject( stream_t *,
asf_object_t *p_obj, asf_object_t *p_father );
/****************************************************************************
* GUID functions
****************************************************************************/
void ASF_GetGUID( guid_t *p_guid, uint8_t *p_data ) void ASF_GetGUID( guid_t *p_guid, uint8_t *p_data )
{ {
p_guid->v1 = GetDWLE( p_data ); p_guid->v1 = GetDWLE( p_data );
...@@ -51,167 +62,57 @@ void ASF_GetGUID( guid_t *p_guid, uint8_t *p_data ) ...@@ -51,167 +62,57 @@ 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 )
{ {
if( (p_guid1->v1 != p_guid2->v1 )||(p_guid1->v2 != p_guid2->v2 )|| if( (p_guid1->v1 != p_guid2->v1 )||
(p_guid1->v2 != p_guid2->v2 )||
(p_guid1->v3 != p_guid2->v3 )|| (p_guid1->v3 != p_guid2->v3 )||
( memcmp( p_guid1->v4, p_guid2->v4,8 )) ) ( memcmp( p_guid1->v4, p_guid2->v4,8 )) )
{ {
return( 0 ); return( 0 );
} }
else return( 1 ); /* match */
{
return( 1 ); /* match */
}
}
/*****************************************************************************
* Some basic functions to manipulate stream more easily in vlc
*
* ASF_TellAbsolute get file position
*
* ASF_SeekAbsolute seek in the file
*
* ASF_ReadData read data from the file in a buffer
*
*****************************************************************************/
off_t ASF_TellAbsolute( input_thread_t *p_input )
{
off_t i_pos;
vlc_mutex_lock( &p_input->stream.stream_lock );
i_pos= p_input->stream.p_selected_area->i_tell;
// - ( p_input->p_last_data - p_input->p_current_data );
vlc_mutex_unlock( &p_input->stream.stream_lock );
return( i_pos );
}
int ASF_SeekAbsolute( input_thread_t *p_input,
off_t i_pos)
{
off_t i_filepos;
i_filepos = ASF_TellAbsolute( p_input );
if( i_pos == i_filepos )
{
return( 1 );
}
if( !p_input->stream.b_seekable && i_pos < i_filepos )
{
msg_Err( p_input, "cannot seek" );
return( 0 );
}
if( p_input->stream.b_seekable &&
( p_input->stream.i_method == INPUT_METHOD_FILE ||
i_pos < i_filepos ||
i_pos - i_filepos > 10000 ) )
{
input_AccessReinit( p_input );
p_input->pf_seek( p_input, i_pos );
return( 1 );
}
else if( i_pos > i_filepos )
{
uint64_t i_size = i_pos - i_filepos;
do
{
data_packet_t *p_data;
int i_read;
i_read =
input_SplitBuffer(p_input, &p_data, __MIN( i_size, 1024 ) );
if( i_read <= 0 )
{
return( 0 );
}
input_DeletePacket( p_input->p_method_data, p_data );
i_size -= i_read;
} while( i_size > 0 );
}
return( 1 );
}
/* return 1 if success, 0 if fail */
int ASF_ReadData( input_thread_t *p_input, uint8_t *p_buff, int i_size )
{
data_packet_t *p_data;
int i_read;
if( !i_size )
{
return( 1 );
}
do
{
i_read = input_SplitBuffer(p_input, &p_data, __MIN( i_size, 1024 ) );
if( i_read <= 0 )
{
return( 0 );
}
memcpy( p_buff, p_data->p_payload_start, i_read );
input_DeletePacket( p_input->p_method_data, p_data );
p_buff += i_read;
i_size -= i_read;
} while( i_size );
return( 1 );
}
int ASF_SkipBytes( input_thread_t *p_input, int i_count )
{
return( ASF_SeekAbsolute( p_input,
ASF_TellAbsolute( p_input ) + i_count ) );
} }
/****************************************************************************/ /****************************************************************************
int ASF_ReadObjectCommon( input_thread_t *p_input, *
asf_object_t *p_obj ) ****************************************************************************/
static int ASF_ReadObjectCommon( stream_t *s, asf_object_t *p_obj )
{ {
asf_object_common_t *p_common = (asf_object_common_t*)p_obj; asf_object_common_t *p_common = (asf_object_common_t*)p_obj;
uint8_t *p_peek; uint8_t *p_peek;
if( input_Peek( p_input, &p_peek, 24 ) < 24 ) if( stream_Peek( s, &p_peek, 24 ) < 24 )
{ {
return( 0 ); return( VLC_EGENERIC );
} }
ASF_GetGUID( &p_common->i_object_id, p_peek ); ASF_GetGUID( &p_common->i_object_id, p_peek );
p_common->i_object_size = GetQWLE( p_peek + 16 ); p_common->i_object_size = GetQWLE( p_peek + 16 );
p_common->i_object_pos = ASF_TellAbsolute( p_input ); stream_Control( s, STREAM_GET_POSITION, &p_common->i_object_pos );
p_common->p_next = NULL; p_common->p_next = NULL;
#ifdef ASF_DEBUG #ifdef ASF_DEBUG
msg_Dbg(p_input, msg_Dbg( (vlc_object_t*)s,
"Found Object guid: " GUID_FMT " size:"I64Fd, "Found Object guid: " GUID_FMT " size:"I64Fd,
GUID_PRINT( p_common->i_object_id ), GUID_PRINT( p_common->i_object_id ),
p_common->i_object_size ); p_common->i_object_size );
#endif #endif
return( 1 ); return( VLC_SUCCESS );
} }
int ASF_NextObject( input_thread_t *p_input, static int ASF_NextObject( stream_t *s, asf_object_t *p_obj )
asf_object_t *p_obj )
{ {
asf_object_t obj; asf_object_t obj;
if( !p_obj ) if( p_obj == NULL )
{ {
if( !ASF_ReadObjectCommon( p_input, &obj ) ) if( ASF_ReadObjectCommon( s, &obj ) )
{ {
return( 0 ); return( VLC_EGENERIC );
} }
p_obj = &obj; p_obj = &obj;
} }
if( !p_obj->common.i_object_size ) if( p_obj->common.i_object_size <= 0 )
{ {
return( 0 ); /* failed */ 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 )
{ {
...@@ -219,109 +120,97 @@ int ASF_NextObject( input_thread_t *p_input, ...@@ -219,109 +120,97 @@ int ASF_NextObject( input_thread_t *p_input,
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 */
{ {
return( 0 ); return( VLC_EGENERIC );
} }
} }
return( ASF_SeekAbsolute( p_input,
p_obj->common.i_object_pos + p_obj->common.i_object_size ) );
}
int ASF_GotoObject( input_thread_t *p_input, return( stream_Control( s, STREAM_SET_POSITION,
asf_object_t *p_obj ) p_obj->common.i_object_pos + p_obj->common.i_object_size ) );
{
if( !p_obj )
{
return( 0 );
}
return( ASF_SeekAbsolute( p_input, p_obj->common.i_object_pos ) );
} }
static void ASF_FreeObject_Null( asf_object_t *pp_obj )
void ASF_FreeObject_Null( input_thread_t *p_input,
asf_object_t *pp_obj )
{ {
return;
} }
int ASF_ReadObject_Header( input_thread_t *p_input, static int ASF_ReadObject_Header( stream_t *s, asf_object_t *p_obj )
asf_object_t *p_obj )
{ {
asf_object_header_t *p_hdr = (asf_object_header_t*)p_obj; asf_object_header_t *p_hdr = (asf_object_header_t*)p_obj;
asf_object_t *p_subobj; asf_object_t *p_subobj;
int i_peek; int i_peek;
uint8_t *p_peek; uint8_t *p_peek;
if( ( i_peek = input_Peek( p_input, &p_peek, 30 ) ) < 30 ) if( ( i_peek = stream_Peek( s, &p_peek, 30 ) ) < 30 )
{ {
return( 0 ); return( VLC_EGENERIC );
} }
p_hdr->i_sub_object_count = GetDWLE( p_peek + 24 ); p_hdr->i_sub_object_count = GetDWLE( p_peek + 24 );
p_hdr->i_reserved1 = p_peek[28]; p_hdr->i_reserved1 = p_peek[28];
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(p_input, msg_Dbg( (vlc_object_t*)s,
"Read \"Header Object\" subobj:%d, reserved1:%d, reserved2:%d", "Read \"Header Object\" subobj:%d, reserved1:%d, reserved2:%d",
p_hdr->i_sub_object_count, p_hdr->i_sub_object_count,
p_hdr->i_reserved1, p_hdr->i_reserved1,
p_hdr->i_reserved2 ); p_hdr->i_reserved2 );
#endif #endif
ASF_SkipBytes( p_input, 30 ); /* Cannot failed as peek succeed */
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( p_input, p_subobj, (asf_object_t*)p_hdr ) ) ) if( ASF_ReadObject( s, p_subobj, (asf_object_t*)p_hdr ) )
{ {
break; break;
} }
if( !ASF_NextObject( p_input, p_subobj ) ) /* Go to the next object */ if( ASF_NextObject( s, p_subobj ) ) /* Go to the next object */
{ {
break; break;
} }
} }
return( 1 ); return VLC_SUCCESS;
} }
int ASF_ReadObject_Data( input_thread_t *p_input, static int ASF_ReadObject_Data( stream_t *s, asf_object_t *p_obj )
asf_object_t *p_obj )
{ {
asf_object_data_t *p_data = (asf_object_data_t*)p_obj; asf_object_data_t *p_data = (asf_object_data_t*)p_obj;
int i_peek; int i_peek;
uint8_t *p_peek; uint8_t *p_peek;
if( ( i_peek = input_Peek( p_input, &p_peek, 50 ) ) < 50 ) if( ( i_peek = stream_Peek( s, &p_peek, 50 ) ) < 50 )
{ {
return( 0 ); return VLC_EGENERIC;
} }
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( p_input, 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:"
I64Fd" reserved:%d", I64Fd" reserved:%d",
GUID_PRINT( p_data->i_file_id ), GUID_PRINT( p_data->i_file_id ),
p_data->i_total_data_packets, p_data->i_total_data_packets,
p_data->i_reserved ); p_data->i_reserved );
#endif #endif
return( 1 ); return VLC_SUCCESS;
} }
int ASF_ReadObject_Index( input_thread_t *p_input, static int ASF_ReadObject_Index( stream_t *s, asf_object_t *p_obj )
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;
int i_peek; int i_peek;
uint8_t *p_peek; uint8_t *p_peek;
if( ( i_peek = input_Peek( p_input, &p_peek, 56 ) ) < 56 ) if( ( i_peek = stream_Peek( s, &p_peek, 56 ) ) < 56 )
{ {
return( 0 ); return VLC_EGENERIC;
} }
ASF_GetGUID( &p_index->i_file_id, p_peek + 24 ); ASF_GetGUID( &p_index->i_file_id, p_peek + 24 );
p_index->i_index_entry_time_interval = GetQWLE( p_peek + 40 ); p_index->i_index_entry_time_interval = GetQWLE( p_peek + 40 );
...@@ -330,7 +219,7 @@ int ASF_ReadObject_Index( input_thread_t *p_input, ...@@ -330,7 +219,7 @@ int ASF_ReadObject_Index( input_thread_t *p_input,
p_index->index_entry = NULL; /* FIXME */ p_index->index_entry = NULL; /* FIXME */
#ifdef ASF_DEBUG #ifdef ASF_DEBUG
msg_Dbg( p_input, msg_Dbg( (vlc_object_t*)s,
"Read \"Index Object\" file_id:" GUID_FMT "Read \"Index Object\" file_id:" GUID_FMT
" index_entry_time_interval:"I64Fd" max_packet_count:%d " " index_entry_time_interval:"I64Fd" max_packet_count:%d "
"index_entry_count:%ld", "index_entry_count:%ld",
...@@ -339,26 +228,24 @@ int ASF_ReadObject_Index( input_thread_t *p_input, ...@@ -339,26 +228,24 @@ int ASF_ReadObject_Index( input_thread_t *p_input,
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( 1 ); return VLC_SUCCESS;
} }
void ASF_FreeObject_Index( input_thread_t *p_input, static void ASF_FreeObject_Index( asf_object_t *p_obj )
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;
FREE( p_index->index_entry ); FREE( p_index->index_entry );
} }
int ASF_ReadObject_file_properties( input_thread_t *p_input, static int ASF_ReadObject_file_properties( stream_t *s, asf_object_t *p_obj )
asf_object_t *p_obj )
{ {
asf_object_file_properties_t *p_fp = (asf_object_file_properties_t*)p_obj; asf_object_file_properties_t *p_fp = (asf_object_file_properties_t*)p_obj;
int i_peek; int i_peek;
uint8_t *p_peek; uint8_t *p_peek;
if( ( i_peek = input_Peek( p_input, &p_peek, 92) ) < 92 ) if( ( i_peek = stream_Peek( s, &p_peek, 92) ) < 92 )
{ {
return( 0 ); return VLC_EGENERIC;
} }
ASF_GetGUID( &p_fp->i_file_id, p_peek + 24 ); ASF_GetGUID( &p_fp->i_file_id, p_peek + 24 );
p_fp->i_file_size = GetQWLE( p_peek + 40 ); p_fp->i_file_size = GetQWLE( p_peek + 40 );
...@@ -373,7 +260,7 @@ int ASF_ReadObject_file_properties( input_thread_t *p_input, ...@@ -373,7 +260,7 @@ int ASF_ReadObject_file_properties( input_thread_t *p_input,
p_fp->i_max_bitrate = GetDWLE( p_peek + 100 ); p_fp->i_max_bitrate = GetDWLE( p_peek + 100 );
#ifdef ASF_DEBUG #ifdef ASF_DEBUG
msg_Dbg( p_input, msg_Dbg( (vlc_object_t*)s,
"Read \"File Properties Object\" file_id:" GUID_FMT "Read \"File Properties Object\" file_id:" GUID_FMT
" file_size:"I64Fd" creation_date:"I64Fd" data_packets_count:" " file_size:"I64Fd" creation_date:"I64Fd" data_packets_count:"
I64Fd" play_duration:"I64Fd" send_duration:"I64Fd" preroll:" I64Fd" play_duration:"I64Fd" send_duration:"I64Fd" preroll:"
...@@ -391,19 +278,18 @@ int ASF_ReadObject_file_properties( input_thread_t *p_input, ...@@ -391,19 +278,18 @@ int ASF_ReadObject_file_properties( input_thread_t *p_input,
p_fp->i_max_data_packet_size, p_fp->i_max_data_packet_size,
p_fp->i_max_bitrate ); p_fp->i_max_bitrate );
#endif #endif
return( 1 ); return VLC_SUCCESS;
} }
int ASF_ReadObject_header_extention( input_thread_t *p_input, static int ASF_ReadObject_header_extention( stream_t *s, asf_object_t *p_obj )
asf_object_t *p_obj )
{ {
asf_object_header_extention_t *p_he = (asf_object_header_extention_t*)p_obj; asf_object_header_extention_t *p_he = (asf_object_header_extention_t*)p_obj;
int i_peek; int i_peek;
uint8_t *p_peek; uint8_t *p_peek;
if( ( i_peek = input_Peek( p_input, &p_peek, p_he->i_object_size ) ) < 46) if( ( i_peek = stream_Peek( s, &p_peek, p_he->i_object_size ) ) < 46)
{ {
return( 0 ); return VLC_EGENERIC;
} }
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 );
...@@ -420,33 +306,31 @@ int ASF_ReadObject_header_extention( input_thread_t *p_input, ...@@ -420,33 +306,31 @@ int ASF_ReadObject_header_extention( input_thread_t *p_input,
p_he->p_header_extention_data = NULL; p_he->p_header_extention_data = NULL;
} }
#ifdef ASF_DEBUG #ifdef ASF_DEBUG
msg_Dbg( p_input, msg_Dbg( (vlc_object_t*)s,
"Read \"Header Extention Object\" reserved1:" GUID_FMT " reserved2:%d header_extention_size:%d", "Read \"Header Extention Object\" reserved1:" GUID_FMT " reserved2:%d header_extention_size:%d",
GUID_PRINT( p_he->i_reserved1 ), GUID_PRINT( p_he->i_reserved1 ),
p_he->i_reserved2, p_he->i_reserved2,
p_he->i_header_extention_size ); p_he->i_header_extention_size );
#endif #endif
return( 1 ); return VLC_SUCCESS;
} }
void ASF_FreeObject_header_extention( input_thread_t *p_input, static void ASF_FreeObject_header_extention( asf_object_t *p_obj )
asf_object_t *p_obj )
{ {
asf_object_header_extention_t *p_he = (asf_object_header_extention_t*)p_obj; asf_object_header_extention_t *p_he = (asf_object_header_extention_t*)p_obj;
FREE( p_he->p_header_extention_data ); FREE( p_he->p_header_extention_data );
} }
int ASF_ReadObject_stream_properties( input_thread_t *p_input, static int ASF_ReadObject_stream_properties( stream_t *s, asf_object_t *p_obj )
asf_object_t *p_obj )
{ {
asf_object_stream_properties_t *p_sp = asf_object_stream_properties_t *p_sp =
(asf_object_stream_properties_t*)p_obj; (asf_object_stream_properties_t*)p_obj;
int i_peek; int i_peek;
uint8_t *p_peek; uint8_t *p_peek;
if( ( i_peek = input_Peek( p_input, &p_peek, p_sp->i_object_size ) ) < 74 ) if( ( i_peek = stream_Peek( s, &p_peek, p_sp->i_object_size ) ) < 74 )
{ {
return( 0 ); return VLC_EGENERIC;
} }
ASF_GetGUID( &p_sp->i_stream_type, p_peek + 24 ); ASF_GetGUID( &p_sp->i_stream_type, p_peek + 24 );
ASF_GetGUID( &p_sp->i_error_correction_type, p_peek + 40 ); ASF_GetGUID( &p_sp->i_error_correction_type, p_peek + 40 );
...@@ -480,7 +364,7 @@ int ASF_ReadObject_stream_properties( input_thread_t *p_input, ...@@ -480,7 +364,7 @@ int ASF_ReadObject_stream_properties( input_thread_t *p_input,
} }
#ifdef ASF_DEBUG #ifdef ASF_DEBUG
msg_Dbg( p_input, msg_Dbg( (vlc_object_t*)s,
"Read \"Stream Properties Object\" stream_type:" GUID_FMT "Read \"Stream Properties Object\" stream_type:" GUID_FMT
" error_correction_type:" GUID_FMT " time_offset:"I64Fd " error_correction_type:" GUID_FMT " time_offset:"I64Fd
" type_specific_data_length:%d error_correction_data_length:%d" " type_specific_data_length:%d error_correction_data_length:%d"
...@@ -494,11 +378,10 @@ int ASF_ReadObject_stream_properties( input_thread_t *p_input, ...@@ -494,11 +378,10 @@ int ASF_ReadObject_stream_properties( input_thread_t *p_input,
p_sp->i_stream_number ); p_sp->i_stream_number );
#endif #endif
return( 1 ); return VLC_SUCCESS;
} }
void ASF_FreeObject_stream_properties( input_thread_t *p_input, static void ASF_FreeObject_stream_properties( asf_object_t *p_obj )
asf_object_t *p_obj )
{ {
asf_object_stream_properties_t *p_sp = asf_object_stream_properties_t *p_sp =
(asf_object_stream_properties_t*)p_obj; (asf_object_stream_properties_t*)p_obj;
...@@ -508,8 +391,7 @@ void ASF_FreeObject_stream_properties( input_thread_t *p_input, ...@@ -508,8 +391,7 @@ void ASF_FreeObject_stream_properties( input_thread_t *p_input,
} }
int ASF_ReadObject_codec_list( input_thread_t *p_input, static int ASF_ReadObject_codec_list( stream_t *s, asf_object_t *p_obj )
asf_object_t *p_obj )
{ {
asf_object_codec_list_t *p_cl = (asf_object_codec_list_t*)p_obj; asf_object_codec_list_t *p_cl = (asf_object_codec_list_t*)p_obj;
int i_peek; int i_peek;
...@@ -517,9 +399,9 @@ int ASF_ReadObject_codec_list( input_thread_t *p_input, ...@@ -517,9 +399,9 @@ int ASF_ReadObject_codec_list( input_thread_t *p_input,
unsigned int i_codec; unsigned int i_codec;
if( ( i_peek = input_Peek( p_input, &p_peek, p_cl->i_object_size ) ) < 44 ) if( ( i_peek = stream_Peek( s, &p_peek, p_cl->i_object_size ) ) < 44 )
{ {
return( 0 ); return VLC_EGENERIC;
} }
ASF_GetGUID( &p_cl->i_reserved, p_peek + 24 ); ASF_GetGUID( &p_cl->i_reserved, p_peek + 24 );
...@@ -527,8 +409,10 @@ int ASF_ReadObject_codec_list( input_thread_t *p_input, ...@@ -527,8 +409,10 @@ int ASF_ReadObject_codec_list( input_thread_t *p_input,
if( p_cl->i_codec_entries_count > 0 ) if( p_cl->i_codec_entries_count > 0 )
{ {
p_cl->codec = calloc( p_cl->i_codec_entries_count, sizeof( asf_codec_entry_t ) ); p_cl->codec = calloc( p_cl->i_codec_entries_count,
memset( p_cl->codec, 0, p_cl->i_codec_entries_count * sizeof( asf_codec_entry_t ) ); sizeof( asf_codec_entry_t ) );
memset( p_cl->codec, 0,
p_cl->i_codec_entries_count * sizeof( asf_codec_entry_t ) );
p_data = p_peek + 44; p_data = p_peek + 44;
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++ )
...@@ -571,7 +455,6 @@ int ASF_ReadObject_codec_list( input_thread_t *p_input, ...@@ -571,7 +455,6 @@ int ASF_ReadObject_codec_list( input_thread_t *p_input,
} }
#undef codec #undef codec
} }
} }
else else
{ {
...@@ -579,35 +462,27 @@ int ASF_ReadObject_codec_list( input_thread_t *p_input, ...@@ -579,35 +462,27 @@ int ASF_ReadObject_codec_list( input_thread_t *p_input,
} }
#ifdef ASF_DEBUG #ifdef ASF_DEBUG
msg_Dbg( p_input, msg_Dbg( (vlc_object_t*)s,
"Read \"Codec List Object\" reserved_guid:" GUID_FMT " codec_entries_count:%d", "Read \"Codec List Object\" reserved_guid:" GUID_FMT " 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++ )
{ {
char psz_cat[sizeof("Stream ")+10];
input_info_category_t *p_cat;
sprintf( psz_cat, "Stream %d", i_codec );
p_cat = input_InfoCategory( p_input, psz_cat);
#define codec p_cl->codec[i_codec] #define codec p_cl->codec[i_codec]
input_AddInfo( p_cat, _("Codec name"), codec.psz_name ); msg_Dbg( (vlc_object_t*)s,
input_AddInfo( p_cat, _("Codec description"), codec.psz_description );
msg_Dbg( p_input,
"Read \"Codec List Object\" codec[%d] %s name:\"%s\" description:\"%s\" information_length:%d", "Read \"Codec List Object\" codec[%d] %s name:\"%s\" description:\"%s\" information_length:%d",
i_codec, i_codec,
( codec.i_type == ASF_CODEC_TYPE_VIDEO ) ? "video" : ( ( codec.i_type == ASF_CODEC_TYPE_AUDIO ) ? "audio" : "unknown" ), ( codec.i_type == ASF_CODEC_TYPE_VIDEO ) ? "video" : ( ( codec.i_type == ASF_CODEC_TYPE_AUDIO ) ? "audio" : "unknown" ),
codec.psz_name, codec.psz_name,
codec.psz_description, codec.psz_description,
codec.i_information_length ); codec.i_information_length );
#undef codec
} }
#endif #endif
return( 1 ); return VLC_SUCCESS;
} }
void ASF_FreeObject_codec_list( input_thread_t *p_input,
asf_object_t *p_obj ) static void ASF_FreeObject_codec_list( asf_object_t *p_obj )
{ {
asf_object_codec_list_t *p_cl = (asf_object_codec_list_t*)p_obj; asf_object_codec_list_t *p_cl = (asf_object_codec_list_t*)p_obj;
unsigned int i_codec; unsigned int i_codec;
...@@ -624,10 +499,9 @@ void ASF_FreeObject_codec_list( input_thread_t *p_input, ...@@ -624,10 +499,9 @@ void ASF_FreeObject_codec_list( input_thread_t *p_input,
FREE( p_cl->codec ); FREE( p_cl->codec );
} }
/* Microsoft should qo to hell. This time the length give number of bytes /* Microsoft should go to hell. This time the length give number of bytes
* and for the some others object, length give char16 count ... */ * and for the some others object, length give char16 count ... */
int ASF_ReadObject_content_description( input_thread_t *p_input, static int ASF_ReadObject_content_description(stream_t *s, asf_object_t *p_obj)
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;
...@@ -650,9 +524,9 @@ int ASF_ReadObject_content_description( input_thread_t *p_input, ...@@ -650,9 +524,9 @@ int ASF_ReadObject_content_description( input_thread_t *p_input,
psz_str[i_size/2] = '\0'; \ psz_str[i_size/2] = '\0'; \
p_data += i_size; p_data += i_size;
if( ( i_peek = input_Peek( p_input, &p_peek, p_cd->i_object_size ) ) < 34 ) if( ( i_peek = stream_Peek( s, &p_peek, p_cd->i_object_size ) ) < 34 )
{ {
return( 0 ); return VLC_EGENERIC;
} }
p_data = p_peek + 24; p_data = p_peek + 24;
...@@ -671,15 +545,7 @@ int ASF_ReadObject_content_description( input_thread_t *p_input, ...@@ -671,15 +545,7 @@ int ASF_ReadObject_content_description( input_thread_t *p_input,
#undef GETSTRINGW #undef GETSTRINGW
#ifdef ASF_DEBUG #ifdef ASF_DEBUG
{ msg_Dbg( (vlc_object_t*)s,
input_info_category_t *p_cat = input_InfoCategory( p_input, _("Asf") );
input_AddInfo( p_cat, _("Title"), p_cd->psz_title );
input_AddInfo( p_cat, _("Author"), p_cd->psz_author );
input_AddInfo( p_cat, _("Copyright"), p_cd->psz_copyright );
input_AddInfo( p_cat, _("Description"), p_cd->psz_description );
input_AddInfo( p_cat, _("Rating"), p_cd->psz_rating );
}
msg_Dbg( p_input,
"Read \"Content Description Object\" title:\"%s\" author:\"%s\" copyright:\"%s\" description:\"%s\" rating:\"%s\"", "Read \"Content Description Object\" title:\"%s\" author:\"%s\" copyright:\"%s\" description:\"%s\" rating:\"%s\"",
p_cd->psz_title, p_cd->psz_title,
p_cd->psz_author, p_cd->psz_author,
...@@ -687,13 +553,13 @@ int ASF_ReadObject_content_description( input_thread_t *p_input, ...@@ -687,13 +553,13 @@ int ASF_ReadObject_content_description( input_thread_t *p_input,
p_cd->psz_description, p_cd->psz_description,
p_cd->psz_rating ); p_cd->psz_rating );
#endif #endif
return( 1 ); return VLC_SUCCESS;
} }
void ASF_FreeObject_content_description( input_thread_t *p_input, static void ASF_FreeObject_content_description( asf_object_t *p_obj)
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_cd =
(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 );
...@@ -706,10 +572,8 @@ static struct ...@@ -706,10 +572,8 @@ static struct
{ {
const guid_t *p_id; const guid_t *p_id;
int i_type; int i_type;
int (*ASF_ReadObject_function)( input_thread_t *p_input, int (*ASF_ReadObject_function)( stream_t *, asf_object_t *p_obj );
asf_object_t *p_obj ); void (*ASF_FreeObject_function)( asf_object_t *p_obj );
void (*ASF_FreeObject_function)( input_thread_t *p_input,
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_ReadObject_Header, ASF_FreeObject_Null },
...@@ -725,9 +589,8 @@ static struct ...@@ -725,9 +589,8 @@ static struct
{ &asf_object_null_guid, 0, NULL, NULL } { &asf_object_null_guid, 0, NULL, NULL }
}; };
int ASF_ReadObject( input_thread_t *p_input, 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;
...@@ -736,10 +599,10 @@ int ASF_ReadObject( input_thread_t *p_input, ...@@ -736,10 +599,10 @@ int ASF_ReadObject( input_thread_t *p_input,
{ {
return( 0 ); return( 0 );
} }
if( !ASF_ReadObjectCommon( p_input, p_obj ) ) if( ASF_ReadObjectCommon( s, p_obj ) )
{ {
msg_Warn( p_input, "Cannot read one asf object" ); msg_Warn( (vlc_object_t*)s, "Cannot read one asf object" );
return( 0 ); return VLC_EGENERIC;
} }
p_obj->common.p_father = p_father; p_obj->common.p_father = p_father;
p_obj->common.p_first = NULL; p_obj->common.p_first = NULL;
...@@ -749,8 +612,8 @@ int ASF_ReadObject( input_thread_t *p_input, ...@@ -749,8 +612,8 @@ int ASF_ReadObject( input_thread_t *p_input,
if( p_obj->common.i_object_size < 24 ) if( p_obj->common.i_object_size < 24 )
{ {
msg_Warn( p_input, "Found a corrupted asf object (size<24)" ); msg_Warn( (vlc_object_t*)s, "Found a corrupted asf object (size<24)" );
return( 0 ); return VLC_EGENERIC;
} }
/* find this object */ /* find this object */
for( i_index = 0; ; i_index++ ) for( i_index = 0; ; i_index++ )
...@@ -768,15 +631,14 @@ int ASF_ReadObject( input_thread_t *p_input, ...@@ -768,15 +631,14 @@ int ASF_ReadObject( input_thread_t *p_input,
/* Now load this object */ /* Now load this object */
if( ASF_Object_Function[i_index].ASF_ReadObject_function == NULL ) if( ASF_Object_Function[i_index].ASF_ReadObject_function == NULL )
{ {
msg_Warn( p_input, "Unknown asf object (not loaded)" ); msg_Warn( (vlc_object_t*)s, "Unknown asf object (not loaded)" );
i_result = 1; i_result = VLC_SUCCESS;
} }
else else
{ {
/* XXX ASF_ReadObject_function realloc *pp_obj XXX */ /* XXX ASF_ReadObject_function realloc *pp_obj XXX */
i_result = i_result =
(ASF_Object_Function[i_index].ASF_ReadObject_function)( p_input, (ASF_Object_Function[i_index].ASF_ReadObject_function)( s, p_obj );
p_obj );
} }
/* link this object with father */ /* link this object with father */
...@@ -796,8 +658,7 @@ int ASF_ReadObject( input_thread_t *p_input, ...@@ -796,8 +658,7 @@ int ASF_ReadObject( input_thread_t *p_input,
return( i_result ); return( i_result );
} }
void ASF_FreeObject( input_thread_t *p_input, static void ASF_FreeObject( stream_t *s, asf_object_t *p_obj )
asf_object_t *p_obj )
{ {
int i_index; int i_index;
asf_object_t *p_child; asf_object_t *p_child;
...@@ -813,7 +674,7 @@ void ASF_FreeObject( input_thread_t *p_input, ...@@ -813,7 +674,7 @@ void ASF_FreeObject( input_thread_t *p_input,
{ {
asf_object_t *p_next; asf_object_t *p_next;
p_next = p_child->common.p_next; p_next = p_child->common.p_next;
ASF_FreeObject( p_input, p_child ); ASF_FreeObject( s, p_child );
p_child = p_next; p_child = p_next;
} }
...@@ -832,19 +693,18 @@ void ASF_FreeObject( input_thread_t *p_input, ...@@ -832,19 +693,18 @@ void ASF_FreeObject( input_thread_t *p_input,
/* Now free this object */ /* Now free this object */
if( ASF_Object_Function[i_index].ASF_FreeObject_function == NULL ) if( ASF_Object_Function[i_index].ASF_FreeObject_function == NULL )
{ {
msg_Warn( p_input, msg_Warn( (vlc_object_t*)s,
"Unknown asf object " GUID_FMT, "Unknown asf object " GUID_FMT,
GUID_PRINT( p_obj->common.i_object_id ) ); GUID_PRINT( p_obj->common.i_object_id ) );
} }
else else
{ {
#ifdef ASF_DEBUG #ifdef ASF_DEBUG
msg_Dbg( p_input, msg_Dbg( (vlc_object_t*)s,
"Free asf object " GUID_FMT, "Free asf object " GUID_FMT,
GUID_PRINT( p_obj->common.i_object_id ) ); GUID_PRINT( p_obj->common.i_object_id ) );
#endif #endif
(ASF_Object_Function[i_index].ASF_FreeObject_function)( p_input, (ASF_Object_Function[i_index].ASF_FreeObject_function)( p_obj );
p_obj );
} }
free( p_obj ); free( p_obj );
return; return;
...@@ -853,30 +713,30 @@ void ASF_FreeObject( input_thread_t *p_input, ...@@ -853,30 +713,30 @@ void ASF_FreeObject( input_thread_t *p_input,
/***************************************************************************** /*****************************************************************************
* ASF_ReadObjetRoot : parse the entire stream/file * ASF_ReadObjetRoot : parse the entire stream/file
*****************************************************************************/ *****************************************************************************/
int ASF_ReadObjectRoot( input_thread_t *p_input, asf_object_root_t *ASF_ReadObjectRoot( stream_t *s, int b_seekable )
asf_object_root_t *p_root,
int b_seekable )
{ {
asf_object_root_t *p_root = malloc( sizeof( asf_object_root_t ) );
asf_object_t *p_obj; asf_object_t *p_obj;
p_root->i_type = ASF_OBJECT_TYPE_ROOT; p_root->i_type = ASF_OBJECT_TYPE_ROOT;
memcpy( &p_root->i_object_id, &asf_object_null_guid, sizeof( guid_t ) ); memcpy( &p_root->i_object_id, &asf_object_null_guid, sizeof( guid_t ) );
p_root->i_object_pos = 0; p_root->i_object_pos = 0;
p_root->i_object_size = p_input->stream.p_selected_area->i_size; stream_Control( s, STREAM_GET_SIZE, &p_root->i_object_size );
p_root->p_first = NULL; p_root->p_first = NULL;
p_root->p_last = NULL; p_root->p_last = NULL;
p_root->p_next = NULL; p_root->p_next = NULL;
p_root->p_hdr = NULL; p_root->p_hdr = NULL;
p_root->p_data = NULL; p_root->p_data = NULL;
p_root->p_fp = NULL;
p_root->p_index = NULL; p_root->p_index = NULL;
for( ; ; ) for( ; ; )
{ {
p_obj = malloc( sizeof( asf_object_t ) ); p_obj = malloc( sizeof( asf_object_t ) );
if( !( ASF_ReadObject( p_input, p_obj, (asf_object_t*)p_root ) ) ) if( ASF_ReadObject( s, p_obj, (asf_object_t*)p_root ) )
{ {
return( 1 ); break;
} }
switch( p_obj->common.i_type ) switch( p_obj->common.i_type )
{ {
...@@ -890,24 +750,39 @@ int ASF_ReadObjectRoot( input_thread_t *p_input, ...@@ -890,24 +750,39 @@ int ASF_ReadObjectRoot( input_thread_t *p_input,
p_root->p_index = (asf_object_index_t*)p_obj; p_root->p_index = (asf_object_index_t*)p_obj;
break; break;
default: default:
msg_Warn( p_input, "Unknow Object found" ); msg_Warn( (vlc_object_t*)s, "Unknow Object found" );
break; break;
} }
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 enouth to play */
return( 1 ); break;
}
if( ASF_NextObject( s, p_obj ) ) /* Go to the next object */
{
break;
} }
}
if( p_root->p_hdr != NULL && p_root->p_data != NULL )
{
p_root->p_fp = ASF_FindObject( p_root->p_hdr,
&asf_object_file_properties_guid, 0 );
if( !ASF_NextObject( p_input, p_obj ) ) /* Go to the next object */ if( p_root->p_fp )
{ {
return( 1 ); return p_root;
} }
msg_Warn( (vlc_object_t*)s, "cannot fine file properties object" );
} }
/* Invalid file */
ASF_FreeObjectRoot( s, p_root );
return NULL;
} }
void ASF_FreeObjectRoot( input_thread_t *p_input, void ASF_FreeObjectRoot( stream_t *s, asf_object_root_t *p_root )
asf_object_root_t *p_root )
{ {
asf_object_t *p_obj; asf_object_t *p_obj;
...@@ -916,17 +791,10 @@ void ASF_FreeObjectRoot( input_thread_t *p_input, ...@@ -916,17 +791,10 @@ void ASF_FreeObjectRoot( input_thread_t *p_input,
{ {
asf_object_t *p_next; asf_object_t *p_next;
p_next = p_obj->common.p_next; p_next = p_obj->common.p_next;
ASF_FreeObject( p_input, p_obj ); ASF_FreeObject( s, p_obj );
p_obj = p_next; p_obj = p_next;
} }
p_root->p_first = NULL; free( p_root );
p_root->p_last = NULL;
p_root->p_next = NULL;
p_root->p_hdr = NULL;
p_root->p_data = NULL;
p_root->p_index = NULL;
} }
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 )
...@@ -975,4 +843,3 @@ void *__ASF_FindObject( asf_object_t *p_obj, const guid_t *p_guid, int i_number ...@@ -975,4 +843,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 VideoLAN * Copyright (C) 2001 VideoLAN
* $Id: libasf.h,v 1.6 2003/08/17 23:42:37 fenrir Exp $ * $Id: libasf.h,v 1.7 2003/08/18 19:18:47 fenrir Exp $
* 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
...@@ -211,16 +211,6 @@ typedef struct asf_object_index_s ...@@ -211,16 +211,6 @@ typedef struct asf_object_index_s
} asf_object_index_t; } asf_object_index_t;
typedef struct asf_object_root_s
{
ASF_OBJECT_COMMON
asf_object_header_t *p_hdr;
asf_object_data_t *p_data;
asf_object_index_t *p_index;
} asf_object_root_t;
/**************************************************************************** /****************************************************************************
* Sub level asf object * Sub level asf object
****************************************************************************/ ****************************************************************************/
...@@ -338,6 +328,26 @@ typedef struct asf_object_marker_s ...@@ -338,6 +328,26 @@ typedef struct asf_object_marker_s
} asf_object_marker_t; } asf_object_marker_t;
/****************************************************************************
* Special Root Object
****************************************************************************/
typedef struct asf_object_root_s
{
ASF_OBJECT_COMMON
asf_object_header_t *p_hdr;
asf_object_data_t *p_data;
/* could be NULL if !b_seekable or not-present */
asf_object_index_t *p_index;
/* from asf_object_header_t */
asf_object_file_properties_t *p_fp;
} asf_object_root_t;
/****************************************************************************
* asf_object_t: union of all objects.
****************************************************************************/
typedef union asf_object_u typedef union asf_object_u
{ {
asf_object_common_t common; asf_object_common_t common;
...@@ -354,35 +364,16 @@ typedef union asf_object_u ...@@ -354,35 +364,16 @@ typedef union asf_object_u
} asf_object_t; } asf_object_t;
off_t ASF_TellAbsolute( input_thread_t *p_input );
int ASF_SeekAbsolute( input_thread_t *p_input, off_t i_pos); void ASF_GetGUID ( guid_t *p_guid, uint8_t *p_data );
int ASF_ReadData( input_thread_t *p_input, uint8_t *p_buff, int i_size ); int ASF_CmpGUID ( const guid_t *p_guid1, const guid_t *p_guid2 );
int ASF_SkipBytes( input_thread_t *p_input, int i_count );
asf_object_root_t *ASF_ReadObjectRoot( stream_t *, int b_seekable );
void ASF_GetGUID( guid_t *p_guid, uint8_t *p_data ); void ASF_FreeObjectRoot ( stream_t *, asf_object_root_t *p_root );
int ASF_CmpGUID( const guid_t *p_guid1, const guid_t *p_guid2 );
int ASF_ReadObjectCommon( input_thread_t *p_input,
asf_object_t *p_obj );
int ASF_NextObject( input_thread_t *p_input,
asf_object_t *p_obj );
int ASF_GotoObject( input_thread_t *p_input,
asf_object_t *p_obj );
int ASF_ReadObject( input_thread_t *p_input,
asf_object_t *p_obj,
asf_object_t *p_father );
void ASF_FreeObject( input_thread_t *p_input,
asf_object_t *p_obj );
int ASF_ReadObjectRoot( input_thread_t *p_input,
asf_object_root_t *p_root,
int b_seekable );
void ASF_FreeObjectRoot( input_thread_t *p_input,
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