{
lock();
logger->log("Player", Log::DEBUG, "SKIP FORWARD %i SECONDS", seconds);
- ULONG newFrame = getCurrentFrameNum() + (seconds * video->getFPS());
+ ULONG newFrame = getCurrentFrameNum();
+ if (newFrame == 0) { unLock(); return; } // Current pos from demuxer is not valid
+ newFrame += seconds * video->getFPS();
if (newFrame > lengthFrames) { switchState(S_PLAY); unLock(); }
else switchState(S_JUMP, newFrame);
// unLock(); - let thread unlock this
{
lock();
logger->log("Player", Log::DEBUG, "SKIP BACKWARD %i SECONDS", seconds);
- long newFrameNum = getCurrentFrameNum() - (seconds * video->getFPS());
- if (newFrameNum < 0) newFrameNum = 0;
- switchState(S_JUMP, newFrameNum);
+ long newFrame = getCurrentFrameNum();
+ if (newFrame == 0) { unLock(); return; } // Current pos from demuxer is not valid
+ newFrame -= seconds * video->getFPS();
+ if (newFrame < 0) newFrame = 0;
+ switchState(S_JUMP, newFrame);
// unLock(); - let thread unlock this
}
video->sync();
vfeed.release();
unLock();
- logger->log("Player", Log::DEBUG, "BANG BANG BANG BANG BANG BANG BANG BANG BANG BANG BANG");
}
threadSignalNoLock();
logger->log("Player", Log::DEBUG, "Message posted...");
}
+/*
void Player::threadFeedScan()
{
ULONG direction = 0;
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
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();
- MILLISLEEP(100);
+
+ // 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;
+ ULLONG filePos;
+ UINT amountReceived;
+ UINT videoLength;
+
+ ULONG iframesep;
+
+ struct timeval loopTime;
+ struct timeval loopTimeN;
+ ULONG realLoopTime;
+ ULONG sleepTime = 0;
+ UINT offset;
+
+ if (state == S_FFWD) direction = 1; // and 0 for backward
+
+ gettimeofday(&loopTime, NULL);
+
+ while(1)
+ {
+ 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(&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;
+
+ 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);
}
// scan has hit one end
}