Skip to content

Commit

Permalink
Async optimizations (#269)
Browse files Browse the repository at this point in the history
* refractoring and cleaning up code for progressive frame extractor

* made progressive frame extractor async writing

* increased max frames ahead, added to config, decreased default bleed
  • Loading branch information
akai-katto committed Oct 23, 2022
1 parent c9c5e36 commit d5a76e6
Show file tree
Hide file tree
Showing 8 changed files with 37 additions and 41 deletions.
3 changes: 2 additions & 1 deletion src/config_files/output_options.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ realsr_ncnn_vulkan:
-verbose: null

dandere2x:
bleed: 3
bleed: 1
max_frames_ahead = 500

dandere2x_cpp:
block_matching_arg: "exhaustive"
Expand Down
6 changes: 4 additions & 2 deletions src/dandere2x/dandere2x_service/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -98,15 +98,17 @@ def run(self):

self.progressive_noise_adder.start()

self.min_disk_demon.extract_initial_frames()
extract_initial_frames = threading.Thread(target=self.min_disk_demon.extract_initial_frames)
extract_initial_frames.start()
self.__upscale_first_frame()
extract_initial_frames.join()

self.min_disk_demon.start()
self.dandere2x_cpp_thread.start()
self.merge_thread.start()
self.residual_thread.start()
self.waifu2x.start()
self.status_thread.start()
self.min_disk_demon.start()

while self.controller.get_current_frame() < self.context.frame_count - 1:
time.sleep(1)
Expand Down
17 changes: 7 additions & 10 deletions src/dandere2x/dandere2x_service/core/min_disk_usage.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,7 @@
from dandere2x.dandere2x_service.dandere2x_service_context import Dandere2xServiceContext
from dandere2x.dandere2x_service.dandere2x_service_controller import Dandere2xController
from dandere2x.dandere2xlib.utils.dandere2x_utils import get_lexicon_value
from dandere2x.dandere2xlib.wrappers.ffmpeg.progressive_frame_extractor_ffmpeg_rework import \
ProgressiveFramesExtractorFFMPEG
from dandere2x.dandere2xlib.wrappers.ffmpeg.progressive_frame_extractor import ProgressiveFrameExtractor


class MinDiskUsage(threading.Thread):
Expand All @@ -53,12 +52,12 @@ def __init__(self, context: Dandere2xServiceContext, controller: Dandere2xContro
self.controller = controller
self.max_frames_ahead = self.context.max_frames_ahead
self.frame_count = context.frame_count
self.progressive_frame_extractor = ProgressiveFramesExtractorFFMPEG(input_video=self.context.service_request.input_file,
extracted_frames_dir=self.context.input_frames_dir,
compressed_frames_dir=self.context.compressed_static_dir,
compressed_quality=self.context.service_request.quality_minimum,
block_size=self.context.service_request.block_size,
output_options_original=self.context.service_request.output_options)
self.progressive_frame_extractor = ProgressiveFrameExtractor(input_video=self.context.service_request.input_file,
extracted_frames_dir=self.context.input_frames_dir,
compressed_frames_dir=self.context.compressed_static_dir,
compressed_quality=self.context.service_request.quality_minimum,
block_size=self.context.service_request.block_size,
output_options_original=self.context.service_request.output_options)
self.start_frame = 1

def join(self, timeout=None):
Expand All @@ -84,14 +83,12 @@ def run(self):
time.sleep(.00001)

if not self.is_alive():
self.progressive_frame_extractor.release_capture()
return

# when it does get ahead, extract the next frame
self.progressive_frame_extractor.next_frame()
self.__delete_used_files(x)

self.progressive_frame_extractor.release_capture()

def extract_initial_frames(self):
"""
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ def __init__(self, service_request: Dandere2xServiceRequest):
self.temp_image = self.temp_image_folder + "tempimage.jpg"
self.debug = False
self.step_size = 4
self.max_frames_ahead = 100
self.max_frames_ahead = self.service_request.output_options["dandere2x"]["max_frames_ahead"]

# Dandere2xCPP
self.dandere2x_cpp_block_matching_arg = self.service_request.output_options["dandere2x_cpp"]["block_matching_arg"]
Expand Down
Empty file.
Empty file.
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
import threading
import time
import uuid
from pathlib import Path

from dandere2x.dandere2xlib.utils.dandere2x_utils import rename_file_wait
from dandere2x.dandere2xlib.utils.yaml_utils import load_executable_paths_yaml
from dandere2x.dandere2xlib.wrappers.ffmpeg.ffmpeg import apply_noise_to_image
from dandere2x.dandere2xlib.wrappers.ffmpeg.ffmpeg_progressive_frame_extractor import VideoFrameExtractor
from dandere2x.dandere2xlib.wrappers.ffmpeg.progressive_frame_extractor._ffmpeg_video_frame_extractor import \
FFMpegVideoFrameExtractor, D2xFrame
from dandere2x.dandere2xlib.wrappers.ffmpeg.ffprobe import get_width_height

class ProgressiveFramesExtractorFFMPEG:

class ProgressiveFrameExtractor:
"""
Temporally extract frames from a video each time next_frame is called.
Saves into dandere2x's inputs DIR.
Expand All @@ -19,7 +23,6 @@ def __init__(self,
compressed_quality: int,
block_size: int,
output_options_original: dict):

ffprobe_path = load_executable_paths_yaml()['ffprobe']
ffmpeg_path = load_executable_paths_yaml()['ffmpeg']

Expand All @@ -30,41 +33,32 @@ def __init__(self,
self.compressed_quality = compressed_quality

width, height = get_width_height(ffprobe_dir=ffprobe_path, input_video=input_video)
self.cap = VideoFrameExtractor(Path(ffmpeg_path), Path(input_video), width, height, block_size, output_options_original)
self.cap = FFMpegVideoFrameExtractor(Path(ffmpeg_path), Path(input_video), width, height, block_size,
output_options_original)

self.ffmpeg_path = load_executable_paths_yaml()['ffmpeg']

self.count = 1

def extract_frames_to(self, stop_frame: int):

for x in range(1, stop_frame):
self.next_frame()

def release_capture(self):
pass
# #todo, investigate / remove this try catch block with an actual solution
# try:
# # Closes all the frames
# self.cap.release()
# cv2.destroyAllWindows()
#
# except cv2.error:
# print("cv2 error caught - this behaviour is unexpected by the developer, but testing to see if this is"
# " a potential duct-tape fix.")

# todo, need to find a fix for "stuck at 99%" error, or getting stuck prematurely.
def next_frame(self):
""" Call and save the next frame. """

success = False
image = self.cap.get_frame()

temp_image = self.extracted_frames_dir + "frame_temp_%s.png" % self.count
temp_image = self.extracted_frames_dir + str(uuid.uuid4()) + "frame_temp_%s.png" % self.count
final_image = self.extracted_frames_dir + "frame%s.png" % self.count

image.save(Path(temp_image))

rename_file_wait(temp_image, final_image)
threading.Thread(target=self.save_asyncable, args=(image, temp_image, final_image,)).start()

self.count += 1

@staticmethod
def save_asyncable(image: D2xFrame, temp_image:str, final_image: str):
image.save(Path(temp_image))
rename_file_wait(temp_image, final_image)
Original file line number Diff line number Diff line change
Expand Up @@ -120,9 +120,11 @@ def valid_input_resolution(width: int, height: int, block_size: int):

return new_output_options

class VideoFrameExtractor:

def __init__(self, ffmpeg_binary: Path, input_video: Path, width: int, height: int, block_size: int, output_options_original: dict):
class FFMpegVideoFrameExtractor:

def __init__(self, ffmpeg_binary: Path, input_video: Path, width: int, height: int, block_size: int,
output_options_original: dict):
self.__count: int = 0
self._width, self._height = get_a_valid_input_resolution(width, height, block_size)
self._dtype = np.uint8
Expand All @@ -140,12 +142,12 @@ def __init__(self, ffmpeg_binary: Path, input_video: Path, width: int, height:

print("pre output options")
options = get_options_from_section(fixed_resolution["ffmpeg"]["pre_process_video"]['output_options'],
ffmpeg_command=True)
ffmpeg_command=True)
for item in options:
extraction_args.append(item)

extraction_args.extend(["-c:v", "rawvideo", "-f", "rawvideo",
"-pix_fmt", "rgb24", "-an", "-"])
"-pix_fmt", "rgb24", "-an", "-"])

pprint(extraction_args)
self.ffmpeg = subprocess.Popen(extraction_args, stdout=subprocess.PIPE)
Expand All @@ -172,4 +174,4 @@ def get_frame(self) -> D2xFrame:


if __name__ == "__main__":
pass
pass

0 comments on commit d5a76e6

Please sign in to comment.