Skip to content
Commits on Source (8)
......@@ -29,6 +29,10 @@ N: M. Benoit
E: <mbenoit@anevia.com>
D: Generate descriptors 0x83, 0xa1
N: O. Braun
E: <oliv.braun@gmail.com>
D: SIS table improvements
N: Roberto Corno
E: corno.roberto@gmail.com
D: Descriptors 0x40, 0x41, 0x49, 0x4a, 0x4b, 0x4f and 0x50
......
......@@ -285,6 +285,10 @@ bool dvbpsi_packet_push(dvbpsi_t *p_dvbpsi, const uint8_t* p_data)
return false;
}
/* Return if no payload in the TS packet */
if (!(p_data[3] & 0x10))
return false;
/* Continuity check */
const bool b_first = (p_decoder->i_continuity_counter == DVBPSI_INVALID_CC);
if (b_first)
......@@ -329,10 +333,6 @@ bool dvbpsi_packet_push(dvbpsi_t *p_dvbpsi, const uint8_t* p_data)
memcpy(p_decoder->prevpacket, p_data, 188);
/* Return if no payload in the TS packet */
if (!(p_data[3] & 0x10))
return false;
/* Skip the adaptation_field if present */
if (p_data[3] & 0x20)
p_payload_pos = p_data + 5 + p_data[4];
......
......@@ -206,7 +206,7 @@ bool dvbpsi_CheckPSISection(dvbpsi_t *p_dvbpsi, dvbpsi_psi_section_t *p_section,
}
if (!p_section->b_syntax_indicator &&
(table_id != 0x70 && table_id != 0x73)) /* TDT/TOT has b_syntax_indicator set to '0' */
(table_id != 0x70 && table_id != 0x73 && table_id != 0xFC)) /* TDT/TOT/SIS has b_syntax_indicator set to '0' */
{
/* Invalid section_syntax_indicator */
dvbpsi_error(p_dvbpsi, psz_table_name,
......
......@@ -191,7 +191,24 @@ dvbpsi_sis_t* dvbpsi_sis_new(uint8_t i_table_id, uint16_t i_extension, uint8_t i
*****************************************************************************/
void dvbpsi_sis_empty(dvbpsi_sis_t* p_sis)
{
/* FIXME: free splice_command_sections */
switch (p_sis->i_splice_command_type)
{
case 0x00: /* splice_null */
case 0x04: /* splice_schedule */
cmd_splice_schedule_cleanup(p_sis->p_splice_command);
break;
case 0x05: /* splice_insert */
cmd_splice_insert_cleanup(p_sis->p_splice_command);
break;
case 0x06: /* time_signal */
cmd_time_signal_cleanup(p_sis->p_splice_command);
break;
case 0x07: /* bandwidth_reservation */
break;
default:
break;
}
p_sis->p_splice_command = NULL;
dvbpsi_DeleteDescriptors(p_sis->p_first_descriptor);
p_sis->p_first_descriptor = NULL;
......@@ -312,7 +329,7 @@ static bool dvbpsi_AddSectionSIS(dvbpsi_t *p_dvbpsi, dvbpsi_sis_decoder_t *p_sis
/* Add to linked list of sections */
if (dvbpsi_decoder_psi_section_add(DVBPSI_DECODER(p_sis_decoder), p_section))
dvbpsi_debug(p_dvbpsi, "SDT decoder", "overwrite section number %d",
dvbpsi_debug(p_dvbpsi, "SIS decoder", "overwrite section number %d",
p_section->i_number);
return true;
......@@ -366,20 +383,6 @@ void dvbpsi_sis_sections_gather(dvbpsi_t *p_dvbpsi, dvbpsi_psi_section_t * p_sec
if (dvbpsi_CheckSIS(p_dvbpsi, p_sis_decoder, p_section))
dvbpsi_ReInitSIS(p_sis_decoder, true);
}
else
{
if( (p_sis_decoder->b_current_valid)
&& (p_sis_decoder->current_sis.i_version == p_section->i_version)
&& (p_sis_decoder->current_sis.b_current_next == p_section->b_current_next))
{
/* Don't decode since this version is already decoded */
dvbpsi_debug(p_dvbpsi, "SIT decoder",
"ignoring already decoded section %d",
p_section->i_number);
dvbpsi_DeletePSISections(p_section);
return;
}
}
}
/* Add section to SIS */
......@@ -402,7 +405,7 @@ void dvbpsi_sis_sections_gather(dvbpsi_t *p_dvbpsi, dvbpsi_psi_section_t * p_sec
/* Decode the sections */
dvbpsi_sis_sections_decode(p_dvbpsi, p_sis_decoder->p_building_sis,
p_sis_decoder->p_sections);
/* signal the new SDT */
/* signal the new SIS */
p_sis_decoder->pf_sis_callback(p_sis_decoder->p_priv,
p_sis_decoder->p_building_sis);
/* Delete sections and Reinitialize the structures */
......@@ -459,6 +462,27 @@ static void dvbpsi_sis_break_duration(uint8_t *p_data, dvbpsi_sis_break_duration
(uint64_t)p_data[4]);
}
/*****************************************************************************
* cmd_splice_insert_cleanup
*****************************************************************************
* Free resource for splice_insert command structure.
*****************************************************************************/
static void cmd_splice_insert_cleanup(dvbpsi_sis_cmd_splice_insert_t *p_cmd)
{
if (p_cmd)
{
dvbpsi_sis_component_splice_time_t *p_splice_time = p_cmd->p_splice_time;
while (p_splice_time != NULL)
{
dvbpsi_sis_component_splice_time_t *p_next = p_splice_time->p_next;
free(p_splice_time);
p_splice_time = p_next;
}
p_cmd->p_splice_time = NULL;
free(p_cmd);
}
}
/*****************************************************************************
* dvbpsi_sis_cmd_splice_insert_decode
*****************************************************************************
......@@ -574,21 +598,27 @@ error:
*****************************************************************************/
static void cmd_splice_schedule_cleanup(dvbpsi_sis_cmd_splice_schedule_t *p_cmd)
{
dvbpsi_sis_splice_event_t *p_event = p_cmd->p_splice_event;
while (p_event) {
dvbpsi_sis_splice_event_t *p_next = p_event->p_next;
if (p_event->p_component) {
dvbpsi_sis_component_t *p_time = p_event->p_component;
while (p_time) {
dvbpsi_sis_component_t *p_tmp = p_time->p_next;
free(p_time);
p_time = p_tmp;
if (p_cmd)
{
dvbpsi_sis_splice_event_t* p_event = p_cmd->p_splice_event;
while (p_event)
{
dvbpsi_sis_splice_event_t* p_next = p_event->p_next;
if (p_event->p_component)
{
dvbpsi_sis_component_t* p_time = p_event->p_component;
while (p_time)
{
dvbpsi_sis_component_t* p_tmp = p_time->p_next;
free(p_time);
p_time = p_tmp;
}
}
free(p_event);
p_event = p_next;
}
free(p_event);
p_event = p_next;
free(p_cmd);
}
free(p_cmd);
}
/*****************************************************************************
......@@ -683,6 +713,76 @@ static dvbpsi_sis_cmd_splice_schedule_t *
return p_cmd;
}
/*****************************************************************************
* cmd_time_signal_cleanup
*****************************************************************************
* Free resource for time_signal command structure.
*****************************************************************************/
static void cmd_time_signal_cleanup(dvbpsi_sis_cmd_time_signal_t *p_cmd)
{
if (p_cmd)
{
dvbpsi_sis_splice_time_t *p_splice_time = p_cmd->p_splice_time;
while (p_splice_time != NULL)
{
dvbpsi_sis_splice_time_t *p_next = p_splice_time->p_next;
free(p_splice_time);
p_splice_time = p_next;
}
p_cmd->p_splice_time = NULL;
free(p_cmd);
}
}
/*****************************************************************************
* dvbpsi_sis_cmd_time_signal_decode
*****************************************************************************
* time_signal command decoder.
*****************************************************************************/
static dvbpsi_sis_cmd_time_signal_t *
dvbpsi_sis_cmd_time_signal_decode(uint8_t *p_data, uint16_t i_length)
{
dvbpsi_sis_cmd_time_signal_t *p_cmd = calloc(1, sizeof(dvbpsi_sis_cmd_time_signal_t));
if (!p_cmd) return NULL;
if (i_length < 1)
{
cmd_time_signal_cleanup(p_cmd);
return NULL;
}
bool b_time_specified = false;
uint64_t i_pts_time = 0;
if ((p_data[0] & 0x80) == 0x80)
{
if (i_length < 5)
{
cmd_time_signal_cleanup(p_cmd);
return NULL;
}
b_time_specified = true;
i_pts_time = ((((uint64_t)p_data[0] & 0x01) << 32) |
((uint64_t)p_data[1] << 24) |
((uint64_t)p_data[2] << 16) |
((uint64_t)p_data[3] << 8) |
(uint64_t)p_data[4]);
}
p_cmd->p_splice_time = calloc(1, sizeof(dvbpsi_sis_splice_time_t));
if (p_cmd->p_splice_time == NULL)
{
cmd_time_signal_cleanup(p_cmd);
return NULL;
}
p_cmd->p_splice_time->b_time_specified_flag = b_time_specified;
p_cmd->p_splice_time->i_pts_time = i_pts_time;
p_cmd->p_splice_time->p_next = NULL;
return p_cmd;
}
/*****************************************************************************
* dvbpsi_sis_sections_decode
*****************************************************************************
......@@ -695,28 +795,29 @@ void dvbpsi_sis_sections_decode(dvbpsi_t* p_dvbpsi, dvbpsi_sis_t* p_sis,
while (p_section)
{
for (p_byte = p_section->p_payload_start + 3;
p_byte + 14 < p_section->p_payload_end; )
for (p_byte = p_section->p_payload_start;
p_byte + 17 <= p_section->p_payload_end; )
{
p_sis->i_protocol_version = p_byte[3];
p_sis->b_encrypted_packet = ((p_byte[4] & 0x80) == 0x80);
p_sis->i_protocol_version = p_byte[0];
p_sis->b_encrypted_packet = ((p_byte[1] & 0x80) == 0x80);
/* NOTE: cannot handle encrypted packet */
assert(p_sis->b_encrypted_packet);
assert(!p_sis->b_encrypted_packet);
if (p_sis->b_encrypted_packet) {
dvbpsi_error(p_dvbpsi, "SIS decoder", "cannot handle encrypted packets");
break;
}
p_sis->i_encryption_algorithm = ((p_byte[4] & 0x7E) >> 1);
p_sis->i_pts_adjustment = ((((uint64_t)p_byte[4] & 0x01) << 32) |
((uint64_t)p_byte[5] << 24) |
((uint64_t)p_byte[6] << 16) |
((uint64_t)p_byte[7] << 8) |
(uint64_t)p_byte[8]);
p_sis->cw_index = p_byte[9];
p_sis->i_splice_command_length = ((p_byte[11] & 0x0F) << 8) | p_byte[12];
p_sis->i_splice_command_type = p_byte[13];
if ((p_byte + 14 + p_sis->i_splice_command_length) >= p_section->p_payload_end) {
p_sis->i_encryption_algorithm = ((p_byte[1] & 0x7E) >> 1);
p_sis->i_pts_adjustment = ((((uint64_t)p_byte[1] & 0x01) << 32) |
((uint64_t)p_byte[2] << 24) |
((uint64_t)p_byte[3] << 16) |
((uint64_t)p_byte[4] << 8) |
(uint64_t)p_byte[5]);
p_sis->cw_index = p_byte[6];
p_sis->i_tier = (p_byte[7] << 4) | (p_byte[8] >> 4);
p_sis->i_splice_command_length = ((p_byte[8] & 0x0F) << 8) | p_byte[9];
p_sis->i_splice_command_type = p_byte[10];
if ((p_byte + 11 + p_sis->i_splice_command_length) >= p_section->p_payload_end) {
dvbpsi_error(p_dvbpsi, "SIS decoder", "corrupt section data");
break;
}
......@@ -730,7 +831,7 @@ void dvbpsi_sis_sections_decode(dvbpsi_t* p_dvbpsi, dvbpsi_sis_t* p_sis,
break;
case 0x04: /* splice_schedule */
p_sis->p_splice_command =
dvbpsi_sis_cmd_splice_schedule_decode(&p_byte[14],
dvbpsi_sis_cmd_splice_schedule_decode(&p_byte[11],
p_sis->i_splice_command_length);
if (!p_sis->p_splice_command)
dvbpsi_error(p_dvbpsi, "SIS decoder",
......@@ -738,13 +839,20 @@ void dvbpsi_sis_sections_decode(dvbpsi_t* p_dvbpsi, dvbpsi_sis_t* p_sis,
break;
case 0x05: /* splice_insert */
p_sis->p_splice_command =
dvbpsi_sis_cmd_splice_insert_decode(&p_byte[14],
dvbpsi_sis_cmd_splice_insert_decode(&p_byte[11],
p_sis->i_splice_command_length);
if (!p_sis->p_splice_command)
dvbpsi_error(p_dvbpsi, "SIS decoder",
"splice insert command is invalid");
break;
case 0x06: /* time_signal */
p_sis->p_splice_command =
dvbpsi_sis_cmd_time_signal_decode(&p_byte[11],
p_sis->i_splice_command_length);
if (!p_sis->p_splice_command)
dvbpsi_error(p_dvbpsi, "SIS decoder",
"time_signal command is invalid");
break;
case 0x07: /* bandwidth_reservation */
break;
default:
......@@ -753,13 +861,13 @@ void dvbpsi_sis_sections_decode(dvbpsi_t* p_dvbpsi, dvbpsi_sis_t* p_sis,
}
/* Service descriptors */
uint8_t *p_desc = p_byte + 14 + p_sis->i_splice_command_length;
uint8_t *p_desc = p_byte + 11 + p_sis->i_splice_command_length;
/* check our boundaries */
if (p_desc + 2 >= p_section->p_payload_end)
break;
p_sis->i_descriptors_length = (p_desc[0] << 8) | p_desc[1];
p_desc += 1;
p_desc += 2;
p_end = p_desc + p_sis->i_descriptors_length;
if (p_end > p_section->p_payload_end) break;
......
......@@ -72,6 +72,8 @@ typedef struct dvbpsi_sis_s
uint64_t i_pts_adjustment; /*!< PTS offset */
uint8_t cw_index; /*!< CA control word */
uint16_t i_tier; /*!< authorization tiers */
/* splice command */
uint16_t i_splice_command_length;/*!< Length of splice command */
uint8_t i_splice_command_type; /*!< Splice command type */
......
......@@ -59,6 +59,27 @@ void dvbpsi_sis_sections_gather(dvbpsi_t* p_dvbpsi, dvbpsi_psi_section_t* p_sect
void dvbpsi_sis_sections_decode(dvbpsi_t* p_dvbpsi, dvbpsi_sis_t* p_sis,
dvbpsi_psi_section_t* p_section);
/*****************************************************************************
* cmd_splice_schedule_cleanup
*****************************************************************************
* Free resource for splice_schedule command structure.
*****************************************************************************/
static void cmd_splice_schedule_cleanup(dvbpsi_sis_cmd_splice_schedule_t *p_cmd);
/*****************************************************************************
* cmd_splice_insert_cleanup
*****************************************************************************
* Free resource for splice_insert command structure.
*****************************************************************************/
static void cmd_splice_insert_cleanup(dvbpsi_sis_cmd_splice_insert_t *p_cmd);
/*****************************************************************************
* cmd_time_signal_cleanup
*****************************************************************************
* Free resource for time_signal command structure.
*****************************************************************************/
static void cmd_time_signal_cleanup(dvbpsi_sis_cmd_time_signal_t *p_cmd);
#else
#error "Multiple inclusions of sis_private.h"
#endif