[vlc-commits] Used last PCR/SCR as fallback PTS for Teletext in TS/PS demuxers.

Laurent Aimar git at videolan.org
Tue Jan 17 23:40:44 CET 2012


vlc | branch: master | Laurent Aimar <fenrir at videolan.org> | Tue Jan 17 23:18:50 2012 +0100| [9e3937721d5e106e70078d15fad456d95f182c52] | committer: Laurent Aimar

Used last PCR/SCR as fallback PTS for Teletext in TS/PS demuxers.

> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=9e3937721d5e106e70078d15fad456d95f182c52
---

 modules/demux/ps.c |   13 +++++++++++++
 modules/demux/ts.c |   21 +++++++++++++++++++++
 2 files changed, 34 insertions(+), 0 deletions(-)

diff --git a/modules/demux/ps.c b/modules/demux/ps.c
index 54cdcb4..e363f15 100644
--- a/modules/demux/ps.c
+++ b/modules/demux/ps.c
@@ -82,6 +82,7 @@ struct demux_sys_t
     ps_track_t  tk[PS_TK_COUNT];
 
     int64_t     i_scr;
+    int64_t     i_last_scr;
     int         i_mux_rate;
     int64_t     i_length;
     int         i_time_track;
@@ -134,6 +135,7 @@ static int OpenCommon( vlc_object_t *p_this, bool b_force )
     /* Init p_sys */
     p_sys->i_mux_rate = 0;
     p_sys->i_scr      = -1;
+    p_sys->i_last_scr = -1;
     p_sys->i_length   = -1;
     p_sys->i_current_pts = (mtime_t) 0;
     p_sys->i_time_track = -1;
@@ -322,6 +324,7 @@ static int Demux( demux_t *p_demux )
     case 0x1ba:
         if( !ps_pkt_parse_pack( p_pkt, &p_sys->i_scr, &i_mux_rate ) )
         {
+            p_sys->i_last_scr = p_sys->i_scr;
             if( !p_sys->b_have_pack ) p_sys->b_have_pack = true;
             /* done later on to work around bad vcd/svcd streams */
             /* es_out_Control( p_demux->out, ES_OUT_SET_PCR, p_sys->i_scr ); */
@@ -395,6 +398,7 @@ static int Demux( demux_t *p_demux )
                   tk->fmt.i_codec == VLC_CODEC_CVD ) )
             {
                 p_sys->i_scr = -1;
+                p_sys->i_last_scr = -1;
             }
 
             if( p_sys->i_scr >= 0 )
@@ -413,6 +417,13 @@ static int Demux( demux_t *p_demux )
                     msg_Dbg( p_demux, "force SCR: %"PRId64, p_pkt->i_pts );
                     es_out_Control( p_demux->out, ES_OUT_SET_PCR, p_pkt->i_pts );
                 }
+                if( tk->fmt.i_codec == VLC_CODEC_TELETEXT &&
+                    p_pkt->i_pts <= VLC_TS_INVALID && p_sys->i_last_scr >= 0 )
+                {
+                    /* Teletext may have missing PTS (ETSI EN 300 472 Annexe A)
+                     * In this case use the last SCR + 40ms */
+                    p_pkt->i_pts = VLC_TS_0 + p_sys->i_last_scr + 40000;
+                }
 
                 if( (int64_t)p_pkt->i_pts > p_sys->i_current_pts )
                 {
@@ -465,6 +476,7 @@ static int Control( demux_t *p_demux, int i_query, va_list args )
             f = (double) va_arg( args, double );
             i64 = stream_Size( p_demux->s );
             p_sys->i_current_pts = 0;
+            p_sys->i_last_scr = -1;
 
             return stream_Seek( p_demux->s, (int64_t)(i64 * f) );
 
@@ -511,6 +523,7 @@ static int Control( demux_t *p_demux, int i_query, va_list args )
                     return i64 ? VLC_EGENERIC : VLC_SUCCESS;
 
                 p_sys->i_current_pts = 0;
+                p_sys->i_last_scr = -1;
                 i_pos *= (float)i64 / (float)i_now;
                 stream_Seek( p_demux->s, i_pos );
                 return VLC_SUCCESS;
diff --git a/modules/demux/ts.c b/modules/demux/ts.c
index e98d78d..89602b4 100644
--- a/modules/demux/ts.c
+++ b/modules/demux/ts.c
@@ -278,6 +278,7 @@ typedef struct
     int             i_number;
     int             i_pid_pcr;
     int             i_pid_pmt;
+    mtime_t         i_pcr_value;
     /* IOD stuff (mpeg4) */
     iod_descriptor_t *iod;
 
@@ -1555,6 +1556,7 @@ static void PIDInit( ts_pid_t *pid, bool b_psi, ts_psi_t *p_owner )
                 prg->i_number   = -1;
                 prg->i_pid_pcr  = -1;
                 prg->i_pid_pmt  = -1;
+                prg->i_pcr_value= -1;
                 prg->iod        = NULL;
                 prg->handle     = NULL;
 
@@ -1834,6 +1836,24 @@ static void ParsePES( demux_t *p_demux, ts_pid_t *pid )
                 abort();
             p_block->p_buffer[p_block->i_buffer -1] = '\0';
         }
+        else if( pid->es->fmt.i_codec == VLC_CODEC_TELETEXT )
+        {
+            if( p_block->i_pts <= VLC_TS_INVALID )
+            {
+                /* Teletext may have missing PTS (ETSI EN 300 472 Annexe A)
+                 * In this case use the last PCR + 40ms */
+                for( int i = 0; pid->p_owner && i < pid->p_owner->i_prg; i++ )
+                {
+                    if( pid->i_owner_number == pid->p_owner->prg[i]->i_number )
+                    {
+                        mtime_t i_pcr = pid->p_owner->prg[i]->i_pcr_value;
+                        if( i_pcr > VLC_TS_INVALID )
+                            p_block->i_pts = VLC_TS_0 + i_pcr * 100 / 9 + 40000;
+                        break;
+                    }
+                }
+            }
+        }
 
         for( i = 0; i < pid->i_extra_es; i++ )
         {
@@ -2189,6 +2209,7 @@ static void PCRHandle( demux_t *p_demux, ts_pid_t *pid, block_t *p_bk )
             {
                 if( pid->i_pid == p_sys->pmt[i]->psi->prg[i_prg]->i_pid_pcr )
                 {
+                    p_sys->pmt[i]->psi->prg[i_prg]->i_pcr_value = i_pcr;
                     es_out_Control( p_demux->out, ES_OUT_SET_GROUP_PCR,
                                     (int)p_sys->pmt[i]->psi->prg[i_prg]->i_number,
                                     (int64_t)(VLC_TS_0 + i_pcr * 100 / 9) );



More information about the vlc-commits mailing list