Line data Source code
1 : /* Copyright (c) 2009 Maxim Makhinya
2 : *
3 : * This library is free software; you can redistribute it and/or modify it under
4 : * the terms of the GNU Lesser General Public License version 2.1 as published
5 : * by the Free Software Foundation.
6 : *
7 : * This library is distributed in the hope that it will be useful, but WITHOUT
8 : * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
9 : * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
10 : * details.
11 : *
12 : * You should have received a copy of the GNU Lesser General Public License
13 : * along with this library; if not, write to the Free Software Foundation, Inc.,
14 : * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
15 : */
16 :
17 : #include "roiTracker.h"
18 :
19 : namespace eq
20 : {
21 :
22 0 : ROITracker::Area::Area( const PixelViewport& pvp_,
23 : uint32_t lastSkip_,
24 : uint32_t skip_ )
25 : :pvp( pvp_ )
26 : ,lastSkip( lastSkip_ )
27 0 : ,skip( skip_ )
28 : {
29 0 : }
30 :
31 :
32 3 : ROITracker::ROITracker()
33 3 : : _needsUpdate( false )
34 : {
35 3 : _ticket = reinterpret_cast< uint8_t* >( this );
36 3 : _prvFrame = new stde::hash_map< uint32_t, Stage >;
37 3 : _curFrame = new stde::hash_map< uint32_t, Stage >;
38 3 : }
39 :
40 :
41 3 : ROITracker::~ROITracker()
42 : {
43 3 : delete _prvFrame;
44 3 : delete _curFrame;
45 3 : _prvFrame = 0;
46 3 : _curFrame = 0;
47 3 : }
48 :
49 :
50 0 : bool ROITracker::_returnPositive( uint8_t*& ticket )
51 : {
52 0 : ticket = ++_ticket;
53 0 : _needsUpdate = true;
54 0 : return true;
55 : }
56 :
57 0 : bool ROITracker::useROIFinder( const PixelViewport& pvp,
58 : const uint32_t stage,
59 : const uint128_t& frameID,
60 : uint8_t*& ticket )
61 : {
62 0 : LBASSERT( !_needsUpdate );
63 0 : ticket = 0;
64 :
65 0 : const uint32_t pvpArea = pvp.getArea();
66 0 : if( pvpArea < 100 )
67 0 : return false;
68 :
69 0 : if( _lastFrameID != frameID ) // new frame
70 : {
71 0 : stde::hash_map< uint32_t, Stage >* tmp = _prvFrame;
72 0 : _prvFrame = _curFrame;
73 0 : _curFrame = tmp;
74 0 : _curFrame->clear();
75 0 : _lastFrameID = frameID;
76 : }
77 :
78 0 : _lastStage = stage;
79 :
80 0 : Stage& curStage = (*_curFrame)[ stage ];
81 :
82 : // check if proper stage is avaliable
83 0 : if( _prvFrame->find( stage ) == _prvFrame->end( )) // new stage
84 : {
85 0 : curStage.areas.push_back( Area( pvp ));
86 0 : return _returnPositive( ticket );
87 : }
88 : //else existing stage, try to find matching area
89 :
90 0 : const Area* match = 0;
91 0 : uint32_t bestArea = 0;
92 0 : const Stage& prvStage = (*_prvFrame)[ stage ];
93 0 : for( uint32_t i = 0; i < prvStage.areas.size(); i++ )
94 : {
95 0 : PixelViewport tmp = prvStage.areas[i].pvp;
96 0 : tmp.intersect( pvp );
97 0 : const uint32_t area = tmp.getArea();
98 0 : if( area > bestArea )
99 : {
100 0 : bestArea = area;
101 0 : match = &prvStage.areas[i];
102 0 : if( area == pvpArea ) // full match
103 0 : break;
104 : }
105 : }
106 :
107 0 : if( bestArea < pvpArea*2/3 ) // no proper match found, new area
108 : {
109 0 : curStage.areas.push_back( Area( pvp ));
110 0 : return _returnPositive( ticket );
111 : }
112 : // else good match
113 :
114 0 : if( match->skip == 0 ) // don't skip frame
115 : {
116 0 : curStage.areas.push_back( Area( pvp, match->lastSkip ));
117 0 : return _returnPositive( ticket );
118 : }
119 : //else skip frame
120 :
121 0 : curStage.areas.push_back( Area( pvp, match->lastSkip, match->skip-1 ));
122 0 : return false;
123 : }
124 :
125 :
126 0 : void ROITracker::updateDelay( const PixelViewports& pvps,
127 : const uint8_t* ticket )
128 : {
129 0 : LBASSERT( _needsUpdate );
130 0 : LBASSERTINFO( ticket == _ticket, "Wrong ticket" );
131 :
132 0 : if( ticket != _ticket )
133 : {
134 0 : LBERROR << "Wrong ticket" << std::endl;
135 0 : return;
136 : }
137 :
138 0 : uint32_t totalAreaFound = 0;
139 0 : for( uint32_t i = 0; i < pvps.size(); i++ )
140 0 : totalAreaFound += pvps[ i ].getArea();
141 :
142 0 : Area& area = (*_curFrame)[ _lastStage ].areas.back();
143 0 : if( totalAreaFound < area.pvp.getArea()*4/5 )
144 : {
145 : // ROI cutted enough, reset failure statistics
146 0 : area.lastSkip = 0;
147 : }else
148 : {
149 : // disable ROI for next frames, if it was failing before,
150 : // increase number of frames to skip
151 0 : area.lastSkip = LB_MIN( area.lastSkip*2 + 1, 64 );
152 0 : area.skip = area.lastSkip;
153 : }
154 0 : _needsUpdate = false;
155 : }
156 :
157 36 : }
158 :
159 :
|