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
|
||||
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.
|
||||
- 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').
|
||||
- Implemented a 10 seconds latency when removing files.
|
||||
- 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
|
||||
* 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"
|
||||
@ -372,7 +372,9 @@ private:
|
||||
int *inFile, *outFile;
|
||||
protected:
|
||||
int Free(void) { return ((tail >= head) ? size + head - tail : head - tail) - 1; }
|
||||
public:
|
||||
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 Writeable(void) { return (tail >= head) ? tail - head : size - head; }
|
||||
int Byte(int Offset);
|
||||
@ -1079,6 +1081,63 @@ int cReplayBuffer::Write(int Max)
|
||||
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 ---------------------------------------------------------------
|
||||
|
||||
int cDvbApi::NumDvbApis = 0;
|
||||
@ -1093,6 +1152,8 @@ cDvbApi::cDvbApi(const char *VideoFileName, const char *VbiFileName)
|
||||
fromReplay = toReplay = -1;
|
||||
ca = 0;
|
||||
priority = -1;
|
||||
transferBuffer = NULL;
|
||||
transferringFromDvbApi = NULL;
|
||||
videoDev = open(VideoFileName, O_RDWR | O_NONBLOCK);
|
||||
if (videoDev >= 0) {
|
||||
siProcessor = new cSIProcessor(VbiFileName);
|
||||
@ -1142,6 +1203,7 @@ cDvbApi::~cDvbApi()
|
||||
Close();
|
||||
Stop();
|
||||
StopRecord();
|
||||
StopTransfer();
|
||||
OvlO(false); //Overlay off!
|
||||
//XXX the following call sometimes causes a segfault - driver problem?
|
||||
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)
|
||||
{
|
||||
if (videoDev >= 0) {
|
||||
StopTransfer();
|
||||
if (transferringFromDvbApi) {
|
||||
transferringFromDvbApi->StopTransfer();
|
||||
transferringFromDvbApi = NULL;
|
||||
}
|
||||
SetReplayMode(VID_PLAY_RESET);
|
||||
struct frontend front;
|
||||
ioctl(videoDev, VIDIOCGFRONTEND, &front);
|
||||
unsigned int freq = FrequencyMHz;
|
||||
@ -1740,6 +1808,17 @@ bool cDvbApi::SetChannel(int ChannelNumber, int FrequencyMHz, char Polarization,
|
||||
if (this == PrimaryDvbApi && siProcessor)
|
||||
siProcessor->SetCurrentServiceID(Pnr);
|
||||
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;
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
if (pidRecord && !CheckProcess(pidRecord))
|
||||
@ -1769,6 +1869,8 @@ bool cDvbApi::StartRecord(const char *FileName, int Ca, int Priority)
|
||||
}
|
||||
if (videoDev >= 0) {
|
||||
|
||||
StopTransfer();
|
||||
|
||||
Stop(); // TODO: remove this if the driver is able to do record and replay at the same time
|
||||
|
||||
// Check FileName:
|
||||
@ -1896,6 +1998,7 @@ bool cDvbApi::StartReplay(const char *FileName, const char *Title)
|
||||
esyslog(LOG_ERR, "ERROR: StartReplay() called while recording - ignored!");
|
||||
return false;
|
||||
}
|
||||
StopTransfer();
|
||||
Stop();
|
||||
if (videoDev >= 0) {
|
||||
|
||||
@ -2144,7 +2247,7 @@ void cEITScanner::Process(void)
|
||||
cDvbApi *DvbApi = cDvbApi::GetDvbApi(i, 0);
|
||||
if (DvbApi) {
|
||||
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 ch = oldCh + 1;
|
||||
while (ch != oldCh) {
|
||||
|
18
dvbapi.h
18
dvbapi.h
@ -4,7 +4,7 @@
|
||||
* See the main source file 'vdr.c' for copyright information and
|
||||
* 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
|
||||
@ -42,6 +42,8 @@ public:
|
||||
bool Save(int Index);
|
||||
};
|
||||
|
||||
class cTransferBuffer;
|
||||
|
||||
class cDvbApi {
|
||||
private:
|
||||
int videoDev;
|
||||
@ -152,6 +154,20 @@ public:
|
||||
static int CurrentChannel(void) { return PrimaryDvbApi ? PrimaryDvbApi->currentChannel : 0; }
|
||||
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
|
||||
|
||||
private:
|
||||
|
Loading…
Reference in New Issue
Block a user