From 5d7de2b8abe9002a0f90af80462a1132cefd0ba4 Mon Sep 17 00:00:00 2001 From: Georgi Chorbadzhiyski Date: Thu, 6 Oct 2011 12:50:59 +0300 Subject: [PATCH] mpeg/psi: Add support for TSDT (Transport Stream Descriptor Table). --- README | 1 + examples/dvb_gen_si.c | 41 ++++++++++++++++++ examples/dvb_print_si.c | 66 ++++++++++++++++++++++++++++ mpeg/psi.h | 1 + mpeg/psi/cat_print.h | 15 +++++-- mpeg/psi/tsdt.h | 95 +++++++++++++++++++++++++++++++++++++++++ mpeg/psi/tsdt_print.h | 48 +++++++++++++++++++++ mpeg/psi_print.h | 1 + 8 files changed, 264 insertions(+), 4 deletions(-) create mode 100644 mpeg/psi/tsdt.h create mode 100644 mpeg/psi/tsdt_print.h diff --git a/README b/README index fe19bc8..517b04b 100644 --- a/README +++ b/README @@ -46,6 +46,7 @@ Supported SI tables * Program Allocation Table (PAT) * Conditional Access Table (CAT) + * Transport Stream Descriptor Table (TSDT) * Program Map Table (PMT) * Network Information Table (NIT) * Bouquet Association Table (BAT) diff --git a/examples/dvb_gen_si.c b/examples/dvb_gen_si.c index 96c08a6..2f79930 100644 --- a/examples/dvb_gen_si.c +++ b/examples/dvb_gen_si.c @@ -845,6 +845,46 @@ static void generate_cat(void) { free(cat); } +/* MPEG Conditional Access Table (TSDT) */ +static void generate_tsdt(void) { + // Generate empty tsdt + uint8_t *tsdt = psi_allocate(); + uint8_t *desc; + uint8_t desc_loop[DESCS_HEADER_SIZE + DESCS_MAX_SIZE]; + uint8_t desc_counter; + + tsdt_init(tsdt); + tsdt_set_length(tsdt, 0); + psi_set_version(tsdt, 0); + psi_set_current(tsdt); + psi_set_crc(tsdt); + output_psi_section(tsdt, TSDT_PID, &cc); + + // Add couple of descriptors to TSDT + psi_set_version(tsdt, 1); + psi_set_current(tsdt); + psi_set_length(tsdt, PSI_MAX_SIZE); + + descs_set_length(desc_loop, DESCS_MAX_SIZE); + desc_counter = 0; + + desc = descs_get_desc(desc_loop, desc_counter++); + build_desc0f(desc); + + // Finish descriptor generation + desc = descs_get_desc(desc_loop, desc_counter); // Get next descriptor pos + descs_set_length(desc_loop, desc - desc_loop - DESCS_HEADER_SIZE); + tsdt_set_desclength(tsdt, descs_get_length(desc_loop)); + // Put descriptor loop into TSDT + memcpy(tsdt_get_descl(tsdt), desc_loop + DESCS_HEADER_SIZE, + descs_get_length(desc_loop)); + + psi_set_crc(tsdt); + output_psi_section(tsdt, TSDT_PID, &cc); + + free(tsdt); +} + /* DVB Network Information Table (NIT) */ static void generate_nit(void) { uint8_t *nit = psi_allocate(); @@ -1791,6 +1831,7 @@ int main(void) { generate_pat(); generate_cat(); + generate_tsdt(); generate_nit(); generate_bat(); generate_sdt(); diff --git a/examples/dvb_print_si.c b/examples/dvb_print_si.c index 264d270..ac06a23 100644 --- a/examples/dvb_print_si.c +++ b/examples/dvb_print_si.c @@ -69,6 +69,8 @@ static PSI_TABLE_DECLARE(pp_current_pat_sections); static PSI_TABLE_DECLARE(pp_next_pat_sections); static PSI_TABLE_DECLARE(pp_current_cat_sections); static PSI_TABLE_DECLARE(pp_next_cat_sections); +static PSI_TABLE_DECLARE(pp_current_tsdt_sections); +static PSI_TABLE_DECLARE(pp_next_tsdt_sections); static PSI_TABLE_DECLARE(pp_current_nit_sections); static PSI_TABLE_DECLARE(pp_next_nit_sections); static PSI_TABLE_DECLARE(pp_current_bat_sections); @@ -343,6 +345,65 @@ static void handle_cat_section(uint16_t i_pid, uint8_t *p_section) handle_cat(); } +/***************************************************************************** + * handle_tsdt + *****************************************************************************/ +static void handle_tsdt(void) +{ + PSI_TABLE_DECLARE(pp_old_tsdt_sections); + + if (psi_table_validate(pp_current_tsdt_sections) && + psi_table_compare(pp_current_tsdt_sections, pp_next_tsdt_sections)) { + /* Identical TSDT. Shortcut. */ + psi_table_free(pp_next_tsdt_sections); + psi_table_init(pp_next_tsdt_sections); + return; + } + + if (!tsdt_table_validate(pp_next_tsdt_sections)) { + switch (i_print_type) { + case PRINT_XML: + printf("\n"); + break; + default: + printf("invalid TSDT received\n"); + } + psi_table_free(pp_next_tsdt_sections); + psi_table_init(pp_next_tsdt_sections); + return; + } + + /* Switch tables. */ + psi_table_copy(pp_old_tsdt_sections, pp_current_tsdt_sections); + psi_table_copy(pp_current_tsdt_sections, pp_next_tsdt_sections); + psi_table_init(pp_next_tsdt_sections); + + if (psi_table_validate(pp_old_tsdt_sections)) + psi_table_free(pp_old_tsdt_sections); + + tsdt_table_print(pp_current_tsdt_sections, print_wrapper, NULL, i_print_type); +} + +static void handle_tsdt_section(uint16_t i_pid, uint8_t *p_section) +{ + if (i_pid != TSDT_PID || !tsdt_validate(p_section)) { + switch (i_print_type) { + case PRINT_XML: + printf("\n"); + break; + default: + printf("invalid TSDT section received on PID %hu\n", i_pid); + } + free(p_section); + return; + } + + if (!psi_table_section(pp_next_tsdt_sections, p_section)) + return; + + handle_tsdt(); +} + /***************************************************************************** * handle_pmt *****************************************************************************/ @@ -725,6 +786,10 @@ static void handle_section(uint16_t i_pid, uint8_t *p_section) handle_cat_section(i_pid, p_section); break; + case TSDT_TABLE_ID: + handle_tsdt_section(i_pid, p_section); + break; + case PMT_TABLE_ID: handle_pmt(i_pid, p_section); break; @@ -852,6 +917,7 @@ int main(int i_argc, char **ppsz_argv) p_pids[PAT_PID].i_psi_refcount++; p_pids[CAT_PID].i_psi_refcount++; + p_pids[TSDT_PID].i_psi_refcount++; p_pids[NIT_PID].i_psi_refcount++; p_pids[BAT_PID].i_psi_refcount++; p_pids[SDT_PID].i_psi_refcount++; diff --git a/mpeg/psi.h b/mpeg/psi.h index a269f9e..e087706 100644 --- a/mpeg/psi.h +++ b/mpeg/psi.h @@ -40,6 +40,7 @@ #include #include #include +#include #include #endif diff --git a/mpeg/psi/cat_print.h b/mpeg/psi/cat_print.h index 28a10f0..e2e381b 100644 --- a/mpeg/psi/cat_print.h +++ b/mpeg/psi/cat_print.h @@ -33,6 +33,7 @@ #include #include #include +#include #ifdef __cplusplus extern "C" @@ -44,15 +45,21 @@ static inline void cat_table_print(uint8_t **pp_sections, f_print pf_print, { uint8_t i_last_section = psi_table_get_lastsection(pp_sections); uint8_t i; + char *psz_table_name = "CAT"; + + if (psi_get_tableid(psi_table_get_section(pp_sections, 0)) == TSDT_TABLE_ID) + psz_table_name = "TSDT"; switch (i_print_type) { case PRINT_XML: - pf_print(opaque, "", + pf_print(opaque, "<%s version=\"%hhu\" current_next=\"%d\">", + psz_table_name, psi_table_get_version(pp_sections), !psi_table_get_current(pp_sections) ? 0 : 1); break; default: - pf_print(opaque, "new CAT version=%hhu%s", + pf_print(opaque, "new %s version=%hhu%s", + psz_table_name, psi_table_get_version(pp_sections), !psi_table_get_current(pp_sections) ? " (next)" : ""); } @@ -66,10 +73,10 @@ static inline void cat_table_print(uint8_t **pp_sections, f_print pf_print, switch (i_print_type) { case PRINT_XML: - pf_print(opaque, ""); + pf_print(opaque, "", psz_table_name); break; default: - pf_print(opaque, "end CAT"); + pf_print(opaque, "end %s", psz_table_name); } } diff --git a/mpeg/psi/tsdt.h b/mpeg/psi/tsdt.h new file mode 100644 index 0000000..cf892cb --- /dev/null +++ b/mpeg/psi/tsdt.h @@ -0,0 +1,95 @@ +/***************************************************************************** + * tsdt.h: ISO/IEC 13818-1 Transport stream descriptor table (TSDT) + ***************************************************************************** + * Copyright (C) 2011 Unix Solutions Ltd. + * + * Authors: Georgi Chorbadzhiyski + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject + * to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + *****************************************************************************/ + +/* + * Normative references: + * - ISO/IEC 13818-1:2007(E) (MPEG-2 Systems) + */ + +#ifndef __BITSTREAM_MPEG_TSDT_H__ +#define __BITSTREAM_MPEG_TSDT_H__ + +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" +{ +#endif + +/***************************************************************************** + * Transport stream descriptor table + *****************************************************************************/ +#define TSDT_PID 0x02 +#define TSDT_TABLE_ID 0x03 +#define TSDT_HEADER_SIZE PSI_HEADER_SIZE_SYNTAX1 + +static inline void tsdt_init(uint8_t *p_tsdt) +{ + psi_init(p_tsdt, true); + psi_set_tableid(p_tsdt, TSDT_TABLE_ID); + p_tsdt[1] &= ~0x40; + psi_set_tableidext(p_tsdt, 0xffff); + psi_set_section(p_tsdt, 0); + psi_set_lastsection(p_tsdt, 0); +} + +#define tsdt_set_length cat_set_length +#define tsdt_get_desclength cat_get_desclength +#define tsdt_set_desclength cat_set_desclength +#define tsdt_get_descl cat_get_descl +#define tsdt_get_descl_const cat_get_descl_const + +static inline bool tsdt_validate(const uint8_t *p_tsdt) +{ + uint16_t i_section_size = psi_get_length(p_tsdt) + PSI_HEADER_SIZE + - PSI_CRC_SIZE; + + if (!psi_get_syntax(p_tsdt) || psi_get_section(p_tsdt) + || psi_get_lastsection(p_tsdt) + || psi_get_tableid(p_tsdt) != TSDT_TABLE_ID) + return false; + + if (i_section_size < TSDT_HEADER_SIZE + || i_section_size < TSDT_HEADER_SIZE + tsdt_get_desclength(p_tsdt)) + return false; + + if (!descl_validate(tsdt_get_descl_const(p_tsdt), tsdt_get_desclength(p_tsdt))) + return false; + + return true; +} + +#define tsdt_table_validate cat_table_validate + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/mpeg/psi/tsdt_print.h b/mpeg/psi/tsdt_print.h new file mode 100644 index 0000000..1ff1ff6 --- /dev/null +++ b/mpeg/psi/tsdt_print.h @@ -0,0 +1,48 @@ +/***************************************************************************** + * tsdt_print.h: ISO/IEC 13818-1 Transport stream descriptor table (printing) + ***************************************************************************** + * Copyright (C) 2011 Unix Solutions Ltd. + * + * Authors: Georgi Chorbadzhiyski + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject + * to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + *****************************************************************************/ + +#ifndef __BITSTREAM_MPEG_TSDT_PRINT_H__ +#define __BITSTREAM_MPEG_TSDT_PRINT_H__ + +#include +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" +{ +#endif + +#define tsdt_table_print cat_table_print + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/mpeg/psi_print.h b/mpeg/psi_print.h index 73f495a..e03e9bf 100644 --- a/mpeg/psi_print.h +++ b/mpeg/psi_print.h @@ -32,6 +32,7 @@ #include #include #include +#include #include #endif