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