diff --git a/CONTRIBUTORS b/CONTRIBUTORS index ea8f1547..629bdceb 100644 --- a/CONTRIBUTORS +++ b/CONTRIBUTORS @@ -1336,6 +1336,8 @@ Marco Schl for improving OSD area handling in cDvbSpuDecoder for suggesting to log the description (if present) in case a thread is canceled for fixing handling DPID when deciding whether to switch to 'Transfer Mode' + for adding VBITeletextDescriptorTag, TeletextDescriptorTag, LocalTimeOffsetDescriptorTag + and PremiereContentTransmissionDescriptor to 'libsi' Jürgen Schmitz for reporting a bug in displaying the current channel when switching via the SVDRP diff --git a/HISTORY b/HISTORY index 0fe2c5cd..9ff354c1 100644 --- a/HISTORY +++ b/HISTORY @@ -4513,3 +4513,5 @@ Video Disk Recorder Revision History - Fixed unnecessary Set() calls in cMenuEditIntItem::ProcessKey(). - Allowing a tolerance for symbol rate values that are off by one (thanks to Richard Lithvall). +- Added VBITeletextDescriptorTag, TeletextDescriptorTag, LocalTimeOffsetDescriptorTag + and PremiereContentTransmissionDescriptor to 'libsi' (thanks to Marco Schlüßler). diff --git a/libsi/descriptor.c b/libsi/descriptor.c index b84e2c44..dc3b71aa 100644 --- a/libsi/descriptor.c +++ b/libsi/descriptor.c @@ -6,7 +6,7 @@ * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * - * $Id: descriptor.c 1.18 2006/02/25 10:06:05 kls Exp $ + * $Id: descriptor.c 1.19 2006/04/14 10:53:44 kls Exp $ * * ***************************************************************************/ @@ -318,6 +318,31 @@ void ParentalRatingDescriptor::Rating::Parse() { languageCode[3]=0; } +void TeletextDescriptor::Parse() { + //this descriptor is only a header and a loop + teletextLoop.setData(data+sizeof(descr_teletext), getLength()-sizeof(descr_teletext)); +} + +void TeletextDescriptor::Teletext::Parse() { + s=data.getData(); + languageCode[0]=s->lang_code1; + languageCode[1]=s->lang_code2; + languageCode[2]=s->lang_code3; + languageCode[3]=0; +} + +int TeletextDescriptor::Teletext::getTeletextType() const { + return s->type; +} + +int TeletextDescriptor::Teletext::getTeletextMagazineNumber() const { + return s->magazine_number; +} + +int TeletextDescriptor::Teletext::getTeletextPageNumber() const { + return s->page_number; +} + int CaDescriptor::getCaType() const { return HILO(s->CA_type); } @@ -536,6 +561,14 @@ void ComponentDescriptor::Parse() { description.setData(data+offset, getLength()-offset); } +void PrivateDataSpecifierDescriptor::Parse() { + s=data.getData(); +} + +int PrivateDataSpecifierDescriptor::getPrivateDataSpecifier() const { + return (HILO(s->private_data_specifier_hi) << 16) | HILO(s->private_data_specifier_lo); +} + void SubtitlingDescriptor::Parse() { subtitlingLoop.setData(data+sizeof(descr_subtitling), getLength()-sizeof(descr_subtitling)); } @@ -633,11 +666,47 @@ void MultilingualServiceNameDescriptor::Name::Parse() { name.setData(data+offset, mid->service_name_length); } +void LocalTimeOffsetDescriptor::Parse() { + localTimeOffsetLoop.setData(data+sizeof(descr_local_time_offset), getLength()-sizeof(descr_local_time_offset)); +} + +int LocalTimeOffsetDescriptor::LocalTimeOffset::getCountryId() const { + return s->country_region_id; +} + +int LocalTimeOffsetDescriptor::LocalTimeOffset::getLocalTimeOffsetPolarity() const { + return s->local_time_offset_polarity; +} + +int LocalTimeOffsetDescriptor::LocalTimeOffset::getLocalTimeOffset() const { + return (s->local_time_offset_h << 8) | s->local_time_offset_m; +} + +time_t LocalTimeOffsetDescriptor::LocalTimeOffset::getTimeOfChange() const { + return DVBTime::getTime(s->time_of_change_mjd_hi, s->time_of_change_mjd_lo, s->time_of_change_time_h, s->time_of_change_time_m, s->time_of_change_time_s); +} + +int LocalTimeOffsetDescriptor::LocalTimeOffset::getNextTimeOffset() const { + return (s->next_time_offset_h << 8) | s->next_time_offset_m; +} + +void LocalTimeOffsetDescriptor::LocalTimeOffset::Parse() { + s=data.getData(); + countryCode[0]=s->country_code1; + countryCode[1]=s->country_code2; + countryCode[2]=s->country_code3; + countryCode[3]=0; +} + void LinkageDescriptor::Parse() { int offset=0; + s1 = NULL; data.setPointerAndOffset(s, offset); - if (checkSize(getLength()-offset)) + if (checkSize(getLength()-offset)) { + if (getLinkageType() == LinkageTypeMobileHandover) + data.setPointerAndOffset(s1, offset); privateData.assign(data.getData(offset), getLength()-offset); + } } int LinkageDescriptor::getTransportStreamId() const { @@ -656,6 +725,18 @@ LinkageType LinkageDescriptor::getLinkageType() const { return (LinkageType)s->linkage_type; } +int LinkageDescriptor::getHandOverType() const { + return s1 == NULL ? 0 : s1->hand_over_type; +} + +int LinkageDescriptor::getOriginType() const { + return s1 == NULL ? 0 : s1->origin_type; +} + +int LinkageDescriptor::getId() const { + return s1 == NULL ? 0 : HILO(s1->id); +} + void ISO639LanguageDescriptor::Parse() { languageLoop.setData(data+sizeof(descr_iso_639_language), getLength()-sizeof(descr_iso_639_language)); @@ -704,6 +785,44 @@ int PDCDescriptor::getMinute() const { return s->pil2 & 0x3F; } +void AncillaryDataDescriptor::Parse() { + int offset=0; + data.setPointerAndOffset(s, offset); +} + +int AncillaryDataDescriptor::getAncillaryDataIdentifier() const { + return s->ancillary_data_identifier; +} + +int PremiereContentTransmissionDescriptor::getOriginalNetworkId() const { + return HILO(s->original_network_id); +} + +int PremiereContentTransmissionDescriptor::getTransportStreamId() const { + return HILO(s->transport_stream_id); +} + +int PremiereContentTransmissionDescriptor::getServiceId() const { + return HILO(s->service_id); +} + +int PremiereContentTransmissionDescriptor::getMJD() const { + return HILO(s->mjd); +} + +void PremiereContentTransmissionDescriptor::Parse() { + s=data.getData(); + startTimeLoop.setData(data+sizeof(descr_premiere_content_transmission), getLength()-sizeof(descr_premiere_content_transmission)); +} + +time_t PremiereContentTransmissionDescriptor::StartTimeEntry::getStartTime(int mjd) const { + return DVBTime::getTime(mjd >> 8, mjd & 0xff, s->start_time_h, s->start_time_m, s->start_time_s); +} + +void PremiereContentTransmissionDescriptor::StartTimeEntry::Parse() { + s=data.getData(); +} + void ApplicationSignallingDescriptor::Parse() { entryLoop.setData(data+sizeof(descr_application_signalling), getLength()-sizeof(descr_application_signalling)); } diff --git a/libsi/descriptor.h b/libsi/descriptor.h index 476da3fb..338a1fd5 100644 --- a/libsi/descriptor.h +++ b/libsi/descriptor.h @@ -6,7 +6,7 @@ * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * - * $Id: descriptor.h 1.13 2005/09/03 15:17:35 kls Exp $ + * $Id: descriptor.h 1.14 2006/04/14 10:53:44 kls Exp $ * * ***************************************************************************/ @@ -121,6 +121,25 @@ protected: virtual void Parse(); }; +class TeletextDescriptor : public Descriptor { +public: + class Teletext : public LoopElement { + public: + char languageCode[4]; + int getTeletextType() const; + int getTeletextMagazineNumber() const; + int getTeletextPageNumber() const; + virtual int getLength() { return sizeof(item_teletext); } + protected: + virtual void Parse(); + private: + const item_teletext *s; + }; + StructureLoop teletextLoop; +protected: + virtual void Parse(); +}; + class CaDescriptor : public Descriptor { public: int getCaType() const; @@ -281,6 +300,15 @@ private: const descr_component *s; }; +class PrivateDataSpecifierDescriptor : public Descriptor { +public: + int getPrivateDataSpecifier() const; +protected: + virtual void Parse(); +private: + const descr_private_data_specifier *s; +}; + class SubtitlingDescriptor : public Descriptor { public: class Subtitling : public LoopElement { @@ -377,17 +405,42 @@ protected: virtual void Parse(); }; +class LocalTimeOffsetDescriptor : public Descriptor { +public: + class LocalTimeOffset : public LoopElement { + public: + char countryCode[4]; + virtual int getLength() { return sizeof(local_time_offset_entry); } + int getCountryId() const; + int getLocalTimeOffsetPolarity() const; + int getLocalTimeOffset() const; + time_t getTimeOfChange() const; + int getNextTimeOffset() const; + protected: + virtual void Parse(); + private: + const local_time_offset_entry *s; + }; + StructureLoop localTimeOffsetLoop; +protected: + virtual void Parse(); +}; + class LinkageDescriptor : public Descriptor { public: int getTransportStreamId() const; int getOriginalNetworkId() const; int getServiceId() const; LinkageType getLinkageType() const; + int getHandOverType() const; + int getOriginType() const; + int getId() const; CharArray privateData; protected: virtual void Parse(); private: const descr_linkage *s; + const descr_linkage_8 *s1; }; class ISO639LanguageDescriptor : public Descriptor { @@ -422,6 +475,41 @@ private: const descr_pdc *s; }; +class AncillaryDataDescriptor : public Descriptor { +public: + int getAncillaryDataIdentifier() const; +protected: + virtual void Parse(); +private: + const descr_ancillary_data *s; +}; + +// Private DVB Descriptor Premiere.de +// 0xF2 Content Transmission Descriptor +// http://dvbsnoop.sourceforge.net/examples/example-private-section.html + +class PremiereContentTransmissionDescriptor : public Descriptor { +public: + class StartTimeEntry : public LoopElement { + public: + virtual int getLength() { return sizeof(item_premiere_content_transmission_reference); } + time_t getStartTime(int mjd) const; //UTC + protected: + virtual void Parse(); + private: + const item_premiere_content_transmission_reference *s; + }; + StructureLoop startTimeLoop; + int getOriginalNetworkId() const; + int getTransportStreamId() const; + int getServiceId() const; + int getMJD() const; +protected: + virtual void Parse(); +private: + const descr_premiere_content_transmission *s; +}; + //a descriptor currently unimplemented in this library class UnimplementedDescriptor : public Descriptor { protected: diff --git a/libsi/headers.h b/libsi/headers.h index 69350cdd..a238ca67 100644 --- a/libsi/headers.h +++ b/libsi/headers.h @@ -10,7 +10,7 @@ * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * - * $Id: headers.h 1.5 2005/09/03 15:18:16 kls Exp $ + * $Id: headers.h 1.6 2006/04/14 10:53:44 kls Exp $ * * ***************************************************************************/ @@ -769,6 +769,57 @@ struct ait_app { /* descriptors */ }; +/* Premiere Content Information Table */ + +#define PCIT_LEN 17 + +struct pcit { + 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; + + u_char contentId_hi_hi :8; + u_char contentId_hi_lo :8; + u_char contentId_lo_hi :8; + u_char contentId_lo_lo :8; + + u_char duration_h :8; + u_char duration_m :8; + u_char duration_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; +}; + /* * * The following describes the different descriptors that can be used within @@ -1010,6 +1061,21 @@ struct descr_linkage { u_char linkage_type :8; }; +#define DESCR_LINKAGE_8_LEN 3 +struct descr_linkage_8 { +#if BYTE_ORDER == BIG_ENDIAN + u_char hand_over_type :4; + u_char reserved :3; + u_char origin_type :1; +#else + u_char origin_type :1; + u_char reserved :3; + u_char hand_over_type :4; +#endif + u_char id_hi :8; + u_char id_lo :8; +}; + /* 0x4B nvod_reference_descriptor */ #define DESCR_NVOD_REFERENCE_LEN 2 @@ -1364,7 +1430,10 @@ struct descr_multilingual_component { struct descr_private_data_specifier { u_char descriptor_tag :8; u_char descriptor_length :8; - /* TBD */ + u_char private_data_specifier_hi_hi :8; + u_char private_data_specifier_hi_lo :8; + u_char private_data_specifier_lo_hi :8; + u_char private_data_specifier_lo_lo :8; }; /* 0x60 service_move_descriptor */ @@ -1717,6 +1786,34 @@ struct descr_application_icons_descriptor_end { u_char icon_flags_lo :8; }; +// Private DVB Descriptor Premiere.de +// 0xF2 Content Transmission Descriptor +// http://dvbsnoop.sourceforge.net/examples/example-private-section.html + +#define DESCR_PREMIERE_CONTENT_TRANSMISSION_LEN 11 + +struct descr_premiere_content_transmission { + 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 mjd_hi :8; + u_char mjd_lo :8; + u_char start_time_loop :8; +}; + +#define ITEM_PREMIERE_CONTENT_TRANSMISSION_LEN 3 + +struct item_premiere_content_transmission_reference { + u_char start_time_h :8; + u_char start_time_m :8; + u_char start_time_s :8; +}; + } //end of namespace #endif //LIBSI_HEADERS_H diff --git a/libsi/section.c b/libsi/section.c index 68af9918..6dd43df7 100644 --- a/libsi/section.c +++ b/libsi/section.c @@ -6,7 +6,7 @@ * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * - * $Id: section.c 1.4 2006/02/18 10:38:20 kls Exp $ + * $Id: section.c 1.5 2006/04/14 10:53:44 kls Exp $ * * ***************************************************************************/ @@ -341,4 +341,20 @@ void AIT::Application::Parse() { applicationDescriptors.setData(data+offset, HILO(s->application_descriptors_length)); } +/******************* PremiereCIT *******************/ + +void PremiereCIT::Parse() { + int offset=0; + data.setPointerAndOffset(s, offset); + eventDescriptors.setData(data+offset, HILO(s->descriptors_loop_length)); +} + +int PremiereCIT::getContentId() const { + return (HILO(s->contentId_hi) << 16) | HILO(s->contentId_lo); +} + +time_t PremiereCIT::getDuration() const { + return DVBTime::getDuration(s->duration_h, s->duration_m, s->duration_s); +} + } //end of namespace diff --git a/libsi/section.h b/libsi/section.h index 5b43f05f..29af7f4b 100644 --- a/libsi/section.h +++ b/libsi/section.h @@ -6,7 +6,7 @@ * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * - * $Id: section.h 1.3 2004/02/20 13:45:45 kls Exp $ + * $Id: section.h 1.4 2006/04/14 10:53:44 kls Exp $ * * ***************************************************************************/ @@ -260,6 +260,21 @@ protected: virtual void Parse(); }; +/* Premiere Content Information Table */ + +class PremiereCIT : public NumberedSection { +public: + PremiereCIT(const unsigned char *data, bool doCopy=true) : NumberedSection(data, doCopy) {} + PremiereCIT() {} + int getContentId() const; + time_t getDuration() const; + PCIT_DescriptorLoop eventDescriptors; +protected: + virtual void Parse(); +private: + const pcit *s; +}; + } //end of namespace #endif //LIBSI_TABLE_H diff --git a/libsi/si.c b/libsi/si.c index bbd3f1af..c7f23e88 100644 --- a/libsi/si.c +++ b/libsi/si.c @@ -6,7 +6,7 @@ * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * - * $Id: si.c 1.15 2006/02/18 10:38:20 kls Exp $ + * $Id: si.c 1.16 2006/04/14 10:53:44 kls Exp $ * * ***************************************************************************/ @@ -373,6 +373,9 @@ Descriptor *Descriptor::getDescriptor(CharArray da, DescriptorTagDomain domain, case MultilingualComponentDescriptorTag: d=new MultilingualComponentDescriptor(); break; + case PrivateDataSpecifierDescriptorTag: + d=new PrivateDataSpecifierDescriptor(); + break; case ServiceMoveDescriptorTag: d=new ServiceMoveDescriptor(); break; @@ -400,9 +403,16 @@ Descriptor *Descriptor::getDescriptor(CharArray da, DescriptorTagDomain domain, case ParentalRatingDescriptorTag: d=new ParentalRatingDescriptor(); break; + case TeletextDescriptorTag: + case VBITeletextDescriptorTag: + d=new TeletextDescriptor(); + break; case ApplicationSignallingDescriptorTag: d=new ApplicationSignallingDescriptor(); break; + case LocalTimeOffsetDescriptorTag: + d=new LocalTimeOffsetDescriptor(); + break; case LinkageDescriptorTag: d=new LinkageDescriptor(); break; @@ -412,6 +422,9 @@ Descriptor *Descriptor::getDescriptor(CharArray da, DescriptorTagDomain domain, case PDCDescriptorTag: d=new PDCDescriptor(); break; + case AncillaryDataDescriptorTag: + d=new AncillaryDataDescriptor(); + break; //note that it is no problem to implement one //of the unimplemented descriptors. @@ -436,13 +449,9 @@ Descriptor *Descriptor::getDescriptor(CharArray da, DescriptorTagDomain domain, //defined in ETSI EN 300 468 case StuffingDescriptorTag: case VBIDataDescriptorTag: - case VBITeletextDescriptorTag: case CountryAvailabilityDescriptorTag: case MocaicDescriptorTag: - case TeletextDescriptorTag: case TelephoneDescriptorTag: - case LocalTimeOffsetDescriptorTag: - case PrivateDataSpecifierDescriptorTag: case CellListDescriptorTag: case CellFrequencyLinkDescriptorTag: case ServiceAvailabilityDescriptorTag: @@ -453,7 +462,6 @@ Descriptor *Descriptor::getDescriptor(CharArray da, DescriptorTagDomain domain, case CaSystemDescriptorTag: case AC3DescriptorTag: case DSNGDescriptorTag: - case AncillaryDataDescriptorTag: case AnnouncementSupportDescriptorTag: case AdaptationFieldDataDescriptorTag: case TransportStreamDescriptorTag: @@ -500,6 +508,27 @@ Descriptor *Descriptor::getDescriptor(CharArray da, DescriptorTagDomain domain, break; } break; + case PCIT: + switch ((DescriptorTag)da.getData()->descriptor_tag) { + case ContentDescriptorTag: + d=new ContentDescriptor(); + break; + case ShortEventDescriptorTag: + d=new ShortEventDescriptor(); + break; + case ExtendedEventDescriptorTag: + d=new ExtendedEventDescriptor(); + break; + case PremiereContentTransmissionDescriptorTag: + d=new PremiereContentTransmissionDescriptor(); + break; + default: + if (!returnUnimplemetedDescriptor) + return 0; + d=new UnimplementedDescriptor(); + break; + } + break; } d->setData(da); return d; diff --git a/libsi/si.h b/libsi/si.h index c8910ffb..6922cdcd 100644 --- a/libsi/si.h +++ b/libsi/si.h @@ -6,7 +6,7 @@ * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * - * $Id: si.h 1.13 2006/02/18 10:38:20 kls Exp $ + * $Id: si.h 1.14 2006/04/14 10:53:44 kls Exp $ * * ***************************************************************************/ @@ -43,7 +43,8 @@ enum TableId { TableIdPAT = 0x00, //program association section TableIdTOT = 0x73, //time offset section TableIdDIT = 0x7E, //discontinuity information section TableIdSIT = 0x7F, //service information section - TableIdAIT = 0x74 //application information section + TableIdAIT = 0x74, //application information section + TableIdPremiereCIT = 0xA0 //premiere content information section }; @@ -139,13 +140,15 @@ enum DescriptorTag { MHP_PrefetchDescriptorTag = 0x0C, MHP_DelegatedApplicationDescriptorTag = 0x0E, MHP_ApplicationStorageDescriptorTag = 0x10, + // Premiere private Descriptor Tags + PremiereContentTransmissionDescriptorTag = 0xF2, //a descriptor currently unimplemented in this library //the actual value 0xFF is "forbidden" according to the spec. UnimplementedDescriptorTag = 0xFF }; -enum DescriptorTagDomain { SI, MHP }; +enum DescriptorTagDomain { SI, MHP, PCIT }; enum RunningStatus { RunningStatusUndefined = 0, RunningStatusNotRunning = 1, @@ -411,6 +414,12 @@ public: MHP_DescriptorLoop() { domain=MHP; } }; +//Premiere Content Information Table +class PCIT_DescriptorLoop : public DescriptorLoop { +public: + PCIT_DescriptorLoop() { domain=PCIT; } +}; + //The content of the ExtendedEventDescriptor may be split over several //descriptors if the text is longer than 256 bytes. //The following classes provide base functionality to handle this case.