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

VideoPlayer.h

Go to the documentation of this file.
00001 //345678901234567890123456789012345678901234567890123456789012345678901234567890
00002 // Author: Richard van Balen
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 //#include "Visualization/ThreadSystemWnd.h"
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++; // we dont want overlapping frame ranges
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         int oldIncr = mIncrement;
00206         if (mIncrement > 0)
00207             oldIncr = 0;
00208         mIncrement = oldIncr-1;
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 //SK
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 //SK
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     // SK experimental
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             // Obtain our 'im' stored as 'imageHandle'
00410         Array2dVec3UInt8* ar = (Array2dVec3UInt8 *) oglIm->imageHandle;
00411 
00412         // Set oglIm dimensions to our 'im' dimensions
00413             oglIm->w = ar->CW();
00414             oglIm->h = ar->CH();
00415         // RvB: Saver to do this after texture loading rather than here
00416             //oglIm->changed = 0;
00417 
00418             return (void *) ar->CPB(0, 0); // Pointer to the image pixels
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     void ReadFrameIntoOglImage(RgbDataSrc* src, OGLIMAGE *oglIm, int incr=1)
00474     {
00475         if (!src || !oglIm )
00476             return;
00477 
00478         int targetFrame = src->FrameNr() + incr;
00479         if (targetFrame < mStartFrame)
00480             targetFrame = mStartFrame;
00481         else if (targetFrame > mEndFrame)
00482         {
00483             if (mLoopVideo)
00484                 targetFrame = mStartFrame;
00485             else {
00486                 Stop();
00487                 return;
00488             }
00489         }
00490         if (targetFrame != src->FrameNr())
00491             src->GotoFrame(targetFrame);
00492 
00493             int imW = src->FrameWidth();
00494             int imH = src->FrameHeight();
00495             Array2dVec3UInt8* ar = (Array2dVec3UInt8 *) oglIm->imageHandle;
00496             memcpy( (void *) ar->CPB(0, 0), src->DataPtr(), imW*imH*3 );
00497             oglIm->changed = 1;
00498         mNewFrame = true;
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; // SK
00524         mEndFrame = 0; // SK
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; // SK
00562     int             mEndFrame;   // SK
00563 
00564     Timer*          mTimer;
00565 
00566     ILOG_VAR_DEC;
00567 };
00568 
00569 ILOG_VAR_INIT(VideoPlayer, Visualization);
00570 
00571 } // namespace Visualization
00572 } // namespace Impala
00573 
00574 #endif

Generated on Fri Mar 19 09:31:55 2010 for ImpalaSrc by  doxygen 1.5.1