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");
261 static int flipflop = 0;
264 if (flipflop) a = video->setAspectRatio(Video::ASPECT16X9);
265 else a = video->setAspectRatio(Video::ASPECT4X3);
267 flipflop = !flipflop;
269 printf("A = %i\n", a);
275 Log::getInstance()->log("Player", Log::DEBUG, "PLAYER TEST");
280 void Player::setPosition(ULLONG position)
282 feedPosition = position;
285 void Player::setLength(ULLONG length)
287 streamLength = length;
288 Log::getInstance()->log("Player", Log::DEBUG, "Player has received length of %llu", streamLength);
291 void Player::skipForward(int seconds)
293 // skip forward 1 minute
294 Log::getInstance()->log("Player", Log::DEBUG, "SKIP FORWARD %i SECONDS", seconds);
296 if (paused) togglePause();
298 ULLONG moveBy = seconds * 500000;
306 audio->doMuting(); // ???
308 feedPosition += moveBy;
310 printf("Audio test %i\n", audio->test());
321 usleep(500000); // SYNC
328 void Player::skipBackward(int seconds)
330 // skip forward 1 minute
331 Log::getInstance()->log("Player", Log::DEBUG, "SKIP BACKWARD %i SECONDS", seconds);
333 if (paused) togglePause();
335 ULLONG moveBy = seconds * 500000;
344 audio->doMuting(); // ???
346 if (feedPosition > moveBy) feedPosition -= moveBy;
356 usleep(500000); // SYNC
363 void Player::toggleFastForward()
365 if (!initted) return;
366 if (!playing) return;
368 if (paused) togglePause();
369 if (fbwd) toggleFastBackward();
374 // video->unFastForward();
395 audio->systemMuteOff();
398 usleep(500000); // SYNC
404 demuxer.flushAudio();
412 audio->systemMuteOff();
419 audio->systemMuteOn();
420 video->fastForward();
424 void Player::toggleFastBackward()
426 if (!initted) return;
427 if (!playing) return;
429 if (paused) togglePause();
430 if (ffwd) toggleFastForward();
436 audio->systemMuteOff();
439 feedMode = MODE_NORMAL;
446 audio->systemMuteOn();
449 feedMode = MODE_BACKWARDS;
457 void Player::jumpToPercent(int percent)
468 feedPosition = streamLength * percent / 100;
478 usleep(500000); // SYNC
487 threadSignalNoLock();
492 void Player::threadMethod()
494 UCHAR buf[blockSize];
499 VDR* vdr = VDR::getInstance();
510 // a bit hackey. this needs to be split to live and rec players
511 if (streamLength && (feedPosition >= streamLength)) break;
513 if (streamLength && ((feedPosition + blockSize) > streamLength))
515 askFor = streamLength - feedPosition;
517 thisRead = vdr->getBlock(buf, feedPosition, askFor);
520 int a_stream = demuxer.scan(buf, thisRead);
521 demuxer.setAudioStream(a_stream);
522 Log::getInstance()->log("Player", Log::DEBUG, "Startup Audio stream chosen %x", a_stream);
526 if (feedMode == MODE_NORMAL)
528 feedPosition += thisRead;
530 else if (feedMode == MODE_BACKWARDS)
532 if (feedPosition >= 100000)
534 feedPosition -= 100000;
539 // got to the start of the recording.. revert to play mode? how?
540 feedPosition += thisRead;
546 while(writeLength < thisRead)
548 thisWrite = demuxer.put(buf + writeLength, thisRead - writeLength);
549 writeLength += thisWrite;
553 Log::getInstance()->log("Player", Log::DEBUG, "DEMUXER FULL!!!");
554 // demuxer is full and cant take anymore
555 threadWaitForSignal();
556 Log::getInstance()->log("Player", Log::DEBUG, "BACK FROM WAIT");
564 Log::getInstance()->log("Player", Log::DEBUG, "Recording playback ends");
565 Message* m = new Message();
566 m->message = Message::STOP_PLAYBACK;
567 Log::getInstance()->log("Player", Log::DEBUG, "Posting message...");
568 commandMessageQueue->postMessage(m);
569 Log::getInstance()->log("Player", Log::DEBUG, "Message posted...");