mirror of
				https://github.com/k4yt3x/video2x.git
				synced 2025-10-30 20:31:11 +01:00 
			
		
		
		
	added arbitrary upscaling ratio/resolution support
This commit is contained in:
		
							parent
							
								
									8b7e9f959b
								
							
						
					
					
						commit
						7059852586
					
				
										
											Binary file not shown.
										
									
								
							
										
											Binary file not shown.
										
									
								
							| @ -5,8 +5,8 @@ | ||||
| msgid "" | ||||
| msgstr "" | ||||
| "Project-Id-Version: \n" | ||||
| "POT-Creation-Date: 2020-05-22 17:51-0400\n" | ||||
| "PO-Revision-Date: 2020-05-22 17:54-0400\n" | ||||
| "POT-Creation-Date: 2020-09-09 13:04-0400\n" | ||||
| "PO-Revision-Date: 2020-09-09 13:06-0400\n" | ||||
| "Last-Translator: \n" | ||||
| "Language-Team: \n" | ||||
| "Language: zh_CN\n" | ||||
| @ -14,234 +14,230 @@ msgstr "" | ||||
| "Content-Type: text/plain; charset=UTF-8\n" | ||||
| "Content-Transfer-Encoding: 8bit\n" | ||||
| "Generated-By: pygettext.py 1.5\n" | ||||
| "X-Generator: Poedit 2.3.1\n" | ||||
| "X-Generator: Poedit 2.4.1\n" | ||||
| "Plural-Forms: nplurals=1; plural=0;\n" | ||||
| 
 | ||||
| #: progress_monitor.py:42 | ||||
| msgid "Upscaling Progress" | ||||
| msgstr "放大进度" | ||||
| #: progress_monitor.py:37 | ||||
| msgid "Processing: {} (pass {}/{})" | ||||
| msgstr "正在处理:{}(进度)" | ||||
| 
 | ||||
| #: upscaler.py:110 | ||||
| #: upscaler.py:144 | ||||
| msgid "Specified or default cache directory is a file/link" | ||||
| msgstr "指定或默认的缓存目录是文件/链接" | ||||
| 
 | ||||
| #: upscaler.py:116 | ||||
| #: upscaler.py:150 | ||||
| msgid "Creating cache directory {}" | ||||
| msgstr "创建缓存目录 {}" | ||||
| 
 | ||||
| #: upscaler.py:119 | ||||
| #: upscaler.py:153 | ||||
| msgid "Unable to create {}" | ||||
| msgstr "无法创建 {}" | ||||
| 
 | ||||
| #: upscaler.py:124 | ||||
| #: upscaler.py:158 | ||||
| msgid "Extracted frames are being saved to: {}" | ||||
| msgstr "提取的帧将被保存到:{}" | ||||
| 
 | ||||
| #: upscaler.py:126 | ||||
| #: upscaler.py:160 | ||||
| msgid "Upscaled frames are being saved to: {}" | ||||
| msgstr "已放大的帧将被保存到:{}" | ||||
| 
 | ||||
| #: upscaler.py:136 | ||||
| #: upscaler.py:170 | ||||
| msgid "Cleaning up cache directory: {}" | ||||
| msgstr "清理缓存目录:{}" | ||||
| 
 | ||||
| #: upscaler.py:141 | ||||
| #: upscaler.py:175 | ||||
| msgid "Unable to delete: {}" | ||||
| msgstr "无法删除:{}" | ||||
| 
 | ||||
| #: upscaler.py:147 upscaler.py:162 upscaler.py:173 | ||||
| #: upscaler.py:181 upscaler.py:196 upscaler.py:207 | ||||
| msgid "Input and output path type mismatch" | ||||
| msgstr "输入和输出路径类型不匹配" | ||||
| 
 | ||||
| #: upscaler.py:148 | ||||
| #: upscaler.py:182 | ||||
| msgid "Input is multiple files but output is not directory" | ||||
| msgstr "输入是多个文件,但输出不是目录" | ||||
| 
 | ||||
| #: upscaler.py:152 | ||||
| #: upscaler.py:186 | ||||
| msgid "Input path {} is neither a file nor a directory" | ||||
| msgstr "输入路径 {} 既不是文件也不是目录" | ||||
| 
 | ||||
| #: upscaler.py:156 upscaler.py:178 | ||||
| #: upscaler.py:190 upscaler.py:212 | ||||
| msgid "Input directory and output directory cannot be the same" | ||||
| msgstr "输入目录和输出目录不能相同" | ||||
| 
 | ||||
| #: upscaler.py:163 | ||||
| #: upscaler.py:197 | ||||
| msgid "Input is single file but output is directory" | ||||
| msgstr "所选的输入路径是单个文件,但输出路径是目录" | ||||
| 
 | ||||
| #: upscaler.py:166 | ||||
| #: upscaler.py:200 | ||||
| msgid "No suffix found in output file path" | ||||
| msgstr "在输出文件路径中未找到后缀" | ||||
| 
 | ||||
| #: upscaler.py:167 | ||||
| #: upscaler.py:201 | ||||
| msgid "Suffix must be specified" | ||||
| msgstr "必须指定文件后缀" | ||||
| 
 | ||||
| #: upscaler.py:174 | ||||
| #: upscaler.py:208 | ||||
| msgid "Input is directory but output is existing single file" | ||||
| msgstr "输入是目录,但输出是现有的单个文件" | ||||
| 
 | ||||
| #: upscaler.py:183 | ||||
| #: upscaler.py:217 | ||||
| msgid "Input path is neither a file nor a directory" | ||||
| msgstr "输入路径既不是文件也不是目录" | ||||
| 
 | ||||
| #: upscaler.py:192 | ||||
| #: upscaler.py:226 | ||||
| msgid "FFmpeg or FFprobe cannot be found under the specified path" | ||||
| msgstr "在指定的路径下找不到 FFmpeg 或 FFprobe" | ||||
| 
 | ||||
| #: upscaler.py:193 upscaler.py:203 | ||||
| #: upscaler.py:227 upscaler.py:237 | ||||
| msgid "Please check the configuration file settings" | ||||
| msgstr "请检查配置文件设置" | ||||
| 
 | ||||
| #: upscaler.py:202 | ||||
| #: upscaler.py:236 | ||||
| msgid "Specified driver executable directory doesn't exist" | ||||
| msgstr "指定驱动的可执行文件不存在" | ||||
| 
 | ||||
| #: upscaler.py:229 | ||||
| #: upscaler.py:263 | ||||
| msgid "Failed to parse driver argument: {}" | ||||
| msgstr "解析驱动程序参数失败:{}" | ||||
| 
 | ||||
| #: upscaler.py:261 | ||||
| #: upscaler.py:283 | ||||
| msgid "Unrecognized driver: {}" | ||||
| msgstr "无法识别的驱动名称:{}" | ||||
| 
 | ||||
| #: upscaler.py:301 | ||||
| #: upscaler.py:323 | ||||
| msgid "Starting progress monitor" | ||||
| msgstr "启动进度监视器" | ||||
| 
 | ||||
| #: upscaler.py:306 | ||||
| #: upscaler.py:328 | ||||
| msgid "Starting upscaled image cleaner" | ||||
| msgstr "启动已放大图像清理程序" | ||||
| 
 | ||||
| #: upscaler.py:315 upscaler.py:332 | ||||
| #: upscaler.py:337 upscaler.py:354 | ||||
| msgid "Killing progress monitor" | ||||
| msgstr "终结进度监视器" | ||||
| 
 | ||||
| #: upscaler.py:318 upscaler.py:335 | ||||
| #: upscaler.py:340 upscaler.py:357 | ||||
| msgid "Killing upscaled image cleaner" | ||||
| msgstr "终结已放大图像清理程序" | ||||
| 
 | ||||
| #: upscaler.py:339 | ||||
| #: upscaler.py:361 | ||||
| msgid "Terminating all processes" | ||||
| msgstr "正在终止所有进程" | ||||
| 
 | ||||
| #: upscaler.py:346 | ||||
| #: upscaler.py:368 | ||||
| msgid "Main process waiting for subprocesses to exit" | ||||
| msgstr "主进程开始等待子进程结束" | ||||
| 
 | ||||
| #: upscaler.py:365 upscaler.py:369 | ||||
| #: upscaler.py:387 upscaler.py:391 | ||||
| msgid "Subprocess {} exited with code {}" | ||||
| msgstr "子进程 {} 结束,返回码 {}" | ||||
| 
 | ||||
| #: upscaler.py:375 | ||||
| #: upscaler.py:397 | ||||
| msgid "Stop signal received" | ||||
| msgstr "收到停止信号" | ||||
| 
 | ||||
| #: upscaler.py:380 | ||||
| #: upscaler.py:402 | ||||
| msgid "Subprocess execution ran into an error" | ||||
| msgstr "子进程执行遇到错误" | ||||
| 
 | ||||
| #: upscaler.py:410 | ||||
| #: upscaler.py:432 | ||||
| msgid "Loading files into processing queue" | ||||
| msgstr "正在将文件添加到处理队列中" | ||||
| 
 | ||||
| #: upscaler.py:415 | ||||
| msgid "Loading files from multiple paths" | ||||
| msgstr "正在从多个路径中导入文件" | ||||
| 
 | ||||
| #: upscaler.py:416 upscaler.py:435 upscaler.py:442 | ||||
| #: upscaler.py:433 | ||||
| msgid "Input path(s): {}" | ||||
| msgstr "输入路径:{}" | ||||
| 
 | ||||
| #: upscaler.py:434 | ||||
| msgid "Loading single file" | ||||
| msgstr "正在导入单个文件" | ||||
| 
 | ||||
| #: upscaler.py:441 | ||||
| msgid "Loading files from directory" | ||||
| msgstr "正在从文件夹中导入文件" | ||||
| 
 | ||||
| #: upscaler.py:455 | ||||
| msgid "Loaded files into processing queue" | ||||
| msgstr "文件已添加到处理队列" | ||||
| 
 | ||||
| #: upscaler.py:458 | ||||
| msgid "Input file: {}" | ||||
| msgstr "输入文件:{}" | ||||
| 
 | ||||
| #: upscaler.py:485 | ||||
| msgid "Starting to upscale image" | ||||
| msgstr "开始放大图像" | ||||
| 
 | ||||
| #: upscaler.py:488 upscaler.py:550 | ||||
| msgid "Upscaling completed" | ||||
| msgstr "放大完成" | ||||
| 
 | ||||
| #: upscaler.py:502 | ||||
| msgid "Reading video information" | ||||
| msgstr "读取视频信息" | ||||
| 
 | ||||
| #: upscaler.py:516 | ||||
| msgid "Aborting: No video stream found" | ||||
| msgstr "程序中止:文件中未找到视频流" | ||||
| 
 | ||||
| #: upscaler.py:521 | ||||
| msgid "Framerate: {}" | ||||
| msgstr "帧率:{}" | ||||
| 
 | ||||
| #: upscaler.py:538 | ||||
| msgid "Unsupported pixel format: {}" | ||||
| msgstr "不支持的像素格式:{}" | ||||
| 
 | ||||
| #: upscaler.py:548 | ||||
| msgid "Starting to upscale extracted frames" | ||||
| msgstr "开始对提取的帧进行放大" | ||||
| 
 | ||||
