vlc | branch: master | Francois Cartegnie <[email protected]> | 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 ); _______________________________________________ vlc-commits mailing list [email protected] https://mailman.videolan.org/listinfo/vlc-commits
