VDR constantly tries to change transponder frequency

Message ID 44785E18.2030006@cadsoft.de
State New
Headers

Commit Message

Klaus Schmidinger May 27, 2006, 2:11 p.m. UTC
  Klaus Schmidinger wrote:
> Anssi Hannula wrote:
>> ...
>> Okay, attached is a patch for nit.c that checks for all the frequencies
>> in frequency_list_descriptor for the channel's frequency and if found,
>> use it so that channel's frequency is not changed.
>>
>> Also in the detection of new transponders all frequencies are added for
>> the EITscanner.
>>
>> I tested it by removing a transponder from channels.conf, and VDR found
>> it again (though it took a while, as there are *many* frequencies in the
>> frequency_list_descriptor). This too hasn't been working before on the
>> DVB-T network of Finland.
>> ...

Please test whether the attached version of the patch still works.
Since none of the satellites I can receive uses the FrequencyListDescriptor,
and I don't have cable or terrestrial signals, I can't test it myself.

If it's ok like this for you, I would include it in tomorrow's
maintenance patch.

Note that I had to make a small change to libsi/si.h in order to
avoid a compiler warning.

Klaus
  

Comments

Anssi Hannula May 27, 2006, 2:52 p.m. UTC | #1
On 5/27/06, Klaus Schmidinger <Klaus.Schmidinger@cadsoft.de> wrote:
> Klaus Schmidinger wrote:
> > Anssi Hannula wrote:
> >> ...
> >> Okay, attached is a patch for nit.c that checks for all the frequencies
> >> in frequency_list_descriptor for the channel's frequency and if found,
> >> use it so that channel's frequency is not changed.
> >>
> >> Also in the detection of new transponders all frequencies are added for
> >> the EITscanner.
> >>
> >> I tested it by removing a transponder from channels.conf, and VDR found
> >> it again (though it took a while, as there are *many* frequencies in the
> >> frequency_list_descriptor). This too hasn't been working before on the
> >> DVB-T network of Finland.
> >> ...
>
> Please test whether the attached version of the patch still works.
> Since none of the satellites I can receive uses the FrequencyListDescriptor,
> and I don't have cable or terrestrial signals, I can't test it myself.
>
> If it's ok like this for you, I would include it in tomorrow's
> maintenance patch.
>
> Note that I had to make a small change to libsi/si.h in order to
> avoid a compiler warning.

Okay, I'll be able to test in few hours.

But I can see few issues in the patch:

> +      if (fld) {
> +         int n = 1;
> +         for (SI::Loop::Iterator it3; fld->frequencies.hasNext(it3); ) {
> +             int f = fld->frequencies.getNext(it3);
> +             int ct = fld->getCodingType();
This can be moved above the loop, as the descriptor has a common coding_type.

> +             if (ct < 3)
> +                f = BCD2INT(f) / (ct == 1 ? 100 : 10);
> +             Frequencies[n++] = f;
You miss two ct cases:
- when ct == 3, frequency should be multiplied with 10.
- when ct == 0, coding_type is undefined, so I guess we should
disregard the frequency_list_descriptor then.

> +             }
> +         }
  

Patch

