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.c 2.6 2011/12/10 15:47:15 kls Exp $ 00010 * * 00011 ***************************************************************************/ 00012 00013 #include "si.h" 00014 #include <errno.h> 00015 #include <iconv.h> 00016 #include <malloc.h> 00017 #include <stdlib.h> // for broadcaster stupidity workaround 00018 #include <string.h> 00019 #include "descriptor.h" 00020 00021 namespace SI { 00022 00023 Object::Object() { 00024 } 00025 00026 Object::Object(CharArray &d) : data(d) { 00027 } 00028 00029 void Object::setData(const unsigned char*d, int size, bool doCopy) { 00030 data.assign(d, size, doCopy); 00031 } 00032 00033 void Object::setData(CharArray &d) { 00034 data=d; 00035 } 00036 00037 bool Object::checkSize(int offset) { 00038 return data.checkSize(offset); 00039 } 00040 00041 Section::Section(const unsigned char *data, bool doCopy) { 00042 setData(data, getLength(data), doCopy); 00043 } 00044 00045 TableId Section::getTableId() const { 00046 return getTableId(data.getData()); 00047 } 00048 00049 int Section::getLength() { 00050 return getLength(data.getData()); 00051 } 00052 00053 TableId Section::getTableId(const unsigned char *d) { 00054 return (TableId)((const SectionHeader *)d)->table_id; 00055 } 00056 00057 int Section::getLength(const unsigned char *d) { 00058 return HILO(((const SectionHeader *)d)->section_length)+sizeof(SectionHeader); 00059 } 00060 00061 bool CRCSection::isCRCValid() { 00062 return CRC32::isValid((const char *)data.getData(), getLength()/*, data.FourBytes(getLength()-4)*/); 00063 } 00064 00065 bool CRCSection::CheckCRCAndParse() { 00066 if (!isCRCValid()) 00067 return false; 00068 CheckParse(); 00069 return isValid(); 00070 } 00071 00072 int NumberedSection::getTableIdExtension() const { 00073 return getTableIdExtension(data.getData()); 00074 } 00075 00076 int NumberedSection::getTableIdExtension(const unsigned char *d) { 00077 return HILO(((const ExtendedSectionHeader *)d)->table_id_extension); 00078 } 00079 00080 bool NumberedSection::getCurrentNextIndicator() const { 00081 return data.getData<ExtendedSectionHeader>()->current_next_indicator; 00082 } 00083 00084 int NumberedSection::getVersionNumber() const { 00085 return data.getData<ExtendedSectionHeader>()->version_number; 00086 } 00087 00088 int NumberedSection::getSectionNumber() const { 00089 return data.getData<ExtendedSectionHeader>()->section_number; 00090 } 00091 00092 int NumberedSection::getLastSectionNumber() const { 00093 return data.getData<ExtendedSectionHeader>()->last_section_number; 00094 } 00095 00096 int Descriptor::getLength() { 00097 return getLength(data.getData()); 00098 } 00099 00100 DescriptorTag Descriptor::getDescriptorTag() const { 00101 return getDescriptorTag(data.getData()); 00102 } 00103 00104 int Descriptor::getLength(const unsigned char *d) { 00105 return ((const DescriptorHeader*)d)->descriptor_length+sizeof(DescriptorHeader); 00106 } 00107 00108 DescriptorTag Descriptor::getDescriptorTag(const unsigned char *d) { 00109 return (DescriptorTag)((const DescriptorHeader*)d)->descriptor_tag; 00110 } 00111 00112 Descriptor *DescriptorLoop::getNext(Iterator &it) { 00113 if (isValid() && it.i<getLength()) { 00114 return createDescriptor(it.i, true); 00115 } 00116 return 0; 00117 } 00118 00119 Descriptor *DescriptorLoop::getNext(Iterator &it, DescriptorTag tag, bool returnUnimplemetedDescriptor) { 00120 Descriptor *d=0; 00121 int len; 00122 if (isValid() && it.i<(len=getLength())) { 00123 const unsigned char *p=data.getData(it.i); 00124 const unsigned char *end=p+len-it.i; 00125 while (p < end) { 00126 if (Descriptor::getDescriptorTag(p) == tag) { 00127 d=createDescriptor(it.i, returnUnimplemetedDescriptor); 00128 if (d) 00129 break; 00130 } 00131 it.i+=Descriptor::getLength(p); 00132 p+=Descriptor::getLength(p); 00133 } 00134 } 00135 return d; 00136 } 00137 00138 Descriptor *DescriptorLoop::getNext(Iterator &it, DescriptorTag *tags, int arrayLength, bool returnUnimplementedDescriptor) { 00139 Descriptor *d=0; 00140 int len; 00141 if (isValid() && it.i<(len=getLength())) { 00142 const unsigned char *p=data.getData(it.i); 00143 const unsigned char *end=p+len-it.i; 00144 while (p < end) { 00145 for (int u=0; u<arrayLength;u++) 00146 if (Descriptor::getDescriptorTag(p) == tags[u]) { 00147 d=createDescriptor(it.i, returnUnimplementedDescriptor); 00148 break; 00149 } 00150 if (d) 00151 break; //length is added to it.i by createDescriptor, break here 00152 it.i+=Descriptor::getLength(p); 00153 p+=Descriptor::getLength(p); 00154 } 00155 } 00156 return d; 00157 } 00158 00159 Descriptor *DescriptorLoop::createDescriptor(int &i, bool returnUnimplemetedDescriptor) { 00160 if (!checkSize(Descriptor::getLength(data.getData(i)))) 00161 return 0; 00162 Descriptor *d=Descriptor::getDescriptor(data+i, domain, returnUnimplemetedDescriptor); 00163 if (!d) 00164 return 0; 00165 i+=d->getLength(); 00166 d->CheckParse(); 00167 return d; 00168 } 00169 00170 int DescriptorLoop::getNumberOfDescriptors() { 00171 const unsigned char *p=data.getData(); 00172 const unsigned char *end=p+getLength(); 00173 int count=0; 00174 while (p < end) { 00175 count++; 00176 p+=Descriptor::getLength(p); 00177 } 00178 return count; 00179 } 00180 00181 DescriptorGroup::DescriptorGroup(bool del) { 00182 array=0; 00183 length=0; 00184 deleteOnDesctruction=del; 00185 } 00186 00187 DescriptorGroup::~DescriptorGroup() { 00188 if (deleteOnDesctruction) 00189 Delete(); 00190 delete[] array; 00191 } 00192 00193 void DescriptorGroup::Delete() { 00194 for (int i=0;i<length;i++) 00195 if (array[i]!=0) { 00196 delete array[i]; 00197 array[i]=0; 00198 } 00199 } 00200 00201 void DescriptorGroup::Add(GroupDescriptor *d) { 00202 if (!array) { 00203 length=d->getLastDescriptorNumber()+1; 00204 array=new GroupDescriptor*[length]; //numbering is zero-based 00205 for (int i=0;i<length;i++) 00206 array[i]=0; 00207 } else if (length != d->getLastDescriptorNumber()+1) 00208 return; //avoid crash in case of misuse 00209 if (length <= d->getDescriptorNumber()) 00210 return; // see http://www.vdr-portal.de/board60-linux/board14-betriebssystem/board69-c-t-vdr/p1025777-segfault-mit-vdr-1-7-21/#post1025777 00211 array[d->getDescriptorNumber()]=d; 00212 } 00213 00214 bool DescriptorGroup::isComplete() { 00215 for (int i=0;i<length;i++) 00216 if (array[i]==0) 00217 return false; 00218 return true; 00219 } 00220 00221 char *String::getText() { 00222 int len=getLength(); 00223 if (len < 0 || len > 4095) 00224 return strdup("text error"); // caller will delete it! 00225 char *data=new char(len+1); // FIXME If this function is ever actually used, this buffer might 00226 // need to be bigger in order to hold the string as UTF-8. 00227 // Maybe decodeText should dynamically handle this? kls 2007-06-10 00228 decodeText(data, len+1); 00229 return data; 00230 } 00231 00232 char *String::getText(char *buffer, int size) { 00233 int len=getLength(); 00234 if (len < 0 || len >= size) { 00235 strncpy(buffer, "text error", size); 00236 buffer[size-1] = 0; 00237 return buffer; 00238 } 00239 decodeText(buffer, size); 00240 return buffer; 00241 } 00242 00243 char *String::getText(char *buffer, char *shortVersion, int sizeBuffer, int sizeShortVersion) { 00244 int len=getLength(); 00245 if (len < 0 || len >= sizeBuffer) { 00246 strncpy(buffer, "text error", sizeBuffer); 00247 buffer[sizeBuffer-1] = 0; 00248 *shortVersion = 0; 00249 return buffer; 00250 } 00251 decodeText(buffer, shortVersion, sizeBuffer, sizeShortVersion); 00252 return buffer; 00253 } 00254 00255 static const char *CharacterTables1[] = { 00256 NULL, // 0x00 00257 "ISO-8859-5", // 0x01 00258 "ISO-8859-6", // 0x02 00259 "ISO-8859-7", // 0x03 00260 "ISO-8859-8", // 0x04 00261 "ISO-8859-9", // 0x05 00262 "ISO-8859-10", // 0x06 00263 "ISO-8859-11", // 0x07 00264 "ISO-8859-12", // 0x08 00265 "ISO-8859-13", // 0x09 00266 "ISO-8859-14", // 0x0A 00267 "ISO-8859-15", // 0x0B 00268 NULL, // 0x0C 00269 NULL, // 0x0D 00270 NULL, // 0x0E 00271 NULL, // 0x0F 00272 NULL, // 0x10 00273 "UTF-16", // 0x11 00274 "EUC-KR", // 0x12 00275 "GB2312", // 0x13 00276 "GBK", // 0x14 00277 "UTF-8", // 0x15 00278 NULL, // 0x16 00279 NULL, // 0x17 00280 NULL, // 0x18 00281 NULL, // 0x19 00282 NULL, // 0x1A 00283 NULL, // 0x1B 00284 NULL, // 0x1C 00285 NULL, // 0x1D 00286 NULL, // 0x1E 00287 NULL, // 0x1F 00288 }; 00289 00290 #define SingleByteLimit 0x0B 00291 00292 static const char *CharacterTables2[] = { 00293 NULL, // 0x00 00294 "ISO-8859-1", // 0x01 00295 "ISO-8859-2", // 0x02 00296 "ISO-8859-3", // 0x03 00297 "ISO-8859-4", // 0x04 00298 "ISO-8859-5", // 0x05 00299 "ISO-8859-6", // 0x06 00300 "ISO-8859-7", // 0x07 00301 "ISO-8859-8", // 0x08 00302 "ISO-8859-9", // 0x09 00303 "ISO-8859-10", // 0x0A 00304 "ISO-8859-11", // 0x0B 00305 NULL, // 0x0C 00306 "ISO-8859-13", // 0x0D 00307 "ISO-8859-14", // 0x0E 00308 "ISO-8859-15", // 0x0F 00309 }; 00310 00311 #define NumEntries(Table) (sizeof(Table) / sizeof(char *)) 00312 00313 static const char *SystemCharacterTable = NULL; 00314 bool SystemCharacterTableIsSingleByte = true; 00315 00316 bool systemCharacterTableIsSingleByte(void) 00317 { 00318 return SystemCharacterTableIsSingleByte; 00319 } 00320 00321 bool SetSystemCharacterTable(const char *CharacterTable) { 00322 if (CharacterTable) { 00323 for (unsigned int i = 0; i < NumEntries(CharacterTables1); i++) { 00324 if (CharacterTables1[i] && strcasecmp(CharacterTable, CharacterTables1[i]) == 0) { 00325 SystemCharacterTable = CharacterTables1[i]; 00326 SystemCharacterTableIsSingleByte = i <= SingleByteLimit; 00327 return true; 00328 } 00329 } 00330 for (unsigned int i = 0; i < NumEntries(CharacterTables2); i++) { 00331 if (CharacterTables2[i] && strcasecmp(CharacterTable, CharacterTables2[i]) == 0) { 00332 SystemCharacterTable = CharacterTables2[i]; 00333 SystemCharacterTableIsSingleByte = true; 00334 return true; 00335 } 00336 } 00337 } else { 00338 SystemCharacterTable = NULL; 00339 SystemCharacterTableIsSingleByte = true; 00340 return true; 00341 } 00342 return false; 00343 } 00344 00345 const char *getCharacterTable(const unsigned char *&buffer, int &length, bool *isSingleByte) { 00346 const char *cs = "ISO6937"; 00347 // Workaround for broadcaster stupidity: according to 00348 // "ETSI EN 300 468" the default character set is ISO6937. But unfortunately some 00349 // broadcasters actually use ISO-8859-9, but fail to correctly announce that. 00350 static const char *CharsetOverride = getenv("VDR_CHARSET_OVERRIDE"); 00351 if (CharsetOverride) 00352 cs = CharsetOverride; 00353 if (isSingleByte) 00354 *isSingleByte = false; 00355 if (length <= 0) 00356 return cs; 00357 unsigned int tag = buffer[0]; 00358 if (tag >= 0x20) 00359 return cs; 00360 if (tag == 0x10) { 00361 if (length >= 3) { 00362 tag = (buffer[1] << 8) | buffer[2]; 00363 if (tag < NumEntries(CharacterTables2) && CharacterTables2[tag]) { 00364 buffer += 3; 00365 length -= 3; 00366 if (isSingleByte) 00367 *isSingleByte = true; 00368 return CharacterTables2[tag]; 00369 } 00370 } 00371 } else if (tag < NumEntries(CharacterTables1) && CharacterTables1[tag]) { 00372 buffer += 1; 00373 length -= 1; 00374 if (isSingleByte) 00375 *isSingleByte = tag <= SingleByteLimit; 00376 return CharacterTables1[tag]; 00377 } 00378 return cs; 00379 } 00380 00381 bool convertCharacterTable(const char *from, size_t fromLength, char *to, size_t toLength, const char *fromCode) 00382 { 00383 if (SystemCharacterTable) { 00384 iconv_t cd = iconv_open(SystemCharacterTable, fromCode); 00385 if (cd != (iconv_t)-1) { 00386 char *fromPtr = (char *)from; 00387 while (fromLength > 0 && toLength > 1) { 00388 if (iconv(cd, &fromPtr, &fromLength, &to, &toLength) == size_t(-1)) { 00389 if (errno == EILSEQ) { 00390 // A character can't be converted, so mark it with '?' and proceed: 00391 fromPtr++; 00392 fromLength--; 00393 *to++ = '?'; 00394 toLength--; 00395 } 00396 else 00397 break; 00398 } 00399 } 00400 *to = 0; 00401 iconv_close(cd); 00402 return true; 00403 } 00404 } 00405 return false; 00406 } 00407 00408 // originally from libdtv, Copyright Rolf Hakenes <hakenes@hippomi.de> 00409 void String::decodeText(char *buffer, int size) { 00410 const unsigned char *from=data.getData(0); 00411 char *to=buffer; 00412 int len=getLength(); 00413 if (len <= 0) { 00414 *to = '\0'; 00415 return; 00416 } 00417 bool singleByte; 00418 const char *cs = getCharacterTable(from, len, &singleByte); 00419 // FIXME Need to make this UTF-8 aware (different control codes). 00420 // However, there's yet to be found a broadcaster that actually 00421 // uses UTF-8 for the SI data... (kls 2007-06-10) 00422 for (int i = 0; i < len; i++) { 00423 if (*from == 0) 00424 break; 00425 if ( ((' ' <= *from) && (*from <= '~')) 00426 || (*from == '\n') 00427 || (0xA0 <= *from) 00428 ) 00429 *to++ = *from; 00430 else if (*from == 0x8A) 00431 *to++ = '\n'; 00432 from++; 00433 if (to - buffer >= size - 1) 00434 break; 00435 } 00436 *to = '\0'; 00437 if (!singleByte || !SystemCharacterTableIsSingleByte) { 00438 char convBuffer[size]; 00439 if (convertCharacterTable(buffer, strlen(buffer), convBuffer, sizeof(convBuffer), cs)) 00440 strncpy(buffer, convBuffer, strlen(convBuffer) + 1); 00441 } 00442 } 00443 00444 void String::decodeText(char *buffer, char *shortVersion, int sizeBuffer, int sizeShortVersion) { 00445 const unsigned char *from=data.getData(0); 00446 char *to=buffer; 00447 char *toShort=shortVersion; 00448 int IsShortName=0; 00449 int len=getLength(); 00450 if (len <= 0) { 00451 *to = '\0'; 00452 *toShort = '\0'; 00453 return; 00454 } 00455 bool singleByte; 00456 const char *cs = getCharacterTable(from, len, &singleByte); 00457 // FIXME Need to make this UTF-8 aware (different control codes). 00458 // However, there's yet to be found a broadcaster that actually 00459 // uses UTF-8 for the SI data... (kls 2007-06-10) 00460 for (int i = 0; i < len; i++) { 00461 if ( ((' ' <= *from) && (*from <= '~')) 00462 || (*from == '\n') 00463 || (0xA0 <= *from) 00464 ) 00465 { 00466 *to++ = *from; 00467 if (IsShortName) 00468 *toShort++ = *from; 00469 } 00470 else if (*from == 0x8A) 00471 *to++ = '\n'; 00472 else if (*from == 0x86) 00473 IsShortName++; 00474 else if (*from == 0x87) 00475 IsShortName--; 00476 else if (*from == 0) 00477 break; 00478 from++; 00479 if (to - buffer >= sizeBuffer - 1 || toShort - shortVersion >= sizeShortVersion - 1) 00480 break; 00481 } 00482 *to = '\0'; 00483 *toShort = '\0'; 00484 if (!singleByte || !SystemCharacterTableIsSingleByte) { 00485 char convBuffer[sizeBuffer]; 00486 if (convertCharacterTable(buffer, strlen(buffer), convBuffer, sizeof(convBuffer), cs)) 00487 strncpy(buffer, convBuffer, strlen(convBuffer) + 1); 00488 char convShortVersion[sizeShortVersion]; 00489 if (convertCharacterTable(shortVersion, strlen(shortVersion), convShortVersion, sizeof(convShortVersion), cs)) 00490 strncpy(shortVersion, convShortVersion, strlen(convShortVersion) + 1); 00491 } 00492 } 00493 00494 Descriptor *Descriptor::getDescriptor(CharArray da, DescriptorTagDomain domain, bool returnUnimplemetedDescriptor) { 00495 Descriptor *d=0; 00496 switch (domain) { 00497 case SI: 00498 switch ((DescriptorTag)da.getData<DescriptorHeader>()->descriptor_tag) { 00499 case CaDescriptorTag: 00500 d=new CaDescriptor(); 00501 break; 00502 case CarouselIdentifierDescriptorTag: 00503 d=new CarouselIdentifierDescriptor(); 00504 break; 00505 case NetworkNameDescriptorTag: 00506 d=new NetworkNameDescriptor(); 00507 break; 00508 case ServiceListDescriptorTag: 00509 d=new ServiceListDescriptor(); 00510 break; 00511 case SatelliteDeliverySystemDescriptorTag: 00512 d=new SatelliteDeliverySystemDescriptor(); 00513 break; 00514 case CableDeliverySystemDescriptorTag: 00515 d=new CableDeliverySystemDescriptor(); 00516 break; 00517 case TerrestrialDeliverySystemDescriptorTag: 00518 d=new TerrestrialDeliverySystemDescriptor(); 00519 break; 00520 case BouquetNameDescriptorTag: 00521 d=new BouquetNameDescriptor(); 00522 break; 00523 case ServiceDescriptorTag: 00524 d=new ServiceDescriptor(); 00525 break; 00526 case NVODReferenceDescriptorTag: 00527 d=new NVODReferenceDescriptor(); 00528 break; 00529 case TimeShiftedServiceDescriptorTag: 00530 d=new TimeShiftedServiceDescriptor(); 00531 break; 00532 case ComponentDescriptorTag: 00533 d=new ComponentDescriptor(); 00534 break; 00535 case StreamIdentifierDescriptorTag: 00536 d=new StreamIdentifierDescriptor(); 00537 break; 00538 case SubtitlingDescriptorTag: 00539 d=new SubtitlingDescriptor(); 00540 break; 00541 case MultilingualNetworkNameDescriptorTag: 00542 d=new MultilingualNetworkNameDescriptor(); 00543 break; 00544 case MultilingualBouquetNameDescriptorTag: 00545 d=new MultilingualBouquetNameDescriptor(); 00546 break; 00547 case MultilingualServiceNameDescriptorTag: 00548 d=new MultilingualServiceNameDescriptor(); 00549 break; 00550 case MultilingualComponentDescriptorTag: 00551 d=new MultilingualComponentDescriptor(); 00552 break; 00553 case PrivateDataSpecifierDescriptorTag: 00554 d=new PrivateDataSpecifierDescriptor(); 00555 break; 00556 case ServiceMoveDescriptorTag: 00557 d=new ServiceMoveDescriptor(); 00558 break; 00559 case FrequencyListDescriptorTag: 00560 d=new FrequencyListDescriptor(); 00561 break; 00562 case ServiceIdentifierDescriptorTag: 00563 d=new ServiceIdentifierDescriptor(); 00564 break; 00565 case CaIdentifierDescriptorTag: 00566 d=new CaIdentifierDescriptor(); 00567 break; 00568 case ShortEventDescriptorTag: 00569 d=new ShortEventDescriptor(); 00570 break; 00571 case ExtendedEventDescriptorTag: 00572 d=new ExtendedEventDescriptor(); 00573 break; 00574 case TimeShiftedEventDescriptorTag: 00575 d=new TimeShiftedEventDescriptor(); 00576 break; 00577 case ContentDescriptorTag: 00578 d=new ContentDescriptor(); 00579 break; 00580 case ParentalRatingDescriptorTag: 00581 d=new ParentalRatingDescriptor(); 00582 break; 00583 case TeletextDescriptorTag: 00584 case VBITeletextDescriptorTag: 00585 d=new TeletextDescriptor(); 00586 break; 00587 case ApplicationSignallingDescriptorTag: 00588 d=new ApplicationSignallingDescriptor(); 00589 break; 00590 case LocalTimeOffsetDescriptorTag: 00591 d=new LocalTimeOffsetDescriptor(); 00592 break; 00593 case LinkageDescriptorTag: 00594 d=new LinkageDescriptor(); 00595 break; 00596 case ISO639LanguageDescriptorTag: 00597 d=new ISO639LanguageDescriptor(); 00598 break; 00599 case PDCDescriptorTag: 00600 d=new PDCDescriptor(); 00601 break; 00602 case AncillaryDataDescriptorTag: 00603 d=new AncillaryDataDescriptor(); 00604 break; 00605 case S2SatelliteDeliverySystemDescriptorTag: 00606 d=new S2SatelliteDeliverySystemDescriptor(); 00607 break; 00608 case ExtensionDescriptorTag: 00609 d=new ExtensionDescriptor(); 00610 break; 00611 case RegistrationDescriptorTag: 00612 d=new RegistrationDescriptor(); 00613 break; 00614 case ContentIdentifierDescriptorTag: 00615 d=new ContentIdentifierDescriptor(); 00616 break; 00617 case DefaultAuthorityDescriptorTag: 00618 d=new DefaultAuthorityDescriptor(); 00619 break; 00620 00621 //note that it is no problem to implement one 00622 //of the unimplemented descriptors. 00623 00624 //defined in ISO-13818-1 00625 case VideoStreamDescriptorTag: 00626 case AudioStreamDescriptorTag: 00627 case HierarchyDescriptorTag: 00628 case DataStreamAlignmentDescriptorTag: 00629 case TargetBackgroundGridDescriptorTag: 00630 case VideoWindowDescriptorTag: 00631 case SystemClockDescriptorTag: 00632 case MultiplexBufferUtilizationDescriptorTag: 00633 case CopyrightDescriptorTag: 00634 case MaximumBitrateDescriptorTag: 00635 case PrivateDataIndicatorDescriptorTag: 00636 case SmoothingBufferDescriptorTag: 00637 case STDDescriptorTag: 00638 case IBPDescriptorTag: 00639 00640 //defined in ETSI EN 300 468 00641 case StuffingDescriptorTag: 00642 case VBIDataDescriptorTag: 00643 case CountryAvailabilityDescriptorTag: 00644 case MocaicDescriptorTag: 00645 case TelephoneDescriptorTag: 00646 case CellListDescriptorTag: 00647 case CellFrequencyLinkDescriptorTag: 00648 case ServiceAvailabilityDescriptorTag: 00649 case ShortSmoothingBufferDescriptorTag: 00650 case PartialTransportStreamDescriptorTag: 00651 case DataBroadcastDescriptorTag: 00652 case DataBroadcastIdDescriptorTag: 00653 case ScramblingDescriptorTag: 00654 case AC3DescriptorTag: 00655 case DSNGDescriptorTag: 00656 case AnnouncementSupportDescriptorTag: 00657 case AdaptationFieldDataDescriptorTag: 00658 case TransportStreamDescriptorTag: 00659 00660 //defined in ETSI EN 300 468 v 1.7.1 00661 case RelatedContentDescriptorTag: 00662 case TVAIdDescriptorTag: 00663 case TimeSliceFecIdentifierDescriptorTag: 00664 case ECMRepetitionRateDescriptorTag: 00665 case EnhancedAC3DescriptorTag: 00666 case DTSDescriptorTag: 00667 case AACDescriptorTag: 00668 default: 00669 if (!returnUnimplemetedDescriptor) 00670 return 0; 00671 d=new UnimplementedDescriptor(); 00672 break; 00673 } 00674 break; 00675 case MHP: 00676 switch ((DescriptorTag)da.getData<DescriptorHeader>()->descriptor_tag) { 00677 // They once again start with 0x00 (see page 234, MHP specification) 00678 case MHP_ApplicationDescriptorTag: 00679 d=new MHP_ApplicationDescriptor(); 00680 break; 00681 case MHP_ApplicationNameDescriptorTag: 00682 d=new MHP_ApplicationNameDescriptor(); 00683 break; 00684 case MHP_TransportProtocolDescriptorTag: 00685 d=new MHP_TransportProtocolDescriptor(); 00686 break; 00687 case MHP_DVBJApplicationDescriptorTag: 00688 d=new MHP_DVBJApplicationDescriptor(); 00689 break; 00690 case MHP_DVBJApplicationLocationDescriptorTag: 00691 d=new MHP_DVBJApplicationLocationDescriptor(); 00692 break; 00693 case MHP_SimpleApplicationLocationDescriptorTag: 00694 d=new MHP_SimpleApplicationLocationDescriptor(); 00695 break; 00696 // 0x05 - 0x0A is unimplemented this library 00697 case MHP_ExternalApplicationAuthorisationDescriptorTag: 00698 case MHP_IPv4RoutingDescriptorTag: 00699 case MHP_IPv6RoutingDescriptorTag: 00700 case MHP_DVBHTMLApplicationDescriptorTag: 00701 case MHP_DVBHTMLApplicationLocationDescriptorTag: 00702 case MHP_DVBHTMLApplicationBoundaryDescriptorTag: 00703 case MHP_ApplicationIconsDescriptorTag: 00704 case MHP_PrefetchDescriptorTag: 00705 case MHP_DelegatedApplicationDescriptorTag: 00706 case MHP_ApplicationStorageDescriptorTag: 00707 default: 00708 if (!returnUnimplemetedDescriptor) 00709 return 0; 00710 d=new UnimplementedDescriptor(); 00711 break; 00712 } 00713 break; 00714 case PCIT: 00715 switch ((DescriptorTag)da.getData<DescriptorHeader>()->descriptor_tag) { 00716 case ContentDescriptorTag: 00717 d=new ContentDescriptor(); 00718 break; 00719 case ShortEventDescriptorTag: 00720 d=new ShortEventDescriptor(); 00721 break; 00722 case ExtendedEventDescriptorTag: 00723 d=new ExtendedEventDescriptor(); 00724 break; 00725 case PremiereContentTransmissionDescriptorTag: 00726 d=new PremiereContentTransmissionDescriptor(); 00727 break; 00728 default: 00729 if (!returnUnimplemetedDescriptor) 00730 return 0; 00731 d=new UnimplementedDescriptor(); 00732 break; 00733 } 00734 break; 00735 default: ; // unknown domain, nothing to do 00736 } 00737 d->setData(da); 00738 return d; 00739 } 00740 00741 } //end of namespace