summaryrefslogtreecommitdiff
path: root/dvbplayer.c
diff options
context:
space:
mode:
authorKlaus Schmidinger <kls (at) cadsoft (dot) de>2002-08-16 18:00:00 +0200
committerKlaus Schmidinger <kls (at) cadsoft (dot) de>2002-08-16 18:00:00 +0200
commited643353b100bee75459c4ef2d0330e7a04e1f2a (patch)
tree8a424eba464677a71309e1125ce4e7acef58607e /dvbplayer.c
parent527748826c8d3cfacff8a7ab3fda9551c1182590 (diff)
downloadvdr-patch-lnbsharing-ed643353b100bee75459c4ef2d0330e7a04e1f2a.tar.gz
vdr-patch-lnbsharing-ed643353b100bee75459c4ef2d0330e7a04e1f2a.tar.bz2
Version 1.1.7vdr-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). By default it currently still uses the old driver. - Added some missing #includes (thanks to Martin Hammerschmid). - Changed the log error message "can't record MPEG1!" to "error in data stream!", since the mentioning of MPEG1 has irritated many people. - 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 DevicePoll() to see whether the replay device is ready for further data. A derived cDevice class must implement Poll() 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). - Improved cCondVar::Wait() and implemented cCondVar::TimedWait() (thanks to Stefan Huelswitt). - VDR no longer gives up if there is no DVB device. It continues to work if there is at least one device, either a DVB device found by the core VDR code itself, or a device implemented by a plugin.
Diffstat (limited to 'dvbplayer.c')
-rw-r--r--dvbplayer.c211
1 files changed, 101 insertions, 110 deletions
diff --git a/dvbplayer.c b/dvbplayer.c
index 1b608dd..2ca5a62 100644
--- a/dvbplayer.c
+++ b/dvbplayer.c
@@ -4,14 +4,15 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
- * $Id: dvbplayer.c 1.8 2002/07/27 11:57:48 kls Exp $
+ * $Id: dvbplayer.c 1.11 2002/08/16 09:16:38 kls Exp $
*/
#include "dvbplayer.h"
-#include <poll.h>
+#include <stdlib.h>
#include "recording.h"
#include "ringbuffer.h"
#include "thread.h"
+#include "tools.h"
// --- cBackTrace ----------------------------------------------------------
@@ -63,7 +64,7 @@ int cBackTrace::Get(bool Forward)
p = BACKTRACE_ENTRIES - 1;
i = index[p] - 1;
l -= length[p];
- n--;
+ n--;
}
return i;
}
@@ -301,121 +302,111 @@ void cDvbPlayer::Action(void)
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;
-
readIndex = Resume();
if (readIndex >= 0)
isyslog("resuming replay at index %d (%s)", readIndex, IndexToHMSF(readIndex, true));
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 (playMode != pmStill) {
- int r = 0;
- if (playMode == pmFast || (playMode == pmSlow && playDir == pdBackward)) {
- uchar FileNumber;
- int FileOffset, Length;
- int Index = index->GetNextIFrame(readIndex, playDir == pdForward, &FileNumber, &FileOffset, &Length, true);
- if (Index >= 0) {
- if (!NextFile(FileNumber, FileOffset))
- break;
- }
- else {
- // can't call Play() here, because those functions may only be
- // called from the foreground thread - and we also don't need
- // to empty the buffer here
- DevicePlay();
- playMode = pmPlay;
- playDir = pdForward;
- continue;
- }
- readIndex = Index;
- r = ReadFrame(replayFile, b, Length, sizeof(b));
- // must call StripAudioPackets() here because the buffer is not emptied
- // when falling back from "fast forward" to "play" (see above)
- StripAudioPackets(b, r);
- }
- else if (index) {
- uchar FileNumber;
- int FileOffset, Length;
- readIndex++;
- if (!(index->Get(readIndex, &FileNumber, &FileOffset, NULL, &Length) && NextFile(FileNumber, FileOffset)))
- break;
- r = ReadFrame(replayFile, b, Length, sizeof(b));
- }
- else // allows replay even if the index file is missing
- r = read(replayFile, b, sizeof(b));
- if (r > 0)
- readFrame = new cFrame(b, r, ftUnknown, readIndex);
- else if (r == 0)
- eof = true;
- else if (r < 0 && FATALERRNO) {
- LOG_ERROR;
- break;
- }
- }
- else//XXX
- usleep(1); // this keeps the CPU load low
- }
-
- // Store the frame in the buffer:
-
- if (readFrame) {
- if (ringBuffer->Put(readFrame))
- readFrame = NULL;
- }
-
- // Get the next frame from the buffer:
-
- if (!playFrame) {
- playFrame = ringBuffer->Get();
- p = NULL;
- pc = 0;
- }
-
- // Play the frame:
-
- if (playFrame && (pfd[0].revents & POLLOUT)) {
- if (!p) {
- p = playFrame->Data();
- pc = playFrame->Count();
- }
- if (p) {
- int w = PlayVideo(p, pc);
- if (w > 0) {
- p += w;
- pc -= w;
- }
- else if (w < 0 && FATALERRNO) {
- LOG_ERROR;
- break;
- }
- }
- if (pc == 0) {
- writeIndex = playFrame->Index();
- backTrace->Add(playFrame->Index(), playFrame->Count());
- ringBuffer->Drop(playFrame);
- playFrame = NULL;
- p = 0;
- }
- }
- }
+ cPoller Poller;
+ if (!readFrame)
+ Poller.Add(replayFile, false);
+ if (DevicePoll(Poller, 100)) {
+
+ LOCK_THREAD;
+
+ // Read the next frame from the file:
+
+ if (!readFrame) {
+ if (playMode != pmStill) {
+ int r = 0;
+ if (playMode == pmFast || (playMode == pmSlow && playDir == pdBackward)) {
+ uchar FileNumber;
+ int FileOffset, Length;
+ int Index = index->GetNextIFrame(readIndex, playDir == pdForward, &FileNumber, &FileOffset, &Length, true);
+ if (Index >= 0) {
+ if (!NextFile(FileNumber, FileOffset))
+ break;
+ }
+ else {
+ // can't call Play() here, because those functions may only be
+ // called from the foreground thread - and we also don't need
+ // to empty the buffer here
+ DevicePlay();
+ playMode = pmPlay;
+ playDir = pdForward;
+ continue;
+ }
+ readIndex = Index;
+ r = ReadFrame(replayFile, b, Length, sizeof(b));
+ // must call StripAudioPackets() here because the buffer is not emptied
+ // when falling back from "fast forward" to "play" (see above)
+ StripAudioPackets(b, r);
+ }
+ else if (index) {
+ uchar FileNumber;
+ int FileOffset, Length;
+ readIndex++;
+ if (!(index->Get(readIndex, &FileNumber, &FileOffset, NULL, &Length) && NextFile(FileNumber, FileOffset)))
+ break;
+ r = ReadFrame(replayFile, b, Length, sizeof(b));
+ }
+ else // allows replay even if the index file is missing
+ r = read(replayFile, b, sizeof(b));
+ if (r > 0)
+ readFrame = new cFrame(b, r, ftUnknown, readIndex);
+ else if (r == 0)
+ eof = true;
+ else if (r < 0 && FATALERRNO) {
+ LOG_ERROR;
+ break;
+ }
+ }
+ else//XXX
+ usleep(1); // this keeps the CPU load low
+ }
- // Wait for input or output to become ready:
+ // Store the frame in the buffer:
- if (poll(pfd, readFrame ? 1 : 2, 10) < 0 && FATALERRNO) {
- LOG_ERROR;
- break;
+ if (readFrame) {
+ if (ringBuffer->Put(readFrame))
+ readFrame = NULL;
+ }
+
+ // Get the next frame from the buffer:
+
+ if (!playFrame) {
+ playFrame = ringBuffer->Get();
+ p = NULL;
+ pc = 0;
+ }
+
+ // Play the frame:
+
+ if (playFrame) {
+ if (!p) {
+ p = playFrame->Data();
+ pc = playFrame->Count();
+ }
+ if (p) {
+ int w = PlayVideo(p, pc);
+ if (w > 0) {
+ p += w;
+ pc -= w;
+ }
+ else if (w < 0 && FATALERRNO) {
+ LOG_ERROR;
+ break;
+ }
+ }
+ if (pc == 0) {
+ writeIndex = playFrame->Index();
+ backTrace->Add(playFrame->Index(), playFrame->Count());
+ ringBuffer->Drop(playFrame);
+ playFrame = NULL;
+ p = 0;
+ }
+ }
}
}
active = running = false;