--- nit.c	2006/04/15 14:10:42	1.11
+++ nit.c	2006/05/27 14:03:49
@@ -95,46 +95,77 @@ 
   SI::NIT::TransportStream ts;
   for (SI::Loop::Iterator it; nit.transportStreamLoop.getNext(ts, it); ) {
       SI::Descriptor *d;
+
+      SI::Loop::Iterator it2;
+      SI::FrequencyListDescriptor *fld = (SI::FrequencyListDescriptor *)ts.transportStreamDescriptors.getNext(it2, SI::FrequencyListDescriptorTag);
+      int NumFrequencies = fld ? fld->frequencies.getCount() + 1 : 1;
+      int Frequencies[NumFrequencies];
+      if (fld) {
+         int n = 1;
+         for (SI::Loop::Iterator it3; fld->frequencies.hasNext(it3); ) {
+             int f = fld->frequencies.getNext(it3);
+             int ct = fld->getCodingType();
+             if (ct < 3)
+                f = BCD2INT(f) / (ct == 1 ? 100 : 10);
+             Frequencies[n++] = f;
+             }
+         }
+      delete fld;
+
       for (SI::Loop::Iterator it2; (d = ts.transportStreamDescriptors.getNext(it2)); ) {
           switch (d->getDescriptorTag()) {
             case SI::SatelliteDeliverySystemDescriptorTag: {
                  SI::SatelliteDeliverySystemDescriptor *sd = (SI::SatelliteDeliverySystemDescriptor *)d;
                  int Source = cSource::FromData(cSource::stSat, BCD2INT(sd->getOrbitalPosition()), sd->getWestEastFlag());
-                 int Frequency = BCD2INT(sd->getFrequency()) / 100;
+                 int Frequency = Frequencies[0] = BCD2INT(sd->getFrequency()) / 100;
                  static char Polarizations[] = { 'h', 'v', 'l', 'r' };
                  char Polarization = Polarizations[sd->getPolarization()];
                  static int CodeRates[] = { FEC_NONE, FEC_1_2, FEC_2_3, FEC_3_4, FEC_5_6, FEC_7_8, FEC_AUTO, FEC_AUTO, FEC_AUTO, FEC_AUTO, FEC_AUTO, FEC_AUTO, FEC_AUTO, FEC_AUTO, FEC_AUTO, FEC_NONE };
                  int CodeRate = CodeRates[sd->getFecInner()];
                  int SymbolRate = BCD2INT(sd->getSymbolRate()) / 10;
                  if (ThisNIT >= 0) {
-                    if (ISTRANSPONDER(cChannel::Transponder(Frequency, Polarization), Transponder())) {
-                       nits[ThisNIT].hasTransponder = true;
-                       //printf("has transponder %d\n", Transponder());
-                       }
+                    for (int n = 0; n < NumFrequencies; n++) {
+                        if (ISTRANSPONDER(cChannel::Transponder(Frequencies[n], Polarization), Transponder())) {
+                           nits[ThisNIT].hasTransponder = true;
+                           //printf("has transponder %d\n", Transponder());
+                           break;
+                           }
+                        }
                     break;
                     }
                  bool found = false;
                  for (cChannel *Channel = Channels.First(); Channel; Channel = Channels.Next(Channel)) {
                      if (!Channel->GroupSep() && Channel->Source() == Source && Channel->Nid() == ts.getOriginalNetworkId() && Channel->Tid() == ts.getTransportStreamId()) {
-                        if (Setup.UpdateChannels >= 5)
+                        if (Setup.UpdateChannels >= 5) {
+                           if (!ISTRANSPONDER(cChannel::Transponder(Frequency, Polarization), Channel->Transponder())) {
+                              for (int n = 0; n < NumFrequencies; n++) {
+                                  if (ISTRANSPONDER(cChannel::Transponder(Frequencies[n], Polarization), Channel->Transponder())) {
+                                     Frequency = Frequencies[n];
+                                     break;
+                                     }
+                                  }
+                              }
                            Channel->SetSatTransponderData(Source, Frequency, Polarization, SymbolRate, CodeRate);
+                           }
                         found = true;
                         }
                      }
                  if (!found && Setup.UpdateChannels >= 5) {
-                    cChannel *Channel = new cChannel;
-                    Channel->SetId(ts.getOriginalNetworkId(), ts.getTransportStreamId(), 0, 0);
-                    if (Channel->SetSatTransponderData(Source, Frequency, Polarization, SymbolRate, CodeRate))
-                       EITScanner.AddTransponder(Channel);
-                    else
-                       delete Channel;
+                    for (int n = 0; n < NumFrequencies; n++) {
+                        cChannel *Channel = new cChannel;
+                        Channel->SetId(ts.getOriginalNetworkId(), ts.getTransportStreamId(), 0, 0);
+                        if (Channel->SetSatTransponderData(Source, Frequencies[n], Polarization, SymbolRate, CodeRate))
+                           EITScanner.AddTransponder(Channel);
+                        else
+                           delete Channel;
+                        }
                     }
                  }
                  break;
             case SI::CableDeliverySystemDescriptorTag: {
                  SI::CableDeliverySystemDescriptor *sd = (SI::CableDeliverySystemDescriptor *)d;
                  int Source = cSource::FromData(cSource::stCable);
-                 int Frequency = BCD2INT(sd->getFrequency()) / 10;
+                 int Frequency = Frequencies[0] = BCD2INT(sd->getFrequency()) / 10;
                  //XXX FEC_outer???
                  static int CodeRates[] = { FEC_NONE, FEC_1_2, FEC_2_3, FEC_3_4, FEC_5_6, FEC_7_8, FEC_AUTO, FEC_AUTO, FEC_AUTO, FEC_AUTO, FEC_AUTO, FEC_AUTO, FEC_AUTO, FEC_AUTO, FEC_AUTO, FEC_NONE };
                  int CodeRate = CodeRates[sd->getFecInner()];
@@ -142,34 +173,48 @@ 
                  int Modulation = Modulations[min(sd->getModulation(), 6)];
                  int SymbolRate = BCD2INT(sd->getSymbolRate()) / 10;
                  if (ThisNIT >= 0) {
-                    if (ISTRANSPONDER(Frequency / 1000, Transponder())) {
-                       nits[ThisNIT].hasTransponder = true;
-                       //printf("has transponder %d\n", Transponder());
-                       }
+                    for (int n = 0; n < NumFrequencies; n++) {
+                        if (ISTRANSPONDER(Frequencies[n] / 1000, Transponder())) {
+                           nits[ThisNIT].hasTransponder = true;
+                           //printf("has transponder %d\n", Transponder());
+                           break;
+                           }
+                        }
                     break;
                     }
                  bool found = false;
                  for (cChannel *Channel = Channels.First(); Channel; Channel = Channels.Next(Channel)) {
                      if (!Channel->GroupSep() && Channel->Source() == Source && Channel->Nid() == ts.getOriginalNetworkId() && Channel->Tid() == ts.getTransportStreamId()) {
-                        if (Setup.UpdateChannels >= 5)
+                        if (Setup.UpdateChannels >= 5) {
+                           if (!ISTRANSPONDER(Frequency / 1000, Channel->Transponder())) {
+                              for (int n = 0; n < NumFrequencies; n++) {
+                                  if (ISTRANSPONDER(Frequencies[n] / 1000, Channel->Transponder())) {
+                                     Frequency = Frequencies[n];
+                                     break;
+                                     }
+                                  }
+                              }
                            Channel->SetCableTransponderData(Source, Frequency, Modulation, SymbolRate, CodeRate);
+                           }
                         found = true;
                         }
                      }
                  if (!found && Setup.UpdateChannels >= 5) {
-                    cChannel *Channel = new cChannel;
-                    Channel->SetId(ts.getOriginalNetworkId(), ts.getTransportStreamId(), 0, 0);
-                    if (Channel->SetCableTransponderData(Source, Frequency, Modulation, SymbolRate, CodeRate))
-                       EITScanner.AddTransponder(Channel);
-                    else
-                       delete Channel;
+                    for (int n = 0; n < NumFrequencies; n++) {
+                        cChannel *Channel = new cChannel;
+                        Channel->SetId(ts.getOriginalNetworkId(), ts.getTransportStreamId(), 0, 0);
+                        if (Channel->SetCableTransponderData(Source, Frequencies[n], Modulation, SymbolRate, CodeRate))
+                           EITScanner.AddTransponder(Channel);
+                        else
+                           delete Channel;
+                        }
                     }
                  }
                  break;
             case SI::TerrestrialDeliverySystemDescriptorTag: {
                  SI::TerrestrialDeliverySystemDescriptor *sd = (SI::TerrestrialDeliverySystemDescriptor *)d;
                  int Source = cSource::FromData(cSource::stTerr);
-                 int Frequency = sd->getFrequency() * 10;
+                 int Frequency = Frequencies[0] = sd->getFrequency() * 10;
                  static int Bandwidths[] = { BANDWIDTH_8_MHZ, BANDWIDTH_7_MHZ, BANDWIDTH_6_MHZ, BANDWIDTH_AUTO, BANDWIDTH_AUTO, BANDWIDTH_AUTO, BANDWIDTH_AUTO, BANDWIDTH_AUTO };
                  int Bandwidth = Bandwidths[sd->getBandwidth()];
                  static int Constellations[] = { QPSK, QAM_16, QAM_64, QAM_AUTO };
@@ -184,27 +229,41 @@ 
                  static int TransmissionModes[] = { TRANSMISSION_MODE_2K, TRANSMISSION_MODE_8K, TRANSMISSION_MODE_AUTO, TRANSMISSION_MODE_AUTO };
                  int TransmissionMode = TransmissionModes[sd->getTransmissionMode()];
                  if (ThisNIT >= 0) {
-                    if (ISTRANSPONDER(Frequency / 1000000, Transponder())) {
-                       nits[ThisNIT].hasTransponder = true;
-                       //printf("has transponder %d\n", Transponder());
-                       }
+                    for (int n = 0; n < NumFrequencies; n++) {
+                        if (ISTRANSPONDER(Frequencies[n] / 1000000, Transponder())) {
+                           nits[ThisNIT].hasTransponder = true;
+                           //printf("has transponder %d\n", Transponder());
+                           break;
+                           }
+                        }
                     break;
                     }
                  bool found = false;
                  for (cChannel *Channel = Channels.First(); Channel; Channel = Channels.Next(Channel)) {
                      if (!Channel->GroupSep() && Channel->Source() == Source && Channel->Nid() == ts.getOriginalNetworkId() && Channel->Tid() == ts.getTransportStreamId()) {
-                        if (Setup.UpdateChannels >= 5)
+                        if (Setup.UpdateChannels >= 5) {
+                           if (!ISTRANSPONDER(Frequency / 1000000, Channel->Transponder())) {
+                              for (int n = 0; n < NumFrequencies; n++) {
+                                  if (ISTRANSPONDER(Frequencies[n] / 1000000, Channel->Transponder())) {
+                                     Frequency = Frequencies[n];
+                                     break;
+                                     }
+                                  }
+                              }
                            Channel->SetTerrTransponderData(Source, Frequency, Bandwidth, Constellation, Hierarchy, CodeRateHP, CodeRateLP, GuardInterval, TransmissionMode);
+                           }
                         found = true;
                         }
                      }
                  if (!found && Setup.UpdateChannels >= 5) {
-                    cChannel *Channel = new cChannel;
-                    Channel->SetId(ts.getOriginalNetworkId(), ts.getTransportStreamId(), 0, 0);
-                    if (Channel->SetTerrTransponderData(Source, Frequency, Bandwidth, Constellation, Hierarchy, CodeRateHP, CodeRateLP, GuardInterval, TransmissionMode))
-                       EITScanner.AddTransponder(Channel);
-                    else
-                       delete Channel;
+                    for (int n = 0; n < NumFrequencies; n++) {
+                        cChannel *Channel = new cChannel;
+                        Channel->SetId(ts.getOriginalNetworkId(), ts.getTransportStreamId(), 0, 0);
+                        if (Channel->SetTerrTransponderData(Source, Frequencies[n], Bandwidth, Constellation, Hierarchy, CodeRateHP, CodeRateLP, GuardInterval, TransmissionMode))
+                           EITScanner.AddTransponder(Channel);
+                        else
+                           delete Channel;
+                        }
                     }
                  }
                  break;
--- libsi/si.h	2006/04/14 10:53:44	1.14
+++ libsi/si.h	2006/05/27 13:07:20
@@ -399,6 +399,7 @@ 
          case 8:
             return (SixtyFourBit(data.FourBytes(index)) << 32) | data.FourBytes(index+4);
          }
+         return 0; // just to avoid a compiler warning
       }
    T getNext(Iterator &it) const
       {