fix: KC color strip test preview — use LiveStreamManager instead of raw engine
Lint & Test / test (push) Successful in 1m28s
Lint & Test / test (push) Successful in 1m28s
BetterCam (DXGI) only supports one capture session per display, so creating a second engine for the KC test produced no frames when a target was already running. Now uses LiveStreamManager.acquire() which ref-counts and reuses the running capture. Also removed double postprocessing — ProcessedLiveStream already applies filters, so re-applying them in the KC test halved the resolution (960x400 → 240x100).
This commit is contained in:
@@ -485,7 +485,6 @@ async def test_key_colors_ws(
|
||||
calculate_dominant_color,
|
||||
calculate_median_color,
|
||||
)
|
||||
from wled_controller.core.filters import FilterRegistry, ImagePool
|
||||
from wled_controller.storage.picture_source import ScreenCapturePictureSource
|
||||
from wled_controller.utils.image_codec import encode_jpeg_data_uri, resize_down
|
||||
|
||||
@@ -497,7 +496,6 @@ async def test_key_colors_ws(
|
||||
source_store = get_picture_source_store()
|
||||
manager = get_processor_manager()
|
||||
device_store = get_device_store()
|
||||
pp_store = get_pp_template_store()
|
||||
|
||||
try:
|
||||
source = store.get_source(source_id)
|
||||
@@ -546,11 +544,19 @@ async def test_key_colors_ws(
|
||||
await websocket.accept()
|
||||
logger.info(f"KC CSS test WS connected for {source_id} (fps={fps})")
|
||||
|
||||
# Use LiveStreamManager — reuses the already-running capture engine when a
|
||||
# target is active. BetterCam (DXGI) only supports one session per display,
|
||||
# so creating a second engine would produce no frames.
|
||||
live_stream_mgr = manager._live_stream_manager
|
||||
live_stream = None
|
||||
|
||||
try:
|
||||
live_stream = await asyncio.to_thread(live_stream_mgr.acquire, source.picture_source_id)
|
||||
except Exception as e:
|
||||
logger.error(f"KC test: LiveStream acquire failed: {e}")
|
||||
await websocket.send_text(ws_json.dumps({"type": "error", "detail": str(e)}))
|
||||
await websocket.close(code=4003, reason=str(e))
|
||||
return
|
||||
|
||||
try:
|
||||
prev_frame_ref = None
|
||||
|
||||
while True:
|
||||
@@ -564,26 +570,14 @@ async def test_key_colors_ws(
|
||||
await asyncio.sleep(frame_interval * 0.5)
|
||||
continue
|
||||
prev_frame_ref = capture
|
||||
|
||||
cur_image = capture.image
|
||||
|
||||
if not isinstance(cur_image, np.ndarray):
|
||||
await asyncio.sleep(frame_interval)
|
||||
continue
|
||||
|
||||
# Apply postprocessing
|
||||
pp_ids = chain.get("postprocessing_template_ids", [])
|
||||
if pp_ids and pp_store:
|
||||
pool = ImagePool()
|
||||
for pp_id in pp_ids:
|
||||
try:
|
||||
pp = pp_store.get_template(pp_id)
|
||||
for fi in pp_store.resolve_filter_instances(pp.filters):
|
||||
f = FilterRegistry.create_instance(fi.filter_id, fi.options)
|
||||
result = f.process_image(cur_image, pool)
|
||||
if result is not None:
|
||||
cur_image = result
|
||||
except Exception:
|
||||
pass
|
||||
# NOTE: postprocessing is already applied by the ProcessedLiveStream
|
||||
# when using LiveStreamManager.acquire() — do NOT re-apply here.
|
||||
|
||||
# Re-read source for hot-update support
|
||||
try:
|
||||
@@ -647,11 +641,10 @@ async def test_key_colors_ws(
|
||||
except Exception as e:
|
||||
logger.error(f"KC CSS test WS error: {e}", exc_info=True)
|
||||
finally:
|
||||
if live_stream is not None:
|
||||
try:
|
||||
await asyncio.to_thread(live_stream_mgr.release, source.picture_source_id)
|
||||
except Exception:
|
||||
pass
|
||||
try:
|
||||
await asyncio.to_thread(live_stream_mgr.release, source.picture_source_id)
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
|
||||
# ===== CALIBRATION TEST =====
|
||||
|
||||
Reference in New Issue
Block a user