Fix race condition gphoto2 : verrou camera sur preview et capture

This commit is contained in:
2026-04-09 01:49:48 +02:00
parent 076e6d0030
commit 4273caf1ee

View File

@@ -1,6 +1,7 @@
import io
import logging
import subprocess
import threading
import time
from datetime import datetime
@@ -66,6 +67,7 @@ class Camera:
self.webcam = None
self.webcam_index = -1
self.preview_dslr_ok = True # True si le dernier preview DSLR a reussi
self._lock = threading.Lock() # Verrou pour eviter acces gphoto2 concurrent
def connecter(self, source=None) -> bool:
"""Connecte la camera. source: 'gphoto2', 'webcam:0', 'webcam:2', etc."""
@@ -145,6 +147,7 @@ class Camera:
def _capture_gphoto2(self, chemin_dest: Path) -> Path | None:
from PIL import Image as PILImage
with self._lock:
for attempt in range(3):
try:
chemin_camera = self.camera.capture(gp.GP_CAPTURE_IMAGE)
@@ -152,11 +155,9 @@ class Camera:
self.camera.file_get(
chemin_camera.folder, chemin_camera.name, gp.GP_FILE_TYPE_NORMAL, fichier_camera
)
# Sauvegarder le fichier brut temporairement
tmp_path = str(chemin_dest) + ".tmp"
fichier_camera.save(tmp_path)
# Redimensionner (max 4000px de large, JPEG 92%)
img = PILImage.open(tmp_path)
if img.width > 4000:
ratio = 4000 / img.width
@@ -203,6 +204,7 @@ class Camera:
"""Active le LiveView sur les Canon (nécessaire avant capture_preview)."""
if self.mode != "gphoto2" or not self.connectee:
return
with self._lock:
try:
cfg = self.camera.get_config()
vf = cfg.get_child_by_name("viewfinder")
@@ -216,6 +218,7 @@ class Camera:
"""Désactive le LiveView."""
if self.mode != "gphoto2" or not self.connectee:
return
with self._lock:
try:
cfg = self.camera.get_config()
vf = cfg.get_child_by_name("viewfinder")
@@ -226,14 +229,11 @@ class Camera:
log.warning(f"Viewfinder non supporté : {e}")
def _preview_gphoto2(self) -> bytes | None:
with self._lock:
try:
fichier = self.camera.capture_preview()
donnees = bytes(fichier.get_data_and_size())
# Redimensionner pour alléger le WebSocket
img = cv2.imdecode(
np.frombuffer(donnees, dtype=np.uint8),
cv2.IMREAD_COLOR,
)
img = cv2.imdecode(np.frombuffer(donnees, dtype=np.uint8), cv2.IMREAD_COLOR)
if img is not None:
h, w = img.shape[:2]
if w > 960: