LCOV - code coverage report
Current view: top level - eq - roiTracker.cpp (source / functions) Hit Total Coverage
Test: Equalizer Lines: 13 73 17.8 %
Date: 2017-12-16 05:07:20 Functions: 4 9 44.4 %

          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           0 : ROITracker::Area::Area(const PixelViewport& pvp_, uint32_t lastSkip_,
      22           0 :                        uint32_t skip_)
      23             :     : pvp(pvp_)
      24             :     , lastSkip(lastSkip_)
      25           0 :     , skip(skip_)
      26             : {
      27           0 : }
      28             : 
      29           2 : ROITracker::ROITracker()
      30             :     : _needsUpdate(false)
      31           2 :     , _lastStage(0)
      32             : {
      33           2 :     _ticket = reinterpret_cast<uint8_t*>(this);
      34           2 :     _prvFrame = new std::unordered_map<uint32_t, Stage>;
      35           2 :     _curFrame = new std::unordered_map<uint32_t, Stage>;
      36           2 : }
      37             : 
      38           4 : ROITracker::~ROITracker()
      39             : {
      40           2 :     delete _prvFrame;
      41           2 :     delete _curFrame;
      42           2 :     _prvFrame = 0;
      43           2 :     _curFrame = 0;
      44           2 : }
      45             : 
      46           0 : bool ROITracker::_returnPositive(uint8_t*& ticket)
      47             : {
      48           0 :     ticket = ++_ticket;
      49           0 :     _needsUpdate = true;
      50           0 :     return true;
      51             : }
      52             : 
      53           0 : bool ROITracker::useROIFinder(const PixelViewport& pvp, const uint32_t stage,
      54             :                               const uint128_t& frameID, uint8_t*& ticket)
      55             : {
      56           0 :     LBASSERT(!_needsUpdate);
      57           0 :     ticket = 0;
      58             : 
      59           0 :     const uint32_t pvpArea = pvp.getArea();
      60           0 :     if (pvpArea < 100)
      61           0 :         return false;
      62             : 
      63           0 :     if (_lastFrameID != frameID) // new frame
      64             :     {
      65           0 :         std::unordered_map<uint32_t, Stage>* tmp = _prvFrame;
      66           0 :         _prvFrame = _curFrame;
      67           0 :         _curFrame = tmp;
      68           0 :         _curFrame->clear();
      69           0 :         _lastFrameID = frameID;
      70             :     }
      71             : 
      72           0 :     _lastStage = stage;
      73             : 
      74           0 :     Stage& curStage = (*_curFrame)[stage];
      75             : 
      76             :     // check if proper stage is avaliable
      77           0 :     if (_prvFrame->find(stage) == _prvFrame->end()) // new stage
      78             :     {
      79           0 :         curStage.areas.push_back(Area(pvp));
      80           0 :         return _returnPositive(ticket);
      81             :     }
      82             :     // else existing stage, try to find matching area
      83             : 
      84           0 :     const Area* match = 0;
      85           0 :     uint32_t bestArea = 0;
      86           0 :     const Stage& prvStage = (*_prvFrame)[stage];
      87           0 :     for (uint32_t i = 0; i < prvStage.areas.size(); i++)
      88             :     {
      89           0 :         PixelViewport tmp = prvStage.areas[i].pvp;
      90           0 :         tmp.intersect(pvp);
      91           0 :         const uint32_t area = tmp.getArea();
      92           0 :         if (area > bestArea)
      93             :         {
      94           0 :             bestArea = area;
      95           0 :             match = &prvStage.areas[i];
      96           0 :             if (area == pvpArea) // full match
      97           0 :                 break;
      98             :         }
      99             :     }
     100             : 
     101           0 :     if (bestArea < pvpArea * 2 / 3) // no proper match found, new area
     102             :     {
     103           0 :         curStage.areas.push_back(Area(pvp));
     104           0 :         return _returnPositive(ticket);
     105             :     }
     106             :     // else good match
     107             : 
     108           0 :     if (match->skip == 0) // don't skip frame
     109             :     {
     110           0 :         curStage.areas.push_back(Area(pvp, match->lastSkip));
     111           0 :         return _returnPositive(ticket);
     112             :     }
     113             :     // else skip frame
     114             : 
     115           0 :     curStage.areas.push_back(Area(pvp, match->lastSkip, match->skip - 1));
     116           0 :     return false;
     117             : }
     118             : 
     119           0 : void ROITracker::updateDelay(const PixelViewports& pvps, const uint8_t* ticket)
     120             : {
     121           0 :     LBASSERT(_needsUpdate);
     122           0 :     LBASSERTINFO(ticket == _ticket, "Wrong ticket");
     123             : 
     124           0 :     if (ticket != _ticket)
     125             :     {
     126           0 :         LBERROR << "Wrong ticket" << std::endl;
     127           0 :         return;
     128             :     }
     129             : 
     130           0 :     uint32_t totalAreaFound = 0;
     131           0 :     for (uint32_t i = 0; i < pvps.size(); i++)
     132           0 :         totalAreaFound += pvps[i].getArea();
     133             : 
     134           0 :     Area& area = (*_curFrame)[_lastStage].areas.back();
     135           0 :     if (totalAreaFound < area.pvp.getArea() * 4 / 5)
     136             :     {
     137             :         // ROI cutted enough, reset failure statistics
     138           0 :         area.lastSkip = 0;
     139             :     }
     140             :     else
     141             :     {
     142             :         // disable ROI for next frames, if it was failing before,
     143             :         // increase number of frames to skip
     144           0 :         area.lastSkip = LB_MIN(area.lastSkip * 2 + 1, 64);
     145           0 :         area.skip = area.lastSkip;
     146             :     }
     147           0 :     _needsUpdate = false;
     148             : }
     149          30 : }

Generated by: LCOV version 1.11