]> git.vomp.tv Git - vompclient-marten.git/commitdiff
Live TV updates
authorChris Tallon <chris@vomp.tv>
Tue, 4 Dec 2007 22:24:18 +0000 (22:24 +0000)
committerChris Tallon <chris@vomp.tv>
Tue, 4 Dec 2007 22:24:18 +0000 (22:24 +0000)
boxx.cc
boxx.h
command.cc
playerlivetv.cc
playerlivetv.h
vchannellist.cc
vchannelselect.cc
vepg.cc
vepg.h
vvideolive.cc
vvideolivetv.cc

diff --git a/boxx.cc b/boxx.cc
index 3b2596e13f359fc460c0dd87a73d6a5fb7039981..17e6dd1e9979c0eb5c6ee3f274b51f11a025eee4 100644 (file)
--- a/boxx.cc
+++ b/boxx.cc
@@ -208,6 +208,17 @@ Region* Boxx::getRegion()
   return &area;
 }
 
+void Boxx::getRootBoxRegion(Region* r)
+{
+  // Returns a region that describes the position of this box on the box with the surface
+  // To be used for boxstack->update calls
+
+  r->x = getRootBoxOffsetX();
+  r->y = getRootBoxOffsetY();
+  r->w = area.w;
+  r->h = area.h;  
+}
+
 // Level 1 drawing functions
 
 void Boxx::fillColour(Colour& colour)
diff --git a/boxx.h b/boxx.h
index 2c741f79836ddd3abec0789ba370daa9d4fc82ae..929e654a7a2789fbf75de7a5af1d471dda75bac5 100644 (file)
--- a/boxx.h
+++ b/boxx.h
@@ -76,7 +76,7 @@ class Boxx
     UINT getHeight();
     bool getVisible();
     Region* getRegion();     // Not to be used for changing the region
-        
+    void getRootBoxRegion(Region*);
     
     // Drawing functions level 1
     void fillColour(Colour& colour);
index 8edb347a7626a7493370d22dc6886b95196c2fa3..e126a9fb32ee6580f00b13be140ff96aa7e1292f 100644 (file)
@@ -892,8 +892,8 @@ void Command::doJustConnected(VConnect* vconnect)
 //    handleCommand(Remote::DOWN);
 //    handleCommand(Remote::DOWN);
 //    handleCommand(Remote::DOWN);
-    handleCommand(Remote::OK);
-    handleCommand(Remote::OK);
+//    handleCommand(Remote::OK);
+//    handleCommand(Remote::OK);
 //    handleCommand(Remote::RED);
   }
 }
index f6dad3cb470a1715b40541fd62437b532574e43b..6616cf7b94d38b82cfc49ca78c9a70556a0e32ac 100644 (file)
@@ -48,7 +48,7 @@ PlayerLiveTV::PlayerLiveTV(MessageQueue* tmessageQueue, void* tmessageReceiver,
   videoStartup = false;
 
   stopNow = false;
-  state = 1;
+  state = S_STOP;
 
   video->turnVideoOn();
 }
