Home || Architecture || Video Search || Visual Search || Scripts || Applications || Important Messages || OGL || Src

mainDataServer.cpp

Go to the documentation of this file.
00001 #include "Basis/CmdOptions.h"
00002 
00003 #include "Persistency/FileSystem.h"
00004 #include "Util/Channel.h"
00005 #include "Util/ChannelServer.h"
00006 #include "Util/Database.h"
00007 #include "Util/SimpleMap.h"
00008 
00009 #include "Core/Array/Arrays.h"
00010 
00011 #include "Core/Stream/RgbDataSrcFactory.h"
00012 #include "Core/Stream/RgbDataDstFactory.h"
00013 
00014 #include "Link/DiskImage/DiskImageFuncs.h"
00015 
00016 // since we are not using libraries:
00017 #ifdef OGL_USED
00018 #include "OglGui/OglLib.cpp"
00019 #endif
00020 #include "Link/ImpalaLib.cpp"
00021 
00022 // cannot use log4cpp as library on sunos due to linker bug:
00023 #ifdef LOG4CPP_USED
00024 #ifdef sun
00025 #define LOG4CPPHACK
00026 #endif
00027 #ifdef LOG4CPPHACK
00028 #include "Link/Log4cppLib.cpp"
00029 #endif
00030 #endif
00031 
00032 namespace Impala
00033 {
00034 namespace Application
00035 {
00036 
00037 
00038 using namespace Util;
00039 using namespace Link;
00040 
00041 /********************************************************************
00042  Instances of this class serve data to e.g. video processing clients.
00043 *********************************************************************/
00044 class DataServer : public ChannelServer
00045 {
00046 
00047 public:
00048 
00049     DataServer(int port, int nrPorts, CString passwordFile, bool useDstTypeWin) 
00050         : ChannelServer(port, nrPorts, true, passwordFile)
00051     {
00052         Init(useDstTypeWin);
00053     }
00054 
00055     virtual
00056     ~DataServer()
00057     {
00058     }
00059 
00060     void 
00061     HandleIdle()
00062     {
00063         ChannelServer::HandleIdle();
00064 
00065         if (mDst == 0)
00066             return;
00067         int done = 0;
00068         mDst->WindowManage(done, GetStatusBuffer());
00069     }
00070 
00071 
00072 protected:
00073 
00074     virtual int
00075     AcceptRequest(char* buf, int len, int bufSize, CString conn, int port)
00076     {
00077         int rcBase = ChannelServer::AcceptRequest(buf, len, bufSize, conn, port);
00078         if (rcBase >= 0)
00079             return rcBase;
00080 
00081         String curCon = ConnectionDescr();
00082 #ifndef REPOSITORY_USED // Here comes the deprecated stuff
00083         Database& db = Database::GetInstance();
00084 #else // REPOSITORY_USED
00085         Persistency::FileSystem db("", "");
00086 #endif // REPOSITORY_USED
00087         ILogErrors& errors = ILogErrors::GetInstance();
00088         errors.Mark();
00089 
00090         if (strncmp(buf, "domkdirpath", 11) == 0)
00091         {
00092             ILOG_DEBUG("Doing domkdirpath for " << curCon);
00093             int index = 11;
00094             String dir = ReadQuotedString(buf, index, len);
00095             String dataPath = ReadQuotedString(buf, index, len);
00096             ILOG_DEBUG("dir : [" << dir << "]");
00097             if (! AllowWrite(port))
00098             {
00099                 ILOG_ERROR("Write is not authorized for dir " << dir);
00100             }
00101             else
00102             {
00103                 db.SetDataPath(dataPath);
00104                 String res = db.MakeDir(dir);
00105                 ILOG_DEBUG("res : [" << res << "]");
00106                 sprintf(buf, "%s\0", res.c_str());
00107             }
00108         }
00109 
00110         else if (strncmp(buf, "getreadablefile", 15) == 0)
00111         {
00112             ILOG_DEBUG("Doing getreadablefile for " << curCon);
00113             int index = 15;
00114             String fileName = ReadQuotedString(buf, index, len);
00115             String dataPath = ReadQuotedString(buf, index, len);
00116             int silent = 0;
00117             if (index < len)
00118                 sscanf(buf + index, "%d", &silent);
00119             ILOG_DEBUG("name : [" << fileName << "], data : [" << dataPath <<
00120                        "], silent = " << silent);
00121             db.SetDataPath(dataPath);
00122             String res = db.GetFilePath(fileName, false, (silent != 0));
00123             ILOG_DEBUG("res : [" << res << "]");
00124             sprintf(buf, "%s\0", res.c_str());
00125         }
00126 
00127         else if (strncmp(buf, "getwritablefile", 15) == 0)
00128         {
00129             ILOG_DEBUG("Doing getwritablefile for " << curCon);
00130             int index = 15;
00131             String fileName = ReadQuotedString(buf, index, len);
00132             String dataPath = ReadQuotedString(buf, index, len);
00133             if (! AllowWrite(port))
00134             {
00135                 ILOG_ERROR("Write is not authorized for " << fileName);
00136             }
00137             else
00138             {
00139                 int silent = 0;
00140                 int override = 0;
00141                 if (index < len)
00142                     sscanf(buf + index, "%d %d", &silent, &override);
00143                 ILOG_DEBUG("name : [" << fileName << "], data : [" << dataPath
00144                            << "], silent = " << silent << ", override = "
00145                            << override);
00146                 db.SetDataPath(dataPath);
00147                 db.SetOverride(override != 0);
00148                 String res = db.GetFilePath(fileName, true, (silent != 0));
00149                 ILOG_DEBUG("res : [" << res << "]");
00150                 sprintf(buf, "%s\0", res.c_str());
00151             }
00152         }
00153 
00154         else if (strncmp(buf, "openfilebuffer", 14) == 0)
00155         {
00156             ILOG_DEBUG("Doing openfilebuffer for " << curCon);
00157             int index = 14;
00158             String fileName = ReadQuotedString(buf, index, len);
00159             int readMode = 123;
00160             if (index < len)
00161                 sscanf(buf + index, "%d", &readMode);
00162             ILOG_DEBUG("name : [" << fileName << "], readMode = " << readMode);
00163             if ((! readMode) && (! AllowWrite(port)))
00164             {
00165                 ILOG_ERROR("Write is not authorized for " << fileName);
00166             }
00167             else if (DiskImage::DiskImageUsed() &&
00168                      fileName.substr(0, 10) == "diskimage:")
00169             {
00170                 int posAfterDiskImageFileName = fileName.find("://", 10);
00171                 String realFilePath =
00172                     fileName.substr(10, posAfterDiskImageFileName-10);
00173                 String filePathInImage =
00174                     fileName.substr(posAfterDiskImageFileName+1);
00175                 DiskImage::FileDescriptor* desc =
00176                     DiskImage::OpenFile(realFilePath, filePathInImage);
00177                 if (!desc)
00178                     return -1;
00179 
00180                 sprintf(buf, "%d %lld\0", mFileBuffersId,
00181                         DiskImage::GetFileSize(desc));
00182                 BufInf inf = BufInfCtor(port, mFileBuffersId++);
00183                 mFileBuffersDiskImage.Add(inf, desc);
00184             }
00185             else
00186             {
00187                 IOBufferFile* ioBuf = new IOBufferFile(fileName, readMode!=0,
00188                                                        false);
00189                 if (!ioBuf->Valid())
00190                 {
00191                     ILOG_ERROR("Unable to open file [" << fileName << "]");
00192                 }
00193                 else
00194                 {
00195                     sprintf(buf, "%d %lld\0", mFileBuffersId, ioBuf->Size());
00196                     BufInf inf = BufInfCtor(port, mFileBuffersId++);
00197                     mFileBuffers.Add(inf, ioBuf);
00198                 }
00199             }
00200         }
00201 
00202         else if (strncmp(buf, "readfilebuffer", 14) == 0)
00203         {
00204             ILOG_DEBUG("Doing readfilebuffer for " << curCon);
00205             int id;
00206             int nrToRead;
00207             sscanf(buf, "readfilebuffer %d %d", &id, &nrToRead);
00208             ILOG_DEBUG("id = " << id << ", nrToRead = " << nrToRead);
00209             nrToRead = Min(Channel::DATA_BUFFER_SIZE, nrToRead);
00210             BufInf inf = BufInfCtor(port, id);
00211             IOBufferFile* ioBuf;
00212             if (mFileBuffers.Get(inf, ioBuf))
00213             {
00214                 int nrToSend = ioBuf->Read(buf, nrToRead);
00215                 return nrToSend; // buffer used for binary data, so return 
00216             }
00217             if (DiskImage::DiskImageUsed())
00218             {
00219                 DiskImage::FileDescriptor* desc;
00220                 if (mFileBuffersDiskImage.Get(inf, desc))
00221                 {
00222                     int bytesRead = DiskImage::ReadFile(desc, buf, nrToRead);
00223                     return bytesRead; // buffer used for binary data, so return 
00224                 }
00225             }
00226             ILOG_ERROR("No file buffer " << id);
00227             return -1;
00228         }
00229 
00230         else if (strncmp(buf, "writefilebuffer", 15) == 0)
00231         {
00232             ILOG_DEBUG("Doing writefilebuffer for " << curCon);
00233             int id;
00234             sscanf(buf, "writefilebuffer %d", &id);
00235             ILOG_DEBUG("id = " << id);
00236             IOBufferFile* ioBuf;
00237             BufInf inf = BufInfCtor(port, id);
00238             if (!mFileBuffers.Get(inf, ioBuf))
00239             {
00240                 ILOG_ERROR("No file buffer " << id);
00241             }
00242             else
00243             {
00244                 int used = strlen(buf) + 1;
00245                 ioBuf->Write(buf+used, len-used);
00246                 sprintf(buf, "OK\0");
00247             }
00248         }
00249 
00250         else if (strncmp(buf, "seekfilebuffer", 14) == 0)
00251         {
00252             ILOG_DEBUG("Doing seekfilebuffer for " << curCon);
00253             int id;
00254             Int64 offset;
00255             int whence;
00256             sscanf(buf, "seekfilebuffer %d %lld %d", &id, &offset, &whence);
00257             ILOG_DEBUG("id = " << id << ", offset = " << offset << ", whence = "
00258                        << whence);
00259             BufInf inf = BufInfCtor(port, id);
00260             IOBufferFile* ioBuf;
00261             if (mFileBuffers.Get(inf, ioBuf))
00262             {
00263                 sprintf(buf, "%lld\0", ioBuf->Seek(offset, whence));
00264             }
00265             else 
00266             {
00267                 DiskImage::FileDescriptor* desc;
00268                 if (DiskImage::DiskImageUsed() &&
00269                     mFileBuffersDiskImage.Get(inf, desc))
00270                 {
00271                     Int64 newPosition = DiskImage::SeekFile(desc, offset,
00272                                                             whence);
00273                     sprintf(buf, "%lld\0", newPosition);
00274                 }
00275                 else
00276                 {
00277                     ILOG_ERROR("No file buffer " << id);
00278                     return -1;
00279                 }
00280             }
00281         }
00282 
00283         else if (strncmp(buf, "closefilebuffer", 15) == 0)
00284         {
00285             ILOG_DEBUG("Doing closefilebuffer for " << curCon);
00286             int id;
00287             sscanf(buf, "closefilebuffer %d", &id);
00288             ILOG_DEBUG("id = " << id);
00289             BufInf inf = BufInfCtor(port, id);
00290             IOBufferFile* ioBuf;
00291             if (mFileBuffers.Get(inf, ioBuf))
00292             {
00293                 mFileBuffers.Remove(inf);
00294                 sprintf(buf, "OK\0");
00295             }
00296             else
00297             {
00298                 DiskImage::FileDescriptor* desc;
00299                 if (DiskImage::DiskImageUsed() &&
00300                     mFileBuffersDiskImage.Get(inf, desc))
00301                 {
00302                     DiskImage::CloseFile(desc);
00303                     mFileBuffersDiskImage.Remove(inf);
00304                     sprintf(buf, "OK\0");
00305                 }
00306                 else
00307                 {
00308                     ILOG_ERROR("No file buffer " << id);
00309                     return -1;
00310                 }
00311             }
00312         }
00313 
00314         else if (strncmp(buf, "testdata", 8) == 0)
00315         {
00316             ILOG_DEBUG("Doing testdata for " << curCon);
00317             int nrBytes;
00318             sscanf(buf, "testdata %d", &nrBytes);
00319             nrBytes = Min(Channel::DATA_BUFFER_SIZE, nrBytes);
00320             ILOG_DEBUG("nrBytes = " << nrBytes);
00321             static int val = 100;
00322             memset(buf, val, nrBytes);
00323             val += 10;
00324             if (val > 255)
00325                 val = 0;
00326             return nrBytes;
00327         }
00328 
00329         else if (strncmp(buf, "opensrc", 7) == 0)
00330         {
00331             using Core::Stream::RgbDataSrcFactory;
00332             ILOG_DEBUG("Doing opensrc for " << curCon);
00333             if (mSrc)
00334             {
00335                 delete mSrc;
00336                 mSrc = 0;
00337             }
00338             int index = 7;
00339             String srcName = ReadQuotedString(buf, index, len);
00340             ILOG_DEBUG("name : [" << srcName << "]");
00341             int src = RgbDataSrcFactory::Instance().SuggestSrc(srcName);
00342 #ifndef REPOSITORY_USED // Here comes the deprecated stuff
00343             mSrc = RgbDataSrcFactory::Instance().Construct(src, srcName);
00344 #else // REPOSITORY_USED
00345             Persistency::RgbDataSrcLocator loc("file:", ".", srcName);
00346             mSrc = RgbDataSrcFactory::Instance().Construct(src, loc);
00347 #endif // REPOSITORY_USED
00348             if ((mSrc == 0) || (! mSrc->Valid()))
00349             {
00350                 ILOG_ERROR("RgbDataSrc failed");
00351             }
00352             else
00353             {
00354                 sprintf(buf, "%d %d\0", mSrc->FrameWidth(),
00355                         mSrc->FrameHeight());
00356             }
00357         }
00358 
00359         else if (strncmp(buf, "nextframe", 9) == 0)
00360         {
00361             ILOG_DEBUG("Doing nextframe for " << curCon);
00362             if ((mSrc == 0) || (! mSrc->Valid()))
00363             {
00364                 ILOG_ERROR("no RgbDataSrc");
00365             }
00366             else
00367             {
00368                 mSrc->NextFrame();
00369                 if (mSrc->DataPtr() == 0)
00370                 {
00371                     ILOG_ERROR("RgbDataSrc::nextFrame has no data");
00372                 }
00373                 else
00374                 {
00375                     int dataSize = mSrc->FrameWidth() * mSrc->FrameHeight() * 3;
00376                     dataSize = Min(Channel::DATA_BUFFER_SIZE, dataSize);
00377                     memcpy(buf, mSrc->DataPtr(), dataSize);
00378                     return dataSize;
00379                 }
00380             }
00381         }
00382 
00383 #ifdef OGL_USED
00384         else if (strncmp(buf, "opendst", 7) == 0)
00385         {
00386             ILOG_DEBUG("Doing opendst for " << curCon);
00387             if (mDst != 0)
00388             {
00389                 ILOG_ERROR("dst already open");
00390             }
00391             else
00392             {
00393                 String dstName("ogl");
00394                 sscanf(buf, "opendst %d %d", &mDstWidth, &mDstHeight);
00395                 mDst = Core::Stream::RgbDataDstFactory::Instance().Construct
00396                     (mDstType, dstName, mDstWidth, mDstHeight);
00397                 if ((mDst == 0) || (! mDst->Valid()))
00398                 {
00399                     ILOG_ERROR("RgbDataDst failed");
00400                 }
00401                 else
00402                 {
00403                     mDstBuf = new unsigned char[mDstWidth * mDstHeight * 3];
00404                     HandleIdle();
00405                     sprintf(buf, "OK\0");
00406                 }
00407             }
00408         }
00409 
00410         else if (strncmp(buf, "show", 4) == 0)
00411         {
00412             ILOG_DEBUG("Doing show for " << curCon);
00413             if ((mDst == 0) || (! mDst->Valid()))
00414             {
00415                 ILOG_ERROR("no RgbDataDst");
00416             }
00417             else
00418             {
00419                 mFramesDone++;
00420                 int dataSize = mDstWidth * mDstHeight * 3;
00421                 memcpy(mDstBuf, buf+5, dataSize);
00422                 mDst->NextFrame(mDstBuf);
00423                 HandleIdle();
00424                 sprintf(buf, "OK\0");
00425             }
00426         }
00427 #endif
00428 
00429 #ifndef REPOSITORY_USED // Here comes the deprecated stuff
00430         else if (strncmp(buf, "readvideoindex", 14) == 0)
00431         {
00432             ILOG_DEBUG("Doing readvideoindex for " << curCon);
00433             int index = 14;
00434             String videoFileName = ReadQuotedString(buf, index, len);
00435             String dataPath = ReadQuotedString(buf, index, len);
00436             ILOG_DEBUG("videoFileName : [" << videoFileName << "], data : ["
00437                        << dataPath << "]");
00438 
00439             if (!dataPath.empty())
00440                 db.SetDataPath(dataPath);
00441 
00442             Int64 bufferUsed = WriteVideoAsHashes(buf, videoFileName, db);
00443             if (bufferUsed >= 0)
00444                 sprintf(buf + bufferUsed, "\0");
00445         }
00446 #endif // REPOSITORY_USED
00447 
00448         else
00449         {
00450             return -1;
00451         }
00452 
00453         if (errors.GetNrErrorsSinceMark() > 0)
00454         {
00455             String last = errors.GetLastErrorSinceMark();
00456             sprintf(buf, "ERROR : last error at server : %s\0", last.c_str());
00457         }
00458 
00459         return strlen(buf) + 1; // use this exit for textual responses only!
00460     }
00461 
00462     virtual void
00463     AcceptDisconnect(int port)
00464     {
00465         std::vector<BufInf> v = mFileBuffers.GetAllIdx();
00466         for (int i=0 ; i<v.size() ; i++)
00467         {
00468             BufInf inf = v[i];
00469             int p = BufInfPort(inf);
00470             if (p == port)
00471             {
00472                 ILOG_DEBUG("cleaning buffer " << BufInfPort(inf) << " " <<
00473                            BufInfBufferId(inf));
00474                 mFileBuffers.Remove(inf);
00475             }
00476         }
00477 
00478         std::vector<BufInf> w = mFileBuffersDiskImage.GetAllIdx();
00479         for (int i=0 ; i<w.size() ; i++)
00480         {
00481             BufInf inf = w[i];
00482             int p = BufInfPort(inf);
00483             if (p == port)
00484             {
00485                 ILOG_DEBUG("cleaning buffer " << BufInfPort(inf) << " " <<
00486                            BufInfBufferId(inf));
00487                 mFileBuffersDiskImage.Remove(inf);
00488             }
00489         }
00490     }
00491 
00492     // overrides base member
00493     virtual void 
00494     UpdateStatusBuf()
00495     {
00496         double timeVal = SplitTime();
00497         double fps = (double) mFramesDone / timeVal;
00498         std::ostrstream statusStream;
00499         statusStream << "Did " << mFramesDone << " frames in " << timeVal
00500                      << " sec = " << fps << " fps" << std::ends;
00501         strcpy(GetStatusBuffer(), statusStream.str());
00502         statusStream.freeze(false); // prevents mem leak
00503     }
00504 
00505 
00506 private:
00507 
00508     void 
00509     Init(bool useDstTypeWin)
00510     {
00511         mDstType = Core::Stream::RgbDataDstFactory::DST_OGL;
00512         if (useDstTypeWin)
00513             mDstType = Core::Stream::RgbDataDstFactory::DST_WIN;
00514         mFramesDone = 0;
00515         mSrc = 0;
00516         mDst = 0;
00517         mDstBuf = 0;
00518         mFileBuffersId = 1000;
00519     }
00520 
00521     typedef UInt64 BufInf;
00522     
00523     BufInf
00524     BufInfCtor(int port, int bufferId)
00525     {
00526         return (((BufInf) port) << 32) | ((BufInf) bufferId);
00527     }
00528 
00529     int
00530     BufInfPort(BufInf inf)
00531     {
00532         return (inf & 0xFFFFFFFF00000000LL) >> 32;
00533     }
00534 
00535     int
00536     BufInfBufferId(BufInf inf)
00537     {
00538         return (inf & 0x00000000FFFFFFFFLL);
00539     }
00540 
00541 #ifndef REPOSITORY_USED // Here comes the deprecated stuff
00542     Int64
00543     WriteVideoAsHashes(char* buf, String videoFileName, Database& db)
00544     {
00545 #ifdef AVC_USED
00546         String videoPath = db.GetFilePath(videoFileName, false, false);
00547         if (videoPath.empty())
00548             return -1;
00549         Core::Stream::RgbDataSrcInfo* video = 
00550             new Core::Stream::RgbDataSrcLavc(
00551             Core::Stream::RgbDataSrcFactory::SRC_LAVC, videoPath, &db, READIDX);
00552         if (!video)
00553             return -1;
00554         int bufUsed = video->DumpIndexHashes(buf, Channel::DATA_BUFFER_SIZE);
00555         if (bufUsed < 0)
00556             return -1;
00557         return bufUsed;
00558 #else
00559         return -1;
00560 #endif
00561     }
00562 #endif // REPOSITORY_USED
00563 
00564     int mFramesDone;
00565     Core::Stream::RgbDataSrc* mSrc;
00566     Core::Stream::RgbDataDst* mDst;
00567     int mDstType;
00568     int mDstWidth;
00569     int mDstHeight;
00570     unsigned char* mDstBuf;
00571 
00572     SimpleMapDelete<BufInf, Util::IOBufferFile*> mFileBuffers;
00573     SimpleMapDelete<BufInf, DiskImage::FileDescriptor*> mFileBuffersDiskImage;
00574     int mFileBuffersId;
00575 
00576     ILOG_VAR_DECL;
00577 
00578 }; // class
00579 
00580 ILOG_VAR_INIT(DataServer, Impala.Application);
00581 
00582 int
00583 mainServer(int argc, char* argv[])
00584 {
00585     CmdOptions& options = CmdOptions::GetInstance();
00586     options.Initialise(true, true, true);
00587     options.AddOption(0, "dstWin", "", "0");
00588     options.AddOption(0, "noIdle", "", "0");
00589     if (! options.ParseArgs(argc, argv, "port [nrPorts]", 1))
00590         return 1;
00591 
00592     bool useDstTypeWin = options.GetBool("dstWin");
00593     String passwordFile = options.GetString("passwordFile");
00594     int port = atol(options.GetArg(0));
00595     int nrPorts = 100;
00596     if (options.GetNrArg() > 1)
00597         nrPorts = atol(options.GetArg(1));
00598 
00599     Application::DataServer dataServer(port, nrPorts, passwordFile, useDstTypeWin);
00600     bool doIdle = ! options.GetBool("noIdle");
00601     dataServer.Start(doIdle);
00602 
00603     return 0;
00604 }
00605 
00606 } // namespace Application
00607 } // namespace Impala
00608 
00609 int
00610 main(int argc, char* argv[])
00611 {
00612     return Impala::Application::mainServer(argc, argv);
00613 }

Generated on Fri Mar 19 09:30:28 2010 for ImpalaSrc by  doxygen 1.5.1