[vlc-commits] demux: ts: improve probing on missing PAT
Francois Cartegnie
git at videolan.org
Tue Oct 13 20:14:53 CEST 2020
vlc | branch: master | Francois Cartegnie <fcvlcdev at free.fr> | Tue Oct 13 15:45:59 2020 +0200| [f4a70e56652da0766d76d468f0d18ca11b4bbd0c] | committer: Francois Cartegnie
demux: ts: improve probing on missing PAT
> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=f4a70e56652da0766d76d468f0d18ca11b4bbd0c
---
modules/demux/mpeg/ts.c | 4 ++--
modules/demux/mpeg/ts.h | 1 +
modules/demux/mpeg/ts_hotfixes.c | 32 +++++++++++++++++++++++++++++---
modules/demux/mpeg/ts_pid.h | 3 ++-
modules/demux/mpeg/ts_psi.c | 2 ++
5 files changed, 36 insertions(+), 6 deletions(-)
diff --git a/modules/demux/mpeg/ts.c b/modules/demux/mpeg/ts.c
index 9e976bd046..eb521ec19b 100644
--- a/modules/demux/mpeg/ts.c
+++ b/modules/demux/mpeg/ts.c
@@ -408,6 +408,7 @@ static int Open( vlc_object_t *p_this )
p_sys->patfix.i_first_dts = -1;
p_sys->patfix.i_timesourcepid = 0;
+ p_sys->patfix.b_pcrhasnopcrfield = false;
p_sys->patfix.status = var_CreateGetBool( p_demux, "ts-patfix" ) ? PAT_WAITING : PAT_FIXTRIED;
/* Init PAT handler */
@@ -691,7 +692,6 @@ static int Demux( demux_t *p_demux )
/* Probe streams to build PAT/PMT after MIN_PAT_INTERVAL in case we don't see any PAT */
if( !SEEN( GetPID( p_sys, 0 ) ) &&
- (p_pid->probed.i_fourcc == 0 || p_pid->i_pid == p_sys->patfix.i_timesourcepid) &&
(p_pkt->p_buffer[1] & 0xC0) == 0x40 && /* Payload start but not corrupt */
(p_pkt->p_buffer[3] & 0xD0) == 0x10 ) /* Has payload but is not encrypted */
{
@@ -2461,7 +2461,7 @@ static void PCRFixHandle( demux_t *p_demux, ts_pmt_t *p_pmt, block_t *p_block )
{
int i_cand = FindPCRCandidate( p_pmt );
p_pmt->i_pid_pcr = i_cand;
- if ( GetPID( p_sys, p_pmt->i_pid_pcr )->probed.i_pcr_count == 0 )
+ if ( GetPID( p_sys, p_pmt->i_pid_pcr )->probed.i_pcr_count == 0 ) /* does not have PCR field */
p_pmt->pcr.b_disable = true;
msg_Warn( p_demux, "No PCR received for program %d, set up workaround using pid %d",
p_pmt->i_number, i_cand );
diff --git a/modules/demux/mpeg/ts.h b/modules/demux/mpeg/ts.h
index 1d869181ff..45d2730b01 100644
--- a/modules/demux/mpeg/ts.h
+++ b/modules/demux/mpeg/ts.h
@@ -131,6 +131,7 @@ struct demux_sys_t
{
stime_t i_first_dts; /* first dts encountered for the stream */
int i_timesourcepid; /* which pid we saved the dts from */
+ bool b_pcrhasnopcrfield;
enum { PAT_WAITING = 0, PAT_MISSING, PAT_FIXTRIED } status; /* set if we haven't seen PAT within MIN_PAT_INTERVAL */
} patfix;
diff --git a/modules/demux/mpeg/ts_hotfixes.c b/modules/demux/mpeg/ts_hotfixes.c
index 4a79b40d75..1af301c801 100644
--- a/modules/demux/mpeg/ts_hotfixes.c
+++ b/modules/demux/mpeg/ts_hotfixes.c
@@ -89,6 +89,7 @@ void ProbePES( demux_t *p_demux, ts_pid_t *pid, const uint8_t *p_pesstart, size_
if ( i_data < i_pesextoffset ||
!ExtractPESTimestamp( &p_pes[9], p_pes[7] >> 6, &i_dts ) )
return;
+ pid->probed.i_dts_count++;
}
if( p_pes[7] & 0x40 ) // DTS
{
@@ -108,6 +109,9 @@ void ProbePES( demux_t *p_demux, ts_pid_t *pid, const uint8_t *p_pesstart, size_
if( p_pes[7] & 0x02 ) // PESCRC
i_pesextoffset += 2;
+ if( pid->probed.i_fourcc != 0 )
+ goto codecprobingend;
+
if ( i_data < i_pesextoffset )
return;
@@ -191,6 +195,7 @@ void ProbePES( demux_t *p_demux, ts_pid_t *pid, const uint8_t *p_pesstart, size_
}
}
+codecprobingend:
/* Track timestamps and flag missing PAT */
if( !p_sys->patfix.i_timesourcepid && i_dts > -1 )
{
@@ -247,6 +252,7 @@ void MissingPATPMTFixup( demux_t *p_demux )
}
}
+ const ts_pid_t * candidates[4] = { NULL };
const ts_pid_t *p_pid = NULL;
ts_pid_next_context_t pidnextctx = ts_pid_NextContextInitValue;
while( (p_pid = ts_pid_Next( &p_sys->pids, &pidnextctx )) )
@@ -254,13 +260,33 @@ void MissingPATPMTFixup( demux_t *p_demux )
if( !SEEN(p_pid) || p_pid->probed.i_fourcc == 0 )
continue;
- if( i_pcr_pid == 0x1FFF && ( p_pid->probed.i_cat == AUDIO_ES ||
- p_pid->probed.i_pcr_count ) )
- i_pcr_pid = p_pid->i_pid;
+ if( p_pid->probed.i_pcr_count && candidates[0] == NULL && false )
+ candidates[0] = p_pid;
+
+ if( p_pid->probed.i_cat == AUDIO_ES &&
+ (candidates[1] == NULL ||
+ candidates[1]->probed.i_dts_count > p_pid->probed.i_dts_count) )
+ candidates[1] = p_pid;
+
+ if( candidates[2] == NULL && p_pid != candidates[1] &&
+ p_pid->probed.i_dts_count > 0 )
+ candidates[2] = p_pid;
+
+ if( candidates[3] == NULL )
+ candidates[3] = p_pid;
i_num_pes++;
}
+ for(int i=0; i<4; i++)
+ {
+ if(!candidates[i])
+ continue;
+ i_pcr_pid = candidates[i]->i_pid;
+ p_sys->patfix.b_pcrhasnopcrfield = (candidates[i]->probed.i_pcr_count < 1);
+ break;
+ }
+
if( i_num_pes == 0 )
return;
diff --git a/modules/demux/mpeg/ts_pid.h b/modules/demux/mpeg/ts_pid.h
index cf2c2a9c9d..8fea481805 100644
--- a/modules/demux/mpeg/ts_pid.h
+++ b/modules/demux/mpeg/ts_pid.h
@@ -78,7 +78,8 @@ struct ts_pid_t
vlc_fourcc_t i_fourcc;
vlc_fourcc_t i_original_fourcc;
int i_cat;
- int i_pcr_count;
+ int i_dts_count;
+ int i_pcr_count; /* carries PCR field */
uint8_t i_stream_id;
} probed;
diff --git a/modules/demux/mpeg/ts_psi.c b/modules/demux/mpeg/ts_psi.c
index 9aa73b9935..fbf6fb19c0 100644
--- a/modules/demux/mpeg/ts_psi.c
+++ b/modules/demux/mpeg/ts_psi.c
@@ -184,6 +184,8 @@ static void PATCallBack( void *data, dvbpsi_pat_t *p_dvbpsipat )
}
pmtpid->u.p_pmt->i_number = p_program->i_number;
+ if( p_pat->b_generated )
+ pmtpid->u.p_pmt->pcr.b_disable = p_sys->patfix.b_pcrhasnopcrfield;
ARRAY_APPEND( p_pat->programs, pmtpid );
More information about the vlc-commits
mailing list