Merge branch 'master' of git.opendreambox.org:/git/enigma2
authorFelix Domke <felix.domke@multimedia-labs.de>
Fri, 14 Aug 2009 11:23:54 +0000 (13:23 +0200)
committerFelix Domke <felix.domke@multimedia-labs.de>
Fri, 14 Aug 2009 11:23:54 +0000 (13:23 +0200)
12 files changed:
lib/dvb/frontend.cpp
lib/dvb/frontend.h
lib/dvb/pmt.cpp
lib/dvb/pmt.h
lib/dvb/radiotext.cpp
lib/dvb/radiotext.h
lib/dvb/sec.cpp
lib/dvb/subtitle.cpp
lib/python/Plugins/SystemPlugins/CrashlogAutoSubmit/plugin.py
lib/python/Plugins/SystemPlugins/NFIFlash/downloader.py
lib/python/Screens/Standby.py
lib/service/servicedvb.cpp

index e5e83b42cd477fdb0e775a866a0b0ed5cfc148ad..cfb881abb0c676d067a8d1c6af24fa6d67902287 100644 (file)
@@ -652,12 +652,6 @@ void eDVBFrontend::feEvent(int w)
                if (res && (errno == EAGAIN))
                        break;
 
-               if (res)
-               {
-                       eWarning("FE_GET_EVENT failed! %m");
-                       return;
-               }
-
                if (w < 0)
                        continue;
 
@@ -1432,14 +1426,18 @@ void eDVBFrontend::tuneLoop()  // called by m_tuneTimer
                                sec_fe->sendToneburst(m_sec_sequence.current()++->toneburst);
                                break;
                        case eSecCommand::SET_FRONTEND:
-                               eDebugNoSimulate("[SEC] setFrontend");
-                               setFrontend();
-                               ++m_sec_sequence.current();
+                       {
+                               int enableEvents = (m_sec_sequence.current()++)->val;
+                               eDebugNoSimulate("[SEC] setFrontend %d", enableEvents);
+                               setFrontend(enableEvents);
                                break;
+                       }
                        case eSecCommand::START_TUNE_TIMEOUT:
                        {
+                               int tuneTimeout = m_sec_sequence.current()->timeout;
+                               eDebugNoSimulate("[SEC] startTuneTimeout %d", tuneTimeout);
                                if (!m_simulate)
-                                       m_timeout->start(m_sec_sequence.current()->timeout, 1);
+                                       m_timeout->start(tuneTimeout, 1);
                                ++m_sec_sequence.current();
                                break;
                        }
@@ -1497,23 +1495,27 @@ void eDVBFrontend::tuneLoop()  // called by m_tuneTimer
                                int signal = 0;
                                int isLocked = readFrontendData(locked);
                                m_idleInputpower[0] = m_idleInputpower[1] = 0;
-                               if (isLocked && ((abs((signal = readFrontendData(signalQualitydB)) - cmd.lastSignal) < 50) || !cmd.lastSignal))
+                               --m_timeoutCount;
+                               if (!m_timeoutCount && m_retryCount > 0)
+                                       --m_retryCount;
+                               if (isLocked && ((abs((signal = readFrontendData(signalQualitydB)) - cmd.lastSignal) < 40) || !cmd.lastSignal))
                                {
                                        if (cmd.lastSignal)
                                                eDebugNoSimulate("[SEC] locked step %d ok (%d %d)", cmd.okcount, signal, cmd.lastSignal);
                                        else
                                        {
                                                eDebugNoSimulate("[SEC] locked step %d ok", cmd.okcount);
-                                               cmd.lastSignal = signal;
+                                               if (!cmd.okcount)
+                                                       cmd.lastSignal = signal;
                                        }
                                        ++cmd.okcount;
                                        if (cmd.okcount > 4)
                                        {
-                                               eDebugNoSimulate("ok > 4 .. goto %d\n",cmd.steps);
+                                               eDebugNoSimulate("ok > 4 .. goto %d\n", cmd.steps);
                                                setSecSequencePos(cmd.steps);
                                                m_state = stateLock;
                                                m_stateChanged(this);
-                                               feEvent(-1);
+                                               feEvent(-1); // flush events
                                                m_sn->start();
                                                break;
                                        }
@@ -1524,9 +1526,6 @@ void eDVBFrontend::tuneLoop()  // called by m_tuneTimer
                                                eDebugNoSimulate("[SEC] rotor locked step %d failed (oldSignal %d, curSignal %d)", cmd.okcount, signal, cmd.lastSignal);
                                        else
                                                eDebugNoSimulate("[SEC] rotor locked step %d failed (not locked)", cmd.okcount);
-                                       --m_timeoutCount;
-                                       if (!m_timeoutCount && m_retryCount > 0)
-                                               --m_retryCount;
                                        cmd.okcount=0;
                                        cmd.lastSignal=0;
                                }
@@ -1558,6 +1557,9 @@ void eDVBFrontend::tuneLoop()  // called by m_tuneTimer
                                }
                                int idleInputpower = m_idleInputpower[ (sec_fe_data[CUR_VOLTAGE]&1) ? 0 : 1];
                                const char *txt = cmd.direction ? "running" : "stopped";
