+#if TS_USE_DVB_SI
+static void SDTCallBack( demux_t *p_demux, dvbpsi_sdt_t *p_sdt )
+{
+ demux_sys_t *p_sys = p_demux->p_sys;
+ ts_pid_t *sdt = &p_sys->pid[0x11];
+ dvbpsi_sdt_service_t *p_srv;
+
+ msg_Dbg( p_demux, "SDTCallBack called" );
+
+ if( sdt->psi->i_sdt_version != -1 &&
+ ( !p_sdt->b_current_next ||
+ p_sdt->i_version == sdt->psi->i_sdt_version ) )
+ {
+ dvbpsi_DeleteSDT( p_sdt );
+ return;
+ }
+
+ msg_Dbg( p_demux, "new SDT ts_id=%d version=%d current_next=%d network_id=%d",
+ p_sdt->i_ts_id, p_sdt->i_version, p_sdt->b_current_next, p_sdt->i_network_id );
+
+ for( p_srv = p_sdt->p_first_service; p_srv; p_srv = p_srv->p_next )
+ {
+ vlc_meta_t *p_meta = vlc_meta_New();
+ dvbpsi_descriptor_t *p_dr;
+
+ msg_Dbg( p_demux, " * service id=%d eit schedule=%d present=%d runing=%d free_ca=%d",
+ p_srv->i_service_id,
+ p_srv->b_eit_schedule, p_srv->b_eit_present, p_srv->i_running_status,
+ p_srv->b_free_ca );
+
+ for( p_dr = p_srv->p_first_descriptor; p_dr; p_dr = p_dr->p_next )
+ {
+ if( p_dr->i_tag == 0x48 )
+ {
+ static const char *psz_type[0x11] = {
+ "Reserved",
+ "Digital television service",
+ "Digital radio sound service",
+ "Teletext service",
+ "NVOD reference service",
+ "NVOD time-shifted service",
+ "Mosaic service",
+ "PAL coded signal",
+ "SECAM coded signal",
+ "D/D2-MAC",
+ "FM Radio",
+ "NTSC coded signal",
+ "Data broadcast service",
+ "Reserved for Common Interface Usage",
+ "RCS Map (see EN 301 790 [35])",
+ "RCS FLS (see EN 301 790 [35])",
+ "DVB MHP service"
+ };
+ dvbpsi_service_dr_t *pD = dvbpsi_DecodeServiceDr( p_dr );
+ char str1[257];
+ char str2[257];
+
+ memcpy( str1, pD->i_service_provider_name, pD->i_service_provider_name_length );
+ str1[pD->i_service_provider_name_length] = '\0';
+ memcpy( str2, pD->i_service_name, pD->i_service_name_length );
+ str2[pD->i_service_name_length] = '\0';
+
+ msg_Dbg( p_demux, " - type=%d provider=%s name=%s",
+ pD->i_service_type, str1, str2 );
+
+ vlc_meta_Add( p_meta, "Name", str2 );
+ vlc_meta_Add( p_meta, "Provider", str1 );
+ if( pD->i_service_type >= 0x01 && pD->i_service_type <= 0x10 )
+ vlc_meta_Add( p_meta, "Type", psz_type[pD->i_service_type] );
+ }
+ }
+
+ if( p_srv->i_running_status == 0x01 )
+ vlc_meta_Add( p_meta, "Status", "Not running" );
+ else if( p_srv->i_running_status == 0x02 )
+ vlc_meta_Add( p_meta, "Status", "Starts in a few seconds" );
+ else if( p_srv->i_running_status == 0x03 )
+ vlc_meta_Add( p_meta, "Status", "Pausing" );
+ else if( p_srv->i_running_status == 0x04 )
+ vlc_meta_Add( p_meta, "Status", "Running" );
+ else
+ vlc_meta_Add( p_meta, "Status", "Unknown" );
+
+
+ es_out_Control( p_demux->out, ES_OUT_SET_GROUP_META,
+ p_srv->i_service_id, p_meta );
+ vlc_meta_Delete( p_meta );
+ }
+
+ sdt->psi->i_sdt_version = p_sdt->i_version;
+ dvbpsi_DeleteSDT( p_sdt );
+}
+#if 0
+static void DecodeMjd( int i_mjd, int *p_y, int *p_m, int *p_d )
+{
+ int yp = (int)( ( (double)i_mjd - 15078.2)/365.25 );
+ int mp = (int)( ((double)i_mjd - 14956.1 - (int)(yp * 365.25)) / 30.6001 );
+
+ *p_d = i_mjd - 14956 - (int)(yp*365.25) - (int)(mp*30.6001);
+
+ if( mp == 14 || mp == 15 )
+ {
+ *p_y = yp + 1;
+ *p_m = mp - 1 + 12;
+ }
+ else
+ {
+ *p_y = yp;
+ *p_m = mp - 1;
+ }
+}
+#endif
+
+static void EITCallBack( ts_eit_psi_t *psi, dvbpsi_eit_t *p_eit )
+{
+ demux_t *p_demux = psi->p_demux;
+
+ dvbpsi_eit_event_t *p_evt;
+
+ msg_Dbg( p_demux, "EITCallBack called" );
+ if( psi->i_version != -1 &&
+ ( !p_eit->b_current_next || psi->i_version == p_eit->i_version ) )
+ {
+ dvbpsi_DeleteEIT( p_eit );
+ return;
+ }
+
+ msg_Dbg( p_demux, "new EIT service_id=%d version=%d current_next=%d ts_id=%d network_id=%d"
+ "segment_last_section_number=%d last_table_id=%d",
+ p_eit->i_service_id, p_eit->i_version, p_eit->b_current_next, p_eit->i_ts_id,
+ p_eit->i_network_id, p_eit->i_segment_last_section_number, p_eit->i_last_table_id );
+
+ for( p_evt = p_eit->p_first_event; p_evt; p_evt = p_evt->p_next )
+ {
+ vlc_meta_t *p_meta = vlc_meta_New();
+ dvbpsi_descriptor_t *p_dr;
+ char *psz_cat = malloc( strlen("Event")+10 );
+ char psz_start[15];
+ char psz_duration[15];
+ char psz_name[256];
+ char psz_text[256];
+ char *psz_extra = strdup("");
+ char *psz_value;
+
+ sprintf( psz_cat, "Event %d", p_evt->i_event_id );
+ sprintf( psz_start, "%d%d:%d%d:%d%d",
+ (int)(p_evt->i_start_time >> 20)&0xf,
+ (int)(p_evt->i_start_time >> 16)&0xf,
+ (int)(p_evt->i_start_time >> 12)&0xf,
+ (int)(p_evt->i_start_time >> 8)&0xf,
+ (int)(p_evt->i_start_time >> 4)&0xf,
+ (int)(p_evt->i_start_time )&0xf );
+ sprintf( psz_duration, "%d%d:%d%d:%d%d",
+ (p_evt->i_duration >> 20)&0xf, (p_evt->i_duration >> 16)&0xf,
+ (p_evt->i_duration >> 12)&0xf, (p_evt->i_duration >> 8)&0xf,
+ (p_evt->i_duration >> 4)&0xf, (p_evt->i_duration )&0xf );
+ psz_name[0] = psz_text[0] = '\0';
+
+ msg_Dbg( p_demux, " * event id=%d start_time:mjd=%d %s duration=%s "
+ "running=%d free_ca=%d",
+ p_evt->i_event_id,
+ (int)(p_evt->i_start_time >> 24),
+ psz_start, psz_duration,
+ p_evt->i_running_status, p_evt->b_free_ca );
+
+ for( p_dr = p_evt->p_first_descriptor; p_dr; p_dr = p_dr->p_next )
+ {
+ if( p_dr->i_tag == 0x4d )
+ {
+ dvbpsi_short_event_dr_t *pE = dvbpsi_DecodeShortEventDr( p_dr );
+
+ if( pE )
+ {
+ memcpy( psz_name, pE->i_event_name, pE->i_event_name_length);
+ psz_name[pE->i_event_name_length] = '\0';
+ memcpy( psz_text, pE->i_text, pE->i_text_length );
+ psz_text[pE->i_text_length] = '\0';
+
+ msg_Dbg( p_demux, " - short event lang=%3.3s '%s' : '%s'",
+ pE->i_iso_639_code, psz_name, psz_text );
+ }
+ }
+ else if( p_dr->i_tag == 0x4e )
+ {
+ dvbpsi_extended_event_dr_t *pE = dvbpsi_DecodeExtendedEventDr( p_dr );
+ char str1[257];
+ char str2[257];
+
+ if( pE )
+ {
+ int i;
+ msg_Dbg( p_demux, " - extended event lang=%3.3s",
+ pE->i_iso_639_code );
+ for( i = 0; i < pE->i_entry_count; i++ )
+ {
+ memcpy( str1, pE->i_item_description[i],
+ pE->i_item_description_length[i] );
+ str1[pE->i_item_description_length[i]] = '\0';
+
+ memcpy( str1, pE->i_item[i],
+ pE->i_item_length[i] );
+ str2[pE->i_item_length[i]] = '\0';
+
+ msg_Dbg( p_demux, " - desc='%s' item='%s'", str1, str2 );
+ psz_extra = realloc( psz_extra,
+ strlen(psz_extra) +
+ strlen(str1) +strlen(str2) + 1 + 3 );
+ strcat( psz_extra, str1 );
+ strcat( psz_extra, "(" );
+ strcat( psz_extra, str2 );
+ strcat( psz_extra, ") " );
+ }
+
+ memcpy( str1, pE->i_text, pE->i_text_length );
+ str1[pE->i_text_length] = '\0';
+ msg_Dbg( p_demux, " - text='%s'", str1 );
+ psz_extra = realloc( psz_extra,
+ strlen(psz_extra) + strlen(str1) + 2 );
+ strcat( psz_extra, str1 );
+ strcat( psz_extra, " " );
+ }
+ }
+ else
+ {
+ msg_Dbg( p_demux, " - tag=0x%x(%d)", p_dr->i_tag, p_dr->i_tag );
+ }
+ }
+
+ asprintf( &psz_value, "%s: %s (+%s) %s (%s)",
+ psz_start,
+ psz_name,
+ psz_duration,
+ psz_text, psz_extra );
+ vlc_meta_Add( p_meta, psz_cat, psz_value );
+ free( psz_value );
+
+ es_out_Control( p_demux->out, ES_OUT_SET_GROUP_META,
+ p_eit->i_service_id, p_meta );
+ vlc_meta_Delete( p_meta );
+
+ free( psz_cat );
+ free( psz_extra );
+ }
+ psi->i_version = p_eit->i_version;
+ dvbpsi_DeleteEIT( p_eit );
+}
+
+static void PSINewTableCallBack( demux_t *p_demux, dvbpsi_handle h,
+ uint8_t i_table_id, uint16_t i_extension )
+{
+#if 0
+ msg_Dbg( p_demux, "PSINewTableCallBack: table 0x%x(%d) ext=0x%x(%d)",
+ i_table_id, i_table_id, i_extension, i_extension );
+#endif
+ if( i_table_id == 0x42 )
+ {
+ msg_Dbg( p_demux, "PSINewTableCallBack: table 0x%x(%d) ext=0x%x(%d)",
+ i_table_id, i_table_id, i_extension, i_extension );
+
+ dvbpsi_AttachSDT( h, i_table_id, i_extension, (dvbpsi_sdt_callback)SDTCallBack, p_demux );
+ }
+ else if( i_table_id == 0x4e || /* Current/Following */
+ ( i_table_id >= 0x50 && i_table_id <= 0x5f ) ) /* Schedule */
+ {
+ ts_eit_psi_t *psi = malloc( sizeof(ts_eit_psi_t) );
+
+ msg_Dbg( p_demux, "PSINewTableCallBack: table 0x%x(%d) ext=0x%x(%d)",
+ i_table_id, i_table_id, i_extension, i_extension );
+
+ psi->p_demux = p_demux;
+ psi->i_table_id = i_table_id;
+ psi->i_version = -1;
+ psi->i_service_id = i_extension;
+
+ dvbpsi_AttachEIT( h, i_table_id, i_extension, (dvbpsi_eit_callback)EITCallBack, psi );
+ }
+}
+#endif
+