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
8
9#include "atscdescriptors.h"
10#include "atsc_huffman.h"
11
13{
14 uint ct = CompressionType(i, j);
15 if (0 == ct)
16 return {"no compression"};
17 if (1 == ct)
18 return {"Huffman Coding using C.4, C.5"};
19 if (2 == ct)
20 return {"Huffman Coding using C.6, C.7"};
21 if (ct < 0xaf)
22 return {"reserved"};
23 return {"compression not used by ATSC in North America, unknown"};
24}
25
27{
28 QString str;
29 if (1 == StringCount() && 1 == SegmentCount(0))
30 {
31 str.append(QString("lang(%1) ").arg(LanguageString(0)));
32 if (0 != Bytes(0, 0))
33 str.append(GetSegment(0, 0));
34 return str;
35 }
36
37 str.append(QString("MultipleStringStructure count(%1)")
38 .arg(StringCount()));
39
40 for (uint i = 0; i < StringCount(); i++)
41 {
42 str.append(QString(" String #%1 lang(%2:%3)")
43 .arg(i).arg(LanguageString(i))
44 .arg(LanguageKey(i)));
45
46 if (SegmentCount(i) > 1)
47 str.append(QString(" segment count(%1)").arg(SegmentCount(i)));
48
49 for (uint j=0; j<SegmentCount(i); j++)
50 str.append(QString(" Segment #%1 ct(%2) str(%3)").arg(j)
51 .arg(CompressionType(i, j)).arg(GetSegment(i, j)));
52 }
53
54 return str;
55}
56
57static uint maxPriority(const QMap<uint,uint> &langPrefs)
58{
59 uint max_pri = 0;
60 for (uint pref : std::as_const(langPrefs))
61 max_pri = std::max(max_pri, pref);
62 return max_pri;
63}
64
66 QMap<uint,uint> &langPrefs) const
67{
68 uint match_idx = 0;
69 uint match_pri = 0;
70
71 for (uint i = 0; i < StringCount(); i++)
72 {
73 QMap<uint,uint>::const_iterator it =
74 langPrefs.constFind(CanonicalLanguageKey(i));
75 if ((it != langPrefs.constEnd()) && (*it > match_pri))
76 {
77 match_idx = i;
78 match_pri = *it;
79 }
80 }
81
82 if (match_pri)
83 return match_idx;
84
85 if (StringCount())
86 langPrefs[CanonicalLanguageKey(0)] = maxPriority(langPrefs) + 1;
87
88 return 0;
89}
90
91QString MultipleStringStructure::GetBestMatch(QMap<uint,uint> &langPrefs) const
92{
93 if (StringCount())
94 return GetFullString(GetIndexOfBestMatch(langPrefs));
95 return {};
96}
97
99{
100 const unsigned char* buf = (Offset(i, j)+3);
101 int len = Bytes(i, j);
102
103 if (len <= 0)
104 return "";
105
106 int ct = CompressionType(i, j);
107
108 if (ct == 0)
109 return Uncompressed(buf, len, Mode(i, j));
110
111 if (ct < 3)
112 return atsc_huffman1_to_string(buf, len, ct);
113
114 return QString("MSS unknown text compression %1").arg(ct);
115}
116
118{
119 QString tmp = "";
120 for (uint j = 0; j < SegmentCount(i); j++)
121 tmp += GetSegment(i, j);
122 return tmp.simplified();
123}
124
126 const unsigned char* buf, int len, int mode) {
127
128 QString str=QString("");
129 if (mode<=6 ||
130 (9<=mode && mode<=0xe) ||
131 (0x10==mode) ||
132 (0x20<=mode && mode<=0x27) ||
133 (0x30<=mode && mode<=0x33)) { // basic runlength encoding
134 int hb=mode<<8;
135 for (int j=0; j<len; j++)
136 {
137#if 0
138 LOG(VB_GENERAL, LOG_DEBUG, QString("str.append(0x%1:0x%2) -> %3")
139 .arg(mode, 0, 16) .arg(buf[j], 0, 16) .arg(QChar(hb|buf[j])));
140#endif
141 if (hb|buf[j])
142 str.append( QChar( hb|buf[j] ) );
143 }
144 } else if (mode==0x3e) {
145 // Standard Compression Scheme for Unicode (SCSU)
146 str=QString("TODO SCSU encoding");
147 } else if (mode==0x3f) { // Unicode, UTF-16 Form
148 const auto* ustr = reinterpret_cast<const unsigned short*>(buf);
149 for (int j=0; j<(len>>1); j++)
150 str.append( QChar( (ustr[j]<<8) | (ustr[j]>>8) ) );
151 } else if (0x40<=mode && mode<=0x41) {
152 str = QString("TODO Tawain Characters");
153 } else if (0x48==mode) {
154 str = QString("TODO South Korean Characters");
155 } else {
156 str = QString("unknown character encoding mode(%0)").arg(mode);
157 }
158 return str;
159}
160
162{
163 m_ptrs.clear();
164 m_ptrs[Index(0,-1)] = m_data + 1;
165 for (uint i = 0; i < StringCount(); i++)
166 {
167 m_ptrs[Index(i,0)] = Offset(i,-1) + 4;
168 uint j = 0;
169 for (; j < SegmentCount(i); j++)
170 m_ptrs[Index(i,j+1)] = Offset(i,j) + Bytes(i,j) + 3;
171 m_ptrs[Index(i+1,-1)] = Offset(i,j);
172 }
173}
174
176{
177 m_ptrs.clear();
178 m_ptrs[Index(0,-1)] = m_data+3;
179
180 for (uint i = 0; i < ServicesCount(); i++)
181 m_ptrs[Index(i+1,-1)] = Offset(i,-1) + 6;
182
183 return true;
184}
185
187{
188 QString str("Caption Service Descriptor ");
189 str.append(QString("services(%2)").arg(ServicesCount()));
190
191 for (uint i = 0; i < ServicesCount(); i++)
192 {
193 str.append(QString("\n lang(%1) type(%2) ")
194 .arg(LanguageString(i)).arg(static_cast<int>(Type(i))));
195 str.append(QString("easy_reader(%1) wide(%2) ")
196 .arg(static_cast<int>(EasyReader(i))).arg(static_cast<int>(WideAspectRatio(i))));
197 if (Type(i))
198 {
199 str.append(QString("service_num(%1)")
200 .arg(CaptionServiceNumber(i)));
201 }
202 else
203 {
204 str.append(QString("line_21_field(%1)").arg(static_cast<int>(Line21Field(i))));
205 }
206 }
207
208 return str;
209}
210
212{
213 m_ptrs.clear();
214 m_ptrs[Index(0,-1)] = m_data + 2;
215
216 for (uint i = 0; i < RatingRegionCount(); i++)
217 {
218 m_ptrs[Index(i,0)] = Offset(i,-1)+2;
219 uint j = 0;
220 for (; j < RatedDimensions(i); j++)
221 m_ptrs[Index(i,j+1)] = Offset(i,j) + 2;
222 const unsigned char *tmp = Offset(i,-1) + 3 + (RatedDimensions(i)<<1);
224 m_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 std::array<const std::string,8> s_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::fromStdString(s_asd[SampleRateCode()]);
244}
245
247{
248 static const std::array<const std::string,19> s_ebr
249 {
250 "=32kbps", "=40kbps", "=48kbps", "=56kbps", "=64kbps",
251 "=80kbps", "=96kbps", "=112kbps", "=128kbps", "=160kbps",
252 "=192kbps", "=224kbps", "=256kbps", "=320kbps", "=384kbps",
253 "=448kbps", "=512kbps", "=576kbps", "=640kbps"
254 };
255 static const std::array<const std::string,19> s_ubr
256 {
257 "<=32kbps", "<=40kbps", "<=48kbps", "<=56kbps", "<=64kbps",
258 "<=80kbps", "<=96kbps", "<=112kbps", "<=128kbps", "<=160kbps",
259 "<=192kbps","<=224kbps", "<=256kbps", "<=320kbps", "<=384kbps",
260 "<=448kbps","<=512kbps", "<=576kbps", "<=640kbps"
261 };
262
263 if (BitRateCode() <= 18)
264 return QString::fromStdString(s_ebr[BitRateCode()]);
265 if ((BitRateCode() >= 32) && (BitRateCode() <= 50))
266 return QString::fromStdString(s_ubr[BitRateCode()-32]);
267 return {"Unknown Bit Rate Code"};
268}
269
271{
272 static const std::array<const std::string,4> s_sms
273 {
274 "Not indicated",
275 "Not Dolby surround encoded",
276 "Dolby surround encoded",
277 "Reserved",
278 };
279 return QString::fromStdString(s_sms[SurroundMode()]);
280}
281
283{
284 static const std::array<const std::string,16> s_cs
285 {
286 "1 + 1", "1/0", "2/0", "3/0",
287 "2/1", "3/1", "2/2 ", "3/2",
288 "1", "<= 2", "<= 3", "<= 4",
289 "<= 5", "<= 6", "Reserved", "Reserved"
290 };
291 return QString::fromStdString(s_cs[Channels()]);
292}
293
295{
296 QString str;
297 str.append(QString("AC-3 Audio Stream Descriptor "));
298 str.append(QString(" full_srv(%1) sample_rate(%2) bit_rate(%3, %4)\n")
299 .arg(static_cast<int>(FullService()))
302 .arg(BitRateCode()));
303 str.append(QString(" bsid(%1) bs_mode(%2) channels(%3) Dolby(%4)\n")
304 .arg(bsid()).arg(BasicServiceMode())
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{
338}
339
345{
346 QString str = "";
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}
QString atsc_huffman1_to_string(const unsigned char *compressed, uint size, uint table_index)
static uint maxPriority(const QMap< uint, uint > &langPrefs)
bool IsTextLatin1(void) const
QString BitRateCodeString(void) const
uint TextLength(void) const
QString SurroundModeString(void) const
uint BitRateCode(void) const
bool FullService(void) const
QString ChannelsString(void) const
uint SurroundMode(void) const
QString SampleRateCodeString(void) const
uint Channels(void) const
uint AServiceFlags(void) const
uint BasicServiceMode(void) const
QString toString() const override
QString Text(void) const
uint SampleRateCode(void) const
bool EasyReader(int i) const
QString toString() const override
bool Line21Field(int i) const
static int Index(int i, int j)
bool Type(int i) const
bool WideAspectRatio(int i) const
int CaptionServiceNumber(int i) const
const unsigned char * Offset(int i, int j) const
QString LanguageString(int i) const
QString toString() const override
static int Index(int i, int j)
const unsigned char * Offset(int i, int j) const
uint RatingDescriptionLength(uint i) const
uint RatedDimensions(uint i) const
uint RatingRegionCount(void) const
MultipleStringStructure LongChannelName(void) const
Returns a MultipleStringStructure representing the long name of the associated channel.
QString toString() const override
QString LongChannelNameString(void) const
Convenience function that returns a QString comprising a concatenation of all the segments in the Lon...
const unsigned char * m_data
QString GetSegment(uint i, uint j) const
uint GetIndexOfBestMatch(QMap< uint, uint > &langPrefs) const
QString CompressionTypeString(uint i, uint j) const
const unsigned char * Offset(int i, int j) const
QString GetFullString(uint i) const
uint StringCount(void) const
uint SegmentCount(uint i) const
int Bytes(int i, int j) const
uint CompressionType(uint i, uint j) const
int Mode(int i, int j) const
const unsigned char * m_data
QString LanguageString(uint i) const
int LanguageKey(uint i) const
QString GetBestMatch(QMap< uint, uint > &langPrefs) const
int CanonicalLanguageKey(uint i) const
static QString Uncompressed(const unsigned char *buf, int len, int mode)
static uint Index(int i, int j)
unsigned int uint
Definition: freesurround.h:24
static guint32 * tmp
Definition: goom_core.cpp:26
ISO 639-1 and ISO 639-2 support functions.
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
Definition: mythlogging.h:39