switch(ifactor)
{
case 2: ifactor = 4; break;
- case 4: ifactor = 6; break;
- case 6: ifactor = 8; break;
- case 8: ifactor = 2; break;
+ case 4: ifactor = 8; break;
+ case 8: ifactor = 16; break;
+ case 16: ifactor = 64; break;
+ case 64: ifactor = 2; break;
}
}
else
switch(ifactor)
{
case 2: ifactor = 4; break;
- case 4: ifactor = 6; break;
- case 6: ifactor = 8; break;
- case 8: ifactor = 2; break;
+ case 4: ifactor = 8; break;
+ case 8: ifactor = 16; break;
+ case 16: ifactor = 64; break;
+ case 64: ifactor = 2; break;
}
}
else
// is to get the wait right so that the scan occurs at the correct rate.
ULONG direction = 0;
+ ULONG baseFrameNumber = 0;
ULONG iframeNumber = 0;
ULONG iframeLength = 0;
ULLONG filePos;
UINT amountReceived;
UINT videoLength;
- ULONG iframesep;
-
#ifndef _MSC_VER
- struct timeval loopTime;
- struct timeval loopTimeN;
+ struct timeval clock0 = {0,0}; // Time stamp after fetching I-frame info
+ struct timeval clock1 = {0,0}; // Time stamp after fetching I-frame data
+ struct timeval clock2 = {0,0} ; // Time stamp after displaying I-frame
#else
- DWORD loopTime;
- DWORD loopTimeN;
+ DWORD clock0 = 0, clock1 = 0, clock2 = 0;
#endif
- ULONG realLoopTime;
- ULONG sleepTime = 0;
- UINT offset;
+ int frameTimeOffset = 0; // Time in msec between frames
+ int disp_msec = 0; // Time taken to display data
+ int total_msec = 0; // Time taken to fetch data and display it
+ int sleepTime = 0;
if (state == S_FFWD) direction = 1; // and 0 for backward
- #ifndef WIN32
- gettimeofday(&loopTime, NULL);
- #else
- loopTime = timeGetTime();
- #endif
-
while(1)
{
- if (!vdr->getNextIFrame(currentFrameNumber, direction, &filePos, &iframeNumber, &iframeLength)) break;
+ // Fetch I-frames until we get one that can be displayed in good time
+ // Repeat while clock0 + total_msec > clock2 + frameTimeOffset
+ baseFrameNumber = currentFrameNumber;
+ do
+ {
+ if (!vdr->getNextIFrame(baseFrameNumber, direction, &filePos, &iframeNumber, &iframeLength))
+ return;
+
+ baseFrameNumber = iframeNumber;
+ frameTimeOffset = abs(iframeNumber - currentFrameNumber) * 1000 / (video->getFPS() * ifactor);
+#ifndef WIN32
+ gettimeofday(&clock0, NULL);
+#else
+ clock0 = timeGetTime();
+#endif
+ }
+#ifndef WIN32
+ while (clock2.tv_sec != 0 &&
+ (clock0.tv_sec - clock2.tv_sec) * 1000 +
+ (clock0.tv_usec - clock2.tv_usec) / 1000 > frameTimeOffset - total_msec);
+#else
+ while (clock2 != 0 && clock0 + total_msec > clock2 + frameTimeOffset);
+#endif
+// logger->log("Player", Log::DEBUG, "XXX Got frame");
+
threadBuffer = vdr->getBlock(filePos, iframeLength, &amountReceived);
+#ifndef WIN32
+ gettimeofday(&clock1, NULL);
+ if (clock2.tv_sec != 0)
+ sleepTime = (clock2.tv_sec - clock1.tv_sec) * 1000
+ + (clock2.tv_usec - clock1.tv_usec) / 1000
+ + frameTimeOffset - disp_msec;
+#else
+ clock1 = timeGetTime():
+ if (clock2 != 0)
+ sleepTime = clock2 + frameTimeOffset - disp_msec - clock1;
+#endif
+ if (sleepTime < 0) sleepTime = 0;
+ threadCheckExit();
+ MILLISLEEP(sleepTime);
+// logger->log("Player", Log::DEBUG, "XXX Slept for %d", sleepTime);
+
videoLength = demuxer->stripAudio(threadBuffer, amountReceived);
video->displayIFrame(threadBuffer, videoLength);
- iframesep = abs(iframeNumber - currentFrameNumber);
currentFrameNumber = iframeNumber;
free(threadBuffer);
threadBuffer = NULL;
- threadCheckExit();
- // Calculate next jump delay
#ifndef WIN32
- gettimeofday(&loopTimeN, NULL);
- realLoopTime = ((loopTimeN.tv_sec - loopTime.tv_sec) * 1000) + ((loopTimeN.tv_usec - loopTime.tv_usec) / 1000);
- loopTime.tv_sec = loopTimeN.tv_sec;
- loopTime.tv_usec = loopTimeN.tv_usec;
+ gettimeofday(&clock2, NULL);
+ total_msec = (clock2.tv_sec - clock0.tv_sec) * 1000
+ + (clock2.tv_usec - clock0.tv_usec) / 1000
+ - sleepTime;
+ disp_msec = (clock2.tv_sec - clock1.tv_sec) * 1000
+ + (clock2.tv_usec - clock1.tv_usec) / 1000
+ - sleepTime;
#else
- loopTimeN = timeGetTime();
- realLoopTime = loopTimeN - loopTime;
- loopTime = loopTimeN;
+ clock2 = timeGetTime();
+ total_msec = clock2 - clock0 - sleepTime;
+ disp_msec = clock2 - clock1 - sleepTime;
#endif
-
- offset = 0;
- if (sleepTime) offset = realLoopTime - sleepTime;
- if (realLoopTime < sleepTime) offset = 0; // sanity check - loop was shorter than requested?
-
- sleepTime = (1000 * iframesep) / (video->getFPS() * ifactor);
- if (offset > sleepTime) sleepTime = 0;
- else sleepTime -= offset;
-
- logger->log("Player", Log::DEBUG, "iframesep %lu, fps %u, ifactor %u, offset %lu, sleep %lu", iframesep, video->getFPS(), ifactor, offset, sleepTime);
- MILLISLEEP(sleepTime);
- threadCheckExit();
+// logger->log("Player", Log::DEBUG, "XXX disp_msec = %4d total_msec = %4d", disp_msec, total_msec);
}
- // scan has hit one end
}
void Player::threadPostStopCleanup()
case Remote::RED:
{
//player->test1();
+ Video::getInstance()->setAspectRatio(Video::ASPECT4X3);
+
/*
// for testing EPG in NTSC with a NTSC test video
}
case Remote::GREEN:
{
- player->test2();
+ Video::getInstance()->setAspectRatio(Video::ASPECT16X9);
+ //player->test2();
return 2;
}
#endif
}
else
{
- timers->setTimerD(this, 1, 4); // only set the getridofbar timer if not ffwd/fbwd
- stickyBar = false;
+// timers->setTimerD(this, 1, 4); // only set the getridofbar timer if not ffwd/fbwd
+// stickyBar = false;
}
timers->setTimerD(this, 2, 0, 200000000);
}
rectangle(clocksRegion, barBlue);
ULONG currentFrameNum = player->getCurrentFrameNum();
- ULONG lengthFrames = player->getLengthFrames();
+ ULONG lengthFrames;
+ if (myRec->recInfo->timerEnd > time(NULL))
+ {
+ // chasing playback
+ // Work out an approximate length in frames (good to 1s...)
+ lengthFrames = (myRec->recInfo->timerEnd - myRec->recInfo->timerStart) * video->getFPS();
+ }
+ else
+ {
+ lengthFrames = player->getLengthFrames();
+ }
hmsf currentFrameHMSF = video->framesToHMSF(currentFrameNum);
hmsf lengthHMSF = video->framesToHMSF(lengthFrames);
rectangle(barRegion.x + progBarXbase, barRegion.y + 12, 310, 24, Colour::LIGHTTEXT);
rectangle(barRegion.x + progBarXbase + 2, barRegion.y + 14, 306, 20, barBlue);
- if (currentFrameNum < lengthFrames)
- {
+ if (currentFrameNum > lengthFrames) return;
+
+
+ // Draw yellow portion
+ int progressWidth = 302 * currentFrameNum / lengthFrames;
+ rectangle(barRegion.x + progBarXbase + 4, barRegion.y + 16, progressWidth, 16, Colour::SELECTHIGHLIGHT);
- int progressWidth = 302 * currentFrameNum / lengthFrames;
+ if (myRec->recInfo->timerEnd > time(NULL)) // if chasing
+ {
+ int nrWidth = (int)(302 * ((double)(lengthFrames - player->getLengthFrames()) / lengthFrames));
- rectangle(barRegion.x + progBarXbase + 4, barRegion.y + 16, progressWidth, 16, Colour::SELECTHIGHLIGHT);
+ Log::getInstance()->log("GVASDF", Log::DEBUG, "Length Frames: %lu", lengthFrames);
+ Log::getInstance()->log("GVASDF", Log::DEBUG, "Player lf: %lu", player->getLengthFrames());
+ Log::getInstance()->log("GVASDF", Log::DEBUG, "NR WDITH: %i", nrWidth);
+ rectangle(barRegion.x + progBarXbase + 4 + 302 - nrWidth, barRegion.y + 16, nrWidth, 16, Colour::RED);
+ }
- // Now calc position for start margin blips
- int posPix;
+ // Now calc position for start margin blips
+ int posPix;
- posPix = 302 * startMargin * video->getFPS() / lengthFrames;
+ posPix = 302 * startMargin * video->getFPS() / lengthFrames;
- rectangle(barRegion.x + progBarXbase + 2 + posPix, barRegion.y + 12 - 2, 2, 2, Colour::LIGHTTEXT);
- rectangle(barRegion.x + progBarXbase + 2 + posPix, barRegion.y + 12 + 24, 2, 2, Colour::LIGHTTEXT);
+ rectangle(barRegion.x + progBarXbase + 2 + posPix, barRegion.y + 12 - 2, 2, 2, Colour::LIGHTTEXT);
+ rectangle(barRegion.x + progBarXbase + 2 + posPix, barRegion.y + 12 + 24, 2, 2, Colour::LIGHTTEXT);
- posPix = 302 * (lengthFrames - endMargin * video->getFPS()) / lengthFrames;
+ posPix = 302 * (lengthFrames - endMargin * video->getFPS()) / lengthFrames;
- rectangle(barRegion.x + progBarXbase + 2 + posPix, barRegion.y + 12 - 2, 2, 2, Colour::LIGHTTEXT);
- rectangle(barRegion.x + progBarXbase + 2 + posPix, barRegion.y + 12 + 24, 2, 2, Colour::LIGHTTEXT);
- }
+ rectangle(barRegion.x + progBarXbase + 2 + posPix, barRegion.y + 12 - 2, 2, 2, Colour::LIGHTTEXT);
+ rectangle(barRegion.x + progBarXbase + 2 + posPix, barRegion.y + 12 + 24, 2, 2, Colour::LIGHTTEXT);
}
void VVideoRec::removeBar()