diff options
author | Klaus Schmidinger <kls (at) cadsoft (dot) de> | 2002-10-13 18:00:00 +0200 |
---|---|---|
committer | Klaus Schmidinger <kls (at) cadsoft (dot) de> | 2002-10-13 18:00:00 +0200 |
commit | cd7ccd64fd51b77b8b75b6e85ef6891b1917aa59 (patch) | |
tree | 7de627368728c02bdf195a3cbca5418175638434 | |
parent | 313e33539cd22fd571fc9a0f9f841173e9faebc4 (diff) | |
download | vdr-patch-lnbsharing-cd7ccd64fd51b77b8b75b6e85ef6891b1917aa59.tar.gz vdr-patch-lnbsharing-cd7ccd64fd51b77b8b75b6e85ef6891b1917aa59.tar.bz2 |
Version 1.1.13vdr-1.1.13
- Added cDevice::DeviceNumber() to get the number of a device, not counting any
gaps that might be in the index count.
- Fixed fetching the current/next information to handle cases where the duration
of an event is set wrongly and would last beyond the start time of the next
event.
- Adapted type names to the new HEAD version of the driver (which the previous
NEWSTRUCT branch has been merged into). Note that to use this driver version
you still need to add NEWSTRUCT=1 to the make call when building VDR. You
need a HEAD version of the LinuxDVB driver dated 2002-10-11 or later to compile
VDR with NEWSTRUCT=1.
- Fixed radio channels in channels.conf.cable (thanks to Robert Schiele and Uwe
Scheffler).
- Fixed switching the video format in the Setup/DVB menu (thanks to Uwe Scheffler
for reporting this one).
- Reactivated full handling of second audio PID (even in 'Transfer Mode').
- Fixed a crash when closing down with remote control plugins (thanks to Oliver
Endriss helping to debug this one).
- Commands in the file 'commands.conf' can now have a '?' at the end of their
title, which will result in a confirmation prompt before executing the
command.
- Changed a few leftover 'new char[...]' to MALLOC(char, ...).
- If a command executed from the "Commands" menu doesn't return any output, the
OSD will now be closed automatically.
- The SVDRP command PUTE now triggers an immediate write of the 'epg.data' file
(suggested by Gerhard Steiner).
- The new configuration file 'reccmds.conf' can be used to define commands that
shall be executed from the "Recordings" menu; see MANUAL and 'man vdr(5)' for
details (suggested by Gerhard Steiner).
-rw-r--r-- | CONTRIBUTORS | 13 | ||||
-rw-r--r-- | HISTORY | 33 | ||||
-rw-r--r-- | MANUAL | 38 | ||||
-rw-r--r-- | PLUGINS.html | 48 | ||||
-rw-r--r-- | channels.conf | 5 | ||||
-rw-r--r-- | channels.conf.cable | 110 | ||||
-rw-r--r-- | config.c | 26 | ||||
-rw-r--r-- | config.h | 9 | ||||
-rw-r--r-- | device.c | 45 | ||||
-rw-r--r-- | device.h | 42 | ||||
-rw-r--r-- | dvbdevice.c | 92 | ||||
-rw-r--r-- | dvbdevice.h | 17 | ||||
-rw-r--r-- | dvbplayer.c | 38 | ||||
-rw-r--r-- | eit.c | 92 | ||||
-rw-r--r-- | eit.h | 4 | ||||
-rw-r--r-- | i18n.c | 18 | ||||
-rw-r--r-- | menu.c | 178 | ||||
-rw-r--r-- | menu.h | 3 | ||||
-rw-r--r-- | osd.c | 6 | ||||
-rw-r--r-- | player.h | 23 | ||||
-rw-r--r-- | rcu.c | 4 | ||||
-rw-r--r-- | recorder.c | 4 | ||||
-rw-r--r-- | recording.c | 10 | ||||
-rw-r--r-- | remote.c | 5 | ||||
-rw-r--r-- | remux.c | 16 | ||||
-rw-r--r-- | remux.h | 5 | ||||
-rw-r--r-- | svdrp.c | 3 | ||||
-rw-r--r-- | transfer.c | 74 | ||||
-rw-r--r-- | transfer.h | 9 | ||||
-rw-r--r-- | vdr.5 | 27 | ||||
-rw-r--r-- | vdr.c | 6 |
31 files changed, 705 insertions, 298 deletions
diff --git a/CONTRIBUTORS b/CONTRIBUTORS index 6b8de52..33d89d7 100644 --- a/CONTRIBUTORS +++ b/CONTRIBUTORS @@ -186,9 +186,10 @@ Aaron Holtzman Wolfgang Henselmann-Weiss <Wolfgang_Henselmann@betaresearch.de> for fixing calculating the timeout value in cFile::FileReady() -Uwe Scheffler <UweScheffler@t-online.de> +Uwe Scheffler <linux_dvb@uni.de> for his help in keeping 'channels.conf.cable' and 'channels.conf.terr' up to date for helping to test new DVB-T handling + for reporting a bug in switching the video format in the Setup/DVB menu Matjaz Thaler <matjaz.thaler@guest.arnes.si> for improving AC3 decoding when replaying DVDs @@ -414,6 +415,7 @@ Oliver Endriss <o.endriss@gmx.de> for helping to test and debug the new channel source and DiSEqC handling for reporting a bug when pressing the "Blue" button in the main menu without having displayed it + for helping to debug a crash when closing down with remote control plugins Reinhard Walter Buchner <rw.buchner@freenet.de> for adding some satellites to 'sources.conf' @@ -423,3 +425,12 @@ Lauri Tischler <lauri.tischler@efore.fi> Andy Carter <fruit@ukgateway.net> for helping to test new DVB-T handling + +Robert Schiele <rschiele@uni-mannheim.de> + for his help in keeping 'channels.conf.cable' up to date + +Gerhard Steiner <steiner@mail.austria.com> + for suggesting that the SVDRP command PUTE shall trigger an immediate write of + the 'epg.data' file + for suggesting the new configuration file 'reccmds.conf' to define commands that + shall be executed from the "Recordings" menu @@ -1150,7 +1150,7 @@ Video Disk Recorder Revision History to their appropriate system locations and creates the /video directory if it doesn't exist yet. - Automatic hotkey assignment is now suppressed if the first entry in - commands.conf starts with a digit in the range '1'...'9', followed by a blank. + 'commands.conf' starts with a digit in the range '1'...'9', followed by a blank. - Fixed a bug in switching back the replay mode display in time shift mode (thanks to Achim Lange for reporting this one). - Fixed a bug in the "First day" timer parameter for timers that record over @@ -1579,3 +1579,34 @@ Video Disk Recorder Revision History - Updated channels.conf.terr and channels.conf.cable (thanks to Uwe Scheffler). - Fixed a bug when pressing the "Blue" button in the main menu without having displayed it (thanks to Oliver Endriss for reporting this one). + +2002-10-13: Version 1.1.13 + +- Added cDevice::DeviceNumber() to get the number of a device, not counting any + gaps that might be in the index count. +- Fixed fetching the current/next information to handle cases where the duration + of an event is set wrongly and would last beyond the start time of the next + event. +- Adapted type names to the new HEAD version of the driver (which the previous + NEWSTRUCT branch has been merged into). Note that to use this driver version + you still need to add NEWSTRUCT=1 to the make call when building VDR. You + need a HEAD version of the LinuxDVB driver dated 2002-10-11 or later to compile + VDR with NEWSTRUCT=1. +- Fixed radio channels in channels.conf.cable (thanks to Robert Schiele and Uwe + Scheffler). +- Fixed switching the video format in the Setup/DVB menu (thanks to Uwe Scheffler + for reporting this one). +- Reactivated full handling of second audio PID (even in 'Transfer Mode'). +- Fixed a crash when closing down with remote control plugins (thanks to Oliver + Endriss helping to debug this one). +- Commands in the file 'commands.conf' can now have a '?' at the end of their + title, which will result in a confirmation prompt before executing the + command. +- Changed a few leftover 'new char[...]' to MALLOC(char, ...). +- If a command executed from the "Commands" menu doesn't return any output, the + OSD will now be closed automatically. +- The SVDRP command PUTE now triggers an immediate write of the 'epg.data' file + (suggested by Gerhard Steiner). +- The new configuration file 'reccmds.conf' can be used to define commands that + shall be executed from the "Recordings" menu; see MANUAL and 'man vdr(5)' for + details (suggested by Gerhard Steiner). @@ -8,20 +8,20 @@ Video Disk Recorder User's Manual possible, several keys have different meanings in the various modes: - Key Normal VDR Channels Timers Edit/New Recordings Replay - - Up Ch up Crsr up Crsr up Crsr up Crsr up Crsr up Play - Down Ch down Crsr down Crsr down Crsr down Crsr down Crsr down Pause - Left Prev group - Page up Page up Decrement Page up Search back - Right Next group - Page down Page down Increment Page down Search forward - Ok Ch display Select Switch Edit Accept Play Progress disp. - Menu Menu on Menu off Menu off Menu off Menu off Menu off Menu on - Back - Menu off VDR menu VDR menu Discard VDR menu Recordings menu - Red - Record Edit Edit ABC/abc Play Jump - Green - Language New New Ins/Ovr Rewind Skip -60s - Yellow - - Delete Delete Delete Delete Skip +60s - Blue - Stop/Resume Mark On/Off(1) - Summary Stop - 0..9 Ch select - - - Numeric inp. - Editing + Key Normal VDR Channels Timers Edit/New Recordings Replay + + Up Ch up Crsr up Crsr up Crsr up Crsr up Crsr up Play + Down Ch down Crsr down Crsr down Crsr down Crsr down Crsr down Pause + Left Prev group - Page up Page up Decrement Page up Search back + Right Next group - Page down Page down Increment Page down Search forward + Ok Ch display Select Switch Edit Accept Play Progress disp. + Menu Menu on Menu off Menu off Menu off Menu off Menu off Menu on + Back - Menu off VDR menu VDR menu Discard VDR menu Recordings menu + Red - Record Edit Edit ABC/abc Play/Commands(2) Jump + Green - Language New New Ins/Ovr Rewind Skip -60s + Yellow - - Delete Delete Delete Delete Skip +60s + Blue - Stop/Resume Mark On/Off(1) - Summary Stop + 0..9 Ch select - - - Numeric inp. Exec cmd(2) Editing Power Shutdown Volume+ Volume up @@ -31,6 +31,7 @@ Video Disk Recorder User's Manual (1) The "On/Off" button in the "Timers" menu only works if sorting the timers has been enabled in the "Setup" menu. Otherwise the Blue button is used to "mark" a timer for moving. + (2) See "Processing Recordings" below. * Navigating through the On Screen Menus @@ -187,6 +188,15 @@ Video Disk Recorder User's Manual A previously stopped playback session can be resumed by pressing the "Blue" button in the "VDR" menu. +* Processing Recordings + + The configuration file 'reccmds.conf' can be used to define system commands + that can be applied to the recording that is currently highlighted in the + "Recordings" menu. The "Red" button in the "Recordings" menu opens the "Recording + commands" menu if there are commands defined in the file 'reccmds.conf'. Pressing + one of the keys '1'..'9' in the "Recordings" menu executes the corresponding + command from 'reccmds.conf' (see also "Executing system commands" below). + * Replay Control The following keys have the listed meaning in Replay mode: diff --git a/PLUGINS.html b/PLUGINS.html index 4c4592d..5cec857 100644 --- a/PLUGINS.html +++ b/PLUGINS.html @@ -21,18 +21,18 @@ VDR program and present itself to the user. The <i>inside</i> interface provides the plugin code access to VDR's internal data structures and allows it to hook itself into specific areas to perform special actions. <p> -<!--X1.1.8--><table width=100%><tr><td bgcolor=#0000AA> </td><td width=100%> -Important modifications introduced in version 1.1.8 are marked like this. -<!--X1.1.8--></td></tr></table> -<!--X1.1.9--><table width=100%><tr><td bgcolor=#00AA00> </td><td width=100%> +<!--X1.1.9--><table width=100%><tr><td bgcolor=#0000AA> </td><td width=100%> Important modifications introduced in version 1.1.9 are marked like this. <!--X1.1.9--></td></tr></table> -<!--X1.1.11--><table width=100%><tr><td bgcolor=#AA0000> </td><td width=100%> +<!--X1.1.11--><table width=100%><tr><td bgcolor=#00AA00> </td><td width=100%> Important modifications introduced in version 1.1.11 are marked like this. <!--X1.1.11--></td></tr></table> -<!--X1.1.12--><table width=100%><tr><td bgcolor=#FF0000> </td><td width=100%> +<!--X1.1.12--><table width=100%><tr><td bgcolor=#AA0000> </td><td width=100%> Important modifications introduced in version 1.1.12 are marked like this. <!--X1.1.12--></td></tr></table> +<!--X1.1.13--><table width=100%><tr><td bgcolor=#FF0000> </td><td width=100%> +Important modifications introduced in version 1.1.13 are marked like this. +<!--X1.1.13--></td></tr></table> <a name="Part I - The Outside Interface"><hr><center><h1>Part I - The Outside Interface</h1></center> @@ -964,6 +964,18 @@ bool DevicePoll(cPoller &Poller, int TimeoutMs = 0); </pre></td></tr></table><p> to determine whether the device is ready for further data. +<!--X1.1.13--><table width=100%><tr><td bgcolor=#FF0000> </td><td width=100%> +<p> +If the player can provide more than a single audio track, it can implement the +following functions to make them available: + +<p><table><tr><td bgcolor=#F0F0F0><pre><br> +virtual int NumAudioTracks(void) const; +virtual const char **GetAudioTracks(int *CurrentTrack = NULL); +virtual void SetAudioTrack(int Index); +</pre></td></tr></table><p> + +<!--X1.1.13--></td></tr></table> <p> TODO: PlayAudio()??? <p> @@ -1182,9 +1194,9 @@ the <tt>cDvbDevice</tt>, which is used to access the DVB PCI cards. If the new device can receive, it most likely needs to provide a way of selecting which channel it shall tune to: -<!--X1.1.9--><table width=100%><tr><td bgcolor=#00AA00> </td><td width=100%> +<!--X1.1.9--><table width=100%><tr><td bgcolor=#0000AA> </td><td width=100%> <p><table><tr><td bgcolor=#F0F0F0><pre><br> -<!--X1.1.12--><table width=100%><tr><td bgcolor=#FF0000> </td><td width=100%> +<!--X1.1.12--><table width=100%><tr><td bgcolor=#AA0000> </td><td width=100%> virtual bool ProvidesSource(int Source) const; <!--X1.1.12--></td></tr></table> virtual bool ProvidesChannel(const cChannel *Channel, int Priority = -1, bool *NeedsDetachReceivers = NULL); @@ -1195,6 +1207,20 @@ These functions will be called with the desired source or channel and shall retu this device can provide the requested source or channel and whether tuning to it was successful, repectively. <!--X1.1.9--></td></tr></table> +<!--X1.1.13--><table width=100%><tr><td bgcolor=#FF0000> </td><td width=100%> +<p> +<b>Audio selection</b> +<p> +If the device can provide more than a single audio track, it can implement the +following functions to make them available: + +<p><table><tr><td bgcolor=#F0F0F0><pre><br> +virtual int NumAudioTracksDevice(void) const; +virtual const char **GetAudioTracksDevice(int *CurrentTrack = NULL) const; +virtual void SetAudioTrackDevice(int Index); +</pre></td></tr></table><p> + +<!--X1.1.13--></td></tr></table> <p> <b>Recording</b> <p> @@ -1204,7 +1230,7 @@ A device that can be used for recording must implement the functions virtual bool SetPid(cPidHandle *Handle, int Type, bool On); virtual bool OpenDvr(void); virtual void CloseDvr(void); -<!--X1.1.9--><table width=100%><tr><td bgcolor=#00AA00> </td><td width=100%> +<!--X1.1.9--><table width=100%><tr><td bgcolor=#0000AA> </td><td width=100%> virtual bool GetTSPacket(uchar *&Data); <!--X1.1.9--></td></tr></table> </pre></td></tr></table><p> @@ -1250,7 +1276,6 @@ virtual void SetVideoFormat(bool VideoFormat16_9); virtual void SetVolumeDevice(int Volume); </pre></td></tr></table><p> -<!--X1.1.8--><table width=100%><tr><td bgcolor=#0000AA> </td><td width=100%> <p> <b>On Screen Display</b> <p> @@ -1266,7 +1291,6 @@ which must return a newly created object of a derived cOsdBase class that implements the functions necessary to display OSD information on your device. The caller of this function will delete the object as soon as it is no longer needed. -<!--X1.1.8--></td></tr></table> <p> <b>Initializing new devices</b> @@ -1291,7 +1315,7 @@ shut down (delete) all devices when the program terminates. It is therefore important that the devices are created on the heap, using the <tt>new</tt> operator! -<!--X1.1.11--><table width=100%><tr><td bgcolor=#AA0000> </td><td width=100%> +<!--X1.1.11--><table width=100%><tr><td bgcolor=#00AA00> </td><td width=100%> <hr><h2>Remote Control</h2> <center><i><b>The joy of zapping!</b></i></center><p> diff --git a/channels.conf b/channels.conf index 3d27214..9288c40 100644 --- a/channels.conf +++ b/channels.conf @@ -184,3 +184,8 @@ MTV German:12699:v:S19.2E:22000:3031:3032:0:0:28643 IFA-TV:10832:h:S19.2E:22000:132:133:32:0:7251 QVC Germany:12552:v:S19.2E:22000:165:166:0:0:12100 TANGOTV:10832:h:S19.2E:22000:61:62:0:0:61920 +:Sky +Sky One:0:h:S28.2E:0:160:80:0:5:106 +itv2:0:h:S28.2E:0:160:80:0:5:226 +sci-fi:0:h:S28.2E:0:160:80:0:5:130 +Paramount Comedy:0:h:S28.2E:0:160:80:0:5:127 diff --git a/channels.conf.cable b/channels.conf.cable index e96cd6a..65321fc 100644 --- a/channels.conf.cable +++ b/channels.conf.cable @@ -151,59 +151,59 @@ PREMIERE EROTIK 2:362:M64:C:6900:1535:1536:0:101:778 PREMIERE EROTIK 3:362:M64:C:6900:1791:1792:0:101:779 PREMIERE EROTIK 4:362:M64:C:6900:3583:3584:0:101:780 :Radio-Sender (FTV) -Fritz:426:M64:C:6900:8191:901:0:0:28209 -SPUTNIK:426:M64:C:6900:8191:1201:0:0:28212 -HR XXL:410:M64:C:6900:8191:3501:0:0:28125 -JUMP:426:M64:C:6900:8191:1001:0:0:28210 -MDR info:426:M64:C:6900:8191:1101:0:0:28211 -MDR KULTUR:426:M64:C:6900:8191:801:0:0:28208 -Radio 3:426:M64:C:6900:8191:701:0:0:28207 -RADIOmultikulti:426:M64:C:6900:8191:1301:0:0:28213 -SWR2:426:M64:C:6900:8191:1401:0:0:28214 -WDR 3:426:M64:C:6900:8191:1501:0:0:28215 -WDR Radio 5:426:M64:C:6900:8191:1601:0:0:28216 -Bayern 4 Klassik:410:M64:C:6900:8191:3001:0:0:28120 -B5 aktuell:410:M64:C:6900:8191:3101:0:0:28121 -NordwestRadio:410:M64:C:6900:8191:3801:0:0:28128 -Bayern 1:410:M64:C:6900:8191:3601:0:0:28126 -NDR Info:410:M64:C:6900:8191:3701:0:0:28127 -SR 1:410:M64:C:6900:8191:3901:0:0:28129 -hr-klassik:410:M64:C:6900:8191:3401:0:0:28124 -hr2:410:M64:C:6900:8191:3301:0:0:28123 -hr-chronos:410:M64:C:6900:8191:3201:0:0:28122 -DLF-Köln:394:M64:C:6900:8191:810:0:0:28013 -DLR-Berlin:394:M64:C:6900:8191:710:0:0:28012 -Österreich 1:394:M64:C:6900:8191:169:0:0:28017 -Radio GoldStar:354:M64:C:6900:8191:368:0:0:171 +Fritz:426:M64:C:6900:0:901:0:0:28209 +SPUTNIK:426:M64:C:6900:0:1201:0:0:28212 +HR XXL:410:M64:C:6900:0:3501:0:0:28125 +JUMP:426:M64:C:6900:0:1001:0:0:28210 +MDR info:426:M64:C:6900:0:1101:0:0:28211 +MDR KULTUR:426:M64:C:6900:0:801:0:0:28208 +Radio 3:426:M64:C:6900:0:701:0:0:28207 +RADIOmultikulti:426:M64:C:6900:0:1301:0:0:28213 +SWR2:426:M64:C:6900:0:1401:0:0:28214 +WDR 3:426:M64:C:6900:0:1501:0:0:28215 +WDR Radio 5:426:M64:C:6900:0:1601:0:0:28216 +Bayern 4 Klassik:410:M64:C:6900:0:3001:0:0:28120 +B5 aktuell:410:M64:C:6900:0:3101:0:0:28121 +NordwestRadio:410:M64:C:6900:0:3801:0:0:28128 +Bayern 1:410:M64:C:6900:0:3601:0:0:28126 +NDR Info:410:M64:C:6900:0:3701:0:0:28127 +SR 1:410:M64:C:6900:0:3901:0:0:28129 +hr-klassik:410:M64:C:6900:0:3401:0:0:28124 +hr2:410:M64:C:6900:0:3301:0:0:28123 +hr-chronos:410:M64:C:6900:0:3201:0:0:28122 +DLF-Köln:394:M64:C:6900:0:810:0:0:28013 +DLR-Berlin:394:M64:C:6900:0:710:0:0:28012 +Österreich 1:394:M64:C:6900:0:169:0:0:28017 +Radio GoldStar:354:M64:C:6900:0:368:0:0:171 :Radio-Sender (PPV) -ALTERNATIVE ROCK:370:M64:C:6900:8191:544:0:101:154 -DEUTSCHE HITS:370:M64:C:6900:8191:800:0:101:151 -HITLISTE:370:M64:C:6900:8191:784:0:101:150 -HIP HOP/R&B:370:M64:C:6900:8191:576:0:101:159 -DANCE:370:M64:C:6900:8191:304:0:101:165 -HARD ROCK:370:M64:C:6900:8191:816:0:101:152 -LOVE SONGS:370:M64:C:6900:8191:592:0:101:156 -FILM & MUSICAL:378:M64:C:6900:8191:592:0:101:145 -EASY LISTENING:378:M64:C:6900:8191:608:0:101:146 -JAZZ:378:M64:C:6900:8191:640:0:101:148 -KLASSIK POPULÄR:378:M64:C:6900:8191:624:0:101:147 -ORCHESTRALE WERKE:378:M64:C:6900:8191:560:0:101:158 -CLASSIC ROCK:370:M64:C:6900:8191:352:0:101:163 -VOLKSMUSIK:370:M64:C:6900:8191:400:0:101:157 -SCHLAGER:370:M64:C:6900:8191:384:0:101:162 -GOLD:370:M64:C:6900:8191:320:0:101:166 -OLD GOLD:362:M64:C:6900:8191:336:0:101:167 -SOUL CLASSICS:362:M64:C:6900:8191:352:0:101:153 -LATIN:362:M64:C:6900:8191:368:0:101:155 -NEW COUNTRY:362:M64:C:6900:8191:384:0:101:164 -COUNTRY:362:M64:C:6900:8191:656:0:101:149 -All Jazz:442:M64:C:6900:8191:535:0:101:53350 -Cristal New Age:442:M64:C:6900:8191:536:0:101:53351 -Movie Sounds:442:M64:C:6900:8191:537:0:101:53352 -Sinfonica:442:M64:C:6900:8191:538:0:101:53353 -Opernfestival:442:M64:C:6900:8191:539:0:101:53354 -Barock Fantasie:442:M64:C:6900:8191:540:0:101:53355 -Musica Camerata:442:M64:C:6900:8191:541:0:101:53356 -Musica Antica:442:M64:C:6900:8191:542:0:101:53357 -Adagio:442:M64:C:6900:8191:543:0:101:53358 -Jazz legends:442:M64:C:6900:8191:544:0:101:53359 +ALTERNATIVE ROCK:370:M64:C:6900:1:544:0:101:154 +DEUTSCHE HITS:370:M64:C:6900:1:800:0:101:151 +HITLISTE:370:M64:C:6900:1:784:0:101:150 +HIP HOP/R&B:370:M64:C:6900:1:576:0:101:159 +DANCE:370:M64:C:6900:1:304:0:101:165 +HARD ROCK:370:M64:C:6900:1:816:0:101:152 +LOVE SONGS:370:M64:C:6900:1:592:0:101:156 +FILM & MUSICAL:378:M64:C:6900:1:592:0:101:145 +EASY LISTENING:378:M64:C:6900:1:608:0:101:146 +JAZZ:378:M64:C:6900:1:640:0:101:148 +KLASSIK POPULÄR:378:M64:C:6900:1:624:0:101:147 +ORCHESTRALE WERKE:378:M64:C:6900:1:560:0:101:158 +CLASSIC ROCK:370:M64:C:6900:1:352:0:101:163 +VOLKSMUSIK:370:M64:C:6900:1:400:0:101:157 +SCHLAGER:370:M64:C:6900:1:384:0:101:162 +GOLD:370:M64:C:6900:1:320:0:101:166 +OLD GOLD:362:M64:C:6900:1:336:0:101:167 +SOUL CLASSICS:362:M64:C:6900:1:352:0:101:153 +LATIN:362:M64:C:6900:1:368:0:101:155 +NEW COUNTRY:362:M64:C:6900:1:384:0:101:164 +COUNTRY:362:M64:C:6900:1:656:0:101:149 +All Jazz:442:M64:C:6900:1:535:0:101:53350 +Cristal New Age:442:M64:C:6900:1:536:0:101:53351 +Movie Sounds:442:M64:C:6900:1:537:0:101:53352 +Sinfonica:442:M64:C:6900:1:538:0:101:53353 +Opernfestival:442:M64:C:6900:1:539:0:101:53354 +Barock Fantasie:442:M64:C:6900:1:540:0:101:53355 +Musica Camerata:442:M64:C:6900:1:541:0:101:53356 +Musica Antica:442:M64:C:6900:1:542:0:101:53357 +Adagio:442:M64:C:6900:1:543:0:101:53358 +Jazz legends:442:M64:C:6900:1:544:0:101:53359 @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: config.c 1.107 2002/10/03 10:06:55 kls Exp $ + * $Id: config.c 1.109 2002/10/13 10:03:49 kls Exp $ */ #include "config.h" @@ -360,6 +360,7 @@ char *cCommand::result = NULL; cCommand::cCommand(void) { title = command = NULL; + confirm = false; } cCommand::~cCommand() @@ -374,9 +375,14 @@ bool cCommand::Parse(const char *s) if (p) { int l = p - s; if (l > 0) { - title = new char[l + 1]; - strn0cpy(title, s, l + 1); + title = MALLOC(char, l + 1); + stripspace(strn0cpy(title, s, l + 1)); if (!isempty(title)) { + int l = strlen(title); + if (l > 1 && title[l - 1] == '?') { + confirm = true; + title[l - 1] = 0; + } command = stripspace(strdup(skipspace(p + 1))); return !isempty(command); } @@ -385,12 +391,16 @@ bool cCommand::Parse(const char *s) return false; } -const char *cCommand::Execute(void) +const char *cCommand::Execute(const char *Parameters) { - dsyslog("executing command '%s'", command); free(result); result = NULL; - FILE *p = popen(command, "r"); + char *cmdbuf = NULL; + if (Parameters) + asprintf(&cmdbuf, "%s %s", command, Parameters); + const char *cmd = cmdbuf ? cmdbuf : command; + dsyslog("executing command '%s'", cmd); + FILE *p = popen(cmd, "r"); if (p) { int l = 0; int c; @@ -404,7 +414,8 @@ const char *cCommand::Execute(void) pclose(p); } else - esyslog("ERROR: can't open pipe for command '%s'", command); + esyslog("ERROR: can't open pipe for command '%s'", cmd); + free(cmdbuf); return result; } @@ -463,6 +474,7 @@ bool cCaDefinition::Parse(const char *s) // -- cCommands -------------------------------------------------------------- cCommands Commands; +cCommands RecordingCommands; // -- cTimers ---------------------------------------------------------------- @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: config.h 1.131 2002/10/05 09:58:58 kls Exp $ + * $Id: config.h 1.134 2002/10/13 10:03:09 kls Exp $ */ #ifndef __CONFIG_H @@ -20,7 +20,7 @@ #include "eit.h" #include "tools.h" -#define VDRVERSION "1.1.12" +#define VDRVERSION "1.1.13" #define MAXPRIORITY 99 #define MAXLIFETIME 99 @@ -87,13 +87,15 @@ class cCommand : public cListObject { private: char *title; char *command; + bool confirm; static char *result; public: cCommand(void); virtual ~cCommand(); bool Parse(const char *s); const char *Title(void) { return title; } - const char *Execute(void); + bool Confirm(void) { return confirm; } + const char *Execute(const char *Parameters = NULL); }; typedef uint32_t in_addr_t; //XXX from /usr/include/netinet/in.h (apparently this is not defined on systems with glibc < 2.2) @@ -222,6 +224,7 @@ public: extern cTimers Timers; extern cCommands Commands; +extern cCommands RecordingCommands; extern cSVDRPhosts SVDRPhosts; extern cCaDefinitions CaDefinitions; @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: device.c 1.25 2002/10/06 13:49:38 kls Exp $ + * $Id: device.c 1.27 2002/10/12 13:24:37 kls Exp $ */ #include "device.h" @@ -87,6 +87,15 @@ int cDevice::NextCardIndex(int n) return nextCardIndex; } +int cDevice::DeviceNumber(void) const +{ + for (int i = 0; i < numDevices; i++) { + if (device[i] == this) + return i; + } + return -1; +} + void cDevice::MakePrimaryDevice(bool On) { } @@ -356,7 +365,7 @@ eSetChannelResult cDevice::SetChannel(const cChannel *Channel, bool LiveView) if (CaDevice) { 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()! - cControl::Launch(new cTransferControl(CaDevice, Channel->Vpid(), Channel->Apid1(), 0, 0, 0));//XXX+ + cControl::Launch(new cTransferControl(CaDevice, Channel->Vpid(), Channel->Apid1(), Channel->Apid2(), Channel->Dpid1(), Channel->Dpid2()));//XXX+ else Result = scrNoTransfer; } @@ -389,6 +398,20 @@ void cDevice::SetVolumeDevice(int Volume) { } +int cDevice::NumAudioTracksDevice(void) const +{ + return 0; +} + +const char **cDevice::GetAudioTracksDevice(int *CurrentTrack) const +{ + return NULL; +} + +void cDevice::SetAudioTrackDevice(int Index) +{ +} + bool cDevice::ToggleMute(void) { int OldVolume = volume; @@ -407,6 +430,24 @@ void cDevice::SetVolume(int Volume, bool Absolute) mute = false; } +int cDevice::NumAudioTracks(void) const +{ + return player ? player->NumAudioTracks() : NumAudioTracksDevice(); +} + +const char **cDevice::GetAudioTracks(int *CurrentTrack) const +{ + return player ? player->GetAudioTracks(CurrentTrack) : GetAudioTracksDevice(CurrentTrack); +} + +void cDevice::SetAudioTrack(int Index) +{ + if (player) + player->SetAudioTrack(Index); + else + SetAudioTrackDevice(Index); +} + bool cDevice::SetPlayMode(ePlayMode PlayMode) { return false; @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: device.h 1.21 2002/10/05 15:18:13 kls Exp $ + * $Id: device.h 1.23 2002/10/12 11:15:13 kls Exp $ */ #ifndef __DEVICE_H @@ -111,6 +111,8 @@ public: bool IsPrimaryDevice(void) const { return this == primaryDevice; } int CardIndex(void) const { return cardIndex; } // Returns the card index of this device (0 ... MAXDEVICES - 1). + int DeviceNumber(void) const; + // Returns number of this device (0 ... MAXDEVICES - 1). int ProvidesCa(int Ca) const; // Checks whether this device provides the given value in its // caCaps. Returns 0 if the value is not provided, 1 if only this @@ -217,7 +219,7 @@ public: // Sets the output video format to either 16:9 or 4:3 (only useful // if this device has an MPEG decoder). -// Volume facilities +// Audio facilities private: bool mute; @@ -225,6 +227,27 @@ private: protected: virtual void SetVolumeDevice(int Volume); // Sets the audio volume on this device (Volume = 0...255). + virtual int NumAudioTracksDevice(void) const; + // Returns the number of audio tracks that are currently available on this + // device. The default return value is 0, meaning that this device + // 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: bool IsMute(void) const { return mute; } bool ToggleMute(void); @@ -233,6 +256,21 @@ public: // Sets the volume to the given value, either absolutely or relative to // the current volume. 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 diff --git a/dvbdevice.c b/dvbdevice.c index eeaa7b0..a4a4308 100644 --- a/dvbdevice.c +++ b/dvbdevice.c @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: dvbdevice.c 1.22 2002/10/06 09:07:45 kls Exp $ + * $Id: dvbdevice.c 1.24 2002/10/12 11:15:45 kls Exp $ */ #include "dvbdevice.h" @@ -80,7 +80,11 @@ static int DvbOpen(const char *Name, int n, int Mode, bool ReportError = false) cDvbDevice::cDvbDevice(int n) { +#ifdef NEWSTRUCT + frontendType = fe_type_t(-1); // don't know how else to initialize this - there is no FE_UNKNOWN +#else frontendType = FrontendType(-1); // don't know how else to initialize this - there is no FE_UNKNOWN +#endif siProcessor = NULL; spuDecoder = NULL; playMode = pmNone; @@ -126,6 +130,8 @@ cDvbDevice::cDvbDevice(int n) else esyslog("ERROR: can't open DVB device %d", n); + aPid1 = aPid2 = 0; + source = -1; frequency = -1; diseqcCommands = NULL; @@ -306,12 +312,20 @@ void cDvbDevice::SetVideoFormat(bool VideoFormat16_9) } // ptAudio ptVideo ptTeletext ptDolby ptOther +#ifdef NEWSTRUCT +dmx_pes_type_t PesTypes[] = { DMX_PES_AUDIO, DMX_PES_VIDEO, DMX_PES_TELETEXT, DMX_PES_OTHER, DMX_PES_OTHER }; +#else dmxPesType_t PesTypes[] = { DMX_PES_AUDIO, DMX_PES_VIDEO, DMX_PES_TELETEXT, DMX_PES_OTHER, DMX_PES_OTHER }; +#endif bool cDvbDevice::SetPid(cPidHandle *Handle, int Type, bool On) { if (Handle->pid) { +#ifdef NEWSTRUCT + dmx_pes_filter_params pesFilterParams; +#else dmxPesFilterParams pesFilterParams; +#endif memset(&pesFilterParams, 0, sizeof(pesFilterParams)); if (On) { if (Handle->handle < 0) { @@ -322,7 +336,11 @@ bool cDvbDevice::SetPid(cPidHandle *Handle, int Type, bool On) pesFilterParams.pid = Handle->pid; pesFilterParams.input = DMX_IN_FRONTEND; pesFilterParams.output = (Type <= ptTeletext && Handle->used <= 1) ? DMX_OUT_DECODER : DMX_OUT_TS_TAP; +#ifdef NEWSTRUCT + pesFilterParams.pes_type= PesTypes[Type < ptOther ? Type : ptOther]; +#else pesFilterParams.pesType = PesTypes[Type < ptOther ? Type : ptOther]; +#endif pesFilterParams.flags = DMX_IMMEDIATE_START; if (ioctl(Handle->handle, DMX_SET_PES_FILTER, &pesFilterParams) < 0) { LOG_ERROR; @@ -335,7 +353,11 @@ bool cDvbDevice::SetPid(cPidHandle *Handle, int Type, bool On) pesFilterParams.pid = 0x1FFF; pesFilterParams.input = DMX_IN_FRONTEND; pesFilterParams.output = DMX_OUT_DECODER; +#ifdef NEWSTRUCT + pesFilterParams.pes_type= PesTypes[Type]; +#else pesFilterParams.pesType = PesTypes[Type]; +#endif pesFilterParams.flags = DMX_IMMEDIATE_START; CHECK(ioctl(Handle->handle, DMX_SET_PES_FILTER, &pesFilterParams)); close(Handle->handle); @@ -584,9 +606,9 @@ bool cDvbDevice::SetChannelDevice(const cChannel *Channel, bool LiveView) #ifdef NEWSTRUCT Frontend.frequency = frequency * 1000UL; - Frontend.inversion = SpectralInversion(Channel->Inversion()); + Frontend.inversion = fe_spectral_inversion_t(Channel->Inversion()); Frontend.u.qpsk.symbol_rate = Channel->Srate() * 1000UL; - Frontend.u.qpsk.fec_inner = CodeRate(Channel->CoderateH()); + Frontend.u.qpsk.fec_inner = fe_code_rate_t(Channel->CoderateH()); #else Frontend.Frequency = frequency * 1000UL; Frontend.Inversion = SpectralInversion(Channel->Inversion()); @@ -601,10 +623,10 @@ bool cDvbDevice::SetChannelDevice(const cChannel *Channel, bool LiveView) #ifdef NEWSTRUCT Frontend.frequency = Channel->Frequency() * 1000000UL; - Frontend.inversion = SpectralInversion(Channel->Inversion()); + Frontend.inversion = fe_spectral_inversion_t(Channel->Inversion()); Frontend.u.qam.symbol_rate = Channel->Srate() * 1000UL; - Frontend.u.qam.fec_inner = CodeRate(Channel->CoderateH()); - Frontend.u.qam.modulation = Modulation(Channel->Modulation()); + Frontend.u.qam.fec_inner = fe_code_rate_t(Channel->CoderateH()); + Frontend.u.qam.modulation = fe_modulation_t(Channel->Modulation()); #else Frontend.Frequency = Channel->Frequency() * 1000000UL; Frontend.Inversion = SpectralInversion(Channel->Inversion()); @@ -620,14 +642,14 @@ bool cDvbDevice::SetChannelDevice(const cChannel *Channel, bool LiveView) #ifdef NEWSTRUCT Frontend.frequency = Channel->Frequency() * 1000UL; - Frontend.inversion = SpectralInversion(Channel->Inversion()); - Frontend.u.ofdm.bandwidth = BandWidth(Channel->Bandwidth()); - Frontend.u.ofdm.code_rate_HP = CodeRate(Channel->CoderateH()); - Frontend.u.ofdm.code_rate_LP = CodeRate(Channel->CoderateL()); - Frontend.u.ofdm.constellation = Modulation(Channel->Modulation()); - Frontend.u.ofdm.transmission_mode = TransmitMode(Channel->Transmission()); - Frontend.u.ofdm.guard_interval = GuardInterval(Channel->Guard()); - Frontend.u.ofdm.hierarchy_information = Hierarchy(Channel->Hierarchy()); + Frontend.inversion = fe_spectral_inversion_t(Channel->Inversion()); + Frontend.u.ofdm.bandwidth = fe_bandwidth_t(Channel->Bandwidth()); + Frontend.u.ofdm.code_rate_HP = fe_code_rate_t(Channel->CoderateH()); + Frontend.u.ofdm.code_rate_LP = fe_code_rate_t(Channel->CoderateL()); + Frontend.u.ofdm.constellation = fe_modulation_t(Channel->Modulation()); + Frontend.u.ofdm.transmission_mode = fe_transmit_mode_t(Channel->Transmission()); + Frontend.u.ofdm.guard_interval = fe_guard_interval_t(Channel->Guard()); + Frontend.u.ofdm.hierarchy_information = fe_hierarchy_t(Channel->Hierarchy()); #else Frontend.Frequency = Channel->Frequency() * 1000UL; Frontend.Inversion = SpectralInversion(Channel->Inversion()); @@ -663,7 +685,7 @@ bool cDvbDevice::SetChannelDevice(const cChannel *Channel, bool LiveView) // Wait for channel lock: #ifdef NEWSTRUCT - FrontendStatus status = FrontendStatus(0); + fe_status_t status = fe_status_t(0); for (int i = 0; i < 100; i++) { CHECK(ioctl(fd_frontend, FE_READ_STATUS, &status)); if (status & FE_HAS_LOCK) @@ -702,6 +724,8 @@ bool cDvbDevice::SetChannelDevice(const cChannel *Channel, bool LiveView) // PID settings: if (TurnOnLivePIDs) { + aPid1 = Channel->Apid1(); + aPid2 = Channel->Apid2(); if (!(AddPid(Channel->Apid1(), ptAudio) && AddPid(Channel->Vpid(), ptVideo))) {//XXX+ dolby dpid1!!! (if audio plugins are attached) esyslog("ERROR: failed to set PIDs for channel %d on device %d", Channel->Number(), CardIndex() + 1); return false; @@ -726,12 +750,46 @@ bool cDvbDevice::SetChannelDevice(const cChannel *Channel, bool LiveView) void cDvbDevice::SetVolumeDevice(int Volume) { if (HasDecoder()) { +#ifdef NEWSTRUCT + audio_mixer_t am; +#else audioMixer_t am; +#endif am.volume_left = am.volume_right = Volume; CHECK(ioctl(fd_audio, AUDIO_SET_MIXER, &am)); } } +int cDvbDevice::NumAudioTracksDevice(void) const +{ + int n = 0; + if (aPid1) + n++; + if (aPid2 && aPid1 != aPid2) + n++; + return n; +} + +const char **cDvbDevice::GetAudioTracksDevice(int *CurrentTrack) const +{ + if (NumAudioTracks()) { + 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 NumAudioTracks() > 1 ? audioTracks2 : audioTracks1; + } + return NULL; +} + +void cDvbDevice::SetAudioTrackDevice(int Index) +{ + if (0 <= Index && Index < NumAudioTracks()) { + DelPid(pidHandles[ptAudio].pid); + AddPid(Index ? aPid2 : aPid1, ptAudio); + } +} + bool cDvbDevice::SetPlayMode(ePlayMode PlayMode) { if (PlayMode != pmExtern_THIS_SHOULD_BE_AVOIDED && fd_video < 0 && fd_audio < 0) { @@ -916,7 +974,11 @@ bool cDvbDevice::GetTSPacket(uchar *&Data) return true; } else if (FATALERRNO) { +#ifdef NEWSTRUCT + if (errno == EOVERFLOW) +#else if (errno == EBUFFEROVERFLOW) // this error code is not defined in the library +#endif esyslog("ERROR: DVB driver buffer overflow on device %d", CardIndex() + 1); else { LOG_ERROR; diff --git a/dvbdevice.h b/dvbdevice.h index df7aa03..b5484dc 100644 --- a/dvbdevice.h +++ b/dvbdevice.h @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: dvbdevice.h 1.12 2002/10/06 08:57:24 kls Exp $ + * $Id: dvbdevice.h 1.14 2002/10/12 11:15:39 kls Exp $ */ #ifndef __DVBDEVICE_H @@ -13,11 +13,6 @@ #ifdef NEWSTRUCT #include <linux/dvb/frontend.h> #else -#include <stdlib.h> // FIXME: this is apparently necessary for the ost/... header files - // FIXME: shouldn't every header file include ALL the other header - // FIXME: files it depends on? The sequence in which header files - // FIXME: are included here should not matter - and it should NOT - // FIXME: be necessary to include <stdlib.h> here! #include <ost/frontend.h> #endif #include "device.h" @@ -36,10 +31,11 @@ public: // Initializes the DVB devices. // Must be called before accessing any DVB functions. private: - FrontendType frontendType; #ifdef NEWSTRUCT + fe_type_t frontendType; int fd_osd, fd_frontend, fd_audio, fd_video, fd_dvr; #else + FrontendType frontendType; int fd_osd, fd_frontend, fd_sec, fd_audio, fd_video, fd_dvr; #endif int OsdDeviceHandle(void) const { return fd_osd; } @@ -86,10 +82,15 @@ public: public: virtual void SetVideoFormat(bool VideoFormat16_9); -// Volume facilities +// Audio facilities +private: + int aPid1, aPid2; protected: virtual void SetVolumeDevice(int Volume); + virtual int NumAudioTracksDevice(void) const; + virtual const char **GetAudioTracksDevice(int *CurrentTrack = NULL) const; + virtual void SetAudioTrackDevice(int Index); // EIT facilities diff --git a/dvbplayer.c b/dvbplayer.c index 7edadfb..927fde4 100644 --- a/dvbplayer.c +++ b/dvbplayer.c @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: dvbplayer.c 1.13 2002/09/15 13:33:31 kls Exp $ + * $Id: dvbplayer.c 1.14 2002/10/12 12:29:31 kls Exp $ */ #include "dvbplayer.h" @@ -96,6 +96,8 @@ private: ePlayDirs playDir; int trickSpeed; int readIndex, writeIndex; + bool canToggleAudioTrack; + uchar audioTrack; cFrame *readFrame; const cFrame *playFrame; void TrickSpeed(int Increment); @@ -120,6 +122,9 @@ public: void Goto(int Position, bool Still = false); virtual bool GetIndex(int &Current, int &Total, bool SnapToIFrame = false); 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? @@ -139,6 +144,8 @@ cDvbPlayer::cDvbPlayer(const char *FileName) playMode = pmPlay; playDir = pdForward; trickSpeed = NORMAL_SPEED; + canToggleAudioTrack = false; + audioTrack = 0xC0; readIndex = writeIndex = -1; readFrame = NULL; playFrame = NULL; @@ -216,7 +223,7 @@ void cDvbPlayer::StripAudioPackets(uchar *b, int Length, uchar Except) // continue with deleting the data - otherwise it disturbs DVB replay case 0xC0 ... 0xC1: // audio if (c == 0xC1) - ;//XXX+ canToggleAudioTrack = true; + canToggleAudioTrack = true; if (!Except || c != Except) { int n = l; for (int j = i; j < Length && n--; j++) @@ -353,7 +360,7 @@ void cDvbPlayer::Action(void) continue; } r = ReadFrame(replayFile, b, Length, sizeof(b)); - StripAudioPackets(b, r, 0xC0); //XXX+ audioTrack + StripAudioPackets(b, r, audioTrack); } else // allows replay even if the index file is missing r = read(replayFile, b, sizeof(b)); @@ -623,6 +630,31 @@ bool cDvbPlayer::GetReplayMode(bool &Play, bool &Forward, int &Speed) return true; } +int cDvbPlayer::NumAudioTracks(void) const +{ + return canToggleAudioTrack ? 2 : 1; +} + +const char **cDvbPlayer::GetAudioTracks(int *CurrentTrack = NULL) 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(const char *FileName) @@ -16,7 +16,7 @@ * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * - * $Id: eit.c 1.54 2002/10/06 10:31:38 kls Exp $ + * $Id: eit.c 1.57 2002/10/13 09:29:05 kls Exp $ ***************************************************************************/ #include "eit.h" @@ -629,50 +629,26 @@ cEventInfo *cSchedule::AddEvent(cEventInfo *EventInfo) return EventInfo; } -/** */ -const cEventInfo * cSchedule::GetPresentEvent() const +const cEventInfo *cSchedule::GetPresentEvent(void) const { - // checking temporal sanity of present event (kls 2000-11-01) - time_t now = time(NULL); -//XXX if (pPresent && !(pPresent->GetTime() <= now && now <= pPresent->GetTime() + pPresent->GetDuration())) - { - cEventInfo *pe = Events.First(); - while (pe != NULL) - { - if (pe->GetTime() <= now && now <= pe->GetTime() + pe->GetDuration()) - return pe; - pe = Events.Next(pe); - } - } - return NULL;//XXX - return pPresent; + return GetEventAround(time(NULL)); } -/** */ -const cEventInfo * cSchedule::GetFollowingEvent() const + +const cEventInfo *cSchedule::GetFollowingEvent(void) const { - // checking temporal sanity of following event (kls 2000-11-01) - time_t now = time(NULL); - const cEventInfo *pr = GetPresentEvent(); // must have it verified! -if (pr)//XXX if (pFollowing && !(pr && pr->GetTime() + pr->GetDuration() <= pFollowing->GetTime())) - { - int minDt = INT_MAX; - cEventInfo *pe = Events.First(), *pf = NULL; - while (pe != NULL) - { - int dt = pe->GetTime() - now; - if (dt > 0 && dt < minDt) - { - minDt = dt; - pf = pe; + const cEventInfo *pe = NULL; + time_t now = time(NULL); + time_t delta = INT_MAX; + for (cEventInfo *p = Events.First(); p; p = Events.Next(p)) { + time_t dt = p->GetTime() - now; + if (dt > 0 && dt < delta) { + delta = dt; + pe = p; } - pe = Events.Next(pe); } - return pf; - } - return NULL;//XXX - return pFollowing; + return pe; } -/** */ + void cSchedule::SetServiceID(unsigned short servid) { uServiceID = servid; @@ -701,21 +677,21 @@ const cEventInfo * cSchedule::GetEvent(unsigned short uEventID, time_t tTime) co return pt; } -/** */ -const cEventInfo * cSchedule::GetEventAround(time_t tTime) const -{ - cEventInfo *pe = Events.First(); - while (pe != NULL) - { - if (pe->GetTime() <= tTime && tTime <= pe->GetTime() + pe->GetDuration()) - return pe; - pe = Events.Next(pe); - } - - return NULL; +const cEventInfo *cSchedule::GetEventAround(time_t Time) const +{ + const cEventInfo *pe = NULL; + time_t delta = INT_MAX; + for (cEventInfo *p = Events.First(); p; p = Events.Next(p)) { + time_t dt = Time - p->GetTime(); + if (dt >= 0 && dt < delta && p->GetTime() + p->GetDuration() >= Time) { + delta = dt; + pe = p; + } + } + return pe; } -/** */ + bool cSchedule::SetPresentEvent(cEventInfo *pEvent) { if (pPresent != NULL) @@ -1007,6 +983,7 @@ int cSIProcessor::numSIProcessors = 0; cSchedules *cSIProcessor::schedules = NULL; cMutex cSIProcessor::schedulesMutex; const char *cSIProcessor::epgDataFileName = EPGDATAFILENAME; +time_t cSIProcessor::lastDump = time(NULL); /** */ cSIProcessor::cSIProcessor(const char *FileName) @@ -1107,7 +1084,6 @@ void cSIProcessor::Action() dsyslog("EIT processing thread started (pid=%d)%s", getpid(), masterSIProcessor ? " - master" : ""); time_t lastCleanup = time(NULL); - time_t lastDump = time(NULL); active = true; @@ -1220,7 +1196,11 @@ void cSIProcessor::Action() table identifer tid */ bool cSIProcessor::AddFilter(u_char pid, u_char tid) { +#ifdef NEWSTRUCT + dmx_sct_filter_params sctFilterParams; +#else dmxSctFilterParams sctFilterParams; +#endif memset(&sctFilterParams, 0, sizeof(sctFilterParams)); sctFilterParams.pid = pid; sctFilterParams.timeout = 0; @@ -1287,3 +1267,9 @@ bool cSIProcessor::SetCurrentServiceID(unsigned short servid) cMutexLock MutexLock(&schedulesMutex); return schedules ? schedules->SetCurrentServiceID(servid) : false; } + +void cSIProcessor::TriggerDump(void) +{ + cMutexLock MutexLock(&schedulesMutex); + lastDump = 0; +} @@ -16,7 +16,7 @@ * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * - * $Id: eit.h 1.18 2002/08/25 10:38:34 kls Exp $ + * $Id: eit.h 1.19 2002/10/13 09:28:06 kls Exp $ ***************************************************************************/ #ifndef __EIT_H @@ -138,6 +138,7 @@ private: static cSchedules *schedules; static cMutex schedulesMutex; static const char *epgDataFileName; + static time_t lastDump; bool masterSIProcessor; int currentTransponder; SIP_FILTER *filters; @@ -160,6 +161,7 @@ public: void SetStatus(bool On); void SetCurrentTransponder(int CurrentTransponder); static bool SetCurrentServiceID(unsigned short servid); + static void TriggerDump(void); }; #endif @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: i18n.c 1.95 2002/10/06 11:31:18 kls Exp $ + * $Id: i18n.c 1.96 2002/10/13 11:03:39 kls Exp $ * * Translations provided by: * @@ -199,6 +199,22 @@ const tI18nPhrase Phrases[] = { "Comenzi", "Parancsok", }, + { "Recording commands", + "Befehle für Aufzeichnungen", + "",// TODO + "",// TODO + "",// TODO + "",// TODO + "",// TODO + "",// TODO + "",// TODO + "",// TODO + "",// TODO + "",// TODO + "",// TODO + "",// TODO + "",// TODO + }, { "Edit channel", "Kanal editieren", "Uredi kanal", @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: menu.c 1.212 2002/10/06 14:08:44 kls Exp $ + * $Id: menu.c 1.217 2002/10/13 12:10:54 kls Exp $ */ #include "menu.h" @@ -1431,6 +1431,77 @@ eOSState cMenuSchedule::ProcessKey(eKeys Key) return state; } +// --- cMenuCommands --------------------------------------------------------- + +class cMenuCommands : public cOsdMenu { +private: + cCommands *commands; + char *parameters; + eOSState Execute(void); +public: + cMenuCommands(const char *Title, cCommands *Commands, const char *Parameters = NULL); + virtual ~cMenuCommands(); + virtual eOSState ProcessKey(eKeys Key); + }; + +cMenuCommands::cMenuCommands(const char *Title, cCommands *Commands, const char *Parameters) +:cOsdMenu(Title) +{ + SetHasHotkeys(); + commands = Commands; + parameters = Parameters ? strdup(Parameters) : NULL; + int i = 0; + cCommand *command; + + while ((command = commands->Get(i)) != NULL) { + Add(new cOsdItem(hk(command->Title()))); + i++; + } +} + +cMenuCommands::~cMenuCommands() +{ + free(parameters); +} + +eOSState cMenuCommands::Execute(void) +{ + cCommand *command = commands->Get(Current()); + if (command) { + char *buffer = NULL; + bool confirmed = true; + if (command->Confirm()) { + asprintf(&buffer, "%s?", command->Title()); + confirmed = Interface->Confirm(buffer); + free(buffer); + } + if (confirmed) { + asprintf(&buffer, "%s...", command->Title()); + Interface->Status(buffer); + Interface->Flush(); + free(buffer); + const char *Result = command->Execute(parameters); + if (Result) + return AddSubMenu(new cMenuText(command->Title(), Result, fontFix)); + return osEnd; + } + } + return osContinue; +} + +eOSState cMenuCommands::ProcessKey(eKeys Key) +{ + eOSState state = cOsdMenu::ProcessKey(Key); + + if (state == osUnknown) { + switch (Key) { + case kOk: return Execute(); + default: break; + } + } + return state; +} + // --- cMenuRecordingItem ---------------------------------------------------- class cMenuRecordingItem : public cOsdItem { @@ -1545,7 +1616,7 @@ void cMenuRecordings::SetHelpKeys(void) case 0: SetHelp(NULL); break; case 1: SetHelp(tr("Open")); break; case 2: - case 3: SetHelp(tr("Play"), tr("Rewind"), tr("Delete"), NewHelpKeys == 3 ? tr("Summary") : NULL); + case 3: SetHelp(RecordingCommands.Count() ? tr("Commands") : tr("Play"), tr("Rewind"), tr("Delete"), NewHelpKeys == 3 ? tr("Summary") : NULL); } helpKeys = NewHelpKeys; } @@ -1595,6 +1666,8 @@ eOSState cMenuRecordings::Play(void) eOSState cMenuRecordings::Rewind(void) { + if (HasSubMenu() || Count() == 0) + return osContinue; cMenuRecordingItem *ri = (cMenuRecordingItem *)Get(Current()); if (ri && !ri->IsDirectory()) { cDevice::PrimaryDevice()->StopReplay(); // must do this first to be able to rewind the currently replayed recording @@ -1607,6 +1680,8 @@ eOSState cMenuRecordings::Rewind(void) eOSState cMenuRecordings::Delete(void) { + if (HasSubMenu() || Count() == 0) + return osContinue; cMenuRecordingItem *ri = (cMenuRecordingItem *)Get(Current()); if (ri && !ri->IsDirectory()) { if (Interface->Confirm(tr("Delete recording?"))) { @@ -1654,6 +1729,27 @@ eOSState cMenuRecordings::Summary(void) return osContinue; } +eOSState cMenuRecordings::Commands(eKeys Key) +{ + if (HasSubMenu() || Count() == 0) + return osContinue; + cMenuRecordingItem *ri = (cMenuRecordingItem *)Get(Current()); + if (ri && !ri->IsDirectory()) { + cRecording *recording = GetRecording(ri); + if (recording) { + char *parameter = NULL; + asprintf(¶meter, "'%s'", recording->FileName()); + cMenuCommands *menu; + eOSState state = AddSubMenu(menu = new cMenuCommands(tr("Recording commands"), &RecordingCommands, parameter)); + free(parameter); + if (Key != kNone) + state = menu->ProcessKey(Key); + return state; + } + } + return osContinue; +} + eOSState cMenuRecordings::ProcessKey(eKeys Key) { bool HadSubMenu = HasSubMenu(); @@ -1661,11 +1757,12 @@ eOSState cMenuRecordings::ProcessKey(eKeys Key) if (state == osUnknown) { switch (Key) { - case kOk: - case kRed: return Play(); + case kOk: return Play(); + case kRed: return (helpKeys > 1 && RecordingCommands.Count()) ? Commands() : Play(); case kGreen: return Rewind(); case kYellow: return Delete(); case kBlue: return Summary(); + case k1...k9: return Commands(Key); default: break; } } @@ -1776,13 +1873,14 @@ cMenuSetupDVB::cMenuSetupDVB(void) eOSState cMenuSetupDVB::ProcessKey(eKeys Key) { int oldPrimaryDVB = Setup.PrimaryDVB; + bool oldVideoFormat = Setup.VideoFormat; eOSState state = cMenuSetupBase::ProcessKey(Key); if (state == osBack && Key == kOk) { - if (Setup.PrimaryDVB != oldPrimaryDVB) { + if (Setup.PrimaryDVB != oldPrimaryDVB) state = osSwitchDvb; + if (Setup.VideoFormat != oldVideoFormat) cDevice::PrimaryDevice()->SetVideoFormat(Setup.VideoFormat); - } } return state; } @@ -2050,58 +2148,6 @@ eOSState cMenuSetup::ProcessKey(eKeys Key) return state; } -// --- cMenuCommands --------------------------------------------------------- - -class cMenuCommands : public cOsdMenu { -private: - eOSState Execute(void); -public: - cMenuCommands(void); - virtual eOSState ProcessKey(eKeys Key); - }; - -cMenuCommands::cMenuCommands(void) -:cOsdMenu(tr("Commands")) -{ - SetHasHotkeys(); - int i = 0; - cCommand *command; - - while ((command = Commands.Get(i)) != NULL) { - Add(new cOsdItem(hk(command->Title()))); - i++; - } -} - -eOSState cMenuCommands::Execute(void) -{ - cCommand *command = Commands.Get(Current()); - if (command) { - char *buffer = NULL; - asprintf(&buffer, "%s...", command->Title()); - Interface->Status(buffer); - Interface->Flush(); - free(buffer); - const char *Result = command->Execute(); - if (Result) - return AddSubMenu(new cMenuText(command->Title(), Result, fontFix)); - } - return osContinue; -} - -eOSState cMenuCommands::ProcessKey(eKeys Key) -{ - eOSState state = cOsdMenu::ProcessKey(Key); - - if (state == osUnknown) { - switch (Key) { - case kOk: return Execute(); - default: break; - } - } - return state; -} - // --- cMenuPluginItem ------------------------------------------------------- class cMenuPluginItem : public cOsdItem { @@ -2211,7 +2257,7 @@ void cMenuMain::Set(void) // Color buttons: - SetHelp(tr("Record"), /*XXX+ cDevice::PrimaryDevice()->CanToggleAudioTrack() ? tr("Language") :XXX*/ NULL, NULL, replaying ? tr("Button$Stop") : cReplayControl::LastReplayed() ? tr("Resume") : NULL); + SetHelp(tr("Record"), cDevice::PrimaryDevice()->NumAudioTracks() > 1 ? tr("Language") : NULL, NULL, replaying ? tr("Button$Stop") : cReplayControl::LastReplayed() ? tr("Resume") : NULL); Display(); lastActivity = time(NULL); } @@ -2227,7 +2273,7 @@ eOSState cMenuMain::ProcessKey(eKeys Key) case osTimers: return AddSubMenu(new cMenuTimers); case osRecordings: return AddSubMenu(new cMenuRecordings); case osSetup: return AddSubMenu(new cMenuSetup); - case osCommands: return AddSubMenu(new cMenuCommands); + case osCommands: return AddSubMenu(new cMenuCommands(tr("Commands"), &Commands)); case osStopRecord: if (Interface->Confirm(tr("Stop recording?"))) { cOsdItem *item = Get(Current()); if (item) { @@ -2263,13 +2309,17 @@ eOSState cMenuMain::ProcessKey(eKeys Key) state = osRecord; break; case kGreen: if (!HasSubMenu()) { - /*XXX+ - if (cDevice::PrimaryDevice()->CanToggleAudioTrack()) { + int CurrentAudioTrack = -1; + const char **AudioTracks = cDevice::PrimaryDevice()->GetAudioTracks(&CurrentAudioTrack); + if (AudioTracks) { + const char **at = &AudioTracks[CurrentAudioTrack]; + if (!*++at) + at = AudioTracks; Interface->Clear(); - cDevice::PrimaryDevice()->ToggleAudioTrack(); + cDevice::PrimaryDevice()->SetAudioTrack(at - AudioTracks); + //XXX Interface->Info(*at); state = osEnd; } - XXX*/ } break; case kBlue: if (!HasSubMenu()) @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: menu.h 1.47 2002/10/06 10:35:49 kls Exp $ + * $Id: menu.h 1.48 2002/10/13 10:34:09 kls Exp $ */ #ifndef __MENU_H @@ -70,6 +70,7 @@ private: eOSState Rewind(void); eOSState Delete(void); eOSState Summary(void); + eOSState Commands(eKeys Key = kNone); public: cMenuRecordings(const char *Base = NULL, int Level = 0, bool OpenSubMenus = false); ~cMenuRecordings(); @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: osd.c 1.35 2002/08/25 09:18:31 kls Exp $ + * $Id: osd.c 1.36 2002/10/13 10:31:28 kls Exp $ */ #include "osd.h" @@ -623,9 +623,7 @@ eOSState cOsdMenu::ProcessKey(eKeys Key) return state; } switch (Key) { - case k1...k9: if (hasHotkeys) - return HotKey(Key); - break; + case k1...k9: return hasHotkeys ? HotKey(Key) : osUnknown; case kUp|k_Repeat: case kUp: CursorUp(); break; case kDown|k_Repeat: @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: player.h 1.8 2002/08/16 09:14:12 kls Exp $ + * $Id: player.h 1.9 2002/10/12 11:17:02 kls Exp $ */ #ifndef __PLAYER_H @@ -50,6 +50,27 @@ public: // 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 // and >0 if this is multi speed mode. + virtual int NumAudioTracks(void) const { return 0; } + // Returns the number of audio tracks that are currently available on this + // player. The default return value is 0, meaning that this player + // 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 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 { @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: rcu.c 1.1 2002/09/29 13:16:44 kls Exp $ + * $Id: rcu.c 1.2 2002/10/06 15:49:03 kls Exp $ */ #include "rcu.h" @@ -308,5 +308,5 @@ void cRcuRemote::ChannelSwitch(const cDevice *Device, int ChannelNumber) void cRcuRemote::Recording(const cDevice *Device, const char *Name) { - SetPoints(1 << Device->CardIndex(), Device->Receiving()); //XXX CardNumber()!!! + SetPoints(1 << Device->DeviceNumber(), Device->Receiving()); } @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: recorder.c 1.2 2002/09/07 13:40:23 kls Exp $ + * $Id: recorder.c 1.3 2002/10/12 13:34:29 kls Exp $ */ #include <stdarg.h> @@ -119,7 +119,7 @@ void cRecorder::Action(void) r += g; if (r > 0) { int Count = r, Result; - const uchar *p = remux->Process(b, Count, Result, &pictureType); + uchar *p = remux->Process(b, Count, Result, &pictureType); if (p) { //XXX+ active??? see old version (Busy) if (!active && pictureType == I_FRAME) // finish the recording before the next 'I' frame diff --git a/recording.c b/recording.c index 544bbbd..1be6623 100644 --- a/recording.c +++ b/recording.c @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: recording.c 1.68 2002/10/05 13:44:56 kls Exp $ + * $Id: recording.c 1.69 2002/10/13 09:08:45 kls Exp $ */ #include "recording.h" @@ -363,7 +363,7 @@ cRecording::cRecording(const char *FileName) t.tm_mon--; t.tm_sec = 0; start = mktime(&t); - name = new char[p - FileName + 1]; + name = MALLOC(char, p - FileName + 1); strncpy(name, FileName, p - FileName); name[p - FileName] = 0; name = ExchangeChars(name, false); @@ -511,7 +511,7 @@ const char *cRecording::Title(char Delimiter, bool NewIndicator, int Level) break; } } - titleBuffer = new char[s - p + 3]; + titleBuffer = MALLOC(char, s - p + 3); *titleBuffer = Delimiter; *(titleBuffer + 1) = Delimiter; strn0cpy(titleBuffer + 2, p, s - p + 1); @@ -769,7 +769,7 @@ cIndexFile::cIndexFile(const char *FileName, bool Record) last = -1; index = NULL; if (FileName) { - fileName = new char[strlen(FileName) + strlen(INDEXFILESUFFIX) + 1]; + fileName = MALLOC(char, strlen(FileName) + strlen(INDEXFILESUFFIX) + 1); if (fileName) { strcpy(fileName, FileName); char *pFileExt = fileName + strlen(fileName); @@ -996,7 +996,7 @@ cFileName::cFileName(const char *FileName, bool Record, bool Blocking) record = Record; blocking = Blocking; // Prepare the file name: - fileName = new char[strlen(FileName) + RECORDFILESUFFIXLEN]; + fileName = MALLOC(char, strlen(FileName) + RECORDFILESUFFIXLEN); if (!fileName) { esyslog("ERROR: can't copy file name '%s'", fileName); return; @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: remote.c 1.28 2002/09/29 12:51:26 kls Exp $ + * $Id: remote.c 1.29 2002/10/12 15:22:08 kls Exp $ */ #include "remote.h" @@ -34,8 +34,7 @@ cCondVar cRemote::keyPressed; cRemote::cRemote(const char *Name) { - if (Name) - name = strdup(Name); + name = Name ? strdup(Name) : NULL; Remotes.Add(this); } @@ -8,7 +8,7 @@ * the Linux DVB driver's 'tuxplayer' example and were rewritten to suit * VDR's needs. * - * $Id: remux.c 1.11 2002/08/11 11:48:34 kls Exp $ + * $Id: remux.c 1.12 2002/10/12 13:33:54 kls Exp $ */ /* The calling interface of the 'cRemux::Process()' function is defined @@ -482,17 +482,9 @@ int cRemux::ScanVideoPacket(const uchar *Data, int Count, int Offset, uchar &Pic return -1; } -void cRemux::SetAudioPid(int APid) -{ - aPid1 = APid; - vTS2PES->Clear(); - aTS2PES1->Clear(); - resultCount = resultDelivered = 0; -} - #define TS_SYNC_BYTE 0x47 -const uchar *cRemux::Process(const uchar *Data, int &Count, int &Result, uchar *PictureType) +uchar *cRemux::Process(const uchar *Data, int &Count, int &Result, uchar *PictureType) { uchar dummyPictureType; if (!PictureType) @@ -611,7 +603,7 @@ XXX*/ if (synced) { *PictureType = pt; Result = l; - const uchar *p = resultBuffer + resultDelivered; + uchar *p = resultBuffer + resultDelivered; resultDelivered += l; return p; } @@ -629,7 +621,7 @@ XXX*/ return NULL; // no useful data found, wait for more if (synced) { Result = l; - const uchar *p = resultBuffer + resultDelivered; + uchar *p = resultBuffer + resultDelivered; resultDelivered += l; return p; } @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: remux.h 1.7 2002/08/09 16:18:02 kls Exp $ + * $Id: remux.h 1.8 2002/10/12 13:30:24 kls Exp $ */ #ifndef __REMUX_H @@ -47,8 +47,7 @@ private: public: cRemux(int VPid, int APid1, int APid2, int DPid1, int DPid2, bool ExitOnFailure = false); ~cRemux(); - void SetAudioPid(int APid); - const uchar *Process(const uchar *Data, int &Count, int &Result, uchar *PictureType = NULL); + uchar *Process(const uchar *Data, int &Count, int &Result, uchar *PictureType = NULL); }; #endif // __REMUX_H @@ -10,7 +10,7 @@ * and interact with the Video Disk Recorder - or write a full featured * graphical interface that sits on top of an SVDRP connection. * - * $Id: svdrp.c 1.44 2002/10/05 13:45:05 kls Exp $ + * $Id: svdrp.c 1.45 2002/10/13 09:31:31 kls Exp $ */ #include "svdrp.h" @@ -153,6 +153,7 @@ bool cPUTEhandler::Process(const char *s) else { rewind(f); if (cSchedules::Read(f)) { + cSIProcessor::TriggerDump(); status = 250; message = "EPG data processed"; } @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: transfer.c 1.3 2002/09/22 09:50:48 kls Exp $ + * $Id: transfer.c 1.4 2002/10/12 13:32:48 kls Exp $ */ #include "transfer.h" @@ -21,6 +21,8 @@ cTransfer::cTransfer(int VPid, int APid1, int APid2, int DPid1, int DPid2) { ringBuffer = new cRingBufferLinear(VIDEOBUFSIZE, true); remux = new cRemux(VPid, APid1, APid2, DPid1, DPid2); + canToggleAudioTrack = false; + audioTrack = 0xC0; gotBufferReserve = false; active = false; } @@ -86,9 +88,9 @@ void cTransfer::Action(void) if (r > 0) { int Count = r, Result; - const uchar *p = remux->Process(b, Count, Result); + uchar *p = remux->Process(b, Count, Result); if (p) { - //XXX+ StripAudio??? + StripAudioPackets(p, Result, audioTrack); while (Result > 0 && active) { int w = PlayVideo(p, Result); if (w > 0) { @@ -112,15 +114,65 @@ void cTransfer::Action(void) dsyslog("transfer thread ended (pid=%d)", getpid()); } -void cTransfer::SetAudioPid(int APid) +void cTransfer::StripAudioPackets(uchar *b, int Length, uchar Except) { - /*XXX+ - Clear(); - //XXX we may need to have access to the audio device, too, in order to clear it - CHECK(ioctl(toDevice, VIDEO_CLEAR_BUFFER)); - gotBufferReserve = false; - remux.SetAudioPid(APid); - XXX*/ + 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) + ;//XXX+ PlayExternalDolby(&b[i], Length - i); + // continue with deleting the data - otherwise it disturbs DVB replay + case 0xC0 ... 0xC1: // audio + if (c == 0xC1) + canToggleAudioTrack = true; + if (!Except || c != Except) { + int n = l; + for (int j = i; j < Length && n--; j++) + b[j] = 0x00; + } + 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 = NULL) 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 ------------------------------------------------------ @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: transfer.h 1.2 2002/06/23 12:26:24 kls Exp $ + * $Id: transfer.h 1.3 2002/10/12 12:59:05 kls Exp $ */ #ifndef __TRANSFER_H @@ -20,8 +20,11 @@ class cTransfer : public cReceiver, public cPlayer, public cThread { private: cRingBufferLinear *ringBuffer; cRemux *remux; + bool canToggleAudioTrack; + uchar audioTrack; bool gotBufferReserve; bool active; + void StripAudioPackets(uchar *b, int Length, uchar Except = 0x00); protected: virtual void Activate(bool On); virtual void Receive(uchar *Data, int Length); @@ -29,7 +32,9 @@ protected: public: cTransfer(int VPid, int APid1, int APid2, int DPid1, int DPid2); virtual ~cTransfer(); - void SetAudioPid(int APid); + virtual int NumAudioTracks(void) const; + virtual const char **GetAudioTracks(int *CurrentTrack = NULL) const; + virtual void SetAudioTrack(int Index); }; class cTransferControl : public cControl { @@ -8,7 +8,7 @@ .\" License as specified in the file COPYING that comes with the .\" vdr distribution. .\" -.\" $Id: vdr.5 1.6 2002/10/06 08:56:01 kls Exp $ +.\" $Id: vdr.5 1.8 2002/10/13 12:14:49 kls Exp $ .\" .TH vdr 5 "7 Sep 2002" "1.2.0" "Video Disk Recorder Files" .SH NAME @@ -311,7 +311,6 @@ PC keyboard, RCU for the home-built "Remote Control Unit", or LIRC for the "Linux Infrared Remote Control"), \fBkey\fR is the name of the key that is defined (like Up, Down, Menu etc.), and \fBcode\fR is a character string that this remote control delivers when the given key is pressed. - .SS COMMANDS The file \fIcommands.conf\fR contains the definitions of commands that can be executed from the \fBvdr\fR main menu's "Commands" option. @@ -322,7 +321,12 @@ Each line contains one command definition in the following format: where \fBtitle\fR is the string that will be displayed in the "Commands" menu, and \fBcommand\fR is the actual command string that will be executed when this option is selected. The delimiting ':' may be surrounded by any number of -white space characters. +white space characters. If \fBtitle\fR ends with the character '?', there will +be a confirmation prompt before actually executing the command. This can be +used for commands that might have serious results (like deleting files etc) +to make sure they are not executed inadvertently. + +Everything following (and including) a '#' character is considered to be comment. By default the menu entries in the "Commands" menu will be numbered '1'...'9' to make them selectable by pressing the corresponding number key. If you want @@ -337,16 +341,25 @@ In order to avoid error messages to the console, every command should have Examples: -Check for new mail: /usr/local/bin/checkmail 2>&1 +Check for new mail?: /usr/local/bin/checkmail 2>&1 .br -CPU status : /usr/local/bin/cpustatus 2>&1 +CPU status: /usr/local/bin/cpustatus 2>&1 .br -Disk space : df -h | grep '/video' | awk '{ print 100 - $5 "% free"; }' +Disk space: df -h | grep '/video' | awk '{ print 100 - $5 "% free"; }' .br -Calendar : date;echo;cal +Calendar: date;echo;cal Note that the commands 'checkmail' and 'cpustatus' are only \fBexamples\fR! Don't send emails to the author asking where to find these ;-) +.br +The '?' at the end of the "Check for new mail?" entry will prompt the user +whether this command shall really be executed. +.SS RECORDING COMMANDS +The file \fIreccmds.conf\fR can be used to define commands that can be applied +to the currently highlighted recording in the "Recordings" menu. The syntax is +exactly the same as described for the file \fIcommands.conf\fR. When executing +a command, the directory name of the recording will be appended to the command +string, separated by a blank and enclosed in single quotes. .SS SVDRP HOSTS The file \fIsvdrphosts.conf\fR contains the IP numbers of all hosts that are allowed to access the SVDRP port. @@ -22,7 +22,7 @@ * * The project's page is at http://www.cadsoft.de/people/kls/vdr * - * $Id: vdr.c 1.125 2002/10/06 10:25:04 kls Exp $ + * $Id: vdr.c 1.127 2002/10/13 12:13:19 kls Exp $ */ #include <getopt.h> @@ -319,6 +319,7 @@ int main(int argc, char *argv[]) Channels.Load(AddDirectory(ConfigDirectory, "channels.conf")); Timers.Load(AddDirectory(ConfigDirectory, "timers.conf")); Commands.Load(AddDirectory(ConfigDirectory, "commands.conf"), true); + RecordingCommands.Load(AddDirectory(ConfigDirectory, "reccmds.conf"), true); SVDRPhosts.Load(AddDirectory(ConfigDirectory, "svdrphosts.conf"), true); CaDefinitions.Load(AddDirectory(ConfigDirectory, "ca.conf"), true); Keys.Load(AddDirectory(ConfigDirectory, "remote.conf")); @@ -634,11 +635,12 @@ int main(int argc, char *argv[]) cControl::Shutdown(); delete Interface; cOsd::Shutdown(); - PluginManager.Shutdown(true); + Remotes.Clear(); Setup.CurrentChannel = cDevice::CurrentChannel(); Setup.CurrentVolume = cDevice::CurrentVolume(); Setup.Save(); cDevice::Shutdown(); + PluginManager.Shutdown(true); if (WatchdogTimeout > 0) dsyslog("max. latency time %d seconds", MaxLatencyTime); isyslog("exiting"); |