[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