diff --git a/js/conf/Debug.js b/js/conf/Debug.js index 8fe7d4a..33396cd 100644 --- a/js/conf/Debug.js +++ b/js/conf/Debug.js @@ -18,7 +18,6 @@ Debug = { debugDetection: true }, debugCanvas: { - enable: true, enabled: true, guardLine: true } diff --git a/js/conf/ExtensionConf.js b/js/conf/ExtensionConf.js index 9cd498d..a59e878 100644 --- a/js/conf/ExtensionConf.js +++ b/js/conf/ExtensionConf.js @@ -14,7 +14,7 @@ var ExtensionConf = { allowedMisaligned: 0.05, // top and bottom letterbox thickness can differ by this much. // Any more and we don't adjust ar. allowedArVariance: 0.075, // amount by which old ar can differ from the new (1 = 100%) - timer_playing: 1000, // we trigger ar this often (in ms) under this conditions + timer_playing: 666, // we trigger ar this often (in ms) under this conditions timer_paused: 3000, timer_error: 3000, timer_minimumTimeout: 5, // but regardless of above, we wait this many msec before retriggering @@ -23,7 +23,7 @@ var ExtensionConf = { samplingInterval: 10, // we sample at columns at (width/this) * [ 1 .. this - 1] blackLevel_default: 10, // everything darker than 10/255 across all RGB components is considered black by // default. GlobalVars.blackLevel can decrease if we detect darker black. - blackbarTreshold: 8, // if pixel is darker than blackLevel + blackbarTreshold, we count it as black + blackbarTreshold: 16, // if pixel is darker than blackLevel + blackbarTreshold, we count it as black // on 0-255. Needs to be fairly high (8 might not cut it) due to compression // artifacts in the video itself staticSampleCols: 9, // we take a column at [0-n]/n-th parts along the width and sample it diff --git a/js/lib/PlayerDetect.js b/js/lib/PlayerDetect.js index beb9637..81108ee 100644 --- a/js/lib/PlayerDetect.js +++ b/js/lib/PlayerDetect.js @@ -138,8 +138,13 @@ var _pd_checkPlayerSizeChange = function(){ console.log("[PlayerDetect] player size changed. reason: exited fullscreen"); } } - - if(GlobalVars.playerDimensions.width != GlobalVars.playerDimensions.element.offsetWidth || GlobalVars.playerDimensions.height != GlobalVars.playerDimensions.element.offsetHeight ){ + if(! GlobalVars.playerDimensions.element) + console.log("[PlayerDetect] player element isnt defined"); + + if ( GlobalVars.playerDimensions.element && + ( GlobalVars.playerDimensions.width != GlobalVars.playerDimensions.element.offsetWidth || + GlobalVars.playerDimensions.height != GlobalVars.playerDimensions.element.offsetHeight ) + ){ console.log("[PlayerDetect] player size changed. reason: dimension change. Old dimensions?", GlobalVars.playerDimensions.width, GlobalVars.playerDimensions.height, "new dimensions:", GlobalVars.playerDimensions.element.offsetWidth, GlobalVars.playerDimensions.element.offsetHeight); } } diff --git a/js/modules/ArDetect.js b/js/modules/ArDetect.js index f0a68f0..b94aa88 100644 --- a/js/modules/ArDetect.js +++ b/js/modules/ArDetect.js @@ -153,20 +153,20 @@ var _arSetup = function(cwidth, cheight){ GlobalVars.canvas.imageDataRowLength = canvasWidth << 2; GlobalVars.arDetect.noLetterboxCanvasReset = false; -// GlobalVars.correctedVideoDimensions.height = null; -// GlobalVars.correctedVideoDimensions.width = null; -// GlobalVars.correctedVideoDimensions.top = null; -// GlobalVars.correctedVideoDimensions.left = null; -// + // GlobalVars.correctedVideoDimensions.height = null; + // GlobalVars.correctedVideoDimensions.width = null; + // GlobalVars.correctedVideoDimensions.top = null; + // GlobalVars.correctedVideoDimensions.left = null; + // _ard_vdraw(0); } catch(ex){ console.log(ex); } - if(Debug.debugCanvas.enable){ + if(Debug.debugCanvas.enabled){ DebugCanvas.init({width: canvasWidth, height: canvasHeight}); - DebugCanvas.draw("test marker","test","rect", {x:5, y:5}, {width: 5, height: 5}); + // DebugCanvas.draw("test marker","test","rect", {x:5, y:5}, {width: 5, height: 5}); } }; @@ -383,6 +383,11 @@ var _ard_vdraw_but_for_reals = function() { // we get the entire frame so there's less references for garbage collection to catch var image = GlobalVars.canvas.context.getImageData(0,0,GlobalVars.canvas.width,GlobalVars.canvas.height).data; + if(Debug.debugCanvas.enabled){ + DebugCanvas.showTraces(); + DebugCanvas.setBuffer(image); + } + // 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; @@ -485,51 +490,7 @@ var _ard_vdraw_but_for_reals = function() { var guardLineOut; var imageDetectOut; - if(ExtensionConf.arDetect.guardLine.enabled){ - console.log("GUARDLINE ENABLED") - - if(Debug.debugCanvas.enabled && Debug.debugCanvas.guardLine){ - var xOffset = parseInt(GlobalVars.canvas.width * ExtensionConf.arDetect.guardLine.ignoreEdgeMargin); - var dbgc_w = GlobalVars.canvas.width - (xOffset * 2); - - if(GlobalVars.arDetect.guardLine.top){ - DebugCanvas.draw( - "", - "guardLine_blackbar", - "rect", - {x: xOffset, y: GlobalVars.arDetect.guardLine.top - ExtensionConf.arDetect.guardLine.edgeTolerancePx}, - {width: dbgc_w, height: 1}, - ExtensionConf.arDetect.timer_playing - ); - DebugCanvas.draw( - "", - "guardLine_imageTest", - "rect", - {x: xOffset, y: GlobalVars.arDetect.guardLine.top + ExtensionConf.arDetect.guardLine.edgeTolerancePx}, - {width: dbgc_w, height: 1}, - ExtensionConf.arDetect.timer_playing - ); - } - if(GlobalVars.arDetect.guardLine.bottom){ - DebugCanvas.draw( - "", - "guardLine_blackbar", - "rect", - {x: xOffset, y: GlobalVars.arDetect.guardLine.bottom + ExtensionConf.arDetect.guardLine.edgeTolerancePx}, - {width: dbgc_w, height: 1}, - ExtensionConf.arDetect.timer_playing - ); - DebugCanvas.draw( - "", - "guardLine_imageTest", - "rect", - {x: xOffset, y: GlobalVars.arDetect.guardLine.bottom - ExtensionConf.arDetect.guardLine.edgeTolerancePx}, - {width: dbgc_w, height: 1}, - ExtensionConf.arDetect.timer_playing - ); - } - } - + if(ExtensionConf.arDetect.guardLine.enabled){ guardLineOut = _ard_guardLineCheck(image, fallbackMode); guardLineResult = guardLineOut.success; @@ -538,7 +499,9 @@ var _ard_vdraw_but_for_reals = function() { sampleCols.push(col) } } - + + console.log("GUARDLINE RESULT:", guardLineResult, guardLineOut) + imageDetectOut = _ard_guardLineImageDetect(image, fallbackMode); imageDetectResult = imageDetectOut.success; @@ -574,12 +537,23 @@ var _ard_vdraw_but_for_reals = function() { // 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. // + // če je pillarbox zaznan v primeru spremembe iz ožjega na širše razmerje stranice, razmerje povrnemo na privzeto vrednost. + // // 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. - if(! imageDetectResult){ + + if(! imageDetectResult || ! guardLineResult){ if(pillarTest(image)){ - console.log("pillarboxing, doing jack shit") + + if(Debug.debug && ! guardLineResult){ + console.log("[ArDetect::_ard_vdraw] Detected blackbar violation and pillarbox. Resetting to default aspect ratio."); + } + + if(! guardLineResult){ + Resizer.reset(); + } + delete image; triggerTimeout = _ard_getTimeout(baseTimeout, startTime); _ard_vdraw(triggerTimeout); @@ -597,7 +571,7 @@ var _ard_vdraw_but_for_reals = function() { var edgeCandidates = _ard_edgeDetect(image, blackbarSamples); var edgePost = _ard_edgePostprocess(edgeCandidates, GlobalVars.canvas.height); -// console.log("SAMPLES:", blackbarSamples, "candidates:", edgeCandidates, "post:", edgePost,"\n\nblack level:",GlobalVars.arDetect.blackLevel, "tresh:", GlobalVars.arDetect.blackLevel + ExtensionConf.arDetect.blackbarTreshold); + // console.log("SAMPLES:", blackbarSamples, "candidates:", edgeCandidates, "post:", edgePost,"\n\nblack level:",GlobalVars.arDetect.blackLevel, "tresh:", GlobalVars.arDetect.blackLevel + ExtensionConf.arDetect.blackbarTreshold); if(edgePost.status == "ar_known"){ // zaznali smo rob — vendar pa moramo pred obdelavo še preveriti, ali ni "rob" slučajno besedilo. Če smo kot rob pofočkali @@ -849,58 +823,20 @@ var _ard_guardLineCheck = function(image, fallbackMode){ rowStart = ((edge_upper * GlobalVars.canvas.width) << 2) + offset; rowEnd = rowStart + ( GlobalVars.canvas.width << 2 ) - (offset * 2); - for(var i = rowStart; i < rowEnd; i+=4){ - - // 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){ - firstOffender = (i >> 2) - rowStart; - offenderCount++; - offenders.push({x: firstOffender, width: 1}) - - if(Debug.debugCanvas.enable && Debug.debugCanvas.guardLine){ - DebugCanvas.draw('','guardLine_blackbar_violation', 'rect', {x: i>>2, y: edge_upper}, {width: 3, height: 3}, 1000) - } - } - else{ - offenders[offenderCount].width++ - } - } - else{ - // is that a black pixel again? Let's reset the 'first offender' - firstOffender = -1; - } - + 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); - for(var i = rowStart; i < rowEnd; i+=4){ - // 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){ - firstOffender = (i >> 2) - rowStart; - offenderCount++; - offenders.push({x: firstOffender, width: 1}) - if(Debug.debugCanvas.enable && Debug.debugCanvas.blackBar){ - DebugCanvas.draw('','guardLine_blackbar_violation', 'rect', {x: i>>2, y: edge_lower}, {width: 3, height: 3}, 1000) - } - } - else{ - offenders[offenderCount].width++ - } - } - else{ - // is that a black pixel again? Let's reset the 'first offender' - firstOffender = -1; - } - + 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 @@ -920,6 +856,59 @@ var _ard_guardLineCheck = function(image, fallbackMode){ return {success: false, offenders: ret}; } + +var _ard_gl_rowCheck = function(image, rowStart, rowEnd, offenders, offenderCount, blackbarTreshold){ + var firstOffender = -1; + for(var i = rowStart; i < rowEnd; i+=4){ + + // 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){ + firstOffender = (i - rowStart) >> 2; + offenderCount++; + offenders.push({x: firstOffender, width: 1}); + } + else{ + offenders[offenderCount].width++ + } + } + else{ + // is that a black pixel again? Let's reset the 'first offender' + firstOffender = -1; + } + } + + return offenderCount; +} +var _ard_gl_debugRowCheck = function(image, rowStart, rowEnd, offenders, offenderCount, blackbarTreshold){ + var firstOffender = -1; + for(var i = rowStart; i < rowEnd; i+=4){ + + // 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){ + DebugCanvas.trace('guardLine_blackbar_violation', i); + if(firstOffender < 0){ + firstOffender = (i - rowStart) >> 2; + offenderCount++; + offenders.push({x: firstOffender, width: 1}); + } + else{ + offenders[offenderCount].width++ + } + } + else{ + DebugCanvas.trace('guardLine_blackbar', i); + // is that a black pixel again? Let's reset the 'first offender' + firstOffender = -1; + } + + } + + return offenderCount; +} + var _ard_edgeDetect = function(image, samples){ var edgeCandidatesTop = {}; var edgeCandidatesBottom = {}; @@ -1167,7 +1156,7 @@ var _ard_findBlackbarLimits = function(image, cols, guardLineResult, imageDetect return {res_top: res_top, res_bottom: res_bottom}; } -var _ard_guardLineImageDetect = function(image, fallbackMode){ +function _ard_guardLineImageDetect(image, fallbackMode){ if(GlobalVars.arDetect.guardLine.top == null || GlobalVars.arDetect.guardLine.bottom == null) return { success: false }; @@ -1204,33 +1193,57 @@ var _ard_guardLineImageDetect = function(image, fallbackMode){ rowStart = ((edge_upper * GlobalVars.canvas.width) << 2) + offset; rowEnd = rowStart + ( GlobalVars.canvas.width << 2 ) - (offset * 2); + var res = false; - - for(var i = rowStart; i < rowEnd; i+=4){ - if(image[i] > blackbarTreshold || image[i+1] > blackbarTreshold || image[i+2] > blackbarTreshold){ - if(successTreshold --<= 0){ - return {success: true} - } - } + 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); } + if(res) + return {success: true}; + // <<<=======| checking lower row |========>>> rowStart = ((edge_lower * GlobalVars.canvas.width) << 2) + offset; - rowEnd = rowStart + ( GlobalVars.canvas.width << 2 ) - (offset * 2); + // rowEnd = rowStart + ( GlobalVars.canvas.width << 2 ) - (offset * 2); + 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) { for(var i = rowStart; i < rowEnd; i+=4){ if(image[i] > blackbarTreshold || image[i+1] > blackbarTreshold || image[i+2] > blackbarTreshold){ if(successTreshold --<= 0){ - - return {success: true} + return true; } - } - + } } - - return {success: false}; + + 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; } var _ard_edgePostprocess = function(edges, canvasHeight){ diff --git a/js/modules/DebugCanvas.js b/js/modules/DebugCanvas.js index 99cb7b3..a07fc46 100644 --- a/js/modules/DebugCanvas.js +++ b/js/modules/DebugCanvas.js @@ -2,6 +2,7 @@ var _dbgc_canvas; var _dbgc_context; var _dbgc_timer; var _dbgc_clearTimeoutCount = 0; +var _dbgc_imageBuffer; // drawQueue vsebuje stvari, ki jih bomo risali na platno // Je tabela objektov, ki naj bi zgledali takole: @@ -20,11 +21,18 @@ var _dbgc_drawQueue = []; var _dbgc_classes = { guardLine_blackbar: "#000099", guardLine_imageTest: "#5555FF", - guardLine_blackbar_violation: "#2222FF", + guardLine_blackbar_violation: "#FF0000", test: "#FF0000" } +var _dbgc_traceColors = { + guardLine_blackbar: [0, 0, 96], + guardLine_imageTest: [72, 72, 255], + guardLine_blackbar_violation: [255, 0, 0], + guardLine_imageTest_noimage: [69, 42, 42] +} + var _dbgc_init = async function(canvasSize, canvasPosition){ console.log("initiating DebugCanvas") @@ -53,9 +61,9 @@ var _dbgc_init = async function(canvasSize, canvasPosition){ _dbgc_canvas.width = canvasSize.width; _dbgc_canvas.height = canvasSize.height; - console.log("debug canvas is:", _dbgc_canvas) + console.log("debug canvas is:", _dbgc_canvas, "context:", _dbgc_context) - _dbgc_start(); + // _dbgc_start(); } var _dbgc_removeFromQueue = function(element){ @@ -154,15 +162,59 @@ var _dbgc_update = function(){ _dbgc_scheduleUpdate(100); } +var _dbgc_setBuffer = function(buffer) { + // _dbgc_imageBuffer = buffer.splice(0); + _dbgc_imageBuffer = new Uint8ClampedArray(buffer); + // console.log(buffer, "<--buf") +} +var _dbgc_trace = function(className, arrayIndex){ + _dbgc_imageBuffer[arrayIndex ] = _dbgc_traceColors[className][0]; + _dbgc_imageBuffer[arrayIndex+1] = _dbgc_traceColors[className][1]; + _dbgc_imageBuffer[arrayIndex+2] = _dbgc_traceColors[className][2]; +} + +// because (context.putImageData) doesnt work +function putImageData(ctx, imageData, dx, dy, dirtyX, dirtyY, dirtyWidth, dirtyHeight) { + var data = imageData.data; + var height = imageData.height; + var width = imageData.width; + dirtyX = dirtyX || 0; + dirtyY = dirtyY || 0; + dirtyWidth = dirtyWidth !== undefined? dirtyWidth: width; + dirtyHeight = dirtyHeight !== undefined? dirtyHeight: height; + var limitBottom = Math.min(dirtyHeight, height); + var limitRight = Math.min(dirtyWidth, width); + for (var y = dirtyY; y < limitBottom; y++) { + for (var x = dirtyX; x < limitRight; x++) { + var pos = y * width + x; + ctx.fillStyle = 'rgba(' + data[pos*4+0] + + ',' + data[pos*4+1] + + ',' + data[pos*4+2] + + ',' + (data[pos*4+3]/255) + ')'; + ctx.fillRect(x + dx, y + dy, 1, 1); + } + } +} + +var _dbgc_showTraces = function(){ + if(_dbgc_context && _dbgc_imageBuffer instanceof Uint8ClampedArray){ + var idata = new ImageData(_dbgc_imageBuffer, _dbgc_canvas.width, _dbgc_canvas.height); + putImageData(_dbgc_context, idata, 0, 0); + } +} var DebugCanvas = { events: { }, init: _dbgc_init, - start: _dbgc_start, - draw: _dbgc_draw, - remove: _dbgc_remove, - removeClass: _dbgc_removeClass + // start: _dbgc_start, + // draw: _dbgc_draw, + // remove: _dbgc_remove, + // removeClass: _dbgc_removeClass, + + setBuffer: _dbgc_setBuffer, + trace: _dbgc_trace, + showTraces: _dbgc_showTraces } \ No newline at end of file diff --git a/js/modules/Resizer.js b/js/modules/Resizer.js index f597720..6da7d77 100644 --- a/js/modules/Resizer.js +++ b/js/modules/Resizer.js @@ -48,11 +48,16 @@ var _res_char = function(newAr, video, player){ // Približevanje opuščeno. // handles "legacy" options, such as 'fit to widht', 'fit to height' and 'reset'. No zoom tho var _res_legacyAr = function(action){ - if (!vid) { - return; - } var vid = GlobalVars.video; var ar; + + if (!vid) { + if(Debug.debug){ + console.log("[Resizer.js::_res_legacyAr] No video??",vid) + } + + return; + } if(! GlobalVars.playerDimensions ){ ar = screen.width / screen.height; @@ -76,6 +81,10 @@ var _res_legacyAr = function(action){ _res_setAr( ar < fileAr ? ar : fileAr); } else if(action == "reset"){ + if(Debug.debug){ + console.log("[Resizer.js::_res_legacyAr] Resetting aspect ratio to", fileAr) + } + _res_setAr(fileAr); GlobalVars.lastAr = {type: "original"}; return;