parent
7e70d91582
commit
0eba96af08
@ -10,6 +10,7 @@ var Debug = {
|
||||
keyboard: true,
|
||||
debugResizer: true,
|
||||
debugArDetect: true,
|
||||
scaler: true,
|
||||
// debugStorage: false,
|
||||
// debugStorage: true,
|
||||
// comms: false,
|
||||
|
@ -45,7 +45,7 @@ var ExtensionConf = {
|
||||
|
||||
// samplingInterval: 10, // we sample at columns at (width/this) * [ 1 .. this - 1]
|
||||
blackframe: {
|
||||
sufficientColorVariance: 0.09, // calculate difference between average intensity and pixel, for every pixel for every color
|
||||
sufficientColorVariance: 0.10, // calculate difference between average intensity and pixel, for every pixel for every color
|
||||
// component. Average intensity is normalized to where 0 is black and 1 is biggest value for
|
||||
// that component. If sum of differences between normalized average intensity and normalized
|
||||
// component varies more than this % between color components, we can afford to use less strict
|
||||
|
@ -284,9 +284,6 @@ class ArDetector {
|
||||
// set initial timestamps so frame check will trigger the first time we run the loop
|
||||
let lastFrameCheckStartTime = Date.now() - (this.settings.active.arDetect.timers.playing << 1);
|
||||
|
||||
//
|
||||
console.log("MAIN: BLACKFRAME CONTEXT:", this.blackframeContext)
|
||||
|
||||
const frameCheckTimes = new Array(10).fill(-1);
|
||||
let frameCheckBufferIndex = 0;
|
||||
let fcstart, fctime;
|
||||
@ -302,7 +299,13 @@ class ArDetector {
|
||||
lastFrameCheckStartTime = Date.now();
|
||||
fcstart = performance.now();
|
||||
|
||||
this.frameCheck();
|
||||
try {
|
||||
this.frameCheck();
|
||||
} catch (e) {
|
||||
if (Debug.debug) {
|
||||
console.log("%c[ArDetector::main] Frame check failed:", "color: #000, background: #f00", e);
|
||||
}
|
||||
}
|
||||
|
||||
if (Debug.performanceMetrics) {
|
||||
fctime = performance.now() - fcstart;
|
||||
@ -428,14 +431,37 @@ class ArDetector {
|
||||
if(edges.top === undefined){
|
||||
edges.top = 0;
|
||||
edges.bottom = 0;
|
||||
edge.left = 0;
|
||||
edges.right = 0;
|
||||
edges.left = 0; // RESERVED FOR FUTURE — CURRENTLY UNUSED
|
||||
edges.right = 0; // THIS FUNCTION CAN PRESENTLY ONLY HANDLE LETTERBOX
|
||||
}
|
||||
|
||||
let zoomFactor = 1;
|
||||
var letterbox = edges.top + edges.bottom;
|
||||
const letterbox = edges.top + edges.bottom;
|
||||
|
||||
|
||||
if (! this.fallbackMode) {
|
||||
// Since video is stretched to fit the canvas, we need to take that into account when calculating target
|
||||
// aspect ratio and correct our calculations to account for that
|
||||
|
||||
const fileAr = this.video.videoWidth / this.video.videoHeight;
|
||||
const canvasAr = this.canvas.width / this.canvas.height;
|
||||
let widthCorrected;
|
||||
|
||||
if (edges.top && edges.bottom) {
|
||||
// in case of letterbox, we take canvas height as canon and assume width got stretched or squished
|
||||
|
||||
if (fileAr != canvasAr) {
|
||||
widthCorrected = this.canvas.height * fileAr;
|
||||
} else {
|
||||
widthCorrected = this.canvas.width;
|
||||
}
|
||||
|
||||
return widthCorrected / (this.canvas.height - letterbox);
|
||||
}
|
||||
} else {
|
||||
// fallback mode behaves a wee bit differently
|
||||
|
||||
let zoomFactor = 1;
|
||||
|
||||
if (this.fallbackMode) {
|
||||
// there's stuff missing from the canvas. We need to assume canvas' actual height is bigger by a factor x, where
|
||||
// x = [video.zoomedHeight] / [video.unzoomedHeight]
|
||||
//
|
||||
@ -446,11 +472,9 @@ class ArDetector {
|
||||
|
||||
zoomFactor = vbr.height / this.video.clientHeight;
|
||||
letterbox += vbr.height - this.video.clientHeight;
|
||||
}
|
||||
|
||||
var trueHeight = this.canvas.height * zoomFactor - letterbox;
|
||||
var trueHeight = this.canvas.height * zoomFactor - letterbox;
|
||||
|
||||
if(this.fallbackMode){
|
||||
if(edges.top > 1 && edges.top <= this.settings.active.arDetect.fallbackMode.noTriggerZonePx ){
|
||||
if(Debug.debug && Debug.debugArDetect) {
|
||||
console.log("Edge is in the no-trigger zone. Aspect ratio change is not triggered.")
|
||||
@ -463,10 +487,9 @@ class ArDetector {
|
||||
// safety border so we can detect aspect ratio narrowing (21:9 -> 16:9).
|
||||
// x2 because safetyBorderPx is for one side.
|
||||
trueHeight += (this.settings.active.arDetect.fallbackMode.safetyBorderPx << 1);
|
||||
|
||||
return this.canvas.width * zoomFactor / trueHeight;
|
||||
}
|
||||
|
||||
|
||||
return this.canvas.width * zoomFactor / trueHeight;
|
||||
}
|
||||
|
||||
processAr(trueAr){
|
||||
@ -476,7 +499,7 @@ class ArDetector {
|
||||
// poglejmo, če se je razmerje stranic spremenilo
|
||||
// check if aspect ratio is changed:
|
||||
var lastAr = this.conf.resizer.getLastAr();
|
||||
if( lastAr.type === AspectRatio.Automatic && lastAr.ratio !== null){
|
||||
if (lastAr.type === AspectRatio.Automatic && lastAr.ratio !== null){
|
||||
// spremembo lahko zavrnemo samo, če uporabljamo avtomatski način delovanja in če smo razmerje stranic
|
||||
// že nastavili.
|
||||
//
|
||||
|
@ -30,25 +30,33 @@ class EdgeDetect{
|
||||
findBars(image, sampleCols, direction = EdgeDetectPrimaryDirection.VERTICAL, quality = EdgeDetectQuality.IMPROVED, guardLineOut, blackFrameAnalysis){
|
||||
let fastCandidates, edgeCandidates, bars;
|
||||
if (direction == EdgeDetectPrimaryDirection.VERTICAL) {
|
||||
fastCandidates = this.findCandidates(image, sampleCols, guardLineOut);
|
||||
|
||||
if (! this.isValidSample(fastCandidates)) {
|
||||
return {status: EdgeStatus.AR_UNKNOWN};
|
||||
}
|
||||
// if(quality == EdgeDetectQuality.FAST){
|
||||
// edges = fastCandidates; // todo: processing
|
||||
// } else {
|
||||
edgeCandidates = this.edgeDetect(image, fastCandidates);
|
||||
console.log("edge candidates:", edgeCandidates)
|
||||
bars = this.edgePostprocess(edgeCandidates, this.conf.canvas.height);
|
||||
console.log("bars:", bars)
|
||||
try {
|
||||
fastCandidates = this.findCandidates(image, sampleCols, guardLineOut);
|
||||
|
||||
if (! this.isValidSample(fastCandidates)) {
|
||||
return {status: EdgeStatus.AR_UNKNOWN};
|
||||
}
|
||||
// if(quality == EdgeDetectQuality.FAST){
|
||||
// edges = fastCandidates; // todo: processing
|
||||
// } else {
|
||||
edgeCandidates = this.edgeDetect(image, fastCandidates);
|
||||
console.log("edge candidates:", edgeCandidates)
|
||||
bars = this.edgePostprocess(edgeCandidates, this.conf.canvas.height);
|
||||
console.log("bars:", bars)
|
||||
|
||||
// }
|
||||
// }
|
||||
} catch (e) {
|
||||
if (Debug.debug) {
|
||||
console.log("%c[EdgeDetect::findBars] find bars failed.", "background: #f00, color: #000", e);
|
||||
}
|
||||
return {status: EdgeStatus.AR_UNKNOWN}
|
||||
}
|
||||
} else {
|
||||
bars = this.pillarTest(image) ? {status: EdgeStatus.AR_KNOWN} : {status: EdgeStatus.AR_UNKNOWN};
|
||||
}
|
||||
|
||||
return bars;
|
||||
|
||||
}
|
||||
|
||||
findCandidates(image, sampleCols, guardLineOut){
|
||||
|
@ -13,13 +13,15 @@ class Scaler {
|
||||
this.conf = videoData;
|
||||
}
|
||||
|
||||
modeToAr(ar){
|
||||
|
||||
// Skrbi za "stare" možnosti, kot na primer "na širino zaslona", "na višino zaslona" in "ponastavi".
|
||||
// Približevanje opuščeno.
|
||||
// handles "legacy" options, such as 'fit to widht', 'fit to height' and AspectRatio.Reset. No zoom tho
|
||||
modeToAr (ar) {
|
||||
if (ar.ratio) {
|
||||
return ar.ratio;
|
||||
}
|
||||
// Skrbi za "stare" možnosti, kot na primer "na širino zaslona", "na višino zaslona" in "ponastavi".
|
||||
// Približevanje opuščeno.
|
||||
// handles "legacy" options, such as 'fit to widht', 'fit to height' and AspectRatio.Reset. No zoom tho
|
||||
|
||||
var ratioOut;
|
||||
|
||||
if (!this.conf.video) {
|
||||
@ -69,8 +71,9 @@ class Scaler {
|
||||
|
||||
calculateCrop(ar) {
|
||||
if(!this.conf.video || this.conf.video.videoWidth == 0 || this.conf.video.videoHeight == 0){
|
||||
if(Debug.debug)
|
||||
if (Debug.debug) {
|
||||
console.log("[Scaler::calculateCrop] ERROR — no video detected.");
|
||||
}
|
||||
|
||||
this.conf.destroy();
|
||||
return {error: "no_video"};
|
||||
@ -81,18 +84,21 @@ class Scaler {
|
||||
}
|
||||
|
||||
// handle fuckie-wuckies
|
||||
if (! ar.ratio){
|
||||
if(Debug.debug)
|
||||
if (!ar.ratio){
|
||||
if (Debug.debug && Debug.scaler) {
|
||||
console.log("[Scaler::calculateCrop] no ar?", ar.ratio, " -- we were given this mode:", ar);
|
||||
}
|
||||
return {error: "no_ar", ratio: ar.ratio};
|
||||
}
|
||||
|
||||
if(Debug.debug)
|
||||
if (Debug.debug && Debug.scaler) {
|
||||
console.log("[Scaler::calculateCrop] trying to set ar. args are: ar->",ar.ratio,"; this.conf.player.dimensions->",this.conf.player.dimensions.width, "×", this.conf.player.dimensions.height, "| obj:", this.conf.player.dimensions);
|
||||
}
|
||||
|
||||
if( (! this.conf.player.dimensions) || this.conf.player.dimensions.width === 0 || this.conf.player.dimensions.height === 0 ){
|
||||
if(Debug.debug)
|
||||
if (Debug.debug && Debug.scaler) {
|
||||
console.log("[Scaler::calculateCrop] ERROR — no (or invalid) this.conf.player.dimensions:",this.conf.player.dimensions);
|
||||
}
|
||||
return {error: "this.conf.player.dimensions_error"};
|
||||
}
|
||||
|
||||
@ -104,12 +110,14 @@ class Scaler {
|
||||
var fileAr = this.conf.video.videoWidth / this.conf.video.videoHeight;
|
||||
var playerAr = this.conf.player.dimensions.width / this.conf.player.dimensions.height;
|
||||
|
||||
if(ar.type === AspectRatio.Initial || !ar.ratio)
|
||||
if (ar.type === AspectRatio.Initial || !ar.ratio) {
|
||||
ar.ratio = fileAr;
|
||||
}
|
||||
|
||||
|
||||
if(Debug.debug)
|
||||
if (Debug.debug && Debug.scaler) {
|
||||
console.log("[Scaler::calculateCrop] ar is " ,ar.ratio, ", file ar is", fileAr, ", this.conf.player.dimensions are ", this.conf.player.dimensions.width, "×", this.conf.player.dimensions.height, "| obj:", this.conf.player.dimensions);
|
||||
}
|
||||
|
||||
var videoDimensions = {
|
||||
xFactor: 1,
|
||||
@ -122,14 +130,15 @@ class Scaler {
|
||||
// console.log("[Scaler::calculateCrop] Player dimensions?", this.conf.player.dimensions.width, "×", this.conf.player.dimensions.height, "| obj:", this.conf.player.dimensions);
|
||||
// }
|
||||
|
||||
if( fileAr < ar.ratio ){
|
||||
if (fileAr < ar.ratio){
|
||||
// imamo letterbox zgoraj in spodaj -> spremenimo velikost videa (a nikoli širše od ekrana)
|
||||
// letterbox -> change video size (but never to wider than monitor width)
|
||||
|
||||
// if (Debug.debug && Debug.scaler) {
|
||||
// console.log(`%c[Scaler::calculateCrop] Trying to determine scaling factors. Aspect ratios:\n file: ${fileAr.toFixed(3)}\n player: ${playerAr.toFixed(3)}\n target: ${ar.ratio.toFixed(3)}\n-----------------------`, "color: #2ba");
|
||||
// }
|
||||
videoDimensions.xFactor = Math.min(ar.ratio, playerAr) / fileAr;
|
||||
videoDimensions.yFactor = videoDimensions.xFactor;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
videoDimensions.xFactor = fileAr / Math.min(ar.ratio, playerAr);
|
||||
videoDimensions.yFactor = videoDimensions.xFactor;
|
||||
}
|
||||
|
@ -34,19 +34,24 @@ https://www.youtube.com/watch?v=NaTGwlfRB_c (dark, triggers minor corrections)
|
||||
|
||||
https://www.youtube.com/watch?v=tXTFdDrd7pA
|
||||
|
||||
|
||||
### HARD MODE
|
||||
|
||||
For situations that would be _really_ hard to fix (if fix is even possible)
|
||||
|
||||
#### Gradient incorrectly triggers aspect ratio correction
|
||||
|
||||
IGN: Hollow Knight Review | https://www.youtube.com/watch?v=hg25ONutphA
|
||||
IGN: Hollow Knight Review | https://www.youtube.com/watch?v=hg25ONutphA (Should be mostly fixed as of 4.0.0)
|
||||
|
||||
#### Text triggers autodetection
|
||||
|
||||
If detected edge is text, extension shouldn't crop.
|
||||
|
||||
https://www.reddit.com/r/videos/comments/a137pj/daily_reminder_that_shelly_miscavige_wife_of/
|
||||
|
||||
### Bugs
|
||||
|
||||
#### Incorrect crops
|
||||
|
||||
Incorrect crop when fixing vertical videos with letterbox: https://www.youtube.com/watch?v=9DP0TbOQcOw — [Issue 48](https://github.com/xternal7/ultrawidify/issues/48)
|
||||
~~Incorrect crop when fixing vertical videos with letterbox: https://www.youtube.com/watch?v=9DP0TbOQcOw — [Issue 48](https://github.com/xternal7/ultrawidify/issues/48)~~
|
||||
|
||||
Incorrect crop on 4:3 in certain circumstances: https://www.reddit.com/r/videos/comments/a137pj/daily_reminder_that_shelly_miscavige_wife_of/ (embedded) — [Issue 54](https://github.com/xternal7/ultrawidify/issues/54)
|
||||
~~Incorrect crop on 4:3 in certain circumstances: https://www.reddit.com/r/videos/comments/a137pj/daily_reminder_that_shelly_miscavige_wife_of/ (embedded) — [Issue 54](https://github.com/xternal7/ultrawidify/issues/54)~~
|
Loading…
Reference in New Issue
Block a user