From 96012b6465c6a0a2b527f00951371f5a5aa4a491 Mon Sep 17 00:00:00 2001 From: Chris Tallon Date: Sat, 23 Sep 2006 22:14:50 +0000 Subject: [PATCH] Add proper time calculations to iframe scan --- player.cc | 88 +++++++++++++++++++++++++++++++++++++++++++++++++++---- player.h | 7 +++-- vdr.cc | 2 +- 3 files changed, 88 insertions(+), 9 deletions(-) diff --git a/player.cc b/player.cc index 374d52f..ca9657f 100644 --- a/player.cc +++ b/player.cc @@ -222,7 +222,9 @@ void Player::skipForward(int seconds) { 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 @@ -232,9 +234,11 @@ void Player::skipBackward(int seconds) { 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 } @@ -699,7 +703,6 @@ void Player::call(void* caller) video->sync(); vfeed.release(); unLock(); - logger->log("Player", Log::DEBUG, "BANG BANG BANG BANG BANG BANG BANG BANG BANG BANG BANG"); } threadSignalNoLock(); @@ -960,6 +963,7 @@ void Player::threadFeedPlay() logger->log("Player", Log::DEBUG, "Message posted..."); } +/* void Player::threadFeedScan() { ULONG direction = 0; @@ -969,19 +973,91 @@ void Player::threadFeedScan() 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 } diff --git a/player.h b/player.h index 9203926..7253cf6 100644 --- a/player.h +++ b/player.h @@ -22,6 +22,9 @@ #define PLAYER_H #include +#include +#include +#include #include "audio.h" #include "video.h" @@ -126,6 +129,8 @@ class Player : public Thread_TYPE, public Callback UINT startupBlockSize; UCHAR* threadBuffer; UCHAR state; + + const static UINT ifactor = 5; }; #endif @@ -187,5 +192,3 @@ Jump -> Play -> FFwd -> FBwd -> Stop - -*/ diff --git a/vdr.cc b/vdr.cc index 26860d4..0158797 100644 --- a/vdr.cc +++ b/vdr.cc @@ -847,7 +847,7 @@ bool VDR::getNextIFrame(ULONG frameNumber, ULONG direction, ULLONG* rfilePositio freePacket(); MUTEX_UNLOCK(&mutex); - Log::getInstance()->log("VDR", Log::DEBUG, "VDR GNIF said %llu %lu %lu", *rfilePosition, *rframeNumber, *rframeLength); +// Log::getInstance()->log("VDR", Log::DEBUG, "VDR GNIF said %llu %lu %lu", *rfilePosition, *rframeNumber, *rframeLength); return true; } -- 2.39.5