diff --git a/atsc/si/desc_81.h b/atsc/si/desc_81.h index a2aab92..e55581b 100644 --- a/atsc/si/desc_81.h +++ b/atsc/si/desc_81.h @@ -81,9 +81,9 @@ static inline uint8_t desc81_bit_rate_code_from_octetrate(uint64_t octetrate) 640, }; for (unsigned i = 0; i < 19; i++) { - if (octetrate * 8 == table[i]) + if (octetrate * 8 == table[i] * 1000) return i; - else if (octetrate * 8 < table[i]) + else if (octetrate * 8 < table[i] * 1000) return 0x20 | i; } return 0xff; diff --git a/dvb/si/desc_6a.h b/dvb/si/desc_6a.h index d64d3a4..7c4291d 100644 --- a/dvb/si/desc_6a.h +++ b/dvb/si/desc_6a.h @@ -51,12 +51,12 @@ static inline void desc6a_init(uint8_t *p_desc) { desc_set_tag(p_desc, 0x6a); desc_set_length(p_desc, (DESC6A_HEADER_SIZE - DESC_HEADER_SIZE)); - p_desc[2] = 0x0f; + p_desc[2] = 0x00; } static inline void desc6a_clear_flags(uint8_t *p_desc) { - p_desc[2] = 0x0f; + p_desc[2] = 0x00; } #define DEFINE_AC3_FLAG(FLAGNAME, bit) \ diff --git a/dvb/si/sdt.h b/dvb/si/sdt.h index d8170e3..7286296 100644 --- a/dvb/si/sdt.h +++ b/dvb/si/sdt.h @@ -1,7 +1,7 @@ /***************************************************************************** * sdt.h: ETSI EN 300 468 Service Definition Table (SDT) ***************************************************************************** - * Copyright (C) 2009-2010 VideoLAN + * Copyright (C) 2009-2020 VideoLAN * * Authors: Christophe Massiot * @@ -238,7 +238,7 @@ static inline bool sdt_table_validate(uint8_t **pp_sections) if (!psi_check_crc(p_section)) return false; - if (!j) + if (!i) i_onid = sdt_get_onid(p_section); else if (sdt_get_onid(p_section) != i_onid) return false; diff --git a/examples/Makefile b/examples/Makefile index b5541d3..f8da852 100644 --- a/examples/Makefile +++ b/examples/Makefile @@ -2,7 +2,7 @@ PREFIX ?= /usr/local WARN = -Wall -Wextra -Wno-unused-parameter -Wno-sign-compare CPPFLAGS = -I. -I.. -I../.. CFLAGS := $(WARN) -O2 -g $(CFLAGS) -OBJ = dvb_print_si dvb_gen_si dvb_ecmg dvb_ecmg_test mpeg_print_pcr rtp_check_seqnum mpeg_restamp +OBJ = dvb_print_si dvb_gen_si dvb_ecmg dvb_ecmg_test mpeg_print_pcr mpeg_print_au_info rtp_check_seqnum mpeg_restamp ifeq "$(shell uname -s)" "Linux" LDFLAGS += -lrt diff --git a/examples/mpeg_print_au_info.c b/examples/mpeg_print_au_info.c new file mode 100644 index 0000000..3df2120 --- /dev/null +++ b/examples/mpeg_print_au_info.c @@ -0,0 +1,134 @@ +/***************************************************************************** + * mpeg_print_au_info.c: Prints adaptation field AU_INFO + ***************************************************************************** + * Copyright (C) 2019 VideoLAN + * + * Authors: Roberto Corno + * + * 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. + *****************************************************************************/ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +/***************************************************************************** + * Local declarations + *****************************************************************************/ +#define MAX_PIDS 8192 +#define READ_ONCE 7 + +typedef struct ts_pid_t { + int i_psi_refcount; + int8_t i_last_cc; + + /* biTStream PSI section gathering */ + uint8_t *p_psi_buffer; + uint16_t i_psi_buffer_used; +} ts_pid_t; + +typedef struct sid_t { + uint16_t i_sid, i_pmt_pid; + uint8_t *p_current_pmt; +} sid_t; + +ts_pid_t p_pids[MAX_PIDS]; + + +/***************************************************************************** + * Main loop + *****************************************************************************/ +static void usage(const char *psz) +{ + fprintf(stderr, "usage: %s < [> ]\n", psz); + exit(EXIT_FAILURE); +} + +int main(int i_argc, char **ppsz_argv) +{ + int i; + + if (ppsz_argv[1] != NULL && + (!strcmp(ppsz_argv[1], "-h") || !strcmp(ppsz_argv[1], "--help"))) + usage(ppsz_argv[0]); + + setvbuf(stdout, NULL, _IOLBF, 0); + + memset(p_pids, 0, sizeof(p_pids)); + + for (i = 0; i < 8192; i++) { + p_pids[i].i_last_cc = -1; + psi_assemble_init( &p_pids[i].p_psi_buffer, + &p_pids[i].i_psi_buffer_used ); + } + + p_pids[PAT_PID].i_psi_refcount++; + + uint64_t pnum = 0; + while (!feof(stdin) && !ferror(stdin)) { + uint8_t p_ts[TS_SIZE]; + size_t i_ret = fread(p_ts, sizeof(p_ts), 1, stdin); + if (i_ret != 1) continue; + if (ts_validate(p_ts)) { + if (ts_has_adaptation(p_ts)) { + if (tsaf_has_transport_private_data(p_ts)) { + uint8_t tag = tsaf_get_private_data_tag(p_ts); + uint8_t len = tsaf_get_private_data_length(p_ts); + fprintf(stderr, "packet %lu ts private data [len %d] found [%d]\n", pnum, len, tag); + if (tag == 0x02) { + uint8_t *p_au = ts_private_data(p_ts); + p_au++; + uint8_t df_len = au_info_get_data_field_length(p_au); + fprintf(stderr, " AU_information len %d\n", df_len); + uint8_t code_fmt = au_info_get_au_coding_format(p_au); + uint8_t ctype_info = au_info_get_au_coding_type_info(p_au); + uint8_t ref_pic_icd = au_info_get_au_ref_pic_idc(p_au); + uint8_t pic_struct = au_info_get_au_pic_struct(p_au); + bool pts = au_info_get_pts_present(p_au); + bool prof_info = au_info_get_profile_info_present(p_au); + bool stream_info = au_info_get_stream_info_present(p_au); + fprintf(stderr, " AU_coding_format:%d AU_coding_type_info:%d\n",code_fmt, ctype_info); + fprintf(stderr, " AU_ref_pic_idc:%d AU_pic_struct:%d\n",ref_pic_icd, pic_struct); + fprintf(stderr, " PTS present:%d ProfileInfo present:%d Stream Info present:%d\n",pts, prof_info, stream_info); + if (pts) { + uint32_t pts32 = au_info_get_pts(p_au); + fprintf(stderr, " PTS :%u\n",pts32); + } + } + exit(0); + } + } + uint16_t i_pid = ts_get_pid(p_ts); + ts_pid_t *p_pid = &p_pids[i_pid]; + p_pid->i_last_cc = ts_get_cc(p_ts); + pnum++; + } + } + + return EXIT_FAILURE; +} diff --git a/ieee/ethernet.h b/ieee/ethernet.h index e15519f..5523af1 100644 --- a/ieee/ethernet.h +++ b/ieee/ethernet.h @@ -45,6 +45,7 @@ extern "C" #define ETHERNET_ADDR_LEN 6 #define ETHERNET_HEADER_LEN (2*ETHERNET_ADDR_LEN + 2) +#define ETHERNET_VLAN_LEN 4 #define ETHERNET_TYPE_IP 0x0800 #define ETHERNET_TYPE_ARP 0x0806 diff --git a/ietf/rtp2435.h b/ietf/rtp2435.h new file mode 100644 index 0000000..11b5d8b --- /dev/null +++ b/ietf/rtp2435.h @@ -0,0 +1,249 @@ +/***************************************************************************** + * rtp2435.h: RFC Profile for JPEG + ***************************************************************************** + * Copyright (C) 2019 Josh de Kock + * + * Authors: Josh de Kock + * + * 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. + *****************************************************************************/ + +/* + * RTP Payload Format for JPEG + */ +#ifndef __BITSTREAM_IETF_RTP2435_H__ +#define __BITSTREAM_IETF_RTP2435_H__ + +#ifdef __cplusplus +extern "C" +{ +#endif + +#define RTP_2435_HEADER_SIZE 8 +#define RTP_2435_RESTART_HEADER_SIZE 4 +#define RTP_2435_QUANTIZATION_HEADER_SIZE 4 + +/* + * Reminder : JPEG header which immediately follows the RTP header + 0 1 2 3 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Type-specific | Fragment Offset | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Type | Q | Width | Height | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + */ + +static inline void rtp2435_set_ts(uint8_t *header, uint8_t ts) +{ + header[0] = ts; +} + +static inline uint8_t rtp2435_get_ts(uint8_t *header) +{ + return header[0]; +} + +static inline void rtp2435_set_offset(uint8_t *header, uint32_t offset) +{ + header[1] = (offset & 0xFF0000) >> 16; + header[2] = (offset & 0xFF00) >> 8; + header[3] = offset & 0xFF; +} + +static inline uint32_t rtp2435_get_offset(uint8_t *header) +{ + return header[1] << 16 | header[2] << 8 | header[3]; +} + +static inline void rtp2435_set_type(uint8_t *header, uint8_t type) +{ + header[4] = type; +} + +static inline uint8_t rtp2435_get_type(uint8_t *header) +{ + return header[4]; +} + +static inline void rtp2435_set_q(uint8_t *header, uint8_t q) +{ + header[5] = q; +} + +static inline uint8_t rtp2435_get_q(uint8_t *header) +{ + return header[5]; +} + +static inline void rtp2435_set_width(uint8_t *header, uint8_t width) +{ + header[6] = width; +} + +static inline uint8_t rtp2435_get_width(uint8_t *header) +{ + return header[6]; +} + +static inline void rtp2435_set_height(uint8_t *header, uint8_t height) +{ + header[7] = height; +} + +static inline uint8_t rtp2435_get_height(uint8_t *header) +{ + return header[7]; +} + +static inline uint8_t *rtp2435_restart(uint8_t *header) +{ + uint8_t t = rtp2435_get_type(header); + if (64 <= t && t <= 127) + return header + RTP_2435_HEADER_SIZE; + else + return NULL; +} + +static inline uint8_t *rtp2435_quantization_table(uint8_t *header) +{ + uint8_t q = rtp2435_get_q(header); + if (128 <= q && q <= 255) { + uint8_t *p; + if ((p = rtp2435_restart(header))) + return p + RTP_2435_RESTART_HEADER_SIZE; + else + return header + RTP_2435_HEADER_SIZE; + } + + return NULL; +} + +/* + * Reminder : Restart Marker header + 0 1 2 3 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Restart Interval |F|L| Restart Count | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + */ + +static inline void rtp2435r_set_first(uint8_t *header) +{ + header[2] |= 0x1; +} + +static inline void rtp2435r_clear_first(uint8_t *header) +{ + header[2] &= ~0x1; +} + +static inline bool rtp2435r_check_first(uint8_t *header) +{ + return !!(header[2] & 0x1); +} + +static inline void rtp2435r_set_last(uint8_t *header) +{ + header[2] |= 0x2; +} + +static inline void rtp2435r_clear_last(uint8_t *header) +{ + header[2] &= ~0x2; +} + +static inline bool rtp2435r_check_last(uint8_t *header) +{ + return !!(header[2] & 0x2); +} + +static inline uint16_t rtp2435r_get_count(uint8_t *header) +{ + return (header[2] << 8 | header[3]) >> 2; +} + +static inline void rtp2435r_set_count(uint8_t *header, uint16_t count) +{ + count = count << 2; + header[2] |= count >> 8; + header[3] = count & 0xFF; +} + +static inline uint16_t rtp2435r_get_interval(uint8_t *header) +{ + return header[0] << 8 | header[1]; +} + +static inline void rtp2435r_set_interval(uint8_t *header, uint16_t interval) +{ + header[0] = (interval & 0xFF00) >> 8; + header[1] = interval & 0xFF; +} + +/* + * Reminder : Quantization Table header + 0 1 2 3 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | MBZ | Precision | Length | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Quantization Table Data | + | ... | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + */ + +static inline void rtp2435q_set_mbz(uint8_t *header, uint8_t mbz) +{ + header[0] = mbz; +} + +static inline uint8_t rtp2435q_get_mbz(uint8_t *header) +{ + return header[0]; +} + +static inline void rtp2435q_set_precision(uint8_t *header, uint8_t precision) +{ + header[1] = precision; +} + +static inline uint8_t rtp2435q_get_precision(uint8_t *header) +{ + return header[1]; +} + +static inline uint16_t rtp2435q_get_length(uint8_t *header) +{ + return header[2] << 16 | header[3]; +} + +static inline void rtp2435q_set_length(uint8_t *header, uint16_t length) +{ + header[2] = (length & 0xFF00) >> 8; + header[3] = length & 0xFF; +} + +#ifdef __cplusplus +} +#endif + +#endif /* !__BITSTREAM_IETF_RTP2435_H__ */ + diff --git a/mpeg/au_info.h b/mpeg/au_info.h new file mode 100644 index 0000000..b16b683 --- /dev/null +++ b/mpeg/au_info.h @@ -0,0 +1,374 @@ +/***************************************************************************** + * au_info.h: ETSI TS 101154 Access Unit Information + ***************************************************************************** + * Copyright (C) 2019 VideoLAN + * + * Authors: Roberto Corno + * + * 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: + * - ETSI TS 101154 V1.9.1 (2009-09) + */ + +#ifndef __BITSTREAM_MPEG_AU_INFO_H__ +#define __BITSTREAM_MPEG_AU_INFO_H__ + +#include /* malloc */ +#include /* uint8_t, uint16_t, etc... */ +#include /* bool */ +#include /* memset */ + +#ifdef __cplusplus +extern "C" +{ +#endif + +#define ANNOUNCEMENT_SWITCHING 0x1 +#define AU_INFORMATION 0x2 +#define PVR_ASSIST_INFO 0x3 + +static inline void au_info_init(uint8_t *p_au_info) { + p_au_info[3] = 0x0; +} + +static inline void au_info_set_data_field_tag(uint8_t *p_au_info, uint8_t i_data_field_tag) +{ + p_au_info[0] = i_data_field_tag; +} + +static inline uint8_t au_info_get_data_field_tag(const uint8_t *p_au_info) +{ + return p_au_info[0]; +} + +static inline void au_info_set_data_field_length(uint8_t *p_au_info, uint8_t i_data_field_length) +{ + p_au_info[1] = i_data_field_length; +} + +static inline uint8_t au_info_get_data_field_length(const uint8_t *p_au_info) +{ + return p_au_info[1]; +} + +#define CF_UNDEFINED 0x0 +#define CF_H262 0x1 +#define CF_H264 0x2 +#define CF_VC1 0x3 +static inline void au_info_set_au_coding_format(uint8_t *p_au_info, uint8_t i_au_coding_format) +{ + p_au_info[2] &= ~0xF0; + p_au_info[2] |= (i_au_coding_format & 0x0F) << 4; +} + +static inline uint8_t au_info_get_au_coding_format(const uint8_t *p_au_info) +{ + return (p_au_info[2] & 0xF0) >> 4; +} + +static inline void au_info_set_au_coding_type_info(uint8_t *p_au_info, uint8_t i_au_coding_type_info) +{ + p_au_info[2] &= ~0x0F; + p_au_info[2] |= (i_au_coding_type_info & 0x0F); +} + +static inline uint8_t au_info_get_au_coding_type_info(const uint8_t *p_au_info) +{ + return (p_au_info[2] & 0x0F); +} + +static inline void au_info_set_au_ref_pic_idc(uint8_t *p_au_info, uint8_t i_au_ref_pic_idc) +{ + p_au_info[3] &= ~0xC0; + p_au_info[3] |= (i_au_ref_pic_idc & 0x3) << 6; +} + +static inline uint8_t au_info_get_au_ref_pic_idc(const uint8_t *p_au_info) +{ + return (p_au_info[3] & 0xC0) >> 6; +} + +static inline void au_info_set_au_pic_struct(uint8_t *p_au_info, uint8_t i_au_pic_struct) +{ + p_au_info[3] &= ~0x30; + p_au_info[3] |= (i_au_pic_struct & 0x3) << 4; +} + +static inline uint8_t au_info_get_au_pic_struct(const uint8_t *p_au_info) +{ + return (p_au_info[3] & 0x30) >> 4; +} + +static inline void au_info_set_pts_present(uint8_t *p_au_info) +{ + p_au_info[3] |= 0x8; +} + +static inline bool au_info_get_pts_present(const uint8_t *p_au_info) +{ + return !!(p_au_info[3] & 0x8); +} + +static inline void au_info_set_profile_info_present(uint8_t *p_au_info) +{ + p_au_info[3] |= 0x4; +} + +static inline bool au_info_get_profile_info_present(const uint8_t *p_au_info) +{ + return !!(p_au_info[3] & 0x4); +} + +static inline void au_info_set_stream_info_present(uint8_t *p_au_info) +{ + p_au_info[3] |= 0x2; +} + +static inline bool au_info_get_stream_info_present(const uint8_t *p_au_info) +{ + return !!(p_au_info[3] & 0x2); +} + +static inline void au_info_set_trickmode_info_present(uint8_t *p_au_info) +{ + p_au_info[3] |= 0x1; +} + +static inline bool au_info_get_trickmode_info_present(const uint8_t *p_au_info) +{ + return !!(p_au_info[3] & 0x1); +} + +static inline void au_info_set_pts(uint8_t *p_au_info, uint32_t i_pts) +{ + p_au_info[4] = (i_pts >> 24) & 0xff; + p_au_info[5] = (i_pts >> 16) & 0xff; + p_au_info[6] = (i_pts >> 8) & 0xff; + p_au_info[7] = i_pts & 0xff; +} + +static inline uint32_t au_info_get_pts(const uint8_t *p_au_info) +{ + return (p_au_info[4] << 24) | (p_au_info[5] << 16) | (p_au_info[6] << 8) | p_au_info[7]; +} + +static inline uint8_t* au_stream_info(uint8_t *p_au_info) { + return p_au_info + 4 + (au_info_get_pts_present(p_au_info) ? 4 : 0); +} + +static inline void au_info_set_frame_rate(uint8_t *p_au_info, uint8_t i_frame_rate) +{ + uint8_t *p_payload = au_stream_info(p_au_info); + *p_payload = i_frame_rate & 0x0F; +} + +static inline uint8_t au_info_get_frame_rate(uint8_t *p_au_info) +{ + uint8_t *p_payload = au_stream_info(p_au_info); + return *p_payload; +} + +static inline uint8_t* au_profile_info(uint8_t *p_au_info) { + return au_stream_info(p_au_info) + (au_info_get_stream_info_present(p_au_info) ? 1 : 0); +} + +static inline void au_info_set_au_profile(uint8_t *p_au_info, uint8_t i_profile) +{ + uint8_t *p_payload = au_profile_info(p_au_info); + *p_payload = i_profile; +} + +static inline uint8_t au_info_get_au_profile(uint8_t *p_au_info) +{ + uint8_t *p_payload = au_profile_info(p_au_info); + return *p_payload; +} + +static inline void au_info_set_au_contsraint_set0(uint8_t *p_au_info) +{ + uint8_t *p_payload = au_profile_info(p_au_info); + p_payload[1] |= 0x80; +} + +static inline bool au_info_get_au_contsraint_set0(uint8_t *p_au_info) +{ + uint8_t *p_payload = au_profile_info(p_au_info); + return !!(p_payload[1] & 0x80); +} + +static inline void au_info_set_au_contsraint_set1(uint8_t *p_au_info) +{ + uint8_t *p_payload = au_profile_info(p_au_info); + p_payload[1] |= 0x40; +} + +static inline bool au_info_get_au_contsraint_set1(uint8_t *p_au_info) +{ + uint8_t *p_payload = au_profile_info(p_au_info); + return !!(p_payload[1] & 0x40); +} + +static inline void au_info_set_au_contsraint_set2(uint8_t *p_au_info) +{ + uint8_t *p_payload = au_profile_info(p_au_info); + p_payload[1] |= 0x20; +} + +static inline bool au_info_get_au_contsraint_set2(uint8_t *p_au_info) +{ + uint8_t *p_payload = au_profile_info(p_au_info); + return !!(p_payload[1] & 0x20); +} + +static inline void au_info_set_au_avc_compatible_flags(uint8_t *p_au_info, uint8_t i_avc_flags) +{ + uint8_t *p_payload = au_profile_info(p_au_info); + p_payload[1] |= i_avc_flags & 0x1F; +} + +static inline uint8_t au_info_get_au_avc_compatible_flags(uint8_t *p_au_info) +{ + uint8_t *p_payload = au_profile_info(p_au_info); + return (p_payload[1] & 0x1F); +} + +static inline void au_info_set_au_level(uint8_t *p_au_info, uint8_t i_au_level) +{ + uint8_t *p_payload = au_profile_info(p_au_info); + p_payload[2] = i_au_level; +} + +static inline uint8_t au_info_get_au_level(uint8_t *p_au_info) +{ + uint8_t *p_payload = au_profile_info(p_au_info); + return p_payload[2]; +} + +static inline uint8_t* au_trickmode_info(uint8_t *p_au_info) { + return au_profile_info(p_au_info) + (au_info_get_profile_info_present(p_au_info) ? 3 : 0); +} + +static inline void au_info_set_max_i_pic_size(uint8_t *p_au_info, uint16_t i_pic_size) +{ + uint8_t *p_payload = au_trickmode_info(p_au_info); + p_payload[0] = (i_pic_size & 0xFFF) >> 4; + p_payload[1] |= (i_pic_size & 0x0F); +} + +static inline uint16_t au_info_get_max_i_pic_size(uint8_t *p_au_info) +{ + uint8_t *p_payload = au_trickmode_info(p_au_info); + return p_payload[0] << 4 | (p_payload[1] & 0xF0) >> 4; +} + +static inline void au_info_set_nominal_i_period(uint8_t *p_au_info, uint8_t i_period) +{ + uint8_t *p_payload = au_trickmode_info(p_au_info); + p_payload[1] |= (i_period & 0xF0) >> 4; + p_payload[2] |= (i_period & 0x0F) << 4; +} + +static inline uint8_t au_info_get_nominal_i_period(uint8_t *p_au_info) +{ + uint8_t *p_payload = au_trickmode_info(p_au_info); + return (p_payload[1] & 0X0F) << 4 | (p_payload[2] & 0xF0) >> 4; +} + +static inline void au_info_set_max_i_period(uint8_t *p_au_info, uint8_t i_period) +{ + uint8_t *p_payload = au_trickmode_info(p_au_info); + p_payload[2] |= (i_period & 0xF0) >> 4; + p_payload[3] |= (i_period & 0x0F) << 4; +} + +static inline uint8_t au_info_get_max_i_period(uint8_t *p_au_info) +{ + uint8_t *p_payload = au_trickmode_info(p_au_info); + return (p_payload[2] & 0X0F) << 4 | (p_payload[3] & 0xF0) >> 4; +} + +static inline uint8_t* au_pulldown_info(uint8_t *p_au_info) { + return au_trickmode_info(p_au_info) + (au_info_get_trickmode_info_present(p_au_info) ? 4 : 0); +} + +static inline void au_info_set_pulldown_info_present(uint8_t *p_au_info) +{ + uint8_t *p_payload = au_pulldown_info(p_au_info); + p_payload[0] |= 0x80; +} + +static inline bool au_info_get_au_pulldown_info_present(uint8_t *p_au_info) +{ + uint8_t *p_payload = au_pulldown_info(p_au_info); + return !!(p_payload[0] & 0x01); +} + +static inline void au_info_set_extension_1_present(uint8_t *p_au_info) +{ + uint8_t *p_payload = au_pulldown_info(p_au_info); + p_payload[0] |= 0x01; +} + +static inline bool au_info_get_au_extension_1_present(uint8_t *p_au_info) +{ + uint8_t *p_payload = au_pulldown_info(p_au_info); + return !!(p_payload[0] & 0x80); +} + +static inline uint8_t* au_pulldown_payload_info(uint8_t *p_au_info) { + return au_pulldown_info(p_au_info) + (au_info_get_au_pulldown_info_present(p_au_info) ? 1 : 0); +} + +static inline void au_info_set_pulldown_info(uint8_t *p_au_info, uint8_t i_pulldown_info) +{ + uint8_t *p_payload = au_pulldown_payload_info(p_au_info); + p_payload[0] = i_pulldown_info & 0x0F; +} + +static inline uint8_t au_info_get_au_pulldown_info(uint8_t *p_au_info) +{ + uint8_t *p_payload = au_pulldown_payload_info(p_au_info); + return p_payload[0]; +} + +static inline uint8_t* au_extension_1(uint8_t *p_au_info) { + return au_pulldown_payload_info(p_au_info) + (au_info_get_au_pulldown_info(p_au_info) ? 1 : 0); +} + +static inline void au_info_set_au_reserved(uint8_t *p_au_info, uint8_t i_reserved) +{ + uint8_t *p_payload = au_extension_1(p_au_info); + p_payload[0] = i_reserved; +} + +static inline uint8_t au_info_get_au_reserved(uint8_t *p_au_info) +{ + uint8_t *p_payload = au_extension_1(p_au_info); + return p_payload[0]; +} + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/mpeg/psi/desc_38.h b/mpeg/psi/desc_38.h new file mode 100755 index 0000000..8966c0f --- /dev/null +++ b/mpeg/psi/desc_38.h @@ -0,0 +1,302 @@ +/***************************************************************************** + * desc_38.h: Descriptor 0x38 (HEVC video descriptor) + ***************************************************************************** +* Copyright (C) 2009-2010 VideoLAN + * + * Authors: Dina Shalkov + * + * 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_DESC_38_H__ +#define __BITSTREAM_MPEG_DESC_38_H__ + +#include +#include + +#ifdef __cplusplus +extern "C" +{ +#endif + +/***************************************************************************** + * Descriptor 0x38 (HEVC video descriptor) + *****************************************************************************/ + +#define DESC38_HEADER_SIZE (DESC_HEADER_SIZE + 13) +#define DESC38_HEADER_SIZE2 (DESC_HEADER_SIZE + 13 + 2) + +static inline void desc38_init(uint8_t *p_desc) +{ + desc_set_tag(p_desc, 0x38); + desc_set_length(p_desc, DESC38_HEADER_SIZE - DESC_HEADER_SIZE); + p_desc[7] = p_desc[8] = p_desc[9] = p_desc[10] = p_desc[11] = p_desc[12] = 0; + p_desc[14] = 0; +} + +static inline uint8_t desc38_get_profile_space(const uint8_t *p_desc) +{ + return (p_desc[2] >> 6); +} + +static inline void desc38_set_profile_space(uint8_t *p_desc, uint8_t profile_space) +{ + p_desc[2] = (profile_space << 6) | (p_desc[2] & 0x3f); +} + +static inline uint8_t desc38_get_tier_flag(const uint8_t *p_desc) +{ + return (p_desc[2] & 0x20) == 0x20; +} + +static inline void desc38_set_tier_flag(uint8_t *p_desc, bool tier_flag) +{ + p_desc[2] = tier_flag ? (p_desc[2] | 0x20) : (p_desc[2] & ~0x20); +} + +static inline uint8_t desc38_get_profile_idc(const uint8_t *p_desc) +{ + return (p_desc[2] & 0x1f); +} + +static inline void desc38_set_profile_idc(uint8_t *p_desc, uint8_t profile_idc) +{ + p_desc[2] = (p_desc[2] & 0xe0) | profile_idc; +} + +static inline uint32_t desc38_get_profile_compatibility_indication(const uint8_t *p_desc) +{ + return (p_desc[3] << 24) | (p_desc[4] << 16) | (p_desc[5] << 8) | p_desc[6]; +} + +static inline void desc38_set_profile_compatibility_indication(uint8_t *p_desc, uint32_t profile_compatibility_indication) +{ +#if BYTE_ORDER == BIG_ENDIAN + p_desc[3] = profile_compatibility_indication & 0xff; + p_desc[4] = (profile_compatibility_indication >> 8) & 0xff; + p_desc[5] = (profile_compatibility_indication >> 16) & 0xff; + p_desc[6] = (profile_compatibility_indication >> 24) & 0xff; +#elif BYTE_ORDER == LITTLE_ENDIAN + p_desc[3] = (profile_compatibility_indication >> 24) & 0xff; + p_desc[4] = (profile_compatibility_indication >> 16) & 0xff; + p_desc[5] = (profile_compatibility_indication >> 8) & 0xff; + p_desc[6] = profile_compatibility_indication & 0xff; +#else + # error "What kind of system is this?" +#endif +} + +static inline bool desc38_get_progressive_source_flag(const uint8_t *p_desc) +{ + return (p_desc[7] & 0x80) == 0x80; +} + +static inline void desc38_set_progressive_source_flag(uint8_t *p_desc, bool progressive_source_flag) +{ + p_desc[7] = progressive_source_flag ? (p_desc[7] | 0x80) : (p_desc[7] & ~0x80); +} + +static inline bool desc38_get_interlaced_source_flag(const uint8_t *p_desc) +{ + return (p_desc[7] & 0x40) == 0x40; +} + +static inline void desc38_set_interlaced_source_flag(uint8_t *p_desc, bool interlaced_source_flag) +{ + p_desc[7] = interlaced_source_flag ? (p_desc[7] | 0x40) : (p_desc[7] & ~0x40); +} + +static inline bool desc38_get_non_packed_constraint_flag(const uint8_t *p_desc) +{ + return (p_desc[7] & 0x20) == 0x20; +} + +static inline void desc38_set_non_packed_constraint_flag(uint8_t *p_desc, bool non_packed_constraint_flag) +{ + p_desc[7] = non_packed_constraint_flag ? (p_desc[7] | 0x20) : (p_desc[7] & ~0x20); +} + +static inline bool desc38_get_frame_only_constraint_flag(const uint8_t *p_desc) +{ + return (p_desc[7] & 0x10) == 0x10; +} + +static inline void desc38_set_frame_only_constraint_flag(uint8_t *p_desc, bool frame_only_constraint_flag) +{ + p_desc[7] = frame_only_constraint_flag ? (p_desc[7] | 0x10) : (p_desc[7] & ~0x10); +} + +static inline uint8_t desc38_get_level_idc(const uint8_t *p_desc) +{ + return p_desc[13]; +} + +static inline void desc38_set_level_idc(uint8_t *p_desc, uint8_t level_idc) +{ + p_desc[13] = level_idc; +} + +static inline bool desc38_get_temporal_layer_subset_flag(const uint8_t *p_desc) +{ + return (p_desc[14] & 0x80) == 0x80; +} + +static inline void desc38_set_temporal_layer_subset_flag(uint8_t *p_desc, bool temporal_layer_subset_flag) +{ + if (temporal_layer_subset_flag) + { + desc_set_length(p_desc, DESC38_HEADER_SIZE2 - DESC_HEADER_SIZE); + p_desc[14] |= 0x80; + } + else { + desc_set_length(p_desc, DESC38_HEADER_SIZE - DESC_HEADER_SIZE); + p_desc[14] &= ~0x80; + } +} + +static inline bool desc38_get_HEVC_still_present_flag(const uint8_t *p_desc) +{ + return (p_desc[14] & 0x40) == 0x40; +} + +static inline void desc38_set_HEVC_still_present_flag(uint8_t *p_desc, bool HEVC_still_present_flag) +{ + p_desc[14] = HEVC_still_present_flag ? (p_desc[14] | 0x40) : (p_desc[14] & ~0x40); +} + +static inline bool desc38_get_HEVC_24hr_picture_present_flag(const uint8_t *p_desc) +{ + return (p_desc[14] & 0x20) == 0x20; +} + +static inline void desc38_set_HEVC_24hr_picture_present_flag(uint8_t *p_desc, bool HEVC_24hr_picture_present_flag) +{ + p_desc[14] = HEVC_24hr_picture_present_flag ? (p_desc[14] | 0x20) : (p_desc[14] & ~0x20); +} + +static inline bool desc38_get_sub_pic_hrd_params_not_present_flag(const uint8_t *p_desc) +{ + return (p_desc[14] & 0x10) == 0x10; +} + +static inline void desc38_set_sub_pic_hrd_params_not_present_flag(uint8_t *p_desc, bool sub_pic_hrd_params_not_present_flag) +{ + p_desc[14] = sub_pic_hrd_params_not_present_flag ? (p_desc[14] | 0x10) : (p_desc[14] & ~0x10); +} + +static inline uint8_t desc38_get_temporal_id_min(const uint8_t *p_desc) +{ + if (desc38_get_temporal_layer_subset_flag(p_desc)) + return (p_desc[15] & 0xe0); + return 0; +} + +static inline void desc38_set_temporal_id_min(uint8_t *p_desc, uint8_t temporal_id_min) +{ + desc38_set_temporal_layer_subset_flag(p_desc, true); + p_desc[15] = (p_desc[15] & 0xe0) | temporal_id_min; +} + +static inline uint8_t desc38_get_temporal_id_max(const uint8_t *p_desc) +{ + if (desc38_get_temporal_layer_subset_flag(p_desc)) + return (p_desc[16] & 0xe0); + return 0; +} + +static inline void desc38_set_temporal_id_max(uint8_t *p_desc, uint8_t temporal_id_max) +{ + desc38_set_temporal_layer_subset_flag(p_desc, true); + p_desc[16] = (p_desc[16] & 0xe0) | temporal_id_max; +} + +static inline bool desc38_validate(const uint8_t *p_desc) +{ + uint8_t desc38_header_size = DESC38_HEADER_SIZE; + if (desc38_get_temporal_layer_subset_flag(p_desc)) + desc38_header_size = DESC38_HEADER_SIZE2; + return desc_get_length(p_desc) >= (desc38_header_size - DESC_HEADER_SIZE); +} + +static inline void desc38_print(const uint8_t *p_desc, f_print pf_print, + void *opaque, print_type_t i_print_type) +{ + switch (i_print_type) { + case PRINT_XML: + pf_print(opaque, " + * + * 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_DESC_3F_H__ +#define __BITSTREAM_MPEG_DESC_3F_H__ + +#include +#include + +#ifdef __cplusplus +extern "C" +{ +#endif + +/***************************************************************************** + * Descriptor 0x3f (HEVC timing and HRD descriptor) + *****************************************************************************/ +#define DESC3F_HEADER_SIZE (DESC_HEADER_SIZE + 1 + 1) +#define DESC3F_HEADER_SIZE2 (DESC3F_HEADER_SIZE + 5) +#define DESC3F_HEADER_SIZE3 (DESC3F_HEADER_SIZE + 5 + 8) + +static inline void desc3f_init(uint8_t *p_desc) +{ + desc_set_tag(p_desc, 0x3f); + p_desc[2] = 0x03; // Extension descriptor tag + desc_set_length(p_desc, DESC3F_HEADER_SIZE - DESC_HEADER_SIZE); +} + +static inline bool desc3f_get_hrd_management_valid_flag(const uint8_t *p_desc) +{ + return (p_desc[3] & 0x80) == 0x80; +} + +static inline void desc3f_set_hrd_management_valid_flag(uint8_t *p_desc, bool hrd_management_valid_flag) +{ + p_desc[3] = hrd_management_valid_flag ? (p_desc[3] | 0x80) : (p_desc[3] & ~0x80); +} + +static inline bool desc3f_get_target_schedule_idx_not_present_flag(const uint8_t *p_desc) +{ + return (p_desc[3] & 0x40) == 0x40; +} + +static inline void desc3f_set_target_schedule_idx_not_present_flag(uint8_t *p_desc, bool target_schedule_idx_not_present_flag) +{ + p_desc[3] = target_schedule_idx_not_present_flag ? p_desc[3] | 0x40 : p_desc[3] & ~0x40; +} + +static inline uint8_t desc3f_get_target_schedule_idx(const uint8_t *p_desc) +{ + return (p_desc[3] >> 1) & 0x1f; +} + +static inline void desc3f_set_target_schedule_idx(uint8_t *p_desc, uint8_t target_schedule_idx) +{ + p_desc[3] |= (target_schedule_idx << 1); +} + +static inline bool desc3f_get_picture_and_timing_info_present_flag(const uint8_t *p_desc) +{ + return (p_desc[3] & 0x01) == 0x01; +} + +static inline void desc3f_set_picture_and_timing_info_present_flag(uint8_t *p_desc, bool picture_and_timing_info_present_flag) +{ + if (picture_and_timing_info_present_flag) + { + desc_set_length(p_desc, DESC3F_HEADER_SIZE2 - DESC_HEADER_SIZE); + p_desc[3] |= 0x01; + } + else + { + desc_set_length(p_desc, DESC3F_HEADER_SIZE - DESC_HEADER_SIZE); + p_desc[3] &= ~0x01; + } +} + +static inline bool desc3f_get_90khz_flag(const uint8_t *p_desc) +{ + if (desc3f_get_picture_and_timing_info_present_flag(p_desc)) + return (p_desc[4] & 0x80) == 0x80; + return false; +} + +static inline void desc3f_set_90khz_flag(uint8_t *p_desc, bool b_90kHz_flag) +{ + if (!desc3f_get_picture_and_timing_info_present_flag(p_desc)) + return; + if (b_90kHz_flag) + { + p_desc[4] = 0xff; + desc_set_length(p_desc, DESC3F_HEADER_SIZE2 - DESC_HEADER_SIZE); + } + else + { + p_desc[4] = 0x7f; + desc_set_length(p_desc, DESC3F_HEADER_SIZE3 - DESC_HEADER_SIZE); + } +} + +static inline uint32_t desc3f_get_N(const uint8_t *p_desc) +{ + if (!desc3f_get_picture_and_timing_info_present_flag(p_desc)) + return 0; + if (desc3f_get_90khz_flag(p_desc)) + return 0; + return (p_desc[5] << 24) | (p_desc[6] << 16) | (p_desc[7] << 8) | p_desc[8]; +} + +static inline void desc3f_set_N(uint8_t *p_desc, uint32_t N) +{ + if (!desc3f_get_picture_and_timing_info_present_flag(p_desc)) + return; + if (desc3f_get_90khz_flag(p_desc)) + return; + p_desc[5] = (N >> 24) & 0xff; + p_desc[6] = (N >> 16) & 0xff; + p_desc[7] = (N >> 8) & 0xff; + p_desc[8] = N & 0xff; +} + +static inline uint32_t desc3f_get_K(const uint8_t *p_desc) +{ + if (!desc3f_get_picture_and_timing_info_present_flag(p_desc)) + return UINT32_MAX; + if (desc3f_get_90khz_flag(p_desc)) + return UINT32_MAX; + return (p_desc[9] << 24) | (p_desc[10] << 16) | (p_desc[11] << 8) | p_desc[12]; +} + +static inline void desc3f_set_K(uint8_t *p_desc, uint32_t K) +{ + if (!desc3f_get_picture_and_timing_info_present_flag(p_desc)) + return; + if (desc3f_get_90khz_flag(p_desc)) + return; + p_desc[ 9] = (K >> 24) & 0xff; + p_desc[10] = (K >> 16) & 0xff; + p_desc[11] = (K >> 8) & 0xff; + p_desc[12] = K & 0xff; +} + +static inline uint32_t desc3f_get_num_units_in_tick(const uint8_t *p_desc) +{ + if (!desc3f_get_picture_and_timing_info_present_flag(p_desc)) + return 0; + uint8_t ofs = desc3f_get_90khz_flag(p_desc) == 0 ? 13 : 5; + return (p_desc[ofs+0] << 24) | (p_desc[ofs+1] << 16) | (p_desc[ofs+2] << 8) | p_desc[ofs+3]; +} + +static inline void desc3f_set_num_units_in_tick(uint8_t *p_desc, uint32_t num_units_in_tick) +{ + if (!desc3f_get_picture_and_timing_info_present_flag(p_desc)) + return; + uint8_t ofs = desc3f_get_90khz_flag(p_desc) == 0 ? 13 : 5; + p_desc[ofs+0] = (num_units_in_tick >> 24) & 0xff; + p_desc[ofs+1] = (num_units_in_tick >> 16) & 0xff; + p_desc[ofs+2] = (num_units_in_tick >> 8) & 0xff; + p_desc[ofs+3] = num_units_in_tick & 0xff; +} + +static inline bool desc3f_validate(const uint8_t *p_desc) +{ + uint8_t desc3f_header_size = DESC3F_HEADER_SIZE; + if (desc3f_get_picture_and_timing_info_present_flag(p_desc)) + { + if (desc3f_get_90khz_flag(p_desc)) + desc3f_header_size = DESC3F_HEADER_SIZE3; + else + desc3f_header_size = DESC3F_HEADER_SIZE2; + + } + return desc_get_length(p_desc) >= (desc3f_header_size - DESC_HEADER_SIZE); +} + +static inline void desc3f_print(const uint8_t *p_desc, f_print pf_print, + void *opaque, print_type_t print_type) +{ + switch (print_type) + { + case PRINT_XML: + pf_print(opaque,"" + , + desc3f_get_hrd_management_valid_flag(p_desc), + desc3f_get_target_schedule_idx_not_present_flag(p_desc), + desc3f_get_picture_and_timing_info_present_flag(p_desc), + desc3f_get_90khz_flag(p_desc), + desc3f_get_N(p_desc), + desc3f_get_K(p_desc), + desc3f_get_num_units_in_tick(p_desc) + ); + break; + default: + pf_print(opaque," - desc 2a hevc_timing_and_hrd hrd_management_valid_flag=%u" + "target_schedule_idx_not_present_flag=%u" + " picture_and_timing_info_present_flag=%u" + " flag_90khz=%u N=%u K=%u num_units_in_tick=%u" + , + desc3f_get_hrd_management_valid_flag(p_desc), + desc3f_get_target_schedule_idx_not_present_flag(p_desc), + desc3f_get_picture_and_timing_info_present_flag(p_desc), + desc3f_get_90khz_flag(p_desc), + desc3f_get_N(p_desc), + desc3f_get_K(p_desc), + desc3f_get_num_units_in_tick(p_desc) + ); + } +} + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/mpeg/psi/descs_list.h b/mpeg/psi/descs_list.h index 35138d3..2501b2e 100644 --- a/mpeg/psi/descs_list.h +++ b/mpeg/psi/descs_list.h @@ -68,5 +68,7 @@ #include #include #include +#include +#include #endif diff --git a/mpeg/ts.h b/mpeg/ts.h index 404d9b3..4554751 100644 --- a/mpeg/ts.h +++ b/mpeg/ts.h @@ -268,6 +268,11 @@ static inline bool tsaf_has_pcr(const uint8_t *p_ts) return !!(p_ts[5] & 0x10); } +static inline bool tsaf_has_opcr(const uint8_t *p_ts) +{ + return !!(p_ts[5] & 0x8); +} + static inline uint64_t tsaf_get_pcr(const uint8_t *p_ts) { return ((uint64_t) p_ts[6] << 25) | (p_ts[7] << 17) | (p_ts[8] << 9) | (p_ts[9] << 1) | @@ -279,6 +284,61 @@ static inline uint64_t tsaf_get_pcrext(const uint8_t *p_ts) return ((p_ts[10] & 1) << 8) | p_ts[11]; } +static inline void tsaf_set_splicing_point(uint8_t *p_ts) +{ + p_ts[5] |= 0x4; +} + +static inline bool tsaf_has_splicing_point(const uint8_t *p_ts) +{ + return !!(p_ts[5] & 0x4); +} + +static inline void tsaf_set_transport_private_data(uint8_t *p_ts) +{ + p_ts[5] |= 0x2; +} + +static inline bool tsaf_has_transport_private_data(const uint8_t *p_ts) +{ + return !!(p_ts[5] & 0x2); +} + +static inline uint8_t *ts_splice_countdown(uint8_t *p_ts) +{ + return (p_ts + 6 + (tsaf_has_pcr(p_ts) ? 6 : 0) + (tsaf_has_opcr(p_ts) ? 6 : 0)); +} + +static inline void tsaf_set_splice_countdown(uint8_t *p_ts, uint8_t i_splice_countdown) +{ + uint8_t *p_payload = ts_splice_countdown(p_ts); + *p_payload = i_splice_countdown; +} + +static inline uint8_t *ts_private_data(uint8_t *p_ts) +{ + return ts_splice_countdown(p_ts) + (tsaf_has_splicing_point(p_ts) ? 1: 0); +} + +static inline void tsaf_set_ts_private_data(uint8_t *p_ts, uint8_t i_length) +{ + uint8_t *p_payload; + p_ts[5] |= 0x2; + p_payload = ts_private_data(p_ts); + *p_payload = i_length; +} + +static inline uint8_t tsaf_get_private_data_length(uint8_t *p_ts) +{ + uint8_t *p_payload = ts_private_data(p_ts); + return p_payload[0]; +} + +static inline uint8_t tsaf_get_private_data_tag(uint8_t *p_ts) +{ + uint8_t *p_payload = ts_private_data(p_ts); + return p_payload[1]; +} /***************************************************************************** * TS payload gathering *****************************************************************************/