monitor autodetection performance
This commit is contained in:
parent
f94f6ec956
commit
1556506bd7
@ -116,6 +116,13 @@
|
||||
:site="site"
|
||||
>
|
||||
</PlayerDetectionPanel>
|
||||
<AutodetectionSettingsPanel
|
||||
v-if="selectedTab === 'autodetectionSettings'"
|
||||
:settings="settings"
|
||||
:eventBus="eventBus"
|
||||
:site="site"
|
||||
>
|
||||
</AutodetectionSettingsPanel>
|
||||
<!-- <ResizerDebugPanel :debugData="debugData">
|
||||
</ResizerDebugPanel> -->
|
||||
</template>
|
||||
@ -127,6 +134,7 @@
|
||||
|
||||
<script>
|
||||
import VideoSettings from './src/PlayerUiPanels/VideoSettings.vue'
|
||||
import AutodetectionSettingsPanel from './src/PlayerUiPanels/AutodetectionSettingsPanel.vue'
|
||||
import PlayerDetectionPanel from './src/PlayerUiPanels/PlayerDetectionPanel.vue'
|
||||
import { mapState } from 'vuex';
|
||||
// import Icon from '../common/components/Icon';
|
||||
@ -142,7 +150,8 @@ export default {
|
||||
// Icon,
|
||||
ResizerDebugPanel,
|
||||
VideoSettings,
|
||||
PlayerDetectionPanel
|
||||
PlayerDetectionPanel,
|
||||
AutodetectionSettingsPanel,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
|
420
src/csui/src/PlayerUiPanels/AutodetectionSettingsPanel.vue
Normal file
420
src/csui/src/PlayerUiPanels/AutodetectionSettingsPanel.vue
Normal file
@ -0,0 +1,420 @@
|
||||
<template>
|
||||
<div class="flex flex-column tab-root">
|
||||
<div class="flex flex-row flex-wrap">
|
||||
|
||||
<!-- AARD performance metrics -->
|
||||
<div class="sub-panel">
|
||||
<div class="flex flex-row">
|
||||
<h1><mdicon name="television-play" :size="32" /> Automatic Aspect Ratio Detection</h1>
|
||||
</div>
|
||||
<div class="sub-panel-content">
|
||||
<p>
|
||||
<b>Autodetection performance</b>
|
||||
</p>
|
||||
<p>
|
||||
Automatic aspect ratio detection is a resource-hungry feature.
|
||||
This page allows you to trade autodetection accuracy and/or frequency for
|
||||
better performance.
|
||||
</p>
|
||||
<p>
|
||||
Note that some browsers <a href="https://developer.mozilla.org/en-US/docs/Web/API/Performance/now" target="_blank">limit the accuracy of time measurements</a>.
|
||||
</p>
|
||||
<div class="performance-graph-container">
|
||||
<div class="performance-graph">
|
||||
<div class="time-budget hz144"></div>
|
||||
<div class="time-budget hz120"></div>
|
||||
<div class="time-budget hz60"></div>
|
||||
<div class="time-budget hz30"></div>
|
||||
<div class="time-budget hz24"></div>
|
||||
<div class="time-budget rest"></div>
|
||||
|
||||
<div class="bar-container">
|
||||
<div class="average-case">
|
||||
<div class="stats">
|
||||
<b>Average: </b>
|
||||
<span class="draw">draw (main) {{(performanceData?.imageDraw?.averageTime ?? 0).toFixed(1)}} ms</span> |
|
||||
<span class="draw-blackframe">draw (blackframe) {{(performanceData?.blackFrameDraw?.averageTime ?? 0).toFixed(1)}} ms</span> |
|
||||
<span class="processing">
|
||||
processing {{
|
||||
Math.max(
|
||||
(performanceData?.total?.averageTime ?? 0)
|
||||
- (performanceData?.imageDraw?.averageTime ?? 0)
|
||||
- (performanceData?.imageDraw?.averageTime ?? 0),
|
||||
0
|
||||
).toFixed(1)
|
||||
}} ms
|
||||
</span>
|
||||
</div>
|
||||
<div class="bar">
|
||||
<div
|
||||
class="draw"
|
||||
:style="{'width': (performanceData?.imageDraw?.averageTime ?? 0) + '%'}"
|
||||
>
|
||||
</div>
|
||||
<div
|
||||
class="draw-blackframe"
|
||||
:style="{'width': (performanceData?.blackFrameDraw?.averageTime ?? 0) + '%'}"
|
||||
>
|
||||
</div>
|
||||
<div
|
||||
class="processing"
|
||||
:style="{
|
||||
'width': Math.max(
|
||||
(performanceData?.total?.averageTime ?? 0)
|
||||
- (performanceData?.imageDraw?.averageTime ?? 0)
|
||||
- (performanceData?.imageDraw?.averageTime ?? 0),
|
||||
0
|
||||
) + '%'
|
||||
}"
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="worst-case">
|
||||
<div class="stats">
|
||||
<b>Worst: </b>
|
||||
<span class="draw">draw (main) {{(performanceData?.imageDraw?.worstTime ?? 0).toFixed(1)}} ms</span> |
|
||||
<span class="draw-blackframe">draw (blackframe) {{(performanceData?.blackFrameDraw?.worstTime ?? 0).toFixed(1)}} ms</span> |
|
||||
<span class="processing">
|
||||
processing {{
|
||||
Math.max(
|
||||
(performanceData?.total?.worstTime ?? 0)
|
||||
- (performanceData?.imageDraw?.worstTime ?? 0)
|
||||
- (performanceData?.blackFrameDraw?.worstTime ?? 0),
|
||||
0
|
||||
).toFixed(1)
|
||||
}} ms
|
||||
</span>
|
||||
</div>
|
||||
<div class="bar">
|
||||
<div
|
||||
class="draw"
|
||||
:style="{'width': (performanceData?.imageDraw?.worstTime ?? 0) + '%'}"
|
||||
>
|
||||
</div>
|
||||
<div
|
||||
class="draw-blackframe"
|
||||
:style="{'width': (performanceData?.blackFrameDraw?.worstTime ?? 0) + '%'}"
|
||||
>
|
||||
</div>
|
||||
<div
|
||||
class="processing"
|
||||
:style="{
|
||||
'width': Math.max(
|
||||
(performanceData?.total?.worstTime ?? 0)
|
||||
- (performanceData?.imageDraw?.worstTime ?? 0)
|
||||
- (performanceData?.blackFrameDraw?.worstTime ?? 0),
|
||||
0
|
||||
) + '%'
|
||||
}"
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="average-case">
|
||||
<div class="stats">
|
||||
<b>AR change (average): </b>
|
||||
<span class="draw">draw (main) {{(performanceData?.imageDraw?.averageTime ?? 0).toFixed(1)}} ms</span> |
|
||||
<span class="draw-blackframe">draw (blackframe) {{(performanceData?.blackFrameDraw?.averageTime ?? 0).toFixed(1)}} ms</span> |
|
||||
<span class="processing">processing {{
|
||||
(
|
||||
(performanceData?.blackFrame?.averageTime ?? 0)
|
||||
+ (performanceData?.fastLetterbox?.averageTime ?? 0)
|
||||
+ (performanceData?.edgeDetect?.averageTime ?? 0)
|
||||
).toFixed(1)
|
||||
}} ms</span>
|
||||
</div>
|
||||
<div class="bar">
|
||||
<div
|
||||
class="draw"
|
||||
:style="{'width': (performanceData?.imageDraw?.averageTime ?? 0) + '%'}"
|
||||
>
|
||||
</div>
|
||||
<div
|
||||
class="draw-blackframe"
|
||||
:style="{'width': (performanceData?.blackFrameDraw?.averageTime ?? 0) + '%'}"
|
||||
>
|
||||
</div>
|
||||
<div
|
||||
class="processing"
|
||||
:style="{
|
||||
'width': (
|
||||
(performanceData?.blackFrame?.averageTime ?? 0)
|
||||
+ (performanceData?.fastLetterbox?.averageTime ?? 0)
|
||||
+ (performanceData?.edgeDetect?.averageTime ?? 0)
|
||||
) + '%'
|
||||
}"
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="worst-case">
|
||||
<div class="stats">
|
||||
<b>AR change (worst): </b>
|
||||
<span class="draw">draw (main) {{(performanceData?.imageDraw?.worstTime ?? 0).toFixed(1)}} ms</span> |
|
||||
<span class="draw-blackframe">draw (blackframe) {{(performanceData?.blackFrameDraw?.worstTime ?? 0).toFixed(1)}} ms</span> |
|
||||
<span class="processing">processing {{
|
||||
(
|
||||
(performanceData?.blackFrame?.worstTime ?? 0)
|
||||
+ (performanceData?.fastLetterbox?.worstTime ?? 0)
|
||||
+ (performanceData?.edgeDetect?.worstTime ?? 0)
|
||||
).toFixed(1)
|
||||
}} ms</span>
|
||||
</div>
|
||||
<div class="bar">
|
||||
<div
|
||||
class="draw"
|
||||
:style="{'width': (performanceData?.imageDraw?.worstTime ?? 0) + '%'}"
|
||||
>
|
||||
</div>
|
||||
<div
|
||||
class="draw-blackframe"
|
||||
:style="{'width': (performanceData?.blackFrameDraw?.worstTime ?? 0) + '%'}"
|
||||
>
|
||||
</div>
|
||||
<div
|
||||
class="processing"
|
||||
:style="{
|
||||
'width': (
|
||||
(performanceData?.blackFrame?.worstTime ?? 0)
|
||||
+ (performanceData?.fastLetterbox?.worstTime ?? 0)
|
||||
+ (performanceData?.edgeDetect?.worstTime ?? 0)
|
||||
) + '%'
|
||||
}"
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Button from '../../../common/components/Button.vue'
|
||||
import KeyboardShortcutParser from '../../../common/js/KeyboardShortcutParser';
|
||||
import ShortcutButton from '../../../common/components/ShortcutButton';
|
||||
import EditShortcutButton from '../../../common/components/EditShortcutButton';
|
||||
import ExecAction from '../ui-libs/ExecAction';
|
||||
import BrowserDetect from '../../../ext/conf/BrowserDetect';
|
||||
import AspectRatioType from '../../../common/enums/AspectRatioType.enum';
|
||||
import StretchType from '../../../common/enums/StretchType.enum';
|
||||
import CropModePersistence from '../../../common/enums/CropModePersistence.enum';
|
||||
import AlignmentOptionsControlComponent from './AlignmentOptionsControlComponent.vue';
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
exec: null,
|
||||
performanceData: {},
|
||||
graphRefreshInterval: undefined,
|
||||
}
|
||||
},
|
||||
mixins: [
|
||||
],
|
||||
props: [
|
||||
'settings',
|
||||
'frame',
|
||||
'eventBus',
|
||||
'site'
|
||||
],
|
||||
created() {
|
||||
this.exec = new ExecAction(this.settings, window.location.hostname);
|
||||
this.eventBus.subscribe('uw-config-broadcast', {function: (config) => this.handleConfigBroadcast(config)});
|
||||
},
|
||||
mounted() {
|
||||
this.eventBus.sendToTunnel('get-aard-timing');
|
||||
this.graphRefreshInterval = setInterval(() => this.eventBus.sendToTunnel('get-aard-timing'), 500);
|
||||
},
|
||||
destroyed() {
|
||||
clearInterval(this.graphRefreshInterval);
|
||||
},
|
||||
components: {
|
||||
ShortcutButton,
|
||||
EditShortcutButton,
|
||||
Button,
|
||||
AlignmentOptionsControlComponent
|
||||
},
|
||||
computed: {
|
||||
},
|
||||
methods: {
|
||||
async openOptionsPage() {
|
||||
BrowserDetect.runtime.openOptionsPage();
|
||||
},
|
||||
refreshGraph() {
|
||||
this.eventBus.sendToTunnel('get-aard-timing');
|
||||
},
|
||||
handleConfigBroadcast(data) {
|
||||
console.log('GOT CONFIG BROADCAST!', data);
|
||||
if (data.type === 'aard-performance-data') {
|
||||
this.performanceData = data.performanceData;
|
||||
this.$nextTick( () => this.$forceUpdate() );
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" src="../../../res/css/flex.scss" scoped module></style>
|
||||
<style lang="scss" src="../res-common/panels.scss" scoped module></style>
|
||||
<style lang="scss" src="../res-common/common.scss" scoped module></style>
|
||||
|
||||
<style lang="scss" scoped module>
|
||||
@import '../res-common/variables';
|
||||
|
||||
.performance-graph-container {
|
||||
position: relative;
|
||||
|
||||
width: 100%;
|
||||
height: 8rem;
|
||||
padding: 1rem;
|
||||
|
||||
.performance-graph {
|
||||
border: 1px solid #fa6;
|
||||
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
// graph is 100 ms wide
|
||||
.time-budget {
|
||||
height: 100%;
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
|
||||
box-sizing: border-box;
|
||||
|
||||
z-index: 100;
|
||||
|
||||
&.hz144 {
|
||||
width: 6.9%;
|
||||
// background-color: rgba(143, 143, 235, 0.47);
|
||||
}
|
||||
&.hz120 {
|
||||
width: 1.39%;
|
||||
// background-color: rgba(108, 108, 211, 0.441);
|
||||
}
|
||||
&.hz60 {
|
||||
width: 8.33%;
|
||||
// background-color: rgba(78, 78, 182, 0.327);
|
||||
border-right: 2px solid rgb(96, 96, 227);
|
||||
&::after {
|
||||
content: '60fps';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: -2px;
|
||||
|
||||
border-right: 2px solid rgb(96, 96, 227);
|
||||
|
||||
transform: translateY(-100%);
|
||||
|
||||
font-size: 0.6rem;
|
||||
padding-right: 0.25rem;
|
||||
text-transform: small-caps;
|
||||
}
|
||||
}
|
||||
&.hz30 {
|
||||
width: 16.67%;
|
||||
// background-color: rgba(56, 56, 151, 0.308);
|
||||
border-right: 2px solid #fb772a;
|
||||
|
||||
&::after {
|
||||
content: '30fps';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: -2px;
|
||||
|
||||
border-right: 2px solid #fb772a;
|
||||
|
||||
transform: translateY(-100%);
|
||||
|
||||
font-size: 0.6rem;
|
||||
padding-right: 0.25rem;
|
||||
text-transform: small-caps;
|
||||
}
|
||||
}
|
||||
&.hz24 {
|
||||
width: 8.33%;
|
||||
// background-color: rgba(37, 37, 118, 0.269);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.bar-container {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
padding-top: 0.5rem;
|
||||
padding-bottom: 0.5rem;
|
||||
|
||||
> div {
|
||||
height: 2.5rem;
|
||||
}
|
||||
|
||||
.stats {
|
||||
background-color: rgba(0, 0, 0, 0.544);
|
||||
font-size: 0.75rem;
|
||||
font-family: 'Overpass Mono';
|
||||
z-index: 11010;
|
||||
|
||||
span {
|
||||
font-size: 0.75rem;
|
||||
z-index: 11011;
|
||||
|
||||
&::before {
|
||||
content: '';
|
||||
display: inline-block;
|
||||
width: 0.75rem;
|
||||
height: 0.75rem;
|
||||
margin-top: 0.25rem;
|
||||
margin-right: 0.5rem;
|
||||
}
|
||||
|
||||
&.draw::before {
|
||||
background-color: #fb772a;
|
||||
}
|
||||
&.draw-blackframe::before {
|
||||
background-color: #e70c0c;
|
||||
}
|
||||
&.processing::before {
|
||||
background-color: rgb(176, 167, 239);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.bar {
|
||||
width: 100%;
|
||||
height: 0.69rem;
|
||||
background-color: #000;
|
||||
|
||||
overflow: hidden;
|
||||
* {
|
||||
display: inline-block;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.draw {
|
||||
background-color: #fb772a;
|
||||
}
|
||||
.draw-blackframe {
|
||||
background-color: #e70c0c;
|
||||
}
|
||||
.processing {
|
||||
background-color: rgb(176, 167, 239);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
@ -31,6 +31,7 @@ export interface AardPerformanceMeasurement {
|
||||
|
||||
export interface AardPerformanceData {
|
||||
total: AardPerformanceMeasurement,
|
||||
theoretical: AardPerformanceMeasurement,
|
||||
imageDraw: AardPerformanceMeasurement
|
||||
blackFrameDraw: AardPerformanceMeasurement,
|
||||
blackFrame: AardPerformanceMeasurement,
|
||||
@ -136,6 +137,8 @@ class ArDetector {
|
||||
this.settings = videoData.settings;
|
||||
this.eventBus = videoData.eventBus;
|
||||
|
||||
this.initEventBus();
|
||||
|
||||
this.sampleCols = [];
|
||||
|
||||
this.blackLevel = this.settings.active.arDetect.blackbar.blackLevel;
|
||||
@ -146,6 +149,15 @@ class ArDetector {
|
||||
this.logger.log('info', 'init', `[ArDetector::ctor] creating new ArDetector. arid: ${this.arid}`);
|
||||
}
|
||||
|
||||
private initEventBus() {
|
||||
for (const action in this.eventBusCommands) {
|
||||
for (const command of this.eventBusCommands[action]) {
|
||||
this.eventBus.subscribe(action, command);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
init(){
|
||||
this.logger.log('info', 'init', `[ArDetect::init] <@${this.arid}> Initializing autodetection.`);
|
||||
this.setup();
|
||||
@ -471,6 +483,10 @@ class ArDetector {
|
||||
let totalWorst = 0;
|
||||
let totalStDev = 0;
|
||||
|
||||
let theoreticalAverage = 0;
|
||||
let theoreticalWorst = 0;
|
||||
let theoreticalStDev = 0;
|
||||
|
||||
for (const sample of this.performance.samples) {
|
||||
if (sample.imageDrawTime) {
|
||||
imageDrawCount++;
|
||||
@ -511,12 +527,39 @@ class ArDetector {
|
||||
if (execTime > totalWorst) {
|
||||
totalWorst = execTime;
|
||||
}
|
||||
|
||||
const partialExecTime =
|
||||
sample.imageDrawTime ?? 0
|
||||
+ sample.blackFrameDrawTime ?? 0
|
||||
+ sample.blackFrameProcessTime ?? 0;
|
||||
|
||||
if (partialExecTime > theoreticalWorst) {
|
||||
theoreticalWorst = partialExecTime;
|
||||
}
|
||||
}
|
||||
|
||||
imageDrawAverage /= imageDrawCount;
|
||||
blackFrameDrawAverage /= blackFrameDrawCount;
|
||||
blackFrameProcessAverage /= blackFrameProcessCount;
|
||||
totalAverage /= this.performance.samples.length;
|
||||
if (imageDrawCount) {
|
||||
imageDrawAverage /= imageDrawCount;
|
||||
} else {
|
||||
imageDrawAverage = 0;
|
||||
}
|
||||
if (blackFrameDrawCount) {
|
||||
blackFrameDrawAverage /= blackFrameDrawCount;
|
||||
} else {
|
||||
blackFrameDrawAverage = 0;
|
||||
}
|
||||
if (blackFrameProcessCount) {
|
||||
blackFrameProcessAverage /= blackFrameProcessCount;
|
||||
} else {
|
||||
blackFrameProcessAverage = 0;
|
||||
}
|
||||
if (this.performance.samples.length) {
|
||||
totalAverage /= this.performance.samples.length;
|
||||
} else {
|
||||
totalAverage = 0;
|
||||
}
|
||||
|
||||
theoreticalAverage = imageDrawAverage + blackFrameDrawAverage + blackFrameProcessAverage;
|
||||
|
||||
for (const sample of this.performance.lastMeasurements.fastLetterbox.samples) {
|
||||
fastLetterboxAverage += sample;
|
||||
@ -533,8 +576,19 @@ class ArDetector {
|
||||
fastLetterboxCount = this.performance.lastMeasurements.fastLetterbox.samples.length;
|
||||
edgeDetectCount = this.performance.lastMeasurements.edgeDetect.samples.length;
|
||||
|
||||
fastLetterboxAverage /= fastLetterboxCount;
|
||||
edgeDetectAverage /= edgeDetectCount;
|
||||
if (fastLetterboxCount) {
|
||||
fastLetterboxAverage /= fastLetterboxCount;
|
||||
} else {
|
||||
fastLetterboxAverage = 0;
|
||||
}
|
||||
if (edgeDetectCount) {
|
||||
edgeDetectAverage /= edgeDetectCount;
|
||||
} else {
|
||||
edgeDetectAverage = 0;
|
||||
}
|
||||
|
||||
theoreticalWorst += fastLetterboxWorst + edgeDetectWorst;
|
||||
theoreticalAverage += fastLetterboxAverage + edgeDetectAverage;
|
||||
|
||||
for (const sample of this.performance.samples) {
|
||||
if (sample.imageDrawTime) {
|
||||
@ -599,6 +653,7 @@ class ArDetector {
|
||||
totalStDev = Math.sqrt(totalStDev / (this.performance.samples.length - 1));
|
||||
}
|
||||
|
||||
|
||||
const res: AardPerformanceData = {
|
||||
total: {
|
||||
sampleCount: this.performance.samples.length,
|
||||
@ -606,6 +661,12 @@ class ArDetector {
|
||||
worstTime: totalWorst,
|
||||
stDev: totalStDev,
|
||||
},
|
||||
theoretical: {
|
||||
sampleCount: -1,
|
||||
averageTime: theoreticalAverage,
|
||||
worstTime: theoreticalWorst,
|
||||
stDev: theoreticalStDev
|
||||
},
|
||||
imageDraw: {
|
||||
sampleCount: imageDrawCount,
|
||||
averageTime: imageDrawAverage,
|
||||
@ -644,7 +705,7 @@ class ArDetector {
|
||||
edgeDetectCount
|
||||
}
|
||||
|
||||
this.eventBus.send('uw-config-broadcast', {type: 'aard-performance-data', config: res});
|
||||
this.eventBus.send('uw-config-broadcast', {type: 'aard-performance-data', performanceData: res});
|
||||
}
|
||||
//#endregion
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user