| #: upscaler.py:555 | ||||
| #: upscaler.py:495 | ||||
| msgid "File {} ({}) neither an image nor a video" | ||||
| msgstr "文件 {} ({}) 既不是图片也不是视频" | ||||
| 
 | ||||
| #: upscaler.py:556 | ||||
| #: upscaler.py:496 | ||||
| msgid "Skipping this file" | ||||
| msgstr "将跳过此文件" | ||||
| 
 | ||||
| #: upscaler.py:566 | ||||
| #: upscaler.py:521 | ||||
| msgid "Loaded files into processing queue" | ||||
| msgstr "文件已添加到处理队列" | ||||
| 
 | ||||
| #: upscaler.py:524 | ||||
| msgid "Input file: {}" | ||||
| msgstr "输入文件:{}" | ||||
| 
 | ||||
| #: upscaler.py:535 | ||||
| msgid "Starting to upscale image" | ||||
| msgstr "开始放大图像" | ||||
| 
 | ||||
| #: upscaler.py:538 upscaler.py:689 | ||||
| msgid "Upscaling completed" | ||||
| msgstr "放大完成" | ||||
| 
 | ||||
| #: upscaler.py:552 | ||||
| msgid "Reading video information" | ||||
| msgstr "读取视频信息" | ||||
| 
 | ||||
| #: upscaler.py:564 | ||||
| msgid "Aborting: No video stream found" | ||||
| msgstr "程序中止:文件中未找到视频流" | ||||
| 
 | ||||
| #: upscaler.py:571 | ||||
| msgid "Framerate: {}" | ||||
| msgstr "帧率:{}" | ||||
| 
 | ||||
| #: upscaler.py:575 | ||||
| msgid "Getting total number of frames in the file" | ||||
| msgstr "正在获取文件中的总帧数" | ||||
| 
 | ||||
| #: upscaler.py:650 | ||||
| msgid "Upscaling jobs queue: {}" | ||||
| msgstr "放大工作队列:{}" | ||||
| 
 | ||||
| #: upscaler.py:666 | ||||
| msgid "Unsupported pixel format: {}" | ||||
| msgstr "不支持的像素格式:{}" | ||||
| 
 | ||||
| #: upscaler.py:676 | ||||
| msgid "Starting to upscale extracted frames" | ||||
| msgstr "开始对提取的帧进行放大" | ||||
| 
 | ||||
| #: upscaler.py:696 | ||||
| msgid "Converting extracted frames into GIF image" | ||||
| msgstr "正在将提取的帧转换为 GIF" | ||||
| 
 | ||||
| #: upscaler.py:570 upscaler.py:579 | ||||
| #: upscaler.py:700 upscaler.py:709 | ||||
| msgid "Conversion completed" | ||||
| msgstr "转换已完成" | ||||
| 
 | ||||
| #: upscaler.py:575 | ||||
| #: upscaler.py:705 | ||||
| msgid "Converting extracted frames into video" | ||||
| msgstr "正在将提取的帧转换为视频" | ||||
| 
 | ||||
| #: upscaler.py:583 | ||||
| #: upscaler.py:713 | ||||
| msgid "Migrating audio, subtitles and other streams to upscaled video" | ||||
| msgstr "正在将音频、字幕和其他流迁移到放大后的视频" | ||||
| 
 | ||||
| #: upscaler.py:593 | ||||
| #: upscaler.py:723 | ||||
| msgid "Failed to migrate streams" | ||||
| msgstr "迁移流失败" | ||||
| 
 | ||||
| #: upscaler.py:594 | ||||
| #: upscaler.py:724 | ||||
| msgid "Trying to output video without additional streams" | ||||
| msgstr "正在尝试输出不含其他流的视频" | ||||
| 
 | ||||
| #: upscaler.py:610 | ||||
| #: upscaler.py:740 | ||||
| msgid "Output video file exists" | ||||
| msgstr "输出目标文件已存在" | ||||
| 
 | ||||
| #: upscaler.py:614 | ||||
| #: upscaler.py:744 | ||||
| msgid "Created temporary directory to contain file" | ||||
| msgstr "为文件创建了临时目录" | ||||
| 
 | ||||
| #: upscaler.py:617 | ||||
| #: upscaler.py:747 | ||||
| msgid "Writing intermediate file to: {}" | ||||
| msgstr "正在将中间视频文件写入至:{}" | ||||
| 
 | ||||
| #: video2x.py:85 | ||||
| #: video2x.py:86 | ||||
| msgid "" | ||||
| "Video2X CLI Version: {}\n" | ||||
| "Upscaler Version: {}\n" | ||||
| @ -257,74 +253,108 @@ msgstr "" | ||||
| "GitHub 主页:https://github.com/k4yt3x/video2x\n" | ||||
| "联系方式:k4yt3x@k4yt3x.com" | ||||
| 
 | ||||
| #: video2x.py:108 | ||||
| #: video2x.py:109 | ||||
| msgid "Video2X Options" | ||||
| msgstr "Video2X 选项" | ||||
| 
 | ||||
| #: video2x.py:109 | ||||
| #: video2x.py:110 | ||||
| msgid "show this help message and exit" | ||||
| msgstr "显示此帮助消息并退出" | ||||
| 
 | ||||
| #: video2x.py:110 | ||||
| #: video2x.py:117 | ||||
| msgid "source video file/directory" | ||||
| msgstr "源视频文件/目录" | ||||
| 
 | ||||
| #: video2x.py:111 | ||||
| #: video2x.py:118 | ||||
| msgid "output video file/directory" | ||||
| msgstr "输出视频文件/目录" | ||||
| 
 | ||||
| #: video2x.py:112 | ||||
| #: video2x.py:120 | ||||
| msgid "video2x config file path" | ||||
| msgstr "video2x 配置文件路径" | ||||
| 
 | ||||
| #: video2x.py:114 | ||||
| #: video2x.py:122 | ||||
| msgid "log file path" | ||||
| msgstr "日志文件路径" | ||||
| 
 | ||||
| #: video2x.py:124 | ||||
| msgid "disable logging" | ||||
| msgstr "禁用日志" | ||||
| 
 | ||||
| #: video2x.py:125 | ||||
| msgid "display version, lawful information and exit" | ||||
| msgstr "显示版本和法律信息并退出" | ||||
| 
 | ||||
| #: video2x.py:117 | ||||
| #: video2x.py:128 | ||||
| msgid "Upscaling Options" | ||||
| msgstr "视频放大选项" | ||||
| 
 | ||||
| #: video2x.py:118 | ||||
| msgid "upscaling driver" | ||||
| msgstr "视频放大驱动" | ||||
| 
 | ||||
| #: video2x.py:119 | ||||
| #: video2x.py:129 | ||||
| msgid "scaling ratio" | ||||
| msgstr "缩放比" | ||||
| 
 | ||||
| #: video2x.py:120 | ||||
| #: video2x.py:130 | ||||
| msgid "output width" | ||||
| msgstr "输出宽度" | ||||
| 
 | ||||
| #: video2x.py:131 | ||||
| msgid "output height" | ||||
| msgstr "输出高度" | ||||
| 
 | ||||
| #: video2x.py:132 | ||||
| msgid "upscaling driver" | ||||
| msgstr "视频放大驱动" | ||||
| 
 | ||||
| #: video2x.py:133 | ||||
| msgid "number of processes to use for upscaling" | ||||
| msgstr "并发进程数" | ||||
| 
 | ||||
| #: video2x.py:121 | ||||
| #: video2x.py:134 | ||||
| msgid "preserve extracted and upscaled frames" | ||||
| msgstr "保留提取的和放大的帧" | ||||
| 
 | ||||
| #: video2x.py:161 | ||||
| #: video2x.py:174 | ||||
| msgid "This file cannot be imported" | ||||
| msgstr "此文件无法被当作模块导入" | ||||
| 
 | ||||
| #: video2x.py:236 | ||||
| #: video2x.py:190 | ||||
| msgid "Specify either scaling ratio or scaling resolution, not both" | ||||
| msgstr "您只能指定缩放比或输出分辨率两者之一" | ||||
| 
 | ||||
| #: video2x.py:194 | ||||
| msgid "Only one of scaling width and scaling height is specified" | ||||
| msgstr "输出高度和宽度仅有其中一项被指定" | ||||
| 
 | ||||
| #: video2x.py:200 | ||||
| msgid "Redirecting console logs to {}" | ||||
| msgstr "将控制台日志重定向到 {}" | ||||
| 
 | ||||
| #: video2x.py:276 | ||||
| msgid "Program completed, taking {} seconds" | ||||
| msgstr "程序执行完毕,总计花费 {} 秒" | ||||
| 
 | ||||
| #: video2x.py:239 | ||||
| #: video2x.py:279 | ||||
| msgid "An exception has occurred" | ||||
| msgstr "发生了异常" | ||||
| 
 | ||||
| #~ msgid "Upscaling Progress" | ||||
| #~ msgstr "放大进度" | ||||
| 
 | ||||
| #~ msgid "Loading files from multiple paths" | ||||
| #~ msgstr "正在从多个路径中导入文件" | ||||
| 
 | ||||
| #~ msgid "Loading single file" | ||||
| #~ msgstr "正在导入单个文件" | ||||
| 
 | ||||
| #~ msgid "Loading files from directory" | ||||
| #~ msgstr "正在从文件夹中导入文件" | ||||
| 
 | ||||
| #~ msgid "Anime4KCPP doesn't yet support GIF processing" | ||||
| #~ msgstr "Anime4KCPP 尚不支持GIF处理" | ||||
| 
 | ||||
| #~ msgid "Starting to upscale video with Anime4KCPP" | ||||
| #~ msgstr "开始用 Anime4KCPP 放大视频" | ||||
| 
 | ||||
| #~ msgid "output video width" | ||||
| #~ msgstr "输出视频宽度" | ||||
| 
 | ||||
| #~ msgid "output video height" | ||||
| #~ msgstr "输出视频高度" | ||||
| 
 | ||||
| #~ msgid "You must specify input video file/directory path" | ||||
| #~ msgstr "您必须指定输入视频文件/目录路径" | ||||
| 
 | ||||
| @ -340,8 +370,5 @@ msgstr "发生了异常" | ||||
| #~ msgid "Scaling ratio must be one of 2, 3 or 4 for srmd_ncnn_vulkan" | ||||
| #~ msgstr "srmd_ncnn_vulkan 的缩放比必须为 2、3 或 4" | ||||
| 
 | ||||
| #~ msgid "You can only specify either scaling ratio or output width and height" | ||||
| #~ msgstr "您只能指定缩放比或输出宽度和高度两者之一" | ||||
| 
 | ||||
