Update httpstream
[vuplus_dvbapp] / lib / dvb / frontend.cpp
old mode 100644 (file)
new mode 100755 (executable)
index eea5d97..a183e37
@@ -1,3 +1,5 @@
+#include <linux/dvb/version.h>
+
 #include <lib/dvb/dvb.h>
 #include <lib/dvb/frontendparms.h>
 #include <lib/base/eerror.h>
@@ -397,7 +399,6 @@ RESULT eDVBFrontendParameters::calculateDifference(const iDVBFrontendParameters
                eDVBFrontendParametersTerrestrial oterrestrial;
                if (parm->getDVBT(oterrestrial))
                        return -2;
-
                if (exact && oterrestrial.bandwidth != terrestrial.bandwidth &&
                        oterrestrial.bandwidth != eDVBFrontendParametersTerrestrial::Bandwidth_Auto &&
                        terrestrial.bandwidth != eDVBFrontendParametersTerrestrial::Bandwidth_Auto)
@@ -426,6 +427,11 @@ RESULT eDVBFrontendParameters::calculateDifference(const iDVBFrontendParameters
                        oterrestrial.code_rate_HP != eDVBFrontendParametersTerrestrial::FEC_Auto &&
                        terrestrial.code_rate_HP != eDVBFrontendParametersTerrestrial::FEC_Auto)
                        diff = 1 << 30;
+               else if (oterrestrial.system != terrestrial.system)
+                       diff = 1 << 30;
+               else if (oterrestrial.system == terrestrial.System_DVB_T2 &&
+                       oterrestrial.plpid != terrestrial.plpid)
+                       diff = 1 << 30;
                else
                        diff = abs(terrestrial.frequency - oterrestrial.frequency) / 1000;
                return 0;
@@ -492,6 +498,8 @@ RESULT eDVBFrontendParameters::calcLockTimeout(unsigned int &timeout) const
 DEFINE_REF(eDVBFrontend);
 
 int eDVBFrontend::PriorityOrder=0;
+int eDVBFrontend::PreferredFrontendIndex=-1;
+
 
 eDVBFrontend::eDVBFrontend(int adap, int fe, int &ok, bool simulate, eDVBFrontend *simulate_fe)
        :m_simulate(simulate), m_enabled(false), m_type(-1), m_simulate_fe(simulate_fe), m_dvbid(fe), m_slotid(fe)
@@ -778,7 +786,7 @@ void eDVBFrontend::timeout()
        m_tuning = 0;
        if (m_state == stateTuning)
        {
-#ifdef BUILD_VUPLUS /* ikseong  */
+#ifdef BUILD_VUPLUS
                eDVBFrontend *sec_fe = this;
                sec_fe->m_data[CSW] = sec_fe->m_data[UCSW] = sec_fe->m_data[TONEBURST] = -1; // reset diseqc
 #endif
@@ -1239,7 +1247,7 @@ static void fillDictWithTerrestrialData(ePyObject dict, struct dtv_property *p)
                case SYS_DVBT: tmp = eDVBFrontendParametersTerrestrial::System_DVB_T; break;
                case SYS_DVBT2:
                {
-#ifdef DTV_DVBT2_PLP_ID
+#if DVB_API_VERSION > 5 || DVB_API_VERSION == 5 && DVB_API_VERSION_MINOR >= 3
                        tmp = p[10].u.data;
                        PutToDict(dict, "plp_id", tmp);
 #endif
@@ -1624,7 +1632,10 @@ void eDVBFrontend::getTransponderData(ePyObject dest, bool original)
                                p[7].cmd = DTV_GUARD_INTERVAL;
                                p[8].cmd = DTV_HIERARCHY;
                                p[9].cmd = DTV_INVERSION;
-#ifdef DTV_DVBT2_PLP_ID
+#if DVB_API_VERSION > 5 || DVB_API_VERSION == 5 && DVB_API_VERSION_MINOR >= 9
+                               p[10].cmd = DTV_STREAM_ID;
+                               cmdseq.num = 11;
+#elif DVB_API_VERSION > 5 || DVB_API_VERSION == 5 && DVB_API_VERSION_MINOR >= 3
                                p[10].cmd = DTV_DVBT2_PLP_ID;
                                cmdseq.num = 11;
 #else
@@ -2258,17 +2269,22 @@ void eDVBFrontend::setFrontend(bool recvEvents)
                }
                else if (m_type == iDVBFrontend::feCable)
                {
-                       struct dtv_property p[7];
+                       struct dtv_property p[8];
                        struct dtv_properties cmdseq;
                        cmdseq.props = p;
                        p[0].cmd = DTV_CLEAR;
-                       p[1].cmd = DTV_FREQUENCY,       p[1].u.data = parm_frequency;
-                       p[2].cmd = DTV_MODULATION,      p[2].u.data = parm_u_qam_modulation;
-                       p[3].cmd = DTV_SYMBOL_RATE,     p[3].u.data = parm_u_qam_symbol_rate;
-                       p[4].cmd = DTV_INNER_FEC,       p[4].u.data = parm_u_qam_fec_inner;
-                       p[5].cmd = DTV_INVERSION,       p[5].u.data = parm_inversion;
-                       p[6].cmd = DTV_TUNE;
-                       cmdseq.num = 7;
+#if DVB_API_VERSION > 5 || DVB_API_VERSION == 5 && DVB_API_VERSION_MINOR >= 6
+                       p[1].cmd = DTV_DELIVERY_SYSTEM, p[1].u.data = SYS_DVBC_ANNEX_A;
+#else
+                       p[1].cmd = DTV_DELIVERY_SYSTEM, p[1].u.data = SYS_DVBC_ANNEX_AC;
+#endif
+                       p[2].cmd = DTV_FREQUENCY,       p[2].u.data = parm_frequency;
+                       p[3].cmd = DTV_MODULATION,      p[3].u.data = parm_u_qam_modulation;
+                       p[4].cmd = DTV_SYMBOL_RATE,     p[4].u.data = parm_u_qam_symbol_rate;
+                       p[5].cmd = DTV_INNER_FEC,       p[5].u.data = parm_u_qam_fec_inner;
+                       p[6].cmd = DTV_INVERSION,       p[6].u.data = parm_inversion;
+                       p[7].cmd = DTV_TUNE;
+                       cmdseq.num = 8;
                        if (ioctl(m_fd, FE_SET_PROPERTY, &cmdseq) == -1)
                        {
                                perror("FE_SET_PROPERTY failed");
@@ -2311,7 +2327,9 @@ void eDVBFrontend::setFrontend(bool recvEvents)
                        p[cmdseq.num].cmd = DTV_HIERARCHY,      p[cmdseq.num].u.data = parm_u_ofdm_hierarchy_information, cmdseq.num++;
                        p[cmdseq.num].cmd = DTV_BANDWIDTH_HZ,   p[cmdseq.num].u.data = bandwidth, cmdseq.num++;
                        p[cmdseq.num].cmd = DTV_INVERSION,      p[cmdseq.num].u.data = parm_inversion, cmdseq.num++;
-#ifdef DTV_DVBT2_PLP_ID
+#if DVB_API_VERSION > 5 || DVB_API_VERSION == 5 && DVB_API_VERSION_MINOR >= 9
+                       p[cmdseq.num].cmd = DTV_STREAM_ID       ,       p[cmdseq.num].u.data = oparm.ter.plpid, cmdseq.num++;
+#elif DVB_API_VERSION > 5 || DVB_API_VERSION == 5 && DVB_API_VERSION_MINOR >= 3
                        p[cmdseq.num].cmd = DTV_DVBT2_PLP_ID    ,       p[cmdseq.num].u.data = oparm.ter.plpid, cmdseq.num++;
 #endif
                        p[cmdseq.num].cmd = DTV_TUNE, cmdseq.num++;
@@ -2749,7 +2767,7 @@ RESULT eDVBFrontend::prepare_terrestrial(const eDVBFrontendParametersTerrestrial
                parm_inversion = INVERSION_AUTO;
                break;
        }
-       eDebug("tuning to %d khz, bandwidth %d, crl %d, crh %d, modulation %d, tm %d, guard %d, hierarchy %d, inversion %d",
+       eDebug("tuning to %d khz, bandwidth %d, crl %d, crh %d, modulation %d, tm %d, guard %d, hierarchy %d, inversion %d, system %d, plpid %d",
                parm_frequency/1000,
                parm_u_ofdm_bandwidth,
                parm_u_ofdm_code_rate_LP,
@@ -2758,7 +2776,9 @@ RESULT eDVBFrontend::prepare_terrestrial(const eDVBFrontendParametersTerrestrial
                parm_u_ofdm_transmission_mode,
                parm_u_ofdm_guard_interval,
                parm_u_ofdm_hierarchy_information,
-               parm_inversion);
+               parm_inversion,
+               feparm.system,
+               feparm.plpid);
        oparm.ter = feparm;
        return 0;
 }
@@ -3075,40 +3095,67 @@ RESULT eDVBFrontend::setData(int num, long val)
 int eDVBFrontend::isCompatibleWith(ePtr<iDVBFrontendParameters> &feparm)
 {
        int type;
+       int score = 0;
+       bool preferred = (eDVBFrontend::getPreferredFrontend() >= 0 && m_slotid == eDVBFrontend::getPreferredFrontend());
+
        if (feparm->getSystem(type) || type != m_type || !m_enabled)
                return 0;
+
        if (m_type == eDVBFrontend::feSatellite)
        {
-               ASSERT(m_sec);
                eDVBFrontendParametersSatellite sat_parm;
-               int ret = feparm->getDVBS(sat_parm);
-               ASSERT(!ret);
+               if (feparm->getDVBS(sat_parm) < 0)
+               {
+                       return 0;
+               }
                if (sat_parm.system == eDVBFrontendParametersSatellite::System_DVB_S2 && !m_can_handle_dvbs2)
+               {
                        return 0;
-               ret = m_sec->canTune(sat_parm, this, 1 << m_slotid);
-               if (ret > 1 && sat_parm.system == eDVBFrontendParametersSatellite::System_DVB_S && m_can_handle_dvbs2)
-                       ret -= 1;
-               return ret;
+               }
+               score = m_sec ? m_sec->canTune(sat_parm, this, 1 << m_slotid) : 0;
+               if (score > 1 && sat_parm.system == eDVBFrontendParametersSatellite::System_DVB_S && m_can_handle_dvbs2)
+               {
+                       /* prefer to use a S tuner, try to keep S2 free for S2 transponders */
+                       score--;
+               }
        }
+
        else if (m_type == eDVBFrontend::feCable)
-               return 2;  // more prio for cable frontends
+       {
+               eDVBFrontendParametersCable cab_parm;
+               if (feparm->getDVBC(cab_parm) < 0)
+               {
+                       return 0;
+               }
+               score = 2;
+       }
+
        else if (m_type == eDVBFrontend::feTerrestrial)
        {
                eDVBFrontendParametersTerrestrial ter_parm;
-               if ( feparm->getDVBT(ter_parm) )
+               if (feparm->getDVBT(ter_parm) < 0)
                {
                        return 0;
                }
-               if (ter_parm.system == eDVBFrontendParametersTerrestrial::System_DVB_T2)
+               if (ter_parm.system == eDVBFrontendParametersTerrestrial::System_DVB_T2 && !m_can_handle_dvbt2)
                {
-                       return m_can_handle_dvbt2 ? 1 : 0;
+                       return 0;
                }
-               else // DVB-T
+               score = 2;
+               if (ter_parm.system == eDVBFrontendParametersTerrestrial::System_DVB_T && m_can_handle_dvbt2)
                {
-                       return m_can_handle_dvbt2 ? 1 : 2;
+                       /* prefer to use a T tuner, try to keep T2 free for T2 transponders */
+                       score--;
                }
        }
-       return 0;
+
+       if (score && preferred)
+       {
+               /* make 'sure' we always prefer this frontend */
+               score += 100000;
+       }
+
+       return score;
 }
 
 bool eDVBFrontend::setSlotInfo(ePyObject obj)