mirror of
https://github.com/VDR4Arch/vdr.git
synced 2023-10-10 13:36:52 +02:00
Implemented several replay modes to allow players that play only audio
This commit is contained in:
parent
d4ab35d1d9
commit
c0ef9a35e2
@ -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
|
||||
|
2
HISTORY
2
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).
|
||||
|
@ -1231,7 +1231,7 @@ The functions to implement replaying capabilites are
|
||||
<!--X1.1.7--><table width=100%><tr><td bgcolor=#FF0000> </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);
|
||||
|
10
device.c
10
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);
|
||||
}
|
||||
}
|
||||
|
||||
|
27
device.h
27
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.
|
||||
|
89
dvbdevice.c
89
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;
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
5
player.c
5
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()
|
||||
|
17
player.h
17
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; }
|
||||
|
Loading…
Reference in New Issue
Block a user