| #~ msgid "You must specify both width and height" | ||||
| #~ msgstr "您必须同时指定宽度和高度" | ||||
|  | ||||
| @ -4,7 +4,7 @@ | ||||
| Name: Video2X Upscale Progress Monitor | ||||
| Author: K4YT3X | ||||
| Date Created: May 7, 2020 | ||||
| Last Modified: June 7, 2020 | ||||
| Last Modified: September 9, 2020 | ||||
| """ | ||||
| 
 | ||||
| # built-in imports | ||||
| @ -34,12 +34,7 @@ class ProgressMonitor(threading.Thread): | ||||
|     def run(self): | ||||
|         self.running = True | ||||
| 
 | ||||
|         # get number of extracted frames | ||||
|         self.upscaler.total_frames = 0 | ||||
|         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.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=_('Processing: {} (pass {}/{})').format(self.upscaler.current_input_file.name, self.upscaler.current_pass, len(self.upscaler.scaling_jobs))) as progress_bar: | ||||
|             # tqdm update method adds the value to the progress | ||||
|             # bar instead of setting the value. Therefore, a delta | ||||
|             # needs to be calculated. | ||||
|  | ||||
							
								
								
									
										154
									
								
								src/upscaler.py
									
									
									
									
									
								
							
							
						
						
									
										154
									
								
								src/upscaler.py
									
									
									
									
									
								
							| @ -4,7 +4,7 @@ | ||||
| Name: Video2X Upscaler | ||||
| Author: K4YT3X | ||||
| Date Created: December 10, 2018 | ||||
| Last Modified: June 29, 2020 | ||||
| Last Modified: September 9, 2020 | ||||
| 
 | ||||
| Description: This file contains the Upscaler class. Each | ||||
| instance of the Upscaler class is an upscaler on an image or | ||||
| @ -25,6 +25,7 @@ import copy | ||||
| import gettext | ||||
| import importlib | ||||
| import locale | ||||
| import math | ||||
| import mimetypes | ||||
| import pathlib | ||||
| import queue | ||||
| @ -50,7 +51,7 @@ language.install() | ||||
| _ = language.gettext | ||||
| 
 | ||||
| # version information | ||||
| UPSCALER_VERSION = '4.2.2' | ||||
| UPSCALER_VERSION = '4.3.0' | ||||
| 
 | ||||
| # these names are consistent for | ||||
| # - driver selection in command line | ||||
| @ -63,6 +64,12 @@ AVAILABLE_DRIVERS = ['waifu2x_caffe', | ||||
|                      'realsr_ncnn_vulkan', | ||||
|                      'anime4kcpp'] | ||||
| 
 | ||||
| DRIVER_FIXED_SCALING_RATIOS = { | ||||
|     'waifu2x_ncnn_vulkan': [1, 2], | ||||
|     'srmd_ncnn_vulkan': [2, 3, 4], | ||||
|     'realsr_ncnn_vulkan': [4], | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| class Upscaler: | ||||
|     """ An instance of this class is a upscaler that will | ||||
| @ -82,6 +89,8 @@ class Upscaler: | ||||
|         gifski_settings: dict, | ||||
|         driver: str = 'waifu2x_caffe', | ||||
|         scale_ratio: float = None, | ||||
|         scale_width: int = None, | ||||
|         scale_height: int = None, | ||||
|         processes: int = 1, | ||||
|         video2x_cache_directory: pathlib.Path = pathlib.Path(tempfile.gettempdir()) / 'video2x', | ||||
|         extracted_frame_format: str = 'png', | ||||
| @ -101,6 +110,8 @@ class Upscaler: | ||||
|         # optional parameters | ||||
|         self.driver = driver | ||||
|         self.scale_ratio = scale_ratio | ||||
|         self.scale_width = scale_width | ||||
|         self.scale_height = scale_height | ||||
|         self.processes = processes | ||||
|         self.video2x_cache_directory = video2x_cache_directory | ||||
|         self.extracted_frame_format = extracted_frame_format | ||||
| @ -115,6 +126,8 @@ class Upscaler: | ||||
|         self.total_frames = 0 | ||||
|         self.total_files = 0 | ||||
|         self.total_processed = 0 | ||||
|         self.scaling_jobs = [] | ||||
|         self.current_pass = 0 | ||||
|         self.current_input_file = pathlib.Path() | ||||
|         self.last_frame_upscaled = pathlib.Path() | ||||
| 
 | ||||
| @ -250,31 +263,19 @@ class Upscaler: | ||||
|             Avalon.error(_('Failed to parse driver argument: {}').format(e.args[0])) | ||||
|             raise e | ||||
| 
 | ||||
|         # waifu2x-caffe scale_ratio, scale_width and scale_height check | ||||
|         if self.driver == 'waifu2x_caffe': | ||||
|             if (driver_settings['scale_width'] != 0 and driver_settings['scale_height'] == 0 or | ||||
|                     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')) | ||||
|                 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 | ||||
|             elif self.driver_settings['scale_width'] != 0 and self.driver_settings['scale_height'] != 0: | ||||
|                 self.driver_settings['scale_ratio'] = None | ||||
| 
 | ||||
|             # if scale_width and scale_height not specified | ||||
|             # ensure they are None, not 0 | ||||
|             else: | ||||
|                 self.driver_settings['scale_width'] = None | ||||
|                 self.driver_settings['scale_height'] = None | ||||
| 
 | ||||
|     def _upscale_frames(self): | ||||
|     def _upscale_frames(self, input_directory: pathlib.Path, output_directory: pathlib.Path): | ||||
|         """ Upscale video frames with waifu2x-caffe | ||||
| 
 | ||||
|         This function upscales all the frames extracted | ||||
|         by ffmpeg using the waifu2x-caffe binary. | ||||
| 
 | ||||
|         Arguments: | ||||
|             w2 {Waifu2x Object} -- initialized waifu2x object | ||||
|         Args: | ||||
|             input_directory (pathlib.Path): directory containing frames to upscale | ||||
|             output_directory (pathlib.Path): directory which upscaled frames should be exported to | ||||
| 
 | ||||
|         Raises: | ||||
|             UnrecognizedDriverError: raised when the given driver is not recognized | ||||
|             e: re-raised exception after an exception has been captured and finished processing in this scope | ||||
|         """ | ||||
| 
 | ||||
|         # initialize waifu2x driver | ||||
| @ -282,7 +283,7 @@ class Upscaler: | ||||
|             raise UnrecognizedDriverError(_('Unrecognized driver: {}').format(self.driver)) | ||||
| 
 | ||||
|         # list all images in the extracted frames | ||||
|         frames = [(self.extracted_frames / f) for f in self.extracted_frames.iterdir() if f.is_file] | ||||
|         frames = [(input_directory / f) for f in input_directory.iterdir() if f.is_file] | ||||
| 
 | ||||
|         # if we have less images than processes, | ||||
|         # create only the processes necessary | ||||
| @ -293,7 +294,7 @@ class Upscaler: | ||||
|         # name into a list | ||||
|         process_directories = [] | ||||
|         for process_id in range(self.processes): | ||||
|             process_directory = self.extracted_frames / str(process_id) | ||||
|             process_directory = input_directory / str(process_id) | ||||
|             process_directories.append(process_directory) | ||||
| 
 | ||||
|             # delete old directories and create new directories | ||||
| @ -303,7 +304,7 @@ class Upscaler: | ||||
| 
 | ||||
|         # waifu2x-converter-cpp will perform multi-threading within its own process | ||||
|         if self.driver in ['waifu2x_converter_cpp', 'waifu2x_ncnn_vulkan', 'srmd_ncnn_vulkan', 'realsr_ncnn_vulkan', 'anime4kcpp']: | ||||
|             process_directories = [self.extracted_frames] | ||||
|             process_directories = [input_directory] | ||||
| 
 | ||||
|         else: | ||||
|             # evenly distribute images into each directory | ||||
| @ -316,7 +317,7 @@ class Upscaler: | ||||
| 
 | ||||
|         # create driver processes and start them | ||||
|         for process_directory in process_directories: | ||||
|             self.process_pool.append(self.driver_object.upscale(process_directory, self.upscaled_frames)) | ||||
|             self.process_pool.append(self.driver_object.upscale(process_directory, output_directory)) | ||||
| 
 | ||||
|         # start progress bar in a different thread | ||||
|         Avalon.debug_info(_('Starting progress monitor')) | ||||
| @ -325,7 +326,7 @@ class Upscaler: | ||||
| 
 | ||||
|         # create the clearer and start it | ||||
|         Avalon.debug_info(_('Starting upscaled image cleaner')) | ||||
|         self.image_cleaner = ImageCleaner(self.extracted_frames, self.upscaled_frames, len(self.process_pool)) | ||||
|         self.image_cleaner = ImageCleaner(input_directory, output_directory, len(self.process_pool)) | ||||
|         self.image_cleaner.start() | ||||
| 
 | ||||
|         # wait for all process to exit | ||||
| @ -343,11 +344,11 @@ class Upscaler: | ||||
|         # if the driver is waifu2x-converter-cpp | ||||
|         # images need to be renamed to be recognizable for FFmpeg | ||||
|         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 output_directory.iterdir() if f.is_file()]: | ||||
|                 renamed = re.sub(f'_\\[.*\\]\\[x(\\d+(\\.\\d+)?)\\]\\.{self.extracted_frame_format}', | ||||
|                                  f'.{self.extracted_frame_format}', | ||||
|                                  str(image.name)) | ||||
|                 (self.upscaled_frames / image).rename(self.upscaled_frames / renamed) | ||||
|                 (output_directory / image).rename(output_directory / renamed) | ||||
| 
 | ||||
|         # upscaling done, kill helper threads | ||||
|         Avalon.debug_info(_('Killing progress monitor')) | ||||
| @ -550,8 +551,6 @@ class Upscaler: | ||||
|                     # get video information JSON using FFprobe | ||||
|                     Avalon.info(_('Reading video information')) | ||||
|                     video_info = self.ffmpeg_object.probe_file_info(self.current_input_file) | ||||
|                     # analyze original video with FFprobe and retrieve framerate | ||||
|                     # width, height = info['streams'][0]['width'], info['streams'][0]['height'] | ||||
| 
 | ||||
|                     # find index of video stream | ||||
|                     video_stream_index = None | ||||
| @ -567,9 +566,89 @@ class Upscaler: | ||||
| 
 | ||||
|                     # get average frame rate of video stream | ||||
|                     framerate = float(Fraction(video_info['streams'][video_stream_index]['r_frame_rate'])) | ||||
|                     width = int(video_info['streams'][video_stream_index]['width']) | ||||
|                     height = int(video_info['streams'][video_stream_index]['height']) | ||||
|                     Avalon.info(_('Framerate: {}').format(framerate)) | ||||
|                     # self.ffmpeg_object.pixel_format = video_info['streams'][video_stream_index]['pix_fmt'] | ||||
| 
 | ||||
|                     # get total number of frames | ||||
|                     Avalon.info(_('Getting total number of frames in the file')) | ||||
| 
 | ||||
|                     # if container stores total number of frames in nb_frames, fetch it directly | ||||
|                     if 'nb_frames' in video_info['streams'][video_stream_index]: | ||||
|                         self.total_frames = int(video_info['streams'][video_stream_index]['nb_frames']) | ||||
| 
 | ||||
|                     # otherwise call FFprobe to count the total number of frames | ||||
|                     else: | ||||
|                         self.total_frames = self.ffmpeg_object.get_number_of_frames(self.current_input_file, video_stream_index) | ||||
| 
 | ||||
|                     # if driver is one of the drivers that doesn't support arbitrary scaling ratio | ||||
|                     # TODO: more documentations on this block | ||||
|                     if self.driver in DRIVER_FIXED_SCALING_RATIOS: | ||||
| 
 | ||||
|                         # if user specified output resolution | ||||
|                         # calculate number of passes needed | ||||
|                         if self.scale_width is not None and self.scale_height is not None: | ||||
|                             self.scale_ratio = 2 | ||||
| 
 | ||||
