SASC
DVBSoftCAM

si.h

Go to the documentation of this file.
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 1.15 2006/05/27 13:07:20 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 = 0x46, //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                CaSystemDescriptorTag = 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 TS 102 812 (MHP)
00126                // They once again start with 0x00 (see page 234, MHP specification)
00127                MHP_ApplicationDescriptorTag = 0x00,
00128                MHP_ApplicationNameDescriptorTag = 0x01,
00129                MHP_TransportProtocolDescriptorTag = 0x02,
00130                MHP_DVBJApplicationDescriptorTag = 0x03,
00131                MHP_DVBJApplicationLocationDescriptorTag = 0x04,
00132                // 0x05 - 0x0A is unimplemented this library
00133                MHP_ExternalApplicationAuthorisationDescriptorTag = 0x05,
00134                MHP_IPv4RoutingDescriptorTag = 0x06,
00135                MHP_IPv6RoutingDescriptorTag = 0x07,
00136                MHP_DVBHTMLApplicationDescriptorTag = 0x08,
00137                MHP_DVBHTMLApplicationLocationDescriptorTag = 0x09,
00138                MHP_DVBHTMLApplicationBoundaryDescriptorTag = 0x0A,
00139                MHP_ApplicationIconsDescriptorTag = 0x0B,
00140                MHP_PrefetchDescriptorTag = 0x0C,
00141                MHP_DelegatedApplicationDescriptorTag = 0x0E,
00142                MHP_ApplicationStorageDescriptorTag = 0x10,
00143   // Premiere private Descriptor Tags
00144                PremiereContentTransmissionDescriptorTag = 0xF2,
00145 
00146                //a descriptor currently unimplemented in this library
00147                //the actual value 0xFF is "forbidden" according to the spec.
00148                UnimplementedDescriptorTag = 0xFF
00149 };
00150 
00151 enum DescriptorTagDomain { SI, MHP, PCIT };
00152 
00153 enum RunningStatus { RunningStatusUndefined = 0,
00154                      RunningStatusNotRunning = 1,
00155                      RunningStatusStartsInAFewSeconds = 2,
00156                      RunningStatusPausing = 3,
00157                      RunningStatusRunning = 4
00158                    };
00159 
00160 enum LinkageType { LinkageTypeInformationService = 0x01,
00161                    LinkageTypeEPGService = 0x02,
00162                    LinkageTypeCaReplacementService = 0x03,
00163                    LinkageTypeTSContainingCompleteNetworkBouquetSi = 0x04,
00164                    LinkageTypeServiceReplacementService = 0x05,
00165                    LinkageTypeDataBroadcastService = 0x06,
00166                    LinkageTypeRCSMap = 0x07,
00167                    LinkageTypeMobileHandover = 0x08,
00168                    LinkageTypeSystemSoftwareUpdateService = 0x09,
00169                    LinkageTypeTSContainingSsuBatOrNit = 0x0A
00170                  };
00171 
00172 enum AudioType { AudioTypeUndefined = 0x00,
00173                  AudioTypeCleanEffects = 0x01,
00174                  AudioTypeHearingImpaired = 0x02,
00175                  AudioTypeVisualImpairedCommentary = 0x03
00176                };
00177 
00178 /* Some principles:
00179    - Objects that return references to other objects contained in their data must make sure
00180      that the returned objects have been parsed.
00181      (the Loop subclasses take care of that.)
00182      Note that this does not apply to Loops and Strings (their are never returned by reference, BTW).
00183 */
00184 
00185 class Object : public Parsable {
00186 public:
00187    Object();
00188    Object(CharArray &d);
00189    //can only be called once since data is immutable
00190    void setData(const unsigned char*data, int size, bool doCopy=true);
00191    CharArray getData() { return data; }
00192    //returns the valid flag which indicates if data is all right or errors have been encountered
00193    bool isValid() { return data.isValid(); }
00194    virtual int getLength() = 0;
00195 protected:
00196    CharArray data;
00197    //is protected - not used for sections
00198    template <class T> friend class StructureLoop;
00199    void setData(CharArray &d);
00200    //returns whether the given offset fits within the limits of the actual data
00201    //The valid flag will be set accordingly
00202    bool checkSize(int offset);
00203 };
00204 
00205 class Section : public Object {
00206 public:
00207    //convenience: sets data and parses if doParse
00208    Section(const unsigned char *data, bool doCopy=true);
00209    Section() {}
00210    TableId getTableId() const;
00211    virtual int getLength();
00212 
00213    static int getLength(const unsigned char *d);
00214    static TableId getTableId(const unsigned char *d);
00215 };
00216 
00217 class CRCSection : public Section {
00218 public:
00219    //convenience: sets data and parses if doParse
00220    CRCSection(const unsigned char *data, bool doCopy=true) : Section(data, doCopy) {}
00221    CRCSection() {}
00222    bool isCRCValid();
00223    //convenience: isValid+CheckParse
00224    bool CheckCRCAndParse();
00225 };
00226 
00227 /* A section which has the ExtendedSectionHeader
00228    (section_syntax_indicator==1) */
00229 class NumberedSection : public CRCSection {
00230 public:
00231    NumberedSection(const unsigned char *data, bool doCopy=true) : CRCSection(data, doCopy) {}
00232    NumberedSection() {}
00233    int getTableIdExtension() const;
00234    bool getCurrentNextIndicator() const;
00235    int getVersionNumber() const;
00236    int getSectionNumber() const;
00237    int getLastSectionNumber() const;
00238    bool moreThanOneSection()  const { return getLastSectionNumber()>0; }
00239 
00240    static int getTableIdExtension(const unsigned char *d);
00241 };
00242 
00243 class VariableLengthPart : public Object {
00244 public:
00245    //never forget to call this
00246    void setData(CharArray d, int l) { Object::setData(d); checkSize(l); length=l; }
00247    //convenience method
00248    void setDataAndOffset(CharArray d, int l, int &offset) { Object::setData(d); checkSize(l); length=l; offset+=l; }
00249    virtual int getLength() { return length; }
00250 private:
00251    int length;
00252 };
00253 
00254 class LoopElement : public Object {
00255 };
00256 
00257 class Descriptor : public LoopElement {
00258 public:
00259    virtual int getLength();
00260    DescriptorTag getDescriptorTag() const;
00261 
00262    static int getLength(const unsigned char *d);
00263    static DescriptorTag getDescriptorTag(const unsigned char *d);
00264 protected:
00265    friend class DescriptorLoop;
00266    //returns a subclass of descriptor according to the data given.
00267    //The object is allocated with new and must be delete'd.
00268    //setData() will have been called, CheckParse() not.
00269    //if returnUnimplemetedDescriptor==true:
00270    //   Never returns null - maybe the UnimplementedDescriptor.
00271    //if returnUnimplemetedDescriptor==false:
00272    //   Never returns the UnimplementedDescriptor - maybe null
00273    static Descriptor *getDescriptor(CharArray d, DescriptorTagDomain domain, bool returnUnimplemetedDescriptor);
00274 };
00275 
00276 class Loop : public VariableLengthPart {
00277 public:
00278    class Iterator {
00279    public:
00280       Iterator() { i=0; }
00281       void reset() { i=0; }
00282    private:
00283       template <class T> friend class StructureLoop;
00284       friend class DescriptorLoop;
00285       template <class T> friend class TypeLoop;
00286       friend class ExtendedEventDescriptors;
00287       int i;
00288    };
00289 protected:
00290    virtual void Parse() {}
00291 };
00292 
00293 //contains LoopElements of one type only
00294 template <class T> class StructureLoop : public Loop {
00295 public:
00296    //currently you must use a while-loop testing for hasNext()
00297    //i must be 0 to get the first descriptor (with the first call)
00298    bool getNext(T &obj, Iterator &it)
00299       {
00300          if (!isValid() || it.i >= getLength())
00301             return false;
00302          CharArray d=data;
00303          d.addOffset(it.i);
00304          T ret;
00305          ret.setData(d);
00306          ret.CheckParse();
00307          if (!checkSize(ret.getLength()))
00308             return false;
00309          it.i+=ret.getLength();
00310          obj=ret;
00311          return true;
00312       }
00313    T* getNextAsPointer(Iterator &it)
00314       {
00315          if (!isValid() || it.i >= getLength())
00316             return 0;
00317          CharArray d=data;
00318          d.addOffset(it.i);
00319          T *ret=new T();
00320          ret->setData(d);
00321          ret->CheckParse();
00322          if (!checkSize(ret->getLength()))
00323             return 0;
00324          it.i+=ret->getLength();
00325          return ret;
00326       }
00327    //bool hasNext(Iterator &it) { return getLength() > it.i; }
00328 };
00329 
00330 //contains descriptors of different types
00331 class DescriptorLoop : public Loop {
00332 public:
00333    DescriptorLoop() { domain=SI; }
00334    //i must be 0 to get the first descriptor (with the first call)
00335    //All returned descriptors must be delete'd.
00336    //returns null if no more descriptors available
00337    Descriptor *getNext(Iterator &it);
00338    //return the next descriptor with given tag, or 0 if not available.
00339    //if returnUnimplemetedDescriptor==true:
00340    //   an UnimplementedDescriptor may be returned if the next matching descriptor is unimplemented,
00341    //   0 will be returned if and only if no matching descriptor is found.
00342    //if returnUnimplemetedDescriptor==false:
00343    //   if 0 is returned, either no descriptor with the given tag was found,
00344    //   or descriptors were found, but the descriptor type is not implemented
00345    //In either case, a return value of 0 indicates that no further calls to this method
00346    //with the iterator shall be made.
00347    Descriptor *getNext(Iterator &it, DescriptorTag tag, bool returnUnimplemetedDescriptor=false);
00348    //return the next descriptor with one of the given tags, or 0 if not available.
00349    //if returnUnimplemetedDescriptor==true:
00350    //   returns 0 if and only if no descriptor with one of the given tags was found.
00351    //   The UnimplementedDescriptor may be returned.
00352    //if returnUnimplemetedDescriptor==false:
00353    //   if 0 is returned, either no descriptor with one of the given tags was found,
00354    //   or descriptors were found, but none of them are implemented.
00355    //   The UnimplementedDescriptor will never be returned.
00356    //In either case, a return value of 0 indicates that no further calls to this method
00357    //with the iterator shall be made.
00358    Descriptor *getNext(Iterator &it, DescriptorTag *tags, int arrayLength, bool returnUnimplemetedDescriptor=false);
00359    //returns the number of descriptors in this loop
00360    int getNumberOfDescriptors();
00361    //writes the tags of the descriptors in this loop in the array,
00362    // which must at least have the size getNumberOfDescriptors().
00363    //The number of descriptors, i.e. getNumberOfDescriptors(), is returned.
00364    // You can specify the array type (Descriptor tags are 8 Bit,
00365    // you might e.g. choose a char, short, int or DescriptorTag array)
00366    template <typename T> int getDescriptorTags(T *tags)
00367       {
00368          const unsigned char *p=data.getData();
00369          const unsigned char *end=p+getLength();
00370          int count=0;
00371          while (p < end) {
00372             tags[count++]=(T)Descriptor::getDescriptorTag(p);
00373             p+=Descriptor::getLength(p);
00374          }
00375          return count;
00376       }
00377 protected:
00378    Descriptor *createDescriptor(int &i, bool returnUnimplemetedDescriptor);
00379    DescriptorTagDomain domain;
00380 };
00381 
00382 typedef uint8_t   EightBit;
00383 typedef uint16_t  SixteenBit;
00384 typedef uint32_t  ThirtyTwoBit;
00385 typedef uint64_t  SixtyFourBit;
00386 
00387 template <typename T> class TypeLoop : public Loop {
00388 public:
00389    int getCount() { return getLength()/sizeof(T); }
00390    T operator[](const int index) const
00391       {
00392          switch (sizeof(T)) {
00393          case 1:
00394             return data[index];
00395          case 2:
00396             return data.TwoBytes(index);
00397          case 4:
00398             return data.FourBytes(index);
00399          case 8:
00400             return (SixtyFourBit(data.FourBytes(index)) << 32) | data.FourBytes(index+4);
00401          }
00402          return 0; // just to avoid a compiler warning
00403       }
00404    T getNext(Iterator &it) const
00405       {
00406          T ret=operator[](it.i);
00407          it.i+=sizeof(T);
00408          return ret;
00409       }
00410    bool hasNext(Iterator &it) { return isValid() && (getLength() > it.i); }
00411 };
00412 
00413 class MHP_DescriptorLoop : public DescriptorLoop {
00414 public:
00415    MHP_DescriptorLoop() { domain=MHP; }
00416 };
00417 
00418 //Premiere Content Information Table
00419 class PCIT_DescriptorLoop : public DescriptorLoop {
00420 public:
00421    PCIT_DescriptorLoop() { domain=PCIT; }
00422 };
00423 
00424 //The content of the ExtendedEventDescriptor may be split over several
00425 //descriptors if the text is longer than 256 bytes.
00426 //The following classes provide base functionality to handle this case.
00427 class GroupDescriptor : public Descriptor {
00428 public:
00429    virtual int getDescriptorNumber() = 0;
00430    virtual int getLastDescriptorNumber() = 0;
00431 };
00432 
00433 class DescriptorGroup {
00434 public:
00435    DescriptorGroup(bool deleteOnDesctruction=true);
00436    ~DescriptorGroup();
00437    void Add(GroupDescriptor *d);
00438    void Delete();
00439    int getLength() { return length; }
00440    GroupDescriptor **getDescriptors() { return array; }
00441    bool isComplete(); //if all descriptors have been added
00442 protected:
00443    int length;
00444    GroupDescriptor **array;
00445    bool deleteOnDesctruction;
00446 };
00447 
00448 class String : public VariableLengthPart {
00449 public:
00450    //A note to the length: getLength() returns the length of the raw data.
00451    //The text may be shorter. Its length can be obtained with one of the
00452    //getText functions and strlen.
00453 
00454    //returns text. Data is allocated with new and must be delete'd by the user.
00455    char *getText();
00456    //copies text into given buffer.
00457    //a buffer of size getLength()+1 is guaranteed to be sufficiently large.
00458    //In most descriptors the string length is an 8-bit field,
00459    //so the maximum there is 256.
00460    //returns the given buffer for convenience.
00461    //The emphasis marks 0x86 and 0x87 are still available.
00462    char *getText(char *buffer, int size);
00463    //The same semantics as for getText(char*) apply.
00464    //The short version of the text according to ETSI TR 101 211 (chapter 4.6)
00465    //will be written into the shortVersion buffer (which should, therefore, have the same
00466    //length as buffer). If no shortVersion is available, shortVersion will contain
00467    //an empty string.
00468    //The emphasis marks 0x86 and 0x87 are still available in buffer, but not in shortVersion.
00469    char *getText(char *buffer, char *shortVersion, int sizeBuffer, int sizeShortVersion);
00470 protected:
00471    virtual void Parse() {}
00472    void decodeText(char *buffer, int size);
00473    void decodeText(char *buffer, char *shortVersion, int sizeBuffer, int sizeShortVersion);
00474 };
00475 
00476 } //end of namespace
00477 
00478 #endif //LIBSI_SI_H
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines