#include <vlc_common.h>
#include <vlc_plugin.h>
+#include <vlc_memory.h>
#include <ctype.h>
#include <assert.h>
# 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;
char *psz_event_text = malloc(130);
char *psz_ext_text = malloc(1025);
+ assert( psz_name );
+ assert( psz_event_text );
+ assert( psz_ext_text );
+
// 2 bytes version Uimsbf (4,5)
// 2 bytes reserved (6,7)
// 2 bytes duration in minutes Uimsbf (8,9(
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 );
+ assert( p_sys->buffer );
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;
}
}
case 0x85: /* DTS (audio) */
es_format_Init( fmt, AUDIO_ES, VLC_CODEC_DTS );
break;
+ case 0x87: /* E-AC3 */
+ es_format_Init( fmt, AUDIO_ES, VLC_CODEC_EAC3 );
+ break;
case 0x91: /* A52 vls (audio) */
es_format_Init( fmt, AUDIO_ES, VLC_FOURCC( 'a', '5', '2', 'b' ) );
{
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 )
{
vlc_iconv_close( iconv_handle );
*psz_out = '\0';
+
+ /* Convert EIT-coded CR/LFs */
+ unsigned char *pbuf = (unsigned char *)psz_outstring;
+ for( ; pbuf < (unsigned char *)psz_out ; pbuf++)
+ {
+ if( pbuf[0] == 0xc2 && pbuf[1] == 0x8a )
+ {
+ pbuf[0] = ' ';
+ pbuf[1] = '\n';
+ }
+ }
+
+
}
return psz_outstring;
}
}
#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 = realloc_or_free( psz_extra,
+ strlen(psz_extra) + strlen(psz_text) + 1 );
+ assert( psz_extra );
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 = realloc_or_free( psz_extra,
+ strlen(psz_extra) + strlen(psz_dsc) +
+ strlen(psz_itm) + 3 + 1 );
+ assert( psz_extra );
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
break;
case 0x84: /* E-AC3 */
- case 0x87: /* E-AC3 */
case 0xA1: /* Secondary E-AC3 */
p_fmt->i_cat = AUDIO_ES;
p_fmt->i_codec = VLC_CODEC_EAC3;
}
}
- 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++ )
{