From 08ab45c72044fc54ecd4aeaa25d3ae7765733c71 Mon Sep 17 00:00:00 2001
From: Chris Tallon <chris@vomp.tv>
Date: Mon, 6 Mar 2006 23:06:47 +0000
Subject: [PATCH] Recording OSD

---
 Makefile       |  3 ++
 command.cc     |  8 ++---
 playervideo.cc | 32 ++++++++++++++----
 playervideo.h  |  1 +
 vvideorec.cc   | 89 +++++++++++++++++++++++++++++++++++++++++---------
 vvideorec.h    |  7 ++++
 6 files changed, 114 insertions(+), 26 deletions(-)

diff --git a/Makefile b/Makefile
index f825f83..ae4b849 100644
--- a/Makefile
+++ b/Makefile
@@ -36,6 +36,9 @@ install:
 	rm -f /diskless/nfs/mvp/vompclient
 	cp vompclient /diskless/nfs/mvp
 
+debug:
+	../../gdb/gdb-6.3-target-ppc/gdb/gdb /diskless/nfs/mvp/vompclient /diskless/nfs/mvp/core.*
+
 dev: CXXFLAGS := $(CXXFLAGS_DEV)
 dev: vompclient
 
diff --git a/command.cc b/command.cc
index 7409b30..6dbe17b 100644
--- a/command.cc
+++ b/command.cc
@@ -575,9 +575,9 @@ void Command::doJustConnected(VConnect* vconnect)
   viewman->updateView(vw);
 
   // Enter pre-keys here
-//  handleCommand(Remote::THREE);
-//  handleCommand(Remote::DOWN);
-//  handleCommand(Remote::OK);
-//  handleCommand(Remote::PLAY);
+  handleCommand(Remote::THREE);
+  handleCommand(Remote::DOWN);
+  handleCommand(Remote::OK);
+  handleCommand(Remote::PLAY);
 
 }
