MythTV  0.27pre
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Groups Pages
atscdescriptors.h
Go to the documentation of this file.
1 // -*- Mode: c++ -*-
2 // Copyright (c) 2003-2004, Daniel Thor Kristjansson
3 #ifndef _ATSC_DESCRIPTORS_H_
4 #define _ATSC_DESCRIPTORS_H_
5 
6 #include <vector>
7 using namespace std;
8 
9 #include <QString>
10 #include <QMap>
11 
12 #include "mpegdescriptors.h"
13 
14 using namespace std;
15 
16 typedef QMap<int, const unsigned char*> IntToBuf;
17 
19 {
20  public:
21  MultipleStringStructure(const unsigned char *data) : _data(data)
22  {
23  Parse();
24  }
25 
26  uint StringCount(void) const { return _data[0]; }
27  //uimsbf for (i= 0;i< number_strings;i++) {
28  // ISO_639_language_code 24;
29  int LanguageKey(uint i) const
30  { return iso639_str3_to_key(Offset(i,-1)); }
31  QString LanguageString(uint i) const
32  { return iso639_key_to_str3(LanguageKey(i)); }
33  int CanonicalLanguageKey(uint i) const
34  { return iso639_key_to_canonical_key(LanguageKey(i)); }
35  QString CanonicalLanguageString(uint i) const
36  { return iso639_key_to_str3(CanonicalLanguageKey(i)); }
37  // uimsbf cc_type 1 3.0
38 
39  // uimsbf number_segments 8;
40  uint SegmentCount(uint i) const { return *(Offset(i,-1)+3); }
41 
42  // uimsbf for (j=0;j<number_segments;j++) {
43  // compression_type 8;
44  uint CompressionType(uint i, uint j) const { return *Offset(i,j); }
45  QString CompressionTypeString(uint i, uint j) const;
46  // uimsbf mode 8;
47  int Mode(int i, int j) const { return *(Offset(i,j)+1); }
48  // uimsbf number_bytes 8;
49  int Bytes(int i, int j) const { return *(Offset(i,j)+2); }
50  // uimsbf for (k= 0;k<number_bytes;k++)
51  // compressed_string_byte [k] 8 bslbf;
52  // }
53  //}
54 
55  uint GetIndexOfBestMatch(QMap<uint,uint> &langPrefs) const;
56  QString GetBestMatch(QMap<uint,uint> &langPrefs) const;
57 
58  QString GetSegment(uint i, uint j) const;
59  QString GetFullString(uint i) const;
60 
61  void Parse(void) const;
62 
63  QString toString() const;
64 
65  private:
66  static QString Uncompressed(const unsigned char *buf, int len, int mode);
67  static uint Index(int i, int j) { return (i<<8)|(j&0xff); }
68  const unsigned char *Offset(int i, int j) const
69  { return _ptrs[Index(i,j)]; }
70 
71  private:
72  const unsigned char *_data;
73  mutable IntToBuf _ptrs;
74 };
75 
77 {
78  public:
79  CaptionServiceDescriptor(const unsigned char *data, int len = 300) :
80  MPEGDescriptor(data, len, DescriptorID::caption_service)
81  {
82  if (_data && !Parse())
83  _data = NULL;
84  }
85  // Name bits loc expected value
86  // descriptor_tag 8 0.0 0x86
87  // descriptor_length 8 1.0
88  // reserved 3 2.0 0x07
89  // number_of_services 5 2.3
90  uint ServicesCount() const { return _data[2]&0x1f; }
91  //uimsbf for (i=0;i<number_of_services;i++) {
92  // language 8*3 0.0
93  int LanguageKey(int i) const
94  { return iso639_str3_to_key(Offset(i,-1)); }
95  QString LanguageString(int i) const
96  { return iso639_key_to_str3(LanguageKey(i)); }
97  int CanonicalLanguageKey(int i) const
98  { return iso639_key_to_canonical_key(LanguageKey(i)); }
99  QString CanonicalLanguageString(int i) const
100  { return iso639_key_to_str3(CanonicalLanguageKey(i)); }
101  // uimsbf cc_type 1 3.0
102  bool Type(int i) const
103  { return ((Offset(i,-1)[3])>>7) & 1; }
104  // bslbf reserved 1 3.1 1
105  // if (cc_type==line21) {
106  // reserved 5 3.2 0x1f
107  // line21_field 1 3.7
108  bool Line21Field(int i) const
109  { return bool(((Offset(i,-1)[3])) & 1); }
110  // } else
111  // cap_service_number 6 3.2
112  int CaptionServiceNumber(int i) const
113  { return ((Offset(i,-1)[3])) & 0x3f; }
114  // easy_reader 1 4.0
115  bool EasyReader(int i) const
116  { return bool(((Offset(i,-1)[4])>>7) & 1); }
117  // wide_aspect_ratio 1 4.1
118  bool WideAspectRatio(int i) const
119  { return bool(((Offset(i,-1)[4])>>6) & 1); }
120  // reserved 14 4.2 0x3fff
121  //} 6.0
122  bool Parse(void);
123  QString toString() const;
124 
125  private:
126  int Index(int i, int j) const { return (i<<8) | (j & 0xff); }
127  const unsigned char *Offset(int i, int j) const
128  { return _ptrs[Index(i,j)]; }
129 
130  private:
132 };
133 
135 {
136  public:
137  ContentAdvisoryDescriptor(const unsigned char *data, int len = 300) :
138  MPEGDescriptor(data, len, DescriptorID::content_advisory)
139  {
140  if (_data && !Parse())
141  _data = NULL;
142  }
143  // Name bits loc expected value
144  // descriptor_tag 8 0.0 0x87
145  // descriptor_length 8 1.0
146  // reserved 2 2.0 0x03
147  // rating_region_count 6 2.2
148  uint RatingRegionCount(void) const { return _data[2] & 0x3f; }
149  // for (i=0; i<rating_region_count; i++) {
150  // rating_region 8 x+0.0
151  uint RatingRegion(uint i) const
152  { return *Offset(i,-1); }
153  // rated_dimensions 8 x+1.0
154  uint RatedDimensions(uint i) const
155  { return *(Offset(i,-1) + 1); }
156  // for (j=0;j<rated_dimensions;j++) {
157  // rating_dimension_j 8 y+0.0
158  uint RatingDimension(uint i, uint j) const
159  { return *Offset(i,j); }
160  // reserved 4 y+1.0 0x0f
161  // rating_value 4 y+1.4
162  uint RatingValue(uint i, uint j) const
163  { return (*(Offset(i,j) + 1)) & 0xf; }
164  // }
165  // rating_desc_length 8 x+2+(rated_dimensions*2)+0.0
166  uint RatingDescriptionLength(uint i) const
167  { return (*(Offset(i,-1) + 2 + (RatedDimensions(i)<<1))); }
168  // rating_desc_text x+2+(rated_dimensions*2)+1.0
169  const MultipleStringStructure RatingDescription(uint i) const
170  {
171  const unsigned char *data = Offset(i,-1) + 3 + (RatedDimensions(i)<<1);
172  return MultipleStringStructure(data);
173  }
174  // }
175 
176  bool Parse(void);
177  QString toString() const;
178  protected:
179  int Index(int i, int j) const { return (i<<8)|(j&0xff); }
180  const unsigned char *Offset(int i, int j) const
181  {
182  IntToBuf::const_iterator it = _ptrs.find(Index(i,j));
183  return (it != _ptrs.end()) ? *it : NULL;
184  }
186 };
187 
189 {
190  public:
191  ComponentNameDescriptor(const unsigned char *data, int len = 300) :
192  MPEGDescriptor(data, len, DescriptorID::component_name)
193  {
194  }
195  const MultipleStringStructure ComponentNameStrings() const
196  {
197  return MultipleStringStructure(_data+2);
198  }
199  QString toString() const
200  {
201  return QString("Component Name Descriptor %1")
202  .arg(ComponentNameStrings().toString());
203  }
204 };
205 
206 
207 // a_52a.pdf p120, Table A2
209 {
210  public:
211  AudioStreamDescriptor(const unsigned char *data, int len = 300) :
212  MPEGDescriptor(data, len, DescriptorID::ac3_audio_stream) { }
213  // descriptor_tag 8 0.0 0x81
214  // sample_rate_code 3 2.0
215  uint SampleRateCode(void) const { return (_data[2]>>5)&7; }
216  QString SampleRateCodeString(void) const;
217  // bsid 5 2.3
218  uint bsid(void) const { return _data[2]&0x1f; }
219  // bit_rate_code 6 3.0
220  uint BitRateCode(void) const { return (_data[3]>>2)&0x3f; }
221  QString BitRateCodeString(void) const;
222  // surround_mode 2 3.6
223  uint SurroundMode(void) const { return _data[3]&3; }
224  QString SurroundModeString(void) const;
225  /*
226  000 Major ?
227  001 Major ?
228  010-111 Minor
229  111 Karaoke Mode if acmod >= 0x2. a_52a.pdf p130
230  */
231  // bsmod 3 4.0
232  uint BasicServiceMode(void) const { return (_data[4]>>5)&7; }
233  // num_channels 4 4.3
234  uint Channels(void) const { return (_data[4]>>1)&0xf; }
235  QString ChannelsString(void) const;
236 
237  // full service that can be presented alone to listener?
238  // full_svc 1 4.7
239  bool FullService(void) const { return bool((_data[4])&1); }
240 
241  // langcod 8 5.0
242  // ignore for language specification
243  uint LanguageCode(void) const { return _data[5]; }
244  // if(num_channels==0) /* 1+1 mode */
245  // langcod2 8 6.0
246  // ignore for language specification
247  uint LanguageCode2(void) const { return _data[6]; }
248 
249  // if(bsmod<2) {
250  // mainid 3 7.0/6.0
251  uint MainID(void) const
252  {
253  return _data[(Channels()==0)?7:6]>>5;
254  }
255  // reserved 5 7.3/6.3
256  //uint reserved(void) const { return _data[7]&0x1f; }
257  // } else asvcflags 8 7.0/6.0
258  uint AServiceFlags(void) const
259  {
260  return _data[(Channels()==0)?7:6];
261  }
262 
263  // textlen 7 8.0/7.0
264  uint TextLength(void) const
265  {
266  return _data[(Channels()==0)?8:7]>>1;
267  }
268 
269  /* If this bit is a 1 , the text is encoded as 1-byte characters
270  using the ISO Latin-1 alphabet (ISO 8859-1). If this bit is a 0,
271  the text is encoded with 2-byte unicode characters. */
272  // text_code 1 bslbf
273  bool IsTextLatin1(void) const
274  {
275  return bool(_data[(Channels()==0)?8:7]&1);
276  }
277  // for(i=0; i<M; i++) {
278  // text[i] 8 bslbf
279  // }
280  QString Text(void) const
281  { // TODO
282 #if 0
283  char *tmp = new char[TextLength()+2];
284  if (IsTextLatin1())
285  {
286  memcpy(tmp, &_data[(Channels()==0)?9:8], TextLength());
287  tmp[TextLength()]=0;
288  for (uint i=0; i<TextLength(); i++)
289  if (!tmp[i]) tmp[i]='H';
290  QString str(tmp);
291  delete[] tmp;
292  return str;
293  }
294  else
295  {
296  QString str; int len = TextLength();
297  const unsigned char *buf = (&_data[(Channels()==0)?9:8]);
298  const unsigned short* ustr =
299  reinterpret_cast<const unsigned short*>(buf);
300  for (int j=0; j<(len>>1); j++)
301  str.append( QChar( (ustr[j]<<8) | (ustr[j]>>8) ) );
302  return str;
303  }
304 #endif
305  return QString("TODO");
306  }
307  // for(i=0; i<N; i++) {
308  // additional_info[i] N×8 bslbf
309  // }
310 
311  QString toString() const;
312 };
313 
319 {
320  ContentIdentifierDescriptor(const unsigned char *data, int len = 300) :
321  MPEGDescriptor(data, len, DescriptorID::atsc_content_identifier) { }
322  // descriptor_tag 8 0.0 0xB6
323  // descriptor_length 8 1.0
324  // content_ID_structure
325  // ID_system 8 2.0
326  // 0x00 ISAN (ISO 15706[1])
327  // 0x01 V-ISAN (ISO 20925-1[2])
328  // 0x02-0xFF ATSC Reserved
329  // ID_length 8 3.0
330  // content_identifier v 4.0
331 };
332 
341 {
342  public:
343  ExtendedChannelNameDescriptor(const unsigned char *data, int len = 300) :
344  MPEGDescriptor(data, len, DescriptorID::extended_channel_name) { }
345  MultipleStringStructure LongChannelName(void) const;
346  QString LongChannelNameString(void) const;
347  QString toString() const;
348 };
349 
350 #endif