1.1.0版本
This commit is contained in:
2
UniTAP/dev/modules/opf/__init__.py
Normal file
2
UniTAP/dev/modules/opf/__init__.py
Normal file
@@ -0,0 +1,2 @@
|
||||
from UniTAP.dev.modules.opf.handlers import OpfHandlerInternal, OpfHandlerDefault, OPFDialogAnswer
|
||||
from UniTAP.dev.modules.opf.handler import OperatorFeedbackHandler
|
||||
66
UniTAP/dev/modules/opf/handler.py
Normal file
66
UniTAP/dev/modules/opf/handler.py
Normal file
@@ -0,0 +1,66 @@
|
||||
import platform
|
||||
import warnings
|
||||
|
||||
from UniTAP.libs.lib_tsi.tsi_types import TSI_OPF_CALLBACK_STRUCT, TSI_OPF_RETURN_CODE_ABORT
|
||||
from UniTAP.libs.lib_tsi.tsi_io import DeviceIO
|
||||
from UniTAP.utils import tsi_logging as logging
|
||||
from .handlers import OpfHandlerBase, OpfHandlerDefault
|
||||
|
||||
if platform.system() == 'Windows':
|
||||
from ctypes import c_int, POINTER, c_void_p, WINFUNCTYPE
|
||||
|
||||
OPF_CALLBACK_TYPE = WINFUNCTYPE(c_int, POINTER(TSI_OPF_CALLBACK_STRUCT), c_void_p)
|
||||
else:
|
||||
from ctypes import c_int, POINTER, c_void_p, CFUNCTYPE
|
||||
|
||||
OPF_CALLBACK_TYPE = CFUNCTYPE(c_int, POINTER(TSI_OPF_CALLBACK_STRUCT), c_void_p)
|
||||
|
||||
|
||||
class OperatorFeedbackHandler:
|
||||
"""
|
||||
Class `OperatorFeedbackHandler` helps to do required actions during DUT tests. Contains object of `OpfHandlerBase`,
|
||||
that can be overridden.
|
||||
- `handler` - set and get OPF Handler. `OpfHandlerBase` does OPF number 19 and 103,
|
||||
`OpfHandlerInternal` does all OPF, `OpfHandlerDefault` does overridden OPF by user.
|
||||
"""
|
||||
|
||||
def __init__(self, device_io: DeviceIO):
|
||||
global OPF_CALLBACK_TYPE
|
||||
self.__io = device_io
|
||||
self.__tsi_callback = OPF_CALLBACK_TYPE(self.__get_callback())
|
||||
self.__io.set_opf_callback(self.__tsi_callback)
|
||||
|
||||
self.__handler = OpfHandlerDefault()
|
||||
|
||||
def __get_callback(self):
|
||||
def ofp_impl(_struct: POINTER(TSI_OPF_CALLBACK_STRUCT), context_ptr: c_void_p):
|
||||
opf_struct: TSI_OPF_CALLBACK_STRUCT = _struct.contents
|
||||
logging.debug(f"Received OPF dialog with ID: {opf_struct.id()}, Session: {opf_struct.session_id()}.")
|
||||
|
||||
try:
|
||||
return self.handler.handle(opf_struct.id(),
|
||||
opf_struct.write_opf_result,
|
||||
opf_struct.title(),
|
||||
opf_struct.request1(),
|
||||
opf_struct.request2(),
|
||||
opf_struct.parameters())
|
||||
except BaseException as e:
|
||||
warnings.warn(f"OPF Dialog {opf_struct.id()} was aborted due an exception. Exception: {e}")
|
||||
return opf_struct.write_opf_result(TSI_OPF_RETURN_CODE_ABORT)
|
||||
|
||||
return ofp_impl
|
||||
|
||||
@property
|
||||
def handler(self) -> OpfHandlerBase:
|
||||
"""
|
||||
|
||||
Return current OPF handler. Can be overriden in `set` method.
|
||||
|
||||
Returns:
|
||||
object of `OpfHandlerBase` type
|
||||
"""
|
||||
return self.__handler
|
||||
|
||||
@handler.setter
|
||||
def handler(self, value):
|
||||
self.__handler = value
|
||||
3
UniTAP/dev/modules/opf/handlers/__init__.py
Normal file
3
UniTAP/dev/modules/opf/handlers/__init__.py
Normal file
@@ -0,0 +1,3 @@
|
||||
from .base import OPFDialogAnswer, OpfHandlerBase
|
||||
from .default import OpfHandlerDefault
|
||||
from .internal import OpfHandlerInternal
|
||||
51
UniTAP/dev/modules/opf/handlers/base.py
Normal file
51
UniTAP/dev/modules/opf/handlers/base.py
Normal file
@@ -0,0 +1,51 @@
|
||||
import abc
|
||||
from typing import Callable
|
||||
from enum import IntEnum
|
||||
|
||||
from .opf_functions import OPFFunctions, logging, OPFDialogAnswer
|
||||
from UniTAP.dev.modules.opf.parsers import OPFParametersParser
|
||||
|
||||
|
||||
class WrongOPFFunctionSignature(Exception):
|
||||
pass
|
||||
|
||||
|
||||
class OpfHandlerBase:
|
||||
"""
|
||||
Class `OpfHandlerBase` allows working with functions that helps to do required actions during DUT tests.
|
||||
- Use DSC content library `set_dsc_content_library`. If DSC image does not exist, it will be generated.
|
||||
"""
|
||||
__FUNCTIONS_MAP = {
|
||||
19: OPFFunctions.opf_19_handler,
|
||||
103: OPFFunctions.opf_103_handler,
|
||||
}
|
||||
|
||||
def __init__(self):
|
||||
self.__parser = OPFParametersParser()
|
||||
self.__tx = None
|
||||
self.__rx = None
|
||||
self.__callback_before_handling = {}
|
||||
self._dsc_content_library_path = ""
|
||||
|
||||
def _set_roles(self, role_tx, role_rx):
|
||||
self.__tx = role_tx
|
||||
self.__rx = role_rx
|
||||
|
||||
def set_dsc_content_library(self, dsc_content_library_path: str = ""):
|
||||
"""
|
||||
Set new path to DSC content library folder.
|
||||
If path is empty, content library will not use (all images will be generated into OPF functions without saving).
|
||||
|
||||
Arguments:
|
||||
dsc_content_library_path (`str`) - full path to DSC content library folder.
|
||||
"""
|
||||
self._dsc_content_library_path = dsc_content_library_path
|
||||
|
||||
def handle(self, opf_id, reply_answer, *args) -> OPFDialogAnswer:
|
||||
opf_params = self.__parser.parse(opf_id, *args)
|
||||
|
||||
OPFFunctions.dsc_content_library_path = self._dsc_content_library_path
|
||||
return reply_answer(self.__FUNCTIONS_MAP.get(opf_id)(self.__tx, self.__rx, *opf_params))
|
||||
|
||||
def _is_opf_processed(self, opf_id: int):
|
||||
return self.__FUNCTIONS_MAP.get(opf_id) is not None
|
||||
46
UniTAP/dev/modules/opf/handlers/default.py
Normal file
46
UniTAP/dev/modules/opf/handlers/default.py
Normal file
@@ -0,0 +1,46 @@
|
||||
import inspect
|
||||
import warnings
|
||||
from typing import Callable
|
||||
|
||||
from UniTAP.dev.modules.opf.handlers.base import OpfHandlerBase, OPFDialogAnswer,\
|
||||
WrongOPFFunctionSignature
|
||||
from UniTAP.dev.modules.opf.parsers import OPFParametersParser
|
||||
|
||||
|
||||
class OpfHandlerDefault(OpfHandlerBase):
|
||||
"""
|
||||
Class `OpfHandlerDefault` inherit functionality from `OpfHandlerBase` and allows overriding opf functions.
|
||||
Function `assign_function_for_opf_id` allows doing it.
|
||||
"""
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self.__user_callback_dict = {}
|
||||
self.__parser = OPFParametersParser()
|
||||
|
||||
def handle(self, opf_id, reply_answer, *args) -> OPFDialogAnswer:
|
||||
base_opf_handler = super()._is_opf_processed(opf_id)
|
||||
user_opf_handler = self.__user_callback_dict.get(opf_id, None) is not None
|
||||
if not user_opf_handler and not base_opf_handler:
|
||||
warnings.warn(f"Test requested operator feedback dialog with id: {opf_id}, but user "
|
||||
f"function was not provided. Test will be aborted.")
|
||||
return reply_answer(OPFDialogAnswer.ABORT)
|
||||
|
||||
if user_opf_handler:
|
||||
opf_params_for_user = self.__parser.parse(opf_id, *args)
|
||||
return reply_answer(self.__user_callback_dict.get(opf_id, None)(*opf_params_for_user))
|
||||
else:
|
||||
return super().handle(opf_id, reply_answer, *args)
|
||||
|
||||
def assign_function_for_opf_id(self, opf_id: int, func: Callable):
|
||||
"""
|
||||
Assign new function for doing required actions from OPF.
|
||||
|
||||
Arguments:
|
||||
opf_id (`int`) - id of OPF.
|
||||
func (`Callable`) - object of function
|
||||
"""
|
||||
signature = inspect.getfullargspec(func)
|
||||
if signature.annotations['return'] != OPFDialogAnswer:
|
||||
raise WrongOPFFunctionSignature(f"Function MUST declare {OPFDialogAnswer} "
|
||||
f"as return value")
|
||||
self.__user_callback_dict[opf_id] = func
|
||||
110
UniTAP/dev/modules/opf/handlers/internal.py
Normal file
110
UniTAP/dev/modules/opf/handlers/internal.py
Normal file
@@ -0,0 +1,110 @@
|
||||
import inspect
|
||||
from typing import Callable
|
||||
|
||||
from UniTAP.dev.modules.opf.handlers.base import OpfHandlerBase, WrongOPFFunctionSignature
|
||||
from UniTAP.dev.modules.opf.parsers import OPFParametersParser
|
||||
from .opf_functions import *
|
||||
|
||||
|
||||
class OpfHandlerInternal(OpfHandlerBase):
|
||||
|
||||
__FUNCTIONS_MAP = {
|
||||
1: OPFFunctions.opf_1_handler,
|
||||
2: OPFFunctions.opf_2_handler,
|
||||
3: OPFFunctions.opf_3_handler,
|
||||
4: OPFFunctions.opf_4_handler,
|
||||
5: OPFFunctions.opf_5_handler,
|
||||
6: OPFFunctions.opf_6_handler,
|
||||
7: OPFFunctions.opf_7_handler,
|
||||
8: OPFFunctions.opf_8_handler,
|
||||
9: OPFFunctions.opf_9_handler,
|
||||
10: OPFFunctions.opf_10_handler,
|
||||
11: OPFFunctions.opf_11_handler,
|
||||
12: OPFFunctions.opf_12_handler,
|
||||
13: OPFFunctions.opf_13_handler,
|
||||
14: OPFFunctions.opf_14_handler,
|
||||
15: OPFFunctions.opf_15_handler,
|
||||
16: OPFFunctions.opf_16_handler,
|
||||
17: OPFFunctions.opf_17_handler,
|
||||
18: OPFFunctions.opf_18_handler,
|
||||
19: OPFFunctions.opf_19_handler,
|
||||
20: OPFFunctions.opf_20_handler,
|
||||
21: OPFFunctions.opf_21_handler,
|
||||
101: OPFFunctions.opf_101_handler,
|
||||
102: OPFFunctions.opf_102_handler,
|
||||
103: OPFFunctions.opf_103_handler,
|
||||
104: OPFFunctions.opf_104_handler,
|
||||
105: OPFFunctions.opf_105_handler,
|
||||
106: OPFFunctions.opf_106_handler,
|
||||
107: OPFFunctions.opf_107_handler,
|
||||
120: OPFFunctions.opf_120_handler,
|
||||
121: OPFFunctions.opf_121_handler,
|
||||
122: OPFFunctions.opf_122_handler,
|
||||
123: OPFFunctions.opf_123_handler,
|
||||
140: OPFFunctions.opf_140_handler,
|
||||
141: OPFFunctions.opf_141_handler,
|
||||
142: OPFFunctions.opf_142_handler,
|
||||
143: OPFFunctions.opf_143_handler,
|
||||
144: OPFFunctions.opf_144_handler,
|
||||
145: OPFFunctions.opf_145_handler,
|
||||
150: OPFFunctions.opf_150_handler,
|
||||
161: OPFFunctions.opf_161_handler
|
||||
}
|
||||
|
||||
__FUNCTIONS_MAP_AFTER = {
|
||||
1: OPFFunctions.opf_1_after_handler
|
||||
}
|
||||
|
||||
def __init__(self, port_tx, port_rx):
|
||||
super().__init__()
|
||||
self.__parser = OPFParametersParser()
|
||||
self.__tx = port_tx
|
||||
self.__rx = port_rx
|
||||
self.__callback_before_handling = {}
|
||||
self.__callback_after_handling = {}
|
||||
|
||||
def handle(self, opf_id, reply_answer, *args) -> OPFDialogAnswer:
|
||||
opf_params = self.__parser.parse(opf_id, *args)
|
||||
user_opf_before_callback = self.__callback_before_handling.get(opf_id, None)
|
||||
user_opf_after_callback = self.__callback_after_handling.get(opf_id, None)
|
||||
internal_opf_after_callback = self.__FUNCTIONS_MAP_AFTER.get(opf_id, None)
|
||||
|
||||
#
|
||||
# Callback before main callback
|
||||
#
|
||||
if user_opf_before_callback is not None:
|
||||
opf_before_result = user_opf_before_callback(*opf_params)
|
||||
# Interrupt OPF in case of fail "before" OPF
|
||||
if opf_before_result not in [OPFDialogAnswer.PASS, OPFDialogAnswer.PROCEED]:
|
||||
return reply_answer(opf_before_result)
|
||||
|
||||
#
|
||||
# Main callback
|
||||
#
|
||||
OPFFunctions.dsc_content_library_path = self._dsc_content_library_path
|
||||
opf_internal_result = self.__FUNCTIONS_MAP.get(opf_id)(self.__tx, self.__rx, *opf_params)
|
||||
reply_answer(opf_internal_result)
|
||||
|
||||
#
|
||||
# Callback after main callback
|
||||
#
|
||||
if user_opf_after_callback is not None:
|
||||
user_opf_after_callback(*opf_params)
|
||||
elif internal_opf_after_callback is not None:
|
||||
internal_opf_after_callback(self.__tx, self.__rx, *opf_params)
|
||||
|
||||
return opf_internal_result
|
||||
|
||||
def assign_function_before_handling_opf_id(self, opf_id: int, func: Callable):
|
||||
signature = inspect.getfullargspec(func)
|
||||
if signature.annotations['return'] != OPFDialogAnswer:
|
||||
raise WrongOPFFunctionSignature(f"Function MUST declare {OPFDialogAnswer} "
|
||||
f"as return value")
|
||||
self.__callback_before_handling[opf_id] = func
|
||||
|
||||
def assign_function_after_handling_opf_id(self, opf_id: int, func: Callable):
|
||||
signature = inspect.getfullargspec(func)
|
||||
if signature.annotations['return'] != OPFDialogAnswer:
|
||||
raise WrongOPFFunctionSignature(f"Function MUST declare {OPFDialogAnswer} "
|
||||
f"as return value")
|
||||
self.__callback_after_handling[opf_id] = func
|
||||
1390
UniTAP/dev/modules/opf/handlers/opf_functions.py
Normal file
1390
UniTAP/dev/modules/opf/handlers/opf_functions.py
Normal file
File diff suppressed because it is too large
Load Diff
1
UniTAP/dev/modules/opf/parsers/__init__.py
Normal file
1
UniTAP/dev/modules/opf/parsers/__init__.py
Normal file
@@ -0,0 +1 @@
|
||||
from .main_handle import OPFParametersParser
|
||||
44
UniTAP/dev/modules/opf/parsers/main_handle.py
Normal file
44
UniTAP/dev/modules/opf/parsers/main_handle.py
Normal file
@@ -0,0 +1,44 @@
|
||||
from .opf_utils import *
|
||||
|
||||
|
||||
class OPFParametersParser:
|
||||
@staticmethod
|
||||
def parse(opf_id: int, *args) -> list:
|
||||
if opf_id in [1]:
|
||||
return parse_link_training(args[3])
|
||||
if opf_id in [2]:
|
||||
return parse_video_mode_2(args[3])
|
||||
if opf_id in [3, 4, 5, 7, 8, 11, 12, 13, 14, 15, 16, 17, 101, 102, 104, 105, 106, 121, 122, 123, 145, 150, 152, 161]:
|
||||
return parse_message(args[1])
|
||||
if opf_id in [6]:
|
||||
return parse_video_mode_6(args[1], args[3])
|
||||
if opf_id in [9]:
|
||||
return parse_video_mode_9(args[3], args[1])
|
||||
if opf_id in [10]:
|
||||
return parse_opf_10(args[3])
|
||||
if opf_id in [18]:
|
||||
return parse_video_mode_18(args[3])
|
||||
if opf_id in [19]:
|
||||
return parse_video_mode_19(args[3])
|
||||
if opf_id in [20]:
|
||||
return parse_video_mode_20(args[3], args[1])
|
||||
if opf_id in [21]:
|
||||
return parse_opf_21(args[3])
|
||||
if opf_id in [103]:
|
||||
return parse_video_mode_103(args[3])
|
||||
if opf_id in [120]:
|
||||
return parse_video_mode_120(args[3])
|
||||
if opf_id in [140]:
|
||||
return parse_video_mode_140(args[3])
|
||||
if opf_id in [141]:
|
||||
return parse_video_mode_141(args[3])
|
||||
if opf_id in [142]:
|
||||
return [args[1]]
|
||||
if opf_id in [143]:
|
||||
return parse_video_mode_143(args[3])
|
||||
if opf_id in [144]:
|
||||
return parse_video_mode_144(args[3])
|
||||
if opf_id in [151]:
|
||||
return parse_video_mode_103(args[3])
|
||||
else:
|
||||
raise ValueError(f"Received OPF request with unknown code: {opf_id}")
|
||||
327
UniTAP/dev/modules/opf/parsers/opf_utils.py
Normal file
327
UniTAP/dev/modules/opf/parsers/opf_utils.py
Normal file
@@ -0,0 +1,327 @@
|
||||
import re
|
||||
from typing import List, Optional
|
||||
|
||||
from UniTAP.libs.lib_tsi.tsi_types import TSI_OPF_PARAMETER
|
||||
|
||||
|
||||
def parse_link_training(parameters_list: List[TSI_OPF_PARAMETER]):
|
||||
dp_lanes = 0
|
||||
dp_link_rate = 0
|
||||
encoding = None
|
||||
|
||||
for param in parameters_list:
|
||||
if param.name == 'Lane Count':
|
||||
dp_lanes, = re.findall(r'\d+', param.description)
|
||||
if param.name == 'Link Rate':
|
||||
dp_link_rate = re.findall(r'\d+', param.description)
|
||||
if len(dp_link_rate) == 0:
|
||||
dp_link_rate = 0
|
||||
elif len(dp_link_rate) == 2:
|
||||
dp_link_rate = f"{dp_link_rate[0]}.{dp_link_rate[1]}"
|
||||
if len(parameters_list) >= 3:
|
||||
if param.name == 'Encoding':
|
||||
encoding = re.findall(r'\d+\w+/\d+\w+', param.description)
|
||||
if len(encoding) == 0:
|
||||
encoding = "8b/10b"
|
||||
else:
|
||||
encoding = encoding[0]
|
||||
|
||||
return int(dp_lanes), float(dp_link_rate), encoding
|
||||
|
||||
|
||||
def parse_video_mode_2(parameters_list: List[TSI_OPF_PARAMETER]):
|
||||
res_x = 0
|
||||
res_y = 0
|
||||
res_frate = 0
|
||||
res_bpc = 0
|
||||
tim_std = None
|
||||
tim_rb = None
|
||||
|
||||
for param in parameters_list:
|
||||
if param.name == 'Video Mode':
|
||||
result = re.findall(r'\d+|RB1|RB2|VIC \d+|DMT \w+|CVT \w+', param.description)
|
||||
if len(result) == 5:
|
||||
res_x, res_y, res_frate, res_bpc, tim_std = result
|
||||
else:
|
||||
res_x, res_y, res_frate, res_bpc, tim_rb, tim_std = result
|
||||
|
||||
return int(res_x), int(res_y), int(float(res_frate) * 1000), int(res_bpc), tim_std, tim_rb
|
||||
|
||||
|
||||
def parse_video_mode_6(pattern_request: str, parameters_list: List[TSI_OPF_PARAMETER]):
|
||||
res_x = 0
|
||||
res_y = 0
|
||||
res_frate = 0
|
||||
res_bpc = 0
|
||||
col_format = 0
|
||||
col_range = 0
|
||||
col_yc = None
|
||||
timing_standard = None
|
||||
|
||||
pattern_name = re.findall(r'Color Ramp|Color Square', pattern_request)[0]
|
||||
|
||||
for param in parameters_list:
|
||||
if param.name == 'Video Mode':
|
||||
result = re.findall(r'\d+|RB1|RB2', param.description)
|
||||
if len(result) == 3:
|
||||
res_x, res_y, res_frate = result
|
||||
else:
|
||||
res_x, res_y, res_frate, timing_standard = result
|
||||
elif param.name == 'Color Format':
|
||||
result = re.findall(r'RGB|YCbCr 4:4:4|YCbCr 4:2:2|YCbCr 4:2:0|Simple 4:2:2|ITU-601|ITU-709|\d+|VESA|CTA',
|
||||
param.description)
|
||||
if len(result) == 3:
|
||||
col_format, res_bpc, col_range = result
|
||||
elif len(result) == 4:
|
||||
col_format, col_yc, res_bpc, col_range = result
|
||||
|
||||
return int(res_x), int(res_y), int(float(res_frate) * 1000), int(
|
||||
res_bpc), timing_standard, col_format, col_range, col_yc, pattern_name
|
||||
|
||||
|
||||
def parse_video_mode_9(parameters_list: List[TSI_OPF_PARAMETER], pattern_request: Optional[str] = None):
|
||||
res_x = 0
|
||||
res_y = 0
|
||||
res_frate = 0
|
||||
res_bpc = 0
|
||||
tim_std = None
|
||||
pattern_name = None
|
||||
|
||||
if pattern_request is not None:
|
||||
pattern_name = re.findall(r'Color Ramp|Color Square', pattern_request)[0]
|
||||
|
||||
for param in parameters_list:
|
||||
if param.name == 'Video Mode':
|
||||
result = re.findall(r'\d+|RB1|RB2', param.description)
|
||||
if len(result) == 4:
|
||||
res_x, res_y, res_frate, res_bpc = result
|
||||
elif len(result) == 5:
|
||||
res_x, res_y, res_frate, tim_std, res_bpc = result
|
||||
|
||||
return int(res_x), int(res_y), int(float(res_frate) * 1000), int(res_bpc), tim_std, pattern_name
|
||||
|
||||
|
||||
def parse_opf_10(parameters_list: List[TSI_OPF_PARAMETER]):
|
||||
res_x, res_y, res_frate, res_bpc, timing_standard = [0] * 5
|
||||
|
||||
audio_pattern = ''
|
||||
ch_count = 0
|
||||
sample_freq = 0
|
||||
sample_size = 0
|
||||
ch_alloc = 0
|
||||
ch_info = []
|
||||
|
||||
for ind, param in enumerate(parameters_list):
|
||||
if param.name == 'Video Mode' and param.description != "Video is not required":
|
||||
res_x, res_y, res_frate, res_bpc, timing_standard, _ = parse_video_mode_9(parameters_list=parameters_list)
|
||||
elif param.name == 'Audio Pattern':
|
||||
audio_pattern = param.description
|
||||
elif param.name == 'Channel Count':
|
||||
ch_count, = re.findall(r'\d+', param.description)
|
||||
elif param.name == 'Sample Frequency':
|
||||
sample_freq, = re.findall(r'\d+', param.description)
|
||||
elif param.name == 'Sample Size':
|
||||
sample_size, = re.findall(r'\d+', param.description)
|
||||
elif param.name == 'Channel Allocation' and ind == 5:
|
||||
ch_alloc = re.findall(r'FL/FR|LFE1|FC|BL/BR|BC|FLC/FRC|RLC/RRC|FLW/FRW|TpFL/TpFR|TpC|TpFC|LS/RS|LFE2|TpBC'
|
||||
r'|SiL/SiR|TpSiL/TpSiR|TpBL/TpBR|BtFC|BtFL/BtFR|TpLS/TpRS', param.description)
|
||||
elif param.name == 'Channel Allocation' and ind > 5:
|
||||
ch_info.append(re.findall(r'\d+', param.description)[0])
|
||||
|
||||
return int(res_x), int(res_y), int(res_frate), int(res_bpc), timing_standard, audio_pattern, \
|
||||
int(ch_count), int(sample_freq), int(sample_size), ch_alloc, ch_info if len(ch_info) > 0 else None
|
||||
|
||||
|
||||
def parse_message(message: str):
|
||||
return [str(message)]
|
||||
|
||||
|
||||
def parse_video_mode_19(parameters_list: List[TSI_OPF_PARAMETER]):
|
||||
use_3tap = False
|
||||
for param in parameters_list:
|
||||
if param.name == 'Conversion type filter':
|
||||
use_3tap = param.description.find('3-Tap Filter') != -1
|
||||
return [use_3tap]
|
||||
|
||||
|
||||
def parse_video_mode_18(parameters_list: List[TSI_OPF_PARAMETER]):
|
||||
res_x = 0
|
||||
res_y = 0
|
||||
res_frate = 0
|
||||
res_bpc = 0
|
||||
col_format = 0
|
||||
col_range = 0
|
||||
col_yc = 0
|
||||
tim_std = 0
|
||||
|
||||
for param in parameters_list:
|
||||
if param.name == 'Video Mode':
|
||||
res_x, res_y, res_frate, tim_std = re.findall(r'\d+|CTA|RB1|RB2', param.description)
|
||||
elif param.name == 'Color Format':
|
||||
color_format_str = param.description.replace("ITU-709", '')
|
||||
col_format, res_bpc, col_range = re.findall(
|
||||
r'RGB|YCbCr 4:2:2|YCbCr 4:4:4|YCbCr 4:2:0|Simple 4:2:2|\d+|VESA|CTA', color_format_str)
|
||||
col_yc = 'ITU-709' if col_format != 'RGB' else None
|
||||
|
||||
return int(res_x), int(res_y), int(float(res_frate) * 1000), int(res_bpc), col_format, col_range, col_yc, tim_std
|
||||
|
||||
|
||||
def parse_video_mode_20(parameters_list: List[TSI_OPF_PARAMETER], pattern_request: Optional[str] = None):
|
||||
pattern_name = None
|
||||
res_x = 0
|
||||
res_y = 0
|
||||
res_frate = 0
|
||||
res_bpc = 0
|
||||
col_format = 0
|
||||
col_range = 0
|
||||
col_yc = None
|
||||
tim_std = ""
|
||||
enable_dsc = False
|
||||
|
||||
if pattern_request is not None:
|
||||
if pattern_request.find('DSC compressed') != -1:
|
||||
enable_dsc = True
|
||||
else:
|
||||
pattern_name = re.findall(r'No Video|Color Ramp|Color Square|Black and Vertical lines|Any', pattern_request)[0]
|
||||
enable_dsc = False
|
||||
|
||||
for param in parameters_list:
|
||||
if param.name == 'Video Mode':
|
||||
line = param.description.split("Hz")
|
||||
res_x, res_y, res_frate = re.findall(r'\d+', line[0])
|
||||
tim_std = re.findall(r'VIC \d+|DMT \w+|UFG \d+|CVT RB\d+|CVT|OVT', line[1])
|
||||
elif param.name == 'Color Format':
|
||||
color_format_str = param.description
|
||||
result = re.findall(r'RGB|YCbCr 4:2:2|YCbCr 4:4:4|YCbCr 4:2:0|Simple 4:2:2|ITU-601|ITU-709|\d+|VESA|CTA',
|
||||
color_format_str)
|
||||
if len(result) == 3:
|
||||
col_format, res_bpc, col_range = result
|
||||
elif len(result) == 4:
|
||||
col_format, col_yc, res_bpc, col_range = result
|
||||
|
||||
return int(res_x), int(res_y), int(float(res_frate) * 1000), int(res_bpc), col_format, col_range, col_yc, tim_std,\
|
||||
pattern_name, enable_dsc
|
||||
|
||||
|
||||
def parse_opf_21(parameters_list: List[TSI_OPF_PARAMETER]):
|
||||
audio_pattern = ''
|
||||
ch_count = 0
|
||||
sample_freq = 0
|
||||
sample_size = 0
|
||||
ch_alloc = 0
|
||||
ch_info = []
|
||||
|
||||
for ind, param in enumerate(parameters_list):
|
||||
if param.name == 'Audio Pattern':
|
||||
audio_pattern = param.description
|
||||
elif param.name == 'Channel Count':
|
||||
ch_count, = re.findall(r'\d+', param.description)
|
||||
elif param.name == 'Sample Frequency':
|
||||
sample_freq, = re.findall(r'\d+', param.description)
|
||||
elif param.name == 'Sample Size':
|
||||
sample_size, = re.findall(r'\d+', param.description)
|
||||
elif param.name == 'Channel Allocation' and ind == 5:
|
||||
ch_alloc = re.findall(r'FL/FR|LFE1|FC|BL/BR|BC|FLC/FRC|RLC/RRC|FLW/FRW|TpFL/TpFR|TpC|TpFC|LS/RS|LFE2|TpBC'
|
||||
r'|SiL/SiR|TpSiL/TpSiR|TpBL/TpBR|BtFC|BtFL/BtFR|TpLS/TpRS', param.description)
|
||||
elif param.name == 'Channel Allocation' and ind > 5:
|
||||
ch_info.append(re.findall(r'\d+', param.description)[0])
|
||||
|
||||
return (audio_pattern, int(ch_count), int(sample_freq), int(sample_size), ch_alloc,
|
||||
ch_info if len(ch_info) > 0 else None)
|
||||
|
||||
|
||||
def parse_video_mode_103(parameters_list: List[TSI_OPF_PARAMETER]):
|
||||
width = 0
|
||||
height = 0
|
||||
res_frate = 60000
|
||||
color_format = ""
|
||||
block_prediction = False
|
||||
bpc = 8
|
||||
bpp = 8
|
||||
h_slice_number = 0
|
||||
buffer_bit_depth = 8
|
||||
v_slice_number = 0
|
||||
dsc_v_minor = 1
|
||||
dsc_v_major = 1
|
||||
|
||||
for param in parameters_list:
|
||||
if param.name == "Video mode":
|
||||
width, height, res_frate = re.findall(r'\d+', param.description)
|
||||
elif param.name == "Color format":
|
||||
color_format = re.findall(r'RGB|YCbCr 4:2:2|YCbCr 4:4:4|YCbCr 4:2:0|Simple 4:2:2', param.description)[0]
|
||||
elif param.name == 'Block prediction':
|
||||
block_prediction = False if param.description.find("disabled") != -1 else True
|
||||
elif param.name == 'Bits per component':
|
||||
bpc = re.findall(r'\d+', param.description)[0]
|
||||
elif param.name == 'Bits per pixel (1/16 units)':
|
||||
bpp = re.findall(r'\d+', param.description)[2]
|
||||
elif param.name == 'Horizontal slice number':
|
||||
h_slice_number = re.findall(r'\d+', param.description)[0]
|
||||
elif param.name == 'Buffer bit depth':
|
||||
buffer_bit_depth = re.findall(r'\d+', param.description)[0]
|
||||
elif param.name == 'Vertical slice number':
|
||||
v_slice_number = re.findall(r'\d+', param.description)[0]
|
||||
elif param.name == 'DSC Algorithm revision':
|
||||
dsc_v_minor, dsc_v_major = re.findall(r'\d+', param.description)
|
||||
|
||||
return int(width), int(height), int(float(res_frate) * 1000), color_format, block_prediction, int(bpc), int(bpp),\
|
||||
int(h_slice_number), int(buffer_bit_depth), int(v_slice_number), int(dsc_v_major), int(dsc_v_minor)
|
||||
|
||||
|
||||
def parse_video_mode_120(parameters_list: List[TSI_OPF_PARAMETER]):
|
||||
res_x = 0
|
||||
res_y = 0
|
||||
res_frate = 0
|
||||
res_bpc = 0
|
||||
color_format = ""
|
||||
|
||||
for param in parameters_list:
|
||||
if param.name == "Video pattern":
|
||||
res_x, res_y, res_frate, res_bpc, color_format = re.findall(r'\d+|RGB|YCbCr 4:2:2|YCbCr 4:4:4|YCbCr 4:2:0|Simple 4:2:2|YCbCr422|YCbCr444|YCbCr420|Simple422', param.description)
|
||||
|
||||
return int(res_x), int(res_y), int(float(res_frate) * 1000), int(res_bpc), color_format
|
||||
|
||||
|
||||
def parse_video_mode_140(parameters_list: List[TSI_OPF_PARAMETER]):
|
||||
res_x = 0
|
||||
res_y = 0
|
||||
res_frate = 0
|
||||
tim_std = 0
|
||||
tim_std_num = None
|
||||
|
||||
for param in parameters_list:
|
||||
if param.name == 'Timing':
|
||||
result = re.findall(r'\d[a-fA-F]h|\d+|VIC|DMT|RB1|RB2|RB3', param.description)
|
||||
if len(result) == 5:
|
||||
res_x, res_y, res_frate, tim_std, tim_std_num = result
|
||||
elif len(result) == 4:
|
||||
res_x, res_y, res_frate, tim_std = result
|
||||
|
||||
return int(res_x), int(res_y), int(float(res_frate) * 1000), tim_std, tim_std_num
|
||||
|
||||
|
||||
def parse_video_mode_141(parameters_list: List[TSI_OPF_PARAMETER]):
|
||||
audio_format = ''
|
||||
channels = 0
|
||||
size = 0
|
||||
rate = 0
|
||||
|
||||
for param in parameters_list:
|
||||
if param.name == 'Audio':
|
||||
audio_format, channels, size, rate = re.findall(r'LPCM|\d+.\d+|\d+', param.description)
|
||||
|
||||
return audio_format, int(channels), int(size), int(float(rate) * 1000)
|
||||
|
||||
|
||||
def parse_video_mode_143(parameters_list: List[TSI_OPF_PARAMETER]):
|
||||
res_frate = 0
|
||||
|
||||
for param in parameters_list:
|
||||
if param.name == 'Refresh Rate':
|
||||
res_frate = re.findall(r'\d+', param.description)[0]
|
||||
|
||||
return [int(float(res_frate))]
|
||||
|
||||
|
||||
def parse_video_mode_144(parameters_list: List[TSI_OPF_PARAMETER]):
|
||||
return [parameters_list[0].description]
|
||||
Reference in New Issue
Block a user