[ANNOUNCE] H.264 updates for VDR-1.5.9

Message ID 46D86B37.3020701@gmx.de
State New
Headers

Commit Message

Reinhard Nissl Aug. 31, 2007, 7:25 p.m. UTC
  Hi,

Petri Hintukainen wrote:

>> But I don't understand why streamdev still delivers a decrypted video
>> stream in that case. Can it be that the client asks streamdev to filter
>> certain TS packets and therefore uses the correct VPID?
> 
> Yes. In http streaming mode streamdev parses PIDs directly from PMT and
> does not use VDR channel data. But the VDR<->VDR streaming mode probably
> does not work if PIDs are not "real" ones.

Please try the attached patch which adds VPID clipping to some locations.

Bye.
  

Patch

--- ../vdr-1.5.9-orig/ci.c	2007-04-30 15:02:49.000000000 +0200
+++ ci.c	2007-08-31 21:08:30.000000000 +0200
@@ -1880,7 +1880,7 @@  void cCamSlot::AddChannel(const cChannel
   source = Channel->Source();
   transponder = Channel->Transponder();
   if (Channel->Ca() >= CA_ENCRYPTED_MIN) {
-     AddPid(Channel->Sid(), Channel->Vpid(), STREAM_TYPE_VIDEO);
+     AddPid(Channel->Sid(), VPID_FROM_ANY(Channel->Vpid()), STREAM_TYPE_VIDEO);
      for (const int *Apid = Channel->Apids(); *Apid; Apid++)
          AddPid(Channel->Sid(), *Apid, STREAM_TYPE_AUDIO);
      for (const int *Dpid = Channel->Dpids(); *Dpid; Dpid++)
@@ -1901,7 +1901,7 @@  bool cCamSlot::CanDecrypt(const cChannel
   if (cas && cas->RepliesToQuery()) {
      cCiCaPmt CaPmt(CPCI_QUERY, Channel->Source(), Channel->Transponder(), Channel->Sid(), GetCaSystemIds());
      CaPmt.SetListManagement(CPLM_ADD); // WORKAROUND: CPLM_ONLY doesn't work with Alphacrypt 3.09 (deletes existing CA_PMTs)
-     CaPmt.AddPid(Channel->Vpid(), STREAM_TYPE_VIDEO);
+     CaPmt.AddPid(VPID_FROM_ANY(Channel->Vpid()), STREAM_TYPE_VIDEO);
      for (const int *Apid = Channel->Apids(); *Apid; Apid++)
          CaPmt.AddPid(*Apid, STREAM_TYPE_AUDIO);
      for (const int *Dpid = Channel->Dpids(); *Dpid; Dpid++)
--- ../vdr-1.5.9-orig/dvbdevice.c	2007-08-17 15:37:56.000000000 +0200
+++ dvbdevice.c	2007-08-31 21:20:22.000000000 +0200
@@ -76,7 +76,7 @@  private:
   int tuneTimeout;
   int lockTimeout;
   time_t lastTimeoutReport;
-  fe_type_t frontendType;
+  dvbfe_delsys frontendType;
   cChannel channel;
   const char *diseqcCommands;
   eTunerStatus tunerStatus;
@@ -87,14 +87,14 @@  private:
   bool SetFrontend(void);
   virtual void Action(void);
 public:
-  cDvbTuner(int Fd_Frontend, int CardIndex, fe_type_t FrontendType);
+  cDvbTuner(int Fd_Frontend, int CardIndex, dvbfe_delsys FrontendType);
   virtual ~cDvbTuner();
   bool IsTunedTo(const cChannel *Channel) const;
   void Set(const cChannel *Channel, bool Tune);
   bool Locked(int TimeoutMs = 0);
   };
 
-cDvbTuner::cDvbTuner(int Fd_Frontend, int CardIndex, fe_type_t FrontendType)
+cDvbTuner::cDvbTuner(int Fd_Frontend, int CardIndex, dvbfe_delsys FrontendType)
 {
   fd_frontend = Fd_Frontend;
   cardIndex = CardIndex;
@@ -104,7 +104,7 @@  cDvbTuner::cDvbTuner(int Fd_Frontend, in
   lastTimeoutReport = 0;
   diseqcCommands = NULL;
   tunerStatus = tsIdle;
-  if (frontendType == FE_QPSK)
+  if (frontendType & (DVBFE_DELSYS_DVBS | DVBFE_DELSYS_DVBS2))
      CHECK(ioctl(fd_frontend, FE_SET_VOLTAGE, SEC_VOLTAGE_13)); // must explicitly turn on LNB power
   SetDescription("tuner on device %d", cardIndex + 1);
   Start();
@@ -173,114 +173,165 @@  static unsigned int FrequencyToHz(unsign
 
 bool cDvbTuner::SetFrontend(void)
 {
-  dvb_frontend_parameters Frontend;
-
+  dvbfe_params Frontend;
   memset(&Frontend, 0, sizeof(Frontend));
 
-  switch (frontendType) {
-    case FE_QPSK: { // DVB-S
-
-         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::daCodes: {
-                             int n = 0;
-                             uchar *codes = diseqc->Codes(n);
-                             if (codes) {
-                                struct dvb_diseqc_master_cmd cmd;
-                                memcpy(cmd.msg, codes, min(n, int(sizeof(cmd.msg))));
-                                cmd.msg_len = n;
-                                CHECK(ioctl(fd_frontend, FE_DISEQC_SEND_MASTER_CMD, &cmd));
-                                }
-                             }
-                             break;
-                        }
-                      }
-                  diseqcCommands = diseqc->Commands();
+  if (frontendType & (DVBFE_DELSYS_DVBS | DVBFE_DELSYS_DVBS2)) { // DVB-S
+     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)) {
+fprintf(stderr, "DiSEqC: %s\n", diseqc->Commands());
+              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::daCodes: {
+                         int n = 0;
+                         uchar *codes = diseqc->Codes(n);
+                         if (codes) {
+                            struct dvb_diseqc_master_cmd cmd;
+                            memcpy(cmd.msg, codes, min(n, int(sizeof(cmd.msg))));
+                            cmd.msg_len = n;
+                            CHECK(ioctl(fd_frontend, FE_DISEQC_SEND_MASTER_CMD, &cmd));
+                            }
+                         }
+                         break;
+                    }
                   }
-               frequency -= diseqc->Lof();
-               }
-            else {
-               esyslog("ERROR: no DiSEqC parameters found for channel %d", channel.Number());
-               return false;
-               }
-            }
-         else {
-            int tone = SEC_TONE_OFF;
-
-            if (frequency < (unsigned int)Setup.LnbSLOF) {
-               frequency -= Setup.LnbFrequLo;
-               tone = SEC_TONE_OFF;
-               }
-            else {
-               frequency -= Setup.LnbFrequHi;
-               tone = SEC_TONE_ON;
-               }
-            int volt = (channel.Polarization() == 'v' || channel.Polarization() == 'V' || channel.Polarization() == 'r' || channel.Polarization() == 'R') ? SEC_VOLTAGE_13 : SEC_VOLTAGE_18;
-            CHECK(ioctl(fd_frontend, FE_SET_VOLTAGE, volt));
-            CHECK(ioctl(fd_frontend, FE_SET_TONE, tone));
-            }
-
-         frequency = abs(frequency); // Allow for C-band, where the frequency is less than the LOF
-         Frontend.frequency = frequency * 1000UL;
-         Frontend.inversion = fe_spectral_inversion_t(channel.Inversion());
-         Frontend.u.qpsk.symbol_rate = channel.Srate() * 1000UL;
-         Frontend.u.qpsk.fec_inner = fe_code_rate_t(channel.CoderateH());
-
-         tuneTimeout = DVBS_TUNE_TIMEOUT;
-         lockTimeout = DVBS_LOCK_TIMEOUT;
-         }
-         break;
-    case FE_QAM: { // DVB-C
-
-         // Frequency and symbol rate:
-
-         Frontend.frequency = FrequencyToHz(channel.Frequency());
-         Frontend.inversion = fe_spectral_inversion_t(channel.Inversion());
-         Frontend.u.qam.symbol_rate = channel.Srate() * 1000UL;
-         Frontend.u.qam.fec_inner = fe_code_rate_t(channel.CoderateH());
-         Frontend.u.qam.modulation = fe_modulation_t(channel.Modulation());
-
-         tuneTimeout = DVBC_TUNE_TIMEOUT;
-         lockTimeout = DVBC_LOCK_TIMEOUT;
-         }
-         break;
-    case FE_OFDM: { // DVB-T
-
-         // Frequency and OFDM paramaters:
-
-         Frontend.frequency = FrequencyToHz(channel.Frequency());
-         Frontend.inversion = fe_spectral_inversion_t(channel.Inversion());
-         Frontend.u.ofdm.bandwidth = fe_bandwidth_t(channel.Bandwidth());
-         Frontend.u.ofdm.code_rate_HP = fe_code_rate_t(channel.CoderateH());
-         Frontend.u.ofdm.code_rate_LP = fe_code_rate_t(channel.CoderateL());
-         Frontend.u.ofdm.constellation = fe_modulation_t(channel.Modulation());
-         Frontend.u.ofdm.transmission_mode = fe_transmit_mode_t(channel.Transmission());
-         Frontend.u.ofdm.guard_interval = fe_guard_interval_t(channel.Guard());
-         Frontend.u.ofdm.hierarchy_information = fe_hierarchy_t(channel.Hierarchy());
-
-         tuneTimeout = DVBT_TUNE_TIMEOUT;
-         lockTimeout = DVBT_LOCK_TIMEOUT;
-         }
-         break;
-    default:
-         esyslog("ERROR: attempt to set channel with unknown DVB frontend type");
-         return false;
-    }
-  if (ioctl(fd_frontend, FE_SET_FRONTEND, &Frontend) < 0) {
+              diseqcCommands = diseqc->Commands();
+              }
+           frequency -= diseqc->Lof();
+           }
+        else {
+           esyslog("ERROR: no DiSEqC parameters found for channel %d", channel.Number());
+           return false;
+           }
+        }
+     else {
+        int tone = SEC_TONE_OFF;
+        if (frequency < (unsigned int)Setup.LnbSLOF) {
+           frequency -= Setup.LnbFrequLo;
+           tone = SEC_TONE_OFF;
+           }
+        else {
+           frequency -= Setup.LnbFrequHi;
+           tone = SEC_TONE_ON;
+           }
+        int volt = (channel.Polarization() == 'v' || channel.Polarization() == 'V' || channel.Polarization() == 'r' || channel.Polarization() == 'R') ? SEC_VOLTAGE_13 : SEC_VOLTAGE_18;
+        CHECK(ioctl(fd_frontend, FE_SET_VOLTAGE, volt));
+        CHECK(ioctl(fd_frontend, FE_SET_TONE, tone));
+        }
+     frequency = abs(frequency); // Allow for C-band, where the frequency is less than the LOF
+     Frontend.frequency = frequency * 1000UL;
+     Frontend.inversion = fe_spectral_inversion_t(channel.Inversion());
+
+     dvbfe_info feinfo;
+     if (channel.ModulationSystem() == DVBFE_DELSYS_DVBS) {
+        dsyslog("set DVB-S");
+        feinfo.delivery = DVBFE_DELSYS_DVBS;
+        CHECK(ioctl(fd_frontend, DVBFE_GET_INFO, &feinfo)); //switch system
+
+        Frontend.delivery = DVBFE_DELSYS_DVBS;
+        Frontend.inversion = fe_spectral_inversion_t(channel.Inversion());
+        Frontend.delsys.dvbs.modulation = dvbfe_modulation(channel.Modulation());
+        Frontend.delsys.dvbs.symbol_rate = channel.Srate() * 1000UL;
+        Frontend.delsys.dvbs.fec = dvbfe_fec(channel.CoderateH());
+        }
+     else {
+        dsyslog("set DVB-S2");
+        feinfo.delivery = DVBFE_DELSYS_DVBS2;
+        CHECK(ioctl(fd_frontend, DVBFE_GET_INFO, &feinfo)); //switch system
+
+        Frontend.delivery = DVBFE_DELSYS_DVBS2;
+        Frontend.inversion = fe_spectral_inversion_t(channel.Inversion());
+        Frontend.delsys.dvbs2.modulation = dvbfe_modulation(channel.Modulation());
+        Frontend.delsys.dvbs2.symbol_rate = channel.Srate() * 1000UL;
+        Frontend.delsys.dvbs2.fec = dvbfe_fec(channel.CoderateH());
+        Frontend.delsys.dvbs2.rolloff = dvbfe_rolloff(channel.RollOff());
+        }
+     tuneTimeout = DVBS_TUNE_TIMEOUT;
+     lockTimeout = DVBS_LOCK_TIMEOUT;
+     }
+  else if (frontendType & DVBFE_DELSYS_DVBC) { // DVB-C
+     dvbfe_info feinfo;
+     feinfo.delivery = DVBFE_DELSYS_DVBC;
+     CHECK(ioctl(fd_frontend, DVBFE_GET_INFO, &feinfo)); //switch system
+
+     Frontend.delivery = DVBFE_DELSYS_DVBC;
+     Frontend.frequency = FrequencyToHz(channel.Frequency());
+     Frontend.inversion = fe_spectral_inversion_t(channel.Inversion());
+     Frontend.delsys.dvbc.symbol_rate = channel.Srate() * 1000UL;
+     Frontend.delsys.dvbc.fec = dvbfe_fec(channel.CoderateH());
+     Frontend.delsys.dvbc.modulation = dvbfe_modulation(channel.Modulation());
+
+     tuneTimeout = DVBC_TUNE_TIMEOUT;
+     lockTimeout = DVBC_LOCK_TIMEOUT;
+     }
+  else if (frontendType & DVBFE_DELSYS_DVBT) { // DVB-T
+     dvbfe_info feinfo;
+     feinfo.delivery = DVBFE_DELSYS_DVBT;
+     CHECK(ioctl(fd_frontend, DVBFE_GET_INFO, &feinfo)); //switch system
+
+     Frontend.delivery = DVBFE_DELSYS_DVBT;
+     Frontend.frequency = FrequencyToHz(channel.Frequency());
+     Frontend.inversion = fe_spectral_inversion_t(channel.Inversion());
+     Frontend.delsys.dvbt.bandwidth = dvbfe_bandwidth(channel.Bandwidth());
+     Frontend.delsys.dvbt.code_rate_HP = dvbfe_fec(channel.CoderateH());
+     Frontend.delsys.dvbt.code_rate_LP = dvbfe_fec(channel.CoderateL());
+     Frontend.delsys.dvbt.constellation = dvbfe_modulation(channel.Modulation());
+     Frontend.delsys.dvbt.transmission_mode = dvbfe_transmission_mode(channel.Transmission());
+     Frontend.delsys.dvbt.guard_interval = dvbfe_guard_interval(channel.Guard());
+     Frontend.delsys.dvbt.hierarchy = dvbfe_hierarchy(channel.Hierarchy());
+     Frontend.delsys.dvbt.alpha = dvbfe_alpha(channel.Alpha());
+     Frontend.delsys.dvbt.priority = dvbfe_stream_priority(channel.Priority());
+
+     tuneTimeout = DVBT_TUNE_TIMEOUT;
+     lockTimeout = DVBT_LOCK_TIMEOUT;
+     }
+/* XXX
+  else if (frontendType & DVBFE_DELSYS_DVBH) { // DVB-H
+     Frontend.delivery = DVBFE_DELSYS_DVBH;
+     Frontend.frequency = FrequencyToHz(channel.Frequency());
+     Frontend.inversion = fe_spectral_inversion_t(channel.Inversion());
+
+     Frontend.delsys.dvbh.bandwidth = dvbfe_bandwidth(channel.Bandwidth());
+     Frontend.delsys.dvbh.code_rate_HP = dvbfe_fec(channel.CoderateH());
+     Frontend.delsys.dvbh.code_rate_LP = dvbfe_fec(channel.CoderateL());
+     Frontend.delsys.dvbh.constellation = dvbfe_modulation(channel.Modulation());
+     Frontend.delsys.dvbh.transmission_mode = dvbfe_transmission_mode(channel.Transmission());
+     Frontend.delsys.dvbh.guard_interval = dvbfe_guard_interval(channel.Guard());
+     Frontend.delsys.dvbh.hierarchy = dvbfe_hierarchy(channel.Hierarchy());
+
+//     Frontend.delsys.dvbh.alpha = 0;       //XXX
+//     Frontend.delsys.dvbh.interleaver = 0; //XXX
+//     Frontend.delsys.dvbh.mpefec = 0;      //XXX
+//     Frontend.delsys.dvbh.timeslicing = 0; //XXX
+//     Frontend.delsys.dvbh.priority = 0;    //XXX
+     }
+  else if (frontendType & DVBFE_DELSYS_DSS) {  // DDS
+     Frontend.delivery = DVBFE_DELSYS_DSS;
+     Frontend.delsys.dss.modulation = DVBFE_MOD_QPSK; //XXX
+     Frontend.delsys.dss.symbol_rate = channel.Srate() * 1000UL;
+     Frontend.delsys.dss.fec = dvbfe_fec(channel.CoderateH());
+     }
+  else if (frontendType & DVBFE_DELSYS_ATSC) { // ATCS
+     Frontend.delivery = DVBFE_DELSYS_ATSC;
+     Frontend.delsys.atsc.modulation = DVBFE_MOD_QPSK; //XXX
+     }
+*/
+  else {
+     esyslog("ERROR: attempt to set channel with unknown DVB frontend type");
+     return false;
+     }
+  if (ioctl(fd_frontend, DVBFE_SET_PARAMS, &Frontend) < 0) {
      esyslog("ERROR: frontend %d: %m", cardIndex);
      return false;
      }
