]> git.vomp.tv Git - vompclient.git/commitdiff
Move Pictureading to separate thread, prepare for HW accelarated Image reading
authorMarten Richter <marten.richter@freenet.de>
Sun, 20 Jul 2014 16:42:48 +0000 (18:42 +0200)
committerMarten Richter <marten.richter@freenet.de>
Sun, 20 Jul 2014 16:42:48 +0000 (18:42 +0200)
command.cc
defines.h
message.h
osdopenvg.cc
osdopenvg.h
osdvector.cc
osdvector.h
vdr.cc
vdr.h

index b942f2c709756db346311819cbdd28f04211d15c..ef50069268cf00ab84f2b6358a27d6659b76a761 100644 (file)
@@ -445,17 +445,14 @@ void Command::processMessage(Message* m)
 
         break;
       }
-      case Message::PICTURES_ARRIVED:
+      case Message::NEW_PICTURE:
       {
-         Log::getInstance()->log("Command", Log::DEBUG, "TVMedia Pictures arrived");
+         Log::getInstance()->log("Command", Log::DEBUG, "TVMedia NEW_PICTURE");
          OsdVector *osdv=dynamic_cast<OsdVector*>(Osd::getInstance());
          if (osdv) {
-                 osdv->processReceivedPictures();
-               /*  if (osdv->processReceivedPictures()) {
-                         Log::getInstance()->log("Command", Log::DEBUG, "TVMedia Boxstack update triggered");
-                         boxstack->update(NULL,NULL);
-                 }*/
+                 osdv->informPicture(m->tag,m->parameter);
          }
+
       } break;
     }
   }
index c5d6f79a1184ba8931a3d73de3f6003c691df4cb..8b62f5da5f1e80deabc1ac5d8cd1bcaeeacfc566 100644 (file)
--- a/defines.h
+++ b/defines.h
@@ -122,6 +122,9 @@ long long getTimeMS();
   #define HANDLE_VT_SWITCHING
   #define GRADIENT_DRAWING
 
+  #define PICTURE_DECODER_MAGICK
+  #define PICTURE_DECODER_OMX
+
   #define VOMP_LINUX_CLOCK  CLOCK_MONOTONIC
 
 #endif
index 1494129a2465bc1f83ac65602560664788e219da..e79a5a3e22e5dae0e53316e6c962eaf70eadaf42 100644 (file)
--- a/message.h
+++ b/message.h
@@ -77,7 +77,7 @@ class Message
     const static ULONG TELETEXTUPDATEFIRSTLINE = 33;
     const static ULONG SUBTITLE_CHANGE_CHANNEL = 34;
     const static ULONG MOUSE_ANDROID_SCROLL = 35;
-    const static ULONG PICTURES_ARRIVED = 36;
+    const static ULONG NEW_PICTURE = 36;
 };
 
 #endif
