vdr
1.7.27
|
00001 /*************************************************************************** 00002 * Copyright (c) 2003 by Marcel Wiesweg * 00003 * * 00004 * This program is free software; you can redistribute it and/or modify * 00005 * it under the terms of the GNU General Public License as published by * 00006 * the Free Software Foundation; either version 2 of the License, or * 00007 * (at your option) any later version. * 00008 * * 00009 * $Id: si.h 2.5 2012/01/11 11:35:17 kls Exp $ 00010 * * 00011 ***************************************************************************/ 00012 00013 #ifndef LIBSI_SI_H 00014 #define LIBSI_SI_H 00015 00016 #include <stdint.h> 00017 00018 #include "util.h" 00019 #include "headers.h" 00020 00021 namespace SI { 00022 00023 enum TableId { TableIdPAT = 0x00, //program association section 00024 TableIdCAT = 0x01, //conditional access section 00025 TableIdPMT = 0x02, //program map section 00026 TableIdTSDT = 0x03,//transport stream description section 00027 TableIdNIT = 0x40, //network information, actual network section 00028 TableIdNIT_other = 0x41, //network information section, other network 00029 TableIdSDT = 0x42, //service description section 00030 TableIdSDT_other = 0x46, 00031 TableIdBAT = 0x4A, //bouquet association section 00032 TableIdEIT_presentFollowing = 0x4E, //event information section 00033 TableIdEIT_presentFollowing_other = 0x4F, 00034 //range from 0x50 to 0x5F 00035 TableIdEIT_schedule_first = 0x50, 00036 TableIdEIT_schedule_last = 0x5F, 00037 //range from 0x60 to 0x6F 00038 TableIdEIT_schedule_Other_first = 0x60, 00039 TableIdEIT_schedule_Other_last = 0x6F, 00040 TableIdTDT = 0x70, //time date section 00041 TableIdRST = 0x71, //running status section 00042 TableIdST = 0x72, //stuffing section 00043 TableIdTOT = 0x73, //time offset section 00044 TableIdDIT = 0x7E, //discontinuity information section 00045 TableIdSIT = 0x7F, //service information section 00046 TableIdAIT = 0x74, //application information section 00047 TableIdPremiereCIT = 0xA0 //premiere content information section 00048 }; 00049 00050 00051 enum DescriptorTag { 00052 // defined by ISO/IEC 13818-1 00053 VideoStreamDescriptorTag = 0x02, 00054 AudioStreamDescriptorTag = 0x03, 00055 HierarchyDescriptorTag = 0x04, 00056 RegistrationDescriptorTag = 0x05, 00057 DataStreamAlignmentDescriptorTag = 0x06, 00058 TargetBackgroundGridDescriptorTag = 0x07, 00059 VideoWindowDescriptorTag = 0x08, 00060 CaDescriptorTag = 0x09, 00061 ISO639LanguageDescriptorTag = 0x0A, 00062 SystemClockDescriptorTag = 0x0B, 00063 MultiplexBufferUtilizationDescriptorTag = 0x0C, 00064 CopyrightDescriptorTag = 0x0D, 00065 MaximumBitrateDescriptorTag = 0x0E, 00066 PrivateDataIndicatorDescriptorTag = 0x0F, 00067 SmoothingBufferDescriptorTag = 0x10, 00068 STDDescriptorTag = 0x11, 00069 IBPDescriptorTag = 0x12, 00070 // defined by ISO-13818-6 (DSM-CC) 00071 CarouselIdentifierDescriptorTag = 0x13, 00072 // 0x14 - 0x3F Reserved 00073 // defined by ETSI (EN 300 468) 00074 NetworkNameDescriptorTag = 0x40, 00075 ServiceListDescriptorTag = 0x41, 00076 StuffingDescriptorTag = 0x42, 00077 SatelliteDeliverySystemDescriptorTag = 0x43, 00078 CableDeliverySystemDescriptorTag = 0x44, 00079 VBIDataDescriptorTag = 0x45, 00080 VBITeletextDescriptorTag = 0x46, 00081 BouquetNameDescriptorTag = 0x47, 00082 ServiceDescriptorTag = 0x48, 00083 CountryAvailabilityDescriptorTag = 0x49, 00084 LinkageDescriptorTag = 0x4A, 00085 NVODReferenceDescriptorTag = 0x4B, 00086 TimeShiftedServiceDescriptorTag = 0x4C, 00087 ShortEventDescriptorTag = 0x4D, 00088 ExtendedEventDescriptorTag = 0x4E, 00089 TimeShiftedEventDescriptorTag = 0x4F, 00090 ComponentDescriptorTag = 0x50, 00091 MocaicDescriptorTag = 0x51, 00092 StreamIdentifierDescriptorTag = 0x52, 00093 CaIdentifierDescriptorTag = 0x53, 00094 ContentDescriptorTag = 0x54, 00095 ParentalRatingDescriptorTag = 0x55, 00096 TeletextDescriptorTag = 0x56, 00097 TelephoneDescriptorTag = 0x57, 00098 LocalTimeOffsetDescriptorTag = 0x58, 00099 SubtitlingDescriptorTag = 0x59, 00100 TerrestrialDeliverySystemDescriptorTag = 0x5A, 00101 MultilingualNetworkNameDescriptorTag = 0x5B, 00102 MultilingualBouquetNameDescriptorTag = 0x5C, 00103 MultilingualServiceNameDescriptorTag = 0x5D, 00104 MultilingualComponentDescriptorTag = 0x5E, 00105 PrivateDataSpecifierDescriptorTag = 0x5F, 00106 ServiceMoveDescriptorTag = 0x60, 00107 ShortSmoothingBufferDescriptorTag = 0x61, 00108 FrequencyListDescriptorTag = 0x62, 00109 PartialTransportStreamDescriptorTag = 0x63, 00110 DataBroadcastDescriptorTag = 0x64, 00111 ScramblingDescriptorTag = 0x65, 00112 DataBroadcastIdDescriptorTag = 0x66, 00113 TransportStreamDescriptorTag = 0x67, 00114 DSNGDescriptorTag = 0x68, 00115 PDCDescriptorTag = 0x69, 00116 AC3DescriptorTag = 0x6A, 00117 AncillaryDataDescriptorTag = 0x6B, 00118 CellListDescriptorTag = 0x6C, 00119 CellFrequencyLinkDescriptorTag = 0x6D, 00120 AnnouncementSupportDescriptorTag = 0x6E, 00121 ApplicationSignallingDescriptorTag = 0x6F, 00122 AdaptationFieldDataDescriptorTag = 0x70, 00123 ServiceIdentifierDescriptorTag = 0x71, 00124 ServiceAvailabilityDescriptorTag = 0x72, 00125 // defined by ETSI (EN 300 468) v 1.7.1 00126 DefaultAuthorityDescriptorTag = 0x73, 00127 RelatedContentDescriptorTag = 0x74, 00128 TVAIdDescriptorTag = 0x75, 00129 ContentIdentifierDescriptorTag = 0x76, 00130 TimeSliceFecIdentifierDescriptorTag = 0x77, 00131 ECMRepetitionRateDescriptorTag = 0x78, 00132 S2SatelliteDeliverySystemDescriptorTag = 0x79, 00133 EnhancedAC3DescriptorTag = 0x7A, 00134 DTSDescriptorTag = 0x7B, 00135 AACDescriptorTag = 0x7C, 00136 ExtensionDescriptorTag = 0x7F, 00137 // Extension descriptors 00138 ImageIconDescriptorTag = 0x00, 00139 CpcmDeliverySignallingDescriptor = 0x01, 00140 CPDescriptorTag = 0x02, 00141 CPIdentifierDescriptorTag = 0x03, 00142 T2DeliverySystemDescriptorTag = 0x04, 00143 SHDeliverySystemDescriptorTag = 0x05, 00144 SupplementaryAudioDescriptorTag = 0x06, 00145 NetworkChangeNotifyDescriptorTag = 0x07, 00146 MessageDescriptorTag = 0x08, 00147 TargetRegionDescriptorTag = 0x09, 00148 TargetRegionNameDescriptorTag = 0x0A, 00149 ServiceRelocatedDescriptorTag = 0x0B, 00150 00151 // Defined by ETSI TS 102 812 (MHP) 00152 // They once again start with 0x00 (see page 234, MHP specification) 00153 MHP_ApplicationDescriptorTag = 0x00, 00154 MHP_ApplicationNameDescriptorTag = 0x01, 00155 MHP_TransportProtocolDescriptorTag = 0x02, 00156 MHP_DVBJApplicationDescriptorTag = 0x03, 00157 MHP_DVBJApplicationLocationDescriptorTag = 0x04, 00158 // 0x05 - 0x0A is unimplemented this library 00159 MHP_ExternalApplicationAuthorisationDescriptorTag = 0x05, 00160 MHP_IPv4RoutingDescriptorTag = 0x06, 00161 MHP_IPv6RoutingDescriptorTag = 0x07, 00162 MHP_DVBHTMLApplicationDescriptorTag = 0x08, 00163 MHP_DVBHTMLApplicationLocationDescriptorTag = 0x09, 00164 MHP_DVBHTMLApplicationBoundaryDescriptorTag = 0x0A, 00165 MHP_ApplicationIconsDescriptorTag = 0x0B, 00166 MHP_PrefetchDescriptorTag = 0x0C, 00167 MHP_DelegatedApplicationDescriptorTag = 0x0E, 00168 MHP_ApplicationStorageDescriptorTag = 0x10, 00169 MHP_SimpleApplicationLocationDescriptorTag = 0x15, 00170 MHP_SimpleApplicationBoundaryDescriptorTag = 0x17, 00171 // Premiere private Descriptor Tags 00172 PremiereContentTransmissionDescriptorTag = 0xF2, 00173 00174 //a descriptor currently unimplemented in this library 00175 //the actual value 0xFF is "forbidden" according to the spec. 00176 UnimplementedDescriptorTag = 0xFF 00177 }; 00178 00179 enum DescriptorTagDomain { SI, MHP, PCIT }; 00180 00181 enum RunningStatus { RunningStatusUndefined = 0, 00182 RunningStatusNotRunning = 1, 00183 RunningStatusStartsInAFewSeconds = 2, 00184 RunningStatusPausing = 3, 00185 RunningStatusRunning = 4 00186 }; 00187 00188 enum LinkageType { LinkageTypeInformationService = 0x01, 00189 LinkageTypeEPGService = 0x02, 00190 LinkageTypeCaReplacementService = 0x03, 00191 LinkageTypeTSContainingCompleteNetworkBouquetSi = 0x04, 00192 LinkageTypeServiceReplacementService = 0x05, 00193 LinkageTypeDataBroadcastService = 0x06, 00194 LinkageTypeRCSMap = 0x07, 00195 LinkageTypeMobileHandover = 0x08, 00196 LinkageTypeSystemSoftwareUpdateService = 0x09, 00197 LinkageTypeTSContainingSsuBatOrNit = 0x0A 00198 }; 00199 00200 enum AudioType { AudioTypeUndefined = 0x00, 00201 AudioTypeCleanEffects = 0x01, 00202 AudioTypeHearingImpaired = 0x02, 00203 AudioTypeVisualImpairedCommentary = 0x03 00204 }; 00205 00206 /* Some principles: 00207 - Objects that return references to other objects contained in their data must make sure 00208 that the returned objects have been parsed. 00209 (the Loop subclasses take care of that.) 00210 Note that this does not apply to Loops and Strings (their are never returned by reference, BTW). 00211 */ 00212 00213 class Object : public Parsable { 00214 public: 00215 Object(); 00216 Object(CharArray &d); 00217 //can only be called once since data is immutable 00218 void setData(const unsigned char*data, int size, bool doCopy=true); 00219 CharArray getData() { return data; } 00220 //returns the valid flag which indicates if data is all right or errors have been encountered 00221 bool isValid() { return data.isValid(); } 00222 virtual int getLength() = 0; 00223 protected: 00224 CharArray data; 00225 //is protected - not used for sections 00226 template <class T> friend class StructureLoop; 00227 void setData(CharArray &d); 00228 //returns whether the given offset fits within the limits of the actual data 00229 //The valid flag will be set accordingly 00230 bool checkSize(int offset); 00231 }; 00232 00233 class Section : public Object { 00234 public: 00235 //convenience: sets data and parses if doParse 00236 Section(const unsigned char *data, bool doCopy=true); 00237 Section() {} 00238 TableId getTableId() const; 00239 virtual int getLength(); 00240 00241 static int getLength(const unsigned char *d); 00242 static TableId getTableId(const unsigned char *d); 00243 }; 00244 00245 class CRCSection : public Section { 00246 public: 00247 //convenience: sets data and parses if doParse 00248 CRCSection(const unsigned char *data, bool doCopy=true) : Section(data, doCopy) {} 00249 CRCSection() {} 00250 bool isCRCValid(); 00251 //convenience: isValid+CheckParse 00252 bool CheckCRCAndParse(); 00253 }; 00254 00255 /* A section which has the ExtendedSectionHeader 00256 (section_syntax_indicator==1) */ 00257 class NumberedSection : public CRCSection { 00258 public: 00259 NumberedSection(const unsigned char *data, bool doCopy=true) : CRCSection(data, doCopy) {} 00260 NumberedSection() {} 00261 int getTableIdExtension() const; 00262 bool getCurrentNextIndicator() const; 00263 int getVersionNumber() const; 00264 int getSectionNumber() const; 00265 int getLastSectionNumber() const; 00266 bool moreThanOneSection() const { return getLastSectionNumber()>0; } 00267 00268 static int getTableIdExtension(const unsigned char *d); 00269 }; 00270 00271 class VariableLengthPart : public Object { 00272 public: 00273 //never forget to call this 00274 void setData(CharArray d, int l) { Object::setData(d); checkSize(l); length=l; } 00275 //convenience method 00276 void setDataAndOffset(CharArray d, int l, int &offset) { Object::setData(d); checkSize(l); length=l; offset+=l; } 00277 virtual int getLength() { return length; } 00278 private: 00279 int length; 00280 }; 00281 00282 class LoopElement : public Object { 00283 }; 00284 00285 class Descriptor : public LoopElement { 00286 public: 00287 virtual int getLength(); 00288 DescriptorTag getDescriptorTag() const; 00289 00290 static int getLength(const unsigned char *d); 00291 static DescriptorTag getDescriptorTag(const unsigned char *d); 00292 protected: 00293 friend class DescriptorLoop; 00294 //returns a subclass of descriptor according to the data given. 00295 //The object is allocated with new and must be delete'd. 00296 //setData() will have been called, CheckParse() not. 00297 //if returnUnimplemetedDescriptor==true: 00298 // Never returns null - maybe the UnimplementedDescriptor. 00299 //if returnUnimplemetedDescriptor==false: 00300 // Never returns the UnimplementedDescriptor - maybe null 00301 static Descriptor *getDescriptor(CharArray d, DescriptorTagDomain domain, bool returnUnimplemetedDescriptor); 00302 }; 00303 00304 class Loop : public VariableLengthPart { 00305 public: 00306 class Iterator { 00307 public: 00308 Iterator() { i=0; } 00309 void reset() { i=0; } 00310 private: 00311 template <class T> friend class StructureLoop; 00312 friend class DescriptorLoop; 00313 template <class T> friend class TypeLoop; 00314 friend class ExtendedEventDescriptors; 00315 int i; 00316 }; 00317 protected: 00318 virtual void Parse() {} 00319 }; 00320 00321 //contains LoopElements of one type only 00322 template <class T> class StructureLoop : public Loop { 00323 public: 00324 //currently you must use a while-loop testing for hasNext() 00325 //i must be 0 to get the first descriptor (with the first call) 00326 bool getNext(T &obj, Iterator &it) 00327 { 00328 if (!isValid() || it.i >= getLength()) 00329 return false; 00330 CharArray d=data; 00331 d.addOffset(it.i); 00332 T ret; 00333 ret.setData(d); 00334 ret.CheckParse(); 00335 if (!checkSize(ret.getLength())) 00336 return false; 00337 it.i+=ret.getLength(); 00338 obj=ret; 00339 return true; 00340 } 00341 T* getNextAsPointer(Iterator &it) 00342 { 00343 if (!isValid() || it.i >= getLength()) 00344 return 0; 00345 CharArray d=data; 00346 d.addOffset(it.i); 00347 T *ret=new T(); 00348 ret->setData(d); 00349 ret->CheckParse(); 00350 if (!checkSize(ret->getLength())) 00351 return 0; 00352 it.i+=ret->getLength(); 00353 return ret; 00354 } 00355 //bool hasNext(Iterator &it) { return getLength() > it.i; } 00356 }; 00357 00358 //contains descriptors of different types 00359 class DescriptorLoop : public Loop { 00360 public: 00361 DescriptorLoop() { domain=SI; } 00362 //i must be 0 to get the first descriptor (with the first call) 00363 //All returned descriptors must be delete'd. 00364 //returns null if no more descriptors available 00365 Descriptor *getNext(Iterator &it); 00366 //return the next descriptor with given tag, or 0 if not available. 00367 //if returnUnimplemetedDescriptor==true: 00368 // an UnimplementedDescriptor may be returned if the next matching descriptor is unimplemented, 00369 // 0 will be returned if and only if no matching descriptor is found. 00370 //if returnUnimplemetedDescriptor==false: 00371 // if 0 is returned, either no descriptor with the given tag was found, 00372 // or descriptors were found, but the descriptor type is not implemented 00373 //In either case, a return value of 0 indicates that no further calls to this method 00374 //with the iterator shall be made. 00375 Descriptor *getNext(Iterator &it, DescriptorTag tag, bool returnUnimplemetedDescriptor=false); 00376 //return the next descriptor with one of the given tags, or 0 if not available. 00377 //if returnUnimplemetedDescriptor==true: 00378 // returns 0 if and only if no descriptor with one of the given tags was found. 00379 // The UnimplementedDescriptor may be returned. 00380 //if returnUnimplemetedDescriptor==false: 00381 // if 0 is returned, either no descriptor with one of the given tags was found, 00382 // or descriptors were found, but none of them are implemented. 00383 // The UnimplementedDescriptor will never be returned. 00384 //In either case, a return value of 0 indicates that no further calls to this method 00385 //with the iterator shall be made. 00386 Descriptor *getNext(Iterator &it, DescriptorTag *tags, int arrayLength, bool returnUnimplemetedDescriptor=false); 00387 //returns the number of descriptors in this loop 00388 int getNumberOfDescriptors(); 00389 //writes the tags of the descriptors in this loop in the array, 00390 // which must at least have the size getNumberOfDescriptors(). 00391 //The number of descriptors, i.e. getNumberOfDescriptors(), is returned. 00392 // You can specify the array type (Descriptor tags are 8 Bit, 00393 // you might e.g. choose a char, short, int or DescriptorTag array) 00394 template <typename T> int getDescriptorTags(T *tags) 00395 { 00396 const unsigned char *p=data.getData(); 00397 const unsigned char *end=p+getLength(); 00398 int count=0; 00399 while (p < end) { 00400 tags[count++]=(T)Descriptor::getDescriptorTag(p); 00401 p+=Descriptor::getLength(p); 00402 } 00403 return count; 00404 } 00405 protected: 00406 Descriptor *createDescriptor(int &i, bool returnUnimplemetedDescriptor); 00407 DescriptorTagDomain domain; 00408 }; 00409 00410 typedef uint8_t EightBit; 00411 typedef uint16_t SixteenBit; 00412 typedef uint32_t ThirtyTwoBit; 00413 typedef uint64_t SixtyFourBit; 00414 00415 template <typename T> class TypeLoop : public Loop { 00416 public: 00417 int getCount() { return getLength()/sizeof(T); } 00418 T operator[](const int index) const 00419 { 00420 switch (sizeof(T)) { 00421 case 1: 00422 return data[index]; 00423 case 2: 00424 return data.TwoBytes(index); 00425 case 4: 00426 return data.FourBytes(index); 00427 case 8: 00428 return (SixtyFourBit(data.FourBytes(index)) << 32) | data.FourBytes(index+4); 00429 default: 00430 return 0; // just to avoid a compiler warning 00431 } 00432 return 0; // just to avoid a compiler warning 00433 } 00434 T getNext(Iterator &it) const 00435 { 00436 T ret=operator[](it.i); 00437 it.i+=sizeof(T); 00438 return ret; 00439 } 00440 bool hasNext(Iterator &it) { return isValid() && (getLength() > it.i); } 00441 }; 00442 00443 class MHP_DescriptorLoop : public DescriptorLoop { 00444 public: 00445 MHP_DescriptorLoop() { domain=MHP; } 00446 }; 00447 00448 //Premiere Content Information Table 00449 class PCIT_DescriptorLoop : public DescriptorLoop { 00450 public: 00451 PCIT_DescriptorLoop() { domain=PCIT; } 00452 }; 00453 00454 //The content of the ExtendedEventDescriptor may be split over several 00455 //descriptors if the text is longer than 256 bytes. 00456 //The following classes provide base functionality to handle this case. 00457 class GroupDescriptor : public Descriptor { 00458 public: 00459 virtual int getDescriptorNumber() = 0; 00460 virtual int getLastDescriptorNumber() = 0; 00461 }; 00462 00463 class DescriptorGroup { 00464 public: 00465 DescriptorGroup(bool deleteOnDesctruction=true); 00466 ~DescriptorGroup(); 00467 void Add(GroupDescriptor *d); 00468 void Delete(); 00469 int getLength() { return length; } 00470 GroupDescriptor **getDescriptors() { return array; } 00471 bool isComplete(); //if all descriptors have been added 00472 protected: 00473 int length; 00474 GroupDescriptor **array; 00475 bool deleteOnDesctruction; 00476 }; 00477 00478 class String : public VariableLengthPart { 00479 public: 00480 //A note to the length: getLength() returns the length of the raw data. 00481 //The text may be shorter. Its length can be obtained with one of the 00482 //getText functions and strlen. 00483 00484 //returns text. Data is allocated with new and must be delete'd by the user. 00485 char *getText(); 00486 //copies text into given buffer. 00487 //a buffer of size getLength()+1 is guaranteed to be sufficiently large. 00488 //In most descriptors the string length is an 8-bit field, 00489 //so the maximum there is 256. 00490 //returns the given buffer for convenience. 00491 //The emphasis marks 0x86 and 0x87 are still available. 00492 char *getText(char *buffer, int size); 00493 //The same semantics as for getText(char*) apply. 00494 //The short version of the text according to ETSI TR 101 211 (chapter 4.6) 00495 //will be written into the shortVersion buffer (which should, therefore, have the same 00496 //length as buffer). If no shortVersion is available, shortVersion will contain 00497 //an empty string. 00498 //The emphasis marks 0x86 and 0x87 are still available in buffer, but not in shortVersion. 00499 char *getText(char *buffer, char *shortVersion, int sizeBuffer, int sizeShortVersion); 00500 protected: 00501 virtual void Parse() {} 00502 void decodeText(char *buffer, int size); 00503 void decodeText(char *buffer, char *shortVersion, int sizeBuffer, int sizeShortVersion); 00504 }; 00505 00506 // Call this function to set the system character table. CharacterTable is a string 00507 // like "iso8859-15" or "utf-8" (case insensitive). 00508 // Returns true if the character table was recognized. 00509 bool SetSystemCharacterTable(const char *CharacterTable); 00510 // Determines the character table used in the given buffer and returns 00511 // a string indicating that table. If no table can be determined, the 00512 // default ISO6937 is returned. If a table can be determined, the buffer 00513 // and length are adjusted accordingly. 00514 const char *getCharacterTable(const unsigned char *&buffer, int &length, bool *isSingleByte = NULL); 00515 bool convertCharacterTable(const char *from, size_t fromLength, char *to, size_t toLength, const char *fromCode); 00516 bool systemCharacterTableIsSingleByte(void); 00517 00518 } //end of namespace 00519 00520 #endif //LIBSI_SI_H