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
00017 #ifdef OGL_USED
00018 #include "OglGui/OglLib.cpp"
00019 #endif
00020 #include "Link/ImpalaLib.cpp"
00021
00022
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
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;
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;
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;
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
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);
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 };
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 }
00607 }
00608
00609 int
00610 main(int argc, char* argv[])
00611 {
00612 return Impala::Application::mainServer(argc, argv);
00613 }