vdr  1.7.31
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 2.9 2012/01/12 08:43:52 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  numNits = 0;
25  networkId = 0;
26  Set(0x10, 0x40); // NIT
27 }
28 
29 void cNitFilter::SetStatus(bool On)
30 {
32  numNits = 0;
33  networkId = 0;
35 }
36 
37 void cNitFilter::Process(u_short Pid, u_char Tid, const u_char *Data, int Length)
38 {
39  SI::NIT nit(Data, false);
40  if (!nit.CheckCRCAndParse())
41  return;
42  // Some broadcasters send more than one NIT, with no apparent way of telling which
43  // one is the right one to use. This is an attempt to find the NIT that contains
44  // the transponder it was transmitted on and use only that one:
45  int ThisNIT = -1;
46  if (!networkId) {
47  for (int i = 0; i < numNits; i++) {
48  if (nits[i].networkId == nit.getNetworkId()) {
49  if (nit.getSectionNumber() == 0) {
50  // all NITs have passed by
51  for (int j = 0; j < numNits; j++) {
52  if (nits[j].hasTransponder) {
54  //printf("taking NIT with network ID %d\n", networkId);
55  //XXX what if more than one NIT contains this transponder???
56  break;
57  }
58  }
59  if (!networkId) {
60  //printf("none of the NITs contains transponder %d\n", Transponder());
61  return;
62  }
63  }
64  else {
65  ThisNIT = i;
66  break;
67  }
68  }
69  }
70  if (!networkId && ThisNIT < 0 && numNits < MAXNITS) {
71  if (nit.getSectionNumber() == 0) {
72  *nits[numNits].name = 0;
73  SI::Descriptor *d;
74  for (SI::Loop::Iterator it; (d = nit.commonDescriptors.getNext(it)); ) {
75  switch (d->getDescriptorTag()) {
78  nnd->name.getText(nits[numNits].name, MAXNETWORKNAME);
79  }
80  break;
81  default: ;
82  }
83  delete d;
84  }
86  nits[numNits].hasTransponder = false;
87  //printf("NIT[%d] %5d '%s'\n", numNits, nits[numNits].networkId, nits[numNits].name);
88  ThisNIT = numNits;
89  numNits++;
90  }
91  }
92  }
93  else if (networkId != nit.getNetworkId())
94  return; // ignore all other NITs
96  return;
97  if (!Channels.Lock(true, 10))
98  return;
100  for (SI::Loop::Iterator it; nit.transportStreamLoop.getNext(ts, it); ) {
101  SI::Descriptor *d;
102 
103  SI::Loop::Iterator it2;
105  int NumFrequencies = fld ? fld->frequencies.getCount() + 1 : 1;
106  int Frequencies[NumFrequencies];
107  if (fld) {
108  int ct = fld->getCodingType();
109  if (ct > 0) {
110  int n = 1;
111  for (SI::Loop::Iterator it3; fld->frequencies.hasNext(it3); ) {
112  int f = fld->frequencies.getNext(it3);
113  switch (ct) {
114  case 1: f = BCD2INT(f) / 100; break;
115  case 2: f = BCD2INT(f) / 10; break;
116  case 3: f = f * 10; break;
117  default: ;
118  }
119  Frequencies[n++] = f;
120  }
121  }
122  else
123  NumFrequencies = 1;
124  }
125  delete fld;
126 
127  for (SI::Loop::Iterator it2; (d = ts.transportStreamDescriptors.getNext(it2)); ) {
128  switch (d->getDescriptorTag()) {
133  int Frequency = Frequencies[0] = BCD2INT(sd->getFrequency()) / 100;
134  static char Polarizations[] = { 'H', 'V', 'L', 'R' };
135  dtp.SetPolarization(Polarizations[sd->getPolarization()]);
136  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 };
137  dtp.SetCoderateH(CodeRates[sd->getFecInner()]);
138  static int Modulations[] = { QAM_AUTO, QPSK, PSK_8, QAM_16 };
139  dtp.SetModulation(Modulations[sd->getModulationType()]);
141  static int RollOffs[] = { ROLLOFF_35, ROLLOFF_25, ROLLOFF_20, ROLLOFF_AUTO };
142  dtp.SetRollOff(sd->getModulationSystem() ? RollOffs[sd->getRollOff()] : ROLLOFF_AUTO);
143  int SymbolRate = BCD2INT(sd->getSymbolRate()) / 10;
144  if (ThisNIT >= 0) {
145  for (int n = 0; n < NumFrequencies; n++) {
146  if (ISTRANSPONDER(cChannel::Transponder(Frequencies[n], dtp.Polarization()), Transponder())) {
147  nits[ThisNIT].hasTransponder = true;
148  //printf("has transponder %d\n", Transponder());
149  break;
150  }
151  }
152  break;
153  }
154  if (Setup.UpdateChannels >= 5) {
155  bool found = false;
156  bool forceTransponderUpdate = false;
158  if (!Channel->GroupSep() && Channel->Source() == Source && Channel->Nid() == ts.getOriginalNetworkId() && Channel->Tid() == ts.getTransportStreamId()) {
159  int transponder = Channel->Transponder();
160  found = true;
161  if (!ISTRANSPONDER(cChannel::Transponder(Frequency, dtp.Polarization()), transponder)) {
162  for (int n = 0; n < NumFrequencies; n++) {
163  if (ISTRANSPONDER(cChannel::Transponder(Frequencies[n], dtp.Polarization()), transponder)) {
164  Frequency = Frequencies[n];
165  break;
166  }
167  }
168  }
169  if (ISTRANSPONDER(cChannel::Transponder(Frequency, dtp.Polarization()), Transponder())) // only modify channels if we're actually receiving this transponder
170  Channel->SetTransponderData(Source, Frequency, SymbolRate, dtp.ToString('S'));
171  else if (Channel->Srate() != SymbolRate || strcmp(Channel->Parameters(), dtp.ToString('S')))
172  forceTransponderUpdate = true; // get us receiving this transponder
173  }
174  }
175  if (!found || forceTransponderUpdate) {
176  for (int n = 0; n < NumFrequencies; n++) {
177  cChannel *Channel = new cChannel;
178  Channel->SetId(ts.getOriginalNetworkId(), ts.getTransportStreamId(), 0, 0);
179  if (Channel->SetTransponderData(Source, Frequencies[n], SymbolRate, dtp.ToString('S')))
180  EITScanner.AddTransponder(Channel);
181  else
182  delete Channel;
183  }
184  }
185  }
186  }
187  break;
192  int Frequency = Frequencies[0] = BCD2INT(sd->getFrequency()) / 10;
193  //XXX FEC_outer???
194  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 };
195  dtp.SetCoderateH(CodeRates[sd->getFecInner()]);
196  static int Modulations[] = { QPSK, QAM_16, QAM_32, QAM_64, QAM_128, QAM_256, QAM_AUTO };
197  dtp.SetModulation(Modulations[min(sd->getModulation(), 6)]);
198  int SymbolRate = BCD2INT(sd->getSymbolRate()) / 10;
199  if (ThisNIT >= 0) {
200  for (int n = 0; n < NumFrequencies; n++) {
201  if (ISTRANSPONDER(Frequencies[n] / 1000, Transponder())) {
202  nits[ThisNIT].hasTransponder = true;
203  //printf("has transponder %d\n", Transponder());
204  break;
205  }
206  }
207  break;
208  }
209  if (Setup.UpdateChannels >= 5) {
210  bool found = false;
211  bool forceTransponderUpdate = false;
213  if (!Channel->GroupSep() && Channel->Source() == Source && Channel->Nid() == ts.getOriginalNetworkId() && Channel->Tid() == ts.getTransportStreamId()) {
214  int transponder = Channel->Transponder();
215  found = true;
216  if (!ISTRANSPONDER(Frequency / 1000, transponder)) {
217  for (int n = 0; n < NumFrequencies; n++) {
218  if (ISTRANSPONDER(Frequencies[n] / 1000, transponder)) {
219  Frequency = Frequencies[n];
220  break;
221  }
222  }
223  }
224  if (ISTRANSPONDER(Frequency / 1000, Transponder())) // only modify channels if we're actually receiving this transponder
225  Channel->SetTransponderData(Source, Frequency, SymbolRate, dtp.ToString('C'));
226  else if (Channel->Srate() != SymbolRate || strcmp(Channel->Parameters(), dtp.ToString('C')))
227  forceTransponderUpdate = true; // get us receiving this transponder
228  }
229  }
230  if (!found || forceTransponderUpdate) {
231  for (int n = 0; n < NumFrequencies; n++) {
232  cChannel *Channel = new cChannel;
233  Channel->SetId(ts.getOriginalNetworkId(), ts.getTransportStreamId(), 0, 0);
234  if (Channel->SetTransponderData(Source, Frequencies[n], SymbolRate, dtp.ToString('C')))
235  EITScanner.AddTransponder(Channel);
236  else
237  delete Channel;
238  }
239  }
240  }
241  }
242  break;
247  int Frequency = Frequencies[0] = sd->getFrequency() * 10;
248  static int Bandwidths[] = { 8000000, 7000000, 6000000, 5000000, 0, 0, 0, 0 };
249  dtp.SetBandwidth(Bandwidths[sd->getBandwidth()]);
250  static int Constellations[] = { QPSK, QAM_16, QAM_64, QAM_AUTO };
251  dtp.SetModulation(Constellations[sd->getConstellation()]);
252  dtp.SetSystem(DVB_SYSTEM_1);
253  static int Hierarchies[] = { HIERARCHY_NONE, HIERARCHY_1, HIERARCHY_2, HIERARCHY_4, HIERARCHY_AUTO, HIERARCHY_AUTO, HIERARCHY_AUTO, HIERARCHY_AUTO };
254  dtp.SetHierarchy(Hierarchies[sd->getHierarchy()]);
255  static int CodeRates[] = { FEC_1_2, FEC_2_3, FEC_3_4, FEC_5_6, FEC_7_8, FEC_AUTO, FEC_AUTO, FEC_AUTO };
256  dtp.SetCoderateH(CodeRates[sd->getCodeRateHP()]);
257  dtp.SetCoderateL(CodeRates[sd->getCodeRateLP()]);
258  static int GuardIntervals[] = { GUARD_INTERVAL_1_32, GUARD_INTERVAL_1_16, GUARD_INTERVAL_1_8, GUARD_INTERVAL_1_4 };
259  dtp.SetGuard(GuardIntervals[sd->getGuardInterval()]);
260  static int TransmissionModes[] = { TRANSMISSION_MODE_2K, TRANSMISSION_MODE_8K, TRANSMISSION_MODE_4K, TRANSMISSION_MODE_AUTO };
261  dtp.SetTransmission(TransmissionModes[sd->getTransmissionMode()]);
262  if (ThisNIT >= 0) {
263  for (int n = 0; n < NumFrequencies; n++) {
264  if (ISTRANSPONDER(Frequencies[n] / 1000000, Transponder())) {
265  nits[ThisNIT].hasTransponder = true;
266  //printf("has transponder %d\n", Transponder());
267  break;
268  }
269  }
270  break;
271  }
272  if (Setup.UpdateChannels >= 5) {
273  bool found = false;
274  bool forceTransponderUpdate = false;
276  if (!Channel->GroupSep() && Channel->Source() == Source && Channel->Nid() == ts.getOriginalNetworkId() && Channel->Tid() == ts.getTransportStreamId()) {
277  int transponder = Channel->Transponder();
278  found = true;
279  if (!ISTRANSPONDER(Frequency / 1000000, transponder)) {
280  for (int n = 0; n < NumFrequencies; n++) {
281  if (ISTRANSPONDER(Frequencies[n] / 1000000, transponder)) {
282  Frequency = Frequencies[n];
283  break;
284  }
285  }
286  }
287  if (ISTRANSPONDER(Frequency / 1000000, Transponder())) // only modify channels if we're actually receiving this transponder
288  Channel->SetTransponderData(Source, Frequency, 0, dtp.ToString('T'));
289  else if (strcmp(Channel->Parameters(), dtp.ToString('T')))
290  forceTransponderUpdate = true; // get us receiving this transponder
291  }
292  }
293  if (!found || forceTransponderUpdate) {
294  for (int n = 0; n < NumFrequencies; n++) {
295  cChannel *Channel = new cChannel;
296  Channel->SetId(ts.getOriginalNetworkId(), ts.getTransportStreamId(), 0, 0);
297  if (Channel->SetTransponderData(Source, Frequencies[n], 0, dtp.ToString('T')))
298  EITScanner.AddTransponder(Channel);
299  else
300  delete Channel;
301  }
302  }
303  }
304  }
305  break;
308  switch (sd->getExtensionDescriptorTag()) {
310  if (Setup.UpdateChannels >= 5) {
313  if (!Channel->GroupSep() && Channel->Source() == Source && Channel->Nid() == ts.getOriginalNetworkId() && Channel->Tid() == ts.getTransportStreamId()) {
315  int Frequency = Channel->Frequency();
316  int SymbolRate = Channel->Srate();
317  //int SystemId = td->getSystemId();
319  dtp.SetSystem(DVB_SYSTEM_2);
320  dtp.SetPlpId(td->getPlpId());
321  if (td->getExtendedDataFlag()) {
322  static int T2Bandwidths[] = { 8000000, 7000000, 6000000, 5000000, 10000000, 1712000, 0, 0 };
323  dtp.SetBandwidth(T2Bandwidths[td->getBandwidth()]);
324  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 };
325  dtp.SetGuard(T2GuardIntervals[td->getGuardInterval()]);
326  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 };
327  dtp.SetTransmission(T2TransmissionModes[td->getTransmissionMode()]);
328  //TODO add parsing of frequencies
329  }
330  Channel->SetTransponderData(Source, Frequency, SymbolRate, dtp.ToString('T'));
331  }
332  }
333  }
334  }
335  break;
336  default: ;
337  }
338  }
339  break;
340  default: ;
341  }
342  delete d;
343  }
344  }
345  Channels.Unlock();
346 }