更新UCD-API库及文档
This commit is contained in:
259
docs/UCD-API文档/examples/work_with_bulk_different_modes.py
Normal file
259
docs/UCD-API文档/examples/work_with_bulk_different_modes.py
Normal file
@@ -0,0 +1,259 @@
|
||||
import os
|
||||
import UniTAP
|
||||
import time
|
||||
import math
|
||||
import threading
|
||||
|
||||
#
|
||||
# Config.
|
||||
#
|
||||
|
||||
BULK_SIZE_MB = 100 # Mb
|
||||
FOLDER_TO_GENERATE = "./BulkData"
|
||||
|
||||
tps3 = True
|
||||
tps4 = True
|
||||
fec = True
|
||||
|
||||
lanes = [
|
||||
1,
|
||||
2,
|
||||
4
|
||||
]
|
||||
|
||||
# If you want to use UCD-400, please, set 'dp_14_mode = True' and 'enable_dp_21_mode = False'
|
||||
# If you want to use UCD-500 in DP 1.4 mode, please, set 'dp_14_mode = True' and 'enable_dp_21_mode = False'
|
||||
# If you want to use UCD-500 in DP 2.1 mode, please, set 'dp_14_mode = False' and 'enable_dp_21_mode = True'
|
||||
dp_14_mode = False
|
||||
bit_rates_14 = [
|
||||
1.62,
|
||||
2.7,
|
||||
5.4,
|
||||
6.75,
|
||||
8.1
|
||||
]
|
||||
|
||||
enable_dp_21_mode = True
|
||||
bit_rates_21 = [
|
||||
10,
|
||||
13.5,
|
||||
20
|
||||
]
|
||||
|
||||
mst = True
|
||||
streams = [
|
||||
0,
|
||||
1,
|
||||
2,
|
||||
3
|
||||
]
|
||||
|
||||
#
|
||||
# Trigger config.
|
||||
#
|
||||
|
||||
trigger_positions = [
|
||||
UniTAP.bulk.TriggerPosition.TP_Start,
|
||||
UniTAP.bulk.TriggerPosition.TP_25,
|
||||
UniTAP.bulk.TriggerPosition.TP_50,
|
||||
UniTAP.bulk.TriggerPosition.TP_75,
|
||||
UniTAP.bulk.TriggerPosition.TP_End
|
||||
]
|
||||
|
||||
# If you do not want to use trigger config, please, set 'None' to variable
|
||||
# Use other types of trigger config. Full list located in 'TriggerType'
|
||||
trigger_config = UniTAP.bulk.TriggerType.U13()
|
||||
trigger_config.position = UniTAP.bulk.TriggerTypeEnum.SourceTypePosition.InitialLT
|
||||
|
||||
|
||||
lUniTAP = UniTAP.TsiLib()
|
||||
|
||||
#
|
||||
# For opening device, please, put serial number of the device as 8 symbol str or put index of device.
|
||||
#
|
||||
# serial_number = "2150C474"
|
||||
# dev = lUniTAP.open(serial_number)
|
||||
|
||||
# If you do not want to write device serial number, you can write index position of device
|
||||
index_position = 0
|
||||
dev = lUniTAP.open(index_position)
|
||||
|
||||
# Need to select type of device: UCD-400 or UCD-500
|
||||
# role = dev.select_role(UniTAP.dev.UCD400.DPSourceDPSink)
|
||||
role = dev.select_role(UniTAP.dev.UCD500.DPSourceDPSink)
|
||||
|
||||
timing_manager = role.dptx.pg.timing_manager
|
||||
|
||||
timings = [
|
||||
timing_manager.get_cta(16),
|
||||
timing_manager.get_cta(90),
|
||||
timing_manager.get_cta(97),
|
||||
timing_manager.get_cta(126),
|
||||
timing_manager.get_cta(196),
|
||||
]
|
||||
|
||||
color_formats = [
|
||||
UniTAP.ColorInfo.ColorFormat.CF_RGB,
|
||||
UniTAP.ColorInfo.ColorFormat.CF_YCbCr_444,
|
||||
UniTAP.ColorInfo.ColorFormat.CF_YCbCr_422,
|
||||
UniTAP.ColorInfo.ColorFormat.CF_YCbCr_420,
|
||||
UniTAP.ColorInfo.ColorFormat.CF_Y_ONLY,
|
||||
UniTAP.ColorInfo.ColorFormat.CF_RAW
|
||||
]
|
||||
|
||||
colorimetry_list = [
|
||||
UniTAP.ColorInfo.Colorimetry.CM_sRGB,
|
||||
UniTAP.ColorInfo.Colorimetry.CM_ITUR_BT601,
|
||||
UniTAP.ColorInfo.Colorimetry.CM_ITUR_BT709
|
||||
]
|
||||
|
||||
# Note: BPC 7 and 14 will be work only with CF_Y_ONLY and CF_RAW
|
||||
bpc_list = [
|
||||
6,
|
||||
7,
|
||||
8,
|
||||
10,
|
||||
12,
|
||||
14,
|
||||
16
|
||||
]
|
||||
|
||||
|
||||
def link_training(dev_role):
|
||||
time.sleep(1)
|
||||
dev_role.dptx.link.start_link_training()
|
||||
|
||||
|
||||
def bool_str_format(value: bool) -> str:
|
||||
return "ON" if value else "OFF"
|
||||
|
||||
|
||||
def prepare_directory_name(_timing, _color_mode, _lane, _rate, _stream, tr_pos, tr_config=None) -> str:
|
||||
tr_conf_str = type(tr_config).__name__ if tr_config is not None else "-"
|
||||
auto_generated_folder = f"cap_[TG_Pos_{tr_pos.name}][TG_Conf-{tr_conf_str}][{'DP1.4' if dp_14_mode else 'DP2.1'}]" \
|
||||
f"[MST-{bool_str_format(mst)}][FEC-{bool_str_format(fec)}][stream-{_stream}]" \
|
||||
f"[TPS3-{bool_str_format(tps3)}][TPS4-{bool_str_format(tps4)}]" \
|
||||
f"[{_timing.hactive}x{_timing.vactive}@" \
|
||||
f"{math.ceil(_timing.frame_rate / 1000)}_{_color_mode.color_format.name}_{_color_mode.bpc}bpc" \
|
||||
f"-{_color_mode.colorimetry.name}]"
|
||||
directory_name = os.path.join(FOLDER_TO_GENERATE, auto_generated_folder)
|
||||
|
||||
return directory_name
|
||||
|
||||
|
||||
def do_bulk_capture(dev_role, _timing, _color_mode, _lane, _rate, _stream):
|
||||
# bulk_size - size of data in megabytes
|
||||
# trigger_position - available position of trigger. Variants: TP_Start, TP_25, TP_50, TP_75, TP_End
|
||||
# trigger_config - one of the variant of active trigger.
|
||||
# assume_scrambler - just flag of assume scrambler
|
||||
|
||||
for tr_pos in trigger_positions:
|
||||
|
||||
thread = None
|
||||
if trigger_config is not None:
|
||||
thread = threading.Thread(target=link_training, args=(role,))
|
||||
thread.start()
|
||||
|
||||
dev_role.dprx.bulk_capturer.start(bulk_size=BULK_SIZE_MB, trigger_position=tr_pos, trigger_config=trigger_config,
|
||||
assume_scrambler=False, gpio=False)
|
||||
dev_role.dprx.bulk_capturer.stop()
|
||||
|
||||
if trigger_config is not None and thread is not None:
|
||||
thread.join()
|
||||
thread.stop_thread = False
|
||||
|
||||
# If you want to get captured data, please, use 'capture_result'. It is the object of class 'ResultBulkObject'.
|
||||
# For saving data in file, please, use 'save_to_bin_file'. You need to set 'directory_name' - name of directory,
|
||||
# where you want to save files. If directory have already existed, is will be clean up.
|
||||
# If directory does not exist, it will be created.
|
||||
result = dev_role.dprx.bulk_capturer.capture_result
|
||||
|
||||
directory_name = prepare_directory_name(_timing, _color_mode, _lane, _rate, _stream, tr_pos, trigger_config)
|
||||
result.save_to_bin_file(directory_name=directory_name)
|
||||
|
||||
|
||||
for lane in lanes:
|
||||
if dp_14_mode:
|
||||
rates = bit_rates_14
|
||||
else:
|
||||
rates = bit_rates_21
|
||||
for timing in timings:
|
||||
for rate in rates:
|
||||
for stream in streams:
|
||||
for color_format in color_formats:
|
||||
for bpc in bpc_list:
|
||||
for colorimetry in colorimetry_list:
|
||||
|
||||
# Configure Sink Link caps
|
||||
caps = UniTAP.LinkCapabilities()
|
||||
caps.max_lane = lane
|
||||
if dp_14_mode:
|
||||
caps.bit_rate = rate
|
||||
else:
|
||||
caps.dp_128_132_bitrates = [rate]
|
||||
caps.fec = fec
|
||||
caps.tps3 = tps3
|
||||
caps.tps4 = tps4
|
||||
caps.mst = mst
|
||||
role.dprx.link.capabilities.set(caps)
|
||||
role.dprx.link.hpd_pulse()
|
||||
time.sleep(0.5)
|
||||
|
||||
# Configure Source Link
|
||||
if dp_14_mode:
|
||||
config = UniTAP.LinkConfig.DP8b10b()
|
||||
config.mst = mst
|
||||
else:
|
||||
config = UniTAP.LinkConfig.DP128b132b()
|
||||
|
||||
config.lane_count = lane
|
||||
config.bit_rate = rate
|
||||
|
||||
if enable_dp_21_mode:
|
||||
config.force_dp_128_132 = True
|
||||
config.try_dp_128_132 = True
|
||||
else:
|
||||
config.force_dp_128_132 = False
|
||||
config.try_dp_128_132 = False
|
||||
|
||||
role.dptx.link.config.set(config)
|
||||
role.dptx.link.start_link_training()
|
||||
time.sleep(0.5)
|
||||
|
||||
color_mode = UniTAP.ColorInfo()
|
||||
color_mode.color_format = color_format
|
||||
color_mode.bpc = bpc
|
||||
color_mode.colorimetry = colorimetry
|
||||
if color_format in [UniTAP.ColorInfo.ColorFormat.CF_RGB,
|
||||
UniTAP.ColorInfo.ColorFormat.CF_RAW,
|
||||
UniTAP.ColorInfo.ColorFormat.CF_Y_ONLY]:
|
||||
color_mode.dynamic_range = UniTAP.ColorInfo.DynamicRange.DR_VESA
|
||||
else:
|
||||
color_mode.dynamic_range = UniTAP.ColorInfo.DynamicRange.DR_CTA
|
||||
|
||||
video_mode = UniTAP.VideoMode(timing=timing, color_info=color_mode)
|
||||
if stream < role.dptx.pg.max_stream_count:
|
||||
role.dptx.pg[stream].set_vm(vm=video_mode)
|
||||
role.dptx.pg[stream].set_pattern(pattern=UniTAP.VideoPattern.ColorBars)
|
||||
role.dptx.pg[stream].apply()
|
||||
res_app = role.dptx.pg[stream].status().error
|
||||
print(f"Stream {stream} - Apply {res_app.__str__()}")
|
||||
if res_app == res_app.OK:
|
||||
print("Start do bulk capturing")
|
||||
try:
|
||||
do_bulk_capture(role, timing, color_mode, lane, rate, stream)
|
||||
print("Bulk capture completed successfully")
|
||||
except BaseException as e:
|
||||
print(f'Error during bulk capturing. Error: {e}')
|
||||
else:
|
||||
print('Cannot start to do bulk capturing, because PG does not apply settings.')
|
||||
|
||||
#
|
||||
# Since the 3.5 version, TsiLib and TSIDevice objects have the option to be closed earlier.
|
||||
# TSIDevice can be closed with the TsiLib method close(). TsiLib can be closed with cleanup().
|
||||
# Clean up will close all opened devices and block ability to open any devices
|
||||
# with same TsiLib object.
|
||||
#
|
||||
lUniTAP.close(dev)
|
||||
|
||||
lUniTAP.cleanup()
|
||||
Reference in New Issue
Block a user