vdr  2.2.0
nit.c
Go to the documentation of this file.
1 /*
2  * nit.c: NIT section filter
3  *
4  * See the main source file 'vdr.c' for copyright information and
5  * how to reach the author.
6  *
7  * $Id: nit.c 3.5 2015/02/04 09:13:54 kls Exp $
8  */
9 
10 #include "nit.h"
11 #include <linux/dvb/frontend.h>
12 #include "channels.h"
13 #include "dvbdevice.h"
14 #include "eitscan.h"
15 #include "libsi/section.h"
16 #include "libsi/descriptor.h"
17 #include "tools.h"
18 
19 #define DVB_SYSTEM_1 0 // see also dvbdevice.c
20 #define DVB_SYSTEM_2 1
21 
23 {
24  sdtFilter = SdtFilter;
25  numNits = 0;
26  networkId = 0;
27  Set(0x10, 0x40); // NIT
28 }
29 
30 void cNitFilter::SetStatus(bool On)
31 {
33  numNits = 0;
34  networkId = 0;
36 }
37 
38 void cNitFilter::Process(u_short Pid, u_char Tid, const u_char *Data, int Length)
39 {
40  SI::NIT nit(Data, false);
41  if (!nit.CheckCRCAndParse())
42  return;
43  // Some broadcasters send more than one NIT, with no apparent way of telling which
44  // one is the right one to use. This is an attempt to find the NIT that contains
45  // the transponder it was transmitted on and use only that one:
46  int ThisNIT = -1;
47  if (!networkId) {
48  for (int i = 0; i < numNits; i++) {
49  if (nits[i].networkId == nit.getNetworkId()) {
50  if (nit.getSectionNumber() == 0) {
51  // all NITs have passed by
52  for (int j = 0; j < numNits; j++) {
53  if (nits[j].hasTransponder) {
55  //printf("taking NIT with network ID %d\n", networkId);
56  //XXX what if more than one NIT contains this transponder???
57  break;
58  }
59  }
60  if (!networkId) {
61  //printf("none of the NITs contains transponder %d\n", Transponder());
62  return;
63  }
64  }
65  else {
66  ThisNIT = i;
67  break;
68  }
69  }
70  }
71  if (!networkId && ThisNIT < 0 && numNits < MAXNITS) {
72  if (nit.getSectionNumber() == 0) {
73  *nits[numNits].name = 0;
74  SI::Descriptor *d;
75  for (SI::Loop::Iterator it; (d = nit.commonDescriptors.getNext(it)); ) {
76  switch (d->getDescriptorTag()) {
79  nnd->name.getText(nits[numNits].name, MAXNETWORKNAME);
80  }
81  break;
82  default: ;
83  }
84  delete d;
85  }
87  nits[numNits].hasTransponder = false;
88  //printf("NIT[%d] %5d '%s'\n", numNits, nits[numNits].networkId, nits[numNits].name);
89  ThisNIT = numNits;
90  numNits++;
91  }
92  }
93  }
94  else if (networkId != nit.getNetworkId())
95  return; // ignore all other NITs
97  return;
98  if (!Channels.Lock(true, 10))
99  return;
101  for (SI::Loop::Iterator it; nit.transportStreamLoop.getNext(ts, it); ) {
102  SI::Descriptor *d;
103 
104  SI::Loop::Iterator it2;
106  int NumFrequencies = fld ? fld->frequencies.getCount() + 1 : 1;
107  int Frequencies[NumFrequencies];
108  if (fld) {
109  int ct = fld->getCodingType();
110  if (ct > 0) {
111  int n = 1;
112  for (SI::Loop::Iterator it3; fld->frequencies.hasNext(it3); ) {
113  int f = fld->frequencies.getNext(it3);
114  switch (ct) {
115  case 1: f = BCD2INT(f) / 100; break;
116  case 2: f = BCD2INT(f) / 10; break;
117  case 3: f = f * 10; break;
118  default: ;
119  }
120  Frequencies[n++] = f;
121  }
122  }
123  else
124  NumFrequencies = 1;
125  }
126  delete fld;
127 
128  for (SI::Loop::Iterator it2; (d = ts.transportStreamDescriptors.getNext(it2)); ) {
129  switch (d->getDescriptorTag()) {
134  int Frequency = Frequencies[0] = BCD2INT(sd->getFrequency()) / 100;
135  static char Polarizations[] = { 'H', 'V', 'L', 'R' };
136  dtp.SetPolarization(Polarizations[sd->getPolarization()]);
137  static int CodeRates[] = { FEC_NONE, FEC_1_2, FEC_2_3, FEC_3_4, FEC_5_6, FEC_7_8, FEC_8_9, FEC_3_5, FEC_4_5, FEC_9_10, FEC_AUTO, FEC_AUTO, FEC_AUTO, FEC_AUTO, FEC_AUTO, FEC_NONE };
138  dtp.SetCoderateH(CodeRates[sd->getFecInner()]);
139  static int Modulations[] = { QAM_AUTO, QPSK, PSK_8, QAM_16 };
140  dtp.SetModulation(Modulations[sd->getModulationType()]);
142  static int RollOffs[] = { ROLLOFF_35, ROLLOFF_25, ROLLOFF_20, ROLLOFF_AUTO };
143  dtp.SetRollOff(sd->getModulationSystem() ? RollOffs[sd->getRollOff()] : ROLLOFF_AUTO);
144  int SymbolRate = BCD2INT(sd->getSymbolRate()) / 10;
145  if (ThisNIT >= 0) {
146  for (int n = 0; n < NumFrequencies; n++) {
147  if (ISTRANSPONDER(cChannel::Transponder(Frequencies[n], dtp.Polarization()), Transponder())) {
148  nits[ThisNIT].hasTransponder = true;
149  //printf("has transponder %d\n", Transponder());
150  break;
151  }
152  }
153  break;
154  }
155  if (Setup.UpdateChannels >= 5) {
156  bool found = false;
157  bool forceTransponderUpdate = false;
159  if (!Channel->GroupSep() && Channel->Source() == Source && Channel->Nid() == ts.getOriginalNetworkId() && Channel->Tid() == ts.getTransportStreamId()) {
160  int transponder = Channel->Transponder();
161  found = true;
162  dtp.SetLcn(Channel->Lcn()); // lcn is set on another descriptor
163  if (!ISTRANSPONDER(cChannel::Transponder(Frequency, dtp.Polarization()), transponder)) {
164  for (int n = 0; n < NumFrequencies; n++) {
165  if (ISTRANSPONDER(cChannel::Transponder(Frequencies[n], dtp.Polarization()), transponder)) {
166  Frequency = Frequencies[n];
167  break;
168  }
169  }
170  }
171  if (ISTRANSPONDER(cChannel::Transponder(Frequency, dtp.Polarization()), Transponder())) // only modify channels if we're actually receiving this transponder
172  Channel->SetTransponderData(Source, Frequency, SymbolRate, dtp.ToString('S'));
173  else if (Channel->Srate() != SymbolRate || strcmp(Channel->Parameters(), dtp.ToString('S')))
174  forceTransponderUpdate = true; // get us receiving this transponder
175  }
176  }
177  if (!found || forceTransponderUpdate) {
178  for (int n = 0; n < NumFrequencies; n++) {
179  cChannel *Channel = new cChannel;
180  Channel->SetId(ts.getOriginalNetworkId(), ts.getTransportStreamId(), 0, 0);
181  if (Channel->SetTransponderData(Source, Frequencies[n], SymbolRate, dtp.ToString('S')))
182  EITScanner.AddTransponder(Channel);
183  else
184  delete Channel;
185  }
186  }
187  }
188  sdtFilter->Trigger(Source);
189  }
190  break;
192  if (Setup.UpdateChannels >= 5) {
197  dtp.SetSystem(DVB_SYSTEM_2);
198  dtp.SetStreamId(sd->getInputStreamIdentifier());
199  Channel->SetTransponderData(Channel->Source(), Channel->Frequency(), Channel->Srate(), dtp.ToString('S'));
200  break;
201  }
202  }
203  }
204  }
205  break;
210  int Frequency = Frequencies[0] = BCD2INT(sd->getFrequency()) / 10;
211  //XXX FEC_outer???
212  static int CodeRates[] = { FEC_NONE, FEC_1_2, FEC_2_3, FEC_3_4, FEC_5_6, FEC_7_8, FEC_8_9, FEC_3_5, FEC_4_5, FEC_9_10, FEC_AUTO, FEC_AUTO, FEC_AUTO, FEC_AUTO, FEC_AUTO, FEC_NONE };
213  dtp.SetCoderateH(CodeRates[sd->getFecInner()]);
214  static int Modulations[] = { QPSK, QAM_16, QAM_32, QAM_64, QAM_128, QAM_256, QAM_AUTO };
215  dtp.SetModulation(Modulations[min(sd->getModulation(), 6)]);
216  int SymbolRate = BCD2INT(sd->getSymbolRate()) / 10;
217  if (ThisNIT >= 0) {
218  for (int n = 0; n < NumFrequencies; n++) {
219  if (ISTRANSPONDER(Frequencies[n] / 1000, Transponder())) {
220  nits[ThisNIT].hasTransponder = true;
221  //printf("has transponder %d\n", Transponder());
222  break;
223  }
224  }
225  break;
226  }
227  if (Setup.UpdateChannels >= 5) {
228  bool found = false;
229  bool forceTransponderUpdate = false;
231  if (!Channel->GroupSep() && Channel->Source() == Source && Channel->Nid() == ts.getOriginalNetworkId() && Channel->Tid() == ts.getTransportStreamId()) {
232  int transponder = Channel->Transponder();
233  found = true;
234  dtp.SetLcn(Channel->Lcn()); // lcn is set on another descriptor
235  if (!ISTRANSPONDER(Frequency / 1000, transponder)) {
236  for (int n = 0; n < NumFrequencies; n++) {
237  if (ISTRANSPONDER(Frequencies[n] / 1000, transponder)) {
238  Frequency = Frequencies[n];
239  break;
240  }
241  }
242  }
243  if (ISTRANSPONDER(Frequency / 1000, Transponder())) // only modify channels if we're actually receiving this transponder
244  Channel->SetTransponderData(Source, Frequency, SymbolRate, dtp.ToString('C'));
245  else if (Channel->Srate() != SymbolRate || strcmp(Channel->Parameters(), dtp.ToString('C')))
246  forceTransponderUpdate = true; // get us receiving this transponder
247  }
248  }
249  if (!found || forceTransponderUpdate) {
250  for (int n = 0; n < NumFrequencies; n++) {
251  cChannel *Channel = new cChannel;
252  Channel->SetId(ts.getOriginalNetworkId(), ts.getTransportStreamId(), 0, 0);
253  if (Channel->SetTransponderData(Source, Frequencies[n], SymbolRate, dtp.ToString('C')))
254  EITScanner.AddTransponder(Channel);
255  else
256  delete Channel;
257  }
258  }
259  }
260  sdtFilter->Trigger(Source);
261  }
262  break;
267  int Frequency = Frequencies[0] = sd->getFrequency() * 10;
268  static int Bandwidths[] = { 8000000, 7000000, 6000000, 5000000, 0, 0, 0, 0 };
269  dtp.SetBandwidth(Bandwidths[sd->getBandwidth()]);
270  static int Constellations[] = { QPSK, QAM_16, QAM_64, QAM_AUTO };
271  dtp.SetModulation(Constellations[sd->getConstellation()]);
272  dtp.SetSystem(DVB_SYSTEM_1);
273  static int Hierarchies[] = { HIERARCHY_NONE, HIERARCHY_1, HIERARCHY_2, HIERARCHY_4, HIERARCHY_AUTO, HIERARCHY_AUTO, HIERARCHY_AUTO, HIERARCHY_AUTO };
274  dtp.SetHierarchy(Hierarchies[sd->getHierarchy()]);
275  static int CodeRates[] = { FEC_1_2, FEC_2_3, FEC_3_4, FEC_5_6, FEC_7_8, FEC_AUTO, FEC_AUTO, FEC_AUTO };
276  dtp.SetCoderateH(CodeRates[sd->getCodeRateHP()]);
277  dtp.SetCoderateL(CodeRates[sd->getCodeRateLP()]);
278  static int GuardIntervals[] = { GUARD_INTERVAL_1_32, GUARD_INTERVAL_1_16, GUARD_INTERVAL_1_8, GUARD_INTERVAL_1_4 };
279  dtp.SetGuard(GuardIntervals[sd->getGuardInterval()]);
280  static int TransmissionModes[] = { TRANSMISSION_MODE_2K, TRANSMISSION_MODE_8K, TRANSMISSION_MODE_4K, TRANSMISSION_MODE_AUTO };
281  dtp.SetTransmission(TransmissionModes[sd->getTransmissionMode()]);
282  if (ThisNIT >= 0) {
283  for (int n = 0; n < NumFrequencies; n++) {
284  if (ISTRANSPONDER(Frequencies[n] / 1000000, Transponder())) {
285  nits[ThisNIT].hasTransponder = true;
286  //printf("has transponder %d\n", Transponder());
287  break;
288  }
289  }
290  break;
291  }
292  if (Setup.UpdateChannels >= 5) {
293  bool found = false;
294  bool forceTransponderUpdate = false;
296  if (!Channel->GroupSep() && Channel->Source() == Source && Channel->Nid() == ts.getOriginalNetworkId() && Channel->Tid() == ts.getTransportStreamId()) {
297  int transponder = Channel->Transponder();
298  found = true;
299  dtp.SetLcn(Channel->Lcn()); // lcn is set on another descriptor
300  if (!ISTRANSPONDER(Frequency / 1000000, transponder)) {
301  for (int n = 0; n < NumFrequencies; n++) {
302  if (ISTRANSPONDER(Frequencies[n] / 1000000, transponder)) {
303  Frequency = Frequencies[n];
304  break;
305  }
306  }
307  }
308  if (ISTRANSPONDER(Frequency / 1000000, Transponder())) // only modify channels if we're actually receiving this transponder
309  Channel->SetTransponderData(Source, Frequency, 0, dtp.ToString('T'));
310  else if (strcmp(Channel->Parameters(), dtp.ToString('T')))
311  forceTransponderUpdate = true; // get us receiving this transponder
312  }
313  }
314  if (!found || forceTransponderUpdate) {
315  for (int n = 0; n < NumFrequencies; n++) {
316  cChannel *Channel = new cChannel;
317  Channel->SetId(ts.getOriginalNetworkId(), ts.getTransportStreamId(), 0, 0);
318  if (Channel->SetTransponderData(Source, Frequencies[n], 0, dtp.ToString('T')))
319  EITScanner.AddTransponder(Channel);
320  else
321  delete Channel;
322  }
323  }
324  }
325  sdtFilter->Trigger(Source);
326  }
327  break;
330  switch (sd->getExtensionDescriptorTag()) {
332  if (Setup.UpdateChannels >= 5) {
335  if (!Channel->GroupSep() && Channel->Source() == Source && Channel->Nid() == ts.getOriginalNetworkId() && Channel->Tid() == ts.getTransportStreamId()) {
337  int Frequency = Channel->Frequency();
338  int SymbolRate = Channel->Srate();
340  dtp.SetSystem(DVB_SYSTEM_2);
341  dtp.SetStreamId(td->getPlpId());
342  dtp.SetT2SystemId(td->getT2SystemId());
343  if (td->getExtendedDataFlag()) {
344  dtp.SetSisoMiso(td->getSisoMiso());
345  static int T2Bandwidths[] = { 8000000, 7000000, 6000000, 5000000, 10000000, 1712000, 0, 0 };
346  dtp.SetBandwidth(T2Bandwidths[td->getBandwidth()]);
347  static int T2GuardIntervals[] = { GUARD_INTERVAL_1_32, GUARD_INTERVAL_1_16, GUARD_INTERVAL_1_8, GUARD_INTERVAL_1_4, GUARD_INTERVAL_1_128, GUARD_INTERVAL_19_128, GUARD_INTERVAL_19_256, 0 };
348  dtp.SetGuard(T2GuardIntervals[td->getGuardInterval()]);
349  static int T2TransmissionModes[] = { TRANSMISSION_MODE_2K, TRANSMISSION_MODE_8K, TRANSMISSION_MODE_4K, TRANSMISSION_MODE_1K, TRANSMISSION_MODE_16K, TRANSMISSION_MODE_32K, TRANSMISSION_MODE_AUTO, TRANSMISSION_MODE_AUTO };
350  dtp.SetTransmission(T2TransmissionModes[td->getTransmissionMode()]);
351  //TODO add parsing of frequencies
352  }
353  Channel->SetTransponderData(Source, Frequency, SymbolRate, dtp.ToString('T'));
354  }
355  }
356  }
357  }
358  break;
359  default: ;
360  }
361  }
362  break;
367  for (SI::Loop::Iterator it4; lcd->logicalChannelLoop.getNext(LogicalChannel, it4); ) {
368  int lcn = LogicalChannel.getLogicalChannelNumber();
369  int sid = LogicalChannel.getServiceId();
370  if (LogicalChannel.getVisibleServiceFlag()) {
372  if (!Channel->GroupSep() && Channel->Sid() == sid && Channel->Nid() == ts.getOriginalNetworkId() && Channel->Tid() == ts.getTransportStreamId()) {
374  dtp.SetLcn(lcn); // for storing lcn into channels.conf
376  Channel->SetLcn(lcn);
377  break;
378  }
379  }
380  }
381  }
382  }
383  break;
388  for (SI::Loop::Iterator it4; lcd->hdSimulcastLogicalChannelLoop.getNext(HdSimulcastLogicalChannel, it4); ) {
389  int lcn = HdSimulcastLogicalChannel.getLogicalChannelNumber();
390  int sid = HdSimulcastLogicalChannel.getServiceId();
391  if (HdSimulcastLogicalChannel.getVisibleServiceFlag()) {
393  if (!Channel->GroupSep() && Channel->Sid() == sid && Channel->Nid() == ts.getOriginalNetworkId() && Channel->Tid() == ts.getTransportStreamId()) {
395  dtp.SetLcn(lcn); // for storing lcn into channels.conf
397  Channel->SetLcn(lcn);
398  break;
399  }
400  }
401  }
402  }
403  }
404  break;
405  default: ;
406  }
407  delete d;
408  }
409  }
410  Channels.Unlock();
411 }
int Tid(void) const
Definition: channels.h:193
void SetId(int Nid, int Tid, int Sid, int Rid=0)
Definition: channels.c:233
void SetTransmission(int Transmission)
Definition: dvbdevice.h:153
cSdtFilter * sdtFilter
Definition: nit.h:30
cChannels Channels
Definition: channels.c:864
static char ToChar(int Code)
Definition: sources.h:51
void SetPolarization(char Polarization)
Definition: dvbdevice.h:146
int StandardCompliance
Definition: config.h:284
char * getText()
Definition: si.c:222
int Nid(void) const
Definition: channels.h:192
StructureLoop< LogicalChannel > logicalChannelLoop
Definition: descriptor.h:571
int getTransportStreamId() const
Definition: section.c:102
cEITScanner EITScanner
Definition: eitscan.c:90
u_short networkId
Definition: nit.h:24
u_short networkId
Definition: nit.h:32
Definition: sdt.h:16
int numNits
Definition: nit.h:33
#define MAXNITS
Definition: nit.h:16
int Srate(void) const
Definition: channels.h:169
const cChannel * Channel(void)
Returns the channel of the data delivered to this filter.
Definition: filter.c:99
int BCD2INT(int x)
Definition: tools.c:45
bool GroupSep(void) const
Definition: channels.h:199
DescriptorTag getDescriptorTag() const
Definition: si.c:100
int getExtensionDescriptorTag() const
Definition: descriptor.c:875
cSectionSyncer sectionSyncer
Definition: nit.h:29
T min(T a, T b)
Definition: tools.h:54
int Transponder(void) const
Returns the transponder frequency in MHz, plus the polarization in case of sat.
Definition: channels.c:158
cString ToString(char Type) const
Definition: dvbdevice.c:228
StructureLoop< HdSimulcastLogicalChannel > hdSimulcastLogicalChannelLoop
Definition: descriptor.h:589
void SetCoderateH(int CoderateH)
Definition: dvbdevice.h:149
const char * Parameters(void) const
Definition: channels.h:200
void SetRollOff(int RollOff)
Definition: dvbdevice.h:156
DescriptorLoop transportStreamDescriptors
Definition: section.h:100
bool SetTransponderData(int Source, int Frequency, int Srate, const char *Parameters, bool Quiet=false)
Definition: channels.c:197
#define DVB_SYSTEM_2
Definition: nit.c:20
void Unlock(void)
Definition: thread.c:170
DescriptorLoop commonDescriptors
Definition: section.h:106
bool hasTransponder
Definition: nit.h:26
int getSectionNumber() const
Definition: si.c:88
#define MAXNETWORKNAME
Definition: nit.h:17
bool Sync(uchar Version, int Number, int LastNumber)
Definition: filter.c:26
void Trigger(int Source)
Definition: sdt.c:34
char Polarization(void) const
Definition: dvbdevice.h:130
T * Next(const T *object) const
Definition: tools.h:495
virtual void Process(u_short Pid, u_char Tid, const u_char *Data, int Length)
Processes the data delivered to this filter.
Definition: nit.c:38
int Source(void) const
Definition: channels.h:168
#define ISTRANSPONDER(f1, f2)
Definition: channels.h:18
#define STANDARD_NORDIG
Definition: config.h:72
void SetLcn(int Lcn)
Definition: dvbdevice.h:161
void SetSystem(int System)
Definition: dvbdevice.h:152
int Source(void)
Returns the source of the data delivered to this filter.
Definition: filter.c:89
cNit nits[MAXNITS]
Definition: nit.h:31
int getOriginalNetworkId() const
Definition: section.c:106
StructureLoop< TransportStream > transportStreamLoop
Definition: section.h:107
static bool IsSat(int Code)
Definition: sources.h:57
cSetup Setup
Definition: config.c:373
bool Lock(bool Write, int TimeoutMs=0)
Definition: thread.c:155
virtual void SetStatus(bool On)
Turns this filter on or off, depending on the value of On.
Definition: nit.c:30
void SetLcn(int Lcn)
Definition: channels.c:252
int Frequency(void) const
Returns the actual frequency, as given in &#39;channels.conf&#39;.
Definition: channels.h:165
bool CheckCRCAndParse()
Definition: si.c:65
bool hasNext(Iterator &it)
Definition: si.h:459
T getNext(Iterator &it) const
Definition: si.h:453
virtual void SetStatus(bool On)
Turns this filter on or off, depending on the value of On.
Definition: filter.c:104
T * First(void) const
Definition: tools.h:492
int getVersionNumber() const
Definition: si.c:84
unsigned char u_char
Definition: headers.h:24
int getLastSectionNumber() const
Definition: si.c:92
int UpdateChannels
Definition: config.h:314
char name[MAXNETWORKNAME]
Definition: nit.h:25
void SetHierarchy(int Hierarchy)
Definition: dvbdevice.h:155
void SetGuard(int Guard)
Definition: dvbdevice.h:154
int Transponder(void)
Returns the transponder of the data delivered to this filter.
Definition: filter.c:94
void Set(u_short Pid, u_char Tid, u_char Mask=0xFF)
Sets the given filter data by calling Add() with Sticky = true.
Definition: filter.c:137
void SetCoderateL(int CoderateL)
Definition: dvbdevice.h:150
int getNetworkId() const
Definition: section.c:89
void AddTransponder(cChannel *Channel)
Definition: eitscan.c:106
int Lcn(void) const
Definition: channels.h:196
cNitFilter(cSdtFilter *SdtFilter)
Definition: nit.c:22
#define DVB_SYSTEM_1
Definition: nit.c:19
static int FromData(eSourceType SourceType, int Position=0, bool East=false)
Definition: sources.c:104
void Reset(void)
Definition: filter.c:20
int Sid(void) const
Definition: channels.h:194
int getCount()
Definition: si.h:436
TypeLoop< ThirtyTwoBit > frequencies
Definition: descriptor.h:350
Descriptor * getNext(Iterator &it)
Definition: si.c:112
void SetBandwidth(int Bandwidth)
Definition: dvbdevice.h:148
void SetModulation(int Modulation)
Definition: dvbdevice.h:151