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;
129 OsdVector::~OsdVector()
134 int OsdVector::getFD()
139 void OsdVector::screenShot(const char* fileName)
141 //Do nothing, if no libmagick is there
142 #ifdef PICTURE_DECODER_MAGICK
144 getRealScreenSize(width, height);
145 size_t length = width * height * 4;
146 void* mem = malloc(length);
152 if (!screenShot(mem, width, height, true))
154 Log::getInstance()->log("OsdVector", Log::DEBUG, "Screenshot failed!");
159 myblob.updateNoCopy(mem, length, Blob::MallocAllocator);
160 Image image(myblob, Geometry(width, height), 8, "RGBA");
161 image.write(fileName);
163 catch ( Exception& error_ )
165 Log::getInstance()->log("MagickEncoder", Log::DEBUG, "Libmagick: %s", error_.what());
172 Surface* OsdVector::createNewSurface()
174 return new SurfaceVector(this);
178 void OsdVector::Blank()
180 // do nothing? remove this one?
183 int OsdVector::restore()
185 // First clear the contents of all registered surfaces
186 surfaces_mutex.lock();
188 //Now go through all surfaces and draw them
189 std::list<SurfaceCommands>::iterator curdraw = scommands.begin();
191 while (curdraw != scommands.end())
193 (*curdraw).commands.clear();
194 (*curdraw).commands.reserve(2048);
198 //also clear all handles, they are now invalid, no need to release them
204 styles_lastit_valid = styles_ref_lastit_valid = false;
208 loadindex_ref.clear();
209 tvmedias_load.clear();
210 tvmedias_load_inv.clear();
211 tvmedias_loaded.clear();
213 surfaces_mutex.unlock();
217 void OsdVector::drawSurfaces()
219 surfaces_mutex.lock();
220 std::list<SurfaceCommands*> todraw; //First figure out if a surfaces is below another surface
221 std::list<SurfaceCommands>::iterator itty1 = scommands.begin();
223 while (itty1 != scommands.end())
225 std::list<SurfaceCommands>::iterator itty2 = itty1;
229 while (itty2 != scommands.end())
231 SurfaceCommands& ref1 = *itty1;
232 SurfaceCommands& ref2 = *itty2;
234 if (ref1.x >= ref2.x && ref1.y >= ref2.y
235 && (ref1.x + ref1.w) <= (ref2.x + ref2.w)
236 && (ref1.y + ref1.h) <= (ref2.y + ref2.h) )
245 if (!hidden) // we are not hidden, perfect
247 todraw.push_back(&(*itty1));
254 getScreenSize(swidth, sheight);
255 //Now go through all surfaces and draw them
256 std::list<SurfaceCommands*>::iterator curdraw = todraw.begin();
258 while (curdraw != todraw.end())
260 drawSetTrans(*(*curdraw));
261 std::vector<SVGCommand>::iterator commands = (*(*curdraw)).commands.begin();
262 std::vector<SVGCommand>::iterator end = (*(*curdraw)).commands.end();
264 while (commands != end)
266 // update any images loaded in the mean time
267 if ((*commands).instr == DrawImageLoading)
269 LoadIndex loadindex = (*commands).target.loadindex;
271 if (tvmedias_loaded.find(loadindex) != tvmedias_loaded.end())
273 (*commands).instr = DrawImage;
274 (*commands).target.image = tvmedias_loaded[loadindex];;
275 incImageRef((*commands).target.image);
276 removeLoadIndexRef(loadindex);
281 // Now check if the command is on screen!
282 if (!(*commands).Outside(0, 0, swidth, sheight))
284 executeDrawCommand(*commands);
293 surfaces_mutex.unlock();
296 void OsdVector::updateOrAddSurface(const SurfaceVector* surf, float x, float y, float height, float width,
297 std::vector<SVGCommand>& commands)
299 surfaces_mutex.lock();
300 //First determine it is already in our system
301 std::list<SurfaceCommands>::iterator itty = scommands.begin();
303 while (itty != scommands.end())
305 if ((*itty).surf == surf)
307 //decrease the references
308 dereferenceSVGCommand((*itty).commands);
316 if (itty == scommands.end())
318 SurfaceCommands new_sc;
324 itty = scommands.insert(itty, new_sc);
327 // update any images loaded in the mean time
328 std::vector<SVGCommand>::iterator ilitty = commands.begin();
330 while (ilitty != commands.end())
332 if ((*ilitty).instr == DrawImageLoading)
334 LoadIndex loadindex = (*ilitty).target.loadindex;
336 if (tvmedias_loaded.find(loadindex) != tvmedias_loaded.end())
339 (*ilitty).instr = DrawImage;
340 (*ilitty).target.image = tvmedias_loaded[loadindex];
341 incImageRef((*ilitty).target.image);
342 removeLoadIndexRef(loadindex);
350 // then clear and copy
351 (*itty).commands.clear();
352 (*itty).commands = commands;
353 //increase the references
354 referenceSVGCommand((*itty).commands);
355 cleanupOrphanedRefs();
357 surfaces_mutex.unlock();
360 void OsdVector::removeSurface(const SurfaceVector* surf)
362 surfaces_mutex.lock();
363 //First determine it is already in our system
364 std::list<SurfaceCommands>::iterator itty = scommands.begin();
366 while (itty != scommands.end())
368 if ((*itty).surf == surf)
370 dereferenceSVGCommand((*itty).commands);
371 (*itty).commands.clear();
372 scommands.erase(itty);
379 surfaces_mutex.unlock();
383 void OsdVector::dereferenceSVGCommand(std::vector<SVGCommand>& commands )
386 std::vector<SVGCommand>::iterator sitty = commands.begin();
388 while (sitty != commands.end())
390 removeStyleRef((*sitty).getRef());
391 ImageIndex ii = (*sitty).getImageIndex();
393 if (ii) removeImageRef(ii);
395 LoadIndex li = (*sitty).getLoadIndex();
397 if (li) removeLoadIndexRef(li);
403 void OsdVector::referenceSVGCommand(std::vector<SVGCommand>& commands )
405 std::vector<SVGCommand>::iterator sitty = commands.begin();
407 while (sitty != commands.end())
409 incStyleRef((*sitty).getRef());
410 ImageIndex ii = (*sitty).getImageIndex();
412 if (ii) incImageRef(ii);
414 LoadIndex li = (*sitty).getLoadIndex();
416 if (li) incLoadIndexRef(li);
423 void OsdVector::incImageRef(ImageIndex index)
425 if (images_ref.find(index) == images_ref.end())
427 images_ref[index] = 1;
435 void OsdVector::removeImageRef(const ImageIndex ref)
440 int OsdVector::getLoadIndexRef(LoadIndex index)
442 surfaces_mutex.lock();
444 if (loadindex_ref.find(index) == loadindex_ref.end())
450 return loadindex_ref[index];
453 surfaces_mutex.unlock();
456 void OsdVector::incLoadIndexRef(LoadIndex index)
458 if (loadindex_ref.find(index) == loadindex_ref.end())
460 loadindex_ref[index] = 1;
464 loadindex_ref[index]++;
468 void OsdVector::removeLoadIndexRef(const LoadIndex ref)
470 loadindex_ref[ref]--;
472 if (loadindex_ref[ref] == 0)
474 //now check, if it is already loaded
475 std::map<LoadIndex, ImageIndex>::iterator itty = tvmedias_loaded.find(ref);
477 if ( itty != tvmedias_loaded.end())
479 removeImageRef((*itty).second); // remove lock
482 tvmedias_loaded.erase(ref);
483 // Log::getInstance()->log("OsdVector", Log::DEBUG, "TVMedia removeLoadIndexRef %d %llx",tvmedias_load.size(),ref);
484 tvmedias_load.erase(tvmedias_load_inv[ref]);
485 tvmedias_load_inv.erase(ref);
487 reader.invalidateLoadIndex(ref);
495 void OsdVector::cleanupOrphanedRefs()
497 // Do some garbage collection
499 std::map<void*, ImageIndex>::iterator mitty = monobitmaps.begin();
501 while (mitty != monobitmaps.end())
503 std::map<ImageIndex, int>::iterator curitty = images_ref.find((*mitty).second);
504 int count = (*curitty).second;
508 ImageIndex ref = (*curitty).first;
509 monobitmaps.erase(mitty++);
510 images_ref.erase(curitty++);
511 destroyImageRef(ref);
516 /*map<string,ImageIndex>::iterator jitty=jpegs.begin();
517 while (jitty!=jpegs.end()) {
518 map<ImageIndex,int>::iterator curitty=images_ref.find((*jitty).second);
519 int count=(*curitty).second;
521 ImageIndex ref=(*curitty).first;
522 jpegs.erase(jitty++);
523 images_ref.erase(curitty++);
524 destroyImageRef(ref);
528 std::map<TVMediaInfo, ImageIndex>::iterator titty = tvmedias.begin();
530 while (titty != tvmedias.end())
532 std::map<ImageIndex, int>::iterator curitty = images_ref.find((*titty).second);
533 int count = (*curitty).second;
537 ImageIndex ref = (*curitty).first;
538 tvmedias.erase(titty++);
539 images_ref.erase(curitty);
540 destroyImageRef(ref);
546 std::map<TVMediaInfo, LoadIndex>::iterator litty = tvmedias_load.begin();
548 while (litty != tvmedias_load.end())
550 std::map<LoadIndex, int>::iterator curitty = loadindex_ref.find((*litty).second);
551 int count = (*curitty).second;
555 tvmedias_load_inv.erase((*litty).second);
556 tvmedias_loaded.erase((*litty).second);
557 tvmedias_load.erase(litty++);
562 std::list<ImageIndex>::iterator pitty = palettepics.begin();
564 while (pitty != palettepics.end())
566 std::map<ImageIndex, int>::iterator curitty = images_ref.find((*pitty));
567 int count = (*curitty).second;
571 ImageIndex ref = (*curitty).first;
572 palettepics.erase(pitty++);
573 images_ref.erase(curitty++);
574 destroyImageRef(ref);
579 std::map<ImageIndex, int>::iterator citty = images_ref.begin();
581 while (citty != images_ref.end())
583 int count = (*citty).second;
587 ImageIndex ref = (*citty).first;
588 images_ref.erase(citty++);
589 destroyImageRef(ref);
595 std::map<DrawStyle, VectorHandle>::iterator sitty = styles.begin();
597 while (sitty != styles.end())
599 std::map<VectorHandle, int>::iterator curitty = styles_ref.find((*sitty).second);
600 int count = (*curitty).second;
604 VectorHandle ref = (*curitty).first;
605 styles.erase(sitty++);
606 styles_ref.erase(curitty++);
607 styles_lastit_valid = styles_ref_lastit_valid = false;
608 destroyStyleRef(ref);
617 int OsdVector::getImageRef(ImageIndex index)
619 surfaces_mutex.lock();
621 if (images_ref.find(index) == images_ref.end())
627 return images_ref[index];
630 surfaces_mutex.unlock();
633 void OsdVector::incStyleRef(VectorHandle index)
635 if (!styles_ref_lastit_valid || (*styles_ref_lastit).first != index)
637 styles_ref_lastit_valid = false;
638 styles_ref_lastit = styles_ref.find(index);
641 if (styles_ref_lastit == styles_ref.end())
643 styles_ref_lastit = styles_ref.insert(std::pair<VectorHandle, int>(index, 1)).first;
647 (*styles_ref_lastit).second++;
650 styles_ref_lastit_valid = true;
653 void OsdVector::removeStyleRef(VectorHandle index)
655 if (!styles_ref_lastit_valid || (*styles_ref_lastit).first != index)
657 styles_ref_lastit_valid = false;
658 styles_ref_lastit = styles_ref.find(index);
661 if (styles_ref_lastit != styles_ref.end())
663 styles_ref_lastit_valid = true;
664 (*styles_ref_lastit).second--;
668 VectorHandle OsdVector::getStyleRef(const DrawStyle& c)
670 surfaces_mutex.lock();
671 VectorHandle style_handle = 0;
673 if (!styles_lastit_valid || (*styles_lastit).first != c)
675 styles_lastit_valid = false;
676 styles_lastit = styles.find(c);
679 if (styles_lastit == styles.end())
681 surfaces_mutex.unlock();
682 style_handle = createStyleRef(c);
683 surfaces_mutex.lock();
684 styles_lastit = styles.insert(std::pair<DrawStyle, VectorHandle>(c, style_handle)).first;
689 style_handle = (*styles_lastit).second;
691 //Now check if the handle is valid
692 if (!styles_ref_lastit_valid || (*styles_ref_lastit).first != style_handle)
694 styles_ref_lastit_valid = false;
695 styles_ref_lastit = styles_ref.find(style_handle);
698 if (styles_ref_lastit == styles_ref.end())
700 //invalid handle recreate
701 surfaces_mutex.unlock();
702 style_handle = createStyleRef(c);
703 surfaces_mutex.lock();
704 (*styles_lastit).second = style_handle;
706 else styles_ref_lastit_valid = true;
709 styles_lastit_valid = true;
710 incStyleRef(style_handle);
711 surfaces_mutex.unlock();
717 int OsdVector::getStyleRef(VectorHandle index)
719 if (!styles_ref_lastit_valid || (*styles_ref_lastit).first != index)
721 styles_ref_lastit_valid = false;
722 styles_ref_lastit = styles_ref.find(index);
725 if (styles_ref_lastit == styles_ref.end())
731 styles_ref_lastit_valid = true;
732 return (*styles_ref_lastit).second;
736 LoadIndex OsdVector::getTVMediaRef(TVMediaInfo& tvmedia, ImageIndex& image)
738 ImageIndex image_handle = 0;
739 LoadIndex loadindex = 0;
740 surfaces_mutex.lock();
742 if (tvmedias.find(tvmedia) == tvmedias.end())
744 loadindex = loadTVMedia(tvmedia);
748 image_handle = tvmedias[tvmedia];
750 if (images_ref.find(image_handle) == images_ref.end())
752 //invalid handle recreate
753 loadindex = loadTVMedia(tvmedia);
758 incImageRef(image_handle);
762 /*tvmedias[tvmedia]=createTVMedia(tvmedia,width,height);
763 incImageRef(image_handle);*/
764 image = image_handle;
765 surfaces_mutex.unlock();
769 LoadIndex OsdVector::loadTVMedia(TVMediaInfo& tvmedia)
773 if (tvmedias_load.find(tvmedia) == tvmedias_load.end())
775 switch (tvmedia.getType())
778 index = VDR::getInstance()->loadTVMediaRecThumb(tvmedia);
783 index = ((long long) tvmedia.getPrimaryID()) << 32LL;
784 reader.addStaticImage(tvmedia.getPrimaryID());
788 index = VDR::getInstance()->loadTVMediaEventThumb(tvmedia);
792 index = VDR::getInstance()->loadChannelLogo(tvmedia);
796 index = VDR::getInstance()->loadTVMedia(tvmedia);
800 if (tvmedia.getType() != 4 && tvmedia.getStaticFallback() > -1)
802 reader.informFallback(index, tvmedia.getStaticFallback());
805 tvmedias_load[tvmedia] = index;
806 tvmedias_load_inv[index] = tvmedia;
810 index = tvmedias_load[tvmedia];
813 incLoadIndexRef(index);
820 void OsdVector::informPicture(LoadIndex index, ImageIndex imageIndex)
822 //Beware for thread safety
823 ImageIndex image_index = 0;
825 Log::getInstance()->log("OsdVector", Log::DEBUG, "TVMedia Picture for request id %llx arrived %x", index, imageIndex);
826 surfaces_mutex.lock();
827 TVMediaInfo tvmedia = tvmedias_load_inv[index];
831 std::map<LoadIndex, int>::iterator itty = loadindex_ref.find(index);
832 image_index = tvmedias[tvmedia] = imageIndex;
833 tvmedias_loaded[index] = image_index;
835 if (itty == loadindex_ref.end() || (*itty).second == 0)
837 // we do not want the picture anymore . Really...
838 // fill images_ref in to not irritate the garbage collector
839 if (images_ref.find(image_index) == images_ref.end())
841 images_ref[image_index] = 0;
846 incImageRef(image_index); // hold one index until all loadings refs are gone;
850 surfaces_mutex.unlock();
859 ImageIndex OsdVector::getJpegRef(const char* fileName, int *width,int *height)
861 ImageIndex image_handle=0;
862 if (jpegs.find(fileName)==jpegs.end())
864 image_handle=jpegs[fileName]=createJpeg(fileName,width,height);
866 image_handle=jpegs[fileName];
869 if (images_ref.find(image_handle)==images_ref.end()) {
870 //invalid handle recreate
871 image_handle=jpegs[fileName]=createJpeg(fileName,width,height);
874 incImageRef(image_handle);
879 ImageIndex OsdVector::getMonoBitmapRef(void* base, int width, int height)
881 ImageIndex image_handle;
882 surfaces_mutex.lock();
884 if (monobitmaps.find(base) == monobitmaps.end())
886 surfaces_mutex.unlock();
887 image_handle = createMonoBitmap(base, width, height);
888 surfaces_mutex.lock();
889 monobitmaps[base] = image_handle;
893 image_handle = monobitmaps[base];
895 if (images_ref.find(image_handle) == images_ref.end())
897 //invalid handle recreate
898 surfaces_mutex.unlock();
899 image_handle = createMonoBitmap(base, width, height);
900 surfaces_mutex.lock();
901 monobitmaps[base] = image_handle;
905 incImageRef(image_handle);
906 surfaces_mutex.unlock();
910 ImageIndex OsdVector::getImagePalette(int width, int height, const unsigned char* image_data, const unsigned int* palette_data)
912 ImageIndex image_handle;
913 image_handle = createImagePalette(width, height, image_data, palette_data);
914 surfaces_mutex.lock();
915 palettepics.push_back(image_handle);
916 incImageRef(image_handle);
917 surfaces_mutex.unlock();
921 OsdVector::PictureReader::~PictureReader()
923 decoders_lock.lock();
925 while ( decoders.size())
927 PictureDecoder* dec = decoders.front();
928 decoders.pop_front();
932 decoders_lock.unlock();
935 void OsdVector::PictureReader::init()
940 void OsdVector::PictureReader::shutdown()
947 void OsdVector::PictureReader::addDecoder(PictureDecoder* decoder)
949 decoders_lock.lock();
951 decoders.push_front(decoder);
952 decoders_lock.unlock();
955 void OsdVector::PictureReader::removeDecoder(PictureDecoder* decoder)
957 decoders_lock.lock();
958 std::list<PictureDecoder*>::iterator itty = decoders.begin();
960 while (itty != decoders.end())
962 if ((*itty) == decoder)
964 decoders.erase(itty);
971 Log::getInstance()->log("OsdVector", Log::DEBUG, "removeDecoder");
974 decoders_lock.unlock();
977 void OsdVector::PictureReader::threadMethod()
979 OsdVector* osdvector = dynamic_cast<OsdVector*>(Osd::getInstance());
980 Log::getInstance()->log("OsdVector", Log::DEBUG, "TVMedia Start Picture Reader");
984 if (!threadIsActive())
986 Log::getInstance()->log("OsdVector", Log::DEBUG, "TVMedia End Picture Reader");
996 decoders_lock.lock();
997 std::list<PictureDecoder*>::iterator itty = decoders.begin();
999 while (itty != decoders.end())
1001 if ((*itty)->getDecodedPicture(pictinf))
1004 osdvector->createPicture(pictinf);
1010 if (processReceivedPictures())
1015 decoders_lock.unlock();
1018 //Log::getInstance()->log("OsdVector", Log::DEBUG, "TVMedia Sleep Picture Reader");
1020 struct timespec target_time;
1021 getClockRealTime(&target_time);
1023 target_time.tv_nsec += 1000000LL * 10;
1025 if (target_time.tv_nsec > 999999999)
1027 target_time.tv_nsec -= 1000000000L;
1028 target_time.tv_sec += 1;
1032 threadWaitForSignalTimed(&target_time);
1034 //Log::getInstance()->log("OsdVector", Log::DEBUG, "TVMedia Sleep end Picture Reader");
1038 void OsdVector::PictureReader::invalidateLoadIndex(LoadIndex index)
1040 pict_lock_incoming.lock();
1041 invalid_loadindex.insert(index);
1042 pict_lock_incoming.unlock();
1045 void OsdVector::PictureReader::informFallback(LoadIndex index, int fallback)
1047 pict_lock_incoming.lock();
1048 inform_fallback[index] = fallback;
1049 pict_lock_incoming.unlock();
1052 void OsdVector::PictureReader::receivePicture(VDR_ResponsePacket* vresp)
1054 pict_lock_incoming.lock();
1055 pict_incoming.push(vresp);
1056 pict_lock_incoming.unlock();
1061 void OsdVector::PictureReader::addStaticImage(unsigned int id)
1063 pict_lock_incoming.lock();
1064 pict_incoming_static.push(id);
1065 invalid_loadindex.erase(((long long) id) << 32LL);
1066 pict_lock_incoming.unlock();
1072 #pragma warning(disable : 4703)
1075 bool OsdVector::PictureReader::processReceivedPictures()
1077 bool decoded = false;
1079 pict_lock_incoming.lock();
1081 if (pict_incoming.size())
1083 VDR_ResponsePacket* vresp = pict_incoming.front();
1084 pict_incoming.pop();
1085 std::set<LoadIndex>::iterator setpos = invalid_loadindex.find(vresp->getStreamID());
1087 if (setpos != invalid_loadindex.end())
1090 invalid_loadindex.erase(setpos);
1093 pict_lock_incoming.unlock();
1095 if (!valid) // we do not want it anymore skip it;
1101 // Log::getInstance()->log("OsdVector", Log::DEBUG, "TVMedia Pictures arrived VDR %x %d %d",
1102 // vresp->getStreamID(),vresp->getUserDataLength(),vresp->getFlag());
1103 bool decode = false;
1108 if (vresp->getFlag() != 2)
1110 userdata = vresp->getUserData();
1111 length = vresp->getUserDataLength();
1118 pict_lock_incoming.lock();
1120 if (inform_fallback.find(vresp->getStreamID()) != inform_fallback.end())
1122 fallback = inform_fallback[vresp->getStreamID()];
1125 pict_lock_incoming.unlock();
1127 if (fallback >= 0 && ((OsdVector*)Osd::getInstance())->getStaticImageData(fallback, &userdata, &length))
1137 std::list<PictureDecoder*>::iterator itty = decoders.begin();
1139 while (itty != decoders.end())
1141 userdata = (*itty)->decodePicture(vresp->getStreamID(), userdata, length, freed);
1152 if (!decoded && userdata && freed)
1158 pict_lock_incoming.lock();
1159 inform_fallback.erase(vresp->getStreamID());
1160 pict_lock_incoming.unlock();
1161 //else osd->informPicture(vresp->getStreamID(), 0);
1164 else if (pict_incoming_static.size())
1166 unsigned int static_id = pict_incoming_static.front();
1167 pict_incoming_static.pop();
1168 std::set<LoadIndex>::iterator setpos = invalid_loadindex.find(((long long) static_id) << 32LL);
1170 if (setpos != invalid_loadindex.end())
1173 invalid_loadindex.erase(setpos);
1176 pict_lock_incoming.unlock();
1178 if (!valid) // we do not want it anymore skip it;
1186 if (((OsdVector*)Osd::getInstance())->getStaticImageData(static_id, &userdata, &length))
1188 std::list<PictureDecoder*>::iterator itty = decoders.begin();
1190 while (itty != decoders.end())
1192 if (!(*itty)->decodePicture(((long long) static_id) << 32LL, userdata, length, false))
1204 pict_lock_incoming.unlock();
1208 if (pict_incoming.size() || pict_incoming_static.size()) return true;