vdr
1.7.27
|
00001 /* 00002 * nit.c: NIT section filter 00003 * 00004 * See the main source file 'vdr.c' for copyright information and 00005 * how to reach the author. 00006 * 00007 * $Id: nit.c 2.9 2012/01/12 08:43:52 kls Exp $ 00008 */ 00009 00010 #include "nit.h" 00011 #include <linux/dvb/frontend.h> 00012 #include "channels.h" 00013 #include "dvbdevice.h" 00014 #include "eitscan.h" 00015 #include "libsi/section.h" 00016 #include "libsi/descriptor.h" 00017 #include "tools.h" 00018 00019 #define DVB_SYSTEM_1 0 // see also dvbdevice.c 00020 #define DVB_SYSTEM_2 1 00021 00022 cNitFilter::cNitFilter(void) 00023 { 00024 numNits = 0; 00025 networkId = 0; 00026 Set(0x10, 0x40); // NIT 00027 } 00028 00029 void cNitFilter::SetStatus(bool On) 00030 { 00031 cFilter::SetStatus(On); 00032 numNits = 0; 00033 networkId = 0; 00034 sectionSyncer.Reset(); 00035 } 00036 00037 void cNitFilter::Process(u_short Pid, u_char Tid, const u_char *Data, int Length) 00038 { 00039 SI::NIT nit(Data, false); 00040 if (!nit.CheckCRCAndParse()) 00041 return; 00042 // Some broadcasters send more than one NIT, with no apparent way of telling which 00043 // one is the right one to use. This is an attempt to find the NIT that contains 00044 // the transponder it was transmitted on and use only that one: 00045 int ThisNIT = -1; 00046 if (!networkId) { 00047 for (int i = 0; i < numNits; i++) { 00048 if (nits[i].networkId == nit.getNetworkId()) { 00049 if (nit.getSectionNumber() == 0) { 00050 // all NITs have passed by 00051 for (int j = 0; j < numNits; j++) { 00052 if (nits[j].hasTransponder) { 00053 networkId = nits[j].networkId; 00054 //printf("taking NIT with network ID %d\n", networkId); 00055 //XXX what if more than one NIT contains this transponder??? 00056 break; 00057 } 00058 } 00059 if (!networkId) { 00060 //printf("none of the NITs contains transponder %d\n", Transponder()); 00061 return; 00062 } 00063 } 00064 else { 00065 ThisNIT = i; 00066 break; 00067 } 00068 } 00069 } 00070 if (!networkId && ThisNIT < 0 && numNits < MAXNITS) { 00071 if (nit.getSectionNumber() == 0) { 00072 *nits[numNits].name = 0; 00073 SI::Descriptor *d; 00074 for (SI::Loop::Iterator it; (d = nit.commonDescriptors.getNext(it)); ) { 00075 switch (d->getDescriptorTag()) { 00076 case SI::NetworkNameDescriptorTag: { 00077 SI::NetworkNameDescriptor *nnd = (SI::NetworkNameDescriptor *)d; 00078 nnd->name.getText(nits[numNits].name, MAXNETWORKNAME); 00079 } 00080 break; 00081 default: ; 00082 } 00083 delete d; 00084 } 00085 nits[numNits].networkId = nit.getNetworkId(); 00086 nits[numNits].hasTransponder = false; 00087 //printf("NIT[%d] %5d '%s'\n", numNits, nits[numNits].networkId, nits[numNits].name); 00088 ThisNIT = numNits; 00089 numNits++; 00090 } 00091 } 00092 } 00093 else if (networkId != nit.getNetworkId()) 00094 return; // ignore all other NITs 00095 else if (!sectionSyncer.Sync(nit.getVersionNumber(), nit.getSectionNumber(), nit.getLastSectionNumber())) 00096 return; 00097 if (!Channels.Lock(true, 10)) 00098 return; 00099 SI::NIT::TransportStream ts; 00100 for (SI::Loop::Iterator it; nit.transportStreamLoop.getNext(ts, it); ) { 00101 SI::Descriptor *d; 00102 00103 SI::Loop::Iterator it2; 00104 SI::FrequencyListDescriptor *fld = (SI::FrequencyListDescriptor *)ts.transportStreamDescriptors.getNext(it2, SI::FrequencyListDescriptorTag); 00105 int NumFrequencies = fld ? fld->frequencies.getCount() + 1 : 1; 00106 int Frequencies[NumFrequencies]; 00107 if (fld) { 00108 int ct = fld->getCodingType(); 00109 if (ct > 0) { 00110 int n = 1; 00111 for (SI::Loop::Iterator it3; fld->frequencies.hasNext(it3); ) { 00112 int f = fld->frequencies.getNext(it3); 00113 switch (ct) { 00114 case 1: f = BCD2INT(f) / 100; break; 00115 case 2: f = BCD2INT(f) / 10; break; 00116 case 3: f = f * 10; break; 00117 default: ; 00118 } 00119 Frequencies[n++] = f; 00120 } 00121 } 00122 else 00123 NumFrequencies = 1; 00124 } 00125 delete fld; 00126 00127 for (SI::Loop::Iterator it2; (d = ts.transportStreamDescriptors.getNext(it2)); ) { 00128 switch (d->getDescriptorTag()) { 00129 case SI::SatelliteDeliverySystemDescriptorTag: { 00130 SI::SatelliteDeliverySystemDescriptor *sd = (SI::SatelliteDeliverySystemDescriptor *)d; 00131 cDvbTransponderParameters dtp; 00132 int Source = cSource::FromData(cSource::stSat, BCD2INT(sd->getOrbitalPosition()), sd->getWestEastFlag()); 00133 int Frequency = Frequencies[0] = BCD2INT(sd->getFrequency()) / 100; 00134 static char Polarizations[] = { 'H', 'V', 'L', 'R' }; 00135 dtp.SetPolarization(Polarizations[sd->getPolarization()]); 00136 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 }; 00137 dtp.SetCoderateH(CodeRates[sd->getFecInner()]); 00138 static int Modulations[] = { QAM_AUTO, QPSK, PSK_8, QAM_16 }; 00139 dtp.SetModulation(Modulations[sd->getModulationType()]); 00140 dtp.SetSystem(sd->getModulationSystem() ? DVB_SYSTEM_2 : DVB_SYSTEM_1); 00141 static int RollOffs[] = { ROLLOFF_35, ROLLOFF_25, ROLLOFF_20, ROLLOFF_AUTO }; 00142 dtp.SetRollOff(sd->getModulationSystem() ? RollOffs[sd->getRollOff()] : ROLLOFF_AUTO); 00143 int SymbolRate = BCD2INT(sd->getSymbolRate()) / 10; 00144 if (ThisNIT >= 0) { 00145 for (int n = 0; n < NumFrequencies; n++) { 00146 if (ISTRANSPONDER(cChannel::Transponder(Frequencies[n], dtp.Polarization()), Transponder())) { 00147 nits[ThisNIT].hasTransponder = true; 00148 //printf("has transponder %d\n", Transponder()); 00149 break; 00150 } 00151 } 00152 break; 00153 } 00154 if (Setup.UpdateChannels >= 5) { 00155 bool found = false; 00156 bool forceTransponderUpdate = false; 00157 for (cChannel *Channel = Channels.First(); Channel; Channel = Channels.Next(Channel)) { 00158 if (!Channel->GroupSep() && Channel->Source() == Source && Channel->Nid() == ts.getOriginalNetworkId() && Channel->Tid() == ts.getTransportStreamId()) { 00159 int transponder = Channel->Transponder(); 00160 found = true; 00161 if (!ISTRANSPONDER(cChannel::Transponder(Frequency, dtp.Polarization()), transponder)) { 00162 for (int n = 0; n < NumFrequencies; n++) { 00163 if (ISTRANSPONDER(cChannel::Transponder(Frequencies[n], dtp.Polarization()), transponder)) { 00164 Frequency = Frequencies[n]; 00165 break; 00166 } 00167 } 00168 } 00169 if (ISTRANSPONDER(cChannel::Transponder(Frequency, dtp.Polarization()), Transponder())) // only modify channels if we're actually receiving this transponder 00170 Channel->SetTransponderData(Source, Frequency, SymbolRate, dtp.ToString('S')); 00171 else if (Channel->Srate() != SymbolRate || strcmp(Channel->Parameters(), dtp.ToString('S'))) 00172 forceTransponderUpdate = true; // get us receiving this transponder 00173 } 00174 } 00175 if (!found || forceTransponderUpdate) { 00176 for (int n = 0; n < NumFrequencies; n++) { 00177 cChannel *Channel = new cChannel; 00178 Channel->SetId(ts.getOriginalNetworkId(), ts.getTransportStreamId(), 0, 0); 00179 if (Channel->SetTransponderData(Source, Frequencies[n], SymbolRate, dtp.ToString('S'))) 00180 EITScanner.AddTransponder(Channel); 00181 else 00182 delete Channel; 00183 } 00184 } 00185 } 00186 } 00187 break; 00188 case SI::CableDeliverySystemDescriptorTag: { 00189 SI::CableDeliverySystemDescriptor *sd = (SI::CableDeliverySystemDescriptor *)d; 00190 cDvbTransponderParameters dtp; 00191 int Source = cSource::FromData(cSource::stCable); 00192 int Frequency = Frequencies[0] = BCD2INT(sd->getFrequency()) / 10; 00193 //XXX FEC_outer??? 00194 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 }; 00195 dtp.SetCoderateH(CodeRates[sd->getFecInner()]); 00196 static int Modulations[] = { QPSK, QAM_16, QAM_32, QAM_64, QAM_128, QAM_256, QAM_AUTO }; 00197 dtp.SetModulation(Modulations[min(sd->getModulation(), 6)]); 00198 int SymbolRate = BCD2INT(sd->getSymbolRate()) / 10; 00199 if (ThisNIT >= 0) { 00200 for (int n = 0; n < NumFrequencies; n++) { 00201 if (ISTRANSPONDER(Frequencies[n] / 1000, Transponder())) { 00202 nits[ThisNIT].hasTransponder = true; 00203 //printf("has transponder %d\n", Transponder()); 00204 break; 00205 } 00206 } 00207 break; 00208 } 00209 if (Setup.UpdateChannels >= 5) { 00210 bool found = false; 00211 bool forceTransponderUpdate = false; 00212 for (cChannel *Channel = Channels.First(); Channel; Channel = Channels.Next(Channel)) { 00213 if (!Channel->GroupSep() && Channel->Source() == Source && Channel->Nid() == ts.getOriginalNetworkId() && Channel->Tid() == ts.getTransportStreamId()) { 00214 int transponder = Channel->Transponder(); 00215 found = true; 00216 if (!ISTRANSPONDER(Frequency / 1000, transponder)) { 00217 for (int n = 0; n < NumFrequencies; n++) { 00218 if (ISTRANSPONDER(Frequencies[n] / 1000, transponder)) { 00219 Frequency = Frequencies[n]; 00220 break; 00221 } 00222 } 00223 } 00224 if (ISTRANSPONDER(Frequency / 1000, Transponder())) // only modify channels if we're actually receiving this transponder 00225 Channel->SetTransponderData(Source, Frequency, SymbolRate, dtp.ToString('C')); 00226 else if (Channel->Srate() != SymbolRate || strcmp(Channel->Parameters(), dtp.ToString('C'))) 00227 forceTransponderUpdate = true; // get us receiving this transponder 00228 } 00229 } 00230 if (!found || forceTransponderUpdate) { 00231 for (int n = 0; n < NumFrequencies; n++) { 00232 cChannel *Channel = new cChannel; 00233 Channel->SetId(ts.getOriginalNetworkId(), ts.getTransportStreamId(), 0, 0); 00234 if (Channel->SetTransponderData(Source, Frequencies[n], SymbolRate, dtp.ToString('C'))) 00235 EITScanner.AddTransponder(Channel); 00236 else 00237 delete Channel; 00238 } 00239 } 00240 } 00241 } 00242 break; 00243 case SI::TerrestrialDeliverySystemDescriptorTag: { 00244 SI::TerrestrialDeliverySystemDescriptor *sd = (SI::TerrestrialDeliverySystemDescriptor *)d; 00245 cDvbTransponderParameters dtp; 00246 int Source = cSource::FromData(cSource::stTerr); 00247 int Frequency = Frequencies[0] = sd->getFrequency() * 10; 00248 static int Bandwidths[] = { 8000000, 7000000, 6000000, 5000000, 0, 0, 0, 0 }; 00249 dtp.SetBandwidth(Bandwidths[sd->getBandwidth()]); 00250 static int Constellations[] = { QPSK, QAM_16, QAM_64, QAM_AUTO }; 00251 dtp.SetModulation(Constellations[sd->getConstellation()]); 00252 dtp.SetSystem(DVB_SYSTEM_1); 00253 static int Hierarchies[] = { HIERARCHY_NONE, HIERARCHY_1, HIERARCHY_2, HIERARCHY_4, HIERARCHY_AUTO, HIERARCHY_AUTO, HIERARCHY_AUTO, HIERARCHY_AUTO }; 00254 dtp.SetHierarchy(Hierarchies[sd->getHierarchy()]); 00255 static int CodeRates[] = { FEC_1_2, FEC_2_3, FEC_3_4, FEC_5_6, FEC_7_8, FEC_AUTO, FEC_AUTO, FEC_AUTO }; 00256 dtp.SetCoderateH(CodeRates[sd->getCodeRateHP()]); 00257 dtp.SetCoderateL(CodeRates[sd->getCodeRateLP()]); 00258 static int GuardIntervals[] = { GUARD_INTERVAL_1_32, GUARD_INTERVAL_1_16, GUARD_INTERVAL_1_8, GUARD_INTERVAL_1_4 }; 00259 dtp.SetGuard(GuardIntervals[sd->getGuardInterval()]); 00260 static int TransmissionModes[] = { TRANSMISSION_MODE_2K, TRANSMISSION_MODE_8K, TRANSMISSION_MODE_4K, TRANSMISSION_MODE_AUTO }; 00261 dtp.SetTransmission(TransmissionModes[sd->getTransmissionMode()]); 00262 if (ThisNIT >= 0) { 00263 for (int n = 0; n < NumFrequencies; n++) { 00264 if (ISTRANSPONDER(Frequencies[n] / 1000000, Transponder())) { 00265 nits[ThisNIT].hasTransponder = true; 00266 //printf("has transponder %d\n", Transponder()); 00267 break; 00268 } 00269 } 00270 break; 00271 } 00272 if (Setup.UpdateChannels >= 5) { 00273 bool found = false; 00274 bool forceTransponderUpdate = false; 00275 for (cChannel *Channel = Channels.First(); Channel; Channel = Channels.Next(Channel)) { 00276 if (!Channel->GroupSep() && Channel->Source() == Source && Channel->Nid() == ts.getOriginalNetworkId() && Channel->Tid() == ts.getTransportStreamId()) { 00277 int transponder = Channel->Transponder(); 00278 found = true; 00279 if (!ISTRANSPONDER(Frequency / 1000000, transponder)) { 00280 for (int n = 0; n < NumFrequencies; n++) { 00281 if (ISTRANSPONDER(Frequencies[n] / 1000000, transponder)) { 00282 Frequency = Frequencies[n]; 00283 break; 00284 } 00285 } 00286 } 00287 if (ISTRANSPONDER(Frequency / 1000000, Transponder())) // only modify channels if we're actually receiving this transponder 00288 Channel->SetTransponderData(Source, Frequency, 0, dtp.ToString('T')); 00289 else if (strcmp(Channel->Parameters(), dtp.ToString('T'))) 00290 forceTransponderUpdate = true; // get us receiving this transponder 00291 } 00292 } 00293 if (!found || forceTransponderUpdate) { 00294 for (int n = 0; n < NumFrequencies; n++) { 00295 cChannel *Channel = new cChannel; 00296 Channel->SetId(ts.getOriginalNetworkId(), ts.getTransportStreamId(), 0, 0); 00297 if (Channel->SetTransponderData(Source, Frequencies[n], 0, dtp.ToString('T'))) 00298 EITScanner.AddTransponder(Channel); 00299 else 00300 delete Channel; 00301 } 00302 } 00303 } 00304 } 00305 break; 00306 case SI::ExtensionDescriptorTag: { 00307 SI::ExtensionDescriptor *sd = (SI::ExtensionDescriptor *)d; 00308 switch (sd->getExtensionDescriptorTag()) { 00309 case SI::T2DeliverySystemDescriptorTag: { 00310 if (Setup.UpdateChannels >= 5) { 00311 for (cChannel *Channel = Channels.First(); Channel; Channel = Channels.Next(Channel)) { 00312 int Source = cSource::FromData(cSource::stTerr); 00313 if (!Channel->GroupSep() && Channel->Source() == Source && Channel->Nid() == ts.getOriginalNetworkId() && Channel->Tid() == ts.getTransportStreamId()) { 00314 SI::T2DeliverySystemDescriptor *td = (SI::T2DeliverySystemDescriptor *)d; 00315 int Frequency = Channel->Frequency(); 00316 int SymbolRate = Channel->Srate(); 00317 //int SystemId = td->getSystemId(); 00318 cDvbTransponderParameters dtp(Channel->Parameters()); 00319 dtp.SetSystem(DVB_SYSTEM_2); 00320 dtp.SetPlpId(td->getPlpId()); 00321 if (td->getExtendedDataFlag()) { 00322 static int T2Bandwidths[] = { 8000000, 7000000, 6000000, 5000000, 10000000, 1712000, 0, 0 }; 00323 dtp.SetBandwidth(T2Bandwidths[td->getBandwidth()]); 00324 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 }; 00325 dtp.SetGuard(T2GuardIntervals[td->getGuardInterval()]); 00326 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 }; 00327 dtp.SetTransmission(T2TransmissionModes[td->getTransmissionMode()]); 00328 //TODO add parsing of frequencies 00329 } 00330 Channel->SetTransponderData(Source, Frequency, SymbolRate, dtp.ToString('T')); 00331 } 00332 } 00333 } 00334 } 00335 break; 00336 default: ; 00337 } 00338 } 00339 break; 00340 default: ; 00341 } 00342 delete d; 00343 } 00344 } 00345 Channels.Unlock(); 00346 }