|                             # when scaled output resolution is smaller than target output resolution | ||||
|                             # increase scaling ratio | ||||
|                             while (self.scale_ratio * width) < self.scale_width: | ||||
|                                 self.scale_ratio += 1 | ||||
| 
 | ||||
|                             while (self.scale_ratio * height) < self.scale_height: | ||||
|                                 self.scale_ratio += 1 | ||||
| 
 | ||||
|                         # select the optimal driver scaling ratio to use | ||||
|                         supported_scaling_ratios = sorted(DRIVER_FIXED_SCALING_RATIOS[self.driver]) | ||||
| 
 | ||||
|                         remaining_scaling_ratio = math.ceil(self.scale_ratio) | ||||
|                         self.scaling_jobs = [] | ||||
| 
 | ||||
|                         while remaining_scaling_ratio > 1: | ||||
|                             for ratio in supported_scaling_ratios: | ||||
|                                 if ratio >= remaining_scaling_ratio: | ||||
|                                     self.scaling_jobs.append(ratio) | ||||
|                                     remaining_scaling_ratio /= ratio | ||||
|                                     break | ||||
| 
 | ||||
|                             else: | ||||
| 
 | ||||
|                                 found = False | ||||
|                                 for i in supported_scaling_ratios: | ||||
|                                     for j in supported_scaling_ratios: | ||||
|                                         if i * j >= remaining_scaling_ratio: | ||||
|                                             self.scaling_jobs.extend([i, j]) | ||||
|                                             remaining_scaling_ratio /= i * j | ||||
|                                             found = True | ||||
|                                             break | ||||
|                                     if found is True: | ||||
|                                         break | ||||
| 
 | ||||
|                                 if found is False: | ||||
|                                     self.scaling_jobs.append(supported_scaling_ratios[-1]) | ||||
|                                     remaining_scaling_ratio /= supported_scaling_ratios[-1] | ||||
| 
 | ||||
|                         # calculate and set output bicubic downscaling filter | ||||
|                         # always ensure that the output resolution is divisible by 2 | ||||
|                         if self.scale_width is not None and self.scale_height is not None: | ||||
|                             output_width = math.ceil(self.scale_width / 2.0) * 2 | ||||
|                             output_height = math.ceil(self.scale_height / 2.0) * 2 | ||||
|                         else: | ||||
|                             output_width = math.ceil(width * self.scale_ratio / 2.0) * 2 | ||||
|                             output_height = math.ceil(height * self.scale_ratio / 2.0) * 2 | ||||
| 
 | ||||
|                         # append scaling filter to video assembly command | ||||
|                         if self.ffmpeg_settings['assemble_video']['output_options'].get('-vf') is None: | ||||
|                             self.ffmpeg_settings['assemble_video']['output_options']['-vf'] = f'scale={output_width}:{output_height}' | ||||
|                         else: | ||||
|                             self.ffmpeg_settings['assemble_video']['output_options']['-vf'] += f',scale={output_width}:{output_height}' | ||||
| 
 | ||||
|                     else: | ||||
|                         self.scaling_jobs = [self.scale_ratio] | ||||
| 
 | ||||
|                     Avalon.debug_info(_('Upscaling jobs queue: {}').format(self.scaling_jobs)) | ||||
| 
 | ||||
|                     # extract frames from video | ||||
|                     self.process_pool.append((self.ffmpeg_object.extract_frames(self.current_input_file, self.extracted_frames))) | ||||
|                     self._wait() | ||||
| @ -595,7 +674,18 @@ class Upscaler: | ||||
| 
 | ||||
|                     # upscale images one by one using waifu2x | ||||
|                     Avalon.info(_('Starting to upscale extracted frames')) | ||||
|                     self._upscale_frames() | ||||
| 
 | ||||
|                     self.current_pass = 1 | ||||
|                     self.driver_object.set_scale_ratio(self.scaling_jobs[0]) | ||||
|                     self._upscale_frames(self.extracted_frames, self.upscaled_frames) | ||||
|                     for job in self.scaling_jobs[1:]: | ||||
|                         self.current_pass += 1 | ||||
|                         self.driver_object.set_scale_ratio(job) | ||||
|                         shutil.rmtree(self.extracted_frames) | ||||
|                         shutil.move(self.upscaled_frames, self.extracted_frames) | ||||
|                         self.upscaled_frames.mkdir(parents=True, exist_ok=True) | ||||
|                         self._upscale_frames(self.extracted_frames, self.upscaled_frames) | ||||
| 
 | ||||
|                     Avalon.info(_('Upscaling completed')) | ||||
| 
 | ||||
|                 # start handling output | ||||
|  | ||||
							
								
								
									
										250
									
								
								src/video2x.pot
									
									
									
									
									
								
							
							
						
						
									
										250
									
								
								src/video2x.pot
									
									
									
									
									
								
							| @ -5,7 +5,7 @@ | ||||
| msgid "" | ||||
| msgstr "" | ||||
| "Project-Id-Version: PACKAGE VERSION\n" | ||||
| "POT-Creation-Date: 2020-05-22 17:51-0400\n" | ||||
| "POT-Creation-Date: 2020-09-09 13:04-0400\n" | ||||
| "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" | ||||
| "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" | ||||
| "Language-Team: LANGUAGE <LL@li.org>\n" | ||||
| @ -15,231 +15,227 @@ msgstr "" | ||||
| "Generated-By: pygettext.py 1.5\n" | ||||
| 
 | ||||
| 
 | ||||
| #: progress_monitor.py:42 | ||||
| msgid "Upscaling Progress" | ||||
| #: progress_monitor.py:37 | ||||
| msgid "Processing: {} (pass {}/{})" | ||||
| msgstr "" | ||||
| 
 | ||||
| #: upscaler.py:110 | ||||
| #: upscaler.py:144 | ||||
| msgid "Specified or default cache directory is a file/link" | ||||
| msgstr "" | ||||
| 
 | ||||
| #: upscaler.py:116 | ||||
| #: upscaler.py:150 | ||||
| msgid "Creating cache directory {}" | ||||
| msgstr "" | ||||
| 
 | ||||
| #: upscaler.py:119 | ||||
| #: upscaler.py:153 | ||||
| msgid "Unable to create {}" | ||||
| msgstr "" | ||||
| 
 | ||||
| #: upscaler.py:124 | ||||
| #: upscaler.py:158 | ||||
| msgid "Extracted frames are being saved to: {}" | ||||
| msgstr "" | ||||
| 
 | ||||
| #: upscaler.py:126 | ||||
| #: upscaler.py:160 | ||||
| msgid "Upscaled frames are being saved to: {}" | ||||
| msgstr "" | ||||
| 
 | ||||
| #: upscaler.py:136 | ||||
| #: upscaler.py:170 | ||||
| msgid "Cleaning up cache directory: {}" | ||||
| msgstr "" | ||||
| 
 | ||||
| #: upscaler.py:141 | ||||
| #: upscaler.py:175 | ||||
| msgid "Unable to delete: {}" | ||||
| msgstr "" | ||||
| 
 | ||||
| #: upscaler.py:147 upscaler.py:162 upscaler.py:173 | ||||
| #: upscaler.py:181 upscaler.py:196 upscaler.py:207 | ||||
| msgid "Input and output path type mismatch" | ||||
| msgstr "" | ||||
| 
 | ||||
| #: upscaler.py:148 | ||||
| #: upscaler.py:182 | ||||
| msgid "Input is multiple files but output is not directory" | ||||
| msgstr "" | ||||
| 
 | ||||
| #: upscaler.py:152 | ||||
| #: upscaler.py:186 | ||||
| msgid "Input path {} is neither a file nor a directory" | ||||
| msgstr "" | ||||
| 
 | ||||
| #: upscaler.py:156 upscaler.py:178 | ||||
| #: upscaler.py:190 upscaler.py:212 | ||||
| msgid "Input directory and output directory cannot be the same" | ||||
| msgstr "" | ||||
| 
 | ||||
| #: upscaler.py:163 | ||||
| #: upscaler.py:197 | ||||
| msgid "Input is single file but output is directory" | ||||
| msgstr "" | ||||
| 
 | ||||
| #: upscaler.py:166 | ||||
| #: upscaler.py:200 | ||||
| msgid "No suffix found in output file path" | ||||
| msgstr "" | ||||
| 
 | ||||
| #: upscaler.py:167 | ||||
| #: upscaler.py:201 | ||||
| msgid "Suffix must be specified" | ||||
| msgstr "" | ||||
| 
 | ||||
| #: upscaler.py:174 | ||||
| #: upscaler.py:208 | ||||
| msgid "Input is directory but output is existing single file" | ||||
| msgstr "" | ||||
| 
 | ||||
| #: upscaler.py:183 | ||||
| #: upscaler.py:217 | ||||
| msgid "Input path is neither a file nor a directory" | ||||
| msgstr "" | ||||
| 
 | ||||
| #: upscaler.py:192 | ||||
| #: upscaler.py:226 | ||||
| msgid "FFmpeg or FFprobe cannot be found under the specified path" | ||||
| msgstr "" | ||||
| 
 | ||||
| #: upscaler.py:193 upscaler.py:203 | ||||
| #: upscaler.py:227 upscaler.py:237 | ||||
| msgid "Please check the configuration file settings" | ||||
| msgstr "" | ||||
| 
 | ||||
| #: upscaler.py:202 | ||||
| #: upscaler.py:236 | ||||
| msgid "Specified driver executable directory doesn't exist" | ||||
| msgstr "" | ||||
| 
 | ||||
| #: upscaler.py:229 | ||||
| #: upscaler.py:263 | ||||
| msgid "Failed to parse driver argument: {}" | ||||
| msgstr "" | ||||
| 
 | ||||
| #: upscaler.py:261 | ||||
| #: upscaler.py:283 | ||||
| msgid "Unrecognized driver: {}" | ||||
| msgstr "" | ||||
| 
 | ||||
| #: upscaler.py:301 | ||||
| #: upscaler.py:323 | ||||
| msgid "Starting progress monitor" | ||||
| msgstr "" | ||||
| 
 | ||||
| #: upscaler.py:306 | ||||
| #: upscaler.py:328 | ||||
| msgid "Starting upscaled image cleaner" | ||||
| msgstr "" | ||||
| 
 | ||||
| #: upscaler.py:315 upscaler.py:332 | ||||
| #: upscaler.py:337 upscaler.py:354 | ||||
| msgid "Killing progress monitor" | ||||
| msgstr "" | ||||
| 
 | ||||
| #: upscaler.py:318 upscaler.py:335 | ||||
| #: upscaler.py:340 upscaler.py:357 | ||||
| msgid "Killing upscaled image cleaner" | ||||
| msgstr "" | ||||
| 
 | ||||
| #: upscaler.py:339 | ||||
| #: upscaler.py:361 | ||||
| msgid "Terminating all processes" | ||||
| msgstr "" | ||||
| 
 | ||||
| #: upscaler.py:346 | ||||
| #: upscaler.py:368 | ||||
| msgid "Main process waiting for subprocesses to exit" | ||||
| msgstr "" | ||||
| 
 | ||||
