From 10c6c7bf12eb3ab5b765ee588fd985c3b0280517 Mon Sep 17 00:00:00 2001
From: Chris Tallon <chris@vomp.tv>
Date: Sat, 25 Nov 2006 00:54:06 +0000
Subject: [PATCH] Radio navigation

---
 demuxer.cc     |  2 +-
 demuxer.h      |  4 +--
 player.cc      |  5 +++-
 playerradio.cc | 78 +++++++++++++++++++++++++++++++-------------------
 4 files changed, 54 insertions(+), 35 deletions(-)

diff --git a/demuxer.cc b/demuxer.cc
index aea868c..293536f 100644
--- a/demuxer.cc
+++ b/demuxer.cc
@@ -64,7 +64,7 @@ Demuxer* Demuxer::getInstance()
   return instance;
 }
 
-int Demuxer::init(Callback* tcallback, DrainTarget* audio, DrainTarget* video)
+int Demuxer::init(Callback* tcallback, DrainTarget* audio, DrainTarget* video, ULONG demuxMemoryV, ULONG demuxMemoryA)
 {
   if (!initted)
   {
diff --git a/demuxer.h b/demuxer.h
index ffbbf77..7471624 100644
--- a/demuxer.h
+++ b/demuxer.h
@@ -69,7 +69,7 @@ protected:
     Demuxer();
     virtual ~Demuxer();
     static Demuxer* getInstance();
-    int init(Callback* callback, DrainTarget* audio, DrainTarget* video);
+    int init(Callback* callback, DrainTarget* audio, DrainTarget* video, ULONG demuxMemoryV, ULONG demuxMemoryA);
     virtual void reset();
     virtual void flush();
     void flushAudio();
@@ -136,8 +136,6 @@ protected:
     ULLONG audio_pts;
 
     // Constants
-    static const int demuxMemoryV = 2097152;
-    static const int demuxMemoryA = 524288;
     static const int FrameRates[9];
 
     enum PESTYPE
diff --git a/player.cc b/player.cc
index 7f4f593..76cda34 100644
--- a/player.cc
+++ b/player.cc
@@ -78,7 +78,7 @@ int Player::init()
   demuxer = new DemuxerVDR();
   if (!demuxer) return 0;
 
-  if (!demuxer->init(this, audio, video))
+  if (!demuxer->init(this, audio, video, 2097152, 524288))
   {
     logger->log("Player", Log::ERR, "Demuxer failed to init");
     shutdown();
@@ -1089,6 +1089,9 @@ void Player::threadFeedScan()
       if (!vdr->getNextIFrame(baseFrameNumber, direction, &filePos, &iframeNumber, &iframeLength))
         return;
 
+      if (iframeNumber >= lengthFrames) return;
+        // scan has got to the end of what we knew to be there before we started scanning
+
       baseFrameNumber = iframeNumber;
       frameTimeOffset = abs(iframeNumber - currentFrameNumber) * 1000 / (video->getFPS() * ifactor);
 #ifndef WIN32
diff --git a/playerradio.cc b/playerradio.cc
index 690c3bf..f3e4b83 100644
--- a/playerradio.cc
+++ b/playerradio.cc
@@ -32,7 +32,7 @@ PlayerRadio::PlayerRadio(MessageQueue* tmessageQueue, void* tmessageReceiver, bo
   vdr = VDR::getInstance();
   initted = false;
   lengthBytes = 0;
-  lengthFrames = 0;
+  lengthPackets = 0;
   streamPos = 0;
   state = S_STOP;
 
@@ -53,7 +53,7 @@ PlayerRadio::~PlayerRadio()
   if (initted) shutdown();
 }
 
-int PlayerRadio::init(ULLONG tlengthBytes, ULONG tlengthFrames)
+int PlayerRadio::init(ULLONG tlengthBytes, ULONG tlengthPackets)
 {
   if (initted) return 0;
 #ifndef WIN32
@@ -65,7 +65,7 @@ int PlayerRadio::init(ULLONG tlengthBytes, ULONG tlengthFrames)
   demuxer = new DemuxerVDR();
   if (!demuxer) return 0;
 
-  if (!demuxer->init(this, audio, NULL))
+  if (!demuxer->init(this, audio, NULL, 10, 40000))
   {
     logger->log("PlayerRadio", Log::ERR, "Demuxer failed to init");
     shutdown();
@@ -76,7 +76,7 @@ int PlayerRadio::init(ULLONG tlengthBytes, ULONG tlengthFrames)
   audio->stop();
 
   lengthBytes = tlengthBytes;
-  lengthFrames = tlengthFrames;
+  lengthPackets = tlengthPackets;
 
   logger->log("PlayerRadio", Log::DEBUG, "PlayerRadio has received length bytes of %llu", lengthBytes);
 
@@ -161,7 +161,12 @@ ULONG PlayerRadio::getLengthSeconds()
 ULONG PlayerRadio::getCurrentSeconds()
 {
   if (startup) return 0;
-  return 0;
+
+  long long currentPTS = demuxer->getAudioPTS();
+  currentPTS -= startPTS;
+  if (currentPTS < 0) currentPTS += 8589934592ULL;
+  ULONG ret = currentPTS / 90000;
+  return ret;
 }
 
 // ----------------------------------- Externally called events
@@ -206,8 +211,8 @@ void PlayerRadio::jumpToPercent(int percent)
 {
   lock();
   logger->log("PlayerRadio", Log::DEBUG, "JUMP TO %i%%", percent);
-  ULONG newFrame = percent * lengthFrames / 100;
-  switchState(S_JUMP, newFrame);
+  ULONG newPacket = percent * lengthPackets / 100;
+  switchState(S_JUMP, newPacket);
   unLock();
 }
 
@@ -215,29 +220,42 @@ void PlayerRadio::skipForward(int seconds)
 {
   lock();
   logger->log("PlayerRadio", Log::DEBUG, "SKIP FORWARD %i SECONDS", seconds);
-  ULONG newFrame = getCurrentSeconds();
-  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);
+  ULONG currentSeconds = getCurrentSeconds();
+  ULONG currentPacket = demuxer->getPacketNum();
+
+  if (currentSeconds == 0) { unLock(); return; } // div by zero
+  if (currentPacket == 0) { unLock(); return; } // Current pos from demuxer is not valid
+
+  ULONG newPacket = demuxer->getPacketNum() / currentSeconds * (currentSeconds + seconds);
+  if (newPacket > lengthPackets) { switchState(S_PLAY); unLock(); }
+  else switchState(S_JUMP, newPacket);
   unLock();
 }
 
-void PlayerRadio::skipBackward(int seconds)
+void PlayerRadio::skipBackward(int seconds) // FIXME why are these signed?!
 {
   lock();
   logger->log("PlayerRadio", Log::DEBUG, "SKIP BACKWARD %i SECONDS", seconds);
-  long newFrame = getCurrentSeconds();
-  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);
+
+  ULONG currentSeconds = getCurrentSeconds();
+  ULONG currentPacket = demuxer->getPacketNum();
+
+  if (currentSeconds == 0) { unLock(); return; } // div by zero
+  if (currentPacket == 0) { unLock(); return; } // Current pos from demuxer is not valid
+
+  ULONG newPacket;
+  if ((UINT)seconds > currentSeconds)
+    newPacket = 0;
+  else
+    newPacket = demuxer->getPacketNum() / currentSeconds * (currentSeconds - seconds);
+
+  switchState(S_JUMP, newPacket);
   unLock();
 }
 
 // ----------------------------------- Implementations called events
 
-void PlayerRadio::switchState(UCHAR toState, ULONG jumpFrame)
+void PlayerRadio::switchState(UCHAR toState, ULONG jumpPacket)
 {
   if (!initted) return;
 
@@ -271,7 +289,7 @@ void PlayerRadio::switchState(UCHAR toState, ULONG jumpFrame)
         }
         case S_JUMP: // to S_JUMP
         {
-          restartAtFrame(jumpFrame);
+          restartAtPacket(jumpPacket);
           return;
         }
       }
@@ -305,7 +323,7 @@ void PlayerRadio::switchState(UCHAR toState, ULONG jumpFrame)
         {
           state = S_PLAY;
           audio->unPause();
-          restartAtFrame(jumpFrame);
+          restartAtPacket(jumpPacket);
           return;
         }
       }
@@ -323,9 +341,9 @@ void PlayerRadio::switchState(UCHAR toState, ULONG jumpFrame)
           demuxer->reset();
           if (isRecording)
           {
-            // FIXME use restartAtFrame here?
-            if (currentFrameNumber > lengthFrames) currentFrameNumber = 0;
-            demuxer->setFrameNum(currentFrameNumber);
+            // FIXME use restartAtPacket here?
+            if (currentPacketNumber > lengthPackets) currentPacketNumber = 0;
+            demuxer->setPacketNum(currentPacketNumber);
           }
 
           state = S_PLAY;
@@ -385,14 +403,14 @@ void PlayerRadio::unLock()
 #endif
 }
 
