1
0
mirror of https://github.com/VDR4Arch/vdr.git synced 2023-10-10 13:36:52 +02:00

Implemented cDevice::NeedsData()

This commit is contained in:
Klaus Schmidinger 2002-08-15 10:13:03 +02:00
parent 2f684611d4
commit d4ab35d1d9
9 changed files with 58 additions and 47 deletions

View File

@ -1393,7 +1393,7 @@ Video Disk Recorder Revision History
- Changed the cDevice class to allow plugins to implement their own devices (see
PLUGINS.html for details).
2002-08-11: Version 1.1.7
2002-08-15: Version 1.1.7
- Adapted VDR to the NEWSTRUCT driver. To use the new driver, compile VDR with
'make NEWSTRUCT=1' (thanks to Holger Wächtler for some valuable advice).
@ -1404,3 +1404,7 @@ Video Disk Recorder Revision History
- Consistently using malloc/free and new/delete (thanks to Andreas Schultz).
- Temporarily made cDevice::ProvidesCa() virtual (Andreas Schultz needs this
in his DXR3 plugin).
- cDevice no longer exposes a file handle to cPlayer. A derived cPlayer class
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.

View File

@ -12,7 +12,6 @@ This interface allows programmers to develop additional functionality for VDR co
separate from the core VDR source, without the need of patching the original
VDR code (and all the problems of correlating various patches).
<p>
<!--X1.1.3--><table width=100%><tr><td bgcolor=#0000AA>&nbsp;</td><td width=100%>
This document is divided into two parts, the first one describing the
<a href="#Part I - The Outside Interface"><i>outside</i> interface</a>
of the plugin system, and the second one describing the
@ -21,20 +20,19 @@ The <i>outside</i> interface handles everything necessary for a plugin to get ho
VDR program and present itself to the user.
The <i>inside</i> interface provides the plugin code access to VDR's internal data
structures and allows it to hook itself into specific areas to perform special actions.
<!--X1.1.3--></td></tr></table>
<p>
<!--X1.1.3--><table width=100%><tr><td bgcolor=#0000AA>&nbsp;</td><td width=100%>
Important modifications introduced in version 1.1.3 are marked like this.
<!--X1.1.3--></td></tr></table>
<!--X1.1.4--><table width=100%><tr><td bgcolor=#00AA00>&nbsp;</td><td width=100%>
<!--X1.1.4--><table width=100%><tr><td bgcolor=#0000AA>&nbsp;</td><td width=100%>
Important modifications introduced in version 1.1.4 are marked like this.
<!--X1.1.4--></td></tr></table>
<!--X1.1.5--><table width=100%><tr><td bgcolor=#AA0000>&nbsp;</td><td width=100%>
<!--X1.1.5--><table width=100%><tr><td bgcolor=#00AA00>&nbsp;</td><td width=100%>
Important modifications introduced in version 1.1.5 are marked like this.
<!--X1.1.5--></td></tr></table>
<!--X1.1.6--><table width=100%><tr><td bgcolor=#FF0000>&nbsp;</td><td width=100%>
<!--X1.1.6--><table width=100%><tr><td bgcolor=#AA0000>&nbsp;</td><td width=100%>
Important modifications introduced in version 1.1.6 are marked like this.
<!--X1.1.6--></td></tr></table>
<!--X1.1.7--><table width=100%><tr><td bgcolor=#FF0000>&nbsp;</td><td width=100%>
Important modifications introduced in version 1.1.7 are marked like this.
<!--X1.1.7--></td></tr></table>
<a name="Part I - The Outside Interface"><hr><center><h1>Part I - The Outside Interface</h1></center>
@ -814,7 +812,6 @@ and display their help and/or version information in addition to its own output.
If you want to make your plugin available to other VDR users, you'll need to
make a package that can be easily distributed.
<!--X1.1.3--><table width=100%><tr><td bgcolor=#0000AA>&nbsp;</td><td width=100%>
The <tt>Makefile</tt> that has been created by the call to
<a href="#Initializing a new plugin directory"><tt>newplugin</tt></a>
provides the target <tt>dist</tt>, which does this for you.
@ -825,7 +822,6 @@ Simply change into your source directory and execute <tt>make dist</tt>:
cd VDR/PLUGINS/src/hello
make dist
</pre></td></tr></table><p>
<!--X1.1.3--></td></tr></table>
After this you should find a file named like
@ -836,7 +832,6 @@ vdr-hello-0.0.1.tgz
in your source directory, where <tt>hello</tt> will be replaced with your actual
plugin's name, and <tt>0.0.1</tt> will be your plugin's current version number.
<!--X1.1.3--><table width=100%><tr><td bgcolor=#0000AA>&nbsp;</td><td width=100%>
<a name="Part II - The Inside Interface"><hr><center><h1>Part II - The Inside Interface</h1></center>
<hr><h2>Status monitor</h2>
@ -911,9 +906,8 @@ objects were created.
See the file <tt>status.h</tt> for detailed information on which status monitor
member functions are available in <tt>cStatus</tt>. You only need to implement
the functions you actually want to use.
<!--X1.1.3--></td></tr></table>
<!--X1.1.4--><table width=100%><tr><td bgcolor=#00AA00>&nbsp;</td><td width=100%>
<!--X1.1.4--><table width=100%><tr><td bgcolor=#0000AA>&nbsp;</td><td width=100%>
<hr><h2>Players</h2>
<center><i><b>Play it again, Sam!</b></i></center><p>
@ -959,11 +953,20 @@ To play the video data, the player needs to call its member function
int PlayVideo(const uchar *Data, int Length);
</pre></td></tr></table><p>
where <tt>Data</tt> point to a block of <tt>Length</tt> bytes of a PES data
where <tt>Data</tt> points to a block of <tt>Length</tt> bytes of a PES data
stream. There are no prerequisites regarding the length or alignment of an
individual block of data. The sum of all blocks must simply result in the
desired video data stream, and it must be delivered fast enough so that the
DVB device doesn't run out of data.
<!--X1.1.7--><table width=100%><tr><td bgcolor=#FF0000>&nbsp;</td><td width=100%>
To avoid busy loops the player should call its member function
<p><table><tr><td bgcolor=#F0F0F0><pre><br>
bool DeviceNeedsData(int Wait = 0);
</pre></td></tr></table><p>
to determine whether the device is ready for further data.
<!--X1.1.7--></td></tr></table>
<p>
TODO: PlayAudio()???
<p>
@ -1064,7 +1067,7 @@ that they already know. If you absolutely want to do things differently, just go
ahead - it's your show...
<!--X1.1.4--></td></tr></table>
<!--X1.1.6--><table width=100%><tr><td bgcolor=#FF0000>&nbsp;</td><td width=100%>
<!--X1.1.6--><table width=100%><tr><td bgcolor=#AA0000>&nbsp;</td><td width=100%>
<hr><h2>Receivers</h2>
<center><i><b>Tapping into the stream...</b></i></center><p>
@ -1120,7 +1123,7 @@ If the <tt>cReceiver</tt> isn't needed any more, it may simply be <i>deleted</i>
and will automatically detach itself from the <tt>cDevice</tt>.
<!--X1.1.6--></td></tr></table>
<!--X1.1.5--><table width=100%><tr><td bgcolor=#AA0000>&nbsp;</td><td width=100%>
<!--X1.1.5--><table width=100%><tr><td bgcolor=#00AA00>&nbsp;</td><td width=100%>
<hr><h2>The On Screen Display</h2>
<center><i><b>Express yourself</b></i></center><p>
@ -1152,7 +1155,7 @@ of these functions, and VDR/osd.c to see how VDR opens the OSD and sets up
its windows and color depths).
<!--X1.1.5--></td></tr></table>
<!--X1.1.6--><table width=100%><tr><td bgcolor=#FF0000>&nbsp;</td><td width=100%>
<!--X1.1.6--><table width=100%><tr><td bgcolor=#AA0000>&nbsp;</td><td width=100%>
<hr><h2>Devices</h2>
<center><i><b>Expanding the possibilities</b></i></center><p>
@ -1225,6 +1228,7 @@ to indicate this to VDR.
<p>
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);
@ -1234,8 +1238,10 @@ virtual void Play(void);
virtual void Freeze(void);
virtual void Mute(void);
virtual void StillPicture(const uchar *Data, int Length);
virtual bool NeedsData(int Wait = 0);
virtual int PlayVideo(const uchar *Data, int Length);
</pre></td></tr></table><p>
<!--X1.1.7--></td></tr></table>
In addition, the following functions may be implemented to provide further
functionality:

