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  m_ptrs.clear();
25  m_ptrs.push_back(m_tscPtr + 2);
26  for (uint i=0; m_ptrs[i] + 6 <= m_ptrs[0] + TransportStreamDataLength(); i++)
27  m_ptrs.push_back(m_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(static_cast<int>(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 (auto & i : desc)
46  {
47  priv_dsid = GetPrivateDataSpecifier(i, priv_dsid);
48  str.append(QString(" %1\n")
49  .arg(MPEGDescriptor(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 (auto & j : desc)
70  {
71  priv_dsid = GetPrivateDataSpecifier(j, priv_dsid);
72  str.append(QString(" %1\n")
73  .arg(MPEGDescriptor(j).toStringPD(priv_dsid)));
74  }
75  }
76  }
77  return str;
78 }
79 
81 {
82  if (m_cachedNetworkName.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  m_cachedNetworkName = nndesc.Name();
96  }
97  if (m_cachedNetworkName.isEmpty())
98  m_cachedNetworkName = QString("Net ID 0x%1")
99  .arg(NetworkID(), 0, 16);
100  }
101  return m_cachedNetworkName;
102 }
103 
105 {
106  if (VerifyCRC())
107  {
109  SetCRC(CalcCRC());
110  return true;
111  }
112  return false;
113 }
114 
116 {
117  m_ptrs.clear();
118  m_ptrs.push_back(pesdata() + 11);
119  uint i = 0;
120  while ((m_ptrs[i] + 5) < (pesdata() + Length()))
121  {
122  m_ptrs.push_back(m_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(static_cast<int>(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 (auto & j : desc)
154  {
155  priv_dsid = GetPrivateDataSpecifier(j, priv_dsid);
156  str.append(QString(" %1\n")
157  .arg(MPEGDescriptor(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  desc_list_t parsed =
184 
185  const unsigned char *desc =
187 
188  if (desc)
189  return new ServiceRelocatedDescriptor(desc);
190 
191  return nullptr;
192 }
193 
195 {
196  if (VerifyCRC())
197  {
199  SetCRC(CalcCRC());
200  return true;
201  }
202  return false;
203 }
204 
206 {
208 
209  m_ptrs.clear();
210  m_ptrs.push_back(m_tscPtr + 2);
211  for (uint i=0; m_ptrs[i] + 6 <= m_ptrs[0] + TransportStreamDataLength(); i++)
212  m_ptrs.push_back(m_ptrs[i] + 6 + TransportDescriptorsLength(i));
213 }
214 
216 {
217  QString str =
218  QString("BAT: BouquetID(0x%1) transports(%2)\n")
219  .arg(BouquetID(), 0, 16).arg(TransportStreamCount());
220 
221  str.append(QString("Section (%1) Last Section (%2) IsCurrent (%3)\n")
222  .arg(Section()).arg(LastSection()).arg(static_cast<int>(IsCurrent())));
223 
224  if (0 != BouquetDescriptorsLength())
225  {
226  str.append(QString("Bouquet descriptors length: %1\n")
227  .arg(BouquetDescriptorsLength()));
228  vector<const unsigned char*> desc =
231  uint priv_dsid = 0;
232  for (auto & i : desc)
233  {
234  priv_dsid = GetPrivateDataSpecifier(i, priv_dsid);
235  str.append(QString(" %1\n")
236  .arg(MPEGDescriptor(i).toStringPD(priv_dsid)));
237  }
238  }
239 
240  for (uint i = 0; i < TransportStreamCount(); i++)
241  {
242  str.append(QString(" Transport #%1 TSID(0x%2) ")
243  .arg(i, 2, 10).arg(TSID(i), 0, 16));
244  str.append(QString("original_network_id(0x%2) desc_len(%3)\n")
245  .arg(OriginalNetworkID(i), 0, 16)
246  .arg(TransportDescriptorsLength(i)));
247 
248  if (0 != TransportDescriptorsLength(i))
249  {
250  str.append(QString(" Transport descriptors length: %1\n")
251  .arg(TransportDescriptorsLength(i)));
252  vector<const unsigned char*> desc =
255  uint priv_dsid = 0;
256  for (auto & j : desc)
257  {
258  priv_dsid = GetPrivateDataSpecifier(j, priv_dsid);
259  str.append(QString(" %1\n")
260  .arg(MPEGDescriptor(j).toStringPD(priv_dsid)));
261  }
262  }
263  }
264  return str;
265 }
266 
267 
269 {
270  m_ptrs.clear();
271  m_ptrs.push_back(psipdata() + 6);
272  uint i = 0;
273  while ((m_ptrs[i] + 12) < (pesdata() + Length()))
274  {
275  m_ptrs.push_back(m_ptrs[i] + 12 + DescriptorsLength(i));
276  i++;
277  }
278 }
279 
281 {
282  bool is_eit = false;
283 
284  // Standard Now/Next Event Information Tables for this transport
285  is_eit |= TableID::PF_EIT == table_id;
286  // Standard Now/Next Event Information Tables for other transport
287  is_eit |= TableID::PF_EITo == table_id;
288  // Standard Future Event Information Tables for this transport
289  is_eit |= (TableID::SC_EITbeg <= table_id &&
290  TableID::SC_EITend >= table_id);
291  // Standard Future Event Information Tables for other transports
292  is_eit |= (TableID::SC_EITbego <= table_id &&
293  TableID::SC_EITendo >= table_id);
294  // Dish Network Long Term Future Event Information for all transports
295  is_eit |= (TableID::DN_EITbego <= table_id &&
296  TableID::DN_EITendo >= table_id);
297 
298  return is_eit;
299 }
300 
304 QDateTime dvbdate2qt(const unsigned char *buf)
305 {
306  /* FIXME what's wrong with QDate::fromJulianDay? */
307  uint mjd = (buf[0] << 8) | buf[1];
308  if (mjd >= 40587)
309  {
310  // Modified Julian date as number of days since 17th November 1858.
311  // 1st Jan 1970 was date 40587.
312  uint secsSince1970 = (mjd - 40587) * 86400;
313  secsSince1970 += byteBCD2int(buf[2]) * 3600;
314  secsSince1970 += byteBCD2int(buf[3]) * 60;
315  secsSince1970 += byteBCD2int(buf[4]);
316 #if QT_VERSION < QT_VERSION_CHECK(5,8,0)
317  return MythDate::fromTime_t(secsSince1970);
318 #else
319  return MythDate::fromSecsSinceEpoch(secsSince1970);
320 #endif
321  }
322 
323  // Original function taken from dvbdate.c in linuxtv-apps code
324  // Use the routine specified in ETSI EN 300 468 V1.4.1,
325  // "Specification for Service Information in Digital Video Broadcasting"
326  // to convert from Modified Julian Date to Year, Month, Day.
327 
328  const auto tmpA = (float)(1.0 / 365.25);
329  const auto tmpB = (float)(1.0 / 30.6001);
330 
331  float mjdf = mjd;
332  int year = (int) truncf((mjdf - 15078.2F) * tmpA);
333  int month = (int) truncf(
334  (mjdf - 14956.1F - truncf(year * 365.25F)) * tmpB);
335  int day = (int) truncf(
336  (mjdf - 14956.0F - truncf(year * 365.25F) - truncf(month * 30.6001F)));
337  int i = (month == 14 || month == 15) ? 1 : 0;
338 
339  QDate date(1900 + year + i, month - 1 - i * 12, day);
340  QTime time(byteBCD2int(buf[2]), byteBCD2int(buf[3]),
341  byteBCD2int(buf[4]));
342 
343  return QDateTime(date, time, Qt::UTC);
344 }
345 
349 time_t dvbdate2unix(const unsigned char *buf)
350 {
351  // Modified Julian date as number of days since 17th November 1858.
352  // The unix epoch, 1st Jan 1970, was day 40587.
353  uint mjd = (buf[0] << 8) | buf[1];
354  if (mjd < 40587)
355  return 0; // we don't handle pre-unix dates..
356 
357  uint secsSince1970 = (mjd - 40587) * 86400;
358  secsSince1970 += byteBCD2int(buf[2]) * 3600;
359  secsSince1970 += byteBCD2int(buf[3]) * 60;
360  secsSince1970 += byteBCD2int(buf[4]);
361  return secsSince1970;
362 }
363 
367 uint32_t dvbdate2key(const unsigned char *buf)
368 {
369  uint dt = (((uint)buf[0]) << 24) | (((uint)buf[1]) << 16); // 16 bits
370  uint tm = ((byteBCD2int(buf[2]) * 3600) +
371  (byteBCD2int(buf[3]) * 60) +
372  (byteBCD2int(buf[4]))); // 17 bits
373  return (dt | (tm>>1)) ^ ((tm & 1)<<31);
374 }
uint BouquetID() const
Definition: dvbtables.h:196
const unsigned char * pesdata() const
Definition: pespacket.h:157
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:532
const unsigned char * TransportDescriptors(uint i) const
for(j=0;j<N;j++) x 6.0+p { descriptor() }
Definition: dvbtables.h:232
bool Mutate(void)
mutates a SDTo into a SDTa (vice versa) and recalculates the CRC
Definition: dvbtables.cpp:194
QString toString(void) const override
Definition: dvbtables.cpp:127
uint Length() const
Definition: pespacket.h:92
void Parse(void) const
Definition: dvbtables.cpp:268
void Parse(void) const
Definition: dvbtables.cpp:115
uint TransportDescriptorsLength(uint i) const
Definition: dvbtables.h:228
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:349
uint BouquetDescriptorsLength(void) const
Definition: dvbtables.h:204
void Parse(void) const
Definition: dvbtables.cpp:205
uint ServiceID(uint i) const
service_id 16 0.0+p
Definition: dvbtables.h:141
uint LastSection(void) const
Definition: mpegtables.h:525
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:222
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
bool IsCurrent(void) const
Definition: mpegtables.h:519
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 * m_tscPtr
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:80
static uint GetPrivateDataSpecifier(const unsigned char *desc, uint priv_dsid)
Definition: dvbtables.cpp:9
uint Section(void) const
Definition: mpegtables.h:522
vector< const unsigned char * > desc_list_t
static bool IsEIT(uint table_id)
Definition: dvbtables.cpp:280
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 * > m_ptrs
Definition: dvbtables.h:170
const unsigned char * BouquetDescriptors(void) const
Definition: dvbtables.h:210
vector< const unsigned char * > m_ptrs
Definition: dvbtables.h:241
void Parse(void) const
Definition: dvbtables.cpp:20
uint DescriptorsLength(uint i) const
Definition: dvbtables.h:354
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
static const unsigned char * FindExtension(const desc_list_t &parsed, uint desc_tag)
uint TransportStreamDataLength(void) const
Definition: dvbtables.h:215
unsigned int uint
Definition: compat.h:140
uint OriginalNetworkID(uint i) const
Definition: dvbtables.h:224
bool HasEITSchedule(uint i) const
Definition: dvbtables.h:144
QString m_cachedNetworkName
Definition: dvbtables.h:92
vector< const unsigned char * > m_ptrs
Definition: dvbtables.h:368
static const unsigned char * Find(const desc_list_t &parsed, uint desc_tag)
vector< const unsigned char * > m_ptrs
Definition: dvbtables.h:94
uint TransportStreamCount(void) const
Definition: dvbtables.h:217
uint TableID(void) const
Definition: mpegtables.h:489
void SetCRC(uint crc)
Definition: pespacket.h:193
uint32_t PrivateDataSpecifier(void) const
ServiceRelocatedDescriptor * GetServiceRelocatedDescriptor(uint i) const
Definition: dvbtables.cpp:179
ServiceDescriptor * GetServiceDescriptor(uint i) const
Definition: dvbtables.cpp:164
uint32_t dvbdate2key(const unsigned char *buf)
Definition: dvbtables.cpp:367
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
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:215
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:304
const unsigned char * m_tscPtr
Definition: dvbtables.h:93
#define byteBCD2int(i)
void SetTableID(uint id)
Definition: mpegtables.h:538