| #: upscaler.py:365 upscaler.py:369 | ||||
| #: upscaler.py:387 upscaler.py:391 | ||||
| msgid "Subprocess {} exited with code {}" | ||||
| msgstr "" | ||||
| 
 | ||||
| #: upscaler.py:375 | ||||
| #: upscaler.py:397 | ||||
| msgid "Stop signal received" | ||||
| msgstr "" | ||||
| 
 | ||||
| #: upscaler.py:380 | ||||
| #: upscaler.py:402 | ||||
| msgid "Subprocess execution ran into an error" | ||||
| msgstr "" | ||||
| 
 | ||||
| #: upscaler.py:410 | ||||
| #: upscaler.py:432 | ||||
| msgid "Loading files into processing queue" | ||||
| msgstr "" | ||||
| 
 | ||||
| #: upscaler.py:415 | ||||
| msgid "Loading files from multiple paths" | ||||
| msgstr "" | ||||
| 
 | ||||
| #: upscaler.py:416 upscaler.py:435 upscaler.py:442 | ||||
| #: upscaler.py:433 | ||||
| msgid "Input path(s): {}" | ||||
| msgstr "" | ||||
| 
 | ||||
| #: upscaler.py:434 | ||||
| msgid "Loading single file" | ||||
| msgstr "" | ||||
| 
 | ||||
| #: upscaler.py:441 | ||||
| msgid "Loading files from directory" | ||||
| msgstr "" | ||||
| 
 | ||||
| #: upscaler.py:455 | ||||
| msgid "Loaded files into processing queue" | ||||
| msgstr "" | ||||
| 
 | ||||
| #: upscaler.py:458 | ||||
| msgid "Input file: {}" | ||||
| msgstr "" | ||||
| 
 | ||||
| #: upscaler.py:485 | ||||
| msgid "Starting to upscale image" | ||||
| msgstr "" | ||||
| 
 | ||||
| #: upscaler.py:488 upscaler.py:550 | ||||
| msgid "Upscaling completed" | ||||
| msgstr "" | ||||
| 
 | ||||
| #: upscaler.py:502 | ||||
| msgid "Reading video information" | ||||
| msgstr "" | ||||
| 
 | ||||
| #: upscaler.py:516 | ||||
| msgid "Aborting: No video stream found" | ||||
| msgstr "" | ||||
| 
 | ||||
| #: upscaler.py:521 | ||||
| msgid "Framerate: {}" | ||||
| msgstr "" | ||||
| 
 | ||||
| #: upscaler.py:538 | ||||
| msgid "Unsupported pixel format: {}" | ||||
| msgstr "" | ||||
| 
 | ||||
| #: upscaler.py:548 | ||||
| msgid "Starting to upscale extracted frames" | ||||
| msgstr "" | ||||
| 
 | ||||
| #: upscaler.py:555 | ||||
| #: upscaler.py:495 | ||||
| msgid "File {} ({}) neither an image nor a video" | ||||
| msgstr "" | ||||
| 
 | ||||
| #: upscaler.py:556 | ||||
| #: upscaler.py:496 | ||||
| msgid "Skipping this file" | ||||
| msgstr "" | ||||
| 
 | ||||
| #: upscaler.py:566 | ||||
| msgid "Converting extracted frames into GIF image" | ||||
| #: upscaler.py:521 | ||||
| msgid "Loaded files into processing queue" | ||||
| msgstr "" | ||||
| 
 | ||||
| #: upscaler.py:570 upscaler.py:579 | ||||
| msgid "Conversion completed" | ||||
| #: upscaler.py:524 | ||||
| msgid "Input file: {}" | ||||
| msgstr "" | ||||
| 
 | ||||
| #: upscaler.py:535 | ||||
| msgid "Starting to upscale image" | ||||
| msgstr "" | ||||
| 
 | ||||
| #: upscaler.py:538 upscaler.py:689 | ||||
| msgid "Upscaling completed" | ||||
| msgstr "" | ||||
| 
 | ||||
| #: upscaler.py:552 | ||||
| msgid "Reading video information" | ||||
| msgstr "" | ||||
| 
 | ||||
| #: upscaler.py:564 | ||||
| msgid "Aborting: No video stream found" | ||||
| msgstr "" | ||||
| 
 | ||||
| #: upscaler.py:571 | ||||
| msgid "Framerate: {}" | ||||
| msgstr "" | ||||
| 
 | ||||
| #: upscaler.py:575 | ||||
| msgid "Getting total number of frames in the file" | ||||
| msgstr "" | ||||
| 
 | ||||
| #: upscaler.py:650 | ||||
| msgid "Upscaling jobs queue: {}" | ||||
| msgstr "" | ||||
| 
 | ||||
| #: upscaler.py:666 | ||||
| msgid "Unsupported pixel format: {}" | ||||
| msgstr "" | ||||
| 
 | ||||
| #: upscaler.py:676 | ||||
| msgid "Starting to upscale extracted frames" | ||||
| msgstr "" | ||||
| 
 | ||||
| #: upscaler.py:696 | ||||
| msgid "Converting extracted frames into GIF image" | ||||
| msgstr "" | ||||
| 
 | ||||
| #: upscaler.py:700 upscaler.py:709 | ||||
| msgid "Conversion completed" | ||||
| msgstr "" | ||||
| 
 | ||||
| #: upscaler.py:705 | ||||
| msgid "Converting extracted frames into video" | ||||
| msgstr "" | ||||
| 
 | ||||
| #: upscaler.py:583 | ||||
| #: upscaler.py:713 | ||||
| msgid "Migrating audio, subtitles and other streams to upscaled video" | ||||
| msgstr "" | ||||
| 
 | ||||
| #: upscaler.py:593 | ||||
| #: upscaler.py:723 | ||||
| msgid "Failed to migrate streams" | ||||
| msgstr "" | ||||
| 
 | ||||
| #: upscaler.py:594 | ||||
| #: upscaler.py:724 | ||||
| msgid "Trying to output video without additional streams" | ||||
| msgstr "" | ||||
| 
 | ||||
| #: upscaler.py:610 | ||||
| #: upscaler.py:740 | ||||
| msgid "Output video file exists" | ||||
| msgstr "" | ||||
| 
 | ||||
| #: upscaler.py:614 | ||||
| #: upscaler.py:744 | ||||
| msgid "Created temporary directory to contain file" | ||||
| msgstr "" | ||||
| 
 | ||||
| #: upscaler.py:617 | ||||
| #: upscaler.py:747 | ||||
| msgid "Writing intermediate file to: {}" | ||||
| msgstr "" | ||||
| 
 | ||||
| #: video2x.py:85 | ||||
| #: video2x.py:86 | ||||
| msgid "" | ||||
| "Video2X CLI Version: {}\n" | ||||
| "Upscaler Version: {}\n" | ||||
| @ -249,59 +245,87 @@ msgid "" | ||||
| "Contact: k4yt3x@k4yt3x.com" | ||||
| msgstr "" | ||||
| 
 | ||||
| #: video2x.py:108 | ||||
| #: video2x.py:109 | ||||
| msgid "Video2X Options" | ||||
| msgstr "" | ||||
| 
 | ||||
| #: video2x.py:109 | ||||
| #: video2x.py:110 | ||||
| msgid "show this help message and exit" | ||||
| msgstr "" | ||||
| 
 | ||||
| #: video2x.py:110 | ||||
| #: video2x.py:117 | ||||
| msgid "source video file/directory" | ||||
| msgstr "" | ||||
| 
 | ||||
| #: video2x.py:111 | ||||
| #: video2x.py:118 | ||||
| msgid "output video file/directory" | ||||
| msgstr "" | ||||
| 
 | ||||
| #: video2x.py:112 | ||||
| #: video2x.py:120 | ||||
| msgid "video2x config file path" | ||||
| msgstr "" | ||||
| 
 | ||||
| #: video2x.py:114 | ||||
| #: video2x.py:122 | ||||
| msgid "log file path" | ||||
| msgstr "" | ||||
| 
 | ||||
| #: video2x.py:124 | ||||
| msgid "disable logging" | ||||
| msgstr "" | ||||
| 
 | ||||
| #: video2x.py:125 | ||||
| msgid "display version, lawful information and exit" | ||||
| msgstr "" | ||||
| 
 | ||||
| #: video2x.py:117 | ||||
| #: video2x.py:128 | ||||
| msgid "Upscaling Options" | ||||
| msgstr "" | ||||
| 
 | ||||
| #: video2x.py:118 | ||||
| msgid "upscaling driver" | ||||
| msgstr "" | ||||
| 
 | ||||
| #: video2x.py:119 | ||||
| #: video2x.py:129 | ||||
| msgid "scaling ratio" | ||||
| msgstr "" | ||||
| 
 | ||||
| #: video2x.py:120 | ||||
| #: video2x.py:130 | ||||
| msgid "output width" | ||||
| msgstr "" | ||||
| 
 | ||||
| #: video2x.py:131 | ||||
| msgid "output height" | ||||
| msgstr "" | ||||
| 
 | ||||
| #: video2x.py:132 | ||||
| msgid "upscaling driver" | ||||
| msgstr "" | ||||
| 
 | ||||
| #: video2x.py:133 | ||||
| msgid "number of processes to use for upscaling" | ||||
| msgstr "" | ||||
| 
 | ||||
| #: video2x.py:121 | ||||
| #: video2x.py:134 | ||||
| msgid "preserve extracted and upscaled frames" | ||||
| msgstr "" | ||||
| 
 | ||||
| #: video2x.py:161 | ||||
| #: video2x.py:174 | ||||
| msgid "This file cannot be imported" | ||||
| msgstr "" | ||||
| 
 | ||||
| #: video2x.py:236 | ||||
| #: video2x.py:190 | ||||
| msgid "Specify either scaling ratio or scaling resolution, not both" | ||||
| msgstr "" | ||||
| 
 | ||||
| #: video2x.py:194 | ||||
| msgid "Only one of scaling width and scaling height is specified" | ||||
| msgstr "" | ||||
| 
 | ||||
| #: video2x.py:200 | ||||
| msgid "Redirecting console logs to {}" | ||||
| msgstr "" | ||||
| 
 | ||||
| #: video2x.py:276 | ||||
| msgid "Program completed, taking {} seconds" | ||||
| msgstr "" | ||||
| 
 | ||||
| #: video2x.py:239 | ||||
| #: video2x.py:279 | ||||
| msgid "An exception has occurred" | ||||
| msgstr "" | ||||
| 
 | ||||
|  | ||||
| @ -13,7 +13,7 @@ __      __  _       _                  ___   __   __ | ||||
| Name: Video2X Controller | ||||
| Creator: K4YT3X | ||||
| Date Created: Feb 24, 2018 | ||||
| Last Modified: June 29, 2020 | ||||
| Last Modified: September 9, 2020 | ||||
| 
 | ||||
