summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CONTRIBUTORS1
-rw-r--r--HISTORY2
-rw-r--r--PLUGINS.html2
-rw-r--r--device.c10
-rw-r--r--device.h27
-rw-r--r--dvbdevice.c89
-rw-r--r--dvbdevice.h5
-rw-r--r--player.c5
-rw-r--r--player.h17
9 files changed, 107 insertions, 51 deletions
diff --git a/CONTRIBUTORS b/CONTRIBUTORS
index b7de2aaf..e39f3021 100644
--- a/CONTRIBUTORS
+++ b/CONTRIBUTORS
@@ -140,6 +140,7 @@ Stefan Huelswitt <huels@iname.com>
for suggesting to make the config directory available to plugins
for suggesting to add an error message if the directory specified in the '-L'
option can't be accessed
+ for implementing several replay modes to allow players that play only audio
Ulrich Röder <roeder@efr-net.de>
for pointing out that there are channels that have a symbol rate higher than
diff --git a/HISTORY b/HISTORY
index a3176062..a145e521 100644
--- a/HISTORY
+++ b/HISTORY
@@ -1408,3 +1408,5 @@ Video Disk Recorder Revision History
can now call DeviceNeedsData() to see whether the replay device is ready for
further data. A derived cDevice class must implement NeedsData() and shall
check if any of its file handles is ready for data.
+- Implemented several replay modes to allow players that play only audio (thanks
+ to Stefan Huelswitt).
diff --git a/PLUGINS.html b/PLUGINS.html
index c0f6d8ab..105865b0 100644
--- a/PLUGINS.html
+++ b/PLUGINS.html
@@ -1231,7 +1231,7 @@ The functions to implement replaying capabilites are
<!--X1.1.7--><table width=100%><tr><td bgcolor=#FF0000>&nbsp;</td><td width=100%>
<p><table><tr><td bgcolor=#F0F0F0><pre><br>
virtual bool HasDecoder(void) const;
-virtual int SetPlayMode(bool On);
+virtual bool SetPlayMode(ePlayMode PlayMode);
virtual void TrickSpeed(int Speed);
virtual void Clear(void);
virtual void Play(void);
diff --git a/device.c b/device.c
index 8d678503..40304618 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.9 2002/08/15 09:59:57 kls Exp $
+ * $Id: device.c 1.10 2002/08/15 10:30:08 kls Exp $
*/
#include "device.h"
@@ -316,9 +316,9 @@ void cDevice::SetVolume(int Volume, bool Absolute)
mute = false;
}
-int cDevice::SetPlayMode(bool On)
+bool cDevice::SetPlayMode(ePlayMode PlayMode)
{
- return -1;
+ return false;
}
void cDevice::TrickSpeed(int Speed)
@@ -361,7 +361,7 @@ bool cDevice::AttachPlayer(cPlayer *Player)
Detach(player);
player = Player;
player->device = this;
- SetPlayMode(true);//XXX
+ SetPlayMode(player->playMode);
player->Activate(true);
return true;
}
@@ -374,7 +374,7 @@ void cDevice::Detach(cPlayer *Player)
player->Activate(false);
player->device = NULL;
player = NULL;
- SetPlayMode(false);
+ SetPlayMode(pmNone);
}
}
diff --git a/device.h b/device.h
index 6bd9828e..bba828a5 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.7 2002/08/15 09:22:13 kls Exp $
+ * $Id: device.h 1.8 2002/08/15 11:09:21 kls Exp $
*/
#ifndef __DEVICE_H
@@ -26,6 +26,23 @@
enum eSetChannelResult { scrOk, scrNoTransfer, scrFailed };
+enum ePlayMode { pmNone, // audio/video from decoder
+ pmAudioVideo, // audio/video from player
+ pmAudioOnly, // audio only from player, video from decoder
+ pmExtern_THIS_SHOULD_BE_AVOIDED
+ // external player (e.g. MPlayer), release the device
+ // WARNING: USE THIS MODE ONLY AS A LAST RESORT, IF YOU
+ // ABSOLUTELY, POSITIVELY CAN'T IMPLEMENT YOUR PLAYER
+ // THE WAY IT IS SUPPOSED TO WORK. FORCING THE DEVICE
+ // TO RELEASE ITS FILES HANDLES (OR WHATEVER RESOURCES
+ // IT MAY USE) TO ALLOW AN EXTERNAL PLAYER TO ACCESS
+ // THEM MEANS THAT SUCH A PLAYER WILL NEED TO HAVE
+ // DETAILED KNOWLEDGE ABOUT THE INTERNALS OF THE DEVICE
+ // IN USE. AS A CONSEQUENCE, YOUR PLAYER MAY NOT WORK
+ // IF A PARTICULAR VDR INSTALLATION USES A DEVICE NOT
+ // KNOWN TO YOUR PLAYER.
+ };
+
class cChannel;
class cPlayer;
class cReceiver;
@@ -190,11 +207,9 @@ public:
private:
cPlayer *player;
protected:
- virtual int SetPlayMode(bool On);
- // Sets the device into play mode (On = true) or normal
- // viewing mode (On = false). If On is true, it may return a file
- // handle that a player can use to poll this device when replaying.
- //XXX TODO should be implemented differently
+ virtual bool SetPlayMode(ePlayMode PlayMode);
+ // Sets the device into the given play mode.
+ // Returns true if the operation was successful.
public:
virtual void TrickSpeed(int Speed);
// Sets the device into a mode where replay is done slower.
diff --git a/dvbdevice.c b/dvbdevice.c
index b37a98db..82587286 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.4 2002/08/15 09:59:33 kls Exp $
+ * $Id: dvbdevice.c 1.5 2002/08/15 11:13:46 kls Exp $
*/
#include "dvbdevice.h"
@@ -81,6 +81,7 @@ cDvbDevice::cDvbDevice(int n)
{
frontendType = FrontendType(-1); // don't know how else to initialize this - there is no FE_UNKNOWN
siProcessor = NULL;
+ playMode = pmNone;
// Devices that are present on all card types:
@@ -569,32 +570,65 @@ void cDvbDevice::SetVolumeDevice(int Volume)
}
}
-int cDvbDevice::SetPlayMode(bool On)
+bool cDvbDevice::SetPlayMode(ePlayMode PlayMode)
{
- if (On) {
- if (siProcessor)
- siProcessor->SetStatus(false);
- CHECK(ioctl(fd_video, VIDEO_SET_BLANK, true));
- CHECK(ioctl(fd_audio, AUDIO_SELECT_SOURCE, AUDIO_SOURCE_MEMORY));
- CHECK(ioctl(fd_audio, AUDIO_SET_AV_SYNC, true));
- CHECK(ioctl(fd_audio, AUDIO_PLAY));
- CHECK(ioctl(fd_video, VIDEO_SELECT_SOURCE, VIDEO_SOURCE_MEMORY));
- CHECK(ioctl(fd_video, VIDEO_PLAY));
- return fd_video;
- }
- else {
- CHECK(ioctl(fd_video, VIDEO_STOP, true));
- CHECK(ioctl(fd_audio, AUDIO_STOP, true));
- CHECK(ioctl(fd_video, VIDEO_CLEAR_BUFFER));
- CHECK(ioctl(fd_audio, AUDIO_CLEAR_BUFFER));
- CHECK(ioctl(fd_video, VIDEO_SELECT_SOURCE, VIDEO_SOURCE_DEMUX));
- CHECK(ioctl(fd_audio, AUDIO_SELECT_SOURCE, AUDIO_SOURCE_DEMUX));
- CHECK(ioctl(fd_audio, AUDIO_SET_AV_SYNC, true));
- CHECK(ioctl(fd_audio, AUDIO_SET_MUTE, false));
- if (siProcessor)
- siProcessor->SetStatus(true);
- return -1;
+ if (PlayMode != pmExtern_THIS_SHOULD_BE_AVOIDED && fd_video < 0 && fd_audio < 0) {
+ // reopen the devices
+ fd_video = DvbOpen(DEV_DVB_VIDEO, CardIndex(), O_RDWR | O_NONBLOCK);
+ fd_audio = DvbOpen(DEV_DVB_AUDIO, CardIndex(), O_RDWR | O_NONBLOCK);
+ SetVideoFormat(Setup.VideoFormat);
}
+
+ switch (PlayMode) {
+ case pmNone:
+ if (playMode == pmAudioOnly) {
+ // special "handling" to return from PCM replay
+ CHECK(ioctl(fd_video, VIDEO_SET_BLANK, true));
+ CHECK(ioctl(fd_video, VIDEO_SELECT_SOURCE, VIDEO_SOURCE_MEMORY));
+ CHECK(ioctl(fd_video, VIDEO_PLAY));
+ }
+ CHECK(ioctl(fd_video, VIDEO_STOP, true));
+ CHECK(ioctl(fd_audio, AUDIO_STOP, true));
+ CHECK(ioctl(fd_video, VIDEO_CLEAR_BUFFER));
+ CHECK(ioctl(fd_audio, AUDIO_CLEAR_BUFFER));
+ CHECK(ioctl(fd_video, VIDEO_SELECT_SOURCE, VIDEO_SOURCE_DEMUX));
+ CHECK(ioctl(fd_audio, AUDIO_SELECT_SOURCE, AUDIO_SOURCE_DEMUX));
+ CHECK(ioctl(fd_audio, AUDIO_SET_AV_SYNC, true));
+ CHECK(ioctl(fd_audio, AUDIO_SET_MUTE, false));
+ if (siProcessor)
+ siProcessor->SetStatus(true);
+ break;
+ case pmAudioVideo:
+ if (siProcessor)
+ siProcessor->SetStatus(false);
+ CHECK(ioctl(fd_video, VIDEO_SET_BLANK, true));
+ CHECK(ioctl(fd_audio, AUDIO_SELECT_SOURCE, AUDIO_SOURCE_MEMORY));
+ CHECK(ioctl(fd_audio, AUDIO_SET_AV_SYNC, true));
+ CHECK(ioctl(fd_audio, AUDIO_PLAY));
+ CHECK(ioctl(fd_video, VIDEO_SELECT_SOURCE, VIDEO_SOURCE_MEMORY));
+ CHECK(ioctl(fd_video, VIDEO_PLAY));
+ break;
+ case pmAudioOnly:
+ if (siProcessor)
+ siProcessor->SetStatus(false);
+ CHECK(ioctl(fd_video, VIDEO_SET_BLANK, true));
+ CHECK(ioctl(fd_audio, AUDIO_STOP, true));
+ CHECK(ioctl(fd_audio, AUDIO_CLEAR_BUFFER));
+ CHECK(ioctl(fd_audio, AUDIO_SELECT_SOURCE, AUDIO_SOURCE_MEMORY));
+ CHECK(ioctl(fd_audio, AUDIO_SET_AV_SYNC, false));
+ CHECK(ioctl(fd_audio, AUDIO_PLAY));
+ CHECK(ioctl(fd_video, VIDEO_SET_BLANK, false));
+ break;
+ case pmExtern_THIS_SHOULD_BE_AVOIDED:
+ if (siProcessor)
+ siProcessor->SetStatus(false);
+ close(fd_video);
+ close(fd_audio);
+ fd_video = fd_audio = -1;
+ break;
+ }
+ playMode = PlayMode;
+ return true;
}
void cDvbDevice::TrickSpeed(int Speed)
@@ -667,8 +701,9 @@ bool cDvbDevice::NeedsData(int Wait)
int cDvbDevice::PlayVideo(const uchar *Data, int Length)
{
- if (fd_video >= 0)
- return write(fd_video, Data, Length);
+ int fd = playMode == pmAudioOnly ? fd_audio : fd_video;
+ if (fd >= 0)
+ return write(fd, Data, Length);
return -1;
}
diff --git a/dvbdevice.h b/dvbdevice.h
index 11c963a7..cbc9b164 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.3 2002/08/15 09:28:36 kls Exp $
+ * $Id: dvbdevice.h 1.4 2002/08/15 10:59:25 kls Exp $
*/
#ifndef __DVBDEVICE_H
@@ -83,7 +83,8 @@ private:
// Player facilities
protected:
- virtual int SetPlayMode(bool On);
+ ePlayMode playMode;
+ virtual bool SetPlayMode(ePlayMode PlayMode);
public:
virtual void TrickSpeed(int Speed);
virtual void Clear(void);
diff --git a/player.c b/player.c
index 3abb79b5..3eecc2d4 100644
--- a/player.c
+++ b/player.c
@@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
- * $Id: player.c 1.4 2002/08/11 15:49:13 kls Exp $
+ * $Id: player.c 1.5 2002/08/15 10:29:17 kls Exp $
*/
#include "player.h"
@@ -12,9 +12,10 @@
// --- cPlayer ---------------------------------------------------------------
-cPlayer::cPlayer(void)
+cPlayer::cPlayer(ePlayMode PlayMode)
{
device = NULL;
+ playMode = PlayMode;
}
cPlayer::~cPlayer()
diff --git a/player.h b/player.h
index 1fd9fdda..1eed0b70 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.6 2002/08/15 09:34:08 kls Exp $
+ * $Id: player.h 1.7 2002/08/15 11:10:09 kls Exp $
*/
#ifndef __PLAYER_H
@@ -17,6 +17,7 @@ class cPlayer {
friend class cDevice;
private:
cDevice *device;
+ ePlayMode playMode;
protected:
bool DeviceNeedsData(int Wait = 0) { return device ? device->NeedsData(Wait) : false; }
void DeviceTrickSpeed(int Speed) { if (device) device->TrickSpeed(Speed); }
@@ -27,17 +28,17 @@ protected:
void DeviceStillPicture(const uchar *Data, int Length) { if (device) device->StillPicture(Data, Length); }
void Detach(void);
virtual void Activate(bool On) {}
- // This function is called right after the cPlayer has been attached to
- // (On == true) or before it gets detached from (On == false) a cDevice.
- // It can be used to do things like starting/stopping a thread.
+ // This function is called right after the cPlayer has been attached to
+ // (On == true) or before it gets detached from (On == false) a cDevice.
+ // It can be used to do things like starting/stopping a thread.
int PlayVideo(const uchar *Data, int Length);
- // Sends the given Data to the video device and returns the number of
- // bytes that have actually been accepted by the video device (or a
- // negative value in case of an error).
+ // Sends the given Data to the video device and returns the number of
+ // bytes that have actually been accepted by the video device (or a
+ // negative value in case of an error).
int PlayAudio(const uchar *Data, int Length);
// XXX+ TODO
public:
- cPlayer(void);
+ cPlayer(ePlayMode PlayMode = pmAudioVideo);
virtual ~cPlayer();
bool IsAttached(void) { return device != NULL; }
virtual bool GetIndex(int &Current, int &Total, bool SnapToIFrame = false) { return false; }