Commit 36b915c1 authored by Laurent Aimar's avatar Laurent Aimar

* plugins/avi/avi.c : with some broken avi file, will not freeze, and

try to detect end of file.
parent 9d6920b9
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* avi.c : AVI file Stream input module for vlc * avi.c : AVI file Stream input module for vlc
***************************************************************************** *****************************************************************************
* Copyright (C) 2001 VideoLAN * Copyright (C) 2001 VideoLAN
* $Id: avi.c,v 1.6 2002/04/27 16:13:23 fenrir Exp $ * $Id: avi.c,v 1.7 2002/04/27 22:54:00 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
...@@ -671,7 +671,7 @@ static int AVIInit( input_thread_t *p_input ) ...@@ -671,7 +671,7 @@ static int AVIInit( input_thread_t *p_input )
#define p_info p_avi_demux->pp_info[i] #define p_info p_avi_demux->pp_info[i]
if( p_info->p_index == NULL ) if( p_info->p_index == NULL )
{ {
intf_WarnMsg( 1, "input init: add index entry for stream %d", i ); intf_WarnMsg( 3, "input init: add index entry for stream %d", i );
RIFF_GoToChunk( p_input, p_avi_demux->p_movi ); RIFF_GoToChunk( p_input, p_avi_demux->p_movi );
if( RIFF_DescendChunk(p_input) != 0 ) { continue; } if( RIFF_DescendChunk(p_input) != 0 ) { continue; }
p_chunk = NULL; p_chunk = NULL;
...@@ -784,8 +784,6 @@ static int AVIInit( input_thread_t *p_input ) ...@@ -784,8 +784,6 @@ static int AVIInit( input_thread_t *p_input )
vlc_mutex_lock( &p_input->stream.stream_lock ); vlc_mutex_lock( &p_input->stream.stream_lock );
if( p_es_video != NULL ) if( p_es_video != NULL )
{ {
intf_WarnMsg( 1,"input init: selecting video stream %d",
p_es_video->i_id );
input_SelectES( p_input, p_es_video ); input_SelectES( p_input, p_es_video );
/* it seems that it's useless to select es because there are selected /* it seems that it's useless to select es because there are selected
* by the interface but i'm not sure of that */ * by the interface but i'm not sure of that */
...@@ -798,8 +796,6 @@ static int AVIInit( input_thread_t *p_input ) ...@@ -798,8 +796,6 @@ static int AVIInit( input_thread_t *p_input )
} }
if( p_es_audio != NULL ) if( p_es_audio != NULL )
{ {
intf_WarnMsg( 1,"input init: selecting audio stream %d",
p_es_audio->i_id );
input_SelectES( p_input, p_es_audio ); input_SelectES( p_input, p_es_audio );
} }
else else
...@@ -902,7 +898,7 @@ static int __AVI_NextIndexEntry( input_thread_t *p_input, ...@@ -902,7 +898,7 @@ static int __AVI_NextIndexEntry( input_thread_t *p_input,
u16 i_type; u16 i_type;
if( (p_chunk = RIFF_ReadChunk( p_input )) == NULL ) if( (p_chunk = RIFF_ReadChunk( p_input )) == NULL )
{ {
if( i > 0) if( b_inc )
{ {
return( 0 ); return( 0 );
} }
...@@ -917,12 +913,11 @@ static int __AVI_NextIndexEntry( input_thread_t *p_input, ...@@ -917,12 +913,11 @@ static int __AVI_NextIndexEntry( input_thread_t *p_input,
index.i_offset = p_chunk->i_pos; index.i_offset = p_chunk->i_pos;
index.i_length = p_chunk->i_size; index.i_length = p_chunk->i_size;
RIFF_DeleteChunk( p_input, p_chunk ); RIFF_DeleteChunk( p_input, p_chunk );
#define p_info_i p_avi_demux->pp_info[i_number] #define p_info_i p_avi_demux->pp_info[i_number]
if( (__AVI_ParseStreamHeader( index.i_id, &i_number, &i_type ) == 0) if( (__AVI_ParseStreamHeader( index.i_id, &i_number, &i_type ) == 0)
&&( i_number < p_avi_demux->i_streams ) &&( i_number < p_avi_demux->i_streams )
&& (p_info_i->p_index[p_info_i->i_idxnb - 1].i_offset + && (p_info_i->p_index[p_info_i->i_idxnb - 1].i_offset +
p_info_i->p_index[p_info_i->i_idxnb - 1].i_length <= p_info_i->p_index[p_info_i->i_idxnb - 1].i_length + 8<=
index.i_offset ) ) index.i_offset ) )
{ {
/* do we need to check i_type ? */ /* do we need to check i_type ? */
...@@ -936,7 +931,7 @@ static int __AVI_NextIndexEntry( input_thread_t *p_input, ...@@ -936,7 +931,7 @@ static int __AVI_NextIndexEntry( input_thread_t *p_input,
#undef p_info_i #undef p_info_i
if( RIFF_NextChunk( p_input, p_avi_demux->p_movi ) != 0 ) if( RIFF_NextChunk( p_input, p_avi_demux->p_movi ) != 0 )
{ {
if( i > 0) if( b_inc )
{ {
return( 0 ); return( 0 );
} }
...@@ -947,7 +942,6 @@ static int __AVI_NextIndexEntry( input_thread_t *p_input, ...@@ -947,7 +942,6 @@ static int __AVI_NextIndexEntry( input_thread_t *p_input,
} }
} }
return( 0 ); return( 0 );
intf_WarnMsg( 1, "input demux: added index entry(%d)",i );
} }
static int __AVI_ReAlign( input_thread_t *p_input, static int __AVI_ReAlign( input_thread_t *p_input,
...@@ -983,7 +977,7 @@ static int __AVI_ReAlign( input_thread_t *p_input, ...@@ -983,7 +977,7 @@ static int __AVI_ReAlign( input_thread_t *p_input,
__AVI_SeekToChunk will correct */ __AVI_SeekToChunk will correct */
if( (p_info->p_index[p_info->i_idxpos].i_offset <= i_pos) if( (p_info->p_index[p_info->i_idxpos].i_offset <= i_pos)
&& ( i_pos < p_info->p_index[p_info->i_idxpos].i_offset + && ( i_pos < p_info->p_index[p_info->i_idxpos].i_offset +
p_info->p_index[p_info->i_idxpos].i_length ) ) p_info->p_index[p_info->i_idxpos].i_length + 8) )
{ {
return( 0 ); return( 0 );
} }
...@@ -991,16 +985,19 @@ static int __AVI_ReAlign( input_thread_t *p_input, ...@@ -991,16 +985,19 @@ static int __AVI_ReAlign( input_thread_t *p_input,
if( i_pos >= p_info->p_index[p_info->i_idxpos].i_offset ) if( i_pos >= p_info->p_index[p_info->i_idxpos].i_offset )
{ {
/* search for a chunk after i_idxpos */ /* search for a chunk after i_idxpos */
while( (p_info->p_index[p_info->i_idxpos].i_offset < i_pos) while( (p_info->p_index[p_info->i_idxpos].i_offset < i_pos) )
&&( p_info->i_idxpos < p_info->i_idxnb - 1 ) ) /* &&( p_info->i_idxpos < p_info->i_idxnb - 1 ) ) */
{ {
/*
if( __AVI_NextIndexEntry( p_input, p_info ) != 0 ) if( __AVI_NextIndexEntry( p_input, p_info ) != 0 )
{ {
return( -1 ); return( -1 );
} }
*/
p_info->i_idxpos++; /* we know that index is valid (first test )*/
} }
while( ((p_info->p_index[p_info->i_idxpos].i_flags&AVIIF_KEYFRAME) == 0) while(((p_info->p_index[p_info->i_idxpos].i_flags&AVIIF_KEYFRAME) == 0))
&&( p_info->i_idxpos < p_info->i_idxnb - 1 ) ) /* &&( p_info->i_idxpos < p_info->i_idxnb - 1 ) ) */
{ {
if( __AVI_NextIndexEntry( p_input, p_info ) != 0 ) if( __AVI_NextIndexEntry( p_input, p_info ) != 0 )
{ {
...@@ -1012,7 +1009,7 @@ static int __AVI_ReAlign( input_thread_t *p_input, ...@@ -1012,7 +1009,7 @@ static int __AVI_ReAlign( input_thread_t *p_input,
{ {
/* search for a chunk before i_idxpos */ /* search for a chunk before i_idxpos */
while( (p_info->p_index[p_info->i_idxpos].i_offset + while( (p_info->p_index[p_info->i_idxpos].i_offset +
p_info->p_index[p_info->i_idxpos].i_length >= i_pos) p_info->p_index[p_info->i_idxpos].i_length + 8>= i_pos)
&&( p_info->i_idxpos > 0 ) ) &&( p_info->i_idxpos > 0 ) )
{ {
p_info->i_idxpos--; /* backward, index is always valid */ p_info->i_idxpos--; /* backward, index is always valid */
...@@ -1042,7 +1039,10 @@ static void __AVI_SynchroReInit( input_thread_t *p_input, ...@@ -1042,7 +1039,10 @@ static void __AVI_SynchroReInit( input_thread_t *p_input,
p_info_slave->i_idxpos = 0; p_info_slave->i_idxpos = 0;
while( __AVI_GetPTS( p_info_slave) < __AVI_GetPTS( p_info_master) ) while( __AVI_GetPTS( p_info_slave) < __AVI_GetPTS( p_info_master) )
{ {
__AVI_NextIndexEntry( p_input, p_info_slave ); if( __AVI_NextIndexEntry( p_input, p_info_slave ) != 0 )
{
return;
}
} }
if( (__AVI_GetPTS( p_info_slave) > __AVI_GetPTS( p_info_master)) if( (__AVI_GetPTS( p_info_slave) > __AVI_GetPTS( p_info_master))
&&(p_info_slave->i_idxpos>0) ) &&(p_info_slave->i_idxpos>0) )
...@@ -1056,16 +1056,6 @@ static void __AVI_SynchroReInit( input_thread_t *p_input, ...@@ -1056,16 +1056,6 @@ static void __AVI_SynchroReInit( input_thread_t *p_input,
/** -1 in case of error, 0 of EOF, 1 otherwise **/ /** -1 in case of error, 0 of EOF, 1 otherwise **/
static int AVIDemux( input_thread_t *p_input ) static int AVIDemux( input_thread_t *p_input )
{ {
/* on cherche un block
plusieurs cas :
* encapsuler dans un chunk "rec "
* juste une succesion de 00dc 01wb ...
* pire tout audio puis tout video ou vice versa
*/
/* TODO : * create dynamically index for invalid or incomplete index
* verify that we are reading in p_movi
* XXX be sure to send audio before video to avoid click
*/
riffchunk_t *p_chunk; riffchunk_t *p_chunk;
int i; int i;
pes_packet_t *p_pes; pes_packet_t *p_pes;
...@@ -1074,10 +1064,10 @@ static int AVIDemux( input_thread_t *p_input ) ...@@ -1074,10 +1064,10 @@ static int AVIDemux( input_thread_t *p_input )
AVIStreamInfo_t *p_info_video; AVIStreamInfo_t *p_info_video;
AVIStreamInfo_t *p_info_audio; AVIStreamInfo_t *p_info_audio;
AVIStreamInfo_t *p_info; AVIStreamInfo_t *p_info;
/* XXX arrive pas a avoir acces a cette fct */ /* try to use this to read data packet at the good time
/* input_ClockManageRef( p_input, * input_ClockManageRef( p_input,
p_input->stream.p_selected_program, p_input->stream.p_selected_program,
(mtime_t)0 ); ??? what suppose to do */ (mtime_t)pcr ); ??? what suppose to do */
p_avi_demux = (demux_data_avi_file_t*)p_input->p_demux_data; p_avi_demux = (demux_data_avi_file_t*)p_input->p_demux_data;
/* search video and audio stream selected */ /* search video and audio stream selected */
...@@ -1118,7 +1108,7 @@ static int AVIDemux( input_thread_t *p_input ) ...@@ -1118,7 +1108,7 @@ static int AVIDemux( input_thread_t *p_input )
if( p_input->stream.p_selected_program->i_synchro_state == SYNCHRO_REINIT ) if( p_input->stream.p_selected_program->i_synchro_state == SYNCHRO_REINIT )
{ {
/*realign on video stream*/ /*realign on video stream*/
if( __AVI_ReAlign( p_input, p_info_video ) != 0 ) if( __AVI_ReAlign( p_input, p_info_video ) != 0 )
{ {
return( 0 ); /* assume EOF */ return( 0 ); /* assume EOF */
} }
...@@ -1128,16 +1118,17 @@ static int AVIDemux( input_thread_t *p_input ) ...@@ -1128,16 +1118,17 @@ static int AVIDemux( input_thread_t *p_input )
/* update i_date if previously unselected ES (ex: 2 channels audio ) */ /* update i_date if previously unselected ES (ex: 2 channels audio ) */
if( (p_info_audio != NULL)&&(p_info_audio->b_unselected )) if( (p_info_audio != NULL)&&(p_info_audio->b_unselected ))
{ {
/* we have to go to the good pts */ p_info_audio->b_unselected = 0 ;
/* we have to go to the good pts */
/* we will reach p_info_ok pts */ /* we will reach p_info_ok pts */
while( __AVI_GetPTS( p_info_audio) < __AVI_GetPTS( p_info_video) ) while( __AVI_GetPTS( p_info_audio) < __AVI_GetPTS( p_info_video) )
{ {
if( __AVI_NextIndexEntry( p_input, p_info_audio ) != 0 ) if( __AVI_NextIndexEntry( p_input, p_info_audio ) != 0 )
{ {
p_info_audio = NULL; /* to force selection of video */
break; break;
} }
} }
p_info_audio->b_unselected = 0 ;
} }
/* what stream we should read in first */ /* what stream we should read in first */
...@@ -1173,7 +1164,10 @@ static int AVIDemux( input_thread_t *p_input ) ...@@ -1173,7 +1164,10 @@ static int AVIDemux( input_thread_t *p_input )
(p_info->p_index[p_info->i_idxpos].i_id&0xFFFF0000) ) (p_info->p_index[p_info->i_idxpos].i_id&0xFFFF0000) )
{ {
intf_WarnMsg( 2, "input demux: bad index entry" ); intf_WarnMsg( 2, "input demux: bad index entry" );
__AVI_NextIndexEntry( p_input, p_info ); if( __AVI_NextIndexEntry( p_input, p_info ) != 0 )
{
return( 0 );
}
return( 1 ); return( 1 );
} }
/* /*
......
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