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, see <https://www.gnu.org/licenses/>.
20 #include "osdvector.h"
21 #include "surfacevector.h"
23 #include "vdrresponsepacket.h"
27 // The next section is activated, if the magick++ PictureReader is provided, it should be available for many POSIX platforms
28 #ifdef PICTURE_DECODER_MAGICK
29 #define MAGICKCORE_QUANTUM_DEPTH 16
30 #define MAGICKCORE_HDRI_ENABLE 0
33 using namespace Magick;
35 class MagickDecoder: public OsdVector::PictureDecoder {
37 MagickDecoder(OsdVector::PictureReader* treader): OsdVector::PictureDecoder(treader) {pictInfValid=false;};
39 unsigned char *decodePicture(LoadIndex index, unsigned char * buffer, unsigned int length, bool freemem);
41 bool getDecodedPicture( struct OsdVector::PictureInfo& pict_inf);
43 void freeReference(void * ref);
46 OsdVector::PictureInfo pictInf;
50 unsigned char * MagickDecoder::decodePicture(LoadIndex index, unsigned char * buffer, unsigned int length, bool freemem)
52 if (pictInfValid) return buffer; // does support only one image at a Time;
54 Blob *imageblob = new Blob();
57 Log::getInstance()->log("MagickDecoder", Log::DEBUG, "decodePicture");
59 if (freemem) myblob.updateNoCopy(buffer,length,Blob::MallocAllocator);
60 else myblob.update(buffer,length);
61 magicimage.read(myblob);
63 magicimage.write(imageblob,"RGBA");
65 }catch( Exception &error_ )
67 Log::getInstance()->log("MagickDecoder", Log::DEBUG, "Libmagick: %s",error_.what());
69 Log::getInstance()->log("MagickDecoder", Log::DEBUG, "Libmagick: error mark2");
70 unsigned char* newbuffer=(unsigned char*) malloc(length);
71 memcpy(newbuffer,myblob.data(),length);
74 pictInf.reference = (void*) imageblob;
75 pictInf.width = magicimage.columns();
76 pictInf.height = magicimage.rows();
77 pictInf.image = imageblob->data();
78 pictInf.decoder = this;
79 pictInf.type = OsdVector::PictureInfo::RGBAMemBlock;
80 pictInf.lindex = index;
85 // I can handle everything, so the return value is always true
88 void MagickDecoder::freeReference(void * ref)
90 Blob *todelete = (Blob*) ref;
94 bool MagickDecoder::getDecodedPicture(struct OsdVector::PictureInfo& pict_inf)
96 if (!pictInfValid) return false;
105 OsdVector::OsdVector()
107 setlocale(LC_CTYPE,"C.UTF-8");
108 #ifdef PICTURE_DECODER_MAGICK
109 reader.addDecoder(new MagickDecoder(&reader));
112 for (int i=0;i<256;i++) {
113 byte_char_width[i]=0.f;
115 styles_lastit_valid=styles_ref_lastit_valid=false;
119 OsdVector::~OsdVector()
124 int OsdVector::getFD()
129 void OsdVector::screenShot(const char* fileName)
131 //Do nothing, if no libmagick is there
132 #ifdef PICTURE_DECODER_MAGICK
134 getRealScreenSize(width,height);
135 size_t length=width*height*4;
136 void *mem=malloc(length);
140 if (!screenShot(mem,width,height,true)) {
141 Log::getInstance()->log("OsdVector", Log::DEBUG, "Screenshot failed!");
145 myblob.updateNoCopy(mem,length,Blob::MallocAllocator);
146 Image image(myblob,Geometry(width,height),8,"RGBA");
147 image.write(fileName);
148 }catch( Exception &error_ )
150 Log::getInstance()->log("MagickEncoder", Log::DEBUG, "Libmagick: %s",error_.what());
157 Surface * OsdVector::createNewSurface()
159 return new SurfaceVector(this);
163 void OsdVector::Blank()
165 // do nothing? remove this one?
168 int OsdVector::restore()
170 // First clear the contents of all registered surfaces
171 surfaces_mutex.lock();
173 //Now go through all surfaces and draw them
174 std::list<SurfaceCommands>::iterator curdraw=scommands.begin();
175 while (curdraw!=scommands.end()) {
176 (*curdraw).commands.clear();
177 (*curdraw).commands.reserve(2048);
180 //also clear all handles, they are now invalid, no need to release them
186 styles_lastit_valid=styles_ref_lastit_valid=false;
190 loadindex_ref.clear();
191 tvmedias_load.clear();
192 tvmedias_load_inv.clear();
193 tvmedias_loaded.clear();
195 surfaces_mutex.unlock();
199 void OsdVector::drawSurfaces()
201 surfaces_mutex.lock();
202 std::list<SurfaceCommands*> todraw; //First figure out if a surfaces is below another surface
203 std::list<SurfaceCommands>::iterator itty1=scommands.begin();
204 while (itty1!=scommands.end()) {
205 std::list<SurfaceCommands>::iterator itty2=itty1;
208 while (itty2!=scommands.end()) {
209 SurfaceCommands & ref1=*itty1;
210 SurfaceCommands & ref2=*itty2;
211 if (ref1.x>=ref2.x && ref1.y>=ref2.y
212 && (ref1.x+ref1.w) <= (ref2.x+ref2.w)
213 && (ref1.y+ref1.h) <= (ref2.y+ref2.h) ) {
219 if (!hidden) { // we are not hidden, perfect
220 todraw.push_back(&(*itty1));
225 getScreenSize(swidth,sheight);
226 //Now go through all surfaces and draw them
227 std::list<SurfaceCommands*>::iterator curdraw=todraw.begin();
228 while (curdraw!=todraw.end()) {
229 drawSetTrans(*(*curdraw));
230 std::vector<SVGCommand>::iterator commands=(*(*curdraw)).commands.begin();
231 std::vector<SVGCommand>::iterator end=(*(*curdraw)).commands.end();
232 while (commands!=end) {
233 // update any images loaded in the mean time
234 if ((*commands).instr==DrawImageLoading) {
235 LoadIndex loadindex=(*commands).target.loadindex;
236 if (tvmedias_loaded.find(loadindex)!=tvmedias_loaded.end()) {
237 (*commands).instr=DrawImage;
238 (*commands).target.image=tvmedias_loaded[loadindex];;
239 incImageRef((*commands).target.image);
240 removeLoadIndexRef(loadindex);
244 // Now check if the command is on screen!
245 if (!(*commands).Outside(0,0,swidth,sheight)) {
246 executeDrawCommand(*commands);
253 surfaces_mutex.unlock();
256 void OsdVector::updateOrAddSurface(const SurfaceVector *surf,float x,float y,float height,float width,
257 std::vector<SVGCommand>& commands)
259 surfaces_mutex.lock();
260 //First determine it is already in our system
261 std::list<SurfaceCommands>::iterator itty=scommands.begin();
262 while (itty!=scommands.end()) {
263 if ((*itty).surf==surf) {
264 //decrease the references
265 dereferenceSVGCommand((*itty).commands);
271 if (itty==scommands.end()) {
272 SurfaceCommands new_sc;
278 itty=scommands.insert(itty,new_sc);
280 // update any images loaded in the mean time
281 std::vector<SVGCommand>::iterator ilitty=commands.begin();
283 while (ilitty!=commands.end())
285 if ((*ilitty).instr==DrawImageLoading) {
286 LoadIndex loadindex=(*ilitty).target.loadindex;
287 if (tvmedias_loaded.find(loadindex)!=tvmedias_loaded.end()) {
289 (*ilitty).instr=DrawImage;
290 (*ilitty).target.image=tvmedias_loaded[loadindex];
291 incImageRef((*ilitty).target.image);
292 removeLoadIndexRef(loadindex);
299 // then clear and copy
300 (*itty).commands.clear();
301 (*itty).commands=commands;
302 //increase the references
303 referenceSVGCommand((*itty).commands);
304 cleanupOrphanedRefs();
306 surfaces_mutex.unlock();
309 void OsdVector::removeSurface(const SurfaceVector *surf)
311 surfaces_mutex.lock();
312 //First determine it is already in our system
313 std::list<SurfaceCommands>::iterator itty=scommands.begin();
314 while (itty!=scommands.end()) {
315 if ((*itty).surf==surf) {
316 dereferenceSVGCommand((*itty).commands);
317 (*itty).commands.clear();
318 scommands.erase(itty);
323 surfaces_mutex.unlock();
327 void OsdVector::dereferenceSVGCommand(std::vector<SVGCommand>& commands )
330 std::vector<SVGCommand>::iterator sitty = commands.begin();
331 while (sitty != commands.end()) {
332 removeStyleRef((*sitty).getRef());
333 ImageIndex ii = (*sitty).getImageIndex();
334 if (ii) removeImageRef(ii);
335 LoadIndex li=(*sitty).getLoadIndex();
336 if (li) removeLoadIndexRef(li);
341 void OsdVector::referenceSVGCommand(std::vector<SVGCommand>& commands )
343 std::vector<SVGCommand>::iterator sitty=commands.begin();
344 while (sitty!=commands.end())
346 incStyleRef((*sitty).getRef());
347 ImageIndex ii=(*sitty).getImageIndex();
348 if (ii) incImageRef(ii);
349 LoadIndex li=(*sitty).getLoadIndex();
350 if (li) incLoadIndexRef(li);
356 void OsdVector::incImageRef(ImageIndex index)
358 if (images_ref.find(index)==images_ref.end()) {
365 void OsdVector::removeImageRef(const ImageIndex ref)
370 int OsdVector::getLoadIndexRef(LoadIndex index)
372 surfaces_mutex.lock();
373 if (loadindex_ref.find(index)==loadindex_ref.end()) {
376 return loadindex_ref[index];
378 surfaces_mutex.unlock();
381 void OsdVector::incLoadIndexRef(LoadIndex index)
383 if (loadindex_ref.find(index)==loadindex_ref.end()) {
384 loadindex_ref[index]=1;
386 loadindex_ref[index]++;
390 void OsdVector::removeLoadIndexRef(const LoadIndex ref)
392 loadindex_ref[ref]--;
393 if (loadindex_ref[ref]==0) {
394 //now check, if it is already loaded
395 std::map<LoadIndex,ImageIndex>::iterator itty=tvmedias_loaded.find(ref);
396 if ( itty != tvmedias_loaded.end()) {
397 removeImageRef((*itty).second); // remove lock
399 tvmedias_loaded.erase(ref);
400 // Log::getInstance()->log("OsdVector", Log::DEBUG, "TVMedia removeLoadIndexRef %d %llx",tvmedias_load.size(),ref);
401 tvmedias_load.erase(tvmedias_load_inv[ref]);
402 tvmedias_load_inv.erase(ref);
404 reader.invalidateLoadIndex(ref);
412 void OsdVector::cleanupOrphanedRefs()
413 { // Do some garbage collection
415 std::map<void *,ImageIndex>::iterator mitty=monobitmaps.begin();
416 while (mitty!=monobitmaps.end()) {
417 std::map<ImageIndex,int>::iterator curitty=images_ref.find((*mitty).second);
418 int count=(*curitty).second;
420 ImageIndex ref=(*curitty).first;
421 monobitmaps.erase(mitty++);
422 images_ref.erase(curitty++);
423 destroyImageRef(ref);
427 /*map<string,ImageIndex>::iterator jitty=jpegs.begin();
428 while (jitty!=jpegs.end()) {
429 map<ImageIndex,int>::iterator curitty=images_ref.find((*jitty).second);
430 int count=(*curitty).second;
432 ImageIndex ref=(*curitty).first;
433 jpegs.erase(jitty++);
434 images_ref.erase(curitty++);
435 destroyImageRef(ref);
439 std::map<TVMediaInfo,ImageIndex>::iterator titty=tvmedias.begin();
440 while (titty!=tvmedias.end()) {
441 std::map<ImageIndex,int>::iterator curitty=images_ref.find((*titty).second);
442 int count=(*curitty).second;
444 ImageIndex ref=(*curitty).first;
445 tvmedias.erase(titty++);
446 images_ref.erase(curitty);
447 destroyImageRef(ref);
452 std::map<TVMediaInfo,LoadIndex>::iterator litty=tvmedias_load.begin();
453 while (litty!=tvmedias_load.end()) {
454 std::map<LoadIndex,int>::iterator curitty=loadindex_ref.find((*litty).second);
455 int count=(*curitty).second;
457 tvmedias_load_inv.erase((*litty).second);
458 tvmedias_loaded.erase((*litty).second);
459 tvmedias_load.erase(litty++);
463 std::list<ImageIndex>::iterator pitty=palettepics.begin();
464 while (pitty!=palettepics.end()) {
465 std::map<ImageIndex,int>::iterator curitty=images_ref.find((*pitty));
466 int count=(*curitty).second;
468 ImageIndex ref=(*curitty).first;
469 palettepics.erase(pitty++);
470 images_ref.erase(curitty++);
471 destroyImageRef(ref);
475 std::map<ImageIndex,int>::iterator citty=images_ref.begin();
476 while (citty!=images_ref.end()) {
477 int count=(*citty).second;
479 ImageIndex ref=(*citty).first;
480 images_ref.erase(citty++);
481 destroyImageRef(ref);
486 std::map<DrawStyle, VectorHandle>::iterator sitty = styles.begin();
487 while (sitty!=styles.end()) {
488 std::map<VectorHandle, int>::iterator curitty = styles_ref.find((*sitty).second);
489 int count=(*curitty).second;
491 VectorHandle ref = (*curitty).first;
492 styles.erase(sitty++);
493 styles_ref.erase(curitty++);
494 styles_lastit_valid=styles_ref_lastit_valid=false;
495 destroyStyleRef(ref);
503 int OsdVector::getImageRef(ImageIndex index)
505 surfaces_mutex.lock();
506 if (images_ref.find(index)==images_ref.end()) {
509 return images_ref[index];
511 surfaces_mutex.unlock();
514 void OsdVector::incStyleRef(VectorHandle index)
516 if (!styles_ref_lastit_valid || (*styles_ref_lastit).first!=index) {
517 styles_ref_lastit_valid=false;
518 styles_ref_lastit=styles_ref.find(index);
520 if (styles_ref_lastit==styles_ref.end()) {
521 styles_ref_lastit = styles_ref.insert(std::pair<VectorHandle, int>(index, 1)).first;
523 (*styles_ref_lastit).second++;
525 styles_ref_lastit_valid=true;
528 void OsdVector::removeStyleRef(VectorHandle index)
530 if (!styles_ref_lastit_valid || (*styles_ref_lastit).first!=index) {
531 styles_ref_lastit_valid=false;
532 styles_ref_lastit=styles_ref.find(index);
534 if (styles_ref_lastit!=styles_ref.end()) {
535 styles_ref_lastit_valid=true;
536 (*styles_ref_lastit).second--;
540 VectorHandle OsdVector::getStyleRef(const DrawStyle &c)
542 surfaces_mutex.lock();
543 VectorHandle style_handle = 0;
544 if (!styles_lastit_valid || (*styles_lastit).first!=c) {
545 styles_lastit_valid=false;
546 styles_lastit=styles.find(c);
549 if (styles_lastit==styles.end())
551 surfaces_mutex.unlock();
552 style_handle=createStyleRef(c);
553 surfaces_mutex.lock();
554 styles_lastit = styles.insert(std::pair<DrawStyle, VectorHandle>(c, style_handle)).first;
557 style_handle=(*styles_lastit).second;
558 //Now check if the handle is valid
559 if (!styles_ref_lastit_valid || (*styles_ref_lastit).first!=style_handle) {
560 styles_ref_lastit_valid=false;
561 styles_ref_lastit=styles_ref.find(style_handle);
564 if (styles_ref_lastit==styles_ref.end()) {
565 //invalid handle recreate
566 surfaces_mutex.unlock();
567 style_handle=createStyleRef(c);
568 surfaces_mutex.lock();
569 (*styles_lastit).second=style_handle;
570 } else styles_ref_lastit_valid=true;
572 styles_lastit_valid=true;
573 incStyleRef(style_handle);
574 surfaces_mutex.unlock();
580 int OsdVector::getStyleRef(VectorHandle index)
582 if (!styles_ref_lastit_valid || (*styles_ref_lastit).first!=index) {
583 styles_ref_lastit_valid=false;
584 styles_ref_lastit=styles_ref.find(index);
586 if (styles_ref_lastit==styles_ref.end()) {
589 styles_ref_lastit_valid=true;
590 return (*styles_ref_lastit).second;
594 LoadIndex OsdVector::getTVMediaRef(TVMediaInfo& tvmedia, ImageIndex& image)
596 ImageIndex image_handle=0;
597 LoadIndex loadindex=0;
598 surfaces_mutex.lock();
599 if (tvmedias.find(tvmedia)==tvmedias.end())
601 loadindex=loadTVMedia(tvmedia);
603 image_handle=tvmedias[tvmedia];
604 if (images_ref.find(image_handle)==images_ref.end()) {
605 //invalid handle recreate
606 loadindex=loadTVMedia(tvmedia);
609 incImageRef(image_handle);
612 /*tvmedias[tvmedia]=createTVMedia(tvmedia,width,height);
613 incImageRef(image_handle);*/
615 surfaces_mutex.unlock();
619 LoadIndex OsdVector::loadTVMedia(TVMediaInfo& tvmedia)
623 if (tvmedias_load.find(tvmedia)==tvmedias_load.end())
625 switch (tvmedia.getType()) {
627 index=VDR::getInstance()->loadTVMediaRecThumb(tvmedia);
630 index = ((long long) tvmedia.getPrimaryID()) << 32LL;
631 reader.addStaticImage(tvmedia.getPrimaryID());
634 index=VDR::getInstance()->loadTVMediaEventThumb(tvmedia);
637 index=VDR::getInstance()->loadChannelLogo(tvmedia);
640 index=VDR::getInstance()->loadTVMedia(tvmedia);
643 if (tvmedia.getType()!=4 && tvmedia.getStaticFallback()>-1) {
644 reader.informFallback(index,tvmedia.getStaticFallback());
647 tvmedias_load[tvmedia]=index;
648 tvmedias_load_inv[index]=tvmedia;
650 index=tvmedias_load[tvmedia];
653 incLoadIndexRef(index);
660 void OsdVector::informPicture(LoadIndex index, ImageIndex imageIndex)
662 //Beware for thread safety
663 ImageIndex image_index=0;
665 Log::getInstance()->log("OsdVector", Log::DEBUG, "TVMedia Picture for request id %llx arrived %x",index, imageIndex);
666 surfaces_mutex.lock();
667 TVMediaInfo tvmedia=tvmedias_load_inv[index];
669 std::map<LoadIndex,int>::iterator itty=loadindex_ref.find(index);
670 image_index=tvmedias[tvmedia]=imageIndex;
671 tvmedias_loaded[index]=image_index;
673 if (itty==loadindex_ref.end() || (*itty).second == 0) {
674 // we do not want the picture anymore . Really...
675 // fill images_ref in to not irritate the garbage collector
676 if (images_ref.find(image_index)==images_ref.end()) {
677 images_ref[image_index]=0;
680 incImageRef(image_index); // hold one index until all loadings refs are gone;
683 surfaces_mutex.unlock();
692 ImageIndex OsdVector::getJpegRef(const char* fileName, int *width,int *height)
694 ImageIndex image_handle=0;
695 if (jpegs.find(fileName)==jpegs.end())
697 image_handle=jpegs[fileName]=createJpeg(fileName,width,height);
699 image_handle=jpegs[fileName];
702 if (images_ref.find(image_handle)==images_ref.end()) {
703 //invalid handle recreate
704 image_handle=jpegs[fileName]=createJpeg(fileName,width,height);
707 incImageRef(image_handle);
712 ImageIndex OsdVector::getMonoBitmapRef(void *base,int width,int height)
714 ImageIndex image_handle;
715 surfaces_mutex.lock();
716 if (monobitmaps.find(base)==monobitmaps.end())
718 surfaces_mutex.unlock();
719 image_handle=createMonoBitmap(base,width,height);
720 surfaces_mutex.lock();
721 monobitmaps[base]=image_handle;
723 image_handle=monobitmaps[base];
724 if (images_ref.find(image_handle)==images_ref.end()) {
725 //invalid handle recreate
726 surfaces_mutex.unlock();
727 image_handle=createMonoBitmap(base,width,height);
728 surfaces_mutex.lock();
729 monobitmaps[base]=image_handle;
732 incImageRef(image_handle);
733 surfaces_mutex.unlock();
737 ImageIndex OsdVector::getImagePalette(int width,int height,const unsigned char *image_data,const unsigned int*palette_data)
739 ImageIndex image_handle;
740 image_handle=createImagePalette(width,height,image_data,palette_data);
741 surfaces_mutex.lock();
742 palettepics.push_back(image_handle);
743 incImageRef(image_handle);
744 surfaces_mutex.unlock();
748 OsdVector::PictureReader::~PictureReader()
750 decoders_lock.lock();
751 while ( decoders.size()) {
752 PictureDecoder* dec=decoders.front();
753 decoders.pop_front();
757 decoders_lock.unlock();
760 void OsdVector::PictureReader::init()
765 void OsdVector::PictureReader::shutdown()
772 void OsdVector::PictureReader::addDecoder(PictureDecoder* decoder)
774 decoders_lock.lock();
776 decoders.push_front(decoder);
777 decoders_lock.unlock();
780 void OsdVector::PictureReader::removeDecoder(PictureDecoder* decoder)
782 decoders_lock.lock();
783 std::list<PictureDecoder*>::iterator itty=decoders.begin();
784 while (itty!=decoders.end()) {
785 if ((*itty) == decoder)
787 decoders.erase(itty);
792 Log::getInstance()->log("OsdVector", Log::DEBUG, "removeDecoder");
795 decoders_lock.unlock();
798 void OsdVector::PictureReader::threadMethod()
800 OsdVector *osdvector = dynamic_cast<OsdVector*>(Osd::getInstance());
801 Log::getInstance()->log("OsdVector", Log::DEBUG, "TVMedia Start Picture Reader");
803 if (!threadIsActive()) {
804 Log::getInstance()->log("OsdVector", Log::DEBUG, "TVMedia End Picture Reader");
813 decoders_lock.lock();
814 std::list<PictureDecoder*>::iterator itty=decoders.begin();
816 while (itty!=decoders.end()) {
817 if ((*itty)->getDecodedPicture(pictinf)) {
819 osdvector->createPicture(pictinf);
824 if (processReceivedPictures())
829 decoders_lock.unlock();
831 //Log::getInstance()->log("OsdVector", Log::DEBUG, "TVMedia Sleep Picture Reader");
833 struct timespec target_time;
834 getClockRealTime(&target_time);
836 target_time.tv_nsec+=1000000LL*10;
837 if (target_time.tv_nsec>999999999) {
838 target_time.tv_nsec-=1000000000L;
839 target_time.tv_sec+=1;
842 threadWaitForSignalTimed(&target_time);
844 //Log::getInstance()->log("OsdVector", Log::DEBUG, "TVMedia Sleep end Picture Reader");
848 void OsdVector::PictureReader::invalidateLoadIndex(LoadIndex index)
850 pict_lock_incoming.lock();
851 invalid_loadindex.insert(index);
852 pict_lock_incoming.unlock();
855 void OsdVector::PictureReader::informFallback(LoadIndex index, int fallback)
857 pict_lock_incoming.lock();
858 inform_fallback[index]=fallback;
859 pict_lock_incoming.unlock();
862 void OsdVector::PictureReader::receivePicture(VDR_ResponsePacket *vresp)
864 pict_lock_incoming.lock();
865 pict_incoming.push(vresp);
866 pict_lock_incoming.unlock();
871 void OsdVector::PictureReader::addStaticImage(unsigned int id)
873 pict_lock_incoming.lock();
874 pict_incoming_static.push(id);
875 invalid_loadindex.erase(((long long) id) << 32LL);
876 pict_lock_incoming.unlock();
882 #pragma warning(disable : 4703)
885 bool OsdVector::PictureReader::processReceivedPictures()
887 bool decoded = false;
889 pict_lock_incoming.lock();
890 if (pict_incoming.size()) {
891 VDR_ResponsePacket *vresp=pict_incoming.front();
893 std::set<LoadIndex>::iterator setpos = invalid_loadindex.find(vresp->getStreamID());
894 if (setpos != invalid_loadindex.end()) {
896 invalid_loadindex.erase(setpos);
898 pict_lock_incoming.unlock();
899 if (!valid) { // we do not want it anymore skip it;
903 // Log::getInstance()->log("OsdVector", Log::DEBUG, "TVMedia Pictures arrived VDR %x %d %d",
904 // vresp->getStreamID(),vresp->getUserDataLength(),vresp->getFlag());
910 if (vresp->getFlag() != 2) {
911 userdata=vresp->getUserData();
912 length=vresp->getUserDataLength();
917 pict_lock_incoming.lock();
918 if (inform_fallback.find(vresp->getStreamID())!=inform_fallback.end()) {
919 fallback=inform_fallback[vresp->getStreamID()];
921 pict_lock_incoming.unlock();
922 if (fallback >= 0 && ((OsdVector*)Osd::getInstance())->getStaticImageData(fallback, &userdata, &length))
930 std::list<PictureDecoder*>::iterator itty=decoders.begin();
931 while (itty!=decoders.end()) {
932 userdata=(*itty)->decodePicture(vresp->getStreamID(), userdata, length, freed);
939 if (!decoded && userdata && freed){
943 pict_lock_incoming.lock();
944 inform_fallback.erase(vresp->getStreamID());
945 pict_lock_incoming.unlock();
946 //else osd->informPicture(vresp->getStreamID(), 0);
948 } else if (pict_incoming_static.size()){
949 unsigned int static_id = pict_incoming_static.front();
950 pict_incoming_static.pop();
951 std::set<LoadIndex>::iterator setpos = invalid_loadindex.find(((long long) static_id) << 32LL);
952 if (setpos != invalid_loadindex.end()) {
954 invalid_loadindex.erase(setpos);
956 pict_lock_incoming.unlock();
957 if (!valid) { // we do not want it anymore skip it;
963 if (((OsdVector*)Osd::getInstance())->getStaticImageData(static_id, &userdata, &length))
965 std::list<PictureDecoder*>::iterator itty=decoders.begin();
966 while (itty!=decoders.end()) {
967 if (!(*itty)->decodePicture(((long long) static_id) << 32LL,userdata, length, false)){
975 pict_lock_incoming.unlock();
979 if (pict_incoming.size() || pict_incoming_static.size()) return true;