summaryrefslogtreecommitdiff
path: root/dvbplayer.c
diff options
context:
space:
mode:
Diffstat (limited to 'dvbplayer.c')
-rw-r--r--dvbplayer.c80
1 files changed, 36 insertions, 44 deletions
diff --git a/dvbplayer.c b/dvbplayer.c
index 0fe8d34..9de7e48 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 2.0 2008/02/09 15:10:54 kls Exp $
+ * $Id: dvbplayer.c 2.1 2009/01/05 16:52:40 kls Exp $
*/
#include "dvbplayer.h"
@@ -182,8 +182,8 @@ bool cNonBlockingFileReader::WaitForDataMs(int msToWait)
#define PLAYERBUFSIZE MEGABYTE(1)
-// The number of frames to back up when resuming an interrupted replay session:
-#define RESUMEBACKUP (10 * FRAMESPERSEC)
+// The number of seconds to back up when resuming an interrupted replay session:
+#define RESUMEBACKUP 10
class cDvbPlayer : public cPlayer, cThread {
private:
@@ -196,6 +196,8 @@ private:
cFileName *fileName;
cIndexFile *index;
cUnbufferedFile *replayFile;
+ double framesPerSecond;
+ bool isPesRecording;
bool eof;
bool firstPacket;
ePlayModes playMode;
@@ -223,6 +225,7 @@ public:
int SkipFrames(int Frames);
void SkipSeconds(int Seconds);
void Goto(int Position, bool Still = false);
+ virtual double FramesPerSecond(void) { return framesPerSecond; }
virtual bool GetIndex(int &Current, int &Total, bool SnapToIFrame = false);
virtual bool GetReplayMode(bool &Play, bool &Forward, int &Speed);
};
@@ -240,6 +243,9 @@ cDvbPlayer::cDvbPlayer(const char *FileName)
ringBuffer = NULL;
backTrace = NULL;
index = NULL;
+ cRecording Recording(FileName);
+ framesPerSecond = Recording.FramesPerSecond();
+ isPesRecording = Recording.IsPesRecording();
eof = false;
firstPacket = true;
playMode = pmPlay;
@@ -249,13 +255,13 @@ cDvbPlayer::cDvbPlayer(const char *FileName)
readFrame = NULL;
playFrame = NULL;
isyslog("replay %s", FileName);
- fileName = new cFileName(FileName, false);
+ fileName = new cFileName(FileName, false, false, isPesRecording);
replayFile = fileName->Open();
if (!replayFile)
return;
ringBuffer = new cRingBufferFrame(PLAYERBUFSIZE);
// Create the index file:
- index = new cIndexFile(FileName, false);
+ index = new cIndexFile(FileName, false, isPesRecording);
if (!index)
esyslog("ERROR: can't allocate index");
else if (!index->Ok()) {
@@ -327,8 +333,8 @@ int cDvbPlayer::Resume(void)
if (index) {
int Index = index->GetResume();
if (Index >= 0) {
- uchar FileNumber;
- int FileOffset;
+ uint16_t FileNumber;
+ off_t FileOffset;
if (index->Get(Index, &FileNumber, &FileOffset) && NextFile(FileNumber, FileOffset))
return Index;
}
@@ -341,7 +347,7 @@ bool cDvbPlayer::Save(void)
if (index) {
int Index = writeIndex;
if (Index >= 0) {
- Index -= RESUMEBACKUP;
+ Index -= RESUMEBACKUP * framesPerSecond;
if (Index > 0)
Index = index->GetNextIFrame(Index, false);
else
@@ -371,7 +377,7 @@ void cDvbPlayer::Action(void)
readIndex = Resume();
if (readIndex >= 0)
- isyslog("resuming replay at index %d (%s)", readIndex, *IndexToHMSF(readIndex, true));
+ isyslog("resuming replay at index %d (%s)", readIndex, *IndexToHMSF(readIndex, true, framesPerSecond));
nonBlockingFileReader = new cNonBlockingFileReader;
int Length = 0;
@@ -397,8 +403,8 @@ void cDvbPlayer::Action(void)
if (!readFrame && (replayFile || readIndex >= 0)) {
if (!nonBlockingFileReader->Reading()) {
if (playMode == pmFast || (playMode == pmSlow && playDir == pdBackward)) {
- uchar FileNumber;
- int FileOffset;
+ uint16_t FileNumber;
+ off_t FileOffset;
bool TimeShiftMode = index->IsStillRecording();
int Index = -1;
if (DeviceHasIBPTrickSpeed() && playDir == pdForward) {
@@ -435,8 +441,8 @@ void cDvbPlayer::Action(void)
readIndex = Index;
}
else if (index) {
- uchar FileNumber;
- int FileOffset;
+ uint16_t FileNumber;
+ off_t FileOffset;
readIndex++;
if (!(index->Get(readIndex, &FileNumber, &FileOffset, NULL, &Length) && NextFile(FileNumber, FileOffset))) {
readIndex = -1;
@@ -496,14 +502,22 @@ void cDvbPlayer::Action(void)
pc = playFrame->Count();
if (p) {
if (firstPacket) {
- PlayPes(NULL, 0);
- cRemux::SetBrokenLink(p, pc);
+ if (isPesRecording) {
+ PlayPes(NULL, 0);
+ cRemux::SetBrokenLink(p, pc);
+ }
+ else
+ PlayTs(NULL, 0);
firstPacket = false;
}
}
}
if (p) {
- int w = PlayPes(p, pc, playMode != pmPlay);
+ int w;
+ if (isPesRecording)
+ w = PlayPes(p, pc, playMode != pmPlay);
+ else
+ w = PlayTs(p, TS_SIZE, playMode != pmPlay);
if (w > 0) {
p += w;
pc -= w;
@@ -513,7 +527,7 @@ void cDvbPlayer::Action(void)
break;
}
}
- if (pc == 0) {
+ if (pc <= 0) {
writeIndex = playFrame->Index();
backTrace->Add(playFrame->Index(), playFrame->Count());
ringBuffer->Drop(playFrame);
@@ -678,7 +692,7 @@ void cDvbPlayer::SkipSeconds(int Seconds)
Empty();
int Index = writeIndex;
if (Index >= 0) {
- Index = max(Index + Seconds * FRAMESPERSEC, 0);
+ Index = max(Index + SecondsToFrames(Seconds, framesPerSecond), 0);
if (Index > 0)
Index = index->GetNextIFrame(Index, false, NULL, NULL, NULL, true);
if (Index >= 0)
@@ -695,38 +709,16 @@ void cDvbPlayer::Goto(int Index, bool Still)
Empty();
if (++Index <= 0)
Index = 1; // not '0', to allow GetNextIFrame() below to work!
- uchar FileNumber;
- int FileOffset, Length;
+ uint16_t FileNumber;
+ off_t FileOffset;
+ int Length;
Index = index->GetNextIFrame(Index, false, &FileNumber, &FileOffset, &Length);
if (Index >= 0 && NextFile(FileNumber, FileOffset) && Still) {
- uchar b[MAXFRAMESIZE + 4 + 5 + 4];
+ uchar b[MAXFRAMESIZE];
int r = ReadFrame(replayFile, b, Length, sizeof(b));
if (r > 0) {
if (playMode == pmPause)
DevicePlay();
- // append sequence end code to get the image shown immediately with softdevices
- if (r > 6 && (b[3] & 0xF0) == 0xE0) { // make sure to append it only to a video packet
- b[r++] = 0x00;
- b[r++] = 0x00;
- b[r++] = 0x01;
- b[r++] = b[3];
- if (b[6] & 0x80) { // MPEG 2
- b[r++] = 0x00;
- b[r++] = 0x07;
- b[r++] = 0x80;
- b[r++] = 0x00;
- b[r++] = 0x00;
- }
- else { // MPEG 1
- b[r++] = 0x00;
- b[r++] = 0x05;
- b[r++] = 0x0F;
- }
- b[r++] = 0x00;
- b[r++] = 0x00;
- b[r++] = 0x01;
- b[r++] = 0xB7;
- }
DeviceStillPicture(b, r);
}
playMode = pmStill;