00001 #include "dvbdescriptors.h"
00002 #include "iso6937tables.h"
00003 #include "freesat_huffman.h"
00004
00005 #include <unistd.h>
00006 #include <qtextcodec.h>
00007 #include <qdeepcopy.h>
00008
00009
00010
00011 static const QTextCodec *iso8859_codecs[16] =
00012 {
00013 QTextCodec::codecForName("Latin1"),
00014 QTextCodec::codecForName("ISO8859-1"),
00015 QTextCodec::codecForName("ISO8859-2"),
00016 QTextCodec::codecForName("ISO8859-3"),
00017 QTextCodec::codecForName("ISO8859-4"),
00018 QTextCodec::codecForName("ISO8859-5"),
00019 QTextCodec::codecForName("ISO8859-6"),
00020 QTextCodec::codecForName("ISO8859-7"),
00021 QTextCodec::codecForName("ISO8859-8"),
00022 QTextCodec::codecForName("ISO8859-9"),
00023 QTextCodec::codecForName("ISO8859-10"),
00024 QTextCodec::codecForName("ISO8859-11"),
00025 QTextCodec::codecForName("ISO8859-12"),
00026 QTextCodec::codecForName("ISO8859-13"),
00027 QTextCodec::codecForName("ISO8859-14"),
00028 QTextCodec::codecForName("ISO8859-15"),
00029 };
00030
00031 static QString decode_iso6937(const unsigned char *buf, uint length)
00032 {
00033
00034
00035 QString result = "";
00036 ushort ch = 0x20;
00037 for (uint i = 0; (i < length) && buf[i]; i++)
00038 {
00039 if (ch == 0xFFFF)
00040 {
00041
00042 ch = iso6937table_secondary[buf[i-1]][buf[i]];
00043 if (ch == 0xFFFF)
00044 {
00045
00046
00047 ch = iso6937table_base[buf[i]];
00048 if (ch == 0xFFFF)
00049 continue;
00050 }
00051 }
00052 else
00053 {
00054
00055
00056 ch = iso6937table_base[buf[i]];
00057 if (ch == 0xFFFF)
00058 continue;
00059
00060 }
00061 result += QChar(ch);
00062 }
00063 return result;
00064 }
00065
00066
00067 QString dvb_decode_text(const unsigned char *src, uint raw_length,
00068 const unsigned char *encoding_override,
00069 uint encoding_override_length)
00070 {
00071 if (!raw_length)
00072 return "";
00073
00074 if (src[0] == 0x1f)
00075 return freesat_huffman_to_string(src, raw_length);
00076
00077 if ((0x10 < src[0]) && (src[0] < 0x20))
00078 {
00079
00080 VERBOSE(VB_SIPARSER, "dvb_decode_text: "
00081 "Multi-byte coded text is not yet supported.");
00082 return "";
00083 }
00084
00085
00086
00087 unsigned char dst[raw_length + encoding_override_length];
00088 uint length = 0;
00089 if (encoding_override && src[0] >= 0x20) {
00090 memcpy(dst, encoding_override, encoding_override_length);
00091 length = encoding_override_length;
00092 }
00093
00094
00095 for (uint i = 0; i < raw_length; i++)
00096 {
00097 if ((src[i] < 0x80) || (src[i] > 0x9F))
00098 {
00099 dst[length] = src[i];
00100 length++;
00101 }
00102 }
00103 const unsigned char *buf = dst;
00104
00105
00106 if (!length)
00107 return "";
00108
00109
00110 if (buf[0] >= 0x20)
00111 {
00112 return decode_iso6937(buf, length);
00113 }
00114 else if ((buf[0] >= 0x01) && (buf[0] <= 0x0B))
00115 {
00116 return iso8859_codecs[4 + buf[0]]->toUnicode((char*)(buf + 1), length - 1);
00117 }
00118 else if (buf[0] == 0x10)
00119 {
00120
00121
00122
00123
00124
00125
00126 uint code = buf[1] << 8 | buf[2];
00127 if (code <= 15)
00128 return iso8859_codecs[code]->toUnicode((char*)(buf + 3), length - 3);
00129 else
00130 return QString::fromLocal8Bit((char*)(buf + 3), length - 3);
00131 }
00132 else
00133 {
00134
00135 return QString::fromLocal8Bit((char*)(buf + 1), length - 1);
00136 }
00137 }
00138
00139 QMutex ContentDescriptor::categoryLock;
00140 map<uint,QString> ContentDescriptor::categoryDesc;
00141 bool ContentDescriptor::categoryDescExists = false;
00142
00143 QString myth_category_type_to_string(uint category_type)
00144 {
00145 static const char *cattype[] =
00146 { "", "movie", "series", "sports", "tvshow", };
00147
00148 if ((category_type > kCategoryNone) && (category_type < kCategoryLast))
00149 return QString(cattype[category_type]);
00150
00151 return QString::null;
00152 }
00153
00154 MythCategoryType string_to_myth_category_type(const QString &category_type)
00155 {
00156 static const char *cattype[] =
00157 { "", "movie", "series", "sports", "tvshow", };
00158
00159 for (uint i = 1; i < 5; i++)
00160 if (category_type == cattype[i])
00161 return (MythCategoryType) i;
00162 return kCategoryNone;
00163 }
00164
00165 MythCategoryType ContentDescriptor::GetMythCategory(uint i) const
00166 {
00167 if (0x1 == Nibble1(i))
00168 return kCategoryMovie;
00169 if (0x4 == Nibble1(i))
00170 return kCategorySports;
00171 return kCategoryTVShow;
00172 }
00173
00174 QString ContentDescriptor::GetDescription(uint i) const
00175 {
00176 if (!categoryDescExists)
00177 Init();
00178
00179 QMutexLocker locker(&categoryLock);
00180
00181
00182 map<uint,QString>::const_iterator it = categoryDesc.find(Nibble(i));
00183 if (it != categoryDesc.end())
00184 return QDeepCopy<QString>((*it).second);
00185
00186
00187 it = categoryDesc.find(Nibble1(i)<<4);
00188 if (it != categoryDesc.end())
00189 return QDeepCopy<QString>((*it).second);
00190
00191
00192 return "";
00193 }
00194
00195 QString ContentDescriptor::toString() const
00196 {
00197 QString tmp("");
00198 for (uint i = 0; i < Count(); i++)
00199 tmp += GetMythCategory(i) + " : " + GetDescription(i);
00200 return tmp;
00201 }
00202
00203 void ContentDescriptor::Init(void)
00204 {
00205 QMutexLocker locker(&categoryLock);
00206
00207 if (categoryDescExists)
00208 return;
00209
00210 categoryDesc[0x10] = QObject::tr("Movie");
00211 categoryDesc[0x11] = QObject::tr("Movie") + " - " +
00212 QObject::tr("Detective/Thriller");
00213 categoryDesc[0x12] = QObject::tr("Movie")+ " - " +
00214 QObject::tr("Adventure/Western/War");
00215 categoryDesc[0x13] = QObject::tr("Movie")+ " - " +
00216 QObject::tr("Science Fiction/Fantasy/Horror");
00217 categoryDesc[0x14] = QObject::tr("Movie")+ " - " +
00218 QObject::tr("Comedy");
00219 categoryDesc[0x15] = QObject::tr("Movie")+ " - " +
00220 QObject::tr("Soap/melodrama/folkloric");
00221 categoryDesc[0x16] = QObject::tr("Movie")+ " - " +
00222 QObject::tr("Romance");
00223 categoryDesc[0x17] = QObject::tr("Movie")+ " - " +
00224 QObject::tr("Serious/Classical/Religious/Historical Movie/Drama");
00225 categoryDesc[0x18] = QObject::tr("Movie")+ " - " +
00226 QObject::tr("Adult", "Adult Movie");
00227
00228 categoryDesc[0x20] = QObject::tr("News");
00229 categoryDesc[0x21] = QObject::tr("News/weather report");
00230 categoryDesc[0x22] = QObject::tr("News magazine");
00231 categoryDesc[0x23] = QObject::tr("Documentary");
00232 categoryDesc[0x24] = QObject::tr("Intelligent Programmes");
00233
00234 categoryDesc[0x30] = QObject::tr("Entertainment");
00235 categoryDesc[0x31] = QObject::tr("Game Show");
00236 categoryDesc[0x32] = QObject::tr("Variety Show");
00237 categoryDesc[0x33] = QObject::tr("Talk Show");
00238
00239 categoryDesc[0x40] = QObject::tr("Sports");
00240 categoryDesc[0x41] =
00241 QObject::tr("Special Events (World Cup, World Series..)");
00242 categoryDesc[0x42] = QObject::tr("Sports Magazines");
00243 categoryDesc[0x43] = QObject::tr("Football (Soccer)");
00244 categoryDesc[0x44] = QObject::tr("Tennis/Squash");
00245 categoryDesc[0x45] =
00246 QObject::tr("Misc. Team Sports");
00247 categoryDesc[0x46] = QObject::tr("Athletics");
00248 categoryDesc[0x47] = QObject::tr("Motor Sport");
00249 categoryDesc[0x48] = QObject::tr("Water Sport");
00250 categoryDesc[0x49] = QObject::tr("Winter Sports");
00251 categoryDesc[0x4A] = QObject::tr("Equestrian");
00252 categoryDesc[0x4B] = QObject::tr("Martial Sports");
00253
00254 categoryDesc[0x50] = QObject::tr("Kids");
00255 categoryDesc[0x51] = QObject::tr("Pre-School Children's Programmes");
00256 categoryDesc[0x52] = QObject::tr("Entertainment Programmes for 6 to 14");
00257 categoryDesc[0x53] = QObject::tr("Entertainment Programmes for 10 to 16");
00258 categoryDesc[0x54] = QObject::tr("Informational/Educational");
00259 categoryDesc[0x55] = QObject::tr("Cartoons/Puppets");
00260
00261 categoryDesc[0x60] = QObject::tr("Music/Ballet/Dance");
00262 categoryDesc[0x61] = QObject::tr("Rock/Pop");
00263 categoryDesc[0x62] = QObject::tr("Classical Music");
00264 categoryDesc[0x63] = QObject::tr("Folk Music");
00265 categoryDesc[0x64] = QObject::tr("Jazz");
00266 categoryDesc[0x65] = QObject::tr("Musical/Opera");
00267 categoryDesc[0x66] = QObject::tr("Ballet");
00268
00269 categoryDesc[0x70] = QObject::tr("Arts/Culture");
00270 categoryDesc[0x71] = QObject::tr("Performing Arts");
00271 categoryDesc[0x72] = QObject::tr("Fine Arts");
00272 categoryDesc[0x73] = QObject::tr("Religion");
00273 categoryDesc[0x74] = QObject::tr("Popular Culture/Traditional Arts");
00274 categoryDesc[0x75] = QObject::tr("Literature");
00275 categoryDesc[0x76] = QObject::tr("Film/Cinema");
00276 categoryDesc[0x77] = QObject::tr("Experimental Film/Video");
00277 categoryDesc[0x78] = QObject::tr("Broadcasting/Press");
00278 categoryDesc[0x79] = QObject::tr("New Media");
00279 categoryDesc[0x7A] = QObject::tr("Arts/Culture Magazines");
00280 categoryDesc[0x7B] = QObject::tr("Fashion");
00281
00282 categoryDesc[0x80] = QObject::tr("Social/Policical/Economics");
00283 categoryDesc[0x81] = QObject::tr("Magazines/Reports/Documentary");
00284 categoryDesc[0x82] = QObject::tr("Economics/Social Advisory");
00285 categoryDesc[0x83] = QObject::tr("Remarkable People");
00286
00287 categoryDesc[0x90] = QObject::tr("Education/Science/Factual");
00288 categoryDesc[0x91] = QObject::tr("Nature/animals/Environment");
00289 categoryDesc[0x92] = QObject::tr("Technology/Natural Sciences");
00290 categoryDesc[0x93] = QObject::tr("Medicine/Physiology/Psychology");
00291 categoryDesc[0x94] = QObject::tr("Foreign Countries/Expeditions");
00292 categoryDesc[0x95] = QObject::tr("Social/Spiritual Sciences");
00293 categoryDesc[0x96] = QObject::tr("Further Education");
00294 categoryDesc[0x97] = QObject::tr("Languages");
00295
00296 categoryDesc[0xA0] = QObject::tr("Leisure/Hobbies");
00297 categoryDesc[0xA1] = QObject::tr("Tourism/Travel");
00298 categoryDesc[0xA2] = QObject::tr("Handicraft");
00299 categoryDesc[0xA3] = QObject::tr("Motoring");
00300 categoryDesc[0xA4] = QObject::tr("Fitness & Health");
00301 categoryDesc[0xA5] = QObject::tr("Cooking");
00302 categoryDesc[0xA6] = QObject::tr("Advertizement/Shopping");
00303 categoryDesc[0xA7] = QObject::tr("Gardening");
00304
00305 categoryDesc[0xB0] = QObject::tr("Original Language");
00306 categoryDesc[0xB1] = QObject::tr("Black & White");
00307 categoryDesc[0xB2] = QObject::tr("\"Unpublished\" Programmes");
00308 categoryDesc[0xB3] = QObject::tr("Live Broadcast");
00309
00310 categoryDesc[0xF0] = QObject::tr("Drama");
00311
00312 categoryDescExists = true;
00313 }
00314
00315 QString FrequencyListDescriptor::toString() const
00316 {
00317 QString str = "FrequencyListDescriptor: frequencies: ";
00318
00319 for (uint i = 0; i < FrequencyCount(); i++)
00320 str.append(QString(" %1").arg(FrequencyHz(i)));
00321
00322 return str;
00323 }
00324
00325 QString ServiceDescriptor::toString() const
00326 {
00327 QString str = QString("ServiceDescriptor: %1").arg(ServiceName());
00328
00329 if (IsDTV())
00330 str.append(" (TV)");
00331 else if (IsDigitalAudio())
00332 str.append(" (Radio)");
00333 else if (IsHDTV())
00334 str.append(" (HDTV)");
00335 else if (IsTeletext())
00336 str.append(" (Teletext)");
00337 else
00338 str.append(QString(" (Unknown %1)").arg(ServiceType(),2,16));
00339
00340 return str;
00341 }
00342
00343 QString CableDeliverySystemDescriptor::toString() const
00344 {
00345 QString str = QString("CableDeliverySystemDescriptor: ");
00346
00347 str.append(QString("Frequency: %1\n").arg(FrequencyHz()));
00348 str.append(QString(" Mod=%1, SymbR=%2, FECInner=%3, FECOuter=%4")
00349 .arg(ModulationString())
00350 .arg(SymbolRateHz())
00351 .arg(FECInnerString())
00352 .arg(FECOuterString()));
00353
00354 return str;
00355 }
00356
00357 QString SatelliteDeliverySystemDescriptor::toString() const
00358 {
00359 QString str = QString("SatelliteDeliverySystemDescriptor: ");
00360
00361 str.append(QString("Frequency: %1\n").arg(FrequencyHz()));
00362 str.append(QString(" Mod=%1, SymbR=%2, FECInner=%3, Orbit=%4, Pol=%5")
00363 .arg(ModulationString())
00364 .arg(SymbolRateHz())
00365 .arg(FECInnerString())
00366 .arg(OrbitalPositionString())
00367 .arg(PolarizationString()));
00368
00369 return str;
00370 }
00371
00372 QString TerrestrialDeliverySystemDescriptor::toString() const
00373 {
00374 QString str = QString("TerrestrialDeliverySystemDescriptor: ");
00375
00376 str.append(QString("Frequency: %1\n").arg(FrequencyHz()));
00377 str.append(QString(" BW=%1k, C=%2, HP=%3, LP=%4, GI=%5, TransMode=%6k")
00378 .arg(BandwidthString())
00379 .arg(ConstellationString())
00380 .arg(CodeRateHPString())
00381 .arg(CodeRateLPString())
00382 .arg(GuardIntervalString())
00383 .arg(TransmissionModeString()));
00384
00385 return str;
00386 }
00387