Commit fb1e2cb9 authored by Laurent Aimar's avatar Laurent Aimar

* All: use input_ClockManageRef to do synchro.

parent 94bda0d1
...@@ -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.15 2002/05/10 02:04:17 fenrir Exp $ * $Id: avi.c,v 1.16 2002/05/10 04:06:10 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
...@@ -449,7 +449,7 @@ static int AVIInit( input_thread_t *p_input ) ...@@ -449,7 +449,7 @@ static int AVIInit( input_thread_t *p_input )
return( -1 ); return( -1 );
} }
memset( p_avi_demux, 0, sizeof( demux_data_avi_file_t ) ); memset( p_avi_demux, 0, sizeof( demux_data_avi_file_t ) );
p_avi_demux->i_rate = DEFAULT_RATE;
/* FIXME I don't know what it's do, copied from ESInit */ /* FIXME I don't know what it's do, copied from ESInit */
/* Initialize access plug-in structures. */ /* Initialize access plug-in structures. */
if( p_input->i_mtu == 0 ) if( p_input->i_mtu == 0 )
...@@ -831,7 +831,6 @@ static void AVIEnd( input_thread_t *p_input ) ...@@ -831,7 +831,6 @@ static void AVIEnd( input_thread_t *p_input )
static mtime_t AVI_GetPTS( AVIStreamInfo_t *p_info ) static mtime_t AVI_GetPTS( AVIStreamInfo_t *p_info )
{ {
/* XXX you need to add p_info->i_date to have correct pts */
/* p_info->p_index[p_info->i_idxposc] need to be valid !! */ /* p_info->p_index[p_info->i_idxposc] need to be valid !! */
mtime_t i_pts; mtime_t i_pts;
...@@ -1245,10 +1244,6 @@ static int AVI_ReAlign( input_thread_t *p_input ) ...@@ -1245,10 +1244,6 @@ static int AVI_ReAlign( input_thread_t *p_input )
} }
else else
{ {
__AVI_GoToStreamChunk( p_input,
p_info,
0 );
__AVI_GoToStreamBytes( p_input, __AVI_GoToStreamBytes( p_input,
p_info, p_info,
0); 0);
...@@ -1318,46 +1313,32 @@ static int AVI_ReAlign( input_thread_t *p_input ) ...@@ -1318,46 +1313,32 @@ static int AVI_ReAlign( input_thread_t *p_input )
return( 0 ); return( 0 );
} }
/* update i_date and */
/* make difference between audio and video pts as little as possible */ /* make difference between audio and video pts as little as possible */
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;
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;
if( p_avi_demux->p_info_video == NULL ) if( ( p_avi_demux->p_info_video )&&( p_avi_demux->p_info_audio ) )
{
p_avi_demux->i_date = mdate() + DEFAULT_PTS_DELAY
- AVI_GetPTS( p_avi_demux->p_info_audio );
return;
}
else
{ {
p_avi_demux->i_date = mdate() + DEFAULT_PTS_DELAY
- AVI_GetPTS( p_avi_demux->p_info_video );
/* now resynch audio video video */ /* now resynch audio video video */
/*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->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,
{ AVI_GetPTS( p_avi_demux->p_info_video ));
int i_chunk = __AVI_PTSToChunk( p_avi_demux->p_info_audio, __AVI_GoToStreamChunk( p_input,
AVI_GetPTS( p_avi_demux->p_info_video )); p_avi_demux->p_info_audio,
__AVI_GoToStreamChunk( p_input, i_chunk );
p_avi_demux->p_info_audio, }
i_chunk ); else
} {
else int i_byte = __AVI_PTSToByte( p_avi_demux->p_info_audio,
{ AVI_GetPTS( p_avi_demux->p_info_video ) ) ;
int i_byte = __AVI_PTSToByte( p_avi_demux->p_info_audio, __AVI_GoToStreamBytes( p_input,
AVI_GetPTS( p_avi_demux->p_info_video ) ) ; p_avi_demux->p_info_audio,
__AVI_GoToStreamBytes( p_input, i_byte );
p_avi_demux->p_info_audio,
i_byte );
}
} }
} }
} }
...@@ -1431,33 +1412,24 @@ static pes_packet_t *AVI_GetFrameInPES( input_thread_t *p_input, ...@@ -1431,33 +1412,24 @@ static pes_packet_t *AVI_GetFrameInPES( input_thread_t *p_input,
} }
} }
static void AVI_DecodePES( AVIStreamInfo_t *p_info, static void AVI_DecodePES( input_thread_t *p_input,
pes_packet_t *p_pes, AVIStreamInfo_t *p_info,
mtime_t i_date, pes_packet_t *p_pes )
int i_rate )
{ {
pes_packet_t *p_pes_next; pes_packet_t *p_pes_next;
if( ( !p_info )||( !p_pes ) ) if( ( !p_info )||( !p_pes ) )
{ {
return; 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 /* input_decode want only one pes, but AVI_GetFrameInPES give
multiple pes so send one by one */ multiple pes so send one by one */
do do
{ {
p_pes_next = p_pes->p_next; p_pes_next = p_pes->p_next;
p_pes->p_next = NULL; p_pes->p_next = NULL;
p_pes->i_pts = i_date + p_pes->i_pts * (mtime_t)i_rate / p_pes->i_pts = input_ClockGetTS( p_input,
(mtime_t)DEFAULT_RATE; p_input->stream.p_selected_program,
p_pes->i_pts * 9/100);
input_DecodePES( p_info->p_es->p_decoder_fifo, p_pes ); input_DecodePES( p_info->p_es->p_decoder_fifo, p_pes );
p_pes = p_pes_next; p_pes = p_pes_next;
} while( p_pes ); } while( p_pes );
...@@ -1473,18 +1445,12 @@ static int AVIDemux( input_thread_t *p_input ) ...@@ -1473,18 +1445,12 @@ static int AVIDemux( input_thread_t *p_input )
{ {
int i; int i;
mtime_t i_pcr; mtime_t i_pcr;
pes_packet_t *p_pes_master; /* video , or audio if no video */ pes_packet_t *p_pes;
pes_packet_t *p_pes_slave; /* audio if there is video */
AVIStreamInfo_t *p_info_master; AVIStreamInfo_t *p_info_master;
AVIStreamInfo_t *p_info_slave; AVIStreamInfo_t *p_info_slave;
demux_data_avi_file_t *p_avi_demux; demux_data_avi_file_t *p_avi_demux =
(demux_data_avi_file_t*)p_input->p_demux_data;
/* try to use this to read data packet at the good time
* input_ClockManageRef( p_input,
p_input->stream.p_selected_program,
(mtime_t)pcr ); ??? what is supposed to do */
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*/
...@@ -1518,7 +1484,7 @@ static int AVIDemux( input_thread_t *p_input ) ...@@ -1518,7 +1484,7 @@ static int AVIDemux( input_thread_t *p_input )
} }
} }
} }
/* by default synchro is made upon video */ /* by default video is master for resync audio (after a seek .. ) */
if( p_avi_demux->p_info_video ) if( p_avi_demux->p_info_video )
{ {
p_info_master = p_avi_demux->p_info_video; p_info_master = p_avi_demux->p_info_video;
...@@ -1537,100 +1503,80 @@ static int AVIDemux( input_thread_t *p_input ) ...@@ -1537,100 +1503,80 @@ static int AVIDemux( input_thread_t *p_input )
} }
/* check for signal from interface */ /* check for signal from interface */
if( (input_ClockManageControl( p_input, p_input->stream.p_selected_program,
(mtime_t)0) == PAUSE_S) )
{
AVI_SynchroReInit( p_input ); /* resynchro, and make pts audio
and video egual */
p_avi_demux->i_rate = DEFAULT_RATE;
}
if( p_input->stream.p_selected_program->i_synchro_state == SYNCHRO_REINIT ) if( p_input->stream.p_selected_program->i_synchro_state == SYNCHRO_REINIT )
{ {
/* wait until buffer is empty */ /* we can supposed that is a seek */
msleep( 3*DEFAULT_PTS_DELAY ); /* first wait for empty buffer, arbitrary time */
/*realign audio and video stream to the good pts*/ msleep( DEFAULT_PTS_DELAY );
/* so try to realign in stream */
if( AVI_ReAlign( p_input ) != 0 ) if( AVI_ReAlign( p_input ) != 0 )
{ {
return( 0 ); /* assume EOF */ return( 0 ); /* assume EOF */
} }
AVI_SynchroReInit( p_input ); /* resynchro, and make pts audio AVI_SynchroReInit( p_input );
and video egual */
p_avi_demux->i_rate = DEFAULT_RATE;
} }
/* manage rate, if not default skeep audio */
vlc_mutex_lock( &p_input->stream.stream_lock ); vlc_mutex_lock( &p_input->stream.stream_lock );
if( (p_input->stream.control.i_rate != p_avi_demux->i_rate) if( p_input->stream.control.i_rate != p_avi_demux->i_rate )
&&(p_info_master->i_cat == VIDEO_ES) )
{ {
msleep( 3*DEFAULT_PTS_DELAY ); if( p_avi_demux->p_info_audio)
p_avi_demux->i_rate = p_input->stream.control.i_rate;
p_avi_demux->i_date = mdate() + DEFAULT_PTS_DELAY
- AVI_GetPTS( p_info_master ) *
(mtime_t)p_avi_demux->i_rate /
(mtime_t)DEFAULT_RATE ;
if( p_avi_demux->i_rate == DEFAULT_RATE )
{ {
if( p_avi_demux->p_info_audio ) p_avi_demux->p_info_audio->b_selected = 1;
{
p_avi_demux->p_info_audio->b_selected = 1;
}
} }
p_avi_demux->i_rate = p_input->stream.control.i_rate;
} }
vlc_mutex_unlock( &p_input->stream.stream_lock );
if( p_avi_demux->i_rate != DEFAULT_RATE ) if( p_avi_demux->i_rate != DEFAULT_RATE )
{ {
p_info_slave = NULL; p_info_slave = NULL;
} }
vlc_mutex_unlock( &p_input->stream.stream_lock );
/* take care of newly selected audio ES */ /* take care of newly selected audio ES */
if( p_info_master->b_selected ) if( p_info_master->b_selected )
{ {
p_info_master->b_selected = 0; p_info_master->b_selected = 0;
AVI_SynchroReInit( p_input ); /* resynchro, and make pts audio AVI_SynchroReInit( p_input );
and video equal */
} }
if( ( p_info_slave )&&( p_info_slave->b_selected ) ) if( ( p_info_slave )&&( p_info_slave->b_selected ) )
{ {
p_info_slave->b_selected = 0; p_info_slave->b_selected = 0;
AVI_SynchroReInit( p_input ); AVI_SynchroReInit( p_input );
} }
/* get audio and video frame */ /* calculate pcr, time when we must read data */
if( p_info_slave ) if( p_info_slave )
{ {
i_pcr = p_avi_demux->i_date + __MIN( AVI_GetPTS( p_info_master ), i_pcr = __MIN( AVI_GetPTS( p_info_master ),
AVI_GetPTS( p_info_slave) ) AVI_GetPTS( p_info_slave ) ) * 9/100;
- mdate() - DEFAULT_PTS_DELAY; /* 9/100 kludge ->need to convert to 1/1000000 clock unit to 1/90000 */
} }
else else
{ {
i_pcr = p_avi_demux->i_date + AVI_GetPTS( p_info_master ) i_pcr = AVI_GetPTS( p_info_master ) * 9/100;
- mdate() - DEFAULT_PTS_DELAY;
}
if( i_pcr > 0 )
{
msleep( i_pcr );
} }
p_pes_master = AVI_GetFrameInPES( p_input, input_ClockManageRef( p_input,
p_info_master, p_input->stream.p_selected_program,
100000 ); /* 100 ms */ p_avi_demux->i_pcr );
p_avi_demux->i_pcr = i_pcr;
/* get video and audio frames */
p_pes = AVI_GetFrameInPES( p_input,
p_info_master,
100000 ); /* 100 ms */
AVI_DecodePES( p_input,
p_info_master,
p_pes);
if( p_info_slave ) if( p_info_slave )
{ {
p_pes_slave = AVI_GetFrameInPES( p_input, p_pes = AVI_GetFrameInPES( p_input,
p_info_slave, p_info_slave,
AVI_GetPTS( p_info_master ) - AVI_GetPTS( p_info_master ) -
AVI_GetPTS( p_info_slave)); AVI_GetPTS( p_info_slave));
/* decode it first because video will make us wait */ AVI_DecodePES( p_input,
AVI_DecodePES( p_info_slave, p_info_slave,
p_pes_slave, p_pes );
p_avi_demux->i_date, }
p_avi_demux->i_rate );
}
AVI_DecodePES( p_info_master,
p_pes_master,
p_avi_demux->i_date,
p_avi_demux->i_rate );
/* at the end ? */ /* at the end ? */
if( p_info_master->i_idxposc >= p_info_master->i_idxnb ) if( p_info_master->i_idxposc >= p_info_master->i_idxnb )
{ {
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* avi.h : AVI file Stream input module for vlc * avi.h : AVI file Stream input module for vlc
***************************************************************************** *****************************************************************************
* Copyright (C) 2001 VideoLAN * Copyright (C) 2001 VideoLAN
* $Id: avi.h,v 1.4 2002/05/02 10:54:34 fenrir Exp $ * $Id: avi.h,v 1.5 2002/05/10 04:06:10 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
...@@ -141,7 +141,7 @@ typedef struct AVIStreamInfo_s ...@@ -141,7 +141,7 @@ typedef struct AVIStreamInfo_s
typedef struct demux_data_avi_file_s typedef struct demux_data_avi_file_s
{ {
mtime_t i_date; mtime_t i_pcr;
int i_rate; int i_rate;
riffchunk_t *p_riff; riffchunk_t *p_riff;
riffchunk_t *p_hdrl; riffchunk_t *p_hdrl;
......
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