[ANNOUNCE] vdr-rotor support patches for VDR-1.5.16

Message ID 47C1D0C9.3070008@gmx.de
State New
Headers

Commit Message

Reinhard Nissl Feb. 24, 2008, 8:17 p.m. UTC
  Hi,

the attached patch replaces the previously released but
incomplete patch for VDR-1.5.14, which was part of my recent
rotor support patches.

You have to apply this patch after patching VDR-1.5.16 with
DVB-S2+H.264 support.

Bye.
  

Comments

Seppo Ingalsuo Feb. 28, 2008, 10:37 p.m. UTC | #1
First, thanks for your vdr patches and all the work with xine-lib!

Reinhard Nissl wrote:
> the attached patch replaces the previously released but
> incomplete patch for VDR-1.5.14, which was part of my recent
> rotor support patches.
>
> You have to apply this patch after patching VDR-1.5.16 with
> DVB-S2+H.264 support.
>   
Do you get this error when compiling rotor plugin 
(vdr-rotor-0.1.4-vdr1.5.7.tgz)?

g++-4.3 -O2 -Wall -Woverloaded-virtual -Wno-parentheses -fPIC -c 
-D_GNU_SOURCE -DPLUGIN_NAME_I18N='"rotor"' 
-I/home/seppo/src/dvb/multiproto-0448e5a6d8a6/linux/include 
-I../../..//include 
-I/home/seppo/src/dvb/multiproto-0448e5a6d8a6/linux/include menu.c
menu.c: In member function 'virtual eOSState 
cMainMenuRotor::ProcessKey(eKeys)':
menu.c:304: error: no matching function for call to 
'cChannel::SetSatTransponderData(int, int&, char&, int&, fe_code_rate)'
../../..//include/vdr/channels.h:226: note: candidates are: bool 
cChannel::SetSatTransponderData(int, int, char, int, int, int, int, int)
menu.c:316: error: no matching function for call to 
'cChannel::SetSatTransponderData(int, int&, char&, int&, fe_code_rate)'
../../..//include/vdr/channels.h:226: note: candidates are: bool 
cChannel::SetSatTransponderData(int, int, char, int, int, int, int, int)
menu.c: In member function 'void cMenuScan::AddChannel(int)':
menu.c:429: error: no matching function for call to 
'cChannel::SetPids(int, int, int [33], char [33][8], int [17], char 
[17][8], int)'
../../..//include/vdr/channels.h:232: note: candidates are: void 
cChannel::SetPids(int, int, int*, char (*)[8], int*, char (*)[8], int*, 
char (*)[8], int)
menu.c: In member function 'void cMenuScan::SetPids(int, int, int, int*, 
char (*)[8], int*, char (*)[8], int)':
menu.c:467: error: no matching function for call to 
'cChannel::SetPids(int&, int&, int*&, char (*&)[8], int*&, char (*&)[8], 
int&)'
../../..//include/vdr/channels.h:232: note: candidates are: void 
cChannel::SetPids(int, int, int*, char (*)[8], int*, char (*)[8], int*, 
char (*)[8], int)
make[1]: *** [menu.o] Error 1

As a brutal fix I added dummy parameters (zeros, copy language strings, 
etc.) for SetSatTransponderData() and SetPids() calls to get it 
compiled. I appreciate a real correction if such exists ;^)

I'm having problems in getting my diseqc motor positioner to work with 
multiproto+h.264 patched vdr 1.5.16. It is at the moment very 
unreliable. Most of the time it just stays stuck into the old position 
so possibly the commands get corrupted.  Is a Technotrend S2-3200 
capable to control a positioner? My old budget-s Tecnotrend was very 
reliable in driving the same positioner.

BR,
Seppo
  
Reinhard Nissl Feb. 29, 2008, 9:41 a.m. UTC | #2
Hi,

Seppo Ingalsuo schrieb:

