added time elapsed, time remaining and speed rate

This commit is contained in:
k4yt3x 2020-05-06 20:20:38 -04:00
parent 5fbc195740
commit 3168737fd4
2 changed files with 205 additions and 116 deletions

View File

@ -10,16 +10,13 @@ Last Modified: May 6, 2020
# local imports # local imports
from upscaler import Upscaler from upscaler import Upscaler
# built-in imports
import pathlib
import sys
# built-in imports # built-in imports
import contextlib import contextlib
import pathlib
import re import re
import shutil import shutil
import sys
import tempfile import tempfile
import threading
import time import time
import traceback import traceback
import yaml import yaml
@ -45,21 +42,45 @@ AVAILABLE_DRIVERS = {
'Anime4KCPP': 'anime4kcpp' 'Anime4KCPP': 'anime4kcpp'
} }
def resource_path(relative_path: str) -> pathlib.Path:
try:
base_path = pathlib.Path(sys._MEIPASS)
except Exception:
base_path = pathlib.Path(__file__).parent
return base_path / relative_path
class UpscalerSignals(QObject):
finished = pyqtSignal() class WorkerSignals(QObject):
progress = pyqtSignal(tuple)
error = pyqtSignal(str) error = pyqtSignal(str)
finished = pyqtSignal()
class Worker(QRunnable): class ProgressBarWorker(QRunnable):
def __init__(self, fn, *args, **kwargs):
super(ProgressBarWorker, self).__init__()
self.fn = fn
self.args = args
self.kwargs = kwargs
self.signals = WorkerSignals()
self.kwargs['progress_callback'] = self.signals.progress
@pyqtSlot()
def run(self):
try:
self.fn(*self.args, **self.kwargs)
except Exception:
pass
class UpscalerWorker(QRunnable):
def __init__(self, fn, *args, **kwargs): def __init__(self, fn, *args, **kwargs):
super(Worker, self).__init__() super(UpscalerWorker, self).__init__()
# Store constructor arguments (re-used for processing) # Store constructor arguments (re-used for processing)
self.fn = fn self.fn = fn
self.args = args self.args = args
self.kwargs = kwargs self.kwargs = kwargs
self.signals = UpscalerSignals() self.signals = WorkerSignals()
@pyqtSlot() @pyqtSlot()
def run(self): def run(self):
@ -78,9 +99,9 @@ class Video2XMainWindow(QtWidgets.QMainWindow):
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs) super().__init__(*args, **kwargs)
uic.loadUi('video2x_gui.ui', self) uic.loadUi(str(resource_path('video2x_gui.ui')), self)
self.video2x_icon_path = str((pathlib.Path(__file__).parent / 'images' / 'video2x.png').absolute()) self.video2x_icon_path = str(resource_path('images/video2x.png'))
self.setWindowTitle(f'Video2X GUI {VERSION}') self.setWindowTitle(f'Video2X GUI {VERSION}')
self.setWindowIcon(QtGui.QIcon(self.video2x_icon_path)) self.setWindowIcon(QtGui.QIcon(self.video2x_icon_path))
@ -126,8 +147,11 @@ class Video2XMainWindow(QtWidgets.QMainWindow):
# progress bar and start/stop controls # progress bar and start/stop controls
self.progress_bar = self.findChild(QtWidgets.QProgressBar, 'progressBar') self.progress_bar = self.findChild(QtWidgets.QProgressBar, 'progressBar')
self.time_elapsed_label = self.findChild(QtWidgets.QLabel, 'timeElapsedLabel')
self.time_remaining_label = self.findChild(QtWidgets.QLabel, 'timeRemainingLabel')
self.rate_label = self.findChild(QtWidgets.QLabel, 'rateLabel')
self.start_button = self.findChild(QtWidgets.QPushButton, 'startButton') self.start_button = self.findChild(QtWidgets.QPushButton, 'startButton')
self.start_button.clicked.connect(self.upscale) self.start_button.clicked.connect(self.start)
self.stop_button = self.findChild(QtWidgets.QPushButton, 'stopButton') self.stop_button = self.findChild(QtWidgets.QPushButton, 'stopButton')
self.stop_button.clicked.connect(self.stop) self.stop_button.clicked.connect(self.stop)
@ -482,7 +506,7 @@ class Video2XMainWindow(QtWidgets.QMainWindow):
message_box.setText(message) message_box.setText(message)
message_box.exec_() message_box.exec_()
def start_progress_bar(self): def start_progress_bar(self, progress_callback):
# initialize variables early # initialize variables early
self.upscaler.progress_bar_exit_signal = False self.upscaler.progress_bar_exit_signal = False
@ -490,14 +514,43 @@ class Video2XMainWindow(QtWidgets.QMainWindow):
self.upscaler.total_frames = 1 self.upscaler.total_frames = 1
# initialize progress bar values # initialize progress bar values
self.progress_bar.setValue(0) upscale_begin_time = time.time()
progress_callback.emit((0, 0, 0, upscale_begin_time))
# keep querying upscaling process and feed information to callback signal
while not self.upscaler.progress_bar_exit_signal: while not self.upscaler.progress_bar_exit_signal:
self.progress_bar.setValue(int(100 * self.upscaler.total_frames_upscaled / self.upscaler.total_frames)) progress_callback.emit((int(100 * self.upscaler.total_frames_upscaled / self.upscaler.total_frames),
self.upscaler.total_frames_upscaled,
self.upscaler.total_frames,
upscale_begin_time))
time.sleep(1) time.sleep(1)
self.progress_bar.setValue(100)
def upscale(self): # upscale process will stop at 99%
# so it's set to 100 manually when all is done
progress_callback.emit((100, 0, 0, upscale_begin_time))
def set_progress(self, progress_information: tuple):
progress_percentage = progress_information[0]
total_frames_upscaled = progress_information[1]
total_frames = progress_information[2]
upscale_begin_time = progress_information[3]
# calculate fields based on frames and time elapsed
time_elapsed = time.time() - upscale_begin_time
try:
rate = total_frames_upscaled / (time.time() - upscale_begin_time)
time_remaining = (total_frames - total_frames_upscaled) / rate
except Exception:
rate = 0.0
time_remaining = 0.0
# set calculated values in GUI
self.progress_bar.setValue(progress_percentage)
self.time_elapsed_label.setText('Time Elapsed: {}'.format(time.strftime("%H:%M:%S", time.gmtime(time_elapsed))))
self.time_remaining_label.setText('Time Remaining: {}'.format(time.strftime("%H:%M:%S", time.gmtime(time_remaining))))
self.rate_label.setText('Rate (FPS): {}'.format(round(rate, 2)))
def start(self):
# start execution # start execution
try: try:
@ -505,6 +558,13 @@ class Video2XMainWindow(QtWidgets.QMainWindow):
self.begin_time = time.time() self.begin_time = time.time()
# resolve input and output directories from GUI # resolve input and output directories from GUI
if self.input_line_edit.text().strip() == '':
self.show_error('Input path not specified')
return
if self.output_line_edit.text().strip() == '':
self.show_error('Output path not specified')
return
input_directory = pathlib.Path(self.input_line_edit.text()) input_directory = pathlib.Path(self.input_line_edit.text())
output_directory = pathlib.Path(self.output_line_edit.text()) output_directory = pathlib.Path(self.output_line_edit.text())
@ -520,8 +580,6 @@ class Video2XMainWindow(QtWidgets.QMainWindow):
# if input specified is a single file # if input specified is a single file
if input_directory.is_file(): if input_directory.is_file():
# upscale single video file
# check for input output format mismatch # check for input output format mismatch
if output_directory.is_dir(): if output_directory.is_dir():
self.show_error('Input and output path type mismatch\n\ self.show_error('Input and output path type mismatch\n\
@ -547,11 +605,12 @@ class Video2XMainWindow(QtWidgets.QMainWindow):
# start progress bar # start progress bar
if AVAILABLE_DRIVERS[self.driver_combo_box.currentText()] != 'anime4kcpp': if AVAILABLE_DRIVERS[self.driver_combo_box.currentText()] != 'anime4kcpp':
progress_bar_worker = Worker(self.start_progress_bar) progress_bar_worker = ProgressBarWorker(self.start_progress_bar)
progress_bar_worker.signals.progress.connect(self.set_progress)
self.threadpool.start(progress_bar_worker) self.threadpool.start(progress_bar_worker)
# run upscaler # run upscaler
worker = Worker(self.upscaler.run) worker = UpscalerWorker(self.upscaler.run)
worker.signals.error.connect(self.upscale_errored) worker.signals.error.connect(self.upscale_errored)
worker.signals.finished.connect(self.upscale_completed) worker.signals.finished.connect(self.upscale_completed)
self.threadpool.start(worker) self.threadpool.start(worker)
@ -582,11 +641,11 @@ class Video2XMainWindow(QtWidgets.QMainWindow):
# start progress bar # start progress bar
if AVAILABLE_DRIVERS[self.driver_combo_box.currentText()] != 'anime4kcpp': if AVAILABLE_DRIVERS[self.driver_combo_box.currentText()] != 'anime4kcpp':
progress_bar_worker = Worker(self.start_progress_bar) progress_bar_worker = ProgressBarWorker(self.start_progress_bar)
self.threadpool.start(progress_bar_worker) self.threadpool.start(progress_bar_worker)
# run upscaler # run upscaler
worker = Worker(self.upscaler.run) worker = UpscalerWorker(self.upscaler.run)
worker.signals.error.connect(self.upscale_errored) worker.signals.error.connect(self.upscale_errored)
worker.signals.finished.connect(self.upscale_completed) worker.signals.finished.connect(self.upscale_completed)
self.threadpool.start(worker) self.threadpool.start(worker)
@ -598,8 +657,6 @@ class Video2XMainWindow(QtWidgets.QMainWindow):
except Exception: except Exception:
self.upscale_errored(traceback.format_exc()) self.upscale_errored(traceback.format_exc())
finally:
self.upscale_completed() self.upscale_completed()
def upscale_errored(self, error_message): def upscale_errored(self, error_message):
@ -624,7 +681,6 @@ class Video2XMainWindow(QtWidgets.QMainWindow):
# TODO unimplemented yet # TODO unimplemented yet
pass pass
app = QtWidgets.QApplication(sys.argv) app = QtWidgets.QApplication(sys.argv)
window = Video2XMainWindow() window = Video2XMainWindow()
window.show() window.show()

View File

@ -6,8 +6,8 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>617</width> <width>691</width>
<height>474</height> <height>503</height>
</rect> </rect>
</property> </property>
<property name="windowTitle"> <property name="windowTitle">
@ -194,82 +194,78 @@
</property> </property>
<layout class="QVBoxLayout" name="verticalLayout_4"> <layout class="QVBoxLayout" name="verticalLayout_4">
<item> <item>
<layout class="QVBoxLayout" name="expressSettingsVerticalLayout"> <layout class="QHBoxLayout" name="driverHorizontalLayout">
<item> <item>
<layout class="QHBoxLayout" name="driverHorizontalLayout"> <widget class="QLabel" name="driverLabel">
<item> <property name="text">
<widget class="QLabel" name="driverLabel"> <string>Driver</string>
<property name="text"> </property>
<string>Driver</string> </widget>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="driverComboBox">
<item>
<property name="text">
<string>Waifu2X Caffe</string>
</property>
</item>
<item>
<property name="text">
<string>Waifu2X Converter CPP</string>
</property>
</item>
<item>
<property name="text">
<string>Waifu2X NCNN Vulkan</string>
</property>
</item>
<item>
<property name="text">
<string>SRMD NCNN Vulkan</string>
</property>
</item>
<item>
<property name="text">
<string>Anime4KCPP</string>
</property>
</item>
</widget>
</item>
</layout>
</item> </item>
<item> <item>
<layout class="QHBoxLayout" name="processesHorizontalLayout"> <widget class="QComboBox" name="driverComboBox">
<item> <item>
<widget class="QLabel" name="processesLabel"> <property name="text">
<property name="text"> <string>Waifu2X Caffe</string>
<string>Processes</string> </property>
</property>
</widget>
</item> </item>
<item> <item>
<widget class="QSpinBox" name="processesSpinBox"> <property name="text">
<property name="minimum"> <string>Waifu2X Converter CPP</string>
<number>1</number> </property>
</property>
</widget>
</item> </item>
</layout> <item>
<property name="text">
<string>Waifu2X NCNN Vulkan</string>
</property>
</item>
<item>
<property name="text">
<string>SRMD NCNN Vulkan</string>
</property>
</item>
<item>
<property name="text">
<string>Anime4KCPP</string>
</property>
</item>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="processesHorizontalLayout">
<item>
<widget class="QLabel" name="processesLabel">
<property name="text">
<string>Processes</string>
</property>
</widget>
</item> </item>
<item> <item>
<layout class="QHBoxLayout" name="scaleRatioHorizontalLayout"> <widget class="QSpinBox" name="processesSpinBox">
<item> <property name="minimum">
<widget class="QLabel" name="scaleRatioLabel"> <number>1</number>
<property name="text"> </property>
<string>Scale Ratio</string> </widget>
</property> </item>
</widget> </layout>
</item> </item>
<item> <item>
<widget class="QDoubleSpinBox" name="scaleRatioDoubleSpinBox"> <layout class="QHBoxLayout" name="scaleRatioHorizontalLayout">
<property name="value"> <item>
<double>2.000000000000000</double> <widget class="QLabel" name="scaleRatioLabel">
</property> <property name="text">
</widget> <string>Scale Ratio</string>
</item> </property>
</layout> </widget>
</item>
<item>
<widget class="QDoubleSpinBox" name="scaleRatioDoubleSpinBox">
<property name="value">
<double>2.000000000000000</double>
</property>
</widget>
</item> </item>
</layout> </layout>
</item> </item>
@ -1188,7 +1184,7 @@
</widget> </widget>
</item> </item>
<item> <item>
<layout class="QHBoxLayout" name="controlsHorizontalLayout"> <layout class="QVBoxLayout" name="controlsVerticalLayout">
<item> <item>
<widget class="QProgressBar" name="progressBar"> <widget class="QProgressBar" name="progressBar">
<property name="value"> <property name="value">
@ -1197,24 +1193,61 @@
</widget> </widget>
</item> </item>
<item> <item>
<widget class="QPushButton" name="startButton"> <layout class="QHBoxLayout" name="timeControlsHorizontalLayout">
<property name="enabled"> <item>
<bool>false</bool> <widget class="QLabel" name="timeElapsedLabel">
</property> <property name="acceptDrops">
<property name="text"> <bool>false</bool>
<string>Start</string> </property>
</property> <property name="frameShape">
</widget> <enum>QFrame::StyledPanel</enum>
</item> </property>
<item> <property name="text">
<widget class="QPushButton" name="stopButton"> <string>Time Elapsed: 00:00:00</string>
<property name="enabled"> </property>
<bool>false</bool> </widget>
</property> </item>
<property name="text"> <item>
<string>Stop</string> <widget class="QLabel" name="timeRemainingLabel">
</property> <property name="frameShape">
</widget> <enum>QFrame::StyledPanel</enum>
</property>
<property name="text">
<string>Time Remaining: 00:00:00</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="rateLabel">
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<property name="text">
<string>Rate (FPS): 0.0</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="startButton">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>Start</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="stopButton">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>Stop</string>
</property>
</widget>
</item>
</layout>
</item> </item>
</layout> </layout>
</item> </item>
@ -1225,7 +1258,7 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>617</width> <width>691</width>
<height>21</height> <height>21</height>
</rect> </rect>
</property> </property>