+                               --m_timeoutCount;
+                               if (!m_timeoutCount && m_retryCount > 0)
+                                       --m_retryCount;
                                eDebugNoSimulate("[SEC] waiting for rotor %s %d, idle %d, delta %d",
                                        txt,
                                        m_runningInputpower,
@@ -1578,9 +1580,6 @@ void eDVBFrontend::tuneLoop()  // called by m_tuneTimer
                                else
                                {
                                        eDebugNoSimulate("[SEC] rotor not %s... reset counter.. increase timeout", txt);
-                                       --m_timeoutCount;
-                                       if (!m_timeoutCount && m_retryCount > 0)
-                                               --m_retryCount;
                                        cmd.okcount=0;
                                }
                                ++m_sec_sequence.current();
@@ -1696,13 +1695,14 @@ void eDVBFrontend::tuneLoop()  // called by m_tuneTimer
                tuneLoop();
 }
 
-void eDVBFrontend::setFrontend()
+void eDVBFrontend::setFrontend(bool recvEvents)
 {
        if (!m_simulate)
        {
                eDebug("setting frontend %d", m_dvbid);
-               m_sn->start();
-               feEvent(-1);
+               if (recvEvents)
+                       m_sn->start();
+               feEvent(-1); // flush events
                if (ioctl(m_fd, FE_SET_FRONTEND, &parm) == -1)
                {
                        perror("FE_SET_FRONTEND failed");
@@ -2141,7 +2141,7 @@ RESULT eDVBFrontend::tune(const iDVBFrontendParameters &where)
                        goto tune_error;
 
                m_sec_sequence.push_back( eSecCommand(eSecCommand::START_TUNE_TIMEOUT, timeout) );
-               m_sec_sequence.push_back( eSecCommand(eSecCommand::SET_FRONTEND) );
+               m_sec_sequence.push_back( eSecCommand(eSecCommand::SET_FRONTEND, 1) );
                break;
        }
        case feTerrestrial:
@@ -2166,7 +2166,7 @@ RESULT eDVBFrontend::tune(const iDVBFrontendParameters &where)
                        m_sec_sequence.push_back( eSecCommand(eSecCommand::SET_VOLTAGE, iDVBFrontend::voltage13) );
                else
                        m_sec_sequence.push_back( eSecCommand(eSecCommand::SET_VOLTAGE, iDVBFrontend::voltageOff) );
-               m_sec_sequence.push_back( eSecCommand(eSecCommand::SET_FRONTEND) );
+               m_sec_sequence.push_back( eSecCommand(eSecCommand::SET_FRONTEND, 1) );
 
                break;
        }
index b6e3b6a4299d734e7271604e206438cea0acd8fc..e1556bd99fccd5e655397b88c0aacc37f7ba47ad 100644 (file)
@@ -105,7 +105,7 @@ private:
        void feEvent(int);
        void timeout();
        void tuneLoop();  // called by m_tuneTimer
-       void setFrontend();
+       void setFrontend(bool recvEvents=true);
        bool setSecSequencePos(int steps);
        static int PriorityOrder;
 public:
index fb81fa4c3f45559892bb1b68d750a10b62d564f9..a4fa212d5cc2f3d32605e1fc206c0f65aa6bc4a9 100644 (file)
@@ -184,6 +184,8 @@ int eDVBServicePMTHandler::getProgramInfo(struct program &program)
 
        int first_ac3 = -1;
        program.defaultAudioStream = 0;
+       int rdsPid = -1;
+       audioStream *prev_audio = 0;
 
        if ( m_service && !m_service->cacheEmpty() )
        {
@@ -215,13 +217,15 @@ int eDVBServicePMTHandler::getProgramInfo(struct program &program)
                                for (es = pmt.getEsInfo()->begin(); es != pmt.getEsInfo()->end(); ++es)
                                {
                                        int isaudio = 0, isvideo = 0, issubtitle = 0, forced_video = 0, forced_audio = 0, isteletext = 0;
+                                       int streamtype = (*es)->getType();
                                        videoStream video;
                                        audioStream audio;
                                        audio.component_tag=video.component_tag=-1;
                                        video.type = videoStream::vtMPEG2;
                                        audio.type = audioStream::atMPEG;
+                                       audio.rdsPid = -1;
 
-                                       switch ((*es)->getType())
+                                       switch (streamtype)
                                        {
                                        case 0x1b: // AVC Video Stream (MPEG4 H264)
                                                video.type = videoStream::vtMPEG4_H264;
@@ -285,11 +289,14 @@ int eDVBServicePMTHandler::getProgramInfo(struct program &program)
                                                }
                                        case 0x06: // PES Private
                                        case 0xEA: // TS_PSI_ST_SMPTE_VC1
+                                       {
+                                               int num_descriptors = 0;
                                                for (DescriptorConstIterator desc = (*es)->getDescriptors()->begin();
                                                        desc != (*es)->getDescriptors()->end(); ++desc)
                                                {
                                                        uint8_t tag = (*desc)->getTag();
                                                        /* check descriptors to get the exakt stream type. */
+                                                       ++num_descriptors;
                                                        if (!forced_video && !forced_audio)
                                                        {
                                                                switch (tag)
@@ -458,6 +465,13 @@ int eDVBServicePMTHandler::getProgramInfo(struct program &program)
                                                                break;
                                                        }
                                                }
+                                               if (!num_descriptors && streamtype == 0x06 && prev_audio)
+                                               {
+                                                       prev_audio->rdsPid = (*es)->getPid();
+                                                       eDebug("Rds PID %04x detected ? ! ?", prev_audio->rdsPid);
+                                               }
+                                               prev_audio = 0;
+                                       }
                                        default:
                                                break;
                                        }
@@ -496,6 +510,7 @@ int eDVBServicePMTHandler::getProgramInfo(struct program &program)
                                                        first_ac3 = program.audioStreams.size();
 
                                                program.audioStreams.push_back(audio);
+                                               prev_audio = &program.audioStreams.back();
                                        }
                                        else
                                                continue;
@@ -548,6 +563,7 @@ int eDVBServicePMTHandler::getProgramInfo(struct program &program)
                        audioStream s;
                        s.type = audioStream::atAC3;
                        s.pid = cached_apid_ac3;
+                       s.rdsPid = -1;
                        program.audioStreams.push_back(s);
                        ++cnt;
                }
