return 1;
}
+int BoxStack::addVideoDisplay(Boxx* box,VideoDisplay vd)
+{
+ videoStack.push(pair<Boxx*,VideoDisplay>(box,vd));
+ Video::getInstance()->setVideoDisplay(vd);
+ return 1;
+}
+
int BoxStack::add(Boxx* v)
{
if (!initted) return 0;
return 0;
}
boxes[numBoxes++] = v;
+ VideoDisplay vd;
+ if (v->getVideoDisplay(vd)) {
+ Log::getInstance()->log("BoxStack", Log::DEBUG, "Add video display");
+ addVideoDisplay(v,vd);
+ }
boxLock.Unlock();
int BoxStack::remove(Boxx* toDelete)
{
if (!initted) return 0;
+ VideoDisplay *display = NULL;
boxLock.Lock();
Log::getInstance()->log("BoxStack", Log::DEBUG, "Locked for remove");
Command::getInstance()->postMessageNoLock(m);
}
+ if (!videoStack.empty() && videoStack.top().first==toDelete) {
+ videoStack.pop();
+ if (!videoStack.empty()) display=&videoStack.top().second;
+ }
boxLock.Unlock();
Log::getInstance()->log("BoxStack", Log::DEBUG, "Unlocked for remove");
// as this box is not in the stack any more, there is no chance for a second delete
Log::getInstance()->log("BoxStack", Log::DEBUG, "remove: going to delete boxx %p, num %d", toDelete, numBoxes);
delete toDelete;
+ if (display) {
+ Log::getInstance()->log("BoxStack", Log::DEBUG, "setVideoDisplay %d %d %d %d %d %d", display->mode, display->fallbackMode,
+ display->x, display->y, display->width, display->height);
+ Video::getInstance()->setVideoDisplay(*display);
+ }
return 1;
}
// This is pretty silly now that preDelete needs mutex unlocked
Boxx* toDel = NULL;
+ VideoDisplay *display = NULL;
while(numBoxes > 1)
{
toDel = NULL;
}
+ if (!videoStack.empty() && videoStack.top().first==toDel) {
+ videoStack.pop();
+ if (!videoStack.empty()) display=&videoStack.top().second;
+ }
boxLock.Unlock();
//AVO: do the delete outside the lock to allow for recursive deletes
Log::getInstance()->log("BoxStack", Log::DEBUG, "going to delete boxx %p, num=%d", toDel, numBoxes);
+ if (display) Video::getInstance()->setVideoDisplay(*display);
+
+
if (toDel) delete toDel;
}
+
+
}
int BoxStack::handleCommand(int command)
#include <time.h>
#include <signal.h>
#include <list>
+#include <stack>
#ifndef WIN32
#include <pthread.h>
#include "boxx.h"
#include "region.h"
#include "message.h"
+#include "video.h"
-//using namespace std;
-//using namespace __gnu_cxx; // needed for newer compilers?
-
-typedef list<Region> RegionList;
+typedef std::list<Region> RegionList;
+typedef std::stack<std::pair<Boxx*,VideoDisplay> > VideoDisplayStack;
class BoxStack
{
Boxx* boxes[20];
int numBoxes;
+ VideoDisplayStack videoStack;
+
Mutex boxLock;
void deleteBox(int z);
void repaintRevealed(int x, Region r);
void boxSplit(Region r, int start, int end, int direction, RegionList& rl);
+ int addVideoDisplay(Boxx*,VideoDisplay);
};
#endif
area.w = 0;
area.h = 0;
+ vdisplay.mode = None;
+
paraVSpace = 6; // default gap for drawPara
backgroundColourSet = false;
backgroundColourSet = true;
}
+void Boxx::setVideoBackground()
+{
+ vdisplay.mode=Window;
+ vdisplay.fallbackMode=Fullscreen;
+ vdisplay.x=getScreenX();
+ vdisplay.y=getScreenY();
+ vdisplay.width=getWidth();
+ vdisplay.height=getHeight();
+}
+
void Boxx::setVisible(bool isVisible)
{
visible = isVisible;
r->h = area.h;
}
+bool Boxx::getVideoDisplay(VideoDisplay &vd)
+{
+ for(vector<Boxx*>::iterator i = children.begin(); i != children.end(); i++)
+ {
+ if ((*i)->getVideoDisplay(vd)) return true;
+ }
+
+ if (vdisplay.mode==None) return false;
+ vd=vdisplay;
+ return true;
+}
+
// Level 1 drawing functions
void Boxx::fillColour(const DrawStyle& colour)
#include "surface.h"
+#include "video.h"
#include "tvmedia.h"
#include "osdvector.h"
void setGap(UINT gap);
void setBackgroundColour(const DrawStyle& colour);
void setVisible(bool isVisible);
+ void setVideoBackground();
// The following are supposed to be abstract functions
Region getRegionR(); // Same but as an object
void getRootBoxRegion(Region*);
+ bool getVideoDisplay(VideoDisplay &vd);
+
// Drawing functions level 1
void fillColour(const DrawStyle & colour);
int drawPara(const char* text, int x, int y, const DrawStyle& colour, unsigned int skiplines=0);
Boxx* parent;
Region area;
vector<Boxx*> children;
+ VideoDisplay vdisplay;
void setParent(Boxx*);
void blt(Region& r);
DrawStyle DrawStyle::YELLOW(255, 255, 0);
DrawStyle DrawStyle::VIDEOBLUE(0, 0, 150);
DrawStyle DrawStyle::VIEWBACKGROUND(0, 0, 100);
+DrawStyle DrawStyle::VIEWTRANSPARENTBACKGROUND(0, 0, 100, 128);
DrawStyle DrawStyle::TABVIEWBACKGROUND(0, 0, 120);
DrawStyle DrawStyle::TITLEBARBACKGROUND(0, 0, 200);
DrawStyle DrawStyle::SELECTHIGHLIGHT(240, 250, 80);
DrawStyle::YELLOW=DrawStyle(255, 255, 0);
DrawStyle::VIDEOBLUE=DrawStyle(0, 0, 150);
DrawStyle::VIEWBACKGROUND=DrawStyle(0, 0, 100);
+ DrawStyle::VIEWTRANSPARENTBACKGROUND=DrawStyle(0, 0, 100, 128);
DrawStyle::TABVIEWBACKGROUND=DrawStyle(0, 0, 120);
DrawStyle::TITLEBARBACKGROUND=DrawStyle(0, 0, 200);
DrawStyle::SELECTHIGHLIGHT=DrawStyle(240, 250, 80);
DrawStyle::VIEWBACKGROUND.x2=0.0;
DrawStyle::VIEWBACKGROUND.y2=1.0;
+ DrawStyle::VIEWTRANSPARENTBACKGROUND=DrawStyle(0, 0, 100, 128);
+ DrawStyle::VIEWTRANSPARENTBACKGROUND.grad_col[0]=Colour(0,0,160,128);
+ DrawStyle::VIEWTRANSPARENTBACKGROUND.num_colors=1;
+ DrawStyle::VIEWTRANSPARENTBACKGROUND.ft=DrawStyle::GradientLinear;
+ DrawStyle::VIEWTRANSPARENTBACKGROUND.x1=0.0;
+ DrawStyle::VIEWTRANSPARENTBACKGROUND.y1=0.0;
+ DrawStyle::VIEWTRANSPARENTBACKGROUND.x2=0.0;
+ DrawStyle::VIEWTRANSPARENTBACKGROUND.y2=1.0;
+
DrawStyle::TABVIEWBACKGROUND=DrawStyle(0, 0, 120);
static DrawStyle DARKGREY;
static DrawStyle VIDEOBLUE;
static DrawStyle VIEWBACKGROUND;
+ static DrawStyle VIEWTRANSPARENTBACKGROUND;
static DrawStyle TABVIEWBACKGROUND;
static DrawStyle TITLEBARBACKGROUND;
static DrawStyle SELECTHIGHLIGHT;
const static ULONG ADD_VIEW = 12;
const static ULONG REDRAW_LANG = 14;
const static ULONG EPG = 16;
- const static ULONG EPG_CLOSE = 17;
+ //const static ULONG EPG_CLOSE = 17; // Not needed anymore
const static ULONG CHANGED_OPTIONS = 18;
const static ULONG CONNECTION_LOST = 19;
const static ULONG MOVE_RECORDING = 20;
int ypos=(video->getScreenHeight()-demuxer->getVerticalSize())/2;
if (ypos < 0) ypos=0;
logger->log("PlayerMedia", Log::DEBUG, "setting pos x=%d,y=%d",xpos,ypos);
- video->setPosition(xpos,ypos);
+ //video->setPosition(xpos,ypos); // needs to be fixed
}
if (video->getTVsize() == Video::ASPECT4X3)
ltime = prevHour(<ime); // set ltime to previous hour TODO make this half hour?
time(&selTime); // set selTime to now
updateEventList(); // get list of programmes
+
+ vdisplay.mode=Window;
+ vdisplay.fallbackMode=Quarter;
+ vdisplay.x=Video::getInstance()->getScreenWidth()/2;
+ vdisplay.y=10;
+ vdisplay.width=Video::getInstance()->getScreenWidth()/2;
+ vdisplay.height=Video::getInstance()->getScreenHeight()/2;
}
void VEpg::preDelete()
case Remote::BACK:
case Remote::GUIDE:
{
- // return to normal TV mode
- 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 = parent;
- m->message = Message::EPG_CLOSE;
- Command::getInstance()->postMessageNoLock(m);
- }
return 4;
}
case Remote::CHANNELUP:
mode = OneChannel;
- setSize(640, 500); //old setSize(570, 420);
+ setSize(640+40, 500+40); //old setSize(570, 420);
createBuffer();
- setPosition(40, 40);
+ setPosition(20, 20);
setTitleBarOn(1);
setTitleBarColour(DrawStyle::TITLEBARBACKGROUND);
epg.setSize(area.w -slarea.x -slarea.w -10, area.h - 30 - 15 - 30);
add(&epg);
epg.setText("");
- epg.setBackgroundColour(DrawStyle::VIEWBACKGROUND);
+ epg.setVideoBackground();
+ epg.setBackgroundColour(DrawStyle::VIEWTRANSPARENTBACKGROUND);
epgTVmedia.setPosition(epg.getRegionR().w-100-10,10);
epgTVmedia.setSize(100,150/Osd::getInstance()->getPixelAspect());
current->duration, current->title);
VEpgSetTimer* vs = new VEpgSetTimer(current, chan);
vs->draw();
- BoxStack *boxstack=BoxStack::getInstance();
boxstack->add(vs);
boxstack->update(vs);
}
void VEpgListAdvanced::doGrid()
{
- Video* video=Video::getInstance();
- video->setMode(Video::QUARTER);
- video->setPosition(170, 5); //TODO add stack for these changes
+
if (mode!=OneChannel) {
Channel * chan=(*chanList)[ sl.getCurrentOptionData()];
channelNumber = chan->number;
if (Video::getInstance()->getFormat() == Video::PAL)
{
- setSize(640, 500);
+ setSize(640+40, 500+40);
createBuffer();
}
else
setSize(560, 400);
createBuffer();
}
- setPosition(40, 40);
+ setPosition(20, 20);
setTitleBarOn(1);
setBorderOn(1);
summary->setText(summary_text.c_str());
OsdVector *osdv=dynamic_cast<OsdVector*>(Osd::getInstance());
+ summary->setBackgroundColour(DrawStyle::VIEWTRANSPARENTBACKGROUND);
tabbar.addTab(tr("EPG"), summary);
+ summary->setVideoBackground();
WMovieView *movieview=NULL;
WSeriesView *seriesview=NULL;
if (event->movieInfo) {
movieview = new WMovieView(event->movieInfo);
movieview->setParaMode(true);
+ movieview->setBackgroundColour(DrawStyle::VIEWTRANSPARENTBACKGROUND);
tabbar.addTab(tr("TheTVDB Info"), movieview);
if (osdv) {
if (event->movieInfo->actors.size() > 0 && osdv)
{
WActorGallery *gallery= new WActorGallery(event->movieInfo->actors);
+ gallery->setBackgroundColour(DrawStyle::VIEWTRANSPARENTBACKGROUND);
tabbar.addTab(tr("Cast"),gallery);
}
WArtworkGallery *artgallery= new WArtworkGallery(*event->movieInfo);
+ artgallery->setBackgroundColour(DrawStyle::VIEWTRANSPARENTBACKGROUND);
tabbar.addTab(tr("Gallery"),artgallery);
}
} else if (event->seriesInfo) {
seriesview = new WSeriesView(event->seriesInfo);
seriesview->setParaMode(true);
+ seriesview->setBackgroundColour(DrawStyle::VIEWTRANSPARENTBACKGROUND);
tabbar.addTab(tr("TheTVDB Info"), seriesview);
if (osdv) {
if (event->seriesInfo->actors.size() > 0 && osdv)
{
WActorGallery *gallery= new WActorGallery(event->seriesInfo->actors);
+ gallery->setBackgroundColour(DrawStyle::VIEWTRANSPARENTBACKGROUND);
tabbar.addTab(tr("Cast"),gallery);
}
WArtworkGallery *artgallery= new WArtworkGallery(*event->seriesInfo);
+ artgallery->setBackgroundColour(DrawStyle::VIEWTRANSPARENTBACKGROUND);
tabbar.addTab(tr("Gallery"),artgallery);
}
{
return instance;
}
+
+// For legacy implementations
+bool Video::setVideoDisplay(VideoDisplay display)
+{
+ VideoMode applyMode=display.mode;
+ if (display.mode==Window || display.mode == None) {
+ if (display.fallbackMode == None || display.fallbackMode == Window) return false; // No Effect
+ applyMode=display.fallbackMode;
+ }
+ switch (applyMode) {
+ case Fullscreen: {
+ setMode(mode);
+ } break;
+ case Quarter: {
+ setMode(QUARTER);
+ setPosition(display.x/2, display.y/2);
+ }break;
+ case Eighth: {
+ setMode(EIGHTH);
+ setPosition(display.x/2, display.y/2);
+ } break;
+ case Window:
+ case None: return false; break; //Stupid
+ }
+ return true;
+
+}
+
/*
void Video::setInstance(Video* inst)
{
UINT frames;
} hmsf;
+enum VideoMode {
+ None,
+ Fullscreen,
+ Window, //Not supported on legacy hardware like mvp
+ Quarter,
+ Eighth
+};
+
+// New video api
+typedef struct _VideoDisplay {
+ enum VideoMode mode;
+ enum VideoMode fallbackMode;
+ UINT x,y;
+ UINT width,height;
+} VideoDisplay;
+
class Video: public DrainTarget, public AbstractOption
{
public:
virtual void executePendingModeChanges() {}; // This is called if you change the output mode and the device take a while for reinitialization
virtual int setDefaultAspect()=0;
virtual int setSource()=0;
- virtual int setPosition(int x, int y)=0;
virtual int sync()=0;
virtual int play()=0;
virtual int stop()=0;
virtual UCHAR getTVsize() { return tvsize; }
+ virtual bool setVideoDisplay(VideoDisplay display);
+
+
+
//hmsf framesToHMSF(ULONG frames,double fps);
// UINT getFPS(); //removed
const static UCHAR ZOOM = 5;
const static UCHAR UNKNOWN6 = 6;
+
+
+
protected:
+
+ virtual int setPosition(int x, int y){return 0;}; //legacy api do not use, use setVideoDisplay instead
static Video* instance;
int initted;
int fdVideo;
UCHAR aspectRatio;
int parx,pary;
UCHAR mode;
+
bool h264;
UINT screenWidth;
if ((tmode != NORMAL) && (tmode != LETTERBOX) && (tmode != UNKNOWN2) && (tmode != QUARTER) && (tmode != EIGHTH)
&& (tmode != ZOOM) && (tmode != UNKNOWN6)) return 0;
- mode = tmode;
+ if (tmode==NORMAL || tmode == LETTERBOX) mode = tmode;
if (ioctl(fdVideo, AV_SET_VID_MODE, mode) != 0) return 0;
return 1;
int setTVsize(UCHAR size); // Is the TV a widescreen?
int setDefaultAspect();
int setSource();
- int setPosition(int x, int y);
int sync();
int play();
int stop();
int test2();
#endif
+
+ protected:
+ int setPosition(int x, int y); // legacy api do not use
+
private:
int checkSCART();
void setLetterboxBorder(char* border);
int VideoOMX::setMode(UCHAR tmode)
{
if (!initted) return 0;
- mode=tmode;
+ if (tmode==LETTERBOX || tmode==NORMAL) mode=tmode;
updateMode();
return 1;
}
+bool VideoOMX::setVideoDisplay(VideoDisplay display)
+{
+ if (!initted) return false;
+ switch (display.mode)
+ {
+ case None: return true; //??
+ case Fullscreen: {
+ windowed = false;
+
+ } break;
+ case Quarter: {
+ windowed =true;
+ xpos = ((float) display.x) / ((float) screenWidth);
+ ypos = ((float) display.y) / ((float) screenHeight);
+ width = 0.5f;
+ height = 0.5f;
+ } break;
+
+ case Eighth: {
+ windowed =true;
+ xpos = ((float) display.x) / ((float) screenWidth);
+ ypos = ((float) display.y) / ((float) screenHeight);
+ width = 0.25f;
+ height = 0.25f;
+ } break;
+
+ case Window: {
+ windowed =true;
+ xpos = ((float) display.x) / ((float) screenWidth);
+ ypos = ((float) display.y) / ((float) screenHeight);
+ width = ((float) display.width) / ((float) screenWidth);
+ height = ((float) display.height) / ((float) screenHeight);
+ }break;
+ }
+ updateMode();
+ return true;
+}
+
void VideoOMX::updateMode()
{
dispconf.set = OMX_DISPLAY_SET_FULLSCREEN;
- if (mode != QUARTER && mode != EIGHTH) {
+ if (!windowed) {
//Set Fullscreen
dispconf.fullscreen = OMX_TRUE;
} else {
}
dispconf.set = OMX_DISPLAY_SET_MODE;
- if (mode != QUARTER && mode != EIGHTH) {
+ if (!windowed) {
dispconf.mode = (mode == NORMAL) ? OMX_DISPLAY_MODE_FILL
: OMX_DISPLAY_MODE_LETTERBOX;
} else {
return;
}
- if (mode == QUARTER || mode == EIGHTH) {
+ if (windowed) {
unsigned int display_width, display_height;
display_width = display_height = 0;
if (graphics_get_display_size(0, &display_width, &display_height)
= (int) (xpos * ((float) display_width));
dispconf.dest_rect.y_offset = (int) (ypos
* ((float) display_height));
- if (mode == QUARTER) {
- dispconf.dest_rect.width = display_width >> 1;
- dispconf.dest_rect.height = display_height >> 1;
- } else if (mode == EIGHTH) {
- dispconf.dest_rect.width = display_width >> 2;
- dispconf.dest_rect.height = display_height >> 2;
- }
+ dispconf.dest_rect.width = (int) (width * ((float) display_width));
+ dispconf.dest_rect.height = (int) (height * ((float) display_height));
+ Log::getInstance()->log("Video", Log::DEBUG,
+ "Set dest_rect as %d %d %d %d", dispconf.dest_rect.x_offset,dispconf.dest_rect.y_offset,
+ dispconf.dest_rect.width , dispconf.dest_rect.height);
+
error = OMX_SetParameter(omx_vid_rend,
OMX_IndexConfigDisplayRegion, &dispconf);
if (error != OMX_ErrorNone) {
int setConnection(UCHAR connection);
int setAspectRatio(UCHAR aspectRatio, int tparx,int tpary); // This one does the pin 8 scart widescreen switching
int setMode(UCHAR mode);
+ bool setVideoDisplay(VideoDisplay display);
int setTVsize(UCHAR size); // Is the TV a widescreen?
UCHAR getTVsize();
bool omx_mpeg2;
bool omx_h264;
float xpos,ypos;
+ float width, height;
+ bool windowed;
int deinterlace;
void updateMode();//called internally to adjust for different parameters
void selectVideoMode(int interlaced);
+
UCHAR tvsystem;
bool signalon;
bool pendingmodechange;
+
+
bool firstsynched;
if ((tmode != NORMAL) && (tmode != LETTERBOX) && (tmode != UNKNOWN2) && (tmode != QUARTER) && (tmode != EIGHTH)
&& (tmode != ZOOM) && (tmode != UNKNOWN6)) return 0;
- mode = tmode;
+ if (tmode==NORMAL || tmode == LETTERBOX) mode = tmode;
videoposx=0;
videoposy=0;
AdjustWindow();
int setTVsize(UCHAR size); // Is the TV a widescreen?
int setDefaultAspect();
int setSource();
- int setPosition(int x, int y);
int sync();
int play();
int dsplay();
int test();
int test2();
#endif
+protected:
+ int setPosition(int x, int y); // legacy api remove
+#error Port the new api
+
private:
int EnterIframePlayback();
#ifdef NEW_DS_MECHANISMENS
Region r1 = summary.getRegionR();
Region r2 = osd.getRegionR();
osdSummaryRegion = r1 + r2;
+
+ vdisplay.mode=Fullscreen;
+ vdisplay.fallbackMode=Fullscreen;
+ vdisplay.x=0;
+ vdisplay.y=0;
+ vdisplay.width=0;
+ vdisplay.height=0;
}
void VVideoLiveTV::preDelete()
if (osd.getVisible()) clearScreen();
if (!Command::getInstance()->advMenues()) {
- video->setMode(Video::QUARTER);
- video->setPosition(170, 5); //TODO need to deal with 4:3 switching
VEpg* vepg = new VEpg(this, currentChannelIndex, chanList);
vepg->draw();
osdChannelIndex = currentChannelIndex;
if (m->tag == 1) displayOSD(true);
}
- else if (m->message == Message::EPG_CLOSE)
- {
- video->setMode(videoMode);
- }
else if (m->message == Message::CHILD_CLOSE)
{
if (m->from == vas)
wssRegion.h = 300;
}
#endif
+ vdisplay.mode=Fullscreen;
+ vdisplay.fallbackMode=Fullscreen;
+ vdisplay.x=0;
+ vdisplay.y=0;
+ vdisplay.width=0;
+ vdisplay.height=0;
}
void VVideoRec::preDelete()