* ts.c: Transport Stream input module for VLC.
*****************************************************************************
* Copyright (C) 2004 VideoLAN
- * $Id: ts.c,v 1.11 2004/02/14 01:53:17 gbazin Exp $
+ * $Id$
*
* Authors: Laurent Aimar <fenrir@via.ecp.fr>
*
/*****************************************************************************
* Module descriptor
*****************************************************************************/
-static int Open ( vlc_object_t * );
-static void Close ( vlc_object_t * );
+static int Open ( vlc_object_t * );
+static void Close ( vlc_object_t * );
vlc_module_begin();
set_description( _("ISO 13818-1 MPEG Transport Stream input - new" ) );
static vlc_bool_t GatherPES( demux_t *p_demux, ts_pid_t *pid, block_t *p_bk );
+static void PCRHandle( demux_t *p_demux, ts_pid_t *, block_t * );
+
static iod_descriptor_t *IODNew( int , uint8_t * );
static void IODFree( iod_descriptor_t * );
csa_Delete( p_sys->csa );
}
+ if( p_sys->i_pmt ) free( p_sys->pmt );
free( p_sys );
}
-
/*****************************************************************************
* Demux:
*****************************************************************************/
{
msg_Dbg( p_demux, "pid[0x%x] unknown", p_pid->i_pid );
}
+ /* We have to handle PCR if present */
+ PCRHandle( p_demux, p_pid, p_pkt );
block_Release( p_pkt );
}
p_pid->b_seen = VLC_TRUE;
}
}
+static void PCRHandle( demux_t *p_demux, ts_pid_t *pid, block_t *p_bk )
+{
+ demux_sys_t *p_sys = p_demux->p_sys;
+ const uint8_t *p = p_bk->p_buffer;
+
+ if( ( p[3]&0x20 ) && /* adaptation */
+ ( p[5]&0x10 ) &&
+ ( p[4] >= 7 ) )
+ {
+ int i;
+ mtime_t i_pcr; /* 33 bits */
+
+ i_pcr = ( (mtime_t)p[6] << 25 ) |
+ ( (mtime_t)p[7] << 17 ) |
+ ( (mtime_t)p[8] << 9 ) |
+ ( (mtime_t)p[9] << 1 ) |
+ ( (mtime_t)p[10] >> 7 );
+
+ /* Search program and set the PCR */
+ for( i = 0; i < p_sys->i_pmt; i++ )
+ {
+ if( pid->i_pid == p_sys->pmt[i]->psi->i_pid_pcr )
+ {
+ es_out_Control( p_demux->out, ES_OUT_SET_GROUP_PCR,
+ (int)p_sys->pmt[i]->psi->i_number,
+ (int64_t)(i_pcr * 100 / 9) );
+ }
+ }
+ }
+}
+
static vlc_bool_t GatherPES( demux_t *p_demux, ts_pid_t *pid, block_t *p_bk )
{
const uint8_t *p = p_bk->p_buffer;
}
}
- if( b_adaptation &&
- (p[5] & 0x10) && p[4]>=7 && pid->p_owner && pid->p_owner->i_pid_pcr == pid->i_pid )
- {
- mtime_t i_pcr; /* 33 bits */
-
- i_pcr = ( (mtime_t)p[6] << 25 ) |
- ( (mtime_t)p[7] << 17 ) |
- ( (mtime_t)p[8] << 9 ) |
- ( (mtime_t)p[9] << 1 ) |
- ( (mtime_t)p[10] >> 7 );
-
- es_out_Control( p_demux->out, ES_OUT_SET_GROUP_PCR, (int)pid->p_owner->i_number, (int64_t)(i_pcr * 100 / 9) );
- }
-
+ PCRHandle( p_demux, pid, p_bk );
if( i_skip >= 188 || pid->es->id == NULL || p_demux->p_sys->b_udp_out )
{
break;
}
+ /* PES packets usually contain truncated frames */
+ fmt->b_packetized = VLC_FALSE;
+
return fmt->i_cat == UNKNOWN_ES ? VLC_EGENERIC : VLC_SUCCESS ;
}
if( p_dr->i_tag == 0x1d )
{
/* We have found an IOD descriptor */
- msg_Warn( p_demux, "found IOD descriptor" );
+ msg_Warn( p_demux, " * descriptor : IOD (0x1d)" );
pmt->psi->iod = IODNew( p_dr->i_length, p_dr->p_data );
}
+ else
+ {
+ msg_Dbg( p_demux, " * descriptor : unknown (0x%x)", p_dr->i_tag );
+ }
}
for( p_es = p_pmt->p_first_es; p_es != NULL; p_es = p_es->p_next )
for( p_dr = p_es->p_first_descriptor; p_dr != NULL; p_dr = p_dr->p_next )
{
+ msg_Dbg( p_demux, " * es pid=0x%x type=0x%x dr->i_tag=0x%x",
+ p_es->i_pid, p_es->i_type, p_dr->i_tag );
+
if( p_dr->i_tag == 0x6a )
{
pid->es->fmt.i_cat = AUDIO_ES;
msg_Dbg( p_demux, "PATCallBack called" );
- if( pat->psi->i_version != -1 && ( !p_pat->b_current_next || p_pat->i_version == pat->psi->i_version ) )
+ if( pat->psi->i_version != -1 &&
+ ( !p_pat->b_current_next || p_pat->i_version == pat->psi->i_version ) )
{
dvbpsi_DeletePAT( p_pat );
return;
}
- msg_Dbg( p_demux, "new PAT ts_id=0x%x version=%d current_next=%d", p_pat->i_ts_id, p_pat->i_version, p_pat->b_current_next );
+ msg_Dbg( p_demux, "new PAT ts_id=0x%x version=%d current_next=%d",
+ p_pat->i_ts_id, p_pat->i_version, p_pat->b_current_next );
/* Clean old */
for( i = 2; i < 8192; i++ )
TAB_REMOVE( p_sys->i_pmt, p_sys->pmt, pid );
}
}
- else if( pid->p_owner && pid->p_owner->i_number != 0 && pid->es->id )
+ else if( pid->p_owner && pid->p_owner->i_number != 0 &&
+ pid->es->id )
{
/* We only remove es that aren't defined by extra pmt */
PIDClean( p_demux->out, pid );
}
/* now create programs */
- for( p_program = p_pat->p_first_program; p_program != NULL; p_program = p_program->p_next )
+ for( p_program = p_pat->p_first_program; p_program != NULL;
+ p_program = p_program->p_next )
{
- msg_Dbg( p_demux, " * number=%d pid=0x%x", p_program->i_number, p_program->i_pid );
+ msg_Dbg( p_demux, " * number=%d pid=0x%x", p_program->i_number,
+ p_program->i_pid );
if( p_program->i_number != 0 )
{
ts_pid_t *pmt = &p_sys->pid[p_program->i_pid];
PIDInit( pmt, VLC_TRUE, pat->psi );
- pmt->psi->handle = dvbpsi_AttachPMT( p_program->i_number, (dvbpsi_pmt_callback)PMTCallBack, p_demux );
+ pmt->psi->handle =
+ dvbpsi_AttachPMT( p_program->i_number,
+ (dvbpsi_pmt_callback)PMTCallBack, p_demux );
pmt->psi->i_number = p_program->i_number;
TAB_APPEND( p_sys->i_pmt, p_sys->pmt, pmt );
dvbpsi_DeletePAT( p_pat );
}
-