index 207063a473b5376361019b4bcdafb8ba69818356..12a0e6d81d5211d4d961153e262b85c2a11bd791 100644 (file)
@@ -101,6 +101,7 @@ OsdOpenVG::~OsdOpenVG()
 int OsdOpenVG::init(void* device)
 {
   if (initted) return 0;
+  reader.init();
   Video* video = Video::getInstance();
    //window=*((HWND*)device);
 
@@ -395,6 +396,7 @@ void OsdOpenVG::purgeAllReferences()
 
 int OsdOpenVG::shutdown()
 {
+  reader.shutdown();
   if (!initted) return 0;
 
   initted = 0;
@@ -1085,6 +1087,27 @@ unsigned int OsdOpenVG::handleTask(OpenVGCommand& command)
                //Log::getInstance()->log("OSD", Log::DEBUG, "Draw create file  %d %d %x %d",command.param1,command.param2,vgGetError(),handle);
                return handle;
        } break;
+       case OVGcreateImageMemory: {
+               PictureInfo *info = (PictureInfo*) command.data;
+               VGImage handle;
+               //Log::getInstance()->log("OSD", Log::DEBUG, "TVMedia OVGcreateImageMemory");
+               handle=vgCreateImage(VG_sXBGR_8888,info->width,info->height,VG_IMAGE_QUALITY_BETTER);
+               vgImageSubData(handle,info->image,info->width*4,
+                                                       VG_sXBGR_8888,0,0,info->width,info->height);
+               info->decoder->freeReference(info->reference);
+               Message* m = new  Message();
+               // We have a pictures! send a message to ourself, to switch to gui thread
+               m->message=Message::NEW_PICTURE;
+               m->from=this;
+               m->to=Command::getInstance();
+               m->parameter = handle;
+               m->tag = info->lindex;
+               Command::getInstance()->postMessageFromOuterSpace(m); // inform command about new picture
+
+               delete info;
+
+       } break;
+
        case OVGcreateColorRef :{
                VGPaint handle;
                handle=vgCreatePaint();
@@ -1156,14 +1179,17 @@ bool OsdOpenVG::processTasks()
        vgmutex.Lock();
        while (vgcommands.size()>0)
        {
-               OpenVGCommand &comm=vgcommands.front();
+               OpenVGCommand comm=vgcommands.front();
+               vgcommands.pop_front();
+               taskmutex.Unlock();
+
                OpenVGResponse resp;
                resp.result=handleTask(comm);
                resp.id=comm.id;
+               taskmutex.Lock();
                if (comm.id) {
                        vgresponses.push_back(resp);
                }
-               vgcommands.pop_front();
                taskmutex.Unlock();
                vgmutex.Unlock();
                //threadCheckExit();
@@ -1257,7 +1283,6 @@ void OsdOpenVG::destroyImageRef(ImageIndex index)
 ImageIndex OsdOpenVG::createJpeg(const char* fileName, int *width,int *height)
 {
        Image* magicimage=NULL;
-       bool mem=false;
        struct OpenVGCommand comm;
        comm.task=OVGcreateImageFile;
 
@@ -1291,26 +1316,19 @@ ImageIndex OsdOpenVG::createJpeg(const char* fileName, int *width,int *height)
        return putOpenVGCommand(comm,true);
 }
 
-ImageIndex OsdOpenVG::createPicture(unsigned char *data, unsigned int length)
+void  OsdOpenVG::createPicture(struct PictureInfo& pict_inf)
 {
-       Image* magicimage=NULL;
-       bool mem=false;
        struct OpenVGCommand comm;
-       comm.task=OVGcreateImageFile;
+       if (pict_inf.type == PictureInfo::RGBAMemBlock) {
+               comm.task = OVGcreateImageMemory;
+               comm.data =  new PictureInfo(pict_inf);
+               putOpenVGCommand(comm,false);
+       } else {
+               // unsupported
+               pict_inf.decoder->freeReference(pict_inf.reference);
 
-       try{
-               // Now figure out, if it is a special case
-               //Log::getInstance()->log("OSD", Log::DEBUG, "createPicture");
-               magicimage=new Image(Blob(data,length)); // fix me this is an unnecessary memcpy
-               free(data);
-       }catch( Exception &error_ )
-       {
-               Log::getInstance()->log("OSD", Log::DEBUG, "Libmagick: %s",error_.what());
 
-               return 0;
        }
-       comm.data=magicimage;
-       return putOpenVGCommand(comm,true);
 }
 
 
index 051e173ffd6958ac85dcceae20cec6247dcaa3b9..afcaebc0b4f06044208a3073b80c95ee08eb1f78 100644 (file)
@@ -51,7 +51,8 @@ enum OpenVGTask {
        OVGcreateColorRef,
        OVGimageUploadLine,
        OVGcreateImageFile,
-       OVGreplacefont
+       OVGreplacefont,
+       OVGcreateImageMemory
 };
 
 struct OpenVGCommand
@@ -94,12 +95,14 @@ class OsdOpenVG : public OsdVector, public Thread_TYPE
 
 
 protected:
+
+
    /*osd vector implementation*/
     void destroyImageRef(ImageIndex index);
     ImageIndex createJpeg(const char* fileName, int *width,int *height);
     ImageIndex createMonoBitmap(void *base,int width,int height);
     ImageIndex createImagePalette(int width,int height,const unsigned char *image_data,const unsigned int*palette_data);
-    ImageIndex createPicture(unsigned char *data, unsigned int length);
+    void createPicture(struct PictureInfo& pict_inf);
     void destroyStyleRef(unsigned int index);
        unsigned int createStyleRef(const DrawStyle &c);
        unsigned int createColorRef(const Colour &c);
index 8012ff6bf435cecd4b6f08de76787bceed79c471..1b1bd769ddb7c5947e699b1cf80e9cbb56e7eb94 100644 (file)
 #include "command.h"
 #include "message.h"
 
+// The next section is activated, if the magick++ PictureReader is provided, it should be available for many POSIX platforms
+#ifdef PICTURE_DECODER_MAGICK
+#include <Magick++.h>
+
+using namespace Magick;
+
+class MagickDecoder: public OsdVector::PictureDecoder {
+public:
+       MagickDecoder(OsdVector::PictureReader* treader): OsdVector::PictureDecoder(treader) {pictInfValid=false;};
+
+       bool decodePicture(LoadIndex index, unsigned char * buffer, unsigned int length);
+
+    bool getDecodedPicture( struct OsdVector::PictureInfo& pict_inf);
+
+    void freeReference(void * ref);
+
+protected:
+    OsdVector::PictureInfo pictInf;
+       bool pictInfValid;
+};
+
+bool MagickDecoder::decodePicture(LoadIndex index, unsigned char * buffer, unsigned int length)
+{
+       if (pictInfValid) return false; // does support only one image at a Time;
+       Image magicimage;
+       Blob *imageblob = new Blob();
+
+       try{
+               Log::getInstance()->log("MagickDecoder", Log::DEBUG, "decodePicture");
+               Blob myblob;
+               myblob.updateNoCopy(buffer,length,Blob::MallocAllocator);
+               magicimage.read(myblob);
+
+               magicimage.write(imageblob,"RGBA");
+
+       }catch( Exception &error_ )
+       {
+               Log::getInstance()->log("MagickDecoder", Log::DEBUG, "Libmagick: %s",error_.what());
+               delete imageblob;
+
+               return false;
+       }
+       pictInf.reference = (void*) imageblob;
+       pictInf.width = magicimage.columns();
+       pictInf.height = magicimage.rows();
+       pictInf.image = imageblob->data();
+       pictInf.decoder = this;
+       pictInf.type = OsdVector::PictureInfo::RGBAMemBlock;
+       pictInf.lindex = index;
+       pictInfValid = true;
+
+
+
+       // I can handle everything, so the return value is always true
+       return true;
+}
+void MagickDecoder::freeReference(void * ref)
+{
+       Blob *todelete = (Blob*) ref;
+       delete todelete;
+}
+
+bool MagickDecoder::getDecodedPicture(struct OsdVector::PictureInfo& pict_inf)
+{
+       if (!pictInfValid) return false;
+       pict_inf=pictInf;
+       pictInfValid = false;
+       return true;
+}
+
+
+#endif
+
 OsdVector::OsdVector()
 {
        setlocale(LC_CTYPE,"C.UTF-8");
-       picture_update=true;
+#ifdef PICTURE_DECODER_MAGICK
+       reader.addDecoder(new MagickDecoder(&reader));
+#endif
+
 }
 
 OsdVector::~OsdVector()
 {
-
 }
 
 
@@ -268,7 +343,7 @@ void OsdVector::removeImageRef(const ImageIndex ref)
        images_ref[ref]--;
 }
 
-unsigned int OsdVector::getLoadIndexRef(LoadIndex index)
+int OsdVector::getLoadIndexRef(LoadIndex index)
 {
        if (loadindex_ref.find(index)==loadindex_ref.end()) {
                return -1;
@@ -298,15 +373,21 @@ void OsdVector::removeLoadIndexRef(const LoadIndex ref)
                tvmedias_loaded.erase(ref);
                tvmedias_load.erase(tvmedias_load_inv[ref]);
                tvmedias_load_inv.erase(ref);
+
+               reader.invalidateLoadIndex(ref);
+
+
        }
 }
 
+
+
 void OsdVector::cleanupOrphanedRefs()
 { // Do some garbage collection
 
        map<void *,ImageIndex>::iterator mitty=monobitmaps.begin();
        while (mitty!=monobitmaps.end()) {
-               map<ImageIndex,unsigned int>::iterator curitty=images_ref.find((*mitty).second);
+               map<ImageIndex,int>::iterator curitty=images_ref.find((*mitty).second);
                int count=(*curitty).second;
                if (count==0) {
                        ImageIndex ref=(*curitty).first;
@@ -318,7 +399,7 @@ void OsdVector::cleanupOrphanedRefs()
 
        map<string,ImageIndex>::iterator jitty=jpegs.begin();
        while (jitty!=jpegs.end()) {
-               map<ImageIndex,unsigned int>::iterator curitty=images_ref.find((*jitty).second);
+               map<ImageIndex,int>::iterator curitty=images_ref.find((*jitty).second);
                int count=(*curitty).second;
                if (count==0) {
                        ImageIndex ref=(*curitty).first;
@@ -330,11 +411,9 @@ void OsdVector::cleanupOrphanedRefs()
 
        map<TVMediaInfo,ImageIndex>::iterator titty=tvmedias.begin();
        while (titty!=tvmedias.end()) {
-               map<ImageIndex,unsigned int>::iterator curitty=images_ref.find((*titty).second);
+               map<ImageIndex,int>::iterator curitty=images_ref.find((*titty).second);
                int count=(*curitty).second;
                if (count==0) {
-
-                       Log::getInstance()->log("OsdVector", Log::DEBUG, "TVMedia destroy Picture");
                        ImageIndex ref=(*curitty).first;
                        tvmedias.erase(titty++);
                        images_ref.erase(curitty++);
@@ -345,7 +424,7 @@ void OsdVector::cleanupOrphanedRefs()
 
        map<pair<Colour*,unsigned int>,unsigned int>::iterator sitty=styles.begin();
        while (sitty!=styles.end()) {
-               map<unsigned int,unsigned int>::iterator curitty=styles_ref.find((*sitty).second);
+               map<unsigned int,int>::iterator curitty=styles_ref.find((*sitty).second);
                int count=(*curitty).second;
                if (count==0) {
                        unsigned int ref=(*curitty).first;
@@ -359,7 +438,7 @@ void OsdVector::cleanupOrphanedRefs()
 }
 
 
-unsigned int OsdVector::getImageRef(ImageIndex index)
+int OsdVector::getImageRef(ImageIndex index)
 {
        if (images_ref.find(index)==images_ref.end()) {
                return -1;
@@ -417,7 +496,7 @@ unsigned int OsdVector::getColorRef(const Colour &c)
        return style_handle;
 }
 
-unsigned int OsdVector::getStyleRef(unsigned int index)
+int OsdVector::getStyleRef(unsigned int index)
 {
        if (styles_ref.find(index)==styles_ref.end()) {
                return -1;
@@ -466,19 +545,26 @@ LoadIndex OsdVector::loadTVMedia(TVMediaInfo& tvmedia)
        return index;
 }
 
-void OsdVector::setTVMedia(LoadIndex index, unsigned char * buffer, unsigned int length)
+
+
+void OsdVector::informPicture(LoadIndex index, ImageIndex imageIndex)
 {
        //Beware for thread safety
        ImageIndex image_index=0;
 
        TVMediaInfo tvmedia=tvmedias_load_inv[index];
          Log::getInstance()->log("OsdVector", Log::DEBUG, "TVMedia Picture for request id %d arrived",index);
-       if (buffer) {
-               if (getLoadIndexRef(index)<1) {
+       if (imageIndex) {
+               image_index=tvmedias[tvmedia]=imageIndex;
+               tvmedias_loaded[index]=image_index;
+               if (getLoadIndexRef(index) < 1) {
                        // we do not want the picture anymore . Really...
+                       // fill images_ref in to not irritate the garbage collector
+                       if (getImageRef(image_index) < 0) {
+                               images_ref[image_index]=0;
+                       }
                } else {
-                       image_index=tvmedias[tvmedia]=createPicture(buffer,length);
-                       tvmedias_loaded[index]=image_index;
+
                        incImageRef(image_index); // hold one index until all loadings refs are gone;
                }
        }
@@ -488,6 +574,8 @@ void OsdVector::setTVMedia(LoadIndex index, unsigned char * buffer, unsigned int
 
 
 
+
+
 ImageIndex OsdVector::getJpegRef(const char* fileName, int *width,int *height)
 {
        ImageIndex image_handle=0;
@@ -532,55 +620,139 @@ ImageIndex  OsdVector::getImagePalette(int width,int height,const unsigned char
        return image_handle;
 }
 
-void OsdVector::receivePicture(VDR_ResponsePacket *vresp)
+OsdVector::PictureReader::~PictureReader()
+{
+       decoders_lock.Lock();
+       while ( decoders.size()) {
+               PictureDecoder* dec=decoders.front();
+               decoders.pop_front();
+               delete dec;
+       }
+
+       decoders_lock.Unlock();
+}
+
+void OsdVector::PictureReader::init()
+{
+       threadStart();
+}
+
+void OsdVector::PictureReader::shutdown()
+{
+       threadStop();
+
+
+}
+
+void OsdVector::PictureReader::addDecoder(PictureDecoder* decoder)
+{
+       decoders_lock.Lock();
+       decoders.push_front(decoder);
+       decoders_lock.Unlock();
+}
+
+void OsdVector::PictureReader::threadMethod()
+{
+       OsdVector *osdvector = dynamic_cast<OsdVector*>(Osd::getInstance());
+       Log::getInstance()->log("OsdVector", Log::DEBUG, "TVMedia Start Picture Reader");
+       while (true) {
+               if (!threadIsActive()) {
+                       Log::getInstance()->log("OsdVector", Log::DEBUG, "TVMedia End Picture Reader");
+                       threadCheckExit();
+               }
+
+               bool todos=true;
+               while (todos)
+               {
+                       todos=false;
+                       PictureInfo pictinf;
+                       decoders_lock.Lock();
+                       std::list<PictureDecoder*>::iterator itty=decoders.begin();
+
+                       while (itty!=decoders.end()) {
+                               if ((*itty)->getDecodedPicture(pictinf)) {
+                                       todos = true;
+                                       osdvector->createPicture(pictinf);
+                               }
+
+                               itty++;
+                       }
+                       if (processReceivedPictures())
+                       {
+                               todos = true;
+                       }
+
+                       decoders_lock.Unlock();
+               }
+               //Log::getInstance()->log("OsdVector", Log::DEBUG, "TVMedia Sleep Picture Reader");
+
+               threadLock();
+               threadWaitForSignal();
+               threadUnlock();
+               //Log::getInstance()->log("OsdVector", Log::DEBUG, "TVMedia Sleep end Picture Reader");
+       }
+}
+
+void OsdVector::PictureReader::threadPostStopCleanup()
+{
+
+}
+
+void OsdVector::PictureReader::invalidateLoadIndex(LoadIndex index)
+{
+       pict_lock_incoming.Lock();
+       invalid_loadindex.insert(index);
+       pict_lock_incoming.Unlock();
+}
+
+void OsdVector::PictureReader::receivePicture(VDR_ResponsePacket *vresp)
 {
        pict_lock_incoming.Lock();
        pict_incoming.push(vresp);
        pict_lock_incoming.Unlock();
-       //Log::getInstance()->log("OsdVector", Log::DEBUG, "TVMedia Pictures arrived");
-       if (picture_update) {
-               Message* m = new  Message();
-               // This is incoming from VDR, we do not want to block gui so send a message to ourself to switch to gui thread
-               m->message=Message::PICTURES_ARRIVED;
-               m->from=this;
-               m->to=Command::getInstance();
-               picture_update=false;
-               Command::getInstance()->postMessageFromOuterSpace(m); // inform command about new picture
-       }
+       threadSignal();
 }
 
-bool OsdVector::processReceivedPictures()
+bool OsdVector::PictureReader::processReceivedPictures()
 {
-       bool ret=false;
+       bool decoded = false;
+       bool valid = true;
        pict_lock_incoming.Lock();
-       int i=0;
-    long long time1 = getTimeMS();
-    long long cur_time =time1;
-       while (pict_incoming.size() && (time1-cur_time)<100) {
+    if (pict_incoming.size()) {
                VDR_ResponsePacket *vresp=pict_incoming.front();
                pict_incoming.pop();
+               set<LoadIndex>::iterator setpos = invalid_loadindex.find(vresp->getStreamID());
+               if (setpos != invalid_loadindex.end()) {
+                       valid = false;
+                       invalid_loadindex.erase(setpos);
+               }
                pict_lock_incoming.Unlock();
+               if (!valid) { // we do not want it anymore skip it;
+                       delete vresp;
+                       return true;
+               }
                if (vresp->getFlag() != 2) {
-                       setTVMedia(vresp->getStreamID(), vresp->getUserData(),  vresp->getUserDataLength());
-                       ret=true;
+                       UCHAR *userdata=vresp->getUserData();
+                       ULONG length=vresp->getUserDataLength();
+                       std::list<PictureDecoder*>::iterator itty=decoders.begin();
+                       while (itty!=decoders.end()) {
+                               if ((*itty)->decodePicture(vresp->getStreamID(),
+                                       userdata, length)){
+                                       decoded=true;
+                                       break;
+                               }
+                               itty++;
+                       }
+                       if (!decoded ){
+                               free(vresp->getUserData());
+                       }
                }
-               else  setTVMedia(vresp->getStreamID(), NULL,  0);
+               //else  osd->informPicture(vresp->getStreamID(), 0);
                delete vresp;
-               cur_time = getTimeMS();
-               pict_lock_incoming.Lock();
+       } else {
+               pict_lock_incoming.Unlock();
        }
-       if (pict_incoming.size()==0) picture_update=true;
-       pict_lock_incoming.Unlock();
 
 
-       if (!picture_update) {
-               Message* m = new  Message();
-               // We have remaing pictures! send a message to ourself to switch to gui thread
-               m->message=Message::PICTURES_ARRIVED;
-               m->from=this;
-               m->to=Command::getInstance();
-               picture_update=false;
-               Command::getInstance()->postMessageNoLock(m); // inform command about new picture
-       }
-       return ret;
+       return decoded;
 }
index 6221ae53688a11812fcb40eced0fa677c16961f2..57d449b499baf38810aae433c43528bf0a1898cd 100644 (file)
@@ -23,6 +23,7 @@
 #include "osd.h"
 #include "mutex.h"
 #include "colour.h"
+#include <set>
 #include <list>
 #include <map>
 #include <queue>
@@ -237,57 +238,132 @@ class OsdVector : public Osd
        virtual void removeStyleRef(unsigned int ref);
        virtual void getScreenSize(int &width, int &height)=0;
 
-       // should be called from command thread
-       bool processReceivedPictures();
+       // should be only called from command thread
+       void informPicture(LoadIndex index, ImageIndex i_index);
+
 
-       void receivePicture(VDR_ResponsePacket *vresp);
 
 
     int charSet() {return 2;}; //UTF-8
 
 
+    class PictureDecoder;
+    struct PictureInfo
+    {
+       enum PictType {
+               RGBAMemBlock,
+               EGLImage
+       };
+       PictType type;
+       ULONG width;
+       ULONG height;
+       LoadIndex lindex;
+       const void * image;
+       void *reference;
+       PictureDecoder* decoder;
+    };
+
+
+    class PictureReader;
+
+    class PictureDecoder
+    {
+    public:
+       PictureDecoder(PictureReader * treader) {reader=treader;};
+
+       // its is always guaranted, that after getDecodedPicture a call to decodePicture follows, if the return value was true;
+       virtual bool decodePicture(LoadIndex index, unsigned char * buffer, unsigned int length)=0;
+
+       virtual bool getDecodedPicture(struct PictureInfo& pict_inf)=0;
+       virtual void freeReference(void * ref)=0;
+
+    protected:
+       PictureReader * reader;
+    };
+
+    class PictureReader: public Thread_TYPE {
+    public:
+
+       ~PictureReader();
+
+       void init();
+       void addDecoder(PictureDecoder*);
+
+       void shutdown();
+
+
+       bool processReceivedPictures();
+
+       // should be called from command thread
+       void receivePicture(VDR_ResponsePacket *vresp);
+
+       void invalidateLoadIndex(LoadIndex index);
+
+
+
+
+    protected:
+
+       void threadMethod();
+       void threadPostStopCleanup();
+
+       Mutex pict_lock_incoming; //locks
+       Mutex decoders_lock;
+       std::queue<VDR_ResponsePacket*> pict_incoming;
+       std::list<PictureDecoder*> decoders;
+       set<LoadIndex> invalid_loadindex;
+
+       bool picture_update;
+
+    };
+
+    PictureReader *getPictReader() { return &reader;};
+
+
 
 protected:
 
+    PictureReader reader;
+
        void incImageRef(ImageIndex index);
-       unsigned int getImageRef(ImageIndex index);
+       int getImageRef(ImageIndex index);
        virtual void destroyImageRef(ImageIndex index)=0;
        void incLoadIndexRef(LoadIndex index);
-       unsigned int getLoadIndexRef(LoadIndex index);
+       int getLoadIndexRef(LoadIndex index);
 
 
        virtual ImageIndex createJpeg(const char* fileName, int *width,int *height)=0;
        virtual ImageIndex createMonoBitmap(void *base,int width,int height)=0;
        virtual ImageIndex createImagePalette(int width,int height,const unsigned char *image_data,const unsigned int*palette_data)=0;
-       virtual ImageIndex createPicture(unsigned char *data, unsigned int length)=0;
+       virtual void createPicture(struct PictureInfo& pict_inf)=0;
 
        virtual LoadIndex loadTVMedia(TVMediaInfo& tvmedia);
 
 
 
-       map<ImageIndex,unsigned int> images_ref;
+       map<ImageIndex,int> images_ref;
        map<void *,ImageIndex> monobitmaps;
        map<string,ImageIndex> jpegs;
        map<TVMediaInfo,ImageIndex> tvmedias;
 
 
 
-       void setTVMedia(LoadIndex index, unsigned char * buffer, unsigned int length);
-       Mutex pict_lock_incoming; //locks
-       std::queue<VDR_ResponsePacket*> pict_incoming;
-       bool picture_update;
 
 
-       map<LoadIndex,unsigned int> loadindex_ref;
+
+
+       map<LoadIndex,int> loadindex_ref;
        map<TVMediaInfo,LoadIndex> tvmedias_load;
        map<LoadIndex,TVMediaInfo> tvmedias_load_inv;
        map<LoadIndex,ImageIndex> tvmedias_loaded;
 
+
+
        void incStyleRef(unsigned int index);
-       unsigned int getStyleRef(ImageIndex index);
+       int getStyleRef(ImageIndex index);
        virtual void destroyStyleRef(unsigned int index)=0;
        map<pair<Colour*,unsigned int>,unsigned int> styles;
-       map<unsigned int,unsigned int> styles_ref;
+       map<unsigned int,int> styles_ref;
        virtual unsigned int createStyleRef(const DrawStyle &c)=0;
        virtual unsigned int createColorRef(const Colour &c)=0;
 
diff --git a/vdr.cc b/vdr.cc
index 1a3fbacf80829d25bb206166460d9f892726cfbf..4d5fb9ec3e1a75d75e0d75a6408e2b5f12ec296e 100644 (file)
--- a/vdr.cc
+++ b/vdr.cc
@@ -40,7 +40,7 @@
 #include "movieinfo.h"
 #include "seriesinfo.h"
 
-#define VOMP_PROTOCOLL_VERSION 0x00000300
+#define VOMP_PROTOCOLL_VERSION 0x00000302
 
 VDR* VDR::instance = NULL;
 //prepare a request
@@ -617,7 +617,7 @@ bool VDR_PacketReceiver::call(void* userTag, bool & deleteme)
          VDR_ResponsePacket* vresp = (VDR_ResponsePacket*)userTag;
          Log::getInstance()->log("VDR", Log::DEBUG, "TVMedia Pictures arrived VDR");
          OsdVector *osd=dynamic_cast<OsdVector*>(Osd::getInstance());
-         if (osd) osd->receivePicture(vresp);
+         if (osd) osd->getPictReader()->receivePicture(vresp);
          else delete vresp; //nonsense
          deleteme=false;
          return true;
diff --git a/vdr.h b/vdr.h
index f322051e876431de70965e9efa3f969be28c0f4f..cd46f1866785dfe26fae683fd0b9bc395f513dda 100644 (file)
--- a/vdr.h
+++ b/vdr.h
@@ -209,6 +209,7 @@ class VDR : public Thread_TYPE, public EventDispatcher, public MediaProvider, pu
     MovieInfo *getScraperMovieInfo(int movieID);
     SeriesInfo *getScraperSeriesInfo(int seriesID, int episodeID);
     ULONG loadTVMedia(TVMediaInfo& tvmedia);
+    void invalidateTVMedia(ULONG loadindex);
 
 
     I18n::lang_code_list getLanguageList();