Hi all,
I was an active VDR user from about 2004 to 2010 when my children were younger and there was a need to record TV programs for them. The old setup was more or less abandoned when I got a smart TV and the family started to use video streaming services.
Some years ago, I got a Raspberry Pi 2 B and an Astrometa DVB-T2 USB stick that also includes an infrared receiver. Because its bundled remote control unit (RCU) has much fewer buttons than the one that I got with the Hauppauge Nova-T PCI 90002 years ago, I configured lircd to translate the RC5 codes from the old RCU. For output, I am using rpihddevice.
Yesterday, I upgraded to VDR 2.5.6 and rpihddevice 1.0.4 from git://projects.vdr-developer.org/vdr-plugin-rpihddevice.git while keeping the rest of the Raspbian 9.13 mostly intact.
I installed the self-built software simply by replacing the original /usr/bin/vdr that was part of the distribution's vdr 2.2.0 package, and copying the plugin to /usr/lib/vdr/plugins/. It might not be the cleanest solution, but it worked for me.
I had some trouble with Systemd, which I resolved by creating a configuration file:
# cat > /etc/systemd/system/vdr.service << EOF [Service] Restart=on-failure RestartSec=1s ExecStart=/usr/bin/vdr TimeoutStartSec=infinity EOF # systemctl daemon-reload # service lightdm stop # service vdr start
I did not double-check it, but I understood that this could entirely bypass the /etc/init.d/vdr script, which would invoke the runvdr script (which normally runs vdr in a loop). If I choose Restart from the VDR menu, systemd will restart it nicely.
I did not configure the Power button yet. Currently, VDR complains that no -s parameter is given when I press the Power button on the RCU. Ideally, I think that VDR should suspend the live video output and somehow inform Systemd that the entire system may be suspended, as far as VDR is concerned. (Of course, only if there are no recordings or remote connections active to VDR.) Then, if nothing else prevents the system from being shut down or suspended, Systemd would do it based on its configuration.
Years ago, I developed some patches and configuration at https://iki.fi/msmakela/software/vdr/ to achieve something like this on my old system, and I would now like to revive this somehow. Ideally, the Power button would shut down the DVB receiver and display some indication on the OSD or the video frame buffer that the output has been suspended.
If my Raspberry Pi were not an "always-on server" that runs some other services as well, I might want to reimplement the "wake-on-RCU" hardware that is generating a wake-on-LAN signal via the Nova-T PCI card, possibly by extending https://spellfoundry.com/product/sleepy-pi-2-usb-c/ or a similar product that would implement a wake-on-timer for the Raspberry Pi. Then, the system would power up nicely either by RCU or by a recording timer.
Integrating the wake-on-timer logic with Systemd could be another challenge. I might try this on PC hardware, which already supports wake-on-timer out of the box. A quick search turned up a promising starting point: https://www.freedesktop.org/software/systemd/man/systemd.timer.html
The motivation of this exercise is to have a stand-alone VDR front/back end installation that plays nicely with Systemd, without reinventing any logic around scheduling, startup, and shutdown.
Maybe one day, once some more progress has been made with Wayland and when using a Raspberry Pi model with more GPU memory, one could press the Power button on the RCU and have the live TV pop up either fullscreen or in a window, on top of the graphical desktop (which would be available for generic use).
Best regards,
Marko
Hallo,
the problem for the shutdown bottom "no -s option" (not parameter) is in /etc/vdr/config.d/00-vdr.conf where the line 21 concerning shutdown is commented out:
#--shutdown=/usr/lib/vdr/vdr-shutdown.wrapper
I uncommented it and it worked for me with the power-off-buttom on the remote control. Perhaps this will help you.
VDR 2.4.2 on linux mate 20.4
Regards
gbruno
Am 12.09.21 um 11:46 schrieb Marko Mäkelä:
Hi all,
I was an active VDR user from about 2004 to 2010 when my children were younger and there was a need to record TV programs for them. The old setup was more or less abandoned when I got a smart TV and the family started to use video streaming services.
Some years ago, I got a Raspberry Pi 2 B and an Astrometa DVB-T2 USB stick that also includes an infrared receiver. Because its bundled remote control unit (RCU) has much fewer buttons than the one that I got with the Hauppauge Nova-T PCI 90002 years ago, I configured lircd to translate the RC5 codes from the old RCU. For output, I am using rpihddevice.
Yesterday, I upgraded to VDR 2.5.6 and rpihddevice 1.0.4 from git://projects.vdr-developer.org/vdr-plugin-rpihddevice.git while keeping the rest of the Raspbian 9.13 mostly intact.
I installed the self-built software simply by replacing the original /usr/bin/vdr that was part of the distribution's vdr 2.2.0 package, and copying the plugin to /usr/lib/vdr/plugins/. It might not be the cleanest solution, but it worked for me.
I had some trouble with Systemd, which I resolved by creating a configuration file:
# cat > /etc/systemd/system/vdr.service << EOF [Service] Restart=on-failure RestartSec=1s ExecStart=/usr/bin/vdr TimeoutStartSec=infinity EOF # systemctl daemon-reload # service lightdm stop # service vdr start
I did not double-check it, but I understood that this could entirely bypass the /etc/init.d/vdr script, which would invoke the runvdr script (which normally runs vdr in a loop). If I choose Restart from the VDR menu, systemd will restart it nicely.
I did not configure the Power button yet. Currently, VDR complains that no -s parameter is given when I press the Power button on the RCU. Ideally, I think that VDR should suspend the live video output and somehow inform Systemd that the entire system may be suspended, as far as VDR is concerned. (Of course, only if there are no recordings or remote connections active to VDR.) Then, if nothing else prevents the system from being shut down or suspended, Systemd would do it based on its configuration.
Years ago, I developed some patches and configuration at https://iki.fi/msmakela/software/vdr/ to achieve something like this on my old system, and I would now like to revive this somehow. Ideally, the Power button would shut down the DVB receiver and display some indication on the OSD or the video frame buffer that the output has been suspended.
If my Raspberry Pi were not an "always-on server" that runs some other services as well, I might want to reimplement the "wake-on-RCU" hardware that is generating a wake-on-LAN signal via the Nova-T PCI card, possibly by extending https://spellfoundry.com/product/sleepy-pi-2-usb-c/ or a similar product that would implement a wake-on-timer for the Raspberry Pi. Then, the system would power up nicely either by RCU or by a recording timer. Integrating the wake-on-timer logic with Systemd could be another challenge. I might try this on PC hardware, which already supports wake-on-timer out of the box. A quick search turned up a promising starting point: https://www.freedesktop.org/software/systemd/man/systemd.timer.html
The motivation of this exercise is to have a stand-alone VDR front/back end installation that plays nicely with Systemd, without reinventing any logic around scheduling, startup, and shutdown.
Maybe one day, once some more progress has been made with Wayland and when using a Raspberry Pi model with more GPU memory, one could press the Power button on the RCU and have the live TV pop up either fullscreen or in a window, on top of the graphical desktop (which would be available for generic use).
Best regards,
Marko
vdr mailing list vdr@linuxtv.org https://www.linuxtv.org/cgi-bin/mailman/listinfo/vdr
Mon, Sep 13, 2021 at 10:57:23AM +0200, g.bruno wrote:
Hallo,
the problem for the shutdown bottom "no -s option" (not parameter) is in /etc/vdr/config.d/00-vdr.conf where the line 21 concerning shutdown is commented out:
#--shutdown=/usr/lib/vdr/vdr-shutdown.wrapper
Thank you, but it is not that simple in case VDR is not the main use of the system. What I would want to achieve is some kind of a "wake lock" (borrowing Android terminology): the system would shut down automatically after some timeout, unless a service prevents it from shutting down. VDR would be only one such service. There could other reasons that prevent a shutdown, say, a user being logged in, or a file server running or being actively used.
I would want VDR to release most resources (and stop consuming 5% of CPU time and a larger chunk of the 1GiB RAM) when I press the Power button on the RCU. If I press the button again, VDR should wake up. Maybe this can be achieved with a "shutdown" program that would not actually shut anything down, but wait for another Power button press to possibly start up VDR.
Another feature that I might want is that when I plug in the DVB-T2 stick into the computer, VDR will start up. That is, the main purpose of the computer could be something else, and the computer would switch to "appliance mode" only when needed. Likewise, the USB stick would only consume power and expose the system to lighting (via the antenna mast) when needed (when someone wants to watch or record something with VDR). That I believe is achievable with udev rules. Maybe the whole should then be driven via udevd and not systemd.
When time permits, I will try to experiment more.
Marko
Hi all, hi Marko!
Am 12.09.21 um 11:46 schrieb Marko Mäkelä:
I was an active VDR user from about 2004 to 2010
Yes good times! :-)
Actually I still use the VDR excatly for the same reasons: to record shows for my kids.
If my Raspberry Pi were not an "always-on server" that runs some other services as well, I might want to reimplement the "wake-on-RCU" hardware that is generating a wake-on-LAN signal via the Nova-T PCI card, possibly by extending https://spellfoundry.com/product/sleepy-pi-2-usb-c/ or a similar product that would implement a wake-on-timer for the Raspberry Pi. Then, the system would power up nicely either by RCU or by a recording timer. Integrating the wake-on-timer logic with Systemd could be another challenge. I might try this on PC hardware, which already supports wake-on-timer out of the box. A quick search turned up a promising starting point: https://www.freedesktop.org/software/systemd/man/systemd.timer.html
The motivation of this exercise is to have a stand-alone VDR front/back end installation that plays nicely with Systemd, without reinventing any logic around scheduling, startup, and shutdown.
I currently don't use systemd, but I have a similar use case for my server. I agree that a solution with systemd would be nicer, but a few years back, I didn't get systemd to work with vdr the way I liked.
So I've created a python script which starts vdr, and if vdr stops it captures the next time vdr requests to be run. Then it kills vdr, unloads the dvb drivers (which also switches of the LNBs) and opens all the network ports vdr is using.
A second script runs every 5 minutes or so and checks if vdr is running, a user is logged in, or some other services have been recently used. If not it suspends the server and sets the wake-up time to vdr requested time. So the server wakes up ahead of a recording.
The python script checks if the start time requested by vdr is close, and starts vdr a few minutes before the requested time.
If I need the server or vdr I just send a wol packet. When I access the vdr and the python script is running instead of the vdr, the python script closes all network ports, loads the dvb drivers and starts the vdr. This even worked very nicely with kodi, but I stopped using kodi, I don't like the user interface. Now I use vdr-xineliboutput. I have to start vdr-xineliboutput several times until the vdr is started, but I don't mind :-).
Using this setup I can use the server for many more services, and don't waste power when I don't need the vdr.
This was partly inspired by systemd, but I think it is still not possible to implement this with systemd.
I can share the scripts if you like to modify them for your needs.
Regards,
Martin
Hi all, hi Martin!
Mon, Sep 13, 2021 at 08:51:05PM +0200, Martin Wache wrote:
Yes good times! :-)
I think that softdevice (without HD in the name) was quite an achievement for the hardware that was available about 20 years ago.
Today, I made a little progress on this. First, I was thinking to set up an unused IBM Thinkpad X60 for VDR. In the end, I found out that softhddevice depends on a number of X11 libraries.
I also found some forum posts that suggested that it is not expected to work with Wayland. If I understood correctly, Wayland helps reduce the CPU overhead, as long as there is some GPU support for compositing RGBA buffers, and it could simplify the rendering path.
In the end, I decided that one 32-bit CPU core (2 with hyperthreading) and a 1024×768 screen panel would likely not be a good match for HDTV.
So, back to the plan with the Raspberry Pi 2B. One problem that I wanted to solve is the power consumption of the DVB-T dongle when it is not in use. I found https://github.com/mvp/uhubctl which can switch off power on individual USB ports. I wrote a VDR shutdown script that does the following:
sudo service lircd stop uhubctl -p ... -a off sudo service vdr stop
I did not refine the uhubctl invocation yet. The physical port could vary.
An easy way to start up VDR could be a udev rule that would start up the lircd and vdr services when the USB DVB stick is plugged in. Obviously, if we power off the port during VDR shutdown, the adapter would have to be plugged into a different port.
A simpler option for the occasional use of VDR might be to simply write udev rules that will start up lircd and vdr when the DVB adapter is plugged in, and shut down the services when the adapter is removed. That would be too risky if recording timers are being used.
I am not yet sure whether powering off the USB port makes any difference, because the plastic case of the DVB stick feels slightly warm to the touch even when the port is supposedly powered off. It might be that some internal heat produced by the Rasberry is being dissipated via the USB port. The metal frame of the USB jacks feels a bit warm too.
I think that I must measure the input power of the Raspberry Pi as well as the voltage on the USB port when it is supposedly powered off.
Marko
Mon, Sep 13, 2021 at 08:51:05PM +0200, Martin Wache wrote:
So, back to the plan with the Raspberry Pi 2B. One problem that I wanted to solve is the power consumption of the DVB-T dongle when it is not in use. I found https://github.com/mvp/uhubctl which can switch off power on individual USB ports. I wrote a VDR shutdown script that does the following:
sudo service lircd stop uhubctl -p ... -a off sudo service vdr stop
I did not refine the uhubctl invocation yet. The physical port could vary.
An easy way to start up VDR could be a udev rule that would start up the lircd and vdr services when the USB DVB stick is plugged in. Obviously, if we power off the port during VDR shutdown, the adapter would have to be plugged into a different port.
A simpler option for the occasional use of VDR might be to simply write udev rules that will start up lircd and vdr when the DVB adapter is plugged in, and shut down the services when the adapter is removed. That would be too risky if recording timers are being used.
I am not yet sure whether powering off the USB port makes any difference, because the plastic case of the DVB stick feels slightly warm to the touch even when the port is supposedly powered off. It might be that some internal heat produced by the Rasberry is being dissipated via the USB port. The metal frame of the USB jacks feels a bit warm too.
I think that I must measure the input power of the Raspberry Pi as well as the voltage on the USB port when it is supposedly powered off.
Marko
Powersaving for DVB receivers - try the attached patch from glenvt18 glenvt18@gmail.com
This has worked for me for a few years without noticeable problems on both USB and PCI cards. I'm still on V2.20 by the way. There's a little bit of log chatter as it powers up/down receivers when VDR scans the EPG etc, but you can filter that I reckoned it saved around 3W at the mains for a 2-receiver server setup when I tested it back in 2016 - which adds up over time.
usbhubctl is a bit of a sledgehammer !
HTH
Richard
Hi.
Here you can find an updated version of the patch: https://github.com/glenvt18/vdr/commits/vdr-2.4.6
On Mon, Oct 11, 2021 at 04:02:43PM +0100, Richard F wrote:
Mon, Sep 13, 2021 at 08:51:05PM +0200, Martin Wache wrote:
So, back to the plan with the Raspberry Pi 2B. One problem that I wanted to solve is the power consumption of the DVB-T dongle when it is not in use. I found https://github.com/mvp/uhubctl which can switch off power on individual USB ports. I wrote a VDR shutdown script that does the following:
sudo service lircd stop uhubctl -p ... -a off sudo service vdr stop
I did not refine the uhubctl invocation yet. The physical port could vary.
An easy way to start up VDR could be a udev rule that would start up the lircd and vdr services when the USB DVB stick is plugged in. Obviously, if we power off the port during VDR shutdown, the adapter would have to be plugged into a different port.
A simpler option for the occasional use of VDR might be to simply write udev rules that will start up lircd and vdr when the DVB adapter is plugged in, and shut down the services when the adapter is removed. That would be too risky if recording timers are being used.
I am not yet sure whether powering off the USB port makes any difference, because the plastic case of the DVB stick feels slightly warm to the touch even when the port is supposedly powered off. It might be that some internal heat produced by the Rasberry is being dissipated via the USB port. The metal frame of the USB jacks feels a bit warm too.
I think that I must measure the input power of the Raspberry Pi as well as the voltage on the USB port when it is supposedly powered off.
Marko
Powersaving for DVB receivers - try the attached patch from glenvt18 glenvt18@gmail.com
This has worked for me for a few years without noticeable problems on both USB and PCI cards. I'm still on V2.20 by the way. There's a little bit of log chatter as it powers up/down receivers when VDR scans the EPG etc, but you can filter that I reckoned it saved around 3W at the mains for a 2-receiver server setup when I tested it back in 2016 - which adds up over time.
usbhubctl is a bit of a sledgehammer !
HTH
Richard
From 656cce97750882fd945d9ba76c47cb93a74c3059 Mon Sep 17 00:00:00 2001 From: glenvt18 glenvt18@gmail.com Date: Tue, 24 May 2016 00:39:01 +0300 Subject: [PATCH] Device power saving feature
config.c | 9 ++++++ config.h | 3 ++ device.c | 96 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-- device.h | 29 +++++++++++++++++++ dvbdevice.c | 39 +++++++++++++++++++++++++ dvbdevice.h | 7 +++++ eitscan.c | 7 ++++- menu.c | 9 +++++- vdr.c | 6 ++++ 9 files changed, 201 insertions(+), 4 deletions(-)
diff --git a/config.c b/config.c index 9c6b71e..e196353 100644 --- a/config.c +++ b/config.c @@ -395,6 +395,9 @@ cSetup::cSetup(void) PositionerSpeed = 15; PositionerSwing = 650; PositionerLastLon = 0;
- PowerdownEnabled = 0;
- PowerdownTimeoutM = 15;
- PowerdownWakeupH = 4; SetSystemTime = 0; TimeSource = 0; TimeTransponder = 0;
@@ -617,6 +620,9 @@ bool cSetup::Parse(const char *Name, const char *Value) else if (!strcasecmp(Name, "PositionerSpeed")) PositionerSpeed = atoi(Value); else if (!strcasecmp(Name, "PositionerSwing")) PositionerSwing = atoi(Value); else if (!strcasecmp(Name, "PositionerLastLon")) PositionerLastLon = atoi(Value);
- else if (!strcasecmp(Name, "PowerdownEnabled")) PowerdownEnabled = atoi(Value);
- else if (!strcasecmp(Name, "PowerdownTimeoutM")) PowerdownTimeoutM = atoi(Value);
- else if (!strcasecmp(Name, "PowerdownWakeupH")) PowerdownWakeupH = atoi(Value); else if (!strcasecmp(Name, "SetSystemTime")) SetSystemTime = atoi(Value); else if (!strcasecmp(Name, "TimeSource")) TimeSource = cSource::FromString(Value); else if (!strcasecmp(Name, "TimeTransponder")) TimeTransponder = atoi(Value);
@@ -743,6 +749,9 @@ bool cSetup::Save(void) Store("PositionerSpeed", PositionerSpeed); Store("PositionerSwing", PositionerSwing); Store("PositionerLastLon", PositionerLastLon);
- Store("PowerdownEnabled", PowerdownEnabled);
- Store("PowerdownTimeoutM", PowerdownTimeoutM);
- Store("PowerdownWakeupH", PowerdownWakeupH); Store("SetSystemTime", SetSystemTime); Store("TimeSource", cSource::ToString(TimeSource)); Store("TimeTransponder", TimeTransponder);
diff --git a/config.h b/config.h index d1bae04..dbe84bb 100644 --- a/config.h +++ b/config.h @@ -273,6 +273,9 @@ public: int PositionerSpeed; int PositionerSwing; int PositionerLastLon;
- int PowerdownEnabled;
- int PowerdownTimeoutM;
- int PowerdownWakeupH; int SetSystemTime; int TimeSource; int TimeTransponder;
diff --git a/device.c b/device.c index 4db7cc2..1c29677 100644 --- a/device.c +++ b/device.c @@ -104,6 +104,9 @@ cDevice::cDevice(void) dvbSubtitleConverter = NULL; autoSelectPreferredSubtitleLanguage = true;
- idleTimerExpires = time(NULL) + Setup.PowerdownTimeoutM * 60;
- wakeupTimerExpires = 0;
- for (int i = 0; i < MAXRECEIVERS; i++) receiver[i] = NULL;
@@ -744,6 +747,11 @@ bool cDevice::SwitchChannel(int Direction) return result; }
+// While switching to a channel, the device will be kept powered up +// for at least this number of seconds before a receiver is attached. +// Must be less than cEITScanner::ScanTimeout. +#define CHANNEL_SWITCH_POWERUP_TIMEOUT 10
eSetChannelResult cDevice::SetChannel(const cChannel *Channel, bool LiveView) { cStatus::MsgChannelSwitch(this, 0, LiveView); @@ -778,6 +786,8 @@ eSetChannelResult cDevice::SetChannel(const cChannel *Channel, bool LiveView) } else { Channels.Lock(false);
// Power up the device
PowerUp(CHANNEL_SWITCH_POWERUP_TIMEOUT); // Stop section handling: if (sectionHandler) { sectionHandler->SetStatus(false);
@@ -843,8 +853,11 @@ int cDevice::Occupied(void) const
void cDevice::SetOccupied(int Seconds) {
- if (Seconds >= 0)
- if (Seconds >= 0) { occupiedTimeout = time(NULL) + min(Seconds, MAXOCCUPIEDTIMEOUT);
// avoid short power-down/power-up cycles
SetIdleTimer(true, Seconds + 30);
}
}
bool cDevice::SetChannelDevice(const cChannel *Channel, bool LiveView) @@ -1675,6 +1688,7 @@ bool cDevice::AttachReceiver(cReceiver *Receiver) startScrambleDetection = time(NULL); } Start();
SetIdleTimer(false); return true; } }
@@ -1708,8 +1722,10 @@ void cDevice::Detach(cReceiver *Receiver) camSlot->Assign(NULL); } }
- if (!receiversLeft)
- if (!receiversLeft) { Cancel(-1);
SetIdleTimer(true);
}
}
void cDevice::DetachAll(int Pid) @@ -1731,6 +1747,82 @@ void cDevice::DetachAllReceivers(void) Detach(receiver[i]); }
+void cDevice::CheckIdle(void) +{
- if (!SupportsPowerDown() || !Setup.PowerdownEnabled)
return;
- cMutexLock MutexLock(&mutexPowerSaving);
- if (idleTimerExpires != 0 && time(NULL) > idleTimerExpires) {
// idle, powered up
dsyslog("power saving: device %d idle timer expired", CardIndex() + 1);
SetIdleTimer(false);
if (Setup.PowerdownWakeupH != 0)
wakeupTimerExpires = time(NULL) + Setup.PowerdownWakeupH * 3600;
else
dsyslog("power saving: waking up is disabled");
if (!IsPoweredDown()) {
dsyslog("power saving: powering device %d down", CardIndex() + 1);
if (sectionHandler) {
sectionHandler->SetStatus(false);
sectionHandler->SetChannel(NULL);
}
PowerDown(true);
}
}
- if (wakeupTimerExpires != 0 && time(NULL) > wakeupTimerExpires) {
// idle, powered down
dsyslog("power saving: device %d wakeup timer expired", CardIndex() + 1);
SetIdleTimer(true);
if (IsPoweredDown()) {
dsyslog("power saving: waking up device %d", CardIndex() + 1);
PowerDown(false);
}
}
+}
+void cDevice::SetIdleTimer(bool On, int ExtraTimeoutS) +{
- if (!SupportsPowerDown())
return;
- cMutexLock MutexLock(&mutexPowerSaving);
- if (On) {
int Tout = Setup.PowerdownTimeoutM * 60;
time_t Now = time(NULL);
if (ExtraTimeoutS > 0) {
if (idleTimerExpires >= Now + ExtraTimeoutS)
return;
Tout = ExtraTimeoutS;
}
idleTimerExpires = Now + Tout;
if (Setup.PowerdownEnabled)
dsyslog("power saving: set device %d idle timer to %d sec", CardIndex() + 1, Tout);
}
- else {
idleTimerExpires = 0;
if (Setup.PowerdownEnabled)
dsyslog("power saving: disable device %d idle timer", CardIndex() + 1);
}
- wakeupTimerExpires = 0;
+}
+bool cDevice::PoweredDown(void) +{
- if (SupportsPowerDown() && Setup.PowerdownEnabled) {
cMutexLock MutexLock(&mutexPowerSaving);
return IsPoweredDown();
}
- else
return false;
+}
+void cDevice::PowerUp(int ExtraTimeoutS) +{
- cMutexLock MutexLock(&mutexPowerSaving);
- SetIdleTimer(true, ExtraTimeoutS);
- if (SupportsPowerDown() && IsPoweredDown())
PowerDown(false);
+}
// --- cTSBuffer -------------------------------------------------------------
cTSBuffer::cTSBuffer(int File, int Size, int CardIndex) diff --git a/device.h b/device.h index b06d977..56c4878 100644 --- a/device.h +++ b/device.h @@ -821,6 +821,35 @@ public: ///< Detaches all receivers from this device for this pid. virtual void DetachAllReceivers(void); ///< Detaches all receivers from this device.
+// Power saving facilities
+private:
- cMutex mutexPowerSaving;
- time_t idleTimerExpires, wakeupTimerExpires;
- void PowerUp(int ExtraTimeoutS);
///< If the device is powered down, powers it up and keeps it
///< powered up for at least ExtraTimeoutS seconds (see
///< cDevice::SetIdleTimer()).
+public:
- void CheckIdle(void);
///< Should be called periodically in the main loop.
- bool PoweredDown(void);
///< Returns true if the device is powered down "logically", that is,
///< idle tasks like EPG scanning are disabled.
- void SetIdleTimer(bool On, int ExtraTimeoutS = 0);
///< Starts/disables the idle timer. This timer must be started when
///< a device gets idle and must be disabled when it is receiving.
///< If ExtraTimeoutS is greater than zero and On is true, a new timer
///< won't be set, but the device will be kept powered up for at least
///< ExtraTimeoutS seconds.
+protected:
- virtual bool IsPoweredDown(void) {return false;}
///< Returns true if the device is powered down "physically".
- virtual void PowerDown(bool On) {};
///< Actually powers the device down/up.
- virtual bool SupportsPowerDown() {return false;}
};///< Returns true if a derived device supports power saving.
/// Derived cDevice classes that can receive channels will have to provide diff --git a/dvbdevice.c b/dvbdevice.c index 9321f16..2a0dad1 100644 --- a/dvbdevice.c +++ b/dvbdevice.c @@ -348,6 +348,8 @@ public: const cPositioner *Positioner(void) const { return positioner; } int GetSignalStrength(void) const; int GetSignalQuality(void) const;
- bool IsPoweredDown(void) {return fd_frontend < 0;}
- void PowerDown(bool On); };
cMutex cDvbTuner::bondMutex; @@ -544,6 +546,8 @@ void cDvbTuner::ClearEventQueue(void) const
bool cDvbTuner::GetFrontendStatus(fe_status_t &Status) const {
- if (fd_frontend < 0)
ClearEventQueue(); while (1) { if (ioctl(fd_frontend, FE_READ_STATUS, &Status) != -1)return false;
@@ -559,6 +563,8 @@ bool cDvbTuner::GetFrontendStatus(fe_status_t &Status) const
int cDvbTuner::GetSignalStrength(void) const {
- if (fd_frontend < 0)
ClearEventQueue(); uint16_t Signal; while (1) {return -1;
@@ -1001,6 +1007,26 @@ void cDvbTuner::Action(void) } }
+void cDvbTuner::PowerDown(bool On) +{
- cMutexLock MutexLock(&mutex);
- if (On && fd_frontend >= 0) {
isyslog("dvb tuner: power-down - closing frontend %d/%d", adapter, frontend);
tunerStatus = tsIdle;
close(fd_frontend);
fd_frontend = -1;
}
- if (!On && fd_frontend < 0) {
cString Filename = cString::sprintf("%s/%s%d/%s%d",
DEV_DVB_BASE, DEV_DVB_ADAPTER, adapter, DEV_DVB_FRONTEND, frontend);
isyslog("dvb tuner: power-up - opening frontend %d/%d", adapter, frontend);
fd_frontend = open(Filename, O_RDWR | O_NONBLOCK);
if (fd_frontend < 0)
esyslog("ERROR: can't open DVB device frontend %d/%d", adapter, frontend);
tunerStatus = tsIdle;
}
+}
// --- cDvbSourceParam -------------------------------------------------------
class cDvbSourceParam : public cSourceParam { @@ -1711,6 +1737,19 @@ void cDvbDevice::DetachAllReceivers(void) needsDetachBondedReceivers = false; }
+bool cDvbDevice::IsPoweredDown(void) +{
- if (dvbTuner)
return dvbTuner->IsPoweredDown();
- return false;
+}
+void cDvbDevice::PowerDown(bool On) +{
- if (dvbTuner)
dvbTuner->PowerDown(On);
+}
// --- cDvbDeviceProbe -------------------------------------------------------
cList<cDvbDeviceProbe> DvbDeviceProbes; diff --git a/dvbdevice.h b/dvbdevice.h index 0a148ce..a156de6 100644 --- a/dvbdevice.h +++ b/dvbdevice.h @@ -289,6 +289,13 @@ protected: virtual void CloseDvr(void); virtual bool GetTSPacket(uchar *&Data); virtual void DetachAllReceivers(void);
+// Power saving facilities
+protected:
- virtual bool IsPoweredDown(void);
- virtual void PowerDown(bool On);
- virtual bool SupportsPowerDown() {return true;} };
// A plugin that implements a DVB device derived from cDvbDevice needs to create diff --git a/eitscan.c b/eitscan.c index 77f15c6..3899e00 100644 --- a/eitscan.c +++ b/eitscan.c @@ -142,7 +142,8 @@ void cEITScanner::Process(void) bool AnyDeviceSwitched = false; for (int i = 0; i < cDevice::NumDevices(); i++) { cDevice *Device = cDevice::GetDevice(i);
if (Device && Device->ProvidesEIT()) {
if (Device && Device->ProvidesEIT()
&& (!Device->PoweredDown() || lastActivity == 0)) { // powered up or forced scan for (cScanData *ScanData = scanList->First(); ScanData; ScanData = scanList->Next(ScanData)) { const cChannel *Channel = ScanData->GetChannel(); if (Channel) {
@@ -159,6 +160,10 @@ void cEITScanner::Process(void) } } //dsyslog("EIT scan: device %d source %-8s tp %5d", Device->DeviceNumber() + 1, *cSource::ToString(Channel->Source()), Channel->Transponder());
if (lastActivity == 0)
// forced scan - set idle timer for each channel switch;
// this prevents powering down while scanning a transponder
Device->SetIdleTimer(true, ScanTimeout + 5); Device->SwitchChannel(Channel, false); scanList->Del(ScanData); AnyDeviceSwitched = true;
diff --git a/menu.c b/menu.c index ae61c64..c469ab0 100644 --- a/menu.c +++ b/menu.c @@ -3464,6 +3464,12 @@ void cMenuSetupLNB::Setup(void) Add(new cMenuEditIntxItem(tr("Setup.LNB$Positioner speed (degrees/s)"), &data.PositionerSpeed, 1, 1800, 10)); }
- Add(new cMenuEditBoolItem(tr("Setup.LNB$Enable power saving"), &data.PowerdownEnabled));
- if (data.PowerdownEnabled) {
Add(new cMenuEditIntItem(tr("Setup.LNB$Power down an idle device after (min)"), &data.PowerdownTimeoutM));
Add(new cMenuEditIntItem(tr("Setup.LNB$Wake up from power-down after (h)"), &data.PowerdownWakeupH));
}
- SetCurrent(Get(current)); Display();
} @@ -3472,6 +3478,7 @@ eOSState cMenuSetupLNB::ProcessKey(eKeys Key) { int oldDiSEqC = data.DiSEqC; int oldUsePositioner = data.UsePositioner;
- int oldPowerdownEnabled = data.PowerdownEnabled; bool DeviceBondingsChanged = false; if (Key == kOk) { cString NewDeviceBondings = satCableNumbers.ToString();
@@ -3480,7 +3487,7 @@ eOSState cMenuSetupLNB::ProcessKey(eKeys Key) } eOSState state = cMenuSetupBase::ProcessKey(Key);
- if (Key != kNone && (data.DiSEqC != oldDiSEqC || data.UsePositioner != oldUsePositioner))
- if (Key != kNone && (data.DiSEqC != oldDiSEqC || data.UsePositioner != oldUsePositioner || data.PowerdownEnabled != oldPowerdownEnabled)) Setup(); else if (DeviceBondingsChanged) cDvbDevice::BondDevices(data.DeviceBondings);
diff --git a/vdr.c b/vdr.c index 71a72f2..c12ad2c 100644 --- a/vdr.c +++ b/vdr.c @@ -1444,6 +1444,12 @@ int main(int argc, char *argv[])
ReportEpgBugFixStats();
for (int i = 0; i < cDevice::NumDevices(); i++) {
cDevice *d = cDevice::GetDevice(i);
if (d)
d->CheckIdle();
}
// Main thread hooks of plugins: PluginManager.MainThreadHook(); }
-- 1.9.1
#/bin/sh
# This script monitors if a dvb device's frontend is opened by VDR. # Can be used with a single tuner or with two tuners. # Output: # 1 - adapter 0 is on # 2 - adapter 1 is on # 3 - both are on # - - both are off # . - VDR is not running
# VDR executable. Change to vdr.bin for OpenELEC. VDR=vdr
# Uncomment this if you want to output timestamps of status changes PRINT_TIMESTAMPS=yes
old_status='*' old_stamp=$(date +%s) while true; do vdrpid=$(pidof $VDR) if [ -z "$vdrpid" ]; then status='.' else mask=0 for adapter in 0 1; do if lsof -p $vdrpid 2>/dev/null | grep -q "adapter$adapter/frontend"; then mask=$(($mask + $adapter + 1)) fi done if [ $mask -eq 0 ]; then status='-' else status=$mask fi fi stamp=$(date +%s) if [ -n "$PRINT_TIMESTAMPS" -a "$old_status" != "$status" ]; then printf '\n[%s] %s>%s +%ds\n' $(date +%H:%M:%S) "$old_status" $status $(($stamp - $old_stamp)) old_stamp=$stamp fi old_status=$status printf "$status" sleep 1 done
vdr mailing list vdr@linuxtv.org https://www.linuxtv.org/cgi-bin/mailman/listinfo/vdr
Tue, Oct 12, 2021 at 07:21:10PM +0300, glenvt18 wrote:
Here you can find an updated version of the patch: https://github.com/glenvt18/vdr/commits/vdr-2.4.6
Thank you. I just conducted some tests with my uncalibrated Agilent power supply. The USB cable of such low quality that the Raspberry Pi complained several times about undervoltage.
I measured the following current draw at 5 volts, in ascending order:
81 mA: Raspberry Pi 2B shut down 200 mA: Raspberry Pi 2B powered up, no Ethernet plugged in 240 mA: Ethernet cable plugged in (HDMI cable makes no difference) 320 mA: Ethernet + USB DVB stick plugged in 440 mA: compiling VDR with "make -j4" (all CPU cores busy) 550 mA: VDR playing back a recording 530 mA: recording paused in VDR 510 mA: EPG scan running 600 mA: VDR displaying live DVB-T2
https://github.com/glenvt18/vdr/commit/b368f67d00d0b466ae36028efb9336e81f77d... applied cleanly on the latest VDR source. I changed the PowerdownTimeoutM from 15 to 1 minute to speed up my testing.
The patch only had a minimal impact. After 1 or 2 minutes of the playback of a recording being paused, the power consumption dropped from 530 mA to 500 mA.
I noticed that VDR is consuming about 5% of the CPU power according to "top". Could it not be made more event-based? It might be interesting to check with "powertop" how many wakeups per second there are, and with "perf record" and "perf replay" (or simply "perf top") where the CPU cycles are being spent when the playback of a recording is paused.
The bulk of the the power consumption ought to be caused by the USB DVB stick not being in fully idle state. After all, utilizing all 4 CPU cores during the "make -j4" minutes showed a pretty stable power consumption of 440 mA for several minutes, which is much less than when the VDR process was running.
Here is a summary of the power consumption measured at 5 volts.
1.2 W (240 mA) mostly idle Raspberry Pi 2B (Ethernet plugged in) 1.6 W (320 mA) USB DVB stick plugged in, VDR not running 2.5 W (500 mA) lowest power consumption achieved with VDR 3.0 W (600 mA) VDR displaying live TV
My conclusion is that I will configure udev so that VDR will automatically start up or shut down when the USB stick is plugged in or removed. In that way, the power consumption of the system will only be more than doubled when VDR is actually in use.
I am planning to install the most recent Raspberry Pi and to document the minimal changes on top of that.
Best regards,
Marko
What is the output of
lsof | grep frontend
when VDR is in the "idle" state?
On Sun, Oct 17, 2021 at 10:52:11PM +0300, Marko Mäkelä wrote:
Tue, Oct 12, 2021 at 07:21:10PM +0300, glenvt18 wrote:
Here you can find an updated version of the patch: https://github.com/glenvt18/vdr/commits/vdr-2.4.6
Thank you. I just conducted some tests with my uncalibrated Agilent power supply. The USB cable of such low quality that the Raspberry Pi complained several times about undervoltage.
I measured the following current draw at 5 volts, in ascending order:
81 mA: Raspberry Pi 2B shut down 200 mA: Raspberry Pi 2B powered up, no Ethernet plugged in 240 mA: Ethernet cable plugged in (HDMI cable makes no difference) 320 mA: Ethernet + USB DVB stick plugged in 440 mA: compiling VDR with "make -j4" (all CPU cores busy) 550 mA: VDR playing back a recording 530 mA: recording paused in VDR 510 mA: EPG scan running 600 mA: VDR displaying live DVB-T2
https://github.com/glenvt18/vdr/commit/b368f67d00d0b466ae36028efb9336e81f77d... applied cleanly on the latest VDR source. I changed the PowerdownTimeoutM from 15 to 1 minute to speed up my testing.
The patch only had a minimal impact. After 1 or 2 minutes of the playback of a recording being paused, the power consumption dropped from 530 mA to 500 mA.
I noticed that VDR is consuming about 5% of the CPU power according to "top". Could it not be made more event-based? It might be interesting to check with "powertop" how many wakeups per second there are, and with "perf record" and "perf replay" (or simply "perf top") where the CPU cycles are being spent when the playback of a recording is paused.
The bulk of the the power consumption ought to be caused by the USB DVB stick not being in fully idle state. After all, utilizing all 4 CPU cores during the "make -j4" minutes showed a pretty stable power consumption of 440 mA for several minutes, which is much less than when the VDR process was running.
Here is a summary of the power consumption measured at 5 volts.
1.2 W (240 mA) mostly idle Raspberry Pi 2B (Ethernet plugged in) 1.6 W (320 mA) USB DVB stick plugged in, VDR not running 2.5 W (500 mA) lowest power consumption achieved with VDR 3.0 W (600 mA) VDR displaying live TV
My conclusion is that I will configure udev so that VDR will automatically start up or shut down when the USB stick is plugged in or removed. In that way, the power consumption of the system will only be more than doubled when VDR is actually in use.
I am planning to install the most recent Raspberry Pi and to document the minimal changes on top of that.
Best regards,
Marko
vdr mailing list vdr@linuxtv.org https://www.linuxtv.org/cgi-bin/mailman/listinfo/vdr
Mon, Oct 18, 2021 at 11:44:32PM +0300, glenvt18 wrote:
What is the output of
lsof | grep frontend
when VDR is in the "idle" state?
I produced some output from /proc/$(pgrep vdr)/fd which I think might be more helpful. The last-but-one "ls" output was "too soon" after I started and paused the recording, so VDR was still in normal mode.
In case you wonder, the connection between lircd and vdr did not work last time I tried, and probably also not this time. That is why I used telnet to the SVDRP port.
The last "ls" command was when VDR was expected to be idle (after 1-minute timeout, instead of the 15-minute timeout of your patch). I ran the command once more after a while, and the output remained identical.
Note that this USB DVB-T stick has two frontends for the same aerial connector. I think that one is for DVB-T and another for DVB-T2. You can see that "frontend1" was replaced with "frontend0" in the not-quite-idle mode.
I am happy to try a revised patch, and I can also use GDB ("thread apply all backtrace" and such) if that is needed.
This was the latest commit 0d50ec57f50375c8fda92d117e348dd8fd5a77a9 ("Version 2.5.6") from http://git.tvdr.de/vdr.git with only your patch on top (and the 15-minute timeout changed to 1 minute).
Best regards,
Marko
pi@raspberrypi:~ $ sudo service lircd start pi@raspberrypi:~ $ pgrep lircd 3811 pi@raspberrypi:~ $ sudo ls -l /proc/3811/fd yhteensä 0 lr-x------ 1 root root 64 loka 20 21:37 0 -> /dev/null lrwx------ 1 root root 64 loka 20 21:37 1 -> socket:[47310] lrwx------ 1 root root 64 loka 20 21:37 2 -> socket:[47310] lrwx------ 1 root root 64 loka 20 21:37 3 -> socket:[49360] lrwx------ 1 root root 64 loka 20 21:37 4 -> socket:[47311] lrwx------ 1 root root 64 loka 20 21:37 5 -> /run/lirc/lircd.pid lr-x------ 1 root root 64 loka 20 21:37 6 -> /sys/devices/platform/soc/3f980000.usb/usb1/1-1/1-1.5/rc/rc0/protocols lr-x------ 1 root root 64 loka 20 21:37 7 -> /sys/devices/platform/soc/3f980000.usb/usb1/1-1/1-1.5/rc/rc0/protocols pi@raspberrypi:~ $ sudo service vdr start pi@raspberrypi:~ $ sudo lsof /dev/dvb/adapter0/* COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME vdr 3878 vdr 7u CHR 212,3 0t0 42703 /dev/dvb/adapter0/frontend0 pi@raspberrypi:~ $ sudo ls -l /proc/3878/fd yhteensä 0 lr-x------ 1 root root 64 loka 20 21:37 0 -> /dev/null lrwx------ 1 root root 64 loka 20 21:37 1 -> socket:[48975] lrwx------ 1 root root 64 loka 20 21:37 10 -> socket:[49006] lrwx------ 1 root root 64 loka 20 21:37 11 -> /dev/dvb/adapter0/demux0 lrwx------ 1 root root 64 loka 20 21:37 12 -> /dev/dvb/adapter0/demux0 lrwx------ 1 root root 64 loka 20 21:37 13 -> /dev/dvb/adapter0/demux0 lrwx------ 1 root root 64 loka 20 21:37 14 -> /dev/dvb/adapter0/demux0 lrwx------ 1 root root 64 loka 20 21:37 15 -> /dev/dvb/adapter0/demux0 lrwx------ 1 root root 64 loka 20 21:37 16 -> /dev/dvb/adapter0/demux0 lrwx------ 1 root root 64 loka 20 21:37 17 -> /dev/dvb/adapter0/demux0 lrwx------ 1 root root 64 loka 20 21:37 18 -> /dev/dvb/adapter0/demux0 lrwx------ 1 root root 64 loka 20 21:37 2 -> socket:[48975] lrwx------ 1 root root 64 loka 20 21:37 3 -> socket:[48980] lrwx------ 1 root root 64 loka 20 21:37 4 -> /dev/dvb/adapter0/frontend1 lrwx------ 1 root root 64 loka 20 21:37 5 -> /dev/vchiq lrwx------ 1 root root 64 loka 20 21:37 6 -> socket:[49005] lrwx------ 1 root root 64 loka 20 21:37 7 -> /dev/dvb/adapter0/demux0 lrwx------ 1 root root 64 loka 20 21:37 8 -> /dev/dvb/adapter0/demux0 lr-x------ 1 root root 64 loka 20 21:37 9 -> /dev/dvb/adapter0/dvr0 pi@raspberrypi:~ $ telnet localhost 6419 Trying ::1... Trying 127.0.0.1... Connected to localhost. Escape character is '^]'. 220 raspberrypi SVDRP VideoDiskRecorder 2.5.6; Wed Oct 20 21:40:00 2021; UTF-8 hitk menu 250 Key "menu" accepted hitk 4 250 Key "4" accepted hitk red 250 Key "red" accepted hitk pause 250 Key "pause" accepted quit 221 raspberrypi closing connection Connection closed by foreign host. pi@raspberrypi:~ $ date ke 20.10.2021 21.40.45 +0300 pi@raspberrypi:~ $ sudo ls -l /proc/3878/fd yhteensä 0 lr-x------ 1 root root 64 loka 20 21:37 0 -> /dev/null lrwx------ 1 root root 64 loka 20 21:37 1 -> socket:[48975] lrwx------ 1 root root 64 loka 20 21:37 10 -> socket:[49006] lrwx------ 1 root root 64 loka 20 21:37 13 -> /dev/dvb/adapter0/demux0 lrwx------ 1 root root 64 loka 20 21:37 14 -> /dev/dvb/adapter0/demux0 lrwx------ 1 root root 64 loka 20 21:37 15 -> /dev/dvb/adapter0/demux0 lrwx------ 1 root root 64 loka 20 21:37 16 -> /dev/dvb/adapter0/demux0 lrwx------ 1 root root 64 loka 20 21:37 17 -> /dev/dvb/adapter0/demux0 lrwx------ 1 root root 64 loka 20 21:37 2 -> socket:[48975] lrwx------ 1 root root 64 loka 20 21:37 3 -> socket:[48980] lrwx------ 1 root root 64 loka 20 21:37 4 -> /dev/dvb/adapter0/frontend1 lrwx------ 1 root root 64 loka 20 21:37 5 -> /dev/vchiq lrwx------ 1 root root 64 loka 20 21:37 6 -> socket:[49005] lr-x------ 1 root root 64 loka 20 21:37 7 -> /var/lib/video/XXX/2019-01-05.19.07.19-0.rec/00001.ts pi@raspberrypi:~ $ date ke 20.10.2021 21.41.17 +0300 pi@raspberrypi:~ $ sudo ls -l /proc/3878/fd yhteensä 0 lr-x------ 1 root root 64 loka 20 21:37 0 -> /dev/null lrwx------ 1 root root 64 loka 20 21:37 1 -> socket:[48975] lrwx------ 1 root root 64 loka 20 21:37 10 -> socket:[49006] lrwx------ 1 root root 64 loka 20 21:37 11 -> /dev/dvb/adapter0/demux0 lrwx------ 1 root root 64 loka 20 21:37 12 -> /dev/dvb/adapter0/demux0 lrwx------ 1 root root 64 loka 20 21:37 13 -> /dev/dvb/adapter0/demux0 lrwx------ 1 root root 64 loka 20 21:37 2 -> socket:[48975] lrwx------ 1 root root 64 loka 20 21:37 3 -> socket:[48980] lrwx------ 1 root root 64 loka 20 21:37 4 -> /dev/dvb/adapter0/frontend0 lrwx------ 1 root root 64 loka 20 21:37 5 -> /dev/vchiq lrwx------ 1 root root 64 loka 20 21:37 6 -> socket:[49005] lr-x------ 1 root root 64 loka 20 21:37 7 -> /var/lib/video/XXX/2019-01-05.19.07.19-0.rec/00001.ts lrwx------ 1 root root 64 loka 20 21:37 8 -> /dev/dvb/adapter0/demux0 lrwx------ 1 root root 64 loka 20 21:37 9 -> /dev/dvb/adapter0/demux0
I'm not sure VDR is "idle" while a recording is paused. What is the log output?
I myself don't use a standalone VDR (using softhddevice etc.). I use it only as a streaming server. When you start VDR as a server, it enters idle mode after a configured timeout. It might be different for a standalone VDR. If I remember, there is a softhddevice's command/option called "suspend" or "detach", or whatever, which stops live TV. That causes idle state too.
BTW. Do you use both DVB-T and DVB-T2?
And I've never tried the patch with VDR > 2.4.6.
On Wed, Oct 20, 2021 at 10:04:26PM +0300, Marko Mäkelä wrote:
Mon, Oct 18, 2021 at 11:44:32PM +0300, glenvt18 wrote:
What is the output of
lsof | grep frontend
when VDR is in the "idle" state?
I produced some output from /proc/$(pgrep vdr)/fd which I think might be more helpful. The last-but-one "ls" output was "too soon" after I started and paused the recording, so VDR was still in normal mode.
In case you wonder, the connection between lircd and vdr did not work last time I tried, and probably also not this time. That is why I used telnet to the SVDRP port.
The last "ls" command was when VDR was expected to be idle (after 1-minute timeout, instead of the 15-minute timeout of your patch). I ran the command once more after a while, and the output remained identical.
Note that this USB DVB-T stick has two frontends for the same aerial connector. I think that one is for DVB-T and another for DVB-T2. You can see that "frontend1" was replaced with "frontend0" in the not-quite-idle mode.
I am happy to try a revised patch, and I can also use GDB ("thread apply all backtrace" and such) if that is needed.
This was the latest commit 0d50ec57f50375c8fda92d117e348dd8fd5a77a9 ("Version 2.5.6") from http://git.tvdr.de/vdr.git with only your patch on top (and the 15-minute timeout changed to 1 minute).
Best regards,
Marko
pi@raspberrypi:~ $ sudo service lircd start pi@raspberrypi:~ $ pgrep lircd 3811 pi@raspberrypi:~ $ sudo ls -l /proc/3811/fd yhteensä 0 lr-x------ 1 root root 64 loka 20 21:37 0 -> /dev/null lrwx------ 1 root root 64 loka 20 21:37 1 -> socket:[47310] lrwx------ 1 root root 64 loka 20 21:37 2 -> socket:[47310] lrwx------ 1 root root 64 loka 20 21:37 3 -> socket:[49360] lrwx------ 1 root root 64 loka 20 21:37 4 -> socket:[47311] lrwx------ 1 root root 64 loka 20 21:37 5 -> /run/lirc/lircd.pid lr-x------ 1 root root 64 loka 20 21:37 6 -> /sys/devices/platform/soc/3f980000.usb/usb1/1-1/1-1.5/rc/rc0/protocols lr-x------ 1 root root 64 loka 20 21:37 7 -> /sys/devices/platform/soc/3f980000.usb/usb1/1-1/1-1.5/rc/rc0/protocols pi@raspberrypi:~ $ sudo service vdr start pi@raspberrypi:~ $ sudo lsof /dev/dvb/adapter0/* COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME vdr 3878 vdr 7u CHR 212,3 0t0 42703 /dev/dvb/adapter0/frontend0 pi@raspberrypi:~ $ sudo ls -l /proc/3878/fd yhteensä 0 lr-x------ 1 root root 64 loka 20 21:37 0 -> /dev/null lrwx------ 1 root root 64 loka 20 21:37 1 -> socket:[48975] lrwx------ 1 root root 64 loka 20 21:37 10 -> socket:[49006] lrwx------ 1 root root 64 loka 20 21:37 11 -> /dev/dvb/adapter0/demux0 lrwx------ 1 root root 64 loka 20 21:37 12 -> /dev/dvb/adapter0/demux0 lrwx------ 1 root root 64 loka 20 21:37 13 -> /dev/dvb/adapter0/demux0 lrwx------ 1 root root 64 loka 20 21:37 14 -> /dev/dvb/adapter0/demux0 lrwx------ 1 root root 64 loka 20 21:37 15 -> /dev/dvb/adapter0/demux0 lrwx------ 1 root root 64 loka 20 21:37 16 -> /dev/dvb/adapter0/demux0 lrwx------ 1 root root 64 loka 20 21:37 17 -> /dev/dvb/adapter0/demux0 lrwx------ 1 root root 64 loka 20 21:37 18 -> /dev/dvb/adapter0/demux0 lrwx------ 1 root root 64 loka 20 21:37 2 -> socket:[48975] lrwx------ 1 root root 64 loka 20 21:37 3 -> socket:[48980] lrwx------ 1 root root 64 loka 20 21:37 4 -> /dev/dvb/adapter0/frontend1 lrwx------ 1 root root 64 loka 20 21:37 5 -> /dev/vchiq lrwx------ 1 root root 64 loka 20 21:37 6 -> socket:[49005] lrwx------ 1 root root 64 loka 20 21:37 7 -> /dev/dvb/adapter0/demux0 lrwx------ 1 root root 64 loka 20 21:37 8 -> /dev/dvb/adapter0/demux0 lr-x------ 1 root root 64 loka 20 21:37 9 -> /dev/dvb/adapter0/dvr0 pi@raspberrypi:~ $ telnet localhost 6419 Trying ::1... Trying 127.0.0.1... Connected to localhost. Escape character is '^]'. 220 raspberrypi SVDRP VideoDiskRecorder 2.5.6; Wed Oct 20 21:40:00 2021; UTF-8 hitk menu 250 Key "menu" accepted hitk 4 250 Key "4" accepted hitk red 250 Key "red" accepted hitk pause 250 Key "pause" accepted quit 221 raspberrypi closing connection Connection closed by foreign host. pi@raspberrypi:~ $ date ke 20.10.2021 21.40.45 +0300 pi@raspberrypi:~ $ sudo ls -l /proc/3878/fd yhteensä 0 lr-x------ 1 root root 64 loka 20 21:37 0 -> /dev/null lrwx------ 1 root root 64 loka 20 21:37 1 -> socket:[48975] lrwx------ 1 root root 64 loka 20 21:37 10 -> socket:[49006] lrwx------ 1 root root 64 loka 20 21:37 13 -> /dev/dvb/adapter0/demux0 lrwx------ 1 root root 64 loka 20 21:37 14 -> /dev/dvb/adapter0/demux0 lrwx------ 1 root root 64 loka 20 21:37 15 -> /dev/dvb/adapter0/demux0 lrwx------ 1 root root 64 loka 20 21:37 16 -> /dev/dvb/adapter0/demux0 lrwx------ 1 root root 64 loka 20 21:37 17 -> /dev/dvb/adapter0/demux0 lrwx------ 1 root root 64 loka 20 21:37 2 -> socket:[48975] lrwx------ 1 root root 64 loka 20 21:37 3 -> socket:[48980] lrwx------ 1 root root 64 loka 20 21:37 4 -> /dev/dvb/adapter0/frontend1 lrwx------ 1 root root 64 loka 20 21:37 5 -> /dev/vchiq lrwx------ 1 root root 64 loka 20 21:37 6 -> socket:[49005] lr-x------ 1 root root 64 loka 20 21:37 7 -> /var/lib/video/XXX/2019-01-05.19.07.19-0.rec/00001.ts pi@raspberrypi:~ $ date ke 20.10.2021 21.41.17 +0300 pi@raspberrypi:~ $ sudo ls -l /proc/3878/fd yhteensä 0 lr-x------ 1 root root 64 loka 20 21:37 0 -> /dev/null lrwx------ 1 root root 64 loka 20 21:37 1 -> socket:[48975] lrwx------ 1 root root 64 loka 20 21:37 10 -> socket:[49006] lrwx------ 1 root root 64 loka 20 21:37 11 -> /dev/dvb/adapter0/demux0 lrwx------ 1 root root 64 loka 20 21:37 12 -> /dev/dvb/adapter0/demux0 lrwx------ 1 root root 64 loka 20 21:37 13 -> /dev/dvb/adapter0/demux0 lrwx------ 1 root root 64 loka 20 21:37 2 -> socket:[48975] lrwx------ 1 root root 64 loka 20 21:37 3 -> socket:[48980] lrwx------ 1 root root 64 loka 20 21:37 4 -> /dev/dvb/adapter0/frontend0 lrwx------ 1 root root 64 loka 20 21:37 5 -> /dev/vchiq lrwx------ 1 root root 64 loka 20 21:37 6 -> socket:[49005] lr-x------ 1 root root 64 loka 20 21:37 7 -> /var/lib/video/XXX/2019-01-05.19.07.19-0.rec/00001.ts lrwx------ 1 root root 64 loka 20 21:37 8 -> /dev/dvb/adapter0/demux0 lrwx------ 1 root root 64 loka 20 21:37 9 -> /dev/dvb/adapter0/demux0
vdr mailing list vdr@linuxtv.org https://www.linuxtv.org/cgi-bin/mailman/listinfo/vdr
Thu, Oct 21, 2021 at 02:06:37AM +0300, glenvt18 wrote:
I'm not sure VDR is "idle" while a recording is paused. What is the log output?
I can only see a clue "trying device number 2 instead":
Oct 20 21:37:56 raspberrypi vdr: [3878] DVB API version is 0x050B (VDR was built with 0x050A) Oct 20 21:37:56 raspberrypi vdr: [3878] frontend 0/0 provides DVB-T with QPSK,QAM16,QAM64 ("Realtek RTL2832 (DVB-T)") Oct 20 21:37:57 raspberrypi kernel: [257117.778208] mn88473 3-0018: downloading firmware from file 'dvb-demod-mn88473-01.fw' Oct 20 21:37:57 raspberrypi vdr: [3878] frontend 0/1 provides DVB-T,DVB-T2,DVB-C with QPSK,QAM16,QAM32,QAM64,QAM128,QAM256 ("Panasonic MN88473") Oct 20 21:37:58 raspberrypi vdr: [3878] found 1 DVB device Oct 20 21:37:58 raspberrypi vdr: [3878] initializing plugin: rpihddevice (1.0.4): HD output device for Raspberry Pi Oct 20 21:37:58 raspberrypi vdr: [3878] rpihddevice: HwInit() done, display size is 1920x1080 Oct 20 21:37:58 raspberrypi vdr: [3878] setting primary device to 1 Oct 20 21:37:58 raspberrypi vdr: [3878] device 1 has no MPEG decoder Oct 20 21:37:58 raspberrypi vdr: [3878] trying device number 2 instead Oct 20 21:37:58 raspberrypi vdr: [3878] setting primary device to 2 Oct 20 21:37:58 raspberrypi vdr: [3878] setting current skin to "lcars" Oct 20 21:37:58 raspberrypi vdr: [3878] loading /var/lib/vdr/themes/lcars-default.theme Oct 20 21:37:58 raspberrypi vdr: [3878] starting plugin: rpihddevice Oct 20 21:37:58 raspberrypi lircd-0.9.4c[3811]: Notice: accepted new client on /var/run/lirc/lircd Oct 20 21:37:58 raspberrypi vdr: [3878] switching to channel 1 T-8438-8193-1501 (Yle TV1 HD (T)) Oct 20 21:37:58 raspberrypi lircd-0.9.4c[3811]: Info: [lirc] protocol is enabled Oct 20 21:37:58 raspberrypi vdr: [3911] SVDRP raspberrypi opening port 6419/tcp Oct 20 21:37:58 raspberrypi vdr: [3911] SVDRP raspberrypi listening on port 6419/tcp Oct 20 21:37:58 raspberrypi vdr: [3907] rpihddevice: loading /usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf ... Oct 20 21:37:58 raspberrypi vdr: [3907] rpihddevice: loading /usr/share/fonts/truetype/dejavu/DejaVuSans.ttf ... Oct 20 21:38:01 raspberrypi vdr: [3878] retuning due to modification of channel 1 (Yle TV1 HD (T)) Oct 20 21:38:01 raspberrypi vdr: [3878] switching to channel 1 T-8438-8193-1501 (Yle TV1 HD (T)) Oct 20 21:40:00 raspberrypi vdr: [3911] SVDRP raspberrypi < 127.0.0.1:52142 client connection accepted Oct 20 21:40:08 raspberrypi vdr: [3878] replay /var/lib/video/XXX/2019-01-05.19.07.19-0.rec Oct 20 21:40:08 raspberrypi vdr: [3878] loading /var/lib/video/XXX/2019-01-05.19.07.19-0.rec/marks Oct 20 21:40:08 raspberrypi vdr: [3947] resuming replay at index 807 (0:00:32.07) Oct 20 21:40:13 raspberrypi vdr: [3911] SVDRP raspberrypi < 127.0.0.1:52142 connection closed Oct 20 21:41:55 raspberrypi vdr: [3878] stopping plugin: rpihddevice Oct 20 21:41:55 raspberrypi lircd-0.9.4c[3811]: Info: removed client Oct 20 21:41:55 raspberrypi vdr: [3878] saved setup to /var/lib/vdr/setup.conf
If I remember, there is a softhddevice's command/option called "suspend" or "detach", or whatever, which stops live TV. That causes idle state too.
I remember (co-)developing such a feature for softdevice (without the "hd" part). Apart from saving power, another motivation was to reduce the probability of crashes, because reception errors of the DVB-T stream used to cause that back then.
Maybe I could check if something similar could be done in rpihddevice.
Still, in my opinion, when a recording is being watched and nothing is being simultaneously recorded or streamed, there should normally be no reason to keep any tuners powered.
BTW. Do you use both DVB-T and DVB-T2?
Yes, some transponders are DVB-T and some are DVB-T2, and I think that all free-to-view DVB-T2 channels are also available via DVB-T. I do not know when that transition period will end here. Wikipedia says that it was supposed to complete by April 2020 already. The first DVB-T2 transponders were introduced in 2011.
And I've never tried the patch with VDR > 2.4.6.
The patch applied without glitches, only some line number differences. In VDR 2.5, the EPG works for me. In 2.4, I think I never got it to cover the DVB-T2 transponders.
Best regards,
Marko
Sun, Oct 17, 2021 at 10:52:11PM +0300, Marko Mäkelä wrote:
I noticed that VDR is consuming about 5% of the CPU power according to "top". Could it not be made more event-based? It might be interesting to check with "powertop" how many wakeups per second there are, and with "perf record" and "perf replay" (or simply "perf top") where the CPU cycles are being spent when the playback of a recording is paused.
I just conducted this experiment with VDR 2.6.1, rpihddevice, and a patch to support a /dev/lirc* remote (with no polling or wakeups in that thread).
While a recording is paused, I see some VDR threads waking up periodically. I ran the command
sudo perf record -p $(pgrep vdr")
and hit ctrl-c (SIGINT) after a couple of minutes. I see the following threads in the "perf report" output:
"dvbplayer", "ovgthread", "vdr" (something related to rpihddevice) "device 1 sectio" (cSectionHandler, possibly updating the EPG) "frontend 0/0 tu" (cDvbTuner)
Updating the EPG is a valid reason to keep the tuner busy. I repeated this experiment once more, this time first manually triggering an update of the EPG, waiting it to finish, and then starting and pausing the playback of a recording, and finally running "perf record" for a couple of minutes while the recording was paused and there was no interaction with VDR.
The result was the same: the system was apparently still parsing EPG data. I set some breakpoints to identify some possible culprits. This one is executed about once per second:
#0 cSectionHandler::SetStatus (On=true) at thread.h:94 #1 0x00093c80 in cDevice::SetChannel (LiveView=false) at device.c:915 #2 0x00093fe0 in cDevice::SwitchChannel (LiveView=false) at device.c:815 #3 0x000ae8ac in cEITScanner::Process (this=<EITScanner>) at eitscan.c:168 #4 0x000738cc in main () at vdr.c:1519
I see that there is a variable InhibitEpgScan, but the scan can only be disabled based on the availability of a tuner. Thus, VDR never seems to disable all tuners or completely suspend the parsing of EPG data.
The main loop in that thread wakes up once per second due to the following:
#4 0x00101b38 in cRemote::Get (WaitMs=1000, UnknownCode=0x0) at remote.c:194 #5 0x000b87d8 in cInterface::GetKey (Wait=true) at interface.c:36 #6 cInterface::GetKey (Wait=true) at interface.c:31 #7 0x00072e4c in main () at vdr.c:1206
I think that a periodic wakeup in the main loop is reasonable. It would still be good to disable the tuners when they are not really needed.
I conducted this test without applying the patch https://github.com/glenvt18/vdr/commit/b368f67d00d0b466ae36028efb9336e81f77d...
As far as I can tell, even with that patch the EPG parser could keep running, because the patch does not set the variable InhibitEpgScan. That would explain why the patch did not help reduce VDR power consumption with the Astrometa USB stick.
I have not tried to measure the power consumption of the Pi TV HAT yet.
Best regards,
Marko
I conducted this test without applying the patch https://github.com/glenvt18/vdr/commit/b368f67d00d0b466ae36028efb9336e81f77d...
As far as I can tell, even with that patch the EPG parser could keep running, because the patch does not set the variable InhibitEpgScan. That would explain why the patch did not help reduce VDR power consumption with the Astrometa USB stick.
Thanks for the info on CPU use etc.
FYI I'm using the powersaving patch on a system with an Astrometa USB stick + an old Winfast PCI receiver, and I see 2-3W reduction when the Astrometa frontend is shut down:
Nov 27 20:13:09 ha-server vdr[7196]: [7196] frontend 1/0 provides DVB-T,DVB-T2,DVB-C with QPSK,QAM16,QAM32,QAM64,QAM128,QAM256 ("Sony CXD2837ER DVB-T/T2/C demodulator")
Nov 27 20:49:08 ha-server vdr[12959]: [12959] dvb tuner: power-down - closing frontend 1/0
But I'm still running V2.20 and have a workaround for the 2 frontends on the Astometa - both for reasons mentioned before on this list.
HTH/Richard
Mon, Nov 28, 2022 at 12:27:08PM +0000, Richard F wrote:
FYI I'm using the powersaving patch on a system with an Astrometa USB stick + an old Winfast PCI receiver, and I see 2-3W reduction when the Astrometa frontend is shut down:
I only tested with a single receiver. Your patch may very well switch off any additional receivers, but it seems to me that one front-end would always remain enabled.
Today, I measured the power consumption again, with the Pi TV HAT attached, but without an aerial cable. The setup is a bit flimsy; like last year, the Raspberry Pi is displaying an undervoltage warning icon on the top right corner. I do not dare to over-volt the power supply.
For comparison, I am quoting my figures from last year, without the Pi TV HAT, and with/without the Astrometa stick:
I measured the following current draw at 5 volts, in ascending order:
81 mA: Raspberry Pi 2B shut down
127 mA: Raspberry Pi 2B + TV HAT shut down
200 mA: Raspberry Pi 2B powered up, no Ethernet plugged in 240 mA: Ethernet cable plugged in (HDMI cable makes no difference)
256 mA: Ethernet cable plugged in; Pi TV HAT attached 267 mA: Ethernet + HDMI plugged in; Pi TV HAT attached
320 mA: Ethernet + USB DVB stick plugged in 440 mA: compiling VDR with "make -j4" (all CPU cores busy)
480 mA: compiling (peak; sometimes as low as 300 mA)
550 mA: VDR playing back a recording 530 mA: recording paused in VDR 510 mA: EPG scan running 600 mA: VDR displaying live DVB-T2
440 mA: VDR started up, blank screen (no aerial plugged in) 510 mA: VDR playing back a recording (peak value) 450 mA: recording paused in VDR
This time, I did not plug in an aerial cable at all. I would guess that displaying live TV would consume at most 550 mA.
As you can see from the above, the idle consumption is about 260 mA. When VDR is seemingly idle, I am seeing additional consumption of around 200 mA.
Notably, after I killed the vdr process, the power consumption would hover around 330 mA. It could be that my version of rpihddevice is not properly shutting down all processes on the Videocore IV GPU. After I restarted the VDR process, I got a similar power consumption as above.
While it does not like we can blame the active tuner for all of the additional consumption of 200 mA, I think that we can attribute at least 100 mA to it. The difference between 260 mA and 450 mA is +70%, not insignificant.
I am glad to see that the Pi TV HAT is consuming less power than the Astrometa stick. It is logical, because the TV HAT does not have to run an additional 8051 microcontroller and a step-down SMPS to produce 3.3V from the 5V USB supply, and presumably at least one separately packaged memory chip.
But I'm still running V2.20 and have a workaround for the 2 frontends on the Astometa - both for reasons mentioned before on this list.
Yes, I remember the frontend-swapping issue on the Astrometa. It may have been fixed in 2.6. I didn't try the Astrometa stick on my Pi after reinstalling Raspberry OS Legacy from the scratch.
Marko
On 28/11/2022 18:17, Marko Mäkelä wrote:
Mon, Nov 28, 2022 at 12:27:08PM +0000, Richard F wrote:
FYI I'm using the powersaving patch on a system with an Astrometa USB stick + an old Winfast PCI receiver, and I see 2-3W reduction when the Astrometa frontend is shut down:
I only tested with a single receiver. Your patch may very well switch off any additional receivers, but it seems to me that one front-end would always remain enabled.
Yes - true - I only see frontend 1/0 powering down
Richard
Mon, Oct 11, 2021 at 04:02:43PM +0100, Richard F wrote:
Powersaving for DVB receivers - try the attached patch from glenvt18
Thank you. I will test it later once I have hooked up the Raspberry Pi to my laboratory power supply so that I can observe the total power consumption.
While "uhubctl -a off" would cause an optimal mouse to power off its LED, it will not completely cut the power. I tested this by plugging in a mobile phone to the USB port. It indicated that charging is available.
One impact of "uhubctl -a off" is that any plug/unplug events for the affected ports will be disabled, and "lsusb" will reflect the state as it was before the invocation.
I just confirmed with a laboratory power supply that my USB DVB-T/T2/C stick is consuming 61 mA at 5 volts. If I remember correctly, USB devices are allowed to drain up to 100 mA without any negotiation, so it should not be out-of-spec. Those additional 0.35 watts should be a significant portion of the total power consumption. I did not measure yet, but I hope it to be in the range of 2 to 3 watts.
For my use case, I think that I will only configure udev events for inserting or removing the stick. No shutdown command would be configured in VDR. I would abruptly shut down VDR and lircd by unplugging the adapter. They would observe the abrupt loss of DVB hardware, followed by a terminating signal sent by systemd or udevd.
Best regards,
Marko