diff --git a/playervideo.cc b/playervideo.cc
index 3a27a71..cd805e3 100644
--- a/playervideo.cc
+++ b/playervideo.cc
@@ -1,4 +1,4 @@
-#/*
+/*
     Copyright 2004-2005 Chris Tallon
 
     This file is part of VOMP.
@@ -36,6 +36,7 @@ PlayerVideo::PlayerVideo(MessageQueue* messageQueue, UCHAR tIsRecording, UCHAR i
   lastRescan = 0;
   startTS = 0;
   endTS = 0;
+  startup = 1;
   threadBuffer = NULL;
 
   if (isRadio)
@@ -75,7 +76,6 @@ int PlayerVideo::init()
   video->blank();
   audio->stop();
 
-  startup = 0;
   initted = 1;
   return 1;
 }
@@ -181,7 +181,6 @@ int PlayerVideo::play()
   audio->reset();
   video->reset();
   demuxer.reset();
-  startup = 1;
 
 // ------------------------ This one works, but doesn't allow any pre-buffering.
   threadStart();
@@ -501,15 +500,16 @@ void PlayerVideo::jumpToPercent(int percent)
 
 ULLONG PlayerVideo::getPositionTS()
 {
+  if (startup) return 0ULL;
   long long currentTS = video->getCurrentTimestamp() - startTS;
-  if (currentTS < 0) currentTS += 7776000000ULL;
+  if (currentTS < 0) currentTS += 8589934592ULL;
   return (ULLONG)currentTS;
 }
 
 ULLONG PlayerVideo::getEndTS()
 {
   long long rendTS = endTS - startTS;
-  if (rendTS < 0) rendTS += 7776000000ULL;
+  if (rendTS < 0) rendTS += 8589934592ULL;
   return (ULLONG)rendTS;
 }
 
@@ -612,7 +612,8 @@ void PlayerVideo::threadMethod()
       demuxer.setAudioStream(a_stream);
       Log::getInstance()->log("Player", Log::DEBUG, "Startup Audio stream chosen %x", a_stream);
 
-      demuxer.findVideoPTS(threadBuffer, thisRead, &startTS);
+      setStartTS(thisRead);
+
       if (isRecording) setEndTS();
 
       startup = 0;
@@ -682,6 +683,25 @@ void PlayerVideo::threadPostStopCleanup()
   }
 }
 
+void PlayerVideo::setStartTS(UINT dataInBuffer)
+{
+  if (isRecording && feedPosition) // (feedPosition != 0)
+  {
+    // FIXME find out how much data need to get to find a TS
+    // Need to get the actual start of the recording
+
+    UINT thisRead;
+    UCHAR* tempBuffer = VDR::getInstance()->getBlock(0, 100000, &thisRead);
+    if (!tempBuffer) return;
+    if (thisRead) demuxer.findVideoPTS(tempBuffer, thisRead, &startTS);
+    free(tempBuffer);
+  }
+  else
+  {
+    demuxer.findVideoPTS(threadBuffer, dataInBuffer, &startTS);
+  }
+}
+
 void PlayerVideo::setEndTS()
 {
   Log::getInstance()->log("Player", Log::DEBUG, "Setting end TS");
diff --git a/playervideo.h b/playervideo.h
index 19a2e9c..f94843e 100644
--- a/playervideo.h
+++ b/playervideo.h
@@ -73,6 +73,7 @@ class PlayerVideo : public Player
     void threadPostStopCleanup();
 
   private:
+    void setStartTS(UINT dataInBuffer);
     void setEndTS();
 
     MessageQueue* commandMessageQueue;
diff --git a/vvideorec.cc b/vvideorec.cc
index 5deb105..c97f984 100644
--- a/vvideorec.cc
+++ b/vvideorec.cc
@@ -26,6 +26,7 @@ VVideoRec::VVideoRec(Recording* rec)
   player->init();
   vdr = VDR::getInstance();
   video = Video::getInstance();
+  timers = Timers::getInstance();
 
   videoMode = video->getMode();
   myRec = rec;
@@ -39,7 +40,14 @@ VVideoRec::VVideoRec(Recording* rec)
   barRegion.w = video->getScreenWidth();
   barRegion.h = 66;
 
+  clocksRegion.x = barRegion.x + 180;
+  clocksRegion.y = barRegion.y + 12;
+  clocksRegion.w = 200;
+  clocksRegion.h = surface->getFontHeight();
+
   barBlue.set(0, 0, 150, 150);
+
+  barShowing = false;
 }
 
 VVideoRec::~VVideoRec()
@@ -49,7 +57,8 @@ VVideoRec::~VVideoRec()
   Log::getInstance()->log("VVideoRec", Log::DEBUG, "Post delete player");
   Video::getInstance()->setDefaultAspect();
 
-  Timers::getInstance()->cancelTimer(this, 1);
+  timers->cancelTimer(this, 1);
+  timers->cancelTimer(this, 2);
 }
 
 void VVideoRec::draw()
@@ -112,8 +121,19 @@ int VVideoRec::handleCommand(int command)
     case Remote::MENU:
     {
       Log::getInstance()->log("VVideoRec", Log::DEBUG, "Pre player stop");
+
+      // FIXME work out a better soln for this
+      // Fix a problem to do with thread sync here
+      // because the bar gets a timer every 0.2s and it seems to take up to 0.1s,
+      // (or maybe just the wrong thread being selected?) for the main loop to lock and process
+      // the video stop message it is possible for a bar message to stack up after a stop message
+      // when the bar message is finally processed the prog crashes because this is deleted by then
+      removeBar();
+      //
+
       player->stop();
       vdr->stopStreaming();
+
       Log::getInstance()->log("VVideoRec", Log::DEBUG, "Post player stop");
       return 4;
     }
@@ -231,6 +251,8 @@ void VVideoRec::toggleChopSides()
 
 void VVideoRec::doBar(int action)
 {
+  barShowing = true;
+
   rectangle(barRegion, barBlue);
 
   /* Work out what to display - choices:
@@ -271,6 +293,41 @@ void VVideoRec::doBar(int action)
 
   w.draw();
 
+  drawBarClocks();
+
+  ViewMan::getInstance()->updateView(this, &barRegion);
+  timers->setTimer(this, 1, (struct timespec){4, 0});
+  timers->setTimer(this, 2, (struct timespec){0, 200000000});
+}
+
+void VVideoRec::timercall(int clientReference)
+{
+  switch(clientReference)
+  {
+    case 1:
+    {
+      // Remove bar
+      removeBar();
+      break;
+    }
+    case 2:
+    {
+      // Update clock
+      if (!barShowing) break;
+      drawBarClocks();
+      ViewMan::getInstance()->updateView(this, &barRegion);
+      timers->setTimer(this, 2, (struct timespec){0, 200000000});
+      break;
+    }
+  }
+}
+
+void VVideoRec::drawBarClocks()
+{
+  Log::getInstance()->log("VVideoRec", Log::DEBUG, "Draw bar clocks");
+
+  rectangle(clocksRegion, barBlue);
+
   ULONG currentTS = (player->getPositionTS() / 90000);
   int chours = currentTS / 3600;
   int cminutes = (currentTS - (chours * 3600)) / 60;
@@ -282,24 +339,24 @@ void VVideoRec::doBar(int action)
   int eseconds = endTS - (ehours * 3600) - (eminutes * 60);
 
   char buffer[100];
-  snprintf(buffer, 99, "%01i:%02i:%02i / %01i:%02i:%02i", chours, cminutes, cseconds, ehours, eminutes, eseconds);
+  if ((currentTS > 95441) // it's at the 33bit rollover point where the calc doesn't work because of the 1s diff
+                          // between demuxer values and video chip return values ... ?
+      || (!endTS))        // No values yet
+  {
+    strcpy(buffer, "-:--:-- / -:--:--");
+  }
+  else
+  {
+    snprintf(buffer, 99, "%01i:%02i:%02i / %01i:%02i:%02i", chours, cminutes, cseconds, ehours, eminutes, eseconds);
+  }
 
   drawText(buffer, barRegion.x + 180, barRegion.y + 12, Colour::LIGHTTEXT);
-
-  ViewMan::getInstance()->updateView(this, &barRegion);
-  Timers::getInstance()->setTimer(this, 1, (struct timespec){4, 0});
 }
 
-void VVideoRec::timercall(int clientReference)
+void VVideoRec::removeBar()
 {
-  switch(clientReference)
-  {
-    case 1:
-    {
-      // Remove bar
-      rectangle(barRegion, transparent);
-      ViewMan::getInstance()->updateView(this, &barRegion);
-      break;
-    }
-  }
+  timers->cancelTimer(this, 2);
+  barShowing = false;
+  rectangle(barRegion, transparent);
+  ViewMan::getInstance()->updateView(this, &barRegion);
 }
diff --git a/vvideorec.h b/vvideorec.h
index 709d475..e8fbbae 100644
--- a/vvideorec.h
+++ b/vvideorec.h
@@ -35,6 +35,8 @@
 
 //#include "vepg.h" // for testing EPG in NTSC with a NTSC test video
 
+class Timers;
+
 class VVideoRec : public View, public TimerReceiver
 {
   public:
@@ -49,6 +51,7 @@ class VVideoRec : public View, public TimerReceiver
   private:
     VDR* vdr;
     Video* video;
+    Timers* timers;
     Player* player;
     Recording* myRec;
 
@@ -58,8 +61,12 @@ class VVideoRec : public View, public TimerReceiver
     UCHAR videoMode;
     void toggleChopSides();
 
+    bool barShowing;
     void doBar(int action);
+    void drawBarClocks();
+    void removeBar();
     Region barRegion;
+    Region clocksRegion;
 };
 
 #endif
-- 
2.39.5