Fixed aspect ratio flip-flopping in fallbackMode (kinda. it's a workaround)

This commit is contained in:
Tamius Han 2018-07-11 00:01:44 +02:00
parent 0825dacdb8
commit 37b59f19ab
4 changed files with 91 additions and 31 deletions

View File

@ -22,7 +22,10 @@ var ExtensionConf = {
autoDisable: { // settings for automatically disabling the extension autoDisable: { // settings for automatically disabling the extension
maxExecutionTime: 6000, // if execution time of main autodetect loop exceeds this many milliseconds, maxExecutionTime: 6000, // if execution time of main autodetect loop exceeds this many milliseconds,
// we disable it. // we disable it.
consecutiveTimeoutCount: 5 // we only do it if it happens this many consecutive times consecutiveTimeoutCount: 5, // we only do it if it happens this many consecutive times
// FOR FUTURE USE
consecutiveArResets: 5 // if aspect ratio reverts immediately after AR change is applied, we disable everything
}, },
hSamples: 640, hSamples: 640,
vSamples: 360, vSamples: 360,
@ -32,6 +35,14 @@ var ExtensionConf = {
blackbarTreshold: 16, // 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 // on 0-255. Needs to be fairly high (8 might not cut it) due to compression
// artifacts in the video itself // artifacts in the video itself
variableBlackbarTresholdOptions: { // In case of poor bitrate videos, jpeg artifacts may cause us issues
// FOR FUTURE USE
enabled: true, // allow increasing blackbar threshold
disableArDetectOnMax: true, // disable autodetection when treshold goes over max blackbar treshold
maxBlackbarTreshold: 48, // max threshold (don't increase past this)
thresholdStep: 8, // when failing to set aspect ratio, increase treshold by this much
increaseAfterConsecutiveResets: 2 // increase if AR resets this many times in a row
},
staticSampleCols: 9, // we take a column at [0-n]/n-th parts along the width and sample it staticSampleCols: 9, // we take a column at [0-n]/n-th parts along the width and sample it
randomSampleCols: 0, // we add this many randomly selected columns to the static columns randomSampleCols: 0, // we add this many randomly selected columns to the static columns
staticSampleRows: 9, // forms grid with staticSampleCols. Determined in the same way. For black frame checks staticSampleRows: 9, // forms grid with staticSampleCols. Determined in the same way. For black frame checks

View File

@ -13,6 +13,17 @@ class GuardLine {
this.imageBar = {top: undefined, bottom: undefined}; this.imageBar = {top: undefined, bottom: undefined};
} }
setBlackbarManual(blackbarConf, imagebarConf){
// ni lepo uporabljat tega, ampak pri fallback mode nastavljamo blackbar stuff na roke
// it's not nice to use this, but we're setting these values manually in fallbackMode
if (blackbarConf) {
this.blackbar = blackbarConf;
}
if (imagebarConf) {
this.imageBar = imagebarConf;
}
}
setBlackbar(bbconf){ setBlackbar(bbconf){
var bbTop = bbconf.top - ExtensionConf.arDetect.guardLine.edgeTolerancePx; var bbTop = bbconf.top - ExtensionConf.arDetect.guardLine.edgeTolerancePx;
var bbBottom = bbconf.bottom + ExtensionConf.arDetect.guardLine.edgeTolerancePx; var bbBottom = bbconf.bottom + ExtensionConf.arDetect.guardLine.edgeTolerancePx;
@ -20,6 +31,7 @@ class GuardLine {
// to odstrani vse neveljavne nastavitve in vse možnosti, ki niso smiselne // to odstrani vse neveljavne nastavitve in vse možnosti, ki niso smiselne
// this removes any configs with invalid values or values that dont make sense // this removes any configs with invalid values or values that dont make sense
if (bbTop < 0 || bbBottom >= this.conf.canvas.height ){ if (bbTop < 0 || bbBottom >= this.conf.canvas.height ){
console.log("%c[GuardLine::setBlackbar] INVALID SETTINGS IN GUARDLINE","background: #000; color: #fff")
this.reset(); this.reset();
return; return;
} }

View File

@ -33,10 +33,18 @@ class ArDetector {
this.edgeDetector = new EdgeDetect(this); this.edgeDetector = new EdgeDetect(this);
this.debugCanvas = new DebugCanvas(this); this.debugCanvas = new DebugCanvas(this);
if(Debug.debug){ if(Debug.debug) {
console.log("[ArDetect::setup] Starting autodetection setup"); console.log("[ArDetect::setup] Starting autodetection setup");
} }
if (this.fallbackMode || cheight !== ExtensionConf.arDetect.hSamples) {
if(Debug.debug) {
console.log("%c[ArDetect::setup] WARNING: CANVAS RESET DETECTED - recalculating guardLine", "background: #000; color: #ff2" )
}
// blackbar, imagebar
this.guardLine.reset();
}
if(!cwidth){ if(!cwidth){
cwidth = ExtensionConf.arDetect.hSamples; cwidth = ExtensionConf.arDetect.hSamples;
cheight = ExtensionConf.arDetect.vSamples; cheight = ExtensionConf.arDetect.vSamples;
@ -292,12 +300,7 @@ class ArDetector {
} }
//#endregion //#endregion
processAr(edges){ calculateArFromEdges(edges) {
if(Debug.debug && Debug.debugArDetect){
console.log("[ArDetect::_ard_processAr] processing ar. sample width:", this.canvas.width, "; sample height:", this.canvas.height, "; edge top:", edges.top);
}
// if we don't specify these things, they'll have some default values. // if we don't specify these things, they'll have some default values.
if(edges.top === undefined){ if(edges.top === undefined){
edges.top = 0; edges.top = 0;
@ -305,10 +308,10 @@ class ArDetector {
edge.left = 0; edge.left = 0;
edges.right = 0; edges.right = 0;
} }
var letterbox = edges.top + edges.bottom; var letterbox = edges.top + edges.bottom;
var trueHeight = this.canvas.height - letterbox; var trueHeight = this.canvas.height - letterbox;
if(this.fallbackMode){ if(this.fallbackMode){
if(edges.top > 1 && edges.top <= ExtensionConf.arDetect.fallbackMode.noTriggerZonePx ){ if(edges.top > 1 && edges.top <= ExtensionConf.arDetect.fallbackMode.noTriggerZonePx ){
console.log("Edge is in the no-trigger zone. Aspect ratio change is not triggered.") console.log("Edge is in the no-trigger zone. Aspect ratio change is not triggered.")
@ -321,9 +324,18 @@ class ArDetector {
// x2 because safetyBorderPx is for one side. // x2 because safetyBorderPx is for one side.
trueHeight += (ExtensionConf.arDetect.fallbackMode.safetyBorderPx << 1); trueHeight += (ExtensionConf.arDetect.fallbackMode.safetyBorderPx << 1);
} }
return this.canvas.width / trueHeight;
}
processAr(trueAr){
// if(Debug.debug && Debug.debugArDetect){
// console.log("[ArDetect::_ard_processAr] processing ar. sample width:", this.canvas.width, "; sample height:", this.canvas.height, "; edge top:", edges.top);
// }
var trueAr = this.canvas.width / trueHeight;
this.detectedAr = trueAr; this.detectedAr = trueAr;
// poglejmo, če se je razmerje stranic spremenilo // poglejmo, če se je razmerje stranic spremenilo
@ -615,25 +627,25 @@ class ArDetector {
// a chance of a logo on black background. We could cut easily cut too much. Because there's a somewhat significant chance // 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. // that we will cut too much, we rather avoid doing anything at all. There's gonna be a next chance.
try{ try{
if(guardLineOut.blackbarFail || guardLineOut.imageFail){ if(guardLineOut.blackbarFail || guardLineOut.imageFail){
if(this.edgeDetector.findBars(image, null, EdgeDetectPrimaryDirection.HORIZONTAL).status === 'ar_known'){ if(this.edgeDetector.findBars(image, null, EdgeDetectPrimaryDirection.HORIZONTAL).status === 'ar_known'){
if(Debug.debug && guardLineOut.blackbarFail){ if(Debug.debug && guardLineOut.blackbarFail){
console.log("[ArDetect::_ard_vdraw] Detected blackbar violation and pillarbox. Resetting to default aspect ratio."); console.log("[ArDetect::_ard_vdraw] Detected blackbar violation and pillarbox. Resetting to default aspect ratio.");
}
if(guardLineOut.blackbarFail){
this.conf.resizer.reset({type: "auto", ar: null});
this.guardLine.reset();
}
triggerTimeout = this.getTimeout(baseTimeout, startTime);
this.scheduleFrameCheck(triggerTimeout);
return;
} }
if(guardLineOut.blackbarFail){
this.conf.resizer.reset({type: "auto", ar: null});
this.guardLine.reset();
}
triggerTimeout = this.getTimeout(baseTimeout, startTime);
this.scheduleFrameCheck(triggerTimeout);
return;
} }
} } catch(e) { }
}catch(e) {console.log("deeee",e)}
// pa poglejmo, kje se končajo črne letvice na vrhu in na dnu videa. // pa poglejmo, kje se končajo črne letvice na vrhu in na dnu videa.
// let's see where black bars end. // let's see where black bars end.
@ -646,6 +658,7 @@ class ArDetector {
// console.log("SAMPLES:", blackbarSamples, "candidates:", edgeCandidates, "post:", edgePost,"\n\nblack level:",GlobalVars.arDetect.blackLevel, "tresh:", this.blackLevel + ExtensionConf.arDetect.blackbarTreshold); // console.log("SAMPLES:", blackbarSamples, "candidates:", edgeCandidates, "post:", edgePost,"\n\nblack level:",GlobalVars.arDetect.blackLevel, "tresh:", this.blackLevel + ExtensionConf.arDetect.blackbarTreshold);
if(edgePost.status == "ar_known"){ 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 // 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. // 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 // we detected an edge — but before we process it, we need to check if the "edge" isn't actually some text. If the detected
@ -661,8 +674,26 @@ class ArDetector {
// textEdge |= textLineTest(image, row); // textEdge |= textLineTest(image, row);
// } // }
// v nekaterih common-sense izjemah ne storimo ničesar
var newAr = this.calculateArFromEdges(edgePost);
if (this.fallbackMode
&& (!guardLineOut.blackbarFail && guardLineOut.imageFail)
&& newAr < this.conf.resizer.getLastAr().ar
) {
// V primeru nesmiselnih rezultatov tudi ne naredimo ničesar.
// v fallback mode se lahko naredi, da je novo razmerje stranice ožje kot staro, kljub temu da je šel
// blackbar test skozi. Spremembe v tem primeru ne dovolimo.
//
// (Pravilen fix? Popraviti je treba računanje robov. V fallback mode je treba upoštevati, da obrobe,
// ki smo jih obrezali, izginejo is canvasa)
triggerTimeout = this.getTimeout(baseTimeout, startTime);
this.scheduleFrameCheck(triggerTimeout);
return;
}
// if(!textEdge){ // if(!textEdge){
this.processAr(edgePost); this.processAr(newAr);
// we also know edges for guardline, so set them. // we also know edges for guardline, so set them.
// we need to be mindful of fallbackMode though // we need to be mindful of fallbackMode though
@ -670,7 +701,13 @@ class ArDetector {
this.guardLine.setBlackbar({top: edgePost.guardLineTop, bottom: edgePost.guardLineBottom}); this.guardLine.setBlackbar({top: edgePost.guardLineTop, bottom: edgePost.guardLineBottom});
} else { } else {
if (this.conf.player.dimensions){ if (this.conf.player.dimensions){
this.guardLine.setBlackbar({top: 0, bottom: this.conf.player.dimensions.height - 1}) this.guardLine.setBlackbarManual({
top: ExtensionConf.arDetect.fallbackMode.noTriggerZonePx,
bottom: this.conf.player.dimensions.height - ExtensionConf.arDetect.fallbackMode.noTriggerZonePx - 1
},{
top: edgePost.guardLineTop + ExtensionConf.arDetect.guardLine.edgeTolerancePx,
bottom: edgePost.guardLineBottom - ExtensionConf.arDetect.guardLine.edgeTolerancePx
})
} }
} }

View File

@ -74,7 +74,7 @@ class Resizer {
if(Debug.debug){ if(Debug.debug){
console.log("[Resizer::setAr] failed to set AR due to problem with calculating crop. Error:", (stretchFactors ? stretchFactors.error : stretchFactors)); console.log("[Resizer::setAr] failed to set AR due to problem with calculating crop. Error:", (stretchFactors ? stretchFactors.error : stretchFactors));
} }
if(dimensions.error === 'no_video'){ if(stretchFactors.error === 'no_video'){
this.conf.destroy(); this.conf.destroy();
} }
return; return;