RTSP Fully Implemented

This commit is contained in:
salirezav
2025-11-01 14:58:25 -04:00
parent 43e1dace8c
commit 1a8aa8a027
5 changed files with 204 additions and 23 deletions

View File

@@ -55,19 +55,21 @@ def suppress_camera_errors():
class CameraStreamer:
"""Provides live preview streaming from cameras without blocking recording"""
def __init__(self, camera_config: CameraConfig, device_info: Any, state_manager: StateManager, event_system: EventSystem):
def __init__(self, camera_config: CameraConfig, device_info: Any, state_manager: StateManager, event_system: EventSystem, recorder=None):
self.camera_config = camera_config
self.device_info = device_info
self.state_manager = state_manager
self.event_system = event_system
self.recorder = recorder # Reference to CameraRecorder for camera sharing (reverse direction)
self.logger = logging.getLogger(f"{__name__}.{camera_config.name}")
# Camera handle and properties (separate from recorder)
# Camera handle and properties (separate from recorder, or shared with recorder)
self.hCamera: Optional[int] = None
self.cap = None
self.monoCamera = False
self.frame_buffer = None
self.frame_buffer_size = 0
self._using_shared_camera = False # Flag to indicate if we're sharing recorder's camera
# Streaming state
self.streaming = False
@@ -259,6 +261,21 @@ class CameraStreamer:
try:
self.logger.info(f"Initializing camera for streaming: {self.camera_config.name}")
# Check if recorder is active and has camera open - if so, share it
if self.recorder and self.recorder.hCamera and self.recorder.recording:
self.logger.info("Recorder is active with camera open - will share recorder's camera connection")
self.hCamera = self.recorder.hCamera
# Copy camera properties from recorder
self.cap = self.recorder.cap
self.monoCamera = self.recorder.monoCamera
self.frame_buffer = self.recorder.frame_buffer
self.frame_buffer_size = self.recorder.frame_buffer_size
self._using_shared_camera = True # Mark that we're using shared camera
# Camera is already started by recorder, so we don't need to call CameraPlay
# Also, we need to populate the frame queues from recorder's frames
self.logger.info("Using recorder's camera connection for streaming - will capture frames from recorder")
return True
# Ensure SDK is initialized
ensure_sdk_initialized()
@@ -342,11 +359,16 @@ class CameraStreamer:
def _streaming_loop(self):
"""Main streaming loop that captures frames continuously"""
self.logger.info("Starting streaming loop")
self.logger.info(f"Starting streaming loop (using {'shared camera from recorder' if self._using_shared_camera else 'own camera'})")
try:
while not self._stop_streaming_event.is_set():
try:
# If using shared camera, skip capture - recorder will populate queues
if self._using_shared_camera:
time.sleep(0.1) # Just wait, recorder populates queues
continue
# Capture frame with timeout
pRawData, FrameHead = mvsdk.CameraGetImageBuffer(self.hCamera, 200) # 200ms timeout
@@ -443,13 +465,21 @@ class CameraStreamer:
def _cleanup_camera(self):
"""Clean up camera resources"""
try:
if self.frame_buffer:
# Only cleanup frame buffer if we allocated it (not sharing with recorder)
if self.frame_buffer and not self._using_shared_camera:
mvsdk.CameraAlignFree(self.frame_buffer)
self.frame_buffer = None
if self.hCamera is not None:
# Only uninitialize camera if we own it (not sharing with recorder)
if self.hCamera is not None and not self._using_shared_camera:
mvsdk.CameraUnInit(self.hCamera)
self.hCamera = None
elif self._using_shared_camera:
# Just clear references, don't free shared resources
self.hCamera = None
self.cap = None
self.frame_buffer = None
self._using_shared_camera = False
self.logger.info("Camera resources cleaned up for streaming")