@@ -123,7 +123,7 @@ void PlayerLiveTV::setAudioChannel(int newChannel)
 void PlayerLiveTV::go(ULONG index)
 {
   struct PLTVInstruction i;
-  i.instruction = 1;
+  i.instruction = I_SETCHANNEL;
   i.channelIndex = index;
   instructions.push(i);
   threadStart();
@@ -133,7 +133,7 @@ void PlayerLiveTV::setChannel(ULONG index)
 {
   logger->log("PlayerLiveTV", Log::DEBUG, "setChannel");
   struct PLTVInstruction i;
-  i.instruction = 1;
+  i.instruction = I_SETCHANNEL;
   i.channelIndex = index;
   instructions.push(i);  
   threadSignalNoLock();
@@ -143,7 +143,7 @@ void PlayerLiveTV::stop()
 {
   logger->log("PlayerLiveTV", Log::DEBUG, "stop");
   struct PLTVInstruction i;
-  i.instruction = 2;
+  i.instruction = I_STOP;
   instructions.push(i);
   threadSignal();
   threadStop();
@@ -478,6 +478,27 @@ void PlayerLiveTV::switchState(UCHAR newState)
   }  
 }
 
+void PlayerLiveTV::optimizeInstructionQueue()
+{
+  // Walk the list
+  
+  // Currently there are only 2 instruction types, so this is a bit overkill...
+
+  struct PLTVInstruction i;
+  while(instructions.size() > 1)
+  {
+    i = instructions.front();
+    if (i.instruction == I_SETCHANNEL)
+    {
+      instructions.pop();  // if this is the first of more than 1 command, currently it cannot possibly be relevant
+    }
+    else if (i.instruction == I_STOP)
+    {
+      return; // return here and ensure the next instruction will be stop
+    }
+  }
+}
+
 void PlayerLiveTV::threadMethod()
 {
   while(1)
@@ -486,18 +507,17 @@ void PlayerLiveTV::threadMethod()
     {
       switchState(S_PREBUFFERING);
       videoStartup = false;
-      videoStartup2Counter = 0;
+      preBufferCount = 0;
     }  
   
     while(!instructions.empty())
     {
+      if (instructions.size() > 1) optimizeInstructionQueue();
+
       struct PLTVInstruction i = instructions.front();
       instructions.pop();
     
-      logger->log("PlayerLiveTV", Log::DEBUG, "%u %lu", i.instruction, i.channelIndex);
-      
-
-      if (i.instruction == 1)
+      if (i.instruction == I_SETCHANNEL)
       {
         logger->log("PlayerLiveTV", Log::DEBUG, "start new stream");
 
@@ -511,7 +531,7 @@ void PlayerLiveTV::threadMethod()
         vdr->streamChannel(chan->number, this);
         
       }
-      else if (i.instruction == 2)
+      else if (i.instruction == I_STOP)
       {
         logger->log("PlayerLiveTV", Log::DEBUG, "Stopping");
         switchState(S_STOP);
@@ -529,7 +549,7 @@ void PlayerLiveTV::threadMethod()
 
       if (state == S_PREBUFFERING)
       {        
-        if (++videoStartup2Counter == 3)
+        if (++preBufferCount == preBufferAmount)
         {
           switchState(S_PLAY);
         }
@@ -538,7 +558,6 @@ void PlayerLiveTV::threadMethod()
     
     threadLock();
     threadWaitForSignal(); // unlocks and waits for signal
-    
     threadUnlock();
   }
 
index 3ee74d8bae13e858a216da7c8d4cb054faac09d3..3f20030bfe89a7352c0c906898ae7f0b93cffddd 100644 (file)
@@ -18,8 +18,8 @@
     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */
 
-#ifndef PLAYER_H
-#define PLAYER_H
+#ifndef PLAYERLIVETV_H
+#define PLAYERLIVETV_H
 
 #include <stdio.h>
 #include <stdlib.h>
@@ -50,7 +50,7 @@ class DemuxerTS;
 
 struct PLTVInstruction
 {
-  UCHAR instruction;   // 1 = setChannel, 2 = stop
+  UCHAR instruction;
   ULONG channelIndex;
 };
 
@@ -97,7 +97,6 @@ class PlayerLiveTV : public Thread_TYPE, public Callback, public StreamReceiver
     void threadPostStopCleanup() {};
 
   private:
-
     MessageQueue* messageQueue;
     void* messageReceiver;
     Log* logger;
@@ -110,6 +109,9 @@ class PlayerLiveTV : public Thread_TYPE, public Callback, public StreamReceiver
     ChannelList* chanList;
 
     queue<PLTVInstruction> instructions;
+    const static UCHAR I_SETCHANNEL = 1;
+    const static UCHAR I_STOP = 2;
+    
     queue<StreamChunk> streamChunks;
     
     bool initted;
@@ -123,13 +125,12 @@ class PlayerLiveTV : public Thread_TYPE, public Callback, public StreamReceiver
 
     bool videoStartup;
     bool stopNow;
+    int preBufferCount;
+    const static int preBufferAmount = 3;
 
-    int videoStartup2Counter;
-
-        
     void clearStreamChunks();
     void chunkToDemuxer();
-
+    void optimizeInstructionQueue();
 };
 
 #endif
index f9191b7a382486a9f1868b16e77b1757333c652a..054f7ea58e752b7fd78f55a0fc98d035a9dbebfd 100644 (file)
@@ -286,23 +286,21 @@ void VChannelList::processMessage(Message* m)
     }
     if (!chan) return;
 
-/*
     if (chan->type == VDR::VIDEO)
     {
-      VVideoLiveTV* v = new VVideoLiveTV(chanList, this);
-      v->draw();
+      VVideoLiveTV* v = new VVideoLiveTV(chanList, chan->number, this);
       boxstack->add(v);
-      boxstack->update(v);
-      v->channelChange(VVideoLive::NUMBER, chan->number);
+      v->go();    
     }
     else
     {
+    /*
       VVideoLive* v = new VVideoLive(chanList, chan->type, this);
       v->draw();
       boxstack->add(v);
       boxstack->update(v);
       v->channelChange(VVideoLive::NUMBER, chan->number);
+    */
     }
-*/
   }
 }
