00001 #include "InterleavedYUVGenerator.h"
00002 #include "Events/EventRouter.h"
00003 #include "Events/FilterBankEvent.h"
00004 #include "Wireless/Wireless.h"
00005 #include "Shared/Profiler.h"
00006
00007 #include "Shared/debuget.h"
00008
00009 InterleavedYUVGenerator::InterleavedYUVGenerator(unsigned int mysid,FilterBankGenerator* fbg, EventBase::EventTypeID_t tid)
00010 : FilterBankGenerator("InterleavedYUVGenerator",EventBase::visInterleaveEGID,mysid,fbg,tid), srcYChan(0), srcUChan(1), srcVChan(2), isAllocated(NULL)
00011 {
00012
00013 if(fbg!=NULL) {
00014 numLayers=numChannels=0;
00015 setNumImages(fbg->getNumLayers(),fbg->getNumChannels());
00016 }
00017 }
00018
00019 InterleavedYUVGenerator::InterleavedYUVGenerator(unsigned int mysid, unsigned int syc, unsigned int suc, unsigned int svc,FilterBankGenerator* fbg, EventBase::EventTypeID_t tid)
00020 : FilterBankGenerator("InterleavedYUVGenerator",EventBase::visInterleaveEGID,mysid,fbg,tid), srcYChan(syc), srcUChan(suc), srcVChan(svc), isAllocated(NULL)
00021 {
00022
00023 if(fbg!=NULL) {
00024 numLayers=numChannels=0;
00025 setNumImages(fbg->getNumLayers(),fbg->getNumChannels());
00026 }
00027 }
00028
00029 void
00030 InterleavedYUVGenerator::doEvent() {
00031 if(event->getGeneratorID()==getListenGeneratorID() && event->getSourceID()==getListenSourceID()) {
00032 FilterBankEvent fbkev(this,getGeneratorID(),getSourceID(),EventBase::activateETID);
00033 erouter->postEvent(fbkev);
00034 fbkev.setTypeID(EventBase::statusETID);
00035 erouter->postEvent(fbkev);
00036 fbkev.setTypeID(EventBase::deactivateETID);
00037 erouter->postEvent(fbkev);
00038 }
00039 }
00040
00041 unsigned int
00042 InterleavedYUVGenerator::getBinSize() const {
00043 unsigned int used=FilterBankGenerator::getBinSize();
00044 used+=strlen("InterleavedYUVImage")+LoadSave::stringpad;
00045 used+=widths[selectedSaveLayer]*heights[selectedSaveLayer]*3;
00046 return used;
00047 }
00048
00049 unsigned int
00050 InterleavedYUVGenerator::loadBuffer(const char buf[], unsigned int len, const char* filename) {
00051 unsigned int origlen=len;
00052 if(!checkInc(FilterBankGenerator::loadBuffer(buf,len,filename),buf,len)) return 0;
00053 std::string tmp;
00054 if(!decodeInc(tmp,buf,len)) return 0;
00055 if(tmp!="InterleavedYUVImage") {
00056 serr->printf("Unhandled image type for InterleavedYUVGenerator: %s",tmp.c_str());
00057 return 0;
00058 } else {
00059 unsigned int used=widths[selectedSaveLayer]*heights[selectedSaveLayer]*3;
00060 if(used>len)
00061 return 0;
00062 if(images[selectedSaveLayer][selectedSaveChannel]==NULL)
00063 images[selectedSaveLayer][selectedSaveChannel]=createImageCache(selectedSaveLayer,selectedSaveChannel);
00064 unsigned char* img=images[selectedSaveLayer][selectedSaveChannel];
00065 if(img==NULL)
00066 return 0;
00067 memcpy(img,buf,used);
00068 len-=used; buf+=used;
00069 imageValids[selectedSaveLayer][selectedSaveChannel]=true;
00070 return origlen-len;
00071 }
00072 }
00073
00074 unsigned int
00075 InterleavedYUVGenerator::saveBuffer(char buf[], unsigned int len) const {
00076 unsigned int origlen=len;
00077 if(!checkInc(FilterBankGenerator::saveBuffer(buf,len),buf,len)) return 0;
00078 if(!encodeInc("InterleavedYUVImage",buf,len)) return 0;
00079
00080 unsigned int used=widths[selectedSaveLayer]*heights[selectedSaveLayer]*3;
00081 if(used>len)
00082 return 0;
00083 if(images[selectedSaveLayer][selectedSaveChannel]==NULL) {
00084 serr->printf("InterleavedYUVGenerator::saveBuffer() failed because selected image is NULL -- call selectSaveImage first to make sure it's up to date\n");
00085 return 0;
00086 }
00087 if(!imageValids[selectedSaveLayer][selectedSaveChannel]) {
00088 serr->printf("InterleavedYUVGenerator::saveBuffer() failed because selected image is invalid -- call selectSaveImage first to make sure it's up to date\n");
00089 return 0;
00090 }
00091 unsigned char* img=images[selectedSaveLayer][selectedSaveChannel];
00092 if(img==NULL)
00093 return 0;
00094 memcpy(buf,img,used);
00095 len-=used;
00096 return origlen-len;
00097 }
00098
00099 void
00100 InterleavedYUVGenerator::setDimensions() {
00101 FilterBankGenerator::setDimensions();
00102 for(unsigned int i=0; i<numLayers; i++)
00103 strides[i]=widths[i]*3;
00104 }
00105
00106 void
00107 InterleavedYUVGenerator::destruct() {
00108 FilterBankGenerator::destruct();
00109 for(unsigned int i=0; i<numLayers; i++)
00110 delete [] isAllocated[i];
00111 delete [] isAllocated;
00112 isAllocated=NULL;
00113 }
00114
00115 void
00116 InterleavedYUVGenerator::setNumImages(unsigned int nLayers, unsigned int ) {
00117 if(nLayers==numLayers && 1==numChannels)
00118 return;
00119 FilterBankGenerator::setNumImages(nLayers,1);
00120 isAllocated=new bool*[numLayers];
00121 for(unsigned int res=0; res<numLayers; res++) {
00122 increments[res]=3;
00123 isAllocated[res]=new bool[numChannels];
00124 for(unsigned int c=0; c<numChannels; c++)
00125 isAllocated[res][c]=false;
00126 }
00127 }
00128
00129 void
00130 InterleavedYUVGenerator::freeCaches() {
00131 FilterBankGenerator::freeCaches();
00132 for(unsigned int i=0; i<numLayers; i++)
00133 for(unsigned int j=0; j<numChannels; j++)
00134 isAllocated[i][j]=false;
00135 }
00136
00137 void
00138 InterleavedYUVGenerator::invalidateCaches() {
00139 for(unsigned int i=0; i<numLayers; i++)
00140 for(unsigned int j=0; j<numChannels; j++) {
00141 if(!isAllocated[i][j])
00142 images[i][j]=NULL;
00143 imageValids[i][j]=false;
00144 }
00145 }
00146
00147 unsigned char *
00148 InterleavedYUVGenerator::createImageCache(unsigned int layer, unsigned int chan) const {
00149 if(src->getStride(layer)==getStride(layer) && src->getIncrement(layer)==getIncrement(layer)) {
00150
00151 ASSERT(!isAllocated[layer][chan],"pass through over allocated image!")
00152 imageValids[layer][chan]=true;
00153 return src->getImage(layer,srcYChan);
00154 } else {
00155 isAllocated[layer][chan]=true;
00156 return new unsigned char[widths[layer]*heights[layer]*3];
00157 }
00158 }
00159
00160 void
00161 InterleavedYUVGenerator::calcImage(unsigned int layer, unsigned int chan) {
00162 PROFSECTION("InterleavedYUVGenerator::calcImage(...)",*mainProfiler);
00163 if(imageValids[layer][chan])
00164 return;
00165
00166 unsigned char* dimg=images[layer][chan];
00167 const unsigned char* syimg=src->getImage(layer,srcYChan);
00168 const unsigned char* suimg=src->getImage(layer,srcUChan);
00169 const unsigned char* svimg=src->getImage(layer,srcVChan);
00170 const unsigned int inc=src->getIncrement(layer);
00171 const unsigned int skip=src->getSkip(layer);
00172
00173 for(unsigned int y=0; y<getHeight(layer); y++) {
00174 for(unsigned int x=0; x<getWidth(layer); x++) {
00175 *dimg++=*syimg;
00176 *dimg++=*suimg;
00177 *dimg++=*svimg;
00178 syimg+=inc;
00179 suimg+=inc;
00180 svimg+=inc;
00181 }
00182 syimg+=skip;
00183 suimg+=skip;
00184 svimg+=skip;
00185 }
00186 imageValids[layer][chan]=true;
00187 }
00188
00189
00190
00191
00192
00193