lengthFrames = 0;
currentFrameNumber = 0;
state = S_STOP;
+ ifactor = 2;
videoStartup = false;
preBuffering = false;
unLock();
}
-void Player::togglePause()
+void Player::pause()
{
if (!initted) return;
lock();
unLock();
}
-void Player::toggleFastForward()
+void Player::fastForward()
{
if (!initted) return;
lock();
- if (state == S_FFWD) switchState(S_PLAY);
- else switchState(S_FFWD);
+
+ if (state == S_FFWD)
+ {
+ // change the rate
+ switch(ifactor)
+ {
+ case 2: ifactor = 4; break;
+ case 4: ifactor = 6; break;
+ case 6: ifactor = 8; break;
+ case 8: ifactor = 2; break;
+ }
+ }
+ else
+ {
+ ifactor = 2;
+ switchState(S_FFWD);
+ }
unLock();
}
-void Player::toggleFastBackward()
+void Player::fastBackward()
{
if (!initted) return;
lock();
- if (state == S_FBWD) switchState(S_PLAY);
- else switchState(S_FBWD);
+
+ if (state == S_FBWD)
+ {
+ // change the rate
+ switch(ifactor)
+ {
+ case 2: ifactor = 4; break;
+ case 4: ifactor = 6; break;
+ case 6: ifactor = 8; break;
+ case 8: ifactor = 2; break;
+ }
+ }
+ else
+ {
+ ifactor = 2;
+ switchState(S_FBWD);
+ }
unLock();
}
logger->log("Player", Log::DEBUG, "Message posted...");
}
-/*
void Player::threadFeedScan()
{
- ULONG direction = 0;
- ULONG iframeNumber = 0;
- ULONG iframeLength = 0;
- ULLONG filePos;
- UINT amountReceived;
- UINT videoLength;
-
- struct timeval displayDelayA;
- struct timeval displayDelayB;
- ULONG displayDelay;
-
- ULONG iframesep;
- ULONG sleeptime;
-
- if (state == S_FFWD) direction = 1; // and 0 for backward
+ // This method is actually really simple - get frame from vdr,
+ // spit it at the video chip, wait for a time. Most of the code here
+ // is to get the wait right so that the scan occurs at the correct rate.
- while(1)
- {
- gettimeofday(&displayDelayA, NULL);
-
- if (!vdr->getNextIFrame(currentFrameNumber, direction, &filePos, &iframeNumber, &iframeLength)) break;
- threadBuffer = vdr->getBlock(filePos, iframeLength, &amountReceived);
- videoLength = demuxer->stripAudio(threadBuffer, amountReceived);
- video->displayIFrame(threadBuffer, videoLength);
- iframesep = abs(iframeNumber - currentFrameNumber);
- currentFrameNumber = iframeNumber;
- free(threadBuffer);
- threadBuffer = NULL;
- threadCheckExit();
-
- // Calculate next jump delay
- gettimeofday(&displayDelayB, NULL);
- displayDelay = ((displayDelayB.tv_sec - displayDelayA.tv_sec) * 1000) + ((displayDelayB.tv_usec - displayDelayA.tv_usec) / 1000);
- sleeptime = (1000 * iframesep) / (video->getFPS() * ifactor);
- if (displayDelay > sleeptime) sleeptime = 0;
- else sleeptime -= displayDelay;
- logger->log("Player", Log::DEBUG, "iframesep %lu, fps %u, ifactor %u, displayDelay %lu, sleep %lu", iframesep, video->getFPS(), ifactor, displayDelay, sleeptime);
- MILLISLEEP(sleeptime);
- }
- // scan has hit one end
-}
-*/
-
-void Player::threadFeedScan()
-{
ULONG direction = 0;
ULONG iframeNumber = 0;
ULONG iframeLength = 0;
logger->log("Player", Log::DEBUG, "iframesep %lu, fps %u, ifactor %u, offset %lu, sleep %lu", iframesep, video->getFPS(), ifactor, offset, sleepTime);
MILLISLEEP(sleepTime);
+ threadCheckExit();
}
// scan has hit one end
}
void play();
void stop();
- void togglePause();
- void toggleFastForward();
- void toggleFastBackward();
+ void pause();
+ void fastForward();
+ void fastBackward();
void jumpToPercent(int percent);
void skipForward(int seconds);
void skipBackward(int seconds);
UCHAR getState() { return state; }
ULONG getCurrentFrameNum();
ULONG getLengthFrames();
+ UCHAR getIScanRate() { return ifactor; }
void call(void*); // for callback interface
UINT startupBlockSize;
UCHAR* threadBuffer;
UCHAR state;
-
- const static UINT ifactor = 5;
+ UCHAR ifactor;
};
#endif
setBackgroundColour(transparent);
barRegion.x = 0;
- barRegion.y = video->getScreenHeight() - 66; // FIXME, need to be - 1? and below?
+ barRegion.y = video->getScreenHeight() - 58; // FIXME, need to be - 1? and below?
barRegion.w = video->getScreenWidth();
barRegion.h = 66;
barBlue.set(0, 0, 150, 150);
barShowing = false;
+ stickyBar = false;
}
VVideoRec::~VVideoRec()
}
case Remote::PAUSE:
{
- player->togglePause();
+ player->pause();
doBar(0);
return 2;
}
}
case Remote::FORWARD:
{
- player->toggleFastForward();
+ player->fastForward();
doBar(0);
return 2;
}
case Remote::REVERSE:
{
- player->toggleFastBackward();
+ player->fastBackward();
doBar(0);
return 2;
}
WSymbol w;
w.setSurface(surface);
w.nextSymbol = 0;
- w.setSurfaceOffset(76, barRegion.y + 16);
+ w.setSurfaceOffset(barRegion.x + 66, barRegion.y + 16);
+
+ UCHAR playerState = 0;
if (action)
{
}
else
{
- UCHAR playerState = player->getState();
+ playerState = player->getState();
if (playerState == Player::S_PAUSE_P) w.nextSymbol = WSymbol::PAUSE;
else if (playerState == Player::S_PAUSE_I) w.nextSymbol = WSymbol::PAUSE;
else if (playerState == Player::S_FFWD) w.nextSymbol = WSymbol::FFWD;
w.draw();
+ if ((playerState == Player::S_FFWD) || (playerState == Player::S_FBWD))
+ {
+ // draw blips to show how fast the scan is
+ UCHAR scanrate = player->getIScanRate();
+ if (scanrate >= 2)
+ {
+ char* text = new char[5];
+ SNPRINTF(text, 5, "%ux", scanrate);
+ drawText(text, barRegion.x + 102, barRegion.y + 12, Colour::LIGHTTEXT);
+ }
+ }
+
drawBarClocks();
ViewMan::getInstance()->updateView(this, &barRegion);
- timers->setTimerD(this, 1, 4);
+
+ if ((playerState == Player::S_FFWD) || (playerState == Player::S_FBWD))
+ {
+ timers->cancelTimer(this, 1);
+ stickyBar = true;
+ }
+ else
+ {
+ timers->setTimerD(this, 1, 4); // only set the getridofbar timer if not ffwd/fbwd
+ stickyBar = false;
+ }
timers->setTimerD(this, 2, 0, 200000000);
}
void VVideoRec::drawBarClocks()
{
+ if (stickyBar)
+ {
+ UCHAR playerState = player->getState();
+ // sticky bar is set if we are in ffwd/fbwd mode
+ // if player has gone to S_PLAY then kill stickyBar, and run doBar(0) which
+ // will repaint all the bar (it will call this function again, but
+ // this section won't run because stickyBar will then == false)
+
+ if ((playerState != Player::S_FFWD) && (playerState != Player::S_FBWD))
+ {
+ stickyBar = false;
+ doBar(0);
+ return; // doBar will call this function and do the rest
+ }
+ }
+
Log* logger = Log::getInstance();
logger->log("VVideoRec", Log::DEBUG, "Draw bar clocks");
if (!barShowing) return;
timers->cancelTimer(this, 2);
barShowing = false;
+ stickyBar = false;
rectangle(barRegion, transparent);
ViewMan::getInstance()->updateView(this, &barRegion);
}
bool playing;
bool barShowing;
+ bool stickyBar;
void doBar(int action);
void drawBarClocks();
void stopPlay();