00001
00002
00003 #ifndef _ATSC_DESCRIPTORS_H_
00004 #define _ATSC_DESCRIPTORS_H_
00005
00006 #include <cassert>
00007 #include <vector>
00008 using namespace std;
00009
00010 #include <qstring.h>
00011 #include <qmap.h>
00012
00013 #include "mythcontext.h"
00014 #include "mpegdescriptors.h"
00015
00016 using namespace std;
00017
00018 typedef QMap<int, const unsigned char*> IntToBuf;
00019
00020 class MultipleStringStructure
00021 {
00022 public:
00023 MultipleStringStructure(const unsigned char* data) : _data(data)
00024 {
00025 Parse();
00026 }
00027
00028 uint StringCount(void) const { return _data[0]; }
00029
00030
00031 int LanguageKey(uint i) const
00032 { return iso639_str3_to_key(Offset(i,-1)); }
00033 QString LanguageString(uint i) const
00034 { return iso639_key_to_str3(LanguageKey(i)); }
00035 int CanonicalLanguageKey(uint i) const
00036 { return iso639_key_to_canonical_key(LanguageKey(i)); }
00037 QString CanonicalLanguageString(uint i) const
00038 { return iso639_key_to_str3(CanonicalLanguageKey(i)); }
00039
00040
00041
00042 uint SegmentCount(uint i) const { return *(Offset(i,-1)+3); }
00043
00044
00045
00046 uint CompressionType(uint i, uint j) const { return *Offset(i,j); }
00047 QString CompressionTypeString(uint i, uint j) const;
00048
00049 int Mode(int i, int j) const { return *(Offset(i,j)+1); }
00050
00051 int Bytes(int i, int j) const { return *(Offset(i,j)+2); }
00052
00053
00054
00055
00056
00057 uint GetIndexOfBestMatch(QMap<uint,uint> &langPrefs) const;
00058 QString GetBestMatch(QMap<uint,uint> &langPrefs) const;
00059
00060 QString GetSegment(uint i, uint j) const;
00061 QString GetFullString(uint i) const;
00062
00063 void Parse(void) const;
00064
00065 QString toString() const;
00066
00067 private:
00068 static QString Uncompressed(const unsigned char* buf, int len, int mode);
00069 static uint Index(int i, int j) { return (i<<8)|(j&0xff); }
00070 const unsigned char* Offset(int i, int j) const
00071 { return _ptrs[Index(i,j)]; }
00072
00073 private:
00074 const unsigned char* _data;
00075 mutable IntToBuf _ptrs;
00076 };
00077
00078 class CaptionServiceDescriptor : public MPEGDescriptor
00079 {
00080 public:
00081 CaptionServiceDescriptor(const unsigned char* data) :
00082 MPEGDescriptor(data)
00083 {
00084
00085
00086 assert(DescriptorID::caption_service == DescriptorTag());
00087 Parse();
00088
00089 }
00090
00091
00092
00093 uint ServicesCount() const { return _data[2]&0x1f; }
00094
00095
00096 int LanguageKey(int i) const
00097 { return iso639_str3_to_key(Offset(i,-1)); }
00098 QString LanguageString(int i) const
00099 { return iso639_key_to_str3(LanguageKey(i)); }
00100 int CanonicalLanguageKey(int i) const
00101 { return iso639_key_to_canonical_key(LanguageKey(i)); }
00102 QString CanonicalLanguageString(int i) const
00103 { return iso639_key_to_str3(CanonicalLanguageKey(i)); }
00104
00105 bool Type(int i) const
00106 { return ((Offset(i,-1)[3])>>7) & 1; }
00107
00108
00109
00110
00111 bool Line21Field(int i) const
00112 { return bool(((Offset(i,-1)[3])) & 1); }
00113
00114
00115 int CaptionServiceNumber(int i) const
00116 { return ((Offset(i,-1)[3])) & 0x3f; }
00117
00118 bool EasyReader(int i) const
00119 { return bool(((Offset(i,-1)[4])>>7) & 1); }
00120
00121 bool WideAspectRatio(int i) const
00122 { return bool(((Offset(i,-1)[4])>>6) & 1); }
00123
00124
00125 void Parse(void) const;
00126 QString toString() const;
00127
00128 private:
00129 int Index(int i, int j) const { return (i<<8) | (j & 0xff); }
00130 const unsigned char* Offset(int i, int j) const
00131 { return _ptrs[Index(i,j)]; }
00132
00133 private:
00134 mutable IntToBuf _ptrs;
00135 };
00136
00137 class ContentAdvisoryDescriptor : public MPEGDescriptor
00138 {
00139 mutable IntToBuf _ptrs;
00140 public:
00141 ContentAdvisoryDescriptor(const unsigned char* data) :
00142 MPEGDescriptor(data)
00143 {
00144
00145
00146 assert(DescriptorID::content_advisory == DescriptorTag());
00147 Parse();
00148
00149 }
00150
00151
00152 uint RatingRegionCount(void) const { return _data[2] & 0x3f; }
00153
00154
00155 uint RatingRegion(uint i) const
00156 { return *Offset(i,-1); }
00157
00158 uint RatedDimensions(uint i) const
00159 { return *(Offset(i,-1) + 1); }
00160
00161
00162 uint RatingDimension(uint i, uint j) const
00163 { return *Offset(i,j); }
00164
00165
00166 uint RatingValue(uint i, uint j) const
00167 { return (*(Offset(i,j) + 1)) & 0xf; }
00168
00169
00170 uint RatingDescriptionLength(uint i) const
00171 { return (*(Offset(i,-1) + 2 + (RatedDimensions(i)<<1))); }
00172
00173 const MultipleStringStructure RatingDescription(uint i) const
00174 {
00175 const unsigned char* data = Offset(i,-1) + 3 + (RatedDimensions(i)<<1);
00176 return MultipleStringStructure(data);
00177 }
00178
00179
00180 void Parse(void) const;
00181 QString toString() const;
00182 protected:
00183 int Index(int i, int j) const { return (i<<8)|(j&0xff); }
00184 const unsigned char* Offset(int i, int j) const {
00185 return _ptrs[Index(i,j)];
00186 }
00187 };
00188
00189 class ComponentNameDescriptor : public MPEGDescriptor {
00190 public:
00191 ComponentNameDescriptor(const unsigned char* data) :
00192 MPEGDescriptor(data) {
00193 assert(0xA3==DescriptorTag());
00194 }
00195 const MultipleStringStructure ComponentNameStrings() const {
00196 return MultipleStringStructure(_data+2);
00197 }
00198 QString toString() const {
00199 return QString("Component Name Descriptor %1").
00200 arg(ComponentNameStrings().toString());
00201 }
00202 };
00203
00204
00205
00206 class AudioStreamDescriptor : public MPEGDescriptor {
00207 public:
00208 AudioStreamDescriptor(const unsigned char* data) :
00209 MPEGDescriptor(data) {
00210
00211 assert(DescriptorID::audio_stream == DescriptorTag());
00212 }
00213
00214 uint SampleRateCode() const { return (_data[2]>>5)&7; }
00215 QString SampleRateCodeString() const;
00216
00217 uint bsid() const { return _data[2]&0x1f; }
00218
00219 uint BitRateCode() const { return (_data[3]>>2)&0x3f; }
00220 QString BitRateCodeString() const;
00221
00222 uint SurroundMode() const { return _data[3]&3; }
00223 QString SurroundModeString() const;
00224
00225
00226
00227
00228
00229
00230
00231 uint BasicServiceMode() const { return (_data[4]>>5)&7; }
00232
00233 uint Channels() const { return (_data[4]>>1)&0xf; }
00234 QString ChannelsString() const;
00235
00236
00237
00238 bool FullService() const { return bool((_data[4])&1); }
00239
00240
00241
00242 uint LanguageCode() const { return _data[5]; }
00243
00244
00245
00246 uint LanguageCode2() const { return _data[6]; }
00247
00248
00249
00250 uint MainID() const {
00251 return _data[(Channels()==0)?7:6]>>5;
00252 }
00253
00254
00255
00256 uint AServiceFlags() const {
00257 return _data[(Channels()==0)?7:6];
00258 }
00259
00260
00261 uint TextLength() const {
00262 return _data[(Channels()==0)?8:7]>>1;
00263 }
00264
00265
00266
00267
00268
00269 bool IsTextLatin1() const {
00270 return bool(_data[(Channels()==0)?8:7]&1);
00271 }
00272
00273
00274
00275 QString Text() const {
00276 #if 0
00277 char* tmp = new char[TextLength()+2];
00278 if (IsTextLatin1()) {
00279 memcpy(tmp, &_data[(Channels()==0)?9:8], TextLength());
00280 tmp[TextLength()]=0;
00281 for (uint i=0; i<TextLength(); i++)
00282 if (!tmp[i]) tmp[i]='H';
00283 QString str(tmp);
00284 delete[] tmp;
00285 return str;
00286 } else {
00287 QString str; int len = TextLength();
00288 const unsigned char* buf = (&_data[(Channels()==0)?9:8]);
00289 const unsigned short* ustr =
00290 reinterpret_cast<const unsigned short*>(buf);
00291 for (int j=0; j<(len>>1); j++)
00292 str.append( QChar( (ustr[j]<<8) | (ustr[j]>>8) ) );
00293 return str;
00294 }
00295 #endif
00296 return QString("TODO");
00297 }
00298
00299
00300
00301
00302 QString toString() const;
00303 };
00304
00309 class ContentIdentifierDescriptor : public MPEGDescriptor {
00310 ContentIdentifierDescriptor(const unsigned char* data) :
00311 MPEGDescriptor(data) {
00312
00313 assert(0xB6==DescriptorTag());
00314 }
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324 QString toString() const { return QString("ContentIdentifierDescriptor(stub)"); }
00325 };
00326
00334 class ExtendedChannelNameDescriptor : public MPEGDescriptor
00335 {
00336 public:
00337 ExtendedChannelNameDescriptor(const unsigned char *data);
00338 MultipleStringStructure LongChannelName(void) const;
00339 QString LongChannelNameString(void) const;
00340
00341 QString toString() const;
00342 };
00343
00344 #endif