mirror of
https://github.com/VDR4Arch/vdr.git
synced 2023-10-10 13:36:52 +02:00
Implemented 'Transfer Mode'
This commit is contained in:
parent
061f344ffa
commit
fd464518b6
6
HISTORY
6
HISTORY
@ -266,7 +266,7 @@ Video Disk Recorder Revision History
|
|||||||
are programmed via the "Schedules" menu) are now replaced by suitable
|
are programmed via the "Schedules" menu) are now replaced by suitable
|
||||||
substitutes.
|
substitutes.
|
||||||
|
|
||||||
2000-11-18: Version 0.68
|
2000-11-19: Version 0.68
|
||||||
|
|
||||||
- Date and time in the title of an event info page are now always right adjusted.
|
- Date and time in the title of an event info page are now always right adjusted.
|
||||||
- The 'current channel' is now handled device specific (in case there is more
|
- The 'current channel' is now handled device specific (in case there is more
|
||||||
@ -307,3 +307,7 @@ Video Disk Recorder Revision History
|
|||||||
that don't send the EIT information correctly (like, e.g., 'VOX').
|
that don't send the EIT information correctly (like, e.g., 'VOX').
|
||||||
- Implemented a 10 seconds latency when removing files.
|
- Implemented a 10 seconds latency when removing files.
|
||||||
- Fixed unwanted reaction on the "Green" and "Yellow" button in the "Event" display.
|
- Fixed unwanted reaction on the "Green" and "Yellow" button in the "Event" display.
|
||||||
|
- Implemented 'Transfer Mode' to display video data from the DVB card that actually
|
||||||
|
can receive a certain channel on the primary interface. This is currently in
|
||||||
|
an early state and may still cause some problems, but it appears to work nice
|
||||||
|
already.
|
||||||
|
107
dvbapi.c
107
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.39 2000/11/18 15:30:57 kls Exp $
|
* $Id: dvbapi.c 1.40 2000/11/19 16:46:37 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "dvbapi.h"
|
#include "dvbapi.h"
|
||||||
@ -372,7 +372,9 @@ private:
|
|||||||
int *inFile, *outFile;
|
int *inFile, *outFile;
|
||||||
protected:
|
protected:
|
||||||
int Free(void) { return ((tail >= head) ? size + head - tail : head - tail) - 1; }
|
int Free(void) { return ((tail >= head) ? size + head - tail : head - tail) - 1; }
|
||||||
|
public:
|
||||||
int Available(void) { return (tail >= head) ? tail - head : size - head + tail; }
|
int Available(void) { return (tail >= head) ? tail - head : size - head + tail; }
|
||||||
|
protected:
|
||||||
int Readable(void) { return (tail >= head) ? size - tail - (head ? 0 : 1) : head - tail - 1; } // keep a 1 byte gap!
|
int Readable(void) { return (tail >= head) ? size - tail - (head ? 0 : 1) : head - tail - 1; } // keep a 1 byte gap!
|
||||||
int Writeable(void) { return (tail >= head) ? tail - head : size - head; }
|
int Writeable(void) { return (tail >= head) ? tail - head : size - head; }
|
||||||
int Byte(int Offset);
|
int Byte(int Offset);
|
||||||
@ -1079,6 +1081,63 @@ int cReplayBuffer::Write(int Max)
|
|||||||
return Written;
|
return Written;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// --- cTransferBuffer -------------------------------------------------------
|
||||||
|
|
||||||
|
class cTransferBuffer : public cThread {
|
||||||
|
private:
|
||||||
|
bool active;
|
||||||
|
int fromDevice, toDevice;
|
||||||
|
protected:
|
||||||
|
virtual void Action(void);
|
||||||
|
public:
|
||||||
|
cTransferBuffer(int FromDevice, int ToDevice);
|
||||||
|
virtual ~cTransferBuffer();
|
||||||
|
};
|
||||||
|
|
||||||
|
cTransferBuffer::cTransferBuffer(int FromDevice, int ToDevice)
|
||||||
|
{
|
||||||
|
fromDevice = FromDevice;
|
||||||
|
toDevice = ToDevice;
|
||||||
|
active = true;
|
||||||
|
Start();
|
||||||
|
}
|
||||||
|
|
||||||
|
cTransferBuffer::~cTransferBuffer()
|
||||||
|
{
|
||||||
|
{
|
||||||
|
LOCK_THREAD;
|
||||||
|
active = false;
|
||||||
|
}
|
||||||
|
for (time_t t0 = time(NULL); time(NULL) - t0 < 3; ) {
|
||||||
|
LOCK_THREAD;
|
||||||
|
if (active)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void cTransferBuffer::Action(void)
|
||||||
|
{
|
||||||
|
dsyslog(LOG_INFO, "data transfer thread started (pid=%d)", getpid());
|
||||||
|
//XXX hack to make the video device go into 'replaying' mode:
|
||||||
|
char *dummy = "AV"; // must be "AV" to make the driver go into AV_PES mode!
|
||||||
|
write(toDevice, dummy, strlen(dummy));
|
||||||
|
{
|
||||||
|
cRingBuffer Buffer(&fromDevice, &toDevice, VIDEOBUFSIZE, 0, 0);
|
||||||
|
while (active && Buffer.Available() < 100000) { // need to give the read buffer a head start
|
||||||
|
Buffer.Read(); // initializes fromDevice for reading
|
||||||
|
usleep(1); // this keeps the CPU load low
|
||||||
|
}
|
||||||
|
for (; active;) {
|
||||||
|
if (Buffer.Read() < 0 || Buffer.Write() < 0)
|
||||||
|
break;
|
||||||
|
usleep(1); // this keeps the CPU load low
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dsyslog(LOG_INFO, "data transfer thread stopped (pid=%d)", getpid());
|
||||||
|
LOCK_THREAD;
|
||||||
|
active = true;
|
||||||
|
}
|
||||||
|
|
||||||
// --- cDvbApi ---------------------------------------------------------------
|
// --- cDvbApi ---------------------------------------------------------------
|
||||||
|
|
||||||
int cDvbApi::NumDvbApis = 0;
|
int cDvbApi::NumDvbApis = 0;
|
||||||
@ -1093,6 +1152,8 @@ cDvbApi::cDvbApi(const char *VideoFileName, const char *VbiFileName)
|
|||||||
fromReplay = toReplay = -1;
|
fromReplay = toReplay = -1;
|
||||||
ca = 0;
|
ca = 0;
|
||||||
priority = -1;
|
priority = -1;
|
||||||
|
transferBuffer = NULL;
|
||||||
|
transferringFromDvbApi = NULL;
|
||||||
videoDev = open(VideoFileName, O_RDWR | O_NONBLOCK);
|
videoDev = open(VideoFileName, O_RDWR | O_NONBLOCK);
|
||||||
if (videoDev >= 0) {
|
if (videoDev >= 0) {
|
||||||
siProcessor = new cSIProcessor(VbiFileName);
|
siProcessor = new cSIProcessor(VbiFileName);
|
||||||
@ -1142,6 +1203,7 @@ cDvbApi::~cDvbApi()
|
|||||||
Close();
|
Close();
|
||||||
Stop();
|
Stop();
|
||||||
StopRecord();
|
StopRecord();
|
||||||
|
StopTransfer();
|
||||||
OvlO(false); //Overlay off!
|
OvlO(false); //Overlay off!
|
||||||
//XXX the following call sometimes causes a segfault - driver problem?
|
//XXX the following call sometimes causes a segfault - driver problem?
|
||||||
close(videoDev);
|
close(videoDev);
|
||||||
@ -1717,6 +1779,12 @@ bool cDvbApi::ShowProgress(bool Initial)
|
|||||||
bool cDvbApi::SetChannel(int ChannelNumber, int FrequencyMHz, char Polarization, int Diseqc, int Srate, int Vpid, int Apid, int Ca, int Pnr)
|
bool cDvbApi::SetChannel(int ChannelNumber, int FrequencyMHz, char Polarization, int Diseqc, int Srate, int Vpid, int Apid, int Ca, int Pnr)
|
||||||
{
|
{
|
||||||
if (videoDev >= 0) {
|
if (videoDev >= 0) {
|
||||||
|
StopTransfer();
|
||||||
|
if (transferringFromDvbApi) {
|
||||||
|
transferringFromDvbApi->StopTransfer();
|
||||||
|
transferringFromDvbApi = NULL;
|
||||||
|
}
|
||||||
|
SetReplayMode(VID_PLAY_RESET);
|
||||||
struct frontend front;
|
struct frontend front;
|
||||||
ioctl(videoDev, VIDIOCGFRONTEND, &front);
|
ioctl(videoDev, VIDIOCGFRONTEND, &front);
|
||||||
unsigned int freq = FrequencyMHz;
|
unsigned int freq = FrequencyMHz;
|
||||||
@ -1740,6 +1808,17 @@ bool cDvbApi::SetChannel(int ChannelNumber, int FrequencyMHz, char Polarization,
|
|||||||
if (this == PrimaryDvbApi && siProcessor)
|
if (this == PrimaryDvbApi && siProcessor)
|
||||||
siProcessor->SetCurrentServiceID(Pnr);
|
siProcessor->SetCurrentServiceID(Pnr);
|
||||||
currentChannel = ChannelNumber;
|
currentChannel = ChannelNumber;
|
||||||
|
// If this DVB card can't receive this channel, let's see if we can
|
||||||
|
// use the card that actually can receive it and transfer data from there:
|
||||||
|
if (Ca && Ca != Index() + 1) {
|
||||||
|
cDvbApi *CaDvbApi = GetDvbApi(Ca, 0);
|
||||||
|
if (CaDvbApi) {
|
||||||
|
if (!CaDvbApi->Recording()) {
|
||||||
|
if (CaDvbApi->SetChannel(ChannelNumber, FrequencyMHz, Polarization, Diseqc, Srate, Vpid, Apid, Ca, Pnr))
|
||||||
|
transferringFromDvbApi = CaDvbApi->StartTransfer(videoDev);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
esyslog(LOG_ERR, "ERROR: channel not sync'ed (front.sync=%X)!", front.sync);
|
esyslog(LOG_ERR, "ERROR: channel not sync'ed (front.sync=%X)!", front.sync);
|
||||||
@ -1747,6 +1826,27 @@ bool cDvbApi::SetChannel(int ChannelNumber, int FrequencyMHz, char Polarization,
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool cDvbApi::Transferring(void)
|
||||||
|
{
|
||||||
|
return transferBuffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
cDvbApi *cDvbApi::StartTransfer(int TransferToVideoDev)
|
||||||
|
{
|
||||||
|
StopTransfer();
|
||||||
|
transferBuffer = new cTransferBuffer(videoDev, TransferToVideoDev);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
void cDvbApi::StopTransfer(void)
|
||||||
|
{
|
||||||
|
if (transferBuffer) {
|
||||||
|
delete transferBuffer;
|
||||||
|
transferBuffer = NULL;
|
||||||
|
SetReplayMode(VID_PLAY_RESET);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool cDvbApi::Recording(void)
|
bool cDvbApi::Recording(void)
|
||||||
{
|
{
|
||||||
if (pidRecord && !CheckProcess(pidRecord))
|
if (pidRecord && !CheckProcess(pidRecord))
|
||||||
@ -1769,6 +1869,8 @@ bool cDvbApi::StartRecord(const char *FileName, int Ca, int Priority)
|
|||||||
}
|
}
|
||||||
if (videoDev >= 0) {
|
if (videoDev >= 0) {
|
||||||
|
|
||||||
|
StopTransfer();
|
||||||
|
|
||||||
Stop(); // TODO: remove this if the driver is able to do record and replay at the same time
|
Stop(); // TODO: remove this if the driver is able to do record and replay at the same time
|
||||||
|
|
||||||
// Check FileName:
|
// Check FileName:
|
||||||
@ -1896,6 +1998,7 @@ bool cDvbApi::StartReplay(const char *FileName, const char *Title)
|
|||||||
esyslog(LOG_ERR, "ERROR: StartReplay() called while recording - ignored!");
|
esyslog(LOG_ERR, "ERROR: StartReplay() called while recording - ignored!");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
StopTransfer();
|
||||||
Stop();
|
Stop();
|
||||||
if (videoDev >= 0) {
|
if (videoDev >= 0) {
|
||||||
|
|
||||||
@ -2144,7 +2247,7 @@ void cEITScanner::Process(void)
|
|||||||
cDvbApi *DvbApi = cDvbApi::GetDvbApi(i, 0);
|
cDvbApi *DvbApi = cDvbApi::GetDvbApi(i, 0);
|
||||||
if (DvbApi) {
|
if (DvbApi) {
|
||||||
if (DvbApi != cDvbApi::PrimaryDvbApi || (cDvbApi::NumDvbApis == 1 && Setup.EPGScanTimeout && now - lastActivity > Setup.EPGScanTimeout * 3600)) {
|
if (DvbApi != cDvbApi::PrimaryDvbApi || (cDvbApi::NumDvbApis == 1 && Setup.EPGScanTimeout && now - lastActivity > Setup.EPGScanTimeout * 3600)) {
|
||||||
if (!(DvbApi->Recording() || DvbApi->Replaying())) {
|
if (!(DvbApi->Recording() || DvbApi->Replaying() || DvbApi->Transferring())) {
|
||||||
int oldCh = lastChannel;
|
int oldCh = lastChannel;
|
||||||
int ch = oldCh + 1;
|
int ch = oldCh + 1;
|
||||||
while (ch != oldCh) {
|
while (ch != oldCh) {
|
||||||
|
18
dvbapi.h
18
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.25 2000/11/18 15:30:09 kls Exp $
|
* $Id: dvbapi.h 1.26 2000/11/19 14:09:41 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __DVBAPI_H
|
#ifndef __DVBAPI_H
|
||||||
@ -42,6 +42,8 @@ public:
|
|||||||
bool Save(int Index);
|
bool Save(int Index);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class cTransferBuffer;
|
||||||
|
|
||||||
class cDvbApi {
|
class cDvbApi {
|
||||||
private:
|
private:
|
||||||
int videoDev;
|
int videoDev;
|
||||||
@ -152,6 +154,20 @@ public:
|
|||||||
static int CurrentChannel(void) { return PrimaryDvbApi ? PrimaryDvbApi->currentChannel : 0; }
|
static int CurrentChannel(void) { return PrimaryDvbApi ? PrimaryDvbApi->currentChannel : 0; }
|
||||||
int Channel(void) { return currentChannel; }
|
int Channel(void) { return currentChannel; }
|
||||||
|
|
||||||
|
// Transfer facilities
|
||||||
|
|
||||||
|
private:
|
||||||
|
cTransferBuffer *transferBuffer;
|
||||||
|
cDvbApi *transferringFromDvbApi;
|
||||||
|
public:
|
||||||
|
bool Transferring(void);
|
||||||
|
// Returns true if we are currently transferring video data.
|
||||||
|
private:
|
||||||
|
cDvbApi *StartTransfer(int TransferToVideoDev);
|
||||||
|
// Starts transferring video data from this DVB device to TransferToVideoDev.
|
||||||
|
void StopTransfer(void);
|
||||||
|
// Stops transferring video data (in case a transfer is currently active).
|
||||||
|
|
||||||
// Record/Replay facilities
|
// Record/Replay facilities
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
Loading…
Reference in New Issue
Block a user