index 8264ccb0bd4925f61966aa0ca70a92e0a0d1daf0..a7e1e08a297234e0f16318e2fe76477d338bbc9a 100644 (file)
@@ -155,6 +155,11 @@ int VChannelSelect::handleCommand(int command)
       else Timers::getInstance()->setTimerD(this, 1, 3);
       return 2;
     }
+    case Remote::OK:
+    {
+      changeChannel(true);
+      return 2;
+    }
   }
 
   // allow command to drop through to other views
diff --git a/vepg.cc b/vepg.cc
index a12cf853b31b65156c8b15740ba2956fd66a6a24..b1aaa5056a41d7c9bd81adf5368bc1fda63ed4c2 100644 (file)
--- a/vepg.cc
+++ b/vepg.cc
 
 VEpg* VEpg::instance = NULL;
 
-VEpg::VEpg(VVideoLive* v, UINT currentChannel, ULONG streamType)
+VEpg::VEpg(void* tparent, UINT tcurrentChannelIndex, ULONG streamType)
 {
   instance = this;
+  currentChannelIndex = tcurrentChannelIndex;
 
   // PAL / NTSC sizes -----------------------
 
@@ -68,7 +69,7 @@ VEpg::VEpg(VVideoLive* v, UINT currentChannel, ULONG streamType)
     xpos = 60;
     ypos = 16;
     summaryLines = 8;
-    summaryLowerPadding = 16;
+    summaryLowerPadding = 18;
     chanNameYpos = 244;
     gridRows = 7;
   }
@@ -79,14 +80,14 @@ VEpg::VEpg(VVideoLive* v, UINT currentChannel, ULONG streamType)
     xpos = 50;
     ypos = 10;
     summaryLines = 6;
-    summaryLowerPadding = 26;
+    summaryLowerPadding = 28;
     chanNameYpos = 206;
     gridRows = 5;
   }
 
   // initialise variables and pointers
   boxstack = BoxStack::getInstance();
-  videoLive = v;
+  parent = tparent;
   eventList = NULL;
   chanList = VDR::getInstance()->getChannelsList(streamType); //TODO want to be able to display video and radio together
   e = 0;
@@ -118,7 +119,7 @@ VEpg::VEpg(VVideoLive* v, UINT currentChannel, ULONG streamType)
 
 //  progInfo.setSurface(surface);
   progInfo.setBackgroundColour(Colour::VIEWBACKGROUND);
-  progInfo.setPosition(0, progTitle.getY() + progTitle.getHeight());
+  progInfo.setPosition(0, progTitle.getY2());
   progInfo.setSize(300,((Surface::getFontHeight() + 4) * summaryLines) + summaryLowerPadding);
   progInfo.setGap(4);
   add(&progInfo);
