mirror of
https://github.com/k4yt3x/video2x.git
synced 2026-02-14 00:54:47 +08:00
Compare commits
19 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f5eb6514e1 | ||
|
|
3f6a3addaa | ||
|
|
8f2113ab0a | ||
|
|
60cf792c23 | ||
|
|
7e87dac15e | ||
|
|
0b15fb7bd2 | ||
|
|
765db2512b | ||
|
|
e14fbea67b | ||
|
|
491f80d2d2 | ||
|
|
2f4953e6c7 | ||
|
|
3f36cb8b43 | ||
|
|
3e57e206c6 | ||
|
|
da0e47528c | ||
|
|
f6aac30f96 | ||
|
|
7d00189f2f | ||
|
|
751150fe64 | ||
|
|
eb2b62b056 | ||
|
|
cc1b0b5464 | ||
|
|
fe7ded7e53 |
3
.gitignore
vendored
3
.gitignore
vendored
@@ -1,3 +1,6 @@
|
|||||||
|
# QtCreator
|
||||||
|
video2x_gui.pyproject.user
|
||||||
|
|
||||||
# PyCharm
|
# PyCharm
|
||||||
.idea/
|
.idea/
|
||||||
|
|
||||||
|
|||||||
178
Dockerfile
178
Dockerfile
@@ -7,181 +7,25 @@
|
|||||||
# Last Modified: May 24, 2020
|
# Last Modified: May 24, 2020
|
||||||
|
|
||||||
# Editor: K4YT3X
|
# Editor: K4YT3X
|
||||||
# Last Modified: May 30, 2020
|
# Last Modified: June 5, 2020
|
||||||
|
|
||||||
|
# using Ubuntu LTS 19.10
|
||||||
|
# Ubuntu 20.x is incompatible with Nvidia libraries
|
||||||
FROM ubuntu:19.10
|
FROM ubuntu:19.10
|
||||||
#FROM nvidia/cuda:10.1-cudnn7-devel-ubuntu18.04
|
|
||||||
|
|
||||||
|
# file mainainter labels
|
||||||
LABEL maintainer="Danielle Douglas <ddouglas87@gmail.com>"
|
LABEL maintainer="Danielle Douglas <ddouglas87@gmail.com>"
|
||||||
LABEL maintainer="Lhanjian <lhjay1@foxmail.com>"
|
LABEL maintainer="Lhanjian <lhjay1@foxmail.com>"
|
||||||
LABEL maintainer="K4YT3X <k4yt3x@k4yt3x.com>"
|
LABEL maintainer="K4YT3X <k4yt3x@k4yt3x.com>"
|
||||||
|
|
||||||
# Don't ask questions during image setup.
|
# run installation
|
||||||
ENV DEBIAN_FRONTEND noninteractive
|
RUN apt-get update \
|
||||||
ENV NASM_VERSION 2.14
|
&& apt-get install -y git-core \
|
||||||
ENV NVCODEC_VERSION 8.2.15.6
|
&& git clone --recurse-submodules --progress https://github.com/k4yt3x/video2x.git /tmp/video2x/video2x \
|
||||||
ENV PKG_CONFIG_PATH /usr/local/lib/pkgconfig
|
&& bash -e /tmp/video2x/video2x/src/video2x_setup_ubuntu.sh /
|
||||||
ENV FFMPEG_VERSION 4.1.2
|
|
||||||
|
|
||||||
# Install apt-fast, because we got gigs to download.
|
WORKDIR /video2x/src
|
||||||
RUN apt-get update && apt-get install -y apt-utils &&\
|
ENTRYPOINT ["python3.8", "/video2x/src/video2x.py"]
|
||||||
apt-get install -y --no-install-recommends software-properties-common &&\
|
|
||||||
add-apt-repository ppa:apt-fast/stable &&\
|
|
||||||
add-apt-repository -y ppa:graphics-drivers/ppa &&\
|
|
||||||
apt-get install -y --no-install-recommends apt-fast && apt-fast update
|
|
||||||
|
|
||||||
# Install dependencies
|
|
||||||
RUN apt-fast install -y --no-install-recommends autoconf ca-certificates curl ffmpeg frei0r-plugins-dev g++ gcc git-core gnupg2 gnutls-dev ladspa-sdk libass-dev libass-dev libbluray-dev libc6-dev libcaca-dev libcdio-paranoia-dev libchromaprint-dev libcodec2-dev libfdk-aac-dev libfdk-aac-dev libfontconfig1-dev libfreetype6-dev libfreetype6-dev libfreetype6-dev libfribidi-dev libgme-dev libgnutls28-dev libgsm1-dev libjack-dev libjack-dev liblilv-dev libmagic-dev libmagic1 libmodplug-dev libmp3lame-dev libmp3lame-dev libmysofa-dev libnuma-dev libopenal-dev libopencore-amrnb-dev libopencore-amrwb-dev libopenjp2-7-dev libopenmpt-dev libopus-dev libopus-dev libpulse-dev librsvg2-dev librtmp-dev librubberband-dev libsdl2-dev libsdl2-dev libshine-dev libsmbclient-dev libsnappy-dev libsoxr-dev libspeex-dev libssh-dev libtesseract-dev libtheora-dev libtool libtwolame-dev libv4l-dev libva-dev libva-dev libvdpau-dev libvdpau-dev libvo-amrwbenc-dev libvorbis-dev libvorbis-dev libvorbis-dev libvpx-dev libvpx-dev libwavpack-dev libwebp-dev libx264-dev libx264-dev libx265-dev libx265-dev libxcb-shm0-dev libxcb-shm0-dev libxcb-xfixes0-dev libxcb-xfixes0-dev libxcb1-dev libxcb1-dev libxml2-dev libxvidcore-dev libzmq3-dev libzvbi-dev nvidia-cuda-toolkit nvidia-driver-440 opencl-dev p11-kit pkg-config pkg-config python3-dev python3-pip python3-setuptools python3-wheel python3.8 texinfo texinfo wget wget yasm zlib1g-dev zlib1g-dev
|
|
||||||
|
|
||||||
# Install NASM
|
|
||||||
RUN curl -vfsSLO https://www.nasm.us/pub/nasm/releasebuilds/$NASM_VERSION/nasm-$NASM_VERSION.tar.bz2 \
|
|
||||||
&& tar -xjf nasm-$NASM_VERSION.tar.bz2 \
|
|
||||||
&& cd nasm-$NASM_VERSION \
|
|
||||||
&& ./autogen.sh \
|
|
||||||
&& ./configure \
|
|
||||||
&& make -j$(nproc) \
|
|
||||||
&& make install
|
|
||||||
|
|
||||||
# Compile FFmpeg with CUDA support
|
|
||||||
|
|
||||||
RUN git clone --recurse-submodules -b n$NVCODEC_VERSION --depth 1 https://git.videolan.org/git/ffmpeg/nv-codec-headers \
|
|
||||||
&& cd nv-codec-headers \
|
|
||||||
&& make install
|
|
||||||
|
|
||||||
RUN curl -vfsSLO https://ffmpeg.org/releases/ffmpeg-$FFMPEG_VERSION.tar.bz2 \
|
|
||||||
&& tar -xjf ffmpeg-$FFMPEG_VERSION.tar.bz2 \
|
|
||||||
&& cd ffmpeg-$FFMPEG_VERSION \
|
|
||||||
&& ./configure --enable-cuda-sdk --enable-cuvid --enable-nonfree --enable-libnpp --enable-nvenc \
|
|
||||||
--enable-gpl --enable-version3 \
|
|
||||||
--enable-small --enable-avisynth --enable-chromaprint \
|
|
||||||
--enable-frei0r --enable-gmp --enable-gnutls --enable-ladspa \
|
|
||||||
--enable-libass --enable-libcaca --enable-libcdio \
|
|
||||||
--enable-libcodec2 --enable-libfontconfig --enable-libfreetype \
|
|
||||||
--enable-libfribidi --enable-libgme --enable-libgsm --enable-libjack \
|
|
||||||
--enable-libmodplug --enable-libmp3lame --enable-libopencore-amrnb \
|
|
||||||
--enable-libopencore-amrwb --enable-libopencore-amrwb \
|
|
||||||
--enable-libopenjpeg --enable-libopenmpt --enable-libopus --enable-libpulse \
|
|
||||||
--enable-librsvg --enable-librubberband --enable-librtmp --enable-libshine \
|
|
||||||
--enable-libsnappy --enable-libsoxr --enable-libspeex \
|
|
||||||
--enable-libssh --enable-libtesseract --enable-libtheora \
|
|
||||||
--enable-libtwolame --enable-libv4l2 --enable-libvo-amrwbenc \
|
|
||||||
--enable-libvorbis --enable-libvpx --enable-libwavpack --enable-libwebp \
|
|
||||||
--enable-libx264 --enable-libx265 --enable-libxvid --enable-libxml2 \
|
|
||||||
--enable-libzmq --enable-libzvbi --enable-lv2 \
|
|
||||||
--enable-libmysofa \
|
|
||||||
--enable-openal --enable-opencl --enable-opengl --enable-libdrm \
|
|
||||||
--enable-libfdk-aac --enable-libbluray \
|
|
||||||
&& make -j$(nproc) \
|
|
||||||
&& make install
|
|
||||||
|
|
||||||
# Add Nvidia's machine-learning repository for libcudnn7 and libcudnn7-dev
|
|
||||||
RUN curl -fsSL https://developer.download.nvidia.com/compute/cuda/repos/ubuntu1804/x86_64/7fa2af80.pub | apt-key add - &&\
|
|
||||||
echo "deb https://developer.download.nvidia.com/compute/machine-learning/repos/ubuntu1804/x86_64 /" > /etc/apt/sources.list.d/nvidia-ml.list
|
|
||||||
|
|
||||||
# Install Video2X
|
|
||||||
RUN update-alternatives --install /usr/bin/python3 python3 /usr/bin/python3.7 1 && update-alternatives --install /usr/bin/python3 python3 /usr/bin/python3.8 2
|
|
||||||
RUN cd / && python3.8 -m pip install --upgrade pip &&\
|
|
||||||
git clone --recurse-submodules --progress https://github.com/k4yt3x/video2x.git --depth=1 &&\
|
|
||||||
python3.8 -m pip install -U -r video2x/src/requirements.txt
|
|
||||||
|
|
||||||
# Compile drivers
|
|
||||||
|
|
||||||
# example: docker build -t video2x . --build-arg driver=waifu2x_ncnn_vulkan
|
|
||||||
ARG driver=all
|
|
||||||
|
|
||||||
# Check if driver exists.
|
|
||||||
SHELL ["/bin/bash", "-c"]
|
|
||||||
RUN drivers=(all waifu2x_caffe waifu2x_converter waifu2x_ncnn_vulkan) &&\
|
|
||||||
case ${drivers[@]} in (*${driver,,}*) true ;; (*)\
|
|
||||||
echo "ERROR: Unrecognized driver." >&2 &&\
|
|
||||||
printf "%s " "Choices are: ${drivers[@]}" >&2 | printf "\n" >&2 &&\
|
|
||||||
exit 1 ;;\
|
|
||||||
esac
|
|
||||||
|
|
||||||
RUN if [ "$driver" = "all" ] || [ "$driver" = "waifu2x_caffe" ] ; then \
|
|
||||||
# nagadomi/caffe prerequisites
|
|
||||||
apt-fast update &&\
|
|
||||||
apt-fast install -y --no-install-recommends build-essential cmake libboost-system-dev libboost-thread-dev libboost-filesystem-dev libboost-chrono-dev libboost-date-time-dev libboost-atomic-dev libboost-python-dev libprotobuf-dev protobuf-compiler libhdf5-dev liblmdb-dev libleveldb-dev libsnappy-dev libopencv-dev libatlas-base-dev python-numpy libgflags-dev libgoogle-glog-dev &&\
|
|
||||||
# nagadomi/waifu2x-caffee-ubuntu prerequisites
|
|
||||||
apt-fast install -y --no-install-recommends libboost-iostreams-dev;\
|
|
||||||
fi
|
|
||||||
# build waifu2x-caffe && install caffe
|
|
||||||
RUN if [ "$driver" = "all" ] || [ "$driver" = "waifu2x_caffe" ] ; then \
|
|
||||||
git clone --recurse-submodules --depth=1 --progress --recurse-submodules https://github.com/nagadomi/waifu2x-caffe-ubuntu.git &&\
|
|
||||||
cd waifu2x-caffe-ubuntu &&\
|
|
||||||
git clone --recurse-submodules --progress --depth=1 https://github.com/nagadomi/caffe.git;\
|
|
||||||
fi
|
|
||||||
|
|
||||||
RUN if [ "$driver" = "all" ] || [ "$driver" = "waifu2x_caffe" ] ; then \
|
|
||||||
apt-fast install --no-install-recommends -y gcc-8 libcudnn7 libcudnn7-dev &&\
|
|
||||||
apt-get remove -y gcc g++ &&\
|
|
||||||
ln -s /usr/bin/gcc-8 /usr/bin/gcc && ln -s /usr/bin/g++-8 /usr/bin/g++ &&\
|
|
||||||
cd /waifu2x-caffe-ubuntu &&\
|
|
||||||
mkdir build &&\
|
|
||||||
cd build &&\
|
|
||||||
cmake .. -DCMAKE_INSTALL_PREFIX=/usr &&\
|
|
||||||
make -j$(nproc) install;\
|
|
||||||
fi
|
|
||||||
|
|
||||||
RUN if [ "$driver" = "all" ] || [ "$driver" = "waifu2x_caffe" ] ; then \
|
|
||||||
# install waifu2x-caffe
|
|
||||||
cd /waifu2x-caffe-ubuntu/build &&\
|
|
||||||
cp waifu2x-caffe ../bin/ &&\
|
|
||||||
mv ../bin tempname &&\
|
|
||||||
mv tempname /video2x/ &&\
|
|
||||||
mv /video2x/tempname /video2x/waifu2x-caffe &&\
|
|
||||||
rm -rf ../waifu2x-caffe-ubuntu ;\
|
|
||||||
fi
|
|
||||||
|
|
||||||
RUN if [ "$driver" = "all" ] || [ "$driver" = "waifu2x_ncnn_vulkan" ] ; then \
|
|
||||||
apt-fast install -y --no-install-recommends software-properties-common build-essential cmake libvulkan-dev glslang-tools libprotobuf-dev protobuf-compiler &&\
|
|
||||||
git clone --recurse-submodules --depth=1 --progress https://github.com/Tencent/ncnn.git &&\
|
|
||||||
cd ncnn &&\
|
|
||||||
mkdir -p build &&\
|
|
||||||
cd build &&\
|
|
||||||
cmake -DCMAKE_INSTALL_PREFIX=/usr -DNCNN_VULKAN=ON .. &&\
|
|
||||||
make -j$(nproc) install &&\
|
|
||||||
rm -rf ../../ncnn &&\
|
|
||||||
cd / &&\
|
|
||||||
# Compile waifu2x-ncnn-vulkan
|
|
||||||
git clone --recurse-submodules --depth=1 --progress https://github.com/nihui/waifu2x-ncnn-vulkan.git &&\
|
|
||||||
cd waifu2x-ncnn-vulkan &&\
|
|
||||||
mkdir -p build &&\
|
|
||||||
cd build &&\
|
|
||||||
cmake ../src &&\
|
|
||||||
make -j$(nproc) &&\
|
|
||||||
# Incall waifu2x-ncnn-vulkan
|
|
||||||
cd /waifu2x-ncnn-vulkan &&\
|
|
||||||
mkdir waifu2x-ncnn-vulkan &&\
|
|
||||||
mv models/models-cunet waifu2x-ncnn-vulkan/ &&\
|
|
||||||
mv build/waifu2x-ncnn-vulkan waifu2x-ncnn-vulkan/ &&\
|
|
||||||
mv waifu2x-ncnn-vulkan /video2x/ &&\
|
|
||||||
rm -rf ../waifu2x-ncnn-vulkan ;\
|
|
||||||
fi
|
|
||||||
|
|
||||||
RUN if [ "$driver" = "all" ] || [ "$driver" = "waifu2x_converter" ] ;\
|
|
||||||
then \
|
|
||||||
# Prerequisits for waifu2x-converter-cpp
|
|
||||||
apt-fast install -y --no-install-recommends build-essential cmake libopencv-dev ocl-icd-opencl-dev &&\
|
|
||||||
# Compile & Install
|
|
||||||
git clone --recurse-submodules --depth=1 --progress https://github.com/DeadSix27/waifu2x-converter-cpp &&\
|
|
||||||
cd waifu2x-converter-cpp &&\
|
|
||||||
mkdir build &&\
|
|
||||||
cd build &&\
|
|
||||||
cmake .. &&\
|
|
||||||
make -j$(nproc) &&\
|
|
||||||
#ldconfig &&\
|
|
||||||
cp -r ../models_rgb ./&&\
|
|
||||||
cd / ;\
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Go!
|
|
||||||
#COPY entrypoint.sh /
|
|
||||||
#ENTRYPOINT ["/entrypoint.sh"]
|
|
||||||
|
|
||||||
WORKDIR /host
|
|
||||||
ENTRYPOINT ["python3", "/video2x/src/video2x.py"]
|
|
||||||
|
|
||||||
ENV NVIDIA_DRIVER_CAPABILITIES all
|
ENV NVIDIA_DRIVER_CAPABILITIES all
|
||||||
# Docker image can ask questions now, if needed.
|
|
||||||
ENV DEBIAN_FRONTEND teletype
|
ENV DEBIAN_FRONTEND teletype
|
||||||
|
|||||||
@@ -14,19 +14,21 @@
|
|||||||
|
|
||||||
### Official Discussion Group (Telegram): https://t.me/video2x
|
### Official Discussion Group (Telegram): https://t.me/video2x
|
||||||
|
|
||||||
## [Download Stable/Beta Builds](https://github.com/k4yt3x/video2x/releases) (Windows)
|
## [Download Stable/Beta Builds](https://github.com/k4yt3x/video2x/releases/latest) (Windows)
|
||||||
|
|
||||||
- **`Full`**: full package comes pre-configured with **all** dependencies like `FFmpeg` and `waifu2x-caffe`.
|
- **`Full`**: full package comes pre-configured with **all** dependencies like `FFmpeg` and `waifu2x-caffe`.
|
||||||
- **`Light`**: ligt package comes with only Video2X binaries and a template configuration file. The user will either have to run the setup script or install and configure dependencies themselves.
|
- **`Light`**: ligt package comes with only Video2X binaries and a template configuration file. The user will either have to run the setup script or install and configure dependencies themselves.
|
||||||
|
|
||||||
Go to the **[Quick Start](#quick-start)** section for usages.
|
Go to the **[Quick Start](#quick-start)** section for usages.
|
||||||
|
|
||||||
### [Download From Mirror](https://files.k4yt3x.com/Projects/Video2X/)
|
### [Download From Mirror](https://files.k4yt3x.com/Projects/Video2X/latest)
|
||||||
|
|
||||||
In case you're unable to download the releases directly from GitHub, you can try downloading from the mirror site hosted by the author. Only releases will be updated in this directory, not nightly builds.
|
In case you're unable to download the releases directly from GitHub, you can try downloading from the mirror site hosted by the author. Only releases will be updated in this directory, not nightly builds.
|
||||||
|
|
||||||
## [Download Nightly Builds](https://github.com/k4yt3x/video2x/actions) (Windows)
|
## [Download Nightly Builds](https://github.com/k4yt3x/video2x/actions) (Windows)
|
||||||
|
|
||||||
|
**You need to be logged into GitHub to be able to download GitHub Actions artifacts.**
|
||||||
|
|
||||||
Nightly builds are built automatically every time a new commit is pushed to the master branch. The lates nightly build is always up-to-date with the latest version of the code, but is less stable and may contain bugs. Nightly builds are handled by GitHub's integrated CI/CD tool, GitHub Actions.
|
Nightly builds are built automatically every time a new commit is pushed to the master branch. The lates nightly build is always up-to-date with the latest version of the code, but is less stable and may contain bugs. Nightly builds are handled by GitHub's integrated CI/CD tool, GitHub Actions.
|
||||||
|
|
||||||
To download the latest nightly build, go to the [GitHub Actions](https://github.com/k4yt3x/video2x/actions) tab, enter the last run of workflow "Video2X Nightly Build, and download the artifacts generated from the run.
|
To download the latest nightly build, go to the [GitHub Actions](https://github.com/k4yt3x/video2x/actions) tab, enter the last run of workflow "Video2X Nightly Build, and download the artifacts generated from the run.
|
||||||
|
|||||||
0
src/bilogger.py
Normal file → Executable file
0
src/bilogger.py
Normal file → Executable file
0
src/build.ps1
Normal file → Executable file
0
src/build.ps1
Normal file → Executable file
@@ -2,9 +2,9 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
"""
|
"""
|
||||||
Name: Video2X Upscale Progress Monitor
|
Name: Video2X Upscale Progress Monitor
|
||||||
Author: BrianPetkovsek
|
Author: K4YT3X
|
||||||
Date Created: May 7, 2020
|
Date Created: May 7, 2020
|
||||||
Last Modified: May 10, 2020
|
Last Modified: June 7, 2020
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# built-in imports
|
# built-in imports
|
||||||
@@ -37,7 +37,7 @@ class ProgressMonitor(threading.Thread):
|
|||||||
# get number of extracted frames
|
# get number of extracted frames
|
||||||
self.upscaler.total_frames = 0
|
self.upscaler.total_frames = 0
|
||||||
for directory in self.extracted_frames_directories:
|
for directory in self.extracted_frames_directories:
|
||||||
self.upscaler.total_frames += len([f for f in directory.iterdir() if str(f).lower().endswith(self.upscaler.image_format.lower())])
|
self.upscaler.total_frames += len([f for f in directory.iterdir() if str(f).lower().endswith(self.upscaler.extracted_frame_format.lower())])
|
||||||
|
|
||||||
with tqdm(total=self.upscaler.total_frames, ascii=True, desc=_('Upscaling Progress')) as progress_bar:
|
with tqdm(total=self.upscaler.total_frames, ascii=True, desc=_('Upscaling Progress')) as progress_bar:
|
||||||
# tqdm update method adds the value to the progress
|
# tqdm update method adds the value to the progress
|
||||||
@@ -47,7 +47,7 @@ class ProgressMonitor(threading.Thread):
|
|||||||
while self.running:
|
while self.running:
|
||||||
|
|
||||||
with contextlib.suppress(FileNotFoundError):
|
with contextlib.suppress(FileNotFoundError):
|
||||||
upscaled_frames = [f for f in self.upscaler.upscaled_frames.iterdir() if str(f).lower().endswith(self.upscaler.image_format.lower())]
|
upscaled_frames = [f for f in self.upscaler.upscaled_frames.iterdir() if str(f).lower().endswith(self.upscaler.extracted_frame_format.lower())]
|
||||||
if len(upscaled_frames) >= 1:
|
if len(upscaled_frames) >= 1:
|
||||||
self.upscaler.last_frame_upscaled = sorted(upscaled_frames)[-1]
|
self.upscaler.last_frame_upscaled = sorted(upscaled_frames)[-1]
|
||||||
self.upscaler.total_frames_upscaled = len(upscaled_frames)
|
self.upscaler.total_frames_upscaled = len(upscaled_frames)
|
||||||
|
|||||||
182
src/upscaler.py
182
src/upscaler.py
@@ -4,7 +4,7 @@
|
|||||||
Name: Video2X Upscaler
|
Name: Video2X Upscaler
|
||||||
Author: K4YT3X
|
Author: K4YT3X
|
||||||
Date Created: December 10, 2018
|
Date Created: December 10, 2018
|
||||||
Last Modified: June 4, 2020
|
Last Modified: June 8, 2020
|
||||||
|
|
||||||
Description: This file contains the Upscaler class. Each
|
Description: This file contains the Upscaler class. Each
|
||||||
instance of the Upscaler class is an upscaler on an image or
|
instance of the Upscaler class is an upscaler on an image or
|
||||||
@@ -50,7 +50,7 @@ language.install()
|
|||||||
_ = language.gettext
|
_ = language.gettext
|
||||||
|
|
||||||
# version information
|
# version information
|
||||||
UPSCALER_VERSION = '4.2.1'
|
UPSCALER_VERSION = '4.2.2'
|
||||||
|
|
||||||
# these names are consistent for
|
# these names are consistent for
|
||||||
# - driver selection in command line
|
# - driver selection in command line
|
||||||
@@ -73,21 +73,39 @@ class Upscaler:
|
|||||||
ArgumentError -- if argument is not valid
|
ArgumentError -- if argument is not valid
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, input_path, output_path, driver_settings, ffmpeg_settings, gifski_settings):
|
def __init__(
|
||||||
# mandatory arguments
|
self,
|
||||||
|
input_path: pathlib.Path or list,
|
||||||
|
output_path: pathlib.Path,
|
||||||
|
driver_settings: dict,
|
||||||
|
ffmpeg_settings: dict,
|
||||||
|
gifski_settings: dict,
|
||||||
|
driver: str = 'waifu2x_caffe',
|
||||||
|
scale_ratio: float = None,
|
||||||
|
processes: int = 1,
|
||||||
|
video2x_cache_directory: pathlib.Path = pathlib.Path(tempfile.gettempdir()) / 'video2x',
|
||||||
|
extracted_frame_format: str = 'png',
|
||||||
|
image_output_extension: str = '.png',
|
||||||
|
video_output_extension: str = '.mp4',
|
||||||
|
preserve_frames: bool = False
|
||||||
|
):
|
||||||
|
|
||||||
|
# required parameters
|
||||||
self.input = input_path
|
self.input = input_path
|
||||||
self.output = output_path
|
self.output = output_path
|
||||||
self.driver_settings = driver_settings
|
self.driver_settings = driver_settings
|
||||||
self.ffmpeg_settings = ffmpeg_settings
|
self.ffmpeg_settings = ffmpeg_settings
|
||||||
self.gifski_settings = gifski_settings
|
self.gifski_settings = gifski_settings
|
||||||
|
|
||||||
# optional arguments
|
# optional parameters
|
||||||
self.driver = 'waifu2x_caffe'
|
self.driver = driver
|
||||||
self.scale_ratio = None
|
self.scale_ratio = scale_ratio
|
||||||
self.processes = 1
|
self.processes = processes
|
||||||
self.video2x_cache_directory = pathlib.Path(tempfile.gettempdir()) / 'video2x'
|
self.video2x_cache_directory = video2x_cache_directory
|
||||||
self.image_format = 'png'
|
self.extracted_frame_format = extracted_frame_format
|
||||||
self.preserve_frames = False
|
self.image_output_extension = image_output_extension
|
||||||
|
self.video_output_extension = video_output_extension
|
||||||
|
self.preserve_frames = preserve_frames
|
||||||
|
|
||||||
# other internal members and signals
|
# other internal members and signals
|
||||||
self.running = False
|
self.running = False
|
||||||
@@ -234,7 +252,7 @@ class Upscaler:
|
|||||||
if self.driver == 'waifu2x_caffe':
|
if self.driver == 'waifu2x_caffe':
|
||||||
if (driver_settings['scale_width'] != 0 and driver_settings['scale_height'] == 0 or
|
if (driver_settings['scale_width'] != 0 and driver_settings['scale_height'] == 0 or
|
||||||
driver_settings['scale_width'] == 0 and driver_settings['scale_height'] != 0):
|
driver_settings['scale_width'] == 0 and driver_settings['scale_height'] != 0):
|
||||||
Avalon.error('Only one of scale_width and scale_height is specified for waifu2x-caffe')
|
Avalon.error(_('Only one of scale_width and scale_height is specified for waifu2x-caffe'))
|
||||||
raise AttributeError('only one of scale_width and scale_height is specified for waifu2x-caffe')
|
raise AttributeError('only one of scale_width and scale_height is specified for waifu2x-caffe')
|
||||||
|
|
||||||
# if scale_width and scale_height are specified, ensure scale_ratio is None
|
# if scale_width and scale_height are specified, ensure scale_ratio is None
|
||||||
@@ -324,8 +342,8 @@ class Upscaler:
|
|||||||
# images need to be renamed to be recognizable for FFmpeg
|
# images need to be renamed to be recognizable for FFmpeg
|
||||||
if self.driver == 'waifu2x_converter_cpp':
|
if self.driver == 'waifu2x_converter_cpp':
|
||||||
for image in [f for f in self.upscaled_frames.iterdir() if f.is_file()]:
|
for image in [f for f in self.upscaled_frames.iterdir() if f.is_file()]:
|
||||||
renamed = re.sub(f'_\\[.*\\]\\[x(\\d+(\\.\\d+)?)\\]\\.{self.image_format}',
|
renamed = re.sub(f'_\\[.*\\]\\[x(\\d+(\\.\\d+)?)\\]\\.{self.extracted_frame_format}',
|
||||||
f'.{self.image_format}',
|
f'.{self.extracted_frame_format}',
|
||||||
str(image.name))
|
str(image.name))
|
||||||
(self.upscaled_frames / image).rename(self.upscaled_frames / renamed)
|
(self.upscaled_frames / image).rename(self.upscaled_frames / renamed)
|
||||||
|
|
||||||
@@ -403,49 +421,93 @@ class Upscaler:
|
|||||||
self.driver_object.load_configurations(self)
|
self.driver_object.load_configurations(self)
|
||||||
|
|
||||||
# initialize FFmpeg object
|
# initialize FFmpeg object
|
||||||
self.ffmpeg_object = Ffmpeg(self.ffmpeg_settings, image_format=self.image_format)
|
self.ffmpeg_object = Ffmpeg(self.ffmpeg_settings, extracted_frame_format=self.extracted_frame_format)
|
||||||
|
|
||||||
# define processing queue
|
# define processing queue
|
||||||
self.processing_queue = queue.Queue()
|
self.processing_queue = queue.Queue()
|
||||||
|
|
||||||
Avalon.info(_('Loading files into processing queue'))
|
Avalon.info(_('Loading files into processing queue'))
|
||||||
|
Avalon.debug_info(_('Input path(s): {}').format(self.input))
|
||||||
|
|
||||||
# if input is a list of files
|
# make output directory if the input is a list or a directory
|
||||||
if isinstance(self.input, list):
|
if isinstance(self.input, list) or self.input.is_dir():
|
||||||
|
|
||||||
Avalon.info(_('Loading files from multiple paths'))
|
|
||||||
Avalon.debug_info(_('Input path(s): {}').format(self.input))
|
|
||||||
|
|
||||||
# make output directory if it doesn't exist
|
|
||||||
self.output.mkdir(parents=True, exist_ok=True)
|
self.output.mkdir(parents=True, exist_ok=True)
|
||||||
|
|
||||||
for input_path in self.input:
|
input_files = []
|
||||||
|
|
||||||
if input_path.is_file():
|
# if input is single directory
|
||||||
output_path = self.output / input_path.name
|
# put it in a list for compability with the following code
|
||||||
self.processing_queue.put((input_path.absolute(), output_path.absolute()))
|
if not isinstance(self.input, list):
|
||||||
|
input_paths = [self.input]
|
||||||
|
else:
|
||||||
|
input_paths = self.input
|
||||||
|
|
||||||
elif input_path.is_dir():
|
# flatten directories into file paths
|
||||||
for input_path in [f for f in input_path.iterdir() if f.is_file()]:
|
for input_path in input_paths:
|
||||||
output_path = self.output / input_path.name
|
|
||||||
self.processing_queue.put((input_path.absolute(), output_path.absolute()))
|
|
||||||
|
|
||||||
# if input specified is single file
|
# if the input path is a single file
|
||||||
elif self.input.is_file():
|
# add the file's path object to input_files
|
||||||
Avalon.info(_('Loading single file'))
|
if input_path.is_file():
|
||||||
Avalon.debug_info(_('Input path(s): {}').format(self.input))
|
input_files.append(input_path)
|
||||||
self.processing_queue.put((self.input.absolute(), self.output.absolute()))
|
|
||||||
|
|
||||||
# if input specified is a directory
|
# if the input path is a directory
|
||||||
elif self.input.is_dir():
|
# add all files under the directory into the input_files (non-recursive)
|
||||||
|
elif input_path.is_dir():
|
||||||
|
input_files.extend([f for f in input_path.iterdir() if f.is_file()])
|
||||||
|
|
||||||
Avalon.info(_('Loading files from directory'))
|
output_paths = []
|
||||||
Avalon.debug_info(_('Input path(s): {}').format(self.input))
|
|
||||||
# make output directory if it doesn't exist
|
for input_path in input_files:
|
||||||
self.output.mkdir(parents=True, exist_ok=True)
|
|
||||||
for input_path in [f for f in self.input.iterdir() if f.is_file()]:
|
# get file type
|
||||||
output_path = self.output / input_path.name
|
# try python-magic if it's available
|
||||||
self.processing_queue.put((input_path.absolute(), output_path.absolute()))
|
try:
|
||||||
|
input_file_mime_type = magic.from_file(str(input_path.absolute()), mime=True)
|
||||||
|
input_file_type = input_file_mime_type.split('/')[0]
|
||||||
|
input_file_subtype = input_file_mime_type.split('/')[1]
|
||||||
|
except Exception:
|
||||||
|
input_file_type = input_file_subtype = None
|
||||||
|
|
||||||
|
# in case python-magic fails to detect file type
|
||||||
|
# try guessing file mime type with mimetypes
|
||||||
|
if input_file_type not in ['image', 'video']:
|
||||||
|
input_file_mime_type = mimetypes.guess_type(input_path.name)[0]
|
||||||
|
input_file_type = input_file_mime_type.split('/')[0]
|
||||||
|
input_file_subtype = input_file_mime_type.split('/')[1]
|
||||||
|
|
||||||
|
# set default output file suffixes
|
||||||
|
# if image type is GIF, default output suffix is also .gif
|
||||||
|
if input_file_mime_type == 'image/gif':
|
||||||
|
output_path = self.output / (input_path.stem + '.gif')
|
||||||
|
|
||||||
|
elif input_file_type == 'image':
|
||||||
|
output_path = self.output / (input_path.stem + self.image_output_extension)
|
||||||
|
|
||||||
|
elif input_file_type == 'video':
|
||||||
|
output_path = self.output / (input_path.stem + self.video_output_extension)
|
||||||
|
|
||||||
|
# if file is none of: image, image/gif, video
|
||||||
|
# skip to the next task
|
||||||
|
else:
|
||||||
|
Avalon.error(_('File {} ({}) neither an image nor a video').format(input_path, input_file_mime_type))
|
||||||
|
Avalon.warning(_('Skipping this file'))
|
||||||
|
continue
|
||||||
|
|
||||||
|
# if there is only one input file
|
||||||
|
# do not modify output file suffix
|
||||||
|
if isinstance(self.input, pathlib.Path) and self.input.is_file():
|
||||||
|
output_path = self.output
|
||||||
|
|
||||||
|
output_path_id = 0
|
||||||
|
while str(output_path) in output_paths:
|
||||||
|
output_path = output_path.parent / pathlib.Path(f'{output_path.stem}_{output_path_id}{output_path.suffix}')
|
||||||
|
output_path_id += 1
|
||||||
|
|
||||||
|
# record output path
|
||||||
|
output_paths.append(str(output_path))
|
||||||
|
|
||||||
|
# push file information into processing queue
|
||||||
|
self.processing_queue.put((input_path.absolute(), output_path.absolute(), input_file_mime_type, input_file_type, input_file_subtype))
|
||||||
|
|
||||||
# check argument sanity before running
|
# check argument sanity before running
|
||||||
self._check_arguments()
|
self._check_arguments()
|
||||||
@@ -461,27 +523,8 @@ class Upscaler:
|
|||||||
try:
|
try:
|
||||||
while not self.processing_queue.empty():
|
while not self.processing_queue.empty():
|
||||||
|
|
||||||
# reset current processing progress for new job
|
|
||||||
self.total_frames_upscaled = 0
|
|
||||||
self.total_frames = 0
|
|
||||||
|
|
||||||
# get new job from queue
|
# get new job from queue
|
||||||
self.current_input_file, output_path = self.processing_queue.get()
|
self.current_input_file, output_path, input_file_mime_type, input_file_type, input_file_subtype = self.processing_queue.get()
|
||||||
|
|
||||||
# get file type
|
|
||||||
try:
|
|
||||||
input_file_mime_type = magic.from_file(str(self.current_input_file.absolute()), mime=True)
|
|
||||||
input_file_type = input_file_mime_type.split('/')[0]
|
|
||||||
input_file_subtype = input_file_mime_type.split('/')[1]
|
|
||||||
except magic.magic.MagicException:
|
|
||||||
input_file_type = input_file_subtype = None
|
|
||||||
|
|
||||||
# in case python-magic fails to detect file type
|
|
||||||
# try guessing file mime type with mimetypes
|
|
||||||
if input_file_type not in ['image', 'video']:
|
|
||||||
input_file_mime_type = mimetypes.guess_type(self.current_input_file.name)[0]
|
|
||||||
input_file_type = input_file_mime_type.split('/')[0]
|
|
||||||
input_file_subtype = input_file_mime_type.split('/')[1]
|
|
||||||
|
|
||||||
# start handling input
|
# start handling input
|
||||||
# if input file is a static image
|
# if input file is a static image
|
||||||
@@ -553,15 +596,6 @@ class Upscaler:
|
|||||||
self._upscale_frames()
|
self._upscale_frames()
|
||||||
Avalon.info(_('Upscaling completed'))
|
Avalon.info(_('Upscaling completed'))
|
||||||
|
|
||||||
# if file is none of: image, image/gif, video
|
|
||||||
# skip to the next task
|
|
||||||
else:
|
|
||||||
Avalon.error(_('File {} ({}) neither an image nor a video').format(self.current_input_file, input_file_mime_type))
|
|
||||||
Avalon.warning(_('Skipping this file'))
|
|
||||||
self.processing_queue.task_done()
|
|
||||||
self.total_processed += 1
|
|
||||||
continue
|
|
||||||
|
|
||||||
# start handling output
|
# start handling output
|
||||||
# output can be either GIF or video
|
# output can be either GIF or video
|
||||||
|
|
||||||
@@ -569,7 +603,7 @@ class Upscaler:
|
|||||||
if output_path.suffix.lower() == '.gif':
|
if output_path.suffix.lower() == '.gif':
|
||||||
Avalon.info(_('Converting extracted frames into GIF image'))
|
Avalon.info(_('Converting extracted frames into GIF image'))
|
||||||
gifski_object = Gifski(self.gifski_settings)
|
gifski_object = Gifski(self.gifski_settings)
|
||||||
self.process_pool.append(gifski_object.make_gif(self.upscaled_frames, output_path, framerate, self.image_format))
|
self.process_pool.append(gifski_object.make_gif(self.upscaled_frames, output_path, framerate, self.extracted_frame_format))
|
||||||
self._wait()
|
self._wait()
|
||||||
Avalon.info(_('Conversion completed'))
|
Avalon.info(_('Conversion completed'))
|
||||||
|
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ __ __ _ _ ___ __ __
|
|||||||
Name: Video2X Controller
|
Name: Video2X Controller
|
||||||
Creator: K4YT3X
|
Creator: K4YT3X
|
||||||
Date Created: Feb 24, 2018
|
Date Created: Feb 24, 2018
|
||||||
Last Modified: June 4, 2020
|
Last Modified: June 8, 2020
|
||||||
|
|
||||||
Editor: BrianPetkovsek
|
Editor: BrianPetkovsek
|
||||||
Last Modified: June 17, 2019
|
Last Modified: June 17, 2019
|
||||||
@@ -81,7 +81,7 @@ language = gettext.translation(DOMAIN, LOCALE_DIRECTORY, [default_locale], fallb
|
|||||||
language.install()
|
language.install()
|
||||||
_ = language.gettext
|
_ = language.gettext
|
||||||
|
|
||||||
CLI_VERSION = '4.1.0'
|
CLI_VERSION = '4.1.1'
|
||||||
|
|
||||||
LEGAL_INFO = _('''Video2X CLI Version: {}
|
LEGAL_INFO = _('''Video2X CLI Version: {}
|
||||||
Upscaler Version: {}
|
Upscaler Version: {}
|
||||||
@@ -121,7 +121,7 @@ def parse_arguments():
|
|||||||
default=pathlib.Path(__file__).parent.absolute() / 'video2x.yaml')
|
default=pathlib.Path(__file__).parent.absolute() / 'video2x.yaml')
|
||||||
video2x_options.add_argument('--log', type=pathlib.Path, help=_('log file path'),
|
video2x_options.add_argument('--log', type=pathlib.Path, help=_('log file path'),
|
||||||
default=pathlib.Path(__file__).parent.absolute() / f'video2x_{datetime.datetime.now().strftime("%Y-%m-%d_%H-%M-%S")}.log')
|
default=pathlib.Path(__file__).parent.absolute() / f'video2x_{datetime.datetime.now().strftime("%Y-%m-%d_%H-%M-%S")}.log')
|
||||||
video2x_options.add_argument('--nolog', help=_('disable logging'), action='store_true')
|
video2x_options.add_argument('--disable_logging', help=_('disable logging'), action='store_true')
|
||||||
video2x_options.add_argument('-v', '--version', help=_('display version, lawful information and exit'), action='store_true')
|
video2x_options.add_argument('-v', '--version', help=_('display version, lawful information and exit'), action='store_true')
|
||||||
|
|
||||||
# scaling options
|
# scaling options
|
||||||
@@ -184,7 +184,7 @@ if video2x_args.version:
|
|||||||
sys.exit(0)
|
sys.exit(0)
|
||||||
|
|
||||||
# redirect output to both terminal and log file
|
# redirect output to both terminal and log file
|
||||||
if video2x_args.nolog is False:
|
if video2x_args.disable_logging is False:
|
||||||
LOGFILE = video2x_args.log
|
LOGFILE = video2x_args.log
|
||||||
Avalon.debug_info(_('Redirecting console logs to {}').format(LOGFILE))
|
Avalon.debug_info(_('Redirecting console logs to {}').format(LOGFILE))
|
||||||
sys.stdout = BiLogger(sys.stdout, LOGFILE)
|
sys.stdout = BiLogger(sys.stdout, LOGFILE)
|
||||||
@@ -206,7 +206,9 @@ gifski_settings = config['gifski']
|
|||||||
gifski_settings['gifski_path'] = os.path.expandvars(gifski_settings['gifski_path'])
|
gifski_settings['gifski_path'] = os.path.expandvars(gifski_settings['gifski_path'])
|
||||||
|
|
||||||
# load video2x settings
|
# load video2x settings
|
||||||
image_format = config['video2x']['image_format'].lower()
|
extracted_frame_format = config['video2x']['extracted_frame_format'].lower()
|
||||||
|
image_output_extension = config['video2x']['image_output_extension']
|
||||||
|
video_output_extension = config['video2x']['video_output_extension']
|
||||||
preserve_frames = config['video2x']['preserve_frames']
|
preserve_frames = config['video2x']['preserve_frames']
|
||||||
|
|
||||||
# if preserve frames specified in command line
|
# if preserve frames specified in command line
|
||||||
@@ -234,19 +236,24 @@ try:
|
|||||||
begin_time = time.time()
|
begin_time = time.time()
|
||||||
|
|
||||||
# initialize upscaler object
|
# initialize upscaler object
|
||||||
upscaler = Upscaler(input_path=video2x_args.input,
|
upscaler = Upscaler(
|
||||||
output_path=video2x_args.output,
|
# required parameters
|
||||||
driver_settings=driver_settings,
|
input_path=video2x_args.input,
|
||||||
ffmpeg_settings=ffmpeg_settings,
|
output_path=video2x_args.output,
|
||||||
gifski_settings=gifski_settings)
|
driver_settings=driver_settings,
|
||||||
|
ffmpeg_settings=ffmpeg_settings,
|
||||||
|
gifski_settings=gifski_settings,
|
||||||
|
|
||||||
# set upscaler optional options
|
# optional parameters
|
||||||
upscaler.driver = video2x_args.driver
|
driver=video2x_args.driver,
|
||||||
upscaler.scale_ratio = video2x_args.ratio
|
scale_ratio=video2x_args.ratio,
|
||||||
upscaler.processes = video2x_args.processes
|
processes=video2x_args.processes,
|
||||||
upscaler.video2x_cache_directory = video2x_cache_directory
|
video2x_cache_directory=video2x_cache_directory,
|
||||||
upscaler.image_format = image_format
|
extracted_frame_format=extracted_frame_format,
|
||||||
upscaler.preserve_frames = preserve_frames
|
image_output_extension=image_output_extension,
|
||||||
|
video_output_extension=video_output_extension,
|
||||||
|
preserve_frames=preserve_frames
|
||||||
|
)
|
||||||
|
|
||||||
# run upscaler
|
# run upscaler
|
||||||
upscaler.run()
|
upscaler.run()
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
# Name: Video2X Configuration File
|
# Name: Video2X Configuration File
|
||||||
# Creator: K4YT3X
|
# Creator: K4YT3X
|
||||||
# Date Created: October 23, 2018
|
# Date Created: October 23, 2018
|
||||||
# Last Modified: May 29, 2020
|
# Last Modified: June 7, 2020
|
||||||
# Values here are the default values. Change the value here to
|
# Values here are the default values. Change the value here to
|
||||||
# save the default value permanently.
|
# save the default value permanently.
|
||||||
# Items commented out are parameters irrelevant to this context
|
# Items commented out are parameters irrelevant to this context
|
||||||
@@ -100,11 +100,12 @@ anime4kcpp:
|
|||||||
fastMode: false # Faster but maybe low quality
|
fastMode: false # Faster but maybe low quality
|
||||||
videoMode: false # Video process
|
videoMode: false # Video process
|
||||||
preview: null # Preview image
|
preview: null # Preview image
|
||||||
preprocessing: False # Enable pre processing
|
preprocessing: false # Enable pre processing
|
||||||
postprocessing: False # Enable post processing
|
postprocessing: false # Enable post processing
|
||||||
preFilters: 4 # Enhancement filter, only working when preProcessing is true,there are 5 options by binary:Median blur=0000001, Mean blur=0000010, CAS Sharpening=0000100, Gaussian blur weak=0001000, Gaussian blur=0010000, Bilateral filter=0100000, Bilateral filter faster=1000000, you can freely combine them, eg: Gaussian blur weak + Bilateral filter = 0001000 | 0100000 = 0101000 = 40(D) (unsigned int [=4])
|
preFilters: 4 # Enhancement filter, only working when preProcessing is true,there are 5 options by binary:Median blur=0000001, Mean blur=0000010, CAS Sharpening=0000100, Gaussian blur weak=0001000, Gaussian blur=0010000, Bilateral filter=0100000, Bilateral filter faster=1000000, you can freely combine them, eg: Gaussian blur weak + Bilateral filter = 0001000 | 0100000 = 0101000 = 40(D) (unsigned int [=4])
|
||||||
postFilters: 40 # Enhancement filter, only working when postProcessing is true,there are 5 options by binary:Median blur=0000001, Mean blur=0000010, CAS Sharpening=0000100, Gaussian blur weak=0001000, Gaussian blur=0010000, Bilateral filter=0100000, Bilateral filter faster=1000000, you can freely combine them, eg: Gaussian blur weak + Bilateral filter = 0001000 | 0100000 = 0101000 = 40(D), so you can put 40 to enable Gaussian blur weak and Bilateral filter, which also is what I recommend for image that < 1080P, 48 for image that >= 1080P, and for performance I recommend to use 72 for video that < 1080P, 80 for video that >=1080P (unsigned int [=40])
|
postFilters: 40 # Enhancement filter, only working when postProcessing is true,there are 5 options by binary:Median blur=0000001, Mean blur=0000010, CAS Sharpening=0000100, Gaussian blur weak=0001000, Gaussian blur=0010000, Bilateral filter=0100000, Bilateral filter faster=1000000, you can freely combine them, eg: Gaussian blur weak + Bilateral filter = 0001000 | 0100000 = 0101000 = 40(D), so you can put 40 to enable Gaussian blur weak and Bilateral filter, which also is what I recommend for image that < 1080P, 48 for image that >= 1080P, and for performance I recommend to use 72 for video that < 1080P, 80 for video that >=1080P (unsigned int [=40])
|
||||||
GPUMode: False # Enable GPU acceleration
|
GPUMode: false # Enable GPU acceleration
|
||||||
|
CNNMode: false # Enable ACNet
|
||||||
listGPUs: null # list GPUs
|
listGPUs: null # list GPUs
|
||||||
platformID: 0 # Specify the platform ID (unsigned int [=0])
|
platformID: 0 # Specify the platform ID (unsigned int [=0])
|
||||||
deviceID: 0 # Specify the device ID (unsigned int [=0])
|
deviceID: 0 # Specify the device ID (unsigned int [=0])
|
||||||
@@ -168,5 +169,7 @@ gifski:
|
|||||||
quiet: false # Do not show a progress bar
|
quiet: false # Do not show a progress bar
|
||||||
video2x:
|
video2x:
|
||||||
video2x_cache_directory: null # default: %TEMP%\video2x, directory where cache files are stored, will be deleted if preserve_frames is not set to true
|
video2x_cache_directory: null # default: %TEMP%\video2x, directory where cache files are stored, will be deleted if preserve_frames is not set to true
|
||||||
image_format: png # png/jpg intermediate file format used for extracted frames during video processing
|
extracted_frame_format: png # png/jpg intermediate file format used for extracted frames during video processing
|
||||||
|
image_output_extension: .png # image output extension during batch processing
|
||||||
|
video_output_extension: .mp4 # video output extension during batch processing
|
||||||
preserve_frames: false # if set to true, the cache directory won't be cleaned upon task completion
|
preserve_frames: false # if set to true, the cache directory won't be cleaned upon task completion
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
Creator: Video2X GUI
|
Creator: Video2X GUI
|
||||||
Author: K4YT3X
|
Author: K4YT3X
|
||||||
Date Created: May 5, 2020
|
Date Created: May 5, 2020
|
||||||
Last Modified: June 4, 2020
|
Last Modified: June 8, 2020
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# local imports
|
# local imports
|
||||||
@@ -34,7 +34,7 @@ from PyQt5.QtGui import *
|
|||||||
from PyQt5.QtWidgets import *
|
from PyQt5.QtWidgets import *
|
||||||
import magic
|
import magic
|
||||||
|
|
||||||
GUI_VERSION = '2.6.0'
|
GUI_VERSION = '2.7.1'
|
||||||
|
|
||||||
LEGAL_INFO = f'''Video2X GUI Version: {GUI_VERSION}\\
|
LEGAL_INFO = f'''Video2X GUI Version: {GUI_VERSION}\\
|
||||||
Upscaler Version: {UPSCALER_VERSION}\\
|
Upscaler Version: {UPSCALER_VERSION}\\
|
||||||
@@ -137,7 +137,7 @@ class InputTableModel(QAbstractTableModel):
|
|||||||
input_file_mime_type = magic.from_file(str(file_path.absolute()), mime=True)
|
input_file_mime_type = magic.from_file(str(file_path.absolute()), mime=True)
|
||||||
input_file_type = input_file_mime_type.split('/')[0]
|
input_file_type = input_file_mime_type.split('/')[0]
|
||||||
input_file_subtype = input_file_mime_type.split('/')[1]
|
input_file_subtype = input_file_mime_type.split('/')[1]
|
||||||
except magic.magic.MagicException:
|
except Exception:
|
||||||
input_file_type = input_file_subtype = None
|
input_file_type = input_file_subtype = None
|
||||||
|
|
||||||
# in case python-magic fails to detect file type
|
# in case python-magic fails to detect file type
|
||||||
@@ -257,7 +257,12 @@ class Video2XMainWindow(QMainWindow):
|
|||||||
# config file
|
# config file
|
||||||
self.config_line_edit = self.findChild(QLineEdit, 'configLineEdit')
|
self.config_line_edit = self.findChild(QLineEdit, 'configLineEdit')
|
||||||
self.enable_line_edit_file_drop(self.config_line_edit)
|
self.enable_line_edit_file_drop(self.config_line_edit)
|
||||||
self.config_line_edit.setText(str((pathlib.Path(__file__).parent / 'video2x.yaml').absolute()))
|
|
||||||
|
if getattr(sys, 'frozen', False):
|
||||||
|
self.config_line_edit.setText(str((pathlib.Path(sys.executable).parent / 'video2x.yaml').absolute()))
|
||||||
|
elif __file__:
|
||||||
|
self.config_line_edit.setText(str((pathlib.Path(__file__).parent / 'video2x.yaml').absolute()))
|
||||||
|
|
||||||
self.config_select_file_button = self.findChild(QPushButton, 'configSelectButton')
|
self.config_select_file_button = self.findChild(QPushButton, 'configSelectButton')
|
||||||
self.config_select_file_button.clicked.connect(self.select_config_file)
|
self.config_select_file_button.clicked.connect(self.select_config_file)
|
||||||
|
|
||||||
@@ -272,7 +277,10 @@ class Video2XMainWindow(QMainWindow):
|
|||||||
self.driver_combo_box.currentTextChanged.connect(self.update_gui_for_driver)
|
self.driver_combo_box.currentTextChanged.connect(self.update_gui_for_driver)
|
||||||
self.processes_spin_box = self.findChild(QSpinBox, 'processesSpinBox')
|
self.processes_spin_box = self.findChild(QSpinBox, 'processesSpinBox')
|
||||||
self.scale_ratio_double_spin_box = self.findChild(QDoubleSpinBox, 'scaleRatioDoubleSpinBox')
|
self.scale_ratio_double_spin_box = self.findChild(QDoubleSpinBox, 'scaleRatioDoubleSpinBox')
|
||||||
|
self.image_output_extension_line_edit = self.findChild(QLineEdit, 'imageOutputExtensionLineEdit')
|
||||||
|
self.video_output_extension_line_edit = self.findChild(QLineEdit, 'videoOutputExtensionLineEdit')
|
||||||
self.preserve_frames_check_box = self.findChild(QCheckBox, 'preserveFramesCheckBox')
|
self.preserve_frames_check_box = self.findChild(QCheckBox, 'preserveFramesCheckBox')
|
||||||
|
self.disable_logging_check_box = self.findChild(QCheckBox, 'disableLoggingCheckBox')
|
||||||
|
|
||||||
# frame preview
|
# frame preview
|
||||||
self.frame_preview_show_preview_check_box = self.findChild(QCheckBox, 'framePreviewShowPreviewCheckBox')
|
self.frame_preview_show_preview_check_box = self.findChild(QCheckBox, 'framePreviewShowPreviewCheckBox')
|
||||||
@@ -385,6 +393,7 @@ class Video2XMainWindow(QMainWindow):
|
|||||||
self.anime4kcpp_pre_processing_check_box = self.findChild(QCheckBox, 'anime4kCppPreProcessingCheckBox')
|
self.anime4kcpp_pre_processing_check_box = self.findChild(QCheckBox, 'anime4kCppPreProcessingCheckBox')
|
||||||
self.anime4kcpp_post_processing_check_box = self.findChild(QCheckBox, 'anime4kCppPostProcessingCheckBox')
|
self.anime4kcpp_post_processing_check_box = self.findChild(QCheckBox, 'anime4kCppPostProcessingCheckBox')
|
||||||
self.anime4kcpp_gpu_mode_check_box = self.findChild(QCheckBox, 'anime4kCppGpuModeCheckBox')
|
self.anime4kcpp_gpu_mode_check_box = self.findChild(QCheckBox, 'anime4kCppGpuModeCheckBox')
|
||||||
|
self.anime4kcpp_cnn_mode_check_box = self.findChild(QCheckBox, 'anime4kCppCnnModeCheckBox')
|
||||||
|
|
||||||
# FFmpeg settings
|
# FFmpeg settings
|
||||||
# global options
|
# global options
|
||||||
@@ -466,6 +475,9 @@ class Video2XMainWindow(QMainWindow):
|
|||||||
self.config['video2x']['video2x_cache_directory'] = str((pathlib.Path(tempfile.gettempdir()) / 'video2x').absolute())
|
self.config['video2x']['video2x_cache_directory'] = str((pathlib.Path(tempfile.gettempdir()) / 'video2x').absolute())
|
||||||
self.cache_line_edit.setText(self.config['video2x']['video2x_cache_directory'])
|
self.cache_line_edit.setText(self.config['video2x']['video2x_cache_directory'])
|
||||||
|
|
||||||
|
self.image_output_extension_line_edit.setText(self.config['video2x']['image_output_extension'])
|
||||||
|
self.video_output_extension_line_edit.setText(self.config['video2x']['video_output_extension'])
|
||||||
|
|
||||||
# load preserve frames settings
|
# load preserve frames settings
|
||||||
self.preserve_frames_check_box.setChecked(self.config['video2x']['preserve_frames'])
|
self.preserve_frames_check_box.setChecked(self.config['video2x']['preserve_frames'])
|
||||||
self.start_button.setEnabled(True)
|
self.start_button.setEnabled(True)
|
||||||
@@ -542,6 +554,7 @@ class Video2XMainWindow(QMainWindow):
|
|||||||
self.anime4kcpp_pre_processing_check_box.setChecked(settings['preprocessing'])
|
self.anime4kcpp_pre_processing_check_box.setChecked(settings['preprocessing'])
|
||||||
self.anime4kcpp_post_processing_check_box.setChecked(settings['postprocessing'])
|
self.anime4kcpp_post_processing_check_box.setChecked(settings['postprocessing'])
|
||||||
self.anime4kcpp_gpu_mode_check_box.setChecked(settings['GPUMode'])
|
self.anime4kcpp_gpu_mode_check_box.setChecked(settings['GPUMode'])
|
||||||
|
self.anime4kcpp_cnn_mode_check_box.setChecked(settings['CNNMode'])
|
||||||
|
|
||||||
# ffmpeg
|
# ffmpeg
|
||||||
# global options
|
# global options
|
||||||
@@ -650,6 +663,7 @@ class Video2XMainWindow(QMainWindow):
|
|||||||
self.config['anime4kcpp']['preprocessing'] = bool(self.anime4kcpp_pre_processing_check_box.isChecked())
|
self.config['anime4kcpp']['preprocessing'] = bool(self.anime4kcpp_pre_processing_check_box.isChecked())
|
||||||
self.config['anime4kcpp']['postprocessing'] = bool(self.anime4kcpp_post_processing_check_box.isChecked())
|
self.config['anime4kcpp']['postprocessing'] = bool(self.anime4kcpp_post_processing_check_box.isChecked())
|
||||||
self.config['anime4kcpp']['GPUMode'] = bool(self.anime4kcpp_gpu_mode_check_box.isChecked())
|
self.config['anime4kcpp']['GPUMode'] = bool(self.anime4kcpp_gpu_mode_check_box.isChecked())
|
||||||
|
self.config['anime4kcpp']['CNNMode'] = bool(self.anime4kcpp_cnn_mode_check_box.isChecked())
|
||||||
|
|
||||||
# ffmpeg
|
# ffmpeg
|
||||||
self.config['ffmpeg']['ffmpeg_path'] = os.path.expandvars(self.ffmpeg_path_line_edit.text())
|
self.config['ffmpeg']['ffmpeg_path'] = os.path.expandvars(self.ffmpeg_path_line_edit.text())
|
||||||
@@ -899,7 +913,7 @@ class Video2XMainWindow(QMainWindow):
|
|||||||
input_file_mime_type = magic.from_file(str(input_path.absolute()), mime=True)
|
input_file_mime_type = magic.from_file(str(input_path.absolute()), mime=True)
|
||||||
input_file_type = input_file_mime_type.split('/')[0]
|
input_file_type = input_file_mime_type.split('/')[0]
|
||||||
input_file_subtype = input_file_mime_type.split('/')[1]
|
input_file_subtype = input_file_mime_type.split('/')[1]
|
||||||
except magic.magic.MagicException:
|
except Exception:
|
||||||
input_file_type = input_file_subtype = None
|
input_file_type = input_file_subtype = None
|
||||||
|
|
||||||
# in case python-magic fails to detect file type
|
# in case python-magic fails to detect file type
|
||||||
@@ -918,11 +932,11 @@ class Video2XMainWindow(QMainWindow):
|
|||||||
|
|
||||||
# otherwise, use .png by default for all images
|
# otherwise, use .png by default for all images
|
||||||
else:
|
else:
|
||||||
suffix = '.png'
|
suffix = self.image_output_extension_line_edit.text()
|
||||||
|
|
||||||
# if input is video, use .mp4 as output by default
|
# if input is video, use .mp4 as output by default
|
||||||
elif input_file_type == 'video':
|
elif input_file_type == 'video':
|
||||||
suffix = '.mp4'
|
suffix = self.video_output_extension_line_edit.text()
|
||||||
|
|
||||||
# if failed to detect file type
|
# if failed to detect file type
|
||||||
# use input file's suffix
|
# use input file's suffix
|
||||||
@@ -934,9 +948,9 @@ class Video2XMainWindow(QMainWindow):
|
|||||||
elif input_path.is_dir():
|
elif input_path.is_dir():
|
||||||
output_path = input_path.parent / f'{input_path.stem}_output'
|
output_path = input_path.parent / f'{input_path.stem}_output'
|
||||||
|
|
||||||
# try up to 1000 times
|
# try a new name with a different file ID
|
||||||
output_path_id = 0
|
output_path_id = 0
|
||||||
while output_path.exists() and output_path_id <= 1000:
|
while output_path.exists():
|
||||||
if input_path.is_file():
|
if input_path.is_file():
|
||||||
output_path = input_path.parent / pathlib.Path(f'{input_path.stem}_output_{output_path_id}{suffix}')
|
output_path = input_path.parent / pathlib.Path(f'{input_path.stem}_output_{output_path_id}{suffix}')
|
||||||
elif input_path.is_dir():
|
elif input_path.is_dir():
|
||||||
@@ -1059,7 +1073,7 @@ It\'s also highly recommended for you to attach the [log file]({}) under the pro
|
|||||||
|
|
||||||
# upscale process will stop at 99%
|
# upscale process will stop at 99%
|
||||||
# so it's set to 100 manually when all is done
|
# so it's set to 100 manually when all is done
|
||||||
progress_callback.emit((upscale_begin_time, 0, 0, 0, 0, pathlib.Path(), pathlib.Path()))
|
# progress_callback.emit((upscale_begin_time, 0, 0, 0, 0, pathlib.Path(), pathlib.Path()))
|
||||||
|
|
||||||
def set_progress(self, progress_information: tuple):
|
def set_progress(self, progress_information: tuple):
|
||||||
upscale_begin_time = progress_information[0]
|
upscale_begin_time = progress_information[0]
|
||||||
@@ -1140,9 +1154,10 @@ It\'s also highly recommended for you to attach the [log file]({}) under the pro
|
|||||||
self.show_warning('Output path unspecified')
|
self.show_warning('Output path unspecified')
|
||||||
return
|
return
|
||||||
|
|
||||||
print(f'Redirecting console logs to {self.logfile}', file=sys.stderr)
|
if self.disable_logging_check_box.isChecked() is False:
|
||||||
sys.stdout = BiLogger(sys.stdout, self.logfile)
|
print(f'Redirecting console logs to {self.logfile}', file=sys.stderr)
|
||||||
sys.stderr = BiLogger(sys.stderr, self.logfile)
|
sys.stdout = BiLogger(sys.stdout, self.logfile)
|
||||||
|
sys.stderr = BiLogger(sys.stderr, self.logfile)
|
||||||
|
|
||||||
if len(self.input_table_data) == 1:
|
if len(self.input_table_data) == 1:
|
||||||
input_directory = self.input_table_data[0]
|
input_directory = self.input_table_data[0]
|
||||||
@@ -1158,19 +1173,24 @@ It\'s also highly recommended for you to attach the [log file]({}) under the pro
|
|||||||
# load driver settings for the current driver
|
# load driver settings for the current driver
|
||||||
self.driver_settings = self.config[AVAILABLE_DRIVERS[self.driver_combo_box.currentText()]]
|
self.driver_settings = self.config[AVAILABLE_DRIVERS[self.driver_combo_box.currentText()]]
|
||||||
|
|
||||||
self.upscaler = Upscaler(input_path=input_directory,
|
self.upscaler = Upscaler(
|
||||||
output_path=output_directory,
|
# required parameters
|
||||||
driver_settings=self.driver_settings,
|
input_path=input_directory,
|
||||||
ffmpeg_settings=self.ffmpeg_settings,
|
output_path=output_directory,
|
||||||
gifski_settings=self.gifski_settings)
|
driver_settings=self.driver_settings,
|
||||||
|
ffmpeg_settings=self.ffmpeg_settings,
|
||||||
|
gifski_settings=self.gifski_settings,
|
||||||
|
|
||||||
# set optional options
|
# optional parameters
|
||||||
self.upscaler.driver = AVAILABLE_DRIVERS[self.driver_combo_box.currentText()]
|
driver=AVAILABLE_DRIVERS[self.driver_combo_box.currentText()],
|
||||||
self.upscaler.scale_ratio = self.scale_ratio_double_spin_box.value()
|
scale_ratio=self.scale_ratio_double_spin_box.value(),
|
||||||
self.upscaler.processes = self.processes_spin_box.value()
|
processes=self.processes_spin_box.value(),
|
||||||
self.upscaler.video2x_cache_directory = pathlib.Path(os.path.expandvars(self.cache_line_edit.text()))
|
video2x_cache_directory=pathlib.Path(os.path.expandvars(self.cache_line_edit.text())),
|
||||||
self.upscaler.image_format = self.config['video2x']['image_format'].lower()
|
extracted_frame_format=self.config['video2x']['extracted_frame_format'].lower(),
|
||||||
self.upscaler.preserve_frames = bool(self.preserve_frames_check_box.isChecked())
|
image_output_extension=self.image_output_extension_line_edit.text(),
|
||||||
|
video_output_extension=self.video_output_extension_line_edit.text(),
|
||||||
|
preserve_frames=bool(self.preserve_frames_check_box.isChecked())
|
||||||
|
)
|
||||||
|
|
||||||
# run upscaler
|
# run upscaler
|
||||||
worker = UpscalerWorker(self.upscaler.run)
|
worker = UpscalerWorker(self.upscaler.run)
|
||||||
@@ -1192,6 +1212,10 @@ It\'s also highly recommended for you to attach the [log file]({}) under the pro
|
|||||||
self.upscale_errored(e)
|
self.upscale_errored(e)
|
||||||
|
|
||||||
def upscale_errored(self, exception: Exception):
|
def upscale_errored(self, exception: Exception):
|
||||||
|
# send stop signal in case it's not triggered
|
||||||
|
with contextlib.suppress(AttributeError):
|
||||||
|
self.upscaler.running = False
|
||||||
|
|
||||||
self.show_error(exception)
|
self.show_error(exception)
|
||||||
self.threadpool.waitForDone(5)
|
self.threadpool.waitForDone(5)
|
||||||
self.start_button.setEnabled(True)
|
self.start_button.setEnabled(True)
|
||||||
|
|||||||
@@ -1,190 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<!DOCTYPE QtCreatorProject>
|
|
||||||
<!-- Written by QtCreator 4.12.0, 2020-05-26T06:35:20. -->
|
|
||||||
<qtcreator>
|
|
||||||
<data>
|
|
||||||
<variable>EnvironmentId</variable>
|
|
||||||
<value type="QByteArray">{25c1e4a4-6b4a-4828-883b-6f32c3f7eba0}</value>
|
|
||||||
</data>
|
|
||||||
<data>
|
|
||||||
<variable>ProjectExplorer.Project.ActiveTarget</variable>
|
|
||||||
<value type="int">0</value>
|
|
||||||
</data>
|
|
||||||
<data>
|
|
||||||
<variable>ProjectExplorer.Project.EditorSettings</variable>
|
|
||||||
<valuemap type="QVariantMap">
|
|
||||||
<value type="bool" key="EditorConfiguration.AutoIndent">true</value>
|
|
||||||
<value type="bool" key="EditorConfiguration.AutoSpacesForTabs">false</value>
|
|
||||||
<value type="bool" key="EditorConfiguration.CamelCaseNavigation">true</value>
|
|
||||||
<valuemap type="QVariantMap" key="EditorConfiguration.CodeStyle.0">
|
|
||||||
<value type="QString" key="language">Cpp</value>
|
|
||||||
<valuemap type="QVariantMap" key="value">
|
|
||||||
<value type="QByteArray" key="CurrentPreferences">CppGlobal</value>
|
|
||||||
</valuemap>
|
|
||||||
</valuemap>
|
|
||||||
<valuemap type="QVariantMap" key="EditorConfiguration.CodeStyle.1">
|
|
||||||
<value type="QString" key="language">QmlJS</value>
|
|
||||||
<valuemap type="QVariantMap" key="value">
|
|
||||||
<value type="QByteArray" key="CurrentPreferences">QmlJSGlobal</value>
|
|
||||||
</valuemap>
|
|
||||||
</valuemap>
|
|
||||||
<value type="int" key="EditorConfiguration.CodeStyle.Count">2</value>
|
|
||||||
<value type="QByteArray" key="EditorConfiguration.Codec">UTF-8</value>
|
|
||||||
<value type="bool" key="EditorConfiguration.ConstrainTooltips">false</value>
|
|
||||||
<value type="int" key="EditorConfiguration.IndentSize">4</value>
|
|
||||||
<value type="bool" key="EditorConfiguration.KeyboardTooltips">false</value>
|
|
||||||
<value type="int" key="EditorConfiguration.MarginColumn">80</value>
|
|
||||||
<value type="bool" key="EditorConfiguration.MouseHiding">true</value>
|
|
||||||
<value type="bool" key="EditorConfiguration.MouseNavigation">true</value>
|
|
||||||
<value type="int" key="EditorConfiguration.PaddingMode">1</value>
|
|
||||||
<value type="bool" key="EditorConfiguration.ScrollWheelZooming">true</value>
|
|
||||||
<value type="bool" key="EditorConfiguration.ShowMargin">false</value>
|
|
||||||
<value type="int" key="EditorConfiguration.SmartBackspaceBehavior">0</value>
|
|
||||||
<value type="bool" key="EditorConfiguration.SmartSelectionChanging">true</value>
|
|
||||||
<value type="bool" key="EditorConfiguration.SpacesForTabs">true</value>
|
|
||||||
<value type="int" key="EditorConfiguration.TabKeyBehavior">0</value>
|
|
||||||
<value type="int" key="EditorConfiguration.TabSize">8</value>
|
|
||||||
<value type="bool" key="EditorConfiguration.UseGlobal">true</value>
|
|
||||||
<value type="int" key="EditorConfiguration.Utf8BomBehavior">1</value>
|
|
||||||
<value type="bool" key="EditorConfiguration.addFinalNewLine">true</value>
|
|
||||||
<value type="bool" key="EditorConfiguration.cleanIndentation">true</value>
|
|
||||||
<value type="bool" key="EditorConfiguration.cleanWhitespace">true</value>
|
|
||||||
<value type="bool" key="EditorConfiguration.inEntireDocument">false</value>
|
|
||||||
</valuemap>
|
|
||||||
</data>
|
|
||||||
<data>
|
|
||||||
<variable>ProjectExplorer.Project.PluginSettings</variable>
|
|
||||||
<valuemap type="QVariantMap">
|
|
||||||
<valuelist type="QVariantList" key="ClangCodeModel.CustomCommandLineKey">
|
|
||||||
<value type="QString">-fno-delayed-template-parsing</value>
|
|
||||||
</valuelist>
|
|
||||||
<value type="bool" key="ClangCodeModel.UseGlobalConfig">true</value>
|
|
||||||
<value type="QString" key="ClangCodeModel.WarningConfigId">Builtin.Questionable</value>
|
|
||||||
<valuemap type="QVariantMap" key="ClangTools">
|
|
||||||
<value type="bool" key="ClangTools.BuildBeforeAnalysis">true</value>
|
|
||||||
<value type="QString" key="ClangTools.DiagnosticConfig">Builtin.DefaultTidyAndClazy</value>
|
|
||||||
<value type="int" key="ClangTools.ParallelJobs">8</value>
|
|
||||||
<valuelist type="QVariantList" key="ClangTools.SelectedDirs"/>
|
|
||||||
<valuelist type="QVariantList" key="ClangTools.SelectedFiles"/>
|
|
||||||
<valuelist type="QVariantList" key="ClangTools.SuppressedDiagnostics"/>
|
|
||||||
<value type="bool" key="ClangTools.UseGlobalSettings">true</value>
|
|
||||||
</valuemap>
|
|
||||||
</valuemap>
|
|
||||||
</data>
|
|
||||||
<data>
|
|
||||||
<variable>ProjectExplorer.Project.Target.0</variable>
|
|
||||||
<valuemap type="QVariantMap">
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Desktop (x86-windows-msvc2019-pe-64bit)</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Desktop (x86-windows-msvc2019-pe-64bit)</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">{5450e32e-f498-4c15-a0a5-7456f3375388}</value>
|
|
||||||
<value type="int" key="ProjectExplorer.Target.ActiveBuildConfiguration">-1</value>
|
|
||||||
<value type="int" key="ProjectExplorer.Target.ActiveDeployConfiguration">0</value>
|
|
||||||
<value type="int" key="ProjectExplorer.Target.ActiveRunConfiguration">0</value>
|
|
||||||
<value type="int" key="ProjectExplorer.Target.BuildConfigurationCount">0</value>
|
|
||||||
<valuemap type="QVariantMap" key="ProjectExplorer.Target.DeployConfiguration.0">
|
|
||||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
|
|
||||||
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">0</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Deploy</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Deploy</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Deploy</value>
|
|
||||||
</valuemap>
|
|
||||||
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">1</value>
|
|
||||||
<valuemap type="QVariantMap" key="ProjectExplorer.DeployConfiguration.CustomData"/>
|
|
||||||
<value type="bool" key="ProjectExplorer.DeployConfiguration.CustomDataEnabled">false</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.DefaultDeployConfiguration</value>
|
|
||||||
</valuemap>
|
|
||||||
<value type="int" key="ProjectExplorer.Target.DeployConfigurationCount">1</value>
|
|
||||||
<valuemap type="QVariantMap" key="ProjectExplorer.Target.PluginSettings"/>
|
|
||||||
<valuemap type="QVariantMap" key="ProjectExplorer.Target.RunConfiguration.0">
|
|
||||||
<value type="QString" key="Analyzer.Perf.CallgraphMode">dwarf</value>
|
|
||||||
<valuelist type="QVariantList" key="Analyzer.Perf.Events">
|
|
||||||
<value type="QString">cpu-cycles</value>
|
|
||||||
</valuelist>
|
|
||||||
<valuelist type="QVariantList" key="Analyzer.Perf.ExtraArguments"/>
|
|
||||||
<value type="int" key="Analyzer.Perf.Frequency">250</value>
|
|
||||||
<valuelist type="QVariantList" key="Analyzer.Perf.RecordArguments">
|
|
||||||
<value type="QString">-e</value>
|
|
||||||
<value type="QString">cpu-cycles</value>
|
|
||||||
<value type="QString">--call-graph</value>
|
|
||||||
<value type="QString">dwarf,4096</value>
|
|
||||||
<value type="QString">-F</value>
|
|
||||||
<value type="QString">250</value>
|
|
||||||
</valuelist>
|
|
||||||
<value type="QString" key="Analyzer.Perf.SampleMode">-F</value>
|
|
||||||
<value type="bool" key="Analyzer.Perf.Settings.UseGlobalSettings">true</value>
|
|
||||||
<value type="int" key="Analyzer.Perf.StackSize">4096</value>
|
|
||||||
<value type="bool" key="Analyzer.QmlProfiler.AggregateTraces">false</value>
|
|
||||||
<value type="bool" key="Analyzer.QmlProfiler.FlushEnabled">false</value>
|
|
||||||
<value type="uint" key="Analyzer.QmlProfiler.FlushInterval">1000</value>
|
|
||||||
<value type="QString" key="Analyzer.QmlProfiler.LastTraceFile"></value>
|
|
||||||
<value type="bool" key="Analyzer.QmlProfiler.Settings.UseGlobalSettings">true</value>
|
|
||||||
<valuelist type="QVariantList" key="Analyzer.Valgrind.AddedSuppressionFiles"/>
|
|
||||||
<value type="bool" key="Analyzer.Valgrind.Callgrind.CollectBusEvents">false</value>
|
|
||||||
<value type="bool" key="Analyzer.Valgrind.Callgrind.CollectSystime">false</value>
|
|
||||||
<value type="bool" key="Analyzer.Valgrind.Callgrind.EnableBranchSim">false</value>
|
|
||||||
<value type="bool" key="Analyzer.Valgrind.Callgrind.EnableCacheSim">false</value>
|
|
||||||
<value type="bool" key="Analyzer.Valgrind.Callgrind.EnableEventToolTips">true</value>
|
|
||||||
<value type="double" key="Analyzer.Valgrind.Callgrind.MinimumCostRatio">0.01</value>
|
|
||||||
<value type="double" key="Analyzer.Valgrind.Callgrind.VisualisationMinimumCostRatio">10</value>
|
|
||||||
<value type="bool" key="Analyzer.Valgrind.FilterExternalIssues">true</value>
|
|
||||||
<value type="QString" key="Analyzer.Valgrind.KCachegrindExecutable">kcachegrind</value>
|
|
||||||
<value type="int" key="Analyzer.Valgrind.LeakCheckOnFinish">1</value>
|
|
||||||
<value type="int" key="Analyzer.Valgrind.NumCallers">25</value>
|
|
||||||
<valuelist type="QVariantList" key="Analyzer.Valgrind.RemovedSuppressionFiles"/>
|
|
||||||
<value type="int" key="Analyzer.Valgrind.SelfModifyingCodeDetection">1</value>
|
|
||||||
<value type="bool" key="Analyzer.Valgrind.Settings.UseGlobalSettings">true</value>
|
|
||||||
<value type="bool" key="Analyzer.Valgrind.ShowReachable">false</value>
|
|
||||||
<value type="bool" key="Analyzer.Valgrind.TrackOrigins">true</value>
|
|
||||||
<value type="QString" key="Analyzer.Valgrind.ValgrindExecutable">valgrind</value>
|
|
||||||
<valuelist type="QVariantList" key="Analyzer.Valgrind.VisibleErrorKinds">
|
|
||||||
<value type="int">0</value>
|
|
||||||
<value type="int">1</value>
|
|
||||||
<value type="int">2</value>
|
|
||||||
<value type="int">3</value>
|
|
||||||
<value type="int">4</value>
|
|
||||||
<value type="int">5</value>
|
|
||||||
<value type="int">6</value>
|
|
||||||
<value type="int">7</value>
|
|
||||||
<value type="int">8</value>
|
|
||||||
<value type="int">9</value>
|
|
||||||
<value type="int">10</value>
|
|
||||||
<value type="int">11</value>
|
|
||||||
<value type="int">12</value>
|
|
||||||
<value type="int">13</value>
|
|
||||||
<value type="int">14</value>
|
|
||||||
</valuelist>
|
|
||||||
<value type="int" key="PE.EnvironmentAspect.Base">2</value>
|
|
||||||
<valuelist type="QVariantList" key="PE.EnvironmentAspect.Changes"/>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">video2x_gui</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">PythonEditor.RunConfiguration.C:/Users/k4yt3x/Documents/Projects/video2x/src/video2x_gui.py</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.RunConfiguration.BuildKey">C:/Users/k4yt3x/Documents/Projects/video2x/src/video2x_gui.py</value>
|
|
||||||
<value type="bool" key="PythonEditor.RunConfiguation.Buffered">false</value>
|
|
||||||
<value type="QString" key="PythonEditor.RunConfiguation.Interpreter">{ffc39ed5-fbe0-4af8-8b16-9a60c393bdb8}</value>
|
|
||||||
<value type="QString" key="PythonEditor.RunConfiguation.Script">C:\Users\k4yt3x\Documents\Projects\video2x\src\video2x_gui.py</value>
|
|
||||||
<value type="QString" key="RunConfiguration.Arguments"></value>
|
|
||||||
<value type="bool" key="RunConfiguration.Arguments.multi">false</value>
|
|
||||||
<value type="QString" key="RunConfiguration.OverrideDebuggerStartup"></value>
|
|
||||||
<value type="bool" key="RunConfiguration.UseCppDebugger">false</value>
|
|
||||||
<value type="bool" key="RunConfiguration.UseCppDebuggerAuto">true</value>
|
|
||||||
<value type="bool" key="RunConfiguration.UseMultiProcess">false</value>
|
|
||||||
<value type="bool" key="RunConfiguration.UseQmlDebugger">false</value>
|
|
||||||
<value type="bool" key="RunConfiguration.UseQmlDebuggerAuto">true</value>
|
|
||||||
<value type="QString" key="RunConfiguration.WorkingDirectory"></value>
|
|
||||||
<value type="QString" key="RunConfiguration.WorkingDirectory.default"></value>
|
|
||||||
</valuemap>
|
|
||||||
<value type="int" key="ProjectExplorer.Target.RunConfigurationCount">1</value>
|
|
||||||
</valuemap>
|
|
||||||
</data>
|
|
||||||
<data>
|
|
||||||
<variable>ProjectExplorer.Project.TargetCount</variable>
|
|
||||||
<value type="int">1</value>
|
|
||||||
</data>
|
|
||||||
<data>
|
|
||||||
<variable>ProjectExplorer.Project.Updater.FileVersion</variable>
|
|
||||||
<value type="int">22</value>
|
|
||||||
</data>
|
|
||||||
<data>
|
|
||||||
<variable>Version</variable>
|
|
||||||
<value type="int">22</value>
|
|
||||||
</data>
|
|
||||||
</qtcreator>
|
|
||||||
@@ -6,8 +6,8 @@
|
|||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>673</width>
|
<width>727</width>
|
||||||
<height>844</height>
|
<height>908</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="acceptDrops">
|
<property name="acceptDrops">
|
||||||
@@ -407,6 +407,54 @@
|
|||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="imageOutputExtensionHorizontalLayout">
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="imageOutputExtensionLabel">
|
||||||
|
<property name="text">
|
||||||
|
<string>Image Output Extension</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLineEdit" name="imageOutputExtensionLineEdit">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>.png</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="videoOutputExtensionHorizontalLayout">
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="videoOutputExtensionLabel">
|
||||||
|
<property name="text">
|
||||||
|
<string>Video Output Extension</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLineEdit" name="videoOutputExtensionLineEdit">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>.mp4</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QCheckBox" name="preserveFramesCheckBox">
|
<widget class="QCheckBox" name="preserveFramesCheckBox">
|
||||||
<property name="toolTip">
|
<property name="toolTip">
|
||||||
@@ -420,6 +468,13 @@
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QCheckBox" name="disableLoggingCheckBox">
|
||||||
|
<property name="text">
|
||||||
|
<string>Disable Logging</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
@@ -448,6 +503,9 @@
|
|||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Keep Aspect Ratio</string>
|
<string>Keep Aspect Ratio</string>
|
||||||
</property>
|
</property>
|
||||||
|
<property name="checked">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
@@ -1685,6 +1743,13 @@
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QCheckBox" name="anime4kCppCnnModeCheckBox">
|
||||||
|
<property name="text">
|
||||||
|
<string>CNN Mode</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
@@ -2770,7 +2835,7 @@
|
|||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>673</width>
|
<width>727</width>
|
||||||
<height>21</height>
|
<height>21</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
|
|||||||
@@ -48,7 +48,6 @@ SETUP_VERSION = '2.2.1'
|
|||||||
|
|
||||||
# global static variables
|
# global static variables
|
||||||
LOCALAPPDATA = pathlib.Path(os.getenv('localappdata'))
|
LOCALAPPDATA = pathlib.Path(os.getenv('localappdata'))
|
||||||
VIDEO2X_CONFIG = pathlib.Path(__file__).parent.absolute() / 'video2x.yaml'
|
|
||||||
DRIVER_OPTIONS = ['all',
|
DRIVER_OPTIONS = ['all',
|
||||||
'ffmpeg',
|
'ffmpeg',
|
||||||
'gifski',
|
'gifski',
|
||||||
|
|||||||
223
src/video2x_setup_ubuntu.sh
Executable file
223
src/video2x_setup_ubuntu.sh
Executable file
@@ -0,0 +1,223 @@
|
|||||||
|
#!/usr/bin/bash -e
|
||||||
|
# Name: Video2X Setup Script (Ubuntu)
|
||||||
|
# Creator: K4YT3X
|
||||||
|
# Date Created: June 5, 2020
|
||||||
|
# Last Modified: June 7, 2020
|
||||||
|
|
||||||
|
# help message if input is incorrect of if -h/--help is specified
|
||||||
|
if [ "$1" == "-h" ] || [ "$1" == "--help" ] || [ "$#" -gt 2 ]; then
|
||||||
|
echo "usage: $0 INSTALLATION_PATH TEMP"
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
# set intallation path if specified
|
||||||
|
if [ ! -z "$1" ]; then
|
||||||
|
INSTALLATION_PATH=$1
|
||||||
|
else
|
||||||
|
INSTALLATION_PATH="$HOME/.local/share"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# set temp directory location if specified
|
||||||
|
if [ ! -z "$2" ]; then
|
||||||
|
TEMP=$2
|
||||||
|
else
|
||||||
|
TEMP="/tmp/video2x"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# environment variables
|
||||||
|
export DEBIAN_FRONTEND="noninteractive"
|
||||||
|
|
||||||
|
# install basic utilities and add PPAs
|
||||||
|
apt-get update
|
||||||
|
apt-get install -y --no-install-recommends apt-utils software-properties-common
|
||||||
|
|
||||||
|
# add PPAs and sources
|
||||||
|
add-apt-repository -y ppa:apt-fast/stable
|
||||||
|
add-apt-repository -y ppa:graphics-drivers/ppa
|
||||||
|
apt-get install -y --no-install-recommends apt-fast
|
||||||
|
apt-fast update
|
||||||
|
|
||||||
|
# install runtime packages
|
||||||
|
apt-fast install -y --no-install-recommends ffmpeg libmagic1 nvidia-cuda-toolkit nvidia-driver-440 python3.8
|
||||||
|
|
||||||
|
# install compilation packages
|
||||||
|
apt-fast install -y --no-install-recommends git-core curl wget ca-certificates gnupg2 python3-dev python3-pip python3-setuptools python3-wheel
|
||||||
|
|
||||||
|
# add Nvidia sources
|
||||||
|
curl -fsSL https://developer.download.nvidia.com/compute/cuda/repos/ubuntu1804/x86_64/7fa2af80.pub | apt-key add -
|
||||||
|
echo "deb https://developer.download.nvidia.com/compute/machine-learning/repos/ubuntu1804/x86_64 /" >/etc/apt/sources.list.d/nvidia-ml.list
|
||||||
|
apt-fast update
|
||||||
|
|
||||||
|
# install python3 packages
|
||||||
|
git clone --recurse-submodules --progress https://github.com/k4yt3x/video2x.git --depth=1 $INSTALLATION_PATH/video2x
|
||||||
|
python3.8 -m pip install -U pip
|
||||||
|
python3.8 -m pip install -U -r $INSTALLATION_PATH/video2x/src/requirements.txt
|
||||||
|
mkdir -v -p $INSTALLATION_PATH/video2x/src/dependencies
|
||||||
|
|
||||||
|
# install gifski
|
||||||
|
apt-fast install -y --no-install-recommends cargo
|
||||||
|
cargo install gifski
|
||||||
|
|
||||||
|
# install waifu2x-caffe
|
||||||
|
apt-fast install -y --no-install-recommends autoconf build-essential cmake gcc-8 libatlas-base-dev libboost-atomic-dev libboost-chrono-dev libboost-date-time-dev libboost-filesystem-dev libboost-iostreams-dev libboost-python-dev libboost-system-dev libboost-thread-dev libcudnn7 libcudnn7-dev libgflags-dev libgoogle-glog-dev libhdf5-dev libleveldb-dev liblmdb-dev libopencv-dev libprotobuf-dev libsnappy-dev protobuf-compiler python-numpy texinfo yasm zlib1g-dev
|
||||||
|
|
||||||
|
git clone --recurse-submodules --depth=1 --progress --recurse-submodules https://github.com/nagadomi/waifu2x-caffe-ubuntu.git $TEMP/waifu2x-caffe-ubuntu
|
||||||
|
git clone --recurse-submodules --progress --depth=1 https://github.com/nagadomi/caffe.git $TEMP/waifu2x-caffe-ubuntu/caffe
|
||||||
|
|
||||||
|
apt-get purge -y gcc g++
|
||||||
|
ln -s /usr/bin/gcc-8 /usr/bin/gcc
|
||||||
|
ln -s /usr/bin/g++-8 /usr/bin/g++
|
||||||
|
mkdir -v -p $TEMP/waifu2x-caffe-ubuntu/build
|
||||||
|
cd $TEMP/waifu2x-caffe-ubuntu/build
|
||||||
|
cmake .. -DCMAKE_INSTALL_PREFIX=/usr
|
||||||
|
make -j$(nproc) install
|
||||||
|
|
||||||
|
mv -v /tmp/video2x/waifu2x-caffe-ubuntu/bin $INSTALLATION_PATH/video2x/src/dependencies/waifu2x-caffe
|
||||||
|
mv -v /tmp/video2x/waifu2x-caffe-ubuntu/build/waifu2x-caffe $INSTALLATION_PATH/video2x/src/dependencies/waifu2x-caffe/waifu2x-caffe
|
||||||
|
|
||||||
|
# install waifu2x-converter-cpp
|
||||||
|
apt-fast install -y --no-install-recommends build-essential cmake libopencv-dev ocl-icd-opencl-dev
|
||||||
|
git clone --recurse-submodules --depth=1 --progress https://github.com/DeadSix27/waifu2x-converter-cpp $TEMP/waifu2x-converter-cpp
|
||||||
|
mkdir -v $TEMP/waifu2x-converter-cpp/build
|
||||||
|
cd $TEMP/waifu2x-converter-cpp/build
|
||||||
|
cmake ..
|
||||||
|
make -j$(nproc)
|
||||||
|
mv -v $TEMP/waifu2x-converter-cpp/build $INSTALLATION_PATH/video2x/src/dependencies/waifu2x-converter-cpp
|
||||||
|
mv -v $TEMP/waifu2x-converter-cpp/models_rgb $INSTALLATION_PATH/video2x/src/dependencies/waifu2x-converter-cpp/models_rgb
|
||||||
|
|
||||||
|
# install waifu2x-ncnn-vulkan
|
||||||
|
# download libvulkan1
|
||||||
|
apt-fast install -y --no-install-recommends libvulkan1 unzip jq
|
||||||
|
|
||||||
|
# get latest release JSON as a string
|
||||||
|
echo "Fetching latest waifu2x-ncnn-vulkan release information using GitHub API"
|
||||||
|
waifu2x_ncnn_vulkan_latest_release=$(curl -s https://api.github.com/repos/nihui/waifu2x-ncnn-vulkan/releases/latest)
|
||||||
|
|
||||||
|
# count the number of assets in this release
|
||||||
|
assets=$(echo "$waifu2x_ncnn_vulkan_latest_release" | jq -r '.assets | length')
|
||||||
|
|
||||||
|
# iterate through each of the assets and see if the name of the asset matches what we're looking for
|
||||||
|
for i in $(seq $assets $END); do
|
||||||
|
if echo "$waifu2x_ncnn_vulkan_latest_release" | jq -r ".assets["$(($i - 1))"].name" | egrep "^waifu2x-ncnn-vulkan-[0-9]*-linux\.zip$"; then
|
||||||
|
download_link=$(echo "$waifu2x_ncnn_vulkan_latest_release" | jq -r ".assets["$(($i - 1))"].browser_download_url")
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
# check if download_link variable is set
|
||||||
|
if [ -z "$download_link" ]; then
|
||||||
|
echo "$waifu2x_ncnn_vulkan_latest_release"
|
||||||
|
echo "Error: unable to find waifu2x-ncnn-vulkan download link or GitHub API rate limit exceeded"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
waifu2x_ncnn_vulkan_zip="$TEMP/waifu2x-ncnn-vulkan-linux.zip"
|
||||||
|
echo "Downloading $download_link to $waifu2x_ncnn_vulkan_zip"
|
||||||
|
wget "$download_link" -O "$waifu2x_ncnn_vulkan_zip"
|
||||||
|
unzip "$waifu2x_ncnn_vulkan_zip" -d $TEMP/waifu2x-ncnn-vulkan
|
||||||
|
mv -v $TEMP/waifu2x-ncnn-vulkan/waifu2x-ncnn-vulkan-*-linux $INSTALLATION_PATH/video2x/src/dependencies/waifu2x-ncnn-vulkan
|
||||||
|
|
||||||
|
# install srmd-ncnn-vulkan
|
||||||
|
# download libvulkan1
|
||||||
|
apt-fast install -y --no-install-recommends libvulkan1 unzip jq
|
||||||
|
|
||||||
|
# get latest release JSON as a string
|
||||||
|
echo "Fetching latest srmd-ncnn-vulkan release information using GitHub API"
|
||||||
|
srmd_ncnn_vulkan_latest_release=$(curl -s https://api.github.com/repos/nihui/srmd-ncnn-vulkan/releases/latest)
|
||||||
|
|
||||||
|
# count the number of assets in this release
|
||||||
|
assets=$(echo "$srmd_ncnn_vulkan_latest_release" | jq -r '.assets | length')
|
||||||
|
|
||||||
|
# iterate through each of the assets and see if the name of the asset matches what we're looking for
|
||||||
|
for i in $(seq $assets $END); do
|
||||||
|
if echo "$srmd_ncnn_vulkan_latest_release" | jq -r ".assets["$(($i - 1))"].name" | egrep "^srmd-ncnn-vulkan-[0-9]*-linux\.zip$"; then
|
||||||
|
download_link=$(echo "$srmd_ncnn_vulkan_latest_release" | jq -r ".assets["$(($i - 1))"].browser_download_url")
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
# check if download_link variable is set
|
||||||
|
if [ -z "$download_link" ]; then
|
||||||
|
echo "$srmd_ncnn_vulkan_latest_release"
|
||||||
|
echo "Error: unable to find srmd-ncnn-vulkan download link or GitHub API rate limit exceeded"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
srmd_ncnn_vulkan_zip="$TEMP/srmd-ncnn-vulkan-linux.zip"
|
||||||
|
echo "Downloading $download_link to $srmd_ncnn_vulkan_zip"
|
||||||
|
wget "$download_link" -O "$srmd_ncnn_vulkan_zip"
|
||||||
|
unzip "$srmd_ncnn_vulkan_zip" -d $TEMP/srmd-ncnn-vulkan
|
||||||
|
mv -v $TEMP/srmd-ncnn-vulkan/srmd-ncnn-vulkan-*-linux $INSTALLATION_PATH/video2x/src/dependencies/srmd-ncnn-vulkan
|
||||||
|
|
||||||
|
# install realsr-ncnn-vulkan
|
||||||
|
# download libvulkan1
|
||||||
|
apt-fast install -y --no-install-recommends libvulkan1 unzip jq
|
||||||
|
|
||||||
|
# get latest release JSON as a string
|
||||||
|
echo "Fetching latest realsr-ncnn-vulkan release information using GitHub API"
|
||||||
|
realsr_ncnn_vulkan_latest_release=$(curl -s https://api.github.com/repos/nihui/realsr-ncnn-vulkan/releases/latest)
|
||||||
|
|
||||||
|
# count the number of assets in this release
|
||||||
|
assets=$(echo "$realsr_ncnn_vulkan_latest_release" | jq -r '.assets | length')
|
||||||
|
|
||||||
|
# iterate through each of the assets and see if the name of the asset matches what we're looking for
|
||||||
|
for i in $(seq $assets $END); do
|
||||||
|
if echo "$realsr_ncnn_vulkan_latest_release" | jq -r ".assets["$(($i - 1))"].name" | egrep "^realsr-ncnn-vulkan-[0-9]*-linux\.zip$"; then
|
||||||
|
download_link=$(echo "$realsr_ncnn_vulkan_latest_release" | jq -r ".assets["$(($i - 1))"].browser_download_url")
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
# check if download_link variable is set
|
||||||
|
if [ -z "$download_link" ]; then
|
||||||
|
echo "$realsr_ncnn_vulkan_latest_release"
|
||||||
|
echo "Error: unable to find realsr-ncnn-vulkan download link or GitHub API rate limit exceeded"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
realsr_ncnn_vulkan_zip="$TEMP/realsr-ncnn-vulkan-linux.zip"
|
||||||
|
echo "Downloading $download_link to $realsr_ncnn_vulkan_zip"
|
||||||
|
wget "$download_link" -O "$realsr_ncnn_vulkan_zip"
|
||||||
|
unzip "$realsr_ncnn_vulkan_zip" -d $TEMP/realsr-ncnn-vulkan
|
||||||
|
mv -v $TEMP/realsr-ncnn-vulkan/realsr-ncnn-vulkan-*-linux $INSTALLATION_PATH/video2x/src/dependencies/realsr-ncnn-vulkan
|
||||||
|
|
||||||
|
# rewrite config file values
|
||||||
|
python3.8 - << EOF
|
||||||
|
import yaml
|
||||||
|
|
||||||
|
with open('/video2x/src/video2x.yaml', 'r') as template:
|
||||||
|
template_dict = yaml.load(template, Loader=yaml.FullLoader)
|
||||||
|
template.close()
|
||||||
|
|
||||||
|
template_dict['ffmpeg']['ffmpeg_path'] = '/usr/bin'
|
||||||
|
template_dict['gifski']['gifski_path'] = '/root/.cargo/bin/gifski'
|
||||||
|
template_dict['waifu2x_caffe']['path'] = '/video2x/src/dependencies/waifu2x-caffe/waifu2x-caffe'
|
||||||
|
template_dict['waifu2x_converter_cpp']['path'] = '/video2x/src/dependencies/waifu2x-converter-cpp/waifu2x-converter-cpp'
|
||||||
|
template_dict['waifu2x_ncnn_vulkan']['path'] = '/video2x/src/dependencies/waifu2x-ncnn-vulkan/waifu2x-ncnn-vulkan'
|
||||||
|
template_dict['srmd_ncnn_vulkan']['path'] = '/video2x/src/dependencies/srmd-ncnn-vulkan/srmd-ncnn-vulkan'
|
||||||
|
template_dict['realsr_ncnn_vulkan']['path'] = '/video2x/src/dependencies/realsr-ncnn-vulkan/realsr-ncnn-vulkan'
|
||||||
|
template_dict['anime4kcpp']['path'] = '/video2x/src/dependencies/anime4kcpp/anime4kcpp'
|
||||||
|
|
||||||
|
# write configuration into file
|
||||||
|
with open('/video2x/src/video2x.yaml', 'w') as config:
|
||||||
|
yaml.dump(template_dict, config)
|
||||||
|
EOF
|
||||||
|
|
||||||
|
# clean up temp directory
|
||||||
|
# purge default utilities
|
||||||
|
apt-get purge -y git-core curl wget ca-certificates gnupg2 python3-dev python3-pip python3-setuptools
|
||||||
|
|
||||||
|
# purge waifu2x-caffe build dependencies
|
||||||
|
apt-get purge -y autoconf build-essential cmake gcc-8 libatlas-base-dev libboost-atomic-dev libboost-chrono-dev libboost-date-time-dev libboost-filesystem-dev libboost-iostreams-dev libboost-python-dev libboost-system-dev libboost-thread-dev libcudnn7 libcudnn7-dev libgflags-dev libgoogle-glog-dev libhdf5-dev libleveldb-dev liblmdb-dev libopencv-dev libprotobuf-dev libsnappy-dev protobuf-compiler python-numpy texinfo yasm zlib1g-dev
|
||||||
|
|
||||||
|
# purge waifu2x-converter-cpp build dependencies
|
||||||
|
apt-get purge -y libopencv-dev ocl-icd-opencl-dev
|
||||||
|
|
||||||
|
# purge waifu2x/srmd/realsr-ncnn-vulkan build dependencies
|
||||||
|
apt-get purge -y unzip jq
|
||||||
|
|
||||||
|
# run autoremove and purge all unused packages
|
||||||
|
apt-get autoremove --purge -y
|
||||||
|
|
||||||
|
# remove temp directory
|
||||||
|
rm -vrf $TEMP
|
||||||
@@ -59,6 +59,7 @@ class WrapperMain:
|
|||||||
parser.add_argument('-r', '--preFilters', type=int, help='Enhancement filter, only working when preProcessing is true,there are 5 options by binary:Median blur=0000001, Mean blur=0000010, CAS Sharpening=0000100, Gaussian blur weak=0001000, Gaussian blur=0010000, Bilateral filter=0100000, Bilateral filter faster=1000000, you can freely combine them, eg: Gaussian blur weak + Bilateral filter = 0001000 | 0100000 = 0101000 = 40(D)')
|
parser.add_argument('-r', '--preFilters', type=int, help='Enhancement filter, only working when preProcessing is true,there are 5 options by binary:Median blur=0000001, Mean blur=0000010, CAS Sharpening=0000100, Gaussian blur weak=0001000, Gaussian blur=0010000, Bilateral filter=0100000, Bilateral filter faster=1000000, you can freely combine them, eg: Gaussian blur weak + Bilateral filter = 0001000 | 0100000 = 0101000 = 40(D)')
|
||||||
parser.add_argument('-e', '--postFilters', type=int, help='Enhancement filter, only working when postProcessing is true,there are 5 options by binary:Median blur=0000001, Mean blur=0000010, CAS Sharpening=0000100, Gaussian blur weak=0001000, Gaussian blur=0010000, Bilateral filter=0100000, Bilateral filter faster=1000000, you can freely combine them, eg: Gaussian blur weak + Bilateral filter = 0001000 | 0100000 = 0101000 = 40(D), so you can put 40 to enable Gaussian blur weak and Bilateral filter, which also is what I recommend for image that < 1080P, 48 for image that >= 1080P, and for performance I recommend to use 72 for video that < 1080P, 80 for video that >=1080P')
|
parser.add_argument('-e', '--postFilters', type=int, help='Enhancement filter, only working when postProcessing is true,there are 5 options by binary:Median blur=0000001, Mean blur=0000010, CAS Sharpening=0000100, Gaussian blur weak=0001000, Gaussian blur=0010000, Bilateral filter=0100000, Bilateral filter faster=1000000, you can freely combine them, eg: Gaussian blur weak + Bilateral filter = 0001000 | 0100000 = 0101000 = 40(D), so you can put 40 to enable Gaussian blur weak and Bilateral filter, which also is what I recommend for image that < 1080P, 48 for image that >= 1080P, and for performance I recommend to use 72 for video that < 1080P, 80 for video that >=1080P')
|
||||||
parser.add_argument('-q', '--GPUMode', action='store_true', help='Enable GPU acceleration')
|
parser.add_argument('-q', '--GPUMode', action='store_true', help='Enable GPU acceleration')
|
||||||
|
parser.add_argument('-w', '--CNNMode', action='store_true', help='Enable ACNet')
|
||||||
parser.add_argument('-l', '--listGPUs', action='store_true', help='list GPUs')
|
parser.add_argument('-l', '--listGPUs', action='store_true', help='list GPUs')
|
||||||
parser.add_argument('-h', '--platformID', type=int, help='Specify the platform ID')
|
parser.add_argument('-h', '--platformID', type=int, help='Specify the platform ID')
|
||||||
parser.add_argument('-d', '--deviceID', type=int, help='Specify the device ID')
|
parser.add_argument('-d', '--deviceID', type=int, help='Specify the device ID')
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
Name: Video2X FFmpeg Controller
|
Name: Video2X FFmpeg Controller
|
||||||
Author: K4YT3X
|
Author: K4YT3X
|
||||||
Date Created: Feb 24, 2018
|
Date Created: Feb 24, 2018
|
||||||
Last Modified: May 14, 2020
|
Last Modified: June 7, 2020
|
||||||
|
|
||||||
Description: This class handles all FFmpeg related operations.
|
Description: This class handles all FFmpeg related operations.
|
||||||
"""
|
"""
|
||||||
@@ -27,7 +27,7 @@ class Ffmpeg:
|
|||||||
and inserting audio tracks to videos.
|
and inserting audio tracks to videos.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, ffmpeg_settings, image_format='png'):
|
def __init__(self, ffmpeg_settings, extracted_frame_format='png'):
|
||||||
self.ffmpeg_settings = ffmpeg_settings
|
self.ffmpeg_settings = ffmpeg_settings
|
||||||
|
|
||||||
self.ffmpeg_path = pathlib.Path(self.ffmpeg_settings['ffmpeg_path'])
|
self.ffmpeg_path = pathlib.Path(self.ffmpeg_settings['ffmpeg_path'])
|
||||||
@@ -35,7 +35,7 @@ class Ffmpeg:
|
|||||||
self.ffmpeg_probe_binary = self.ffmpeg_path / 'ffprobe'
|
self.ffmpeg_probe_binary = self.ffmpeg_path / 'ffprobe'
|
||||||
|
|
||||||
# video metadata
|
# video metadata
|
||||||
self.image_format = image_format
|
self.extracted_frame_format = extracted_frame_format
|
||||||
self.intermediate_file_name = pathlib.Path(self.ffmpeg_settings['intermediate_file_name'])
|
self.intermediate_file_name = pathlib.Path(self.ffmpeg_settings['intermediate_file_name'])
|
||||||
self.pixel_format = self.ffmpeg_settings['extract_frames']['output_options']['-pix_fmt']
|
self.pixel_format = self.ffmpeg_settings['extract_frames']['output_options']['-pix_fmt']
|
||||||
|
|
||||||
@@ -133,7 +133,7 @@ class Ffmpeg:
|
|||||||
|
|
||||||
# specify output file
|
# specify output file
|
||||||
execute.extend([
|
execute.extend([
|
||||||
extracted_frames / f'extracted_%0d.{self.image_format}'
|
extracted_frames / f'extracted_%0d.{self.extracted_frame_format}'
|
||||||
])
|
])
|
||||||
|
|
||||||
return(self._execute(execute))
|
return(self._execute(execute))
|
||||||
@@ -174,7 +174,7 @@ class Ffmpeg:
|
|||||||
# append input frames path into command
|
# append input frames path into command
|
||||||
execute.extend([
|
execute.extend([
|
||||||
'-i',
|
'-i',
|
||||||
upscaled_frames / f'extracted_%d.{self.image_format}'
|
upscaled_frames / f'extracted_%d.{self.extracted_frame_format}'
|
||||||
])
|
])
|
||||||
|
|
||||||
# read FFmpeg output options
|
# read FFmpeg output options
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
Name: Gifski Wrapper
|
Name: Gifski Wrapper
|
||||||
Creator: K4YT3X
|
Creator: K4YT3X
|
||||||
Date Created: May 11, 2020
|
Date Created: May 11, 2020
|
||||||
Last Modified: May 11, 2020
|
Last Modified: June 7, 2020
|
||||||
|
|
||||||
Description: High-level wrapper for Gifski.
|
Description: High-level wrapper for Gifski.
|
||||||
"""
|
"""
|
||||||
@@ -22,7 +22,7 @@ class Gifski:
|
|||||||
def __init__(self, gifski_settings):
|
def __init__(self, gifski_settings):
|
||||||
self.gifski_settings = gifski_settings
|
self.gifski_settings = gifski_settings
|
||||||
|
|
||||||
def make_gif(self, upscaled_frames: pathlib.Path, output_path: pathlib.Path, framerate: float, image_format: str) -> subprocess.Popen:
|
def make_gif(self, upscaled_frames: pathlib.Path, output_path: pathlib.Path, framerate: float, extracted_frame_format: str) -> subprocess.Popen:
|
||||||
execute = [
|
execute = [
|
||||||
self.gifski_settings['gifski_path'],
|
self.gifski_settings['gifski_path'],
|
||||||
'-o',
|
'-o',
|
||||||
@@ -35,7 +35,7 @@ class Gifski:
|
|||||||
execute.extend(self._load_configuration())
|
execute.extend(self._load_configuration())
|
||||||
|
|
||||||
# append frames location
|
# append frames location
|
||||||
execute.extend([upscaled_frames / f'extracted_*.{image_format}'])
|
execute.extend([upscaled_frames / f'extracted_*.{extracted_frame_format}'])
|
||||||
|
|
||||||
return(self._execute(execute))
|
return(self._execute(execute))
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
Name: Waifu2x Caffe Driver
|
Name: Waifu2x Caffe Driver
|
||||||
Author: K4YT3X
|
Author: K4YT3X
|
||||||
Date Created: Feb 24, 2018
|
Date Created: Feb 24, 2018
|
||||||
Last Modified: May 11, 2020
|
Last Modified: June 7, 2020
|
||||||
|
|
||||||
Description: This class is a high-level wrapper
|
Description: This class is a high-level wrapper
|
||||||
for waifu2x-caffe.
|
for waifu2x-caffe.
|
||||||
@@ -63,7 +63,7 @@ class WrapperMain:
|
|||||||
def load_configurations(self, upscaler):
|
def load_configurations(self, upscaler):
|
||||||
# use scale width and scale height if specified
|
# use scale width and scale height if specified
|
||||||
self.driver_settings['scale_ratio'] = upscaler.scale_ratio
|
self.driver_settings['scale_ratio'] = upscaler.scale_ratio
|
||||||
self.driver_settings['output_extention'] = upscaler.image_format
|
self.driver_settings['output_extention'] = upscaler.extracted_frame_format
|
||||||
|
|
||||||
# bit_depth will be 12 at this point
|
# bit_depth will be 12 at this point
|
||||||
# it will up updated later
|
# it will up updated later
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
Name: Waifu2x Converter CPP Driver
|
Name: Waifu2x Converter CPP Driver
|
||||||
Author: K4YT3X
|
Author: K4YT3X
|
||||||
Date Created: February 8, 2019
|
Date Created: February 8, 2019
|
||||||
Last Modified: May 11, 2020
|
Last Modified: June 7, 2020
|
||||||
|
|
||||||
Description: This class is a high-level wrapper
|
Description: This class is a high-level wrapper
|
||||||
for waifu2x-converter-cpp.
|
for waifu2x-converter-cpp.
|
||||||
@@ -69,7 +69,7 @@ class WrapperMain:
|
|||||||
def load_configurations(self, upscaler):
|
def load_configurations(self, upscaler):
|
||||||
self.driver_settings['scale-ratio'] = upscaler.scale_ratio
|
self.driver_settings['scale-ratio'] = upscaler.scale_ratio
|
||||||
self.driver_settings['jobs'] = upscaler.processes
|
self.driver_settings['jobs'] = upscaler.processes
|
||||||
self.driver_settings['output-format'] = upscaler.image_format.lower()
|
self.driver_settings['output-format'] = upscaler.extracted_frame_format.lower()
|
||||||
|
|
||||||
def upscale(self, input_directory, output_directory):
|
def upscale(self, input_directory, output_directory):
|
||||||
""" Waifu2x Converter Driver Upscaler
|
""" Waifu2x Converter Driver Upscaler
|
||||||
|
|||||||
Reference in New Issue
Block a user