* mpeg_system.c: TS, PS and PES management
*****************************************************************************
* Copyright (C) 1998, 1999, 2000 VideoLAN
- * $Id: mpeg_system.c,v 1.13 2000/12/21 13:54:15 massiot Exp $
+ * $Id: mpeg_system.c,v 1.16 2000/12/22 13:04:45 sam Exp $
*
* Authors:
*
#include "input.h"
#include "mpeg_system.h"
+#include "input_dec.h"
#include "main.h" /* AC3/MPEG channel, SPU channel */
* PES Packet management
*/
-/*****************************************************************************
- * input_DecodePES
- *****************************************************************************
- * Put a PES in the decoder's fifo.
- *****************************************************************************/
-void input_DecodePES( input_thread_t * p_input, es_descriptor_t * p_es )
-{
-#define p_pes (p_es->p_pes)
-
- if( p_es->p_decoder_fifo != NULL )
- {
- vlc_mutex_lock( &p_es->p_decoder_fifo->data_lock );
-
-#if 0
- if( p_input->stream.b_pace_control )
- {
- /* FIXME : normally we shouldn't need this... */
- while( DECODER_FIFO_ISFULL( *p_es->p_decoder_fifo ) )
- {
- vlc_mutex_unlock( &p_es->p_decoder_fifo->data_lock );
- msleep( 20000 );
- vlc_mutex_lock( &p_es->p_decoder_fifo->data_lock );
- }
- }
-#endif
-
- if( !DECODER_FIFO_ISFULL( *p_es->p_decoder_fifo ) )
- {
- //intf_DbgMsg("Putting %p into fifo %p/%d\n",
- // p_pes, p_fifo, p_fifo->i_end);
- p_es->p_decoder_fifo->buffer[p_es->p_decoder_fifo->i_end] = p_pes;
- DECODER_FIFO_INCEND( *p_es->p_decoder_fifo );
-
- /* Warn the decoder that it's got work to do. */
- vlc_cond_signal( &p_es->p_decoder_fifo->data_wait );
- }
- else
- {
- /* The FIFO is full !!! This should not happen. */
- p_input->p_plugin->pf_delete_pes( p_input->p_method_data, p_pes );
- intf_ErrMsg( "PES trashed - fifo full ! (%d, %d)",
- p_es->i_id, p_es->i_type);
- }
- vlc_mutex_unlock( &p_es->p_decoder_fifo->data_lock );
- }
- else
- {
- intf_ErrMsg("No fifo to receive PES %p (who wrote this damn code ?)",
- p_pes);
- p_input->p_plugin->pf_delete_pes( p_input->p_method_data, p_pes );
- }
- p_pes = NULL;
-
-#undef p_pes
-}
-
/*****************************************************************************
* input_ParsePES
*****************************************************************************
#define p_pes (p_es->p_pes)
- //intf_DbgMsg("End of PES packet %p\n", p_pes);
+ //intf_DbgMsg("End of PES packet %p", p_pes);
/* Parse the header. The header has a variable length, but in order
* to improve the algorithm, we will read the 14 bytes we may be
/* PTS management */
if( p_pes->b_has_pts )
{
- //intf_Msg("%lld\n", p_pes->i_pts);
+ //intf_Msg("%lld", p_pes->i_pts);
switch( p_es->p_pgrm->i_synchro_state )
{
case SYNCHRO_NOT_STARTED:
/* Now we can eventually put the PES packet in the decoder's
* PES fifo */
- input_DecodePES( p_input, p_es );
+ if( p_es->p_decoder_fifo != NULL )
+ {
+ input_DecodePES( p_es->p_decoder_fifo, p_pes );
+ }
+ else
+ {
+ intf_ErrMsg("No fifo to receive PES %p (who wrote this damn code ?)",
+ p_pes);
+ p_input->p_plugin->pf_delete_pes( p_input->p_method_data, p_pes );
+ }
+ p_pes = NULL;
}
#undef p_pes
}
{
#define p_pes (p_es->p_pes)
- //intf_DbgMsg("PES-demultiplexing %p (%p)\n", p_ts_packet, p_pes);
+ //intf_DbgMsg("PES-demultiplexing %p (%p)", p_ts_packet, p_pes);
/* If we lost data, insert an NULL data packet (philosophy : 0 is quite
* often an escape sequence in decoders, so that should make them wait
p_input->p_method_data,
PADDING_PACKET_SIZE )) == NULL )
{
- intf_ErrMsg("Out of memory\n");
+ intf_ErrMsg("Out of memory");
p_input->b_error = 1;
return;
}
if( (p_pes = p_input->p_plugin->pf_new_pes(
p_input->p_method_data )) == NULL )
{
- intf_ErrMsg("Out of memory\n");
+ intf_ErrMsg("Out of memory");
p_input->b_error = 1;
return;
}
p_pes->p_first = p_pad_data;
p_pes->b_messed_up = p_pes->b_discontinuity = 1;
- input_DecodePES( p_input, p_es );
+ input_DecodePES( p_es->p_decoder_fifo, p_pes );
}
p_es->b_discontinuity = 0;
p_input->b_error = 1;
return;
}
- //intf_DbgMsg("New PES packet %p (first data: %p)\n", p_pes, p_data);
+ //intf_DbgMsg("New PES packet %p (first data: %p)", p_pes, p_data);
p_pes->p_first = p_data;
/* If the PES header fits in the first data packet, we can
stream_ps_data_t * p_demux =
(stream_ps_data_t *)p_input->stream.p_demux_data;
+ intf_Msg("input info: Your stream contains Program Stream Map information");
+ intf_Msg("input info: Please send a mail to <massiot@via.ecp.fr>");
+
+#if 0
if( !p_demux->b_is_PSM_complete )
{
byte_t * p_byte;
byte_t * p_end;
- int i_es = 0;
intf_DbgMsg( "Building PSM" );
if( p_data->p_payload_start + 10 > p_data->p_payload_end )
/* 4 == minimum useful size of a section */
while( p_byte + 4 <= p_end )
{
-#if 0
- p_input->p_es[i_es].i_id
- = p_input->p_es[i_es].i_stream_id
- = p_byte[1];
- p_input->p_es[i_es].i_type = p_byte[0];
- p_input->p_es[i_es].p_pgrm = p_input->stream.pp_programs[0];
- p_input->p_es[i_es].p_pes = NULL;
- p_byte += 4 + U16_AT(&p_byte[2]);
-
-#ifdef AUTO_SPAWN
- switch( p_input->p_es[i_es].i_type )
- {
- case MPEG1_AUDIO_ES:
- case MPEG2_AUDIO_ES:
- /* Spawn audio thread. */
- intf_DbgMsg( "Starting an MPEG-audio decoder" );
- break;
+ es_descriptor_t * p_es;
- case MPEG1_VIDEO_ES:
- case MPEG2_VIDEO_ES:
- /* Spawn video thread. */
- intf_DbgMsg( "Starting an MPEG-video decoder" );
- break;
- }
-#endif
-
- i_es++;
-#endif
+ p_es = input_AddES( p_input, p_input->stream.pp_programs[0],
+ p_byte[1], 0 );
+ p_es->i_type = p_byte[0];
+ p_byte += 4 + U16_AT(&p_byte[2]);
}
vlc_mutex_unlock( &p_input->stream.stream_lock );
intf_ErrMsg( "PSM changed, this is not supported yet !" );
p_demux->i_PSM_version = p_data->p_buffer[6] & 0x1F;
}
+#endif
}
/*****************************************************************************
if( p_input->stream.pp_programs[0]->b_is_ok )
{
/* Look only at the selected ES. */
- for( i_dummy = 0; i_dummy < p_input->i_selected_es_number;
+ for( i_dummy = 0; i_dummy < p_input->stream.i_selected_es_number;
i_dummy++ )
{
- if( p_input->pp_selected_es[i_dummy] != NULL
- && p_input->pp_selected_es[i_dummy]->i_id == i_id )
+ if( p_input->stream.pp_selected_es[i_dummy] != NULL
+ && p_input->stream.pp_selected_es[i_dummy]->i_id == i_id )
{
- p_es = p_input->pp_selected_es[i_dummy];
+ p_es = p_input->stream.pp_selected_es[i_dummy];
break;
}
}
else
{
/* Search all ES ; if not found -> AddES */
- for( i_dummy = 0; i_dummy < p_input->i_es_number; i_dummy++ )
- {
- if( p_input->pp_es[i_dummy] != NULL
- && p_input->pp_es[i_dummy]->i_id == i_id )
- {
- p_es = p_input->pp_es[i_dummy];
- break;
- }
- }
+ p_es = input_FindES( p_input, i_id );
if( p_es == NULL )
{
) * 300) / 27;
}
/* Call the pace control. */
- //intf_Msg("+%lld\n", scr_time);
+ //intf_Msg("+%lld", scr_time);
CRDecode( p_input, p_input->stream.pp_programs[0],
scr_time );
b_trash = 1;
break;
case 0x1BC: /* PROGRAM_STREAM_MAP_CODE */
- intf_ErrMsg("meuuuuh\n");
DecodePSM( p_input, p_data );
b_trash = 1;
break;
{
p_es = input_ParsePS( p_input, p_data );
- if( p_es != NULL && p_es->p_decoder_fifo != NULL && !b_trash )
+ if( p_es != NULL && p_es->p_decoder_fifo != NULL )
{
#ifdef STATS
p_es->c_packets++;
#endif
input_GatherPES( p_input, p_data, p_es, 1, 0 );
}
+ else
+ {
+ b_trash = 1;
+ }
}
/* Trash the packet if it has no payload or if it isn't selected */
#define p (p_data->p_buffer)
- //intf_DbgMsg("input debug: TS-demultiplexing packet %p, pid %d\n",
+ //intf_DbgMsg("input debug: TS-demultiplexing packet %p, pid %d",
// p_ts_packet, U16_AT(&p[1]) & 0x1fff);
/* Extract flags values from TS common header. */
/* Find out the elementary stream. */
vlc_mutex_lock( &p_input->stream.stream_lock );
- for( i_dummy = 0; i_dummy < p_input->i_es_number; i_dummy++ )
- {
- if( p_input->pp_es[i_dummy] != NULL )
- {
- if( p_input->pp_es[i_dummy]->i_id == i_pid )
- {
- p_es = p_input->pp_es[i_dummy];
- p_es_demux = (es_ts_data_t *)p_es->p_demux_data;
- p_pgrm_demux = (pgrm_ts_data_t *)p_es->p_pgrm->p_demux_data;
- break;
- }
- }
- }
+ p_es = input_FindES( p_input, i_pid );
vlc_mutex_unlock( &p_input->stream.stream_lock );
-#ifdef STATS
- p_es->c_packets++;
-#endif
-
- if( p_es->p_decoder_fifo == NULL )
+ if( p_es == NULL || p_es->p_decoder_fifo == NULL )
{
/* Not selected. Just read the adaptation field for a PCR. */
b_trash = 1;
if( (p_es->p_decoder_fifo != NULL) || (p_pgrm_demux->i_pcr_pid == i_pid) )
{
+#ifdef STATS
+ p_es->c_packets++;
+#endif
+
/* Extract adaptation field information if any */
if( !b_adaptation )
{
* don't know, do as if we missed a packet to be sure to recover
* from this situation */
intf_WarnMsg( 2,
- "Packet lost by TS demux: current %d, packet %d\n",
+ "Packet lost by TS demux: current %d, packet %d",
p_es_demux->i_continuity_counter & 0x0f,
p[3] & 0x0f );
b_lost = 1;