2 Copyright 2012 Marten Richter
4 This file is part of VOMP.
6 VOMP is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 VOMP is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with VOMP; if not, write to the Free Software
18 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
21 #include "osdvector.h"
22 #include "surfacevector.h"
24 #include "vdrresponsepacket.h"
28 // The next section is activated, if the magick++ PictureReader is provided, it should be available for many POSIX platforms
29 #ifdef PICTURE_DECODER_MAGICK
30 #define MAGICKCORE_QUANTUM_DEPTH 16
31 #define MAGICKCORE_HDRI_ENABLE 0
34 using namespace Magick;
36 class MagickDecoder: public OsdVector::PictureDecoder {
38 MagickDecoder(OsdVector::PictureReader* treader): OsdVector::PictureDecoder(treader) {pictInfValid=false;};
40 unsigned char *decodePicture(LoadIndex index, unsigned char * buffer, unsigned int length, bool freemem);
42 bool getDecodedPicture( struct OsdVector::PictureInfo& pict_inf);
44 void freeReference(void * ref);
47 OsdVector::PictureInfo pictInf;
51 unsigned char * MagickDecoder::decodePicture(LoadIndex index, unsigned char * buffer, unsigned int length, bool freemem)
53 if (pictInfValid) return buffer; // does support only one image at a Time;
55 Blob *imageblob = new Blob();
58 Log::getInstance()->log("MagickDecoder", Log::DEBUG, "decodePicture");
60 if (freemem) myblob.updateNoCopy(buffer,length,Blob::MallocAllocator);
61 else myblob.update(buffer,length);
62 magicimage.read(myblob);
64 magicimage.write(imageblob,"RGBA");
66 }catch( Exception &error_ )
68 Log::getInstance()->log("MagickDecoder", Log::DEBUG, "Libmagick: %s",error_.what());
70 Log::getInstance()->log("MagickDecoder", Log::DEBUG, "Libmagick: error mark2");
71 unsigned char* newbuffer=(unsigned char*) malloc(length);
72 memcpy(newbuffer,myblob.data(),length);
75 pictInf.reference = (void*) imageblob;
76 pictInf.width = magicimage.columns();
77 pictInf.height = magicimage.rows();
78 pictInf.image = imageblob->data();
79 pictInf.decoder = this;
80 pictInf.type = OsdVector::PictureInfo::RGBAMemBlock;
81 pictInf.lindex = index;
86 // I can handle everything, so the return value is always true
89 void MagickDecoder::freeReference(void * ref)
91 Blob *todelete = (Blob*) ref;
95 bool MagickDecoder::getDecodedPicture(struct OsdVector::PictureInfo& pict_inf)
97 if (!pictInfValid) return false;
106 OsdVector::OsdVector()
108 setlocale(LC_CTYPE,"C.UTF-8");
109 #ifdef PICTURE_DECODER_MAGICK
110 reader.addDecoder(new MagickDecoder(&reader));
113 for (int i=0;i<256;i++) {
114 byte_char_width[i]=0.f;
116 styles_lastit_valid=styles_ref_lastit_valid=false;
120 OsdVector::~OsdVector()
125 int OsdVector::getFD()
130 void OsdVector::screenShot(const char* fileName)
132 //Do nothing, if no libmagick is there
133 #ifdef PICTURE_DECODER_MAGICK
135 getRealScreenSize(width,height);
136 size_t length=width*height*4;
137 void *mem=malloc(length);
141 if (!screenShot(mem,width,height,true)) {
142 Log::getInstance()->log("OsdVector", Log::DEBUG, "Screenshot failed!");
146 myblob.updateNoCopy(mem,length,Blob::MallocAllocator);
147 Image image(myblob,Geometry(width,height),8,"RGBA");
148 image.write(fileName);
149 }catch( Exception &error_ )
151 Log::getInstance()->log("MagickEncoder", Log::DEBUG, "Libmagick: %s",error_.what());
158 Surface * OsdVector::createNewSurface()
160 return new SurfaceVector(this);
164 void OsdVector::Blank()
166 // do nothing? remove this one?
169 int OsdVector::restore()
171 // First clear the contents of all registered surfaces
172 surfaces_mutex.Lock();
174 //Now go through all surfaces and draw them
175 list<SurfaceCommands>::iterator curdraw=scommands.begin();
176 while (curdraw!=scommands.end()) {
177 (*curdraw).commands.clear();
178 (*curdraw).commands.reserve(2048);
181 //also clear all handles, they are now invalid, no need to release them
187 styles_lastit_valid=styles_ref_lastit_valid=false;
191 loadindex_ref.clear();
192 tvmedias_load.clear();
193 tvmedias_load_inv.clear();
194 tvmedias_loaded.clear();
196 surfaces_mutex.Unlock();
200 void OsdVector::drawSurfaces()
202 surfaces_mutex.Lock();
203 list<SurfaceCommands*> todraw; //First figure out if a surfaces is below another surface
204 list<SurfaceCommands>::iterator itty1=scommands.begin();
205 while (itty1!=scommands.end()) {
206 list<SurfaceCommands>::iterator itty2=itty1;
209 while (itty2!=scommands.end()) {
210 SurfaceCommands & ref1=*itty1;
211 SurfaceCommands & ref2=*itty2;
212 if (ref1.x>=ref2.x && ref1.y>=ref2.y
213 && (ref1.x+ref1.w) <= (ref2.x+ref2.w)
214 && (ref1.y+ref1.h) <= (ref2.y+ref2.h) ) {
220 if (!hidden) { // we are not hidden, perfect
221 todraw.push_back(&(*itty1));
226 getScreenSize(swidth,sheight);
227 //Now go through all surfaces and draw them
228 list<SurfaceCommands*>::iterator curdraw=todraw.begin();
229 while (curdraw!=todraw.end()) {
230 drawSetTrans(*(*curdraw));
231 std::vector<SVGCommand>::iterator commands=(*(*curdraw)).commands.begin();
232 std::vector<SVGCommand>::iterator end=(*(*curdraw)).commands.end();
233 while (commands!=end) {
234 // update any images loaded in the mean time
235 if ((*commands).instr==DrawImageLoading) {
236 LoadIndex loadindex=(*commands).target.loadindex;
237 if (tvmedias_loaded.find(loadindex)!=tvmedias_loaded.end()) {
238 (*commands).instr=DrawImage;
239 (*commands).target.image=tvmedias_loaded[loadindex];;
240 incImageRef((*commands).target.image);
241 removeLoadIndexRef(loadindex);
245 // Now check if the command is on screen!
246 if (!(*commands).Outside(0,0,swidth,sheight)) {
247 executeDrawCommand(*commands);
254 surfaces_mutex.Unlock();
257 void OsdVector::updateOrAddSurface(const SurfaceVector *surf,float x,float y,float height,float width,
258 std::vector<SVGCommand>& commands)
260 surfaces_mutex.Lock();
261 //First determine it is already in our system
262 list<SurfaceCommands>::iterator itty=scommands.begin();
263 while (itty!=scommands.end()) {
264 if ((*itty).surf==surf) {
265 //decrease the references
266 dereferenceSVGCommand((*itty).commands);
272 if (itty==scommands.end()) {
273 SurfaceCommands new_sc;
279 itty=scommands.insert(itty,new_sc);
281 // update any images loaded in the mean time
282 std::vector<SVGCommand>::iterator ilitty=commands.begin();
284 while (ilitty!=commands.end())
286 if ((*ilitty).instr==DrawImageLoading) {
287 LoadIndex loadindex=(*ilitty).target.loadindex;
288 if (tvmedias_loaded.find(loadindex)!=tvmedias_loaded.end()) {
290 (*ilitty).instr=DrawImage;
291 (*ilitty).target.image=tvmedias_loaded[loadindex];
292 incImageRef((*ilitty).target.image);
293 removeLoadIndexRef(loadindex);
300 // then clear and copy
301 (*itty).commands.clear();
302 (*itty).commands=commands;
303 //increase the references
304 referenceSVGCommand((*itty).commands);
305 cleanupOrphanedRefs();
307 surfaces_mutex.Unlock();
310 void OsdVector::removeSurface(const SurfaceVector *surf)
312 surfaces_mutex.Lock();
313 //First determine it is already in our system
314 list<SurfaceCommands>::iterator itty=scommands.begin();
315 while (itty!=scommands.end()) {
316 if ((*itty).surf==surf) {
317 dereferenceSVGCommand((*itty).commands);
318 (*itty).commands.clear();
319 scommands.erase(itty);
324 surfaces_mutex.Unlock();
328 void OsdVector::dereferenceSVGCommand(std::vector<SVGCommand>& commands )
331 std::vector<SVGCommand>::iterator sitty = commands.begin();
332 while (sitty != commands.end()) {
333 removeStyleRef((*sitty).getRef());
334 ImageIndex ii = (*sitty).getImageIndex();
335 if (ii) removeImageRef(ii);
336 LoadIndex li=(*sitty).getLoadIndex();
337 if (li) removeLoadIndexRef(li);
342 void OsdVector::referenceSVGCommand(std::vector<SVGCommand>& commands )
344 std::vector<SVGCommand>::iterator sitty=commands.begin();
345 while (sitty!=commands.end())
347 incStyleRef((*sitty).getRef());
348 ImageIndex ii=(*sitty).getImageIndex();
349 if (ii) incImageRef(ii);
350 LoadIndex li=(*sitty).getLoadIndex();
351 if (li) incLoadIndexRef(li);
357 void OsdVector::incImageRef(ImageIndex index)
359 if (images_ref.find(index)==images_ref.end()) {
366 void OsdVector::removeImageRef(const ImageIndex ref)
371 int OsdVector::getLoadIndexRef(LoadIndex index)
373 surfaces_mutex.Lock();
374 if (loadindex_ref.find(index)==loadindex_ref.end()) {
377 return loadindex_ref[index];
379 surfaces_mutex.Unlock();
382 void OsdVector::incLoadIndexRef(LoadIndex index)
384 if (loadindex_ref.find(index)==loadindex_ref.end()) {
385 loadindex_ref[index]=1;
387 loadindex_ref[index]++;
391 void OsdVector::removeLoadIndexRef(const LoadIndex ref)
393 loadindex_ref[ref]--;
394 if (loadindex_ref[ref]==0) {
395 //now check, if it is already loaded
396 map<LoadIndex,ImageIndex>::iterator itty=tvmedias_loaded.find(ref);
397 if ( itty != tvmedias_loaded.end()) {
398 removeImageRef((*itty).second); // remove lock
400 tvmedias_loaded.erase(ref);
401 // Log::getInstance()->log("OsdVector", Log::DEBUG, "TVMedia removeLoadIndexRef %d %llx",tvmedias_load.size(),ref);
402 tvmedias_load.erase(tvmedias_load_inv[ref]);
403 tvmedias_load_inv.erase(ref);
405 reader.invalidateLoadIndex(ref);
413 void OsdVector::cleanupOrphanedRefs()
414 { // Do some garbage collection
416 map<void *,ImageIndex>::iterator mitty=monobitmaps.begin();
417 while (mitty!=monobitmaps.end()) {
418 map<ImageIndex,int>::iterator curitty=images_ref.find((*mitty).second);
419 int count=(*curitty).second;
421 ImageIndex ref=(*curitty).first;
422 monobitmaps.erase(mitty++);
423 images_ref.erase(curitty++);
424 destroyImageRef(ref);
428 /*map<string,ImageIndex>::iterator jitty=jpegs.begin();
429 while (jitty!=jpegs.end()) {
430 map<ImageIndex,int>::iterator curitty=images_ref.find((*jitty).second);
431 int count=(*curitty).second;
433 ImageIndex ref=(*curitty).first;
434 jpegs.erase(jitty++);
435 images_ref.erase(curitty++);
436 destroyImageRef(ref);
440 map<TVMediaInfo,ImageIndex>::iterator titty=tvmedias.begin();
441 while (titty!=tvmedias.end()) {
442 map<ImageIndex,int>::iterator curitty=images_ref.find((*titty).second);
443 int count=(*curitty).second;
445 ImageIndex ref=(*curitty).first;
446 tvmedias.erase(titty++);
447 images_ref.erase(curitty);
448 destroyImageRef(ref);
453 map<TVMediaInfo,LoadIndex>::iterator litty=tvmedias_load.begin();
454 while (litty!=tvmedias_load.end()) {
455 map<LoadIndex,int>::iterator curitty=loadindex_ref.find((*litty).second);
456 int count=(*curitty).second;
458 tvmedias_load_inv.erase((*litty).second);
459 tvmedias_loaded.erase((*litty).second);
460 tvmedias_load.erase(litty++);
464 list<ImageIndex>::iterator pitty=palettepics.begin();
465 while (pitty!=palettepics.end()) {
466 map<ImageIndex,int>::iterator curitty=images_ref.find((*pitty));
467 int count=(*curitty).second;
469 ImageIndex ref=(*curitty).first;
470 palettepics.erase(pitty++);
471 images_ref.erase(curitty++);
472 destroyImageRef(ref);
476 map<ImageIndex,int>::iterator citty=images_ref.begin();
477 while (citty!=images_ref.end()) {
478 int count=(*citty).second;
480 ImageIndex ref=(*citty).first;
481 images_ref.erase(citty++);
482 destroyImageRef(ref);
487 map<DrawStyle, VectorHandle>::iterator sitty = styles.begin();
488 while (sitty!=styles.end()) {
489 map<VectorHandle, int>::iterator curitty = styles_ref.find((*sitty).second);
490 int count=(*curitty).second;
492 VectorHandle ref = (*curitty).first;
493 styles.erase(sitty++);
494 styles_ref.erase(curitty++);
495 styles_lastit_valid=styles_ref_lastit_valid=false;
496 destroyStyleRef(ref);
504 int OsdVector::getImageRef(ImageIndex index)
506 surfaces_mutex.Lock();
507 if (images_ref.find(index)==images_ref.end()) {
510 return images_ref[index];
512 surfaces_mutex.Unlock();
515 void OsdVector::incStyleRef(VectorHandle index)
517 if (!styles_ref_lastit_valid || (*styles_ref_lastit).first!=index) {
518 styles_ref_lastit_valid=false;
519 styles_ref_lastit=styles_ref.find(index);
521 if (styles_ref_lastit==styles_ref.end()) {
522 styles_ref_lastit = styles_ref.insert(std::pair<VectorHandle, int>(index, 1)).first;
524 (*styles_ref_lastit).second++;
526 styles_ref_lastit_valid=true;
529 void OsdVector::removeStyleRef(VectorHandle index)
531 if (!styles_ref_lastit_valid || (*styles_ref_lastit).first!=index) {
532 styles_ref_lastit_valid=false;
533 styles_ref_lastit=styles_ref.find(index);
535 if (styles_ref_lastit!=styles_ref.end()) {
536 styles_ref_lastit_valid=true;
537 (*styles_ref_lastit).second--;
541 VectorHandle OsdVector::getStyleRef(const DrawStyle &c)
543 surfaces_mutex.Lock();
544 VectorHandle style_handle = 0;
545 if (!styles_lastit_valid || (*styles_lastit).first!=c) {
546 styles_lastit_valid=false;
547 styles_lastit=styles.find(c);
550 if (styles_lastit==styles.end())
552 surfaces_mutex.Unlock();
553 style_handle=createStyleRef(c);
554 surfaces_mutex.Lock();
555 styles_lastit = styles.insert(std::pair<DrawStyle, VectorHandle>(c, style_handle)).first;
558 style_handle=(*styles_lastit).second;
559 //Now check if the handle is valid
560 if (!styles_ref_lastit_valid || (*styles_ref_lastit).first!=style_handle) {
561 styles_ref_lastit_valid=false;
562 styles_ref_lastit=styles_ref.find(style_handle);
565 if (styles_ref_lastit==styles_ref.end()) {
566 //invalid handle recreate
567 surfaces_mutex.Unlock();
568 style_handle=createStyleRef(c);
569 surfaces_mutex.Lock();
570 (*styles_lastit).second=style_handle;
571 } else styles_ref_lastit_valid=true;
573 styles_lastit_valid=true;
574 incStyleRef(style_handle);
575 surfaces_mutex.Unlock();
581 int OsdVector::getStyleRef(VectorHandle index)
583 if (!styles_ref_lastit_valid || (*styles_ref_lastit).first!=index) {
584 styles_ref_lastit_valid=false;
585 styles_ref_lastit=styles_ref.find(index);
587 if (styles_ref_lastit==styles_ref.end()) {
590 styles_ref_lastit_valid=true;
591 return (*styles_ref_lastit).second;
595 LoadIndex OsdVector::getTVMediaRef(TVMediaInfo& tvmedia, ImageIndex& image)
597 ImageIndex image_handle=0;
598 LoadIndex loadindex=0;
599 surfaces_mutex.Lock();
600 if (tvmedias.find(tvmedia)==tvmedias.end())
602 loadindex=loadTVMedia(tvmedia);
604 image_handle=tvmedias[tvmedia];
605 if (images_ref.find(image_handle)==images_ref.end()) {
606 //invalid handle recreate
607 loadindex=loadTVMedia(tvmedia);
610 incImageRef(image_handle);
613 /*tvmedias[tvmedia]=createTVMedia(tvmedia,width,height);
614 incImageRef(image_handle);*/
616 surfaces_mutex.Unlock();
620 LoadIndex OsdVector::loadTVMedia(TVMediaInfo& tvmedia)
624 if (tvmedias_load.find(tvmedia)==tvmedias_load.end())
626 switch (tvmedia.getType()) {
628 index=VDR::getInstance()->loadTVMediaRecThumb(tvmedia);
631 index = ((long long) tvmedia.getPrimaryID()) << 32LL;
632 reader.addStaticImage(tvmedia.getPrimaryID());
635 index=VDR::getInstance()->loadTVMediaEventThumb(tvmedia);
638 index=VDR::getInstance()->loadChannelLogo(tvmedia);
641 index=VDR::getInstance()->loadTVMedia(tvmedia);
644 if (tvmedia.getType()!=4 && tvmedia.getStaticFallback()>-1) {
645 reader.informFallback(index,tvmedia.getStaticFallback());
648 tvmedias_load[tvmedia]=index;
649 tvmedias_load_inv[index]=tvmedia;
651 index=tvmedias_load[tvmedia];
654 incLoadIndexRef(index);
661 void OsdVector::informPicture(LoadIndex index, ImageIndex imageIndex)
663 //Beware for thread safety
664 ImageIndex image_index=0;
666 Log::getInstance()->log("OsdVector", Log::DEBUG, "TVMedia Picture for request id %llx arrived %x",index, imageIndex);
667 surfaces_mutex.Lock();
668 TVMediaInfo tvmedia=tvmedias_load_inv[index];
670 map<LoadIndex,int>::iterator itty=loadindex_ref.find(index);
671 image_index=tvmedias[tvmedia]=imageIndex;
672 tvmedias_loaded[index]=image_index;
674 if (itty==loadindex_ref.end() || (*itty).second == 0) {
675 // we do not want the picture anymore . Really...
676 // fill images_ref in to not irritate the garbage collector
677 if (images_ref.find(image_index)==images_ref.end()) {
678 images_ref[image_index]=0;
681 incImageRef(image_index); // hold one index until all loadings refs are gone;
684 surfaces_mutex.Unlock();
693 ImageIndex OsdVector::getJpegRef(const char* fileName, int *width,int *height)
695 ImageIndex image_handle=0;
696 if (jpegs.find(fileName)==jpegs.end())
698 image_handle=jpegs[fileName]=createJpeg(fileName,width,height);
700 image_handle=jpegs[fileName];
703 if (images_ref.find(image_handle)==images_ref.end()) {
704 //invalid handle recreate
705 image_handle=jpegs[fileName]=createJpeg(fileName,width,height);
708 incImageRef(image_handle);
713 ImageIndex OsdVector::getMonoBitmapRef(void *base,int width,int height)
715 ImageIndex image_handle;
716 surfaces_mutex.Lock();
717 if (monobitmaps.find(base)==monobitmaps.end())
719 surfaces_mutex.Unlock();
720 image_handle=createMonoBitmap(base,width,height);
721 surfaces_mutex.Lock();
722 monobitmaps[base]=image_handle;
724 image_handle=monobitmaps[base];
725 if (images_ref.find(image_handle)==images_ref.end()) {
726 //invalid handle recreate
727 surfaces_mutex.Unlock();
728 image_handle=createMonoBitmap(base,width,height);
729 surfaces_mutex.Lock();
730 monobitmaps[base]=image_handle;
733 incImageRef(image_handle);
734 surfaces_mutex.Unlock();
738 ImageIndex OsdVector::getImagePalette(int width,int height,const unsigned char *image_data,const unsigned int*palette_data)
740 ImageIndex image_handle;
741 image_handle=createImagePalette(width,height,image_data,palette_data);
742 surfaces_mutex.Lock();
743 palettepics.push_back(image_handle);
744 incImageRef(image_handle);
745 surfaces_mutex.Unlock();
749 OsdVector::PictureReader::~PictureReader()
751 decoders_lock.Lock();
752 while ( decoders.size()) {
753 PictureDecoder* dec=decoders.front();
754 decoders.pop_front();
758 decoders_lock.Unlock();
761 void OsdVector::PictureReader::init()
766 void OsdVector::PictureReader::shutdown()
773 void OsdVector::PictureReader::addDecoder(PictureDecoder* decoder)
775 decoders_lock.Lock();
777 decoders.push_front(decoder);
778 decoders_lock.Unlock();
781 void OsdVector::PictureReader::removeDecoder(PictureDecoder* decoder)
783 decoders_lock.Lock();
784 std::list<PictureDecoder*>::iterator itty=decoders.begin();
785 while (itty!=decoders.end()) {
786 if ((*itty) == decoder)
788 decoders.erase(itty);
793 Log::getInstance()->log("OsdVector", Log::DEBUG, "removeDecoder");
796 decoders_lock.Unlock();
799 void OsdVector::PictureReader::threadMethod()
801 OsdVector *osdvector = dynamic_cast<OsdVector*>(Osd::getInstance());
802 Log::getInstance()->log("OsdVector", Log::DEBUG, "TVMedia Start Picture Reader");
804 if (!threadIsActive()) {
805 Log::getInstance()->log("OsdVector", Log::DEBUG, "TVMedia End Picture Reader");
814 decoders_lock.Lock();
815 std::list<PictureDecoder*>::iterator itty=decoders.begin();
817 while (itty!=decoders.end()) {
818 if ((*itty)->getDecodedPicture(pictinf)) {
820 osdvector->createPicture(pictinf);
825 if (processReceivedPictures())
830 decoders_lock.Unlock();
832 //Log::getInstance()->log("OsdVector", Log::DEBUG, "TVMedia Sleep Picture Reader");
834 struct timespec target_time;
835 getClockRealTime(&target_time);
837 target_time.tv_nsec+=1000000LL*10;
838 if (target_time.tv_nsec>999999999) {
839 target_time.tv_nsec-=1000000000L;
840 target_time.tv_sec+=1;
843 threadWaitForSignalTimed(&target_time);
845 //Log::getInstance()->log("OsdVector", Log::DEBUG, "TVMedia Sleep end Picture Reader");
849 void OsdVector::PictureReader::threadPostStopCleanup()
854 void OsdVector::PictureReader::invalidateLoadIndex(LoadIndex index)
856 pict_lock_incoming.Lock();
857 invalid_loadindex.insert(index);
858 pict_lock_incoming.Unlock();
861 void OsdVector::PictureReader::informFallback(LoadIndex index, int fallback)
863 pict_lock_incoming.Lock();
864 inform_fallback[index]=fallback;
865 pict_lock_incoming.Unlock();
868 void OsdVector::PictureReader::receivePicture(VDR_ResponsePacket *vresp)
870 pict_lock_incoming.Lock();
871 pict_incoming.push(vresp);
872 pict_lock_incoming.Unlock();
877 void OsdVector::PictureReader::addStaticImage(unsigned int id)
879 pict_lock_incoming.Lock();
880 pict_incoming_static.push(id);
881 invalid_loadindex.erase(((long long) id) << 32LL);
882 pict_lock_incoming.Unlock();
888 #pragma warning(disable : 4703)
891 bool OsdVector::PictureReader::processReceivedPictures()
893 bool decoded = false;
895 pict_lock_incoming.Lock();
896 if (pict_incoming.size()) {
897 VDR_ResponsePacket *vresp=pict_incoming.front();
899 set<LoadIndex>::iterator setpos = invalid_loadindex.find(vresp->getStreamID());
900 if (setpos != invalid_loadindex.end()) {
902 invalid_loadindex.erase(setpos);
904 pict_lock_incoming.Unlock();
905 if (!valid) { // we do not want it anymore skip it;
909 // Log::getInstance()->log("OsdVector", Log::DEBUG, "TVMedia Pictures arrived VDR %x %d %d",
910 // vresp->getStreamID(),vresp->getUserDataLength(),vresp->getFlag());
916 if (vresp->getFlag() != 2) {
917 userdata=vresp->getUserData();
918 length=vresp->getUserDataLength();
923 pict_lock_incoming.Lock();
924 if (inform_fallback.find(vresp->getStreamID())!=inform_fallback.end()) {
925 fallback=inform_fallback[vresp->getStreamID()];
927 pict_lock_incoming.Unlock();
928 if (fallback >= 0 && ((OsdVector*)Osd::getInstance())->getStaticImageData(fallback, &userdata, &length))
936 std::list<PictureDecoder*>::iterator itty=decoders.begin();
937 while (itty!=decoders.end()) {
938 userdata=(*itty)->decodePicture(vresp->getStreamID(), userdata, length, freed);
945 if (!decoded && userdata && freed){
949 pict_lock_incoming.Lock();
950 inform_fallback.erase(vresp->getStreamID());
951 pict_lock_incoming.Unlock();
952 //else osd->informPicture(vresp->getStreamID(), 0);
954 } else if (pict_incoming_static.size()){
955 unsigned int static_id = pict_incoming_static.front();
956 pict_incoming_static.pop();
957 set<LoadIndex>::iterator setpos = invalid_loadindex.find(((long long) static_id) << 32LL);
958 if (setpos != invalid_loadindex.end()) {
960 invalid_loadindex.erase(setpos);
962 pict_lock_incoming.Unlock();
963 if (!valid) { // we do not want it anymore skip it;
969 if (((OsdVector*)Osd::getInstance())->getStaticImageData(static_id, &userdata, &length))
971 std::list<PictureDecoder*>::iterator itty=decoders.begin();
972 while (itty!=decoders.end()) {
973 if (!(*itty)->decodePicture(((long long) static_id) << 32LL,userdata, length, false)){
981 pict_lock_incoming.Unlock();
985 if (pict_incoming.size() || pict_incoming_static.size()) return true;