@@ -556,6 +572,7 @@ int eDVBServicePMTHandler::getProgramInfo(struct program &program)
                        audioStream s;
                        s.type = audioStream::atMPEG;
                        s.pid = cached_apid_mpeg;
+                       s.rdsPid = -1;
                        program.audioStreams.push_back(s);
                        ++cnt;
                }
index e27135e3c9968bd73cf1cb048485d1684bf034e6..a9ca23f246308b44d750fcaee304b7fa99d5dc2b 100644 (file)
@@ -141,7 +141,8 @@ public:
        
        struct audioStream
        {
-               int pid;
+               int pid,
+                   rdsPid; // hack for some radio services which transmit radiotext on different pid (i.e. harmony fm, HIT RADIO FFH, ...)
                enum { atMPEG, atAC3, atDTS, atAAC, atAACHE, atLPCM };
                int type; // mpeg2, ac3, dts, ...
                
@@ -188,7 +189,6 @@ public:
                int pmtPid;
                int textPid;
                bool isCrypted() { return !caids.empty(); }
-               
                PyObject *createPythonObject();
        };
 
index 9f8cf5f0dee2aa2b343097c71daadbf7846f300e..e9bdd63a860052f0261cdca9897355fe392ce7ed 100644 (file)
@@ -5,9 +5,9 @@
 
 DEFINE_REF(eDVBRdsDecoder);
 
-eDVBRdsDecoder::eDVBRdsDecoder(iDVBDemux *demux)
+eDVBRdsDecoder::eDVBRdsDecoder(iDVBDemux *demux, int type)
        :msgPtr(0), bsflag(0), qdar_pos(0), t_ptr(0), qdarmvi_show(0), state(0)
-       ,m_abortTimer(eTimer::create(eApp))
+       ,m_type(type), m_pid(-1), m_abortTimer(eTimer::create(eApp))
 {
        setStreamID(0xC0, 0xC0);
 
@@ -16,8 +16,10 @@ eDVBRdsDecoder::eDVBRdsDecoder(iDVBDemux *demux)
 
        if (demux->createPESReader(eApp, m_pes_reader))
                eDebug("failed to create PES reader!");
-       else
+       else if (type == 0)
                m_pes_reader->connectRead(slot(*this, &eDVBRdsDecoder::processData), m_read_connection);
+       else
+               m_pes_reader->connectRead(slot(*this, &eDVBRdsDecoder::gotAncillaryData), m_read_connection);
        CONNECT(m_abortTimer->timeout, eDVBRdsDecoder::abortNonAvail);
 }
 
@@ -196,7 +198,7 @@ void eDVBRdsDecoder::processPESPacket(__u8 *data, int len)
                        m_abortTimer->stop();
                        int ancillary_len = 1 + data[offs - 1];
                        offs -= ancillary_len;
-                       gotAncillaryData(data+offs, ancillary_len);
+                       gotAncillaryData(data+offs, ancillary_len-1);
                }
        }
 }
@@ -310,13 +312,19 @@ void eDVBRdsDecoder::process_qdar(unsigned char *buf)
        }
 }
 
