Simultaneous record/replay with two DVB cards

This commit is contained in:
Klaus Schmidinger 2000-05-27 14:07:17 +02:00
parent 5d34487621
commit 86f14230c2
2 changed files with 78 additions and 20 deletions

View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and * See the main source file 'vdr.c' for copyright information and
* how to reach the author. * how to reach the author.
* *
* $Id: dvbapi.c 1.9 2000/05/01 13:18:29 kls Exp $ * $Id: dvbapi.c 1.10 2000/05/27 14:07:17 kls Exp $
*/ */
#include "dvbapi.h" #include "dvbapi.h"
@ -70,8 +70,9 @@ private:
struct tIndex { int offset; uchar type; uchar number; short reserved; }; struct tIndex { int offset; uchar type; uchar number; short reserved; };
int f; int f;
char *fileName, *pFileExt; char *fileName, *pFileExt;
int last, resume; int size, last, resume;
tIndex *index; tIndex *index;
bool CatchUp(void);
public: public:
cIndexFile(const char *FileName, bool Record = false); cIndexFile(const char *FileName, bool Record = false);
~cIndexFile(); ~cIndexFile();
@ -89,6 +90,7 @@ cIndexFile::cIndexFile(const char *FileName, bool Record)
{ {
f = -1; f = -1;
fileName = pFileExt = NULL; fileName = pFileExt = NULL;
size = 0;
last = resume = -1; last = resume = -1;
index = NULL; index = NULL;
if (FileName) { if (FileName) {
@ -108,19 +110,26 @@ cIndexFile::cIndexFile(const char *FileName, bool Record)
} }
last = (buf.st_size + delta) / sizeof(tIndex) - 1; last = (buf.st_size + delta) / sizeof(tIndex) - 1;
if (!Record && last >= 0) { if (!Record && last >= 0) {
index = new tIndex[last + 1]; size = last + 1;
int fi = open(fileName, O_RDONLY); index = new tIndex[size];
if (fi >= 0) { if (index) {
if ((int)read(fi, index, buf.st_size) != buf.st_size) { f = open(fileName, O_RDONLY);
if (f >= 0) {
if ((int)read(f, index, buf.st_size) != buf.st_size) {
esyslog(LOG_ERR, "ERROR: can't read from file '%s'", fileName); esyslog(LOG_ERR, "ERROR: can't read from file '%s'", fileName);
delete index; delete index;
index = NULL; index = NULL;
close(f);
f = -1;
} }
close(fi); // we don't close f here, see CatchUp()!
} }
else else
LOG_ERROR_STR(fileName); LOG_ERROR_STR(fileName);
} }
else
esyslog(LOG_ERR, "ERROR: can't allocate %d bytes for index '%s'", size * sizeof(tIndex), fileName);
}
} }
else else
LOG_ERROR; LOG_ERROR;
@ -164,6 +173,46 @@ cIndexFile::~cIndexFile()
delete fileName; delete fileName;
} }
bool cIndexFile::CatchUp(void)
{
if (index && f >= 0) {
struct stat buf;
if (fstat(f, &buf) == 0) {
int newLast = buf.st_size / sizeof(tIndex) - 1;
if (newLast > last) {
if (size <= newLast) {
size *= 2;
if (size <= newLast)
size = newLast + 1;
}
index = (tIndex *)realloc(index, size * sizeof(tIndex));
if (index) {
int offset = (last + 1) * sizeof(tIndex);
int delta = (newLast - last) * sizeof(tIndex);
if (lseek(f, offset, SEEK_SET) == offset) {
if (read(f, &index[last + 1], delta) != delta) {
esyslog(LOG_ERR, "ERROR: can't read from index");
delete index;
index = NULL;
close(f);
f = -1;
}
last = newLast;
return true;
}
else
LOG_ERROR;
}
else
esyslog(LOG_ERR, "ERROR: can't realloc() index");
}
}
else
LOG_ERROR;
}
return false;
}
void cIndexFile::Write(uchar PictureType, uchar FileNumber, int FileOffset) void cIndexFile::Write(uchar PictureType, uchar FileNumber, int FileOffset)
{ {
if (f >= 0) { if (f >= 0) {
@ -181,6 +230,7 @@ void cIndexFile::Write(uchar PictureType, uchar FileNumber, int FileOffset)
bool cIndexFile::Get(int Index, uchar *FileNumber, int *FileOffset, uchar *PictureType) bool cIndexFile::Get(int Index, uchar *FileNumber, int *FileOffset, uchar *PictureType)
{ {
if (index) { if (index) {
CatchUp();
if (Index >= 0 && Index <= last) { if (Index >= 0 && Index <= last) {
*FileNumber = index[Index].number; *FileNumber = index[Index].number;
*FileOffset = index[Index].offset; *FileOffset = index[Index].offset;
@ -195,10 +245,12 @@ bool cIndexFile::Get(int Index, uchar *FileNumber, int *FileOffset, uchar *Pictu
int cIndexFile::GetNextIFrame(int Index, bool Forward, uchar *FileNumber, int *FileOffset, int *Length) int cIndexFile::GetNextIFrame(int Index, bool Forward, uchar *FileNumber, int *FileOffset, int *Length)
{ {
if (index) { if (index) {
if (Forward)
CatchUp();
int d = Forward ? 1 : -1; int d = Forward ? 1 : -1;
for (;;) { for (;;) {
Index += d; Index += d;
if (Index >= 0 && Index <= last) { if (Index >= 0 && Index <= last - 100) { // '- 100': need to stay off the end!
if (index[Index].type == I_FRAME) { if (index[Index].type == I_FRAME) {
*FileNumber = index[Index].number; *FileNumber = index[Index].number;
*FileOffset = index[Index].offset; *FileOffset = index[Index].offset;
@ -226,6 +278,7 @@ int cIndexFile::GetNextIFrame(int Index, bool Forward, uchar *FileNumber, int *F
int cIndexFile::Get(uchar FileNumber, int FileOffset) int cIndexFile::Get(uchar FileNumber, int FileOffset)
{ {
if (index) { if (index) {
CatchUp();
//TODO implement binary search! //TODO implement binary search!
int i; int i;
for (i = 0; i < last; i++) { for (i = 0; i < last; i++) {
@ -842,6 +895,7 @@ void cReplayBuffer::SkipSeconds(int Seconds)
uchar FileNumber; uchar FileNumber;
int FileOffset; int FileOffset;
if (index->GetNextIFrame(Index, false, &FileNumber, &FileOffset) >= 0) if (index->GetNextIFrame(Index, false, &FileNumber, &FileOffset) >= 0)
if ((Index = index->GetNextIFrame(Index, false, &FileNumber, &FileOffset)) >= 0)
NextFile(FileNumber, FileOffset); NextFile(FileNumber, FileOffset);
} }
} }
@ -1014,7 +1068,7 @@ cDvbApi::cDvbApi(const char *FileName)
leaveok(stdscr, TRUE); leaveok(stdscr, TRUE);
window = NULL; window = NULL;
#endif #endif
lastProgress = -1; lastProgress = lastTotal = -1;
replayTitle = NULL; replayTitle = NULL;
} }
@ -1162,7 +1216,7 @@ void cDvbApi::Open(int w, int h)
SETCOLOR(clrMagenta, 0xB0, 0x00, 0xFC, 255); SETCOLOR(clrMagenta, 0xB0, 0x00, 0xFC, 255);
SETCOLOR(clrWhite, 0xFC, 0xFC, 0xFC, 255); SETCOLOR(clrWhite, 0xFC, 0xFC, 0xFC, 255);
lastProgress = -1; lastProgress = lastTotal = -1;
} }
void cDvbApi::Close(void) void cDvbApi::Close(void)
@ -1172,7 +1226,7 @@ void cDvbApi::Close(void)
#else #else
Cmd(OSD_Close); Cmd(OSD_Close);
#endif #endif
lastProgress = -1; lastProgress = lastTotal = -1;
} }
void cDvbApi::Clear(void) void cDvbApi::Clear(void)
@ -1227,8 +1281,9 @@ bool cDvbApi::ShowProgress(bool Initial)
if (Initial) { if (Initial) {
if (replayTitle) if (replayTitle)
Text(0, 0, replayTitle); Text(0, 0, replayTitle);
Text(-7, 2, cIndexFile::Str(Total));
} }
if (Total != lastTotal)
Text(-7, 2, cIndexFile::Str(Total));
#ifdef DEBUG_OSD #ifdef DEBUG_OSD
int p = cols * Current / Total; int p = cols * Current / Total;
Fill(0, 1, p, 1, clrGreen); Fill(0, 1, p, 1, clrGreen);
@ -1260,6 +1315,7 @@ bool cDvbApi::ShowProgress(bool Initial)
} }
#endif #endif
Text(0, 2, cIndexFile::Str(Current)); Text(0, 2, cIndexFile::Str(Current));
lastTotal = Total;
return true; return true;
} }
return false; return false;
@ -1441,7 +1497,7 @@ bool cDvbApi::StartReplay(const char *FileName, const char *Title)
StopReplay(); StopReplay();
if (videoDev >= 0) { if (videoDev >= 0) {
lastProgress = -1; lastProgress = lastTotal = -1;
delete replayTitle; delete replayTitle;
if (Title) { if (Title) {
if ((replayTitle = strdup(Title)) == NULL) if ((replayTitle = strdup(Title)) == NULL)
@ -1509,7 +1565,8 @@ bool cDvbApi::StartReplay(const char *FileName, const char *Title)
} }
if (FD_ISSET(fromMain, &setIn)) { if (FD_ISSET(fromMain, &setIn)) {
switch (readchar(fromMain)) { switch (readchar(fromMain)) {
case dvbStop: Buffer->Stop(); break; case dvbStop: SetReplayMode(VID_PLAY_CLEAR_BUFFER);
Buffer->Stop(); break;
case dvbPauseReplay: SetReplayMode(Paused ? VID_PLAY_NORMAL : VID_PLAY_PAUSE); case dvbPauseReplay: SetReplayMode(Paused ? VID_PLAY_NORMAL : VID_PLAY_PAUSE);
Paused = !Paused; Paused = !Paused;
FastForward = FastRewind = false; FastForward = FastRewind = false;
@ -1528,6 +1585,7 @@ bool cDvbApi::StartReplay(const char *FileName, const char *Title)
case dvbSkip: { case dvbSkip: {
int Seconds; int Seconds;
if (readint(fromMain, Seconds)) { if (readint(fromMain, Seconds)) {
SetReplayMode(VID_PLAY_CLEAR_BUFFER);
SetReplayMode(VID_PLAY_NORMAL); SetReplayMode(VID_PLAY_NORMAL);
FastForward = FastRewind = Paused = false; FastForward = FastRewind = Paused = false;
Buffer->SetMode(rmPlay); Buffer->SetMode(rmPlay);

View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and * See the main source file 'vdr.c' for copyright information and
* how to reach the author. * how to reach the author.
* *
* $Id: dvbapi.h 1.9 2000/05/01 12:46:25 kls Exp $ * $Id: dvbapi.h 1.10 2000/05/20 14:50:43 kls Exp $
*/ */
#ifndef __DVBAPI_H #ifndef __DVBAPI_H
@ -91,7 +91,7 @@ public:
// Progress Display facilities // Progress Display facilities
private: private:
int lastProgress; int lastProgress, lastTotal;
char *replayTitle; char *replayTitle;
public: public:
bool ShowProgress(bool Initial = false); bool ShowProgress(bool Initial = false);