mirror of
https://github.com/VDR4Arch/vdr.git
synced 2023-10-10 13:36:52 +02:00
Implemented audio track menu
This commit is contained in:
parent
286af66cfb
commit
0b3a801ab4
16
HISTORY
16
HISTORY
@ -3160,7 +3160,7 @@ Video Disk Recorder Revision History
|
||||
right day of week for timers in the future.
|
||||
- Some improvements to cPoller (thanks to Marco Schlüßler).
|
||||
|
||||
2004-12-26: Version 1.3.18
|
||||
2005-01-02: Version 1.3.18
|
||||
|
||||
- Removed an unused variable from cTimer::GetWDayFromMDay() (thanks to Wayne Keer
|
||||
for reporting this one).
|
||||
@ -3251,3 +3251,17 @@ Video Disk Recorder Revision History
|
||||
Zocholl for pointing out this problem).
|
||||
- Added cDevice::mutexReceiver to avoid a race condition when attaching/detaching
|
||||
receivers from different threads.
|
||||
- The new remote control button "Audio" can be used to switch between different
|
||||
audio tracks. The "Green" button in the "Main" menu has been changed from "Language"
|
||||
to "Audio", since it now also controls switching between normal and Dolby Digital
|
||||
audio tracks.
|
||||
- The description of the audio tracks is now taken from the "component descriptors"
|
||||
that are broadcast in the EPG data. However (as no big surprise), not all channels
|
||||
actually provide useful data here, so there are now some additional EPG bugfixes,
|
||||
which can be activated by setting the "EPG bugfix level" to 3.
|
||||
- The format of the 'epg.data' files has been extended by the new tag 'X', which
|
||||
contains the stream components of an event (see man vdr(5) for details).
|
||||
- The cStatus class now has the new member function SetAudioTrack(), which can be
|
||||
used to get notified when the audio track has been switched.
|
||||
- Skins need to implement the new cSkinDisplayTrack class to display the audio
|
||||
track menu.
|
||||
|
26
MANUAL
26
MANUAL
@ -21,7 +21,7 @@ Version 1.2
|
||||
Menu Menu on Menu off Menu off Menu off Menu off Menu off Menu on
|
||||
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
|
||||
Green - Audio New New Ins/Ovr Rewind Skip -60s
|
||||
Yellow - Pause live Delete Delete Delete Delete Skip +60s
|
||||
Blue - Stop/Resume Mark On/Off(1) - Summary Stop
|
||||
0..9 Ch select - Sort(3) Day(4) Numeric inp. Exec cmd(2) Editing
|
||||
@ -49,6 +49,8 @@ Version 1.2
|
||||
Volume- volume down
|
||||
Mute mute
|
||||
|
||||
Audio select audio track
|
||||
|
||||
Schedule \
|
||||
Channels |
|
||||
Timers | directly access the VDR
|
||||
@ -187,15 +189,16 @@ Version 1.2
|
||||
To bring up the channel display without switching channels you can press
|
||||
the "Ok" button.
|
||||
|
||||
* Selecting language specific audio track
|
||||
* Selecting audio tracks
|
||||
|
||||
If the current channel provides different audio tracks (typically for
|
||||
different languages), the "Green" button in the "VDR" menu can be pressed
|
||||
to toggle between these. There can be two different audio PIDs per channel,
|
||||
assuming that typically a channel broadcasts a country specific language
|
||||
plus the movie's original soundtrack.
|
||||
Recordings made form such channels will contain both audio tracks, and when
|
||||
replaying the desired audio track can be selected the same way.
|
||||
If the current channel or recording provides different audio tracks (for
|
||||
different languages or Dolby Digital), the "Green" button in the "VDR" menu can
|
||||
be pressed to bring up the "Audio" menu. Within this menu, the "Up" and "Down"
|
||||
keys can be used to switch between the audio tracks. If your remote control has
|
||||
a dedicated "Audio" button, the first press of that button brings up the "Audio"
|
||||
menu, and every further press switches to the next available audio track.
|
||||
The "Audio" menu will automatically disappear after 5 seconds of user inactivity,
|
||||
or if any key other than the ones described above is pressed.
|
||||
|
||||
* Switching through channel groups
|
||||
|
||||
@ -495,14 +498,15 @@ Version 1.2
|
||||
A value of '0' completely turns off scanning on both single
|
||||
and multiple card systems.
|
||||
|
||||
EPG bugfix level = 2 Some tv stations transmit weirdly formatted EPG data.
|
||||
EPG bugfix level = 3 Some tv stations transmit weirdly formatted EPG data.
|
||||
VDR attempts to fix these bugs up to the given level:
|
||||
0 = no EPG fixing
|
||||
1 = basic fixing of text location (Title, Episode and
|
||||
Extended Description)
|
||||
2 = removal of excess whitespace and hyphens, mapping of
|
||||
wrongly used characters
|
||||
Default is '2'.
|
||||
3 = fix stream component descriptions
|
||||
Default is '3'.
|
||||
Note that after changing the setting of this parameter
|
||||
any EPG data that has already been received will remain
|
||||
in its existing format - only newly received data will
|
||||
|
@ -1362,6 +1362,9 @@ public:
|
||||
virtual cSkinDisplayMenu *DisplayMenu(void);
|
||||
virtual cSkinDisplayReplay *DisplayReplay(bool ModeOnly);
|
||||
virtual cSkinDisplayVolume *DisplayVolume(void);
|
||||
<!--X1.3.18--><table width=100%><tr><td bgcolor=#FF0000> </td><td width=100%>
|
||||
virtual cSkinDisplayMessage *DisplayTrack(int NumTracks, const char * const *Tracks);
|
||||
<!--X1.3.18--></td></tr></table>
|
||||
virtual cSkinDisplayMessage *DisplayMessage(void);
|
||||
};
|
||||
</pre></td></tr></table><p>
|
||||
|
@ -9,6 +9,7 @@ VDR Plugin 'skincurses' Revision History
|
||||
|
||||
- Fixed some default parameters.
|
||||
|
||||
2004-12-26: Version 0.0.3
|
||||
2005-01-02: Version 0.0.3
|
||||
|
||||
- Made several functions threadsafe.
|
||||
- New audio track display.
|
||||
|
@ -3,7 +3,7 @@
|
||||
*
|
||||
* See the README file for copyright information and how to reach the author.
|
||||
*
|
||||
* $Id: skincurses.c 1.3 2004/12/26 11:36:35 kls Exp $
|
||||
* $Id: skincurses.c 1.4 2005/01/02 15:11:29 kls Exp $
|
||||
*/
|
||||
|
||||
#include <ncurses.h>
|
||||
@ -558,6 +558,68 @@ void cSkinCursesDisplayVolume::Flush(void)
|
||||
osd->Flush();
|
||||
}
|
||||
|
||||
// --- cSkinCursesDisplayTracks ----------------------------------------------
|
||||
|
||||
class cSkinCursesDisplayTracks : public cSkinDisplayTracks {
|
||||
private:
|
||||
cOsd *osd;
|
||||
int itemsWidth;
|
||||
int currentIndex;
|
||||
void SetItem(const char *Text, int Index, bool Current);
|
||||
public:
|
||||
cSkinCursesDisplayTracks(const char *Title, int NumTracks, const char * const *Tracks);
|
||||
virtual ~cSkinCursesDisplayTracks();
|
||||
virtual void SetTrack(int Index, const char * const *Tracks);
|
||||
virtual void Flush(void);
|
||||
};
|
||||
|
||||
cSkinCursesDisplayTracks::cSkinCursesDisplayTracks(const char *Title, int NumTracks, const char * const *Tracks)
|
||||
{
|
||||
currentIndex = -1;
|
||||
itemsWidth = Font.Width(Title);
|
||||
for (int i = 0; i < NumTracks; i++)
|
||||
itemsWidth = max(itemsWidth, Font.Width(Tracks[i]));
|
||||
itemsWidth = min(itemsWidth, OsdWidth);
|
||||
osd = new cCursesOsd(0, 0);
|
||||
osd->DrawRectangle(0, 0, OsdWidth - 1, OsdHeight - 1, clrBackground);
|
||||
osd->DrawText(0, 0, Title, clrBlack, clrCyan, &Font, itemsWidth);
|
||||
for (int i = 0; i < NumTracks; i++)
|
||||
SetItem(Tracks[i], i, false);
|
||||
}
|
||||
|
||||
cSkinCursesDisplayTracks::~cSkinCursesDisplayTracks()
|
||||
{
|
||||
delete osd;
|
||||
}
|
||||
|
||||
void cSkinCursesDisplayTracks::SetItem(const char *Text, int Index, bool Current)
|
||||
{
|
||||
int y = 1 + Index;
|
||||
int ColorFg, ColorBg;
|
||||
if (Current) {
|
||||
ColorFg = clrBlack;
|
||||
ColorBg = clrCyan;
|
||||
currentIndex = Index;
|
||||
}
|
||||
else {
|
||||
ColorFg = clrWhite;
|
||||
ColorBg = clrBackground;
|
||||
}
|
||||
osd->DrawText(0, y, Text, ColorFg, ColorBg, &Font, itemsWidth);
|
||||
}
|
||||
|
||||
void cSkinCursesDisplayTracks::SetTrack(int Index, const char * const *Tracks)
|
||||
{
|
||||
if (currentIndex >= 0)
|
||||
SetItem(Tracks[currentIndex], currentIndex, false);
|
||||
SetItem(Tracks[Index], Index, true);
|
||||
}
|
||||
|
||||
void cSkinCursesDisplayTracks::Flush(void)
|
||||
{
|
||||
osd->Flush();
|
||||
}
|
||||
|
||||
// --- cSkinCursesDisplayMessage ---------------------------------------------
|
||||
|
||||
class cSkinCursesDisplayMessage : public cSkinDisplayMessage {
|
||||
@ -600,6 +662,7 @@ public:
|
||||
virtual cSkinDisplayMenu *DisplayMenu(void);
|
||||
virtual cSkinDisplayReplay *DisplayReplay(bool ModeOnly);
|
||||
virtual cSkinDisplayVolume *DisplayVolume(void);
|
||||
virtual cSkinDisplayTracks *DisplayTracks(const char *Title, int NumTracks, const char * const *Tracks);
|
||||
virtual cSkinDisplayMessage *DisplayMessage(void);
|
||||
};
|
||||
|
||||
@ -633,6 +696,11 @@ cSkinDisplayVolume *cSkinCurses::DisplayVolume(void)
|
||||
return new cSkinCursesDisplayVolume;
|
||||
}
|
||||
|
||||
cSkinDisplayTracks *cSkinCurses::DisplayTracks(const char *Title, int NumTracks, const char * const *Tracks)
|
||||
{
|
||||
return new cSkinCursesDisplayTracks(Title, NumTracks, Tracks);
|
||||
}
|
||||
|
||||
cSkinDisplayMessage *cSkinCurses::DisplayMessage(void)
|
||||
{
|
||||
return new cSkinCursesDisplayMessage;
|
||||
|
23
device.c
23
device.c
@ -4,7 +4,7 @@
|
||||
* See the main source file 'vdr.c' for copyright information and
|
||||
* how to reach the author.
|
||||
*
|
||||
* $Id: device.c 1.64 2004/12/24 15:37:11 kls Exp $
|
||||
* $Id: device.c 1.65 2005/01/02 14:08:40 kls Exp $
|
||||
*/
|
||||
|
||||
#include "device.h"
|
||||
@ -604,15 +604,19 @@ void cDevice::ClrAvailableTracks(void)
|
||||
memset(availableTracks, 0, sizeof(availableTracks));
|
||||
}
|
||||
|
||||
bool cDevice::SetAvailableTrack(eTrackType Type, int Index, uint16_t Id, const char *Language, uint32_t Flags)
|
||||
bool cDevice::SetAvailableTrack(eTrackType Type, int Index, uint16_t Id, const char *Language, const char *Description, uint32_t Flags)
|
||||
{
|
||||
eTrackType t = eTrackType(Type + Index);
|
||||
if ((Type == ttAudio && IS_AUDIO_TRACK(t)) ||
|
||||
(Type == ttDolby && IS_DOLBY_TRACK(t))) {
|
||||
if (Language)
|
||||
strn0cpy(availableTracks[t].language, Language, sizeof(availableTracks[t].language));
|
||||
if (Description)
|
||||
strn0cpy(availableTracks[t].description, Description, sizeof(availableTracks[t].description));
|
||||
if (Id) {
|
||||
availableTracks[t].flags = Flags;
|
||||
availableTracks[t].id = Id; // setting 'id' last to avoid the need for extensive locking
|
||||
}
|
||||
return true;
|
||||
}
|
||||
else
|
||||
@ -652,21 +656,6 @@ bool cDevice::SetCurrentAudioTrack(eTrackType Type)
|
||||
return false;
|
||||
}
|
||||
|
||||
bool cDevice::IncCurrentAudioTrack(void)
|
||||
{
|
||||
int i = currentAudioTrack + 1;
|
||||
for (;;) {
|
||||
if (i > ttDolbyLast)
|
||||
i = ttAudioFirst;
|
||||
if (i == currentAudioTrack)
|
||||
break;
|
||||
if (availableTracks[i].id)
|
||||
return SetCurrentAudioTrack(eTrackType(i));
|
||||
i++;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool cDevice::CanReplay(void) const
|
||||
{
|
||||
return HasDecoder();
|
||||
|
11
device.h
11
device.h
@ -4,7 +4,7 @@
|
||||
* See the main source file 'vdr.c' for copyright information and
|
||||
* how to reach the author.
|
||||
*
|
||||
* $Id: device.h 1.48 2004/12/24 14:57:24 kls Exp $
|
||||
* $Id: device.h 1.49 2005/01/02 14:08:36 kls Exp $
|
||||
*/
|
||||
|
||||
#ifndef __DEVICE_H
|
||||
@ -77,6 +77,7 @@ enum eTrackType { ttNone,
|
||||
struct tTrackId {
|
||||
uint16_t id; // The PES packet id or the PID.
|
||||
char language[8]; // something like either "eng" or "deu/eng"
|
||||
char description[32]; // something like "Dolby Digital 5.1"
|
||||
// for future use:
|
||||
uint32_t flags; // Used to further identify the actual track.
|
||||
};
|
||||
@ -319,10 +320,12 @@ protected:
|
||||
///< Sets the current audio track to the given value.
|
||||
public:
|
||||
void ClrAvailableTracks(void);
|
||||
bool SetAvailableTrack(eTrackType Type, int Index, uint16_t Id, const char *Language = NULL, uint32_t Flags = 0);
|
||||
bool SetAvailableTrack(eTrackType Type, int Index, uint16_t Id, const char *Language = NULL, const char *Description = NULL, uint32_t Flags = 0);
|
||||
///< Sets the track of the given Type and Index to the given values.
|
||||
///< Type must be one of the basic eTrackType values, like ttAudio or ttDolby.
|
||||
///< Index tells which track of the given basic type is meant.
|
||||
///< If Id is 0 any existing id (and flags) will be left untouched and only the
|
||||
///< given Language and Description will be set.
|
||||
///< \return Returns true if the track was set correctly, false otherwise.
|
||||
const tTrackId *GetTrack(eTrackType Type);
|
||||
///< Returns a pointer to the given track id, or NULL if Type is not
|
||||
@ -335,10 +338,6 @@ public:
|
||||
bool SetCurrentAudioTrack(eTrackType Type);
|
||||
///< Sets the current audio track to the given Type.
|
||||
///< \return Returns true if Type is a valid audio track, false otherwise.
|
||||
bool IncCurrentAudioTrack(void);
|
||||
///< Sets the current audio track to the next available track (wraps to
|
||||
///< to the first one if necessary).
|
||||
///< \return Returns true if the audio track has been changed, false otherwise.
|
||||
|
||||
// Audio facilities
|
||||
|
||||
|
@ -4,7 +4,7 @@
|
||||
* See the main source file 'vdr.c' for copyright information and
|
||||
* how to reach the author.
|
||||
*
|
||||
* $Id: dvbdevice.c 1.107 2004/12/17 14:19:48 kls Exp $
|
||||
* $Id: dvbdevice.c 1.108 2005/01/02 11:51:18 kls Exp $
|
||||
*/
|
||||
|
||||
#include "dvbdevice.h"
|
||||
@ -860,10 +860,8 @@ void cDvbDevice::SetAudioTrackDevice(eTrackType Type)
|
||||
else if (IS_DOLBY_TRACK(Type)) {
|
||||
// Currently this works only in Transfer Mode
|
||||
cChannel *Channel = Channels.GetByNumber(CurrentChannel());
|
||||
if (Channel) {
|
||||
SetChannelDevice(Channel, false);
|
||||
cControl::Launch(new cTransferControl(this, Channel->Vpid(), Channel->Apid(0), Channel->Apid(1), Channel->Dpid(0), Channel->Dpid(1)));
|
||||
}
|
||||
if (Channel)
|
||||
SetChannelDevice(Channel, false); // this implicitly starts Transfer Mode
|
||||
}
|
||||
}
|
||||
}
|
||||
|
32
eit.c
32
eit.c
@ -8,7 +8,7 @@
|
||||
* Robert Schneider <Robert.Schneider@web.de> and Rolf Hakenes <hakenes@hippomi.de>.
|
||||
* Adapted to 'libsi' for VDR 1.3.0 by Marcel Wiesweg <marcel.wiesweg@gmx.de>.
|
||||
*
|
||||
* $Id: eit.c 1.101 2004/12/26 10:38:46 kls Exp $
|
||||
* $Id: eit.c 1.102 2005/01/02 11:52:12 kls Exp $
|
||||
*/
|
||||
|
||||
#include "eit.h"
|
||||
@ -91,6 +91,8 @@ cEIT::cEIT(cSchedules *Schedules, int Source, u_char Tid, const u_char *Data)
|
||||
SI::ExtendedEventDescriptors *ExtendedEventDescriptors = NULL;
|
||||
SI::ShortEventDescriptor *ShortEventDescriptor = NULL;
|
||||
cLinkChannels *LinkChannels = NULL;
|
||||
int NumComponents = 0;
|
||||
SI::ComponentDescriptor *ComponentDescriptors[MAXCOMPONENTS];
|
||||
for (SI::Loop::Iterator it2; (d = SiEitEvent.eventDescriptors.getNext(it2)); ) {
|
||||
switch (d->getDescriptorTag()) {
|
||||
case SI::ExtendedEventDescriptorTag: {
|
||||
@ -186,6 +188,20 @@ cEIT::cEIT(cSchedules *Schedules, int Source, u_char Tid, const u_char *Data)
|
||||
}
|
||||
}
|
||||
break;
|
||||
case SI::ComponentDescriptorTag: {
|
||||
SI::ComponentDescriptor *cd = (SI::ComponentDescriptor *)d;
|
||||
uchar Stream = cd->getStreamContent();
|
||||
uchar Type = cd->getComponentType();
|
||||
if (1 <= Stream && Stream <= 2 && Type != 0) {
|
||||
if (NumComponents < MAXCOMPONENTS) {
|
||||
ComponentDescriptors[NumComponents++] = cd;
|
||||
d = NULL; // so that it is not deleted
|
||||
}
|
||||
else
|
||||
dsyslog("more than %d component descriptors!", MAXCOMPONENTS);
|
||||
}
|
||||
}
|
||||
break;
|
||||
default: ;
|
||||
}
|
||||
delete d;
|
||||
@ -205,8 +221,20 @@ cEIT::cEIT(cSchedules *Schedules, int Source, u_char Tid, const u_char *Data)
|
||||
delete ExtendedEventDescriptors;
|
||||
delete ShortEventDescriptor;
|
||||
|
||||
pEvent->FixEpgBugs();
|
||||
if (NumComponents > 0) {
|
||||
cComponents *Components = new cComponents(NumComponents);
|
||||
for (int i = 0; i < NumComponents; i++) {
|
||||
char buffer[256];
|
||||
SI::ComponentDescriptor *cd = ComponentDescriptors[i];
|
||||
Components->SetComponent(i, cd->getStreamContent(), cd->getComponentType(), I18nNormalizeLanguageCode(cd->languageCode), cd->description.getText(buffer, sizeof(buffer)));
|
||||
delete cd;
|
||||
}
|
||||
pEvent->SetComponents(Components);
|
||||
}
|
||||
else
|
||||
pEvent->SetComponents(NULL);
|
||||
|
||||
pEvent->FixEpgBugs();
|
||||
if (LinkChannels)
|
||||
channel->SetLinkChannels(LinkChannels);
|
||||
if (Tid == 0x4E) { // we trust only the present/following info on the actual TS
|
||||
|
165
epg.c
165
epg.c
@ -7,7 +7,7 @@
|
||||
* Original version (as used in VDR before 1.3.0) written by
|
||||
* Robert Schneider <Robert.Schneider@web.de> and Rolf Hakenes <hakenes@hippomi.de>.
|
||||
*
|
||||
* $Id: epg.c 1.23 2004/12/26 11:32:01 kls Exp $
|
||||
* $Id: epg.c 1.24 2005/01/02 11:25:25 kls Exp $
|
||||
*/
|
||||
|
||||
#include "epg.h"
|
||||
@ -16,6 +16,66 @@
|
||||
#include <ctype.h>
|
||||
#include <time.h>
|
||||
|
||||
// --- tComponent ------------------------------------------------------------
|
||||
|
||||
cString tComponent::ToString(void)
|
||||
{
|
||||
char buffer[256];
|
||||
snprintf(buffer, sizeof(buffer), "%X %02X %-3s %s", stream, type, language, description ? description : "");
|
||||
return buffer;
|
||||
}
|
||||
|
||||
bool tComponent::FromString(const char *s)
|
||||
{
|
||||
unsigned int Stream, Type;
|
||||
int n = sscanf(s, "%X %02X %3c %a[^\n]", &Stream, &Type, language, &description);
|
||||
if (n != 4)
|
||||
description = NULL;
|
||||
else if (isempty(description)) {
|
||||
free(description);
|
||||
description = NULL;
|
||||
}
|
||||
stream = Stream;
|
||||
type = Type;
|
||||
return n >= 3;
|
||||
}
|
||||
|
||||
// --- cComponents -----------------------------------------------------------
|
||||
|
||||
cComponents::cComponents(int NumComponents)
|
||||
{
|
||||
numComponents = NumComponents;
|
||||
components = MALLOC(tComponent, numComponents);
|
||||
memset(components, 0, sizeof(tComponent) * numComponents);
|
||||
}
|
||||
|
||||
cComponents::~cComponents(void)
|
||||
{
|
||||
for (int i = 0; i < numComponents; i++)
|
||||
free(components[i].description);
|
||||
free(components);
|
||||
}
|
||||
|
||||
bool cComponents::SetComponent(int Index, const char *s)
|
||||
{
|
||||
if (Index < numComponents)
|
||||
return components[Index].FromString(s);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool cComponents::SetComponent(int Index, uchar Stream, uchar Type, const char *Language, const char *Description)
|
||||
{
|
||||
if (Index < numComponents) {
|
||||
tComponent *p = &components[Index];
|
||||
p->stream = Stream;
|
||||
p->type = Type;
|
||||
strn0cpy(p->language, Language, sizeof(p->language));
|
||||
p->description = strcpyrealloc(p->description, !isempty(Description) ? Description : NULL);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// --- cEvent ----------------------------------------------------------------
|
||||
|
||||
cEvent::cEvent(tChannelID ChannelID, u_int16_t EventID)
|
||||
@ -28,6 +88,7 @@ cEvent::cEvent(tChannelID ChannelID, u_int16_t EventID)
|
||||
title = NULL;
|
||||
shortText = NULL;
|
||||
description = NULL;
|
||||
components = NULL;
|
||||
startTime = 0;
|
||||
duration = 0;
|
||||
vps = 0;
|
||||
@ -39,6 +100,7 @@ cEvent::~cEvent()
|
||||
free(title);
|
||||
free(shortText);
|
||||
free(description);
|
||||
delete components;
|
||||
}
|
||||
|
||||
int cEvent::Compare(const cListObject &ListObject) const
|
||||
@ -85,6 +147,12 @@ void cEvent::SetDescription(const char *Description)
|
||||
description = strcpyrealloc(description, Description);
|
||||
}
|
||||
|
||||
void cEvent::SetComponents(cComponents *Components)
|
||||
{
|
||||
delete components;
|
||||
components = Components;
|
||||
}
|
||||
|
||||
void cEvent::SetStartTime(time_t StartTime)
|
||||
{
|
||||
startTime = StartTime;
|
||||
@ -168,6 +236,12 @@ void cEvent::Dump(FILE *f, const char *Prefix) const
|
||||
fprintf(f, "%sD %s\n", Prefix, description);
|
||||
strreplace(description, '|', '\n');
|
||||
}
|
||||
if (components) {
|
||||
for (int i = 0; i < components->NumComponents(); i++) {
|
||||
tComponent *p = components->Component(i);
|
||||
fprintf(f, "%sX %s\n", Prefix, *p->ToString());
|
||||
}
|
||||
}
|
||||
if (vps)
|
||||
fprintf(f, "%sV %ld\n", Prefix, vps);
|
||||
fprintf(f, "%se\n", Prefix);
|
||||
@ -178,6 +252,8 @@ bool cEvent::Read(FILE *f, cSchedule *Schedule)
|
||||
{
|
||||
if (Schedule) {
|
||||
cEvent *Event = NULL;
|
||||
int NumComponents = 0;
|
||||
char *ComponentStrings[MAXCOMPONENTS];
|
||||
char *s;
|
||||
cReadLine ReadLine;
|
||||
while ((s = ReadLine.Read(f)) != NULL) {
|
||||
@ -199,6 +275,7 @@ bool cEvent::Read(FILE *f, cSchedule *Schedule)
|
||||
Event->SetDuration(Duration);
|
||||
}
|
||||
}
|
||||
NumComponents = 0;
|
||||
}
|
||||
break;
|
||||
case 'T': if (Event)
|
||||
@ -212,10 +289,26 @@ bool cEvent::Read(FILE *f, cSchedule *Schedule)
|
||||
Event->SetDescription(t);
|
||||
}
|
||||
break;
|
||||
case 'X': if (Event) {
|
||||
if (NumComponents < MAXCOMPONENTS)
|
||||
ComponentStrings[NumComponents++] = strdup(t);
|
||||
else
|
||||
dsyslog("more than %d component descriptors!", MAXCOMPONENTS);
|
||||
}
|
||||
break;
|
||||
case 'V': if (Event)
|
||||
Event->SetVps(atoi(t));
|
||||
break;
|
||||
case 'e': Event = NULL;
|
||||
case 'e': if (Event && NumComponents > 0) {
|
||||
cComponents *Components = new cComponents(NumComponents);
|
||||
for (int i = 0; i < NumComponents; i++) {
|
||||
if (!Components->SetComponent(i, ComponentStrings[i]))
|
||||
esyslog("ERROR: faulty component string in EPG data: '%s'", ComponentStrings[i]);
|
||||
free(ComponentStrings[i]);
|
||||
}
|
||||
Event->SetComponents(Components);
|
||||
}
|
||||
Event = NULL;
|
||||
break;
|
||||
case 'c': // to keep things simple we react on 'c' here
|
||||
return true;
|
||||
@ -228,7 +321,7 @@ bool cEvent::Read(FILE *f, cSchedule *Schedule)
|
||||
return false;
|
||||
}
|
||||
|
||||
#define MAXEPGBUGFIXSTATS 8
|
||||
#define MAXEPGBUGFIXSTATS 12
|
||||
#define MAXEPGBUGFIXCHANS 100
|
||||
struct tEpgBugFixStats {
|
||||
int hits;
|
||||
@ -476,6 +569,72 @@ void cEvent::FixEpgBugs(void)
|
||||
strreplace(title, '`', '\'');
|
||||
strreplace(shortText, '`', '\'');
|
||||
strreplace(description, '`', '\'');
|
||||
|
||||
if (Setup.EPGBugfixLevel <= 2)
|
||||
return;
|
||||
|
||||
// The stream components have a "description" field which some channels
|
||||
// apparently have no idea of how to set correctly:
|
||||
if (components) {
|
||||
for (int i = 0; i < components->NumComponents(); i++) {
|
||||
tComponent *p = components->Component(i);
|
||||
switch (p->stream) {
|
||||
case 0x01: { // video
|
||||
if (p->description) {
|
||||
if (strcasecmp(p->description, "Video") == 0 ||
|
||||
strcasecmp(p->description, "Bildformat") == 0) {
|
||||
// Yes, we know it's video - that's what the 'stream' code
|
||||
// is for! But _which_ video is it?
|
||||
free(p->description);
|
||||
p->description = NULL;
|
||||
EpgBugFixStat(8, ChannelID());
|
||||
}
|
||||
}
|
||||
if (!p->description) {
|
||||
switch (p->type) {
|
||||
case 0x01:
|
||||
case 0x05: p->description = strdup("4:3"); break;
|
||||
case 0x02:
|
||||
case 0x03:
|
||||
case 0x06:
|
||||
case 0x07: p->description = strdup("16:9"); break;
|
||||
case 0x04:
|
||||
case 0x08: p->description = strdup(">16:9"); break;
|
||||
case 0x09:
|
||||
case 0x0D: p->description = strdup("HD 4:3"); break;
|
||||
case 0x0A:
|
||||
case 0x0B:
|
||||
case 0x0E:
|
||||
case 0x0F: p->description = strdup("HD 16:9"); break;
|
||||
case 0x0C:
|
||||
case 0x10: p->description = strdup("HD >16:9"); break;
|
||||
}
|
||||
EpgBugFixStat(9, ChannelID());
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 0x02: { // audio
|
||||
if (p->description) {
|
||||
if (strcasecmp(p->description, "Audio") == 0) {
|
||||
// Yes, we know it's audio - that's what the 'stream' code
|
||||
// is for! But _which_ audio is it?
|
||||
free(p->description);
|
||||
p->description = NULL;
|
||||
EpgBugFixStat(10, ChannelID());
|
||||
}
|
||||
}
|
||||
if (!p->description) {
|
||||
switch (p->type) {
|
||||
case 0x05: p->description = strdup("Dolby Digital"); break;
|
||||
// all others will just display the language
|
||||
}
|
||||
EpgBugFixStat(11, ChannelID());
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
30
epg.h
30
epg.h
@ -7,7 +7,7 @@
|
||||
* Original version (as used in VDR before 1.3.0) written by
|
||||
* Robert Schneider <Robert.Schneider@web.de> and Rolf Hakenes <hakenes@hippomi.de>.
|
||||
*
|
||||
* $Id: epg.h 1.18 2004/12/26 11:31:27 kls Exp $
|
||||
* $Id: epg.h 1.19 2005/01/02 10:44:41 kls Exp $
|
||||
*/
|
||||
|
||||
#ifndef __EPG_H
|
||||
@ -17,10 +17,33 @@
|
||||
#include "thread.h"
|
||||
#include "tools.h"
|
||||
|
||||
#define MAXEPGBUGFIXLEVEL 2
|
||||
#define MAXEPGBUGFIXLEVEL 3
|
||||
#define MAXCOMPONENTS 32
|
||||
|
||||
enum eDumpMode { dmAll, dmPresent, dmFollowing, dmAtTime };
|
||||
|
||||
struct tComponent {
|
||||
uchar stream;
|
||||
uchar type;
|
||||
char language[4];
|
||||
char *description;
|
||||
cString ToString(void);
|
||||
bool FromString(const char *s);
|
||||
};
|
||||
|
||||
class cComponents {
|
||||
private:
|
||||
int numComponents;
|
||||
tComponent *components;
|
||||
public:
|
||||
cComponents(int NumComponents);
|
||||
~cComponents(void);
|
||||
int NumComponents(void) const { return numComponents; }
|
||||
bool SetComponent(int Index, const char *s);
|
||||
bool SetComponent(int Index, uchar Stream, uchar Type, const char *Language, const char *Description);
|
||||
tComponent *Component(int Index) const { return (Index < numComponents) ? &components[Index] : NULL; }
|
||||
};
|
||||
|
||||
class cSchedule;
|
||||
|
||||
class cEvent : public cListObject {
|
||||
@ -33,6 +56,7 @@ private:
|
||||
char *title; // Title of this event
|
||||
char *shortText; // Short description of this event (typically the episode name in case of a series)
|
||||
char *description; // Description of this event
|
||||
cComponents *components; // The stream components of this event (separated by '\n')
|
||||
time_t startTime; // Start time of this event
|
||||
int duration; // Duration of this event in seconds
|
||||
time_t vps; // Video Programming Service timestamp (VPS, aka "Programme Identification Label", PIL)
|
||||
@ -49,6 +73,7 @@ public:
|
||||
const char *Title(void) const { return title; }
|
||||
const char *ShortText(void) const { return shortText; }
|
||||
const char *Description(void) const { return description; }
|
||||
const cComponents *Components(void) const { return components; }
|
||||
time_t StartTime(void) const { return startTime; }
|
||||
time_t EndTime(void) const { return startTime + duration; }
|
||||
int Duration(void) const { return duration; }
|
||||
@ -67,6 +92,7 @@ public:
|
||||
void SetTitle(const char *Title);
|
||||
void SetShortText(const char *ShortText);
|
||||
void SetDescription(const char *Description);
|
||||
void SetComponents(cComponents *Components); // Will take ownership of Components!
|
||||
void SetStartTime(time_t StartTime);
|
||||
void SetDuration(int Duration);
|
||||
void SetVps(time_t Vps);
|
||||
|
23
i18n.c
23
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.166 2004/12/18 16:44:24 kls Exp $
|
||||
* $Id: i18n.c 1.167 2004/12/27 11:10:42 kls Exp $
|
||||
*
|
||||
* Translations provided by:
|
||||
*
|
||||
@ -4610,6 +4610,27 @@ const tI18nPhrase Phrases[] = {
|
||||
"Hääletu",
|
||||
"Sluk lyd",
|
||||
},
|
||||
{ "Audio",
|
||||
"Audio",
|
||||
"",// TODO
|
||||
"",// TODO
|
||||
"",// TODO
|
||||
"",// TODO
|
||||
"",// TODO
|
||||
"",// TODO
|
||||
"",// TODO
|
||||
"",// TODO
|
||||
"",// TODO
|
||||
"",// TODO
|
||||
"",// TODO
|
||||
"",// TODO
|
||||
"",// TODO
|
||||
"",// TODO
|
||||
"",// TODO
|
||||
"",// TODO
|
||||
"",// TODO
|
||||
"",// TODO
|
||||
},
|
||||
// Miscellaneous:
|
||||
{ "yes",
|
||||
"ja",
|
||||
|
3
keys.c
3
keys.c
@ -4,7 +4,7 @@
|
||||
* See the main source file 'vdr.c' for copyright information and
|
||||
* how to reach the author.
|
||||
*
|
||||
* $Id: keys.c 1.6 2004/12/19 11:25:47 kls Exp $
|
||||
* $Id: keys.c 1.7 2004/12/27 11:08:34 kls Exp $
|
||||
*/
|
||||
|
||||
#include "keys.h"
|
||||
@ -44,6 +44,7 @@ static tKey keyTable[] = { // "Up" and "Down" must be the first two keys!
|
||||
{ kVolUp, "Volume+" },
|
||||
{ kVolDn, "Volume-" },
|
||||
{ kMute, "Mute" },
|
||||
{ kAudio, "Audio" },
|
||||
{ kSchedule, "Schedule" },
|
||||
{ kChannels, "Channels" },
|
||||
{ kTimers, "Timers" },
|
||||
|
3
keys.h
3
keys.h
@ -4,7 +4,7 @@
|
||||
* See the main source file 'vdr.c' for copyright information and
|
||||
* how to reach the author.
|
||||
*
|
||||
* $Id: keys.h 1.5 2002/12/14 15:49:42 kls Exp $
|
||||
* $Id: keys.h 1.6 2004/12/27 11:10:59 kls Exp $
|
||||
*/
|
||||
|
||||
#ifndef __KEYS_H
|
||||
@ -38,6 +38,7 @@ enum eKeys { // "Up" and "Down" must be the first two keys!
|
||||
kVolUp,
|
||||
kVolDn,
|
||||
kMute,
|
||||
kAudio,
|
||||
kSchedule,
|
||||
kChannels,
|
||||
kTimers,
|
||||
|
124
menu.c
124
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.323 2004/12/26 12:18:29 kls Exp $
|
||||
* $Id: menu.c 1.324 2005/01/02 15:03:53 kls Exp $
|
||||
*/
|
||||
|
||||
#include "menu.h"
|
||||
@ -2410,7 +2410,7 @@ void cMenuMain::Set(const char *Plugin)
|
||||
|
||||
// Color buttons:
|
||||
|
||||
SetHelp(!replaying ? tr("Record") : NULL, cDevice::PrimaryDevice()->NumAudioTracks() > 1 ? tr("Language") : NULL, replaying ? NULL : tr("Pause"), replaying ? tr("Button$Stop") : cReplayControl::LastReplayed() ? tr("Resume") : NULL);
|
||||
SetHelp(!replaying ? tr("Record") : NULL, cDevice::PrimaryDevice()->NumAudioTracks() > 1 ? tr("Audio") : NULL, replaying ? NULL : tr("Pause"), replaying ? tr("Button$Stop") : cReplayControl::LastReplayed() ? tr("Resume") : NULL);
|
||||
Display();
|
||||
lastActivity = time(NULL);
|
||||
}
|
||||
@ -2471,9 +2471,11 @@ eOSState cMenuMain::ProcessKey(eKeys Key)
|
||||
state = replaying ? osContinue : osRecord;
|
||||
break;
|
||||
case kGreen: if (!HadSubMenu) {
|
||||
cDevice::PrimaryDevice()->IncCurrentAudioTrack();
|
||||
if (cDevice::PrimaryDevice()->NumAudioTracks() > 1) {
|
||||
cRemote::Put(kAudio, true);
|
||||
state = osEnd;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case kYellow: if (!HadSubMenu)
|
||||
state = replaying ? osContinue : osPause;
|
||||
@ -2764,6 +2766,122 @@ eOSState cDisplayVolume::ProcessKey(eKeys Key)
|
||||
return timeout.TimedOut() ? osEnd : osContinue;
|
||||
}
|
||||
|
||||
// --- cDisplayTracks --------------------------------------------------------
|
||||
|
||||
#define TRACKTIMEOUT 5000 //ms
|
||||
|
||||
cDisplayTracks *cDisplayTracks::currentDisplayTracks = NULL;
|
||||
|
||||
cDisplayTracks::cDisplayTracks(void)
|
||||
:cOsdObject(true)
|
||||
{
|
||||
// Get the actual audio track descriptions from the EPG if we're not replaying:
|
||||
if (!cDevice::PrimaryDevice()->Replaying() || cTransferControl::ReceiverDevice()) {
|
||||
cChannel *Channel = Channels.GetByNumber(cDevice::CurrentChannel());
|
||||
if (Channel) {
|
||||
cSchedulesLock SchedulesLock;
|
||||
const cSchedules *Schedules = cSchedules::Schedules(SchedulesLock);
|
||||
if (Schedules) {
|
||||
const cSchedule *Schedule = Schedules->GetSchedule(Channel->GetChannelID());
|
||||
if (Schedule) {
|
||||
const cEvent *Present = Schedule->GetPresentEvent(true);
|
||||
if (Present) {
|
||||
const cComponents *Components = Present->Components();
|
||||
if (Components) {
|
||||
int indexAudio = 0;
|
||||
int indexDolby = 0;
|
||||
for (int i = 0; i < Components->NumComponents(); i++) {
|
||||
const tComponent *p = Components->Component(i);
|
||||
if (p->stream == 2) {
|
||||
if (p->type == 0x05)
|
||||
cDevice::PrimaryDevice()->SetAvailableTrack(ttDolby, indexDolby++, 0, NULL, p->description);
|
||||
else
|
||||
cDevice::PrimaryDevice()->SetAvailableTrack(ttAudio, indexAudio++, 0, NULL, p->description);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
currentDisplayTracks = this;
|
||||
numTracks = track = 0;
|
||||
eTrackType CurrentAudioTrack = cDevice::PrimaryDevice()->GetCurrentAudioTrack();
|
||||
for (int i = ttAudioFirst; i <= ttDolbyLast; i++) {
|
||||
const tTrackId *TrackId = cDevice::PrimaryDevice()->GetTrack(eTrackType(i));
|
||||
if (TrackId && TrackId->id) {
|
||||
types[numTracks] = eTrackType(i);
|
||||
descriptions[numTracks] = strdup(*TrackId->description ? TrackId->description : *TrackId->language ? TrackId->language : itoa(i));
|
||||
if (i == CurrentAudioTrack)
|
||||
track = numTracks;
|
||||
numTracks++;
|
||||
}
|
||||
}
|
||||
timeout.Set(TRACKTIMEOUT);
|
||||
displayTracks = Skins.Current()->DisplayTracks(tr("Audio"), numTracks, descriptions);
|
||||
Show();
|
||||
}
|
||||
|
||||
cDisplayTracks::~cDisplayTracks()
|
||||
{
|
||||
delete displayTracks;
|
||||
currentDisplayTracks = NULL;
|
||||
for (int i = 0; i < numTracks; i++)
|
||||
free(descriptions[i]);
|
||||
cStatus::MsgOsdClear();
|
||||
}
|
||||
|
||||
void cDisplayTracks::Show(void)
|
||||
{
|
||||
displayTracks->SetTrack(track, descriptions);
|
||||
displayTracks->Flush();
|
||||
cStatus::MsgSetAudioTrack(track, descriptions);
|
||||
}
|
||||
|
||||
cDisplayTracks *cDisplayTracks::Create(void)
|
||||
{
|
||||
if (!currentDisplayTracks)
|
||||
new cDisplayTracks;
|
||||
return currentDisplayTracks;
|
||||
}
|
||||
|
||||
void cDisplayTracks::Process(eKeys Key)
|
||||
{
|
||||
if (currentDisplayTracks)
|
||||
currentDisplayTracks->ProcessKey(Key);
|
||||
}
|
||||
|
||||
eOSState cDisplayTracks::ProcessKey(eKeys Key)
|
||||
{
|
||||
int oldTrack = track;
|
||||
switch (Key) {
|
||||
case kUp|k_Repeat:
|
||||
case kUp:
|
||||
case kDown|k_Repeat:
|
||||
case kDown:
|
||||
if (NORMALKEY(Key) == kUp && track > 0)
|
||||
track--;
|
||||
else if (NORMALKEY(Key) == kDown && track < numTracks - 1)
|
||||
track++;
|
||||
timeout.Set(TRACKTIMEOUT);
|
||||
break;
|
||||
case kAudio:
|
||||
if (++track >= numTracks)
|
||||
track = 0;
|
||||
timeout.Set(TRACKTIMEOUT);
|
||||
break;
|
||||
case kNone: break;
|
||||
default: return osEnd;
|
||||
}
|
||||
if (track != oldTrack) {
|
||||
Show();
|
||||
cDevice::PrimaryDevice()->SetCurrentAudioTrack(types[track]);
|
||||
}
|
||||
return timeout.TimedOut() ? osEnd : osContinue;
|
||||
}
|
||||
|
||||
// --- cRecordControl --------------------------------------------------------
|
||||
|
||||
cRecordControl::cRecordControl(cDevice *Device, cTimer *Timer, bool Pause)
|
||||
|
19
menu.h
19
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.65 2004/12/19 17:59:47 kls Exp $
|
||||
* $Id: menu.h 1.66 2005/01/02 14:38:00 kls Exp $
|
||||
*/
|
||||
|
||||
#ifndef __MENU_H
|
||||
@ -75,6 +75,23 @@ public:
|
||||
eOSState ProcessKey(eKeys Key);
|
||||
};
|
||||
|
||||
class cDisplayTracks : public cOsdObject {
|
||||
private:
|
||||
cSkinDisplayTracks *displayTracks;
|
||||
cTimeMs timeout;
|
||||
eTrackType types[ttMaxTrackTypes];
|
||||
char *descriptions[ttMaxTrackTypes];
|
||||
int numTracks, track;
|
||||
static cDisplayTracks *currentDisplayTracks;
|
||||
virtual void Show(void);
|
||||
cDisplayTracks(void);
|
||||
public:
|
||||
virtual ~cDisplayTracks();
|
||||
static cDisplayTracks *Create(void);
|
||||
static void Process(eKeys Key);
|
||||
eOSState ProcessKey(eKeys Key);
|
||||
};
|
||||
|
||||
class cMenuCam : public cOsdMenu {
|
||||
private:
|
||||
cCiMenu *ciMenu;
|
||||
|
4
player.h
4
player.h
@ -4,7 +4,7 @@
|
||||
* See the main source file 'vdr.c' for copyright information and
|
||||
* how to reach the author.
|
||||
*
|
||||
* $Id: player.h 1.13 2004/12/12 11:20:19 kls Exp $
|
||||
* $Id: player.h 1.14 2004/12/30 10:44:34 kls Exp $
|
||||
*/
|
||||
|
||||
#ifndef __PLAYER_H
|
||||
@ -19,7 +19,7 @@ private:
|
||||
cDevice *device;
|
||||
ePlayMode playMode;
|
||||
protected:
|
||||
bool DeviceSetAvailableTrack(eTrackType Type, int Index, uint16_t Id, const char *Language = NULL, uint32_t Flags = 0) { return device ? device->SetAvailableTrack(Type, Index, Id, Language, Flags) : false; }
|
||||
bool DeviceSetAvailableTrack(eTrackType Type, int Index, uint16_t Id, const char *Language = NULL, const char *Description = NULL, uint32_t Flags = 0) { return device ? device->SetAvailableTrack(Type, Index, Id, Language, Description, Flags) : false; }
|
||||
bool DevicePoll(cPoller &Poller, int TimeoutMs = 0) { return device ? device->Poll(Poller, TimeoutMs) : false; }
|
||||
bool DeviceFlush(int TimeoutMs = 0) { return device ? device->Flush(TimeoutMs) : true; }
|
||||
void DeviceTrickSpeed(int Speed) { if (device) device->TrickSpeed(Speed); }
|
||||
|
@ -4,7 +4,7 @@
|
||||
* See the main source file 'vdr.c' for copyright information and
|
||||
* how to reach the author.
|
||||
*
|
||||
* $Id: skinclassic.c 1.9 2004/12/26 11:33:53 kls Exp $
|
||||
* $Id: skinclassic.c 1.10 2005/01/02 14:41:08 kls Exp $
|
||||
*/
|
||||
|
||||
#include "skinclassic.h"
|
||||
@ -502,6 +502,84 @@ void cSkinClassicDisplayVolume::Flush(void)
|
||||
osd->Flush();
|
||||
}
|
||||
|
||||
// --- cSkinClassicDisplayTracks ---------------------------------------------
|
||||
|
||||
class cSkinClassicDisplayTracks : public cSkinDisplayTracks {
|
||||
private:
|
||||
cOsd *osd;
|
||||
int x0, x1;
|
||||
int y0, y1, y2;
|
||||
int lineHeight;
|
||||
int currentIndex;
|
||||
void SetItem(const char *Text, int Index, bool Current);
|
||||
public:
|
||||
cSkinClassicDisplayTracks(const char *Title, int NumTracks, const char * const *Tracks);
|
||||
virtual ~cSkinClassicDisplayTracks();
|
||||
virtual void SetTrack(int Index, const char * const *Tracks);
|
||||
virtual void Flush(void);
|
||||
};
|
||||
|
||||
cSkinClassicDisplayTracks::cSkinClassicDisplayTracks(const char *Title, int NumTracks, const char * const *Tracks)
|
||||
{
|
||||
const cFont *font = cFont::GetFont(fontOsd);
|
||||
lineHeight = font->Height();
|
||||
currentIndex = -1;
|
||||
int ItemsWidth = font->Width(Title);
|
||||
for (int i = 0; i < NumTracks; i++)
|
||||
ItemsWidth = max(ItemsWidth, font->Width(Tracks[i]));
|
||||
ItemsWidth += 10;
|
||||
x0 = 0;
|
||||
x1 = Setup.OSDWidth;
|
||||
int d = x1 - x0;
|
||||
if (d > ItemsWidth) {
|
||||
d = (d - ItemsWidth) & ~0x07; // must be multiple of 8
|
||||
x1 -= d;
|
||||
}
|
||||
y0 = 0;
|
||||
y1 = lineHeight;
|
||||
y2 = y1 + NumTracks * lineHeight;
|
||||
osd = cOsdProvider::NewOsd(Setup.OSDLeft, Setup.OSDTop + Setup.OSDHeight - y2);
|
||||
tArea Areas[] = { { x0, y0, x1 - 1, y2 - 1, 4 } };
|
||||
osd->SetAreas(Areas, sizeof(Areas) / sizeof(tArea));
|
||||
osd->DrawText(x0, y0, Title, Theme.Color(clrMenuTitleFg), Theme.Color(clrMenuTitleBg), font, x1 - x0);
|
||||
for (int i = 0; i < NumTracks; i++)
|
||||
SetItem(Tracks[i], i, false);
|
||||
}
|
||||
|
||||
cSkinClassicDisplayTracks::~cSkinClassicDisplayTracks()
|
||||
{
|
||||
delete osd;
|
||||
}
|
||||
|
||||
void cSkinClassicDisplayTracks::SetItem(const char *Text, int Index, bool Current)
|
||||
{
|
||||
int y = y1 + Index * lineHeight;
|
||||
tColor ColorFg, ColorBg;
|
||||
if (Current) {
|
||||
ColorFg = Theme.Color(clrMenuItemCurrentFg);
|
||||
ColorBg = Theme.Color(clrMenuItemCurrentBg);
|
||||
currentIndex = Index;
|
||||
}
|
||||
else {
|
||||
ColorFg = Theme.Color(clrMenuItemSelectable);
|
||||
ColorBg = Theme.Color(clrBackground);
|
||||
}
|
||||
const cFont *font = cFont::GetFont(fontOsd);
|
||||
osd->DrawText(x0, y, Text, ColorFg, ColorBg, font, x1 - x0);
|
||||
}
|
||||
|
||||
void cSkinClassicDisplayTracks::SetTrack(int Index, const char * const *Tracks)
|
||||
{
|
||||
if (currentIndex >= 0)
|
||||
SetItem(Tracks[currentIndex], currentIndex, false);
|
||||
SetItem(Tracks[Index], Index, true);
|
||||
}
|
||||
|
||||
void cSkinClassicDisplayTracks::Flush(void)
|
||||
{
|
||||
osd->Flush();
|
||||
}
|
||||
|
||||
// --- cSkinClassicDisplayMessage --------------------------------------------
|
||||
|
||||
class cSkinClassicDisplayMessage : public cSkinDisplayMessage {
|
||||
@ -571,6 +649,12 @@ cSkinDisplayVolume *cSkinClassic::DisplayVolume(void)
|
||||
return new cSkinClassicDisplayVolume;
|
||||
}
|
||||
|
||||
|
||||
cSkinDisplayTracks *cSkinClassic::DisplayTracks(const char *Title, int NumTracks, const char * const *Tracks)
|
||||
{
|
||||
return new cSkinClassicDisplayTracks(Title, NumTracks, Tracks);
|
||||
}
|
||||
|
||||
cSkinDisplayMessage *cSkinClassic::DisplayMessage(void)
|
||||
{
|
||||
return new cSkinClassicDisplayMessage;
|
||||
|
@ -4,7 +4,7 @@
|
||||
* See the main source file 'vdr.c' for copyright information and
|
||||
* how to reach the author.
|
||||
*
|
||||
* $Id: skinclassic.h 1.1 2004/04/18 09:38:02 kls Exp $
|
||||
* $Id: skinclassic.h 1.2 2005/01/02 14:38:56 kls Exp $
|
||||
*/
|
||||
|
||||
#ifndef __SKINCLASSIC_H
|
||||
@ -20,6 +20,7 @@ public:
|
||||
virtual cSkinDisplayMenu *DisplayMenu(void);
|
||||
virtual cSkinDisplayReplay *DisplayReplay(bool ModeOnly);
|
||||
virtual cSkinDisplayVolume *DisplayVolume(void);
|
||||
virtual cSkinDisplayTracks *DisplayTracks(const char *Title, int NumTracks, const char * const *Tracks);
|
||||
virtual cSkinDisplayMessage *DisplayMessage(void);
|
||||
};
|
||||
|
||||
|
18
skins.h
18
skins.h
@ -4,7 +4,7 @@
|
||||
* See the main source file 'vdr.c' for copyright information and
|
||||
* how to reach the author.
|
||||
*
|
||||
* $Id: skins.h 1.4 2004/12/26 11:57:54 kls Exp $
|
||||
* $Id: skins.h 1.5 2005/01/02 14:36:19 kls Exp $
|
||||
*/
|
||||
|
||||
#ifndef __SKINS_H
|
||||
@ -66,8 +66,6 @@ public:
|
||||
Red = Video options
|
||||
Green = Info now
|
||||
Yellow = Info next
|
||||
Blue = Audio options
|
||||
AudioOptions
|
||||
VideoOptions
|
||||
*/
|
||||
};
|
||||
@ -223,6 +221,14 @@ public:
|
||||
///< indicator shall be displayed.
|
||||
};
|
||||
|
||||
class cSkinDisplayTracks : public cSkinDisplay {
|
||||
///< This class implements the track display.
|
||||
public:
|
||||
virtual void SetTrack(int Index, const char * const *Tracks) = 0;
|
||||
///< Sets the current track to the one given by Index, which
|
||||
///< points into the Tracks array of strings.
|
||||
};
|
||||
|
||||
class cSkinDisplayMessage : public cSkinDisplay {
|
||||
///< This class implements a simple message display.
|
||||
public:
|
||||
@ -275,6 +281,12 @@ public:
|
||||
virtual cSkinDisplayVolume *DisplayVolume(void) = 0;
|
||||
///< Creates and returns a new object for displaying the current volume.
|
||||
///< The caller must delete the object after use.
|
||||
virtual cSkinDisplayTracks *DisplayTracks(const char *Title, int NumTracks, const char * const *Tracks) = 0;
|
||||
///< Creates and returns a new object for displaying the available tracks.
|
||||
///< NumTracks indicates how many entries in Tracks are available.
|
||||
///< Tracks will be valid throughout the entire lifetime of the returned
|
||||
///< cSkinDisplayTrack object.
|
||||
///< The caller must delete the object after use.
|
||||
virtual cSkinDisplayMessage *DisplayMessage(void) = 0;
|
||||
///< Creates and returns a new object for displaying a message.
|
||||
///< The caller must delete the object after use.
|
||||
|
141
skinsttng.c
141
skinsttng.c
@ -4,7 +4,7 @@
|
||||
* See the main source file 'vdr.c' for copyright information and
|
||||
* how to reach the author.
|
||||
*
|
||||
* $Id: skinsttng.c 1.9 2004/12/26 11:34:29 kls Exp $
|
||||
* $Id: skinsttng.c 1.10 2005/01/02 14:41:49 kls Exp $
|
||||
*/
|
||||
|
||||
// Star Trek: The Next Generation® is a registered trademark of Paramount Pictures
|
||||
@ -822,6 +822,140 @@ void cSkinSTTNGDisplayVolume::Flush(void)
|
||||
osd->Flush();
|
||||
}
|
||||
|
||||
// --- cSkinSTTNGDisplayTracks -----------------------------------------------
|
||||
|
||||
class cSkinSTTNGDisplayTracks : public cSkinDisplayTracks {
|
||||
private:
|
||||
cOsd *osd;
|
||||
int x0, x1, x2, x3, x4, x5, x6, x7;
|
||||
int y0, y1, y2, y3, y4, y5, y6, y7;
|
||||
int lineHeight;
|
||||
tColor frameColor;
|
||||
int currentIndex;
|
||||
void SetItem(const char *Text, int Index, bool Current);
|
||||
public:
|
||||
cSkinSTTNGDisplayTracks(const char *Title, int NumTracks, const char * const *Tracks);
|
||||
virtual ~cSkinSTTNGDisplayTracks();
|
||||
virtual void SetTrack(int Index, const char * const *Tracks);
|
||||
virtual void Flush(void);
|
||||
};
|
||||
|
||||
cSkinSTTNGDisplayTracks::cSkinSTTNGDisplayTracks(const char *Title, int NumTracks, const char * const *Tracks)
|
||||
{
|
||||
const cFont *font = cFont::GetFont(fontOsd);
|
||||
lineHeight = font->Height();
|
||||
frameColor = Theme.Color(clrMenuFrame);
|
||||
currentIndex = -1;
|
||||
int ItemsWidth = font->Width(Title);
|
||||
for (int i = 0; i < NumTracks; i++)
|
||||
ItemsWidth = max(ItemsWidth, font->Width(Tracks[i]));
|
||||
ItemsWidth += 10;
|
||||
x0 = 0;
|
||||
x1 = lineHeight / 2;
|
||||
x3 = (x1 + Roundness + Gap + 7) & ~0x07; // must be multiple of 8
|
||||
x2 = x3 - Gap;
|
||||
x7 = Setup.OSDWidth;
|
||||
x6 = x7 - lineHeight / 2;
|
||||
x4 = (x6 - lineHeight / 2 - Gap) & ~0x07; // must be multiple of 8
|
||||
x5 = x4 + Gap;
|
||||
int d = x4 - x3;
|
||||
if (d > ItemsWidth) {
|
||||
d = (d - ItemsWidth) & ~0x07; // must be multiple of 8
|
||||
x4 -= d;
|
||||
x5 -= d;
|
||||
x6 -= d;
|
||||
x7 -= d;
|
||||
}
|
||||
y0 = 0;
|
||||
y1 = lineHeight;
|
||||
y2 = y1 + Roundness;
|
||||
y3 = y2 + Gap;
|
||||
// limit to Setup.OSDHeight? - what if height is too big???
|
||||
y4 = y3 + NumTracks * lineHeight + 2 * Roundness;
|
||||
y5 = y4 + Gap;
|
||||
y6 = y5 + Roundness;
|
||||
y7 = y6 + cFont::GetFont(fontSml)->Height();
|
||||
int yt = (y0 + y1) / 2;
|
||||
int yb = (y6 + y7) / 2;
|
||||
osd = cOsdProvider::NewOsd(Setup.OSDLeft, Setup.OSDTop + Setup.OSDHeight - y7);
|
||||
tArea Areas[] = { { x0, y0, x7 - 1, y7 - 1, 4 } };
|
||||
if (osd->CanHandleAreas(Areas, sizeof(Areas) / sizeof(tArea)) == oeOk)
|
||||
osd->SetAreas(Areas, sizeof(Areas) / sizeof(tArea));
|
||||
else {
|
||||
tArea Areas[] = { { x0, y0, x7 - 1, y3 - 1, 2 },
|
||||
{ x0, y3, x3 - 1, y4 - 1, 1 },
|
||||
{ x3, y3, x4 - 1, y4 - 1, 2 },
|
||||
{ x4, y3, x7 - 1, y4 - 1, 2 },
|
||||
{ x0, y4, x7 - 1, y7 - 1, 4 }
|
||||
};
|
||||
osd->SetAreas(Areas, sizeof(Areas) / sizeof(tArea));
|
||||
}
|
||||
osd->DrawRectangle(x0, y0, x7 - 1, y7 - 1, Theme.Color(clrBackground));
|
||||
osd->DrawRectangle(x0, y0, x1 - 1, y1 - 1, clrTransparent);
|
||||
osd->DrawRectangle(x0, y6, x1 - 1, y7 - 1, clrTransparent);
|
||||
osd->DrawRectangle(x6, y0, x7 - 1, yt - 1, clrTransparent);
|
||||
osd->DrawRectangle(x6, yb, x7 - 1, y7 - 1, clrTransparent);
|
||||
osd->DrawEllipse (x0, y0, x1 - 1, y1 - 1, frameColor, 2);
|
||||
osd->DrawRectangle(x1, y0, x2 - 1, y1 - 1, frameColor);
|
||||
osd->DrawRectangle(x3, y0, x4 - 1, y1 - 1, frameColor);
|
||||
osd->DrawRectangle(x5, y0, x6 - 1, y1 - 1, frameColor);
|
||||
osd->DrawEllipse (x6, y0, x7 - 1, y1 - 1, frameColor, 5);
|
||||
osd->DrawRectangle(x0, y1, x1 - 1, y6 - 1, frameColor);
|
||||
osd->DrawEllipse (x1, y1, x2 - 1, y2 - 1, frameColor, -2);
|
||||
osd->DrawEllipse (x1, y5, x2 - 1, y6 - 1, frameColor, -3);
|
||||
osd->DrawEllipse (x0, y6, x1 - 1, y7 - 1, frameColor, 3);
|
||||
osd->DrawRectangle(x1, y6, x2 - 1, y7 - 1, frameColor);
|
||||
osd->DrawRectangle(x3, y6, x4 - 1, y7 - 1, frameColor);
|
||||
osd->DrawRectangle(x5, y6, x6 - 1, y7 - 1, frameColor);
|
||||
osd->DrawEllipse (x6, y6, x7 - 1, y7 - 1, frameColor, 5);
|
||||
osd->DrawText(x3 + 5, y0, Title, Theme.Color(clrMenuTitle), frameColor, font, x4 - x3 - 5);
|
||||
for (int i = 0; i < NumTracks; i++)
|
||||
SetItem(Tracks[i], i, false);
|
||||
}
|
||||
|
||||
cSkinSTTNGDisplayTracks::~cSkinSTTNGDisplayTracks()
|
||||
{
|
||||
delete osd;
|
||||
}
|
||||
|
||||
void cSkinSTTNGDisplayTracks::SetItem(const char *Text, int Index, bool Current)
|
||||
{
|
||||
int y = y3 + Roundness + Index * lineHeight;
|
||||
tColor ColorFg, ColorBg;
|
||||
if (Current) {
|
||||
ColorFg = Theme.Color(clrMenuItemCurrentFg);
|
||||
ColorBg = Theme.Color(clrMenuItemCurrentBg);
|
||||
osd->DrawEllipse (x1, y - Roundness, x2 - 1, y - 1, frameColor, -3);
|
||||
osd->DrawRectangle(x1, y, x2 - 1, y + lineHeight - 1, frameColor);
|
||||
osd->DrawEllipse (x1, y + lineHeight, x2 - 1, y + lineHeight + Roundness - 1, frameColor, -2);
|
||||
osd->DrawRectangle(x3, y, x4 - 1, y + lineHeight - 1, ColorBg);
|
||||
currentIndex = Index;
|
||||
}
|
||||
else {
|
||||
ColorFg = Theme.Color(clrMenuItemSelectable);
|
||||
ColorBg = Theme.Color(clrBackground);
|
||||
if (currentIndex == Index) {
|
||||
osd->DrawRectangle(x1, y - Roundness, x2 - 1, y + lineHeight + Roundness - 1, Theme.Color(clrBackground));
|
||||
osd->DrawRectangle(x3, y, x4 - 1, y + lineHeight - 1, Theme.Color(clrBackground));
|
||||
}
|
||||
}
|
||||
const cFont *font = cFont::GetFont(fontOsd);
|
||||
int xt = x3 + 5;
|
||||
osd->DrawText(xt, y, Text, ColorFg, ColorBg, font, x4 - xt);
|
||||
}
|
||||
|
||||
void cSkinSTTNGDisplayTracks::SetTrack(int Index, const char * const *Tracks)
|
||||
{
|
||||
if (currentIndex >= 0)
|
||||
SetItem(Tracks[currentIndex], currentIndex, false);
|
||||
SetItem(Tracks[Index], Index, true);
|
||||
}
|
||||
|
||||
void cSkinSTTNGDisplayTracks::Flush(void)
|
||||
{
|
||||
osd->Flush();
|
||||
}
|
||||
|
||||
// --- cSkinSTTNGDisplayMessage ----------------------------------------------
|
||||
|
||||
class cSkinSTTNGDisplayMessage : public cSkinDisplayMessage {
|
||||
@ -909,6 +1043,11 @@ cSkinDisplayVolume *cSkinSTTNG::DisplayVolume(void)
|
||||
return new cSkinSTTNGDisplayVolume;
|
||||
}
|
||||
|
||||
cSkinDisplayTracks *cSkinSTTNG::DisplayTracks(const char *Title, int NumTracks, const char * const *Tracks)
|
||||
{
|
||||
return new cSkinSTTNGDisplayTracks(Title, NumTracks, Tracks);
|
||||
}
|
||||
|
||||
cSkinDisplayMessage *cSkinSTTNG::DisplayMessage(void)
|
||||
{
|
||||
return new cSkinSTTNGDisplayMessage;
|
||||
|
@ -4,7 +4,7 @@
|
||||
* See the main source file 'vdr.c' for copyright information and
|
||||
* how to reach the author.
|
||||
*
|
||||
* $Id: skinsttng.h 1.1 2004/04/18 09:38:47 kls Exp $
|
||||
* $Id: skinsttng.h 1.2 2005/01/02 14:39:29 kls Exp $
|
||||
*/
|
||||
|
||||
#ifndef __SKINSTTNG_H
|
||||
@ -20,6 +20,7 @@ public:
|
||||
virtual cSkinDisplayMenu *DisplayMenu(void);
|
||||
virtual cSkinDisplayReplay *DisplayReplay(bool ModeOnly);
|
||||
virtual cSkinDisplayVolume *DisplayVolume(void);
|
||||
virtual cSkinDisplayTracks *DisplayTracks(const char *Title, int NumTracks, const char * const *Tracks);
|
||||
virtual cSkinDisplayMessage *DisplayMessage(void);
|
||||
};
|
||||
|
||||
|
8
status.c
8
status.c
@ -4,7 +4,7 @@
|
||||
* See the main source file 'vdr.c' for copyright information and
|
||||
* how to reach the author.
|
||||
*
|
||||
* $Id: status.c 1.5 2003/05/03 14:47:44 kls Exp $
|
||||
* $Id: status.c 1.6 2005/01/02 12:09:12 kls Exp $
|
||||
*/
|
||||
|
||||
#include "status.h"
|
||||
@ -47,6 +47,12 @@ void cStatus::MsgSetVolume(int Volume, bool Absolute)
|
||||
sm->SetVolume(Volume, Absolute);
|
||||
}
|
||||
|
||||
void cStatus::MsgSetAudioTrack(int Index, const char * const *Tracks)
|
||||
{
|
||||
for (cStatus *sm = statusMonitors.First(); sm; sm = statusMonitors.Next(sm))
|
||||
sm->SetAudioTrack(Index, Tracks);
|
||||
}
|
||||
|
||||
void cStatus::MsgOsdClear(void)
|
||||
{
|
||||
for (cStatus *sm = statusMonitors.First(); sm; sm = statusMonitors.Next(sm))
|
||||
|
6
status.h
6
status.h
@ -4,7 +4,7 @@
|
||||
* See the main source file 'vdr.c' for copyright information and
|
||||
* how to reach the author.
|
||||
*
|
||||
* $Id: status.h 1.6 2003/05/03 14:43:18 kls Exp $
|
||||
* $Id: status.h 1.7 2005/01/02 12:08:12 kls Exp $
|
||||
*/
|
||||
|
||||
#ifndef __STATUS_H
|
||||
@ -36,6 +36,9 @@ protected:
|
||||
virtual void SetVolume(int Volume, bool Absolute) {}
|
||||
// The volume has been set to the given value, either
|
||||
// absolutely or relative to the current volume.
|
||||
virtual void SetAudioTrack(int Index, const char * const *Tracks) {}
|
||||
// The audio track has been set to the one given by Index, which
|
||||
// points into the Tracks array of strings.
|
||||
virtual void OsdClear(void) {}
|
||||
// The OSD has been cleared.
|
||||
virtual void OsdTitle(const char *Title) {}
|
||||
@ -67,6 +70,7 @@ public:
|
||||
static void MsgRecording(const cDevice *Device, const char *Name);
|
||||
static void MsgReplaying(const cControl *Control, const char *Name);
|
||||
static void MsgSetVolume(int Volume, bool Absolute);
|
||||
static void MsgSetAudioTrack(int Index, const char * const *Tracks);
|
||||
static void MsgOsdClear(void);
|
||||
static void MsgOsdTitle(const char *Title);
|
||||
static void MsgOsdStatusMessage(const char *Message);
|
||||
|
@ -4,7 +4,7 @@
|
||||
* See the main source file 'vdr.c' for copyright information and
|
||||
* how to reach the author.
|
||||
*
|
||||
* $Id: transfer.c 1.19 2004/11/28 11:51:00 kls Exp $
|
||||
* $Id: transfer.c 1.20 2004/12/27 11:08:34 kls Exp $
|
||||
*/
|
||||
|
||||
#include "transfer.h"
|
||||
@ -58,11 +58,7 @@ void cTransfer::Action(void)
|
||||
int PollTimeouts = 0;
|
||||
uchar *p = NULL;
|
||||
int Result = 0;
|
||||
// XXX Apparently this isn't necessary with the new PES data handling that
|
||||
// XXX was intorduced in VDR 1.3.18. If you do need this, enable the following
|
||||
// XXX line and send an email to kls@cadsoft.de. If nobody requires this, it
|
||||
// XXX will be removed later. kls 2004-12-27
|
||||
//#define FW_NEEDS_BUFFER_RESERVE_FOR_AC3
|
||||
#define FW_NEEDS_BUFFER_RESERVE_FOR_AC3
|
||||
#ifdef FW_NEEDS_BUFFER_RESERVE_FOR_AC3
|
||||
bool Cleared = false;
|
||||
bool GotBufferReserve = false;
|
||||
|
11
vdr.5
11
vdr.5
@ -8,7 +8,7 @@
|
||||
.\" License as specified in the file COPYING that comes with the
|
||||
.\" vdr distribution.
|
||||
.\"
|
||||
.\" $Id: vdr.5 1.30 2004/12/18 12:40:47 kls Exp $
|
||||
.\" $Id: vdr.5 1.31 2005/01/02 13:57:10 kls Exp $
|
||||
.\"
|
||||
.TH vdr 5 "19 Dec 2004" "1.3.18" "Video Disk Recorder Files"
|
||||
.SH NAME
|
||||
@ -613,6 +613,7 @@ l l.
|
||||
\fBT\fR@<title>
|
||||
\fBS\fR@<short text>
|
||||
\fBD\fR@<description>
|
||||
\fBX\fR@<stream> <type> <language> <descr>
|
||||
\fBV\fR@<vps time>
|
||||
\fBe\fR@
|
||||
\fBc\fR@
|
||||
@ -622,8 +623,10 @@ Lowercase characters mark the end of a sequence that was started by the
|
||||
corresponding uppercase character. The outer frame consists of a sequence
|
||||
of one or more \fBC\fR...\fBc\fR (Channel) entries. Inside these any number of
|
||||
\fBE\fR...\fBe\fR (Event) entries are allowed.
|
||||
The \fBT\fR, \fBS\fR and \fBD\fR entries are optional (although every event
|
||||
All other tags are optional (although every event
|
||||
should at least have a \fBT\fR entry).
|
||||
There may be several \fBX\fR tags, depending on the number of tracks (video, audio etc.)
|
||||
the event provides.
|
||||
|
||||
.TS
|
||||
tab (@);
|
||||
@ -636,6 +639,10 @@ l l.
|
||||
<title> @is the title of the event
|
||||
<short text> @is the short text of the event (typically the name of the episode etc.)
|
||||
<description> @is the description of the event (any '|' characters will be interpreted as newlines)
|
||||
<stream> @is the stream content (1 = video, 2 = audio)
|
||||
<type> @is the stream type according to ETSI EN 300 468
|
||||
<language> @is the three letter language code
|
||||
<descr> @is the description of this stream component
|
||||
<vps time> @is the Video Programming Service time of this event
|
||||
.TE
|
||||
|
||||
|
12
vdr.c
12
vdr.c
@ -22,7 +22,7 @@
|
||||
*
|
||||
* The project's page is at http://www.cadsoft.de/vdr
|
||||
*
|
||||
* $Id: vdr.c 1.196 2004/12/26 10:30:30 kls Exp $
|
||||
* $Id: vdr.c 1.197 2005/01/02 14:39:41 kls Exp $
|
||||
*/
|
||||
|
||||
#include <getopt.h>
|
||||
@ -678,7 +678,7 @@ int main(int argc, char *argv[])
|
||||
case kChanDn:
|
||||
cDevice::SwitchChannel(NORMALKEY(key) == kChanUp ? 1 : -1);
|
||||
break;
|
||||
// Volume Control:
|
||||
// Volume control:
|
||||
case kVolUp|k_Repeat:
|
||||
case kVolUp:
|
||||
case kVolDn|k_Repeat:
|
||||
@ -697,6 +697,14 @@ int main(int argc, char *argv[])
|
||||
cDisplayVolume::Process(key);
|
||||
key = kNone; // nobody else needs to see these keys
|
||||
break;
|
||||
// Audio track control:
|
||||
case kAudio:
|
||||
if (!Menu && !cOsd::IsOpen())
|
||||
Menu = Temp = cDisplayTracks::Create();
|
||||
else
|
||||
cDisplayTracks::Process(key);
|
||||
key = kNone;
|
||||
break;
|
||||
// Pausing live video:
|
||||
case kPause:
|
||||
if (!cControl::Control()) {
|
||||
|
Loading…
Reference in New Issue
Block a user