| Editor: BrianPetkovsek | ||||
| Last Modified: June 17, 2019 | ||||
| @ -81,7 +81,7 @@ language = gettext.translation(DOMAIN, LOCALE_DIRECTORY, [default_locale], fallb | ||||
| language.install() | ||||
| _ = language.gettext | ||||
| 
 | ||||
| CLI_VERSION = '4.2.0' | ||||
| CLI_VERSION = '4.3.0' | ||||
| 
 | ||||
| LEGAL_INFO = _('''Video2X CLI Version: {} | ||||
| Upscaler Version: {} | ||||
| @ -107,7 +107,7 @@ def parse_arguments(): | ||||
| 
 | ||||
|     # video options | ||||
|     video2x_options = parser.add_argument_group(_('Video2X Options')) | ||||
|     video2x_options.add_argument('-h', '--help', action='help', help=_('show this help message and exit')) | ||||
|     video2x_options.add_argument('--help', action='help', help=_('show this help message and exit')) | ||||
| 
 | ||||
|     # if help is in arguments list | ||||
|     # do not require input and output path to be specified | ||||
| @ -126,8 +126,10 @@ def parse_arguments(): | ||||
| 
 | ||||
|     # scaling options | ||||
|     upscaling_options = parser.add_argument_group(_('Upscaling Options')) | ||||
|     upscaling_options.add_argument('-d', '--driver', help=_('upscaling driver'), choices=AVAILABLE_DRIVERS, default='waifu2x_caffe') | ||||
|     upscaling_options.add_argument('-r', '--ratio', help=_('scaling ratio'), action='store', type=float, default=2.0) | ||||
|     upscaling_options.add_argument('-r', '--ratio', help=_('scaling ratio'), action='store', type=float) | ||||
|     upscaling_options.add_argument('-w', '--width', help=_('output width'), action='store', type=float) | ||||
|     upscaling_options.add_argument('-h', '--height', help=_('output height'), action='store', type=float) | ||||
|     upscaling_options.add_argument('-d', '--driver', help=_('upscaling driver'), choices=AVAILABLE_DRIVERS, default='waifu2x_ncnn_vulkan') | ||||
|     upscaling_options.add_argument('-p', '--processes', help=_('number of processes to use for upscaling'), action='store', type=int, default=1) | ||||
|     upscaling_options.add_argument('--preserve_frames', help=_('preserve extracted and upscaled frames'), action='store_true') | ||||
| 
 | ||||
| @ -183,6 +185,15 @@ if video2x_args.version: | ||||
|     print(LEGAL_INFO) | ||||
|     sys.exit(0) | ||||
| 
 | ||||
| # additional checks on upscaling arguments | ||||
| if video2x_args.ratio is not None and (video2x_args.width is not None or video2x_args.height is not None): | ||||
|     Avalon.error(_('Specify either scaling ratio or scaling resolution, not both')) | ||||
|     sys.exit(1) | ||||
| 
 | ||||
| if bool(video2x_args.width) ^ bool(video2x_args.height): | ||||
|     Avalon.error(_('Only one of scaling width and scaling height is specified')) | ||||
|     sys.exit(1) | ||||
| 
 | ||||
| # redirect output to both terminal and log file | ||||
| if video2x_args.disable_logging is False: | ||||
|     LOGFILE = video2x_args.log | ||||
| @ -248,6 +259,8 @@ try: | ||||
|         # optional parameters | ||||
|         driver=video2x_args.driver, | ||||
|         scale_ratio=video2x_args.ratio, | ||||
|         scale_width=video2x_args.width, | ||||
|         scale_height=video2x_args.height, | ||||
|         processes=video2x_args.processes, | ||||
|         video2x_cache_directory=video2x_cache_directory, | ||||
|         extracted_frame_format=extracted_frame_format, | ||||
|  | ||||
| @ -4,7 +4,7 @@ | ||||
| Creator: Video2X GUI | ||||
| Author: K4YT3X | ||||
| Date Created: May 5, 2020 | ||||
| Last Modified: September 4, 2020 | ||||
| Last Modified: September 9, 2020 | ||||
| """ | ||||
| 
 | ||||
| # local imports | ||||
| @ -34,7 +34,7 @@ from PyQt5.QtGui import * | ||||
| from PyQt5.QtWidgets import * | ||||
| import magic | ||||
| 
 | ||||
| GUI_VERSION = '2.7.3' | ||||
| GUI_VERSION = '2.8.0' | ||||
| 
 | ||||
| LEGAL_INFO = f'''Video2X GUI Version: {GUI_VERSION}\\ | ||||
| Upscaler Version: {UPSCALER_VERSION}\\ | ||||
| @ -277,6 +277,10 @@ class Video2XMainWindow(QMainWindow): | ||||
|         self.driver_combo_box.currentTextChanged.connect(self.update_gui_for_driver) | ||||
|         self.processes_spin_box = self.findChild(QSpinBox, 'processesSpinBox') | ||||
|         self.scale_ratio_double_spin_box = self.findChild(QDoubleSpinBox, 'scaleRatioDoubleSpinBox') | ||||
|         self.output_width_spin_box = self.findChild(QSpinBox, 'outputWidthSpinBox') | ||||
|         self.output_width_spin_box.valueChanged.connect(self.mutually_exclude_scale_ratio_resolution) | ||||
|         self.output_height_spin_box = self.findChild(QSpinBox, 'outputHeightSpinBox') | ||||
|         self.output_height_spin_box.valueChanged.connect(self.mutually_exclude_scale_ratio_resolution) | ||||
|         self.output_file_name_format_string_line_edit = self.findChild(QLineEdit, 'outputFileNameFormatStringLineEdit') | ||||
|         self.image_output_extension_line_edit = self.findChild(QLineEdit, 'imageOutputExtensionLineEdit') | ||||
|         self.video_output_extension_line_edit = self.findChild(QLineEdit, 'videoOutputExtensionLineEdit') | ||||
| @ -310,8 +314,6 @@ class Video2XMainWindow(QMainWindow): | ||||
|         self.enable_line_edit_file_drop(self.waifu2x_caffe_path_line_edit) | ||||
|         self.waifu2x_caffe_path_select_button = self.findChild(QPushButton, 'waifu2xCaffePathSelectButton') | ||||
|         self.waifu2x_caffe_path_select_button.clicked.connect(lambda: self.select_driver_binary_path(self.waifu2x_caffe_path_line_edit)) | ||||
|         self.waifu2x_caffe_scale_width_spin_box = self.findChild(QSpinBox, 'waifu2xCaffeScaleWidthSpinBox') | ||||
|         self.waifu2x_caffe_scale_height_spin_box = self.findChild(QSpinBox, 'waifu2xCaffeScaleHeightSpinBox') | ||||
|         self.waifu2x_caffe_mode_combo_box = self.findChild(QComboBox, 'waifu2xCaffeModeComboBox') | ||||
|         self.waifu2x_caffe_noise_level_spin_box = self.findChild(QSpinBox, 'waifu2xCaffeNoiseLevelSpinBox') | ||||
|         self.waifu2x_caffe_process_combo_box = self.findChild(QComboBox, 'waifu2xCaffeProcessComboBox') | ||||
| @ -491,8 +493,6 @@ class Video2XMainWindow(QMainWindow): | ||||
| 
 | ||||
|         # waifu2x-caffe | ||||
|         settings = self.config['waifu2x_caffe'] | ||||
|         self.waifu2x_caffe_scale_width_spin_box.setValue(settings['scale_width']) | ||||
|         self.waifu2x_caffe_scale_height_spin_box.setValue(settings['scale_height']) | ||||
|         self.waifu2x_caffe_path_line_edit.setText(str(pathlib.Path(os.path.expandvars(settings['path'])).absolute())) | ||||
|         self.waifu2x_caffe_mode_combo_box.setCurrentText(settings['mode']) | ||||
|         self.waifu2x_caffe_noise_level_spin_box.setValue(settings['noise_level']) | ||||
| @ -605,8 +605,6 @@ class Video2XMainWindow(QMainWindow): | ||||
|     def resolve_driver_settings(self): | ||||
| 
 | ||||
|         # waifu2x-caffe | ||||
|         self.config['waifu2x_caffe']['scale_width'] = self.waifu2x_caffe_scale_width_spin_box.value() | ||||
|         self.config['waifu2x_caffe']['scale_height'] = self.waifu2x_caffe_scale_height_spin_box.value() | ||||
|         self.config['waifu2x_caffe']['path'] = os.path.expandvars(self.waifu2x_caffe_path_line_edit.text()) | ||||
|         self.config['waifu2x_caffe']['mode'] = self.waifu2x_caffe_mode_combo_box.currentText() | ||||
|         self.config['waifu2x_caffe']['noise_level'] = self.waifu2x_caffe_noise_level_spin_box.value() | ||||
| @ -831,6 +829,12 @@ class Video2XMainWindow(QMainWindow): | ||||
|         with open(config_file, 'r') as config: | ||||
|             return yaml.load(config, Loader=yaml.FullLoader) | ||||
| 
 | ||||
|     def mutually_exclude_scale_ratio_resolution(self): | ||||
|         if self.output_width_spin_box.value() != 0 or self.output_height_spin_box.value() != 0: | ||||
|             self.scale_ratio_double_spin_box.setDisabled(True) | ||||
|         elif self.output_width_spin_box.value() == 0 and self.output_height_spin_box.value() == 0: | ||||
|             self.scale_ratio_double_spin_box.setDisabled(False) | ||||
| 
 | ||||
|     def mutually_exclude_frame_interpolation_stream_copy(self): | ||||
|         if self.ffmpeg_migrate_streams_output_options_frame_interpolation_spin_box.value() > 0: | ||||
|             self.ffmpeg_migrate_streams_output_options_copy_streams_check_box.setChecked(False) | ||||
| @ -842,24 +846,6 @@ class Video2XMainWindow(QMainWindow): | ||||
|     def update_gui_for_driver(self): | ||||
|         current_driver = AVAILABLE_DRIVERS[self.driver_combo_box.currentText()] | ||||
| 
 | ||||
|         # update scale ratio constraints | ||||
|         if current_driver in ['waifu2x_caffe', 'waifu2x_converter_cpp', 'anime4kcpp']: | ||||
|             self.scale_ratio_double_spin_box.setMinimum(0.0) | ||||
|             self.scale_ratio_double_spin_box.setMaximum(999.0) | ||||
|             self.scale_ratio_double_spin_box.setValue(2.0) | ||||
|         elif current_driver == 'waifu2x_ncnn_vulkan': | ||||
|             self.scale_ratio_double_spin_box.setMinimum(1.0) | ||||
|             self.scale_ratio_double_spin_box.setMaximum(2.0) | ||||
|             self.scale_ratio_double_spin_box.setValue(2.0) | ||||
|         elif current_driver == 'srmd_ncnn_vulkan': | ||||
|             self.scale_ratio_double_spin_box.setMinimum(2.0) | ||||
|             self.scale_ratio_double_spin_box.setMaximum(4.0) | ||||
|             self.scale_ratio_double_spin_box.setValue(2.0) | ||||
|         elif current_driver == 'realsr_ncnn_vulkan': | ||||
|             self.scale_ratio_double_spin_box.setMinimum(4.0) | ||||
|             self.scale_ratio_double_spin_box.setMaximum(4.0) | ||||
|             self.scale_ratio_double_spin_box.setValue(4.0) | ||||
| 
 | ||||
|         # update preferred processes/threads count | ||||
|         if current_driver == 'anime4kcpp': | ||||
|             self.processes_spin_box.setValue(16) | ||||
| @ -1074,7 +1060,7 @@ It\'s also highly recommended for you to attach the [log file]({}) under the pro | ||||
| 
 | ||||
|         # initialize progress bar values | ||||
|         upscale_begin_time = time.time() | ||||
|         progress_callback.emit((upscale_begin_time, 0, 0, 0, 0, pathlib.Path(), pathlib.Path())) | ||||
|         progress_callback.emit((upscale_begin_time, 0, 0, 0, 0, 0, [], pathlib.Path(), pathlib.Path())) | ||||
| 
 | ||||
|         # keep querying upscaling process and feed information to callback signal | ||||
|         while self.upscaler.running: | ||||
| @ -1084,6 +1070,8 @@ It\'s also highly recommended for you to attach the [log file]({}) under the pro | ||||
|                                     self.upscaler.total_frames, | ||||
|                                     self.upscaler.total_processed, | ||||
|                                     self.upscaler.total_files, | ||||
|                                     self.upscaler.current_pass, | ||||
|                                     self.upscaler.scaling_jobs, | ||||
|                                     self.upscaler.current_input_file, | ||||
|                                     self.upscaler.last_frame_upscaled)) | ||||
|             time.sleep(1) | ||||
| @ -1098,8 +1086,10 @@ It\'s also highly recommended for you to attach the [log file]({}) under the pro | ||||
|         total_frames = progress_information[2] | ||||
|         total_processed = progress_information[3] | ||||
|         total_files = progress_information[4] | ||||
|         current_input_file = progress_information[5] | ||||
|         last_frame_upscaled = progress_information[6] | ||||
|         current_pass = progress_information[5] | ||||
|         scaling_jobs = progress_information[6] | ||||
|         current_input_file = progress_information[7] | ||||
|         last_frame_upscaled = progress_information[8] | ||||
| 
 | ||||
