2017-09-24 01:54:46 +02:00
if ( Debug . debug )
console . log ( "Loading: ArDetect" ) ;
2017-12-29 23:34:40 +01:00
var _ard _console _stop = "background: #000; color: #f41" ;
var _ard _console _start = "background: #000; color: #00c399" ;
2017-10-02 00:27:01 +02:00
2017-09-27 02:26:47 +02:00
var _ard _currentAr ;
2017-12-29 23:34:40 +01:00
var _ard _setup _timer ;
var _ard _timer
2017-09-27 02:26:47 +02:00
// kjer vzemamo vzorce za blackbox/stuff. 9 vzorcev. Če spremenimo velikost vzorca, moramo spremeniti tudi vrednosti v tej tabeli
2018-03-18 15:14:57 +01:00
// vrednosti v tabeli so na osminskih intervalih od [0, <sample height << 2> - 4].
2017-09-27 02:26:47 +02:00
// we sample these lines in blackbox/stuff. 9 samples. If we change the canvas sample size, we have to correct these values as well
2018-03-18 15:14:57 +01:00
// samples are every eighth between [0, <sample height << 2> - 4].
2018-03-05 23:55:14 +01:00
var _ard _sampleCols = [ ] ;
2017-09-27 02:26:47 +02:00
2017-12-31 18:26:59 +01:00
var _ard _canvasWidth ;
var _ard _canvasHeight ;
var _ard _canvasDrawWindowHOffset = 0 ;
2017-09-27 02:26:47 +02:00
2018-02-26 22:38:17 +01:00
var localSettings = { } ;
2018-02-28 23:54:32 +01:00
2017-09-27 02:26:47 +02:00
// **** FUNCTIONS **** //
2017-09-24 01:54:46 +02:00
2017-12-31 18:26:59 +01:00
var _arSetup = function ( cwidth , cheight ) {
2018-02-28 23:54:32 +01:00
try {
2017-12-29 23:34:40 +01:00
if ( Debug . debug )
console . log ( "%c[ArDetect::_ard_setup] Starting automatic aspect ratio detection" , _ard _console _start ) ;
2017-12-31 18:26:59 +01:00
2017-12-30 18:36:08 +01:00
this . _halted = false ;
2017-12-29 23:34:40 +01:00
2018-03-05 23:55:14 +01:00
// vstavimo začetne stolpce v _ard_sampleCols.
// let's insert initial columns to _ard_sampleCols
_ard _sampleCols = [ ] ;
2018-03-13 23:55:38 +01:00
var samplingIntervalPx = parseInt ( GlobalVars . canvas . height / ExtensionConf . arDetect . samplingInterval )
for ( var i = 1 ; i < ExtensionConf . arDetect . samplingInterval ; i ++ ) {
2018-03-05 23:55:14 +01:00
_ard _sampleCols . push ( i * samplingIntervalPx ) ;
}
2018-02-28 23:54:32 +01:00
2017-12-31 18:26:59 +01:00
var existingCanvas = document . getElementById ( "uw_ArDetect_canvas" ) ;
if ( existingCanvas ) {
if ( Debug . debug )
console . log ( "[ArDetect::_ard_setup] existing canvas found. REMOVING KEBAB removing kebab\n\n\n\n(im hungry and you're not authorized to have it)" ) ;
existingCanvas . remove ( ) ;
if ( Debug . debug )
console . log ( "[ArDetect::_ard_setup] canvas removed" ) ;
}
var vid = document . getElementsByTagName ( "video" ) [ 0 ] ;
2017-09-24 01:54:46 +02:00
2018-04-22 14:35:40 +02:00
if ( vid === undefined || vid === null ) {
2017-12-29 23:34:40 +01:00
_ard _setup _timer = setTimeout ( _arSetup , 1000 ) ;
2017-09-24 01:54:46 +02:00
return ;
}
2017-10-02 00:27:01 +02:00
// imamo video, pa tudi problem. Ta problem bo verjetno kmalu popravljen, zato setup začnemo hitreje kot prej
// we have a video, but also a problem. This problem will prolly be fixed very soon, so setup is called with
// less delay than before
2018-03-07 21:42:40 +01:00
if ( vid . videoWidth === 0 || vid . videoHeight === 0 ) {
if ( ! _ard _timer )
_ard _setup _timer = setTimeout ( _arSetup , 100 ) ;
2017-10-02 00:27:01 +02:00
return ;
}
2018-02-28 23:54:32 +01:00
// things to note: we'll be keeping canvas in memory only.
GlobalVars . arDetect . canvas = document . createElement ( "canvas" ) ;
2017-09-24 01:54:46 +02:00
2018-03-13 23:55:38 +01:00
_ard _canvasWidth = cwidth ? cwidth : ExtensionConf . arDetect . hSamples ;
_ard _canvasHeight = cheight ? cheight : ExtensionConf . arDetect . vSamples ;
2017-09-24 01:54:46 +02:00
2017-10-17 22:17:51 +02:00
if ( Debug . showArDetectCanvas ) {
2018-02-28 23:54:32 +01:00
GlobalVars . arDetect . canvas . style . position = "absolute" ;
GlobalVars . arDetect . canvas . style . left = "200px" ;
2018-03-18 15:14:57 +01:00
GlobalVars . arDetect . canvas . style . top = "1200px" ;
2018-02-28 23:54:32 +01:00
GlobalVars . arDetect . canvas . style . zIndex = 10000 ;
GlobalVars . arDetect . canvas . id = "uw_ArDetect_canvas" ;
var test = document . getElementsByTagName ( "body" ) [ 0 ] ;
test . appendChild ( GlobalVars . arDetect . canvas ) ;
2017-10-02 00:27:01 +02:00
}
2017-09-24 01:54:46 +02:00
2018-02-28 23:54:32 +01:00
var context = GlobalVars . arDetect . canvas . getContext ( "2d" ) ;
2017-09-24 01:54:46 +02:00
// do setup once
// tho we could do it for every frame
2017-12-31 18:26:59 +01:00
if ( cwidth && cheight ) {
var canvasWidth = cwidth ;
var canvasHeight = cheight ;
var canvasScaleFactor = cheight / vid . videoHeight ;
}
else {
var canvasScaleFactor = _ard _canvasWidth / vid . videoWidth ;
var canvasWidth = vid . videoWidth * canvasScaleFactor ;
var canvasHeight = vid . videoHeight * canvasScaleFactor ;
}
2017-09-24 01:54:46 +02:00
2018-02-28 23:54:32 +01:00
GlobalVars . arDetect . canvas . width = canvasWidth ;
GlobalVars . arDetect . canvas . height = canvasHeight ;
2018-04-26 00:40:09 +02:00
2017-09-24 01:54:46 +02:00
2017-12-31 18:26:59 +01:00
try {
// determine where to sample
2018-03-13 23:55:38 +01:00
var ncol = ExtensionConf . arDetect . staticSampleCols ;
var nrow = ExtensionConf . arDetect . staticSampleRows ;
2017-12-31 18:26:59 +01:00
var colSpacing = _ard _canvasWidth / ncol ;
2018-03-18 15:14:57 +01:00
var rowSpacing = ( _ard _canvasHeight << 2 ) / nrow ;
2017-12-31 18:26:59 +01:00
_ard _sampleLines = [ ] ;
_ard _sampleCols = [ ] ;
for ( var i = 0 ; i < ncol ; i ++ ) {
if ( i < ncol - 1 )
_ard _sampleCols . push ( Math . round ( colSpacing * i ) ) ;
else {
_ard _sampleCols . push ( Math . round ( colSpacing * i ) - 1 ) ;
}
}
for ( var i = 0 ; i < nrow ; i ++ ) {
if ( i < ncol - 5 )
_ard _sampleLines . push ( Math . round ( rowSpacing * i ) ) ;
else {
_ard _sampleLines . push ( Math . round ( rowSpacing * i ) - 4 ) ;
}
}
}
catch ( ex ) {
2018-03-13 23:55:38 +01:00
console . log ( "%c[ArDetect::_arSetup] something went terribly wrong when calcuating sample colums." , ExtensionConf . colors . criticalFail ) ;
2017-12-31 18:26:59 +01:00
console . log ( "settings object:" , Settings ) ;
console . log ( "error:" , ex ) ;
}
2018-03-18 17:35:51 +01:00
// we're also gonna reset this
GlobalVars . arDetect . guardLine . top = null ;
GlobalVars . arDetect . guardLine . bottom = null ;
2018-02-15 22:59:31 +01:00
_ard _resetBlackLevel ( ) ;
2017-12-29 23:34:40 +01:00
this . _forcehalt = false ;
2018-02-12 23:28:31 +01:00
// if we're restarting ArDetect, we need to do this in order to force-recalculate aspect ratio
GlobalVars . lastAr = { type : "auto" , ar : null } ;
2018-02-28 23:54:32 +01:00
GlobalVars . canvas . context = context ;
GlobalVars . canvas . width = canvasWidth ;
GlobalVars . canvas . height = canvasHeight ;
2018-03-18 15:14:57 +01:00
GlobalVars . canvas . imageDataRowLength = canvasWidth << 2 ;
2018-03-08 22:22:42 +01:00
GlobalVars . arDetect . noLetterboxCanvasReset = false ;
2018-03-18 15:14:57 +01:00
2018-05-01 23:09:58 +02:00
// GlobalVars.correctedVideoDimensions.height = null;
// GlobalVars.correctedVideoDimensions.width = null;
// GlobalVars.correctedVideoDimensions.top = null;
// GlobalVars.correctedVideoDimensions.left = null;
//
2018-02-28 23:54:32 +01:00
_ard _vdraw ( 0 ) ;
}
catch ( ex ) {
console . log ( ex ) ;
}
2018-04-26 00:40:09 +02:00
2018-05-01 23:09:58 +02:00
if ( Debug . debugCanvas . enabled ) {
2018-04-26 00:40:09 +02:00
DebugCanvas . init ( { width : canvasWidth , height : canvasHeight } ) ;
2018-05-01 23:09:58 +02:00
// DebugCanvas.draw("test marker","test","rect", {x:5, y:5}, {width: 5, height: 5});
2018-04-26 00:40:09 +02:00
}
2017-09-24 01:54:46 +02:00
} ;
2017-12-31 18:26:59 +01:00
var _ard _canvasReadyForDrawWindow = function ( ) {
if ( Debug . debug )
console . log ( "%c[ArDetect::_ard_canvasReadyForDrawWindow] (?)" , "color: #44f" , _ard _canvasHeight == window . innerHeight , "(ard_height:" , _ard _canvasHeight , "| window height:" , window . innerHeight , ")" ) ;
return _ard _canvasHeight == window . innerHeight
}
2017-09-24 01:54:46 +02:00
2017-12-31 18:26:59 +01:00
var _ard _processAr = function ( video , width , height , edge _h , edge _w , fallbackMode ) {
2017-09-24 01:54:46 +02:00
// width, height —> canvas/sample
2018-02-15 00:17:58 +01:00
// edge_w -—> null/undefined, because we don't autocorrect pillarbox yet
2017-12-31 18:26:59 +01:00
2018-01-18 00:11:03 +01:00
if ( Debug . debug && Debug . debugArDetect ) {
console . log ( "[ArDetect::_ard_processAr] processing ar. sample width:" , width , "; sample height:" , height , "; edge top:" , edge _h ) ;
2017-12-31 18:26:59 +01:00
}
2017-09-27 02:26:47 +02:00
// if we don't specify these things, they'll have some default values.
if ( edge _h === undefined ) {
edge _h = 0 ;
edge _w = 0 ;
}
2017-09-24 01:54:46 +02:00
var letterbox = 2 * edge _h ;
var trueHeight = height - letterbox ;
2017-12-31 18:26:59 +01:00
if ( fallbackMode ) {
2018-03-18 15:14:57 +01:00
if ( edge _h > 1 && edge _h <= ExtensionConf . arDetect . fallbackMode . noTriggerZonePx )
2017-12-31 18:26:59 +01:00
return ;
2018-03-18 15:14:57 +01:00
// safety border so we can detect aspect ratio widening
trueHeight += ( ExtensionConf . arDetect . fallbackMode . safetyBorderPx << 1 ) ;
2017-12-31 18:26:59 +01:00
}
2017-09-24 01:54:46 +02:00
var trueAr = width / trueHeight ;
2017-10-02 00:27:01 +02:00
ArDetect . detectedAr = trueAr ;
2017-09-24 01:54:46 +02:00
// poglejmo, če se je razmerje stranic spremenilo
// check if aspect ratio is changed:
2018-02-12 23:28:31 +01:00
if ( GlobalVars . lastAr . type == "auto" && GlobalVars . lastAr . ar != null ) {
// spremembo lahko zavrnemo samo, če uporabljamo avtomatski način delovanja in če smo razmerje stranic
// že nastavili.
//
// we can only deny aspect ratio changes if we use automatic mode and if aspect ratio was set from here.
var arDiff = trueAr - GlobalVars . lastAr . ar ;
if ( arDiff < 0 )
arDiff = - arDiff ;
var arDiff _percent = arDiff / trueAr ;
// ali je sprememba v mejah dovoljenega? Če da -> fertik
// is ar variance within acceptable levels? If yes -> we done
2018-01-02 03:36:29 +01:00
if ( Debug . debug && Debug . debugArDetect )
2018-02-12 23:28:31 +01:00
console . log ( "%c[ArDetect::_ard_processAr] new aspect ratio varies from the old one by this much:\n" , "color: #aaf" , "old Ar" , GlobalVars . lastAr . ar , "current ar" , trueAr , "arDiff (absolute):" , arDiff , "ar diff (relative to new ar)" , arDiff _percent ) ;
2018-03-13 23:55:38 +01:00
if ( arDiff < trueAr * ExtensionConf . arDetect . allowedArVariance ) {
2018-02-12 23:28:31 +01:00
if ( Debug . debug && Debug . debugArDetect )
console . log ( "%c[ArDetect::_ard_processAr] aspect ratio change denied — diff %:" , "background: #740; color: #fa2" , arDiff _percent )
return ;
}
else if ( Debug . debug && Debug . debugArDetect ) {
console . log ( "%c[ArDetect::_ard_processAr] aspect ratio change accepted — diff %:" , "background: #153; color: #4f9" , arDiff _percent )
}
2018-01-02 03:36:29 +01:00
}
2017-10-02 00:27:01 +02:00
2018-02-12 23:28:31 +01:00
if ( Debug . debug )
console . log ( "[ArDetect::_ard_processAr] attempting to fix aspect ratio. New aspect ratio: " , trueAr ) ;
2017-09-24 01:54:46 +02:00
2018-02-12 23:28:31 +01:00
// POMEMBNO: GlobalVars.lastAr je potrebno nastaviti šele po tem, ko kličemo _res_setAr(). _res_setAr() predvideva,
// da želimo nastaviti statično (type: 'static') razmerje stranic — tudi, če funkcijo kličemo tu oz. v ArDetect.
//
// IMPORTANT NOTE: GlobalVars.lastAr needs to be set after _res_setAr() is called, as _res_setAr() assumes we're
// setting a static aspect ratio (even if the function is called from here or ArDetect).
Resizer . setAr ( trueAr ) ;
GlobalVars . lastAr = { type : "auto" , ar : trueAr } ;
2017-09-24 01:54:46 +02:00
}
2018-03-04 23:07:11 +01:00
2018-03-07 21:42:40 +01:00
var clearTimeoutCount = 0 ;
2018-03-04 23:07:11 +01:00
2018-03-07 21:42:40 +01:00
var _ard _vdraw = function ( timeout , force _reset ) {
// don't allow more than 1 instance
if ( _ard _timer ) {
++ clearTimeoutCount ;
clearTimeout ( _ard _timer ) ;
}
2018-02-28 23:54:32 +01:00
_ard _timer = setTimeout ( function ( ) {
2018-03-07 21:42:40 +01:00
_ard _timer = null ;
2018-02-28 23:54:32 +01:00
_ard _vdraw _but _for _reals ( ) ;
} ,
timeout ) ;
}
2018-03-05 23:55:14 +01:00
2018-02-28 23:54:32 +01:00
var _ard _vdraw _but _for _reals = function ( ) {
// thanks dude:
// https://www.reddit.com/r/iiiiiiitttttttttttt/comments/80qnss/i_tried_to_write_something_that_would/duyfg53/
2018-03-05 23:55:14 +01:00
// except this method stops working as soon as I try to do something with the image :/
2018-03-03 23:58:29 +01:00
if ( this . _forcehalt )
2017-12-29 23:34:40 +01:00
return ;
2018-04-22 14:35:40 +02:00
if ( ! GlobalVars . video ) {
if ( Debug . debug || Debug . warnings _critical )
console . log ( "[ArDetect::_ard_vdraw] Video went missing. Stopping current instance of automatic detection and trying to start a new one." )
_ard _stop ( ) ;
this . _forcehalt = true ;
_arSetup ( ) ;
return ;
}
2017-12-29 23:34:40 +01:00
2017-12-31 18:26:59 +01:00
var fallbackMode = false ;
2018-02-15 00:17:58 +01:00
var startTime = performance . now ( ) ;
2018-03-13 23:55:38 +01:00
var baseTimeout = ExtensionConf . arDetect . timer _playing ;
2018-02-15 22:59:31 +01:00
var triggerTimeout ;
2018-02-15 00:17:58 +01:00
var guardLineResult = true ; // true if success, false if fail. true by default
2018-02-15 22:59:31 +01:00
var imageDetectResult = false ; // true if we detect image along the way. false by default
2018-02-15 00:17:58 +01:00
2018-03-04 23:07:11 +01:00
var sampleCols = [ ] ;
for ( var i in _ard _sampleCols ) {
sampleCols [ i ] = _ard _sampleCols [ i ] ;
}
2017-12-29 23:34:40 +01:00
2018-02-15 22:59:31 +01:00
var how _far _treshold = 8 ; // how much can the edge pixel vary (*4)
2017-09-24 01:54:46 +02:00
2018-03-08 22:22:42 +01:00
if ( GlobalVars . video == null || GlobalVars . video . ended || Status . arStrat != "auto" ) {
// we slow down if ended, null, or not auto. Detecting is pointless.
2018-03-14 21:19:15 +01:00
2018-03-13 23:55:38 +01:00
_ard _vdraw ( ExtensionConf . arDetect . timer _paused ) ;
2017-09-24 01:54:46 +02:00
return false ;
}
2018-03-08 22:22:42 +01:00
if ( GlobalVars . video . paused ) {
// if the video is paused, we still do autodetection. We just increase the interval.
2018-03-13 23:55:38 +01:00
baseTimeout = ExtensionConf . arDetect . timer _paused ;
2018-03-08 22:22:42 +01:00
}
2018-03-14 21:19:15 +01:00
2017-12-31 18:26:59 +01:00
try {
2018-02-28 23:54:32 +01:00
GlobalVars . canvas . context . drawImage ( GlobalVars . video , 0 , 0 , GlobalVars . canvas . width , GlobalVars . canvas . height ) ;
2017-12-31 18:26:59 +01:00
}
catch ( ex ) {
if ( Debug . debug )
console . log ( "%c[ArDetect::_ard_vdraw] can't draw image on canvas. Trying canvas.drawWindow instead" , "color:#000; backgroud:#f51;" , ex ) ;
try {
2018-03-18 15:14:57 +01:00
if ( ! ExtensionConf . arDetect . fallbackMode . enabled )
throw "fallbackMode is disabled." ;
2017-12-31 18:26:59 +01:00
if ( _ard _canvasReadyForDrawWindow ( ) ) {
2018-03-18 15:14:57 +01:00
GlobalVars . canvas . context . drawWindow ( window , _ard _canvasDrawWindowHOffset , 0 , GlobalVars . canvas . width , GlobalVars . canvas . height , "rgba(0,0,0,1)" ) ;
2017-12-31 18:26:59 +01:00
if ( Debug . debug )
console . log ( "%c[ArDetect::_ard_vdraw] canvas.drawImage seems to have worked" , "color:#000; backgroud:#2f5;" ) ;
fallbackMode = true ;
}
else {
// canvas needs to be resized, so let's change setup
_ard _stop ( ) ;
2018-03-18 15:14:57 +01:00
var newCanvasWidth = window . innerHeight * ( GlobalVars . video . videoWidth / GlobalVars . video . videoHeight ) ;
2017-12-31 18:26:59 +01:00
var newCanvasHeight = window . innerHeight ;
2018-03-13 23:55:38 +01:00
if ( ExtensionConf . miscFullscreenSettings . videoFloat == "center" )
2017-12-31 18:26:59 +01:00
_ard _canvasDrawWindowHOffset = Math . round ( ( window . innerWidth - newCanvasWidth ) * 0.5 ) ;
2018-03-13 23:55:38 +01:00
else if ( ExtensionConf . miscFullscreenSettings . videFloat == "left" )
2017-12-31 18:26:59 +01:00
_ard _canvasDrawWindowHOffset = 0 ;
else
_ard _canvasDrawWindowHOffset = window . innerWidth - newCanvasWidth ;
_arSetup ( newCanvasWidth , newCanvasHeight ) ;
2018-03-18 15:14:57 +01:00
2017-12-31 18:26:59 +01:00
return ;
}
}
catch ( ex ) {
if ( Debug . debug )
console . log ( "%c[ArDetect::_ard_vdraw] okay this didnt work either" , "color:#000; backgroud:#f51;" , ex ) ;
2018-03-13 23:55:38 +01:00
_ard _vdraw ( ExtensionConf . arDetect . timer _error ) ;
2017-12-31 18:26:59 +01:00
return ;
}
}
2017-09-24 01:54:46 +02:00
2018-03-18 15:14:57 +01:00
if ( GlobalVars . arDetect . blackLevel == undefined ) {
if ( Debug . debugArDetect )
console . log ( "[ArDetect::_ard_vdraw] black level undefined, resetting" ) ;
_ard _resetBlackLevel ( ) ;
}
2018-02-28 23:54:32 +01:00
// we get the entire frame so there's less references for garbage collection to catch
2018-03-04 23:07:46 +01:00
var image = GlobalVars . canvas . context . getImageData ( 0 , 0 , GlobalVars . canvas . width , GlobalVars . canvas . height ) . data ;
2018-03-03 23:58:29 +01:00
2018-05-01 23:09:58 +02:00
if ( Debug . debugCanvas . enabled ) {
DebugCanvas . showTraces ( ) ;
DebugCanvas . setBuffer ( image ) ;
}
2018-02-15 22:59:31 +01:00
// fast test to see if aspect ratio is correct. If we detect anything darker than blackLevel, we modify
// blackLevel to the new lowest value
var isLetter = true ;
2018-02-28 23:54:32 +01:00
var currentMaxVal = 0 ;
var currentMax _a ;
var currentMinVal = 48 ; // not 255 cos safety, even this is prolly too high
var currentMin _a ;
2018-02-15 22:59:31 +01:00
2018-02-28 23:54:32 +01:00
var rowOffset = 0 ;
var colOffset _r , colOffset _g , colOffset _b ;
2018-02-15 22:59:31 +01:00
2018-02-28 23:54:32 +01:00
// detect black level. if currentMax and currentMin vary too much, we automatically know that
// black level is bogus and that we aren't letterboxed. We still save the darkest value as black level,
// though — as black bars will never be brighter than that.
for ( var i = 0 ; i < sampleCols . length ; ++ i ) {
2018-03-18 15:14:57 +01:00
colOffset _r = sampleCols [ i ] << 2 ;
2018-03-03 23:58:29 +01:00
colOffset _g = colOffset _r + 1 ;
colOffset _b = colOffset _r + 2 ;
2018-02-28 23:54:32 +01:00
currentMax _a = image [ colOffset _r ] > image [ colOffset _g ] ? image [ colOffset _r ] : image [ colOffset _g ] ;
currentMax _a = currentMax _a > image [ colOffset _b ] ? currentMax _a : image [ colOffset _b ] ;
2018-02-15 22:59:31 +01:00
currentMaxVal = currentMaxVal > currentMax _a ? currentMaxVal : currentMax _a ;
2018-02-28 23:54:32 +01:00
currentMin _a = image [ colOffset _r ] < image [ colOffset _g ] ? image [ colOffset _r ] : image [ colOffset _g ] ;
currentMin _a = currentMin _a < image [ colOffset _b ] ? currentMin _a : image [ colOffset _b ] ;
2018-02-15 22:59:31 +01:00
2018-03-03 23:58:29 +01:00
currentMinVal = currentMinVal < currentMin _a ? currentMinVal : currentMin _a ;
2017-09-24 01:54:46 +02:00
}
2018-02-28 23:54:32 +01:00
// we'll shift the sum. math says we can do this
2018-03-03 23:58:29 +01:00
rowOffset = GlobalVars . canvas . width * ( GlobalVars . canvas . height - 1 ) ;
2018-02-28 23:54:32 +01:00
for ( var i = 0 ; i < sampleCols . length ; ++ i ) {
2018-03-18 15:14:57 +01:00
colOffset _r = ( rowOffset + sampleCols [ i ] ) << 2 ;
2018-03-03 23:58:29 +01:00
colOffset _g = colOffset _r + 1 ;
colOffset _b = colOffset _r + 2 ;
2018-02-28 23:54:32 +01:00
currentMax _a = image [ colOffset _r ] > image [ colOffset _g ] ? image [ colOffset _r ] : image [ colOffset _g ] ;
currentMax _a = currentMax _a > image [ colOffset _b ] ? currentMax _a : image [ colOffset _b ] ;
currentMaxVal = currentMaxVal > currentMax _a ? currentMaxVal : currentMax _a ;
currentMin _a = image [ colOffset _r ] < image [ colOffset _g ] ? image [ colOffset _r ] : image [ colOffset _g ] ;
currentMin _a = currentMin _a < image [ colOffset _b ] ? currentMin _a : image [ colOffset _b ] ;
2018-03-18 15:14:57 +01:00
if ( currentMinVal == undefined && currenMinVal != undefined )
currentMinVal = currentMin _a ;
else if ( currentMin _a != undefined )
currentMinVal = currentMinVal < currentMin _a ? currentMinVal : currentMin _a ;
2018-02-28 23:54:32 +01:00
}
2018-03-18 15:14:57 +01:00
// save black level only if defined
if ( currentMinVal != undefined )
GlobalVars . arDetect . blackLevel = GlobalVars . arDetect . blackLevel < currentMinVal ? GlobalVars . arDetect . blackLevel : currentMinVal ;
2018-02-28 23:54:32 +01:00
// this means we don't have letterbox
2018-03-13 23:55:38 +01:00
if ( currentMaxVal > ( GlobalVars . arDetect . blackLevel + ExtensionConf . arDetect . blackbarTreshold ) || ( currentMaxVal - currentMinVal ) > ExtensionConf . arDetect . blackbarTreshold ) {
2018-02-28 23:54:32 +01:00
2018-01-27 22:25:25 +01:00
// Če ne zaznamo letterboxa, kličemo reset. Lahko, da je bilo razmerje stranic popravljeno na roke. Možno je tudi,
// da je letterbox izginil.
// If we don't detect letterbox, we reset aspect ratio to aspect ratio of the video file. The aspect ratio could
// have been corrected manually. It's also possible that letterbox (that was there before) disappeared.
2017-12-31 18:26:59 +01:00
if ( Debug . debug ) {
console . log ( "%c[ArDetect::_ard_vdraw] no edge detected. canvas has no edge." , "color: #aaf" ) ;
}
2018-03-14 21:19:15 +01:00
2018-03-04 23:07:11 +01:00
image = null ;
2018-03-08 22:22:42 +01:00
// Pogledamo, ali smo že kdaj ponastavili CSS. Če še nismo, potem to storimo. Če smo že, potem ne.
// Ponastavimo tudi guardline (na null).
// let's chec if we ever reset CSS. If we haven't, then we do so. If we did, then we don't.
// while resetting the CSS, we also reset guardline top and bottom back to null.
if ( ! GlobalVars . arDetect . noLetterboxCanvasReset ) {
Resizer . reset ( ) ;
GlobalVars . lastAr = { type : "auto" , ar : null } ;
GlobalVars . arDetect . guardLine . top = null ;
GlobalVars . arDetect . guardLine . bottom = null ;
GlobalVars . arDetect . noLetterboxCanvasReset = true ;
}
2018-02-15 22:59:31 +01:00
triggerTimeout = _ard _getTimeout ( baseTimeout , startTime ) ;
2018-02-28 23:54:32 +01:00
_ard _vdraw ( triggerTimeout ) ; //no letterbox, no problem
2017-09-24 01:54:46 +02:00
return ;
}
2017-09-27 02:26:47 +02:00
2018-03-08 22:22:42 +01:00
// Če preverjamo naprej, potem moramo postaviti to vrednost nazaj na 'false'. V nasprotnem primeru se bo
// css resetiral enkrat na video/pageload namesto vsakič, ko so za nekaj časa obrobe odstranejene
// if we look further we need to reset this value back to false. Otherwise we'll only get CSS reset once
// per video/pageload instead of every time letterbox goes away (this can happen more than once per vid)
GlobalVars . arDetect . noLetterboxCanvasReset = false ;
2018-03-05 23:55:14 +01:00
2018-02-15 00:17:58 +01:00
// let's do a quick test to see if we're on a black frame
// TODO: reimplement but with less bullshit
2018-03-04 23:07:11 +01:00
2018-02-15 00:17:58 +01:00
// poglejmo, če obrežemo preveč.
2018-02-15 22:59:31 +01:00
// let's check if we're cropping too much (or whatever)
2018-02-15 00:17:58 +01:00
var guardLineOut ;
2018-02-15 22:59:31 +01:00
var imageDetectOut ;
2018-05-01 23:09:58 +02:00
if ( ExtensionConf . arDetect . guardLine . enabled ) {
2018-03-18 15:14:57 +01:00
guardLineOut = _ard _guardLineCheck ( image , fallbackMode ) ;
2017-09-27 02:26:47 +02:00
2018-03-18 15:14:57 +01:00
guardLineResult = guardLineOut . success ;
2018-02-15 22:59:31 +01:00
if ( ! guardLineResult ) { // add new ssamples to our sample columns
for ( var col of guardLineOut . offenders ) {
sampleCols . push ( col )
2017-09-24 01:54:46 +02:00
}
}
2018-05-01 23:09:58 +02:00
console . log ( "GUARDLINE RESULT:" , guardLineResult , guardLineOut )
2018-03-18 17:35:51 +01:00
imageDetectOut = _ard _guardLineImageDetect ( image , fallbackMode ) ;
2018-02-15 22:59:31 +01:00
imageDetectResult = imageDetectOut . success ;
2017-09-27 02:26:47 +02:00
2018-02-15 22:59:31 +01:00
// če sta obe funkciji uspeli, potem se razmerje stranic ni spremenilo.
// if both succeed, then aspect ratio hasn't changed.
2018-03-18 15:14:57 +01:00
// if we're in fallback mode, we restore CSS
if ( fallbackMode && ! guardLineResult ) {
delete image ;
Resizer . reset ( ) ;
GlobalVars . lastAr = { type : "auto" , ar : null } ;
GlobalVars . arDetect . guardLine . top = null ;
GlobalVars . arDetect . guardLine . bottom = null ;
GlobalVars . arDetect . noLetterboxCanvasReset = true ;
2018-03-14 21:19:15 +01:00
2018-03-18 15:14:57 +01:00
triggerTimeout = _ard _getTimeout ( baseTimeout , startTime ) ;
_ard _vdraw ( triggerTimeout ) ; //no letterbox, no problem
return ;
}
if ( imageDetectResult && guardLineResult ) {
2018-03-03 23:58:29 +01:00
delete image ;
2018-02-15 22:59:31 +01:00
triggerTimeout = _ard _getTimeout ( baseTimeout , startTime ) ;
2018-02-28 23:54:32 +01:00
_ard _vdraw ( triggerTimeout ) ; //no letterbox, no problem
2018-02-15 22:59:31 +01:00
return ;
2017-09-27 02:26:47 +02:00
}
2018-03-18 15:14:57 +01:00
2017-09-27 02:26:47 +02:00
}
2018-04-11 00:19:44 +02:00
// će se razmerje stranic spreminja iz ožjega na širšega, potem najprej poglejmo za prisotnostjo navpičnih črnih obrob.
// če so prisotne navpične obrobe tudi na levi in desni strani, potlej obstaja možnost, da gre za logo na črnem ozadju.
// v tem primeru obstaja nevarnost, da porežemo preveč. Ker obstaja dovolj velika možnost, da bi porezali preveč, rajši
// ne naredimo ničesar.
//
2018-05-01 23:09:58 +02:00
// če je pillarbox zaznan v primeru spremembe iz ožjega na širše razmerje stranice, razmerje povrnemo na privzeto vrednost.
//
2018-04-11 00:19:44 +02:00
// If aspect ratio changes from narrower to wider, we first check for presence of pillarbox. Presence of pillarbox indicates
// a chance of a logo on black background. We could cut easily cut too much. Because there's a somewhat significant chance
// that we will cut too much, we rather avoid doing anything at all. There's gonna be a next chance.
2018-05-01 23:09:58 +02:00
if ( ! imageDetectResult || ! guardLineResult ) {
2018-04-11 00:19:44 +02:00
if ( pillarTest ( image ) ) {
2018-05-01 23:09:58 +02:00
if ( Debug . debug && ! guardLineResult ) {
console . log ( "[ArDetect::_ard_vdraw] Detected blackbar violation and pillarbox. Resetting to default aspect ratio." ) ;
}
if ( ! guardLineResult ) {
Resizer . reset ( ) ;
}
2018-04-11 00:19:44 +02:00
delete image ;
triggerTimeout = _ard _getTimeout ( baseTimeout , startTime ) ;
_ard _vdraw ( triggerTimeout ) ;
return ;
}
}
2018-02-15 22:59:31 +01:00
// pa poglejmo, kje se končajo črne letvice na vrhu in na dnu videa.
// let's see where black bars end.
GlobalVars . sampleCols _current = sampleCols . length ;
2018-03-03 23:58:29 +01:00
// blackSamples -> {res_top, res_bottom}
2018-03-04 23:07:11 +01:00
var blackbarSamples = _ard _findBlackbarLimits ( image , sampleCols , guardLineResult , imageDetectResult ) ;
2018-03-03 23:58:29 +01:00
var edgeCandidates = _ard _edgeDetect ( image , blackbarSamples ) ;
2018-02-28 23:54:32 +01:00
var edgePost = _ard _edgePostprocess ( edgeCandidates , GlobalVars . canvas . height ) ;
2018-02-15 22:59:31 +01:00
2018-05-01 23:09:58 +02:00
// console.log("SAMPLES:", blackbarSamples, "candidates:", edgeCandidates, "post:", edgePost,"\n\nblack level:",GlobalVars.arDetect.blackLevel, "tresh:", GlobalVars.arDetect.blackLevel + ExtensionConf.arDetect.blackbarTreshold);
2018-03-04 23:07:11 +01:00
2018-02-15 22:59:31 +01:00
if ( edgePost . status == "ar_known" ) {
2018-04-11 00:19:44 +02:00
// zaznali smo rob — vendar pa moramo pred obdelavo še preveriti, ali ni "rob" slučajno besedilo. Če smo kot rob pofočkali
// besedilo, potem to ni veljaven rob. Razmerja stranic se zato ne bomo pipali.
// we detected an edge — but before we process it, we need to check if the "edge" isn't actually some text. If the detected
// edge is actually some text on black background, we shouldn't touch the aspect ratio. Whatever we detected is invalid.
var textEdge = false ; ;
if ( edgePost . guardLineTop != null ) {
var row = edgePost . guardLineTop + ~ ~ ( GlobalVars . canvas . height * ExtensionConf . arDetect . textLineTest . testRowOffset ) ;
textEdge |= textLineTest ( image , row ) ;
}
if ( edgePost . guardLineTop != null ) {
var row = edgePost . guardLineTop - ~ ~ ( GlobalVars . canvas . height * ExtensionConf . arDetect . textLineTest . testRowOffset ) ;
textEdge |= textLineTest ( image , row ) ;
}
if ( ! textEdge ) {
_ard _processAr ( GlobalVars . video , GlobalVars . canvas . width , GlobalVars . canvas . height , edgePost . blackbarWidth , null , fallbackMode ) ;
2018-02-22 21:06:57 +01:00
2018-04-11 00:19:44 +02:00
// we also know edges for guardline, so set them
GlobalVars . arDetect . guardLine . top = edgePost . guardLineTop ;
GlobalVars . arDetect . guardLine . bottom = edgePost . guardLineBottom ;
}
else {
console . log ( "detected text on edges, dooing nothing" )
}
2018-03-03 23:58:29 +01:00
delete image ;
2018-02-15 22:59:31 +01:00
triggerTimeout = _ard _getTimeout ( baseTimeout , startTime ) ;
2018-02-28 23:54:32 +01:00
_ard _vdraw ( triggerTimeout ) ; //no letterbox, no problem
2018-02-15 22:59:31 +01:00
return ;
2017-09-24 01:54:46 +02:00
}
2018-02-15 22:59:31 +01:00
else {
2018-03-03 23:58:29 +01:00
delete image ;
2018-02-15 22:59:31 +01:00
triggerTimeout = _ard _getTimeout ( baseTimeout , startTime ) ;
2018-02-28 23:54:32 +01:00
_ard _vdraw ( triggerTimeout ) ; //no letterbox, no problem
2018-02-15 22:59:31 +01:00
return ;
2017-09-27 02:26:47 +02:00
}
2018-03-03 23:58:29 +01:00
delete image ;
2017-09-24 01:54:46 +02:00
}
2018-04-11 00:19:44 +02:00
var pillarTest = function ( image ) {
// preverimo, če na sliki obstajajo navpične črne obrobe. Vrne 'true' če so zaznane (in če so približno enako debele), 'false' sicer.
// true vrne tudi, če zaznamo preveč črnine.
// <==XX(::::}----{::::)XX==>
// checks the image for presence of vertical pillars. Less accurate than 'find blackbar limits'. If we find a non-black object that's
// roughly centered, we return true. Otherwise we return false.
// we also return true if we detect too much black
2018-03-04 23:07:11 +01:00
2018-04-11 00:19:44 +02:00
var blackbarTreshold , upper , lower ;
2018-04-10 21:35:34 +02:00
blackbarTreshold = GlobalVars . arDetect . blackLevel + ExtensionConf . arDetect . blackbarTreshold ;
2018-04-11 00:19:44 +02:00
var middleRowStart = ( GlobalVars . canvas . height >> 1 ) * GlobalVars . canvas . width ;
var middleRowEnd = middleRowStart + GlobalVars . canvas . width - 1 ;
2018-04-10 21:35:34 +02:00
2018-04-11 00:19:44 +02:00
var rowStart = middleRowStart << 2 ;
var midpoint = ( middleRowStart + ( GlobalVars . canvas . width >> 1 ) ) << 2
var rowEnd = middleRowEnd << 2 ;
2018-04-10 21:35:34 +02:00
2018-04-11 00:19:44 +02:00
var edge _left = - 1 ; edge _right = - 1 ;
2018-04-10 21:35:34 +02:00
2018-04-11 00:19:44 +02:00
// preverimo na levi strani
// let's check for edge on the left side
for ( var i = rowStart ; i < midpoint ; i += 4 ) {
if ( image [ i ] > blackbarTreshold || image [ i + 1 ] > blackbarTreshold || image [ i + 2 ] > blackbarTreshold ) {
edge _left = ( i - rowStart ) >> 2 ;
break ;
}
}
2018-04-10 21:35:34 +02:00
2018-04-11 00:19:44 +02:00
// preverimo na desni strani
// check on the right
for ( var i = rowEnd ; i > midpoint ; i -= 4 ) {
if ( image [ i ] > blackbarTreshold || image [ i + 1 ] > blackbarTreshold || image [ i + 2 ] > blackbarTreshold ) {
edge _right = GlobalVars . canvas . width - ( ( i - rowStart ) >> 2 ) ;
break ;
}
}
2018-04-10 21:35:34 +02:00
2018-04-11 00:19:44 +02:00
// če je katerikoli -1, potem imamo preveč črnine
// we probably have too much black if either of those two is -1
if ( edge _left == - 1 || edge _right == - 1 ) {
return true ;
}
2018-04-10 21:35:34 +02:00
2018-04-11 00:19:44 +02:00
// če sta oba robova v mejah merske napake, potem vrnemo 'false'
// if both edges resemble rounding error, we retunr 'false'
if ( edge _left < ExtensionConf . arDetect . pillarTest . ignoreThinPillarsPx && edge _right < ExtensionConf . arDetect . pillarTest . ignoreThinPillarsPx ) {
return false ;
}
var edgeError = ExtensionConf . arDetect . pillarTest . allowMisaligned ;
var error _low = 1 - edgeError ;
var error _hi = 1 + edgeError ;
2018-04-10 21:35:34 +02:00
2018-04-11 00:19:44 +02:00
// če sta 'edge_left' in 'edge_right' podobna/v mejah merske napake, potem vrnemo true — lahko da smo našli logo na sredini zaslona
// if 'edge_left' and 'edge_right' are similar enough to each other, we return true. If we found a logo in a black frame, we could
// crop too eagerly
if ( ( edge _left * error _low ) < edge _right &&
( edge _left * error _hi ) > edge _right ) {
return true ;
2018-04-10 21:35:34 +02:00
}
2018-04-11 00:19:44 +02:00
// če se ne zgodi nič od neštetega, potem nismo našli problemov
// if none of the above, we haven't found a problem
return false ;
}
2018-04-10 21:35:34 +02:00
2018-04-11 00:19:44 +02:00
var textLineTest = function ( image , row ) {
// preverimo, če vrstica vsebuje besedilo na črnem ozadju. Če ob pregledu vrstice naletimo na veliko sprememb
// iz črnega v ne-črno, potem obstaja možnost, da gledamo besedilo. Prisotnost take vrstice je lahko znak, da
// zaznano razmerje stranic ni veljavno
//
// vrne 'true' če zazna text, 'false' drugače.
//
//
// check if line contains any text. If line scan reveals a lot of changes from black to non-black there's a
// chance we're looking at text on a black background. If we detect text near what we think is an edge of the
// video, there's a good chance we're about to incorrectly adjust the aspect ratio.
//
// returns 'true' if text is detected, 'false' otherwise
var blackbarTreshold = GlobalVars . arDetect . blackLevel + ExtensionConf . arDetect . blackbarTreshold ;
var nontextTreshold = GlobalVars . canvas . width * ExtensionConf . arDetect . textLineTest . nonTextPulse ;
var rowStart = ( row * GlobalVars . canvas . width ) << 2 ;
var rowEnd = rowStart + ( GlobalVars . canvas . width << 2 ) ;
var pulse = false ;
var currentPulseLength = 0 , pulseCount = 0 ;
var pulses = [ ] ;
var longestBlack = 0 ;
// preglejmo vrstico
// analyse the row
for ( var i = rowStart ; i < rowEnd ; i += 4 ) {
if ( pulse ) {
if ( image [ i ] < blackbarTreshold || image [ i + 1 ] < blackbarTreshold || image [ i + 2 ] < blackbarTreshold ) {
// pulses.push(currentPulseLength);
pulseCount ++ ;
pulse = false ;
currentPulseLength = 0 ;
2018-04-10 21:35:34 +02:00
}
else {
2018-04-11 00:19:44 +02:00
currentPulseLength ++ ;
// če najdemo dovolj dolgo zaporedje ne-črnih točk, potem vrnemo 'false' — dobili smo legitimen rob
// if we find long enough uninterrupted line of non-black point, we fail the test. We found a legit edge.
if ( currentPulseLength > nontextTreshold ) {
return false ;
}
2018-04-10 21:35:34 +02:00
}
}
else {
2018-04-11 00:19:44 +02:00
if ( image [ i ] > blackbarTreshold || image [ i + 1 ] > blackbarTreshold || image [ i + 2 ] > blackbarTreshold ) {
if ( currentPulseLength > longestBlack ) {
longestBlack = currentPulseLength ;
}
pulse = true ;
currentPulseLength = 0 ;
}
else {
currentPulseLength ++ ;
}
2018-04-10 21:35:34 +02:00
}
}
2018-04-11 00:19:44 +02:00
if ( pulse ) {
pulseCount ++ ;
// pulses.push(currentPulseLength);
}
2018-03-04 23:07:11 +01:00
2018-04-11 00:19:44 +02:00
// pregledamo rezultate:
// analyse the results
console . log ( "pulse test:\n\npulses:" , pulseCount , "longest black:" , longestBlack ) ;
// če smo zaznali dovolj pulzov, potem vrnemo res
// if we detected enough pulses, we return true
if ( pulseCount > ExtensionConf . arDetect . textLineTest . pulsesToConfirm ) {
return true ;
}
// če je najdaljša neprekinjena črta črnih pikslov širša od polovice širine je merilo za zaznavanje
// besedila rahlo milejše
// if the longest uninterrupted line of black pixels is wider than half the width, we use a more
// forgiving standard for determining if we found text
if ( longestBlack > ( GlobalVars . canvas . width >> 1 ) &&
pulseCount > ExtensionConf . arDetect . textLineTest . pulsesToConfirmIfHalfBlack ) {
return true ;
}
// če pridemo do sem, potem besedilo ni bilo zaznano
// if we're here, no text was detected
return false ;
}
2018-03-04 23:07:11 +01:00
2018-03-18 15:14:57 +01:00
var _ard _guardLineCheck = function ( image , fallbackMode ) {
2018-02-15 00:17:58 +01:00
// this test tests for whether we crop too aggressively
// if this test is passed, then aspect ratio probably didn't change from wider to narrower. However, further
// checks are needed to determine whether aspect ratio got wider.
// if this test fails, it returns a list of offending points.
// if the upper edge is null, then edge hasn't been detected before. This test is pointless, therefore it
2018-02-22 21:06:57 +01:00
// should succeed by default. Also need to check bottom, for cases where only one edge is known
2018-02-15 00:17:58 +01:00
2018-03-18 15:14:57 +01:00
if ( ! fallbackMode ) {
if ( GlobalVars . arDetect . guardLine . top == null || GlobalVars . arDetect . guardLine . bottom == null )
return { success : true } ;
var edges = GlobalVars . arDetect . guardLine ;
}
2018-03-13 23:55:38 +01:00
var blackbarTreshold = GlobalVars . arDetect . blackLevel + ExtensionConf . arDetect . blackbarTreshold ;
2018-03-04 23:07:11 +01:00
2018-03-18 15:14:57 +01:00
var offset = parseInt ( GlobalVars . canvas . width * ExtensionConf . arDetect . guardLine . ignoreEdgeMargin ) << 2 ;
2018-02-28 23:54:32 +01:00
var offenders = [ ] ;
var firstOffender = - 1 ;
var offenderCount = - 1 ; // doing it this way means first offender has offenderCount==0. Ez index.
2018-03-04 23:07:11 +01:00
2018-02-15 00:17:58 +01:00
// TODO: implement logo check.
// preglejmo obe vrstici
// check both rows
2018-03-04 23:07:11 +01:00
2018-03-18 15:14:57 +01:00
if ( ! fallbackMode ) {
var edge _upper = edges . top - ExtensionConf . arDetect . guardLine . edgeTolerancePx ;
if ( edge _upper < 0 )
return { success : true } ; // if we go out of bounds here, the black bars are negligible
var edge _lower = edges . bottom + ExtensionConf . arDetect . guardLine . edgeTolerancePx ;
if ( edge _lower > GlobalVars . canvas . height - 1 )
return { success : true } ; // if we go out of bounds here, the black bars are negligible
}
else {
// fallback mode is a bit different
edge _upper = 0 ;
edge _lower = GlobalVars . canvas . height - 1 ;
}
var rowStart , rowEnd ;
2018-02-28 23:54:32 +01:00
2018-02-22 21:06:57 +01:00
2018-03-03 23:58:29 +01:00
// <<<=======| checking upper row |========>>>
2018-03-18 15:14:57 +01:00
rowStart = ( ( edge _upper * GlobalVars . canvas . width ) << 2 ) + offset ;
rowEnd = rowStart + ( GlobalVars . canvas . width << 2 ) - ( offset * 2 ) ;
2018-03-03 23:58:29 +01:00
2018-05-01 23:09:58 +02:00
if ( Debug . debugCanvas . enabled && Debug . debugCanvas . guardLine ) {
offenderCount = _ard _gl _debugRowCheck ( image , rowStart , rowEnd , offenders , offenderCount , blackbarTreshold ) ;
} else {
offenderCount = _ard _gl _rowCheck ( image , rowStart , rowEnd , offenders , offenderCount , blackbarTreshold ) ;
}
// <<<=======| checking lower row |========>>>
rowStart = ( ( edge _lower * GlobalVars . canvas . width ) << 2 ) + offset ;
rowEnd = rowStart + ( GlobalVars . canvas . width << 2 ) - ( offset * 2 ) ;
if ( Debug . debugCanvas . enabled && Debug . debugCanvas . guardLine ) {
offenderCount = _ard _gl _debugRowCheck ( image , rowStart , rowEnd , offenders , offenderCount , blackbarTreshold ) ;
} else {
offenderCount = _ard _gl _rowCheck ( image , rowStart , rowEnd , offenders , offenderCount , blackbarTreshold ) ;
}
// če nismo našli nobenih prekrškarjev, vrnemo uspeh. Drugače vrnemo seznam prekrškarjev
// vrnemo tabelo, ki vsebuje sredinsko točko vsakega prekrškarja (x + width*0.5)
//
// if we haven't found any offenders, we return success. Else we return list of offenders
// we return array of middle points of offenders (x + (width * 0.5) for every offender)
if ( offenderCount == - 1 ) {
return { success : true } ;
}
var ret = new Array ( offenders . length ) ;
for ( var o in offenders ) {
ret [ o ] = offenders [ o ] . x + ( offenders [ o ] . width * 0.25 ) ;
}
return { success : false , offenders : ret } ;
}
var _ard _gl _rowCheck = function ( image , rowStart , rowEnd , offenders , offenderCount , blackbarTreshold ) {
var firstOffender = - 1 ;
2018-03-03 23:58:29 +01:00
for ( var i = rowStart ; i < rowEnd ; i += 4 ) {
2018-03-04 23:07:11 +01:00
2018-03-03 23:58:29 +01:00
// we track sections that go over what's supposed to be a black line, so we can suggest more
// columns to sample
if ( image [ i ] > blackbarTreshold || image [ i + 1 ] > blackbarTreshold || image [ i + 2 ] > blackbarTreshold ) {
if ( firstOffender < 0 ) {
2018-05-01 23:09:58 +02:00
firstOffender = ( i - rowStart ) >> 2 ;
2018-03-03 23:58:29 +01:00
offenderCount ++ ;
2018-05-01 23:09:58 +02:00
offenders . push ( { x : firstOffender , width : 1 } ) ;
2018-02-15 00:17:58 +01:00
}
else {
2018-03-03 23:58:29 +01:00
offenders [ offenderCount ] . width ++
2018-02-15 00:17:58 +01:00
}
2018-03-03 23:58:29 +01:00
}
else {
// is that a black pixel again? Let's reset the 'first offender'
firstOffender = - 1 ;
}
}
2018-05-01 23:09:58 +02:00
return offenderCount ;
}
var _ard _gl _debugRowCheck = function ( image , rowStart , rowEnd , offenders , offenderCount , blackbarTreshold ) {
var firstOffender = - 1 ;
for ( var i = rowStart ; i < rowEnd ; i += 4 ) {
2018-03-03 23:58:29 +01:00
// we track sections that go over what's supposed to be a black line, so we can suggest more
// columns to sample
if ( image [ i ] > blackbarTreshold || image [ i + 1 ] > blackbarTreshold || image [ i + 2 ] > blackbarTreshold ) {
2018-05-01 23:09:58 +02:00
DebugCanvas . trace ( 'guardLine_blackbar_violation' , i ) ;
2018-03-03 23:58:29 +01:00
if ( firstOffender < 0 ) {
2018-05-01 23:09:58 +02:00
firstOffender = ( i - rowStart ) >> 2 ;
2018-03-03 23:58:29 +01:00
offenderCount ++ ;
2018-05-01 23:09:58 +02:00
offenders . push ( { x : firstOffender , width : 1 } ) ;
2018-03-03 23:58:29 +01:00
}
else {
offenders [ offenderCount ] . width ++
}
2018-02-15 00:17:58 +01:00
}
2018-03-03 23:58:29 +01:00
else {
2018-05-01 23:09:58 +02:00
DebugCanvas . trace ( 'guardLine_blackbar' , i ) ;
2018-03-03 23:58:29 +01:00
// is that a black pixel again? Let's reset the 'first offender'
firstOffender = - 1 ;
}
2018-02-15 00:17:58 +01:00
}
2018-05-01 23:09:58 +02:00
return offenderCount ;
2018-02-15 22:59:31 +01:00
}
2018-05-01 23:09:58 +02:00
2018-03-04 23:07:11 +01:00
var _ard _edgeDetect = function ( image , samples ) {
2018-02-15 22:59:31 +01:00
var edgeCandidatesTop = { } ;
var edgeCandidatesBottom = { } ;
2018-02-15 00:17:58 +01:00
2018-03-18 15:14:57 +01:00
var sampleWidthBase = ExtensionConf . arDetect . edgeDetection . sampleWidth << 2 ; // corrected so we can work on imagedata
2018-03-04 23:07:11 +01:00
var halfSample = sampleWidthBase * 0.5 ;
2018-02-15 22:59:31 +01:00
var detections ;
2018-03-13 23:55:38 +01:00
var detectionTreshold = ExtensionConf . arDetect . edgeDetection . detectionTreshold ;
2018-03-03 23:58:29 +01:00
var canvasWidth = GlobalVars . canvas . width ;
var canvasHeight = GlobalVars . canvas . height ;
2018-02-15 00:17:58 +01:00
2018-03-03 23:58:29 +01:00
var sampleStart , sampleEnd , loopEnd ;
var sampleRow _black , sampleRow _color ;
2018-02-15 22:59:31 +01:00
var blackEdgeViolation = false ;
2018-03-13 23:55:38 +01:00
var blackbarTreshold = GlobalVars . arDetect . blackLevel + ExtensionConf . arDetect . blackbarTreshold ;
2018-02-15 22:59:31 +01:00
var topEdgeCount = 0 ;
var bottomEdgeCount = 0 ;
2018-02-15 00:17:58 +01:00
2018-02-16 00:19:08 +01:00
2018-03-03 23:58:29 +01:00
for ( sample of samples . res _top ) {
blackEdgeViolation = false ; // reset this
2018-02-15 22:59:31 +01:00
2018-03-03 23:58:29 +01:00
// determine our bounds. Note that sample.col is _not_ corrected for imageData, but halfSample is
2018-03-18 15:14:57 +01:00
sampleStart = ( sample . col << 2 ) - halfSample ;
2018-02-15 22:59:31 +01:00
if ( sampleStart < 0 )
sampleStart = 0 ;
2018-02-15 00:17:58 +01:00
2018-03-03 23:58:29 +01:00
sampleEnd = sampleStart + sampleWidthBase ;
if ( sampleEnd > GlobalVars . canvas . imageDataRowLength )
sampleEnd = GlobalVars . canvas . imageDataRowLength ;
// calculate row offsets for imageData array
2018-03-13 23:55:38 +01:00
sampleRow _black = ( sample . top - ExtensionConf . arDetect . edgeDetection . edgeTolerancePx ) * GlobalVars . canvas . imageDataRowLength ;
sampleRow _color = ( sample . top + 1 + ExtensionConf . arDetect . edgeDetection . edgeTolerancePx ) * GlobalVars . canvas . imageDataRowLength ;
2018-03-03 23:58:29 +01:00
// že ena kršitev črnega roba pomeni, da kandidat ni primeren
// even a single black edge violation means the candidate is not an edge
loopEnd = sampleRow _black + sampleEnd ;
for ( var i = sampleRow _black + sampleStart ; i < loopEnd ; i += 4 ) {
if ( image [ i ] > blackbarTreshold ||
image [ i + 1 ] > blackbarTreshold ||
image [ i + 2 ] > blackbarTreshold ) {
blackEdgeViolation = true ;
2018-03-04 23:07:11 +01:00
break ;
}
2018-02-15 22:59:31 +01:00
}
2018-03-03 23:58:29 +01:00
// če je bila črna črta skrunjena, preverimo naslednjega kandidata
// if we failed, we continue our search with the next candidate
if ( blackEdgeViolation )
continue ;
2018-03-04 23:07:11 +01:00
detections = 0 ;
2018-03-03 23:58:29 +01:00
loopEnd = sampleRow _color + sampleEnd ;
for ( var i = sampleRow _color + sampleStart ; i < loopEnd ; i += 4 ) {
if ( image [ i ] > blackbarTreshold ||
2018-03-04 23:07:11 +01:00
image [ i + 1 ] > blackbarTreshold ||
image [ i + 2 ] > blackbarTreshold ) {
2018-03-03 23:58:29 +01:00
++ detections ;
2018-03-04 23:07:11 +01:00
}
2018-03-03 23:58:29 +01:00
}
if ( detections >= detectionTreshold ) {
if ( edgeCandidatesTop [ sample . top ] != undefined )
edgeCandidatesTop [ sample . top ] . count ++ ;
else {
topEdgeCount ++ ; // only count distinct
edgeCandidatesTop [ sample . top ] = { top : sample . top , count : 1 } ;
}
}
}
for ( sample of samples . res _bottom ) {
blackEdgeViolation = false ; // reset this
// determine our bounds. Note that sample.col is _not_ corrected for imageData, but halfSample is
2018-03-18 15:14:57 +01:00
sampleStart = ( sample . col << 2 ) - halfSample ;
2018-03-03 23:58:29 +01:00
if ( sampleStart < 0 )
sampleStart = 0 ;
sampleEnd = sampleStart + sampleWidthBase ;
if ( sampleEnd > GlobalVars . canvas . imageDataRowLength )
sampleEnd = GlobalVars . canvas . imageDataRowLength ;
// calculate row offsets for imageData array
2018-03-13 23:55:38 +01:00
sampleRow _black = ( sample . bottom + ExtensionConf . arDetect . edgeDetection . edgeTolerancePx ) * GlobalVars . canvas . imageDataRowLength ;
sampleRow _color = ( sample . bottom - 1 - ExtensionConf . arDetect . edgeDetection . edgeTolerancePx ) * GlobalVars . canvas . imageDataRowLength ;
2018-03-03 23:58:29 +01:00
// že ena kršitev črnega roba pomeni, da kandidat ni primeren
// even a single black edge violation means the candidate is not an edge
loopEnd = sampleRow _black + sampleEnd ;
for ( var i = sampleRow _black + sampleStart ; i < loopEnd ; i += 4 ) {
if ( image [ i ] > blackbarTreshold ||
image [ i + 1 ] > blackbarTreshold ||
image [ i + 2 ] > blackbarTreshold ) {
blackEdgeViolation = true ;
break ;
2018-02-15 22:59:31 +01:00
}
2018-03-03 23:58:29 +01:00
}
// če je bila črna črta skrunjena, preverimo naslednjega kandidata
// if we failed, we continue our search with the next candidate
if ( blackEdgeViolation )
continue ;
2018-03-04 23:07:11 +01:00
detections = 0 ;
2018-03-03 23:58:29 +01:00
loopEnd = sampleRow _color + sampleEnd ;
for ( var i = sampleRow _color + sampleStart ; i < loopEnd ; i += 4 ) {
if ( image [ i ] > blackbarTreshold ||
image [ i + 1 ] > blackbarTreshold ||
image [ i + 2 ] > blackbarTreshold ) {
++ detections ;
2018-02-15 22:59:31 +01:00
}
2018-03-03 23:58:29 +01:00
}
if ( detections >= detectionTreshold ) {
if ( edgeCandidatesBottom [ sample . bottom ] != undefined )
2018-03-04 23:07:11 +01:00
edgeCandidatesBottom [ sample . bottom ] . count ++ ;
2018-03-03 23:58:29 +01:00
else {
bottomEdgeCount ++ ; // only count distinct
edgeCandidatesBottom [ sample . bottom ] = { bottom : sample . bottom , bottomRelative : sample . bottomRelative , count : 1 } ;
2018-02-15 22:59:31 +01:00
}
}
2018-02-15 00:17:58 +01:00
}
2018-02-15 22:59:31 +01:00
return {
edgeCandidatesTop : edgeCandidatesTop ,
edgeCandidatesTopCount : topEdgeCount ,
edgeCandidatesBottom : edgeCandidatesBottom ,
edgeCandidatesBottomCount : bottomEdgeCount
} ;
2018-02-15 00:17:58 +01:00
}
2018-03-04 23:07:11 +01:00
var _ard _findBlackbarLimits = function ( image , cols , guardLineResult , imageDetectResult ) {
var upper _top , upper _bottom , lower _top , lower _bottom ;
var blackbarTreshold ;
var cols _a = cols ;
var cols _b = [ ]
for ( var i in cols ) {
cols _b [ i ] = cols _a [ i ] + 0 ;
}
var res _top = [ ] ;
var res _bottom = [ ] ;
2018-03-13 23:55:38 +01:00
var colsTreshold = cols . length * ExtensionConf . arDetect . edgeDetection . minColsForSearch ;
2018-03-04 23:07:11 +01:00
if ( colsTreshold == 0 )
colsTreshold = 1 ;
2018-03-13 23:55:38 +01:00
blackbarTreshold = GlobalVars . arDetect . blackLevel + ExtensionConf . arDetect . blackbarTreshold ;
2018-03-04 23:07:11 +01:00
// if guardline didn't fail and imageDetect did, we don't have to check the upper few pixels
// but only if upper and lower edge are defined. If they're not, we need to check full height
// if(GlobalVars.arDetect.guardLine.top != null || GlobalVars.arDetect.guardLine.bottom != null){
// if(guardLineResult && !imageDetectResult){
// upper_top = GlobalVars.arDetect.guardline.top;
2018-03-13 23:55:38 +01:00
// upper_bottom = (GlobalVars.canvas.height * 0.5) - parseInt(GlobalVars.canvas.height * ExtensionConf.arDetect.edgeDetection.middleIgnoredArea);
2018-03-04 23:07:11 +01:00
//
2018-03-13 23:55:38 +01:00
// lower_top = (GlobalVars.canvas.height * 0.5) + parseInt(GlobalVars.canvas.height * ExtensionConf.arDetect.edgeDetection.middleIgnoredArea);
2018-03-04 23:07:11 +01:00
// lower_bottom = GlobalVars.arDetect.guardline.bottom;
// }
// else if(!guardLineResult && imageDetectResult){
// upper_top = 0;
// upper_bottom = GlobalVars.arDetect.guardline.top;
//
// lower_top = GlobalVars.arDetect.guardline.bottom;
// lower_bottom = GlobalVars.canvas.height;
// }
// else{
// // if they're both false or true (?? they shouldn't be, but let's handle it anyway because dark frames
// // could get confusing enough for that to happen), we go for default
// upper_top = 0;
2018-03-13 23:55:38 +01:00
// upper_bottom = (GlobalVars.canvas.height * 0.5) - parseInt(GlobalVars.canvas.height * ExtensionConf.arDetect.edgeDetection.middleIgnoredArea);
2018-03-04 23:07:11 +01:00
//
2018-03-13 23:55:38 +01:00
// lower_top = (GlobalVars.canvas.height * 0.5) + parseInt(GlobalVars.canvas.height * ExtensionConf.arDetect.edgeDetection.middleIgnoredArea);
2018-03-04 23:07:11 +01:00
// lower_bottom = GlobalVars.canvas.height;
// }
// }
// else{
upper _top = 0 ;
2018-03-13 23:55:38 +01:00
upper _bottom = ( GlobalVars . canvas . height * 0.5 ) /*- parseInt(GlobalVars.canvas.height * ExtensionConf.arDetect.edgeDetection.middleIgnoredArea);*/
2018-03-04 23:07:11 +01:00
2018-03-13 23:55:38 +01:00
lower _top = ( GlobalVars . canvas . height * 0.5 ) /*+ parseInt(GlobalVars.canvas.height * ExtensionConf.arDetect.edgeDetection.middleIgnoredArea);*/
2018-03-04 23:07:11 +01:00
lower _bottom = GlobalVars . canvas . height - 1 ;
// }
var upper _top _corrected = upper _top * GlobalVars . canvas . imageDataRowLength ;
var upper _bottom _corrected = upper _bottom * GlobalVars . canvas . imageDataRowLength ;
var lower _top _corrected = lower _top * GlobalVars . canvas . imageDataRowLength ;
var lower _bottom _corrected = lower _bottom * GlobalVars . canvas . imageDataRowLength ;
var tmpI ;
for ( var i = upper _top _corrected ; i < upper _bottom _corrected ; i += GlobalVars . canvas . imageDataRowLength ) {
for ( var col of cols _a ) {
2018-03-18 15:14:57 +01:00
tmpI = i + ( col << 2 ) ;
2018-03-04 23:07:11 +01:00
if ( image [ tmpI ] > blackbarTreshold ||
image [ tmpI + 1 ] > blackbarTreshold ||
image [ tmpI + 2 ] > blackbarTreshold ) {
2018-03-14 21:19:15 +01:00
2018-03-04 23:07:11 +01:00
res _top . push ( {
col : col ,
top : ( i / GlobalVars . canvas . imageDataRowLength ) - 1
} ) ;
2018-03-18 15:14:57 +01:00
cols _a . splice ( cols _a . indexOf ( col ) , 1 ) ;
}
2018-03-04 23:07:11 +01:00
}
if ( cols _a . length < colsTreshold )
break ;
}
for ( var i = lower _bottom _corrected - GlobalVars . canvas . imageDataRowLength ; i >= lower _top _corrected ; i -= GlobalVars . canvas . imageDataRowLength ) {
for ( var col of cols _b ) {
2018-03-18 15:14:57 +01:00
tmpI = i + ( col << 2 ) ;
2018-03-04 23:07:11 +01:00
if ( image [ tmpI ] > blackbarTreshold ||
image [ tmpI + 1 ] > blackbarTreshold ||
image [ tmpI + 2 ] > blackbarTreshold ) {
2018-03-14 21:19:15 +01:00
2018-03-04 23:07:11 +01:00
var bottom = ( i / GlobalVars . canvas . imageDataRowLength ) + 1 ;
2018-03-18 15:14:57 +01:00
res _bottom . push ( {
col : col ,
bottom : bottom ,
bottomRelative : GlobalVars . canvas . height - bottom
} ) ;
cols _b . splice ( cols _a . indexOf ( col ) , 1 ) ;
}
2018-03-04 23:07:11 +01:00
}
if ( cols _b . length < colsTreshold )
break ;
}
return { res _top : res _top , res _bottom : res _bottom } ;
}
2018-05-01 23:09:58 +02:00
function _ard _guardLineImageDetect ( image , fallbackMode ) {
2018-03-04 23:07:11 +01:00
if ( GlobalVars . arDetect . guardLine . top == null || GlobalVars . arDetect . guardLine . bottom == null )
return { success : false } ;
2018-03-13 23:55:38 +01:00
var blackbarTreshold = GlobalVars . arDetect . blackLevel + ExtensionConf . arDetect . blackbarTreshold ;
2018-03-04 23:07:11 +01:00
var edges = GlobalVars . arDetect . guardLine ;
2018-03-18 15:14:57 +01:00
var offset = parseInt ( GlobalVars . canvas . width * ExtensionConf . arDetect . guardLine . ignoreEdgeMargin ) << 2 ;
2018-03-08 22:22:42 +01:00
2018-03-04 23:07:11 +01:00
// TODO: implement logo check.
// preglejmo obe vrstici - tukaj po pravilih ne bi smeli iti prek mej platna. ne rabimo preverjati
// check both rows - by the rules and definitions, we shouldn't go out of bounds here. no need to check, then
2018-04-11 00:19:44 +02:00
// if(fallbackMode){
// var edge_upper = ExtensionConf.arDetect.fallbackMode.noTriggerZonePx;
// var edge_lower = GlobalVars.canvas.height - ExtensionConf.arDetect.fallbackMode.noTriggerZonePx - 1;
// }
// else{
var edge _upper = edges . top + ExtensionConf . arDetect . guardLine . edgeTolerancePx ;
var edge _lower = edges . bottom - ExtensionConf . arDetect . guardLine . edgeTolerancePx ;
// }
2018-03-18 17:35:51 +01:00
2018-03-04 23:07:11 +01:00
// koliko pikslov rabimo zaznati, da je ta funkcija uspe. Tu dovoljujemo tudi, da so vsi piksli na enem
// robu (eden izmed robov je lahko v celoti črn)
// how many non-black pixels we need to consider this check a success. We only need to detect enough pixels
// on one edge (one of the edges can be black as long as both aren't)
2018-03-13 23:55:38 +01:00
var successTreshold = parseInt ( GlobalVars . canvas . width * ExtensionConf . arDetect . guardLine . imageTestTreshold ) ;
2018-03-04 23:07:11 +01:00
var rowStart , rowEnd ;
// <<<=======| checking upper row |========>>>
2018-03-18 15:14:57 +01:00
rowStart = ( ( edge _upper * GlobalVars . canvas . width ) << 2 ) + offset ;
rowEnd = rowStart + ( GlobalVars . canvas . width << 2 ) - ( offset * 2 ) ;
2018-03-04 23:07:11 +01:00
2018-05-01 23:09:58 +02:00
var res = false ;
2018-03-04 23:07:11 +01:00
2018-05-01 23:09:58 +02:00
if ( Debug . debugCanvas . enabled && Debug . debugCanvas . guardLine ) {
res = _ard _ti _debugCheckRow ( image , rowStart , rowEnd , successTreshold , blackbarTreshold ) ;
} else {
res = _ard _ti _checkRow ( image , rowStart , rowEnd , successTreshold , blackbarTreshold ) ;
2018-03-04 23:07:11 +01:00
}
2018-05-01 23:09:58 +02:00
if ( res )
return { success : true } ;
2018-03-04 23:07:11 +01:00
// <<<=======| checking lower row |========>>>
2018-03-18 15:14:57 +01:00
rowStart = ( ( edge _lower * GlobalVars . canvas . width ) << 2 ) + offset ;
2018-05-01 23:09:58 +02:00
// rowEnd = rowStart + ( GlobalVars.canvas.width << 2 ) - (offset * 2);
2018-03-04 23:07:11 +01:00
2018-05-01 23:09:58 +02:00
if ( Debug . debugCanvas . enabled && Debug . debugCanvas . guardLine ) {
res = _ard _ti _debugCheckRow ( image , rowStart , rowEnd , successTreshold ) ;
} else {
res = _ard _ti _checkRow ( image , rowStart , rowEnd , successTreshold ) ;
}
return { success : res } ;
}
function _ard _ti _checkRow ( image , rowStart , rowEnd , successTreshold , blackbarTreshold ) {
2018-03-04 23:07:11 +01:00
for ( var i = rowStart ; i < rowEnd ; i += 4 ) {
if ( image [ i ] > blackbarTreshold || image [ i + 1 ] > blackbarTreshold || image [ i + 2 ] > blackbarTreshold ) {
if ( successTreshold -- <= 0 ) {
2018-05-01 23:09:58 +02:00
return true ;
2018-03-04 23:07:11 +01:00
}
2018-05-01 23:09:58 +02:00
}
2018-03-04 23:07:11 +01:00
}
2018-05-01 23:09:58 +02:00
return false ;
}
function _ard _ti _debugCheckRow ( image , rowStart , rowEnd , successTreshold , blackbarTreshold ) {
for ( var i = rowStart ; i < rowEnd ; i += 4 ) {
if ( image [ i ] > blackbarTreshold || image [ i + 1 ] > blackbarTreshold || image [ i + 2 ] > blackbarTreshold ) {
DebugCanvas . trace ( 'guardLine_imageTest' , i ) ;
if ( successTreshold -- <= 0 ) {
return true ;
}
} else {
DebugCanvas . trace ( 'guardLine_imageTest_noimage' , i ) ;
}
}
return false ;
2018-03-04 23:07:11 +01:00
}
var _ard _edgePostprocess = function ( edges , canvasHeight ) {
2018-02-15 22:59:31 +01:00
var edgesTop = [ ] ;
var edgesBottom = [ ] ;
2018-03-13 23:55:38 +01:00
var alignMargin = canvasHeight * ExtensionConf . arDetect . allowedMisaligned ;
2018-02-15 22:59:31 +01:00
var missingEdge = edges . edgeCandidatesTopCount == 0 || edges . edgeCandidatesBottomCount == 0 ;
2018-02-15 00:17:58 +01:00
2018-02-15 22:59:31 +01:00
// pretvorimo objekt v tabelo
// convert objects to array
if ( edges . edgeCandidatesTopCount > 0 ) {
2018-02-16 00:19:08 +01:00
for ( var e in edges . edgeCandidatesTop ) {
var edge = edges . edgeCandidatesTop [ e ] ;
2018-02-15 22:59:31 +01:00
edgesTop . push ( { distance : edge . top , count : edge . count } ) ;
}
}
if ( edges . edgeCandidatesBottomCount > 0 ) {
2018-02-16 00:19:08 +01:00
for ( var e in edges . edgeCandidatesBottom ) {
var edge = edges . edgeCandidatesBottom [ e ] ;
2018-02-22 21:06:57 +01:00
edgesBottom . push ( { distance : edge . bottomRelative , absolute : edge . bottom , count : edge . count } ) ;
2018-02-15 22:59:31 +01:00
}
}
2018-04-11 00:19:44 +02:00
// console.log("count top:",edges.edgeCandidatesTopCount, "edges:", edges, "edgesTop[]", edgesTop);
2018-02-16 00:19:08 +01:00
2018-02-15 22:59:31 +01:00
// če za vsako stran (zgoraj in spodaj) poznamo vsaj enega kandidata, potem lahko preverimo nekaj
// stvari
if ( ! missingEdge ) {
// predvidevamo, da je logo zgoraj ali spodaj, nikakor pa ne na obeh straneh hkrati.
// če kanal logotipa/watermarka ni vključil v video, potem si bosta razdaliji (edge.distance) prvih ključev
// zgornjega in spodnjega roba približno enaki
//
// we'll assume that no youtube channel is rude enough to put channel logo/watermark both on top and the bottom
// of the video. If logo's not included in the video, distances (edge.distance) of the first two keys should be
// roughly equal. Let's check for that.
if ( edgesTop [ 0 ] . distance >= edgesBottom [ 0 ] . distance - alignMargin &&
edgesTop [ 0 ] . distance <= edgesBottom [ 0 ] . distance + alignMargin ) {
var blackbarWidth = edgesTop [ 0 ] . distance > edgesBottom [ 0 ] . distance ?
edgesTop [ 0 ] . distance : edgesBottom [ 0 ] . distance ;
2018-02-22 21:06:57 +01:00
return { status : "ar_known" , blackbarWidth : blackbarWidth , guardLineTop : edgesTop [ 0 ] . distance , guardLineBottom : edgesBottom [ 0 ] . absolute } ;
2018-02-15 22:59:31 +01:00
}
// torej, lahko da je na sliki watermark. Lahko, da je slika samo ornh črna. Najprej preverimo za watermark
// it could be watermark. It could be a dark frame. Let's check for watermark first.
if ( edgesTop [ 0 ] . distance < edgesBottom [ 0 ] . distance &&
edgesTop [ 0 ] . count < edgesBottom [ 0 ] . count &&
2018-03-13 23:55:38 +01:00
edgesTop [ 0 ] . count < GlobalVars . arDetect . sampleCols * ExtensionConf . arDetect . edgeDetection . logoTreshold ) {
2018-02-15 22:59:31 +01:00
// možno, da je watermark zgoraj. Preverimo, če se kateri od drugih potencialnih robov na zgornjem robu
// ujema s prvim spodnjim (+/- variance). Če je temu tako, potem bo verjetno watermark. Logo mora imeti
// manj vzorcev kot navaden rob.
if ( edgesTop [ 0 ] . length > 1 ) {
var lowMargin = edgesBottom [ 0 ] . distance - alignMargin ;
var highMargin = edgesBottom [ 0 ] . distance + alignMargin ;
for ( var i = 1 ; i < edgesTop . length ; i ++ ) {
if ( edgesTop [ i ] . distance >= lowMargin && edgesTop [ i ] . distance <= highMargin ) {
// dobili smo dejanski rob. vrnimo ga
// we found the actual edge. let's return that.
var blackbarWidth = edgesTop [ i ] . distance > edgesBottom [ 0 ] . distance ?
edgesTop [ i ] . distance : edgesBottom [ 0 ] . distance ;
2018-02-22 21:06:57 +01:00
return { status : "ar_known" , blackbarWidth : blackbarWidth , guardLineTop : edgesTop [ i ] . distance , guardLineBottom : edgesBottom [ 0 ] . absolute } ;
2018-02-15 22:59:31 +01:00
}
}
}
}
if ( edgesBottom [ 0 ] . distance < edgesTop [ 0 ] . distance &&
edgesBottom [ 0 ] . count < edgesTop [ 0 ] . count &&
2018-03-13 23:55:38 +01:00
edgesBottom [ 0 ] . count < GlobalVars . arDetect . sampleCols * ExtensionConf . arDetect . edgeDetection . logoTreshold ) {
2018-02-15 22:59:31 +01:00
if ( edgesBottom [ 0 ] . length > 1 ) {
var lowMargin = edgesTop [ 0 ] . distance - alignMargin ;
var highMargin = edgesTop [ 0 ] . distance + alignMargin ;
for ( var i = 1 ; i < edgesBottom . length ; i ++ ) {
if ( edgesBottom [ i ] . distance >= lowMargin && edgesTop [ i ] . distance <= highMargin ) {
// dobili smo dejanski rob. vrnimo ga
// we found the actual edge. let's return that.
var blackbarWidth = edgesBottom [ i ] . distance > edgesTop [ 0 ] . distance ?
edgesBottom [ i ] . distance : edgesTop [ 0 ] . distance ;
2018-02-22 21:06:57 +01:00
return { status : "ar_known" , blackbarWidth : blackbarWidth , guardLineTop : edgesTop [ 0 ] . distance , guardLineBottom : edgesBottom [ 0 ] . absolute } ;
2018-02-15 22:59:31 +01:00
}
}
}
}
}
else {
// zgornjega ali spodnjega roba nismo zaznali. Imamo še en trik, s katerim lahko poskusimo
// določiti razmerje stranic
// either the top or the bottom edge remains undetected, but we have one more trick that we
// can try. It also tries to work around logos.
2018-03-13 23:55:38 +01:00
var edgeDetectionTreshold = GlobalVars . arDetect . sampleCols * ExtensionConf . arDetect . edgeDetection . singleSideConfirmationTreshold ;
2018-02-15 22:59:31 +01:00
if ( edges . edgeCandidatesTopCount == 0 && edges . edgeCandidatesBottomCount != 0 ) {
for ( var edge of edgesBottom ) {
if ( edge . count >= edgeDetectionTreshold )
2018-02-22 21:06:57 +01:00
return { status : "ar_known" , blackbarWidth : edge . distance , guardLineTop : null , guardLineBottom : edge . bottom }
2018-02-15 22:59:31 +01:00
}
}
if ( edges . edgeCandidatesTopCount != 0 && edges . edgeCandidatesBottomCount == 0 ) {
for ( var edge of edgesTop ) {
if ( edge . count >= edgeDetectionTreshold )
2018-02-22 21:06:57 +01:00
return { status : "ar_known" , blackbarWidth : edge . distance , guardLineTop : edge . top , guardLineBottom : null }
2018-02-15 22:59:31 +01:00
}
}
}
// če pridemo do sem, nam ni uspelo nič. Razmerje stranic ni znano
// if we reach this bit, we have failed in determining aspect ratio. It remains unknown.
return { status : "ar_unknown" }
2018-02-15 00:17:58 +01:00
}
2017-12-29 23:34:40 +01:00
var _ard _stop = function ( ) {
if ( Debug . debug ) {
console . log ( "%c[ArDetect::_ard_stop] Stopping automatic aspect ratio detection" , _ard _console _stop ) ;
}
this . _forcehalt = true ;
2017-12-30 18:36:08 +01:00
this . _halted = true ;
2017-12-29 23:34:40 +01:00
clearTimeout ( _ard _timer ) ;
clearTimeout ( _ard _setup _timer ) ;
}
2017-09-24 01:54:46 +02:00
2018-02-15 22:59:31 +01:00
var _ard _resetBlackLevel = function ( ) {
2018-03-13 23:55:38 +01:00
GlobalVars . arDetect . blackLevel = ExtensionConf . arDetect . blackLevel _default ;
2018-02-15 22:59:31 +01:00
}
2017-12-30 18:36:08 +01:00
var _ard _isRunning = function ( ) {
return ! this . _halted ;
}
2018-02-15 22:59:31 +01:00
function _ard _getTimeout ( baseTimeout , startTime ) {
2018-03-05 23:55:14 +01:00
// baseTimeout -= (performance.now() - startTime);
2018-02-15 22:59:31 +01:00
2018-03-13 23:55:38 +01:00
// return baseTimeout > ExtensionConf.arDetect.minimumTimeout ? baseTimeout : ExtensionConf.arDetect.minimumTimeout;
2018-03-05 23:55:14 +01:00
return baseTimeout ;
2018-02-15 22:59:31 +01:00
}
2017-09-24 01:54:46 +02:00
var ArDetect = {
2017-12-29 23:34:40 +01:00
_forcehalt : false ,
2017-12-30 18:36:08 +01:00
_halted : false ,
2017-09-24 01:54:46 +02:00
arSetup : _arSetup ,
2017-12-30 12:55:58 +01:00
init : _arSetup ,
2017-09-24 01:54:46 +02:00
vdraw : _ard _vdraw ,
2017-10-02 00:27:01 +02:00
detectedAr : 1 ,
2017-12-29 23:34:40 +01:00
arChangedCallback : function ( ) { } ,
stop : _ard _stop ,
2018-02-15 22:59:31 +01:00
isRunning : _ard _isRunning ,
resetBlackLevel : _ard _resetBlackLevel
2017-09-24 01:54:46 +02:00
}