Commit 24309a1e authored by Jean-Paul Saman's avatar Jean-Paul Saman

SIS: implement splice_insert command decoder

The splice_insert command decoder is implemented in function dvbpsi_sis_cmd_splice_insert_decode().
parent 57e76567
...@@ -411,6 +411,96 @@ void dvbpsi_sis_sections_gather(dvbpsi_t *p_dvbpsi, dvbpsi_psi_section_t * p_sec ...@@ -411,6 +411,96 @@ void dvbpsi_sis_sections_gather(dvbpsi_t *p_dvbpsi, dvbpsi_psi_section_t * p_sec
} }
} }
/*****************************************************************************
* dvbpsi_sis_cmd_splice_insert_decode
*****************************************************************************
* splice_schedule command decoder.
*****************************************************************************/
static dvbpsi_sis_cmd_splice_insert_t *
dvbpsi_sis_cmd_splice_insert_decode(uint8_t *p_data, uint16_t i_length)
{
dvbpsi_sis_cmd_splice_insert_t *p_cmd = calloc(1, sizeof(dvbpsi_sis_cmd_splice_insert_t));
if (!p_cmd) return NULL;
p_cmd->i_splice_event_id = (((uint32_t)p_data[0] << 24) |
((uint32_t)p_data[1] << 16) |
((uint32_t)p_data[2] << 8) |
(uint32_t)p_data[3]);
p_cmd->b_splice_event_cancel_indicator = (p_data[4] & 0x80);
if (!p_cmd->b_splice_event_cancel_indicator) {
p_cmd->b_out_of_network_indicator = (p_data[5] & 0x80);
p_cmd->b_program_splice_flag = (p_data[5] & 0x40);
p_cmd->b_duration_flag = (p_data[5] & 0x20);
p_cmd->b_splice_immediate_flag = (p_data[5] & 0x10);
uint16_t pos = 6;
if (p_cmd->b_program_splice_flag && !p_cmd->b_splice_immediate_flag) {
/* splice_time () */
p_cmd->i_splice_time.b_time_specified_flag = (p_data[pos] & 0x80);
if (p_cmd->i_splice_time.b_time_specified_flag) {
p_cmd->i_splice_time.i_pts_time =
(((uint64_t)(p_data[pos] & 0x01) << 32) |
((uint64_t)p_data[pos + 1] << 24) |
((uint64_t)p_data[pos + 2] << 16) |
((uint64_t)p_data[pos + 3] << 8) |
(uint64_t)p_data[pos + 4]);
pos += 5;
}
else
pos++;
p_cmd->i_splice_time.p_next = NULL;
}
if (!p_cmd->b_program_splice_flag) {
p_cmd->i_component_count = p_data[pos];
dvbpsi_sis_component_splice_time_t *p_splice_time = p_cmd->p_splice_time;
for (uint8_t i = 0; i < p_cmd->i_component_count; i++) {
p_splice_time = (dvbpsi_sis_component_splice_time_t *)
calloc(1, sizeof(dvbpsi_sis_component_splice_time_t));
if (!p_splice_time) {
/* partially decoded */
p_cmd->i_component_count = (i > 0) ? i - 1 : 0;
break;
}
p_splice_time->i_component_tag = p_data[pos++];
if (!p_cmd->b_splice_immediate_flag) {
/* splice_time */
p_splice_time->i_splice_time.b_time_specified_flag = (p_data[pos] & 0x80);
if (p_splice_time->i_splice_time.b_time_specified_flag) {
p_splice_time->i_splice_time.i_pts_time =
(((uint64_t)(p_data[pos] & 0x01) << 32) |
((uint64_t)p_data[pos + 1] << 24) |
((uint64_t)p_data[pos + 2] << 16) |
((uint64_t)p_data[pos + 3] << 8) |
(uint64_t)p_data[pos + 4]);
pos += 5;
}
else
pos++;
}
p_splice_time = p_splice_time->p_next;
/* Check if we have an overflow */
assert(pos < i_length);
}
}
if (p_cmd->b_duration_flag) {
/* break duration */
p_cmd->i_break_duration.b_auto_return = (p_data[pos] & 0x80);
p_cmd->i_break_duration.i_duration =
((((uint64_t)p_data[pos] & 0x01) << 32) |
((uint64_t)p_data[pos + 1] << 24) |
((uint64_t)p_data[pos + 2] << 16) |
((uint64_t)p_data[pos + 3] << 8) |
(uint64_t)p_data[pos + 4]);
pos += 5;
}
p_cmd->i_unique_program_id = (((uint16_t)p_data[pos] << 8) |
(uint16_t)p_data[pos+1]);
pos += 2;
p_cmd->i_avail_num = p_data[pos];
p_cmd->i_avails_expected = p_data[pos];
}
return p_cmd;
}
/***************************************************************************** /*****************************************************************************
* cmd_splice_schedule_cleanup * cmd_splice_schedule_cleanup
***************************************************************************** *****************************************************************************
...@@ -468,7 +558,10 @@ static dvbpsi_sis_cmd_splice_schedule_t * ...@@ -468,7 +558,10 @@ static dvbpsi_sis_cmd_splice_schedule_t *
/* 5 reserved bits */ /* 5 reserved bits */
if (p_event->b_program_splice_flag) { if (p_event->b_program_splice_flag) {
/* utc_splice_time */ /* utc_splice_time */
p_event->i_utc_splice_time = p_data[pos]; p_event->i_utc_splice_time = (((uint32_t)p_data[pos ] << 24) |
((uint32_t)p_data[pos+1] << 16) |
((uint32_t)p_data[pos+2] << 8) |
(uint32_t)p_data[pos+3]);
pos += 4; pos += 4;
} }
else { /* component */ else { /* component */
...@@ -482,7 +575,7 @@ static dvbpsi_sis_cmd_splice_schedule_t * ...@@ -482,7 +575,7 @@ static dvbpsi_sis_cmd_splice_schedule_t *
} }
for (uint8_t j = 0; j < p_event->i_component_count; j++) { for (uint8_t j = 0; j < p_event->i_component_count; j++) {
p_time = malloc(sizeof(dvbpsi_sis_component_t)); p_time = (dvbpsi_sis_component_t *) calloc(1, sizeof(dvbpsi_sis_component_t));
if (!p_time) { if (!p_time) {
cmd_splice_schedule_cleanup(p_cmd); cmd_splice_schedule_cleanup(p_cmd);
return NULL; return NULL;
...@@ -502,6 +595,7 @@ static dvbpsi_sis_cmd_splice_schedule_t * ...@@ -502,6 +595,7 @@ static dvbpsi_sis_cmd_splice_schedule_t *
((uint64_t)p_data[pos + 2] << 16) | ((uint64_t)p_data[pos + 2] << 16) |
((uint64_t)p_data[pos + 3] << 8) | ((uint64_t)p_data[pos + 3] << 8) |
(uint64_t)p_data[pos + 4]); (uint64_t)p_data[pos + 4]);
pos += 5;
} }
p_event->i_unique_program_id = p_data[pos]; p_event->i_unique_program_id = p_data[pos];
pos += 2; pos += 2;
...@@ -565,9 +659,15 @@ void dvbpsi_sis_sections_decode(dvbpsi_t* p_dvbpsi, dvbpsi_sis_t* p_sis, ...@@ -565,9 +659,15 @@ void dvbpsi_sis_sections_decode(dvbpsi_t* p_dvbpsi, dvbpsi_sis_t* p_sis,
if (!p_sis->p_splice_command) if (!p_sis->p_splice_command)
dvbpsi_error(p_dvbpsi, "SIS decoder", dvbpsi_error(p_dvbpsi, "SIS decoder",
"splice schedule command is invalid"); "splice schedule command is invalid");
/* somthing went wrong */
break; break;
case 0x05: /* splice_insert */ case 0x05: /* splice_insert */
p_sis->p_splice_command =
dvbpsi_sis_cmd_splice_insert_decode(&p_byte[14],
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 */ case 0x06: /* time_signal */
case 0x07: /* bandwidth_reservation */ case 0x07: /* bandwidth_reservation */
break; break;
......
...@@ -264,7 +264,7 @@ struct dvbpsi_sis_component_splice_time_s ...@@ -264,7 +264,7 @@ struct dvbpsi_sis_component_splice_time_s
the Splice Point specified by the value of the Splice Point specified by the value of
splice_time() that follows. */ splice_time() that follows. */
/* if (splice_immediate_flag) */ /* if (splice_immediate_flag) */
dvbpsi_sis_splice_time_t *p_splice_time; /*!< splice time defintions */ dvbpsi_sis_splice_time_t i_splice_time; /*!< splice time defintions */
/* */ /* */
dvbpsi_sis_component_splice_time_t *p_next; /*!< next in list */ dvbpsi_sis_component_splice_time_t *p_next; /*!< next in list */
...@@ -278,7 +278,8 @@ struct dvbpsi_sis_component_splice_time_s ...@@ -278,7 +278,8 @@ struct dvbpsi_sis_component_splice_time_s
* \struct dvbpsi_sis_cmd_splice_insert_s * \struct dvbpsi_sis_cmd_splice_insert_s
* \brief splice_insert() splice command definition * \brief splice_insert() splice command definition
*/ */
typedef struct dvbpsi_sis_cmd_splice_insert_s typedef struct dvbpsi_sis_cmd_splice_insert_s dvbpsi_sis_cmd_splice_insert_t;
struct dvbpsi_sis_cmd_splice_insert_s
{ {
uint32_t i_splice_event_id; /*!< splice event identifier */ uint32_t i_splice_event_id; /*!< splice event identifier */
bool b_splice_event_cancel_indicator; /*!< cancels splice event when true */ bool b_splice_event_cancel_indicator; /*!< cancels splice event when true */
...@@ -290,25 +291,30 @@ typedef struct dvbpsi_sis_cmd_splice_insert_s ...@@ -290,25 +291,30 @@ typedef struct dvbpsi_sis_cmd_splice_insert_s
bool b_splice_immediate_flag; /*!< signals immediate splice insertion */ bool b_splice_immediate_flag; /*!< signals immediate splice insertion */
/* if (b_program_splice_flag) && (!b_splice_immediate_flag) */ /* if (b_program_splice_flag) && (!b_splice_immediate_flag) */
dvbpsi_sis_splice_time_t *p_splice_time; /*!< splice time */ dvbpsi_sis_splice_time_t i_splice_time; /*!< splice time */
/* if (!b_program_splice_flag) */ /* if (!b_program_splice_flag) */
uint8_t i_component_count; /*!< number of stream PID in the following loop. uint8_t i_component_count; /*!< number of stream PID in the following
A component is equivalent to elementary stream PIDs.*/ loop. A component is equivalent to
dvbpsi_sis_component_splice_time_t *p_data; /*!< identifies the elementary PID stream containing elementary stream PIDs.*/
dvbpsi_sis_component_splice_time_t *p_splice_time;
/*!< identifies the elementary PID stream containing
the Splice Point specified by the value of the Splice Point specified by the value of
splice_time() that follows. */ splice_time() that follows. */
/* if (b_duration_flag) */
dvbpsi_sis_break_duration_t *p_break_duration; /*!< break duration is present when b_duration_flag is set */
/* if (b_duration_flag) */
dvbpsi_sis_break_duration_t i_break_duration; /*!< break duration is present when
b_duration_flag is set */
/* */ /* */
uint16_t i_unique_program_id; /*!< provide a unique identification for a viewing event */
uint8_t i_avail_num; /*!< identification for a specific avail within uint16_t i_unique_program_id; /*!< provide a unique identification for
one unique_program_id. */ a viewing event */
uint8_t i_avails_expected; /*!< count of the expected number of individual avails uint8_t i_avail_num; /*!< identification for a specific
within the current viewing event */ avail within one unique_program_id. */
uint8_t i_avails_expected; /*!< count of the expected number of individual
avails within the current viewing event */
/* end */ /* end */
} dvbpsi_sis_cmd_splice_insert_t; };
/*! /*!
* \typedef struct dvbpsi_sis_cmd_time_signal_s dvbpsi_sis_cmd_time_signal_t * \typedef struct dvbpsi_sis_cmd_time_signal_s dvbpsi_sis_cmd_time_signal_t
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment