From c0d4e140b6ab536c08074800248c366fa7cb79b0 Mon Sep 17 00:00:00 2001 From: andy Date: Thu, 30 Oct 2008 15:09:21 +0100 Subject: add plugin list icon for dvdburn --- lib/python/Plugins/Extensions/DVDBurn/dvdburn.png | Bin 0 -> 3869 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100755 lib/python/Plugins/Extensions/DVDBurn/dvdburn.png (limited to 'lib') diff --git a/lib/python/Plugins/Extensions/DVDBurn/dvdburn.png b/lib/python/Plugins/Extensions/DVDBurn/dvdburn.png new file mode 100755 index 00000000..7e7adead Binary files /dev/null and b/lib/python/Plugins/Extensions/DVDBurn/dvdburn.png differ -- cgit v1.2.3 From d36def84f92bb9206c792356954e62c533297af4 Mon Sep 17 00:00:00 2001 From: andy Date: Thu, 30 Oct 2008 18:24:06 +0100 Subject: fix execute string for tasks --- lib/python/Components/Task.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'lib') diff --git a/lib/python/Components/Task.py b/lib/python/Components/Task.py index 7ea64f1a..c152e9a2 100644 --- a/lib/python/Components/Task.py +++ b/lib/python/Components/Task.py @@ -136,7 +136,6 @@ class Task(object): def setTool(self, tool): self.cmd = tool - self.args = [tool] self.global_preconditions.append(ToolExistsPrecondition()) self.postconditions.append(ReturncodePostcondition()) @@ -172,7 +171,7 @@ class Task(object): if self.cwd is not None: self.container.setCWD(self.cwd) - execstr = self.cmd + " ".join(self.args) + #execstr = " ".join([self.cmd]+self.args) print "execute:", self.container.execute(execstr), execstr if self.initial_input: self.writeInput(self.initial_input) -- cgit v1.2.3 From 8d4316d824f584eb3900fef898de59c9aca8d771 Mon Sep 17 00:00:00 2001 From: ghost Date: Thu, 30 Oct 2008 18:54:24 +0100 Subject: add possibility to disable user input in Messageboxes --- lib/python/Screens/MessageBox.py | 31 ++++++++++++++++--------------- 1 file changed, 16 insertions(+), 15 deletions(-) (limited to 'lib') diff --git a/lib/python/Screens/MessageBox.py b/lib/python/Screens/MessageBox.py index 8477fe04..8a5989c7 100644 --- a/lib/python/Screens/MessageBox.py +++ b/lib/python/Screens/MessageBox.py @@ -12,7 +12,7 @@ class MessageBox(Screen): TYPE_WARNING = 2 TYPE_ERROR = 3 - def __init__(self, session, text, type = TYPE_YESNO, timeout = -1, close_on_any_key = False, default = True): + def __init__(self, session, text, type = TYPE_YESNO, timeout = -1, close_on_any_key = False, default = True, enable_input = True): self.type = type Screen.__init__(self, session) @@ -47,20 +47,21 @@ class MessageBox(Screen): self["selectedChoice"].setText(self.list[0][0]) self["list"] = MenuList(self.list) - self["actions"] = ActionMap(["MsgBoxActions", "DirectionActions"], - { - "cancel": self.cancel, - "ok": self.ok, - "alwaysOK": self.alwaysOK, - "up": self.up, - "down": self.down, - "left": self.left, - "right": self.right, - "upRepeated": self.up, - "downRepeated": self.down, - "leftRepeated": self.left, - "rightRepeated": self.right - }, -1) + if enable_input: + self["actions"] = ActionMap(["MsgBoxActions", "DirectionActions"], + { + "cancel": self.cancel, + "ok": self.ok, + "alwaysOK": self.alwaysOK, + "up": self.up, + "down": self.down, + "left": self.left, + "right": self.right, + "upRepeated": self.up, + "downRepeated": self.down, + "leftRepeated": self.left, + "rightRepeated": self.right + }, -1) def initTimeout(self, timeout): self.timeout = timeout -- cgit v1.2.3 From fe9c79a96232f5e5dd12158bf948188110412664 Mon Sep 17 00:00:00 2001 From: ghost Date: Thu, 30 Oct 2008 21:21:46 +0100 Subject: Add DiSEqC reset after voltage enable and tune failed... hopefully this fixes problems with some DiSEqC switches --- lib/dvb/frontend.cpp | 7 ++++++- lib/dvb/sec.cpp | 21 +++++++++++++++++++++ 2 files changed, 27 insertions(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/dvb/frontend.cpp b/lib/dvb/frontend.cpp index 1bcacc03..635de8f5 100644 --- a/lib/dvb/frontend.cpp +++ b/lib/dvb/frontend.cpp @@ -1492,7 +1492,12 @@ void eDVBFrontend::tuneLoop() // called by m_tuneTimer eDebugNoSimulateNoNewLine("[SEC] sendDiseqc: "); for (int i=0; i < m_sec_sequence.current()->diseqc.len; ++i) eDebugNoSimulateNoNewLine("%02x", m_sec_sequence.current()->diseqc.data[i]); - eDebugNoSimulate(""); + if (!memcmp(m_sec_sequence.current()->diseqc.data, "\xE0\x00\x00", 3)) + eDebugNoSimulate("(DiSEqC reset)"); + else if (!memcmp(m_sec_sequence.current()->diseqc.data, "\xE0\x00\x03", 3)) + eDebugNoSimulate("(DiSEqC peripherial power on)"); + else + eDebugNoSimulate(""); ++m_sec_sequence.current(); break; case eSecCommand::SEND_TONEBURST: diff --git a/lib/dvb/sec.cpp b/lib/dvb/sec.cpp index ca9e4ec8..35a8d04a 100644 --- a/lib/dvb/sec.cpp +++ b/lib/dvb/sec.cpp @@ -372,6 +372,7 @@ RESULT eDVBSatelliteEquipmentControl::prepare(iDVBFrontend &frontend, FRONTENDPA bool doSetVoltageToneFrontend = true; bool sendDiSEqC = false; bool forceChanged = false; + bool needDiSEqCReset = false; long band=0, voltage = iDVBFrontend::voltageOff, tone = iDVBFrontend::toneOff, @@ -418,6 +419,9 @@ RESULT eDVBSatelliteEquipmentControl::prepare(iDVBFrontend &frontend, FRONTENDPA sec_fe->getData(eDVBFrontend::ROTOR_CMD, lastRotorCmd); sec_fe->getData(eDVBFrontend::ROTOR_POS, curRotorPos); + if (lastcsw == lastucsw && lastToneburst == lastucsw && lastucsw == -1) + needDiSEqCReset = true; + if ( sat.frequency > lnb_param.m_lof_threshold ) band |= 1; @@ -623,6 +627,23 @@ RESULT eDVBSatelliteEquipmentControl::prepare(iDVBFrontend &frontend, FRONTENDPA sec_sequence.push_back( eSecCommand(eSecCommand::SLEEP, m_params[DELAY_AFTER_ENABLE_VOLTAGE_BEFORE_SWITCH_CMDS]) ); sec_sequence.push_back( eSecCommand(eSecCommand::INVALIDATE_CURRENT_SWITCHPARMS) ); + if (needDiSEqCReset) + { + eDVBDiseqcCommand diseqc; + memset(diseqc.data, 0, MAX_DISEQC_LENGTH); + diseqc.len = 3; + diseqc.data[0] = 0xE0; + diseqc.data[1] = 0; + diseqc.data[2] = 0; + // diseqc reset + sec_sequence.push_back( eSecCommand(eSecCommand::SEND_DISEQC, diseqc) ); + sec_sequence.push_back( eSecCommand(eSecCommand::SLEEP, 50) ); + diseqc.data[2] = 3; + // diseqc peripherial powersupply on + sec_sequence.push_back( eSecCommand(eSecCommand::SEND_DISEQC, diseqc) ); + sec_sequence.push_back( eSecCommand(eSecCommand::SLEEP, 150) ); + } + for (int seq_repeat = 0; seq_repeat < (di_param.m_seq_repeat?2:1); ++seq_repeat) { if ( send_mask & 4 ) -- cgit v1.2.3 From 6c6704a6c897cef2aca87bd8d5a732ae1a2bac4a Mon Sep 17 00:00:00 2001 From: Felix Domke Date: Fri, 31 Oct 2008 02:03:15 +0100 Subject: Patch by Anders Holst: * Undo "sparse-AP-fix" At March 25 a patch was checked in that makes sure that AP:s closer than half a second from each other are filtered away. I don't know the exact purpose of this fix, but I don't think it is a good idea: Besides being the cause of bugs 4 and 5 above, all seek operations are based on the AP:s, and it is a pity to cripple the precision here. And for example, when cutting movies it is important to be able to reach the right GOP boundary. (And the next fix relies on all boundaries being available.) (If you wonder, bug 5 was caused by a destructive interaction of this with the discontinuity handling.) * Hit GOP:s somewhat before GOP start It turns out that if you jump exactly to the GOP start, then that GOP is nevertheless skipped and playback starts from the GOP thereafter. However, if you jump to (at least) one frame before the GOP start, playback starts from that GOP. I don't know if this is a bug in the driver or elsewhere, but the best I can do is this workaround: Hit the GOP by jumping to half a GOP length before the GOP start. (By scanning the ts file it is of course possible to find the exact frame boundaries, but why bother since anywhere between the previous GOP start and the previous frame start will do.) Similarly, to show the first frame of a GOP, a few more frames must be included. Therefore, add half a GOP at the end of each source span. * Jump over discontinuities during AP relative seek The above two fixes together *almost* take care of bugs 1 and 2 above. Now seekRelative(1) moves one forward and seekRelative(-1) one backwards. However, at discontinuities they may get stuck. This is remedied by an extra if statement to check for discontinuities when stepping throught the AP:s in AP relative seek. * Stop after last source span In the function eDVBChannel::getNextSourceSpan there was no code to take care of the case when the seeked-to point is after the last source span. Currently it just goes on until the movie ends. I have added code for this, which takes care of bug 3, and as a fortunate bonus effect bug 6 too. (But please check my code here, I hope I can use current_offset the way I do, and return 0 size when it should stop.) --- lib/dvb/dvb.cpp | 32 +++++++++++++++++++++----------- lib/dvb/pvrparse.cpp | 48 +++++++++++++++++++++++++++++++++--------------- lib/dvb/pvrparse.h | 2 +- lib/dvb/tstools.cpp | 7 +++++-- lib/dvb/tstools.h | 2 +- 5 files changed, 61 insertions(+), 30 deletions(-) (limited to 'lib') diff --git a/lib/dvb/dvb.cpp b/lib/dvb/dvb.cpp index 68d9a0dd..6edf9e87 100644 --- a/lib/dvb/dvb.cpp +++ b/lib/dvb/dvb.cpp @@ -1195,7 +1195,7 @@ void eDVBChannel::cueSheetEvent(int event) { off_t offset_in, offset_out; pts_t pts_in = i->first, pts_out = i->second; - if (m_tstools.getOffset(offset_in, pts_in) || m_tstools.getOffset(offset_out, pts_out)) + if (m_tstools.getOffset(offset_in, pts_in, -1) || m_tstools.getOffset(offset_out, pts_out, 1)) { eDebug("span translation failed.\n"); continue; @@ -1323,13 +1323,13 @@ void eDVBChannel::getNextSourceSpan(off_t current_offset, size_t bytes_read, off eDebug("AP relative seeking failed!"); } else { - eDebug("next ap is %llx\n", pts); pts = nextap; + eDebug("next ap is %llx\n", pts); } } off_t offset = 0; - if (m_tstools.getOffset(offset, pts)) + if (m_tstools.getOffset(offset, pts, -1)) { eDebug("get offset for pts=%lld failed!", pts); continue; @@ -1403,16 +1403,26 @@ void eDVBChannel::getNextSourceSpan(off_t current_offset, size_t bytes_read, off } } - if ((current_offset < -m_skipmode_m) && (m_skipmode_m < 0)) - { - eDebug("reached SOF"); - m_skipmode_m = 0; - m_pvr_thread->sendEvent(eFilePushThread::evtUser); + if (m_source_span.empty()) { + if ((current_offset < -m_skipmode_m) && (m_skipmode_m < 0)) + { + eDebug("reached SOF"); + m_skipmode_m = 0; + m_pvr_thread->sendEvent(eFilePushThread::evtUser); + } + start = current_offset; + size = max; + } else { + off_t tmp = align(m_source_span.rbegin()->second, blocksize); + if (current_offset == tmp) { + start = current_offset; + size = 0; + } else { + start = tmp - align(512*1024, blocksize); + size = align(512*1024, blocksize); + } } - start = current_offset; - size = max; - eDebug("END OF CUESHEET. (%08llx, %d)", start, size); return; } diff --git a/lib/dvb/pvrparse.cpp b/lib/dvb/pvrparse.cpp index 1b827d3c..35ba9091 100644 --- a/lib/dvb/pvrparse.cpp +++ b/lib/dvb/pvrparse.cpp @@ -36,8 +36,6 @@ int eMPEGStreamInformation::load(const char *filename) return -1; m_access_points.clear(); m_pts_to_offset.clear(); - pts_t last = -(1LL<<62); - int loaded = 0, skipped = 0; while (1) { unsigned long long d[2]; @@ -48,16 +46,9 @@ int eMPEGStreamInformation::load(const char *filename) d[0] = bswap_64(d[0]); d[1] = bswap_64(d[1]); #endif - if ((d[1] - last) > 90000/2) - { - m_access_points[d[0]] = d[1]; - m_pts_to_offset.insert(std::pair(d[1], d[0])); - last = d[1]; - loaded++; - } else - skipped++; + m_access_points[d[0]] = d[1]; + m_pts_to_offset.insert(std::pair(d[1], d[0])); } - eDebug("loaded %d, skipped %d", loaded, skipped); fclose(f); fixupDiscontinuties(); return 0; @@ -216,30 +207,45 @@ pts_t eMPEGStreamInformation::getInterpolated(off_t offset) return before_ts + diff; } -off_t eMPEGStreamInformation::getAccessPoint(pts_t ts) +off_t eMPEGStreamInformation::getAccessPoint(pts_t ts, int marg) { /* FIXME: more efficient implementation */ off_t last = 0; + off_t last2 = 0; + pts_t lastc = 0; for (std::map::const_iterator i(m_access_points.begin()); i != m_access_points.end(); ++i) { pts_t delta = getDelta(i->first); pts_t c = i->second - delta; - if (c > ts) - break; + if (c > ts) { + if (marg > 0) + return (last + i->first)/376*188; + else if (marg < 0) + return (last + last2)/376*188; + else + return last; + } + lastc = c; + last2 = last; last = i->first; } - return last; + if (marg < 0) + return (last + last2)/376*188; + else + return last; } int eMPEGStreamInformation::getNextAccessPoint(pts_t &ts, const pts_t &start, int direction) { off_t offset = getAccessPoint(start); + pts_t c1, c2; std::map::const_iterator i = m_access_points.find(offset); if (i == m_access_points.end()) { eDebug("getNextAccessPoint: initial AP not found"); return -1; } + c1 = i->second - getDelta(i->first); while (direction) { if (direction > 0) @@ -247,6 +253,12 @@ int eMPEGStreamInformation::getNextAccessPoint(pts_t &ts, const pts_t &start, in if (i == m_access_points.end()) return -1; ++i; + c2 = i->second - getDelta(i->first); + if (c1 == c2) { // Discontinuity + ++i; + c2 = i->second - getDelta(i->first); + } + c1 = c2; direction--; } if (direction < 0) @@ -257,6 +269,12 @@ int eMPEGStreamInformation::getNextAccessPoint(pts_t &ts, const pts_t &start, in return -1; } --i; + c2 = i->second - getDelta(i->first); + if (c1 == c2) { // Discontinuity + --i; + c2 = i->second - getDelta(i->first); + } + c1 = c2; direction++; } } diff --git a/lib/dvb/pvrparse.h b/lib/dvb/pvrparse.h index 69bb9924..b2ddd23d 100644 --- a/lib/dvb/pvrparse.h +++ b/lib/dvb/pvrparse.h @@ -41,7 +41,7 @@ public: /* inter/extrapolate timestamp from offset */ pts_t getInterpolated(off_t offset); - off_t getAccessPoint(pts_t ts); + off_t getAccessPoint(pts_t ts, int marg=0); int getNextAccessPoint(pts_t &ts, const pts_t &start, int direction); diff --git a/lib/dvb/tstools.cpp b/lib/dvb/tstools.cpp index 5157ef22..bd7ebce2 100644 --- a/lib/dvb/tstools.cpp +++ b/lib/dvb/tstools.cpp @@ -209,11 +209,14 @@ int eDVBTSTools::fixupPTS(const off_t &offset, pts_t &now) } } -int eDVBTSTools::getOffset(off_t &offset, pts_t &pts) +int eDVBTSTools::getOffset(off_t &offset, pts_t &pts, int marg) { if (m_use_streaminfo) { - offset = m_streaminfo.getAccessPoint(pts); + if (pts >= m_pts_end && marg > 0 && m_end_valid) + offset = m_offset_end; + else + offset = m_streaminfo.getAccessPoint(pts, marg); return 0; } else { diff --git a/lib/dvb/tstools.h b/lib/dvb/tstools.h index 13168253..4bc04729 100644 --- a/lib/dvb/tstools.h +++ b/lib/dvb/tstools.h @@ -40,7 +40,7 @@ public: int fixupPTS(const off_t &offset, pts_t &pts); /* get (approximate) offset corresponding to PTS */ - int getOffset(off_t &offset, pts_t &pts); + int getOffset(off_t &offset, pts_t &pts, int marg=0); int getNextAccessPoint(pts_t &ts, const pts_t &start, int direction); -- cgit v1.2.3 From d58b056ba2fff638bfb27b385192abaa9a84e31b Mon Sep 17 00:00:00 2001 From: Fraxinas Date: Fri, 31 Oct 2008 10:24:17 +0100 Subject: fix mem bug by changing c strings to cpp strings --- lib/service/servicemp3.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'lib') diff --git a/lib/service/servicemp3.cpp b/lib/service/servicemp3.cpp index a453f54f..5c982aa1 100644 --- a/lib/service/servicemp3.cpp +++ b/lib/service/servicemp3.cpp @@ -273,31 +273,31 @@ eServiceMP3::eServiceMP3(const char *filename): m_filename(filename), m_pump(eAp queue_audio = gst_element_factory_make("queue", "queue_audio"); queue_video = gst_element_factory_make("queue", "queue_video"); - char demux_type[14]; + std::string demux_type; switch (sourceinfo.containertype) { case ctMPEGTS: - strcat(demux_type, "flutsdemux"); + demux_type = "flutsdemux"; break; case ctMPEGPS: case ctVCD: - strcat(demux_type, "flupsdemux"); + demux_type = "flupsdemux"; break; case ctMKV: - strcat(demux_type, "matroskademux"); + demux_type = "matroskademux"; break; case ctAVI: - strcat(demux_type, "avidemux"); + demux_type = "avidemux"; break; case ctMP4: - strcat(demux_type, "qtdemux"); + demux_type = "qtdemux"; break; default: break; } - videodemux = gst_element_factory_make(demux_type, "videodemux"); + videodemux = gst_element_factory_make(demux_type.c_str(), "videodemux"); if (!videodemux) - m_error_message = "GStreamer plugin " + (std::string)demux_type + " not available!\n"; + m_error_message = "GStreamer plugin " + demux_type + " not available!\n"; switch_audio = gst_element_factory_make ("input-selector", "switch_audio"); if (!switch_audio) -- cgit v1.2.3 From f69b4f8dbed8ff96260b951cf8cecd76fa85423b Mon Sep 17 00:00:00 2001 From: Fraxinas Date: Fri, 31 Oct 2008 11:18:40 +0100 Subject: uncomment necessary line --- lib/python/Components/Task.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/python/Components/Task.py b/lib/python/Components/Task.py index c152e9a2..47acc87e 100644 --- a/lib/python/Components/Task.py +++ b/lib/python/Components/Task.py @@ -171,7 +171,7 @@ class Task(object): if self.cwd is not None: self.container.setCWD(self.cwd) - #execstr = " ".join([self.cmd]+self.args) + execstr = " ".join([self.cmd]+self.args) print "execute:", self.container.execute(execstr), execstr if self.initial_input: self.writeInput(self.initial_input) -- cgit v1.2.3 From 19ce1123c780a9475e2f158712da6e73fa543e9c Mon Sep 17 00:00:00 2001 From: ghost Date: Fri, 31 Oct 2008 13:07:01 +0100 Subject: add possibility to call eConsoleAppContainer execute with unlimited count of arguments when its called with single argument, then /bin/sh is started else not --- lib/base/console.cpp | 36 +++++++++++++++++++++++++++++++----- lib/python/Components/Task.py | 4 ++-- 2 files changed, 33 insertions(+), 7 deletions(-) (limited to 'lib') diff --git a/lib/base/console.cpp b/lib/base/console.cpp index a12cb5e2..25318cc9 100644 --- a/lib/base/console.cpp +++ b/lib/base/console.cpp @@ -476,11 +476,37 @@ eConsolePy_running(eConsolePy* self) static PyObject * eConsolePy_execute(eConsolePy* self, PyObject *argt) { - const char *str; - if (PyArg_ParseTuple(argt, "s", &str)) - return PyInt_FromLong(self->cont->execute(str)); - PyErr_SetString(PyExc_TypeError, - "argument is not a string"); + Py_ssize_t argc = PyTuple_Size(argt); + if (argc > 1) + { + const char *argv[argc + 1]; + int argpos=0; + while(argpos < argc) + { + PyObject *arg = PyTuple_GET_ITEM(argt, argpos); + if (!PyString_Check(arg)) + { + char err[255]; + if (argpos) + snprintf(err, 255, "arg %d is not a string", argpos); + else + snprintf(err, 255, "cmd is not a string!"); + PyErr_SetString(PyExc_TypeError, err); + return NULL; + } + argv[argpos++] = PyString_AsString(arg); + } + argv[argpos] = 0; + return PyInt_FromLong(self->cont->execute(argv[0], argv)); + } + else + { + const char *str; + if (PyArg_ParseTuple(argt, "s", &str)) + return PyInt_FromLong(self->cont->execute(str)); + PyErr_SetString(PyExc_TypeError, + "cmd is not a string!"); + } return NULL; } diff --git a/lib/python/Components/Task.py b/lib/python/Components/Task.py index 47acc87e..ab85c667 100644 --- a/lib/python/Components/Task.py +++ b/lib/python/Components/Task.py @@ -136,6 +136,7 @@ class Task(object): def setTool(self, tool): self.cmd = tool + self.args = [tool] self.global_preconditions.append(ToolExistsPrecondition()) self.postconditions.append(ReturncodePostcondition()) @@ -171,8 +172,7 @@ class Task(object): if self.cwd is not None: self.container.setCWD(self.cwd) - execstr = " ".join([self.cmd]+self.args) - print "execute:", self.container.execute(execstr), execstr + print "execute:", self.container.execute(self.cmd, *self.args), self.cmd, *self.args if self.initial_input: self.writeInput(self.initial_input) -- cgit v1.2.3 From 55acebf9599ad782cc305c13d18a14af66e65c20 Mon Sep 17 00:00:00 2001 From: ghost Date: Fri, 31 Oct 2008 14:03:55 +0100 Subject: dont add cmd to arglist --- lib/base/console.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/base/console.cpp b/lib/base/console.cpp index 25318cc9..5ca77d12 100644 --- a/lib/base/console.cpp +++ b/lib/base/console.cpp @@ -497,7 +497,7 @@ eConsolePy_execute(eConsolePy* self, PyObject *argt) argv[argpos++] = PyString_AsString(arg); } argv[argpos] = 0; - return PyInt_FromLong(self->cont->execute(argv[0], argv)); + return PyInt_FromLong(self->cont->execute(argv[0], argv+1)); } else { -- cgit v1.2.3 From de868496fdbc0dc65d961d7404bfd7af827e045f Mon Sep 17 00:00:00 2001 From: ghost Date: Fri, 31 Oct 2008 14:04:12 +0100 Subject: fix syntax error --- lib/python/Components/Task.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/python/Components/Task.py b/lib/python/Components/Task.py index ab85c667..f249f711 100644 --- a/lib/python/Components/Task.py +++ b/lib/python/Components/Task.py @@ -172,7 +172,7 @@ class Task(object): if self.cwd is not None: self.container.setCWD(self.cwd) - print "execute:", self.container.execute(self.cmd, *self.args), self.cmd, *self.args + print "execute:", self.container.execute(self.cmd, *self.args), self.cmd, self.args if self.initial_input: self.writeInput(self.initial_input) -- cgit v1.2.3 From 95f74bb07093569c7996b331efa189a1d115eefe Mon Sep 17 00:00:00 2001 From: Fraxinas Date: Fri, 31 Oct 2008 14:11:59 +0100 Subject: actually burn and not just simulate burning to dvd-MINUS-r(w) media --- lib/python/Plugins/Extensions/DVDBurn/Process.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'lib') diff --git a/lib/python/Plugins/Extensions/DVDBurn/Process.py b/lib/python/Plugins/Extensions/DVDBurn/Process.py index b8a3788e..1cc11e2d 100644 --- a/lib/python/Plugins/Extensions/DVDBurn/Process.py +++ b/lib/python/Plugins/Extensions/DVDBurn/Process.py @@ -701,7 +701,7 @@ class DVDJob(Job): if output == "dvd": self.name = _("Burn DVD") tool = "/bin/growisofs" - burnargs = [ "-Z", "/dev/" + harddiskmanager.getCD(), "-dvd-compat", "-use-the-force-luke=dummy" ] + burnargs = [ "-Z", "/dev/" + harddiskmanager.getCD(), "-dvd-compat" ] elif output == "iso": self.name = _("Create DVD-ISO") tool = "/usr/bin/mkisofs" @@ -739,7 +739,7 @@ class DVDdataJob(Job): tool = "/bin/growisofs" if output == "dvd": self.name = _("Burn DVD") - burnargs = [ "-Z", "/dev/" + harddiskmanager.getCD(), "-dvd-compat", "-use-the-force-luke=dummy" ] + burnargs = [ "-Z", "/dev/" + harddiskmanager.getCD(), "-dvd-compat" ] elif output == "iso": tool = "/usr/bin/mkisofs" self.name = _("Create DVD-ISO") @@ -762,11 +762,11 @@ class DVDisoJob(Job): self.menupreview = False if imagepath.endswith(".iso"): PreviewTask(self, imagepath) - burnargs = [ "-Z", "/dev/" + harddiskmanager.getCD() + '='+imagepath, "-dvd-compat", "-use-the-force-luke=dummy" ] + burnargs = [ "-Z", "/dev/" + harddiskmanager.getCD() + '='+imagepath, "-dvd-compat" ] else: PreviewTask(self, imagepath + "/VIDEO_TS/") volName = self.project.settings.name.getValue() - burnargs = [ "-Z", "/dev/" + harddiskmanager.getCD(), "-dvd-compat", "-use-the-force-luke=dummy" ] + burnargs = [ "-Z", "/dev/" + harddiskmanager.getCD(), "-dvd-compat" ] burnargs += [ "-dvd-video", "-publisher", "Dreambox", "-V", volName, imagepath ] tool = "/bin/growisofs" BurnTask(self, burnargs, tool) -- cgit v1.2.3 From 9f767ea6bfa7f37de7553b3c7f15adb678c63d71 Mon Sep 17 00:00:00 2001 From: Fraxinas Date: Fri, 31 Oct 2008 15:08:48 +0100 Subject: add additional clear text error messages for burntask --- lib/python/Plugins/Extensions/DVDBurn/Process.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/python/Plugins/Extensions/DVDBurn/Process.py b/lib/python/Plugins/Extensions/DVDBurn/Process.py index 1cc11e2d..7a03b7eb 100644 --- a/lib/python/Plugins/Extensions/DVDBurn/Process.py +++ b/lib/python/Plugins/Extensions/DVDBurn/Process.py @@ -251,11 +251,13 @@ class BurnTaskPostcondition(Condition): task.ERROR_WRITE_FAILED: _("Write failed!"), task.ERROR_DVDROM: _("No (supported) DVDROM found!"), task.ERROR_ISOFS: _("Medium is not empty!"), + task.ERROR_FILETOOLARGE: _("TS file is too large for ISO9660 level 1!"), + task.ERROR_ISOTOOLARGE: _("ISO file is too large for this filesystem!"), task.ERROR_UNKNOWN: _("An unknown error occured!") }[task.error] class BurnTask(Task): - ERROR_NOTWRITEABLE, ERROR_LOAD, ERROR_SIZE, ERROR_WRITE_FAILED, ERROR_DVDROM, ERROR_ISOFS, ERROR_UNKNOWN = range(7) + ERROR_NOTWRITEABLE, ERROR_LOAD, ERROR_SIZE, ERROR_WRITE_FAILED, ERROR_DVDROM, ERROR_ISOFS, ERROR_FILETOOLARGE, ERROR_ISOTOOLARGE, ERROR_UNKNOWN = range(9) def __init__(self, job, extra_args=[], tool="/bin/growisofs"): Task.__init__(self, job, job.name) self.weighting = 500 @@ -303,6 +305,10 @@ class BurnTask(Task): else: self.error = self.ERROR_UNKNOWN print "BurnTask: unknown error %s" % line + elif line.find("-allow-limited-size was not specified. There is no way do represent this file size. Aborting.") != -1: + self.error = self.ERROR_FILETOOLARGE + elif line.startswith("genisoimage: File too large."): + self.error = self.ERROR_ISOTOOLARGE class RemoveDVDFolder(Task): def __init__(self, job): -- cgit v1.2.3 From 28c7b76bc72da019f3c3bf3aca88c3636062a618 Mon Sep 17 00:00:00 2001 From: ghost Date: Fri, 31 Oct 2008 16:43:41 +0100 Subject: needed update for avahi stuff --- lib/python/Components/Network.py | 102 +++++++++++++++++++++++++-------------- 1 file changed, 65 insertions(+), 37 deletions(-) (limited to 'lib') diff --git a/lib/python/Components/Network.py b/lib/python/Components/Network.py index 9b0898e0..5c9e06b7 100644 --- a/lib/python/Components/Network.py +++ b/lib/python/Components/Network.py @@ -14,10 +14,11 @@ class Network: self.Console = Console() self.getInterfaces() - def getInterfaces(self): + def getInterfaces(self, callback = None): devicesPattern = re_compile('[a-z]+[0-9]+') self.configuredInterfaces = [] fp = file('/proc/net/dev', 'r') + system("cat /proc/net/dev") result = fp.readlines() fp.close() for line in result: @@ -25,19 +26,10 @@ class Network: device = devicesPattern.search(line).group() if device == 'wifi0': continue - self.getDataForInterface(device) - # Show only UP Interfaces in E2 - #if self.getAdapterAttribute(device, 'up') is False: - # del self.ifaces[device] + self.getDataForInterface(device, callback) except AttributeError: pass - #print "self.ifaces:", self.ifaces - #self.writeNetworkConfig() - #print ord(' ') - #for line in result: - # print ord(line[0]) - # helper function def regExpMatch(self, pattern, string): if string is None: @@ -55,12 +47,37 @@ class Network: ip.append(int(x)) return ip - def getDataForInterface(self, iface): - cmd = "ifconfig " + iface - self.Console.ePopen(cmd, self.ifconfigFinished, iface) - - def ifconfigFinished(self, result, retval, iface): + def IPaddrFinished(self, result, retval, extra_args): + (iface, callback ) = extra_args data = { 'up': False, 'dhcp': False, 'preup' : False, 'postdown' : False } + globalIPpattern = re_compile("scope global") + ipRegexp = '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' + ipLinePattern = re_compile('inet ' + ipRegexp +'/') + ipPattern = re_compile(ipRegexp) + + for line in result.splitlines(): + split = line.strip().split(' ',2) + if (split[1] == iface): + if re_search(globalIPpattern, split[2]): + ip = self.regExpMatch(ipPattern, self.regExpMatch(ipLinePattern, split[2])) + if ip is not None: + data['ip'] = self.convertIP(ip) + if not data.has_key('ip'): + data['dhcp'] = True + data['ip'] = [0, 0, 0, 0] + data['netmask'] = [0, 0, 0, 0] + data['gateway'] = [0, 0, 0, 0] + + cmd = "ifconfig " + iface + self.Console.ePopen(cmd, self.ifconfigFinished, [iface, data, callback]) + + def getDataForInterface(self, iface,callback): + #get ip out of ip addr, as avahi sometimes overrides it in ifconfig. + cmd = "ip -o addr" + self.Console.ePopen(cmd, self.IPaddrFinished, [iface,callback]) + + def ifconfigFinished(self, result, retval, extra_args ): + (iface, data, callback ) = extra_args ipRegexp = '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' ipLinePattern = re_compile('inet addr:' + ipRegexp) netmaskLinePattern = re_compile('Mask:' + ipRegexp) @@ -68,15 +85,15 @@ class Network: ipPattern = re_compile(ipRegexp) upPattern = re_compile('UP ') macPattern = re_compile('[0-9]{2}\:[0-9]{2}\:[0-9]{2}\:[0-9]{2}\:[0-9]{2}\:[0-9]{2}') - + for line in result.splitlines(): - ip = self.regExpMatch(ipPattern, self.regExpMatch(ipLinePattern, line)) + #ip = self.regExpMatch(ipPattern, self.regExpMatch(ipLinePattern, line)) netmask = self.regExpMatch(ipPattern, self.regExpMatch(netmaskLinePattern, line)) bcast = self.regExpMatch(ipPattern, self.regExpMatch(bcastLinePattern, line)) up = self.regExpMatch(upPattern, line) mac = self.regExpMatch(macPattern, line) - if ip is not None: - data['ip'] = self.convertIP(ip) + #if ip is not None: + # data['ip'] = self.convertIP(ip) if netmask is not None: data['netmask'] = self.convertIP(netmask) if bcast is not None: @@ -87,27 +104,34 @@ class Network: self.configuredInterfaces.append(iface) if mac is not None: data['mac'] = mac - if not data.has_key('ip'): - data['dhcp'] = True - data['ip'] = [0, 0, 0, 0] - data['netmask'] = [0, 0, 0, 0] - data['gateway'] = [0, 0, 0, 0] - + cmd = "route -n | grep " + iface - self.Console.ePopen(cmd,self.routeFinished,[iface,data,ipPattern]) + self.Console.ePopen(cmd,self.routeFinished,[iface,data,callback]) def routeFinished(self, result, retval, extra_args): - (iface, data, ipPattern) = extra_args - + (iface, data, callback) = extra_args + ipRegexp = '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' + ipPattern = re_compile(ipRegexp) + ipLinePattern = re_compile(ipRegexp) + for line in result.splitlines(): print line[0:7] if line[0:7] == "0.0.0.0": gateway = self.regExpMatch(ipPattern, line[16:31]) if gateway is not None: data['gateway'] = self.convertIP(gateway) + + for line in result.splitlines(): #get real netmask in case avahi has overridden ifconfig netmask + split = line.strip().split(' ') + if re_search(ipPattern, split[0]): + foundip = self.convertIP(split[0]) + if (foundip[0] == data['ip'][0] and foundip[1] == data['ip'][1]): + if re_search(ipPattern, split[4]): + mask = self.regExpMatch(ipPattern, self.regExpMatch(ipLinePattern, split[4])) + if mask is not None: + data['netmask'] = self.convertIP(mask) self.ifaces[iface] = data - if len(self.Console.appContainers) == 0: - self.loadNetworkConfig() + self.loadNetworkConfig(iface,callback) def writeNetworkConfig(self): self.configuredInterfaces = [] @@ -144,8 +168,7 @@ class Network: fp.write("nameserver %d.%d.%d.%d\n" % tuple(nameserver)) fp.close() - def loadNetworkConfig(self): - self.loadNameserverConfig() + def loadNetworkConfig(self,iface,callback = None): interfaces = [] # parse the interfaces-file try: @@ -166,7 +189,7 @@ class Network: ifaces[currif]["dhcp"] = True else: ifaces[currif]["dhcp"] = False - if (currif != ""): + if (currif == iface): #read information only for available interfaces if (split[0] == "address"): ifaces[currif]["address"] = map(int, split[1].split('.')) if self.ifaces[currif].has_key("ip"): @@ -181,7 +204,7 @@ class Network: ifaces[currif]["gateway"] = map(int, split[1].split('.')) if self.ifaces[currif].has_key("gateway"): if self.ifaces[currif]["gateway"] != ifaces[currif]["gateway"] and ifaces[currif]["dhcp"] == False: - self.ifaces[currif]["gateway"] = map(int, split[1].split('.')) + self.ifaces[currif]["gateway"] = map(int, split[1].split('.')) if (split[0] == "pre-up"): if self.ifaces[currif].has_key("preup"): self.ifaces[currif]["preup"] = i @@ -189,11 +212,16 @@ class Network: if self.ifaces[currif].has_key("postdown"): self.ifaces[currif]["postdown"] = i - print "read interfaces:", ifaces for ifacename, iface in ifaces.items(): if self.ifaces.has_key(ifacename): self.ifaces[ifacename]["dhcp"] = iface["dhcp"] - print "self.ifaces after loading:", self.ifaces + if len(self.Console.appContainers) == 0: + # load ns only once + self.loadNameserverConfig() + print "read configured interfac:", ifaces + print "self.ifaces after loading:", self.ifaces + if callback is not None: + callback(True) def loadNameserverConfig(self): ipRegexp = "[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}" -- cgit v1.2.3 From 340ec4b3727cb61e1038ca97b006471b5568e8a3 Mon Sep 17 00:00:00 2001 From: ghost Date: Fri, 31 Oct 2008 17:16:10 +0100 Subject: remove debug output --- lib/python/Components/Network.py | 1 - 1 file changed, 1 deletion(-) (limited to 'lib') diff --git a/lib/python/Components/Network.py b/lib/python/Components/Network.py index 5c9e06b7..cf21c6d0 100644 --- a/lib/python/Components/Network.py +++ b/lib/python/Components/Network.py @@ -18,7 +18,6 @@ class Network: devicesPattern = re_compile('[a-z]+[0-9]+') self.configuredInterfaces = [] fp = file('/proc/net/dev', 'r') - system("cat /proc/net/dev") result = fp.readlines() fp.close() for line in result: -- cgit v1.2.3 From 7d90a93493f1dc9ab9d3a5694aa96501a9b25b89 Mon Sep 17 00:00:00 2001 From: ghost Date: Fri, 31 Oct 2008 19:36:58 +0100 Subject: add missing import --- lib/python/Components/Network.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/python/Components/Network.py b/lib/python/Components/Network.py index cf21c6d0..bed9d95f 100644 --- a/lib/python/Components/Network.py +++ b/lib/python/Components/Network.py @@ -1,5 +1,5 @@ from os import system, popen, path as os_path, listdir -from re import compile as re_compile +from re import compile as re_compile, search as re_search from socket import * from enigma import eConsoleAppContainer from Components.Console import Console -- cgit v1.2.3 From 70084c02aa33ef20e61d0b6257a679ab76a42660 Mon Sep 17 00:00:00 2001 From: Fraxinas Date: Sat, 1 Nov 2008 00:34:47 +0100 Subject: add icon to be installed. remove deprecated directories --- .../Plugins/Extensions/DVDBurn/data/Makefile.am | 6 ------ .../Plugins/Extensions/DVDBurn/data/dreamdvd_boat.jpg | Bin 187417 -> 0 bytes .../Plugins/Extensions/DVDBurn/data/dreamvmgm.mpg | Bin 575488 -> 0 bytes .../Plugins/Extensions/DVDBurn/data/silence.mp2 | Bin 8340 -> 0 bytes .../DVDBurn/template/DreamboxDVDtemplate.ddvdp.xml | 18 ------------------ .../Plugins/Extensions/DVDBurn/template/Makefile.am | 7 ------- 6 files changed, 31 deletions(-) delete mode 100644 lib/python/Plugins/Extensions/DVDBurn/data/Makefile.am delete mode 100755 lib/python/Plugins/Extensions/DVDBurn/data/dreamdvd_boat.jpg delete mode 100644 lib/python/Plugins/Extensions/DVDBurn/data/dreamvmgm.mpg delete mode 100644 lib/python/Plugins/Extensions/DVDBurn/data/silence.mp2 delete mode 100644 lib/python/Plugins/Extensions/DVDBurn/template/DreamboxDVDtemplate.ddvdp.xml delete mode 100644 lib/python/Plugins/Extensions/DVDBurn/template/Makefile.am (limited to 'lib') diff --git a/lib/python/Plugins/Extensions/DVDBurn/data/Makefile.am b/lib/python/Plugins/Extensions/DVDBurn/data/Makefile.am deleted file mode 100644 index e5992b9c..00000000 --- a/lib/python/Plugins/Extensions/DVDBurn/data/Makefile.am +++ /dev/null @@ -1,6 +0,0 @@ -AUTOMAKE_OPTIONS = gnu - -installdir = $(DATADIR)/enigma2 - -install_DATA = \ - dreamdvd_boat.jpg dreamvmgm.mpg silence.mp2 diff --git a/lib/python/Plugins/Extensions/DVDBurn/data/dreamdvd_boat.jpg b/lib/python/Plugins/Extensions/DVDBurn/data/dreamdvd_boat.jpg deleted file mode 100755 index a5256e28..00000000 Binary files a/lib/python/Plugins/Extensions/DVDBurn/data/dreamdvd_boat.jpg and /dev/null differ diff --git a/lib/python/Plugins/Extensions/DVDBurn/data/dreamvmgm.mpg b/lib/python/Plugins/Extensions/DVDBurn/data/dreamvmgm.mpg deleted file mode 100644 index 4797986f..00000000 Binary files a/lib/python/Plugins/Extensions/DVDBurn/data/dreamvmgm.mpg and /dev/null differ diff --git a/lib/python/Plugins/Extensions/DVDBurn/data/silence.mp2 b/lib/python/Plugins/Extensions/DVDBurn/data/silence.mp2 deleted file mode 100644 index e8a817f8..00000000 Binary files a/lib/python/Plugins/Extensions/DVDBurn/data/silence.mp2 and /dev/null differ diff --git a/lib/python/Plugins/Extensions/DVDBurn/template/DreamboxDVDtemplate.ddvdp.xml b/lib/python/Plugins/Extensions/DVDBurn/template/DreamboxDVDtemplate.ddvdp.xml deleted file mode 100644 index b839ad8a..00000000 --- a/lib/python/Plugins/Extensions/DVDBurn/template/DreamboxDVDtemplate.ddvdp.xml +++ /dev/null @@ -1,18 +0,0 @@ - - - - - diff --git a/lib/python/Plugins/Extensions/DVDBurn/template/Makefile.am b/lib/python/Plugins/Extensions/DVDBurn/template/Makefile.am deleted file mode 100644 index f0d9e8a0..00000000 --- a/lib/python/Plugins/Extensions/DVDBurn/template/Makefile.am +++ /dev/null @@ -1,7 +0,0 @@ -AUTOMAKE_OPTIONS = gnu - -installdir = /etc/enigma2/playlist - -install_DATA = \ - DreamboxDVDtemplate.ddvdp.xml - -- cgit v1.2.3 From bac628cdd294815c4c09f8f6634357d4f2baadf9 Mon Sep 17 00:00:00 2001 From: ghost Date: Sun, 2 Nov 2008 10:40:46 +0100 Subject: small fix --- lib/dvb/dvbtime.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/dvb/dvbtime.cpp b/lib/dvb/dvbtime.cpp index 83ca3355..c4335795 100644 --- a/lib/dvb/dvbtime.cpp +++ b/lib/dvb/dvbtime.cpp @@ -394,7 +394,9 @@ void eDVBLocalTimeHandler::updateTime( time_t tp_time, eDVBChannel *chan, int up m_knownChannels.find(chan); if ( it != m_knownChannels.end() ) { - it->second.tdt = new TDT(chan, it->second.tdt->getUpdateCount()); + int updateCount = it->second.tdt->getUpdateCount(); + it->second.tdt = 0; + it->second.tdt = new TDT(chan, updateCount); it->second.tdt->startTimer(60*60*1000); // restart TDT for this transponder in 60min } } -- cgit v1.2.3 From 09fd651afb1107d45f5d400fad6bb4bb9b825439 Mon Sep 17 00:00:00 2001 From: ghost Date: Sun, 2 Nov 2008 10:42:12 +0100 Subject: check sid and tsid before start automatic service update (STD update) --- lib/dvb/pmt.cpp | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) (limited to 'lib') diff --git a/lib/dvb/pmt.cpp b/lib/dvb/pmt.cpp index 6082bf4a..13734e0d 100644 --- a/lib/dvb/pmt.cpp +++ b/lib/dvb/pmt.cpp @@ -135,7 +135,19 @@ void eDVBServicePMTHandler::PATready(int) if (pmtpid == -1) serviceEvent(eventNoPATEntry); else + { // here we know a pat entry for this service id exist m_PMT.begin(eApp, eDVBPMTSpec(pmtpid, m_reference.getServiceID().get()), m_demux); + if (m_reference.path.empty()) + { // also check the tsid now before start sdt update + eDVBChannelID chid; + m_reference.getChannelID(chid); + if (eTransportStreamID((*i)->getTableIdExtension()) == chid.transport_stream_id) + { + m_dvb_scan = new eDVBScan(m_channel, true, false); + m_dvb_scan->connectEvent(slot(*this, &eDVBServicePMTHandler::SDTScanEvent), m_scan_event_connection); + } + } + } } else serviceEvent(eventNoPAT); } @@ -604,10 +616,7 @@ int eDVBServicePMTHandler::tune(eServiceReferenceDVB &ref, int use_decode_demux, m_channelEvent_connection); if (ref.path.empty()) - { - m_dvb_scan = new eDVBScan(m_channel, true, false); - m_dvb_scan->connectEvent(slot(*this, &eDVBServicePMTHandler::SDTScanEvent), m_scan_event_connection); - } + m_dvb_scan = 0; } else { if (res == eDVBResourceManager::errAllSourcesBusy) -- cgit v1.2.3 From bd9c23676ae20d70488f7a539574b2ec75886940 Mon Sep 17 00:00:00 2001 From: ghost Date: Sun, 2 Nov 2008 11:14:33 +0100 Subject: add .mp2 as supported filetype --- lib/python/Components/FileList.py | 1 + lib/python/Plugins/Extensions/MediaPlayer/plugin.py | 6 +++--- lib/service/servicemp3.cpp | 1 + 3 files changed, 5 insertions(+), 3 deletions(-) (limited to 'lib') diff --git a/lib/python/Components/FileList.py b/lib/python/Components/FileList.py index 7801c556..e028ec3a 100644 --- a/lib/python/Components/FileList.py +++ b/lib/python/Components/FileList.py @@ -10,6 +10,7 @@ from enigma import RT_HALIGN_LEFT, eListboxPythonMultiContent, \ from Tools.LoadPixmap import LoadPixmap EXTENSIONS = { + "mp2": "music", "mp3": "music", "wav": "music", "ogg": "music", diff --git a/lib/python/Plugins/Extensions/MediaPlayer/plugin.py b/lib/python/Plugins/Extensions/MediaPlayer/plugin.py index a144f2cd..841ad614 100644 --- a/lib/python/Plugins/Extensions/MediaPlayer/plugin.py +++ b/lib/python/Plugins/Extensions/MediaPlayer/plugin.py @@ -66,7 +66,7 @@ class MediaPlayer(Screen, InfoBarBase, InfoBarSeek, InfoBarAudioSelection, InfoB self.addPlaylistParser(PlaylistIOInternal, "e2pls") # 'None' is magic to start at the list of mountpoints - self.filelist = FileList(None, matchingPattern = "(?i)^.*\.(mp3|ogg|ts|wav|wave|m3u|pls|e2pls|mpg|vob|avi|mkv|mp4|dat|flac)", useServiceRef = True, additionalExtensions = "4098:m3u 4098:e2pls 4098:pls") + self.filelist = FileList(None, matchingPattern = "(?i)^.*\.(mp2|mp3|ogg|ts|wav|wave|m3u|pls|e2pls|mpg|vob|avi|mkv|mp4|dat|flac)", useServiceRef = True, additionalExtensions = "4098:m3u 4098:e2pls 4098:pls") self["filelist"] = self.filelist self.playlist = MyPlayList() @@ -727,7 +727,7 @@ class MediaPlayer(Screen, InfoBarBase, InfoBarSeek, InfoBarAudioSelection, InfoB ext = text[-4:].lower() # FIXME: the information if the service contains video (and we should hide our window) should com from the service instead - if ext not in [".mp3", ".wav", ".ogg", "flac"] and not self.isAudioCD: + if ext not in [".mp2", ".mp3", ".wav", ".ogg", "flac"] and not self.isAudioCD: self.hide() else: needsInfoUpdate = True @@ -754,7 +754,7 @@ class MediaPlayer(Screen, InfoBarBase, InfoBarSeek, InfoBarAudioSelection, InfoB currref = self.playlist.getServiceRefList()[idx] text = currref.getPath() ext = text[-4:].lower() - if ext not in [".mp3", ".wav", ".ogg", "flac"] and not self.isAudioCD: + if ext not in [".mp2", ".mp3", ".wav", ".ogg", "flac"] and not self.isAudioCD: self.hide() else: needsInfoUpdate = True diff --git a/lib/service/servicemp3.cpp b/lib/service/servicemp3.cpp index 5c982aa1..c76e346e 100644 --- a/lib/service/servicemp3.cpp +++ b/lib/service/servicemp3.cpp @@ -27,6 +27,7 @@ eServiceFactoryMP3::eServiceFactoryMP3() if (sc) { std::list extensions; + extensions.push_back("mp2"); extensions.push_back("mp3"); extensions.push_back("ogg"); extensions.push_back("mpg"); -- cgit v1.2.3 From 1a1aa77247ad62a590f7c91d4e5b9c7b45c9dd25 Mon Sep 17 00:00:00 2001 From: ghost Date: Sun, 2 Nov 2008 12:52:14 +0100 Subject: Revert "check sid and tsid before start automatic service update (STD update)" This reverts commit 21812866841eec7ab7a79ee61067581f8202df55. --- lib/dvb/pmt.cpp | 17 ++++------------- 1 file changed, 4 insertions(+), 13 deletions(-) (limited to 'lib') diff --git a/lib/dvb/pmt.cpp b/lib/dvb/pmt.cpp index 13734e0d..6082bf4a 100644 --- a/lib/dvb/pmt.cpp +++ b/lib/dvb/pmt.cpp @@ -135,19 +135,7 @@ void eDVBServicePMTHandler::PATready(int) if (pmtpid == -1) serviceEvent(eventNoPATEntry); else - { // here we know a pat entry for this service id exist m_PMT.begin(eApp, eDVBPMTSpec(pmtpid, m_reference.getServiceID().get()), m_demux); - if (m_reference.path.empty()) - { // also check the tsid now before start sdt update - eDVBChannelID chid; - m_reference.getChannelID(chid); - if (eTransportStreamID((*i)->getTableIdExtension()) == chid.transport_stream_id) - { - m_dvb_scan = new eDVBScan(m_channel, true, false); - m_dvb_scan->connectEvent(slot(*this, &eDVBServicePMTHandler::SDTScanEvent), m_scan_event_connection); - } - } - } } else serviceEvent(eventNoPAT); } @@ -616,7 +604,10 @@ int eDVBServicePMTHandler::tune(eServiceReferenceDVB &ref, int use_decode_demux, m_channelEvent_connection); if (ref.path.empty()) - m_dvb_scan = 0; + { + m_dvb_scan = new eDVBScan(m_channel, true, false); + m_dvb_scan->connectEvent(slot(*this, &eDVBServicePMTHandler::SDTScanEvent), m_scan_event_connection); + } } else { if (res == eDVBResourceManager::errAllSourcesBusy) -- cgit v1.2.3 From c2e910d7e435dc9aefcc34e5c2eda5f7732606d8 Mon Sep 17 00:00:00 2001 From: Fraxinas Date: Mon, 3 Nov 2008 09:01:50 +0100 Subject: user correct playlist parser from dict --- lib/python/Plugins/Extensions/MediaPlayer/plugin.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'lib') diff --git a/lib/python/Plugins/Extensions/MediaPlayer/plugin.py b/lib/python/Plugins/Extensions/MediaPlayer/plugin.py index 841ad614..ed1a8874 100644 --- a/lib/python/Plugins/Extensions/MediaPlayer/plugin.py +++ b/lib/python/Plugins/Extensions/MediaPlayer/plugin.py @@ -592,12 +592,13 @@ class MediaPlayer(Screen, InfoBarBase, InfoBarSeek, InfoBarAudioSelection, InfoB def PlaylistSelected(self,path): if path is not None: self.clear_playlist() - self.playlistIOInternal = PlaylistIOInternal() - list = self.playlistIOInternal.open(path[1]) - if list: + extension = path[0].rsplit('.',1)[-1] + if self.playlistparsers.has_key(extension): + playlist = self.playlistparsers[extension]() + list = playlist.open(path[1]) for x in list: self.playlist.addFile(x.ref) - self.playlist.updateList() + self.playlist.updateList() def delete_saved_playlist(self): listpath = [] -- cgit v1.2.3 From 7f7f308008f91781d9223c3350f5ed86272096e7 Mon Sep 17 00:00:00 2001 From: Felix Domke Date: Mon, 3 Nov 2008 13:16:58 +0100 Subject: fix decode --- lib/service/service.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'lib') diff --git a/lib/service/service.cpp b/lib/service/service.cpp index 7721fed7..f34237d2 100644 --- a/lib/service/service.cpp +++ b/lib/service/service.cpp @@ -41,8 +41,8 @@ static std::string decode(const std::string s) i += 2; if (i >= len) break; - char s[3] = {s[i - 1], s[i], 0}; - unsigned char r = strtoul(s, 0, 0x10); + char t[3] = {s[i - 1], s[i], 0}; + unsigned char r = strtoul(t, 0, 0x10); if (r) res += r; } -- cgit v1.2.3 From 6d9bdc5e7ee8990b74da7e18f0b641b39250a827 Mon Sep 17 00:00:00 2001 From: Fraxinas Date: Mon, 3 Nov 2008 13:47:04 +0100 Subject: fix streaming playback (webradio) --- lib/python/Components/Playlist.py | 2 ++ lib/service/servicemp3.cpp | 35 +++++++++++++++++++---------------- 2 files changed, 21 insertions(+), 16 deletions(-) (limited to 'lib') diff --git a/lib/python/Components/Playlist.py b/lib/python/Components/Playlist.py index 22799692..744ee3af 100644 --- a/lib/python/Components/Playlist.py +++ b/lib/python/Components/Playlist.py @@ -70,6 +70,8 @@ class PlaylistIOM3U(PlaylistIO): # TODO: use e2 facilities to create a service ref from file if entry[0] == "/": self.addService(ServiceReference("4097:0:0:0:0:0:0:0:0:0:" + entry)) + elif entry.startswith("http"): + self.addService(ServiceReference("4097:0:0:0:0:0:0:0:0:0:" + entry.replace(':',"%3a"))) else: self.addService(ServiceReference("4097:0:0:0:0:0:0:0:0:0:" + os.path.dirname(filename) + "/" + entry)) file.close() diff --git a/lib/service/servicemp3.cpp b/lib/service/servicemp3.cpp index c76e346e..19b7735b 100644 --- a/lib/service/servicemp3.cpp +++ b/lib/service/servicemp3.cpp @@ -227,11 +227,29 @@ eServiceMP3::eServiceMP3(const char *filename): m_filename(filename), m_pump(eAp if (!m_gst_pipeline) m_error_message = "failed to create GStreamer pipeline!\n"; - if ( sourceinfo.containertype == ctCDA ) + if ( sourceinfo.is_streaming ) + { + eDebug("play webradio!"); + source = gst_element_factory_make ("neonhttpsrc", "http-source"); + if (source) + { + g_object_set (G_OBJECT (source), "location", filename, NULL); + g_object_set (G_OBJECT (source), "automatic-redirect", TRUE, NULL); + } + else + m_error_message = "GStreamer plugin neonhttpsrc not available!\n"; + } + else if ( sourceinfo.containertype == ctCDA ) { source = gst_element_factory_make ("cdiocddasrc", "cda-source"); if (source) + { g_object_set (G_OBJECT (source), "device", "/dev/cdroms/cdrom0", NULL); + int track = atoi(filename+18); + eDebug("play audio CD track #%i",track); + if (track > 0) + g_object_set (G_OBJECT (source), "track", track, NULL); + } else sourceinfo.containertype = ctNone; } @@ -243,21 +261,6 @@ eServiceMP3::eServiceMP3(const char *filename): m_filename(filename), m_pump(eAp else m_error_message = "GStreamer can't open filesrc " + (std::string)filename + "!\n"; } - else if ( sourceinfo.is_streaming ) - { - source = gst_element_factory_make ("neonhttpsrc", "http-source"); - if (source) - g_object_set (G_OBJECT (source), "automatic-redirect", TRUE, NULL); - else - m_error_message = "GStreamer plugin neonhttpsrc not available!\n"; - } - else - { - int track = atoi(filename+18); - eDebug("play audio CD track #%i",track); - if (track > 0) - g_object_set (G_OBJECT (source), "track", track, NULL); - } if ( sourceinfo.is_video ) { /* filesrc -> mpegdemux -> | queue_audio -> dvbaudiosink -- cgit v1.2.3 From c8ef71e5f906e3898e767e485d96611d8860c21c Mon Sep 17 00:00:00 2001 From: Andreas Oberritter Date: Mon, 3 Nov 2008 16:57:21 +0100 Subject: Don't block key '5' on keyboard. '5' should never be blocked because it is essential for many functions. Also it is unclear why both 0x35 and 0x7E codes are supposed to be generated by 'mute'. Until this is resolved, unblocking '5' is the best solution from a user's POV. --- lib/driver/rcconsole.cpp | 1 - 1 file changed, 1 deletion(-) (limited to 'lib') diff --git a/lib/driver/rcconsole.cpp b/lib/driver/rcconsole.cpp index 05fbec1d..bcce5601 100644 --- a/lib/driver/rcconsole.cpp +++ b/lib/driver/rcconsole.cpp @@ -70,7 +70,6 @@ void eRCConsoleDriver::keyPressed(int) code = -1; else switch(code) { - case 0x35: // mute case 0x7E: // mute, einfg, entf case 0x7F: // backspace code = -1; -- cgit v1.2.3 From ae6c45c7c6ae6c03fd535e40ddb5ce63ffa8e1f8 Mon Sep 17 00:00:00 2001 From: Fraxinas Date: Mon, 3 Nov 2008 20:48:01 +0100 Subject: save backup network configuration files and not only gui stuff from enigma2 and change the default backup location to harddisk (on behalf of sat-man) --- lib/python/Plugins/SystemPlugins/ConfigurationBackup/plugin.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'lib') diff --git a/lib/python/Plugins/SystemPlugins/ConfigurationBackup/plugin.py b/lib/python/Plugins/SystemPlugins/ConfigurationBackup/plugin.py index 9ff8c05d..7a918da6 100644 --- a/lib/python/Plugins/SystemPlugins/ConfigurationBackup/plugin.py +++ b/lib/python/Plugins/SystemPlugins/ConfigurationBackup/plugin.py @@ -104,8 +104,8 @@ class BackupSetup(Screen): self.list = [ ] self["config"] = ConfigList(self.list) self.backup = ConfigSubsection() - self.backup.type = ConfigSelection(choices = [("settings", _("only /etc/enigma2 directory")), ("var", _("/var directory")), ("skin", _("/usr/share/enigma2 directory"))], default="settings") - self.backup.location = ConfigSelection(choices = [("usb", _("USB Stick")), ("cf", _("CF Drive")), ("hdd", _("Harddisk"))]) + self.backup.type = ConfigSelection(choices = [("settings", _("enigma2 and network")), ("var", _("/var directory")), ("skin", _("/usr/share/enigma2 directory"))], default="settings") + self.backup.location = ConfigSelection(choices = [("hdd", _("Harddisk")), ("usb", _("USB Stick")), ("cf", _("CF Drive"))]) self.list.append(getConfigListEntry(_("Backup Mode"), self.backup.type)) self.list.append(getConfigListEntry(_("Backup Location"), self.backup.location)) @@ -132,7 +132,7 @@ class BackupSetup(Screen): self.path = BackupPath[self.backup.location.value] if self.backup.type.value == "settings": print "Backup Mode: Settings" - self.session.open(Console, title = "Backup running", cmdlist = ["tar -czvf " + self.path + "/" + str(dt) + "_settings_backup.tar.gz /etc/enigma2/"]) + self.session.open(Console, title = "Backup running", cmdlist = ["tar -czvf " + self.path + "/" + str(dt) + "_settings_backup.tar.gz /etc/enigma2/ /etc/network/interfaces /etc/wpa_supplicant.conf"]) elif self.backup.type.value == "var": print "Backup Mode: var" self.session.open(Console, title = "Backup running", cmdlist = [ "tar -czvf " + self.path + "/" + str(dt) + "_var_backup.tar.gz /var/"]) -- cgit v1.2.3 From f3078c3363b29cdb8ccf05cbb251392966137977 Mon Sep 17 00:00:00 2001 From: ghost Date: Mon, 3 Nov 2008 21:05:52 +0100 Subject: dont do SDT update when tuned to wrong transponder --- lib/dvb/pmt.cpp | 12 ++++++++++-- lib/dvb/scan.h | 1 + 2 files changed, 11 insertions(+), 2 deletions(-) (limited to 'lib') diff --git a/lib/dvb/pmt.cpp b/lib/dvb/pmt.cpp index 6082bf4a..692428d7 100644 --- a/lib/dvb/pmt.cpp +++ b/lib/dvb/pmt.cpp @@ -524,8 +524,15 @@ void eDVBServicePMTHandler::SDTScanEvent(int event) eDebug("no channel list"); else { - m_dvb_scan->insertInto(db, true); - eDebug("sdt update done!"); + eDVBChannelID chid; + m_reference.getChannelID(chid); + if (chid == m_dvb_scan->getCurrentChannelID()) + { + m_dvb_scan->insertInto(db, true); + eDebug("sdt update done!"); + } + else + eDebug("ignore sdt update data.... incorrect transponder tuned!!!"); } break; } @@ -605,6 +612,7 @@ int eDVBServicePMTHandler::tune(eServiceReferenceDVB &ref, int use_decode_demux, if (ref.path.empty()) { + m_dvb_scan = 0; m_dvb_scan = new eDVBScan(m_channel, true, false); m_dvb_scan->connectEvent(slot(*this, &eDVBServicePMTHandler::SDTScanEvent), m_scan_event_connection); } diff --git a/lib/dvb/scan.h b/lib/dvb/scan.h index 95e3fb39..38ac784f 100644 --- a/lib/dvb/scan.h +++ b/lib/dvb/scan.h @@ -110,6 +110,7 @@ public: void getLastServiceName(std::string &name); RESULT getFrontend(ePtr &); RESULT getCurrentTransponder(ePtr &); + eDVBChannelID getCurrentChannelID() { return m_chid_current; } }; #endif -- cgit v1.2.3 From 229de887b7ee74c1ed0eae8a7bbabd6a758756eb Mon Sep 17 00:00:00 2001 From: ghost Date: Tue, 4 Nov 2008 11:30:56 +0100 Subject: more failsave code, remove imho unneeded invalidate calls --- lib/python/Screens/TimerEdit.py | 47 ++++++++++++++++++----------------------- 1 file changed, 20 insertions(+), 27 deletions(-) (limited to 'lib') diff --git a/lib/python/Screens/TimerEdit.py b/lib/python/Screens/TimerEdit.py index 67c49cc5..800bab33 100644 --- a/lib/python/Screens/TimerEdit.py +++ b/lib/python/Screens/TimerEdit.py @@ -117,41 +117,40 @@ class TimerEditList(Screen): self.session.nav.RecordTimer.timeChanged(t) self.refill() self.updateState() - + + def removeAction(self, descr): + actions = self["actions"].actions + if descr in actions: + del actions[descr] + def updateState(self): cur = self["timerlist"].getCurrent() if cur: if self.key_red_choice != self.DELETE: self["actions"].actions.update({"red":self.removeTimerQuestion}) self["key_red"].setText(_("Delete")) - self["key_red"].instance.invalidate() self.key_red_choice = self.DELETE if cur.disabled and (self.key_yellow_choice != self.ENABLE): self["actions"].actions.update({"yellow":self.toggleDisabledState}) self["key_yellow"].setText(_("Enable")) - self["key_yellow"].instance.invalidate() self.key_yellow_choice = self.ENABLE elif cur.isRunning() and not cur.repeated and (self.key_yellow_choice != self.EMPTY): - del self["actions"].actions["yellow"] + self.removeAction("yellow") self["key_yellow"].setText(" ") - self["key_yellow"].instance.invalidate() self.key_yellow_choice = self.EMPTY elif ((not cur.isRunning())or cur.repeated ) and (not cur.disabled) and (self.key_yellow_choice != self.DISABLE): self["actions"].actions.update({"yellow":self.toggleDisabledState}) self["key_yellow"].setText(_("Disable")) - self["key_yellow"].instance.invalidate() self.key_yellow_choice = self.DISABLE else: if self.key_red_choice != self.EMPTY: - del self["actions"].actions["red"] + self.removeAction("red") self["key_red"].setText(" ") - self["key_red"].instance.invalidate() self.key_red_choice = self.EMPTY if self.key_yellow_choice != self.EMPTY: - del self["actions"].actions["yellow"] + self.removeAction("yellow") self["key_yellow"].setText(" ") - self["key_yellow"].instance.invalidate() self.key_yellow_choice = self.EMPTY showCleanup = True @@ -164,15 +163,12 @@ class TimerEditList(Screen): if showCleanup and (self.key_blue_choice != self.CLEANUP): self["actions"].actions.update({"blue":self.cleanupQuestion}) self["key_blue"].setText(_("Cleanup")) - self["key_blue"].instance.invalidate() self.key_blue_choice = self.CLEANUP elif (not showCleanup) and (self.key_blue_choice != self.EMPTY): - del self["actions"].actions["blue"] + self.removeAction("blue") self["key_blue"].setText(" ") - self["key_blue"].instance.invalidate() self.key_blue_choice = self.EMPTY - def fillTimerList(self): del self.list[:] @@ -399,23 +395,25 @@ class TimerSanityConflict(Screen): def down(self): self["list"].instance.moveSelection(self["list"].instance.moveDown) self["timer2"].moveToIndex(self["list"].getSelectedIndex()) - + + def removeAction(self, descr): + actions = self["actions"].actions + if descr in actions: + del actions[descr] + def updateState(self): if self.timer[0] is not None: if self.timer[0].disabled and self.key_green_choice != self.ENABLE: self["actions"].actions.update({"green":self.toggleTimer1}) self["key_green"].setText(_("Enable")) - self["key_green"].instance.invalidate() self.key_green_choice = self.ENABLE elif self.timer[0].isRunning() and not timer[0].repeated and self.key_green_choice != self.EMPTY: - del self["actions"].actions["green"] + self.removeAction("green") self["key_green"].setText(" ") - self["key_green"].instance.invalidate() self.key_green_choice = self.EMPTY elif (not self.timer[0].isRunning() or self.timer[0].repeated ) and self.key_green_choice != self.DISABLE: self["actions"].actions.update({"green":self.toggleTimer1}) self["key_green"].setText(_("Disable")) - self["key_green"].instance.invalidate() self.key_green_choice = self.DISABLE if len(self.timer) > 1: x = self["list"].getSelectedIndex() @@ -423,25 +421,20 @@ class TimerSanityConflict(Screen): if self.timer[x].disabled and self.key_blue_choice != self.ENABLE: self["actions"].actions.update({"blue":self.toggleTimer2}) self["key_blue"].setText(_("Enable")) - self["key_blue"].instance.invalidate() self.key_blue_choice = self.ENABLE elif self.timer[x].isRunning() and not timer[x].repeated and self.key_blue_choice != self.EMPTY: - del self["actions"].actions["blue"] + self.removeAction("blue") self["key_blue"].setText(" ") - self["key_blue"].instance.invalidate() self.key_blue_choice = self.EMPTY elif (not self.timer[x].isRunning() or self.timer[x].repeated ) and self.key_blue_choice != self.DISABLE: self["actions"].actions.update({"blue":self.toggleTimer2}) self["key_blue"].setText(_("Disable")) - self["key_blue"].instance.invalidate() self.key_blue_choice = self.DISABLE else: #FIXME.... this doesnt hide the buttons self.... just the text - del self["actions"].actions["yellow"] + self.removeAction("yellow") self["key_yellow"].setText(" ") - self["key_yellow"].instance.invalidate() self.key_yellow_choice = self.EMPTY - del self["actions"].actions["blue"] + self.removeAction("blue") self["key_blue"].setText(" ") - self["key_blue"].instance.invalidate() self.key_blue_choice = self.EMPTY -- cgit v1.2.3 From 61e2eca2450a20da4ecd5cc138058e221df9837f Mon Sep 17 00:00:00 2001 From: Fraxinas Date: Tue, 4 Nov 2008 15:27:06 +0100 Subject: implement blanking of dvd minus rw media --- lib/python/Plugins/Extensions/DVDBurn/DVDToolbox.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'lib') diff --git a/lib/python/Plugins/Extensions/DVDBurn/DVDToolbox.py b/lib/python/Plugins/Extensions/DVDBurn/DVDToolbox.py index 0c375129..d4e6a375 100644 --- a/lib/python/Plugins/Extensions/DVDBurn/DVDToolbox.py +++ b/lib/python/Plugins/Extensions/DVDBurn/DVDToolbox.py @@ -150,7 +150,7 @@ class DVDformatJob(Job): DVDformatTask(self) def retry(self): - self.tasks[0].args += [ "-force" ] + self.tasks[0].args += self.tasks[0].retryargs Job.retry(self) class DVDformatTaskPostcondition(Condition): @@ -174,6 +174,7 @@ class DVDformatTask(Task): self.setTool("/bin/dvd+rw-format") self.args += [ "/dev/" + harddiskmanager.getCD() ] self.end = 1100 + self.retryargs = [ ] def prepare(self): self.error = None @@ -181,7 +182,10 @@ class DVDformatTask(Task): def processOutputLine(self, line): if line.startswith("- media is already formatted"): self.error = self.ERROR_ALREADYFORMATTED - self.force = True + self.retryargs = [ "-force" ] + if line.startswith("- media is not blank"): + self.error = self.ERROR_ALREADYFORMATTED + self.retryargs = [ "-blank" ] if line.startswith(":-( mounted media doesn't appear to be"): self.error = self.ERROR_NOTWRITEABLE -- cgit v1.2.3 From 73e179bb7dfd67800dce39a383a269b2d871d180 Mon Sep 17 00:00:00 2001 From: Fraxinas Date: Tue, 4 Nov 2008 23:03:42 +0100 Subject: don't crash when exitting dvd image selection without selection --- lib/python/Plugins/Extensions/DVDBurn/TitleList.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'lib') diff --git a/lib/python/Plugins/Extensions/DVDBurn/TitleList.py b/lib/python/Plugins/Extensions/DVDBurn/TitleList.py index 600411ce..19380af4 100644 --- a/lib/python/Plugins/Extensions/DVDBurn/TitleList.py +++ b/lib/python/Plugins/Extensions/DVDBurn/TitleList.py @@ -207,10 +207,11 @@ class TitleList(Screen, HelpableScreen): self.session.openWithCallback(self.JobViewCB, JobView, job) def burnISO(self, path, scope): - job = Process.DVDisoJob(self.project, path) - job_manager.AddJob(job) - job_manager.in_background = False - self.session.openWithCallback(self.JobViewCB, JobView, job) + if path: + job = Process.DVDisoJob(self.project, path) + job_manager.AddJob(job) + job_manager.in_background = False + self.session.openWithCallback(self.JobViewCB, JobView, job) def JobViewCB(self, in_background): job_manager.in_background = in_background -- cgit v1.2.3 From a1404d58d60d5dc369e89cb98f239a83d447a986 Mon Sep 17 00:00:00 2001 From: Fraxinas Date: Wed, 5 Nov 2008 09:00:27 +0100 Subject: don't crash when background jobs fail and user presses red key --- lib/python/Components/Task.py | 1 + 1 file changed, 1 insertion(+) (limited to 'lib') diff --git a/lib/python/Components/Task.py b/lib/python/Components/Task.py index f249f711..b276438f 100644 --- a/lib/python/Components/Task.py +++ b/lib/python/Components/Task.py @@ -265,6 +265,7 @@ class JobManager: from Tools import Notifications if self.in_background: from Screens.TaskView import JobView + self.in_background = False Notifications.AddNotification(JobView, self.active_job) if problems: from Screens.MessageBox import MessageBox -- cgit v1.2.3 From 938a550b0874cd87f475a638551d7046f729d1bc Mon Sep 17 00:00:00 2001 From: Fraxinas Date: Wed, 5 Nov 2008 12:52:46 +0100 Subject: nastily pretend the dvd minus rw bruning error never happened --- lib/python/Plugins/Extensions/DVDBurn/Process.py | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) (limited to 'lib') diff --git a/lib/python/Plugins/Extensions/DVDBurn/Process.py b/lib/python/Plugins/Extensions/DVDBurn/Process.py index 7a03b7eb..9cca8f70 100644 --- a/lib/python/Plugins/Extensions/DVDBurn/Process.py +++ b/lib/python/Plugins/Extensions/DVDBurn/Process.py @@ -241,7 +241,11 @@ class WaitForResidentTasks(Task): class BurnTaskPostcondition(Condition): RECOVERABLE = True def check(self, task): - return task.error is None + if task.returncode == 0: + return True + elif task.error is None or task.error is task.ERROR_MINUSRWBUG: + return True + return False def getErrorMessage(self, task): return { @@ -257,7 +261,7 @@ class BurnTaskPostcondition(Condition): }[task.error] class BurnTask(Task): - ERROR_NOTWRITEABLE, ERROR_LOAD, ERROR_SIZE, ERROR_WRITE_FAILED, ERROR_DVDROM, ERROR_ISOFS, ERROR_FILETOOLARGE, ERROR_ISOTOOLARGE, ERROR_UNKNOWN = range(9) + ERROR_NOTWRITEABLE, ERROR_LOAD, ERROR_SIZE, ERROR_WRITE_FAILED, ERROR_DVDROM, ERROR_ISOFS, ERROR_FILETOOLARGE, ERROR_ISOTOOLARGE, ERROR_MINUSRWBUG, ERROR_UNKNOWN = range(10) def __init__(self, job, extra_args=[], tool="/bin/growisofs"): Task.__init__(self, job, job.name) self.weighting = 500 @@ -284,12 +288,17 @@ class BurnTask(Task): self.error = self.ERROR_NOTWRITEABLE if line.find("ASC=24h") != -1: self.error = self.ERROR_LOAD + if line.find("SK=5h/ASC=A8h/ACQ=04h") != -1: + self.error = self.ERROR_MINUSRWBUG else: self.error = self.ERROR_UNKNOWN print "BurnTask: unknown error %s" % line elif line.startswith(":-("): if line.find("No space left on device") != -1: self.error = self.ERROR_SIZE + elif self.error == self.ERROR_MINUSRWBUG: + print "*sigh* this is a known bug. we're simply gonna assume everything is fine." + self.postconditions = [] elif line.find("write failed") != -1: self.error = self.ERROR_WRITE_FAILED elif line.find("unable to open64(") != -1 and line.find(",O_RDONLY): No such file or directory") != -1: @@ -309,6 +318,11 @@ class BurnTask(Task): self.error = self.ERROR_FILETOOLARGE elif line.startswith("genisoimage: File too large."): self.error = self.ERROR_ISOTOOLARGE + + def setTool(self, tool): + self.cmd = tool + self.args = [tool] + self.global_preconditions.append(ToolExistsPrecondition()) class RemoveDVDFolder(Task): def __init__(self, job): -- cgit v1.2.3 From 317d39715811fcfab181641398b43582cdb4e22d Mon Sep 17 00:00:00 2001 From: ghost Date: Wed, 5 Nov 2008 13:05:08 +0100 Subject: also make in FD nonblocking --- lib/base/console.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'lib') diff --git a/lib/base/console.cpp b/lib/base/console.cpp index 5ca77d12..add87066 100644 --- a/lib/base/console.cpp +++ b/lib/base/console.cpp @@ -109,6 +109,7 @@ int eConsoleAppContainer::execute(const char *cmdline, const char * const argv[] // eDebug("pipe in = %d, out = %d, err = %d", fd[0], fd[1], fd[2]); + ::fcntl(fd[0], F_SETFL, O_NONBLOCK); ::fcntl(fd[1], F_SETFL, O_NONBLOCK); ::fcntl(fd[2], F_SETFL, O_NONBLOCK); in = eSocketNotifier::create(eApp, fd[0], eSocketNotifier::Read|eSocketNotifier::Priority|eSocketNotifier::Hungup ); -- cgit v1.2.3 From 8ab0666af66fdb08f955daa70b255a5841ea73fb Mon Sep 17 00:00:00 2001 From: Fraxinas Date: Wed, 5 Nov 2008 14:32:25 +0100 Subject: try to add dvdburn icon once again --- lib/python/Plugins/Extensions/DVDBurn/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/python/Plugins/Extensions/DVDBurn/Makefile.am b/lib/python/Plugins/Extensions/DVDBurn/Makefile.am index d5c558d1..cb65f56a 100644 --- a/lib/python/Plugins/Extensions/DVDBurn/Makefile.am +++ b/lib/python/Plugins/Extensions/DVDBurn/Makefile.am @@ -5,5 +5,5 @@ install_PYTHON = \ plugin.py \ DVDProject.py DVDTitle.py TitleCutter.py TitleList.py Process.py ProjectSettings.py DVDToolbox.py -install_DATA = *.xml *.jpg *.mpg *.mp2 +install_DATA = *.xml *.jpg *.mpg *.mp2 *.png -- cgit v1.2.3 From be092c47edfd4babfd3b4c5ea511710e6458343f Mon Sep 17 00:00:00 2001 From: Fraxinas Date: Wed, 5 Nov 2008 17:25:52 +0100 Subject: allow setting progress for current task from within resident task, implement rudimentary progress for mplextask in dvdburn (requires dvdauthor patch) --- lib/python/Components/Task.py | 12 ++++--- lib/python/Plugins/Extensions/DVDBurn/Process.py | 45 ++++++++++++++---------- 2 files changed, 33 insertions(+), 24 deletions(-) (limited to 'lib') diff --git a/lib/python/Components/Task.py b/lib/python/Components/Task.py index b276438f..9a768425 100644 --- a/lib/python/Components/Task.py +++ b/lib/python/Components/Task.py @@ -45,6 +45,7 @@ class Job(object): def addTask(self, task): task.job = self + task.task_progress_changed = self.task_progress_changed_CB self.tasks.append(task) def start(self, callback): @@ -70,7 +71,7 @@ class Job(object): else: print "still waiting for %d resident task(s) %s to finish" % (len(self.resident_tasks), str(self.resident_tasks)) else: - self.tasks[self.current_task].run(self.taskCallback, self.task_progress_changed_CB) + self.tasks[self.current_task].run(self.taskCallback) self.state_changed() def taskCallback(self, task, res, stay_resident = False): @@ -151,7 +152,7 @@ class Task(object): not_met.append(precondition) return not_met - def run(self, callback, task_progress_changed): + def run(self, callback): failed_preconditions = self.checkPreconditions(True) + self.checkPreconditions(False) if len(failed_preconditions): callback(self, failed_preconditions) @@ -159,7 +160,6 @@ class Task(object): self.prepare() self.callback = callback - self.task_progress_changed = task_progress_changed from enigma import eConsoleAppContainer self.container = eConsoleAppContainer() self.container.appClosed.append(self.processFinished) @@ -235,7 +235,8 @@ class Task(object): if progress < 0: progress = 0 self.__progress = progress - self.task_progress_changed() + if self.task_progress_changed: + self.task_progress_changed() progress = property(getProgress, setProgress) @@ -372,7 +373,8 @@ class ToolExistsPrecondition(Condition): return _("A required tool (%s) was not found.") % (self.realpath) class AbortedPostcondition(Condition): - pass + def getErrorMessage(self, task): + return "Cancelled upon user request" class ReturncodePostcondition(Condition): def check(self, task): diff --git a/lib/python/Plugins/Extensions/DVDBurn/Process.py b/lib/python/Plugins/Extensions/DVDBurn/Process.py index 9cca8f70..49054596 100644 --- a/lib/python/Plugins/Extensions/DVDBurn/Process.py +++ b/lib/python/Plugins/Extensions/DVDBurn/Process.py @@ -10,8 +10,8 @@ class png2yuvTask(Task): self.dumpFile = outputfile self.weighting = 15 - def run(self, callback, task_progress_changed): - Task.run(self, callback, task_progress_changed) + def run(self, callback): + Task.run(self, callback) self.container.stdoutAvail.remove(self.processStdout) self.container.dumpToFile(self.dumpFile) @@ -26,8 +26,8 @@ class mpeg2encTask(Task): self.inputFile = inputfile self.weighting = 25 - def run(self, callback, task_progress_changed): - Task.run(self, callback, task_progress_changed) + def run(self, callback): + Task.run(self, callback) self.container.readFromFile(self.inputFile) def processOutputLine(self, line): @@ -42,8 +42,8 @@ class spumuxTask(Task): self.dumpFile = outputfile self.weighting = 15 - def run(self, callback, task_progress_changed): - Task.run(self, callback, task_progress_changed) + def run(self, callback): + Task.run(self, callback) self.container.stdoutAvail.remove(self.processStdout) self.container.dumpToFile(self.dumpFile) self.container.readFromFile(self.inputFile) @@ -212,7 +212,7 @@ class RemoveESFiles(Task): class DVDAuthorTask(Task): def __init__(self, job): Task.__init__(self, job, "Authoring DVD") - self.weighting = 300 + self.weighting = 20 self.setTool("/usr/bin/dvdauthor") self.CWD = self.job.workspace self.args += ["-x", self.job.workspace+"/dvdauthor.xml"] @@ -222,6 +222,14 @@ class DVDAuthorTask(Task): print "[DVDAuthorTask] ", line[:-1] if not self.menupreview and line.startswith("STAT: Processing"): self.callback(self, [], stay_resident=True) + elif line.startswith("STAT: VOBU"): + try: + progress = int(line.split("MB")[0].split(" ")[-1]) + if progress: + self.job.mplextask.progress = progress + print "[DVDAuthorTask] update mplextask progress:", self.job.mplextask.progress, "of", self.job.mplextask.end + except: + print "couldn't set mux progress" class DVDAuthorFinalTask(Task): def __init__(self, job): @@ -233,7 +241,7 @@ class WaitForResidentTasks(Task): def __init__(self, job): Task.__init__(self, job, "waiting for dvdauthor to finalize") - def run(self, callback, task_progress_changed): + def run(self, callback): print "waiting for %d resident task(s) %s to finish..." % (len(self.job.resident_tasks),str(self.job.resident_tasks)) if self.job.resident_tasks == 0: callback(self, []) @@ -334,23 +342,24 @@ class RemoveDVDFolder(Task): class CheckDiskspaceTask(Task): def __init__(self, job): Task.__init__(self, job, "Checking free space") - totalsize = 50*1024*1024 # require an extra safety 50 MB + totalsize = 0 # require an extra safety 50 MB maxsize = 0 for title in job.project.titles: titlesize = title.estimatedDiskspace if titlesize > maxsize: maxsize = titlesize totalsize += titlesize diskSpaceNeeded = totalsize + maxsize + job.estimateddvdsize = totalsize / 1024 / 1024 + totalsize += 50*1024*1024 # require an extra safety 50 MB self.global_preconditions.append(DiskspacePrecondition(diskSpaceNeeded)) self.weighting = 5 - def run(self, callback, task_progress_changed): + def run(self, callback): failed_preconditions = self.checkPreconditions(True) + self.checkPreconditions(False) if len(failed_preconditions): callback(self, failed_preconditions) return self.callback = callback - self.task_progress_changed = task_progress_changed Task.processFinished(self, 0) class PreviewTask(Task): @@ -361,9 +370,8 @@ class PreviewTask(Task): self.path = path self.weighting = 10 - def run(self, callback, task_progress_changed): + def run(self, callback): self.callback = callback - self.task_progress_changed = task_progress_changed if self.job.menupreview: self.previewProject() else: @@ -439,9 +447,8 @@ class ImagePrepareTask(Task): self.job = job self.Menus = job.Menus - def run(self, callback, task_progress_changed): + def run(self, callback): self.callback = callback - self.task_progress_changed = task_progress_changed # we are doing it this weird way so that the TaskView Screen actually pops up before the spinner comes from enigma import eTimer self.delayTimer = eTimer() @@ -451,7 +458,7 @@ class ImagePrepareTask(Task): def conduct(self): try: from ImageFont import truetype - from Image import open as Image_open + from Image import open as Image_open s = self.job.project.settings self.Menus.im_bg_orig = Image_open(s.menubg.getValue()) if self.Menus.im_bg_orig.size != (self.Menus.imgwidth, self.Menus.imgheight): @@ -475,9 +482,8 @@ class MenuImageTask(Task): self.menubgpngfilename = menubgpngfilename self.highlightpngfilename = highlightpngfilename - def run(self, callback, task_progress_changed): + def run(self, callback): self.callback = callback - self.task_progress_changed = task_progress_changed try: import ImageDraw, Image, os s = self.job.project.settings @@ -712,7 +718,8 @@ class DVDJob(Job): title_filename = self.workspace + "/dvd_title_%d.mpg" % (self.i+1) LinkTS(self, title.inputfile, link_name) demux = DemuxTask(self, link_name) - MplexTask(self, outputfile=title_filename, demux_task=demux) + self.mplextask = MplexTask(self, outputfile=title_filename, demux_task=demux) + self.mplextask.end = self.estimateddvdsize RemoveESFiles(self, demux) WaitForResidentTasks(self) PreviewTask(self, self.workspace + "/dvd/VIDEO_TS/") -- cgit v1.2.3 From 58ee3c3a218a0aa5d45e9c465eb9759375b4129c Mon Sep 17 00:00:00 2001 From: Felix Domke Date: Mon, 17 Nov 2008 00:08:58 +0100 Subject: By Anders Holst: * I have checked the effect on DM800 of the margin before GOP:s, introduced by the "timing bugs" patch and needed for DM7025. As was previously noted, the margins are not needed on DM800. Fortunately it turns out also not to have any significant adverse effects: When jumping back or forward I expected some flickering, but there are none at all! There is only one small effect as far as I have found: When a cut list is used, there are somewhat more flickering at the cut points than without the margins. Since there are flickering also without the margins, this may be considered a less serious effect. If you consider this effect serious enough though, or think that it is cleaner to separate the code for DM7025 and DM800 since the margin is needed for one but not the other, then I can try to produce such a patch. Otherwise I suggest to wait with this. * In the original timing bugs patch there were a fix to stop playback after the last OUT cut. It did this by setting the size of the next source span to 0. But this turned out not to be a good idea: It seems that playback stops immediately when the next size is set to zero, and not when the buffer is used up. Therefore playback may stop some seconds before the actual end. If instead a jump is made to the last position in the file and a non-zero size is used there, then for some reason it plays up the whole buffer. Don't ask me why it is like this. A modification to this effect is anyway included below. * Rewind did not work at all for HD movies on DM800. The picture just freezes. It is because HD movies have another sequence at beginning of frames than normal movies. There is a rather simple fix, looking for both HD and normal sequences, in the trickmode playback code. (If the HD movie sequence condition seems complicated, it is because it has to make sure not to be accidentally triggered by normal movies.) --- lib/dvb/dvb.cpp | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) (limited to 'lib') diff --git a/lib/dvb/dvb.cpp b/lib/dvb/dvb.cpp index 6edf9e87..7b05feb4 100644 --- a/lib/dvb/dvb.cpp +++ b/lib/dvb/dvb.cpp @@ -985,9 +985,9 @@ int eDVBChannelFilePush::filterRecordData(const unsigned char *_data, int len, s unsigned char *ts = data + ts_offset; int pid = ((ts[1] << 8) | ts[2]) & 0x1FFF; - if ((d[3] == 0) && (m_pid == pid)) /* picture start */ + if ((d[3] == 0 || d[3] == 0x09 && d[-1] == 0 && (ts[1] & 0x40)) && (m_pid == pid)) /* picture start */ { - int picture_type = (d[5] >> 3) & 7; + int picture_type = (d[3]==0 ? (d[5] >> 3) & 7 : (d[4] >> 5) + 1); d += 4; // eDebug("%d-frame at %d, offset in TS packet: %d, pid=%04x", picture_type, offset, offset % 188, pid); @@ -1413,10 +1413,13 @@ void eDVBChannel::getNextSourceSpan(off_t current_offset, size_t bytes_read, off start = current_offset; size = max; } else { - off_t tmp = align(m_source_span.rbegin()->second, blocksize); - if (current_offset == tmp) { - start = current_offset; - size = 0; + off_t tmp2, tmp = align(m_source_span.rbegin()->second, blocksize); + pts_t len; + getLength(len); + m_tstools.getOffset(tmp2, len, 1); + if (current_offset == tmp || current_offset == tmp2) { + start = tmp2; + size = max; } else { start = tmp - align(512*1024, blocksize); size = align(512*1024, blocksize); -- cgit v1.2.3 From 638123eeac3874577ca1454c3420b15dd4ccdbc0 Mon Sep 17 00:00:00 2001 From: Felix Domke Date: Mon, 17 Nov 2008 00:10:33 +0100 Subject: By Anders Holst: only record MPEG-4 I-frames to ap-file --- lib/dvb/pvrparse.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/dvb/pvrparse.cpp b/lib/dvb/pvrparse.cpp index 35ba9091..dfc62249 100644 --- a/lib/dvb/pvrparse.cpp +++ b/lib/dvb/pvrparse.cpp @@ -370,7 +370,8 @@ int eMPEGStreamParserTS::processPacket(const unsigned char *pkt, off_t offset) eDebug("Sequence header but no valid PTS value."); } - if (pkt[3] == 0x09) /* MPEG4 AVC unit access delimiter */ + if (pkt[3] == 0x09 && /* MPEG4 AVC unit access delimiter */ + (pkt[4] >> 5) == 0) /* and I-frame */ { if (ptsvalid) { -- cgit v1.2.3 From 401863ab3c54d849a22cd0fb677dec487621ab97 Mon Sep 17 00:00:00 2001 From: Felix Domke Date: Mon, 17 Nov 2008 15:35:42 +0100 Subject: lock on pids only if video startcode is in a pes header --- lib/dvb/dvb.cpp | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) (limited to 'lib') diff --git a/lib/dvb/dvb.cpp b/lib/dvb/dvb.cpp index 7b05feb4..8afa70db 100644 --- a/lib/dvb/dvb.cpp +++ b/lib/dvb/dvb.cpp @@ -1031,10 +1031,20 @@ int eDVBChannelFilePush::filterRecordData(const unsigned char *_data, int len, s } } else if ((d[3] & 0xF0) == 0xE0) /* video stream */ { - if (m_pid != pid) + /* verify that this is actually a PES header, not just some ES data */ + if (ts[1] & 0x40) /* PUSI set */ { - eDebug("now locked to pid %04x", pid); - m_pid = pid; + int payload_start = 4; + if (ts[3] & 0x20) /* adaptation field present */ + payload_start += ts[4] + 1; /* skip AF */ + if (payload_start == (offset%184)) /* the 00 00 01 should be directly at the payload start, otherwise it's not a PES header */ + { + if (m_pid != pid) + { + eDebug("now locked to pid %04x (%02x %02x %02x %02x)", pid, ts[0], ts[1], ts[2], ts[3]); + m_pid = pid; + } + } } // m_pid = 0x6e; d += 4; -- cgit v1.2.3 From 6c8fd4b0dc66959d22e2b3612f00076699664756 Mon Sep 17 00:00:00 2001 From: Felix Domke Date: Mon, 17 Nov 2008 15:36:15 +0100 Subject: remove ugly SIGUSR1 loop once again --- lib/base/filepush.cpp | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) (limited to 'lib') diff --git a/lib/base/filepush.cpp b/lib/base/filepush.cpp index 1999707f..e99e956c 100644 --- a/lib/base/filepush.cpp +++ b/lib/base/filepush.cpp @@ -260,12 +260,9 @@ void eFilePushThread::stop() // fixmee.. here we need a better solution to ensure // that the thread context take notice of the signal // even when no syscall is in progress - while(!sendSignal(SIGUSR1)) - { - eDebug("send SIGUSR1 to thread context"); - usleep(5000); // wait msek - } - kill(); + eDebug("if enigma hangs here, the filepush thread is non-responsive. FIX THAT DAMN THREAD."); + sendSignal(SIGUSR1); + kill(0); } void eFilePushThread::pause() -- cgit v1.2.3 From 588010098dbcc24b82ea736feec6b6056cffd2e3 Mon Sep 17 00:00:00 2001 From: Felix Domke Date: Mon, 17 Nov 2008 15:36:45 +0100 Subject: a few more debugging to debug the pvr state stuff --- lib/service/servicedvb.cpp | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'lib') diff --git a/lib/service/servicedvb.cpp b/lib/service/servicedvb.cpp index 954a3964..a873576d 100644 --- a/lib/service/servicedvb.cpp +++ b/lib/service/servicedvb.cpp @@ -1286,6 +1286,7 @@ RESULT eDVBServicePlay::pause(ePtr &ptr) RESULT eDVBServicePlay::setSlowMotion(int ratio) { + eDebug("eDVBServicePlay::setSlowMotion(%d)", ratio); if (m_decoder) return m_decoder->setSlowMotion(ratio); else @@ -1294,6 +1295,7 @@ RESULT eDVBServicePlay::setSlowMotion(int ratio) RESULT eDVBServicePlay::setFastForward(int ratio) { + eDebug("eDVBServicePlay::setFastForward(%d)", ratio); int skipmode, ffratio; if (ratio > 8) @@ -1354,6 +1356,7 @@ RESULT eDVBServicePlay::getLength(pts_t &len) RESULT eDVBServicePlay::pause() { + eDebug("eDVBServicePlay::pause"); if (!m_is_paused && m_decoder) { m_is_paused = 1; @@ -1364,6 +1367,7 @@ RESULT eDVBServicePlay::pause() RESULT eDVBServicePlay::unpause() { + eDebug("eDVBServicePlay::unpause"); if (m_is_paused && m_decoder) { m_is_paused = 0; -- cgit v1.2.3 From a9efd192b545113282c7c7891a231570f49f27e6 Mon Sep 17 00:00:00 2001 From: Felix Domke Date: Mon, 17 Nov 2008 17:19:06 +0100 Subject: fix comment, don't memmem over end of packet --- lib/dvb/dvb.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'lib') diff --git a/lib/dvb/dvb.cpp b/lib/dvb/dvb.cpp index 3ad086de..07cc611b 100644 --- a/lib/dvb/dvb.cpp +++ b/lib/dvb/dvb.cpp @@ -973,7 +973,7 @@ int eDVBChannelFilePush::filterRecordData(const unsigned char *_data, int len, s } #endif -#if 1 /* not yet */ +#if 1 /* This codepath is required on Broadcom-based Dreamboxes (DM800, DM8000) and strips away non-I-frames. */ if (!m_iframe_search) return len; @@ -982,7 +982,7 @@ int eDVBChannelFilePush::filterRecordData(const unsigned char *_data, int len, s // eDebug("filterRecordData, size=%d (mod 188=%d), first byte is %02x", len, len %188, data[0]); unsigned char *d = data; - while ((d = (unsigned char*)memmem(d, data + len - d, "\x00\x00\x01", 3))) + while ((d + 3 < data + len) && (d = (unsigned char*)memmem(d, data + len - d, "\x00\x00\x01", 3))) { int offset = d - data; int ts_offset = offset - offset % 188; /* offset to the start of TS packet */ @@ -1054,7 +1054,6 @@ int eDVBChannelFilePush::filterRecordData(const unsigned char *_data, int len, s d += 4; } else d += 4; /* ignore */ - } if (m_iframe_state == 1) -- cgit v1.2.3 From 67a09e962e20c1a2becd8b8699b542779941b6e7 Mon Sep 17 00:00:00 2001 From: Felix Domke Date: Mon, 17 Nov 2008 17:19:39 +0100 Subject: performance fix: don't redraw if in/out list is the same --- lib/python/Components/Renderer/PositionGauge.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'lib') diff --git a/lib/python/Components/Renderer/PositionGauge.py b/lib/python/Components/Renderer/PositionGauge.py index 5fa8c356..3f93d82e 100644 --- a/lib/python/Components/Renderer/PositionGauge.py +++ b/lib/python/Components/Renderer/PositionGauge.py @@ -50,9 +50,10 @@ class PositionGauge(Renderer): return self.__cutlist def setCutlist(self, cutlist): - self.__cutlist = cutlist - if self.instance is not None: - self.instance.setInOutList(cutlist) + if self.__cutlist != cutlist: + self.__cutlist = cutlist + if self.instance is not None: + self.instance.setInOutList(cutlist) cutlist = property(getCutlist, setCutlist) -- cgit v1.2.3 From 39bd88513deee4a1a00993212c76e503fdd47fe7 Mon Sep 17 00:00:00 2001 From: Felix Domke Date: Mon, 17 Nov 2008 22:54:04 +0100 Subject: fix typo --- lib/dvb/dvb.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/dvb/dvb.cpp b/lib/dvb/dvb.cpp index 07cc611b..28012e7a 100644 --- a/lib/dvb/dvb.cpp +++ b/lib/dvb/dvb.cpp @@ -1041,7 +1041,7 @@ int eDVBChannelFilePush::filterRecordData(const unsigned char *_data, int len, s int payload_start = 4; if (ts[3] & 0x20) /* adaptation field present */ payload_start += ts[4] + 1; /* skip AF */ - if (payload_start == (offset%184)) /* the 00 00 01 should be directly at the payload start, otherwise it's not a PES header */ + if (payload_start == (offset%188)) /* the 00 00 01 should be directly at the payload start, otherwise it's not a PES header */ { if (m_pid != pid) { -- cgit v1.2.3 From 3aedbe22cf74b72ad0c3e2bc1869e914701e6574 Mon Sep 17 00:00:00 2001 From: Felix Domke Date: Tue, 18 Nov 2008 00:39:59 +0100 Subject: experimental dm8000 recording fix, doesn't belong here --- lib/python/Components/Renderer/FrontpanelLed.py | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/python/Components/Renderer/FrontpanelLed.py b/lib/python/Components/Renderer/FrontpanelLed.py index 7bb584e5..cd329b56 100644 --- a/lib/python/Components/Renderer/FrontpanelLed.py +++ b/lib/python/Components/Renderer/FrontpanelLed.py @@ -6,15 +6,24 @@ class FrontpanelLed(Element): Element.__init__(self) def changed(self, *args, **kwargs): - if self.source.value: + if self.source.value or 1: pattern = 0x55555555 + pattern_4bit = 0x84fc8c04 speed = 20 else: pattern = 0 + pattern_4bit = 0xffffffff speed = 1 try: open("/proc/stb/fp/led0_pattern", "w").write("%08x" % pattern) + except IOError: + pass + try: + open("/proc/stb/fp/led_pattern", "w").write("%08x" % pattern_4bit) + except IOError: + pass + try: open("/proc/stb/fp/led_pattern_speed", "w").write("%d" % speed) except IOError: pass -- cgit v1.2.3 From 4f7990ff2a55874b9eb65e3c9cd47dacb9f76deb Mon Sep 17 00:00:00 2001 From: Felix Domke Date: Tue, 18 Nov 2008 00:40:19 +0100 Subject: rework decoder states --- lib/dvb/decoder.cpp | 208 ++++++++++++++++------------------ lib/dvb/decoder.h | 42 +++++-- lib/dvb/idvb.h | 33 ++---- lib/python/Screens/InfoBarGenerics.py | 17 ++- lib/service/iservice.h | 2 + lib/service/servicedvb.cpp | 40 ++++--- lib/service/servicedvb.h | 1 + 7 files changed, 177 insertions(+), 166 deletions(-) (limited to 'lib') diff --git a/lib/dvb/decoder.cpp b/lib/dvb/decoder.cpp index 6ad39225..66b923a6 100644 --- a/lib/dvb/decoder.cpp +++ b/lib/dvb/decoder.cpp @@ -39,7 +39,7 @@ DEFINE_REF(eDVBAudio); eDVBAudio::eDVBAudio(eDVBDemux *demux, int dev) - :m_demux(demux), m_dev(dev), m_is_freezed(0) + :m_demux(demux), m_dev(dev) { char filename[128]; #if HAVE_DVB_API_VERSION < 3 @@ -194,7 +194,7 @@ int eDVBAudio::startPid(int pid, int type) */ } - eDebugNoNewLine("AUDIO_SET_BYPASS - "); + eDebugNoNewLine("AUDIO_SET_BYPASS(%d) - ", bypass); if (::ioctl(m_fd, AUDIO_SET_BYPASS_MODE, bypass) < 0) eDebug("failed (%m)"); else @@ -240,28 +240,20 @@ void eDVBAudio::flush() void eDVBAudio::freeze() { - if (!m_is_freezed) - { - eDebugNoNewLine("AUDIO_PAUSE - "); - if (::ioctl(m_fd, AUDIO_PAUSE) < 0) - eDebug("failed (%m)"); - else - eDebug("ok"); - m_is_freezed=1; - } + eDebugNoNewLine("AUDIO_PAUSE - "); + if (::ioctl(m_fd, AUDIO_PAUSE) < 0) + eDebug("failed (%m)"); + else + eDebug("ok"); } void eDVBAudio::unfreeze() { - if (m_is_freezed) - { - eDebugNoNewLine("AUDIO_CONTINUE - "); - if (::ioctl(m_fd, AUDIO_CONTINUE) < 0) - eDebug("failed (%m)"); - else - eDebug("ok"); - m_is_freezed=0; - } + eDebugNoNewLine("AUDIO_CONTINUE - "); + if (::ioctl(m_fd, AUDIO_CONTINUE) < 0) + eDebug("failed (%m)"); + else + eDebug("ok"); } void eDVBAudio::setChannel(int channel) @@ -299,7 +291,7 @@ eDVBAudio::~eDVBAudio() DEFINE_REF(eDVBVideo); eDVBVideo::eDVBVideo(eDVBDemux *demux, int dev) - :m_demux(demux), m_dev(dev), m_is_slow_motion(0), m_is_fast_forward(0), m_is_freezed(0) + :m_demux(demux), m_dev(dev) { char filename[128]; #if HAVE_DVB_API_VERSION < 3 @@ -461,34 +453,25 @@ void eDVBVideo::flush() void eDVBVideo::freeze() { - if (!m_is_freezed) - { - eDebugNoNewLine("VIDEO_FREEZE - "); - if (::ioctl(m_fd, VIDEO_FREEZE) < 0) - eDebug("failed (%m)"); - else - eDebug("ok"); - m_is_freezed=1; - } + eDebugNoNewLine("VIDEO_FREEZE - "); + if (::ioctl(m_fd, VIDEO_FREEZE) < 0) + eDebug("failed (%m)"); + else + eDebug("ok"); } void eDVBVideo::unfreeze() { - if (m_is_freezed) - { - eDebugNoNewLine("VIDEO_CONTINUE - "); - if (::ioctl(m_fd, VIDEO_CONTINUE) < 0) - eDebug("failed (%m)"); - else - eDebug("ok"); - m_is_freezed=0; - } + eDebugNoNewLine("VIDEO_CONTINUE - "); + if (::ioctl(m_fd, VIDEO_CONTINUE) < 0) + eDebug("failed (%m)"); + else + eDebug("ok"); } int eDVBVideo::setSlowMotion(int repeat) { - eDebugNoNewLine("VIDEO_SLOWMOTION - "); - m_is_slow_motion = repeat; + eDebugNoNewLine("VIDEO_SLOWMOTION(%d) - ", repeat); int ret = ::ioctl(m_fd, VIDEO_SLOWMOTION, repeat); if (ret < 0) eDebug("failed(%m)"); @@ -499,8 +482,7 @@ int eDVBVideo::setSlowMotion(int repeat) int eDVBVideo::setFastForward(int skip) { - eDebugNoNewLine("VIDEO_FAST_FORWARD - "); - m_is_fast_forward = skip; + eDebugNoNewLine("VIDEO_FAST_FORWARD(%d) - ", skip); int ret = ::ioctl(m_fd, VIDEO_FAST_FORWARD, skip); if (ret < 0) eDebug("failed(%m)"); @@ -527,11 +509,6 @@ int eDVBVideo::getPTS(pts_t &now) eDVBVideo::~eDVBVideo() { - if (m_is_slow_motion) - setSlowMotion(0); - if (m_is_fast_forward) - setFastForward(0); - unfreeze(); if (m_fd >= 0) ::close(m_fd); if (m_fd_demux >= 0) @@ -750,14 +727,14 @@ int eTSMPEGDecoder::setState() { int res = 0; - int noaudio = m_is_sm || m_is_ff || m_is_trickmode; + int noaudio = (m_state != statePlay) && (m_state != statePause); int nott = noaudio; /* actually same conditions */ if ((noaudio && m_audio) || (!m_audio && !noaudio)) - m_changed |= changeAudio; + m_changed |= changeAudio | changeState; if ((nott && m_text) || (!m_text && !nott)) - m_changed |= changeText; + m_changed |= changeText | changeState; bool changed = !!m_changed; #if HAVE_DVB_API_VERSION < 3 @@ -900,6 +877,39 @@ int eTSMPEGDecoder::setState() m_changed &= ~changeText; } #endif + + if (m_changed & changeState) + { + /* play, slowmotion, fast-forward */ + int state_table[6][4] = + { + /* [stateStop] = */ {0, 0, 0}, + /* [statePause] = */ {0, 0, 0}, + /* [statePlay] = */ {1, 0, 0}, + /* [stateDecoderFastForward] = */ {1, 0, m_ff_sm_ratio}, + /* [stateHighspeedFastForward] = */ {1, 0, 1}, + /* [stateSlowMotion] = */ {1, m_ff_sm_ratio, 0} + }; + int *s = state_table[m_state]; + if (m_video) + { + m_video->setSlowMotion(s[1]); + m_video->setFastForward(s[2]); + if (s[0]) + m_video->unfreeze(); + else + m_video->freeze(); + } + if (m_audio) + { + if (s[0]) + m_audio->unfreeze(); + else + m_audio->freeze(); + } + m_changed &= ~changeState; + } + if (changed && !m_video && m_audio && m_radio_pic.length()) showSinglePic(m_radio_pic.c_str()); @@ -946,7 +956,7 @@ eTSMPEGDecoder::eTSMPEGDecoder(eDVBDemux *demux, int decoder) { demux->connectEvent(slot(*this, &eTSMPEGDecoder::demux_event), m_demux_event_conn); CONNECT(m_showSinglePicTimer->timeout, eTSMPEGDecoder::finishShowSinglePic); - m_is_ff = m_is_sm = m_is_trickmode = 0; + m_state = stateStop; } eTSMPEGDecoder::~eTSMPEGDecoder() @@ -1028,82 +1038,61 @@ RESULT eTSMPEGDecoder::setSyncMaster(int who) return -1; } -RESULT eTSMPEGDecoder::start() -{ - RESULT r; - r = setState(); - if (r) - return r; - return unfreeze(); -} - - /* preroll is start in freezed mode. */ -RESULT eTSMPEGDecoder::preroll() +RESULT eTSMPEGDecoder::set() { return setState(); } -RESULT eTSMPEGDecoder::freeze(int cont) -{ - if (m_video) - m_video->freeze(); - - if (m_audio) - m_audio->freeze(); - - return 0; -} - -RESULT eTSMPEGDecoder::unfreeze() -{ - if (m_video) - m_video->unfreeze(); - - if (m_audio) - m_audio->unfreeze(); - - return 0; -} - -RESULT eTSMPEGDecoder::setSinglePictureMode(int when) +RESULT eTSMPEGDecoder::play() { - return -1; + if (m_state == statePlay) + return 0; + m_state = statePlay; + m_changed |= changeState; + return setState(); } -RESULT eTSMPEGDecoder::setPictureSkipMode(int what) +RESULT eTSMPEGDecoder::pause() { - return -1; + if (m_state == statePause) + return 0; + m_state = statePause; + m_changed |= changeState; + return setState(); } RESULT eTSMPEGDecoder::setFastForward(int frames_to_skip) { - m_is_ff = frames_to_skip != 0; + if ((m_state == stateDecoderFastForward) && (m_ff_sm_ratio == frames_to_skip)) + return 0; - setState(); - unfreeze(); // audio might be restarted and still in preroll (freezed) state. + m_state = stateDecoderFastForward; + m_ff_sm_ratio = frames_to_skip; + m_changed |= changeState; + return setState(); - if (m_video) - return m_video->setFastForward(frames_to_skip); - else - return -1; +// return m_video->setFastForward(frames_to_skip); } RESULT eTSMPEGDecoder::setSlowMotion(int repeat) { - m_is_sm = repeat != 0; + if ((m_state == stateSlowMotion) && (m_ff_sm_ratio == repeat)) + return 0; - setState(); - unfreeze(); // audio might be restarted and still in preroll (freezed) state. - - if (m_video) - return m_video->setSlowMotion(repeat); - else - return -1; + m_state = stateSlowMotion; + m_ff_sm_ratio = repeat; + m_changed |= changeState; + return setState(); } -RESULT eTSMPEGDecoder::setZoom(int what) +RESULT eTSMPEGDecoder::setTrickmode() { - return -1; + if (m_state == stateTrickmode) + return 0; + + m_state = stateTrickmode; + m_changed |= changeState; + return setState(); } RESULT eTSMPEGDecoder::flush() @@ -1127,13 +1116,6 @@ void eTSMPEGDecoder::demux_event(int event) } } -RESULT eTSMPEGDecoder::setTrickmode(int what) -{ - m_is_trickmode = what; - setState(); - return 0; -} - RESULT eTSMPEGDecoder::getPTS(int what, pts_t &pts) { if (what == 0) /* auto */ diff --git a/lib/dvb/decoder.h b/lib/dvb/decoder.h index 05e07ef9..04501fe6 100644 --- a/lib/dvb/decoder.h +++ b/lib/dvb/decoder.h @@ -119,10 +119,12 @@ private: changeVideo = 1, changeAudio = 2, changePCR = 4, - changeText = 8 + changeText = 8, + changeState = 16, }; int m_changed, m_decoder; - int m_is_ff, m_is_sm, m_is_trickmode; + int m_state; + int m_ff_sm_ratio; int setState(); ePtr m_demux_event_conn; ePtr m_video_event_conn; @@ -148,17 +150,33 @@ public: RESULT setSyncPCR(int pcrpid); RESULT setTextPID(int textpid); RESULT setSyncMaster(int who); - RESULT start(); - RESULT preroll(); - RESULT freeze(int cont); - RESULT unfreeze(); - RESULT setSinglePictureMode(int when); - RESULT setPictureSkipMode(int what); - RESULT setFastForward(int frames_to_skip); - RESULT setSlowMotion(int repeat); - RESULT setZoom(int what); + + /* + The following states exist: + + - stop: data source closed, no playback + - pause: data source active, decoder paused + - play: data source active, decoder consuming + - decoder fast forward: data source linear, decoder drops frames + - trickmode, highspeed reverse: data source fast forwards / reverses, decoder just displays frames as fast as it can + - slow motion: decoder displays frames multiple times + */ + enum { + stateStop, + statePause, + statePlay, + stateDecoderFastForward, + stateTrickmode, + stateSlowMotion + }; + RESULT set(); /* just apply settings, keep state */ + RESULT play(); /* -> play */ + RESULT pause(); /* -> pause */ + RESULT setFastForward(int frames_to_skip); /* -> decoder fast forward */ + RESULT setSlowMotion(int repeat); /* -> slow motion **/ + RESULT setTrickmode(); /* -> highspeed fast forward */ + RESULT flush(); - RESULT setTrickmode(int what); RESULT showSinglePic(const char *filename); RESULT setRadioPic(const std::string &filename); /* what 0=auto, 1=video, 2=audio. */ diff --git a/lib/dvb/idvb.h b/lib/dvb/idvb.h index cda05894..bd1c7035 100644 --- a/lib/dvb/idvb.h +++ b/lib/dvb/idvb.h @@ -662,37 +662,24 @@ public: /** Set Sync mode to either audio or video master */ virtual RESULT setSyncMaster(int who)=0; - /** Apply settings with starting video */ - virtual RESULT start()=0; - /** Apply settings but don't start yet */ - virtual RESULT preroll()=0; + /** Apply settings but don't change state */ + virtual RESULT set()=0; + /* all those apply settings, then transition to the given state */ - /** Freeze frame. Either continue decoding (without display) or halt. */ - virtual RESULT freeze(int cont)=0; - /** Continue after freeze. */ - virtual RESULT unfreeze()=0; + /** play */ + virtual RESULT play()=0; + /** Freeze frame. */ + virtual RESULT pause()=0; /** fast forward by skipping frames. 0 is disabled, 2 is twice-the-speed, ... */ virtual RESULT setFastForward(int skip=0)=0; - // stop on .. Picture - enum { spm_I, spm_Ref, spm_Any }; - /** Stop on specific decoded picture. For I-Frame display. */ - virtual RESULT setSinglePictureMode(int when)=0; - - enum { pkm_B, pkm_PB }; - /** Fast forward by skipping either B or P/B pictures */ - virtual RESULT setPictureSkipMode(int what)=0; - /** Slow Motion by repeating pictures */ virtual RESULT setSlowMotion(int repeat)=0; - - enum { zoom_Normal, zoom_PanScan, zoom_Letterbox, zoom_Fullscreen }; - /** Set Zoom. mode *must* be fitting. */ - virtual RESULT setZoom(int what)=0; - - virtual RESULT setTrickmode(int what) = 0; + /** Display any complete data as fast as possible */ + virtual RESULT setTrickmode()=0; + virtual RESULT getPTS(int what, pts_t &pts) = 0; virtual RESULT showSinglePic(const char *filename) = 0; diff --git a/lib/python/Screens/InfoBarGenerics.py b/lib/python/Screens/InfoBarGenerics.py index cdaa2c1e..409018de 100644 --- a/lib/python/Screens/InfoBarGenerics.py +++ b/lib/python/Screens/InfoBarGenerics.py @@ -779,12 +779,21 @@ class InfoBarSeek: print "not pauseable." state = self.SEEK_STATE_PLAY - oldstate = self.seekstate self.seekstate = state - for i in range(3): - if oldstate[i] != self.seekstate[i]: - (self.session.nav.pause, pauseable.setFastForward, pauseable.setSlowMotion)[i](self.seekstate[i]) + if pauseable is not None: + if self.seekstate[0]: + print "resolved to PAUSE" + pauseable.pause() + elif self.seekstate[1]: + print "resolved to FAST FORWARD" + pauseable.setFastForward(self.seekstate[1]) + elif self.seekstate[2]: + print "resolved to SLOW MOTION" + pauseable.setSlowMotion(self.seekstate[2]) + else: + print "resolved to PLAY" + pauseable.unpause() for c in self.onPlayStateChanged: c(self.seekstate) diff --git a/lib/service/iservice.h b/lib/service/iservice.h index 02fc4508..e27752a2 100644 --- a/lib/service/iservice.h +++ b/lib/service/iservice.h @@ -392,6 +392,8 @@ class iPauseableService: public iObject ~iPausableService(); #endif public: + + /* this will set the *state* directly. So just call a SINGLE function of those at a time. */ virtual RESULT pause()=0; virtual RESULT unpause()=0; diff --git a/lib/service/servicedvb.cpp b/lib/service/servicedvb.cpp index 7e6c0337..af3ab206 100644 --- a/lib/service/servicedvb.cpp +++ b/lib/service/servicedvb.cpp @@ -1281,7 +1281,9 @@ RESULT eDVBServicePlay::pause(ePtr &ptr) RESULT eDVBServicePlay::setSlowMotion(int ratio) { + assert(ratio); /* The API changed: instead of calling setSlowMotion(0), call play! */ eDebug("eDVBServicePlay::setSlowMotion(%d)", ratio); + setFastForward_internal(0); if (m_decoder) return m_decoder->setSlowMotion(ratio); else @@ -1291,6 +1293,12 @@ RESULT eDVBServicePlay::setSlowMotion(int ratio) RESULT eDVBServicePlay::setFastForward(int ratio) { eDebug("eDVBServicePlay::setFastForward(%d)", ratio); + assert(ratio); + return setFastForward_internal(ratio); +} + +RESULT eDVBServicePlay::setFastForward_internal(int ratio) +{ int skipmode, ffratio; if (ratio > 8) @@ -1323,7 +1331,12 @@ RESULT eDVBServicePlay::setFastForward(int ratio) if (!m_decoder) return -1; - return m_decoder->setFastForward(ffratio); + if (ffratio == 0) + return 0; + else if (ffratio != 1) + return m_decoder->setFastForward(ffratio); + else + return m_decoder->setTrickmode(); } RESULT eDVBServicePlay::seek(ePtr &ptr) @@ -1352,10 +1365,10 @@ RESULT eDVBServicePlay::getLength(pts_t &len) RESULT eDVBServicePlay::pause() { eDebug("eDVBServicePlay::pause"); - if (!m_is_paused && m_decoder) + setFastForward_internal(0); + if (m_decoder) { - m_is_paused = 1; - return m_decoder->freeze(0); + return m_decoder->pause(); } else return -1; } @@ -1363,10 +1376,10 @@ RESULT eDVBServicePlay::pause() RESULT eDVBServicePlay::unpause() { eDebug("eDVBServicePlay::unpause"); - if (m_is_paused && m_decoder) + setFastForward_internal(0); + if (m_decoder) { - m_is_paused = 0; - return m_decoder->unfreeze(); + return m_decoder->play(); } else return -1; } @@ -1448,9 +1461,8 @@ RESULT eDVBServicePlay::getPlayPosition(pts_t &pos) RESULT eDVBServicePlay::setTrickmode(int trick) { - if (m_decoder) - m_decoder->setTrickmode(trick); - return 0; + /* currently unimplemented */ + return -1; } RESULT eDVBServicePlay::isCurrentlySeekable() @@ -1761,7 +1773,7 @@ RESULT eDVBServicePlay::selectTrack(unsigned int i) { int ret = selectAudioStream(i); - if (m_decoder->start()) + if (m_decoder->play()) return -5; return ret; @@ -2486,12 +2498,12 @@ void eDVBServicePlay::updateDecoder() m_teletext_parser->start(program.textPid); if (!m_is_primary) - m_decoder->setTrickmode(1); + m_decoder->setTrickmode(); if (m_is_paused) - m_decoder->preroll(); + m_decoder->pause(); else - m_decoder->start(); + m_decoder->play(); if (vpid > 0 && vpid < 0x2000) ; diff --git a/lib/service/servicedvb.h b/lib/service/servicedvb.h index d19b92d6..c19e1ed5 100644 --- a/lib/service/servicedvb.h +++ b/lib/service/servicedvb.h @@ -218,6 +218,7 @@ private: int m_current_audio_stream; int selectAudioStream(int n = -1); + RESULT setFastForward_internal(int ratio); /* timeshift */ ePtr m_record; -- cgit v1.2.3 From 979cdde152f5998de6593f1d3b6998bb224d5c97 Mon Sep 17 00:00:00 2001 From: Felix Domke Date: Fri, 13 Feb 2009 01:13:59 +0100 Subject: fix merge --- lib/dvb/decoder.cpp | 1 - 1 file changed, 1 deletion(-) (limited to 'lib') diff --git a/lib/dvb/decoder.cpp b/lib/dvb/decoder.cpp index f73dbdd9..6f0ead65 100644 --- a/lib/dvb/decoder.cpp +++ b/lib/dvb/decoder.cpp @@ -295,7 +295,6 @@ eDVBAudio::~eDVBAudio() DEFINE_REF(eDVBVideo); eDVBVideo::eDVBVideo(eDVBDemux *demux, int dev) -<<<<<<< HEAD:lib/dvb/decoder.cpp : m_demux(demux), m_dev(dev), m_width(-1), m_height(-1), m_framerate(-1), m_aspect(-1), m_progressive(-1) { -- cgit v1.2.3 From dce87891f204f8e1f7151c4a3ba00b9dd048e795 Mon Sep 17 00:00:00 2001 From: Felix Domke Date: Fri, 13 Feb 2009 03:41:57 +0100 Subject: - While recording, collect startcodes and save them into ".sc"-files - this allows finding iframes for fast forward/reverse more easily - when in fast forward, strictly just output good (=complete iframes) data (this might break dm7025, we will fix this later) - draw smaller, fixed-size bar in position gauge --- lib/dvb/decoder.cpp | 4 +- lib/dvb/demux.cpp | 28 ++- lib/dvb/demux.h | 2 +- lib/dvb/dvb.cpp | 56 +++-- lib/dvb/idemux.h | 2 +- lib/dvb/pvrparse.cpp | 302 ++++++++++++++++++++------ lib/dvb/pvrparse.h | 26 ++- lib/dvb/tstools.cpp | 70 +++++- lib/dvb/tstools.h | 2 + lib/gui/epositiongauge.cpp | 2 +- lib/python/Components/Converter/StringList.py | 6 + lib/python/Components/Renderer/Listbox.py | 4 + lib/service/servicedvb.cpp | 18 +- lib/service/servicedvbrecord.cpp | 10 +- 14 files changed, 416 insertions(+), 116 deletions(-) (limited to 'lib') diff --git a/lib/dvb/decoder.cpp b/lib/dvb/decoder.cpp index 6f0ead65..a4cffb77 100644 --- a/lib/dvb/decoder.cpp +++ b/lib/dvb/decoder.cpp @@ -1071,7 +1071,9 @@ RESULT eTSMPEGDecoder::setAC3Delay(int delay) } eTSMPEGDecoder::eTSMPEGDecoder(eDVBDemux *demux, int decoder) - :m_demux(demux), m_changed(0), m_decoder(decoder), m_video_clip_fd(-1), m_showSinglePicTimer(eTimer::create(eApp)) + : m_demux(demux), + m_vpid(-1), m_vtype(-1), m_apid(-1), m_atype(-1), m_pcrpid(-1), m_textpid(-1), + m_changed(0), m_decoder(decoder), m_video_clip_fd(-1), m_showSinglePicTimer(eTimer::create(eApp)) { demux->connectEvent(slot(*this, &eTSMPEGDecoder::demux_event), m_demux_event_conn); CONNECT(m_showSinglePicTimer->timeout, eTSMPEGDecoder::finishShowSinglePic); diff --git a/lib/dvb/demux.cpp b/lib/dvb/demux.cpp index 810b10a5..918ecec6 100644 --- a/lib/dvb/demux.cpp +++ b/lib/dvb/demux.cpp @@ -402,9 +402,10 @@ class eDVBRecordFileThread: public eFilePushThread { public: eDVBRecordFileThread(); - void setTimingPID(int pid); + void setTimingPID(int pid, int type); - void saveTimingInformation(const std::string &filename); + void startSaveMetaInformation(const std::string &filename); + void stopSaveMetaInformation(); int getLastPTS(pts_t &pts); protected: int filterRecordData(const unsigned char *data, int len, size_t ¤t_span_remaining); @@ -422,14 +423,19 @@ eDVBRecordFileThread::eDVBRecordFileThread() m_current_offset = 0; } -void eDVBRecordFileThread::setTimingPID(int pid) +void eDVBRecordFileThread::setTimingPID(int pid, int type) { - m_ts_parser.setPid(pid); + m_ts_parser.setPid(pid, type); } -void eDVBRecordFileThread::saveTimingInformation(const std::string &filename) +void eDVBRecordFileThread::startSaveMetaInformation(const std::string &filename) { - m_stream_info.save(filename.c_str()); + m_stream_info.startSave(filename.c_str()); +} + +void eDVBRecordFileThread::stopSaveMetaInformation() +{ + m_stream_info.stopSave(); } int eDVBRecordFileThread::getLastPTS(pts_t &pts) @@ -520,6 +526,9 @@ RESULT eDVBTSRecorder::start() ::ioctl(m_source_fd, DMX_START); #endif + + if (m_target_filename != "") + m_thread->startSaveMetaInformation(m_target_filename); m_thread->start(m_source_fd, m_target_fd); m_running = 1; @@ -553,11 +562,11 @@ RESULT eDVBTSRecorder::removePID(int pid) return 0; } -RESULT eDVBTSRecorder::setTimingPID(int pid) +RESULT eDVBTSRecorder::setTimingPID(int pid, int type) { if (m_running) return -1; - m_thread->setTimingPID(pid); + m_thread->setTimingPID(pid, type); return 0; } @@ -590,8 +599,7 @@ RESULT eDVBTSRecorder::stop() close(m_source_fd); m_source_fd = -1; - if (m_target_filename != "") - m_thread->saveTimingInformation(m_target_filename + ".ap"); + m_thread->stopSaveMetaInformation(); return 0; } diff --git a/lib/dvb/demux.h b/lib/dvb/demux.h index 14501b98..7a697d49 100644 --- a/lib/dvb/demux.h +++ b/lib/dvb/demux.h @@ -94,7 +94,7 @@ public: RESULT addPID(int pid); RESULT removePID(int pid); - RESULT setTimingPID(int pid); + RESULT setTimingPID(int pid, int type); RESULT setTargetFD(int fd); RESULT setTargetFilename(const char *filename); diff --git a/lib/dvb/dvb.cpp b/lib/dvb/dvb.cpp index c320fc78..4bbed519 100644 --- a/lib/dvb/dvb.cpp +++ b/lib/dvb/dvb.cpp @@ -974,7 +974,7 @@ int eDVBChannelFilePush::filterRecordData(const unsigned char *_data, int len, s } #endif -#if 1 /* This codepath is required on Broadcom-based Dreamboxes (DM800, DM8000) and strips away non-I-frames. */ +#if 0 if (!m_iframe_search) return len; @@ -1272,6 +1272,21 @@ void eDVBChannel::getNextSourceSpan(off_t current_offset, size_t bytes_read, off eDebug("getNextSourceSpan, current offset is %08llx, m_skipmode_m = %d!", current_offset, m_skipmode_m); current_offset += align(m_skipmode_m, blocksize); + + if (m_skipmode_m) + { + eDebug("we are at %llx, and we try to find the iframe here:", current_offset); + size_t iframe_len; + off_t iframe_start = current_offset; + + if (m_tstools.findIFrame(iframe_start, iframe_len, (m_skipmode_m < 0) ? -1 : +1)) + eDebug("failed"); + else + { + current_offset = align(iframe_start, blocksize); + max = align(iframe_len, blocksize); + } + } while (!m_cue->m_seek_requests.empty()) { @@ -1348,6 +1363,10 @@ void eDVBChannel::getNextSourceSpan(off_t current_offset, size_t bytes_read, off eDebug("get offset for pts=%lld failed!", pts); continue; } + + size_t iframe_len; + /* try to align to iframe */ + m_tstools.findIFrame(offset, iframe_len, pts < 0 ? -1 : 1); eDebug("ok, resolved skip (rel: %d, diff %lld), now at %08llx", relative, pts, offset); current_offset = align(offset, blocksize); /* in case tstools return non-aligned offset */ @@ -1417,30 +1436,23 @@ void eDVBChannel::getNextSourceSpan(off_t current_offset, size_t bytes_read, off } } - if (m_source_span.empty()) { - if ((current_offset < -m_skipmode_m) && (m_skipmode_m < 0)) - { - eDebug("reached SOF"); - m_skipmode_m = 0; - m_pvr_thread->sendEvent(eFilePushThread::evtUser); - } + if ((current_offset < -m_skipmode_m) && (m_skipmode_m < 0)) + { + eDebug("reached SOF"); + m_skipmode_m = 0; + m_pvr_thread->sendEvent(eFilePushThread::evtUser); + } + + if (m_source_span.empty()) + { start = current_offset; size = max; - } else { - off_t tmp2, tmp = align(m_source_span.rbegin()->second, blocksize); - pts_t len; - getLength(len); - m_tstools.getOffset(tmp2, len, 1); - if (current_offset == tmp || current_offset == tmp2) { - start = tmp2; - size = max; - } else { - start = tmp - align(512*1024, blocksize); - size = align(512*1024, blocksize); - } + eDebug("NO CUESHEET. (%08llx, %d)", start, size); + } else + { + start = current_offset; + size = 0; } - - eDebug("END OF CUESHEET. (%08llx, %d)", start, size); return; } diff --git a/lib/dvb/idemux.h b/lib/dvb/idemux.h index 9432afb6..e92b1e75 100644 --- a/lib/dvb/idemux.h +++ b/lib/dvb/idemux.h @@ -30,7 +30,7 @@ public: virtual RESULT addPID(int pid) = 0; virtual RESULT removePID(int pid) = 0; - virtual RESULT setTimingPID(int pid) = 0; + virtual RESULT setTimingPID(int pid, int type) = 0; virtual RESULT setTargetFD(int fd) = 0; /* for saving additional meta data. */ diff --git a/lib/dvb/pvrparse.cpp b/lib/dvb/pvrparse.cpp index 71cbd602..1393bf77 100644 --- a/lib/dvb/pvrparse.cpp +++ b/lib/dvb/pvrparse.cpp @@ -6,9 +6,36 @@ #error no byte order defined! #endif -int eMPEGStreamInformation::save(const char *filename) +eMPEGStreamInformation::eMPEGStreamInformation() + : m_structure_cache_valid(0), m_structure_read(0), m_structure_write(0) { - FILE *f = fopen(filename, "wb"); +} + +eMPEGStreamInformation::~eMPEGStreamInformation() +{ + if (m_structure_read) + fclose(m_structure_read); + if (m_structure_write) + fclose(m_structure_write); +} + +int eMPEGStreamInformation::startSave(const char *filename) +{ + m_filename = filename; + m_structure_write = fopen((m_filename + ".sc").c_str(), "wb"); + return 0; +} + +int eMPEGStreamInformation::stopSave(void) +{ + if (m_structure_write) + { + fclose(m_structure_write); + m_structure_write = 0; + } + if (m_filename == "") + return -1; + FILE *f = fopen((m_filename + ".ap").c_str(), "wb"); if (!f) return -1; @@ -31,7 +58,11 @@ int eMPEGStreamInformation::save(const char *filename) int eMPEGStreamInformation::load(const char *filename) { - FILE *f = fopen(filename, "rb"); + m_filename = filename; + if (m_structure_read) + fclose(m_structure_read); + m_structure_read = fopen((std::string(m_filename) + ".sc").c_str(), "rb"); + FILE *f = fopen((std::string(m_filename) + ".ap").c_str(), "rb"); if (!f) return -1; m_access_points.clear(); @@ -284,6 +315,117 @@ int eMPEGStreamInformation::getNextAccessPoint(pts_t &ts, const pts_t &start, in return 0; } +void eMPEGStreamInformation::writeStructureEntry(off_t offset, structure_data data) +{ + unsigned long long d[2]; +#if BYTE_ORDER == BIG_ENDIAN + d[0] = offset; + d[1] = data; +#else + d[0] = bswap_64(offset); + d[1] = bswap_64(data); +#endif + if (m_structure_write) + fwrite(d, sizeof(d), 1, m_structure_write); +} + +int eMPEGStreamInformation::getStructureEntry(off_t &offset, unsigned long long &data, int get_next) +{ + if (!m_structure_read) + { + eDebug("getStructureEntry failed because of no m_structure_read"); + return -1; + } + + const int struture_cache_entries = sizeof(m_structure_cache) / 16; + if ((!m_structure_cache_valid) || ((off_t)m_structure_cache[0] > offset) || ((off_t)m_structure_cache[(struture_cache_entries - (get_next ? 2 : 1)) * 2] <= offset)) + { + fseek(m_structure_read, 0, SEEK_END); + int l = ftell(m_structure_read); + unsigned long long d[2]; + const int entry_size = sizeof d; + + /* do a binary search */ + int count = l / entry_size; + int i = 0; + + while (count) + { + int step = count >> 1; + + fseek(m_structure_read, (i + step) * entry_size, SEEK_SET); + if (!fread(d, 1, entry_size, m_structure_read)) + { + eDebug("read error at entry %d", i); + return -1; + } + +#if BYTE_ORDER != BIG_ENDIAN + d[0] = bswap_64(d[0]); + d[1] = bswap_64(d[1]); +#endif +// eDebug("%d: %08llx > %llx", i, d[0], d[1]); + + if (d[0] < (unsigned long long)offset) + { + i += step + 1; + count -= step + 1; + } else + count = step; + } + + eDebug("found %d", i); + + /* put that in the middle */ + i -= struture_cache_entries / 2; + if (i < 0) + i = 0; + eDebug("cache starts at %d", i); + fseek(m_structure_read, i * entry_size, SEEK_SET); + int num = fread(m_structure_cache, entry_size, struture_cache_entries, m_structure_read); + eDebug("%d entries", num); + for (i = 0; i < struture_cache_entries; ++i) + { + if (i < num) + { +#if BYTE_ORDER != BIG_ENDIAN + m_structure_cache[i * 2] = bswap_64(m_structure_cache[i * 2]); + m_structure_cache[i * 2 + 1] = bswap_64(m_structure_cache[i * 2 + 1]); +#endif + } else + { + m_structure_cache[i * 2] = 0x7fffffffffffffffULL; /* fill with harmless content */ + m_structure_cache[i * 2 + 1] = 0; + } + } + m_structure_cache_valid = 1; + } + + int i = 0; + while ((off_t)m_structure_cache[i * 2] <= offset) + { + ++i; + if (i == struture_cache_entries) + { + eDebug("structure data consistency fail!, we are looking for %llx, but last entry is %llx", offset, m_structure_cache[i*2-2]); + return -1; + } + } + if (!i) + { + eDebug("structure data (first entry) consistency fail!"); + return -1; + } + + if (!get_next) + --i; + +// eDebug("[%d] looked for %llx, found %llx=%llx", sizeof offset, offset, m_structure_cache[i * 2], m_structure_cache[i * 2 + 1]); + offset = m_structure_cache[i * 2]; + data = m_structure_cache[i * 2 + 1]; + return 0; +} + eMPEGStreamParserTS::eMPEGStreamParserTS(eMPEGStreamInformation &streaminfo): m_streaminfo(streaminfo), m_pktptr(0), m_pid(-1), m_need_next_packet(0), m_skip(0), m_last_pts_valid(0) { } @@ -293,16 +435,15 @@ int eMPEGStreamParserTS::processPacket(const unsigned char *pkt, off_t offset) if (!wantPacket(pkt)) eWarning("something's wrong."); - const unsigned char *end = pkt + 188; + const unsigned char *end = pkt + 188, *begin = pkt; - if (!(pkt[3] & 0x10)) - { - eWarning("[TSPARSE] PUSI set but no payload."); - return 0; - } + int pusi = !!(pkt[1] & 0x40); - if (pkt[3] & 0x20) // adaption field present? - pkt += pkt[4] + 4 + 1; /* skip adaption field and header */ + if (!(pkt[3] & 0x10)) /* no payload? */ + return 0; + + if (pkt[3] & 0x20) // adaptation field present? + pkt += pkt[4] + 4 + 1; /* skip adaptation field and header */ else pkt += 4; /* skip header */ @@ -311,78 +452,96 @@ int eMPEGStreamParserTS::processPacket(const unsigned char *pkt, off_t offset) eWarning("[TSPARSE] dropping huge adaption field"); return 0; } - - // ok, we now have the start of the payload, aligned with the PES packet start. - if (pkt[0] || pkt[1] || (pkt[2] != 1)) - { - eWarning("broken startcode"); - return 0; - } - - + pts_t pts = 0; int ptsvalid = 0; - if (pkt[7] & 0x80) // PTS present? + if (pusi) { - pts = ((unsigned long long)(pkt[ 9]&0xE)) << 29; - pts |= ((unsigned long long)(pkt[10]&0xFF)) << 22; - pts |= ((unsigned long long)(pkt[11]&0xFE)) << 14; - pts |= ((unsigned long long)(pkt[12]&0xFF)) << 7; - pts |= ((unsigned long long)(pkt[13]&0xFE)) >> 1; - ptsvalid = 1; - - m_last_pts = pts; - m_last_pts_valid = 1; - -#if 0 - int sec = pts / 90000; - int frm = pts % 90000; - int min = sec / 60; - sec %= 60; - int hr = min / 60; - min %= 60; - int d = hr / 24; - hr %= 24; + // ok, we now have the start of the payload, aligned with the PES packet start. + if (pkt[0] || pkt[1] || (pkt[2] != 1)) + { + eWarning("broken startcode"); + return 0; + } + + if (pkt[7] & 0x80) // PTS present? + { + pts = ((unsigned long long)(pkt[ 9]&0xE)) << 29; + pts |= ((unsigned long long)(pkt[10]&0xFF)) << 22; + pts |= ((unsigned long long)(pkt[11]&0xFE)) << 14; + pts |= ((unsigned long long)(pkt[12]&0xFF)) << 7; + pts |= ((unsigned long long)(pkt[13]&0xFE)) >> 1; + ptsvalid = 1; + + m_last_pts = pts; + m_last_pts_valid = 1; + + #if 0 + int sec = pts / 90000; + int frm = pts % 90000; + int min = sec / 60; + sec %= 60; + int hr = min / 60; + min %= 60; + int d = hr / 24; + hr %= 24; + + eDebug("pts: %016llx %d:%02d:%02d:%02d:%05d", pts, d, hr, min, sec, frm); + #endif + } - eDebug("pts: %016llx %d:%02d:%02d:%02d:%05d", pts, d, hr, min, sec, frm); -#endif + /* advance to payload */ + pkt += pkt[8] + 9; } - - /* advance to payload */ - pkt += pkt[8] + 9; - /* sometimes, there are zeros before the startcode. */ while (pkt < (end-4)) - if (pkt[0] || pkt[1] || pkt[2]) - break; - else - pkt++; - - /* if startcode found */ -// eDebug("%02x %02x %02x %02x", pkt[0], pkt[1], pkt[2], pkt[3]); - if (!(pkt[0] || pkt[1] || (pkt[2] != 1))) { - if (pkt[3] == 0xb3) /* sequence header */ + int pkt_offset = pkt - begin; + if (!(pkt[0] || pkt[1] || (pkt[2] != 1))) { - if (ptsvalid) +// eDebug("SC %02x %02x %02x %02x, %02x", pkt[0], pkt[1], pkt[2], pkt[3], pkt[4]); + int sc = pkt[3]; + + if (m_streamtype == 0) /* mpeg2 */ { - m_streaminfo.m_access_points[offset] = pts; -// eDebug("Sequence header at %llx, pts %llx", offset, pts); - } else - /*eDebug("Sequence header but no valid PTS value.")*/; - } + if ((sc == 0x00) || (sc == 0xb3) || (sc == 0xb8)) /* picture, sequence, group start code */ + { + unsigned long long data = sc | (pkt[4] << 8) | (pkt[5] << 16) | (pkt[6] << 24); + m_streaminfo.writeStructureEntry(offset + pkt_offset, data & 0xFFFFFFFFULL); + } + if (pkt[3] == 0xb3) /* sequence header */ + { + if (ptsvalid) + { + m_streaminfo.m_access_points[offset] = pts; + // eDebug("Sequence header at %llx, pts %llx", offset, pts); + } else + /*eDebug("Sequence header but no valid PTS value.")*/; + } + } - if (pkt[3] == 0x09 && /* MPEG4 AVC unit access delimiter */ - (pkt[4] >> 5) == 0) /* and I-frame */ - { - if (ptsvalid) + if (m_streamtype == 1) /* H.264 */ { - m_streaminfo.m_access_points[offset] = pts; -// eDebug("MPEG4 AVC UAD at %llx, pts %llx", offset, pts); - } else - /*eDebug("MPEG4 AVC UAD but no valid PTS value.")*/; + if (sc == 0x09) + { + /* store image type */ + unsigned long long data = sc | (pkt[4] << 8); + m_streaminfo.writeStructureEntry(offset + pkt_offset, data); + } + if (pkt[3] == 0x09 && /* MPEG4 AVC NAL unit access delimiter */ + (pkt[4] >> 5) == 0) /* and I-frame */ + { + if (ptsvalid) + { + m_streaminfo.m_access_points[offset] = pts; + // eDebug("MPEG4 AVC UAD at %llx, pts %llx", offset, pts); + } else + /*eDebug("MPEG4 AVC UAD but no valid PTS value.")*/; + } + } } + ++pkt; } return 0; } @@ -405,7 +564,7 @@ inline int eMPEGStreamParserTS::wantPacket(const unsigned char *hdr) const if (hdr[1] & 0x40) /* pusi set: yes. */ return 1; - return 0; + return m_streamtype == 0; /* we need all packets for MPEG2, but only PUSI packets for H.264 */ } void eMPEGStreamParserTS::parseData(off_t offset, const void *data, unsigned int len) @@ -520,10 +679,11 @@ void eMPEGStreamParserTS::parseData(off_t offset, const void *data, unsigned int } } -void eMPEGStreamParserTS::setPid(int _pid) +void eMPEGStreamParserTS::setPid(int _pid, int type) { m_pktptr = 0; m_pid = _pid; + m_streamtype = type; } int eMPEGStreamParserTS::getLastPTS(pts_t &last_pts) diff --git a/lib/dvb/pvrparse.h b/lib/dvb/pvrparse.h index 20d33470..28c0314a 100644 --- a/lib/dvb/pvrparse.h +++ b/lib/dvb/pvrparse.h @@ -12,6 +12,8 @@ class eMPEGStreamInformation { public: + eMPEGStreamInformation(); + ~eMPEGStreamInformation(); /* we order by off_t here, since the timestamp may */ /* wrap around. */ /* we only record sequence start's pts values here. */ @@ -23,7 +25,8 @@ public: /* these are non-fixed up pts value (like m_access_points), just used to accelerate stuff. */ std::multimap m_pts_to_offset; - int save(const char *filename); + int startSave(const char *filename); + int stopSave(void); int load(const char *filename); /* recalculates timestampDeltas */ @@ -46,6 +49,23 @@ public: int getNextAccessPoint(pts_t &ts, const pts_t &start, int direction); bool empty(); + + typedef unsigned long long structure_data; + /* this is usually: + sc | (other_information << 8) + but is really specific to the used video encoder. + */ + void writeStructureEntry(off_t offset, structure_data data); + + /* get a structure entry at given offset (or previous one, if no exact match was found). + optionall, return next element. Offset will be returned. this allows you to easily + get previous and next structure elements. */ + int getStructureEntry(off_t &offset, unsigned long long &data, int get_next); + + std::string m_filename; + int m_structure_cache_valid; + unsigned long long m_structure_cache[1024]; + FILE *m_structure_read, *m_structure_write; }; /* Now we define the parser's state: */ @@ -54,7 +74,7 @@ class eMPEGStreamParserTS public: eMPEGStreamParserTS(eMPEGStreamInformation &streaminfo); void parseData(off_t offset, const void *data, unsigned int len); - void setPid(int pid); + void setPid(int pid, int streamtype); int getLastPTS(pts_t &last_pts); private: eMPEGStreamInformation &m_streaminfo; @@ -62,7 +82,7 @@ private: int m_pktptr; int processPacket(const unsigned char *pkt, off_t offset); inline int wantPacket(const unsigned char *hdr) const; - int m_pid; + int m_pid, m_streamtype; int m_need_next_packet; int m_skip; int m_last_pts_valid; diff --git a/lib/dvb/tstools.cpp b/lib/dvb/tstools.cpp index bd7ebce2..7ac86f08 100644 --- a/lib/dvb/tstools.cpp +++ b/lib/dvb/tstools.cpp @@ -32,7 +32,10 @@ int eDVBTSTools::openFile(const char *filename, int nostreaminfo) closeFile(); if (!nostreaminfo) - m_streaminfo.load((std::string(filename) + ".ap").c_str()); + { + eDebug("loading streaminfo for %s", filename); + m_streaminfo.load(filename); + } if (!m_streaminfo.empty()) m_use_streaminfo = 1; @@ -562,3 +565,68 @@ int eDVBTSTools::findPMT(int &pmt_pid, int &service_id) return -1; } + +int eDVBTSTools::findIFrame(off_t &_offset, size_t &len, int direction) +{ + off_t offset = _offset; +// eDebug("trying to find iFrame at %llx", offset); + + if (!m_use_streaminfo) + { + eDebug("can't get next iframe without streaminfo"); + return -1; + } + + /* let's find the iframe before the given offset */ + unsigned long long data; + while (1) + { + if (m_streaminfo.getStructureEntry(offset, data, (direction == 0) ? 1 : 0)) + { + eDebug("getting structure info for origin offset failed."); + return -1; + } + if (offset == 0x7fffffffffffffffLL) /* eof */ + { + eDebug("reached eof"); + return -1; + } + /* data is usually the start code in the lower 8 bit, and the next byte <<8. we extract the picture type from there */ + /* we know that we aren't recording startcode 0x09 for mpeg2, so this is safe */ + int is_start = (data & 0xE0FF) == 0x0009; /* H.264 NAL unit access delimiter with I-frame*/ + is_start |= (data & 0x3800FF) == 0x080000; /* MPEG2 picture start code with I-frame */ +// eDebug("%08llx@%llx -> %d", data, offset, is_start); + if (is_start) + break; + + if (direction == -1) + --offset; /* move to previous entry */ + else if (direction == +1) + direction = 0; + } + /* let's find the next frame after the given offset */ + off_t start = offset; + + do { + if (m_streaminfo.getStructureEntry(offset, data, 1)) + { + eDebug("get next failed"); + return -1; + } + if (offset == 0x7fffffffffffffffLL) /* eof */ + { + eDebug("reached eof (while looking for end of iframe)"); + return -1; + } +// eDebug("%08llx@%llx", data, offset); + } while (((data & 0xFF) != 9) && ((data & 0xFF) != 0x00)); /* next frame */ + + /* align to TS pkt start */ + start = start - (start % 188); + offset = offset - (offset % 188); + + len = offset - start; + _offset = start; +// eDebug("result: offset=%llx, len: %ld", offset, (int)len); + return 0; +} diff --git a/lib/dvb/tstools.h b/lib/dvb/tstools.h index 4bc04729..a8e0751e 100644 --- a/lib/dvb/tstools.h +++ b/lib/dvb/tstools.h @@ -55,6 +55,8 @@ public: int takeSample(off_t off, pts_t &p); int findPMT(int &pmt_pid, int &service_id); + + int findIFrame(off_t &offset, size_t &len, int direction); private: int m_pid; int m_maxrange; diff --git a/lib/gui/epositiongauge.cpp b/lib/gui/epositiongauge.cpp index b3ee5111..ff98c080 100644 --- a/lib/gui/epositiongauge.cpp +++ b/lib/gui/epositiongauge.cpp @@ -144,7 +144,7 @@ int ePositionGauge::event(int event, void *data, void *data2) { painter.setForegroundColor(gRGB(m_foreground_color)); int xi = scale(in), xo = scale(out); - painter.fill(eRect(xi, 10, xo-xi, s.height()-14)); + painter.fill(eRect(xi, (s.height()-4) / 2, xo-xi, 4)); } in = m_length; diff --git a/lib/python/Components/Converter/StringList.py b/lib/python/Components/Converter/StringList.py index c9488db0..08794b34 100644 --- a/lib/python/Components/Converter/StringList.py +++ b/lib/python/Components/Converter/StringList.py @@ -19,8 +19,11 @@ class StringList(Converter): def selectionChanged(self, index): self.source.selectionChanged(index) # update all non-master targets + print "changed selection in listbox!" for x in self.downstream_elements: + print "downstream element", x if x is not self.master: + print "is not master, so update to index", index x.index = index @cached @@ -43,3 +46,6 @@ class StringList(Converter): self.master.index = index index = property(getIndex, setIndex) + + def entry_changed(self, index): + self.downstream_elements.entry_changed(index) \ No newline at end of file diff --git a/lib/python/Components/Renderer/Listbox.py b/lib/python/Components/Renderer/Listbox.py index 8e510b4c..7a895330 100644 --- a/lib/python/Components/Renderer/Listbox.py +++ b/lib/python/Components/Renderer/Listbox.py @@ -78,3 +78,7 @@ class Listbox(Renderer, object): def changed(self, what): self.content = self.source.content + + def entry_changed(self, index): + if self.instance is not None: + self.instance.entryChanged(index) diff --git a/lib/service/servicedvb.cpp b/lib/service/servicedvb.cpp index 33cd865e..e3d960d4 100644 --- a/lib/service/servicedvb.cpp +++ b/lib/service/servicedvb.cpp @@ -370,13 +370,17 @@ int eStaticServiceDVBPVRInformation::getLength(const eServiceReference &ref) struct stat s; stat(ref.path.c_str(), &s); - if (tstools.openFile(ref.path.c_str())) + if (tstools.openFile(ref.path.c_str(), 1)) return 0; /* check if cached data is still valid */ if (m_parser.m_data_ok && (s.st_size == m_parser.m_filesize) && (m_parser.m_length)) return m_parser.m_length / 90000; + /* open again, this time with stream info */ + if (tstools.openFile(ref.path.c_str())) + return 0; + /* otherwise, re-calc length and update meta file */ pts_t len; if (tstools.calcLen(len)) @@ -502,6 +506,7 @@ RESULT eDVBPVRServiceOfflineOperations::getListOfFilenames(std::list= 0)) + { + eDebug("timeshift EOF, so let's go live"); switchToLive(); + } break; } } @@ -1173,9 +1181,9 @@ RESULT eDVBServicePlay::setFastForward_internal(int ratio) if (!m_decoder) return -1; - + if (ffratio == 0) - return 0; + return m_decoder->play(); else if (ffratio != 1) return m_decoder->setFastForward(ffratio); else @@ -1211,6 +1219,7 @@ RESULT eDVBServicePlay::pause() setFastForward_internal(0); if (m_decoder) { + m_is_paused = 1; return m_decoder->pause(); } else return -1; @@ -1222,6 +1231,7 @@ RESULT eDVBServicePlay::unpause() setFastForward_internal(0); if (m_decoder) { + m_is_paused = 0; return m_decoder->play(); } else return -1; @@ -2136,6 +2146,8 @@ void eDVBServicePlay::switchToLive() if (!m_timeshift_active) return; + eDebug("SwitchToLive"); + m_cue = 0; m_decoder = 0; m_decode_demux = 0; diff --git a/lib/service/servicedvbrecord.cpp b/lib/service/servicedvbrecord.cpp index c2767e8d..5b7b5d8c 100644 --- a/lib/service/servicedvbrecord.cpp +++ b/lib/service/servicedvbrecord.cpp @@ -270,7 +270,7 @@ int eDVBServiceRecord::doRecord() if (program.pmtPid != -1) pids_to_record.insert(program.pmtPid); // PMT - int timing_pid = -1; + int timing_pid = -1, timing_pid_type = -1; eDebugNoNewLine("RECORD: have %d video stream(s)", program.videoStreams.size()); if (!program.videoStreams.empty()) @@ -283,7 +283,10 @@ int eDVBServiceRecord::doRecord() pids_to_record.insert(i->pid); if (timing_pid == -1) + { timing_pid = i->pid; + timing_pid_type = i->type; + } if (i != program.videoStreams.begin()) eDebugNoNewLine(", "); @@ -302,7 +305,10 @@ int eDVBServiceRecord::doRecord() pids_to_record.insert(i->pid); if (timing_pid == -1) + { timing_pid = i->pid; + timing_pid_type = -1; + } if (i != program.audioStreams.begin()) eDebugNoNewLine(", "); @@ -358,7 +364,7 @@ int eDVBServiceRecord::doRecord() } if (timing_pid != -1) - m_record->setTimingPID(timing_pid); + m_record->setTimingPID(timing_pid, timing_pid_type); m_pids_active = pids_to_record; -- cgit v1.2.3 From 8351aa6cc857d1113b38f34e9c2dbd3e47ec9ffa Mon Sep 17 00:00:00 2001 From: Felix Domke Date: Fri, 13 Feb 2009 14:05:55 +0100 Subject: fix timeshift, a bit --- lib/service/servicedvb.cpp | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'lib') diff --git a/lib/service/servicedvb.cpp b/lib/service/servicedvb.cpp index e3d960d4..4773d097 100644 --- a/lib/service/servicedvb.cpp +++ b/lib/service/servicedvb.cpp @@ -2205,7 +2205,7 @@ void eDVBServicePlay::updateDecoder() eDVBServicePMTHandler &h = m_timeshift_active ? m_service_handler_timeshift : m_service_handler; eDVBServicePMTHandler::program program; - if (h.getProgramInfo(program)) + if (h.getProgramInfo(program) && m_service_handler.getProgramInfo(program)) eDebug("getting program info failed."); else { @@ -2318,10 +2318,9 @@ void eDVBServicePlay::updateDecoder() m_teletext_parser->start(program.textPid); - if (!m_is_primary) +/* if (!m_is_primary) m_decoder->setTrickmode(); - - if (m_is_paused) + else */ if (m_is_paused) m_decoder->pause(); else m_decoder->play(); @@ -2346,7 +2345,7 @@ void eDVBServicePlay::updateDecoder() m_dvb_service->setCacheEntry(eDVBService::cPCRPID, pcrpid); m_dvb_service->setCacheEntry(eDVBService::cTPID, tpid); } - } + } m_have_video_pid = (vpid > 0 && vpid < 0x2000); } -- cgit v1.2.3 From 5698c2b573e69c2e62ee8212893f620f0588c208 Mon Sep 17 00:00:00 2001 From: Felix Domke Date: Fri, 13 Feb 2009 14:40:56 +0100 Subject: better fix for timeshift --- lib/dvb/pmt.cpp | 5 ++++- lib/service/servicedvb.cpp | 4 ++-- 2 files changed, 6 insertions(+), 3 deletions(-) (limited to 'lib') diff --git a/lib/dvb/pmt.cpp b/lib/dvb/pmt.cpp index 279ec74f..0198c8f7 100644 --- a/lib/dvb/pmt.cpp +++ b/lib/dvb/pmt.cpp @@ -605,12 +605,15 @@ void eDVBServicePMTHandler::SDTScanEvent(int event) } } -int eDVBServicePMTHandler::tune(eServiceReferenceDVB &ref, int use_decode_demux, eCueSheet *cue, bool simulate) +int eDVBServicePMTHandler::tune(eServiceReferenceDVB &ref, int use_decode_demux, eCueSheet *cue, bool simulate, eDVBService *service) { RESULT res=0; m_reference = ref; m_use_decode_demux = use_decode_demux; + + /* use given service as backup. This is used for timeshift where we want to clone the live stream using the cache, but in fact have a PVR channel */ + m_service = service; /* is this a normal (non PVR) channel? */ if (ref.path.empty()) diff --git a/lib/service/servicedvb.cpp b/lib/service/servicedvb.cpp index 4773d097..8a609095 100644 --- a/lib/service/servicedvb.cpp +++ b/lib/service/servicedvb.cpp @@ -2189,7 +2189,7 @@ void eDVBServicePlay::switchToTimeshift() r.path = m_timeshift_file; m_cue = new eCueSheet(); - m_service_handler_timeshift.tune(r, 1, m_cue); /* use the decoder demux for everything */ + m_service_handler_timeshift.tune(r, 1, m_cue, 0, m_dvb_service); /* use the decoder demux for everything */ eDebug("eDVBServicePlay::switchToTimeshift, in pause mode now."); pause(); @@ -2205,7 +2205,7 @@ void eDVBServicePlay::updateDecoder() eDVBServicePMTHandler &h = m_timeshift_active ? m_service_handler_timeshift : m_service_handler; eDVBServicePMTHandler::program program; - if (h.getProgramInfo(program) && m_service_handler.getProgramInfo(program)) + if (h.getProgramInfo(program)) eDebug("getting program info failed."); else { -- cgit v1.2.3 From d043db1c05a2d5c66b6faddd6f18d18a5a832515 Mon Sep 17 00:00:00 2001 From: Felix Domke Date: Fri, 13 Feb 2009 14:45:13 +0100 Subject: allow service to be overridden for pvr services --- lib/dvb/pmt.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/dvb/pmt.h b/lib/dvb/pmt.h index 3e22174b..cabc6ace 100644 --- a/lib/dvb/pmt.h +++ b/lib/dvb/pmt.h @@ -204,7 +204,7 @@ public: int getChannel(eUsePtr &channel); void resetCachedProgram() { m_have_cached_program = false; } - int tune(eServiceReferenceDVB &ref, int use_decode_demux, eCueSheet *sg=0, bool simulate=false); + int tune(eServiceReferenceDVB &ref, int use_decode_demux, eCueSheet *sg=0, bool simulate=false, eDVBService *service = 0); void free(); private: bool m_have_cached_program; -- cgit v1.2.3 From c178c52d01ede2b9c474fd4a3677acdecf18f0c6 Mon Sep 17 00:00:00 2001 From: Felix Domke Date: Fri, 13 Feb 2009 14:45:41 +0100 Subject: show decoder state --- lib/dvb/decoder.cpp | 3 +++ 1 file changed, 3 insertions(+) (limited to 'lib') diff --git a/lib/dvb/decoder.cpp b/lib/dvb/decoder.cpp index a4cffb77..edefd764 100644 --- a/lib/dvb/decoder.cpp +++ b/lib/dvb/decoder.cpp @@ -855,6 +855,9 @@ int eTSMPEGDecoder::setState() if ((nott && m_text) || (!m_text && !nott)) m_changed |= changeText | changeState; + const char *decoder_states[] = {"stop", "pause", "play", "decoderfastforward", "trickmode", "slowmotion"}; + eDebug("decoder state: %s, vpid=%d, apid=%d", decoder_states[m_state], m_vpid, m_apid); + bool changed = !!m_changed; #if HAVE_DVB_API_VERSION < 3 bool checkAVSync = m_changed & (changeAudio|changeVideo|changePCR); -- cgit v1.2.3 From eccbf5ccedceaf21d4d2557e5ef12ef9a53930ca Mon Sep 17 00:00:00 2001 From: Felix Domke Date: Fri, 13 Feb 2009 14:45:58 +0100 Subject: decoder_play is already called in caller --- lib/service/servicedvb.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/service/servicedvb.cpp b/lib/service/servicedvb.cpp index 8a609095..81157ae5 100644 --- a/lib/service/servicedvb.cpp +++ b/lib/service/servicedvb.cpp @@ -1183,7 +1183,7 @@ RESULT eDVBServicePlay::setFastForward_internal(int ratio) return -1; if (ffratio == 0) - return m_decoder->play(); + ; /* return m_decoder->play(); is done in caller*/ else if (ffratio != 1) return m_decoder->setFastForward(ffratio); else -- cgit v1.2.3 From 166db5a9c9222c82939eede51d964c706039ebe8 Mon Sep 17 00:00:00 2001 From: Felix Domke Date: Wed, 18 Feb 2009 03:09:08 +0100 Subject: optional fuzzing support --- lib/dvb/demux.cpp | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) (limited to 'lib') diff --git a/lib/dvb/demux.cpp b/lib/dvb/demux.cpp index 918ecec6..11465186 100644 --- a/lib/dvb/demux.cpp +++ b/lib/dvb/demux.cpp @@ -5,6 +5,13 @@ #include #include +// #define FUZZING 1 + +#if FUZZING + /* change every 1:FUZZING_PROPABILITY byte */ +#define FUZZING_PROPABILITY 100 +#endif + #if HAVE_DVB_API_VERSION < 3 #include @@ -178,6 +185,14 @@ void eDVBSectionReader::data(int) __u8 data[4096]; // max. section size int r; r = ::read(fd, data, 4096); +#if FUZZING + int j; + for (j = 0; j < r; ++j) + { + if (!(rand()%FUZZING_PROPABILITY)) + data[j] ^= rand(); + } +#endif if(r < 0) { eWarning("ERROR reading section - %m\n"); @@ -243,11 +258,13 @@ RESULT eDVBSectionReader::start(const eDVBSectionFilterMask &mask) #else sct.flags = DMX_IMMEDIATE_START; #endif +#if !FUZZING if (mask.flags & eDVBSectionFilterMask::rfCRC) { sct.flags |= DMX_CHECK_CRC; checkcrc = 1; } else +#endif checkcrc = 0; memcpy(sct.filter.filter, mask.data, DMX_FILTER_SIZE); -- cgit v1.2.3