summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'media-video/vdr')
-rw-r--r--media-video/vdr/Manifest10
-rw-r--r--media-video/vdr/files/vdr-2.4.1_mainmenuhook-1.0.1.patch114
-rw-r--r--media-video/vdr/files/vdr-2.4.7_gcc11.patch26
-rw-r--r--media-video/vdr/files/vdr-2.6.1-patch-for-permashift.patch517
-rw-r--r--media-video/vdr/files/vdr-2.6.1_naludump.patch598
-rw-r--r--media-video/vdr/files/vdr-2.6.1_pinplugin.patch447
-rw-r--r--media-video/vdr/files/vdr-2.6.6_gentoo.patch (renamed from media-video/vdr/files/vdr-2.4.6_gentoo.patch)22
-rw-r--r--media-video/vdr/metadata.xml4
-rw-r--r--media-video/vdr/vdr-2.2.0-r6.ebuild301
-rw-r--r--media-video/vdr/vdr-2.2.0-r7.ebuild17
-rw-r--r--media-video/vdr/vdr-2.6.6.ebuild (renamed from media-video/vdr/vdr-2.4.7-r1.ebuild)82
-rw-r--r--media-video/vdr/vdr-2.6.7.ebuild199
12 files changed, 1932 insertions, 405 deletions
diff --git a/media-video/vdr/Manifest b/media-video/vdr/Manifest
index 42d12f50673f..bf8fec3e6a3d 100644
--- a/media-video/vdr/Manifest
+++ b/media-video/vdr/Manifest
@@ -1,9 +1,7 @@
DIST extpng-vdr-2.2.0-gentoo-edition-v1.patch.bz2 34664 BLAKE2B 81b68ebe0ef4588c3676f0b7a2c766d8d4d4f754a987b3be5868f3c6eff9158d4cea8e492ca81df535e637dbdc5baff638d1fafb4163e9d9a2d0125aba17e2e1 SHA512 16d6fbb8201f003dfe653b6a49424b794d7e697e27ad6f2383dbe17b76712ea5a3da88a676900b84d75ff7425bf3eb9084d60a89a4598758f482dc1f013f7b3e
-DIST vdr-2.1.5-naludump-0.1.diff 21548 BLAKE2B f193d982d072bbba2261d7dabd82e27795b2e4d8d18ae4486d8c559e7325b87f5902def7bb313e98585331144af62597f6f025f44ca142187e724516bc32c175 SHA512 d9188d5bfcf0588c22dc526fc1082253a1b505b322ccfbe676b8b2c12d4471af7b605924bcea85e879c9606d5e2cecdf6a6e8819cd9b8d877e5bb9f62b91251f
DIST vdr-2.2.0.tar.bz2 922708 BLAKE2B 975e07d6d4c5bd13ee92be5d6a1826d6404b0c59e20fa2e30689b185a61e02d54782ad528e6a4f15e0d36806b30bcf48aa336d63adb3604e78056ff318e0fd2c SHA512 183f58133915c6c0fe8ec2b88becbcb2a36418210e6dcf7931053d3771d727c3581593f9eb5c9693abf39e22e728f7b41c42079cd704610c3636ec05134ea93d
-DIST vdr-2.4-patch-for-permashift.diff.bz2 5298 BLAKE2B ebd00ba1c66783f97f5a6cc757cc9be6d937bd460f46b1880eec8b86ead1a5673a25ab64b733b8030e1c9a94123af28a5d6383905da265c67b2a945ba2c06c33 SHA512 3ba1968d2710061627e2a3b320e24ffeb08be6d8a7e71ed0c6732ebe6ed02d25f3a8afff524a6185ad0025d187ed9c7b259a9fb63dcf0c91e3fd2a079b5ef9d3
-DIST vdr-2.4.1_mainmenuhook-1.0.1.patch.bz2 1463 BLAKE2B 2be3597a273a92d02be0d072e3d74b39275cbbe17d22e570f416d42c46b53f43209498e569142a2cc357e5f7176d2454cb2a86d0822b29cca913eab2ae9cc27f SHA512 9d3eb501fa06ff5b03361ef65c8ddeeba5f37493cc0edc2d4f54e200e48e17607957fa95bd1540f028bc9a98ad6f42b4d38cf79e9ce971de36bed30def108759
-DIST vdr-2.4.6_pinplugin.patch.bz2 5176 BLAKE2B 142ad6551b8e37d223acf86f8c2f511cf2cb3664b5ff968bac5e44420c56bf5fdb974360df574141c424cd7a4b1e1489c4a504207420af10f722a77e6d2bad2f SHA512 d5c7263b908302ebf88a5e5ddcb658f56ee92656b40797fd48af1ff9852454adc1d1672cc97411e7744cc31a56f4d0f51df5ece102c21b2aa25d87e3c3c8fe12
-DIST vdr-2.4.6_ttxtsubs_v2.patch.bz2 51971 BLAKE2B e4915314e8f659df1c3e0ff631fd0c3dcec89053ff727fd28400dc6eecc49c1d4743a9bedaf3b11fce03fc6082309d4b4658d00a5b01aa5cbe8686e05412f882 SHA512 14c7b4397ba65e0ff9a5fb0705872f1cb6f1cdd1752b14f83f260540da25b5957632900232f83904c3d4fd6759e537c85bda2cce61455729eab3050a96441548
-DIST vdr-2.4.7.tbz2 919632 BLAKE2B be4e1ec365330855e4b2b26f44b1f35dc323e4783e96ef344a67b3e9fe2c0499760ab0f3d27c5e3bdddf5a65ebb65b0c81a62092301d34370aa19d0dd63bb1ab SHA512 41b8453bc6cdbb0db728b5d7d6624ab3ff9034b58ba443a8196f5fcc9fa78d18698cc91905890244e69d482ffc493374e6da2c97baed95fe742b888bdc63e42b
+DIST vdr-2.6.6.tbz2 946758 BLAKE2B 22ad6d0d4048347ff16a48ad137900f32dda7adfc7fb54bb1501f14cfc426185f942ffa4997de1e0318ca8c6b67a7dfc48d49b30bfda9367d7337b2d601544fc SHA512 4e798d3e39be0e851ec2e7f7cc563b070c3aa9438165a6aab8fcfc1cee5d7255cdc7dd4f6d4c4c84be770223491a9660bb41874e7b4d1ae504bbb16fe11f2a71
+DIST vdr-2.6.6_ttxtsubs_v2.patch 40549 BLAKE2B 525c05b72fa957372cc1ef91428428f664f42d92eebc06fd0b179afbe99e4ecc4919c69cef000cc15c8340c9a2506d38cbf755fd6665cde1708ce17d4320a35f SHA512 590c43e63818de8be9637cb3b32bf3399b82a181ca151d67e2341232669619020ab78ba9934da3a9c58cdb3bac56fc2a332a5838a92ee0851e42c3707726eb49
+DIST vdr-2.6.7.tbz2 948424 BLAKE2B 61a8e80feed5a90567093ae2a89e570fb2cba51e7ce8cb47cf5748af9141b0f41deb759c35e8e0a6e0d5e1bb2106834a84d2932b6b0a97f9766d221a60486a15 SHA512 e0d63d0414288bb7c09155f0014ba492a87e46650aaa20cdae098365e227075ae5f5d98f69750ac925e96e5054f7a8a41c59816038ffa0a0bc94b55d4e924f83
+DIST vdr-2.6.7_ttxtsubs_v2.patch 40549 BLAKE2B 525c05b72fa957372cc1ef91428428f664f42d92eebc06fd0b179afbe99e4ecc4919c69cef000cc15c8340c9a2506d38cbf755fd6665cde1708ce17d4320a35f SHA512 590c43e63818de8be9637cb3b32bf3399b82a181ca151d67e2341232669619020ab78ba9934da3a9c58cdb3bac56fc2a332a5838a92ee0851e42c3707726eb49
DIST vdr-menuorg-2.3.x.diff 8852 BLAKE2B 19b98d51a69f52ecda5500f51ef1741a8397953b20c490055eab0393da5f56ff9598c3e1e8ed8b915f5877e08deeb9ba7a9ef8d9356ad3a1fa12e3778869174a SHA512 7b41c3a529858a4953a57f21619ea01864e140cc1755ee0b03caf1c4de41e80c3f805653502bc8d39d02a4dfcddf720acd4a8c8bd91f4871eef31d86e8e915c0
diff --git a/media-video/vdr/files/vdr-2.4.1_mainmenuhook-1.0.1.patch b/media-video/vdr/files/vdr-2.4.1_mainmenuhook-1.0.1.patch
new file mode 100644
index 000000000000..deec2cd7cfdb
--- /dev/null
+++ b/media-video/vdr/files/vdr-2.4.1_mainmenuhook-1.0.1.patch
@@ -0,0 +1,114 @@
+original https://raw.githubusercontent.com/VDR4Arch/vdr4arch/master/vdr/vdr-MainMenuHooks.patch
+
+rebased for media-video/vdr-2.4.1
+
+Signed-off-by: Joerg Bornkessel <hd_brummy@gentoo.org> ( 2019 Dez 22 )
+diff -Naur vdr-2.4.1.orig/config.h vdr-2.4.1/config.h
+--- vdr-2.4.1.orig/config.h 2019-12-22 00:04:59.000000000 +0100
++++ vdr-2.4.1/config.h 2019-12-22 00:11:25.000000000 +0100
+@@ -36,6 +36,10 @@
+ // plugins to work with newer versions of the core VDR as long as no
+ // VDR header files have changed.
+
++// The MainMenuHook Patch's version number:
++#define MAINMENUHOOKSVERSION "1.0.1"
++#define MAINMENUHOOKSVERSNUM 10001 // Version * 10000 + Major * 100 + Minor
++
+ #define MAXPRIORITY 99
+ #define MINPRIORITY (-MAXPRIORITY)
+ #define LIVEPRIORITY 0 // priority used when selecting a device for live viewing
+diff -Naur vdr-2.4.1.orig/menu.c vdr-2.4.1/menu.c
+--- vdr-2.4.1.orig/menu.c 2019-12-22 00:04:59.000000000 +0100
++++ vdr-2.4.1/menu.c 2019-12-22 00:11:25.000000000 +0100
+@@ -4395,15 +4395,31 @@
+
+ // Initial submenus:
+
++ cOsdObject *menu = NULL;
+ switch (State) {
+- case osSchedule: AddSubMenu(new cMenuSchedule); break;
+- case osChannels: AddSubMenu(new cMenuChannels); break;
+- case osTimers: AddSubMenu(new cMenuTimers); break;
+- case osRecordings: AddSubMenu(new cMenuRecordings(NULL, 0, OpenSubMenus)); break;
+- case osSetup: AddSubMenu(new cMenuSetup); break;
+- case osCommands: AddSubMenu(new cMenuCommands(tr("Commands"), &Commands)); break;
++ case osSchedule:
++ if (!cPluginManager::CallFirstService("MainMenuHooksPatch-v1.0::osSchedule", &menu))
++ menu = new cMenuSchedule;
++ break;
++ case osChannels:
++ if (!cPluginManager::CallFirstService("MainMenuHooksPatch-v1.0::osChannels", &menu))
++ menu = new cMenuChannels;
++ break;
++ case osTimers:
++ if (!cPluginManager::CallFirstService("MainMenuHooksPatch-v1.0::osTimers", &menu))
++ menu = new cMenuTimers;
++ break;
++ case osRecordings:
++ if (!cPluginManager::CallFirstService("MainMenuHooksPatch-v1.0::osRecordings", &menu))
++ menu = new cMenuRecordings(NULL, 0, OpenSubMenus);
++ break;
++ case osSetup: menu = new cMenuSetup; break;
++ case osCommands: menu = new cMenuCommands(tr("Commands"), &Commands); break;
+ default: break;
+ }
++ if (menu)
++ if (menu->IsMenu())
++ AddSubMenu((cOsdMenu *) menu);
+ }
+
+ cOsdObject *cMenuMain::PluginOsdObject(void)
+@@ -4511,13 +4527,34 @@
+ eOSState state = cOsdMenu::ProcessKey(Key);
+ HadSubMenu |= HasSubMenu();
+
++ cOsdObject *menu = NULL;
+ switch (state) {
+- case osSchedule: return AddSubMenu(new cMenuSchedule);
+- case osChannels: return AddSubMenu(new cMenuChannels);
+- case osTimers: return AddSubMenu(new cMenuTimers);
+- case osRecordings: return AddSubMenu(new cMenuRecordings);
+- case osSetup: return AddSubMenu(new cMenuSetup);
+- case osCommands: return AddSubMenu(new cMenuCommands(tr("Commands"), &Commands));
++ case osSchedule:
++ if (!cPluginManager::CallFirstService("MainMenuHooksPatch-v1.0::osSchedule", &menu))
++ menu = new cMenuSchedule;
++ else
++ state = osContinue;
++ break;
++ case osChannels:
++ if (!cPluginManager::CallFirstService("MainMenuHooksPatch-v1.0::osChannels", &menu))
++ menu = new cMenuChannels;
++ else
++ state = osContinue;
++ break;
++ case osTimers:
++ if (!cPluginManager::CallFirstService("MainMenuHooksPatch-v1.0::osTimers", &menu))
++ menu = new cMenuTimers;
++ else
++ state = osContinue;
++ break;
++ case osRecordings:
++ if (!cPluginManager::CallFirstService("MainMenuHooksPatch-v1.0::osRecordings", &menu))
++ menu = new cMenuRecordings;
++ else
++ state = osContinue;
++ break;
++ case osSetup: menu = new cMenuSetup; break;
++ case osCommands: menu = new cMenuCommands(tr("Commands"), &Commands); break;
+ case osStopRecord: if (Interface->Confirm(tr("Stop recording?"))) {
+ if (cOsdItem *item = Get(Current())) {
+ cRecordControls::Stop(item->Text() + strlen(tr(STOP_RECORDING)));
+@@ -4568,6 +4605,12 @@
+ default: break;
+ }
+ }
++ if (menu) {
++ if (menu->IsMenu())
++ return AddSubMenu((cOsdMenu *) menu);
++ pluginOsdObject = menu;
++ return osPlugin;
++ }
+ if (!HasSubMenu() && Update(HadSubMenu))
+ Display();
+ if (Key != kNone) {
diff --git a/media-video/vdr/files/vdr-2.4.7_gcc11.patch b/media-video/vdr/files/vdr-2.4.7_gcc11.patch
deleted file mode 100644
index 1e37b2f0010c..000000000000
--- a/media-video/vdr/files/vdr-2.4.7_gcc11.patch
+++ /dev/null
@@ -1,26 +0,0 @@
-Fix compile with gcc-11, officially from kls
-
-Signed-off-by: Martin Dummer <martin.dummer@gmx.net>
-
---- a/tools.h 2021/01/19 20:38:28 5.3
-+++ b/tools.h 2021/05/05 15:16:45
-@@ -53,17 +53,15 @@
-
- // In case some plugin needs to use the STL and gets an error message regarding one
- // of these functions, you can #define DISABLE_TEMPLATES_COLLIDING_WITH_STL before
--// including tools.h.
--#if !defined(__STL_CONFIG_H) // for old versions of the STL
--#if !defined(DISABLE_TEMPLATES_COLLIDING_WITH_STL) && !defined(_STL_ALGOBASE_H)
-+// including any VDR header files.
-+#if !defined(DISABLE_TEMPLATES_COLLIDING_WITH_STL)
- template<class T> inline T min(T a, T b) { return a <= b ? a : b; }
- template<class T> inline T max(T a, T b) { return a >= b ? a : b; }
- #endif
- template<class T> inline int sgn(T a) { return a < 0 ? -1 : a > 0 ? 1 : 0; }
--#if !defined(DISABLE_TEMPLATES_COLLIDING_WITH_STL) && !defined(_MOVE_H)
-+#if !defined(DISABLE_TEMPLATES_COLLIDING_WITH_STL)
- template<class T> inline void swap(T &a, T &b) { T t = a; a = b; b = t; }
- #endif
--#endif
-
- template<class T> inline T constrain(T v, T l, T h) { return v < l ? l : v > h ? h : v; }
diff --git a/media-video/vdr/files/vdr-2.6.1-patch-for-permashift.patch b/media-video/vdr/files/vdr-2.6.1-patch-for-permashift.patch
new file mode 100644
index 000000000000..03b476f986bb
--- /dev/null
+++ b/media-video/vdr/files/vdr-2.6.1-patch-for-permashift.patch
@@ -0,0 +1,517 @@
+Adapted Patch from forum post
+https://www.vdr-portal.de/forum/index.php?thread/134171-permashift-1-0-4-f%C3%BCr-vdr-2-4-betaversion/&postID=1341243#post1341243
+
+SRC Url https://www.vdr-portal.de/index.php?attachment/45632-vdr-2-5-4-patch-for-permashift-diff-gz/ adapted for vdr-2.6.1
+
+Signed-off-by: Martin Dummer <martin.dummer@gmx.net>
+
+diff -Naur vdr-2.6.1.orig/device.c vdr-2.6.1/device.c
+--- vdr-2.6.1.orig/device.c 2022-02-02 10:56:43.000000000 +0100
++++ vdr-2.6.1/device.c 2022-02-06 18:05:26.452890690 +0100
+@@ -1880,6 +1880,17 @@
+ ReleaseCamSlot();
+ }
+
++cRecorder* cDevice::GetPreRecording(const cChannel *Channel)
++{
++ cMutexLock MutexLock(&mutexReceiver);
++ for (int i = 0; i < MAXRECEIVERS; i++) {
++ if (receiver[i])
++ if (receiver[i]->IsPreRecording(Channel))
++ return (cRecorder*)receiver[i];
++ }
++ return NULL;
++}
++
+ // --- cTSBuffer -------------------------------------------------------------
+
+ cTSBuffer::cTSBuffer(int File, int Size, int DeviceNumber)
+diff -Naur vdr-2.6.1.orig/device.h vdr-2.6.1/device.h
+--- vdr-2.6.1.orig/device.h 2022-02-02 10:56:43.000000000 +0100
++++ vdr-2.6.1/device.h 2022-02-06 18:05:51.541429884 +0100
+@@ -85,6 +85,7 @@
+
+ class cPlayer;
+ class cReceiver;
++class cRecorder;
+ class cLiveSubtitle;
+
+ class cDeviceHook : public cListObject {
+@@ -854,6 +855,8 @@
+ ///< Returns true if we are currently receiving. The parameter has no meaning (for backwards compatibility only).
+ bool AttachReceiver(cReceiver *Receiver);
+ ///< Attaches the given receiver to this device.
++ cRecorder* GetPreRecording(const cChannel *Channel);
++ ///< Get precocious recording for the channel if there is one.
+ void Detach(cReceiver *Receiver, bool ReleaseCam = true);
+ ///< Detaches the given receiver from this device.
+ ///< If ReleaseCam is true, the CAM slot will be released if it
+diff -Naur vdr-2.6.1.orig/dvbplayer.c vdr-2.6.1/dvbplayer.c
+--- vdr-2.6.1.orig/dvbplayer.c 2022-02-02 10:56:43.000000000 +0100
++++ vdr-2.6.1/dvbplayer.c 2022-02-06 18:05:26.452890690 +0100
+@@ -249,13 +249,14 @@
+ cUnbufferedFile *replayFile;
+ double framesPerSecond;
+ bool isPesRecording;
+- bool pauseLive;
++ ReplayState replayState;
+ bool eof;
+ bool firstPacket;
+ ePlayModes playMode;
+ ePlayDirs playDir;
+ int trickSpeed;
+ int readIndex;
++ int startIndex;
+ bool readIndependent;
+ cFrame *readFrame;
+ cFrame *playFrame;
+@@ -271,6 +272,8 @@
+ virtual void Action(void);
+ public:
+ cDvbPlayer(const char *FileName, bool PauseLive);
++ cDvbPlayer(const char *FileName, ReplayState newReplayState);
++ void Construct(const char *FileName, ReplayState newReplayState);
+ virtual ~cDvbPlayer();
+ void SetMarks(const cMarks *Marks);
+ bool Active(void) { return cThread::Running(); }
+@@ -297,6 +300,17 @@
+ cDvbPlayer::cDvbPlayer(const char *FileName, bool PauseLive)
+ :cThread("dvbplayer")
+ {
++ Construct(FileName, PauseLive? restPauseLive : restNormal);
++}
++
++cDvbPlayer::cDvbPlayer(const char *FileName, ReplayState newReplayState)
++:cThread("dvbplayer")
++{
++ Construct(FileName, newReplayState);
++}
++
++void cDvbPlayer::Construct(const char *FileName, ReplayState newReplayState)
++{
+ nonBlockingFileReader = NULL;
+ ringBuffer = NULL;
+ marks = NULL;
+@@ -304,7 +318,8 @@
+ cRecording Recording(FileName);
+ framesPerSecond = Recording.FramesPerSecond();
+ isPesRecording = Recording.IsPesRecording();
+- pauseLive = PauseLive;
++ replayState = newReplayState;
++ bool reuse = (replayState == restReusePause || replayState == restReuseRewind);
+ eof = false;
+ firstPacket = true;
+ playMode = pmPlay;
+@@ -323,15 +338,21 @@
+ return;
+ ringBuffer = new cRingBufferFrame(PLAYERBUFSIZE);
+ // Create the index file:
+- index = new cIndexFile(FileName, false, isPesRecording, pauseLive);
++ index = new cIndexFile(FileName, false, isPesRecording, replayState == restPauseLive);
+ if (!index)
+ esyslog("ERROR: can't allocate index");
+ else if (!index->Ok()) {
+ delete index;
+ index = NULL;
+ }
+- else if (PauseLive)
++ else if (reuse)
+ framesPerSecond = cRecording(FileName).FramesPerSecond(); // the fps rate might have changed from the default
++ startIndex = 0;
++ if (replayState == restReuseRewind || replayState == restReusePause) {
++ int Current, Total;
++ GetIndex(Current, Total, false);
++ startIndex = max(Total - 1, 0);
++ }
+ }
+
+ cDvbPlayer::~cDvbPlayer()
+@@ -481,8 +502,21 @@
+ bool CutIn = false;
+ bool AtLastMark = false;
+
+- if (pauseLive)
+- Goto(0, true);
++ if (replayState == restPauseLive) {
++ Goto(0, true);
++ }
++ else if (replayState == restReuseRewind || replayState == restReusePause) {
++ readIndex = startIndex;
++ Goto(readIndex, true);
++ playMode = pmPlay;
++ if (replayState == restReuseRewind) {
++ Backward();
++ }
++ else if (replayState == restReusePause) {
++ Pause();
++ }
++ }
++
+ while (Running()) {
+ if (WaitingForData)
+ WaitingForData = !nonBlockingFileReader->WaitForDataMs(3); // this keeps the CPU load low, but reacts immediately on new data
+@@ -985,6 +1019,11 @@
+ {
+ }
+
++cDvbPlayerControl::cDvbPlayerControl(const char *FileName, ReplayState replayState)
++:cControl(player = new cDvbPlayer(FileName, replayState))
++{
++}
++
+ cDvbPlayerControl::~cDvbPlayerControl()
+ {
+ Stop();
+diff -Naur vdr-2.6.1.orig/dvbplayer.h vdr-2.6.1/dvbplayer.h
+--- vdr-2.6.1.orig/dvbplayer.h 2022-02-02 10:56:43.000000000 +0100
++++ vdr-2.6.1/dvbplayer.h 2022-02-06 18:05:26.452890690 +0100
+@@ -16,6 +16,14 @@
+
+ class cDvbPlayer;
+
++enum ReplayState
++{
++ restNormal,
++ restPauseLive,
++ restReusePause,
++ restReuseRewind
++};
++
+ class cDvbPlayerControl : public cControl {
+ private:
+ cDvbPlayer *player;
+@@ -25,6 +33,8 @@
+ // If PauseLive is true, special care is taken to make sure the index
+ // file of the recording is long enough to allow the player to display
+ // the first frame in still picture mode.
++ cDvbPlayerControl(const char *FileName, ReplayState replayState);
++ // Sets up a player for the given file. replayState represents the initial state.
+ virtual ~cDvbPlayerControl();
+ void SetMarks(const cMarks *Marks);
+ bool Active(void);
+diff -Naur vdr-2.6.1.orig/menu.c vdr-2.6.1/menu.c
+--- vdr-2.6.1.orig/menu.c 2022-02-02 10:56:43.000000000 +0100
++++ vdr-2.6.1/menu.c 2022-02-06 18:05:26.452890690 +0100
+@@ -5303,6 +5303,16 @@
+
+ cRecordControl::cRecordControl(cDevice *Device, cTimers *Timers, cTimer *Timer, bool Pause)
+ {
++ Construct(Device, Timers, Timer, Pause, NULL);
++}
++
++cRecordControl::cRecordControl(cDevice *Device, cTimers *Timers, cTimer *Timer, bool Pause, bool* reused)
++{
++ Construct(Device, Timers, Timer, Pause, reused);
++}
++
++void cRecordControl::Construct(cDevice *Device, cTimers *Timers, cTimer *Timer, bool Pause, bool* reused)
++{
+ const char *LastReplayed = cReplayControl::LastReplayed(); // must do this before locking schedules!
+ // Whatever happens here, the timers will be modified in some way...
+ Timers->SetModified();
+@@ -5331,6 +5341,7 @@
+ timer->SetPending(true);
+ timer->SetRecording(true);
+ event = timer->Event();
++ if (reused != NULL) *reused = false;
+
+ if (event || GetEvent())
+ dsyslog("Title: '%s' Subtitle: '%s'", event->Title(), event->ShortText());
+@@ -5360,8 +5371,21 @@
+ if (MakeDirs(fileName, true)) {
+ Recording.WriteInfo(); // we write this *before* attaching the recorder to the device, to make sure the info file is present when the recorder needs to update the fps value!
+ const cChannel *ch = timer->Channel();
+- recorder = new cRecorder(fileName, ch, timer->Priority());
+- if (device->AttachReceiver(recorder)) {
++
++ if (!Timer) {
++ recorder = device->GetPreRecording(ch);
++ if (recorder != NULL) {
++ recorder->ActivatePreRecording(fileName, timer->Priority());
++ if (reused != NULL) *reused = true;
++ }
++ }
++
++ if (recorder == NULL) {
++ recorder = new cRecorder(fileName, ch, timer->Priority());
++ if (!device->AttachReceiver(recorder)) DELETENULL(recorder);
++ }
++
++ if (recorder != NULL) {
+ cStatus::MsgRecording(device, Recording.Name(), Recording.FileName(), true);
+ if (!Timer && !LastReplayed) // an instant recording, maybe from cRecordControls::PauseLiveVideo()
+ cReplayControl::SetRecording(fileName);
+@@ -5371,8 +5395,6 @@
+ Recordings->AddByName(fileName);
+ return;
+ }
+- else
+- DELETENULL(recorder);
+ }
+ else
+ timer->SetDeferred(DEFERTIMER);
+@@ -5452,7 +5474,7 @@
+ cRecordControl *cRecordControls::RecordControls[MAXRECORDCONTROLS] = { NULL };
+ int cRecordControls::state = 0;
+
+-bool cRecordControls::Start(cTimers *Timers, cTimer *Timer, bool Pause)
++bool cRecordControls::Start(cTimers *Timers, cTimer *Timer, bool Pause, bool* reused)
+ {
+ static time_t LastNoDiskSpaceMessage = 0;
+ int FreeMB = 0;
+@@ -5490,7 +5512,7 @@
+ if (!Timer || Timer->Matches()) {
+ for (int i = 0; i < MAXRECORDCONTROLS; i++) {
+ if (!RecordControls[i]) {
+- RecordControls[i] = new cRecordControl(device, Timers, Timer, Pause);
++ RecordControls[i] = new cRecordControl(device, Timers, Timer, Pause, reused);
+ return RecordControls[i]->Process(time(NULL));
+ }
+ }
+@@ -5514,6 +5536,11 @@
+ return Start(Timers, NULL, Pause);
+ }
+
++bool cRecordControls::Start(cTimers *Timers, cTimer *Timer, bool Pause)
++{
++ return Start(Timers, Timer, Pause, NULL);
++}
++
+ void cRecordControls::Stop(const char *InstantId)
+ {
+ LOCK_TIMERS_WRITE;
+@@ -5549,10 +5576,17 @@
+
+ bool cRecordControls::PauseLiveVideo(void)
+ {
++ return PauseLiveVideo(false);
++}
++
++bool cRecordControls::PauseLiveVideo(bool rewind)
++{
+ Skins.Message(mtStatus, tr("Pausing live video..."));
++ bool reused = false;
+ cReplayControl::SetRecording(NULL); // make sure the new cRecordControl will set cReplayControl::LastReplayed()
+- if (Start(true)) {
+- cReplayControl *rc = new cReplayControl(true);
++ LOCK_TIMERS_WRITE;
++ if (Start(Timers, NULL, true, &reused)) {
++ cReplayControl *rc = new cReplayControl(rewind? restReuseRewind : reused? restReusePause : restPauseLive);
+ cControl::Launch(rc);
+ cControl::Attach();
+ Skins.Message(mtStatus, NULL);
+@@ -5695,7 +5729,18 @@
+ cReplayControl::cReplayControl(bool PauseLive)
+ :cDvbPlayerControl(fileName, PauseLive)
+ {
+- cDevice::PrimaryDevice()->SetKeepTracks(PauseLive);
++ Construct(PauseLive? restPauseLive : restNormal);
++}
++
++cReplayControl::cReplayControl(ReplayState replayState)
++:cDvbPlayerControl(fileName, replayState)
++{
++ Construct(replayState);
++}
++
++void cReplayControl::Construct(ReplayState replayState)
++{
++ cDevice::PrimaryDevice()->SetKeepTracks(replayState == restPauseLive);
+ currentReplayControl = this;
+ displayReplay = NULL;
+ marksModified = false;
+diff -Naur vdr-2.6.1.orig/menu.h vdr-2.6.1/menu.h
+--- vdr-2.6.1.orig/menu.h 2022-02-02 10:56:43.000000000 +0100
++++ vdr-2.6.1/menu.h 2022-02-06 18:05:26.452890690 +0100
+@@ -246,6 +246,8 @@
+ bool GetEvent(void);
+ public:
+ cRecordControl(cDevice *Device, cTimers *Timers, cTimer *Timer = NULL, bool Pause = false);
++ cRecordControl(cDevice *Device, cTimers *Timers, cTimer *Timer, bool Pause, bool* reused);
++ void Construct(cDevice *Device, cTimers *Timers, cTimer *Timer, bool Pause, bool* reused);
+ virtual ~cRecordControl();
+ bool Process(time_t t);
+ cDevice *Device(void) { return device; }
+@@ -261,10 +263,12 @@
+ static int state;
+ public:
+ static bool Start(cTimers *Timers, cTimer *Timer, bool Pause = false);
++ static bool Start(cTimers *Timers, cTimer *Timer, bool Pause, bool* reused);
+ static bool Start(bool Pause = false);
+ static void Stop(const char *InstantId);
+ static void Stop(cTimer *Timer);
+ static bool PauseLiveVideo(void);
++ static bool PauseLiveVideo(bool rewind);
+ static const char *GetInstantId(const char *LastInstantId);
+ static cRecordControl *GetRecordControl(const char *FileName);
+ static cRecordControl *GetRecordControl(const cTimer *Timer);
+@@ -320,6 +324,8 @@
+ void EditTest(void);
+ public:
+ cReplayControl(bool PauseLive = false);
++ cReplayControl(ReplayState replayState);
++ void Construct(ReplayState replayState);
+ virtual ~cReplayControl();
+ void Stop(void);
+ virtual cOsdObject *GetInfo(void);
+diff -Naur vdr-2.6.1.orig/receiver.h vdr-2.6.1/receiver.h
+--- vdr-2.6.1.orig/receiver.h 2022-02-02 10:56:43.000000000 +0100
++++ vdr-2.6.1/receiver.h 2022-02-06 18:05:26.452890690 +0100
+@@ -85,6 +85,10 @@
+ ///< case the device is needed otherwise, so code that uses a cReceiver
+ ///< should repeatedly check whether it is still attached, and if
+ ///< it isn't, delete it (or take any other appropriate measures).
++ virtual bool IsPreRecording(const cChannel *Channel) { return false; }
++ ///< prerecords given channel; may be turned into a disc recording.
++ virtual bool ActivatePreRecording(const char* fileName, int Priority) { return false; }
++ ///< turn prerecording into a disc recording
+ };
+
+ #endif //__RECEIVER_H
+diff -Naur vdr-2.6.1.orig/recorder.c vdr-2.6.1/recorder.c
+--- vdr-2.6.1.orig/recorder.c 2022-02-02 10:56:43.000000000 +0100
++++ vdr-2.6.1/recorder.c 2022-02-06 18:05:26.452890690 +0100
+@@ -164,11 +164,25 @@
+ cRecorder::cRecorder(const char *FileName, const cChannel *Channel, int Priority)
+ :cReceiver(Channel, Priority)
+ ,cThread("recording")
++,tsChecker(NULL), frameChecker(NULL), recordingInfo(NULL), ringBuffer(NULL), frameDetector(NULL), fileName(NULL), index(NULL), recordFile(NULL), recordingName(NULL)
+ {
+- tsChecker = new cTsChecker;
+- frameChecker = new cFrameChecker;
++ if (FileName != NULL) {
++ InitializeFile(FileName, Channel);
++ }
++}
++
++void cRecorder::InitializeFile(const char *FileName, const cChannel *Channel)
++{
++ if (tsChecker == NULL) {
++ tsChecker = new cTsChecker;
++ }
++ if (frameChecker == NULL) {
++ frameChecker = new cFrameChecker;
++ }
+ recordingName = strdup(FileName);
+- recordingInfo = new cRecordingInfo(recordingName);
++ if (recordingInfo == NULL) {
++ recordingInfo = new cRecordingInfo(recordingName);
++ }
+ recordingInfo->Read();
+ oldErrors = max(0, recordingInfo->Errors()); // in case this is a re-started recording
+ errors = oldErrors;
+@@ -193,7 +207,9 @@
+ Pid = Channel->Dpid(0);
+ Type = 0x06;
+ }
+- frameDetector = new cFrameDetector(Pid, Type);
++ if (frameDetector == NULL) {
++ frameDetector = new cFrameDetector(Pid, Type);
++ }
+ index = NULL;
+ fileSize = 0;
+ lastDiskSpaceCheck = time(NULL);
+diff -Naur vdr-2.6.1.orig/recorder.h vdr-2.6.1/recorder.h
+--- vdr-2.6.1.orig/recorder.h 2022-02-02 10:56:43.000000000 +0100
++++ vdr-2.6.1/recorder.h 2022-02-06 18:05:26.452890690 +0100
+@@ -19,8 +19,8 @@
+ class cTsChecker;
+ class cFrameChecker;
+
+-class cRecorder : public cReceiver, cThread {
+-private:
++class cRecorder : public cReceiver, protected cThread {
++protected:
+ cTsChecker *tsChecker;
+ cFrameChecker *frameChecker;
+ cRingBufferLinear *ringBuffer;
+@@ -41,7 +41,6 @@
+ bool RunningLowOnDiskSpace(void);
+ bool NextFile(void);
+ void HandleErrors(bool Force = false);
+-protected:
+ virtual void Activate(bool On);
+ ///< If you override Activate() you need to call Detach() (which is a
+ ///< member of the cReceiver class) from your own destructor in order
+@@ -49,6 +48,9 @@
+ ///< destroyed.
+ virtual void Receive(const uchar *Data, int Length);
+ virtual void Action(void);
++ void InitializeFile(const char *FileName, const cChannel *Channel);
++ ///< Starts recording to file.
++ ///< Called in constructor if file name has been given.
+ public:
+ cRecorder(const char *FileName, const cChannel *Channel, int Priority);
+ ///< Creates a new recorder for the given Channel and
+diff -Naur vdr-2.6.1.orig/ringbuffer.c vdr-2.6.1/ringbuffer.c
+--- vdr-2.6.1.orig/ringbuffer.c 2022-02-02 10:56:43.000000000 +0100
++++ vdr-2.6.1/ringbuffer.c 2022-02-06 18:05:26.452890690 +0100
+@@ -368,6 +368,25 @@
+ return NULL;
+ }
+
++uchar *cRingBufferLinear::GetRest(int &Count)
++{
++ int Head = head;
++ if (getThreadTid <= 0)
++ getThreadTid = cThread::ThreadId();
++ int rest = Size() - tail;
++ int diff = Head - tail;
++ int cont = (diff >= 0) ? diff : Size() + diff - margin;
++ if (cont > rest)
++ cont = rest;
++ uchar *p = buffer + tail;
++ if (cont > 0) {
++ Count = gotten = cont;
++ return p;
++ }
++ WaitForGet();
++ return NULL;
++}
++
+ void cRingBufferLinear::Del(int Count)
+ {
+ if (Count > gotten) {
+diff -Naur vdr-2.6.1.orig/ringbuffer.h vdr-2.6.1/ringbuffer.h
+--- vdr-2.6.1.orig/ringbuffer.h 2022-02-02 10:56:43.000000000 +0100
++++ vdr-2.6.1/ringbuffer.h 2022-02-06 18:05:26.452890690 +0100
+@@ -98,6 +98,12 @@
+ ///< The data will remain in the buffer until a call to Del() deletes it.
+ ///< Returns a pointer to the data, and stores the number of bytes
+ ///< actually available in Count. If the returned pointer is NULL, Count has no meaning.
++ uchar *GetRest(int &Count);
++ ///< Gets data from the ring buffer disregarding the margin.
++ ///< Might have to be called several times to get all data.
++ ///< The data will remain in the buffer until a call to Del() deletes it.
++ ///< Returns a pointer to the data, and stores the number of bytes
++ ///< actually available in Count. If the returned pointer is NULL, Count has no meaning.
+ void Del(int Count);
+ ///< Deletes at most Count bytes from the ring buffer.
+ ///< Count must be less or equal to the number that was returned by a previous
+diff -Naur vdr-2.6.1.orig/vdr.c vdr-2.6.1/vdr.c
+--- vdr-2.6.1.orig/vdr.c 2022-02-02 10:56:43.000000000 +0100
++++ vdr-2.6.1/vdr.c 2022-02-06 18:05:26.452890690 +0100
+@@ -1352,13 +1352,22 @@
+ key = kNone;
+ break;
+ // Pausing live video:
++ case kFastRew:
++ {
++ // test if there's a live buffer to rewind into...
++ LOCK_CHANNELS_READ;
++ if (cDevice::ActualDevice()->GetPreRecording(Channels->GetByNumber(cDevice::CurrentChannel())) == NULL) {
++ break;
++ }
++ }
++ // fall through to pause
+ case kPlayPause:
+ case kPause:
+ if (!Control) {
+ DELETE_MENU;
+ if (Setup.PauseKeyHandling) {
+ if (Setup.PauseKeyHandling > 1 || Interface->Confirm(tr("Pause live video?"))) {
+- if (!cRecordControls::PauseLiveVideo())
++ if (!cRecordControls::PauseLiveVideo(int(key) == kFastRew))
+ Skins.QueueMessage(mtError, tr("No free DVB device to record!"));
+ }
+ }
diff --git a/media-video/vdr/files/vdr-2.6.1_naludump.patch b/media-video/vdr/files/vdr-2.6.1_naludump.patch
new file mode 100644
index 000000000000..efea3a1d74f7
--- /dev/null
+++ b/media-video/vdr/files/vdr-2.6.1_naludump.patch
@@ -0,0 +1,598 @@
+diff -a -U 2 -r a/config.c b/config.c
+--- a/config.c
++++ b/config.c
+@@ -469,4 +469,5 @@
+ SplitEditedFiles = 0;
+ DelTimeshiftRec = 0;
++ DumpNaluFill = 0;
+ MinEventTimeout = 30;
+ MinUserInactivity = 300;
+@@ -697,4 +698,5 @@
+ else if (!strcasecmp(Name, "SplitEditedFiles")) SplitEditedFiles = atoi(Value);
+ else if (!strcasecmp(Name, "DelTimeshiftRec")) DelTimeshiftRec = atoi(Value);
++ else if (!strcasecmp(Name, "DumpNaluFill")) DumpNaluFill = atoi(Value);
+ else if (!strcasecmp(Name, "MinEventTimeout")) MinEventTimeout = atoi(Value);
+ else if (!strcasecmp(Name, "MinUserInactivity")) MinUserInactivity = atoi(Value);
+@@ -829,4 +831,5 @@
+ Store("SplitEditedFiles", SplitEditedFiles);
+ Store("DelTimeshiftRec", DelTimeshiftRec);
++ Store("DumpNaluFill", DumpNaluFill);
+ Store("MinEventTimeout", MinEventTimeout);
+ Store("MinUserInactivity", MinUserInactivity);
+diff -a -U 2 -r a/config.h b/config.h
+--- a/config.h
++++ b/config.h
+@@ -341,4 +341,5 @@
+ int SplitEditedFiles;
+ int DelTimeshiftRec;
++ int DumpNaluFill;
+ int MinEventTimeout, MinUserInactivity;
+ time_t NextWakeupTime;
+diff -a -U 2 -r a/menu.c b/menu.c
+--- a/menu.c
++++ b/menu.c
+@@ -4185,4 +4185,5 @@
+ Add(new cMenuEditBoolItem(tr("Setup.Recording$Split edited files"), &data.SplitEditedFiles));
+ Add(new cMenuEditStraItem(tr("Setup.Recording$Delete timeshift recording"),&data.DelTimeshiftRec, 3, delTimeshiftRecTexts));
++ Add(new cMenuEditBoolItem(tr("Setup.Recording$Dump NALU Fill data"), &data.DumpNaluFill));
+ }
+
+diff -a -U 2 -r a/recorder.c b/recorder.c
+--- a/recorder.c
++++ b/recorder.c
+@@ -195,4 +195,12 @@
+ }
+ frameDetector = new cFrameDetector(Pid, Type);
++ if ( Type == 0x1B // MPEG4 video
++ && (Setup.DumpNaluFill ? (strstr(FileName, "NALUKEEP") == NULL) : (strstr(FileName, "NALUDUMP") != NULL))) { // MPEG4
++ isyslog("Starting NALU fill dumper");
++ naluStreamProcessor = new cNaluStreamProcessor();
++ naluStreamProcessor->SetPid(Pid);
++ }
++ else
++ naluStreamProcessor = NULL;
+ index = NULL;
+ fileSize = 0;
+@@ -217,4 +225,10 @@
+ {
+ Detach();
++ if (naluStreamProcessor) {
++ long long int TotalPackets = naluStreamProcessor->GetTotalPackets();
++ long long int DroppedPackets = naluStreamProcessor->GetDroppedPackets();
++ isyslog("NALU fill dumper: %lld of %lld packets dropped, %lli%%", DroppedPackets, TotalPackets, TotalPackets ? DroppedPackets*100/TotalPackets : 0);
++ delete naluStreamProcessor;
++ }
+ delete index;
+ delete fileName;
+@@ -357,10 +371,32 @@
+ t.Set(MAXBROKENTIMEOUT);
+ }
+- if (recordFile->Write(b, Count) < 0) {
+- LOG_ERROR_STR(fileName->Name());
+- break;
++ if (naluStreamProcessor) {
++ naluStreamProcessor->PutBuffer(b, Count);
++ bool Fail = false;
++ while (true) {
++ int OutLength = 0;
++ uchar *OutData = naluStreamProcessor->GetBuffer(OutLength);
++ if (!OutData || OutLength <= 0)
++ break;
++ if (recordFile->Write(OutData, OutLength) < 0) {
++ LOG_ERROR_STR(fileName->Name());
++ Fail = true;
++ break;
++ }
++ HandleErrors();
++ fileSize += OutLength;
++ }
++ if (Fail)
++ break;
++ }
++ else {
++ if (recordFile->Write(b, Count) < 0) {
++ LOG_ERROR_STR(fileName->Name());
++ break;
++ }
++ HandleErrors();
++ fileSize += Count;
+ }
+- HandleErrors();
+- fileSize += Count;
++
+ }
+ }
+diff -a -U 2 -r a/recorder.h b/recorder.h
+--- a/recorder.h
++++ b/recorder.h C2022-01-08 17:51:00.397595525 +0100
+@@ -27,4 +27,5 @@
+ cFrameDetector *frameDetector;
+ cPatPmtGenerator patPmtGenerator;
++ cNaluStreamProcessor *naluStreamProcessor;
+ cFileName *fileName;
+ cRecordingInfo *recordingInfo;
+diff -a -U 2 -r a/remux.c b/remux.c
+--- a/remux.c
++++ b/remux.c
+@@ -357,4 +357,40 @@
+ }
+
++void TsExtendAdaptionField(unsigned char *Packet, int ToLength)
++{
++ // Hint: ExtenAdaptionField(p, TsPayloadOffset(p) - 4) is a null operation
++
++ int Offset = TsPayloadOffset(Packet); // First byte after existing adaption field
++
++ if (ToLength <= 0)
++ {
++ // Remove adaption field
++ Packet[3] = Packet[3] & ~TS_ADAPT_FIELD_EXISTS;
++ return;
++ }
++
++ // Set adaption field present
++ Packet[3] = Packet[3] | TS_ADAPT_FIELD_EXISTS;
++
++ // Set new length of adaption field:
++ Packet[4] = ToLength <= TS_SIZE-4 ? ToLength-1 : TS_SIZE-4-1;
++
++ if (Packet[4] == TS_SIZE-4-1)
++ {
++ // No more payload, remove payload flag
++ Packet[3] = Packet[3] & ~TS_PAYLOAD_EXISTS;
++ }
++
++ int NewPayload = TsPayloadOffset(Packet); // First byte after new adaption field
++
++ // Fill new adaption field
++ if (Offset == 4 && Offset < NewPayload)
++ Offset++; // skip adaptation_field_length
++ if (Offset == 5 && Offset < NewPayload)
++ Packet[Offset++] = 0; // various flags set to 0
++ while (Offset < NewPayload)
++ Packet[Offset++] = 0xff; // stuffing byte
++}
++
+ // --- cPatPmtGenerator ------------------------------------------------------
+
+@@ -1765,2 +1801,343 @@
+ return Processed;
+ }
++
++// --- cNaluDumper ---------------------------------------------------------
++
++cNaluDumper::cNaluDumper()
++{
++ LastContinuityOutput = -1;
++ reset();
++}
++
++void cNaluDumper::reset()
++{
++ LastContinuityInput = -1;
++ ContinuityOffset = 0;
++ PesId = -1;
++ PesOffset = 0;
++ NaluFillState = NALU_NONE;
++ NaluOffset = 0;
++ History = 0xffffffff;
++ DropAllPayload = false;
++}
++
++void cNaluDumper::ProcessPayload(unsigned char *Payload, int size, bool PayloadStart, sPayloadInfo &Info)
++{
++ Info.DropPayloadStartBytes = 0;
++ Info.DropPayloadEndBytes = 0;
++ int LastKeepByte = -1;
++
++ if (PayloadStart)
++ {
++ History = 0xffffffff;
++ PesId = -1;
++ NaluFillState = NALU_NONE;
++ }
++
++ for (int i=0; i<size; i++) {
++ History = (History << 8) | Payload[i];
++
++ PesOffset++;
++ NaluOffset++;
++
++ bool DropByte = false;
++
++ if (History >= 0x00000180 && History <= 0x000001FF)
++ {
++ // Start of PES packet
++ PesId = History & 0xff;
++ PesOffset = 0;
++ NaluFillState = NALU_NONE;
++ }
++ else if (PesId >= 0xe0 && PesId <= 0xef // video stream
++ && History >= 0x00000100 && History <= 0x0000017F) // NALU start code
++ {
++ int NaluId = History & 0xff;
++ NaluOffset = 0;
++ NaluFillState = ((NaluId & 0x1f) == 0x0c) ? NALU_FILL : NALU_NONE;
++ }
++
++ if (PesId >= 0xe0 && PesId <= 0xef // video stream
++ && PesOffset >= 1 && PesOffset <= 2)
++ {
++ Payload[i] = 0; // Zero out PES length field
++ }
++
++ if (NaluFillState == NALU_FILL && NaluOffset > 0) // Within NALU fill data
++ {
++ // We expect a series of 0xff bytes terminated by a single 0x80 byte.
++
++ if (Payload[i] == 0xFF)
++ {
++ DropByte = true;
++ }
++ else if (Payload[i] == 0x80)
++ {
++ NaluFillState = NALU_TERM; // Last byte of NALU fill, next byte sets NaluFillEnd=true
++ DropByte = true;
++ }
++ else // Invalid NALU fill
++ {
++ dsyslog("cNaluDumper: Unexpected NALU fill data: %02x", Payload[i]);
++ NaluFillState = NALU_END;
++ if (LastKeepByte == -1)
++ {
++ // Nalu fill from beginning of packet until last byte
++ // packet start needs to be dropped
++ Info.DropPayloadStartBytes = i;
++ }
++ }
++ }
++ else if (NaluFillState == NALU_TERM) // Within NALU fill data
++ {
++ // We are after the terminating 0x80 byte
++ NaluFillState = NALU_END;
++ if (LastKeepByte == -1)
++ {
++ // Nalu fill from beginning of packet until last byte
++ // packet start needs to be dropped
++ Info.DropPayloadStartBytes = i;
++ }
++ }
++
++ if (!DropByte)
++ LastKeepByte = i; // Last useful byte
++ }
++
++ Info.DropAllPayloadBytes = (LastKeepByte == -1);
++ Info.DropPayloadEndBytes = size-1-LastKeepByte;
++}
++
++bool cNaluDumper::ProcessTSPacket(unsigned char *Packet)
++{
++ bool HasAdaption = TsHasAdaptationField(Packet);
++ bool HasPayload = TsHasPayload(Packet);
++
++ // Check continuity:
++ int ContinuityInput = TsContinuityCounter(Packet);
++ if (LastContinuityInput >= 0)
++ {
++ int NewContinuityInput = HasPayload ? (LastContinuityInput + 1) & TS_CONT_CNT_MASK : LastContinuityInput;
++ int Offset = (NewContinuityInput - ContinuityInput) & TS_CONT_CNT_MASK;
++ if (Offset > 0)
++ dsyslog("cNaluDumper: TS continuity offset %i", Offset);
++ if (Offset > ContinuityOffset)
++ ContinuityOffset = Offset; // max if packets get dropped, otherwise always the current one.
++ }
++ LastContinuityInput = ContinuityInput;
++
++ if (HasPayload) {
++ sPayloadInfo Info;
++ int Offset = TsPayloadOffset(Packet);
++ ProcessPayload(Packet + Offset, TS_SIZE - Offset, TsPayloadStart(Packet), Info);
++
++ if (DropAllPayload && !Info.DropAllPayloadBytes)
++ {
++ // Return from drop packet mode to normal mode
++ DropAllPayload = false;
++
++ // Does the packet start with some remaining NALU fill data?
++ if (Info.DropPayloadStartBytes > 0)
++ {
++ // Add these bytes as stuffing to the adaption field.
++
++ // Sample payload layout:
++ // FF FF FF FF FF 80 00 00 01 xx xx xx xx
++ // ^DropPayloadStartBytes
++
++ TsExtendAdaptionField(Packet, Offset - 4 + Info.DropPayloadStartBytes);
++ }
++ }
++
++ bool DropThisPayload = DropAllPayload;
++
++ if (!DropAllPayload && Info.DropPayloadEndBytes > 0) // Payload ends with 0xff NALU Fill
++ {
++ // Last packet of useful data
++ // Do early termination of NALU fill data
++ Packet[TS_SIZE-1] = 0x80;
++ DropAllPayload = true;
++ // Drop all packets AFTER this one
++
++ // Since we already wrote the 0x80, we have to make sure that
++ // as soon as we stop dropping packets, any beginning NALU fill of next
++ // packet gets dumped. (see DropPayloadStartBytes above)
++ }
++
++ if (DropThisPayload && HasAdaption)
++ {
++ // Drop payload data, but keep adaption field data
++ TsExtendAdaptionField(Packet, TS_SIZE-4);
++ DropThisPayload = false;
++ }
++
++ if (DropThisPayload)
++ {
++ return true; // Drop packet
++ }
++ }
++
++ // Fix Continuity Counter and reproduce incoming offsets:
++ int NewContinuityOutput = TsHasPayload(Packet) ? (LastContinuityOutput + 1) & TS_CONT_CNT_MASK : LastContinuityOutput;
++ NewContinuityOutput = (NewContinuityOutput + ContinuityOffset) & TS_CONT_CNT_MASK;
++ TsSetContinuityCounter(Packet, NewContinuityOutput);
++ LastContinuityOutput = NewContinuityOutput;
++ ContinuityOffset = 0;
++
++ return false; // Keep packet
++}
++
++// --- cNaluStreamProcessor ---------------------------------------------------------
++
++cNaluStreamProcessor::cNaluStreamProcessor()
++{
++ pPatPmtParser = NULL;
++ vpid = -1;
++ data = NULL;
++ length = 0;
++ tempLength = 0;
++ tempLengthAtEnd = false;
++ TotalPackets = 0;
++ DroppedPackets = 0;
++}
++
++void cNaluStreamProcessor::PutBuffer(uchar *Data, int Length)
++{
++ if (length > 0)
++ esyslog("cNaluStreamProcessor::PutBuffer: New data before old data was processed!");
++
++ data = Data;
++ length = Length;
++}
++
++uchar* cNaluStreamProcessor::GetBuffer(int &OutLength)
++{
++ if (length <= 0)
++ {
++ // Need more data - quick exit
++ OutLength = 0;
++ return NULL;
++ }
++ if (tempLength > 0) // Data in temp buffer?
++ {
++ if (tempLengthAtEnd) // Data is at end, copy to beginning
++ {
++ // Overlapping src and dst!
++ for (int i=0; i<tempLength; i++)
++ tempBuffer[i] = tempBuffer[TS_SIZE-tempLength+i];
++ }
++ // Normalize TempBuffer fill
++ if (tempLength < TS_SIZE && length > 0)
++ {
++ int Size = min(TS_SIZE-tempLength, length);
++ memcpy(tempBuffer+tempLength, data, Size);
++ data += Size;
++ length -= Size;
++ tempLength += Size;
++ }
++ if (tempLength < TS_SIZE)
++ {
++ // All incoming data buffered, but need more data
++ tempLengthAtEnd = false;
++ OutLength = 0;
++ return NULL;
++ }
++ // Now: TempLength==TS_SIZE
++ if (tempBuffer[0] != TS_SYNC_BYTE)
++ {
++ // Need to sync on TS within temp buffer
++ int Skipped = 1;
++ while (Skipped < TS_SIZE && (tempBuffer[Skipped] != TS_SYNC_BYTE || (Skipped < length && data[Skipped] != TS_SYNC_BYTE)))
++ Skipped++;
++ esyslog("ERROR: skipped %d bytes to sync on start of TS packet", Skipped);
++ // Pass through skipped bytes
++ tempLengthAtEnd = true;
++ tempLength = TS_SIZE - Skipped; // may be 0, thats ok
++ OutLength = Skipped;
++ return tempBuffer;
++ }
++ // Now: TempBuffer is a TS packet
++ int Pid = TsPid(tempBuffer);
++ if (pPatPmtParser)
++ {
++ if (Pid == 0)
++ pPatPmtParser->ParsePat(tempBuffer, TS_SIZE);
++ else if (pPatPmtParser->IsPmtPid(Pid))
++ pPatPmtParser->ParsePmt(tempBuffer, TS_SIZE);
++ }
++
++ TotalPackets++;
++ bool Drop = false;
++ if (Pid == vpid || (pPatPmtParser && Pid == pPatPmtParser->Vpid() && pPatPmtParser->Vtype() == 0x1B))
++ Drop = NaluDumper.ProcessTSPacket(tempBuffer);
++ if (!Drop)
++ {
++ // Keep this packet, then continue with new data
++ tempLength = 0;
++ OutLength = TS_SIZE;
++ return tempBuffer;
++ }
++ // Drop TempBuffer
++ DroppedPackets++;
++ tempLength = 0;
++ }
++ // Now: TempLength==0, just process data/length
++
++ // Pointer to processed data / length:
++ uchar *Out = data;
++ uchar *OutEnd = Out;
++
++ while (length >= TS_SIZE)
++ {
++ if (data[0] != TS_SYNC_BYTE) {
++ int Skipped = 1;
++ while (Skipped < length && (data[Skipped] != TS_SYNC_BYTE || (length - Skipped > TS_SIZE && data[Skipped + TS_SIZE] != TS_SYNC_BYTE)))
++ Skipped++;
++ esyslog("ERROR: skipped %d bytes to sync on start of TS packet", Skipped);
++
++ // Pass through skipped bytes
++ if (OutEnd != data)
++ memcpy(OutEnd, data, Skipped);
++ OutEnd += Skipped;
++ continue;
++ }
++ // Now: Data starts with complete TS packet
++
++ int Pid = TsPid(data);
++ if (pPatPmtParser)
++ {
++ if (Pid == 0)
++ pPatPmtParser->ParsePat(data, TS_SIZE);
++ else if (pPatPmtParser->IsPmtPid(Pid))
++ pPatPmtParser->ParsePmt(data, TS_SIZE);
++ }
++
++ TotalPackets++;
++ bool Drop = false;
++ if (Pid == vpid || (pPatPmtParser && Pid == pPatPmtParser->Vpid() && pPatPmtParser->Vtype() == 0x1B))
++ Drop = NaluDumper.ProcessTSPacket(data);
++ if (!Drop)
++ {
++ if (OutEnd != data)
++ memcpy(OutEnd, data, TS_SIZE);
++ OutEnd += TS_SIZE;
++ }
++ else
++ {
++ DroppedPackets++;
++ }
++ data += TS_SIZE;
++ length -= TS_SIZE;
++ }
++ // Now: Less than a packet remains.
++ if (length > 0)
++ {
++ // copy remains into temp buffer
++ memcpy(tempBuffer, data, length);
++ tempLength = length;
++ tempLengthAtEnd = false;
++ length = 0;
++ }
++ OutLength = (OutEnd - Out);
++ return OutLength > 0 ? Out : NULL;
++}
+diff -a -U 2 -r a/remux.h b/remux.h
+--- a/remux.h
++++ b/remux.h
+@@ -65,4 +65,9 @@
+ }
+
++inline bool TsSetPayload(const uchar *p)
++{
++ return p[3] & TS_PAYLOAD_EXISTS;
++}
++
+ inline bool TsHasAdaptationField(const uchar *p)
+ {
+@@ -156,4 +161,5 @@
+ void TsSetPts(uchar *p, int l, int64_t Pts);
+ void TsSetDts(uchar *p, int l, int64_t Dts);
++void TsExtendAdaptionField(unsigned char *Packet, int ToLength);
+
+ // Some PES handling tools:
+@@ -550,3 +556,77 @@
+ };
+
++
++#define PATCH_NALUDUMP 100
++
++class cNaluDumper {
++ unsigned int History;
++
++ int LastContinuityInput;
++ int LastContinuityOutput;
++ int ContinuityOffset;
++
++ bool DropAllPayload;
++
++ int PesId;
++ int PesOffset;
++
++ int NaluOffset;
++
++ enum eNaluFillState {
++ NALU_NONE=0, // currently not NALU fill stream
++ NALU_FILL, // Within NALU fill stream, 0xff bytes and NALU start code in byte 0
++ NALU_TERM, // Within NALU fill stream, read 0x80 terminating byte
++ NALU_END // Beyond end of NALU fill stream, expecting 0x00 0x00 0x01 now
++ };
++
++ eNaluFillState NaluFillState;
++
++ struct sPayloadInfo {
++ int DropPayloadStartBytes;
++ int DropPayloadEndBytes;
++ bool DropAllPayloadBytes;
++ };
++
++public:
++ cNaluDumper();
++
++ void reset();
++
++ // Single packet interface:
++ bool ProcessTSPacket(unsigned char *Packet);
++
++private:
++ void ProcessPayload(unsigned char *Payload, int size, bool PayloadStart, sPayloadInfo &Info);
++};
++
++class cNaluStreamProcessor {
++ //Buffer stream interface:
++ int vpid;
++ uchar *data;
++ int length;
++ uchar tempBuffer[TS_SIZE];
++ int tempLength;
++ bool tempLengthAtEnd;
++ cPatPmtParser *pPatPmtParser;
++ cNaluDumper NaluDumper;
++
++ long long int TotalPackets;
++ long long int DroppedPackets;
++public:
++ cNaluStreamProcessor();
++
++ void SetPid(int VPid) { vpid = VPid; }
++ void SetPatPmtParser(cPatPmtParser *_pPatPmtParser) { pPatPmtParser = _pPatPmtParser; }
++ // Set either a PID or set a pointer to an PatPmtParser that will detect _one_ PID
++
++ void PutBuffer(uchar *Data, int Length);
++ // Add new data to be processed. Data must be valid until Get() returns NULL.
++ uchar* GetBuffer(int &OutLength);
++ // Returns filtered data, or NULL/0 to indicate that all data from Put() was processed
++ // or buffered.
++
++ long long int GetTotalPackets() { return TotalPackets; }
++ long long int GetDroppedPackets() { return DroppedPackets; }
++};
++
+ #endif // __REMUX_H
diff --git a/media-video/vdr/files/vdr-2.6.1_pinplugin.patch b/media-video/vdr/files/vdr-2.6.1_pinplugin.patch
new file mode 100644
index 000000000000..2552f9e7109f
--- /dev/null
+++ b/media-video/vdr/files/vdr-2.6.1_pinplugin.patch
@@ -0,0 +1,447 @@
+original vdr-pinplugin_vdr-2.3.1.diff
+rebased for media-video/vdr-2.6.1
+
+Signed-off-by: Christian Kunkel <ch.kunkel@gmx.de> ( 2021 Feb 12 )
+Reviewed-by: Martin Dummer <martin.dummer@gmx.net> ( 2022-06-22 )
+diff -Naur a/Makefile b/Makefile
+--- a/Makefile 2022-02-02 10:56:43.000000000 +0100
++++ b/Makefile 2022-06-20 08:08:11.346956148 +0200
+@@ -351,7 +351,7 @@
+ clean:
+ @$(MAKE) --no-print-directory -C $(LSIDIR) clean
+ @-rm -f $(OBJS) $(DEPFILE) vdr vdr.pc core* *~
+- @-rm -rf $(LOCALEDIR) $(PODIR)/*.mo $(PODIR)/*.pot
++ @-rm -rf $(LOCALEDIR) $(PODIR)/*~ $(PODIR)/*.mo $(PODIR)/*.pot
+ @-rm -rf include
+ @-rm -rf srcdoc
+ CLEAN: clean
+diff -Naur a/device.c b/device.c
+--- a/device.c 2022-02-02 10:56:43.000000000 +0100
++++ b/device.c 2022-06-20 08:08:11.346956148 +0200
+@@ -839,6 +839,7 @@
+ const cChannel *Channel;
+ while ((Channel = Channels->GetByNumber(n, Direction)) != NULL) {
+ // try only channels which are currently available
++ if (!cStatus::MsgChannelProtected(0, Channel)) // PIN PATCH
+ if (GetDevice(Channel, LIVEPRIORITY, true, true))
+ break;
+ n = Channel->Number() + Direction;
+@@ -860,6 +861,12 @@
+
+ eSetChannelResult cDevice::SetChannel(const cChannel *Channel, bool LiveView)
+ {
++ // I hope 'LiveView = false' indicates a channel switch for recording, // PIN PATCH
++ // I really don't know, but it works ... // PIN PATCH
++
++ if (LiveView && cStatus::MsgChannelProtected(this, Channel)) // PIN PATCH
++ return scrNotAvailable; // PIN PATCH
++
+ cMutexLock MutexLock(&mutexChannel); // to avoid a race between SVDRP CHAN and HasProgramme()
+ cStatus::MsgChannelSwitch(this, 0, LiveView);
+
+diff -Naur a/menu.c b/menu.c
+--- a/menu.c 2022-02-02 10:56:43.000000000 +0100
++++ b/menu.c 2022-06-20 08:08:11.346956148 +0200
+@@ -1035,6 +1035,18 @@
+ Add(new cMenuEditBitItem( tr("VPS"), &data.flags, tfVps));
+ Add(new cMenuEditIntItem( tr("Priority"), &data.priority, 0, MAXPRIORITY));
+ Add(new cMenuEditIntItem( tr("Lifetime"), &data.lifetime, 0, MAXLIFETIME));
++
++ // PIN PATCH
++ if (cOsd::pinValid || !data.fskProtection) Add(new cMenuEditBoolItem(tr("Childlock"),&data.fskProtection));
++ else {
++ char* buf = 0;
++ int res = 0;
++ res = asprintf(&buf, "%s\t%s", tr("Childlock"), data.fskProtection ? tr("yes") : tr("no"));
++ if (res < 0) ; // memory problems :o
++ Add(new cOsdItem(buf));
++ free(buf);
++ }
++
+ Add(file = new cMenuEditStrItem( tr("File"), data.file, sizeof(data.file)));
+ SetFirstDayItem();
+ SetPatternItem(true);
+@@ -3130,7 +3142,8 @@
+ }
+ }
+ }
+- if (*Item->Text() && !LastDir) {
++ if (*Item->Text() && !LastDir
++ && (!cStatus::MsgReplayProtected(Item->Recording(), Item->Name(), base, Item->IsDirectory(), true))) { // PIN PATCH
+ Add(Item);
+ LastItem = Item;
+ if (Item->IsDirectory())
+@@ -3201,6 +3214,9 @@
+ {
+ cMenuRecordingItem *ri = (cMenuRecordingItem *)Get(Current());
+ if (ri) {
++ if (cStatus::MsgReplayProtected(ri->Recording(), ri->Name(), base,
++ ri->IsDirectory()) == true) // PIN PATCH
++ return osContinue;
+ if (ri->IsDirectory())
+ Open();
+ else {
+@@ -4506,28 +4522,32 @@
+
+ // Basic menu items:
+
+- Add(new cOsdItem(hk(tr("Schedule")), osSchedule));
+- Add(new cOsdItem(hk(tr("Channels")), osChannels));
+- Add(new cOsdItem(hk(tr("Timers")), osTimers));
+- Add(new cOsdItem(hk(tr("Recordings")), osRecordings));
++ // PIN PATCH
++ if (!cStatus::MsgMenuItemProtected("Schedule", true)) Add(new cOsdItem(hk(tr("Schedule")), osSchedule));
++ if (!cStatus::MsgMenuItemProtected("Channels", true)) Add(new cOsdItem(hk(tr("Channels")), osChannels));
++ if (!cStatus::MsgMenuItemProtected("Timers", true)) Add(new cOsdItem(hk(tr("Timers")), osTimers));
++ if (!cStatus::MsgMenuItemProtected("Recordings", true)) Add(new cOsdItem(hk(tr("Recordings")), osRecordings));
+
+ // Plugins:
+
+ for (int i = 0; ; i++) {
+ cPlugin *p = cPluginManager::GetPlugin(i);
+ if (p) {
++ if (!cStatus::MsgPluginProtected(p, true)) { // PIN PATCH
+ const char *item = p->MainMenuEntry();
+ if (item)
+ Add(new cMenuPluginItem(hk(item), i));
+ }
++ }
+ else
+ break;
+ }
+
+ // More basic menu items:
+
+- Add(new cOsdItem(hk(tr("Setup")), osSetup));
++ if (!cStatus::MsgMenuItemProtected("Setup", true)) Add(new cOsdItem(hk(tr("Setup")), osSetup)); // PIN PATCH
+ if (Commands.Count())
++ if (!cStatus::MsgMenuItemProtected("Commands", true)) // PIN PATCH
+ Add(new cOsdItem(hk(tr("Commands")), osCommands));
+
+ Update(true);
+@@ -4600,6 +4620,14 @@
+ eOSState state = cOsdMenu::ProcessKey(Key);
+ HadSubMenu |= HasSubMenu();
+
++ // > PIN PATCH
++ cOsdItem* item = Get(Current());
++
++ if (item && item->Text() && state != osContinue && state != osUnknown && state != osBack)
++ if (cStatus::MsgMenuItemProtected(item->Text()))
++ return osContinue;
++ // PIN PATCH <
++
+ switch (state) {
+ case osSchedule: return AddSubMenu(new cMenuSchedule);
+ case osChannels: return AddSubMenu(new cMenuChannels);
+@@ -4624,6 +4652,7 @@
+ if (item) {
+ cPlugin *p = cPluginManager::GetPlugin(item->PluginIndex());
+ if (p) {
++ if (!cStatus::MsgPluginProtected(p)) { // PIN PATCH
+ cOsdObject *menu = p->MainMenuAction();
+ if (menu) {
+ if (menu->IsMenu())
+@@ -4635,6 +4664,7 @@
+ }
+ }
+ }
++ }
+ state = osEnd;
+ }
+ break;
+@@ -4814,6 +4844,7 @@
+ Channel = Direction > 0 ? Channels->Next(Channel) : Channels->Prev(Channel);
+ if (!Channel && Setup.ChannelsWrap)
+ Channel = Direction > 0 ? Channels->First() : Channels->Last();
++ if (!cStatus::MsgChannelProtected(0, Channel)) // PIN PATCH
+ if (Channel && !Channel->GroupSep() && cDevice::GetDevice(Channel, LIVEPRIORITY, true, true))
+ return Channel;
+ }
+@@ -5491,6 +5522,7 @@
+ for (int i = 0; i < MAXRECORDCONTROLS; i++) {
+ if (!RecordControls[i]) {
+ RecordControls[i] = new cRecordControl(device, Timers, Timer, Pause);
++ cStatus::MsgRecordingFile(RecordControls[i]->FileName()); // PIN PATCH
+ return RecordControls[i]->Process(time(NULL));
+ }
+ }
+diff -Naur a/osd.c b/osd.c
+--- a/osd.c 2022-02-02 10:56:43.000000000 +0100
++++ b/osd.c 2022-06-20 08:08:11.346956148 +0200
+@@ -1844,6 +1844,7 @@
+ cSize cOsd::maxPixmapSize(INT_MAX, INT_MAX);
+ cVector<cOsd *> cOsd::Osds;
+ cMutex cOsd::mutex;
++bool cOsd::pinValid = false; // PIN PATCH
+
+ cOsd::cOsd(int Left, int Top, uint Level)
+ {
+diff -Naur a/osd.h b/osd.h
+--- a/osd.h 2022-02-02 10:56:43.000000000 +0100
++++ b/osd.h 2022-06-20 08:08:11.346956148 +0200
+@@ -957,6 +957,7 @@
+ ///<
+ ///< If a plugin uses a derived cPixmap implementation, it needs to use that
+ ///< type instead of cPixmapMemory.
++ static bool pinValid; // PIN PATCH
+ };
+
+ #define MAXOSDIMAGES 64
+diff -Naur a/status.c b/status.c
+--- a/status.c 2022-02-02 10:56:43.000000000 +0100
++++ b/status.c 2022-06-20 08:08:11.346956148 +0200
+@@ -136,3 +136,55 @@
+ for (cStatus *sm = statusMonitors.First(); sm; sm = statusMonitors.Next(sm))
+ sm->OsdProgramme(PresentTime, PresentTitle, PresentSubtitle, FollowingTime, FollowingTitle, FollowingSubtitle);
+ }
++
++bool cStatus::MsgChannelProtected(const cDevice* Device, const cChannel* Channel) // PIN PATCH
++{
++ for (cStatus *sm = statusMonitors.First(); sm; sm = statusMonitors.Next(sm))
++ if (sm->ChannelProtected(Device, Channel) == true)
++ return true;
++
++ return false;
++}
++
++bool cStatus::MsgReplayProtected(const cRecording* Recording, const char* Name,
++ const char* Base, bool isDirectory, int menuView) // PIN PATCH
++{
++ for (cStatus *sm = statusMonitors.First(); sm; sm = statusMonitors.Next(sm))
++ if (sm->ReplayProtected(Recording, Name, Base, isDirectory, menuView) == true)
++ return true;
++ return false;
++}
++
++void cStatus::MsgRecordingFile(const char* FileName)
++{
++ for (cStatus *sm = statusMonitors.First(); sm; sm = statusMonitors.Next(sm)) // PIN PATCH
++ sm->RecordingFile(FileName);
++}
++
++void cStatus::MsgTimerCreation(cTimer* Timer, const cEvent *Event)
++{
++ for (cStatus *sm = statusMonitors.First(); sm; sm = statusMonitors.Next(sm)) // PIN PATCH
++ sm->TimerCreation(Timer, Event);
++}
++
++bool cStatus::MsgPluginProtected(cPlugin* Plugin, int menuView) // PIN PATCH
++{
++ for (cStatus *sm = statusMonitors.First(); sm; sm = statusMonitors.Next(sm))
++ if (sm->PluginProtected(Plugin, menuView) == true)
++ return true;
++ return false;
++}
++
++void cStatus::MsgUserAction(const eKeys key) // PIN PATCH
++{
++ for (cStatus *sm = statusMonitors.First(); sm; sm = statusMonitors.Next(sm))
++ sm->UserAction(key);
++}
++
++bool cStatus::MsgMenuItemProtected(const char* Name, int menuView) // PIN PATCH
++{
++ for (cStatus *sm = statusMonitors.First(); sm; sm = statusMonitors.Next(sm))
++ if (sm->MenuItemProtected(Name, menuView) == true)
++ return true;
++ return false;
++}
+diff -Naur a/status.h b/status.h
+--- a/status.h 2022-02-02 10:56:43.000000000 +0100
++++ b/status.h 2022-06-20 08:08:11.350956230 +0200
+@@ -14,6 +14,7 @@
+ #include "device.h"
+ #include "player.h"
+ #include "tools.h"
++#include "plugin.h"
+
+ // Several member functions of the following classes are called with a pointer to
+ // an object from a global list (cTimer, cChannel, cRecording or cEvent). In these
+@@ -99,6 +100,22 @@
+ // The OSD displays the single line Text with the current channel information.
+ virtual void OsdProgramme(time_t PresentTime, const char *PresentTitle, const char *PresentSubtitle, time_t FollowingTime, const char *FollowingTitle, const char *FollowingSubtitle) {}
+ // The OSD displays the given programme information.
++ virtual bool ChannelProtected(const cDevice *Device, const cChannel* Channel) { return false; } // PIN PATCH
++ // Checks if a channel is protected.
++ virtual bool ReplayProtected(const cRecording* Recording, const char* Name,
++ const char* Base, bool isDirectory, int menuView = false) { return false; } // PIN PATCH
++ // Checks if a recording is protected.
++ virtual void RecordingFile(const char* FileName) {} // PIN PATCH
++ // The given DVB device has started recording to FileName. FileName is the name of the
++ // recording directory
++ virtual void TimerCreation(cTimer* Timer, const cEvent *Event) {} // PIN PATCH
++ // The given timer is created
++ virtual bool PluginProtected(cPlugin* Plugin, int menuView = false) { return false; } // PIN PATCH
++ // Checks if a plugin is protected.
++ virtual void UserAction(const eKeys key) {} // PIN PATCH
++ // report user action
++ virtual bool MenuItemProtected(const char* Name, int menuView = false) { return false; } // PIN PATCH
++
+ public:
+ cStatus(void);
+ virtual ~cStatus();
+@@ -122,6 +139,14 @@
+ static void MsgOsdTextItem(const char *Text, bool Scroll = false);
+ static void MsgOsdChannel(const char *Text);
+ static void MsgOsdProgramme(time_t PresentTime, const char *PresentTitle, const char *PresentSubtitle, time_t FollowingTime, const char *FollowingTitle, const char *FollowingSubtitle);
++ static bool MsgChannelProtected(const cDevice* Device, const cChannel* Channel); // PIN PATCH
++ static bool MsgReplayProtected(const cRecording* Recording, const char* Name,
++ const char* Base, bool isDirectory, int menuView = false); // PIN PATCH
++ static void MsgRecordingFile(const char* FileName); // PIN PATCH
++ static void MsgTimerCreation(cTimer* Timer, const cEvent *Event); // PIN PATCH
++ static bool MsgPluginProtected(cPlugin* Plugin, int menuView = false); // PIN PATCH
++ static void MsgUserAction(const eKeys key); // PIN PATCH
++ static bool MsgMenuItemProtected(const char* Name, int menuView = false); // PIN PATCH
+ };
+
+ #endif //__STATUS_H
+diff -Naur a/timers.c b/timers.c
+--- a/timers.c 2022-02-02 10:56:43.000000000 +0100
++++ b/timers.c 2022-06-20 08:14:07.898392829 +0200
+@@ -81,6 +81,7 @@
+ stop -= 2400;
+ priority = Pause ? Setup.PausePriority : Setup.DefaultPriority;
+ lifetime = Pause ? Setup.PauseLifetime : Setup.DefaultLifetime;
++ fskProtection = 0; // PIN PATCH
+ if (Instant && channel)
+ snprintf(file, sizeof(file), "%s%s", Setup.MarkInstantRecord ? "@" : "", *Setup.NameInstantRecord ? Setup.NameInstantRecord : channel->Name());
+ }
+@@ -212,11 +213,13 @@
+ stop -= 2400;
+ priority = PatternTimer ? PatternTimer->Priority() : Setup.DefaultPriority;
+ lifetime = PatternTimer ? PatternTimer->Lifetime() : Setup.DefaultLifetime;
++ fskProtection = 0; // PIN PATCH
+ if (!FileName)
+ FileName = Event->Title();
+ if (!isempty(FileName))
+ Utf8Strn0Cpy(file, FileName, sizeof(file));
+ SetEvent(Event);
++ cStatus::MsgTimerCreation(this, Event); // PIN PATCH
+ }
+
+ cTimer::cTimer(const cTimer &Timer)
+@@ -255,6 +258,7 @@
+ stop = Timer.stop;
+ priority = Timer.priority;
+ lifetime = Timer.lifetime;
++ fskProtection = Timer.fskProtection; // PIN PATCH
+ strncpy(pattern, Timer.pattern, sizeof(pattern));
+ strncpy(file, Timer.file, sizeof(file));
+ free(aux);
+@@ -484,6 +488,7 @@
+ result = false;
+ }
+ }
++ fskProtection = aux && strstr(aux, "<pin-plugin><protected>yes</protected></pin-plugin>"); // PIN PATCH
+ free(channelbuffer);
+ free(daybuffer);
+ free(filebuffer);
+@@ -1037,6 +1042,36 @@
+ Matches(); // refresh start and end time
+ }
+
++void cTimer::SetFskProtection(int aFlag) // PIN PATCH
++{
++ char* p;
++ char* tmp = 0;
++ int res = 0;
++
++ fskProtection = aFlag;
++
++ if (fskProtection && (!aux || !strstr(aux, "<pin-plugin><protected>yes</protected></pin-plugin>")))
++ {
++ // add protection info to aux
++
++ if (aux) { tmp = strdup(aux); free(aux); }
++ res = asprintf(&aux, "%s<pin-plugin><protected>yes</protected></pin-plugin>", tmp ? tmp : "");
++ }
++ else if (!fskProtection && aux && (p = strstr(aux, "<pin-plugin><protected>yes</protected></pin-plugin>")))
++ {
++ // remove protection info from aux
++
++ res = asprintf(&tmp, "%.*s%s", (int)(p-aux), aux, p+strlen("<pin-plugin><protected>yes</protected></pin-plugin>"));
++ free(aux);
++ aux = strdup(tmp);
++ }
++
++ if (res < 0) ; // memory problems :o
++
++ if (tmp)
++ free(tmp);
++}
++
+ // --- cTimers ---------------------------------------------------------------
+
+ cTimers cTimers::timers;
+diff -Naur a/timers.h b/timers.h
+--- a/timers.h 2022-02-02 10:56:43.000000000 +0100
++++ b/timers.h 2022-06-20 08:08:11.350956230 +0200
+@@ -45,6 +45,7 @@
+ int start; ///< the start and stop time of this timer as given by the user,
+ int stop; ///< in the form hhmm, with hh (00..23) and mm (00..59) added as hh*100+mm
+ int priority;
++ int fskProtection; // PIN PATCH
+ int lifetime;
+ mutable char pattern[NAME_MAX * 2 + 1]; // same size as 'file', to be able to initially fill 'pattern' with 'file' in the 'Edit timer' menu
+ mutable char file[NAME_MAX * 2 + 1]; // *2 to be able to hold 'title' and 'episode', which can each be up to 255 characters long
+@@ -70,6 +71,7 @@
+ int Start(void) const { return start; }
+ int Stop(void) const { return stop; }
+ int Priority(void) const { return priority; }
++ int FskProtection(void) const { return fskProtection; } // PIN PATCH
+ int Lifetime(void) const { return lifetime; }
+ const char *Pattern(void) const { return pattern; }
+ const char *File(void) const { return file; }
+@@ -120,6 +122,7 @@
+ void SetRemote(const char *Remote);
+ void SetDeferred(int Seconds);
+ void SetFlags(uint Flags);
++ void SetFskProtection(int aFlag); // PIN PATCH
+ void ClrFlags(uint Flags);
+ void InvFlags(uint Flags);
+ bool HasFlags(uint Flags) const;
+diff -Naur a/vdr.c b/vdr.c
+--- a/vdr.c 2022-02-02 10:56:43.000000000 +0100
++++ b/vdr.c 2022-06-20 08:08:11.350956230 +0200
+@@ -71,6 +71,7 @@
+ #include "tools.h"
+ #include "transfer.h"
+ #include "videodir.h"
++#include "status.h" // PIN PATCH
+
+ #define MINCHANNELWAIT 10 // seconds to wait between failed channel switchings
+ #define ACTIVITYTIMEOUT 60 // seconds before starting housekeeping
+@@ -1210,6 +1211,7 @@
+ if (!Menu)
+ Interact = Control = cControl::Control(ControlMutexLock);
+ if (ISREALKEY(key)) {
++ cStatus::MsgUserAction(key); // PIN PATCH
+ EITScanner.Activity();
+ // Cancel shutdown countdown:
+ if (ShutdownHandler.countdown)
+@@ -1282,10 +1284,12 @@
+ Control->Hide();
+ cPlugin *plugin = cPluginManager::GetPlugin(PluginName);
+ if (plugin) {
++ if (!cStatus::MsgPluginProtected(plugin)) { // PIN PATCH
+ Menu = plugin->MainMenuAction();
+ if (Menu)
+ Menu->Show();
+ }
++ }
+ else
+ esyslog("ERROR: unknown plugin '%s'", PluginName);
+ }
+@@ -1505,9 +1509,11 @@
+ case kPlay:
+ if (cReplayControl::LastReplayed()) {
+ Control = NULL;
++ if (cStatus::MsgReplayProtected(0, cReplayControl::LastReplayed(), 0, false) == false) { // PIN PATCH
+ cControl::Shutdown();
+ cControl::Launch(new cReplayControl);
+ }
++ }
+ else
+ DirectMainFunction(osRecordings); // no last viewed recording, so enter the Recordings menu
+ break;
diff --git a/media-video/vdr/files/vdr-2.4.6_gentoo.patch b/media-video/vdr/files/vdr-2.6.6_gentoo.patch
index 6ecd2ccfd436..0fcf4c3de943 100644
--- a/media-video/vdr/files/vdr-2.4.6_gentoo.patch
+++ b/media-video/vdr/files/vdr-2.6.6_gentoo.patch
@@ -1,12 +1,6 @@
-this patch will disable some handling in the core Makefile
-as we use for Linux FHS a different handling in gentoo
-demoplugins from core vdr install disabled
-support from Linguas variable
-
-Signed-off-by: Joerg Bornkessel <hd_brummy@gentoo.org> 2021/Feb/11
-diff -Naur vdr-2.4.6.orig/Makefile vdr-2.4.6/Makefile
---- vdr-2.4.6.orig/Makefile 2020-06-27 11:13:04.000000000 +0200
-+++ vdr-2.4.6/Makefile 2020-08-08 18:16:02.519719542 +0200
+diff -Naur a/Makefile b/Makefile
+--- a/Makefile 2024-01-25 09:44:48.000000000 +0100
++++ b/Makefile 2024-01-28 19:35:17.020243042 +0100
@@ -193,7 +193,7 @@
PODIR = po
@@ -36,10 +30,10 @@ diff -Naur vdr-2.4.6.orig/Makefile vdr-2.4.6/Makefile
install-conf: install-dirs
+ @mkdir -p $(DESTDIR)$(CONFDIR)
- @cp -pn *.conf $(DESTDIR)$(CONFDIR)
-
- # Documentation:
-@@ -307,9 +306,9 @@
+ # 'cp -n' may be broken, so let's do it the hard way
+ @for i in *.conf; do\
+ if ! [ -e $(DESTDIR)$(CONFDIR)/$$i ] ; then\
+@@ -312,9 +311,9 @@
install-doc:
@mkdir -p $(DESTDIR)$(MANDIR)/man1
@mkdir -p $(DESTDIR)$(MANDIR)/man5
@@ -52,7 +46,7 @@ diff -Naur vdr-2.4.6.orig/Makefile vdr-2.4.6/Makefile
# Plugins:
-@@ -326,8 +325,9 @@
+@@ -331,8 +330,9 @@
# Includes:
install-includes: include-dir
diff --git a/media-video/vdr/metadata.xml b/media-video/vdr/metadata.xml
index 07fd8b79f976..9cfb241df919 100644
--- a/media-video/vdr/metadata.xml
+++ b/media-video/vdr/metadata.xml
@@ -1,10 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE pkgmetadata SYSTEM "https://www.gentoo.org/dtd/metadata.dtd">
<pkgmetadata>
- <maintainer type="person">
- <email>hd_brummy@gentoo.org</email>
- <name>Joerg Bornkessel</name>
- </maintainer>
<maintainer type="person" proxied="yes">
<email>martin.dummer@gmx.net</email>
<name>Martin Dummer</name>
diff --git a/media-video/vdr/vdr-2.2.0-r6.ebuild b/media-video/vdr/vdr-2.2.0-r6.ebuild
deleted file mode 100644
index 73bef819af6e..000000000000
--- a/media-video/vdr/vdr-2.2.0-r6.ebuild
+++ /dev/null
@@ -1,301 +0,0 @@
-# Copyright 2021 Gentoo Authors
-# Distributed under the terms of the GNU General Public License v2
-
-EAPI=7
-
-inherit flag-o-matic strip-linguas toolchain-funcs
-
-# Switches supported by extensions-patch
-EXT_PATCH_FLAGS="alternatechannel graphtft naludump permashift pinplugin
- mainmenuhooks menuorg menuselection resumereset ttxtsubs"
-
-# names of the use-flags
-EXT_PATCH_FLAGS_RENAMED=""
-
-# names ext-patch uses internally, here only used for maintainer checks
-EXT_PATCH_FLAGS_RENAMED_EXT_NAME="bidi no_kbd sdnotify"
-
-MY_PV="${PV%_p*}"
-MY_P="${PN}-${MY_PV}"
-S="${WORKDIR}/${MY_P}"
-
-EXT_P="extpng-${P}-gentoo-edition-v1"
-
-DESCRIPTION="Video Disk Recorder - turns a pc into a powerful set top box for DVB"
-HOMEPAGE="http://www.tvdr.de/"
-SRC_URI="ftp://ftp.tvdr.de/vdr/${MY_P}.tar.bz2
- mirror://gentoo/${EXT_P}.patch.bz2"
-
-LICENSE="GPL-2+"
-SLOT="0"
-KEYWORDS="amd64 ~arm ~arm64 ~ppc x86"
-IUSE="bidi debug keyboard html systemd vanilla ${EXT_PATCH_FLAGS} ${EXT_PATCH_FLAGS_RENAMED}"
-
-COMMON_DEPEND="
- virtual/jpeg:*
- sys-libs/libcap
- >=media-libs/fontconfig-2.4.2
- >=media-libs/freetype-2"
-DEPEND="${COMMON_DEPEND}
- >=virtual/linuxtv-dvb-headers-5.3"
-RDEPEND="${COMMON_DEPEND}
- dev-lang/perl
- >=media-tv/gentoo-vdr-scripts-2.7
- media-fonts/corefonts
- bidi? ( dev-libs/fribidi )
- systemd? ( sys-apps/systemd )"
-BDEPEND="sys-devel/gettext"
-
-CONF_DIR="/etc/vdr"
-CAP_FILE="${S}/capabilities.sh"
-CAPS="# Capabilities of the vdr-executable for use by startscript etc."
-
-pkg_setup() {
- use debug && append-flags -g
-
- PLUGIN_LIBDIR="/usr/$(get_libdir)/vdr/plugins"
-
- tc-export CC CXX AR
-}
-
-add_cap() {
- local arg
- for arg; do
- CAPS="${CAPS}\n${arg}=1"
- done
-}
-
-enable_patch() {
- local arg ARG_UPPER
- for arg; do
- ARG_UPPER=$(echo $arg | tr '[:lower:]' '[:upper:]')
- echo "${ARG_UPPER} = 1" >> Make.config || die "cannot write to Make.config"
-
- # codesnippet to bring the extpng defines into the vdr.pc CXXFLAGS CFLAGS
- echo "-DUSE_${ARG_UPPER}" >> "${T}"/defines.tmp || die "cannot write to defines.tmp"
- cat "${T}"/defines.tmp | tr \\\012 ' ' > "${T}"/defines.IUSE || die "cannot write to defines.tmp"
- export DEFINES_IUSE=$( cat ${T}/defines.IUSE )
- done
-}
-
-extensions_add_make_conf() {
- # copy all ifdef for extensions-patch to Make.config
- sed -e '1,/need to touch the following:/d' \
- -e '/need to touch the following/,/^$/d' \
- Make.config.template >> Make.config || die "cannot write to Make.config"
-}
-
-extensions_all_defines() {
- # extract all possible settings for extensions-patch
- sed -e '/^#\?[A-Z].*= 1/!d' -e 's/^#\?//' -e 's/ .*//' \
- Make.config.template \
- | sort \
- | tr '[:upper:]' '[:lower:]' || die "error in function extensions_all_defines"
-}
-
-lang_po() {
- LING_PO=$( ls ${S}/po | sed -e "s:.po::g" | cut -d_ -f1 | tr \\\012 ' ' )
-}
-
-src_configure() {
- # support languages, written from right to left
- export "BIDI=$(usex bidi 1 0)"
- # systemd notification support
- export "SDNOTIFY=$(usex systemd 1 0)"
- # with/without keyboard
- export "USE_KBD=$(usex keyboard 1 0)"
-}
-
-src_prepare() {
- # apply maintenance-patches
- ebegin "Changing paths for gentoo"
-
- local DVBDIR="/usr/include"
- local i
- for i in ${DVB_HEADER_PATH} /usr/include/v4l-dvb-hg /usr/include; do
- [[ -d ${i} ]] || continue
- if [[ -f ${i}/linux/dvb/dmx.h ]]; then
- einfo "Found DVB header files in ${i}"
- DVBDIR="${i}"
- break
- fi
- done
-
- # checking for s2api headers
- local api_version
- api_version=$(awk -F' ' '/define DVB_API_VERSION / {print $3}' "${DVBDIR}"/linux/dvb/version.h)
- api_version=${api_version}*$(awk -F' ' '/define DVB_API_VERSION_MINOR / {print $3}' "${DVBDIR}"/linux/dvb/version.h)
-
- if [[ ${api_version:-0} -lt 5*3 ]]; then
- eerror "DVB header files do not contain s2api support or too old for ${P}"
- eerror "You cannot compile VDR against old dvb-header"
- die "DVB headers too old"
- fi
-
- cat > Make.config <<-EOT || die "cannot write to Make.config"
- #
- # Generated by ebuild ${PF}
- #
- PREFIX = /usr
- DVBDIR = ${DVBDIR}
- PLUGINLIBDIR = ${PLUGIN_LIBDIR}
- CONFDIR = ${CONF_DIR}
- VIDEODIR = /var/vdr/video
- LOCDIR = \$(PREFIX)/share/locale
- INCDIR = \$(PREFIX)/include
-
- DEFINES += -DCONFDIR=\"\$(CONFDIR)\"
- INCLUDES += -I\$(DVBDIR)
-
- # >=vdr-1.7.36-r1; parameter only used for compiletime on vdr
- # PLUGINLIBDIR (plugin Makefile old) = LIBDIR (plugin Makefile new)
- LIBDIR = ${PLUGIN_LIBDIR}
- PCDIR = /usr/$(get_libdir)/pkgconfig
-
- EOT
- eend 0
-
- # wrt bug 586070
- if has_version ">=sys-apps/systemd-230"; then
- sed -e "s:libsystemd-daemon:libsystemd:g" -i Makefile || die "sed libsystemd failed"
- fi
-
- if ! use vanilla; then
-
- # Now apply extensions patch
- eapply "${WORKDIR}/${EXT_P}.patch"
- sed -e 's/PERMASHIFT_V1/PERMASHIFT/g' -i "${S}"/*.[ch] "${S}"/Make.config* || die "sed failed"
-
- # This allows us to start even if some plugin does not exist
- # or is not loadable.
- enable_patch PLUGINMISSING
-
- if [[ -n ${VDR_MAINTAINER_MODE} ]]; then
- einfo "Doing maintainer checks:"
-
- # we do not support these patches
- # (or have them already hard enabled)
- local IGNORE_PATCHES="pluginmissing"
-
- extensions_all_defines > "${T}"/new.IUSE || die "cannot write to new.IUSE"
- echo $EXT_PATCH_FLAGS $EXT_PATCH_FLAGS_RENAMED_EXT_NAME \
- $IGNORE_PATCHES | \
- tr ' ' '\n' |sort > "${T}"/old.IUSE || die "cannot write to old.IUSE"
- local DIFFS=$(diff -u "${T}"/old.IUSE "${T}"/new.IUSE|grep '^[+-][^+-]')
- if [[ -z ${DIFFS} ]]; then
- einfo "EXT_PATCH_FLAGS are up to date."
- else
- ewarn "IUSE differences!"
- local diff
- for diff in $DIFFS; do
- ewarn "$diff"
- done
- fi
- fi
-
- ebegin "Enabling selected patches"
- local flag
- for flag in $EXT_PATCH_FLAGS; do
- use $flag && enable_patch ${flag}
- done
-
- eend 0
-
- extensions_add_make_conf
-
- # add defined use-flags compile options to vdr.pc
- sed -e "s:\$(CDEFINES) \$(CINCLUDES) \$(HDRDIR):\$(CDEFINES) \$(CINCLUDES) \$(HDRDIR) \$(DEFINES_IUSE):" \
- -i Makefile || die "sed fails on Makefile"
-
- ebegin "Make depend"
- emake .dependencies >/dev/null
- eend $? "make depend failed"
-
- eapply "${FILESDIR}/${P}_gcc7extpng.patch"
- fi
-
- eapply "${FILESDIR}/${P}_gentoo.patch"
- eapply "${FILESDIR}/${P}_unsignedtosigned.patch"
- eapply "${FILESDIR}/${P}_glibc-2.24.patch"
- eapply "${FILESDIR}/${P}-jpeg-9c.patch"
- eapply "${FILESDIR}/${P}_glibc-2.31.patch"
-
- # fix some makefile issues
- sed -e "s:ifndef NO_KBD:ifeq (\$(USE_KBD),1):" \
- -e "s:ifdef BIDI:ifeq (\$(BIDI),1):" \
- -e "s:ifdef SDNOTIFY:ifeq (\$(SDNOTIFY),1):" \
- -i "${S}"/Makefile || die "sed fails on Makefile"
-
- eapply_user
-
- add_cap CAP_UTF8
-
- add_cap CAP_IRCTRL_RUNTIME_PARAM \
- CAP_VFAT_RUNTIME_PARAM \
- CAP_CHUID \
- CAP_SHUTDOWN_AUTO_RETRY
-
- echo -e ${CAPS} > "${CAP_FILE}"
-
- # LINGUAS support
- einfo "\n \t VDR supports the LINGUAS values"
-
- lang_po
-
- einfo "\t Please set one of this values in your sytem make.conf"
- einfo "\t LINGUAS=\"${LING_PO}\"\n"
-
- if [[ -z ${LINGUAS} ]]; then
- einfo "\n \t No values in LINGUAS="
- einfo "\t You will get only english text on OSD \n"
- fi
-
- strip-linguas ${LING_PO} en
-}
-
-src_install() {
- # trick makefile not to create a videodir by supplying it with an existing
- # directory
- emake install \
- VIDEODIR="/" \
- DESTDIR="${ED}" install
-
- keepdir "${PLUGIN_LIBDIR}"
-
- # backup for plugins they don't be able to create this dir
- keepdir "${CONF_DIR}"/plugins
-
- if use html; then
- local HTML_DOCS=( *.html )
- fi
-
- local DOCS=( MANUAL INSTALL README* HISTORY CONTRIBUTORS )
-
- einstalldocs
-
- insinto /usr/share/vdr
- doins "${CAP_FILE}"
-
- if use alternatechannel; then
- insinto /etc/vdr
- doins "${FILESDIR}"/channel_alternative.conf
- fi
-
- chown -R vdr:vdr "${ED}/${CONF_DIR}" || die "chown failed"
-}
-
-pkg_postinst() {
-
- elog "\n\t---- 15 YEARS ANNIVERSARY EDITON ----\n"
- elog "\tA lot of thanks to Klaus Schmidinger"
- elog "\tfor this nice piece of Software...\n"
-
- elog "It is a good idea to run vdrplugin-rebuild now."
-
- elog "To get nice symbols in OSD we recommend to install"
- elog "\t1. emerge media-fonts/vdrsymbols-ttf"
- elog "\t2. select font VDRSymbolsSans in Setup"
- elog ""
- elog "To get an idea how to proceed now, have a look at our vdr-guide:"
- elog "\thttps://wiki.gentoo.org/wiki/VDR"
-}
diff --git a/media-video/vdr/vdr-2.2.0-r7.ebuild b/media-video/vdr/vdr-2.2.0-r7.ebuild
index ead539ebbd1f..1f82375d5508 100644
--- a/media-video/vdr/vdr-2.2.0-r7.ebuild
+++ b/media-video/vdr/vdr-2.2.0-r7.ebuild
@@ -1,4 +1,4 @@
-# Copyright 2021 Gentoo Authors
+# Copyright 2022-2024 Gentoo Authors
# Distributed under the terms of the GNU General Public License v2
EAPI=7
@@ -28,23 +28,24 @@ SRC_URI="ftp://ftp.tvdr.de/vdr/${MY_P}.tar.bz2
LICENSE="GPL-2+"
SLOT="0"
-KEYWORDS="~amd64 ~arm ~arm64 ~ppc ~x86"
+KEYWORDS="amd64 ~arm ~arm64 ~ppc x86"
IUSE="bidi debug keyboard html systemd vanilla ${EXT_PATCH_FLAGS} ${EXT_PATCH_FLAGS_RENAMED}"
COMMON_DEPEND="
- virtual/jpeg:*
+ media-libs/libjpeg-turbo
sys-libs/libcap
>=media-libs/fontconfig-2.4.2
>=media-libs/freetype-2"
DEPEND="${COMMON_DEPEND}
- >=virtual/linuxtv-dvb-headers-5.3"
+ sys-kernel/linux-headers"
RDEPEND="${COMMON_DEPEND}
dev-lang/perl
>=media-tv/gentoo-vdr-scripts-2.7
media-fonts/corefonts
bidi? ( dev-libs/fribidi )
systemd? ( sys-apps/systemd )"
-BDEPEND="sys-devel/gettext"
+BDEPEND="sys-devel/gettext
+ virtual/pkgconfig"
CONF_DIR="/etc/vdr"
CAP_FILE="${S}/capabilities.sh"
@@ -74,7 +75,7 @@ enable_patch() {
# codesnippet to bring the extpng defines into the vdr.pc CXXFLAGS CFLAGS
echo "-DUSE_${ARG_UPPER}" >> "${T}"/defines.tmp || die "cannot write to defines.tmp"
cat "${T}"/defines.tmp | tr \\\012 ' ' > "${T}"/defines.IUSE || die "cannot write to defines.tmp"
- export DEFINES_IUSE=$( cat ${T}/defines.IUSE )
+ export DEFINES_IUSE=$( cat "${T}"/defines.IUSE )
done
}
@@ -94,7 +95,7 @@ extensions_all_defines() {
}
lang_po() {
- LING_PO=$( ls ${S}/po | sed -e "s:.po::g" | cut -d_ -f1 | tr \\\012 ' ' )
+ LING_PO=$( ls "${S}"/po | sed -e "s:.po::g" | cut -d_ -f1 | tr \\\012 ' ' )
}
src_configure() {
@@ -212,9 +213,9 @@ src_prepare() {
eend $? "make depend failed"
eapply "${FILESDIR}/${P}_gcc7extpng.patch"
- eapply "${FILESDIR}/${P}_gcc11.patch"
fi
+ eapply "${FILESDIR}/${P}_gcc11.patch"
eapply "${FILESDIR}/${P}_gentoo.patch"
eapply "${FILESDIR}/${P}_unsignedtosigned.patch"
eapply "${FILESDIR}/${P}_glibc-2.24.patch"
diff --git a/media-video/vdr/vdr-2.4.7-r1.ebuild b/media-video/vdr/vdr-2.6.6.ebuild
index 0e8eed4d4ee5..953a907493f9 100644
--- a/media-video/vdr/vdr-2.4.7-r1.ebuild
+++ b/media-video/vdr/vdr-2.6.6.ebuild
@@ -1,19 +1,15 @@
-# Copyright 2021 Gentoo Authors
+# Copyright 2021-2024 Gentoo Authors
# Distributed under the terms of the GNU General Public License v2
-EAPI=7
+EAPI=8
-inherit flag-o-matic strip-linguas toolchain-funcs
+inherit flag-o-matic strip-linguas toolchain-funcs user-info
DESCRIPTION="Video Disk Recorder - turns a pc into a powerful set top box for DVB"
HOMEPAGE="http://www.tvdr.de/"
-SRC_URI="http://git.tvdr.de/?p=vdr.git;a=snapshot;h=refs/tags/2.4.7;sf=tbz2 -> ${P}.tbz2
- mainmenuhooks? ( http://vdr.websitec.de/download/${PN}/${PN}-2.4.1/${PN}-2.4.1_mainmenuhook-1.0.1.patch.bz2 )
- menuorg? ( https://projects.vdr-developer.org/projects/plg-menuorg/repository/revisions/master/raw/vdr-patch/vdr-menuorg-2.3.x.diff )
- naludump? ( https://www.udo-richter.de/vdr/files/vdr-2.1.5-naludump-0.1.diff )
- pinplugin? ( http://vdr.websitec.de/download/${PN}/vdr-2.4.6/${PN}-2.4.6_pinplugin.patch.bz2 )
- ttxtsubs? ( http://vdr.websitec.de/download/${PN}/vdr-2.4.6/${PN}-2.4.6_ttxtsubs_v2.patch.bz2 )
- permashift? ( http://vdr.websitec.de/download/${PN}/vdr-2.4.6/vdr-2.4-patch-for-permashift.diff.bz2 )"
+SRC_URI="http://git.tvdr.de/?p=vdr.git;a=snapshot;h=refs/tags/${PV};sf=tbz2 -> ${P}.tbz2
+ menuorg? ( https://github.com/vdr-projects/vdr-plugin-menuorg/raw/master/vdr-patch/vdr-menuorg-2.3.x.diff )
+ ttxtsubs? ( https://md11.it.cx/download/${PN}/${P}_ttxtsubs_v2.patch )"
LICENSE="GPL-2+"
SLOT="0"
@@ -21,22 +17,25 @@ KEYWORDS="amd64 ~arm ~arm64 ~ppc x86"
IUSE="bidi debug demoplugins html keyboard mainmenuhooks menuorg naludump permashift pinplugin systemd ttxtsubs verbose"
COMMON_DEPEND="
- virtual/jpeg:*
- sys-libs/libcap
- >=media-libs/fontconfig-2.4.2
- >=media-libs/freetype-2"
+ acct-group/vdr
+ acct-user/vdr
+ media-libs/fontconfig
+ media-libs/freetype
+ media-libs/libjpeg-turbo:=
+ sys-libs/libcap"
DEPEND="${COMMON_DEPEND}
- >=virtual/linuxtv-dvb-headers-5.3"
+ sys-kernel/linux-headers"
RDEPEND="${COMMON_DEPEND}
dev-lang/perl
media-tv/gentoo-vdr-scripts
media-fonts/corefonts
bidi? ( dev-libs/fribidi )
systemd? ( sys-apps/systemd )"
-BDEPEND="sys-devel/gettext"
+BDEPEND="
+ sys-devel/gettext
+ virtual/pkgconfig"
-REQUIRED_USE="pinplugin? ( !mainmenuhooks )
- permashift? ( !naludump !pinplugin )"
+REQUIRED_USE="permashift? ( !naludump !pinplugin )"
CONF_DIR="/etc/vdr"
CAP_FILE="${S}/capabilities.sh"
@@ -46,13 +45,7 @@ pkg_setup() {
use debug && append-flags -g
PLUGIN_LIBDIR="/usr/$(get_libdir)/vdr/plugins"
-
- # use the corrected DIR /var/lib/vdr/* for acct/{user,group) handling
- if has_version ">=media-tv/gentoo-vdr-scripts-3.0_rc1"; then
- VIDEO_DIR="/var/lib/vdr/video"
- else
- VIDEO_DIR="/var/vdr/video"
- fi
+ VIDEO_DIR="$(egethome vdr)/video"
tc-export CC CXX AR
}
@@ -65,18 +58,7 @@ add_cap() {
}
lang_po() {
- LING_PO=$( ls ${S}/po | sed -e "s:.po::g" | cut -d_ -f1 | tr \\\012 ' ' )
-}
-
-src_configure() {
- # support languages, written from right to left
- export "BIDI=$(usex bidi 1 0)"
- # systemd notification support
- export "SDNOTIFY=$(usex systemd 1 0)"
- # with/without keyboard
- export "USE_KBD=$(usex keyboard 1 0)"
- # detailed compile output for debug
- export "VERBOSE=$(usex verbose 1 0)"
+ LING_PO=$( ls "${S}"/po | sed -e "s:.po::g" | cut -d_ -f1 | tr \\\012 ' ' )
}
src_prepare() {
@@ -129,22 +111,19 @@ src_prepare() {
EOT
eend 0
- eapply "${FILESDIR}/${PN}-2.4.6_gentoo.patch"
+ eapply "${FILESDIR}/${P}_gentoo.patch"
use demoplugins || eapply "${FILESDIR}/vdr-2.4_remove_plugins.patch"
eapply "${FILESDIR}/${PN}-2.4.6_makefile-variables.patch"
# fix clang/LLVM compile
eapply "${FILESDIR}/${PN}-2.4.6_clang.patch"
- # fix gcc-11 compile
- eapply "${FILESDIR}/${P}_gcc11.patch"
-
- use naludump && eapply "${DISTDIR}/${PN}-2.1.5-naludump-0.1.diff"
- use permashift && eapply "${WORKDIR}/${PN}-2.4-patch-for-permashift.diff"
- use pinplugin && eapply "${WORKDIR}/${PN}-2.4.6_pinplugin.patch"
- use ttxtsubs && eapply "${WORKDIR}/${PN}-2.4.6_ttxtsubs_v2.patch"
+ use naludump && eapply "${FILESDIR}/${PN}-2.6.1_naludump.patch"
+ use permashift && eapply "${FILESDIR}/${PN}-2.6.1-patch-for-permashift.patch"
+ use pinplugin && eapply "${FILESDIR}/${PN}-2.6.1_pinplugin.patch"
+ use ttxtsubs && eapply "${DISTDIR}/${P}_ttxtsubs_v2.patch"
use menuorg && eapply "${DISTDIR}/vdr-menuorg-2.3.x.diff"
- use mainmenuhooks && eapply "${WORKDIR}/${PN}-2.4.1_mainmenuhook-1.0.1.patch"
+ use mainmenuhooks && eapply "${FILESDIR}/${PN}-2.4.1_mainmenuhook-1.0.1.patch"
add_cap CAP_UTF8 \
CAP_IRCTRL_RUNTIME_PARAM \
@@ -172,6 +151,17 @@ src_prepare() {
default
}
+src_configure() {
+ # support languages, written from right to left
+ export "BIDI=$(usex bidi 1 0)"
+ # systemd notification support
+ export "SDNOTIFY=$(usex systemd 1 0)"
+ # with/without keyboard
+ export "USE_KBD=$(usex keyboard 1 0)"
+ # detailed compile output for debug
+ export "VERBOSE=$(usex verbose 1 0)"
+}
+
src_install() {
# trick the makefile to not create a VIDEODIR by supplying it with an
# existing directory
diff --git a/media-video/vdr/vdr-2.6.7.ebuild b/media-video/vdr/vdr-2.6.7.ebuild
new file mode 100644
index 000000000000..d9ec76a88b84
--- /dev/null
+++ b/media-video/vdr/vdr-2.6.7.ebuild
@@ -0,0 +1,199 @@
+# Copyright 2021-2024 Gentoo Authors
+# Distributed under the terms of the GNU General Public License v2
+
+EAPI=8
+
+inherit flag-o-matic strip-linguas toolchain-funcs user-info
+
+DESCRIPTION="Video Disk Recorder - turns a pc into a powerful set top box for DVB"
+HOMEPAGE="http://www.tvdr.de/"
+SRC_URI="http://git.tvdr.de/?p=vdr.git;a=snapshot;h=refs/tags/${PV};sf=tbz2 -> ${P}.tbz2
+ menuorg? ( https://github.com/vdr-projects/vdr-plugin-menuorg/raw/master/vdr-patch/vdr-menuorg-2.3.x.diff )
+ ttxtsubs? ( https://md11.it.cx/download/${PN}/${P}_ttxtsubs_v2.patch )"
+
+LICENSE="GPL-2+"
+SLOT="0"
+KEYWORDS="~amd64 ~arm ~arm64 ~ppc ~x86"
+IUSE="bidi debug demoplugins html keyboard mainmenuhooks menuorg naludump permashift pinplugin systemd ttxtsubs verbose"
+
+COMMON_DEPEND="
+ acct-group/vdr
+ acct-user/vdr
+ media-libs/fontconfig
+ media-libs/freetype
+ media-libs/libjpeg-turbo:=
+ sys-libs/libcap"
+DEPEND="${COMMON_DEPEND}
+ sys-kernel/linux-headers"
+RDEPEND="${COMMON_DEPEND}
+ dev-lang/perl
+ media-tv/gentoo-vdr-scripts
+ media-fonts/corefonts
+ bidi? ( dev-libs/fribidi )
+ systemd? ( sys-apps/systemd )"
+BDEPEND="
+ sys-devel/gettext
+ virtual/pkgconfig"
+
+REQUIRED_USE="permashift? ( !naludump !pinplugin )"
+
+CONF_DIR="/etc/vdr"
+CAP_FILE="${S}/capabilities.sh"
+CAPS="# Capabilities of the vdr-executable for use by startscript etc."
+
+pkg_setup() {
+ use debug && append-flags -g
+
+ PLUGIN_LIBDIR="/usr/$(get_libdir)/vdr/plugins"
+ VIDEO_DIR="$(egethome vdr)/video"
+
+ tc-export CC CXX AR
+}
+
+add_cap() {
+ local arg
+ for arg; do
+ CAPS="${CAPS}\n${arg}=1"
+ done
+}
+
+lang_po() {
+ LING_PO=$( ls "${S}"/po | sed -e "s:.po::g" | cut -d_ -f1 | tr \\\012 ' ' )
+}
+
+src_prepare() {
+ # apply maintenance-patches
+ ebegin "Changing paths for gentoo"
+
+ local DVBDIR=/usr/include
+ local i
+ for i in ${DVB_HEADER_PATH} /usr/include/v4l-dvb-hg /usr/include; do
+ [[ -d ${i} ]] || continue
+ if [[ -f ${i}/linux/dvb/dmx.h ]]; then
+ einfo "Found DVB header files in ${i}"
+ DVBDIR=${i}
+ break
+ fi
+ done
+
+ # checking for s2api headers
+ local api_version
+ api_version=$(awk -F' ' '/define DVB_API_VERSION / {print $3}' "${DVBDIR}"/linux/dvb/version.h)
+ api_version=${api_version}*$(awk -F' ' '/define DVB_API_VERSION_MINOR / {print $3}' "${DVBDIR}"/linux/dvb/version.h)
+
+ if [[ ${api_version:-0} -lt 5*3 ]]; then
+ eerror "DVB header files do not contain s2api support or too old for ${P}"
+ eerror "You cannot compile VDR against old dvb-header"
+ die "DVB headers too old"
+ fi
+
+ cat > Make.config <<-EOT || die "cannot write to Make.config"
+ #
+ # Generated by ebuild ${PF}
+ #
+ PREFIX = /usr
+ DVBDIR = ${DVBDIR}
+ PLUGINLIBDIR = ${PLUGIN_LIBDIR}
+ CONFDIR = ${CONF_DIR}
+ ARGSDIR = \$(CONFDIR)/conf.d
+ VIDEODIR = ${VIDEO_DIR}
+ LOCDIR = \$(PREFIX)/share/locale
+ INCDIR = \$(PREFIX)/include
+
+ DEFINES += -DCONFDIR=\"\$(CONFDIR)\"
+ INCLUDES += -I\$(DVBDIR)
+
+ # >=vdr-1.7.36-r1; parameter only used for compiletime on vdr
+ # PLUGINLIBDIR (plugin Makefile old) = LIBDIR (plugin Makefile new)
+ LIBDIR = ${PLUGIN_LIBDIR}
+ PCDIR = /usr/$(get_libdir)/pkgconfig
+
+ EOT
+ eend 0
+
+ eapply "${FILESDIR}/vdr-2.6.6_gentoo.patch"
+ use demoplugins || eapply "${FILESDIR}/vdr-2.4_remove_plugins.patch"
+ eapply "${FILESDIR}/${PN}-2.4.6_makefile-variables.patch"
+
+ # fix clang/LLVM compile
+ eapply "${FILESDIR}/${PN}-2.4.6_clang.patch"
+
+ use naludump && eapply "${FILESDIR}/${PN}-2.6.1_naludump.patch"
+ use permashift && eapply "${FILESDIR}/${PN}-2.6.1-patch-for-permashift.patch"
+ use pinplugin && eapply "${FILESDIR}/${PN}-2.6.1_pinplugin.patch"
+ use ttxtsubs && eapply "${DISTDIR}/${P}_ttxtsubs_v2.patch"
+ use menuorg && eapply "${DISTDIR}/vdr-menuorg-2.3.x.diff"
+ use mainmenuhooks && eapply "${FILESDIR}/${PN}-2.4.1_mainmenuhook-1.0.1.patch"
+
+ add_cap CAP_UTF8 \
+ CAP_IRCTRL_RUNTIME_PARAM \
+ CAP_VFAT_RUNTIME_PARAM \
+ CAP_CHUID \
+ CAP_SHUTDOWN_AUTO_RETRY
+
+ echo -e ${CAPS} > "${CAP_FILE}" || die "cannot write to CAP_FILE"
+
+ # LINGUAS support
+ einfo "\n \t VDR supports the LINGUAS values"
+
+ lang_po
+
+ einfo "\t Please set one of this values in your sytem make.conf"
+ einfo "\t LINGUAS=\"${LING_PO}\"\n"
+
+ if [[ -z ${LINGUAS} ]]; then
+ einfo "\n \t No values in LINGUAS="
+ einfo "\t You will get only english text on OSD \n"
+ fi
+
+ strip-linguas ${LING_PO} en
+
+ default
+}
+
+src_configure() {
+ # support languages, written from right to left
+ export "BIDI=$(usex bidi 1 0)"
+ # systemd notification support
+ export "SDNOTIFY=$(usex systemd 1 0)"
+ # with/without keyboard
+ export "USE_KBD=$(usex keyboard 1 0)"
+ # detailed compile output for debug
+ export "VERBOSE=$(usex verbose 1 0)"
+}
+
+src_install() {
+ # trick the makefile to not create a VIDEODIR by supplying it with an
+ # existing directory
+ emake VIDEODIR="/" DESTDIR="${ED}" install
+
+ keepdir "${PLUGIN_LIBDIR}"
+
+ # backup for plugins they don't be able to create this dir
+ keepdir "${CONF_DIR}/plugins"
+
+ if use html; then
+ local HTML_DOCS=( *.html )
+ fi
+ local DOCS=( MANUAL INSTALL README* HISTORY CONTRIBUTORS UPDATE-2* )
+ einstalldocs
+
+ insinto /usr/share/vdr
+ doins "${CAP_FILE}"
+
+ fowners vdr:vdr "${CONF_DIR}" -R
+}
+
+pkg_postinst() {
+ elog "Please read the /usr/share/doc/${PF}/UPDATE-2.4"
+ elog "for major changes in this version\n"
+
+ elog "It is a good idea to run vdrplugin-rebuild now.\n"
+
+ elog "To get nice symbols in OSD we recommend to install"
+ elog "\t1. emerge media-fonts/vdrsymbols-ttf"
+ elog "\t2. select font VDRSymbolsSans in Setup\n"
+
+ elog "To get an idea how to proceed now, have a look at our vdr-guide:"
+ elog "\thttps://wiki.gentoo.org/wiki/VDR"
+}