Commit 9e393772 authored by Laurent Aimar's avatar Laurent Aimar

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

parent b3c35a76
...@@ -82,6 +82,7 @@ struct demux_sys_t ...@@ -82,6 +82,7 @@ struct demux_sys_t
ps_track_t tk[PS_TK_COUNT]; ps_track_t tk[PS_TK_COUNT];
int64_t i_scr; int64_t i_scr;
int64_t i_last_scr;
int i_mux_rate; int i_mux_rate;
int64_t i_length; int64_t i_length;
int i_time_track; int i_time_track;
...@@ -134,6 +135,7 @@ static int OpenCommon( vlc_object_t *p_this, bool b_force ) ...@@ -134,6 +135,7 @@ static int OpenCommon( vlc_object_t *p_this, bool b_force )
/* Init p_sys */ /* Init p_sys */
p_sys->i_mux_rate = 0; p_sys->i_mux_rate = 0;
p_sys->i_scr = -1; p_sys->i_scr = -1;
p_sys->i_last_scr = -1;
p_sys->i_length = -1; p_sys->i_length = -1;
p_sys->i_current_pts = (mtime_t) 0; p_sys->i_current_pts = (mtime_t) 0;
p_sys->i_time_track = -1; p_sys->i_time_track = -1;
...@@ -322,6 +324,7 @@ static int Demux( demux_t *p_demux ) ...@@ -322,6 +324,7 @@ static int Demux( demux_t *p_demux )
case 0x1ba: case 0x1ba:
if( !ps_pkt_parse_pack( p_pkt, &p_sys->i_scr, &i_mux_rate ) ) 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; if( !p_sys->b_have_pack ) p_sys->b_have_pack = true;
/* done later on to work around bad vcd/svcd streams */ /* done later on to work around bad vcd/svcd streams */
/* es_out_Control( p_demux->out, ES_OUT_SET_PCR, p_sys->i_scr ); */ /* 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 ) ...@@ -395,6 +398,7 @@ static int Demux( demux_t *p_demux )
tk->fmt.i_codec == VLC_CODEC_CVD ) ) tk->fmt.i_codec == VLC_CODEC_CVD ) )
{ {
p_sys->i_scr = -1; p_sys->i_scr = -1;
p_sys->i_last_scr = -1;
} }
if( p_sys->i_scr >= 0 ) if( p_sys->i_scr >= 0 )
...@@ -413,6 +417,13 @@ static int Demux( demux_t *p_demux ) ...@@ -413,6 +417,13 @@ static int Demux( demux_t *p_demux )
msg_Dbg( p_demux, "force SCR: %"PRId64, p_pkt->i_pts ); 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 ); 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 ) 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 ) ...@@ -465,6 +476,7 @@ static int Control( demux_t *p_demux, int i_query, va_list args )
f = (double) va_arg( args, double ); f = (double) va_arg( args, double );
i64 = stream_Size( p_demux->s ); i64 = stream_Size( p_demux->s );
p_sys->i_current_pts = 0; p_sys->i_current_pts = 0;
p_sys->i_last_scr = -1;
return stream_Seek( p_demux->s, (int64_t)(i64 * f) ); 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 ) ...@@ -511,6 +523,7 @@ static int Control( demux_t *p_demux, int i_query, va_list args )
return i64 ? VLC_EGENERIC : VLC_SUCCESS; return i64 ? VLC_EGENERIC : VLC_SUCCESS;
p_sys->i_current_pts = 0; p_sys->i_current_pts = 0;
p_sys->i_last_scr = -1;
i_pos *= (float)i64 / (float)i_now; i_pos *= (float)i64 / (float)i_now;
stream_Seek( p_demux->s, i_pos ); stream_Seek( p_demux->s, i_pos );
return VLC_SUCCESS; return VLC_SUCCESS;
......
...@@ -278,6 +278,7 @@ typedef struct ...@@ -278,6 +278,7 @@ typedef struct
int i_number; int i_number;
int i_pid_pcr; int i_pid_pcr;
int i_pid_pmt; int i_pid_pmt;
mtime_t i_pcr_value;
/* IOD stuff (mpeg4) */ /* IOD stuff (mpeg4) */
iod_descriptor_t *iod; iod_descriptor_t *iod;
...@@ -1555,6 +1556,7 @@ static void PIDInit( ts_pid_t *pid, bool b_psi, ts_psi_t *p_owner ) ...@@ -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_number = -1;
prg->i_pid_pcr = -1; prg->i_pid_pcr = -1;
prg->i_pid_pmt = -1; prg->i_pid_pmt = -1;
prg->i_pcr_value= -1;
prg->iod = NULL; prg->iod = NULL;
prg->handle = NULL; prg->handle = NULL;
...@@ -1834,6 +1836,24 @@ static void ParsePES( demux_t *p_demux, ts_pid_t *pid ) ...@@ -1834,6 +1836,24 @@ static void ParsePES( demux_t *p_demux, ts_pid_t *pid )
abort(); abort();
p_block->p_buffer[p_block->i_buffer -1] = '\0'; 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++ ) 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 ) ...@@ -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 ) 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, es_out_Control( p_demux->out, ES_OUT_SET_GROUP_PCR,
(int)p_sys->pmt[i]->psi->prg[i_prg]->i_number, (int)p_sys->pmt[i]->psi->prg[i_prg]->i_number,
(int64_t)(VLC_TS_0 + i_pcr * 100 / 9) ); (int64_t)(VLC_TS_0 + i_pcr * 100 / 9) );
......
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