Merge branch 'master' into tmbinc/FixTimingBugs
[enigma2.git] / lib / service / servicedvb.cpp
index fb67787a42360318c8315b992b8865dc90238913..7e6c0337b5f5b046e605614c038fe6ea8459dc12 100644 (file)
@@ -31,8 +31,6 @@
 #error no byte order defined!
 #endif
 
-#define TSPATH "/media/hdd"
-
 class eStaticServiceDVBInformation: public iStaticServiceInformation
 {
        DECLARE_REF(eStaticServiceDVBInformation);
@@ -166,15 +164,22 @@ void PutSatelliteDataToDict(ePyObject &dict, eDVBFrontendParametersSatellite &fe
                default:
                case eDVBFrontendParametersSatellite::System::DVB_S: tmp="DVB-S"; break;
                case eDVBFrontendParametersSatellite::System::DVB_S2:
-                       switch(feparm.roll_off)
+                       switch(feparm.rolloff)
                        {
+                               default:
                                case eDVBFrontendParametersSatellite::RollOff::alpha_0_35: tmp="0.35"; break;
                                case eDVBFrontendParametersSatellite::RollOff::alpha_0_25: tmp="0.25"; break;
                                case eDVBFrontendParametersSatellite::RollOff::alpha_0_20: tmp="0.20"; break;
-                               default:
-                               case eDVBFrontendParametersSatellite::RollOff::alpha_auto: tmp="AUTO"; break;
                        }
                        PutToDict(dict, "roll off", tmp);
+                       switch(feparm.pilot)
+                       {
+                               case eDVBFrontendParametersSatellite::Pilot::On: tmp="ON"; break;
+                               case eDVBFrontendParametersSatellite::Pilot::Off: tmp="OFF"; break;
+                               default:
+                               case eDVBFrontendParametersSatellite::Pilot::Unknown: tmp="AUTO"; break;
+                       }
+                       PutToDict(dict, "pilot", tmp);
                        tmp="DVB-S2";
                        break;
        }
@@ -402,7 +407,7 @@ RESULT eStaticServiceDVBBouquetInformation::getName(const eServiceReference &ref
                return -1;
 }
 
-int eStaticServiceDVBBouquetInformation::isPlayable(const eServiceReference &ref, const eServiceReference &ignore)
+int eStaticServiceDVBBouquetInformation::isPlayable(const eServiceReference &ref, const eServiceReference &ignore, bool simulate)
 {
        if (ref.flags & eServiceReference::isGroup)
        {
@@ -443,7 +448,7 @@ int eStaticServiceDVBBouquetInformation::isPlayable(const eServiceReference &ref
                                { 2, 1, 3 }  // -T -S -C
                        };
                        ((const eServiceReferenceDVB&)*it).getChannelID(chid);
-                       int tmp=res->canAllocateChannel(chid, chid_ignore);
+                       int tmp=res->canAllocateChannel(chid, chid_ignore, simulate);
                        switch(tmp)
                        {
                                case 0:
@@ -1055,7 +1060,9 @@ eDVBServicePlay::eDVBServicePlay(const eServiceReference &ref, eDVBService *serv
        
        m_tune_state = -1;
 
-       CONNECT(m_subtitle_sync_timer.timeout, eDVBServicePlay::checkSubtitleTiming);
+       m_subtitle_sync_timer = eTimer::create(eApp);
+
+       CONNECT(m_subtitle_sync_timer->timeout, eDVBServicePlay::checkSubtitleTiming);
 }
 
 eDVBServicePlay::~eDVBServicePlay()
@@ -1100,6 +1107,7 @@ void eDVBServicePlay::serviceEvent(int event)
                        else
                                m_event_handler.start(m_demux, sid);
                }
+               m_event((iPlayableService*)this, evTunedIn);
                break;
        }
        case eDVBServicePMTHandler::eventNoResources:
@@ -1220,8 +1228,8 @@ RESULT eDVBServicePlay::stop()
                        {
                                int perc = play_position * 100LL / length;
                        
-                                       /* only store last play position when between 5% and 95% */
-                               if ((5 < perc) && (perc < 95))
+                                       /* only store last play position when between 1% and 99% */
+                               if ((1 < perc) && (perc < 99))
                                        m_cue_entries.insert(cueEntry(play_position, 3)); /* last play position */
                        }
                        m_cuesheet_changed = 1;
@@ -1273,6 +1281,7 @@ RESULT eDVBServicePlay::pause(ePtr<iPauseableService> &ptr)
 
 RESULT eDVBServicePlay::setSlowMotion(int ratio)
 {
+       eDebug("eDVBServicePlay::setSlowMotion(%d)", ratio);
        if (m_decoder)
                return m_decoder->setSlowMotion(ratio);
        else
@@ -1281,6 +1290,7 @@ RESULT eDVBServicePlay::setSlowMotion(int ratio)
 
 RESULT eDVBServicePlay::setFastForward(int ratio)
 {
+       eDebug("eDVBServicePlay::setFastForward(%d)", ratio);
        int skipmode, ffratio;
        
        if (ratio > 8)
@@ -1341,6 +1351,7 @@ RESULT eDVBServicePlay::getLength(pts_t &len)
 
 RESULT eDVBServicePlay::pause()
 {
+       eDebug("eDVBServicePlay::pause");
        if (!m_is_paused && m_decoder)
        {
                m_is_paused = 1;
@@ -1351,6 +1362,7 @@ RESULT eDVBServicePlay::pause()
 
 RESULT eDVBServicePlay::unpause()
 {
+       eDebug("eDVBServicePlay::unpause");
        if (m_is_paused && m_decoder)
        {
                m_is_paused = 0;
@@ -1446,12 +1458,6 @@ RESULT eDVBServicePlay::isCurrentlySeekable()
        return m_is_pvr || m_timeshift_active;
 }
 
-RESULT eDVBServicePlay::seekChapter(int chapter)
-{
-               /* seekChapter N/I. */
-       return -1;
-}
-
 RESULT eDVBServicePlay::frontendInfo(ePtr<iFrontendInformation> &ptr)
 {
        ptr = this;
@@ -1490,9 +1496,16 @@ RESULT eDVBServicePlay::timeshift(ePtr<iTimeshiftService> &ptr)
        {
                if (!m_timeshift_enabled)
                {
-                               /* we need enough diskspace */
+                       /* query config path */
+                       std::string tspath;
+                       if(ePythonConfigQuery::getConfigValue("config.usage.timeshift_path", tspath) == -1){
+                               eDebug("could not query ts path from config");
+                               return -4;
+                       }
+                       tspath.append("/");
+                       /* we need enough diskspace */
                        struct statfs fs;
-                       if (statfs(TSPATH "/.", &fs) < 0)
+                       if (statfs(tspath.c_str(), &fs) < 0)
                        {
                                eDebug("statfs failed!");
                                return -2;
@@ -1564,38 +1577,67 @@ RESULT eDVBServicePlay::getEvent(ePtr<eServiceEvent> &evt, int nownext)
        return m_event_handler.getEvent(evt, nownext);
 }
 
+static int readMpegProc(char *str, int decoder)
+{
+       int val = -1;
+       char tmp[64];
+       sprintf(tmp, "/proc/stb/vmpeg/%d/%s", decoder, str);
+       FILE *f = fopen(tmp, "r");
+       if (f)
+       {
+               fscanf(f, "%x", &val);
+               fclose(f);
+       }
+       return val;
+}
+
 int eDVBServicePlay::getInfo(int w)
 {
        eDVBServicePMTHandler::program program;
-       
+
        if (w == sCAIDs)
                return resIsPyObject;
 
        eDVBServicePMTHandler &h = m_timeshift_active ? m_service_handler_timeshift : m_service_handler;
-       
+
        int no_program_info = 0;
-       
+
        if (h.getProgramInfo(program))
                no_program_info = 1;
-       
+
        switch (w)
        {
 #if HAVE_DVB_API_VERSION >= 3
        case sVideoHeight:
-               if (m_videoEventData.type != iTSMPEGDecoder::videoEvent::eventUnknown)
+               if (m_videoEventData.type == iTSMPEGDecoder::videoEvent::eventSizeChanged)
                        return m_videoEventData.height;
-               return -1;
+               else
+                       return readMpegProc("yres", !m_is_primary);
        case sVideoWidth:
-               if (m_videoEventData.type != iTSMPEGDecoder::videoEvent::eventUnknown)
+               if (m_videoEventData.type == iTSMPEGDecoder::videoEvent::eventSizeChanged)
                        return m_videoEventData.width;
-               return -1;
+               else
+                       return readMpegProc("xres", !m_is_primary);
+       case sFrameRate:
+               if (m_videoEventData.type == iTSMPEGDecoder::videoEvent::eventFrameRateChanged)
+                       return m_videoEventData.framerate;
+               else
+                       return readMpegProc("framerate", !m_is_primary);
+       case sProgressive:
+               if (m_videoEventData.type == iTSMPEGDecoder::videoEvent::eventProgressiveChanged)
+                       return m_videoEventData.progressive;
+               return readMpegProc("progressive", !m_is_primary);
 #else
-#warning "FIXMEE implement sVideoHeight, sVideoWidth for old DVB API"
+#warning "FIXMEE implement sFrameRate, sProgressive, sVideoHeight, sVideoWidth for old DVB API"
 #endif
        case sAspect:
+       {
+               int val;
 #if HAVE_DVB_API_VERSION >= 3
-               if (m_videoEventData.type != iTSMPEGDecoder::videoEvent::eventUnknown)
+               if (m_videoEventData.type == iTSMPEGDecoder::videoEvent::eventSizeChanged)
                        return m_videoEventData.aspect == VIDEO_FORMAT_4_3 ? 1 : 3;
+               else if ((val=readMpegProc("aspect", !m_is_primary)) != -1)
+                       return val;
                else
 #else
 #warning "FIXMEE implement sAspect for old DVB API"
@@ -1640,6 +1682,7 @@ int eDVBServicePlay::getInfo(int w)
                        }
                }
                return -1;
+       }
        case sIsCrypted: if (no_program_info) return -1; return program.isCrypted();
        case sVideoPID: if (no_program_info) return -1; if (program.videoStreams.empty()) return -1; return program.videoStreams[0].pid;
        case sVideoType: if (no_program_info) return -1; if (program.videoStreams.empty()) return -1; return program.videoStreams[0].type;
@@ -2080,12 +2123,23 @@ RESULT eDVBServicePlay::startTimeshift()
        if (!m_record)
                return -3;
 
-       char templ[]=TSPATH "/timeshift.XXXXXX";
+       std::string tspath;
+       if(ePythonConfigQuery::getConfigValue("config.usage.timeshift_path", tspath) == -1){ 
+               eDebug("could not query ts path");
+               return -5;
+       }
+       tspath.append("/timeshift.XXXXXX");
+       char* templ;
+       templ = new char[tspath.length() + 1];
+       strcpy(templ, tspath.c_str());
+
        m_timeshift_fd = mkstemp(templ);
-       m_timeshift_file = templ;
-       
+       m_timeshift_file = std::string(templ);
+
        eDebug("recording to %s", templ);
-       
+
+       delete [] templ;
+
        if (m_timeshift_fd < 0)
        {
                m_record = 0;
@@ -2891,7 +2945,7 @@ void eDVBServicePlay::checkSubtitleTiming()
                } else
                {
                        eDebug("start subtitle delay %d", diff / 90);
-                       m_subtitle_sync_timer.start(diff / 90, 1);
+                       m_subtitle_sync_timer->start(diff / 90, 1);
                        break;
                }
        }
@@ -2948,8 +3002,20 @@ void eDVBServicePlay::setPCMDelay(int delay)
 
 void eDVBServicePlay::video_event(struct iTSMPEGDecoder::videoEvent event)
 {
-       memcpy(&m_videoEventData, &event, sizeof(iTSMPEGDecoder::videoEvent));
-       m_event((iPlayableService*)this, evVideoSizeChanged);
+       memcpy(&m_videoEventData, &event, sizeof(event));
+       switch(event.type) {
+               case iTSMPEGDecoder::videoEvent::eventSizeChanged:
+                       m_event((iPlayableService*)this, evVideoSizeChanged);
+                       break;
+               case iTSMPEGDecoder::videoEvent::eventFrameRateChanged:
+                       m_event((iPlayableService*)this, evVideoFramerateChanged);
+                       break;
+               case iTSMPEGDecoder::videoEvent::eventProgressiveChanged:
+                       m_event((iPlayableService*)this, evVideoProgressiveChanged);
+                       break;
+               default:
+                       break;
+       }
 }
 
 RESULT eDVBServicePlay::stream(ePtr<iStreamableService> &ptr)