@@ -355,7 +406,7 @@  cDvbDevice::cDvbDevice(int n)
 {
   ciAdapter = NULL;
   dvbTuner = NULL;
-  frontendType = fe_type_t(-1); // don't know how else to initialize this - there is no FE_UNKNOWN
+  frontendType = DVBFE_DELSYS_DUMMY;
   spuDecoder = NULL;
   digitalAudio = false;
   playMode = pmNone;
@@ -417,11 +468,8 @@  cDvbDevice::cDvbDevice(int n)
   // We only check the devices that must be present - the others will be checked before accessing them://XXX
 
   if (fd_frontend >= 0) {
-     dvb_frontend_info feinfo;
-     if (ioctl(fd_frontend, FE_GET_INFO, &feinfo) >= 0) {
-        frontendType = feinfo.type;
+     if (ioctl(fd_frontend, DVBFE_GET_DELSYS, &frontendType) >= 0)
         dvbTuner = new cDvbTuner(fd_frontend, CardIndex(), frontendType);
-        }
      else
         LOG_ERROR;
      }
@@ -738,9 +786,9 @@  bool cDvbDevice::ProvidesSource(int Sour
 {
   int type = Source & cSource::st_Mask;
   return type == cSource::stNone
-      || type == cSource::stCable && frontendType == FE_QAM
-      || type == cSource::stSat   && frontendType == FE_QPSK
-      || type == cSource::stTerr  && frontendType == FE_OFDM;
+      || type == cSource::stCable && (frontendType & DVBFE_DELSYS_DVBC)
+      || type == cSource::stSat   && (frontendType & (DVBFE_DELSYS_DVBS | DVBFE_DELSYS_DVBS2))
+      || type == cSource::stTerr  && (frontendType & DVBFE_DELSYS_DVBT);
 }
 
 bool cDvbDevice::ProvidesTransponder(const cChannel *Channel) const
@@ -758,7 +806,7 @@  bool cDvbDevice::ProvidesChannel(const c
      result = hasPriority;
      if (Priority >= 0 && Receiving(true)) {
         if (dvbTuner->IsTunedTo(Channel)) {
-           if (Channel->Vpid() && !HasPid(Channel->Vpid()) || Channel->Apid(0) && !HasPid(Channel->Apid(0))) {
+           if (Channel->Vpid() && !HasPid(VPID_FROM_ANY(Channel->Vpid())) || Channel->Apid(0) && !HasPid(Channel->Apid(0))) {
 #ifdef DO_MULTIPLE_RECORDINGS
               if (CamSlot() && Channel->Ca() >= CA_ENCRYPTED_MIN) {
                  if (CamSlot()->CanDecrypt(Channel))
@@ -794,7 +842,7 @@  bool cDvbDevice::IsTunedToTransponder(co
 bool cDvbDevice::SetChannelDevice(const cChannel *Channel, bool LiveView)
 {
   int apid = Channel->Apid(0);
-  int vpid = Channel->Vpid();
+  int vpid = VPID_FROM_ANY(Channel->Vpid());
   int dpid = Channel->Dpid(0);
 
   bool DoTune = !dvbTuner->IsTunedTo(Channel);
@@ -855,7 +903,7 @@  bool cDvbDevice::SetChannelDevice(const 
      CHECK(ioctl(fd_audio, AUDIO_SET_AV_SYNC, true));
      }
   else if (StartTransferMode)
-     cControl::Launch(new cTransferControl(this, Channel->GetChannelID(), vpid, Channel->Apids(), Channel->Dpids(), Channel->Spids()));
+     cControl::Launch(new cTransferControl(this, Channel->GetChannelID(), Channel->Vpid(), Channel->Apids(), Channel->Dpids(), Channel->Spids()));
 
   return true;
 }