summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKlaus Schmidinger <vdr@tvdr.de>2002-06-22 13:45:53 +0200
committerKlaus Schmidinger <vdr@tvdr.de>2002-06-22 13:45:53 +0200
commit359e90b8a7fee368e496b79ab253045b989fa6a5 (patch)
treee8f5dc7c57d99b8876adc33610fa221b3e4023e8
parent7ade39597ac83a03395e86a8276fbb6dec6a6a2f (diff)
downloadvdr-359e90b8a7fee368e496b79ab253045b989fa6a5.tar.gz
vdr-359e90b8a7fee368e496b79ab253045b989fa6a5.tar.bz2
Activated transfer mode
-rw-r--r--HISTORY1
-rw-r--r--Makefile4
-rw-r--r--device.c16
-rw-r--r--device.h8
-rw-r--r--dvbplayer.c4
-rw-r--r--eitscan.c4
-rw-r--r--menu.c4
-rw-r--r--transfer.c122
-rw-r--r--transfer.h35
9 files changed, 181 insertions, 17 deletions
diff --git a/HISTORY b/HISTORY
index 00a64394..3b881cb2 100644
--- a/HISTORY
+++ b/HISTORY
@@ -1352,3 +1352,4 @@ Video Disk Recorder Revision History
- Added Hungarian language texts (thanks to Istvan Koenigsberger and Guido Josten).
- Activated cutting.
+- Activated transfer mode.
diff --git a/Makefile b/Makefile
index f3b37504..7e922184 100644
--- a/Makefile
+++ b/Makefile
@@ -4,7 +4,7 @@
# See the main source file 'vdr.c' for copyright information and
# how to reach the author.
#
-# $Id: Makefile 1.41 2002/06/22 09:49:29 kls Exp $
+# $Id: Makefile 1.42 2002/06/22 10:21:56 kls Exp $
.DELETE_ON_ERROR:
@@ -24,7 +24,7 @@ DTVLIB = $(DTVDIR)/libdtv.a
OBJS = audio.o config.o cutter.o device.o dvbplayer.o dvbosd.o eit.o eitscan.o font.o i18n.o\
interface.o menu.o menuitems.o osdbase.o osd.o player.o plugin.o receiver.o\
recorder.o recording.o remote.o remux.o ringbuffer.o status.o svdrp.o thread.o\
- tools.o vdr.o videodir.o
+ tools.o transfer.o vdr.o videodir.o
OSDFONT = -adobe-helvetica-medium-r-normal--23-*-100-100-p-*-iso8859-1
FIXFONT = -adobe-courier-bold-r-normal--25-*-100-100-m-*-iso8859-1
diff --git a/device.c b/device.c
index fe756592..7bce6c4e 100644
--- a/device.c
+++ b/device.c
@@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
- * $Id: device.c 1.2 2002/06/16 13:23:31 kls Exp $
+ * $Id: device.c 1.3 2002/06/22 13:45:53 kls Exp $
*/
#include "device.h"
@@ -21,6 +21,7 @@ extern "C" {
#include "player.h"
#include "receiver.h"
#include "status.h"
+#include "transfer.h"
#define DEV_VIDEO "/dev/video"
#define DEV_OST_OSD "/dev/ost/osd"
@@ -105,6 +106,7 @@ cDevice::cDevice(int n)
currentChannel = 0;
frequency = 0;
+ transfer = NULL;
mute = false;
volume = Setup.CurrentVolume;
@@ -118,6 +120,7 @@ cDevice::cDevice(int n)
cDevice::~cDevice()
{
+ delete transfer;
delete dvrFileName;
delete siProcessor;
Detach(player);
@@ -456,7 +459,7 @@ bool cDevice::SetPid(int fd, dmxPesType_t PesType, int Pid, dmxOutput_t Output)
eSetChannelResult cDevice::SetChannel(int ChannelNumber, int Frequency, char Polarization, int Diseqc, int Srate, int Vpid, int Apid, int Tpid, int Ca, int Pnr)
{
- //XXX+StopTransfer();
+ DELETENULL(transfer);
//XXX+StopReplay();
cStatus::MsgChannelSwitch(this, 0);
@@ -621,8 +624,9 @@ eSetChannelResult cDevice::SetChannel(int ChannelNumber, int Frequency, char Pol
cDevice *CaDevice = GetDevice(Ca, 0);
if (CaDevice && !CaDevice->Receiving()) {
if ((Result = CaDevice->SetChannel(ChannelNumber, Frequency, Polarization, Diseqc, Srate, Vpid, Apid, Tpid, Ca, Pnr)) == scrOk) {
- //XXX+SetModeReplay();
- //XXX+transferringFromDevice = CaDevice->StartTransfer(fd_video);
+ transfer = new cTransfer(Vpid, Apid, 0, 0, 0);//XXX+
+ AttachPlayer(transfer);
+ CaDevice->AttachReceiver(transfer);
}
}
else
@@ -739,7 +743,7 @@ bool cDevice::Replaying(void)
return player != NULL;
}
-bool cDevice::Attach(cPlayer *Player)
+bool cDevice::AttachPlayer(cPlayer *Player)
{
if (Receiving()) {
esyslog("ERROR: attempt to attach a cPlayer while receiving on device %d - ignored", CardIndex() + 1);
@@ -958,7 +962,7 @@ void cDevice::Action(void)
dsyslog("receiver thread ended on device %d (pid=%d)", CardIndex() + 1, getpid());
}
-bool cDevice::Attach(cReceiver *Receiver)
+bool cDevice::AttachReceiver(cReceiver *Receiver)
{
//XXX+ check for same transponder???
if (!Receiver)
diff --git a/device.h b/device.h
index e598430a..8c68ee0a 100644
--- a/device.h
+++ b/device.h
@@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
- * $Id: device.h 1.1 2002/06/10 16:30:00 kls Exp $
+ * $Id: device.h 1.2 2002/06/22 13:34:55 kls Exp $
*/
#ifndef __DEVICE_H
@@ -33,6 +33,7 @@ enum eSetChannelResult { scrOk, scrNoTransfer, scrFailed };
class cPlayer;
class cReceiver;
+class cTransfer;
class cDevice : cThread {
friend class cOsd;//XXX
@@ -106,6 +107,7 @@ public:
private:
int currentChannel;
int frequency;
+ cTransfer *transfer;
public:
eSetChannelResult SetChannel(int ChannelNumber, int Frequency, char Polarization, int Diseqc, int Srate, int Vpid, int Apid, int Tpid, int Ca, int Pnr);
static int CurrentChannel(void) { return primaryDevice ? primaryDevice->currentChannel : 0; }
@@ -172,7 +174,7 @@ public:
// Returns true if we are currently replaying.
void StopReplay(void);
// Stops the current replay session (if any).
- bool Attach(cPlayer *Player);
+ bool AttachPlayer(cPlayer *Player);
void Detach(cPlayer *Player);
virtual int PlayVideo(const uchar *Data, int Length);
virtual int PlayAudio(const uchar *Data, int Length);
@@ -192,7 +194,7 @@ public:
// Returns the ca of the current receiving session.
bool Receiving(void);
// Returns true if we are currently receiving.
- bool Attach(cReceiver *Receiver);
+ bool AttachReceiver(cReceiver *Receiver);
void Detach(cReceiver *Receiver);
};
diff --git a/dvbplayer.c b/dvbplayer.c
index f18eb84e..3027e37d 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 1.2 2002/06/22 10:11:59 kls Exp $
+ * $Id: dvbplayer.c 1.3 2002/06/22 13:35:36 kls Exp $
*/
#include "dvbplayer.h"
@@ -644,7 +644,7 @@ bool cDvbPlayerControl::Start(const char *FileName)
{
delete player;
player = new cDvbPlayer(FileName);
- if (cDevice::PrimaryDevice()->Attach(player))
+ if (cDevice::PrimaryDevice()->AttachPlayer(player))
return true;
Stop();
return false;
diff --git a/eitscan.c b/eitscan.c
index 21fbe74e..a275abe0 100644
--- a/eitscan.c
+++ b/eitscan.c
@@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
- * $Id: eitscan.c 1.2 2002/06/10 16:30:00 kls Exp $
+ * $Id: eitscan.c 1.3 2002/06/22 13:02:40 kls Exp $
*/
#include "eitscan.h"
@@ -52,7 +52,7 @@ void cEITScanner::Process(void)
cDevice *Device = cDevice::GetDevice(i + 1, MAXPRIORITY + 1);
if (Device) {
if (Device != cDevice::PrimaryDevice() || (cDevice::NumDevices() == 1 && Setup.EPGScanTimeout && now - lastActivity > Setup.EPGScanTimeout * 3600)) {
- if (!(Device->Receiving() || Device->Replaying()/*XXX+ || Device->Transferring()XXX*/)) {
+ if (!(Device->Receiving() || Device->Replaying())) {
int oldCh = lastChannel;
int ch = oldCh + 1;
while (ch != oldCh) {
diff --git a/menu.c b/menu.c
index 29703da1..904a630a 100644
--- a/menu.c
+++ b/menu.c
@@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
- * $Id: menu.c 1.198 2002/06/22 09:55:58 kls Exp $
+ * $Id: menu.c 1.199 2002/06/22 13:36:10 kls Exp $
*/
#include "menu.h"
@@ -2442,7 +2442,7 @@ cRecordControl::cRecordControl(cDevice *Device, cTimer *Timer)
cRecordingUserCommand::InvokeCommand(RUC_BEFORERECORDING, fileName);
cChannel *ch = Channels.GetByNumber(timer->channel);
recorder = new cRecorder(fileName, ch->ca, timer->priority, ch->vpid, ch->apid1, ch->apid2, ch->dpid1, ch->dpid2);
- if (device->Attach(recorder)) {
+ if (device->AttachReceiver(recorder)) {
Recording.WriteSummary();
cStatus::MsgRecording(device, fileName);
Interface->DisplayRecording(device->CardIndex(), true);
diff --git a/transfer.c b/transfer.c
new file mode 100644
index 00000000..0e0a7083
--- /dev/null
+++ b/transfer.c
@@ -0,0 +1,122 @@
+/*
+ * transfer.c: Transfer mode
+ *
+ * See the main source file 'vdr.c' for copyright information and
+ * how to reach the author.
+ *
+ * $Id: transfer.c 1.1 2002/06/22 13:39:23 kls Exp $
+ */
+
+#include "transfer.h"
+
+//XXX+ also used in recorder.c - find a better place???
+// The size of the array used to buffer video data:
+// (must be larger than MINVIDEODATA - see remux.h)
+#define VIDEOBUFSIZE MEGABYTE(1)
+
+// --- cTransfer -------------------------------------------------------------
+
+cTransfer::cTransfer(int VPid, int APid1, int APid2, int DPid1, int DPid2)
+:cReceiver(0, 0, 5, VPid, APid1, APid2, DPid1, DPid2)
+{
+ ringBuffer = new cRingBufferLinear(VIDEOBUFSIZE, true);
+ remux = new cRemux(VPid, APid1, APid2, DPid1, DPid2);
+ gotBufferReserve = false;
+ active = false;
+}
+
+cTransfer::~cTransfer()
+{
+ cReceiver::Detach();
+ cPlayer::Detach();
+ delete remux;
+ delete ringBuffer;
+}
+
+void cTransfer::Activate(bool On)
+{
+ if (On) {
+ if (!active)
+ Start();
+ }
+ else if (active) {
+ active = false;
+ Cancel(3);
+ }
+}
+
+void cTransfer::Receive(uchar *Data, int Length)
+{
+ int p = ringBuffer->Put(Data, Length);
+ if (p != Length && active)
+ esyslog("ERROR: ring buffer overflow (%d bytes dropped)", Length - p);
+}
+
+void cTransfer::Action(void)
+{
+ dsyslog("transfer thread started (pid=%d)", getpid());
+
+ uchar b[MINVIDEODATA];
+ int r = 0;
+ active = true;
+ while (active) {
+
+ //XXX+ Maybe we need this to avoid "buffer empty" log messages from the driver.
+ //XXX+ But then again, it appears to play just fine without this...
+ /*
+ if (!gotBufferReserve) {
+ if (ringBuffer->Available() < 4 * MAXFRAMESIZE) {
+ usleep(100000); // allow the buffer to collect some reserve
+ continue;
+ }
+ else
+ gotBufferReserve = true;
+ }
+ */
+
+ // Get data from the buffer:
+
+ int g = ringBuffer->Get(b + r, sizeof(b) - r);
+ if (g > 0)
+ r += g;
+
+ // Play the data:
+
+ if (r > 0) {
+ int Count = r, Result;
+ const uchar *p = remux->Process(b, Count, Result);
+ if (p) {
+ //XXX+ StripAudio???
+ while (Result > 0 && active) {
+ int w = PlayVideo(p, Result);
+ if (w > 0) {
+ p += w;
+ Result -= w;
+ }
+ else if (w < 0 && FATALERRNO) {
+ LOG_ERROR;
+ break;
+ }
+ }
+ }
+ if (Count > 0) {
+ r -= Count;
+ if (r > 0)
+ memmove(b, b + Count, r);
+ }
+ }
+ }
+
+ dsyslog("transfer thread ended (pid=%d)", getpid());
+}
+
+void cTransfer::SetAudioPid(int APid)
+{
+ /*XXX+
+ Clear();
+ //XXX we may need to have access to the audio device, too, in order to clear it
+ CHECK(ioctl(toDevice, VIDEO_CLEAR_BUFFER));
+ gotBufferReserve = false;
+ remux.SetAudioPid(APid);
+ XXX*/
+}
diff --git a/transfer.h b/transfer.h
new file mode 100644
index 00000000..060401f7
--- /dev/null
+++ b/transfer.h
@@ -0,0 +1,35 @@
+/*
+ * transfer.h: Transfer mode
+ *
+ * See the main source file 'vdr.c' for copyright information and
+ * how to reach the author.
+ *
+ * $Id: transfer.h 1.1 2002/06/22 13:38:23 kls Exp $
+ */
+
+#ifndef __TRANSFER_H
+#define __TRANSFER_H
+
+#include "player.h"
+#include "receiver.h"
+#include "remux.h"
+#include "ringbuffer.h"
+#include "thread.h"
+
+class cTransfer : public cReceiver, public cPlayer, public cThread {
+private:
+ cRingBufferLinear *ringBuffer;
+ cRemux *remux;
+ bool gotBufferReserve;
+ bool active;
+protected:
+ virtual void Activate(bool On);
+ virtual void Receive(uchar *Data, int Length);
+ virtual void Action(void);
+public:
+ cTransfer(int VPid, int APid1, int APid2, int DPid1, int DPid2);
+ virtual ~cTransfer();
+ void SetAudioPid(int APid);
+ };
+
+#endif //__TRANSFER_H