]> git.vomp.tv Git - vompserver.git/blob - mvpreceiver.c
Code to move recordings. Not quite finished yet
[vompserver.git] / mvpreceiver.c
1 #include "mvpreceiver.h"
2
3 MVPReceiver* MVPReceiver::create(cChannel* channel, int priority)
4 {
5   bool NeedsDetachReceivers;
6   cDevice* device = cDevice::GetDevice(channel, priority, &NeedsDetachReceivers);
7
8   if (!device)
9   {
10     Log::getInstance()->log("MVPReceiver", Log::DEBUG, "No device found to receive this channel at this priority");
11     return NULL;
12   }
13
14   if (NeedsDetachReceivers)
15   {
16     Log::getInstance()->log("MVPReceiver", Log::DEBUG, "Needs detach receivers");
17
18     // Need to detach other receivers or VDR will shut down
19   }
20
21   MVPReceiver* m = new MVPReceiver(channel, device);
22   return m;
23 }
24
25 MVPReceiver::MVPReceiver(cChannel* channel, cDevice* device)
26 #if VDRVERSNUM < 10300
27 : cReceiver(channel->Ca(), 0, 7, channel->Vpid(), channel->Ppid(), channel->Apid1(), channel->Apid2(), channel->Dpid1(), channel->Dpid2(), channel->Tpid())
28 #else
29 : cReceiver(channel->Ca(), 0, channel->Vpid(), channel->Apids(), channel->Dpids(), channel->Spids())
30 #endif
31 {
32   logger = Log::getInstance();
33   vdrActivated = false;
34   inittedOK = 0;
35   remuxer = NULL;
36   unprocessed = NULL;
37
38   // Init
39
40   // Get the remuxer for audio or video
41
42 #if VDRVERSNUM < 10300
43 //  if ((channel->Vpid() == 0) || (channel->Vpid() == 1) || (channel->Vpid() == 0x1FFF))
44 //  {
45 //    remuxer = new cTS2ESRemux(channel->Apid1());
46 //    logger->log("MVPReceiver", Log::DEBUG, "Created new < 1.3 TS->ES");
47 //  }
48 //  else
49 //  {
50     remuxer = new cTS2PSRemux(channel->Vpid(), channel->Apid1(), 0, 0, 0, 0);
51     logger->log("MVPReceiver", Log::DEBUG, "Created new < 1.3 TS->PS");
52 //  }
53 #else
54 //  if ((channel->Vpid() == 0) || (channel->Vpid() == 1) || (channel->Vpid() == 0x1FFF))
55 //  {
56 //    remuxer = new cTS2ESRemux(channel->Apid(0));
57 //    logger->log("MVPReceiver", Log::DEBUG, "Created new > 1.3 TS->ES");
58 //  }
59 //  else
60 //  {
61     remuxer = new cTS2PSRemux(channel->Vpid(), channel->Apid(0), 0, 0, 0, 0);
62     logger->log("MVPReceiver", Log::DEBUG, "Created new > 1.3 TS->PS");
63 //  }
64 #endif
65
66   unprocessed = new cRingBufferLinear(1000000, TS_SIZE * 2, false);
67
68   if (!processed.init(1000000)) return;
69   pthread_mutex_init(&processedRingLock, NULL);
70
71   if (!threadStart()) return;
72
73   // OK
74
75   inittedOK = 1;
76   device->SwitchChannel(channel, false);
77   device->AttachReceiver(this);
78 }
79
80 int MVPReceiver::init()
81 {
82   return inittedOK;
83 }
84
85 MVPReceiver::~MVPReceiver()
86 {
87   Detach();
88   if (threadIsActive()) threadCancel();
89   if (unprocessed) delete unprocessed;
90   if (remuxer) delete remuxer;
91 }
92
93 void MVPReceiver::Activate(bool on)
94 {
95   vdrActivated = on;
96   if (on) logger->log("MVPReceiver", Log::DEBUG, "VDR active");
97   else logger->log("MVPReceiver", Log::DEBUG, "VDR inactive");
98 }
99
100 bool MVPReceiver::isVdrActivated()
101 {
102   return vdrActivated;
103 }
104
105 void MVPReceiver::Receive(UCHAR* data, int length)
106 {
107   static int receiveCount = 0;
108
109 //  int p = unprocessed->Put(data, length);
110 //  if (p != length) printf("Buffer overrun\n");
111
112   unprocessed->Put(data, length);
113
114   if (++receiveCount == 15)
115   {
116     threadSignal();
117     receiveCount = 0;
118   }
119 }
120
121 void MVPReceiver::threadMethod()
122 {
123   int amountGot;
124   UCHAR* dataGot;
125
126   int remuxTook;
127   UCHAR* remuxedData;
128   int outputSize;
129
130   while(1)
131   {
132     threadWaitForSignal();
133
134     while(1)
135     {
136       dataGot = unprocessed->Get(amountGot);
137       if (dataGot && (amountGot > 0))
138       {
139         outputSize = 0;
140         remuxTook = amountGot;
141         remuxedData = remuxer->Process(dataGot, remuxTook, outputSize);
142         unprocessed->Del(remuxTook);
143
144         pthread_mutex_lock(&processedRingLock);
145         processed.put(remuxedData, outputSize);
146         pthread_mutex_unlock(&processedRingLock);
147
148 //        logger->log("MVPReceiver", Log::DEBUG, "Got from unprocessed: %i, Got from remux: %p %i, consumed: %i",
149 //               amountGot, remuxedData, outputSize, remuxTook);
150       }
151       else
152       {
153         break;
154       }
155     }
156   }
157 }
158
159 unsigned long MVPReceiver::getBlock(unsigned char* buffer, unsigned long amount)
160 {
161   pthread_mutex_lock(&processedRingLock);
162
163   int numTries = 0;
164
165   while ((unsigned long)processed.getContent() < amount)
166   {
167     pthread_mutex_unlock(&processedRingLock);
168     if (++numTries == 30) // 15s
169     {
170       logger->log("MVPReceiver", Log::DEBUG, "getBlock timeout");
171       return 0;
172     }
173     usleep(500000);
174     pthread_mutex_lock(&processedRingLock);
175   }
176
177   unsigned long amountReceived = processed.get(buffer, amount);
178   pthread_mutex_unlock(&processedRingLock);
179   return amountReceived;
180 }