#include <vlc_common.h>
#include <vlc_plugin.h>
-#include <ctype.h>
#include <assert.h>
#include <vlc_access.h> /* DVB-specific things */
# include "tables/eit.h"
# endif
#endif
-#include <time.h>
+
+/* TDT support */
+#ifdef _DVBPSI_DR_58_H_
+# define TS_USE_TDT 1
+# ifdef HAVE_DVBPSI_DR_H
+# include <dvbpsi/tot.h>
+# else
+# include "tables/tot.h"
+# endif
+#else
+# include <time.h>
+#endif
+
#undef TS_DEBUG
/*****************************************************************************
/* */
bool b_dvb_meta;
+ int64_t i_tdt_delta;
int64_t i_dvb_start;
int64_t i_dvb_length;
{
p_sys->i_ts_read = 1500 / p_sys->i_packet_size;
}
- p_sys->buffer = malloc( p_sys->i_packet_size * p_sys->i_ts_read );
+ p_sys->buffer = xmalloc( p_sys->i_packet_size * p_sys->i_ts_read );
msg_Info( p_demux, "%s raw stream to file `%s' reading packets %d",
b_append ? "appending" : "dumping", p_sys->psz_file,
p_sys->i_ts_read );
p_sys->b_dvb_meta = true;
p_sys->b_access_control = true;
p_sys->i_current_program = 0;
+ p_sys->i_tdt_delta = 0;
p_sys->i_dvb_start = 0;
p_sys->i_dvb_length = 0;
eit->psi->handle =
dvbpsi_AttachDemux( (dvbpsi_demux_new_cb_t)PSINewTableCallBack,
p_demux );
+#ifdef TS_USE_TDT
+ ts_pid_t *tdt = &p_sys->pid[0x14];
+ PIDInit( tdt, true, NULL );
+ tdt->psi->handle =
+ dvbpsi_AttachDemux( (dvbpsi_demux_new_cb_t)PSINewTableCallBack,
+ p_demux );
+#endif
if( p_sys->b_access_control )
{
if( stream_Control( p_demux->s, STREAM_CONTROL_ACCESS,
ACCESS_SET_PRIVATE_ID_STATE, 0x11, true ) ||
+#ifdef TS_USE_TDT
+ stream_Control( p_demux->s, STREAM_CONTROL_ACCESS,
+ ACCESS_SET_PRIVATE_ID_STATE, 0x14, true ) ||
+#endif
stream_Control( p_demux->s, STREAM_CONTROL_ACCESS,
ACCESS_SET_PRIVATE_ID_STATE, 0x12, true ) )
p_sys->b_access_control = false;
free( pid->psi );
break;
default:
- if( p_sys->b_dvb_meta && ( pid->i_pid == 0x11 || pid->i_pid == 0x12 ) )
+ if( p_sys->b_dvb_meta && ( pid->i_pid == 0x11 || pid->i_pid == 0x12 || pid->i_pid == 0x14 ) )
{
- /* SDT or EIT */
+ /* SDT or EIT or TDT */
dvbpsi_DetachDemux( pid->psi->handle );
free( pid->psi );
}
{
if( p_pid->psi )
{
- if( p_pid->i_pid == 0 || ( p_sys->b_dvb_meta && ( p_pid->i_pid == 0x11 || p_pid->i_pid == 0x12 ) ) )
+ if( p_pid->i_pid == 0 || ( p_sys->b_dvb_meta && ( p_pid->i_pid == 0x11 || p_pid->i_pid == 0x12 || p_pid->i_pid == 0x14 ) ) )
{
dvbpsi_PushPacket( p_pid->psi->handle, p_pkt->p_buffer );
}
if( pi_time )
*pi_time = 0;
- if( p_sys->b_access_control && p_sys->i_dvb_length > 0 )
+ if( p_sys->i_dvb_length > 0 )
{
- /* FIXME we should not use time() but read the date from the tdt */
- const time_t t = time( NULL );
+#ifdef TS_USE_TDT
+ const int64_t t = mdate() + p_sys->i_tdt_delta;
+#else
+ const int64_t t = CLOCK_FREQ * time ( NULL );
+#endif
+
if( p_sys->i_dvb_start <= t && t < p_sys->i_dvb_start + p_sys->i_dvb_length )
{
if( pi_length )
- *pi_length = p_sys->i_dvb_length * INT64_C(1000000);
+ *pi_length = p_sys->i_dvb_length;
if( pi_time )
- *pi_time = (t - p_sys->i_dvb_start) * INT64_C(1000000);
+ *pi_time = t - p_sys->i_dvb_start;
return VLC_SUCCESS;
}
}
if( !b_old_valid )
{
- pid->psi = malloc( sizeof( ts_psi_t ) );
+ pid->psi = xmalloc( sizeof( ts_psi_t ) );
if( pid->psi )
{
pid->psi->handle = NULL;
int i;
if( i_dts >= 0 )
- {
- p_pes->i_dts = i_dts * 100 / 9;
- }
+ p_pes->i_dts = VLC_TS_0 + i_dts * 100 / 9;
+
if( i_pts >= 0 )
- {
- p_pes->i_pts = i_pts * 100 / 9;
- }
+ p_pes->i_pts = VLC_TS_0 + i_pts * 100 / 9;
+
p_pes->i_length = i_length * 100 / 9;
p_block = block_ChainGather( p_pes );
{
es_out_Control( p_demux->out, ES_OUT_SET_GROUP_PCR,
(int)p_sys->pmt[i]->psi->prg[i_prg]->i_number,
- (int64_t)(i_pcr * 100 / 9) );
+ (int64_t)(VLC_TS_0 + i_pcr * 100 / 9) );
}
}
}
case 0x04: /* MPEG-2 audio */
es_format_Init( fmt, AUDIO_ES, VLC_CODEC_MPGA );
break;
- case 0x11: /* MPEG4 (audio) */
+ case 0x11: /* MPEG4 (audio) LATM */
case 0x0f: /* ISO/IEC 13818-7 Audio with ADTS transport syntax */
es_format_Init( fmt, AUDIO_ES, VLC_CODEC_MP4A );
break;
{
demux_sys_t *p_sys = p_demux->p_sys;
- if( !p_sys->b_dvb_meta || ( i_pid != 0x11 && i_pid != 0x12 ) )
+ if( !p_sys->b_dvb_meta || ( i_pid != 0x11 && i_pid != 0x12 && i_pid != 0x14 ) )
return;
msg_Warn( p_demux, "Switching to non DVB mode" );
/* This doesn't look like a DVB stream so don't try
- * parsing the SDT/EDT */
+ * parsing the SDT/EDT/TDT */
- for( int i = 0x11; i <= 0x12; i++ )
+ for( int i = 0x11; i <= 0x14; i++ )
{
+ if( i == 0x13 ) continue;
ts_pid_t *p_pid = &p_sys->pid[i];
if( p_pid->psi )
{
}
#undef CVT_FROM_BCD
+#ifdef TS_USE_TDT
+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 = CLOCK_FREQ * EITConvertStartTime( p_tdt->i_utc_time )
+ - mdate();
+ dvbpsi_DeleteTOT(p_tdt);
+}
+#endif
+
static void EITCallBack( demux_t *p_demux,
dvbpsi_eit_t *p_eit, bool b_current_following )
{
msg_Dbg( p_demux, " - text='%s'", psz_text );
- psz_extra = realloc( psz_extra, strlen(psz_extra) + strlen(psz_text) + 1 );
+ psz_extra = xrealloc( psz_extra,
+ strlen(psz_extra) + strlen(psz_text) + 1 );
strcat( psz_extra, psz_text );
free( psz_text );
}
{
msg_Dbg( p_demux, " - desc='%s' item='%s'", psz_dsc, psz_itm );
#if 0
- psz_extra = realloc( psz_extra, strlen(psz_extra) + strlen(psz_dsc) + strlen(psz_itm) + 3 + 1 );
+ psz_extra = xrealloc( psz_extra,
+ strlen(psz_extra) + strlen(psz_dsc) +
+ strlen(psz_itm) + 3 + 1 );
strcat( psz_extra, "(" );
strcat( psz_extra, psz_dsc );
strcat( psz_extra, " " );
}
if( p_epg->i_event > 0 )
{
- if( p_eit->i_service_id == p_sys->i_current_program && b_current_following )
+ if( b_current_following &&
+ ( p_sys->i_current_program == -1 ||
+ p_sys->i_current_program == p_eit->i_service_id ) )
{
p_sys->i_dvb_length = 0;
p_sys->i_dvb_start = 0;
if( p_epg->p_current )
{
- p_sys->i_dvb_start = p_epg->p_current->i_start;
- p_sys->i_dvb_length = p_epg->p_current->i_duration;
+ p_sys->i_dvb_start = CLOCK_FREQ * p_epg->p_current->i_start;
+ p_sys->i_dvb_length = CLOCK_FREQ * p_epg->p_current->i_duration;
}
}
es_out_Control( p_demux->out, ES_OUT_SET_GROUP_EPG, p_eit->i_service_id, p_epg );
(dvbpsi_eit_callback)EITCallBackSchedule;
dvbpsi_AttachEIT( h, i_table_id, i_extension, cb, p_demux );
}
+#ifdef TS_USE_TDT
+ else if( p_demux->p_sys->pid[0x11].psi->i_sdt_version != -1 &&
+ i_table_id == 0x70 ) /* TDT */
+ {
+ msg_Dbg( p_demux, "PSINewTableCallBack: table 0x%x(%d) ext=0x%x(%d)",
+ i_table_id, i_table_id, i_extension, i_extension );
+ dvbpsi_AttachTOT( h, i_table_id, i_extension,
+ (dvbpsi_tot_callback)TDTCallBack, p_demux);
+ }
+#endif
+
}
#endif
}
}
- if( ProgramIsSelected( p_demux, prg->i_number ) )
- {
- /* Set CAM descrambling */
- stream_Control( p_demux->s, STREAM_CONTROL_ACCESS,
- ACCESS_SET_PRIVATE_ID_CA, p_pmt );
- }
- else
- {
+ /* Set CAM descrambling */
+ if( !ProgramIsSelected( p_demux, prg->i_number )
+ || stream_Control( p_demux->s, STREAM_CONTROL_ACCESS,
+ ACCESS_SET_PRIVATE_ID_CA, p_pmt ) != VLC_SUCCESS )
dvbpsi_DeletePMT( p_pmt );
- }
for( int i = 0; i < i_clean; i++ )
{