MythTV  0.26-pre
atscdescriptors.cpp
Go to the documentation of this file.
00001 // -*- Mode: c++ -*-
00002 // Copyright (c) 2003-2004, Daniel Thor Kristjansson
00003 
00004 #include <algorithm>
00005 using namespace std;
00006 
00007 #include "atscdescriptors.h"
00008 #include "mythlogging.h"
00009 #include "iso639.h"
00010 #include "atsc_huffman.h"
00011 
00012 using namespace std;
00013 
00014 
00015 QString MultipleStringStructure::CompressionTypeString(uint i, uint j) const
00016 {
00017     uint ct = CompressionType(i, j);
00018     if (0 == ct)
00019         return QString("no compression");
00020     if (1 == ct)
00021         return QString("Huffman Coding using C.4, C.5");
00022     if (2 == ct)
00023         return QString("Huffman Coding using C.6, C.7");
00024     if (ct < 0xaf)
00025         return QString("reserved");
00026     return QString("compression not used by ATSC in North America, unknown");
00027 }
00028 
00029 QString MultipleStringStructure::toString() const
00030 {
00031     QString str;
00032     if (1 == StringCount() && 1 == SegmentCount(0))
00033     {
00034         str.append(QString("lang(%1) ").arg(LanguageString(0)));
00035         if (0 != Bytes(0, 0))
00036             str.append(GetSegment(0, 0));
00037         return str;
00038     }
00039 
00040     str.append(QString("MultipleStringStructure    count(%1)")
00041                .arg(StringCount()));
00042 
00043     for (uint i = 0; i < StringCount(); i++)
00044     {
00045         str.append(QString(" String #%1 lang(%2:%3)")
00046                    .arg(i).arg(LanguageString(i))
00047                    .arg(LanguageKey(i)));
00048 
00049         if (SegmentCount(i) > 1)
00050             str.append(QString("  segment count(%1)").arg(SegmentCount(i)));
00051 
00052         for (uint j=0; j<SegmentCount(i); j++)
00053             str.append(QString("  Segment #%1  ct(%2) str(%3)").arg(j)
00054                        .arg(CompressionType(i, j)).arg(GetSegment(i, j)));
00055     }
00056 
00057     return str;
00058 }
00059 
00060 static uint maxPriority(const QMap<uint,uint> &langPrefs)
00061 {
00062     uint max_pri = 0;
00063     QMap<uint,uint>::const_iterator it = langPrefs.begin();
00064     for (; it != langPrefs.end(); ++it)
00065         max_pri = max(max_pri, *it);
00066     return max_pri;
00067 }
00068 
00069 uint MultipleStringStructure::GetIndexOfBestMatch(
00070     QMap<uint,uint> &langPrefs) const
00071 {
00072     uint match_idx = 0;
00073     uint match_pri = 0;
00074 
00075     for (uint i = 0; i < StringCount(); i++)
00076     {
00077         QMap<uint,uint>::const_iterator it =
00078             langPrefs.find(CanonicalLanguageKey(i));
00079         if ((it != langPrefs.end()) && (*it > match_pri))
00080         {
00081             match_idx = i;
00082             match_pri = *it;
00083         }
00084     }
00085 
00086     if (match_pri)
00087         return match_idx;
00088 
00089     if (StringCount())
00090         langPrefs[CanonicalLanguageKey(0)] = maxPriority(langPrefs) + 1;
00091 
00092     return 0;
00093 }
00094 
00095 QString MultipleStringStructure::GetBestMatch(QMap<uint,uint> &langPrefs) const
00096 {
00097     if (StringCount())
00098         return GetFullString(GetIndexOfBestMatch(langPrefs));
00099     return QString::null;
00100 }
00101 
00102 QString MultipleStringStructure::GetSegment(uint i, uint j) const
00103 {
00104     const unsigned char* buf = (Offset(i, j)+3);
00105     int len = Bytes(i, j);
00106 
00107     if (len <= 0)
00108         return "";
00109 
00110     int ct = CompressionType(i, j);
00111 
00112     if (ct == 0)
00113         return Uncompressed(buf, len, Mode(i, j));
00114 
00115     if (ct < 3)
00116         return atsc_huffman1_to_string(buf, len, ct);
00117 
00118     return QString("MSS unknown text compression %1").arg(ct);
00119 }
00120 
00121 QString MultipleStringStructure::GetFullString(uint i) const
00122 {
00123     QString tmp = "";
00124     for (uint j = 0; j < SegmentCount(i); j++)
00125         tmp += GetSegment(i, j);
00126     return tmp;
00127 }
00128 
00129 QString MultipleStringStructure::Uncompressed(
00130     const unsigned char* buf, int len, int mode) {
00131 
00132     QString str=QString("");
00133     if (mode<=6 ||
00134         (9<=mode && mode<=0xe) ||
00135         (0x10==mode) ||
00136         (0x20<=mode && mode<=0x27) ||
00137         (0x30<=mode && mode<=0x33)) { // basic runlength encoding
00138         int hb=mode<<8;
00139         for (int j=0; j<len; j++)
00140         {
00141 #if 0
00142             LOG(VB_GENERAL, LOG_DEBUG, QString("str.append(0x%1:0x%2) -> %3")
00143                 .arg(mode, 0, 16) .arg(buf[j], 0, 16) .arg(QChar(hb|buf[j])));
00144 #endif
00145             str.append( QChar( hb|buf[j] ) );
00146         }
00147     } else if (mode==0x3e) {
00148         // Standard Compression Scheme for Unicode (SCSU)
00149         str=QString("TODO SCSU encoding");
00150     } else if (mode==0x3f) { //  Unicode, UTF-16 Form
00151         const unsigned short* ustr =
00152             reinterpret_cast<const unsigned short*>(buf);
00153         for (int j=0; j<(len>>1); j++)
00154             str.append( QChar( (ustr[j]<<8) | (ustr[j]>>8) ) );
00155     } else if (0x40<=mode && mode<=0x41)
00156         str = QString("TODO Tawain Characters");
00157     else if (0x48==mode)
00158         str = QString("TODO South Korean Characters");
00159     else
00160         str = QString("unknown character encoding mode(%0)").arg(mode);
00161     return str;
00162 }
00163 
00164 void MultipleStringStructure::Parse(void) const
00165 {
00166     _ptrs.clear();
00167     _ptrs[Index(0,-1)] = _data + 1;
00168     for (uint i = 0; i < StringCount(); i++)
00169     {
00170         _ptrs[Index(i,0)] = Offset(i,-1) + 4;
00171         uint j = 0;
00172         for (; j < SegmentCount(i); j++)
00173             _ptrs[Index(i,j+1)] = Offset(i,j) + Bytes(i,j) + 3;
00174         _ptrs[Index(i+1,-1)] = Offset(i,j);
00175     }
00176 }
00177 
00178 bool CaptionServiceDescriptor::Parse(void)
00179 {
00180     _ptrs.clear();
00181     _ptrs[Index(0,-1)] = _data+3;
00182 
00183     for (uint i = 0; i < ServicesCount(); i++)
00184         _ptrs[Index(i+1,-1)] = Offset(i,-1) + 6;
00185 
00186     return true;
00187 }
00188 
00189 QString CaptionServiceDescriptor::toString(void) const
00190 {
00191     QString str("Caption Service Descriptor  ");
00192     str.append(QString("services(%2)").arg(ServicesCount()));
00193 
00194     for (uint i = 0; i < ServicesCount(); i++)
00195     {
00196         str.append(QString("\n     lang(%1) type(%2) ")
00197                    .arg(LanguageString(i)).arg(Type(i)));
00198         str.append(QString("easy_reader(%1) wide(%2) ")
00199                    .arg(EasyReader(i)).arg(WideAspectRatio(i)));
00200         if (Type(i))
00201             str.append(QString("service_num(%1)")
00202                        .arg(CaptionServiceNumber(i)));
00203         else
00204             str.append(QString("line_21_field(%1)").arg(Line21Field(i)));
00205     }
00206 
00207     return str;
00208 }
00209 
00210 bool ContentAdvisoryDescriptor::Parse(void)
00211 {
00212     _ptrs.clear();
00213     _ptrs[Index(0,-1)] = _data + 2;
00214 
00215     for (uint i = 0; i < RatingRegionCount(); i++)
00216     {
00217         _ptrs[Index(i,0)] = Offset(i,-1)+2;
00218         uint j = 0;
00219         for (; j < RatedDimensions(i); j++)
00220             _ptrs[Index(i,j+1)] = Offset(i,j) + 2;
00221         const unsigned char *tmp = Offset(i,-1) + 3 + (RatedDimensions(i)<<1);
00222         uint len = RatingDescriptionLength(i);
00223         _ptrs[Index(i+1,-1)] = tmp + len;
00224     }
00225 
00226     return true;
00227 }
00228 
00229 QString ContentAdvisoryDescriptor::toString() const
00230 {
00231     return "ContentAdvisoryDescriptor::toString(): Not implemented";
00232 }
00233 
00234 QString AudioStreamDescriptor::SampleRateCodeString(void) const
00235 {
00236     static const char* asd[] =
00237     {
00238         "48kbps", "44.1kbps", "32kbps", "Reserved",
00239         "48kbps or 44.1kbps", "48kbps or 32kbps",
00240         "44.1kbps or 32kbps", "48kbps or 44.1kbps or 32kbps"
00241     };
00242     return QString(asd[SampleRateCode()]);
00243 }
00244 
00245 QString AudioStreamDescriptor::BitRateCodeString(void) const
00246 {
00247     static const char* ebr[19] =
00248     {
00249         "=32kbps",  "=40kbps",  "=48kbps",  "=56kbps",  "=64kbps",
00250         "=80kbps",  "=96kbps",  "=112kbps", "=128kbps", "=160kbps",
00251         "=192kbps", "=224kbps", "=256kbps", "=320kbps", "=384kbps",
00252         "=448kbps", "=512kbps", "=576kbps", "=640kbps"
00253     };
00254     static const char* ubr[19] =
00255     {
00256         "<=32kbps",  "<=40kbps", "<=48kbps",  "<=56kbps",  "<=64kbps",
00257         "<=80kbps",  "<=96kbps", "<=112kbps", "<=128kbps", "<=160kbps",
00258         "<=192kbps","<=224kbps", "<=256kbps", "<=320kbps", "<=384kbps",
00259         "<=448kbps","<=512kbps", "<=576kbps", "<=640kbps"
00260     };
00261 
00262     if (BitRateCode() <= 18)
00263         return QString(ebr[BitRateCode()]);
00264     else if ((BitRateCode() >= 32) && (BitRateCode() <= 50))
00265         return QString(ubr[BitRateCode()-32]);
00266 
00267     return QString("Unknown Bit Rate Code");
00268 }
00269 
00270 QString AudioStreamDescriptor::SurroundModeString(void) const
00271 {
00272     static const char* sms[] =
00273     {
00274         "Not indicated",
00275         "Not Dolby surround encoded",
00276         "Dolby surround encoded",
00277         "Reserved",
00278     };
00279     return QString(sms[SurroundMode()]);
00280 }
00281 
00282 QString AudioStreamDescriptor::ChannelsString(void) const
00283 {
00284     static const char* cs[] =
00285     {
00286         "1 + 1",    "1/0",      "2/0",      "3/0",
00287         "2/1",      "3/1",      "2/2 ",     "3/2",
00288         "1",        "<= 2",     "<= 3",     "<= 4",
00289         "<= 5",     "<= 6",     "Reserved", "Reserved"
00290     };
00291     return cs[Channels()];
00292 }
00293 
00294 QString AudioStreamDescriptor::toString() const
00295 {
00296     QString str;
00297     str.append(QString("Audio Stream Descriptor "));
00298     str.append(QString(" full_srv(%1) sample_rate(%2) bit_rate(%3, %4)\n")
00299                .arg(FullService()).arg(SampleRateCodeString())
00300                .arg(BitRateCodeString()).arg(BitRateCode()));
00301     str.append(QString("      bsid(%1) bs_mode(%2) channels(%3) Dolby(%4)\n")
00302                .arg(bsid()).arg(BasicServiceMode())
00303                .arg(ChannelsString()).arg(SurroundModeString()));
00304 
00305     /*
00306     str.append(QString("   language code: %1").arg(languageCode()));
00307     if (0==channels()) {
00308         str.append(QString(" language code 2: %1").arg(languageCode2()));
00309     }
00310     */
00311 
00312     if (BasicServiceMode() < 2)
00313         str.append(QString("      mainID(%1) ").arg(MainID()));
00314     else
00315         str.append(QString("      associated_service(0x%1) ")
00316                    .arg(AServiceFlags(),0,16));
00317 
00318     if (TextLength())
00319     {
00320         str.append(QString("isLatin-1(%1) ")
00321                    .arg(IsTextLatin1() ? "true" : "false"));
00322         str.append(QString("text_length(%1) ").arg(TextLength()));
00323         str.append(QString("text(%1)").arg(Text()));
00324     }
00325     return str;
00326 }
00327 
00332 MultipleStringStructure ExtendedChannelNameDescriptor::LongChannelName(
00333     void) const
00334 {
00335     return MultipleStringStructure(_data + 2);
00336 }
00337 
00342 QString ExtendedChannelNameDescriptor::LongChannelNameString(void) const
00343 {
00344     QString str = "";
00345     MultipleStringStructure mstr = LongChannelName();
00346 
00347     for (uint i = 0; i < mstr.StringCount(); i++)
00348         str += mstr.GetFullString(i);
00349 
00350     return str;
00351 }
00352 
00353 QString ExtendedChannelNameDescriptor::toString() const
00354 {
00355     return QString("ExtendedChannelNameDescriptor: '%1'")
00356         .arg(LongChannelNameString());
00357 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends