Implemented several replay modes to allow players that play only audio

This commit is contained in:
Klaus Schmidinger 2002-08-15 11:16:34 +02:00
parent d4ab35d1d9
commit c0ef9a35e2
9 changed files with 107 additions and 51 deletions

View File

@ -140,6 +140,7 @@ Stefan Huelswitt <huels@iname.com>
for suggesting to make the config directory available to plugins for suggesting to make the config directory available to plugins
for suggesting to add an error message if the directory specified in the '-L' for suggesting to add an error message if the directory specified in the '-L'
option can't be accessed option can't be accessed
for implementing several replay modes to allow players that play only audio
Ulrich Röder <roeder@efr-net.de> Ulrich Röder <roeder@efr-net.de>
for pointing out that there are channels that have a symbol rate higher than for pointing out that there are channels that have a symbol rate higher than

View File

@ -1408,3 +1408,5 @@ Video Disk Recorder Revision History
can now call DeviceNeedsData() to see whether the replay device is ready for can now call DeviceNeedsData() to see whether the replay device is ready for
further data. A derived cDevice class must implement NeedsData() and shall further data. A derived cDevice class must implement NeedsData() and shall
check if any of its file handles is ready for data. 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).

View File

@ -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%> <!--X1.1.7--><table width=100%><tr><td bgcolor=#FF0000>&nbsp;</td><td width=100%>
<p><table><tr><td bgcolor=#F0F0F0><pre><br> <p><table><tr><td bgcolor=#F0F0F0><pre><br>
virtual bool HasDecoder(void) const; virtual bool HasDecoder(void) const;
virtual int SetPlayMode(bool On); virtual bool SetPlayMode(ePlayMode PlayMode);
virtual void TrickSpeed(int Speed); virtual void TrickSpeed(int Speed);
virtual void Clear(void); virtual void Clear(void);
virtual void Play(void); virtual void Play(void);

View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and * See the main source file 'vdr.c' for copyright information and
* how to reach the author. * how to reach the author.
* *
* $Id: device.c 1.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" #include "device.h"
@ -316,9 +316,9 @@ void cDevice::SetVolume(int Volume, bool Absolute)
mute = false; mute = false;
} }
int cDevice::SetPlayMode(bool On) bool cDevice::SetPlayMode(ePlayMode PlayMode)
{ {
return -1; return false;
} }
void cDevice::TrickSpeed(int Speed) void cDevice::TrickSpeed(int Speed)
@ -361,7 +361,7 @@ bool cDevice::AttachPlayer(cPlayer *Player)
Detach(player); Detach(player);
player = Player; player = Player;
player->device = this; player->device = this;
SetPlayMode(true);//XXX SetPlayMode(player->playMode);
player->Activate(true); player->Activate(true);
return true; return true;
} }
@ -374,7 +374,7 @@ void cDevice::Detach(cPlayer *Player)
player->Activate(false); player->Activate(false);
player->device = NULL; player->device = NULL;
player = NULL; player = NULL;
SetPlayMode(false); SetPlayMode(pmNone);
} }
} }

View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and * See the main source file 'vdr.c' for copyright information and
* how to reach the author. * how to reach the author.
* *
* $Id: device.h 1.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 #ifndef __DEVICE_H
@ -26,6 +26,23 @@
enum eSetChannelResult { scrOk, scrNoTransfer, scrFailed }; 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 cChannel;
class cPlayer; class cPlayer;
class cReceiver; class cReceiver;
@ -190,11 +207,9 @@ public:
private: private:
cPlayer *player; cPlayer *player;
protected: protected:
virtual int SetPlayMode(bool On); virtual bool SetPlayMode(ePlayMode PlayMode);
// Sets the device into play mode (On = true) or normal // Sets the device into the given play mode.
// viewing mode (On = false). If On is true, it may return a file // Returns true if the operation was successful.
// handle that a player can use to poll this device when replaying.
//XXX TODO should be implemented differently
public: public:
virtual void TrickSpeed(int Speed); virtual void TrickSpeed(int Speed);
// Sets the device into a mode where replay is done slower. // Sets the device into a mode where replay is done slower.

