Skip to content
Merged

2.3.8 #167

Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
273553c
update ver
TNTwise Oct 3, 2025
f37be9f
fix rocm display
TNTwise Oct 3, 2025
94fd831
update changelog
TNTwise Oct 3, 2025
4468864
pass gpu id through to everything
TNTwise Oct 3, 2025
3babfea
remove GIMM due to licensing and publishing to steam
TNTwise Oct 5, 2025
e0224a3
remove all model downloads
TNTwise Oct 6, 2025
cc7cb07
Fix formatting issues in README introduction
TNTwise Oct 8, 2025
27ddfdf
Update README.md
TNTwise Oct 8, 2025
b2f5956
fix yuv decode with ffmpeg and not opencv
TNTwise Oct 10, 2025
ce7fd08
fix output ffmpeg command
TNTwise Oct 10, 2025
2bacc26
open output folder button
TNTwise Oct 12, 2025
8a21361
open output folder button
TNTwise Oct 12, 2025
4e1cf86
cap output scale based on model scale
TNTwise Oct 12, 2025
44377e8
fix error in an incorrect way
TNTwise Oct 12, 2025
87e7d57
better input to output showing in gui
TNTwise Oct 12, 2025
fba510a
UI tweaks
TNTwise Oct 12, 2025
c98e3e7
remove unlock
TNTwise Oct 12, 2025
7be4590
revert yuv420p mods
TNTwise Oct 13, 2025
d1b5038
fix stupid
TNTwise Oct 13, 2025
0067247
some gui improvements
TNTwise Oct 15, 2025
5608421
fix ffv1 colorspace detection
TNTwise Oct 16, 2025
360ef96
rmove log
TNTwise Oct 16, 2025
c49d8e8
update ver
TNTwise Oct 16, 2025
08e02f7
fix auto 10 bit pixel format on auto hdr mode or 10 bit input
TNTwise Oct 16, 2025
3405ccc
hdr mode conditional
TNTwise Oct 16, 2025
c1afacb
better gui info and fix hdr mode not working in all cases
TNTwise Oct 17, 2025
1e509c8
logs or sum
TNTwise Oct 18, 2025
4466d80
improve tooltips
TNTwise Oct 20, 2025
473a9e3
whoops
TNTwise Oct 20, 2025
1d9283a
maybe fix color space detection
TNTwise Oct 20, 2025
c848a53
fix gmfss
TNTwise Oct 20, 2025
c116d33
Update CHANGELOG.md
TNTwise Oct 20, 2025
ffa085b
gmfss full fp16
TNTwise Oct 23, 2025
2cc800d
maybe better videos folder detection
TNTwise Oct 23, 2025
a346627
broken refactoring
TNTwise Oct 23, 2025
d2049ce
upscale model wrapper
TNTwise Oct 24, 2025
a472a4a
fix trt
TNTwise Oct 24, 2025
292f029
Update version number from 2.3.7 to 2.3.8
TNTwise Oct 25, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/prerelease.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ on:
workflow_dispatch:

env:
APP_VERSION: 2.3.7
APP_VERSION: 2.3.8

jobs:

