2 Copyright 2012 Marten Richter, 2020 Chris Tallon
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 "surfacevector.h"
22 #include "vdrresponsepacket.h"
26 #include "osdvector.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
39 MagickDecoder(OsdVector::PictureReader* treader): OsdVector::PictureDecoder(treader) {pictInfValid = false;};
41 unsigned char* decodePicture(LoadIndex index, unsigned char* buffer, unsigned int length, bool freemem);
43 bool getDecodedPicture( struct OsdVector::PictureInfo& pict_inf);
45 void freeReference(void* ref);
48 OsdVector::PictureInfo pictInf;
52 unsigned char* MagickDecoder::decodePicture(LoadIndex index, unsigned char* buffer, unsigned int length, bool freemem)
54 if (pictInfValid) return buffer; // does support only one image at a Time;
57 Blob* imageblob = new Blob();
62 Log::getInstance()->log("MagickDecoder", Log::DEBUG, "decodePicture");
64 if (freemem) myblob.updateNoCopy(buffer, length, Blob::MallocAllocator);
65 else myblob.update(buffer, length);
67 magicimage.read(myblob);
69 magicimage.write(imageblob, "RGBA");
72 catch ( Exception& error_ )
74 Log::getInstance()->log("MagickDecoder", Log::DEBUG, "Libmagick: %s", error_.what());
76 Log::getInstance()->log("MagickDecoder", Log::DEBUG, "Libmagick: error mark2");
77 unsigned char* newbuffer = (unsigned char*) malloc(length);
78 memcpy(newbuffer, myblob.data(), length);
82 pictInf.reference = (void*) imageblob;
83 pictInf.width = magicimage.columns();
84 pictInf.height = magicimage.rows();
85 pictInf.image = imageblob->data();
86 pictInf.decoder = this;
87 pictInf.type = OsdVector::PictureInfo::RGBAMemBlock;
88 pictInf.lindex = index;
93 // I can handle everything, so the return value is always true
96 void MagickDecoder::freeReference(void* ref)
98 Blob* todelete = (Blob*) ref;
102 bool MagickDecoder::getDecodedPicture(struct OsdVector::PictureInfo& pict_inf)
104 if (!pictInfValid) return false;
107 pictInfValid = false;
114 OsdVector::OsdVector()
116 setlocale(LC_CTYPE, "C.UTF-8");
117 #ifdef PICTURE_DECODER_MAGICK
118 reader.addDecoder(new MagickDecoder(&reader));
121 for (int i = 0; i < 256; i++)
123 byte_char_width[i] = 0.f;
127 void OsdVector::screenShot(const char* fileName)
129 //Do nothing, if no libmagick is there
130 #ifdef PICTURE_DECODER_MAGICK
132 getRealScreenSize(width, height);
133 size_t length = width * height * 4;
134 void* mem = malloc(length);
140 if (!screenShot(mem, width, height, true))
142 Log::getInstance()->log("OsdVector", Log::DEBUG, "Screenshot failed!");
147 myblob.updateNoCopy(mem, length, Blob::MallocAllocator);
148 Image image(myblob, Geometry(width, height), 8, "RGBA");
149 image.write(fileName);
151 catch ( Exception& error_ )
153 Log::getInstance()->log("MagickEncoder", Log::DEBUG, "Libmagick: %s", error_.what());
160 Surface* OsdVector::createNewSurface()
162 return new SurfaceVector(this);
165 void OsdVector::Blank()
167 // do nothing? remove this one?
170 int OsdVector::restore()
172 // First clear the contents of all registered surfaces
173 surfaces_mutex.lock();
175 //Now go through all surfaces and clear them
176 for (auto& surface : surfaces)
178 surface.commands.clear();
179 surface.commands.reserve(2048);
182 //also clear all handles, they are now invalid, no need to release them
188 styles_lastit_valid = styles_ref_lastit_valid = false;
192 loadindex_ref.clear();
193 tvmedias_load.clear();
194 tvmedias_load_inv.clear();
195 tvmedias_loaded.clear();
197 surfaces_mutex.unlock();
201 void OsdVector::drawSurfaces()
203 surfaces_mutex.lock();
204 std::list<SurfaceInfo*> todraw; //First figure out if a surfaces is below another surface
205 std::list<SurfaceInfo>::iterator itty1 = surfaces.begin();
207 while (itty1 != surfaces.end())
209 std::list<SurfaceInfo>::iterator itty2 = itty1;
213 while (itty2 != surfaces.end())
215 SurfaceInfo& ref1 = *itty1;
216 SurfaceInfo& ref2 = *itty2;
218 if (ref1.x >= ref2.x && ref1.y >= ref2.y
219 && (ref1.x + ref1.w) <= (ref2.x + ref2.w)
220 && (ref1.y + ref1.h) <= (ref2.y + ref2.h) )
229 if (!hidden) // we are not hidden, perfect
231 todraw.push_back(&(*itty1));
238 getScreenSize(swidth, sheight);
239 //Now go through all surfaces and draw them
240 std::list<SurfaceInfo*>::iterator curdraw = todraw.begin();
242 while (curdraw != todraw.end())
244 drawSetTrans(*(*curdraw));
245 std::vector<SVGCommand>::iterator commands = (*(*curdraw)).commands.begin();
246 std::vector<SVGCommand>::iterator end = (*(*curdraw)).commands.end();
248 while (commands != end)
250 // update any images loaded in the mean time
251 if ((*commands).instr == DrawImageLoading)
253 LoadIndex loadindex = (*commands).target.loadindex;
255 if (tvmedias_loaded.find(loadindex) != tvmedias_loaded.end())
257 (*commands).instr = DrawImage;
258 (*commands).target.image = tvmedias_loaded[loadindex];;
259 incImageRef((*commands).target.image);
260 removeLoadIndexRef(loadindex);
265 // Now check if the command is on screen!
266 if (!(*commands).Outside(0, 0, swidth, sheight))
268 executeDrawCommand(*commands);
277 surfaces_mutex.unlock();
280 void OsdVector::updateOrAddSurface(const SurfaceVector* surf, float x, float y, float height, float width, std::vector<SVGCommand>& commands)
282 std::lock_guard<std::mutex> lg(surfaces_mutex);
285 // First determine it is already in our system
286 for(si = surfaces.begin(); si != surfaces.end(); si++)
288 if (si->surface == surf)
290 // If the surface given (surf) is already in our surfaces vector, reset our SurfaceInfo->commands vector
291 decrementAllRefCounts(si->commands);
292 si->commands.clear();
297 // if not found, make a new SurfaceInfo
298 if (si == surfaces.end())
301 new_sc.surface = surf;
306 si = surfaces.insert(si, new_sc);
309 // update any images loaded in the mean time
311 for (SVGCommand& command : commands)
313 if (command.instr == DrawImageLoading)
315 LoadIndex loadindex = command.target.loadindex;
317 if (tvmedias_loaded.find(loadindex) != tvmedias_loaded.end())
319 command.instr = DrawImage;
320 command.target.image = tvmedias_loaded[loadindex];
321 incImageRef(command.target.image);
322 removeLoadIndexRef(loadindex);
327 si->commands = commands; // Copy surf->commands to our SurfaceInfo->commands
328 incrementAllRefCounts(si->commands);
330 cleanupOrphanedRefs();
333 void OsdVector::removeSurface(const SurfaceVector* surf)
335 std::lock_guard<std::mutex> lg(surfaces_mutex);
336 for (auto i = surfaces.begin(); i != surfaces.end(); i++)
338 if (i->surface == surf)
340 decrementAllRefCounts(i->commands);
348 void OsdVector::decrementAllRefCounts(std::vector<SVGCommand>& commands)
350 for (SVGCommand& command : commands)
352 decrementStyleRefCount(command.getRef());
354 ImageIndex ii = command.getImageIndex();
355 if (ii) removeImageRef(ii);
357 LoadIndex li = command.getLoadIndex();
358 if (li) removeLoadIndexRef(li);
362 void OsdVector::incrementAllRefCounts(std::vector<SVGCommand>& commands)
364 for (SVGCommand& command : commands)
366 incrementStyleRefCount(command.getRef());
368 ImageIndex ii = command.getImageIndex();
369 if (ii) incImageRef(ii);
371 LoadIndex li = command.getLoadIndex();
372 if (li) incLoadIndexRef(li);
376 void OsdVector::incImageRef(ImageIndex index)
378 if (images_ref.find(index) == images_ref.end())
380 images_ref[index] = 1;
388 void OsdVector::removeImageRef(const ImageIndex ref)
393 int OsdVector::getLoadIndexRef(LoadIndex index)
395 surfaces_mutex.lock();
397 if (loadindex_ref.find(index) == loadindex_ref.end())
403 return loadindex_ref[index];
406 surfaces_mutex.unlock();
409 void OsdVector::incLoadIndexRef(LoadIndex index)
411 if (loadindex_ref.find(index) == loadindex_ref.end())
413 loadindex_ref[index] = 1;
417 loadindex_ref[index]++;
421 void OsdVector::removeLoadIndexRef(const LoadIndex ref)
423 loadindex_ref[ref]--;
425 if (loadindex_ref[ref] == 0)
427 //now check, if it is already loaded
428 std::map<LoadIndex, ImageIndex>::iterator itty = tvmedias_loaded.find(ref);
430 if ( itty != tvmedias_loaded.end())
432 removeImageRef((*itty).second); // remove lock
435 tvmedias_loaded.erase(ref);
436 // Log::getInstance()->log("OsdVector", Log::DEBUG, "TVMedia removeLoadIndexRef %d %llx",tvmedias_load.size(),ref);
437 tvmedias_load.erase(tvmedias_load_inv[ref]);
438 tvmedias_load_inv.erase(ref);
440 reader.invalidateLoadIndex(ref);
444 void OsdVector::cleanupOrphanedRefs()
446 // Do some garbage collection
448 std::map<void*, ImageIndex>::iterator mitty = monobitmaps.begin();
450 while (mitty != monobitmaps.end())
452 std::map<ImageIndex, int>::iterator curitty = images_ref.find((*mitty).second);
453 int count = (*curitty).second;
457 ImageIndex ref = (*curitty).first;
458 monobitmaps.erase(mitty++);
459 images_ref.erase(curitty++);
460 destroyImageRef(ref);
465 /*map<string,ImageIndex>::iterator jitty=jpegs.begin();
466 while (jitty!=jpegs.end()) {
467 map<ImageIndex,int>::iterator curitty=images_ref.find((*jitty).second);
468 int count=(*curitty).second;
470 ImageIndex ref=(*curitty).first;
471 jpegs.erase(jitty++);
472 images_ref.erase(curitty++);
473 destroyImageRef(ref);
477 std::map<TVMediaInfo, ImageIndex>::iterator titty = tvmedias.begin();
479 while (titty != tvmedias.end())
481 std::map<ImageIndex, int>::iterator curitty = images_ref.find((*titty).second);
482 int count = (*curitty).second;
486 ImageIndex ref = (*curitty).first;
487 tvmedias.erase(titty++);
488 images_ref.erase(curitty);
489 destroyImageRef(ref);
495 std::map<TVMediaInfo, LoadIndex>::iterator litty = tvmedias_load.begin();
497 while (litty != tvmedias_load.end())
499 std::map<LoadIndex, int>::iterator curitty = loadindex_ref.find((*litty).second);
500 int count = (*curitty).second;
504 tvmedias_load_inv.erase((*litty).second);
505 tvmedias_loaded.erase((*litty).second);
506 tvmedias_load.erase(litty++);
511 std::list<ImageIndex>::iterator pitty = palettepics.begin();
513 while (pitty != palettepics.end())
515 std::map<ImageIndex, int>::iterator curitty = images_ref.find((*pitty));
516 int count = (*curitty).second;
520 ImageIndex ref = (*curitty).first;
521 palettepics.erase(pitty++);
522 images_ref.erase(curitty++);
523 destroyImageRef(ref);
528 std::map<ImageIndex, int>::iterator citty = images_ref.begin();
530 while (citty != images_ref.end())
532 int count = (*citty).second;
536 ImageIndex ref = (*citty).first;
537 images_ref.erase(citty++);
538 destroyImageRef(ref);
544 std::map<DrawStyle, VectorHandle>::iterator sitty = styles.begin();
546 while (sitty != styles.end())
548 std::map<VectorHandle, int>::iterator curitty = styles_ref.find((*sitty).second);
549 int count = (*curitty).second;
553 VectorHandle ref = (*curitty).first;
554 styles.erase(sitty++);
555 styles_ref.erase(curitty++);
556 styles_lastit_valid = styles_ref_lastit_valid = false;
557 destroyStyleRef(ref);
565 int OsdVector::getImageRef(ImageIndex index)
567 surfaces_mutex.lock();
569 if (images_ref.find(index) == images_ref.end())
575 return images_ref[index];
578 surfaces_mutex.unlock();
581 void OsdVector::incrementStyleRefCount(VectorHandle index)
583 if (!styles_ref_lastit_valid || (styles_ref_lastit->first != index))
585 styles_ref_lastit = styles_ref.find(index);
586 if (styles_ref_lastit == styles_ref.end())
588 styles_ref_lastit = styles_ref.insert(std::pair<VectorHandle, int>(index, 0)).first;
592 styles_ref_lastit->second++;
593 styles_ref_lastit_valid = true;
596 void OsdVector::decrementStyleRefCount(VectorHandle index)
598 if (!styles_ref_lastit_valid || (styles_ref_lastit->first != index))
600 styles_ref_lastit_valid = false;
601 styles_ref_lastit = styles_ref.find(index);
604 if (styles_ref_lastit != styles_ref.end())
606 styles_ref_lastit_valid = true;
607 styles_ref_lastit->second--;
611 VectorHandle OsdVector::getStyleRef(const DrawStyle& c)
613 surfaces_mutex.lock();
614 VectorHandle style_handle = 0;
616 if (!styles_lastit_valid || (styles_lastit->first != c))
618 styles_lastit_valid = false;
619 styles_lastit = styles.find(c);
622 if (styles_lastit == styles.end())
624 surfaces_mutex.unlock();
625 style_handle = createStyleRef(c);
626 surfaces_mutex.lock();
627 styles_lastit = styles.insert(std::pair<DrawStyle, VectorHandle>(c, style_handle)).first;
631 style_handle = styles_lastit->second;
633 //Now check if the handle is valid
634 if (!styles_ref_lastit_valid || (*styles_ref_lastit).first != style_handle)
636 styles_ref_lastit_valid = false;
637 styles_ref_lastit = styles_ref.find(style_handle);
640 if (styles_ref_lastit == styles_ref.end())
642 //invalid handle recreate
643 surfaces_mutex.unlock();
644 style_handle = createStyleRef(c);
645 surfaces_mutex.lock();
646 styles_lastit->second = style_handle;
648 else styles_ref_lastit_valid = true;
651 styles_lastit_valid = true;
652 incrementStyleRefCount(style_handle);
653 surfaces_mutex.unlock();
657 LoadIndex OsdVector::getTVMediaRef(TVMediaInfo& tvmedia, ImageIndex& image)
659 ImageIndex image_handle = 0;
660 LoadIndex loadindex = 0;
661 surfaces_mutex.lock();
663 if (tvmedias.find(tvmedia) == tvmedias.end())
665 loadindex = loadTVMedia(tvmedia);
669 image_handle = tvmedias[tvmedia];
671 if (images_ref.find(image_handle) == images_ref.end())
673 //invalid handle recreate
674 loadindex = loadTVMedia(tvmedia);
679 incImageRef(image_handle);
683 /*tvmedias[tvmedia]=createTVMedia(tvmedia,width,height);
684 incImageRef(image_handle);*/
685 image = image_handle;
686 surfaces_mutex.unlock();
690 LoadIndex OsdVector::loadTVMedia(TVMediaInfo& tvmedia)
694 if (tvmedias_load.find(tvmedia) == tvmedias_load.end())
696 switch (tvmedia.getType())
699 index = VDR::getInstance()->loadTVMediaRecThumb(tvmedia);
704 index = ((long long) tvmedia.getPrimaryID()) << 32LL;
705 reader.addStaticImage(tvmedia.getPrimaryID());
709 index = VDR::getInstance()->loadTVMediaEventThumb(tvmedia);
713 index = VDR::getInstance()->loadChannelLogo(tvmedia);
717 index = VDR::getInstance()->loadTVMedia(tvmedia);
721 if (tvmedia.getType() != 4 && tvmedia.getStaticFallback() > -1)
723 reader.informFallback(index, tvmedia.getStaticFallback());
726 tvmedias_load[tvmedia] = index;
727 tvmedias_load_inv[index] = tvmedia;
731 index = tvmedias_load[tvmedia];
734 incLoadIndexRef(index);
739 void OsdVector::informPicture(LoadIndex index, ImageIndex imageIndex)
741 //Beware for thread safety
742 ImageIndex image_index = 0;
744 Log::getInstance()->log("OsdVector", Log::DEBUG, "TVMedia Picture for request id %llx arrived %x", index, imageIndex);
745 surfaces_mutex.lock();
746 TVMediaInfo tvmedia = tvmedias_load_inv[index];
750 std::map<LoadIndex, int>::iterator itty = loadindex_ref.find(index);
751 image_index = tvmedias[tvmedia] = imageIndex;
752 tvmedias_loaded[index] = image_index;
754 if (itty == loadindex_ref.end() || (*itty).second == 0)
756 // we do not want the picture anymore . Really...
757 // fill images_ref in to not irritate the garbage collector
758 if (images_ref.find(image_index) == images_ref.end())
760 images_ref[image_index] = 0;
765 incImageRef(image_index); // hold one index until all loadings refs are gone;
769 surfaces_mutex.unlock();
773 ImageIndex OsdVector::getJpegRef(const char* fileName, int *width,int *height)
775 ImageIndex image_handle=0;
776 if (jpegs.find(fileName)==jpegs.end())
778 image_handle=jpegs[fileName]=createJpeg(fileName,width,height);
780 image_handle=jpegs[fileName];
783 if (images_ref.find(image_handle)==images_ref.end()) {
784 //invalid handle recreate
785 image_handle=jpegs[fileName]=createJpeg(fileName,width,height);
788 incImageRef(image_handle);
793 ImageIndex OsdVector::getMonoBitmapRef(void* base, int width, int height)
795 ImageIndex image_handle;
796 surfaces_mutex.lock();
798 if (monobitmaps.find(base) == monobitmaps.end())
800 surfaces_mutex.unlock();
801 image_handle = createMonoBitmap(base, width, height);
802 surfaces_mutex.lock();
803 monobitmaps[base] = image_handle;
807 image_handle = monobitmaps[base];
809 if (images_ref.find(image_handle) == images_ref.end())
811 //invalid handle recreate
812 surfaces_mutex.unlock();
813 image_handle = createMonoBitmap(base, width, height);
814 surfaces_mutex.lock();
815 monobitmaps[base] = image_handle;
819 incImageRef(image_handle);
820 surfaces_mutex.unlock();
824 ImageIndex OsdVector::getImagePalette(int width, int height, const unsigned char* image_data, const unsigned int* palette_data)
826 ImageIndex image_handle;
827 image_handle = createImagePalette(width, height, image_data, palette_data);
828 surfaces_mutex.lock();
829 palettepics.push_back(image_handle);
830 incImageRef(image_handle);
831 surfaces_mutex.unlock();
835 OsdVector::PictureReader::~PictureReader()
837 decoders_lock.lock();
839 while (decoders.size())
841 PictureDecoder* dec = decoders.front();
842 decoders.pop_front();
846 decoders_lock.unlock();
849 void OsdVector::PictureReader::init()
854 void OsdVector::PictureReader::shutdown()
859 void OsdVector::PictureReader::addDecoder(PictureDecoder* decoder)
861 decoders_lock.lock();
863 decoders.push_front(decoder);
864 decoders_lock.unlock();
867 void OsdVector::PictureReader::removeDecoder(PictureDecoder* decoder)
869 decoders_lock.lock();
870 std::list<PictureDecoder*>::iterator itty = decoders.begin();
872 while (itty != decoders.end())
874 if ((*itty) == decoder)
876 decoders.erase(itty);
883 Log::getInstance()->log("OsdVector", Log::DEBUG, "removeDecoder");
886 decoders_lock.unlock();
889 void OsdVector::PictureReader::threadMethod()
891 OsdVector* osdvector = dynamic_cast<OsdVector*>(Osd::getInstance());
892 Log::getInstance()->log("OsdVector", Log::DEBUG, "TVMedia Start Picture Reader");
896 if (!threadIsActive())
898 Log::getInstance()->log("OsdVector", Log::DEBUG, "TVMedia End Picture Reader");
908 decoders_lock.lock();
909 std::list<PictureDecoder*>::iterator itty = decoders.begin();
911 while (itty != decoders.end())
913 if ((*itty)->getDecodedPicture(pictinf))
916 osdvector->createPicture(pictinf);
922 if (processReceivedPictures())
927 decoders_lock.unlock();
930 //Log::getInstance()->log("OsdVector", Log::DEBUG, "TVMedia Sleep Picture Reader");
932 struct timespec target_time;
933 getClockRealTime(&target_time);
935 target_time.tv_nsec += 1000000LL * 10;
937 if (target_time.tv_nsec > 999999999)
939 target_time.tv_nsec -= 1000000000L;
940 target_time.tv_sec += 1;
944 threadWaitForSignalTimed(&target_time);
946 //Log::getInstance()->log("OsdVector", Log::DEBUG, "TVMedia Sleep end Picture Reader");
950 void OsdVector::PictureReader::invalidateLoadIndex(LoadIndex index)
952 pict_lock_incoming.lock();
953 invalid_loadindex.insert(index);
954 pict_lock_incoming.unlock();
957 void OsdVector::PictureReader::informFallback(LoadIndex index, int fallback)
959 pict_lock_incoming.lock();
960 inform_fallback[index] = fallback;
961 pict_lock_incoming.unlock();
964 void OsdVector::PictureReader::receivePicture(VDR_ResponsePacket* vresp)
966 pict_lock_incoming.lock();
967 pict_incoming.push(vresp);
968 pict_lock_incoming.unlock();
973 void OsdVector::PictureReader::addStaticImage(unsigned int id)
975 pict_lock_incoming.lock();
976 pict_incoming_static.push(id);
977 invalid_loadindex.erase(((long long) id) << 32LL);
978 pict_lock_incoming.unlock();
984 #pragma warning(disable : 4703)
987 bool OsdVector::PictureReader::processReceivedPictures()
989 bool decoded = false;
991 pict_lock_incoming.lock();
993 if (pict_incoming.size())
995 VDR_ResponsePacket* vresp = pict_incoming.front();
997 std::set<LoadIndex>::iterator setpos = invalid_loadindex.find(vresp->getStreamID());
999 if (setpos != invalid_loadindex.end())
1002 invalid_loadindex.erase(setpos);
1005 pict_lock_incoming.unlock();
1007 if (!valid) // we do not want it anymore skip it;
1013 // Log::getInstance()->log("OsdVector", Log::DEBUG, "TVMedia Pictures arrived VDR %x %d %d",
1014 // vresp->getStreamID(),vresp->getUserDataLength(),vresp->getFlag());
1015 bool decode = false;
1020 if (vresp->getFlag() != 2)
1022 userdata = vresp->getUserData();
1023 length = vresp->getUserDataLength();
1030 pict_lock_incoming.lock();
1032 if (inform_fallback.find(vresp->getStreamID()) != inform_fallback.end())
1034 fallback = inform_fallback[vresp->getStreamID()];
1037 pict_lock_incoming.unlock();
1039 if (fallback >= 0 && ((OsdVector*)Osd::getInstance())->getStaticImageData(fallback, &userdata, &length))
1048 std::list<PictureDecoder*>::iterator itty = decoders.begin();
1050 while (itty != decoders.end())
1052 userdata = (*itty)->decodePicture(vresp->getStreamID(), userdata, length, freed);
1063 if (!decoded && userdata && freed)
1069 pict_lock_incoming.lock();
1070 inform_fallback.erase(vresp->getStreamID());
1071 pict_lock_incoming.unlock();
1072 //else osd->informPicture(vresp->getStreamID(), 0);
1075 else if (pict_incoming_static.size())
1077 unsigned int static_id = pict_incoming_static.front();
1078 pict_incoming_static.pop();
1079 std::set<LoadIndex>::iterator setpos = invalid_loadindex.find(((long long) static_id) << 32LL);
1081 if (setpos != invalid_loadindex.end())
1084 invalid_loadindex.erase(setpos);
1087 pict_lock_incoming.unlock();
1089 if (!valid) // we do not want it anymore skip it;
1097 if (((OsdVector*)Osd::getInstance())->getStaticImageData(static_id, &userdata, &length))
1099 std::list<PictureDecoder*>::iterator itty = decoders.begin();
1101 while (itty != decoders.end())
1103 if (!(*itty)->decodePicture(((long long) static_id) << 32LL, userdata, length, false))
1115 pict_lock_incoming.unlock();
1118 if (pict_incoming.size() || pict_incoming_static.size()) return true;