X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=modules%2Fdemux%2Fts.c;h=0f3a13e79d39dffd8eba53818d51076060411721;hb=779340cfa2ce06d7226e037765807edd24942885;hp=aff4e010548815c9f8cb8aa6817c501a4d7b554d;hpb=d09106d2bd9e4ed24f1edc48073e8df66aab5d8d;p=vlc diff --git a/modules/demux/ts.c b/modules/demux/ts.c index aff4e01054..0f3a13e79d 100644 --- a/modules/demux/ts.c +++ b/modules/demux/ts.c @@ -2,7 +2,7 @@ * 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 * @@ -60,8 +60,8 @@ /***************************************************************************** * 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" ) ); @@ -235,6 +235,8 @@ static inline int PIDGet( block_t *p ) 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 * ); @@ -528,10 +530,10 @@ static void Close( vlc_object_t *p_this ) csa_Delete( p_sys->csa ); } + if( p_sys->i_pmt ) free( p_sys->pmt ); free( p_sys ); } - /***************************************************************************** * Demux: *****************************************************************************/ @@ -625,6 +627,8 @@ static int Demux( demux_t *p_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; @@ -934,6 +938,37 @@ static void ParsePES ( demux_t *p_demux, ts_pid_t *pid ) } } +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; @@ -1009,20 +1044,7 @@ static vlc_bool_t GatherPES( demux_t *p_demux, ts_pid_t *pid, block_t *p_bk ) } } - 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 ) { @@ -1126,6 +1148,9 @@ static int PIDFillFormat( ts_pid_t *pid, int i_stream_type ) break; } + /* PES packets usually contain truncated frames */ + fmt->b_packetized = VLC_FALSE; + return fmt->i_cat == UNKNOWN_ES ? VLC_EGENERIC : VLC_SUCCESS ; } @@ -1545,10 +1570,14 @@ static void PMTCallBack( demux_t *p_demux, dvbpsi_pmt_t *p_pmt ) 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 ) @@ -1673,6 +1702,9 @@ static void PMTCallBack( demux_t *p_demux, dvbpsi_pmt_t *p_pmt ) 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; @@ -1761,13 +1793,15 @@ static void PATCallBack( demux_t *p_demux, dvbpsi_pat_t *p_pat ) 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++ ) @@ -1784,7 +1818,8 @@ static void PATCallBack( demux_t *p_demux, dvbpsi_pat_t *p_pat ) 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 ); @@ -1793,15 +1828,19 @@ static void PATCallBack( demux_t *p_demux, dvbpsi_pat_t *p_pat ) } /* 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 ); @@ -1811,4 +1850,3 @@ static void PATCallBack( demux_t *p_demux, dvbpsi_pat_t *p_pat ) dvbpsi_DeletePAT( p_pat ); } -