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 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

View File

@ -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).

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%>
<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);

View File

@ -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);
}
}

View File

@ -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.

View File

@ -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;
}

View File

@ -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);

View File

@ -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()

View File

@ -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; }