diff options
Diffstat (limited to 'p2pvr/scanner')
-rw-r--r-- | p2pvr/scanner/Jamfile.jam | 17 | ||||
-rw-r--r-- | p2pvr/scanner/dvbSiReaderHelper.cpp | 133 | ||||
-rw-r--r-- | p2pvr/scanner/dvbSiReaderHelper.h | 40 | ||||
-rw-r--r-- | p2pvr/scanner/epgRows.cpp | 528 | ||||
-rw-r--r-- | p2pvr/scanner/epgRows.h | 52 | ||||
-rw-r--r-- | p2pvr/scanner/serviceRows.cpp | 155 | ||||
-rw-r--r-- | p2pvr/scanner/serviceRows.h | 43 | ||||
-rw-r--r-- | p2pvr/scanner/si_tables.h | 1667 |
8 files changed, 0 insertions, 2635 deletions
diff --git a/p2pvr/scanner/Jamfile.jam b/p2pvr/scanner/Jamfile.jam deleted file mode 100644 index 768e86c..0000000 --- a/p2pvr/scanner/Jamfile.jam +++ /dev/null @@ -1,17 +0,0 @@ -alias glibmm : : : : - <cflags>"`pkg-config --cflags glibmm-2.4`" - <linkflags>"`pkg-config --libs glibmm-2.4`" - ; -project - : requirements - <variant>debug:<linkflags>-Wl,-z,defs <cflags>"-W -Wall -Werror -Wwrite-strings" - ; - -# Scanner - t -lib p2pvrscanner : - [ glob *.cpp ] - : - <library>../../project2/common//p2common - <library>glibmm - ; - diff --git a/p2pvr/scanner/dvbSiReaderHelper.cpp b/p2pvr/scanner/dvbSiReaderHelper.cpp deleted file mode 100644 index 88b025d..0000000 --- a/p2pvr/scanner/dvbSiReaderHelper.cpp +++ /dev/null @@ -1,133 +0,0 @@ -#include "dvbSiReaderHelper.h" -#include <errno.h> -#include <fcntl.h> -#include <string.h> -#include <stdio.h> -#include <glibmm.h> -#include <sys/poll.h> -#include "si_tables.h" -#include <boost/crc.hpp> - -SimpleMessageException(ErrorReadingData); -SimpleMessageException(TimeoutReadingData); -SimpleMessageException(DemuxOpenFailure); - -const std::string DvbSiParserHelper::ISO10646("ISO-10646"); -const std::string DvbSiParserHelper::EitEncoding("ISO6937"); -const std::string DvbSiParserHelper::UTF8("UTF8"); - -DvbSiReaderHelper::DvbSiReaderHelper(const ScriptNodePtr p) : - demux(p, "demux", "/dev/dvb/adapter0/demux0"), - timeout(p, "timeout", 10000), - fd_epg(0) -{ -} - -DvbSiReaderHelper::~DvbSiReaderHelper() -{ - closeInput(); -} - -void -DvbSiReaderHelper::openInput(ExecContext * ec) const -{ - if ((fd_epg = open(demux(ec), O_RDWR)) < 0) { - throw DemuxOpenFailure(strerror(errno)); - } - filterInput(fd_epg); -} - -void -DvbSiReaderHelper::closeInput() const -{ - if (fd_epg) { - close(fd_epg); - fd_epg = 0; - } -} - -DvbSiParserHelper::StrPtr -DvbSiParserHelper::convert(const char * txt, size_t len) -{ - if (len == 0) { - return boost::shared_ptr<Glib::ustring>(new Glib::ustring()); - } - char enc[20]; - switch (*txt) { - default: - EitEncoding.copy(enc, EitEncoding.length()); - enc[EitEncoding.length()] = '\0'; - break; - case 0x01 ... 0x05: - snprintf(enc, sizeof(enc), "ISO-8859-%d\n", txt[0] + 4); - txt += 1; - len -= 1; - break; - case 0x10: - snprintf(enc, sizeof(enc), "ISO-8859-%02x%02x\n", txt[1], txt[2]); - txt += 3; - len -= 3; - break; - case 0x11: - ISO10646.copy(enc, ISO10646.length()); - enc[ISO10646.length()] = '\0'; - break; - case 0x1F: - // Values for the first byte of "0x00", "0x06" to "0x0F", and "0x12" to "0x1F" are reserved for future use. - //fprintf(stderr, "Reserved encoding: %02x\n", txt[0]); - //fprintf(stderr, "%d: %.*s\n", txt[1], len - 2, txt + 2); - case 0x06 ... 0x0F: - case 0x12 ... 0x1E: - case 0x00: // empty string - return boost::shared_ptr<Glib::ustring>(new Glib::ustring()); - } - size_t used = 0, newlen = 0; - GError * err = NULL; - boost::shared_ptr<gchar> utf8 = boost::shared_ptr<gchar>(g_convert(txt, len, "utf-8", enc, &used, &newlen, &err), g_free); - if (err) { - throw Glib::ConvertError(err); - } - return boost::shared_ptr<Glib::ustring>(new Glib::ustring(utf8.get())); -} - -bool -_dvb_crc32(void * buf, size_t len) -{ - boost::crc_optimal<32, 0x0, 0xFFFFFFFF, 0x0, true, false> crc; - crc.process_bytes(buf, len); - return crc.checksum() == 0; -} - -void -DvbSiReaderHelper::readTables(const InfoTableParser & parseInfoTable) const -{ - u_char buf[1<<12]; - struct pollfd ufd; - memset(&ufd, 0, sizeof(pollfd)); - ufd.fd = fd_epg; - ufd.events = POLLIN; - size_t n; - int prtn = 0; - time_t lastuseful = time(NULL); - while (((prtn = poll(&ufd, 1, timeout(NULL))) == 1) && (n = read(fd_epg, buf, sizeof(buf)))) { - if (n < sizeof(struct si_tab)) - throw ErrorReadingData("Smaller that si_tab"); - struct si_tab *tab = (struct si_tab *)buf; - size_t l = sizeof(struct si_tab) + GetSectionLength(tab); - if (n < l) - throw ErrorReadingData("Smaller that section length"); - if (_dvb_crc32(buf, l)) { - if (parseInfoTable(buf, l)) { - time(&lastuseful); - } - else { - if (lastuseful < time(NULL) - 15) { - break; - } - } - } - } - if (prtn < 1) { - throw TimeoutReadingData("Tuned to a multiplex?"); - } -} diff --git a/p2pvr/scanner/dvbSiReaderHelper.h b/p2pvr/scanner/dvbSiReaderHelper.h deleted file mode 100644 index d0080f1..0000000 --- a/p2pvr/scanner/dvbSiReaderHelper.h +++ /dev/null @@ -1,40 +0,0 @@ -#ifndef DVBSIREADERHELPER_H -#define DVBSIREADERHELPER_H - -#include "scripts.h" -#include "variables.h" -#include <boost/function.hpp> - -class RowProcessor; - -class DvbSiReaderHelper { - public: - typedef boost::function<bool (const u_char *, size_t)> InfoTableParser; - - DvbSiReaderHelper(const ScriptNodePtr p); - ~DvbSiReaderHelper(); - - const Variable demux; - const Variable timeout; - - protected: - void openInput(ExecContext *) const; - virtual void filterInput(int fd) const = 0; - void readTables(const InfoTableParser &) const; - void closeInput() const; - - private: - mutable int fd_epg; -}; - -class DvbSiParserHelper { - protected: - typedef boost::shared_ptr<Glib::ustring> StrPtr; - static StrPtr convert(const char * txt, size_t len); - static const std::string ISO10646; - static const std::string EitEncoding; - static const std::string UTF8; -}; - -#endif - diff --git a/p2pvr/scanner/epgRows.cpp b/p2pvr/scanner/epgRows.cpp deleted file mode 100644 index e27769d..0000000 --- a/p2pvr/scanner/epgRows.cpp +++ /dev/null @@ -1,528 +0,0 @@ -/* - * tv_grab_dvb - dump dvb epg info in xmltv - * Version 0.2 - 20/04/2004 - First Public Release - * - * Copyright (C) 2004 Mark Bryars <dvb at darkskiez d0t co d0t uk> - * - * DVB code Mercilessly ripped off from dvddate - * dvbdate Copyright (C) Laurence Culhane 2002 <dvbdate@holmes.demon.co.uk> - * - * 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; either version 2 - * of the License, or (at your option) any later version. - * - * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * Or, point your browser to http://www.gnu.org/copyleft/gpl.html - */ - -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <string.h> -#include <sys/ioctl.h> -#include <errno.h> -#include <stdint.h> -#include <time.h> -#include <glibmm/regex.h> -#include <boost/regex.hpp> -#include <boost/bind.hpp> -#include <boost/date_time/gregorian_calendar.hpp> -#include <boost/algorithm/string/predicate.hpp> -#include <boost/algorithm/string/trim.hpp> -#include <boost/foreach.hpp> -#include <boost/lexical_cast.hpp> - -#include <linux/dvb/dmx.h> -#include "si_tables.h" - -#include "rowProcessor.h" -#include "epgRows.h" -#include <boost/tuple/tuple_comparison.hpp> - -struct EpgProgram { - VariableType serviceID; - VariableType eventID; - VariableType title; - VariableType titleLang; - VariableType subtitle; - VariableType descLang; - VariableType desc1; - VariableType desc2; - VariableType desc3; - VariableType videoAspect; - VariableType videoFrameRate; - VariableType videoHD; - VariableType audioChannels; - VariableType language; - VariableType teletextSubtitleLang; - VariableType category; - VariableType dvbRating; - VariableType contentItemID; - VariableType contentSeriesID; - VariableType contentRecommendation; - VariableType startTime; - VariableType stopTime; - VariableType episode; - VariableType episodes; - VariableType year; - VariableType flags; -}; - -static Glib::ustring title("title"); -template <class C, class M> -const M & -getMember(M C::*t, C * p) { - return p->*t; -} -SimpleMessageException(NoSuchAttribute); - -void -EpgRows::loadComplete(const CommonObjects *) -{ -} - -EpgRowState::EpgRowState() : - current(NULL) -{ -} - -const Columns & -EpgRowState::getColumns() const -{ - return columns; -} - -#define returnAttr(name) if (attrName == #name) return boost::bind(getMember<EpgProgram, VariableType>, &EpgProgram::name, boost::ref(current)) -RowState::RowAttribute -EpgRowState::resolveAttr(const Glib::ustring & attrName) const { - returnAttr(serviceID); - returnAttr(eventID); - returnAttr(title); - returnAttr(titleLang); - returnAttr(subtitle); - returnAttr(descLang); - returnAttr(desc1); - returnAttr(desc2); - returnAttr(desc3); - returnAttr(videoAspect); - returnAttr(videoFrameRate); - returnAttr(videoHD); - returnAttr(audioChannels); - returnAttr(language); - returnAttr(teletextSubtitleLang); - returnAttr(category); - returnAttr(dvbRating); - returnAttr(contentItemID); - returnAttr(contentSeriesID); - returnAttr(contentRecommendation); - returnAttr(startTime); - returnAttr(stopTime); - returnAttr(episode); - returnAttr(episodes); - returnAttr(year); - returnAttr(flags); - throw NoSuchAttribute(attrName); -} - -DECLARE_LOADER("epgrows", EpgRows); - -EpgRows::EpgRows(const ScriptNodePtr p) : - RowSet(p), - DvbSiReaderHelper(p) -{ -} - -EpgRows::~EpgRows() -{ -} - -static int time_offset = 0; -static int chan_filter = 0; -static int chan_filter_mask = 0; -static Glib::RefPtr<Glib::Regex> episodeRegex = Glib::Regex::create("[ (]+(?:\\w+ )?([0-9]+)(?: of |/)([0-9]+)[.)]+"); -static Glib::RefPtr<Glib::Regex> yearRegex = Glib::Regex::create("\\(([0-9]{4})[ )]+"); -static Glib::RefPtr<Glib::Regex> flagsRegex = Glib::Regex::create("[ []+([A-Z,]+)\\]"); - -void -EpgRowState::parseEventDescription(const u_char * data, EpgProgram * current) const { - assert(GetDescriptorTag(data) == 0x4D); - const struct descr_short_event *evtdesc = reinterpret_cast<const struct descr_short_event *>(data); - - size_t evtlen = evtdesc->event_name_length; - StrPtr title, subtitle, desc; - if (evtlen) { - current->titleLang = Glib::ustring((const char *)&evtdesc->lang_code1, 3); - title = convert((const char *)evtdesc->data, evtlen); - } - - size_t dsclen = evtdesc->data[evtlen]; - if (dsclen) { - subtitle = convert((const char *)evtdesc->data + evtlen + 1, dsclen); - } - if (subtitle) { - Glib::MatchInfo matches; - if (episodeRegex->match(*subtitle, matches)) { - current->episode = boost::lexical_cast<int>(matches.fetch(1)); - current->episodes = boost::lexical_cast<int>(matches.fetch(2)); - *subtitle = episodeRegex->replace_literal(*subtitle, 0, "", Glib::REGEX_MATCH_NOTEMPTY); - } - if (yearRegex->match(*subtitle, matches)) { - current->year = boost::lexical_cast<int>(matches.fetch(1)); - *subtitle = yearRegex->replace_literal(*subtitle, 0, "", Glib::REGEX_MATCH_NOTEMPTY); - } - if (flagsRegex->match(*subtitle, matches)) { - current->flags = matches.fetch(1); - *subtitle = yearRegex->replace_literal(*subtitle, 0, "", Glib::REGEX_MATCH_NOTEMPTY); - } - } - if (title && subtitle) { - if (boost::algorithm::ends_with(*title, "...") && boost::algorithm::starts_with(*subtitle, "...")) { - title->resize(title->length() - 3); - *title += " "; - size_t dot = subtitle->find('.', 4); - if (dot == Glib::ustring::npos) { - title->append(*subtitle, 3, subtitle->length() - 3); - } - else { - title->append(*subtitle, 3, dot - 3); - subtitle->erase(0, dot + 2); - } - } - size_t colon = subtitle->find(':'); - if (colon != Glib::ustring::npos) { - desc = StrPtr(new Glib::ustring(*subtitle, colon + 1, subtitle->length() - colon)); - subtitle->resize(colon); - } - else { - colon = title->find(':'); - desc = subtitle; - if (colon != Glib::ustring::npos) { - subtitle = StrPtr(new Glib::ustring(*title, colon + 1, title->length() - colon)); - title->resize(colon); - } - else { - subtitle.reset(); - } - } - } - if (title) { - boost::algorithm::trim_if(*title, isspace); - current->title = *title; - } - if (subtitle) { - boost::algorithm::trim_if(*subtitle, isspace); - if (!subtitle->empty()) { - current->subtitle = *subtitle; - } - } - if (desc) { - boost::algorithm::trim_if(*desc, isspace); - if (!desc->empty()) { - current->desc1 = *desc; - } - } -} - -/* Parse 0x4E Extended Event Descriptor. {{{ */ -void -EpgRowState::parseLongEventDescription(const u_char * data, EpgProgram * current) const { - assert(GetDescriptorTag(data) == 0x4E); - const struct descr_extended_event *levt = reinterpret_cast<const struct descr_extended_event *>(data); - bool non_empty = (levt->descriptor_number || levt->last_descriptor_number || levt->length_of_items || levt->data[0]); - - if (non_empty && levt->descriptor_number == 0) { - current->descLang = Glib::ustring((const char *)&levt->lang_code1, 3); - - const u_char *p = reinterpret_cast<const u_char *>(&levt->data); -#ifndef NDEBUG - const void *data_end = data + DESCR_GEN_LEN + GetDescriptorLength(data); -#endif - while (p < levt->data + levt->length_of_items) { - const struct item_extended_event *name = reinterpret_cast<const struct item_extended_event *>(p); - size_t name_len = name->item_description_length; - assert(p + ITEM_EXTENDED_EVENT_LEN + name_len < data_end); - current->desc1 = *convert((const char *)name->data, name_len); - - p += ITEM_EXTENDED_EVENT_LEN + name_len; - - const struct item_extended_event *value = reinterpret_cast<const struct item_extended_event *>(p); - size_t value_len = value->item_description_length; - assert(p + ITEM_EXTENDED_EVENT_LEN + value_len < data_end); - current->desc2 = *convert((const char *)value->data, value_len); - - p += ITEM_EXTENDED_EVENT_LEN + value_len; - } - const struct item_extended_event *text = reinterpret_cast<const struct item_extended_event *>(p); - size_t len = text->item_description_length; - if (non_empty && len) { - current->desc3 = *convert((const char *)text->data, len); - } - - } -} /*}}}*/ - -/* Parse 0x50 Component Descriptor. {{{ - video is a flag, 1=> output the video information, 0=> output the - audio information. seen is a pointer to a counter to ensure we - only output the first one of each (XMLTV can't cope with more than - one) */ -void -EpgRowState::parseComponentDescription(const u_char * data, EpgProgram * current) const { - assert(GetDescriptorTag(data) == 0x50); - const struct descr_component *dc = reinterpret_cast<const struct descr_component *>(data); - - switch (dc->stream_content) { - case 0x01: // Video Info - current->videoHD = ((dc->component_type - 1) & 0x08) ? 1 : 0; - current->videoFrameRate = ((dc->component_type - 1) & 0x04) ? 30 : 25; - current->videoAspect = ((dc->component_type - 1) & 0x03); - break; - case 0x02: // Audio Info - current->audioChannels = dc->component_type; - current->language = Glib::ustring((const char *)&dc->lang_code1, 3); - break; - case 0x03: // Teletext Info - // FIXME: is there a suitable XMLTV output for this? - // if ((dc->component_type)&0x10) //subtitles - // if ((dc->component_type)&0x20) //subtitles for hard of hearing - current->teletextSubtitleLang = Glib::ustring((const char *)&dc->lang_code1, 3); - break; - // case 0x04: // AC3 info - } -} /*}}}*/ - -void -EpgRowState::parseContentDescription(const u_char * data, EpgProgram * current) const { - assert(GetDescriptorTag(data) == 0x54); - const struct descr_content * dc = reinterpret_cast<const struct descr_content *>(data); - for (const u_char * p = reinterpret_cast<const u_char*>(&dc->data); p < data + DESCR_GEN_LEN + dc->descriptor_length; p += NIBBLE_CONTENT_LEN) { - const struct nibble_content *nc = reinterpret_cast<const nibble_content *>(p); - int c1 = (nc->content_nibble_level_1 << 4) + nc->content_nibble_level_2; - // This is weird in the uk, they use user but not content, and almost the same values - current->category = c1 ? c1 : (nc->user_nibble_1 << 4) + nc->user_nibble_2; - } -} - -void -EpgRowState::parseRatingDescription(const u_char * data, EpgProgram * current) const { - assert(GetDescriptorTag(data) == 0x55); - const struct descr_parental_rating * pr = reinterpret_cast<const struct descr_parental_rating *>(data); - for (const u_char * p = reinterpret_cast<const u_char *>(&pr->data); p < data + DESCR_GEN_LEN + pr->descriptor_length; p += PARENTAL_RATING_ITEM_LEN) { - const struct parental_rating_item *pr = reinterpret_cast<const struct parental_rating_item *>(p); - switch (pr->rating) { - case 0x00: /*undefined*/ - break; - case 0x01 ... 0x0F: - current->dvbRating = pr->rating + 3; - break; - case 0x10 ... 0xFF: /*broadcaster defined*/ - break; - } - } -} - -int parsePrivateDataSpecifier(const u_char *data) { - assert(GetDescriptorTag(data) == 0x5F); - return GetPrivateDataSpecifier(data); -} - -/* Parse 0x76 Content Identifier Descriptor. {{{ */ -/* See ETSI TS 102 323, section 12 */ -void -EpgRowState::parseContentIdentifierDescription(const u_char * data, EpgProgram * current) const { - assert(GetDescriptorTag(data) == 0x76); - const struct descr_content_identifier *ci = reinterpret_cast<const struct descr_content_identifier *>(data); - for (const u_char * p = reinterpret_cast<const u_char *>(&ci->data); p < data + DESCR_GEN_LEN + ci->descriptor_length; p += DESCR_GEN_LEN + ci->descriptor_length) { - const struct descr_content_identifier_crid *crid = reinterpret_cast<const struct descr_content_identifier_crid *>(p); - - switch (crid->crid_location) - { - case 0x01: /* Carried in Content Identifier Table (CIT) */ - default: - break; - case 0x00: /* Carried explicitly within descriptor */ - struct descr_content_identifier_crid_local * crid_data = (descr_content_identifier_crid_local_t *)&crid->crid_ref_data; - size_t len = crid_data->crid_length; - switch (crid->crid_type) { - case 0x01: - case 0x31: - current->contentItemID = Glib::ustring((const char *)crid_data->crid_byte, len); - break; - case 0x02: - case 0x32: - current->contentSeriesID = Glib::ustring((const char *)crid_data->crid_byte, len); - break; - case 0x03: - case 0x33: - current->contentRecommendation = Glib::ustring((const char *)crid_data->crid_byte, len); - break; - } - break; - } - } -} /*}}}*/ - -/* Parse Descriptor. {{{ - * Tags should be output in this order: - -'title', 'sub-title', 'desc', 'credits', 'date', 'category', 'language', -'orig-language', 'length', 'icon', 'url', 'country', 'episode-num', -'video', 'audio', 'previously-shown', 'premiere', 'last-chance', -'new', 'subtitles', 'rating', 'star-rating' -*/ -void -EpgRowState::parseDescription(const u_char * data, size_t len, EpgProgram * current) const { - int pds = 0; - for (const u_char * p = data; p < data + len; p += DESCR_GEN_LEN + GetDescriptorLength(p)) { - const struct descr_gen *desc = reinterpret_cast<const struct descr_gen *>(p); - switch (GetDescriptorTag(desc)) { - case 0: - break; - case 0x4D: //short evt desc, [title] [sub-title] - // there can be multiple language versions of these - parseEventDescription(p, current); - break; - case 0x4E: //long evt descriptor [desc] - parseLongEventDescription(p, current); - break; - case 0x50: //component desc [language] [video] [audio] [subtitles] - parseComponentDescription(p, current); - break; - case 0x53: // CA Identifier Descriptor - break; - case 0x54: // content desc [category] - parseContentDescription(p, current); - break; - case 0x55: // Parental Rating Descriptor [rating] - parseRatingDescription(p, current); - break; - case 0x5f: // Private Data Specifier - pds = parsePrivateDataSpecifier(p); - break; - case 0x64: // Data broadcast desc - Text Desc for Data components - break; - case 0x69: // Programm Identification Label - break; - case 0x81: // TODO ??? - if (pds == 5) // ARD_ZDF_ORF - break; - case 0x82: // VPS (ARD, ZDF, ORF) - if (pds == 5) // ARD_ZDF_ORF - // TODO: <programme @vps-start="???"> - break; - case 0x4F: // Time Shifted Event - case 0x52: // Stream Identifier Descriptor - case 0x5E: // Multi Lingual Component Descriptor - case 0x83: // Logical Channel Descriptor (some kind of news-ticker on ARD-MHP-Data?) - case 0x84: // Preferred Name List Descriptor - case 0x85: // Preferred Name Identifier Descriptor - case 0x86: // Eacem Stream Identifier Descriptor - break; - case 0x76: // Content identifier descriptor - parseContentIdentifierDescription(p, current); - break; - default: - break; - } - } -} /*}}}*/ - -/* Check that program has at least a title as is required by xmltv.dtd. {{{ */ -static bool validateDescription(const u_char *data, size_t len) { - for (const u_char * p = data; p < data + len; p += DESCR_GEN_LEN + GetDescriptorLength(p)) { - const struct descr_gen *desc = reinterpret_cast<const struct descr_gen *>(p); - if (GetDescriptorTag(desc) == 0x4D) { - const struct descr_short_event *evtdesc = reinterpret_cast<const struct descr_short_event *>(p); - // make sure that title isn't empty - if (evtdesc->event_name_length) return true; - } - } - return false; -} /*}}}*/ - -bool -EpgRowState::parseInfoTable(const u_char *data, size_t len, const RowProcessorCallback & rp) { - const struct eit *e = reinterpret_cast<const struct eit *>(data); - - len -= 4; //remove CRC - - // For each event listing - bool found = false; - for (const u_char *p = reinterpret_cast<const u_char *>(&e->data); p < data + len; p += EIT_EVENT_LEN + GetEITDescriptorsLoopLength(p)) { - const struct eit_event *evt = reinterpret_cast<const struct eit_event *>(p); - SeenProgram sp(HILO(e->service_id), HILO(evt->event_id)); - if (seenPrograms.find(sp) != seenPrograms.end()) { - continue; - } - seenPrograms.insert(sp); - - // No program info at end! Just skip it - if (GetEITDescriptorsLoopLength(evt) == 0) { - continue; - } - - boost::gregorian::date startDate(boost::gregorian::gregorian_calendar::from_modjulian_day_number(HILO(evt->mjd))); - boost::posix_time::ptime startTime(startDate); - startTime += boost::posix_time::time_duration( - BcdCharToInt(evt->start_time_h) + time_offset, - BcdCharToInt(evt->start_time_m), - BcdCharToInt(evt->start_time_s)); - EpgProgram results; - current = &results; - results.startTime = startTime; - results.stopTime = startTime + boost::posix_time::time_duration( - BcdCharToInt(evt->duration_h), - BcdCharToInt(evt->duration_m), - BcdCharToInt(evt->duration_s)); - - // a program must have a title that isn't empty - if (!validateDescription(reinterpret_cast<const u_char *>(&evt->data), GetEITDescriptorsLoopLength(evt))) { - continue; - } - - - results.serviceID = HILO(e->service_id); - results.eventID = HILO(evt->event_id); - - parseDescription(reinterpret_cast<const u_char *>(&evt->data), GetEITDescriptorsLoopLength(evt), &results); - process(rp); - found = true; - } - return found; -} - -SimpleMessageException(DemuxSetFilterFailure); - -void -EpgRows::filterInput(int fd) const -{ - struct dmx_sct_filter_params sctFilterParams; - memset(&sctFilterParams, 0, sizeof(dmx_sct_filter_params)); - sctFilterParams.pid = 0x12; // EIT data - sctFilterParams.timeout = 0; - sctFilterParams.flags = DMX_IMMEDIATE_START; - sctFilterParams.filter.filter[0] = chan_filter; // 4e is now/next this multiplex, 4f others - sctFilterParams.filter.mask[0] = chan_filter_mask; - - if (ioctl(fd, DMX_SET_FILTER, &sctFilterParams) < 0) { - throw DemuxSetFilterFailure(strerror(errno)); - } -} - -void -EpgRows::execute(const Glib::ustring &, const RowProcessorCallback & rp, ExecContext * ec) const -{ - EpgRowState state; - openInput(ec); - readTables(boost::bind(&EpgRowState::parseInfoTable, &state, _1, _2, rp)); - closeInput(); -} - diff --git a/p2pvr/scanner/epgRows.h b/p2pvr/scanner/epgRows.h deleted file mode 100644 index 61c55ff..0000000 --- a/p2pvr/scanner/epgRows.h +++ /dev/null @@ -1,52 +0,0 @@ -#ifndef EPGROWS_H -#define EPGROWS_H - -#include "scripts.h" -#include "rowSet.h" -#include "variables.h" -#include "dvbSiReaderHelper.h" -#include <boost/tuple/tuple.hpp> - -class EpgProgram; - -class EpgRows : public RowSet, DvbSiReaderHelper { - public: - EpgRows(const ScriptNodePtr p); - ~EpgRows(); - - void execute(const Glib::ustring &, const RowProcessorCallback &, ExecContext *) const; - void loadComplete(const CommonObjects *); - - private: - void filterInput(int fd) const; -}; - -class EpgRowState : public RowState, DvbSiParserHelper { - public: - EpgRowState(); - const Columns & getColumns() const; - RowAttribute resolveAttr(const Glib::ustring & attrName) const; - - bool parseInfoTable(const u_char *data, size_t len, const RowProcessorCallback &); - - private: - void parseEventDescription(const u_char *data, EpgProgram * current) const; - void parseLongEventDescription(const u_char *data, EpgProgram * current) const; - void parseComponentDescription(const u_char *data, EpgProgram * current) const; - void parseContentDescription(const u_char *data, EpgProgram * current) const; - void parseRatingDescription(const u_char *data, EpgProgram * current) const; - void parseContentIdentifierDescription(const u_char *data, EpgProgram * current) const; - void parseDescription(const u_char * data, size_t len, EpgProgram * current) const; - - typedef boost::tuple<int, int> SeenProgram; - typedef std::set<SeenProgram> SeenPrograms; - SeenPrograms seenPrograms; - - Columns columns; - friend class EpgRows; - mutable EpgProgram * current; -}; - - -#endif - diff --git a/p2pvr/scanner/serviceRows.cpp b/p2pvr/scanner/serviceRows.cpp deleted file mode 100644 index e743858..0000000 --- a/p2pvr/scanner/serviceRows.cpp +++ /dev/null @@ -1,155 +0,0 @@ -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <string.h> -#include <sys/ioctl.h> -#include <errno.h> -#include <stdint.h> -#include <time.h> -#include <boost/bind.hpp> -#include <boost/date_time/gregorian_calendar.hpp> - -#include <linux/dvb/dmx.h> -#include "si_tables.h" - -#include "rowProcessor.h" -#include "serviceRows.h" - -class Service { - public: - VariableType serviceID; - VariableType name; - VariableType type; - VariableType providerName; - VariableType defaultAuthority; - VariableType transportID; -}; - -void -ServiceRows::loadComplete(const CommonObjects *) -{ -} - -ServiceRowState::ServiceRowState() : - current(NULL) -{ -} - -const Columns & -ServiceRowState::getColumns() const -{ - return columns; -} - -SimpleMessageException(NoSuchAttribute); -template <class C, class M> -const M & -getMember(M C::*t, C * p) { - return p->*t; -} -#define returnAttr(name) if (attrName == #name) return boost::bind(getMember<Service, VariableType>, &Service::name, boost::ref(current)) -RowState::RowAttribute -ServiceRowState::resolveAttr(const Glib::ustring & attrName) const { - returnAttr(serviceID); - returnAttr(name); - returnAttr(type); - returnAttr(providerName); - returnAttr(defaultAuthority); - returnAttr(transportID); - throw NoSuchAttribute(attrName); -} - -DECLARE_LOADER("servicerows", ServiceRows); - -ServiceRows::ServiceRows(const ScriptNodePtr e) : - RowSet(e), - DvbSiReaderHelper(e) -{ -} - -ServiceRows::~ServiceRows() -{ -} - -SimpleMessageException(DemuxSetFilterFailure); - -void -ServiceRows::filterInput(int fd) const -{ - struct dmx_sct_filter_params sctFilterParams; - memset(&sctFilterParams, 0, sizeof(dmx_sct_filter_params)); - sctFilterParams.pid = 0x11; // Service data - sctFilterParams.timeout = 0; - sctFilterParams.flags = DMX_IMMEDIATE_START; - - if (ioctl(fd, DMX_SET_FILTER, &sctFilterParams) < 0) { - throw DemuxSetFilterFailure(strerror(errno)); - } -} - -void -ServiceRows::execute(const Glib::ustring &, const RowProcessorCallback & rp, ExecContext * ec) const -{ - ServiceRowState state; - openInput(ec); - readTables(boost::bind(&ServiceRowState::parseInfoTable, &state, _1, _2, rp)); - closeInput(); -} - -bool -ServiceRowState::parseInfoTable(const u_char * data, size_t len, const RowProcessorCallback & rp) { - const struct sit *e = reinterpret_cast<const struct sit *>(data); - assert(e->tableid == 0x42 || e->tableid == 0x46); - len -= 4; //remove CRC - - // For each event listing - bool found = false; - for (const u_char * p = e->serviceData; p < data + len; ) { - const struct si * sid = reinterpret_cast<const struct si *>(p); - int sID = be16toh(sid->serviceid); - bool seen = (seenServices.find(sID) != seenServices.end()); - size_t dll = HILO(sid->desc_loop_len); - Service serv; - current = &serv; - for (p = sid->descData; p < sid->descData + dll; p += DESCR_GEN_LEN + GetDescriptorLength(p)) { - if (!seen) { - serv.serviceID = sID; - serv.transportID = be16toh(e->transport_stream_id); - const struct descr_gen *desc = reinterpret_cast<const struct descr_gen *>(p); - switch (GetDescriptorTag(desc)) { - case 0x48: // Service descriptor - parseServiceDescriptor(p, GetDescriptorLength(desc), &serv); - break; - case 0x73: // Service authority descriptor - parseServiceAuthDescriptor(p, GetDescriptorLength(desc), &serv); - break; - default: - break; - } - } - } - if (!seen) { - found = true; - seenServices.insert(sID); - process(rp); - } - } - return found; -} - -void -ServiceRowState::parseServiceDescriptor(const u_char * p, size_t, Service * current) const -{ - current->type = p[2]; - if (p[3]) { - current->providerName = *convert((const char *)(p + 4), p[3]); - } - current->name = *convert((const char *)(p + 5 + p[3]), p[4 + p[3]]); -} - -void -ServiceRowState::parseServiceAuthDescriptor(const u_char * p, size_t len, Service * current) const -{ - current->defaultAuthority = *convert((const char *)(p + 2), len); -} - diff --git a/p2pvr/scanner/serviceRows.h b/p2pvr/scanner/serviceRows.h deleted file mode 100644 index 36cbee7..0000000 --- a/p2pvr/scanner/serviceRows.h +++ /dev/null @@ -1,43 +0,0 @@ -#ifndef SERVICEROWS_H -#define SERVICEROWS_H - -#include "scripts.h" -#include "rowSet.h" -#include "variables.h" -#include "dvbSiReaderHelper.h" - -class Service; - -class ServiceRows : public RowSet, DvbSiReaderHelper { - public: - ServiceRows(const ScriptNodePtr p); - ~ServiceRows(); - - void execute(const Glib::ustring &, const RowProcessorCallback &, ExecContext *) const; - void loadComplete(const CommonObjects *); - - private: - void filterInput(int fd) const; -}; - -class ServiceRowState : public RowState, DvbSiParserHelper { - public: - ServiceRowState(); - const Columns & getColumns() const; - RowAttribute resolveAttr(const Glib::ustring & attrName) const; - bool parseInfoTable(const u_char *data, size_t len, const RowProcessorCallback &); - - private: - void parseServiceDescriptor(const u_char *data, size_t len, Service * current) const; - void parseServiceAuthDescriptor(const u_char *data, size_t len, Service * current) const; - - typedef std::set<int> SeenServices; - SeenServices seenServices; - - Columns columns; - friend class ServiceRows; - mutable Service * current; -}; - -#endif - diff --git a/p2pvr/scanner/si_tables.h b/p2pvr/scanner/si_tables.h deleted file mode 100644 index c48fdae..0000000 --- a/p2pvr/scanner/si_tables.h +++ /dev/null @@ -1,1667 +0,0 @@ -////////////////////////////////////////////////////////////// -/// /// -/// si_tables.h: definitions for data structures of the /// -/// incoming SI data stream /// -/// /// -////////////////////////////////////////////////////////////// - -// $Revision: 84 $ -// $Date: 2010-03-05 17:46:16 +0000 (Fri, 05 Mar 2010) $ -// $Author: cpaton $ -// -// (C) 2001-03 Rolf Hakenes <hakenes@hippomi.de>, under the -// GNU GPL with contribution of Oleg Assovski, -// www.satmania.com -// -// libsi 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; either version 2, or (at your option) -// any later version. -// -// libsi 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 may have received a copy of the GNU General Public License -// along with libsi; see the file COPYING. If not, write to the -// Free Software Foundation, Inc., 59 Temple Place - Suite 330, -// Boston, MA 02111-1307, USA. - -#include <stdint.h> - -#define HILO(x) (x##_hi << 8 | x##_lo) -#define HILO2(x) (x##1 << 8 | x##2) -#define HILO3(x) (x##1 << 16 | x##2 << 8 | x##3) -#define HILO4(x) (x##4 << 24 | x##2 << 16 | x##3 << 8 | x##4) - -#define MjdToEpochTime(x) ((HILO(x)-40587)*86400) -#define BcdTimeToSeconds(x) ((3600 * ((10*((x##_h & 0xF0)>>4)) + (x##_h & 0xF))) + \ - (60 * ((10*((x##_m & 0xF0)>>4)) + (x##_m & 0xF))) + \ - ((10*((x##_s & 0xF0)>>4)) + (x##_s & 0xF))) -#define BcdTimeToMinutes(x) ((60 * ((10*((x##_h & 0xF0)>>4)) + (x##_h & 0xF))) + \ - (((10*((x##_m & 0xF0)>>4)) + (x##_m & 0xF)))) -#define BcdCharToInt(x) (10*((x & 0xF0)>>4) + (x & 0xF)) -#define CheckBcdChar(x) ((((x & 0xF0)>>4) <= 9) && \ - ((x & 0x0F) <= 9)) -#define CheckBcdSignedChar(x) ((((x & 0xF0)>>4) >= 0) && (((x & 0xF0)>>4) <= 9) && \ - ((x & 0x0F) >= 0) && ((x & 0x0F) <= 9)) - -#define GetTableId(x) (((si_tab_t *)(x))->table_id) -#define GetSectionLength(x) HILO(((si_tab_t *)(x))->section_length) -typedef struct si_tab { - u_char table_id /*:8*/; -#if BYTE_ORDER == BIG_ENDIAN - u_char section_syntax_indicator :1; - u_char dummy :1; // has to be 0 - u_char :2; - u_char section_length_hi :4; -#else - u_char section_length_hi :4; - u_char :2; - u_char dummy :1; // has to be 0 - u_char section_syntax_indicator :1; -#endif - u_char section_length_lo /*:8*/; -} si_tab_t; - -/* - * - * ETSI ISO/IEC 13818-1 specifies SI which is referred to as PSI. The PSI - * data provides information to enable automatic configuration of the - * receiver to demultiplex and decode the various streams of programs - * within the multiplex. The PSI data is structured as four types of table. - * The tables are transmitted in sections. - * - * 1) Program Association Table (PAT): - * - * - for each service in the multiplex, the PAT indicates the location - * (the Packet Identifier (PID) values of the Transport Stream (TS) - * packets) of the corresponding Program Map Table (PMT). - * It also gives the location of the Network Information Table (NIT). - * - */ -#define TableHasMoreSections(x) (((pat_t *)(x))->last_section_number > ((pat_t *)(x))->section_number) -#define GetSectionNumber(x) ((pat_t *)(x))->section_number -#define GetLastSectionNumber(x) ((pat_t *)(x))->last_section_number -#define GetServiceId(x) HILO(((eit_t *)(x))->service_id) -#define GetLastTableId(x) ((eit_t *)(x))->segment_last_table_id -#define GetSegmentLastSectionNumber(x) ((eit_t *)(x))->segment_last_section_number -typedef struct pat { - u_char table_id /*:8*/; -#if BYTE_ORDER == BIG_ENDIAN - u_char section_syntax_indicator :1; - u_char dummy :1; // has to be 0 - u_char :2; - u_char section_length_hi :4; -#else - u_char section_length_hi :4; - u_char :2; - u_char dummy :1; // has to be 0 - u_char section_syntax_indicator :1; -#endif - u_char section_length_lo /*:8*/; - u_char transport_stream_id_hi /*:8*/; - u_char transport_stream_id_lo /*:8*/; -#if BYTE_ORDER == BIG_ENDIAN - u_char :2; - u_char version_number :5; - u_char current_next_indicator :1; -#else - u_char current_next_indicator :1; - u_char version_number :5; - u_char :2; -#endif - u_char section_number /*:8*/; - u_char last_section_number /*:8*/; -} pat_t; -#define PAT_LEN sizeof (pat_t) - -typedef struct pat_prog { - u_char program_number_hi /*:8*/; - u_char program_number_lo /*:8*/; -#if BYTE_ORDER == BIG_ENDIAN - u_char :3; - u_char network_pid_hi :5; -#else - u_char network_pid_hi :5; - u_char :3; -#endif - u_char network_pid_lo /*:8*/; - /* or program_map_pid (if prog_num=0)*/ -} pat_prog_t; -#define PAT_PROG_LEN sizeof (pat_prog_t) - -/* - * - * 2) Conditional Access Table (CAT): - * - * - the CAT provides information on the CA systems used in the - * multiplex; the information is private and dependent on the CA - * system, but includes the location of the EMM stream, when - * applicable. - * - */ -typedef struct cat { - u_char table_id /*:8*/; -#if BYTE_ORDER == BIG_ENDIAN - u_char section_syntax_indicator :1; - u_char dummy :1; // has to be 0 - u_char :2; - u_char section_length_hi :4; -#else - u_char section_length_hi :4; - u_char :2; - u_char dummy :1; // has to be 0 - u_char section_syntax_indicator :1; -#endif - u_char section_length_lo /*:8*/; - u_char :8; - u_char :8; -#if BYTE_ORDER == BIG_ENDIAN - u_char :2; - u_char version_number :5; - u_char current_next_indicator :1; -#else - u_char current_next_indicator :1; - u_char version_number :5; - u_char :2; -#endif - u_char section_number /*:8*/; - u_char last_section_number /*:8*/; -} cat_t; -#define CAT_LEN sizeof (cat_t) - -/* - * - * 3) Program Map Table (PMT): - * - * - the PMT identifies and indicates the locations of the streams that - * make up each service, and the location of the Program Clock - * Reference fields for a service. - * - */ -typedef struct pmt { - u_char table_id /*:8*/; -#if BYTE_ORDER == BIG_ENDIAN - u_char section_syntax_indicator :1; - u_char dummy :1; // has to be 0 - u_char :2; - u_char section_length_hi :4; -#else - u_char section_length_hi :4; - u_char :2; - u_char dummy :1; // has to be 0 - u_char section_syntax_indicator :1; -#endif - u_char section_length_lo /*:8*/; - u_char program_number_hi /*:8*/; - u_char program_number_lo /*:8*/; -#if BYTE_ORDER == BIG_ENDIAN - u_char :2; - u_char version_number :5; - u_char current_next_indicator :1; -#else - u_char current_next_indicator :1; - u_char version_number :5; - u_char :2; -#endif - u_char section_number /*:8*/; - u_char last_section_number /*:8*/; -#if BYTE_ORDER == BIG_ENDIAN - u_char :3; - u_char PCR_PID_hi :5; -#else - u_char PCR_PID_hi :5; - u_char :3; -#endif - u_char PCR_PID_lo /*:8*/; -#if BYTE_ORDER == BIG_ENDIAN - u_char :4; - u_char program_info_length_hi :4; -#else - u_char program_info_length_hi :4; - u_char :4; -#endif - u_char program_info_length_lo /*:8*/; - //descriptors -} pmt_t; -#define PMT_LEN sizeof (pmt_t) - -typedef struct pmt_info { - u_char stream_type /*:8*/; -#if BYTE_ORDER == BIG_ENDIAN - u_char :3; - u_char elementary_PID_hi :5; -#else - u_char elementary_PID_hi :5; - u_char :3; -#endif - u_char elementary_PID_lo /*:8*/; -#if BYTE_ORDER == BIG_ENDIAN - u_char :4; - u_char ES_info_length_hi :4; -#else - u_char ES_info_length_hi :4; - u_char :4; -#endif - u_char ES_info_length_lo /*:8*/; - // descriptors -} pmt_info_t; -#define PMT_INFO_LEN sizeof (pmt_info_t) - -/* - * - * 4) Network Information Table (NIT): - * - * - the NIT is intended to provide information about the physical - * network. The syntax and semantics of the NIT are defined in - * ETSI EN 300 468. - * - */ -typedef struct nit { - u_char table_id /*:8*/; -#if BYTE_ORDER == BIG_ENDIAN - u_char section_syntax_indicator :1; - u_char :3; - u_char section_length_hi :4; -#else - u_char section_length_hi :4; - u_char :3; - u_char section_syntax_indicator :1; -#endif - u_char section_length_lo /*:8*/; - u_char network_id_hi /*:8*/; - u_char network_id_lo /*:8*/; -#if BYTE_ORDER == BIG_ENDIAN - u_char :2; - u_char version_number :5; - u_char current_next_indicator :1; -#else - u_char current_next_indicator :1; - u_char version_number :5; - u_char :2; -#endif - u_char section_number /*:8*/; - u_char last_section_number /*:8*/; -#if BYTE_ORDER == BIG_ENDIAN - u_char :4; - u_char network_descriptor_length_hi :4; -#else - u_char network_descriptor_length_hi :4; - u_char :4; -#endif - u_char network_descriptor_length_lo /*:8*/; - /* descriptors */ -} nit_t; -#define NIT_LEN sizeof (nit_t) - -typedef struct nit_mid { // after descriptors -#if BYTE_ORDER == BIG_ENDIAN - u_char :4; - u_char transport_stream_loop_length_hi :4; -#else - u_char transport_stream_loop_length_hi :4; - u_char :4; -#endif - u_char transport_stream_loop_length_lo /*:8*/; -} nit_mid_t; -#define SIZE_NIT_MID sizeof (nit_mid_t) - -typedef struct nit_end { - long CRC; -} nit_end_t; -#define SIZE_NIT_END sizeof (nit_end_t) - -typedef struct nit_ts { - u_char transport_stream_id_hi /*:8*/; - u_char transport_stream_id_lo /*:8*/; - u_char original_network_id_hi /*:8*/; - u_char original_network_id_lo /*:8*/; -#if BYTE_ORDER == BIG_ENDIAN - u_char :4; - u_char transport_descriptors_length_hi :4; -#else - u_char transport_descriptors_length_hi :4; - u_char :4; -#endif - u_char transport_descriptors_length_lo /*:8*/; - /* descriptors */ -} nit_ts_t; -#define NIT_TS_LEN sizeof (nit_ts_t) - -/* - * - * In addition to the PSI, data is needed to provide identification of - * services and events for the user. In contrast with the PAT, CAT, and - * PMT of the PSI, which give information only for the multiplex in which - * they are contained (the actual multiplex), the additional information - * defined within the present document can also provide information on - * services and events carried by different multiplexes, and even on other - * networks. This data is structured as nine tables: - * - * 1) Bouquet Association Table (BAT): - * - * - the BAT provides information regarding bouquets. As well as giving - * the name of the bouquet, it provides a list of services for each - * bouquet. - * - */ -/* SEE NIT (It has the same structure but has different allowed descriptors) */ -/* - * - * 2) Service Description Table (SDT): - * - * - the SDT contains data describing the services in the system e.g. - * names of services, the service provider, etc. - * - */ -typedef struct sdt { - u_char table_id /*:8*/; -#if BYTE_ORDER == BIG_ENDIAN - u_char section_syntax_indicator :1; - u_char :3; - u_char section_length_hi :4; -#else - u_char section_length_hi :4; - u_char :3; - u_char section_syntax_indicator :1; -#endif - u_char section_length_lo /*:8*/; - u_char transport_stream_id_hi /*:8*/; - u_char transport_stream_id_lo /*:8*/; -#if BYTE_ORDER == BIG_ENDIAN - u_char :2; - u_char version_number :5; - u_char current_next_indicator :1; -#else - u_char current_next_indicator :1; - u_char version_number :5; - u_char :2; -#endif - u_char section_number /*:8*/; - u_char last_section_number /*:8*/; - u_char original_network_id_hi /*:8*/; - u_char original_network_id_lo /*:8*/; - u_char :8; -} sdt_t; -#define SDT_LEN sizeof (sdt_t) -#define GetSDTTransportStreamId(x) HILO(((sdt_t *)x)->transport_stream_id) -#define GetSDTOriginalNetworkId(x) HILO(((sdt_t *)x)->original_network_id) - -typedef struct sdt_descr { - u_char service_id_hi /*:8*/; - u_char service_id_lo /*:8*/; -#if BYTE_ORDER == BIG_ENDIAN - u_char :6; - u_char eit_schedule_flag :1; - u_char eit_present_following_flag :1; - u_char running_status :3; - u_char free_ca_mode :1; - u_char descriptors_loop_length_hi :4; -#else - u_char eit_present_following_flag :1; - u_char eit_schedule_flag :1; - u_char :6; - u_char descriptors_loop_length_hi :4; - u_char free_ca_mode :1; - u_char running_status :3; -#endif - u_char descriptors_loop_length_lo /*:8*/; - u_char data[]; -} sdt_descr_t; -#define SDT_DESCR_LEN sizeof (sdt_descr_t) -#define GetSDTDescriptorsLoopLength(x) HILO(((sdt_descr_t *)x)->descriptors_loop_length) - -/* - * - * 3) Event Information Table (EIT): - * - * - the EIT contains data concerning events or programmes such as event - * name, start time, duration, etc.; - the use of different descriptors - * allows the transmission of different kinds of event information e.g. - * for different service types. - * - */ -typedef struct eit { - u_char table_id /*:8*/; -#if BYTE_ORDER == BIG_ENDIAN - u_char section_syntax_indicator :1; - u_char :3; - u_char section_length_hi :4; -#else - u_char section_length_hi :4; - u_char :3; - u_char section_syntax_indicator :1; -#endif - u_char section_length_lo /*:8*/; - u_char service_id_hi /*:8*/; - u_char service_id_lo /*:8*/; -#if BYTE_ORDER == BIG_ENDIAN - u_char :2; - u_char version_number :5; - u_char current_next_indicator :1; -#else - u_char current_next_indicator :1; - u_char version_number :5; - u_char :2; -#endif - u_char section_number /*:8*/; - u_char last_section_number /*:8*/; - u_char transport_stream_id_hi /*:8*/; - u_char transport_stream_id_lo /*:8*/; - u_char original_network_id_hi /*:8*/; - u_char original_network_id_lo /*:8*/; - u_char segment_last_section_number /*:8*/; - u_char segment_last_table_id /*:8*/; - u_char data[]; /* struct eit_event */ -} eit_t; -#define EIT_LEN sizeof (eit_t) - -typedef struct eit_event { - u_char event_id_hi /*:8*/; - u_char event_id_lo /*:8*/; - u_char mjd_hi /*:8*/; - u_char mjd_lo /*:8*/; - u_char start_time_h /*:8*/; - u_char start_time_m /*:8*/; - u_char start_time_s /*:8*/; - u_char duration_h /*:8*/; - u_char duration_m /*:8*/; - u_char duration_s /*:8*/; -#if BYTE_ORDER == BIG_ENDIAN - u_char running_status :3; - u_char free_ca_mode :1; - u_char descriptors_loop_length_hi :4; -#else - u_char descriptors_loop_length_hi :4; - u_char free_ca_mode :1; - u_char running_status :3; -#endif - u_char descriptors_loop_length_lo /*:8*/; - u_char data[]; /* struct descr_gen */ -} eit_event_t; -#define EIT_EVENT_LEN sizeof (eit_event_t) -#define GetEITDescriptorsLoopLength(x) HILO(((eit_event_t *)x)->descriptors_loop_length) - -/* - * - * 4) Running Status Table (RST): - * - * - the RST gives the status of an event (running/not running). The RST - * updates this information and allows timely automatic switching to - * events. - * - */ - /* TO BE DONE */ -/* - * - * 5) Time and Date Table (TDT): - * - * - the TDT gives information relating to the present time and date. - * This information is given in a separate table due to the frequent - * updating of this information. - * - */ - -typedef struct tdt { - u_char table_id /*:8*/; -#if BYTE_ORDER == BIG_ENDIAN - u_char section_syntax_indicator :1; - u_char :3; - u_char section_length_hi :4; -#else - u_char section_length_hi :4; - u_char :3; - u_char section_syntax_indicator :1; -#endif - u_char section_length_lo /*:8*/; - u_char utc_mjd_hi /*:8*/; - u_char utc_mjd_lo /*:8*/; - u_char utc_time_h /*:8*/; - u_char utc_time_m /*:8*/; - u_char utc_time_s /*:8*/; -} tdt_t; -#define TDT_LEN sizeof (tdt_t) - -/* - * - * 6) Time Offset Table (TOT): - * - * - the TOT gives information relating to the present time and date and - * local time offset. This information is given in a separate table due - * to the frequent updating of the time information. - * - */ -typedef struct tot { - u_char table_id /*:8*/; -#if BYTE_ORDER == BIG_ENDIAN - u_char section_syntax_indicator :1; - u_char :3; - u_char section_length_hi :4; -#else - u_char section_length_hi :4; - u_char :3; - u_char section_syntax_indicator :1; -#endif - u_char section_length_lo /*:8*/; - u_char utc_mjd_hi /*:8*/; - u_char utc_mjd_lo /*:8*/; - u_char utc_time_h /*:8*/; - u_char utc_time_m /*:8*/; - u_char utc_time_s /*:8*/; -#if BYTE_ORDER == BIG_ENDIAN - u_char :4; - u_char descriptors_loop_length_hi :4; -#else - u_char descriptors_loop_length_hi :4; - u_char :4; -#endif - u_char descriptors_loop_length_lo /*:8*/; -} tot_t; -#define TOT_LEN sizeof (tot_t) - -/* - * - * 7) Stuffing Table (ST): - * - * - the ST is used to invalidate existing sections, for example at - * delivery system boundaries. - * - */ - /* TO BE DONE */ -/* - * - * 8) Selection Information Table (SIT): - * - * - the SIT is used only in "partial" (i.e. recorded) bitstreams. It - * carries a summary of the SI information required to describe the - * streams in the partial bitstream. - * - */ -struct sit { - uint8_t tableid; -#if BYTE_ORDER == BIG_ENDIAN - uint8_t section_length_hi : 4; - bool reserved1 : 2; - bool reserved_fu : 1; - bool section_syntax : 1; -#else - bool section_syntax : 1; - bool reserved_fu : 1; - bool reserved1 : 2; - uint8_t section_length_hi : 4; -#endif - uint8_t section_length_lo; - uint16_t transport_stream_id ; - bool reserved2 : 2; - uint8_t version : 5; - bool current_next_ind : 1; - uint8_t section_number; - uint8_t last_section_number; - uint16_t original_network_id; - uint8_t reserved3; - u_char serviceData[]; -} __attribute__((packed)); -struct si { - uint16_t serviceid; - uint8_t reserved_fu : 6; - bool eit_sched : 1; - bool eit_now_and_next : 1; -#if BYTE_ORDER == BIG_ENDIAN - uint8_t running_status : 3; - bool free_ca_mode : 1; - uint8_t desc_loop_len_hi : 4; -#else - uint8_t desc_loop_len_hi : 4; - bool free_ca_mode : 1; - uint8_t running_status : 3; -#endif - uint8_t desc_loop_len_lo; - u_char descData[]; -} __attribute__((packed)); -/* - * - * 9) Discontinuity Information Table (DIT): - * - * - the DIT is used only in "partial" (i.e. recorded) bitstreams. - * It is inserted where the SI information in the partial bitstream may - * be discontinuous. Where applicable the use of descriptors allows a - * flexible approach to the organization of the tables and allows for - * future compatible extensions. - * - */ - /* TO BE DONE */ -/* - * - * The following describes the different descriptors that can be used within - * the SI. - * - * The following semantics apply to all the descriptors defined in this - * subclause: - * - * descriptor_tag: The descriptor tag is an 8-bit field which identifies - * each descriptor. Those values with MPEG-2 normative - * meaning are described in ISO/IEC 13818-1. The values of - * descriptor_tag are defined in 'libsi.h' - * descriptor_length: The descriptor length is an 8-bit field specifying the - * total number of bytes of the data portion of the - * descriptor following the byte defining the value of - * this field. - * - */ - -typedef struct descr_gen { - u_char descriptor_tag /*:8*/; - u_char descriptor_length /*:8*/; -} descr_gen_t; -#define DESCR_GEN_LEN sizeof (descr_gen_t) -#define CastGenericDescriptor(x) ((descr_gen_t *)(x)) - -#define GetDescriptorTag(x) (((descr_gen_t *)x)->descriptor_tag) -#define GetDescriptorLength(x) (((descr_gen_t *)x)->descriptor_length) - -/* 0x09 ca_descriptor */ -typedef struct descr_ca { - u_char descriptor_tag /*:8*/; - u_char descriptor_length /*:8*/; - u_char CA_type_hi /*:8*/; - u_char CA_type_lo /*:8*/; -#if BYTE_ORDER == BIG_ENDIAN - u_char :3; - u_char CA_PID_hi :5; -#else - u_char CA_PID_hi :5; - u_char :3; -#endif - u_char CA_PID_lo /*:8*/; -} descr_ca_t; -#define DESCR_CA_LEN sizeof (descr_ca_t) -#define CastCaDescriptor(x) ((descr_ca_t *)(x)) - -/* 0x0A iso_639_language_descriptor */ -typedef struct descr_iso_639_language { - u_char descriptor_tag /*:8*/; - u_char descriptor_length /*:8*/; - u_char lang_code1 /*:8*/; - u_char lang_code2 /*:8*/; - u_char lang_code3 /*:8*/; -} descr_iso_639_language_t; -#define DESCR_ISO_639_LANGUAGE_LEN sizeof (descr_iso_639_language_t) -#define CastIso639LanguageDescriptor(x) ((descr_iso_639_language_t *)(x)) - -/* 0x40 network_name_descriptor */ -typedef struct descr_network_name { - u_char descriptor_tag /*:8*/; - u_char descriptor_length /*:8*/; -} descr_network_name_t; -#define DESCR_NETWORK_NAME_LEN sizeof (descr_network_name_t) -#define CastNetworkNameDescriptor(x) ((descr_network_name_t *)(x)) - -/* 0x41 service_list_descriptor */ -typedef struct descr_service_list { - u_char descriptor_tag /*:8*/; - u_char descriptor_length /*:8*/; -} descr_service_list_t; -#define DESCR_SERVICE_LIST_LEN sizeof (descr_service_list_t) -#define CastServiceListDescriptor(x) ((descr_service_list_t *)(x)) - -typedef struct descr_service_list_loop { - u_char service_id_hi /*:8*/; - u_char service_id_lo /*:8*/; - u_char service_type /*:8*/; -} descr_service_list_loop_t; -#define DESCR_SERVICE_LIST_LOOP_LEN sizeof (descr_service_list_loop_t) -#define CastServiceListDescriptorLoop(x) ((descr_service_list_loop_t *)(x)) - -/* 0x42 stuffing_descriptor */ -typedef struct descr_stuffing { - u_char descriptor_tag /*:8*/; - u_char descriptor_length /*:8*/; - u_char data[]; -} descr_stuffing_t; -#define DESCR_STUFFING_LEN sizeof (descr_stuffing_t) -#define CastStuffingDescriptor(x) ((descr_stuffing_t *)(x)) - -/* 0x43 satellite_delivery_system_descriptor */ -typedef struct descr_satellite_delivery_system { - u_char descriptor_tag /*:8*/; - u_char descriptor_length /*:8*/; - u_char frequency1 /*:8*/; - u_char frequency2 /*:8*/; - u_char frequency3 /*:8*/; - u_char frequency4 /*:8*/; - u_char orbital_position1 /*:8*/; - u_char orbital_position2 /*:8*/; -#if BYTE_ORDER == BIG_ENDIAN - u_char west_east_flag :1; - u_char polarization :2; - u_char modulation :5; -#else - u_char modulation :5; - u_char polarization :2; - u_char west_east_flag :1; -#endif - u_char symbol_rate1 /*:8*/; - u_char symbol_rate2 /*:8*/; - u_char symbol_rate3 /*:8*/; -#if BYTE_ORDER == BIG_ENDIAN - u_char symbol_rate4 :4; - u_char fec_inner :4; -#else - u_char fec_inner :4; - u_char symbol_rate4 :4; -#endif -} descr_satellite_delivery_system_t; -#define DESCR_SATELLITE_DELIVERY_SYSTEM_LEN sizeof (descr_satellite_delivery_system_t) -#define CastSatelliteDeliverySystemDescriptor(x) ((descr_satellite_delivery_system_t *)(x)) -#define GetSatelliteDeliverySystemFrequency(x) HILO4(((descr_satellite_delivert_system_t *)x)->frequency) -#define GetSatelliteDeliverySystemSymbolRate(x) HILO4(((descr_satellite_delivert_system_t *)x)->symbol_rate) - - -/* 0x44 cable_delivery_system_descriptor */ -typedef struct descr_cable_delivery_system { - u_char descriptor_tag /*:8*/; - u_char descriptor_length /*:8*/; - u_char frequency1 /*:8*/; - u_char frequency2 /*:8*/; - u_char frequency3 /*:8*/; - u_char frequency4 /*:8*/; - u_char :8; -#if BYTE_ORDER == BIG_ENDIAN - u_char :4; - u_char fec_outer :4; -#else - u_char fec_outer :4; - u_char :4; -#endif - u_char modulation /*:8*/; - u_char symbol_rate1 /*:8*/; - u_char symbol_rate2 /*:8*/; - u_char symbol_rate3 /*:8*/; -#if BYTE_ORDER == BIG_ENDIAN - u_char symbol_rate4 :4; - u_char fec_inner :4; -#else - u_char fec_inner :4; - u_char symbol_rate4 :4; -#endif -} descr_cable_delivery_system_t; -#define DESCR_CABLE_DELIVERY_SYSTEM_LEN sizeof (descr_cable_delivery_system_t) -#define CastCableDeliverySystemDescriptor(x) ((descr_cable_delivery_system_t *)(x)) -#define GetCableDeliverySystemFrequency(x) HILO4(((descr_cable_delivert_system_t *)x)->frequency) -#define GetCableDeliverySystemSymbolRate(x) HILO4(((descr_cable_delivert_system_t *)x)->symbol_rate) - -/* 0x45 vbi_data_descriptor */ -typedef struct descr_vbi_data { - u_char descriptor_tag /*:8*/; - u_char descriptor_length /*:8*/; - /* TBD */ -} descr_vbi_data_t; -#define DESCR_VBI_DATA_LEN sizeof (descr_vbi_data_t) -#define CastVbiDataDescriptor(x) ((descr_vbi_data_t *)(x)) - -/* 0x46 vbi_teletext_descriptor */ -typedef struct descr_vbi_teletext { - u_char descriptor_tag /*:8*/; - u_char descriptor_length /*:8*/; - /* TBD */ -} descr_vbi_teletext_t; -#define DESCR_VBI_TELETEXT_LEN sizeof (descr_vbi_teletext_t) -#define CastVbiDescriptor(x) ((descr_vbi_teletext_t *)(x)) - -/* 0x47 bouquet_name_descriptor */ -typedef struct descr_bouquet_name { - u_char descriptor_tag /*:8*/; - u_char descriptor_length /*:8*/; -} descr_bouquet_name_t; -#define DESCR_BOUQUET_NAME_LEN sizeof (descr_bouquet_name_t) - -#define CastBouquetNameDescriptor(x) ((descr_bouquet_name_t *)(x)) - -/* 0x48 service_descriptor */ -typedef struct descr_service { - u_char descriptor_tag /*:8*/; - u_char descriptor_length /*:8*/; - u_char service_type /*:8*/; - u_char provider_name_length /*:8*/; -} descr_service_t; -#define DESCR_SERVICE_LEN sizeof (descr_service_t) -#define CastServiceDescriptor(x) ((descr_service_t *)(x)) - -/* 0x49 country_availability_descriptor */ -typedef struct descr_country_availability { - u_char descriptor_tag /*:8*/; - u_char descriptor_length /*:8*/; -#if BYTE_ORDER == BIG_ENDIAN - u_char country_availability_flag :1; - u_char :7; -#else - u_char :7; - u_char country_availability_flag :1; -#endif -} descr_country_availability_t; -#define DESCR_COUNTRY_AVAILABILITY_LEN sizeof (descr_country_availability_t) -#define CastCountryAvailabilityDescriptor(x) ((descr_country_availability_t *)(x)) - -/* 0x4A linkage_descriptor */ -typedef struct descr_linkage { - u_char descriptor_tag /*:8*/; - u_char descriptor_length /*:8*/; - u_char transport_stream_id_hi /*:8*/; - u_char transport_stream_id_lo /*:8*/; - u_char original_network_id_hi /*:8*/; - u_char original_network_id_lo /*:8*/; - u_char service_id_hi /*:8*/; - u_char service_id_lo /*:8*/; - u_char linkage_type /*:8*/; -} descr_linkage_t; -#define DESCR_LINKAGE_LEN sizeof (descr_linkage_t) -#define CastLinkageDescriptor(x) ((descr_linkage_t *)(x)) - -/* 0x4B nvod_reference_descriptor */ -typedef struct descr_nvod_reference { - u_char descriptor_tag /*:8*/; - u_char descriptor_length /*:8*/; - u_char data[]; /* struct item_nvod_reference */ -} descr_nvod_reference_t; -#define DESCR_NVOD_REFERENCE_LEN sizeof (descr_nvod_reference_t) -#define CastNvodReferenceDescriptor(x) ((descr_nvod_reference_t *)(x)) - -typedef struct item_nvod_reference { - u_char transport_stream_id_hi /*:8*/; - u_char transport_stream_id_lo /*:8*/; - u_char original_network_id_hi /*:8*/; - u_char original_network_id_lo /*:8*/; - u_char service_id_hi /*:8*/; - u_char service_id_lo /*:8*/; -} item_nvod_reference_t; -#define ITEM_NVOD_REFERENCE_LEN sizeof (item_nvod_reference_t) -#define CastNvodReferenceItem(x) ((item_nvod_reference_t *)(x)) - -/* 0x4C time_shifted_service_descriptor */ -typedef struct descr_time_shifted_service { - u_char descriptor_tag /*:8*/; - u_char descriptor_length /*:8*/; - u_char reference_service_id_hi /*:8*/; - u_char reference_service_id_lo /*:8*/; -} descr_time_shifted_service_t; -#define DESCR_TIME_SHIFTED_SERVICE_LEN sizeof (descr_time_shifted_service_t) -#define CastTimeShiftedServiceDescriptor(x) ((descr_time_shifted_service_t *)(x)) - -/* 0x4D short_event_descriptor */ -typedef struct descr_short_event { - u_char descriptor_tag /*:8*/; - u_char descriptor_length /*:8*/; - u_char lang_code1 /*:8*/; - u_char lang_code2 /*:8*/; - u_char lang_code3 /*:8*/; - u_char event_name_length /*:8*/; - u_char data[]; -} descr_short_event_t; -#define DESCR_SHORT_EVENT_LEN sizeof (descr_short_event_t) -#define CastShortEventDescriptor(x) ((descr_short_event_t *)(x)) - -/* 0x4E extended_event_descriptor */ -typedef struct descr_extended_event { - u_char descriptor_tag /*:8*/; - u_char descriptor_length /*:8*/; -#if BYTE_ORDER == BIG_ENDIAN - u_char descriptor_number :4; - u_char last_descriptor_number :4; -#else - u_char last_descriptor_number :4; - u_char descriptor_number :4; -#endif - u_char lang_code1 /*:8*/; - u_char lang_code2 /*:8*/; - u_char lang_code3 /*:8*/; - u_char length_of_items /*:8*/; - u_char data[]; /* struct item_extended_event */ -} descr_extended_event_t; -#define DESCR_EXTENDED_EVENT_LEN sizeof (descr_extended_event_t) -#define CastExtendedEventDescriptor(x) ((descr_extended_event_t *)(x)) - -typedef struct item_extended_event { - u_char item_description_length /*:8*/; - u_char data[]; -} item_extended_event_t; -#define ITEM_EXTENDED_EVENT_LEN sizeof (item_extended_event_t) -#define CastExtendedEventItem(x) ((item_extended_event_t *)(x)) - -/* 0x4F time_shifted_event_descriptor */ -typedef struct descr_time_shifted_event { - u_char descriptor_tag /*:8*/; - u_char descriptor_length /*:8*/; - u_char reference_service_id_hi /*:8*/; - u_char reference_service_id_lo /*:8*/; - u_char reference_event_id_hi /*:8*/; - u_char reference_event_id_lo /*:8*/; -} descr_time_shifted_event_t; -#define DESCR_TIME_SHIFTED_EVENT_LEN sizeof (descr_time_shifted_event_t) -#define CastTimeShiftedEventDescriptor(x) ((descr_time_shifted_event_t *)(x)) - -/* 0x50 component_descriptor */ -typedef struct descr_component { - u_char descriptor_tag /*:8*/; - u_char descriptor_length /*:8*/; -#if BYTE_ORDER == BIG_ENDIAN - u_char :4; - u_char stream_content :4; -#else - u_char stream_content :4; - u_char :4; -#endif - u_char component_type /*:8*/; - u_char component_tag /*:8*/; - u_char lang_code1 /*:8*/; - u_char lang_code2 /*:8*/; - u_char lang_code3 /*:8*/; - u_char data[]; -} descr_component_t; -#define DESCR_COMPONENT_LEN sizeof (descr_component_t) -#define CastComponentDescriptor(x) ((descr_component_t *)(x)) - -/* 0x51 mosaic_descriptor */ -typedef struct descr_mosaic { - u_char descriptor_tag /*:8*/; - u_char descriptor_length /*:8*/; -#if BYTE_ORDER == BIG_ENDIAN - u_char mosaic_entry_point :1; - u_char number_of_horizontal_elementary_cells :3; - u_char :1; - u_char number_of_vertical_elementary_cells :3; -#else - u_char number_of_vertical_elementary_cells :3; - u_char :1; - u_char number_of_horizontal_elementary_cells :3; - u_char mosaic_entry_point :1; -#endif - u_char data[]; /* struct item_mosaic */ -} descr_mosaic_t; -#define DESCR_MOSAIC_LEN sizeof (descr_mosaic_t) -#define CastMosaicDescriptor(x) ((descr_mosaic_t *)(x)) - -typedef struct item_mosaic { -#if BYTE_ORDER == BIG_ENDIAN - u_char logical_cell_id :6; - u_char :7; - u_char logical_cell_presentation_info :3; -#else - u_char :2; - u_char logical_cell_id :6; - u_char logical_cell_presentation_info :3; /*0=undefined, 1=video, 2=still picture, 3=graphical text, 4--7=reserved*/ - u_char :5; -#endif - u_char elementary_cell_field_length /*:8*/; - u_char data[]; /* struct item_mosaic_cell; struct item_mosaic_end */ -} item_mosaic_t; -typedef struct item_mosaic_end { - u_char cell_linkage_info /*:8*/; /*0=undefined, 1=bouquet, 2=service, 3=other mosaic, 4=event, 5--255=reserved*/ - u_char data[]; /* union item_cell_linkage */ -} item_mosaic_end_t; - -typedef struct item_mosaic_cell { -#if BYTE_ORDER == BIG_ENDIAN - u_char :2; - u_char elementary_cell_id :6; -#else - u_char elementary_cell_id :6; - u_char :2; -#endif -} item_mosaic_cell_t; -typedef union item_mosaic_cell_linkage { - struct item_mosaic_cell_bouquet { - u_char bouquet_id_hi /*:8*/; - u_char bouquet_id_lo /*:8*/; - } bouquet; - struct item_mosaic_cell_service { - u_char original_network_id_hi /*:8*/; - u_char original_network_id_lo /*:8*/; - u_char transport_stream_id_hi /*:8*/; - u_char transport_stream_id_lo /*:8*/; - u_char service_id_hi /*:8*/; - u_char service_id_lo /*:8*/; - } service; - struct item_mosaic_cell_other { - u_char original_network_id_hi /*:8*/; - u_char original_network_id_lo /*:8*/; - u_char transport_stream_id_hi /*:8*/; - u_char transport_stream_id_lo /*:8*/; - u_char service_id_hi /*:8*/; - u_char service_id_lo /*:8*/; - } other; - struct item_mosaic_cell_event { - u_char original_network_id_hi /*:8*/; - u_char original_network_id_lo /*:8*/; - u_char transport_stream_id_hi /*:8*/; - u_char transport_stream_id_lo /*:8*/; - u_char service_id_hi /*:8*/; - u_char service_id_lo /*:8*/; - u_char event_id_hi /*:8*/; - u_char event_id_lo /*:8*/; - } event; -} item_mosaic_cell_linkage_t; - -/* 0x52 stream_identifier_descriptor */ -typedef struct descr_stream_identifier { - u_char descriptor_tag /*:8*/; - u_char descriptor_length /*:8*/; - u_char component_tag /*:8*/; -} descr_stream_identifier_t; -#define DESCR_STREAM_IDENTIFIER_LEN sizeof (descr_stream_identifier_t) -#define CastStreamIdentifierDescriptor(x) ((descr_stream_identifier_t *)(x)) - -/* 0x53 ca_identifier_descriptor */ -typedef struct descr_ca_identifier { - u_char descriptor_tag /*:8*/; - u_char descriptor_length /*:8*/; -} descr_ca_identifier_t; -#define DESCR_CA_IDENTIFIER_LEN sizeof (descr_ca_identifier_t) -#define CastCaIdentifierDescriptor(x) ((descr_ca_identifier_t *)(x)) - -/* 0x54 content_descriptor */ -typedef struct descr_content { - u_char descriptor_tag /*:8*/; - u_char descriptor_length /*:8*/; - u_char data[]; /* struct nibble_content */ -} descr_content_t; -#define DESCR_CONTENT_LEN sizeof (descr_content_t) -#define CastContentDescriptor(x) ((descr_content_t *)(x)) - -typedef struct nibble_content { -#if BYTE_ORDER == BIG_ENDIAN - u_char content_nibble_level_1 :4; - u_char content_nibble_level_2 :4; - u_char user_nibble_1 :4; - u_char user_nibble_2 :4; -#else - u_char user_nibble_2 :4; - u_char user_nibble_1 :4; - u_char content_nibble_level_2 :4; - u_char content_nibble_level_1 :4; -#endif -} nibble_content_t; -#define NIBBLE_CONTENT_LEN sizeof (nibble_content_t) -#define CastContentNibble(x) ((nibble_content_t *)(x)) - -/* 0x55 parental_rating_descriptor */ -typedef struct descr_parental_rating { - u_char descriptor_tag /*:8*/; - u_char descriptor_length /*:8*/; - u_char data[]; /* struct parental_rating_item */ -} descr_parental_rating_t; -#define DESCR_PARENTAL_RATING_LEN sizeof (descr_parental_rating_t) -#define CastParentalRatingDescriptor(x) ((descr_parental_rating_t *)(x)) - -typedef struct parental_rating_item { - u_char lang_code1 /*:8*/; - u_char lang_code2 /*:8*/; - u_char lang_code3 /*:8*/; - u_char rating /*:8*/; -} parental_rating_item_t; -#define PARENTAL_RATING_ITEM_LEN sizeof (parental_rating_item_t) -#define CastParentalRatingItem(x) ((parental_rating_item_t *)(x)) - -/* 0x56 teletext_descriptor */ -typedef struct descr_teletext { - u_char descriptor_tag /*:8*/; - u_char descriptor_length /*:8*/; - u_char data[]; /* struct item_teletext */ -} descr_teletext_t; -#define DESCR_TELETEXT_LEN sizeof (descr_teletext_t) -#define CastTeletextDescriptor(x) ((descr_teletext_t *)(x)) - -typedef struct item_teletext { - u_char lang_code1 /*:8*/; - u_char lang_code2 /*:8*/; - u_char lang_code3 /*:8*/; -#if BYTE_ORDER == BIG_ENDIAN - u_char type :5; - u_char magazine_number :3; -#else - u_char magazine_number :3; - u_char type :5; -#endif - u_char page_number /*:8*/; -} item_teletext_t; -#define ITEM_TELETEXT_LEN sizeof (item_teletext_t) -#define CastTeletextItem(x) ((item_teletext_t *)(x)) - -/* 0x57 telephone_descriptor */ -typedef struct descr_telephone { - u_char descriptor_tag /*:8*/; - u_char descriptor_length /*:8*/; -#if BYTE_ORDER == BIG_ENDIAN - u_char :2; - u_char foreign_availability :1; - u_char connection_type :5; -#else - u_char connection_type :5; - u_char foreign_availability :1; - u_char :2; -#endif -#if BYTE_ORDER == BIG_ENDIAN - u_char :1; - u_char country_prefix_length :2; - u_char international_area_code_length :3; - u_char operator_code_length :2; -#else - u_char operator_code_length :2; - u_char international_area_code_length :3; - u_char country_prefix_length :2; - u_char :1; -#endif -#if BYTE_ORDER == BIG_ENDIAN - u_char :1; - u_char national_area_code_length :3; - u_char core_number_length :4; -#else - u_char core_number_length :4; - u_char national_area_code_length :3; - u_char :1; -#endif - u_char data[]; /* coutry area operator national core */ -} descr_telephone_t; -#define DESCR_TELEPHONE_LEN sizeof (descr_telephone_t) -#define CastTelephoneDescriptor(x) ((descr_telephone_t *)(x)) - -/* 0x58 local_time_offset_descriptor */ -typedef struct descr_local_time_offset { - u_char descriptor_tag /*:8*/; - u_char descriptor_length /*:8*/; -} descr_local_time_offset_t; -#define DESCR_LOCAL_TIME_OFFSET_LEN sizeof (descr_local_time_offset_t) -#define CastLocalTimeOffsetDescriptor(x) ((descr_local_time_offset_t *)(x)) - -typedef struct local_time_offset_entry { - u_char country_code1 /*:8*/; - u_char country_code2 /*:8*/; - u_char country_code3 /*:8*/; -#if BYTE_ORDER == BIG_ENDIAN - u_char country_region_id :6; - u_char :1; - u_char local_time_offset_polarity :1; -#else - u_char local_time_offset_polarity :1; - u_char :1; - u_char country_region_id :6; -#endif - u_char local_time_offset_h /*:8*/; - u_char local_time_offset_m /*:8*/; - u_char time_of_change_mjd_hi /*:8*/; - u_char time_of_change_mjd_lo /*:8*/; - u_char time_of_change_time_h /*:8*/; - u_char time_of_change_time_m /*:8*/; - u_char time_of_change_time_s /*:8*/; - u_char next_time_offset_h /*:8*/; - u_char next_time_offset_m /*:8*/; -} local_time_offset_entry_t ; -#define LOCAL_TIME_OFFSET_ENTRY_LEN sizeof (local_time_offset_entry_t) -#define CastLocalTimeOffsetEntry(x) ((local_time_offset_entry_t *)(x)) - -/* 0x59 subtitling_descriptor */ -typedef struct descr_subtitling { - u_char descriptor_tag /*:8*/; - u_char descriptor_length /*:8*/; - u_char data[]; /* item_subtitling */ -} descr_subtitling_t; -#define DESCR_SUBTITLING_LEN sizeof (descr_subtitling_t) -#define CastSubtitlingDescriptor(x) ((descr_subtitling_t *)(x)) - -typedef struct item_subtitling { - u_char lang_code1 /*:8*/; - u_char lang_code2 /*:8*/; - u_char lang_code3 /*:8*/; - u_char subtitling_type /*:8*/; - u_char composition_page_id_hi /*:8*/; - u_char composition_page_id_lo /*:8*/; - u_char ancillary_page_id_hi /*:8*/; - u_char ancillary_page_id_lo /*:8*/; -} item_subtitling_t; -#define ITEM_SUBTITLING_LEN sizeof (item_subtitling_t) -#define CastSubtitlingItem(x) ((item_subtitling_t *)(x)) - -/* 0x5A terrestrial_delivery_system_descriptor */ -typedef struct descr_terrestrial_delivery { - u_char descriptor_tag /*:8*/; - u_char descriptor_length /*:8*/; - u_char frequency1 /*:8*/; - u_char frequency2 /*:8*/; - u_char frequency3 /*:8*/; - u_char frequency4 /*:8*/; -#if BYTE_ORDER == BIG_ENDIAN - u_char bandwidth :3; - u_char :5; -#else - u_char :5; - u_char bandwidth :3; -#endif -#if BYTE_ORDER == BIG_ENDIAN - u_char constellation :2; - u_char hierarchy :3; - u_char code_rate_HP :3; -#else - u_char code_rate_HP :3; - u_char hierarchy :3; - u_char constellation :2; -#endif -#if BYTE_ORDER == BIG_ENDIAN - u_char code_rate_LP :3; - u_char guard_interval :2; - u_char transmission_mode :2; - u_char other_frequency_flag :1; -#else - u_char other_frequency_flag :1; - u_char transmission_mode :2; - u_char guard_interval :2; - u_char code_rate_LP :3; -#endif - u_char reserver2 /*:8*/; - u_char reserver3 /*:8*/; - u_char reserver4 /*:8*/; - u_char reserver5 /*:8*/; -} descr_terrestrial_delivery_system_t; -#define DESCR_TERRESTRIAL_DELIVERY_SYSTEM_LEN sizeof (descr_terrestrial_delivery_system_t) -#define CastTerrestrialDeliverySystemDescriptor(x) ((descr_terrestrial_delivery_system_t *)(x)) -#define GetTerrestrialDeliverySystemFrequency(x) HILO4(((descr_terrestrial_delivert_system_t *)x)->frequency) - -/* 0x5B multilingual_network_name_descriptor */ -typedef struct descr_multilingual_network_name { - u_char descriptor_tag /*:8*/; - u_char descriptor_length /*:8*/; - u_char data[]; /* struct item_multilingual_network_name */ -} descr_multilingual_network_name_t; -#define DESCR_MULTILINGUAL_NETWORK_NAME_LEN sizeof (descr_multilingual_network_name_t) -#define CastMultilingualNetworkNameDescriptor(x) ((descr_multilingual_network_name_t *)(x)) - -typedef struct item_multilingual_network_name { - u_char lang_code1 /*:8*/; - u_char lang_code2 /*:8*/; - u_char lang_code3 /*:8*/; - u_char network_name_length /*:8*/; - u_char network_name[]; -} item_multilingual_network_name_t; - -/* 0x5C multilingual_bouquet_name_descriptor */ -typedef struct descr_multilingual_bouquet_name { - u_char descriptor_tag /*:8*/; - u_char descriptor_length /*:8*/; - u_char names[]; /* struct item_multilingual_bouquet_name */ -} descr_multilingual_bouquet_name_t; -#define DESCR_MULTILINGUAL_BOUQUET_NAME_LEN sizeof (descr_multilingual_bouquet_name_t) -#define CastMultilingualBouquetNameDescriptor(x) ((descr_multilingual_bouquet_name_t *)(x)) - -typedef struct item_multilingual_bouquet_name { - u_char lang_code1 /*:8*/; - u_char lang_code2 /*:8*/; - u_char lang_code3 /*:8*/; - u_char bouquet_name_length /*:8*/; - u_char bouquet_name[]; -} item_multilingual_bouquet_name_t; - -/* 0x5D multilingual_service_name_descriptor */ -typedef struct descr_multilingual_service_name { - u_char descriptor_tag /*:8*/; - u_char descriptor_length /*:8*/; - u_char data[]; /* struct multilingual_service_name_item */ -} descr_multilingual_service_name_t; -#define DESCR_MULTILINGUAL_SERVICE_NAME_LEN sizeof (descr_multilingual_service_name_t) -#define CastMultilingualServiceNameDescriptor(x) ((descr_multilingual_service_name_t *)(x)) - -typedef struct multilingual_service_name_item { - u_char lang_code1 /*:8*/; - u_char lang_code2 /*:8*/; - u_char lang_code3 /*:8*/; - u_char data[]; /* struct multilingual_service_name_item_(mid|end) */ -} multilingual_service_name_item_t; -typedef struct multilingual_service_name_item_mid { - u_char service_provider_name_length /*:8*/; - u_char service_provider_name[]; -} multilingual_service_name_item_mid_t; -typedef struct multilingual_service_name_item_end { - u_char service_name_length /*:8*/; - u_char service_name[]; -} multilingual_service_name_item_end_t; - -/* 0x5E multilingual_component_descriptor */ -typedef struct descr_multilingual_component { - u_char descriptor_tag /*:8*/; - u_char descriptor_length /*:8*/; - u_char component_tag /*:8*/; - u_char data[]; /* struct multilingual_component_item */ -} descr_multilingual_component_t; -#define DESCR_MULTILINGUAL_COMPONENT_LEN sizeof (descr_multilingual_component_t) -#define CastMultilingualComponentDescriptor(x) ((descr_multilingual_component_t *)(x)) - -typedef struct item_multilingual_component { - u_char lang_code1 /*:8*/; - u_char lang_code2 /*:8*/; - u_char lang_code3 /*:8*/; - u_char text_description_length /*:8*/; - u_char text_description[]; -} item_multilingual_component_t; - -/* 0x5F private_data_specifier_descriptor */ -typedef struct descr_private_data_specifier { - u_char descriptor_tag /*:8*/; - u_char descriptor_length /*:8*/; - u_char private_data_specifier1 /*:8*/; - u_char private_data_specifier2 /*:8*/; - u_char private_data_specifier3 /*:8*/; - u_char private_data_specifier4 /*:8*/; -} descr_private_data_specifier_t; -#define DESCR_PRIVATE_DATA_SPECIFIER_LEN sizeof (descr_private_data_specifier_t) -#define CastPrivateDataSpecifierDescriptor(x) ((descr_private_data_specifier_t *)(x)) -#define GetPrivateDataSpecifier(x) HILO4(((descr_private_data_specifier_t *)x)->private_data_specifier) - -/* 0x60 service_move_descriptor */ -typedef struct descr_service_move { - u_char descriptor_tag /*:8*/; - u_char descriptor_length /*:8*/; - u_char new_original_network_id_hi /*:8*/; - u_char new_original_network_id_lo /*:8*/; - u_char new_transport_stream_id_hi /*:8*/; - u_char new_transport_stream_id_lo /*:8*/; - u_char new_service_id_hi /*:8*/; - u_char new_service_id_lo /*:8*/; -} descr_service_move_t; -#define DESCR_SERVICE_MOVE_LEN sizeof (descr_service_move_t) -#define CastServiceMoveDescriptor(x) ((descr_service_move_t *)(x)) - -/* 0x61 short_smoothing_buffer_descriptor */ -typedef struct descr_short_smoothing_buffer { - u_char descriptor_tag /*:8*/; - u_char descriptor_length /*:8*/; -#if BYTE_ORDER == BIG_ENDIAN - u_char sb_size :2; - u_char sb_leak_rate :6; -#else - u_char sb_leak_rate :6; - u_char sb_size :2; -#endif - u_char data[]; -} descr_short_smoothing_buffer_t; -#define DESCR_SHORT_SMOOTHING_BUFFER_LEN sizeof (descr_short_smoothing_buffer_t) -#define CastShortSmoothingBufferDescriptor(x) ((descr_short_smoothing_buffer_t *)(x)) - -/* 0x62 frequency_list_descriptor */ -typedef struct descr_frequency_list { - u_char descriptor_tag /*:8*/; - u_char descriptor_length /*:8*/; -#if BYTE_ORDER == BIG_ENDIAN - u_char :6; - u_char coding_type :2; /* 00=not def 01=satelite 10=cable 11=terrestrial */ -#else - u_char coding_type :2; /* 00=not def 01=satelite 10=cable 11=terrestrial */ - u_char :6; -#endif - u_char centre_frequency1 /*:8*/; - u_char centre_frequency2 /*:8*/; - u_char centre_frequency3 /*:8*/; - u_char centre_frequency4 /*:8*/; -} descr_frequency_list_t; -#define DESCR_FREQUENCY_LIST_LEN sizeof (descr_frequency_list_t) -#define CastFrequencyListDescriptor(x) ((descr_frequency_list_t *)(x)) - -/* 0x63 partial_transport_stream_descriptor */ -typedef struct descr_partial_transport_stream { - u_char descriptor_tag /*:8*/; - u_char descriptor_length /*:8*/; -#if BYTE_ORDER == BIG_ENDIAN - u_char :2; - u_char peak_rate1 :6; -#else - u_char peak_rate1 :6; - u_char :2; -#endif - u_char peak_rate2 /*:8*/; - u_char peak_rate3 /*:8*/; -#if BYTE_ORDER == BIG_ENDIAN - u_char :2; - u_char minimum_overall_smoothing_rate1 :6; -#else - u_char minimum_overall_smoothing_rate1 :6; - u_char :2; -#endif - u_char minimum_overall_smoothing_rate2 /*:8*/; - u_char minimum_overall_smoothing_rate3 /*:8*/; -#if BYTE_ORDER == BIG_ENDIAN - u_char :2; - u_char maximum_overall_smoothing_rate1 :6; -#else - u_char maximum_overall_smoothing_rate1 :6; - u_char :2; -#endif - u_char maximum_overall_smoothing_rate2 /*:8*/; -} descr_partial_transport_stream_t; -#define DESCR_PARTIAL_TRANSPORT_STREAM_LEN sizeof (descr_partial_transport_stream_t) -#define CastPartialDescriptor(x) ((descr_partial_transport_stream_t *)(x)) -#define GetPartialTransportStreamCentreFrequency(x) HILO4(((descr_partial_transport_stream_t *)x)->centre_frequency) -#define GetPTSPeakRate(x) HILO2(((descr_partial_transport_stream *)x)->peak_rate) -#define GetPTSMinOSRate(x) HILO3(((descr_partial_transport_stream *)x)->minimum_overall_smoothing_rate) -#define GetPTSMaxOSRate(x) HILO2(((descr_partial_transport_stream *)x)->minimum_overall_smoothing_rate) - -/* 0x64 data_broadcast_descriptor */ -typedef struct descr_data_broadcast { - u_char descriptor_tag /*:8*/; - u_char descriptor_length /*:8*/; - u_char data_broadcast_id_hi /*:8*/; - u_char data_broadcast_id_lo /*:8*/; - u_char component_tag /*:8*/; - u_char selector_length /*:8*/; - u_char data[]; /* char[]; struct descr_data_broadcast_end */ -} descr_data_broadcast_t; -typedef struct descr_data_broadcast_end { - u_char lang_code1 /*:8*/; - u_char lang_code2 /*:8*/; - u_char lang_code3 /*:8*/; - u_char text_length /*:8*/; - u_char text[]; -} descr_data_broadcast_end_t; - -/* 0x65 ca_system_descriptor */ -typedef struct descr_ca_system { - u_char descriptor_tag /*:8*/; - u_char descriptor_length /*:8*/; - u_char data[]; /* struct item_ca_system */ -} descr_ca_system_t; -#define DESCR_CA_SYSTEM_LEN sizeof (descr_ca_system_t) -#define CastCaSystemDescriptor(x) ((descr_ca_system_t *)(x)) - -typedef struct item_ca_system { - u_char CA_system_id_hi /*:8*/; - u_char CA_system_id_lo /*:8*/; -} item_ca_system_t; - -/* 0x66 data_broadcast_id_descriptor */ -typedef struct descr_data_broadcast_id { - u_char descriptor_tag /*:8*/; - u_char descriptor_length /*:8*/; - u_char data_broadcast_id_hi /*:8*/; - u_char data_broadcast_id_lo /*:8*/; -} descr_data_broadcast_id_t; -#define DESCR_DATA_BROADCAST_ID_LEN sizeof (descr_data_broadcast_id_t) -#define CastDataBroadcastIdDescriptor(x) ((descr_data_broadcast_id_t *)(x)) - -/* 0x67 transport_stream_descriptor */ -typedef struct descr_transport_stream { - u_char descriptor_tag /*:8*/; - u_char descriptor_length /*:8*/; - /* TBD */ -} descr_transport_stream_t; -#define DESCR_TRANSPORT_STREAM_LEN sizeof (descr_transport_stream_t) -#define CastTransportStreamDescriptor(x) ((descr_transport_stream_t *)(x)) - -/* 0x68 dsng_descriptor */ -typedef struct descr_dsng { - u_char descriptor_tag /*:8*/; - u_char descriptor_length /*:8*/; - /* TBD */ -} descr_dsng_t; -#define DESCR_DSNG_LEN sizeof (descr_dsng_t) -#define CastDsngDescriptor(x) ((descr_dsng_t *)(x)) - -/* 0x69 programme_identificaion_label_descriptor */ -typedef struct descr_pdc { - u_char descriptor_tag /*:8*/; - u_char descriptor_length /*:8*/; -#if BYTE_ORDER == BIG_ENDIAN - u_char :4; - u_char day :5; - u_char month :4; - u_char hour :5; - u_char minute :6; -#else - u_char minute :6; - u_char hour :5; - u_char month :4; - u_char day :5; - u_char :4; -#endif -} descr_pdc_t; -#define DESCR_PDC_LEN sizeof (descr_pdc_t) -#define CastPdcDescriptor(x) ((descr_pdc_t *)(x)) - -/* 0x6A ac3_descriptor */ -typedef struct descr_ac3 { - u_char descriptor_tag /*:8*/; - u_char descriptor_length /*:8*/; -#if BYTE_ORDER == BIG_ENDIAN - u_char ac3_type_flag :1; - u_char bsid_flag :1; - u_char mainid_flag :1; - u_char asvc_flag :1; - u_char :4; -#else - u_char :4; - u_char asvc_flag :1; - u_char mainid_flag :1; - u_char bsid_flag :1; - u_char ac3_type_flag :1; -#endif - u_char ac3_type /*:8*/; - u_char bsid /*:8*/; - u_char mainid /*:8*/; - u_char asvc /*:8*/; -} descr_ac3_t; -#define DESCR_AC3_LEN sizeof (descr_ac3_t) -#define CastAc3Descriptor(x) ((descr_ac3_t *)(x)) - -/* 0x6B ancillary_data_descriptor */ -typedef struct descr_ancillary_data { - u_char descriptor_tag /*:8*/; - u_char descriptor_length /*:8*/; - u_char ancillary_data_identifier /*:8*/; -} descr_ancillary_data_t; -#define DESCR_ANCILLARY_DATA_LEN sizeof (descr_ancillary_data_t) -#define CastAncillaryDataDescriptor(x) ((descr_ancillary_data_t *)(x)) - -/* 0x6C cell_list_descriptor */ -typedef struct descr_cell_list { - u_char descriptor_tag /*:8*/; - u_char descriptor_length /*:8*/; - /* TBD */ -} descr_cell_list_t; -#define DESCR_CELL_LIST_LEN sizeof (descr_cell_list_t) -#define CastCellListDescriptor(x) ((descr_cell_list_t *)(x)) - -/* 0x6D cell_frequency_link_descriptor */ -typedef struct descr_cell_frequency_link { - u_char descriptor_tag /*:8*/; - u_char descriptor_length /*:8*/; - /* TBD */ -} descr_cell_frequency_link_t; -#define DESCR_CELL_FREQUENCY_LINK_LEN sizeof (descr_cell_frequency_link_t) -#define CastCellFrequencyLinkDescriptor(x) ((descr_cell_frequency_link_t *)(x)) - -/* 0x6E announcement_support_descriptor */ -typedef struct descr_announcement_support { - u_char descriptor_tag /*:8*/; - u_char descriptor_length /*:8*/; - /* TBD */ -} descr_announcement_support_t; -#define DESCR_ANNOUNCEMENT_SUPPORT_LEN sizeof (descr_announcement_support_t) -#define CastAnnouncementSupportDescriptor(x) ((descr_announcement_support_t *)(x)) - -/* 0x76 content_identifier_descriptor */ -typedef struct descr_content_identifier { - u_char descriptor_tag /*:8*/; - u_char descriptor_length /*:8*/; - u_char data[]; -} descr_content_identifier_t; - -typedef struct descr_content_identifier_crid { -#if BYTE_ORDER == BIG_ENDIAN - u_char crid_type :6; - u_char crid_location :2; -#else - u_char crid_location :2; - u_char crid_type :6; -#endif - u_char crid_ref_data[]; -} descr_content_identifier_crid_t; - -typedef struct descr_content_identifier_crid_local { - u_char crid_length /*:8*/; - u_char crid_byte[]; -} descr_content_identifier_crid_local_t; - - -/* 0x80 custom_category_descriptor TODO */ -typedef struct descr_custom_category { - u_char descriptor_tag /*:8*/; - u_char descriptor_length /*:8*/; - u_char dummy /*:8*/; // 7F - u_char data_length /*:8*/; - u_char data[]; /* struct custom_category_item(1|2) */ -} descr_custom_category_t; -struct custom_category_item1 { - u_char dummy /*:8*/; // 10 40 -}; -struct custom_category_item2 { - u_char length /*:8*/; - u_char data[]; /* struct custom_category_item3 */ -}; -struct custom_category_item3 { - u_char dummy0 /*:8*/; // FF -#if BYTE_ORDER == BIG_ENDIAN - u_char content_nibble_level_1 :4; - u_char content_nibble_level_2 :4; - u_char user_nibble_1 :4; - u_char user_nibble_2 :4; -#else - u_char user_nibble_2 :4; - u_char user_nibble_1 :4; - u_char content_nibble_level_2 :4; - u_char content_nibble_level_1 :4; -#endif - u_char dummy1[2] /*:8*/; // CF E2 | D4 48 - u_char text_length /*:8*/; - u_char text[]; -}; - -/* 0x81 xxx_descriptor TODO */ -typedef struct descr_xxx { - u_char descriptor_tag /*:8*/; - u_char descriptor_length /*:8*/; - u_char dummy /*:8 FF*/; -} descr_xxx_t; -#define DESCR_XXX_LEN sizeof (descr_xxx_t) -#define CastXxxDescriptor(x) ((descr_xxx_t *)(x)) - -/* 0x82 vps_descriptor TODO */ -typedef struct descr_vps { - u_char descriptor_tag /*:8*/; - u_char descriptor_length /*:8*/; - u_char hour[2] /*:8*/; - u_char delimiter_time /*:8 ':'*/; - u_char minute[2] /*:8*/; - u_char day[2] /*:8*/; - u_char delimiter_date /*:8 '.'*/; - u_char month[2] /*:8*/; - u_char delimiter /*:8 '#'*/; - u_char number[2] /*:8*/; -} descr_vps_t; -#define DESCR_VPS_LEN sizeof (descr_vps_t) -#define CastVpsDescriptor(x) ((descr_vps_t *)(x)) |