Spaces:
Running
Running
Update roop/processors/frame/core.py
Browse files- roop/processors/frame/core.py +49 -37
roop/processors/frame/core.py
CHANGED
@@ -29,11 +29,12 @@ def load_frame_processor_module(frame_processor: str) -> Any:
|
|
29 |
frame_processor_module = importlib.import_module(f'roop.processors.frame.{frame_processor}')
|
30 |
for method_name in FRAME_PROCESSORS_INTERFACE:
|
31 |
if not hasattr(frame_processor_module, method_name):
|
32 |
-
raise NotImplementedError
|
33 |
logging.info(f'Successfully loaded frame processor module: {frame_processor}')
|
34 |
except (ImportError, NotImplementedError) as e:
|
35 |
logging.error(f'Error loading frame processor {frame_processor}: {e}')
|
36 |
-
|
|
|
37 |
return frame_processor_module
|
38 |
|
39 |
def get_frame_processors_modules(frame_processors: List[str]) -> List[ModuleType]:
|
@@ -45,51 +46,62 @@ def get_frame_processors_modules(frame_processors: List[str]) -> List[ModuleType
|
|
45 |
FRAME_PROCESSORS_MODULES.append(frame_processor_module)
|
46 |
return FRAME_PROCESSORS_MODULES
|
47 |
|
48 |
-
def multi_process_frame(source_path: str, temp_frame_paths: List[str], process_frames: Callable[[str, List[str],
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
|
|
|
|
|
|
|
|
63 |
|
64 |
-
def create_queue(temp_frame_paths: List[str]) -> Queue
|
65 |
-
queue
|
66 |
for frame_path in temp_frame_paths:
|
67 |
queue.put(frame_path)
|
68 |
logging.info('Queue created with frame paths.')
|
69 |
return queue
|
70 |
|
71 |
-
def pick_queue(queue: Queue
|
72 |
-
|
73 |
for _ in range(queue_per_future):
|
74 |
if not queue.empty():
|
75 |
-
|
76 |
-
logging.info(f'Picked {len(
|
77 |
-
return
|
78 |
|
79 |
-
def process_video(source_path: str, frame_paths: List[str], process_frames: Callable[[str, List[str],
|
80 |
progress_bar_format = '{l_bar}{bar}| {n_fmt}/{total_fmt} [{elapsed}<{remaining}, {rate_fmt}{postfix}]'
|
81 |
total = len(frame_paths)
|
82 |
-
|
83 |
-
|
|
|
|
|
|
|
84 |
|
85 |
def update_progress(progress: Any = None) -> None:
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
|
91 |
-
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
|
|
|
|
|
|
|
|
|
|
29 |
frame_processor_module = importlib.import_module(f'roop.processors.frame.{frame_processor}')
|
30 |
for method_name in FRAME_PROCESSORS_INTERFACE:
|
31 |
if not hasattr(frame_processor_module, method_name):
|
32 |
+
raise NotImplementedError(f"Missing method: {method_name}")
|
33 |
logging.info(f'Successfully loaded frame processor module: {frame_processor}')
|
34 |
except (ImportError, NotImplementedError) as e:
|
35 |
logging.error(f'Error loading frame processor {frame_processor}: {e}')
|
36 |
+
raise SystemExit(f'Frame processor {frame_processor} crashed.')
|
37 |
+
|
38 |
return frame_processor_module
|
39 |
|
40 |
def get_frame_processors_modules(frame_processors: List[str]) -> List[ModuleType]:
|
|
|
46 |
FRAME_PROCESSORS_MODULES.append(frame_processor_module)
|
47 |
return FRAME_PROCESSORS_MODULES
|
48 |
|
49 |
+
def multi_process_frame(source_path: str, temp_frame_paths: List[str], process_frames: Callable[[str, List[str], Callable[[], None]], None], update: Callable[[], None]) -> None:
|
50 |
+
try:
|
51 |
+
with ThreadPoolExecutor(max_workers=roop.globals.execution_threads) as executor:
|
52 |
+
futures = []
|
53 |
+
queue = create_queue(temp_frame_paths)
|
54 |
+
queue_per_future = len(temp_frame_paths) // roop.globals.execution_threads
|
55 |
+
while not queue.empty():
|
56 |
+
future = executor.submit(process_frames, source_path, pick_queue(queue, queue_per_future), update)
|
57 |
+
futures.append(future)
|
58 |
+
logging.info('Submitted future for processing frames.')
|
59 |
+
|
60 |
+
for future in as_completed(futures):
|
61 |
+
try:
|
62 |
+
future.result()
|
63 |
+
logging.info('Frame processing completed for a future.')
|
64 |
+
except Exception as e:
|
65 |
+
logging.error(f'Error in processing frame: {e}')
|
66 |
+
except Exception as e:
|
67 |
+
logging.error(f'Error in multi-process frame: {e}')
|
68 |
|
69 |
+
def create_queue(temp_frame_paths: List[str]) -> Queue:
|
70 |
+
queue = Queue()
|
71 |
for frame_path in temp_frame_paths:
|
72 |
queue.put(frame_path)
|
73 |
logging.info('Queue created with frame paths.')
|
74 |
return queue
|
75 |
|
76 |
+
def pick_queue(queue: Queue, queue_per_future: int) -> List[str]:
|
77 |
+
picked_items = []
|
78 |
for _ in range(queue_per_future):
|
79 |
if not queue.empty():
|
80 |
+
picked_items.append(queue.get())
|
81 |
+
logging.info(f'Picked {len(picked_items)} items from queue for processing.')
|
82 |
+
return picked_items
|
83 |
|
84 |
+
def process_video(source_path: str, frame_paths: List[str], process_frames: Callable[[str, List[str], Callable[[], None]], None]) -> None:
|
85 |
progress_bar_format = '{l_bar}{bar}| {n_fmt}/{total_fmt} [{elapsed}<{remaining}, {rate_fmt}{postfix}]'
|
86 |
total = len(frame_paths)
|
87 |
+
try:
|
88 |
+
with tqdm(total=total, desc='Processing', unit='frame', dynamic_ncols=True, bar_format=progress_bar_format, mininterval=0.1) as progress:
|
89 |
+
multi_process_frame(source_path, frame_paths, process_frames, lambda: update_progress(progress))
|
90 |
+
except Exception as e:
|
91 |
+
logging.error(f'Error in processing video: {e}')
|
92 |
|
93 |
def update_progress(progress: Any = None) -> None:
|
94 |
+
try:
|
95 |
+
process = psutil.Process(os.getpid())
|
96 |
+
memory_usage = process.memory_info().rss / 1024 / 1024 / 1024
|
97 |
+
if progress:
|
98 |
+
progress.set_postfix({
|
99 |
+
'memory_usage': '{:.2f}'.format(memory_usage).zfill(5) + 'GB',
|
100 |
+
'execution_providers': roop.globals.execution_providers,
|
101 |
+
'execution_threads': roop.globals.execution_threads
|
102 |
+
})
|
103 |
+
progress.refresh()
|
104 |
+
progress.update(1)
|
105 |
+
logging.info(f'Updated progress: {progress.n}/{progress.total} frames processed. Memory usage: {memory_usage:.2f}GB')
|
106 |
+
except Exception as e:
|
107 |
+
logging.error(f'Error updating progress: {e}')
|