@@ -132,7 +133,7 @@ VEpg::VEpg(VVideoLive* v, UINT currentChannel, ULONG streamType)
 
   // create area to display list of channels
 //  chanListbox.setSurface(surface); // add channel list
-  chanListbox.setPosition(0, progInfo.getY() + progInfo.getHeight() + Surface::getFontHeight() + 8); // position channel list
+  chanListbox.setPosition(0, progInfo.getY2() + Surface::getFontHeight() + 8); // position channel list
   chanListbox.setSize(150, ((Surface::getFontHeight() + 2) * gridRows) + 5); //listbox line seperation is 2 pixels
   chanListbox.setGap(2);
   add(&chanListbox);
@@ -145,7 +146,7 @@ VEpg::VEpg(VVideoLive* v, UINT currentChannel, ULONG streamType)
     for (UINT i = 0; i < chanList->size(); i++)
     {
       chan = (*chanList)[i];
-      if (i == currentChannel)
+      if (i == currentChannelIndex)
         first = 1;
       chan->index = chanListbox.addOption(chan->name, 0, first);
       first = 0;
@@ -428,7 +429,20 @@ int VEpg::handleCommand(int command)
       if (!chanList) return 2;
 
       // select programme and display menu TODO currently just changes to selected channel
-      if (videoLive) videoLive->channelChange(VVideoLive::NUMBER, (*chanList)[chanListbox.getCurrentOption()]->number);
+
+      currentChannelIndex = chanListbox.getCurrentOption();
+
+      if (parent)
+      {
+        Message* m = new Message(); // Must be done after this view deleted
+        m->from = this;
+        m->to = parent;
+        m->message = Message::CHANNEL_CHANGE;
+        m->parameter = (*chanList)[currentChannelIndex]->number;
+        Command::getInstance()->postMessageNoLock(m);
+      }
+      
+      setCurrentChannel();
 
       if(command == Remote::GO)
         return 2;
@@ -438,11 +452,11 @@ int VEpg::handleCommand(int command)
     case Remote::GUIDE:
     {
       // return to normal TV mode
-      if (videoLive) // ptr check done in case being tested from videorec
+      if (parent) // ptr check done in case being tested from videorec
       {
         Message* m = new Message(); // Must be done after this view deleted
         m->from = this;
-        m->to = videoLive;
+        m->to = parent;
         m->message = Message::EPG_CLOSE;
         Command::getInstance()->postMessageNoLock(m);
       }
@@ -450,12 +464,44 @@ int VEpg::handleCommand(int command)
     }
     case Remote::CHANNELUP:
     {
-      if (videoLive) videoLive->channelChange(VVideoLive::OFFSET, VVideoLive::UP);
+      if (currentChannelIndex == (chanList->size() - 1)) // at the end
+        currentChannelIndex = 0;
+      else
+        ++currentChannelIndex;
+      
+      if (parent)
+      {
+        Message* m = new Message(); // Must be done after this view deleted
+        m->from = this;
+        m->to = parent;
+        m->message = Message::CHANNEL_CHANGE;
+        m->parameter = (*chanList)[currentChannelIndex]->number;
+        Command::getInstance()->postMessageNoLock(m);
+      }
+      
+      setCurrentChannel();
+
       return 2;
     }
     case Remote::CHANNELDOWN:
     {
-      if (videoLive) videoLive->channelChange(VVideoLive::OFFSET, VVideoLive::DOWN);
+      if (currentChannelIndex == 0) // at the start
+        currentChannelIndex = chanList->size() - 1; // so go to end
+      else
+        --currentChannelIndex;
+
+      if (parent)
+      {
+        Message* m = new Message(); // Must be done after this view deleted
+        m->from = this;
+        m->to = parent;
+        m->message = Message::CHANNEL_CHANGE;
+        m->parameter = (*chanList)[currentChannelIndex]->number;
+        Command::getInstance()->postMessageNoLock(m);
+      }
+      
+      setCurrentChannel();
+
       return 2;
     }
   }
