]> git.vomp.tv Git - vompserver.git/blob - mvpreceiver.c
Fixes for compilation against VDR 1.7.27. It compiles!
[vompserver.git] / mvpreceiver.c
1 #include "mvpreceiver.h"
2
3 int MVPReceiver::numMVPReceivers = 0;
4
5 MVPReceiver* MVPReceiver::create(cChannel* channel, int priority)
6 {
7 #if VDRVERSNUM < 10500
8   bool NeedsDetachReceivers;
9   cDevice* device = cDevice::GetDevice(channel, priority, &NeedsDetachReceivers);
10 #else
11   cDevice* device = cDevice::GetDevice(channel, priority, true); // last param is live-view
12 #endif
13
14   if (!device)
15   {
16     Log::getInstance()->log("MVPReceiver", Log::INFO, "No device found to receive this channel at this priority");
17     return NULL;
18   }
19
20 #if VDRVERSNUM < 10500
21   if (NeedsDetachReceivers)
22   {
23     Log::getInstance()->log("MVPReceiver", Log::WARN, "Needs detach receivers");
24
25     // Need to detach other receivers or VDR will shut down??
26   }
27 #endif
28
29   MVPReceiver* m = new MVPReceiver(channel, device);
30
31   numMVPReceivers++;
32   Log::getInstance()->log("MVPReceiver", Log::DEBUG, "num mvp receivers now up to %i", numMVPReceivers);
33   
34   return m;
35 }
36
37 MVPReceiver::MVPReceiver(cChannel* channel, cDevice* device)
38 #if VDRVERSNUM < 10300
39 : cReceiver(channel->Ca(), 0, 7, channel->Vpid(), channel->Ppid(), channel->Apid1(), channel->Apid2(), channel->Dpid1(), channel->Dpid2(), channel->Tpid())
40 #elif VDRVERSNUM < 10500
41 : cReceiver(channel->Ca(), 0, channel->Vpid(), channel->Apids(), channel->Dpids(), mergeSpidsTpid(channel->Spids(),channel->Tpid()))
42 #elif VDRVERSNUM < 10712
43 : cReceiver(channel->GetChannelID(), 0, channel->Vpid(), channel->Apids(), channel->Dpids(), mergeSpidsTpid(channel->Spids(),channel->Tpid()))
44 #else
45 : cReceiver(channel, 0)
46 #endif
47 {
48   logger = Log::getInstance();
49   vdrActivated = false;
50   inittedOK = 0;
51   streamID = 0;
52   tcp = NULL;
53
54 //  logger->log("MVPReceiver", Log::DEBUG, "Channel has VPID %i APID %i", channel->Vpid(), channel->Apid(0));
55
56   if (!processed.init(1000000)) return;
57   pthread_mutex_init(&processedRingLock, NULL);
58
59   // OK
60   
61   // Detect whether this is video or radio and set an appropriate stream chunk size
62   // 50k for video, 5k for radio
63   // Perhaps move this client side?
64   if (channel->Vpid()) streamChunkSize = 50000;
65   else streamChunkSize = 5000;
66   
67   inittedOK = 1;
68   device->SwitchChannel(channel, false);
69   device->AttachReceiver(this);
70 }
71
72 int MVPReceiver::init(TCP* ttcp, ULONG tstreamID)
73 {
74   tcp = ttcp;
75   streamID = tstreamID;
76   return inittedOK;
77 }
78
79 MVPReceiver::~MVPReceiver()
80 {
81   Detach();
82   threadStop();
83
84   numMVPReceivers--;
85   Log::getInstance()->log("MVPReceiver", Log::DEBUG, "num mvp receivers now down to %i", numMVPReceivers);
86 }
87
88 void MVPReceiver::Activate(bool on)
89 {
90   vdrActivated = on;
91   if (on) 
92   {
93     logger->log("MVPReceiver", Log::DEBUG, "VDR active");
94     threadStart();
95   }
96   else
97   {
98     logger->log("MVPReceiver", Log::DEBUG, "VDR inactive, sending stream end message");
99     threadStop();
100     sendStreamEnd();
101   }
102 }
103
104 bool MVPReceiver::isVdrActivated()
105 {
106   return vdrActivated;
107 }
108
109 void MVPReceiver::Receive(UCHAR* data, int length)
110 {
111   pthread_mutex_lock(&processedRingLock);
112   processed.put(data, length);
113   if (processed.getContent() > streamChunkSize) threadSignal();
114   pthread_mutex_unlock(&processedRingLock);
115 }
116
117 void MVPReceiver::threadMethod()
118 {
119   ULONG headerLength = sizeof(ULONG) * 4;
120   UCHAR buffer[streamChunkSize + headerLength];
121   int amountReceived;
122
123 //   threadSetKillable(); ??
124
125   while(1)
126   {
127     threadLock();
128     threadWaitForSignal();
129     threadUnlock();
130     threadCheckExit();
131     
132     do
133     {
134       pthread_mutex_lock(&processedRingLock);
135       amountReceived = processed.get(buffer+headerLength, streamChunkSize);
136       pthread_mutex_unlock(&processedRingLock);
137     
138       *(ULONG*)&buffer[0] = htonl(2); // stream channel
139       *(ULONG*)&buffer[4] = htonl(streamID);
140       *(ULONG*)&buffer[8] = htonl(0); // here insert flag: 0 = ok, data follows
141       *(ULONG*)&buffer[12] = htonl(amountReceived);
142
143       tcp->sendPacket(buffer, amountReceived + headerLength);
144     } while(processed.getContent() >= streamChunkSize);
145   }  
146 }
147
148 void MVPReceiver::sendStreamEnd()
149 {
150   ULONG bufferLength = sizeof(ULONG) * 4;
151   UCHAR buffer[bufferLength];
152   *(ULONG*)&buffer[0] = htonl(2); // stream channel
153   *(ULONG*)&buffer[4] = htonl(streamID);
154   *(ULONG*)&buffer[8] = htonl(1); // stream end
155   *(ULONG*)&buffer[12] = htonl(0); // zero length, no more data
156   tcp->sendPacket(buffer, bufferLength);
157 }
158
159
160 int *MVPReceiver::mergeSpidsTpid(const int *spids,int tpid)
161 {
162   int *destpids;
163   const int *runspid=spids;
164   for (runspid=spids,destpids=mergedSpidsTpid;*runspid;runspid++,destpids++) {
165        *destpids=*runspid;
166   }
167   *destpids=tpid;
168   destpids++;
169   *destpids=0;
170   return mergedSpidsTpid;
171 }