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