diff options
author | Klaus Schmidinger <vdr@tvdr.de> | 2002-08-15 10:13:03 +0200 |
---|---|---|
committer | Klaus Schmidinger <vdr@tvdr.de> | 2002-08-15 10:13:03 +0200 |
commit | d4ab35d1d92e14e9a4e7490058546642da728e02 (patch) | |
tree | 95cd2a77cfb8c83f189b509802d99c1567070a86 | |
parent | 2f684611d488fb3b05680b8d40e1a4d0b3e124fc (diff) | |
download | vdr-d4ab35d1d92e14e9a4e7490058546642da728e02.tar.gz vdr-d4ab35d1d92e14e9a4e7490058546642da728e02.tar.bz2 |
Implemented cDevice::NeedsData()
-rw-r--r-- | HISTORY | 6 | ||||
-rw-r--r-- | PLUGINS.html | 40 | ||||
-rw-r--r-- | device.c | 11 | ||||
-rw-r--r-- | device.h | 7 | ||||
-rw-r--r-- | dvbdevice.c | 7 | ||||
-rw-r--r-- | dvbdevice.h | 3 | ||||
-rw-r--r-- | dvbplayer.c | 23 | ||||
-rw-r--r-- | player.c | 3 | ||||
-rw-r--r-- | player.h | 5 |
9 files changed, 58 insertions, 47 deletions
@@ -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. diff --git a/PLUGINS.html b/PLUGINS.html index c9d6c542..c0f6d8ab 100644 --- a/PLUGINS.html +++ b/PLUGINS.html @@ -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> </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> </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> </td><td width=100%> +<!--X1.1.4--><table width=100%><tr><td bgcolor=#0000AA> </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> </td><td width=100%> +<!--X1.1.5--><table width=100%><tr><td bgcolor=#00AA00> </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> </td><td width=100%> +<!--X1.1.6--><table width=100%><tr><td bgcolor=#AA0000> </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> </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> </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> </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> </td><td width=100%> +<!--X1.1.4--><table width=100%><tr><td bgcolor=#0000AA> </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> </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> </td><td width=100%> +<!--X1.1.6--><table width=100%><tr><td bgcolor=#AA0000> </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> </td><td width=100%> +<!--X1.1.5--><table width=100%><tr><td bgcolor=#00AA00> </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> </td><td width=100%> +<!--X1.1.6--><table width=100%><tr><td bgcolor=#AA0000> </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> </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: @@ -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; @@ -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 diff --git a/dvbdevice.c b/dvbdevice.c index 3c54d70d..b37a98db 100644 --- a/dvbdevice.c +++ b/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.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) diff --git a/dvbdevice.h b/dvbdevice.h index 3cf3304d..11c963a7 100644 --- a/dvbdevice.h +++ b/dvbdevice.h @@ -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); diff --git a/dvbplayer.c b/dvbplayer.c index 159f1b53..e2d011db 100644 --- a/dvbplayer.c +++ b/dvbplayer.c @@ -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; @@ -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() @@ -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(); } |