mirror of
https://github.com/vdr-projects/vdr.git
synced 2025-03-01 10:50:46 +00:00
- Fixed resetting the file size when regenerating the index file. - The new function cDevice::PatPmtParser() can be used in derived devices to access the PAT/PMT of the currently replayed material. - Updated the Italian OSD texts (thanks to Diego Pierotto). - The PCR pid in generated PMTs is now set to 0x1FFF ("no PCR pid") in cPatPmtGenerator::GeneratePmt(), because VDR doesn't record the PCR pid. - Updated the Estonian OSD texts (thanks to Arthur Konovalov). - The 'sky' plugin is no longer part of the VDR source. - Improved SPU handling on devices with limited OSD capabilities (thanks to Matthieu Castet). - Several code modifications to avoid compiler warnings (thanks to Winfried Köhler). - Added stream type 11172 AUDIO to cPatPmtParser::ParsePmt() (thanks to Johann Friedrichs). - Removed debug output of '-' from cTransfer::Receive(). - Added defines for large files to the 'newplugin' script (reported by Udo Richter). - Removed the workaround for short channel names of "Kabel Deutschland", because apparently they now have their data according to the DVB standard (thanks to Johann Friedrichs). - Some fixes to dvbspu.[hc] (thanks to Johann Friedrichs). - Fixed a busy loop when moving editing marks (thanks to Johann Friedrichs). - Updated sources.conf (thanks to Derek Kelly). - Modified cCharSetConv so that it can be used to convert from "whatever VDR uses" to a given code (thanks to Joachim Wilke). - Channel names containing commas are now handled correctly in channels.conf. If a channel's short name contains a comma, it is replaced with a '.'. - cDevice now logs the device number when a new device is created. - Fixed handling STREAMTYPE_11172_AUDIO in cPatPmtParser::ParsePmt(). - cParsePatPmt now has functions to retrieve the audio, dolby and subtitle pids. - cPatFilter::Process() now only stores CA descriptors for video and audio pids (thanks to Francesco Saverio Schiavarelli for reporting a problem with channels that have some encrypted components that VDR doesn't use). - cDevice::AddPid() now stores the stream type of the given pid (thanks to Andreas Regel). - Added cFont::FontName() and cFont::Size() (thanks to Andreas Regel). - cPatPmtParser now also stores the audio stream types. - The support for full featured DVB cards of the TT/FuSi design has been moved into the new plugin 'dvbsddevice'. On systems that use such a card as their primary device, this plugin now needs to be loaded when running VDR in order to view live or recorded video. If the plugin is not loaded, the card will be treated like a budget DVB card, and there will be no OSD or viewing capability. - Fixed handling the "CA PMT" generation (revised a change not mentioned in version 1.7.9's changes, which caused a malfunction with Conax and Viaccess CAMs). - Fixed stopping subtitle display when switching the primary device (thanks to Anssi Hannula). IMPORTANT NOTE TO PLUGIN AUTHORS: a plugin that implements a derived cDevice class that can replay video must now call the MakePrimaryDevice() function of its base class. - Fixed compiler warnings "format not a string literal and no format arguments" in some syslog calls (thanks to Rolf Ahrenberg). - The new command line options --edit and --genindex can be used to edit a recording or generate its index without actually starting the entire VDR (based on a patch from Helmut Auer). - Improved the description of the transponder parameters in vdr.5 (thanks to Winfried Köhler). - Avoiding setting the video stream type to 2 if the vpid is 0 (problem reported by Arthur Konovalov). - Implemented handling the "Content Descriptor" (based on a patch from Rolf Ahrenberg). The 'classic', 'sttng' and 'curses' skins display the textual representation of the content descriptors as "genre". The epg.data file stores the genre using the tag character 'G'. - Implemented handling the "Parental Rating Descriptor" (based on a patch from Rolf Ahrenberg). The 'classic', 'sttng' and 'curses' skins display the parental rating (if given) in their event displays. The epg.data file stores the parental rating using the tag character 'R'. IMPORTANT NOTE: if VDR doesn't display a parental rating, this does not necessarily mean that the given programme is suitable for all audiences! - Rearranged cEvent members to minimize memory waste. - After a CLRE command, no further EPG processing is now done for 10 seconds, so that data sent with subsequent PUTE commands doesn't interfere with data from the broadcasters (suggested by Helmut Auer). - Added support for DVB cards with multiple fontends. Note that this only works for DVB cards where each frontend can be used independently of all the others on the same adapter. - Fixed plugin arguments corruption with glibc 2.11 on x86_64 (thanks to Anssi Hannula).
730 lines
23 KiB
C
730 lines
23 KiB
C
/***************************************************************************
|
|
* 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. *
|
|
* *
|
|
* $Id: si.c 2.1 2009/12/05 16:20:12 kls Exp $
|
|
* *
|
|
***************************************************************************/
|
|
|
|
#include "si.h"
|
|
#include <errno.h>
|
|
#include <iconv.h>
|
|
#include <malloc.h>
|
|
#include <stdlib.h> // for broadcaster stupidity workaround
|
|
#include <string.h>
|
|
#include "descriptor.h"
|
|
|
|
namespace SI {
|
|
|
|
Object::Object() {
|
|
}
|
|
|
|
Object::Object(CharArray &d) : data(d) {
|
|
}
|
|
|
|
void Object::setData(const unsigned char*d, int size, bool doCopy) {
|
|
data.assign(d, size, doCopy);
|
|
}
|
|
|
|
void Object::setData(CharArray &d) {
|
|
data=d;
|
|
}
|
|
|
|
bool Object::checkSize(int offset) {
|
|
return data.checkSize(offset);
|
|
}
|
|
|
|
Section::Section(const unsigned char *data, bool doCopy) {
|
|
setData(data, getLength(data), doCopy);
|
|
}
|
|
|
|
TableId Section::getTableId() const {
|
|
return getTableId(data.getData());
|
|
}
|
|
|
|
int Section::getLength() {
|
|
return getLength(data.getData());
|
|
}
|
|
|
|
TableId Section::getTableId(const unsigned char *d) {
|
|
return (TableId)((const SectionHeader *)d)->table_id;
|
|
}
|
|
|
|
int Section::getLength(const unsigned char *d) {
|
|
return HILO(((const SectionHeader *)d)->section_length)+sizeof(SectionHeader);
|
|
}
|
|
|
|
bool CRCSection::isCRCValid() {
|
|
return CRC32::isValid((const char *)data.getData(), getLength()/*, data.FourBytes(getLength()-4)*/);
|
|
}
|
|
|
|
bool CRCSection::CheckCRCAndParse() {
|
|
if (!isCRCValid())
|
|
return false;
|
|
CheckParse();
|
|
return isValid();
|
|
}
|
|
|
|
int NumberedSection::getTableIdExtension() const {
|
|
return getTableIdExtension(data.getData());
|
|
}
|
|
|
|
int NumberedSection::getTableIdExtension(const unsigned char *d) {
|
|
return HILO(((const ExtendedSectionHeader *)d)->table_id_extension);
|
|
}
|
|
|
|
bool NumberedSection::getCurrentNextIndicator() const {
|
|
return data.getData<ExtendedSectionHeader>()->current_next_indicator;
|
|
}
|
|
|
|
int NumberedSection::getVersionNumber() const {
|
|
return data.getData<ExtendedSectionHeader>()->version_number;
|
|
}
|
|
|
|
int NumberedSection::getSectionNumber() const {
|
|
return data.getData<ExtendedSectionHeader>()->section_number;
|
|
}
|
|
|
|
int NumberedSection::getLastSectionNumber() const {
|
|
return data.getData<ExtendedSectionHeader>()->last_section_number;
|
|
}
|
|
|
|
int Descriptor::getLength() {
|
|
return getLength(data.getData());
|
|
}
|
|
|
|
DescriptorTag Descriptor::getDescriptorTag() const {
|
|
return getDescriptorTag(data.getData());
|
|
}
|
|
|
|
int Descriptor::getLength(const unsigned char *d) {
|
|
return ((const DescriptorHeader*)d)->descriptor_length+sizeof(DescriptorHeader);
|
|
}
|
|
|
|
DescriptorTag Descriptor::getDescriptorTag(const unsigned char *d) {
|
|
return (DescriptorTag)((const DescriptorHeader*)d)->descriptor_tag;
|
|
}
|
|
|
|
Descriptor *DescriptorLoop::getNext(Iterator &it) {
|
|
if (isValid() && it.i<getLength()) {
|
|
return createDescriptor(it.i, true);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
Descriptor *DescriptorLoop::getNext(Iterator &it, DescriptorTag tag, bool returnUnimplemetedDescriptor) {
|
|
Descriptor *d=0;
|
|
int len;
|
|
if (isValid() && it.i<(len=getLength())) {
|
|
const unsigned char *p=data.getData(it.i);
|
|
const unsigned char *end=p+len-it.i;
|
|
while (p < end) {
|
|
if (Descriptor::getDescriptorTag(p) == tag) {
|
|
d=createDescriptor(it.i, returnUnimplemetedDescriptor);
|
|
if (d)
|
|
break;
|
|
}
|
|
it.i+=Descriptor::getLength(p);
|
|
p+=Descriptor::getLength(p);
|
|
}
|
|
}
|
|
return d;
|
|
}
|
|
|
|
Descriptor *DescriptorLoop::getNext(Iterator &it, DescriptorTag *tags, int arrayLength, bool returnUnimplementedDescriptor) {
|
|
Descriptor *d=0;
|
|
int len;
|
|
if (isValid() && it.i<(len=getLength())) {
|
|
const unsigned char *p=data.getData(it.i);
|
|
const unsigned char *end=p+len-it.i;
|
|
while (p < end) {
|
|
for (int u=0; u<arrayLength;u++)
|
|
if (Descriptor::getDescriptorTag(p) == tags[u]) {
|
|
d=createDescriptor(it.i, returnUnimplementedDescriptor);
|
|
break;
|
|
}
|
|
if (d)
|
|
break; //length is added to it.i by createDescriptor, break here
|
|
it.i+=Descriptor::getLength(p);
|
|
p+=Descriptor::getLength(p);
|
|
}
|
|
}
|
|
return d;
|
|
}
|
|
|
|
Descriptor *DescriptorLoop::createDescriptor(int &i, bool returnUnimplemetedDescriptor) {
|
|
if (!checkSize(Descriptor::getLength(data.getData(i))))
|
|
return 0;
|
|
Descriptor *d=Descriptor::getDescriptor(data+i, domain, returnUnimplemetedDescriptor);
|
|
if (!d)
|
|
return 0;
|
|
i+=d->getLength();
|
|
d->CheckParse();
|
|
return d;
|
|
}
|
|
|
|
int DescriptorLoop::getNumberOfDescriptors() {
|
|
const unsigned char *p=data.getData();
|
|
const unsigned char *end=p+getLength();
|
|
int count=0;
|
|
while (p < end) {
|
|
count++;
|
|
p+=Descriptor::getLength(p);
|
|
}
|
|
return count;
|
|
}
|
|
|
|
DescriptorGroup::DescriptorGroup(bool del) {
|
|
array=0;
|
|
length=0;
|
|
deleteOnDesctruction=del;
|
|
}
|
|
|
|
DescriptorGroup::~DescriptorGroup() {
|
|
if (deleteOnDesctruction)
|
|
Delete();
|
|
delete[] array;
|
|
}
|
|
|
|
void DescriptorGroup::Delete() {
|
|
for (int i=0;i<length;i++)
|
|
if (array[i]!=0) {
|
|
delete array[i];
|
|
array[i]=0;
|
|
}
|
|
}
|
|
|
|
void DescriptorGroup::Add(GroupDescriptor *d) {
|
|
if (!array) {
|
|
length=d->getLastDescriptorNumber()+1;
|
|
array=new GroupDescriptor*[length]; //numbering is zero-based
|
|
for (int i=0;i<length;i++)
|
|
array[i]=0;
|
|
} else if (length != d->getLastDescriptorNumber()+1)
|
|
return; //avoid crash in case of misuse
|
|
array[d->getDescriptorNumber()]=d;
|
|
}
|
|
|
|
bool DescriptorGroup::isComplete() {
|
|
for (int i=0;i<length;i++)
|
|
if (array[i]==0)
|
|
return false;
|
|
return true;
|
|
}
|
|
|
|
char *String::getText() {
|
|
int len=getLength();
|
|
if (len < 0 || len > 4095)
|
|
return strdup("text error"); // caller will delete it!
|
|
char *data=new char(len+1); // FIXME If this function is ever actually used, this buffer might
|
|
// need to be bigger in order to hold the string as UTF-8.
|
|
// Maybe decodeText should dynamically handle this? kls 2007-06-10
|
|
decodeText(data, len+1);
|
|
return data;
|
|
}
|
|
|
|
char *String::getText(char *buffer, int size) {
|
|
int len=getLength();
|
|
if (len < 0 || len >= size) {
|
|
strncpy(buffer, "text error", size);
|
|
buffer[size-1] = 0;
|
|
return buffer;
|
|
}
|
|
decodeText(buffer, size);
|
|
return buffer;
|
|
}
|
|
|
|
char *String::getText(char *buffer, char *shortVersion, int sizeBuffer, int sizeShortVersion) {
|
|
int len=getLength();
|
|
if (len < 0 || len >= sizeBuffer) {
|
|
strncpy(buffer, "text error", sizeBuffer);
|
|
buffer[sizeBuffer-1] = 0;
|
|
*shortVersion = 0;
|
|
return buffer;
|
|
}
|
|
decodeText(buffer, shortVersion, sizeBuffer, sizeShortVersion);
|
|
return buffer;
|
|
}
|
|
|
|
static const char *CharacterTables1[] = {
|
|
NULL, // 0x00
|
|
"ISO-8859-5", // 0x01
|
|
"ISO-8859-6", // 0x02
|
|
"ISO-8859-7", // 0x03
|
|
"ISO-8859-8", // 0x04
|
|
"ISO-8859-9", // 0x05
|
|
"ISO-8859-10", // 0x06
|
|
"ISO-8859-11", // 0x07
|
|
"ISO-8859-12", // 0x08
|
|
"ISO-8859-13", // 0x09
|
|
"ISO-8859-14", // 0x0A
|
|
"ISO-8859-15", // 0x0B
|
|
NULL, // 0x0C
|
|
NULL, // 0x0D
|
|
NULL, // 0x0E
|
|
NULL, // 0x0F
|
|
NULL, // 0x10
|
|
"UTF-16", // 0x11
|
|
"EUC-KR", // 0x12
|
|
"GB2312", // 0x13
|
|
"GBK", // 0x14
|
|
"UTF-8", // 0x15
|
|
NULL, // 0x16
|
|
NULL, // 0x17
|
|
NULL, // 0x18
|
|
NULL, // 0x19
|
|
NULL, // 0x1A
|
|
NULL, // 0x1B
|
|
NULL, // 0x1C
|
|
NULL, // 0x1D
|
|
NULL, // 0x1E
|
|
NULL, // 0x1F
|
|
};
|
|
|
|
#define SingleByteLimit 0x0B
|
|
|
|
static const char *CharacterTables2[] = {
|
|
NULL, // 0x00
|
|
"ISO-8859-1", // 0x01
|
|
"ISO-8859-2", // 0x02
|
|
"ISO-8859-3", // 0x03
|
|
"ISO-8859-4", // 0x04
|
|
"ISO-8859-5", // 0x05
|
|
"ISO-8859-6", // 0x06
|
|
"ISO-8859-7", // 0x07
|
|
"ISO-8859-8", // 0x08
|
|
"ISO-8859-9", // 0x09
|
|
"ISO-8859-10", // 0x0A
|
|
"ISO-8859-11", // 0x0B
|
|
NULL, // 0x0C
|
|
"ISO-8859-13", // 0x0D
|
|
"ISO-8859-14", // 0x0E
|
|
"ISO-8859-15", // 0x0F
|
|
};
|
|
|
|
#define NumEntries(Table) (sizeof(Table) / sizeof(char *))
|
|
|
|
static const char *SystemCharacterTable = NULL;
|
|
bool SystemCharacterTableIsSingleByte = true;
|
|
|
|
bool SetSystemCharacterTable(const char *CharacterTable) {
|
|
if (CharacterTable) {
|
|
for (unsigned int i = 0; i < NumEntries(CharacterTables1); i++) {
|
|
if (CharacterTables1[i] && strcasecmp(CharacterTable, CharacterTables1[i]) == 0) {
|
|
SystemCharacterTable = CharacterTables1[i];
|
|
SystemCharacterTableIsSingleByte = i <= SingleByteLimit;
|
|
return true;
|
|
}
|
|
}
|
|
for (unsigned int i = 0; i < NumEntries(CharacterTables2); i++) {
|
|
if (CharacterTables2[i] && strcasecmp(CharacterTable, CharacterTables2[i]) == 0) {
|
|
SystemCharacterTable = CharacterTables2[i];
|
|
SystemCharacterTableIsSingleByte = true;
|
|
return true;
|
|
}
|
|
}
|
|
} else {
|
|
SystemCharacterTable = NULL;
|
|
SystemCharacterTableIsSingleByte = true;
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
// Determines the character table used in the given buffer and returns
|
|
// a string indicating that table. If no table can be determined, the
|
|
// default ISO6937 is returned. If a table can be determined, the buffer
|
|
// and length are adjusted accordingly.
|
|
static const char *getCharacterTable(const unsigned char *&buffer, int &length, bool *isSingleByte = NULL) {
|
|
const char *cs = "ISO6937";
|
|
// Workaround for broadcaster stupidity: according to
|
|
// "ETSI EN 300 468" the default character set is ISO6937. But unfortunately some
|
|
// broadcasters actually use ISO-8859-9, but fail to correctly announce that.
|
|
static const char *CharsetOverride = getenv("VDR_CHARSET_OVERRIDE");
|
|
if (CharsetOverride)
|
|
cs = CharsetOverride;
|
|
if (isSingleByte)
|
|
*isSingleByte = false;
|
|
if (length <= 0)
|
|
return cs;
|
|
unsigned int tag = buffer[0];
|
|
if (tag >= 0x20)
|
|
return cs;
|
|
if (tag == 0x10) {
|
|
if (length >= 3) {
|
|
tag = (buffer[1] << 8) | buffer[2];
|
|
if (tag < NumEntries(CharacterTables2) && CharacterTables2[tag]) {
|
|
buffer += 3;
|
|
length -= 3;
|
|
if (isSingleByte)
|
|
*isSingleByte = true;
|
|
return CharacterTables2[tag];
|
|
}
|
|
}
|
|
} else if (tag < NumEntries(CharacterTables1) && CharacterTables1[tag]) {
|
|
buffer += 1;
|
|
length -= 1;
|
|
if (isSingleByte)
|
|
*isSingleByte = tag <= SingleByteLimit;
|
|
return CharacterTables1[tag];
|
|
}
|
|
return cs;
|
|
}
|
|
|
|
static bool convertCharacterTable(const char *from, size_t fromLength, char *to, size_t toLength, const char *fromCode)
|
|
{
|
|
if (SystemCharacterTable) {
|
|
iconv_t cd = iconv_open(SystemCharacterTable, fromCode);
|
|
if (cd != (iconv_t)-1) {
|
|
char *fromPtr = (char *)from;
|
|
while (fromLength > 0 && toLength > 1) {
|
|
if (iconv(cd, &fromPtr, &fromLength, &to, &toLength) == size_t(-1)) {
|
|
if (errno == EILSEQ) {
|
|
// A character can't be converted, so mark it with '?' and proceed:
|
|
fromPtr++;
|
|
fromLength--;
|
|
*to++ = '?';
|
|
toLength--;
|
|
}
|
|
else
|
|
break;
|
|
}
|
|
}
|
|
*to = 0;
|
|
iconv_close(cd);
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
// originally from libdtv, Copyright Rolf Hakenes <hakenes@hippomi.de>
|
|
void String::decodeText(char *buffer, int size) {
|
|
const unsigned char *from=data.getData(0);
|
|
char *to=buffer;
|
|
int len=getLength();
|
|
if (len <= 0) {
|
|
*to = '\0';
|
|
return;
|
|
}
|
|
bool singleByte;
|
|
const char *cs = getCharacterTable(from, len, &singleByte);
|
|
// FIXME Need to make this UTF-8 aware (different control codes).
|
|
// However, there's yet to be found a broadcaster that actually
|
|
// uses UTF-8 for the SI data... (kls 2007-06-10)
|
|
for (int i = 0; i < len; i++) {
|
|
if (*from == 0)
|
|
break;
|
|
if ( ((' ' <= *from) && (*from <= '~'))
|
|
|| (*from == '\n')
|
|
|| (0xA0 <= *from)
|
|
)
|
|
*to++ = *from;
|
|
else if (*from == 0x8A)
|
|
*to++ = '\n';
|
|
from++;
|
|
if (to - buffer >= size - 1)
|
|
break;
|
|
}
|
|
*to = '\0';
|
|
if (!singleByte || !SystemCharacterTableIsSingleByte) {
|
|
char convBuffer[size];
|
|
if (convertCharacterTable(buffer, strlen(buffer), convBuffer, sizeof(convBuffer), cs))
|
|
strncpy(buffer, convBuffer, strlen(convBuffer) + 1);
|
|
}
|
|
}
|
|
|
|
void String::decodeText(char *buffer, char *shortVersion, int sizeBuffer, int sizeShortVersion) {
|
|
const unsigned char *from=data.getData(0);
|
|
char *to=buffer;
|
|
char *toShort=shortVersion;
|
|
int IsShortName=0;
|
|
int len=getLength();
|
|
if (len <= 0) {
|
|
*to = '\0';
|
|
*toShort = '\0';
|
|
return;
|
|
}
|
|
bool singleByte;
|
|
const char *cs = getCharacterTable(from, len, &singleByte);
|
|
// FIXME Need to make this UTF-8 aware (different control codes).
|
|
// However, there's yet to be found a broadcaster that actually
|
|
// uses UTF-8 for the SI data... (kls 2007-06-10)
|
|
for (int i = 0; i < len; i++) {
|
|
if ( ((' ' <= *from) && (*from <= '~'))
|
|
|| (*from == '\n')
|
|
|| (0xA0 <= *from)
|
|
)
|
|
{
|
|
*to++ = *from;
|
|
if (IsShortName)
|
|
*toShort++ = *from;
|
|
}
|
|
else if (*from == 0x8A)
|
|
*to++ = '\n';
|
|
else if (*from == 0x86)
|
|
IsShortName++;
|
|
else if (*from == 0x87)
|
|
IsShortName--;
|
|
else if (*from == 0)
|
|
break;
|
|
from++;
|
|
if (to - buffer >= sizeBuffer - 1 || toShort - shortVersion >= sizeShortVersion - 1)
|
|
break;
|
|
}
|
|
*to = '\0';
|
|
*toShort = '\0';
|
|
if (!singleByte || !SystemCharacterTableIsSingleByte) {
|
|
char convBuffer[sizeBuffer];
|
|
if (convertCharacterTable(buffer, strlen(buffer), convBuffer, sizeof(convBuffer), cs))
|
|
strncpy(buffer, convBuffer, strlen(convBuffer) + 1);
|
|
char convShortVersion[sizeShortVersion];
|
|
if (convertCharacterTable(shortVersion, strlen(shortVersion), convShortVersion, sizeof(convShortVersion), cs))
|
|
strncpy(shortVersion, convShortVersion, strlen(convShortVersion) + 1);
|
|
}
|
|
}
|
|
|
|
Descriptor *Descriptor::getDescriptor(CharArray da, DescriptorTagDomain domain, bool returnUnimplemetedDescriptor) {
|
|
Descriptor *d=0;
|
|
switch (domain) {
|
|
case SI:
|
|
switch ((DescriptorTag)da.getData<DescriptorHeader>()->descriptor_tag) {
|
|
case CaDescriptorTag:
|
|
d=new CaDescriptor();
|
|
break;
|
|
case CarouselIdentifierDescriptorTag:
|
|
d=new CarouselIdentifierDescriptor();
|
|
break;
|
|
case NetworkNameDescriptorTag:
|
|
d=new NetworkNameDescriptor();
|
|
break;
|
|
case ServiceListDescriptorTag:
|
|
d=new ServiceListDescriptor();
|
|
break;
|
|
case SatelliteDeliverySystemDescriptorTag:
|
|
d=new SatelliteDeliverySystemDescriptor();
|
|
break;
|
|
case CableDeliverySystemDescriptorTag:
|
|
d=new CableDeliverySystemDescriptor();
|
|
break;
|
|
case TerrestrialDeliverySystemDescriptorTag:
|
|
d=new TerrestrialDeliverySystemDescriptor();
|
|
break;
|
|
case BouquetNameDescriptorTag:
|
|
d=new BouquetNameDescriptor();
|
|
break;
|
|
case ServiceDescriptorTag:
|
|
d=new ServiceDescriptor();
|
|
break;
|
|
case NVODReferenceDescriptorTag:
|
|
d=new NVODReferenceDescriptor();
|
|
break;
|
|
case TimeShiftedServiceDescriptorTag:
|
|
d=new TimeShiftedServiceDescriptor();
|
|
break;
|
|
case ComponentDescriptorTag:
|
|
d=new ComponentDescriptor();
|
|
break;
|
|
case StreamIdentifierDescriptorTag:
|
|
d=new StreamIdentifierDescriptor();
|
|
break;
|
|
case SubtitlingDescriptorTag:
|
|
d=new SubtitlingDescriptor();
|
|
break;
|
|
case MultilingualNetworkNameDescriptorTag:
|
|
d=new MultilingualNetworkNameDescriptor();
|
|
break;
|
|
case MultilingualBouquetNameDescriptorTag:
|
|
d=new MultilingualBouquetNameDescriptor();
|
|
break;
|
|
case MultilingualServiceNameDescriptorTag:
|
|
d=new MultilingualServiceNameDescriptor();
|
|
break;
|
|
case MultilingualComponentDescriptorTag:
|
|
d=new MultilingualComponentDescriptor();
|
|
break;
|
|
case PrivateDataSpecifierDescriptorTag:
|
|
d=new PrivateDataSpecifierDescriptor();
|
|
break;
|
|
case ServiceMoveDescriptorTag:
|
|
d=new ServiceMoveDescriptor();
|
|
break;
|
|
case FrequencyListDescriptorTag:
|
|
d=new FrequencyListDescriptor();
|
|
break;
|
|
case ServiceIdentifierDescriptorTag:
|
|
d=new ServiceIdentifierDescriptor();
|
|
break;
|
|
case CaIdentifierDescriptorTag:
|
|
d=new CaIdentifierDescriptor();
|
|
break;
|
|
case ShortEventDescriptorTag:
|
|
d=new ShortEventDescriptor();
|
|
break;
|
|
case ExtendedEventDescriptorTag:
|
|
d=new ExtendedEventDescriptor();
|
|
break;
|
|
case TimeShiftedEventDescriptorTag:
|
|
d=new TimeShiftedEventDescriptor();
|
|
break;
|
|
case ContentDescriptorTag:
|
|
d=new ContentDescriptor();
|
|
break;
|
|
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;
|
|
case ISO639LanguageDescriptorTag:
|
|
d=new ISO639LanguageDescriptor();
|
|
break;
|
|
case PDCDescriptorTag:
|
|
d=new PDCDescriptor();
|
|
break;
|
|
case AncillaryDataDescriptorTag:
|
|
d=new AncillaryDataDescriptor();
|
|
break;
|
|
case S2SatelliteDeliverySystemDescriptorTag:
|
|
d=new S2SatelliteDeliverySystemDescriptor();
|
|
break;
|
|
case ExtensionDescriptorTag:
|
|
d=new ExtensionDescriptor();
|
|
break;
|
|
|
|
//note that it is no problem to implement one
|
|
//of the unimplemented descriptors.
|
|
|
|
//defined in ISO-13818-1
|
|
case VideoStreamDescriptorTag:
|
|
case AudioStreamDescriptorTag:
|
|
case HierarchyDescriptorTag:
|
|
case RegistrationDescriptorTag:
|
|
case DataStreamAlignmentDescriptorTag:
|
|
case TargetBackgroundGridDescriptorTag:
|
|
case VideoWindowDescriptorTag:
|
|
case SystemClockDescriptorTag:
|
|
case MultiplexBufferUtilizationDescriptorTag:
|
|
case CopyrightDescriptorTag:
|
|
case MaximumBitrateDescriptorTag:
|
|
case PrivateDataIndicatorDescriptorTag:
|
|
case SmoothingBufferDescriptorTag:
|
|
case STDDescriptorTag:
|
|
case IBPDescriptorTag:
|
|
|
|
//defined in ETSI EN 300 468
|
|
case StuffingDescriptorTag:
|
|
case VBIDataDescriptorTag:
|
|
case CountryAvailabilityDescriptorTag:
|
|
case MocaicDescriptorTag:
|
|
case TelephoneDescriptorTag:
|
|
case CellListDescriptorTag:
|
|
case CellFrequencyLinkDescriptorTag:
|
|
case ServiceAvailabilityDescriptorTag:
|
|
case ShortSmoothingBufferDescriptorTag:
|
|
case PartialTransportStreamDescriptorTag:
|
|
case DataBroadcastDescriptorTag:
|
|
case DataBroadcastIdDescriptorTag:
|
|
case ScramblingDescriptorTag:
|
|
case AC3DescriptorTag:
|
|
case DSNGDescriptorTag:
|
|
case AnnouncementSupportDescriptorTag:
|
|
case AdaptationFieldDataDescriptorTag:
|
|
case TransportStreamDescriptorTag:
|
|
|
|
//defined in ETSI EN 300 468 v 1.7.1
|
|
case DefaultAuthorityDescriptorTag:
|
|
case RelatedContentDescriptorTag:
|
|
case TVAIdDescriptorTag:
|
|
case ContentIdentifierDescriptorTag:
|
|
case TimeSliceFecIdentifierDescriptorTag:
|
|
case ECMRepetitionRateDescriptorTag:
|
|
case EnhancedAC3DescriptorTag:
|
|
case DTSDescriptorTag:
|
|
case AACDescriptorTag:
|
|
default:
|
|
if (!returnUnimplemetedDescriptor)
|
|
return 0;
|
|
d=new UnimplementedDescriptor();
|
|
break;
|
|
}
|
|
break;
|
|
case MHP:
|
|
switch ((DescriptorTag)da.getData<DescriptorHeader>()->descriptor_tag) {
|
|
// They once again start with 0x00 (see page 234, MHP specification)
|
|
case MHP_ApplicationDescriptorTag:
|
|
d=new MHP_ApplicationDescriptor();
|
|
break;
|
|
case MHP_ApplicationNameDescriptorTag:
|
|
d=new MHP_ApplicationNameDescriptor();
|
|
break;
|
|
case MHP_TransportProtocolDescriptorTag:
|
|
d=new MHP_TransportProtocolDescriptor();
|
|
break;
|
|
case MHP_DVBJApplicationDescriptorTag:
|
|
d=new MHP_DVBJApplicationDescriptor();
|
|
break;
|
|
case MHP_DVBJApplicationLocationDescriptorTag:
|
|
d=new MHP_DVBJApplicationLocationDescriptor();
|
|
break;
|
|
// 0x05 - 0x0A is unimplemented this library
|
|
case MHP_ExternalApplicationAuthorisationDescriptorTag:
|
|
case MHP_IPv4RoutingDescriptorTag:
|
|
case MHP_IPv6RoutingDescriptorTag:
|
|
case MHP_DVBHTMLApplicationDescriptorTag:
|
|
case MHP_DVBHTMLApplicationLocationDescriptorTag:
|
|
case MHP_DVBHTMLApplicationBoundaryDescriptorTag:
|
|
case MHP_ApplicationIconsDescriptorTag:
|
|
case MHP_PrefetchDescriptorTag:
|
|
case MHP_DelegatedApplicationDescriptorTag:
|
|
case MHP_ApplicationStorageDescriptorTag:
|
|
default:
|
|
if (!returnUnimplemetedDescriptor)
|
|
return 0;
|
|
d=new UnimplementedDescriptor();
|
|
break;
|
|
}
|
|
break;
|
|
case PCIT:
|
|
switch ((DescriptorTag)da.getData<DescriptorHeader>()->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;
|
|
default: ; // unknown domain, nothing to do
|
|
}
|
|
d->setData(da);
|
|
return d;
|
|
}
|
|
|
|
} //end of namespace
|