From: Marten Richter Date: Sat, 18 Oct 2014 19:48:57 +0000 (+0200) Subject: Fix leak in picture handling of osdvector, add static fallback pictures, some default... X-Git-Tag: 0-5-0~52 X-Git-Url: https://git.vomp.tv/gitweb/?a=commitdiff_plain;h=2622da84bf2dc9f6e23429295979cb82d4aa3d13;p=vompclient.git Fix leak in picture handling of osdvector, add static fallback pictures, some default artwork and optimized drawing for epglistadvanced and recordingslistadvanced --- diff --git a/GNUmakefile b/GNUmakefile index 3b11831..e0dd899 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -63,6 +63,9 @@ PICTURES += -Wl,other/txtoff.png 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 diff --git a/osdopenvg.cc b/osdopenvg.cc index 16c41a6..de536d9 100644 --- a/osdopenvg.cc +++ b/osdopenvg.cc @@ -1104,7 +1104,7 @@ unsigned int OsdOpenVG::handleTask(OpenVGCommand& command) } 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; @@ -1215,13 +1215,18 @@ unsigned int OsdOpenVG::handleTask(OpenVGCommand& command) 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; diff --git a/osdvector.cc b/osdvector.cc index ac2f059..aa872fb 100644 --- a/osdvector.cc +++ b/osdvector.cc @@ -389,6 +389,7 @@ void OsdVector::removeLoadIndexRef(const LoadIndex ref) 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); @@ -463,6 +464,16 @@ void OsdVector::cleanupOrphanedRefs() } else ++pitty; } + map::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,unsigned int>::iterator sitty=styles.begin(); while (sitty!=styles.end()) { @@ -593,6 +604,7 @@ LoadIndex OsdVector::getTVMediaRef(TVMediaInfo& tvmedia, ImageIndex& image) LoadIndex OsdVector::loadTVMedia(TVMediaInfo& tvmedia) { LoadIndex index=0; + if (tvmedias_load.find(tvmedia)==tvmedias_load.end()) { switch (tvmedia.getType()) { @@ -613,11 +625,13 @@ LoadIndex OsdVector::loadTVMedia(TVMediaInfo& tvmedia) 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]; } @@ -633,20 +647,21 @@ void OsdVector::informPicture(LoadIndex index, ImageIndex imageIndex) //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::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; } } @@ -826,6 +841,13 @@ void OsdVector::PictureReader::invalidateLoadIndex(LoadIndex index) 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(); @@ -862,24 +884,49 @@ bool OsdVector::PictureReader::processReceivedPictures() 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::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()){ diff --git a/osdvector.h b/osdvector.h index 698b668..4e27ab4 100644 --- a/osdvector.h +++ b/osdvector.h @@ -314,6 +314,8 @@ class OsdVector : public Osd void invalidateLoadIndex(LoadIndex index); + void informFallback(LoadIndex index, int fallback); + @@ -327,6 +329,7 @@ class OsdVector : public Osd std::queue pict_incoming; std::queue pict_incoming_static; std::list decoders; + std::map inform_fallback; set invalid_loadindex; bool picture_update; diff --git a/other/defposter.png b/other/defposter.png new file mode 100644 index 0000000..ba7e4df Binary files /dev/null and b/other/defposter.png differ diff --git a/other/recfolder.png b/other/recfolder.png new file mode 100644 index 0000000..3f8b4ce Binary files /dev/null and b/other/recfolder.png differ diff --git a/other/recording.png b/other/recording.png new file mode 100644 index 0000000..3213d84 Binary files /dev/null and b/other/recording.png differ diff --git a/staticartwork.h b/staticartwork.h index dd7ebdc..daca433 100644 --- a/staticartwork.h +++ b/staticartwork.h @@ -36,6 +36,9 @@ 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) diff --git a/tvmedia.cc b/tvmedia.cc index 20deaf4..feb2577 100644 --- a/tvmedia.cc +++ b/tvmedia.cc @@ -32,6 +32,7 @@ TVMediaInfo::TVMediaInfo() 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 } @@ -44,6 +45,7 @@ TVMediaInfo::TVMediaInfo(const TVMediaInfo& info) 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; } @@ -73,6 +75,13 @@ void TVMediaInfo::setStaticArtwork(int id) primary_id=id; } +void TVMediaInfo::setStaticFallback(int id) +{ + static_fallback=id; +} + + + void TVMediaInfo::setPosterThumb(int channel, int eventid) { type=5; @@ -90,25 +99,29 @@ bool operator<(const TVMediaInfo& rhs, const TVMediaInfo& lhs) { 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.containersetStaticArtwork(sa_radio); setTitleBarIcon(info); } + setTitleBarColour(DrawStyle::TITLEBARBACKGROUND); sl.setPosition(10, 30 + 5); @@ -108,6 +110,8 @@ void VChannelList::setList(ChannelList* tlist) 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; diff --git a/vchannellist.h b/vchannellist.h index 589f6ab..cb54db3 100644 --- a/vchannellist.h +++ b/vchannellist.h @@ -51,6 +51,7 @@ class VChannelList : public TBBoxx ChannelList* chanList; WSelectList sl; + ULONG type; void doShowingBar(); void quickUpdate(); diff --git a/vepglistadvanced.cc b/vepglistadvanced.cc index 981f780..fe19fb9 100644 --- a/vepglistadvanced.cc +++ b/vepglistadvanced.cc @@ -60,6 +60,7 @@ VEpgListAdvanced::VEpgListAdvanced(VVideoLiveTV *tvideolive, ChannelList* tchanL setTitleBarColour(DrawStyle::TITLEBARBACKGROUND); TVMediaInfo *info= new TVMediaInfo(); info->setChannelLogo(channelNumber); + info->setStaticFallback(sa_tv); setTitleBarIcon(info); sl.setPosition(10, 30 + 5); @@ -248,6 +249,7 @@ void VEpgListAdvanced::doProgramm() setButtonText(); TVMediaInfo *info= new TVMediaInfo(); info->setChannelLogo(channelNumber); + info->setStaticFallback(sa_tv); setTitleBarIcon(info); draw(true); boxstack->update(this); @@ -475,6 +477,7 @@ void VEpgListAdvanced::drawDataChannel(bool doIndexPop) // 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; } @@ -490,8 +493,7 @@ void VEpgListAdvanced::drawDataChannel(bool doIndexPop) sl.hintSetTop(saveTop); } updateSelection(); - sl.draw(); - epg.draw(); + } void VEpgListAdvanced::drawDataNowNext(bool next, bool doIndexPop) @@ -549,6 +551,7 @@ 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; } @@ -563,8 +566,6 @@ void VEpgListAdvanced::drawDataNowNext(bool next, bool doIndexPop) sl.hintSetTop(saveTop); } updateSelection(); - sl.draw(); - epg.draw(); } void VEpgListAdvanced::draw(bool doIndexPop) @@ -595,6 +596,7 @@ void VEpgListAdvanced::draw(bool doIndexPop) + drawData(doIndexPop); TBBoxx::draw(); @@ -633,7 +635,7 @@ void VEpgListAdvanced::draw(bool doIndexPop) drawTextRJ(tr("[ok] = info"), 560+70, 385+80, DrawStyle::LIGHTTEXT); // All static stuff done - drawData(doIndexPop); + } @@ -696,6 +698,7 @@ void VEpgListAdvanced::updateSelection() if (mode==OneChannel) { TVMediaInfo *info= new TVMediaInfo(); info->setChannelLogo(channelNumber); + info->setStaticFallback(sa_tv); setTitleBarIcon(info); } Event* toShow = getCurrentOptionEvent(channel); diff --git a/vrecordinglistadvanced.cc b/vrecordinglistadvanced.cc index 557516f..004a0d0 100644 --- a/vrecordinglistadvanced.cc +++ b/vrecordinglistadvanced.cc @@ -109,8 +109,11 @@ void VRecordingListAdvanced::drawData(bool doIndexPop) 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; @@ -136,6 +139,7 @@ void VRecordingListAdvanced::drawData(bool doIndexPop) // 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; } @@ -151,9 +155,6 @@ void VRecordingListAdvanced::drawData(bool doIndexPop) sl.hintSetTop(saveTop); } updateSelection(); - sl.draw(); - doShowingBar(); - epg.draw(); } void VRecordingListAdvanced::draw(bool doIndexPop) @@ -170,8 +171,10 @@ void VRecordingListAdvanced::draw(bool doIndexPop) { setTitleText(tr("Recordings")); } + drawData(doIndexPop); } + TBBoxx::draw(); if (loading) @@ -206,7 +209,7 @@ void VRecordingListAdvanced::draw(bool doIndexPop) drawTextRJ(tr("[ok] = menu"), 560+70, 385+80, DrawStyle::LIGHTTEXT); // All static stuff done - drawData(doIndexPop); + doShowingBar(); } }