mirror of
https://github.com/k4yt3x/video2x.git
synced 2025-01-01 10:29:09 +00:00
added time elapsed, time remaining and speed rate
This commit is contained in:
parent
5fbc195740
commit
3168737fd4
@ -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()
|
||||||
|
@ -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>
|
||||||
|
Loading…
Reference in New Issue
Block a user