@@ -627,11 +673,13 @@ void VEpg::updateEventList()
   }
 }
 
-void VEpg::setCurrentChannel(char* chname)
+void VEpg::setCurrentChannel()
 {
-  chanName.setText(chname);
+  chanName.setText((*chanList)[currentChannelIndex]->name);
   chanName.draw();
-  boxstack->update(this);
+  Region r;
+  chanName.getRootBoxRegion(&r);
+  boxstack->update(this, &r);
 }
 
 void VEpg::paintCell(Event* event, int yOffset, Colour bg, Colour fg)
@@ -775,3 +823,4 @@ void VEpg::processMessage(Message* m)
     }
   }
 }
+
diff --git a/vepg.h b/vepg.h
index c633b4907b116ea4cc449ff1c2490967fd225b0b..a03eed1e55efa3cbe574d8f7db663691afd54c7f 100644 (file)
--- a/vepg.h
+++ b/vepg.h
@@ -44,13 +44,12 @@ class VVideoLive;
 class VEpg : public Boxx, public TimerReceiver
 {
   public:
-    VEpg(VVideoLive* v, UINT currentChannel, ULONG streamType);
+    VEpg(void* parent, UINT currentChannel, ULONG streamType);
     ~VEpg();
     static VEpg* getInstance();
 
     int handleCommand(int command); // deal with commands (from remote control)
     void draw(); // draw epg view
-    void setCurrentChannel(char* chname);
     void processMessage(Message* m);
     void timercall(int clientReference);
 
@@ -60,6 +59,7 @@ class VEpg : public Boxx, public TimerReceiver
     void setInfo(Event* event); // display details of selected programme
     void drawgrid(); // redraws grid and select programme
     void drawData();
+    void setCurrentChannel();
 
     WSelectList chanListbox; // listbox to display available channels
     WTextbox progTitle; // area to display time and title of selected programme
@@ -81,9 +81,10 @@ class VEpg : public Boxx, public TimerReceiver
     void updateEventList();
     void paintCell(Event* event, int yOffset, Colour bg, Colour fg);
     time_t prevHour(time_t* t);
-    VVideoLive* videoLive;
+    void* parent;
     BoxStack* boxstack;
     UINT gridRows;
+    UINT currentChannelIndex;
 };
 
 #endif
index 90945beb293a0067a2150a71dba5540b38e5f474..18d580c0544db660c1047a9e35a0990c8ae46b39 100644 (file)
@@ -268,8 +268,8 @@ void VVideoLive::channelChange(UCHAR changeType, UINT newData)
   if (unavailable) showUnavailable(0);
   else stop(1);
 
-  VEpg* vepg = VEpg::getInstance();
-  if(vepg) vepg->setCurrentChannel((*chanList)[currentChannel]->name);
+//  VEpg* vepg = VEpg::getInstance();
+//  if(vepg) vepg->setCurrentChannel((*chanList)[currentChannel]->name);
 
   VLiveBanner* vlb = VLiveBanner::getInstance();
   if (vlb)
index 2840c0d1db3c6e249a123184491c9226e402bb43..897cca479137a6f9ae7f49f442ed180aedcbb873 100644 (file)
@@ -98,7 +98,7 @@ VVideoLiveTV::VVideoLiveTV(ChannelList* tchanList, ULONG initialChannelNumber, V
     wssRegion.h = 2;
   }
   
-  Colour osdBack = Colour(50, 50, 50);
+  Colour osdBack = Colour(0, 0, 0, 128);
   
   osd.setBackgroundColour(osdBack);
   osd.setPosition(0, video->getScreenHeight() - 150);
