mirror of
https://github.com/VDR4Arch/vdr.git
synced 2023-10-10 13:36:52 +02:00
Fixed a possible crash in case replay is started and stopped in rapid sequence
This commit is contained in:
parent
dd9dd76722
commit
196785ff05
11
HISTORY
11
HISTORY
@ -9420,7 +9420,7 @@ Video Disk Recorder Revision History
|
|||||||
- Fixed handling the S2SatelliteDeliverySystemDescriptor for transponders broadcasting
|
- Fixed handling the S2SatelliteDeliverySystemDescriptor for transponders broadcasting
|
||||||
in "backwards compatibility mode" according to ETSI EN 300 468 (thanks to Onur Sentürk).
|
in "backwards compatibility mode" according to ETSI EN 300 468 (thanks to Onur Sentürk).
|
||||||
|
|
||||||
2020-05-15:
|
2020-05-18: Version 2.4.2
|
||||||
|
|
||||||
- Fixed moving channels between number groups in SVDRP's MOVC command and the Channels
|
- Fixed moving channels between number groups in SVDRP's MOVC command and the Channels
|
||||||
menu, in case a channel is moved to a higher number and into a numbered group
|
menu, in case a channel is moved to a higher number and into a numbered group
|
||||||
@ -9443,3 +9443,12 @@ Video Disk Recorder Revision History
|
|||||||
is valid (suggested by Helmut Binder).
|
is valid (suggested by Helmut Binder).
|
||||||
- The isSingleByte parameter in the call to getCharacterTable() is deprecated and only
|
- The isSingleByte parameter in the call to getCharacterTable() is deprecated and only
|
||||||
present for backwards compatibility.
|
present for backwards compatibility.
|
||||||
|
- Fixed a possible crash in case replay is started and stopped in rapid sequence, by
|
||||||
|
adding missing locking to cControl::Control(). The caller of this function must now
|
||||||
|
provide a cMutexLock which stays alive as long as the result of this call is used.
|
||||||
|
The old version of this function is still there for backwards compatibility with
|
||||||
|
plugins, because this problem appears to occur only under very rare circumstances.
|
||||||
|
Authors of plugins that use this function should switch to the new version, because
|
||||||
|
the old one is deprecated and will be removed in a future version.
|
||||||
|
The version numbers (both VDRVERSNUM and APIVERSNUM) have been bumped to 2.4.2, so
|
||||||
|
that plugins can detect the presence of the new cControl::Control().
|
||||||
|
10
config.h
10
config.h
@ -4,7 +4,7 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* how to reach the author.
|
||||||
*
|
*
|
||||||
* $Id: config.h 4.16 2019/06/16 09:13:45 kls Exp $
|
* $Id: config.h 4.17 2020/05/18 16:47:29 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __CONFIG_H
|
#ifndef __CONFIG_H
|
||||||
@ -22,13 +22,13 @@
|
|||||||
|
|
||||||
// VDR's own version number:
|
// VDR's own version number:
|
||||||
|
|
||||||
#define VDRVERSION "2.4.1"
|
#define VDRVERSION "2.4.2"
|
||||||
#define VDRVERSNUM 20401 // Version * 10000 + Major * 100 + Minor
|
#define VDRVERSNUM 20402 // Version * 10000 + Major * 100 + Minor
|
||||||
|
|
||||||
// The plugin API's version number:
|
// The plugin API's version number:
|
||||||
|
|
||||||
#define APIVERSION "2.4.1"
|
#define APIVERSION "2.4.2"
|
||||||
#define APIVERSNUM 20401 // Version * 10000 + Major * 100 + Minor
|
#define APIVERSNUM 20402 // Version * 10000 + Major * 100 + Minor
|
||||||
|
|
||||||
// When loading plugins, VDR searches them by their APIVERSION, which
|
// When loading plugins, VDR searches them by their APIVERSION, which
|
||||||
// may be smaller than VDRVERSION in case there have been no changes to
|
// may be smaller than VDRVERSION in case there have been no changes to
|
||||||
|
11
menu.c
11
menu.c
@ -4,7 +4,7 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* how to reach the author.
|
||||||
*
|
*
|
||||||
* $Id: menu.c 4.81 2020/04/11 09:22:05 kls Exp $
|
* $Id: menu.c 4.82 2020/05/18 16:47:29 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "menu.h"
|
#include "menu.h"
|
||||||
@ -2731,7 +2731,8 @@ eOSState cMenuRecordingEdit::DeleteMarks(void)
|
|||||||
if (buttonDeleteMarks && Interface->Confirm(tr("Delete editing marks for this recording?"))) {
|
if (buttonDeleteMarks && Interface->Confirm(tr("Delete editing marks for this recording?"))) {
|
||||||
if (cMarks::DeleteMarksFile(recording)) {
|
if (cMarks::DeleteMarksFile(recording)) {
|
||||||
SetHelpKeys();
|
SetHelpKeys();
|
||||||
if (cControl *Control = cControl::Control(true)) {
|
cMutexLock ControlMutexLock;
|
||||||
|
if (cControl *Control = cControl::Control(ControlMutexLock, true)) {
|
||||||
if (const cRecording *Recording = Control->GetRecording()) {
|
if (const cRecording *Recording = Control->GetRecording()) {
|
||||||
if (strcmp(recording->FileName(), Recording->FileName()) == 0)
|
if (strcmp(recording->FileName(), Recording->FileName()) == 0)
|
||||||
Control->ClearEditingMarks();
|
Control->ClearEditingMarks();
|
||||||
@ -4457,7 +4458,11 @@ bool cMenuMain::Update(bool Force)
|
|||||||
{
|
{
|
||||||
bool result = false;
|
bool result = false;
|
||||||
|
|
||||||
bool NewReplaying = cControl::Control() != NULL;
|
bool NewReplaying = false;
|
||||||
|
{
|
||||||
|
cMutexLock ControlMutexLock;
|
||||||
|
NewReplaying = cControl::Control(ControlMutexLock) != NULL;
|
||||||
|
}
|
||||||
if (Force || NewReplaying != replaying) {
|
if (Force || NewReplaying != replaying) {
|
||||||
replaying = NewReplaying;
|
replaying = NewReplaying;
|
||||||
// Replay control:
|
// Replay control:
|
||||||
|
12
player.c
12
player.c
@ -4,7 +4,7 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* how to reach the author.
|
||||||
*
|
*
|
||||||
* $Id: player.c 2.2 2012/04/28 11:52:50 kls Exp $
|
* $Id: player.c 4.1 2020/05/18 16:47:29 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "player.h"
|
#include "player.h"
|
||||||
@ -70,16 +70,24 @@ cString cControl::GetHeader(void)
|
|||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if DEPRECATED_CCONTROL
|
||||||
cControl *cControl::Control(bool Hidden)
|
cControl *cControl::Control(bool Hidden)
|
||||||
{
|
{
|
||||||
cMutexLock MutexLock(&mutex);
|
cMutexLock MutexLock(&mutex);
|
||||||
return (control && (!control->hidden || Hidden)) ? control : NULL;
|
return (control && (!control->hidden || Hidden)) ? control : NULL;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
cControl *cControl::Control(cMutexLock &MutexLock, bool Hidden)
|
||||||
|
{
|
||||||
|
MutexLock.Lock(&mutex);
|
||||||
|
return (control && (!control->hidden || Hidden)) ? control : NULL;
|
||||||
|
}
|
||||||
|
|
||||||
void cControl::Launch(cControl *Control)
|
void cControl::Launch(cControl *Control)
|
||||||
{
|
{
|
||||||
cMutexLock MutexLock(&mutex);
|
cMutexLock MutexLock(&mutex);
|
||||||
cControl *c = control; // keeps control from pointing to uninitialized memory
|
cControl *c = control; // keeps control from pointing to uninitialized memory TODO obsolete once DEPRECATED_CCONTROL is gone
|
||||||
control = Control;
|
control = Control;
|
||||||
delete c;
|
delete c;
|
||||||
}
|
}
|
||||||
|
13
player.h
13
player.h
@ -4,7 +4,7 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* how to reach the author.
|
||||||
*
|
*
|
||||||
* $Id: player.h 4.4 2018/02/01 15:34:51 kls Exp $
|
* $Id: player.h 4.5 2020/05/18 16:47:29 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __PLAYER_H
|
#ifndef __PLAYER_H
|
||||||
@ -114,10 +114,21 @@ public:
|
|||||||
static void Launch(cControl *Control);
|
static void Launch(cControl *Control);
|
||||||
static void Attach(void);
|
static void Attach(void);
|
||||||
static void Shutdown(void);
|
static void Shutdown(void);
|
||||||
|
#define DEPRECATED_CCONTROL 1
|
||||||
|
#if DEPRECATED_CCONTROL
|
||||||
static cControl *Control(bool Hidden = false);
|
static cControl *Control(bool Hidden = false);
|
||||||
|
///< Old version of this function, for backwards compatibility with plugins.
|
||||||
|
///< Plugins should be changed to use the new version below, which does
|
||||||
|
///< proper locking.
|
||||||
|
///< Use of this function may result in program crashes in case replay is
|
||||||
|
///< stopped immediately after starting it.
|
||||||
|
#endif
|
||||||
|
static cControl *Control(cMutexLock &MutexLock, bool Hidden = false);
|
||||||
///< Returns the current replay control (if any) in case it is currently
|
///< Returns the current replay control (if any) in case it is currently
|
||||||
///< visible. If Hidden is true, the control will be returned even if it is
|
///< visible. If Hidden is true, the control will be returned even if it is
|
||||||
///< currently hidden.
|
///< currently hidden.
|
||||||
|
///< The given MutexLock must live as long as the replay control is accessed,
|
||||||
|
///< and must go out of scope as soon as the control is no longer accessed.
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif //__PLAYER_H
|
#endif //__PLAYER_H
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* how to reach the author.
|
||||||
*
|
*
|
||||||
* $Id: skinlcars.c 4.6 2017/11/08 10:10:30 kls Exp $
|
* $Id: skinlcars.c 4.7 2020/05/18 16:47:29 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// "Star Trek: The Next Generation"(R) is a registered trademark of Paramount Pictures,
|
// "Star Trek: The Next Generation"(R) is a registered trademark of Paramount Pictures,
|
||||||
@ -1741,12 +1741,13 @@ void cSkinLCARSDisplayMenu::Flush(void)
|
|||||||
{
|
{
|
||||||
if (MenuCategory() == mcMain) {
|
if (MenuCategory() == mcMain) {
|
||||||
cDevice *Device = cDevice::PrimaryDevice();
|
cDevice *Device = cDevice::PrimaryDevice();
|
||||||
|
cMutexLock ControlMutexLock;
|
||||||
if (!Device->Replaying() || Device->Transferring()) {
|
if (!Device->Replaying() || Device->Transferring()) {
|
||||||
LOCK_CHANNELS_READ;
|
LOCK_CHANNELS_READ;
|
||||||
const cChannel *Channel = Channels->GetByNumber(cDevice::PrimaryDevice()->CurrentChannel());
|
const cChannel *Channel = Channels->GetByNumber(cDevice::PrimaryDevice()->CurrentChannel());
|
||||||
DrawLive(Channel);
|
DrawLive(Channel);
|
||||||
}
|
}
|
||||||
else if (cControl *Control = cControl::Control(true))
|
else if (cControl *Control = cControl::Control(ControlMutexLock, true))
|
||||||
DrawPlay(Control);
|
DrawPlay(Control);
|
||||||
DrawTimers();
|
DrawTimers();
|
||||||
DrawDevices();
|
DrawDevices();
|
||||||
|
69
vdr.c
69
vdr.c
@ -22,7 +22,7 @@
|
|||||||
*
|
*
|
||||||
* The project's page is at http://www.tvdr.de
|
* The project's page is at http://www.tvdr.de
|
||||||
*
|
*
|
||||||
* $Id: vdr.c 4.32 2020/05/15 11:31:40 kls Exp $
|
* $Id: vdr.c 4.33 2020/05/18 16:47:29 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <getopt.h>
|
#include <getopt.h>
|
||||||
@ -1196,8 +1196,19 @@ int main(int argc, char *argv[])
|
|||||||
// Queued messages:
|
// Queued messages:
|
||||||
Skins.ProcessQueuedMessages();
|
Skins.ProcessQueuedMessages();
|
||||||
// User Input:
|
// User Input:
|
||||||
cOsdObject *Interact = Menu ? Menu : cControl::Control();
|
bool NeedsFastResponse = Menu && Menu->NeedsFastResponse();
|
||||||
eKeys key = Interface->GetKey(!Interact || !Interact->NeedsFastResponse());
|
if (!NeedsFastResponse) {
|
||||||
|
// Must limit the scope of ControlMutexLock here to not hold the lock during the call to Interface->GetKey().
|
||||||
|
cMutexLock ControlMutexLock;
|
||||||
|
cControl *Control = cControl::Control(ControlMutexLock);
|
||||||
|
NeedsFastResponse = Control && Control->NeedsFastResponse();
|
||||||
|
}
|
||||||
|
eKeys key = Interface->GetKey(!NeedsFastResponse);
|
||||||
|
cOsdObject *Interact = Menu;
|
||||||
|
cMutexLock ControlMutexLock;
|
||||||
|
cControl *Control = NULL;
|
||||||
|
if (!Menu)
|
||||||
|
Interact = Control = cControl::Control(ControlMutexLock);
|
||||||
if (ISREALKEY(key)) {
|
if (ISREALKEY(key)) {
|
||||||
EITScanner.Activity();
|
EITScanner.Activity();
|
||||||
// Cancel shutdown countdown:
|
// Cancel shutdown countdown:
|
||||||
@ -1215,9 +1226,9 @@ int main(int argc, char *argv[])
|
|||||||
bool WasMenu = Interact && Interact->IsMenu();
|
bool WasMenu = Interact && Interact->IsMenu();
|
||||||
if (Menu)
|
if (Menu)
|
||||||
DELETE_MENU;
|
DELETE_MENU;
|
||||||
else if (cControl::Control()) {
|
else if (Control) {
|
||||||
if (cOsd::IsOpen())
|
if (cOsd::IsOpen())
|
||||||
cControl::Control()->Hide();
|
Control->Hide();
|
||||||
else
|
else
|
||||||
WasOpen = false;
|
WasOpen = false;
|
||||||
}
|
}
|
||||||
@ -1233,9 +1244,9 @@ int main(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
else if (!Menu) {
|
else if (!Menu) {
|
||||||
IsInfoMenu = true;
|
IsInfoMenu = true;
|
||||||
if (cControl::Control()) {
|
if (Control) {
|
||||||
cControl::Control()->Hide();
|
Control->Hide();
|
||||||
Menu = cControl::Control()->GetInfo();
|
Menu = Control->GetInfo();
|
||||||
if (Menu)
|
if (Menu)
|
||||||
Menu->Show();
|
Menu->Show();
|
||||||
else
|
else
|
||||||
@ -1252,8 +1263,8 @@ int main(int argc, char *argv[])
|
|||||||
// Direct main menu functions:
|
// Direct main menu functions:
|
||||||
#define DirectMainFunction(function)\
|
#define DirectMainFunction(function)\
|
||||||
{ DELETE_MENU;\
|
{ DELETE_MENU;\
|
||||||
if (cControl::Control())\
|
if (Control)\
|
||||||
cControl::Control()->Hide();\
|
Control->Hide();\
|
||||||
Menu = new cMenuMain(function);\
|
Menu = new cMenuMain(function);\
|
||||||
key = kNone; } // nobody else needs to see this key
|
key = kNone; } // nobody else needs to see this key
|
||||||
case kSchedule: DirectMainFunction(osSchedule); break;
|
case kSchedule: DirectMainFunction(osSchedule); break;
|
||||||
@ -1267,8 +1278,8 @@ int main(int argc, char *argv[])
|
|||||||
const char *PluginName = cRemote::GetPlugin();
|
const char *PluginName = cRemote::GetPlugin();
|
||||||
if (PluginName) {
|
if (PluginName) {
|
||||||
DELETE_MENU;
|
DELETE_MENU;
|
||||||
if (cControl::Control())
|
if (Control)
|
||||||
cControl::Control()->Hide();
|
Control->Hide();
|
||||||
cPlugin *plugin = cPluginManager::GetPlugin(PluginName);
|
cPlugin *plugin = cPluginManager::GetPlugin(PluginName);
|
||||||
if (plugin) {
|
if (plugin) {
|
||||||
Menu = plugin->MainMenuAction();
|
Menu = plugin->MainMenuAction();
|
||||||
@ -1290,7 +1301,7 @@ int main(int argc, char *argv[])
|
|||||||
Menu = new cDisplayChannel(NORMALKEY(key));
|
Menu = new cDisplayChannel(NORMALKEY(key));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else if (cDisplayChannel::IsOpen() || cControl::Control()) {
|
else if (cDisplayChannel::IsOpen() || Control) {
|
||||||
Interact->ProcessKey(key);
|
Interact->ProcessKey(key);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -1318,8 +1329,8 @@ int main(int argc, char *argv[])
|
|||||||
break;
|
break;
|
||||||
// Audio track control:
|
// Audio track control:
|
||||||
case kAudio:
|
case kAudio:
|
||||||
if (cControl::Control())
|
if (Control)
|
||||||
cControl::Control()->Hide();
|
Control->Hide();
|
||||||
if (!cDisplayTracks::IsOpen()) {
|
if (!cDisplayTracks::IsOpen()) {
|
||||||
DELETE_MENU;
|
DELETE_MENU;
|
||||||
Menu = cDisplayTracks::Create();
|
Menu = cDisplayTracks::Create();
|
||||||
@ -1330,8 +1341,8 @@ int main(int argc, char *argv[])
|
|||||||
break;
|
break;
|
||||||
// Subtitle track control:
|
// Subtitle track control:
|
||||||
case kSubtitles:
|
case kSubtitles:
|
||||||
if (cControl::Control())
|
if (Control)
|
||||||
cControl::Control()->Hide();
|
Control->Hide();
|
||||||
if (!cDisplaySubtitleTracks::IsOpen()) {
|
if (!cDisplaySubtitleTracks::IsOpen()) {
|
||||||
DELETE_MENU;
|
DELETE_MENU;
|
||||||
Menu = cDisplaySubtitleTracks::Create();
|
Menu = cDisplaySubtitleTracks::Create();
|
||||||
@ -1343,7 +1354,7 @@ int main(int argc, char *argv[])
|
|||||||
// Pausing live video:
|
// Pausing live video:
|
||||||
case kPlayPause:
|
case kPlayPause:
|
||||||
case kPause:
|
case kPause:
|
||||||
if (!cControl::Control()) {
|
if (!Control) {
|
||||||
DELETE_MENU;
|
DELETE_MENU;
|
||||||
if (Setup.PauseKeyHandling) {
|
if (Setup.PauseKeyHandling) {
|
||||||
if (Setup.PauseKeyHandling > 1 || Interface->Confirm(tr("Pause live video?"))) {
|
if (Setup.PauseKeyHandling > 1 || Interface->Confirm(tr("Pause live video?"))) {
|
||||||
@ -1356,7 +1367,7 @@ int main(int argc, char *argv[])
|
|||||||
break;
|
break;
|
||||||
// Instant recording:
|
// Instant recording:
|
||||||
case kRecord:
|
case kRecord:
|
||||||
if (!cControl::Control()) {
|
if (!Control) {
|
||||||
if (Setup.RecordKeyHandling) {
|
if (Setup.RecordKeyHandling) {
|
||||||
if (Setup.RecordKeyHandling > 1 || Interface->Confirm(tr("Start recording?"))) {
|
if (Setup.RecordKeyHandling > 1 || Interface->Confirm(tr("Start recording?"))) {
|
||||||
if (cRecordControls::Start())
|
if (cRecordControls::Start())
|
||||||
@ -1395,15 +1406,16 @@ int main(int argc, char *argv[])
|
|||||||
break;
|
break;
|
||||||
default: break;
|
default: break;
|
||||||
}
|
}
|
||||||
Interact = Menu ? Menu : cControl::Control(); // might have been closed in the mean time
|
Interact = Menu ? Menu : Control; // might have been closed in the mean time
|
||||||
if (Interact) {
|
if (Interact) {
|
||||||
LastInteract = Now;
|
LastInteract = Now;
|
||||||
eOSState state = Interact->ProcessKey(key);
|
eOSState state = Interact->ProcessKey(key);
|
||||||
if (state == osUnknown && Interact != cControl::Control()) {
|
if (state == osUnknown && Interact != Control) {
|
||||||
if (ISMODELESSKEY(key) && cControl::Control()) {
|
if (ISMODELESSKEY(key) && Control) {
|
||||||
state = cControl::Control()->ProcessKey(key);
|
state = Control->ProcessKey(key);
|
||||||
if (state == osEnd) {
|
if (state == osEnd) {
|
||||||
// let's not close a menu when replay ends:
|
// let's not close a menu when replay ends:
|
||||||
|
Control = NULL;
|
||||||
cControl::Shutdown();
|
cControl::Shutdown();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -1422,15 +1434,18 @@ int main(int argc, char *argv[])
|
|||||||
break;
|
break;
|
||||||
case osRecordings:
|
case osRecordings:
|
||||||
DELETE_MENU;
|
DELETE_MENU;
|
||||||
|
Control = NULL;
|
||||||
cControl::Shutdown();
|
cControl::Shutdown();
|
||||||
Menu = new cMenuMain(osRecordings, true);
|
Menu = new cMenuMain(osRecordings, true);
|
||||||
break;
|
break;
|
||||||
case osReplay: DELETE_MENU;
|
case osReplay: DELETE_MENU;
|
||||||
|
Control = NULL;
|
||||||
cControl::Shutdown();
|
cControl::Shutdown();
|
||||||
cControl::Launch(new cReplayControl);
|
cControl::Launch(new cReplayControl);
|
||||||
break;
|
break;
|
||||||
case osStopReplay:
|
case osStopReplay:
|
||||||
DELETE_MENU;
|
DELETE_MENU;
|
||||||
|
Control = NULL;
|
||||||
cControl::Shutdown();
|
cControl::Shutdown();
|
||||||
break;
|
break;
|
||||||
case osPlugin: DELETE_MENU;
|
case osPlugin: DELETE_MENU;
|
||||||
@ -1441,8 +1456,10 @@ int main(int argc, char *argv[])
|
|||||||
case osBack:
|
case osBack:
|
||||||
case osEnd: if (Interact == Menu)
|
case osEnd: if (Interact == Menu)
|
||||||
DELETE_MENU;
|
DELETE_MENU;
|
||||||
else
|
else {
|
||||||
|
Control = NULL;
|
||||||
cControl::Shutdown();
|
cControl::Shutdown();
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
default: ;
|
default: ;
|
||||||
}
|
}
|
||||||
@ -1487,6 +1504,7 @@ int main(int argc, char *argv[])
|
|||||||
// Instant resume of the last viewed recording:
|
// Instant resume of the last viewed recording:
|
||||||
case kPlay:
|
case kPlay:
|
||||||
if (cReplayControl::LastReplayed()) {
|
if (cReplayControl::LastReplayed()) {
|
||||||
|
Control = NULL;
|
||||||
cControl::Shutdown();
|
cControl::Shutdown();
|
||||||
cControl::Launch(new cReplayControl);
|
cControl::Launch(new cReplayControl);
|
||||||
}
|
}
|
||||||
@ -1512,6 +1530,7 @@ int main(int argc, char *argv[])
|
|||||||
int NewPrimaryDVB = Setup.PrimaryDVB;
|
int NewPrimaryDVB = Setup.PrimaryDVB;
|
||||||
if (NewPrimaryDVB != OldPrimaryDVB) {
|
if (NewPrimaryDVB != OldPrimaryDVB) {
|
||||||
DELETE_MENU;
|
DELETE_MENU;
|
||||||
|
Control = NULL;
|
||||||
cControl::Shutdown();
|
cControl::Shutdown();
|
||||||
Skins.QueueMessage(mtInfo, tr("Switching primary DVB..."));
|
Skins.QueueMessage(mtInfo, tr("Switching primary DVB..."));
|
||||||
cOsdProvider::Shutdown();
|
cOsdProvider::Shutdown();
|
||||||
@ -1532,7 +1551,7 @@ int main(int argc, char *argv[])
|
|||||||
ShutdownHandler.countdown.Cancel();
|
ShutdownHandler.countdown.Cancel();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!cControl::Control() && !cRecordControls::Active() && !RecordingsHandler.Active() && (Now - cRemote::LastActivity()) > ACTIVITYTIMEOUT) {
|
if (!Control && !cRecordControls::Active() && !RecordingsHandler.Active() && (Now - cRemote::LastActivity()) > ACTIVITYTIMEOUT) {
|
||||||
// Shutdown:
|
// Shutdown:
|
||||||
// Check whether VDR will be ready for shutdown in SHUTDOWNWAIT seconds:
|
// Check whether VDR will be ready for shutdown in SHUTDOWNWAIT seconds:
|
||||||
time_t Soon = Now + SHUTDOWNWAIT;
|
time_t Soon = Now + SHUTDOWNWAIT;
|
||||||
|
Loading…
Reference in New Issue
Block a user