@@ -35,7 +35,7 @@
struct dvb_v5_fe_parms;
-typedef void (*dvb_table_init_func)(struct dvb_v5_fe_parms *parms, const uint8_t *ptr, ssize_t size, uint8_t **buf, ssize_t *buflen);
+typedef void (*dvb_table_init_func)(struct dvb_v5_fe_parms *parms, const uint8_t *buf, ssize_t buflen, uint8_t *table, ssize_t *table_length);
struct dvb_table_init {
dvb_table_init_func init;
@@ -77,18 +77,21 @@ uint32_t bcd(uint32_t bcd);
void hexdump(struct dvb_v5_fe_parms *parms, const char *prefix, const unsigned char *buf, int len);
-ssize_t dvb_parse_descriptors(struct dvb_v5_fe_parms *parms, const uint8_t *buf, uint8_t *dest, uint16_t section_length, struct dvb_desc **head_desc);
+void dvb_parse_descriptors(struct dvb_v5_fe_parms *parms, const uint8_t *buf, uint16_t section_length, struct dvb_desc **head_desc);
+void dvb_free_descriptors(struct dvb_desc **list);
void dvb_print_descriptors(struct dvb_v5_fe_parms *parms, struct dvb_desc *desc);
struct dvb_v5_fe_parms;
typedef ssize_t (*dvb_desc_init_func)(struct dvb_v5_fe_parms *parms, const uint8_t *buf, struct dvb_desc *desc);
typedef void (*dvb_desc_print_func)(struct dvb_v5_fe_parms *parms, const struct dvb_desc *desc);
+typedef void (*dvb_desc_free_func)(struct dvb_desc *desc);
struct dvb_descriptor {
const char *name;
dvb_desc_init_func init;
dvb_desc_print_func print;
+ dvb_desc_free_func free;
ssize_t desc_size;
};
new file mode 100644
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2011-2012 - Mauro Carvalho Chehab <mchehab@redhat.com>
+ * Copyright (c) 2012 - Andre Roth <neolynx@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation version 2
+ * of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ * Or, point your browser to http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ *
+ */
+
+#ifndef _DESC_EVENT_EXTENDED_H
+#define _DESC_EVENT_EXTENDED_H
+
+#include <stdint.h>
+#include <unistd.h> /* ssize_t */
+
+struct dvb_desc_event_extended {
+ uint8_t type;
+ uint8_t length;
+ struct dvb_desc *next;
+
+ union {
+ struct {
+ uint8_t last_id:4;
+ uint8_t id:4;
+ };
+ uint8_t ids;
+ };
+
+ unsigned char language[4];
+ char *text;
+ char *text_emph;
+} __attribute__((packed));
+
+struct dvb_v5_fe_parms;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+ssize_t dvb_desc_event_extended_init(struct dvb_v5_fe_parms *parms, const uint8_t *buf, struct dvb_desc *desc);
+void dvb_desc_event_extended_print (struct dvb_v5_fe_parms *parms, const struct dvb_desc *desc);
+void dvb_desc_event_extended_free (struct dvb_desc *desc);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
@@ -32,7 +32,9 @@ struct dvb_desc_event_short {
unsigned char language[4];
char *name;
+ char *name_emph;
char *text;
+ char *text_emph;
} __attribute__((packed));
struct dvb_v5_fe_parms;
@@ -43,6 +45,7 @@ extern "C" {
ssize_t dvb_desc_event_short_init(struct dvb_v5_fe_parms *parms, const uint8_t *buf, struct dvb_desc *desc);
void dvb_desc_event_short_print (struct dvb_v5_fe_parms *parms, const struct dvb_desc *desc);
+void dvb_desc_event_short_free (struct dvb_desc *desc);
#ifdef __cplusplus
}
@@ -32,7 +32,9 @@ struct dvb_desc_service {
uint8_t service_type;
char *name;
+ char *name_emph;
char *provider;
+ char *provider_emph;
} __attribute__((packed));
struct dvb_v5_fe_parms;
@@ -43,6 +45,7 @@ extern "C" {
ssize_t dvb_desc_service_init(struct dvb_v5_fe_parms *parms, const uint8_t *buf, struct dvb_desc *desc);
void dvb_desc_service_print (struct dvb_v5_fe_parms *parms, const struct dvb_desc *desc);
+void dvb_desc_service_free (struct dvb_desc *desc);
#ifdef __cplusplus
}
@@ -24,6 +24,7 @@
#include <stdint.h>
#include <unistd.h> /* ssize_t */
+#include <time.h>
#include "descriptors/header.h"
#include "descriptors.h"
@@ -38,18 +39,23 @@
struct dvb_table_eit_event {
uint16_t event_id;
- uint8_t start[5];
- uint8_t duration[3];
union {
uint16_t bitfield;
+ uint8_t dvbstart[5];
+ } __attribute__((packed));
+ uint8_t dvbduration[3];
+ union {
+ uint16_t bitfield2;
struct {
uint16_t section_length:12;
uint16_t free_CA_mode:1;
uint16_t running_status:3;
} __attribute__((packed));
- };
+ } __attribute__((packed));
struct dvb_desc *descriptor;
struct dvb_table_eit_event *next;
+ struct tm start;
+ uint32_t duration;
} __attribute__((packed));
struct dvb_table_eit {
@@ -61,17 +67,21 @@ struct dvb_table_eit {
struct dvb_table_eit_event *event;
} __attribute__((packed));
-#define dvb_eit_service_foreach(_event, _eit) \
+#define dvb_eit_event_foreach(_event, _eit) \
for( struct dvb_table_eit_event *_event = _eit->event; _event; _event = _event->next ) \
struct dvb_v5_fe_parms;
+extern const char *dvb_eit_running_status_name[8];
+
#ifdef __cplusplus
extern "C" {
#endif
-void dvb_table_eit_init (struct dvb_v5_fe_parms *parms, const uint8_t *ptr, ssize_t size, uint8_t **buf, ssize_t *buflen);
+void dvb_table_eit_init (struct dvb_v5_fe_parms *parms, const uint8_t *buf, ssize_t buflen, uint8_t *table, ssize_t *table_length);
+void dvb_table_eit_free(struct dvb_table_eit *eit);
void dvb_table_eit_print(struct dvb_v5_fe_parms *parms, struct dvb_table_eit *eit);
+void dvb_time(const uint8_t data[5], struct tm *tm);
#ifdef __cplusplus
}
@@ -76,7 +76,8 @@ struct dvb_v5_fe_parms;
extern "C" {
#endif
-void dvb_table_nit_init (struct dvb_v5_fe_parms *parms, const uint8_t *ptr, ssize_t size, uint8_t **buf, ssize_t *buflen);
+void dvb_table_nit_init (struct dvb_v5_fe_parms *parms, const uint8_t *buf, ssize_t buflen, uint8_t *table, ssize_t *table_length);
+void dvb_table_nit_free(struct dvb_table_nit *nit);
void dvb_table_nit_print(struct dvb_v5_fe_parms *parms, struct dvb_table_nit *nit);
#ifdef __cplusplus
@@ -57,7 +57,8 @@ struct dvb_v5_fe_parms;
extern "C" {
#endif
-void dvb_table_pat_init (struct dvb_v5_fe_parms *parms, const uint8_t *ptr, ssize_t size, uint8_t **buf, ssize_t *buflen);
+void dvb_table_pat_init (struct dvb_v5_fe_parms *parms, const uint8_t *buf, ssize_t buflen, uint8_t *table, ssize_t *table_length);
+void dvb_table_pat_free(struct dvb_table_pat *pat);
void dvb_table_pat_print(struct dvb_v5_fe_parms *parms, struct dvb_table_pat *t);
#ifdef __cplusplus
@@ -80,7 +80,8 @@ struct dvb_v5_fe_parms;
extern "C" {
#endif
-void dvb_table_pmt_init (struct dvb_v5_fe_parms *parms, const uint8_t *ptr, ssize_t size, uint8_t **buf, ssize_t *buflen);
+void dvb_table_pmt_init (struct dvb_v5_fe_parms *parms, const uint8_t *buf, ssize_t buflen, uint8_t *table, ssize_t *table_length);
+void dvb_table_pmt_free(struct dvb_table_pmt *pmt);
void dvb_table_pmt_print(struct dvb_v5_fe_parms *parms, const struct dvb_table_pmt *pmt);
#ifdef __cplusplus
@@ -64,7 +64,8 @@ struct dvb_v5_fe_parms;
extern "C" {
#endif
-void dvb_table_sdt_init (struct dvb_v5_fe_parms *parms, const uint8_t *ptr, ssize_t size, uint8_t **buf, ssize_t *buflen);
+void dvb_table_sdt_init (struct dvb_v5_fe_parms *parms, const uint8_t *buf, ssize_t buflen, uint8_t *table, ssize_t *table_length);
+void dvb_table_sdt_free(struct dvb_table_sdt *sdt);
void dvb_table_sdt_print(struct dvb_v5_fe_parms *parms, struct dvb_table_sdt *sdt);
#ifdef __cplusplus
@@ -26,13 +26,17 @@
/* According with ISO/IEC 13818-1:2007 */
+#define MAX_TABLE_SIZE 1024 * 1024
#ifdef __cplusplus
extern "C" {
#endif
-int dvb_read_section(struct dvb_v5_fe_parms *parms, int dmx_fd, unsigned char table, uint16_t pid, unsigned char **buf,
- unsigned *length, unsigned timeout);
+int dvb_read_section(struct dvb_v5_fe_parms *parms, int dmx_fd, unsigned char tid, uint16_t pid, unsigned char **table,
+ unsigned timeout);
+
+int dvb_read_section_with_id(struct dvb_v5_fe_parms *parms, int dmx_fd, unsigned char tid, uint16_t pid, int id, uint8_t **table,
+ unsigned timeout);
struct dvb_v5_descriptors *dvb_get_ts_tables(struct dvb_v5_fe_parms *parms, int dmx_fd,
uint32_t delivery_system,
@@ -35,6 +35,7 @@ libdvbv5_la_SOURCES = \
descriptors/desc_frequency_list.c ../include/descriptors/desc_frequency_list.h \
descriptors/desc_service_list.c ../include/descriptors/desc_service_list.h \
descriptors/desc_event_short.c ../include/descriptors/desc_event_short.h \
+ descriptors/desc_event_extended.c ../include/descriptors/desc_event_extended.h \
descriptors/nit.c ../include/descriptors/nit.h \
descriptors/sdt.c ../include/descriptors/sdt.h \
descriptors/eit.c ../include/descriptors/eit.h
@@ -44,6 +44,7 @@
#include "descriptors/desc_service_list.h"
#include "descriptors/desc_frequency_list.h"
#include "descriptors/desc_event_short.h"
+#include "descriptors/desc_event_extended.h"
ssize_t dvb_desc_init(const uint8_t *buf, struct dvb_desc *desc)
{
@@ -71,6 +72,7 @@ const struct dvb_table_init dvb_table_initializers[] = {
[DVB_TABLE_NIT] = { dvb_table_nit_init },
[DVB_TABLE_SDT] = { dvb_table_sdt_init },
[DVB_TABLE_EIT] = { dvb_table_eit_init },
+ [DVB_TABLE_EIT_SCHEDULE] = { dvb_table_eit_init },
};
char *default_charset = "iso-8859-1";
@@ -83,29 +85,26 @@ static char *table[] = {
[SDT] = "SDT",
};
-ssize_t dvb_parse_descriptors(struct dvb_v5_fe_parms *parms, const uint8_t *buf, uint8_t *dest, uint16_t section_length, struct dvb_desc **head_desc)
+void dvb_parse_descriptors(struct dvb_v5_fe_parms *parms, const uint8_t *buf, uint16_t section_length, struct dvb_desc **head_desc)
{
const uint8_t *ptr = buf;
- ssize_t length = 0;
struct dvb_desc *current = NULL;
struct dvb_desc *last = NULL;
while (ptr < buf + section_length) {
- current = (struct dvb_desc *) dest;
+ current = (struct dvb_desc *) malloc(section_length << 2);
ptr += dvb_desc_init(ptr, current); /* the standard header was read */
dvb_desc_init_func init = dvb_descriptors[current->type].init;
if (!init)
init = dvb_desc_default_init;
ssize_t len = init(parms, ptr, current);
+ current = (struct dvb_desc *) realloc(current, len);
if(!*head_desc)
*head_desc = current;
if (last)
last->next = current;
last = current;
- dest += len;
- length += len;
ptr += current->length; /* standard descriptor header plus descriptor length */
}
- return length;
}
void dvb_print_descriptors(struct dvb_v5_fe_parms *parms, struct dvb_desc *desc)
@@ -119,156 +118,170 @@ void dvb_print_descriptors(struct dvb_v5_fe_parms *parms, struct dvb_desc *desc)
}
}
+void dvb_free_descriptors(struct dvb_desc **list)
+{
+ struct dvb_desc *desc = *list;
+ while (desc) {
+ struct dvb_desc *tmp = desc;
+ desc = desc->next;
+ if (dvb_descriptors[tmp->type].free)
+ dvb_descriptors[tmp->type].free(tmp);
+ else
+ free(tmp);
+ }
+ *list = NULL;
+}
+
const struct dvb_descriptor dvb_descriptors[] = {
- [0 ...255 ] = { "Unknown descriptor", NULL, NULL },
- [video_stream_descriptor] = { "video_stream_descriptor", NULL, NULL },
- [audio_stream_descriptor] = { "audio_stream_descriptor", NULL, NULL },
- [hierarchy_descriptor] = { "hierarchy_descriptor", NULL, NULL },
- [dvbpsi_registration_descriptor] = { "dvbpsi_registration_descriptor", NULL, NULL },
- [ds_alignment_descriptor] = { "ds_alignment_descriptor", NULL, NULL },
- [target_background_grid_descriptor] = { "target_background_grid_descriptor", NULL, NULL },
- [video_window_descriptor] = { "video_window_descriptor", NULL, NULL },
- [conditional_access_descriptor] = { "conditional_access_descriptor", NULL, NULL },
- [iso639_language_descriptor] = { "iso639_language_descriptor", dvb_desc_language_init, dvb_desc_language_print },
- [system_clock_descriptor] = { "system_clock_descriptor", NULL, NULL },
- [multiplex_buffer_utilization_descriptor] = { "multiplex_buffer_utilization_descriptor", NULL, NULL },
- [copyright_descriptor] = { "copyright_descriptor", NULL, NULL },
- [maximum_bitrate_descriptor] = { "maximum_bitrate_descriptor", NULL, NULL },
- [private_data_indicator_descriptor] = { "private_data_indicator_descriptor", NULL, NULL },
- [smoothing_buffer_descriptor] = { "smoothing_buffer_descriptor", NULL, NULL },
- [std_descriptor] = { "std_descriptor", NULL, NULL },
- [ibp_descriptor] = { "ibp_descriptor", NULL, NULL },
- [mpeg4_video_descriptor] = { "mpeg4_video_descriptor", NULL, NULL },
- [mpeg4_audio_descriptor] = { "mpeg4_audio_descriptor", NULL, NULL },
- [iod_descriptor] = { "iod_descriptor", NULL, NULL },
- [sl_descriptor] = { "sl_descriptor", NULL, NULL },
- [fmc_descriptor] = { "fmc_descriptor", NULL, NULL },
- [external_es_id_descriptor] = { "external_es_id_descriptor", NULL, NULL },
- [muxcode_descriptor] = { "muxcode_descriptor", NULL, NULL },
- [fmxbuffersize_descriptor] = { "fmxbuffersize_descriptor", NULL, NULL },
- [multiplexbuffer_descriptor] = { "multiplexbuffer_descriptor", NULL, NULL },
- [content_labeling_descriptor] = { "content_labeling_descriptor", NULL, NULL },
- [metadata_pointer_descriptor] = { "metadata_pointer_descriptor", NULL, NULL },
- [metadata_descriptor] = { "metadata_descriptor", NULL, NULL },
- [metadata_std_descriptor] = { "metadata_std_descriptor", NULL, NULL },
- [AVC_video_descriptor] = { "AVC_video_descriptor", NULL, NULL },
- [ipmp_descriptor] = { "ipmp_descriptor", NULL, NULL },
- [AVC_timing_and_HRD_descriptor] = { "AVC_timing_and_HRD_descriptor", NULL, NULL },
- [mpeg2_aac_audio_descriptor] = { "mpeg2_aac_audio_descriptor", NULL, NULL },
- [flexmux_timing_descriptor] = { "flexmux_timing_descriptor", NULL, NULL },
- [network_name_descriptor] = { "network_name_descriptor", dvb_desc_network_name_init, dvb_desc_network_name_print },
- [service_list_descriptor] = { "service_list_descriptor", dvb_desc_service_list_init, dvb_desc_service_list_print },
- [stuffing_descriptor] = { "stuffing_descriptor", NULL, NULL },
- [satellite_delivery_system_descriptor] = { "satellite_delivery_system_descriptor", dvb_desc_sat_init, dvb_desc_sat_print },
- [cable_delivery_system_descriptor] = { "cable_delivery_system_descriptor", dvb_desc_cable_delivery_init, dvb_desc_cable_delivery_print },
- [VBI_data_descriptor] = { "VBI_data_descriptor", NULL, NULL },
- [VBI_teletext_descriptor] = { "VBI_teletext_descriptor", NULL, NULL },
- [bouquet_name_descriptor] = { "bouquet_name_descriptor", NULL, NULL },
- [service_descriptor] = { "service_descriptor", dvb_desc_service_init, dvb_desc_service_print },
- [country_availability_descriptor] = { "country_availability_descriptor", NULL, NULL },
- [linkage_descriptor] = { "linkage_descriptor", NULL, NULL },
- [NVOD_reference_descriptor] = { "NVOD_reference_descriptor", NULL, NULL },
- [time_shifted_service_descriptor] = { "time_shifted_service_descriptor", NULL, NULL },
- [short_event_descriptor] = { "short_event_descriptor", dvb_desc_event_short_init, dvb_desc_event_short_print },
- [extended_event_descriptor] = { "extended_event_descriptor", NULL, NULL },
- [time_shifted_event_descriptor] = { "time_shifted_event_descriptor", NULL, NULL },
- [component_descriptor] = { "component_descriptor", NULL, NULL },
- [mosaic_descriptor] = { "mosaic_descriptor", NULL, NULL },
- [stream_identifier_descriptor] = { "stream_identifier_descriptor", NULL, NULL },
- [CA_identifier_descriptor] = { "CA_identifier_descriptor", NULL, NULL },
- [content_descriptor] = { "content_descriptor", NULL, NULL },
- [parental_rating_descriptor] = { "parental_rating_descriptor", NULL, NULL },
- [teletext_descriptor] = { "teletext_descriptor", NULL, NULL },
- [telephone_descriptor] = { "telephone_descriptor", NULL, NULL },
- [local_time_offset_descriptor] = { "local_time_offset_descriptor", NULL, NULL },
- [subtitling_descriptor] = { "subtitling_descriptor", NULL, NULL },
- [terrestrial_delivery_system_descriptor] = { "terrestrial_delivery_system_descriptor", dvb_desc_terrestrial_delivery_init, dvb_desc_terrestrial_delivery_print },
- [multilingual_network_name_descriptor] = { "multilingual_network_name_descriptor", NULL, NULL },
- [multilingual_bouquet_name_descriptor] = { "multilingual_bouquet_name_descriptor", NULL, NULL },
- [multilingual_service_name_descriptor] = { "multilingual_service_name_descriptor", NULL, NULL },
- [multilingual_component_descriptor] = { "multilingual_component_descriptor", NULL, NULL },
- [private_data_specifier_descriptor] = { "private_data_specifier_descriptor", NULL, NULL },
- [service_move_descriptor] = { "service_move_descriptor", NULL, NULL },
- [short_smoothing_buffer_descriptor] = { "short_smoothing_buffer_descriptor", NULL, NULL },
- [frequency_list_descriptor] = { "frequency_list_descriptor", dvb_desc_frequency_list_init, dvb_desc_frequency_list_print },
- [partial_transport_stream_descriptor] = { "partial_transport_stream_descriptor", NULL, NULL },
- [data_broadcast_descriptor] = { "data_broadcast_descriptor", NULL, NULL },
- [scrambling_descriptor] = { "scrambling_descriptor", NULL, NULL },
- [data_broadcast_id_descriptor] = { "data_broadcast_id_descriptor", NULL, NULL },
- [transport_stream_descriptor] = { "transport_stream_descriptor", NULL, NULL },
- [DSNG_descriptor] = { "DSNG_descriptor", NULL, NULL },
- [PDC_descriptor] = { "PDC_descriptor", NULL, NULL },
- [AC_3_descriptor] = { "AC_3_descriptor", NULL, NULL },
- [ancillary_data_descriptor] = { "ancillary_data_descriptor", NULL, NULL },
- [cell_list_descriptor] = { "cell_list_descriptor", NULL, NULL },
- [cell_frequency_link_descriptor] = { "cell_frequency_link_descriptor", NULL, NULL },
- [announcement_support_descriptor] = { "announcement_support_descriptor", NULL, NULL },
- [application_signalling_descriptor] = { "application_signalling_descriptor", NULL, NULL },
- [adaptation_field_data_descriptor] = { "adaptation_field_data_descriptor", NULL, NULL },
- [service_identifier_descriptor] = { "service_identifier_descriptor", NULL, NULL },
- [service_availability_descriptor] = { "service_availability_descriptor", NULL, NULL },
- [default_authority_descriptor] = { "default_authority_descriptor", NULL, NULL },
- [related_content_descriptor] = { "related_content_descriptor", NULL, NULL },
- [TVA_id_descriptor] = { "TVA_id_descriptor", NULL, NULL },
- [content_identifier_descriptor] = { "content_identifier_descriptor", NULL, NULL },
- [time_slice_fec_identifier_descriptor] = { "time_slice_fec_identifier_descriptor", NULL, NULL },
- [ECM_repetition_rate_descriptor] = { "ECM_repetition_rate_descriptor", NULL, NULL },
- [S2_satellite_delivery_system_descriptor] = { "S2_satellite_delivery_system_descriptor", NULL, NULL },
- [enhanced_AC_3_descriptor] = { "enhanced_AC_3_descriptor", NULL, NULL },
- [DTS_descriptor] = { "DTS_descriptor", NULL, NULL },
- [AAC_descriptor] = { "AAC_descriptor", NULL, NULL },
- [XAIT_location_descriptor] = { "XAIT_location_descriptor", NULL, NULL },
- [FTA_content_management_descriptor] = { "FTA_content_management_descriptor", NULL, NULL },
- [extension_descriptor] = { "extension_descriptor", NULL, NULL },
-
- [CUE_identifier_descriptor] = { "CUE_identifier_descriptor", NULL, NULL },
-
- [component_name_descriptor] = { "component_name_descriptor", NULL, NULL },
- [logical_channel_number_descriptor] = { "logical_channel_number_descriptor", NULL, NULL },
-
- [carousel_id_descriptor] = { "carousel_id_descriptor", NULL, NULL },
- [association_tag_descriptor] = { "association_tag_descriptor", NULL, NULL },
- [deferred_association_tags_descriptor] = { "deferred_association_tags_descriptor", NULL, NULL },
-
- [hierarchical_transmission_descriptor] = { "hierarchical_transmission_descriptor", NULL, NULL },
- [digital_copy_control_descriptor] = { "digital_copy_control_descriptor", NULL, NULL },
- [network_identifier_descriptor] = { "network_identifier_descriptor", NULL, NULL },
- [partial_transport_stream_time_descriptor] = { "partial_transport_stream_time_descriptor", NULL, NULL },
- [audio_component_descriptor] = { "audio_component_descriptor", NULL, NULL },
- [hyperlink_descriptor] = { "hyperlink_descriptor", NULL, NULL },
- [target_area_descriptor] = { "target_area_descriptor", NULL, NULL },
- [data_contents_descriptor] = { "data_contents_descriptor", NULL, NULL },
- [video_decode_control_descriptor] = { "video_decode_control_descriptor", NULL, NULL },
- [download_content_descriptor] = { "download_content_descriptor", NULL, NULL },
- [CA_EMM_TS_descriptor] = { "CA_EMM_TS_descriptor", NULL, NULL },
- [CA_contract_information_descriptor] = { "CA_contract_information_descriptor", NULL, NULL },
- [CA_service_descriptor] = { "CA_service_descriptor", NULL, NULL },
- [TS_Information_descriptior] = { "TS_Information_descriptior", NULL, NULL },
- [extended_broadcaster_descriptor] = { "extended_broadcaster_descriptor", NULL, NULL },
- [logo_transmission_descriptor] = { "logo_transmission_descriptor", NULL, NULL },
- [basic_local_event_descriptor] = { "basic_local_event_descriptor", NULL, NULL },
- [reference_descriptor] = { "reference_descriptor", NULL, NULL },
- [node_relation_descriptor] = { "node_relation_descriptor", NULL, NULL },
- [short_node_information_descriptor] = { "short_node_information_descriptor", NULL, NULL },
- [STC_reference_descriptor] = { "STC_reference_descriptor", NULL, NULL },
- [series_descriptor] = { "series_descriptor", NULL, NULL },
- [event_group_descriptor] = { "event_group_descriptor", NULL, NULL },
- [SI_parameter_descriptor] = { "SI_parameter_descriptor", NULL, NULL },
- [broadcaster_Name_Descriptor] = { "broadcaster_Name_Descriptor", NULL, NULL },
- [component_group_descriptor] = { "component_group_descriptor", NULL, NULL },
- [SI_prime_TS_descriptor] = { "SI_prime_TS_descriptor", NULL, NULL },
- [board_information_descriptor] = { "board_information_descriptor", NULL, NULL },
- [LDT_linkage_descriptor] = { "LDT_linkage_descriptor", NULL, NULL },
- [connected_transmission_descriptor] = { "connected_transmission_descriptor", NULL, NULL },
- [content_availability_descriptor] = { "content_availability_descriptor", NULL, NULL },
- [service_group_descriptor] = { "service_group_descriptor", NULL, NULL },
- [carousel_compatible_composite_Descriptor] = { "carousel_compatible_composite_Descriptor", NULL, NULL },
- [conditional_playback_descriptor] = { "conditional_playback_descriptor", NULL, NULL },
- [ISDBT_delivery_system_descriptor] = { "ISDBT_delivery_system_descriptor", NULL, NULL },
- [partial_reception_descriptor] = { "partial_reception_descriptor", NULL, NULL },
- [emergency_information_descriptor] = { "emergency_information_descriptor", NULL, NULL },
- [data_component_descriptor] = { "data_component_descriptor", NULL, NULL },
- [system_management_descriptor] = { "system_management_descriptor", NULL, NULL },
+ [0 ...255 ] = { "Unknown descriptor", NULL, NULL, NULL },
+ [video_stream_descriptor] = { "video_stream_descriptor", NULL, NULL, NULL },
+ [audio_stream_descriptor] = { "audio_stream_descriptor", NULL, NULL, NULL },
+ [hierarchy_descriptor] = { "hierarchy_descriptor", NULL, NULL, NULL },
+ [dvbpsi_registration_descriptor] = { "dvbpsi_registration_descriptor", NULL, NULL, NULL },
+ [ds_alignment_descriptor] = { "ds_alignment_descriptor", NULL, NULL, NULL },
+ [target_background_grid_descriptor] = { "target_background_grid_descriptor", NULL, NULL, NULL },
+ [video_window_descriptor] = { "video_window_descriptor", NULL, NULL, NULL },
+ [conditional_access_descriptor] = { "conditional_access_descriptor", NULL, NULL, NULL },
+ [iso639_language_descriptor] = { "iso639_language_descriptor", dvb_desc_language_init, dvb_desc_language_print, NULL },
+ [system_clock_descriptor] = { "system_clock_descriptor", NULL, NULL, NULL },
+ [multiplex_buffer_utilization_descriptor] = { "multiplex_buffer_utilization_descriptor", NULL, NULL, NULL },
+ [copyright_descriptor] = { "copyright_descriptor", NULL, NULL, NULL },
+ [maximum_bitrate_descriptor] = { "maximum_bitrate_descriptor", NULL, NULL, NULL },
+ [private_data_indicator_descriptor] = { "private_data_indicator_descriptor", NULL, NULL, NULL },
+ [smoothing_buffer_descriptor] = { "smoothing_buffer_descriptor", NULL, NULL, NULL },
+ [std_descriptor] = { "std_descriptor", NULL, NULL, NULL },
+ [ibp_descriptor] = { "ibp_descriptor", NULL, NULL, NULL },
+ [mpeg4_video_descriptor] = { "mpeg4_video_descriptor", NULL, NULL, NULL },
+ [mpeg4_audio_descriptor] = { "mpeg4_audio_descriptor", NULL, NULL, NULL },
+ [iod_descriptor] = { "iod_descriptor", NULL, NULL, NULL },
+ [sl_descriptor] = { "sl_descriptor", NULL, NULL, NULL },
+ [fmc_descriptor] = { "fmc_descriptor", NULL, NULL, NULL },
+ [external_es_id_descriptor] = { "external_es_id_descriptor", NULL, NULL, NULL },
+ [muxcode_descriptor] = { "muxcode_descriptor", NULL, NULL, NULL },
+ [fmxbuffersize_descriptor] = { "fmxbuffersize_descriptor", NULL, NULL, NULL },
+ [multiplexbuffer_descriptor] = { "multiplexbuffer_descriptor", NULL, NULL, NULL },
+ [content_labeling_descriptor] = { "content_labeling_descriptor", NULL, NULL, NULL },
+ [metadata_pointer_descriptor] = { "metadata_pointer_descriptor", NULL, NULL, NULL },
+ [metadata_descriptor] = { "metadata_descriptor", NULL, NULL, NULL },
+ [metadata_std_descriptor] = { "metadata_std_descriptor", NULL, NULL, NULL },
+ [AVC_video_descriptor] = { "AVC_video_descriptor", NULL, NULL, NULL },
+ [ipmp_descriptor] = { "ipmp_descriptor", NULL, NULL, NULL },
+ [AVC_timing_and_HRD_descriptor] = { "AVC_timing_and_HRD_descriptor", NULL, NULL, NULL },
+ [mpeg2_aac_audio_descriptor] = { "mpeg2_aac_audio_descriptor", NULL, NULL, NULL },
+ [flexmux_timing_descriptor] = { "flexmux_timing_descriptor", NULL, NULL, NULL },
+ [network_name_descriptor] = { "network_name_descriptor", dvb_desc_network_name_init, dvb_desc_network_name_print, NULL },
+ [service_list_descriptor] = { "service_list_descriptor", dvb_desc_service_list_init, dvb_desc_service_list_print, NULL },
+ [stuffing_descriptor] = { "stuffing_descriptor", NULL, NULL, NULL },
+ [satellite_delivery_system_descriptor] = { "satellite_delivery_system_descriptor", dvb_desc_sat_init, dvb_desc_sat_print, NULL },
+ [cable_delivery_system_descriptor] = { "cable_delivery_system_descriptor", dvb_desc_cable_delivery_init, dvb_desc_cable_delivery_print, NULL },
+ [VBI_data_descriptor] = { "VBI_data_descriptor", NULL, NULL, NULL },
+ [VBI_teletext_descriptor] = { "VBI_teletext_descriptor", NULL, NULL, NULL },
+ [bouquet_name_descriptor] = { "bouquet_name_descriptor", NULL, NULL, NULL },
+ [service_descriptor] = { "service_descriptor", dvb_desc_service_init, dvb_desc_service_print, dvb_desc_service_free },
+ [country_availability_descriptor] = { "country_availability_descriptor", NULL, NULL, NULL },
+ [linkage_descriptor] = { "linkage_descriptor", NULL, NULL, NULL },
+ [NVOD_reference_descriptor] = { "NVOD_reference_descriptor", NULL, NULL, NULL },
+ [time_shifted_service_descriptor] = { "time_shifted_service_descriptor", NULL, NULL, NULL },
+ [short_event_descriptor] = { "short_event_descriptor", dvb_desc_event_short_init, dvb_desc_event_short_print, dvb_desc_event_short_free },
+ [extended_event_descriptor] = { "extended_event_descriptor", dvb_desc_event_extended_init, dvb_desc_event_extended_print, dvb_desc_event_extended_free },
+ [time_shifted_event_descriptor] = { "time_shifted_event_descriptor", NULL, NULL, NULL },
+ [component_descriptor] = { "component_descriptor", NULL, NULL, NULL },
+ [mosaic_descriptor] = { "mosaic_descriptor", NULL, NULL, NULL },
+ [stream_identifier_descriptor] = { "stream_identifier_descriptor", NULL, NULL, NULL },
+ [CA_identifier_descriptor] = { "CA_identifier_descriptor", NULL, NULL, NULL },
+ [content_descriptor] = { "content_descriptor", NULL, NULL, NULL },
+ [parental_rating_descriptor] = { "parental_rating_descriptor", NULL, NULL, NULL },
+ [teletext_descriptor] = { "teletext_descriptor", NULL, NULL, NULL },
+ [telephone_descriptor] = { "telephone_descriptor", NULL, NULL, NULL },
+ [local_time_offset_descriptor] = { "local_time_offset_descriptor", NULL, NULL, NULL },
+ [subtitling_descriptor] = { "subtitling_descriptor", NULL, NULL, NULL },
+ [terrestrial_delivery_system_descriptor] = { "terrestrial_delivery_system_descriptor", dvb_desc_terrestrial_delivery_init, dvb_desc_terrestrial_delivery_print, NULL },
+ [multilingual_network_name_descriptor] = { "multilingual_network_name_descriptor", NULL, NULL, NULL },
+ [multilingual_bouquet_name_descriptor] = { "multilingual_bouquet_name_descriptor", NULL, NULL, NULL },
+ [multilingual_service_name_descriptor] = { "multilingual_service_name_descriptor", NULL, NULL, NULL },
+ [multilingual_component_descriptor] = { "multilingual_component_descriptor", NULL, NULL, NULL },
+ [private_data_specifier_descriptor] = { "private_data_specifier_descriptor", NULL, NULL, NULL },
+ [service_move_descriptor] = { "service_move_descriptor", NULL, NULL, NULL },
+ [short_smoothing_buffer_descriptor] = { "short_smoothing_buffer_descriptor", NULL, NULL, NULL },
+ [frequency_list_descriptor] = { "frequency_list_descriptor", dvb_desc_frequency_list_init, dvb_desc_frequency_list_print, NULL },
+ [partial_transport_stream_descriptor] = { "partial_transport_stream_descriptor", NULL, NULL, NULL },
+ [data_broadcast_descriptor] = { "data_broadcast_descriptor", NULL, NULL, NULL },
+ [scrambling_descriptor] = { "scrambling_descriptor", NULL, NULL, NULL },
+ [data_broadcast_id_descriptor] = { "data_broadcast_id_descriptor", NULL, NULL, NULL },
+ [transport_stream_descriptor] = { "transport_stream_descriptor", NULL, NULL, NULL },
+ [DSNG_descriptor] = { "DSNG_descriptor", NULL, NULL, NULL },
+ [PDC_descriptor] = { "PDC_descriptor", NULL, NULL, NULL },
+ [AC_3_descriptor] = { "AC_3_descriptor", NULL, NULL, NULL },
+ [ancillary_data_descriptor] = { "ancillary_data_descriptor", NULL, NULL, NULL },
+ [cell_list_descriptor] = { "cell_list_descriptor", NULL, NULL, NULL },
+ [cell_frequency_link_descriptor] = { "cell_frequency_link_descriptor", NULL, NULL, NULL },
+ [announcement_support_descriptor] = { "announcement_support_descriptor", NULL, NULL, NULL },
+ [application_signalling_descriptor] = { "application_signalling_descriptor", NULL, NULL, NULL },
+ [adaptation_field_data_descriptor] = { "adaptation_field_data_descriptor", NULL, NULL, NULL },
+ [service_identifier_descriptor] = { "service_identifier_descriptor", NULL, NULL, NULL },
+ [service_availability_descriptor] = { "service_availability_descriptor", NULL, NULL, NULL },
+ [default_authority_descriptor] = { "default_authority_descriptor", NULL, NULL, NULL },
+ [related_content_descriptor] = { "related_content_descriptor", NULL, NULL, NULL },
+ [TVA_id_descriptor] = { "TVA_id_descriptor", NULL, NULL, NULL },
+ [content_identifier_descriptor] = { "content_identifier_descriptor", NULL, NULL, NULL },
+ [time_slice_fec_identifier_descriptor] = { "time_slice_fec_identifier_descriptor", NULL, NULL, NULL },
+ [ECM_repetition_rate_descriptor] = { "ECM_repetition_rate_descriptor", NULL, NULL, NULL },
+ [S2_satellite_delivery_system_descriptor] = { "S2_satellite_delivery_system_descriptor", NULL, NULL, NULL },
+ [enhanced_AC_3_descriptor] = { "enhanced_AC_3_descriptor", NULL, NULL, NULL },
+ [DTS_descriptor] = { "DTS_descriptor", NULL, NULL, NULL },
+ [AAC_descriptor] = { "AAC_descriptor", NULL, NULL, NULL },
+ [XAIT_location_descriptor] = { "XAIT_location_descriptor", NULL, NULL, NULL },
+ [FTA_content_management_descriptor] = { "FTA_content_management_descriptor", NULL, NULL, NULL },
+ [extension_descriptor] = { "extension_descriptor", NULL, NULL, NULL },
+
+ [CUE_identifier_descriptor] = { "CUE_identifier_descriptor", NULL, NULL, NULL },
+
+ [component_name_descriptor] = { "component_name_descriptor", NULL, NULL, NULL },
+ [logical_channel_number_descriptor] = { "logical_channel_number_descriptor", NULL, NULL, NULL },
+
+ [carousel_id_descriptor] = { "carousel_id_descriptor", NULL, NULL, NULL },
+ [association_tag_descriptor] = { "association_tag_descriptor", NULL, NULL, NULL },
+ [deferred_association_tags_descriptor] = { "deferred_association_tags_descriptor", NULL, NULL, NULL },
+
+ [hierarchical_transmission_descriptor] = { "hierarchical_transmission_descriptor", NULL, NULL, NULL },
+ [digital_copy_control_descriptor] = { "digital_copy_control_descriptor", NULL, NULL, NULL },
+ [network_identifier_descriptor] = { "network_identifier_descriptor", NULL, NULL, NULL },
+ [partial_transport_stream_time_descriptor] = { "partial_transport_stream_time_descriptor", NULL, NULL, NULL },
+ [audio_component_descriptor] = { "audio_component_descriptor", NULL, NULL, NULL },
+ [hyperlink_descriptor] = { "hyperlink_descriptor", NULL, NULL, NULL },
+ [target_area_descriptor] = { "target_area_descriptor", NULL, NULL, NULL },
+ [data_contents_descriptor] = { "data_contents_descriptor", NULL, NULL, NULL },
+ [video_decode_control_descriptor] = { "video_decode_control_descriptor", NULL, NULL, NULL },
+ [download_content_descriptor] = { "download_content_descriptor", NULL, NULL, NULL },
+ [CA_EMM_TS_descriptor] = { "CA_EMM_TS_descriptor", NULL, NULL, NULL },
+ [CA_contract_information_descriptor] = { "CA_contract_information_descriptor", NULL, NULL, NULL },
+ [CA_service_descriptor] = { "CA_service_descriptor", NULL, NULL, NULL },
+ [TS_Information_descriptior] = { "TS_Information_descriptior", NULL, NULL, NULL },
+ [extended_broadcaster_descriptor] = { "extended_broadcaster_descriptor", NULL, NULL, NULL },
+ [logo_transmission_descriptor] = { "logo_transmission_descriptor", NULL, NULL, NULL },
+ [basic_local_event_descriptor] = { "basic_local_event_descriptor", NULL, NULL, NULL },
+ [reference_descriptor] = { "reference_descriptor", NULL, NULL, NULL },
+ [node_relation_descriptor] = { "node_relation_descriptor", NULL, NULL, NULL },
+ [short_node_information_descriptor] = { "short_node_information_descriptor", NULL, NULL, NULL },
+ [STC_reference_descriptor] = { "STC_reference_descriptor", NULL, NULL, NULL },
+ [series_descriptor] = { "series_descriptor", NULL, NULL, NULL },
+ [event_group_descriptor] = { "event_group_descriptor", NULL, NULL, NULL },
+ [SI_parameter_descriptor] = { "SI_parameter_descriptor", NULL, NULL, NULL },
+ [broadcaster_Name_Descriptor] = { "broadcaster_Name_Descriptor", NULL, NULL, NULL },
+ [component_group_descriptor] = { "component_group_descriptor", NULL, NULL, NULL },
+ [SI_prime_TS_descriptor] = { "SI_prime_TS_descriptor", NULL, NULL, NULL },
+ [board_information_descriptor] = { "board_information_descriptor", NULL, NULL, NULL },
+ [LDT_linkage_descriptor] = { "LDT_linkage_descriptor", NULL, NULL, NULL },
+ [connected_transmission_descriptor] = { "connected_transmission_descriptor", NULL, NULL, NULL },
+ [content_availability_descriptor] = { "content_availability_descriptor", NULL, NULL, NULL },
+ [service_group_descriptor] = { "service_group_descriptor", NULL, NULL, NULL },
+ [carousel_compatible_composite_Descriptor] = { "carousel_compatible_composite_Descriptor", NULL, NULL, NULL },
+ [conditional_playback_descriptor] = { "conditional_playback_descriptor", NULL, NULL, NULL },
+ [ISDBT_delivery_system_descriptor] = { "ISDBT_delivery_system_descriptor", NULL, NULL, NULL },
+ [partial_reception_descriptor] = { "partial_reception_descriptor", NULL, NULL, NULL },
+ [emergency_information_descriptor] = { "emergency_information_descriptor", NULL, NULL, NULL },
+ [data_component_descriptor] = { "data_component_descriptor", NULL, NULL, NULL },
+ [system_management_descriptor] = { "system_management_descriptor", NULL, NULL, NULL },
};
static const char *extension_descriptors[] = {
new file mode 100644
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2011-2012 - Mauro Carvalho Chehab <mchehab@redhat.com>
+ * Copyright (c) 2012 - Andre Roth <neolynx@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation version 2
+ * of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ * Or, point your browser to http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ *
+ */
+
+#include "descriptors/desc_event_extended.h"
+#include "descriptors.h"
+#include "dvb-fe.h"
+#include "parse_string.h"
+
+ssize_t dvb_desc_event_extended_init(struct dvb_v5_fe_parms *parms, const uint8_t *buf, struct dvb_desc *desc)
+{
+ struct dvb_desc_event_extended *event = (struct dvb_desc_event_extended *) desc;
+ uint8_t len; /* the length of the string in the input data */
+ uint8_t len1; /* the lenght of the output strings */
+
+ /*hexdump(parms, "event extended desc: ", buf - 2, desc->length + 2);*/
+
+ event->ids = buf[0];
+ event->language[0] = buf[1];
+ event->language[1] = buf[2];
+ event->language[2] = buf[3];
+ event->language[3] = '\0';
+
+ uint8_t items = buf[4];
+ buf += 5;
+
+ int i;
+ for (i = 0; i < items; i++) {
+ dvb_logwarn("dvb_desc_event_extended: items not implemented");
+ uint8_t desc_len = *buf;
+ buf++;
+
+ buf += desc_len;
+
+ uint8_t item_len = *buf;
+ buf++;
+
+ buf += item_len;
+ }
+
+ event->text = NULL;
+ event->text_emph = NULL;
+ len = *buf;
+ len1 = len;
+ buf++;
+ parse_string(parms, &event->text, &event->text_emph, buf, len1, default_charset, output_charset);
+ buf += len;
+
+ return sizeof(struct dvb_desc_event_extended);
+}
+
+void dvb_desc_event_extended_free(struct dvb_desc *desc)
+{
+ struct dvb_desc_event_extended *event = (struct dvb_desc_event_extended *) desc;
+ free(event->text);
+ free(event->text_emph);
+}
+
+void dvb_desc_event_extended_print(struct dvb_v5_fe_parms *parms, const struct dvb_desc *desc)
+{
+ const struct dvb_desc_event_extended *event = (const struct dvb_desc_event_extended *) desc;
+ dvb_log("| Description '%s'", event->text);
+}
+
@@ -27,7 +27,6 @@
ssize_t dvb_desc_event_short_init(struct dvb_v5_fe_parms *parms, const uint8_t *buf, struct dvb_desc *desc)
{
struct dvb_desc_event_short *event = (struct dvb_desc_event_short *) desc;
- char *string, *emph;
uint8_t len; /* the length of the string in the input data */
uint8_t len1, len2; /* the lenght of the output strings */
@@ -39,51 +38,39 @@ ssize_t dvb_desc_event_short_init(struct dvb_v5_fe_parms *parms, const uint8_t *
event->language[3] = '\0';
buf += 3;
- event->name = ((char *) desc) + sizeof(struct dvb_desc_event_short);
+ event->name = NULL;
+ event->name_emph = NULL;
len = buf[0];
buf++;
len1 = len;
- string = NULL;
- emph = NULL;
- parse_string(parms, &string, &emph, buf, len1, default_charset, output_charset);
+ parse_string(parms, &event->name, &event->name_emph, buf, len1, default_charset, output_charset);
buf += len;
- if (emph)
- free(emph);
- if (string) {
- len1 = strlen(string);
- memcpy(event->name, string, len1);
- free(string);
- } else {
- memcpy(event->name, buf, len1);
- }
- event->name[len1] = '\0';
- event->text = event->name + len1 + 1;
+ event->text = NULL;
+ event->text_emph = NULL;
len = buf[0];
len2 = len;
buf++;
- string = NULL;
- emph = NULL;
- parse_string(parms, &string, &emph, buf, len2, default_charset, output_charset);
+ parse_string(parms, &event->text, &event->text_emph, buf, len2, default_charset, output_charset);
buf += len;
- if (emph)
- free(emph);
- if (string) {
- len2 = strlen(string);
- memcpy(event->text, string, len2);
- free(string);
- } else {
- memcpy(event->text, buf, len2);
- }
- event->text[len2] = '\0';
- return sizeof(struct dvb_desc_event_short) + len1 + 1 + len2 + 1;
+ return sizeof(struct dvb_desc_event_short);
+}
+
+void dvb_desc_event_short_free(struct dvb_desc *desc)
+{
+ struct dvb_desc_event_short *event = (struct dvb_desc_event_short *) desc;
+ free(event->name);
+ free(event->name_emph);
+ free(event->text);
+ free(event->text_emph);
}
void dvb_desc_event_short_print(struct dvb_v5_fe_parms *parms, const struct dvb_desc *desc)
{
const struct dvb_desc_event_short *event = (const struct dvb_desc_event_short *) desc;
- dvb_log("| Event '%s'", event->name);
+ dvb_log("| Name '%s'", event->name);
+ dvb_log("| Language '%s'", event->language);
dvb_log("| Description '%s'", event->text);
}
@@ -27,7 +27,6 @@
ssize_t dvb_desc_service_init(struct dvb_v5_fe_parms *parms, const uint8_t *buf, struct dvb_desc *desc)
{
struct dvb_desc_service *service = (struct dvb_desc_service *) desc;
- char *name, *emph;
uint8_t len; /* the length of the string in the input data */
uint8_t len1, len2; /* the lenght of the output strings */
@@ -35,45 +34,32 @@ ssize_t dvb_desc_service_init(struct dvb_v5_fe_parms *parms, const uint8_t *buf,
service->service_type = buf[0];
buf++;
- service->provider = ((char *) desc) + sizeof(struct dvb_desc_service);
+ service->provider = NULL;
+ service->provider_emph = NULL;
len = buf[0];
buf++;
len1 = len;
- name = NULL;
- emph = NULL;
- parse_string(parms, &name, &emph, buf, len1, default_charset, output_charset);
+ parse_string(parms, &service->provider, &service->provider_emph, buf, len1, default_charset, output_charset);
buf += len;
- if (emph)
- free(emph);
- if (name) {
- len1 = strlen(name);
- memcpy(service->provider, name, len1);
- free(name);
- } else {
- memcpy(service->provider, buf, len1);
- }
- service->provider[len1] = '\0';
- service->name = service->provider + len1 + 1;
+ service->name = NULL;
+ service->name_emph = NULL;
len = buf[0];
len2 = len;
buf++;
- name = NULL;
- emph = NULL;
- parse_string(parms, &name, &emph, buf, len2, default_charset, output_charset);
+ parse_string(parms, &service->name, &service->name_emph, buf, len2, default_charset, output_charset);
buf += len;
- if (emph)
- free(emph);
- if (name) {
- len2 = strlen(name);
- memcpy(service->name, name, len2);
- free(name);
- } else {
- memcpy(service->name, buf, len2);
- }
- service->name[len2] = '\0';
- return sizeof(struct dvb_desc_service) + len1 + 1 + len2 + 1;
+ return sizeof(struct dvb_desc_service);
+}
+
+void dvb_desc_service_free(struct dvb_desc *desc)
+{
+ struct dvb_desc_service *service = (struct dvb_desc_service *) desc;
+ free(service->provider);
+ free(service->provider_emph);
+ free(service->name);
+ free(service->name_emph);
}
void dvb_desc_service_print(struct dvb_v5_fe_parms *parms, const struct dvb_desc *desc)
@@ -22,52 +22,44 @@
#include "descriptors/eit.h"
#include "dvb-fe.h"
-void dvb_table_eit_init(struct dvb_v5_fe_parms *parms, const uint8_t *ptr, ssize_t size, uint8_t **buf, ssize_t *buflen)
+void dvb_table_eit_init(struct dvb_v5_fe_parms *parms, const uint8_t *buf, ssize_t buflen, uint8_t *table, ssize_t *table_length)
{
- uint8_t *d;
- const uint8_t *p = ptr;
- struct dvb_table_eit *eit = (struct dvb_table_eit *) ptr;
+ const uint8_t *p = buf;
+ struct dvb_table_eit *eit = (struct dvb_table_eit *) table;
struct dvb_table_eit_event **head;
- bswap16(eit->transport_id);
- bswap16(eit->network_id);
-
- if (!*buf) {
- d = malloc(DVB_MAX_PAYLOAD_PACKET_SIZE * 2);
- *buf = d;
- *buflen = 0;
- eit = (struct dvb_table_eit *) d;
- memcpy(eit, p, sizeof(struct dvb_table_eit) - sizeof(eit->event));
- *buflen += sizeof(struct dvb_table_eit);
-
- eit->event = NULL;
- head = &eit->event;
- } else {
- // should realloc d
- d = *buf;
-
+ if (*table_length > 0) {
/* find end of curent list */
- eit = (struct dvb_table_eit *) d;
head = &eit->event;
while (*head != NULL)
head = &(*head)->next;
+ } else {
+ memcpy(eit, p, sizeof(struct dvb_table_eit) - sizeof(eit->event));
+ *table_length = sizeof(struct dvb_table_eit);
- /* read new table */
- eit = (struct dvb_table_eit *) p;
+ bswap16(eit->transport_id);
+ bswap16(eit->network_id);
+
+ eit->event = NULL;
+ head = &eit->event;
}
p += sizeof(struct dvb_table_eit) - sizeof(eit->event);
struct dvb_table_eit_event *last = NULL;
- while ((uint8_t *) p < ptr + size - 4) {
- struct dvb_table_eit_event *event = (struct dvb_table_eit_event *) (d + *buflen);
- memcpy(d + *buflen, p, sizeof(struct dvb_table_eit_event) - sizeof(event->descriptor) - sizeof(event->next));
- p += sizeof(struct dvb_table_eit_event) - sizeof(event->descriptor) - sizeof(event->next);
- *buflen += sizeof(struct dvb_table_eit_event);
+ while ((uint8_t *) p < buf + buflen - 4) {
+ struct dvb_table_eit_event *event = (struct dvb_table_eit_event *) malloc(sizeof(struct dvb_table_eit_event));
+ memcpy(event, p, sizeof(struct dvb_table_eit_event) - sizeof(event->descriptor) - sizeof(event->next) - sizeof(event->start) - sizeof(event->duration));
+ p += sizeof(struct dvb_table_eit_event) - sizeof(event->descriptor) - sizeof(event->next) - sizeof(event->start) - sizeof(event->duration);
bswap16(event->event_id);
bswap16(event->bitfield);
+ bswap16(event->bitfield2);
event->descriptor = NULL;
event->next = NULL;
+ dvb_time(event->dvbstart, &event->start);
+ event->duration = bcd(event->dvbduration[0]) * 3600 +
+ bcd(event->dvbduration[1]) * 60 +
+ bcd(event->dvbduration[2]);
if(!*head)
*head = event;
@@ -76,13 +68,25 @@ void dvb_table_eit_init(struct dvb_v5_fe_parms *parms, const uint8_t *ptr, ssize
/* get the descriptors for each program */
struct dvb_desc **head_desc = &event->descriptor;
- *buflen += dvb_parse_descriptors(parms, p, d + *buflen, event->section_length, head_desc);
+ dvb_parse_descriptors(parms, p, event->section_length, head_desc);
p += event->section_length;
last = event;
}
}
+void dvb_table_eit_free(struct dvb_table_eit *eit)
+{
+ struct dvb_table_eit_event *event = eit->event;
+ while (event) {
+ dvb_free_descriptors((struct dvb_desc **) &event->descriptor);
+ struct dvb_table_eit_event *tmp = event;
+ event = event->next;
+ free(tmp);
+ }
+ free(eit);
+}
+
void dvb_table_eit_print(struct dvb_v5_fe_parms *parms, struct dvb_table_eit *eit)
{
dvb_log("EIT");
@@ -94,10 +98,14 @@ void dvb_table_eit_print(struct dvb_v5_fe_parms *parms, struct dvb_table_eit *ei
dvb_log("|\\ event_id");
const struct dvb_table_eit_event *event = eit->event;
uint16_t events = 0;
- while(event) {
+ while (event) {
+ char start[255];
+ strftime(start, sizeof(start), "%F %T", &event->start);
dvb_log("|- %7d", event->event_id);
+ dvb_log("| Start %s UTC", start);
+ dvb_log("| Duration %dh %dm %ds", event->duration / 3600, (event->duration % 3600) / 60, event->duration % 60);
dvb_log("| free CA mode %d", event->free_CA_mode);
- dvb_log("| running status %d", event->running_status);
+ dvb_log("| running status %d: %s", event->running_status, dvb_eit_running_status_name[event->running_status] );
dvb_print_descriptors(parms, event->descriptor);
event = event->next;
events++;
@@ -105,3 +113,41 @@ void dvb_table_eit_print(struct dvb_v5_fe_parms *parms, struct dvb_table_eit *ei
dvb_log("|_ %d events", events);
}
+void dvb_time(const uint8_t data[5], struct tm *tm)
+{
+ /* ETSI EN 300 468 V1.4.1 */
+ int year, month, day, hour, min, sec;
+ int k = 0;
+ uint16_t mjd;
+
+ mjd = *(uint16_t *) data;
+ hour = bcd(data[2]);
+ min = bcd(data[3]);
+ sec = bcd(data[4]);
+ year = ((mjd - 15078.2) / 365.25);
+ month = ((mjd - 14956.1 - (int) (year * 365.25)) / 30.6001);
+ day = mjd - 14956 - (int) (year * 365.25) - (int) (month * 30.6001);
+ if (month == 14 || month == 15) k = 1;
+ year += k;
+ month = month - 1 - k * 12;
+
+ tm->tm_sec = sec;
+ tm->tm_min = min;
+ tm->tm_hour = hour;
+ tm->tm_mday = day;
+ tm->tm_mon = month - 1;
+ tm->tm_year = year;
+ tm->tm_isdst = -1;
+ tm->tm_wday = 0;
+ tm->tm_yday = 0;
+}
+
+
+const char *dvb_eit_running_status_name[8] = {
+ [0] = "Undefined",
+ [1] = "Not running",
+ [2] = "Starts in a few seconds",
+ [3] = "Pausing",
+ [4] = "Running",
+ [5 ... 7] = "Reserved"
+};
@@ -22,57 +22,50 @@
#include "descriptors/nit.h"
#include "dvb-fe.h"
-void dvb_table_nit_init(struct dvb_v5_fe_parms *parms, const uint8_t *ptr, ssize_t size, uint8_t **buf, ssize_t *buflen)
+void dvb_table_nit_init(struct dvb_v5_fe_parms *parms, const uint8_t *buf, ssize_t buflen, uint8_t *table, ssize_t *table_length)
{
- uint8_t *d;
- const uint8_t *p = ptr;
- struct dvb_table_nit *nit = (struct dvb_table_nit *) ptr;
+ const uint8_t *p = buf;
+ struct dvb_table_nit *nit = (struct dvb_table_nit *) table;
struct dvb_desc **head_desc;
struct dvb_table_nit_transport **head;
+ int desc_length;
- bswap16(nit->bitfield);
+ if (*table_length > 0) {
+ /* find end of curent lists */
+ head_desc = &nit->descriptor;
+ while (*head_desc != NULL)
+ head_desc = &(*head_desc)->next;
+ head = &nit->transport;
+ while (*head != NULL)
+ head = &(*head)->next;
- if (!*buf) {
- d = malloc(DVB_MAX_PAYLOAD_PACKET_SIZE * 4);
- *buf = d;
- *buflen = 0;
- nit = (struct dvb_table_nit *) d;
+ struct dvb_table_nit *t = (struct dvb_table_nit *) buf;
+ bswap16(t->bitfield);
+ desc_length = t->desc_length;
- memcpy(d + *buflen, p, sizeof(struct dvb_table_nit) - sizeof(nit->descriptor) - sizeof(nit->transport));
- *buflen += sizeof(struct dvb_table_nit);
+ } else {
+ memcpy(table, p, sizeof(struct dvb_table_nit) - sizeof(nit->descriptor) - sizeof(nit->transport));
+ *table_length = sizeof(struct dvb_table_nit);
+ bswap16(nit->bitfield);
nit->descriptor = NULL;
nit->transport = NULL;
head_desc = &nit->descriptor;
head = &nit->transport;
- } else {
- // should realloc d
- d = *buf;
-
- // find end of curent list
- nit = (struct dvb_table_nit *) d;
- head_desc = &nit->descriptor;
- while (*head_desc != NULL)
- head_desc = &(*head_desc)->next;
- head = &nit->transport;
- while (*head != NULL)
- head = &(*head)->next;
- // read new table
- nit = (struct dvb_table_nit *) p; // FIXME: should be copied to tmp, cause bswap in const
+ desc_length = nit->desc_length;
}
p += sizeof(struct dvb_table_nit) - sizeof(nit->descriptor) - sizeof(nit->transport);
- *buflen += dvb_parse_descriptors(parms, p, d + *buflen, nit->desc_length, head_desc);
- p += nit->desc_length;
+ dvb_parse_descriptors(parms, p, desc_length, head_desc);
+ p += desc_length;
p += sizeof(union dvb_table_nit_transport_header);
struct dvb_table_nit_transport *last = NULL;
- while ((uint8_t *) p < ptr + size - 4) {
- struct dvb_table_nit_transport *transport = (struct dvb_table_nit_transport *) (d + *buflen);
- memcpy(d + *buflen, p, sizeof(struct dvb_table_nit_transport) - sizeof(transport->descriptor) - sizeof(transport->next));
+ while ((uint8_t *) p < buf + buflen - 4) {
+ struct dvb_table_nit_transport *transport = (struct dvb_table_nit_transport *) malloc(sizeof(struct dvb_table_nit_transport));
+ memcpy(transport, p, sizeof(struct dvb_table_nit_transport) - sizeof(transport->descriptor) - sizeof(transport->next));
p += sizeof(struct dvb_table_nit_transport) - sizeof(transport->descriptor) - sizeof(transport->next);
- *buflen += sizeof(struct dvb_table_nit_transport);
bswap16(transport->transport_id);
bswap16(transport->network_id);
@@ -87,24 +80,32 @@ void dvb_table_nit_init(struct dvb_v5_fe_parms *parms, const uint8_t *ptr, ssize
/* get the descriptors for each transport */
struct dvb_desc **head_desc = &transport->descriptor;
- *buflen += dvb_parse_descriptors(parms, p, d + *buflen, transport->section_length, head_desc);
+ dvb_parse_descriptors(parms, p, transport->section_length, head_desc);
p += transport->section_length;
last = transport;
}
}
+void dvb_table_nit_free(struct dvb_table_nit *nit)
+{
+ struct dvb_table_nit_transport *transport = nit->transport;
+ dvb_free_descriptors((struct dvb_desc **) &nit->descriptor);
+ while(transport) {
+ dvb_free_descriptors((struct dvb_desc **) &transport->descriptor);
+ struct dvb_table_nit_transport *tmp = transport;
+ transport = transport->next;
+ free(tmp);
+ }
+ free(nit);
+}
+
void dvb_table_nit_print(struct dvb_v5_fe_parms *parms, struct dvb_table_nit *nit)
{
dvb_log("NIT");
dvb_table_header_print(parms, &nit->header);
dvb_log("| desc_length %d", nit->desc_length);
- struct dvb_desc *desc = nit->descriptor;
- while (desc) {
- if (dvb_descriptors[desc->type].print)
- dvb_descriptors[desc->type].print(parms, desc);
- desc = desc->next;
- }
+ dvb_print_descriptors(parms, nit->descriptor);
const struct dvb_table_nit_transport *transport = nit->transport;
uint16_t transports = 0;
while(transport) {
@@ -23,40 +23,43 @@
#include "descriptors.h"
#include "dvb-fe.h"
-void dvb_table_pat_init(struct dvb_v5_fe_parms *parms, const uint8_t *ptr, ssize_t size, uint8_t **buf, ssize_t *buflen)
+void dvb_table_pat_init(struct dvb_v5_fe_parms *parms, const uint8_t *buf, ssize_t buflen, uint8_t *table, ssize_t *table_length)
{
- uint8_t *d;
- struct dvb_table_pat *pat;
- if (!*buf) {
- d = malloc(size + sizeof(uint16_t));
- *buf = d;
- *buflen = size + sizeof(uint16_t);
- pat = (struct dvb_table_pat *) d;
- memcpy(pat, ptr, sizeof(struct dvb_table_pat) - sizeof(uint16_t));
-
- struct dvb_table_pat_program *p = (struct dvb_table_pat_program *)
- (ptr + sizeof(struct dvb_table_pat) - sizeof(uint16_t));
- pat->programs = 0;
- while ((uint8_t *) p < ptr + size - 4) {
- memcpy(pat->program + pat->programs, p, sizeof(struct dvb_table_pat_program));
- bswap16(pat->program[pat->programs].service_id);
- bswap16(pat->program[pat->programs].bitfield);
- p++;
- pat->programs++;
- }
- } else {
+ if (*table_length > 0) {
dvb_logerr("multisection PAT table not implemented");
+ return;
}
+
+ const uint8_t *p = buf;
+ memcpy(table, buf, sizeof(struct dvb_table_pat) - sizeof(uint16_t));
+ p += sizeof(struct dvb_table_pat) - sizeof(uint16_t);
+ *table_length = buflen + sizeof(uint16_t);
+
+ struct dvb_table_pat *pat = (struct dvb_table_pat *) table;
+ pat->programs = 0;
+
+ while (p < buf + buflen - 4) {
+ memcpy(pat->program + pat->programs, p, sizeof(struct dvb_table_pat_program));
+ bswap16(pat->program[pat->programs].service_id);
+ bswap16(pat->program[pat->programs].bitfield);
+ p += sizeof(struct dvb_table_pat_program);
+ pat->programs++;
+ }
+}
+
+void dvb_table_pat_free(struct dvb_table_pat *pat)
+{
+ free(pat);
}
-void dvb_table_pat_print(struct dvb_v5_fe_parms *parms, struct dvb_table_pat *t)
+void dvb_table_pat_print(struct dvb_v5_fe_parms *parms, struct dvb_table_pat *pat)
{
dvb_log("PAT");
- dvb_table_header_print(parms, &t->header);
- dvb_log("|\\ program service (%d programs)", t->programs);
+ dvb_table_header_print(parms, &pat->header);
+ dvb_log("|\\ program service (%d programs)", pat->programs);
int i;
- for (i = 0; i < t->programs; i++) {
- dvb_log("|- %7d %7d", t->program[i].pid, t->program[i].service_id);
+ for (i = 0; i < pat->programs; i++) {
+ dvb_log("|- %7d %7d", pat->program[i].pid, pat->program[i].service_id);
}
}
@@ -25,60 +25,63 @@
#include <string.h> /* memcpy */
-void dvb_table_pmt_init(struct dvb_v5_fe_parms *parms, const uint8_t *ptr, ssize_t size, uint8_t **buf, ssize_t *buflen)
+void dvb_table_pmt_init(struct dvb_v5_fe_parms *parms, const uint8_t *buf, ssize_t buflen, uint8_t *table, ssize_t *table_length)
{
- uint8_t *d;
- const uint8_t *p = ptr;
- struct dvb_table_pmt *pmt = (struct dvb_table_pmt *) ptr;
+ if (*table_length > 0) {
+ dvb_logerr("multisecttion PMT table not implemented");
+ return;
+ }
+
+ const uint8_t *p = buf;
+ struct dvb_table_pmt *pmt = (struct dvb_table_pmt *) table;
+ memcpy(table, p, sizeof(struct dvb_table_pmt) - sizeof(pmt->stream));
+ p += sizeof(struct dvb_table_pmt) - sizeof(pmt->stream);
+ *table_length = sizeof(struct dvb_table_pmt);
bswap16(pmt->bitfield);
bswap16(pmt->bitfield2);
+ pmt->stream = NULL;
+
+ /* skip prog section */
+ p += pmt->prog_length;
+
+ /* get the stream entries */
+ struct dvb_table_pmt_stream *last = NULL;
+ struct dvb_table_pmt_stream **head = &pmt->stream;
+ while (p < buf + buflen - 4) {
+ struct dvb_table_pmt_stream *stream = (struct dvb_table_pmt_stream *) malloc(sizeof(struct dvb_table_pmt_stream));
+ memcpy(stream, p, sizeof(struct dvb_table_pmt_stream) - sizeof(stream->descriptor) - sizeof(stream->next));
+ p += sizeof(struct dvb_table_pmt_stream) - sizeof(stream->descriptor) - sizeof(stream->next);
+
+ bswap16(stream->bitfield);
+ bswap16(stream->bitfield2);
+ stream->descriptor = NULL;
+ stream->next = NULL;
+
+ if(!*head)
+ *head = stream;
+ if(last)
+ last->next = stream;
+
+ /* get the descriptors for each program */
+ struct dvb_desc **head_desc = &stream->descriptor;
+ dvb_parse_descriptors(parms, p, stream->section_length, head_desc);
+
+ p += stream->section_length;
+ last = stream;
+ }
+}
- if (!*buf) {
- d = malloc(DVB_MAX_PAYLOAD_PACKET_SIZE * 2);
- *buf = d;
- *buflen = 0;
- pmt = (struct dvb_table_pmt *) d;
-
- memcpy(d + *buflen, p, sizeof(struct dvb_table_pmt) - sizeof(pmt->stream));
- p += sizeof(struct dvb_table_pmt) - sizeof(pmt->stream);
- *buflen += sizeof(struct dvb_table_pmt);
-
- pmt->stream = NULL;
-
- /* skip prog section */
- p += pmt->prog_length;
-
- /* get the stream entries */
- struct dvb_table_pmt_stream *last = NULL;
- struct dvb_table_pmt_stream **head = &pmt->stream;
- while (p < ptr + size - 4) {
- struct dvb_table_pmt_stream *stream = (struct dvb_table_pmt_stream *) (d + *buflen);
- memcpy(d + *buflen, p, sizeof(struct dvb_table_pmt_stream) - sizeof(stream->descriptor) - sizeof(stream->next));
- p += sizeof(struct dvb_table_pmt_stream) - sizeof(stream->descriptor) - sizeof(stream->next);
- *buflen += sizeof(struct dvb_table_pmt_stream);
-
- bswap16(stream->bitfield);
- bswap16(stream->bitfield2);
- stream->descriptor = NULL;
- stream->next = NULL;
-
- if(!*head)
- *head = stream;
- if(last)
- last->next = stream;
-
- /* get the descriptors for each program */
- struct dvb_desc **head_desc = &stream->descriptor;
- *buflen += dvb_parse_descriptors(parms, p, d + *buflen, stream->section_length, head_desc);
-
- p += stream->section_length;
- last = stream;
- }
-
- } else {
- dvb_logerr("multisecttion PMT table not implemented");
+void dvb_table_pmt_free(struct dvb_table_pmt *pmt)
+{
+ struct dvb_table_pmt_stream *stream = pmt->stream;
+ while(stream) {
+ dvb_free_descriptors((struct dvb_desc **) &stream->descriptor);
+ struct dvb_table_pmt_stream *tmp = stream;
+ stream = stream->next;
+ free(tmp);
}
+ free(pmt);
}
void dvb_table_pmt_print(struct dvb_v5_fe_parms *parms, const struct dvb_table_pmt *pmt)
@@ -22,46 +22,33 @@
#include "descriptors/sdt.h"
#include "dvb-fe.h"
-void dvb_table_sdt_init(struct dvb_v5_fe_parms *parms, const uint8_t *ptr, ssize_t size, uint8_t **buf, ssize_t *buflen)
+void dvb_table_sdt_init(struct dvb_v5_fe_parms *parms, const uint8_t *buf, ssize_t buflen, uint8_t *table, ssize_t *table_length)
{
- uint8_t *d;
- const uint8_t *p = ptr;
- struct dvb_table_sdt *sdt = (struct dvb_table_sdt *) ptr;
+ const uint8_t *p = buf;
+ struct dvb_table_sdt *sdt = (struct dvb_table_sdt *) table;
struct dvb_table_sdt_service **head;
- bswap16(sdt->network_id);
-
- if (!*buf) {
- d = malloc(DVB_MAX_PAYLOAD_PACKET_SIZE * 2);
- *buf = d;
- *buflen = 0;
- sdt = (struct dvb_table_sdt *) d;
- memcpy(sdt, p, sizeof(struct dvb_table_sdt) - sizeof(sdt->service));
- *buflen += sizeof(struct dvb_table_sdt);
-
- sdt->service = NULL;
- head = &sdt->service;
- } else {
- // should realloc d
- d = *buf;
-
+ if (*table_length > 0) {
/* find end of curent list */
- sdt = (struct dvb_table_sdt *) d;
head = &sdt->service;
while (*head != NULL)
head = &(*head)->next;
+ } else {
+ memcpy(sdt, p, sizeof(struct dvb_table_sdt) - sizeof(sdt->service));
+ *table_length = sizeof(struct dvb_table_sdt);
- /* read new table */
- sdt = (struct dvb_table_sdt *) p;
+ bswap16(sdt->network_id);
+
+ sdt->service = NULL;
+ head = &sdt->service;
}
p += sizeof(struct dvb_table_sdt) - sizeof(sdt->service);
struct dvb_table_sdt_service *last = NULL;
- while ((uint8_t *) p < ptr + size - 4) {
- struct dvb_table_sdt_service *service = (struct dvb_table_sdt_service *) (d + *buflen);
- memcpy(d + *buflen, p, sizeof(struct dvb_table_sdt_service) - sizeof(service->descriptor) - sizeof(service->next));
+ while ((uint8_t *) p < buf + buflen - 4) {
+ struct dvb_table_sdt_service *service = (struct dvb_table_sdt_service *) malloc(sizeof(struct dvb_table_sdt_service));
+ memcpy(service, p, sizeof(struct dvb_table_sdt_service) - sizeof(service->descriptor) - sizeof(service->next));
p += sizeof(struct dvb_table_sdt_service) - sizeof(service->descriptor) - sizeof(service->next);
- *buflen += sizeof(struct dvb_table_sdt_service);
bswap16(service->service_id);
bswap16(service->bitfield);
@@ -75,13 +62,25 @@ void dvb_table_sdt_init(struct dvb_v5_fe_parms *parms, const uint8_t *ptr, ssize
/* get the descriptors for each program */
struct dvb_desc **head_desc = &service->descriptor;
- *buflen += dvb_parse_descriptors(parms, p, d + *buflen, service->section_length, head_desc);
+ dvb_parse_descriptors(parms, p, service->section_length, head_desc);
p += service->section_length;
last = service;
}
}
+void dvb_table_sdt_free(struct dvb_table_sdt *sdt)
+{
+ struct dvb_table_sdt_service *service = sdt->service;
+ while(service) {
+ dvb_free_descriptors((struct dvb_desc **) &service->descriptor);
+ struct dvb_table_sdt_service *tmp = service;
+ service = service->next;
+ free(tmp);
+ }
+ free(sdt);
+}
+
void dvb_table_sdt_print(struct dvb_v5_fe_parms *parms, struct dvb_table_sdt *sdt)
{
dvb_log("SDT");
@@ -32,6 +32,7 @@
#include "crc32.h"
#include "dvb-fe.h"
#include "dvb-log.h"
+#include "dvb-demux.h"
#include "descriptors/header.h"
#include <errno.h>
@@ -277,7 +278,7 @@ static void parse_sdt(struct dvb_v5_fe_parms *parms, struct dvb_v5_descriptors *
sdt_table->service_table_len = n;
}
-static int poll(int filedes, unsigned int seconds)
+static int poll(struct dvb_v5_fe_parms *parms, int fd, unsigned int seconds)
{
fd_set set;
struct timeval timeout;
@@ -285,114 +286,141 @@ static int poll(int filedes, unsigned int seconds)
/* Initialize the file descriptor set. */
FD_ZERO (&set);
- FD_SET (filedes, &set);
+ FD_SET (fd, &set);
/* Initialize the timeout data structure. */
timeout.tv_sec = seconds;
timeout.tv_usec = 0;
- /* `select' returns 0 if timeout, 1 if input available, -1 if error. */
+ /* `select' logfuncreturns 0 if timeout, 1 if input available, -1 if error. */
do ret = select (FD_SETSIZE, &set, NULL, NULL, &timeout);
- while (ret == -1 && errno == EINTR);
+ while (!parms->abort && ret == -1 && errno == EINTR);
return ret;
}
-int dvb_read_section(struct dvb_v5_fe_parms *parms, int dmx_fd, unsigned char table, uint16_t pid, uint8_t **buf,
- unsigned *length, unsigned timeout)
+int dvb_read_section(struct dvb_v5_fe_parms *parms, int dmx_fd, unsigned char tid, uint16_t pid, uint8_t **table,
+ unsigned timeout)
{
- int available;
- ssize_t count;
- struct dmx_sct_filter_params f;
- uint8_t *tmp = NULL;
- uint64_t sections_read = 0;
- uint64_t sections_total = 0;
+ return dvb_read_section_with_id(parms, dmx_fd, tid, pid, -1, table, timeout);
+}
+
+
+int dvb_read_section_with_id(struct dvb_v5_fe_parms *parms, int dmx_fd, unsigned char tid, uint16_t pid, int id, uint8_t **table,
+ unsigned timeout)
+{
+ if (!table)
+ return -4;
+ *table = NULL;
ssize_t table_length = 0;
+
+ int first_section = -1;
+ int last_section = -1;
int table_id = -1;
+ int sections = 0;
// FIXME: verify known table
- *buf = NULL;
+ /* table cannot be reallocated due to linked lists */
+ uint8_t *tbl = NULL;
+
+ struct dmx_sct_filter_params f;
memset(&f, 0, sizeof(f));
f.pid = pid;
- f.filter.filter[0] = table;
+ f.filter.filter[0] = tid;
f.filter.mask[0] = 0xff;
f.timeout = 0;
- f.flags = DMX_IMMEDIATE_START | DMX_CHECK_CRC;
+ f.flags = DMX_IMMEDIATE_START; // | DMX_CHECK_CRC;
if (ioctl(dmx_fd, DMX_SET_FILTER, &f) == -1) {
dvb_perror("dvb_read_section: ioctl DMX_SET_FILTER failed");
return -1;
}
- do {
- count = 0;
+ while (1) {
+ int available;
+
+ uint8_t *buf = NULL;
+ ssize_t buf_length = 0;
+
do {
- available = poll(dmx_fd, timeout);
+ available = poll(parms, dmx_fd, timeout);
} while (available < 0 && errno == EOVERFLOW);
+ if (parms->abort)
+ return 0; // FIXME: free tbl
if (available <= 0) {
dvb_logerr("dvb_read_section: no data read" );
return -1;
}
- tmp = malloc(DVB_MAX_PAYLOAD_PACKET_SIZE);
- count = read(dmx_fd, tmp, DVB_MAX_PAYLOAD_PACKET_SIZE);
- if (!count) {
+ buf = malloc(DVB_MAX_PAYLOAD_PACKET_SIZE);
+ buf_length = read(dmx_fd, buf, DVB_MAX_PAYLOAD_PACKET_SIZE);
+ if (!buf_length) {
dvb_logerr("dvb_read_section: no data read" );
- free(tmp);
+ free(buf);
return -1;
}
- if (count < 0) {
+ if (buf_length < 0) {
dvb_perror("dvb_read_section: read error");
- free(tmp);
+ free(buf);
return -2;
}
- uint32_t crc = crc32(tmp, count, 0xFFFFFFFF);
+ buf = realloc(buf, buf_length);
+
+ uint32_t crc = crc32(buf, buf_length, 0xFFFFFFFF);
if (crc != 0) {
dvb_logerr("dvb_read_section: crc error");
- free(tmp);
+ free(buf);
return -3;
}
- //ARRAY_SIZE(vb_table_initializers) >= table
-
- struct dvb_table_header *h = (struct dvb_table_header *) tmp;
+ struct dvb_table_header *h = (struct dvb_table_header *) buf;
dvb_table_header_init(h);
- if (table_id == -1)
- table_id = h->id;
- else if (h->id != table_id) {
- dvb_logwarn("Table ID mismatch reading multi section table: %d != %d", h->id, table_id);
- free(tmp);
- tmp = NULL;
+ if (id != -1 && h->id != id) { /* search for a specific table id */
+ free(buf);
continue;
- }
- /*dvb_log("dvb_read_section: got section %d/%d", h->section_id + 1, h->last_section + 1);*/
- if (!sections_total) {
- if (h->last_section + 1 > 32) {
- dvb_logerr("dvb_read_section: cannot read more than 32 sections, %d requested", h->last_section);
- h->last_section = 31;
+ } else {
+ if (table_id == -1)
+ table_id = h->id;
+ else if (h->id != table_id) {
+ dvb_logwarn("dvb_read_section: table ID mismatch reading multi section table: %d != %d", h->id, table_id);
+ free(buf);
+ continue;
}
- sections_total = (1 << (h->last_section + 1)) - 1;
}
- if (sections_read & (1 << h->section_id)) {
- dvb_logwarn("dvb_read_section: section %d already read", h->section_id);
+
+ dvb_logwarn("section %d/%d", h->section_id, h->last_section);
+
+ /* handle the sections */
+ if (first_section == -1)
+ first_section = h->section_id;
+ else if (h->section_id == first_section)
+ {
+ free(buf);
+ break;
}
- sections_read |= 1 << h->section_id;
- /*if (sections_read != sections_total)*/
- /*dvb_logwarn("dvb_read_section: sections are missing: %d != %d", sections_read, sections_total);*/
-
- if (dvb_table_initializers[table].init)
- dvb_table_initializers[table].init(parms, tmp, count, buf, &table_length);
- else
- dvb_logerr("no initializer for table %d", table);
-
- free(tmp);
- tmp = NULL;
- } while(sections_read != sections_total);
- // FIXME: log incomplete sections
-
- if (length)
- *length = table_length;
+ if (last_section == -1)
+ last_section = h->last_section;
+
+ //ARRAY_SIZE(vb_table_initializers) >= table
+ if (!tbl)
+ tbl = malloc(MAX_TABLE_SIZE);
+
+ if (dvb_table_initializers[tid].init) {
+ dvb_table_initializers[tid].init(parms, buf, buf_length, tbl, &table_length);
+ tbl = realloc(tbl, table_length);
+ } else
+ dvb_logerr("dvb_read_section: no initializer for table %d", tid);
+
+ free(buf);
+
+ if (++sections == last_section + 1)
+ break;
+ }
+
+ dvb_dmx_stop(dmx_fd);
+
+ *table = tbl;
return 0;
}
@@ -419,7 +447,7 @@ static int read_section(struct dvb_v5_fe_parms *parms, int dmx_fd, struct dvb_v5
do {
do {
- count = poll(dmx_fd, timeout);
+ count = poll(parms, dmx_fd, timeout);
if (count > 0)
count = read(dmx_fd, buf, sizeof(buf));
} while (count < 0 && errno == EOVERFLOW);
Signed-off-by: André Roth <neolynx@gmail.com> --- lib/include/descriptors.h | 7 +- lib/include/descriptors/desc_event_extended.h | 60 +++++ lib/include/descriptors/desc_event_short.h | 3 + lib/include/descriptors/desc_service.h | 3 + lib/include/descriptors/eit.h | 20 ++- lib/include/descriptors/nit.h | 3 +- lib/include/descriptors/pat.h | 3 +- lib/include/descriptors/pmt.h | 3 +- lib/include/descriptors/sdt.h | 3 +- lib/include/dvb-scan.h | 8 +- lib/libdvbv5/Makefile.am | 1 + lib/libdvbv5/descriptors.c | 315 ++++++++++++----------- lib/libdvbv5/descriptors/desc_event_extended.c | 81 ++++++ lib/libdvbv5/descriptors/desc_event_short.c | 49 ++--- lib/libdvbv5/descriptors/desc_service.c | 46 ++--- lib/libdvbv5/descriptors/eit.c | 110 ++++++--- lib/libdvbv5/descriptors/nit.c | 79 +++--- lib/libdvbv5/descriptors/pat.c | 55 +++-- lib/libdvbv5/descriptors/pmt.c | 99 ++++---- lib/libdvbv5/descriptors/sdt.c | 55 ++-- lib/libdvbv5/dvb-scan.c | 150 +++++++----- 21 files changed, 694 insertions(+), 459 deletions(-) create mode 100644 lib/include/descriptors/desc_event_extended.h create mode 100644 lib/libdvbv5/descriptors/desc_event_extended.c