[dvblast-devel] [PATCH 4/9] demux: Track each EIT PSI table separately
Georgi Chorbadzhiyski
gf at unixsol.org
Sat Jan 20 13:42:52 CET 2018
This stops sections from one table to overwrite sections in
another table (usually seen with section 0 from EIT/pf and EIT/schedule).
This increases memory usage by at least 32 kb per service
but allows extracting of complete EIT data.
---
demux.c | 65 +++++++++++++++++++++++++++++++++++++++++++++--------------------
1 file changed, 45 insertions(+), 20 deletions(-)
diff --git a/demux.c b/demux.c
index b4f2814..c32ae9c 100644
--- a/demux.c
+++ b/demux.c
@@ -82,11 +82,19 @@ typedef struct ts_pid_t
struct ev_timer timeout_watcher;
} ts_pid_t;
+struct eit_sections {
+ PSI_TABLE_DECLARE(data);
+};
+
+/* EIT is carried in several separate tables, we need to track each table
+ separately, otherwise one table overwrites sections of another table */
+#define MAX_EIT_TABLES ( EIT_TABLE_ID_SCHED_ACTUAL_LAST - EIT_TABLE_ID_PF_ACTUAL )
+
typedef struct sid_t
{
uint16_t i_sid, i_pmt_pid;
uint8_t *p_current_pmt;
- PSI_TABLE_DECLARE(pp_eit_sections);
+ struct eit_sections eit_table[MAX_EIT_TABLES];
} sid_t;
mtime_t i_wallclock = 0;
@@ -440,7 +448,7 @@ void demux_Open( void )
*****************************************************************************/
void demux_Close( void )
{
- int i;
+ int i, r;
psi_table_free( pp_current_pat_sections );
psi_table_free( pp_next_pat_sections );
@@ -461,7 +469,9 @@ void demux_Close( void )
for ( i = 0; i < i_nb_sids; i++ )
{
sid_t *p_sid = pp_sids[i];
- psi_table_free(p_sid->pp_eit_sections);
+ for ( r = 0; r < MAX_EIT_TABLES; r++ ) {
+ psi_table_free( p_sid->eit_table[r].data );
+ }
free( p_sid->p_current_pmt );
free( p_sid );
}
@@ -1414,11 +1424,17 @@ static void SendSDT( mtime_t i_dts )
/*****************************************************************************
* SendEIT
*****************************************************************************/
+static bool handle_epg( int i_table_id )
+{
+ return (i_table_id == EIT_TABLE_ID_PF_ACTUAL ||
+ (i_table_id >= EIT_TABLE_ID_SCHED_ACTUAL_FIRST &&
+ i_table_id <= EIT_TABLE_ID_SCHED_ACTUAL_LAST));
+}
+
static void SendEIT( sid_t *p_sid, mtime_t i_dts, uint8_t *p_eit )
{
uint8_t i_table_id = psi_get_tableid( p_eit );
- bool b_epg = i_table_id >= EIT_TABLE_ID_SCHED_ACTUAL_FIRST &&
- i_table_id <= EIT_TABLE_ID_SCHED_ACTUAL_LAST;
+ bool b_epg = handle_epg( i_table_id );
uint16_t i_onid = eit_get_onid(p_eit);
int i;
@@ -2170,8 +2186,13 @@ static void DeleteProgram( uint16_t i_sid, uint16_t i_pid )
}
p_sid->i_sid = 0;
p_sid->i_pmt_pid = 0;
- psi_table_free(p_sid->pp_eit_sections);
- psi_table_init(p_sid->pp_eit_sections);
+
+ uint8_t r;
+ for ( r = 0; r < MAX_EIT_TABLES; r++ ) {
+ psi_table_free( p_sid->eit_table[r].data );
+ psi_table_init( p_sid->eit_table[r].data );
+ }
+
}
/*****************************************************************************
@@ -2262,7 +2283,7 @@ static void HandlePAT( mtime_t i_dts )
bool b_change = false;
PSI_TABLE_DECLARE( pp_old_pat_sections );
uint8_t i_last_section = psi_table_get_lastsection( pp_next_pat_sections );
- uint8_t i;
+ uint8_t i, r;
if ( psi_table_validate( pp_current_pat_sections ) &&
psi_table_compare( pp_current_pat_sections, pp_next_pat_sections ) )
@@ -2346,7 +2367,9 @@ static void HandlePAT( mtime_t i_dts )
{
p_sid = malloc( sizeof(sid_t) );
p_sid->p_current_pmt = NULL;
- psi_table_init(p_sid->pp_eit_sections);
+ for ( r = 0; r < MAX_EIT_TABLES; r++ ) {
+ psi_table_init( p_sid->eit_table[r].data );
+ }
i_nb_sids++;
pp_sids = realloc( pp_sids, sizeof(sid_t *) * i_nb_sids );
pp_sids[i_nb_sids - 1] = p_sid;
@@ -3009,23 +3032,27 @@ static void HandleEIT( uint16_t i_pid, uint8_t *p_eit, mtime_t i_dts )
return;
}
- if ( i_table_id != EIT_TABLE_ID_PF_ACTUAL )
+ bool b_epg = handle_epg( i_table_id );
+ if ( ! b_epg )
goto out_eit;
/* We do not use psi_table_* primitives as the spec allows for holes in
* section numbering, and there is no sure way to know whether you have
* gathered all sections. */
uint8_t i_section = psi_get_section(p_eit);
- if (p_sid->pp_eit_sections[i_section] != NULL &&
- psi_compare(p_sid->pp_eit_sections[i_section], p_eit)) {
+ uint8_t eit_table_id = i_table_id - EIT_TABLE_ID_PF_ACTUAL;
+ if (eit_table_id >= MAX_EIT_TABLES)
+ goto out_eit;
+ if (p_sid->eit_table[eit_table_id].data[i_section] != NULL &&
+ psi_compare(p_sid->eit_table[eit_table_id].data[i_section], p_eit)) {
/* Identical section. Shortcut. */
- free(p_sid->pp_eit_sections[i_section]);
- p_sid->pp_eit_sections[i_section] = p_eit;
+ free(p_sid->eit_table[eit_table_id].data[i_section]);
+ p_sid->eit_table[eit_table_id].data[i_section] = p_eit;
goto out_eit;
}
- free(p_sid->pp_eit_sections[i_section]);
- p_sid->pp_eit_sections[i_section] = p_eit;
+ free(p_sid->eit_table[eit_table_id].data[i_section]);
+ p_sid->eit_table[eit_table_id].data[i_section] = p_eit;
if ( b_print_enabled )
{
@@ -3037,7 +3064,7 @@ static void HandleEIT( uint16_t i_pid, uint8_t *p_eit, mtime_t i_dts )
out_eit:
SendEIT( p_sid, i_dts, p_eit );
- if ( i_table_id != EIT_TABLE_ID_PF_ACTUAL )
+ if ( ! b_epg )
free( p_eit );
}
@@ -3096,9 +3123,7 @@ static void HandleSection( uint16_t i_pid, uint8_t *p_section, mtime_t i_dts )
break;
default:
- if ( i_table_id == EIT_TABLE_ID_PF_ACTUAL ||
- (i_table_id >= EIT_TABLE_ID_SCHED_ACTUAL_FIRST &&
- i_table_id <= EIT_TABLE_ID_SCHED_ACTUAL_LAST) )
+ if ( handle_epg( i_table_id ) )
{
HandleEIT( i_pid, p_section, i_dts );
break;
--
2.14.1
More information about the dvblast-devel
mailing list