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
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;
56 Blob* imageblob = new Blob();
61 Log::getInstance()->log("MagickDecoder", Log::DEBUG, "decodePicture");
63 if (freemem) myblob.updateNoCopy(buffer, length, Blob::MallocAllocator);
64 else myblob.update(buffer, length);
66 magicimage.read(myblob);
68 magicimage.write(imageblob, "RGBA");
71 catch ( Exception& error_ )
73 Log::getInstance()->log("MagickDecoder", Log::DEBUG, "Libmagick: %s", error_.what());
75 Log::getInstance()->log("MagickDecoder", Log::DEBUG, "Libmagick: error mark2");
76 unsigned char* newbuffer = (unsigned char*) malloc(length);
77 memcpy(newbuffer, myblob.data(), length);
81 pictInf.reference = (void*) imageblob;
82 pictInf.width = magicimage.columns();
83 pictInf.height = magicimage.rows();
84 pictInf.image = imageblob->data();
85 pictInf.decoder = this;
86 pictInf.type = OsdVector::PictureInfo::RGBAMemBlock;
87 pictInf.lindex = index;
92 // I can handle everything, so the return value is always true
95 void MagickDecoder::freeReference(void* ref)
97 Blob* todelete = (Blob*) ref;
101 bool MagickDecoder::getDecodedPicture(struct OsdVector::PictureInfo& pict_inf)
103 if (!pictInfValid) return false;
106 pictInfValid = false;
113 OsdVector::OsdVector()
115 setlocale(LC_CTYPE, "C.UTF-8");
116 #ifdef PICTURE_DECODER_MAGICK
117 reader.addDecoder(new MagickDecoder(&reader));
120 for (int i = 0; i < 256; i++)
122 byte_char_width[i] = 0.f;
125 styles_lastit_valid = styles_ref_lastit_valid = false;
128 void OsdVector::screenShot(const char* fileName)
130 //Do nothing, if no libmagick is there
131 #ifdef PICTURE_DECODER_MAGICK
133 getRealScreenSize(width, height);
134 size_t length = width * height * 4;
135 void* mem = malloc(length);
141 if (!screenShot(mem, width, height, true))
143 Log::getInstance()->log("OsdVector", Log::DEBUG, "Screenshot failed!");
148 myblob.updateNoCopy(mem, length, Blob::MallocAllocator);
149 Image image(myblob, Geometry(width, height), 8, "RGBA");
150 image.write(fileName);
152 catch ( Exception& error_ )
154 Log::getInstance()->log("MagickEncoder", Log::DEBUG, "Libmagick: %s", error_.what());
161 Surface* OsdVector::createNewSurface()
163 return new SurfaceVector(this);
167 void OsdVector::Blank()
169 // do nothing? remove this one?
172 int OsdVector::restore()
174 // First clear the contents of all registered surfaces
175 surfaces_mutex.lock();
177 //Now go through all surfaces and draw them
178 std::list<SurfaceInfo>::iterator curdraw = surfaces.begin();
180 while (curdraw != surfaces.end())
182 (*curdraw).commands.clear();
183 (*curdraw).commands.reserve(2048);
187 //also clear all handles, they are now invalid, no need to release them
193 styles_lastit_valid = styles_ref_lastit_valid = false;
197 loadindex_ref.clear();
198 tvmedias_load.clear();
199 tvmedias_load_inv.clear();
200 tvmedias_loaded.clear();
202 surfaces_mutex.unlock();
206 void OsdVector::drawSurfaces()
208 surfaces_mutex.lock();
209 std::list<SurfaceInfo*> todraw; //First figure out if a surfaces is below another surface
210 std::list<SurfaceInfo>::iterator itty1 = surfaces.begin();
212 while (itty1 != surfaces.end())
214 std::list<SurfaceInfo>::iterator itty2 = itty1;
218 while (itty2 != surfaces.end())
220 SurfaceInfo& ref1 = *itty1;
221 SurfaceInfo& ref2 = *itty2;
223 if (ref1.x >= ref2.x && ref1.y >= ref2.y
224 && (ref1.x + ref1.w) <= (ref2.x + ref2.w)
225 && (ref1.y + ref1.h) <= (ref2.y + ref2.h) )
234 if (!hidden) // we are not hidden, perfect
236 todraw.push_back(&(*itty1));
243 getScreenSize(swidth, sheight);
244 //Now go through all surfaces and draw them
245 std::list<SurfaceInfo*>::iterator curdraw = todraw.begin();
247 while (curdraw != todraw.end())
249 drawSetTrans(*(*curdraw));
250 std::vector<SVGCommand>::iterator commands = (*(*curdraw)).commands.begin();
251 std::vector<SVGCommand>::iterator end = (*(*curdraw)).commands.end();
253 while (commands != end)
255 // update any images loaded in the mean time
256 if ((*commands).instr == DrawImageLoading)
258 LoadIndex loadindex = (*commands).target.loadindex;
260 if (tvmedias_loaded.find(loadindex) != tvmedias_loaded.end())
262 (*commands).instr = DrawImage;
263 (*commands).target.image = tvmedias_loaded[loadindex];;
264 incImageRef((*commands).target.image);
265 removeLoadIndexRef(loadindex);
270 // Now check if the command is on screen!
271 if (!(*commands).Outside(0, 0, swidth, sheight))
273 executeDrawCommand(*commands);
282 surfaces_mutex.unlock();
285 void OsdVector::updateOrAddSurface(const SurfaceVector* surf, float x, float y, float height, float width,
286 std::vector<SVGCommand>& commands)
288 surfaces_mutex.lock();
289 //First determine it is already in our system
290 std::list<SurfaceInfo>::iterator itty = surfaces.begin();
292 while (itty != surfaces.end())
294 if ((*itty).surf == surf)
296 //decrease the references
297 decrementAllRefCounts((*itty).commands);
305 if (itty == surfaces.end())
313 itty = surfaces.insert(itty, new_sc);
316 // update any images loaded in the mean time
317 std::vector<SVGCommand>::iterator ilitty = commands.begin();
319 while (ilitty != commands.end())
321 if ((*ilitty).instr == DrawImageLoading)
323 LoadIndex loadindex = (*ilitty).target.loadindex;
325 if (tvmedias_loaded.find(loadindex) != tvmedias_loaded.end())
328 (*ilitty).instr = DrawImage;
329 (*ilitty).target.image = tvmedias_loaded[loadindex];
330 incImageRef((*ilitty).target.image);
331 removeLoadIndexRef(loadindex);
339 // then clear and copy
340 (*itty).commands.clear();
341 (*itty).commands = commands;
342 //increase the references
343 incrementAllRefCounts((*itty).commands);
344 cleanupOrphanedRefs();
346 surfaces_mutex.unlock();
349 void OsdVector::removeSurface(const SurfaceVector* surf)
351 surfaces_mutex.lock();
352 //First determine it is already in our system
353 std::list<SurfaceInfo>::iterator itty = surfaces.begin();
355 while (itty != surfaces.end())
357 if ((*itty).surf == surf)
359 decrementAllRefCounts((*itty).commands);
360 (*itty).commands.clear();
361 surfaces.erase(itty);
368 surfaces_mutex.unlock();
372 void OsdVector::decrementAllRefCounts(std::vector<SVGCommand>& commands )
375 std::vector<SVGCommand>::iterator sitty = commands.begin();
377 while (sitty != commands.end())
379 removeStyleRef((*sitty).getRef());
380 ImageIndex ii = (*sitty).getImageIndex();
382 if (ii) removeImageRef(ii);
384 LoadIndex li = (*sitty).getLoadIndex();
386 if (li) removeLoadIndexRef(li);
392 void OsdVector::incrementAllRefCounts(std::vector<SVGCommand>& commands )
394 std::vector<SVGCommand>::iterator sitty = commands.begin();
396 while (sitty != commands.end())
398 incStyleRef((*sitty).getRef());
399 ImageIndex ii = (*sitty).getImageIndex();
401 if (ii) incImageRef(ii);
403 LoadIndex li = (*sitty).getLoadIndex();
405 if (li) incLoadIndexRef(li);
412 void OsdVector::incImageRef(ImageIndex index)
414 if (images_ref.find(index) == images_ref.end())
416 images_ref[index] = 1;
424 void OsdVector::removeImageRef(const ImageIndex ref)
429 int OsdVector::getLoadIndexRef(LoadIndex index)
431 surfaces_mutex.lock();
433 if (loadindex_ref.find(index) == loadindex_ref.end())
439 return loadindex_ref[index];
442 surfaces_mutex.unlock();
445 void OsdVector::incLoadIndexRef(LoadIndex index)
447 if (loadindex_ref.find(index) == loadindex_ref.end())
449 loadindex_ref[index] = 1;
453 loadindex_ref[index]++;
457 void OsdVector::removeLoadIndexRef(const LoadIndex ref)
459 loadindex_ref[ref]--;
461 if (loadindex_ref[ref] == 0)
463 //now check, if it is already loaded
464 std::map<LoadIndex, ImageIndex>::iterator itty = tvmedias_loaded.find(ref);
466 if ( itty != tvmedias_loaded.end())
468 removeImageRef((*itty).second); // remove lock
471 tvmedias_loaded.erase(ref);
472 // Log::getInstance()->log("OsdVector", Log::DEBUG, "TVMedia removeLoadIndexRef %d %llx",tvmedias_load.size(),ref);
473 tvmedias_load.erase(tvmedias_load_inv[ref]);
474 tvmedias_load_inv.erase(ref);
476 reader.invalidateLoadIndex(ref);
484 void OsdVector::cleanupOrphanedRefs()
486 // Do some garbage collection
488 std::map<void*, ImageIndex>::iterator mitty = monobitmaps.begin();
490 while (mitty != monobitmaps.end())
492 std::map<ImageIndex, int>::iterator curitty = images_ref.find((*mitty).second);
493 int count = (*curitty).second;
497 ImageIndex ref = (*curitty).first;
498 monobitmaps.erase(mitty++);
499 images_ref.erase(curitty++);
500 destroyImageRef(ref);
505 /*map<string,ImageIndex>::iterator jitty=jpegs.begin();
506 while (jitty!=jpegs.end()) {
507 map<ImageIndex,int>::iterator curitty=images_ref.find((*jitty).second);
508 int count=(*curitty).second;
510 ImageIndex ref=(*curitty).first;
511 jpegs.erase(jitty++);
512 images_ref.erase(curitty++);
513 destroyImageRef(ref);
517 std::map<TVMediaInfo, ImageIndex>::iterator titty = tvmedias.begin();
519 while (titty != tvmedias.end())
521 std::map<ImageIndex, int>::iterator curitty = images_ref.find((*titty).second);
522 int count = (*curitty).second;
526 ImageIndex ref = (*curitty).first;
527 tvmedias.erase(titty++);
528 images_ref.erase(curitty);
529 destroyImageRef(ref);
535 std::map<TVMediaInfo, LoadIndex>::iterator litty = tvmedias_load.begin();
537 while (litty != tvmedias_load.end())
539 std::map<LoadIndex, int>::iterator curitty = loadindex_ref.find((*litty).second);
540 int count = (*curitty).second;
544 tvmedias_load_inv.erase((*litty).second);
545 tvmedias_loaded.erase((*litty).second);
546 tvmedias_load.erase(litty++);
551 std::list<ImageIndex>::iterator pitty = palettepics.begin();
553 while (pitty != palettepics.end())
555 std::map<ImageIndex, int>::iterator curitty = images_ref.find((*pitty));
556 int count = (*curitty).second;
560 ImageIndex ref = (*curitty).first;
561 palettepics.erase(pitty++);
562 images_ref.erase(curitty++);
563 destroyImageRef(ref);
568 std::map<ImageIndex, int>::iterator citty = images_ref.begin();
570 while (citty != images_ref.end())
572 int count = (*citty).second;
576 ImageIndex ref = (*citty).first;
577 images_ref.erase(citty++);
578 destroyImageRef(ref);
584 std::map<DrawStyle, VectorHandle>::iterator sitty = styles.begin();
586 while (sitty != styles.end())
588 std::map<VectorHandle, int>::iterator curitty = styles_ref.find((*sitty).second);
589 int count = (*curitty).second;
593 VectorHandle ref = (*curitty).first;
594 styles.erase(sitty++);
595 styles_ref.erase(curitty++);
596 styles_lastit_valid = styles_ref_lastit_valid = false;
597 destroyStyleRef(ref);
606 int OsdVector::getImageRef(ImageIndex index)
608 surfaces_mutex.lock();
610 if (images_ref.find(index) == images_ref.end())
616 return images_ref[index];
619 surfaces_mutex.unlock();
622 void OsdVector::incStyleRef(VectorHandle index)
624 if (!styles_ref_lastit_valid || (*styles_ref_lastit).first != index)
626 styles_ref_lastit_valid = false;
627 styles_ref_lastit = styles_ref.find(index);
630 if (styles_ref_lastit == styles_ref.end())
632 styles_ref_lastit = styles_ref.insert(std::pair<VectorHandle, int>(index, 1)).first;
636 (*styles_ref_lastit).second++;
639 styles_ref_lastit_valid = true;
642 void OsdVector::removeStyleRef(VectorHandle index)
644 if (!styles_ref_lastit_valid || (*styles_ref_lastit).first != index)
646 styles_ref_lastit_valid = false;
647 styles_ref_lastit = styles_ref.find(index);
650 if (styles_ref_lastit != styles_ref.end())
652 styles_ref_lastit_valid = true;
653 (*styles_ref_lastit).second--;
657 VectorHandle OsdVector::getStyleRef(const DrawStyle& c)
659 surfaces_mutex.lock();
660 VectorHandle style_handle = 0;
662 if (!styles_lastit_valid || (*styles_lastit).first != c)
664 styles_lastit_valid = false;
665 styles_lastit = styles.find(c);
668 if (styles_lastit == styles.end())
670 surfaces_mutex.unlock();
671 style_handle = createStyleRef(c);
672 surfaces_mutex.lock();
673 styles_lastit = styles.insert(std::pair<DrawStyle, VectorHandle>(c, style_handle)).first;
678 style_handle = (*styles_lastit).second;
680 //Now check if the handle is valid
681 if (!styles_ref_lastit_valid || (*styles_ref_lastit).first != style_handle)
683 styles_ref_lastit_valid = false;
684 styles_ref_lastit = styles_ref.find(style_handle);
687 if (styles_ref_lastit == styles_ref.end())
689 //invalid handle recreate
690 surfaces_mutex.unlock();
691 style_handle = createStyleRef(c);
692 surfaces_mutex.lock();
693 (*styles_lastit).second = style_handle;
695 else styles_ref_lastit_valid = true;
698 styles_lastit_valid = true;
699 incStyleRef(style_handle);
700 surfaces_mutex.unlock();
704 LoadIndex OsdVector::getTVMediaRef(TVMediaInfo& tvmedia, ImageIndex& image)
706 ImageIndex image_handle = 0;
707 LoadIndex loadindex = 0;
708 surfaces_mutex.lock();
710 if (tvmedias.find(tvmedia) == tvmedias.end())
712 loadindex = loadTVMedia(tvmedia);
716 image_handle = tvmedias[tvmedia];
718 if (images_ref.find(image_handle) == images_ref.end())
720 //invalid handle recreate
721 loadindex = loadTVMedia(tvmedia);
726 incImageRef(image_handle);
730 /*tvmedias[tvmedia]=createTVMedia(tvmedia,width,height);
731 incImageRef(image_handle);*/
732 image = image_handle;
733 surfaces_mutex.unlock();
737 LoadIndex OsdVector::loadTVMedia(TVMediaInfo& tvmedia)
741 if (tvmedias_load.find(tvmedia) == tvmedias_load.end())
743 switch (tvmedia.getType())
746 index = VDR::getInstance()->loadTVMediaRecThumb(tvmedia);
751 index = ((long long) tvmedia.getPrimaryID()) << 32LL;
752 reader.addStaticImage(tvmedia.getPrimaryID());
756 index = VDR::getInstance()->loadTVMediaEventThumb(tvmedia);
760 index = VDR::getInstance()->loadChannelLogo(tvmedia);
764 index = VDR::getInstance()->loadTVMedia(tvmedia);
768 if (tvmedia.getType() != 4 && tvmedia.getStaticFallback() > -1)
770 reader.informFallback(index, tvmedia.getStaticFallback());
773 tvmedias_load[tvmedia] = index;
774 tvmedias_load_inv[index] = tvmedia;
778 index = tvmedias_load[tvmedia];
781 incLoadIndexRef(index);
788 void OsdVector::informPicture(LoadIndex index, ImageIndex imageIndex)
790 //Beware for thread safety
791 ImageIndex image_index = 0;
793 Log::getInstance()->log("OsdVector", Log::DEBUG, "TVMedia Picture for request id %llx arrived %x", index, imageIndex);
794 surfaces_mutex.lock();
795 TVMediaInfo tvmedia = tvmedias_load_inv[index];
799 std::map<LoadIndex, int>::iterator itty = loadindex_ref.find(index);
800 image_index = tvmedias[tvmedia] = imageIndex;
801 tvmedias_loaded[index] = image_index;
803 if (itty == loadindex_ref.end() || (*itty).second == 0)
805 // we do not want the picture anymore . Really...
806 // fill images_ref in to not irritate the garbage collector
807 if (images_ref.find(image_index) == images_ref.end())
809 images_ref[image_index] = 0;
814 incImageRef(image_index); // hold one index until all loadings refs are gone;
818 surfaces_mutex.unlock();
827 ImageIndex OsdVector::getJpegRef(const char* fileName, int *width,int *height)
829 ImageIndex image_handle=0;
830 if (jpegs.find(fileName)==jpegs.end())
832 image_handle=jpegs[fileName]=createJpeg(fileName,width,height);
834 image_handle=jpegs[fileName];
837 if (images_ref.find(image_handle)==images_ref.end()) {
838 //invalid handle recreate
839 image_handle=jpegs[fileName]=createJpeg(fileName,width,height);
842 incImageRef(image_handle);
847 ImageIndex OsdVector::getMonoBitmapRef(void* base, int width, int height)
849 ImageIndex image_handle;
850 surfaces_mutex.lock();
852 if (monobitmaps.find(base) == monobitmaps.end())
854 surfaces_mutex.unlock();
855 image_handle = createMonoBitmap(base, width, height);
856 surfaces_mutex.lock();
857 monobitmaps[base] = image_handle;
861 image_handle = monobitmaps[base];
863 if (images_ref.find(image_handle) == images_ref.end())
865 //invalid handle recreate
866 surfaces_mutex.unlock();
867 image_handle = createMonoBitmap(base, width, height);
868 surfaces_mutex.lock();
869 monobitmaps[base] = image_handle;
873 incImageRef(image_handle);
874 surfaces_mutex.unlock();
878 ImageIndex OsdVector::getImagePalette(int width, int height, const unsigned char* image_data, const unsigned int* palette_data)
880 ImageIndex image_handle;
881 image_handle = createImagePalette(width, height, image_data, palette_data);
882 surfaces_mutex.lock();
883 palettepics.push_back(image_handle);
884 incImageRef(image_handle);
885 surfaces_mutex.unlock();
889 OsdVector::PictureReader::~PictureReader()
891 decoders_lock.lock();
893 while ( decoders.size())
895 PictureDecoder* dec = decoders.front();
896 decoders.pop_front();
900 decoders_lock.unlock();
903 void OsdVector::PictureReader::init()
908 void OsdVector::PictureReader::shutdown()
915 void OsdVector::PictureReader::addDecoder(PictureDecoder* decoder)
917 decoders_lock.lock();
919 decoders.push_front(decoder);
920 decoders_lock.unlock();
923 void OsdVector::PictureReader::removeDecoder(PictureDecoder* decoder)
925 decoders_lock.lock();
926 std::list<PictureDecoder*>::iterator itty = decoders.begin();
928 while (itty != decoders.end())
930 if ((*itty) == decoder)
932 decoders.erase(itty);
939 Log::getInstance()->log("OsdVector", Log::DEBUG, "removeDecoder");
942 decoders_lock.unlock();
945 void OsdVector::PictureReader::threadMethod()
947 OsdVector* osdvector = dynamic_cast<OsdVector*>(Osd::getInstance());
948 Log::getInstance()->log("OsdVector", Log::DEBUG, "TVMedia Start Picture Reader");
952 if (!threadIsActive())
954 Log::getInstance()->log("OsdVector", Log::DEBUG, "TVMedia End Picture Reader");
964 decoders_lock.lock();
965 std::list<PictureDecoder*>::iterator itty = decoders.begin();
967 while (itty != decoders.end())
969 if ((*itty)->getDecodedPicture(pictinf))
972 osdvector->createPicture(pictinf);
978 if (processReceivedPictures())
983 decoders_lock.unlock();
986 //Log::getInstance()->log("OsdVector", Log::DEBUG, "TVMedia Sleep Picture Reader");
988 struct timespec target_time;
989 getClockRealTime(&target_time);
991 target_time.tv_nsec += 1000000LL * 10;
993 if (target_time.tv_nsec > 999999999)
995 target_time.tv_nsec -= 1000000000L;
996 target_time.tv_sec += 1;
1000 threadWaitForSignalTimed(&target_time);
1002 //Log::getInstance()->log("OsdVector", Log::DEBUG, "TVMedia Sleep end Picture Reader");
1006 void OsdVector::PictureReader::invalidateLoadIndex(LoadIndex index)
1008 pict_lock_incoming.lock();
1009 invalid_loadindex.insert(index);
1010 pict_lock_incoming.unlock();
1013 void OsdVector::PictureReader::informFallback(LoadIndex index, int fallback)
1015 pict_lock_incoming.lock();
1016 inform_fallback[index] = fallback;
1017 pict_lock_incoming.unlock();
1020 void OsdVector::PictureReader::receivePicture(VDR_ResponsePacket* vresp)
1022 pict_lock_incoming.lock();
1023 pict_incoming.push(vresp);
1024 pict_lock_incoming.unlock();
1029 void OsdVector::PictureReader::addStaticImage(unsigned int id)
1031 pict_lock_incoming.lock();
1032 pict_incoming_static.push(id);
1033 invalid_loadindex.erase(((long long) id) << 32LL);
1034 pict_lock_incoming.unlock();
1040 #pragma warning(disable : 4703)
1043 bool OsdVector::PictureReader::processReceivedPictures()
1045 bool decoded = false;
1047 pict_lock_incoming.lock();
1049 if (pict_incoming.size())
1051 VDR_ResponsePacket* vresp = pict_incoming.front();
1052 pict_incoming.pop();
1053 std::set<LoadIndex>::iterator setpos = invalid_loadindex.find(vresp->getStreamID());
1055 if (setpos != invalid_loadindex.end())
1058 invalid_loadindex.erase(setpos);
1061 pict_lock_incoming.unlock();
1063 if (!valid) // we do not want it anymore skip it;
1069 // Log::getInstance()->log("OsdVector", Log::DEBUG, "TVMedia Pictures arrived VDR %x %d %d",
1070 // vresp->getStreamID(),vresp->getUserDataLength(),vresp->getFlag());
1071 bool decode = false;
1076 if (vresp->getFlag() != 2)
1078 userdata = vresp->getUserData();
1079 length = vresp->getUserDataLength();
1086 pict_lock_incoming.lock();
1088 if (inform_fallback.find(vresp->getStreamID()) != inform_fallback.end())
1090 fallback = inform_fallback[vresp->getStreamID()];
1093 pict_lock_incoming.unlock();
1095 if (fallback >= 0 && ((OsdVector*)Osd::getInstance())->getStaticImageData(fallback, &userdata, &length))
1105 std::list<PictureDecoder*>::iterator itty = decoders.begin();
1107 while (itty != decoders.end())
1109 userdata = (*itty)->decodePicture(vresp->getStreamID(), userdata, length, freed);
1120 if (!decoded && userdata && freed)
1126 pict_lock_incoming.lock();
1127 inform_fallback.erase(vresp->getStreamID());
1128 pict_lock_incoming.unlock();
1129 //else osd->informPicture(vresp->getStreamID(), 0);
1132 else if (pict_incoming_static.size())
1134 unsigned int static_id = pict_incoming_static.front();
1135 pict_incoming_static.pop();
1136 std::set<LoadIndex>::iterator setpos = invalid_loadindex.find(((long long) static_id) << 32LL);
1138 if (setpos != invalid_loadindex.end())
1141 invalid_loadindex.erase(setpos);
1144 pict_lock_incoming.unlock();
1146 if (!valid) // we do not want it anymore skip it;
1154 if (((OsdVector*)Osd::getInstance())->getStaticImageData(static_id, &userdata, &length))
1156 std::list<PictureDecoder*>::iterator itty = decoders.begin();
1158 while (itty != decoders.end())
1160 if (!(*itty)->decodePicture(((long long) static_id) << 32LL, userdata, length, false))
1172 pict_lock_incoming.unlock();
1176 if (pict_incoming.size() || pict_incoming_static.size()) return true;