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 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
|
||||||
|
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
|
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).
|
||||||
|
@ -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%>
|
<!--X1.1.7--><table width=100%><tr><td bgcolor=#FF0000> </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);
|
||||||
|
10
device.c
10
device.c
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
27
device.h
27
device.h
@ -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.
|
||||||
|
89
dvbdevice.c
89
dvbdevice.c
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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);
|
||||||
|
5
player.c
5
player.c
@ -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()
|
||||||
|
17
player.h
17
player.h
@ -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; }
|
||||||
|
Loading…
Reference in New Issue
Block a user