-void PlayerRadio::restartAtFrame(ULONG newFrame)
+void PlayerRadio::restartAtPacket(ULONG newPacket)
 {
   afeed.stop();
   threadStop();
   audio->reset();
   demuxer->flush();
-  currentFrameNumber = newFrame;
-  demuxer->setFrameNum(newFrame);
+  currentPacketNumber = newPacket;
+  demuxer->setPacketNum(newPacket);
   afeed.start();
   threadStart();
   audio->play();
@@ -531,9 +549,9 @@ void PlayerRadio::threadFeedPlay()
   UINT thisRead, writeLength, thisWrite, askFor;
   time_t lastRescan = time(NULL);
 
-  feedPosition = vdr->positionFromFrameNumber(currentFrameNumber);
+  feedPosition = vdr->positionFromFrameNumber(currentPacketNumber);
   if (!vdr->isConnected()) { doConnectionLost(); return; }
-  logger->log("PlayerRadio", Log::DEBUG, "startFeedPlay: wantedframe %i goto %llu", currentFrameNumber, feedPosition);
+  logger->log("PlayerRadio", Log::DEBUG, "startFeedPlay: wantedPacket %i goto %llu", currentPacketNumber, feedPosition);
 
 
   while(1)
@@ -547,7 +565,7 @@ void PlayerRadio::threadFeedPlay()
     // If we havn't rescanned for a while..
     if ((lastRescan + 60) < time(NULL))
     {
-      lengthBytes = vdr->rescanRecording(&lengthFrames);
+      lengthBytes = vdr->rescanRecording(&lengthPackets);
       if (!vdr->isConnected()) { doConnectionLost(); return; }
       logger->log("PlayerRadio", Log::DEBUG, "Rescanned and reset length: %llu", lengthBytes);
       lastRescan = time(NULL);
-- 
2.39.5