Expand Down
12 changes: 12 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,15 @@
# RVE 2.3.8 pre-release
### Added
- Open output folder button
- Cap output scale based on model scale
### Changed
- UI Tweaks
### Fixed
- ROCm showing cuda on front end.
- GMFSS not working
### Removed
- GIMM.
- locking the app to 1 instance.
# RVE 2.3.7
### Added:
- PyTorch 2.9
Expand Down
7 changes: 4 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
[![pypresence](https://img.shields.io/badge/using-pypresence-00bb88.svg?style=for-the-badge&logo=discord&logoWidth=20)](https://github.com/qwertyquerty/pypresence)

![license](https://img.shields.io/github/license/tntwise/real-video-enhancer)
![Version](https://img.shields.io/badge/Version-2.3.6-blue)
![Version](https://img.shields.io/badge/Version-2.3.8-blue)
![downloads_total](https://img.shields.io/github/downloads/tntwise/REAL-Video-Enhancer/total.svg?label=downloads%40total)
<a href="https://discord.gg/hwGHXga8ck">
<img src="https://img.shields.io/discord/1041502781808328704?label=Discord" alt="Discord Shield"/></a>
Expand Down Expand Up @@ -40,7 +40,7 @@

# Introduction

<strong>REAL Video Enhancer</strong> is a redesigned and enhanced version of the original Rife ESRGAN App for Linux. This program offers convenient access to frame interpolation and upscaling functionalities on Windows, Linux and MacOS , and is an alternative to outdated software like <a rel="noopener noreferrer" href="https://nmkd.itch.io/flowframes" target="_blank" >Flowframes</a> or <a rel="noopener noreferrer" href="https://github.com/mafiosnik777/enhancr" target="_blank">enhancr</a>.
<strong>REAL Video Enhancer</strong> is a redesigned and enhanced version of the original Rife ESRGAN App for Linux. This program offers convenient access to frame interpolation and upscaling functionalities on Windows, Linux and MacOS, and is an alternative to outdated software like <a rel="noopener noreferrer" href="https://nmkd.itch.io/flowframes" target="_blank" >Flowframes</a> or <a rel="noopener noreferrer" href="https://github.com/mafiosnik777/enhancr" target="_blank">enhancr</a>.

<p align=center>
<img src="https://github.com/TNTwise/REAL-Video-Enhancer/blob/v2-main/screenshots/demo.png?raw=true" width = "100%">
Expand Down Expand Up @@ -128,7 +128,7 @@
git clone --recurse-submodules https://github.com/TNTwise/REAL-Video-Enhancer

# Stable
git clone --recurse-submodules https://github.com/TNTwise/REAL-Video-Enhancer --branch 2.3.6
git clone --recurse-submodules https://github.com/TNTwise/REAL-Video-Enhancer --branch 2.3.8
```
# Building:

Expand Down Expand Up @@ -161,6 +161,7 @@ python3 build.py --build BUILD_OPTION --copy_backend
| Software Used | For | Link|
|--|--|--|
| FFmpeg | Multimedia framework for handling video, audio, and other media files | https://ffmpeg.org/
| QT | GUI framework | https://qt.io/
| FFMpeg Builds | Pre-compiled builds of FFMpeg. | Windows/Linux: https://github.com/BtbN/FFmpeg-Builds, MacOS: https://github.com/eko5624/mpv-mac
| PyTorch | Neural Network Inference (CUDA/ROCm/TensorRT) | https://pytorch.org/
| NCNN | Neural Network Inference (Vulkan) | https://github.com/tencent/ncnn
Expand Down
4 changes: 2 additions & 2 deletions REAL-Video-Enhancer.nsi
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,12 @@
; Custom defines
!define NAME "REAL Video Enhancer"
!define APPFILE "REAL-Video-Enhancer.exe"
!define VERSION "2.3.7"
!define VERSION "2.3.8"
!define SLUG "${NAME} v${VERSION}"
!define COMPANYNAME "TNTwise"
!define VERSIONMAJOR 2
!define VERSIONMINOR 3
!define VERSIONBUILD 7
!define VERSIONBUILD 8
!define DISPLAYVERSION "${VERSIONMAJOR}.${VERSIONMINOR}.${VERSIONBUILD}"
!define INSTALLSIZE 297000

Expand Down
41 changes: 27 additions & 14 deletions REAL-Video-Enhancer.py
Original file line number Diff line number Diff line change
Expand Up @@ -340,25 +340,27 @@ def switchToDownloadPage(self):
self.animationHandler.fadeInAnimation(self.stackedWidget)

def updateVideoGUIText(self):
self.settings.readSettings()
if self.isVideoLoaded:
upscaleModelName = self.upscaleModelComboBox.currentText()
interpolateModelName = self.interpolateModelComboBox.currentText()
interpolateTimes = self.getInterpolationMultiplier(interpolateModelName)
scale = self.getUpscaleModelScale(upscaleModelName)
text = (
new_bitrate = 8 if "10" not in self.settingsTab.in_pix_fmt else 10
inputText = (
f"FPS: {round(self.videoFps, 0)} -> {round(self.videoFps * interpolateTimes, 0)}\n"
+ f"Resolution: {self.videoWidth}x{self.videoHeight} -> {self.videoWidth * scale}x{self.videoHeight * scale}\n"
+ f"Frame Count: {self.videoFrameCount} -> {int(round(self.videoFrameCount * interpolateTimes, 0))}\n"
+ f"Bitrate: {self.videoBitrate}\n"
+ f"Encoder: {self.videoEncoder}\n"
+ f"Container: {self.videoContainer}\n"
+ f"Color Space: {self.colorSpace}\n"
+ f"Pixel Format: {self.pixelFMT}\n"
+ f"HDR: {self.videoHDR}\n"
+ f"Bit Depth: {self.videoBitDepth} bit\n"
+ f"Encoder: {self.videoEncoder} -> {self.settings.settings['encoder']}\n"
+ f"Container: {self.videoContainer} -> {self.settings.settings['video_container']}\n"
+ f"Color Space: {self.colorSpace} -> {self.colorSpace}\n"
+ f"Pixel Format: {self.settingsTab.in_pix_fmt} -> {self.settingsTab.out_pixel_fmt}\n"
+ f"HDR: {self.videoHDR} -> {self.videoHDR if self.settings.settings['auto_hdr_mode'] == 'True' else 'False'}\n"
+ f"Bit Depth: {self.videoBitDepth} bit -> {new_bitrate if self.settings.settings['auto_hdr_mode'] == 'True' else 8} bit\n"
)
self.videoInfoTextEdit.setFontPointSize(10)
self.videoInfoTextEdit.setText(text)

self.inputVideoInfoTextEdit.setFontPointSize(10)
self.inputVideoInfoTextEdit.setText(inputText)

def getInterpolationMultiplier(self, interpolateModelName):
if interpolateModelName == "None" or not self.interpolateCheckBox.isChecked():
Expand Down Expand Up @@ -427,6 +429,7 @@ def updateVideoGUIDetails(self):
isDeblur = self.deblurCheckBox.isChecked()
isDenoise = self.denoiseCheckBox.isChecked()
isDecompress = self.decompressCheckBox.isChecked()

self.interpolationContainer.setVisible(isInterpolate)
self.interpolateContainer_2.setVisible(isInterpolate)
self.deblurContainer.setVisible(isDeblur)
Expand All @@ -446,7 +449,13 @@ def updateVideoGUIDetails(self):
self.startTimeSpinBox.setMaximum(self.videoLength)
self.endTimeSpinBox.setMaximum(self.videoLength)
self.timeInVideoScrollBar.setMaximum(self.videoLength)

if isUpscale and (self.upscaleModelComboBox.currentText() != "" or self.upscaleModelComboBox.currentText() != "None"):
try:
max_scale = totalModels[self.upscaleModelComboBox.currentText()][2]
self.upscaleScaleSpinBox.setMaximum(max_scale if max_scale > 0 else 4)
except KeyError: # idk why it does this, gui is shit tbh.
self.upscaleScaleSpinBox.setMaximum(4)

def getCurrentRenderOptions(self, input_file=None, output_path=None):
interpolate = self.interpolateModelComboBox.currentText()
upscale = self.upscaleModelComboBox.currentText()
Expand Down Expand Up @@ -679,6 +688,8 @@ def disableProcessPage(self):
child.setEnabled(False)
for child in self.renderQueueTab.children():
child.setEnabled(False)
for child in self.encoderSettings.children():
child.setEnabled(False)
self.RenderedPreviewControlsContainer.setEnabled(False)
self.scrollArea_4.setEnabled(True)
self.scrollAreaWidgetContents_4.setEnabled(False)
Expand All @@ -691,6 +702,8 @@ def enableProcessPage(self):
child.setEnabled(True)
for child in self.renderQueueTab.children():
child.setEnabled(True)
for child in self.encoderSettings.children():
child.setEnabled(True)
self.RenderedPreviewControlsContainer.setEnabled(True)
self.scrollAreaWidgetContents_4.setEnabled(True)

Expand Down Expand Up @@ -753,6 +766,7 @@ def loadVideo(self, inputFile, multi_file=False):
self.outputFileText.setEnabled(True)

self.outputFileSelectButton.setEnabled(True)
self.openOutputFolderButton.setEnabled(True)
self.isVideoLoaded = True
self.updateVideoGUIDetails()

Expand Down Expand Up @@ -915,11 +929,11 @@ def main():
app.setStyle("Fusion")
app.setPalette(Palette())

if not "--unlock" in sys.argv:
"""if not "--unlock" in sys.argv:
lock_file = QLockFile(LOCKFILE)
if not lock_file.tryLock(10):
QMessageBox.warning(None, "Instance Running", "Another instance is already running.")
sys.exit(0)
sys.exit(0)"""

# setting the pallette
window = MainWindow()
Expand All @@ -933,7 +947,6 @@ def main():
"""
custom command args
--debug: runs the app in debug mode
--unlock: allows more than one instance to be launched
--fullscreen: runs the app in fullscreen
--swap-flatpak-checks: swaps the flatpak checks, ex if the app is running in flatpak, it will run as if it is not
"""
Expand Down
11 changes: 10 additions & 1 deletion backend/rve-backend.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
import argparse
import sys
from src.version import __version__
from src.utils.Util import log


class HandleApplication:
def __init__(self):
Expand All @@ -14,7 +16,7 @@ def __init__(self):
"""from pyinstrument import Profiler
profiler = Profiler()
profiler.start()"""

from src.utils.VideoInfo import OpenCVInfo, print_video_info

if self.args.print_video_info:
Expand All @@ -35,6 +37,13 @@ def __init__(self):
download_ffmpeg()

if not self.batchProcessing():
buffer_str = "=" * len(str(sys.argv[0]))
log(buffer_str, False)
log("RVE Backend Version: " + __version__, False)
log(buffer_str, False)
log("CLI Arguments: ", False)
log(str(sys.argv), False)
log(buffer_str, False)
self.renderVideo()

else:
Expand Down
26 changes: 12 additions & 14 deletions backend/src/FFmpegBuffers.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import queue
import sys
from abc import ABC, abstractmethod
import os
import subprocess
import queue
import sys
import time
import cv2
import numpy as np
Expand Down Expand Up @@ -36,15 +36,16 @@ def __init__(self, inputFile, width, height, start_time, end_time, borderX, bord
self.color_transfer = color_transfer
self.input_pixel_format = input_pixel_format
self.yuv420pMOD = self.input_pixel_format == "yuv420p" and not self.hdr_mode

#self.yuv420pMOD = False
if self.hdr_mode:
self.inputFrameChunkSize = width * height * 6
else:
if self.yuv420pMOD:
self.inputFrameChunkSize = width * height * 3 // 2
else:
self.inputFrameChunkSize = width * height * 3

command = self.command()
log("FFMPEG READ COMMAND: " + str(command))
self.readProcess = subprocess_popen_without_terminal(
self.command(),
stdout=subprocess.PIPE,
Expand All @@ -53,15 +54,14 @@ def __init__(self, inputFile, width, height, start_time, end_time, borderX, bord
self.readQueue = queue.Queue(maxsize=25)

def command(self):
log("Generating FFmpeg READ command...")

command = [
f"{FFMPEG_PATH}",
"-i",
f"{self.inputFile}",
]
filter_string = f"crop={self.width}:{self.height}:{self.borderX}:{self.borderY},scale=w=iw*sar:h=ih" # fix dar != sar

filter_string = f"crop={self.width}:{self.height}:{self.borderX}:{self.borderY},scale=w=iw*sar:h=ih" #+ ":in_range=limited:out_range=full,format=yuv420p" if self.yuv420pMOD == "yuv420p" else "" # fix dar != sar
#if not self.hdr_mode:
# if self.input_pixel_format == "yuv420p":
# filter_string += ":in_range=tv:out_range=pc" # color shifts a smidgen but helps with artifacts when converting yuv to raw
Expand Down Expand Up @@ -182,17 +182,17 @@ def __init__(
self.color_space = color_space
self.color_primaries = color_primaries
self.color_transfer = color_transfer
log(f"FFmpegWrite parameters: inputFile={inputFile}, outputFile={outputFile}, width={width}, height={height}, start_time={start_time}, end_time={end_time}, fps={fps}, crf={crf}, audio_bitrate={audio_bitrate}, pixelFormat={pixelFormat}, overwrite={overwrite}, custom_encoder={custom_encoder}, benchmark={benchmark}, slowmo_mode={slowmo_mode}, upscaleTimes={upscaleTimes}, interpolateFactor={interpolateFactor}, ceilInterpolateFactor={ceilInterpolateFactor}, video_encoder={video_encoder}, audio_encoder={audio_encoder}, subtitle_encoder={subtitle_encoder}, hdr_mode={hdr_mode}, mpv_output={mpv_output}, merge_subtitles={merge_subtitles}")
self.outputFPS = (
(self.fps * self.interpolateFactor)
if not self.slowmo_mode
else self.fps
)
self.ffmpeg_log = open(FFMPEG_LOG_FILE, "w", encoding='utf-8')
try:

command = self.command()
log("\nFFMPEG WRITE COMMAND: " + str(command) + "\n")
self.writeProcess = subprocess_popen_without_terminal(
self.command(),
command,
stdin=subprocess.PIPE,
stderr=self.ffmpeg_log,
stdout=subprocess.PIPE if self.mpv_output else self.ffmpeg_log,
Expand Down Expand Up @@ -386,7 +386,7 @@ def command(self):
"-",
]

log("FFMPEG WRITE COMMAND: " + str(command))

return command

def get_num_frames_rendered(self):
Expand Down Expand Up @@ -440,7 +440,7 @@ def merge_subtitles(self):
log("Benchmark mode enabled, skipping subtitle merge.")
return

temp_output = self.outputFile + ".temp.mkv"
temp_output = self.outputFile + "-" + str(os.getpid()) + "-temp.mkv"
os.rename(self.outputFile, temp_output)

command = [
Expand All @@ -462,16 +462,14 @@ def merge_subtitles(self):
self.outputFile,
]

if self.overwrite:
command.append("-y")

log("Merging subtitles with command: " + " ".join(command))

try:
result = subprocess.run(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
if result.returncode != 0:
log("Failed to merge subtitles. FFmpeg error:")
log(result.stderr.decode())
os.remove(self.outputFile) # Remove incomplete output file
os.rename(temp_output, self.outputFile) # Restore original file
return
os.remove(temp_output)
Expand Down
4 changes: 2 additions & 2 deletions backend/src/RenderVideo.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
from .FFmpeg import InformationWriteOut
from .utils.Encoders import EncoderSettings
from .utils.SceneDetect import SceneDetect
from .utils.Util import log, bytesToImg, resize_image_bytes
from .utils.Util import log, resize_image_bytes
from .utils.BorderDetect import BorderDetect
from .utils.VideoInfo import OpenCVInfo
import numpy as np
Expand Down Expand Up @@ -215,7 +215,7 @@ def __init__(
log(f"Interpolate Factor: {self.interpolateFactor}")
log(f"Total Output Frames: {self.totalOutputFrames}")
log("Model Scale: " + str(self.modelScale))
print("HDR Mode: " + str(hdr_mode), file=sys.stderr)
log("HDR Mode: " + str(hdr_mode))

self.readBuffer = FFmpegRead( # input width
inputFile=inputFile,
Expand Down
Loading