mirror of
https://github.com/VDR4Arch/vdr.git
synced 2023-10-10 13:36:52 +02:00
Simultaneous record/replay with two DVB cards
This commit is contained in:
parent
5d34487621
commit
86f14230c2
86
dvbapi.c
86
dvbapi.c
@ -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);
|
||||||
|
4
dvbapi.h
4
dvbapi.h
@ -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);
|
||||||
|
Loading…
Reference in New Issue
Block a user