Commit 85216729 authored by François Cartegnie's avatar François Cartegnie 🤞

demux: ts: simplify eit offset (arib) and add network time

parent b051a4b5
......@@ -367,7 +367,8 @@ static int Open( vlc_object_t *p_this )
p_sys->b_end_preparse = false;
ARRAY_INIT( p_sys->programs );
p_sys->b_default_selection = false;
p_sys->i_tdt_delta = TS_TIME_DELTA_INVALID;
p_sys->i_network_time = 0;
p_sys->i_network_time_update = 0;
p_sys->vdr = vdr;
......@@ -700,29 +701,25 @@ static int Demux( demux_t *p_demux )
/*****************************************************************************
* Control:
*****************************************************************************/
static int EITCurrentEventTime( const ts_pmt_t *p_pmt, time_t i_tdt_delta,
static int EITCurrentEventTime( const ts_pmt_t *p_pmt, demux_sys_t *p_sys,
time_t *pi_time, time_t *pi_length )
{
if( i_tdt_delta == TS_TIME_DELTA_INVALID )
if( p_sys->i_network_time == 0 || !p_pmt || p_pmt->eit.i_event_length == 0 )
return VLC_EGENERIC;
if( pi_length )
*pi_length = 0;
if( pi_time )
*pi_time = 0;
if( p_pmt && p_pmt->eit.i_event_length > 0 )
if( p_pmt->eit.i_event_start <= p_sys->i_network_time &&
p_sys->i_network_time < p_pmt->eit.i_event_start + p_pmt->eit.i_event_length )
{
const time_t t = time(NULL) + i_tdt_delta;
if( p_pmt->eit.i_event_start <= t && t < p_pmt->eit.i_event_start + p_pmt->eit.i_event_length )
if( pi_length )
*pi_length = p_pmt->eit.i_event_length;
if( pi_time )
{
if( pi_length )
*pi_length = p_pmt->eit.i_event_length;
if( pi_time )
*pi_time = t - p_pmt->eit.i_event_start;
return VLC_SUCCESS;
*pi_time = p_sys->i_network_time - p_pmt->eit.i_event_start;
*pi_time += time(NULL) - p_sys->i_network_time_update;
}
return VLC_SUCCESS;
}
return VLC_EGENERIC;
}
......@@ -849,7 +846,7 @@ static int Control( demux_t *p_demux, int i_query, va_list args )
if( p_sys->b_access_control )
{
time_t i_time, i_length;
if( !EITCurrentEventTime( p_pmt, p_sys->i_tdt_delta, &i_time, &i_length ) && i_length > 0 )
if( !EITCurrentEventTime( p_pmt, p_sys, &i_time, &i_length ) && i_length > 0 )
{
*pf = (double)i_time/(double)i_length;
return VLC_SUCCESS;
......@@ -890,7 +887,7 @@ static int Control( demux_t *p_demux, int i_query, va_list args )
!p_sys->b_force_seek_per_percent && p_pmt )
{
time_t i_time, i_length;
if( !EITCurrentEventTime( p_pmt, p_sys->i_tdt_delta, &i_time, &i_length ) &&
if( !EITCurrentEventTime( p_pmt, p_sys, &i_time, &i_length ) &&
i_length > 0 && !SeekToTime( p_demux, p_pmt, (int64_t)(TO_SCALE(i_length * CLOCK_FREQ) * f) ) )
{
ReadyQueuesPostSeek( p_demux );
......@@ -946,7 +943,7 @@ static int Control( demux_t *p_demux, int i_query, va_list args )
if( p_sys->b_access_control )
{
time_t i_event_start;
if( !EITCurrentEventTime( p_pmt, p_sys->i_tdt_delta, &i_event_start, NULL ) )
if( !EITCurrentEventTime( p_pmt, p_sys, &i_event_start, NULL ) )
{
*pi64 = i_event_start * CLOCK_FREQ;
return VLC_SUCCESS;
......@@ -967,7 +964,7 @@ static int Control( demux_t *p_demux, int i_query, va_list args )
if( p_sys->b_access_control )
{
time_t i_event_duration;
if( !EITCurrentEventTime( p_pmt, p_sys->i_tdt_delta, NULL, &i_event_duration ) )
if( !EITCurrentEventTime( p_pmt, p_sys, NULL, &i_event_duration ) )
{
*pi64 = i_event_duration * CLOCK_FREQ;
return VLC_SUCCESS;
......
......@@ -20,9 +20,6 @@
#ifndef VLC_TS_H
#define VLC_TS_H
#include <limits.h>
#define TS_TIME_DELTA_INVALID INT64_MAX
#ifdef HAVE_ARIBB24
typedef struct arib_instance_t arib_instance_t;
#endif
......@@ -105,7 +102,8 @@ struct demux_sys_t
bool b_end_preparse;
/* */
time_t i_tdt_delta;
time_t i_network_time;
time_t i_network_time_update; /* for network time interpolation */
bool b_broken_charset; /* True if broken encoding is used in EPG/SDT */
/* Selected programs */
......
......@@ -341,11 +341,26 @@ static void TDTCallBack( demux_t *p_demux, dvbpsi_tot_t *p_tdt )
{
demux_sys_t *p_sys = p_demux->p_sys;
p_sys->i_tdt_delta = EITConvertStartTime( p_tdt->i_utc_time ) - time(NULL);
p_sys->i_network_time = EITConvertStartTime( p_tdt->i_utc_time );
p_sys->i_network_time_update = time(NULL);
if( p_sys->standard == TS_STANDARD_ARIB )
{
/* All ARIB-B10 times are in JST time, where DVB is UTC. (spec being a fork)
DVB TOT should include DTS offset in descriptor 0x58 (including DST),
but as there's no DST in JAPAN (since Showa 27/1952)
and considering that no-one seems to send TDT or desc 0x58,
falling back on fixed offset is safe */
p_sys->i_network_time += 9 * 3600;
}
/* Because libdvbpsi is broken and deduplicating timestamp tables,
* we need to reset it to get next timestamp callback */
ts_pid_t *pid = ts_pid_Get( &p_sys->pids, TS_SI_TDT_PID );
dvbpsi_decoder_reset( pid->u.p_si->handle->p_decoder, true );
dvbpsi_tot_delete(p_tdt);
}
static void EITCallBack( demux_t *p_demux,
dvbpsi_eit_t *p_eit, bool b_current_following )
{
......@@ -386,24 +401,14 @@ static void EITCallBack( demux_t *p_demux,
/* We have to fix ARIB-B10 as all timestamps are JST */
if( p_sys->standard == TS_STANDARD_ARIB )
{
time_t i_now = time(NULL);
time_t i_tot_time = 0;
if( p_sys->i_tdt_delta == TS_TIME_DELTA_INVALID )
p_sys->i_tdt_delta = (i_start + i_duration - 5) - i_now;
i_tot_time = i_now + p_sys->i_tdt_delta;
tzset(); // JST -> UTC
i_start += timezone; // FIXME: what about DST?
i_tot_time += timezone;
/* See comments on TDT callback */
i_start += 9 * 3600;
/* Services are not setting runstatus */
if( p_evt->i_running_status == TS_SI_RUNSTATUS_UNDEFINED &&
(i_start - 5 < i_tot_time &&
i_tot_time < i_start + i_duration + 5) )
(i_start <= p_sys->i_network_time &&
p_sys->i_network_time < i_start + i_duration) )
{
p_evt->i_running_status = TS_SI_RUNSTATUS_RUNNING;
msg_Dbg( p_demux, " EIT running status undefined -> running" );
}
}
......@@ -601,12 +606,16 @@ static void SINewTableCallBack( dvbpsi_t *h, uint8_t i_table_id,
msg_Dbg( p_demux, "SINewTableCallback: table 0x%x(%d) ext=0x%x(%d)",
i_table_id, i_table_id, i_extension, i_extension );
dvbpsi_eit_callback cb = i_table_id == 0x4e ?
(dvbpsi_eit_callback)EITCallBackCurrentFollowing :
(dvbpsi_eit_callback)EITCallBackSchedule;
/* Do not attach decoders if we can't decode timestamps */
if( p_demux->p_sys->i_network_time > 0 )
{
dvbpsi_eit_callback cb = i_table_id == 0x4e ?
(dvbpsi_eit_callback)EITCallBackCurrentFollowing :
(dvbpsi_eit_callback)EITCallBackSchedule;
if( !dvbpsi_eit_attach( h, i_table_id, i_extension, cb, p_demux ) )
msg_Err( p_demux, "SINewTableCallback: failed attaching EITCallback" );
if( !dvbpsi_eit_attach( h, i_table_id, i_extension, cb, p_demux ) )
msg_Err( p_demux, "SINewTableCallback: failed attaching EITCallback" );
}
}
else if( p_pid->i_pid == TS_SI_TDT_PID &&
(i_table_id == TS_SI_TDT_TABLE_ID || i_table_id == TS_SI_TOT_TABLE_ID) )
......
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