VDR constantly tries to change transponder frequency

Message ID 44787299.1070800@cadsoft.de
State New
Headers

Commit Message

Klaus Schmidinger May 27, 2006, 3:39 p.m. UTC
  Anssi Hannula wrote:
> 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.

Ah, you're right.
Attached is a new version.

Klaus
  

Comments

Anssi Hannula May 27, 2006, 4:44 p.m. UTC | #1
Klaus Schmidinger wrote:
> Anssi Hannula wrote:
> 
>> 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.
>>>

> Attached is a new version.
> 

It works fine :)
  

Patch

--- nit.c	2006/04/15 14:10:42	1.11
+++ nit.c	2006/05/27 15:35:16
@@ -48,7 +48,7 @@ 
                    if (nits[j].hasTransponder) {
                       networkId = nits[j].networkId;
                       //printf("taking NIT with network ID %d\n", networkId);
-                      //XXX what if more than one NIT contaisn this transponder???
+                      //XXX what if more than one NIT contains this transponder???
                       break;
                       }
                    }
@@ -95,46 +95,84 @@ 
   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 ct = fld->getCodingType();
+         if (ct > 0) {
+            int n = 1;
+            for (SI::Loop::Iterator it3; fld->frequencies.hasNext(it3); ) {
+                int f = fld->frequencies.getNext(it3);
+                switch (ct) {
+                  case 1: f = BCD2INT(f) / 100; break;
+                  case 2: f = BCD2INT(f) / 10; break;
+                  case 3: f = f * 10;  break;
+                  }
+                Frequencies[n++] = f;
+                }
+            }
+         else
+            NumFrequencies = 1;
+         }
+      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 +180,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 +236,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
       {