@@ -106,17 +106,17 @@ VVideoLiveTV::VVideoLiveTV(ChannelList* tchanList, ULONG initialChannelNumber, V
   osd.setVisible(false);
   add(&osd);
   
-  clock.setBackgroundColour(Colour::BLACK);
+  clock.setBackgroundColour(osdBack);
   clock.setPosition(osd.getWidth() - 100, 4);
   clock.setSize(90, 30);
   osd.add(&clock);
 
-  osdChanNum.setBackgroundColour(Colour::BLACK);
+  osdChanNum.setBackgroundColour(osdBack);
   osdChanNum.setPosition(40, 4);
   osdChanNum.setSize((numberWidth*10) + 22, 30); // 10 px = width of number chars in font
   osd.add(&osdChanNum);  
 
-  osdChanName.setBackgroundColour(Colour::BLACK);
+  osdChanName.setBackgroundColour(osdBack);
   osdChanName.setPosition(osdChanNum.getX2() + 10, 4);
   osdChanName.setSize(300, 30);
   osd.add(&osdChanName);
@@ -141,30 +141,31 @@ VVideoLiveTV::VVideoLiveTV(ChannelList* tchanList, ULONG initialChannelNumber, V
   boxBlue.setSize(18, 16);
   osd.add(&boxBlue);  
   
-  textRed.setBackgroundColour(Colour::BLACK);
+  textRed.setBackgroundColour(osdBack);
   textRed.setPosition(boxRed.getX()+18, 98);
   textRed.setSize(120, 30);
   textRed.setText("Summary");
   osd.add(&textRed);  
     
-  textGreen.setBackgroundColour(Colour::BLACK);
+  textGreen.setBackgroundColour(osdBack);
   textGreen.setPosition(boxGreen.getX()+18, 98);
   textGreen.setSize(120, 30);
   textGreen.setText("Audio");
   osd.add(&textGreen);  
     
-  textYellow.setBackgroundColour(Colour::BLACK);
+  textYellow.setBackgroundColour(osdBack);
   textYellow.setPosition(boxYellow.getX()+18, 98);
   textYellow.setSize(120, 30);
   textYellow.setText("");
   osd.add(&textYellow);  
     
-  textBlue.setBackgroundColour(Colour::BLACK);
+  textBlue.setBackgroundColour(osdBack);
   textBlue.setPosition(boxBlue.getX()+18, 98);
   textBlue.setSize(90, 30);
   textBlue.setText("EPG");
   osd.add(&textBlue);  
     
+  sl.setBackgroundColour(osdBack);
   sl.setPosition(70, 36);
   sl.setSize(500, 58);
   sl.setNoLoop();
@@ -311,7 +312,7 @@ void VVideoLiveTV::go()
   setClock();
   displayOSD();
   
-  player->go(0);
+  player->go(currentChannelIndex);
 }
 
 void VVideoLiveTV::stop()
@@ -566,7 +567,7 @@ void VVideoLiveTV::doEPG()
   video->setMode(Video::QUARTER);
   video->setPosition(170, 5); //TODO need to deal with 4:3 switching
 
-  VEpg* vepg = new VEpg(NULL, currentChannelIndex, VDR::VIDEO);
+  VEpg* vepg = new VEpg(this, currentChannelIndex, VDR::VIDEO);
   vepg->draw();
   boxstack->add(vepg);
   boxstack->update(vepg);
@@ -663,8 +664,9 @@ bool VVideoLiveTV::channelChange(UCHAR changeType, UINT newData)
   currentChannelIndex = newChannel;
   
   Log::getInstance()->log("VVideoLiveTV", Log::DEBUG, "Set player to channel %u", currentChannelIndex);
-
   player->setChannel(currentChannelIndex);
+  Log::getInstance()->log("VVideoLiveTV", Log::DEBUG, "Done Set player to channel %u", currentChannelIndex);
+
   return true;
 }
 
@@ -678,7 +680,6 @@ void VVideoLiveTV::processMessage(Message* m)
   {
     channelChange(NUMBER, m->parameter);
     osdChannelIndex = currentChannelIndex;
-    displayOSD();
   }
   else if (m->message == Message::EPG_CLOSE)
   {