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

RotorView.h

Go to the documentation of this file.
00001 //345678901234567890123456789012345678901234567890123456789012345678901234567890
00002 #ifndef Impala_Visualization_RotorBrowser_RotorView_h
00003 #define Impala_Visualization_RotorBrowser_RotorView_h
00004 
00005 #include "Core/Trec/ThreadSet.h"
00006 #include "Basis/CmdOptions.h"
00007 #include "Core/ImageSet/ImageSet.h"
00008 #include "Core/VideoSet/Stills.h"
00009 #include "Core/Array/Arrays.h"
00010 #include "Core/Geometry/Rectangle.h"
00011 
00012 #include "Visualization/RgbOglImage.h"
00013 #include "RotorDoDView.h"
00014 #include "RotorViewCacheResolver.h"
00015 
00016 namespace Impala {
00017 namespace Visualization {
00018 namespace RotorBrowser {
00019 
00020 //using namespace OglGui;
00021 //using namespace Impala::Core::Trec;
00022 
00023 class RotorViewListener
00024 {
00025 public:
00026     virtual void
00027     OnRectangleSelect(int shotID, float x, float y, float w, float h)
00028     {
00029     }
00030 };
00031 
00032 class RotorView : public RectangleListener
00033 {
00034 public:
00035     typedef Core::Trec::Thread              Thread;
00036     typedef Core::Trec::ThreadSet           ThreadSet;
00037     typedef Core::Array::Array2dVec3UInt8   Array2dVec3UInt8;
00038     typedef Core::ImageSet::ImageSet        CoreImageSet;
00039     typedef Core::Stream::RgbDataSrc        RgbDataSrc;
00040     typedef Core::Geometry::Rectangle       GeoRectangle;
00041 
00042 //    RotorView(Window *browser, ThreadSet *threadset, CString name,
00043 //              int nr, float x, float y, RotorViewCacheResolver* resolver=NULL)
00044     RotorView(OglGui::Window *browser, ThreadSet *threadset, CString name,
00045               int nr, float x, float y, RotorViewCacheResolver* resolver=NULL)
00046     {
00047         mViewListener           = NULL;
00048         mNr                     = nr;
00049         mName                   = name;
00050         mThreadSet              = threadset;
00051         mTurnsNotShown          = 0;
00052         mDeleteThreshold        = 5;
00053         mIsBookmarked           = false;
00054         mIsBookmarkedNegative   = false;
00055         mUseKeyframes           = RotorView::KEYFRAMES_NEVER;
00056         mAspectRatio            = 1.375f;
00057         mIsHighRes              = false;
00058         mCurrentRes             = false;
00059         mIsShowingStills        = false;
00060         mStillImages            = NULL;
00061         mVideoSource            = NULL;
00062         mPlayUntilEnd           = false;
00063         mViewBeingRecycled      = false;
00064         mViewedProbability      = 0.0;
00065         mBookmarked             = GetThreadByName("bookmarked");
00066         mBookmarkedNegative     = GetThreadByName("bookmarked_negative");
00067         mRect                   = GeoRectangle(10, 10, 50, 20);
00068         mTimer                  = new Timer(1);
00069         mLastTime               = mTimer->SplitTime();
00070         CmdOptions &options     = CmdOptions::GetInstance();
00071         mUseKeyframes           = options.GetInt("mdBrowserUseKeyframes");
00072 
00073         if (mUseKeyframes == KEYFRAMES_ALWAYS)
00074             mCurrentRes = mIsHighRes = true;
00075 
00076         mAspectRatio = (float)options.GetDouble("mdBrowserAspectRatio");
00077         mForceAspect = mAspectRatio > 0.0 ? true : false;
00078 
00079         RegisterView(browser, x, y, resolver);
00080         UpdateBookmarkState();
00081     }
00082 
00083     ~RotorView()
00084     {
00085         if (!mViewBeingRecycled)
00086             delete mView;
00087 
00088         if (mVideoSource)
00089             delete mVideoSource;
00090     }
00091 
00092     void SetViewListener(RotorViewListener *t)
00093     {
00094         mViewListener = t;
00095     }
00096 
00097     Thread* GetThreadByName(CString name)
00098     {
00099         return mThreadSet->GetThreadByName(name);
00100     }
00101 
00102     inline String GetName() { return mName; }
00103     inline int    GetNR()   { return mNr; }
00104     inline float  GetX()    { return mReqX; }
00105     inline float  GetY()    { return mReqY; }
00106     inline float  GetZ()    { return mReqZ; }
00107     inline float  GetRX()   { return mReqW; }
00108     inline float  GetRY()   { return mReqH; }
00109     
00110     void Rename(CString newname)        { mName = newname; }
00111     void SetViewedProbability(float f)  { mViewedProbability = f; }
00112     void SetPlayUntilEnd(bool v)        { mPlayUntilEnd = v; }
00113     void Hide()                         { mIsShown = false; }
00114     bool IsCurrentlyShown()             { return mIsShown; }
00115     bool GetPlayUntilEnd()              { return mPlayUntilEnd; }
00116     bool GetVideoStillsEnabled()        { return mVideoSource != 0; }
00117 
00118     /* should be called from RotorBrowser::DisplayFunc */
00119     bool DrawView()
00120     {
00121         if (!mIsShown) return false;
00122 
00123         mView->SetVisible(true);
00124         if (mIsShowingStills)
00125             UpdateStill();
00126 
00127         bool stillRequiresMovement = DoPhysics();
00128 
00129         OGLVIEW3D *oglV3D = mView->GetOGLVIEW3D();
00130         if (oglV3D->object3D && oglV3D->im)
00131         {
00132             OGLIMAGE* im = oglV3D->im;
00133             CheckOglImageChanged(im);
00134             // Scale to view dims
00135             float tW = im->noTexScaling ? im->texW : im->w;
00136             float tH = im->noTexScaling ? im->texH : im->h;
00137             float zX = (oglV3D->w)*(tW/im->w);
00138             float zY = (oglV3D->h)*(tH/im->h);
00139             view3DSys.SetZoom(oglV3D,zX,zY);
00140 
00141             float f = (oglV3D->x == 0 || oglV3D->y == 0) ? 0.15 : 0.08;
00142             float opacity = fabs(oglV3D->x * f) + fabs(oglV3D->y * f);
00143             opacity = opacity > 0.8 ? 0.8 : opacity;
00144             mView->SetObscure(opacity);
00145 
00146             float a = sShowPositiveBookmarks&&mIsBookmarked ? 0.2 : 0;
00147             mView->PositiveAlpha(a);
00148             a = sShowNegativeBookmarks&&mIsBookmarkedNegative ? 0.2 : 0;
00149             mView->NegativeAlpha(a);
00150             mView->ProbabiltyAlpha(0);
00151             if (sShowProbabilityFeedback && mViewedProbability > 0)
00152                 mView->ProbabiltyAlpha(mViewedProbability);
00153         }
00154         view3DSys.DrawView(oglV3D);
00155         return stillRequiresMovement | mIsShowingStills;
00156     }
00157 
00158 
00159     void MoveTo(float x, float y, float z, float resX =0.0f, float resY = 0.0f)
00160     {
00161         mReqX = x; mReqY = y; mReqZ = z;
00162         mReqW = resX; mReqH = resY;
00163     }
00164 
00165     void MoveFrom(float x, float y, float z, float resX, float resY)
00166     {
00167         if (!mMoveNow)
00168             return;
00169         mActX = x; mActY = y; mActZ = z;
00170         mActW = resX; mActH = resY;
00171         mMoveNow = false;
00172     }
00173 
00174     void MoveNOW()
00175     {
00176         mActX = mReqX; mActY = mReqY; mActZ = mReqZ;
00177         mActW = mReqW; mActH = mReqH;
00178     }
00179 
00180     void SetRect(GeoRectangle r)
00181     {
00182         mRect = r;
00183         mRect.CheckSize();
00184     }
00185 
00186     GeoRectangle GetRect()
00187     {
00188         return mRect;
00189     }
00190 
00191     void SetShowHighResolution(bool showhighresolution)
00192     {
00193         if (mUseKeyframes == RotorView::KEYFRAMES_ALWAYS)
00194             return;
00195         mIsHighRes = showhighresolution;
00196         UpdateResolution();
00197     }
00198 
00199     bool GetShowHighResolution()
00200     {
00201         return mIsHighRes;
00202     }
00203 
00204     void
00205     SetShowStills(Core::VideoSet::Stills *stills, CoreImageSet* stillImages)
00206     {
00207         mIsShowingStills = true;
00208         if (mStillImages != NULL)
00209             return;
00210 
00211         mStillStart  = stills->GetFirstStillShot(mNr);
00212         mStillEnd    = mStillStart + stills->GetNrStillsShot(mNr);
00213         mStillPos    = mStillStart;
00214         mStillImages = stillImages;
00215     }
00216 
00217     void DisableVideoStills()
00218     {
00219         if (mVideoSource != NULL)
00220         {
00221             delete mVideoSource;
00222             mVideoSource = NULL;
00223         }
00224     }
00225 
00226     bool EnableVideoStills(Core::VideoSet::SegmentationDocument* doc)
00227     {
00228         if (mVideoSource != NULL)
00229             return true;
00230 
00231         int shot = doc->CurShot();
00232         int vidId = doc->CurFileId();
00233         Core::VideoSet::Segmentation* shots = doc->GetSegmentation();
00234         ILOG_DEBUG("RotorView::EnableVideoStills: initializing video stream..");
00235         mVideoSource = doc->GetVideoSet()->GetVideo(vidId);
00236         if (!mVideoSource)
00237             return false;
00238 
00239 // RvB: Added to prevent crashes
00240 #ifdef AS_TODS_BROWSER
00241         if (!mVideoSource->HasIndex())
00242         {
00243             ILOG_WARNING("Video [" << vidId << "] has no index: Not playing");
00244             DisableVideoStills();
00245             return false;
00246         }
00247 #endif
00248         mVideoStart = shots->GetStart(shot) + 1;
00249         mVideoEnd = shots->GetEnd(shot);
00250 
00251         mVideoSource->GotoFrame(mVideoStart);
00252         ILOG_DEBUG( "RotorView::EnableVideoStills: video stream ready." );
00253 
00254         return true;
00255     }
00256     void SetHideStills()
00257     {
00258         mIsShowingStills = false;
00259         // to revert to representative keyframe, enable next line:
00260         // DoUpdateCurrentImage();
00261     }
00262 
00263     void UpdateBookmarkState()
00264     {
00265         if (mBookmarked)
00266             mIsBookmarked = mBookmarked->GetShotPosition(mNr) != -1;
00267         if (mBookmarkedNegative)
00268             mIsBookmarkedNegative=mBookmarkedNegative->GetShotPosition(mNr)!=-1;
00269     }
00270 
00271     bool IsInvalid()
00272     {
00273         if (mViewBeingRecycled)
00274         {
00275             ILOG_WARN( "RotorView::IsInvalid: yes. View is being recycled!" );
00276             return true;
00277         }
00278         return !mIsShown && mTurnsNotShown > mDeleteThreshold;
00279     }
00280 
00281     void Show()
00282     {
00283         if (mViewBeingRecycled)
00284         {
00285             ILOG_WARN("RotorView::Show: view is being recycled! Can't show!" );
00286             return;
00287         }
00288         mIsShown = true;
00289         if (mTurnsNotShown > 2)
00290             mMoveNow = true;
00291         mTurnsNotShown = 0;
00292     }
00293 
00294         void TryDelete()
00295     {
00296         mTurnsNotShown++;
00297         if (IsInvalid())
00298             delete this;
00299     }
00300 
00301         bool IsUnused()
00302     {
00303         mTurnsNotShown++;
00304         return IsInvalid();
00305     }
00306 
00307     RotorDoDView* RecycleView()
00308     {
00309         mIsShown = false;
00310         mViewBeingRecycled = true;
00311         mViewedProbability = 0.0;
00312         view3DSys.SetUserData(mView->GetOGLVIEW3D(), VIEW_ROTORVIEW, NULL);
00313         return mView;
00314     }
00315 
00316     bool IsSameAs(CString name, int nr)
00317     {
00318         return (mNr == nr && mName == name);
00319     }
00320 
00321     // handlers:
00322     virtual void
00323     OnRectangleSelect(float x, float y, float w, float h)
00324     {
00325         if (mViewListener)
00326             mViewListener->OnRectangleSelect(mNr, x, y, w, h);
00327     }
00328 
00329     static void SetStillFrameWait(int fw) {
00330         RotorView::sStillFrameWait = fw;
00331     }
00332     static int GetStillFrameWait() {
00333         return RotorView::sStillFrameWait;
00334     }
00335 
00336     static void SetShowPositiveBookmarks(bool val) {
00337         sShowPositiveBookmarks = val;
00338     }
00339     static bool GetShowPositiveBookmarks()
00340     {
00341         return sShowPositiveBookmarks;
00342     }
00343 
00344     static void SetShowNegativeBookmarks(bool val) {
00345         sShowNegativeBookmarks = val;
00346     }
00347     static bool GetShowNegativeBookmarks() {
00348         return sShowNegativeBookmarks;
00349     }
00350 
00351     static void SetShowProbabilityFeedback(bool val) {
00352         sShowProbabilityFeedback = val;
00353     }
00354     static bool GetShowProbabilityFeedback() {
00355         return sShowProbabilityFeedback;
00356     }
00357 
00358     static void SetSpeedFactor(float f)
00359     {
00360         if (f > 1.0 && f < 20.0)
00361             RotorView::sFactor = f;
00362         if (f <= 1.0)
00363             RotorView::sFactor = 1.0;
00364     }
00365     static float GetSpeedFactor()
00366     {
00367         return RotorView::sFactor;
00368     }
00369 
00370 private:
00371 
00372     void UpdateResolution()
00373     {
00374         if (mUseKeyframes == KEYFRAMES_CENTER && mIsHighRes != mCurrentRes)
00375         {
00376             // returning to low resolution would be silly;
00377             if (!mIsHighRes) return;
00378 
00379             ILOG_DEBUG("Switching to keyframe image for "<< mName << ":"<<mNr);
00380             DoUpdateCurrentImage();
00381         }
00382     }
00383 
00384     // RvB: Placed in its own function to prevent double coding
00385     // Exact copies were coded inside:
00386     //      DoUpdateCurrentImage, UpdateStill, RegisterView
00387     void UpdateWithImage(Array2dVec3UInt8* image)
00388     {
00389         if (image == NULL)
00390         {
00391             ILOG_WARN( "NULL image received for shot ID " << mNr );
00392             return;
00393         }
00394 
00395         OGLIMAGE* oldOglIm = mView->GetOGLIMAGE();
00396         Array2dVec3UInt8* oldIm = (Array2dVec3UInt8*) oldOglIm->imageHandle;
00397 
00398         // RvB: The new image only has to have smaller dims then texture
00399         //if ((image->CW() != oldIm->CW()) || (image->CH() != oldIm->CH()))
00400         if ((image->CW() > oldOglIm->texW) || (image->CH() > oldOglIm->texH))
00401         {
00402             ILOG_DEBUG( "Changed resolution from "
00403                         << oldIm->CW() << "x" << oldIm->CH()
00404                         << " to " << image->CW() << "x" << image->CH());
00405             OGLIMAGE *im = InitOGLIMAGE(image);
00406             mView->SetImage(im);
00407             oglSys.ReleaseOglImage(im);
00408         }
00409         else
00410         {
00411             delete oldIm;
00412             oldOglIm->imageHandle = image;
00413             oldOglIm->w = image->CW();
00414             oldOglIm->h = image->CH();
00415             oldOglIm->changed = 1;
00416         }
00417         oglSys.ReleaseOglImage(oldOglIm);
00418     }
00419 
00420     void DoUpdateCurrentImage()
00421     {
00422         Array2dVec3UInt8* image = mThreadSet->GetImageByShotID(mNr,mIsHighRes);
00423         UpdateWithImage(image);
00424         mCurrentRes = mIsHighRes;
00425     }
00426 
00427     bool HasNextStill()
00428     {
00429         double cpuTime = mTimer->SplitTime();
00430         double frTime  = mVideoSource ? 0.04 : RotorView::sStillFrameWait*0.01;
00431         if (cpuTime-mLastTime >= frTime)
00432         {
00433             mLastTime = cpuTime;
00434             return true;
00435         }
00436         return false;
00437     }
00438 
00439     Array2dVec3UInt8* getNextStill()
00440     {
00441         if (mVideoSource != NULL)
00442         {
00443             RgbDataSrc* src = mVideoSource;
00444             if (src->TheEnd())
00445                 src->GotoFrame(mVideoStart);
00446             else if (!mPlayUntilEnd && src->FrameNr() > mVideoEnd)
00447                 src->GotoFrame(mVideoStart);
00448             else
00449                 src->NextFrame();
00450             return Core::Array::ArrayCreate<Array2dVec3UInt8>
00451               (src->FrameWidth(),src->FrameHeight(),0,0,src->DataPtr(),true);
00452         }
00453 
00454         if ((mStillPos += 1) >= mStillEnd)
00455             mStillPos = mStillStart;
00456         return mStillImages->GetImage(mStillPos);
00457     }
00458 
00459     // RvB: Changed to use UpdateWithImage
00460     void UpdateStill()
00461     {
00462         if (!HasNextStill()) return;
00463 
00464         Array2dVec3UInt8* image = getNextStill();
00465         UpdateWithImage(image);
00466     }
00467 
00468     void
00469     //RegisterView(Window *b, float x, float y, RotorViewCacheResolver* resolver)
00470     RegisterView(OglGui::Window *b, float x, float y, RotorViewCacheResolver* resolver)
00471     {
00472         mBrowser    = b;
00473         mCurrentRes = mIsHighRes;
00474 
00475         Array2dVec3UInt8* image = mThreadSet->GetImageByShotID(mNr,mIsHighRes);
00476         OGLWND*           oglWnd = b->GetOGLWND();
00477         if (image == NULL)
00478         {
00479             ILOG_WARN("NULL image received for shot ID " << mNr);
00480             mView = new RotorDoDView(oglWnd,NULL,x,y,-10.0f,1.0f,1.0f,1.0f);
00481         }
00482         else
00483         {
00484             int imW = image->CW(), imH = image->CH();
00485             if (!mForceAspect)
00486                 mAspectRatio = imH==0 ? 1.f : imW/(float)imH;
00487             if (resolver) // recycle old RotorDoDView for new purposes.
00488             {                
00489                 // This is fastest when old view had the same texture size.
00490                 if (!(mView = resolver->FindRecycledView(imW, imH)))
00491                     ILOG_ERROR("RegisterView:resolver should not return NULL!");
00492                 UpdateWithImage(image);
00493             }
00494             else // nothing to recycle: create a new view
00495             {   
00496                 OGLIMAGE *im = InitOGLIMAGE(image);
00497                 mView = new RotorDoDView(oglWnd,im,x,y,-100.0f,1.0f,1.0f,1.0f);
00498                 oglSys.ReleaseOglImage(im);
00499             }
00500         }
00501 
00502         view3DSys.SetUserData(mView->GetOGLVIEW3D(), VIEW_ROTORVIEW, this);
00503 
00504          // map rectangle select to this RotorView now.
00505         mView->SetCurrentRotorView(this);
00506 
00507         mActX = mReqX = x;
00508         mActY = mReqY = y;
00509         mActZ = mReqZ = -10.0f;
00510 
00511         mActW = mActH = mReqW = mReqH = 0.0f;
00512         mMoveNow = true;
00513     }
00514 
00515 /*
00516     void removeView()
00517     {
00518         // destroy the RotorDoDView only when it's not being recycled:
00519         if (!mViewBeingRecycled) {
00520             delete mView;
00521         }
00522     }
00523 */
00524 
00525 protected:
00526     OGLIMAGE* InitOGLIMAGE(Array2dVec3UInt8* im)
00527     {
00528         OGLIMAGE* oglIm = RgbOglImage::OglImage(im);
00529         oglIm->noTexScaling = 1;
00530         oglIm->changed = 1;
00531         return oglIm;
00532     }
00533 
00534 private:
00535     bool DoPhysics()
00536     {
00537         mView->GetDimensions3D(&mActX,&mActY,&mActZ,NULL,NULL,NULL);
00538 
00539         if (mMoveNow)
00540         {
00541             mActX = mReqX; mActY = mReqY; mActZ = mReqZ;
00542             mActW = mReqW; mActH = mReqH;
00543             mMoveNow = false;
00544         }
00545         else
00546         {
00547             mActX += (mReqX - mActX) / sFactor;
00548             mActY += (mReqY - mActY) / sFactor;
00549             mActZ += (mReqZ - mActZ) / sFactor;
00550             mActW += (mReqW - mActW) / sFactor;
00551             mActH += (mReqH - mActH) / sFactor;
00552         }
00553         float vW = mAspectRatio >  1.0 ? mActW*mAspectRatio : mActW;
00554         float vH = mAspectRatio <= 1.0 ? mActW/mAspectRatio : mActW;
00555         mView->SetDimensions3D(mActX,mActY,mActZ,vW,vH,FRETAIN);
00556 
00557         return AlmostAtDestiny() ? false : true;
00558     }
00559 
00560     bool AlmostAtDestiny()
00561     {
00562         return IsAlmost(mActX, mReqX) &&
00563                IsAlmost(mActY, mReqY) &&
00564                IsAlmost(mActZ, mReqZ) &&
00565                IsAlmost(mActW, mReqW) &&
00566                IsAlmost(mActH, mReqH);
00567     }
00568 
00569     bool IsAlmost(float a, float r)
00570     {
00571         return (a==r) || (a>r && a - r < 0.01) || (r>a && r - a < 0.01);
00572     }
00573 
00574     //Window*                 mBrowser;
00575     OglGui::Window*         mBrowser;
00576     RotorDoDView*           mView;
00577     RotorViewListener*      mViewListener;
00578 
00579     ThreadSet*              mThreadSet;
00580     Thread*                 mBookmarked;
00581     Thread*                 mBookmarkedNegative;
00582 
00583     GeoRectangle            mRect;
00584 
00585     CoreImageSet*           mStillImages;
00586     RgbDataSrc*             mVideoSource;
00587 
00588     String                  mName;
00589 
00590     Timer*                  mTimer;
00591     double                  mLastTime;
00592 
00593     int                     mNr;
00594     int                     mTurnsNotShown;
00595     int                     mDeleteThreshold;
00596     int                     mUseKeyframes;
00597 
00598     int                     mVideoStart, mVideoEnd;
00599     int                     mStillStart, mStillEnd;
00600     int                     mStillPos;
00601 
00602     float                   mActX, mActY, mActZ, mActW, mActH; // actual XYZWH
00603     float                   mReqX, mReqY, mReqZ, mReqW, mReqH; // requested
00604     float                   mAspectRatio;
00605     float                   mViewedProbability;
00606 
00607     bool                    mIsShown;
00608     bool                    mMoveNow;
00609     bool                    mIsBookmarked;
00610     bool                    mIsBookmarkedNegative;
00611     bool                    mForceAspect;
00612     bool                    mIsHighRes;
00613     bool                    mCurrentRes;
00614     bool                    mViewBeingRecycled;
00615     bool                    mPlayUntilEnd;
00616     bool                    mIsShowingStills;
00617 
00618     static float            sFactor;
00619     static int              sStillFrameWait;
00620     static bool             sShowNegativeBookmarks;
00621     static bool             sShowPositiveBookmarks;
00622     static bool             sShowProbabilityFeedback;
00623 
00624 public:
00625     static const int        KEYFRAMES_NEVER  = 0;
00626     static const int        KEYFRAMES_CENTER = 1;
00627     static const int        KEYFRAMES_ALWAYS = 2;
00628     static const int        VIEW_ROTORVIEW   = 4;
00629  
00630    ILOG_VAR_DEC;
00631 
00632 }; // class RotorView
00633 
00634 ILOG_VAR_INIT(RotorView, Visualization.RotorBrowser);
00635 
00636 float   RotorView::sFactor                  = 1.0;
00637 int     RotorView::sStillFrameWait          = 15;
00638 
00639 bool    RotorView::sShowNegativeBookmarks   = true;
00640 bool    RotorView::sShowPositiveBookmarks   = true;
00641 bool    RotorView::sShowProbabilityFeedback = false;
00642 }
00643 }
00644 }
00645 #endif

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