|         # calculate fields based on frames and time elapsed | ||||
|         time_elapsed = time.time() - upscale_begin_time | ||||
| @ -1120,7 +1110,7 @@ It\'s also highly recommended for you to attach the [log file]({}) under the pro | ||||
|         self.overall_progress_label.setText('Overall Progress: {}/{}'.format(total_processed, total_files)) | ||||
|         self.overall_progress_bar.setMaximum(total_files) | ||||
|         self.overall_progress_bar.setValue(total_processed) | ||||
|         self.currently_processing_label.setText('Currently Processing: {}'.format(str(current_input_file.name))) | ||||
|         self.currently_processing_label.setText('Currently Processing: {} (pass {}/{})'.format(str(current_input_file.name), current_pass, len(scaling_jobs))) | ||||
| 
 | ||||
|         # if show frame is checked, show preview image | ||||
|         if self.frame_preview_show_preview_check_box.isChecked() and last_frame_upscaled.is_file(): | ||||
| @ -1190,6 +1180,16 @@ It\'s also highly recommended for you to attach the [log file]({}) under the pro | ||||
|             # load driver settings for the current driver | ||||
|             self.driver_settings = self.config[AVAILABLE_DRIVERS[self.driver_combo_box.currentText()]] | ||||
| 
 | ||||
|             # get scale ratio or resolution | ||||
|             if self.scale_ratio_double_spin_box.isEnabled(): | ||||
|                 scale_ratio = self.scale_ratio_double_spin_box.value() | ||||
|                 scale_width = scale_height = None | ||||
| 
 | ||||
|             else: | ||||
|                 scale_ratio = None | ||||
|                 scale_width = self.output_width_spin_box.value() | ||||
|                 scale_height = self.output_height_spin_box.value() | ||||
| 
 | ||||
