diff options
author | Klaus Schmidinger <kls (at) cadsoft (dot) de> | 2005-06-12 18:00:00 +0200 |
---|---|---|
committer | Klaus Schmidinger <kls (at) cadsoft (dot) de> | 2005-06-12 18:00:00 +0200 |
commit | a616d4b8597cfb69af7a8f0e0a96da2143970ffe (patch) | |
tree | e6c64553b643803984d2d093cbbd01ff45dd3be8 | |
parent | f8367110245149a1333e47118c41827288c814c3 (diff) | |
download | vdr-patch-lnbsharing-a616d4b8597cfb69af7a8f0e0a96da2143970ffe.tar.gz vdr-patch-lnbsharing-a616d4b8597cfb69af7a8f0e0a96da2143970ffe.tar.bz2 |
Version 1.3.26vdr-1.3.26
- Updated the Estonian OSD texts (thanks to Arthur Konovalov).
- Updated the Finnish OSD texts (thanks to Rolf Ahrenberg).
- Fixed handling 'summary.vdr' files with more than two empty lines (thanks to
Christian Jacobsen for reporting this one).
- Improved resetting CAM connections (thanks to Marco Schlüßler).
- Implemented cVideoRepacker in remux.c to make sure every PES packet contains
only data from one frame (thanks to Reinhard Nissl).
NOTE: currently this doesn't work with MPEG1, so if you use MPEG1 you may want
to change line 1158 in remux.c to
ts2pes[numTracks++] = new cTS2PES(VPid, resultBuffer, IPACKS);
as it was before.
- EPG events without a title now display "No title" instead of "(null)" (thanks
to Rolf Ahrenberg).
- A device can now detach all receivers for a given PID, as is necessary, e.g.,
for the bitstreamout plugin (thanks to Werner Fink).
- Added the year (two digits) to recording dates in LSTR, and thus also in menus
(suggested by Jan Ekholm).
- Fixed the call to Channels.Unlock() in cEITScanner::Process() (thanks to
Reinhard Nissl).
- Fixed handling timers with a day given as MTWTF--@6, i.e. a repeating timer with
first day not as full date, but just day of month (thanks to Henrik Niehaus for
reporting this one).
- Removed an unnecessary #include from osd.c (thanks to Wolfgang Rohdewald).
- Fixed dropping EPG events that have a zero start time or duration, in case it's
an NVOD event (thanks to Chris Warren).
- Fixed handling page up/down in menu lists in case there are several non selectable
items in a row (thanks to Udo Richter for reporting this one).
- Added cOsdMenu::SetCols() to allow adjusting the menu columns.
- Modified cEITScanner::Process() so that it works on systems with only budget cards
or a mix of DVB-S, DVB-C or DVB-T cards.
-rw-r--r-- | CONTRIBUTORS | 17 | ||||
-rw-r--r-- | HISTORY | 35 | ||||
-rw-r--r-- | channels.conf | 15 | ||||
-rw-r--r-- | ci.c | 21 | ||||
-rw-r--r-- | config.h | 6 | ||||
-rw-r--r-- | device.c | 27 | ||||
-rw-r--r-- | device.h | 7 | ||||
-rw-r--r-- | dvbdevice.c | 11 | ||||
-rw-r--r-- | eit.c | 6 | ||||
-rw-r--r-- | eitscan.c | 53 | ||||
-rw-r--r-- | epg.c | 9 | ||||
-rw-r--r-- | i18n.c | 47 | ||||
-rw-r--r-- | menu.c | 4 | ||||
-rw-r--r-- | osd.c | 3 | ||||
-rw-r--r-- | osdbase.c | 82 | ||||
-rw-r--r-- | osdbase.h | 3 | ||||
-rw-r--r-- | recording.c | 9 | ||||
-rw-r--r-- | remux.c | 358 | ||||
-rwxr-xr-x | summary2info.pl | 4 | ||||
-rw-r--r-- | timers.c | 4 |
20 files changed, 618 insertions, 103 deletions
diff --git a/CONTRIBUTORS b/CONTRIBUTORS index eff35c7..92c6801 100644 --- a/CONTRIBUTORS +++ b/CONTRIBUTORS @@ -283,6 +283,7 @@ Werner Fink <werner@suse.de> for pointing out that MAXDPIDS needs to be to 16 (8xAC3 + 8xDTS) for reporting a problem with ensuring there is a current audio track in case there is only one track + for enabling a device to detach all receivers for a given PID Rolf Hakenes <hakenes@hippomi.de> for providing 'libdtv' and adapting the EIT mechanisms to it @@ -713,6 +714,7 @@ Jan Ekholm <chakie@infa.abo.fi> for reporting a compiler warning in g++ 3.2.3 regarding cReplayControl::Show() for reporting and helping to debug a problem in frequency handling when setting the CA descriptors in cDvbTuner::Action() + for suggesting to add the year to recording dates in LSTR Marcel Wiesweg <marcel.wiesweg@gmx.de> for pointing out a problem with high CPU load during replay @@ -828,6 +830,7 @@ Christian Jacobsen <christian.jacobsen@stageholding.de> for reporting a problem in handling the '-E' options in version 1.3.18 for reporting a problem in case a station defines all 32 audio PIDs for suggestions and experiments regarding the buffer reserve in cTransfer + for reporting a problem with 'summary.vdr' files with more than two empty lines Andreas Mair <Andreas.Mair@linogate.com> for reporting a short display of the main menu if a plugin displays its own OSD and @@ -880,6 +883,7 @@ Rolf Ahrenberg <rahrenbe@cc.hut.fi> for translating OSD texts to the Finnish language for fixing internationalization of the text for "Setup/DVB/Audio language(s)" for making pressing the Power button not stop Transfer Mode or replay immediately + for making EPG events without a title display "No title" instead of "(null)" Ralf Klueber <ralf.klueber@vodafone.com> for reporting a bug in cutting a recording if there is only a single editing mark @@ -954,6 +958,9 @@ Reinhard Nissl <rnissl@gmx.de> for fixing a typo in detecting UTF-8 for fixing handling fragments of less than 4 byte in cPesAssembler for some rearrangements in cDvbPlayer::Action() to avoid lockups on NPTL systems + for implementing cVideoRepacker in remux.c to make sure every PES packet contains + only data from one frame + for fixing the call to Channels.Unlock() in cEITScanner::Process() Richard Robson <richard_robson@beeb.net> for reporting freezing replay if a timer starts while in Transfer Mode from the @@ -1186,6 +1193,7 @@ Marco Schlüßler <marco@lordzodiac.de> level from being set to a wrong value for fixing a possible hangup when ending a replay session while cIndexFile::CatchUp() is waiting + for improving resetting CAM connections Jürgen Schmitz <j.schmitz@web.de> for reporting a bug in displaying the current channel when switching via the SVDRP @@ -1231,6 +1239,8 @@ Milos Kapoun <m.kapoun@cra.cz> Udo Richter <udo_richter@gmx.de> for refining the formula for making volume control more linear for fixing handling lifetime when deciding whether to delete a recording + for reporting a problem in handling page up/down in menu lists in case there are + several non selectable items in a row Sven Kreiensen <svenk@kammer.uni-hannover.de> for his help in keeping 'channels.conf.terr' up to date @@ -1311,6 +1321,7 @@ Wolfgang Rohdewald <wolfgang@rohdewald.de> for removing some unneeded code and fixing access to unallocated memory in cEvent::FixEpgBugs() for adding a missing cMutexLock to cRemote::HasKeys() + for removing an unnecessary #include from osd.c Chad Flynt <hoochster@sofnet.com> for suggestions and experiments regarding the buffer reserve in cTransfer @@ -1318,6 +1329,8 @@ Chad Flynt <hoochster@sofnet.com> Chris Warren <dvb@ixalon.net> for pointing out that the call to system("sync") in SpinUpDisk() should be replaced with fsync(f) to avoid problems on NPTL systems + for fixing dropping EPG events that have a zero start time or duration, in case it's + an NVOD event Luca Olivetti <luca@ventoso.org> for making cDevice::AttachPlayer() keep the track language codes and descriptions @@ -1367,3 +1380,7 @@ Georg Acher <acher@baycom.de> for avoiding unnecessary calls to getLength() in libsi/si.c, and avoiding the '& 0xff' in CRC32::crc32() of libsi/util.c for suggesting to reduce the priority of the section handler threads + +Henrik Niehaus <henrik.niehaus@gmx.de> + for reporting a problem with timers with a day given as MTWTF--@6, i.e. a repeating + timer with first day not as full date, but just day of month @@ -3577,3 +3577,38 @@ Video Disk Recorder Revision History to Stefan Huelswitt for pointing this out). - Added cThread::SetPriority() and using it in cSectionHandler::Action() to reduce the priority of the section handler threads (as suggested by Georg Acher). + +2005-06-12: Version 1.3.26 + +- Updated the Estonian OSD texts (thanks to Arthur Konovalov). +- Updated the Finnish OSD texts (thanks to Rolf Ahrenberg). +- Fixed handling 'summary.vdr' files with more than two empty lines (thanks to + Christian Jacobsen for reporting this one). +- Improved resetting CAM connections (thanks to Marco Schlüßler). +- Implemented cVideoRepacker in remux.c to make sure every PES packet contains + only data from one frame (thanks to Reinhard Nissl). + NOTE: currently this doesn't work with MPEG1, so if you use MPEG1 you may want + to change line 1158 in remux.c to + + ts2pes[numTracks++] = new cTS2PES(VPid, resultBuffer, IPACKS); + + as it was before. +- EPG events without a title now display "No title" instead of "(null)" (thanks + to Rolf Ahrenberg). +- A device can now detach all receivers for a given PID, as is necessary, e.g., + for the bitstreamout plugin (thanks to Werner Fink). +- Added the year (two digits) to recording dates in LSTR, and thus also in menus + (suggested by Jan Ekholm). +- Fixed the call to Channels.Unlock() in cEITScanner::Process() (thanks to + Reinhard Nissl). +- Fixed handling timers with a day given as MTWTF--@6, i.e. a repeating timer with + first day not as full date, but just day of month (thanks to Henrik Niehaus for + reporting this one). +- Removed an unnecessary #include from osd.c (thanks to Wolfgang Rohdewald). +- Fixed dropping EPG events that have a zero start time or duration, in case it's + an NVOD event (thanks to Chris Warren). +- Fixed handling page up/down in menu lists in case there are several non selectable + items in a row (thanks to Udo Richter for reporting this one). +- Added cOsdMenu::SetCols() to allow adjusting the menu columns. +- Modified cEITScanner::Process() so that it works on systems with only budget cards + or a mix of DVB-S, DVB-C or DVB-T cards. diff --git a/channels.conf b/channels.conf index f62e0fe..01caab7 100644 --- a/channels.conf +++ b/channels.conf @@ -26,7 +26,7 @@ NEUN LIVE Television,NEUN LIVE;BetaDigital:12480:vC34:S19.2E:27500:767:768=deu:3 DSF;BetaDigital:12480:vC34:S19.2E:27500:1023:1024=deu:0:0:900:133:33:0 HSE24,HSE24;BetaDigital:12480:vC34:S19.2E:27500:1279:1280=deu:37:0:40:133:33:0 Bloomberg TV Germany;Bloomberg:12551:vC56:S19.2E:22000:162:99=deu:0:0:12160:1:1108:0 -EURONEWS;CSAT:11817:vC34:S19.2E:27500:163:92=fra,91=rus,93=eng,94=ita,95=esl,98=por,99=deu:0:0:8004:1:1070:0 +EURONEWS;CSAT:11817:vC34:S19.2E:27500:163:92=fra,93=eng,94=ita,95=esl,91=rus,98=por,99=deu:0:0:8004:1:1070:0 rbb Brandenburg;ARD:12109:hC34:S19.2E:27500:601:602=deu:604:0:28205:1:1073:0 Sky News;BSkyB:11597:vC56:S19.2E:22000:305+131:306=eng:0:0:28707:1:1026:0 Veronica/JETIX;CANAL+:12574:hC56:S19.2E:22000:518+8190:92=dut:38:622,100:5020:53:1109:0 @@ -45,9 +45,9 @@ rbb Berlin;ARD:12109:hC34:S19.2E:27500:601:602=deu:604:0:28206:1:1073:0 :Premiere World PREMIERE START,START;PREMIERE:11797:hC34:S19.2E:27500:255:256=deu:32:1702,1801,1722:8:133:2:0 PREMIERE 1,PREM 1;PREMIERE:11797:hC34:S19.2E:27500:511:512=deu,513=deu;515=deu:32:1722,1801,1702:10:133:2:0 -PREMIERE 2,PREM 2;PREMIERE:11797:hC34:S19.2E:27500:1791:1792=deu;1795=deu:32:1722,1801,1702:11:133:2:0 +PREMIERE 2,PREM 2;PREMIERE:11797:hC34:S19.2E:27500:1791:1792=deu,1793=deu;1795=deu:32:1722,1801,1702:11:133:2:0 PREMIERE 3,PREM 3;PREMIERE:11797:hC34:S19.2E:27500:2303:2304=deu,2305=deu:32:1722,1801,1702:43:133:2:0 -PREMIERE 4,PREM 4;PREMIERE:11797:hC34:S19.2E:27500:767:768=deu:32:1801,1722,1702:9:133:2:0 +PREMIERE 4,PREM 4;PREMIERE:11797:hC34:S19.2E:27500:767:768=deu,769=deu:32:1801,1722,1702:9:133:2:0 PREMIERE 5,PREM 5;PREMIERE:11797:hC34:S19.2E:27500:1279:1280=deu:32:1801,1722,1702:29:133:2:0 PREMIERE 6,PREM 6;PREMIERE:11797:hC34:S19.2E:27500:1535:1536=deu:32:1702,1722,1801:41:133:2:0 PREMIERE 7,PREM 7;PREMIERE:11797:hC34:S19.2E:27500:1023:1024=deu:32:1722,1702,1801:20:133:2:0 @@ -55,11 +55,11 @@ DISNEY CHANNEL,DISNEY;PREMIERE:11758:hC34:S19.2E:27500:2559:2560=deu:32:1722,180 :Premiere Direkt PREMIERE DIREKT,DIREKT;PREMIERE:12031:hC34:S19.2E:27500:2815:2816=deu,2817=deu;2819=deu:0:0:18:133:4:0 :PW Erotic -BEATE-UHSE.TV,B-UHSE;PREMIERE:12070:hC34:S19.2E:27500:1023:1024=deu:32:1702,1801,1722:21:133:1:0 +BEATE-UHSE.TV,B-UHSE;PREMIERE:11758:hC34:S19.2E:27500:1791:1792=deu:32:1801,1722,1702:21:133:17:0 DIREKT EROTIK,EROTIK;PREMIERE:12031:hC34:S19.2E:27500:1279:0:0:1722,1801,1702:513:133:4:0 :Sportsworld -F1-Portal:11719:hC34:S19.2E:27500:255:256=deu,257=deu:32:1702,1801,1722:17:133:3:0 -PREMIERE SPORT 2,SPORT 2;PREMIERE:12031:hC34:S19.2E:27500:3839:3840=deu,3841=deu:32:1722,1702,1801:27:133:4:0 +PREMIERE SPORT PORTAL,SPORT PORTAL;PREMIERE:11719:hC34:S19.2E:27500:255:256=deu,257=deu:32:1702,1801,1722:17:133:3:0 +.,.;PREMIERE:12031:hC34:S19.2E:27500:3839:3840=deu:32:1722,1702,1801:27:133:4:0 :Beta Digital N24;ProSiebenSat.1:12480:vC34:S19.2E:27500:2047:2048=deu:36:0:47:133:33:0 LibertyTV FR;LibertyTV.com:12610:vC56:S19.2E:22000:941:943=deu:0:0:12199:1:1112:0 @@ -69,7 +69,7 @@ Kabel 1 Schweiz;ProSiebenSat.1:12051:vC34:S19.2E:27500:162:163=deu:165:0:20003:1 Kabel 1 Austria;ProSiebenSat.1:12051:vC34:S19.2E:27500:166:167=deu:169:0:20004:1:1082:0 ProSieben Schweiz;ProSiebenSat.1:12051:vC34:S19.2E:27500:289:290=deu:33:0:20001:1:1082:0 FRANCE 5;CSAT:12207:vC34:S19.2E:27500:160:80=fra:32:500,100:8501:1:1090:0 -LCP;CSAT:12207:vC34:S19.2E:27500:2047+8191:0:0:0:8506:1:1090:0 +LCP;ABSAT:12285:vC34:S19.2E:27500:167:108:0:0:17027:1:1094:0 ESCALES;ABSAT:12285:vC34:S19.2E:27500:165:100:41:500,100:17025:1:1094:0 Best of Shopping;CSAT:12324:vC34:S19.2E:27500:160:80=fra:0:0:8612:1:1096:0 ASTRA-Mosaic;SES ASTRA:12551:vC56:S19.2E:22000:175:176=fra:0:0:3988:1:1108:0 @@ -82,7 +82,6 @@ RTL TELE Letzebuerg:12551:vC56:S19.2E:22000:168:144=eng,146=fra,151=ltz:74:0:399 Yorin;CANAL+:12574:hC56:S19.2E:22000:512+8190:84=dut:33:622,100:5010:53:1109:0 MTV2 Pop Channel;MTV Networks:12226:hC34:S19.2E:27500:513+8190:661=deu:577:0:28640:1:1091:0 MTV Central;MTV Networks:11739:vC34:S19.2E:27500:3031:3032:3034:0:28653:1:1066:0 -Via 1 - Schöner Reisen:12148:h:S19.2E:27500:511:512:0:0:44:0:0:0 VIVA;VIVA Fernsehen GmbH & Co. KG:12669:vC56:S19.2E:22000:309:310=deu:311:0:12732:1:1116:0 VIVA PLUS;VIVA Fernsehen GmbH & Co. KG:12551:vC56:S19.2E:22000:171:172=deu:173:0:12120:1:1108:0 QVC Deutschland;QVC:12551:vC56:S19.2E:22000:165:166:167:0:12100:1:1108:0 @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: ci.c 1.23 2004/07/17 14:30:17 kls Exp $ + * $Id: ci.c 1.24 2005/06/04 11:57:05 kls Exp $ */ #include "ci.h" @@ -287,6 +287,7 @@ public: int RecvData(void); const uint8_t *Data(int &Length); //XXX Close() + void Reset(void); }; cCiTransportConnection::cCiTransportConnection(void) @@ -428,6 +429,11 @@ int cCiTransportConnection::Poll(void) return ERROR; } +void cCiTransportConnection::Reset(void) +{ + Init(-1, 0, 0); +} + // --- cCiTransportLayer ----------------------------------------------------- #define MAX_CI_CONNECT 16 // maximum possible value is 254 @@ -440,7 +446,7 @@ private: public: cCiTransportLayer(int Fd, int NumSlots); cCiTransportConnection *NewConnection(int Slot); - bool ResetSlot(int Slot); + bool ResetSlot(int Slot, bool Wait = false); bool ModuleReady(int Slot); cCiTransportConnection *Process(int Slot); }; @@ -451,6 +457,7 @@ cCiTransportLayer::cCiTransportLayer(int Fd, int NumSlots) numSlots = NumSlots; for (int s = 0; s < numSlots; s++) ResetSlot(s); + cCondWait::SleepMs(2000); } cCiTransportConnection *cCiTransportLayer::NewConnection(int Slot) @@ -467,10 +474,16 @@ cCiTransportConnection *cCiTransportLayer::NewConnection(int Slot) return NULL; } -bool cCiTransportLayer::ResetSlot(int Slot) +bool cCiTransportLayer::ResetSlot(int Slot, bool Wait) { + for (int i = 0; i < MAX_CI_CONNECT; i++) { + if (tc[i].State() != stIDLE && tc[i].Slot() == Slot) + tc[i].Reset(); + } dbgprotocol("Resetting slot %d...", Slot); if (ioctl(fd, CA_RESET, 1 << Slot) != -1) { + if (Wait) + cCondWait::SleepMs(2000); dbgprotocol("ok.\n"); return true; } @@ -1602,5 +1615,5 @@ bool cCiHandler::Reset(int Slot) { cMutexLock MutexLock(&mutex); CloseAllSessions(Slot); - return tpl->ResetSlot(Slot); + return tpl->ResetSlot(Slot, true); } @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: config.h 1.218 2005/05/14 09:18:08 kls Exp $ + * $Id: config.h 1.219 2005/06/03 12:39:16 kls Exp $ */ #ifndef __CONFIG_H @@ -20,8 +20,8 @@ #include "i18n.h" #include "tools.h" -#define VDRVERSION "1.3.25" -#define VDRVERSNUM 10325 // Version * 10000 + Major * 100 + Minor +#define VDRVERSION "1.3.26" +#define VDRVERSNUM 10326 // Version * 10000 + Major * 100 + Minor #define MAXPRIORITY 99 #define MAXLIFETIME 99 @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: device.c 1.101 2005/05/07 15:04:17 kls Exp $ + * $Id: device.c 1.103 2005/06/12 13:39:11 kls Exp $ */ #include "device.h" @@ -397,6 +397,8 @@ bool cDevice::AddPid(int Pid, ePidType PidType) PRINTPIDS("A"); if (!SetPid(&pidHandles[n], n, true)) { esyslog("ERROR: can't set PID %d on device %d", Pid, CardIndex() + 1); + if (PidType <= ptTeletext) + DetachAll(Pid); DelPid(Pid, PidType); return false; } @@ -422,6 +424,8 @@ bool cDevice::AddPid(int Pid, ePidType PidType) PRINTPIDS("C"); if (!SetPid(&pidHandles[n], n, true)) { esyslog("ERROR: can't set PID %d on device %d", Pid, CardIndex() + 1); + if (PidType <= ptTeletext) + DetachAll(Pid); DelPid(Pid, PidType); return false; } @@ -501,6 +505,15 @@ bool cDevice::ProvidesTransponder(const cChannel *Channel) const return false; } +bool cDevice::ProvidesTransponderExclusively(const cChannel *Channel) const +{ + for (int i = 0; i < numDevices; i++) { + if (device[i] && device[i] != this && device[i]->ProvidesTransponder(Channel)) + return false; + } + return true; +} + bool cDevice::ProvidesChannel(const cChannel *Channel, int Priority, bool *NeedsDetachReceivers) const { return false; @@ -1211,6 +1224,18 @@ void cDevice::Detach(cReceiver *Receiver) } } +void cDevice::DetachAll(int Pid) +{ + if (Pid) { + cMutexLock MutexLock(&mutexReceiver); + for (int i = 0; i < MAXRECEIVERS; i++) { + cReceiver *Receiver = receiver[i]; + if (Receiver && Receiver->WantsPid(Pid)) + Detach(Receiver); + } + } +} + // --- cTSBuffer ------------------------------------------------------------- cTSBuffer::cTSBuffer(int File, int Size, int CardIndex) @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: device.h 1.57 2005/02/20 14:06:28 kls Exp $ + * $Id: device.h 1.59 2005/06/12 13:35:47 kls Exp $ */ #ifndef __DEVICE_H @@ -186,6 +186,9 @@ public: ///< Returns true if this device can provide the given source. virtual bool ProvidesTransponder(const cChannel *Channel) const; ///< XXX -> PLUGINS.html! + virtual bool ProvidesTransponderExclusively(const cChannel *Channel) const; + ///< Returns true if this is the only device that is able to provide + ///< the given channel's transponder. virtual bool ProvidesChannel(const cChannel *Channel, int Priority = -1, bool *NeedsDetachReceivers = NULL) const; ///< Returns true if this device can provide the given channel. ///< In case the device has cReceivers attached to it or it is the primary @@ -500,6 +503,8 @@ public: ///< Attaches the given receiver to this device. void Detach(cReceiver *Receiver); ///< Detaches the given receiver from this device. + void DetachAll(int Pid); + ///< Detaches all receivers from this device for this pid. }; /// Derived cDevice classes that can receive channels will have to provide diff --git a/dvbdevice.c b/dvbdevice.c index 3a3b19b..88afdff 100644 --- a/dvbdevice.c +++ b/dvbdevice.c @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: dvbdevice.c 1.129 2005/05/16 15:23:43 kls Exp $ + * $Id: dvbdevice.c 1.130 2005/06/05 13:05:55 kls Exp $ */ #include "dvbdevice.h" @@ -654,8 +654,10 @@ bool cDvbDevice::SetPid(cPidHandle *Handle, int Type, bool On) if (On) { if (Handle->handle < 0) { Handle->handle = DvbOpen(DEV_DVB_DEMUX, CardIndex(), O_RDWR | O_NONBLOCK, true); - if (Handle->handle < 0) + if (Handle->handle < 0) { + LOG_ERROR; return false; + } } pesFilterParams.pid = Handle->pid; pesFilterParams.input = DMX_IN_FRONTEND; @@ -722,6 +724,10 @@ void cDvbDevice::TurnOffLiveMode(bool LiveView) // Turn off live PIDs: + DetachAll(pidHandles[ptAudio].pid); + DetachAll(pidHandles[ptVideo].pid); + DetachAll(pidHandles[ptPcr].pid); + DetachAll(pidHandles[ptTeletext].pid); DelPid(pidHandles[ptAudio].pid); DelPid(pidHandles[ptVideo].pid); DelPid(pidHandles[ptPcr].pid, ptPcr); @@ -891,6 +897,7 @@ void cDvbDevice::SetAudioTrackDevice(eTrackType Type) if (TrackId && TrackId->id) { if (IS_AUDIO_TRACK(Type)) { if (pidHandles[ptAudio].pid && pidHandles[ptAudio].pid != TrackId->id) { + DetachAll(pidHandles[ptAudio].pid); pidHandles[ptAudio].pid = TrackId->id; SetPid(&pidHandles[ptAudio], ptAudio, true); } @@ -8,7 +8,7 @@ * Robert Schneider <Robert.Schneider@web.de> and Rolf Hakenes <hakenes@hippomi.de>. * Adapted to 'libsi' for VDR 1.3.0 by Marcel Wiesweg <marcel.wiesweg@gmx.de>. * - * $Id: eit.c 1.107 2005/05/28 11:35:55 kls Exp $ + * $Id: eit.c 1.108 2005/06/11 15:31:21 kls Exp $ */ #include "eit.h" @@ -48,8 +48,8 @@ cEIT::cEIT(cSchedules *Schedules, int Source, u_char Tid, const u_char *Data) SI::EIT::Event SiEitEvent; for (SI::Loop::Iterator it; eventLoop.getNext(SiEitEvent, it); ) { - // Drop bogus events. - if (SiEitEvent.getStartTime() == 0 || SiEitEvent.getDuration() == 0) + // Drop bogus events - but keep NVOD reference events, where all bits of the start time field are set to 1, resulting in a negative number. + if (SiEitEvent.getStartTime() == 0 || SiEitEvent.getStartTime() > 0 && SiEitEvent.getDuration() == 0) continue; Empty = false; cEvent *newEvent = NULL; @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: eitscan.c 1.24 2005/05/05 13:05:00 kls Exp $ + * $Id: eitscan.c 1.26 2005/06/12 14:09:45 kls Exp $ */ #include "eitscan.h" @@ -12,6 +12,7 @@ #include "channels.h" #include "dvbdevice.h" #include "skins.h" +#include "transfer.h" // --- cScanData ------------------------------------------------------------- @@ -139,51 +140,47 @@ void cEITScanner::Process(void) transponderList = NULL; } } - for (bool AnyDeviceSwitched = false; !AnyDeviceSwitched; ) { - cScanData *ScanData = NULL; - for (int i = 0; i < cDevice::NumDevices(); i++) { - if (ScanData || (ScanData = scanList->First()) != NULL) { - cDevice *Device = cDevice::GetDevice(i); - if (Device) { - if (Device != cDevice::PrimaryDevice() || (cDevice::NumDevices() == 1 && Setup.EPGScanTimeout && now - lastActivity > Setup.EPGScanTimeout * 3600)) { - if (!(Device->Receiving(true) || Device->Replaying())) { - const cChannel *Channel = ScanData->GetChannel(); - if (Channel) { - if ((!Channel->Ca() || Channel->Ca() == Device->DeviceNumber() + 1 || Channel->Ca() >= 0x0100) && Device->ProvidesTransponder(Channel)) { - if (Device == cDevice::PrimaryDevice() && !currentChannel) { + bool AnyDeviceSwitched = false; + for (int i = 0; i < cDevice::NumDevices(); i++) { + cDevice *Device = cDevice::GetDevice(i); + if (Device) { + for (cScanData *ScanData = scanList->First(); ScanData; ScanData = scanList->Next(ScanData)) { + const cChannel *Channel = ScanData->GetChannel(); + if (Channel) { + if (!Channel->Ca() || Channel->Ca() == Device->DeviceNumber() + 1 || Channel->Ca() >= 0x0100) { + if (Device->ProvidesTransponder(Channel)) { + if (!Device->Receiving()) { + if (Device != cDevice::ActualDevice() || (Device->ProvidesTransponderExclusively(Channel) && Setup.EPGScanTimeout && now - lastActivity > Setup.EPGScanTimeout * 3600)) { + if (Device == cDevice::ActualDevice() && !currentChannel) { + if (cTransferControl::ReceiverDevice()) + cDevice::PrimaryDevice()->StopReplay(); // stop transfer mode currentChannel = Device->CurrentChannel(); Skins.Message(mtInfo, tr("Starting EPG scan")); } currentDevice = Device;//XXX see also dvbdevice.c!!! + //dsyslog("EIT scan: device %d source %-8s tp %5d", Device->DeviceNumber() + 1, *cSource::ToString(Channel->Source()), Channel->Transponder()); Device->SwitchChannel(Channel, false); currentDevice = NULL; scanList->Del(ScanData); - ScanData = NULL; AnyDeviceSwitched = true; + break; } } } } } } - else - break; - } - if (ScanData && !AnyDeviceSwitched) { - scanList->Del(ScanData); - ScanData = NULL; - } - if (!scanList->Count()) { - delete scanList; - scanList = NULL; - if (lastActivity == 0) // this was a triggered scan - Activity(); - break; } } + if (!scanList->Count() || !AnyDeviceSwitched) { + delete scanList; + scanList = NULL; + if (lastActivity == 0) // this was a triggered scan + Activity(); + } + Channels.Unlock(); } lastScan = time(NULL); - Channels.Unlock(); } } } @@ -7,7 +7,7 @@ * Original version (as used in VDR before 1.3.0) written by * Robert Schneider <Robert.Schneider@web.de> and Rolf Hakenes <hakenes@hippomi.de>. * - * $Id: epg.c 1.34 2005/05/29 10:19:48 kls Exp $ + * $Id: epg.c 1.35 2005/06/05 12:17:15 kls Exp $ */ #include "epg.h" @@ -323,7 +323,7 @@ bool cEvent::Read(FILE *f, cSchedule *Schedule) return false; } -#define MAXEPGBUGFIXSTATS 12 +#define MAXEPGBUGFIXSTATS 13 #define MAXEPGBUGFIXCHANS 100 struct tEpgBugFixStats { int hits; @@ -638,6 +638,11 @@ void cEvent::FixEpgBugs(void) } } } + else { + // we don't want any "(null)" titles + title = strcpyrealloc(title, tr("No title")); + EpgBugFixStat(12, ChannelID()); + } } // --- cSchedule ------------------------------------------------------------- @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: i18n.c 1.191 2005/05/15 14:37:59 kls Exp $ + * $Id: i18n.c 1.194 2005/06/05 11:59:09 kls Exp $ * * Translations provided by: * @@ -386,7 +386,7 @@ const tI18nPhrase Phrases[] = { "Resumo", "Résumé", "Sammendrag", - "Tiedot", + "Yhteenveto", "Zawartosc", "Resúmen", "Ðåñéå÷üìåíï", @@ -407,6 +407,7 @@ const tI18nPhrase Phrases[] = { "",//TODO "",//TODO "",//TODO + "Tiedot", "",//TODO "",//TODO "",//TODO @@ -416,8 +417,7 @@ const tI18nPhrase Phrases[] = { "",//TODO "",//TODO "",//TODO - "",//TODO - "",//TODO + "Info", "",//TODO }, { "Schedule - %s", @@ -964,7 +964,7 @@ const tI18nPhrase Phrases[] = { "Reiniciar", "ÁÑàÞá", "Reset", - "Reset", + "Nullimine", "Nulstille", }, { "Scan", @@ -2734,7 +2734,7 @@ const tI18nPhrase Phrases[] = { "Durada dels missatges (s)", "´ÛØâÕÛìÝÞáâì ßÞÚÐ×Ð áÞÞÑéÕÝØÙ (áÕÚ)", "Vrijeme prikaza poruka (s)", - "Kanaliteate esitusaeg (s)", + "Teate esitusaeg (s)", "Tid beskeder skal vises (s)", }, { "Setup.OSD$Use small font", @@ -2860,7 +2860,7 @@ const tI18nPhrase Phrases[] = { "",// TODO "¿ÞÚÐ× ØÝäÞàÜÐæØØ Þ ÚÐÝÐÛÕ (áÕÚ)", "",// TODO - "",// TODO + "Kanaliteate esitusaeg (s)", "Tid kanalinfo skal vises (s)", }, { "Setup.OSD$Info on channel switch", @@ -2881,7 +2881,7 @@ const tI18nPhrase Phrases[] = { "Informació del canvi de canal", "¿ÞÚÐ×ëÒÐâì ØÝäÞàÜÐæØî Þ ÚÐÝÐÛÕ", "Informacije kod promjene kanala", - "Näita kanaliteadet", + "Kanaliteate näitamine", "Info ved kanalskift", }, { "Setup.OSD$Scroll pages", @@ -2944,7 +2944,7 @@ const tI18nPhrase Phrases[] = { "Gravacions en subcarpetes", "ºÐâÐÛÞÓØ åàÐÝÕÝØï ×ÐßØáÕÙ", "Imenik za snimke", - "Salvesta kausta nime", + "Kausta nime salvestamine", "Optagelser i foldere", }, { "Setup.EPG$EPG scan timeout (h)", @@ -3658,7 +3658,7 @@ const tI18nPhrase Phrases[] = { "Utilitzar el nom de l'episodi", "³àãßßØàÞÒÐâì äÐÙÛë ßÞ íßØ×ÞÔÐÜ", "Koristi ime epizode", - "Kasuta episoodi nime", + "Episoodi nime kasutamine", "Anvend udsendelsesnavn", }, { "Setup.Recording$Use VPS", @@ -3679,7 +3679,7 @@ const tI18nPhrase Phrases[] = { "",// TODO "¸áßÞÛì×ÞÒÐâì áØÓÝÐÛë VPS", "Koristi VPS", - "Kasuta VPS-i", + "VPS-i kasutamine", "Anvend VPS", }, { "Setup.Recording$VPS margin (s)", @@ -3721,7 +3721,7 @@ const tI18nPhrase Phrases[] = { "Marcar gravació instantània", "¾âÜÕçÐâì áÔÕÛÐÝÝëÕ ÒàãçÝãî ×ÐßØáØ", "Oznaèi direktno snimanje", - "Märgista otsesalvestusi", + "Otsesalvestuse märgistamine", "Markér direkte optagelse", }, { "Setup.Recording$Name instant recording", @@ -3805,7 +3805,7 @@ const tI18nPhrase Phrases[] = { "Separar arxius", "´ÕÛØâì ÞâàÕÔÐÚâØàÞÒÐÝÝëÕ äÐÙÛë", "Podijeli ureðene datoteke", - "Tükelda redigeeritud faile", + "Redigeeritud failide tükeldamine", "Opdel redigerede filer", }, { "Setup.Replay$Multi speed mode", @@ -5346,6 +5346,27 @@ const tI18nPhrase Phrases[] = { "ST:TNG konsool", "ST:TNG konsol", }, + { "No title", + "Kein Titel", + "",// TODO + "",// TODO + "",// TODO + "",// TODO + "",// TODO + "",// TODO + "Ei esitystä", + "",// TODO + "",// TODO + "",// TODO + "",// TODO + "",// TODO + "",// TODO + "",// TODO + "",// TODO + "",// TODO + "",// TODO + "",// TODO + }, { NULL } }; @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: menu.c 1.349 2005/05/16 13:59:03 kls Exp $ + * $Id: menu.c 1.350 2005/06/05 14:11:54 kls Exp $ */ #include "menu.h" @@ -1537,7 +1537,7 @@ void cMenuRecordingItem::IncrementCounter(bool New) int cMenuRecordings::helpKeys = -1; cMenuRecordings::cMenuRecordings(const char *Base, int Level, bool OpenSubMenus) -:cOsdMenu(Base ? Base : tr("Recordings"), 6, 6) +:cOsdMenu(Base ? Base : tr("Recordings"), 8, 6) { base = Base ? strdup(Base) : NULL; level = Setup.RecordingDirs ? Level : -1; @@ -4,12 +4,11 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: osd.c 1.60 2005/05/14 11:16:30 kls Exp $ + * $Id: osd.c 1.61 2005/06/11 14:31:36 kls Exp $ */ #include "osd.h" #include <math.h> -#include <signal.h> #include <stdlib.h> #include <sys/ioctl.h> #include <sys/stat.h> @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: osdbase.c 1.15 2005/01/07 16:16:41 kls Exp $ + * $Id: osdbase.c 1.17 2005/06/12 10:44:22 kls Exp $ */ #include "osdbase.h" @@ -74,11 +74,7 @@ cOsdMenu::cOsdMenu(const char *Title, int c0, int c1, int c2, int c3, int c4) hasHotkeys = false; title = NULL; SetTitle(Title); - cols[0] = c0; - cols[1] = c1; - cols[2] = c2; - cols[3] = c3; - cols[4] = c4; + SetCols(c0, c1, c2, c3, c4); first = 0; current = marked = -1; subMenu = NULL; @@ -116,6 +112,15 @@ const char *cOsdMenu::hk(const char *s) return s; } +void cOsdMenu::SetCols(int c0, int c1, int c2, int c3, int c4) +{ + cols[0] = c0; + cols[1] = c1; + cols[2] = c2; + cols[3] = c3; + cols[4] = c4; +} + void cOsdMenu::SetHasHotkeys(void) { hasHotkeys = true; @@ -258,7 +263,8 @@ void cOsdMenu::CursorUp(void) { if (current > 0) { int tmpCurrent = current; - while (--tmpCurrent >= 0 && !SelectableItem(tmpCurrent)); + while (--tmpCurrent >= 0 && !SelectableItem(tmpCurrent)) + ; if (tmpCurrent < 0) return; if (tmpCurrent >= first) @@ -282,7 +288,8 @@ void cOsdMenu::CursorDown(void) if (current < last) { int tmpCurrent = current; - while (++tmpCurrent <= last && !SelectableItem(tmpCurrent)); + while (++tmpCurrent <= last && !SelectableItem(tmpCurrent)) + ; if (tmpCurrent > last) return; if (tmpCurrent <= lastOnScreen) @@ -306,33 +313,62 @@ void cOsdMenu::CursorDown(void) void cOsdMenu::PageUp(void) { + int oldCurrent = current; + int oldFirst = first; current -= displayMenuItems; first -= displayMenuItems; + int last = Count() - 1; + if (current < 0) + current = 0; if (first < 0) - first = current = 0; - if (!SelectableItem(current)) { - current -= (current > 0) ? 1 : -1; - first = min(first, current - 1); + first = 0; + int tmpCurrent = current; + while (!SelectableItem(tmpCurrent) && --tmpCurrent >= 0) + ; + if (tmpCurrent < 0) { + tmpCurrent = current; + while (++tmpCurrent <= last && !SelectableItem(tmpCurrent)) + ; + } + current = tmpCurrent <= last ? tmpCurrent : -1; + if (current >= 0) { + if (current < first) + first = current; + else if (current - first >= displayMenuItems) + first = current - displayMenuItems + 1; + } + if (current != oldCurrent || first != oldFirst) { + Display(); + DisplayCurrent(true); } - Display(); - DisplayCurrent(true); } void cOsdMenu::PageDown(void) { + int oldCurrent = current; + int oldFirst = first; current += displayMenuItems; first += displayMenuItems; - int count = Count(); - if (current > count - 1) { - current = count - 1; - first = max(0, count - displayMenuItems); + int last = Count() - 1; + int tmpCurrent = current; + while (!SelectableItem(tmpCurrent) && ++tmpCurrent <= last) + ; + if (tmpCurrent > last) { + tmpCurrent = current; + while (--tmpCurrent >= 0 && !SelectableItem(tmpCurrent)) + ; } - if (!SelectableItem(current)) { - current += (current < count - 1) ? 1 : -1; - first = max(first, current - displayMenuItems); + current = tmpCurrent > 0 ? tmpCurrent : -1; + if (current >= 0) { + if (current < first) + first = current; + else if (current - first >= displayMenuItems) + first = current - displayMenuItems + 1; + } + if (current != oldCurrent || first != oldFirst) { + Display(); + DisplayCurrent(true); } - Display(); - DisplayCurrent(true); } void cOsdMenu::Mark(void) @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: osdbase.h 1.10 2004/04/30 13:40:11 kls Exp $ + * $Id: osdbase.h 1.11 2005/06/12 10:46:34 kls Exp $ */ #ifndef __OSDBASE_H @@ -98,6 +98,7 @@ private: protected: cSkinDisplayMenu *DisplayMenu(void) { return displayMenu; } const char *hk(const char *s); + void SetCols(int c0, int c1 = 0, int c2 = 0, int c3 = 0, int c4 = 0); void SetHasHotkeys(void); virtual void Clear(void); bool SelectableItem(int idx); diff --git a/recording.c b/recording.c index 93b0af8..462b160 100644 --- a/recording.c +++ b/recording.c @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: recording.c 1.107 2005/05/29 11:16:57 kls Exp $ + * $Id: recording.c 1.109 2005/06/05 14:11:45 kls Exp $ */ #include "recording.h" @@ -480,8 +480,8 @@ cRecording::cRecording(const char *FileName) char *data[3] = { NULL }; cReadLine ReadLine; char *s; - while ((s = ReadLine.Read(f)) != NULL && line < 3) { - if (*s) { + while ((s = ReadLine.Read(f)) != NULL) { + if (*s || line > 1) { if (data[line]) { int len = strlen(s); len += strlen(data[line]) + 1; @@ -593,9 +593,10 @@ const char *cRecording::Title(char Delimiter, bool NewIndicator, int Level) cons s++; else s = name; - asprintf(&titleBuffer, "%02d.%02d%c%02d:%02d%c%c%s", + asprintf(&titleBuffer, "%02d.%02d.%02d%c%02d:%02d%c%c%s", t->tm_mday, t->tm_mon + 1, + t->tm_year % 100, Delimiter, t->tm_hour, t->tm_min, @@ -11,7 +11,7 @@ * The cDolbyRepacker code was originally written by Reinhard Nissl <rnissl@gmx.de>, * and adapted to the VDR coding style by Klaus.Schmidinger@cadsoft.de. * - * $Id: remux.c 1.33 2005/03/20 13:18:15 kls Exp $ + * $Id: remux.c 1.34 2005/06/04 14:49:25 kls Exp $ */ #include "remux.h" @@ -32,10 +32,363 @@ public: virtual void Reset(void) {} virtual int Put(cRingBufferLinear *ResultBuffer, const uchar *Data, int Count) = 0; virtual int BreakAt(const uchar *Data, int Count) = 0; + virtual int QuerySnoopSize(void) { return 0; } void SetMaxPacketSize(int MaxPacketSize) { maxPacketSize = MaxPacketSize; } void SetSubStreamId(uint8_t SubStreamId) { subStreamId = SubStreamId; } }; +// --- cVideoRepacker -------------------------------------------------------- + +class cVideoRepacker : public cRepacker { +private: + int skippedBytes; + int packetTodo; + uchar fragmentData[6 + 65535 + 3]; + int fragmentLen; + uchar pesHeader[6 + 3 + 255 + 3]; + int pesHeaderLen; + uchar pesHeaderBackup[6 + 3 + 255]; + int pesHeaderBackupLen; + uint32_t scanner; + enum eState { + syncing, + findPicture, + scanPicture + } state; + uint32_t localScanner; + int localStart; + bool PushOutPacket(cRingBufferLinear *ResultBuffer, const uchar *Data, int Count); +public: + cVideoRepacker(void); + virtual void Reset(void); + virtual int Put(cRingBufferLinear *ResultBuffer, const uchar *Data, int Count); + virtual int BreakAt(const uchar *Data, int Count); + virtual int QuerySnoopSize() { return 4; } + }; + +cVideoRepacker::cVideoRepacker(void) +{ + Reset(); +} + +void cVideoRepacker::Reset(void) +{ + skippedBytes = 0; + packetTodo = maxPacketSize - 6 - 3; + fragmentLen = 0; + pesHeaderLen = 0; + pesHeaderBackupLen = 0; + scanner = 0xFFFFFFFF; + state = syncing; + localStart = -1; +} + +bool cVideoRepacker::PushOutPacket(cRingBufferLinear *ResultBuffer, const uchar *Data, int Count) +{ + // enter packet length into PES header ... + if (fragmentLen > 0) { // ... which is contained in the fragment buffer + // determine PES packet payload + int PacketLen = fragmentLen + Count - 6; + fragmentData[ 4 ] = PacketLen >> 8; + fragmentData[ 5 ] = PacketLen & 0xFF; + // amount of data to put into result buffer: a negative Count value means + // to strip off any partially contained start code. + int Bite = fragmentLen + (Count >= 0 ? 0 : Count); + // put data into result buffer + int n = ResultBuffer->Put(fragmentData, Bite); + if (n != Bite) { + Reset(); + return false; + } + fragmentLen = 0; + } + else if (pesHeaderLen > 0) { // ... which is contained in the PES header buffer + int PacketLen = pesHeaderLen + Count - 6; + pesHeader[ 4 ] = PacketLen >> 8; + pesHeader[ 5 ] = PacketLen & 0xFF; + // amount of data to put into result buffer: a negative Count value means + // to strip off any partially contained start code. + int Bite = pesHeaderLen + (Count >= 0 ? 0 : Count); + // put data into result buffer + int n = ResultBuffer->Put(pesHeader, Bite); + if (n != Bite) { + Reset(); + return false; + } + pesHeaderLen = 0; + } + // append further payload + if (Count > 0) { + // amount of data to put into result buffer + int Bite = Count; + // put data into result buffer + int n = ResultBuffer->Put(Data, Bite); + if (n != Bite) { + Reset(); + return false; + } + } + // we did it ;-) + return true; +} + +int cVideoRepacker::Put(cRingBufferLinear *ResultBuffer, const uchar *Data, int Count) +{ + // reset local scanner + localStart = -1; + + // check for MPEG 2 + if ((Data[6] & 0xC0) != 0x80) + return 0; + + // backup PES header + if (Data[6] != 0x80 || Data[7] != 0x00 || Data[8] != 0x00) { + pesHeaderBackupLen = 6 + 3 + Data[8]; + memcpy(pesHeaderBackup, Data, pesHeaderBackupLen); + } + + // skip PES header + int done = 6 + 3 + Data[8]; + int todo = Count - done; + const uchar *data = Data + done; + // remember start of the data + const uchar *payload = data; + + while (todo > 0) { + // collect number of skipped bytes while syncing + if (state <= syncing) + skippedBytes++; + // did we reach a start code? + scanner <<= 8; + if (scanner != 0x00000100) + scanner |= *data; + else { + scanner |= *data; + + // which kind of start code have we got? + switch (*data) { + case 0xB9 ... 0xFF: // system start codes + esyslog("cVideoRepacker: found system start code: stream seems to be scrambled or not demultiplexed"); + Reset(); + break; + case 0xB0 ... 0xB1: // reserved start codes + case 0xB6: + esyslog("cVideoRepacker: found reserved start code: stream seems to be scrambled"); + Reset(); + break; + case 0xB4: // sequence error code + isyslog("cVideoRepacker: found sequence error code: stream seems to be damaged"); + case 0xB2: // user data start code + case 0xB5: // extension start code + break; + case 0xB7: // sequence end code + case 0xB3: // sequence header code + case 0xB8: // group start code + case 0x00: // picture start code + if (state == scanPicture) { + // the above start codes indicate that the current picture is done. So + // push out the packet to start a new packet for the next picuture. If + // the byte count get's negative then the current buffer ends in a + // partitial start code that must be stripped off, as it shall be put + // in the next packet. + if (!PushOutPacket(ResultBuffer, payload, data - 3 - payload)) + return done - 3; + // go on with syncing to the next picture + state = syncing; + } + if (state == syncing) { + // report that syncing dropped some bytes + if (skippedBytes > 4) + esyslog("cVideoRepacker: skipped %d bytes to sync on next picture", skippedBytes - 4); + skippedBytes = 0; + // if there is a PES header available, then use it ... + if (pesHeaderBackupLen > 0) { + // ISO 13818-1 says: + // In the case of video, if a PTS is present in a PES packet header + // it shall refer to the access unit containing the first picture start + // code that commences in this PES packet. A picture start code commences + // in PES packet if the first byte of the picture start code is present + // in the PES packet. + memcpy(pesHeader, pesHeaderBackup, pesHeaderBackupLen); + pesHeaderLen = pesHeaderBackupLen; + pesHeaderBackupLen = 0; + } + else { + // ... otherwise create a continuation PES header + pesHeaderLen = 0; + pesHeader[pesHeaderLen++] = 0x00; + pesHeader[pesHeaderLen++] = 0x00; + pesHeader[pesHeaderLen++] = 0x01; + pesHeader[pesHeaderLen++] = Data[3]; // video stream ID + pesHeader[pesHeaderLen++] = 0x00; // length still unknown + pesHeader[pesHeaderLen++] = 0x00; // length still unknown + pesHeader[pesHeaderLen++] = 0x80; + pesHeader[pesHeaderLen++] = 0x00; + pesHeader[pesHeaderLen++] = 0x00; + } + // append the first three bytes of the start code + pesHeader[pesHeaderLen++] = 0x00; + pesHeader[pesHeaderLen++] = 0x00; + pesHeader[pesHeaderLen++] = 0x01; + // the next packet's payload will begin with the fourth byte of + // the start code (= the actual code) + payload = data; + // as there is no length information available, assume the + // maximum we can hold in one PES packet + packetTodo = maxPacketSize - pesHeaderLen; + // go on with finding the picture data + ((int &)state)++; + } + break; + case 0x01 ... 0xAF: // slice start codes + if (state == findPicture) { + // go on with scanning the picture data + ((int &)state)++; + } + break; + } + } + data++; + done++; + todo--; + // do we have to start a new packet as there is no more space left? + if (--packetTodo <= 0) { + // we connot start a new packet here if the current might end in a start + // code and this start code shall possibly be put in the next packet. So + // overfill the current packet until we can safely detect that we won't + // break a start code into pieces: + // + // A) the last four bytes were a start code. + // B) the current byte introduces a start code. + // C) the last three bytes begin a start code. + // + // Todo : Data : Rule : Result + // -----:-------------------------------:------:------- + // : XX 00 00 00 01 YY|YY YY YY YY : : + // 0 : ^^| : A : push + // -----:-------------------------------:------:------- + // : XX XX 00 00 00 01|YY YY YY YY : : + // 0 : ^^| : B : wait + // -1 : |^^ : A : push + // -----:-------------------------------:------:------- + // : XX XX XX 00 00 00|01 YY YY YY : : + // 0 : ^^| : C : wait + // -1 : |^^ : B : wait + // -2 : | ^^ : A : push + // -----:-------------------------------:------:------- + // : XX XX XX XX 00 00|00 01 YY YY : : + // 0 : ^^| : C : wait + // -1 : |^^ : C : wait + // -2 : | ^^ : B : wait + // -3 : | ^^ : A : push + // -----:-------------------------------:------:------- + // : XX XX XX XX XX 00|00 00 01 YY : : + // 0 : ^^| : C : wait + // -1 : |^^ : C : wait + // -2 : | ^^ : : push + // -----:-------------------------------:------:------- + bool A = ((scanner & 0xFFFFFF00) == 0x00000100); + bool B = ((scanner & 0xFFFFFF) == 0x000001); + bool C = ((scanner & 0xFF) == 0x00) && (packetTodo >= -1); + if (A || (!B && !C)) { + // actually we cannot push out an overfull packet. So we'll have to + // adjust the byte count and payload start as necessary. If the byte + // count get's negative we'll have to append the excess from fragment's + // tail to the next PES header. + int bite = data + packetTodo - payload; + const uchar *excessData = fragmentData + fragmentLen + bite; + // a negative byte count means to drop some bytes from the current + // fragment's tail, to not exceed the maximum packet size. + if (!PushOutPacket(ResultBuffer, payload, bite)) + return done; + // create a continuation PES header + pesHeaderLen = 0; + pesHeader[pesHeaderLen++] = 0x00; + pesHeader[pesHeaderLen++] = 0x00; + pesHeader[pesHeaderLen++] = 0x01; + pesHeader[pesHeaderLen++] = Data[3]; // video stream ID + pesHeader[pesHeaderLen++] = 0x00; // length still unknown + pesHeader[pesHeaderLen++] = 0x00; // length still unknown + pesHeader[pesHeaderLen++] = 0x80; + pesHeader[pesHeaderLen++] = 0x00; + pesHeader[pesHeaderLen++] = 0x00; + // copy any excess data + while (bite++ < 0) { + // append the excess data here + pesHeader[pesHeaderLen++] = *excessData++; + packetTodo++; + } + // the next packet's payload will begin here + payload = data + packetTodo; + // as there is no length information available, assume the + // maximum we can hold in one PES packet + packetTodo += maxPacketSize - pesHeaderLen; + } + } + } + // the packet is done. Now store any remaining data into fragment buffer + // if we are no longer syncing. + if (state != syncing) { + // append the PES header ... + int bite = pesHeaderLen; + pesHeaderLen = 0; + if (bite > 0) { + memcpy(fragmentData + fragmentLen, pesHeader, bite); + fragmentLen += bite; + } + // append payload. It may contain part of a start code at it's end, + // which will be removed when the next packet gets processed. + bite = data - payload; + if (bite > 0) { + memcpy(fragmentData + fragmentLen, payload, bite); + fragmentLen += bite; + } + } + // we've eaten the whole packet ;-) + return Count; +} + +int cVideoRepacker::BreakAt(const uchar *Data, int Count) +{ + // enough data for test? + if (Count < 6 + 3) + return -1; + // check for MPEG 2 + if ((Data[6] & 0xC0) != 0x80) + return -1; + int headerLen = Data[8] + 6 + 3; + // enough data for test? + if (Count < headerLen) + return -1; + // just detect end of picture + if (state == scanPicture) { + // setup local scanner + if (localStart < 0) { + localScanner = scanner; + localStart = 0; + } + // start where we've stopped at the last run + const uchar *data = Data + headerLen + localStart; + const uchar *limit = Data + Count; + // scan data + while (data < limit) { + localStart++; + localScanner <<= 8; + localScanner |= *data++; + // check start codes which follow picture data + switch (localScanner) { + case 0x00000100: // picture start code + case 0x000001B8: // group start code + case 0x000001B3: // sequence header code + case 0x000001B7: // sequence end code + return data - Data; + } + } + } + // just fill up packet and append next start code + return headerLen + packetTodo + 4; +} + // --- cDolbyRepacker -------------------------------------------------------- class cDolbyRepacker : public cRepacker { @@ -462,6 +815,7 @@ cTS2PES::cTS2PES(int Pid, cRingBufferLinear *ResultBuffer, int Size, uint8_t Aud if (repacker) { repacker->SetMaxPacketSize(size); repacker->SetSubStreamId(subStreamId); + size += repacker->QuerySnoopSize(); } tsErrors = 0; @@ -801,7 +1155,7 @@ cRemux::cRemux(int VPid, const int *APids, const int *DPids, const int *SPids, b resultBuffer = new cRingBufferLinear(RESULTBUFFERSIZE, IPACKS, false, "Result"); resultBuffer->SetTimeouts(0, 100); if (VPid) - ts2pes[numTracks++] = new cTS2PES(VPid, resultBuffer, IPACKS); + ts2pes[numTracks++] = new cTS2PES(VPid, resultBuffer, IPACKS, 0x00, 0x00, new cVideoRepacker); if (APids) { int n = 0; while (*APids && numTracks < MAXTRACKS && n < MAXAPIDS) diff --git a/summary2info.pl b/summary2info.pl index 8e80abe..f757ac3 100755 --- a/summary2info.pl +++ b/summary2info.pl @@ -10,7 +10,7 @@ # See the main source file 'vdr.c' for copyright information and # how to reach the author. # -# $Id: summary2info.pl 1.2 2005/05/22 10:37:47 kls Exp $ +# $Id: summary2info.pl 1.3 2005/06/04 11:33:09 kls Exp $ $VideoDir = $ARGV[0] || die "please provide the name of the video directory\n"; @@ -24,7 +24,7 @@ for $SummaryFile (@SummaryFiles) { @data = (); while (<F>) { chomp; - if ($_) { + if ($_ || $line > 1) { $data[$line] .= '|' if ($data[$line]); $data[$line] .= $_; } @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: timers.c 1.31 2005/05/07 11:10:56 kls Exp $ + * $Id: timers.c 1.32 2005/06/11 14:19:58 kls Exp $ */ #include "timers.h" @@ -159,7 +159,7 @@ bool cTimer::ParseDay(const char *s, time_t &Day, int &WeekDays) else { // handle "day of month" for compatibility with older versions: char *tail = NULL; - int day = strtol(s, &tail, 10); + int day = strtol(d, &tail, 10); if (tail && *tail || day < 1 || day > 31) return false; time_t t = time(NULL); |