00001
00002
00003 #include "dishdescriptors.h"
00004 #include "atsc_huffman.h"
00005 #include "programinfo.h"
00006 #include "dvbtables.h"
00007
00008 QString DishEventNameDescriptor::Name(uint compression_type) const
00009 {
00010 if (!HasName())
00011 return QString::null;
00012
00013 return atsc_huffman2_to_string(
00014 _data + 3, DescriptorLength() - 1, compression_type);
00015 }
00016
00017 const unsigned char *DishEventDescriptionDescriptor::DescriptionRaw(void) const
00018 {
00019 if (DescriptorLength() <= 2)
00020 return NULL;
00021
00022 bool offset = (_data[3] & 0xf8) == 0x80;
00023 return _data + ((offset) ? 4 : 3);
00024 }
00025
00026 uint DishEventDescriptionDescriptor::DescriptionRawLength(void) const
00027 {
00028 if (DescriptorLength() <= 2)
00029 return 0;
00030
00031 bool offset = (_data[3] & 0xf8) == 0x80;
00032 return DescriptorLength() - ((offset) ? 2 : 1);
00033 }
00034
00035 QString DishEventDescriptionDescriptor::Description(
00036 uint compression_type) const
00037 {
00038 const unsigned char *raw = DescriptionRaw();
00039 uint len = DescriptionRawLength();
00040
00041 if (raw && len)
00042 return atsc_huffman2_to_string(raw, len, compression_type);
00043
00044 return QString::null;
00045 }
00046
00047 bool DishEventPropertiesDescriptor::decompressed = false;
00048 uint DishEventPropertiesDescriptor::subtitle_props = SUB_UNKNOWN;
00049 uint DishEventPropertiesDescriptor::audio_props = AUD_UNKNOWN;
00050
00051 uint DishEventPropertiesDescriptor::SubtitleProperties(uint compression_type) const
00052 {
00053 decompress_properties(compression_type);
00054
00055 return subtitle_props;
00056 }
00057
00058 uint DishEventPropertiesDescriptor::AudioProperties(uint compression_type) const
00059 {
00060 decompress_properties(compression_type);
00061
00062 return audio_props;
00063 }
00064
00065 void DishEventPropertiesDescriptor::decompress_properties(uint compression_type) const
00066 {
00067 subtitle_props = SUB_UNKNOWN;
00068 audio_props = AUD_UNKNOWN;
00069
00070 if (HasProperties())
00071 {
00072 QString properties_raw = atsc_huffman2_to_string(
00073 _data + 4, DescriptorLength() - 2, compression_type);
00074
00075 if (properties_raw.contains("6|CC"))
00076 subtitle_props |= SUB_HARDHEAR;
00077
00078 if (properties_raw.contains("7|Stereo"))
00079 audio_props |= AUD_STEREO;
00080 }
00081 }
00082
00083 QString DishEventTagsDescriptor::programid(void) const
00084 {
00085 QString prefix = QString("");
00086
00087 if (DescriptorLength() != 8)
00088 return QString::null;
00089
00090 QString series = seriesid();
00091 series.remove(0, 2);
00092
00093 uint episode = ((_data[6] & 0x3f) << 0x08) | _data[7];
00094
00095 if (_data[2] == 0x7c)
00096 prefix = "MV";
00097 else if (_data[2] == 0x7d)
00098 prefix = "SP";
00099 else if (_data[2] == 0x7e)
00100 {
00101 if (episode > 0)
00102 prefix = "EP";
00103 else
00104 prefix = "SH";
00105 } else
00106 return prefix;
00107
00108 QString id = QString("%1%2%3").arg(prefix).arg(series).arg(episode, 4, 0);
00109
00110 return id;
00111 }
00112
00113 QString DishEventTagsDescriptor::seriesid(void) const
00114 {
00115 QString prefix = QString("");
00116
00117 if (DescriptorLength() != 8)
00118 return QString::null;
00119
00120 if (_data[2] == 0x7c)
00121 prefix = "MV";
00122 else if (_data[2] == 0x7d)
00123 prefix = "SP";
00124 else if (_data[2] == 0x7e)
00125 prefix = "EP";
00126 else
00127 return prefix;
00128
00129 uint series = (_data[3] << 0x12) | (_data[4] << 0x0a) | (_data[5] << 0x02) |
00130 ((_data[6] & 0xc0) >> 0x06);
00131
00132 QString id = QString("%1%2").arg(prefix).arg(series, 8, 0);
00133
00134 return id;
00135 }
00136
00137 QDate DishEventTagsDescriptor::originalairdate(void) const
00138 {
00139 unsigned char mjd[5];
00140
00141 if (DescriptorLength() != 8)
00142 return QDate();
00143
00144 mjd[0] = _data[8];
00145 mjd[1] = _data[9];
00146 mjd[2] = 0;
00147 mjd[3] = 0;
00148 mjd[4] = 0;
00149
00150 QDateTime t = dvbdate2qt(mjd);
00151
00152 if (!t.isValid())
00153 return QDate();
00154
00155 QDate originalairdate = t.date();
00156
00157 if (originalairdate.year() < 1940)
00158 return QDate();
00159
00160 return originalairdate;
00161 }
00162
00163 QMutex DishEventMPAADescriptor::mpaaRatingsLock;
00164 QMap<uint,QString> DishEventMPAADescriptor::mpaaRatingsDesc;
00165 bool DishEventMPAADescriptor::mpaaRatingsExists = false;
00166
00167 float DishEventMPAADescriptor::stars(void) const
00168 {
00169 switch(stars_raw())
00170 {
00171 case 0x01: return 1.0 / 4;
00172 case 0x02: return 1.5 / 4;
00173 case 0x03: return 2.0 / 4;
00174 case 0x04: return 2.5 / 4;
00175 case 0x05: return 3.0 / 4;
00176 case 0x06: return 3.5 / 4;
00177 case 0x07: return 4.0 / 4;
00178 }
00179
00180 return 0.0;
00181 }
00182
00183 QString DishEventMPAADescriptor::rating(void) const
00184 {
00185 if (!mpaaRatingsExists)
00186 Init();
00187
00188 QMutexLocker locker(&mpaaRatingsLock);
00189
00190 QMap<uint,QString>::const_iterator it = mpaaRatingsDesc.find(rating_raw());
00191 if (it != mpaaRatingsDesc.end())
00192 return *it;
00193
00194
00195 return "";
00196 }
00197
00198 QString DishEventMPAADescriptor::advisory(void) const
00199 {
00200 int advisory = advisory_raw();
00201 QStringList advisories;
00202
00203 if (advisory & 0x01)
00204 advisories.append("S");
00205 if (advisory & 0x02)
00206 advisories.append("L");
00207 if (advisory & 0x04)
00208 advisories.append("mQ");
00209 if (advisory & 0x08)
00210 advisories.append("FV");
00211 if (advisory & 0x10)
00212 advisories.append("V");
00213 if (advisory & 0x20)
00214 advisories.append("mK");
00215 if (advisory & 0x40)
00216 advisories.append("N");
00217
00218 return advisories.join(",");
00219 }
00220
00221 void DishEventMPAADescriptor::Init(void)
00222 {
00223 QMutexLocker locker(&mpaaRatingsLock);
00224
00225 if (mpaaRatingsExists)
00226 return;
00227
00228 mpaaRatingsDesc[0x01] = "G";
00229 mpaaRatingsDesc[0x02] = "PG";
00230 mpaaRatingsDesc[0x03] = "PG-13";
00231 mpaaRatingsDesc[0x04] = "R";
00232 mpaaRatingsDesc[0x05] = "NC-17";
00233 mpaaRatingsDesc[0x06] = "NR";
00234
00235 mpaaRatingsExists = true;
00236 }
00237
00238 QMutex DishEventVCHIPDescriptor::vchipRatingsLock;
00239 QMap<uint,QString> DishEventVCHIPDescriptor::vchipRatingsDesc;
00240 bool DishEventVCHIPDescriptor::vchipRatingsExists = false;
00241
00242 QString DishEventVCHIPDescriptor::rating(void) const
00243 {
00244 if (!vchipRatingsExists)
00245 Init();
00246
00247 QMutexLocker locker(&vchipRatingsLock);
00248
00249 QMap<uint,QString>::const_iterator it = vchipRatingsDesc.find(rating_raw());
00250 if (it != vchipRatingsDesc.end())
00251 return *it;
00252
00253
00254 return "";
00255 }
00256
00257 QString DishEventVCHIPDescriptor::advisory(void) const
00258 {
00259 int advisory = advisory_raw();
00260 QStringList advisories;
00261
00262 if (advisory & 0x01)
00263 advisories.append("FV");
00264 if (advisory & 0x02)
00265 advisories.append("V");
00266 if (advisory & 0x04)
00267 advisories.append("S");
00268 if (advisory & 0x08)
00269 advisories.append("L");
00270 if (advisory & 0x10)
00271 advisories.append("D");
00272
00273 return advisories.join(",");
00274 }
00275
00276 void DishEventVCHIPDescriptor::Init(void)
00277 {
00278 QMutexLocker locker(&vchipRatingsLock);
00279
00280 if (vchipRatingsExists)
00281 return;
00282
00283 vchipRatingsDesc[0x01] = "TV-Y";
00284 vchipRatingsDesc[0x02] = "TV-Y7";
00285 vchipRatingsDesc[0x03] = "TV-G";
00286 vchipRatingsDesc[0x04] = "TV-PG";
00287 vchipRatingsDesc[0x05] = "TV-14";
00288 vchipRatingsDesc[0x06] = "TV-MA";
00289
00290 vchipRatingsExists = true;
00291 }
00292
00293 QMap<uint,QString> DishContentDescriptor::themeDesc;
00294 QMap<uint,QString> DishContentDescriptor::dishCategoryDesc;
00295 volatile bool DishContentDescriptor::dishCategoryDescExists = false;
00296
00297 QString dish_theme_type_to_string(uint theme_type)
00298 {
00299 static const char *themes[kThemeLast] =
00300 {
00301 "", "Movie", "Sports", "News/Business", "Family/Children", "Education",
00302 "Series/Special", "Music/Art", "Religious", "Off-Air"
00303 };
00304
00305 if ((theme_type > kThemeNone) && (theme_type < kThemeLast))
00306 return QString(themes[theme_type]);
00307
00308 return "";
00309 }
00310
00311 DishThemeType string_to_dish_theme_type(const QString &theme_type)
00312 {
00313 static const char *themes[kThemeLast] =
00314 {
00315 "", "Movie", "Sports", "News/Business", "Family/Children", "Education",
00316 "Series/Special", "Music/Art", "Religious", "Off-Air"
00317 };
00318
00319 for (uint i = 1; i < 10; i++)
00320 if (theme_type == themes[i])
00321 return (DishThemeType) i;
00322
00323 return kThemeNone;
00324 }
00325
00326 DishThemeType DishContentDescriptor::GetTheme(void) const
00327 {
00328 if (!dishCategoryDescExists)
00329 Init();
00330
00331 if (Nibble1(0) == 0x00)
00332 return kThemeOffAir;
00333
00334 QMap<uint,QString>::const_iterator it = themeDesc.find(Nibble2(0));
00335 if (it != themeDesc.end())
00336 return string_to_dish_theme_type(*it);
00337
00338
00339 return kThemeNone;
00340 }
00341
00342 QString DishContentDescriptor::GetCategory(void) const
00343 {
00344 if (!dishCategoryDescExists)
00345 Init();
00346
00347 QMutexLocker locker(&categoryLock);
00348
00349
00350 QMap<uint,QString>::const_iterator it =
00351 dishCategoryDesc.find(UserNibble(0));
00352 if (it != dishCategoryDesc.end())
00353 return *it;
00354
00355
00356 QString theme = dish_theme_type_to_string(GetTheme());
00357
00358 return theme;
00359 }
00360
00361 QString DishContentDescriptor::toString() const
00362 {
00363 return QString("%1 : %2").arg(int(GetTheme())).arg(GetCategory());
00364 }
00365
00366 void DishContentDescriptor::Init(void)
00367 {
00368 ContentDescriptor::Init();
00369
00370 QMutexLocker locker(&categoryLock);
00371
00372 if (dishCategoryDescExists)
00373 return;
00374
00375
00376 themeDesc[kThemeMovie] = "Movie";
00377 themeDesc[kThemeSports] = "Sports";
00378 themeDesc[kThemeNews] = "News/Business";
00379 themeDesc[kThemeFamily] = "Family/Children";
00380 themeDesc[kThemeEducation] = "Education";
00381 themeDesc[kThemeSeries] = "Series/Special";
00382 themeDesc[kThemeMusic] = "Music/Art";
00383 themeDesc[kThemeReligious] = "Religious";
00384
00385
00386 dishCategoryDesc[0x01] = "Action";
00387 dishCategoryDesc[0x02] = "Adults only";
00388 dishCategoryDesc[0x03] = "Adventure";
00389 dishCategoryDesc[0x04] = "Animals";
00390 dishCategoryDesc[0x05] = "Animated";
00391 dishCategoryDesc[0x07] = "Anthology";
00392 dishCategoryDesc[0x08] = "Art";
00393 dishCategoryDesc[0x09] = "Auto";
00394 dishCategoryDesc[0x0a] = "Awards";
00395 dishCategoryDesc[0x0b] = "Ballet";
00396 dishCategoryDesc[0x0c] = "Baseball";
00397 dishCategoryDesc[0x0d] = "Basketball";
00398 dishCategoryDesc[0x11] = "Biography";
00399 dishCategoryDesc[0x12] = "Boat";
00400 dishCategoryDesc[0x14] = "Bowling";
00401 dishCategoryDesc[0x15] = "Boxing";
00402 dishCategoryDesc[0x16] = "Bus./financial";
00403 dishCategoryDesc[0x1a] = "Children";
00404 dishCategoryDesc[0x1b] = "Children-special";
00405 dishCategoryDesc[0x1c] = "Children-news";
00406 dishCategoryDesc[0x1d] = "Children-music";
00407 dishCategoryDesc[0x1f] = "Collectibles";
00408 dishCategoryDesc[0x20] = "Comedy";
00409 dishCategoryDesc[0x21] = "Comedy-drama";
00410 dishCategoryDesc[0x22] = "Computers";
00411 dishCategoryDesc[0x23] = "Cooking";
00412 dishCategoryDesc[0x24] = "Crime";
00413 dishCategoryDesc[0x25] = "Crime drama";
00414 dishCategoryDesc[0x27] = "Dance";
00415 dishCategoryDesc[0x29] = "Docudrama";
00416 dishCategoryDesc[0x2a] = "Documentary";
00417 dishCategoryDesc[0x2b] = "Drama";
00418 dishCategoryDesc[0x2c] = "Educational";
00419 dishCategoryDesc[0x2f] = "Excercise";
00420 dishCategoryDesc[0x31] = "Fantasy";
00421 dishCategoryDesc[0x32] = "Fasion";
00422 dishCategoryDesc[0x34] = "Fishing";
00423 dishCategoryDesc[0x35] = "Football";
00424 dishCategoryDesc[0x36] = "French";
00425 dishCategoryDesc[0x37] = "Fundraiser";
00426 dishCategoryDesc[0x38] = "Game show";
00427 dishCategoryDesc[0x39] = "Golf";
00428 dishCategoryDesc[0x3a] = "Gymnastics";
00429 dishCategoryDesc[0x3b] = "Health";
00430 dishCategoryDesc[0x3c] = "History";
00431 dishCategoryDesc[0x3d] = "Historical drama";
00432 dishCategoryDesc[0x3e] = "Hockey";
00433 dishCategoryDesc[0x3f] = "Holiday";
00434 dishCategoryDesc[0x40] = "Holiday-children";
00435 dishCategoryDesc[0x41] = "Holiday-children special";
00436 dishCategoryDesc[0x44] = "Holiday special";
00437 dishCategoryDesc[0x45] = "Horror";
00438 dishCategoryDesc[0x46] = "Horse racing";
00439 dishCategoryDesc[0x47] = "House/garden";
00440 dishCategoryDesc[0x49] = "How-to";
00441 dishCategoryDesc[0x4b] = "Interview";
00442 dishCategoryDesc[0x4d] = "Lacrosse";
00443 dishCategoryDesc[0x4f] = "Martial Arts";
00444 dishCategoryDesc[0x50] = "Medical";
00445 dishCategoryDesc[0x51] = "Miniseries";
00446 dishCategoryDesc[0x52] = "Motorsports";
00447 dishCategoryDesc[0x53] = "Motorcycle";
00448 dishCategoryDesc[0x54] = "Music";
00449 dishCategoryDesc[0x55] = "Music special";
00450 dishCategoryDesc[0x56] = "Music talk";
00451 dishCategoryDesc[0x57] = "Musical";
00452 dishCategoryDesc[0x58] = "Musical comedy";
00453 dishCategoryDesc[0x5a] = "Mystery";
00454 dishCategoryDesc[0x5b] = "Nature";
00455 dishCategoryDesc[0x5c] = "News";
00456 dishCategoryDesc[0x5f] = "Opera";
00457 dishCategoryDesc[0x60] = "Outdoors";
00458 dishCategoryDesc[0x63] = "Public affairs";
00459 dishCategoryDesc[0x66] = "Reality";
00460 dishCategoryDesc[0x67] = "Religious";
00461 dishCategoryDesc[0x68] = "Rodeo";
00462 dishCategoryDesc[0x69] = "Romance";
00463 dishCategoryDesc[0x6a] = "Romance-comedy";
00464 dishCategoryDesc[0x6b] = "Rugby";
00465 dishCategoryDesc[0x6c] = "Running";
00466 dishCategoryDesc[0x6e] = "Science";
00467 dishCategoryDesc[0x6f] = "Science fiction";
00468 dishCategoryDesc[0x70] = "Self improvement";
00469 dishCategoryDesc[0x71] = "Shopping";
00470 dishCategoryDesc[0x74] = "Skiing";
00471 dishCategoryDesc[0x77] = "Soap";
00472 dishCategoryDesc[0x7b] = "Soccor";
00473 dishCategoryDesc[0x7c] = "Softball";
00474 dishCategoryDesc[0x7d] = "Spanish";
00475 dishCategoryDesc[0x7e] = "Special";
00476 dishCategoryDesc[0x81] = "Sports non-event";
00477 dishCategoryDesc[0x82] = "Sports talk";
00478 dishCategoryDesc[0x83] = "Suspense";
00479 dishCategoryDesc[0x85] = "Swimming";
00480 dishCategoryDesc[0x86] = "Talk";
00481 dishCategoryDesc[0x87] = "Tennis";
00482 dishCategoryDesc[0x89] = "Track/field";
00483 dishCategoryDesc[0x8a] = "Travel";
00484 dishCategoryDesc[0x8b] = "Variety";
00485 dishCategoryDesc[0x8c] = "Volleyball";
00486 dishCategoryDesc[0x8d] = "War";
00487 dishCategoryDesc[0x8e] = "Watersports";
00488 dishCategoryDesc[0x8f] = "Weather";
00489 dishCategoryDesc[0x90] = "Western";
00490 dishCategoryDesc[0x92] = "Wrestling";
00491 dishCategoryDesc[0x93] = "Yoga";
00492 dishCategoryDesc[0x94] = "Agriculture";
00493 dishCategoryDesc[0x95] = "Anime";
00494 dishCategoryDesc[0x97] = "Arm Wrestling";
00495 dishCategoryDesc[0x98] = "Arts/crafts";
00496 dishCategoryDesc[0x99] = "Auction";
00497 dishCategoryDesc[0x9a] = "Auto racing";
00498 dishCategoryDesc[0x9b] = "Air racing";
00499 dishCategoryDesc[0x9c] = "Badminton";
00500 dishCategoryDesc[0xa0] = "Bicycle racing";
00501 dishCategoryDesc[0xa1] = "Boat Racing";
00502 dishCategoryDesc[0xa6] = "Community";
00503 dishCategoryDesc[0xa7] = "Consumer";
00504 dishCategoryDesc[0xaa] = "Debate";
00505 dishCategoryDesc[0xac] = "Dog show";
00506 dishCategoryDesc[0xad] = "Drag racing";
00507 dishCategoryDesc[0xae] = "Entertainment";
00508 dishCategoryDesc[0xaf] = "Environment";
00509 dishCategoryDesc[0xb0] = "Equestrian";
00510 dishCategoryDesc[0xb3] = "Field hockey";
00511 dishCategoryDesc[0xb5] = "Football";
00512 dishCategoryDesc[0xb6] = "Gay/lesbian";
00513 dishCategoryDesc[0xb7] = "Handball";
00514 dishCategoryDesc[0xb8] = "Home improvement";
00515 dishCategoryDesc[0xb9] = "Hunting";
00516 dishCategoryDesc[0xbb] = "Hydroplane racing";
00517 dishCategoryDesc[0xc1] = "Law";
00518 dishCategoryDesc[0xc3] = "Motorcycle racing";
00519 dishCategoryDesc[0xc5] = "Newsmagazine";
00520 dishCategoryDesc[0xc7] = "Paranormal";
00521 dishCategoryDesc[0xc8] = "Parenting";
00522 dishCategoryDesc[0xca] = "Performing arts";
00523 dishCategoryDesc[0xcc] = "Politics";
00524 dishCategoryDesc[0xcf] = "Pro wrestling";
00525 dishCategoryDesc[0xd3] = "Sailing";
00526 dishCategoryDesc[0xd4] = "Shooting";
00527 dishCategoryDesc[0xd5] = "Sitcom";
00528 dishCategoryDesc[0xd6] = "Skateboarding";
00529 dishCategoryDesc[0xd9] = "Snowboarding";
00530 dishCategoryDesc[0xdd] = "Standup";
00531 dishCategoryDesc[0xdf] = "Surfing";
00532 dishCategoryDesc[0xe0] = "Tennis";
00533 dishCategoryDesc[0xe1] = "Triathlon";
00534 dishCategoryDesc[0xe6] = "Card games";
00535 dishCategoryDesc[0xe7] = "Poker";
00536 dishCategoryDesc[0xea] = "Military";
00537 dishCategoryDesc[0xeb] = "Technology";
00538 dishCategoryDesc[0xec] = "Mixed martial arts";
00539 dishCategoryDesc[0xed] = "Action sports";
00540 dishCategoryDesc[0xff] = "Dish Network";
00541
00542 dishCategoryDescExists = true;
00543 }
00544
00545