2 Copyright 2004-2005 Chris Tallon
4 This file is part of VOMP.
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.
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.
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
23 Player::Player(MessageQueue* messageQueue)
24 : vfeed(this), afeed(this)
27 commandMessageQueue = messageQueue;
34 feedMode = MODE_NORMAL;
37 // FIXME - this might need settings back to zero for new live play depending on what is done with it
42 if (initted) shutdown();
47 if (initted) return 0;
49 video = Video::getInstance();
50 audio = Audio::getInstance();
52 if (demuxer.init()) // inverted
54 Log::getInstance()->log("Player", Log::ERR, "Demuxer failed to init");
59 vfeed.init(video->getFD());
60 afeed.init(audio->getFD());
71 int Player::shutdown()
73 if (!initted) return 0;
76 Log::getInstance()->log("Player", Log::DEBUG, "Player shutdown...");
98 if (!initted) return 0;
100 // If we are just paused, unpause!
107 // If we are fast forwarding, set to normal
114 // If we are fast backwarding, set to normal
117 toggleFastBackward();
121 // If we are already playing, bail // FIXME - resync?
124 Log::getInstance()->log("Player", Log::DEBUG, "DOING RESYNC");
155 // Standard play start
162 // ------------------------ This one works, but doesn't allow any pre-buffering.
172 usleep(500000); // SYNC
177 // ------------------------ This one doesn't work, but it should, and would allow for prebuffering.
184 // struct timespec delay;
186 // delay.tv_nsec = 500000000;
187 // nanosleep(&delay, NULL);
196 // ------------------------------------------------------------------------------------------------
204 if (!initted) return;
205 if (!playing) return;
212 video->unFastForward();
213 audio->systemMuteOff();
214 feedMode = MODE_NORMAL;
231 void Player::togglePause()
233 if (!initted) return;
234 if (!playing) return;
236 if (ffwd) toggleFastForward();
237 if (fbwd) toggleFastBackward();
255 Log::getInstance()->log("Player", Log::DEBUG, "PLAYER TEST");
259 // static int flipflop = 0;
261 // if (flipflop) video->setAspectRatio(Video::ASPECT16X9);
262 // else video->setAspectRatio(Video::ASPECT4X3);
264 // flipflop = !flipflop;
271 Log::getInstance()->log("Player", Log::DEBUG, "PLAYER TEST");
276 void Player::setPosition(ULLONG position)
278 feedPosition = position;
281 void Player::setLength(ULLONG length)
283 streamLength = length;
284 Log::getInstance()->log("Player", Log::DEBUG, "Player has received length of %llu", streamLength);
287 void Player::skipForward(int seconds)
289 // skip forward 1 minute
290 Log::getInstance()->log("Player", Log::DEBUG, "SKIP FORWARD %i SECONDS", seconds);
292 if (paused) togglePause();
294 ULLONG moveBy = seconds * 500000;
302 audio->doMuting(); // ???
304 feedPosition += moveBy;
306 printf("Audio test %i\n", audio->test());
317 usleep(500000); // SYNC
324 void Player::skipBackward(int seconds)
326 // skip forward 1 minute
327 Log::getInstance()->log("Player", Log::DEBUG, "SKIP BACKWARD %i SECONDS", seconds);
329 if (paused) togglePause();
331 ULLONG moveBy = seconds * 500000;
340 audio->doMuting(); // ???
342 if (feedPosition > moveBy) feedPosition -= moveBy;
352 usleep(500000); // SYNC
359 void Player::toggleFastForward()
361 if (!initted) return;
362 if (!playing) return;
364 if (paused) togglePause();
365 if (fbwd) toggleFastBackward();
370 // video->unFastForward();
391 audio->systemMuteOff();
394 usleep(500000); // SYNC
400 demuxer.flushAudio();
408 audio->systemMuteOff();
415 audio->systemMuteOn();
416 video->fastForward();
420 void Player::toggleFastBackward()
422 if (!initted) return;
423 if (!playing) return;
425 if (paused) togglePause();
426 if (ffwd) toggleFastForward();
432 audio->systemMuteOff();
435 feedMode = MODE_NORMAL;
442 audio->systemMuteOn();
445 feedMode = MODE_BACKWARDS;
453 void Player::jumpToPercent(int percent)
464 feedPosition = streamLength * percent / 100;
474 usleep(500000); // SYNC
483 threadSignalNoLock();
488 void Player::threadMethod()
490 UCHAR buf[blockSize];
495 VDR* vdr = VDR::getInstance();
506 // a bit hackey. this needs to be split to live and rec players
507 if (streamLength && (feedPosition >= streamLength)) break;
509 if (streamLength && ((feedPosition + blockSize) > streamLength))
511 askFor = streamLength - feedPosition;
513 thisRead = vdr->getBlock(buf, feedPosition, askFor);
516 int a_stream = demuxer.scan(buf, thisRead);
517 demuxer.setAudioStream(a_stream);
518 Log::getInstance()->log("Player", Log::DEBUG, "Startup Audio stream chosen %x", a_stream);
522 if (feedMode == MODE_NORMAL)
524 feedPosition += thisRead;
526 else if (feedMode == MODE_BACKWARDS)
528 if (feedPosition >= 100000)
530 feedPosition -= 100000;
535 // got to the start of the recording.. revert to play mode? how?
536 feedPosition += thisRead;
542 while(writeLength < thisRead)
544 thisWrite = demuxer.put(buf + writeLength, thisRead - writeLength);
545 writeLength += thisWrite;
549 Log::getInstance()->log("Player", Log::DEBUG, "DEMUXER FULL!!!");
550 // demuxer is full and cant take anymore
551 threadWaitForSignal();
552 Log::getInstance()->log("Player", Log::DEBUG, "BACK FROM WAIT");
560 Log::getInstance()->log("Player", Log::DEBUG, "Recording playback ends");
561 Message* m = new Message();
562 m->message = Message::STOP_PLAYBACK;
563 Log::getInstance()->log("Player", Log::DEBUG, "Posting message...");
564 commandMessageQueue->postMessage(m);
565 Log::getInstance()->log("Player", Log::DEBUG, "Message posted...");