@@ -1003,7 +1003,6 @@ def run(self):
10031003
10041004 # Get the appropriate template for the detection mode
10051005 template = DETECTION_MODES [mode_name ]["template" ]
1006-
10071006 results = self .cvr_instance .capture_multi_pages (self .file_path , template )
10081007
10091008 self .finished .emit (results )
@@ -1496,6 +1495,7 @@ def __init__(self):
14961495 # Initialize variables
14971496 self .cvr_instance = None
14981497 self .custom_receiver = None
1498+ self .receiver_active = False # Track if intermediate receiver is currently active
14991499 self .current_file_path = None
15001500 self .current_pages = {} # Store page data {page_index: cv_image}
15011501 self .page_hash_mapping = {} # Map page_index to hash_id
@@ -2057,8 +2057,10 @@ def initialize_license(self):
20572057 if initialize_license_once ():
20582058 self .cvr_instance = CaptureVisionRouter ()
20592059 intermediate_result_manager = self .cvr_instance .get_intermediate_result_manager ()
2060+
2061+ # Create receiver but don't add it yet - only add for barcode detection
20602062 self .custom_receiver = MyIntermediateResultReceiver (intermediate_result_manager )
2061- intermediate_result_manager . add_result_receiver ( self .custom_receiver )
2063+ self .receiver_active = False # Track if receiver is currently active
20622064
20632065 self .log_message ("✅ License initialized successfully!" )
20642066
@@ -2077,6 +2079,36 @@ def delayed_camera_init(self):
20772079 if hasattr (self , 'camera_widget' ):
20782080 self .camera_widget .initialize_dynamsoft_camera (self .cvr_instance )
20792081
2082+ def manage_intermediate_receiver (self , detection_mode , action = 'add' ):
2083+ """
2084+ Conditionally manage the intermediate result receiver based on detection mode.
2085+ Only add the receiver for barcode detection to avoid deadlocks in document/MRZ modes.
2086+
2087+ Args:
2088+ detection_mode (str): The detection mode ('Barcode', 'Document', 'MRZ')
2089+ action (str): 'add' to add receiver, 'remove' to remove receiver
2090+ """
2091+ if not self .cvr_instance or not self .custom_receiver :
2092+ return
2093+
2094+ try :
2095+ intermediate_result_manager = self .cvr_instance .get_intermediate_result_manager ()
2096+
2097+ if action == 'add' and detection_mode == "Barcode" and not self .receiver_active :
2098+ # Only add receiver for barcode detection
2099+ intermediate_result_manager .add_result_receiver (self .custom_receiver )
2100+ self .receiver_active = True
2101+ print ("🔧 Added intermediate receiver for barcode detection" )
2102+
2103+ elif action == 'remove' and self .receiver_active :
2104+ # Remove receiver for non-barcode modes or when explicitly requested
2105+ intermediate_result_manager .remove_result_receiver (self .custom_receiver )
2106+ self .receiver_active = False
2107+ print ("🔧 Removed intermediate receiver to avoid deadlock" )
2108+
2109+ except Exception as e :
2110+ print (f"⚠️ Warning: Error managing intermediate receiver: { e } " )
2111+
20802112 def on_detection_mode_changed (self , mode_text ):
20812113 """Handle detection mode change in camera."""
20822114 mode_name = mode_text .split (" - " )[0 ] # Extract mode name from combo text
@@ -2646,6 +2678,13 @@ def process_current_file(self):
26462678 current_mode_text = self .picture_detection_mode_combo .currentText ()
26472679 mode_name = current_mode_text .split (" - " )[0 ]
26482680
2681+ # Manage intermediate receiver based on detection mode to avoid deadlocks
2682+ # Only use receiver for barcode detection - remove for document/MRZ modes
2683+ if mode_name == "Barcode" :
2684+ self .manage_intermediate_receiver (mode_name , 'add' )
2685+ else :
2686+ self .manage_intermediate_receiver (mode_name , 'remove' )
2687+
26492688 self .is_processing = True
26502689 self .process_button .setEnabled (False )
26512690 self .process_button .setText (f"🔄 Processing { mode_name } ..." )
@@ -2724,9 +2763,18 @@ def on_processing_finished(self, results):
27242763 else :
27252764 self .log_message (f"⚠️ Error on page { i + 1 } : { result .get_error_string ()} " )
27262765
2727- # Extract pages from intermediate receiver for PDF files
2766+ # Extract pages from intermediate receiver for PDF files (only for Barcode mode)
2767+ # For Document/MRZ modes, we extract pages directly from results to avoid deadlock
27282768 if self .current_file_path and self .current_file_path .lower ().endswith ('.pdf' ):
2729- self .extract_pdf_pages_from_receiver ()
2769+ if mode_name == "Barcode" and self .receiver_active :
2770+ self .extract_pdf_pages_from_receiver ()
2771+ else :
2772+ # For Document/MRZ modes, extract pages directly from results
2773+ self .extract_pdf_pages_from_results (results )
2774+ elif self .current_file_path and not self .current_file_path .lower ().endswith ('.pdf' ):
2775+ # For single images, ensure we have the image in current_pages
2776+ if 0 not in self .current_pages and hasattr (self , 'image_widget' ) and self .image_widget .original_image is not None :
2777+ self .current_pages [0 ] = self .image_widget .original_image .copy ()
27302778
27312779 # Setup navigation for multi-page PDFs
27322780 if len (self .current_pages ) > 1 :
@@ -2812,6 +2860,62 @@ def extract_pdf_pages_from_receiver(self):
28122860 else :
28132861 self .log_message ("⚠️ No pages extracted from PDF" )
28142862
2863+ def extract_pdf_pages_from_results (self , captured_results ):
2864+ """
2865+ Extract PDF pages directly from capture results without intermediate receiver.
2866+ This method is used for Document/MRZ modes to avoid deadlock issues.
2867+ """
2868+ try :
2869+ self .current_pages = {}
2870+
2871+ # Get the original image data from each result
2872+ result_list = captured_results .get_results ()
2873+
2874+ for page_index , result in enumerate (result_list ):
2875+ if result .get_error_code () == EnumErrorCode .EC_OK :
2876+ try :
2877+ # Try to get the original image directly from the result
2878+ original_image = result .get_original_image ()
2879+ if original_image is not None :
2880+ # Convert Dynamsoft image to OpenCV format
2881+ from dynamsoft_capture_vision_bundle import ImageIO
2882+ image_io = ImageIO ()
2883+ saved = image_io .save_to_numpy (original_image )
2884+
2885+ if saved is not None :
2886+ # Handle different return formats
2887+ if isinstance (saved , tuple ) and len (saved ) == 3 :
2888+ error_code , error_message , numpy_array = saved
2889+ if error_code == 0 and numpy_array is not None :
2890+ self .current_pages [page_index ] = numpy_array
2891+ elif isinstance (saved , tuple ) and len (saved ) == 2 :
2892+ success , numpy_array = saved
2893+ if success and numpy_array is not None :
2894+ self .current_pages [page_index ] = numpy_array
2895+ else :
2896+ # Direct numpy array return
2897+ self .current_pages [page_index ] = saved
2898+
2899+ self .log_message (f"📄 Extracted page { page_index + 1 } directly from results" )
2900+ else :
2901+ self .log_message (f"⚠️ No image data for page { page_index + 1 } " )
2902+
2903+ except Exception as e :
2904+ self .log_message (f"⚠️ Error extracting page { page_index + 1 } : { e } " )
2905+ continue
2906+ else :
2907+ self .log_message (f"⚠️ Error on page { page_index + 1 } : { result .get_error_string ()} " )
2908+
2909+ # Set the first page as current
2910+ if self .current_pages :
2911+ self .current_page_index = 0
2912+ self .log_message (f"✅ Extracted { len (self .current_pages )} page(s) from PDF results (no receiver)" )
2913+ else :
2914+ self .log_message ("⚠️ No pages extracted from PDF results" )
2915+
2916+ except Exception as e :
2917+ self .log_message (f"❌ Error in direct PDF page extraction: { e } " )
2918+
28152919 def display_current_page (self ):
28162920 """Display the current page with annotations."""
28172921 if self .current_page_index not in self .current_pages :
@@ -3653,8 +3757,10 @@ def enter_license_key(self):
36533757
36543758 self .cvr_instance = CaptureVisionRouter ()
36553759 intermediate_result_manager = self .cvr_instance .get_intermediate_result_manager ()
3760+
3761+ # Create receiver but don't add it yet - only add for barcode detection
36563762 self .custom_receiver = MyIntermediateResultReceiver (intermediate_result_manager )
3657- intermediate_result_manager . add_result_receiver ( self .custom_receiver )
3763+ self .receiver_active = False # Track if receiver is currently active
36583764
36593765 # Update camera widget if it exists
36603766 if hasattr (self , 'camera_widget' ):
0 commit comments