>> the attached patch replaces the previously released but
>> incomplete patch for VDR-1.5.14, which was part of my recent
>> rotor support patches.
>>
>> You have to apply this patch after patching VDR-1.5.16 with
>> DVB-S2+H.264 support.
>   
> Do you get this error when compiling rotor plugin 
> (vdr-rotor-0.1.4-vdr1.5.7.tgz)?

As mentioned above, you'll need an updated vdr-rotor too (see
attachment), which makes use of the new API.

> As a brutal fix I added dummy parameters (zeros, copy language strings, 
> etc.) for SetSatTransponderData() and SetPids() calls to get it 
> compiled. I appreciate a real correction if such exists ;^)

Well, 0 is not a good dummy value in case of the multiproto tree,
but the attached vdr-rotor should solve this issue.

> I'm having problems in getting my diseqc motor positioner to work with 
> multiproto+h.264 patched vdr 1.5.16. It is at the moment very 
> unreliable. Most of the time it just stays stuck into the old position 
> so possibly the commands get corrupted.  Is a Technotrend S2-3200 
> capable to control a positioner? My old budget-s Tecnotrend was very 
> reliable in driving the same positioner.

Hhm, as I do not own a positioner myself, I cannot test vdr-rotor
in practice.

Bye.
  
Seppo Ingalsuo Feb. 29, 2008, 7:03 p.m. UTC | #3
Reinhard Nissl wrote:
> As mentioned above, you'll need an updated vdr-rotor too (see
> attachment), which makes use of the new API.
>
>   
Thanks! This one compiled cleanly.
> Hhm, as I do not own a positioner myself, I cannot test vdr-rotor
> in practice.
>   
OK, I got some help in linux-dvb mailing list with diseqc command 
unreliability. Now it looks a bit better (but not yet good enough "WAF").

Cheers,
Seppo
  
Ales Jurik March 3, 2008, 2:59 p.m. UTC | #4
On Thursday 28 of February 2008, Seppo Ingalsuo wrote:
> I'm having problems in getting my diseqc motor positioner to work with
> multiproto+h.264 patched vdr 1.5.16. It is at the moment very
> unreliable. Most of the time it just stays stuck into the old position
> so possibly the commands get corrupted.  Is a Technotrend S2-3200
> capable to control a positioner? My old budget-s Tecnotrend was very
> reliable in driving the same positioner.

I've also had such problem. This weekend I've tried to solve which part of sw 
is making this diseqc unreliability - and today I've tested the result once 
more. 

My result is that the problem with stucked motor appears with new multiproto 
driver. When I'm using multiproto from 21.12. no problem appears at all.

