Commit c4419019 authored by Laurent Aimar's avatar Laurent Aimar

* plugins/avi/avi.c : corrected a bug with broken avi file.

parent 6ee8965b
...@@ -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.8 2002/04/30 12:35:24 fenrir Exp $ * $Id: avi.c,v 1.9 2002/04/30 16:42:14 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
...@@ -325,7 +325,6 @@ static int __AVI_SeekToChunk( input_thread_t *p_input, AVIStreamInfo_t *p_info ) ...@@ -325,7 +325,6 @@ static int __AVI_SeekToChunk( input_thread_t *p_input, AVIStreamInfo_t *p_info )
if( (p_info->p_index != NULL)&&(p_info->i_idxposc < p_info->i_idxnb) ) if( (p_info->p_index != NULL)&&(p_info->i_idxposc < p_info->i_idxnb) )
{ {
/* perfect */
off_t i_pos; off_t i_pos;
i_pos = (off_t)p_info->p_index[p_info->i_idxposc].i_offset + i_pos = (off_t)p_info->p_index[p_info->i_idxposc].i_offset +
p_info->i_idxoffset; p_info->i_idxoffset;
...@@ -912,7 +911,7 @@ static int __AVI_NextIndexEntry( input_thread_t *p_input, ...@@ -912,7 +911,7 @@ static int __AVI_NextIndexEntry( input_thread_t *p_input,
} }
/* save idxpos of p_info */ /* save idxpos of p_info */
/* now parse for all stream and stop when reach next chunk for p_info */ /* now parse for all stream and stop when reach next chunk for p_info */
for( i = 0; (i < 30)||(!b_inc); i++) for( i = 0; (i < 15)||(!b_inc); i++)
{ {
int i_number; int i_number;
u16 i_type; u16 i_type;
...@@ -1051,6 +1050,7 @@ static int __AVI_GoToStreamBytes( input_thread_t *p_input, ...@@ -1051,6 +1050,7 @@ static int __AVI_GoToStreamBytes( input_thread_t *p_input,
if( p_info->p_index[p_info->i_idxnb - 1].i_lengthtotal + if( p_info->p_index[p_info->i_idxnb - 1].i_lengthtotal +
p_info->p_index[p_info->i_idxnb - 1].i_length <= i_byte) p_info->p_index[p_info->i_idxnb - 1].i_length <= i_byte)
{ {
p_info->i_idxposc = p_info->i_idxnb - 1;
while( p_info->p_index[p_info->i_idxposc].i_lengthtotal + while( p_info->p_index[p_info->i_idxposc].i_lengthtotal +
p_info->p_index[p_info->i_idxposc].i_length <= i_byte) p_info->p_index[p_info->i_idxposc].i_length <= i_byte)
{ {
...@@ -1079,7 +1079,7 @@ static int __AVI_GoToStreamBytes( input_thread_t *p_input, ...@@ -1079,7 +1079,7 @@ static int __AVI_GoToStreamBytes( input_thread_t *p_input,
p_info->p_index[i_idxposc].i_length <= i_byte) p_info->p_index[i_idxposc].i_length <= i_byte)
{ {
i_idxmin = i_idxposc ; i_idxmin = i_idxposc ;
i_idxposc = (p_info->i_idxmax + i_idxposc ) / 2 ; i_idxposc = (i_idxmax + i_idxposc ) / 2 ;
} }
else else
{ {
...@@ -1194,20 +1194,20 @@ static pes_packet_t *__AVI_ReadStreamBytesInPES( input_thread_t *p_input, ...@@ -1194,20 +1194,20 @@ static pes_packet_t *__AVI_ReadStreamBytesInPES( input_thread_t *p_input,
static __inline__ mtime_t __AVI_PTSToChunk( AVIStreamInfo_t *p_info, static __inline__ mtime_t __AVI_PTSToChunk( AVIStreamInfo_t *p_info,
mtime_t i_pts ) mtime_t i_pts )
{ {
return( (mtime_t)((double)i_pts * return( (mtime_t)((mtime_t)i_pts *
(double)p_info->header.i_rate / (mtime_t)p_info->header.i_rate /
(double)p_info->header.i_scale / (mtime_t)p_info->header.i_scale /
(double)1000000.0 ) ); (mtime_t)1000000.0 ) );
} }
static __inline__ mtime_t __AVI_PTSToByte( AVIStreamInfo_t *p_info, static __inline__ mtime_t __AVI_PTSToByte( AVIStreamInfo_t *p_info,
mtime_t i_pts ) mtime_t i_pts )
{ {
return( (mtime_t)((double)i_pts * return( (mtime_t)((mtime_t)i_pts *
(double)p_info->header.i_samplesize * (mtime_t)p_info->header.i_samplesize *
(double)p_info->header.i_rate / (mtime_t)p_info->header.i_rate /
(double)p_info->header.i_scale / (mtime_t)p_info->header.i_scale /
(double)1000000.0 ) ); (mtime_t)1000000.0 ) );
} }
...@@ -1293,7 +1293,6 @@ static int __AVI_ReAlign( input_thread_t *p_input ) ...@@ -1293,7 +1293,6 @@ static int __AVI_ReAlign( input_thread_t *p_input )
i_idxposc = (i_idxposc_a - i_idxposc < i_idxposc = (i_idxposc_a - i_idxposc <
i_idxposc - i_idxposc_b ) ? i_idxposc_a : i_idxposc_b; i_idxposc - i_idxposc_b ) ? i_idxposc_a : i_idxposc_b;
__AVI_GoToStreamChunk( p_input, p_info, i_idxposc ); __AVI_GoToStreamChunk( p_input, p_info, i_idxposc );
} }
return( 0 ); return( 0 );
...@@ -1304,7 +1303,6 @@ static int __AVI_ReAlign( input_thread_t *p_input ) ...@@ -1304,7 +1303,6 @@ static int __AVI_ReAlign( input_thread_t *p_input )
static void __AVI_SynchroReInit( input_thread_t *p_input ) static void __AVI_SynchroReInit( input_thread_t *p_input )
{ {
demux_data_avi_file_t *p_avi_demux; demux_data_avi_file_t *p_avi_demux;
mtime_t i_dpts;
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;
p_input->stream.p_selected_program->i_synchro_state = SYNCHRO_OK; p_input->stream.p_selected_program->i_synchro_state = SYNCHRO_OK;
...@@ -1323,13 +1321,10 @@ static void __AVI_SynchroReInit( input_thread_t *p_input ) ...@@ -1323,13 +1321,10 @@ static void __AVI_SynchroReInit( input_thread_t *p_input )
/*don't care of AVIF_KEYFRAME */ /*don't care of AVIF_KEYFRAME */
if( p_avi_demux->p_info_audio != NULL ) if( p_avi_demux->p_info_audio != NULL )
{ {
i_dpts = __AVI_GetPTS( p_avi_demux->p_info_video )
- __AVI_GetPTS( p_avi_demux->p_info_audio );
if( p_avi_demux->p_info_audio->header.i_samplesize == 0 ) if( p_avi_demux->p_info_audio->header.i_samplesize == 0 )
{ {
int i_chunk = __AVI_PTSToChunk( p_avi_demux->p_info_audio, int i_chunk = __AVI_PTSToChunk( p_avi_demux->p_info_audio,
i_dpts) + __AVI_GetPTS( p_avi_demux->p_info_video ));
p_avi_demux->p_info_audio->i_idxposc;
if( i_chunk < 0 ) if( i_chunk < 0 )
{ {
i_chunk = 0; i_chunk = 0;
...@@ -1341,9 +1336,7 @@ static void __AVI_SynchroReInit( input_thread_t *p_input ) ...@@ -1341,9 +1336,7 @@ static void __AVI_SynchroReInit( input_thread_t *p_input )
else else
{ {
int i_byte = __AVI_PTSToByte( p_avi_demux->p_info_audio, int i_byte = __AVI_PTSToByte( p_avi_demux->p_info_audio,
i_dpts) + __AVI_GetPTS( p_avi_demux->p_info_video ) );
p_avi_demux->p_info_audio->p_index[p_avi_demux->p_info_audio->i_idxposc].i_lengthtotal +
p_avi_demux->p_info_audio->i_idxposb;
if( i_byte < 0 ) if( i_byte < 0 )
{ {
i_byte = 0; i_byte = 0;
...@@ -1370,14 +1363,10 @@ static pes_packet_t *__AVI_GetFrameInPES( input_thread_t *p_input, ...@@ -1370,14 +1363,10 @@ static pes_packet_t *__AVI_GetFrameInPES( input_thread_t *p_input,
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;
if( p_info == NULL ) if( ( !p_info)||(i_dpts < 0 ) )
{ {
return( NULL ) ; return( NULL ) ;
} }
if( i_dpts < 0 )
{
return( NULL );
}
/* if i_pts is too small use 100 ms */ /* if i_pts is too small use 100 ms */
if( i_dpts <= 100000) if( i_dpts <= 100000)
{ {
...@@ -1397,21 +1386,20 @@ static pes_packet_t *__AVI_GetFrameInPES( input_thread_t *p_input, ...@@ -1397,21 +1386,20 @@ static pes_packet_t *__AVI_GetFrameInPES( input_thread_t *p_input,
/* get pts while is valid */ /* get pts while is valid */
i_pts = __AVI_GetPTS( p_info ); i_pts = __AVI_GetPTS( p_info );
p_pes_tmp = __AVI_ReadStreamChunkInPES( p_input, p_info ); p_pes_tmp = __AVI_ReadStreamChunkInPES( p_input, p_info );
if( p_pes_tmp == NULL ) if( !p_pes_tmp )
{ {
return( p_pes_first ); return( p_pes_first );
} }
p_pes_tmp->i_pts = i_pts; p_pes_tmp->i_pts = i_pts;
if( p_pes_first == NULL ) if( !p_pes_first )
{ {
p_pes_first = p_pes_tmp; p_pes_first = p_pes_tmp;
p_pes = p_pes_tmp;
} }
else else
{ {
p_pes->p_next = p_pes_tmp; p_pes->p_next = p_pes_tmp;
p_pes = p_pes_tmp;
} }
p_pes = p_pes_tmp;
} }
return( p_pes_first ); return( p_pes_first );
} }
...@@ -1432,6 +1420,35 @@ static pes_packet_t *__AVI_GetFrameInPES( input_thread_t *p_input, ...@@ -1432,6 +1420,35 @@ static pes_packet_t *__AVI_GetFrameInPES( input_thread_t *p_input,
} }
} }
static void __AVI_DecodePES( AVIStreamInfo_t *p_info,
pes_packet_t *p_pes,
mtime_t i_date )
{
pes_packet_t *p_pes_next;
if( ( !p_info )||( !p_pes ) )
{
return;
}
vlc_mutex_lock( &p_info->p_es->p_decoder_fifo->data_lock );
if( p_info->p_es->p_decoder_fifo->i_depth >= MAX_PACKETS_IN_FIFO )
{
vlc_cond_wait( &p_info->p_es->p_decoder_fifo->data_wait,
&p_info->p_es->p_decoder_fifo->data_lock );
}
vlc_mutex_unlock( &p_info->p_es->p_decoder_fifo->data_lock );
/* input_decode want only one pes, but AVI_GetFrameInPES give
multiple pes so send one by one */
do
{
p_pes_next = p_pes->p_next;
p_pes->p_next = NULL;
p_pes->i_pts += i_date;
input_DecodePES( p_info->p_es->p_decoder_fifo, p_pes );
p_pes = p_pes_next;
} while( p_pes != NULL );
}
/***************************************************************************** /*****************************************************************************
* AVIDemux: reads and demuxes data packets * AVIDemux: reads and demuxes data packets
***************************************************************************** *****************************************************************************
...@@ -1447,13 +1464,13 @@ static int AVIDemux( input_thread_t *p_input ) ...@@ -1447,13 +1464,13 @@ static int AVIDemux( input_thread_t *p_input )
/* try to use this to read data packet at the good time /* 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)pcr ); ??? what suppose to do */ (mtime_t)pcr ); ??? what is supposed 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 new video and audio stream selected /* search new video and audio stream selected
if current have been unselected*/ if current have been unselected*/
if( (p_avi_demux->p_info_video == NULL ) if( ( !p_avi_demux->p_info_video )
|| (p_avi_demux->p_info_video->p_es->p_decoder_fifo == NULL ) ) || ( !p_avi_demux->p_info_video->p_es->p_decoder_fifo ) )
{ {
p_avi_demux->p_info_video = NULL; p_avi_demux->p_info_video = NULL;
for( i = 0; i < p_avi_demux->i_streams; i++ ) for( i = 0; i < p_avi_demux->i_streams; i++ )
...@@ -1467,8 +1484,8 @@ static int AVIDemux( input_thread_t *p_input ) ...@@ -1467,8 +1484,8 @@ static int AVIDemux( input_thread_t *p_input )
} }
} }
} }
if( (p_avi_demux->p_info_audio == NULL ) if( ( !p_avi_demux->p_info_audio )
||(p_avi_demux->p_info_audio->p_es->p_decoder_fifo == NULL ) ) ||( !p_avi_demux->p_info_audio->p_es->p_decoder_fifo ) )
{ {
p_avi_demux->p_info_audio = NULL; p_avi_demux->p_info_audio = NULL;
for( i = 0; i < p_avi_demux->i_streams; i++ ) for( i = 0; i < p_avi_demux->i_streams; i++ )
...@@ -1483,7 +1500,7 @@ static int AVIDemux( input_thread_t *p_input ) ...@@ -1483,7 +1500,7 @@ static int AVIDemux( input_thread_t *p_input )
} }
} }
/* for now, we need at least one video stream */ /* for now, we need at least one video stream */
if( p_avi_demux->p_info_video == NULL ) if( !p_avi_demux->p_info_video )
{ {
intf_ErrMsg( "input error: no video ouput selected" ); intf_ErrMsg( "input error: no video ouput selected" );
return( -1 ); return( -1 );
...@@ -1542,36 +1559,12 @@ static int AVIDemux( input_thread_t *p_input ) ...@@ -1542,36 +1559,12 @@ static int AVIDemux( input_thread_t *p_input )
100000 ); /* 100 ms */ 100000 ); /* 100 ms */
} }
/* send them to decoder */ /* send them to decoder */
for( i = 0; i < 2; i++ ) __AVI_DecodePES( p_avi_demux->p_info_audio, p_pes_audio,
{ p_avi_demux->i_date );
pes_packet_t *p_pes = ( i == 0 ? p_pes_audio : p_pes_video ); __AVI_DecodePES( p_avi_demux->p_info_video, p_pes_video,
AVIStreamInfo_t *p_info = ( i == 0 ? p_avi_demux->p_info_audio : p_avi_demux->i_date );
p_avi_demux->p_info_video );
/* send audio first */
if( ( p_info != NULL )&&( p_pes != NULL ) )
{
vlc_mutex_lock( &p_info->p_es->p_decoder_fifo->data_lock );
if( p_info->p_es->p_decoder_fifo->i_depth >= MAX_PACKETS_IN_FIFO )
{
vlc_cond_wait( &p_info->p_es->p_decoder_fifo->data_wait,
&p_info->p_es->p_decoder_fifo->data_lock );
}
vlc_mutex_unlock( &p_info->p_es->p_decoder_fifo->data_lock );
/* input_decode want only one pes, but AVI_GetFrameInPES give
multiple pes so send one by one */
do
{
pes_packet_t *p_pes_next = p_pes->p_next;
p_pes->p_next = NULL;
p_pes->i_pts += p_avi_demux->i_date;
input_DecodePES( p_info->p_es->p_decoder_fifo, p_pes );
p_pes = p_pes_next;
} while( p_pes != NULL );
}
}
if( p_pes_video == NULL ) /* no more video */ if( !p_pes_video ) /* no more video */
{ /* currently i need a video stream */ { /* currently i need a video stream */
return( 0 ); return( 0 );
} }
......
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