|             self.upscaler = Upscaler( | ||||
|                 # required parameters | ||||
|                 input_path=input_directory, | ||||
| @ -1200,7 +1200,9 @@ It\'s also highly recommended for you to attach the [log file]({}) under the pro | ||||
| 
 | ||||
|                 # optional parameters | ||||
|                 driver=AVAILABLE_DRIVERS[self.driver_combo_box.currentText()], | ||||
|                 scale_ratio=self.scale_ratio_double_spin_box.value(), | ||||
|                 scale_ratio=scale_ratio, | ||||
|                 scale_width=scale_width, | ||||
|                 scale_height=scale_height, | ||||
|                 processes=self.processes_spin_box.value(), | ||||
|                 video2x_cache_directory=pathlib.Path(os.path.expandvars(self.cache_line_edit.text())), | ||||
|                 extracted_frame_format=self.config['video2x']['extracted_frame_format'].lower(), | ||||
|  | ||||
| @ -6,8 +6,8 @@ | ||||
|    <rect> | ||||
|     <x>0</x> | ||||
|     <y>0</y> | ||||
|     <width>756</width> | ||||
|     <height>954</height> | ||||
|     <width>737</width> | ||||
|     <height>1020</height> | ||||
|    </rect> | ||||
|   </property> | ||||
|   <property name="acceptDrops"> | ||||
| @ -40,8 +40,8 @@ | ||||
|         <rect> | ||||
|          <x>0</x> | ||||
|          <y>0</y> | ||||
|          <width>744</width> | ||||
|          <height>696</height> | ||||
|          <width>725</width> | ||||
|          <height>762</height> | ||||
|         </rect> | ||||
|        </property> | ||||
|        <layout class="QVBoxLayout" name="verticalLayout_36"> | ||||
| @ -376,6 +376,11 @@ | ||||
|     </li> | ||||
| </ul></string> | ||||
|                      </property> | ||||
|                      <item> | ||||
|                       <property name="text"> | ||||
|                        <string>Waifu2X NCNN Vulkan</string> | ||||
|                       </property> | ||||
|                      </item> | ||||
|                      <item> | ||||
|                       <property name="text"> | ||||
|                        <string>Waifu2X Caffe</string> | ||||
| @ -386,11 +391,6 @@ | ||||
|                        <string>Waifu2X Converter CPP</string> | ||||
|                       </property> | ||||
|                      </item> | ||||
|                      <item> | ||||
|                       <property name="text"> | ||||
|                        <string>Waifu2X NCNN Vulkan</string> | ||||
|                       </property> | ||||
|                      </item> | ||||
|                      <item> | ||||
|                       <property name="text"> | ||||
|                        <string>SRMD NCNN Vulkan</string> | ||||
| @ -461,6 +461,42 @@ | ||||
|                    </item> | ||||
|                   </layout> | ||||
|                  </item> | ||||
|                  <item> | ||||
|                   <layout class="QHBoxLayout" name="outputWidthHorizontalLayout"> | ||||
|                    <item> | ||||
|                     <widget class="QLabel" name="outputWidthLabel"> | ||||
|                      <property name="text"> | ||||
|                       <string>Output Width</string> | ||||
|                      </property> | ||||
|                     </widget> | ||||
|                    </item> | ||||
|                    <item> | ||||
|                     <widget class="QSpinBox" name="outputWidthSpinBox"> | ||||
|                      <property name="maximum"> | ||||
|                       <number>99999</number> | ||||
|                      </property> | ||||
|                     </widget> | ||||
|                    </item> | ||||
|                   </layout> | ||||
|                  </item> | ||||
|                  <item> | ||||
|                   <layout class="QHBoxLayout" name="outputHeightHorizontalLayout"> | ||||
|                    <item> | ||||
|                     <widget class="QLabel" name="outputHeightLabel"> | ||||
|                      <property name="text"> | ||||
|                       <string>Output Height</string> | ||||
|                      </property> | ||||
|                     </widget> | ||||
|                    </item> | ||||
|                    <item> | ||||
|                     <widget class="QSpinBox" name="outputHeightSpinBox"> | ||||
|                      <property name="maximum"> | ||||
|                       <number>99999</number> | ||||
|                      </property> | ||||
|                     </widget> | ||||
|                    </item> | ||||
|                   </layout> | ||||
|                  </item> | ||||
|                  <item> | ||||
|                   <layout class="QHBoxLayout" name="imageOutputExtensionHorizontalLayout"> | ||||
|                    <item> | ||||
| @ -628,48 +664,6 @@ | ||||
|                   </item> | ||||
|                  </layout> | ||||
|                 </item> | ||||
|                 <item> | ||||
|                  <layout class="QHBoxLayout" name="waifu2xCaffeScaleWidthHorizontalLayout"> | ||||
|                   <item> | ||||
|                    <widget class="QLabel" name="waifu2xCaffeScaleWidthLabel"> | ||||
|                     <property name="text"> | ||||
|                      <string>Scale Width</string> | ||||
|                     </property> | ||||
|                    </widget> | ||||
|                   </item> | ||||
|                   <item> | ||||
|                    <widget class="QSpinBox" name="waifu2xCaffeScaleWidthSpinBox"> | ||||
|                     <property name="toolTip"> | ||||
|                      <string>custom scale width (specifying this will overwrite scale_ratio)</string> | ||||
|                     </property> | ||||
|                     <property name="maximum"> | ||||
|                      <number>999999</number> | ||||
|                     </property> | ||||
|                    </widget> | ||||
|                   </item> | ||||
|                  </layout> | ||||
|                 </item> | ||||
|                 <item> | ||||
|                  <layout class="QHBoxLayout" name="waifu2xCaffeScaleHeightHorizontalLayout"> | ||||
|                   <item> | ||||
|                    <widget class="QLabel" name="waifu2xCaffeScaleHeightLabel"> | ||||
|                     <property name="text"> | ||||
|                      <string>Scale Height</string> | ||||
|                     </property> | ||||
|                    </widget> | ||||
|                   </item> | ||||
|                   <item> | ||||
|                    <widget class="QSpinBox" name="waifu2xCaffeScaleHeightSpinBox"> | ||||
|                     <property name="toolTip"> | ||||
|                      <string>custom scale height (specifying this will overwrite scale_ratio)</string> | ||||
|                     </property> | ||||
|                     <property name="maximum"> | ||||
|                      <number>999999</number> | ||||
|                     </property> | ||||
|                    </widget> | ||||
|                   </item> | ||||
|                  </layout> | ||||
|                 </item> | ||||
|                 <item> | ||||
|                  <layout class="QHBoxLayout" name="waifu2xCaffeModeHorizontalLayout"> | ||||
|                   <item> | ||||
| @ -2946,7 +2940,7 @@ | ||||
|     <rect> | ||||
|      <x>0</x> | ||||
|      <y>0</y> | ||||
|      <width>756</width> | ||||
|      <width>737</width> | ||||
|      <height>21</height> | ||||
|     </rect> | ||||
|    </property> | ||||
|  | ||||
| @ -4,7 +4,7 @@ | ||||
| Name: Anime4KCPP Driver | ||||
| Author: K4YT3X | ||||
| Date Created: May 3, 2020 | ||||
| Last Modified: September 1, 2020 | ||||
| Last Modified: September 9, 2020 | ||||
| 
 | ||||
| Description: This class is a high-level wrapper | ||||
| for Anime4KCPP. | ||||
| @ -73,13 +73,16 @@ class WrapperMain: | ||||
|         return parser.parse_args(arguments) | ||||
| 
 | ||||
|     def load_configurations(self, upscaler): | ||||
|         self.driver_settings['zoomFactor'] = upscaler.scale_ratio | ||||
|         # self.driver_settings['zoomFactor'] = upscaler.scale_ratio | ||||
|         self.driver_settings['threads'] = upscaler.processes | ||||
| 
 | ||||
|         # append FFmpeg path to the end of PATH | ||||
|         # Anime4KCPP will then use FFmpeg to migrate audio tracks | ||||
|         os.environ['PATH'] += f';{upscaler.ffmpeg_settings["ffmpeg_path"]}' | ||||
| 
 | ||||
|     def set_scale_ratio(self, scale_ratio: float): | ||||
|         self.driver_settings['zoomFactor'] = scale_ratio | ||||
| 
 | ||||
|     def upscale(self, input_file, output_file): | ||||
|         """This is the core function for WAIFU2X class | ||||
| 
 | ||||
|  | ||||
| @ -75,6 +75,37 @@ class Ffmpeg: | ||||
| 
 | ||||
|         return pixel_formats | ||||
| 
 | ||||
|     def get_number_of_frames(self, input_file: str, video_stream_index: int) -> int: | ||||
|         """ Count the number of frames in a video | ||||
| 
 | ||||
|         Args: | ||||
|             input_file (str): input file path | ||||
|             video_stream_index (int): index number of the video stream | ||||
| 
 | ||||
|         Returns: | ||||
|             int: number of frames in the video | ||||
|         """ | ||||
| 
 | ||||
|         execute = [ | ||||
|             self.ffmpeg_probe_binary, | ||||
|             '-v', | ||||
|             'quiet', | ||||
|             '-count_frames', | ||||
|             '-select_streams', | ||||
|             f'v:{video_stream_index}', | ||||
|             '-show_entries', | ||||
|             'stream=nb_read_frames', | ||||
|             '-of', | ||||
|             'default=nokey=1:noprint_wrappers=1', | ||||
|             input_file | ||||
|         ] | ||||
| 
 | ||||
|         # turn elements into str | ||||
|         execute = [str(e) for e in execute] | ||||
| 
 | ||||
|         Avalon.debug_info(f'Executing: {shlex.join(execute)}') | ||||
|         return int(subprocess.run(execute, check=True, stdout=subprocess.PIPE).stdout.decode().strip()) | ||||
| 
 | ||||
|     def probe_file_info(self, input_video): | ||||
|         """ Gets input video information | ||||
| 
 | ||||
| @ -134,6 +165,7 @@ class Ffmpeg: | ||||
|         # specify output file | ||||
|         execute.extend([ | ||||
|             extracted_frames / f'extracted_%0d.{self.extracted_frame_format}' | ||||
|             # extracted_frames / f'frame_%06d.{self.extracted_frame_format}' | ||||
|         ]) | ||||
| 
 | ||||
|         return(self._execute(execute)) | ||||
| @ -175,6 +207,7 @@ class Ffmpeg: | ||||
|         execute.extend([ | ||||
|             '-i', | ||||
|             upscaled_frames / f'extracted_%d.{self.extracted_frame_format}' | ||||
|             # upscaled_frames / f'%06d.{self.extracted_frame_format}' | ||||
|         ]) | ||||
| 
 | ||||
|         # read FFmpeg output options | ||||
|  | ||||
| @ -4,7 +4,7 @@ | ||||
| Name: RealSR NCNN Vulkan Driver | ||||
| Creator: K4YT3X | ||||
| Date Created: May 26, 2020 | ||||
| Last Modified: May 26, 2020 | ||||
| Last Modified: September 9, 2020 | ||||
| 
 | ||||
| Description: This class is a high-level wrapper | ||||
| for realsr_ncnn_vulkan. | ||||
| @ -44,7 +44,7 @@ class WrapperMain: | ||||
|         parser.add_argument('-v', action='store_true', help='verbose output') | ||||
|         parser.add_argument('-i', type=str, help=argparse.SUPPRESS)  # help='input image path (jpg/png) or directory') | ||||
|         parser.add_argument('-o', type=str, help=argparse.SUPPRESS)  # help='output image path (png) or directory') | ||||
|         parser.add_argument('-s', type=int, choices=[4], help='upscale ratio') | ||||
|         parser.add_argument('-s', type=int, help='upscale ratio') | ||||
|         parser.add_argument('-t', type=int, help='tile size (>=32/0=auto)') | ||||
|         parser.add_argument('-m', type=str, help='realsr model path') | ||||
|         parser.add_argument('-g', type=int, help='gpu device to use') | ||||
| @ -53,9 +53,12 @@ class WrapperMain: | ||||
|         return parser.parse_args(arguments) | ||||
| 
 | ||||
|     def load_configurations(self, upscaler): | ||||
|         self.driver_settings['s'] = int(upscaler.scale_ratio) | ||||
|         # self.driver_settings['s'] = int(upscaler.scale_ratio) | ||||
|         self.driver_settings['j'] = '{}:{}:{}'.format(upscaler.processes, upscaler.processes, upscaler.processes) | ||||
| 
 | ||||
|     def set_scale_ratio(self, scale_ratio: int): | ||||
|         self.driver_settings['s'] = int(scale_ratio) | ||||
| 
 | ||||
|     def upscale(self, input_directory, output_directory): | ||||
|         """This is the core function for RealSR NCNN Vulkan class | ||||
| 
 | ||||
|  | ||||
| @ -4,7 +4,7 @@ | ||||
| Name: SRMD NCNN Vulkan Driver | ||||
| Creator: K4YT3X | ||||
| Date Created: April 26, 2020 | ||||
| Last Modified: May 11, 2020 | ||||
| Last Modified: September 9, 2020 | ||||
| 
 | ||||
| Description: This class is a high-level wrapper | ||||
| for srmd_ncnn_vulkan. | ||||
| @ -45,7 +45,7 @@ class WrapperMain: | ||||
|         parser.add_argument('-i', type=str, help=argparse.SUPPRESS)  # help='input image path (jpg/png) or directory') | ||||
|         parser.add_argument('-o', type=str, help=argparse.SUPPRESS)  # help='output image path (png) or directory') | ||||
|         parser.add_argument('-n', type=int, choices=range(-1, 11), help='denoise level') | ||||
|         parser.add_argument('-s', type=int, choices=range(2, 5), help='upscale ratio') | ||||
|         parser.add_argument('-s', type=int, help='upscale ratio') | ||||
|         parser.add_argument('-t', type=int, help='tile size (>=32)') | ||||
|         parser.add_argument('-m', type=str, help='srmd model path') | ||||
|         parser.add_argument('-g', type=int, help='gpu device to use') | ||||
| @ -54,9 +54,12 @@ class WrapperMain: | ||||
|         return parser.parse_args(arguments) | ||||
| 
 | ||||
|     def load_configurations(self, upscaler): | ||||
|         self.driver_settings['s'] = int(upscaler.scale_ratio) | ||||
|         # self.driver_settings['s'] = int(upscaler.scale_ratio) | ||||
|         self.driver_settings['j'] = '{}:{}:{}'.format(upscaler.processes, upscaler.processes, upscaler.processes) | ||||
| 
 | ||||
|     def set_scale_ratio(self, scale_ratio: int): | ||||
|         self.driver_settings['s'] = int(scale_ratio) | ||||
| 
 | ||||
|     def upscale(self, input_directory, output_directory): | ||||
|         """This is the core function for SRMD ncnn Vulkan class | ||||
| 
 | ||||
|  | ||||
| @ -4,7 +4,7 @@ | ||||
| Name: Waifu2x Caffe Driver | ||||
| Author: K4YT3X | ||||
| Date Created: Feb 24, 2018 | ||||
| Last Modified: June 7, 2020 | ||||
| Last Modified: September 9, 2020 | ||||
| 
 | ||||
| Description: This class is a high-level wrapper | ||||
| for waifu2x-caffe. | ||||
| @ -63,13 +63,16 @@ class WrapperMain: | ||||
| 
 | ||||
|     def load_configurations(self, upscaler): | ||||
|         # 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.extracted_frame_format | ||||
| 
 | ||||
|         # bit_depth will be 12 at this point | ||||
|         # it will up updated later | ||||
|         self.driver_settings['output_depth'] = 12 | ||||
| 
 | ||||
|     def set_scale_ratio(self, scale_ratio: float): | ||||
|         self.driver_settings['scale_ratio'] = scale_ratio | ||||
| 
 | ||||
|     def upscale(self, input_directory, output_directory): | ||||
|         """ start upscaling process | ||||
|         """ | ||||
|  | ||||
| @ -4,7 +4,7 @@ | ||||
| Name: Waifu2x Converter CPP Driver | ||||
| Author: K4YT3X | ||||
| Date Created: February 8, 2019 | ||||
| Last Modified: June 13, 2020 | ||||
| Last Modified: September 9, 2020 | ||||
| 
 | ||||
| Description: This class is a high-level wrapper | ||||
| for waifu2x-converter-cpp. | ||||
| @ -67,10 +67,13 @@ class WrapperMain: | ||||
|         return parser.parse_args(arguments) | ||||
| 
 | ||||
|     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['output-format'] = upscaler.extracted_frame_format.lower() | ||||
| 
 | ||||
|     def set_scale_ratio(self, scale_ratio: float): | ||||
|         self.driver_settings['scale-ratio'] = scale_ratio | ||||
| 
 | ||||
|     def upscale(self, input_directory, output_directory): | ||||
|         """ Waifu2x Converter Driver Upscaler | ||||
|         This method executes the upscaling of extracted frames. | ||||
|  | ||||
| @ -7,7 +7,7 @@ Date Created: June 26, 2019 | ||||
| Last Modified: May 11, 2020 | ||||
| 
 | ||||
| Editor: K4YT3X | ||||
| Last Modified: February 22, 2020 | ||||
| Last Modified: September 9, 2020 | ||||
| 
 | ||||
| Description: This class is a high-level wrapper | ||||
| for waifu2x_ncnn_vulkan. | ||||
| @ -48,7 +48,7 @@ class WrapperMain: | ||||
|         parser.add_argument('-i', type=str, help=argparse.SUPPRESS)  # help='input image path (jpg/png) or directory') | ||||
|         parser.add_argument('-o', type=str, help=argparse.SUPPRESS)  # help='output image path (png) or directory') | ||||
|         parser.add_argument('-n', type=int, choices=range(-1, 4), help='denoise level') | ||||
|         parser.add_argument('-s', type=int, choices=range(1, 3), help='upscale ratio') | ||||
|         parser.add_argument('-s', type=int, help='upscale ratio') | ||||
|         parser.add_argument('-t', type=int, help='tile size (>=32)') | ||||
|         parser.add_argument('-m', type=str, help='waifu2x model path') | ||||
|         parser.add_argument('-g', type=int, help='gpu device to use') | ||||
| @ -57,11 +57,14 @@ class WrapperMain: | ||||
|         return parser.parse_args(arguments) | ||||
| 
 | ||||
|     def load_configurations(self, upscaler): | ||||
|         self.driver_settings['s'] = int(upscaler.scale_ratio) | ||||
|         # self.driver_settings['s'] = int(upscaler.scale_ratio) | ||||
|         self.driver_settings['j'] = '{}:{}:{}'.format(upscaler.processes, upscaler.processes, upscaler.processes) | ||||
| 
 | ||||
|     def set_scale_ratio(self, scale_ratio: int): | ||||
|         self.driver_settings['s'] = int(scale_ratio) | ||||
| 
 | ||||
|     def upscale(self, input_directory, output_directory): | ||||
|         """This is the core function for WAIFU2X class | ||||
|         """ This is the core function for waifu2x class | ||||
| 
 | ||||
|         Arguments: | ||||
|             input_directory {string} -- source directory path | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user