My configuration is Debian Lenny, vdr-1.5.14 with rotor-0.1.4 
(vdr-1.5.5-rotor.diff and Rotor-0.1.4-vdr1.5.10.diff patches), diseqc in vdr 
enabled (I've motor at 4th input of 4-input diseqc switch). 

BTW - Repeat DiSEqC-Commands must be set to enabled (this seems to be related 
to my diseqc cascade with switch).

Hw is TT S2-3200, AMD Athlon 64 X2 - 5200+.

Regards,

Ales
  
Seppo Ingalsuo March 4, 2008, 11:41 p.m. UTC | #5
Ales Jurik wrote:
> My result is that the problem with stucked motor appears with new multiproto 
> driver. When I'm using multiproto from 21.12. no problem appears at all.
>   
I couldn't repeat that but I didn't find exactly that multiproto driver.

But I noticed that zapping works reliably with between channels in 
different positions with LNB tone off (frequency < 11700, if I got this 
right...). V/H polarization didn't matter (13V or 18V LNB voltage). 
There should be 15 ms tone off between DiSEqC messages and continuous 
tone that might not happen with rotor plugin and this DVB driver. I 
wonder if that could be the reason?

I wish the GotoX would be better integrated to vdr's DiSEqC 
architecture. Now it looks a bit flaky, rotor plugin seems to monitor 
channel switch events in status.c. I wonder if additing tone off 
controls around gotox transmission would have impact to tuning where 
tone and voltage are set?

BR,
Seppo
  
Ales Jurik March 5, 2008, 2:33 p.m. UTC | #6
On Wednesday 05 of March 2008, Seppo Ingalsuo wrote:
> I couldn't repeat that but I didn't find exactly that multiproto driver.

Hi,

I'm testing it with this one - 
http://jusst.de/hg/multiproto/archive/4df151d5b3fe.tar.bz2. 
I've only changed some print and debug options in my tests.

>
> But I noticed that zapping works reliably with between channels in
> different positions with LNB tone off (frequency < 11700, if I got this
> right...). V/H polarization didn't matter (13V or 18V LNB voltage).
> There should be 15 ms tone off between DiSEqC messages and continuous
> tone that might not happen with rotor plugin and this DVB driver. I
> wonder if that could be the reason?
>

Yes, my fault - I've switched between satellites only on lower band. But with 
newest version of multiproto also this was not possible. But I'm using it 
with cascade switch/motor, so my tests could have different results.

BR,

Ales
  
Seppo Ingalsuo March 7, 2008, 9:06 p.m. UTC | #7
Hi,

I haven't been able to make rotor plugin work with the multiproto 
driver. I created dummy channel entries that have tone off (f < 11700) 
into beginning of each satellite position group in my channels.conf  and 
now zapping with rotor plugin by pressing ok and then < and > keys works 
with 100% success. I have been looking at rotor plugin and didn't get 
idea how switching off tone could be syncronized to tuning and 
diseqc.conf sequences without possible negative influence to tuning. Or 
is there a guarantee for some order of execution? I wonder if it worked 
with the existing Linux kernel DVB-S driver with just good luck.

Wouldn't it be better to have in diseqc.conf possibility for this kind 
of setup

S19.2E 11700 V  9750 t V W15 G W15 v t
S19.2E 99999 V 10600 t V W15 G W15 v T
S19.2E 11700 H  9750 t V W15 G W15 V t
S19.2E 99999 H 10600 t V W15 G W15 V T

where the continuous tone is first switched off, then LNB voltage is set 
to 18V for better rotor speed and then GotoX is sent with internal 
computation based on new position and geographic location, etc (to be 
added to vdr setup, e.g. LNB diseqc config page). There could blind be 
waiting of positioning inside G operation with estimate about rotor 
speed to avoid temporary tuning to intermediate positions. Finally the 
proper tone and voltage is set. This way there would be exact control 
when GotoX is issued. It would be possible to enable EIT scan and 
channel/multiplex updates with rotor without fear that it messes up 
channels.conf. With some more thinking the "t V W15" and  "W15" should 
perhaps be put inside "G".

This could be done by utilizing code from rotor plugin this into dvbdevice.c

  if (frontendType & (DVBFE_DELSYS_DVBS | DVBFE_DELSYS_DVBS2)) {
     unsigned int frequency = channel.Frequency();
     if (Setup.DiSEqC) {
        cDiseqc *diseqc = Diseqcs.Get(channel.Source(), 
channel.Frequency(), channel.Polarization());
        if (diseqc) {
           if (diseqc->Commands() && (!diseqcCommands || 
strcmp(diseqcCommands, diseqc->Commands()) != 0)) {
              cDiseqc::eDiseqcActions da;
              for (char *CurrentAction = NULL; (da = 
diseqc->Execute(&CurrentAction)) != cDiseqc::daNone; ) {
                  switch (da) {
                    case cDiseqc::daNone:      break;
                    case cDiseqc::daToneOff:   CHECK(ioctl(fd_frontend, 
FE_SET_TONE, SEC_TONE_OFF)); break;
                    case cDiseqc::daToneOn:    CHECK(ioctl(fd_frontend, 
FE_SET_TONE, SEC_TONE_ON)); break;
                    case cDiseqc::daVoltage13: CHECK(ioctl(fd_frontend, 
FE_SET_VOLTAGE, SEC_VOLTAGE_13)); break;
                    case cDiseqc::daVoltage18: CHECK(ioctl(fd_frontend, 
FE_SET_VOLTAGE, SEC_VOLTAGE_18)); break;
                    case cDiseqc::daMiniA:     CHECK(ioctl(fd_frontend, 
FE_DISEQC_SEND_BURST, SEC_MINI_A)); break;
                    case cDiseqc::daMiniB:     CHECK(ioctl(fd_frontend, 
FE_DISEQC_SEND_BURST, SEC_MINI_B)); break;
                    case cDiseqc::daGotoX: {

             ...

              int gotoXTable[10] = { 0x00, 0x02, 0x03, 0x05, 0x06, 0x08, 
0x0A, 0x0B, 0x0D, 0x0E };
              int satlong = (Source & ~0xC800);
              if ((Source & 0xC000) != 0x8000)
            return;
              if (Source & 0x0800)
            satlong = satlong * (-1);
              int Long=data.GotoxEW ? -data.GotoxLong : data.GotoxLong;
              int Lat=data.GotoxSN ? -data.GotoxLat : data.GotoxLat;
              double 
azimuth=M_PI+atan(tan((satlong-Long)*M_PI/1800)/sin(Lat*M_PI/1800));
              double 
x=acos(cos((satlong-Long)*M_PI/1800)*cos(Lat*M_PI/1800));
              double elevation=atan((cos(x)-0.1513)/sin(x));
              double 
SatHourangle=180+atan((-cos(elevation)*sin(azimuth))/(sin(elevation)*cos(Lat*M_PI/1800)
                          
-cos(elevation)*sin(Lat*M_PI/1800)*cos(azimuth)))*180/M_PI;
              int tmp=(int)(fabs(180-SatHourangle)*10);
              tmp=(tmp/10)*0x10 + gotoXTable[ tmp % 10 ];
              int p2=(tmp%0x0100);
              int p1=(tmp/0x0100);
              if (SatHourangle < 180)
            p1 |= 0xe0;
              else
            p1 |= 0xd0;
              DiseqcCommand(Gotox,p1,p2);
            }

            ...

            break;

But as vdr illiterate I couldn't figure how to check if the zapped 
source (diseqc->source?) is a new one to avoid generating unnecessary 
DiSEqC traffic and delays, and wondered to get a global variable for 
storing the previous position... help!

Or does this make sense?

Cheers,
Seppo
  
Ales Jurik March 7, 2008, 10:51 p.m. UTC | #8
On Friday 07 of March 2008, Seppo Ingalsuo wrote:

> But as vdr illiterate I couldn't figure how to check if the zapped
> source (diseqc->source?) is a new one to avoid generating unnecessary
> DiSEqC traffic and delays, and wondered to get a global variable for
> storing the previous position... help!

This seems to be already checked in status.c. I've used debug message to show 
all diseqc commands send and it seems to work fine (for me).

BR,

Ales
  

Patch

diff -Nurp ../vdr-1.5.16-dvbs2-other/device.c ./device.c
--- ../vdr-1.5.16-dvbs2-other/device.c	2008-02-24 19:14:45.000000000 +0100
+++ ./device.c	2008-02-24 20:53:36.000000000 +0100
@@ -745,12 +745,22 @@  bool cDevice::MaySwitchTransponder(void)
 
 bool cDevice::SwitchChannel(const cChannel *Channel, bool LiveView)
 {
+  return SwitchChannel(Channel, LiveView, NULL);
+}
+
+bool cDevice::SwitchChannel(const cChannel *Channel, cDevice *SpecificSourceDevice)
+{
+  return SwitchChannel(Channel, true, SpecificSourceDevice);
+}
+
+bool cDevice::SwitchChannel(const cChannel *Channel, bool LiveView, cDevice *SpecificSourceDevice)
+{
   if (LiveView) {
      isyslog("switching to channel %d", Channel->Number());
      cControl::Shutdown(); // prevents old channel from being shown too long if GetDevice() takes longer
      }
   for (int i = 3; i--;) {
-      switch (SetChannel(Channel, LiveView)) {
+      switch (SetChannel(Channel, LiveView, SpecificSourceDevice)) {
         case scrOk:           return true;
         case scrNotAvailable: Skins.Message(mtInfo, tr("Channel not available!"));
                               return false;
@@ -793,7 +803,7 @@  bool cDevice::SwitchChannel(int Directio
   return result;
 }
 
-eSetChannelResult cDevice::SetChannel(const cChannel *Channel, bool LiveView)
+eSetChannelResult cDevice::SetChannel(const cChannel *Channel, bool LiveView, cDevice *SpecificSourceDevice)
 {
   if (LiveView) {
      StopReplay();
@@ -801,7 +811,7 @@  eSetChannelResult cDevice::SetChannel(co
      DELETENULL(dvbSubtitleConverter);
      }
 
-  cDevice *Device = (LiveView && IsPrimaryDevice()) ? GetDevice(Channel, 0, LiveView) : this;
+  cDevice *Device = (LiveView && IsPrimaryDevice()) ? (SpecificSourceDevice ? SpecificSourceDevice : GetDevice(Channel, 0, LiveView)) : this;
 
   bool NeedsTransferMode = Device != this;
 
diff -Nurp ../vdr-1.5.16-dvbs2-other/device.h ./device.h
--- ../vdr-1.5.16-dvbs2-other/device.h	2008-02-24 19:14:45.000000000 +0100
+++ ./device.h	2008-02-24 20:53:36.000000000 +0100
@@ -23,6 +23,7 @@ 
 #include "spu.h"
 #include "thread.h"
 #include "tools.h"
+#include <linux/dvb/frontend.h>
 
 #define MAXDEVICES         16 // the maximum number of devices in the system
 #define MAXPIDHANDLES      64 // the maximum number of different PIDs per device
@@ -203,6 +204,7 @@  public:
 
 protected:
   static int currentChannel;
+  bool SwitchChannel(const cChannel *Channel, bool LiveView, cDevice *SpecificSourceDevice);
 public:
   virtual bool ProvidesSource(int Source) const;
          ///< Returns true if this device can provide the given source.
@@ -243,12 +245,16 @@  public:
   bool SwitchChannel(const cChannel *Channel, bool LiveView);
          ///< Switches the device to the given Channel, initiating transfer mode
          ///< if necessary.
+  bool SwitchChannel(const cChannel *Channel, cDevice *SpecificSourceDevice);
+         ///< Switches the device to the given Channel for live view, initiating
+         ///< transfer mode if necessary. SpecificSourceDevice will be used to
+         ///< provide the channel.
   static bool SwitchChannel(int Direction);
          ///< Switches the primary device to the next available channel in the given
          ///< Direction (only the sign of Direction is evaluated, positive values
          ///< switch to higher channel numbers).
 private:
-  eSetChannelResult SetChannel(const cChannel *Channel, bool LiveView);
+  eSetChannelResult SetChannel(const cChannel *Channel, bool LiveView, cDevice *SpecificSourceDevice = NULL);
          ///< Sets the device to the given channel (general setup).
 protected:
   virtual bool SetChannelDevice(const cChannel *Channel, bool LiveView);
@@ -271,6 +277,7 @@  public:
   virtual bool HasProgramme(void);
          ///< Returns true if the device is currently showing any programme to
          ///< the user, either through replaying or live.
+  virtual bool SendDiseqcCmd(dvb_diseqc_master_cmd cmd) {return false;}
 
 // PID handle facilities
 
diff -Nurp ../vdr-1.5.16-dvbs2-other/dvbdevice.c ./dvbdevice.c
--- ../vdr-1.5.16-dvbs2-other/dvbdevice.c	2008-02-24 19:14:45.000000000 +0100
+++ ./dvbdevice.c	2008-02-24 20:52:50.000000000 +0100
@@ -71,6 +71,7 @@  static int DvbOpen(const char *Name, int
 class cDvbTuner : public cThread {
 private:
   enum eTunerStatus { tsIdle, tsSet, tsTuned, tsLocked };
+  bool SendDiseqc;
   int fd_frontend;
   int cardIndex;
   int tuneTimeout;
@@ -83,6 +84,7 @@  private:
   cMutex mutex;
   cCondVar locked;
   cCondVar newSet;
+  dvb_diseqc_master_cmd diseqc_cmd;
   bool GetFrontendStatus(fe_status_t &Status, int TimeoutMs = 0);
   bool SetFrontend(void);
   virtual void Action(void);
@@ -91,12 +93,14 @@  public:
   virtual ~cDvbTuner();
   bool IsTunedTo(const cChannel *Channel) const;
   void Set(const cChannel *Channel, bool Tune);
+  bool SendDiseqcCmd(dvb_diseqc_master_cmd cmd);
   bool Locked(int TimeoutMs = 0);
   };
 
 cDvbTuner::cDvbTuner(int Fd_Frontend, int CardIndex, dvbfe_delsys FrontendType)
 {
   fd_frontend = Fd_Frontend;
+  SendDiseqc = false;
   cardIndex = CardIndex;
   frontendType = FrontendType;
   tuneTimeout = 0;
@@ -164,6 +168,17 @@  bool cDvbTuner::Locked(int TimeoutMs)
   return tunerStatus >= tsLocked;
 }
 
+bool cDvbTuner::SendDiseqcCmd(dvb_diseqc_master_cmd cmd)
+{
+  cMutexLock MutexLock(&mutex);
+  if (!(frontendType & (DVBFE_DELSYS_DVBS | DVBFE_DELSYS_DVBS2)) || SendDiseqc)
+    return false;
+  diseqc_cmd=cmd;
+  SendDiseqc=true;
+  newSet.Broadcast();
+  return true;
+}
+
 bool cDvbTuner::GetFrontendStatus(fe_status_t &Status, int TimeoutMs)
 {
   if (TimeoutMs) {
@@ -328,6 +343,10 @@  void cDvbTuner::Action(void)
         if (GetFrontendStatus(NewStatus, 10))
            Status = NewStatus;
         cMutexLock MutexLock(&mutex);
+        if (SendDiseqc) {
+           CHECK(ioctl(fd_frontend, FE_DISEQC_SEND_MASTER_CMD, &diseqc_cmd));
+           SendDiseqc=false;
+           }
         switch (tunerStatus) {
           case tsIdle:
                break;
@@ -938,6 +957,11 @@  bool cDvbDevice::HasLock(int TimeoutMs)
   return dvbTuner ? dvbTuner->Locked(TimeoutMs) : false;
 }
 
+bool cDvbDevice::SendDiseqcCmd(dvb_diseqc_master_cmd cmd)
+{
+  return dvbTuner->SendDiseqcCmd(cmd);
+}
+
 int cDvbDevice::GetAudioChannelDevice(void)
 {
   if (HasDecoder()) {
diff -Nurp ../vdr-1.5.16-dvbs2-other/dvbdevice.h ./dvbdevice.h
--- ../vdr-1.5.16-dvbs2-other/dvbdevice.h	2008-02-24 19:14:45.000000000 +0100
+++ ./dvbdevice.h	2008-02-24 20:52:50.000000000 +0100
@@ -73,6 +73,7 @@  protected:
   virtual bool SetChannelDevice(const cChannel *Channel, bool LiveView);
 public:
   virtual bool HasLock(int TimeoutMs = 0);
+  virtual bool SendDiseqcCmd(dvb_diseqc_master_cmd cmd);
 
 // PID handle facilities