RTSP Fully Implemented
This commit is contained in:
@@ -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")
|
||||
|
||||
|
||||
Reference in New Issue
Block a user