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");
145 // Standard play start
152 // ------------------------ This one works, but doesn't allow any pre-buffering.
160 // ------------------------ This one doesn't work, but it should, and would allow for prebuffering.
167 // struct timespec delay;
169 // delay.tv_nsec = 500000000;
170 // nanosleep(&delay, NULL);
179 // ------------------------------------------------------------------------------------------------
187 if (!initted) return;
188 if (!playing) return;
195 video->unFastForward();
196 audio->systemMuteOff();
197 feedMode = MODE_NORMAL;
214 void Player::togglePause()
216 if (!initted) return;
217 if (!playing) return;
219 if (ffwd) toggleFastForward();
220 if (fbwd) toggleFastBackward();
238 Log::getInstance()->log("Player", Log::DEBUG, "PLAYER TEST");
242 // static int flipflop = 0;
244 // if (flipflop) video->setAspectRatio(Video::ASPECT16X9);
245 // else video->setAspectRatio(Video::ASPECT4X3);
247 // flipflop = !flipflop;
253 Log::getInstance()->log("Player", Log::DEBUG, "PLAYER TEST");
258 void Player::setPosition(ULLONG position)
260 feedPosition = position;
263 void Player::setLength(ULLONG length)
265 streamLength = length;
266 Log::getInstance()->log("Player", Log::DEBUG, "Player has received length of %llu", streamLength);
269 void Player::skipForward(int seconds)
271 // skip forward 1 minute
272 Log::getInstance()->log("Player", Log::DEBUG, "SKIP FORWARD %i SECONDS", seconds);
274 if (paused) togglePause();
276 ULLONG moveBy = seconds * 500000;
284 audio->doMuting(); // ???
286 feedPosition += moveBy;
288 printf("Audio test %i\n", audio->test());
300 void Player::skipBackward(int seconds)
302 // skip forward 1 minute
303 Log::getInstance()->log("Player", Log::DEBUG, "SKIP BACKWARD %i SECONDS", seconds);
305 if (paused) togglePause();
307 ULLONG moveBy = seconds * 500000;
316 audio->doMuting(); // ???
318 if (feedPosition > moveBy) feedPosition -= moveBy;
328 void Player::toggleFastForward()
330 if (!initted) return;
331 if (!playing) return;
333 if (paused) togglePause();
334 if (fbwd) toggleFastBackward();
340 video->unFastForward();
344 audio->systemMuteOff();
350 audio->systemMuteOn();
351 video->fastForward();
355 void Player::toggleFastBackward()
357 if (!initted) return;
358 if (!playing) return;
360 if (paused) togglePause();
361 if (ffwd) toggleFastForward();
367 audio->systemMuteOff();
370 feedMode = MODE_NORMAL;
377 audio->systemMuteOn();
380 feedMode = MODE_BACKWARDS;
388 void Player::jumpToPercent(int percent)
399 feedPosition = streamLength * percent / 100;
412 threadSignalNoLock();
417 void Player::threadMethod()
419 UCHAR buf[blockSize];
424 VDR* vdr = VDR::getInstance();
435 // a bit hackey. this needs to be split to live and rec players
436 if (streamLength && (feedPosition >= streamLength)) break;
438 if (streamLength && ((feedPosition + blockSize) > streamLength))
440 askFor = streamLength - feedPosition;
442 thisRead = vdr->getBlock(buf, feedPosition, askFor);
445 int a_stream = demuxer.scan(buf, thisRead);
446 demuxer.setAudioStream(a_stream);
447 Log::getInstance()->log("Player", Log::DEBUG, "Startup Audio stream chosen %x", a_stream);
451 if (feedMode == MODE_NORMAL)
453 feedPosition += thisRead;
455 else if (feedMode == MODE_BACKWARDS)
457 if (feedPosition >= 100000)
459 feedPosition -= 100000;
464 // got to the start of the recording.. revert to play mode? how?
465 feedPosition += thisRead;
471 while(writeLength < thisRead)
473 thisWrite = demuxer.put(buf + writeLength, thisRead - writeLength);
474 writeLength += thisWrite;
478 Log::getInstance()->log("Player", Log::DEBUG, "DEMUXER FULL!!!");
479 // demuxer is full and cant take anymore
480 threadWaitForSignal();
481 Log::getInstance()->log("Player", Log::DEBUG, "BACK FROM WAIT");
489 Log::getInstance()->log("Player", Log::DEBUG, "Recording playback ends");
490 Message* m = new Message();
491 m->message = Message::STOP_PLAYBACK;
492 Log::getInstance()->log("Player", Log::DEBUG, "Posting message...");
493 commandMessageQueue->postMessage(m);
494 Log::getInstance()->log("Player", Log::DEBUG, "Message posted...");