mirror of
https://github.com/vdr-projects/vdr.git
synced 2025-03-01 10:50:46 +00:00
Added 'libsi'
This commit is contained in:
405
libsi/si.h
Normal file
405
libsi/si.h
Normal file
@@ -0,0 +1,405 @@
|
||||
/***************************************************************************
|
||||
* Copyright (c) 2003 by Marcel Wiesweg *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
|
||||
#ifndef LIBSI_SI_H
|
||||
#define LIBSI_SI_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "util.h"
|
||||
#include "headers.h"
|
||||
|
||||
namespace SI {
|
||||
|
||||
enum TableId { TableIdPAT = 0x00, //program association section
|
||||
TableIdCAT = 0x01, //conditional access section
|
||||
TableIdPMT = 0x02, //program map section
|
||||
TableIdTSDT = 0x03,//transport stream description section
|
||||
TableIdNIT = 0x40, //network information, actual network section
|
||||
TableIdNIT_other = 0x41, //network information section, other network
|
||||
TableIdSDT = 0x42, //service description section
|
||||
TableIdSDT_other = 0x46,
|
||||
TableIdBAT = 0x46, //bouquet association section
|
||||
TableIdEIT_presentFollowing = 0x4E, //event information section
|
||||
TableIdEIT_presentFollowing_other = 0x4F,
|
||||
//range from 0x50 to 0x5F
|
||||
TableIdEIT_schedule_first = 0x50,
|
||||
TableIdEIT_schedule_last = 0x5F,
|
||||
//range from 0x60 to 0x6F
|
||||
TableIdEIT_schedule_Other_first = 0x60,
|
||||
TableIdEIT_schedule_Other_fast = 0x6F,
|
||||
TableIdTDT = 0x70, //time date section
|
||||
TableIdRST = 0x71, //running status section
|
||||
TableIdST = 0x72, //stuffing section
|
||||
TableIdTOT = 0x73, //time offset section
|
||||
TableIdDIT = 0x7E, //discontinuity information section
|
||||
TableIdSIT = 0x7F, //service information section
|
||||
TableIdAIT = 0x74 //application information section
|
||||
};
|
||||
|
||||
|
||||
enum DescriptorTag {
|
||||
// defined by ISO/IEC 13818-1
|
||||
VideoStreamDescriptorTag = 0x02,
|
||||
AudioStreamDescriptorTag = 0x03,
|
||||
HierarchyDescriptorTag = 0x04,
|
||||
RegistrationDescriptorTag = 0x05,
|
||||
DataStreamAlignmentDescriptorTag = 0x06,
|
||||
TargetBackgroundGridDescriptorTag = 0x07,
|
||||
VideoWindowDescriptorTag = 0x08,
|
||||
CaDescriptorTag = 0x09,
|
||||
ISO639LanguageDescriptorTag = 0x0A,
|
||||
SystemClockDescriptorTag = 0x0B,
|
||||
MultiplexBufferUtilizationDescriptorTag = 0x0C,
|
||||
CopyrightDescriptorTag = 0x0D,
|
||||
MaximumBitrateDescriptorTag = 0x0E,
|
||||
PrivateDataIndicatorDescriptorTag = 0x0F,
|
||||
SmoothingBufferDescriptorTag = 0x10,
|
||||
STDDescriptorTag = 0x11,
|
||||
IBPDescriptorTag = 0x12,
|
||||
// defined by ISO-13818-6 (DSM-CC)
|
||||
CarouselIdentifierDescriptorTag = 0x13,
|
||||
// 0x14 - 0x3F Reserved
|
||||
// defined by ETSI (EN 300 468)
|
||||
NetworkNameDescriptorTag = 0x40,
|
||||
ServiceListDescriptorTag = 0x41,
|
||||
StuffingDescriptorTag = 0x42,
|
||||
SatelliteDeliverySystemDescriptorTag = 0x43,
|
||||
CableDeliverySystemDescriptorTag = 0x44,
|
||||
VBIDataDescriptorTag = 0x45,
|
||||
VBITeletextDescriptorTag = 0x46,
|
||||
BouquetNameDescriptorTag = 0x47,
|
||||
ServiceDescriptorTag = 0x48,
|
||||
CountryAvailabilityDescriptorTag = 0x49,
|
||||
LinkageDescriptorTag = 0x4A,
|
||||
NVODReferenceDescriptorTag = 0x4B,
|
||||
TimeShiftedServiceDescriptorTag = 0x4C,
|
||||
ShortEventDescriptorTag = 0x4D,
|
||||
ExtendedEventDescriptorTag = 0x4E,
|
||||
TimeShiftedEventDescriptorTag = 0x4F,
|
||||
ComponentDescriptorTag = 0x50,
|
||||
MocaicDescriptorTag = 0x51,
|
||||
StreamIdentifierDescriptorTag = 0x52,
|
||||
CaIdentifierDescriptorTag = 0x53,
|
||||
ContentDescriptorTag = 0x54,
|
||||
ParentalRatingDescriptorTag = 0x55,
|
||||
TeletextDescriptorTag = 0x56,
|
||||
TelephoneDescriptorTag = 0x57,
|
||||
LocalTimeOffsetDescriptorTag = 0x58,
|
||||
SubtitlingDescriptorTag = 0x59,
|
||||
TerrestrialDeliverySystemDescriptorTag = 0x5A,
|
||||
MultilingualNetworkNameDescriptorTag = 0x5B,
|
||||
MultilingualBouquetNameDescriptorTag = 0x5C,
|
||||
MultilingualServiceNameDescriptorTag = 0x5D,
|
||||
MultilingualComponentDescriptorTag = 0x5E,
|
||||
PrivateDataSpecifierDescriptorTag = 0x5F,
|
||||
ServiceMoveDescriptorTag = 0x60,
|
||||
ShortSmoothingBufferDescriptorTag = 0x61,
|
||||
FrequencyListDescriptorTag = 0x62,
|
||||
PartialTransportStreamDescriptorTag = 0x63,
|
||||
DataBroadcastDescriptorTag = 0x64,
|
||||
CaSystemDescriptorTag = 0x65,
|
||||
DataBroadcastIdDescriptorTag = 0x66,
|
||||
TransportStreamDescriptorTag = 0x67,
|
||||
DSNGDescriptorTag = 0x68,
|
||||
PDCDescriptorTag = 0x69,
|
||||
AC3DescriptorTag = 0x6A,
|
||||
AncillaryDataDescriptorTag = 0x6B,
|
||||
CellListDescriptorTag = 0x6C,
|
||||
CellFrequencyLinkDescriptorTag = 0x6D,
|
||||
AnnouncementSupportDescriptorTag = 0x6E,
|
||||
ApplicationSignallingDescriptorTag = 0x6F,
|
||||
AdaptationFieldDataDescriptorTag = 0x70,
|
||||
ServiceIdentifierDescriptorTag = 0x71,
|
||||
ServiceAvailabilityDescriptorTag = 0x72,
|
||||
// Defined by ETSI TS 102 812 (MHP)
|
||||
// They once again start with 0x00 (see page 234, MHP specification)
|
||||
MHP_ApplicationDescriptorTag = 0x00,
|
||||
MHP_ApplicationNameDescriptorTag = 0x01,
|
||||
MHP_TransportProtocolDescriptorTag = 0x02,
|
||||
MHP_DVBJApplicationDescriptorTag = 0x03,
|
||||
MHP_DVBJApplicationLocationDescriptorTag = 0x04,
|
||||
// 0x05 - 0x0A is unimplemented this library
|
||||
MHP_ExternalApplicationAuthorisationDescriptorTag = 0x05,
|
||||
MHP_IPv4RoutingDescriptorTag = 0x06,
|
||||
MHP_IPv6RoutingDescriptorTag = 0x07,
|
||||
MHP_DVBHTMLApplicationDescriptorTag = 0x08,
|
||||
MHP_DVBHTMLApplicationLocationDescriptorTag = 0x09,
|
||||
MHP_DVBHTMLApplicationBoundaryDescriptorTag = 0x0A,
|
||||
MHP_ApplicationIconsDescriptorTag = 0x0B,
|
||||
MHP_PrefetchDescriptorTag = 0x0C,
|
||||
MHP_DelegatedApplicationDescriptorTag = 0x0E,
|
||||
MHP_ApplicationStorageDescriptorTag = 0x10,
|
||||
|
||||
//a descriptor currently unimplemented in this library
|
||||
//the actual value 0xFF is "forbidden" according to the spec.
|
||||
UnimplementedDescriptorTag = 0xFF
|
||||
};
|
||||
|
||||
enum DescriptorTagDomain { SI, MHP };
|
||||
|
||||
enum RunningStatus { RunningStatusUndefined = 0,
|
||||
RunningStatusNotRunning = 1,
|
||||
RunningStatusStartsInAFewSeconds = 2,
|
||||
RunningStatusPausing = 3,
|
||||
RunningStatusRunning = 4
|
||||
};
|
||||
|
||||
|
||||
/* Some principles:
|
||||
- Objects that return references to other objects contained in their data must make sure
|
||||
that the returned objects have been parsed.
|
||||
(the Loop subclasses take care of that.)
|
||||
Note that this does not apply to Loops and Strings (their are never returned by reference, BTW).
|
||||
*/
|
||||
|
||||
|
||||
class Object : public Parsable {
|
||||
public:
|
||||
Object();
|
||||
Object(CharArray &d);
|
||||
//can only be called once since data is immutable
|
||||
void setData(const unsigned char*data, unsigned int size, bool doCopy=true);
|
||||
virtual int getLength() = 0;
|
||||
protected:
|
||||
CharArray data;
|
||||
//is protected - not used for sections
|
||||
template <class T> friend class StructureLoop;
|
||||
void setData(CharArray &d);
|
||||
};
|
||||
|
||||
class Section : public Object {
|
||||
public:
|
||||
//convenience: sets data and parses if doParse
|
||||
Section(const unsigned char *data, bool doCopy=true);
|
||||
Section() {}
|
||||
TableId getTableId() const;
|
||||
virtual int getLength();
|
||||
|
||||
static int getLength(const unsigned char *d);
|
||||
static TableId getTableId(const unsigned char *d);
|
||||
};
|
||||
|
||||
class CRCSection : public Section {
|
||||
public:
|
||||
//convenience: sets data and parses if doParse
|
||||
CRCSection(const unsigned char *data, bool doCopy=true) : Section(data, doCopy) {}
|
||||
CRCSection() {}
|
||||
bool isValid();
|
||||
//convenience: isValid+CheckParse
|
||||
bool CheckCRCAndParse();
|
||||
};
|
||||
|
||||
/* A section which has the ExtendedSectionHeader
|
||||
(section_syntax_indicator==1) */
|
||||
class NumberedSection : public CRCSection {
|
||||
public:
|
||||
NumberedSection(const unsigned char *data, bool doCopy=true) : CRCSection(data, doCopy) {}
|
||||
NumberedSection() {}
|
||||
bool getCurrentNextIndicator() const;
|
||||
int getVersionNumber() const;
|
||||
int getSectionNumber() const;
|
||||
int getLastSectionNumber() const;
|
||||
bool moreThanOneSection() const { return getLastSectionNumber()>1; }
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
class VariableLengthPart : public Object {
|
||||
public:
|
||||
//never forget to call this
|
||||
void setData(CharArray d, int l) { Object::setData(d); length=l; }
|
||||
//convenience method
|
||||
void setDataAndOffset(CharArray d, int l, unsigned int &offset) { Object::setData(d); length=l; offset+=l; }
|
||||
virtual int getLength() { return length; }
|
||||
private:
|
||||
int length;
|
||||
};
|
||||
|
||||
|
||||
|
||||
class LoopElement : public Object {
|
||||
};
|
||||
|
||||
|
||||
class SubStructure : public LoopElement {
|
||||
};
|
||||
|
||||
class Descriptor : public LoopElement {
|
||||
public:
|
||||
virtual int getLength();
|
||||
DescriptorTag getDescriptorTag() const;
|
||||
|
||||
static int getLength(const unsigned char *d);
|
||||
static DescriptorTag getDescriptorTag(const unsigned char *d);
|
||||
protected:
|
||||
friend class DescriptorLoop;
|
||||
//returns a subclass of descriptor according to the data given.
|
||||
//The object is allocated with new and must be delete'd.
|
||||
//setData() will have been called, CheckParse() not.
|
||||
//Never returns null - maybe the UnimplementedDescriptor.
|
||||
static Descriptor *getDescriptor(CharArray d, DescriptorTagDomain domain);
|
||||
};
|
||||
|
||||
|
||||
|
||||
class Loop : public VariableLengthPart {
|
||||
public:
|
||||
class Iterator {
|
||||
public:
|
||||
Iterator() { i=0; }
|
||||
void reset() { i=0; }
|
||||
private:
|
||||
template <class T> friend class StructureLoop;
|
||||
friend class DescriptorLoop;
|
||||
int i;
|
||||
};
|
||||
protected:
|
||||
virtual void Parse() {}
|
||||
};
|
||||
|
||||
//contains LoopElements of one type only
|
||||
template <class T> class StructureLoop : public Loop {
|
||||
public:
|
||||
//currently you must use a while-loop testing for hasNext()
|
||||
//i must be 0 to get the first descriptor (with the first call)
|
||||
T getNext(Iterator &it)
|
||||
{
|
||||
CharArray d=data;
|
||||
d.addOffset(it.i);
|
||||
T ret;
|
||||
ret.setData(d);
|
||||
ret.CheckParse();
|
||||
it.i+=ret.getLength();
|
||||
return ret;
|
||||
}
|
||||
T* getNextAsPointer(Iterator &it)
|
||||
{
|
||||
if (getLength() <= it.i)
|
||||
return 0;
|
||||
CharArray d=data;
|
||||
d.addOffset(it.i);
|
||||
T *ret=new T();
|
||||
ret->setData(d);
|
||||
ret->CheckParse();
|
||||
it.i+=ret->getLength();
|
||||
return ret;
|
||||
}
|
||||
bool hasNext(Iterator &it) { return getLength() > it.i; }
|
||||
};
|
||||
|
||||
//contains descriptors of different types
|
||||
class DescriptorLoop : public Loop {
|
||||
public:
|
||||
DescriptorLoop() { domain=SI; }
|
||||
//i must be 0 to get the first descriptor (with the first call)
|
||||
//All returned descriptors must be delete'd.
|
||||
//returns null if no more descriptors available
|
||||
Descriptor *getNext(Iterator &it);
|
||||
//return the next descriptor with given tag, or 0 if not available.
|
||||
//if the descriptor found is not implemented,
|
||||
// an UnimplementedDescriptor will be returned if returnUnimplemetedDescriptor==true,
|
||||
// 0 will be returned if returnUnimplemetedDescriptor==false
|
||||
Descriptor *getNext(Iterator &it, DescriptorTag tag, bool returnUnimplemetedDescriptor=false);
|
||||
//return the next descriptor with one of the given tags, or 0 if not available.
|
||||
Descriptor *getNext(Iterator &it, DescriptorTag *tags, int arrayLength, bool returnUnimplemetedDescriptor=false);
|
||||
protected:
|
||||
Descriptor *createDescriptor(int &i);
|
||||
DescriptorTagDomain domain;
|
||||
};
|
||||
|
||||
typedef uint8_t EightBit;
|
||||
typedef uint16_t SixteenBit;
|
||||
typedef uint32_t ThirtyTwoBit;
|
||||
typedef uint64_t SixtyFourBit;
|
||||
|
||||
template <typename T> class TypeLoop : public Loop {
|
||||
public:
|
||||
int getCount() const { return getLength()/sizeof(T); }
|
||||
T operator[](const unsigned int index) const
|
||||
{
|
||||
switch (sizeof(T)) {
|
||||
case 1:
|
||||
return data[index];
|
||||
case 2:
|
||||
return data.TwoBytes(index);
|
||||
case 4:
|
||||
return data.FourBytes(index);
|
||||
case 8:
|
||||
return (data.FourBytes(index) << 32) | data.FourBytes(index+4);
|
||||
}
|
||||
}
|
||||
T getNext(Iterator &it) const
|
||||
{
|
||||
T ret=operator[](it.i);
|
||||
it.i+=sizeof(T);
|
||||
return ret;
|
||||
}
|
||||
bool hasNext() const { return getLength() > it.i; }
|
||||
};
|
||||
|
||||
class MHP_DescriptorLoop : public DescriptorLoop {
|
||||
public:
|
||||
MHP_DescriptorLoop() { domain=MHP; }
|
||||
};
|
||||
|
||||
|
||||
//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.
|
||||
class GroupDescriptor : public Descriptor {
|
||||
public:
|
||||
virtual int getDescriptorNumber() = 0;
|
||||
virtual int getLastDescriptorNumber() = 0;
|
||||
};
|
||||
|
||||
class DescriptorGroup {
|
||||
public:
|
||||
DescriptorGroup(bool deleteOnDesctruction=true);
|
||||
~DescriptorGroup();
|
||||
void Add(GroupDescriptor *d);
|
||||
void Delete();
|
||||
int getLength() { return length; }
|
||||
GroupDescriptor **getDescriptors() { return array; }
|
||||
bool isComplete(); //if all descriptors have been added
|
||||
protected:
|
||||
int length;
|
||||
GroupDescriptor **array;
|
||||
bool deleteOnDesctruction;
|
||||
};
|
||||
|
||||
|
||||
|
||||
class String : public VariableLengthPart {
|
||||
public:
|
||||
//A note to the length: getLength() returns the length of the raw data.
|
||||
//The text may be shorter. Its length can be obtained with one of the
|
||||
//above functions and strlen.
|
||||
|
||||
//returns text. Data is allocated with new and must be delete'd by the user.
|
||||
char *getText();
|
||||
//copies text into given buffer.
|
||||
//a buffer of size getLength()+1 is guaranteed to be sufficiently large.
|
||||
//In most descriptors the string length is an 8-bit field,
|
||||
//so the maximum there is 256.
|
||||
//returns the given buffer for convenience.
|
||||
char * getText(char *buffer);
|
||||
protected:
|
||||
virtual void Parse() {}
|
||||
void decodeText(char *buffer);
|
||||
};
|
||||
|
||||
|
||||
} //end of namespace
|
||||
|
||||
#endif //LIBSI_SI_H
|
||||
|
Reference in New Issue
Block a user