From 2d1239b3a424678e659c449b26d09ff487118003 Mon Sep 17 00:00:00 2001 From: SnuffSocket <82658601+SnuffSocket@users.noreply.github.com> Date: Mon, 14 Oct 2024 08:34:35 +0300 Subject: [PATCH 1/2] Fix: Decouple OSC from GUI render loop --- BabbleApp/babble_processor.py | 39 ++++++++++++++++++----------------- BabbleApp/camera_widget.py | 4 +--- 2 files changed, 21 insertions(+), 22 deletions(-) diff --git a/BabbleApp/babble_processor.py b/BabbleApp/babble_processor.py index 2eddb4c..dfcf7f0 100644 --- a/BabbleApp/babble_processor.py +++ b/BabbleApp/babble_processor.py @@ -49,6 +49,7 @@ def __init__( capture_queue_incoming: "queue.Queue(maxsize=2)", image_queue_outgoing: "queue.Queue(maxsize=2)", cam_id, + osc_queue: queue.Queue, ): self.main_config = BabbleSettingsConfig self.config = config @@ -61,6 +62,7 @@ def __init__( self.cancellation_event = cancellation_event self.capture_event = capture_event self.cam_id = cam_id + self.osc_queue = osc_queue # Image state self.previous_image = None @@ -111,20 +113,22 @@ def __init__( ) def output_images_and_update(self, output_information: CamInfo): - try: - image_stack = np.concatenate( - ( - cv2.cvtColor(self.current_image_gray, cv2.COLOR_GRAY2BGR), - ), - axis=1, - ) - self.image_queue_outgoing.put((image_stack, output_information)) - self.previous_image = self.current_image - self.previous_rotation = self.config.rotation_angle - except: # If this fails it likely means that the images are not the same size for some reason. - print('\033[91m[ERROR] Size of frames to display are of unequal sizes.\033[0m') + image_stack = np.concatenate( + ( + cv2.cvtColor(self.current_image_gray, cv2.COLOR_GRAY2BGR), + ), + axis=1, + ) + self.image_queue_outgoing.put((image_stack, output_information)) + if self.image_queue_outgoing.qsize() > 1: + self.image_queue_outgoing.get() + + self.previous_image = self.current_image + self.previous_rotation = self.config.rotation_angle + + # Relay information to OSC + self.osc_queue.put((None, output_information)) - pass def capture_crop_rotate_image(self): # Get our current frame @@ -194,7 +198,6 @@ def run(self): print("\033[94m[INFO] Exiting Tracking thread\033[0m") return - if self.config.roi_window_w <= 0 or self.config.roi_window_h <= 0: # At this point, we're waiting for the user to set up the ROI window in the GUI. # Sleep a bit while we wait. @@ -202,8 +205,6 @@ def run(self): return continue - - try: if self.capture_queue_incoming.empty(): self.capture_event.set() @@ -212,7 +213,7 @@ def run(self): self.current_image, self.current_frame_number, self.current_fps, - ) = self.capture_queue_incoming.get(block=True, timeout=0.2) + ) = self.capture_queue_incoming.get(block=True, timeout=0.1) except queue.Empty: # print("No image available") continue @@ -234,11 +235,11 @@ def run(self): run_model(self) if self.settings.use_calibration: self.output = cal.cal_osc(self, self.output) - #else: # pass #print(self.output) + self.output_images_and_update(CamInfo(self.current_algo, self.output)) def get_framesize(self): - return self.FRAMESIZE \ No newline at end of file + return self.FRAMESIZE diff --git a/BabbleApp/camera_widget.py b/BabbleApp/camera_widget.py index 66a3c47..e81d0c9 100644 --- a/BabbleApp/camera_widget.py +++ b/BabbleApp/camera_widget.py @@ -65,6 +65,7 @@ def __init__(self, widget_id: Tab, main_config: BabbleConfig, osc_queue: Queue): self.capture_queue, self.image_queue, self.cam_id, + self.osc_queue, ) @@ -413,8 +414,5 @@ def render(self, window, event, values): imgbytes = cv2.imencode(".ppm", maybe_image)[1].tobytes() window[self.gui_tracking_image].update(data=imgbytes) - # Relay information to OSC - if cam_info.info_type != CamInfoOrigin.FAILURE: - self.osc_queue.put((self.cam_id, cam_info)) except Empty: pass \ No newline at end of file From 179d899bff1502fed8138b56207b4a0ab40ee3ed Mon Sep 17 00:00:00 2001 From: SnuffSocket <82658601+SnuffSocket@users.noreply.github.com> Date: Sun, 6 Oct 2024 22:12:32 +0300 Subject: [PATCH 2/2] Fix: Crash "GUI off mem leak, frame buildup" By RedHawk989: https://github.com/EyeTrackVR/EyeTrackVR/commit/df29fc0380ace8845ca91f4bf1ae426244525653 --- BabbleApp/babble_processor.py | 2 -- BabbleApp/babbleapp.py | 2 +- BabbleApp/landmark_processor.py | 6 ++++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/BabbleApp/babble_processor.py b/BabbleApp/babble_processor.py index ef187d8..13c171b 100644 --- a/BabbleApp/babble_processor.py +++ b/BabbleApp/babble_processor.py @@ -141,8 +141,6 @@ def output_images_and_update(self, output_information: CamInfo): f'\033[91m[{lang._instance.get_string("log.error")}] {lang._instance.get_string("error.size")}.\033[0m' ) - pass - def capture_crop_rotate_image(self): # Get our current frame diff --git a/BabbleApp/babbleapp.py b/BabbleApp/babbleapp.py index 60fb160..ff5e40c 100644 --- a/BabbleApp/babbleapp.py +++ b/BabbleApp/babbleapp.py @@ -112,7 +112,7 @@ def main(): # Check to see if we have an ROI. If not, bring up ROI finder GUI. # Spawn worker threads - osc_queue: queue.Queue[tuple[bool, int, int]] = queue.Queue(maxsize=2) + osc_queue: queue.Queue[tuple[bool, int, int]] = queue.Queue(maxsize=10) osc = VRChatOSC(cancellation_event, osc_queue, config) osc_thread = threading.Thread(target=osc.run) # start worker threads diff --git a/BabbleApp/landmark_processor.py b/BabbleApp/landmark_processor.py index c23225f..19d6fa0 100644 --- a/BabbleApp/landmark_processor.py +++ b/BabbleApp/landmark_processor.py @@ -114,7 +114,7 @@ def __init__( def get_frame(self): return self.current_image_gray_clean - + def infer_frame(self, image): return write_image(self, image) @@ -127,12 +127,14 @@ def output_images_and_update(self, output_information: CamInfo): axis=1, ) self.image_queue_outgoing.put((image_stack, output_information)) + if self.image_queue_outgoing.qsize() > 1: + self.image_queue_outgoing.get() + self.previous_image = self.current_image self.previous_rotation = self.config.rotation_angle except: # If this fails it likely means that the images are not the same size for some reason. print('\033[91m[{lang._instance.get_string("log.error")}] Size of frames to display are of unequal sizes.\033[0m') - pass def capture_crop_rotate_image(self): # Get our current frame