roiTracker.cpp
00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #include "roiTracker.h"
00018
00019 namespace eq
00020 {
00021
00022 ROITracker::Area::Area( const PixelViewport& pvp_,
00023 uint32_t lastSkip_,
00024 uint32_t skip_ )
00025 :pvp( pvp_ )
00026 ,lastSkip( lastSkip_ )
00027 ,skip( skip_ )
00028 {
00029 }
00030
00031
00032 ROITracker::ROITracker()
00033 : _needsUpdate( false )
00034 {
00035 _ticket = reinterpret_cast< uint8_t* >( this );
00036 _prvFrame = new stde::hash_map< uint32_t, Stage >;
00037 _curFrame = new stde::hash_map< uint32_t, Stage >;
00038 }
00039
00040
00041 ROITracker::~ROITracker()
00042 {
00043 delete _prvFrame;
00044 delete _curFrame;
00045 _prvFrame = 0;
00046 _curFrame = 0;
00047 }
00048
00049
00050 bool ROITracker::_returnPositive( uint8_t*& ticket )
00051 {
00052 ticket = ++_ticket;
00053 _needsUpdate = true;
00054 return true;
00055 }
00056
00057 bool ROITracker::useROIFinder( const PixelViewport& pvp,
00058 const uint32_t stage,
00059 const uint32_t frameID,
00060 uint8_t*& ticket )
00061 {
00062 EQASSERT( !_needsUpdate );
00063 ticket = 0;
00064
00065 const uint32_t pvpArea = pvp.getArea();
00066 if( pvpArea < 100 )
00067 return false;
00068
00069 if( _lastFrameID != frameID )
00070 {
00071 stde::hash_map< uint32_t, Stage >* tmp = _prvFrame;
00072 _prvFrame = _curFrame;
00073 _curFrame = tmp;
00074 _curFrame->clear();
00075 _lastFrameID = frameID;
00076 }
00077
00078 _lastStage = stage;
00079
00080 Stage& curStage = (*_curFrame)[ stage ];
00081
00082
00083 if( _prvFrame->find( stage ) == _prvFrame->end( ))
00084 {
00085 curStage.areas.push_back( Area( pvp ));
00086 return _returnPositive( ticket );
00087 }
00088
00089
00090 const Area* match = 0;
00091 uint32_t bestArea = 0;
00092 const Stage& prvStage = (*_prvFrame)[ stage ];
00093 for( uint32_t i = 0; i < prvStage.areas.size(); i++ )
00094 {
00095 PixelViewport tmp = prvStage.areas[i].pvp;
00096 tmp.intersect( pvp );
00097 const uint32_t area = tmp.getArea();
00098 if( area > bestArea )
00099 {
00100 bestArea = area;
00101 match = &prvStage.areas[i];
00102 if( area == pvpArea )
00103 break;
00104 }
00105 }
00106
00107 if( bestArea < pvpArea*2/3 )
00108 {
00109 curStage.areas.push_back( Area( pvp ));
00110 return _returnPositive( ticket );
00111 }
00112
00113
00114 if( match->skip == 0 )
00115 {
00116 curStage.areas.push_back( Area( pvp, match->lastSkip ));
00117 return _returnPositive( ticket );
00118 }
00119
00120
00121 curStage.areas.push_back( Area( pvp, match->lastSkip, match->skip-1 ));
00122 return false;
00123 }
00124
00125
00126 void ROITracker::updateDelay( const PixelViewportVector& pvps,
00127 const uint8_t* ticket )
00128 {
00129 EQASSERT( _needsUpdate );
00130 EQASSERTINFO( ticket == _ticket, "Wrong ticket" );
00131
00132 if( ticket != _ticket )
00133 {
00134 EQERROR << "Wrong ticket" << std::endl;
00135 return;
00136 }
00137
00138 uint32_t totalAreaFound = 0;
00139 for( uint32_t i = 0; i < pvps.size(); i++ )
00140 totalAreaFound += pvps[ i ].getArea();
00141
00142 Area& area = (*_curFrame)[ _lastStage ].areas.back();
00143 if( totalAreaFound < area.pvp.getArea()*4/5 )
00144 {
00145
00146 area.lastSkip = 0;
00147 }else
00148 {
00149
00150
00151 area.lastSkip = EQ_MIN( area.lastSkip*2 + 1, 64 );
00152 area.skip = area.lastSkip;
00153 }
00154 _needsUpdate = false;
00155 }
00156
00157 }
00158
00159