From gitlab at videolan.org Sun Oct 20 16:01:11 2019 From: gitlab at videolan.org (Jean-Paul Saman) Date: Sun, 20 Oct 2019 16:01:11 +0200 Subject: [libdvbpsi-devel] [Git][videolan/libdvbpsi][master] 8 commits: Don't perform continuity check if there is no payload Message-ID: <5dac68a79028e_851e3f9869d9a9e09891ae@gitlab.mail> Jean-Paul Saman pushed to branch master at VideoLAN / libdvbpsi Commits: aff54341 by Olivier Braun at 2019-10-18T14:17:35Z Don't perform continuity check if there is no payload According to ISO 13818-1: The continuity_counter shall not be incremented when the adaptation_field_control of the packet equals '00' or '10'. - - - - - 26e371dd by Olivier Braun at 2019-10-18T14:27:16Z SIS also has b_syntax_indicator set to '0' ANSI/SCTE 35 2019r1: The section_syntax_indicator is a 1-bit field that should always be set to ‘0’, indicating that MPEG short sections are to be used. - - - - - eddc9b29 by Olivier Braun at 2019-10-18T15:39:58Z Bugfix: asset packet is NOT encrypted - - - - - 1bb2efe0 by Olivier Braun at 2019-10-18T20:45:29Z Add time_signal handling - - - - - c0a7a8c1 by Olivier Braun at 2019-10-18T20:55:23Z Disable long section checks >From SCTE 35:2019: The section_syntax_indicator is a 1-bit field that should always be set to ‘0’ >From ISO 13818-1: if the indicator is set to '0', then only the fields 'table_id' through 'private_section_length' shall follow the common structure syntax and semantics and the rest of the private_section may take any form the user determines. - - - - - 8fb730fd by Olivier Braun at 2019-10-18T22:37:36Z Fix splice_info_section decoding The 3 first bytes of the secion are already skipped in dvbpsi.c `p_section->p_payload_start = p_section->p_data + 3;` p_section->p_payload_start therefore points to the protocol_version field of the splice_info_section - - - - - 7d1b5361 by Jean-Paul Saman at 2019-10-19T17:53:23Z sis: dvbpsi_sis_cmd_time_signal_decode() initialize i_pts_time - - - - - f186f4b9 by Jean-Paul Saman at 2019-10-19T17:55:47Z AUTHORS: update - - - - - 6 changed files: - AUTHORS - src/dvbpsi.c - src/psi.c - src/tables/sis.c - src/tables/sis.h - src/tables/sis_private.h Changes: ===================================== AUTHORS ===================================== @@ -29,6 +29,10 @@ N: M. Benoit E: D: Generate descriptors 0x83, 0xa1 +N: O. Braun +E: +D: SIS table improvements + N: Roberto Corno E: corno.roberto at gmail.com D: Descriptors 0x40, 0x41, 0x49, 0x4a, 0x4b, 0x4f and 0x50 ===================================== src/dvbpsi.c ===================================== @@ -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]; ===================================== src/psi.c ===================================== @@ -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, ===================================== src/tables/sis.c ===================================== @@ -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; ===================================== src/tables/sis.h ===================================== @@ -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 */ ===================================== src/tables/sis_private.h ===================================== @@ -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 View it on GitLab: https://code.videolan.org/videolan/libdvbpsi/compare/36d88fa6abe60d3acfd1b038ecf89fcbc102fed0...f186f4b9df2f75fbba7ea9257553bbce1fd76e47 -- View it on GitLab: https://code.videolan.org/videolan/libdvbpsi/compare/36d88fa6abe60d3acfd1b038ecf89fcbc102fed0...f186f4b9df2f75fbba7ea9257553bbce1fd76e47 You're receiving this email because of your account on code.videolan.org.