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