|
MythTV
0.26-pre
|
00001 // -*- Mode: c++ -*- 00002 // Copyright (c) 2003-2004, Daniel Thor Kristjansson 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 //uimsbf for (i= 0;i< number_strings;i++) { 00028 // ISO_639_language_code 24; 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 // uimsbf cc_type 1 3.0 00038 00039 // uimsbf number_segments 8; 00040 uint SegmentCount(uint i) const { return *(Offset(i,-1)+3); } 00041 00042 // uimsbf for (j=0;j<number_segments;j++) { 00043 // compression_type 8; 00044 uint CompressionType(uint i, uint j) const { return *Offset(i,j); } 00045 QString CompressionTypeString(uint i, uint j) const; 00046 // uimsbf mode 8; 00047 int Mode(int i, int j) const { return *(Offset(i,j)+1); } 00048 // uimsbf number_bytes 8; 00049 int Bytes(int i, int j) const { return *(Offset(i,j)+2); } 00050 // uimsbf for (k= 0;k<number_bytes;k++) 00051 // compressed_string_byte [k] 8 bslbf; 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 // Name bits loc expected value 00086 // descriptor_tag 8 0.0 0x86 00087 // descriptor_length 8 1.0 00088 // reserved 3 2.0 0x07 00089 // number_of_services 5 2.3 00090 uint ServicesCount() const { return _data[2]&0x1f; } 00091 //uimsbf for (i=0;i<number_of_services;i++) { 00092 // language 8*3 0.0 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 // uimsbf cc_type 1 3.0 00102 bool Type(int i) const 00103 { return ((Offset(i,-1)[3])>>7) & 1; } 00104 // bslbf reserved 1 3.1 1 00105 // if (cc_type==line21) { 00106 // reserved 5 3.2 0x1f 00107 // line21_field 1 3.7 00108 bool Line21Field(int i) const 00109 { return bool(((Offset(i,-1)[3])) & 1); } 00110 // } else 00111 // cap_service_number 6 3.2 00112 int CaptionServiceNumber(int i) const 00113 { return ((Offset(i,-1)[3])) & 0x3f; } 00114 // easy_reader 1 4.0 00115 bool EasyReader(int i) const 00116 { return bool(((Offset(i,-1)[4])>>7) & 1); } 00117 // wide_aspect_ratio 1 4.1 00118 bool WideAspectRatio(int i) const 00119 { return bool(((Offset(i,-1)[4])>>6) & 1); } 00120 // reserved 14 4.2 0x3fff 00121 //} 6.0 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 // Name bits loc expected value 00144 // descriptor_tag 8 0.0 0x87 00145 // descriptor_length 8 1.0 00146 // reserved 2 2.0 0x03 00147 // rating_region_count 6 2.2 00148 uint RatingRegionCount(void) const { return _data[2] & 0x3f; } 00149 // for (i=0; i<rating_region_count; i++) { 00150 // rating_region 8 x+0.0 00151 uint RatingRegion(uint i) const 00152 { return *Offset(i,-1); } 00153 // rated_dimensions 8 x+1.0 00154 uint RatedDimensions(uint i) const 00155 { return *(Offset(i,-1) + 1); } 00156 // for (j=0;j<rated_dimensions;j++) { 00157 // rating_dimension_j 8 y+0.0 00158 uint RatingDimension(uint i, uint j) const 00159 { return *Offset(i,j); } 00160 // reserved 4 y+1.0 0x0f 00161 // rating_value 4 y+1.4 00162 uint RatingValue(uint i, uint j) const 00163 { return (*(Offset(i,j) + 1)) & 0xf; } 00164 // } 00165 // rating_desc_length 8 x+2+(rated_dimensions*2)+0.0 00166 uint RatingDescriptionLength(uint i) const 00167 { return (*(Offset(i,-1) + 2 + (RatedDimensions(i)<<1))); } 00168 // rating_desc_text x+2+(rated_dimensions*2)+1.0 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 // a_52a.pdf p120, Table A2 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 // descriptor_tag 8 0.0 0x81 00214 // sample_rate_code 3 2.0 00215 uint SampleRateCode(void) const { return (_data[2]>>5)&7; } 00216 QString SampleRateCodeString(void) const; 00217 // bsid 5 2.3 00218 uint bsid(void) const { return _data[2]&0x1f; } 00219 // bit_rate_code 6 3.0 00220 uint BitRateCode(void) const { return (_data[3]>>2)&0x3f; } 00221 QString BitRateCodeString(void) const; 00222 // surround_mode 2 3.6 00223 uint SurroundMode(void) const { return _data[3]&3; } 00224 QString SurroundModeString(void) const; 00225 /* 00226 000 Major ? 00227 001 Major ? 00228 010-111 Minor 00229 111 Karaoke Mode if acmod >= 0x2. a_52a.pdf p130 00230 */ 00231 // bsmod 3 4.0 00232 uint BasicServiceMode(void) const { return (_data[4]>>5)&7; } 00233 // num_channels 4 4.3 00234 uint Channels(void) const { return (_data[4]>>1)&0xf; } 00235 QString ChannelsString(void) const; 00236 00237 // full service that can be presented alone to listener? 00238 // full_svc 1 4.7 00239 bool FullService(void) const { return bool((_data[4])&1); } 00240 00241 // langcod 8 5.0 00242 // ignore for language specification 00243 uint LanguageCode(void) const { return _data[5]; } 00244 // if(num_channels==0) /* 1+1 mode */ 00245 // langcod2 8 6.0 00246 // ignore for language specification 00247 uint LanguageCode2(void) const { return _data[6]; } 00248 00249 // if(bsmod<2) { 00250 // mainid 3 7.0/6.0 00251 uint MainID(void) const 00252 { 00253 return _data[(Channels()==0)?7:6]>>5; 00254 } 00255 // reserved 5 7.3/6.3 00256 //uint reserved(void) const { return _data[7]&0x1f; } 00257 // } else asvcflags 8 7.0/6.0 00258 uint AServiceFlags(void) const 00259 { 00260 return _data[(Channels()==0)?7:6]; 00261 } 00262 00263 // textlen 7 8.0/7.0 00264 uint TextLength(void) const 00265 { 00266 return _data[(Channels()==0)?8:7]>>1; 00267 } 00268 00269 /* If this bit is a 1 , the text is encoded as 1-byte characters 00270 using the ISO Latin-1 alphabet (ISO 8859-1). If this bit is a 0, 00271 the text is encoded with 2-byte unicode characters. */ 00272 // text_code 1 bslbf 00273 bool IsTextLatin1(void) const 00274 { 00275 return bool(_data[(Channels()==0)?8:7]&1); 00276 } 00277 // for(i=0; i<M; i++) { 00278 // text[i] 8 bslbf 00279 // } 00280 QString Text(void) const 00281 { // TODO 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 // for(i=0; i<N; i++) { 00308 // additional_info[i] N×8 bslbf 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 // descriptor_tag 8 0.0 0xB6 00323 // descriptor_length 8 1.0 00324 // content_ID_structure 00325 // ID_system 8 2.0 00326 // 0x00 ISAN (ISO 15706[1]) 00327 // 0x01 V-ISAN (ISO 20925-1[2]) 00328 // 0x02-0xFF ATSC Reserved 00329 // ID_length 8 3.0 00330 // content_identifier v 4.0 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
1.7.6.1