]> git.vomp.tv Git - vompclient.git/commitdiff
Add proper time calculations to iframe scan
authorChris Tallon <chris@vomp.tv>
Sat, 23 Sep 2006 22:14:50 +0000 (22:14 +0000)
committerChris Tallon <chris@vomp.tv>
Sat, 23 Sep 2006 22:14:50 +0000 (22:14 +0000)
player.cc
player.h
vdr.cc

index 374d52fa418a2d67c7fcaac98b04dd63ae9360a6..ca9657f8b72cc7a02bb2c28471b09d3d1606d1f1 100644 (file)
--- 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
 }
index 9203926956af3b892148e5c71f624bd31fbfba03..7253cf6123de26621095e0fd012a956a82ef8215 100644 (file)
--- a/player.h
+++ b/player.h
@@ -22,6 +22,9 @@
 #define PLAYER_H
 
 #include <stdio.h>
+#include <stdlib.h>
+#include <sys/time.h>
+#include <time.h>
 
 #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 26860d43210ee6fefa23e29fcf4b950006e63654..015879762614caeed409f32a822078e942604862 100644 (file)
--- 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;
 }