PICTURES += -Wl,other/txton.png
PICTURES += -Wl,other/dolbyoff.png
PICTURES += -Wl,other/dolbyon.png
+PICTURES += -Wl,other/recording.png
+PICTURES += -Wl,other/recfolder.png
+PICTURES += -Wl,other/defposter.png
PICTURES += -Wl,--format=default
} break;
case OVGdestroyImageRef: {
- //Log::getInstance()->log("OSD", Log::DEBUG, "TVMedia Draw Image Destroy %d ",command.param1);
+ //Log::getInstance()->log("OSD", Log::DEBUG, "TVMedia Draw Image Destroy %x",command.param1);
vgDestroyImage((VGImage)command.param1);
return 0;
} break;
case OVGcreateEGLImage: {
PictureInfo *info = (PictureInfo*) command.data;
VGImage handle;
- //Log::getInstance()->log("OSD", Log::DEBUG, "TVMedia OVGcreateImageMemory %d %d",info->width,info->height);
+
handle=vgCreateImage(VG_sABGR_8888,info->width,info->height,VG_IMAGE_QUALITY_BETTER);
+ //Log::getInstance()->log("OSD", Log::DEBUG, "TVMedia OVGcreateEGLImage %d %d %x",info->width,info->height, handle);
info->handle = handle;
info->reference = eglCreateImageKHR(egl_display, egl_context, EGL_VG_PARENT_IMAGE_KHR, (EGLClientBuffer)handle, NULL);
if (info->reference) return true;
- else return false;
+ else {
+ Log::getInstance()->log("OSD", Log::DEBUG, "TVMedia OVGcreateEGLImage %d %d %x Fail!",info->width,info->height, handle);
+ if (handle) vgDestroyImage(handle);
+ return false;
+ }
} break;
removeImageRef((*itty).second); // remove lock
}
tvmedias_loaded.erase(ref);
+// Log::getInstance()->log("OsdVector", Log::DEBUG, "TVMedia removeLoadIndexRef %d %llx",tvmedias_load.size(),ref);
tvmedias_load.erase(tvmedias_load_inv[ref]);
tvmedias_load_inv.erase(ref);
} else ++pitty;
}
+ map<ImageIndex,int>::iterator citty=images_ref.begin();
+ while (citty!=images_ref.end()) {
+ int count=(*citty).second;
+ if (count==0) {
+ ImageIndex ref=(*citty).first;
+ images_ref.erase(citty++);
+ destroyImageRef(ref);
+ } else ++citty;
+ }
+
map<pair<Colour*,unsigned int>,unsigned int>::iterator sitty=styles.begin();
while (sitty!=styles.end()) {
LoadIndex OsdVector::loadTVMedia(TVMediaInfo& tvmedia)
{
LoadIndex index=0;
+
if (tvmedias_load.find(tvmedia)==tvmedias_load.end())
{
switch (tvmedia.getType()) {
index=VDR::getInstance()->loadTVMedia(tvmedia);
break;
}
+ if (tvmedia.getType()!=4 && tvmedia.getStaticFallback()>-1) {
+ reader.informFallback(index,tvmedia.getStaticFallback());
+ }
tvmedias_load[tvmedia]=index;
tvmedias_load_inv[index]=tvmedia;
} else {
-
index=tvmedias_load[tvmedia];
}
//Beware for thread safety
ImageIndex image_index=0;
- Log::getInstance()->log("OsdVector", Log::DEBUG, "TVMedia Picture for request id %llx arrived %d",index, imageIndex);
+ Log::getInstance()->log("OsdVector", Log::DEBUG, "TVMedia Picture for request id %llx arrived %x",index, imageIndex);
surfaces_mutex.Lock();
TVMediaInfo tvmedia=tvmedias_load_inv[index];
if (imageIndex) {
+ map<LoadIndex,int>::iterator itty=loadindex_ref.find(index);
image_index=tvmedias[tvmedia]=imageIndex;
tvmedias_loaded[index]=image_index;
- if (loadindex_ref.find(index)==loadindex_ref.end()) {
+
+ if (itty==loadindex_ref.end() || (*itty).second == 0) {
// we do not want the picture anymore . Really...
// fill images_ref in to not irritate the garbage collector
if (images_ref.find(index)==images_ref.end()) {
images_ref[image_index]=0;
}
} else {
-
incImageRef(image_index); // hold one index until all loadings refs are gone;
}
}
pict_lock_incoming.Unlock();
}
+void OsdVector::PictureReader::informFallback(LoadIndex index, int fallback)
+{
+ pict_lock_incoming.Lock();
+ inform_fallback[index]=fallback;
+ pict_lock_incoming.Unlock();
+}
+
void OsdVector::PictureReader::receivePicture(VDR_ResponsePacket *vresp)
{
pict_lock_incoming.Lock();
delete vresp;
return true;
}
- // Log::getInstance()->log("OsdVector", Log::DEBUG, "TVMedia Pictures arrived VDR %x %d %d",
- // vresp->getStreamID(),vresp->getUserDataLength(),vresp->getFlag());
+// Log::getInstance()->log("OsdVector", Log::DEBUG, "TVMedia Pictures arrived VDR %x %d %d",
+// vresp->getStreamID(),vresp->getUserDataLength(),vresp->getFlag());
+ bool decode = false;
+ bool freed = false;
+ UCHAR *userdata;
+ ULONG length;
+
if (vresp->getFlag() != 2) {
- UCHAR *userdata=vresp->getUserData();
- ULONG length=vresp->getUserDataLength();
+ userdata=vresp->getUserData();
+ length=vresp->getUserDataLength();
+ decode = true;
+ freed = true;
+ } else {
+ int fallback=-1;
+ pict_lock_incoming.Lock();
+ if (inform_fallback.find(vresp->getStreamID())!=inform_fallback.end()) {
+ fallback=inform_fallback[vresp->getStreamID()];
+ }
+ pict_lock_incoming.Unlock();
+ if (fallback >= 0 && ((OsdVector*)Osd::getInstance())->getStaticImageData(fallback, &userdata, &length))
+ {
+ decode = true;
+ freed = false;
+ }
+
+ }
+ if (decode) {
std::list<PictureDecoder*>::iterator itty=decoders.begin();
while (itty!=decoders.end()) {
- userdata=(*itty)->decodePicture(vresp->getStreamID(), userdata, length);
+ userdata=(*itty)->decodePicture(vresp->getStreamID(), userdata, length, freed);
if (!userdata){
decoded=true;
break;
}
itty++;
}
- if (!decoded && userdata ){
+ if (!decoded && userdata && freed){
free(userdata);
}
}
+ pict_lock_incoming.Lock();
+ inform_fallback.erase(vresp->getStreamID());
+ pict_lock_incoming.Unlock();
//else osd->informPicture(vresp->getStreamID(), 0);
delete vresp;
} else if (pict_incoming_static.size()){
void invalidateLoadIndex(LoadIndex index);
+ void informFallback(LoadIndex index, int fallback);
+
std::queue<VDR_ResponsePacket*> pict_incoming;
std::queue<unsigned int> pict_incoming_static;
std::list<PictureDecoder*> decoders;
+ std::map<LoadIndex,int> inform_fallback;
set<LoadIndex> invalid_loadindex;
bool picture_update;
EXTERNALPICTURE(txton, txton, png) \
EXTERNALPICTURE(dolbyoff,dolbyoff, png) \
EXTERNALPICTURE(dolbyon, dolbyon, png) \
+ EXTERNALPICTURE(recording,recording, png) \
+ EXTERNALPICTURE(recfolder, recfolder, png) \
+ EXTERNALPICTURE(defposter, defposter, png) \
EXTERNALPICTURE(tv, tv, png)
container=-1; // indices the dataelements with picture in movieinfo or seriesinfo
container_member=-1; // index into the container
primary_name="";
+ static_fallback = -1; // fallback if not available
}
container=info.container; // indices the dataelements with picture in movieinfo or seriesinfo
container_member=info.container_member; // index into the container
primary_name=info.primary_name;
+ static_fallback = info.static_fallback;
}
primary_id=id;
}
+void TVMediaInfo::setStaticFallback(int id)
+{
+ static_fallback=id;
+}
+
+
+
void TVMediaInfo::setPosterThumb(int channel, int eventid)
{
type=5;
{
if (rhs.type==lhs.type) {
if (rhs.primary_id==lhs.primary_id) {
- if (rhs.secondary_id==lhs.secondary_id) {
- if (rhs.type_pict==lhs.type_pict) {
- if (rhs.container==lhs.container) {
- if (rhs.primary_name== lhs.primary_name) {
- return rhs.container_member < lhs.container_member;
+ if (rhs.static_fallback==lhs.static_fallback) {
+ if (rhs.secondary_id==lhs.secondary_id) {
+ if (rhs.type_pict==lhs.type_pict) {
+ if (rhs.container==lhs.container) {
+ if (rhs.primary_name== lhs.primary_name) {
+ return rhs.container_member < lhs.container_member;
+ } else {
+ return rhs.primary_name < lhs.primary_name;
+ }
} else {
- return rhs.primary_name < lhs.primary_name;
+ return rhs.container<lhs.container;
}
+
+
} else {
- return rhs.container<lhs.container;
+ return rhs.type_pict<lhs.type_pict;
}
-
} else {
- return rhs.type_pict<lhs.type_pict;
+ return rhs.secondary_id<lhs.secondary_id;
}
-
} else {
- return rhs.secondary_id<lhs.secondary_id;
+ return rhs.static_fallback<lhs.static_fallback;
}
} else {
bool operator==(const TVMediaInfo& rhs, const TVMediaInfo& lhs)
{
- return (rhs.type==lhs.type) && (rhs.primary_id==lhs.primary_id) &&
+ return (rhs.type==lhs.type) && (rhs.primary_id==lhs.primary_id) && (rhs.static_fallback==lhs.static_fallback) &&
(rhs.secondary_id==lhs.secondary_id) && (rhs.type_pict==lhs.type_pict) &&
(rhs.container==lhs.container) && (rhs.primary_name== lhs.primary_name)
&& (rhs.container_member == lhs.container_member);
void setPosterThumb(int channel, int eventid);
void setChannelLogo(int channel);
void setStaticArtwork(int artwork);
+ void setStaticFallback(int fallback);
int getType() {return type;};
int getPrimaryID() {return primary_id;};
int getSecondaryID() {return secondary_id;};
+ int getStaticFallback() {return static_fallback;};
private:
int type; // 1 movie or 2 series or 3 unknown recording or 4 static artwork
int container; // indices the dataelements with picture in movieinfo or seriesinfo
int container_member; // index into the container
std::string primary_name;
+ int static_fallback; // id of static replacement in case resource is not available
};
struct TVMedia
#include "vchannelselect.h"
#include "staticartwork.h"
-VChannelList::VChannelList(ULONG type)
+VChannelList::VChannelList(ULONG ttype)
{
boxstack = BoxStack::getInstance();
setSize(570, 420);
setTitleBarOn(1);
+ type = ttype;
if (type == VDR::VIDEO)
{
setTitleText(tr("Channels"));
info->setStaticArtwork(sa_radio);
setTitleBarIcon(info);
}
+
setTitleBarColour(DrawStyle::TITLEBARBACKGROUND);
sl.setPosition(10, 30 + 5);
if (osdv) {
info= new TVMediaInfo();
info->setChannelLogo((*chanList)[i]->number);
+ if (type == VDR::VIDEO) info->setStaticFallback(sa_tv);
+ else info->setStaticFallback(sa_radio);
}
chan->index = sl.addOption(str, (ULONG)chan, first, info);
first = 0;
ChannelList* chanList;
WSelectList sl;
+ ULONG type;
void doShowingBar();
void quickUpdate();
setTitleBarColour(DrawStyle::TITLEBARBACKGROUND);
TVMediaInfo *info= new TVMediaInfo();
info->setChannelLogo(channelNumber);
+ info->setStaticFallback(sa_tv);
setTitleBarIcon(info);
sl.setPosition(10, 30 + 5);
setButtonText();
TVMediaInfo *info= new TVMediaInfo();
info->setChannelLogo(channelNumber);
+ info->setStaticFallback(sa_tv);
setTitleBarIcon(info);
draw(true);
boxstack->update(this);
// New TVMedia stuff
TVMediaInfo *info= new TVMediaInfo();
info->setPosterThumb(channelNumber, currentEvent->id);
+ info->setStaticFallback(sa_defposter);
currentEvent->index = sl.addOption(tempC, currentEvent->id, first, info);
first = 0;
}
sl.hintSetTop(saveTop);
}
updateSelection();
- sl.draw();
- epg.draw();
+
}
void VEpgListAdvanced::drawDataNowNext(bool next, bool doIndexPop)
setcurrenthelper = listIndex;
}
info->setChannelLogo((*chanList)[listIndex]->number);
+ info->setStaticFallback(sa_tv);
currentEvent->index = sl.addOption(tempC, listIndex, first, info);
first = 0;
}
sl.hintSetTop(saveTop);
}
updateSelection();
- sl.draw();
- epg.draw();
}
void VEpgListAdvanced::draw(bool doIndexPop)
+ drawData(doIndexPop);
TBBoxx::draw();
drawTextRJ(tr("[ok] = info"), 560+70, 385+80, DrawStyle::LIGHTTEXT);
// All static stuff done
- drawData(doIndexPop);
+
}
if (mode==OneChannel) {
TVMediaInfo *info= new TVMediaInfo();
info->setChannelLogo(channelNumber);
+ info->setStaticFallback(sa_tv);
setTitleBarIcon(info);
}
Event* toShow = getCurrentOptionEvent(channel);
TVMediaInfo *info= NULL;
if (currentSubDir->recList.begin() != currentSubDir->recList.end())
{
- info=new TVMediaInfo();
- info->setPosterThumb((*currentSubDir->recList.begin())->getFileName());
+ info=new TVMediaInfo();
+ info->setPosterThumb((*currentSubDir->recList.begin())->getFileName());
+ info->setStaticFallback(sa_recfolder);
+ } else {
+ info->setStaticArtwork(sa_recfolder);
}
currentSubDir->index = sl.addOption(tempA, 0, first, info);
first = 0;
// New TVMedia stuff
TVMediaInfo *info= new TVMediaInfo();
info->setPosterThumb(currentRec->getFileName());
+ info->setStaticFallback(sa_recording);
currentRec->index = sl.addOption(tempB, 0, first, info);
first = 0;
}
sl.hintSetTop(saveTop);
}
updateSelection();
- sl.draw();
- doShowingBar();
- epg.draw();
}
void VRecordingListAdvanced::draw(bool doIndexPop)
{
setTitleText(tr("Recordings"));
}
+ drawData(doIndexPop);
}
+
TBBoxx::draw();
if (loading)
drawTextRJ(tr("[ok] = menu"), 560+70, 385+80, DrawStyle::LIGHTTEXT);
// All static stuff done
- drawData(doIndexPop);
+ doShowingBar();
}
}