00001
00002
00003 #ifndef Impala_Visualization_VideoPlayer_h
00004 #define Impala_Visualization_VideoPlayer_h
00005
00006 #include <time.h>
00007
00008 #ifndef Impala_Core_Array_Arrays_h
00009 #include "Core/Array/Arrays.h"
00010 #endif
00011
00012 #ifndef Impala_Core_Stream_RgbDataSrcFactory_h
00013 #include "Core/Stream/RgbDataSrcFactory.h"
00014 #endif
00015
00016 #ifndef OglGui_Window_h
00017 #include "OglGui/Window.h"
00018 #endif
00019
00020
00021
00022 #ifndef Impala_Visualization_VideoPlayerListener_h
00023 #include "Visualization/VideoPlayerListener.h"
00024 #endif
00025
00026 namespace Impala {
00027 namespace Visualization {
00028
00029 class VideoPlayer : public OglGui::Window
00030 {
00031 public:
00032 typedef Impala::Core::Stream::RgbDataSrcFactory RgbDataSrcFactory;
00033 typedef Impala::Core::Stream::RgbDataSrc RgbDataSrc;
00034 typedef Impala::Core::Array::Array2dVec3UInt8 Array2dVec3UInt8;
00035 typedef OglGui::Window Window;
00036
00037 VideoPlayer(int x, int y, int w, int h,
00038 strconst videoFileName="", strconst videoType="lavc"):
00039 Window(x, y, w, h)
00040 {
00041 Init(w, h, videoFileName, videoType);
00042 }
00043
00044 VideoPlayer(Window* parent, int w, int h,
00045 strconst videoFileName="", strconst videoType="lavc"):
00046 Window(parent, w, h)
00047 {
00048 Init(w, h, videoFileName, videoType);
00049 }
00050
00051 VideoPlayer(Window* parent,int x,int y,int w,int h,
00052 strconst videoFileName="", strconst videoType="lavc"):
00053 Window(parent, x, y, w, h)
00054 {
00055 Init(w, h, videoFileName, videoType);
00056 }
00057
00058 void SetVideoPlayerListener(VideoPlayerListener* listener, void* userData)
00059 {
00060 mListener = listener;
00061 mListenerData = userData;
00062 }
00063 void SetVideoPlayerListener(VideoPlayerListener* listener, int userData)
00064 {
00065 SetVideoPlayerListener(listener,(void*)userData);
00066 }
00067
00068
00069 static RgbDataSrc*
00070 Construct(String videoName, strconst videoType)
00071 {
00072 #ifndef REPOSITORY_USED
00073 RgbDataSrcFactory& factory = RgbDataSrcFactory::Instance();
00074 RgbDataSrc* rgbDataSrc = factory.Construct(videoName, videoType);
00075 #else
00076 Persistency::RgbDataSrcLocator loc("file:", "abs", videoName);
00077 RgbDataSrcFactory& factory = RgbDataSrcFactory::Instance();
00078 RgbDataSrc* rgbDataSrc = factory.Construct(loc, videoType);
00079 #endif
00080 if (!rgbDataSrc || !rgbDataSrc->Valid())
00081 {
00082 ILOG_ERROR("Construct Rgb [" << videoName << "] " << "failed");
00083 if (rgbDataSrc)
00084 delete rgbDataSrc;
00085 return 0;
00086 }
00087 return rgbDataSrc;
00088 }
00089
00090 void OpenVideo(strconst videoFileName, strconst videoType, int lastFrame=-1,
00091 int partitionInto=1, int partitionIndex = 0)
00092 {
00093 RgbDataSrc* rgbDataSrc = Construct(videoFileName, videoType);
00094 OpenVideo(rgbDataSrc, lastFrame, partitionInto, partitionIndex);
00095 }
00096
00097 void OpenVideo(RgbDataSrc *video, int lastFrame=-1,
00098 int partitionInto=1, int partitionIndex = 0)
00099 {
00100 if (mOwnRgbDataSrc && mRgbDataSrc)
00101 delete mRgbDataSrc;
00102
00103 if ( !(mRgbDataSrc = video))
00104 {
00105 viewSys.SetImage(mOglView,0);
00106 return;
00107 }
00108
00109 if (!mRgbDataSrc->Valid())
00110 {
00111 ILOG_WARN("OpenVideo stream failed");
00112 return;
00113 }
00114
00115 mRgbDataSrc->Reset();
00116
00117 if (partitionInto < 1)
00118 return;
00119 if (partitionIndex < 0 || partitionIndex >= partitionInto)
00120 return;
00121
00122 if (lastFrame < 0)
00123 lastFrame = mRgbDataSrc->LastFrame();
00124 if (lastFrame < 0 || lastFrame == RgbDataSrc::LASTFRAME_UNKNOWN)
00125 {
00126 mRgbDataSrc->GotoFrame(RgbDataSrc::LASTFRAME_UNKNOWN);
00127 lastFrame = mRgbDataSrc->LastFrame();
00128 }
00129 mStartFrame = (partitionIndex * lastFrame) / partitionInto;
00130 if (partitionIndex > 0)
00131 mStartFrame++;
00132 mEndFrame = ((partitionIndex + 1) * lastFrame) / partitionInto;
00133
00134 ILOG_SYSTEM("OpenVideo: " << partitionIndex+1 << " of " <<
00135 partitionInto << ": " << mStartFrame << " -- " <<
00136 mEndFrame << " in " << lastFrame << " frames.");
00137
00138 mRgbDataSrc->GotoFrame(mStartFrame);
00139
00140 OGLIMAGE* im = OglImageReadFrame(mRgbDataSrc);
00141 mImW = im->w;
00142 mImH = im->h;
00143 IsPower2(mImW, &mPower2W);
00144 IsPower2(mImH, &mPower2H);
00145 im->noTexScaling = 1;
00146
00147 viewSys.SetImage(mOglView, im);
00148 oglSys.ReleaseOglImage(im);
00149 }
00150
00151 int FrameNr()
00152 {
00153 if (mRgbDataSrc)
00154 return mRgbDataSrc->FrameNr();
00155 return -1;
00156 }
00157
00158 int LastFrame()
00159 {
00160 if (mRgbDataSrc)
00161 return mRgbDataSrc->LastFrame();
00162 return -1;
00163 }
00164
00165 void Play()
00166 {
00167 if (!mRgbDataSrc)
00168 return;
00169 if (mRgbDataSrc->FrameNr() >= mEndFrame)
00170 Rewind();
00171 mPlaying = true;
00172 mIncrement = 1;
00173 mLastTime = mTimer->SplitTime();
00174 oglSys.SetAlwaysDraw(mOglWnd, true);
00175 }
00176
00177 void Stop()
00178 {
00179 mPlaying = false;
00180 SetAlwaysDraw(false);
00181 UpdateScene();
00182 }
00183
00184 void Reset()
00185 {
00186 Stop();
00187 if (mRgbDataSrc)
00188 {
00189 mRgbDataSrc->Reset();
00190 ReadFrameIntoOglImage(mRgbDataSrc, mOglView->im);
00191 }
00192 }
00193
00194 void FFwd()
00195 {
00196 Play();
00197 mNormalSpeed = false;
00198 }
00199
00200 void FBwd()
00201 {
00202 if (!mRgbDataSrc)
00203 return;
00204
00205
00206
00207
00208
00209
00210 mIncrement = -1;
00211 mPlaying = true;
00212 mNormalSpeed = false;
00213 mLastTime = mTimer->SplitTime();
00214 oglSys.SetAlwaysDraw(mOglWnd, true);
00215 }
00216
00217
00218 void Rewind()
00219 {
00220 GotoFrame(mStartFrame);
00221 }
00222
00223 void NextFrame(int inc=1)
00224 {
00225 if (!mRgbDataSrc)
00226 return;
00227 int fr = mRgbDataSrc->FrameNr() + inc;
00228 if (inc > 0 && fr >= mEndFrame)
00229 fr = mLoopVideo ? mStartFrame : mEndFrame;
00230 if (inc < 0 && fr < mStartFrame)
00231 fr = mLoopVideo ? mEndFrame : mStartFrame;
00232 if (fr != mRgbDataSrc->FrameNr())
00233 GotoFrame(fr);
00234 }
00235
00236 void GotoFrame(int frameNr)
00237 {
00238 if (!mRgbDataSrc)
00239 return;
00240 mRgbDataSrc->GotoFrame(frameNr);
00241 ReadFrameIntoOglImage(mRgbDataSrc,mOglView->im,0);
00242 }
00243
00244 bool Playing() { return mPlaying; }
00245 bool FFwding() { return mPlaying&& !mNormalSpeed && mIncrement > 0; }
00246 bool FBwding() { return mPlaying && !mNormalSpeed && mIncrement < 0; }
00247 OGLVIEW* OglView() { return mOglView; }
00248
00249 bool GetLoopVideo() { return mLoopVideo; }
00250 void SetLoopVideo(bool value) { mLoopVideo = value; }
00251 void FitViewToWindow(bool mode) { mFitViewToWindow = mode; }
00252 bool FitViewToWindow() { return mFitViewToWindow; }
00253 void ScaleImageToView(bool mode) { mScaleImageToView = mode; }
00254 bool ScaleImageToView() { return mScaleImageToView; }
00255 void NormalSpeed(bool mode) { mNormalSpeed = mode; }
00256 void OwnRgbDataSrc(bool mode) { mOwnRgbDataSrc = mode; }
00257 RgbDataSrc* DataSrc() { return mRgbDataSrc; }
00258 void ShowFrameNr(bool mode) { mShowFrameNr = mode; }
00259 bool ShowFrameNr() { return mShowFrameNr; }
00260
00261 void MoveToFrame(int frameNr)
00262 {
00263 if (mPlaying)
00264 GotoFrame(frameNr);
00265 else {
00266 mMoveToFrameTarget = frameNr;
00267 oglSys.SetAlwaysDraw(mOglWnd,1);
00268 }
00269 }
00270
00271 int GetMoveToFrame()
00272 {
00273 return mMoveToFrameTarget;
00274 }
00275
00276 void StopMoveToFrame()
00277 {
00278 mMoveToFrameTarget = -1;
00279 oglSys.SetAlwaysDraw(mOglWnd,0);
00280 }
00281
00282 void HandleMoveToFrame()
00283 {
00284 if (mMoveToFrameTarget == -1)
00285 return;
00286 if (!mRgbDataSrc || !mOglView || mPlaying)
00287 {
00288 mMoveToFrameTarget = -1;
00289 return;
00290 }
00291 int frameNr = FrameNr();
00292 if (frameNr == -1 || frameNr == mMoveToFrameTarget)
00293 StopMoveToFrame();
00294 else {
00295 int dir = (mMoveToFrameTarget < frameNr) ? -1 : 1;
00296 int inc = (mMoveToFrameTarget - frameNr) / 4;
00297 if (abs(inc)<6) inc = dir;
00298 GotoFrame(frameNr+inc);
00299 }
00300 }
00301
00302 virtual void InitDisplayFunc()
00303 {
00304 if (mFitViewToWindow && mOglView)
00305 viewSys.SetDimensions(mOglView, 2, 2, W()-4, H()-4);
00306
00307 if (mOglView && mScaleImageToView && mOglView->im)
00308 {
00309 float zX = (W()-4)/(float)mImW;
00310 float zY = (H()-4)/(float)mImH;
00311 if (mOglView->texturing && mOglView->im->noTexScaling)
00312 {
00313 zX = ((W()-4)/(float)mImW)*(mPower2W/(float)mImW);
00314 zY = ((H()-4)/(float)mImH)*(mPower2H/(float)mImH);
00315 }
00316 viewSys.SetZoom(mOglView, zX, zY);
00317 }
00318 Window::InitDisplayFunc();
00319 }
00320
00321 virtual void DisplayFunc()
00322 {
00323
00324
00325 try
00326 {
00327 double cpuTime = mTimer->SplitTime();
00328 if (mRgbDataSrc && mPlaying && mOglView)
00329 {
00330 if (!mNormalSpeed || cpuTime-mLastTime >= 0.04)
00331 {
00332 mLastTime = cpuTime + (0.04-(cpuTime-mLastTime));
00333 ReadFrameIntoOglImage(mRgbDataSrc, mOglView->im,mIncrement);
00334 }
00335 }
00336 else if (mMoveToFrameTarget != -1)
00337 HandleMoveToFrame();
00338 Window::DisplayFunc();
00339 if (mRgbDataSrc && mShowFrameNr)
00340 oglSys.ShadowPrintf(mOglWnd,8,8,oglLIGHTGREY,oglBLACK,"%d",
00341 mRgbDataSrc->FrameNr());
00342 if (mRgbDataSrc && mNewFrame && mListener)
00343 mListener->OnNewFrame(this, mRgbDataSrc->FrameNr(), mListenerData);
00344 mNewFrame = false;
00345 }
00346 catch (std::exception e)
00347 {
00348 ILOG_ERROR("Video playback failure");
00349 }
00350
00351
00352 }
00353
00354 virtual void KeyboardFunc(int c, int state)
00355 {
00356 if (c == 'P')
00357 {
00358 char sysBuf[1024];
00359 sprintf(sysBuf, "mplayer -ss %d:%d:%d %s",
00360 mRgbDataSrc->GetHour(), mRgbDataSrc->GetMinute(),
00361 mRgbDataSrc->GetSecond(), mRgbDataSrc->GetName().c_str());
00362 ILOG_INFO("sysbuf = [" << sysBuf << "]");
00363 int sysRes = system(sysBuf);
00364 if (sysRes != 0)
00365 {
00366 ILOG_ERROR("system [" << sysBuf << "]");
00367 return;
00368 }
00369 }
00370 if (c == 'p')
00371 Play();
00372 if (c == 's')
00373 Stop();
00374 if (c == oglHOME)
00375 Reset();
00376 if (c == '+')
00377 NextFrame(1);
00378 if (c == '-')
00379 NextFrame(-1);
00380 if (c == '<')
00381 NextFrame(-10);
00382 if (c == '>')
00383 NextFrame(10);
00384 if (c == 'S')
00385 mScaleImageToView = !mScaleImageToView;
00386 if (c == 'F')
00387 mFitViewToWindow = !mFitViewToWindow;
00388 if (c=='f') FFwd();
00389 if (c=='b') FBwd();
00390 Window::KeyboardFunc(c, state);
00391 if (mListener)
00392 mListener->OnKey(this, c, state, mListenerData);
00393 }
00394
00395
00396 int LastFrameNr()
00397 {
00398 if (mRgbDataSrc == 0)
00399 return -1;
00400 int lastFrame = mRgbDataSrc->LastFrame();
00401 if (lastFrame == RgbDataSrc::LASTFRAME_UNKNOWN)
00402 return -1;
00403 return lastFrame;
00404 }
00405
00406 protected:
00407 static void* OglImdataFunc(OGLIMAGE* oglIm)
00408 {
00409
00410 Array2dVec3UInt8* ar = (Array2dVec3UInt8 *) oglIm->imageHandle;
00411
00412
00413 oglIm->w = ar->CW();
00414 oglIm->h = ar->CH();
00415
00416
00417
00418 return (void *) ar->CPB(0, 0);
00419 }
00420
00421 static void OglImdataDestroyFunc(OGLIMAGE* oglIm)
00422 {
00423 if (!oglIm) return;
00424
00425 Array2dVec3UInt8* ar = (Array2dVec3UInt8 *) oglIm->imageHandle;
00426
00427 if (ar) delete ar;
00428 }
00429
00430 OGLIMAGE* OglImageReadFrame(RgbDataSrc* src)
00431 {
00432 int imW = src->FrameWidth();
00433 int imH = src->FrameHeight();
00434
00435 Array2dVec3UInt8* ar =
00436 new Array2dVec3UInt8(imW, imH, 0, 0, 0, false);
00437
00438 OGLIMAGE* oglIm = oglSys.OglImage(GL_RGB, imW, imH);
00439 oglIm->imDataFunc = OglImdataFunc;
00440 oglIm->onDestroy = OglImdataDestroyFunc;
00441 oglIm->imageHandle = ar;
00442 ReadFrameIntoOglImage(src,oglIm,0);
00443 return oglIm;
00444 }
00445
00446 void ReadFrameIntoOglImage(RgbDataSrc* src, OGLIMAGE *oglIm, int incr=1)
00447 {
00448 if (!src || !oglIm )
00449 return;
00450
00451 int targetFrame = src->FrameNr() + incr;
00452 if (targetFrame < mStartFrame || targetFrame > mEndFrame)
00453 {
00454 if (mLoopVideo)
00455 targetFrame = targetFrame > mEndFrame ? mStartFrame : mEndFrame;
00456 else
00457 {
00458 Stop();
00459 return;
00460 }
00461 }
00462 if (targetFrame != src->FrameNr())
00463 src->GotoFrame(targetFrame);
00464
00465 int imW = src->FrameWidth();
00466 int imH = src->FrameHeight();
00467 Array2dVec3UInt8* ar = (Array2dVec3UInt8 *) oglIm->imageHandle;
00468 memcpy( (void *) ar->CPB(0, 0), src->DataPtr(), imW*imH*3 );
00469 oglIm->changed = 1;
00470 mNewFrame = true;
00471 }
00472
00473
00474
00475
00476
00477
00478
00479
00480
00481
00482
00483
00484
00485
00486
00487
00488
00489
00490
00491
00492
00493
00494
00495
00496
00497
00498
00499
00500
00501 private:
00502
00503 void Init(int w, int h, strconst videoFileName, strconst videoType)
00504 {
00505 GuiGeneralName("VideoPlayer");
00506 GuiName("VideoPlayer");
00507 mRgbDataSrc = 0;
00508
00509 mListener = 0;
00510
00511 mOwnRgbDataSrc = true;
00512 mNewFrame = false;
00513 mIncrement = 1;
00514 mMoveToFrameTarget = -1;
00515 mOglView = 0;
00516 mPlaying = 0;
00517 mLastTime = 0;
00518 mNormalSpeed = true;
00519 mFitViewToWindow = true;
00520 mScaleImageToView = true;
00521 mLoopVideo = false;
00522 mShowFrameNr = false;
00523 mStartFrame = 0;
00524 mEndFrame = 0;
00525
00526 mOglView = viewSys.View2D(mOglWnd, NULL, 0, 0, w, h);
00527 viewSys.SetColor(mOglView, OGL_BG, 0x400000ff);
00528 viewSys.SetTexturing(mOglView, true);
00529 viewSys.SetTags(mOglView, FlexViewTags & ~deletableTag);
00530 viewSys.ClearTags(mOglView, deletableTag|showBorderTag);
00531
00532 if (!(videoFileName == ""))
00533 OpenVideo(videoFileName, videoType);
00534 mTimer = new Timer(1);
00535 }
00536
00537 VideoPlayerListener* mListener;
00538 void* mListenerData;
00539
00540 RgbDataSrc* mRgbDataSrc;
00541 bool mOwnRgbDataSrc;
00542 OGLVIEW* mOglView;
00543
00544 double mLastTime;
00545 bool mNewFrame;
00546 bool mLoopVideo;
00547
00548 int mIncrement;
00549
00550 int mMoveToFrameTarget;
00551
00552 int mImW, mImH;
00553 int mPower2W, mPower2H;
00554
00555 bool mPlaying;
00556 bool mNormalSpeed;
00557 bool mFitViewToWindow;
00558 bool mScaleImageToView;
00559 bool mShowFrameNr;
00560
00561 int mStartFrame;
00562 int mEndFrame;
00563
00564 Timer* mTimer;
00565
00566 ILOG_VAR_DEC;
00567 };
00568
00569 ILOG_VAR_INIT(VideoPlayer, Visualization);
00570
00571 }
00572 }
00573
00574 #endif