diff options
author | Klaus Schmidinger <kls (at) cadsoft (dot) de> | 2002-08-16 18:00:00 +0200 |
---|---|---|
committer | Klaus Schmidinger <kls (at) cadsoft (dot) de> | 2002-08-16 18:00:00 +0200 |
commit | ed643353b100bee75459c4ef2d0330e7a04e1f2a (patch) | |
tree | 8a424eba464677a71309e1125ce4e7acef58607e /dvbplayer.c | |
parent | 527748826c8d3cfacff8a7ab3fda9551c1182590 (diff) | |
download | vdr-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.c | 211 |
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; |