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  if ((BitRateCode() >= 32) && (BitRateCode() <= 50))
267  return QString(ubr[BitRateCode()-32]);
268  return QString("Unknown Bit Rate Code");
269 }
270 
272 {
273  static const char* sms[] =
274  {
275  "Not indicated",
276  "Not Dolby surround encoded",
277  "Dolby surround encoded",
278  "Reserved",
279  };
280  return QString(sms[SurroundMode()]);
281 }
282 
284 {
285  static const char* cs[] =
286  {
287  "1 + 1", "1/0", "2/0", "3/0",
288  "2/1", "3/1", "2/2 ", "3/2",
289  "1", "<= 2", "<= 3", "<= 4",
290  "<= 5", "<= 6", "Reserved", "Reserved"
291  };
292  return cs[Channels()];
293 }
294 
296 {
297  QString str;
298  str.append(QString("Audio Stream Descriptor "));
299  str.append(QString(" full_srv(%1) sample_rate(%2) bit_rate(%3, %4)\n")
300  .arg(FullService()).arg(SampleRateCodeString())
301  .arg(BitRateCodeString()).arg(BitRateCode()));
302  str.append(QString(" bsid(%1) bs_mode(%2) channels(%3) Dolby(%4)\n")
303  .arg(bsid()).arg(BasicServiceMode())
304  .arg(ChannelsString()).arg(SurroundModeString()));
305 
306  /*
307  str.append(QString(" language code: %1").arg(languageCode()));
308  if (0==channels()) {
309  str.append(QString(" language code 2: %1").arg(languageCode2()));
310  }
311  */
312 
313  if (BasicServiceMode() < 2)
314  str.append(QString(" mainID(%1) ").arg(MainID()));
315  else
316  str.append(QString(" associated_service(0x%1) ")
317  .arg(AServiceFlags(),0,16));
318 
319  if (TextLength())
320  {
321  str.append(QString("isLatin-1(%1) ")
322  .arg(IsTextLatin1() ? "true" : "false"));
323  str.append(QString("text_length(%1) ").arg(TextLength()));
324  str.append(QString("text(%1)").arg(Text()));
325  }
326  return str;
327 }
328 
334  void) const
335 {
336  return MultipleStringStructure(_data + 2);
337 }
338 
344 {
345  QString str = "";
346  MultipleStringStructure mstr = LongChannelName();
347 
348  for (uint i = 0; i < mstr.StringCount(); i++)
349  str += mstr.GetFullString(i);
350 
351  return str;
352 }
353 
355 {
356  return QString("ExtendedChannelNameDescriptor: '%1'")
357  .arg(LongChannelNameString());
358 }
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