From gitlab at videolan.org Wed Mar 5 10:43:14 2025 From: gitlab at videolan.org (Christophe Massiot (@cmassiot)) Date: Wed, 05 Mar 2025 11:43:14 +0100 Subject: [bTSstream-devel] [Git][videolan/bitstream][master] 2 commits: dvb/si/desc_6f: fix typo Message-ID: <67c82ac2da286_80ce75c660126251b@gitlab.mail> Christophe Massiot pushed to branch master at VideoLAN / bitstream Commits: f1c59857 by Arnaud de Turckheim at 2025-03-03T17:59:47+01:00 dvb/si/desc_6f: fix typo - - - - - 612b0160 by Christophe Massiot at 2025-03-05T11:42:41+01:00 Merge branch 'quarium-typo' - - - - - 1 changed file: - dvb/si/desc_6f.h Changes: ===================================== dvb/si/desc_6f.h ===================================== @@ -1,5 +1,5 @@ /***************************************************************************** - * desc_6f.h: ETSI EN 300 468 Descriptor 0x7f: Application signalling + * desc_6f.h: ETSI EN 300 468 Descriptor 0x6f: Application signalling * descriptor ***************************************************************************** * Copyright (C) 2022 EasyTools View it on GitLab: https://code.videolan.org/videolan/bitstream/-/compare/1a29d709aeeb4a80d2f9e2b5fcb27c4e223a113b...612b01604e2920f2941b52431997afca1abd64c0 -- View it on GitLab: https://code.videolan.org/videolan/bitstream/-/compare/1a29d709aeeb4a80d2f9e2b5fcb27c4e223a113b...612b01604e2920f2941b52431997afca1abd64c0 You're receiving this email because of your account on code.videolan.org. VideoLAN code repository instance From gitlab at videolan.org Wed Mar 5 10:47:32 2025 From: gitlab at videolan.org (Christophe Massiot (@cmassiot)) Date: Wed, 05 Mar 2025 11:47:32 +0100 Subject: [bTSstream-devel] [Git][videolan/bitstream][master] 3 commits: dvb/si: add AIT Message-ID: <67c82bc4c6d95_80c7e76100126351e@gitlab.mail> Christophe Massiot pushed to branch master at VideoLAN / bitstream Commits: 915db7d1 by Arnaud de Turckheim at 2025-03-03T18:04:24+01:00 dvb/si: add AIT - - - - - b3774681 by Arnaud de Turckheim at 2025-03-05T11:47:10+01:00 dvb/si/desc_6f: fix typo - - - - - ebc8106c by Christophe Massiot at 2025-03-05T11:47:18+01:00 Merge branch 'quarium-ait' - - - - - 5 changed files: - dvb/si.h - + dvb/si/ait.h - + dvb/si/ait_print.h - dvb/si_print.h - examples/dvb_print_si.c Changes: ===================================== dvb/si.h ===================================== @@ -51,5 +51,6 @@ #include #include #include +#include #endif ===================================== dvb/si/ait.h ===================================== @@ -0,0 +1,413 @@ +/***************************************************************************** + * ait.h: ETSI TS 102 809 Application Information Table (AIT) + ***************************************************************************** + * Copyright (C) 2024 EasyTools + * + * Authors: Arnaud de Turckheim + * + * 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 102 809 V1.1.1 (2010-01) (Signalling and carriage of interactive + * applications and services) + */ + +#ifndef __BITSTREAM_DVB_AIT_H__ +#define __BITSTREAM_DVB_AIT_H__ + +#include +#include +#include + +#ifdef __cplusplus +extern "C" +{ +#endif + +/***************************************************************************** + * Application Information Table descriptors + *****************************************************************************/ +#define AIT_DESC_APP 0x00 + +#define AIT_DESC_APP_SIZE 3 +#define AIT_DESC_APP_PROFILE_SIZE 5 + +static inline uint8_t ait_desc_app_get_profilelength(const uint8_t *p_desc) +{ + return p_desc[2]; +} + +static inline uint8_t *ait_desc_app_next_profile(const uint8_t *p_desc, + uint8_t *p_profile) +{ + uint8_t profilelength = ait_desc_app_get_profilelength(p_desc); + + if (!p_profile) + p_profile = (uint8_t *)p_desc + 3; + else + p_profile += AIT_DESC_APP_PROFILE_SIZE; + return p_profile - p_desc - 3 + AIT_DESC_APP_PROFILE_SIZE > profilelength ? + NULL : p_profile; +} + +#define ait_desc_app_each_profile(DESC, PROFILE) \ + for (uint8_t *PROFILE = ait_desc_app_next_profile(DESC, NULL); \ + PROFILE != NULL; \ + PROFILE = ait_desc_app_next_profile(DESC, PROFILE)) + +static inline uint16_t ait_desc_app_profile_get_type(const uint8_t *p_profile) +{ + return p_profile[0] << 8 | p_profile[1]; +} + +static inline uint8_t ait_desc_app_profile_get_major(const uint8_t *p_profile) +{ + return p_profile[2]; +} + +static inline uint8_t ait_desc_app_profile_get_minor(const uint8_t *p_profile) +{ + return p_profile[3]; +} + +static inline uint8_t ait_desc_app_profile_get_micro(const uint8_t *p_profile) +{ + return p_profile[4]; +} + +static inline uint8_t ait_desc_app_get_service_bound(const uint8_t *p_desc) +{ + uint8_t profilelength = ait_desc_app_get_profilelength(p_desc); + return (p_desc[3 + profilelength] >> 7) & 0x1; +} + +static inline uint8_t ait_desc_app_get_visibily(const uint8_t *p_desc) +{ + uint8_t profilelength = ait_desc_app_get_profilelength(p_desc); + return (p_desc[3 + profilelength] >> 5) & 0x3; +} + +static inline uint8_t ait_desc_app_get_priority(const uint8_t *p_desc) +{ + uint8_t profilelength = ait_desc_app_get_profilelength(p_desc); + return p_desc[3 + profilelength + 1]; +} + +static inline uint8_t *ait_desc_app_next_transport_proto(const uint8_t *p_desc, + uint8_t *p_proto) +{ + const uint8_t *p_end = p_desc + DESC_HEADER_SIZE + desc_get_length(p_desc); + uint8_t profilelength = ait_desc_app_get_profilelength(p_desc); + if (!p_proto) + p_proto = (uint8_t *)p_desc + 5 + profilelength; + else + p_proto++; + return p_proto >= p_end ? NULL : p_proto; +} + +#define ait_desc_app_each_transport_proto(DESC, PROTO) \ + for (uint8_t *PROTO = ait_desc_app_next_transport_proto(DESC, NULL); \ + PROTO != NULL; \ + PROTO = ait_desc_app_next_transport_proto(DESC, PROTO)) + +static inline bool ait_desc_app_validate(const uint8_t *p_desc) +{ + uint8_t tag = desc_get_tag(p_desc); + uint8_t length = desc_get_length(p_desc); + + if (tag != AIT_DESC_APP || length < AIT_DESC_APP_SIZE) + return false; + + uint8_t profilelength = ait_desc_app_get_profilelength(p_desc); + if (length < AIT_DESC_APP + profilelength) + return false; + return true; +} + +#define AIT_DESC_APP_NAME 0x01 + +static inline uint8_t *ait_desc_app_name_get_code(const uint8_t *p_name) +{ + return (uint8_t *)p_name; +} + +static inline uint8_t ait_desc_app_name_get_textlength(const uint8_t *p_name) +{ + return p_name[3]; +} + +static inline uint8_t *ait_desc_app_name_get_text(const uint8_t *p_name, + uint8_t *text_len) +{ + if (text_len) + *text_len = p_name[3]; + return (uint8_t *)p_name + 4; +} + +static inline uint8_t *ait_desc_app_name_next_name(const uint8_t *p_desc, + uint8_t *p_name) +{ + const uint8_t *p_end = p_desc + DESC_HEADER_SIZE + desc_get_length(p_desc); + if (!p_name) + p_name = (uint8_t *)p_desc + DESC_HEADER_SIZE; + else + p_name += 3 + ait_desc_app_name_get_textlength(p_name); + return p_name + 3 > p_end ? NULL : p_name; +} + +#define ait_desc_app_name_each_name(DESC, NAME) \ + for (uint8_t *NAME = ait_desc_app_name_next_name(DESC, NULL); \ + NAME != NULL; \ + NAME = ait_desc_app_name_next_name(DESC, NAME)) + +static inline bool ait_desc_app_name_validate(const uint8_t *p_desc) +{ + return desc_get_tag(p_desc) == AIT_DESC_APP_NAME; +} + +#define AIT_DESC_TRANSPORT_PROTO 0x02 + +#define AIT_DESC_TRANSPORT_PROTO_SIZE 3 + +static inline uint16_t ait_desc_transport_proto_get_id(const uint8_t *p_desc) +{ + return p_desc[2] << 8 | p_desc[3]; +} + +static inline uint8_t ait_desc_transport_proto_get_label(const uint8_t *p_desc) +{ + return p_desc[4]; +} + +static inline bool ait_desc_transport_proto_validate(const uint8_t *p_desc) +{ + uint8_t tag = desc_get_tag(p_desc); + uint8_t length = desc_get_length(p_desc); + + return tag == AIT_DESC_TRANSPORT_PROTO && + length >= AIT_DESC_TRANSPORT_PROTO_SIZE; +} + + +#define AIT_DESC_EXTERNAL_APP_AUTH 0x05 +#define AIT_DESC_APP_RECORD 0x06 +#define AIT_DESC_APP_ICON 0x0B +#define AIT_DESC_APP_STORAGE 0x10 +#define AIT_DESC_GRAPH_CONSTRAINS 0x14 +#define AIT_DESC_APP_LOCATION 0x15 + +static inline uint8_t * +ait_desc_app_location_get_initial_path(const uint8_t *p_desc, uint8_t *length) +{ + if (length) + *length = p_desc[1]; + return (uint8_t *)p_desc + 2; +} + +static inline bool ait_desc_app_location_validate(const uint8_t *p_desc) +{ + return desc_get_tag(p_desc) == AIT_DESC_APP_LOCATION; +} + +#define AIT_DESC_APP_USAGE 0x16 +#define AIT_DESC_APP_BOUND 0x17 +#define AIT_DESC_PRIVATE_DATA 0x5F + + +/***************************************************************************** + * Application Information Table + *****************************************************************************/ +#define AIT_TABLE_ID 0x74 +#define AIT_HEADER_SIZE (PSI_HEADER_SIZE_SYNTAX1 + 4) +#define AIT_APP_IDENTIFIER_SIZE 6 +#define AIT_APP_SIZE (AIT_APP_IDENTIFIER_SIZE + 3) + +static inline void ait_init(uint8_t *p_ait) +{ + psi_init(p_ait, true); + psi_set_tableid(p_ait, AIT_TABLE_ID); + p_ait[8] = 0xf0; +} + +static inline void ait_set_length(uint8_t *p_ait, uint16_t i_ait_length) +{ + psi_set_length(p_ait, AIT_HEADER_SIZE + PSI_CRC_SIZE - PSI_HEADER_SIZE + + i_ait_length); +} + +static inline void ait_set_desclength(uint8_t *p_ait, uint16_t i_length) +{ + p_ait[8] &= ~0xf; + p_ait[8] |= i_length >> 8; + p_ait[9] = i_length & 0xff; +} + +static inline uint16_t ait_get_desclength(const uint8_t *p_ait) +{ + return ((p_ait[8] & 0xf) << 8) | p_ait[9]; +} + +static inline uint8_t *ait_get_descs(uint8_t *p_ait) +{ + return &p_ait[8]; +} + +static inline uint32_t aitn_get_organisation_id(const uint8_t *p_aitn) +{ + return p_aitn[0] << 24 | p_aitn[1] << 16 | p_aitn[2] << 8 | p_aitn[3]; +} + +static inline uint16_t aitn_get_application_id(const uint8_t *p_aitn) +{ + return p_aitn[4] << 8 | p_aitn[5]; +} + +#define AITN_CONTROL_CODE_AUTOSTART 0x01 +#define AITN_CONTROL_CODE_PRESENT 0x02 +#define AITN_CONTROL_CODE_DESTROY 0x03 +#define AITN_CONTROL_CODE_KILL 0x04 +#define AITN_CONTROL_CODE_PREFETCH 0x05 +#define AITN_CONTROL_CODE_REMOTE 0x06 +#define AITN_CONTROL_CODE_DISABLED 0x07 +#define AITN_CONTROL_CODE_PLAYBACK_AUTOSTART 0x08 + +static inline const char *aitn_control_code_txt(uint8_t i_control_code) +{ + switch (i_control_code) { + case AITN_CONTROL_CODE_AUTOSTART: return "autostart"; + case AITN_CONTROL_CODE_PRESENT: return "present"; + case AITN_CONTROL_CODE_DESTROY: return "destroy"; + case AITN_CONTROL_CODE_KILL: return "kill"; + case AITN_CONTROL_CODE_PREFETCH: return "prefetch"; + case AITN_CONTROL_CODE_REMOTE: return "remote"; + case AITN_CONTROL_CODE_DISABLED: return "disabled"; + case AITN_CONTROL_CODE_PLAYBACK_AUTOSTART: return "playback autostart"; + default: + return "Reserved"; + } +} + +static inline uint8_t aitn_get_control_code(const uint8_t *p_aitn) +{ + return p_aitn[6]; +} + +static inline void aitn_set_desclength(uint8_t *p_aitn, uint16_t i_length) +{ + p_aitn[7] &= ~0xf; + p_aitn[7] |= i_length >> 8; + p_aitn[8] = i_length & 0xff; +} + +static inline uint16_t aitn_get_desclength(const uint8_t *p_aitn) +{ + return ((p_aitn[7] & 0xf) << 8) | p_aitn[8]; +} + +static inline uint8_t *aitn_get_descs(uint8_t *p_aitn) +{ + return &p_aitn[7]; +} + +#define aitn_each_desc(AITN, DESC) descs_each_desc(aitn_get_descs(AITN), DESC) + +static inline uint8_t *ait_next_app(const uint8_t *p_ait, uint8_t *p_ait_n) +{ + uint16_t i_section_size = + psi_get_length(p_ait) + PSI_HEADER_SIZE - PSI_CRC_SIZE; + if (!p_ait_n) + p_ait_n = (uint8_t *)p_ait + AIT_HEADER_SIZE + + ait_get_desclength(p_ait); + else { + if (p_ait_n + AIT_APP_SIZE - p_ait > i_section_size) return NULL; + p_ait_n += AIT_APP_SIZE + aitn_get_desclength(p_ait_n); + } + return (p_ait_n - p_ait < i_section_size) ? p_ait_n : NULL; +} + +#define ait_each_app(AIT, APP) \ + for (uint8_t *APP = ait_next_app(AIT, NULL); \ + APP; \ + APP = ait_next_app(AIT, APP)) + +static inline uint8_t *ait_get_apps(uint8_t *p_ait) +{ + uint16_t desclength = ait_get_desclength(p_ait); + return ait_get_descs(p_ait) + 2 + desclength; +} + +static inline void ait_set_applength(uint8_t *p_ait, uint16_t i_length) +{ + uint8_t *p_apps = ait_get_apps(p_ait); + p_apps[0] &= ~0xf; + p_apps[0] |= i_length >> 8; + p_apps[1] = i_length & 0xff; +} + +static inline uint16_t ait_get_appslength(const uint8_t *p_ait) +{ + const uint8_t *p_apps = ait_get_apps((uint8_t *)p_ait); + return ((p_apps[0] & 0xf) << 8) | p_apps[1]; +} + +static inline bool ait_validate(const uint8_t *p_ait) +{ + uint16_t i_section_size = + psi_get_length(p_ait) + PSI_HEADER_SIZE - PSI_CRC_SIZE; + + if (!psi_get_syntax(p_ait) || psi_get_tableid(p_ait) != AIT_TABLE_ID) + return false; + + if (i_section_size < AIT_HEADER_SIZE + || i_section_size < AIT_HEADER_SIZE + ait_get_desclength(p_ait)) + return false; + + if (!descs_validate(p_ait + 8)) + return false; + + ait_each_app(p_ait, p_app) { + if (!descs_validate(p_app + 7)) + return false; + } + return true; +} + +static inline bool ait_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); + + if (!psi_check_crc(p_section)) + return false; + } + + return true; +} + +#ifdef __cplusplus +} +#endif + +#endif ===================================== dvb/si/ait_print.h ===================================== @@ -0,0 +1,278 @@ +/***************************************************************************** + * ait_print.h: ETSI TS 102 809 Application Information Table (AIT) (printing) + ***************************************************************************** + * Copyright (C) 2024 EasyTools + * + * Authors: Arnaud de Turckheim + * + * 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_DVB_AIT_PRINT_H__ +#define __BITSTREAM_DVB_AIT_PRINT_H__ + +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" +{ +#endif + +/***************************************************************************** + * Application Information Table descriptors + *****************************************************************************/ +static inline void ait_desc_app_print(const uint8_t *p_desc, + f_print pf_print, void *print_opaque, + f_iconv pf_iconv, void *iconv_opaque, + print_type_t i_print_type) +{ + switch (i_print_type) { + case PRINT_XML: + pf_print(print_opaque, "", + ait_desc_app_get_service_bound(p_desc) ? "true" : "false", + ait_desc_app_get_visibily(p_desc), + ait_desc_app_get_priority(p_desc)); + break; + default: + pf_print(print_opaque, " - app service_bound=%s visibilty=%u " + "priority=%u", + ait_desc_app_get_service_bound(p_desc) ? "true" : "false", + ait_desc_app_get_visibily(p_desc), + ait_desc_app_get_priority(p_desc)); + } + + ait_desc_app_each_profile(p_desc, p_profile) { + switch (i_print_type) { + case PRINT_XML: + pf_print(print_opaque, "", + ait_desc_app_profile_get_type(p_profile), + ait_desc_app_profile_get_major(p_profile), + ait_desc_app_profile_get_minor(p_profile), + ait_desc_app_profile_get_micro(p_profile)); + break; + + default: + pf_print(print_opaque, " - profile type=%u " + "version=%u.%u.%u", + ait_desc_app_profile_get_type(p_profile), + ait_desc_app_profile_get_major(p_profile), + ait_desc_app_profile_get_minor(p_profile), + ait_desc_app_profile_get_micro(p_profile)); + + } + } + + ait_desc_app_each_transport_proto(p_desc, p_proto) { + switch (i_print_type) { + case PRINT_XML: + pf_print(print_opaque, "", + *p_proto); + break; + + default: + pf_print(print_opaque, " - transport_protocol %u", + *p_proto); + } + } +} + +static inline void ait_desc_app_name_print(const uint8_t *p_desc, + f_print pf_print, void *print_opaque, + f_iconv pf_iconv, void *iconv_opaque, + print_type_t i_print_type) +{ + switch (i_print_type) { + case PRINT_XML: + pf_print(print_opaque, ""); + break; + default: + pf_print(print_opaque, " - app_name"); + } + + ait_desc_app_name_each_name(p_desc, p_name) { + uint8_t *code = ait_desc_app_name_get_code(p_name); + uint8_t text_len; + const uint8_t *text = ait_desc_app_name_get_text(p_name, &text_len); + char *psz_text = dvb_string_get(text, text_len, pf_iconv, iconv_opaque); + + switch (i_print_type) { + case PRINT_XML: + pf_print(print_opaque, "", + (char *)code, psz_text); + break; + + default: + pf_print(print_opaque, " - language=%3.3s test=\"%s\"", + (char *)code, psz_text); + } + + free(psz_text); + } +} + +static inline void ait_desc_transport_proto_print(const uint8_t *p_desc, + f_print pf_print, + void *print_opaque, + f_iconv pf_iconv, + void *iconv_opaque, + print_type_t i_print_type) +{ + switch (i_print_type) { + case PRINT_XML: + pf_print(print_opaque, "", + ait_desc_transport_proto_get_id(p_desc), + ait_desc_transport_proto_get_label(p_desc)); + break; + default: + pf_print(print_opaque, " - transport_protocol id=%u label=%u", + ait_desc_transport_proto_get_id(p_desc), + ait_desc_transport_proto_get_label(p_desc)); + } +} + +static inline void ait_desc_app_location_print(const uint8_t *p_desc, + f_print pf_print, + void *print_opaque, + f_iconv pf_iconv, + void *iconv_opaque, + print_type_t i_print_type) +{ + uint8_t initial_path_len; + uint8_t *initial_path = + ait_desc_app_location_get_initial_path(p_desc, &initial_path_len); + switch (i_print_type) { + case PRINT_XML: + pf_print(print_opaque, "", + ait_desc_transport_proto_get_id(p_desc), + ait_desc_transport_proto_get_label(p_desc), + (int)initial_path_len, (char *)initial_path); + break; + default: + pf_print(print_opaque, " - transport_protocol id=%u label=%u " + "initial_path=\"%.*s\"", + ait_desc_transport_proto_get_id(p_desc), + ait_desc_transport_proto_get_label(p_desc), + (int)initial_path_len, (char *)initial_path); + } +} + +/***************************************************************************** + * Application Information Table + *****************************************************************************/ +static inline void ait_table_print(uint8_t **pp_sections, + f_print pf_print, void *print_opaque, + f_iconv pf_iconv, void *iconv_opaque, + print_type_t i_print_type) +{ + uint8_t i_last_section = psi_table_get_lastsection(pp_sections); + uint8_t i; + + uint16_t idext = psi_table_get_tableidext(pp_sections); + uint8_t test = idext & 0x8000 ? 1 : 0; + uint16_t type = idext & 0x7fff; + + switch (i_print_type) { + case PRINT_XML: + pf_print(print_opaque, "", + test ? "true" : "false", + type, + psi_table_get_version(pp_sections), + !psi_table_get_current(pp_sections) ? 0 : 1); + break; + default: + pf_print(print_opaque, "new AIT %stype=%hu version=%hhu%s", + test ? "test " : "", + type, + psi_table_get_version(pp_sections), + !psi_table_get_current(pp_sections) ? " (next)" : ""); + } + + descs_print(ait_get_descs(psi_table_get_section(pp_sections, 0)), + pf_print, print_opaque, pf_iconv, iconv_opaque, i_print_type); + + for (i = 0; i <= i_last_section; i++) { + uint8_t *p_section = psi_table_get_section(pp_sections, i); + + ait_each_app(p_section, p_app) { + switch (i_print_type) { + case PRINT_XML: + break; + default: + pf_print(print_opaque, " * app organisation=%u id=%hu " + "control_code=%s", + aitn_get_organisation_id(p_app), + aitn_get_application_id(p_app), + aitn_control_code_txt(aitn_get_control_code(p_app)) + ); + break; + } + + aitn_each_desc(p_app, p_desc) { + uint8_t tag = desc_get_tag(p_desc); + + switch (tag) { +#define CASE_DESC(Value, Name) \ + case AIT_DESC_##Value: \ + if (ait_desc_##Name##_validate(p_desc)) \ + ait_desc_##Name##_print(p_desc, \ + pf_print, print_opaque, \ + pf_iconv, iconv_opaque, \ + i_print_type); \ + else \ + desc_print_error(p_desc, pf_print, print_opaque, \ + i_print_type); \ + break; + + CASE_DESC(APP, app) + CASE_DESC(APP_NAME, app_name) + CASE_DESC(TRANSPORT_PROTO, transport_proto) + CASE_DESC(APP_LOCATION, app_location) +#undef CASE_DESC + + default: + desc_print(p_desc, pf_print, print_opaque, i_print_type); + break; + } + } + } + } + + switch (i_print_type) { + case PRINT_XML: + pf_print(print_opaque, ""); + break; + default: + pf_print(print_opaque, "end AIT"); + } +} + +#ifdef __cplusplus +} +#endif + +#endif ===================================== dvb/si_print.h ===================================== @@ -38,5 +38,6 @@ #include #include #include +#include #endif ===================================== examples/dvb_print_si.c ===================================== @@ -89,6 +89,8 @@ static PSI_TABLE_DECLARE(pp_current_nit_sections); static PSI_TABLE_DECLARE(pp_next_nit_sections); static PSI_TABLE_DECLARE(pp_current_sdt_sections); static PSI_TABLE_DECLARE(pp_next_sdt_sections); +static PSI_TABLE_DECLARE(pp_current_ait_sections); +static PSI_TABLE_DECLARE(pp_next_ait_sections); static const char *psz_native_encoding = "UTF-8"; static const char *psz_current_encoding = ""; @@ -111,11 +113,12 @@ enum tables_t { TABLE_SIT, TABLE_PMT, TABLE_SCTE35, + TABLE_AIT, TABLE_END }; static const char * const ppsz_all_tables[TABLE_END] = { "pat", "cat", "tsdt", "nit", "bat", "sdt", "eit", "tot", "tdt", "rst", - "dit", "sit", "pmt", "scte35" + "dit", "sit", "pmt", "scte35", "ait" }; static bool pb_print_table[TABLE_END]; @@ -461,14 +464,27 @@ static void handle_tsdt_section(uint16_t i_pid, uint8_t *p_section) *****************************************************************************/ static void handle_pmt_es(uint8_t *p_pmt, bool b_select) { - int j = 0; - uint8_t *p_es; - while ((p_es = pmt_get_es(p_pmt, j)) != NULL) { + pmt_each_es(p_pmt, p_es) { uint16_t i_pid = pmtn_get_pid(p_es); uint8_t i_type = pmtn_get_streamtype(p_es); - j++; switch (i_type) { + case PMT_STREAMTYPE_PRIVATE_PSI: + pmtn_each_desc(p_es, p_desc) { + uint8_t tag = desc_get_tag(p_desc); + + switch (tag) { + case 0x6f: + if (b_select) + p_pids[i_pid].i_psi_refcount++; + else + p_pids[i_pid].i_psi_refcount--; + break; + default: + break; + } + } + break; case PMT_STREAMTYPE_SCTE_35: if (b_select) p_pids[i_pid].i_psi_refcount++; @@ -961,6 +977,63 @@ static void handle_scte35_section(uint16_t i_pid, uint8_t *p_scte35) free(p_scte35); } +/***************************************************************************** + * handle_ait + *****************************************************************************/ +static void handle_ait(void) +{ + if (psi_table_validate(pp_current_ait_sections) && + psi_table_compare(pp_current_ait_sections, pp_next_ait_sections)) { + /* Same version AIT. Shortcut. */ + psi_table_free(pp_next_ait_sections); + psi_table_init(pp_next_ait_sections); + return; + } + + if (!ait_table_validate(pp_next_ait_sections)) { + switch (i_print_type) { + case PRINT_XML: + printf("\n"); + break; + default: + printf("invalid AIT received\n"); + } + psi_table_free(pp_next_ait_sections); + psi_table_init(pp_next_ait_sections); + return; + } + + /* Switch tables. */ + psi_table_free(pp_current_ait_sections); + psi_table_copy(pp_current_ait_sections, pp_next_ait_sections); + psi_table_init(pp_next_ait_sections); + + if (pb_print_table[TABLE_AIT]) + ait_table_print(pp_current_ait_sections, print_wrapper, NULL, + iconv_wrapper, NULL, i_print_type); +} + +static void handle_ait_section(uint16_t i_pid, uint8_t *p_section) +{ + if (!ait_validate(p_section)) { + switch (i_print_type) { + case PRINT_XML: + printf("\n", + i_pid); + break; + default: + printf("invalid AIT section received on PID %hu\n", i_pid); + } + free(p_section); + return; + } + + if (!psi_table_section(pp_next_ait_sections, p_section)) + return; + + handle_ait(); +} + /***************************************************************************** * handle_section *****************************************************************************/ @@ -1037,6 +1110,10 @@ static void handle_section(uint16_t i_pid, uint8_t *p_section) handle_scte35_section(i_pid, p_section); break; + case AIT_TABLE_ID: + handle_ait_section(i_pid, p_section); + break; + default: free( p_section ); break; View it on GitLab: https://code.videolan.org/videolan/bitstream/-/compare/612b01604e2920f2941b52431997afca1abd64c0...ebc8106ce8279b8be7861ab9e83e9ac42bb528f8 -- View it on GitLab: https://code.videolan.org/videolan/bitstream/-/compare/612b01604e2920f2941b52431997afca1abd64c0...ebc8106ce8279b8be7861ab9e83e9ac42bb528f8 You're receiving this email because of your account on code.videolan.org. VideoLAN code repository instance From gitlab at videolan.org Wed Mar 5 10:50:09 2025 From: gitlab at videolan.org (Christophe Massiot (@cmassiot)) Date: Wed, 05 Mar 2025 11:50:09 +0100 Subject: [bTSstream-devel] [Git][videolan/bitstream][master] 4 commits: scte/35: add avail splice descriptor helpers Message-ID: <67c82c618988d_80c7df57d01264267@gitlab.mail> Christophe Massiot pushed to branch master at VideoLAN / bitstream Commits: 5c6d469c by Arnaud de Turckheim at 2025-03-03T18:10:03+01:00 scte/35: add avail splice descriptor helpers - - - - - dd82c0ae by Arnaud de Turckheim at 2025-03-05T11:49:56+01:00 dvb/si/desc_6f: fix typo - - - - - d2483df1 by Arnaud de Turckheim at 2025-03-05T11:49:56+01:00 dvb/si: add AIT - - - - - 2944df2f by Christophe Massiot at 2025-03-05T11:50:03+01:00 Merge branch 'quarium-avail-splice-desc' - - - - - 1 changed file: - scte/35.h Changes: ===================================== scte/35.h ===================================== @@ -695,6 +695,38 @@ static inline void scte35_splice_desc_set_identifier(uint8_t *p_desc, p_desc[5] = identifier & 0xff; } +/***************************************************************************** + * Splice Information Table - avail descriptor + *****************************************************************************/ +#define SCTE35_AVAIL_DESC_HEADER_SIZE 4 + +static inline void scte35_avail_desc_init(uint8_t *p_desc) +{ + scte35_splice_desc_set_tag(p_desc, SCTE35_SPLICE_DESC_TAG_AVAIL); + scte35_splice_desc_set_length(p_desc, + SCTE35_SPLICE_DESC_HEADER_SIZE - + DESC_HEADER_SIZE + + SCTE35_AVAIL_DESC_HEADER_SIZE); + scte35_splice_desc_set_identifier(p_desc, SCTE35_SPLICE_DESC_IDENTIFIER); + p_desc[10] = 0x7f; +} + +static inline uint32_t +scte35_avail_desc_get_provider_avail_id(const uint8_t *p_desc) +{ + return ((uint32_t)p_desc[6] << 24) | (p_desc[7] << 16) | + (p_desc[8] << 8) | p_desc[9]; +} + +static inline void scte35_avail_desc_set_provider_avail_id(uint8_t *p_desc, + uint32_t id) +{ + p_desc[6] = (id >> 24) & 0xff; + p_desc[7] = (id >> 16) & 0xff; + p_desc[8] = (id >> 8) & 0xff; + p_desc[9] = id & 0xff; +} + /***************************************************************************** * Splice Information Table - segmentation descriptor *****************************************************************************/ View it on GitLab: https://code.videolan.org/videolan/bitstream/-/compare/ebc8106ce8279b8be7861ab9e83e9ac42bb528f8...2944df2f18e761b78af95e7f33adfacf15097ca8 -- View it on GitLab: https://code.videolan.org/videolan/bitstream/-/compare/ebc8106ce8279b8be7861ab9e83e9ac42bb528f8...2944df2f18e761b78af95e7f33adfacf15097ca8 You're receiving this email because of your account on code.videolan.org. VideoLAN code repository instance From gitlab at videolan.org Wed Mar 5 10:51:20 2025 From: gitlab at videolan.org (Christophe Massiot (@cmassiot)) Date: Wed, 05 Mar 2025 11:51:20 +0100 Subject: [bTSstream-devel] [Git][videolan/bitstream][master] 5 commits: scte/35: add time descriptor Message-ID: <67c82ca8df16_80c7df57d01264864@gitlab.mail> Christophe Massiot pushed to branch master at VideoLAN / bitstream Commits: 7365a98c by Arnaud de Turckheim at 2025-03-03T18:13:48+01:00 scte/35: add time descriptor - - - - - c8cb5722 by Arnaud de Turckheim at 2025-03-05T11:51:08+01:00 dvb/si/desc_6f: fix typo - - - - - 62415e8f by Arnaud de Turckheim at 2025-03-05T11:51:08+01:00 dvb/si: add AIT - - - - - f2ad50c9 by Arnaud de Turckheim at 2025-03-05T11:51:08+01:00 scte/35: add avail splice descriptor helpers - - - - - fc71ca6d by Christophe Massiot at 2025-03-05T11:51:14+01:00 Merge branch 'quarium-time-desc' - - - - - 1 changed file: - scte/35.h Changes: ===================================== scte/35.h ===================================== @@ -674,6 +674,7 @@ static inline bool scte35_private_validate(const uint8_t *p_scte35) #define SCTE35_SPLICE_DESC_TAG_AVAIL 0x00 #define SCTE35_SPLICE_DESC_TAG_DTMF 0x01 #define SCTE35_SPLICE_DESC_TAG_SEG 0x02 +#define SCTE35_SPLICE_DESC_TAG_TIME 0x03 #define scte35_splice_desc_get_tag desc_get_tag #define scte35_splice_desc_set_tag desc_set_tag @@ -1405,6 +1406,68 @@ static inline void scte35_seg_desc_set_sub_expected(uint8_t *p_desc, p[4] = value; } +/***************************************************************************** + * Splice Information Table - time descriptor + *****************************************************************************/ +#define SCTE35_TIME_DESC_HEADER_SIZE 16 + +static inline uint64_t scte35_time_desc_get_tai_sec(const uint8_t *p_desc) +{ + return ((uint64_t)p_desc[6] << 40) | ((uint64_t)p_desc[7] << 32) | + (p_desc[8] << 24) | (p_desc[9] << 16) | (p_desc[10] << 8) | p_desc[11]; +} + +static inline void scte35_time_desc_set_tai_sec(uint8_t *p_desc, + uint64_t tai_sec) +{ + p_desc[6] = (tai_sec >> 40) & 0xff; + p_desc[7] = (tai_sec >> 32) & 0xff; + p_desc[8] = (tai_sec >> 24) & 0xff; + p_desc[9] = (tai_sec >> 16) & 0xff; + p_desc[10] = (tai_sec >> 8) & 0xff; + p_desc[11] = tai_sec & 0xff; +} + +static inline uint32_t scte35_time_desc_get_tai_ns(const uint8_t *p_desc) +{ + return ((uint32_t)p_desc[12] << 24) | (p_desc[13] << 16) | + (p_desc[14] << 8) | p_desc[15]; +} + +static inline void scte35_time_desc_set_tai_ns(uint8_t *p_desc, + uint32_t tai_ns) +{ + p_desc[12] = (tai_ns >> 24) & 0xff; + p_desc[13] = (tai_ns >> 16) & 0xff; + p_desc[14] = (tai_ns >> 8) & 0xff; + p_desc[15] = tai_ns & 0xff; +} + +static inline uint16_t scte35_time_desc_get_utc_off(const uint8_t *p_desc) +{ + return ((uint16_t)p_desc[16] << 8) | p_desc[17]; +} + +static inline void scte35_time_desc_set_utc_off(uint8_t *p_desc, + uint16_t utc_off) +{ + p_desc[16] = (utc_off >> 8) & 0xff; + p_desc[17] = utc_off & 0xff; +} + +static inline void scte35_time_desc_init(uint8_t *p_desc) +{ + scte35_splice_desc_set_tag(p_desc, SCTE35_SPLICE_DESC_TAG_TIME); + scte35_splice_desc_set_length(p_desc, + SCTE35_SPLICE_DESC_HEADER_SIZE - + DESC_HEADER_SIZE + + SCTE35_TIME_DESC_HEADER_SIZE); + scte35_splice_desc_set_identifier(p_desc, SCTE35_SPLICE_DESC_IDENTIFIER); + scte35_time_desc_set_tai_sec(p_desc, 0); + scte35_time_desc_set_tai_ns(p_desc, 0); + scte35_time_desc_set_utc_off(p_desc, 0); +} + /***************************************************************************** * Splice Information Table validation *****************************************************************************/ View it on GitLab: https://code.videolan.org/videolan/bitstream/-/compare/2944df2f18e761b78af95e7f33adfacf15097ca8...fc71ca6d9da88e82ada96588ebf2e121cd3ad583 -- View it on GitLab: https://code.videolan.org/videolan/bitstream/-/compare/2944df2f18e761b78af95e7f33adfacf15097ca8...fc71ca6d9da88e82ada96588ebf2e121cd3ad583 You're receiving this email because of your account on code.videolan.org. VideoLAN code repository instance