mirror of
https://github.com/vdr-projects/vdr.git
synced 2025-03-01 10:50:46 +00:00
Version 1.1.28
- Using masks in EIT filtering to reduce the number of filters (thanks to Andreas Schultz). - Fixed handling Ca descriptors (thanks to Stefan Huelswitt). - Now only those Ca descriptors are sent to a CAM that are actually understood by that CAM. - Re-enabled CAM communication during replay and on non-Ca channels. This requires a DVB driver with firmware version 2613 or later. - It is now possible to do simultaneous recording and replay with a single DVB card, even with encrypted channels. This requires the use of the Link Layer firmware, version 2613 or higher; the -icam firmware is still limited to live encrypted channels only. Finally we have time shift for encrypted channels on single card systems! - Enhanced detection of pending user I/O from CAMs to avoid sluggish reaction to remote control keypresses. - Implemented "pause live video". You can now press "Menu/Yellow" or "Pause" on your remote control while watching live video to start an instant recording of the current programme and immediately start replaying that recording.
This commit is contained in:
parent
9f91980146
commit
21a52ccb6d
@ -196,6 +196,7 @@ Andreas Schultz <aschultz@warp10.net>
|
||||
for pointing out some unnecessary #includes in eit.c and a problem with
|
||||
cMenuRecordings::Del(), which caused warnings with gcc-3.2
|
||||
for suggesting a Make.config file
|
||||
for making EIT filtering use masks to reduce the number of filters
|
||||
|
||||
Aaron Holtzman
|
||||
for writing 'ac3dec'
|
||||
|
20
HISTORY
20
HISTORY
@ -2033,3 +2033,23 @@ Video Disk Recorder Revision History
|
||||
applies to the RCU remote control in case of errors during startup.
|
||||
- Fixed handling of Ca parameters with values <= MAXDEVICES, which don't indicate
|
||||
an actual encrypted channel (thanks to Stefan Huelswitt for reporting this one).
|
||||
|
||||
2003-04-21: Version 1.1.28
|
||||
|
||||
- Using masks in EIT filtering to reduce the number of filters (thanks to Andreas
|
||||
Schultz).
|
||||
- Fixed handling Ca descriptors (thanks to Stefan Huelswitt).
|
||||
- Now only those Ca descriptors are sent to a CAM that are actually understood
|
||||
by that CAM.
|
||||
- Re-enabled CAM communication during replay and on non-Ca channels. This requires
|
||||
a DVB driver with firmware version 2613 or later.
|
||||
- It is now possible to do simultaneous recording and replay with a single DVB
|
||||
card, even with encrypted channels. This requires the use of the Link Layer
|
||||
firmware, version 2613 or higher; the -icam firmware is still limited to live
|
||||
encrypted channels only. Finally we have time shift for encrypted channels on
|
||||
single card systems!
|
||||
- Enhanced detection of pending user I/O from CAMs to avoid sluggish reaction
|
||||
to remote control keypresses.
|
||||
- Implemented "pause live video". You can now press "Menu/Yellow" or "Pause" on
|
||||
your remote control while watching live video to start an instant recording
|
||||
of the current programme and immediately start replaying that recording.
|
||||
|
18
MANUAL
18
MANUAL
@ -19,7 +19,7 @@ Video Disk Recorder User's Manual
|
||||
Back - Menu off VDR menu VDR menu Discard VDR menu Recordings menu
|
||||
Red - Record Edit Edit ABC/abc Play/Commands(2) Jump
|
||||
Green - Language New New Ins/Ovr Rewind Skip -60s
|
||||
Yellow - - Delete Delete Delete Delete Skip +60s
|
||||
Yellow - Pause live Delete Delete Delete Delete Skip +60s
|
||||
Blue - Stop/Resume Mark On/Off(1) - Summary Stop
|
||||
0..9 Ch select - - - Numeric inp. Exec cmd(2) Editing
|
||||
|
||||
@ -31,7 +31,7 @@ Video Disk Recorder User's Manual
|
||||
following functions:
|
||||
|
||||
Play resume normal replay
|
||||
Pause pause replay
|
||||
Pause pause replay or live video
|
||||
Stop stop replay
|
||||
Record instant recording
|
||||
FastFwd fast forward
|
||||
@ -191,6 +191,20 @@ Video Disk Recorder User's Manual
|
||||
Stop instant recording by pressing the "Menu" button and selecting
|
||||
"Stop Recording", or by disabling the timer.
|
||||
|
||||
* Pausing live video
|
||||
|
||||
If you want to pause the live programme you are just watching, simple press
|
||||
"Menu/Yellow" or "Pause" on your remote control. VDR will start an instant
|
||||
recording of the current channel (just as if you had pressed "Menu/Red" or
|
||||
"Record") and immediately begin replaying that recording. Replay will be
|
||||
put into "pause" mode, so you can attend to whatever it was that disturbed
|
||||
your live viewing session. Once you're back, simply press the "Up" or "Play"
|
||||
button and you'll be watching the current channel in time shift mode, right
|
||||
from the point where you left off. The instant recording VDR has started
|
||||
will use the same parameters for priority, lifetime and recording duration
|
||||
as any other instant recording, so by default it will record 3 hours (which
|
||||
should be enough for any normal broadcast).
|
||||
|
||||
* Replaying a Recording
|
||||
|
||||
All recordings are listed in the "Recordings" menu. Browse through the
|
||||
|
@ -59,7 +59,7 @@ Studio Universal:12071:h:S19.2E:27500:2047:2048:0:101:36:0:0:0
|
||||
Premiere Serie:12031:h:S19.2E:27500:1023:1024:0:101:16:0:0:0
|
||||
Disney Channel:11758:h:S19.2E:27500:2559:2560:0:101:34:0:0:0
|
||||
Premiere Nostalgie:12031:h:S19.2E:27500:2559:2560:0:101:516:0:0:0
|
||||
Discovery Channel:12031:h:S19.2E:27500:1791:1792:0:101:14:0:0:0
|
||||
Discovery Channel:11758:h:S19.2E:27500:1023:1024:8181:101:14:0:0:0
|
||||
Planet:12090:v:S19.2E:27500:1279:1280:0:101:13:0:0:0
|
||||
Fox Kids:11758:h:S19.2E:27500:1279:1280:0:101:28:0:0:0
|
||||
Junior:11758:h:S19.2E:27500:255:256:0:101:19:0:0:0
|
||||
|
61
ci.c
61
ci.c
@ -4,7 +4,7 @@
|
||||
* See the main source file 'vdr.c' for copyright information and
|
||||
* how to reach the author.
|
||||
*
|
||||
* $Id: ci.c 1.9 2003/03/23 15:18:40 kls Exp $
|
||||
* $Id: ci.c 1.14 2003/04/20 09:52:45 kls Exp $
|
||||
*/
|
||||
|
||||
/* XXX TODO
|
||||
@ -625,6 +625,7 @@ public:
|
||||
const cCiTransportConnection *Tc(void) { return tc; }
|
||||
int SessionId(void) { return sessionId; }
|
||||
int ResourceId(void) { return resourceId; }
|
||||
virtual bool HasUserIO(void) { return false; }
|
||||
virtual bool Process(int Length = 0, const uint8_t *Data = NULL);
|
||||
};
|
||||
|
||||
@ -769,7 +770,7 @@ public:
|
||||
cCiApplicationInformation::cCiApplicationInformation(int SessionId, cCiTransportConnection *Tc)
|
||||
:cCiSession(SessionId, RI_APPLICATION_INFORMATION, Tc)
|
||||
{
|
||||
dbgprotocol("New Aplication Information (session id %d)\n", SessionId);
|
||||
dbgprotocol("New Application Information (session id %d)\n", SessionId);
|
||||
state = 0;
|
||||
creationTime = time(NULL);
|
||||
menuString = NULL;
|
||||
@ -827,12 +828,17 @@ bool cCiApplicationInformation::EnterMenu(void)
|
||||
|
||||
// --- cCiConditionalAccessSupport -------------------------------------------
|
||||
|
||||
#define MAXCASYSTEMIDS 16
|
||||
|
||||
class cCiConditionalAccessSupport : public cCiSession {
|
||||
private:
|
||||
int state;
|
||||
int numCaSystemIds;
|
||||
unsigned short caSystemIds[MAXCASYSTEMIDS + 1]; // list is zero terminated!
|
||||
public:
|
||||
cCiConditionalAccessSupport(int SessionId, cCiTransportConnection *Tc);
|
||||
virtual bool Process(int Length = 0, const uint8_t *Data = NULL);
|
||||
const unsigned short *GetCaSystemIds(void) { return caSystemIds; }
|
||||
bool SendPMT(cCiCaPmt &CaPmt);
|
||||
};
|
||||
|
||||
@ -841,6 +847,7 @@ cCiConditionalAccessSupport::cCiConditionalAccessSupport(int SessionId, cCiTrans
|
||||
{
|
||||
dbgprotocol("New Conditional Access Support (session id %d)\n", SessionId);
|
||||
state = 0;
|
||||
caSystemIds[numCaSystemIds = 0] = 0;
|
||||
}
|
||||
|
||||
bool cCiConditionalAccessSupport::Process(int Length, const uint8_t *Data)
|
||||
@ -853,9 +860,16 @@ bool cCiConditionalAccessSupport::Process(int Length, const uint8_t *Data)
|
||||
int l = 0;
|
||||
const uint8_t *d = GetData(Data, l);
|
||||
while (l > 1) {
|
||||
dbgprotocol(" %04X", ((unsigned int)(*d) << 8) | *(d + 1));
|
||||
unsigned short id = ((unsigned short)(*d) << 8) | *(d + 1);
|
||||
dbgprotocol(" %04X", id);
|
||||
d += 2;
|
||||
l -= 2;
|
||||
if (numCaSystemIds < MAXCASYSTEMIDS) {
|
||||
caSystemIds[numCaSystemIds++] = id;
|
||||
caSystemIds[numCaSystemIds] = 0;
|
||||
}
|
||||
else
|
||||
esyslog("ERROR: too many CA system IDs!");
|
||||
}
|
||||
dbgprotocol("\n");
|
||||
}
|
||||
@ -996,6 +1010,7 @@ public:
|
||||
cCiMMI(int SessionId, cCiTransportConnection *Tc);
|
||||
virtual ~cCiMMI();
|
||||
virtual bool Process(int Length = 0, const uint8_t *Data = NULL);
|
||||
virtual bool HasUserIO(void) { return menu || enquiry; }
|
||||
cCiMenu *Menu(void);
|
||||
cCiEnquiry *Enquiry(void);
|
||||
bool SendMenuAnswer(uint8_t Selection);
|
||||
@ -1273,7 +1288,8 @@ void cCiCaPmt::AddCaDescriptor(int Length, uint8_t *Data)
|
||||
cCiHandler::cCiHandler(int Fd, int NumSlots)
|
||||
{
|
||||
numSlots = NumSlots;
|
||||
enabled = true;
|
||||
newCaSupport = false;
|
||||
hasUserIO = false;
|
||||
for (int i = 0; i < MAX_CI_SESSION; i++)
|
||||
sessions[i] = NULL;
|
||||
tpl = new cCiTransportLayer(Fd, numSlots);
|
||||
@ -1299,12 +1315,14 @@ cCiHandler *cCiHandler::CreateCiHandler(const char *FileName)
|
||||
if (Caps.slot_type == CA_CI_LINK)
|
||||
return new cCiHandler(fd_ca, NumSlots);
|
||||
else
|
||||
esyslog("ERROR: CAM doesn't support link layer interface");
|
||||
isyslog("CAM doesn't support link layer interface");
|
||||
}
|
||||
esyslog("ERROR: no CAM slots found");
|
||||
else
|
||||
esyslog("ERROR: no CAM slots found");
|
||||
}
|
||||
else
|
||||
LOG_ERROR_STR(FileName);
|
||||
close(fd_ca);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
@ -1358,7 +1376,8 @@ cCiSession *cCiHandler::CreateSession(int ResourceId)
|
||||
switch (ResourceId) {
|
||||
case RI_RESOURCE_MANAGER: return sessions[i] = new cCiResourceManager(i + 1, tc);
|
||||
case RI_APPLICATION_INFORMATION: return sessions[i] = new cCiApplicationInformation(i + 1, tc);
|
||||
case RI_CONDITIONAL_ACCESS_SUPPORT: return sessions[i] = new cCiConditionalAccessSupport(i + 1, tc);
|
||||
case RI_CONDITIONAL_ACCESS_SUPPORT: newCaSupport = true;
|
||||
return sessions[i] = new cCiConditionalAccessSupport(i + 1, tc);
|
||||
case RI_HOST_CONTROL: break; //XXX
|
||||
case RI_DATE_TIME: return sessions[i] = new cCiDateTime(i + 1, tc);
|
||||
case RI_MMI: return sessions[i] = new cCiMMI(i + 1, tc);
|
||||
@ -1426,8 +1445,6 @@ int cCiHandler::CloseAllSessions(int Slot)
|
||||
|
||||
bool cCiHandler::Process(void)
|
||||
{
|
||||
if (!enabled)
|
||||
return false;
|
||||
bool result = true;
|
||||
cMutexLock MutexLock(&mutex);
|
||||
for (int Slot = 0; Slot < numSlots; Slot++) {
|
||||
@ -1466,10 +1483,14 @@ bool cCiHandler::Process(void)
|
||||
tpl->NewConnection(Slot);
|
||||
}
|
||||
}
|
||||
bool UserIO = false;
|
||||
for (int i = 0; i < MAX_CI_SESSION; i++) {
|
||||
if (sessions[i])
|
||||
sessions[i]->Process();
|
||||
if (sessions[i] && sessions[i]->Process())
|
||||
UserIO |= sessions[i]->HasUserIO();
|
||||
}
|
||||
hasUserIO = UserIO;
|
||||
if (newCaSupport)
|
||||
newCaSupport = result = false; // triggers new SetCaPmt at caller!
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -1502,16 +1523,18 @@ cCiEnquiry *cCiHandler::GetEnquiry(void)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bool cCiHandler::SetCaPmt(cCiCaPmt &CaPmt)
|
||||
const unsigned short *cCiHandler::GetCaSystemIds(int Slot)
|
||||
{
|
||||
cMutexLock MutexLock(&mutex);
|
||||
bool result = false;
|
||||
for (int Slot = 0; Slot < numSlots; Slot++) {
|
||||
cCiConditionalAccessSupport *cas = (cCiConditionalAccessSupport *)GetSessionByResourceId(RI_CONDITIONAL_ACCESS_SUPPORT, Slot);
|
||||
if (cas)
|
||||
result |= cas->SendPMT(CaPmt);
|
||||
}
|
||||
return result;
|
||||
cCiConditionalAccessSupport *cas = (cCiConditionalAccessSupport *)GetSessionByResourceId(RI_CONDITIONAL_ACCESS_SUPPORT, Slot);
|
||||
return cas ? cas->GetCaSystemIds() : NULL;
|
||||
}
|
||||
|
||||
bool cCiHandler::SetCaPmt(cCiCaPmt &CaPmt, int Slot)
|
||||
{
|
||||
cMutexLock MutexLock(&mutex);
|
||||
cCiConditionalAccessSupport *cas = (cCiConditionalAccessSupport *)GetSessionByResourceId(RI_CONDITIONAL_ACCESS_SUPPORT, Slot);
|
||||
return cas && cas->SendPMT(CaPmt);
|
||||
}
|
||||
|
||||
bool cCiHandler::Reset(int Slot)
|
||||
|
11
ci.h
11
ci.h
@ -4,7 +4,7 @@
|
||||
* See the main source file 'vdr.c' for copyright information and
|
||||
* how to reach the author.
|
||||
*
|
||||
* $Id: ci.h 1.4 2003/03/23 15:18:40 kls Exp $
|
||||
* $Id: ci.h 1.7 2003/04/20 09:21:23 kls Exp $
|
||||
*/
|
||||
|
||||
#ifndef __CI_H
|
||||
@ -80,7 +80,8 @@ class cCiHandler {
|
||||
private:
|
||||
cMutex mutex;
|
||||
int numSlots;
|
||||
bool enabled;
|
||||
bool newCaSupport;
|
||||
bool hasUserIO;
|
||||
cCiSession *sessions[MAX_CI_SESSION];
|
||||
cCiTransportLayer *tpl;
|
||||
cCiTransportConnection *tc;
|
||||
@ -96,12 +97,14 @@ private:
|
||||
public:
|
||||
~cCiHandler();
|
||||
static cCiHandler *CreateCiHandler(const char *FileName);
|
||||
void SetEnabled(bool Enabled) { enabled = Enabled; }
|
||||
int NumSlots(void) { return numSlots; }
|
||||
bool Process(void);
|
||||
bool HasUserIO(void) { return hasUserIO; }
|
||||
bool EnterMenu(int Slot);
|
||||
cCiMenu *GetMenu(void);
|
||||
cCiEnquiry *GetEnquiry(void);
|
||||
bool SetCaPmt(cCiCaPmt &CaPmt);
|
||||
const unsigned short *GetCaSystemIds(int Slot);
|
||||
bool SetCaPmt(cCiCaPmt &CaPmt, int Slot);
|
||||
bool Reset(int Slot);
|
||||
};
|
||||
|
||||
|
4
config.h
4
config.h
@ -4,7 +4,7 @@
|
||||
* See the main source file 'vdr.c' for copyright information and
|
||||
* how to reach the author.
|
||||
*
|
||||
* $Id: config.h 1.152 2003/04/12 09:35:50 kls Exp $
|
||||
* $Id: config.h 1.153 2003/04/13 14:02:02 kls Exp $
|
||||
*/
|
||||
|
||||
#ifndef __CONFIG_H
|
||||
@ -19,7 +19,7 @@
|
||||
#include "device.h"
|
||||
#include "tools.h"
|
||||
|
||||
#define VDRVERSION "1.1.27"
|
||||
#define VDRVERSION "1.1.28"
|
||||
|
||||
#define MAXPRIORITY 99
|
||||
#define MAXLIFETIME 99
|
||||
|
66
dvbdevice.c
66
dvbdevice.c
@ -4,7 +4,7 @@
|
||||
* See the main source file 'vdr.c' for copyright information and
|
||||
* how to reach the author.
|
||||
*
|
||||
* $Id: dvbdevice.c 1.51 2003/04/12 15:06:11 kls Exp $
|
||||
* $Id: dvbdevice.c 1.54 2003/04/19 14:24:25 kls Exp $
|
||||
*/
|
||||
|
||||
#include "dvbdevice.h"
|
||||
@ -116,13 +116,14 @@ bool cDvbTuner::IsTunedTo(const cChannel *Channel) const
|
||||
void cDvbTuner::Set(const cChannel *Channel, bool Tune)
|
||||
{
|
||||
cMutexLock MutexLock(&mutex);
|
||||
channel = *Channel;
|
||||
bool CaChange = !(Channel->GetChannelID() == channel.GetChannelID());
|
||||
if (Tune)
|
||||
tunerStatus = tsSet;
|
||||
else if (tunerStatus == tsCam)
|
||||
else if (tunerStatus == tsCam && CaChange)
|
||||
tunerStatus = tsTuned;
|
||||
if (Channel->Ca())
|
||||
if (Channel->Ca() && CaChange)
|
||||
startTime = time(NULL);
|
||||
channel = *Channel;
|
||||
newSet.Broadcast();
|
||||
}
|
||||
|
||||
@ -264,27 +265,29 @@ void cDvbTuner::Action(void)
|
||||
}
|
||||
}
|
||||
if (tunerStatus >= tsLocked) {
|
||||
if (ciHandler && channel.Ca()) {
|
||||
if (ciHandler) {
|
||||
if (ciHandler->Process()) {
|
||||
if (tunerStatus != tsCam) {//XXX TODO update in case the CA descriptors have changed
|
||||
uchar buffer[2048];
|
||||
int length = cSIProcessor::GetCaDescriptors(channel.Source(), channel.Frequency(), channel.Sid(), sizeof(buffer), buffer);
|
||||
if (length > 0) {
|
||||
cCiCaPmt CaPmt(channel.Sid());
|
||||
CaPmt.AddCaDescriptor(length, buffer);
|
||||
if (channel.Vpid())
|
||||
CaPmt.AddPid(channel.Vpid());
|
||||
if (channel.Apid1())
|
||||
CaPmt.AddPid(channel.Apid1());
|
||||
if (channel.Apid2())
|
||||
CaPmt.AddPid(channel.Apid2());
|
||||
if (channel.Dpid1())
|
||||
CaPmt.AddPid(channel.Dpid1());
|
||||
if (ciHandler->SetCaPmt(CaPmt)) {
|
||||
tunerStatus = tsCam;
|
||||
startTime = 0;
|
||||
}
|
||||
}
|
||||
for (int Slot = 0; Slot < ciHandler->NumSlots(); Slot++) {
|
||||
uchar buffer[2048];
|
||||
int length = cSIProcessor::GetCaDescriptors(channel.Source(), channel.Frequency(), channel.Sid(), ciHandler->GetCaSystemIds(Slot), sizeof(buffer), buffer);
|
||||
if (length > 0) {
|
||||
cCiCaPmt CaPmt(channel.Sid());
|
||||
CaPmt.AddCaDescriptor(length, buffer);
|
||||
if (channel.Vpid())
|
||||
CaPmt.AddPid(channel.Vpid());
|
||||
if (channel.Apid1())
|
||||
CaPmt.AddPid(channel.Apid1());
|
||||
if (channel.Apid2())
|
||||
CaPmt.AddPid(channel.Apid2());
|
||||
if (channel.Dpid1())
|
||||
CaPmt.AddPid(channel.Dpid1());
|
||||
if (ciHandler->SetCaPmt(CaPmt, Slot)) {
|
||||
tunerStatus = tsCam;
|
||||
startTime = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -588,7 +591,8 @@ bool cDvbDevice::ProvidesChannel(const cChannel *Channel, int Priority, bool *Ne
|
||||
if (!HasPid(Channel->Vpid())) {
|
||||
#ifdef DO_MULTIPLE_RECORDINGS
|
||||
if (Channel->Ca() > CACONFBASE)
|
||||
needsDetachReceivers = true;
|
||||
needsDetachReceivers = !ciHandler // only LL-firmware can do non-live CA channels
|
||||
|| Ca() != Channel->Ca();
|
||||
else if (!IsPrimaryDevice())
|
||||
result = true;
|
||||
#ifdef DO_REC_AND_PLAY_ON_PRIMARY_DEVICE
|
||||
@ -609,7 +613,7 @@ bool cDvbDevice::ProvidesChannel(const cChannel *Channel, int Priority, bool *Ne
|
||||
|
||||
bool cDvbDevice::SetChannelDevice(const cChannel *Channel, bool LiveView)
|
||||
{
|
||||
bool IsEncrypted = Channel->Ca() > CACONFBASE;
|
||||
bool IsEncrypted = Channel->Ca() > CACONFBASE && !ciHandler; // only LL-firmware can do non-live CA channels
|
||||
|
||||
bool DoTune = !dvbTuner->IsTunedTo(Channel);
|
||||
|
||||
@ -714,7 +718,7 @@ int cDvbDevice::NumAudioTracksDevice(void) const
|
||||
int n = 0;
|
||||
if (aPid1)
|
||||
n++;
|
||||
if (Ca() <= MAXDEVICES && aPid2 && aPid1 != aPid2) // a Ca recording session blocks switching live audio tracks
|
||||
if (Ca() <= MAXDEVICES && aPid2 && aPid1 != aPid2) // a CA recording session blocks switching live audio tracks
|
||||
n++;
|
||||
return n;
|
||||
}
|
||||
@ -746,7 +750,7 @@ bool cDvbDevice::CanReplay(void) const
|
||||
if (Receiving())
|
||||
return false;
|
||||
#endif
|
||||
return cDevice::CanReplay() && Ca() <= MAXDEVICES; // we can only replay if there is no Ca recording going on
|
||||
return cDevice::CanReplay() && (Ca() <= MAXDEVICES || ciHandler); // with non-LL-firmware we can only replay if there is no CA recording going on
|
||||
}
|
||||
|
||||
bool cDvbDevice::SetPlayMode(ePlayMode PlayMode)
|
||||
@ -775,15 +779,11 @@ bool cDvbDevice::SetPlayMode(ePlayMode PlayMode)
|
||||
CHECK(ioctl(fd_audio, AUDIO_SET_MUTE, false));
|
||||
if (siProcessor)
|
||||
siProcessor->SetStatus(true);
|
||||
if (ciHandler)
|
||||
ciHandler->SetEnabled(true);
|
||||
break;
|
||||
case pmAudioVideo:
|
||||
case pmAudioOnlyBlack:
|
||||
if (siProcessor)
|
||||
siProcessor->SetStatus(false);
|
||||
if (ciHandler)
|
||||
ciHandler->SetEnabled(false);
|
||||
CHECK(ioctl(fd_video, VIDEO_SET_BLANK, true));
|
||||
CHECK(ioctl(fd_audio, AUDIO_SELECT_SOURCE, AUDIO_SOURCE_MEMORY));
|
||||
CHECK(ioctl(fd_audio, AUDIO_SET_AV_SYNC, PlayMode == pmAudioVideo));
|
||||
@ -794,8 +794,6 @@ bool cDvbDevice::SetPlayMode(ePlayMode PlayMode)
|
||||
case pmAudioOnly:
|
||||
if (siProcessor)
|
||||
siProcessor->SetStatus(false);
|
||||
if (ciHandler)
|
||||
ciHandler->SetEnabled(false);
|
||||
CHECK(ioctl(fd_video, VIDEO_SET_BLANK, true));
|
||||
CHECK(ioctl(fd_audio, AUDIO_STOP, true));
|
||||
CHECK(ioctl(fd_audio, AUDIO_CLEAR_BUFFER));
|
||||
@ -807,8 +805,6 @@ bool cDvbDevice::SetPlayMode(ePlayMode PlayMode)
|
||||
case pmExtern_THIS_SHOULD_BE_AVOIDED:
|
||||
if (siProcessor)
|
||||
siProcessor->SetStatus(false);
|
||||
if (ciHandler)
|
||||
ciHandler->SetEnabled(false);
|
||||
close(fd_video);
|
||||
close(fd_audio);
|
||||
fd_video = fd_audio = -1;
|
||||
|
91
eit.c
91
eit.c
@ -16,7 +16,7 @@
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* $Id: eit.c 1.68 2003/04/12 11:27:31 kls Exp $
|
||||
* $Id: eit.c 1.72 2003/04/21 13:21:54 kls Exp $
|
||||
***************************************************************************/
|
||||
|
||||
#include "eit.h"
|
||||
@ -1002,34 +1002,38 @@ bool cEIT::IsPresentFollowing()
|
||||
// --- cCaDescriptor ---------------------------------------------------------
|
||||
|
||||
class cCaDescriptor : public cListObject {
|
||||
friend class cCaDescriptors;
|
||||
friend class cSIProcessor;
|
||||
private:
|
||||
int source;
|
||||
int transponder;
|
||||
int serviceId;
|
||||
int caSystem;
|
||||
unsigned int providerId;
|
||||
int caPid;
|
||||
int length;
|
||||
uchar *data;
|
||||
public:
|
||||
cCaDescriptor(int Source, int Transponder, int ServiceId, int CaSystem, int CaPid, int Length, uchar *Data);
|
||||
cCaDescriptor(int Source, int Transponder, int ServiceId, int CaSystem, unsigned int ProviderId, int CaPid, int Length, uchar *Data);
|
||||
virtual ~cCaDescriptor();
|
||||
int Length(void) const { return length; }
|
||||
const uchar *Data(void) const { return data; }
|
||||
};
|
||||
|
||||
cCaDescriptor::cCaDescriptor(int Source, int Transponder, int ServiceId, int CaSystem, int CaPid, int Length, uchar *Data)
|
||||
cCaDescriptor::cCaDescriptor(int Source, int Transponder, int ServiceId, int CaSystem, unsigned int ProviderId, int CaPid, int Length, uchar *Data)
|
||||
{
|
||||
source = Source;
|
||||
transponder = Transponder;
|
||||
serviceId = ServiceId;
|
||||
caSystem = CaSystem;
|
||||
providerId = ProviderId;
|
||||
caPid = CaPid;
|
||||
length = Length + 6;
|
||||
data = MALLOC(uchar, length);
|
||||
data[0] = DESCR_CA;
|
||||
data[1] = length - 2;
|
||||
data[2] = (caSystem >> 8) & 0xFF;
|
||||
data[3] = caSystem & 0xFF;
|
||||
data[4] = ((CaPid >> 8) & 0xFF) | 0xE0;
|
||||
data[4] = ((CaPid >> 8) & 0x1F) | 0xE0;
|
||||
data[5] = CaPid & 0xFF;
|
||||
if (Length)
|
||||
memcpy(&data[6], Data, Length);
|
||||
@ -1037,7 +1041,7 @@ cCaDescriptor::cCaDescriptor(int Source, int Transponder, int ServiceId, int CaS
|
||||
#ifdef DEBUG_CA_DESCRIPTORS
|
||||
char buffer[1024];
|
||||
char *q = buffer;
|
||||
q += sprintf(q, "CAM: %04X %5d %4d", source, transponder, serviceId);
|
||||
q += sprintf(q, "CAM: %04X %5d %5d %04X %6X %04X -", source, transponder, serviceId, caSystem, providerId, caPid);
|
||||
for (int i = 0; i < length; i++)
|
||||
q += sprintf(q, " %02X", data[i]);
|
||||
dsyslog(buffer);
|
||||
@ -1049,26 +1053,6 @@ cCaDescriptor::~cCaDescriptor()
|
||||
free(data);
|
||||
}
|
||||
|
||||
// --- cCaDescriptors --------------------------------------------------------
|
||||
|
||||
class cCaDescriptors : public cList<cCaDescriptor> {
|
||||
public:
|
||||
const cCaDescriptor *Get(int Source, int Transponder, int ServiceId, int CaSystem);
|
||||
};
|
||||
|
||||
const cCaDescriptor *cCaDescriptors::Get(int Source, int Transponder, int ServiceId, int CaSystem)
|
||||
{
|
||||
for (cCaDescriptor *ca = First(); ca; ca = Next(ca)) {
|
||||
if (ca->source == Source && ca->transponder == Transponder && ca->serviceId == ServiceId) {
|
||||
if (CaSystem == -1 || ca->caSystem == CaSystem)
|
||||
return ca;
|
||||
if (CaSystem < 0)
|
||||
CaSystem++;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// --- cSIProcessor ----------------------------------------------------------
|
||||
|
||||
#define MAX_FILTERS 20
|
||||
@ -1077,7 +1061,7 @@ const cCaDescriptor *cCaDescriptors::Get(int Source, int Transponder, int Servic
|
||||
int cSIProcessor::numSIProcessors = 0;
|
||||
cSchedules *cSIProcessor::schedules = NULL;
|
||||
cMutex cSIProcessor::schedulesMutex;
|
||||
cCaDescriptors *cSIProcessor::caDescriptors = NULL;
|
||||
cList<cCaDescriptor> cSIProcessor::caDescriptors;
|
||||
cMutex cSIProcessor::caDescriptorsMutex;
|
||||
const char *cSIProcessor::epgDataFileName = EPGDATAFILENAME;
|
||||
time_t cSIProcessor::lastDump = time(NULL);
|
||||
@ -1094,7 +1078,6 @@ cSIProcessor::cSIProcessor(const char *FileName)
|
||||
filters = NULL;
|
||||
if (!numSIProcessors++) { // the first one creates them
|
||||
schedules = new cSchedules;
|
||||
caDescriptors = new cCaDescriptors;
|
||||
}
|
||||
filters = (SIP_FILTER *)calloc(MAX_FILTERS, sizeof(SIP_FILTER));
|
||||
SetStatus(true);
|
||||
@ -1111,7 +1094,6 @@ cSIProcessor::~cSIProcessor()
|
||||
free(filters);
|
||||
if (!--numSIProcessors) { // the last one deletes them
|
||||
delete schedules;
|
||||
delete caDescriptors;
|
||||
}
|
||||
free(fileName);
|
||||
}
|
||||
@ -1176,12 +1158,9 @@ void cSIProcessor::SetStatus(bool On)
|
||||
AddFilter(0x00, 0x00); // PAT
|
||||
AddFilter(0x14, 0x70); // TDT
|
||||
AddFilter(0x14, 0x73); // TOT
|
||||
AddFilter(0x12, 0x4e); // event info, actual TS, present/following
|
||||
AddFilter(0x12, 0x4f); // event info, other TS, present/following
|
||||
AddFilter(0x12, 0x50); // event info, actual TS, schedule
|
||||
AddFilter(0x12, 0x60); // event info, other TS, schedule
|
||||
AddFilter(0x12, 0x51); // event info, actual TS, schedule for another 4 days
|
||||
AddFilter(0x12, 0x61); // event info, other TS, schedule for another 4 days
|
||||
AddFilter(0x12, 0x4e, 0xfe); // event info, actual(0x4e)/other(0x4f) TS, present/following
|
||||
AddFilter(0x12, 0x50, 0xfe); // event info, actual TS, schedule(0x50)/schedule for another 4 days(0x51)
|
||||
AddFilter(0x12, 0x60, 0xfe); // event info, other TS, schedule(0x60)/schedule for another 4 days(0x61)
|
||||
}
|
||||
}
|
||||
|
||||
@ -1351,7 +1330,7 @@ void cSIProcessor::Action()
|
||||
|
||||
/** Add a filter with packet identifier pid and
|
||||
table identifer tid */
|
||||
bool cSIProcessor::AddFilter(unsigned short pid, u_char tid)
|
||||
bool cSIProcessor::AddFilter(unsigned short pid, u_char tid, u_char mask)
|
||||
{
|
||||
dmx_sct_filter_params sctFilterParams;
|
||||
memset(&sctFilterParams, 0, sizeof(sctFilterParams));
|
||||
@ -1359,7 +1338,7 @@ bool cSIProcessor::AddFilter(unsigned short pid, u_char tid)
|
||||
sctFilterParams.timeout = 0;
|
||||
sctFilterParams.flags = DMX_IMMEDIATE_START;
|
||||
sctFilterParams.filter.filter[0] = tid;
|
||||
sctFilterParams.filter.mask[0] = 0xFF;
|
||||
sctFilterParams.filter.mask[0] = mask;
|
||||
|
||||
for (int a = 0; a < MAX_FILTERS; a++)
|
||||
{
|
||||
@ -1443,36 +1422,40 @@ void cSIProcessor::TriggerDump(void)
|
||||
lastDump = 0;
|
||||
}
|
||||
|
||||
void cSIProcessor::NewCaDescriptor(struct Descriptor *d, int ProgramID)
|
||||
void cSIProcessor::NewCaDescriptor(struct Descriptor *d, int ServiceId)
|
||||
{
|
||||
if (DescriptorTag(d) == DESCR_CA) {
|
||||
struct CaDescriptor *cd = (struct CaDescriptor *)d;
|
||||
if (!caDescriptors->Get(currentSource, currentTransponder, ProgramID, cd->CA_type)) {
|
||||
cMutexLock MutexLock(&caDescriptorsMutex);
|
||||
caDescriptors->Add(new cCaDescriptor(currentSource, currentTransponder, ProgramID, cd->CA_type, cd->CA_PID, cd->DataLength, cd->Data));
|
||||
}
|
||||
cMutexLock MutexLock(&caDescriptorsMutex);
|
||||
|
||||
for (cCaDescriptor *ca = caDescriptors.First(); ca; ca = caDescriptors.Next(ca)) {
|
||||
if (ca->source == currentSource && ca->transponder == currentTransponder && ca->serviceId == ServiceId && ca->caSystem == cd->CA_type && ca->providerId == cd->ProviderID && ca->caPid == cd->CA_PID)
|
||||
return;
|
||||
}
|
||||
caDescriptors.Add(new cCaDescriptor(currentSource, currentTransponder, ServiceId, cd->CA_type, cd->ProviderID, cd->CA_PID, cd->DataLength, cd->Data));
|
||||
//XXX update???
|
||||
}
|
||||
}
|
||||
|
||||
int cSIProcessor::GetCaDescriptors(int Source, int Transponder, int ServiceId, int BufSize, uchar *Data)
|
||||
int cSIProcessor::GetCaDescriptors(int Source, int Transponder, int ServiceId, const unsigned short *CaSystemIds, int BufSize, uchar *Data)
|
||||
{
|
||||
if (!CaSystemIds || !*CaSystemIds)
|
||||
return 0;
|
||||
if (BufSize > 0 && Data) {
|
||||
cMutexLock MutexLock(&caDescriptorsMutex);
|
||||
int length = 0;
|
||||
for (int i = -1; ; i--) {
|
||||
const cCaDescriptor *d = caDescriptors->Get(Source, Transponder, ServiceId, i);
|
||||
if (d) {
|
||||
if (length + d->Length() <= BufSize) {
|
||||
memcpy(Data + length, d->Data(), d->Length());
|
||||
length += d->Length();
|
||||
do {
|
||||
for (cCaDescriptor *d = caDescriptors.First(); d; d = caDescriptors.Next(d)) {
|
||||
if (d->source == Source && d->transponder == Transponder && d->serviceId == ServiceId && d->caSystem == *CaSystemIds) {
|
||||
if (length + d->Length() <= BufSize) {
|
||||
memcpy(Data + length, d->Data(), d->Length());
|
||||
length += d->Length();
|
||||
}
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
} while (*++CaSystemIds);
|
||||
return length;
|
||||
}
|
||||
return -1;
|
||||
|
14
eit.h
14
eit.h
@ -16,7 +16,7 @@
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* $Id: eit.h 1.25 2003/04/12 10:59:26 kls Exp $
|
||||
* $Id: eit.h 1.28 2003/04/21 13:22:06 kls Exp $
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef __EIT_H
|
||||
@ -135,14 +135,13 @@ typedef struct sip_filter {
|
||||
}SIP_FILTER;
|
||||
|
||||
class cCaDescriptor;
|
||||
class cCaDescriptors;
|
||||
|
||||
class cSIProcessor : public cThread {
|
||||
private:
|
||||
static int numSIProcessors;
|
||||
static cSchedules *schedules;
|
||||
static cMutex schedulesMutex;
|
||||
static cCaDescriptors *caDescriptors;
|
||||
static cList<cCaDescriptor> caDescriptors;
|
||||
static cMutex caDescriptorsMutex;
|
||||
static const char *epgDataFileName;
|
||||
static time_t lastDump;
|
||||
@ -155,10 +154,10 @@ private:
|
||||
char *fileName;
|
||||
bool active;
|
||||
void Action(void);
|
||||
bool AddFilter(unsigned short pid, u_char tid);
|
||||
bool AddFilter(unsigned short pid, u_char tid, u_char mask = 0xFF);
|
||||
bool DelFilter(unsigned short pid, u_char tid);
|
||||
bool ShutDownFilters(void);
|
||||
void NewCaDescriptor(struct Descriptor *d, int ProgramID);
|
||||
void NewCaDescriptor(struct Descriptor *d, int ServiceId);
|
||||
public:
|
||||
cSIProcessor(const char *FileName);
|
||||
~cSIProcessor();
|
||||
@ -168,10 +167,11 @@ public:
|
||||
// Caller must provide a cMutexLock which has to survive the entire
|
||||
// time the returned cSchedules is accessed. Once the cSchedules is no
|
||||
// longer used, the cMutexLock must be destroyed.
|
||||
static int GetCaDescriptors(int Source, int Transponder, int ServiceId, int BufSize, uchar *Data);
|
||||
static int GetCaDescriptors(int Source, int Transponder, int ServiceId, const unsigned short *CaSystemIds, int BufSize, uchar *Data);
|
||||
///< Gets all CA descriptors for a given channel.
|
||||
///< Copies all available CA descriptors for the given Source, Transponder and ServiceId
|
||||
///< into the provided buffer at Data (at most BufSize bytes).
|
||||
///< into the provided buffer at Data (at most BufSize bytes). Only those CA descriptors
|
||||
///< are copied that match one of the given CA system IDs.
|
||||
///< \return Returns the number of bytes copied into Data (0 if no CA descriptors are
|
||||
///< available), or -1 if BufSize was too small to hold all CA descriptors.
|
||||
static bool Read(FILE *f = NULL);
|
||||
|
18
i18n.c
18
i18n.c
@ -4,7 +4,7 @@
|
||||
* See the main source file 'vdr.c' for copyright information and
|
||||
* how to reach the author.
|
||||
*
|
||||
* $Id: i18n.c 1.105 2003/04/12 09:39:35 kls Exp $
|
||||
* $Id: i18n.c 1.106 2003/04/21 14:05:17 kls Exp $
|
||||
*
|
||||
* Translations provided by:
|
||||
*
|
||||
@ -3411,6 +3411,22 @@ const tI18nPhrase Phrases[] = {
|
||||
"Caut inregistrari...",
|
||||
"Felvett adások böngészése...",
|
||||
},
|
||||
{ "Pausing live video...",
|
||||
"Live-Signal wird angehalten...",
|
||||
"",// TODO
|
||||
"",// TODO
|
||||
"",// TODO
|
||||
"",// TODO
|
||||
"",// TODO
|
||||
"",// TODO
|
||||
"",// TODO
|
||||
"",// TODO
|
||||
"",// TODO
|
||||
"",// TODO
|
||||
"",// TODO
|
||||
"",// TODO
|
||||
"",// TODO
|
||||
},
|
||||
{ "This plugin has no setup parameters!",
|
||||
"Dieses Plugin hat keine Setup-Parameter!",
|
||||
"",// TODO
|
||||
|
31
menu.c
31
menu.c
@ -4,7 +4,7 @@
|
||||
* See the main source file 'vdr.c' for copyright information and
|
||||
* how to reach the author.
|
||||
*
|
||||
* $Id: menu.c 1.235 2003/04/12 09:40:48 kls Exp $
|
||||
* $Id: menu.c 1.237 2003/04/21 14:57:13 kls Exp $
|
||||
*/
|
||||
|
||||
#include "menu.h"
|
||||
@ -1636,7 +1636,7 @@ cOsdObject *CamControl(void)
|
||||
cDevice *Device = cDevice::GetDevice(d);
|
||||
if (Device) {
|
||||
cCiHandler *CiHandler = Device->CiHandler();
|
||||
if (CiHandler) {
|
||||
if (CiHandler && CiHandler->HasUserIO()) {
|
||||
cCiMenu *CiMenu = CiHandler->GetMenu();
|
||||
if (CiMenu)
|
||||
return new cMenuCam(CiMenu);
|
||||
@ -2488,7 +2488,7 @@ void cMenuMain::Set(const char *Plugin)
|
||||
|
||||
// Color buttons:
|
||||
|
||||
SetHelp(tr("Record"), cDevice::PrimaryDevice()->NumAudioTracks() > 1 ? tr("Language") : NULL, NULL, replaying ? tr("Button$Stop") : cReplayControl::LastReplayed() ? tr("Resume") : NULL);
|
||||
SetHelp(tr("Record"), cDevice::PrimaryDevice()->NumAudioTracks() > 1 ? tr("Language") : NULL, replaying ? NULL : tr("Pause"), replaying ? tr("Button$Stop") : cReplayControl::LastReplayed() ? tr("Resume") : NULL);
|
||||
Display();
|
||||
lastActivity = time(NULL);
|
||||
}
|
||||
@ -2560,6 +2560,9 @@ eOSState cMenuMain::ProcessKey(eKeys Key)
|
||||
}
|
||||
}
|
||||
break;
|
||||
case kYellow: if (!HasSubMenu())
|
||||
state = osPause;
|
||||
break;
|
||||
case kBlue: if (!HasSubMenu())
|
||||
state = replaying ? osStopReplay : cReplayControl::LastReplayed() ? osReplay : osContinue;
|
||||
break;
|
||||
@ -2936,6 +2939,8 @@ cRecordControl::cRecordControl(cDevice *Device, cTimer *Timer)
|
||||
if (device->AttachReceiver(recorder)) {
|
||||
Recording.WriteSummary();
|
||||
cStatus::MsgRecording(device, Recording.Name());
|
||||
if (!Timer && !cReplayControl::LastReplayed()) // an instant recording, maybe from cRecordControls::PauseLiveVideo()
|
||||
cReplayControl::SetRecording(fileName, Recording.Name());
|
||||
}
|
||||
else
|
||||
DELETENULL(recorder);
|
||||
@ -3073,6 +3078,26 @@ bool cRecordControls::StopPrimary(bool DoIt)
|
||||
return false;
|
||||
}
|
||||
|
||||
bool cRecordControls::PauseLiveVideo(void)
|
||||
{
|
||||
Interface->Open(Setup.OSDwidth, -1);
|
||||
Interface->Status(tr("Pausing live video..."));
|
||||
Interface->Flush();
|
||||
cReplayControl::SetRecording(NULL, NULL); // make sure the new cRecordControl will set cReplayControl::LastReplayed()
|
||||
if (Start()) {
|
||||
sleep(2); // allow recorded file to fill up enough to start replaying
|
||||
cReplayControl *rc = new cReplayControl;
|
||||
cControl::Launch(rc);
|
||||
cControl::Attach();
|
||||
sleep(1); // allow device to replay some frames, so we have a picture
|
||||
Interface->Close();
|
||||
rc->ProcessKey(kPause); // pause, allowing replay mode display
|
||||
return true;
|
||||
}
|
||||
Interface->Close();
|
||||
return false;
|
||||
}
|
||||
|
||||
const char *cRecordControls::GetInstantId(const char *LastInstantId)
|
||||
{
|
||||
for (int i = 0; i < MAXRECORDCONTROLS; i++) {
|
||||
|
3
menu.h
3
menu.h
@ -4,7 +4,7 @@
|
||||
* See the main source file 'vdr.c' for copyright information and
|
||||
* how to reach the author.
|
||||
*
|
||||
* $Id: menu.h 1.53 2003/01/12 14:54:05 kls Exp $
|
||||
* $Id: menu.h 1.54 2003/04/21 13:40:45 kls Exp $
|
||||
*/
|
||||
|
||||
#ifndef __MENU_H
|
||||
@ -135,6 +135,7 @@ public:
|
||||
static void Stop(const char *InstantId);
|
||||
static void Stop(cDevice *Device);
|
||||
static bool StopPrimary(bool DoIt = false);
|
||||
static bool PauseLiveVideo(void);
|
||||
static const char *GetInstantId(const char *LastInstantId);
|
||||
static cRecordControl *GetRecordControl(const char *FileName);
|
||||
static void Process(time_t t);
|
||||
|
3
osd.h
3
osd.h
@ -4,7 +4,7 @@
|
||||
* See the main source file 'vdr.c' for copyright information and
|
||||
* how to reach the author.
|
||||
*
|
||||
* $Id: osd.h 1.38 2002/12/08 12:21:26 kls Exp $
|
||||
* $Id: osd.h 1.39 2003/04/21 10:27:41 kls Exp $
|
||||
*/
|
||||
|
||||
#ifndef __OSD_H
|
||||
@ -30,6 +30,7 @@ enum eOSState { osUnknown,
|
||||
osPlugin,
|
||||
osSetup,
|
||||
osCommands,
|
||||
osPause,
|
||||
osRecord,
|
||||
osReplay,
|
||||
osStopRecord,
|
||||
|
35
vdr.c
35
vdr.c
@ -22,7 +22,7 @@
|
||||
*
|
||||
* The project's page is at http://www.cadsoft.de/people/kls/vdr
|
||||
*
|
||||
* $Id: vdr.c 1.149 2003/04/12 13:57:45 kls Exp $
|
||||
* $Id: vdr.c 1.150 2003/04/21 14:41:41 kls Exp $
|
||||
*/
|
||||
|
||||
#include <getopt.h>
|
||||
@ -553,6 +553,26 @@ int main(int argc, char *argv[])
|
||||
cDisplayVolume::Process(key);
|
||||
key = kNone; // nobody else needs to see these keys
|
||||
break;
|
||||
// Pausing live video:
|
||||
case kPause:
|
||||
if (!cControl::Control()) {
|
||||
DELETENULL(Menu);
|
||||
Temp = NULL;
|
||||
if (!cRecordControls::PauseLiveVideo())
|
||||
Interface->Error(tr("No free DVB device to record!"));
|
||||
key = kNone; // nobody else needs to see this key
|
||||
}
|
||||
break;
|
||||
// Instant recording:
|
||||
case kRecord:
|
||||
if (!cControl::Control()) {
|
||||
if (cRecordControls::Start())
|
||||
;//XXX Interface->Info(tr("Recording"));
|
||||
else
|
||||
Interface->Error(tr("No free DVB device to record!"));
|
||||
key = kNone; // nobody else needs to see this key
|
||||
}
|
||||
break;
|
||||
// Power off:
|
||||
case kPower: isyslog("Power button pressed");
|
||||
DELETENULL(Menu);
|
||||
@ -577,6 +597,12 @@ int main(int argc, char *argv[])
|
||||
if (state == osUnknown && ISMODELESSKEY(key) && cControl::Control() && Interact != cControl::Control())
|
||||
state = cControl::Control()->ProcessKey(key);
|
||||
switch (state) {
|
||||
case osPause: DELETENULL(Menu);
|
||||
cControl::Shutdown(); // just in case
|
||||
Temp = NULL;
|
||||
if (!cRecordControls::PauseLiveVideo())
|
||||
Interface->Error(tr("No free DVB device to record!"));
|
||||
break;
|
||||
case osRecord: DELETENULL(Menu);
|
||||
Temp = NULL;
|
||||
if (cRecordControls::Start())
|
||||
@ -652,13 +678,6 @@ int main(int argc, char *argv[])
|
||||
break;
|
||||
// Viewing Control:
|
||||
case kOk: LastChannel = -1; break; // forces channel display
|
||||
// Instant recording:
|
||||
case kRecord:
|
||||
if (cRecordControls::Start())
|
||||
;//XXX Interface->Info(tr("Recording"));
|
||||
else
|
||||
Interface->Error(tr("No free DVB device to record!"));
|
||||
break;
|
||||
// Key macros:
|
||||
case kRed:
|
||||
case kGreen:
|
||||
|
Loading…
x
Reference in New Issue
Block a user