MythTV master
dvbtables.cpp
Go to the documentation of this file.
1// -*- Mode: c++ -*-
2// Copyright (c) 2005, Daniel Thor Kristjansson
3
4#include <cmath>
5
6#include <QTimeZone>
7
8#include "dvbtables.h"
9#include "dvbdescriptors.h"
10
11static uint GetPrivateDataSpecifier(const unsigned char *desc, uint priv_dsid)
12{
14 {
16 if (pd.IsValid())
17 priv_dsid = pd.PrivateDataSpecifier();
18 }
19 return priv_dsid;
20}
21
23{
25
26 m_ptrs.clear();
27 m_ptrs.push_back(m_tscPtr + 2);
28 for (uint i=0; m_ptrs[i] + 6 <= m_ptrs[0] + TransportStreamDataLength(); i++)
29 m_ptrs.push_back(m_ptrs[i] + 6 + TransportDescriptorsLength(i));
30}
31
33{
34 QString str = QString("NIT: NetID(%1) transports(%2)\n")
35 .arg(NetworkID()).arg(TransportStreamCount());
36 str.append(QString("Section (%1) Last Section (%2) IsCurrent (%3)\n")
37 .arg(Section()).arg(LastSection()).arg(static_cast<int>(IsCurrent())));
38
39 if (0 != NetworkDescriptorsLength())
40 {
41 str.append(QString("Network descriptors length: %1\n")
43 std::vector<const unsigned char*> desc =
46 uint priv_dsid = 0;
47 for (auto & i : desc)
48 {
49 priv_dsid = GetPrivateDataSpecifier(i, priv_dsid);
50 str.append(QString(" %1\n")
51 .arg(MPEGDescriptor(i).toStringPD(priv_dsid)));
52 }
53 }
54
55 for (uint i = 0; i < TransportStreamCount(); i++)
56 {
57 str.append(QString(" Transport #%1 TSID(0x%2) ")
58 .arg(i, 2, 10).arg(TSID(i), 0, 16));
59 str.append(QString("original_network_id(0x%2) desc_len(%3)\n")
60 .arg(OriginalNetworkID(i), 0, 16)
62
64 {
65 str.append(QString(" Transport descriptors length: %1\n")
67 std::vector<const unsigned char*> desc =
70 uint priv_dsid = 0;
71 for (auto & j : desc)
72 {
73 priv_dsid = GetPrivateDataSpecifier(j, priv_dsid);
74 str.append(QString(" %1\n")
75 .arg(MPEGDescriptor(j).toStringPD(priv_dsid)));
76 }
77 }
78 }
79 return str;
80}
81
83{
84 if (m_cachedNetworkName.isEmpty())
85 {
86 desc_list_t parsed =
89
90 const unsigned char *desc =
92
93 if (desc)
94 {
95 auto nndesc = NetworkNameDescriptor(desc);
96 if (nndesc.IsValid())
97 m_cachedNetworkName = nndesc.Name();
98 }
99 if (m_cachedNetworkName.isEmpty())
100 m_cachedNetworkName = QString("Net ID 0x%1")
101 .arg(NetworkID(), 0, 16);
102 }
103 return m_cachedNetworkName;
104}
105
107{
108 if (VerifyCRC())
109 {
111 SetCRC(CalcCRC());
112 return true;
113 }
114 return false;
115}
116
118{
119 m_ptrs.clear();
120 m_ptrs.push_back(pesdata() + 11);
121 uint i = 0;
122 while ((m_ptrs[i] + 5) < (pesdata() + Length()))
123 {
124 m_ptrs.push_back(m_ptrs[i] + 5 + ServiceDescriptorsLength(i));
125 i++;
126 }
127}
128
130{
131 QString str =
132 QString("SDT: TSID(0x%1) original_network_id(0x%2) services(%3)\n")
133 .arg(TSID(), 0, 16).arg(OriginalNetworkID(), 0, 16)
134 .arg(ServiceCount());
135 str.append(QString("Section (%1) Last Section (%2) IsCurrent (%3)\n")
136 .arg(Section()).arg(LastSection()).arg(static_cast<int>(IsCurrent())));
137
138 for (uint i = 0; i < ServiceCount(); i++)
139 {
140 str.append(QString(" Service #%1 SID(0x%2) ")
141 .arg(i, 2, 10).arg(ServiceID(i), 0, 16));
142 str.append(QString("eit_schd(%1) eit_pf(%2) encrypted(%3)\n")
143 .arg(HasEITSchedule(i) ? "t" : "f",
144 HasEITPresentFollowing(i) ? "t" : "f",
145 IsEncrypted(i) ? "t" : "f"));
146
147 if (0 != ServiceDescriptorsLength(i))
148 {
149 str.append(QString(" Service descriptors length: %1\n")
150 .arg(ServiceDescriptorsLength(i)));
151 std::vector<const unsigned char*> desc =
154 uint priv_dsid = 0;
155 for (auto & j : desc)
156 {
157 priv_dsid = GetPrivateDataSpecifier(j, priv_dsid);
158 str.append(QString(" %1\n")
159 .arg(MPEGDescriptor(j).toStringPD(priv_dsid)));
160 }
161 }
162 }
163 return str;
164}
165
167{
168 desc_list_t parsed =
171
172 const unsigned char *desc =
174
175 if (desc)
176 return new ServiceDescriptor(desc);
177
178 return nullptr;
179}
180
182{
183 desc_list_t parsed =
186
187 const unsigned char *desc =
189
190 if (desc)
191 return new ServiceRelocatedDescriptor(desc);
192
193 return nullptr;
194}
195
197{
198 if (VerifyCRC())
199 {
201 SetCRC(CalcCRC());
202 return true;
203 }
204 return false;
205}
206
208{
210
211 m_ptrs.clear();
212 m_ptrs.push_back(m_tscPtr + 2);
213 for (uint i=0; m_ptrs[i] + 6 <= m_ptrs[0] + TransportStreamDataLength(); i++)
214 m_ptrs.push_back(m_ptrs[i] + 6 + TransportDescriptorsLength(i));
215}
216
218{
219 QString str =
220 QString("BAT: BouquetID(0x%1) transports(%2)\n")
221 .arg(BouquetID(), 0, 16).arg(TransportStreamCount());
222
223 str.append(QString("Section (%1) Last Section (%2) IsCurrent (%3)\n")
224 .arg(Section()).arg(LastSection()).arg(static_cast<int>(IsCurrent())));
225
226 if (0 != BouquetDescriptorsLength())
227 {
228 str.append(QString("Bouquet descriptors length: %1\n")
230 std::vector<const unsigned char*> desc =
233 uint priv_dsid = 0;
234 for (auto & i : desc)
235 {
236 priv_dsid = GetPrivateDataSpecifier(i, priv_dsid);
237 str.append(QString(" %1\n")
238 .arg(MPEGDescriptor(i).toStringPD(priv_dsid)));
239 }
240 }
241
242 for (uint i = 0; i < TransportStreamCount(); i++)
243 {
244 str.append(QString(" Transport #%1 TSID(0x%2) ")
245 .arg(i, 2, 10).arg(TSID(i), 0, 16));
246 str.append(QString("original_network_id(0x%2) desc_len(%3)\n")
247 .arg(OriginalNetworkID(i), 0, 16)
249
250 if (0 != TransportDescriptorsLength(i))
251 {
252 str.append(QString(" Transport descriptors length: %1\n")
254 std::vector<const unsigned char*> desc =
257 uint priv_dsid = 0;
258 for (auto & j : desc)
259 {
260 priv_dsid = GetPrivateDataSpecifier(j, priv_dsid);
261 str.append(QString(" %1\n")
262 .arg(MPEGDescriptor(j).toStringPD(priv_dsid)));
263 }
264 }
265 }
266 return str;
267}
268
269
271{
272 m_ptrs.clear();
273 m_ptrs.push_back(psipdata() + 6);
274 uint i = 0;
275 while ((m_ptrs[i] + 12) < (pesdata() + Length()))
276 {
277 m_ptrs.push_back(m_ptrs[i] + 12 + DescriptorsLength(i));
278 i++;
279 }
280}
281
283{
284 bool is_eit = false;
285
286 // Standard Now/Next Event Information Tables for this transport
287 is_eit |= TableID::PF_EIT == table_id;
288 // Standard Now/Next Event Information Tables for other transport
289 is_eit |= TableID::PF_EITo == table_id;
290 // Standard Future Event Information Tables for this transport
291 is_eit |= (TableID::SC_EITbeg <= table_id &&
292 TableID::SC_EITend >= table_id);
293 // Standard Future Event Information Tables for other transports
294 is_eit |= (TableID::SC_EITbego <= table_id &&
295 TableID::SC_EITendo >= table_id);
296 // Dish Network Long Term Future Event Information for all transports
297 is_eit |= (TableID::DN_EITbego <= table_id &&
298 TableID::DN_EITendo >= table_id);
299
300 return is_eit;
301}
302
306QDateTime dvbdate2qt(const unsigned char *buf)
307{
308 /* FIXME what's wrong with QDate::fromJulianDay? */
309 uint mjd = (buf[0] << 8) | buf[1];
310 if (mjd >= 40587)
311 {
312 // Modified Julian date as number of days since 17th November 1858.
313 // 1st Jan 1970 was date 40587.
314 uint secsSince1970 = (mjd - 40587) * 86400;
315 secsSince1970 += byteBCD2int(buf[2]) * 3600;
316 secsSince1970 += byteBCD2int(buf[3]) * 60;
317 secsSince1970 += byteBCD2int(buf[4]);
318 return MythDate::fromSecsSinceEpoch(secsSince1970);
319 }
320
321 // Original function taken from dvbdate.c in linuxtv-apps code
322 // Use the routine specified in ETSI EN 300 468 V1.4.1,
323 // "Specification for Service Information in Digital Video Broadcasting"
324 // to convert from Modified Julian Date to Year, Month, Day.
325
326 const auto tmpA = (float)(1.0 / 365.25);
327 const auto tmpB = (float)(1.0 / 30.6001);
328
329 float mjdf = mjd;
330 int year = (int) truncf((mjdf - 15078.2F) * tmpA);
331 int month = (int) truncf(
332 (mjdf - 14956.1F - truncf(year * 365.25F)) * tmpB);
333 int day = (int) truncf(
334 (mjdf - 14956.0F - truncf(year * 365.25F) - truncf(month * 30.6001F)));
335 int i = (month == 14 || month == 15) ? 1 : 0;
336
337 QDate date(1900 + year + i, month - 1 - (i * 12), day);
338 QTime time(byteBCD2int(buf[2]), byteBCD2int(buf[3]),
339 byteBCD2int(buf[4]));
340
341#if QT_VERSION < QT_VERSION_CHECK(6,5,0)
342 return {date, time, Qt::UTC};
343#else
344 return {date, time, QTimeZone(QTimeZone::UTC)};
345#endif
346}
347
351time_t dvbdate2unix(const unsigned char *buf)
352{
353 // Modified Julian date as number of days since 17th November 1858.
354 // The unix epoch, 1st Jan 1970, was day 40587.
355 uint mjd = (buf[0] << 8) | buf[1];
356 if (mjd < 40587)
357 return 0; // we don't handle pre-unix dates..
358
359 uint secsSince1970 = (mjd - 40587) * 86400;
360 secsSince1970 += byteBCD2int(buf[2]) * 3600;
361 secsSince1970 += byteBCD2int(buf[3]) * 60;
362 secsSince1970 += byteBCD2int(buf[4]);
363 return secsSince1970;
364}
365
369uint32_t dvbdate2key(const unsigned char *buf)
370{
371 uint dt = (((uint)buf[0]) << 24) | (((uint)buf[1]) << 16); // 16 bits
372 uint tm = ((byteBCD2int(buf[2]) * 3600) +
373 (byteBCD2int(buf[3]) * 60) +
374 (byteBCD2int(buf[4]))); // 17 bits
375 return (dt | (tm>>1)) ^ ((tm & 1)<<31);
376}
uint TSID(uint i) const
Definition: dvbtables.h:234
const unsigned char * BouquetDescriptors(void) const
Definition: dvbtables.h:222
uint TransportDescriptorsLength(uint i) const
Definition: dvbtables.h:240
const unsigned char * TransportDescriptors(uint i) const
for(j=0;j<N;j++) x 6.0+p { descriptor() }
Definition: dvbtables.h:244
void Parse(void) const
Definition: dvbtables.cpp:207
std::vector< const unsigned char * > m_ptrs
Definition: dvbtables.h:253
uint BouquetID() const
Definition: dvbtables.h:208
QString toString(void) const override
Definition: dvbtables.cpp:217
const unsigned char * m_tscPtr
Definition: dvbtables.h:252
uint BouquetDescriptorsLength(void) const
Definition: dvbtables.h:216
uint TransportStreamDataLength(void) const
Definition: dvbtables.h:227
uint OriginalNetworkID(uint i) const
Definition: dvbtables.h:236
uint TransportStreamCount(void) const
Definition: dvbtables.h:229
void Parse(void) const
Definition: dvbtables.cpp:270
std::vector< const unsigned char * > m_ptrs
Definition: dvbtables.h:380
uint DescriptorsLength(uint i) const
Definition: dvbtables.h:366
static bool IsEIT(uint table_id)
Definition: dvbtables.cpp:282
static const unsigned char * FindExtension(const desc_list_t &parsed, uint desc_tag)
static desc_list_t Parse(const unsigned char *data, uint len)
bool IsValid(void) const
static const unsigned char * Find(const desc_list_t &parsed, uint desc_tag)
uint OriginalNetworkID(uint i) const
original_network_id 16 2.0+p
Definition: dvbtables.h:84
QString toString(void) const override
Definition: dvbtables.cpp:32
uint TransportDescriptorsLength(uint i) const
trans_desc_length 12 4.4+p
Definition: dvbtables.h:88
uint NetworkID(void) const
network_id 16 3.0 0x0000
Definition: dvbtables.h:62
const unsigned char * TransportDescriptors(uint i) const
for(j=0;j<N;j++) x 6.0+p { descriptor() }
Definition: dvbtables.h:92
void Parse(void) const
Definition: dvbtables.cpp:22
uint TransportStreamDataLength(void) const
trans_stream_loop_len 12 0.4+ndl
Definition: dvbtables.h:76
QString NetworkName(void) const
Definition: dvbtables.cpp:82
uint TSID(uint i) const
transport_stream_id 16 0.0+p
Definition: dvbtables.h:82
const unsigned char * NetworkDescriptors(void) const
for(i=0; i<N; i++) x 10.0 { descriptor() }
Definition: dvbtables.h:71
std::vector< const unsigned char * > m_ptrs
Definition: dvbtables.h:106
const unsigned char * m_tscPtr
Definition: dvbtables.h:105
uint NetworkDescriptorsLength(void) const
network_desc_length 12 8.4 0
Definition: dvbtables.h:66
bool Mutate(void)
mutates a NITo into a NITa (vice versa) and recalculates the CRC
Definition: dvbtables.cpp:106
uint TransportStreamCount(void) const
Definition: dvbtables.h:78
bool VerifyCRC(void) const
Definition: pespacket.cpp:180
void SetCRC(uint crc)
Definition: pespacket.h:200
uint CalcCRC(void) const
Definition: pespacket.cpp:172
const unsigned char * pesdata() const
Definition: pespacket.h:164
uint Length() const
Definition: pespacket.h:99
uint LastSection(void) const
Definition: mpegtables.h:534
void SetTableID(uint id)
Definition: mpegtables.h:547
const unsigned char * psipdata(void) const
Definition: mpegtables.h:541
bool IsCurrent(void) const
Definition: mpegtables.h:528
uint TableID(void) const
Definition: mpegtables.h:496
uint Section(void) const
Definition: mpegtables.h:531
uint32_t PrivateDataSpecifier(void) const
uint TSID() const
transport_stream_id 16 3.0 0x0000
Definition: dvbtables.h:141
QString toString(void) const override
Definition: dvbtables.cpp:129
const unsigned char * ServiceDescriptors(uint i) const
for (j=0;j<N;j++) x 5.0+p { descriptor() }
Definition: dvbtables.h:169
bool HasEITPresentFollowing(uint i) const
Definition: dvbtables.h:158
std::vector< const unsigned char * > m_ptrs
Definition: dvbtables.h:182
bool HasEITSchedule(uint i) const
Definition: dvbtables.h:156
ServiceDescriptor * GetServiceDescriptor(uint i) const
Definition: dvbtables.cpp:166
bool Mutate(void)
mutates a SDTo into a SDTa (vice versa) and recalculates the CRC
Definition: dvbtables.cpp:196
uint ServiceID(uint i) const
service_id 16 0.0+p
Definition: dvbtables.h:153
uint ServiceCount() const
Number of services.
Definition: dvbtables.h:148
uint ServiceDescriptorsLength(uint i) const
desc_loop_length 12 3.4+p
Definition: dvbtables.h:165
uint OriginalNetworkID() const
original_network_id 16 8.0
Definition: dvbtables.h:144
bool IsEncrypted(uint i) const
free_CA_mode 1 3.3+p
Definition: dvbtables.h:163
void Parse(void) const
Definition: dvbtables.cpp:117
ServiceRelocatedDescriptor * GetServiceRelocatedDescriptor(uint i) const
Definition: dvbtables.cpp:181
@ DN_EITbego
Definition: mpegtables.h:314
@ SC_EITbeg
Definition: mpegtables.h:280
@ SC_EITend
Definition: mpegtables.h:281
@ DN_EITendo
Definition: mpegtables.h:315
@ SC_EITendo
Definition: mpegtables.h:283
@ SC_EITbego
Definition: mpegtables.h:282
static constexpr uint8_t byteBCD2int(uint8_t i)
uint32_t dvbdate2key(const unsigned char *buf)
Definition: dvbtables.cpp:369
QDateTime dvbdate2qt(const unsigned char *buf)
Definition: dvbtables.cpp:306
static uint GetPrivateDataSpecifier(const unsigned char *desc, uint priv_dsid)
Definition: dvbtables.cpp:11
time_t dvbdate2unix(const unsigned char *buf)
Definition: dvbtables.cpp:351
unsigned int uint
Definition: freesurround.h:24
std::vector< const unsigned char * > desc_list_t
MBASE_PUBLIC QDateTime fromSecsSinceEpoch(int64_t seconds)
This function takes the number of seconds since the start of the epoch and returns a QDateTime with t...
Definition: mythdate.cpp:81