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;
233 void Player::togglePause()
235 if (!initted) return;
236 if (!playing) return;
238 if (ffwd) toggleFastForward();
239 if (fbwd) toggleFastBackward();
257 Log::getInstance()->log("Player", Log::DEBUG, "PLAYER TEST");
263 static int flipflop = 0;
266 if (flipflop) a = video->setAspectRatio(Video::ASPECT16X9);
267 else a = video->setAspectRatio(Video::ASPECT4X3);
269 flipflop = !flipflop;
271 printf("A = %i\n", a);
277 Log::getInstance()->log("Player", Log::DEBUG, "PLAYER TEST");
282 void Player::setPosition(ULLONG position)
284 feedPosition = position;
287 void Player::setLength(ULLONG length)
289 streamLength = length;
290 Log::getInstance()->log("Player", Log::DEBUG, "Player has received length of %llu", streamLength);
293 void Player::skipForward(int seconds)
295 // skip forward 1 minute
296 Log::getInstance()->log("Player", Log::DEBUG, "SKIP FORWARD %i SECONDS", seconds);
298 if (paused) togglePause();
300 ULLONG moveBy = seconds * 500000;
308 audio->doMuting(); // ???
310 feedPosition += moveBy;
312 printf("Audio test %i\n", audio->test());
323 usleep(500000); // SYNC
330 void Player::skipBackward(int seconds)
332 // skip forward 1 minute
333 Log::getInstance()->log("Player", Log::DEBUG, "SKIP BACKWARD %i SECONDS", seconds);
335 if (paused) togglePause();
337 ULLONG moveBy = seconds * 500000;
346 audio->doMuting(); // ???
348 if (feedPosition > moveBy) feedPosition -= moveBy;
358 usleep(500000); // SYNC
365 void Player::toggleFastForward()
367 if (!initted) return;
368 if (!playing) return;
370 if (paused) togglePause();
371 if (fbwd) toggleFastBackward();
376 // video->unFastForward();
397 audio->systemMuteOff();
400 usleep(500000); // SYNC
406 demuxer.flushAudio();
414 audio->systemMuteOff();
421 audio->systemMuteOn();
422 video->fastForward();
426 void Player::toggleFastBackward()
428 if (!initted) return;
429 if (!playing) return;
431 if (paused) togglePause();
432 if (ffwd) toggleFastForward();
438 audio->systemMuteOff();
441 feedMode = MODE_NORMAL;
448 audio->systemMuteOn();
451 feedMode = MODE_BACKWARDS;
459 void Player::jumpToPercent(int percent)
470 feedPosition = streamLength * percent / 100;
480 usleep(500000); // SYNC
489 threadSignalNoLock();
494 void Player::threadMethod()
496 UCHAR buf[blockSize];
501 VDR* vdr = VDR::getInstance();
512 // a bit hackey. this needs to be split to live and rec players
513 if (streamLength && (feedPosition >= streamLength)) break;
515 if (streamLength && ((feedPosition + blockSize) > streamLength))
517 askFor = streamLength - feedPosition;
519 thisRead = vdr->getBlock(buf, feedPosition, askFor);
522 int a_stream = demuxer.scan(buf, thisRead);
523 demuxer.setAudioStream(a_stream);
524 Log::getInstance()->log("Player", Log::DEBUG, "Startup Audio stream chosen %x", a_stream);
528 if (feedMode == MODE_NORMAL)
530 feedPosition += thisRead;
532 else if (feedMode == MODE_BACKWARDS)
534 if (feedPosition >= 100000)
536 feedPosition -= 100000;
541 // got to the start of the recording.. revert to play mode? how?
542 feedPosition += thisRead;
548 while(writeLength < thisRead)
550 thisWrite = demuxer.put(buf + writeLength, thisRead - writeLength);
551 writeLength += thisWrite;
555 Log::getInstance()->log("Player", Log::DEBUG, "DEMUXER FULL!!!");
556 // demuxer is full and cant take anymore
557 threadWaitForSignal();
558 Log::getInstance()->log("Player", Log::DEBUG, "BACK FROM WAIT");
566 Log::getInstance()->log("Player", Log::DEBUG, "Recording playback ends");
567 Message* m = new Message();
568 m->message = Message::STOP_PLAYBACK;
569 Log::getInstance()->log("Player", Log::DEBUG, "Posting message...");
570 commandMessageQueue->postMessage(m);
571 Log::getInstance()->log("Player", Log::DEBUG, "Message posted...");