2 Edited for VOMP by Chris Tallon
3 Edits Copyright 2004-2005 Chris Tallon
9 * (C) 2003 Dominic Morris
14 * Transceiver stuff - blatantly stolen from streamdev then changed
22 #include "transceiver.h"
27 #include <vdr/ringbuffer.h>
29 #include <sys/types.h>
33 #define VIDEOBUFSIZE MEGABYTE(1)
35 /* Disable logging if BUFCOUNT buffer overflows occur within BUFOVERTIME
36 milliseconds. Enable logging again if there is no error within BUFOVERTIME
38 #define BUFOVERTIME 5000
39 #define BUFOVERCOUNT 100
41 #if VDRVERSNUM < 10300
42 cMediamvpTransceiver::cMediamvpTransceiver(const cChannel *Channel, int Priority, int Socket, cDevice *Device) :
43 cReceiver(Channel->Ca(), Priority, 7, Channel->Vpid(), Channel->Ppid(),
44 Channel->Apid1(), Channel->Apid2(), Channel->Dpid1(), Channel->Dpid2(),
47 cMediamvpTransceiver::cMediamvpTransceiver(const cChannel *Channel, int Priority, int Socket, cDevice *Device) :
48 cReceiver(Channel->Ca(), Priority, Channel->Vpid(),
49 Channel->Apids(), Channel->Dpids(), Channel->Spids()) {
56 m_RingBuffer = new cRingBufferLinear(VIDEOBUFSIZE, TS_SIZE * 2, true);
57 // m_RingBuffer = new cRingBufferLinear(VIDEOBUFSIZE, TS_SIZE * 20, true);
59 /* Select the correct Muxing depending on whether it's video or not */
60 #if VDRVERSNUM < 10300
61 if ( Channel->Vpid() == 0 || Channel->Vpid() == 1 || Channel->Vpid() == 0x1FFF ) {
62 m_Remux = new cTS2ESRemux(Channel->Apid1());
64 m_Remux = new cTS2PSRemux(Channel->Vpid(), Channel->Apid1(), 0, 0, 0, 0);
67 if ( Channel->Vpid() == 0 || Channel->Vpid() == 1 || Channel->Vpid() == 0x1FFF ) {
68 m_Remux = new cTS2ESRemux(Channel->Apid(0));
70 m_Remux = new cTS2PSRemux(Channel->Vpid(), Channel->Apid(0), 0, 0, 0, 0);
73 printf("Created transceiver at %p, remux @%p ringbuffer %p\n",this,m_Remux,m_RingBuffer);
75 /* Suggested by Peter Wagner to assist single DVB card systems */
77 m_Device->SwitchChannel(Channel, true);
79 m_Device->SwitchChannel(Channel, false);
86 pthread_mutex_init(&ringLock, NULL);
90 cMediamvpTransceiver::~cMediamvpTransceiver(void)
92 printf("Deleting transceiver at %p, remux @%p ringbuffer %p\n",this,m_Remux,m_RingBuffer);
103 void cMediamvpTransceiver::Activate(bool On)
111 void cMediamvpTransceiver::Stop(void)
120 void cMediamvpTransceiver::Receive(uchar *Data, int Length)
122 static time_t firsterr = 0;
123 static int errcnt = 0;
124 static bool showerr = true;
127 int p = m_RingBuffer->Put(Data, Length);
130 #if VDRVERSNUM < 10300
133 firsterr = time_ms();
134 else if (firsterr + BUFOVERTIME > time_ms() && errcnt > BUFOVERCOUNT) {
135 esyslog("ERROR: too many buffer overflows, logging stopped");
137 firsterr = time_ms();
139 } else if (firsterr + BUFOVERTIME < time_ms()) {
146 esyslog("ERROR: ring buffer overflow (%d bytes dropped)", Length - p);
148 firsterr = time_ms();
155 else if (lastTime.Elapsed() > BUFOVERTIME && errcnt > BUFOVERCOUNT) {
156 esyslog("ERROR: too many buffer overflows, logging stopped");
159 } else if (lastTime.Elapsed() < BUFOVERTIME) {
166 esyslog("ERROR: ring buffer overflow (%d bytes dropped)", Length - p);
174 void cMediamvpTransceiver::Action(void)
179 printf("Mediamvp: Transceiver thread started (pid=%d)", getpid());
186 const uchar *block = m_RingBuffer->Get(recvd);
188 if (block && recvd > 0) {
189 const uchar *sendBlock;
193 sendBlock = m_Remux->Process(block, taken, bytes);
195 m_RingBuffer->Del(taken);
201 // write(m_Socket,sendBlock,bytes);
202 // printf("Written %i bytes\n", bytes);
205 pthread_mutex_lock(&ringLock);
206 rb.put((unsigned char*)sendBlock, bytes);
207 pthread_mutex_unlock(&ringLock);
208 //printf("Put %i into buffer\n", bytes);
216 printf("Mediamvp: Transceiver thread ended");
219 unsigned long cMediamvpTransceiver::getBlock(unsigned char* buffer, unsigned long amount)
221 pthread_mutex_lock(&ringLock);
223 while ((unsigned long)rb.getContent() < amount)
225 pthread_mutex_unlock(&ringLock);
227 pthread_mutex_lock(&ringLock);
230 unsigned long amountReceived = rb.get(buffer, amount);
231 pthread_mutex_unlock(&ringLock);
232 return amountReceived;