mirror of
https://github.com/vdr-projects/vdr.git
synced 2025-03-01 10:50:46 +00:00
Version 1.3.18
- Removed an unused variable from cTimer::GetWDayFromMDay() (thanks to Wayne Keer for reporting this one). - Some more changes to the 'childTid' handling in cThread (based on suggestions by Stefan Huelswitt). - Fixed the spelling of 'canceling' (thanks to Wayne Keer for reporting this one). - Re-introduced a sleep to cDvbPlayer::Action() to avoid high CPU load in still picture mode (thanks to Reinhard Nissl for reporting this one). - Fixed a possible race condition in generating the DVB device names (thanks to Rainer Zocholl for reporting this one). - Changed the way PES packets are played to allow replay of AC3 sound over the full featured DVB cards (partially based on a patch from Werner Fink). + The new function cDevice::PlayPes() is now called with the complete PES data stream and calls PlayVideo() and PlayAudio() as necessary. + cDevice::PlayVideo() is now only called with actual video PES packets. + cDevice::PlayAudio() is now called with the actual audio PES packets, which can be either "normal" audio or AC3 data. You need at least firmware version 0x261d to replay AC3 sound over a full featured DVB card. This function now has an 'int' return value. + PlayAudio() of derived cDevice classes shall no longer call the base class function. It shall just play the given data as audio. + cPlayer::PlayVideo() and cPlayer::PlayAudio() are now obsolete and have been replaced with cPlayer::PlayPes(). + All StripAudioPackets() functions are now obsolete. The functionality has been moved into cDevice::PlayPes(), where only the video and audio packets that are actually required will be processed. + All audio track handling is now done by cDevice; cTransfer and cDvbPlayer no longer care about audio tracks. cPlayer, however, still has the virtual hooks for audio track handling in order to allow plugins to implement players that have their own idea about this. + cChannel::[AD]pid[12]() have been replaced with cChannel::[AD]pid(int i) to allow access to all available PIDs. - Escaped the '-' and 'ö' characters in the man pages (thanks to Darren Salt for pointing this out). - Completed the Italian OSD texts (thanks to Sean Carlos). - Fixed setting 'synced' in cRemux when recording radio channels (thanks to Laurence Abbott). - Removed the LOCK_THREAD from the LIRC thread (thanks to Ludwig Nussel). - Fixed genfontfile.c (sometimes the character width was wrong, and the codes were shifted one too far to the left). - Fixed the character width and shifted the codes one to the right in all font files. - Renamed font???.c to font???-iso8859-1.c for symmetry. - Switched the character set to iso8859-15 for English, German and Finnish (thanks to Andreas Brugger for reporting the missing Euro sign in iso8859-1). - Added 'channels.conf.terr' entries for Lübeck (thanks to Stefan Hußfeldt). - Fixed a race condition in starting a thread (thanks to Reinhard Nissl for reporting this one). - Replaced non-threadsafe library functions with their threadsafe versions (thanks to Rainer Zocholl for pointing this out). - Other non-threadsafe functions have been replaced by threadsafe classes that hide the actual buffering. In particular these are: readdir() -> cReadDir readline() -> cReadLine - Several formerly non-threadsafe functions now have a return type of cString: cChannel::ToText() tChannelID::ToString() cEvent::GetDateString() cEvent::GetTimeString() cEvent::GetEndTimeString() cEvent::GetVpsString() cMark::ToText() cTimer::ToText() cSource::ToString() cTimer::PrintDay() cTimer::PrintFirstDay() PrefixVideoFileName() IndexToHMSF() ChannelString() strescape() AddDirectory() itoa() WeekDayName() DayDateTime() When using these functions in a 'const char *' context there is nothing special to consider, except that you can no longer have a pointer to the return value, as in const char *date = DayDateTime(); Although this will compile without error message, the resulting 'date' will not be valid after this line. Use this instead: cString date = DayDateTime(); In a 'const void *' context (as in printf() etc.) the result needs to be dereferenced with a '*', as in printf("%s", *DayDateTime()); to make it a 'const char *'. - Removed delay_ms(), using cCondWait::SleepMs() instead. - Replaced time_ms() with a threadsafe and non-overflowing cTimeMs (thanks to Rainer 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 (see MANUAL for details). - 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, and the new member function SetAudioChannel() which is called when the audio channel is changed. - Skins need to implement the new cSkinDisplayTrack class to display the audio track menu. - The ST:TNG skin now displays the current audio track description (if any) at the botton left side. - The new setup option "DVB/Audio languages" can be used to control which audio language shall be selected in case a channel broadcasts in different languages (see MANUAL for details). - The "Left" and "Right" keys in the "Audio" menu can be used to switch between the left and right stereo channels in case there are different audio tracks in these channels (see MANUAL for details). - Fixed a possible race condition in cDevice::Action() (thanks to Mattias Grönlund). - Fixed the default quality value when grabbing a JPEG image (thanks to Patrick Gleichmann). - Fixed deleting a menu item in case the next item is not selectable (thanks to Dino Ravnic). - Implemented displaying mandatory subtitles in the SPU decoder (thanks to Marco Schlüßler). - The setup option "Recording/Record Dolby Digital" has been renamed and moved to "DVB/Use Dolby Digital". It now controls whether Dolby Digital is recorded and whether an available DD audio track will appear in the "Audio" menu. - Added support for circular polarization (thanks to Jonan Santiago). - Thanks to Werner Fink, Reinhard Nissl, Sascha Volkenandt and Bjørnar Nilsen for their support in testing and fine tuning this version.
This commit is contained in:
parent
630ba21dc1
commit
fb5cccb2df
35
CONTRIBUTORS
35
CONTRIBUTORS
@ -263,6 +263,8 @@ Werner Fink <werner@suse.de>
|
|||||||
for suggesting to add more checks and polling when getting frontend events
|
for suggesting to add more checks and polling when getting frontend events
|
||||||
for setting the VPID before the APID in live mode to avoid unnecessary
|
for setting the VPID before the APID in live mode to avoid unnecessary
|
||||||
overhead in the firmware
|
overhead in the firmware
|
||||||
|
for a patch that was used as a base for implementing a modified PES packet
|
||||||
|
handling in order to play AC3 audio over full featured DVB cards
|
||||||
|
|
||||||
Rolf Hakenes <hakenes@hippomi.de>
|
Rolf Hakenes <hakenes@hippomi.de>
|
||||||
for providing 'libdtv' and adapting the EIT mechanisms to it
|
for providing 'libdtv' and adapting the EIT mechanisms to it
|
||||||
@ -345,6 +347,10 @@ Rainer Zocholl <vdrcontrib@zocki.toppoint.de>
|
|||||||
replaying in time shift mode
|
replaying in time shift mode
|
||||||
for suggesting that VDR should stop if one of the configuration files can't be
|
for suggesting that VDR should stop if one of the configuration files can't be
|
||||||
read correctly at program startup
|
read correctly at program startup
|
||||||
|
for reporting a possible race condition in generating the DVB device names
|
||||||
|
for pointing out that non-threadsafe functions should be replaced with their
|
||||||
|
threadsafe versions
|
||||||
|
for pointing out a threadsafe and overflow problem with time_ms()
|
||||||
|
|
||||||
Oleg Assovski <assen@bitcom.msk.ru>
|
Oleg Assovski <assen@bitcom.msk.ru>
|
||||||
for adding EPG scanning for another 4 days
|
for adding EPG scanning for another 4 days
|
||||||
@ -755,8 +761,9 @@ Ludwig Nussel <ludwig.nussel@web.de>
|
|||||||
for reporting a problem on systems that have UTF-8 enabled
|
for reporting a problem on systems that have UTF-8 enabled
|
||||||
for pointing out a flaw in the the description of cRingBufferLinear
|
for pointing out a flaw in the the description of cRingBufferLinear
|
||||||
for reporting a bug in cRingBufferLinear::Get() in case the buffer wraps around
|
for reporting a bug in cRingBufferLinear::Get() in case the buffer wraps around
|
||||||
for adding some checks when cancelling a thread and removing the usleep() in
|
for adding some checks when canceling a thread and removing the usleep() in
|
||||||
cThread::Start()
|
cThread::Start()
|
||||||
|
for removing the LOCK_THREAD from the LIRC thread
|
||||||
|
|
||||||
Thomas Koch <tom@harhar.net>
|
Thomas Koch <tom@harhar.net>
|
||||||
for his support in keeping the Premiere World channels up to date in 'channels.conf'
|
for his support in keeping the Premiere World channels up to date in 'channels.conf'
|
||||||
@ -764,6 +771,7 @@ Thomas Koch <tom@harhar.net>
|
|||||||
|
|
||||||
Stefan Hußfeldt <vdr@marvin.on-luebeck.de>
|
Stefan Hußfeldt <vdr@marvin.on-luebeck.de>
|
||||||
for his help in keeping 'channels.conf.cable' up to date
|
for his help in keeping 'channels.conf.cable' up to date
|
||||||
|
for adding 'channels.conf.terr' entries for Lübeck
|
||||||
|
|
||||||
Christoph Friederich <christoph.friederich@gmx.de>
|
Christoph Friederich <christoph.friederich@gmx.de>
|
||||||
for reporting a bug in deleting the last recording in the "Recordings" menu, which
|
for reporting a bug in deleting the last recording in the "Recordings" menu, which
|
||||||
@ -804,6 +812,7 @@ Wolfgang Goeller <wgoeller@heraklit.ch>
|
|||||||
Jonan Santiago <jonan-lists-vdr@callisia.com>
|
Jonan Santiago <jonan-lists-vdr@callisia.com>
|
||||||
for fixing handling EPG data where the "extended event descriptor" comes before the
|
for fixing handling EPG data where the "extended event descriptor" comes before the
|
||||||
"short event" or a "time shifted event"
|
"short event" or a "time shifted event"
|
||||||
|
for adding support for circular polarization
|
||||||
|
|
||||||
Juri Haberland <juri@koschikode.com>
|
Juri Haberland <juri@koschikode.com>
|
||||||
for his help in keeping 'channels.conf.terr' up to date
|
for his help in keeping 'channels.conf.terr' up to date
|
||||||
@ -857,7 +866,7 @@ Jon Burgess <mplayer@jburgess.uklinux.net>
|
|||||||
for fixing a memory leak in thread handling when using NPTL
|
for fixing a memory leak in thread handling when using NPTL
|
||||||
|
|
||||||
Thomas Schmidt <thomas.schmidt@in.stud.tu-ilmenau.de>
|
Thomas Schmidt <thomas.schmidt@in.stud.tu-ilmenau.de>
|
||||||
for reporting a crash when cancelling a newly created timer
|
for reporting a crash when canceling a newly created timer
|
||||||
for making 'diseqc.conf' a required file only if Setup.DiSEqC is activated
|
for making 'diseqc.conf' a required file only if Setup.DiSEqC is activated
|
||||||
|
|
||||||
Michael Walle <michael.walle@web.de>
|
Michael Walle <michael.walle@web.de>
|
||||||
@ -890,6 +899,9 @@ Reinhard Nissl <rnissl@gmx.de>
|
|||||||
for reporting a a crash in the time search mechanism
|
for reporting a a crash in the time search mechanism
|
||||||
for taking the complete size of available data into account when deciding whether
|
for taking the complete size of available data into account when deciding whether
|
||||||
to clear the transfer buffer to avoid overflows
|
to clear the transfer buffer to avoid overflows
|
||||||
|
for reporting a high CPU load in still picture mode after removing the usleep()
|
||||||
|
call from cDvbPlayer::Action()
|
||||||
|
for reporting a race condition in starting a thread
|
||||||
|
|
||||||
Richard Robson <richard_robson@beeb.net>
|
Richard Robson <richard_robson@beeb.net>
|
||||||
for reporting freezing replay if a timer starts while in Transfer Mode from the
|
for reporting freezing replay if a timer starts while in Transfer Mode from the
|
||||||
@ -1059,6 +1071,8 @@ Wayne Keer <syphir@syphir.sytes.net>
|
|||||||
cDvbDevice::cDvbDevice() in case a patch references them
|
cDvbDevice::cDvbDevice() in case a patch references them
|
||||||
for suggesting to make the "Channel not available!" message and mtInfo instead of
|
for suggesting to make the "Channel not available!" message and mtInfo instead of
|
||||||
mtError
|
mtError
|
||||||
|
for reporting an unused variable from cTimer::GetWDayFromMDay()
|
||||||
|
for reporting a spelling error in 'canceling'
|
||||||
|
|
||||||
Marco Schlüßler <marco@lordzodiac.de>
|
Marco Schlüßler <marco@lordzodiac.de>
|
||||||
for fixing handling colors in cDvbSpuPalette::yuv2rgb()
|
for fixing handling colors in cDvbSpuPalette::yuv2rgb()
|
||||||
@ -1088,6 +1102,7 @@ Marco Schl
|
|||||||
the end of the given buffer, which has caused some unjustified "unknown picture
|
the end of the given buffer, which has caused some unjustified "unknown picture
|
||||||
type errors"
|
type errors"
|
||||||
for some improvements to cPoller
|
for some improvements to cPoller
|
||||||
|
for implementing displaying mandatory subtitles in the SPU decoder
|
||||||
|
|
||||||
Jürgen Schmitz <j.schmitz@web.de>
|
Jürgen Schmitz <j.schmitz@web.de>
|
||||||
for reporting a bug in displaying the current channel when switching via the SVDRP
|
for reporting a bug in displaying the current channel when switching via the SVDRP
|
||||||
@ -1146,6 +1161,7 @@ Lucian Muresan <lucianm@users.sourceforge.net>
|
|||||||
Mattias Grönlund <Mattias@Gronlund.net>
|
Mattias Grönlund <Mattias@Gronlund.net>
|
||||||
for pointing out a missing cleanup at program exit in case there is a problem
|
for pointing out a missing cleanup at program exit in case there is a problem
|
||||||
with a plugin
|
with a plugin
|
||||||
|
for fixing possible race condition in cDevice::Action()
|
||||||
|
|
||||||
Uwe Hanke <uhanke@gmx.de>
|
Uwe Hanke <uhanke@gmx.de>
|
||||||
for fixing some typos in the Makefile's 'font' target
|
for fixing some typos in the Makefile's 'font' target
|
||||||
@ -1162,10 +1178,25 @@ Sascha Klek <sklek@gmx.de>
|
|||||||
Andreas Brugger <brougs78@gmx.net>
|
Andreas Brugger <brougs78@gmx.net>
|
||||||
for reporting a possible crash when pausing live video and the recording was
|
for reporting a possible crash when pausing live video and the recording was
|
||||||
unable to start, maybe because there was no lock on the device
|
unable to start, maybe because there was no lock on the device
|
||||||
|
for reporting the missing Euro sign in iso8859-1
|
||||||
|
|
||||||
Dino Ravnic <dino.ravnic@fer.hr>
|
Dino Ravnic <dino.ravnic@fer.hr>
|
||||||
for fixing some characters in the iso8859-2 font file
|
for fixing some characters in the iso8859-2 font file
|
||||||
for fixing some errors in the Croatian language texts
|
for fixing some errors in the Croatian language texts
|
||||||
|
for fixing deleting a menu item in case the next item is not selectable
|
||||||
|
|
||||||
Olaf Titz <olaf@bigred.inka.de>
|
Olaf Titz <olaf@bigred.inka.de>
|
||||||
for fixing some typos in the Makefile's 'font' target
|
for fixing some typos in the Makefile's 'font' target
|
||||||
|
|
||||||
|
Darren Salt <linux@youmustbejoking.demon.co.uk>
|
||||||
|
for pointing out that the '-' and 'ö' characters need to be escaped in the man
|
||||||
|
pages
|
||||||
|
|
||||||
|
Sean Carlos <seanc@libero.it>
|
||||||
|
for translating OSD texts to the Italian language
|
||||||
|
|
||||||
|
Laurence Abbott <laz@club-burniston.co.uk>
|
||||||
|
for fixing setting 'synced' in cRemux when recording radio channels
|
||||||
|
|
||||||
|
Patrick Gleichmann <patrick@feedface.com>
|
||||||
|
for fixing the default quality value when grabbing a JPEG image
|
||||||
|
134
HISTORY
134
HISTORY
@ -346,7 +346,7 @@ Video Disk Recorder Revision History
|
|||||||
and then renames it).
|
and then renames it).
|
||||||
- In case the video data stream is broken the log message will come only every
|
- In case the video data stream is broken the log message will come only every
|
||||||
5 seconds.
|
5 seconds.
|
||||||
- The current channel is now saved in the 'setup.conf' file when VDR is cancelled,
|
- The current channel is now saved in the 'setup.conf' file when VDR is canceled,
|
||||||
and will be restored next time it is started (thanks to Deti Fliegl).
|
and will be restored next time it is started (thanks to Deti Fliegl).
|
||||||
- The EIT scanning thread is now locked when switching channels to avoid problems.
|
- The EIT scanning thread is now locked when switching channels to avoid problems.
|
||||||
- Encrypted channels can now be selected even without knowing the PNR (however, it
|
- Encrypted channels can now be selected even without knowing the PNR (however, it
|
||||||
@ -2241,7 +2241,7 @@ Video Disk Recorder Revision History
|
|||||||
Gruber for reporting this one).
|
Gruber for reporting this one).
|
||||||
- Fixed editing channels ('timers.conf' was not written after a channel has
|
- Fixed editing channels ('timers.conf' was not written after a channel has
|
||||||
been modified, which could result in errors upon the next start of VDR).
|
been modified, which could result in errors upon the next start of VDR).
|
||||||
- Fixed a crash when cancelling a newly created timer (thanks to Thomas Schmidt
|
- Fixed a crash when canceling a newly created timer (thanks to Thomas Schmidt
|
||||||
for reporting this one).
|
for reporting this one).
|
||||||
- Completed Hungarian language texts (thanks to Istvan Koenigsberger and Guido
|
- Completed Hungarian language texts (thanks to Istvan Koenigsberger and Guido
|
||||||
Josten).
|
Josten).
|
||||||
@ -3065,7 +3065,7 @@ Video Disk Recorder Revision History
|
|||||||
small packet.
|
small packet.
|
||||||
- Removed the signal handler and WakeUp() call from cThread (it is no longer
|
- Removed the signal handler and WakeUp() call from cThread (it is no longer
|
||||||
needed).
|
needed).
|
||||||
- Added some checks when cancelling a thread and removed the usleep() in
|
- Added some checks when canceling a thread and removed the usleep() in
|
||||||
cThread::Start() (suggested by Ludwig Nussel). Also removed 'running' from
|
cThread::Start() (suggested by Ludwig Nussel). Also removed 'running' from
|
||||||
cThread and using only childTid to indicate whether a thread is actually
|
cThread and using only childTid to indicate whether a thread is actually
|
||||||
running.
|
running.
|
||||||
@ -3159,3 +3159,131 @@ Video Disk Recorder Revision History
|
|||||||
- Fixed toggling the "Day" item in the "Timers" menu, so that it selects the
|
- Fixed toggling the "Day" item in the "Timers" menu, so that it selects the
|
||||||
right day of week for timers in the future.
|
right day of week for timers in the future.
|
||||||
- Some improvements to cPoller (thanks to Marco Schlüßler).
|
- Some improvements to cPoller (thanks to Marco Schlüßler).
|
||||||
|
|
||||||
|
2005-01-09: Version 1.3.18
|
||||||
|
|
||||||
|
- Removed an unused variable from cTimer::GetWDayFromMDay() (thanks to Wayne Keer
|
||||||
|
for reporting this one).
|
||||||
|
- Some more changes to the 'childTid' handling in cThread (based on suggestions by
|
||||||
|
Stefan Huelswitt).
|
||||||
|
- Fixed the spelling of 'canceling' (thanks to Wayne Keer for reporting this one).
|
||||||
|
- Re-introduced a sleep to cDvbPlayer::Action() to avoid high CPU load in still
|
||||||
|
picture mode (thanks to Reinhard Nissl for reporting this one).
|
||||||
|
- Fixed a possible race condition in generating the DVB device names (thanks to
|
||||||
|
Rainer Zocholl for reporting this one).
|
||||||
|
- Changed the way PES packets are played to allow replay of AC3 sound over the
|
||||||
|
full featured DVB cards (partially based on a patch from Werner Fink).
|
||||||
|
+ The new function cDevice::PlayPes() is now called with the complete PES data
|
||||||
|
stream and calls PlayVideo() and PlayAudio() as necessary.
|
||||||
|
+ cDevice::PlayVideo() is now only called with actual video PES packets.
|
||||||
|
+ cDevice::PlayAudio() is now called with the actual audio PES packets, which
|
||||||
|
can be either "normal" audio or AC3 data. You need at least firmware version
|
||||||
|
0x261d to replay AC3 sound over a full featured DVB card. This function now
|
||||||
|
has an 'int' return value.
|
||||||
|
+ PlayAudio() of derived cDevice classes shall no longer call the base class
|
||||||
|
function. It shall just play the given data as audio.
|
||||||
|
+ cPlayer::PlayVideo() and cPlayer::PlayAudio() are now obsolete and have been
|
||||||
|
replaced with cPlayer::PlayPes().
|
||||||
|
+ All StripAudioPackets() functions are now obsolete. The functionality has been
|
||||||
|
moved into cDevice::PlayPes(), where only the video and audio packets that are
|
||||||
|
actually required will be processed.
|
||||||
|
+ All audio track handling is now done by cDevice; cTransfer and cDvbPlayer no
|
||||||
|
longer care about audio tracks. cPlayer, however, still has the virtual hooks
|
||||||
|
for audio track handling in order to allow plugins to implement players that
|
||||||
|
have their own idea about this.
|
||||||
|
+ cChannel::[AD]pid[12]() have been replaced with cChannel::[AD]pid(int i) to
|
||||||
|
allow access to all available PIDs.
|
||||||
|
- Escaped the '-' and 'ö' characters in the man pages (thanks to Darren Salt for
|
||||||
|
pointing this out).
|
||||||
|
- Completed the Italian OSD texts (thanks to Sean Carlos).
|
||||||
|
- Fixed setting 'synced' in cRemux when recording radio channels (thanks to
|
||||||
|
Laurence Abbott).
|
||||||
|
- Removed the LOCK_THREAD from the LIRC thread (thanks to Ludwig Nussel).
|
||||||
|
- Fixed genfontfile.c (sometimes the character width was wrong, and the codes were
|
||||||
|
shifted one too far to the left).
|
||||||
|
- Fixed the character width and shifted the codes one to the right in all font
|
||||||
|
files.
|
||||||
|
- Renamed font???.c to font???-iso8859-1.c for symmetry.
|
||||||
|
- Switched the character set to iso8859-15 for English, German and Finnish (thanks
|
||||||
|
to Andreas Brugger for reporting the missing Euro sign in iso8859-1).
|
||||||
|
- Added 'channels.conf.terr' entries for Lübeck (thanks to Stefan Hußfeldt).
|
||||||
|
- Fixed a race condition in starting a thread (thanks to Reinhard Nissl for
|
||||||
|
reporting this one).
|
||||||
|
- Replaced non-threadsafe library functions with their threadsafe versions (thanks
|
||||||
|
to Rainer Zocholl for pointing this out).
|
||||||
|
- Other non-threadsafe functions have been replaced by threadsafe classes that hide
|
||||||
|
the actual buffering. In particular these are:
|
||||||
|
readdir() -> cReadDir
|
||||||
|
readline() -> cReadLine
|
||||||
|
- Several formerly non-threadsafe functions now have a return type of cString:
|
||||||
|
cChannel::ToText()
|
||||||
|
tChannelID::ToString()
|
||||||
|
cEvent::GetDateString()
|
||||||
|
cEvent::GetTimeString()
|
||||||
|
cEvent::GetEndTimeString()
|
||||||
|
cEvent::GetVpsString()
|
||||||
|
cMark::ToText()
|
||||||
|
cTimer::ToText()
|
||||||
|
cSource::ToString()
|
||||||
|
cTimer::PrintDay()
|
||||||
|
cTimer::PrintFirstDay()
|
||||||
|
PrefixVideoFileName()
|
||||||
|
IndexToHMSF()
|
||||||
|
ChannelString()
|
||||||
|
strescape()
|
||||||
|
AddDirectory()
|
||||||
|
itoa()
|
||||||
|
WeekDayName()
|
||||||
|
DayDateTime()
|
||||||
|
When using these functions in a 'const char *' context there is nothing special
|
||||||
|
to consider, except that you can no longer have a pointer to the return value,
|
||||||
|
as in
|
||||||
|
const char *date = DayDateTime();
|
||||||
|
Although this will compile without error message, the resulting 'date' will not
|
||||||
|
be valid after this line. Use this instead:
|
||||||
|
cString date = DayDateTime();
|
||||||
|
In a 'const void *' context (as in printf() etc.) the result needs to be
|
||||||
|
dereferenced with a '*', as in
|
||||||
|
printf("%s", *DayDateTime());
|
||||||
|
to make it a 'const char *'.
|
||||||
|
- Removed delay_ms(), using cCondWait::SleepMs() instead.
|
||||||
|
- Replaced time_ms() with a threadsafe and non-overflowing cTimeMs (thanks to Rainer
|
||||||
|
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 (see MANUAL for details).
|
||||||
|
- 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, and the new member
|
||||||
|
function SetAudioChannel() which is called when the audio channel is changed.
|
||||||
|
- Skins need to implement the new cSkinDisplayTrack class to display the audio
|
||||||
|
track menu.
|
||||||
|
- The ST:TNG skin now displays the current audio track description (if any) at the
|
||||||
|
botton left side.
|
||||||
|
- The new setup option "DVB/Audio languages" can be used to control which audio
|
||||||
|
language shall be selected in case a channel broadcasts in different languages
|
||||||
|
(see MANUAL for details).
|
||||||
|
- The "Left" and "Right" keys in the "Audio" menu can be used to switch between
|
||||||
|
the left and right stereo channels in case there are different audio tracks
|
||||||
|
in these channels (see MANUAL for details).
|
||||||
|
- Fixed a possible race condition in cDevice::Action() (thanks to Mattias Grönlund).
|
||||||
|
- Fixed the default quality value when grabbing a JPEG image (thanks to Patrick
|
||||||
|
Gleichmann).
|
||||||
|
- Fixed deleting a menu item in case the next item is not selectable (thanks to
|
||||||
|
Dino Ravnic).
|
||||||
|
- Implemented displaying mandatory subtitles in the SPU decoder (thanks to Marco
|
||||||
|
Schlüßler).
|
||||||
|
- The setup option "Recording/Record Dobly Digital" has been renamed and moved to
|
||||||
|
"DVB/Use Dolby Digital". It now controls whether Dolby Digital is recorded and
|
||||||
|
whether an available DD audio track will appear in the "Audio" menu.
|
||||||
|
- Added support for circular polarization (thanks to Jonan Santiago).
|
||||||
|
- Thanks to Werner Fink, Reinhard Nissl, Sascha Volkenandt and Bjørnar Nilsen for
|
||||||
|
their support in testing and fine tuning this version.
|
||||||
|
87
MANUAL
87
MANUAL
@ -11,20 +11,20 @@ Version 1.2
|
|||||||
possible, several keys have different meanings in the various
|
possible, several keys have different meanings in the various
|
||||||
modes:
|
modes:
|
||||||
|
|
||||||
Key Normal VDR Channels Timers Edit/New Recordings Replay
|
Key Normal VDR Channels Timers Edit/New Recordings Replay Audio
|
||||||
|
|
||||||
Up Ch up Crsr up Crsr up Crsr up Crsr up Crsr up Play
|
Up Ch up Crsr up Crsr up Crsr up Crsr up Crsr up Play Sel. track
|
||||||
Down Ch down Crsr down Crsr down Crsr down Crsr down Crsr down Pause
|
Down Ch down Crsr down Crsr down Crsr down Crsr down Crsr down Pause Sel. track
|
||||||
Left Prev group - Page up Page up Decrement Page up Search back
|
Left Prev group - Page up Page up Decrement Page up Search back Sel. channel
|
||||||
Right Next group - Page down Page down Increment Page down Search forward
|
Right Next group - Page down Page down Increment Page down Search forward Sel. channel
|
||||||
Ok Ch display Select Switch Edit Accept Play Progress disp.
|
Ok Ch display Select Switch Edit Accept Play Progress disp. Switch & Close
|
||||||
Menu Menu on Menu off Menu off Menu off Menu off Menu off Menu on
|
Menu Menu on Menu off Menu off Menu off Menu off Menu off Menu on Menu on
|
||||||
Back - Menu off VDR menu VDR menu Discard VDR menu Recordings menu
|
Back - Menu off VDR menu VDR menu Discard VDR menu Recordings menu Close
|
||||||
Red - Record Edit Edit ABC/abc Play/Commands(2) Jump
|
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
|
Yellow - Pause live Delete Delete Delete Delete Skip +60s -
|
||||||
Blue - Stop/Resume Mark On/Off(1) - Summary Stop
|
Blue - Stop/Resume Mark On/Off(1) - Summary Stop -
|
||||||
0..9 Ch select - Sort(3) Day(4) Numeric inp. Exec cmd(2) Editing
|
0..9 Ch select - Sort(3) Day(4) Numeric inp. Exec cmd(2) Editing -
|
||||||
|
|
||||||
In a numerical input field (like the response to a CAM enquiry) the keys 0..9
|
In a numerical input field (like the response to a CAM enquiry) the keys 0..9
|
||||||
are used to enter the data, and the Left key can be used to delete the last
|
are used to enter the data, and the Left key can be used to delete the last
|
||||||
@ -49,6 +49,8 @@ Version 1.2
|
|||||||
Volume- volume down
|
Volume- volume down
|
||||||
Mute mute
|
Mute mute
|
||||||
|
|
||||||
|
Audio select audio track
|
||||||
|
|
||||||
Schedule \
|
Schedule \
|
||||||
Channels |
|
Channels |
|
||||||
Timers | directly access the VDR
|
Timers | directly access the VDR
|
||||||
@ -181,21 +183,36 @@ Version 1.2
|
|||||||
selected for at least 3 seconds.
|
selected for at least 3 seconds.
|
||||||
|
|
||||||
After switching to a different channel the channel number and name, as well
|
After switching to a different channel the channel number and name, as well
|
||||||
as the current time are displayed at the top of the screen. If available, the
|
as the current time are displayed in the OSD. If available, the
|
||||||
'current/next' information will be displayed below this line. This display
|
'current/next' information will be displayed below this line. This display
|
||||||
automatically goes away after about five seconds, or if any key is pressed.
|
automatically goes away after about five seconds, or if any key is pressed.
|
||||||
To bring up the channel display without switching channels you can press
|
To bring up the channel display without switching channels you can press
|
||||||
the "Ok" button.
|
the "Ok" button.
|
||||||
|
|
||||||
* Selecting language specific audio track
|
* Selecting audio tracks
|
||||||
|
|
||||||
If the current channel provides different audio tracks (typically for
|
If the current channel or recording provides different audio tracks (for
|
||||||
different languages), the "Green" button in the "VDR" menu can be pressed
|
different languages or Dolby Digital), the "Green" button in the "VDR" menu can
|
||||||
to toggle between these. There can be two different audio PIDs per channel,
|
be pressed to bring up the "Audio" menu. Within this menu, the "Up" and "Down"
|
||||||
assuming that typically a channel broadcasts a country specific language
|
keys can be used to switch between the audio tracks. If your remote control has
|
||||||
plus the movie's original soundtrack.
|
a dedicated "Audio" button, the first press of that button brings up the "Audio"
|
||||||
Recordings made form such channels will contain both audio tracks, and when
|
menu, and every further press switches to the next available audio track.
|
||||||
replaying the desired audio track can be selected the same way.
|
|
||||||
|
The "Left" and "Right" keys can be used to switch between "mono left", "stereo"
|
||||||
|
and "mono right" for channels that broadcast different audio tracks in the
|
||||||
|
left and right stereo channels.
|
||||||
|
|
||||||
|
The "Ok" key explicitly switches to the selected track (in case the device
|
||||||
|
for some reason doesn't play it) and closes the "Audio" menu.
|
||||||
|
|
||||||
|
The "Audio" menu will automatically disappear after 5 seconds of user inactivity,
|
||||||
|
or if any key other than the ones described above is pressed.
|
||||||
|
|
||||||
|
Once a Dolby Digital track has been selected on any channel, further channel
|
||||||
|
switches will first search for a Dolby Digital track of one of the preferred
|
||||||
|
audio languages. If no such track can be found, a normal audio track will
|
||||||
|
be selected. Note that this only works if the broadcasters use actual language
|
||||||
|
codes in their PID data, not things like "dd" or "2ch".
|
||||||
|
|
||||||
* Switching through channel groups
|
* Switching through channel groups
|
||||||
|
|
||||||
@ -495,14 +512,15 @@ Version 1.2
|
|||||||
A value of '0' completely turns off scanning on both single
|
A value of '0' completely turns off scanning on both single
|
||||||
and multiple card systems.
|
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:
|
VDR attempts to fix these bugs up to the given level:
|
||||||
0 = no EPG fixing
|
0 = no EPG fixing
|
||||||
1 = basic fixing of text location (Title, Episode and
|
1 = basic fixing of text location (Title, Episode and
|
||||||
Extended Description)
|
Extended Description)
|
||||||
2 = removal of excess whitespace and hyphens, mapping of
|
2 = removal of excess whitespace and hyphens, mapping of
|
||||||
wrongly used characters
|
wrongly used characters
|
||||||
Default is '2'.
|
3 = fix stream component descriptions
|
||||||
|
Default is '3'.
|
||||||
Note that after changing the setting of this parameter
|
Note that after changing the setting of this parameter
|
||||||
any EPG data that has already been received will remain
|
any EPG data that has already been received will remain
|
||||||
in its existing format - only newly received data will
|
in its existing format - only newly received data will
|
||||||
@ -570,12 +588,28 @@ Version 1.2
|
|||||||
Video format = 4:3 The video format (or aspect ratio) of the tv set in use
|
Video format = 4:3 The video format (or aspect ratio) of the tv set in use
|
||||||
(4:3 or 16:9).
|
(4:3 or 16:9).
|
||||||
|
|
||||||
|
Use Dolby Digital = yes
|
||||||
|
Turns recording of the Dolby Digital audio channels on
|
||||||
|
or off. This may be useful if you don't have the equipment
|
||||||
|
to replay Dolby Digital audio and want to save disk space.
|
||||||
|
If turned off, Dolby Digital tracks also don't appear in the
|
||||||
|
"Audio" menu.
|
||||||
|
|
||||||
Update channels = 4 Controls the automatic channel update function. '0' means
|
Update channels = 4 Controls the automatic channel update function. '0' means
|
||||||
no update, '1' will only update channel names, '2' will
|
no update, '1' will only update channel names, '2' will
|
||||||
update channel names and PIDs, '3' will perform all
|
update channel names and PIDs, '3' will perform all
|
||||||
updates and also add newly found channels, and '4' will
|
updates and also add newly found channels, and '4' will
|
||||||
also add newly found transponders.
|
also add newly found transponders.
|
||||||
|
|
||||||
|
Audio languages = 0 Some tv stations broadcast various audio tracks in different
|
||||||
|
languages. This option allows you to define which language(s)
|
||||||
|
you prefer in such cases. By default, or if none of the
|
||||||
|
preferred languages is broadcast, the first audio track will
|
||||||
|
be selected when switching to such a channel. If this option
|
||||||
|
is set to a non-zero value, the menu page will contain that
|
||||||
|
many "Audio language" options which allow you to select the
|
||||||
|
individual preferred languages.
|
||||||
|
|
||||||
LNB:
|
LNB:
|
||||||
|
|
||||||
SLOF = 11700 The switching frequency (in MHz) between low and
|
SLOF = 11700 The switching frequency (in MHz) between low and
|
||||||
@ -663,11 +697,6 @@ Version 1.2
|
|||||||
instant recording can be modified at any time by editing
|
instant recording can be modified at any time by editing
|
||||||
the respective timer in the "Timers" menu.
|
the respective timer in the "Timers" menu.
|
||||||
|
|
||||||
Record Dolby Digital = yes
|
|
||||||
Turns recording of the Dolby Digital audio channels on
|
|
||||||
or off. This may be useful if you don't have the equipment
|
|
||||||
to replay Dolby Digital audio and want to save disk space.
|
|
||||||
|
|
||||||
Max. video file size = 2000
|
Max. video file size = 2000
|
||||||
The maximum size of a single recorded video file in MB.
|
The maximum size of a single recorded video file in MB.
|
||||||
The valid range is 100...2000. Default is 2000, but
|
The valid range is 100...2000. Default is 2000, but
|
||||||
|
10
Makefile
10
Makefile
@ -4,7 +4,7 @@
|
|||||||
# See the main source file 'vdr.c' for copyright information and
|
# See the main source file 'vdr.c' for copyright information and
|
||||||
# how to reach the author.
|
# how to reach the author.
|
||||||
#
|
#
|
||||||
# $Id: Makefile 1.72 2004/11/21 11:28:55 kls Exp $
|
# $Id: Makefile 1.73 2004/12/18 13:39:19 kls Exp $
|
||||||
|
|
||||||
.DELETE_ON_ERROR:
|
.DELETE_ON_ERROR:
|
||||||
|
|
||||||
@ -78,7 +78,7 @@ endif
|
|||||||
|
|
||||||
all: vdr
|
all: vdr
|
||||||
font: genfontfile\
|
font: genfontfile\
|
||||||
fontfix.c fontosd.c fontsml.c\
|
fontfix-iso8859-1.c fontosd-iso8859-1.c fontsml-iso8859-1.c\
|
||||||
fontfix-iso8859-2.c fontosd-iso8859-2.c fontsml-iso8859-2.c\
|
fontfix-iso8859-2.c fontosd-iso8859-2.c fontsml-iso8859-2.c\
|
||||||
fontfix-iso8859-5.c fontosd-iso8859-5.c fontsml-iso8859-5.c\
|
fontfix-iso8859-5.c fontosd-iso8859-5.c fontsml-iso8859-5.c\
|
||||||
fontfix-iso8859-7.c fontosd-iso8859-7.c fontsml-iso8859-7.c\
|
fontfix-iso8859-7.c fontosd-iso8859-7.c fontsml-iso8859-7.c\
|
||||||
@ -106,11 +106,11 @@ vdr: $(OBJS) $(SILIB)
|
|||||||
|
|
||||||
# The font files:
|
# The font files:
|
||||||
|
|
||||||
fontfix.c:
|
fontfix-iso8859-1.c:
|
||||||
./genfontfile "cFont::tPixelData FontFix_iso8859_1" "$(FIXFONT_ISO8859_1)" > $@
|
./genfontfile "cFont::tPixelData FontFix_iso8859_1" "$(FIXFONT_ISO8859_1)" > $@
|
||||||
fontosd.c:
|
fontosd-iso8859-1.c:
|
||||||
./genfontfile "cFont::tPixelData FontOsd_iso8859_1" "$(OSDFONT_ISO8859_1)" > $@
|
./genfontfile "cFont::tPixelData FontOsd_iso8859_1" "$(OSDFONT_ISO8859_1)" > $@
|
||||||
fontsml.c:
|
fontsml-iso8859-1.c:
|
||||||
./genfontfile "cFont::tPixelData FontSml_iso8859_1" "$(SMLFONT_ISO8859_1)" > $@
|
./genfontfile "cFont::tPixelData FontSml_iso8859_1" "$(SMLFONT_ISO8859_1)" > $@
|
||||||
|
|
||||||
fontfix-iso8859-2.c:
|
fontfix-iso8859-2.c:
|
||||||
|
75
PLUGINS.html
75
PLUGINS.html
@ -14,18 +14,18 @@ Copyright © 2004 Klaus Schmidinger<br>
|
|||||||
<a href="http://www.cadsoft.de/vdr">www.cadsoft.de/vdr</a>
|
<a href="http://www.cadsoft.de/vdr">www.cadsoft.de/vdr</a>
|
||||||
</center>
|
</center>
|
||||||
<p>
|
<p>
|
||||||
<!--X1.2.6--><table width=100%><tr><td bgcolor=#0000AA> </td><td width=100%>
|
<!--X1.3.0--><table width=100%><tr><td bgcolor=#0000AA> </td><td width=100%>
|
||||||
Important modifications introduced in version 1.2.6 are marked like this.
|
|
||||||
<!--X1.2.6--></td></tr></table>
|
|
||||||
<!--X1.3.0--><table width=100%><tr><td bgcolor=#00AA00> </td><td width=100%>
|
|
||||||
Important modifications introduced in version 1.3.0 are marked like this.
|
Important modifications introduced in version 1.3.0 are marked like this.
|
||||||
<!--X1.3.0--></td></tr></table>
|
<!--X1.3.0--></td></tr></table>
|
||||||
<!--X1.3.7--><table width=100%><tr><td bgcolor=#AA0000> </td><td width=100%>
|
<!--X1.3.7--><table width=100%><tr><td bgcolor=#00AA00> </td><td width=100%>
|
||||||
Important modifications introduced in version 1.3.7 are marked like this.
|
Important modifications introduced in version 1.3.7 are marked like this.
|
||||||
<!--X1.3.7--></td></tr></table>
|
<!--X1.3.7--></td></tr></table>
|
||||||
<!--X1.3.8--><table width=100%><tr><td bgcolor=#FF0000> </td><td width=100%>
|
<!--X1.3.8--><table width=100%><tr><td bgcolor=#AA0000> </td><td width=100%>
|
||||||
Important modifications introduced in version 1.3.8 are marked like this.
|
Important modifications introduced in version 1.3.8 are marked like this.
|
||||||
<!--X1.3.8--></td></tr></table>
|
<!--X1.3.8--></td></tr></table>
|
||||||
|
<!--X1.3.18--><table width=100%><tr><td bgcolor=#FF0000> </td><td width=100%>
|
||||||
|
Important modifications introduced in version 1.3.18 are marked like this.
|
||||||
|
<!--X1.3.18--></td></tr></table>
|
||||||
<p>
|
<p>
|
||||||
VDR provides an easy to use plugin interface that allows additional functionality
|
VDR provides an easy to use plugin interface that allows additional functionality
|
||||||
to be added to the program by implementing a dynamically loadable library file.
|
to be added to the program by implementing a dynamically loadable library file.
|
||||||
@ -73,11 +73,11 @@ structures and allows it to hook itself into specific areas to perform special a
|
|||||||
<li><a href="#Status monitor">Status monitor</a>
|
<li><a href="#Status monitor">Status monitor</a>
|
||||||
<li><a href="#Players">Players</a>
|
<li><a href="#Players">Players</a>
|
||||||
<li><a href="#Receivers">Receivers</a>
|
<li><a href="#Receivers">Receivers</a>
|
||||||
<!--X1.3.0--><table width=100%><tr><td bgcolor=#00AA00> </td><td width=100%>
|
<!--X1.3.0--><table width=100%><tr><td bgcolor=#0000AA> </td><td width=100%>
|
||||||
<li><a href="#Filters">Filters</a>
|
<li><a href="#Filters">Filters</a>
|
||||||
<!--X1.3.0--></td></tr></table>
|
<!--X1.3.0--></td></tr></table>
|
||||||
<li><a href="#The On Screen Display">The On Screen Display</a>
|
<li><a href="#The On Screen Display">The On Screen Display</a>
|
||||||
<!--X1.3.7--><table width=100%><tr><td bgcolor=#AA0000> </td><td width=100%>
|
<!--X1.3.7--><table width=100%><tr><td bgcolor=#00AA00> </td><td width=100%>
|
||||||
<li><a href="#Skins">Skins</a>
|
<li><a href="#Skins">Skins</a>
|
||||||
<li><a href="#Themes">Themes</a>
|
<li><a href="#Themes">Themes</a>
|
||||||
<!--X1.3.7--></td></tr></table>
|
<!--X1.3.7--></td></tr></table>
|
||||||
@ -1023,17 +1023,21 @@ public:
|
|||||||
Take a look at the files <tt>player.h</tt> and <tt>dvbplayer.c</tt> to see how VDR implements
|
Take a look at the files <tt>player.h</tt> and <tt>dvbplayer.c</tt> to see how VDR implements
|
||||||
its own player for the VDR recordings.
|
its own player for the VDR recordings.
|
||||||
<p>
|
<p>
|
||||||
To play the video data, the player needs to call its member function
|
<!--X1.3.18--><table width=100%><tr><td bgcolor=#FF0000> </td><td width=100%>
|
||||||
|
To play the actual data, the player needs to call its member function
|
||||||
|
|
||||||
<p><table><tr><td bgcolor=#F0F0F0><pre>
|
<p><table><tr><td bgcolor=#F0F0F0><pre>
|
||||||
int PlayVideo(const uchar *Data, int Length);
|
int PlayPes(const uchar *Data, int Length, bool VideoOnly);
|
||||||
</pre></td></tr></table><p>
|
</pre></td></tr></table><p>
|
||||||
|
|
||||||
where <tt>Data</tt> points to a block of <tt>Length</tt> bytes of a PES data
|
where <tt>Data</tt> points to a block of <tt>Length</tt> bytes of a PES data
|
||||||
stream. There are no prerequisites regarding the length or alignment of an
|
stream containing any combination of video, audio or dolby tracks. Which audio
|
||||||
|
or dolby track will actually be played is controlled by the device the player
|
||||||
|
is attached to. There are no prerequisites regarding the length or alignment of an
|
||||||
individual block of data. The sum of all blocks must simply result in the
|
individual block of data. The sum of all blocks must simply result in the
|
||||||
desired video data stream, and it must be delivered fast enough so that the
|
desired data stream, and it must be delivered fast enough so that the
|
||||||
DVB device doesn't run out of data.
|
DVB device doesn't run out of data.
|
||||||
|
<!--X1.3.18--></td></tr></table>
|
||||||
To avoid busy loops the player should call its member function
|
To avoid busy loops the player should call its member function
|
||||||
|
|
||||||
<p><table><tr><td bgcolor=#F0F0F0><pre>
|
<p><table><tr><td bgcolor=#F0F0F0><pre>
|
||||||
@ -1042,24 +1046,26 @@ bool DevicePoll(cPoller &Poller, int TimeoutMs = 0);
|
|||||||
|
|
||||||
to determine whether the device is ready for further data.
|
to determine whether the device is ready for further data.
|
||||||
<p>
|
<p>
|
||||||
If the player can provide more than a single audio track, it can implement the
|
<!--X1.3.18--><table width=100%><tr><td bgcolor=#FF0000> </td><td width=100%>
|
||||||
following functions to make them available:
|
By default all audio track handling is done by the device a player is
|
||||||
|
attached to.
|
||||||
|
If the player can provide more than a single audio track, and has special
|
||||||
|
requirements in order to set a given track, it can implement the
|
||||||
|
following function to allow the device to set a specific track:
|
||||||
|
|
||||||
<p><table><tr><td bgcolor=#F0F0F0><pre>
|
<p><table><tr><td bgcolor=#F0F0F0><pre>
|
||||||
virtual int NumAudioTracks(void) const;
|
virtual void SetAudioTrack(eTrackType Type, const tTrackId *TrackId)
|
||||||
virtual const char **GetAudioTracks(int *CurrentTrack = NULL);
|
|
||||||
virtual void SetAudioTrack(int Index);
|
|
||||||
</pre></td></tr></table><p>
|
</pre></td></tr></table><p>
|
||||||
|
|
||||||
<p>
|
A player that has special requirements about audio tracks should announce its
|
||||||
If there is an additional audio track that has to be replayed with external hardware,
|
available audio tracks by calling
|
||||||
the player shall call its member function
|
|
||||||
|
|
||||||
<p><table><tr><td bgcolor=#F0F0F0><pre>
|
<p><table><tr><td bgcolor=#F0F0F0><pre>
|
||||||
void PlayAudio(const uchar *Data, int Length);
|
bool DeviceSetAvailableTrack(eTrackType Type, int Index, uint16_t Id, const char *Language = NULL, uint32_t Flags = 0)
|
||||||
</pre></td></tr></table><p>
|
</pre></td></tr></table><p>
|
||||||
|
|
||||||
where <tt>Data</tt> points to a complete audio PES packet of <tt>Length</tt> bytes.
|
See <tt>device.h</tt> for details about the parameters for track handling.
|
||||||
|
<!--X1.3.18--></td></tr></table>
|
||||||
<p>
|
<p>
|
||||||
The second part needed here is a control object that receives user input from the main
|
The second part needed here is a control object that receives user input from the main
|
||||||
program loop and reacts on this by telling the player what to do:
|
program loop and reacts on this by telling the player what to do:
|
||||||
@ -1217,7 +1223,7 @@ Mode</i>).
|
|||||||
If the <tt>cReceiver</tt> isn't needed any more, it may simply be <i>deleted</i>
|
If the <tt>cReceiver</tt> isn't needed any more, it may simply be <i>deleted</i>
|
||||||
and will automatically detach itself from the <tt>cDevice</tt>.
|
and will automatically detach itself from the <tt>cDevice</tt>.
|
||||||
|
|
||||||
<!--X1.3.0--><table width=100%><tr><td bgcolor=#00AA00> </td><td width=100%>
|
<!--X1.3.0--><table width=100%><tr><td bgcolor=#0000AA> </td><td width=100%>
|
||||||
<a name="Filters"><hr><h2>Filters</h2>
|
<a name="Filters"><hr><h2>Filters</h2>
|
||||||
|
|
||||||
<center><i><b>A Fistful of Datas</b></i></center><p>
|
<center><i><b>A Fistful of Datas</b></i></center><p>
|
||||||
@ -1263,7 +1269,7 @@ and will automatically detach itself from the <tt>cDevice</tt>.
|
|||||||
See VDR/eit.c or VDR/pat.c to learn how to process filter data.
|
See VDR/eit.c or VDR/pat.c to learn how to process filter data.
|
||||||
<!--X1.3.0--></td></tr></table>
|
<!--X1.3.0--></td></tr></table>
|
||||||
|
|
||||||
<!--X1.3.7--><table width=100%><tr><td bgcolor=#AA0000> </td><td width=100%>
|
<!--X1.3.7--><table width=100%><tr><td bgcolor=#00AA00> </td><td width=100%>
|
||||||
<a name="The On Screen Display"><hr><h2>The On Screen Display</h2>
|
<a name="The On Screen Display"><hr><h2>The On Screen Display</h2>
|
||||||
|
|
||||||
<center><i><b>Window to the world</b></i></center><p>
|
<center><i><b>Window to the world</b></i></center><p>
|
||||||
@ -1356,6 +1362,9 @@ public:
|
|||||||
virtual cSkinDisplayMenu *DisplayMenu(void);
|
virtual cSkinDisplayMenu *DisplayMenu(void);
|
||||||
virtual cSkinDisplayReplay *DisplayReplay(bool ModeOnly);
|
virtual cSkinDisplayReplay *DisplayReplay(bool ModeOnly);
|
||||||
virtual cSkinDisplayVolume *DisplayVolume(void);
|
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);
|
virtual cSkinDisplayMessage *DisplayMessage(void);
|
||||||
};
|
};
|
||||||
</pre></td></tr></table><p>
|
</pre></td></tr></table><p>
|
||||||
@ -1375,7 +1384,7 @@ new cMySkin;
|
|||||||
in the <a href="#Getting started"><tt>Start()</tt></a> function of your plugin.
|
in the <a href="#Getting started"><tt>Start()</tt></a> function of your plugin.
|
||||||
Do not delete this object, it will be automatically deleted when the program ends.
|
Do not delete this object, it will be automatically deleted when the program ends.
|
||||||
<p>
|
<p>
|
||||||
<!--X1.3.8--><table width=100%><tr><td bgcolor=#FF0000> </td><td width=100%>
|
<!--X1.3.8--><table width=100%><tr><td bgcolor=#AA0000> </td><td width=100%>
|
||||||
In order to be able to easily identify plugins that implement a skin it is recommended
|
In order to be able to easily identify plugins that implement a skin it is recommended
|
||||||
that the name of such a plugin should be
|
that the name of such a plugin should be
|
||||||
|
|
||||||
@ -1484,13 +1493,15 @@ repectively.
|
|||||||
<b>Audio selection</b>
|
<b>Audio selection</b>
|
||||||
<p>
|
<p>
|
||||||
If the device can provide more than a single audio track, it can implement the
|
If the device can provide more than a single audio track, it can implement the
|
||||||
following functions to make them available:
|
following function to make them available:
|
||||||
|
|
||||||
|
<!--X1.3.18--><table width=100%><tr><td bgcolor=#FF0000> </td><td width=100%>
|
||||||
<p><table><tr><td bgcolor=#F0F0F0><pre>
|
<p><table><tr><td bgcolor=#F0F0F0><pre>
|
||||||
virtual int NumAudioTracksDevice(void) const;
|
virtual void SetAudioTrackDevice(eTrackType Type);
|
||||||
virtual const char **GetAudioTracksDevice(int *CurrentTrack = NULL) const;
|
virtual int GetAudioChannelDevice(void);
|
||||||
virtual void SetAudioTrackDevice(int Index);
|
virtual void SetAudioChannelDevice(int AudioChannel);
|
||||||
</pre></td></tr></table><p>
|
</pre></td></tr></table><p>
|
||||||
|
<!--X1.3.18--></td></tr></table>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
<b>Recording</b>
|
<b>Recording</b>
|
||||||
@ -1527,9 +1538,7 @@ The functions to implement replaying capabilites are
|
|||||||
virtual bool HasDecoder(void) const;
|
virtual bool HasDecoder(void) const;
|
||||||
virtual bool CanReplay(void) const;
|
virtual bool CanReplay(void) const;
|
||||||
virtual bool SetPlayMode(ePlayMode PlayMode);
|
virtual bool SetPlayMode(ePlayMode PlayMode);
|
||||||
<!--X1.2.6--><table width=100%><tr><td bgcolor=#0000AA> </td><td width=100%>
|
|
||||||
virtual int64_t GetSTC(void);
|
virtual int64_t GetSTC(void);
|
||||||
<!--X1.2.6--></td></tr></table>
|
|
||||||
virtual void TrickSpeed(int Speed);
|
virtual void TrickSpeed(int Speed);
|
||||||
virtual void Clear(void);
|
virtual void Clear(void);
|
||||||
virtual void Play(void);
|
virtual void Play(void);
|
||||||
@ -1549,7 +1558,7 @@ virtual void SetVideoFormat(bool VideoFormat16_9);
|
|||||||
virtual void SetVolumeDevice(int Volume);
|
virtual void SetVolumeDevice(int Volume);
|
||||||
</pre></td></tr></table><p>
|
</pre></td></tr></table><p>
|
||||||
|
|
||||||
<!--X1.3.0--><table width=100%><tr><td bgcolor=#00AA00> </td><td width=100%>
|
<!--X1.3.0--><table width=100%><tr><td bgcolor=#0000AA> </td><td width=100%>
|
||||||
<p>
|
<p>
|
||||||
<b>Section Filtering</b>
|
<b>Section Filtering</b>
|
||||||
<p>
|
<p>
|
||||||
@ -1579,7 +1588,7 @@ handle section data.
|
|||||||
<p>
|
<p>
|
||||||
<b>On Screen Display</b>
|
<b>On Screen Display</b>
|
||||||
<p>
|
<p>
|
||||||
<!--X1.3.7--><table width=100%><tr><td bgcolor=#AA0000> </td><td width=100%>
|
<!--X1.3.7--><table width=100%><tr><td bgcolor=#00AA00> </td><td width=100%>
|
||||||
If your device provides On Screen Display (OSD) capabilities (which every device
|
If your device provides On Screen Display (OSD) capabilities (which every device
|
||||||
that is supposed to be used as a primary device should do), it shall implement
|
that is supposed to be used as a primary device should do), it shall implement
|
||||||
an "OSD provider" class, derived from <tt>cOsdProvider</tt>, which, when its <tt>CreateOsd()</tt>
|
an "OSD provider" class, derived from <tt>cOsdProvider</tt>, which, when its <tt>CreateOsd()</tt>
|
||||||
|
@ -8,3 +8,8 @@ VDR Plugin 'skincurses' Revision History
|
|||||||
2004-05-31: Version 0.0.2
|
2004-05-31: Version 0.0.2
|
||||||
|
|
||||||
- Fixed some default parameters.
|
- Fixed some default parameters.
|
||||||
|
|
||||||
|
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.
|
* See the README file for copyright information and how to reach the author.
|
||||||
*
|
*
|
||||||
* $Id: skincurses.c 1.2 2004/05/31 14:57:40 kls Exp $
|
* $Id: skincurses.c 1.5 2005/01/09 11:56:26 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <ncurses.h>
|
#include <ncurses.h>
|
||||||
@ -11,7 +11,7 @@
|
|||||||
#include <vdr/plugin.h>
|
#include <vdr/plugin.h>
|
||||||
#include <vdr/skins.h>
|
#include <vdr/skins.h>
|
||||||
|
|
||||||
static const char *VERSION = "0.0.2";
|
static const char *VERSION = "0.0.3";
|
||||||
static const char *DESCRIPTION = "A text only skin";
|
static const char *DESCRIPTION = "A text only skin";
|
||||||
static const char *MAINMENUENTRY = NULL;
|
static const char *MAINMENUENTRY = NULL;
|
||||||
|
|
||||||
@ -252,7 +252,7 @@ void cSkinCursesDisplayChannel::SetMessage(eMessageType Type, const char *Text)
|
|||||||
void cSkinCursesDisplayChannel::Flush(void)
|
void cSkinCursesDisplayChannel::Flush(void)
|
||||||
{
|
{
|
||||||
if (!message) {
|
if (!message) {
|
||||||
const char *date = DayDateTime();
|
cString date = DayDateTime();
|
||||||
osd->DrawText(OsdWidth - strlen(date), 0, date, clrWhite, clrBackground, &Font);
|
osd->DrawText(OsdWidth - strlen(date), 0, date, clrWhite, clrBackground, &Font);
|
||||||
}
|
}
|
||||||
osd->Flush();
|
osd->Flush();
|
||||||
@ -382,11 +382,11 @@ void cSkinCursesDisplayMenu::SetEvent(const cEvent *Event)
|
|||||||
int y = 2;
|
int y = 2;
|
||||||
cTextScroller ts;
|
cTextScroller ts;
|
||||||
char t[32];
|
char t[32];
|
||||||
snprintf(t, sizeof(t), "%s %s - %s", Event->GetDateString(), Event->GetTimeString(), Event->GetEndTimeString());
|
snprintf(t, sizeof(t), "%s %s - %s", *Event->GetDateString(), *Event->GetTimeString(), *Event->GetEndTimeString());
|
||||||
ts.Set(osd, 0, y, OsdWidth, OsdHeight - y - 2, t, &Font, clrYellow, clrBackground);
|
ts.Set(osd, 0, y, OsdWidth, OsdHeight - y - 2, t, &Font, clrYellow, clrBackground);
|
||||||
if (Event->Vps() && Event->Vps() != Event->StartTime()) {
|
if (Event->Vps() && Event->Vps() != Event->StartTime()) {
|
||||||
char *buffer;
|
char *buffer;
|
||||||
asprintf(&buffer, " VPS: %s", Event->GetVpsString());
|
asprintf(&buffer, " VPS: %s", *Event->GetVpsString());
|
||||||
osd->DrawText(OsdWidth - strlen(buffer), y, buffer, clrBlack, clrYellow, &Font);
|
osd->DrawText(OsdWidth - strlen(buffer), y, buffer, clrBlack, clrYellow, &Font);
|
||||||
free(buffer);
|
free(buffer);
|
||||||
}
|
}
|
||||||
@ -418,7 +418,7 @@ void cSkinCursesDisplayMenu::SetText(const char *Text, bool FixedFont)
|
|||||||
|
|
||||||
void cSkinCursesDisplayMenu::Flush(void)
|
void cSkinCursesDisplayMenu::Flush(void)
|
||||||
{
|
{
|
||||||
const char *date = DayDateTime();
|
cString date = DayDateTime();
|
||||||
osd->DrawText(OsdWidth - strlen(date) - 2, 0, date, clrBlack, clrCyan, &Font);
|
osd->DrawText(OsdWidth - strlen(date) - 2, 0, date, clrBlack, clrCyan, &Font);
|
||||||
osd->Flush();
|
osd->Flush();
|
||||||
}
|
}
|
||||||
@ -558,6 +558,69 @@ void cSkinCursesDisplayVolume::Flush(void)
|
|||||||
osd->Flush();
|
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 SetAudioChannel(int AudioChannel) {}
|
||||||
|
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 ---------------------------------------------
|
// --- cSkinCursesDisplayMessage ---------------------------------------------
|
||||||
|
|
||||||
class cSkinCursesDisplayMessage : public cSkinDisplayMessage {
|
class cSkinCursesDisplayMessage : public cSkinDisplayMessage {
|
||||||
@ -600,6 +663,7 @@ public:
|
|||||||
virtual cSkinDisplayMenu *DisplayMenu(void);
|
virtual cSkinDisplayMenu *DisplayMenu(void);
|
||||||
virtual cSkinDisplayReplay *DisplayReplay(bool ModeOnly);
|
virtual cSkinDisplayReplay *DisplayReplay(bool ModeOnly);
|
||||||
virtual cSkinDisplayVolume *DisplayVolume(void);
|
virtual cSkinDisplayVolume *DisplayVolume(void);
|
||||||
|
virtual cSkinDisplayTracks *DisplayTracks(const char *Title, int NumTracks, const char * const *Tracks);
|
||||||
virtual cSkinDisplayMessage *DisplayMessage(void);
|
virtual cSkinDisplayMessage *DisplayMessage(void);
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -633,6 +697,11 @@ cSkinDisplayVolume *cSkinCurses::DisplayVolume(void)
|
|||||||
return new cSkinCursesDisplayVolume;
|
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)
|
cSkinDisplayMessage *cSkinCurses::DisplayMessage(void)
|
||||||
{
|
{
|
||||||
return new cSkinCursesDisplayMessage;
|
return new cSkinCursesDisplayMessage;
|
||||||
|
@ -28,3 +28,12 @@ VDR Plugin 'sky' Revision History
|
|||||||
2004-10-16: Version 0.3.1
|
2004-10-16: Version 0.3.1
|
||||||
|
|
||||||
- Improved buffer handling.
|
- Improved buffer handling.
|
||||||
|
|
||||||
|
2004-12-12: Version 0.3.2
|
||||||
|
|
||||||
|
- Changed Apid access in cChannel.
|
||||||
|
|
||||||
|
2004-12-19: Version 0.3.3
|
||||||
|
|
||||||
|
- Made several functions threadsafe.
|
||||||
|
- Removed delay_ms(), using cCondWait::SleepMs() instead.
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
*
|
*
|
||||||
* See the README file for copyright information and how to reach the author.
|
* See the README file for copyright information and how to reach the author.
|
||||||
*
|
*
|
||||||
* $Id: sky.c 1.7 2004/10/16 09:10:06 kls Exp $
|
* $Id: sky.c 1.11 2004/12/26 12:45:22 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
@ -14,7 +14,7 @@
|
|||||||
#include <vdr/plugin.h>
|
#include <vdr/plugin.h>
|
||||||
#include <vdr/sources.h>
|
#include <vdr/sources.h>
|
||||||
|
|
||||||
static const char *VERSION = "0.3.1";
|
static const char *VERSION = "0.3.3";
|
||||||
static const char *DESCRIPTION = "Sky Digibox interface";
|
static const char *DESCRIPTION = "Sky Digibox interface";
|
||||||
|
|
||||||
// --- cDigiboxDevice --------------------------------------------------------
|
// --- cDigiboxDevice --------------------------------------------------------
|
||||||
@ -113,7 +113,7 @@ void cDigiboxDevice::LircSend(const char *s)
|
|||||||
dsyslog(buf);//XXX
|
dsyslog(buf);//XXX
|
||||||
if (write(fd_lirc, buf, strlen(buf)) < 0)
|
if (write(fd_lirc, buf, strlen(buf)) < 0)
|
||||||
LOG_ERROR;//XXX _STR
|
LOG_ERROR;//XXX _STR
|
||||||
delay_ms(200);
|
cCondWait::SleepMs(200);
|
||||||
}
|
}
|
||||||
|
|
||||||
void cDigiboxDevice::LircSend(int n)
|
void cDigiboxDevice::LircSend(int n)
|
||||||
@ -213,7 +213,7 @@ bool cDigiboxDevice::SetChannelDevice(const cChannel *Channel, bool LiveView)
|
|||||||
cSkyChannel *SkyChannel = SkyChannels.GetSkyChannel(Channel);
|
cSkyChannel *SkyChannel = SkyChannels.GetSkyChannel(Channel);
|
||||||
if (SkyChannel) {
|
if (SkyChannel) {
|
||||||
digiboxChannelNumber = SkyChannel->digiboxChannelNumber;
|
digiboxChannelNumber = SkyChannel->digiboxChannelNumber;
|
||||||
apid = Channel->Apid1();
|
apid = Channel->Apid(0);
|
||||||
vpid = Channel->Vpid();
|
vpid = Channel->Vpid();
|
||||||
//XXX only when recording??? -> faster channel switching!
|
//XXX only when recording??? -> faster channel switching!
|
||||||
LircSend("SKY"); // makes sure the Digibox is "on"
|
LircSend("SKY"); // makes sure the Digibox is "on"
|
||||||
|
6
README
6
README
@ -19,10 +19,10 @@ development of VDR.
|
|||||||
|
|
||||||
The author can be contacted at kls@cadsoft.de.
|
The author can be contacted at kls@cadsoft.de.
|
||||||
|
|
||||||
Yet another "set-top-box"?
|
Yet another "set-top box"?
|
||||||
--------------------------
|
--------------------------
|
||||||
|
|
||||||
The "set-top-boxes" available from commercial companies all have
|
The "set-top boxes" available from commercial companies all have
|
||||||
one major drawback: they are not "open". This project's goal is
|
one major drawback: they are not "open". This project's goal is
|
||||||
to build an "open" digital satellite receiver and timer controlled
|
to build an "open" digital satellite receiver and timer controlled
|
||||||
video disk recorder, based upon open standards and freely available
|
video disk recorder, based upon open standards and freely available
|
||||||
@ -31,6 +31,6 @@ driver software (of course, the hardware still has to be bought).
|
|||||||
The on screen menu system is simple, but shall provide all the
|
The on screen menu system is simple, but shall provide all the
|
||||||
possibilites necessary to perform timer controlled recording,
|
possibilites necessary to perform timer controlled recording,
|
||||||
file management and even "on disk editing". The menus
|
file management and even "on disk editing". The menus
|
||||||
of commercial set-top-boxes usually are a lot more fancy than
|
of commercial set-top boxes usually are a lot more fancy than
|
||||||
the ones in this system, but here we have the full source code
|
the ones in this system, but here we have the full source code
|
||||||
and can modify the menus in whatever way desired.
|
and can modify the menus in whatever way desired.
|
||||||
|
47
channels.c
47
channels.c
@ -4,7 +4,7 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* how to reach the author.
|
||||||
*
|
*
|
||||||
* $Id: channels.c 1.31 2004/11/02 18:07:05 kls Exp $
|
* $Id: channels.c 1.33 2004/12/26 12:34:52 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "channels.h"
|
#include "channels.h"
|
||||||
@ -146,10 +146,10 @@ tChannelID tChannelID::FromString(const char *s)
|
|||||||
return tChannelID::InvalidID;
|
return tChannelID::InvalidID;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *tChannelID::ToString(void)
|
cString tChannelID::ToString(void)
|
||||||
{
|
{
|
||||||
static char buffer[256];
|
char buffer[256];
|
||||||
snprintf(buffer, sizeof(buffer), rid ? "%s-%d-%d-%d-%d" : "%s-%d-%d-%d", cSource::ToString(source), nid, tid, sid, rid);
|
snprintf(buffer, sizeof(buffer), rid ? "%s-%d-%d-%d-%d" : "%s-%d-%d-%d", *cSource::ToString(source), nid, tid, sid, rid);
|
||||||
return buffer;
|
return buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -162,8 +162,6 @@ tChannelID &tChannelID::ClrPolarization(void)
|
|||||||
|
|
||||||
// -- cChannel ---------------------------------------------------------------
|
// -- cChannel ---------------------------------------------------------------
|
||||||
|
|
||||||
char *cChannel::buffer = NULL;
|
|
||||||
|
|
||||||
cChannel::cChannel(void)
|
cChannel::cChannel(void)
|
||||||
{
|
{
|
||||||
name = strdup("");
|
name = strdup("");
|
||||||
@ -289,7 +287,7 @@ bool cChannel::SetSatTransponderData(int Source, int Frequency, char Polarizatio
|
|||||||
|
|
||||||
if (source != Source || frequency != Frequency || polarization != Polarization || srate != Srate || coderateH != CoderateH) {
|
if (source != Source || frequency != Frequency || polarization != Polarization || srate != Srate || coderateH != CoderateH) {
|
||||||
if (Number()) {
|
if (Number()) {
|
||||||
dsyslog("changing transponder data of channel %d from %s:%d:%c:%d:%d to %s:%d:%c:%d:%d", Number(), cSource::ToString(source), frequency, polarization, srate, coderateH, cSource::ToString(Source), Frequency, Polarization, Srate, CoderateH);
|
dsyslog("changing transponder data of channel %d from %s:%d:%c:%d:%d to %s:%d:%c:%d:%d", Number(), *cSource::ToString(source), frequency, polarization, srate, coderateH, *cSource::ToString(Source), Frequency, Polarization, Srate, CoderateH);
|
||||||
modification |= CHANNELMOD_TRANSP;
|
modification |= CHANNELMOD_TRANSP;
|
||||||
Channels.SetModified();
|
Channels.SetModified();
|
||||||
}
|
}
|
||||||
@ -307,7 +305,7 @@ bool cChannel::SetCableTransponderData(int Source, int Frequency, int Modulation
|
|||||||
{
|
{
|
||||||
if (source != Source || frequency != Frequency || modulation != Modulation || srate != Srate || coderateH != CoderateH) {
|
if (source != Source || frequency != Frequency || modulation != Modulation || srate != Srate || coderateH != CoderateH) {
|
||||||
if (Number()) {
|
if (Number()) {
|
||||||
dsyslog("changing transponder data of channel %d from %s:%d:%d:%d:%d to %s:%d:%d:%d:%d", Number(), cSource::ToString(source), frequency, modulation, srate, coderateH, cSource::ToString(Source), Frequency, Modulation, Srate, CoderateH);
|
dsyslog("changing transponder data of channel %d from %s:%d:%d:%d:%d to %s:%d:%d:%d:%d", Number(), *cSource::ToString(source), frequency, modulation, srate, coderateH, *cSource::ToString(Source), Frequency, Modulation, Srate, CoderateH);
|
||||||
modification |= CHANNELMOD_TRANSP;
|
modification |= CHANNELMOD_TRANSP;
|
||||||
Channels.SetModified();
|
Channels.SetModified();
|
||||||
}
|
}
|
||||||
@ -324,7 +322,7 @@ bool cChannel::SetTerrTransponderData(int Source, int Frequency, int Bandwidth,
|
|||||||
{
|
{
|
||||||
if (source != Source || frequency != Frequency || bandwidth != Bandwidth || modulation != Modulation || hierarchy != Hierarchy || coderateH != CoderateH || coderateL != CoderateL || guard != Guard || transmission != Transmission) {
|
if (source != Source || frequency != Frequency || bandwidth != Bandwidth || modulation != Modulation || hierarchy != Hierarchy || coderateH != CoderateH || coderateL != CoderateL || guard != Guard || transmission != Transmission) {
|
||||||
if (Number()) {
|
if (Number()) {
|
||||||
dsyslog("changing transponder data of channel %d from %s:%d:%d:%d:%d:%d:%d:%d:%d to %s:%d:%d:%d:%d:%d:%d:%d:%d", Number(), cSource::ToString(source), frequency, bandwidth, modulation, hierarchy, coderateH, coderateL, guard, transmission, cSource::ToString(Source), Frequency, Bandwidth, Modulation, Hierarchy, CoderateH, CoderateL, Guard, Transmission);
|
dsyslog("changing transponder data of channel %d from %s:%d:%d:%d:%d:%d:%d:%d:%d to %s:%d:%d:%d:%d:%d:%d:%d:%d", Number(), *cSource::ToString(source), frequency, bandwidth, modulation, hierarchy, coderateH, coderateL, guard, transmission, *cSource::ToString(Source), Frequency, Bandwidth, Modulation, Hierarchy, CoderateH, CoderateL, Guard, Transmission);
|
||||||
modification |= CHANNELMOD_TRANSP;
|
modification |= CHANNELMOD_TRANSP;
|
||||||
Channels.SetModified();
|
Channels.SetModified();
|
||||||
}
|
}
|
||||||
@ -540,13 +538,13 @@ static int PrintParameter(char *p, char Name, int Value)
|
|||||||
return Value >= 0 && Value != 999 ? sprintf(p, "%c%d", Name, Value) : 0;
|
return Value >= 0 && Value != 999 ? sprintf(p, "%c%d", Name, Value) : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *cChannel::ParametersToString(void) const
|
cString cChannel::ParametersToString(void) const
|
||||||
{
|
{
|
||||||
char type = *cSource::ToString(source);
|
char type = **cSource::ToString(source);
|
||||||
if (isdigit(type))
|
if (isdigit(type))
|
||||||
type = 'S';
|
type = 'S';
|
||||||
#define ST(s) if (strchr(s, type))
|
#define ST(s) if (strchr(s, type))
|
||||||
static char buffer[64];
|
char buffer[64];
|
||||||
char *q = buffer;
|
char *q = buffer;
|
||||||
*q = 0;
|
*q = 0;
|
||||||
ST(" S ") q += sprintf(q, "%c", polarization);
|
ST(" S ") q += sprintf(q, "%c", polarization);
|
||||||
@ -600,7 +598,7 @@ bool cChannel::StringToParameters(const char *s)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *cChannel::ToText(const cChannel *Channel)
|
cString cChannel::ToText(const cChannel *Channel)
|
||||||
{
|
{
|
||||||
char FullName[strlen(Channel->name) + 1 + strlen(Channel->shortName) + 1 + strlen(Channel->provider) + 1 + 10]; // +10: paranoia
|
char FullName[strlen(Channel->name) + 1 + strlen(Channel->shortName) + 1 + strlen(Channel->provider) + 1 + 10]; // +10: paranoia
|
||||||
char *q = FullName;
|
char *q = FullName;
|
||||||
@ -611,7 +609,7 @@ const char *cChannel::ToText(const cChannel *Channel)
|
|||||||
q += sprintf(q, ";%s", Channel->provider);
|
q += sprintf(q, ";%s", Channel->provider);
|
||||||
*q = 0;
|
*q = 0;
|
||||||
strreplace(FullName, ':', '|');
|
strreplace(FullName, ':', '|');
|
||||||
free(buffer);
|
char *buffer;
|
||||||
if (Channel->groupSep) {
|
if (Channel->groupSep) {
|
||||||
if (Channel->number)
|
if (Channel->number)
|
||||||
asprintf(&buffer, ":@%d %s\n", Channel->number, FullName);
|
asprintf(&buffer, ":@%d %s\n", Channel->number, FullName);
|
||||||
@ -637,12 +635,12 @@ const char *cChannel::ToText(const cChannel *Channel)
|
|||||||
q = caidbuf;
|
q = caidbuf;
|
||||||
q += IntArrayToString(q, Channel->caids, 16);
|
q += IntArrayToString(q, Channel->caids, 16);
|
||||||
*q = 0;
|
*q = 0;
|
||||||
asprintf(&buffer, "%s:%d:%s:%s:%d:%s:%s:%d:%s:%d:%d:%d:%d\n", FullName, Channel->frequency, Channel->ParametersToString(), cSource::ToString(Channel->source), Channel->srate, vpidbuf, apidbuf, Channel->tpid, caidbuf, Channel->sid, Channel->nid, Channel->tid, Channel->rid);
|
asprintf(&buffer, "%s:%d:%s:%s:%d:%s:%s:%d:%s:%d:%d:%d:%d\n", FullName, Channel->frequency, *Channel->ParametersToString(), *cSource::ToString(Channel->source), Channel->srate, vpidbuf, apidbuf, Channel->tpid, caidbuf, Channel->sid, Channel->nid, Channel->tid, Channel->rid);
|
||||||
}
|
}
|
||||||
return buffer;
|
return buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *cChannel::ToText(void) const
|
cString cChannel::ToText(void) const
|
||||||
{
|
{
|
||||||
return ToText(this);
|
return ToText(this);
|
||||||
}
|
}
|
||||||
@ -705,7 +703,8 @@ bool cChannel::Parse(const char *s, bool AllowNonUniqueID)
|
|||||||
p = apidbuf;
|
p = apidbuf;
|
||||||
char *q;
|
char *q;
|
||||||
int NumApids = 0;
|
int NumApids = 0;
|
||||||
while ((q = strtok(p, ",")) != NULL) {
|
char *strtok_next;
|
||||||
|
while ((q = strtok_r(p, ",", &strtok_next)) != NULL) {
|
||||||
if (NumApids < MAXAPIDS) {
|
if (NumApids < MAXAPIDS) {
|
||||||
char *l = strchr(q, '=');
|
char *l = strchr(q, '=');
|
||||||
if (l) {
|
if (l) {
|
||||||
@ -725,7 +724,8 @@ bool cChannel::Parse(const char *s, bool AllowNonUniqueID)
|
|||||||
char *p = dpidbuf;
|
char *p = dpidbuf;
|
||||||
char *q;
|
char *q;
|
||||||
int NumDpids = 0;
|
int NumDpids = 0;
|
||||||
while ((q = strtok(p, ",")) != NULL) {
|
char *strtok_next;
|
||||||
|
while ((q = strtok_r(p, ",", &strtok_next)) != NULL) {
|
||||||
if (NumDpids < MAXAPIDS) {
|
if (NumDpids < MAXAPIDS) {
|
||||||
char *l = strchr(q, '=');
|
char *l = strchr(q, '=');
|
||||||
if (l) {
|
if (l) {
|
||||||
@ -747,7 +747,8 @@ bool cChannel::Parse(const char *s, bool AllowNonUniqueID)
|
|||||||
char *p = caidbuf;
|
char *p = caidbuf;
|
||||||
char *q;
|
char *q;
|
||||||
int NumCaIds = 0;
|
int NumCaIds = 0;
|
||||||
while ((q = strtok(p, ",")) != NULL) {
|
char *strtok_next;
|
||||||
|
while ((q = strtok_r(p, ",", &strtok_next)) != NULL) {
|
||||||
if (NumCaIds < MAXCAIDS) {
|
if (NumCaIds < MAXCAIDS) {
|
||||||
caids[NumCaIds++] = strtol(q, NULL, 16) & 0xFFFF;
|
caids[NumCaIds++] = strtol(q, NULL, 16) & 0xFFFF;
|
||||||
if (NumCaIds == 1 && caids[0] <= 0x00FF)
|
if (NumCaIds == 1 && caids[0] <= 0x00FF)
|
||||||
@ -797,7 +798,7 @@ bool cChannel::Parse(const char *s, bool AllowNonUniqueID)
|
|||||||
|
|
||||||
bool cChannel::Save(FILE *f)
|
bool cChannel::Save(FILE *f)
|
||||||
{
|
{
|
||||||
return fprintf(f, ToText()) > 0;
|
return fprintf(f, "%s", *ToText()) > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// -- cChannels --------------------------------------------------------------
|
// -- cChannels --------------------------------------------------------------
|
||||||
@ -936,7 +937,7 @@ int cChannels::Modified(void)
|
|||||||
cChannel *cChannels::NewChannel(const cChannel *Transponder, const char *Name, const char *ShortName, const char *Provider, int Nid, int Tid, int Sid, int Rid)
|
cChannel *cChannels::NewChannel(const cChannel *Transponder, const char *Name, const char *ShortName, const char *Provider, int Nid, int Tid, int Sid, int Rid)
|
||||||
{
|
{
|
||||||
if (Transponder) {
|
if (Transponder) {
|
||||||
dsyslog("creating new channel '%s,%s;%s' on %s transponder %d with id %d-%d-%d-%d", Name, ShortName, Provider, cSource::ToString(Transponder->Source()), Transponder->Transponder(), Nid, Tid, Sid, Rid);
|
dsyslog("creating new channel '%s,%s;%s' on %s transponder %d with id %d-%d-%d-%d", Name, ShortName, Provider, *cSource::ToString(Transponder->Source()), Transponder->Transponder(), Nid, Tid, Sid, Rid);
|
||||||
cChannel *NewChannel = new cChannel(*Transponder);
|
cChannel *NewChannel = new cChannel(*Transponder);
|
||||||
NewChannel->SetId(Nid, Tid, Sid, Rid);
|
NewChannel->SetId(Nid, Tid, Sid, Rid);
|
||||||
NewChannel->SetName(Name, ShortName, Provider);
|
NewChannel->SetName(Name, ShortName, Provider);
|
||||||
@ -947,9 +948,9 @@ cChannel *cChannels::NewChannel(const cChannel *Transponder, const char *Name, c
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *ChannelString(const cChannel *Channel, int Number)
|
cString ChannelString(const cChannel *Channel, int Number)
|
||||||
{
|
{
|
||||||
static char buffer[256];
|
char buffer[256];
|
||||||
if (Channel) {
|
if (Channel) {
|
||||||
if (Channel->GroupSep())
|
if (Channel->GroupSep())
|
||||||
snprintf(buffer, sizeof(buffer), "%s", Channel->Name());
|
snprintf(buffer, sizeof(buffer), "%s", Channel->Name());
|
||||||
|
@ -27,13 +27,13 @@ DSF;BetaDigital:12480:vC34:S19.2E:27500:1023:1024=deu:0:0:900:133:33:0
|
|||||||
HSE24,HSE24;BetaDigital:12480:vC34:S19.2E:27500:1279:1280=deu:37:0:40:133:33:0
|
HSE24,HSE24;BetaDigital:12480:vC34:S19.2E:27500:1279:1280=deu:37:0:40:133:33:0
|
||||||
Bloomberg TV Germany;Bloomberg:12551:vC56:S19.2E:22000:162:99=deu:0:0:12160:1:1108:0
|
Bloomberg TV Germany;Bloomberg:12551:vC56:S19.2E:22000:162:99=deu:0:0:12160:1:1108:0
|
||||||
EURONEWS;CSAT:11817:vC34:S19.2E:27500:163:92=fra,93=eng,94=ita,95=esl,91=rus,98=por,99=deu:0:0:8004:1:1070:0
|
EURONEWS;CSAT:11817:vC34:S19.2E:27500:163:92=fra,93=eng,94=ita,95=esl,91=rus,98=por,99=deu:0:0:8004:1:1070:0
|
||||||
rbb Brandenburg;ARD:12109:hC34:S19.2E:27500:501:502=deu:504:0:28205:1:1073:0
|
rbb Brandenburg;ARD:12109:hC34:S19.2E:27500:601:602=deu:604:0:28205:1:1073:0
|
||||||
Sky News;BSkyB:11597:vC56:S19.2E:22000:305+131:306=eng:0:0:28707:1:1026:0
|
Sky News;BSkyB:11597:vC56:S19.2E:22000:305+131:306=eng:0:0:28707:1:1026:0
|
||||||
Veronica/FoxKids;CANAL+:12574:hC56:S19.2E:22000:518+8190:92=dut:38:622,602,100:5020:53:1109:0
|
Veronica/FoxKids;CANAL+:12574:hC56:S19.2E:22000:518+8190:92=dut:38:622,602,100:5020:53:1109:0
|
||||||
BVN;CANAL+:12574:hC56:S19.2E:22000:515+8190:96=dut:36:0:5025:53:1109:0
|
BVN;CANAL+:12574:hC56:S19.2E:22000:515+8190:96=dut:36:0:5025:53:1109:0
|
||||||
n-tv;RTL World:12187:hC34:S19.2E:27500:169:73=deu:80:0:12090:1:1089:0
|
n-tv;RTL World:12187:hC34:S19.2E:27500:169:73=deu:80:0:12090:1:1089:0
|
||||||
Al Jazeera;CANALSATELLITE:11567:vC56:S19.2E:22000:55:56=ara:0:0:9021:1:1024:0
|
Al Jazeera;CANALSATELLITE:11567:vC56:S19.2E:22000:55:56=ara:0:0:9021:1:1024:0
|
||||||
TW1;ORF:12692:hC56:S19.2E:22000:166:167=deu:168:0:13013:1:1117:0
|
TW1 - 28Feb05;ORF:12692:hC56:S19.2E:22000:166:167=deu:168:0:13013:1:1117:0
|
||||||
Eurosport;ZDFvision:11953:hC34:S19.2E:27500:410:420=deu:430:0:28009:1:1079:0
|
Eurosport;ZDFvision:11953:hC34:S19.2E:27500:410:420=deu:430:0:28009:1:1079:0
|
||||||
EinsExtra;ARD:12109:hC34:S19.2E:27500:101:102=deu:0:0:28201:1:1073:0
|
EinsExtra;ARD:12109:hC34:S19.2E:27500:101:102=deu:0:0:28201:1:1073:0
|
||||||
EinsFestival;ARD:12109:hC34:S19.2E:27500:201:202=deu:0:0:28202:1:1073:0
|
EinsFestival;ARD:12109:hC34:S19.2E:27500:201:202=deu:0:0:28202:1:1073:0
|
||||||
@ -44,25 +44,25 @@ MDR FERNSEHEN;ARD:12109:hC34:S19.2E:27500:401:402=deu:404:0:28204:1:1073:0
|
|||||||
rbb Berlin;ARD:12109:hC34:S19.2E:27500:601:602=deu:604:0:28206:1:1073:0
|
rbb Berlin;ARD:12109:hC34:S19.2E:27500:601:602=deu:604:0:28206:1:1073:0
|
||||||
:Premiere World
|
:Premiere World
|
||||||
PREMIERE START,START;PREMIERE:11797:hC34:S19.2E:27500:255:256=deu:32:1702,1801,1722:8:133:2:0
|
PREMIERE START,START;PREMIERE:11797:hC34:S19.2E:27500:255:256=deu:32:1702,1801,1722:8:133:2:0
|
||||||
PREMIERE 1,PREM 1;PREMIERE:11797:hC34:S19.2E:27500:511:512=deu,513=deu;515=deu:32:1702,1801,1722:10:133:2:0
|
PREMIERE 1,PREM 1;PREMIERE:11797:hC34:S19.2E:27500:511:512=deu,513=deu;515=deu:32:1722,1702,1801:10:133:2:0
|
||||||
PREMIERE 2,PREM 2;PREMIERE:11797:hC34:S19.2E:27500:1791:1792=deu,1793=deu;1795=deu:32:1702,1722,1801:11:133:2:0
|
PREMIERE 2,PREM 2;PREMIERE:11797:hC34:S19.2E:27500:1791:1792=deu,1793=deu;1795=deu:32:1722,1801,1702:11:133:2:0
|
||||||
PREMIERE 3,PREM 3;PREMIERE:11797:hC34:S19.2E:27500:2303:2304=deu,2305=deu:32:1722,1801,1702:43:133:2:0
|
PREMIERE 3,PREM 3;PREMIERE:11797:hC34:S19.2E:27500:2303:2304=deu,2305=deu:32:1722,1801,1702:43:133:2:0
|
||||||
PREMIERE 4,PREM 4;PREMIERE:11797:hC34:S19.2E:27500:767:768=deu,769=deu:32:1801,1722,1702:9:133:2:0
|
PREMIERE 4,PREM 4;PREMIERE:11797:hC34:S19.2E:27500:767:768=deu:32:1801,1722,1702:9:133:2:0
|
||||||
PREMIERE 5,PREM 5;PREMIERE:11797:hC34:S19.2E:27500:1279:1280=deu:32:1722,1702,1801:29:133:2:0
|
PREMIERE 5,PREM 5;PREMIERE:11797:hC34:S19.2E:27500:1279:1280=deu,1281=deu:32:1801,1722,1702:29:133:2:0
|
||||||
PREMIERE 6,PREM 6;PREMIERE:11797:hC34:S19.2E:27500:1535:1536=deu:32:1702,1722,1801:41:133:2:0
|
PREMIERE 6,PREM 6;PREMIERE:11797:hC34:S19.2E:27500:1535:1536=deu:32:1702,1801,1722:41:133:2:0
|
||||||
PREMIERE 7,PREM 7;PREMIERE:11797:hC34:S19.2E:27500:1023:1024=deu:32:1722,1702,1801:20:133:2:0
|
PREMIERE 7,PREM 7;PREMIERE:11797:hC34:S19.2E:27500:1023:1024=deu:32:1722,1801,1702:20:133:2:0
|
||||||
DISNEY CHANNEL,DISNEY;PREMIERE:11758:hC34:S19.2E:27500:2559:2560=deu:0:1722,1702,1801:34:133:17:0
|
DISNEY CHANNEL,DISNEY;PREMIERE:11758:hC34:S19.2E:27500:2559:2560=deu:0:1722,1801,1702:34:133:17:0
|
||||||
:Premiere Direkt
|
:Premiere Direkt
|
||||||
PREMIERE DIREKT,DIREKT;PREMIERE:12031:hC34:S19.2E:27500:2815:2816=deu,2817=deu;2819=deu:0:0:18:133:4:0
|
PREMIERE DIREKT,DIREKT;PREMIERE:12031:hC34:S19.2E:27500:2815:2816=deu,2817=deu;2819=deu:0:0:18:133:4:0
|
||||||
:PW Erotic
|
:PW Erotic
|
||||||
BEATE-UHSE.TV,B-UHSE;PREMIERE:12070:hC34:S19.2E:27500:1023:1024=deu:32:1801,1702,1722:21:133:1:0
|
BEATE-UHSE.TV,B-UHSE;PREMIERE:12070:hC34:S19.2E:27500:1023:1024=deu:32:1702,1801,1722:21:133:1:0
|
||||||
DIREKT EROTIK,EROTIK;PREMIERE:12031:hC34:S19.2E:27500:1279:0:0:1722,1702,1801:513:133:4:0
|
DIREKT EROTIK,EROTIK;PREMIERE:12031:hC34:S19.2E:27500:1279:0:0:1722,1801,1702:513:133:4:0
|
||||||
:Sportsworld
|
:Sportsworld
|
||||||
Konferenz:11719:hC34:S19.2E:27500:255:256=deu,257=deu:32:1801,1702,1722:17:133:3:0
|
PREMIERE SPORT 1,SPORT 1;PREMIERE:11719:hC34:S19.2E:27500:255:256=deu,257=deu:32:1702,1722,1801:17:133:3:0
|
||||||
PREMIERE SPORT 2,SPORT 2;PREMIERE:12031:hC34:S19.2E:27500:3839:3840=deu,3841=deu:32:1722,1702,1801:27:133:4:0
|
PREMIERE SPORT 2,SPORT 2;PREMIERE:12031:hC34:S19.2E:27500:3839:3840=deu:32:1702,1801,1722:27:133:4:0
|
||||||
:Beta Digital
|
:Beta Digital
|
||||||
N24;ProSiebenSat.1:12480:vC34:S19.2E:27500:2047:2048=deu:36:0:47:133:33:0
|
N24;ProSiebenSat.1:12480:vC34:S19.2E:27500:2047:2048=deu:36:0:47:133:33:0
|
||||||
Liberty TV.com;Maastricht Multimedia:12610:vC56:S19.2E:22000:941:943=deu:0:0:12199:1:1112:0
|
LibertyTV FR;LibertyTV.com:12610:vC56:S19.2E:22000:941:943=deu:0:0:12199:1:1112:0
|
||||||
:-
|
:-
|
||||||
ProSieben Austria;ProSiebenSat.1:12051:vC34:S19.2E:27500:161:84=deu:36:0:20002:1:1082:0
|
ProSieben Austria;ProSiebenSat.1:12051:vC34:S19.2E:27500:161:84=deu:36:0:20002:1:1082:0
|
||||||
Kabel 1 Schweiz;ProSiebenSat.1:12051:vC34:S19.2E:27500:162:163=deu:165:0:20003:1:1082:0
|
Kabel 1 Schweiz;ProSiebenSat.1:12051:vC34:S19.2E:27500:162:163=deu:165:0:20003:1:1082:0
|
||||||
@ -94,14 +94,14 @@ ITV2;BSkyB:10906:vC56:S28.2E:22000:2350:2351=eng,2352=eng:2353:960,961:10240:2:2
|
|||||||
Sci-Fi;BSkyB:12148:hC23:S28.2E:27500:2314+2304:2315=eng:2316:960,961:4905:2:2023:0
|
Sci-Fi;BSkyB:12148:hC23:S28.2E:27500:2314+2304:2315=eng:2316:960,961:4905:2:2023:0
|
||||||
Paramount;BSkyB:12187:hC23:S28.2E:27500:2313+2304:2314=eng:2315:960,961:5904:2:2025:0
|
Paramount;BSkyB:12187:hC23:S28.2E:27500:2313+2304:2314=eng:2315:960,961:5904:2:2025:0
|
||||||
Discovery;BSkyB:11875:hC23:S28.2E:27500:2304:2306=eng,2307=NAR:2305:960,961:6201:2:2009:0
|
Discovery;BSkyB:11875:hC23:S28.2E:27500:2304:2306=eng,2307=NAR:2305:960,961:6201:2:2009:0
|
||||||
Sky Movies 1;BSkyB:11836:hC23:S28.2E:27500:2310+2304:2311=eng,2312=NAR;2314=eng:2313:960,961:4303:2:2007:0
|
Sky Movies 1;BSkyB:11836:hC23:S28.2E:27500:518+8190:646=eng,653=NAR;686=eng:582:960,961:4303:2:2007:0
|
||||||
Sky Movies 2;BSkyB:11836:hC23:S28.2E:27500:2305+2304:2306=eng,2307=NAR;2309=eng:2308:960,961:4302:2:2007:0
|
Sky Movies 2;BSkyB:11836:hC23:S28.2E:27500:519+8190:647=eng,667=NAR;687=eng:583:960,961:4302:2:2007:0
|
||||||
Sky Movies 3;BSkyB:11836:hC23:S28.2E:27500:2321+2304:2322=eng,2323=NAR;2325=eng:2324:960,961:4403:2:2007:0
|
Sky Movies 3;BSkyB:11836:hC23:S28.2E:27500:520+8190:648=eng,654=NAR;688=eng:584:960,961:4403:2:2007:0
|
||||||
Sky Movies 4;BSkyB:11914:hC23:S28.2E:27500:2305+2304:2306=eng,2307=NAR:2308:960,961:4402:2:2011:0
|
Sky Movies 4;BSkyB:11914:hC23:S28.2E:27500:512+8190:640=eng,660=NAR:576:960,961:4402:2:2011:0
|
||||||
Sky Movies 5;BSkyB:11914:hC23:S28.2E:27500:2313+2304:2314=eng,2315=NAR:2316:960,961:4503:2:2011:0
|
Sky Movies 5;BSkyB:11914:hC23:S28.2E:27500:515+8190:643=eng,663=NAR:579:960,961:4503:2:2011:0
|
||||||
Sky Movies 6;BSkyB:11914:hC23:S28.2E:27500:2309+2304:2310=eng,2311=NAR:2312:960,961:4502:2:2011:0
|
Sky Movies 6;BSkyB:11914:hC23:S28.2E:27500:513+8190:641=eng,661=NAR:577:960,961:4502:2:2011:0
|
||||||
Sky Movies 7;BSkyB:12090:vC23:S28.2E:27500:2312+2304:2313=eng,2314=NAR:2315:960,961:4603:2:2020:0
|
Sky Movies 7;BSkyB:12090:vC23:S28.2E:27500:2312+2304:2313=eng,2314=NAR:2315:960,961:4603:2:2020:0
|
||||||
Sky Movies 8;BSkyB:11836:hC23:S28.2E:27500:2326+2304:2327=eng,2328=NAR:2329:960,961:5502:2:2007:0
|
Sky Movies 8;BSkyB:11836:hC23:S28.2E:27500:515+8190:643=eng,663=NAR:579:960,961:5502:2:2007:0
|
||||||
Sky Movies 9;BSkyB:12090:vC23:S28.2E:27500:2308+2304:2309=eng,2310=NAR:2311:960,961:4602:2:2020:0
|
Sky Movies 9;BSkyB:12090:vC23:S28.2E:27500:2308+2304:2309=eng,2310=NAR:2311:960,961:4602:2:2020:0
|
||||||
Sky Cinema 1;BSkyB:12090:vC23:S28.2E:27500:2305+2304:2306=eng:2307:960,961:4809:2:2020:0
|
Sky Cinema 1;BSkyB:12090:vC23:S28.2E:27500:2305+2304:2306=eng:2307:960,961:4809:2:2020:0
|
||||||
Sky Cinema 2;BSkyB:12090:vC23:S28.2E:27500:2316+2304:2317=eng:2318:960,961:4802:2:2020:0
|
Sky Cinema 2;BSkyB:12090:vC23:S28.2E:27500:2316+2304:2317=eng:2318:960,961:4802:2:2020:0
|
||||||
@ -116,4 +116,5 @@ BBC PARL'MNT:12129:vC23:S28.2E:27500:2304:2306=eng,2307=eng:2305:0:7300:2:2022:0
|
|||||||
Olisat / Telefe;T-Systems/MTI:11200:vC56:S13.0E:27500:413:414=ita:0:0:4733:318:13400:0
|
Olisat / Telefe;T-Systems/MTI:11200:vC56:S13.0E:27500:413:414=ita:0:0:4733:318:13400:0
|
||||||
Euro1080;EURO1080:12168:vC34:S19.2E:27500:308:256:0:FF:21100:1:1088:0
|
Euro1080;EURO1080:12168:vC34:S19.2E:27500:308:256:0:FF:21100:1:1088:0
|
||||||
Astra HD:12441:vC34:S19.2E:27500:133+80:134:0:FF:29700:0:0:0
|
Astra HD:12441:vC34:S19.2E:27500:133+80:134:0:FF:29700:0:0:0
|
||||||
|
eng-WRN-multi;WRN:12597:vC34:S13.0E:27500:0:2132:0:0:8230:318:9400:0
|
||||||
:@1000 New channels
|
:@1000 New channels
|
||||||
|
@ -89,3 +89,26 @@ Sat.1:658000:I0C23D0M16B8T8G32Y0:T:27500:385:386:391:0:16408:0:0
|
|||||||
N24:658000:I0C23D0M16B8T8G32Y0:T:27500:225:226:231:0:16398:0:0
|
N24:658000:I0C23D0M16B8T8G32Y0:T:27500:225:226:231:0:16398:0:0
|
||||||
ProSieben:658000:I0C23D0M16B8T8G32Y0:T:27500:305:306:311:0:16403:0:0
|
ProSieben:658000:I0C23D0M16B8T8G32Y0:T:27500:305:306:311:0:16403:0:0
|
||||||
KABEL1:658000:I0C23D0M16B8T8G32Y0:T:27500:161:162:167:0:16394:0:0
|
KABEL1:658000:I0C23D0M16B8T8G32Y0:T:27500:161:162:167:0:16394:0:0
|
||||||
|
: DVB-T Lübeck, Germany
|
||||||
|
ZDF:490000:I999B8C23D23M16T8G4Y0:T:27500:545:546,547;559:551:0:514:0:0:0
|
||||||
|
Info/3sat:490000:I999B8C23D23M16T8G4Y0:T:27500:561:562,563:567:0:515:0:0:0
|
||||||
|
Doku/KiKa:490000:I999B8C23D23M16T8G4Y0:T:27500:593:594:599:0:517:0:0:0
|
||||||
|
Bayerisches Fernsehen:530000:I999B8C12D999M16T8G32Y0:T:27500:5185:5186:5188:0:34:0:0:0
|
||||||
|
MDR FERNSEHEN:530000:I999B8C12D999M16T8G32Y0:T:27500:5169:5170:5172:0:100:0:0:0
|
||||||
|
NDR FS NDS *:530000:I999B8C12D999M16T8G32Y0:T:27500:5137:5138:5140:0:129:0:0:0
|
||||||
|
NDR FS HH *:530000:I999B8C12D999M16T8G32Y0:T:27500:5137:5138:5140:0:130:0:0:0
|
||||||
|
NDR FS SH:530000:I999B8C12D999M16T8G32Y0:T:27500:5137:5138:5140:0:131:0:0:0
|
||||||
|
NDR FS MVP *:530000:I999B8C12D999M16T8G32Y0:T:27500:5137:5138:5140:0:132:0:0:0
|
||||||
|
WDR Köln:530000:I999B8C12D999M16T8G32Y0:T:27500:5153:5154:5156:0:262:0:0:0
|
||||||
|
N24:546000:I999B8C12D999M16T8G32Y0:T:27500:225:226:231:0:16398:0:0:0
|
||||||
|
ProSieben:546000:I999B8C12D999M16T8G32Y0:T:27500:305:306;312:311:0:16403:0:0:0
|
||||||
|
KABEL1:546000:I999B8C12D999M16T8G32Y0:T:27500:161:162:167:0:16394:0:0:0
|
||||||
|
SAT.1:546000:I999B8C12D999M16T8G32Y0:T:27500:385:386;392:391:0:16408:0:0:0
|
||||||
|
arte:570000:I999B8C12D999M16T8G32Y0:T:27500:4385:4386,4387:4388:0:2:0:0:0
|
||||||
|
Phoenix:570000:I999B8C12D999M16T8G32Y0:T:27500:4401:4402:4404:0:3:0:0:0
|
||||||
|
EinsExtra:570000:I999B8C12D999M16T8G32Y0:T:27500:4417:4418:0:0:4:0:0:0
|
||||||
|
Das Erste:570000:I999B8C12D999M16T8G32Y0:T:27500:4369:4370:4372:0:128:0:0:0
|
||||||
|
RTL Television:626000:I999B8C23D23M16T8G4Y0:T:27500:337:338:343:0:16405:0:0:0
|
||||||
|
RTL2:626000:I999B8C23D23M16T8G4Y0:T:27500:353:354:359:0:16406:0:0:0
|
||||||
|
Super RTL:626000:I999B8C23D23M16T8G4Y0:T:27500:369:370:375:0:16407:0:0:0
|
||||||
|
VOX:626000:I999B8C23D23M16T8G4Y0:T:27500:545:546:551:0:16418:0:0:0
|
||||||
|
21
channels.h
21
channels.h
@ -4,7 +4,7 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* how to reach the author.
|
||||||
*
|
*
|
||||||
* $Id: channels.h 1.22 2004/10/31 12:54:26 kls Exp $
|
* $Id: channels.h 1.24 2004/12/26 12:15:52 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __CHANNELS_H
|
#ifndef __CHANNELS_H
|
||||||
@ -67,7 +67,7 @@ public:
|
|||||||
tChannelID &ClrRid(void) { rid = 0; return *this; }
|
tChannelID &ClrRid(void) { rid = 0; return *this; }
|
||||||
tChannelID &ClrPolarization(void);
|
tChannelID &ClrPolarization(void);
|
||||||
static tChannelID FromString(const char *s);
|
static tChannelID FromString(const char *s);
|
||||||
const char *ToString(void);
|
cString ToString(void);
|
||||||
static const tChannelID InvalidID;
|
static const tChannelID InvalidID;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -87,8 +87,7 @@ class cLinkChannels : public cList<cLinkChannel> {
|
|||||||
class cChannel : public cListObject {
|
class cChannel : public cListObject {
|
||||||
friend class cMenuEditChannel;
|
friend class cMenuEditChannel;
|
||||||
private:
|
private:
|
||||||
static char *buffer;
|
static cString ToText(const cChannel *Channel);
|
||||||
static const char *ToText(const cChannel *Channel);
|
|
||||||
char *name;
|
char *name;
|
||||||
char *shortName;
|
char *shortName;
|
||||||
char *provider;
|
char *provider;
|
||||||
@ -124,14 +123,14 @@ private:
|
|||||||
int modification;
|
int modification;
|
||||||
cLinkChannels *linkChannels;
|
cLinkChannels *linkChannels;
|
||||||
cChannel *refChannel;
|
cChannel *refChannel;
|
||||||
const char *ParametersToString(void) const;
|
cString ParametersToString(void) const;
|
||||||
bool StringToParameters(const char *s);
|
bool StringToParameters(const char *s);
|
||||||
public:
|
public:
|
||||||
cChannel(void);
|
cChannel(void);
|
||||||
cChannel(const cChannel &Channel);
|
cChannel(const cChannel &Channel);
|
||||||
~cChannel();
|
~cChannel();
|
||||||
cChannel& operator= (const cChannel &Channel);
|
cChannel& operator= (const cChannel &Channel);
|
||||||
const char *ToText(void) const;
|
cString ToText(void) const;
|
||||||
bool Parse(const char *s, bool AllowNonUniqueID = false);
|
bool Parse(const char *s, bool AllowNonUniqueID = false);
|
||||||
bool Save(FILE *f);
|
bool Save(FILE *f);
|
||||||
const char *Name(void) const { return name; }
|
const char *Name(void) const { return name; }
|
||||||
@ -145,10 +144,10 @@ public:
|
|||||||
int Srate(void) const { return srate; }
|
int Srate(void) const { return srate; }
|
||||||
int Vpid(void) const { return vpid; }
|
int Vpid(void) const { return vpid; }
|
||||||
int Ppid(void) const { return ppid; }
|
int Ppid(void) const { return ppid; }
|
||||||
int Apid1(void) const { return apids[0]; }
|
int Apid(int i) const { return (0 <= i && i < MAXAPIDS) ? apids[i] : 0; }
|
||||||
int Apid2(void) const { return apids[1]; }
|
int Dpid(int i) const { return (0 <= i && i < MAXAPIDS) ? dpids[i] : 0; }
|
||||||
int Dpid1(void) const { return dpids[0]; }
|
const char *Alang(int i) const { return (0 <= i && i < MAXAPIDS) ? alangs[i] : ""; }
|
||||||
int Dpid2(void) const { return dpids[1]; }
|
const char *Dlang(int i) const { return (0 <= i && i < MAXAPIDS) ? dlangs[i] : ""; }
|
||||||
int Tpid(void) const { return tpid; }
|
int Tpid(void) const { return tpid; }
|
||||||
int Ca(int Index = 0) const { return Index < MAXCAIDS ? caids[Index] : 0; }
|
int Ca(int Index = 0) const { return Index < MAXCAIDS ? caids[Index] : 0; }
|
||||||
int Nid(void) const { return nid; }
|
int Nid(void) const { return nid; }
|
||||||
@ -216,6 +215,6 @@ public:
|
|||||||
|
|
||||||
extern cChannels Channels;
|
extern cChannels Channels;
|
||||||
|
|
||||||
const char *ChannelString(const cChannel *Channel, int Number);
|
cString ChannelString(const cChannel *Channel, int Number);
|
||||||
|
|
||||||
#endif //__CHANNELS_H
|
#endif //__CHANNELS_H
|
||||||
|
14
config.c
14
config.c
@ -4,7 +4,7 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* how to reach the author.
|
||||||
*
|
*
|
||||||
* $Id: config.c 1.128 2004/10/31 16:17:39 kls Exp $
|
* $Id: config.c 1.131 2005/01/09 12:14:58 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
@ -262,6 +262,7 @@ cSetup::cSetup(void)
|
|||||||
TimeTransponder = 0;
|
TimeTransponder = 0;
|
||||||
MarginStart = 2;
|
MarginStart = 2;
|
||||||
MarginStop = 10;
|
MarginStop = 10;
|
||||||
|
AudioLanguages[0] = -1;
|
||||||
EPGLanguages[0] = -1;
|
EPGLanguages[0] = -1;
|
||||||
EPGScanTimeout = 5;
|
EPGScanTimeout = 5;
|
||||||
EPGBugfixLevel = 2;
|
EPGBugfixLevel = 2;
|
||||||
@ -280,7 +281,7 @@ cSetup::cSetup(void)
|
|||||||
RecordingDirs = 1;
|
RecordingDirs = 1;
|
||||||
VideoFormat = 0;
|
VideoFormat = 0;
|
||||||
UpdateChannels = 4;
|
UpdateChannels = 4;
|
||||||
RecordDolbyDigital = 1;
|
UseDolbyDigital = 1;
|
||||||
ChannelInfoPos = 0;
|
ChannelInfoPos = 0;
|
||||||
OSDLeft = 54;
|
OSDLeft = 54;
|
||||||
OSDTop = 45;
|
OSDTop = 45;
|
||||||
@ -297,6 +298,7 @@ cSetup::cSetup(void)
|
|||||||
ResumeID = 0;
|
ResumeID = 0;
|
||||||
CurrentChannel = -1;
|
CurrentChannel = -1;
|
||||||
CurrentVolume = MAXVOLUME;
|
CurrentVolume = MAXVOLUME;
|
||||||
|
CurrentDolby = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
cSetup& cSetup::operator= (const cSetup &s)
|
cSetup& cSetup::operator= (const cSetup &s)
|
||||||
@ -415,6 +417,7 @@ bool cSetup::Parse(const char *Name, const char *Value)
|
|||||||
else if (!strcasecmp(Name, "TimeTransponder")) TimeTransponder = atoi(Value);
|
else if (!strcasecmp(Name, "TimeTransponder")) TimeTransponder = atoi(Value);
|
||||||
else if (!strcasecmp(Name, "MarginStart")) MarginStart = atoi(Value);
|
else if (!strcasecmp(Name, "MarginStart")) MarginStart = atoi(Value);
|
||||||
else if (!strcasecmp(Name, "MarginStop")) MarginStop = atoi(Value);
|
else if (!strcasecmp(Name, "MarginStop")) MarginStop = atoi(Value);
|
||||||
|
else if (!strcasecmp(Name, "AudioLanguages")) return ParseLanguages(Value, AudioLanguages);
|
||||||
else if (!strcasecmp(Name, "EPGLanguages")) return ParseLanguages(Value, EPGLanguages);
|
else if (!strcasecmp(Name, "EPGLanguages")) return ParseLanguages(Value, EPGLanguages);
|
||||||
else if (!strcasecmp(Name, "EPGScanTimeout")) EPGScanTimeout = atoi(Value);
|
else if (!strcasecmp(Name, "EPGScanTimeout")) EPGScanTimeout = atoi(Value);
|
||||||
else if (!strcasecmp(Name, "EPGBugfixLevel")) EPGBugfixLevel = atoi(Value);
|
else if (!strcasecmp(Name, "EPGBugfixLevel")) EPGBugfixLevel = atoi(Value);
|
||||||
@ -433,7 +436,7 @@ bool cSetup::Parse(const char *Name, const char *Value)
|
|||||||
else if (!strcasecmp(Name, "RecordingDirs")) RecordingDirs = atoi(Value);
|
else if (!strcasecmp(Name, "RecordingDirs")) RecordingDirs = atoi(Value);
|
||||||
else if (!strcasecmp(Name, "VideoFormat")) VideoFormat = atoi(Value);
|
else if (!strcasecmp(Name, "VideoFormat")) VideoFormat = atoi(Value);
|
||||||
else if (!strcasecmp(Name, "UpdateChannels")) UpdateChannels = atoi(Value);
|
else if (!strcasecmp(Name, "UpdateChannels")) UpdateChannels = atoi(Value);
|
||||||
else if (!strcasecmp(Name, "RecordDolbyDigital")) RecordDolbyDigital = atoi(Value);
|
else if (!strcasecmp(Name, "UseDolbyDigital")) UseDolbyDigital = atoi(Value);
|
||||||
else if (!strcasecmp(Name, "ChannelInfoPos")) ChannelInfoPos = atoi(Value);
|
else if (!strcasecmp(Name, "ChannelInfoPos")) ChannelInfoPos = atoi(Value);
|
||||||
else if (!strcasecmp(Name, "OSDLeft")) OSDLeft = atoi(Value);
|
else if (!strcasecmp(Name, "OSDLeft")) OSDLeft = atoi(Value);
|
||||||
else if (!strcasecmp(Name, "OSDTop")) OSDTop = atoi(Value);
|
else if (!strcasecmp(Name, "OSDTop")) OSDTop = atoi(Value);
|
||||||
@ -450,6 +453,7 @@ bool cSetup::Parse(const char *Name, const char *Value)
|
|||||||
else if (!strcasecmp(Name, "ResumeID")) ResumeID = atoi(Value);
|
else if (!strcasecmp(Name, "ResumeID")) ResumeID = atoi(Value);
|
||||||
else if (!strcasecmp(Name, "CurrentChannel")) CurrentChannel = atoi(Value);
|
else if (!strcasecmp(Name, "CurrentChannel")) CurrentChannel = atoi(Value);
|
||||||
else if (!strcasecmp(Name, "CurrentVolume")) CurrentVolume = atoi(Value);
|
else if (!strcasecmp(Name, "CurrentVolume")) CurrentVolume = atoi(Value);
|
||||||
|
else if (!strcasecmp(Name, "CurrentDolby")) CurrentDolby = atoi(Value);
|
||||||
else
|
else
|
||||||
return false;
|
return false;
|
||||||
return true;
|
return true;
|
||||||
@ -475,6 +479,7 @@ bool cSetup::Save(void)
|
|||||||
Store("TimeTransponder", TimeTransponder);
|
Store("TimeTransponder", TimeTransponder);
|
||||||
Store("MarginStart", MarginStart);
|
Store("MarginStart", MarginStart);
|
||||||
Store("MarginStop", MarginStop);
|
Store("MarginStop", MarginStop);
|
||||||
|
StoreLanguages("AudioLanguages", AudioLanguages);
|
||||||
StoreLanguages("EPGLanguages", EPGLanguages);
|
StoreLanguages("EPGLanguages", EPGLanguages);
|
||||||
Store("EPGScanTimeout", EPGScanTimeout);
|
Store("EPGScanTimeout", EPGScanTimeout);
|
||||||
Store("EPGBugfixLevel", EPGBugfixLevel);
|
Store("EPGBugfixLevel", EPGBugfixLevel);
|
||||||
@ -493,7 +498,7 @@ bool cSetup::Save(void)
|
|||||||
Store("RecordingDirs", RecordingDirs);
|
Store("RecordingDirs", RecordingDirs);
|
||||||
Store("VideoFormat", VideoFormat);
|
Store("VideoFormat", VideoFormat);
|
||||||
Store("UpdateChannels", UpdateChannels);
|
Store("UpdateChannels", UpdateChannels);
|
||||||
Store("RecordDolbyDigital", RecordDolbyDigital);
|
Store("UseDolbyDigital", UseDolbyDigital);
|
||||||
Store("ChannelInfoPos", ChannelInfoPos);
|
Store("ChannelInfoPos", ChannelInfoPos);
|
||||||
Store("OSDLeft", OSDLeft);
|
Store("OSDLeft", OSDLeft);
|
||||||
Store("OSDTop", OSDTop);
|
Store("OSDTop", OSDTop);
|
||||||
@ -510,6 +515,7 @@ bool cSetup::Save(void)
|
|||||||
Store("ResumeID", ResumeID);
|
Store("ResumeID", ResumeID);
|
||||||
Store("CurrentChannel", CurrentChannel);
|
Store("CurrentChannel", CurrentChannel);
|
||||||
Store("CurrentVolume", CurrentVolume);
|
Store("CurrentVolume", CurrentVolume);
|
||||||
|
Store("CurrentDolby", CurrentDolby);
|
||||||
|
|
||||||
Sort();
|
Sort();
|
||||||
|
|
||||||
|
10
config.h
10
config.h
@ -4,7 +4,7 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* how to reach the author.
|
||||||
*
|
*
|
||||||
* $Id: config.h 1.205 2004/11/16 16:57:43 kls Exp $
|
* $Id: config.h 1.209 2005/01/09 12:14:33 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __CONFIG_H
|
#ifndef __CONFIG_H
|
||||||
@ -20,8 +20,8 @@
|
|||||||
#include "i18n.h"
|
#include "i18n.h"
|
||||||
#include "tools.h"
|
#include "tools.h"
|
||||||
|
|
||||||
#define VDRVERSION "1.3.17"
|
#define VDRVERSION "1.3.18"
|
||||||
#define VDRVERSNUM 10317 // Version * 10000 + Major * 100 + Minor
|
#define VDRVERSNUM 10318 // Version * 10000 + Major * 100 + Minor
|
||||||
|
|
||||||
#define MAXPRIORITY 99
|
#define MAXPRIORITY 99
|
||||||
#define MAXLIFETIME 99
|
#define MAXLIFETIME 99
|
||||||
@ -222,6 +222,7 @@ public:
|
|||||||
int TimeSource;
|
int TimeSource;
|
||||||
int TimeTransponder;
|
int TimeTransponder;
|
||||||
int MarginStart, MarginStop;
|
int MarginStart, MarginStop;
|
||||||
|
int AudioLanguages[I18nNumLanguages + 1];
|
||||||
int EPGLanguages[I18nNumLanguages + 1];
|
int EPGLanguages[I18nNumLanguages + 1];
|
||||||
int EPGScanTimeout;
|
int EPGScanTimeout;
|
||||||
int EPGBugfixLevel;
|
int EPGBugfixLevel;
|
||||||
@ -238,7 +239,7 @@ public:
|
|||||||
int RecordingDirs;
|
int RecordingDirs;
|
||||||
int VideoFormat;
|
int VideoFormat;
|
||||||
int UpdateChannels;
|
int UpdateChannels;
|
||||||
int RecordDolbyDigital;
|
int UseDolbyDigital;
|
||||||
int ChannelInfoPos;
|
int ChannelInfoPos;
|
||||||
int OSDLeft, OSDTop, OSDWidth, OSDHeight;
|
int OSDLeft, OSDTop, OSDWidth, OSDHeight;
|
||||||
int OSDMessageTime;
|
int OSDMessageTime;
|
||||||
@ -251,6 +252,7 @@ public:
|
|||||||
int ResumeID;
|
int ResumeID;
|
||||||
int CurrentChannel;
|
int CurrentChannel;
|
||||||
int CurrentVolume;
|
int CurrentVolume;
|
||||||
|
int CurrentDolby;
|
||||||
int __EndData__;
|
int __EndData__;
|
||||||
cSetup(void);
|
cSetup(void);
|
||||||
cSetup& operator= (const cSetup &s);
|
cSetup& operator= (const cSetup &s);
|
||||||
|
320
device.c
320
device.c
@ -4,7 +4,7 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* how to reach the author.
|
||||||
*
|
*
|
||||||
* $Id: device.c 1.62 2004/10/30 14:53:38 kls Exp $
|
* $Id: device.c 1.73 2005/01/09 12:36:48 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "device.h"
|
#include "device.h"
|
||||||
@ -19,6 +19,87 @@
|
|||||||
#include "status.h"
|
#include "status.h"
|
||||||
#include "transfer.h"
|
#include "transfer.h"
|
||||||
|
|
||||||
|
// --- cPesAssembler ---------------------------------------------------------
|
||||||
|
|
||||||
|
class cPesAssembler {
|
||||||
|
private:
|
||||||
|
uchar *data;
|
||||||
|
uint32_t tag;
|
||||||
|
int length;
|
||||||
|
int size;
|
||||||
|
bool Realloc(int Size);
|
||||||
|
public:
|
||||||
|
cPesAssembler(void);
|
||||||
|
~cPesAssembler();
|
||||||
|
int ExpectedLength(void) { return data[4] * 256 + data[5] + 6; }
|
||||||
|
int Length(void) { return length; }
|
||||||
|
const uchar *Data(void) { return data; }
|
||||||
|
void Reset(void);
|
||||||
|
void Put(uchar c);
|
||||||
|
void Put(const uchar *Data, int Length);
|
||||||
|
bool IsPes(void);
|
||||||
|
};
|
||||||
|
|
||||||
|
cPesAssembler::cPesAssembler(void)
|
||||||
|
{
|
||||||
|
data = NULL;
|
||||||
|
size = 0;
|
||||||
|
Reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
cPesAssembler::~cPesAssembler()
|
||||||
|
{
|
||||||
|
free(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
void cPesAssembler::Reset(void)
|
||||||
|
{
|
||||||
|
tag = 0xFFFFFFFF;
|
||||||
|
length = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool cPesAssembler::Realloc(int Size)
|
||||||
|
{
|
||||||
|
if (Size > size) {
|
||||||
|
size = max(Size, 2048);
|
||||||
|
data = (uchar *)realloc(data, size);
|
||||||
|
if (!data) {
|
||||||
|
esyslog("ERROR: can't allocate memory for PES assembler");
|
||||||
|
length = 0;
|
||||||
|
size = 0;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void cPesAssembler::Put(uchar c)
|
||||||
|
{
|
||||||
|
if (!length) {
|
||||||
|
tag = (tag << 8) | c;
|
||||||
|
if ((tag & 0xFFFFFF00) == 0x00000100) {
|
||||||
|
if (Realloc(4)) {
|
||||||
|
*(uint32_t *)data = htonl(tag);
|
||||||
|
length = 4;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (Realloc(length + 1))
|
||||||
|
data[length++] = c;
|
||||||
|
}
|
||||||
|
|
||||||
|
void cPesAssembler::Put(const uchar *Data, int Length)
|
||||||
|
{
|
||||||
|
while (!length && Length > 0) {
|
||||||
|
Put(*Data++);
|
||||||
|
Length--;
|
||||||
|
}
|
||||||
|
if (Length && Realloc(length + Length)) {
|
||||||
|
memcpy(data + length, Data, Length);
|
||||||
|
length += Length;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// --- cDevice ---------------------------------------------------------------
|
// --- cDevice ---------------------------------------------------------------
|
||||||
|
|
||||||
// The default priority for non-primary devices:
|
// The default priority for non-primary devices:
|
||||||
@ -53,6 +134,9 @@ cDevice::cDevice(void)
|
|||||||
|
|
||||||
ciHandler = NULL;
|
ciHandler = NULL;
|
||||||
player = NULL;
|
player = NULL;
|
||||||
|
pesAssembler = new cPesAssembler;
|
||||||
|
ClrAvailableTracks();
|
||||||
|
currentAudioTrack = ttAudioFirst;
|
||||||
|
|
||||||
for (int i = 0; i < MAXRECEIVERS; i++)
|
for (int i = 0; i < MAXRECEIVERS; i++)
|
||||||
receiver[i] = NULL;
|
receiver[i] = NULL;
|
||||||
@ -74,6 +158,7 @@ cDevice::~cDevice()
|
|||||||
delete patFilter;
|
delete patFilter;
|
||||||
delete eitFilter;
|
delete eitFilter;
|
||||||
delete sectionHandler;
|
delete sectionHandler;
|
||||||
|
delete pesAssembler;
|
||||||
}
|
}
|
||||||
|
|
||||||
void cDevice::SetUseDevice(int n)
|
void cDevice::SetUseDevice(int n)
|
||||||
@ -427,7 +512,7 @@ eSetChannelResult cDevice::SetChannel(const cChannel *Channel, bool LiveView)
|
|||||||
if (CaDevice && CanReplay()) {
|
if (CaDevice && CanReplay()) {
|
||||||
cStatus::MsgChannelSwitch(this, 0); // only report status if we are actually going to switch the channel
|
cStatus::MsgChannelSwitch(this, 0); // only report status if we are actually going to switch the channel
|
||||||
if (CaDevice->SetChannel(Channel, false) == scrOk) // calling SetChannel() directly, not SwitchChannel()!
|
if (CaDevice->SetChannel(Channel, false) == scrOk) // calling SetChannel() directly, not SwitchChannel()!
|
||||||
cControl::Launch(new cTransferControl(CaDevice, Channel->Vpid(), Channel->Apid1(), Channel->Apid2(), Channel->Dpid1(), Channel->Dpid2()));//XXX+
|
cControl::Launch(new cTransferControl(CaDevice, Channel->Vpid(), Channel->Apid(0), Channel->Apid(1), Channel->Dpid(0), Channel->Dpid(1)));
|
||||||
else
|
else
|
||||||
Result = scrNoTransfer;
|
Result = scrNoTransfer;
|
||||||
}
|
}
|
||||||
@ -455,8 +540,35 @@ eSetChannelResult cDevice::SetChannel(const cChannel *Channel, bool LiveView)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (Result == scrOk) {
|
if (Result == scrOk) {
|
||||||
if (LiveView && IsPrimaryDevice())
|
if (LiveView && IsPrimaryDevice()) {
|
||||||
currentChannel = Channel->Number();
|
currentChannel = Channel->Number();
|
||||||
|
// Set the available audio tracks:
|
||||||
|
ClrAvailableTracks();
|
||||||
|
currentAudioTrack = ttAudioFirst;
|
||||||
|
for (int i = 0; i < MAXAPIDS; i++) {
|
||||||
|
SetAvailableTrack(ttAudio, i, Channel->Apid(i), Channel->Alang(i));
|
||||||
|
if (Setup.UseDolbyDigital)
|
||||||
|
SetAvailableTrack(ttDolby, i, Channel->Dpid(i), Channel->Dlang(i));
|
||||||
|
}
|
||||||
|
// Select the preferred audio track:
|
||||||
|
eTrackType PreferredTrack = ttAudioFirst;
|
||||||
|
int LanguagePreference = -1;
|
||||||
|
int StartCheck = Setup.CurrentDolby ? ttDolbyFirst : ttAudioFirst;
|
||||||
|
int EndCheck = ttDolbyLast;
|
||||||
|
for (int i = StartCheck; i <= EndCheck; i++) {
|
||||||
|
const tTrackId *TrackId = GetTrack(eTrackType(i));
|
||||||
|
if (TrackId && TrackId->id && I18nIsPreferredLanguage(Setup.AudioLanguages, I18nLanguageIndex(TrackId->language), LanguagePreference))
|
||||||
|
PreferredTrack = eTrackType(i);
|
||||||
|
if (Setup.CurrentDolby && i == ttDolbyLast) {
|
||||||
|
i = ttAudioFirst - 1;
|
||||||
|
EndCheck = ttAudioLast;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Make sure we're set to an available audio track:
|
||||||
|
const tTrackId *Track = GetTrack(GetCurrentAudioTrack());
|
||||||
|
if (!Track || !Track->id || PreferredTrack != GetCurrentAudioTrack())
|
||||||
|
SetCurrentAudioTrack(PreferredTrack);
|
||||||
|
}
|
||||||
cStatus::MsgChannelSwitch(this, Channel->Number()); // only report status if channel switch successfull
|
cStatus::MsgChannelSwitch(this, Channel->Number()); // only report status if channel switch successfull
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -478,21 +590,24 @@ bool cDevice::HasProgramme(void)
|
|||||||
return Replaying() || pidHandles[ptAudio].pid || pidHandles[ptVideo].pid;
|
return Replaying() || pidHandles[ptAudio].pid || pidHandles[ptVideo].pid;
|
||||||
}
|
}
|
||||||
|
|
||||||
void cDevice::SetVolumeDevice(int Volume)
|
int cDevice::GetAudioChannelDevice(void)
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
int cDevice::NumAudioTracksDevice(void) const
|
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char **cDevice::GetAudioTracksDevice(int *CurrentTrack) const
|
void cDevice::SetAudioChannelDevice(int AudioChannel)
|
||||||
{
|
{
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void cDevice::SetAudioTrackDevice(int Index)
|
void cDevice::SetVolumeDevice(int Volume)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void cDevice::SetDigitalAudioDevice(bool On)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void cDevice::SetAudioTrackDevice(eTrackType Type)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -513,6 +628,18 @@ bool cDevice::ToggleMute(void)
|
|||||||
return mute;
|
return mute;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int cDevice::GetAudioChannel(void)
|
||||||
|
{
|
||||||
|
int c = GetAudioChannelDevice();
|
||||||
|
return (0 <= c && c <= 2) ? c : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void cDevice::SetAudioChannel(int AudioChannel)
|
||||||
|
{
|
||||||
|
if (0 <= AudioChannel && AudioChannel <= 2)
|
||||||
|
SetAudioChannelDevice(AudioChannel);
|
||||||
|
}
|
||||||
|
|
||||||
void cDevice::SetVolume(int Volume, bool Absolute)
|
void cDevice::SetVolume(int Volume, bool Absolute)
|
||||||
{
|
{
|
||||||
volume = min(max(Absolute ? Volume : volume + Volume, 0), MAXVOLUME);
|
volume = min(max(Absolute ? Volume : volume + Volume, 0), MAXVOLUME);
|
||||||
@ -524,22 +651,66 @@ void cDevice::SetVolume(int Volume, bool Absolute)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void cDevice::ClrAvailableTracks(bool DescriptionsOnly)
|
||||||
|
{
|
||||||
|
if (DescriptionsOnly) {
|
||||||
|
for (int i = ttNone; i < ttMaxTrackTypes; i++)
|
||||||
|
*availableTracks[i].description = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
memset(availableTracks, 0, sizeof(availableTracks));
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
esyslog("ERROR: SetAvailableTrack called with invalid Type/Index (%d/%d)", Type, Index);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const tTrackId *cDevice::GetTrack(eTrackType Type)
|
||||||
|
{
|
||||||
|
return (ttNone < Type && Type < ttMaxTrackTypes) ? &availableTracks[Type] : NULL;
|
||||||
|
}
|
||||||
|
|
||||||
int cDevice::NumAudioTracks(void) const
|
int cDevice::NumAudioTracks(void) const
|
||||||
{
|
{
|
||||||
return player ? player->NumAudioTracks() : NumAudioTracksDevice();
|
int n = 0;
|
||||||
|
for (int i = ttAudioFirst; i <= ttDolbyLast; i++) {
|
||||||
|
if (availableTracks[i].id)
|
||||||
|
n++;
|
||||||
|
}
|
||||||
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char **cDevice::GetAudioTracks(int *CurrentTrack) const
|
bool cDevice::SetCurrentAudioTrack(eTrackType Type)
|
||||||
{
|
{
|
||||||
return player ? player->GetAudioTracks(CurrentTrack) : GetAudioTracksDevice(CurrentTrack);
|
if (ttNone < Type && Type < ttDolbyLast) {
|
||||||
}
|
if (IS_DOLBY_TRACK(Type))
|
||||||
|
SetDigitalAudioDevice(true);
|
||||||
void cDevice::SetAudioTrack(int Index)
|
currentAudioTrack = Type;
|
||||||
{
|
if (player)
|
||||||
if (player)
|
player->SetAudioTrack(currentAudioTrack, GetTrack(currentAudioTrack));
|
||||||
player->SetAudioTrack(Index);
|
else
|
||||||
else
|
SetAudioTrackDevice(currentAudioTrack);
|
||||||
SetAudioTrackDevice(Index);
|
if (IS_AUDIO_TRACK(Type))
|
||||||
|
SetDigitalAudioDevice(false);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool cDevice::CanReplay(void) const
|
bool cDevice::CanReplay(void) const
|
||||||
@ -595,6 +766,7 @@ bool cDevice::AttachPlayer(cPlayer *Player)
|
|||||||
if (CanReplay()) {
|
if (CanReplay()) {
|
||||||
if (player)
|
if (player)
|
||||||
Detach(player);
|
Detach(player);
|
||||||
|
ClrAvailableTracks();
|
||||||
player = Player;
|
player = Player;
|
||||||
SetPlayMode(player->playMode);
|
SetPlayMode(player->playMode);
|
||||||
player->device = this;
|
player->device = this;
|
||||||
@ -639,11 +811,107 @@ int cDevice::PlayVideo(const uchar *Data, int Length)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void cDevice::PlayAudio(const uchar *Data, int Length)
|
int cDevice::PlayAudio(const uchar *Data, int Length)
|
||||||
{
|
{
|
||||||
Audios.PlayAudio(Data, Length);
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int cDevice::PlayPesPacket(const uchar *Data, int Length, bool VideoOnly)
|
||||||
|
{
|
||||||
|
bool FirstLoop = true;
|
||||||
|
uchar c = Data[3];
|
||||||
|
const uchar *Start = Data;
|
||||||
|
const uchar *End = Start + Length;
|
||||||
|
while (Start < End) {
|
||||||
|
int d = End - Start;
|
||||||
|
int w = d;
|
||||||
|
switch (c) {
|
||||||
|
case 0xE0 ... 0xEF: // video
|
||||||
|
w = PlayVideo(Start, d);
|
||||||
|
break;
|
||||||
|
case 0xC0 ... 0xDF: // audio
|
||||||
|
SetAvailableTrack(ttAudio, c - 0xC0, c);
|
||||||
|
if (!VideoOnly && c == availableTracks[currentAudioTrack].id)
|
||||||
|
w = PlayAudio(Start, d);
|
||||||
|
break;
|
||||||
|
case 0xBD: // dolby
|
||||||
|
if (Setup.UseDolbyDigital) {
|
||||||
|
SetAvailableTrack(ttDolby, 0, c);
|
||||||
|
if (!VideoOnly && c == availableTracks[currentAudioTrack].id) {
|
||||||
|
w = PlayAudio(Start, d);
|
||||||
|
if (FirstLoop)
|
||||||
|
Audios.PlayAudio(Data, Length);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
;//esyslog("ERROR: unexpected packet id %02X", c);
|
||||||
|
}
|
||||||
|
if (w > 0)
|
||||||
|
Start += w;
|
||||||
|
else if (w <= 0) {
|
||||||
|
if (Start != Data)
|
||||||
|
esyslog("ERROR: incomplete PES packet write!");
|
||||||
|
return Start == Data ? w : Start - Data;
|
||||||
|
}
|
||||||
|
FirstLoop = false;
|
||||||
|
}
|
||||||
|
return Length;
|
||||||
|
}
|
||||||
|
|
||||||
|
int cDevice::PlayPes(const uchar *Data, int Length, bool VideoOnly)
|
||||||
|
{
|
||||||
|
if (!Data) {
|
||||||
|
pesAssembler->Reset();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
int Result = 0;
|
||||||
|
if (pesAssembler->Length()) {
|
||||||
|
// Make sure we have a complete PES header:
|
||||||
|
while (pesAssembler->Length() < 6 && Length > 0) {
|
||||||
|
pesAssembler->Put(*Data++);
|
||||||
|
Length--;
|
||||||
|
Result++;
|
||||||
|
}
|
||||||
|
if (pesAssembler->Length() < 6)
|
||||||
|
return Result; // Still no complete PES header - wait for more
|
||||||
|
int l = pesAssembler->ExpectedLength();
|
||||||
|
int Rest = min(l - pesAssembler->Length(), Length);
|
||||||
|
pesAssembler->Put(Data, Rest);
|
||||||
|
Data += Rest;
|
||||||
|
Length -= Rest;
|
||||||
|
Result += Rest;
|
||||||
|
if (pesAssembler->Length() < l)
|
||||||
|
return Result; // Still no complete PES packet - wait for more
|
||||||
|
// Now pesAssembler contains one complete PES packet.
|
||||||
|
int w = PlayPesPacket(pesAssembler->Data(), pesAssembler->Length(), VideoOnly);
|
||||||
|
if (w > 0)
|
||||||
|
pesAssembler->Reset();
|
||||||
|
return Result > 0 ? Result : w < 0 ? w : 0;
|
||||||
|
}
|
||||||
|
int i = 0;
|
||||||
|
while (i <= Length - 6) {
|
||||||
|
if (Data[i] == 0x00 && Data[i + 1] == 0x00 && Data[i + 2] == 0x01) {
|
||||||
|
int l = Data[i + 4] * 256 + Data[i + 5] + 6;
|
||||||
|
if (i + l > Length) {
|
||||||
|
// Store incomplete PES packet for later completion:
|
||||||
|
pesAssembler->Put(Data + i, Length - i);
|
||||||
|
return Length;
|
||||||
|
}
|
||||||
|
int w = PlayPesPacket(Data + i, l, VideoOnly);
|
||||||
|
if (w > 0)
|
||||||
|
i += l;
|
||||||
|
else if (w < 0)
|
||||||
|
return i == 0 ? w : i;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
if (i < Length)
|
||||||
|
pesAssembler->Put(Data + i, Length - i);
|
||||||
|
return Length;
|
||||||
|
}
|
||||||
|
|
||||||
int cDevice::Ca(void) const
|
int cDevice::Ca(void) const
|
||||||
{
|
{
|
||||||
int ca = 0;
|
int ca = 0;
|
||||||
@ -722,8 +990,8 @@ bool cDevice::Receiving(bool CheckAny) const
|
|||||||
|
|
||||||
void cDevice::Action(void)
|
void cDevice::Action(void)
|
||||||
{
|
{
|
||||||
|
active = true;
|
||||||
if (OpenDvr()) {
|
if (OpenDvr()) {
|
||||||
active = true;
|
|
||||||
for (; active;) {
|
for (; active;) {
|
||||||
// Read data from the DVR device:
|
// Read data from the DVR device:
|
||||||
uchar *b = NULL;
|
uchar *b = NULL;
|
||||||
@ -770,6 +1038,7 @@ bool cDevice::AttachReceiver(cReceiver *Receiver)
|
|||||||
esyslog("ERROR: device %d has no lock, can't attach receiver!", CardIndex() + 1);
|
esyslog("ERROR: device %d has no lock, can't attach receiver!", CardIndex() + 1);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
cMutexLock MutexLock(&mutexReceiver);
|
||||||
for (int i = 0; i < MAXRECEIVERS; i++) {
|
for (int i = 0; i < MAXRECEIVERS; i++) {
|
||||||
if (!receiver[i]) {
|
if (!receiver[i]) {
|
||||||
for (int n = 0; n < MAXRECEIVEPIDS; n++) {
|
for (int n = 0; n < MAXRECEIVEPIDS; n++) {
|
||||||
@ -797,6 +1066,7 @@ void cDevice::Detach(cReceiver *Receiver)
|
|||||||
if (!Receiver || Receiver->device != this)
|
if (!Receiver || Receiver->device != this)
|
||||||
return;
|
return;
|
||||||
bool receiversLeft = false;
|
bool receiversLeft = false;
|
||||||
|
cMutexLock MutexLock(&mutexReceiver);
|
||||||
for (int i = 0; i < MAXRECEIVERS; i++) {
|
for (int i = 0; i < MAXRECEIVERS; i++) {
|
||||||
if (receiver[i] == Receiver) {
|
if (receiver[i] == Receiver) {
|
||||||
Receiver->Activate(false);
|
Receiver->Activate(false);
|
||||||
|
147
device.h
147
device.h
@ -4,7 +4,7 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* how to reach the author.
|
||||||
*
|
*
|
||||||
* $Id: device.h 1.46 2004/10/30 14:49:56 kls Exp $
|
* $Id: device.h 1.51 2005/01/07 14:57:01 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __DEVICE_H
|
#ifndef __DEVICE_H
|
||||||
@ -56,10 +56,37 @@ enum eVideoSystem { vsPAL,
|
|||||||
vsNTSC
|
vsNTSC
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum eTrackType { ttNone,
|
||||||
|
ttAudio,
|
||||||
|
ttAudioFirst = ttAudio,
|
||||||
|
ttAudioLast = ttAudioFirst + 31/*XXX MAXAPIDS - 1*/,
|
||||||
|
ttDolby,
|
||||||
|
ttDolbyFirst = ttDolby,
|
||||||
|
ttDolbyLast = ttDolbyFirst + 31/*XXX MAXAPIDS - 1*/,
|
||||||
|
/* future...
|
||||||
|
ttSubtitle,
|
||||||
|
ttSubtitleFirst = ttSubtitle,
|
||||||
|
ttSubtitleLast = ttSubtitleFirst + 31,
|
||||||
|
*/
|
||||||
|
ttMaxTrackTypes
|
||||||
|
};
|
||||||
|
|
||||||
|
#define IS_AUDIO_TRACK(t) (ttAudioFirst <= (t) && (t) <= ttAudioLast)
|
||||||
|
#define IS_DOLBY_TRACK(t) (ttDolbyFirst <= (t) && (t) <= ttDolbyLast)
|
||||||
|
|
||||||
|
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.
|
||||||
|
};
|
||||||
|
|
||||||
class cChannel;
|
class cChannel;
|
||||||
class cPlayer;
|
class cPlayer;
|
||||||
class cReceiver;
|
class cReceiver;
|
||||||
class cSpuDecoder;
|
class cSpuDecoder;
|
||||||
|
class cPesAssembler;
|
||||||
|
|
||||||
/// The cDevice class is the base from which actual devices can be derived.
|
/// The cDevice class is the base from which actual devices can be derived.
|
||||||
|
|
||||||
@ -283,69 +310,96 @@ public:
|
|||||||
///< Returns the video system of the currently displayed material
|
///< Returns the video system of the currently displayed material
|
||||||
///< (default is PAL).
|
///< (default is PAL).
|
||||||
|
|
||||||
|
// Track facilities
|
||||||
|
|
||||||
|
private:
|
||||||
|
tTrackId availableTracks[ttMaxTrackTypes];
|
||||||
|
eTrackType currentAudioTrack;
|
||||||
|
protected:
|
||||||
|
virtual void SetAudioTrackDevice(eTrackType Type);
|
||||||
|
///< Sets the current audio track to the given value.
|
||||||
|
public:
|
||||||
|
void ClrAvailableTracks(bool DescriptionsOnly = false);
|
||||||
|
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
|
||||||
|
///< less than ttMaxTrackTypes.
|
||||||
|
int NumAudioTracks(void) const;
|
||||||
|
///< Returns the number of audio tracks that are currently available.
|
||||||
|
///< This is just for information, to quickly find out whether there
|
||||||
|
///< is more than one audio track.
|
||||||
|
eTrackType GetCurrentAudioTrack(void) { return currentAudioTrack; }
|
||||||
|
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.
|
||||||
|
|
||||||
// Audio facilities
|
// Audio facilities
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool mute;
|
bool mute;
|
||||||
int volume;
|
int volume;
|
||||||
protected:
|
protected:
|
||||||
|
virtual int GetAudioChannelDevice(void);
|
||||||
|
///< Gets the current audio channel, which is stereo (0), mono left (1) or
|
||||||
|
///< mono right (2).
|
||||||
|
virtual void SetAudioChannelDevice(int AudioChannel);
|
||||||
|
///< Sets the audio channel to stereo (0), mono left (1) or mono right (2).
|
||||||
virtual void SetVolumeDevice(int Volume);
|
virtual void SetVolumeDevice(int Volume);
|
||||||
///< Sets the audio volume on this device (Volume = 0...255).
|
///< Sets the audio volume on this device (Volume = 0...255).
|
||||||
virtual int NumAudioTracksDevice(void) const;
|
virtual void SetDigitalAudioDevice(bool On);
|
||||||
///< Returns the number of audio tracks that are currently available on this
|
///< Tells the actual device that digital audio output shall be switched
|
||||||
///< device. The default return value is 0, meaning that this device
|
///< on or off.
|
||||||
///< doesn't have multiple audio track capabilities. The return value may
|
|
||||||
///< change with every call and need not necessarily be the number of list
|
|
||||||
///< entries returned by GetAudioTracksDevice(). This function is mainly called to
|
|
||||||
///< decide whether there should be an "Audio" button in a menu.
|
|
||||||
virtual const char **GetAudioTracksDevice(int *CurrentTrack = NULL) const;
|
|
||||||
///< Returns a list of currently available audio tracks. The last entry in the
|
|
||||||
///< list must be NULL. The number of entries does not necessarily have to be
|
|
||||||
///< the same as returned by a previous call to NumAudioTracksDevice().
|
|
||||||
///< If CurrentTrack is given, it will be set to the index of the current track
|
|
||||||
///< in the returned list. Note that the list must not be changed after it has
|
|
||||||
///< been returned by a call to GetAudioTracksDevice()! The only time the list may
|
|
||||||
///< change is *inside* the GetAudioTracksDevice() function.
|
|
||||||
///< By default the return value is NULL and CurrentTrack, if given, will not
|
|
||||||
///< have any meaning.
|
|
||||||
virtual void SetAudioTrackDevice(int Index);
|
|
||||||
///< Sets the current audio track to the given value, which should be within the
|
|
||||||
///< range of the list returned by a previous call to GetAudioTracksDevice()
|
|
||||||
///< (otherwise nothing will happen).
|
|
||||||
public:
|
public:
|
||||||
bool IsMute(void) const { return mute; }
|
bool IsMute(void) const { return mute; }
|
||||||
bool ToggleMute(void);
|
bool ToggleMute(void);
|
||||||
///< Turns the volume off or on and returns the new mute state.
|
///< Turns the volume off or on and returns the new mute state.
|
||||||
|
int GetAudioChannel(void);
|
||||||
|
///< Gets the current audio channel, which is stereo (0), mono left (1) or
|
||||||
|
///< mono right (2).
|
||||||
|
void SetAudioChannel(int AudioChannel);
|
||||||
|
///< Sets the audio channel to stereo (0), mono left (1) or mono right (2).
|
||||||
|
///< Any other values will be silently ignored.
|
||||||
void SetVolume(int Volume, bool Absolute = false);
|
void SetVolume(int Volume, bool Absolute = false);
|
||||||
///< Sets the volume to the given value, either absolutely or relative to
|
///< Sets the volume to the given value, either absolutely or relative to
|
||||||
///< the current volume.
|
///< the current volume.
|
||||||
static int CurrentVolume(void) { return primaryDevice ? primaryDevice->volume : 0; }//XXX???
|
static int CurrentVolume(void) { return primaryDevice ? primaryDevice->volume : 0; }//XXX???
|
||||||
int NumAudioTracks(void) const;
|
|
||||||
///< Returns the number of audio tracks that are currently available on this
|
|
||||||
///< device or a player attached to it.
|
|
||||||
const char **GetAudioTracks(int *CurrentTrack = NULL) const;
|
|
||||||
///< Returns a list of currently available audio tracks. The last entry in the
|
|
||||||
///< list is NULL. The number of entries does not necessarily have to be
|
|
||||||
///< the same as returned by a previous call to NumAudioTracks().
|
|
||||||
///< If CurrentTrack is given, it will be set to the index of the current track
|
|
||||||
///< in the returned list.
|
|
||||||
///< By default the return value is NULL and CurrentTrack, if given, will not
|
|
||||||
///< have any meaning.
|
|
||||||
void SetAudioTrack(int Index);
|
|
||||||
///< Sets the current audio track to the given value, which should be within the
|
|
||||||
///< range of the list returned by a previous call to GetAudioTracks() (otherwise
|
|
||||||
///< nothing will happen).
|
|
||||||
|
|
||||||
// Player facilities
|
// Player facilities
|
||||||
|
|
||||||
private:
|
private:
|
||||||
cPlayer *player;
|
cPlayer *player;
|
||||||
|
cPesAssembler *pesAssembler;
|
||||||
protected:
|
protected:
|
||||||
virtual bool CanReplay(void) const;
|
virtual bool CanReplay(void) const;
|
||||||
///< Returns true if this device can currently start a replay session.
|
///< Returns true if this device can currently start a replay session.
|
||||||
virtual bool SetPlayMode(ePlayMode PlayMode);
|
virtual bool SetPlayMode(ePlayMode PlayMode);
|
||||||
///< Sets the device into the given play mode.
|
///< Sets the device into the given play mode.
|
||||||
///< \return true if the operation was successful.
|
///< \return true if the operation was successful.
|
||||||
|
virtual int PlayVideo(const uchar *Data, int Length);
|
||||||
|
///< Plays the given data block as video.
|
||||||
|
///< Data points to exactly one complete PES packet of the given Length.
|
||||||
|
///< PlayVideo() shall process the packet either as a whole (returning
|
||||||
|
///< Length) or not at all (returning 0 or -1 and setting 'errno' to EAGAIN).
|
||||||
|
///< \return Returns the number of bytes actually taken from Data, or -1
|
||||||
|
///< in case of an error.
|
||||||
|
virtual int PlayAudio(const uchar *Data, int Length);
|
||||||
|
///< Plays the given data block as audio.
|
||||||
|
///< Data points to exactly one complete PES packet of the given Length.
|
||||||
|
///< PlayAudio() shall process the packet either as a whole (returning
|
||||||
|
///< Length) or not at all (returning 0 or -1 and setting 'errno' to EAGAIN).
|
||||||
|
///< \return Returns the number of bytes actually taken from Data, or -1
|
||||||
|
///< in case of an error.
|
||||||
|
virtual int PlayPesPacket(const uchar *Data, int Length, bool VideoOnly = false);
|
||||||
|
///< Plays the single PES packet in Data with the given Length.
|
||||||
|
///< If VideoOnly is true, only the video will be displayed,
|
||||||
|
///< which is necessary for trick modes like 'fast forward'.
|
||||||
|
///< Data must point to one single, complete PES packet.
|
||||||
public:
|
public:
|
||||||
virtual int64_t GetSTC(void);
|
virtual int64_t GetSTC(void);
|
||||||
///< Gets the current System Time Counter, which can be used to
|
///< Gets the current System Time Counter, which can be used to
|
||||||
@ -382,14 +436,16 @@ public:
|
|||||||
///< If TimeoutMs is not zero, the device will wait up to the given
|
///< If TimeoutMs is not zero, the device will wait up to the given
|
||||||
///< number of milliseconds before returning in case there is still
|
///< number of milliseconds before returning in case there is still
|
||||||
///< data in the buffers..
|
///< data in the buffers..
|
||||||
virtual int PlayVideo(const uchar *Data, int Length);
|
virtual int PlayPes(const uchar *Data, int Length, bool VideoOnly = false);
|
||||||
///< Actually plays the given data block as video. The data must be
|
///< Plays all valid PES packets in Data with the given Length.
|
||||||
///< part of a PES (Packetized Elementary Stream) which can contain
|
///< If Data is NULL any leftover data from a previous call will be
|
||||||
///< one video and one audio stream.
|
///< discarded. If VideoOnly is true, only the video will be displayed,
|
||||||
virtual void PlayAudio(const uchar *Data, int Length);
|
///< which is necessary for trick modes like 'fast forward'.
|
||||||
///< Plays additional audio streams, like Dolby Digital.
|
///< Data should point to a sequence of complete PES packets. If the
|
||||||
///< A derived class must call the base class function to make sure data
|
///< last packet in Data is not complete, it will be copied and combined
|
||||||
///< is distributed to all registered cAudio objects.
|
///< to a complete packet with data from the next call to PlayPes().
|
||||||
|
///< That way any functions called from within PlayPes() will be
|
||||||
|
///< guaranteed to always receive complete PES packets.
|
||||||
bool Replaying(void) const;
|
bool Replaying(void) const;
|
||||||
///< Returns true if we are currently replaying.
|
///< Returns true if we are currently replaying.
|
||||||
void StopReplay(void);
|
void StopReplay(void);
|
||||||
@ -402,6 +458,7 @@ public:
|
|||||||
// Receiver facilities
|
// Receiver facilities
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
cMutex mutexReceiver;
|
||||||
cReceiver *receiver[MAXRECEIVERS];
|
cReceiver *receiver[MAXRECEIVERS];
|
||||||
int CanShift(int Ca, int Priority, int UsedCards = 0) const;
|
int CanShift(int Ca, int Priority, int UsedCards = 0) const;
|
||||||
protected:
|
protected:
|
||||||
|
4
diseqc.c
4
diseqc.c
@ -4,7 +4,7 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* how to reach the author.
|
||||||
*
|
*
|
||||||
* $Id: diseqc.c 1.3 2004/10/24 11:04:56 kls Exp $
|
* $Id: diseqc.c 1.4 2005/01/09 13:05:11 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "diseqc.h"
|
#include "diseqc.h"
|
||||||
@ -37,7 +37,7 @@ bool cDiseqc::Parse(const char *s)
|
|||||||
source = cSource::FromString(sourcebuf);
|
source = cSource::FromString(sourcebuf);
|
||||||
if (Sources.Get(source)) {
|
if (Sources.Get(source)) {
|
||||||
polarization = toupper(polarization);
|
polarization = toupper(polarization);
|
||||||
if (polarization == 'V' || polarization == 'H') {
|
if (polarization == 'V' || polarization == 'H' || polarization == 'L' || polarization == 'R') {
|
||||||
parsing = true;
|
parsing = true;
|
||||||
char *CurrentAction = NULL;
|
char *CurrentAction = NULL;
|
||||||
while (Execute(&CurrentAction) != daNone)
|
while (Execute(&CurrentAction) != daNone)
|
||||||
|
113
dvbdevice.c
113
dvbdevice.c
@ -4,7 +4,7 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* how to reach the author.
|
||||||
*
|
*
|
||||||
* $Id: dvbdevice.c 1.105 2004/11/20 11:41:37 kls Exp $
|
* $Id: dvbdevice.c 1.113 2005/01/09 13:04:20 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "dvbdevice.h"
|
#include "dvbdevice.h"
|
||||||
@ -46,16 +46,19 @@ extern "C" {
|
|||||||
#define DEV_DVB_AUDIO "audio"
|
#define DEV_DVB_AUDIO "audio"
|
||||||
#define DEV_DVB_CA "ca"
|
#define DEV_DVB_CA "ca"
|
||||||
|
|
||||||
static const char *DvbName(const char *Name, int n)
|
class cDvbName {
|
||||||
{
|
private:
|
||||||
static char buffer[PATH_MAX];
|
char buffer[PATH_MAX];
|
||||||
snprintf(buffer, sizeof(buffer), "%s%d/%s%d", DEV_DVB_ADAPTER, n, Name, 0);
|
public:
|
||||||
return buffer;
|
cDvbName(const char *Name, int n) {
|
||||||
}
|
snprintf(buffer, sizeof(buffer), "%s%d/%s%d", DEV_DVB_ADAPTER, n, Name, 0);
|
||||||
|
}
|
||||||
|
const char *operator*() { return buffer; }
|
||||||
|
};
|
||||||
|
|
||||||
static int DvbOpen(const char *Name, int n, int Mode, bool ReportError = false)
|
static int DvbOpen(const char *Name, int n, int Mode, bool ReportError = false)
|
||||||
{
|
{
|
||||||
const char *FileName = DvbName(Name, n);
|
const char *FileName = *cDvbName(Name, n);
|
||||||
int fd = open(FileName, Mode);
|
int fd = open(FileName, Mode);
|
||||||
if (fd < 0 && ReportError)
|
if (fd < 0 && ReportError)
|
||||||
LOG_ERROR_STR(FileName);
|
LOG_ERROR_STR(FileName);
|
||||||
@ -239,7 +242,7 @@ bool cDvbTuner::SetFrontend(void)
|
|||||||
frequency -= Setup.LnbFrequHi;
|
frequency -= Setup.LnbFrequHi;
|
||||||
tone = SEC_TONE_ON;
|
tone = SEC_TONE_ON;
|
||||||
}
|
}
|
||||||
int volt = (channel.Polarization() == 'v' || channel.Polarization() == 'V') ? SEC_VOLTAGE_13 : SEC_VOLTAGE_18;
|
int volt = (channel.Polarization() == 'v' || channel.Polarization() == 'V' || channel.Polarization() == 'r' || channel.Polarization() == 'R') ? SEC_VOLTAGE_13 : SEC_VOLTAGE_18;
|
||||||
CHECK(ioctl(fd_frontend, FE_SET_VOLTAGE, volt));
|
CHECK(ioctl(fd_frontend, FE_SET_VOLTAGE, volt));
|
||||||
CHECK(ioctl(fd_frontend, FE_SET_TONE, tone));
|
CHECK(ioctl(fd_frontend, FE_SET_TONE, tone));
|
||||||
}
|
}
|
||||||
@ -319,9 +322,9 @@ void cDvbTuner::Action(void)
|
|||||||
cCiCaPmt CaPmt(channel.Source(), channel.Transponder(), channel.Sid(), ciHandler->GetCaSystemIds(Slot));
|
cCiCaPmt CaPmt(channel.Source(), channel.Transponder(), channel.Sid(), ciHandler->GetCaSystemIds(Slot));
|
||||||
if (CaPmt.Valid()) {
|
if (CaPmt.Valid()) {
|
||||||
CaPmt.AddPid(channel.Vpid(), 2);
|
CaPmt.AddPid(channel.Vpid(), 2);
|
||||||
CaPmt.AddPid(channel.Apid1(), 4);
|
CaPmt.AddPid(channel.Apid(0), 4);
|
||||||
CaPmt.AddPid(channel.Apid2(), 4);
|
CaPmt.AddPid(channel.Apid(1), 4);
|
||||||
CaPmt.AddPid(channel.Dpid1(), 0);
|
CaPmt.AddPid(channel.Dpid(0), 0);
|
||||||
if (ciHandler->SetCaPmt(CaPmt, Slot)) {
|
if (ciHandler->SetCaPmt(CaPmt, Slot)) {
|
||||||
tunerStatus = tsCam;
|
tunerStatus = tsCam;
|
||||||
startTime = 0;
|
startTime = 0;
|
||||||
@ -349,8 +352,8 @@ cDvbDevice::cDvbDevice(int n)
|
|||||||
dvbTuner = NULL;
|
dvbTuner = NULL;
|
||||||
frontendType = fe_type_t(-1); // don't know how else to initialize this - there is no FE_UNKNOWN
|
frontendType = fe_type_t(-1); // don't know how else to initialize this - there is no FE_UNKNOWN
|
||||||
spuDecoder = NULL;
|
spuDecoder = NULL;
|
||||||
|
digitalAudio = false;
|
||||||
playMode = pmNone;
|
playMode = pmNone;
|
||||||
aPid1 = aPid2 = 0;
|
|
||||||
|
|
||||||
// Devices that are present on all card types:
|
// Devices that are present on all card types:
|
||||||
|
|
||||||
@ -406,7 +409,7 @@ cDvbDevice::cDvbDevice(int n)
|
|||||||
dvb_frontend_info feinfo;
|
dvb_frontend_info feinfo;
|
||||||
if (ioctl(fd_frontend, FE_GET_INFO, &feinfo) >= 0) {
|
if (ioctl(fd_frontend, FE_GET_INFO, &feinfo) >= 0) {
|
||||||
frontendType = feinfo.type;
|
frontendType = feinfo.type;
|
||||||
ciHandler = cCiHandler::CreateCiHandler(DvbName(DEV_DVB_CA, n));
|
ciHandler = cCiHandler::CreateCiHandler(*cDvbName(DEV_DVB_CA, n));
|
||||||
dvbTuner = new cDvbTuner(fd_frontend, CardIndex(), frontendType, ciHandler);
|
dvbTuner = new cDvbTuner(fd_frontend, CardIndex(), frontendType, ciHandler);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -449,7 +452,7 @@ bool cDvbDevice::Initialize(void)
|
|||||||
int i;
|
int i;
|
||||||
for (i = 0; i < MAXDVBDEVICES; i++) {
|
for (i = 0; i < MAXDVBDEVICES; i++) {
|
||||||
if (UseDevice(NextCardIndex())) {
|
if (UseDevice(NextCardIndex())) {
|
||||||
if (Probe(DvbName(DEV_DVB_FRONTEND, i))) {
|
if (Probe(*cDvbName(DEV_DVB_FRONTEND, i))) {
|
||||||
new cDvbDevice(i);
|
new cDvbDevice(i);
|
||||||
found++;
|
found++;
|
||||||
}
|
}
|
||||||
@ -541,7 +544,7 @@ bool cDvbDevice::GrabImage(const char *FileName, bool Jpeg, int Quality, int Siz
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (Quality < 0)
|
if (Quality < 0)
|
||||||
Quality = 255; //XXX is this 'best'???
|
Quality = 100;
|
||||||
|
|
||||||
isyslog("grabbing to %s (%s %d %d %d)", FileName, Jpeg ? "JPEG" : "PNM", Quality, vm.width, vm.height);
|
isyslog("grabbing to %s (%s %d %d %d)", FileName, Jpeg ? "JPEG" : "PNM", Quality, vm.width, vm.height);
|
||||||
FILE *f = fopen(FileName, "wb");
|
FILE *f = fopen(FileName, "wb");
|
||||||
@ -659,7 +662,7 @@ bool cDvbDevice::SetPid(cPidHandle *Handle, int Type, bool On)
|
|||||||
|
|
||||||
int cDvbDevice::OpenFilter(u_short Pid, u_char Tid, u_char Mask)
|
int cDvbDevice::OpenFilter(u_short Pid, u_char Tid, u_char Mask)
|
||||||
{
|
{
|
||||||
const char *FileName = DvbName(DEV_DVB_DEMUX, CardIndex());
|
const char *FileName = *cDvbName(DEV_DVB_DEMUX, CardIndex());
|
||||||
int f = open(FileName, O_RDWR | O_NONBLOCK);
|
int f = open(FileName, O_RDWR | O_NONBLOCK);
|
||||||
if (f >= 0) {
|
if (f >= 0) {
|
||||||
dmx_sct_filter_params sctFilterParams;
|
dmx_sct_filter_params sctFilterParams;
|
||||||
@ -725,7 +728,7 @@ bool cDvbDevice::ProvidesChannel(const cChannel *Channel, int Priority, bool *Ne
|
|||||||
result = hasPriority;
|
result = hasPriority;
|
||||||
if (Priority >= 0 && Receiving(true)) {
|
if (Priority >= 0 && Receiving(true)) {
|
||||||
if (dvbTuner->IsTunedTo(Channel)) {
|
if (dvbTuner->IsTunedTo(Channel)) {
|
||||||
if (Channel->Vpid() && !HasPid(Channel->Vpid()) || Channel->Apid1() && !HasPid(Channel->Apid1())) {
|
if (Channel->Vpid() && !HasPid(Channel->Vpid()) || Channel->Apid(0) && !HasPid(Channel->Apid(0))) {
|
||||||
#ifdef DO_MULTIPLE_RECORDINGS
|
#ifdef DO_MULTIPLE_RECORDINGS
|
||||||
if (Ca() > CACONFBASE || Channel->Ca() > CACONFBASE)
|
if (Ca() > CACONFBASE || Channel->Ca() > CACONFBASE)
|
||||||
needsDetachReceivers = !ciHandler // only LL-firmware can do non-live CA channels
|
needsDetachReceivers = !ciHandler // only LL-firmware can do non-live CA channels
|
||||||
@ -798,9 +801,7 @@ bool cDvbDevice::SetChannelDevice(const cChannel *Channel, bool LiveView)
|
|||||||
// PID settings:
|
// PID settings:
|
||||||
|
|
||||||
if (TurnOnLivePIDs) {
|
if (TurnOnLivePIDs) {
|
||||||
aPid1 = Channel->Apid1();
|
if (!(AddPid(Channel->Ppid(), ptPcr) && AddPid(Channel->Vpid(), ptVideo) && AddPid(Channel->Apid(0), ptAudio))) {
|
||||||
aPid2 = Channel->Apid2();
|
|
||||||
if (!(AddPid(Channel->Ppid(), ptPcr) && AddPid(Channel->Vpid(), ptVideo) && AddPid(Channel->Apid1(), ptAudio))) {//XXX+ dolby dpid1!!! (if audio plugins are attached)
|
|
||||||
esyslog("ERROR: failed to set PIDs for channel %d on device %d", Channel->Number(), CardIndex() + 1);
|
esyslog("ERROR: failed to set PIDs for channel %d on device %d", Channel->Number(), CardIndex() + 1);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -812,7 +813,7 @@ bool cDvbDevice::SetChannelDevice(const cChannel *Channel, bool LiveView)
|
|||||||
CHECK(ioctl(fd_audio, AUDIO_SET_AV_SYNC, true));
|
CHECK(ioctl(fd_audio, AUDIO_SET_AV_SYNC, true));
|
||||||
}
|
}
|
||||||
else if (StartTransferMode)
|
else if (StartTransferMode)
|
||||||
cControl::Launch(new cTransferControl(this, Channel->Vpid(), Channel->Apid1(), Channel->Apid2(), Channel->Dpid1(), Channel->Dpid2()));
|
cControl::Launch(new cTransferControl(this, Channel->Vpid(), Channel->Apid(0), Channel->Apid(1), Channel->Dpid(0), Channel->Dpid(1)));
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -822,6 +823,22 @@ bool cDvbDevice::HasLock(int TimeoutMs)
|
|||||||
return dvbTuner ? dvbTuner->Locked(TimeoutMs) : false;
|
return dvbTuner ? dvbTuner->Locked(TimeoutMs) : false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int cDvbDevice::GetAudioChannelDevice(void)
|
||||||
|
{
|
||||||
|
if (HasDecoder()) {
|
||||||
|
audio_status_t as;
|
||||||
|
CHECK(ioctl(fd_audio, AUDIO_GET_STATUS, &as));
|
||||||
|
return as.channel_select;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void cDvbDevice::SetAudioChannelDevice(int AudioChannel)
|
||||||
|
{
|
||||||
|
if (HasDecoder())
|
||||||
|
CHECK(ioctl(fd_audio, AUDIO_CHANNEL_SELECT, AudioChannel));
|
||||||
|
}
|
||||||
|
|
||||||
void cDvbDevice::SetVolumeDevice(int Volume)
|
void cDvbDevice::SetVolumeDevice(int Volume)
|
||||||
{
|
{
|
||||||
if (HasDecoder()) {
|
if (HasDecoder()) {
|
||||||
@ -832,34 +849,30 @@ void cDvbDevice::SetVolumeDevice(int Volume)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int cDvbDevice::NumAudioTracksDevice(void) const
|
void cDvbDevice::SetDigitalAudioDevice(bool On)
|
||||||
{
|
{
|
||||||
int n = 0;
|
if (digitalAudio != On) {
|
||||||
if (aPid1)
|
if (digitalAudio)
|
||||||
n++;
|
cCondWait::SleepMs(1000); // Wait until any leftover digital data has been flushed
|
||||||
if (Ca() <= MAXDEVICES && aPid2 && aPid1 != aPid2) // a CA recording session blocks switching live audio tracks
|
SetVolumeDevice(On || IsMute() ? 0 : CurrentVolume());
|
||||||
n++;
|
digitalAudio = On;
|
||||||
return n;
|
|
||||||
}
|
|
||||||
|
|
||||||
const char **cDvbDevice::GetAudioTracksDevice(int *CurrentTrack) const
|
|
||||||
{
|
|
||||||
if (NumAudioTracksDevice()) {
|
|
||||||
if (CurrentTrack)
|
|
||||||
*CurrentTrack = (pidHandles[ptAudio].pid == aPid1) ? 0 : 1;
|
|
||||||
static const char *audioTracks1[] = { "Audio 1", NULL };
|
|
||||||
static const char *audioTracks2[] = { "Audio 1", "Audio 2", NULL };
|
|
||||||
return NumAudioTracksDevice() > 1 ? audioTracks2 : audioTracks1;
|
|
||||||
}
|
}
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void cDvbDevice::SetAudioTrackDevice(int Index)
|
void cDvbDevice::SetAudioTrackDevice(eTrackType Type)
|
||||||
{
|
{
|
||||||
if (0 <= Index && Index < NumAudioTracksDevice()) {
|
const tTrackId *TrackId = GetTrack(Type);
|
||||||
int Pid = Index ? aPid2 : aPid1;
|
if (TrackId && TrackId->id) {
|
||||||
pidHandles[ptAudio].pid = Pid;
|
if (IS_AUDIO_TRACK(Type)) {
|
||||||
SetPid(&pidHandles[ptAudio], ptAudio, true);
|
pidHandles[ptAudio].pid = TrackId->id;
|
||||||
|
SetPid(&pidHandles[ptAudio], ptAudio, true);
|
||||||
|
}
|
||||||
|
else if (IS_DOLBY_TRACK(Type)) {
|
||||||
|
// Currently this works only in Transfer Mode
|
||||||
|
cChannel *Channel = Channels.GetByNumber(CurrentChannel());
|
||||||
|
if (Channel)
|
||||||
|
SetChannelDevice(Channel, false); // this implicitly starts Transfer Mode
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1117,16 +1130,12 @@ bool cDvbDevice::Flush(int TimeoutMs)
|
|||||||
|
|
||||||
int cDvbDevice::PlayVideo(const uchar *Data, int Length)
|
int cDvbDevice::PlayVideo(const uchar *Data, int Length)
|
||||||
{
|
{
|
||||||
int fd = (playMode == pmAudioOnly || playMode == pmAudioOnlyBlack) ? fd_audio : fd_video;
|
return write(fd_video, Data, Length);
|
||||||
if (fd >= 0)
|
|
||||||
return write(fd, Data, Length);
|
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void cDvbDevice::PlayAudio(const uchar *Data, int Length)
|
int cDvbDevice::PlayAudio(const uchar *Data, int Length)
|
||||||
{
|
{
|
||||||
//XXX actually this function will only be needed to implement replaying AC3 over the DVB card's S/PDIF
|
return write(fd_audio, Data, Length);
|
||||||
cDevice::PlayAudio(Data, Length);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool cDvbDevice::OpenDvr(void)
|
bool cDvbDevice::OpenDvr(void)
|
||||||
|
19
dvbdevice.h
19
dvbdevice.h
@ -4,7 +4,7 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* how to reach the author.
|
||||||
*
|
*
|
||||||
* $Id: dvbdevice.h 1.30 2004/11/07 10:25:16 kls Exp $
|
* $Id: dvbdevice.h 1.32 2005/01/06 13:30:51 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __DVBDEVICE_H
|
#ifndef __DVBDEVICE_H
|
||||||
@ -90,15 +90,20 @@ public:
|
|||||||
virtual void SetVideoFormat(bool VideoFormat16_9);
|
virtual void SetVideoFormat(bool VideoFormat16_9);
|
||||||
virtual eVideoSystem GetVideoSystem(void);
|
virtual eVideoSystem GetVideoSystem(void);
|
||||||
|
|
||||||
|
// Track facilities
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual void SetAudioTrackDevice(eTrackType Type);
|
||||||
|
|
||||||
// Audio facilities
|
// Audio facilities
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int aPid1, aPid2;
|
bool digitalAudio;
|
||||||
protected:
|
protected:
|
||||||
|
virtual int GetAudioChannelDevice(void);
|
||||||
|
virtual void SetAudioChannelDevice(int AudioChannel);
|
||||||
virtual void SetVolumeDevice(int Volume);
|
virtual void SetVolumeDevice(int Volume);
|
||||||
virtual int NumAudioTracksDevice(void) const;
|
virtual void SetDigitalAudioDevice(bool On);
|
||||||
virtual const char **GetAudioTracksDevice(int *CurrentTrack = NULL) const;
|
|
||||||
virtual void SetAudioTrackDevice(int Index);
|
|
||||||
|
|
||||||
// Player facilities
|
// Player facilities
|
||||||
|
|
||||||
@ -106,6 +111,8 @@ protected:
|
|||||||
ePlayMode playMode;
|
ePlayMode playMode;
|
||||||
virtual bool CanReplay(void) const;
|
virtual bool CanReplay(void) const;
|
||||||
virtual bool SetPlayMode(ePlayMode PlayMode);
|
virtual bool SetPlayMode(ePlayMode PlayMode);
|
||||||
|
virtual int PlayVideo(const uchar *Data, int Length);
|
||||||
|
virtual int PlayAudio(const uchar *Data, int Length);
|
||||||
public:
|
public:
|
||||||
virtual int64_t GetSTC(void);
|
virtual int64_t GetSTC(void);
|
||||||
virtual void TrickSpeed(int Speed);
|
virtual void TrickSpeed(int Speed);
|
||||||
@ -116,8 +123,6 @@ public:
|
|||||||
virtual void StillPicture(const uchar *Data, int Length);
|
virtual void StillPicture(const uchar *Data, int Length);
|
||||||
virtual bool Poll(cPoller &Poller, int TimeoutMs = 0);
|
virtual bool Poll(cPoller &Poller, int TimeoutMs = 0);
|
||||||
virtual bool Flush(int TimeoutMs = 0);
|
virtual bool Flush(int TimeoutMs = 0);
|
||||||
virtual int PlayVideo(const uchar *Data, int Length);
|
|
||||||
virtual void PlayAudio(const uchar *Data, int Length);
|
|
||||||
|
|
||||||
// Receiver facilities
|
// Receiver facilities
|
||||||
|
|
||||||
|
91
dvbplayer.c
91
dvbplayer.c
@ -4,7 +4,7 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* how to reach the author.
|
||||||
*
|
*
|
||||||
* $Id: dvbplayer.c 1.26 2004/10/23 12:39:35 kls Exp $
|
* $Id: dvbplayer.c 1.29 2004/12/26 11:45:34 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "dvbplayer.h"
|
#include "dvbplayer.h"
|
||||||
@ -194,13 +194,10 @@ private:
|
|||||||
ePlayDirs playDir;
|
ePlayDirs playDir;
|
||||||
int trickSpeed;
|
int trickSpeed;
|
||||||
int readIndex, writeIndex;
|
int readIndex, writeIndex;
|
||||||
bool canToggleAudioTrack;
|
|
||||||
uchar audioTrack;
|
|
||||||
cFrame *readFrame;
|
cFrame *readFrame;
|
||||||
cFrame *playFrame;
|
cFrame *playFrame;
|
||||||
void TrickSpeed(int Increment);
|
void TrickSpeed(int Increment);
|
||||||
void Empty(void);
|
void Empty(void);
|
||||||
void StripAudioPackets(uchar *b, int Length, uchar Except = 0x00);
|
|
||||||
bool NextFile(uchar FileNumber = 0, int FileOffset = -1);
|
bool NextFile(uchar FileNumber = 0, int FileOffset = -1);
|
||||||
int Resume(void);
|
int Resume(void);
|
||||||
bool Save(void);
|
bool Save(void);
|
||||||
@ -220,9 +217,6 @@ public:
|
|||||||
void Goto(int Position, bool Still = false);
|
void Goto(int Position, bool Still = false);
|
||||||
virtual bool GetIndex(int &Current, int &Total, bool SnapToIFrame = false);
|
virtual bool GetIndex(int &Current, int &Total, bool SnapToIFrame = false);
|
||||||
virtual bool GetReplayMode(bool &Play, bool &Forward, int &Speed);
|
virtual bool GetReplayMode(bool &Play, bool &Forward, int &Speed);
|
||||||
virtual int NumAudioTracks(void) const;
|
|
||||||
virtual const char **GetAudioTracks(int *CurrentTrack = NULL) const;
|
|
||||||
virtual void SetAudioTrack(int Index);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#define MAX_VIDEO_SLOWMOTION 63 // max. arg to pass to VIDEO_SLOWMOTION // TODO is this value correct?
|
#define MAX_VIDEO_SLOWMOTION 63 // max. arg to pass to VIDEO_SLOWMOTION // TODO is this value correct?
|
||||||
@ -245,8 +239,6 @@ cDvbPlayer::cDvbPlayer(const char *FileName)
|
|||||||
playMode = pmPlay;
|
playMode = pmPlay;
|
||||||
playDir = pdForward;
|
playDir = pdForward;
|
||||||
trickSpeed = NORMAL_SPEED;
|
trickSpeed = NORMAL_SPEED;
|
||||||
canToggleAudioTrack = false;
|
|
||||||
audioTrack = 0xC0;
|
|
||||||
readIndex = writeIndex = -1;
|
readIndex = writeIndex = -1;
|
||||||
readFrame = NULL;
|
readFrame = NULL;
|
||||||
playFrame = NULL;
|
playFrame = NULL;
|
||||||
@ -312,41 +304,6 @@ void cDvbPlayer::Empty(void)
|
|||||||
firstPacket = true;
|
firstPacket = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void cDvbPlayer::StripAudioPackets(uchar *b, int Length, uchar Except)
|
|
||||||
{
|
|
||||||
if (index) {
|
|
||||||
for (int i = 0; i < Length - 6; i++) {
|
|
||||||
if (b[i] == 0x00 && b[i + 1] == 0x00 && b[i + 2] == 0x01) {
|
|
||||||
uchar c = b[i + 3];
|
|
||||||
int l = b[i + 4] * 256 + b[i + 5] + 6;
|
|
||||||
switch (c) {
|
|
||||||
case 0xBD: // dolby
|
|
||||||
if (Except)
|
|
||||||
PlayAudio(&b[i], l);
|
|
||||||
// continue with deleting the data - otherwise it disturbs DVB replay
|
|
||||||
case 0xC0 ... 0xC1: // audio
|
|
||||||
if (c == 0xC1)
|
|
||||||
canToggleAudioTrack = true;
|
|
||||||
if (!Except || c != Except)
|
|
||||||
memset(&b[i], 0x00, min(l, Length-i));
|
|
||||||
break;
|
|
||||||
case 0xE0 ... 0xEF: // video
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
//esyslog("ERROR: unexpected packet id %02X", c);
|
|
||||||
l = 0;
|
|
||||||
}
|
|
||||||
if (l)
|
|
||||||
i += l - 1; // the loop increments, too!
|
|
||||||
}
|
|
||||||
/*XXX
|
|
||||||
else
|
|
||||||
esyslog("ERROR: broken packet header");
|
|
||||||
XXX*/
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool cDvbPlayer::NextFile(uchar FileNumber, int FileOffset)
|
bool cDvbPlayer::NextFile(uchar FileNumber, int FileOffset)
|
||||||
{
|
{
|
||||||
if (FileNumber > 0)
|
if (FileNumber > 0)
|
||||||
@ -409,11 +366,10 @@ void cDvbPlayer::Action(void)
|
|||||||
|
|
||||||
readIndex = Resume();
|
readIndex = Resume();
|
||||||
if (readIndex >= 0)
|
if (readIndex >= 0)
|
||||||
isyslog("resuming replay at index %d (%s)", readIndex, IndexToHMSF(readIndex, true));
|
isyslog("resuming replay at index %d (%s)", readIndex, *IndexToHMSF(readIndex, true));
|
||||||
|
|
||||||
nonBlockingFileReader = new cNonBlockingFileReader;
|
nonBlockingFileReader = new cNonBlockingFileReader;
|
||||||
int Length = 0;
|
int Length = 0;
|
||||||
int AudioTrack = 0; // -1 = any, 0 = none, >0 = audioTrack
|
|
||||||
|
|
||||||
running = true;
|
running = true;
|
||||||
while (running && (NextFile() || readIndex >= 0 || ringBuffer->Available() || !DeviceFlush(100))) {
|
while (running && (NextFile() || readIndex >= 0 || ringBuffer->Available() || !DeviceFlush(100))) {
|
||||||
@ -449,9 +405,6 @@ void cDvbPlayer::Action(void)
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
readIndex = Index;
|
readIndex = Index;
|
||||||
AudioTrack = 0;
|
|
||||||
// must clear all audio packets because the buffer is not emptied
|
|
||||||
// when falling back from "fast forward" to "play" (see above)
|
|
||||||
}
|
}
|
||||||
else if (index) {
|
else if (index) {
|
||||||
uchar FileNumber;
|
uchar FileNumber;
|
||||||
@ -462,12 +415,9 @@ void cDvbPlayer::Action(void)
|
|||||||
eof = true;
|
eof = true;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
AudioTrack = audioTrack;
|
|
||||||
}
|
}
|
||||||
else { // allows replay even if the index file is missing
|
else // allows replay even if the index file is missing
|
||||||
Length = MAXFRAMESIZE;
|
Length = MAXFRAMESIZE;
|
||||||
AudioTrack = -1;
|
|
||||||
}
|
|
||||||
if (Length == -1)
|
if (Length == -1)
|
||||||
Length = MAXFRAMESIZE; // this means we read up to EOF (see cIndex)
|
Length = MAXFRAMESIZE; // this means we read up to EOF (see cIndex)
|
||||||
else if (Length > MAXFRAMESIZE) {
|
else if (Length > MAXFRAMESIZE) {
|
||||||
@ -478,8 +428,6 @@ void cDvbPlayer::Action(void)
|
|||||||
}
|
}
|
||||||
int r = nonBlockingFileReader->Read(replayFile, b, Length);
|
int r = nonBlockingFileReader->Read(replayFile, b, Length);
|
||||||
if (r > 0) {
|
if (r > 0) {
|
||||||
if (AudioTrack == 0)
|
|
||||||
StripAudioPackets(b, r);
|
|
||||||
readFrame = new cFrame(b, -r, ftUnknown, readIndex); // hands over b to the ringBuffer
|
readFrame = new cFrame(b, -r, ftUnknown, readIndex); // hands over b to the ringBuffer
|
||||||
b = NULL;
|
b = NULL;
|
||||||
}
|
}
|
||||||
@ -490,6 +438,8 @@ void cDvbPlayer::Action(void)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
cCondWait::SleepMs(1); // this keeps the CPU load low
|
||||||
}
|
}
|
||||||
|
|
||||||
// Store the frame in the buffer:
|
// Store the frame in the buffer:
|
||||||
@ -515,15 +465,14 @@ void cDvbPlayer::Action(void)
|
|||||||
pc = playFrame->Count();
|
pc = playFrame->Count();
|
||||||
if (p) {
|
if (p) {
|
||||||
if (firstPacket) {
|
if (firstPacket) {
|
||||||
|
PlayPes(NULL, 0);
|
||||||
cRemux::SetBrokenLink(p, pc);
|
cRemux::SetBrokenLink(p, pc);
|
||||||
firstPacket = false;
|
firstPacket = false;
|
||||||
}
|
}
|
||||||
if (AudioTrack > 0)
|
|
||||||
StripAudioPackets(p, pc, AudioTrack);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (p) {
|
if (p) {
|
||||||
int w = PlayVideo(p, pc);
|
int w = PlayPes(p, pc, playMode != pmPlay);
|
||||||
if (w > 0) {
|
if (w > 0) {
|
||||||
p += w;
|
p += w;
|
||||||
pc -= w;
|
pc -= w;
|
||||||
@ -715,7 +664,6 @@ void cDvbPlayer::Goto(int Index, bool Still)
|
|||||||
if (r > 0) {
|
if (r > 0) {
|
||||||
if (playMode == pmPause)
|
if (playMode == pmPause)
|
||||||
DevicePlay();
|
DevicePlay();
|
||||||
StripAudioPackets(b, r);
|
|
||||||
DeviceStillPicture(b, r);
|
DeviceStillPicture(b, r);
|
||||||
}
|
}
|
||||||
playMode = pmStill;
|
playMode = pmStill;
|
||||||
@ -755,31 +703,6 @@ bool cDvbPlayer::GetReplayMode(bool &Play, bool &Forward, int &Speed)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
int cDvbPlayer::NumAudioTracks(void) const
|
|
||||||
{
|
|
||||||
return canToggleAudioTrack ? 2 : 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
const char **cDvbPlayer::GetAudioTracks(int *CurrentTrack) const
|
|
||||||
{
|
|
||||||
if (NumAudioTracks()) {
|
|
||||||
if (CurrentTrack)
|
|
||||||
*CurrentTrack = (audioTrack == 0xC0) ? 0 : 1;
|
|
||||||
static const char *audioTracks1[] = { "Audio 1", NULL };
|
|
||||||
static const char *audioTracks2[] = { "Audio 1", "Audio 2", NULL };
|
|
||||||
return NumAudioTracks() > 1 ? audioTracks2 : audioTracks1;
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
void cDvbPlayer::SetAudioTrack(int Index)
|
|
||||||
{
|
|
||||||
if ((audioTrack == 0xC0) != (Index == 0)) {
|
|
||||||
audioTrack = (Index == 1) ? 0xC1 : 0xC0;
|
|
||||||
Empty();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// --- cDvbPlayerControl -----------------------------------------------------
|
// --- cDvbPlayerControl -----------------------------------------------------
|
||||||
|
|
||||||
cDvbPlayerControl::cDvbPlayerControl(const char *FileName)
|
cDvbPlayerControl::cDvbPlayerControl(const char *FileName)
|
||||||
|
8
dvbspu.c
8
dvbspu.c
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
* parts of this file are derived from the OMS program.
|
* parts of this file are derived from the OMS program.
|
||||||
*
|
*
|
||||||
* $Id: dvbspu.c 1.8 2004/11/06 11:50:13 kls Exp $
|
* $Id: dvbspu.c 1.11 2005/01/08 09:57:03 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
@ -227,6 +227,7 @@ cDvbSpuDecoder::cDvbSpuDecoder()
|
|||||||
spu = NULL;
|
spu = NULL;
|
||||||
osd = NULL;
|
osd = NULL;
|
||||||
spubmp = NULL;
|
spubmp = NULL;
|
||||||
|
allowedShow = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
cDvbSpuDecoder::~cDvbSpuDecoder()
|
cDvbSpuDecoder::~cDvbSpuDecoder()
|
||||||
@ -236,7 +237,7 @@ cDvbSpuDecoder::~cDvbSpuDecoder()
|
|||||||
delete osd;
|
delete osd;
|
||||||
}
|
}
|
||||||
|
|
||||||
void cDvbSpuDecoder::processSPU(uint32_t pts, uint8_t * buf)
|
void cDvbSpuDecoder::processSPU(uint32_t pts, uint8_t * buf, bool AllowedShow)
|
||||||
{
|
{
|
||||||
setTime(pts);
|
setTime(pts);
|
||||||
|
|
||||||
@ -252,6 +253,7 @@ void cDvbSpuDecoder::processSPU(uint32_t pts, uint8_t * buf)
|
|||||||
prev_DCSQ_offset = 0;
|
prev_DCSQ_offset = 0;
|
||||||
|
|
||||||
clean = true;
|
clean = true;
|
||||||
|
allowedShow = AllowedShow;
|
||||||
}
|
}
|
||||||
|
|
||||||
void cDvbSpuDecoder::setScaleMode(cSpuDecoder::eScaleMode ScaleMode)
|
void cDvbSpuDecoder::setScaleMode(cSpuDecoder::eScaleMode ScaleMode)
|
||||||
@ -530,7 +532,7 @@ int cDvbSpuDecoder::setTime(uint32_t pts)
|
|||||||
} else if (!clean)
|
} else if (!clean)
|
||||||
state = spSHOW;
|
state = spSHOW;
|
||||||
|
|
||||||
if (state == spSHOW || state == spMENU)
|
if ((state == spSHOW && allowedShow) || state == spMENU)
|
||||||
Draw();
|
Draw();
|
||||||
|
|
||||||
if (state == spHIDE)
|
if (state == spHIDE)
|
||||||
|
5
dvbspu.h
5
dvbspu.h
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
* parts of this file are derived from the OMS program.
|
* parts of this file are derived from the OMS program.
|
||||||
*
|
*
|
||||||
* $Id: dvbspu.h 1.6 2004/11/06 11:42:37 kls Exp $
|
* $Id: dvbspu.h 1.7 2005/01/08 09:59:44 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __DVBSPU_H
|
#ifndef __DVBSPU_H
|
||||||
@ -120,6 +120,7 @@ class cDvbSpuDecoder:public cSpuDecoder {
|
|||||||
uint16_t prev_DCSQ_offset;
|
uint16_t prev_DCSQ_offset;
|
||||||
|
|
||||||
cDvbSpuBitmap *spubmp;
|
cDvbSpuBitmap *spubmp;
|
||||||
|
bool allowedShow;
|
||||||
private:
|
private:
|
||||||
int cmdOffs(void) {
|
int cmdOffs(void) {
|
||||||
return ((spu[2] << 8) | spu[3]);
|
return ((spu[2] << 8) | spu[3]);
|
||||||
@ -147,7 +148,7 @@ class cDvbSpuDecoder:public cSpuDecoder {
|
|||||||
void Hide(void);
|
void Hide(void);
|
||||||
void Draw(void);
|
void Draw(void);
|
||||||
bool IsVisible(void) { return osd != NULL; }
|
bool IsVisible(void) { return osd != NULL; }
|
||||||
void processSPU(uint32_t pts, uint8_t * buf);
|
void processSPU(uint32_t pts, uint8_t * buf, bool AllowedShow);
|
||||||
};
|
};
|
||||||
|
|
||||||
// --- cDvbSpuPalette -------------------------------------------
|
// --- cDvbSpuPalette -------------------------------------------
|
||||||
|
36
eit.c
36
eit.c
@ -8,7 +8,7 @@
|
|||||||
* Robert Schneider <Robert.Schneider@web.de> and Rolf Hakenes <hakenes@hippomi.de>.
|
* 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>.
|
* Adapted to 'libsi' for VDR 1.3.0 by Marcel Wiesweg <marcel.wiesweg@gmx.de>.
|
||||||
*
|
*
|
||||||
* $Id: eit.c 1.100 2004/10/31 12:56:24 kls Exp $
|
* $Id: eit.c 1.102 2005/01/02 11:52:12 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "eit.h"
|
#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::ExtendedEventDescriptors *ExtendedEventDescriptors = NULL;
|
||||||
SI::ShortEventDescriptor *ShortEventDescriptor = NULL;
|
SI::ShortEventDescriptor *ShortEventDescriptor = NULL;
|
||||||
cLinkChannels *LinkChannels = NULL;
|
cLinkChannels *LinkChannels = NULL;
|
||||||
|
int NumComponents = 0;
|
||||||
|
SI::ComponentDescriptor *ComponentDescriptors[MAXCOMPONENTS];
|
||||||
for (SI::Loop::Iterator it2; (d = SiEitEvent.eventDescriptors.getNext(it2)); ) {
|
for (SI::Loop::Iterator it2; (d = SiEitEvent.eventDescriptors.getNext(it2)); ) {
|
||||||
switch (d->getDescriptorTag()) {
|
switch (d->getDescriptorTag()) {
|
||||||
case SI::ExtendedEventDescriptorTag: {
|
case SI::ExtendedEventDescriptorTag: {
|
||||||
@ -186,6 +188,20 @@ cEIT::cEIT(cSchedules *Schedules, int Source, u_char Tid, const u_char *Data)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
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: ;
|
default: ;
|
||||||
}
|
}
|
||||||
delete d;
|
delete d;
|
||||||
@ -205,8 +221,20 @@ cEIT::cEIT(cSchedules *Schedules, int Source, u_char Tid, const u_char *Data)
|
|||||||
delete ExtendedEventDescriptors;
|
delete ExtendedEventDescriptors;
|
||||||
delete ShortEventDescriptor;
|
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)
|
if (LinkChannels)
|
||||||
channel->SetLinkChannels(LinkChannels);
|
channel->SetLinkChannels(LinkChannels);
|
||||||
if (Tid == 0x4E) { // we trust only the present/following info on the actual TS
|
if (Tid == 0x4E) { // we trust only the present/following info on the actual TS
|
||||||
@ -245,8 +273,8 @@ cTDT::cTDT(const u_char *Data)
|
|||||||
|
|
||||||
if (abs(sattim - loctim) > 2) {
|
if (abs(sattim - loctim) > 2) {
|
||||||
mutex.Lock();
|
mutex.Lock();
|
||||||
isyslog("System Time = %s (%ld)\n", ctime(&loctim), loctim);
|
isyslog("System Time = %s (%ld)\n", *TimeToString(loctim), loctim);
|
||||||
isyslog("Local Time = %s (%ld)\n", ctime(&sattim), sattim);
|
isyslog("Local Time = %s (%ld)\n", *TimeToString(sattim), sattim);
|
||||||
if (stime(&sattim) < 0)
|
if (stime(&sattim) < 0)
|
||||||
esyslog("ERROR while setting system time: %m");
|
esyslog("ERROR while setting system time: %m");
|
||||||
mutex.Unlock();
|
mutex.Unlock();
|
||||||
|
194
epg.c
194
epg.c
@ -7,7 +7,7 @@
|
|||||||
* Original version (as used in VDR before 1.3.0) written by
|
* Original version (as used in VDR before 1.3.0) written by
|
||||||
* Robert Schneider <Robert.Schneider@web.de> and Rolf Hakenes <hakenes@hippomi.de>.
|
* Robert Schneider <Robert.Schneider@web.de> and Rolf Hakenes <hakenes@hippomi.de>.
|
||||||
*
|
*
|
||||||
* $Id: epg.c 1.22 2004/11/07 10:43:30 kls Exp $
|
* $Id: epg.c 1.24 2005/01/02 11:25:25 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "epg.h"
|
#include "epg.h"
|
||||||
@ -16,6 +16,66 @@
|
|||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <time.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::cEvent(tChannelID ChannelID, u_int16_t EventID)
|
cEvent::cEvent(tChannelID ChannelID, u_int16_t EventID)
|
||||||
@ -28,6 +88,7 @@ cEvent::cEvent(tChannelID ChannelID, u_int16_t EventID)
|
|||||||
title = NULL;
|
title = NULL;
|
||||||
shortText = NULL;
|
shortText = NULL;
|
||||||
description = NULL;
|
description = NULL;
|
||||||
|
components = NULL;
|
||||||
startTime = 0;
|
startTime = 0;
|
||||||
duration = 0;
|
duration = 0;
|
||||||
vps = 0;
|
vps = 0;
|
||||||
@ -39,6 +100,7 @@ cEvent::~cEvent()
|
|||||||
free(title);
|
free(title);
|
||||||
free(shortText);
|
free(shortText);
|
||||||
free(description);
|
free(description);
|
||||||
|
delete components;
|
||||||
}
|
}
|
||||||
|
|
||||||
int cEvent::Compare(const cListObject &ListObject) const
|
int cEvent::Compare(const cListObject &ListObject) const
|
||||||
@ -66,7 +128,7 @@ void cEvent::SetRunningStatus(int RunningStatus, cChannel *Channel)
|
|||||||
{
|
{
|
||||||
if (Channel && runningStatus != RunningStatus && (RunningStatus > SI::RunningStatusNotRunning || runningStatus > SI::RunningStatusUndefined))
|
if (Channel && runningStatus != RunningStatus && (RunningStatus > SI::RunningStatusNotRunning || runningStatus > SI::RunningStatusUndefined))
|
||||||
if (Channel->Number() <= 30)//XXX maybe log only those that have timers???
|
if (Channel->Number() <= 30)//XXX maybe log only those that have timers???
|
||||||
isyslog("channel %d (%s) event %s '%s' status %d", Channel->Number(), Channel->Name(), GetTimeString(), Title(), RunningStatus);
|
isyslog("channel %d (%s) event %s '%s' status %d", Channel->Number(), Channel->Name(), *GetTimeString(), Title(), RunningStatus);
|
||||||
runningStatus = RunningStatus;
|
runningStatus = RunningStatus;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -85,6 +147,12 @@ void cEvent::SetDescription(const char *Description)
|
|||||||
description = strcpyrealloc(description, Description);
|
description = strcpyrealloc(description, Description);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void cEvent::SetComponents(cComponents *Components)
|
||||||
|
{
|
||||||
|
delete components;
|
||||||
|
components = Components;
|
||||||
|
}
|
||||||
|
|
||||||
void cEvent::SetStartTime(time_t StartTime)
|
void cEvent::SetStartTime(time_t StartTime)
|
||||||
{
|
{
|
||||||
startTime = StartTime;
|
startTime = StartTime;
|
||||||
@ -119,9 +187,9 @@ bool cEvent::IsRunning(bool OrAboutToStart) const
|
|||||||
return runningStatus >= (OrAboutToStart ? SI::RunningStatusStartsInAFewSeconds : SI::RunningStatusPausing);
|
return runningStatus >= (OrAboutToStart ? SI::RunningStatusStartsInAFewSeconds : SI::RunningStatusPausing);
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *cEvent::GetDateString(void) const
|
cString cEvent::GetDateString(void) const
|
||||||
{
|
{
|
||||||
static char buf[32];
|
char buf[32];
|
||||||
struct tm tm_r;
|
struct tm tm_r;
|
||||||
tm *tm = localtime_r(&startTime, &tm_r);
|
tm *tm = localtime_r(&startTime, &tm_r);
|
||||||
char *p = stpcpy(buf, WeekDayName(tm->tm_wday));
|
char *p = stpcpy(buf, WeekDayName(tm->tm_wday));
|
||||||
@ -130,26 +198,26 @@ const char *cEvent::GetDateString(void) const
|
|||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *cEvent::GetTimeString(void) const
|
cString cEvent::GetTimeString(void) const
|
||||||
{
|
{
|
||||||
static char buf[25];
|
char buf[25];
|
||||||
struct tm tm_r;
|
struct tm tm_r;
|
||||||
strftime(buf, sizeof(buf), "%R", localtime_r(&startTime, &tm_r));
|
strftime(buf, sizeof(buf), "%R", localtime_r(&startTime, &tm_r));
|
||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *cEvent::GetEndTimeString(void) const
|
cString cEvent::GetEndTimeString(void) const
|
||||||
{
|
{
|
||||||
static char buf[25];
|
char buf[25];
|
||||||
time_t EndTime = startTime + duration;
|
time_t EndTime = startTime + duration;
|
||||||
struct tm tm_r;
|
struct tm tm_r;
|
||||||
strftime(buf, sizeof(buf), "%R", localtime_r(&EndTime, &tm_r));
|
strftime(buf, sizeof(buf), "%R", localtime_r(&EndTime, &tm_r));
|
||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *cEvent::GetVpsString(void) const
|
cString cEvent::GetVpsString(void) const
|
||||||
{
|
{
|
||||||
static char buf[25];
|
char buf[25];
|
||||||
struct tm tm_r;
|
struct tm tm_r;
|
||||||
strftime(buf, sizeof(buf), "%d.%m %R", localtime_r(&vps, &tm_r));
|
strftime(buf, sizeof(buf), "%d.%m %R", localtime_r(&vps, &tm_r));
|
||||||
return buf;
|
return buf;
|
||||||
@ -168,6 +236,12 @@ void cEvent::Dump(FILE *f, const char *Prefix) const
|
|||||||
fprintf(f, "%sD %s\n", Prefix, description);
|
fprintf(f, "%sD %s\n", Prefix, description);
|
||||||
strreplace(description, '|', '\n');
|
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)
|
if (vps)
|
||||||
fprintf(f, "%sV %ld\n", Prefix, vps);
|
fprintf(f, "%sV %ld\n", Prefix, vps);
|
||||||
fprintf(f, "%se\n", Prefix);
|
fprintf(f, "%se\n", Prefix);
|
||||||
@ -178,8 +252,11 @@ bool cEvent::Read(FILE *f, cSchedule *Schedule)
|
|||||||
{
|
{
|
||||||
if (Schedule) {
|
if (Schedule) {
|
||||||
cEvent *Event = NULL;
|
cEvent *Event = NULL;
|
||||||
|
int NumComponents = 0;
|
||||||
|
char *ComponentStrings[MAXCOMPONENTS];
|
||||||
char *s;
|
char *s;
|
||||||
while ((s = readline(f)) != NULL) {
|
cReadLine ReadLine;
|
||||||
|
while ((s = ReadLine.Read(f)) != NULL) {
|
||||||
char *t = skipspace(s + 1);
|
char *t = skipspace(s + 1);
|
||||||
switch (*s) {
|
switch (*s) {
|
||||||
case 'E': if (!Event) {
|
case 'E': if (!Event) {
|
||||||
@ -198,6 +275,7 @@ bool cEvent::Read(FILE *f, cSchedule *Schedule)
|
|||||||
Event->SetDuration(Duration);
|
Event->SetDuration(Duration);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
NumComponents = 0;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'T': if (Event)
|
case 'T': if (Event)
|
||||||
@ -211,10 +289,26 @@ bool cEvent::Read(FILE *f, cSchedule *Schedule)
|
|||||||
Event->SetDescription(t);
|
Event->SetDescription(t);
|
||||||
}
|
}
|
||||||
break;
|
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)
|
case 'V': if (Event)
|
||||||
Event->SetVps(atoi(t));
|
Event->SetVps(atoi(t));
|
||||||
break;
|
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;
|
break;
|
||||||
case 'c': // to keep things simple we react on 'c' here
|
case 'c': // to keep things simple we react on 'c' here
|
||||||
return true;
|
return true;
|
||||||
@ -227,7 +321,7 @@ bool cEvent::Read(FILE *f, cSchedule *Schedule)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define MAXEPGBUGFIXSTATS 8
|
#define MAXEPGBUGFIXSTATS 12
|
||||||
#define MAXEPGBUGFIXCHANS 100
|
#define MAXEPGBUGFIXCHANS 100
|
||||||
struct tEpgBugFixStats {
|
struct tEpgBugFixStats {
|
||||||
int hits;
|
int hits;
|
||||||
@ -475,6 +569,72 @@ void cEvent::FixEpgBugs(void)
|
|||||||
strreplace(title, '`', '\'');
|
strreplace(title, '`', '\'');
|
||||||
strreplace(shortText, '`', '\'');
|
strreplace(shortText, '`', '\'');
|
||||||
strreplace(description, '`', '\'');
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -604,7 +764,7 @@ void cSchedule::Dump(FILE *f, const char *Prefix, eDumpMode DumpMode, time_t AtT
|
|||||||
{
|
{
|
||||||
cChannel *channel = Channels.GetByChannelID(channelID, true);
|
cChannel *channel = Channels.GetByChannelID(channelID, true);
|
||||||
if (channel) {
|
if (channel) {
|
||||||
fprintf(f, "%sC %s %s\n", Prefix, channel->GetChannelID().ToString(), channel->Name());
|
fprintf(f, "%sC %s %s\n", Prefix, *channel->GetChannelID().ToString(), channel->Name());
|
||||||
const cEvent *p;
|
const cEvent *p;
|
||||||
switch (DumpMode) {
|
switch (DumpMode) {
|
||||||
case dmAll: {
|
case dmAll: {
|
||||||
@ -635,8 +795,9 @@ void cSchedule::Dump(FILE *f, const char *Prefix, eDumpMode DumpMode, time_t AtT
|
|||||||
bool cSchedule::Read(FILE *f, cSchedules *Schedules)
|
bool cSchedule::Read(FILE *f, cSchedules *Schedules)
|
||||||
{
|
{
|
||||||
if (Schedules) {
|
if (Schedules) {
|
||||||
|
cReadLine ReadLine;
|
||||||
char *s;
|
char *s;
|
||||||
while ((s = readline(f)) != NULL) {
|
while ((s = ReadLine.Read(f)) != NULL) {
|
||||||
if (*s == 'C') {
|
if (*s == 'C') {
|
||||||
s = skipspace(s + 1);
|
s = skipspace(s + 1);
|
||||||
char *p = strchr(s, ' ');
|
char *p = strchr(s, ' ');
|
||||||
@ -698,8 +859,7 @@ const cSchedules *cSchedules::Schedules(cSchedulesLock &SchedulesLock)
|
|||||||
void cSchedules::SetEpgDataFileName(const char *FileName)
|
void cSchedules::SetEpgDataFileName(const char *FileName)
|
||||||
{
|
{
|
||||||
delete epgDataFileName;
|
delete epgDataFileName;
|
||||||
if (FileName)
|
epgDataFileName = FileName ? strdup(FileName) : NULL;
|
||||||
epgDataFileName = strdup(FileName);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void cSchedules::SetModified(cSchedule *Schedule)
|
void cSchedules::SetModified(cSchedule *Schedule)
|
||||||
|
62
epg.h
62
epg.h
@ -7,7 +7,7 @@
|
|||||||
* Original version (as used in VDR before 1.3.0) written by
|
* Original version (as used in VDR before 1.3.0) written by
|
||||||
* Robert Schneider <Robert.Schneider@web.de> and Rolf Hakenes <hakenes@hippomi.de>.
|
* Robert Schneider <Robert.Schneider@web.de> and Rolf Hakenes <hakenes@hippomi.de>.
|
||||||
*
|
*
|
||||||
* $Id: epg.h 1.17 2004/10/31 16:17:10 kls Exp $
|
* $Id: epg.h 1.19 2005/01/02 10:44:41 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __EPG_H
|
#ifndef __EPG_H
|
||||||
@ -17,26 +17,50 @@
|
|||||||
#include "thread.h"
|
#include "thread.h"
|
||||||
#include "tools.h"
|
#include "tools.h"
|
||||||
|
|
||||||
#define MAXEPGBUGFIXLEVEL 2
|
#define MAXEPGBUGFIXLEVEL 3
|
||||||
|
#define MAXCOMPONENTS 32
|
||||||
|
|
||||||
enum eDumpMode { dmAll, dmPresent, dmFollowing, dmAtTime };
|
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 cSchedule;
|
||||||
|
|
||||||
class cEvent : public cListObject {
|
class cEvent : public cListObject {
|
||||||
private:
|
private:
|
||||||
tChannelID channelID; // Channel ID of program for this event
|
tChannelID channelID; // Channel ID of program for this event
|
||||||
u_int16_t eventID; // Event ID of this event
|
u_int16_t eventID; // Event ID of this event
|
||||||
uchar tableID; // Table ID this event came from
|
uchar tableID; // Table ID this event came from
|
||||||
uchar version; // Version number of section this event came from
|
uchar version; // Version number of section this event came from
|
||||||
int runningStatus; // 0=undefined, 1=not running, 2=starts in a few seconds, 3=pausing, 4=running
|
int runningStatus; // 0=undefined, 1=not running, 2=starts in a few seconds, 3=pausing, 4=running
|
||||||
char *title; // Title of this event
|
char *title; // Title of this event
|
||||||
char *shortText; // Short description of this event (typically the episode name in case of a series)
|
char *shortText; // Short description of this event (typically the episode name in case of a series)
|
||||||
char *description; // Description of this event
|
char *description; // Description of this event
|
||||||
time_t startTime; // Start time of this event
|
cComponents *components; // The stream components of this event (separated by '\n')
|
||||||
int duration; // Duration of this event in seconds
|
time_t startTime; // Start time of this event
|
||||||
time_t vps; // Video Programming Service timestamp (VPS, aka "Programme Identification Label", PIL)
|
int duration; // Duration of this event in seconds
|
||||||
time_t seen; // When this event was last seen in the data stream
|
time_t vps; // Video Programming Service timestamp (VPS, aka "Programme Identification Label", PIL)
|
||||||
|
time_t seen; // When this event was last seen in the data stream
|
||||||
public:
|
public:
|
||||||
cEvent(tChannelID ChannelID, u_int16_t EventID);
|
cEvent(tChannelID ChannelID, u_int16_t EventID);
|
||||||
~cEvent();
|
~cEvent();
|
||||||
@ -49,6 +73,7 @@ public:
|
|||||||
const char *Title(void) const { return title; }
|
const char *Title(void) const { return title; }
|
||||||
const char *ShortText(void) const { return shortText; }
|
const char *ShortText(void) const { return shortText; }
|
||||||
const char *Description(void) const { return description; }
|
const char *Description(void) const { return description; }
|
||||||
|
const cComponents *Components(void) const { return components; }
|
||||||
time_t StartTime(void) const { return startTime; }
|
time_t StartTime(void) const { return startTime; }
|
||||||
time_t EndTime(void) const { return startTime + duration; }
|
time_t EndTime(void) const { return startTime + duration; }
|
||||||
int Duration(void) const { return duration; }
|
int Duration(void) const { return duration; }
|
||||||
@ -56,10 +81,10 @@ public:
|
|||||||
time_t Seen(void) const { return seen; }
|
time_t Seen(void) const { return seen; }
|
||||||
bool HasTimer(void) const;
|
bool HasTimer(void) const;
|
||||||
bool IsRunning(bool OrAboutToStart = false) const;
|
bool IsRunning(bool OrAboutToStart = false) const;
|
||||||
const char *GetDateString(void) const;
|
cString GetDateString(void) const;
|
||||||
const char *GetTimeString(void) const;
|
cString GetTimeString(void) const;
|
||||||
const char *GetEndTimeString(void) const;
|
cString GetEndTimeString(void) const;
|
||||||
const char *GetVpsString(void) const;
|
cString GetVpsString(void) const;
|
||||||
void SetEventID(u_int16_t EventID);
|
void SetEventID(u_int16_t EventID);
|
||||||
void SetTableID(uchar TableID);
|
void SetTableID(uchar TableID);
|
||||||
void SetVersion(uchar Version);
|
void SetVersion(uchar Version);
|
||||||
@ -67,6 +92,7 @@ public:
|
|||||||
void SetTitle(const char *Title);
|
void SetTitle(const char *Title);
|
||||||
void SetShortText(const char *ShortText);
|
void SetShortText(const char *ShortText);
|
||||||
void SetDescription(const char *Description);
|
void SetDescription(const char *Description);
|
||||||
|
void SetComponents(cComponents *Components); // Will take ownership of Components!
|
||||||
void SetStartTime(time_t StartTime);
|
void SetStartTime(time_t StartTime);
|
||||||
void SetDuration(int Duration);
|
void SetDuration(int Duration);
|
||||||
void SetVps(time_t Vps);
|
void SetVps(time_t Vps);
|
||||||
|
8
font.c
8
font.c
@ -4,7 +4,7 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* how to reach the author.
|
||||||
*
|
*
|
||||||
* $Id: font.c 1.9 2004/10/23 14:06:01 kls Exp $
|
* $Id: font.c 1.10 2004/12/18 13:41:19 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
@ -12,9 +12,9 @@
|
|||||||
#include "font.h"
|
#include "font.h"
|
||||||
#include "tools.h"
|
#include "tools.h"
|
||||||
|
|
||||||
#include "fontfix.c"
|
#include "fontfix-iso8859-1.c"
|
||||||
#include "fontosd.c"
|
#include "fontosd-iso8859-1.c"
|
||||||
#include "fontsml.c"
|
#include "fontsml-iso8859-1.c"
|
||||||
|
|
||||||
#include "fontfix-iso8859-2.c"
|
#include "fontfix-iso8859-2.c"
|
||||||
#include "fontosd-iso8859-2.c"
|
#include "fontosd-iso8859-2.c"
|
||||||
|
File diff suppressed because it is too large
Load Diff
5508
fontfix-iso8859-15.c
5508
fontfix-iso8859-15.c
File diff suppressed because it is too large
Load Diff
5540
fontfix-iso8859-2.c
5540
fontfix-iso8859-2.c
File diff suppressed because it is too large
Load Diff
4874
fontfix-iso8859-5.c
4874
fontfix-iso8859-5.c
File diff suppressed because it is too large
Load Diff
5754
fontfix-iso8859-7.c
5754
fontfix-iso8859-7.c
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
5904
fontosd-iso8859-15.c
5904
fontosd-iso8859-15.c
File diff suppressed because it is too large
Load Diff
5818
fontosd-iso8859-2.c
5818
fontosd-iso8859-2.c
File diff suppressed because it is too large
Load Diff
4898
fontosd-iso8859-5.c
4898
fontosd-iso8859-5.c
File diff suppressed because it is too large
Load Diff
6026
fontosd-iso8859-7.c
6026
fontosd-iso8859-7.c
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
4858
fontsml-iso8859-15.c
4858
fontsml-iso8859-15.c
File diff suppressed because it is too large
Load Diff
4902
fontsml-iso8859-2.c
4902
fontsml-iso8859-2.c
File diff suppressed because it is too large
Load Diff
4464
fontsml-iso8859-5.c
4464
fontsml-iso8859-5.c
File diff suppressed because it is too large
Load Diff
4772
fontsml-iso8859-7.c
4772
fontsml-iso8859-7.c
File diff suppressed because it is too large
Load Diff
@ -240,7 +240,7 @@ printGlyph(FontInfoPtr font, int c)
|
|||||||
{
|
{
|
||||||
PerGlyphInfoPtr glyph;
|
PerGlyphInfoPtr glyph;
|
||||||
unsigned char *bitmapData;
|
unsigned char *bitmapData;
|
||||||
int width, height, spanLength;
|
int width, height, spanLength, charWidth;
|
||||||
int x, y, l;
|
int x, y, l;
|
||||||
char buf[1000], *b;
|
char buf[1000], *b;
|
||||||
|
|
||||||
@ -253,12 +253,15 @@ printGlyph(FontInfoPtr font, int c)
|
|||||||
width = glyph->width;
|
width = glyph->width;
|
||||||
spanLength = (width + 7) / 8;
|
spanLength = (width + 7) / 8;
|
||||||
height = glyph->height;
|
height = glyph->height;
|
||||||
|
charWidth = glyph->xoffset + width;
|
||||||
|
if (charWidth < glyph->advance)
|
||||||
|
charWidth = glyph->advance;
|
||||||
|
|
||||||
printf(" { // %d\n", c);
|
printf(" { // %d\n", c);
|
||||||
printf(" %d, %d,\n", glyph->advance, font->max_ascent + font->max_descent);
|
printf(" %d, %d,\n", charWidth, font->max_ascent + font->max_descent);
|
||||||
for (y = 0; y < font->max_ascent - glyph->yoffset - height; y++) {
|
for (y = 0; y < font->max_ascent - glyph->yoffset - height; y++) {
|
||||||
printf(" 0x%08X, // ", 0);
|
printf(" 0x%08X, // ", 0);
|
||||||
for (x = 0; x < glyph->xoffset + width || x < glyph->advance; x++)
|
for (x = 0; x < charWidth; x++)
|
||||||
putchar('.');
|
putchar('.');
|
||||||
putchar('\n');
|
putchar('\n');
|
||||||
}
|
}
|
||||||
@ -269,13 +272,13 @@ printGlyph(FontInfoPtr font, int c)
|
|||||||
*b++ = '.';
|
*b++ = '.';
|
||||||
if (bitmapData) {
|
if (bitmapData) {
|
||||||
for (x = 0; x < width; x++) {
|
for (x = 0; x < width; x++) {
|
||||||
|
l <<= 1;
|
||||||
if (bitmapData[y * spanLength + x / 8] & (1 << (x & 7))) {
|
if (bitmapData[y * spanLength + x / 8] & (1 << (x & 7))) {
|
||||||
*b++ = '*';
|
*b++ = '*';
|
||||||
l |= 1;
|
l |= 1;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
*b++ = '.';
|
*b++ = '.';
|
||||||
l <<= 1;
|
|
||||||
}
|
}
|
||||||
for (x = 0; x < glyph->advance - width - glyph->xoffset; x++) {
|
for (x = 0; x < glyph->advance - width - glyph->xoffset; x++) {
|
||||||
*b++ = '.';
|
*b++ = '.';
|
||||||
|
178
i18n.c
178
i18n.c
@ -4,26 +4,26 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* how to reach the author.
|
||||||
*
|
*
|
||||||
* $Id: i18n.c 1.164 2004/11/20 11:23:58 kls Exp $
|
* $Id: i18n.c 1.169 2005/01/09 12:17:44 kls Exp $
|
||||||
*
|
*
|
||||||
* Translations provided by:
|
* Translations provided by:
|
||||||
*
|
*
|
||||||
* Slovenian Miha Setina <mihasetina@softhome.net> and Matjaz Thaler <matjaz.thaler@guest.arnes.si>
|
* Slovenian Miha Setina <mihasetina@softhome.net>, Matjaz Thaler <matjaz.thaler@guest.arnes.si>
|
||||||
* Italian Alberto Carraro <bertocar@tin.it> and Antonio Ospite <ospite@studenti.unina.it>
|
* Italian Alberto Carraro <bertocar@tin.it>, Antonio Ospite <ospite@studenti.unina.it>, Sean Carlos <seanc@libero.it>
|
||||||
* Dutch Arnold Niessen <niessen@iae.nl> <arnold.niessen@philips.com> and Hans Dingemans <hans.dingemans@tacticalops.nl>
|
* Dutch Arnold Niessen <niessen@iae.nl> <arnold.niessen@philips.com>, Hans Dingemans <hans.dingemans@tacticalops.nl>
|
||||||
* Portuguese Paulo Lopes <pmml@netvita.pt>
|
* Portuguese Paulo Lopes <pmml@netvita.pt>
|
||||||
* French Jean-Claude Repetto <jc@repetto.org>, Olivier Jacques <jacquesolivier@hotmail.com> and Gregoire Favre <greg@magma.unil.ch>
|
* French Jean-Claude Repetto <jc@repetto.org>, Olivier Jacques <jacquesolivier@hotmail.com>, Gregoire Favre <greg@magma.unil.ch>
|
||||||
* Norwegian Jørgen Tvedt <pjtvedt@online.no> and Truls Slevigen <truls@slevigen.no>
|
* Norwegian Jørgen Tvedt <pjtvedt@online.no>, Truls Slevigen <truls@slevigen.no>
|
||||||
* Finnish Hannu Savolainen <hannu@opensound.com>, Jaakko Hyvätti <jaakko@hyvatti.iki.fi>, Niko Tarnanen <niko.tarnanen@hut.fi> and Rolf Ahrenberg <rahrenbe@cc.hut.fi>
|
* Finnish Hannu Savolainen <hannu@opensound.com>, Jaakko Hyvätti <jaakko@hyvatti.iki.fi>, Niko Tarnanen <niko.tarnanen@hut.fi>, Rolf Ahrenberg <rahrenbe@cc.hut.fi>
|
||||||
* Polish Michael Rakowski <mrak@gmx.de>
|
* Polish Michael Rakowski <mrak@gmx.de>
|
||||||
* Spanish Ruben Nunez Francisco <ruben.nunez@tang-it.com>
|
* Spanish Ruben Nunez Francisco <ruben.nunez@tang-it.com>
|
||||||
* Greek Dimitrios Dimitrakos <mail@dimitrios.de>
|
* Greek Dimitrios Dimitrakos <mail@dimitrios.de>
|
||||||
* Swedish Tomas Prybil <tomas@prybil.se> and Jan Ekholm <chakie@infa.abo.fi>
|
* Swedish Tomas Prybil <tomas@prybil.se>, Jan Ekholm <chakie@infa.abo.fi>
|
||||||
* Romanian Paul Lacatus <paul@campina.iiruc.ro>, Lucian Muresan <lucianm@users.sourceforge.net>
|
* Romanian Paul Lacatus <paul@campina.iiruc.ro>, Lucian Muresan <lucianm@users.sourceforge.net>
|
||||||
* Hungarian Istvan Koenigsberger <istvnko@hotmail.com> and Guido Josten <guido.josten@t-online.de>
|
* Hungarian Istvan Koenigsberger <istvnko@hotmail.com>, Guido Josten <guido.josten@t-online.de>
|
||||||
* Catalanian Marc Rovira Vall <tm05462@salleURL.edu>, Ramon Roca <ramon.roca@xcombo.com> and Jordi Vilà <jvila@tinet.org>
|
* Catalanian Marc Rovira Vall <tm05462@salleURL.edu>, Ramon Roca <ramon.roca@xcombo.com>, Jordi Vilà <jvila@tinet.org>
|
||||||
* Russian Vyacheslav Dikonov <sdiconov@mail.ru>
|
* Russian Vyacheslav Dikonov <sdiconov@mail.ru>
|
||||||
* Croatian Drazen Dupor <drazen.dupor@dupor.com> and Dino Ravnic <dino.ravnic@fer.hr>
|
* Croatian Drazen Dupor <drazen.dupor@dupor.com>, Dino Ravnic <dino.ravnic@fer.hr>
|
||||||
* Estonian Arthur Konovalov <kasjas@hot.ee>
|
* Estonian Arthur Konovalov <kasjas@hot.ee>
|
||||||
* Danish Mogens Elneff <mogens@elneff.dk>
|
* Danish Mogens Elneff <mogens@elneff.dk>
|
||||||
*
|
*
|
||||||
@ -103,15 +103,15 @@ const tI18nPhrase Phrases[] = {
|
|||||||
"Dansk",
|
"Dansk",
|
||||||
},
|
},
|
||||||
// The character set needed for this language (this MUST be the second phrase!):
|
// The character set needed for this language (this MUST be the second phrase!):
|
||||||
{ "iso8859-1",
|
{ "iso8859-15",
|
||||||
"iso8859-1",
|
"iso8859-15",
|
||||||
"iso8859-1",
|
|
||||||
"iso8859-1",
|
"iso8859-1",
|
||||||
"iso8859-1",
|
"iso8859-1",
|
||||||
"iso8859-1",
|
"iso8859-1",
|
||||||
"iso8859-1",
|
"iso8859-1",
|
||||||
"iso8859-1",
|
"iso8859-1",
|
||||||
"iso8859-1",
|
"iso8859-1",
|
||||||
|
"iso8859-15",
|
||||||
"iso8859-1",
|
"iso8859-1",
|
||||||
"iso8859-1",
|
"iso8859-1",
|
||||||
"iso8859-7",
|
"iso8859-7",
|
||||||
@ -907,7 +907,7 @@ const tI18nPhrase Phrases[] = {
|
|||||||
{ "Menu",
|
{ "Menu",
|
||||||
"Menü",
|
"Menü",
|
||||||
"Meni",
|
"Meni",
|
||||||
"Menu",
|
"Menù",
|
||||||
"Menu",
|
"Menu",
|
||||||
"Menu",
|
"Menu",
|
||||||
"Menu",
|
"Menu",
|
||||||
@ -949,7 +949,7 @@ const tI18nPhrase Phrases[] = {
|
|||||||
{ "Scan",
|
{ "Scan",
|
||||||
"Scan",
|
"Scan",
|
||||||
"",//TODO
|
"",//TODO
|
||||||
"",//TODO
|
"Scansione",
|
||||||
"",//TODO
|
"",//TODO
|
||||||
"",//TODO
|
"",//TODO
|
||||||
"",//TODO
|
"",//TODO
|
||||||
@ -1792,7 +1792,7 @@ const tI18nPhrase Phrases[] = {
|
|||||||
{ "VPS",
|
{ "VPS",
|
||||||
"VPS",
|
"VPS",
|
||||||
"",// TODO
|
"",// TODO
|
||||||
"",// TODO
|
"VPS",
|
||||||
"",// TODO
|
"",// TODO
|
||||||
"",// TODO
|
"",// TODO
|
||||||
"",// TODO
|
"",// TODO
|
||||||
@ -2294,6 +2294,27 @@ const tI18nPhrase Phrases[] = {
|
|||||||
"CAM mooduli taaskäivitus tehtud",
|
"CAM mooduli taaskäivitus tehtud",
|
||||||
"CAM er blevet nulstillet",
|
"CAM er blevet nulstillet",
|
||||||
},
|
},
|
||||||
|
{ "No audio available!",
|
||||||
|
"Kein Audio verfügbar!",
|
||||||
|
"",//TODO
|
||||||
|
"",//TODO
|
||||||
|
"",//TODO
|
||||||
|
"",//TODO
|
||||||
|
"",//TODO
|
||||||
|
"",//TODO
|
||||||
|
"",//TODO
|
||||||
|
"",//TODO
|
||||||
|
"",//TODO
|
||||||
|
"",//TODO
|
||||||
|
"",//TODO
|
||||||
|
"",//TODO
|
||||||
|
"",//TODO
|
||||||
|
"",//TODO
|
||||||
|
"",//TODO
|
||||||
|
"",//TODO
|
||||||
|
"",//TODO
|
||||||
|
"",//TODO
|
||||||
|
},
|
||||||
// Setup pages:
|
// Setup pages:
|
||||||
{ "OSD",
|
{ "OSD",
|
||||||
"OSD",
|
"OSD",
|
||||||
@ -2319,7 +2340,7 @@ const tI18nPhrase Phrases[] = {
|
|||||||
{ "EPG",
|
{ "EPG",
|
||||||
"EPG",
|
"EPG",
|
||||||
"Programski vodnik",
|
"Programski vodnik",
|
||||||
"EPG",
|
"Guida programmi EPG",
|
||||||
"EPG",
|
"EPG",
|
||||||
"EPG",
|
"EPG",
|
||||||
"Guide des programmes",
|
"Guide des programmes",
|
||||||
@ -2382,7 +2403,7 @@ const tI18nPhrase Phrases[] = {
|
|||||||
{ "CICAM",
|
{ "CICAM",
|
||||||
"CICAM",
|
"CICAM",
|
||||||
"CICAM",
|
"CICAM",
|
||||||
"CICAM",
|
"Accesso condizionato CICAM",
|
||||||
"CICAM",
|
"CICAM",
|
||||||
"CICAM",
|
"CICAM",
|
||||||
"Accès conditionnel",
|
"Accès conditionnel",
|
||||||
@ -2551,7 +2572,7 @@ const tI18nPhrase Phrases[] = {
|
|||||||
{ "Setup.OSD$Skin",
|
{ "Setup.OSD$Skin",
|
||||||
"Oberfläche",
|
"Oberfläche",
|
||||||
"",// TODO
|
"",// TODO
|
||||||
"",// TODO
|
"Superficie Skin",
|
||||||
"",// TODO
|
"",// TODO
|
||||||
"",// TODO
|
"",// TODO
|
||||||
"",// TODO
|
"",// TODO
|
||||||
@ -2572,7 +2593,7 @@ const tI18nPhrase Phrases[] = {
|
|||||||
{ "Setup.OSD$Theme",
|
{ "Setup.OSD$Theme",
|
||||||
"Thema",
|
"Thema",
|
||||||
"",// TODO
|
"",// TODO
|
||||||
"",// TODO
|
"Tema",
|
||||||
"",// TODO
|
"",// TODO
|
||||||
"",// TODO
|
"",// TODO
|
||||||
"",// TODO
|
"",// TODO
|
||||||
@ -2593,7 +2614,7 @@ const tI18nPhrase Phrases[] = {
|
|||||||
{ "Setup.OSD$Left",
|
{ "Setup.OSD$Left",
|
||||||
"Links",
|
"Links",
|
||||||
"",// TODO
|
"",// TODO
|
||||||
"",// TODO
|
"Sinistra",
|
||||||
"",// TODO
|
"",// TODO
|
||||||
"",// TODO
|
"",// TODO
|
||||||
"",// TODO
|
"",// TODO
|
||||||
@ -2614,7 +2635,7 @@ const tI18nPhrase Phrases[] = {
|
|||||||
{ "Setup.OSD$Top",
|
{ "Setup.OSD$Top",
|
||||||
"Oben",
|
"Oben",
|
||||||
"",// TODO
|
"",// TODO
|
||||||
"",// TODO
|
"Cima",
|
||||||
"",// TODO
|
"",// TODO
|
||||||
"",// TODO
|
"",// TODO
|
||||||
"",// TODO
|
"",// TODO
|
||||||
@ -2698,7 +2719,7 @@ const tI18nPhrase Phrases[] = {
|
|||||||
{ "Setup.OSD$Use small font",
|
{ "Setup.OSD$Use small font",
|
||||||
"Kleine Schrift benutzen",
|
"Kleine Schrift benutzen",
|
||||||
"",// TODO
|
"",// TODO
|
||||||
"",// TODO
|
"Utilizzare caratteri piccoli",
|
||||||
"",// TODO
|
"",// TODO
|
||||||
"",// TODO
|
"",// TODO
|
||||||
"",// TODO
|
"",// TODO
|
||||||
@ -2719,7 +2740,7 @@ const tI18nPhrase Phrases[] = {
|
|||||||
{ "never",
|
{ "never",
|
||||||
"nie",
|
"nie",
|
||||||
"",// TODO
|
"",// TODO
|
||||||
"",// TODO
|
"mai",
|
||||||
"",// TODO
|
"",// TODO
|
||||||
"",// TODO
|
"",// TODO
|
||||||
"",// TODO
|
"",// TODO
|
||||||
@ -2740,7 +2761,7 @@ const tI18nPhrase Phrases[] = {
|
|||||||
{ "skin dependent",
|
{ "skin dependent",
|
||||||
"je nach Oberfläche",
|
"je nach Oberfläche",
|
||||||
"",// TODO
|
"",// TODO
|
||||||
"",// TODO
|
"in base alla superficie",
|
||||||
"",// TODO
|
"",// TODO
|
||||||
"",// TODO
|
"",// TODO
|
||||||
"",// TODO
|
"",// TODO
|
||||||
@ -2761,7 +2782,7 @@ const tI18nPhrase Phrases[] = {
|
|||||||
{ "always",
|
{ "always",
|
||||||
"immer",
|
"immer",
|
||||||
"",// TODO
|
"",// TODO
|
||||||
"",// TODO
|
"sempre",
|
||||||
"",// TODO
|
"",// TODO
|
||||||
"",// TODO
|
"",// TODO
|
||||||
"",// TODO
|
"",// TODO
|
||||||
@ -2887,7 +2908,7 @@ const tI18nPhrase Phrases[] = {
|
|||||||
{ "Setup.EPG$EPG scan timeout (h)",
|
{ "Setup.EPG$EPG scan timeout (h)",
|
||||||
"Zeit bis EPG Scan (h)",
|
"Zeit bis EPG Scan (h)",
|
||||||
"Cas do EPG pregleda (h)",
|
"Cas do EPG pregleda (h)",
|
||||||
"Timeout scansione EPG (h)",
|
"Timeout scansione aggiornamento EPG (ore)",
|
||||||
"EPG-scan Timeout (h)",
|
"EPG-scan Timeout (h)",
|
||||||
"Expirou o EPG (h)",
|
"Expirou o EPG (h)",
|
||||||
"Inactivité avant rech. EPG (h)",
|
"Inactivité avant rech. EPG (h)",
|
||||||
@ -2929,7 +2950,7 @@ const tI18nPhrase Phrases[] = {
|
|||||||
{ "Setup.EPG$EPG linger time (min)",
|
{ "Setup.EPG$EPG linger time (min)",
|
||||||
"Alte EPG-Daten anzeigen (min)",// TODO
|
"Alte EPG-Daten anzeigen (min)",// TODO
|
||||||
"",// TODO
|
"",// TODO
|
||||||
"",// TODO
|
"Visualizzazione dati vecchi (min)",
|
||||||
"",// TODO
|
"",// TODO
|
||||||
"",// TODO
|
"",// TODO
|
||||||
"",// TODO
|
"",// TODO
|
||||||
@ -2992,7 +3013,7 @@ const tI18nPhrase Phrases[] = {
|
|||||||
{ "Setup.EPG$Preferred languages", // note the plural
|
{ "Setup.EPG$Preferred languages", // note the plural
|
||||||
"Bevorzugte Sprachen",
|
"Bevorzugte Sprachen",
|
||||||
"",// TODO
|
"",// TODO
|
||||||
"",// TODO
|
"Lingue preferite",
|
||||||
"",// TODO
|
"",// TODO
|
||||||
"",// TODO
|
"",// TODO
|
||||||
"",// TODO
|
"",// TODO
|
||||||
@ -3013,7 +3034,7 @@ const tI18nPhrase Phrases[] = {
|
|||||||
{ "Setup.EPG$Preferred language", // note the singular
|
{ "Setup.EPG$Preferred language", // note the singular
|
||||||
"Bevorzugte Sprache",
|
"Bevorzugte Sprache",
|
||||||
"",// TODO
|
"",// TODO
|
||||||
"",// TODO
|
"Lingua preferita",
|
||||||
"",// TODO
|
"",// TODO
|
||||||
"",// TODO
|
"",// TODO
|
||||||
"",// TODO
|
"",// TODO
|
||||||
@ -3073,10 +3094,31 @@ const tI18nPhrase Phrases[] = {
|
|||||||
"TV külgsuhe",
|
"TV külgsuhe",
|
||||||
"Video format",
|
"Video format",
|
||||||
},
|
},
|
||||||
|
{ "Setup.DVB$Use Dolby Digital",
|
||||||
|
"Dolby Digital Ton benutzen",
|
||||||
|
"",//TODO
|
||||||
|
"",//TODO
|
||||||
|
"",//TODO
|
||||||
|
"",//TODO
|
||||||
|
"",//TODO
|
||||||
|
"",//TODO
|
||||||
|
"",//TODO
|
||||||
|
"",//TODO
|
||||||
|
"",//TODO
|
||||||
|
"",//TODO
|
||||||
|
"",//TODO
|
||||||
|
"",//TODO
|
||||||
|
"",//TODO
|
||||||
|
"",//TODO
|
||||||
|
"",//TODO
|
||||||
|
"",//TODO
|
||||||
|
"",//TODO
|
||||||
|
"",//TODO
|
||||||
|
},
|
||||||
{ "Setup.DVB$Update channels",
|
{ "Setup.DVB$Update channels",
|
||||||
"Kanäle aktualisieren",
|
"Kanäle aktualisieren",
|
||||||
"",// TODO
|
"",// TODO
|
||||||
"",// TODO
|
"Aggiornare i canali",
|
||||||
"",// TODO
|
"",// TODO
|
||||||
"",// TODO
|
"",// TODO
|
||||||
"",// TODO
|
"",// TODO
|
||||||
@ -3097,7 +3139,7 @@ const tI18nPhrase Phrases[] = {
|
|||||||
{ "names only",
|
{ "names only",
|
||||||
"nur Namen",
|
"nur Namen",
|
||||||
"",// TODO
|
"",// TODO
|
||||||
"",// TODO
|
"solo nomi",
|
||||||
"",// TODO
|
"",// TODO
|
||||||
"",// TODO
|
"",// TODO
|
||||||
"",// TODO
|
"",// TODO
|
||||||
@ -3118,7 +3160,7 @@ const tI18nPhrase Phrases[] = {
|
|||||||
{ "names and PIDs",
|
{ "names and PIDs",
|
||||||
"Namen und PIDs",
|
"Namen und PIDs",
|
||||||
"",// TODO
|
"",// TODO
|
||||||
"",// TODO
|
"nomi e PIDs",
|
||||||
"",// TODO
|
"",// TODO
|
||||||
"",// TODO
|
"",// TODO
|
||||||
"",// TODO
|
"",// TODO
|
||||||
@ -3139,7 +3181,7 @@ const tI18nPhrase Phrases[] = {
|
|||||||
{ "add new channels",
|
{ "add new channels",
|
||||||
"neue Kanäle hinzufügen",
|
"neue Kanäle hinzufügen",
|
||||||
"",// TODO
|
"",// TODO
|
||||||
"",// TODO
|
"aggiungere canali nuovi",
|
||||||
"",// TODO
|
"",// TODO
|
||||||
"",// TODO
|
"",// TODO
|
||||||
"",// TODO
|
"",// TODO
|
||||||
@ -3160,7 +3202,7 @@ const tI18nPhrase Phrases[] = {
|
|||||||
{ "add new transponders",
|
{ "add new transponders",
|
||||||
"neue Transponder hinzufügen",
|
"neue Transponder hinzufügen",
|
||||||
"",// TODO
|
"",// TODO
|
||||||
"",// TODO
|
"aggiungere transponder nuovi",
|
||||||
"",// TODO
|
"",// TODO
|
||||||
"",// TODO
|
"",// TODO
|
||||||
"",// TODO
|
"",// TODO
|
||||||
@ -3454,7 +3496,7 @@ const tI18nPhrase Phrases[] = {
|
|||||||
{ "Setup.Recording$Use VPS",
|
{ "Setup.Recording$Use VPS",
|
||||||
"VPS benutzen",
|
"VPS benutzen",
|
||||||
"",// TODO
|
"",// TODO
|
||||||
"",// TODO
|
"Utilizzare VPS",
|
||||||
"",// TODO
|
"",// TODO
|
||||||
"",// TODO
|
"",// TODO
|
||||||
"",// TODO
|
"",// TODO
|
||||||
@ -3475,7 +3517,7 @@ const tI18nPhrase Phrases[] = {
|
|||||||
{ "Setup.Recording$VPS margin (s)",
|
{ "Setup.Recording$VPS margin (s)",
|
||||||
"Zeitpuffer bei VPS (s)",
|
"Zeitpuffer bei VPS (s)",
|
||||||
"",// TODO
|
"",// TODO
|
||||||
"",// TODO
|
"Margine VPS",
|
||||||
"",// TODO
|
"",// TODO
|
||||||
"",// TODO
|
"",// TODO
|
||||||
"",// TODO
|
"",// TODO
|
||||||
@ -3556,27 +3598,6 @@ const tI18nPhrase Phrases[] = {
|
|||||||
"Otsesalvestuse kestus (min)",
|
"Otsesalvestuse kestus (min)",
|
||||||
"Længde af direkte optagelse (min)",
|
"Længde af direkte optagelse (min)",
|
||||||
},
|
},
|
||||||
{ "Setup.Recording$Record Dolby Digital",
|
|
||||||
"Dolby Digital Ton aufzeichnen",
|
|
||||||
"Posnemi dolby digital",
|
|
||||||
"Registra Dolby Digital",
|
|
||||||
"Dolby Digital geluid opnamen",
|
|
||||||
"Gravar em Dolby Digital",
|
|
||||||
"Enregistrer en Dolby Digital",
|
|
||||||
"Ta opp Dolby Digital lyd",
|
|
||||||
"Dolby Digital tallennus",
|
|
||||||
"Nagrywac Dolby Digital",
|
|
||||||
"Grabar sonido Dolby Digital",
|
|
||||||
"ÅããñáöÞ ôïõ Dolby Digital Þ÷ïõ",
|
|
||||||
"Spela in ljudet med Dolby Digital",
|
|
||||||
"Înregistreazã Dolby Digital",
|
|
||||||
"Dolby Digitál felvétel",
|
|
||||||
"Gravar el so en Dolby Digital",
|
|
||||||
"·ÐßØáëÒÐâì ×ÒãÚ Dolby Digital",
|
|
||||||
"Snimi 'Dolby digital' ton",
|
|
||||||
"Dolby Digital salvestamine",
|
|
||||||
"Optag Dolby Digital lyd",
|
|
||||||
},
|
|
||||||
{ "Setup.Recording$Max. video file size (MB)",
|
{ "Setup.Recording$Max. video file size (MB)",
|
||||||
"Max. Video Dateigröße (MB)",
|
"Max. Video Dateigröße (MB)",
|
||||||
"Najvecja velikost datoteke (MB)",
|
"Najvecja velikost datoteke (MB)",
|
||||||
@ -3664,7 +3685,7 @@ const tI18nPhrase Phrases[] = {
|
|||||||
{ "Setup.Replay$Resume ID",
|
{ "Setup.Replay$Resume ID",
|
||||||
"Wiedergabe ID",
|
"Wiedergabe ID",
|
||||||
"Predvajalni ID",
|
"Predvajalni ID",
|
||||||
"Resume ID",// TODO
|
"ID Ripresa",
|
||||||
"Hervattings ID",
|
"Hervattings ID",
|
||||||
"Resume ID",// TODO
|
"Resume ID",// TODO
|
||||||
"ID de reprise",
|
"ID de reprise",
|
||||||
@ -3685,7 +3706,7 @@ const tI18nPhrase Phrases[] = {
|
|||||||
{ "Setup.Miscellaneous$Min. event timeout (min)",
|
{ "Setup.Miscellaneous$Min. event timeout (min)",
|
||||||
"Mindest Event Pause (min)",
|
"Mindest Event Pause (min)",
|
||||||
"Najmanjsi cas dogodka (min)",
|
"Najmanjsi cas dogodka (min)",
|
||||||
"Tempo minimo di pausa (min)", // ??? i don't know...
|
"Spegnimento: controllo prossimo evento (m)",
|
||||||
"Minimale event time-out (min)",
|
"Minimale event time-out (min)",
|
||||||
"Período mínimo de pausa (min)",
|
"Período mínimo de pausa (min)",
|
||||||
"MinEventTimeout (min)",
|
"MinEventTimeout (min)",
|
||||||
@ -3706,7 +3727,7 @@ const tI18nPhrase Phrases[] = {
|
|||||||
{ "Setup.Miscellaneous$Min. user inactivity (min)",
|
{ "Setup.Miscellaneous$Min. user inactivity (min)",
|
||||||
"Mindest Benutzer-Inaktivität (min)",
|
"Mindest Benutzer-Inaktivität (min)",
|
||||||
"Najmanjsi cas neaktivnosti (min)",
|
"Najmanjsi cas neaktivnosti (min)",
|
||||||
"Tempo minimo di inattivita' (min)",
|
"Spegnimento: tempo minimo di inattività (m)",
|
||||||
"Minimum gebruikers inactiviteit (min)",
|
"Minimum gebruikers inactiviteit (min)",
|
||||||
"Período mínimo de inactividade (min)",
|
"Período mínimo de inactividade (min)",
|
||||||
"Durée minimale d'inact. (min)",
|
"Durée minimale d'inact. (min)",
|
||||||
@ -3748,7 +3769,7 @@ const tI18nPhrase Phrases[] = {
|
|||||||
{ "Setup.Miscellaneous$Zap timeout (s)",
|
{ "Setup.Miscellaneous$Zap timeout (s)",
|
||||||
"Zap Timeout (s)",
|
"Zap Timeout (s)",
|
||||||
"",// TODO
|
"",// TODO
|
||||||
"",// TODO
|
"Timeout Zapping",
|
||||||
"Zap timeout (s)",
|
"Zap timeout (s)",
|
||||||
"",// TODO
|
"",// TODO
|
||||||
"",// TODO
|
"",// TODO
|
||||||
@ -4151,7 +4172,7 @@ const tI18nPhrase Phrases[] = {
|
|||||||
{ "Down",
|
{ "Down",
|
||||||
"Ab",
|
"Ab",
|
||||||
"Dol",
|
"Dol",
|
||||||
"Giu",
|
"Giù",
|
||||||
"Omlaag",
|
"Omlaag",
|
||||||
"Baixo",
|
"Baixo",
|
||||||
"Bas",
|
"Bas",
|
||||||
@ -4172,7 +4193,7 @@ const tI18nPhrase Phrases[] = {
|
|||||||
{ "Menu",
|
{ "Menu",
|
||||||
"Menü",
|
"Menü",
|
||||||
"Meni",
|
"Meni",
|
||||||
"Menu",
|
"Menù",
|
||||||
"Menu",
|
"Menu",
|
||||||
"Menu",
|
"Menu",
|
||||||
"Menu",
|
"Menu",
|
||||||
@ -4610,6 +4631,27 @@ const tI18nPhrase Phrases[] = {
|
|||||||
"Hääletu",
|
"Hääletu",
|
||||||
"Sluk lyd",
|
"Sluk lyd",
|
||||||
},
|
},
|
||||||
|
{ "Audio",
|
||||||
|
"Audio",
|
||||||
|
"",// TODO
|
||||||
|
"",// TODO
|
||||||
|
"",// TODO
|
||||||
|
"",// TODO
|
||||||
|
"",// TODO
|
||||||
|
"",// TODO
|
||||||
|
"",// TODO
|
||||||
|
"",// TODO
|
||||||
|
"",// TODO
|
||||||
|
"",// TODO
|
||||||
|
"",// TODO
|
||||||
|
"",// TODO
|
||||||
|
"",// TODO
|
||||||
|
"",// TODO
|
||||||
|
"",// TODO
|
||||||
|
"",// TODO
|
||||||
|
"",// TODO
|
||||||
|
"",// TODO
|
||||||
|
},
|
||||||
// Miscellaneous:
|
// Miscellaneous:
|
||||||
{ "yes",
|
{ "yes",
|
||||||
"ja",
|
"ja",
|
||||||
@ -4929,7 +4971,7 @@ const tI18nPhrase Phrases[] = {
|
|||||||
{ "Up/Dn for new location - OK to move",
|
{ "Up/Dn for new location - OK to move",
|
||||||
"Auf/Ab für neue Position - dann OK",
|
"Auf/Ab für neue Position - dann OK",
|
||||||
"Gor/Dol za novo poz. - Ok za premik",
|
"Gor/Dol za novo poz. - Ok za premik",
|
||||||
"Su/Giu per nuova posizione - OK per muovere",
|
"Su/Giù per nuova posizione - OK per muovere",
|
||||||
"Gebruik Omhoog/Omlaag - daarna Ok",
|
"Gebruik Omhoog/Omlaag - daarna Ok",
|
||||||
"Cima/Baixo para nova localização - Ok para mover",
|
"Cima/Baixo para nova localização - Ok para mover",
|
||||||
"Haut/Bas -> nouvelle place - OK -> déplacer",
|
"Haut/Bas -> nouvelle place - OK -> déplacer",
|
||||||
@ -5076,7 +5118,7 @@ const tI18nPhrase Phrases[] = {
|
|||||||
{ "Classic VDR",
|
{ "Classic VDR",
|
||||||
"Klassischer VDR",
|
"Klassischer VDR",
|
||||||
"",// TODO
|
"",// TODO
|
||||||
"",// TODO
|
"VDR Classico",
|
||||||
"",// TODO
|
"",// TODO
|
||||||
"",// TODO
|
"",// TODO
|
||||||
"",// TODO
|
"",// TODO
|
||||||
@ -5097,7 +5139,7 @@ const tI18nPhrase Phrases[] = {
|
|||||||
{ "ST:TNG Panels",
|
{ "ST:TNG Panels",
|
||||||
"ST:TNG Konsolen",
|
"ST:TNG Konsolen",
|
||||||
"",// TODO
|
"",// TODO
|
||||||
"",// TODO
|
"Consolles ST:TNG",
|
||||||
"",// TODO
|
"",// TODO
|
||||||
"",// TODO
|
"",// TODO
|
||||||
"",// TODO
|
"",// TODO
|
||||||
|
6
keys.c
6
keys.c
@ -4,7 +4,7 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* how to reach the author.
|
||||||
*
|
*
|
||||||
* $Id: keys.c 1.5 2003/09/14 10:07:47 kls Exp $
|
* $Id: keys.c 1.7 2004/12/27 11:08:34 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "keys.h"
|
#include "keys.h"
|
||||||
@ -44,6 +44,7 @@ static tKey keyTable[] = { // "Up" and "Down" must be the first two keys!
|
|||||||
{ kVolUp, "Volume+" },
|
{ kVolUp, "Volume+" },
|
||||||
{ kVolDn, "Volume-" },
|
{ kVolDn, "Volume-" },
|
||||||
{ kMute, "Mute" },
|
{ kMute, "Mute" },
|
||||||
|
{ kAudio, "Audio" },
|
||||||
{ kSchedule, "Schedule" },
|
{ kSchedule, "Schedule" },
|
||||||
{ kChannels, "Channels" },
|
{ kChannels, "Channels" },
|
||||||
{ kTimers, "Timers" },
|
{ kTimers, "Timers" },
|
||||||
@ -195,7 +196,8 @@ bool cKeyMacro::Parse(char *s)
|
|||||||
{
|
{
|
||||||
int n = 0;
|
int n = 0;
|
||||||
char *p;
|
char *p;
|
||||||
while ((p = strtok(s, " \t")) != NULL) {
|
char *strtok_next;
|
||||||
|
while ((p = strtok_r(s, " \t", &strtok_next)) != NULL) {
|
||||||
if (n < MAXKEYSINMACRO) {
|
if (n < MAXKEYSINMACRO) {
|
||||||
if (*p == '@') {
|
if (*p == '@') {
|
||||||
if (plugin) {
|
if (plugin) {
|
||||||
|
3
keys.h
3
keys.h
@ -4,7 +4,7 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* how to reach the author.
|
||||||
*
|
*
|
||||||
* $Id: 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
|
#ifndef __KEYS_H
|
||||||
@ -38,6 +38,7 @@ enum eKeys { // "Up" and "Down" must be the first two keys!
|
|||||||
kVolUp,
|
kVolUp,
|
||||||
kVolDn,
|
kVolDn,
|
||||||
kMute,
|
kMute,
|
||||||
|
kAudio,
|
||||||
kSchedule,
|
kSchedule,
|
||||||
kChannels,
|
kChannels,
|
||||||
kTimers,
|
kTimers,
|
||||||
|
21
lirc.c
21
lirc.c
@ -6,7 +6,7 @@
|
|||||||
*
|
*
|
||||||
* LIRC support added by Carsten Koch <Carsten.Koch@icem.de> 2000-06-16.
|
* LIRC support added by Carsten Koch <Carsten.Koch@icem.de> 2000-06-16.
|
||||||
*
|
*
|
||||||
* $Id: lirc.c 1.7 2003/10/18 11:34:02 kls Exp $
|
* $Id: lirc.c 1.9 2004/12/19 18:05:13 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "lirc.h"
|
#include "lirc.h"
|
||||||
@ -41,6 +41,8 @@ cLircRemote::cLircRemote(char *DeviceName)
|
|||||||
cLircRemote::~cLircRemote()
|
cLircRemote::~cLircRemote()
|
||||||
{
|
{
|
||||||
Cancel();
|
Cancel();
|
||||||
|
if (f >= 0)
|
||||||
|
close(f);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool cLircRemote::Ready(void)
|
bool cLircRemote::Ready(void)
|
||||||
@ -50,8 +52,8 @@ bool cLircRemote::Ready(void)
|
|||||||
|
|
||||||
void cLircRemote::Action(void)
|
void cLircRemote::Action(void)
|
||||||
{
|
{
|
||||||
int FirstTime = 0;
|
cTimeMs FirstTime;
|
||||||
int LastTime = 0;
|
cTimeMs LastTime;
|
||||||
char buf[LIRC_BUFFER_SIZE];
|
char buf[LIRC_BUFFER_SIZE];
|
||||||
char LastKeyName[LIRC_KEY_BUF] = "";
|
char LastKeyName[LIRC_KEY_BUF] = "";
|
||||||
bool repeat = false;
|
bool repeat = false;
|
||||||
@ -59,8 +61,6 @@ void cLircRemote::Action(void)
|
|||||||
|
|
||||||
for (; f >= 0;) {
|
for (; f >= 0;) {
|
||||||
|
|
||||||
LOCK_THREAD;
|
|
||||||
|
|
||||||
bool ready = cFile::FileReady(f, timeout);
|
bool ready = cFile::FileReady(f, timeout);
|
||||||
int ret = ready ? safe_read(f, buf, sizeof(buf)) : -1;
|
int ret = ready ? safe_read(f, buf, sizeof(buf)) : -1;
|
||||||
|
|
||||||
@ -75,28 +75,27 @@ void cLircRemote::Action(void)
|
|||||||
int count;
|
int count;
|
||||||
char KeyName[LIRC_KEY_BUF];
|
char KeyName[LIRC_KEY_BUF];
|
||||||
sscanf(buf, "%*x %x %29s", &count, KeyName); // '29' in '%29s' is LIRC_KEY_BUF-1!
|
sscanf(buf, "%*x %x %29s", &count, KeyName); // '29' in '%29s' is LIRC_KEY_BUF-1!
|
||||||
int Now = time_ms();
|
|
||||||
if (count == 0) {
|
if (count == 0) {
|
||||||
if (strcmp(KeyName, LastKeyName) == 0 && Now - FirstTime < KEYPRESSDELAY)
|
if (strcmp(KeyName, LastKeyName) == 0 && FirstTime.Elapsed() < KEYPRESSDELAY)
|
||||||
continue; // skip keys coming in too fast
|
continue; // skip keys coming in too fast
|
||||||
if (repeat)
|
if (repeat)
|
||||||
Put(LastKeyName, false, true);
|
Put(LastKeyName, false, true);
|
||||||
strcpy(LastKeyName, KeyName);
|
strcpy(LastKeyName, KeyName);
|
||||||
repeat = false;
|
repeat = false;
|
||||||
FirstTime = Now;
|
FirstTime.Set();
|
||||||
timeout = -1;
|
timeout = -1;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (Now - FirstTime < REPEATDELAY)
|
if (FirstTime.Elapsed() < REPEATDELAY)
|
||||||
continue; // repeat function kicks in after a short delay
|
continue; // repeat function kicks in after a short delay
|
||||||
repeat = true;
|
repeat = true;
|
||||||
timeout = REPEATDELAY;
|
timeout = REPEATDELAY;
|
||||||
}
|
}
|
||||||
LastTime = Now;
|
LastTime.Set();
|
||||||
Put(KeyName, repeat);
|
Put(KeyName, repeat);
|
||||||
}
|
}
|
||||||
else if (repeat) { // the last one was a repeat, so let's generate a release
|
else if (repeat) { // the last one was a repeat, so let's generate a release
|
||||||
if (time_ms() - LastTime >= REPEATDELAY) {
|
if (LastTime.Elapsed() >= REPEATDELAY) {
|
||||||
Put(LastKeyName, false, true);
|
Put(LastKeyName, false, true);
|
||||||
repeat = false;
|
repeat = false;
|
||||||
*LastKeyName = 0;
|
*LastKeyName = 0;
|
||||||
|
271
menu.c
271
menu.c
@ -4,7 +4,7 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* how to reach the author.
|
||||||
*
|
*
|
||||||
* $Id: menu.c 1.320 2004/11/20 10:49:17 kls Exp $
|
* $Id: menu.c 1.334 2005/01/09 13:04:49 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "menu.h"
|
#include "menu.h"
|
||||||
@ -116,7 +116,7 @@ void cMenuEditSrcItem::Set(void)
|
|||||||
{
|
{
|
||||||
if (source) {
|
if (source) {
|
||||||
char *buffer = NULL;
|
char *buffer = NULL;
|
||||||
asprintf(&buffer, "%s - %s", cSource::ToString(source->Code()), source->Description());
|
asprintf(&buffer, "%s - %s", *cSource::ToString(source->Code()), source->Description());
|
||||||
SetValue(buffer);
|
SetValue(buffer);
|
||||||
free(buffer);
|
free(buffer);
|
||||||
}
|
}
|
||||||
@ -249,7 +249,7 @@ cMenuEditChannel::cMenuEditChannel(cChannel *Channel, bool New)
|
|||||||
void cMenuEditChannel::Setup(void)
|
void cMenuEditChannel::Setup(void)
|
||||||
{
|
{
|
||||||
int current = Current();
|
int current = Current();
|
||||||
char type = *cSource::ToString(data.source);
|
char type = **cSource::ToString(data.source);
|
||||||
#define ST(s) if (strchr(s, type))
|
#define ST(s) if (strchr(s, type))
|
||||||
|
|
||||||
Clear();
|
Clear();
|
||||||
@ -274,7 +274,7 @@ void cMenuEditChannel::Setup(void)
|
|||||||
Add(new cMenuEditIntItem( tr("Rid"), &data.rid, 0));
|
Add(new cMenuEditIntItem( tr("Rid"), &data.rid, 0));
|
||||||
XXX*/
|
XXX*/
|
||||||
// Parameters for specific types of sources:
|
// Parameters for specific types of sources:
|
||||||
ST(" S ") Add(new cMenuEditChrItem( tr("Polarization"), &data.polarization, "hv"));
|
ST(" S ") Add(new cMenuEditChrItem( tr("Polarization"), &data.polarization, "hvlr"));
|
||||||
ST("CS ") Add(new cMenuEditIntItem( tr("Srate"), &data.srate));
|
ST("CS ") Add(new cMenuEditIntItem( tr("Srate"), &data.srate));
|
||||||
ST("CST") Add(new cMenuEditMapItem( tr("Inversion"), &data.inversion, InversionValues, tr("off")));
|
ST("CST") Add(new cMenuEditMapItem( tr("Inversion"), &data.inversion, InversionValues, tr("off")));
|
||||||
ST("CST") Add(new cMenuEditMapItem( tr("CoderateH"), &data.coderateH, CoderateValues, tr("none")));
|
ST("CST") Add(new cMenuEditMapItem( tr("CoderateH"), &data.coderateH, CoderateValues, tr("none")));
|
||||||
@ -300,7 +300,7 @@ eOSState cMenuEditChannel::ProcessKey(eKeys Key)
|
|||||||
data.name = strcpyrealloc(data.name, name);
|
data.name = strcpyrealloc(data.name, name);
|
||||||
if (channel) {
|
if (channel) {
|
||||||
*channel = data;
|
*channel = data;
|
||||||
isyslog("edited channel %d %s", channel->Number(), data.ToText());
|
isyslog("edited channel %d %s", channel->Number(), *data.ToText());
|
||||||
state = osBack;
|
state = osBack;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -308,7 +308,7 @@ eOSState cMenuEditChannel::ProcessKey(eKeys Key)
|
|||||||
*channel = data;
|
*channel = data;
|
||||||
Channels.Add(channel);
|
Channels.Add(channel);
|
||||||
Channels.ReNumber();
|
Channels.ReNumber();
|
||||||
isyslog("added channel %d %s", channel->Number(), data.ToText());
|
isyslog("added channel %d %s", channel->Number(), *data.ToText());
|
||||||
state = osUser1;
|
state = osUser1;
|
||||||
}
|
}
|
||||||
Channels.SetModified(true);
|
Channels.SetModified(true);
|
||||||
@ -737,9 +737,9 @@ void cMenuTimerItem::Set(void)
|
|||||||
asprintf(&buffer, "%c\t%d\t%s%s%s\t%02d:%02d\t%02d:%02d\t%s",
|
asprintf(&buffer, "%c\t%d\t%s%s%s\t%02d:%02d\t%02d:%02d\t%s",
|
||||||
!(timer->HasFlags(tfActive)) ? ' ' : timer->FirstDay() ? '!' : timer->Recording() ? '#' : '>',
|
!(timer->HasFlags(tfActive)) ? ' ' : timer->FirstDay() ? '!' : timer->Recording() ? '#' : '>',
|
||||||
timer->Channel()->Number(),
|
timer->Channel()->Number(),
|
||||||
timer->IsSingleEvent() ? WeekDayName(timer->StartTime()) : "",
|
timer->IsSingleEvent() ? *WeekDayName(timer->StartTime()) : "",
|
||||||
timer->IsSingleEvent() ? " " : "",
|
timer->IsSingleEvent() ? " " : "",
|
||||||
timer->PrintDay(timer->Day()),
|
*timer->PrintDay(timer->Day()),
|
||||||
timer->Start() / 100,
|
timer->Start() / 100,
|
||||||
timer->Start() % 100,
|
timer->Start() % 100,
|
||||||
timer->Stop() / 100,
|
timer->Stop() / 100,
|
||||||
@ -795,7 +795,7 @@ eOSState cMenuTimers::OnOff(void)
|
|||||||
RefreshCurrent();
|
RefreshCurrent();
|
||||||
DisplayCurrent(true);
|
DisplayCurrent(true);
|
||||||
if (timer->FirstDay())
|
if (timer->FirstDay())
|
||||||
isyslog("timer %d first day set to %s", timer->Index() + 1, timer->PrintFirstDay());
|
isyslog("timer %d first day set to %s", timer->Index() + 1, *timer->PrintFirstDay());
|
||||||
else
|
else
|
||||||
isyslog("timer %d %sactivated", timer->Index() + 1, timer->HasFlags(tfActive) ? "" : "de");
|
isyslog("timer %d %sactivated", timer->Index() + 1, timer->HasFlags(tfActive) ? "" : "de");
|
||||||
Timers.SetModified();
|
Timers.SetModified();
|
||||||
@ -969,7 +969,7 @@ cMenuWhatsOnItem::cMenuWhatsOnItem(const cEvent *Event, cChannel *Channel)
|
|||||||
char t = Timers.GetMatch(Event, &TimerMatch) ? (TimerMatch == tmFull) ? 'T' : 't' : ' ';
|
char t = Timers.GetMatch(Event, &TimerMatch) ? (TimerMatch == tmFull) ? 'T' : 't' : ' ';
|
||||||
char v = event->Vps() && (event->Vps() - event->StartTime()) ? 'V' : ' ';
|
char v = event->Vps() && (event->Vps() - event->StartTime()) ? 'V' : ' ';
|
||||||
char r = event->IsRunning() ? '*' : ' ';
|
char r = event->IsRunning() ? '*' : ' ';
|
||||||
asprintf(&buffer, "%d\t%.*s\t%s\t%c%c%c\t%s", channel->Number(), 6, channel->ShortName(true), event->GetTimeString(), t, v, r, event->Title());
|
asprintf(&buffer, "%d\t%.*s\t%s\t%c%c%c\t%s", channel->Number(), 6, channel->ShortName(true), *event->GetTimeString(), t, v, r, event->Title());
|
||||||
SetText(buffer, false);
|
SetText(buffer, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1087,7 +1087,7 @@ cMenuScheduleItem::cMenuScheduleItem(const cEvent *Event)
|
|||||||
char t = Timers.GetMatch(Event, &TimerMatch) ? (TimerMatch == tmFull) ? 'T' : 't' : ' ';
|
char t = Timers.GetMatch(Event, &TimerMatch) ? (TimerMatch == tmFull) ? 'T' : 't' : ' ';
|
||||||
char v = event->Vps() && (event->Vps() - event->StartTime()) ? 'V' : ' ';
|
char v = event->Vps() && (event->Vps() - event->StartTime()) ? 'V' : ' ';
|
||||||
char r = event->IsRunning() ? '*' : ' ';
|
char r = event->IsRunning() ? '*' : ' ';
|
||||||
asprintf(&buffer, "%.*s\t%s\t%c%c%c\t%s", 6, event->GetDateString(), event->GetTimeString(), t, v, r, event->Title());
|
asprintf(&buffer, "%.*s\t%s\t%c%c%c\t%s", 6, *event->GetDateString(), *event->GetTimeString(), t, v, r, event->Title());
|
||||||
SetText(buffer, false);
|
SetText(buffer, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1911,6 +1911,9 @@ eOSState cMenuSetupEPG::ProcessKey(eKeys Key)
|
|||||||
|
|
||||||
class cMenuSetupDVB : public cMenuSetupBase {
|
class cMenuSetupDVB : public cMenuSetupBase {
|
||||||
private:
|
private:
|
||||||
|
int originalNumAudioLanguages;
|
||||||
|
int numAudioLanguages;
|
||||||
|
void Setup(void);
|
||||||
const char *updateChannelsTexts[5];
|
const char *updateChannelsTexts[5];
|
||||||
public:
|
public:
|
||||||
cMenuSetupDVB(void);
|
cMenuSetupDVB(void);
|
||||||
@ -1919,6 +1922,9 @@ public:
|
|||||||
|
|
||||||
cMenuSetupDVB::cMenuSetupDVB(void)
|
cMenuSetupDVB::cMenuSetupDVB(void)
|
||||||
{
|
{
|
||||||
|
for (numAudioLanguages = 0; numAudioLanguages < I18nNumLanguages && data.AudioLanguages[numAudioLanguages] >= 0; numAudioLanguages++)
|
||||||
|
;
|
||||||
|
originalNumAudioLanguages = numAudioLanguages;
|
||||||
updateChannelsTexts[0] = tr("no");
|
updateChannelsTexts[0] = tr("no");
|
||||||
updateChannelsTexts[1] = tr("names only");
|
updateChannelsTexts[1] = tr("names only");
|
||||||
updateChannelsTexts[2] = tr("names and PIDs");
|
updateChannelsTexts[2] = tr("names and PIDs");
|
||||||
@ -1926,22 +1932,59 @@ cMenuSetupDVB::cMenuSetupDVB(void)
|
|||||||
updateChannelsTexts[4] = tr("add new transponders");
|
updateChannelsTexts[4] = tr("add new transponders");
|
||||||
|
|
||||||
SetSection(tr("DVB"));
|
SetSection(tr("DVB"));
|
||||||
|
Setup();
|
||||||
|
}
|
||||||
|
|
||||||
|
void cMenuSetupDVB::Setup(void)
|
||||||
|
{
|
||||||
|
int current = Current();
|
||||||
|
|
||||||
|
Clear();
|
||||||
|
|
||||||
Add(new cMenuEditIntItem( tr("Setup.DVB$Primary DVB interface"), &data.PrimaryDVB, 1, cDevice::NumDevices()));
|
Add(new cMenuEditIntItem( tr("Setup.DVB$Primary DVB interface"), &data.PrimaryDVB, 1, cDevice::NumDevices()));
|
||||||
Add(new cMenuEditBoolItem(tr("Setup.DVB$Video format"), &data.VideoFormat, "4:3", "16:9"));
|
Add(new cMenuEditBoolItem(tr("Setup.DVB$Video format"), &data.VideoFormat, "4:3", "16:9"));
|
||||||
|
Add(new cMenuEditBoolItem(tr("Setup.DVB$Use Dolby Digital"), &data.UseDolbyDigital));
|
||||||
Add(new cMenuEditStraItem(tr("Setup.DVB$Update channels"), &data.UpdateChannels, 5, updateChannelsTexts));
|
Add(new cMenuEditStraItem(tr("Setup.DVB$Update channels"), &data.UpdateChannels, 5, updateChannelsTexts));
|
||||||
|
Add(new cMenuEditIntItem( tr("Setup.DVB$Audio languages"), &numAudioLanguages, 0, I18nNumLanguages));
|
||||||
|
for (int i = 0; i < numAudioLanguages; i++)
|
||||||
|
Add(new cMenuEditStraItem(tr("Setup.EPG$Audio language"), &data.AudioLanguages[i], I18nNumLanguages, I18nLanguages()));
|
||||||
|
|
||||||
|
SetCurrent(Get(current));
|
||||||
|
Display();
|
||||||
}
|
}
|
||||||
|
|
||||||
eOSState cMenuSetupDVB::ProcessKey(eKeys Key)
|
eOSState cMenuSetupDVB::ProcessKey(eKeys Key)
|
||||||
{
|
{
|
||||||
int oldPrimaryDVB = Setup.PrimaryDVB;
|
int oldPrimaryDVB = ::Setup.PrimaryDVB;
|
||||||
bool oldVideoFormat = Setup.VideoFormat;
|
bool oldVideoFormat = ::Setup.VideoFormat;
|
||||||
|
int oldnumAudioLanguages = numAudioLanguages;
|
||||||
eOSState state = cMenuSetupBase::ProcessKey(Key);
|
eOSState state = cMenuSetupBase::ProcessKey(Key);
|
||||||
|
|
||||||
|
if (Key != kNone) {
|
||||||
|
if (numAudioLanguages != oldnumAudioLanguages) {
|
||||||
|
for (int i = oldnumAudioLanguages; i < numAudioLanguages; i++) {
|
||||||
|
data.AudioLanguages[i] = 0;
|
||||||
|
for (int l = 0; l < I18nNumLanguages; l++) {
|
||||||
|
int k;
|
||||||
|
for (k = 0; k < oldnumAudioLanguages; k++) {
|
||||||
|
if (data.AudioLanguages[k] == l)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (k >= oldnumAudioLanguages) {
|
||||||
|
data.AudioLanguages[i] = l;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
data.AudioLanguages[numAudioLanguages] = -1;
|
||||||
|
Setup();
|
||||||
|
}
|
||||||
|
}
|
||||||
if (state == osBack && Key == kOk) {
|
if (state == osBack && Key == kOk) {
|
||||||
if (Setup.PrimaryDVB != oldPrimaryDVB)
|
if (::Setup.PrimaryDVB != oldPrimaryDVB)
|
||||||
state = osSwitchDvb;
|
state = osSwitchDvb;
|
||||||
if (Setup.VideoFormat != oldVideoFormat)
|
if (::Setup.VideoFormat != oldVideoFormat)
|
||||||
cDevice::PrimaryDevice()->SetVideoFormat(Setup.VideoFormat);
|
cDevice::PrimaryDevice()->SetVideoFormat(::Setup.VideoFormat);
|
||||||
}
|
}
|
||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
@ -2111,7 +2154,6 @@ cMenuSetupRecord::cMenuSetupRecord(void)
|
|||||||
Add(new cMenuEditBoolItem(tr("Setup.Recording$Mark instant recording"), &data.MarkInstantRecord));
|
Add(new cMenuEditBoolItem(tr("Setup.Recording$Mark instant recording"), &data.MarkInstantRecord));
|
||||||
Add(new cMenuEditStrItem( tr("Setup.Recording$Name instant recording"), data.NameInstantRecord, sizeof(data.NameInstantRecord), tr(FileNameChars)));
|
Add(new cMenuEditStrItem( tr("Setup.Recording$Name instant recording"), data.NameInstantRecord, sizeof(data.NameInstantRecord), tr(FileNameChars)));
|
||||||
Add(new cMenuEditIntItem( tr("Setup.Recording$Instant rec. time (min)"), &data.InstantRecordTime, 1, MAXINSTANTRECTIME));
|
Add(new cMenuEditIntItem( tr("Setup.Recording$Instant rec. time (min)"), &data.InstantRecordTime, 1, MAXINSTANTRECTIME));
|
||||||
Add(new cMenuEditBoolItem(tr("Setup.Recording$Record Dolby Digital"), &data.RecordDolbyDigital));
|
|
||||||
Add(new cMenuEditIntItem( tr("Setup.Recording$Max. video file size (MB)"), &data.MaxVideoFileSize, MINVIDEOFILESIZE, MAXVIDEOFILESIZE));
|
Add(new cMenuEditIntItem( tr("Setup.Recording$Max. video file size (MB)"), &data.MaxVideoFileSize, MINVIDEOFILESIZE, MAXVIDEOFILESIZE));
|
||||||
Add(new cMenuEditBoolItem(tr("Setup.Recording$Split edited files"), &data.SplitEditedFiles));
|
Add(new cMenuEditBoolItem(tr("Setup.Recording$Split edited files"), &data.SplitEditedFiles));
|
||||||
}
|
}
|
||||||
@ -2410,7 +2452,7 @@ void cMenuMain::Set(const char *Plugin)
|
|||||||
|
|
||||||
// Color buttons:
|
// 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();
|
Display();
|
||||||
lastActivity = time(NULL);
|
lastActivity = time(NULL);
|
||||||
}
|
}
|
||||||
@ -2471,13 +2513,8 @@ eOSState cMenuMain::ProcessKey(eKeys Key)
|
|||||||
state = replaying ? osContinue : osRecord;
|
state = replaying ? osContinue : osRecord;
|
||||||
break;
|
break;
|
||||||
case kGreen: if (!HadSubMenu) {
|
case kGreen: if (!HadSubMenu) {
|
||||||
int CurrentAudioTrack = -1;
|
if (cDevice::PrimaryDevice()->NumAudioTracks() > 1) {
|
||||||
const char **AudioTracks = cDevice::PrimaryDevice()->GetAudioTracks(&CurrentAudioTrack);
|
cRemote::Put(kAudio, true);
|
||||||
if (AudioTracks) {
|
|
||||||
const char **at = &AudioTracks[CurrentAudioTrack];
|
|
||||||
if (!*++at)
|
|
||||||
at = AudioTracks;
|
|
||||||
cDevice::PrimaryDevice()->SetAudioTrack(at - AudioTracks);
|
|
||||||
state = osEnd;
|
state = osEnd;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2504,6 +2541,40 @@ eOSState cMenuMain::ProcessKey(eKeys Key)
|
|||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// --- SetTrackDescriptions --------------------------------------------------
|
||||||
|
|
||||||
|
static void SetTrackDescriptions(void)
|
||||||
|
{
|
||||||
|
cDevice::PrimaryDevice()->ClrAvailableTracks(true);
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// --- cDisplayChannel -------------------------------------------------------
|
// --- cDisplayChannel -------------------------------------------------------
|
||||||
|
|
||||||
#define DIRECTCHANNELTIMEOUT 1000 //ms
|
#define DIRECTCHANNELTIMEOUT 1000 //ms
|
||||||
@ -2523,7 +2594,7 @@ cDisplayChannel::cDisplayChannel(int Number, bool Switched)
|
|||||||
DisplayInfo();
|
DisplayInfo();
|
||||||
displayChannel->Flush();
|
displayChannel->Flush();
|
||||||
}
|
}
|
||||||
lastTime = time_ms();
|
lastTime.Set();
|
||||||
}
|
}
|
||||||
|
|
||||||
cDisplayChannel::cDisplayChannel(eKeys FirstKey)
|
cDisplayChannel::cDisplayChannel(eKeys FirstKey)
|
||||||
@ -2532,7 +2603,7 @@ cDisplayChannel::cDisplayChannel(eKeys FirstKey)
|
|||||||
group = -1;
|
group = -1;
|
||||||
number = 0;
|
number = 0;
|
||||||
lastPresent = lastFollowing = NULL;
|
lastPresent = lastFollowing = NULL;
|
||||||
lastTime = time_ms();
|
lastTime.Set();
|
||||||
withInfo = Setup.ShowInfoOnChSwitch;
|
withInfo = Setup.ShowInfoOnChSwitch;
|
||||||
displayChannel = Skins.Current()->DisplayChannel(withInfo);
|
displayChannel = Skins.Current()->DisplayChannel(withInfo);
|
||||||
ProcessKey(FirstKey);
|
ProcessKey(FirstKey);
|
||||||
@ -2562,6 +2633,7 @@ void cDisplayChannel::DisplayInfo(void)
|
|||||||
const cEvent *Present = Schedule->GetPresentEvent(true);
|
const cEvent *Present = Schedule->GetPresentEvent(true);
|
||||||
const cEvent *Following = Schedule->GetFollowingEvent(true);
|
const cEvent *Following = Schedule->GetFollowingEvent(true);
|
||||||
if (Present != lastPresent || Following != lastFollowing) {
|
if (Present != lastPresent || Following != lastFollowing) {
|
||||||
|
SetTrackDescriptions();
|
||||||
displayChannel->SetEvents(Present, Following);
|
displayChannel->SetEvents(Present, Following);
|
||||||
cStatus::MsgOsdProgramme(Present ? Present->StartTime() : 0, Present ? Present->Title() : NULL, Present ? Present->ShortText() : NULL, Following ? Following->StartTime() : 0, Following ? Following->Title() : NULL, Following ? Following->ShortText() : NULL);
|
cStatus::MsgOsdProgramme(Present ? Present->StartTime() : 0, Present ? Present->Title() : NULL, Present ? Present->ShortText() : NULL, Following ? Following->StartTime() : 0, Following ? Following->Title() : NULL, Following ? Following->ShortText() : NULL);
|
||||||
lastPresent = Present;
|
lastPresent = Present;
|
||||||
@ -2577,7 +2649,7 @@ void cDisplayChannel::Refresh(void)
|
|||||||
channel = Channels.GetByNumber(cDevice::CurrentChannel());
|
channel = Channels.GetByNumber(cDevice::CurrentChannel());
|
||||||
DisplayChannel();
|
DisplayChannel();
|
||||||
displayChannel->SetEvents(NULL, NULL);
|
displayChannel->SetEvents(NULL, NULL);
|
||||||
lastTime = time_ms();
|
lastTime.Set();
|
||||||
}
|
}
|
||||||
|
|
||||||
eOSState cDisplayChannel::ProcessKey(eKeys Key)
|
eOSState cDisplayChannel::ProcessKey(eKeys Key)
|
||||||
@ -2597,7 +2669,7 @@ eOSState cDisplayChannel::ProcessKey(eKeys Key)
|
|||||||
displayChannel->SetEvents(NULL, NULL);
|
displayChannel->SetEvents(NULL, NULL);
|
||||||
withInfo = false;
|
withInfo = false;
|
||||||
DisplayChannel();
|
DisplayChannel();
|
||||||
lastTime = time_ms();
|
lastTime.Set();
|
||||||
// Lets see if there can be any useful further input:
|
// Lets see if there can be any useful further input:
|
||||||
int n = channel ? number * 10 : 0;
|
int n = channel ? number * 10 : 0;
|
||||||
cChannel *ch = channel;
|
cChannel *ch = channel;
|
||||||
@ -2646,7 +2718,7 @@ eOSState cDisplayChannel::ProcessKey(eKeys Key)
|
|||||||
group = -1;
|
group = -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
lastTime = time_ms();
|
lastTime.Set();
|
||||||
break;
|
break;
|
||||||
case kUp|k_Repeat:
|
case kUp|k_Repeat:
|
||||||
case kUp:
|
case kUp:
|
||||||
@ -2663,14 +2735,14 @@ eOSState cDisplayChannel::ProcessKey(eKeys Key)
|
|||||||
Refresh();
|
Refresh();
|
||||||
break;
|
break;
|
||||||
case kNone:
|
case kNone:
|
||||||
if (number && time_ms() - lastTime > DIRECTCHANNELTIMEOUT) {
|
if (number && lastTime.Elapsed() > DIRECTCHANNELTIMEOUT) {
|
||||||
if (Channels.GetByNumber(number))
|
if (Channels.GetByNumber(number))
|
||||||
Channels.SwitchTo(number);
|
Channels.SwitchTo(number);
|
||||||
else {
|
else {
|
||||||
number = 0;
|
number = 0;
|
||||||
channel = NULL;
|
channel = NULL;
|
||||||
DisplayChannel();
|
DisplayChannel();
|
||||||
lastTime = time_ms();
|
lastTime.Set();
|
||||||
return osContinue;
|
return osContinue;
|
||||||
}
|
}
|
||||||
return osEnd;
|
return osEnd;
|
||||||
@ -2694,7 +2766,7 @@ eOSState cDisplayChannel::ProcessKey(eKeys Key)
|
|||||||
return osEnd;
|
return osEnd;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
if (time_ms() - lastTime < INFOTIMEOUT) {
|
if (lastTime.Elapsed() < INFOTIMEOUT) {
|
||||||
if (!number && group < 0 && channel && channel->Number() != cDevice::CurrentChannel())
|
if (!number && group < 0 && channel && channel->Number() != cDevice::CurrentChannel())
|
||||||
Refresh(); // makes sure a channel switch through the SVDRP CHAN command is displayed
|
Refresh(); // makes sure a channel switch through the SVDRP CHAN command is displayed
|
||||||
DisplayInfo();
|
DisplayInfo();
|
||||||
@ -2715,7 +2787,7 @@ cDisplayVolume::cDisplayVolume(void)
|
|||||||
:cOsdObject(true)
|
:cOsdObject(true)
|
||||||
{
|
{
|
||||||
currentDisplayVolume = this;
|
currentDisplayVolume = this;
|
||||||
timeout = time_ms() + (cDevice::PrimaryDevice()->IsMute() ? MUTETIMEOUT : VOLUMETIMEOUT);
|
timeout.Set(cDevice::PrimaryDevice()->IsMute() ? MUTETIMEOUT : VOLUMETIMEOUT);
|
||||||
displayVolume = Skins.Current()->DisplayVolume();
|
displayVolume = Skins.Current()->DisplayVolume();
|
||||||
Show();
|
Show();
|
||||||
}
|
}
|
||||||
@ -2752,15 +2824,15 @@ eOSState cDisplayVolume::ProcessKey(eKeys Key)
|
|||||||
case kVolDn|k_Repeat:
|
case kVolDn|k_Repeat:
|
||||||
case kVolDn:
|
case kVolDn:
|
||||||
Show();
|
Show();
|
||||||
timeout = time_ms() + VOLUMETIMEOUT;
|
timeout.Set(VOLUMETIMEOUT);
|
||||||
break;
|
break;
|
||||||
case kMute:
|
case kMute:
|
||||||
if (cDevice::PrimaryDevice()->IsMute()) {
|
if (cDevice::PrimaryDevice()->IsMute()) {
|
||||||
Show();
|
Show();
|
||||||
timeout = time_ms() + MUTETIMEOUT;
|
timeout.Set(MUTETIMEOUT);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
timeout = 0;
|
timeout.Set();
|
||||||
break;
|
break;
|
||||||
case kNone: break;
|
case kNone: break;
|
||||||
default: if ((Key & k_Release) == 0) {
|
default: if ((Key & k_Release) == 0) {
|
||||||
@ -2768,7 +2840,128 @@ eOSState cDisplayVolume::ProcessKey(eKeys Key)
|
|||||||
return osEnd;
|
return osEnd;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return time_ms() < timeout ? osContinue : osEnd;
|
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())
|
||||||
|
SetTrackDescriptions();
|
||||||
|
currentDisplayTracks = this;
|
||||||
|
numTracks = track = 0;
|
||||||
|
audioChannel = cDevice::PrimaryDevice()->GetAudioChannel();
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
int ac = IS_AUDIO_TRACK(types[track]) ? audioChannel : -1;
|
||||||
|
displayTracks->SetTrack(track, descriptions);
|
||||||
|
displayTracks->SetAudioChannel(ac);
|
||||||
|
displayTracks->Flush();
|
||||||
|
cStatus::MsgSetAudioTrack(track, descriptions);
|
||||||
|
cStatus::MsgSetAudioChannel(ac);
|
||||||
|
}
|
||||||
|
|
||||||
|
cDisplayTracks *cDisplayTracks::Create(void)
|
||||||
|
{
|
||||||
|
if (cDevice::PrimaryDevice()->NumAudioTracks() > 0) {
|
||||||
|
if (!currentDisplayTracks)
|
||||||
|
new cDisplayTracks;
|
||||||
|
return currentDisplayTracks;
|
||||||
|
}
|
||||||
|
Skins.Message(mtWarning, tr("No audio available!"));
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void cDisplayTracks::Process(eKeys Key)
|
||||||
|
{
|
||||||
|
if (currentDisplayTracks)
|
||||||
|
currentDisplayTracks->ProcessKey(Key);
|
||||||
|
}
|
||||||
|
|
||||||
|
eOSState cDisplayTracks::ProcessKey(eKeys Key)
|
||||||
|
{
|
||||||
|
int oldTrack = track;
|
||||||
|
int oldAudioChannel = audioChannel;
|
||||||
|
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 kLeft|k_Repeat:
|
||||||
|
case kLeft:
|
||||||
|
case kRight|k_Repeat:
|
||||||
|
case kRight: if (IS_AUDIO_TRACK(types[track])) {
|
||||||
|
static int ac[] = { 1, 0, 2 };
|
||||||
|
audioChannel = ac[cDevice::PrimaryDevice()->GetAudioChannel()];
|
||||||
|
if (NORMALKEY(Key) == kLeft && audioChannel > 0)
|
||||||
|
audioChannel--;
|
||||||
|
else if (NORMALKEY(Key) == kRight && audioChannel < 2)
|
||||||
|
audioChannel++;
|
||||||
|
audioChannel = ac[audioChannel];
|
||||||
|
timeout.Set(TRACKTIMEOUT);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case kAudio:
|
||||||
|
if (++track >= numTracks)
|
||||||
|
track = 0;
|
||||||
|
timeout.Set(TRACKTIMEOUT);
|
||||||
|
break;
|
||||||
|
case kOk:
|
||||||
|
if (track != cDevice::PrimaryDevice()->GetCurrentAudioTrack())
|
||||||
|
oldTrack = -1; // make sure we explicitly switch to that track
|
||||||
|
timeout.Set();
|
||||||
|
break;
|
||||||
|
case kNone: break;
|
||||||
|
default: if ((Key & k_Release) == 0)
|
||||||
|
return osEnd;
|
||||||
|
}
|
||||||
|
if (track != oldTrack || audioChannel != oldAudioChannel)
|
||||||
|
Show();
|
||||||
|
if (track != oldTrack) {
|
||||||
|
cDevice::PrimaryDevice()->SetCurrentAudioTrack(types[track]);
|
||||||
|
Setup.CurrentDolby = IS_DOLBY_TRACK(types[track]);
|
||||||
|
}
|
||||||
|
if (audioChannel != oldAudioChannel)
|
||||||
|
cDevice::PrimaryDevice()->SetAudioChannel(audioChannel);
|
||||||
|
return timeout.TimedOut() ? osEnd : osContinue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// --- cRecordControl --------------------------------------------------------
|
// --- cRecordControl --------------------------------------------------------
|
||||||
@ -2826,7 +3019,7 @@ cRecordControl::cRecordControl(cDevice *Device, cTimer *Timer, bool Pause)
|
|||||||
isyslog("record %s", fileName);
|
isyslog("record %s", fileName);
|
||||||
if (MakeDirs(fileName, true)) {
|
if (MakeDirs(fileName, true)) {
|
||||||
const cChannel *ch = timer->Channel();
|
const cChannel *ch = timer->Channel();
|
||||||
recorder = new cRecorder(fileName, ch->Ca(), timer->Priority(), ch->Vpid(), ch->Apid1(), ch->Apid2(), ch->Dpid1(), ch->Dpid2());
|
recorder = new cRecorder(fileName, ch->Ca(), timer->Priority(), ch->Vpid(), ch->Apid(0), ch->Apid(1), ch->Dpid(0), ch->Dpid(1));
|
||||||
if (device->AttachReceiver(recorder)) {
|
if (device->AttachReceiver(recorder)) {
|
||||||
Recording.WriteSummary();
|
Recording.WriteSummary();
|
||||||
cStatus::MsgRecording(device, Recording.Name());
|
cStatus::MsgRecording(device, Recording.Name());
|
||||||
|
24
menu.h
24
menu.h
@ -4,7 +4,7 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* how to reach the author.
|
||||||
*
|
*
|
||||||
* $Id: menu.h 1.64 2004/06/13 11:46:03 kls Exp $
|
* $Id: menu.h 1.68 2005/01/08 15:48:57 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __MENU_H
|
#ifndef __MENU_H
|
||||||
@ -46,7 +46,7 @@ private:
|
|||||||
cSkinDisplayChannel *displayChannel;
|
cSkinDisplayChannel *displayChannel;
|
||||||
int group;
|
int group;
|
||||||
bool withInfo;
|
bool withInfo;
|
||||||
int lastTime;
|
cTimeMs lastTime;
|
||||||
int number;
|
int number;
|
||||||
cChannel *channel;
|
cChannel *channel;
|
||||||
const cEvent *lastPresent;
|
const cEvent *lastPresent;
|
||||||
@ -64,7 +64,7 @@ public:
|
|||||||
class cDisplayVolume : public cOsdObject {
|
class cDisplayVolume : public cOsdObject {
|
||||||
private:
|
private:
|
||||||
cSkinDisplayVolume *displayVolume;
|
cSkinDisplayVolume *displayVolume;
|
||||||
int timeout;
|
cTimeMs timeout;
|
||||||
static cDisplayVolume *currentDisplayVolume;
|
static cDisplayVolume *currentDisplayVolume;
|
||||||
virtual void Show(void);
|
virtual void Show(void);
|
||||||
cDisplayVolume(void);
|
cDisplayVolume(void);
|
||||||
@ -75,6 +75,24 @@ public:
|
|||||||
eOSState ProcessKey(eKeys Key);
|
eOSState ProcessKey(eKeys Key);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class cDisplayTracks : public cOsdObject {
|
||||||
|
private:
|
||||||
|
cSkinDisplayTracks *displayTracks;
|
||||||
|
cTimeMs timeout;
|
||||||
|
eTrackType types[ttMaxTrackTypes];
|
||||||
|
char *descriptions[ttMaxTrackTypes];
|
||||||
|
int numTracks, track, audioChannel;
|
||||||
|
static cDisplayTracks *currentDisplayTracks;
|
||||||
|
virtual void Show(void);
|
||||||
|
cDisplayTracks(void);
|
||||||
|
public:
|
||||||
|
virtual ~cDisplayTracks();
|
||||||
|
static bool IsOpen(void) { return currentDisplayTracks != NULL; }
|
||||||
|
static cDisplayTracks *Create(void);
|
||||||
|
static void Process(eKeys Key);
|
||||||
|
eOSState ProcessKey(eKeys Key);
|
||||||
|
};
|
||||||
|
|
||||||
class cMenuCam : public cOsdMenu {
|
class cMenuCam : public cOsdMenu {
|
||||||
private:
|
private:
|
||||||
cCiMenu *ciMenu;
|
cCiMenu *ciMenu;
|
||||||
|
5
osd.c
5
osd.c
@ -4,7 +4,7 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* how to reach the author.
|
||||||
*
|
*
|
||||||
* $Id: osd.c 1.58 2004/10/16 10:31:34 kls Exp $
|
* $Id: osd.c 1.59 2004/12/19 12:27:38 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "osd.h"
|
#include "osd.h"
|
||||||
@ -197,7 +197,8 @@ bool cBitmap::LoadXpm(const char *FileName)
|
|||||||
int lines = 0;
|
int lines = 0;
|
||||||
int index = 0;
|
int index = 0;
|
||||||
char *s;
|
char *s;
|
||||||
while ((s = readline(f)) != NULL) {
|
cReadLine ReadLine;
|
||||||
|
while ((s = ReadLine.Read(f)) != NULL) {
|
||||||
s = skipspace(s);
|
s = skipspace(s);
|
||||||
if (!isXpm) {
|
if (!isXpm) {
|
||||||
if (strcmp(s, "/* XPM */") != 0) {
|
if (strcmp(s, "/* XPM */") != 0) {
|
||||||
|
11
osdbase.c
11
osdbase.c
@ -4,7 +4,7 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* how to reach the author.
|
||||||
*
|
*
|
||||||
* $Id: osdbase.c 1.14 2004/07/17 13:29:13 kls Exp $
|
* $Id: osdbase.c 1.15 2005/01/07 16:16:41 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "osdbase.h"
|
#include "osdbase.h"
|
||||||
@ -149,8 +149,13 @@ void cOsdMenu::SetHelp(const char *Red, const char *Green, const char *Yellow, c
|
|||||||
void cOsdMenu::Del(int Index)
|
void cOsdMenu::Del(int Index)
|
||||||
{
|
{
|
||||||
cList<cOsdItem>::Del(Get(Index));
|
cList<cOsdItem>::Del(Get(Index));
|
||||||
if (current == Count())
|
int count = Count();
|
||||||
current--;
|
while (current < count && !SelectableItem(current))
|
||||||
|
current++;
|
||||||
|
if (current == count) {
|
||||||
|
while (current > 0 && !SelectableItem(current))
|
||||||
|
current--;
|
||||||
|
}
|
||||||
if (Index == first && first > 0)
|
if (Index == first && first > 0)
|
||||||
first--;
|
first--;
|
||||||
}
|
}
|
||||||
|
17
player.c
17
player.c
@ -4,7 +4,7 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* how to reach the author.
|
||||||
*
|
*
|
||||||
* $Id: player.c 1.8 2004/11/20 11:33:08 kls Exp $
|
* $Id: player.c 1.9 2004/12/12 11:21:07 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "player.h"
|
#include "player.h"
|
||||||
@ -23,23 +23,14 @@ cPlayer::~cPlayer()
|
|||||||
Detach();
|
Detach();
|
||||||
}
|
}
|
||||||
|
|
||||||
int cPlayer::PlayVideo(const uchar *Data, int Length)
|
int cPlayer::PlayPes(const uchar *Data, int Length, bool VideoOnly)
|
||||||
{
|
{
|
||||||
if (device)
|
if (device)
|
||||||
return device->PlayVideo(Data, Length);
|
return device->PlayPes(Data, Length, VideoOnly);
|
||||||
esyslog("ERROR: attempt to use cPlayer::PlayVideo() without attaching to a cDevice!");
|
esyslog("ERROR: attempt to use cPlayer::PlayPes() without attaching to a cDevice!");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void cPlayer::PlayAudio(const uchar *Data, int Length)
|
|
||||||
{
|
|
||||||
if (device) {
|
|
||||||
device->PlayAudio(Data, Length);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
esyslog("ERROR: attempt to use cPlayer::PlayAudio() without attaching to a cDevice!");
|
|
||||||
}
|
|
||||||
|
|
||||||
void cPlayer::Detach(void)
|
void cPlayer::Detach(void)
|
||||||
{
|
{
|
||||||
if (device)
|
if (device)
|
||||||
|
36
player.h
36
player.h
@ -4,7 +4,7 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* how to reach the author.
|
||||||
*
|
*
|
||||||
* $Id: player.h 1.12 2004/06/19 08:53:07 kls Exp $
|
* $Id: player.h 1.14 2004/12/30 10:44:34 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __PLAYER_H
|
#ifndef __PLAYER_H
|
||||||
@ -19,6 +19,7 @@ private:
|
|||||||
cDevice *device;
|
cDevice *device;
|
||||||
ePlayMode playMode;
|
ePlayMode playMode;
|
||||||
protected:
|
protected:
|
||||||
|
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 DevicePoll(cPoller &Poller, int TimeoutMs = 0) { return device ? device->Poll(Poller, TimeoutMs) : false; }
|
||||||
bool DeviceFlush(int TimeoutMs = 0) { return device ? device->Flush(TimeoutMs) : true; }
|
bool DeviceFlush(int TimeoutMs = 0) { return device ? device->Flush(TimeoutMs) : true; }
|
||||||
void DeviceTrickSpeed(int Speed) { if (device) device->TrickSpeed(Speed); }
|
void DeviceTrickSpeed(int Speed) { if (device) device->TrickSpeed(Speed); }
|
||||||
@ -32,12 +33,10 @@ protected:
|
|||||||
// This function is called right after the cPlayer has been attached to
|
// This function is called right after the cPlayer has been attached to
|
||||||
// (On == true) or before it gets detached from (On == false) a cDevice.
|
// (On == true) or before it gets detached from (On == false) a cDevice.
|
||||||
// It can be used to do things like starting/stopping a thread.
|
// It can be used to do things like starting/stopping a thread.
|
||||||
int PlayVideo(const uchar *Data, int Length);
|
int PlayPes(const uchar *Data, int Length, bool VideoOnly = false);
|
||||||
// Sends the given Data to the video device and returns the number of
|
// Sends the given PES Data to the device and returns the number of
|
||||||
// bytes that have actually been accepted by the video device (or a
|
// bytes that have actually been accepted by the device (or a
|
||||||
// negative value in case of an error).
|
// negative value in case of an error).
|
||||||
void PlayAudio(const uchar *Data, int Length);
|
|
||||||
// Plays additional audio streams, like Dolby Digital.
|
|
||||||
public:
|
public:
|
||||||
cPlayer(ePlayMode PlayMode = pmAudioVideo);
|
cPlayer(ePlayMode PlayMode = pmAudioVideo);
|
||||||
virtual ~cPlayer();
|
virtual ~cPlayer();
|
||||||
@ -51,27 +50,10 @@ public:
|
|||||||
// we are going forward or backward and 'Speed' is -1 if this is normal
|
// we are going forward or backward and 'Speed' is -1 if this is normal
|
||||||
// play/pause mode, 0 if it is single speed fast/slow forward/back mode
|
// play/pause mode, 0 if it is single speed fast/slow forward/back mode
|
||||||
// and >0 if this is multi speed mode.
|
// and >0 if this is multi speed mode.
|
||||||
virtual int NumAudioTracks(void) const { return 0; }
|
virtual void SetAudioTrack(eTrackType Type, const tTrackId *TrackId) {}
|
||||||
// Returns the number of audio tracks that are currently available on this
|
// Sets the current audio track to the given value.
|
||||||
// player. The default return value is 0, meaning that this player
|
// This is just a virtual hook for players that need to do special things
|
||||||
// doesn't have multiple audio track capabilities. The return value may
|
// in order to switch audio tracks.
|
||||||
// change with every call and need not necessarily be the number of list
|
|
||||||
// entries returned by GetAudioTracks(). This function is mainly called to
|
|
||||||
// decide whether there should be an "Audio" button in a menu.
|
|
||||||
virtual const char **GetAudioTracks(int *CurrentTrack = NULL) const { return NULL; }
|
|
||||||
// Returns a list of currently available audio tracks. The last entry in the
|
|
||||||
// list must be NULL. The number of entries does not necessarily have to be
|
|
||||||
// the same as returned by a previous call to NumAudioTracks().
|
|
||||||
// If CurrentTrack is given, it will be set to the index of the current track
|
|
||||||
// in the returned list. Note that the list must not be changed after it has
|
|
||||||
// been returned by a call to GetAudioTracks()! The only time the list may
|
|
||||||
// change is *inside* the GetAudioTracks() function.
|
|
||||||
// By default the return value is NULL and CurrentTrack, if given, will not
|
|
||||||
// have any meaning.
|
|
||||||
virtual void SetAudioTrack(int Index) {}
|
|
||||||
// Sets the current audio track to the given value, which should be within the
|
|
||||||
// range of the list returned by a previous call to GetAudioTracks()
|
|
||||||
// (otherwise nothing will happen).
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class cControl : public cOsdObject {
|
class cControl : public cOsdObject {
|
||||||
|
31
plugin.c
31
plugin.c
@ -4,7 +4,7 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* how to reach the author.
|
||||||
*
|
*
|
||||||
* $Id: plugin.c 1.11 2004/05/22 11:25:22 kls Exp $
|
* $Id: plugin.c 1.12 2004/12/19 12:05:28 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "plugin.h"
|
#include "plugin.h"
|
||||||
@ -256,26 +256,23 @@ void cPluginManager::SetDirectory(const char *Directory)
|
|||||||
void cPluginManager::AddPlugin(const char *Args)
|
void cPluginManager::AddPlugin(const char *Args)
|
||||||
{
|
{
|
||||||
if (strcmp(Args, "*") == 0) {
|
if (strcmp(Args, "*") == 0) {
|
||||||
DIR *d = opendir(directory);
|
cReadDir d(directory);
|
||||||
if (d) {
|
struct dirent *e;
|
||||||
struct dirent *e;
|
while ((e = d.Next()) != NULL) {
|
||||||
while ((e = readdir(d)) != NULL) {
|
if (strstr(e->d_name, LIBVDR_PREFIX) == e->d_name) {
|
||||||
if (strstr(e->d_name, LIBVDR_PREFIX) == e->d_name) {
|
char *p = strstr(e->d_name, SO_INDICATOR);
|
||||||
char *p = strstr(e->d_name, SO_INDICATOR);
|
if (p) {
|
||||||
if (p) {
|
*p = 0;
|
||||||
*p = 0;
|
p += strlen(SO_INDICATOR);
|
||||||
p += strlen(SO_INDICATOR);
|
if (strcmp(p, VDRVERSION) == 0) {
|
||||||
if (strcmp(p, VDRVERSION) == 0) {
|
char *name = e->d_name + strlen(LIBVDR_PREFIX);
|
||||||
char *name = e->d_name + strlen(LIBVDR_PREFIX);
|
if (strcmp(name, "*") != 0) { // let's not get into a loop!
|
||||||
if (strcmp(name, "*") != 0) { // let's not get into a loop!
|
AddPlugin(e->d_name + strlen(LIBVDR_PREFIX));
|
||||||
AddPlugin(e->d_name + strlen(LIBVDR_PREFIX));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
closedir(d);
|
}
|
||||||
}
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
char *s = strdup(skipspace(Args));
|
char *s = strdup(skipspace(Args));
|
||||||
|
11
rcu.c
11
rcu.c
@ -4,7 +4,7 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* how to reach the author.
|
||||||
*
|
*
|
||||||
* $Id: rcu.c 1.6 2003/10/18 11:34:30 kls Exp $
|
* $Id: rcu.c 1.8 2004/12/19 18:06:00 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "rcu.h"
|
#include "rcu.h"
|
||||||
@ -94,7 +94,7 @@ void cRcuRemote::Action(void)
|
|||||||
#pragma pack()
|
#pragma pack()
|
||||||
|
|
||||||
time_t LastCodeRefresh = 0;
|
time_t LastCodeRefresh = 0;
|
||||||
int FirstTime = 0;
|
cTimeMs FirstTime;
|
||||||
uint64 LastCommand = 0;
|
uint64 LastCommand = 0;
|
||||||
bool repeat = false;
|
bool repeat = false;
|
||||||
|
|
||||||
@ -116,15 +116,14 @@ void cRcuRemote::Action(void)
|
|||||||
// This remote control sends the above command before and after
|
// This remote control sends the above command before and after
|
||||||
// each keypress - let's just drop this:
|
// each keypress - let's just drop this:
|
||||||
break;
|
break;
|
||||||
int Now = time_ms();
|
|
||||||
Command |= uint64(Address) << 32;
|
Command |= uint64(Address) << 32;
|
||||||
if (Command != LastCommand) {
|
if (Command != LastCommand) {
|
||||||
LastCommand = Command;
|
LastCommand = Command;
|
||||||
repeat = false;
|
repeat = false;
|
||||||
FirstTime = Now;
|
FirstTime.Set();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (Now - FirstTime < REPEATDELAY)
|
if (FirstTime.Elapsed() < REPEATDELAY)
|
||||||
break; // repeat function kicks in after a short delay
|
break; // repeat function kicks in after a short delay
|
||||||
repeat = true;
|
repeat = true;
|
||||||
}
|
}
|
||||||
@ -295,7 +294,7 @@ bool cRcuRemote::DetectCode(unsigned char *Code)
|
|||||||
sprintf(buf, "C0D%c", *Code);
|
sprintf(buf, "C0D%c", *Code);
|
||||||
String(buf);
|
String(buf);
|
||||||
SetCode(*Code);
|
SetCode(*Code);
|
||||||
delay_ms(2 * REPEATDELAY);
|
cCondWait::SleepMs(2 * REPEATDELAY);
|
||||||
if (receivedCommand) {
|
if (receivedCommand) {
|
||||||
SetMode(modeB);
|
SetMode(modeB);
|
||||||
String("----");
|
String("----");
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* how to reach the author.
|
||||||
*
|
*
|
||||||
* $Id: recorder.c 1.11 2004/10/16 09:23:01 kls Exp $
|
* $Id: recorder.c 1.12 2005/01/09 12:16:36 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
@ -128,7 +128,7 @@ void cFileWriter::Action(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
cRecorder::cRecorder(const char *FileName, int Ca, int Priority, int VPid, int APid1, int APid2, int DPid1, int DPid2)
|
cRecorder::cRecorder(const char *FileName, int Ca, int Priority, int VPid, int APid1, int APid2, int DPid1, int DPid2)
|
||||||
:cReceiver(Ca, Priority, Setup.RecordDolbyDigital ? 5 : 3, VPid, APid1, APid2, DPid1, DPid2)
|
:cReceiver(Ca, Priority, Setup.UseDolbyDigital ? 5 : 3, VPid, APid1, APid2, DPid1, DPid2)
|
||||||
,cThread("recording")
|
,cThread("recording")
|
||||||
{
|
{
|
||||||
active = false;
|
active = false;
|
||||||
|
84
recording.c
84
recording.c
@ -4,7 +4,7 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* how to reach the author.
|
||||||
*
|
*
|
||||||
* $Id: recording.c 1.92 2004/11/01 14:04:47 kls Exp $
|
* $Id: recording.c 1.94 2004/12/26 11:55:24 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "recording.h"
|
#include "recording.h"
|
||||||
@ -157,7 +157,7 @@ cResumeFile::cResumeFile(const char *FileName)
|
|||||||
fileName = MALLOC(char, strlen(FileName) + strlen(RESUMEFILESUFFIX) + 1);
|
fileName = MALLOC(char, strlen(FileName) + strlen(RESUMEFILESUFFIX) + 1);
|
||||||
if (fileName) {
|
if (fileName) {
|
||||||
strcpy(fileName, FileName);
|
strcpy(fileName, FileName);
|
||||||
sprintf(fileName + strlen(fileName), RESUMEFILESUFFIX, Setup.ResumeID ? "." : "", Setup.ResumeID ? itoa(Setup.ResumeID) : "");
|
sprintf(fileName + strlen(fileName), RESUMEFILESUFFIX, Setup.ResumeID ? "." : "", Setup.ResumeID ? *itoa(Setup.ResumeID) : "");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
esyslog("ERROR: can't allocate memory for resume file name");
|
esyslog("ERROR: can't allocate memory for resume file name");
|
||||||
@ -541,8 +541,8 @@ const char *cRecording::Title(char Delimiter, bool NewIndicator, int Level) cons
|
|||||||
|
|
||||||
const char *cRecording::PrefixFileName(char Prefix)
|
const char *cRecording::PrefixFileName(char Prefix)
|
||||||
{
|
{
|
||||||
const char *p = PrefixVideoFileName(FileName(), Prefix);
|
cString p = PrefixVideoFileName(FileName(), Prefix);
|
||||||
if (p) {
|
if (*p) {
|
||||||
free(fileName);
|
free(fileName);
|
||||||
fileName = strdup(p);
|
fileName = strdup(p);
|
||||||
return fileName;
|
return fileName;
|
||||||
@ -628,42 +628,39 @@ cRecordings::cRecordings(bool Deleted)
|
|||||||
|
|
||||||
void cRecordings::ScanVideoDir(const char *DirName)
|
void cRecordings::ScanVideoDir(const char *DirName)
|
||||||
{
|
{
|
||||||
DIR *d = opendir(DirName);
|
cReadDir d(DirName);
|
||||||
if (d) {
|
struct dirent *e;
|
||||||
struct dirent *e;
|
while ((e = d.Next()) != NULL) {
|
||||||
while ((e = readdir(d)) != NULL) {
|
if (strcmp(e->d_name, ".") && strcmp(e->d_name, "..")) {
|
||||||
if (strcmp(e->d_name, ".") && strcmp(e->d_name, "..")) {
|
char *buffer;
|
||||||
char *buffer;
|
asprintf(&buffer, "%s/%s", DirName, e->d_name);
|
||||||
asprintf(&buffer, "%s/%s", DirName, e->d_name);
|
struct stat st;
|
||||||
struct stat st;
|
if (stat(buffer, &st) == 0) {
|
||||||
if (stat(buffer, &st) == 0) {
|
if (S_ISLNK(st.st_mode)) {
|
||||||
if (S_ISLNK(st.st_mode)) {
|
free(buffer);
|
||||||
|
buffer = ReadLink(buffer);
|
||||||
|
if (!buffer)
|
||||||
|
continue;
|
||||||
|
if (stat(buffer, &st) != 0) {
|
||||||
free(buffer);
|
free(buffer);
|
||||||
buffer = ReadLink(buffer);
|
continue;
|
||||||
if (!buffer)
|
|
||||||
continue;
|
|
||||||
if (stat(buffer, &st) != 0) {
|
|
||||||
free(buffer);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (S_ISDIR(st.st_mode)) {
|
|
||||||
if (endswith(buffer, deleted ? DELEXT : RECEXT)) {
|
|
||||||
cRecording *r = new cRecording(buffer);
|
|
||||||
if (r->Name())
|
|
||||||
Add(r);
|
|
||||||
else
|
|
||||||
delete r;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
ScanVideoDir(buffer);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
free(buffer);
|
if (S_ISDIR(st.st_mode)) {
|
||||||
|
if (endswith(buffer, deleted ? DELEXT : RECEXT)) {
|
||||||
|
cRecording *r = new cRecording(buffer);
|
||||||
|
if (r->Name())
|
||||||
|
Add(r);
|
||||||
|
else
|
||||||
|
delete r;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
ScanVideoDir(buffer);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
free(buffer);
|
||||||
}
|
}
|
||||||
closedir(d);
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool cRecordings::NeedsUpdate(void)
|
bool cRecordings::NeedsUpdate(void)
|
||||||
@ -707,8 +704,6 @@ void cRecordings::DelByName(const char *FileName)
|
|||||||
|
|
||||||
// --- cMark -----------------------------------------------------------------
|
// --- cMark -----------------------------------------------------------------
|
||||||
|
|
||||||
char *cMark::buffer = NULL;
|
|
||||||
|
|
||||||
cMark::cMark(int Position, const char *Comment)
|
cMark::cMark(int Position, const char *Comment)
|
||||||
{
|
{
|
||||||
position = Position;
|
position = Position;
|
||||||
@ -720,10 +715,10 @@ cMark::~cMark()
|
|||||||
free(comment);
|
free(comment);
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *cMark::ToText(void)
|
cString cMark::ToText(void)
|
||||||
{
|
{
|
||||||
free(buffer);
|
char *buffer;
|
||||||
asprintf(&buffer, "%s%s%s\n", IndexToHMSF(position, true), comment ? " " : "", comment ? comment : "");
|
asprintf(&buffer, "%s%s%s\n", *IndexToHMSF(position, true), comment ? " " : "", comment ? comment : "");
|
||||||
return buffer;
|
return buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -750,8 +745,7 @@ bool cMark::Save(FILE *f)
|
|||||||
|
|
||||||
bool cMarks::Load(const char *RecordingFileName)
|
bool cMarks::Load(const char *RecordingFileName)
|
||||||
{
|
{
|
||||||
const char *MarksFile = AddDirectory(RecordingFileName, MARKSFILESUFFIX);
|
if (cConfig<cMark>::Load(AddDirectory(RecordingFileName, MARKSFILESUFFIX))) {
|
||||||
if (cConfig<cMark>::Load(MarksFile)) {
|
|
||||||
Sort();
|
Sort();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -815,7 +809,7 @@ void cRecordingUserCommand::InvokeCommand(const char *State, const char *Recordi
|
|||||||
{
|
{
|
||||||
if (command) {
|
if (command) {
|
||||||
char *cmd;
|
char *cmd;
|
||||||
asprintf(&cmd, "%s %s \"%s\"", command, State, strescape(RecordingFileName, "\"$"));
|
asprintf(&cmd, "%s %s \"%s\"", command, State, *strescape(RecordingFileName, "\"$"));
|
||||||
isyslog("executing '%s'", cmd);
|
isyslog("executing '%s'", cmd);
|
||||||
SystemExec(cmd);
|
SystemExec(cmd);
|
||||||
free(cmd);
|
free(cmd);
|
||||||
@ -1156,9 +1150,9 @@ int cFileName::NextFile(void)
|
|||||||
|
|
||||||
// --- Index stuff -----------------------------------------------------------
|
// --- Index stuff -----------------------------------------------------------
|
||||||
|
|
||||||
const char *IndexToHMSF(int Index, bool WithFrame)
|
cString IndexToHMSF(int Index, bool WithFrame)
|
||||||
{
|
{
|
||||||
static char buffer[16];
|
char buffer[16];
|
||||||
int f = (Index % FRAMESPERSEC) + 1;
|
int f = (Index % FRAMESPERSEC) + 1;
|
||||||
int s = (Index / FRAMESPERSEC);
|
int s = (Index / FRAMESPERSEC);
|
||||||
int m = s / 60 % 60;
|
int m = s / 60 % 60;
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* how to reach the author.
|
||||||
*
|
*
|
||||||
* $Id: recording.h 1.32 2004/10/31 16:24:38 kls Exp $
|
* $Id: recording.h 1.33 2004/12/26 11:47:35 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __RECORDING_H
|
#ifndef __RECORDING_H
|
||||||
@ -86,14 +86,12 @@ public:
|
|||||||
extern cRecordings Recordings;
|
extern cRecordings Recordings;
|
||||||
|
|
||||||
class cMark : public cListObject {
|
class cMark : public cListObject {
|
||||||
private:
|
|
||||||
static char *buffer;
|
|
||||||
public:
|
public:
|
||||||
int position;
|
int position;
|
||||||
char *comment;
|
char *comment;
|
||||||
cMark(int Position = 0, const char *Comment = NULL);
|
cMark(int Position = 0, const char *Comment = NULL);
|
||||||
~cMark();
|
~cMark();
|
||||||
const char *ToText(void);
|
cString ToText(void);
|
||||||
bool Parse(const char *s);
|
bool Parse(const char *s);
|
||||||
bool Save(FILE *f);
|
bool Save(FILE *f);
|
||||||
};
|
};
|
||||||
@ -176,7 +174,7 @@ public:
|
|||||||
int NextFile(void);
|
int NextFile(void);
|
||||||
};
|
};
|
||||||
|
|
||||||
const char *IndexToHMSF(int Index, bool WithFrame = false);
|
cString IndexToHMSF(int Index, bool WithFrame = false);
|
||||||
// Converts the given index to a string, optionally containing the frame number.
|
// Converts the given index to a string, optionally containing the frame number.
|
||||||
int HMSFToIndex(const char *HMSF);
|
int HMSFToIndex(const char *HMSF);
|
||||||
// Converts the given string (format: "hh:mm:ss.ff") to an index.
|
// Converts the given string (format: "hh:mm:ss.ff") to an index.
|
||||||
|
4
remux.c
4
remux.c
@ -8,7 +8,7 @@
|
|||||||
* the Linux DVB driver's 'tuxplayer' example and were rewritten to suit
|
* the Linux DVB driver's 'tuxplayer' example and were rewritten to suit
|
||||||
* VDR's needs.
|
* VDR's needs.
|
||||||
*
|
*
|
||||||
* $Id: remux.c 1.22 2004/11/16 16:49:03 kls Exp $
|
* $Id: remux.c 1.23 2004/12/18 13:15:02 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "remux.h"
|
#include "remux.h"
|
||||||
@ -541,6 +541,8 @@ uchar *cRemux::Get(int &Count, uchar *PictureType)
|
|||||||
// XXX actually '0' should be enough, but '1' must be used with encrypted channels (driver bug?)
|
// XXX actually '0' should be enough, but '1' must be used with encrypted channels (driver bug?)
|
||||||
// XXX also allowing 0x1FFF to not break Michael Paar's original patch,
|
// XXX also allowing 0x1FFF to not break Michael Paar's original patch,
|
||||||
// XXX but it would probably be best to only use '0'
|
// XXX but it would probably be best to only use '0'
|
||||||
|
// Force syncing of radio channels to avoid "no useful data" error
|
||||||
|
synced = true;
|
||||||
if (PictureType)
|
if (PictureType)
|
||||||
*PictureType = I_FRAME;
|
*PictureType = I_FRAME;
|
||||||
return resultBuffer->Get(Count);
|
return resultBuffer->Get(Count);
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* how to reach the author.
|
||||||
*
|
*
|
||||||
* $Id: skinclassic.c 1.7 2004/05/29 14:04:50 kls Exp $
|
* $Id: skinclassic.c 1.11 2005/01/09 11:56:29 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "skinclassic.h"
|
#include "skinclassic.h"
|
||||||
@ -141,7 +141,7 @@ void cSkinClassicDisplayChannel::SetMessage(eMessageType Type, const char *Text)
|
|||||||
void cSkinClassicDisplayChannel::Flush(void)
|
void cSkinClassicDisplayChannel::Flush(void)
|
||||||
{
|
{
|
||||||
if (!message) {
|
if (!message) {
|
||||||
const char *date = DayDateTime();
|
cString date = DayDateTime();
|
||||||
osd->DrawText(osd->Width() - cFont::GetFont(fontSml)->Width(date) - 2, 0, date, Theme.Color(clrChannelDate), Theme.Color(clrBackground), cFont::GetFont(fontSml));
|
osd->DrawText(osd->Width() - cFont::GetFont(fontSml)->Width(date) - 2, 0, date, Theme.Color(clrChannelDate), Theme.Color(clrBackground), cFont::GetFont(fontSml));
|
||||||
}
|
}
|
||||||
osd->Flush();
|
osd->Flush();
|
||||||
@ -299,11 +299,11 @@ void cSkinClassicDisplayMenu::SetEvent(const cEvent *Event)
|
|||||||
int y = y2;
|
int y = y2;
|
||||||
cTextScroller ts;
|
cTextScroller ts;
|
||||||
char t[32];
|
char t[32];
|
||||||
snprintf(t, sizeof(t), "%s %s - %s", Event->GetDateString(), Event->GetTimeString(), Event->GetEndTimeString());
|
snprintf(t, sizeof(t), "%s %s - %s", *Event->GetDateString(), *Event->GetTimeString(), *Event->GetEndTimeString());
|
||||||
ts.Set(osd, xl, y, x1 - xl, y3 - y, t, font, Theme.Color(clrMenuEventTime), Theme.Color(clrBackground));
|
ts.Set(osd, xl, y, x1 - xl, y3 - y, t, font, Theme.Color(clrMenuEventTime), Theme.Color(clrBackground));
|
||||||
if (Event->Vps() && Event->Vps() != Event->StartTime()) {
|
if (Event->Vps() && Event->Vps() != Event->StartTime()) {
|
||||||
char *buffer;
|
char *buffer;
|
||||||
asprintf(&buffer, " VPS: %s", Event->GetVpsString());
|
asprintf(&buffer, " VPS: %s", *Event->GetVpsString());
|
||||||
const cFont *font = cFont::GetFont(fontSml);
|
const cFont *font = cFont::GetFont(fontSml);
|
||||||
osd->DrawText(x1 - font->Width(buffer), y, buffer, Theme.Color(clrMenuEventVpsFg), Theme.Color(clrMenuEventVpsBg), font);
|
osd->DrawText(x1 - font->Width(buffer), y, buffer, Theme.Color(clrMenuEventVpsFg), Theme.Color(clrMenuEventVpsBg), font);
|
||||||
free(buffer);
|
free(buffer);
|
||||||
@ -338,7 +338,7 @@ void cSkinClassicDisplayMenu::SetText(const char *Text, bool FixedFont)
|
|||||||
|
|
||||||
void cSkinClassicDisplayMenu::Flush(void)
|
void cSkinClassicDisplayMenu::Flush(void)
|
||||||
{
|
{
|
||||||
const char *date = DayDateTime();
|
cString date = DayDateTime();
|
||||||
const cFont *font = cFont::GetFont(fontOsd);
|
const cFont *font = cFont::GetFont(fontOsd);
|
||||||
osd->DrawText(x1 - font->Width(date) - 2, y0, date, Theme.Color(clrMenuDate), Theme.Color(clrMenuTitleBg), font);
|
osd->DrawText(x1 - font->Width(date) - 2, y0, date, Theme.Color(clrMenuDate), Theme.Color(clrMenuTitleBg), font);
|
||||||
osd->Flush();
|
osd->Flush();
|
||||||
@ -502,6 +502,85 @@ void cSkinClassicDisplayVolume::Flush(void)
|
|||||||
osd->Flush();
|
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 SetAudioChannel(int AudioChannel) {}
|
||||||
|
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 --------------------------------------------
|
// --- cSkinClassicDisplayMessage --------------------------------------------
|
||||||
|
|
||||||
class cSkinClassicDisplayMessage : public cSkinDisplayMessage {
|
class cSkinClassicDisplayMessage : public cSkinDisplayMessage {
|
||||||
@ -571,6 +650,12 @@ cSkinDisplayVolume *cSkinClassic::DisplayVolume(void)
|
|||||||
return new cSkinClassicDisplayVolume;
|
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)
|
cSkinDisplayMessage *cSkinClassic::DisplayMessage(void)
|
||||||
{
|
{
|
||||||
return new cSkinClassicDisplayMessage;
|
return new cSkinClassicDisplayMessage;
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* how to reach the author.
|
||||||
*
|
*
|
||||||
* $Id: 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
|
#ifndef __SKINCLASSIC_H
|
||||||
@ -20,6 +20,7 @@ public:
|
|||||||
virtual cSkinDisplayMenu *DisplayMenu(void);
|
virtual cSkinDisplayMenu *DisplayMenu(void);
|
||||||
virtual cSkinDisplayReplay *DisplayReplay(bool ModeOnly);
|
virtual cSkinDisplayReplay *DisplayReplay(bool ModeOnly);
|
||||||
virtual cSkinDisplayVolume *DisplayVolume(void);
|
virtual cSkinDisplayVolume *DisplayVolume(void);
|
||||||
|
virtual cSkinDisplayTracks *DisplayTracks(const char *Title, int NumTracks, const char * const *Tracks);
|
||||||
virtual cSkinDisplayMessage *DisplayMessage(void);
|
virtual cSkinDisplayMessage *DisplayMessage(void);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
24
skins.h
24
skins.h
@ -4,7 +4,7 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* how to reach the author.
|
||||||
*
|
*
|
||||||
* $Id: skins.h 1.3 2004/05/29 13:13:21 kls Exp $
|
* $Id: skins.h 1.6 2005/01/09 11:49:37 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __SKINS_H
|
#ifndef __SKINS_H
|
||||||
@ -66,9 +66,6 @@ public:
|
|||||||
Red = Video options
|
Red = Video options
|
||||||
Green = Info now
|
Green = Info now
|
||||||
Yellow = Info next
|
Yellow = Info next
|
||||||
Blue = Audio options
|
|
||||||
AudioOptions
|
|
||||||
VideoOptions
|
|
||||||
*/
|
*/
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -99,7 +96,7 @@ protected:
|
|||||||
///< Returns the offset of the given tab from the left border of the
|
///< Returns the offset of the given tab from the left border of the
|
||||||
///< item display area. The value returned is in pixel.//XXX ncurses???
|
///< item display area. The value returned is in pixel.//XXX ncurses???
|
||||||
const char *GetTabbedText(const char *s, int Tab);
|
const char *GetTabbedText(const char *s, int Tab);
|
||||||
///< Returns the that part of the given string, that follows the given
|
///< Returns the part of the given string that follows the given
|
||||||
///< Tab (where 0 indicates the beginning of the string). If no such
|
///< Tab (where 0 indicates the beginning of the string). If no such
|
||||||
///< part can be found, NULL will be returned.
|
///< part can be found, NULL will be returned.
|
||||||
public:
|
public:
|
||||||
@ -223,6 +220,17 @@ public:
|
|||||||
///< indicator shall be displayed.
|
///< 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.
|
||||||
|
virtual void SetAudioChannel(int AudioChannel) = 0;
|
||||||
|
///< Sets the audio channel indicator.
|
||||||
|
///< 0=stereo, 1=left, 2=right, -1=don't display the audio channel indicator.
|
||||||
|
};
|
||||||
|
|
||||||
class cSkinDisplayMessage : public cSkinDisplay {
|
class cSkinDisplayMessage : public cSkinDisplay {
|
||||||
///< This class implements a simple message display.
|
///< This class implements a simple message display.
|
||||||
public:
|
public:
|
||||||
@ -275,6 +283,12 @@ public:
|
|||||||
virtual cSkinDisplayVolume *DisplayVolume(void) = 0;
|
virtual cSkinDisplayVolume *DisplayVolume(void) = 0;
|
||||||
///< Creates and returns a new object for displaying the current volume.
|
///< Creates and returns a new object for displaying the current volume.
|
||||||
///< The caller must delete the object after use.
|
///< 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;
|
virtual cSkinDisplayMessage *DisplayMessage(void) = 0;
|
||||||
///< Creates and returns a new object for displaying a message.
|
///< Creates and returns a new object for displaying a message.
|
||||||
///< The caller must delete the object after use.
|
///< The caller must delete the object after use.
|
||||||
|
183
skinsttng.c
183
skinsttng.c
@ -4,7 +4,7 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* how to reach the author.
|
||||||
*
|
*
|
||||||
* $Id: skinsttng.c 1.6 2004/07/18 11:32:42 kls Exp $
|
* $Id: skinsttng.c 1.12 2005/01/08 15:37:55 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// Star Trek: The Next Generation® is a registered trademark of Paramount Pictures
|
// Star Trek: The Next Generation® is a registered trademark of Paramount Pictures
|
||||||
@ -20,6 +20,9 @@
|
|||||||
#include "symbols/arrowdown.xpm"
|
#include "symbols/arrowdown.xpm"
|
||||||
#include "symbols/arrowup.xpm"
|
#include "symbols/arrowup.xpm"
|
||||||
#include "symbols/audio.xpm"
|
#include "symbols/audio.xpm"
|
||||||
|
#include "symbols/audioleft.xpm"
|
||||||
|
#include "symbols/audioright.xpm"
|
||||||
|
#include "symbols/audiostereo.xpm"
|
||||||
#include "symbols/dolbydigital.xpm"
|
#include "symbols/dolbydigital.xpm"
|
||||||
#include "symbols/encrypted.xpm"
|
#include "symbols/encrypted.xpm"
|
||||||
#include "symbols/ffwd.xpm"
|
#include "symbols/ffwd.xpm"
|
||||||
@ -233,14 +236,14 @@ void cSkinSTTNGDisplayChannel::SetChannel(const cChannel *Channel, int Number)
|
|||||||
x -= bmEncrypted.Width() + d;
|
x -= bmEncrypted.Width() + d;
|
||||||
osd->DrawBitmap(x, y0 + (y1 - y0 - bmEncrypted.Height()) / 2, bmEncrypted, Theme.Color(Channel->Ca() ? clrChannelSymbolOn : clrChannelSymbolOff), frameColor);
|
osd->DrawBitmap(x, y0 + (y1 - y0 - bmEncrypted.Height()) / 2, bmEncrypted, Theme.Color(Channel->Ca() ? clrChannelSymbolOn : clrChannelSymbolOff), frameColor);
|
||||||
x -= bmDolbyDigital.Width() + d;
|
x -= bmDolbyDigital.Width() + d;
|
||||||
osd->DrawBitmap(x, y0 + (y1 - y0 - bmDolbyDigital.Height()) / 2, bmDolbyDigital, Theme.Color(Channel->Dpid1() ? clrChannelSymbolOn : clrChannelSymbolOff), frameColor);
|
osd->DrawBitmap(x, y0 + (y1 - y0 - bmDolbyDigital.Height()) / 2, bmDolbyDigital, Theme.Color(Channel->Dpid(0) ? clrChannelSymbolOn : clrChannelSymbolOff), frameColor);
|
||||||
x -= bmAudio.Width() + d;
|
x -= bmAudio.Width() + d;
|
||||||
osd->DrawBitmap(x, y0 + (y1 - y0 - bmAudio.Height()) / 2, bmAudio, Theme.Color(Channel->Apid2() ? clrChannelSymbolOn : clrChannelSymbolOff), frameColor);
|
osd->DrawBitmap(x, y0 + (y1 - y0 - bmAudio.Height()) / 2, bmAudio, Theme.Color(Channel->Apid(1) ? clrChannelSymbolOn : clrChannelSymbolOff), frameColor);
|
||||||
if (Channel->Vpid()) {
|
if (Channel->Vpid()) {
|
||||||
x -= bmTeletext.Width() + d;
|
x -= bmTeletext.Width() + d;
|
||||||
osd->DrawBitmap(x, y0 + (y1 - y0 - bmTeletext.Height()) / 2, bmTeletext, Theme.Color(Channel->Tpid() ? clrChannelSymbolOn : clrChannelSymbolOff), frameColor);
|
osd->DrawBitmap(x, y0 + (y1 - y0 - bmTeletext.Height()) / 2, bmTeletext, Theme.Color(Channel->Tpid() ? clrChannelSymbolOn : clrChannelSymbolOff), frameColor);
|
||||||
}
|
}
|
||||||
else if (Channel->Apid1()) {
|
else if (Channel->Apid(0)) {
|
||||||
x -= bmRadio.Width() + d;
|
x -= bmRadio.Width() + d;
|
||||||
osd->DrawBitmap(x, y0 + (y1 - y0 - bmRadio.Height()) / 2, bmRadio, Theme.Color(clrChannelSymbolOn), frameColor);
|
osd->DrawBitmap(x, y0 + (y1 - y0 - bmRadio.Height()) / 2, bmRadio, Theme.Color(clrChannelSymbolOn), frameColor);
|
||||||
}
|
}
|
||||||
@ -265,6 +268,9 @@ void cSkinSTTNGDisplayChannel::SetEvents(const cEvent *Present, const cEvent *Fo
|
|||||||
osd->DrawText(x3 + 2, y3 + (2 * i + 1) * lineHeight, e->ShortText(), Theme.Color(clrChannelEpgShortText), Theme.Color(clrBackground), cFont::GetFont(fontSml), x4 - x3 - 2);
|
osd->DrawText(x3 + 2, y3 + (2 * i + 1) * lineHeight, e->ShortText(), Theme.Color(clrChannelEpgShortText), Theme.Color(clrBackground), cFont::GetFont(fontSml), x4 - x3 - 2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
cDevice *Device = cDevice::PrimaryDevice();
|
||||||
|
const tTrackId *Track = Device->GetTrack(Device->GetCurrentAudioTrack());
|
||||||
|
osd->DrawText(x3 + 2, y6, Track ? Track->description : "", Theme.Color(clrChannelName), frameColor, cFont::GetFont(fontSml), x4 - x3 - 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
void cSkinSTTNGDisplayChannel::SetMessage(eMessageType Type, const char *Text)
|
void cSkinSTTNGDisplayChannel::SetMessage(eMessageType Type, const char *Text)
|
||||||
@ -289,7 +295,7 @@ void cSkinSTTNGDisplayChannel::Flush(void)
|
|||||||
{
|
{
|
||||||
if (withInfo) {
|
if (withInfo) {
|
||||||
if (!message) {
|
if (!message) {
|
||||||
const char *date = DayDateTime();
|
cString date = DayDateTime();
|
||||||
const cFont *font = cFont::GetFont(fontSml);
|
const cFont *font = cFont::GetFont(fontSml);
|
||||||
osd->DrawText(x4 - font->Width(date) - 2, y7 - font->Height(date), date, Theme.Color(clrChannelDate), frameColor, font);
|
osd->DrawText(x4 - font->Width(date) - 2, y7 - font->Height(date), date, Theme.Color(clrChannelDate), frameColor, font);
|
||||||
}
|
}
|
||||||
@ -456,7 +462,7 @@ void cSkinSTTNGDisplayMenu::SetTitle(const char *Title)
|
|||||||
|
|
||||||
void cSkinSTTNGDisplayMenu::SetButtons(const char *Red, const char *Green, const char *Yellow, const char *Blue)
|
void cSkinSTTNGDisplayMenu::SetButtons(const char *Red, const char *Green, const char *Yellow, const char *Blue)
|
||||||
{
|
{
|
||||||
const char *date = DayDateTime();
|
cString date = DayDateTime();
|
||||||
const cFont *font = cFont::GetFont(fontSml);
|
const cFont *font = cFont::GetFont(fontSml);
|
||||||
int d = 10;
|
int d = 10;
|
||||||
int d2 = d / 2;
|
int d2 = d / 2;
|
||||||
@ -533,11 +539,11 @@ void cSkinSTTNGDisplayMenu::SetEvent(const cEvent *Event)
|
|||||||
int y = y3;
|
int y = y3;
|
||||||
cTextScroller ts;
|
cTextScroller ts;
|
||||||
char t[32];
|
char t[32];
|
||||||
snprintf(t, sizeof(t), "%s %s - %s", Event->GetDateString(), Event->GetTimeString(), Event->GetEndTimeString());
|
snprintf(t, sizeof(t), "%s %s - %s", *Event->GetDateString(), *Event->GetTimeString(), *Event->GetEndTimeString());
|
||||||
ts.Set(osd, xl, y, x4 - xl, y4 - y, t, font, Theme.Color(clrMenuEventTime), Theme.Color(clrBackground));
|
ts.Set(osd, xl, y, x4 - xl, y4 - y, t, font, Theme.Color(clrMenuEventTime), Theme.Color(clrBackground));
|
||||||
if (Event->Vps() && Event->Vps() != Event->StartTime()) {
|
if (Event->Vps() && Event->Vps() != Event->StartTime()) {
|
||||||
char *buffer;
|
char *buffer;
|
||||||
asprintf(&buffer, " VPS: %s", Event->GetVpsString());
|
asprintf(&buffer, " VPS: %s", *Event->GetVpsString());
|
||||||
const cFont *font = cFont::GetFont(fontSml);
|
const cFont *font = cFont::GetFont(fontSml);
|
||||||
osd->DrawText(x4 - font->Width(buffer), y, buffer, Theme.Color(clrMenuEventVps), frameColor, font);
|
osd->DrawText(x4 - font->Width(buffer), y, buffer, Theme.Color(clrMenuEventVps), frameColor, font);
|
||||||
int yb = y + font->Height();
|
int yb = y + font->Height();
|
||||||
@ -583,7 +589,7 @@ void cSkinSTTNGDisplayMenu::SetText(const char *Text, bool FixedFont)
|
|||||||
void cSkinSTTNGDisplayMenu::Flush(void)
|
void cSkinSTTNGDisplayMenu::Flush(void)
|
||||||
{
|
{
|
||||||
if (!message) {
|
if (!message) {
|
||||||
const char *date = DayDateTime();
|
cString date = DayDateTime();
|
||||||
const cFont *font = cFont::GetFont(fontSml);
|
const cFont *font = cFont::GetFont(fontSml);
|
||||||
osd->DrawText(x4 - font->Width(date) - 2, y7 - font->Height(date), date, Theme.Color(clrMenuDate), frameColor, font);
|
osd->DrawText(x4 - font->Width(date) - 2, y7 - font->Height(date), date, Theme.Color(clrMenuDate), frameColor, font);
|
||||||
}
|
}
|
||||||
@ -822,6 +828,160 @@ void cSkinSTTNGDisplayVolume::Flush(void)
|
|||||||
osd->Flush();
|
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;
|
||||||
|
static cBitmap bmAudioLeft, bmAudioRight, bmAudioStereo;
|
||||||
|
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 SetAudioChannel(int AudioChannel);
|
||||||
|
virtual void Flush(void);
|
||||||
|
};
|
||||||
|
|
||||||
|
cBitmap cSkinSTTNGDisplayTracks::bmAudioLeft(audioleft_xpm);
|
||||||
|
cBitmap cSkinSTTNGDisplayTracks::bmAudioRight(audioright_xpm);
|
||||||
|
cBitmap cSkinSTTNGDisplayTracks::bmAudioStereo(audiostereo_xpm);
|
||||||
|
|
||||||
|
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::SetAudioChannel(int AudioChannel)
|
||||||
|
{
|
||||||
|
cBitmap *bm = NULL;
|
||||||
|
switch (AudioChannel) {
|
||||||
|
case 0: bm = &bmAudioStereo; break;
|
||||||
|
case 1: bm = &bmAudioLeft; break;
|
||||||
|
case 2: bm = &bmAudioRight; break;
|
||||||
|
}
|
||||||
|
if (bm)
|
||||||
|
osd->DrawBitmap(x3 + 5, y6 + (y7 - y6 - bm->Height()) / 2, *bm, Theme.Color(clrChannelSymbolOn), frameColor);
|
||||||
|
else
|
||||||
|
osd->DrawRectangle(x3, y6, x4 - 1, y7 - 1, frameColor);
|
||||||
|
}
|
||||||
|
|
||||||
|
void cSkinSTTNGDisplayTracks::Flush(void)
|
||||||
|
{
|
||||||
|
osd->Flush();
|
||||||
|
}
|
||||||
|
|
||||||
// --- cSkinSTTNGDisplayMessage ----------------------------------------------
|
// --- cSkinSTTNGDisplayMessage ----------------------------------------------
|
||||||
|
|
||||||
class cSkinSTTNGDisplayMessage : public cSkinDisplayMessage {
|
class cSkinSTTNGDisplayMessage : public cSkinDisplayMessage {
|
||||||
@ -909,6 +1069,11 @@ cSkinDisplayVolume *cSkinSTTNG::DisplayVolume(void)
|
|||||||
return new cSkinSTTNGDisplayVolume;
|
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)
|
cSkinDisplayMessage *cSkinSTTNG::DisplayMessage(void)
|
||||||
{
|
{
|
||||||
return new cSkinSTTNGDisplayMessage;
|
return new cSkinSTTNGDisplayMessage;
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* how to reach the author.
|
||||||
*
|
*
|
||||||
* $Id: 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
|
#ifndef __SKINSTTNG_H
|
||||||
@ -20,6 +20,7 @@ public:
|
|||||||
virtual cSkinDisplayMenu *DisplayMenu(void);
|
virtual cSkinDisplayMenu *DisplayMenu(void);
|
||||||
virtual cSkinDisplayReplay *DisplayReplay(bool ModeOnly);
|
virtual cSkinDisplayReplay *DisplayReplay(bool ModeOnly);
|
||||||
virtual cSkinDisplayVolume *DisplayVolume(void);
|
virtual cSkinDisplayVolume *DisplayVolume(void);
|
||||||
|
virtual cSkinDisplayTracks *DisplayTracks(const char *Title, int NumTracks, const char * const *Tracks);
|
||||||
virtual cSkinDisplayMessage *DisplayMessage(void);
|
virtual cSkinDisplayMessage *DisplayMessage(void);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* how to reach the author.
|
||||||
*
|
*
|
||||||
* $Id: sources.c 1.2 2004/01/11 10:36:57 kls Exp $
|
* $Id: sources.c 1.3 2004/12/26 11:58:52 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "sources.h"
|
#include "sources.h"
|
||||||
@ -32,9 +32,9 @@ bool cSource::Parse(const char *s)
|
|||||||
return code != stNone && description && *description;
|
return code != stNone && description && *description;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *cSource::ToString(int Code)
|
cString cSource::ToString(int Code)
|
||||||
{
|
{
|
||||||
static char buffer[16];
|
char buffer[16];
|
||||||
char *q = buffer;
|
char *q = buffer;
|
||||||
switch (Code & st_Mask) {
|
switch (Code & st_Mask) {
|
||||||
case stCable: *q++ = 'C'; break;
|
case stCable: *q++ = 'C'; break;
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* how to reach the author.
|
||||||
*
|
*
|
||||||
* $Id: sources.h 1.2 2004/01/11 10:35:36 kls Exp $
|
* $Id: sources.h 1.3 2004/12/26 11:59:21 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __SOURCES_H
|
#ifndef __SOURCES_H
|
||||||
@ -32,7 +32,7 @@ public:
|
|||||||
int Code(void) const { return code; }
|
int Code(void) const { return code; }
|
||||||
const char *Description(void) const { return description; }
|
const char *Description(void) const { return description; }
|
||||||
bool Parse(const char *s);
|
bool Parse(const char *s);
|
||||||
static const char *ToString(int Code);
|
static cString ToString(int Code);
|
||||||
static int FromString(const char *s);
|
static int FromString(const char *s);
|
||||||
static int FromData(eSourceType SourceType, int Position = 0, bool East = false);
|
static int FromData(eSourceType SourceType, int Position = 0, bool East = false);
|
||||||
};
|
};
|
||||||
|
4
spu.h
4
spu.h
@ -6,7 +6,7 @@
|
|||||||
* This code is distributed under the terms and conditions of the
|
* This code is distributed under the terms and conditions of the
|
||||||
* GNU GENERAL PUBLIC LICENSE. See the file COPYING for details.
|
* GNU GENERAL PUBLIC LICENSE. See the file COPYING for details.
|
||||||
*
|
*
|
||||||
* $Id: spu.h 1.2 2004/06/12 12:56:27 kls Exp $
|
* $Id: spu.h 1.3 2005/01/08 09:58:35 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __SPU_VDR_H
|
#ifndef __SPU_VDR_H
|
||||||
@ -35,7 +35,7 @@ class cSpuDecoder {
|
|||||||
virtual void Hide(void) = 0;
|
virtual void Hide(void) = 0;
|
||||||
virtual void Draw(void) = 0;
|
virtual void Draw(void) = 0;
|
||||||
virtual bool IsVisible(void) = 0;
|
virtual bool IsVisible(void) = 0;
|
||||||
virtual void processSPU(uint32_t pts, uint8_t * buf) = 0;
|
virtual void processSPU(uint32_t pts, uint8_t * buf, bool AllowedShow = true) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // __SPU_VDR_H
|
#endif // __SPU_VDR_H
|
||||||
|
14
status.c
14
status.c
@ -4,7 +4,7 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* how to reach the author.
|
||||||
*
|
*
|
||||||
* $Id: status.c 1.5 2003/05/03 14:47:44 kls Exp $
|
* $Id: status.c 1.7 2005/01/09 11:51:04 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "status.h"
|
#include "status.h"
|
||||||
@ -47,6 +47,18 @@ void cStatus::MsgSetVolume(int Volume, bool Absolute)
|
|||||||
sm->SetVolume(Volume, 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::MsgSetAudioChannel(int AudioChannel)
|
||||||
|
{
|
||||||
|
for (cStatus *sm = statusMonitors.First(); sm; sm = statusMonitors.Next(sm))
|
||||||
|
sm->SetAudioChannel(AudioChannel);
|
||||||
|
}
|
||||||
|
|
||||||
void cStatus::MsgOsdClear(void)
|
void cStatus::MsgOsdClear(void)
|
||||||
{
|
{
|
||||||
for (cStatus *sm = statusMonitors.First(); sm; sm = statusMonitors.Next(sm))
|
for (cStatus *sm = statusMonitors.First(); sm; sm = statusMonitors.Next(sm))
|
||||||
|
10
status.h
10
status.h
@ -4,7 +4,7 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* how to reach the author.
|
||||||
*
|
*
|
||||||
* $Id: status.h 1.6 2003/05/03 14:43:18 kls Exp $
|
* $Id: status.h 1.8 2005/01/09 11:50:21 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __STATUS_H
|
#ifndef __STATUS_H
|
||||||
@ -36,6 +36,12 @@ protected:
|
|||||||
virtual void SetVolume(int Volume, bool Absolute) {}
|
virtual void SetVolume(int Volume, bool Absolute) {}
|
||||||
// The volume has been set to the given value, either
|
// The volume has been set to the given value, either
|
||||||
// absolutely or relative to the current volume.
|
// 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 SetAudioChannel(int AudioChannel) {}
|
||||||
|
// The audio channel has been set to the given value.
|
||||||
|
// 0=stereo, 1=left, 2=right, -1=no information available.
|
||||||
virtual void OsdClear(void) {}
|
virtual void OsdClear(void) {}
|
||||||
// The OSD has been cleared.
|
// The OSD has been cleared.
|
||||||
virtual void OsdTitle(const char *Title) {}
|
virtual void OsdTitle(const char *Title) {}
|
||||||
@ -67,6 +73,8 @@ public:
|
|||||||
static void MsgRecording(const cDevice *Device, const char *Name);
|
static void MsgRecording(const cDevice *Device, const char *Name);
|
||||||
static void MsgReplaying(const cControl *Control, const char *Name);
|
static void MsgReplaying(const cControl *Control, const char *Name);
|
||||||
static void MsgSetVolume(int Volume, bool Absolute);
|
static void MsgSetVolume(int Volume, bool Absolute);
|
||||||
|
static void MsgSetAudioTrack(int Index, const char * const *Tracks);
|
||||||
|
static void MsgSetAudioChannel(int AudioChannel);
|
||||||
static void MsgOsdClear(void);
|
static void MsgOsdClear(void);
|
||||||
static void MsgOsdTitle(const char *Title);
|
static void MsgOsdTitle(const char *Title);
|
||||||
static void MsgOsdStatusMessage(const char *Message);
|
static void MsgOsdStatusMessage(const char *Message);
|
||||||
|
59
svdrp.c
59
svdrp.c
@ -10,7 +10,7 @@
|
|||||||
* and interact with the Video Disk Recorder - or write a full featured
|
* and interact with the Video Disk Recorder - or write a full featured
|
||||||
* graphical interface that sits on top of an SVDRP connection.
|
* graphical interface that sits on top of an SVDRP connection.
|
||||||
*
|
*
|
||||||
* $Id: svdrp.c 1.65 2004/10/31 10:09:53 kls Exp $
|
* $Id: svdrp.c 1.67 2004/12/26 12:23:55 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "svdrp.h"
|
#include "svdrp.h"
|
||||||
@ -555,8 +555,9 @@ void cSVDRP::CmdGRAB(const char *Option)
|
|||||||
char buf[strlen(Option) + 1];
|
char buf[strlen(Option) + 1];
|
||||||
char *p = strcpy(buf, Option);
|
char *p = strcpy(buf, Option);
|
||||||
const char *delim = " \t";
|
const char *delim = " \t";
|
||||||
FileName = strtok(p, delim);
|
char *strtok_next;
|
||||||
if ((p = strtok(NULL, delim)) != NULL) {
|
FileName = strtok_r(p, delim, &strtok_next);
|
||||||
|
if ((p = strtok_r(NULL, delim, &strtok_next)) != NULL) {
|
||||||
if (strcasecmp(p, "JPEG") == 0)
|
if (strcasecmp(p, "JPEG") == 0)
|
||||||
Jpeg = true;
|
Jpeg = true;
|
||||||
else if (strcasecmp(p, "PNM") == 0)
|
else if (strcasecmp(p, "PNM") == 0)
|
||||||
@ -566,7 +567,7 @@ void cSVDRP::CmdGRAB(const char *Option)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ((p = strtok(NULL, delim)) != NULL) {
|
if ((p = strtok_r(NULL, delim, &strtok_next)) != NULL) {
|
||||||
if (isnumber(p))
|
if (isnumber(p))
|
||||||
Quality = atoi(p);
|
Quality = atoi(p);
|
||||||
else {
|
else {
|
||||||
@ -574,14 +575,14 @@ void cSVDRP::CmdGRAB(const char *Option)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ((p = strtok(NULL, delim)) != NULL) {
|
if ((p = strtok_r(NULL, delim, &strtok_next)) != NULL) {
|
||||||
if (isnumber(p))
|
if (isnumber(p))
|
||||||
SizeX = atoi(p);
|
SizeX = atoi(p);
|
||||||
else {
|
else {
|
||||||
Reply(501, "Illegal sizex \"%s\"", p);
|
Reply(501, "Illegal sizex \"%s\"", p);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if ((p = strtok(NULL, delim)) != NULL) {
|
if ((p = strtok_r(NULL, delim, &strtok_next)) != NULL) {
|
||||||
if (isnumber(p))
|
if (isnumber(p))
|
||||||
SizeY = atoi(p);
|
SizeY = atoi(p);
|
||||||
else {
|
else {
|
||||||
@ -594,7 +595,7 @@ void cSVDRP::CmdGRAB(const char *Option)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ((p = strtok(NULL, delim)) != NULL) {
|
if ((p = strtok_r(NULL, delim, &strtok_next)) != NULL) {
|
||||||
Reply(501, "Unexpected parameter \"%s\"", p);
|
Reply(501, "Unexpected parameter \"%s\"", p);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -672,7 +673,7 @@ void cSVDRP::CmdLSTC(const char *Option)
|
|||||||
if (isnumber(Option)) {
|
if (isnumber(Option)) {
|
||||||
cChannel *channel = Channels.GetByNumber(strtol(Option, NULL, 10));
|
cChannel *channel = Channels.GetByNumber(strtol(Option, NULL, 10));
|
||||||
if (channel)
|
if (channel)
|
||||||
Reply(250, "%d %s", channel->Number(), channel->ToText());
|
Reply(250, "%d %s", channel->Number(), *channel->ToText());
|
||||||
else
|
else
|
||||||
Reply(501, "Channel \"%s\" not defined", Option);
|
Reply(501, "Channel \"%s\" not defined", Option);
|
||||||
}
|
}
|
||||||
@ -684,7 +685,7 @@ void cSVDRP::CmdLSTC(const char *Option)
|
|||||||
if (channel) {
|
if (channel) {
|
||||||
if (strcasestr(channel->Name(), Option)) {
|
if (strcasestr(channel->Name(), Option)) {
|
||||||
if (next)
|
if (next)
|
||||||
Reply(-250, "%d %s", next->Number(), next->ToText());
|
Reply(-250, "%d %s", next->Number(), *next->ToText());
|
||||||
next = channel;
|
next = channel;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -695,7 +696,7 @@ void cSVDRP::CmdLSTC(const char *Option)
|
|||||||
i = channel->Number() + 1;
|
i = channel->Number() + 1;
|
||||||
}
|
}
|
||||||
if (next)
|
if (next)
|
||||||
Reply(250, "%d %s", next->Number(), next->ToText());
|
Reply(250, "%d %s", next->Number(), *next->ToText());
|
||||||
else
|
else
|
||||||
Reply(501, "Channel \"%s\" not defined", Option);
|
Reply(501, "Channel \"%s\" not defined", Option);
|
||||||
}
|
}
|
||||||
@ -705,7 +706,7 @@ void cSVDRP::CmdLSTC(const char *Option)
|
|||||||
while (i <= Channels.MaxNumber()) {
|
while (i <= Channels.MaxNumber()) {
|
||||||
cChannel *channel = Channels.GetByNumber(i, 1);
|
cChannel *channel = Channels.GetByNumber(i, 1);
|
||||||
if (channel)
|
if (channel)
|
||||||
Reply(channel->Number() < Channels.MaxNumber() ? -250 : 250, "%d %s", channel->Number(), channel->ToText());
|
Reply(channel->Number() < Channels.MaxNumber() ? -250 : 250, "%d %s", channel->Number(), *channel->ToText());
|
||||||
else
|
else
|
||||||
Reply(501, "Channel \"%d\" not found", i);
|
Reply(501, "Channel \"%d\" not found", i);
|
||||||
i = channel->Number() + 1;
|
i = channel->Number() + 1;
|
||||||
@ -727,7 +728,8 @@ void cSVDRP::CmdLSTE(const char *Option)
|
|||||||
char buf[strlen(Option) + 1];
|
char buf[strlen(Option) + 1];
|
||||||
strcpy(buf, Option);
|
strcpy(buf, Option);
|
||||||
const char *delim = " \t";
|
const char *delim = " \t";
|
||||||
char *p = strtok(buf, delim);
|
char *strtok_next;
|
||||||
|
char *p = strtok_r(buf, delim, &strtok_next);
|
||||||
while (p && DumpMode == dmAll) {
|
while (p && DumpMode == dmAll) {
|
||||||
if (strcasecmp(p, "NOW") == 0)
|
if (strcasecmp(p, "NOW") == 0)
|
||||||
DumpMode = dmPresent;
|
DumpMode = dmPresent;
|
||||||
@ -735,7 +737,7 @@ void cSVDRP::CmdLSTE(const char *Option)
|
|||||||
DumpMode = dmFollowing;
|
DumpMode = dmFollowing;
|
||||||
else if (strcasecmp(p, "AT") == 0) {
|
else if (strcasecmp(p, "AT") == 0) {
|
||||||
DumpMode = dmAtTime;
|
DumpMode = dmAtTime;
|
||||||
if ((p = strtok(NULL, delim)) != NULL) {
|
if ((p = strtok_r(NULL, delim, &strtok_next)) != NULL) {
|
||||||
if (isnumber(p))
|
if (isnumber(p))
|
||||||
AtTime = strtol(p, NULL, 10);
|
AtTime = strtol(p, NULL, 10);
|
||||||
else {
|
else {
|
||||||
@ -770,7 +772,7 @@ void cSVDRP::CmdLSTE(const char *Option)
|
|||||||
Reply(501, "Unknown option: \"%s\"", p);
|
Reply(501, "Unknown option: \"%s\"", p);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
p = strtok(NULL, delim);
|
p = strtok_r(NULL, delim, &strtok_next);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
FILE *f = fdopen(file, "w");
|
FILE *f = fdopen(file, "w");
|
||||||
@ -828,7 +830,7 @@ void cSVDRP::CmdLSTT(const char *Option)
|
|||||||
if (isnumber(Option)) {
|
if (isnumber(Option)) {
|
||||||
cTimer *timer = Timers.Get(strtol(Option, NULL, 10) - 1);
|
cTimer *timer = Timers.Get(strtol(Option, NULL, 10) - 1);
|
||||||
if (timer)
|
if (timer)
|
||||||
Reply(250, "%d %s", timer->Index() + 1, timer->ToText());
|
Reply(250, "%d %s", timer->Index() + 1, *timer->ToText());
|
||||||
else
|
else
|
||||||
Reply(501, "Timer \"%s\" not defined", Option);
|
Reply(501, "Timer \"%s\" not defined", Option);
|
||||||
}
|
}
|
||||||
@ -839,7 +841,7 @@ void cSVDRP::CmdLSTT(const char *Option)
|
|||||||
for (int i = 0; i < Timers.Count(); i++) {
|
for (int i = 0; i < Timers.Count(); i++) {
|
||||||
cTimer *timer = Timers.Get(i);
|
cTimer *timer = Timers.Get(i);
|
||||||
if (timer)
|
if (timer)
|
||||||
Reply(i < Timers.Count() - 1 ? -250 : 250, "%d %s", timer->Index() + 1, timer->ToText());
|
Reply(i < Timers.Count() - 1 ? -250 : 250, "%d %s", timer->Index() + 1, *timer->ToText());
|
||||||
else
|
else
|
||||||
Reply(501, "Timer \"%d\" not found", i + 1);
|
Reply(501, "Timer \"%d\" not found", i + 1);
|
||||||
}
|
}
|
||||||
@ -877,8 +879,8 @@ void cSVDRP::CmdMODC(const char *Option)
|
|||||||
*channel = ch;
|
*channel = ch;
|
||||||
Channels.ReNumber();
|
Channels.ReNumber();
|
||||||
Channels.SetModified(true);
|
Channels.SetModified(true);
|
||||||
isyslog("modifed channel %d %s", channel->Number(), channel->ToText());
|
isyslog("modifed channel %d %s", channel->Number(), *channel->ToText());
|
||||||
Reply(250, "%d %s", channel->Number(), channel->ToText());
|
Reply(250, "%d %s", channel->Number(), *channel->ToText());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
Reply(501, "Channel settings are not unique");
|
Reply(501, "Channel settings are not unique");
|
||||||
@ -917,7 +919,7 @@ void cSVDRP::CmdMODT(const char *Option)
|
|||||||
*timer = t;
|
*timer = t;
|
||||||
Timers.SetModified();
|
Timers.SetModified();
|
||||||
isyslog("timer %d modified (%s)", timer->Index() + 1, timer->HasFlags(tfActive) ? "active" : "inactive");
|
isyslog("timer %d modified (%s)", timer->Index() + 1, timer->HasFlags(tfActive) ? "active" : "inactive");
|
||||||
Reply(250, "%d %s", timer->Index() + 1, timer->ToText());
|
Reply(250, "%d %s", timer->Index() + 1, *timer->ToText());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
Reply(501, "Timer \"%d\" not defined", n);
|
Reply(501, "Timer \"%d\" not defined", n);
|
||||||
@ -952,8 +954,8 @@ void cSVDRP::CmdNEWC(const char *Option)
|
|||||||
Channels.Add(channel);
|
Channels.Add(channel);
|
||||||
Channels.ReNumber();
|
Channels.ReNumber();
|
||||||
Channels.SetModified(true);
|
Channels.SetModified(true);
|
||||||
isyslog("new channel %d %s", channel->Number(), channel->ToText());
|
isyslog("new channel %d %s", channel->Number(), *channel->ToText());
|
||||||
Reply(250, "%d %s", channel->Number(), channel->ToText());
|
Reply(250, "%d %s", channel->Number(), *channel->ToText());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
Reply(501, "Channel settings are not unique");
|
Reply(501, "Channel settings are not unique");
|
||||||
@ -975,11 +977,11 @@ void cSVDRP::CmdNEWT(const char *Option)
|
|||||||
Timers.Add(timer);
|
Timers.Add(timer);
|
||||||
Timers.SetModified();
|
Timers.SetModified();
|
||||||
isyslog("timer %d added", timer->Index() + 1);
|
isyslog("timer %d added", timer->Index() + 1);
|
||||||
Reply(250, "%d %s", timer->Index() + 1, timer->ToText());
|
Reply(250, "%d %s", timer->Index() + 1, *timer->ToText());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
Reply(550, "Timer already defined: %d %s", t->Index() + 1, t->ToText());
|
Reply(550, "Timer already defined: %d %s", t->Index() + 1, *t->ToText());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
Reply(501, "Error in timer settings");
|
Reply(501, "Error in timer settings");
|
||||||
@ -995,11 +997,8 @@ void cSVDRP::CmdNEXT(const char *Option)
|
|||||||
if (t) {
|
if (t) {
|
||||||
time_t Start = t->StartTime();
|
time_t Start = t->StartTime();
|
||||||
int Number = t->Index() + 1;
|
int Number = t->Index() + 1;
|
||||||
if (!*Option) {
|
if (!*Option)
|
||||||
char *s = ctime(&Start);
|
Reply(250, "%d %s", Number, *TimeToString(Start));
|
||||||
s[strlen(s) - 1] = 0; // strip trailing newline
|
|
||||||
Reply(250, "%d %s", Number, s);
|
|
||||||
}
|
|
||||||
else if (strcasecmp(Option, "ABS") == 0)
|
else if (strcasecmp(Option, "ABS") == 0)
|
||||||
Reply(250, "%d %ld", Number, Start);
|
Reply(250, "%d %ld", Number, Start);
|
||||||
else if (strcasecmp(Option, "REL") == 0)
|
else if (strcasecmp(Option, "REL") == 0)
|
||||||
@ -1058,7 +1057,7 @@ void cSVDRP::CmdUPDT(const char *Option)
|
|||||||
isyslog("timer %d added", timer->Index() + 1);
|
isyslog("timer %d added", timer->Index() + 1);
|
||||||
}
|
}
|
||||||
Timers.SetModified();
|
Timers.SetModified();
|
||||||
Reply(250, "%d %s", timer->Index() + 1, timer->ToText());
|
Reply(250, "%d %s", timer->Index() + 1, *timer->ToText());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -1152,7 +1151,7 @@ bool cSVDRP::Process(void)
|
|||||||
char buffer[BUFSIZ];
|
char buffer[BUFSIZ];
|
||||||
gethostname(buffer, sizeof(buffer));
|
gethostname(buffer, sizeof(buffer));
|
||||||
time_t now = time(NULL);
|
time_t now = time(NULL);
|
||||||
Reply(220, "%s SVDRP VideoDiskRecorder %s; %s", buffer, VDRVERSION, ctime(&now));
|
Reply(220, "%s SVDRP VideoDiskRecorder %s; %s", buffer, VDRVERSION, *TimeToString(now));
|
||||||
}
|
}
|
||||||
if (NewConnection)
|
if (NewConnection)
|
||||||
lastActivity = time(NULL);
|
lastActivity = time(NULL);
|
||||||
|
23
symbols/audioleft.xpm
Normal file
23
symbols/audioleft.xpm
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
/* XPM */
|
||||||
|
static char * audioleft_xpm[] = {
|
||||||
|
"27 18 2 1",
|
||||||
|
". c #FFFFFF",
|
||||||
|
"+ c #000000",
|
||||||
|
"...........................",
|
||||||
|
"...........................",
|
||||||
|
"...........................",
|
||||||
|
"...........................",
|
||||||
|
".....++++.........++++.....",
|
||||||
|
"...++++++++.....++++++++...",
|
||||||
|
"...++++++++.....++....++...",
|
||||||
|
"..++++++++++...++......++..",
|
||||||
|
"..++++++++++...++......++..",
|
||||||
|
"..++++++++++...++......++..",
|
||||||
|
"..++++++++++...++......++..",
|
||||||
|
"...++++++++.....++....++...",
|
||||||
|
"...++++++++.....++++++++...",
|
||||||
|
".....++++.........++++.....",
|
||||||
|
"...........................",
|
||||||
|
"...........................",
|
||||||
|
"...........................",
|
||||||
|
"..........................."};
|
23
symbols/audioright.xpm
Normal file
23
symbols/audioright.xpm
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
/* XPM */
|
||||||
|
static char * audioright_xpm[] = {
|
||||||
|
"27 18 2 1",
|
||||||
|
". c #FFFFFF",
|
||||||
|
"+ c #000000",
|
||||||
|
"...........................",
|
||||||
|
"...........................",
|
||||||
|
"...........................",
|
||||||
|
"...........................",
|
||||||
|
".....++++.........++++.....",
|
||||||
|
"...++++++++.....++++++++...",
|
||||||
|
"...++....++.....++++++++...",
|
||||||
|
"..++......++...++++++++++..",
|
||||||
|
"..++......++...++++++++++..",
|
||||||
|
"..++......++...++++++++++..",
|
||||||
|
"..++......++...++++++++++..",
|
||||||
|
"...++....++.....++++++++...",
|
||||||
|
"...++++++++.....++++++++...",
|
||||||
|
".....++++.........++++.....",
|
||||||
|
"...........................",
|
||||||
|
"...........................",
|
||||||
|
"...........................",
|
||||||
|
"..........................."};
|
23
symbols/audiostereo.xpm
Normal file
23
symbols/audiostereo.xpm
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
/* XPM */
|
||||||
|
static char * audiostereo_xpm[] = {
|
||||||
|
"27 18 2 1",
|
||||||
|
". c #FFFFFF",
|
||||||
|
"+ c #000000",
|
||||||
|
"...........................",
|
||||||
|
"...........................",
|
||||||
|
"...........................",
|
||||||
|
"...........................",
|
||||||
|
".....++++.........++++.....",
|
||||||
|
"...++++++++.....++++++++...",
|
||||||
|
"...++++++++.....++++++++...",
|
||||||
|
"..++++++++++...++++++++++..",
|
||||||
|
"..++++++++++...++++++++++..",
|
||||||
|
"..++++++++++...++++++++++..",
|
||||||
|
"..++++++++++...++++++++++..",
|
||||||
|
"...++++++++.....++++++++...",
|
||||||
|
"...++++++++.....++++++++...",
|
||||||
|
".....++++.........++++.....",
|
||||||
|
"...........................",
|
||||||
|
"...........................",
|
||||||
|
"...........................",
|
||||||
|
"..........................."};
|
42
themes.c
42
themes.c
@ -4,7 +4,7 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* how to reach the author.
|
||||||
*
|
*
|
||||||
* $Id: themes.c 1.3 2004/06/18 15:05:07 kls Exp $
|
* $Id: themes.c 1.5 2004/12/24 17:00:41 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "themes.h"
|
#include "themes.h"
|
||||||
@ -96,7 +96,8 @@ bool cTheme::Load(const char *FileName, bool OnlyDescriptions)
|
|||||||
result = true;
|
result = true;
|
||||||
char *s;
|
char *s;
|
||||||
const char *error = NULL;
|
const char *error = NULL;
|
||||||
while ((s = readline(f)) != NULL) {
|
cReadLine ReadLine;
|
||||||
|
while ((s = ReadLine.Read(f)) != NULL) {
|
||||||
line++;
|
line++;
|
||||||
char *p = strchr(s, '#');
|
char *p = strchr(s, '#');
|
||||||
if (p)
|
if (p)
|
||||||
@ -242,29 +243,26 @@ bool cThemes::Load(const char *SkinName)
|
|||||||
{
|
{
|
||||||
Clear();
|
Clear();
|
||||||
if (themesDirectory) {
|
if (themesDirectory) {
|
||||||
DIR *d = opendir(themesDirectory);
|
cReadDir d(themesDirectory);
|
||||||
if (d) {
|
struct dirent *e;
|
||||||
struct dirent *e;
|
while ((e = d.Next()) != NULL) {
|
||||||
while ((e = readdir(d)) != NULL) {
|
if (strcmp(e->d_name, ".") && strcmp(e->d_name, "..")) {
|
||||||
if (strcmp(e->d_name, ".") && strcmp(e->d_name, "..")) {
|
if (strstr(e->d_name, SkinName) == e->d_name && e->d_name[strlen(SkinName)] == '-') {
|
||||||
if (strstr(e->d_name, SkinName) == e->d_name && e->d_name[strlen(SkinName)] == '-') {
|
cString FileName = AddDirectory(themesDirectory, e->d_name);
|
||||||
const char *FileName = AddDirectory(themesDirectory, e->d_name);
|
cTheme Theme;
|
||||||
cTheme Theme;
|
if (Theme.Load(*FileName, true)) {
|
||||||
if (Theme.Load(FileName, true)) {
|
names = (char **)realloc(names, (numThemes + 1) * sizeof(char *));
|
||||||
names = (char **)realloc(names, (numThemes + 1) * sizeof(char *));
|
names[numThemes] = strdup(Theme.Name());
|
||||||
names[numThemes] = strdup(Theme.Name());
|
fileNames = (char **)realloc(fileNames, (numThemes + 1) * sizeof(char *));
|
||||||
fileNames = (char **)realloc(fileNames, (numThemes + 1) * sizeof(char *));
|
fileNames[numThemes] = strdup(*FileName);
|
||||||
fileNames[numThemes] = strdup(FileName);
|
descriptions = (char **)realloc(descriptions, (numThemes + 1) * sizeof(char *));
|
||||||
descriptions = (char **)realloc(descriptions, (numThemes + 1) * sizeof(char *));
|
descriptions[numThemes] = strdup(Theme.Description());
|
||||||
descriptions[numThemes] = strdup(Theme.Description());
|
numThemes++;
|
||||||
numThemes++;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
closedir(d);
|
}
|
||||||
return numThemes > 0;
|
return numThemes > 0;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
49
thread.c
49
thread.c
@ -4,7 +4,7 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* how to reach the author.
|
||||||
*
|
*
|
||||||
* $Id: thread.c 1.37 2004/11/20 16:21:14 kls Exp $
|
* $Id: thread.c 1.40 2004/12/19 10:43:14 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "thread.h"
|
#include "thread.h"
|
||||||
@ -197,7 +197,8 @@ bool cThread::emergencyExitRequested = false;
|
|||||||
|
|
||||||
cThread::cThread(const char *Description)
|
cThread::cThread(const char *Description)
|
||||||
{
|
{
|
||||||
parentTid = childTid = 0;
|
running = false;
|
||||||
|
childTid = 0;
|
||||||
description = NULL;
|
description = NULL;
|
||||||
SetDescription(Description);
|
SetDescription(Description);
|
||||||
}
|
}
|
||||||
@ -221,33 +222,35 @@ void cThread::SetDescription(const char *Description, ...)
|
|||||||
|
|
||||||
void *cThread::StartThread(cThread *Thread)
|
void *cThread::StartThread(cThread *Thread)
|
||||||
{
|
{
|
||||||
Thread->childTid = pthread_self();
|
|
||||||
if (Thread->description)
|
if (Thread->description)
|
||||||
dsyslog("%s thread started (pid=%d, tid=%ld)", Thread->description, getpid(), Thread->childTid);
|
dsyslog("%s thread started (pid=%d, tid=%ld)", Thread->description, getpid(), pthread_self());
|
||||||
Thread->Action();
|
Thread->Action();
|
||||||
if (Thread->description)
|
if (Thread->description)
|
||||||
dsyslog("%s thread ended (pid=%d, tid=%ld)", Thread->description, getpid(), Thread->childTid);
|
dsyslog("%s thread ended (pid=%d, tid=%ld)", Thread->description, getpid(), pthread_self());
|
||||||
Thread->childTid = 0;
|
Thread->running = false;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool cThread::Start(void)
|
bool cThread::Start(void)
|
||||||
{
|
{
|
||||||
Lock();
|
if (!running) {
|
||||||
if (!childTid) {
|
running = true;
|
||||||
parentTid = pthread_self();
|
if (pthread_create(&childTid, NULL, (void *(*) (void *))&StartThread, (void *)this) == 0) {
|
||||||
pthread_t Tid;
|
pthread_detach(childTid); // auto-reap
|
||||||
pthread_create(&Tid, NULL, (void *(*) (void *))&StartThread, (void *)this);
|
pthread_setschedparam(childTid, SCHED_RR, 0);
|
||||||
pthread_detach(Tid); // auto-reap
|
}
|
||||||
pthread_setschedparam(Tid, SCHED_RR, 0);
|
else {
|
||||||
|
LOG_ERROR;
|
||||||
|
running = false;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Unlock();
|
return true;
|
||||||
return true; //XXX return value of pthread_create()???
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool cThread::Active(void)
|
bool cThread::Active(void)
|
||||||
{
|
{
|
||||||
if (childTid) {
|
if (running) {
|
||||||
//
|
//
|
||||||
// Single UNIX Spec v2 says:
|
// Single UNIX Spec v2 says:
|
||||||
//
|
//
|
||||||
@ -262,6 +265,7 @@ bool cThread::Active(void)
|
|||||||
if (err != ESRCH)
|
if (err != ESRCH)
|
||||||
LOG_ERROR;
|
LOG_ERROR;
|
||||||
childTid = 0;
|
childTid = 0;
|
||||||
|
running = false;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
return true;
|
return true;
|
||||||
@ -271,21 +275,18 @@ bool cThread::Active(void)
|
|||||||
|
|
||||||
void cThread::Cancel(int WaitSeconds)
|
void cThread::Cancel(int WaitSeconds)
|
||||||
{
|
{
|
||||||
if (childTid) {
|
if (running) {
|
||||||
if (WaitSeconds > 0) {
|
if (WaitSeconds > 0) {
|
||||||
for (time_t t0 = time(NULL) + WaitSeconds; time(NULL) < t0; ) {
|
for (time_t t0 = time(NULL) + WaitSeconds; time(NULL) < t0; ) {
|
||||||
if (!Active())
|
if (!Active())
|
||||||
return;
|
return;
|
||||||
cCondWait::SleepMs(10);
|
cCondWait::SleepMs(10);
|
||||||
}
|
}
|
||||||
esyslog("ERROR: thread %ld won't end (waited %d seconds) - cancelling it...", childTid, WaitSeconds);
|
esyslog("ERROR: thread %ld won't end (waited %d seconds) - canceling it...", childTid, WaitSeconds);
|
||||||
}
|
}
|
||||||
Lock();
|
pthread_cancel(childTid);
|
||||||
if (childTid) {
|
childTid = 0;
|
||||||
pthread_cancel(childTid);
|
running = false;
|
||||||
childTid = 0;
|
|
||||||
}
|
|
||||||
Unlock();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
5
thread.h
5
thread.h
@ -4,7 +4,7 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* how to reach the author.
|
||||||
*
|
*
|
||||||
* $Id: thread.h 1.24 2004/10/24 11:00:32 kls Exp $
|
* $Id: thread.h 1.26 2004/12/19 10:43:10 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __THREAD_H
|
#ifndef __THREAD_H
|
||||||
@ -73,7 +73,8 @@ public:
|
|||||||
class cThread {
|
class cThread {
|
||||||
friend class cThreadLock;
|
friend class cThreadLock;
|
||||||
private:
|
private:
|
||||||
pthread_t parentTid, childTid;
|
bool running;
|
||||||
|
pthread_t childTid;
|
||||||
cMutex mutex;
|
cMutex mutex;
|
||||||
char *description;
|
char *description;
|
||||||
static bool emergencyExitRequested;
|
static bool emergencyExitRequested;
|
||||||
|
27
timers.c
27
timers.c
@ -4,7 +4,7 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* how to reach the author.
|
||||||
*
|
*
|
||||||
* $Id: timers.c 1.18 2004/11/21 13:15:33 kls Exp $
|
* $Id: timers.c 1.21 2004/12/26 12:35:33 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "timers.h"
|
#include "timers.h"
|
||||||
@ -19,8 +19,6 @@
|
|||||||
|
|
||||||
// -- cTimer -----------------------------------------------------------------
|
// -- cTimer -----------------------------------------------------------------
|
||||||
|
|
||||||
char *cTimer::buffer = NULL;
|
|
||||||
|
|
||||||
cTimer::cTimer(bool Instant, bool Pause)
|
cTimer::cTimer(bool Instant, bool Pause)
|
||||||
{
|
{
|
||||||
startTime = stopTime = 0;
|
startTime = stopTime = 0;
|
||||||
@ -106,12 +104,12 @@ int cTimer::Compare(const cListObject &ListObject) const
|
|||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *cTimer::ToText(bool UseChannelID)
|
cString cTimer::ToText(bool UseChannelID)
|
||||||
{
|
{
|
||||||
free(buffer);
|
char *buffer;
|
||||||
strreplace(file, ':', '|');
|
strreplace(file, ':', '|');
|
||||||
strreplace(summary, '\n', '|');
|
strreplace(summary, '\n', '|');
|
||||||
asprintf(&buffer, "%d:%s:%s:%04d:%04d:%d:%d:%s:%s\n", flags, UseChannelID ? Channel()->GetChannelID().ToString() : itoa(Channel()->Number()), PrintDay(day, firstday), start, stop, priority, lifetime, file, summary ? summary : "");
|
asprintf(&buffer, "%d:%s:%s:%04d:%04d:%d:%d:%s:%s\n", flags, UseChannelID ? *Channel()->GetChannelID().ToString() : *itoa(Channel()->Number()), *PrintDay(day, firstday), start, stop, priority, lifetime, file, summary ? summary : "");
|
||||||
strreplace(summary, '|', '\n');
|
strreplace(summary, '|', '\n');
|
||||||
strreplace(file, '|', ':');
|
strreplace(file, '|', ':');
|
||||||
return buffer;
|
return buffer;
|
||||||
@ -162,10 +160,10 @@ int cTimer::ParseDay(const char *s, time_t *FirstDay)
|
|||||||
return d;
|
return d;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *cTimer::PrintDay(int d, time_t FirstDay)
|
cString cTimer::PrintDay(int d, time_t FirstDay)
|
||||||
{
|
{
|
||||||
#define DAYBUFFERSIZE 32
|
#define DAYBUFFERSIZE 32
|
||||||
static char buffer[DAYBUFFERSIZE];
|
char buffer[DAYBUFFERSIZE];
|
||||||
if ((d & 0x80000000) != 0) {
|
if ((d & 0x80000000) != 0) {
|
||||||
char *b = buffer;
|
char *b = buffer;
|
||||||
const char *w = tr("MTWTFSS");
|
const char *w = tr("MTWTFSS");
|
||||||
@ -186,12 +184,12 @@ const char *cTimer::PrintDay(int d, time_t FirstDay)
|
|||||||
return buffer;
|
return buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *cTimer::PrintFirstDay(void)
|
cString cTimer::PrintFirstDay(void)
|
||||||
{
|
{
|
||||||
if (firstday) {
|
if (firstday) {
|
||||||
const char *s = PrintDay(day, firstday);
|
cString s = PrintDay(day, firstday);
|
||||||
if (strlen(s) == 18)
|
if (strlen(s) == 18)
|
||||||
return s + 8;
|
return *s + 8;
|
||||||
}
|
}
|
||||||
return ""; // not NULL, so the caller can always use the result
|
return ""; // not NULL, so the caller can always use the result
|
||||||
}
|
}
|
||||||
@ -248,7 +246,7 @@ bool cTimer::Parse(const char *s)
|
|||||||
|
|
||||||
bool cTimer::Save(FILE *f)
|
bool cTimer::Save(FILE *f)
|
||||||
{
|
{
|
||||||
return fprintf(f, ToText(true)) > 0;
|
return fprintf(f, "%s", *ToText(true)) > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool cTimer::IsSingleEvent(void) const
|
bool cTimer::IsSingleEvent(void) const
|
||||||
@ -272,7 +270,6 @@ int cTimer::GetWDay(time_t t)
|
|||||||
int cTimer::GetWDayFromMDay(int MDay)
|
int cTimer::GetWDayFromMDay(int MDay)
|
||||||
{
|
{
|
||||||
time_t now = time(NULL);
|
time_t now = time(NULL);
|
||||||
int md = GetMDay(now);
|
|
||||||
for (int i = -1; i <= 28; i++) { // looking 4 weeks into the future should be enough
|
for (int i = -1; i <= 28; i++) { // looking 4 weeks into the future should be enough
|
||||||
time_t t0 = IncDay(now, i);
|
time_t t0 = IncDay(now, i);
|
||||||
if (GetMDay(t0) == MDay)
|
if (GetMDay(t0) == MDay)
|
||||||
@ -398,8 +395,8 @@ void cTimer::SetEvent(const cEvent *Event)
|
|||||||
if (Event) {
|
if (Event) {
|
||||||
char vpsbuf[64] = "";
|
char vpsbuf[64] = "";
|
||||||
if (Event->Vps())
|
if (Event->Vps())
|
||||||
sprintf(vpsbuf, "(VPS: %s) ", Event->GetVpsString());
|
sprintf(vpsbuf, "(VPS: %s) ", *Event->GetVpsString());
|
||||||
isyslog("timer %d (%d %04d-%04d '%s') set to event %s %s-%s %s'%s'", Index() + 1, Channel()->Number(), start, stop, file, Event->GetDateString(), Event->GetTimeString(), Event->GetEndTimeString(), vpsbuf, Event->Title());
|
isyslog("timer %d (%d %04d-%04d '%s') set to event %s %s-%s %s'%s'", Index() + 1, Channel()->Number(), start, stop, file, *Event->GetDateString(), *Event->GetTimeString(), *Event->GetEndTimeString(), vpsbuf, Event->Title());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
isyslog("timer %d (%d %04d-%04d '%s') set to no event", Index() + 1, Channel()->Number(), start, stop, file);
|
isyslog("timer %d (%d %04d-%04d '%s') set to no event", Index() + 1, Channel()->Number(), start, stop, file);
|
||||||
|
9
timers.h
9
timers.h
@ -4,7 +4,7 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* how to reach the author.
|
||||||
*
|
*
|
||||||
* $Id: timers.h 1.12 2004/11/21 12:37:33 kls Exp $
|
* $Id: timers.h 1.13 2004/12/26 12:21:29 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __TIMERS_H
|
#ifndef __TIMERS_H
|
||||||
@ -27,7 +27,6 @@ class cTimer : public cListObject {
|
|||||||
friend class cMenuEditTimer;
|
friend class cMenuEditTimer;
|
||||||
private:
|
private:
|
||||||
mutable time_t startTime, stopTime;
|
mutable time_t startTime, stopTime;
|
||||||
static char *buffer;
|
|
||||||
bool recording, pending, inVpsMargin;
|
bool recording, pending, inVpsMargin;
|
||||||
int flags;
|
int flags;
|
||||||
cChannel *channel;
|
cChannel *channel;
|
||||||
@ -59,7 +58,7 @@ public:
|
|||||||
const char *File(void) { return file; }
|
const char *File(void) { return file; }
|
||||||
time_t FirstDay(void) { return firstday; }
|
time_t FirstDay(void) { return firstday; }
|
||||||
const char *Summary(void) { return summary; }
|
const char *Summary(void) { return summary; }
|
||||||
const char *ToText(bool UseChannelID = false);
|
cString ToText(bool UseChannelID = false);
|
||||||
const cEvent *Event(void) { return event; }
|
const cEvent *Event(void) { return event; }
|
||||||
bool Parse(const char *s);
|
bool Parse(const char *s);
|
||||||
bool Save(FILE *f);
|
bool Save(FILE *f);
|
||||||
@ -85,10 +84,10 @@ public:
|
|||||||
bool HasFlags(int Flags) const;
|
bool HasFlags(int Flags) const;
|
||||||
void Skip(void);
|
void Skip(void);
|
||||||
void OnOff(void);
|
void OnOff(void);
|
||||||
const char *PrintFirstDay(void);
|
cString PrintFirstDay(void);
|
||||||
static int TimeToInt(int t);
|
static int TimeToInt(int t);
|
||||||
static int ParseDay(const char *s, time_t *FirstDay = NULL);
|
static int ParseDay(const char *s, time_t *FirstDay = NULL);
|
||||||
static const char *PrintDay(int d, time_t FirstDay = 0);
|
static cString PrintDay(int d, time_t FirstDay = 0);
|
||||||
};
|
};
|
||||||
|
|
||||||
class cTimers : public cConfig<cTimer> {
|
class cTimers : public cConfig<cTimer> {
|
||||||
|
173
tools.c
173
tools.c
@ -4,7 +4,7 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* how to reach the author.
|
||||||
*
|
*
|
||||||
* $Id: tools.c 1.82 2004/11/21 14:36:34 kls Exp $
|
* $Id: tools.c 1.87 2005/01/04 11:06:45 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "tools.h"
|
#include "tools.h"
|
||||||
@ -65,18 +65,6 @@ void writechar(int filedes, char c)
|
|||||||
safe_write(filedes, &c, sizeof(c));
|
safe_write(filedes, &c, sizeof(c));
|
||||||
}
|
}
|
||||||
|
|
||||||
char *readline(FILE *f)
|
|
||||||
{
|
|
||||||
static char buffer[MAXPARSEBUFFER];
|
|
||||||
if (fgets(buffer, sizeof(buffer), f) > 0) {
|
|
||||||
int l = strlen(buffer) - 1;
|
|
||||||
if (l >= 0 && buffer[l] == '\n')
|
|
||||||
buffer[l] = 0;
|
|
||||||
return buffer;
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
char *strcpyrealloc(char *dest, const char *src)
|
char *strcpyrealloc(char *dest, const char *src)
|
||||||
{
|
{
|
||||||
if (src) {
|
if (src) {
|
||||||
@ -167,15 +155,15 @@ char *compactspace(char *s)
|
|||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *strescape(const char *s, const char *chars)
|
cString strescape(const char *s, const char *chars)
|
||||||
{
|
{
|
||||||
static char *buffer = NULL;
|
char *buffer;
|
||||||
const char *p = s;
|
const char *p = s;
|
||||||
char *t = NULL;
|
char *t = NULL;
|
||||||
while (*p) {
|
while (*p) {
|
||||||
if (strchr(chars, *p)) {
|
if (strchr(chars, *p)) {
|
||||||
if (!t) {
|
if (!t) {
|
||||||
buffer = (char *)realloc(buffer, 2 * strlen(s) + 1);
|
buffer = MALLOC(char, 2 * strlen(s) + 1);
|
||||||
t = buffer + (p - s);
|
t = buffer + (p - s);
|
||||||
s = strcpy(buffer, s);
|
s = strcpy(buffer, s);
|
||||||
}
|
}
|
||||||
@ -222,25 +210,6 @@ int numdigits(int n)
|
|||||||
return strlen(buf);
|
return strlen(buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
int time_ms(void)
|
|
||||||
{
|
|
||||||
static time_t t0 = 0;
|
|
||||||
struct timeval t;
|
|
||||||
if (gettimeofday(&t, NULL) == 0) {
|
|
||||||
if (t0 == 0)
|
|
||||||
t0 = t.tv_sec; // this avoids an overflow (we only work with deltas)
|
|
||||||
return (t.tv_sec - t0) * 1000 + t.tv_usec / 1000;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void delay_ms(int ms)
|
|
||||||
{
|
|
||||||
int t0 = time_ms();
|
|
||||||
while (time_ms() - t0 < ms)
|
|
||||||
;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool isnumber(const char *s)
|
bool isnumber(const char *s)
|
||||||
{
|
{
|
||||||
if (!*s)
|
if (!*s)
|
||||||
@ -253,18 +222,17 @@ bool isnumber(const char *s)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *itoa(int n)
|
cString AddDirectory(const char *DirName, const char *FileName)
|
||||||
{
|
{
|
||||||
static char buf[16];
|
char *buf;
|
||||||
snprintf(buf, sizeof(buf), "%d", n);
|
asprintf(&buf, "%s/%s", DirName && *DirName ? DirName : ".", FileName);
|
||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *AddDirectory(const char *DirName, const char *FileName)
|
cString itoa(int n)
|
||||||
{
|
{
|
||||||
static char *buf = NULL;
|
char buf[16];
|
||||||
free(buf);
|
snprintf(buf, sizeof(buf), "%d", n);
|
||||||
asprintf(&buf, "%s/%s", DirName && *DirName ? DirName : ".", FileName);
|
|
||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -336,10 +304,10 @@ bool RemoveFileOrDir(const char *FileName, bool FollowSymlinks)
|
|||||||
struct stat st;
|
struct stat st;
|
||||||
if (stat(FileName, &st) == 0) {
|
if (stat(FileName, &st) == 0) {
|
||||||
if (S_ISDIR(st.st_mode)) {
|
if (S_ISDIR(st.st_mode)) {
|
||||||
DIR *d = opendir(FileName);
|
cReadDir d(FileName);
|
||||||
if (d) {
|
if (d.Ok()) {
|
||||||
struct dirent *e;
|
struct dirent *e;
|
||||||
while ((e = readdir(d)) != NULL) {
|
while ((e = d.Next()) != NULL) {
|
||||||
if (strcmp(e->d_name, ".") && strcmp(e->d_name, "..")) {
|
if (strcmp(e->d_name, ".") && strcmp(e->d_name, "..")) {
|
||||||
char *buffer;
|
char *buffer;
|
||||||
asprintf(&buffer, "%s/%s", FileName, e->d_name);
|
asprintf(&buffer, "%s/%s", FileName, e->d_name);
|
||||||
@ -367,7 +335,6 @@ bool RemoveFileOrDir(const char *FileName, bool FollowSymlinks)
|
|||||||
free(buffer);
|
free(buffer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
closedir(d);
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
LOG_ERROR_STR(FileName);
|
LOG_ERROR_STR(FileName);
|
||||||
@ -389,11 +356,11 @@ bool RemoveFileOrDir(const char *FileName, bool FollowSymlinks)
|
|||||||
|
|
||||||
bool RemoveEmptyDirectories(const char *DirName, bool RemoveThis)
|
bool RemoveEmptyDirectories(const char *DirName, bool RemoveThis)
|
||||||
{
|
{
|
||||||
DIR *d = opendir(DirName);
|
cReadDir d(DirName);
|
||||||
if (d) {
|
if (d.Ok()) {
|
||||||
bool empty = true;
|
bool empty = true;
|
||||||
struct dirent *e;
|
struct dirent *e;
|
||||||
while ((e = readdir(d)) != NULL) {
|
while ((e = d.Next()) != NULL) {
|
||||||
if (strcmp(e->d_name, ".") && strcmp(e->d_name, "..") && strcmp(e->d_name, "lost+found")) {
|
if (strcmp(e->d_name, ".") && strcmp(e->d_name, "..") && strcmp(e->d_name, "lost+found")) {
|
||||||
char *buffer;
|
char *buffer;
|
||||||
asprintf(&buffer, "%s/%s", DirName, e->d_name);
|
asprintf(&buffer, "%s/%s", DirName, e->d_name);
|
||||||
@ -414,7 +381,6 @@ bool RemoveEmptyDirectories(const char *DirName, bool RemoveThis)
|
|||||||
free(buffer);
|
free(buffer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
closedir(d);
|
|
||||||
if (RemoveThis && empty) {
|
if (RemoveThis && empty) {
|
||||||
dsyslog("removing %s", DirName);
|
dsyslog("removing %s", DirName);
|
||||||
if (remove(DirName) < 0) {
|
if (remove(DirName) < 0) {
|
||||||
@ -451,7 +417,7 @@ char *ReadLink(const char *FileName)
|
|||||||
|
|
||||||
bool SpinUpDisk(const char *FileName)
|
bool SpinUpDisk(const char *FileName)
|
||||||
{
|
{
|
||||||
static char *buf = NULL;
|
char *buf = NULL;
|
||||||
for (int n = 0; n < 10; n++) {
|
for (int n = 0; n < 10; n++) {
|
||||||
free(buf);
|
free(buf);
|
||||||
if (DirectoryOk(FileName))
|
if (DirectoryOk(FileName))
|
||||||
@ -471,12 +437,14 @@ bool SpinUpDisk(const char *FileName)
|
|||||||
double seconds = (((long long)tp2.tv_sec * 1000000 + tp2.tv_usec) - ((long long)tp1.tv_sec * 1000000 + tp1.tv_usec)) / 1000000.0;
|
double seconds = (((long long)tp2.tv_sec * 1000000 + tp2.tv_usec) - ((long long)tp1.tv_sec * 1000000 + tp1.tv_usec)) / 1000000.0;
|
||||||
if (seconds > 0.5)
|
if (seconds > 0.5)
|
||||||
dsyslog("SpinUpDisk took %.2f seconds\n", seconds);
|
dsyslog("SpinUpDisk took %.2f seconds\n", seconds);
|
||||||
|
free(buf);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
LOG_ERROR_STR(buf);
|
LOG_ERROR_STR(buf);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
free(buf);
|
||||||
esyslog("ERROR: SpinUpDisk failed");
|
esyslog("ERROR: SpinUpDisk failed");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -489,37 +457,108 @@ time_t LastModifiedTime(const char *FileName)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *WeekDayName(int WeekDay)
|
// --- cTimeMs ---------------------------------------------------------------
|
||||||
|
|
||||||
|
cTimeMs::cTimeMs(void)
|
||||||
{
|
{
|
||||||
static char buffer[4];
|
Set();
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64 cTimeMs::Now(void)
|
||||||
|
{
|
||||||
|
struct timeval t;
|
||||||
|
if (gettimeofday(&t, NULL) == 0)
|
||||||
|
return (uint64(t.tv_sec)) * 1000 + t.tv_usec / 1000;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void cTimeMs::Set(int Ms)
|
||||||
|
{
|
||||||
|
begin = Now() + Ms;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool cTimeMs::TimedOut(void)
|
||||||
|
{
|
||||||
|
return Now() >= begin;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64 cTimeMs::Elapsed(void)
|
||||||
|
{
|
||||||
|
return Now() - begin;
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- cString ---------------------------------------------------------------
|
||||||
|
|
||||||
|
cString::cString(const char *S)
|
||||||
|
{
|
||||||
|
s = S ? strdup(S) : NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
cString::~cString()
|
||||||
|
{
|
||||||
|
free(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
cString &cString::operator=(const cString &String)
|
||||||
|
{
|
||||||
|
s = String.s ? strdup(String.s) : NULL;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
cString WeekDayName(int WeekDay)
|
||||||
|
{
|
||||||
|
char buffer[4];
|
||||||
WeekDay = WeekDay == 0 ? 6 : WeekDay - 1; // we start with monday==0!
|
WeekDay = WeekDay == 0 ? 6 : WeekDay - 1; // we start with monday==0!
|
||||||
if (0 <= WeekDay && WeekDay <= 6) {
|
if (0 <= WeekDay && WeekDay <= 6) {
|
||||||
const char *day = tr("MonTueWedThuFriSatSun");
|
const char *day = tr("MonTueWedThuFriSatSun");
|
||||||
day += WeekDay * 3;
|
day += WeekDay * 3;
|
||||||
strncpy(buffer, day, 3);
|
strn0cpy(buffer, day, sizeof(buffer));
|
||||||
return buffer;
|
return buffer;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
return "???";
|
return "???";
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *WeekDayName(time_t t)
|
cString WeekDayName(time_t t)
|
||||||
{
|
{
|
||||||
struct tm tm_r;
|
struct tm tm_r;
|
||||||
return WeekDayName(localtime_r(&t, &tm_r)->tm_wday);
|
return WeekDayName(localtime_r(&t, &tm_r)->tm_wday);
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *DayDateTime(time_t t)
|
cString DayDateTime(time_t t)
|
||||||
{
|
{
|
||||||
static char buffer[32];
|
char buffer[32];
|
||||||
if (t == 0)
|
if (t == 0)
|
||||||
time(&t);
|
time(&t);
|
||||||
struct tm tm_r;
|
struct tm tm_r;
|
||||||
tm *tm = localtime_r(&t, &tm_r);
|
tm *tm = localtime_r(&t, &tm_r);
|
||||||
snprintf(buffer, sizeof(buffer), "%s %2d.%02d %02d:%02d", WeekDayName(tm->tm_wday), tm->tm_mday, tm->tm_mon + 1, tm->tm_hour, tm->tm_min);
|
snprintf(buffer, sizeof(buffer), "%s %2d.%02d %02d:%02d", *WeekDayName(tm->tm_wday), tm->tm_mday, tm->tm_mon + 1, tm->tm_hour, tm->tm_min);
|
||||||
return buffer;
|
return buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cString TimeToString(time_t t)
|
||||||
|
{
|
||||||
|
char buffer[32];
|
||||||
|
if (ctime_r(&t, buffer)) {
|
||||||
|
buffer[strlen(buffer) - 1] = 0; // strip trailing newline
|
||||||
|
return buffer;
|
||||||
|
}
|
||||||
|
return "???";
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- cReadLine -------------------------------------------------------------
|
||||||
|
|
||||||
|
char *cReadLine::Read(FILE *f)
|
||||||
|
{
|
||||||
|
if (fgets(buffer, sizeof(buffer), f) > 0) {
|
||||||
|
int l = strlen(buffer) - 1;
|
||||||
|
if (l >= 0 && buffer[l] == '\n')
|
||||||
|
buffer[l] = 0;
|
||||||
|
return buffer;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
// --- cPoller ---------------------------------------------------------------
|
// --- cPoller ---------------------------------------------------------------
|
||||||
|
|
||||||
cPoller::cPoller(int FileHandle, bool Out)
|
cPoller::cPoller(int FileHandle, bool Out)
|
||||||
@ -557,6 +596,24 @@ bool cPoller::Poll(int TimeoutMs)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// --- cReadDir --------------------------------------------------------------
|
||||||
|
|
||||||
|
cReadDir::cReadDir(const char *Directory)
|
||||||
|
{
|
||||||
|
directory = opendir(Directory);
|
||||||
|
}
|
||||||
|
|
||||||
|
cReadDir::~cReadDir()
|
||||||
|
{
|
||||||
|
if (directory)
|
||||||
|
closedir(directory);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct dirent *cReadDir::Next(void)
|
||||||
|
{
|
||||||
|
return directory && readdir_r(directory, &u.d, &result) == 0 ? result : NULL;
|
||||||
|
}
|
||||||
|
|
||||||
// --- cFile -----------------------------------------------------------------
|
// --- cFile -----------------------------------------------------------------
|
||||||
|
|
||||||
bool cFile::files[FD_SETSIZE] = { false };
|
bool cFile::files[FD_SETSIZE] = { false };
|
||||||
|
64
tools.h
64
tools.h
@ -4,15 +4,17 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* how to reach the author.
|
||||||
*
|
*
|
||||||
* $Id: tools.h 1.58 2004/10/31 16:16:37 kls Exp $
|
* $Id: tools.h 1.64 2005/01/04 11:09:51 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __TOOLS_H
|
#ifndef __TOOLS_H
|
||||||
#define __TOOLS_H
|
#define __TOOLS_H
|
||||||
|
|
||||||
|
#include <dirent.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <poll.h>
|
#include <poll.h>
|
||||||
|
#include <stddef.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <syslog.h>
|
#include <syslog.h>
|
||||||
@ -55,10 +57,20 @@ template<class T> inline void swap(T &a, T &b) { T t = a; a = b; b = t; }
|
|||||||
#define BCDCHARTOINT(x) (10 * ((x & 0xF0) >> 4) + (x & 0xF))
|
#define BCDCHARTOINT(x) (10 * ((x & 0xF0) >> 4) + (x & 0xF))
|
||||||
int BCD2INT(int x);
|
int BCD2INT(int x);
|
||||||
|
|
||||||
|
class cString {
|
||||||
|
private:
|
||||||
|
char *s;
|
||||||
|
public:
|
||||||
|
cString(const char *S = NULL);
|
||||||
|
virtual ~cString();
|
||||||
|
operator const char * () const { return s; } // for use in (const char *) context
|
||||||
|
const char * operator*() const { return s; } // for use in (const void *) context (printf() etc.)
|
||||||
|
cString &operator=(const cString &String);
|
||||||
|
};
|
||||||
|
|
||||||
ssize_t safe_read(int filedes, void *buffer, size_t size);
|
ssize_t safe_read(int filedes, void *buffer, size_t size);
|
||||||
ssize_t safe_write(int filedes, const void *buffer, size_t size);
|
ssize_t safe_write(int filedes, const void *buffer, size_t size);
|
||||||
void writechar(int filedes, char c);
|
void writechar(int filedes, char c);
|
||||||
char *readline(FILE *f);
|
|
||||||
char *strcpyrealloc(char *dest, const char *src);
|
char *strcpyrealloc(char *dest, const char *src);
|
||||||
char *strn0cpy(char *dest, const char *src, size_t n);
|
char *strn0cpy(char *dest, const char *src, size_t n);
|
||||||
char *strreplace(char *s, char c1, char c2);
|
char *strreplace(char *s, char c1, char c2);
|
||||||
@ -66,16 +78,14 @@ char *strreplace(char *s, const char *s1, const char *s2); ///< re-allocates 's'
|
|||||||
char *skipspace(const char *s);
|
char *skipspace(const char *s);
|
||||||
char *stripspace(char *s);
|
char *stripspace(char *s);
|
||||||
char *compactspace(char *s);
|
char *compactspace(char *s);
|
||||||
const char *strescape(const char *s, const char *chars); ///< \warning returns a statically allocated string!
|
cString strescape(const char *s, const char *chars);
|
||||||
bool startswith(const char *s, const char *p);
|
bool startswith(const char *s, const char *p);
|
||||||
bool endswith(const char *s, const char *p);
|
bool endswith(const char *s, const char *p);
|
||||||
bool isempty(const char *s);
|
bool isempty(const char *s);
|
||||||
int numdigits(int n);
|
int numdigits(int n);
|
||||||
int time_ms(void);
|
|
||||||
void delay_ms(int ms);
|
|
||||||
bool isnumber(const char *s);
|
bool isnumber(const char *s);
|
||||||
const char *itoa(int n); ///< \warning returns a statically allocated string!
|
cString itoa(int n);
|
||||||
const char *AddDirectory(const char *DirName, const char *FileName); ///< \warning returns a statically allocated string!
|
cString AddDirectory(const char *DirName, const char *FileName);
|
||||||
int FreeDiskSpaceMB(const char *Directory, int *UsedMB = NULL);
|
int FreeDiskSpaceMB(const char *Directory, int *UsedMB = NULL);
|
||||||
bool DirectoryOk(const char *DirName, bool LogErrors = false);
|
bool DirectoryOk(const char *DirName, bool LogErrors = false);
|
||||||
bool MakeDirs(const char *FileName, bool IsDirectory = false);
|
bool MakeDirs(const char *FileName, bool IsDirectory = false);
|
||||||
@ -84,9 +94,28 @@ bool RemoveEmptyDirectories(const char *DirName, bool RemoveThis = false);
|
|||||||
char *ReadLink(const char *FileName);
|
char *ReadLink(const char *FileName);
|
||||||
bool SpinUpDisk(const char *FileName);
|
bool SpinUpDisk(const char *FileName);
|
||||||
time_t LastModifiedTime(const char *FileName);
|
time_t LastModifiedTime(const char *FileName);
|
||||||
const char *WeekDayName(int WeekDay); ///< \warning returns a statically allocated string!
|
cString WeekDayName(int WeekDay);
|
||||||
const char *WeekDayName(time_t t); ///< \warning returns a statically allocated string!
|
cString WeekDayName(time_t t);
|
||||||
const char *DayDateTime(time_t t = 0); ///< \warning returns a statically allocated string!
|
cString DayDateTime(time_t t = 0);
|
||||||
|
cString TimeToString(time_t t);
|
||||||
|
|
||||||
|
class cTimeMs {
|
||||||
|
private:
|
||||||
|
uint64 begin;
|
||||||
|
public:
|
||||||
|
cTimeMs(void);
|
||||||
|
static uint64 Now(void);
|
||||||
|
void Set(int Ms = 0);
|
||||||
|
bool TimedOut(void);
|
||||||
|
uint64 Elapsed(void);
|
||||||
|
};
|
||||||
|
|
||||||
|
class cReadLine {
|
||||||
|
private:
|
||||||
|
char buffer[MAXPARSEBUFFER];
|
||||||
|
public:
|
||||||
|
char *Read(FILE *f);
|
||||||
|
};
|
||||||
|
|
||||||
class cPoller {
|
class cPoller {
|
||||||
private:
|
private:
|
||||||
@ -99,6 +128,21 @@ public:
|
|||||||
bool Poll(int TimeoutMs = 0);
|
bool Poll(int TimeoutMs = 0);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class cReadDir {
|
||||||
|
private:
|
||||||
|
DIR *directory;
|
||||||
|
struct dirent *result;
|
||||||
|
union { // according to "The GNU C Library Reference Manual"
|
||||||
|
struct dirent d;
|
||||||
|
char b[offsetof(struct dirent, d_name) + NAME_MAX + 1];
|
||||||
|
} u;
|
||||||
|
public:
|
||||||
|
cReadDir(const char *Directory);
|
||||||
|
~cReadDir();
|
||||||
|
bool Ok(void) { return directory != NULL; }
|
||||||
|
struct dirent *Next(void);
|
||||||
|
};
|
||||||
|
|
||||||
class cFile {
|
class cFile {
|
||||||
private:
|
private:
|
||||||
static bool files[];
|
static bool files[];
|
||||||
|
97
transfer.c
97
transfer.c
@ -4,7 +4,7 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* how to reach the author.
|
||||||
*
|
*
|
||||||
* $Id: transfer.c 1.18 2004/10/23 13:35:08 kls Exp $
|
* $Id: transfer.c 1.22 2005/01/07 15:44:30 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "transfer.h"
|
#include "transfer.h"
|
||||||
@ -20,8 +20,7 @@ cTransfer::cTransfer(int VPid, int APid1, int APid2, int DPid1, int DPid2)
|
|||||||
{
|
{
|
||||||
ringBuffer = new cRingBufferLinear(TRANSFERBUFSIZE, TS_SIZE * 2, true, "Transfer");
|
ringBuffer = new cRingBufferLinear(TRANSFERBUFSIZE, TS_SIZE * 2, true, "Transfer");
|
||||||
remux = new cRemux(VPid, APid1, APid2, DPid1, DPid2);
|
remux = new cRemux(VPid, APid1, APid2, DPid1, DPid2);
|
||||||
canToggleAudioTrack = false;
|
needsBufferReserve = VPid != 0 && DPid1 != 0;
|
||||||
audioTrack = 0xC0;
|
|
||||||
active = false;
|
active = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -60,8 +59,36 @@ void cTransfer::Action(void)
|
|||||||
int PollTimeouts = 0;
|
int PollTimeouts = 0;
|
||||||
uchar *p = NULL;
|
uchar *p = NULL;
|
||||||
int Result = 0;
|
int Result = 0;
|
||||||
|
#define FW_NEEDS_BUFFER_RESERVE_FOR_AC3
|
||||||
|
#ifdef FW_NEEDS_BUFFER_RESERVE_FOR_AC3
|
||||||
|
bool Cleared = false;
|
||||||
|
bool GotBufferReserve = false;
|
||||||
|
#endif
|
||||||
active = true;
|
active = true;
|
||||||
while (active) {
|
while (active) {
|
||||||
|
#ifdef FW_NEEDS_BUFFER_RESERVE_FOR_AC3
|
||||||
|
if (needsBufferReserve) {
|
||||||
|
if (IsAttached() && !Cleared) {
|
||||||
|
PlayPes(NULL, 0);
|
||||||
|
Cleared = true;
|
||||||
|
}
|
||||||
|
//XXX For dolby we've to fill the buffer because the firmware does
|
||||||
|
//XXX not decode dolby but use a PCM stream for transport, therefore
|
||||||
|
//XXX the firmware has not enough buffer for noiseless skipping early
|
||||||
|
//XXX PCM samples (each dolby frame requires 6144 bytes in PCM and
|
||||||
|
//XXX audio is mostly to early in comparison to video).
|
||||||
|
//XXX To resolve this, the remuxer or PlayPes() should synchronize
|
||||||
|
//XXX audio with the video frames. 2004/09/09 Werner
|
||||||
|
if (!GotBufferReserve) {
|
||||||
|
if (ringBuffer->Available() < 3 * MAXFRAMESIZE / 2) {
|
||||||
|
cCondWait::SleepMs(20); // allow the buffer to collect some reserve
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
GotBufferReserve = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
int Count;
|
int Count;
|
||||||
uchar *b = ringBuffer->Get(Count);
|
uchar *b = ringBuffer->Get(Count);
|
||||||
if (b) {
|
if (b) {
|
||||||
@ -80,13 +107,13 @@ void cTransfer::Action(void)
|
|||||||
if (Count)
|
if (Count)
|
||||||
ringBuffer->Del(Count);
|
ringBuffer->Del(Count);
|
||||||
}
|
}
|
||||||
if (!p && (p = remux->Get(Result)) != NULL)
|
if (!p)
|
||||||
StripAudioPackets(p, Result, audioTrack);
|
p = remux->Get(Result);
|
||||||
if (p) {
|
if (p) {
|
||||||
cPoller Poller;
|
cPoller Poller;
|
||||||
if (DevicePoll(Poller, 100)) {
|
if (DevicePoll(Poller, 100)) {
|
||||||
PollTimeouts = 0;
|
PollTimeouts = 0;
|
||||||
int w = PlayVideo(p, Result);
|
int w = PlayPes(p, Result);
|
||||||
if (w > 0) {
|
if (w > 0) {
|
||||||
p += w;
|
p += w;
|
||||||
Result -= w;
|
Result -= w;
|
||||||
@ -112,64 +139,6 @@ void cTransfer::Action(void)
|
|||||||
active = false;
|
active = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void cTransfer::StripAudioPackets(uchar *b, int Length, uchar Except)
|
|
||||||
{
|
|
||||||
for (int i = 0; i < Length - 6; i++) {
|
|
||||||
if (b[i] == 0x00 && b[i + 1] == 0x00 && b[i + 2] == 0x01) {
|
|
||||||
uchar c = b[i + 3];
|
|
||||||
int l = b[i + 4] * 256 + b[i + 5] + 6;
|
|
||||||
switch (c) {
|
|
||||||
case 0xBD: // dolby
|
|
||||||
if (Except)
|
|
||||||
PlayAudio(&b[i], l);
|
|
||||||
// continue with deleting the data - otherwise it disturbs DVB replay
|
|
||||||
case 0xC0 ... 0xC1: // audio
|
|
||||||
if (c == 0xC1)
|
|
||||||
canToggleAudioTrack = true;
|
|
||||||
if (!Except || c != Except)
|
|
||||||
memset(&b[i], 0x00, min(l, Length-i));
|
|
||||||
break;
|
|
||||||
case 0xE0 ... 0xEF: // video
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
//esyslog("ERROR: unexpected packet id %02X", c);
|
|
||||||
l = 0;
|
|
||||||
}
|
|
||||||
if (l)
|
|
||||||
i += l - 1; // the loop increments, too!
|
|
||||||
}
|
|
||||||
/*XXX
|
|
||||||
else
|
|
||||||
esyslog("ERROR: broken packet header");
|
|
||||||
XXX*/
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int cTransfer::NumAudioTracks(void) const
|
|
||||||
{
|
|
||||||
return canToggleAudioTrack ? 2 : 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
const char **cTransfer::GetAudioTracks(int *CurrentTrack) const
|
|
||||||
{
|
|
||||||
if (NumAudioTracks()) {
|
|
||||||
if (CurrentTrack)
|
|
||||||
*CurrentTrack = (audioTrack == 0xC0) ? 0 : 1;
|
|
||||||
static const char *audioTracks1[] = { "Audio 1", NULL };
|
|
||||||
static const char *audioTracks2[] = { "Audio 1", "Audio 2", NULL };
|
|
||||||
return NumAudioTracks() > 1 ? audioTracks2 : audioTracks1;
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
void cTransfer::SetAudioTrack(int Index)
|
|
||||||
{
|
|
||||||
if ((audioTrack == 0xC0) != (Index == 0)) {
|
|
||||||
audioTrack = (Index == 1) ? 0xC1 : 0xC0;
|
|
||||||
DeviceClear();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// --- cTransferControl ------------------------------------------------------
|
// --- cTransferControl ------------------------------------------------------
|
||||||
|
|
||||||
cDevice *cTransferControl::receiverDevice = NULL;
|
cDevice *cTransferControl::receiverDevice = NULL;
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* how to reach the author.
|
||||||
*
|
*
|
||||||
* $Id: transfer.h 1.5 2004/10/15 12:39:54 kls Exp $
|
* $Id: transfer.h 1.8 2005/01/07 15:44:32 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __TRANSFER_H
|
#ifndef __TRANSFER_H
|
||||||
@ -20,10 +20,8 @@ class cTransfer : public cReceiver, public cPlayer, public cThread {
|
|||||||
private:
|
private:
|
||||||
cRingBufferLinear *ringBuffer;
|
cRingBufferLinear *ringBuffer;
|
||||||
cRemux *remux;
|
cRemux *remux;
|
||||||
bool canToggleAudioTrack;
|
bool needsBufferReserve;
|
||||||
uchar audioTrack;
|
|
||||||
bool active;
|
bool active;
|
||||||
void StripAudioPackets(uchar *b, int Length, uchar Except = 0x00);
|
|
||||||
protected:
|
protected:
|
||||||
virtual void Activate(bool On);
|
virtual void Activate(bool On);
|
||||||
virtual void Receive(uchar *Data, int Length);
|
virtual void Receive(uchar *Data, int Length);
|
||||||
@ -31,9 +29,6 @@ protected:
|
|||||||
public:
|
public:
|
||||||
cTransfer(int VPid, int APid1, int APid2, int DPid1, int DPid2);
|
cTransfer(int VPid, int APid1, int APid2, int DPid1, int DPid2);
|
||||||
virtual ~cTransfer();
|
virtual ~cTransfer();
|
||||||
virtual int NumAudioTracks(void) const;
|
|
||||||
virtual const char **GetAudioTracks(int *CurrentTrack = NULL) const;
|
|
||||||
virtual void SetAudioTrack(int Index);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class cTransferControl : public cControl {
|
class cTransferControl : public cControl {
|
||||||
|
62
vdr.1
62
vdr.1
@ -2,15 +2,15 @@
|
|||||||
.\" ** The above line should force tbl to be a preprocessor **
|
.\" ** The above line should force tbl to be a preprocessor **
|
||||||
.\" Man page for vdr
|
.\" Man page for vdr
|
||||||
.\"
|
.\"
|
||||||
.\" Copyright (C) 2003 Klaus Schmidinger
|
.\" Copyright (C) 2004 Klaus Schmidinger
|
||||||
.\"
|
.\"
|
||||||
.\" You may distribute under the terms of the GNU General Public
|
.\" You may distribute under the terms of the GNU General Public
|
||||||
.\" License as specified in the file COPYING that comes with the
|
.\" License as specified in the file COPYING that comes with the
|
||||||
.\" vdr distribution.
|
.\" vdr distribution.
|
||||||
.\"
|
.\"
|
||||||
.\" $Id: vdr.1 1.11 2004/06/13 14:48:03 kls Exp $
|
.\" $Id: vdr.1 1.13 2004/12/19 09:36:25 kls Exp $
|
||||||
.\"
|
.\"
|
||||||
.TH vdr 1 "1 June 2003" "1.2.0" "Video Disk Recorder"
|
.TH vdr 1 "19 Dec 2004" "1.3.18" "Video Disk Recorder"
|
||||||
.SH NAME
|
.SH NAME
|
||||||
vdr - the Video Disk Recorder
|
vdr - the Video Disk Recorder
|
||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
@ -18,7 +18,7 @@ vdr - the Video Disk Recorder
|
|||||||
[options]
|
[options]
|
||||||
.SH DESCRIPTION
|
.SH DESCRIPTION
|
||||||
.B vdr
|
.B vdr
|
||||||
implements a complete digital Set-Top-Box and Video Recorder.
|
implements a complete digital Set-Top Box and Video Recorder.
|
||||||
It can work with signals received from satellites (DVB-S) as
|
It can work with signals received from satellites (DVB-S) as
|
||||||
well as cable (DVB-C) and terrestrial (DVB-T) signals.
|
well as cable (DVB-C) and terrestrial (DVB-T) signals.
|
||||||
|
|
||||||
@ -38,31 +38,31 @@ Remote access is possible via the "Simple Video Disk Recorder Protocol" (SVDRP),
|
|||||||
which can be accessed on port 2001, for instance by \fBtelnet\fR.
|
which can be accessed on port 2001, for instance by \fBtelnet\fR.
|
||||||
.SH OPTIONS
|
.SH OPTIONS
|
||||||
.TP
|
.TP
|
||||||
.BI -a\ cmd ,\ --audio= cmd
|
.BI \-a\ cmd ,\ \-\-audio= cmd
|
||||||
Send Dolby Digital audio to stdin of command \fIcmd\fR.
|
Send Dolby Digital audio to stdin of command \fIcmd\fR.
|
||||||
.TP
|
.TP
|
||||||
.BI -c\ dir ,\ --config= dir
|
.BI \-c\ dir ,\ \-\-config= dir
|
||||||
Read config files from directory \fIdir\fR
|
Read config files from directory \fIdir\fR
|
||||||
(default is to read them from the video directory).
|
(default is to read them from the video directory).
|
||||||
.TP
|
.TP
|
||||||
.B -d, --daemon
|
.B \-d, \-\-daemon
|
||||||
Run in daemon mode.
|
Run in daemon mode.
|
||||||
.TP
|
.TP
|
||||||
.BI -D\ num ,\ --device= num
|
.BI \-D\ num ,\ \-\-device= num
|
||||||
Use only the given DVB device (\fInum\fR = 0, 1, 2...).
|
Use only the given DVB device (\fInum\fR = 0, 1, 2...).
|
||||||
There may be several \fB-D\fR options (by default all DVB devices will be used).
|
There may be several \fB\-D\fR options (by default all DVB devices will be used).
|
||||||
.TP
|
.TP
|
||||||
.BI -E\ file ,\ --epgfile= file
|
.BI \-E\ file ,\ \-\-epgfile= file
|
||||||
Write the EPG data into the given \fIfile\fR
|
Write the EPG data into the given \fIfile\fR
|
||||||
(default is \fI/video/epg.data\fR).
|
(default is \fI/video/epg.data\fR).
|
||||||
Use \fB-E-\fR to disable this.
|
Use \fB\-E\-\fR to disable this.
|
||||||
If \fIfile\fR is a directory, the file \fIepg.data\fR
|
If \fIfile\fR is a directory, the file \fIepg.data\fR
|
||||||
will be created in that directory.
|
will be created in that directory.
|
||||||
.TP
|
.TP
|
||||||
.B -h, --help
|
.B \-h, \-\-help
|
||||||
Print a help message and exit.
|
Print a help message and exit.
|
||||||
.TP
|
.TP
|
||||||
.BI -l\ level ,\ --log= level
|
.BI \-l\ level ,\ \-\-log= level
|
||||||
Set logging to \fIlevel\fR.
|
Set logging to \fIlevel\fR.
|
||||||
\fB0\fR\ =\ no logging, \fB1\fR\ =\ errors only,
|
\fB0\fR\ =\ no logging, \fB1\fR\ =\ errors only,
|
||||||
\fB2\fR\ =\ errors and info, \fB3\fR\ =\ errors, info and debug.
|
\fB2\fR\ =\ errors and info, \fB3\fR\ =\ errors, info and debug.
|
||||||
@ -70,54 +70,54 @@ The default logging level is \fB3\fR.
|
|||||||
If logging should be done to LOG_LOCALn instead of
|
If logging should be done to LOG_LOCALn instead of
|
||||||
LOG_USER, add '.n' to LEVEL, as in 3.7 (n=0..7).
|
LOG_USER, add '.n' to LEVEL, as in 3.7 (n=0..7).
|
||||||
.TP
|
.TP
|
||||||
.BI -L\ dir ,\ --lib= dir
|
.BI \-L\ dir ,\ \-\-lib= dir
|
||||||
Search for plugins in directory \fIdir\fR (default is ./PLUGINS/lib).
|
Search for plugins in directory \fIdir\fR (default is ./PLUGINS/lib).
|
||||||
There can be several \fB-L\fR options with different \fIdir\fR values.
|
There can be several \fB\-L\fR options with different \fIdir\fR values.
|
||||||
Each of them will apply to the \fB-P\fR options following it.
|
Each of them will apply to the \fB\-P\fR options following it.
|
||||||
.TP
|
.TP
|
||||||
.B -m, --mute
|
.B \-m, \-\-mute
|
||||||
Mute audio of the primary DVB device at startup.
|
Mute audio of the primary DVB device at startup.
|
||||||
.TP
|
.TP
|
||||||
.BI -p\ port ,\ --port= port
|
.BI \-p\ port ,\ \-\-port= port
|
||||||
Use \fIport\fR for SVDRP. A value of \fB0\fR turns off SVDRP.
|
Use \fIport\fR for SVDRP. A value of \fB0\fR turns off SVDRP.
|
||||||
The default SVDRP port is \fB2001\fR.
|
The default SVDRP port is \fB2001\fR.
|
||||||
You need to edit the file \fIsvdrphosts.conf\fR in order to enable
|
You need to edit the file \fIsvdrphosts.conf\fR in order to enable
|
||||||
access to the SVDRP port.
|
access to the SVDRP port.
|
||||||
.TP
|
.TP
|
||||||
.BI -P\ options ,\ --plugin= options
|
.BI \-P\ options ,\ \-\-plugin= options
|
||||||
Load a plugin, defined by the given \fIoptions\fR.
|
Load a plugin, defined by the given \fIoptions\fR.
|
||||||
The first word in \fIoptions\fR must be the name of an existing \fBvdr\fR
|
The first word in \fIoptions\fR must be the name of an existing \fBvdr\fR
|
||||||
plugin, optionally followed by a blank separated list of command line options
|
plugin, optionally followed by a blank separated list of command line options
|
||||||
for that plugin. If \fIoptions\fR contains any blanks, you need to enclose it
|
for that plugin. If \fIoptions\fR contains any blanks, you need to enclose it
|
||||||
in quotes, like for example
|
in quotes, like for example
|
||||||
|
|
||||||
\fBvdr -P "abc -a -b xyz"\fR
|
\fBvdr \-P "abc \-a \-b xyz"\fR
|
||||||
|
|
||||||
which would load a plugin named \fBabc\fR, giving it the command line options
|
which would load a plugin named \fBabc\fR, giving it the command line options
|
||||||
\fB-a\ -b\ xyz\fR. If you want to load all available plugins (without any
|
\fB\-a\ \-b\ xyz\fR. If you want to load all available plugins (without any
|
||||||
particular options) you can use
|
particular options) you can use
|
||||||
|
|
||||||
\fBvdr -P "*"\fR
|
\fBvdr \-P "*"\fR
|
||||||
|
|
||||||
(note the quotes around the asterisk to prevent wildcard expansion).
|
(note the quotes around the asterisk to prevent wildcard expansion).
|
||||||
.TP
|
.TP
|
||||||
.BI -r\ cmd ,\ --record= cmd
|
.BI \-r\ cmd ,\ \-\-record= cmd
|
||||||
Call \fIcmd\fR before and after a recording.
|
Call \fIcmd\fR before and after a recording.
|
||||||
.TP
|
.TP
|
||||||
.BI -s\ cmd ,\ --shutdown= cmd
|
.BI \-s\ cmd ,\ \-\-shutdown= cmd
|
||||||
Call \fIcmd\fR to shutdown the computer.
|
Call \fIcmd\fR to shutdown the computer.
|
||||||
.TP
|
.TP
|
||||||
.BI -t\ tty ,\ --terminal= tty
|
.BI \-t\ tty ,\ \-\-terminal= tty
|
||||||
Set the controlling terminal.
|
Set the controlling terminal.
|
||||||
.TP
|
.TP
|
||||||
.BI -v\ dir ,\ --video= dir
|
.BI \-v\ dir ,\ \-\-video= dir
|
||||||
Use \fIdir\fR as video directory.
|
Use \fIdir\fR as video directory.
|
||||||
The default is \fI/video\fR.
|
The default is \fI/video\fR.
|
||||||
.TP
|
.TP
|
||||||
.B -V, --version
|
.B \-V, \-\-version
|
||||||
Print version information and exit.
|
Print version information and exit.
|
||||||
.TP
|
.TP
|
||||||
.BI -w\ sec ,\ --watchdog= sec
|
.BI \-w\ sec ,\ \-\-watchdog= sec
|
||||||
Activate the watchdog timer with a timeout of \fIsec\fR seconds.
|
Activate the watchdog timer with a timeout of \fIsec\fR seconds.
|
||||||
A value of \fB0\fR (default) disables the watchdog.
|
A value of \fB0\fR (default) disables the watchdog.
|
||||||
.SH EXIT STATUS
|
.SH EXIT STATUS
|
||||||
@ -127,7 +127,7 @@ Successful program execution.
|
|||||||
.TP
|
.TP
|
||||||
.B 1
|
.B 1
|
||||||
An error has been detected which requires the DVB driver and \fBvdr\fR
|
An error has been detected which requires the DVB driver and \fBvdr\fR
|
||||||
to be re-loaded.
|
to be reloaded.
|
||||||
.TP
|
.TP
|
||||||
.B 2
|
.B 2
|
||||||
An non-recoverable error has been detected, \fBvdr\fR has given up.
|
An non-recoverable error has been detected, \fBvdr\fR has given up.
|
||||||
@ -186,9 +186,9 @@ be used to trigger an update of the list of recordings in the "Recordings" menu.
|
|||||||
Written by Klaus Schmidinger, with contributions from many others.
|
Written by Klaus Schmidinger, with contributions from many others.
|
||||||
See the file \fICONTRIBUTORS\fR in the \fBvdr\fR source distribution.
|
See the file \fICONTRIBUTORS\fR in the \fBvdr\fR source distribution.
|
||||||
.SH REPORTING BUGS
|
.SH REPORTING BUGS
|
||||||
Report bugs to <vdr-bugs@cadsoft.de>.
|
Report bugs to <vdr\-bugs@cadsoft.de>.
|
||||||
.SH COPYRIGHT
|
.SH COPYRIGHT
|
||||||
Copyright \(co 2003 Klaus Schmidinger.
|
Copyright \(co 2004 Klaus Schmidinger.
|
||||||
|
|
||||||
This is free software; see the source for copying conditions. There is NO
|
This is free software; see the source for copying conditions. There is NO
|
||||||
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
45
vdr.5
45
vdr.5
@ -8,9 +8,9 @@
|
|||||||
.\" License as specified in the file COPYING that comes with the
|
.\" License as specified in the file COPYING that comes with the
|
||||||
.\" vdr distribution.
|
.\" vdr distribution.
|
||||||
.\"
|
.\"
|
||||||
.\" $Id: vdr.5 1.29 2004/10/31 12:13:43 kls Exp $
|
.\" $Id: vdr.5 1.32 2005/01/09 13:16:40 kls Exp $
|
||||||
.\"
|
.\"
|
||||||
.TH vdr 5 "31 Oct 2004" "1.3.15" "Video Disk Recorder Files"
|
.TH vdr 5 "19 Dec 2004" "1.3.18" "Video Disk Recorder Files"
|
||||||
.SH NAME
|
.SH NAME
|
||||||
vdr file formats - the Video Disk Recorder Files
|
vdr file formats - the Video Disk Recorder Files
|
||||||
.SH DESCRIPTION
|
.SH DESCRIPTION
|
||||||
@ -89,7 +89,9 @@ l l.
|
|||||||
\fBG\fR@Guard interval (4, 8, 16, 32)
|
\fBG\fR@Guard interval (4, 8, 16, 32)
|
||||||
\fBH\fR@Horizontal polarization
|
\fBH\fR@Horizontal polarization
|
||||||
\fBI\fR@Inversion (0, 1)
|
\fBI\fR@Inversion (0, 1)
|
||||||
|
\fBL\fR@Left circular polarization
|
||||||
\fBM\fR@Modulation (0, 16, 32, 64, 128, 256)
|
\fBM\fR@Modulation (0, 16, 32, 64, 128, 256)
|
||||||
|
\fBR\fR@Right circular polarization
|
||||||
\fBT\fR@Transmission mode (2, 8)
|
\fBT\fR@Transmission mode (2, 8)
|
||||||
\fBV\fR@Vertical polarization
|
\fBV\fR@Vertical polarization
|
||||||
\fBY\fR@Hierarchy (0, 1, 2, 4)
|
\fBY\fR@Hierarchy (0, 1, 2, 4)
|
||||||
@ -174,12 +176,12 @@ NID, TID and SID are all equal).
|
|||||||
A particular channel can be uniquely identified by its \fBchannel\ ID\fR,
|
A particular channel can be uniquely identified by its \fBchannel\ ID\fR,
|
||||||
which is a string that looks like this:
|
which is a string that looks like this:
|
||||||
|
|
||||||
\fBS19.2E-1-1089-12003-0\fR
|
\fBS19.2E\-1\-1089\-12003\-0\fR
|
||||||
|
|
||||||
The components of this string are the \fBSource\fR (S19.2E), \fBNID\fR
|
The components of this string are the \fBSource\fR (S19.2E), \fBNID\fR
|
||||||
(1), \fBTID\fR (1089), \fBSID\fR (12003) and \fBRID\fR (0) as defined above.
|
(1), \fBTID\fR (1089), \fBSID\fR (12003) and \fBRID\fR (0) as defined above.
|
||||||
The last part can be omitted if it is \fB0\fR,
|
The last part can be omitted if it is \fB0\fR,
|
||||||
so the above example could also be written as S19.2E-1-1089-12003).
|
so the above example could also be written as S19.2E\-1\-1089\-12003).
|
||||||
.br
|
.br
|
||||||
The \fBchannel\ ID\fR is used in the \fItimers.conf\fR and \fIepg.data\fR
|
The \fBchannel\ ID\fR is used in the \fItimers.conf\fR and \fIepg.data\fR
|
||||||
files to properly identify the channels.
|
files to properly identify the channels.
|
||||||
@ -195,7 +197,7 @@ The file \fItimers.conf\fR contains the timer setup.
|
|||||||
Each line contains one timer definition, with individual fields
|
Each line contains one timer definition, with individual fields
|
||||||
separated by ':' characters. Example:
|
separated by ':' characters. Example:
|
||||||
|
|
||||||
\fB1:10:-T-----:2058:2150:50:5:Quarks & Co:\fR
|
\fB1:10:\-T\-\-\-\-\-:2058:2150:50:5:Quarks & Co:\fR
|
||||||
|
|
||||||
The fields in a timer definition have the following meaning (from left
|
The fields in a timer definition have the following meaning (from left
|
||||||
to right):
|
to right):
|
||||||
@ -234,21 +236,21 @@ timer shall record. This must be in the range \fB1...31\fR.
|
|||||||
|
|
||||||
In case of a `repeating' timer this is a string consisting of exactly seven
|
In case of a `repeating' timer this is a string consisting of exactly seven
|
||||||
characters, where each character position corresponds to one day of the week
|
characters, where each character position corresponds to one day of the week
|
||||||
(with Monday being the first day). The character '-' at a certain position
|
(with Monday being the first day). The character '\-' at a certain position
|
||||||
means that the timer shall not record on that day. Any other character will
|
means that the timer shall not record on that day. Any other character will
|
||||||
cause the timer to record on that day. Example:
|
cause the timer to record on that day. Example:
|
||||||
|
|
||||||
.B MTWTF--
|
.B MTWTF\-\-
|
||||||
|
|
||||||
will define a timer that records on Monday thru Friday and does not record
|
will define a timer that records on Monday thru Friday and does not record
|
||||||
on weekends. The same result could be achieved with \fBABCDE--\fR (this is
|
on weekends. The same result could be achieved with \fBABCDE\-\-\fR (this is
|
||||||
used to allow setting the days with language specific characters).
|
used to allow setting the days with language specific characters).
|
||||||
|
|
||||||
The day definition of a `repeating' timer may be followed by the date when that
|
The day definition of a `repeating' timer may be followed by the date when that
|
||||||
timer shall hit for the first time. The format for this is \fB@YYYY-MM-DD\fR,
|
timer shall hit for the first time. The format for this is \fB@YYYY\-MM\-DD\fR,
|
||||||
so a complete definition could look like this:
|
so a complete definition could look like this:
|
||||||
|
|
||||||
\fBMTWTF--@2002-02-18\fR
|
\fBMTWTF\-\-@2002\-02\-18\fR
|
||||||
|
|
||||||
which would implement a timer that records Moday thru Friday, and will hit
|
which would implement a timer that records Moday thru Friday, and will hit
|
||||||
for the first time on or after February 18, 2002.
|
for the first time on or after February 18, 2002.
|
||||||
@ -416,7 +418,7 @@ and can be one of \fIRed\fR, \fIGreen\fR, \fIYellow\fR, \fIBlue\fR or
|
|||||||
keys, which will be executed just as if they had been pressed in the given
|
keys, which will be executed just as if they had been pressed in the given
|
||||||
sequence. The optional \fB@plugin\fR can be used to automatically select
|
sequence. The optional \fB@plugin\fR can be used to automatically select
|
||||||
the given plugin from the main menu (provided that plugin has a main menu
|
the given plugin from the main menu (provided that plugin has a main menu
|
||||||
entry). \fBplugin\fR is the name of the plugin, exactly as given in the -P
|
entry). \fBplugin\fR is the name of the plugin, exactly as given in the \-P
|
||||||
option when starting VDR. There can be only one \fB@plugin\fR per key macro,
|
option when starting VDR. There can be only one \fB@plugin\fR per key macro,
|
||||||
and it implicitly adds an \fIOk\fR key to the macro definition (in order to
|
and it implicitly adds an \fIOk\fR key to the macro definition (in order to
|
||||||
actually select the plugins main menu entry), which counts against the total
|
actually select the plugins main menu entry), which counts against the total
|
||||||
@ -465,12 +467,12 @@ Check for new mail?: /usr/local/bin/checkmail 2>&1
|
|||||||
.br
|
.br
|
||||||
CPU status: /usr/local/bin/cpustatus 2>&1
|
CPU status: /usr/local/bin/cpustatus 2>&1
|
||||||
.br
|
.br
|
||||||
Disk space: df -h | grep '/video' | awk '{ print 100 - $5 "% free"; }'
|
Disk space: df \-h | grep '/video' | awk '{ print 100 \- $5 "% free"; }'
|
||||||
.br
|
.br
|
||||||
Calendar: date;echo;cal
|
Calendar: date;echo;cal
|
||||||
|
|
||||||
Note that the commands 'checkmail' and 'cpustatus' are only \fBexamples\fR!
|
Note that the commands 'checkmail' and 'cpustatus' are only \fBexamples\fR!
|
||||||
Don't send emails to the author asking where to find these ;-)
|
Don't send emails to the author asking where to find these ;\-)
|
||||||
.br
|
.br
|
||||||
The '?' at the end of the "Check for new mail?" entry will prompt the user
|
The '?' at the end of the "Check for new mail?" entry will prompt the user
|
||||||
whether this command shall really be executed.
|
whether this command shall really be executed.
|
||||||
@ -511,7 +513,7 @@ The file \fIsetup.conf\fR contains the basic configuration options for \fBvdr\fR
|
|||||||
Each line contains one option in the format "Name = Value".
|
Each line contains one option in the format "Name = Value".
|
||||||
See the MANUAL file for a description of the available options.
|
See the MANUAL file for a description of the available options.
|
||||||
.SS THEMES
|
.SS THEMES
|
||||||
The files \fIthemes/<skin>-<theme>.theme\fR in the config directory contain the
|
The files \fIthemes/<skin>\-<theme>.theme\fR in the config directory contain the
|
||||||
color theme definitions for the various skins. In the actual file names \fI<skin>\fR
|
color theme definitions for the various skins. In the actual file names \fI<skin>\fR
|
||||||
will be replaced by the name if the skin this theme belongs to, and \fI<theme>\fR
|
will be replaced by the name if the skin this theme belongs to, and \fI<theme>\fR
|
||||||
will be the name of this theme.
|
will be the name of this theme.
|
||||||
@ -545,7 +547,7 @@ you can provide language specific descriptions as
|
|||||||
|
|
||||||
\fBDescription.eng = Shades of blue\fR
|
\fBDescription.eng = Shades of blue\fR
|
||||||
.br
|
.br
|
||||||
\fBDescription.ger = Blautöne\fR
|
\fBDescription.ger = Blaut\(:one\fR
|
||||||
|
|
||||||
where the language code (as defined in VDR/i18n.c) is added to the keyword
|
where the language code (as defined in VDR/i18n.c) is added to the keyword
|
||||||
"Description", separated by a dot. You can enter as many language specific
|
"Description", separated by a dot. You can enter as many language specific
|
||||||
@ -613,6 +615,7 @@ l l.
|
|||||||
\fBT\fR@<title>
|
\fBT\fR@<title>
|
||||||
\fBS\fR@<short text>
|
\fBS\fR@<short text>
|
||||||
\fBD\fR@<description>
|
\fBD\fR@<description>
|
||||||
|
\fBX\fR@<stream> <type> <language> <descr>
|
||||||
\fBV\fR@<vps time>
|
\fBV\fR@<vps time>
|
||||||
\fBe\fR@
|
\fBe\fR@
|
||||||
\fBc\fR@
|
\fBc\fR@
|
||||||
@ -622,8 +625,10 @@ Lowercase characters mark the end of a sequence that was started by the
|
|||||||
corresponding uppercase character. The outer frame consists of a sequence
|
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
|
of one or more \fBC\fR...\fBc\fR (Channel) entries. Inside these any number of
|
||||||
\fBE\fR...\fBe\fR (Event) entries are allowed.
|
\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).
|
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
|
.TS
|
||||||
tab (@);
|
tab (@);
|
||||||
@ -636,6 +641,10 @@ l l.
|
|||||||
<title> @is the title of the event
|
<title> @is the title of the event
|
||||||
<short text> @is the short text of the event (typically the name of the episode etc.)
|
<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)
|
<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
|
<vps time> @is the Video Programming Service time of this event
|
||||||
.TE
|
.TE
|
||||||
|
|
||||||
@ -646,9 +655,9 @@ previous EPG scans.
|
|||||||
.SH AUTHOR
|
.SH AUTHOR
|
||||||
Written by Klaus Schmidinger.
|
Written by Klaus Schmidinger.
|
||||||
.SH REPORTING BUGS
|
.SH REPORTING BUGS
|
||||||
Report bugs to <vdr-bugs@cadsoft.de>.
|
Report bugs to <vdr\-bugs@cadsoft.de>.
|
||||||
.SH COPYRIGHT
|
.SH COPYRIGHT
|
||||||
Copyright \(co 2003 Klaus Schmidinger.
|
Copyright \(co 2004 Klaus Schmidinger.
|
||||||
|
|
||||||
This is free software; see the source for copying conditions. There is NO
|
This is free software; see the source for copying conditions. There is NO
|
||||||
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
37
vdr.c
37
vdr.c
@ -22,7 +22,7 @@
|
|||||||
*
|
*
|
||||||
* The project's page is at http://www.cadsoft.de/vdr
|
* The project's page is at http://www.cadsoft.de/vdr
|
||||||
*
|
*
|
||||||
* $Id: vdr.c 1.193 2004/11/06 10:30:30 kls Exp $
|
* $Id: vdr.c 1.198 2005/01/06 14:36:40 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <getopt.h>
|
#include <getopt.h>
|
||||||
@ -405,13 +405,16 @@ int main(int argc, char *argv[])
|
|||||||
// EPG data:
|
// EPG data:
|
||||||
|
|
||||||
if (EpgDataFileName) {
|
if (EpgDataFileName) {
|
||||||
if (DirectoryOk(EpgDataFileName))
|
const char *EpgDirectory = NULL;
|
||||||
EpgDataFileName = AddDirectory(EpgDataFileName, DEFAULTEPGDATAFILENAME);
|
if (DirectoryOk(EpgDataFileName)) {
|
||||||
|
EpgDirectory = EpgDataFileName;
|
||||||
|
EpgDataFileName = DEFAULTEPGDATAFILENAME;
|
||||||
|
}
|
||||||
else if (*EpgDataFileName != '/' && *EpgDataFileName != '.')
|
else if (*EpgDataFileName != '/' && *EpgDataFileName != '.')
|
||||||
EpgDataFileName = AddDirectory(VideoDirectory, EpgDataFileName);
|
EpgDirectory = VideoDirectory;
|
||||||
|
cSchedules::SetEpgDataFileName(AddDirectory(EpgDirectory, EpgDataFileName));
|
||||||
|
cSchedules::Read();
|
||||||
}
|
}
|
||||||
cSchedules::SetEpgDataFileName(EpgDataFileName);
|
|
||||||
cSchedules::Read();
|
|
||||||
|
|
||||||
// DVB interfaces:
|
// DVB interfaces:
|
||||||
|
|
||||||
@ -532,7 +535,7 @@ int main(int argc, char *argv[])
|
|||||||
static time_t lastTime = 0;
|
static time_t lastTime = 0;
|
||||||
if (time(NULL) - lastTime > MINCHANNELWAIT) {
|
if (time(NULL) - lastTime > MINCHANNELWAIT) {
|
||||||
cChannel *Channel = Channels.GetByNumber(cDevice::CurrentChannel());
|
cChannel *Channel = Channels.GetByNumber(cDevice::CurrentChannel());
|
||||||
if (Channel && (Channel->Vpid() || Channel->Apid1())) {
|
if (Channel && (Channel->Vpid() || Channel->Apid(0))) {
|
||||||
if (!Channels.SwitchTo(cDevice::CurrentChannel()) // try to switch to the original channel...
|
if (!Channels.SwitchTo(cDevice::CurrentChannel()) // try to switch to the original channel...
|
||||||
&& !(LastTimerChannel > 0 && Channels.SwitchTo(LastTimerChannel)) // ...or the one used by the last timer...
|
&& !(LastTimerChannel > 0 && Channels.SwitchTo(LastTimerChannel)) // ...or the one used by the last timer...
|
||||||
&& !cDevice::SwitchChannel(1) // ...or the next higher available one...
|
&& !cDevice::SwitchChannel(1) // ...or the next higher available one...
|
||||||
@ -675,7 +678,7 @@ int main(int argc, char *argv[])
|
|||||||
case kChanDn:
|
case kChanDn:
|
||||||
cDevice::SwitchChannel(NORMALKEY(key) == kChanUp ? 1 : -1);
|
cDevice::SwitchChannel(NORMALKEY(key) == kChanUp ? 1 : -1);
|
||||||
break;
|
break;
|
||||||
// Volume Control:
|
// Volume control:
|
||||||
case kVolUp|k_Repeat:
|
case kVolUp|k_Repeat:
|
||||||
case kVolUp:
|
case kVolUp:
|
||||||
case kVolDn|k_Repeat:
|
case kVolDn|k_Repeat:
|
||||||
@ -694,6 +697,20 @@ int main(int argc, char *argv[])
|
|||||||
cDisplayVolume::Process(key);
|
cDisplayVolume::Process(key);
|
||||||
key = kNone; // nobody else needs to see these keys
|
key = kNone; // nobody else needs to see these keys
|
||||||
break;
|
break;
|
||||||
|
// Audio track control:
|
||||||
|
case kAudio:
|
||||||
|
if (cControl::Control())
|
||||||
|
cControl::Control()->Hide();
|
||||||
|
if (Temp && !cDisplayTracks::IsOpen()) {
|
||||||
|
DELETENULL(Menu);
|
||||||
|
Temp = NULL;
|
||||||
|
}
|
||||||
|
if (!Menu && !cOsd::IsOpen())
|
||||||
|
Menu = Temp = cDisplayTracks::Create();
|
||||||
|
else
|
||||||
|
cDisplayTracks::Process(key);
|
||||||
|
key = kNone;
|
||||||
|
break;
|
||||||
// Pausing live video:
|
// Pausing live video:
|
||||||
case kPause:
|
case kPause:
|
||||||
if (!cControl::Control()) {
|
if (!cControl::Control()) {
|
||||||
@ -867,7 +884,7 @@ int main(int argc, char *argv[])
|
|||||||
if (!Next || Delta > Setup.MinEventTimeout * 60 || ForceShutdown) {
|
if (!Next || Delta > Setup.MinEventTimeout * 60 || ForceShutdown) {
|
||||||
ForceShutdown = false;
|
ForceShutdown = false;
|
||||||
if (timer)
|
if (timer)
|
||||||
dsyslog("next timer event at %s", ctime(&Next));
|
dsyslog("next timer event at %s", *TimeToString(Next));
|
||||||
if (WatchdogTimeout > 0)
|
if (WatchdogTimeout > 0)
|
||||||
signal(SIGALRM, SIG_IGN);
|
signal(SIGALRM, SIG_IGN);
|
||||||
if (Interface->Confirm(tr("Press any key to cancel shutdown"), UserShutdown ? 5 : SHUTDOWNWAIT, true)) {
|
if (Interface->Confirm(tr("Press any key to cancel shutdown"), UserShutdown ? 5 : SHUTDOWNWAIT, true)) {
|
||||||
@ -875,7 +892,7 @@ int main(int argc, char *argv[])
|
|||||||
const char *File = timer ? timer->File() : "";
|
const char *File = timer ? timer->File() : "";
|
||||||
Delta = Next - time(NULL); // compensates for Confirm() timeout
|
Delta = Next - time(NULL); // compensates for Confirm() timeout
|
||||||
char *cmd;
|
char *cmd;
|
||||||
asprintf(&cmd, "%s %ld %ld %d \"%s\" %d", Shutdown, Next, Delta, Channel, strescape(File, "\"$"), UserShutdown);
|
asprintf(&cmd, "%s %ld %ld %d \"%s\" %d", Shutdown, Next, Delta, Channel, *strescape(File, "\"$"), UserShutdown);
|
||||||
isyslog("executing '%s'", cmd);
|
isyslog("executing '%s'", cmd);
|
||||||
SystemExec(cmd);
|
SystemExec(cmd);
|
||||||
free(cmd);
|
free(cmd);
|
||||||
|
32
videodir.c
32
videodir.c
@ -4,7 +4,7 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* how to reach the author.
|
||||||
*
|
*
|
||||||
* $Id: videodir.c 1.10 2003/08/02 13:43:28 kls Exp $
|
* $Id: videodir.c 1.11 2004/12/26 11:52:12 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "videodir.h"
|
#include "videodir.h"
|
||||||
@ -197,27 +197,23 @@ int VideoDiskSpace(int *FreeMB, int *UsedMB)
|
|||||||
return (free + used) ? used * 100 / (free + used) : 0;
|
return (free + used) ? used * 100 / (free + used) : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *PrefixVideoFileName(const char *FileName, char Prefix)
|
cString PrefixVideoFileName(const char *FileName, char Prefix)
|
||||||
{
|
{
|
||||||
static char *PrefixedName = NULL;
|
char PrefixedName[strlen(FileName) + 2];
|
||||||
|
|
||||||
if (!PrefixedName || strlen(PrefixedName) <= strlen(FileName))
|
const char *p = FileName + strlen(FileName); // p points at the terminating 0
|
||||||
PrefixedName = (char *)realloc(PrefixedName, strlen(FileName) + 2);
|
int n = 2;
|
||||||
if (PrefixedName) {
|
while (p-- > FileName && n > 0) {
|
||||||
const char *p = FileName + strlen(FileName); // p points at the terminating 0
|
if (*p == '/') {
|
||||||
int n = 2;
|
if (--n == 0) {
|
||||||
while (p-- > FileName && n > 0) {
|
int l = p - FileName + 1;
|
||||||
if (*p == '/') {
|
strncpy(PrefixedName, FileName, l);
|
||||||
if (--n == 0) {
|
PrefixedName[l] = Prefix;
|
||||||
int l = p - FileName + 1;
|
strcpy(PrefixedName + l + 1, p + 1);
|
||||||
strncpy(PrefixedName, FileName, l);
|
return PrefixedName;
|
||||||
PrefixedName[l] = Prefix;
|
|
||||||
strcpy(PrefixedName + l + 1, p + 1);
|
|
||||||
return PrefixedName;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,13 +4,14 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* how to reach the author.
|
||||||
*
|
*
|
||||||
* $Id: videodir.h 1.4 2002/01/27 12:37:20 kls Exp $
|
* $Id: videodir.h 1.5 2004/12/26 11:52:56 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __VIDEODIR_H
|
#ifndef __VIDEODIR_H
|
||||||
#define __VIDEODIR_H
|
#define __VIDEODIR_H
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include "tools.h"
|
||||||
|
|
||||||
extern const char *VideoDirectory;
|
extern const char *VideoDirectory;
|
||||||
|
|
||||||
@ -20,7 +21,7 @@ bool RenameVideoFile(const char *OldName, const char *NewName);
|
|||||||
bool RemoveVideoFile(const char *FileName);
|
bool RemoveVideoFile(const char *FileName);
|
||||||
bool VideoFileSpaceAvailable(int SizeMB);
|
bool VideoFileSpaceAvailable(int SizeMB);
|
||||||
int VideoDiskSpace(int *FreeMB = NULL, int *UsedMB = NULL); // returns the used disk space in percent
|
int VideoDiskSpace(int *FreeMB = NULL, int *UsedMB = NULL); // returns the used disk space in percent
|
||||||
const char *PrefixVideoFileName(const char *FileName, char Prefix);
|
cString PrefixVideoFileName(const char *FileName, char Prefix);
|
||||||
void RemoveEmptyVideoDirectories(void);
|
void RemoveEmptyVideoDirectories(void);
|
||||||
|
|
||||||
#endif //__VIDEODIR_H
|
#endif //__VIDEODIR_H
|
||||||
|
Loading…
x
Reference in New Issue
Block a user