diff options
author | randomdan <randomdan@localhost> | 2011-03-18 17:35:29 +0000 |
---|---|---|
committer | randomdan <randomdan@localhost> | 2011-03-18 17:35:29 +0000 |
commit | 6c46db92549568b9167f4e72c6d22eceff0d2c6c (patch) | |
tree | dbaf309307c664f1a9819b1c526bf6fd159b66f9 | |
parent | Second round of tweaks, fixes and XMLTV stripping (diff) | |
download | p2pvr-6c46db92549568b9167f4e72c6d22eceff0d2c6c.tar.bz2 p2pvr-6c46db92549568b9167f4e72c6d22eceff0d2c6c.tar.xz p2pvr-6c46db92549568b9167f4e72c6d22eceff0d2c6c.zip |
Split into DVB SI Base reader for any SI table type
And EIT row source based on SI tables
Use Boost CRC32 for checksums
Bin more spare stuff
-rw-r--r-- | p2pvr/scanner/Jamfile.jam | 7 | ||||
-rw-r--r-- | p2pvr/scanner/crc32.cpp | 61 | ||||
-rw-r--r-- | p2pvr/scanner/dvbSiReaderHelper.cpp | 130 | ||||
-rw-r--r-- | p2pvr/scanner/dvbSiReaderHelper.h | 34 | ||||
-rw-r--r-- | p2pvr/scanner/dvb_info_tables.c | 284 | ||||
-rw-r--r-- | p2pvr/scanner/eitRows.cpp (renamed from p2pvr/scanner/p2scan.cpp) | 296 | ||||
-rw-r--r-- | p2pvr/scanner/eitRows.h | 42 | ||||
-rw-r--r-- | p2pvr/scanner/lookup.cpp | 52 | ||||
-rw-r--r-- | p2pvr/scanner/tv_grab_dvb.h | 32 |
9 files changed, 282 insertions, 656 deletions
diff --git a/p2pvr/scanner/Jamfile.jam b/p2pvr/scanner/Jamfile.jam index d784eeb..7288b23 100644 --- a/p2pvr/scanner/Jamfile.jam +++ b/p2pvr/scanner/Jamfile.jam @@ -3,14 +3,11 @@ project <variant>debug:<linkflags>-Wl,-z,defs <cflags>"-W -Wall -Werror -Wwrite-strings" ; -# Scanner base - the common part lifted from tv_grab_dvb -lib p2pvr-scan-base : crc32.cpp dvb_info_tables.c lookup.cpp ; - # Scanner - the common part implementing the ICE interface -lib p2pvr-scan-ice : icescan.cpp scanner.ice : <library>p2pvr-scan-base ; +lib p2pvr-scan-ice : icescan.cpp scanner.ice : <library>p2pvr-scan-p2 ; # Scanner - t -lib p2pvr-scan-p2 : p2scan.cpp : <library>p2pvr-scan-base <library>../../project2//p2common ; +lib p2pvr-scan-p2 : eitRows.cpp dvbSiReaderHelper.cpp : <library>../../project2//p2common ; # ScannerICE - the ICE test app #exe scanice : ice_scan.cpp : <library>p2pvr-scan ; diff --git a/p2pvr/scanner/crc32.cpp b/p2pvr/scanner/crc32.cpp deleted file mode 100644 index 3dec763..0000000 --- a/p2pvr/scanner/crc32.cpp +++ /dev/null @@ -1,61 +0,0 @@ -/* crc32.c: CRC32 routine - */ -#include <stdio.h> -#include <stdint.h> - -static const uint32_t crc_table[256] = { - 0x00000000, 0x04c11db7, 0x09823b6e, 0x0d4326d9, 0x130476dc, 0x17c56b6b, - 0x1a864db2, 0x1e475005, 0x2608edb8, 0x22c9f00f, 0x2f8ad6d6, 0x2b4bcb61, - 0x350c9b64, 0x31cd86d3, 0x3c8ea00a, 0x384fbdbd, 0x4c11db70, 0x48d0c6c7, - 0x4593e01e, 0x4152fda9, 0x5f15adac, 0x5bd4b01b, 0x569796c2, 0x52568b75, - 0x6a1936c8, 0x6ed82b7f, 0x639b0da6, 0x675a1011, 0x791d4014, 0x7ddc5da3, - 0x709f7b7a, 0x745e66cd, 0x9823b6e0, 0x9ce2ab57, 0x91a18d8e, 0x95609039, - 0x8b27c03c, 0x8fe6dd8b, 0x82a5fb52, 0x8664e6e5, 0xbe2b5b58, 0xbaea46ef, - 0xb7a96036, 0xb3687d81, 0xad2f2d84, 0xa9ee3033, 0xa4ad16ea, 0xa06c0b5d, - 0xd4326d90, 0xd0f37027, 0xddb056fe, 0xd9714b49, 0xc7361b4c, 0xc3f706fb, - 0xceb42022, 0xca753d95, 0xf23a8028, 0xf6fb9d9f, 0xfbb8bb46, 0xff79a6f1, - 0xe13ef6f4, 0xe5ffeb43, 0xe8bccd9a, 0xec7dd02d, 0x34867077, 0x30476dc0, - 0x3d044b19, 0x39c556ae, 0x278206ab, 0x23431b1c, 0x2e003dc5, 0x2ac12072, - 0x128e9dcf, 0x164f8078, 0x1b0ca6a1, 0x1fcdbb16, 0x018aeb13, 0x054bf6a4, - 0x0808d07d, 0x0cc9cdca, 0x7897ab07, 0x7c56b6b0, 0x71159069, 0x75d48dde, - 0x6b93dddb, 0x6f52c06c, 0x6211e6b5, 0x66d0fb02, 0x5e9f46bf, 0x5a5e5b08, - 0x571d7dd1, 0x53dc6066, 0x4d9b3063, 0x495a2dd4, 0x44190b0d, 0x40d816ba, - 0xaca5c697, 0xa864db20, 0xa527fdf9, 0xa1e6e04e, 0xbfa1b04b, 0xbb60adfc, - 0xb6238b25, 0xb2e29692, 0x8aad2b2f, 0x8e6c3698, 0x832f1041, 0x87ee0df6, - 0x99a95df3, 0x9d684044, 0x902b669d, 0x94ea7b2a, 0xe0b41de7, 0xe4750050, - 0xe9362689, 0xedf73b3e, 0xf3b06b3b, 0xf771768c, 0xfa325055, 0xfef34de2, - 0xc6bcf05f, 0xc27dede8, 0xcf3ecb31, 0xcbffd686, 0xd5b88683, 0xd1799b34, - 0xdc3abded, 0xd8fba05a, 0x690ce0ee, 0x6dcdfd59, 0x608edb80, 0x644fc637, - 0x7a089632, 0x7ec98b85, 0x738aad5c, 0x774bb0eb, 0x4f040d56, 0x4bc510e1, - 0x46863638, 0x42472b8f, 0x5c007b8a, 0x58c1663d, 0x558240e4, 0x51435d53, - 0x251d3b9e, 0x21dc2629, 0x2c9f00f0, 0x285e1d47, 0x36194d42, 0x32d850f5, - 0x3f9b762c, 0x3b5a6b9b, 0x0315d626, 0x07d4cb91, 0x0a97ed48, 0x0e56f0ff, - 0x1011a0fa, 0x14d0bd4d, 0x19939b94, 0x1d528623, 0xf12f560e, 0xf5ee4bb9, - 0xf8ad6d60, 0xfc6c70d7, 0xe22b20d2, 0xe6ea3d65, 0xeba91bbc, 0xef68060b, - 0xd727bbb6, 0xd3e6a601, 0xdea580d8, 0xda649d6f, 0xc423cd6a, 0xc0e2d0dd, - 0xcda1f604, 0xc960ebb3, 0xbd3e8d7e, 0xb9ff90c9, 0xb4bcb610, 0xb07daba7, - 0xae3afba2, 0xaafbe615, 0xa7b8c0cc, 0xa379dd7b, 0x9b3660c6, 0x9ff77d71, - 0x92b45ba8, 0x9675461f, 0x8832161a, 0x8cf30bad, 0x81b02d74, 0x857130c3, - 0x5d8a9099, 0x594b8d2e, 0x5408abf7, 0x50c9b640, 0x4e8ee645, 0x4a4ffbf2, - 0x470cdd2b, 0x43cdc09c, 0x7b827d21, 0x7f436096, 0x7200464f, 0x76c15bf8, - 0x68860bfd, 0x6c47164a, 0x61043093, 0x65c52d24, 0x119b4be9, 0x155a565e, - 0x18197087, 0x1cd86d30, 0x029f3d35, 0x065e2082, 0x0b1d065b, 0x0fdc1bec, - 0x3793a651, 0x3352bbe6, 0x3e119d3f, 0x3ad08088, 0x2497d08d, 0x2056cd3a, - 0x2d15ebe3, 0x29d4f654, 0xc5a92679, 0xc1683bce, 0xcc2b1d17, 0xc8ea00a0, - 0xd6ad50a5, 0xd26c4d12, 0xdf2f6bcb, 0xdbee767c, 0xe3a1cbc1, 0xe760d676, - 0xea23f0af, 0xeee2ed18, 0xf0a5bd1d, 0xf464a0aa, 0xf9278673, 0xfde69bc4, - 0x89b8fd09, 0x8d79e0be, 0x803ac667, 0x84fbdbd0, 0x9abc8bd5, 0x9e7d9662, - 0x933eb0bb, 0x97ffad0c, 0xafb010b1, 0xab710d06, 0xa6322bdf, 0xa2f33668, - 0xbcb4666d, 0xb8757bda, 0xb5365d03, 0xb1f740b4 -}; - -uint32_t _dvb_crc32(const uint8_t *data, size_t len) -{ - size_t i; - uint32_t crc = 0xffffffff; - - for (i = 0; i < len; i++) - crc = (crc << 8) ^ crc_table[((crc >> 24) ^ *data++) & 0xff]; - - return crc; -} diff --git a/p2pvr/scanner/dvbSiReaderHelper.cpp b/p2pvr/scanner/dvbSiReaderHelper.cpp new file mode 100644 index 0000000..015a60c --- /dev/null +++ b/p2pvr/scanner/dvbSiReaderHelper.cpp @@ -0,0 +1,130 @@ +#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 DvbSiReaderHelper::ISO10646("ISO-10646"); +const std::string DvbSiReaderHelper::EitEncoding("ISO6937"); +const std::string DvbSiReaderHelper::UTF8("UTF8"); + +DvbSiReaderHelper::DvbSiReaderHelper(const xmlpp::Element * p) : + demux(p, "demux", false, "/dev/dvb/adapter0/demux0"), + timeout(p, "timeout", false, 10000), + fd_epg(0) +{ +} + +DvbSiReaderHelper::~DvbSiReaderHelper() +{ + closeInput(); +} + +void +DvbSiReaderHelper::openInput() const +{ + if ((fd_epg = open(demux(), O_RDWR)) < 0) { + throw DemuxOpenFailure(strerror(errno)); + } + filterInput(fd_epg); +} + +void +DvbSiReaderHelper::closeInput() const +{ + if (fd_epg) { + close(fd_epg); + fd_epg = 0; + } +} + +VariableType +DvbSiReaderHelper::convert(const char * txt, size_t len) +{ + 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 RowProcessor * rp) 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())) == 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 (parseSIT(buf, l, rp)) { + time(&lastuseful); + } + else { + if (lastuseful < time(NULL) - 5) { + break; + } + } + } + } + if (prtn < 1) { + throw TimeoutReadingData("Tuned to a multiplex?"); + } +} diff --git a/p2pvr/scanner/dvbSiReaderHelper.h b/p2pvr/scanner/dvbSiReaderHelper.h new file mode 100644 index 0000000..325bc66 --- /dev/null +++ b/p2pvr/scanner/dvbSiReaderHelper.h @@ -0,0 +1,34 @@ +#ifndef DVBSIREADERHELPER_H +#define DVBSIREADERHELPER_H + +#include "xmlObjectLoader.h" +#include "variables.h" + +class RowProcessor; + +class DvbSiReaderHelper { + public: + DvbSiReaderHelper(const xmlpp::Element * p); + ~DvbSiReaderHelper(); + + const Variable demux; + const Variable timeout; + + protected: + void openInput() const; + virtual void filterInput(int fd) const = 0; + void readTables(const RowProcessor *) const; + virtual bool parseSIT(const u_char *data, size_t len, const RowProcessor *) const = 0; + void closeInput() const; + + static VariableType convert(const char * txt, size_t len); + static const std::string ISO10646; + static const std::string EitEncoding; + static const std::string UTF8; + + private: + mutable int fd_epg; +}; + +#endif + diff --git a/p2pvr/scanner/dvb_info_tables.c b/p2pvr/scanner/dvb_info_tables.c deleted file mode 100644 index 10a687a..0000000 --- a/p2pvr/scanner/dvb_info_tables.c +++ /dev/null @@ -1,284 +0,0 @@ -/* - * tv_grab_dvb - (c) Mark Bryars 2004 - * God bless vim and macros, this would have taken forever to format otherwise. - */ -#include "tv_grab_dvb.h" - -const struct lookup_table description_table[] = { - { {0x00}, "\0UNDEFINED CONTENT"}, - { {0x01}, "\0UNDEFINED CONTENT"}, - { {0x02}, "\0UNDEFINED CONTENT"}, - { {0x03}, "\0UNDEFINED CONTENT"}, - { {0x04}, "\0UNDEFINED CONTENT"}, - { {0x05}, "\0UNDEFINED CONTENT"}, - { {0x06}, "\0UNDEFINED CONTENT"}, - { {0x07}, "\0UNDEFINED CONTENT"}, - { {0x08}, "\0UNDEFINED CONTENT"}, - { {0x09}, "\0UNDEFINED CONTENT"}, - { {0x0A}, "\0UNDEFINED CONTENT"}, - { {0x0B}, "\0UNDEFINED CONTENT"}, - { {0x0C}, "\0UNDEFINED CONTENT"}, - { {0x0D}, "\0UNDEFINED CONTENT"}, - { {0x0E}, "\0UNDEFINED CONTENT"}, - { {0x0F}, "\0UNDEFINED CONTENT"}, - - { {0x10}, "Movie / Drama" }, - { {0x11}, "Movie - detective/thriller" }, - { {0x12}, "Movie - adventure/western/war" }, - { {0x13}, "Movie - science fiction/fantasy/horror" }, - { {0x14}, "Movie - comedy" }, - { {0x15}, "Movie - soap/melodrama/folkloric" }, - { {0x16}, "Movie - romance" }, - { {0x17}, "Movie - serious/classical/religious/historical movie/drama" }, - { {0x18}, "Movie - adult movie/drama" }, - { {0x19}, "\0Movie - RESERVED" }, - { {0x1A}, "\0Movie - RESERVED" }, - { {0x1B}, "\0Movie - RESERVED" }, - { {0x1C}, "\0Movie - RESERVED" }, - { {0x1D}, "\0Movie - RESERVED" }, - { {0x1E}, "\0Movie - RESERVED" }, - { {0x1F}, NULL }, - - { {0x20}, "News / Current Affairs" }, - { {0x21}, "New - news/weather report" }, - { {0x22}, "New - news magazine" }, - { {0x23}, "New - documentary" }, - { {0x24}, "New - discussion/interview/debate" }, - { {0x25}, "\0News - RESERVED" }, - { {0x26}, "\0News - RESERVED" }, - { {0x27}, "\0News - RESERVED" }, - { {0x28}, "\0News - RESERVED" }, - { {0x29}, "\0News - RESERVED" }, - { {0x2A}, "\0News - RESERVED" }, - { {0x2B}, "\0News - RESERVED" }, - { {0x2C}, "\0News - RESERVED" }, - { {0x2D}, "\0News - RESERVED" }, - { {0x2E}, "\0News - RESERVED" }, - { {0x2E}, NULL }, - - { {0x30}, "Show / Game Show" }, - { {0x31}, "Show - game show/quiz/contest" }, - { {0x32}, "Show - variety show" }, - { {0x33}, "Show - talk show" }, - { {0x34}, "\0Show - RESERVED" }, - { {0x35}, "\0Show - RESERVED" }, - { {0x36}, "\0Show - RESERVED" }, - { {0x37}, "\0Show - RESERVED" }, - { {0x38}, "\0Show - RESERVED" }, - { {0x39}, "\0Show - RESERVED" }, - { {0x3A}, "\0Show - RESERVED" }, - { {0x3B}, "\0Show - RESERVED" }, - { {0x3C}, "\0Show - RESERVED" }, - { {0x3D}, "\0Show - RESERVED" }, - { {0x3E}, "\0Show - RESERVED" }, - { {0x3F}, NULL }, - - { {0x40}, "Sports" }, - { {0x41}, "Sports - special events (Olympic Games, World Cup etc.)" }, - { {0x42}, "Sports - sports magazines" }, - { {0x43}, "Sports - football/soccer" }, - { {0x44}, "Sports - tennis/squash" }, - { {0x45}, "Sports - team sports (excluding football)" }, - { {0x46}, "Sports - athletics" }, - { {0x47}, "Sports - motor sport" }, - { {0x48}, "Sports - water sport" }, - { {0x49}, "Sports - winter sports" }, - { {0x4A}, "Sports - equestrian" }, - { {0x4B}, "Sports - martial sports" }, - { {0x4C}, "\0Sports - RESERVED" }, - { {0x4D}, "\0Sports - RESERVED" }, - { {0x4E}, "\0Sports - RESERVED" }, - { {0x4F}, NULL }, - - { {0x50}, "Childrens / Youth" }, - { {0x51}, "Children - pre-school children's programmes" }, - { {0x52}, "Children - entertainment programmes for 6 to 14" }, - { {0x53}, "Children - entertainment programmes for 10 to 16" }, - { {0x54}, "Children - informational/educational/school programmes" }, - { {0x55}, "Children - cartoons/puppets" }, - { {0x56}, "\0Children - RESERVED" }, - { {0x57}, "\0Children - RESERVED" }, - { {0x58}, "\0Children - RESERVED" }, - { {0x59}, "\0Children - RESERVED" }, - { {0x5A}, "\0Children - RESERVED" }, - { {0x5B}, "\0Children - RESERVED" }, - { {0x5C}, "\0Children - RESERVED" }, - { {0x5D}, "\0Children - RESERVED" }, - { {0x5E}, "\0Children - RESERVED" }, - { {0x5F}, NULL }, - - { {0x60}, "Music / Ballet / Dance" }, - { {0x61}, "Music - rock/pop" }, - { {0x62}, "Music - serious music/classical music" }, - { {0x63}, "Music - folk/traditional music" }, - { {0x64}, "Music - jazz" }, - { {0x65}, "Music - musical/opera" }, - { {0x66}, "Music - ballet" }, - { {0x67}, "\0Music - RESERVED" }, - { {0x68}, "\0Music - RESERVED" }, - { {0x69}, "\0Music - RESERVED" }, - { {0x6A}, "\0Music - RESERVED" }, - { {0x6B}, "\0Music - RESERVED" }, - { {0x6C}, "\0Music - RESERVED" }, - { {0x6D}, "\0Music - RESERVED" }, - { {0x6E}, "\0Music - RESERVED" }, - { {0x6F}, NULL }, - - { {0x70}, "Arts / Culture" }, - { {0x71}, "Arts - performing arts" }, - { {0x72}, "Arts - fine arts" }, - { {0x73}, "Arts - religion" }, - { {0x74}, "Arts - popular culture/traditional arts" }, - { {0x75}, "Arts - literature" }, - { {0x76}, "Arts - film/cinema" }, - { {0x77}, "Arts - experimental film/video" }, - { {0x78}, "Arts - broadcasting/press" }, - { {0x79}, "Arts - new media" }, - { {0x7A}, "Arts - arts/culture magazines" }, - { {0x7B}, "Arts - fashion" }, - { {0x7C}, "\0Arts - RESERVED" }, - { {0x7D}, "\0Arts - RESERVED" }, - { {0x7E}, "\0Arts - RESERVED" }, - { {0x7F}, NULL }, - - { {0x80}, "Social / Policical / Economics" }, - { {0x81}, "Social - magazines/reports/documentary" }, - { {0x82}, "Social - economics/social advisory" }, - { {0x83}, "Social - remarkable people" }, - { {0x84}, "\0Social - RESERVED" }, - { {0x85}, "\0Social - RESERVED" }, - { {0x86}, "\0Social - RESERVED" }, - { {0x87}, "\0Social - RESERVED" }, - { {0x88}, "\0Social - RESERVED" }, - { {0x89}, "\0Social - RESERVED" }, - { {0x8A}, "\0Social - RESERVED" }, - { {0x8b}, "\0Social - RESERVED" }, - { {0x8C}, "\0Social - RESERVED" }, - { {0x8D}, "\0Social - RESERVED" }, - { {0x8E}, "\0Social - RESERVED" }, - { {0x8F}, NULL }, - - { {0x90}, "Education / Science / Factual" }, - { {0x91}, "Education - nature/animals/environment" }, - { {0x92}, "Education - technology/natural sciences" }, - { {0x93}, "Education - medicine/physiology/psychology" }, - { {0x94}, "Education - foreign countries/expeditions" }, - { {0x95}, "Education - social/spiritual sciences" }, - { {0x96}, "Education - further education" }, - { {0x97}, "Education - languages" }, - { {0x98}, "\0Education - RESERVED" }, - { {0x99}, "\0Education - RESERVED" }, - { {0x9A}, "\0Education - RESERVED" }, - { {0x9B}, "\0Education - RESERVED" }, - { {0x9C}, "\0Education - RESERVED" }, - { {0x9D}, "\0Education - RESERVED" }, - { {0x9E}, "\0Education - RESERVED" }, - { {0x9F}, NULL }, - - { {0xA0}, "Leisure / Hobbies" }, - { {0xA1}, "Leisure - tourism/travel" }, - { {0xA2}, "Leisure - handicraft" }, - { {0xA3}, "Leisure - motoring" }, - { {0xA4}, "Leisure - fitness & health" }, - { {0xA5}, "Leisure - cooking" }, - { {0xA6}, "Leisure - advertizement/shopping" }, - { {0xA7}, "Leisure - gardening" }, - { {0xA8}, "\0Leisure - RESERVED" }, - { {0xA9}, "\0Leisure - RESERVED" }, - { {0xAA}, "\0Leisure - RESERVED" }, - { {0xAB}, "\0Leisure - RESERVED" }, - { {0xAC}, "\0Leisure - RESERVED" }, - { {0xAD}, "\0Leisure - RESERVED" }, - { {0xAE}, "\0Leisure - RESERVED" }, - { {0xAF}, NULL }, - - // Special - { {0xB0}, "Original Language" }, - { {0xB1}, "black & white" }, - { {0xB2}, "unpublished" }, - { {0xB3}, "live broadcast" }, - { {0xB4}, "\0Characteristics - RESERVED" }, - { {0xB5}, "\0Characteristics - RESERVED" }, - { {0xB6}, "\0Characteristics - RESERVED" }, - { {0xB7}, "\0Characteristics - RESERVED" }, - { {0xB8}, "\0Characteristics - RESERVED" }, - { {0xB9}, "\0Characteristics - RESERVED" }, - { {0xBA}, "\0Characteristics - RESERVED" }, - { {0xBB}, "\0Characteristics - RESERVED" }, - { {0xBC}, "\0Characteristics - RESERVED" }, - { {0xBD}, "\0Characteristics - RESERVED" }, - { {0xBE}, "\0Characteristics - RESERVED" }, - { {0xBF}, NULL }, - - { {0xC0}, "\0RESERVED" }, - { {0xC1}, "\0RESERVED" }, - { {0xC2}, "\0RESERVED" }, - { {0xC3}, "\0RESERVED" }, - { {0xC4}, "\0RESERVED" }, - { {0xC5}, "\0RESERVED" }, - { {0xC6}, "\0RESERVED" }, - { {0xC7}, "\0RESERVED" }, - { {0xC8}, "\0RESERVED" }, - { {0xC9}, "\0RESERVED" }, - { {0xCA}, "\0RESERVED" }, - { {0xCB}, "\0RESERVED" }, - { {0xCC}, "\0RESERVED" }, - { {0xCD}, "\0RESERVED" }, - { {0xCE}, "\0RESERVED" }, - { {0xCF}, "\0RESERVED" }, - - { {0xD0}, "\0RESERVED" }, - { {0xD1}, "\0RESERVED" }, - { {0xD2}, "\0RESERVED" }, - { {0xD3}, "\0RESERVED" }, - { {0xD4}, "\0RESERVED" }, - { {0xD5}, "\0RESERVED" }, - { {0xD6}, "\0RESERVED" }, - { {0xD7}, "\0RESERVED" }, - { {0xD8}, "\0RESERVED" }, - { {0xD9}, "\0RESERVED" }, - { {0xDA}, "\0RESERVED" }, - { {0xDB}, "\0RESERVED" }, - { {0xDC}, "\0RESERVED" }, - { {0xDD}, "\0RESERVED" }, - { {0xDE}, "\0RESERVED" }, - { {0xDF}, "\0RESERVED" }, - - { {0xE0}, "\0RESERVED" }, - { {0xE1}, "\0RESERVED" }, - { {0xE2}, "\0RESERVED" }, - { {0xE3}, "\0RESERVED" }, - { {0xE4}, "\0RESERVED" }, - { {0xE5}, "\0RESERVED" }, - { {0xE6}, "\0RESERVED" }, - { {0xE7}, "\0RESERVED" }, - { {0xE8}, "\0RESERVED" }, - { {0xE9}, "\0RESERVED" }, - { {0xEA}, "\0RESERVED" }, - { {0xEB}, "\0RESERVED" }, - { {0xEC}, "\0RESERVED" }, - { {0xED}, "\0RESERVED" }, - { {0xEE}, "\0RESERVED" }, - { {0xEF}, "\0RESERVED" }, - - // UK Freeview custom id - { {0xF0}, "Drama" }, - { {0xF1}, NULL }, - { {0xF2}, NULL }, - { {0xF3}, NULL }, - { {0xF4}, NULL }, - { {0xF5}, NULL }, - { {0xF6}, NULL }, - { {0xF7}, NULL }, - { {0xF8}, NULL }, - { {0xF9}, NULL }, - { {0xFA}, NULL }, - { {0xFB}, NULL }, - { {0xFC}, NULL }, - { {0xFD}, NULL }, - { {0xFE}, NULL }, - { {0xFF}, NULL }, - - { {-1}, NULL } -}; - diff --git a/p2pvr/scanner/p2scan.cpp b/p2pvr/scanner/eitRows.cpp index 8fe3578..aea639f 100644 --- a/p2pvr/scanner/p2scan.cpp +++ b/p2pvr/scanner/eitRows.cpp @@ -27,29 +27,18 @@ #include <stdlib.h> #include <unistd.h> #include <string.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <fcntl.h> #include <sys/ioctl.h> -#include <sys/poll.h> #include <errno.h> -#include <getopt.h> -#include <stdarg.h> #include <stdint.h> -#include <signal.h> #include <time.h> -#include <stdbool.h> -#include <assert.h> -#include <glibmm.h> #include <boost/bind.hpp> #include <boost/date_time/gregorian_calendar.hpp> #include <linux/dvb/dmx.h> #include "si_tables.h" -#include "tv_grab_dvb.h" -#include "variables.h" #include "rowProcessor.h" +#include "eitRows.h" struct EitProgram { VariableType serviceID; @@ -77,195 +66,99 @@ struct EitProgram { }; Glib::ustring title("title"); -#include "xmlObjectLoader.h" -#include "rowSet.h" template <class C, class M> const M & getMember(M C::*t, C * p) { return p->*t; } SimpleMessageException(NoSuchAttribute); -class EitRows : public RowSet { - public: - EitRows(const xmlpp::Element * p); - ~EitRows(); - void execute(const RowProcessor *) const; - void loadComplete(const CommonObjects *) { - } - void setFilter(const Glib::ustring &) { - } - unsigned int columnCount() const { - return 1; - } - const Glib::ustring & getColumnName(unsigned int) const { - return title; - } - VariableType getCurrentValue(const Glib::ustring &) const { - return current->title; - } - VariableType getCurrentValue(unsigned int) const { - return current->title; - } - bool isNull(unsigned int ) const { - return false; - } - bool isNull(const Glib::ustring & ) const { - return false; - } + +void +EitRows::loadComplete(const CommonObjects *) +{ +} + +void +EitRows::setFilter(const Glib::ustring &) +{ +} + +unsigned int +EitRows::columnCount() const +{ + return 1; +} + +const Glib::ustring & +EitRows::getColumnName(unsigned int) const { + return title; +} + +VariableType +EitRows::getCurrentValue(const Glib::ustring &) const { + return current->title; +} + +VariableType +EitRows::getCurrentValue(unsigned int) const { + return current->title; +} + +bool +EitRows::isNull(unsigned int ) const { + return false; +} + +bool +EitRows::isNull(const Glib::ustring & ) const { + return false; +} + #define returnAttr(name) if (attrName == #name) return boost::bind(getMember<EitProgram, VariableType>, &EitProgram::name, boost::ref(current)) - RowAttribute 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); - throw NoSuchAttribute(attrName); - } - private: - Variable demux; - Variable timeout; - void openInput() const; - void closeInput() const; - void readEventTables(const RowProcessor *) const; - bool parseEIT(const u_char *data, size_t len, const RowProcessor *) const; - void parseEventDescription(const u_char *data) const; - void parseLongEventDescription(const u_char *data) const; - void parseComponentDescription(const u_char *data) const; - void parseContentDescription(const u_char *data) const; - void parseRatingDescription(const u_char *data) const; - void parseContentIdentifierDescription(const u_char *data) const; - void parseDescription(const u_char * data, size_t len) const; - - VariableType convert(const char * txt, size_t len) const; - - mutable int fd_epg; - mutable EitProgram * current; - - static const std::string ISO10646; - static const std::string EitEncoding; - static const std::string UTF8; -}; +RowSet::RowAttribute +EitRows::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); + throw NoSuchAttribute(attrName); +} DECLARE_LOADER("eitrows", EitRows); -const std::string EitRows::ISO10646("ISO-10646"); -const std::string EitRows::EitEncoding("ISO6937"); -const std::string EitRows::UTF8("UTF8"); - EitRows::EitRows(const xmlpp::Element * p) : RowSet(p), - demux(p, "demux", false, "/dev/dvb/adapter0/demux0"), - timeout(p, "timeout", false, 10000), - fd_epg(0), + DvbSiReaderHelper(p), current(NULL) { } EitRows::~EitRows() { - closeInput(); -} -void -EitRows::closeInput() const -{ - if (fd_epg) { - close(fd_epg); - fd_epg = 0; - } } static int time_offset = 0; static int chan_filter = 0; static int chan_filter_mask = 0; -/* Parse command line arguments. {{{ */ -int do_options(int arg_count, char **arg_strings) { - static const struct option Long_Options[] = { - {"help", 0, 0, 'h'}, - {"chanidents", 1, 0, 'c'}, - {0, 0, 0, 0} - }; - int Option_Index = 0; - - while (1) { - int c = getopt_long(arg_count, arg_strings, "udscmpnht:o:f:i:e:", Long_Options, &Option_Index); - switch (c) { - case 'n': - chan_filter = 0x4e; - chan_filter_mask = 0xfe; - break; - case 'm': - chan_filter = 0x4e; - chan_filter_mask = 0xff; - break; - case 'p': - chan_filter = 0x4f; - chan_filter_mask = 0xff; - break; - } - } - return 0; -} /*}}}*/ - - -VariableType -EitRows::convert(const char * txt, size_t len) const -{ - 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())); -} - void EitRows::parseEventDescription(const u_char *data) const { assert(GetDescriptorTag(data) == 0x4D); @@ -521,7 +414,7 @@ SeenProgram::operator<(const SeenProgram & o) const typedef std::set<SeenProgram> SeenPrograms; SeenPrograms seenPrograms; bool -EitRows::parseEIT(const u_char *data, size_t len, const RowProcessor * rp) const { +EitRows::parseSIT(const u_char *data, size_t len, const RowProcessor * rp) const { const struct eit *e = reinterpret_cast<const struct eit *>(data); len -= 4; //remove CRC @@ -572,52 +465,11 @@ EitRows::parseEIT(const u_char *data, size_t len, const RowProcessor * rp) const return found; } -SimpleMessageException(ErrorReadingData); -SimpleMessageException(TimeoutReadingData); -void -EitRows::readEventTables(const RowProcessor * rp) 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())) == 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) == 0) { - if (parseEIT(buf, l, rp)) { - time(&lastuseful); - } - else { - if (lastuseful < time(NULL) - 5) { - break; - } - } - } - } - if (prtn < 1) { - throw TimeoutReadingData("Tuned to a multiplex?"); - } -} - -SimpleMessageException(DemuxOpenFailure); SimpleMessageException(DemuxSetFilterFailure); void -EitRows::openInput() const +EitRows::filterInput(int fd) const { - if ((fd_epg = open(demux(), O_RDWR)) < 0) { - throw DemuxOpenFailure(strerror(errno)); - } - struct dmx_sct_filter_params sctFilterParams; memset(&sctFilterParams, 0, sizeof(dmx_sct_filter_params)); sctFilterParams.pid = 18; // EIT data @@ -626,7 +478,7 @@ EitRows::openInput() const sctFilterParams.filter.filter[0] = chan_filter; // 4e is now/next this multiplex, 4f others sctFilterParams.filter.mask[0] = chan_filter_mask; - if (ioctl(fd_epg, DMX_SET_FILTER, &sctFilterParams) < 0) { + if (ioctl(fd, DMX_SET_FILTER, &sctFilterParams) < 0) { throw DemuxSetFilterFailure(strerror(errno)); } } @@ -635,7 +487,7 @@ void EitRows::execute(const RowProcessor * rp) const { openInput(); - readEventTables(rp); + readTables(rp); closeInput(); } diff --git a/p2pvr/scanner/eitRows.h b/p2pvr/scanner/eitRows.h new file mode 100644 index 0000000..9078b53 --- /dev/null +++ b/p2pvr/scanner/eitRows.h @@ -0,0 +1,42 @@ +#ifndef P2SCAN_H +#define P2SCAN_H + +#include "xmlObjectLoader.h" +#include "rowSet.h" +#include "variables.h" +#include "dvbSiReaderHelper.h" + +class EitProgram; + +class EitRows : public RowSet, DvbSiReaderHelper { + public: + EitRows(const xmlpp::Element * p); + ~EitRows(); + + void execute(const RowProcessor *) const; + void loadComplete(const CommonObjects *); + void setFilter(const Glib::ustring &); + unsigned int columnCount() const; + const Glib::ustring & getColumnName(unsigned int) const; + VariableType getCurrentValue(const Glib::ustring &) const; + VariableType getCurrentValue(unsigned int) const; + bool isNull(unsigned int ) const; + bool isNull(const Glib::ustring & ) const; + RowAttribute resolveAttr(const Glib::ustring & attrName) const; + + private: + void filterInput(int fd) const; + bool parseSIT(const u_char *data, size_t len, const RowProcessor *) const; + void parseEventDescription(const u_char *data) const; + void parseLongEventDescription(const u_char *data) const; + void parseComponentDescription(const u_char *data) const; + void parseContentDescription(const u_char *data) const; + void parseRatingDescription(const u_char *data) const; + void parseContentIdentifierDescription(const u_char *data) const; + void parseDescription(const u_char * data, size_t len) const; + + mutable EitProgram * current; +}; + +#endif + diff --git a/p2pvr/scanner/lookup.cpp b/p2pvr/scanner/lookup.cpp deleted file mode 100644 index 6d2a0b6..0000000 --- a/p2pvr/scanner/lookup.cpp +++ /dev/null @@ -1,52 +0,0 @@ -#include <stdio.h> -#include <string.h> - -#include "tv_grab_dvb.h" - -const char *lookup(const struct lookup_table *l, int id) { -// printf("Looked up %x", id); - while ((l->u.i != id) && (l->u.i != -1)) - l++; - return l->desc; -} - -/* Read lookup_table from file into newly allocated table. - * The table is a single allocation consisting of two parts: - * first the array of structs, followed by a char-array of strings. */ -int load_lookup(struct lookup_table **l, const char *file) { - int name; - char value[256]; - int n = 1, size = sizeof(struct lookup_table); - - if (file == NULL) - return -1; - - FILE *fd = fopen(file, "r"); - if (!fd) - return -1; - - // 1st: determine size needed - while (fscanf(fd, "%d %255s", &name, value) == 2) { - n++; - size += sizeof(struct lookup_table); - size += strlen(value) + 1; - } - struct lookup_table *p = *l = static_cast<struct lookup_table *>(malloc(size)); - if (p == NULL) - return -1; - - // 2nd: read data - rewind(fd); - char *c = (char *)(p + n); - while (fscanf(fd, "%d %255s", &p->u.i, c) == 2) { - p->desc = c; - c += strlen(c) + 1; - p++; - } - p->u.i = -1; - p->desc = NULL; - - fclose(fd); - return 0; -} - diff --git a/p2pvr/scanner/tv_grab_dvb.h b/p2pvr/scanner/tv_grab_dvb.h deleted file mode 100644 index 460b7f6..0000000 --- a/p2pvr/scanner/tv_grab_dvb.h +++ /dev/null @@ -1,32 +0,0 @@ -#ifndef __tv_grab_dvd -#define __tv_grab_dvd - -#include <stdint.h> -#include <stdlib.h> - -/* lookup.c */ -union lookup_key { - int i; - char c[4]; -}; -struct lookup_table { - union lookup_key u; - const char *desc; -}; - -extern const char *lookup(const struct lookup_table *l, int id); -extern int load_lookup(struct lookup_table **l, const char *file); - -/* dvb_info_tables.c */ -extern const struct lookup_table description_table[]; -extern const struct lookup_table aspect_table[]; -extern const struct lookup_table audio_table[]; -extern const struct lookup_table crid_type_table[]; - -/* langidents.c */ -extern const struct lookup_table languageid_table[]; - -/* crc32.c */ -extern uint32_t _dvb_crc32(const uint8_t *data, size_t len); - -#endif |