-inline void eDVBRdsDecoder::gotAncillaryData(__u8 *buf, int len)
+void eDVBRdsDecoder::gotAncillaryData(const __u8 *buf, int len)
 {
-       int cnt=buf[--len];
-       while ( cnt-- > 0 )
+       if (len <= 0)
+               return;
+       int pos = m_type ? 0 : len-1;
+       while ( len )
        {
-               unsigned char c = buf[--len];
-       
+               unsigned char c = buf[pos];
+
+               pos += m_type ? 1 : -1;
+
+               --len;
+
                if (bsflag == 1) // byte stuffing
                {
                        bsflag=2;
@@ -638,8 +646,9 @@ std::string eDVBRdsDecoder::getRassPicture(int page, int subpage)
 int eDVBRdsDecoder::start(int pid)
 {
        int ret = -1;
-       if (m_pes_reader && !(ret = m_pes_reader->start(pid)))
+       if (m_pes_reader && !(ret = m_pes_reader->start(pid)) && m_type == 0)
                m_abortTimer->startLongTimer(20);
+       m_pid = pid;
        return ret;
 }
 
index ace7b6ece88f4dca670ad8732ce07ebd2d52a184..7a73eea3371afd3d08f3ac7af34a74bb9450373f 100644 (file)
@@ -18,9 +18,11 @@ class eDVBRdsDecoder: public iObject, public ePESParser, public Object
        unsigned char rass_picture_mask[5];  // 40 bits... (10 * 4 pictures)
        void addToPictureMask(int id);
        void removeFromPictureMask(int id);
+       int m_type;
+       int m_pid;
 public:
        enum { RadioTextChanged, RtpTextChanged, RassInteractivePicMaskChanged, RecvRassSlidePic };
-       eDVBRdsDecoder(iDVBDemux *demux);
+       eDVBRdsDecoder(iDVBDemux *demux, int type);
        ~eDVBRdsDecoder();
        int start(int pid);
        void connectEvent(const Slot1<void, int> &slot, ePtr<eConnection> &connection);
@@ -29,10 +31,11 @@ public:
        ePyObject getRassPictureMask();
        std::string getRassPicture(int page, int subpage);
        std::string getRassSlideshowPicture() { return "/tmp/RassLast.mvi"; }
+       int getPid() { return m_pid; }
 private:
        void abortNonAvail();
        void processPESPacket(__u8 *pkt, int len);
-       inline void gotAncillaryData(__u8 *data, int len);
+       void gotAncillaryData(const __u8 *data, int len);
        void process_qdar(unsigned char*);
        ePtr<iDVBPESReader> m_pes_reader;
        ePtr<eConnection> m_read_connection;
index 83092d8e8e5309f72f06626fd9ead9a45c7eabb3..71c8a19cfd10a3ed5874a13c8a4a46ecae79e667 100644 (file)
@@ -754,6 +754,7 @@ RESULT eDVBSatelliteEquipmentControl::prepare(iDVBFrontend &frontend, FRONTENDPA
                                                }
                                                if(lnb_param.SatCR_idx == -1)
                                                {
+                                                       int mrt = m_params[MOTOR_RUNNING_TIMEOUT]; // in seconds!
                                                        if ( rotor_param.m_inputpower_parameters.m_use )
                                                        { // use measure rotor input power to detect rotor state
                                                                bool turn_fast = need_turn_fast(rotor_param.m_inputpower_parameters.m_turning_speed);
@@ -800,7 +801,7 @@ RESULT eDVBSatelliteEquipmentControl::prepare(iDVBFrontend &frontend, FRONTENDPA
                                                                sec_sequence.push_back( eSecCommand(eSecCommand::SET_ROTOR_MOVING) );
                                                                if (turn_fast)
                                                                        sec_sequence.push_back( eSecCommand(eSecCommand::SET_VOLTAGE, VOLTAGE(18)) );
-                                                               sec_sequence.push_back( eSecCommand(eSecCommand::SET_TIMEOUT, m_params[MOTOR_RUNNING_TIMEOUT]*20) );  // 2 minutes running timeout
+                                                               sec_sequence.push_back( eSecCommand(eSecCommand::SET_TIMEOUT, mrt*20) );  // mrt is in seconds... our SLEEP time is 50ms.. so * 20
        // rotor running loop
                                                                sec_sequence.push_back( eSecCommand(eSecCommand::SLEEP, 50) );  // wait 50msec
                                                                sec_sequence.push_back( eSecCommand(eSecCommand::MEASURE_RUNNING_INPUTPOWER) );
@@ -815,6 +816,17 @@ RESULT eDVBSatelliteEquipmentControl::prepare(iDVBFrontend &frontend, FRONTENDPA
                                                        }
                                                        else
                                                        {  // use normal turning mode
+                                                               if (curRotorPos != -1)
+                                                               {               
+                                                                       mrt = abs(curRotorPos - sat.orbital_position);
+                                                                       if (mrt > 1800)
+                                                                               mrt = 3600 - mrt;
+                                                                       if (mrt % 10)
+                                                                               mrt += 10; // round a little bit
+                                                                       mrt *= 2000;  // (we assume a very slow rotor with just 0.5 degree per second here)
+                                                                       mrt /= 10000;
+                                                                       mrt += 3; // a little bit overhead
+                                                               }
                                                                doSetVoltageToneFrontend=false;
                                                                doSetFrontend=false;
                                                                eSecCommand::rotor cmd;
@@ -828,37 +840,40 @@ RESULT eDVBSatelliteEquipmentControl::prepare(iDVBFrontend &frontend, FRONTENDPA
                                                                sec_sequence.push_back( eSecCommand(eSecCommand::INVALIDATE_CURRENT_ROTORPARMS) );
                                                                sec_sequence.push_back( eSecCommand(eSecCommand::SET_ROTOR_MOVING) );
                                                                sec_sequence.push_back( eSecCommand(eSecCommand::SEND_DISEQC, diseqc) );
-       
+                                                               sec_sequence.push_back( eSecCommand(eSecCommand::SLEEP, 1000) ); // sleep one second before change voltage or tone
+
                                                                compare.voltage = voltage;
                                                                compare.steps = +3;
                                                                sec_sequence.push_back( eSecCommand(eSecCommand::IF_VOLTAGE_GOTO, compare) ); // correct final voltage?
                                                                sec_sequence.push_back( eSecCommand(eSecCommand::SLEEP, 2000) );  // wait 2 second before set high voltage
                                                                sec_sequence.push_back( eSecCommand(eSecCommand::SET_VOLTAGE, voltage) );
-       
+
                                                                compare.tone = tone;
                                                                sec_sequence.push_back( eSecCommand(eSecCommand::IF_TONE_GOTO, compare) );
                                                                sec_sequence.push_back( eSecCommand(eSecCommand::SET_TONE, tone) );
                                                                sec_sequence.push_back( eSecCommand(eSecCommand::SLEEP, m_params[DELAY_AFTER_FINAL_CONT_TONE_CHANGE]) );
-                                                               sec_sequence.push_back( eSecCommand(eSecCommand::SET_FRONTEND) );
+                                                               sec_sequence.push_back( eSecCommand(eSecCommand::SET_FRONTEND, 0) );
        
                                                                cmd.direction=1;  // check for running rotor
                                                                cmd.deltaA=0;
-                                                               cmd.steps=+3;
+                                                               cmd.steps = +3;
                                                                cmd.okcount=0;
-                                                               sec_sequence.push_back( eSecCommand(eSecCommand::SET_TIMEOUT, m_params[MOTOR_RUNNING_TIMEOUT]*4) );  // 2 minutes running timeout
+                                                               sec_sequence.push_back( eSecCommand(eSecCommand::SET_TIMEOUT, mrt*4) );  // mrt is in seconds... our SLEEP time is 250ms.. so * 4
                                                                sec_sequence.push_back( eSecCommand(eSecCommand::SLEEP, 250) );  // 250msec delay
                                                                sec_sequence.push_back( eSecCommand(eSecCommand::IF_TUNER_LOCKED_GOTO, cmd ) );
-                                                               sec_sequence.push_back( eSecCommand(eSecCommand::IF_TIMEOUT_GOTO, +3 ) ); 
+                                                               sec_sequence.push_back( eSecCommand(eSecCommand::IF_TIMEOUT_GOTO, +5 ) );
                                                                sec_sequence.push_back( eSecCommand(eSecCommand::GOTO, -3) );  // goto loop start
                                                                sec_sequence.push_back( eSecCommand(eSecCommand::UPDATE_CURRENT_ROTORPARAMS) );
                                                                sec_sequence.push_back( eSecCommand(eSecCommand::SET_ROTOR_STOPPED) );
-                                                               sec_sequence.push_back( eSecCommand(eSecCommand::GOTO, +3) );
-                                                               sec_sequence.push_back( eSecCommand(eSecCommand::SET_FRONTEND) );
-                                                               sec_sequence.push_back( eSecCommand(eSecCommand::GOTO, -4) );
+                                                               sec_sequence.push_back( eSecCommand(eSecCommand::GOTO, +4) );
+                                                               sec_sequence.push_back( eSecCommand(eSecCommand::START_TUNE_TIMEOUT, tunetimeout) );
+                                                               sec_sequence.push_back( eSecCommand(eSecCommand::SET_FRONTEND, 1) );
+                                                               sec_sequence.push_back( eSecCommand(eSecCommand::GOTO, -5) );
                                                        }
+                                                       eDebug("set rotor timeout to %d seconds", mrt);
+                                                       sec_fe->setData(eDVBFrontend::NEW_ROTOR_CMD, RotorCmd);
+                                                       sec_fe->setData(eDVBFrontend::NEW_ROTOR_POS, sat.orbital_position);
                                                }
-                                               sec_fe->setData(eDVBFrontend::NEW_ROTOR_CMD, RotorCmd);
-                                               sec_fe->setData(eDVBFrontend::NEW_ROTOR_POS, sat.orbital_position);
                                        }
                                }
                        }
@@ -919,7 +934,7 @@ RESULT eDVBSatelliteEquipmentControl::prepare(iDVBFrontend &frontend, FRONTENDPA
                        if (doSetFrontend)
                        {
                                sec_sequence.push_back( eSecCommand(eSecCommand::START_TUNE_TIMEOUT, tunetimeout) );
-                               sec_sequence.push_back( eSecCommand(eSecCommand::SET_FRONTEND) );
+                               sec_sequence.push_back( eSecCommand(eSecCommand::SET_FRONTEND, 1) );
                        }
 
                        sec_sequence.push_front( eSecCommand(eSecCommand::SET_POWER_LIMITING_MODE, eSecCommand::modeStatic) );
index 82cf002361dfca6c85701d7aa96779cd78cf11af..06bb266eb596b7c2a6ccaab4ac25cc7062956e9b 100644 (file)
@@ -82,7 +82,7 @@ static int map_4_to_8_bit_table[16];
 int eDVBSubtitleParser::subtitle_process_pixel_data(subtitle_region *region, subtitle_region_object *object, int *linenr, int *linep, __u8 *data)
 {
        int data_type = *data++;
-       static __u8 line[720];
+       static __u8 line[1920];
 
        bitstream bit;
        bit.size=0;
@@ -142,7 +142,7 @@ int eDVBSubtitleParser::subtitle_process_pixel_data(subtitle_region *region, sub
                                map_2_to_4_bit_table[col] :
                                region->depth == subtitle_region::bpp8 ?
                                map_2_to_8_bit_table[col] : col;
-                       while (len && ((*linep) < 720))
+                       while (len && ((*linep) < m_display_size.width()))
                        {
                                line[(*linep)++] = c;
                                len--;
@@ -197,7 +197,7 @@ int eDVBSubtitleParser::subtitle_process_pixel_data(subtitle_region *region, sub
                        }
                        uint8_t c = region->depth == subtitle_region::bpp8 ?
                                map_4_to_8_bit_table[col] : col;
-                       while (len && ((*linep) < 720))
+                       while (len && ((*linep) < m_display_size.width()))
                        {
                                line[(*linep)++] = c;
                                len--;
@@ -231,7 +231,7 @@ int eDVBSubtitleParser::subtitle_process_pixel_data(subtitle_region *region, sub
                                } else
                                        break;
                        }
-                       while (len && ((*linep) < 720))
+                       while (len && ((*linep) < m_display_size.width()))
                        {
                                line[(*linep)++] = col;
                                len--;
@@ -270,7 +270,7 @@ int eDVBSubtitleParser::subtitle_process_pixel_data(subtitle_region *region, sub
                subtitle_process_line(region, object, *linenr, line, *linep);
 /*             {
                        int i;
-                       for (i=0; i<720; ++i)
+                       for (i=0; i<m_display_size.width(); ++i)
                                eDebugNoNewLine("%d ", line[i]);
                        eDebug("");
                } */
index e58f19a01388b4078837f758200702b7ec82c328..dca75af149cdcae4fd3f07173c813a90bb3f19b2 100755 (executable)
@@ -12,6 +12,7 @@ from enigma import ePoint
 
 import os
 from twisted.mail import smtp, relaymanager
+import MimeWriter, mimetools, StringIO
 
 config.plugins.crashlogautosubmit = ConfigSubsection()
 config.plugins.crashlogautosubmit.sendmail = ConfigSelection(default = "send", choices = [
@@ -219,13 +220,28 @@ class CrashlogAutoSubmitConfiguration(Screen, ConfigListScreen):
 
 def mxServerFound(mxServer,session):
        print "[CrashlogAutoSubmit] - mxServerFound -->", mxServer
-       attachments = []
        crashLogFilelist = []
+       message = StringIO.StringIO()
+       writer = MimeWriter.MimeWriter(message)
        mailFrom = "enigma2@crashlog.dream-multimedia-tv.de"
        mailTo = "enigma2@crashlog.dream-multimedia-tv.de"
        subject = "Automatically generated crashlogmail"
-       mailtext = "\nHello\n\nHere are some crashlogs i found for you.\n"
-       mailfooter = "\n\nThis is an automatically generated email from the CrashlogAutoSubmit plugin.\n\n\nHave a nice day.\n"
+       # Define the main body headers.
+       writer.addheader('To', "dream-multimedia-crashlogs <enigma2@crashlog.dream-multimedia-tv.de>")
+       writer.addheader('From', "CrashlogAutoSubmitter <enigma2@crashlog.dream-multimedia-tv.de>")
+       writer.addheader('Subject', str(subject))
+       writer.addheader('Date', smtp.rfc822date())
+       if config.plugins.crashlogautosubmit.attachemail.value is True:
+               if  str(config.plugins.crashlogautosubmit.email.value) != "myemail@home.com":
+                       writer.addheader('Reply-To', str(str(config.plugins.crashlogautosubmit.email.value)))
+       writer.addheader('MIME-Version', '1.0')
+       writer.startmultipartbody('mixed')
+       # start with a text/plain part
+       part = writer.nextpart()
+       body = part.startbody('text/plain')
+       part.flushheaders()
+       # Define the message body
+       body_text1 = "\nHello\n\nHere are some crashlogs i found for you.\n"
        if  str(config.plugins.crashlogautosubmit.email.value) == "myemail@home.com":
                user_email = ""
        else:
@@ -234,11 +250,9 @@ def mxServerFound(mxServer,session):
                user_name = ""
        else:
                user_name = "\n\nOptional supplied name: " + str(config.plugins.crashlogautosubmit.name.value)
-       headers = { 'from': 'CrashlogAutoSubmitter <enigma2@crashlog.dream-multimedia-tv.de>', 'to': 'dream-multimedia-crashlogs <enigma2@crashlog.dream-multimedia-tv.de>', 'subject' : str(subject) }
-       mailData = mailtext + user_email + user_name + mailfooter
-       if config.plugins.crashlogautosubmit.attachemail.value is True:
-               if  str(config.plugins.crashlogautosubmit.email.value) != "myemail@home.com":
-                       headers["reply-to"] = str(config.plugins.crashlogautosubmit.email.value)
+       body_text2 = "\n\nThis is an automatically generated email from the CrashlogAutoSubmit plugin.\n\n\nHave a nice day.\n"
+       body_text = body_text1 + user_email + user_name + body_text2
+       body.write(body_text)
 
        list = (
                (_("Yes"), "send"),
@@ -263,16 +277,17 @@ def mxServerFound(mxServer,session):
 
        def send_mail():
                print "[CrashlogAutoSubmit] - send_mail"
-               attachments = []
                if len(crashLogFilelist):
                        for crashlog in crashLogFilelist:
                                filename = str(os.path.basename(crashlog))
-                               mimetype = "text/plain"
-                               f = open (crashlog, 'r')
-                               attachment = str(f.read())
-                               f.close()
-                               attachments.append ((filename,mimetype,attachment))
-               sending = smtp.sendEmail(str(mxServer), mailFrom, mailTo, str(mailData), headers, attachments)
+                               subpart = writer.nextpart()
+                               subpart.addheader("Content-Transfer-Encoding", 'base64')
+                               subpart.addheader("Content-Disposition",'attachment; filename="%s"' % filename)
+                               subpart.addheader('Content-Description', 'Enigma2 crashlog')
+                               body = subpart.startbody("%s; name=%s" % ('application/octet-stream', filename))
+                               mimetools.encode(open(crashlog, 'rb'), body, 'base64')
+               writer.lastpart()
+               sending = smtp.sendmail(str(mxServer), mailFrom, mailTo, message.getvalue())
                sending.addCallback(handleSuccess).addErrback(handleError)
 
        def handleAnswer(answer):
@@ -296,7 +311,6 @@ def mxServerFound(mxServer,session):
                elif answer == "send_not":
                        print "[CrashlogAutoSubmit] - not sending crashlogs for this time."
 
-
        for crashlog in os.listdir('/media/hdd'):
                if crashlog.startswith("enigma2_crash_") and crashlog.endswith(".log"):
                        print "[CrashlogAutoSubmit] - found crashlog: ",os.path.basename(crashlog)
@@ -313,14 +327,10 @@ def mxServerFound(mxServer,session):
 
 def getMailExchange(host):
        print "[CrashlogAutoSubmit] - getMailExchange"
+       return relaymanager.MXCalculator().getMX(host).addCallback(_gotMXRecord)
 
-       def handleMXError(error):
-               print "[CrashlogAutoSubmit] - DNS-Error, sending aborted -->", error.getErrorMessage()
-
-       def cbMX(mxRecord):
-               return str(mxRecord.name)
-
-       return relaymanager.MXCalculator().getMX(host).addCallback(cbMX).addErrback(handleMXError)
+def _gotMXRecord(mxRecord):
+       return str(mxRecord.name)
 
 
 def startMailer(session):
@@ -328,8 +338,15 @@ def startMailer(session):
                print "[CrashlogAutoSubmit] - not starting CrashlogAutoSubmit"
                return False
 
+       def gotMXServer(mxServer):
+               print "[CrashlogAutoSubmit] gotMXServer: ",mxServer
+               mxServerFound(mxServer,session)
+
+       def handleMXError(error):
+               print "[CrashlogAutoSubmit] - MX resolve ERROR:", error.getErrorMessage()
+
        if not config.misc.firstrun.value:
-               getMailExchange('crashlog.dream-multimedia-tv.de').addCallback(mxServerFound,session)
+               getMailExchange('crashlog.dream-multimedia-tv.de').addCallback(gotMXServer).addErrback(handleMXError)
 
 
 def callCrashMailer(result,session):
index 6292a46fe38aa968907d0a4f096814b177f517f0..ba668f8b55fbde836a6d56aadb60e0be69cb9924 100644 (file)
@@ -9,6 +9,7 @@ from Components.Sources.Progress import Progress
 from Components.Label import Label
 from Components.FileList import FileList
 from Components.MultiContent import MultiContentEntryText
+from Components.ScrollLabel import ScrollLabel
 from Tools.Directories import fileExists
 from Tools.HardwareInfo import HardwareInfo
 from enigma import eConsoleAppContainer, eListbox, gFont, eListboxPythonMultiContent, \
@@ -62,6 +63,34 @@ class Feedlist(MenuList):
                if self.instance is not None:
                        self.instance.moveSelectionTo(idx)
 
+class NFOViewer(Screen):
+       skin = """
+               <screen name="NFOViewer" position="110,115" size="540,400" title="Changelog viewer" >
+                       <widget name="changelog" position="10,10" size="520,380" font="Regular;16" />
+               </screen>"""
+
+       def __init__(self, session, nfo):
+               Screen.__init__(self, session)
+               self["changelog"] = ScrollLabel(nfo)
+
+               self["ViewerActions"] = ActionMap(["SetupActions", "ColorActions", "DirectionActions"],
+                       {
+                               "green": self.exit,
+                               "red": self.exit,
+                               "ok": self.exit,
+                               "cancel": self.exit,
+                               "down": self.pageDown,
+                               "up": self.pageUp                       
+                       })
+       def pageUp(self):
+               self["changelog"].pageUp()
+
+       def pageDown(self):
+               self["changelog"].pageDown()
+                       
+       def exit(self):
+               self.close(False)
+
 class NFIDownload(Screen):
        LIST_SOURCE = 1
        LIST_DEST = 2
@@ -230,6 +259,8 @@ class NFIDownload(Screen):
                        self["destlist"].pageDown()
 
        def ok(self):
+               if self.focus is self.LIST_SOURCE and self.nfo:
+                       self.session.open(NFOViewer, self.nfo)
                if self.download:
                        return
                if self.focus is self.LIST_DEST:
@@ -249,7 +280,7 @@ class NFIDownload(Screen):
        def feed_finished(self, feedhtml):
                print "[feed_finished] " + str(feedhtml)
                self.downloading(False)
-               fileresultmask = re.compile("<a href=[\'\"](?P<url>.*?)[\'\"]>(?P<name>.*?.nfi)</a>", re.DOTALL)
+               fileresultmask = re.compile("<a class=[\'\"]nfi[\'\"] href=[\'\"](?P<url>.*?)[\'\"]>(?P<name>.*?.nfi)</a>", re.DOTALL)
                searchresults = fileresultmask.finditer(feedhtml)
                fileresultlist = []
                if searchresults:
@@ -308,7 +339,7 @@ class NFIDownload(Screen):
                else:   
                        self.nfofilename = ""
                        self["infolabel"].text = _("No details for this image file")
-               self["statusbar"].text = ""
+               self["statusbar"].text = _("Press OK to view full changelog")
 
        def nfi_download(self):
                if self["destlist"].getCurrentDirectory() is None:
index 8314e21394e6b6f95debb82097cb15579e1ca842..b8ccb6c2e219d9644e9f8e8a46adb0ce06ef8f29 100644 (file)
@@ -162,9 +162,14 @@ class TryQuitMainloop(MessageBox):
                        self.conntected=False
                        self.session.nav.record_event.remove(self.getRecordEvent)
                if value:
-                       quitMainloop(self.retval)
-               else:
-                       MessageBox.close(self, True)
+                       # hack .. we dont like to show any other screens when this screen has closed
+                       self.onClose = [self.__closed]
+                       self.session.dialog_stack = []
+                       self.session.summary_stack = [None]
+               MessageBox.close(self, True)
+
+       def __closed(self):
+               quitMainloop(self.retval)
 
        def __onShow(self):
                global inTryQuitMainloop
index 497911c5dd03e7fe97842efd7f951dac414f9539..01169986e10e443ee71bc9b1f5370d814459efc3 100644 (file)
@@ -1795,21 +1795,26 @@ int eDVBServicePlay::selectAudioStream(int i)
                return -4;
        }
 
+       int rdsPid = apid;
+
                /* if we are not in PVR mode, timeshift is not active and we are not in pip mode, check if we need to enable the rds reader */
        if (!(m_is_pvr || m_timeshift_active || !m_is_primary))
-               if (!m_rds_decoder)
+       {
+               int different_pid = program.videoStreams.empty() && program.audioStreams.size() == 1 && program.audioStreams[stream].rdsPid != -1;
+               if (different_pid)
+                       rdsPid = program.audioStreams[stream].rdsPid;
+               if (!m_rds_decoder || m_rds_decoder->getPid() != rdsPid)
                {
+                       m_rds_decoder = 0;
                        ePtr<iDVBDemux> data_demux;
                        if (!h.getDataDemux(data_demux))
                        {
-                               m_rds_decoder = new eDVBRdsDecoder(data_demux);
+                               m_rds_decoder = new eDVBRdsDecoder(data_demux, different_pid);
                                m_rds_decoder->connectEvent(slot(*this, &eDVBServicePlay::rdsDecoderEvent), m_rds_decoder_event_connection);
+                               m_rds_decoder->start(rdsPid);
                        }
                }
-
-               /* if we decided that we need one, update the pid */
-       if (m_rds_decoder)
-               m_rds_decoder->start(apid);
+       }
 
                        /* store new pid as default only when:
                                a.) we have an entry in the service db for the current service,