根据新版本调整set_pattern:0~65535

This commit is contained in:
xinzhu.yin
2026-07-07 18:59:44 +08:00
parent 9fa811a9eb
commit 32aaef1c0f
24 changed files with 3016 additions and 279 deletions

View File

@@ -43,6 +43,8 @@ from app.ucd.domain import (
is_ycbcr,
)
from app.ucd.enum import UCDEnum
from app.ucd.pg_status import read_pattern_generator_status_lines
from app.solid_color_scale import SOLID_COLOR_MIN_BPC, clamp_solid_color, pack_solid_color_hw_registers
log = logging.getLogger(__name__)
_DEVICE_LOCK_TIMEOUT_SECONDS = 8.0
@@ -108,6 +110,7 @@ class _UcdSdkBackend:
self.current_pattern_params = None
self.current_pattern_index = 0
self.last_error = None
self._solid_color_stream_ready = False
def search_device(self):
"""搜索可用设备"""
@@ -213,6 +216,10 @@ class _UcdSdkBackend:
self.current_pattern_params = None
self.current_pattern_index = 0
self.current_interface = "HDMI"
self._solid_color_stream_ready = False
def _invalidate_solid_color_stream(self) -> None:
self._solid_color_stream_ready = False
def _force_cleanup(self):
"""强制清理所有状态"""
@@ -440,6 +447,7 @@ class _UcdSdkBackend:
pg, _ = self.get_tx_modules()
log.info("UcdSdk.set_video_mode calling pg.set_vm()")
pg.set_vm(vm=video_mode)
self._invalidate_solid_color_stream()
self._stop_audio_output()
log.info("UcdSdk.set_video_mode done")
self._last_sent_config = current_config
@@ -681,6 +689,104 @@ class _UcdSdkBackend:
log.warning("UcdSdk.set_pattern_params unsupported pattern=%s", getattr(pattern, "name", pattern))
return False
def _solid_color_pattern_ids(self):
return {
UCDEnum.VideoPatternInfo.VideoPatternParams.SolidColor,
UCDEnum.VideoPatternInfo.VideoPattern.SolidColor,
}
def _is_solid_color_pattern(self, pattern) -> bool:
return pattern in self._solid_color_pattern_ids()
def _write_pg_solid_color_registers(self, pg, rgb_list) -> None:
"""直接写入 SolidColor 硬件寄存器65535 刻度,无 SDK 左移)。"""
from ctypes import c_uint
from UniTAP.libs.lib_tsi import ci
param0, param1 = pack_solid_color_hw_registers(rgb_list)
pg._become_active()
pg._PatternGenerator__io.set(ci.TSI_PG_PREDEF_PATTERN_PARAM_1, param0, c_uint)
pg._PatternGenerator__io.set(ci.TSI_PG_PREDEF_PATTERN_PARAM_2, param1, c_uint)
log.info(
"UcdSdk._write_pg_solid_color_registers rgb=%s hw=(0x%08X, 0x%08X)",
rgb_list,
param0,
param1,
)
def apply_solid_color(self, rgb, *, force_reapply: bool = False) -> bool:
"""发送 SolidColor顺序对齐 ``work_with_solid_color.py``。
首次(或信号格式变化后):``set_pattern → set_vm → apply() → set_pattern_params``。
同一会话内后续仅 ``set_pattern_params``,避免重复 ``apply()`` 导致 HDMI 重锁、
灰阶测量出现锯齿形 Gamma 曲线。
"""
if not self.status or not self.role:
return False
try:
pg, _ = self.get_tx_modules()
pattern = UCDEnum.VideoPatternInfo.get_video_pattern("solidcolor")
if pattern is None:
log.error("UcdSdk.apply_solid_color failed: solidcolor pattern not found")
return False
rgb_list = [clamp_solid_color(v) for v in list(rgb)[:3]]
if len(rgb_list) < 3:
log.error("UcdSdk.apply_solid_color invalid rgb=%s", rgb)
return False
if self.current_timing is None:
self.current_timing = self._resolve_timing(pg)
if self.current_timing is None:
log.error("UcdSdk.apply_solid_color current_timing is None")
self.last_error = "current_timing is None"
return False
bpc_bumped = False
if self.color_info.bpc < SOLID_COLOR_MIN_BPC:
log.info(
"UcdSdk.apply_solid_color bump bpc %s -> %s for SolidColor video mode",
self.color_info.bpc,
SOLID_COLOR_MIN_BPC,
)
self.color_info.bpc = SOLID_COLOR_MIN_BPC
bpc_bumped = True
self.current_pattern = pattern
self.current_pattern_param = UniTAP.SolidColorParams(
first=rgb_list[0],
second=rgb_list[1],
third=rgb_list[2],
)
need_full_setup = (
force_reapply
or bpc_bumped
or not self._solid_color_stream_ready
)
if need_full_setup:
log.info("UcdSdk.apply_solid_color full setup rgb=%s", rgb_list)
pg.set_pattern(pattern=pattern)
self.set_video_mode()
if not self._apply_pg_output(pg):
log.error("UcdSdk.apply_solid_color pg.apply failed")
self._invalidate_solid_color_stream()
return False
self._solid_color_stream_ready = True
else:
log.info("UcdSdk.apply_solid_color params-only rgb=%s", rgb_list)
self._write_pg_solid_color_registers(pg, rgb_list)
log.info("UcdSdk.apply_solid_color done")
return True
except Exception:
log.exception("UcdSdk.apply_solid_color exception")
self._invalidate_solid_color_stream()
return False
def apply_pattern(self):
"""应用当前pattern"""
if self.current_pattern is not None:
@@ -715,6 +821,7 @@ class _UcdSdkBackend:
def set_ucd_params(self, config):
"""设置UCD323参数"""
self._invalidate_solid_color_stream()
self.last_error = None
self.config = config
test_type = self.config.current_test_type
@@ -799,6 +906,10 @@ class _UcdSdkBackend:
log.error("UcdSdk.send_current_pattern_params failed: set_pattern returned False")
return False
if self._is_solid_color_pattern(self.current_pattern):
log.info("UcdSdk.send_current_pattern_params using apply_solid_color")
return self.apply_solid_color(pattern_params)
log.info("UcdSdk.send_current_pattern_params calling run()")
self.run()
log.info("UcdSdk.send_current_pattern_params done")
@@ -814,12 +925,7 @@ class _UcdSdkBackend:
try:
log.info("UcdSdk.send_solid_rgb_pattern rgb=%s", rgb)
self.current_pattern = UCDEnum.VideoPatternInfo.get_video_pattern("solidcolor")
if self.current_pattern is None:
log.error("UcdSdk.send_solid_rgb_pattern failed: solidcolor pattern not found")
return False
return self.send_current_pattern_params(list(rgb))
return self.apply_solid_color(list(rgb))
except Exception:
log.exception("UcdSdk.send_solid_rgb_pattern exception")
return False
@@ -839,6 +945,20 @@ class _UcdSdkBackend:
except Exception:
return False
def get_pattern_generator_status_lines(
self,
pattern_hint: str | None = None,
) -> list[str]:
"""读取 PG 当前状态,格式对齐 UCD Console 的 Pattern Generator Status。"""
if not self.status or not self.role:
return []
try:
pg, _ = self.get_tx_modules()
return read_pattern_generator_status_lines(pg, pattern_hint=pattern_hint)
except Exception:
log.exception("UcdSdk.get_pattern_generator_status_lines failed")
return []
# ─── §3 DeviceInfo / list_devices ────────────────────────────────
@@ -1244,6 +1364,13 @@ class UCD323Device(IUcdDevice):
self._state = UcdState.APPLIED
return ok
def get_pattern_generator_status_lines(
self,
pattern_hint: str | None = None,
) -> list[str]:
with self._acquire_device_lock("get_pattern_generator_status_lines"):
return self._sdk.get_pattern_generator_status_lines(pattern_hint=pattern_hint)
# --- 内部 ---
def _apply_dynamic_range(self, signal: SignalFormat) -> None:
@@ -1262,6 +1389,13 @@ class UCD323Device(IUcdDevice):
raise UcdConfigError("IMAGE pattern 必须提供 image_path")
return bool(self._sdk.send_image_pattern(pattern.image_path))
if pattern.kind is PatternKind.SOLID:
if pattern.solid_rgb is None:
raise UcdConfigError("SOLID pattern 必须提供 solid_rgb")
if not self._sdk.apply_solid_color(list(pattern.solid_rgb)):
raise UcdApplyFailed("apply_solid_color 返回 False")
return True
# 预定义图案路径:复用 controller.set_pattern + run()
video_pattern = UCDEnum.VideoPatternInfo.get_video_pattern(pattern.kind.value)
@@ -1270,11 +1404,7 @@ class UCD323Device(IUcdDevice):
self._sdk.current_pattern = video_pattern
params: list[int] | None = None
if pattern.kind is PatternKind.SOLID:
if pattern.solid_rgb is None:
raise UcdConfigError("SOLID pattern 必须提供 solid_rgb")
params = list(pattern.solid_rgb)
elif pattern.extras:
if pattern.extras:
params = list(pattern.extras)
if not self._sdk.set_pattern(video_pattern, params):