2 Edited for VOMP by Chris Tallon
3 Edits Copyright 2004-2005 Chris Tallon
5 This class will be replaced soon.
11 * (C) 2003 Dominic Morris
16 * Transceiver stuff - blatantly stolen from streamdev then changed
24 #include "transceiver.h"
29 #include <vdr/ringbuffer.h>
31 #include <sys/types.h>
35 #define VIDEOBUFSIZE MEGABYTE(1)
37 /* Disable logging if BUFCOUNT buffer overflows occur within BUFOVERTIME
38 milliseconds. Enable logging again if there is no error within BUFOVERTIME
40 #define BUFOVERTIME 5000
41 #define BUFOVERCOUNT 100
43 #if VDRVERSNUM < 10300
44 cMediamvpTransceiver::cMediamvpTransceiver(const cChannel *Channel, int Priority, int Socket, cDevice *Device) :
45 cReceiver(Channel->Ca(), Priority, 7, Channel->Vpid(), Channel->Ppid(),
46 Channel->Apid1(), Channel->Apid2(), Channel->Dpid1(), Channel->Dpid2(),
49 cMediamvpTransceiver::cMediamvpTransceiver(const cChannel *Channel, int Priority, int Socket, cDevice *Device) :
50 cReceiver(Channel->Ca(), Priority, Channel->Vpid(),
51 Channel->Apids(), Channel->Dpids(), Channel->Spids()) {
59 log = Log::getInstance();
61 m_RingBuffer = new cRingBufferLinear(VIDEOBUFSIZE, TS_SIZE * 2, true);
62 // m_RingBuffer = new cRingBufferLinear(VIDEOBUFSIZE, TS_SIZE * 20, true);
64 /* Select the correct Muxing depending on whether it's video or not */
65 #if VDRVERSNUM < 10300
66 if ( Channel->Vpid() == 0 || Channel->Vpid() == 1 || Channel->Vpid() == 0x1FFF ) {
67 m_Remux = new cTS2ESRemux(Channel->Apid1());
69 m_Remux = new cTS2PSRemux(Channel->Vpid(), Channel->Apid1(), 0, 0, 0, 0);
72 if ( Channel->Vpid() == 0 || Channel->Vpid() == 1 || Channel->Vpid() == 0x1FFF ) {
73 m_Remux = new cTS2ESRemux(Channel->Apid(0));
75 m_Remux = new cTS2PSRemux(Channel->Vpid(), Channel->Apid(0), 0, 0, 0, 0);
78 log->log("Transciever", Log::DEBUG, "Created transceiver at %p, remux @%p ringbuffer %p",this,m_Remux,m_RingBuffer);
80 /* Suggested by Peter Wagner to assist single DVB card systems */
82 m_Device->SwitchChannel(Channel, true);
84 m_Device->SwitchChannel(Channel, false);
91 pthread_mutex_init(&ringLock, NULL);
95 cMediamvpTransceiver::~cMediamvpTransceiver(void)
97 log->log("Transciever", Log::DEBUG, "Deleting transceiver at %p, remux @%p ringbuffer %p",this,m_Remux,m_RingBuffer);
108 void cMediamvpTransceiver::Activate(bool On)
116 void cMediamvpTransceiver::Stop(void)
125 void cMediamvpTransceiver::Receive(uchar *Data, int Length)
127 static time_t firsterr = 0;
128 static int errcnt = 0;
129 static bool showerr = true;
132 int p = m_RingBuffer->Put(Data, Length);
135 #if VDRVERSNUM < 10300
138 firsterr = time_ms();
139 else if (firsterr + BUFOVERTIME > time_ms() && errcnt > BUFOVERCOUNT) {
140 esyslog("ERROR: too many buffer overflows, logging stopped");
142 firsterr = time_ms();
144 } else if (firsterr + BUFOVERTIME < time_ms()) {
151 esyslog("ERROR: ring buffer overflow (%d bytes dropped)", Length - p);
153 firsterr = time_ms();
160 else if (lastTime.Elapsed() > BUFOVERTIME && errcnt > BUFOVERCOUNT) {
161 esyslog("ERROR: too many buffer overflows, logging stopped");
164 } else if (lastTime.Elapsed() < BUFOVERTIME) {
171 esyslog("ERROR: ring buffer overflow (%d bytes dropped)", Length - p);
179 void cMediamvpTransceiver::Action(void)
184 log->log("Transciever", Log::DEBUG, "Mediamvp: Transceiver thread started (pid=%d)", getpid());
191 const uchar *block = m_RingBuffer->Get(recvd);
193 if (block && recvd > 0) {
194 const uchar *sendBlock;
198 sendBlock = m_Remux->Process(block, taken, bytes);
200 m_RingBuffer->Del(taken);
206 // write(m_Socket,sendBlock,bytes);
207 // printf("Written %i bytes\n", bytes);
210 pthread_mutex_lock(&ringLock);
211 rb.put((unsigned char*)sendBlock, bytes);
212 pthread_mutex_unlock(&ringLock);
213 //printf("Put %i into buffer\n", bytes);
221 log->log("Transciever", Log::DEBUG, "Mediamvp: Transceiver thread ended");
224 unsigned long cMediamvpTransceiver::getBlock(unsigned char* buffer, unsigned long amount)
226 pthread_mutex_lock(&ringLock);
230 while ((unsigned long)rb.getContent() < amount)
232 pthread_mutex_unlock(&ringLock);
233 if (++numTries == 10) // 5s
235 log->log("Transciever", Log::DEBUG, "getBlock timeout");
239 pthread_mutex_lock(&ringLock);
242 unsigned long amountReceived = rb.get(buffer, amount);
243 pthread_mutex_unlock(&ringLock);
244 return amountReceived;