Commit c557ef6c authored by Laurent Aimar's avatar Laurent Aimar

Split PMTCallback to make it (a bit) more readable.

parent 54d6f042
......@@ -780,10 +780,8 @@ static void Close( vlc_object_t *p_this )
demux_t *p_demux = (demux_t*)p_this;
demux_sys_t *p_sys = p_demux->p_sys;
int i;
msg_Dbg( p_demux, "pid list:" );
for( i = 0; i < 8192; i++ )
for( int i = 0; i < 8192; i++ )
{
ts_pid_t *pid = &p_sys->pid[i];
......@@ -3019,167 +3017,16 @@ static void PSINewTableCallBack( demux_t *p_demux, dvbpsi_handle h,
}
#endif
static void PMTCallBack( demux_t *p_demux, dvbpsi_pmt_t *p_pmt )
/*****************************************************************************
* PMT callback and helpers
*****************************************************************************/
static void PMTSetupEsISO14496( demux_t *p_demux, ts_pid_t *pid,
const ts_prg_psi_t *prg, const dvbpsi_pmt_es_t *p_es )
{
demux_sys_t *p_sys = p_demux->p_sys;
dvbpsi_descriptor_t *p_dr;
dvbpsi_pmt_es_t *p_es;
ts_pid_t *pmt = NULL;
ts_prg_psi_t *prg = NULL;
ts_pid_t **pp_clean = NULL;
int i_clean = 0;
bool b_hdmv = false;
msg_Dbg( p_demux, "PMTCallBack called" );
/* First find this PMT declared in PAT */
for( int i = 0; i < p_sys->i_pmt; i++ )
{
int i_prg;
for( i_prg = 0; i_prg < p_sys->pmt[i]->psi->i_prg; i_prg++ )
{
const int i_pmt_number = p_sys->pmt[i]->psi->prg[i_prg]->i_number;
if( i_pmt_number != TS_USER_PMT_NUMBER && i_pmt_number == p_pmt->i_program_number )
{
pmt = p_sys->pmt[i];
prg = p_sys->pmt[i]->psi->prg[i_prg];
break;
}
}
if( pmt )
break;
}
if( pmt == NULL )
{
msg_Warn( p_demux, "unreferenced program (broken stream)" );
dvbpsi_DeletePMT(p_pmt);
return;
}
if( prg->i_version != -1 &&
( !p_pmt->b_current_next || prg->i_version == p_pmt->i_version ) )
{
dvbpsi_DeletePMT( p_pmt );
return;
}
/* Clean this program (remove all es) */
for( int i = 0; i < 8192; i++ )
{
ts_pid_t *pid = &p_sys->pid[i];
if( pid->b_valid && pid->p_owner == pmt->psi &&
pid->i_owner_number == prg->i_number && pid->psi == NULL )
{
TAB_APPEND( i_clean, pp_clean, pid );
}
}
if( prg->iod )
{
IODFree( prg->iod );
prg->iod = NULL;
}
msg_Dbg( p_demux, "new PMT program number=%d version=%d pid_pcr=%d",
p_pmt->i_program_number, p_pmt->i_version, p_pmt->i_pcr_pid );
prg->i_pid_pcr = p_pmt->i_pcr_pid;
prg->i_version = p_pmt->i_version;
ValidateDVBMeta( p_demux, prg->i_pid_pcr );
if( ProgramIsSelected( p_demux, prg->i_number ) )
{
/* Set demux filter */
stream_Control( p_demux->s, STREAM_CONTROL_ACCESS,
ACCESS_SET_PRIVATE_ID_STATE, prg->i_pid_pcr,
true );
}
else if ( p_sys->b_access_control )
{
msg_Warn( p_demux, "skipping program (not selected)" );
dvbpsi_DeletePMT(p_pmt);
return;
}
/* Parse descriptor */
for( p_dr = p_pmt->p_first_descriptor; p_dr != NULL; p_dr = p_dr->p_next )
{
if( p_dr->i_tag == 0x1d )
{
/* We have found an IOD descriptor */
msg_Dbg( p_demux, " * descriptor : IOD (0x1d)" );
prg->iod = IODNew( p_dr->i_length, p_dr->p_data );
}
else if( p_dr->i_tag == 0x9 )
{
uint16_t i_sysid = ((uint16_t)p_dr->p_data[0] << 8)
| p_dr->p_data[1];
msg_Dbg( p_demux, " * descriptor : CA (0x9) SysID 0x%x", i_sysid );
}
else if( p_dr->i_tag == 0x05 )
{
if( p_dr->i_tag == 0x05 )
{
/* Registration Descriptor */
if( p_dr->i_length != 4 )
{
msg_Warn( p_demux, "invalid Registration Descriptor" );
}
else
{
msg_Dbg( p_demux, " * descriptor : registration %4.4s", p_dr->p_data );
if( !memcmp( p_dr->p_data, "HDMV", 4 ) )
{
/* Blu-Ray */
b_hdmv = true;
}
}
}
}
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 )
{
ts_pid_t tmp_pid, *old_pid = 0, *pid = &tmp_pid;
/* Find out if the PID was already declared */
for( int i = 0; i < i_clean; i++ )
{
if( pp_clean[i] == &p_sys->pid[p_es->i_pid] )
{
old_pid = pp_clean[i];
break;
}
}
ValidateDVBMeta( p_demux, p_es->i_pid );
if( !old_pid && p_sys->pid[p_es->i_pid].b_valid )
{
msg_Warn( p_demux, "pmt error: pid=%d already defined",
p_es->i_pid );
continue;
}
PIDInit( pid, false, pmt->psi );
PIDFillFormat( pid, p_es->i_type );
pid->i_owner_number = prg->i_number;
pid->i_pid = p_es->i_pid;
pid->b_seen = p_sys->pid[p_es->i_pid].b_seen;
if( p_es->i_type == 0x10 || p_es->i_type == 0x11 ||
p_es->i_type == 0x12 || p_es->i_type == 0x0f )
{
/* MPEG-4 stream: search SL_DESCRIPTOR */
dvbpsi_descriptor_t *p_dr = p_es->p_first_descriptor;;
while( p_dr && ( p_dr->i_tag != 0x1f ) ) p_dr = p_dr->p_next;
while( p_dr && ( p_dr->i_tag != 0x1f ) )
p_dr = p_dr->p_next;
if( p_dr && p_dr->i_length == 2 )
{
......@@ -3284,9 +3131,11 @@ static void PMTCallBack( demux_t *p_demux, dvbpsi_pmt_t *p_pmt )
}
}
}
}
else if( p_es->i_type == 0x06 )
{
}
static void PMTSetupEs0x06( demux_t *p_demux, ts_pid_t *pid,
const dvbpsi_pmt_es_t *p_es )
{
dvbpsi_descriptor_t *p_dr;
for( p_dr = p_es->p_first_descriptor; p_dr != NULL;
......@@ -3392,7 +3241,6 @@ static void PMTCallBack( demux_t *p_demux, dvbpsi_pmt_t *p_pmt )
#if defined _DVBPSI_DR_56_H_ && defined DVBPSI_VERSION \
&& DVBPSI_VERSION_INT > ((0<<16)+(1<<8)+5)
pid->es->fmt.i_group = p_pmt->i_program_number;
/* In stream output mode, only enable descriptor
* pass-through. */
......@@ -3488,7 +3336,6 @@ static void PMTCallBack( demux_t *p_demux, dvbpsi_pmt_t *p_pmt )
p_dr->i_length );
#ifdef _DVBPSI_DR_59_H_
pid->es->fmt.i_group = p_pmt->i_program_number;
/* In stream output mode, only enable descriptor
* pass-through. */
......@@ -3576,9 +3423,11 @@ static void PMTCallBack( demux_t *p_demux, dvbpsi_pmt_t *p_pmt )
}
}
}
}
else if( p_es->i_type == 0xEA )
{
}
static void PMTSetupEs0xEA( demux_t *p_demux, ts_pid_t *pid,
const dvbpsi_pmt_es_t *p_es )
{
dvbpsi_descriptor_t *p_dr;
for( p_dr = p_es->p_first_descriptor; p_dr != NULL;
......@@ -3616,9 +3465,11 @@ static void PMTCallBack( demux_t *p_demux, dvbpsi_pmt_t *p_pmt )
}
}
}
}
else if( p_es->i_type == 0xd1 )
{
}
static void PMTSetupEs0xD1( demux_t *p_demux, ts_pid_t *pid,
const dvbpsi_pmt_es_t *p_es )
{
dvbpsi_descriptor_t *p_dr;
for( p_dr = p_es->p_first_descriptor; p_dr != NULL;
......@@ -3645,13 +3496,16 @@ static void PMTCallBack( demux_t *p_demux, dvbpsi_pmt_t *p_pmt )
}
}
}
}
else if( p_es->i_type == 0xa0 )
{
}
static void PMTSetupEs0xA0( demux_t *p_demux, ts_pid_t *pid,
const dvbpsi_pmt_es_t *p_es )
{
/* MSCODEC sent by vlc */
dvbpsi_descriptor_t *p_dr = p_es->p_first_descriptor;
while( p_dr && ( p_dr->i_tag != 0xa0 ) ) p_dr = p_dr->p_next;
while( p_dr && ( p_dr->i_tag != 0xa0 ) )
p_dr = p_dr->p_next;
if( p_dr && p_dr->i_length >= 8 )
{
......@@ -3683,9 +3537,11 @@ static void PMTCallBack( demux_t *p_demux, dvbpsi_pmt_t *p_pmt )
* packetizer.
* Yes it's ugly but it's the only way to have DIV3 working */
pid->es->fmt.b_packetized = true;
}
else if( b_hdmv )
{
}
static void PMTSetupEsHDMV( demux_t *p_demux, ts_pid_t *pid,
const dvbpsi_pmt_es_t *p_es )
{
/* Blu-Ray mapping */
switch( p_es->i_type )
{
......@@ -3718,16 +3574,14 @@ static void PMTCallBack( demux_t *p_demux, dvbpsi_pmt_t *p_pmt )
default:
break;
}
}
if( pid->es->fmt.i_cat == AUDIO_ES ||
( pid->es->fmt.i_cat == SPU_ES &&
pid->es->fmt.i_codec != VLC_FOURCC('d','v','b','s') &&
pid->es->fmt.i_codec != VLC_FOURCC('t','e','l','x') ) )
{
}
static void PMTParseEsIso639( demux_t *p_demux, ts_pid_t *pid,
const dvbpsi_pmt_es_t *p_es )
{
/* get language descriptor */
dvbpsi_descriptor_t *p_dr = p_es->p_first_descriptor;
while( p_dr && ( p_dr->i_tag != 0x0a ) ) p_dr = p_dr->p_next;
while( p_dr && ( p_dr->i_tag != 0x0a ) )
p_dr = p_dr->p_next;
if( p_dr )
{
......@@ -3823,9 +3677,200 @@ static void PMTCallBack( demux_t *p_demux, dvbpsi_pmt_t *p_pmt )
#endif
}
}
}
static void PMTCallBack( demux_t *p_demux, dvbpsi_pmt_t *p_pmt )
{
demux_sys_t *p_sys = p_demux->p_sys;
dvbpsi_descriptor_t *p_dr;
dvbpsi_pmt_es_t *p_es;
ts_pid_t *pmt = NULL;
ts_prg_psi_t *prg = NULL;
ts_pid_t **pp_clean = NULL;
int i_clean = 0;
bool b_hdmv = false;
msg_Dbg( p_demux, "PMTCallBack called" );
/* First find this PMT declared in PAT */
for( int i = 0; i < p_sys->i_pmt; i++ )
{
int i_prg;
for( i_prg = 0; i_prg < p_sys->pmt[i]->psi->i_prg; i_prg++ )
{
const int i_pmt_number = p_sys->pmt[i]->psi->prg[i_prg]->i_number;
if( i_pmt_number != TS_USER_PMT_NUMBER && i_pmt_number == p_pmt->i_program_number )
{
pmt = p_sys->pmt[i];
prg = p_sys->pmt[i]->psi->prg[i_prg];
break;
}
}
if( pmt )
break;
}
if( pmt == NULL )
{
msg_Warn( p_demux, "unreferenced program (broken stream)" );
dvbpsi_DeletePMT(p_pmt);
return;
}
if( prg->i_version != -1 &&
( !p_pmt->b_current_next || prg->i_version == p_pmt->i_version ) )
{
dvbpsi_DeletePMT( p_pmt );
return;
}
/* Clean this program (remove all es) */
for( int i = 0; i < 8192; i++ )
{
ts_pid_t *pid = &p_sys->pid[i];
if( pid->b_valid && pid->p_owner == pmt->psi &&
pid->i_owner_number == prg->i_number && pid->psi == NULL )
{
TAB_APPEND( i_clean, pp_clean, pid );
}
}
if( prg->iod )
{
IODFree( prg->iod );
prg->iod = NULL;
}
msg_Dbg( p_demux, "new PMT program number=%d version=%d pid_pcr=%d",
p_pmt->i_program_number, p_pmt->i_version, p_pmt->i_pcr_pid );
prg->i_pid_pcr = p_pmt->i_pcr_pid;
prg->i_version = p_pmt->i_version;
ValidateDVBMeta( p_demux, prg->i_pid_pcr );
if( ProgramIsSelected( p_demux, prg->i_number ) )
{
/* Set demux filter */
stream_Control( p_demux->s, STREAM_CONTROL_ACCESS,
ACCESS_SET_PRIVATE_ID_STATE, prg->i_pid_pcr,
true );
}
else if ( p_sys->b_access_control )
{
msg_Warn( p_demux, "skipping program (not selected)" );
dvbpsi_DeletePMT(p_pmt);
return;
}
/* Parse descriptor */
for( p_dr = p_pmt->p_first_descriptor; p_dr != NULL; p_dr = p_dr->p_next )
{
if( p_dr->i_tag == 0x1d )
{
/* We have found an IOD descriptor */
msg_Dbg( p_demux, " * descriptor : IOD (0x1d)" );
prg->iod = IODNew( p_dr->i_length, p_dr->p_data );
}
else if( p_dr->i_tag == 0x9 )
{
uint16_t i_sysid = ((uint16_t)p_dr->p_data[0] << 8)
| p_dr->p_data[1];
msg_Dbg( p_demux, " * descriptor : CA (0x9) SysID 0x%x", i_sysid );
}
else if( p_dr->i_tag == 0x05 )
{
if( p_dr->i_tag == 0x05 )
{
/* Registration Descriptor */
if( p_dr->i_length != 4 )
{
msg_Warn( p_demux, "invalid Registration Descriptor" );
}
else
{
msg_Dbg( p_demux, " * descriptor : registration %4.4s", p_dr->p_data );
if( !memcmp( p_dr->p_data, "HDMV", 4 ) )
{
/* Blu-Ray */
b_hdmv = true;
}
}
}
}
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 )
{
ts_pid_t tmp_pid, *old_pid = 0, *pid = &tmp_pid;
/* Find out if the PID was already declared */
for( int i = 0; i < i_clean; i++ )
{
if( pp_clean[i] == &p_sys->pid[p_es->i_pid] )
{
old_pid = pp_clean[i];
break;
}
}
ValidateDVBMeta( p_demux, p_es->i_pid );
if( !old_pid && p_sys->pid[p_es->i_pid].b_valid )
{
msg_Warn( p_demux, "pmt error: pid=%d already defined",
p_es->i_pid );
continue;
}
PIDInit( pid, false, pmt->psi );
PIDFillFormat( pid, p_es->i_type );
pid->i_owner_number = prg->i_number;
pid->i_pid = p_es->i_pid;
pid->b_seen = p_sys->pid[p_es->i_pid].b_seen;
if( p_es->i_type == 0x10 || p_es->i_type == 0x11 ||
p_es->i_type == 0x12 || p_es->i_type == 0x0f )
{
PMTSetupEsISO14496( p_demux, pid, prg, p_es );
}
else if( p_es->i_type == 0x06 )
{
PMTSetupEs0x06( p_demux, pid, p_es );
}
else if( p_es->i_type == 0xEA )
{
PMTSetupEs0xEA( p_demux, pid, p_es );
}
else if( p_es->i_type == 0xd1 )
{
PMTSetupEs0xD1( p_demux, pid, p_es );
}
else if( p_es->i_type == 0xa0 )
{
PMTSetupEs0xA0( p_demux, pid, p_es );
}
else if( b_hdmv )
{
PMTSetupEsHDMV( p_demux, pid, p_es );
}
if( pid->es->fmt.i_cat == AUDIO_ES ||
( pid->es->fmt.i_cat == SPU_ES &&
pid->es->fmt.i_codec != VLC_FOURCC('d','v','b','s') &&
pid->es->fmt.i_codec != VLC_FOURCC('t','e','l','x') ) )
{
PMTParseEsIso639( p_demux, pid, p_es );
}
pid->es->fmt.i_group = p_pmt->i_program_number;
for( int i = 0; i < pid->i_extra_es; i++ )
pid->extra_es[i]->fmt.i_group = p_pmt->i_program_number;
if( pid->es->fmt.i_cat == UNKNOWN_ES )
{
msg_Dbg( p_demux, " * es pid=%d type=%d *unknown*",
......
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