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));
122 bool OsdVector::screenShot(const char* fileName)
124 //Do nothing, if no libmagick is there
125 #ifdef PICTURE_DECODER_MAGICK
127 getRealScreenSize(width, height);
128 size_t length = width * height * 4;
129 void* mem = malloc(length);
135 if (!screenShotInternal(mem, width, height, true))
137 Log::getInstance()->log("OsdVector", Log::DEBUG, "Screenshot failed!");
142 myblob.updateNoCopy(mem, length, Blob::MallocAllocator);
143 Image image(myblob, Geometry(width, height), 8, "RGBA");
144 image.write(fileName);
146 catch ( Exception& error_ )
148 Log::getInstance()->log("MagickEncoder", Log::DEBUG, "Libmagick: %s", error_.what());
157 Surface* OsdVector::createNewSurface()
159 return new SurfaceVector(this);
162 void OsdVector::Blank()
164 // do nothing? remove this one?
167 int OsdVector::restore()
169 // First clear the contents of all registered surfaces
170 surfaces_mutex.lock();
172 //Now go through all surfaces and clear them
173 for (auto& surface : surfaces)
175 surface.commands.clear();
176 surface.commands.reserve(2048);
179 //also clear all handles, they are now invalid, no need to release them
183 drawstyleHandles.clear();
184 drawstyleHandlesRefCounts.clear();
185 drawstyleHandles_lastit_valid = drawstyleHandlesRefCounts_lastit_valid = false;
189 loadindex_ref.clear();
190 tvmedias_load.clear();
191 tvmedias_load_inv.clear();
192 tvmedias_loaded.clear();
194 surfaces_mutex.unlock();
198 void OsdVector::drawSurfaces()
200 surfaces_mutex.lock();
201 std::list<SurfaceInfo*> todraw; //First figure out if a surfaces is below another surface
202 std::list<SurfaceInfo>::iterator itty1 = surfaces.begin();
204 while (itty1 != surfaces.end())
206 std::list<SurfaceInfo>::iterator itty2 = itty1;
210 while (itty2 != surfaces.end())
212 SurfaceInfo& ref1 = *itty1;
213 SurfaceInfo& ref2 = *itty2;
215 if (ref1.x >= ref2.x && ref1.y >= ref2.y
216 && (ref1.x + ref1.w) <= (ref2.x + ref2.w)
217 && (ref1.y + ref1.h) <= (ref2.y + ref2.h) )
226 if (!hidden) // we are not hidden, perfect
228 todraw.push_back(&(*itty1));
235 getScreenSize(swidth, sheight);
236 //Now go through all surfaces and draw them
237 std::list<SurfaceInfo*>::iterator curdraw = todraw.begin();
239 while (curdraw != todraw.end())
241 drawSetTrans(*(*curdraw));
242 std::vector<SVGCommand>::iterator commands = (*(*curdraw)).commands.begin();
243 std::vector<SVGCommand>::iterator end = (*(*curdraw)).commands.end();
245 while (commands != end)
247 // update any images loaded in the mean time
248 if ((*commands).instr == DrawImageLoading)
250 LoadIndex loadindex = (*commands).target.loadindex;
252 if (tvmedias_loaded.find(loadindex) != tvmedias_loaded.end())
254 (*commands).instr = DrawImage;
255 (*commands).target.image = tvmedias_loaded[loadindex];;
256 incImageRef((*commands).target.image);
257 removeLoadIndexRef(loadindex);
262 // Now check if the command is on screen!
263 if (!(*commands).Outside(0, 0, swidth, sheight))
265 executeDrawCommand(*commands);
274 surfaces_mutex.unlock();
277 void OsdVector::updateOrAddSurface(const SurfaceVector* surf, float x, float y, float height, float width, std::vector<SVGCommand>& commands)
279 std::lock_guard<std::mutex> lg(surfaces_mutex);
283 Log::getInstance()->log("OsdVector", Log::CRAZY, "updateOrAddSurface, surfaces.length %i", surfaces.size());
287 // First determine it is already in our system
288 for(si = surfaces.begin(); si != surfaces.end(); si++)
290 if (si->surface == surf)
292 // If the surface given (surf) is already in our surfaces vector, reset our SurfaceInfo->commands vector
293 decrementAllRefCounts(si->commands);
294 si->commands.clear();
299 // if not found, make a new SurfaceInfo
300 if (si == surfaces.end())
303 new_sc.surface = surf;
308 si = surfaces.insert(si, new_sc);
311 // update any images loaded in the mean time
313 for (SVGCommand& command : commands)
315 if (command.instr == DrawImageLoading)
317 LoadIndex loadindex = command.target.loadindex;
319 if (tvmedias_loaded.find(loadindex) != tvmedias_loaded.end())
321 command.instr = DrawImage;
322 command.target.image = tvmedias_loaded[loadindex];
323 incImageRef(command.target.image);
324 removeLoadIndexRef(loadindex);
329 si->commands = commands; // Copy surf->commands to our SurfaceInfo->commands
330 incrementAllRefCounts(si->commands);
332 cleanupOrphanedRefs();
335 Log::getInstance()->log("OsdVector", Log::CRAZY, "After UOAS:");
339 // OSDOVG-ROD-EXPERIMENT
340 Log::getInstance()->log("OsdVector", Log::CRAZY, "EXPERIMENT - call doRender");
344 void OsdVector::removeSurface(const SurfaceVector* surf)
346 std::lock_guard<std::mutex> lg(surfaces_mutex); // FIXME - Can block here on shutdown if a timer is fired just as the wrong time
347 Log::getInstance()->log("OSDVector-347", Log::CRAZY, "EXPERIMENT - removeSurface");
348 for (auto i = surfaces.begin(); i != surfaces.end(); i++)
350 if (i->surface == surf)
352 decrementAllRefCounts(i->commands);
360 void OsdVector::decrementAllRefCounts(std::vector<SVGCommand>& commands)
362 for (SVGCommand& command : commands)
364 VectorHandle handle = command.getHandle();
365 if (handle != 0) // command might not have a handle
366 decrementDrawStyleHandleRefCount(handle);
368 ImageIndex ii = command.getImageIndex();
369 if (ii) removeImageRef(ii);
371 LoadIndex li = command.getLoadIndex();
372 if (li) removeLoadIndexRef(li);
376 void OsdVector::incrementAllRefCounts(std::vector<SVGCommand>& commands)
378 for (SVGCommand& command : commands)
380 VectorHandle handle = command.getHandle();
381 if (handle != 0) // command might not have a handle
382 incrementDrawStyleHandleRefCount(handle);
384 ImageIndex ii = command.getImageIndex();
385 if (ii) incImageRef(ii);
387 LoadIndex li = command.getLoadIndex();
388 if (li) incLoadIndexRef(li);
392 void OsdVector::incImageRef(ImageIndex index)
394 if (images_ref.find(index) == images_ref.end())
396 images_ref[index] = 1;
404 void OsdVector::removeImageRef(const ImageIndex ref)
409 int OsdVector::getLoadIndexRef(LoadIndex index)
411 surfaces_mutex.lock();
413 if (loadindex_ref.find(index) == loadindex_ref.end())
419 return loadindex_ref[index];
422 surfaces_mutex.unlock();
425 void OsdVector::incLoadIndexRef(LoadIndex index)
427 if (loadindex_ref.find(index) == loadindex_ref.end())
429 loadindex_ref[index] = 1;
433 loadindex_ref[index]++;
437 void OsdVector::removeLoadIndexRef(const LoadIndex ref)
439 loadindex_ref[ref]--;
441 if (loadindex_ref[ref] == 0)
443 //now check, if it is already loaded
444 std::map<LoadIndex, ImageIndex>::iterator itty = tvmedias_loaded.find(ref);
446 if ( itty != tvmedias_loaded.end())
448 removeImageRef((*itty).second); // remove lock
451 tvmedias_loaded.erase(ref);
452 // Log::getInstance()->log("OsdVector", Log::DEBUG, "TVMedia removeLoadIndexRef %d %llx",tvmedias_load.size(),ref);
453 tvmedias_load.erase(tvmedias_load_inv[ref]);
454 tvmedias_load_inv.erase(ref);
456 reader.invalidateLoadIndex(ref);
460 void OsdVector::cleanupOrphanedRefs()
462 // Do some garbage collection
464 std::map<void*, ImageIndex>::iterator mitty = monobitmaps.begin();
466 while (mitty != monobitmaps.end())
468 std::map<ImageIndex, int>::iterator curitty = images_ref.find((*mitty).second);
469 int count = (*curitty).second;
473 ImageIndex ref = (*curitty).first;
474 monobitmaps.erase(mitty++);
475 images_ref.erase(curitty++);
476 destroyImageRef(ref);
481 /*map<string,ImageIndex>::iterator jitty=jpegs.begin();
482 while (jitty!=jpegs.end()) {
483 map<ImageIndex,int>::iterator curitty=images_ref.find((*jitty).second);
484 int count=(*curitty).second;
486 ImageIndex ref=(*curitty).first;
487 jpegs.erase(jitty++);
488 images_ref.erase(curitty++);
489 destroyImageRef(ref);
493 std::map<TVMediaInfo, ImageIndex>::iterator titty = tvmedias.begin();
495 while (titty != tvmedias.end())
497 std::map<ImageIndex, int>::iterator curitty = images_ref.find((*titty).second);
498 int count = (*curitty).second;
502 ImageIndex ref = (*curitty).first;
503 tvmedias.erase(titty++);
504 images_ref.erase(curitty);
505 destroyImageRef(ref);
511 std::map<TVMediaInfo, LoadIndex>::iterator litty = tvmedias_load.begin();
513 while (litty != tvmedias_load.end())
515 std::map<LoadIndex, int>::iterator curitty = loadindex_ref.find((*litty).second);
516 int count = (*curitty).second;
520 tvmedias_load_inv.erase((*litty).second);
521 tvmedias_loaded.erase((*litty).second);
522 tvmedias_load.erase(litty++);
527 std::list<ImageIndex>::iterator pitty = palettepics.begin();
529 while (pitty != palettepics.end())
531 std::map<ImageIndex, int>::iterator curitty = images_ref.find((*pitty));
532 int count = (*curitty).second;
536 ImageIndex ref = (*curitty).first;
537 palettepics.erase(pitty++);
538 images_ref.erase(curitty++);
539 destroyImageRef(ref);
544 std::map<ImageIndex, int>::iterator citty = images_ref.begin();
546 while (citty != images_ref.end())
548 int count = (*citty).second;
552 ImageIndex ref = (*citty).first;
553 images_ref.erase(citty++);
554 destroyImageRef(ref);
560 std::map<DrawStyle, VectorHandle>::iterator sitty = drawstyleHandles.begin();
562 while (sitty != drawstyleHandles.end())
564 std::map<VectorHandle, int>::iterator curitty = drawstyleHandlesRefCounts.find((*sitty).second);
565 int count = (*curitty).second;
569 VectorHandle ref = (*curitty).first;
570 drawstyleHandles.erase(sitty++);
571 drawstyleHandlesRefCounts.erase(curitty++);
572 drawstyleHandles_lastit_valid = drawstyleHandlesRefCounts_lastit_valid = false;
573 destroyDrawStyleHandle(ref);
581 int OsdVector::getImageRef(ImageIndex index)
583 surfaces_mutex.lock();
585 if (images_ref.find(index) == images_ref.end())
591 return images_ref[index];
594 surfaces_mutex.unlock();
597 void OsdVector::incrementDrawStyleHandleRefCount(VectorHandle index)
599 if (!drawstyleHandlesRefCounts_lastit_valid || (drawstyleHandlesRefCounts_lastit->first != index))
601 drawstyleHandlesRefCounts_lastit = drawstyleHandlesRefCounts.find(index);
602 if (drawstyleHandlesRefCounts_lastit == drawstyleHandlesRefCounts.end())
604 drawstyleHandlesRefCounts_lastit = drawstyleHandlesRefCounts.insert(std::pair<VectorHandle, int>(index, 0)).first;
608 drawstyleHandlesRefCounts_lastit->second++;
609 drawstyleHandlesRefCounts_lastit_valid = true;
612 void OsdVector::decrementDrawStyleHandleRefCount(VectorHandle index)
614 if (!drawstyleHandlesRefCounts_lastit_valid || (drawstyleHandlesRefCounts_lastit->first != index))
616 drawstyleHandlesRefCounts_lastit_valid = false;
617 drawstyleHandlesRefCounts_lastit = drawstyleHandlesRefCounts.find(index);
620 if (drawstyleHandlesRefCounts_lastit != drawstyleHandlesRefCounts.end())
622 drawstyleHandlesRefCounts_lastit_valid = true;
623 drawstyleHandlesRefCounts_lastit->second--;
627 VectorHandle OsdVector::getDrawStyleHandle(const DrawStyle& c)
629 surfaces_mutex.lock();
630 VectorHandle style_handle = 0;
636 if (!drawstyleHandles_lastit_valid || (drawstyleHandles_lastit->first != c))
638 drawstyleHandles_lastit_valid = false;
639 drawstyleHandles_lastit = drawstyleHandles.find(c);
642 if (drawstyleHandles_lastit == drawstyleHandles.end())
644 surfaces_mutex.unlock();
645 style_handle = createDrawStyleHandle(c);
646 surfaces_mutex.lock();
647 drawstyleHandles_lastit = drawstyleHandles.insert(std::pair<DrawStyle, VectorHandle>(c, style_handle)).first;
651 style_handle = drawstyleHandles_lastit->second;
653 //Now check if the handle is valid
654 if (!drawstyleHandlesRefCounts_lastit_valid || (*drawstyleHandlesRefCounts_lastit).first != style_handle)
656 drawstyleHandlesRefCounts_lastit_valid = false;
657 drawstyleHandlesRefCounts_lastit = drawstyleHandlesRefCounts.find(style_handle);
660 if (drawstyleHandlesRefCounts_lastit == drawstyleHandlesRefCounts.end())
662 //invalid handle recreate
663 surfaces_mutex.unlock();
664 style_handle = createDrawStyleHandle(c);
665 surfaces_mutex.lock();
666 drawstyleHandles_lastit->second = style_handle;
668 else drawstyleHandlesRefCounts_lastit_valid = true;
671 drawstyleHandles_lastit_valid = true;
672 incrementDrawStyleHandleRefCount(style_handle);
673 surfaces_mutex.unlock();
678 void OsdVector::dumpStyles()
682 std::map<DrawStyle, VectorHandle>::iterator i;
683 for(i = drawstyleHandles.begin(); i != drawstyleHandles.end(); i++)
685 const DrawStyle* test = &(i->first);
686 Log::getInstance()->log("OsdVector", Log::DEBUG, "DumpStyles: %p %i", test , i->second);
689 std::map<VectorHandle, int>::iterator i2;
690 for (i2 = drawstyleHandlesRefCounts.begin(); i2 != drawstyleHandlesRefCounts.end(); i2++)
692 Log::getInstance()->log("OsdVector", Log::DEBUG, "DumpStylesRef: %i %i", i2->first, i2->second);
697 LoadIndex OsdVector::getTVMediaRef(TVMediaInfo& tvmedia, ImageIndex& image)
699 ImageIndex image_handle = 0;
700 LoadIndex loadindex = 0;
701 surfaces_mutex.lock();
703 if (tvmedias.find(tvmedia) == tvmedias.end())
705 loadindex = loadTVMedia(tvmedia);
709 image_handle = tvmedias[tvmedia];
711 if (images_ref.find(image_handle) == images_ref.end())
713 //invalid handle recreate
714 loadindex = loadTVMedia(tvmedia);
719 incImageRef(image_handle);
723 /*tvmedias[tvmedia]=createTVMedia(tvmedia,width,height);
724 incImageRef(image_handle);*/
725 image = image_handle;
726 surfaces_mutex.unlock();
730 LoadIndex OsdVector::loadTVMedia(TVMediaInfo& tvmedia)
734 if (tvmedias_load.find(tvmedia) == tvmedias_load.end())
736 switch (tvmedia.getType())
739 index = VDR::getInstance()->loadTVMediaRecThumb(tvmedia);
744 index = ((long long) tvmedia.getPrimaryID()) << 32LL;
745 reader.addStaticImage(tvmedia.getPrimaryID());
749 index = VDR::getInstance()->loadTVMediaEventThumb(tvmedia);
753 index = VDR::getInstance()->loadChannelLogo(tvmedia);
757 index = VDR::getInstance()->loadTVMedia(tvmedia);
761 if (tvmedia.getType() != 4 && tvmedia.getStaticFallback() > -1)
763 reader.informFallback(index, tvmedia.getStaticFallback());
766 tvmedias_load[tvmedia] = index;
767 tvmedias_load_inv[index] = tvmedia;
771 index = tvmedias_load[tvmedia];
774 incLoadIndexRef(index);
779 void OsdVector::informPicture(LoadIndex index, ImageIndex imageIndex)
781 //Beware for thread safety
782 ImageIndex image_index = 0;
784 Log::getInstance()->log("OsdVector", Log::DEBUG, "TVMedia Picture for request id %llx arrived %x", index, imageIndex);
785 surfaces_mutex.lock();
786 TVMediaInfo tvmedia = tvmedias_load_inv[index];
790 std::map<LoadIndex, int>::iterator itty = loadindex_ref.find(index);
791 image_index = tvmedias[tvmedia] = imageIndex;
792 tvmedias_loaded[index] = image_index;
794 if (itty == loadindex_ref.end() || (*itty).second == 0)
796 // we do not want the picture anymore . Really...
797 // fill images_ref in to not irritate the garbage collector
798 if (images_ref.find(image_index) == images_ref.end())
800 images_ref[image_index] = 0;
805 incImageRef(image_index); // hold one index until all loadings refs are gone;
809 surfaces_mutex.unlock();
813 ImageIndex OsdVector::getJpegRef(const char* fileName, int *width,int *height)
815 ImageIndex image_handle=0;
816 if (jpegs.find(fileName)==jpegs.end())
818 image_handle=jpegs[fileName]=createJpeg(fileName,width,height);
820 image_handle=jpegs[fileName];
823 if (images_ref.find(image_handle)==images_ref.end()) {
824 //invalid handle recreate
825 image_handle=jpegs[fileName]=createJpeg(fileName,width,height);
828 incImageRef(image_handle);
833 ImageIndex OsdVector::getMonoBitmapRef(void* base, int width, int height)
835 ImageIndex image_handle;
836 surfaces_mutex.lock();
838 if (monobitmaps.find(base) == monobitmaps.end())
840 surfaces_mutex.unlock();
841 image_handle = createMonoBitmap(base, width, height);
842 surfaces_mutex.lock();
843 monobitmaps[base] = image_handle;
847 image_handle = monobitmaps[base];
849 if (images_ref.find(image_handle) == images_ref.end())
851 //invalid handle recreate
852 surfaces_mutex.unlock();
853 image_handle = createMonoBitmap(base, width, height);
854 surfaces_mutex.lock();
855 monobitmaps[base] = image_handle;
859 incImageRef(image_handle);
860 surfaces_mutex.unlock();
864 ImageIndex OsdVector::getImagePalette(int width, int height, const unsigned char* image_data, const unsigned int* palette_data)
866 ImageIndex image_handle;
867 image_handle = createImagePalette(width, height, image_data, palette_data);
868 surfaces_mutex.lock();
869 palettepics.push_back(image_handle);
870 incImageRef(image_handle);
871 surfaces_mutex.unlock();
875 /// PictureReader Class
877 OsdVector::PictureReader::~PictureReader()
879 decoders_lock.lock();
881 while (decoders.size())
883 PictureDecoder* dec = decoders.front();
884 decoders.pop_front();
888 decoders_lock.unlock();
891 void OsdVector::PictureReader::init()
896 void OsdVector::PictureReader::shutdown()
901 void OsdVector::PictureReader::addDecoder(PictureDecoder* decoder)
903 decoders_lock.lock();
905 decoders.push_front(decoder);
906 decoders_lock.unlock();
909 void OsdVector::PictureReader::removeDecoder(PictureDecoder* decoder)
911 decoders_lock.lock();
912 std::list<PictureDecoder*>::iterator itty = decoders.begin();
914 while (itty != decoders.end())
916 if ((*itty) == decoder)
918 decoders.erase(itty);
925 Log::getInstance()->log("OsdVector", Log::DEBUG, "removeDecoder");
928 decoders_lock.unlock();
931 void OsdVector::PictureReader::threadMethod()
933 OsdVector* osdvector = dynamic_cast<OsdVector*>(Osd::getInstance());
934 Log::getInstance()->log("OsdVector", Log::DEBUG, "TVMedia Start Picture Reader");
938 if (!threadIsActive())
940 Log::getInstance()->log("OsdVector", Log::DEBUG, "TVMedia End Picture Reader");
950 decoders_lock.lock();
951 std::list<PictureDecoder*>::iterator itty = decoders.begin();
953 while (itty != decoders.end())
955 if ((*itty)->getDecodedPicture(pictinf))
958 osdvector->createPicture(pictinf);
964 if (processReceivedPictures())
969 decoders_lock.unlock();
972 //Log::getInstance()->log("OsdVector", Log::DEBUG, "TVMedia Sleep Picture Reader");
974 struct timespec target_time;
975 getClockRealTime(&target_time);
977 target_time.tv_nsec += 1000000LL * 10;
979 if (target_time.tv_nsec > 999999999)
981 target_time.tv_nsec -= 1000000000L;
982 target_time.tv_sec += 1;
986 threadWaitForSignalTimed(&target_time);
988 //Log::getInstance()->log("OsdVector", Log::DEBUG, "TVMedia Sleep end Picture Reader");
992 void OsdVector::PictureReader::invalidateLoadIndex(LoadIndex index)
994 pict_lock_incoming.lock();
995 invalid_loadindex.insert(index);
996 pict_lock_incoming.unlock();
999 void OsdVector::PictureReader::informFallback(LoadIndex index, int fallback)
1001 pict_lock_incoming.lock();
1002 inform_fallback[index] = fallback;
1003 pict_lock_incoming.unlock();
1006 void OsdVector::PictureReader::receivePicture(VDR_ResponsePacket* vresp)
1008 pict_lock_incoming.lock();
1009 pict_incoming.push(vresp);
1010 pict_lock_incoming.unlock();
1015 void OsdVector::PictureReader::addStaticImage(unsigned int id)
1017 pict_lock_incoming.lock();
1018 pict_incoming_static.push(id);
1019 invalid_loadindex.erase(((long long) id) << 32LL);
1020 pict_lock_incoming.unlock();
1026 #pragma warning(disable : 4703)
1029 bool OsdVector::PictureReader::processReceivedPictures()
1031 bool decoded = false;
1033 pict_lock_incoming.lock();
1035 if (pict_incoming.size())
1037 VDR_ResponsePacket* vresp = pict_incoming.front();
1038 pict_incoming.pop();
1039 std::set<LoadIndex>::iterator setpos = invalid_loadindex.find(vresp->getStreamID());
1041 if (setpos != invalid_loadindex.end())
1044 invalid_loadindex.erase(setpos);
1047 pict_lock_incoming.unlock();
1049 if (!valid) // we do not want it anymore skip it;
1055 // Log::getInstance()->log("OsdVector", Log::DEBUG, "TVMedia Pictures arrived VDR %x %d %d",
1056 // vresp->getStreamID(),vresp->getUserDataLength(),vresp->getFlag());
1057 bool decode = false;
1062 if (vresp->getFlag() != 2)
1064 userdata = vresp->getUserData();
1065 length = vresp->getUserDataLength();
1072 pict_lock_incoming.lock();
1074 if (inform_fallback.find(vresp->getStreamID()) != inform_fallback.end())
1076 fallback = inform_fallback[vresp->getStreamID()];
1079 pict_lock_incoming.unlock();
1081 if (fallback >= 0 && ((OsdVector*)Osd::getInstance())->getStaticImageData(fallback, &userdata, &length))
1090 std::list<PictureDecoder*>::iterator itty = decoders.begin();
1092 while (itty != decoders.end())
1094 userdata = (*itty)->decodePicture(vresp->getStreamID(), userdata, length, freed);
1105 if (!decoded && userdata && freed)
1111 pict_lock_incoming.lock();
1112 inform_fallback.erase(vresp->getStreamID());
1113 pict_lock_incoming.unlock();
1114 //else osd->informPicture(vresp->getStreamID(), 0);
1117 else if (pict_incoming_static.size())
1119 unsigned int static_id = pict_incoming_static.front();
1120 pict_incoming_static.pop();
1121 std::set<LoadIndex>::iterator setpos = invalid_loadindex.find(((long long) static_id) << 32LL);
1123 if (setpos != invalid_loadindex.end())
1126 invalid_loadindex.erase(setpos);
1129 pict_lock_incoming.unlock();
1131 if (!valid) // we do not want it anymore skip it;
1139 if (((OsdVector*)Osd::getInstance())->getStaticImageData(static_id, &userdata, &length))
1141 std::list<PictureDecoder*>::iterator itty = decoders.begin();
1143 while (itty != decoders.end())
1145 if (!(*itty)->decodePicture(((long long) static_id) << 32LL, userdata, length, false))
1157 pict_lock_incoming.unlock();
1160 if (pict_incoming.size() || pict_incoming_static.size()) return true;