mirror of
https://github.com/vdr-projects/vdr.git
synced 2025-03-01 10:50:46 +00:00
Activated transfer mode
This commit is contained in:
122
transfer.c
Normal file
122
transfer.c
Normal file
@@ -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*/
|
||||
}
|
||||
Reference in New Issue
Block a user