View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and * See the main source file 'vdr.c' for copyright information and
* how to reach the author. * how to reach the author.
* *
* $Id: dvbdevice.c 1.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" #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 frontendType = FrontendType(-1); // don't know how else to initialize this - there is no FE_UNKNOWN
siProcessor = NULL; siProcessor = NULL;
playMode = pmNone;
// Devices that are present on all card types: // 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 (PlayMode != pmExtern_THIS_SHOULD_BE_AVOIDED && fd_video < 0 && fd_audio < 0) {
if (siProcessor) // reopen the devices
siProcessor->SetStatus(false); fd_video = DvbOpen(DEV_DVB_VIDEO, CardIndex(), O_RDWR | O_NONBLOCK);
CHECK(ioctl(fd_video, VIDEO_SET_BLANK, true)); fd_audio = DvbOpen(DEV_DVB_AUDIO, CardIndex(), O_RDWR | O_NONBLOCK);
CHECK(ioctl(fd_audio, AUDIO_SELECT_SOURCE, AUDIO_SOURCE_MEMORY)); SetVideoFormat(Setup.VideoFormat);
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;
} }
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) void cDvbDevice::TrickSpeed(int Speed)
@ -667,8 +701,9 @@ bool cDvbDevice::NeedsData(int Wait)
int cDvbDevice::PlayVideo(const uchar *Data, int Length) int cDvbDevice::PlayVideo(const uchar *Data, int Length)
{ {
if (fd_video >= 0) int fd = playMode == pmAudioOnly ? fd_audio : fd_video;
return write(fd_video, Data, Length); if (fd >= 0)
return write(fd, Data, Length);
return -1; return -1;
} }

View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and * See the main source file 'vdr.c' for copyright information and
* how to reach the author. * how to reach the author.
* *
* $Id: dvbdevice.h 1.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 #ifndef __DVBDEVICE_H
@ -83,7 +83,8 @@ private:
// Player facilities // Player facilities
protected: protected:
virtual int SetPlayMode(bool On); ePlayMode playMode;
virtual bool SetPlayMode(ePlayMode PlayMode);
public: public:
virtual void TrickSpeed(int Speed); virtual void TrickSpeed(int Speed);
virtual void Clear(void); virtual void Clear(void);

View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and * See the main source file 'vdr.c' for copyright information and
* how to reach the author. * how to reach the author.
* *
* $Id: player.c 1.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" #include "player.h"
@ -12,9 +12,10 @@
// --- cPlayer --------------------------------------------------------------- // --- cPlayer ---------------------------------------------------------------
cPlayer::cPlayer(void) cPlayer::cPlayer(ePlayMode PlayMode)
{ {
device = NULL; device = NULL;
playMode = PlayMode;
} }
cPlayer::~cPlayer() cPlayer::~cPlayer()

View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and * See the main source file 'vdr.c' for copyright information and
* how to reach the author. * how to reach the author.
* *
* $Id: player.h 1.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 #ifndef __PLAYER_H
@ -17,6 +17,7 @@ class cPlayer {
friend class cDevice; friend class cDevice;
private: private:
cDevice *device; cDevice *device;
ePlayMode playMode;
protected: protected:
bool DeviceNeedsData(int Wait = 0) { return device ? device->NeedsData(Wait) : false; } bool DeviceNeedsData(int Wait = 0) { return device ? device->NeedsData(Wait) : false; }
void DeviceTrickSpeed(int Speed) { if (device) device->TrickSpeed(Speed); } 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 DeviceStillPicture(const uchar *Data, int Length) { if (device) device->StillPicture(Data, Length); }
void Detach(void); void Detach(void);
virtual void Activate(bool On) {} virtual void Activate(bool On) {}
// This function is called right after the cPlayer has been attached to // This function is called right after the cPlayer has been attached to
// (On == true) or before it gets detached from (On == false) a cDevice. // (On == true) or before it gets detached from (On == false) a cDevice.
// It can be used to do things like starting/stopping a thread. // It can be used to do things like starting/stopping a thread.
int PlayVideo(const uchar *Data, int Length); int PlayVideo(const uchar *Data, int Length);
// Sends the given Data to the video device and returns the number of // 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 // bytes that have actually been accepted by the video device (or a
// negative value in case of an error). // negative value in case of an error).
int PlayAudio(const uchar *Data, int Length); int PlayAudio(const uchar *Data, int Length);
// XXX+ TODO // XXX+ TODO
public: public:
cPlayer(void); cPlayer(ePlayMode PlayMode = pmAudioVideo);
virtual ~cPlayer(); virtual ~cPlayer();
bool IsAttached(void) { return device != NULL; } bool IsAttached(void) { return device != NULL; }
virtual bool GetIndex(int &Current, int &Total, bool SnapToIFrame = false) { return false; } virtual bool GetIndex(int &Current, int &Total, bool SnapToIFrame = false) { return false; }