diff --git a/web_viewer/app.py b/web_viewer/app.py index afe990b..f97f576 100644 --- a/web_viewer/app.py +++ b/web_viewer/app.py @@ -60,15 +60,18 @@ async def init_video_fifo(): return try: - print(f"Opening FIFO {VIDEO_FIFO_PATH} for reading (will block until C++ opens for writing)...") + print(f"Opening FIFO {VIDEO_FIFO_PATH} for reading (non-blocking mode)...") loop = asyncio.get_event_loop() - # Open file in BLOCKING mode - this will unblock C++ when it opens for writing + # Open file in NON-BLOCKING mode to prevent deadlock + # GStreamer filesink opens FIFO lazily (only when first frame arrives) + # Using O_NONBLOCK prevents Python from blocking while waiting for C++ writer def open_fifo(): - return open(VIDEO_FIFO_PATH, 'rb', buffering=0) + fd = os.open(VIDEO_FIFO_PATH, os.O_RDONLY | os.O_NONBLOCK) + return os.fdopen(fd, 'rb', buffering=0) video_fifo_file = await loop.run_in_executor(None, open_fifo) - print(f"FIFO opened successfully - C++ should now be writing") + print(f"FIFO opened successfully in non-blocking mode") except Exception as e: print(f"Failed to open video FIFO: {e}") @@ -333,16 +336,39 @@ async def stream_video_from_fifo(): async def read_from_fifo(): """Read from FIFO and pipe to ffmpeg stdin""" nonlocal bytes_written + writer_connected = False + try: while streaming_active: def read_chunk(): - return fifo.read(chunk_size) + try: + return fifo.read(chunk_size) + except BlockingIOError: + # No data available yet (writer not connected or no data) + return None data = await loop.run_in_executor(None, read_chunk) + + if data is None: + # BlockingIOError: no data available, wait a bit + if not writer_connected: + print("Waiting for C++ to start writing to FIFO...") + await asyncio.sleep(0.1) + continue + if not data: - print("FIFO EOF reached") + # Empty data: EOF (writer closed the FIFO) + if writer_connected: + print("FIFO EOF reached - C++ stopped writing") + else: + print("FIFO closed before C++ started writing") break + # Got data! Mark writer as connected + if not writer_connected: + writer_connected = True + print("C++ started writing to FIFO successfully") + if ffmpeg_process and ffmpeg_process.stdin: try: ffmpeg_process.stdin.write(data)