View File

@ -4,12 +4,11 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
* $Id: device.c 1.8 2002/08/04 15:18:05 kls Exp $
* $Id: device.c 1.9 2002/08/15 09:59:57 kls Exp $
*/
#include "device.h"
#include <errno.h>
#include <poll.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include "eit.h"
@ -362,7 +361,7 @@ bool cDevice::AttachPlayer(cPlayer *Player)
Detach(player);
player = Player;
player->device = this;
player->deviceFileHandle = SetPlayMode(true);
SetPlayMode(true);//XXX
player->Activate(true);
return true;
}
@ -373,7 +372,6 @@ void cDevice::Detach(cPlayer *Player)
{
if (Player && player == Player) {
player->Activate(false);
player->deviceFileHandle = -1;
player->device = NULL;
player = NULL;
SetPlayMode(false);
@ -399,6 +397,11 @@ void cDevice::StopReplay(void)
}
}
bool cDevice::NeedsData(int Wait)
{
return false;
}
int cDevice::PlayVideo(const uchar *Data, int 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: device.h 1.6 2002/08/11 13:38:13 kls Exp $
* $Id: device.h 1.7 2002/08/15 09:22:13 kls Exp $
*/
#ifndef __DEVICE_H
@ -211,6 +211,11 @@ public:
// Turns off audio while replaying.
virtual void StillPicture(const uchar *Data, int Length);
// Displays the given I-frame as a still picture.
virtual bool NeedsData(int Wait = 0);
// Returns true if the device needs further data for replaying.
// If Wait is not zero, the device will wait up to the given number
// of milleseconds before returning in case there is no immediate
// need for data.
virtual int PlayVideo(const uchar *Data, int Length);
// Actually plays the given data block as video. The data must be
// part of a PES (Packetized Elementary Stream) which can contain

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.3 2002/08/11 12:03:33 kls Exp $
* $Id: dvbdevice.c 1.4 2002/08/15 09:59:33 kls Exp $
*/
#include "dvbdevice.h"
@ -660,6 +660,11 @@ void cDvbDevice::StillPicture(const uchar *Data, int Length)
#endif
}
bool cDvbDevice::NeedsData(int Wait)
{
return cFile::FileReadyForWriting(fd_video, Wait);
}
int cDvbDevice::PlayVideo(const uchar *Data, int Length)
{
if (fd_video >= 0)

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.2 2002/08/09 16:23:53 kls Exp $
* $Id: dvbdevice.h 1.3 2002/08/15 09:28:36 kls Exp $
*/
#ifndef __DVBDEVICE_H
@ -91,6 +91,7 @@ public:
virtual void Freeze(void);
virtual void Mute(void);
virtual void StillPicture(const uchar *Data, int Length);
virtual bool NeedsData(int Wait = 0);
virtual int PlayVideo(const uchar *Data, int Length);
virtual int PlayAudio(const uchar *Data, int Length);

View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
* $Id: dvbplayer.c 1.9 2002/08/11 10:46:53 kls Exp $
* $Id: dvbplayer.c 1.10 2002/08/15 10:00:28 kls Exp $
*/
#include "dvbplayer.h"
@ -13,6 +13,7 @@
#include "recording.h"
#include "ringbuffer.h"
#include "thread.h"
#include "tools.h"
// --- cBackTrace ----------------------------------------------------------
@ -301,12 +302,7 @@ void cDvbPlayer::Action(void)
uchar b[MAXFRAMESIZE];
const uchar *p = NULL;
int pc = 0;
pollfd pfd[2];
pfd[0].fd = DeviceFileHandle();
pfd[0].events = pfd[0].revents = POLLOUT;
pfd[1].fd = replayFile;
pfd[1].events = pfd[1].revents = POLLIN;
bool CanWrite = true;
readIndex = Resume();
if (readIndex >= 0)
@ -314,13 +310,12 @@ void cDvbPlayer::Action(void)
running = true;
while (running && NextFile()) {
pfd[1].fd = replayFile; // NextFile() may have returned a new file handle!
{
LOCK_THREAD;
// Read the next frame from the file:
if (!readFrame && (pfd[1].revents & POLLIN)) {
if (!readFrame) {
if (playMode != pmStill) {
int r = 0;
if (playMode == pmFast || (playMode == pmSlow && playDir == pdBackward)) {
@ -386,7 +381,7 @@ void cDvbPlayer::Action(void)
// Play the frame:
if (playFrame && (pfd[0].revents & POLLOUT)) {
if (playFrame && CanWrite) {
if (!p) {
p = playFrame->Data();
pc = playFrame->Count();
@ -411,13 +406,7 @@ void cDvbPlayer::Action(void)
}
}
}
// Wait for input or output to become ready:
if (poll(pfd, readFrame ? 1 : 2, 10) < 0 && FATALERRNO) {
LOG_ERROR;
break;
}
CanWrite = DeviceNeedsData(readFrame ? 10 : 0);
}
active = running = false;

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.3 2002/06/23 12:56:25 kls Exp $
* $Id: player.c 1.4 2002/08/11 15:49:13 kls Exp $
*/
#include "player.h"
@ -15,7 +15,6 @@
cPlayer::cPlayer(void)
{
device = NULL;
deviceFileHandle = -1;
}
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.5 2002/07/13 11:12:26 kls Exp $
* $Id: player.h 1.6 2002/08/15 09:34:08 kls Exp $
*/
#ifndef __PLAYER_H
@ -17,9 +17,8 @@ class cPlayer {
friend class cDevice;
private:
cDevice *device;
int deviceFileHandle;
protected:
int DeviceFileHandle(void) { return deviceFileHandle; } //XXX+ needed for polling
bool DeviceNeedsData(int Wait = 0) { return device ? device->NeedsData(Wait) : false; }
void DeviceTrickSpeed(int Speed) { if (device) device->TrickSpeed(Speed); }
void DeviceClear(void) { if (device) device->Clear(); }
void DevicePlay(void) { if (device) device->Play(); }