summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CONTRIBUTORS3
-rw-r--r--HISTORY18
-rw-r--r--Makefile6
-rw-r--r--PLUGINS.html188
-rw-r--r--PLUGINS/SRC/hello/i18n.c20
-rw-r--r--config.h4
-rw-r--r--cutter.c253
-rw-r--r--cutter.h29
-rw-r--r--device.c23
-rw-r--r--device.h6
-rw-r--r--dmxdev.c.diff12
-rw-r--r--dvbplayer.c35
-rw-r--r--dvbplayer.h7
-rw-r--r--eitscan.c4
-rw-r--r--i18n.c188
-rw-r--r--i18n.h4
-rw-r--r--interface.h3
-rw-r--r--menu.c30
-rw-r--r--menu.h4
-rw-r--r--osd.h5
-rw-r--r--player.c41
-rw-r--r--player.h16
-rw-r--r--recording.c22
-rw-r--r--recording.h7
-rw-r--r--transfer.c135
-rw-r--r--transfer.h44
-rw-r--r--vdr.c80
27 files changed, 1030 insertions, 157 deletions
diff --git a/CONTRIBUTORS b/CONTRIBUTORS
index 22bbc70..f886624 100644
--- a/CONTRIBUTORS
+++ b/CONTRIBUTORS
@@ -362,3 +362,6 @@ Matthias Fechner <matthiasfechner@web.de>
Paul Lacatus <paul@campina.iiruc.ro>
for translating OSD texts to the Romanian language
+
+Istvan Koenigsberger <istvnko@hotmail.com> and Guido Josten <guido.josten@t-online.de>
+ for translating OSD texts to the Hungarian language
diff --git a/HISTORY b/HISTORY
index b15541c..4b4eee9 100644
--- a/HISTORY
+++ b/HISTORY
@@ -724,7 +724,7 @@ Video Disk Recorder Revision History
"next timer event at..." messages in that case).
- Reduced the default value for MinEventTimeout to 30 minutes.
- Fixed detecting manual start in shutdown feature.
-- An error message is now displayed in case the Transfer Mode can't be
+- An error message is now displayed in case the 'Transfer Mode' can't be
started because the necessary DVB card is currently recording (or there
is no DVB card that can access this channel).
- Fixed toggling channels with the '0' key in case the "Ok" button has been
@@ -1108,7 +1108,7 @@ Video Disk Recorder Revision History
- The "Left" and "Right" keys are now used to page up and down in text displays
(like the EPG descriptions or the results of commands executed from the
"Commands" menu).
-- Fixed high CPU usage in transfer mode.
+- Fixed high CPU usage in 'Transfer Mode'.
- Replaced 'killproc' with 'killall' in 'runvdr', since apparently 'killproc'
is not available by default on some Linux distributions, whereas 'killall' is.
Please check if your system provides 'killall' - if it doesn't, please change
@@ -1343,7 +1343,19 @@ Video Disk Recorder Revision History
will use the same DVB card. During the time where both timers record the data
is simply saved to both files.
- The following limitations apply to this version:
- + Transfer mode doesn't work yet.
+ + 'Transfer Mode' doesn't work yet.
+ The '-a' option (for Dolby Digital audio) doesn't work yet.
+ Switching between different language tracks doesn't work yet.
+ Cutting doesn't work yet.
+
+2002-06-23: Version 1.1.4
+
+- Added Hungarian language texts (thanks to Istvan Koenigsberger and Guido Josten).
+- Activated cutting.
+- Activated 'Transfer Mode'.
+- Moved handling of the Menu key entirely into vdr.c.
+- Switched VDR's own player to the new cPlayer/cControl structures.
+- Switched handling 'Transfer Mode' to the new cPlayer/cControl structures.
+- The following limitations apply to this version:
+ + The '-a' option (for Dolby Digital audio) doesn't work yet.
+ + Switching between different language tracks doesn't work yet.
diff --git a/Makefile b/Makefile
index 3cc655f..dd9741d 100644
--- a/Makefile
+++ b/Makefile
@@ -4,7 +4,7 @@
# See the main source file 'vdr.c' for copyright information and
# how to reach the author.
#
-# $Id: Makefile 1.40 2002/06/10 16:31:34 kls Exp $
+# $Id: Makefile 1.42 2002/06/22 10:21:56 kls Exp $
.DELETE_ON_ERROR:
@@ -21,10 +21,10 @@ INCLUDES = -I$(DVBDIR)/ost/include
DTVLIB = $(DTVDIR)/libdtv.a
-OBJS = audio.o config.o device.o dvbplayer.o dvbosd.o eit.o eitscan.o font.o i18n.o\
+OBJS = audio.o config.o cutter.o device.o dvbplayer.o dvbosd.o eit.o eitscan.o font.o i18n.o\
interface.o menu.o menuitems.o osdbase.o osd.o player.o plugin.o receiver.o\
recorder.o recording.o remote.o remux.o ringbuffer.o status.o svdrp.o thread.o\
- tools.o vdr.o videodir.o
+ tools.o transfer.o vdr.o videodir.o
OSDFONT = -adobe-helvetica-medium-r-normal--23-*-100-100-p-*-iso8859-1
FIXFONT = -adobe-courier-bold-r-normal--25-*-100-100-m-*-iso8859-1
diff --git a/PLUGINS.html b/PLUGINS.html
index 9b5a496..59a2f18 100644
--- a/PLUGINS.html
+++ b/PLUGINS.html
@@ -12,7 +12,7 @@ This interface allows programmers to develop additional functionality for VDR co
separate from the core VDR source, without the need of patching the original
VDR code (and all the problems of correlating various patches).
<p>
-<!--X1.1.3--><table width=100%><tr><td bgcolor=red>&nbsp;</td><td width=100%>
+<!--X1.1.3--><table width=100%><tr><td bgcolor=#AA0000>&nbsp;</td><td width=100%>
This document is divided into two parts, the first one describing the
<a href="#Part I - The Outside Interface"><i>outside</i> interface</a>
of the plugin system, and the second one describing the
@@ -23,16 +23,18 @@ The <i>inside</i> interface provides the plugin code access to VDR's internal da
structures and allows it to hook itself into specific areas to perform special actions.
<!--X1.1.3--></td></tr></table>
<p>
-<!--X1.1.1--><table width=100%><tr><td bgcolor=lime>&nbsp;</td><td width=100%>
+<!--X1.1.1--><table width=100%><tr><td bgcolor=#0000AA>&nbsp;</td><td width=100%>
Important modifications introduced in version 1.1.1 are marked like this.
<!--X1.1.1--></td></tr></table>
-<!--X1.1.2--><table width=100%><tr><td bgcolor=cyan>&nbsp;</td><td width=100%>
+<!--X1.1.2--><table width=100%><tr><td bgcolor=#00AA00>&nbsp;</td><td width=100%>
Important modifications introduced in version 1.1.2 are marked like this.
<!--X1.1.2--></td></tr></table>
-<!--X1.1.3--><table width=100%><tr><td bgcolor=red>&nbsp;</td><td width=100%>
+<!--X1.1.3--><table width=100%><tr><td bgcolor=#AA0000>&nbsp;</td><td width=100%>
Important modifications introduced in version 1.1.3 are marked like this.
<!--X1.1.3--></td></tr></table>
-<!--<p>TODO: Link to the document about VDR base classes to use when implementing actual functionality (yet to be written).-->
+<!--X1.1.4--><table width=100%><tr><td bgcolor=#FF0000>&nbsp;</td><td width=100%>
+Important modifications introduced in version 1.1.4 are marked like this.
+<!--X1.1.4--></td></tr></table>
<a name="Part I - The Outside Interface"><hr><center><h1>Part I - The Outside Interface</h1></center>
@@ -129,7 +131,7 @@ from the web, it will typically have a name like
<p>
and will unpack into a directory named
<p>
-<!--X1.1.2--><table width=100%><tr><td bgcolor=cyan>&nbsp;</td><td width=100%>
+<!--X1.1.2--><table width=100%><tr><td bgcolor=#00AA00>&nbsp;</td><td width=100%>
<tt>hello-0.0.1</tt>
<!--X1.1.2--></td></tr></table>
<p>
@@ -137,7 +139,7 @@ To use the <tt>plugins</tt> and <tt>plugins-clean</tt> targets from the VDR <tt>
you need to unpack such an archive into the <tt>VDR/PLUGINS/SRC</tt> directory and
create a symbolic link with the basic plugin name, as in
-<!--X1.1.2--><table width=100%><tr><td bgcolor=cyan>&nbsp;</td><td width=100%>
+<!--X1.1.2--><table width=100%><tr><td bgcolor=#00AA00>&nbsp;</td><td width=100%>
<p><table><tr><td bgcolor=#F0F0F0><pre><br>
ln -s hello-0.0.1 hello
</pre></td></tr></table><p>
@@ -203,7 +205,7 @@ its memory. You don't need to worry about the details behind all this.
If your plugin requires additional source files, simply add them to your plugin's
source directory and adjust the <tt>Makefile</tt> accordingly.
<p>
-<!--X1.1.1--><table width=100%><tr><td bgcolor=lime>&nbsp;</td><td width=100%>
+<!--X1.1.1--><table width=100%><tr><td bgcolor=#0000AA>&nbsp;</td><td width=100%>
Header files usually contain preprocessor statements that prevent the same
file (or rather its contents, to be precise) from being included more than once, like
@@ -422,7 +424,7 @@ If a plugin implements a function that runs in the background (presumably in a
thread of its own), or wants to make use of <a href="#Internationalization">internationalization</a>,
it needs to implement the function
-<!--X1.1.2--><table width=100%><tr><td bgcolor=cyan>&nbsp;</td><td width=100%>
+<!--X1.1.2--><table width=100%><tr><td bgcolor=#00AA00>&nbsp;</td><td width=100%>
<p><table><tr><td bgcolor=#F0F0F0><pre><br>
virtual bool Start(void);
</pre></td></tr></table><p>
@@ -434,7 +436,7 @@ its task. This may, for instance, be a thread that collects data from the DVB
stream, which is later presented to the user via a function that is available
from the main menu.
<p>
-<!--X1.1.2--><table width=100%><tr><td bgcolor=cyan>&nbsp;</td><td width=100%>
+<!--X1.1.2--><table width=100%><tr><td bgcolor=#00AA00>&nbsp;</td><td width=100%>
A return value of <i>false</i> indicates that something has gone wrong and the
plugin will not be able to perform its task. In that case, the plugin should
write a proper error message to the log file. The first plugin that returns
@@ -498,7 +500,7 @@ interaction is possible. If a specific action takes longer than a few seconds,
the plugin should launch a separate thread to do this.
</b>
-<!--X1.1.2--><table width=100%><tr><td bgcolor=cyan>&nbsp;</td><td width=100%>
+<!--X1.1.2--><table width=100%><tr><td bgcolor=#00AA00>&nbsp;</td><td width=100%>
<hr><h2>Housekeeping</h2>
<center><i><b>Chores, chores...</b></i></center><p>
@@ -545,7 +547,7 @@ previously stored in the global setup data (see below). It shall return
<i>true</i> if the parameter was parsed correctly, <i>false</i> in case of
an error. If <i>false</i> is returned, an error message will be written to
the log file (and program execution will continue).
-<!--X1.1.1--><table width=100%><tr><td bgcolor=lime>&nbsp;</td><td width=100%>
+<!--X1.1.1--><table width=100%><tr><td bgcolor=#0000AA>&nbsp;</td><td width=100%>
A possible implementation of <tt>SetupParse()</tt> could look like this:
<p><table><tr><td bgcolor=#F0F0F0><pre><br>
@@ -600,7 +602,7 @@ needs setup parameters that are not directly user adjustable. It can use
<tt>SetupStore()</tt> and <tt>SetupParse()</tt> without presenting these
parameters to the user.
-<!--X1.1.1--><table width=100%><tr><td bgcolor=lime>&nbsp;</td><td width=100%>
+<!--X1.1.1--><table width=100%><tr><td bgcolor=#0000AA>&nbsp;</td><td width=100%>
<a name="The Setup menu"><hr><h2>The Setup menu</h2>
<center><i><b>Have it your way!</b></i></center><p>
@@ -660,7 +662,7 @@ your setup parameters and use that one to copy all parameters with one single st
(like VDR does with its cSetup class).
<!--X1.1.1--></td></tr></table>
-<!--X1.1.2--><table width=100%><tr><td bgcolor=cyan>&nbsp;</td><td width=100%>
+<!--X1.1.2--><table width=100%><tr><td bgcolor=#00AA00>&nbsp;</td><td width=100%>
<hr><h2>Configuration files</h2>
<center><i><b>I want my own stuff!</b></i></center><p>
@@ -746,6 +748,9 @@ const tI18nPhrase Phrases[] = {
"",// TODO
"",// TODO
"",// TODO
+ "",// TODO
+ "",// TODO
+ "",// TODO
},
{ NULL }
};
@@ -827,7 +832,7 @@ and display their help and/or version information in addition to its own output.
If you want to make your plugin available to other VDR users, you'll need to
make a package that can be easily distributed.
-<!--X1.1.3--><table width=100%><tr><td bgcolor=red>&nbsp;</td><td width=100%>
+<!--X1.1.3--><table width=100%><tr><td bgcolor=#AA0000>&nbsp;</td><td width=100%>
The <tt>Makefile</tt> that has been created by the call to
<a href="#Initializing a new plugin directory"><tt>newplugin</tt></a>
provides the target <tt>dist</tt>, which does this for you.
@@ -849,7 +854,7 @@ vdr-hello-0.0.1.tgz
in your source directory, where <tt>hello</tt> will be replaced with your actual
plugin's name, and <tt>0.0.1</tt> will be your plugin's current version number.
-<!--X1.1.3--><table width=100%><tr><td bgcolor=red>&nbsp;</td><td width=100%>
+<!--X1.1.3--><table width=100%><tr><td bgcolor=#AA0000>&nbsp;</td><td width=100%>
<a name="Part II - The Inside Interface"><hr><center><h1>Part II - The Inside Interface</h1></center>
<hr><h2>Status monitor</h2>
@@ -926,5 +931,156 @@ member functions are available in <tt>cStatus</tt>. You only need to implement
the functions you actually want to use.
<!--X1.1.3--></td></tr></table>
+<!--X1.1.4--><table width=100%><tr><td bgcolor=#FF0000>&nbsp;</td><td width=100%>
+<hr><h2>Players</h2>
+
+<center><i><b>Play it again, Sam!</b></i></center><p>
+
+Implementing a player is a two step process.
+First you need the actual player class, which is derived from the abstract <tt>cPlayer</tt>:
+
+<p><table><tr><td bgcolor=#F0F0F0><pre><br>
+#include &lt;vdr/player.h&gt;
+
+class cMyPlayer : public cPlayer {
+protected:
+ virtual void Activate(bool On);
+public:
+ cMyPlayer(void);
+ virtual ~cMyPlayer();
+ };
+</pre></td></tr></table><p>
+
+What exactly you do in this class is entirely up to you. If you want to run a separate
+thread which, e.g., reads data from a file, you can additionally derive your class from
+<tt>cThread</tt> and implement the necessary functionality:
+
+<p><table><tr><td bgcolor=#F0F0F0><pre><br>
+#include &lt;vdr/player.h&gt;
+
+class cMyPlayer : public cPlayer, cThread {
+protected:
+ virtual void Activate(bool On);
+ virtual void Action(void);
+public:
+ cMyPlayer(void);
+ virtual ~cMyPlayer();
+ };
+</pre></td></tr></table><p>
+
+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.
+<p>
+To play the video data, the player needs to call its member function
+
+<p><table><tr><td bgcolor=#F0F0F0><pre><br>
+int PlayVideo(const uchar *Data, int Length);
+</pre></td></tr></table><p>
+
+where <tt>Data</tt> point to a block of <tt>Length</tt> bytes of a PES data
+stream. 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
+desired video data stream, and it must be delivered fast enough so that the
+DVB device doesn't run out of data.
+<p>
+TODO: PlayAudio()???
+<p>
+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:
+
+<p><table><tr><td bgcolor=#F0F0F0><pre><br>
+#include &lt;vdr/player.h&gt;
+
+class cMyControl : public cControl {
+private:
+ cMyPlayer *player;
+public:
+ cMyControl(void);
+ virtual ~cMyControl();
+ virtual void Hide(void);
+ virtual eOSState ProcessKey(eKeys Key);
+ };
+</pre></td></tr></table><p>
+
+<tt>cMyControl</tt> shall create an object of type <tt>cMyPlayer</tt> and
+hand over a pointer to it to the <tt>cControl</tt> base class, so that it
+can be later attached to the primary DVB device:
+
+<p><table><tr><td bgcolor=#F0F0F0><pre><br>
+cMyControl::cMyControl(void)
+:cControl(player = new cMyPlayer)
+{
+}
+</pre></td></tr></table><p>
+
+<tt>cMyControl</tt> will receive the user's key presses through the <tt>ProcessKey()</tt>
+function. It will get all button presses, except for the volume control buttons
+(<tt>kVolUp</tt>, <tt>kVolDn</tt>, <tt>kMute</tt>), the power button (<tt>kPower</tt>)
+and the menu button (<tt>kMenu</tt>). If the user has not pressed a button for a while
+(which is typically in the area of about one second), <tt>ProcessKey()</tt> will be called
+with <tt>kNone</tt>, so that the <tt>cMyControl</tt> gets a chance to check whether its
+player is still active. Once the player has become inactive (because the user has decided
+to stop it or the DVB device has detached it), <tt>ProcessKey()</tt> must return <tt>osEnd</tt>
+to make the main program loop shut down the player control.
+<p>
+A derived <tt>cControl</tt> <b>must</b> implement the <tt>Hide()</tt> function, in which
+it has to hide itself from the OSD, in case it uses it. <tt>Hide()</tt> may be called at
+any time, and it may be called even if the <tt>cControl</tt> is not visible at the moment.
+The reason for this is that the <tt>Menu</tt> button shall always bring up the main VDR
+menu, so any active <tt>cControl</tt> needs to be hidden when that button is pressed.
+<p>
+Finally, to get things going, a plugin that implements a player (and the surrounding
+infrastructure like displaying a list of playable stuff etc) simply has to call the
+static function <tt>cControl::Launch()</tt> with the player control object, as in
+
+<p><table><tr><td bgcolor=#F0F0F0><pre><br>
+cControl::Launch(new cMyControl);
+</pre></td></tr></table><p>
+
+Ownership of the <tt>MyControl</tt> object is handed over to the VDR core code,
+so the plugin should not keep a pointer to it, because VDR will destroy the object
+whenever it sees fit (for instance because a recording shall start that needs to
+use the primary DVB device, or the user decides to start a different replay).
+<p>
+The <tt>cPlayer</tt> class has a member function
+
+<p><table><tr><td bgcolor=#F0F0F0><pre><br>
+void DeviceStillPicture(const uchar *Data, int Length);
+</pre></td></tr></table><p>
+
+which can be called to display a still picture. VDR uses this function when handling
+its editing marks. A special case of a "player" might use this function to implement
+a "picture viewer".
+<p>
+For detailed information on how to implement your own player, please take a look
+at VDR's <tt>cDvbPlayer</tt> and <tt>cDvbPlayerControl</tt> classes.
+<p>
+<b>User interface</b>
+<p>
+In order for a new player to nicely "blend in" to the overall VDR appearance it
+is recommended that it implements the same functionality with the same keys as the
+VDR player does (as far as this is possible and makes sense). The main points to
+consider here are
+<ul>
+<li>The <i>Ok</i> button shall bring up some display that indicates what is currently
+ being played, and what the status of this replay session is. As an alternative (for
+ instance with a DVD player) it may display a player specific menu, from which the
+ user can select certain options.
+<li>The <i>Up</i>, <i>Down</i>, <i>Left</i> and <i>Right</i> buttons shall control
+ <i>Play</i>, <i>Pause</i>, <i>Fast Rewind</i> and <i>Fast Forward</i>, respectively
+ (provided that this particular player can implement these functions) if the player
+ is not currently showing any menu. If there is a menu, they shall allow the user
+ to navigate in the menu.
+<li>The <i>Green</i> and <i>Yellow</i> buttons shall skip back- and forward by an
+ amount of time suitable for this player (provided that this particular player can
+ implement these functions).
+<li>The <i>Blue</i> button shall immediately stop the replay session.
+</ul>
+Of course, these are only suggestions which should make it easier for VDR users to
+enjoy additional players, since they will be able to control them with actions
+that they already know. If you absolutely want to do things differently, just go
+ahead - it's your show...
+<!--X1.1.4--></td></tr></table>
+
</body>
</html>
diff --git a/PLUGINS/SRC/hello/i18n.c b/PLUGINS/SRC/hello/i18n.c
index 9bb6fbf..644bb50 100644
--- a/PLUGINS/SRC/hello/i18n.c
+++ b/PLUGINS/SRC/hello/i18n.c
@@ -3,7 +3,7 @@
*
* See the README file for copyright information and how to reach the author.
*
- * $Id: i18n.c 1.2 2002/05/11 12:27:00 kls Exp $
+ * $Id: i18n.c 1.3 2002/06/23 13:05:59 kls Exp $
*/
#include "i18n.h"
@@ -21,6 +21,9 @@ const tI18nPhrase Phrases[] = {
"",// TODO
"",// TODO
"",// TODO
+ "",// TODO
+ "",// TODO
+ "",// TODO
},
{ "Hello world!",
"Hallo Welt!",
@@ -34,6 +37,9 @@ const tI18nPhrase Phrases[] = {
"",// TODO
"",// TODO
"",// TODO
+ "",// TODO
+ "",// TODO
+ "",// TODO
},
{ "Howdy folks!",
"Tach zusammen!",
@@ -47,6 +53,9 @@ const tI18nPhrase Phrases[] = {
"",// TODO
"",// TODO
"",// TODO
+ "",// TODO
+ "",// TODO
+ "",// TODO
},
{ "A friendly greeting",
"Ein freundlicher Gruß",
@@ -60,6 +69,9 @@ const tI18nPhrase Phrases[] = {
"",// TODO
"",// TODO
"",// TODO
+ "",// TODO
+ "",// TODO
+ "",// TODO
},
{ "Greeting time (s)",
"Dauer des Grußes (s)",
@@ -73,6 +85,9 @@ const tI18nPhrase Phrases[] = {
"",// TODO
"",// TODO
"",// TODO
+ "",// TODO
+ "",// TODO
+ "",// TODO
},
{ "Use alternate greeting",
"Alternativen Gruß verwenden",
@@ -86,6 +101,9 @@ const tI18nPhrase Phrases[] = {
"",// TODO
"",// TODO
"",// TODO
+ "",// TODO
+ "",// TODO
+ "",// TODO
},
{ NULL }
};
diff --git a/config.h b/config.h
index 577d02d..601b6fd 100644
--- a/config.h
+++ b/config.h
@@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
- * $Id: config.h 1.118 2002/05/31 10:20:56 kls Exp $
+ * $Id: config.h 1.119 2002/06/16 14:49:52 kls Exp $
*/
#ifndef __CONFIG_H
@@ -19,7 +19,7 @@
#include "eit.h"
#include "tools.h"
-#define VDRVERSION "1.1.3"
+#define VDRVERSION "1.1.4"
#define MAXPRIORITY 99
#define MAXLIFETIME 99
diff --git a/cutter.c b/cutter.c
new file mode 100644
index 0000000..2b623ed
--- /dev/null
+++ b/cutter.c
@@ -0,0 +1,253 @@
+/*
+ * cutter.c: The video cutting facilities
+ *
+ * See the main source file 'vdr.c' for copyright information and
+ * how to reach the author.
+ *
+ * $Id: cutter.c 1.1 2002/06/22 10:09:34 kls Exp $
+ */
+
+#include "cutter.h"
+#include "recording.h"
+#include "remux.h"
+#include "thread.h"
+#include "videodir.h"
+
+// --- cCuttingThread --------------------------------------------------------
+
+class cCuttingThread : public cThread {
+private:
+ const char *error;
+ bool active;
+ int fromFile, toFile;
+ cFileName *fromFileName, *toFileName;
+ cIndexFile *fromIndex, *toIndex;
+ cMarks fromMarks, toMarks;
+protected:
+ virtual void Action(void);
+public:
+ cCuttingThread(const char *FromFileName, const char *ToFileName);
+ virtual ~cCuttingThread();
+ const char *Error(void) { return error; }
+ };
+
+cCuttingThread::cCuttingThread(const char *FromFileName, const char *ToFileName)
+{
+ error = NULL;
+ active = false;
+ fromFile = toFile = -1;
+ fromFileName = toFileName = NULL;
+ fromIndex = toIndex = NULL;
+ if (fromMarks.Load(FromFileName) && fromMarks.Count()) {
+ fromFileName = new cFileName(FromFileName, false, true);
+ toFileName = new cFileName(ToFileName, true, true);
+ fromIndex = new cIndexFile(FromFileName, false);
+ toIndex = new cIndexFile(ToFileName, true);
+ toMarks.Load(ToFileName); // doesn't actually load marks, just sets the file name
+ Start();
+ }
+ else
+ esyslog("no editing marks found for %s", FromFileName);
+}
+
+cCuttingThread::~cCuttingThread()
+{
+ active = false;
+ Cancel(3);
+ delete fromFileName;
+ delete toFileName;
+ delete fromIndex;
+ delete toIndex;
+}
+
+void cCuttingThread::Action(void)
+{
+ dsyslog("video cutting thread started (pid=%d)", getpid());
+
+ cMark *Mark = fromMarks.First();
+ if (Mark) {
+ fromFile = fromFileName->Open();
+ toFile = toFileName->Open();
+ active = fromFile >= 0 && toFile >= 0;
+ int Index = Mark->position;
+ Mark = fromMarks.Next(Mark);
+ int FileSize = 0;
+ int CurrentFileNumber = 0;
+ int LastIFrame = 0;
+ toMarks.Add(0);
+ toMarks.Save();
+ uchar buffer[MAXFRAMESIZE];
+ while (active) {
+ uchar FileNumber;
+ int FileOffset, Length;
+ uchar PictureType;
+
+ // Make sure there is enough disk space:
+
+ AssertFreeDiskSpace();
+
+ // Read one frame:
+
+ if (fromIndex->Get(Index++, &FileNumber, &FileOffset, &PictureType, &Length)) {
+ if (FileNumber != CurrentFileNumber) {
+ fromFile = fromFileName->SetOffset(FileNumber, FileOffset);
+ CurrentFileNumber = FileNumber;
+ }
+ if (fromFile >= 0) {
+ int len = ReadFrame(fromFile, buffer, Length, sizeof(buffer));
+ if (len < 0) {
+ error = "ReadFrame";
+ break;
+ }
+ if (len != Length) {
+ CurrentFileNumber = 0; // this re-syncs in case the frame was larger than the buffer
+ Length = len;
+ }
+ }
+ else {
+ error = "fromFile";
+ break;
+ }
+ }
+ else
+ break;
+
+ // Write one frame:
+
+ if (PictureType == I_FRAME) { // every file shall start with an I_FRAME
+ if (!Mark) // edited version shall end before next I-frame
+ break;
+ if (FileSize > MEGABYTE(Setup.MaxVideoFileSize)) {
+ toFile = toFileName->NextFile();
+ if (toFile < 0) {
+ error = "toFile 1";
+ break;
+ }
+ FileSize = 0;
+ }
+ LastIFrame = 0;
+ }
+ if (safe_write(toFile, buffer, Length) < 0) {
+ error = "safe_write";
+ break;
+ }
+ if (!toIndex->Write(PictureType, toFileName->Number(), FileSize)) {
+ error = "toIndex";
+ break;
+ }
+ FileSize += Length;
+ if (!LastIFrame)
+ LastIFrame = toIndex->Last();
+
+ // Check editing marks:
+
+ if (Mark && Index >= Mark->position) {
+ Mark = fromMarks.Next(Mark);
+ toMarks.Add(LastIFrame);
+ if (Mark)
+ toMarks.Add(toIndex->Last() + 1);
+ toMarks.Save();
+ if (Mark) {
+ Index = Mark->position;
+ Mark = fromMarks.Next(Mark);
+ CurrentFileNumber = 0; // triggers SetOffset before reading next frame
+ if (Setup.SplitEditedFiles) {
+ toFile = toFileName->NextFile();
+ if (toFile < 0) {
+ error = "toFile 2";
+ break;
+ }
+ FileSize = 0;
+ }
+ }
+ // the 'else' case (i.e. 'final end mark reached') is handled above
+ // in 'Write one frame', so that the edited version will end right
+ // before the next I-frame.
+ }
+ }
+ }
+ else
+ esyslog("no editing marks found!");
+ dsyslog("end video cutting thread");
+}
+
+// --- cCutter ---------------------------------------------------------------
+
+char *cCutter::editedVersionName = NULL;
+cCuttingThread *cCutter::cuttingThread = NULL;
+bool cCutter::error = false;
+bool cCutter::ended = false;
+
+bool cCutter::Start(const char *FileName)
+{
+ if (!cuttingThread) {
+ error = false;
+ ended = false;
+ cRecording Recording(FileName);
+ const char *evn = Recording.PrefixFileName('%');
+ if (evn && RemoveVideoFile(evn) && MakeDirs(evn, true)) {
+ // XXX this can be removed once RenameVideoFile() follows symlinks (see videodir.c)
+ // remove a possible deleted recording with the same name to avoid symlink mixups:
+ char *s = strdup(evn);
+ char *e = strrchr(s, '.');
+ if (e) {
+ if (strcmp(e, ".rec") == 0) {
+ strcpy(e, ".del");
+ RemoveVideoFile(s);
+ }
+ }
+ delete s;
+ // XXX
+ editedVersionName = strdup(evn);
+ Recording.WriteSummary();
+ cuttingThread = new cCuttingThread(FileName, editedVersionName);
+ return true;
+ }
+ }
+ return false;
+}
+
+void cCutter::Stop(void)
+{
+ bool Interrupted = cuttingThread && cuttingThread->Active();
+ const char *Error = cuttingThread ? cuttingThread->Error() : NULL;
+ delete cuttingThread;
+ cuttingThread = NULL;
+ if ((Interrupted || Error) && editedVersionName) {
+ if (Interrupted)
+ isyslog("editing process has been interrupted");
+ if (Error)
+ esyslog("ERROR: '%s' during editing process", Error);
+ RemoveVideoFile(editedVersionName); //XXX what if this file is currently being replayed?
+ }
+}
+
+bool cCutter::Active(void)
+{
+ if (cuttingThread) {
+ if (cuttingThread->Active())
+ return true;
+ error = cuttingThread->Error();
+ Stop();
+ if (!error)
+ cRecordingUserCommand::InvokeCommand(RUC_EDITEDRECORDING, editedVersionName);
+ delete editedVersionName;
+ editedVersionName = NULL;
+ ended = true;
+ }
+ return false;
+}
+
+bool cCutter::Error(void)
+{
+ bool result = error;
+ error = false;
+ return result;
+}
+
+bool cCutter::Ended(void)
+{
+ bool result = ended;
+ ended = false;
+ return result;
+}
diff --git a/cutter.h b/cutter.h
new file mode 100644
index 0000000..8275281
--- /dev/null
+++ b/cutter.h
@@ -0,0 +1,29 @@
+/*
+ * cutter.h: The video cutting facilities
+ *
+ * See the main source file 'vdr.c' for copyright information and
+ * how to reach the author.
+ *
+ * $Id: cutter.h 1.1 2002/06/22 10:03:15 kls Exp $
+ */
+
+#ifndef __CUTTER_H
+#define __CUTTER_H
+
+class cCuttingThread;
+
+class cCutter {
+private:
+ static char *editedVersionName;
+ static cCuttingThread *cuttingThread;
+ static bool error;
+ static bool ended;
+public:
+ static bool Start(const char *FileName);
+ static void Stop(void);
+ static bool Active(void);
+ static bool Error(void);
+ static bool Ended(void);
+ };
+
+#endif //__CUTTER_H
diff --git a/device.c b/device.c
index fe75659..c85cd45 100644
--- a/device.c
+++ b/device.c
@@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
- * $Id: device.c 1.2 2002/06/16 13:23:31 kls Exp $
+ * $Id: device.c 1.5 2002/06/23 12:51:24 kls Exp $
*/
#include "device.h"
@@ -21,6 +21,7 @@ extern "C" {
#include "player.h"
#include "receiver.h"
#include "status.h"
+#include "transfer.h"
#define DEV_VIDEO "/dev/video"
#define DEV_OST_OSD "/dev/ost/osd"
@@ -456,8 +457,7 @@ bool cDevice::SetPid(int fd, dmxPesType_t PesType, int Pid, dmxOutput_t Output)
eSetChannelResult cDevice::SetChannel(int ChannelNumber, int Frequency, char Polarization, int Diseqc, int Srate, int Vpid, int Apid, int Tpid, int Ca, int Pnr)
{
- //XXX+StopTransfer();
- //XXX+StopReplay();
+ StopReplay();
cStatus::MsgChannelSwitch(this, 0);
@@ -620,10 +620,8 @@ eSetChannelResult cDevice::SetChannel(int ChannelNumber, int Frequency, char Pol
if (NeedsTransferMode) {
cDevice *CaDevice = GetDevice(Ca, 0);
if (CaDevice && !CaDevice->Receiving()) {
- if ((Result = CaDevice->SetChannel(ChannelNumber, Frequency, Polarization, Diseqc, Srate, Vpid, Apid, Tpid, Ca, Pnr)) == scrOk) {
- //XXX+SetModeReplay();
- //XXX+transferringFromDevice = CaDevice->StartTransfer(fd_video);
- }
+ if ((Result = CaDevice->SetChannel(ChannelNumber, Frequency, Polarization, Diseqc, Srate, Vpid, Apid, Tpid, Ca, Pnr)) == scrOk)
+ cControl::Launch(new cTransferControl(CaDevice, Vpid, Apid, 0, 0, 0));//XXX+
}
else
Result = scrNoTransfer;
@@ -731,15 +729,10 @@ void cDevice::StillPicture(const uchar *Data, int Length)
bool cDevice::Replaying(void)
{
- /*XXX+
- if (replayBuffer && !replayBuffer->Active())
- StopReplay();
- return replayBuffer != NULL;
- XXX*/
return player != NULL;
}
-bool cDevice::Attach(cPlayer *Player)
+bool cDevice::AttachPlayer(cPlayer *Player)
{
if (Receiving()) {
esyslog("ERROR: attempt to attach a cPlayer while receiving on device %d - ignored", CardIndex() + 1);
@@ -792,6 +785,8 @@ void cDevice::StopReplay(void)
{
if (player) {
Detach(player);
+ if (IsPrimaryDevice())
+ cControl::Shutdown();
/*XXX+
if (IsPrimaryDevice()) {
// let's explicitly switch the channel back in case it was in Transfer Mode:
@@ -958,7 +953,7 @@ void cDevice::Action(void)
dsyslog("receiver thread ended on device %d (pid=%d)", CardIndex() + 1, getpid());
}
-bool cDevice::Attach(cReceiver *Receiver)
+bool cDevice::AttachReceiver(cReceiver *Receiver)
{
//XXX+ check for same transponder???
if (!Receiver)
diff --git a/device.h b/device.h
index a25ff94..6f2a34f 100644
--- a/device.h
+++ b/device.h
@@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
- * $Id: device.h 1.1 2002/06/09 15:48:32 kls Exp $
+ * $Id: device.h 1.3 2002/06/23 11:50:24 kls Exp $
*/
#ifndef __DEVICE_H
@@ -172,7 +172,7 @@ public:
// Returns true if we are currently replaying.
void StopReplay(void);
// Stops the current replay session (if any).
- bool Attach(cPlayer *Player);
+ bool AttachPlayer(cPlayer *Player);
void Detach(cPlayer *Player);
virtual int PlayVideo(const uchar *Data, int Length);
virtual int PlayAudio(const uchar *Data, int Length);
@@ -192,7 +192,7 @@ public:
// Returns the ca of the current receiving session.
bool Receiving(void);
// Returns true if we are currently receiving.
- bool Attach(cReceiver *Receiver);
+ bool AttachReceiver(cReceiver *Receiver);
void Detach(cReceiver *Receiver);
};
diff --git a/dmxdev.c.diff b/dmxdev.c.diff
deleted file mode 100644
index 85672c0..0000000
--- a/dmxdev.c.diff
+++ /dev/null
@@ -1,12 +0,0 @@
---- dmxdev.c Mon Apr 1 10:59:46 2002
-+++ dmxdev.c Sun Jun 16 11:02:38 2002
-@@ -1048,6 +1048,9 @@
- if (dmxdev->dvr_buffer.pread!=dmxdev->dvr_buffer.pwrite)
- return (POLLIN | POLLRDNORM | POLLPRI);
-
-+ if (dmxdev->dvr_buffer.error)
-+ return (POLLIN | POLLRDNORM | POLLPRI | POLLERR);
-+
- return 0;
- } else
- return (POLLOUT | POLLWRNORM | POLLPRI);
diff --git a/dvbplayer.c b/dvbplayer.c
index 10fdf4b..9ea8eb1 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.1 2002/06/16 10:59:45 kls Exp $
+ * $Id: dvbplayer.c 1.4 2002/06/23 10:52:51 kls Exp $
*/
#include "dvbplayer.h"
@@ -13,22 +13,6 @@
#include "ringbuffer.h"
#include "thread.h"
-// --- ReadFrame -------------------------------------------------------------
-
-int ReadFrame(int f, uchar *b, int Length, int Max)
-{
- if (Length == -1)
- Length = Max; // this means we read up to EOF (see cIndex)
- else if (Length > Max) {
- esyslog("ERROR: frame larger than buffer (%d > %d)", Length, Max);
- Length = Max;
- }
- int r = safe_read(f, b, Length);
- if (r < 0)
- LOG_ERROR;
- return r;
-}
-
// --- cBackTrace ----------------------------------------------------------
#define AVG_FRAME_SIZE 15000 // an assumption about the average frame size
@@ -91,9 +75,6 @@ int cBackTrace::Get(bool Forward)
// (must be larger than MINVIDEODATA - see remux.h)
#define VIDEOBUFSIZE MEGABYTE(1)
-// The maximum size of a single frame:
-#define MAXFRAMESIZE KILOBYTE(192)
-
// The number of frames to back up when resuming an interrupted replay session:
#define RESUMEBACKUP (10 * FRAMESPERSEC)
@@ -644,9 +625,9 @@ bool cDvbPlayer::GetReplayMode(bool &Play, bool &Forward, int &Speed)
// --- cDvbPlayerControl -----------------------------------------------------
-cDvbPlayerControl::cDvbPlayerControl(void)
+cDvbPlayerControl::cDvbPlayerControl(const char *FileName)
+:cControl(player = new cDvbPlayer(FileName))
{
- player = NULL;
}
cDvbPlayerControl::~cDvbPlayerControl()
@@ -659,16 +640,6 @@ bool cDvbPlayerControl::Active(void)
return player && player->Active();
}
-bool cDvbPlayerControl::Start(const char *FileName)
-{
- delete player;
- player = new cDvbPlayer(FileName);
- if (cDevice::PrimaryDevice()->Attach(player))
- return true;
- Stop();
- return false;
-}
-
void cDvbPlayerControl::Stop(void)
{
delete player;
diff --git a/dvbplayer.h b/dvbplayer.h
index b05bcdf..4159025 100644
--- a/dvbplayer.h
+++ b/dvbplayer.h
@@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
- * $Id: dvbplayer.h 1.1 2002/06/16 10:59:14 kls Exp $
+ * $Id: dvbplayer.h 1.2 2002/06/23 10:13:51 kls Exp $
*/
#ifndef __DVBPLAYER_H
@@ -19,11 +19,10 @@ class cDvbPlayerControl : public cControl {
private:
cDvbPlayer *player;
public:
- cDvbPlayerControl(void);
+ cDvbPlayerControl(const char *FileName);
+ // Sets up a player for the given file.
virtual ~cDvbPlayerControl();
bool Active(void);
- bool Start(const char *FileName);
- // Starts replaying the given file.
void Stop(void);
// Stops the current replay session (if any).
void Pause(void);
diff --git a/eitscan.c b/eitscan.c
index f620b09..a275abe 100644
--- a/eitscan.c
+++ b/eitscan.c
@@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
- * $Id: eitscan.c 1.2 2002/06/02 09:02:05 kls Exp $
+ * $Id: eitscan.c 1.3 2002/06/22 13:02:40 kls Exp $
*/
#include "eitscan.h"
@@ -52,7 +52,7 @@ void cEITScanner::Process(void)
cDevice *Device = cDevice::GetDevice(i + 1, MAXPRIORITY + 1);
if (Device) {
if (Device != cDevice::PrimaryDevice() || (cDevice::NumDevices() == 1 && Setup.EPGScanTimeout && now - lastActivity > Setup.EPGScanTimeout * 3600)) {
- if (!(Device->Receiving() || Device->Replaying()/*XXX+ || Device->Transferring()XXX*/)) {
+ if (!(Device->Receiving() || Device->Replaying())) {
int oldCh = lastChannel;
int ch = oldCh + 1;
while (ch != oldCh) {
diff --git a/i18n.c b/i18n.c
index 84164a3..39948c2 100644
--- a/i18n.c
+++ b/i18n.c
@@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
- * $Id: i18n.c 1.91 2002/06/10 16:16:08 kls Exp $
+ * $Id: i18n.c 1.92 2002/06/22 09:26:36 kls Exp $
*
* Translations provided by:
*
@@ -20,6 +20,7 @@
* Greek Dimitrios Dimitrakos <mail@dimitrios.de>
* Swedish Tomas Prybil <tomas@prybil.se>
* Romanian Paul Lacatus <paul@campina.iiruc.ro>
+ * Hungarian Istvan Koenigsberger <istvnko@hotmail.com> and Guido Josten <guido.josten@t-online.de>
*
*/
@@ -83,6 +84,7 @@ const tI18nPhrase Phrases[] = {
"Ellinika",
"Svenska",
"Romaneste",
+ "Magyar",
},
// Menu titles:
{ "VDR",
@@ -99,6 +101,7 @@ const tI18nPhrase Phrases[] = {
"VDR",
"VDR",
"VDR",
+ "VDR",
},
{ "Schedule",
"Programm",
@@ -114,6 +117,7 @@ const tI18nPhrase Phrases[] = {
"Programma",
"Program",
"Program",
+ "Program",
},
{ "Channels",
"Kanäle",
@@ -129,6 +133,7 @@ const tI18nPhrase Phrases[] = {
"Kanalia",
"Kanaler",
"Canale",
+ "Csatornák",
},
{ "Timers",
"Timer",
@@ -144,6 +149,7 @@ const tI18nPhrase Phrases[] = {
"Programmatismos",
"Timers",
"Timere",
+ "Felvétel beprogramozása",
},
{ "Recordings",
"Aufzeichnungen",
@@ -159,6 +165,7 @@ const tI18nPhrase Phrases[] = {
"Egrafes",
"Inspelningar",
"Inregistrari",
+ "Felvett adások",
},
{ "Setup",
"Einstellungen",
@@ -174,6 +181,7 @@ const tI18nPhrase Phrases[] = {
"Rithmisis",
"Inställningar",
"Setari",
+ "Beállítások",
},
{ "Commands",
"Befehle",
@@ -189,6 +197,7 @@ const tI18nPhrase Phrases[] = {
"Entoles",
"Kommandon",
"Comenzi",
+ "Parancsok",
},
{ "Edit channel",
"Kanal editieren",
@@ -204,6 +213,7 @@ const tI18nPhrase Phrases[] = {
"Prosarmoges kanaliou",
"Ändra kanal",
"Editare canale",
+ "Csatornák beállítása",
},
{ "Edit timer",
"Timer editieren",
@@ -219,6 +229,7 @@ const tI18nPhrase Phrases[] = {
"Prosarmoges programmatismou",
"Ändra timer",
"Editare timere",
+ "Felvétel beprogramozásának megváltoztatása",
},
{ "Event",
"Sendung",
@@ -234,6 +245,7 @@ const tI18nPhrase Phrases[] = {
"Ekpompi",
"Sändning",
"Evenimente",
+ "Adás",
},
{ "Summary",
"Inhalt",
@@ -249,6 +261,7 @@ const tI18nPhrase Phrases[] = {
"Periexomeno",
"Sammandrag",
"Cuprins",
+ "Tartalom",
},
{ "Schedule - %s",
"Programm - %s",
@@ -264,6 +277,7 @@ const tI18nPhrase Phrases[] = {
"Programma - %s",
"Program - %s",
"Program - %s",
+ "Program - %s",
},
{ "What's on now?",
"Was läuft jetzt?",
@@ -279,6 +293,7 @@ const tI18nPhrase Phrases[] = {
"Ti pezi tora",
"Vilket program sänds nu?",
"Programul actual?",
+ "Mi megy most?",
},
{ "What's on next?",
"Was läuft als nächstes?",
@@ -294,6 +309,7 @@ const tI18nPhrase Phrases[] = {
"Ti tha peksi meta",
"Vilket är nästa program?",
"Programul urmator?",
+ "Mi következik?",
},
// Button texts (should not be more than 10 characters!):
{ "Edit",
@@ -310,6 +326,7 @@ const tI18nPhrase Phrases[] = {
"Prosarmogi",
"Ändra",
"Modificare",
+ "Beállítani",
},
{ "New",
"Neu",
@@ -325,6 +342,7 @@ const tI18nPhrase Phrases[] = {
"Neo",
"Ny",
"Nou",
+ "Új",
},
{ "Delete",
"Löschen",
@@ -340,6 +358,7 @@ const tI18nPhrase Phrases[] = {
"Swisimo",
"Ta bort",
"Sterge",
+ "Törölni",
},
{ "Mark",
"Markieren",
@@ -355,6 +374,7 @@ const tI18nPhrase Phrases[] = {
"Markarisma",
"Märk",
"Marcheaza",
+ "Megjelölni",
},
{ "On/Off",
"Ein/Aus",
@@ -370,6 +390,7 @@ const tI18nPhrase Phrases[] = {
"Energo/Klisto",
"Pĺ/Av",
"Pornit/Oprit",
+ "Be/Ki",
},
{ "Record",
"Aufnehmen",
@@ -385,6 +406,7 @@ const tI18nPhrase Phrases[] = {
"Egrafi",
"Inspelning",
"Inregistrare",
+ "Felvenni",
},
{ "Play",
"Wiedergabe",
@@ -400,6 +422,7 @@ const tI18nPhrase Phrases[] = {
"Anametadosi",
"Spela upp",
"Redare",
+ "Lejátszani",
},
{ "Rewind",
"Anfang",
@@ -415,6 +438,7 @@ const tI18nPhrase Phrases[] = {
"Arxi",
"Ĺterspolning",
"Inapoi",
+ "Vissza az elejére",
},
{ "Button$Stop",
"Beenden",
@@ -430,6 +454,7 @@ const tI18nPhrase Phrases[] = {
"Terma",
"Stopp",
"Stop",
+ "Stop",
},
{ "Resume",
"Weiter",
@@ -445,6 +470,7 @@ const tI18nPhrase Phrases[] = {
"Sinexia",
"Fortsätt",
"Reia",
+ "Tovább",
},
{ "Summary",
"Inhalt",
@@ -460,6 +486,7 @@ const tI18nPhrase Phrases[] = {
"Periexomeno",
"Sammandrag",
"Cuprins",
+ "Tartalom",
},
{ "Open",
"Öffnen",
@@ -475,6 +502,7 @@ const tI18nPhrase Phrases[] = {
"Anigma",
"Öppna",
"Deschide",
+ "Kinyitni",
},
{ "Switch",
"Umschalten",
@@ -490,6 +518,7 @@ const tI18nPhrase Phrases[] = {
"Alagi",
"Byt",
"Schimba",
+ "Átkapcsolni",
},
{ "Now",
"Jetzt",
@@ -505,6 +534,7 @@ const tI18nPhrase Phrases[] = {
"Tora",
"Nu",
"Acum",
+ "Most",
},
{ "Next",
"Nächste",
@@ -520,6 +550,7 @@ const tI18nPhrase Phrases[] = {
"Epomeno",
"Nästa",
"Urmator",
+ "Következö",
},
{ "Button$Schedule",
"Programm",
@@ -535,6 +566,7 @@ const tI18nPhrase Phrases[] = {
"Programma",
"Program",
"Program",
+ "Program",
},
{ "Language",
"Sprache",
@@ -550,6 +582,7 @@ const tI18nPhrase Phrases[] = {
"Glosa",
"Sprĺk",
"Limba",
+ "Nyelv",
},
{ "Eject",
"Auswerfen",
@@ -565,6 +598,7 @@ const tI18nPhrase Phrases[] = {
"Apovoli",
"Mata ut",
"Ejecteaza",
+ "Kidobni",
},
{ "ABC/abc",
"ABC/abc",
@@ -580,6 +614,7 @@ const tI18nPhrase Phrases[] = {
"ABC/abc",
"ABC/abc",
"ABC/abc",
+ "ABC/abc",
},
{ "Insert",
"Einfügen",
@@ -595,6 +630,7 @@ const tI18nPhrase Phrases[] = {
"Isodos",
"Infoga",
"Insereaza",
+ "Beilleszteni",
},
{ "Overwrite",
"Überschreiben",
@@ -610,6 +646,7 @@ const tI18nPhrase Phrases[] = {
"Epanagrafi",
"Skriv över",
"Suprascrie",
+ "Átírni",
},
// Confirmations:
{ "Delete channel?",
@@ -626,6 +663,7 @@ const tI18nPhrase Phrases[] = {
"Na sviso to kanali?",
"Ta bort kanalen?",
"Sterg canalul?",
+ "Csatorna törlése?",
},
{ "Delete timer?",
"Timer löschen?",
@@ -641,6 +679,7 @@ const tI18nPhrase Phrases[] = {
"Svisimo tou programmitismou?",
"Ta bort timern?",
"Sterg timer-ul?",
+ "Felvétel beprogramozásának törlése?",
},
{ "Delete recording?",
"Aufzeichnung löschen?",
@@ -656,6 +695,7 @@ const tI18nPhrase Phrases[] = {
"Svisimo tis egrafis?",
"Ta bort inspelningen?",
"Sterg inregistrarea?",
+ "Felvétel törlése?",
},
{ "Timer still recording - really delete?",
"Timer zeichnet auf - trotzdem löschen?",
@@ -671,6 +711,7 @@ const tI18nPhrase Phrases[] = {
"Ginete akoma programmatismeni egrafi - na svisti sigoura?",
"Timerstyrd inspelning pĺgĺr - Avbryta ändĺ?",
"Timer-ul in inregistrare - sterg?",
+ "Felvétel folyamatban van - mégis törölni?",
},
{ "Stop recording?",
"Aufzeichnung beenden?",
@@ -686,6 +727,7 @@ const tI18nPhrase Phrases[] = {
"Akirosi egrafis?",
"Stanna inspelning?",
"Opresc inregistrarea?",
+ "Felvétel befejezni?",
},
{ "on primary interface",
"auf dem primären Interface",
@@ -701,6 +743,7 @@ const tI18nPhrase Phrases[] = {
"stin protevon karta",
"frĺn det första enheten?",
"pe prima interfata",
+ "az elsö kártyán",
},
{ "Cancel editing?",
"Schneiden abbrechen?",
@@ -716,6 +759,7 @@ const tI18nPhrase Phrases[] = {
"Akirosi alagon?",
"Avbryta editeringen?",
"Opresc editarea?",
+ "Vágást befejezni?",
},
{ "Really restart?",
"Wirklich neu starten?",
@@ -731,6 +775,7 @@ const tI18nPhrase Phrases[] = {
"Na gini sigoura epanekinisi?",
"Vill du verkligen starta om?",
"Esti sigur de repornire?",
+ "Tényleg újraindítani?",
},
{ "Recording - restart anyway?",
"Aufnahme läuft - trotzdem neu starten?",
@@ -746,6 +791,7 @@ const tI18nPhrase Phrases[] = {
"Ginete egrafi - na gini epanekinisi sigoura?",
"Inspelning pĺgĺr, vill du starta om i alla fall?",
"In inregistrare - repornesc?",
+ "Felvétel folyamatban van - mégis újraindítani?",
},
{ "Recording - shut down anyway?",
"Aufnahme läuft - trotzdem ausschalten?",
@@ -761,6 +807,7 @@ const tI18nPhrase Phrases[] = {
"Ginete egrafi - na stamatisi i litourgia sigoura?",
"Inspelning pĺgĺr, vill du avbryta i alla fall?",
"In inregistrare - opresc?",
+ "Felvétel folyamatban van - mégis kikapcsolni?",
},
{ "Recording in %d minutes, shut down anyway?",
"Aufnahme in %d Minuten - trotzdem ausschalten?",
@@ -776,6 +823,7 @@ const tI18nPhrase Phrases[] = {
"Anamenete egrafi se %d lepta - na stamatisi i litourgia sigoura?",
"Inspelning startar om %d minuter, vill du avsluta?",
"Inregistrez in %d minute, opresc?",
+ "Felvétel %d perc mulva kezdödik - mégis kikapcsolni?",
},
{ "Press any key to cancel shutdown",
"Taste drücken um Shutdown abzubrechen",
@@ -791,6 +839,7 @@ const tI18nPhrase Phrases[] = {
"Piese ena pliktro na stamatisi to katevasma",
"Tryck valfri knapp för att avbryta nedstängning",
"Apasa orice tasta pentru a anula inchiderea",
+ "Nyomj egy gombot a leállás megállításához",
},
// Channel parameters:
{ "Name",
@@ -807,6 +856,7 @@ const tI18nPhrase Phrases[] = {
"Onoma",
"Namn",
"Nume",
+ "Név",
},
{ "Frequency",
"Frequenz",
@@ -822,6 +872,7 @@ const tI18nPhrase Phrases[] = {
"Sixnotita",
"Frekvens",
"Frecventa",
+ "Frekvencia",
},
{ "Polarization",
"Polarisation",
@@ -837,6 +888,7 @@ const tI18nPhrase Phrases[] = {
"Polosi",
"Polarisation",
"Polarizare",
+ "Polarizáció",
},
{ "DiSEqC",
"DiSEqC",
@@ -852,6 +904,7 @@ const tI18nPhrase Phrases[] = {
"DiSEqC",
"DiSEqC",
"DiSEqC",
+ "DiSEqC",
},
{ "Srate",
"Srate",
@@ -867,6 +920,7 @@ const tI18nPhrase Phrases[] = {
"Srate",
"Srate",
"Rata simboluri",
+ "Srate",
},
{ "Vpid",
"Vpid",
@@ -882,6 +936,7 @@ const tI18nPhrase Phrases[] = {
"Vpid",
"Vpid",
"PID Video",
+ "Vpid",
},
{ "Apid1",
"Apid1",
@@ -897,6 +952,7 @@ const tI18nPhrase Phrases[] = {
"Apid1",
"Apid1",
"PID Audio (1)",
+ "Apid1",
},
{ "Apid2",
"Apid2",
@@ -912,6 +968,7 @@ const tI18nPhrase Phrases[] = {
"Apid2",
"Apid2",
"PID Audio (2)",
+ "Apid2",
},
{ "Dpid1",
"Dpid1",
@@ -927,6 +984,7 @@ const tI18nPhrase Phrases[] = {
"Dpid1",
"Dpid1",
"PID AC3 (1)",
+ "Dpid1",
},
{ "Dpid2",
"Dpid2",
@@ -942,6 +1000,7 @@ const tI18nPhrase Phrases[] = {
"Dpid2",
"Dpid2",
"PID AC3 (2)",
+ "Dpid2",
},
{ "Tpid",
"Tpid",
@@ -957,6 +1016,7 @@ const tI18nPhrase Phrases[] = {
"Tpid",
"Tpid",
"PID Teletext",
+ "Tpid",
},
{ "CA",
"CA",
@@ -972,6 +1032,7 @@ const tI18nPhrase Phrases[] = {
"CA",
"CA",
"Criptare",
+ "CA",
},
{ "Pnr",
"Pnr",
@@ -987,6 +1048,7 @@ const tI18nPhrase Phrases[] = {
"Pnr",
"Pnr",
"Nr. Prog.",
+ "Pnr",
},
// Timer parameters:
{ "Active",
@@ -1003,6 +1065,7 @@ const tI18nPhrase Phrases[] = {
"Energo",
"Aktiv",
"Activ",
+ "Aktiv",
},
{ "Channel",
"Kanal",
@@ -1018,6 +1081,7 @@ const tI18nPhrase Phrases[] = {
"Kanali",
"Kanal",
"Canal",
+ "Csatorna",
},
{ "Day",
"Tag",
@@ -1033,6 +1097,7 @@ const tI18nPhrase Phrases[] = {
"Imera",
"Dag",
"Ziua",
+ "Nap",
},
{ "Start",
"Anfang",
@@ -1048,6 +1113,7 @@ const tI18nPhrase Phrases[] = {
"Arxi",
"Börjar",
"Start",
+ "Kezdet",
},
{ "Stop",
"Ende",
@@ -1063,6 +1129,7 @@ const tI18nPhrase Phrases[] = {
"Telos",
"Slutar",
"Stop",
+ "Vége",
},
{ "Priority",
"Priorität",
@@ -1078,6 +1145,7 @@ const tI18nPhrase Phrases[] = {
"Protereotita",
"Prioritet",
"Prioritate",
+ "Prioritás",
},
{ "Lifetime",
"Lebensdauer",
@@ -1093,6 +1161,7 @@ const tI18nPhrase Phrases[] = {
"Xronos Zois",
"Speltid",
"Durata",
+ "Élettartam",
},
{ "File",
"Datei",
@@ -1108,6 +1177,7 @@ const tI18nPhrase Phrases[] = {
"Arxeio",
"Filnamn",
"Fisier",
+ "File",
},
{ "First day",
"Erster Tag",
@@ -1123,6 +1193,7 @@ const tI18nPhrase Phrases[] = {
"Proti mera",
"Första dag",
"Prima zi",
+ "Elsö nap",
},
// Error messages:
{ "Channel is being used by a timer!",
@@ -1139,6 +1210,7 @@ const tI18nPhrase Phrases[] = {
"To kanali xrisimopiite apo programmatismeni thesi",
"Kanalen används av en timer!",
"Canalul este utilizat de un timer!",
+ "Csatornát más használja!",
},
{ "Can't switch channel!",
"Kanal kann nicht umgeschaltet werden!",
@@ -1154,6 +1226,7 @@ const tI18nPhrase Phrases[] = {
"Den mporo na pao sto kanali!",
"Omöjligt att byta kanal!",
"Nu pot comuta canalul!",
+ "Csatornát nem lehet átkapcsolni!",
},
{ "Timer is recording!",
"Timer zeichnet gerade auf!",
@@ -1169,6 +1242,7 @@ const tI18nPhrase Phrases[] = {
"Ginete progrmamatismeni egrafi!",
"Timerstyrd inspelning pĺgĺr!",
"Timer-ul este in inregistrare!",
+ "Felvétel folyamatban van!",
},
{ "Error while accessing recording!",
"Fehler beim Ansprechen der Aufzeichnung!",
@@ -1184,6 +1258,7 @@ const tI18nPhrase Phrases[] = {
"Lathos stin evresi tis egrafis!",
"Det gĺr inte att läsa inspelningen",
"Eroare in timpul accesarii inregistrarii",
+ "Hiba a felvétel hozzáférésénél",
},
{ "Error while deleting recording!",
"Fehler beim Löschen der Aufzeichnung!",
@@ -1199,6 +1274,7 @@ const tI18nPhrase Phrases[] = {
"Lathos stin prospathia na svisti i egrafi!",
"Det gĺr inte att ta bort inspelningen",
"Eroare in timpul stergerii inregistrarii!",
+ "Hiba a felvétel törlésénél!",
},
{ "*** Invalid Channel ***",
"*** Ungültiger Kanal ***",
@@ -1214,6 +1290,7 @@ const tI18nPhrase Phrases[] = {
"*** Kanali akiro ***",
"*** Felaktig kanal ***",
"*** Canal invalid ***",
+ "*** Érvénytelen csatorna ***",
},
{ "No free DVB device to record!",
"Keine freie DVB-Karte zum Aufnehmen!",
@@ -1229,6 +1306,7 @@ const tI18nPhrase Phrases[] = {
"Den iparxi elevteri DVB Karta gia egrafi!",
"Det finns ingen ledig DVB enhet för inspelning!",
"Nu mai sunt dispozitive DVB pentru inregistrare!",
+ "Nincs szabad DVB kártya a felvételhez!",
},
{ "Channel locked (recording)!",
"Kanal blockiert (zeichnet auf)!",
@@ -1244,6 +1322,7 @@ const tI18nPhrase Phrases[] = {
"To kanali ine mplokarismeno (Ginete egrafi)!",
"Kanalen är lĺst (inspelning pĺgĺr)!",
"Canal blocat (inregistrare)!",
+ "Csatorna hozzáférhetetlen (felvétel)!",
},
{ "Can't start Transfer Mode!",
"Transfer-Mode kann nicht gestartet werden!",
@@ -1259,6 +1338,7 @@ const tI18nPhrase Phrases[] = {
"Den mpori na arxisi to Transfer-Mode!",
"Kan inte starta Transfer Mode!",
"Nu pot porni Modul de Transfer!",
+ "Transfer-Mode nem indítható!",
},
{ "Can't start editing process!",
"Schnitt kann nicht gestartet werden!",
@@ -1274,6 +1354,7 @@ const tI18nPhrase Phrases[] = {
"Den mpori na arxisi to kopsimo tis tenias!",
"Kan inte starta editering!",
"Nu pot porni procesul de editare!",
+ "A vágás nem indítható!",
},
{ "Editing process already active!",
"Schnitt bereits aktiv!",
@@ -1289,6 +1370,7 @@ const tI18nPhrase Phrases[] = {
"To kopsimo ti tenias ini idi se litourgia!",
"Editering är redan aktiv!",
"Procesul de editare este activ!",
+ "A vágás már aktivált!",
},
{ "Can't shutdown - option '-s' not given!",
"Shutdown unmöglich - Option '-s' fehlt!",
@@ -1304,6 +1386,7 @@ const tI18nPhrase Phrases[] = {
"Den mporo na kliso ton ipologisti. Lipi i parametros '-s'!",
"Kan inte avsluta, mĺste använda flagga '-s'",
"Nu pot opri calculatorul - vezi optiunea '-s'",
+ "A leállítás nem lehetséges - Opció '-s' hiányzik!",
},
{ "Low disk space!",
"Platte beinahe voll!",
@@ -1319,6 +1402,7 @@ const tI18nPhrase Phrases[] = {
"O Skliros kontevi na gemisi!",
"Lĺgt diskutrymme!",
"Spatiu scazut pe disc!",
+ "A merev lemez majdnem tele!",
},
// Setup pages:
{ "OSD",
@@ -1335,6 +1419,7 @@ const tI18nPhrase Phrases[] = {
"OSD",
"OSD",
"OSD",
+ "OSD",
},
{ "EPG",
"EPG",
@@ -1350,6 +1435,7 @@ const tI18nPhrase Phrases[] = {
"EPG",
"Elektronisk programguide",
"EPG",
+ "EPG",
},
{ "DVB",
"DVB",
@@ -1365,6 +1451,7 @@ const tI18nPhrase Phrases[] = {
"DVB",
"DVB",
"Placa DVB",
+ "DVB",
},
{ "LNB",
"LNB",
@@ -1380,6 +1467,7 @@ const tI18nPhrase Phrases[] = {
"LNB",
"LNB",
"LNB",
+ "LNB",
},
{ "CICAM",
"CICAM",
@@ -1395,6 +1483,7 @@ const tI18nPhrase Phrases[] = {
"CICAM",
"CICAM",
"Acces conditionat",
+ "CICAM",
},
{ "Recording",
"Aufnahme",
@@ -1410,6 +1499,7 @@ const tI18nPhrase Phrases[] = {
"Egrafi",
"Inspelning",
"Inregistrare",
+ "Felvétel",
},
{ "Replay",
"Wiedergabe",
@@ -1425,6 +1515,7 @@ const tI18nPhrase Phrases[] = {
"Anametadosi",
"Repris",
"Redare",
+ "Lejátszás",
},
{ "Miscellaneous",
"Sonstiges",
@@ -1440,6 +1531,7 @@ const tI18nPhrase Phrases[] = {
"Diafora",
"Diverse",
"Diverse",
+ "Egyéb",
},
{ "Plugins",
"Plugins",
@@ -1453,6 +1545,9 @@ const tI18nPhrase Phrases[] = {
"Plugins",
"Plugins",
"Plugins",
+ "Plugins",
+ "Plugins",
+ "Plugins",
},
{ "Plugin",
"Plugin",
@@ -1466,6 +1561,9 @@ const tI18nPhrase Phrases[] = {
"Plugin",
"Plugin",
"Plugin",
+ "Plugin",
+ "Plugin",
+ "Plugin",
},
{ "Restart",
"Neustart",
@@ -1481,6 +1579,7 @@ const tI18nPhrase Phrases[] = {
"Epanekinisi",
"Omstart",
"Restart",
+ "Ůjraindítás",
},
// Setup parameters:
{ "Setup.OSD$Language",
@@ -1497,6 +1596,7 @@ const tI18nPhrase Phrases[] = {
"Glosa",
"Sprĺk",
"Limba OSD",
+ "Nyelv",
},
{ "Setup.OSD$Width",
"Breite",
@@ -1512,6 +1612,7 @@ const tI18nPhrase Phrases[] = {
"Makros",
"Bredd",
"Latime OSD",
+ "Szélesség",
},
{ "Setup.OSD$Height",
"Höhe",
@@ -1527,6 +1628,7 @@ const tI18nPhrase Phrases[] = {
"Ipsos",
"Höjd",
"Inaltime OSD",
+ "Magasság",
},
{ "Setup.OSD$Message time (s)",
"Anzeigedauer für Nachrichten (s)",
@@ -1542,6 +1644,7 @@ const tI18nPhrase Phrases[] = {
"Xronos endiksis minimaton (d)",
"Tid för meddelanden (sek)",
"Timp afisare mesaj (sec)",
+ "Információ feltüntetésének idötartama",
},
{ "Setup.OSD$Channel info position",
"Kanal-Info Position",
@@ -1557,6 +1660,7 @@ const tI18nPhrase Phrases[] = {
"Thesi Pliroforias kanalion",
"Placering av kanalinformation",
"Pozitie info canal",
+ "Csatorna-Infó poziciója",
},
{ "Setup.OSD$Info on channel switch",
"Info beim Kanalwechsel",
@@ -1572,6 +1676,7 @@ const tI18nPhrase Phrases[] = {
"Plirofories stin alagi kanaliou",
"Information vid kanalbyte",
"Info despre comutare canal",
+ "Infó a csatorna váltásánál",
},
{ "Setup.OSD$Scroll pages",
"Seitenweise scrollen",
@@ -1587,6 +1692,7 @@ const tI18nPhrase Phrases[] = {
"Scroll selidas",
"Bläddra sidor",
"Deruleaza pagini",
+ "Oldalanként léptetmi",
},
{ "Setup.OSD$Sort timers",
"Timer sortieren",
@@ -1602,6 +1708,7 @@ const tI18nPhrase Phrases[] = {
"Organosi programmatismenon",
"Sortera timers",
"Sortare timere",
+ "A beprogramozott felvételek elrendezése",
},
{ "Setup.OSD$Recording directories",
"Aufnahmeverzeichnisse",
@@ -1617,6 +1724,7 @@ const tI18nPhrase Phrases[] = {
"Fakeli egrafon",
"Kataloger för inspelningar",
"Directoare inregistrari",
+ "Felvételek listája",
},
{ "Setup.EPG$EPG scan timeout (h)",
"Zeit bis EPG Scan (h)",
@@ -1632,6 +1740,7 @@ const tI18nPhrase Phrases[] = {
"Xronos mexri sarosi EPG se Ores",
"EPG sökning timeout",
"Timeout EPG",
+ "Fennmaradt idö az EPG-g (h)",
},
{ "Setup.EPG$EPG bugfix level",
"EPG Fehlerbereinigung",
@@ -1647,6 +1756,7 @@ const tI18nPhrase Phrases[] = {
"EPG Bugfix Vathmos",
"Nivĺ för EPG bugfix",
"Nivel corectie EPG",
+ "EPG hibaelhárítás",
},
{ "Setup.EPG$Set system time",
"Systemzeit stellen",
@@ -1662,6 +1772,7 @@ const tI18nPhrase Phrases[] = {
"Sintonismos Oras ipologosti",
"Ställ in systemtid",
"Seteaza ceasul sistem",
+ "Az idö beállítása",
},
{ "Setup.EPG$Use time from transponder",
"Transponder für Systemzeit",
@@ -1677,6 +1788,7 @@ const tI18nPhrase Phrases[] = {
"Transponder gia sintonismo tis oras",
"Använd klockan frĺn fransponder",
"Preia ceasul din transponder",
+ "Idöhöz tartozó Transponder",
},
{ "Setup.DVB$Primary DVB interface",
"Primäres DVB Interface",
@@ -1692,6 +1804,7 @@ const tI18nPhrase Phrases[] = {
"Protevon DVB karta",
"Primär DVB enhet",
"Placa DVB primara",
+ "Elsö DVB interface",
},
{ "Setup.DVB$Video format",
"Video Format",
@@ -1707,6 +1820,7 @@ const tI18nPhrase Phrases[] = {
"Video Format",
"Video format",
"Format Video",
+ "Video formátum",
},
{ "Setup.LNB$SLOF (MHz)",
"SLOF (MHz)",
@@ -1722,6 +1836,7 @@ const tI18nPhrase Phrases[] = {
"SLOF (MHz)",
"SLOF (MHz)",
"SLOF (MHz)",
+ "SLOF (MHz)",
},
{ "Setup.LNB$Low LNB frequency (MHz)",
"Untere LNB-Frequenz (MHz)",
@@ -1737,6 +1852,7 @@ const tI18nPhrase Phrases[] = {
"Kato LNB-Sixnotita (MHz)",
"Undre LNB frekvens (MHz)",
"Frecvnta LO LNB (Mhz)",
+ "Alsó LNB-frekvencia (MHZ)",
},
{ "Setup.LNB$High LNB frequency (MHz)",
"Obere LNB-Frequenz (MHz)",
@@ -1752,6 +1868,7 @@ const tI18nPhrase Phrases[] = {
"Ano LNB-Sixnotita (MHz)",
"Övre LNB frekvens (MHz)",
"Feecventa HI LNB (MHz)",
+ "Felsö LNB-frekvencia (MHZ)",
},
{ "Setup.LNB$Use DiSEqC",
"DiSEqC benutzen",
@@ -1767,6 +1884,7 @@ const tI18nPhrase Phrases[] = {
"Energopiisi DiSEqC",
"Använd DiSEqC",
"Utilizez DiSEqC",
+ "DiSEqC használata",
},
{ "Setup.CICAM$CICAM DVB",
"CICAM DVB",
@@ -1782,6 +1900,7 @@ const tI18nPhrase Phrases[] = {
"CICAM DVB",
"CICAM DVB",
"Setare acces conditional",
+ "CICAM DVB",
},
{ "Setup.Recording$Margin at start (min)",
"Zeitpuffer bei Anfang (min)",
@@ -1797,6 +1916,7 @@ const tI18nPhrase Phrases[] = {
"Prosthetos xronos prin arxi (lepta)",
"Marginal för start (min)",
"Margine la pornire (min)",
+ "Idöeltolódás a kezdésnél (min)",
},
{ "Setup.Recording$Margin at stop (min)",
"Zeitpuffer bei Ende (min)",
@@ -1812,6 +1932,7 @@ const tI18nPhrase Phrases[] = {
"Prosthetos xronos sto telos (lepta)",
"Marginal för stopp (min)",
"Margine la oprire (min)",
+ "Idöeltolódás a befejezésnél",
},
{ "Setup.Recording$Primary limit",
"Primär-Limit",
@@ -1827,6 +1948,7 @@ const tI18nPhrase Phrases[] = {
"Protevon limit",
"Primär gräns",
"Limita Primara",
+ "Primér-határ",
},
{ "Setup.Recording$Default priority",
"Default Priorität",
@@ -1842,6 +1964,7 @@ const tI18nPhrase Phrases[] = {
"Protereotita",
"Normal prioritet",
"Prioritate implicita",
+ "Default priority",
},
{ "Setup.Recording$Default lifetime (d)",
"Default Lebensdauer (d)",
@@ -1857,6 +1980,7 @@ const tI18nPhrase Phrases[] = {
"Xronos zois",
"Normal livstid",
"Durata predefinita",
+ "Default élettartam",
},
{ "Setup.Recording$Use episode name",
"Episodenname verwenden",
@@ -1872,6 +1996,7 @@ const tI18nPhrase Phrases[] = {
"Xrisimopiisi onomatos episodiou",
"Använd episodnamn",
"Utilizeaza numele episodului",
+ "Epizódnév felhasználása",
},
{ "Setup.Recording$Mark instant recording",
"Direktaufzeichnung markieren",
@@ -1887,6 +2012,7 @@ const tI18nPhrase Phrases[] = {
"Markarisma apevthias egrafis",
"Märk direktinspelning",
"Inregistrare imediata",
+ "Direktfelvétel megjelölése",
},
{ "Setup.Recording$Name instant recording",
"Direktaufzeichnung benennen",
@@ -1902,6 +2028,7 @@ const tI18nPhrase Phrases[] = {
"eponomasi apevthias egrafis",
"Namnge direktinspelning",
"Nume inregistrare imediata",
+ "Direktfelvétel megnevezése",
},
{ "Setup.Recording$Instant rec. time (min)",
"Dauer der Direktaufzeichnung (min)",
@@ -1917,6 +2044,7 @@ const tI18nPhrase Phrases[] = {
"",//TODO
"Direktinspelning längd (min)",
"Timpul de inregistarea imediata (min)",
+ "Felvétel idötartama",
},
{ "Setup.Recording$Record Dolby Digital",
"Dolby Digital Ton aufzeichnen",
@@ -1932,6 +2060,7 @@ const tI18nPhrase Phrases[] = {
"Egrafi tou Dolby Digital ixou",
"Spela in ljud med Dolby Digital",
"Inregistreaza Dolby Digital",
+ "Dolby Digitál felvétel",
},
{ "Setup.Recording$Max. video file size (MB)",
"Max. Video Dateigröße (MB)",
@@ -1947,6 +2076,7 @@ const tI18nPhrase Phrases[] = {
"Megisto megethos arxeiou (MB)",
"Maximal filstorlek för inspelning (MB)",
"Dimensiune maxima a fisierului video (MB)",
+ "Max. video File-terjedelem (MB)",
},
{ "Setup.Recording$Split edited files",
"Editierte Dateien aufteilen",
@@ -1962,6 +2092,7 @@ const tI18nPhrase Phrases[] = {
"Diamelisma epeksergasm. arxeion",
"Dela upp editerade filer",
"Separare fisiere editate",
+ "Feldolgozott File-k felosztása",
},
{ "Setup.Replay$Multi speed mode",
"MultiSpeed Modus",
@@ -1977,6 +2108,7 @@ const tI18nPhrase Phrases[] = {
"Multispeed modus",
"Multispeed mode",
"Mod multi-rata",
+ "MultiSpeed funkció",
},
{ "Setup.Replay$Show replay mode",
"Wiedergabestatus anzeigen",
@@ -1992,6 +2124,7 @@ const tI18nPhrase Phrases[] = {
"Endiksi status anametadosis",
"Visa uppspelnings mode",
"Afiseaza modul de redare",
+ "Lejátszás feltüntetése",
},
{ "Setup.Miscellaneous$Min. event timeout (min)",
"Mindest Event Pause (min)",
@@ -2007,6 +2140,7 @@ const tI18nPhrase Phrases[] = {
"Elaxistos Xronos paremvolis (lepta)",
"Minsta händelse-pause (min)",
"MinEventTimeout (min)",
+ "Min. esemény szünet (min)",
},
{ "Setup.Miscellaneous$Min. user inactivity (min)",
"Mindest Benutzer-Inaktivität (min)",
@@ -2022,6 +2156,7 @@ const tI18nPhrase Phrases[] = {
"Elaxistos xronos mi xrisis (lepta)",
"Minsta anändar-inaktivitet (min)",
"Durata minima de inactivitate (min)",
+ "Min. kezelési aktivitás (min)",
},
{ "Setup.Miscellaneous$SVDRP timeout (s)",
"SVDRP Timeout (s)",
@@ -2037,6 +2172,7 @@ const tI18nPhrase Phrases[] = {
"SVDRP Timeout (d)",
"SVDRP Timeout (d)",
"Timeout SVDRP (sec)",
+ "SVDRP Timeout (s)",
},
// The days of the week:
{ "MTWTFSS",
@@ -2053,6 +2189,7 @@ const tI18nPhrase Phrases[] = {
"DTTPPSK",
"MTOTFLS",
"LMMJVSD",
+ "HKSCPSV",
},
{ "MonTueWedThuFriSatSun", // must all be 3 letters!
"MonDieMitDonFreSamSon",
@@ -2068,6 +2205,7 @@ const tI18nPhrase Phrases[] = {
"DevTriTetPemParSavKir",
"MĺnTisOnsTorFreLörSön",
"LunMarMieJoiVinSimDum",
+ "HétKedSzeCsüPénSzoVas",
},
// The allowed characters in strings:
{ " abcdefghijklmnopqrstuvwxyz0123456789-.#~",
@@ -2084,6 +2222,7 @@ const tI18nPhrase Phrases[] = {
"",// TODO
" abcdefghijklmnopqrstuvxyzĺäö0123456789-.#~",
" abcdefghijklmnopqrstuvwxyz0123456789-.#~",
+ " aábcdeéfghijklmnoóöpqrstuúüvwxyz0123456789-.,#~",
},
// Learning keys:
{ "Learning Remote Control Keys",
@@ -2100,6 +2239,7 @@ const tI18nPhrase Phrases[] = {
"Ekmathisi Remote Control",
"Inlärning av fjärrkontrollsknappar",
"Invatare taste telecomanda",
+ "Távirányító betanítása",
},
{ "Phase 1: Detecting RC code type",
"Phase 1: FB Code feststellen",
@@ -2115,6 +2255,7 @@ const tI18nPhrase Phrases[] = {
"Phasi 1: Dilosi RC Code",
"Steg1: identifiering av RC kod",
"Faza 1: Detectie tip telecomanda",
+ "Elsö lépés: távirányító kódjának meghatározása",
},
{ "Press any key on the RC unit",
"Eine Taste auf der FB drücken",
@@ -2130,6 +2271,7 @@ const tI18nPhrase Phrases[] = {
"Pata ena pliktro sto RC",
"Tryck valfri tangent pĺ fjärrkontrollen",
"Apasati o tasta pe telecomanda",
+ "Nyomjon meg egy gombot a távirányítón",
},
{ "RC code detected!",
"FB Code erkannt!",
@@ -2145,6 +2287,7 @@ const tI18nPhrase Phrases[] = {
"Evresi RC Code!",
"RC koden detekterad!",
"S-a detectat tipul telecomenzii!",
+ "Távirányító kódja felismerve!",
},
{ "Do not press any key...",
"Keine Taste drücken...",
@@ -2160,6 +2303,7 @@ const tI18nPhrase Phrases[] = {
"Min patas Pliktra...",
"Tryck inte pĺ nĺgon knapp...",
"Nu apasati nicio tasta...",
+ "Ne nyomjon meg gombot...",
},
{ "Phase 2: Learning specific key codes",
"Phase 2: Einzelne Tastencodes lernen",
@@ -2175,6 +2319,7 @@ const tI18nPhrase Phrases[] = {
"Fasi 2: Ekmathisi memonomenon kodikon pliktron",
"Fas 2: Inlärning av specifika knapp koder",
"Faza 2: Invatarea codurilor specifice tastelor",
+ "Második lépés: az egyes gombok betanítása",
},
{ "Press key for '%s'",
"Taste für '%s' drücken",
@@ -2190,6 +2335,7 @@ const tI18nPhrase Phrases[] = {
"Pata to pliktro gia '%s'",
"Tryck pĺ knappen för '%s'",
"Apasati tasta pentru '%s'",
+ "'%s' gomb megnyomása",
},
{ "Press 'Up' to confirm",
"'Auf' drücken zum Bestätigen",
@@ -2205,6 +2351,7 @@ const tI18nPhrase Phrases[] = {
"Pata 'pano' gia apodoxi",
"Tryck 'Upp' för att bekräfta",
"Apsati 'Sus' pentru confirmare",
+ "'Fel' megnyomása az elfogadáshoz",
},
{ "Press 'Down' to continue",
"'Ab' drücken zum Weitermachen",
@@ -2220,6 +2367,7 @@ const tI18nPhrase Phrases[] = {
"Pata 'kato' gia sinexia",
"Tryck 'Ner' för att bekräfta",
"Apasati jos pentru continuare",
+ "'Le' megnyomása a folytatáshoz",
},
{ "(press 'Up' to go back)",
"('Auf' drücken um zurückzugehen)",
@@ -2235,6 +2383,7 @@ const tI18nPhrase Phrases[] = {
"(Pata 'pano' gia na pas piso)",
"(Tryck 'Upp' för att backa)",
"(Apsati 'Sus' pentru revenire)",
+ "(´Fel' megnyomása a visszatéréshez)",
},
{ "(press 'Down' to end key definition)",
"('Ab' drücken zum Beenden)",
@@ -2250,6 +2399,7 @@ const tI18nPhrase Phrases[] = {
"(Pata 'Kato' gia termatismo)",
"(Tryck 'Ner' för att avsluta knapp definition)",
"(Apasati 'Jos' pentru terminare)",
+ "('Le' megnyomása a befejezéshez)",
},
{ "Phase 3: Saving key codes",
"Phase 3: Codes abspeichern",
@@ -2265,6 +2415,7 @@ const tI18nPhrase Phrases[] = {
"Fasi 3: Apothikevsi kodikon",
"Fas 3: Spara knappkoder",
"Faza 3: Salvarea codurilor de taste",
+ "Harmadik lépés: kód mentése",
},
{ "Press 'Up' to save, 'Down' to cancel",
"'Auf' speichert, 'Ab' bricht ab",
@@ -2280,6 +2431,7 @@ const tI18nPhrase Phrases[] = {
"'kato' apothikevsi, 'Pano' akirosi",
"Tryck 'Upp' för att spara, 'Ner' för att avsluta",
"Apsati 'Sus' pentru salvare, 'Jos' pentru anulare",
+ "'Fel' mentés, 'Le´ mégse",
},
// Key names:
{ "Up",
@@ -2296,6 +2448,7 @@ const tI18nPhrase Phrases[] = {
"Pano",
"Upp",
"Sus",
+ "Fel",
},
{ "Down",
"Ab",
@@ -2311,6 +2464,7 @@ const tI18nPhrase Phrases[] = {
"Kato",
"Ner",
"Jos",
+ "Le",
},
{ "Menu",
"Menü",
@@ -2326,6 +2480,7 @@ const tI18nPhrase Phrases[] = {
"Menou",
"Meny",
"Meniu",
+ "Menü",
},
{ "Ok",
"Ok",
@@ -2341,6 +2496,7 @@ const tI18nPhrase Phrases[] = {
"Ok",
"Ok",
"Ok",
+ "Ok",
},
{ "Back",
"Zurück",
@@ -2356,6 +2512,7 @@ const tI18nPhrase Phrases[] = {
"Piso",
"Tillbaka",
"Inapoi",
+ "Vissza",
},
{ "Left",
"Links",
@@ -2371,6 +2528,7 @@ const tI18nPhrase Phrases[] = {
"Aristera",
"Vänster",
"Stinga",
+ "Balra",
},
{ "Right",
"Rechts",
@@ -2386,6 +2544,7 @@ const tI18nPhrase Phrases[] = {
"Deksia",
"Höger",
"Dreapta",
+ "Jobbra",
},
{ "Red",
"Rot",
@@ -2401,6 +2560,7 @@ const tI18nPhrase Phrases[] = {
"Kokino",
"Röd",
"Rosu",
+ "Piros",
},
{ "Green",
"Grün",
@@ -2416,6 +2576,7 @@ const tI18nPhrase Phrases[] = {
"Prasino",
"Grön",
"Verde",
+ "Zöld",
},
{ "Yellow",
"Gelb",
@@ -2431,6 +2592,7 @@ const tI18nPhrase Phrases[] = {
"Kitrino",
"Gul",
"Galben",
+ "Sárga",
},
{ "Blue",
"Blau",
@@ -2446,6 +2608,7 @@ const tI18nPhrase Phrases[] = {
"Mple",
"Blĺ",
"Albastru",
+ "Kék",
},
{ "Power",
"Ausschalten",
@@ -2461,6 +2624,7 @@ const tI18nPhrase Phrases[] = {
"Klisimo",
"Pĺ/Av",
"Pornit",
+ "Kikapcsolni",
},
{ "Volume+",
"Lautstärke+",
@@ -2476,6 +2640,7 @@ const tI18nPhrase Phrases[] = {
"Entasi+",
"Volym+",
"Volum+",
+ "Hangerö+",
},
{ "Volume-",
"Lautstärke-",
@@ -2491,6 +2656,7 @@ const tI18nPhrase Phrases[] = {
"Entasi-",
"Volym-",
"Volum-",
+ "Hangerö-",
},
{ "Mute",
"Stumm",
@@ -2506,6 +2672,7 @@ const tI18nPhrase Phrases[] = {
"Mougko",
"Ljud Av",
"Mut(e)",
+ "Csend",
},
// Miscellaneous:
{ "yes",
@@ -2522,6 +2689,7 @@ const tI18nPhrase Phrases[] = {
"nai",
"ja",
"da",
+ "igen",
},
{ "no",
"nein",
@@ -2537,6 +2705,7 @@ const tI18nPhrase Phrases[] = {
"oxi",
"nej",
"nu",
+ "nem",
},
{ "top",
"oben",
@@ -2552,6 +2721,7 @@ const tI18nPhrase Phrases[] = {
"pano",
"övre",
"sus",
+ "Fent",
},
{ "bottom",
"unten",
@@ -2567,6 +2737,7 @@ const tI18nPhrase Phrases[] = {
"kato",
"nedre",
"jos",
+ "lent",
},
{ "Disk",
"Disk",
@@ -2582,6 +2753,7 @@ const tI18nPhrase Phrases[] = {
"Disk",
"Disk",
"Disc",
+ "Lemez",
},
{ "free",
"frei",
@@ -2597,6 +2769,7 @@ const tI18nPhrase Phrases[] = {
"akoma",
"ledigt",
"liber",
+ "szabad",
},
{ "Jump: ", // note the trailing blank
"Springen: ",
@@ -2612,6 +2785,7 @@ const tI18nPhrase Phrases[] = {
"Pidima: ",
"Hopp: ",
"Salt: ",
+ "Ugrás: ",
},
{ "Volume ", // note the trailing blank
"Lautstärke ",
@@ -2627,6 +2801,7 @@ const tI18nPhrase Phrases[] = {
"Entasi ",
"Volym ",
"Volum ",
+ "Hangerö ",
},
{ " Stop replaying", // note the leading blank!
" Wiedergabe beenden",
@@ -2642,6 +2817,7 @@ const tI18nPhrase Phrases[] = {
" Telos anametadosis",
" Avsluta uppspelning",
" Opreste redare",
+ " Lejátszást befejzni",
},
{ " Stop recording ", // note the leading and trailing blanks!
" Aufzeichnung beenden ",
@@ -2657,6 +2833,7 @@ const tI18nPhrase Phrases[] = {
" Telos egrafis ",
" Avsluta inspelning ",
" Opreste inregistrarea ",
+ " Felvételt befejezni ",
},
{ " Cancel editing", // note the leading blank!
" Schneiden abbrechen",
@@ -2672,6 +2849,7 @@ const tI18nPhrase Phrases[] = {
" Diakopi kopsimatos",
" Avbryt editering",
" Opreste editare",
+ " Vágást megszakítani",
},
{ "Switching primary DVB...",
"Primäres Interface wird umgeschaltet...",
@@ -2687,6 +2865,7 @@ const tI18nPhrase Phrases[] = {
"I protevon DVB Karta alazi...",
"Byter primär DVB enhet...",
"Comuta interfata primara DVB...",
+ "Primér Interface átkapcsolva...",
},
{ "Up/Dn for new location - OK to move",
"Auf/Ab für neue Position - dann OK",
@@ -2702,6 +2881,7 @@ const tI18nPhrase Phrases[] = {
"Pano/Kato gia nea thesi. meta OK",
"Upp/Ner för ny plats - OK för att flytta",
"Sus/Jos pentru noua locatie - OK pentru a muta",
+ "Fel/Le egy uj opcióért - aztán OK",
},
{ "Editing process started",
"Schnitt gestartet",
@@ -2717,6 +2897,7 @@ const tI18nPhrase Phrases[] = {
"Arxi kopsimatos",
"Editering startad",
"Procesul de editare a inceput",
+ "Vágás elindítva",
},
{ "Editing process finished",
"Schnitt beendet",
@@ -2732,6 +2913,7 @@ const tI18nPhrase Phrases[] = {
"To kopsimo termatistike",
"Editering avslutad",
"Procesul de editare s-a terminat",
+ "Vágás befejezve",
},
{ "Editing process failed!",
"Schnitt gescheitert!",
@@ -2747,6 +2929,7 @@ const tI18nPhrase Phrases[] = {
"Kopsimo apetixe!",
"Editeringsprocessen misslyckades",
"Proces de editare nereusit",
+ "Vágás sikertelen!",
},
{ "scanning recordings...",
"Aufzeichnungen werden durchsucht...",
@@ -2762,6 +2945,7 @@ const tI18nPhrase Phrases[] = {
"Ginete sarosi egrafon...",
"Söker igenom inspelningarna...",
"Caut inregistrari...",
+ "Felvett adások böngészése...",
},
{ "This plugin has no setup parameters!",
"Dieses Plugin hat keine Setup-Parameter!",
@@ -2776,6 +2960,8 @@ const tI18nPhrase Phrases[] = {
"",// TODO
"",// TODO
"",// TODO
+ "",// TODO
+ "",// TODO
},
{ NULL }
};
diff --git a/i18n.h b/i18n.h
index 2b0ae50..f7ff268 100644
--- a/i18n.h
+++ b/i18n.h
@@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
- * $Id: i18n.h 1.4 2002/06/10 16:14:02 kls Exp $
+ * $Id: i18n.h 1.5 2002/06/22 09:12:21 kls Exp $
*/
#ifndef __I18N_H
@@ -12,7 +12,7 @@
#include <stdio.h>
-const int I18nNumLanguages = 14;
+const int I18nNumLanguages = 15;
typedef const char *tI18nPhrase[I18nNumLanguages];
diff --git a/interface.h b/interface.h
index 240db63..137c7d4 100644
--- a/interface.h
+++ b/interface.h
@@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
- * $Id: interface.h 1.26 2002/05/18 13:43:20 kls Exp $
+ * $Id: interface.h 1.27 2002/06/22 14:39:48 kls Exp $
*/
#ifndef __INTERFACE_H
@@ -33,6 +33,7 @@ private:
public:
cInterface(int SVDRPport = 0);
~cInterface();
+ bool IsOpen(void) { return open > 0; }
void Open(int NumCols = 0, int NumLines = 0);
void Close(void);
void Interrupt(void) { interrupted = true; }
diff --git a/menu.c b/menu.c
index ff63fbc..2a5f2fe 100644
--- a/menu.c
+++ b/menu.c
@@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
- * $Id: menu.c 1.197 2002/06/16 13:23:51 kls Exp $
+ * $Id: menu.c 1.201 2002/06/23 11:07:19 kls Exp $
*/
#include "menu.h"
@@ -14,6 +14,7 @@
#include <stdlib.h>
#include <string.h>
#include "config.h"
+#include "cutter.h"
#include "eit.h"
#include "i18n.h"
#include "menuitems.h"
@@ -1512,7 +1513,6 @@ eOSState cMenuRecordings::ProcessKey(eKeys Key)
case kGreen: return Rewind();
case kYellow: return Del();
case kBlue: return Summary();
- case kMenu: return osEnd;
default: break;
}
}
@@ -2026,10 +2026,8 @@ void cMenuMain::Set(void)
// Editing control:
- /*XXX+
- if (cVideoCutter::Active())
+ if (cCutter::Active())
Add(new cOsdItem(tr(" Cancel editing"), osCancelEdit));
- XXX*/
// Color buttons:
@@ -2063,7 +2061,7 @@ eOSState cMenuMain::ProcessKey(eKeys Key)
}
break;
case osCancelEdit: if (Interface->Confirm(tr("Cancel editing?"))) {
- //XXX+cVideoCutter::Stop();
+ cCutter::Stop();
return osEnd;
}
break;
@@ -2081,7 +2079,6 @@ eOSState cMenuMain::ProcessKey(eKeys Key)
}
break;
default: switch (Key) {
- case kMenu: state = osEnd; break;
case kRed: if (!HasSubMenu())
state = osRecord;
break;
@@ -2443,7 +2440,7 @@ cRecordControl::cRecordControl(cDevice *Device, cTimer *Timer)
cRecordingUserCommand::InvokeCommand(RUC_BEFORERECORDING, fileName);
cChannel *ch = Channels.GetByNumber(timer->channel);
recorder = new cRecorder(fileName, ch->ca, timer->priority, ch->vpid, ch->apid1, ch->apid2, ch->dpid1, ch->dpid2);
- if (device->Attach(recorder)) {
+ if (device->AttachReceiver(recorder)) {
Recording.WriteSummary();
cStatus::MsgRecording(device, fileName);
Interface->DisplayRecording(device->CardIndex(), true);
@@ -2684,18 +2681,14 @@ char *cReplayControl::fileName = NULL;
char *cReplayControl::title = NULL;
cReplayControl::cReplayControl(void)
+:cDvbPlayerControl(fileName)
{
visible = modeOnly = shown = displayFrames = false;
lastCurrent = lastTotal = -1;
timeoutShow = 0;
timeSearchActive = false;
- if (fileName) {
- marks.Load(fileName);
- if (!Start(fileName))
- Interface->Error(tr("Channel locked (recording)!"));//XXX+
- else
- cStatus::MsgReplaying(this, fileName);
- }
+ marks.Load(fileName);
+ cStatus::MsgReplaying(this, fileName);
}
cReplayControl::~cReplayControl()
@@ -2973,11 +2966,10 @@ void cReplayControl::MarkMove(bool Forward)
void cReplayControl::EditCut(void)
{
- /*XXX+
if (fileName) {
Hide();
- if (!cVideoCutter::Active()) {
- if (!cVideoCutter::Start(fileName))
+ if (!cCutter::Active()) {
+ if (!cCutter::Start(fileName))
Interface->Error(tr("Can't start editing process!"));
else
Interface->Info(tr("Editing process started"));
@@ -2986,7 +2978,6 @@ void cReplayControl::EditCut(void)
Interface->Error(tr("Editing process already active!"));
ShowMode();
}
- XXX*/
}
void cReplayControl::EditTest(void)
@@ -3065,7 +3056,6 @@ eOSState cReplayControl::ProcessKey(eKeys Key)
displayFrames = DisplayedFrames;
switch (Key) {
// Menu control:
- case kMenu: Hide(); return osMenu; // allow direct switching to menu
case kOk: if (visible && !modeOnly) {
Hide();
DoShowMode = true;
diff --git a/menu.h b/menu.h
index 9dfe1a4..c03e627 100644
--- a/menu.h
+++ b/menu.h
@@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
- * $Id: menu.h 1.44 2002/06/14 12:33:35 kls Exp $
+ * $Id: menu.h 1.45 2002/06/22 14:49:15 kls Exp $
*/
#ifndef __MENU_H
@@ -124,7 +124,6 @@ private:
void TimeSearchProcess(eKeys Key);
void TimeSearch(void);
void Show(int Seconds = 0);
- void Hide(void);
static char *fileName;
static char *title;
void DisplayAtBottom(const char *s = NULL);
@@ -139,6 +138,7 @@ public:
cReplayControl(void);
virtual ~cReplayControl();
virtual eOSState ProcessKey(eKeys Key);
+ virtual void Hide(void);
bool Visible(void) { return visible; }
static void SetRecording(const char *FileName, const char *Title);
static const char *LastReplayed(void);
diff --git a/osd.h b/osd.h
index 88c986c..c062157 100644
--- a/osd.h
+++ b/osd.h
@@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
- * $Id: osd.h 1.31 2002/05/18 14:00:15 kls Exp $
+ * $Id: osd.h 1.32 2002/06/23 09:13:17 kls Exp $
*/
#ifndef __OSD_H
@@ -22,7 +22,6 @@
#define MAXOSDITEMS (Setup.OSDheight - 4)
enum eOSState { osUnknown,
- osMenu,
osContinue,
osSchedule,
osChannels,
@@ -115,7 +114,7 @@ public:
int Width(void) { return Interface->Width(); }
int Height(void) { return Interface->Height(); }
bool NeedsFastResponse(void) { return needsFastResponse; }
- virtual eOSState ProcessKey(eKeys Key) = 0;
+ virtual eOSState ProcessKey(eKeys Key) { return osUnknown; }
};
class cOsdMenu : public cOsdObject, public cList<cOsdItem> {
diff --git a/player.c b/player.c
index fe0a277..ca182df 100644
--- a/player.c
+++ b/player.c
@@ -4,10 +4,11 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
- * $Id: player.c 1.1 2002/06/16 10:34:50 kls Exp $
+ * $Id: player.c 1.3 2002/06/23 12:56:25 kls Exp $
*/
#include "player.h"
+#include "i18n.h"
// --- cPlayer ---------------------------------------------------------------
@@ -46,10 +47,46 @@ void cPlayer::Detach(void)
// --- cControl --------------------------------------------------------------
-cControl::cControl(void)
+cControl *cControl::control = NULL;
+
+cControl::cControl(cPlayer *Player, bool Hidden)
{
+ attached = false;
+ hidden = Hidden;
+ player = Player;
}
cControl::~cControl()
{
+ if (this == control)
+ control = NULL;
+}
+
+cControl *cControl::Control(void)
+{
+ return (control && !control->hidden) ? control : NULL;
+}
+
+void cControl::Launch(cControl *Control)
+{
+ delete control;
+ control = Control;
+}
+
+void cControl::Attach(void)
+{
+ if (control && !control->attached && control->player && !control->player->IsAttached()) {
+ if (cDevice::PrimaryDevice()->AttachPlayer(control->player))
+ control->attached = true;
+ else {
+ Interface->Error(tr("Channel locked (recording)!"));
+ Shutdown();
+ }
+ }
+}
+
+void cControl::Shutdown(void)
+{
+ delete control;
+ control = NULL;
}
diff --git a/player.h b/player.h
index 1221c24..51265f3 100644
--- a/player.h
+++ b/player.h
@@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
- * $Id: player.h 1.1 2002/06/16 11:52:45 kls Exp $
+ * $Id: player.h 1.4 2002/06/23 12:56:38 kls Exp $
*/
#ifndef __PLAYER_H
@@ -40,12 +40,24 @@ protected:
public:
cPlayer(void);
virtual ~cPlayer();
+ bool IsAttached(void) { return device != NULL; }
};
class cControl : public cOsdObject {
+private:
+ static cControl *control;
+ bool attached;
+ bool hidden;
+protected:
+ cPlayer *player;
public:
- cControl(void);
+ cControl(cPlayer *Player, bool Hidden = false);
virtual ~cControl();
+ virtual void Hide(void) = 0;
+ static void Launch(cControl *Control);
+ static void Attach(void);
+ static void Shutdown(void);
+ static cControl *Control(void);
};
#endif //__PLAYER_H
diff --git a/recording.c b/recording.c
index 7bc896c..7ebec5c 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.63 2002/06/16 11:29:27 kls Exp $
+ * $Id: recording.c 1.64 2002/06/22 10:11:49 kls Exp $
*/
#include "recording.h"
@@ -1056,6 +1056,8 @@ int cFileName::NextFile(void)
return SetOffset(fileNumber + 1);
}
+// --- Index stuff -----------------------------------------------------------
+
const char *IndexToHMSF(int Index, bool WithFrame)
{
static char buffer[16];
@@ -1080,3 +1082,21 @@ int SecondsToFrames(int Seconds)
{
return Seconds * FRAMESPERSEC;
}
+
+// --- ReadFrame -------------------------------------------------------------
+
+int ReadFrame(int f, uchar *b, int Length, int Max)
+{
+ if (Length == -1)
+ Length = Max; // this means we read up to EOF (see cIndex)
+ else if (Length > Max) {
+ esyslog("ERROR: frame larger than buffer (%d > %d)", Length, Max);
+ Length = Max;
+ }
+ int r = safe_read(f, b, Length);
+ if (r < 0)
+ LOG_ERROR;
+ return r;
+}
+
+
diff --git a/recording.h b/recording.h
index 16c6506..2fae49e 100644
--- a/recording.h
+++ b/recording.h
@@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
- * $Id: recording.h 1.23 2002/06/16 11:29:47 kls Exp $
+ * $Id: recording.h 1.24 2002/06/22 10:09:27 kls Exp $
*/
#ifndef __RECORDING_H
@@ -107,6 +107,9 @@ public:
//XXX+
#define FRAMESPERSEC 25
+// The maximum size of a single frame:
+#define MAXFRAMESIZE KILOBYTE(192)
+
// The maximum file size is limited by the range that can be covered
// with 'int'. 4GB might be possible (if the range is considered
// 'unsigned'), 2GB should be possible (even if the range is considered
@@ -163,4 +166,6 @@ int HMSFToIndex(const char *HMSF);
int SecondsToFrames(int Seconds); //XXX+ ->player???
// Returns the number of frames corresponding to the given number of seconds.
+int ReadFrame(int f, uchar *b, int Length, int Max);
+
#endif //__RECORDING_H
diff --git a/transfer.c b/transfer.c
new file mode 100644
index 0000000..3b0b636
--- /dev/null
+++ b/transfer.c
@@ -0,0 +1,135 @@
+/*
+ * transfer.c: Transfer mode
+ *
+ * See the main source file 'vdr.c' for copyright information and
+ * how to reach the author.
+ *
+ * $Id: transfer.c 1.2 2002/06/23 12:56:49 kls Exp $
+ */
+
+#include "transfer.h"
+
+//XXX+ also used in recorder.c - find a better place???
+// The size of the array used to buffer video data:
+// (must be larger than MINVIDEODATA - see remux.h)
+#define VIDEOBUFSIZE MEGABYTE(1)
+
+// --- cTransfer -------------------------------------------------------------
+
+cTransfer::cTransfer(int VPid, int APid1, int APid2, int DPid1, int DPid2)
+:cReceiver(0, 0, 5, VPid, APid1, APid2, DPid1, DPid2)
+{
+ ringBuffer = new cRingBufferLinear(VIDEOBUFSIZE, true);
+ remux = new cRemux(VPid, APid1, APid2, DPid1, DPid2);
+ gotBufferReserve = false;
+ active = false;
+}
+
+cTransfer::~cTransfer()
+{
+ cReceiver::Detach();
+ cPlayer::Detach();
+ delete remux;
+ delete ringBuffer;
+}
+
+void cTransfer::Activate(bool On)
+{
+ if (On) {
+ if (!active)
+ Start();
+ }
+ else if (active) {
+ active = false;
+ Cancel(3);
+ }
+}
+
+void cTransfer::Receive(uchar *Data, int Length)
+{
+ int p = ringBuffer->Put(Data, Length);
+ if (p != Length && active)
+ esyslog("ERROR: ring buffer overflow (%d bytes dropped)", Length - p);
+}
+
+void cTransfer::Action(void)
+{
+ dsyslog("transfer thread started (pid=%d)", getpid());
+
+ uchar b[MINVIDEODATA];
+ int r = 0;
+ active = true;
+ while (active) {
+
+ //XXX+ Maybe we need this to avoid "buffer empty" log messages from the driver.
+ //XXX+ But then again, it appears to play just fine without this...
+ /*
+ if (!gotBufferReserve) {
+ if (ringBuffer->Available() < 4 * MAXFRAMESIZE) {
+ usleep(100000); // allow the buffer to collect some reserve
+ continue;
+ }
+ else
+ gotBufferReserve = true;
+ }
+ */
+
+ // Get data from the buffer:
+
+ int g = ringBuffer->Get(b + r, sizeof(b) - r);
+ if (g > 0)
+ r += g;
+
+ // Play the data:
+
+ if (r > 0) {
+ int Count = r, Result;
+ const uchar *p = remux->Process(b, Count, Result);
+ if (p) {
+ //XXX+ StripAudio???
+ while (Result > 0 && active) {
+ int w = PlayVideo(p, Result);
+ if (w > 0) {
+ p += w;
+ Result -= w;
+ }
+ else if (w < 0 && FATALERRNO) {
+ LOG_ERROR;
+ break;
+ }
+ }
+ }
+ if (Count > 0) {
+ r -= Count;
+ if (r > 0)
+ memmove(b, b + Count, r);
+ }
+ }
+ }
+
+ dsyslog("transfer thread ended (pid=%d)", getpid());
+}
+
+void cTransfer::SetAudioPid(int APid)
+{
+ /*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*/
+}
+
+// --- cTransferControl ------------------------------------------------------
+
+cTransferControl::cTransferControl(cDevice *ReceiverDevice, int VPid, int APid1, int APid2, int DPid1, int DPid2)
+:cControl(transfer = new cTransfer(VPid, APid1, APid2, DPid1, DPid2), true)
+{
+ ReceiverDevice->AttachReceiver(transfer);
+}
+
+cTransferControl::~cTransferControl()
+{
+ delete transfer;
+}
diff --git a/transfer.h b/transfer.h
new file mode 100644
index 0000000..567f21a
--- /dev/null
+++ b/transfer.h
@@ -0,0 +1,44 @@
+/*
+ * transfer.h: Transfer mode
+ *
+ * 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 $
+ */
+
+#ifndef __TRANSFER_H
+#define __TRANSFER_H
+
+#include "player.h"
+#include "receiver.h"
+#include "remux.h"
+#include "ringbuffer.h"
+#include "thread.h"
+
+class cTransfer : public cReceiver, public cPlayer, public cThread {
+private:
+ cRingBufferLinear *ringBuffer;
+ cRemux *remux;
+ bool gotBufferReserve;
+ bool active;
+protected:
+ virtual void Activate(bool On);
+ virtual void Receive(uchar *Data, int Length);
+ virtual void Action(void);
+public:
+ cTransfer(int VPid, int APid1, int APid2, int DPid1, int DPid2);
+ virtual ~cTransfer();
+ void SetAudioPid(int APid);
+ };
+
+class cTransferControl : public cControl {
+private:
+ cTransfer *transfer;
+public:
+ cTransferControl(cDevice *ReceiverDevice, int VPid, int APid1, int APid2, int DPid1, int DPid2);
+ ~cTransferControl();
+ virtual void Hide(void) {}
+ };
+
+#endif //__TRANSFER_H
diff --git a/vdr.c b/vdr.c
index bef3919..10c54f7 100644
--- a/vdr.c
+++ b/vdr.c
@@ -22,7 +22,7 @@
*
* The project's page is at http://www.cadsoft.de/people/kls/vdr
*
- * $Id: vdr.c 1.114 2002/06/16 11:30:28 kls Exp $
+ * $Id: vdr.c 1.117 2002/06/23 11:23:34 kls Exp $
*/
#include <getopt.h>
@@ -31,6 +31,7 @@
#include <stdlib.h>
#include <unistd.h>
#include "config.h"
+#include "cutter.h"
#include "device.h"
#include "eitscan.h"
#include "i18n.h"
@@ -371,7 +372,7 @@ int main(int argc, char *argv[])
// Main program loop:
cOsdObject *Menu = NULL;
- cReplayControl *ReplayControl = NULL;
+ cOsdObject *Temp = NULL;
int LastChannel = -1;
int PreviousChannel = cDevice::CurrentChannel();
time_t LastActivity = 0;
@@ -389,6 +390,8 @@ int main(int argc, char *argv[])
esyslog("emergency exit requested - shutting down");
break;
}
+ // Attach launched player control:
+ cControl::Attach();
// Restart the Watchdog timer:
if (WatchdogTimeout > 0) {
int LatencyTime = WatchdogTimeout - alarm(WatchdogTimeout);
@@ -400,7 +403,7 @@ int main(int argc, char *argv[])
// Channel display:
if (!EITScanner.Active() && cDevice::CurrentChannel() != LastChannel) {
if (!Menu)
- Menu = new cDisplayChannel(cDevice::CurrentChannel(), LastChannel > 0);
+ Menu = Temp = new cDisplayChannel(cDevice::CurrentChannel(), LastChannel > 0);
if (LastChannel > 0)
PreviousChannel = LastChannel;
LastChannel = cDevice::CurrentChannel();
@@ -416,14 +419,26 @@ int main(int argc, char *argv[])
}
}
// User Input:
- cOsdObject **Interact = Menu ? &Menu : (cOsdObject **)&ReplayControl;
- eKeys key = Interface->GetKey(!*Interact || !(*Interact)->NeedsFastResponse());
+ cOsdObject *Interact = Menu ? Menu : cControl::Control();
+ eKeys key = Interface->GetKey(!Interact || !Interact->NeedsFastResponse());
if (NORMALKEY(key) != kNone) {
EITScanner.Activity();
LastActivity = time(NULL);
}
// Keys that must work independent of any interactive mode:
switch (key) {
+ // Menu control:
+ case kMenu:
+ if (Menu) {
+ DELETENULL(Menu);
+ if (!Temp)
+ break;
+ }
+ if (cControl::Control())
+ cControl::Control()->Hide();
+ Menu = new cMenuMain(cControl::Control());
+ Temp = NULL;
+ break;
// Volume Control:
case kVolUp|k_Repeat:
case kVolUp:
@@ -436,13 +451,15 @@ int main(int argc, char *argv[])
}
else
cDevice::PrimaryDevice()->SetVolume(NORMALKEY(key) == kVolDn ? -VOLUMEDELTA : VOLUMEDELTA);
- if (!Menu && (!ReplayControl || !ReplayControl->Visible()))
- Menu = cDisplayVolume::Create();
+ if (!Interface->IsOpen())
+ Menu = Temp = cDisplayVolume::Create();
cDisplayVolume::Process(key);
break;
// Power off:
case kPower: isyslog("Power button pressed");
- DELETENULL(*Interact);
+ DELETENULL(Menu);
+ cControl::Shutdown();
+ Temp = NULL;
if (!Shutdown) {
Interface->Error(tr("Can't shutdown - option '-s' not given!"));
break;
@@ -454,35 +471,42 @@ int main(int argc, char *argv[])
LastActivity = 1; // not 0, see below!
break;
default:
- if (*Interact) {
- switch ((*Interact)->ProcessKey(key)) {
- case osMenu: DELETENULL(Menu);
- Menu = new cMenuMain(ReplayControl);
- break;
+ if (Interact) {
+ switch (Interact->ProcessKey(key)) {
case osRecord: DELETENULL(Menu);
+ Temp = NULL;
if (!cRecordControls::Start())
Interface->Error(tr("No free DVB device to record!"));
break;
case osRecordings:
DELETENULL(Menu);
- DELETENULL(ReplayControl);
- Menu = new cMenuMain(ReplayControl, osRecordings);
+ cControl::Shutdown();
+ Temp = NULL;
+ Menu = new cMenuMain(false, osRecordings);
break;
case osReplay: DELETENULL(Menu);
- DELETENULL(ReplayControl);
- ReplayControl = new cReplayControl;
+ cControl::Shutdown();
+ Temp = NULL;
+ cControl::Launch(new cReplayControl);
break;
case osStopReplay:
- DELETENULL(*Interact);
- DELETENULL(ReplayControl);
+ DELETENULL(Menu);
+ cControl::Shutdown();
+ Temp = NULL;
break;
case osSwitchDvb:
- DELETENULL(*Interact);
+ DELETENULL(Menu);
+ cControl::Shutdown();
+ Temp = NULL;
Interface->Info(tr("Switching primary DVB..."));
cDevice::SetPrimaryDevice(Setup.PrimaryDVB);
break;
case osBack:
- case osEnd: DELETENULL(*Interact);
+ case osEnd: if (Interact == Menu)
+ DELETENULL(Menu);
+ else
+ cControl::Shutdown();
+ Temp = NULL;
break;
default: ;
}
@@ -519,8 +543,6 @@ int main(int argc, char *argv[])
channel->Switch();
break;
}
- // Menu Control:
- case kMenu: Menu = new cMenuMain(ReplayControl); break;
// Viewing Control:
case kOk: LastChannel = -1; break; // forces channel display
default: break;
@@ -529,16 +551,14 @@ int main(int argc, char *argv[])
}
if (!Menu) {
EITScanner.Process();
- /*XXX+
- if (!cVideoCutter::Active() && cVideoCutter::Ended()) {
- if (cVideoCutter::Error())
+ if (!cCutter::Active() && cCutter::Ended()) {
+ if (cCutter::Error())
Interface->Error(tr("Editing process failed!"));
else
Interface->Info(tr("Editing process finished"));
}
- XXX*/
}
- if (!*Interact && ((!cRecordControls::Active() /*XXX+&& !cVideoCutter::Active()XXX*/) || ForceShutdown)) {
+ if (!Interact && ((!cRecordControls::Active() && !cCutter::Active()) || ForceShutdown)) {
time_t Now = time(NULL);
if (Now - LastActivity > ACTIVITYTIMEOUT) {
// Shutdown:
@@ -598,9 +618,9 @@ int main(int argc, char *argv[])
if (Interrupted)
isyslog("caught signal %d", Interrupted);
cRecordControls::Shutdown();
- //XXX+cVideoCutter::Stop();
+ cCutter::Stop();
delete Menu;
- delete ReplayControl;
+ cControl::Shutdown();
delete Interface;
cOsd::Shutdown();
PluginManager.Shutdown(true);