MythTV  master
atscdescriptors.cpp
Go to the documentation of this file.
1 // -*- Mode: c++ -*-
2 // Copyright (c) 2003-2004, Daniel Thor Kristjansson
3 
4 #include <algorithm>
5 using namespace std;
6 
7 #include "atscdescriptors.h"
8 #include "mythlogging.h"
9 #include "iso639.h"
10 #include "atsc_huffman.h"
11 
12 using namespace std;
13 
14 
16 {
17  uint ct = CompressionType(i, j);
18  if (0 == ct)
19  return QString("no compression");
20  if (1 == ct)
21  return QString("Huffman Coding using C.4, C.5");
22  if (2 == ct)
23  return QString("Huffman Coding using C.6, C.7");
24  if (ct < 0xaf)
25  return QString("reserved");
26  return QString("compression not used by ATSC in North America, unknown");
27 }
28 
30 {
31  QString str;
32  if (1 == StringCount() && 1 == SegmentCount(0))
33  {
34  str.append(QString("lang(%1) ").arg(LanguageString(0)));
35  if (0 != Bytes(0, 0))
36  str.append(GetSegment(0, 0));
37  return str;
38  }
39 
40  str.append(QString("MultipleStringStructure count(%1)")
41  .arg(StringCount()));
42 
43  for (uint i = 0; i < StringCount(); i++)
44  {
45  str.append(QString(" String #%1 lang(%2:%3)")
46  .arg(i).arg(LanguageString(i))
47  .arg(LanguageKey(i)));
48 
49  if (SegmentCount(i) > 1)
50  str.append(QString(" segment count(%1)").arg(SegmentCount(i)));
51 
52  for (uint j=0; j<SegmentCount(i); j++)
53  str.append(QString(" Segment #%1 ct(%2) str(%3)").arg(j)
54  .arg(CompressionType(i, j)).arg(GetSegment(i, j)));
55  }
56 
57  return str;
58 }
59 
60 static uint maxPriority(const QMap<uint,uint> &langPrefs)
61 {
62  uint max_pri = 0;
63  QMap<uint,uint>::const_iterator it = langPrefs.begin();
64  for (; it != langPrefs.end(); ++it)
65  max_pri = max(max_pri, *it);
66  return max_pri;
67 }
68 
70  QMap<uint,uint> &langPrefs) const
71 {
72  uint match_idx = 0;
73  uint match_pri = 0;
74 
75  for (uint i = 0; i < StringCount(); i++)
76  {
77  QMap<uint,uint>::const_iterator it =
78  langPrefs.find(CanonicalLanguageKey(i));
79  if ((it != langPrefs.end()) && (*it > match_pri))
80  {
81  match_idx = i;
82  match_pri = *it;
83  }
84  }
85 
86  if (match_pri)
87  return match_idx;
88 
89  if (StringCount())
90  langPrefs[CanonicalLanguageKey(0)] = maxPriority(langPrefs) + 1;
91 
92  return 0;
93 }
94 
95 QString MultipleStringStructure::GetBestMatch(QMap<uint,uint> &langPrefs) const
96 {
97  if (StringCount())
98  return GetFullString(GetIndexOfBestMatch(langPrefs));
99  return QString();
100 }
101 
103 {
104  const unsigned char* buf = (Offset(i, j)+3);
105  int len = Bytes(i, j);
106 
107  if (len <= 0)
108  return "";
109 
110  int ct = CompressionType(i, j);
111 
112  if (ct == 0)
113  return Uncompressed(buf, len, Mode(i, j));
114 
115  if (ct < 3)
116  return atsc_huffman1_to_string(buf, len, ct);
117 
118  return QString("MSS unknown text compression %1").arg(ct);
119 }
120 
122 {
123  QString tmp = "";
124  for (uint j = 0; j < SegmentCount(i); j++)
125  tmp += GetSegment(i, j);
126  return tmp.simplified();
127 }
128 
130  const unsigned char* buf, int len, int mode) {
131 
132  QString str=QString("");
133  if (mode<=6 ||
134  (9<=mode && mode<=0xe) ||
135  (0x10==mode) ||
136  (0x20<=mode && mode<=0x27) ||
137  (0x30<=mode && mode<=0x33)) { // basic runlength encoding
138  int hb=mode<<8;
139  for (int j=0; j<len; j++)
140  {
141 #if 0
142  LOG(VB_GENERAL, LOG_DEBUG, QString("str.append(0x%1:0x%2) -> %3")
143  .arg(mode, 0, 16) .arg(buf[j], 0, 16) .arg(QChar(hb|buf[j])));
144 #endif
145  if (hb|buf[j])
146  str.append( QChar( hb|buf[j] ) );
147  }
148  } else if (mode==0x3e) {
149  // Standard Compression Scheme for Unicode (SCSU)
150  str=QString("TODO SCSU encoding");
151  } else if (mode==0x3f) { // Unicode, UTF-16 Form
152  const unsigned short* ustr =
153  reinterpret_cast<const unsigned short*>(buf);
154  for (int j=0; j<(len>>1); j++)
155  str.append( QChar( (ustr[j]<<8) | (ustr[j]>>8) ) );
156  } else if (0x40<=mode && mode<=0x41)
157  str = QString("TODO Tawain Characters");
158  else if (0x48==mode)
159  str = QString("TODO South Korean Characters");
160  else
161  str = QString("unknown character encoding mode(%0)").arg(mode);
162  return str;
163 }
164 
166 {
167  _ptrs.clear();
168  _ptrs[Index(0,-1)] = _data + 1;
169  for (uint i = 0; i < StringCount(); i++)
170  {
171  _ptrs[Index(i,0)] = Offset(i,-1) + 4;
172  uint j = 0;
173  for (; j < SegmentCount(i); j++)
174  _ptrs[Index(i,j+1)] = Offset(i,j) + Bytes(i,j) + 3;
175  _ptrs[Index(i+1,-1)] = Offset(i,j);
176  }
177 }
178 
180 {
181  _ptrs.clear();
182  _ptrs[Index(0,-1)] = _data+3;
183 
184  for (uint i = 0; i < ServicesCount(); i++)
185  _ptrs[Index(i+1,-1)] = Offset(i,-1) + 6;
186 
187  return true;
188 }
189 
191 {
192  QString str("Caption Service Descriptor ");
193  str.append(QString("services(%2)").arg(ServicesCount()));
194 
195  for (uint i = 0; i < ServicesCount(); i++)
196  {
197  str.append(QString("\n lang(%1) type(%2) ")
198  .arg(LanguageString(i)).arg(Type(i)));
199  str.append(QString("easy_reader(%1) wide(%2) ")
200  .arg(EasyReader(i)).arg(WideAspectRatio(i)));
201  if (Type(i))
202  str.append(QString("service_num(%1)")
203  .arg(CaptionServiceNumber(i)));
204  else
205  str.append(QString("line_21_field(%1)").arg(Line21Field(i)));
206  }
207 
208  return str;
209 }
210 
212 {
213  _ptrs.clear();
214  _ptrs[Index(0,-1)] = _data + 2;
215 
216  for (uint i = 0; i < RatingRegionCount(); i++)
217  {
218  _ptrs[Index(i,0)] = Offset(i,-1)+2;
219  uint j = 0;
220  for (; j < RatedDimensions(i); j++)
221  _ptrs[Index(i,j+1)] = Offset(i,j) + 2;
222  const unsigned char *tmp = Offset(i,-1) + 3 + (RatedDimensions(i)<<1);
223  uint len = RatingDescriptionLength(i);
224  _ptrs[Index(i+1,-1)] = tmp + len;
225  }
226 
227  return true;
228 }
229 
231 {
232  return "ContentAdvisoryDescriptor::toString(): Not implemented";
233 }
234 
236 {
237  static const char* asd[] =
238  {
239  "48kbps", "44.1kbps", "32kbps", "Reserved",
240  "48kbps or 44.1kbps", "48kbps or 32kbps",
241  "44.1kbps or 32kbps", "48kbps or 44.1kbps or 32kbps"
242  };
243  return QString(asd[SampleRateCode()]);
244 }
245 
247 {
248  // cppcheck-suppress variableScope
249  static const char* ebr[19] =
250  {
251  "=32kbps", "=40kbps", "=48kbps", "=56kbps", "=64kbps",
252  "=80kbps", "=96kbps", "=112kbps", "=128kbps", "=160kbps",
253  "=192kbps", "=224kbps", "=256kbps", "=320kbps", "=384kbps",
254  "=448kbps", "=512kbps", "=576kbps", "=640kbps"
255  };
256  static const char* ubr[19] =
257  {
258  "<=32kbps", "<=40kbps", "<=48kbps", "<=56kbps", "<=64kbps",
259  "<=80kbps", "<=96kbps", "<=112kbps", "<=128kbps", "<=160kbps",
260  "<=192kbps","<=224kbps", "<=256kbps", "<=320kbps", "<=384kbps",
261  "<=448kbps","<=512kbps", "<=576kbps", "<=640kbps"
262  };
263 
264  if (BitRateCode() <= 18)
265  return QString(ebr[BitRateCode()]);
266  else if ((BitRateCode() >= 32) && (BitRateCode() <= 50))
267  return QString(ubr[BitRateCode()-32]);
268 
269  return QString("Unknown Bit Rate Code");
270 }
271 
273 {
274  static const char* sms[] =
275  {
276  "Not indicated",
277  "Not Dolby surround encoded",
278  "Dolby surround encoded",
279  "Reserved",
280  };
281  return QString(sms[SurroundMode()]);
282 }
283 
285 {
286  static const char* cs[] =
287  {
288  "1 + 1", "1/0", "2/0", "3/0",
289  "2/1", "3/1", "2/2 ", "3/2",
290  "1", "<= 2", "<= 3", "<= 4",
291  "<= 5", "<= 6", "Reserved", "Reserved"
292  };
293  return cs[Channels()];
294 }
295 
297 {
298  QString str;
299  str.append(QString("Audio Stream Descriptor "));
300  str.append(QString(" full_srv(%1) sample_rate(%2) bit_rate(%3, %4)\n")
301  .arg(FullService()).arg(SampleRateCodeString())
302  .arg(BitRateCodeString()).arg(BitRateCode()));
303  str.append(QString(" bsid(%1) bs_mode(%2) channels(%3) Dolby(%4)\n")
304  .arg(bsid()).arg(BasicServiceMode())
305  .arg(ChannelsString()).arg(SurroundModeString()));
306 
307  /*
308  str.append(QString(" language code: %1").arg(languageCode()));
309  if (0==channels()) {
310  str.append(QString(" language code 2: %1").arg(languageCode2()));
311  }
312  */
313 
314  if (BasicServiceMode() < 2)
315  str.append(QString(" mainID(%1) ").arg(MainID()));
316  else
317  str.append(QString(" associated_service(0x%1) ")
318  .arg(AServiceFlags(),0,16));
319 
320  if (TextLength())
321  {
322  str.append(QString("isLatin-1(%1) ")
323  .arg(IsTextLatin1() ? "true" : "false"));
324  str.append(QString("text_length(%1) ").arg(TextLength()));
325  str.append(QString("text(%1)").arg(Text()));
326  }
327  return str;
328 }
329 
335  void) const
336 {
337  return MultipleStringStructure(_data + 2);
338 }
339 
345 {
346  QString str = "";
347  MultipleStringStructure mstr = LongChannelName();
348 
349  for (uint i = 0; i < mstr.StringCount(); i++)
350  str += mstr.GetFullString(i);
351 
352  return str;
353 }
354 
356 {
357  return QString("ExtendedChannelNameDescriptor: '%1'")
358  .arg(LongChannelNameString());
359 }
ISO 639-1 and ISO 639-2 support functions.
QString toString() const override
QString toString() const override
QString LongChannelNameString(void) const
Convenience function that returns a QString comprising a concatenation of all the segments in the Lon...
unsigned int uint
Definition: compat.h:140
QString SampleRateCodeString(void) const
static guint32 * tmp
Definition: goom_core.c:35
MultipleStringStructure LongChannelName(void) const
Returns a MultipleStringStructure representing the long name of the associated channel.
QString toString() const override
uint StringCount(void) const
QString CompressionTypeString(uint i, uint j) const
QString GetFullString(uint i) const
static QString Uncompressed(const unsigned char *buf, int len, int mode)
static uint maxPriority(const QMap< uint, uint > &langPrefs)
uint GetIndexOfBestMatch(QMap< uint, uint > &langPrefs) const
QString GetBestMatch(QMap< uint, uint > &langPrefs) const
QString toString() const override
QString BitRateCodeString(void) const
QString GetSegment(uint i, uint j) const
#define LOG(_MASK_, _LEVEL_, _STRING_)
Definition: mythlogging.h:41
QString ChannelsString(void) const
QString atsc_huffman1_to_string(const unsigned char *compressed, uint size, uint table_index)
QString SurroundModeString(void) const