sistemati alcuni salvataggi delle immagini/video

This commit is contained in:
VALLONGOL 2026-01-19 15:07:20 +01:00
parent bef6cf6f08
commit ac1d9e23da
4 changed files with 28 additions and 12 deletions

View File

@ -18,7 +18,11 @@ SAVE_RAW_UNKNOWN = True
# Flags to also save decoded previews for quick inspection # Flags to also save decoded previews for quick inspection
# MFD: save BMP; SAR/UNKNOWN: save BMP by default for lossless grayscale # MFD: save BMP; SAR/UNKNOWN: save BMP by default for lossless grayscale
SAVE_BMP_MFD = False SAVE_BMP_MFD = False
SAVE_BMP_SAR = True # By default do not automatically save decoded SAR previews; leave saving
# under user control via the UI checkboxes. Previously this was True and
# caused SAR previews to be written even when the user only enabled video
# recording. Set to False to avoid unexpected saves.
SAVE_BMP_SAR = False
SAVE_BMP_UNKNOWN = True SAVE_BMP_UNKNOWN = True
# Video recording defaults # Video recording defaults

View File

@ -172,13 +172,12 @@ class DumpManager:
except Exception: except Exception:
logger.exception("Error closing video writer") logger.exception("Error closing video writer")
finally: finally:
# Remove the active writer and runtime timestamp but keep
# the recorded video's start time/path so the UI can show
# the last produced file even after recording stopped.
self._video_writers.pop(category, None) self._video_writers.pop(category, None)
self._video_start_times.pop(category, None) # keep _video_start_times[category] and _video_paths[category]
self._last_frame_timestamps.pop(category, None) self._last_frame_timestamps.pop(category, None)
try:
self._video_paths.pop(category, None)
except Exception:
pass
def _enqueue(self, path: str, category: str) -> None: def _enqueue(self, path: str, category: str) -> None:
"""Track saved file and trigger pruning.""" """Track saved file and trigger pruning."""

View File

@ -168,19 +168,27 @@ def dispatch_frame(module: Any, frame: Any, leader: Optional[Any]) -> None:
pass pass
# generic callbacks and saving # generic callbacks and saving
try:
is_mfd = (image_type_id == getattr(module, 'IMAGE_TYPE_MFD', 1))
except Exception:
is_mfd = False
for cb in list(getattr(module, '_callbacks', [])): for cb in list(getattr(module, '_callbacks', [])):
try: try:
if getattr(module, '_save_png', False) and Image is not None and hasattr(frame, 'save'): # Only the MFD generic save is controlled by _save_png. SAR has its
# own _sar_save_png flag handled earlier. Save MFD previews under
# the 'mfd' category so get_last_saved_mfd() can find them.
if is_mfd and getattr(module, '_save_png', False) and Image is not None and hasattr(frame, 'save'):
try: try:
if getattr(module, '_dump_manager', None) is not None: if getattr(module, '_dump_manager', None) is not None:
saved = module._dump_manager.save_preview_from_pil(frame, category='frame', fmt='png') saved = module._dump_manager.save_preview_from_pil(frame, category='mfd', fmt='png')
if saved: if saved:
logging.getLogger().info("VideoReceiverSFP: saved frame to %s", saved) logging.getLogger().info("VideoReceiverSFP: saved MFD preview to %s", saved)
else: else:
ts = time.strftime('%Y%m%d_%H%M%S') + (f"_{int(time.time() * 1000) % 1000:03d}") ts = time.strftime('%Y%m%d_%H%M%S') + (f"_{int(time.time() * 1000) % 1000:03d}")
dumps_dir = getattr(module, '_dumps_dir', os.path.join(os.getcwd(), 'dumps')) dumps_dir = getattr(module, '_dumps_dir', os.path.join(os.getcwd(), 'dumps'))
os.makedirs(dumps_dir, exist_ok=True) os.makedirs(dumps_dir, exist_ok=True)
pngpath = os.path.join(dumps_dir, f'VideoReceiverSFP_frame_{ts}.png') pngpath = os.path.join(dumps_dir, f'VideoReceiverSFP_mfd_{ts}.png')
frame.save(pngpath) frame.save(pngpath)
module._saved_pngs.append(pngpath) module._saved_pngs.append(pngpath)
while len(module._saved_pngs) > module._dump_keep: while len(module._saved_pngs) > module._dump_keep:
@ -190,7 +198,7 @@ def dispatch_frame(module: Any, frame: Any, leader: Optional[Any]) -> None:
except Exception: except Exception:
pass pass
except Exception: except Exception:
logging.getLogger().exception('VideoReceiverSFP: failed to save preview png') logging.getLogger().exception('VideoReceiverSFP: failed to save MFD preview png')
try: try:
cb(frame) cb(frame)
except Exception: except Exception:

View File

@ -12,6 +12,7 @@ import logging
import threading import threading
import tkinter as tk import tkinter as tk
from tkinter import ttk from tkinter import ttk
from tkinter import messagebox
from .sfp_module import SfpConnectorModule from .sfp_module import SfpConnectorModule
@ -326,8 +327,12 @@ def run_orchestrator():
rec_mfd = bool(mfd_vid_save_var.get()) rec_mfd = bool(mfd_vid_save_var.get())
rec_sar = bool(sar_vid_save_var.get()) rec_sar = bool(sar_vid_save_var.get())
# If nothing selected, do nothing (per user request) # If nothing selected, inform the user and abort
if not (save_mfd or save_sar or rec_mfd or rec_sar): if not (save_mfd or save_sar or rec_mfd or rec_sar):
try:
messagebox.showwarning("No selection", "Please select at least one save or record option before starting.")
except Exception:
pass
return return
# Apply selections to module: image saving and video recording only while 'recording' # Apply selections to module: image saving and video recording only while 'recording'