]> git.vomp.tv Git - vompclient.git/blob - playerradio.cc
Zero length recording segfault fixed
[vompclient.git] / playerradio.cc
1 /*
2     Copyright 2004-2005 Chris Tallon
3
4     This file is part of VOMP.
5
6     VOMP is free software; you can redistribute it and/or modify
7     it under the terms of the GNU General Public License as published by
8     the Free Software Foundation; either version 2 of the License, or
9     (at your option) any later version.
10
11     VOMP is distributed in the hope that it will be useful,
12     but WITHOUT ANY WARRANTY; without even the implied warranty of
13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14     GNU General Public License for more details.
15
16     You should have received a copy of the GNU General Public License
17     along with VOMP; if not, write to the Free Software
18     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19 */
20
21 // this is a total copy from player but with video stuff taken out
22 // most of this isn't used because it's designed for recording playback
23
24
25 #include "playerradio.h"
26
27 PlayerRadio::PlayerRadio()
28 : afeedr(this, &stream)
29 {
30   paused = 0;
31   playing = 0;
32   ffwd = 0;
33   fbwd = 0;
34   feedPosition = 0;
35   feedMode = MODE_NORMAL;
36 }
37
38 PlayerRadio::~PlayerRadio()
39 {
40   if (initted) shutdown();
41 }
42
43 int PlayerRadio::init()
44 {
45   if (initted) return 0;
46
47   stream.init(120000);
48   afeedr.init(audio->getFD());
49
50   audio->stop();
51
52
53   initted = 1;
54   return 1;
55 }
56
57 int PlayerRadio::shutdown()
58 {
59   if (!initted) return 0;
60   initted = 0;
61
62   Log::getInstance()->log("PlayerRadio", Log::DEBUG, "PlayerRadio shutdown...");
63
64   // copy of stop
65   if (playing)
66   {
67     playing = 0;
68     threadStop();
69     audio->stop();
70     afeedr.stop();
71     feedPosition = 0;
72   }
73
74   return 1;
75 }
76
77 int PlayerRadio::play()
78 {
79   if (!initted) return 0;
80
81   // If we are just paused, unpause!
82   if (paused)
83   {
84     togglePause();
85     return 1;
86   }
87
88   // If we are fast forwarding, set to normal
89   if (ffwd)
90   {
91     toggleFastForward();
92     return 1;
93   }
94
95   // If we are fast backwarding, set to normal
96   if (fbwd)
97   {
98     toggleFastBackward();
99     return 1;
100   }
101
102   // If we are already playing, bail // FIXME - resync?
103   if (playing)
104   {
105     Log::getInstance()->log("PlayerRadio", Log::DEBUG, "DOING RESYNC");
106
107     afeedr.stop();
108     audio->reset();
109     afeedr.start();
110
111
112     audio->play();
113     call(this);
114
115     return 1;
116   }
117
118   // Standard play start
119
120   audio->reset();
121   audio->stop();
122
123 /*
124 // ------------------------ This one works, but doesn't allow any pre-buffering.
125   threadStart();
126   afeedr.start();
127   audio->play();
128   audio->sync();
129
130 // ------------------------ This one doesn't work, but it should, and would allow for prebuffering.
131 */
132
133 //    audio->test();
134   threadStart();
135     sleep(6);
136
137 //  struct timespec delay;
138 //  delay.tv_sec = 1;
139 //  delay.tv_nsec = 500000000;
140 //  nanosleep(&delay, NULL);
141
142
143   afeedr.start();
144   audio->play();
145 //  audio->sync();
146 // ------------------------------------------------------------------------------------------------
147
148   playing = 1;
149   return 1;
150 }
151
152 void PlayerRadio::stop()
153 {
154   if (!initted) return;
155   if (!playing) return;
156   playing = 0;
157
158   threadCancel();
159   audio->stop();
160   afeedr.stop();
161
162   feedPosition = 0;
163 }
164
165 void PlayerRadio::togglePause()
166 {
167   if (!initted) return;
168   if (!playing) return;
169
170   if (ffwd) toggleFastForward();
171   if (fbwd) toggleFastBackward();
172
173   if (paused)
174   {
175     audio->unPause();
176     paused = 0;
177   }
178   else
179   {
180     audio->pause();
181     paused = 1;
182   }
183 }
184
185 void PlayerRadio::setPosition(ULLONG position)
186 {
187   feedPosition = position;
188 }
189
190 void PlayerRadio::setLength(ULLONG length)
191 {
192   streamLength = length;
193   Log::getInstance()->log("PlayerRadio", Log::DEBUG, "Player has received length of %llu", streamLength);
194 }
195
196 void PlayerRadio::skipForward()
197 {
198   // skip forward 1 minute
199   Log::getInstance()->log("PlayerRadio", Log::DEBUG, "SKIP FORWARD 1 MINUTE");
200
201   if (paused) togglePause();
202
203   threadStop();
204   afeedr.stop();
205   audio->stop();
206   audio->reset();
207   audio->doMuting();  // ???
208   feedPosition += 30000000;
209   afeedr.start();
210   threadStart();
211   audio->play();
212 }
213
214 void PlayerRadio::skipBackward()
215 {
216   // skip forward 1 minute
217   Log::getInstance()->log("PlayerRadio", Log::DEBUG, "SKIP BACKWARD 1 MINUTE");
218
219   if (paused) togglePause();
220
221   threadStop();
222   afeedr.stop();
223   audio->stop();
224   audio->reset();
225   audio->doMuting(); // ???
226   if (feedPosition > 30000000) feedPosition -= 30000000;
227   afeedr.start();
228   threadStart();
229   audio->play();
230 }
231
232 void PlayerRadio::toggleFastForward()
233 {
234   if (!initted) return;
235   if (!playing) return;
236
237   if (paused) togglePause();
238   if (fbwd) toggleFastBackward();
239
240   if (ffwd)
241   {
242     ffwd = 0;
243 //    afeedr.enable();
244     audio->reset();
245     audio->systemMuteOff();
246   }
247   else
248   {
249     ffwd = 1;
250 //    afeedr.disable();
251     audio->systemMuteOn();
252   }
253 }
254
255 void PlayerRadio::toggleFastBackward()
256 {
257   if (!initted) return;
258   if (!playing) return;
259
260   if (paused) togglePause();
261   if (ffwd) toggleFastForward();
262
263   if (fbwd)
264   {
265     fbwd = 0;
266 //    afeedr.enable();
267     audio->systemMuteOff();
268
269 //    threadStop();
270     feedMode = MODE_NORMAL;
271 //    threadStart();
272   }
273   else
274   {
275     fbwd = 1;
276 //    afeedr.disable();
277     audio->systemMuteOn();
278
279     threadStop();
280     feedMode = MODE_BACKWARDS;
281     threadStart();
282   }
283 }
284
285 void PlayerRadio::jumpToPercent(int percent)
286 {
287   threadStop();
288   afeedr.stop();
289   audio->stop();
290   audio->reset();
291   feedPosition = streamLength * percent / 100;
292   afeedr.start();
293   threadStart();
294   audio->play();
295   audio->sync();
296 }
297
298
299 void PlayerRadio::call(void* caller)
300 {
301   Log::getInstance()->log("PlayerRadio", Log::DEBUG, "playerradio called\n");
302 //  threadSignalNoLock();
303 }
304
305 // Feed thread
306
307 void PlayerRadio::threadMethod()
308 {
309   UCHAR* buf;
310   UINT thisRead;
311   UINT writeLength;
312   UINT thisWrite;
313
314   VDR* vdr = VDR::getInstance();
315
316   UINT askFor;
317   while(1)
318   {
319     thisRead = 0;
320     writeLength = 0;
321     thisWrite = 0;
322
323     threadCheckExit();
324
325     // a bit hackey. this needs to be split to live and rec players
326     if (streamLength && (feedPosition >= streamLength)) break;
327     askFor = blockSize;
328     if (streamLength && ((feedPosition + blockSize) > streamLength))
329     {
330       askFor = streamLength - feedPosition;
331     }
332     buf = vdr->getBlock(feedPosition, askFor, &thisRead);
333     if (!buf) break;
334
335     printf("Written direct: %i\n", write(audio->getFD(), buf, thisRead)); // temp
336
337
338
339     if (feedMode == MODE_NORMAL)
340     {
341       feedPosition += thisRead;
342     }
343     else if (feedMode == MODE_BACKWARDS)
344     {
345       if (feedPosition >= blockSize)
346       {
347         feedPosition -= blockSize;
348       }
349       else
350       {
351         // got to the start of the recording.. revert to play mode? how?
352         feedPosition += thisRead;
353       }
354     }
355
356     threadCheckExit();
357
358     free(buf);
359
360 /*    while(writeLength < thisRead)
361     {
362       thisWrite = stream.put(buf + writeLength, thisRead - writeLength);
363       Log::getInstance()->log("PlayerRadio", Log::DEBUG, "Just put %i to stream", thisWrite);
364
365       writeLength += thisWrite;
366
367       if (!thisWrite)
368       {
369         Log::getInstance()->log("PlayerRadio", Log::DEBUG, "RADIO OUTPUT STREAM FULL!!!");
370         // stream is full and cant take anymore
371         threadLock();
372         threadWaitForSignal();
373         threadUnlock();
374         Log::getInstance()->log("PlayerRadio", Log::DEBUG, "BACK FROM WAIT");
375       }
376
377       threadCheckExit();
378     }
379
380     Log::getInstance()->log("PlayerRadio", Log::DEBUG, "Written audio");
381 */
382   }
383 }