From effeceed0aa044d09e32725ae92023c86aa2f59e Mon Sep 17 00:00:00 2001 From: Christophe Massiot Date: Mon, 10 Oct 2011 12:53:08 +0300 Subject: [PATCH] mpeg/psi: Move PAT functions out to mpeg/psi/pat{_print}.h --- mpeg/psi.h | 175 +------------------------------------------ mpeg/psi/pat.h | 168 +++++++++++++++++++++++++++++++++++++++++ mpeg/psi/pat_print.h | 100 +++++++++++++++++++++++++ mpeg/psi_print.h | 1 + 4 files changed, 270 insertions(+), 174 deletions(-) create mode 100644 mpeg/psi/pat.h create mode 100644 mpeg/psi/pat_print.h diff --git a/mpeg/psi.h b/mpeg/psi.h index b3bf069..1a35a25 100644 --- a/mpeg/psi.h +++ b/mpeg/psi.h @@ -38,6 +38,7 @@ #include #include #include +#include #ifdef __cplusplus extern "C" @@ -190,180 +191,6 @@ static inline void desc0a_print(uint8_t *p_desc, f_print pf_print, } } -/***************************************************************************** - * Program Association Table - *****************************************************************************/ -#define PAT_PID 0x0 -#define PAT_TABLE_ID 0x0 -#define PAT_HEADER_SIZE PSI_HEADER_SIZE_SYNTAX1 -#define PAT_PROGRAM_SIZE 4 - -#define pat_set_tsid psi_set_tableidext -#define pat_get_tsid psi_get_tableidext - -static inline void pat_init(uint8_t *p_pat) -{ - psi_init(p_pat, true); - psi_set_tableid(p_pat, PAT_TABLE_ID); - p_pat[1] &= ~0x40; -} - -static inline void pat_set_length(uint8_t *p_pat, uint16_t i_pat_length) -{ - psi_set_length(p_pat, PAT_HEADER_SIZE + PSI_CRC_SIZE - PSI_HEADER_SIZE - + i_pat_length); -} - -static inline void patn_init(uint8_t *p_pat_n) -{ - p_pat_n[2] = 0xe0; -} - -static inline void patn_set_program(uint8_t *p_pat_n, uint16_t i_program) -{ - p_pat_n[0] = i_program >> 8; - p_pat_n[1] = i_program & 0xff; -} - -static inline uint16_t patn_get_program(const uint8_t *p_pat_n) -{ - return (p_pat_n[0] << 8) | p_pat_n[1]; -} - -static inline void patn_set_pid(uint8_t *p_pat_n, uint16_t i_pid) -{ - p_pat_n[2] &= ~0x1f; - p_pat_n[2] |= i_pid >> 8; - p_pat_n[3] = i_pid & 0xff; -} - -static inline uint16_t patn_get_pid(const uint8_t *p_pat_n) -{ - return ((p_pat_n[2] & 0x1f) << 8) | p_pat_n[3]; -} - -static inline uint8_t *pat_get_program(uint8_t *p_pat, uint8_t n) -{ - uint8_t *p_pat_n = p_pat + PAT_HEADER_SIZE + n * PAT_PROGRAM_SIZE; - if (p_pat_n + PAT_PROGRAM_SIZE - p_pat - > psi_get_length(p_pat) + PSI_HEADER_SIZE - PSI_CRC_SIZE) - return NULL; - return p_pat_n; -} - -static inline bool pat_validate(const uint8_t *p_pat) -{ - if (!psi_get_syntax(p_pat) || psi_get_tableid(p_pat) != PAT_TABLE_ID) - return false; - if ((psi_get_length(p_pat) - PAT_HEADER_SIZE + PSI_HEADER_SIZE - - PSI_CRC_SIZE) % PAT_PROGRAM_SIZE) - return false; - - return true; -} - -static inline uint8_t *pat_table_find_program(uint8_t **pp_sections, - uint16_t i_program) -{ - uint8_t i_last_section = psi_table_get_lastsection(pp_sections); - uint8_t i; - - for (i = 0; i <= i_last_section; i++) { - uint8_t *p_section = psi_table_get_section(pp_sections, i); - uint8_t *p_program; - int j = 0; - - while ((p_program = pat_get_program(p_section, j)) != NULL) { - j++; - if (patn_get_program(p_program) == i_program) - return p_program; - } - } - - return NULL; -} - -static inline bool pat_table_validate(uint8_t **pp_sections) -{ - uint8_t i_last_section = psi_table_get_lastsection(pp_sections); - uint8_t i; - - for (i = 0; i <= i_last_section; i++) { - uint8_t *p_section = psi_table_get_section(pp_sections, i); - uint8_t *p_program; - int j = 0; - - if (!psi_check_crc(p_section)) - return false; - - while ((p_program = pat_get_program(p_section, j)) != NULL) { - uint8_t *p_program2 = pat_table_find_program(pp_sections, - patn_get_program(p_program)); - j++; - /* check that the program number is not already in the table - * with another PID */ - if (patn_get_pid(p_program) != patn_get_pid(p_program2)) - return false; - } - } - - return true; -} - -static inline void pat_table_print(uint8_t **pp_sections, f_print pf_print, - void *opaque, print_type_t i_print_type) -{ - uint8_t i_last_section = psi_table_get_lastsection(pp_sections); - uint8_t i; - - switch (i_print_type) { - case PRINT_XML: - pf_print(opaque, "", - psi_table_get_tableidext(pp_sections), - psi_table_get_version(pp_sections), - !psi_table_get_current(pp_sections) ? 0 : 1); - break; - default: - pf_print(opaque, "new PAT tsid=%hu version=%hhu%s", - psi_table_get_tableidext(pp_sections), - psi_table_get_version(pp_sections), - !psi_table_get_current(pp_sections) ? " (next)" : ""); - } - - for (i = 0; i <= i_last_section; i++) { - uint8_t *p_section = psi_table_get_section(pp_sections, i); - const uint8_t *p_program; - int j = 0; - - while ((p_program = pat_get_program(p_section, j)) != NULL) { - uint16_t i_program = patn_get_program(p_program); - uint16_t i_pid = patn_get_pid(p_program); - j++; - switch (i_print_type) { - case PRINT_XML: - pf_print(opaque, "", - i_program, i_pid); - break; - default: - if (i_program == 0) - pf_print(opaque, " * NIT pid=%hu", i_pid); - else - pf_print(opaque, " * program number=%hu pid=%hu", - i_program, i_pid); - } - } - } - - - switch (i_print_type) { - case PRINT_XML: - pf_print(opaque, ""); - break; - default: - pf_print(opaque, "end PAT"); - } -} - /***************************************************************************** * Conditional Access Table *****************************************************************************/ diff --git a/mpeg/psi/pat.h b/mpeg/psi/pat.h new file mode 100644 index 0000000..f245de1 --- /dev/null +++ b/mpeg/psi/pat.h @@ -0,0 +1,168 @@ +/***************************************************************************** + * pat.h: ISO/IEC 13818-1 Program Allocation Table (PAT) + ***************************************************************************** + * Copyright (C) 2009-2010 VideoLAN + * + * Authors: Christophe Massiot + * + * 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_PAT_H__ +#define __BITSTREAM_MPEG_PAT_H__ + +#include +#include + +#ifdef __cplusplus +extern "C" +{ +#endif + +/***************************************************************************** + * Program Association Table + *****************************************************************************/ +#define PAT_PID 0x0 +#define PAT_TABLE_ID 0x0 +#define PAT_HEADER_SIZE PSI_HEADER_SIZE_SYNTAX1 +#define PAT_PROGRAM_SIZE 4 + +#define pat_set_tsid psi_set_tableidext +#define pat_get_tsid psi_get_tableidext + +static inline void pat_init(uint8_t *p_pat) +{ + psi_init(p_pat, true); + psi_set_tableid(p_pat, PAT_TABLE_ID); + p_pat[1] &= ~0x40; +} + +static inline void pat_set_length(uint8_t *p_pat, uint16_t i_pat_length) +{ + psi_set_length(p_pat, PAT_HEADER_SIZE + PSI_CRC_SIZE - PSI_HEADER_SIZE + + i_pat_length); +} + +static inline void patn_init(uint8_t *p_pat_n) +{ + p_pat_n[2] = 0xe0; +} + +static inline void patn_set_program(uint8_t *p_pat_n, uint16_t i_program) +{ + p_pat_n[0] = i_program >> 8; + p_pat_n[1] = i_program & 0xff; +} + +static inline uint16_t patn_get_program(const uint8_t *p_pat_n) +{ + return (p_pat_n[0] << 8) | p_pat_n[1]; +} + +static inline void patn_set_pid(uint8_t *p_pat_n, uint16_t i_pid) +{ + p_pat_n[2] &= ~0x1f; + p_pat_n[2] |= i_pid >> 8; + p_pat_n[3] = i_pid & 0xff; +} + +static inline uint16_t patn_get_pid(const uint8_t *p_pat_n) +{ + return ((p_pat_n[2] & 0x1f) << 8) | p_pat_n[3]; +} + +static inline uint8_t *pat_get_program(uint8_t *p_pat, uint8_t n) +{ + uint8_t *p_pat_n = p_pat + PAT_HEADER_SIZE + n * PAT_PROGRAM_SIZE; + if (p_pat_n + PAT_PROGRAM_SIZE - p_pat + > psi_get_length(p_pat) + PSI_HEADER_SIZE - PSI_CRC_SIZE) + return NULL; + return p_pat_n; +} + +static inline bool pat_validate(const uint8_t *p_pat) +{ + if (!psi_get_syntax(p_pat) || psi_get_tableid(p_pat) != PAT_TABLE_ID) + return false; + if ((psi_get_length(p_pat) - PAT_HEADER_SIZE + PSI_HEADER_SIZE + - PSI_CRC_SIZE) % PAT_PROGRAM_SIZE) + return false; + + return true; +} + +static inline uint8_t *pat_table_find_program(uint8_t **pp_sections, + uint16_t i_program) +{ + uint8_t i_last_section = psi_table_get_lastsection(pp_sections); + uint8_t i; + + for (i = 0; i <= i_last_section; i++) { + uint8_t *p_section = psi_table_get_section(pp_sections, i); + uint8_t *p_program; + int j = 0; + + while ((p_program = pat_get_program(p_section, j)) != NULL) { + j++; + if (patn_get_program(p_program) == i_program) + return p_program; + } + } + + return NULL; +} + +static inline bool pat_table_validate(uint8_t **pp_sections) +{ + uint8_t i_last_section = psi_table_get_lastsection(pp_sections); + uint8_t i; + + for (i = 0; i <= i_last_section; i++) { + uint8_t *p_section = psi_table_get_section(pp_sections, i); + uint8_t *p_program; + int j = 0; + + if (!psi_check_crc(p_section)) + return false; + + while ((p_program = pat_get_program(p_section, j)) != NULL) { + uint8_t *p_program2 = pat_table_find_program(pp_sections, + patn_get_program(p_program)); + j++; + /* check that the program number is not already in the table + * with another PID */ + if (patn_get_pid(p_program) != patn_get_pid(p_program2)) + return false; + } + } + + return true; +} + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/mpeg/psi/pat_print.h b/mpeg/psi/pat_print.h new file mode 100644 index 0000000..2cd397b --- /dev/null +++ b/mpeg/psi/pat_print.h @@ -0,0 +1,100 @@ +/***************************************************************************** + * pat_print.h: ISO/IEC 13818-1 Program Allocation Table (PAT) (printing) + ***************************************************************************** + * Copyright (C) 2009-2010 VideoLAN + * + * Authors: Christophe Massiot + * + * 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_PAT_PRINT_H__ +#define __BITSTREAM_MPEG_PAT_PRINT_H__ + +#include +#include +#include + +#ifdef __cplusplus +extern "C" +{ +#endif + +/***************************************************************************** + * Program Association Table + *****************************************************************************/ +static inline void pat_table_print(uint8_t **pp_sections, f_print pf_print, + void *opaque, print_type_t i_print_type) +{ + uint8_t i_last_section = psi_table_get_lastsection(pp_sections); + uint8_t i; + + switch (i_print_type) { + case PRINT_XML: + pf_print(opaque, "", + psi_table_get_tableidext(pp_sections), + psi_table_get_version(pp_sections), + !psi_table_get_current(pp_sections) ? 0 : 1); + break; + default: + pf_print(opaque, "new PAT tsid=%hu version=%hhu%s", + psi_table_get_tableidext(pp_sections), + psi_table_get_version(pp_sections), + !psi_table_get_current(pp_sections) ? " (next)" : ""); + } + + for (i = 0; i <= i_last_section; i++) { + uint8_t *p_section = psi_table_get_section(pp_sections, i); + const uint8_t *p_program; + int j = 0; + + while ((p_program = pat_get_program(p_section, j)) != NULL) { + uint16_t i_program = patn_get_program(p_program); + uint16_t i_pid = patn_get_pid(p_program); + j++; + switch (i_print_type) { + case PRINT_XML: + pf_print(opaque, "", + i_program, i_pid); + break; + default: + if (i_program == 0) + pf_print(opaque, " * NIT pid=%hu", i_pid); + else + pf_print(opaque, " * program number=%hu pid=%hu", + i_program, i_pid); + } + } + } + + switch (i_print_type) { + case PRINT_XML: + pf_print(opaque, ""); + break; + default: + pf_print(opaque, "end PAT"); + } +} + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/mpeg/psi_print.h b/mpeg/psi_print.h index 867ba6a..4cdcad3 100644 --- a/mpeg/psi_print.h +++ b/mpeg/psi_print.h @@ -35,6 +35,7 @@ #include #include +#include /* here you must manually include or the ATSC equivalent * if/when it is available */