From 43c02b513f9bd539460041d55f613504de605e09 Mon Sep 17 00:00:00 2001 From: Christophe Massiot Date: Mon, 10 Oct 2011 13:03:42 +0300 Subject: [PATCH] mpeg/psi: Move PMT functions to mpeg/psi/pmt{_print}.h --- mpeg/psi.h | 176 +--------------------------------- mpeg/psi/pmt.h | 224 +++++++++++++++++++++++++++++++++++++++++++ mpeg/psi/pmt_print.h | 102 ++++++++++++++++++++ mpeg/psi_print.h | 79 +-------------- 4 files changed, 328 insertions(+), 253 deletions(-) create mode 100644 mpeg/psi/pmt.h create mode 100644 mpeg/psi/pmt_print.h diff --git a/mpeg/psi.h b/mpeg/psi.h index 403cbfe..42ae0bf 100644 --- a/mpeg/psi.h +++ b/mpeg/psi.h @@ -40,6 +40,7 @@ #include #include #include +#include #ifdef __cplusplus extern "C" @@ -192,181 +193,6 @@ static inline void desc0a_print(uint8_t *p_desc, f_print pf_print, } } -/***************************************************************************** - * Program Map Table - *****************************************************************************/ -#define PMT_TABLE_ID 0x2 -#define PMT_HEADER_SIZE (PSI_HEADER_SIZE_SYNTAX1 + 4) -#define PMT_ES_SIZE 5 - -#define pmt_set_program psi_set_tableidext -#define pmt_get_program psi_get_tableidext - -static inline void pmt_init(uint8_t *p_pmt) -{ - psi_init(p_pmt, true); - psi_set_tableid(p_pmt, PMT_TABLE_ID); - p_pmt[1] &= ~0x40; - psi_set_section(p_pmt, 0); - psi_set_lastsection(p_pmt, 0); - p_pmt[8] = 0xe0; - p_pmt[10] = 0xf0; -} - -static inline void pmt_set_length(uint8_t *p_pmt, uint16_t i_pmt_length) -{ - psi_set_length(p_pmt, PMT_HEADER_SIZE + PSI_CRC_SIZE - PSI_HEADER_SIZE - + i_pmt_length); -} - -static inline void pmt_set_pcrpid(uint8_t *p_pmt, uint16_t i_pcr_pid) -{ - p_pmt[8] &= ~0x1f; - p_pmt[8] |= i_pcr_pid >> 8; - p_pmt[9] = i_pcr_pid & 0xff; -} - -static inline uint16_t pmt_get_pcrpid(const uint8_t *p_pmt) -{ - return ((p_pmt[8] & 0x1f) << 8) | p_pmt[9]; -} - -static inline void pmt_set_desclength(uint8_t *p_pmt, uint16_t i_length) -{ - p_pmt[10] &= ~0xf; - p_pmt[10] |= i_length >> 8; - p_pmt[11] = i_length & 0xff; -} - -static inline uint16_t pmt_get_desclength(const uint8_t *p_pmt) -{ - return ((p_pmt[10] & 0xf) << 8) | p_pmt[11]; -} - -static inline uint8_t *pmt_get_descs(uint8_t *p_pmt) -{ - return &p_pmt[10]; -} - -static inline void pmtn_init(uint8_t *p_pmt_n) -{ - p_pmt_n[1] = 0xe0; - p_pmt_n[3] = 0xf0; -} - -static inline void pmtn_set_streamtype(uint8_t *p_pmt_n, uint8_t i_stream_type) -{ - p_pmt_n[0] = i_stream_type; -} - -static inline uint8_t pmtn_get_streamtype(const uint8_t *p_pmt_n) -{ - return p_pmt_n[0]; -} - -static inline void pmtn_set_pid(uint8_t *p_pmt_n, uint16_t i_pid) -{ - p_pmt_n[1] &= ~0x1f; - p_pmt_n[1] |= i_pid >> 8; - p_pmt_n[2] = i_pid & 0xff; -} - -static inline uint16_t pmtn_get_pid(const uint8_t *p_pmt_n) -{ - return ((p_pmt_n[1] & 0x1f) << 8) | p_pmt_n[2]; -} - -static inline void pmtn_set_desclength(uint8_t *p_pmt_n, uint16_t i_length) -{ - p_pmt_n[3] &= ~0xf; - p_pmt_n[3] |= i_length >> 8; - p_pmt_n[4] = i_length & 0xff; -} - -static inline uint16_t pmtn_get_desclength(const uint8_t *p_pmt_n) -{ - return ((p_pmt_n[3] & 0xf) << 8) | p_pmt_n[4]; -} - -static inline uint8_t *pmtn_get_descs(uint8_t *p_pmt_n) -{ - return &p_pmt_n[3]; -} - -static inline uint8_t *pmt_get_es(uint8_t *p_pmt, uint8_t n) -{ - uint16_t i_section_size = psi_get_length(p_pmt) + PSI_HEADER_SIZE - - PSI_CRC_SIZE; - uint8_t *p_pmt_n = p_pmt + PMT_HEADER_SIZE + pmt_get_desclength(p_pmt); - if (p_pmt_n - p_pmt > i_section_size) return NULL; - - while (n) { - if (p_pmt_n + PMT_ES_SIZE - p_pmt > i_section_size) return NULL; - p_pmt_n += PMT_ES_SIZE + pmtn_get_desclength(p_pmt_n); - n--; - } - if (p_pmt_n - p_pmt >= i_section_size) return NULL; - return p_pmt_n; -} - -static inline bool pmt_validate_es(const uint8_t *p_pmt, const uint8_t *p_pmt_n, - uint16_t i_desclength) -{ - uint16_t i_section_size = psi_get_length(p_pmt) + PSI_HEADER_SIZE - - PSI_CRC_SIZE; - return (p_pmt_n + PMT_ES_SIZE + i_desclength - <= p_pmt + i_section_size); -} - -static inline bool pmt_validate(const uint8_t *p_pmt) -{ - uint16_t i_section_size = psi_get_length(p_pmt) + PSI_HEADER_SIZE - - PSI_CRC_SIZE; - const uint8_t *p_pmt_n; - - if (!psi_get_syntax(p_pmt) || psi_get_section(p_pmt) - || psi_get_lastsection(p_pmt) - || psi_get_tableid(p_pmt) != PMT_TABLE_ID) - return false; - - if (!psi_check_crc(p_pmt)) - return false; - - if (i_section_size < PMT_HEADER_SIZE - || i_section_size < PMT_HEADER_SIZE + pmt_get_desclength(p_pmt)) - return false; - - if (!descs_validate(p_pmt + 10)) - return false; - - p_pmt_n = p_pmt + PMT_HEADER_SIZE + pmt_get_desclength(p_pmt); - - while (p_pmt_n + PMT_ES_SIZE - p_pmt <= i_section_size - && p_pmt_n + PMT_ES_SIZE + pmtn_get_desclength(p_pmt_n) - p_pmt - <= i_section_size) { - if (!descs_validate(p_pmt_n + 3)) - return false; - - p_pmt_n += PMT_ES_SIZE + pmtn_get_desclength(p_pmt_n); - } - - return (p_pmt_n - p_pmt == i_section_size); -} - -static inline uint8_t *pmt_find_es(uint8_t *p_pmt, uint16_t i_pid) -{ - uint8_t *p_es; - uint8_t j = 0; - - while ((p_es = pmt_get_es(p_pmt, j)) != NULL) { - j++; - if (pmtn_get_pid(p_es) == i_pid) - return p_es; - } - - return NULL; -} - #ifdef __cplusplus } #endif diff --git a/mpeg/psi/pmt.h b/mpeg/psi/pmt.h new file mode 100644 index 0000000..0ae5f6b --- /dev/null +++ b/mpeg/psi/pmt.h @@ -0,0 +1,224 @@ +/***************************************************************************** + * pmt.h: ISO/IEC 13818-1 Program Map Table (PMT) + ***************************************************************************** + * 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_PMT_H__ +#define __BITSTREAM_MPEG_PMT_H__ + +#include +#include +#include + +#ifdef __cplusplus +extern "C" +{ +#endif + +/***************************************************************************** + * Program Map Table + *****************************************************************************/ +#define PMT_TABLE_ID 0x2 +#define PMT_HEADER_SIZE (PSI_HEADER_SIZE_SYNTAX1 + 4) +#define PMT_ES_SIZE 5 + +#define pmt_set_program psi_set_tableidext +#define pmt_get_program psi_get_tableidext + +static inline void pmt_init(uint8_t *p_pmt) +{ + psi_init(p_pmt, true); + psi_set_tableid(p_pmt, PMT_TABLE_ID); + p_pmt[1] &= ~0x40; + psi_set_section(p_pmt, 0); + psi_set_lastsection(p_pmt, 0); + p_pmt[8] = 0xe0; + p_pmt[10] = 0xf0; +} + +static inline void pmt_set_length(uint8_t *p_pmt, uint16_t i_pmt_length) +{ + psi_set_length(p_pmt, PMT_HEADER_SIZE + PSI_CRC_SIZE - PSI_HEADER_SIZE + + i_pmt_length); +} + +static inline void pmt_set_pcrpid(uint8_t *p_pmt, uint16_t i_pcr_pid) +{ + p_pmt[8] &= ~0x1f; + p_pmt[8] |= i_pcr_pid >> 8; + p_pmt[9] = i_pcr_pid & 0xff; +} + +static inline uint16_t pmt_get_pcrpid(const uint8_t *p_pmt) +{ + return ((p_pmt[8] & 0x1f) << 8) | p_pmt[9]; +} + +static inline void pmt_set_desclength(uint8_t *p_pmt, uint16_t i_length) +{ + p_pmt[10] &= ~0xf; + p_pmt[10] |= i_length >> 8; + p_pmt[11] = i_length & 0xff; +} + +static inline uint16_t pmt_get_desclength(const uint8_t *p_pmt) +{ + return ((p_pmt[10] & 0xf) << 8) | p_pmt[11]; +} + +static inline uint8_t *pmt_get_descs(uint8_t *p_pmt) +{ + return &p_pmt[10]; +} + +static inline void pmtn_init(uint8_t *p_pmt_n) +{ + p_pmt_n[1] = 0xe0; + p_pmt_n[3] = 0xf0; +} + +static inline void pmtn_set_streamtype(uint8_t *p_pmt_n, uint8_t i_stream_type) +{ + p_pmt_n[0] = i_stream_type; +} + +static inline uint8_t pmtn_get_streamtype(const uint8_t *p_pmt_n) +{ + return p_pmt_n[0]; +} + +static inline void pmtn_set_pid(uint8_t *p_pmt_n, uint16_t i_pid) +{ + p_pmt_n[1] &= ~0x1f; + p_pmt_n[1] |= i_pid >> 8; + p_pmt_n[2] = i_pid & 0xff; +} + +static inline uint16_t pmtn_get_pid(const uint8_t *p_pmt_n) +{ + return ((p_pmt_n[1] & 0x1f) << 8) | p_pmt_n[2]; +} + +static inline void pmtn_set_desclength(uint8_t *p_pmt_n, uint16_t i_length) +{ + p_pmt_n[3] &= ~0xf; + p_pmt_n[3] |= i_length >> 8; + p_pmt_n[4] = i_length & 0xff; +} + +static inline uint16_t pmtn_get_desclength(const uint8_t *p_pmt_n) +{ + return ((p_pmt_n[3] & 0xf) << 8) | p_pmt_n[4]; +} + +static inline uint8_t *pmtn_get_descs(uint8_t *p_pmt_n) +{ + return &p_pmt_n[3]; +} + +static inline uint8_t *pmt_get_es(uint8_t *p_pmt, uint8_t n) +{ + uint16_t i_section_size = psi_get_length(p_pmt) + PSI_HEADER_SIZE + - PSI_CRC_SIZE; + uint8_t *p_pmt_n = p_pmt + PMT_HEADER_SIZE + pmt_get_desclength(p_pmt); + if (p_pmt_n - p_pmt > i_section_size) return NULL; + + while (n) { + if (p_pmt_n + PMT_ES_SIZE - p_pmt > i_section_size) return NULL; + p_pmt_n += PMT_ES_SIZE + pmtn_get_desclength(p_pmt_n); + n--; + } + if (p_pmt_n - p_pmt >= i_section_size) return NULL; + return p_pmt_n; +} + +static inline bool pmt_validate_es(const uint8_t *p_pmt, const uint8_t *p_pmt_n, + uint16_t i_desclength) +{ + uint16_t i_section_size = psi_get_length(p_pmt) + PSI_HEADER_SIZE + - PSI_CRC_SIZE; + return (p_pmt_n + PMT_ES_SIZE + i_desclength + <= p_pmt + i_section_size); +} + +static inline bool pmt_validate(const uint8_t *p_pmt) +{ + uint16_t i_section_size = psi_get_length(p_pmt) + PSI_HEADER_SIZE + - PSI_CRC_SIZE; + const uint8_t *p_pmt_n; + + if (!psi_get_syntax(p_pmt) || psi_get_section(p_pmt) + || psi_get_lastsection(p_pmt) + || psi_get_tableid(p_pmt) != PMT_TABLE_ID) + return false; + + if (!psi_check_crc(p_pmt)) + return false; + + if (i_section_size < PMT_HEADER_SIZE + || i_section_size < PMT_HEADER_SIZE + pmt_get_desclength(p_pmt)) + return false; + + if (!descs_validate(p_pmt + 10)) + return false; + + p_pmt_n = p_pmt + PMT_HEADER_SIZE + pmt_get_desclength(p_pmt); + + while (p_pmt_n + PMT_ES_SIZE - p_pmt <= i_section_size + && p_pmt_n + PMT_ES_SIZE + pmtn_get_desclength(p_pmt_n) - p_pmt + <= i_section_size) { + if (!descs_validate(p_pmt_n + 3)) + return false; + + p_pmt_n += PMT_ES_SIZE + pmtn_get_desclength(p_pmt_n); + } + + return (p_pmt_n - p_pmt == i_section_size); +} + +static inline uint8_t *pmt_find_es(uint8_t *p_pmt, uint16_t i_pid) +{ + uint8_t *p_es; + uint8_t j = 0; + + while ((p_es = pmt_get_es(p_pmt, j)) != NULL) { + j++; + if (pmtn_get_pid(p_es) == i_pid) + return p_es; + } + + return NULL; +} + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/mpeg/psi/pmt_print.h b/mpeg/psi/pmt_print.h new file mode 100644 index 0000000..b15013f --- /dev/null +++ b/mpeg/psi/pmt_print.h @@ -0,0 +1,102 @@ +/***************************************************************************** + * pmt_print.h: ISO/IEC 13818-1 Program Map Table (printing) + ***************************************************************************** + * Copyright (C) 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_PMT_PRINT_H__ +#define __BITSTREAM_MPEG_PMT_PRINT_H__ + +#include +#include +#include + +#ifdef __cplusplus +extern "C" +{ +#endif + +static inline void pmt_print(uint8_t *p_pmt, + f_print pf_print, void *print_opaque, + f_iconv pf_iconv, void *iconv_opaque, + print_type_t i_print_type) +{ + uint8_t *p_es; + uint8_t j = 0; + + switch (i_print_type) { + case PRINT_XML: + pf_print(print_opaque, "", + pmt_get_program(p_pmt), psi_get_version(p_pmt), + !psi_get_current(p_pmt) ? 0 : 1, + pmt_get_pcrpid(p_pmt)); + break; + default: + pf_print(print_opaque, "new PMT program=%hu version=%hhu%s pcrpid=%hu", + pmt_get_program(p_pmt), psi_get_version(p_pmt), + !psi_get_current(p_pmt) ? " (next)" : "", + pmt_get_pcrpid(p_pmt)); + } + + descs_print(pmt_get_descs(p_pmt), pf_print, print_opaque, + pf_iconv, iconv_opaque, i_print_type); + + while ((p_es = pmt_get_es(p_pmt, j)) != NULL) { + j++; + switch (i_print_type) { + case PRINT_XML: + pf_print(print_opaque, "", pmtn_get_pid(p_es), + pmtn_get_streamtype(p_es)); + break; + default: + pf_print(print_opaque, " * ES pid=%hu streamtype=0x%hx", pmtn_get_pid(p_es), + pmtn_get_streamtype(p_es)); + } + + descs_print(pmtn_get_descs(p_es), pf_print, print_opaque, + pf_iconv, iconv_opaque, i_print_type); + + switch (i_print_type) { + case PRINT_XML: + pf_print(print_opaque, ""); + break; + default: + break; + } + } + + switch (i_print_type) { + case PRINT_XML: + pf_print(print_opaque, ""); + break; + default: + pf_print(print_opaque, "end PMT"); + } +} + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/mpeg/psi_print.h b/mpeg/psi_print.h index d40da06..73f495a 100644 --- a/mpeg/psi_print.h +++ b/mpeg/psi_print.h @@ -2,7 +2,6 @@ * psi_print.h: ISO/IEC 13818-1 Program Stream Information (printing) ***************************************************************************** * Copyright (C) 2010 VideoLAN - * $Id: psi_print.h -1 $ * * Authors: Christophe Massiot * @@ -26,10 +25,6 @@ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *****************************************************************************/ -/* - * Placed here for dependancy reasons - */ - #ifndef __BITSTREAM_MPEG_PSI_PRINT_H__ #define __BITSTREAM_MPEG_PSI_PRINT_H__ @@ -37,78 +32,6 @@ #include #include #include - -/* here you must manually include or the ATSC equivalent - * if/when it is available */ - -#ifdef __cplusplus -extern "C" -{ -#endif - -/***************************************************************************** - * Program Map Table - *****************************************************************************/ -static inline void pmt_print(uint8_t *p_pmt, - f_print pf_print, void *print_opaque, - f_iconv pf_iconv, void *iconv_opaque, - print_type_t i_print_type) -{ - uint8_t *p_es; - uint8_t j = 0; - - switch (i_print_type) { - case PRINT_XML: - pf_print(print_opaque, "", - pmt_get_program(p_pmt), psi_get_version(p_pmt), - !psi_get_current(p_pmt) ? 0 : 1, - pmt_get_pcrpid(p_pmt)); - break; - default: - pf_print(print_opaque, "new PMT program=%hu version=%hhu%s pcrpid=%hu", - pmt_get_program(p_pmt), psi_get_version(p_pmt), - !psi_get_current(p_pmt) ? " (next)" : "", - pmt_get_pcrpid(p_pmt)); - } - - descs_print(pmt_get_descs(p_pmt), pf_print, print_opaque, - pf_iconv, iconv_opaque, i_print_type); - - while ((p_es = pmt_get_es(p_pmt, j)) != NULL) { - j++; - switch (i_print_type) { - case PRINT_XML: - pf_print(print_opaque, "", pmtn_get_pid(p_es), - pmtn_get_streamtype(p_es)); - break; - default: - pf_print(print_opaque, " * ES pid=%hu streamtype=0x%hx", pmtn_get_pid(p_es), - pmtn_get_streamtype(p_es)); - } - - descs_print(pmtn_get_descs(p_es), pf_print, print_opaque, - pf_iconv, iconv_opaque, i_print_type); - - switch (i_print_type) { - case PRINT_XML: - pf_print(print_opaque, ""); - break; - default: - break; - } - } - - switch (i_print_type) { - case PRINT_XML: - pf_print(print_opaque, ""); - break; - default: - pf_print(print_opaque, "end PMT"); - } -} - -#ifdef __cplusplus -} -#endif +#include #endif