2016-02-07 13:26:40 +01:00
# include <iostream>
2016-07-10 23:14:23 +02:00
2018-12-27 23:11:32 +01:00
# include <hyperion/Hyperion.h>
2016-02-11 15:50:51 +01:00
2014-01-26 14:23:08 +01:00
// Blackborder includes
# include <blackborder/BlackBorderProcessor.h>
2013-08-21 22:44:17 +02:00
2013-08-23 07:08:44 +02:00
using namespace hyperion ;
2018-12-27 23:11:32 +01:00
BlackBorderProcessor : : BlackBorderProcessor ( Hyperion * hyperion , QObject * parent )
: QObject ( parent )
, _hyperion ( hyperion )
, _enabled ( false )
, _unknownSwitchCnt ( 600 )
, _borderSwitchCnt ( 50 )
, _maxInconsistentCnt ( 10 )
, _blurRemoveCnt ( 1 )
, _detectionMode ( " default " )
, _detector ( nullptr )
2016-07-10 23:14:23 +02:00
, _currentBorder ( { true , - 1 , - 1 } )
, _previousDetectedBorder ( { true , - 1 , - 1 } )
, _consistentCnt ( 0 )
, _inconsistentCnt ( 10 )
2018-12-27 23:11:32 +01:00
, _oldThreshold ( - 0.1 )
, _hardDisabled ( false )
, _userEnabled ( false )
{
// init
handleSettingsUpdate ( settings : : BLACKBORDER , _hyperion - > getSetting ( settings : : BLACKBORDER ) ) ;
// listen for settings updates
connect ( _hyperion , & Hyperion : : settingsChanged , this , & BlackBorderProcessor : : handleSettingsUpdate ) ;
// listen for component state changes
2020-02-26 18:54:56 +01:00
connect ( _hyperion , & Hyperion : : compStateChangeRequest , this , & BlackBorderProcessor : : handleCompStateChangeRequest ) ;
2018-12-27 23:11:32 +01:00
}
BlackBorderProcessor : : ~ BlackBorderProcessor ( )
{
delete _detector ;
}
void BlackBorderProcessor : : handleSettingsUpdate ( const settings : : type & type , const QJsonDocument & config )
{
if ( type = = settings : : BLACKBORDER )
{
const QJsonObject & obj = config . object ( ) ;
_unknownSwitchCnt = obj [ " unknownFrameCnt " ] . toInt ( 600 ) ;
_borderSwitchCnt = obj [ " borderFrameCnt " ] . toInt ( 50 ) ;
_maxInconsistentCnt = obj [ " maxInconsistentCnt " ] . toInt ( 10 ) ;
_blurRemoveCnt = obj [ " blurRemoveCnt " ] . toInt ( 1 ) ;
_detectionMode = obj [ " mode " ] . toString ( " default " ) ;
2018-12-28 18:12:45 +01:00
const double newThreshold = obj [ " threshold " ] . toDouble ( 5.0 ) / 100.0 ;
2018-12-27 23:11:32 +01:00
2018-12-28 18:12:45 +01:00
if ( _oldThreshold ! = newThreshold )
2018-12-27 23:11:32 +01:00
{
2018-12-28 18:12:45 +01:00
_oldThreshold = newThreshold ;
if ( _detector ! = nullptr )
delete _detector ;
_detector = new BlackBorderDetector ( newThreshold ) ;
2018-12-27 23:11:32 +01:00
}
Debug ( Logger : : getInstance ( " BLACKBORDER " ) , " Set mode to: %s " , QSTRING_CSTR ( _detectionMode ) ) ;
// eval the comp state
2020-02-26 18:54:56 +01:00
handleCompStateChangeRequest ( hyperion : : COMP_BLACKBORDER , obj [ " enable " ] . toBool ( true ) ) ;
2018-12-27 23:11:32 +01:00
}
}
2020-02-26 18:54:56 +01:00
void BlackBorderProcessor : : handleCompStateChangeRequest ( const hyperion : : Components component , bool enable )
2013-08-21 22:44:17 +02:00
{
2018-12-27 23:11:32 +01:00
if ( component = = hyperion : : COMP_BLACKBORDER )
2016-07-15 10:28:12 +02:00
{
2018-12-27 23:11:32 +01:00
_userEnabled = enable ;
if ( enable )
{
// eg effects and probably other components don't want a BB, mimik a wrong comp state to the comp register
if ( ! _hardDisabled )
_enabled = enable ;
}
else
{
_enabled = enable ;
}
2020-02-26 18:54:56 +01:00
_hyperion - > setNewComponentState ( hyperion : : COMP_BLACKBORDER , enable ) ;
2016-07-15 10:28:12 +02:00
}
2013-08-21 22:44:17 +02:00
}
2018-12-27 23:11:32 +01:00
void BlackBorderProcessor : : setHardDisable ( const bool & disable ) {
if ( disable )
{
_enabled = false ;
}
else
{
// the user has the last word to enable
if ( _userEnabled )
_enabled = true ;
}
_hardDisabled = disable ;
} ;
2013-08-21 22:44:17 +02:00
BlackBorder BlackBorderProcessor : : getCurrentBorder ( ) const
{
return _currentBorder ;
}
2016-07-15 10:28:12 +02:00
bool BlackBorderProcessor : : enabled ( ) const
{
return _enabled ;
}
void BlackBorderProcessor : : setEnabled ( bool enable )
{
_enabled = enable ;
}
2013-11-11 10:00:37 +01:00
bool BlackBorderProcessor : : updateBorder ( const BlackBorder & newDetectedBorder )
2016-01-10 14:41:47 +01:00
{
2016-01-19 23:43:00 +01:00
// the new changes ignore false small borders (no reset of consistance)
// as long as the previous stable state returns within 10 frames
// and will only switch to a new border if it is realy detected stable >50 frames
// sometimes the grabber delivers "bad" frames with a smaller black border (looks like random number every few frames and even when freezing the image)
// maybe some interferences of the power supply or bad signal causing this effect - not exactly sure what causes it but changing the power supply of the converter significantly increased that "random" effect on my system
// (you can check with the debug output below or if you want i can provide some output logs)
// this "random effect" caused the old algorithm to switch to that smaller border immediatly, resulting in a too small border being detected
// makes it look like the border detectionn is not working - since the new 3 line detection algorithm is more precise this became a problem specialy in dark scenes
// wisc
2016-02-07 13:26:40 +01:00
// std::cout << "c: " << setw(2) << _currentBorder.verticalSize << " " << setw(2) << _currentBorder.horizontalSize << " p: " << setw(2) << _previousDetectedBorder.verticalSize << " " << setw(2) << _previousDetectedBorder.horizontalSize << " n: " << setw(2) << newDetectedBorder.verticalSize << " " << setw(2) << newDetectedBorder.horizontalSize << " c:i " << setw(2) << _consistentCnt << ":" << setw(2) << _inconsistentCnt << std::endl;
2016-01-19 23:43:00 +01:00
2016-01-10 14:41:47 +01:00
// set the consistency counter
if ( newDetectedBorder = = _previousDetectedBorder )
{
+ + _consistentCnt ;
_inconsistentCnt = 0 ;
}
else
2013-08-21 22:44:17 +02:00
{
2016-01-19 23:43:00 +01:00
+ + _inconsistentCnt ;
2016-02-07 13:26:40 +01:00
if ( _inconsistentCnt < = _maxInconsistentCnt ) // only few inconsistent frames
2016-01-19 23:43:00 +01:00
{
//discard the newDetectedBorder -> keep the consistent count for previousDetectedBorder
return false ;
}
// the inconsistency threshold is reached
// -> give the newDetectedBorder a chance to proof that its consistent
2013-11-11 10:00:37 +01:00
_previousDetectedBorder = newDetectedBorder ;
2013-08-23 18:24:10 +02:00
_consistentCnt = 0 ;
}
2013-10-27 09:25:02 +01:00
// check if there is a change
2013-11-11 10:00:37 +01:00
if ( _currentBorder = = newDetectedBorder )
2013-08-23 18:24:10 +02:00
{
// No change required
2016-01-19 23:43:00 +01:00
_inconsistentCnt = 0 ; // we have found a consistent border -> reset _inconsistentCnt
2013-08-23 18:24:10 +02:00
return false ;
2013-08-21 22:44:17 +02:00
}
bool borderChanged = false ;
2013-11-11 10:00:37 +01:00
if ( newDetectedBorder . unknown )
2013-08-21 22:44:17 +02:00
{
2013-10-27 09:25:02 +01:00
// apply the unknown border if we consistently can't determine a border
2016-01-10 18:42:55 +01:00
if ( _consistentCnt = = _unknownSwitchCnt )
2013-08-23 18:24:10 +02:00
{
2013-11-11 10:00:37 +01:00
_currentBorder = newDetectedBorder ;
2013-08-23 18:24:10 +02:00
borderChanged = true ;
}
2013-10-27 09:25:02 +01:00
}
else
{
// apply the detected border if it has been detected consistently
2016-01-10 18:42:55 +01:00
if ( _currentBorder . unknown | | _consistentCnt = = _borderSwitchCnt )
2013-08-21 22:44:17 +02:00
{
2013-11-11 10:00:37 +01:00
_currentBorder = newDetectedBorder ;
2013-08-21 22:44:17 +02:00
borderChanged = true ;
}
}
return borderChanged ;
2016-07-15 10:28:12 +02:00
}