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)
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);
// handleCommand(Remote::DOWN);
// handleCommand(Remote::DOWN);
// handleCommand(Remote::DOWN);
- handleCommand(Remote::OK);
- handleCommand(Remote::OK);
+// handleCommand(Remote::OK);
+// handleCommand(Remote::OK);
// handleCommand(Remote::RED);
}
}
videoStartup = false;
stopNow = false;
- state = 1;
+ state = S_STOP;
video->turnVideoOn();
}
void PlayerLiveTV::go(ULONG index)
{
struct PLTVInstruction i;
- i.instruction = 1;
+ i.instruction = I_SETCHANNEL;
i.channelIndex = index;
instructions.push(i);
threadStart();
{
logger->log("PlayerLiveTV", Log::DEBUG, "setChannel");
struct PLTVInstruction i;
- i.instruction = 1;
+ i.instruction = I_SETCHANNEL;
i.channelIndex = index;
instructions.push(i);
threadSignalNoLock();
{
logger->log("PlayerLiveTV", Log::DEBUG, "stop");
struct PLTVInstruction i;
- i.instruction = 2;
+ i.instruction = I_STOP;
instructions.push(i);
threadSignal();
threadStop();
}
}
+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)
{
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");
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);
if (state == S_PREBUFFERING)
{
- if (++videoStartup2Counter == 3)
+ if (++preBufferCount == preBufferAmount)
{
switchState(S_PLAY);
}
threadLock();
threadWaitForSignal(); // unlocks and waits for signal
-
threadUnlock();
}
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>
struct PLTVInstruction
{
- UCHAR instruction; // 1 = setChannel, 2 = stop
+ UCHAR instruction;
ULONG channelIndex;
};
void threadPostStopCleanup() {};
private:
-
MessageQueue* messageQueue;
void* messageReceiver;
Log* logger;
ChannelList* chanList;
queue<PLTVInstruction> instructions;
+ const static UCHAR I_SETCHANNEL = 1;
+ const static UCHAR I_STOP = 2;
+
queue<StreamChunk> streamChunks;
bool initted;
bool videoStartup;
bool stopNow;
+ int preBufferCount;
+ const static int preBufferAmount = 3;
- int videoStartup2Counter;
-
-
void clearStreamChunks();
void chunkToDemuxer();
-
+ void optimizeInstructionQueue();
};
#endif
}
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);
+ */
}
-*/
}
}
else Timers::getInstance()->setTimerD(this, 1, 3);
return 2;
}
+ case Remote::OK:
+ {
+ changeChannel(true);
+ return 2;
+ }
}
// allow command to drop through to other views
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 -----------------------
xpos = 60;
ypos = 16;
summaryLines = 8;
- summaryLowerPadding = 16;
+ summaryLowerPadding = 18;
chanNameYpos = 244;
gridRows = 7;
}
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;
// 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);
// 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);
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;
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;
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);
}
}
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;
}
}
}
}
-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)
}
}
}
+
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);
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
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
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)
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);
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);
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();
setClock();
displayOSD();
- player->go(0);
+ player->go(currentChannelIndex);
}
void VVideoLiveTV::stop()
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);
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;
}
{
channelChange(NUMBER, m->parameter);
osdChannelIndex = currentChannelIndex;
- displayOSD();
}
else if (m->message == Message::EPG_CLOSE)
{