first commit
4
.gitignore
vendored
Executable file
@ -0,0 +1,4 @@
|
||||
bin
|
||||
build
|
||||
.vscode
|
||||
output
|
3
.idea/.gitignore
generated
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
# Default ignored files
|
||||
/shelf/
|
||||
/workspace.xml
|
20
.idea/CppBuildDebug_CMakeAppBuildConfigurations.xml
generated
Normal file
@ -0,0 +1,20 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="CppBuildDebug_CppBuildConfigurations">
|
||||
<option name="cppBuildConfigurations">
|
||||
<list>
|
||||
<CppBuildConfiguration>
|
||||
<option name="buildDirectory" value="build/" />
|
||||
<option name="buildOptions" value="-- -j 9" />
|
||||
<option name="buildType" value="Release" />
|
||||
<option name="cmakeOptions" value="-DCMAKE_BUILD_TYPE=Release" />
|
||||
<option name="name" value="Debug_ss928" />
|
||||
<option name="selected" value="true" />
|
||||
<option name="toolchainName" value="build_conf_ss928" />
|
||||
<option name="toolchainUuid" value="8bc3bf58-e069-4eca-a9b6-292381c929b6" />
|
||||
</CppBuildConfiguration>
|
||||
</list>
|
||||
</option>
|
||||
<option name="select" value="Debug_ss928" />
|
||||
</component>
|
||||
</project>
|
6
.idea/misc.xml
generated
Normal file
@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectRootManager">
|
||||
<output url="file://$PROJECT_DIR$/out" />
|
||||
</component>
|
||||
</project>
|
8
.idea/modules.xml
generated
Normal file
@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectModuleManager">
|
||||
<modules>
|
||||
<module fileurl="file://$PROJECT_DIR$/.idea/ss928_framework.iml" filepath="$PROJECT_DIR$/.idea/ss928_framework.iml" />
|
||||
</modules>
|
||||
</component>
|
||||
</project>
|
9
.idea/ss928_framework.iml
generated
Normal file
@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module type="JAVA_MODULE" version="4">
|
||||
<component name="NewModuleRootManager" inherit-compiler-output="true">
|
||||
<exclude-output />
|
||||
<content url="file://$MODULE_DIR$" />
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
</component>
|
||||
</module>
|
116
CMakeLists.txt
Executable file
@ -0,0 +1,116 @@
|
||||
cmake_minimum_required(VERSION 3.24)
|
||||
|
||||
include(${CMAKE_SOURCE_DIR}/cmake/cmakebase.cmake)
|
||||
include(${CMAKE_SOURCE_DIR}/cmake/project.cmake)
|
||||
include(${CMAKE_SOURCE_DIR}/cmake/ss928.cmake)
|
||||
|
||||
message(STATUS "========================")
|
||||
message(STATUS ${CMAKE_SYSTEM_NAME})
|
||||
message(STATUS ${CMAKE_SYSTEM_PROCESSOR})
|
||||
message(STATUS "========================")
|
||||
|
||||
PROJECT(ss928_exe)
|
||||
set(CMAKE_SOURCE_DIR "./")
|
||||
|
||||
find_package(OpenCV 4.10)
|
||||
if(NOT OpenCV_FOUND)
|
||||
message(FATAL_ERROR "OpenCV >= 4.10 not found.")
|
||||
endif()
|
||||
MESSAGE(${OpenCV_VERSION})
|
||||
|
||||
# 检测操作系统和架构
|
||||
if(CMAKE_SYSTEM_NAME STREQUAL "Linux")
|
||||
if(CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64")
|
||||
set(PLATFORM "linux/x64")
|
||||
elseif(CMAKE_SYSTEM_PROCESSOR STREQUAL "aarch64")
|
||||
set(PLATFORM "linux/aarch64")
|
||||
else()
|
||||
message(FATAL_ERROR "Unsupported architecture on Linux")
|
||||
endif()
|
||||
elseif(CMAKE_SYSTEM_NAME STREQUAL "Windows")
|
||||
if(CMAKE_SIZEOF_VOID_P EQUAL 8)
|
||||
set(PLATFORM "windows/x64")
|
||||
else()
|
||||
message(FATAL_ERROR "Unsupported architecture on Windows")
|
||||
endif()
|
||||
else()
|
||||
message(FATAL_ERROR "Unsupported operating system")
|
||||
endif()
|
||||
|
||||
# 输出当前系统和架构
|
||||
message(STATUS "operating system: ${PLATFORM}")
|
||||
|
||||
SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_SOURCE_DIR}/output/")
|
||||
|
||||
INCLUDE_DIRECTORIES(
|
||||
${CMAKE_SOURCE_DIR}/ss928sdk/common/
|
||||
${CMAKE_SOURCE_DIR}/ss928sdk/common/audio/adp
|
||||
${CMAKE_SOURCE_DIR}/ss928sdk/include/
|
||||
${CMAKE_SOURCE_DIR}/ss928sdk/include/npu
|
||||
${CMAKE_SOURCE_DIR}/ss928sdk/include/svp_npu
|
||||
${CMAKE_SOURCE_DIR}/svp/
|
||||
${CMAKE_SOURCE_DIR}/svp/common/
|
||||
#${CMAKE_SOURCE_DIR}/svp/npu/include/
|
||||
# ${CMAKE_SOURCE_DIR}/svp/npu/sample_svp_npu/
|
||||
${CMAKE_SOURCE_DIR}/thridpart/ncnn/include/
|
||||
${CMAKE_SOURCE_DIR}/libapi/
|
||||
${CMAKE_SOURCE_DIR}/libapi/include
|
||||
${CMAKE_SOURCE_DIR}/libapi/sort/include
|
||||
${CMAKE_SOURCE_DIR}/libapi/svp_npu
|
||||
${CMAKE_SOURCE_DIR}/libapi/sys
|
||||
${CMAKE_SOURCE_DIR}/libapi/ive
|
||||
"/usr/local/include/opencv4"
|
||||
)
|
||||
LINK_DIRECTORIES(
|
||||
${CMAKE_SOURCE_DIR}/ss928sdk/lib/
|
||||
${CMAKE_SOURCE_DIR}/ss928sdk/lib/npu/
|
||||
${CMAKE_SOURCE_DIR}/ss928sdk/lib/svp_npu
|
||||
${CMAKE_SOURCE_DIR}/thridpart/ncnn/lib
|
||||
/usr/lib/aarch64-linux-gnu
|
||||
)
|
||||
|
||||
aux_source_directory(${CMAKE_SOURCE_DIR}/ss928sdk/common/ SOCSDKCOMMON_SRCLIST)
|
||||
aux_source_directory(${CMAKE_SOURCE_DIR}/ss928sdk/common/audio SOCSDKCOMMON_SRCLIST)
|
||||
aux_source_directory(${CMAKE_SOURCE_DIR}/svp/common/ SVP_SRCLIST)
|
||||
|
||||
aux_source_directory(${CMAKE_SOURCE_DIR}/svp/ SVP_SRCLIST)
|
||||
aux_source_directory(${CMAKE_SOURCE_DIR}/libapi/sort/src LIBAPI_SRCLIST)
|
||||
aux_source_directory(${CMAKE_SOURCE_DIR}/libapi/svp_npu LIBAPI_SRCLIST)
|
||||
aux_source_directory(${CMAKE_SOURCE_DIR}/libapi/sys LIBAPI_SRCLIST)
|
||||
aux_source_directory(${CMAKE_SOURCE_DIR}/libapi/ive LIBAPI_SRCLIST)
|
||||
aux_source_directory(${CMAKE_SOURCE_DIR}/libapi/ LIBAPI_SRCLIST)
|
||||
|
||||
add_executable(${PROJECT_NAME} ${SVP_SRCLIST} ${SOCSDKCOMMON_SRCLIST} ${LIBAPI_SRCLIST})
|
||||
set_target_properties(${PROJECT_NAME} PROPERTIES LINK_FLAGS "-Wl,-rpath-link,/usr/lib/aarch64-linux-gnu")
|
||||
target_link_libraries(
|
||||
${PROJECT_NAME}
|
||||
${SOC_LIBS}
|
||||
${SYSTEM_LINK_LIB}
|
||||
/home/setups/ss928_framework/thridpart/ncnn/lib/libncnn.a
|
||||
/home/setups/ss928_framework/thridpart/ncnn/lib/libgomp.a
|
||||
${OpenCV_LIBS})
|
||||
|
||||
set(OUTPUT_LIB_DIR ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/lib)
|
||||
add_custom_command(
|
||||
TARGET ${PROJECT_NAME}
|
||||
POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E make_directory ${OUTPUT_LIB_DIR}
|
||||
COMMAND ${CMAKE_COMMAND} -E copy ../doc/atc/yolov5s_v6.2.om ../output
|
||||
COMMAND ${CMAKE_COMMAND} -E copy ../doc/rundemo.sh ../output
|
||||
COMMAND ${CMAKE_COMMAND} -E copy ../doc/test.jpg ../output
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_directory ../ss928sdk/lib ${OUTPUT_LIB_DIR}
|
||||
COMMENT "Copying lib files to output directory"
|
||||
)
|
||||
add_custom_target(cpfiles ALL DEPENDS ${PROJECT_NAME})
|
||||
|
||||
# for so
|
||||
add_library(ss928driver MODULE ${SVP_SRCLIST} ${SOCSDKCOMMON_SRCLIST} ${LIBAPI_SRCLIST})
|
||||
target_link_libraries(
|
||||
ss928driver
|
||||
${SOC_LIBS}
|
||||
${SYSTEM_LINK_LIB}
|
||||
/home/setups/ss928_framework/thridpart/ncnn/lib/libncnn.a
|
||||
/home/setups/ss928_framework/thridpart/ncnn/lib/libgomp.so
|
||||
${OpenCV_LIBS})
|
||||
set_property(TARGET ss928driver PROPERTY POSITION_INDEPENDENT_CODE ON) #添加-fPIC
|
||||
set_target_properties(ss928driver PROPERTIES LINK_FLAGS "-fPIC")
|
21
LICENSE
Executable file
@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2024 1658988725
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
40
Readme.md
Executable file
@ -0,0 +1,40 @@
|
||||
#### YOlOV5 SS928 3403 demo完整
|
||||
|
||||
### 一、编译
|
||||
|
||||
依赖ss928交叉编译工具,和Cmake
|
||||
|
||||
```
|
||||
./build.sh
|
||||
```
|
||||
|
||||
|
||||
### 二、运行程序
|
||||
|
||||
复制整个output到板端,确保板端ko正常加载
|
||||
|
||||
```
|
||||
cd output
|
||||
./rudemo.sh test.jpg
|
||||
```
|
||||
|
||||
|
||||
### 三、效果图片如下
|
||||
|
||||
<img src="doc/test.jpg" alt="alt text" title="测试图片 " style="max-width:300px;max-height:300px;">
|
||||
<img src="doc/image.png" alt="alt text" title="效果图" style="max-width:300px;max-height:300px;">
|
||||
|
||||
### 四、专栏相关
|
||||
|
||||
哔哩哔哩
|
||||
<https://www.bilibili.com/video/BV1bH4y1u7nv/>
|
||||
|
||||
csdn
|
||||
<https://blog.csdn.net/apchy_ll/category_12628981.html?spm=1001.2014.3001.5482>
|
||||
|
||||
### 五、其它
|
||||
创造不易,谢谢大家支持
|
||||
<img src="doc/other/aipashhandemumu.png" alt="alt text" title="谢谢大家" style="max-width:100px;max-height:100px;">
|
||||
|
||||
如果需要项目合作,请添加下面微信
|
||||
<img src="doc/other/wx.png" alt="alt text" title="谢谢大家" style="max-width:100px;max-height:100px;">
|
8
build.sh
Executable file
@ -0,0 +1,8 @@
|
||||
####!/bin/sh
|
||||
|
||||
mkdir -p build/
|
||||
pushd build/
|
||||
cmake ..
|
||||
make -j8
|
||||
popd
|
||||
|
24
cmake/cmakebase.cmake
Executable file
@ -0,0 +1,24 @@
|
||||
# this one is important
|
||||
SET(CMAKE_SYSTEM_NAME Linux)
|
||||
set(CMAKE_SYSTEM_PROCESSOR aarch64 )
|
||||
|
||||
SET(CMAKE_SYSTEM_VERSION 1)
|
||||
|
||||
SET(SYSTEM_LINK_LIB
|
||||
/usr/lib/aarch64-linux-gnu/libpthread.so
|
||||
/usr/lib/aarch64-linux-gnu/librt.so
|
||||
/usr/lib/aarch64-linux-gnu/libdl.so
|
||||
/usr/lib/aarch64-linux-gnu/libm.so
|
||||
)
|
||||
SET(DO_FLAG -DO2)
|
||||
SET(O_FLAG -O2)
|
||||
SET(CMAKE_CXX_FLAGS
|
||||
"${CMAKE_CXX_FLAGS} ${O_FLAG} -std=c++11 -Wno-deprecated-declarations -ffunction-sections -fdata-sections -Werror -Wno-psabi -Wno-pointer-arith -Wno-int-to-pointer-cast"
|
||||
)
|
||||
# SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -lstdc++)
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -lstdc++ -mcpu=cortex-a53 -fno-aggressive-loop-optimizations -ldl -ffunction-sections -fdata-sections -O2 -fstack-protector-strong -fPIC")
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIE -pie -s -Wall -fsigned-char")
|
||||
|
||||
set(CMAKE_CXX_STANDARD 11)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED TRUE)
|
||||
|
94
cmake/project.cmake
Executable file
@ -0,0 +1,94 @@
|
||||
# Project libs
|
||||
|
||||
SET(SOC_LIBS
|
||||
|
||||
# MPI_LIBS
|
||||
libss_mpi.a
|
||||
# ISP_SUPPORT
|
||||
libss_ae.a
|
||||
libss_isp.a
|
||||
libot_isp.a
|
||||
libss_awb.a
|
||||
libss_dehaze.a
|
||||
libss_extend_stats.a
|
||||
libss_drc.a
|
||||
libss_ldci.a
|
||||
libss_crb.a
|
||||
libss_bnr.a
|
||||
libss_calcflicker.a
|
||||
libss_ir_auto.a
|
||||
libss_acs.a
|
||||
libss_acs.a
|
||||
libsns_os08a20.a
|
||||
libsns_os05a10_2l_slave.a
|
||||
libsns_imx347_slave.a
|
||||
libsns_imx485.a
|
||||
libsns_os04a10.a
|
||||
libsns_os08b10.a
|
||||
# ss_hnr
|
||||
|
||||
# AUDIO_LIBA
|
||||
libss_voice_engine.a
|
||||
libss_upvqe.a
|
||||
libss_dnvqe.a
|
||||
libaac_comm.a
|
||||
libaac_enc.a
|
||||
libaac_dec.a
|
||||
libaac_sbr_enc.a
|
||||
libaac_sbr_dec.a
|
||||
|
||||
# memset_s memcpy_s
|
||||
libsecurec.a
|
||||
|
||||
# HDMI lib
|
||||
libss_hdmi.a
|
||||
|
||||
# SVP
|
||||
libss_ive.a
|
||||
libss_md.a
|
||||
libss_mau.a
|
||||
libss_dpu_rect.a
|
||||
libss_dpu_match.a
|
||||
libss_dsp.a
|
||||
libascend_protobuf.a
|
||||
libsvp_acl.a
|
||||
libprotobuf-c.a
|
||||
|
||||
libacl_cblas.so
|
||||
libacl_retr.so
|
||||
libacl_tdt_queue.so
|
||||
libadump.so
|
||||
libaicpu_kernels.so
|
||||
libaicpu_processer.so
|
||||
libaicpu_prof.so
|
||||
libaicpu_scheduler.so
|
||||
libalog.so
|
||||
libascendcl.so
|
||||
libascend_protobuf.so
|
||||
libcce_aicore.so
|
||||
libcpu_kernels_context.so
|
||||
libcpu_kernels.so
|
||||
libc_sec.so
|
||||
libdrv_aicpu.so
|
||||
libdrvdevdrv.so
|
||||
libdrv_dfx.so
|
||||
liberror_manager.so
|
||||
libge_common.so
|
||||
libge_executor.so
|
||||
libgraph.so
|
||||
libmmpa.so
|
||||
libmsprofiler.so
|
||||
libmsprof.so
|
||||
libopt_feature.so
|
||||
libregister.so
|
||||
libruntime.so
|
||||
libslog.so
|
||||
libtsdclient.so
|
||||
|
||||
libss_mcf.so
|
||||
libss_mcf_vi.so
|
||||
libss_pqp.so
|
||||
)
|
||||
|
||||
add_definitions(-DSENSOR0_TYPE=SONY_IMX485_MIPI_8M_30FPS_12BIT)
|
||||
# add_definitions(-DUSE_NCNN_SIMPLEOCV)
|
5
cmake/ss928.cmake
Executable file
@ -0,0 +1,5 @@
|
||||
SET(PLATFORM ss928)
|
||||
SET(CMAKE_C_COMPILER /home/setups/aarch64-mix210-linux/aarch64-mix210-linux/bin/aarch64-mix210-linux-gcc)
|
||||
SET(CMAKE_CXX_COMPILER /home/setups/aarch64-mix210-linux/aarch64-mix210-linux/bin/aarch64-mix210-linux-g++)
|
||||
SET(CMAKE_STRIP /home/setups/aarch64-mix210-linux/aarch64-mix210-linux/bin/aarch64-mix210-linux-strip)
|
||||
SET(CMAKE_ASM_COMPILER ${CMAKE_C_COMPILER})
|
90
doc/atc/atc.md
Executable file
@ -0,0 +1,90 @@
|
||||
### ATC环境的搭建
|
||||
|
||||
#### 一.安装conda
|
||||
|
||||
#### 二、安装atc相关环境
|
||||
|
||||
~~~
|
||||
|
||||
conda create -n atc python=3.9.2
|
||||
conda env list
|
||||
conda config --set auto_activate_base false
|
||||
conda activate atc
|
||||
|
||||
conda deactivate
|
||||
~~~
|
||||
|
||||
#### 三、安装atc相关依赖
|
||||
|
||||
~~~
|
||||
pip3 install protobuf==3.13.0 --user -i https://pypi.tuna.tsinghua.edu.cn/simple
|
||||
pip3 install psutil==5.7.0 --user -i https://pypi.tuna.tsinghua.edu.cn/simple
|
||||
pip3 install numpy --user -i https://pypi.tuna.tsinghua.edu.cn/simple
|
||||
pip3 install scipy --user -i https://pypi.tuna.tsinghua.edu.cn/simple
|
||||
pip3 install decorator==4.4.0 --user -i https://pypi.tuna.tsinghua.edu.cn/simple
|
||||
pip3 install sympy==1.5.1 --user -i https://pypi.tuna.tsinghua.edu.cn/simple
|
||||
pip3 install cffi==1.12.3 --user -i https://pypi.tuna.tsinghua.edu.cn/simple
|
||||
pip3 install pyyaml --user -i https://pypi.tuna.tsinghua.edu.cn/simple
|
||||
pip3 install pathlib2 --user -i https://pypi.tuna.tsinghua.edu.cn/simple
|
||||
|
||||
~~~
|
||||
|
||||
#### 四、安装atc软件
|
||||
|
||||
#### 五、转换模型
|
||||
|
||||
YOLOv5 v6.2 export onnx model method https://github.com/shaoshengsong/yolov5_62_export_ncnn
|
||||
~~~
|
||||
|
||||
source $HOME/Ascend/ascend-toolkit/latest/x86_64-linux/bin/setenv.bash
|
||||
atc --model=yolov5s_v6.2.onnx --framework=5 --output=yolov5s_v6.2 --soc_version="OPTG" --output_type=FP32 --insert_op_conf=./op.cfg
|
||||
~~~
|
||||
|
||||
##### 5.1 op.cfg yuv420输入配置,输入为640*640 yuv420
|
||||
~~~
|
||||
aipp_op {
|
||||
aipp_mode : static
|
||||
related_input_rank : 0
|
||||
max_src_image_size : 1228800
|
||||
support_rotation : false
|
||||
input_format : YUV420SP_U8
|
||||
src_image_size_w : 640
|
||||
src_image_size_h: 640
|
||||
cpadding_value: 0.0
|
||||
crop : false
|
||||
load_start_pos_w : 0
|
||||
load_start_pos_h : 0
|
||||
crop_size_w : 0
|
||||
crop_size_h : 0
|
||||
resize : false
|
||||
resize_output_w : 640
|
||||
resize_output_h : 640
|
||||
padding : false
|
||||
left_padding_size : 0
|
||||
right_padding_size : 0
|
||||
top_padding_size : 0
|
||||
bottom_padding_size : 0
|
||||
padding_value : 0
|
||||
csc_switch : true
|
||||
rbuv_swap_switch : false
|
||||
ax_swap_switch : false
|
||||
matrix_r0c0 : 256
|
||||
matrix_r0c1 : 0
|
||||
matrix_r0c2 : 0
|
||||
matrix_r1c0 : 0
|
||||
matrix_r1c1 : 0
|
||||
matrix_r1c2 : 0
|
||||
matrix_r2c0 : 0
|
||||
matrix_r2c1 : 0
|
||||
matrix_r2c2 : 0
|
||||
output_bias_0 : 0
|
||||
output_bias_1 : 0
|
||||
output_bias_2 : 0
|
||||
input_bias_0 : 0
|
||||
input_bias_1 : 0
|
||||
input_bias_2 : 0
|
||||
mean_chn_0 : 0
|
||||
min_chn_0 : 0.0
|
||||
var_reci_chn_0 : 0.00392157
|
||||
}
|
||||
~~~
|
45
doc/atc/op.cfg
Executable file
@ -0,0 +1,45 @@
|
||||
aipp_op {
|
||||
aipp_mode : static
|
||||
related_input_rank : 0
|
||||
max_src_image_size : 1228800
|
||||
support_rotation : false
|
||||
input_format : YUV420SP_U8
|
||||
src_image_size_w : 640
|
||||
src_image_size_h: 640
|
||||
cpadding_value: 0.0
|
||||
crop : false
|
||||
load_start_pos_w : 0
|
||||
load_start_pos_h : 0
|
||||
crop_size_w : 0
|
||||
crop_size_h : 0
|
||||
resize : false
|
||||
resize_output_w : 640
|
||||
resize_output_h : 640
|
||||
padding : false
|
||||
left_padding_size : 0
|
||||
right_padding_size : 0
|
||||
top_padding_size : 0
|
||||
bottom_padding_size : 0
|
||||
padding_value : 0
|
||||
csc_switch : true
|
||||
rbuv_swap_switch : false
|
||||
ax_swap_switch : false
|
||||
matrix_r0c0 : 256
|
||||
matrix_r0c1 : 0
|
||||
matrix_r0c2 : 0
|
||||
matrix_r1c0 : 0
|
||||
matrix_r1c1 : 0
|
||||
matrix_r1c2 : 0
|
||||
matrix_r2c0 : 0
|
||||
matrix_r2c1 : 0
|
||||
matrix_r2c2 : 0
|
||||
output_bias_0 : 0
|
||||
output_bias_1 : 0
|
||||
output_bias_2 : 0
|
||||
input_bias_0 : 0
|
||||
input_bias_1 : 0
|
||||
input_bias_2 : 0
|
||||
mean_chn_0 : 0
|
||||
min_chn_0 : 0.0
|
||||
var_reci_chn_0 : 0.00392157
|
||||
}
|
BIN
doc/atc/yolov5s_v6.2.om
Executable file
BIN
doc/atc/yolov5s_v6.2.onnx
Executable file
BIN
doc/image.png
Executable file
After Width: | Height: | Size: 1020 KiB |
25
doc/ncnn/aarch64-mix210-linux.toolchain.cmake
Executable file
@ -0,0 +1,25 @@
|
||||
set(CMAKE_SYSTEM_NAME Linux)
|
||||
set(CMAKE_SYSTEM_PROCESSOR aarch64)
|
||||
|
||||
set(CMAKE_C_COMPILER "/usr/bin/gcc")
|
||||
set(CMAKE_CXX_COMPILER "/usr/bin/g++")
|
||||
|
||||
if(NOT CMAKE_FIND_ROOT_PATH_MODE_PROGRAM)
|
||||
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
|
||||
endif()
|
||||
if(NOT CMAKE_FIND_ROOT_PATH_MODE_LIBRARY)
|
||||
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
|
||||
endif()
|
||||
if(NOT CMAKE_FIND_ROOT_PATH_MODE_INCLUDE)
|
||||
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
|
||||
endif()
|
||||
if(NOT CMAKE_FIND_ROOT_PATH_MODE_PACKAGE)
|
||||
set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)
|
||||
endif()
|
||||
|
||||
# set(CMAKE_C_FLAGS "-march=armv8-a")
|
||||
# set(CMAKE_CXX_FLAGS "-march=armv8-a")
|
||||
|
||||
# cache flags
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS}" CACHE STRING "c flags")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}" CACHE STRING "c++ flags")
|
9
doc/ncnn/build_aarch64-mix210-linux.sh
Executable file
@ -0,0 +1,9 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
##### linux for aarch64-mix210-linux- toolchain
|
||||
mkdir -p build-aarch64-mix210-linux-
|
||||
pushd build-aarch64-mix210-linux-
|
||||
cmake -DCMAKE_TOOLCHAIN_FILE=../toolchains/aarch64-mix210-linux.toolchain.cmake -DNCNN_SIMPLEOCV=ON -DNCNN_BUILD_EXAMPLES=ON -DNCNN_OPENMP=OFF ..
|
||||
make -j4
|
||||
make install
|
||||
popd
|
150
doc/ncnn/readme.md
Executable file
@ -0,0 +1,150 @@
|
||||
### 通过NCNN储存YUV420
|
||||
|
||||
~~~
|
||||
|
||||
int imgin_w = 640,imgin_h = 640;
|
||||
cv::Mat a(imgin_w, imgin_h, CV_8UC3);
|
||||
memset(a.data,0xFF,imgin_w*imgin_h*3);
|
||||
in.to_pixels(a.data, ncnn::Mat::PIXEL_RGB2BGR);
|
||||
cv::imshow("in_image", a);
|
||||
|
||||
//yuv420sp
|
||||
ncnn::Mat yuv(imgin_w, imgin_h/2*3,1);
|
||||
unsigned char *puv =(unsigned char *) yuv+imgin_w*imgin_h;
|
||||
bgr2yuv420sp(a.data,imgin_w, imgin_h,yuv,puv,imgin_w);
|
||||
|
||||
FILE* fp = fopen("output.yuv", "wb");
|
||||
if (fp) {
|
||||
fwrite(yuv, imgin_w*imgin_h*3/2,1, fp);
|
||||
fclose(fp);
|
||||
}
|
||||
~~~
|
||||
|
||||
~~~
|
||||
|
||||
static void bgr2yuv420sp(const unsigned char* bgrdata, int width, int height, unsigned char* yptr, unsigned char* uvptr, int stride)
|
||||
{
|
||||
#if __ARM_NEON
|
||||
uint8x8_t _v38 = vdup_n_u8(38);
|
||||
uint8x8_t _v75 = vdup_n_u8(75);
|
||||
uint8x8_t _v15 = vdup_n_u8(15);
|
||||
|
||||
uint8x8_t _v127 = vdup_n_u8(127);
|
||||
uint8x8_t _v84_107 = vzip_u8(vdup_n_u8(84), vdup_n_u8(107)).val[0];
|
||||
uint8x8_t _v43_20 = vzip_u8(vdup_n_u8(43), vdup_n_u8(20)).val[0];
|
||||
uint16x8_t _v128 = vdupq_n_u16((128 << 8) + 128);
|
||||
#endif // __ARM_NEON
|
||||
|
||||
for (int y = 0; y + 1 < height; y += 2)
|
||||
{
|
||||
const unsigned char* p0 = bgrdata + y * width * 3;
|
||||
const unsigned char* p1 = bgrdata + (y + 1) * width * 3;
|
||||
unsigned char* yptr0 = yptr + y * stride;
|
||||
unsigned char* yptr1 = yptr + (y + 1) * stride;
|
||||
unsigned char* uvptr0 = uvptr + (y / 2) * stride;
|
||||
|
||||
int x = 0;
|
||||
#if __ARM_NEON
|
||||
for (; x + 7 < width; x += 8)
|
||||
{
|
||||
uint8x8x3_t _bgr0 = vld3_u8(p0);
|
||||
uint8x8x3_t _bgr1 = vld3_u8(p1);
|
||||
|
||||
uint16x8_t _y0 = vmull_u8(_bgr0.val[0], _v15);
|
||||
uint16x8_t _y1 = vmull_u8(_bgr1.val[0], _v15);
|
||||
_y0 = vmlal_u8(_y0, _bgr0.val[1], _v75);
|
||||
_y1 = vmlal_u8(_y1, _bgr1.val[1], _v75);
|
||||
_y0 = vmlal_u8(_y0, _bgr0.val[2], _v38);
|
||||
_y1 = vmlal_u8(_y1, _bgr1.val[2], _v38);
|
||||
uint8x8_t _y0_u8 = vqrshrun_n_s16(vreinterpretq_s16_u16(_y0), 7);
|
||||
uint8x8_t _y1_u8 = vqrshrun_n_s16(vreinterpretq_s16_u16(_y1), 7);
|
||||
|
||||
uint16x4_t _b4 = vpaddl_u8(_bgr0.val[0]);
|
||||
uint16x4_t _g4 = vpaddl_u8(_bgr0.val[1]);
|
||||
uint16x4_t _r4 = vpaddl_u8(_bgr0.val[2]);
|
||||
_b4 = vpadal_u8(_b4, _bgr1.val[0]);
|
||||
_g4 = vpadal_u8(_g4, _bgr1.val[1]);
|
||||
_r4 = vpadal_u8(_r4, _bgr1.val[2]);
|
||||
uint16x4x2_t _brbr = vzip_u16(_b4, _r4);
|
||||
uint16x4x2_t _gggg = vzip_u16(_g4, _g4);
|
||||
uint16x4x2_t _rbrb = vzip_u16(_r4, _b4);
|
||||
uint8x8_t _br = vshrn_n_u16(vcombine_u16(_brbr.val[0], _brbr.val[1]), 2);
|
||||
uint8x8_t _gg = vshrn_n_u16(vcombine_u16(_gggg.val[0], _gggg.val[1]), 2);
|
||||
uint8x8_t _rb = vshrn_n_u16(vcombine_u16(_rbrb.val[0], _rbrb.val[1]), 2);
|
||||
|
||||
// uint8x8_t _br = vtrn_u8(_bgr0.val[0], _bgr0.val[2]).val[0];
|
||||
// uint8x8_t _gg = vtrn_u8(_bgr0.val[1], _bgr0.val[1]).val[0];
|
||||
// uint8x8_t _rb = vtrn_u8(_bgr0.val[2], _bgr0.val[0]).val[0];
|
||||
|
||||
uint16x8_t _uv = vmlal_u8(_v128, _br, _v127);
|
||||
_uv = vmlsl_u8(_uv, _gg, _v84_107);
|
||||
_uv = vmlsl_u8(_uv, _rb, _v43_20);
|
||||
uint8x8_t _uv_u8 = vqshrn_n_u16(_uv, 8);
|
||||
|
||||
vst1_u8(yptr0, _y0_u8);
|
||||
vst1_u8(yptr1, _y1_u8);
|
||||
vst1_u8(uvptr0, _uv_u8);
|
||||
|
||||
p0 += 24;
|
||||
p1 += 24;
|
||||
yptr0 += 8;
|
||||
yptr1 += 8;
|
||||
uvptr0 += 8;
|
||||
}
|
||||
#endif
|
||||
for (; x + 1 < width; x += 2)
|
||||
{
|
||||
unsigned char b00 = p0[0];
|
||||
unsigned char g00 = p0[1];
|
||||
unsigned char r00 = p0[2];
|
||||
|
||||
unsigned char b01 = p0[3];
|
||||
unsigned char g01 = p0[4];
|
||||
unsigned char r01 = p0[5];
|
||||
|
||||
unsigned char b10 = p1[0];
|
||||
unsigned char g10 = p1[1];
|
||||
unsigned char r10 = p1[2];
|
||||
|
||||
unsigned char b11 = p1[3];
|
||||
unsigned char g11 = p1[4];
|
||||
unsigned char r11 = p1[5];
|
||||
|
||||
// y = 0.29900 * r + 0.58700 * g + 0.11400 * b
|
||||
// u = -0.16874 * r - 0.33126 * g + 0.50000 * b + 128
|
||||
// v = 0.50000 * r - 0.41869 * g - 0.08131 * b + 128
|
||||
|
||||
#define SATURATE_CAST_UCHAR(X) (unsigned char)::std::min(::std::max((int)(X), 0), 255);
|
||||
unsigned char y00 = SATURATE_CAST_UCHAR(( 38 * r00 + 75 * g00 + 15 * b00 + 64) >> 7);
|
||||
unsigned char y01 = SATURATE_CAST_UCHAR(( 38 * r01 + 75 * g01 + 15 * b01 + 64) >> 7);
|
||||
unsigned char y10 = SATURATE_CAST_UCHAR(( 38 * r10 + 75 * g10 + 15 * b10 + 64) >> 7);
|
||||
unsigned char y11 = SATURATE_CAST_UCHAR(( 38 * r11 + 75 * g11 + 15 * b11 + 64) >> 7);
|
||||
|
||||
unsigned char b4 = (b00 + b01 + b10 + b11) / 4;
|
||||
unsigned char g4 = (g00 + g01 + g10 + g11) / 4;
|
||||
unsigned char r4 = (r00 + r01 + r10 + r11) / 4;
|
||||
|
||||
// unsigned char b4 = b00;
|
||||
// unsigned char g4 = g00;
|
||||
// unsigned char r4 = r00;
|
||||
|
||||
unsigned char u = SATURATE_CAST_UCHAR(((-43 * r4 - 84 * g4 + 127 * b4 + 128) >> 8) + 128);
|
||||
unsigned char v = SATURATE_CAST_UCHAR(((127 * r4 - 107 * g4 - 20 * b4 + 128) >> 8) + 128);
|
||||
#undef SATURATE_CAST_UCHAR
|
||||
|
||||
yptr0[0] = y00;
|
||||
yptr0[1] = y01;
|
||||
yptr1[0] = y10;
|
||||
yptr1[1] = y11;
|
||||
uvptr0[0] = u;
|
||||
uvptr0[1] = v;
|
||||
|
||||
p0 += 6;
|
||||
p1 += 6;
|
||||
yptr0 += 2;
|
||||
yptr1 += 2;
|
||||
uvptr0 += 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
~~~
|
BIN
doc/other/aipashhandemumu.png
Executable file
After Width: | Height: | Size: 80 KiB |
BIN
doc/other/wx.png
Executable file
After Width: | Height: | Size: 101 KiB |
11
doc/rundemo.sh
Executable file
@ -0,0 +1,11 @@
|
||||
#!/bin/sh
|
||||
|
||||
# 设置 LD_LIBRARY_PATH
|
||||
export LD_LIBRARY_PATH=${PWD}/lib:${PWD}/lib/npu:${PWD}/lib/svp_npu:$LD_LIBRARY_PATH
|
||||
|
||||
# 杀死进程
|
||||
killall -9 ss928_libapi
|
||||
|
||||
# 执行命令,传入参数
|
||||
./ss928_libapi "$@"
|
||||
|
BIN
doc/test.jpg
Executable file
After Width: | Height: | Size: 407 KiB |
BIN
doc/基于海思SS928(3403)端侧目标检测(yolov5s)培训课程.pdf
Executable file
1166
libapi/LibApi.cpp
Executable file
84
libapi/LibApi.h
Executable file
@ -0,0 +1,84 @@
|
||||
/*
|
||||
**************************************************************************************
|
||||
* Filename: LibApi.h
|
||||
* Description: header file
|
||||
*
|
||||
* Version: 1.0
|
||||
* Created:
|
||||
* Author:
|
||||
*
|
||||
* Revision: initial draft;
|
||||
**************************************************************************************
|
||||
*/
|
||||
extern "C"{
|
||||
#pragma once
|
||||
|
||||
#include "wrapperncnn.h"
|
||||
|
||||
/*
|
||||
@desc : error define
|
||||
*/
|
||||
#define UM_OK 0
|
||||
#define UM_SYS_ERROR 1
|
||||
#define UM_PORT_HAS_NO_DEV 6
|
||||
#define UM_AUTH_ERROR 7
|
||||
#define UM_DEV_IS_IN_USE 15
|
||||
#define UM_CANNOT_RELEASE_PORT 16
|
||||
#define UM_UPDATE_DEV_ERROR 34
|
||||
|
||||
#define UM_NETWORK_ERROR 129
|
||||
#define UM_PROTOCAL_ERROR 130
|
||||
#define UM_USBBUS_REG_ERROR 133
|
||||
#define UM_USB_PORT_ERROR 134
|
||||
#define UM_USBDEV_ID_ERROR 142
|
||||
#define UM_USBDEV_OFFLINE_ERROR 143
|
||||
|
||||
#define UM_DRIVER_MIDDLEWARE_ERROR 255
|
||||
|
||||
#define UmError int
|
||||
|
||||
/*
|
||||
@desc : struct
|
||||
*/
|
||||
|
||||
/*
|
||||
@desc :NNN function
|
||||
*/
|
||||
UmError LibapiSvpNpuHandleSig(void);
|
||||
|
||||
UmError LibapiSvpNpuAclPrepareInit(void);
|
||||
UmError LibApiSvpNpuAclPrepareExit(void);
|
||||
|
||||
UmError LibApiSvpNpuLoadModel(char* om_model_path, int model_index, bool is_cached);
|
||||
UmError LibApiSvpNpuUnLoadModel(int model_index);
|
||||
|
||||
UmError LibApiSvpNpuLoadDataset(int model_index, void *src, size_t data_len, size_t imgin_w, size_t imgin_h, int flag);
|
||||
UmError LibApiSvpNpuUnloadDataset();
|
||||
|
||||
UmError LibApiSvpNpuModelExecute(int model_index);
|
||||
UmError LibApiSvpNpuGetModelExecuteResult(int model_index, void* objs /*RetrunObject*/ );
|
||||
|
||||
/*
|
||||
@desc : IVE sobel function
|
||||
*/
|
||||
|
||||
UmError LibapiCommonIveCheckMpiInit();
|
||||
UmError LibapiCommonIveMpiInit();
|
||||
UmError LibapiCommonIveMpiExit();
|
||||
|
||||
UmError LibApiIveCreateMMZImage(void *mmz_img, int img_type, int width, int height);
|
||||
UmError LibApiIveDestroyMMZImage(void *mmz_img);
|
||||
|
||||
UmError LibApiIveReadMMZFromOsMem(void *mmz_img, void *cv_src, int width, int height, int img_type);
|
||||
UmError LibApiIveWriteMMZToOsMem(void *mmz_img, void *cv_tar);
|
||||
UmError LibApiIveWriteMMZToFile(void *mmz_img, FILE *fp);
|
||||
|
||||
UmError LibApiCanny(void* src, int width, int height, int img_type,
|
||||
void* dst, char canny_complete);
|
||||
|
||||
UmError LibapiSobelHandleSig();
|
||||
UmError LibApiSobel();
|
||||
|
||||
UmError LibapiKcfHandleSig();
|
||||
UmError LibApiKcf();
|
||||
}
|
602
libapi/ive/libapi_common_ive.c
Executable file
@ -0,0 +1,602 @@
|
||||
/*
|
||||
Copyright (c), 2001-2022, Shenshu Tech. Co., Ltd.
|
||||
*/
|
||||
#include "libapi_common_ive.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#include <signal.h>
|
||||
|
||||
#include "ot_common.h"
|
||||
#include "ot_common_video.h"
|
||||
#include "ot_common_sys.h"
|
||||
#include "ot_common_vgs.h"
|
||||
#include "ot_common_vi.h"
|
||||
#include "ot_common_vo.h"
|
||||
#include "ss_mpi_sys.h"
|
||||
#include <arm_neon.h>
|
||||
|
||||
#define OT_SAMPLE_IVE_QUERY_SLEEP 100
|
||||
#define OT_SAMPLE_IVE_MAX_WIDTH 4096
|
||||
#define OT_SAMPLE_IVE_MAX_HEIGHT 4096
|
||||
|
||||
|
||||
// 在一个进程内,MPI初始化是否只能执行一次,如果只能执行一次,那么这里可以设置为全局变量
|
||||
// for test
|
||||
static td_bool g_is_mpi_init = TD_FALSE;
|
||||
|
||||
/*
|
||||
* function : Mpi check init
|
||||
*/
|
||||
td_s32 libapi_common_ive_check_mpi_init(td_void)
|
||||
{
|
||||
if (g_is_mpi_init == TD_FALSE) {
|
||||
if (libapi_common_ive_mpi_init() != TD_SUCCESS) {
|
||||
macro_svp_trace_err("Ive mpi init failed!\n");
|
||||
return TD_FALSE;
|
||||
}
|
||||
g_is_mpi_init = TD_TRUE;
|
||||
}
|
||||
return TD_TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* function :mpi_init
|
||||
*/
|
||||
td_s32 libapi_common_ive_mpi_init(td_void)
|
||||
{
|
||||
td_s32 ret;
|
||||
|
||||
ss_mpi_sys_exit();
|
||||
|
||||
ret = ss_mpi_sys_init();
|
||||
if (ret != TD_SUCCESS) {
|
||||
macro_svp_trace_err("ss_mpi_sys_init fail,Error(%#x)\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return TD_SUCCESS;
|
||||
}
|
||||
|
||||
/*
|
||||
* function : Mpi exit
|
||||
*/
|
||||
td_void libapi_common_ive_mpi_exit(td_void)
|
||||
{
|
||||
if (g_is_mpi_init == TD_TRUE) {
|
||||
if (ss_mpi_sys_exit() != TD_SUCCESS) {
|
||||
macro_svp_trace_err("Sys exit failed!\n");
|
||||
return;
|
||||
}
|
||||
}
|
||||
g_is_mpi_init = TD_FALSE;
|
||||
macro_svp_trace_info("ive mpi exit ok!\n");
|
||||
}
|
||||
|
||||
static td_void _comm_ive_get_loop_info(const ot_svp_img *img, ot_struct_rw_image_loop_info *loop_info)
|
||||
{
|
||||
loop_info->ele_size = 1;
|
||||
loop_info->loop_c = 1;
|
||||
loop_info->loop_h[0] = img->height;
|
||||
switch (img->type) {
|
||||
case OT_SVP_IMG_TYPE_U8C1:
|
||||
case OT_SVP_IMG_TYPE_S8C1: {
|
||||
}
|
||||
break;
|
||||
case OT_SVP_IMG_TYPE_YUV420SP: {
|
||||
loop_info->ele_size = 1;
|
||||
loop_info->loop_c = OT_MACRO_IVE_IMAGE_CHN_TWO;
|
||||
loop_info->loop_h[1] = img->height / OT_MACRO_IVE_DIV_TWO;
|
||||
}
|
||||
break;
|
||||
case OT_SVP_IMG_TYPE_YUV422SP: {
|
||||
loop_info->loop_c = OT_MACRO_IVE_IMAGE_CHN_TWO;
|
||||
loop_info->loop_h[1] = img->height;
|
||||
}
|
||||
break;
|
||||
case OT_SVP_IMG_TYPE_U8C3_PACKAGE: {
|
||||
loop_info->ele_size = sizeof(td_u8) + sizeof(td_u16);
|
||||
}
|
||||
break;
|
||||
case OT_SVP_IMG_TYPE_U8C3_PLANAR: {
|
||||
loop_info->loop_c = OT_MACRO_IVE_IMAGE_CHN_THREE;
|
||||
loop_info->loop_h[1] = img->height;
|
||||
loop_info->loop_h[OT_MACRO_IVE_IMAGE_CHN_TWO] = img->height;
|
||||
}
|
||||
break;
|
||||
case OT_SVP_IMG_TYPE_S16C1:
|
||||
case OT_SVP_IMG_TYPE_U16C1: {
|
||||
loop_info->ele_size = sizeof(td_u16);
|
||||
}
|
||||
break;
|
||||
case OT_SVP_IMG_TYPE_U32C1:
|
||||
case OT_SVP_IMG_TYPE_S32C1: {
|
||||
loop_info->ele_size = sizeof(td_u32);
|
||||
}
|
||||
break;
|
||||
case OT_SVP_IMG_TYPE_S64C1:
|
||||
case OT_SVP_IMG_TYPE_U64C1: {
|
||||
loop_info->ele_size = sizeof(td_u64);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* function :Read file
|
||||
*/
|
||||
td_s32 libapi_common_ive_read_file(ot_svp_img *img, FILE *fp)
|
||||
{
|
||||
td_u8 *ptr_tmp = TD_NULL;
|
||||
td_u16 c, h;
|
||||
td_s32 ret = OT_ERR_IVE_NULL_PTR;
|
||||
ot_struct_rw_image_loop_info loop_info = {0};
|
||||
|
||||
macro_svp_check_exps_return(img == TD_NULL, ret, ENUM_SVP_ERR_LEVEL_DEBUG, "img can't be null\n");
|
||||
macro_svp_check_exps_return(fp == TD_NULL, ret, ENUM_SVP_ERR_LEVEL_DEBUG, "fp can't be null\n");
|
||||
|
||||
ret = fgetc(fp);
|
||||
macro_svp_check_exps_return(ret == EOF, ret, ENUM_SVP_ERR_LEVEL_DEBUG, "fgetc fp failed!\n");
|
||||
if (feof(fp)) {
|
||||
macro_svp_trace_err("end of file!\n");
|
||||
ret = fseek(fp, 0, SEEK_SET);
|
||||
if (ret != 0) {
|
||||
macro_svp_trace_err("fseek failed!\n");
|
||||
return ret;
|
||||
}
|
||||
} else {
|
||||
ret = fseek(fp, -1, SEEK_CUR);
|
||||
if (ret != 0) {
|
||||
macro_svp_trace_err("fseek failed!\n");
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
_comm_ive_get_loop_info(img, &loop_info);
|
||||
for (c = 0; (c < loop_info.loop_c) && (c < OT_SVP_IMG_STRIDE_NUM) && (c < OT_SVP_IMG_ADDR_NUM); c++) {
|
||||
ptr_tmp = macro_svp_convert_addr_to_ptr(td_u8, img->virt_addr[c]);
|
||||
macro_svp_check_exps_return(ptr_tmp == 0, OT_ERR_IVE_ILLEGAL_PARAM,
|
||||
ENUM_SVP_ERR_LEVEL_DEBUG, "ptr_tmp can't be 0\n");
|
||||
for (h = 0; h < loop_info.loop_h[c]; h++) {
|
||||
if (fread(ptr_tmp, img->width * loop_info.ele_size, 1, fp) != 1) {
|
||||
macro_svp_trace_err("Read file fail\n");
|
||||
return OT_ERR_IVE_ILLEGAL_PARAM;
|
||||
}
|
||||
ptr_tmp += img->stride[c] * loop_info.ele_size;
|
||||
}
|
||||
}
|
||||
|
||||
return TD_SUCCESS;
|
||||
}
|
||||
|
||||
/*
|
||||
* function :Write file
|
||||
*/
|
||||
td_s32 libapi_common_ive_write_file(ot_svp_img *img, FILE *fp)
|
||||
{
|
||||
td_u16 c, h;
|
||||
td_u8 *ptr_tmp = TD_NULL;
|
||||
td_s32 ret = OT_ERR_IVE_NULL_PTR;
|
||||
ot_struct_rw_image_loop_info loop_info = {0};
|
||||
|
||||
macro_svp_check_exps_return(img == TD_NULL, ret, ENUM_SVP_ERR_LEVEL_DEBUG, "img can't be null\n");
|
||||
macro_svp_check_exps_return(fp == TD_NULL, ret, ENUM_SVP_ERR_LEVEL_DEBUG, "fp can't be null\n");
|
||||
ret = OT_ERR_IVE_ILLEGAL_PARAM;
|
||||
macro_svp_check_exps_return(img->phys_addr == 0, ret, ENUM_SVP_ERR_LEVEL_DEBUG, "img->phys_addr can't be 0\n");
|
||||
macro_svp_check_exps_return(img->virt_addr == 0, ret, ENUM_SVP_ERR_LEVEL_DEBUG, "img->phys_addr can't be 0\n");
|
||||
|
||||
_comm_ive_get_loop_info(img, &loop_info);
|
||||
for (c = 0; (c < loop_info.loop_c) && (c < OT_SVP_IMG_STRIDE_NUM) && (c < OT_SVP_IMG_ADDR_NUM); c++) {
|
||||
ptr_tmp = macro_svp_convert_addr_to_ptr(td_u8, img->virt_addr[c]);
|
||||
macro_svp_check_exps_return(ptr_tmp == 0, ret, ENUM_SVP_ERR_LEVEL_DEBUG, "ptr_tmp can't be 0\n");
|
||||
for (h = 0; h < loop_info.loop_h[c]; h++) {
|
||||
if (fwrite(ptr_tmp, img->width * loop_info.ele_size, 1, fp) != 1) {
|
||||
macro_svp_trace_err("Write file fail\n");
|
||||
return ret;
|
||||
}
|
||||
ptr_tmp += img->stride[c] * loop_info.ele_size;
|
||||
}
|
||||
}
|
||||
return TD_SUCCESS;
|
||||
}
|
||||
|
||||
// static void *memcpy_128(void *dest, void *src, size_t count)
|
||||
// {
|
||||
// int i;
|
||||
// unsigned long *s = (unsigned long *)src;
|
||||
// unsigned long *d = (unsigned long *)dest;
|
||||
// for (i = 0; i < count / 64; i++) {
|
||||
// vst1q_u64(&d[0], vld1q_u64(&s[0]));
|
||||
// vst1q_u64(&d[2], vld1q_u64(&s[2]));
|
||||
// vst1q_u64(&d[4], vld1q_u64(&s[4]));
|
||||
// vst1q_u64(&d[6], vld1q_u64(&s[6]));
|
||||
// d += 8; s += 8;
|
||||
// }
|
||||
// return dest;
|
||||
// }
|
||||
|
||||
/*
|
||||
* 先执行
|
||||
* ret = libapi_common_ive_create_image(img, img_type, width, height);
|
||||
* macro_svp_check_exps_return(ret != TD_SUCCESS, fail, ENUM_SVP_ERR_LEVEL_ERROR, "Error,create src img failed!\n");
|
||||
* function :Read os_mem
|
||||
*/
|
||||
td_s32 libapi_common_ive_read_os_mem(ot_svp_img *img, td_void *src, td_u32 whidh, td_u32 height, td_u32 img_type)
|
||||
{
|
||||
td_u8 *ptr_tmp = TD_NULL;
|
||||
td_u16 c, h;
|
||||
td_s32 ret = OT_ERR_IVE_NULL_PTR;
|
||||
ot_struct_rw_image_loop_info loop_info = {0};
|
||||
|
||||
macro_svp_check_exps_return(img == TD_NULL, ret, ENUM_SVP_ERR_LEVEL_DEBUG, "img can't be null\n");
|
||||
macro_svp_check_exps_return(src == TD_NULL, ret, ENUM_SVP_ERR_LEVEL_DEBUG, "src can't be null\n");
|
||||
|
||||
_comm_ive_get_loop_info(img, &loop_info);
|
||||
td_void *_tmp_src = src;
|
||||
for (c = 0; (c < loop_info.loop_c) && (c < OT_SVP_IMG_STRIDE_NUM) && (c < OT_SVP_IMG_ADDR_NUM); c++) {
|
||||
ptr_tmp = macro_svp_convert_addr_to_ptr(td_u8, img->virt_addr[c]);
|
||||
macro_svp_check_exps_return(ptr_tmp == 0, OT_ERR_IVE_ILLEGAL_PARAM,
|
||||
ENUM_SVP_ERR_LEVEL_DEBUG, "ptr_tmp can't be 0\n");
|
||||
td_u32 len = img->width * loop_info.ele_size;
|
||||
if (len == img->stride[c] * loop_info.ele_size) {
|
||||
memcpy(ptr_tmp, _tmp_src, len * loop_info.loop_h[c]);
|
||||
}
|
||||
else
|
||||
{
|
||||
for (h = 0; h < loop_info.loop_h[c]; h++) {
|
||||
memcpy(ptr_tmp, _tmp_src, len);
|
||||
_tmp_src += len;
|
||||
ptr_tmp += img->stride[c] * loop_info.ele_size;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return TD_SUCCESS;
|
||||
}
|
||||
|
||||
/*
|
||||
* function :Write os_mem
|
||||
*/
|
||||
td_s32 libapi_common_ive_write_os_mem(ot_svp_img *img, td_void *tar)
|
||||
{
|
||||
td_u16 c, h;
|
||||
td_u8 *ptr_tmp = TD_NULL;
|
||||
td_s32 ret = OT_ERR_IVE_NULL_PTR;
|
||||
ot_struct_rw_image_loop_info loop_info = {0};
|
||||
|
||||
macro_svp_check_exps_return(img == TD_NULL, ret, ENUM_SVP_ERR_LEVEL_DEBUG, "img can't be null\n");
|
||||
macro_svp_check_exps_return(tar == TD_NULL, ret, ENUM_SVP_ERR_LEVEL_DEBUG, "tar can't be null\n");
|
||||
ret = OT_ERR_IVE_ILLEGAL_PARAM;
|
||||
macro_svp_check_exps_return(img->phys_addr == 0, ret, ENUM_SVP_ERR_LEVEL_DEBUG, "img->phys_addr can't be 0\n");
|
||||
macro_svp_check_exps_return(img->virt_addr == 0, ret, ENUM_SVP_ERR_LEVEL_DEBUG, "img->phys_addr can't be 0\n");
|
||||
|
||||
_comm_ive_get_loop_info(img, &loop_info);
|
||||
td_void *_tmp_tar = tar;
|
||||
for (c = 0; (c < loop_info.loop_c) && (c < OT_SVP_IMG_STRIDE_NUM) && (c < OT_SVP_IMG_ADDR_NUM); c++) {
|
||||
ptr_tmp = macro_svp_convert_addr_to_ptr(td_u8, img->virt_addr[c]);
|
||||
macro_svp_check_exps_return(ptr_tmp == 0, ret, ENUM_SVP_ERR_LEVEL_DEBUG, "ptr_tmp can't be 0\n");
|
||||
td_u32 len = img->width * loop_info.ele_size;
|
||||
if (len == img->stride[c] * loop_info.ele_size) {
|
||||
memcpy(_tmp_tar, ptr_tmp, len * loop_info.loop_h[c]);
|
||||
// macro_svp_trace_info("len is %d, len2 is %d\n", len, img->stride[c] * loop_info.ele_size);
|
||||
}
|
||||
else {
|
||||
for (h = 0; h < loop_info.loop_h[c]; h++) {
|
||||
memcpy(_tmp_tar, ptr_tmp, len);
|
||||
_tmp_tar += len;
|
||||
ptr_tmp += img->stride[c] * loop_info.ele_size;
|
||||
}
|
||||
}
|
||||
}
|
||||
return TD_SUCCESS;
|
||||
}
|
||||
|
||||
/*
|
||||
* function :Calc stride
|
||||
*/
|
||||
td_u32 libapi_common_ive_calc_stride(td_u32 width, td_u8 align)
|
||||
{
|
||||
macro_svp_check_exps_return(align == 0, OT_ERR_IVE_ILLEGAL_PARAM,
|
||||
ENUM_SVP_ERR_LEVEL_DEBUG, "align can't be 0\n");
|
||||
macro_svp_check_exps_return((width > OT_SAMPLE_IVE_MAX_WIDTH) || (width < 1), OT_ERR_IVE_ILLEGAL_PARAM,
|
||||
ENUM_SVP_ERR_LEVEL_DEBUG, "width(%u) must be in [1, %u]", width, OT_SAMPLE_IVE_MAX_WIDTH);
|
||||
return (width + (align - width % align) % align);
|
||||
}
|
||||
|
||||
static td_void _comm_ive_get_thresh(ot_ive_ccblob *blob, td_u16 area_thr_step, td_u16 rect_max_num,
|
||||
td_u16 *thresh)
|
||||
{
|
||||
td_u32 i;
|
||||
td_u16 num;
|
||||
td_u16 thr = blob->info.bits.cur_area_threshold;
|
||||
do {
|
||||
num = 0;
|
||||
thr += area_thr_step;
|
||||
for (i = 0; i < blob->info.bits.rgn_num; i++) {
|
||||
if (blob->rgn[i].area > thr) {
|
||||
num++;
|
||||
}
|
||||
}
|
||||
} while (num > rect_max_num);
|
||||
|
||||
*thresh = thr;
|
||||
}
|
||||
|
||||
/*
|
||||
* function : judge if rect is valid
|
||||
*/
|
||||
static td_void _common_ive_is_rect_valid(ot_struct_svp_rect_info *rect, td_u32 num, td_bool *valid)
|
||||
{
|
||||
td_u32 j, k;
|
||||
for (j = 0; j < (OT_POINT_NUM - 1); j++) {
|
||||
for (k = j + 1; k < OT_POINT_NUM; k++) {
|
||||
if ((rect->rect[num].point[j].x == rect->rect[num].point[k].x) &&
|
||||
(rect->rect[num].point[j].y == rect->rect[num].point[k].y)) {
|
||||
*valid = TD_FALSE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* function : Copy blob to rect
|
||||
*/
|
||||
td_s32 libapi_common_ive_blob_to_rect(ot_ive_ccblob *blob, ot_struct_svp_rect_info *rect,
|
||||
td_u16 rect_max_num, td_u16 area_thr_step, ot_struct_src_dst_size src_dst_size)
|
||||
{
|
||||
td_u16 num, i;
|
||||
td_u16 thr = 0;
|
||||
td_bool valid;
|
||||
macro_svp_check_exps_return(blob == TD_NULL, OT_ERR_IVE_NULL_PTR,
|
||||
ENUM_SVP_ERR_LEVEL_DEBUG, "blob can't be null\n");
|
||||
macro_svp_check_exps_return(rect == TD_NULL, OT_ERR_IVE_NULL_PTR,
|
||||
ENUM_SVP_ERR_LEVEL_DEBUG, "rect can't be null\n");
|
||||
|
||||
if (blob->info.bits.rgn_num > rect_max_num) {
|
||||
_comm_ive_get_thresh(blob, area_thr_step, rect_max_num, &thr);
|
||||
}
|
||||
|
||||
num = 0;
|
||||
for (i = 0; i < blob->info.bits.rgn_num; i++) {
|
||||
if (blob->rgn[i].area <= thr) {
|
||||
continue;
|
||||
}
|
||||
macro_svp_check_exps_return(num > (OT_SVP_RECT_NUM - 1), TD_FAILURE,
|
||||
ENUM_SVP_ERR_LEVEL_ERROR, "num is larger than %u\n", OT_SVP_RECT_NUM - 1);
|
||||
rect->rect[num].point[OT_MACRO_POINT_IDX_ZERO].x = (td_u32)((td_float)blob->rgn[i].left /
|
||||
(td_float)src_dst_size.src.width * (td_float)src_dst_size.dst.width) & (~1);
|
||||
rect->rect[num].point[OT_MACRO_POINT_IDX_ZERO].y = (td_u32)((td_float)blob->rgn[i].top /
|
||||
(td_float)src_dst_size.src.height * (td_float)src_dst_size.dst.height) & (~1);
|
||||
|
||||
rect->rect[num].point[OT_MACRO_POINT_IDX_ONE].x = (td_u32)((td_float)blob->rgn[i].right /
|
||||
(td_float)src_dst_size.src.width * (td_float)src_dst_size.dst.width) & (~1);
|
||||
rect->rect[num].point[OT_MACRO_POINT_IDX_ONE].y = (td_u32)((td_float)blob->rgn[i].top /
|
||||
(td_float)src_dst_size.src.height * (td_float)src_dst_size.dst.height) & (~1);
|
||||
|
||||
rect->rect[num].point[OT_MACRO_POINT_IDX_TWO].x = (td_u32)((td_float)blob->rgn[i].right /
|
||||
(td_float)src_dst_size.src.width * (td_float)src_dst_size.dst.width) & (~1);
|
||||
rect->rect[num].point[OT_MACRO_POINT_IDX_TWO].y = (td_u32)((td_float)blob->rgn[i].bottom /
|
||||
(td_float)src_dst_size.src.height * (td_float)src_dst_size.dst.height) & (~1);
|
||||
|
||||
rect->rect[num].point[OT_MACRO_POINT_IDX_THREE].x = (td_u32)((td_float)blob->rgn[i].left /
|
||||
(td_float)src_dst_size.src.width * (td_float)src_dst_size.dst.width) & (~1);
|
||||
rect->rect[num].point[OT_MACRO_POINT_IDX_THREE].y = (td_u32)((td_float)blob->rgn[i].bottom /
|
||||
(td_float)src_dst_size.src.height * (td_float)src_dst_size.dst.height) & (~1);
|
||||
|
||||
valid = TD_TRUE;
|
||||
_common_ive_is_rect_valid(rect, num, &valid);
|
||||
if (valid == TD_TRUE) {
|
||||
num++;
|
||||
}
|
||||
}
|
||||
|
||||
rect->num = num;
|
||||
return TD_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
static td_s32 _comm_ive_set_image_addr(ot_svp_img *img, const ot_struct_rw_image_loop_info *loop_info,
|
||||
td_bool is_mmz_cached)
|
||||
{
|
||||
td_u32 c;
|
||||
td_u32 size = 0;
|
||||
td_s32 ret;
|
||||
td_void *virt_addr = TD_NULL;
|
||||
for (c = 0; (c < loop_info->loop_c) && (c < OT_MAX_LOOP_IMG_H) && (c < OT_SVP_IMG_STRIDE_NUM); c++) {
|
||||
size += img->stride[0] * loop_info->loop_h[c] * loop_info->ele_size;
|
||||
img->stride[c] = img->stride[0];
|
||||
}
|
||||
|
||||
if (is_mmz_cached == TD_FALSE) {
|
||||
ret = ss_mpi_sys_mmz_alloc((td_phys_addr_t *)&img->phys_addr[0], (td_void **)&virt_addr,
|
||||
TD_NULL, TD_NULL, size);
|
||||
} else {
|
||||
ret = ss_mpi_sys_mmz_alloc_cached((td_phys_addr_t *)&img->phys_addr[0], (td_void **)&virt_addr,
|
||||
TD_NULL, TD_NULL, size);
|
||||
}
|
||||
macro_svp_check_exps_return(ret != TD_SUCCESS, ret, ENUM_SVP_ERR_LEVEL_ERROR, "mmz malloc fail\n");
|
||||
img->virt_addr[OT_MACRO_ADDR_IDX_ZERO] = macro_svp_convert_ptr_to_addr(td_u64, virt_addr);
|
||||
|
||||
if (img->type != OT_SVP_IMG_TYPE_U8C3_PACKAGE) {
|
||||
for (c = 1; (c < loop_info->loop_c) && (c < OT_MAX_LOOP_IMG_H) && (c < OT_SVP_IMG_STRIDE_NUM); c++) {
|
||||
img->phys_addr[c] = img->phys_addr[c - 1] + img->stride[c - 1] * img->height;
|
||||
img->virt_addr[c] = img->virt_addr[c - 1] + img->stride[c - 1] * img->height;
|
||||
}
|
||||
} else {
|
||||
img->virt_addr[OT_MACRO_ADDR_IDX_ONE] = img->virt_addr[OT_MACRO_ADDR_IDX_ZERO] + 1;
|
||||
img->virt_addr[OT_MACRO_ADDR_IDX_TWO] = img->virt_addr[OT_MACRO_ADDR_IDX_ONE] + 1;
|
||||
img->phys_addr[OT_MACRO_ADDR_IDX_ONE] = img->phys_addr[OT_MACRO_ADDR_IDX_ZERO] + 1;
|
||||
img->phys_addr[OT_MACRO_ADDR_IDX_TWO] = img->phys_addr[OT_MACRO_ADDR_IDX_ONE] + 1;
|
||||
}
|
||||
return TD_SUCCESS;
|
||||
}
|
||||
|
||||
/*
|
||||
* function : Create ive image
|
||||
*/
|
||||
static td_s32 _common_ive_create_image_flag(ot_svp_img *img, ot_svp_img_type type,
|
||||
td_u32 width, td_u32 height, td_bool is_mmz_cached)
|
||||
{
|
||||
td_s32 ret = OT_ERR_IVE_ILLEGAL_PARAM;
|
||||
ot_struct_rw_image_loop_info loop_info = {0};
|
||||
macro_svp_check_exps_return(img == TD_NULL, OT_ERR_IVE_NULL_PTR, ENUM_SVP_ERR_LEVEL_ERROR, "img can't be null\n");
|
||||
macro_svp_check_exps_return((type < 0) || (type >= OT_SVP_IMG_TYPE_BUTT), ret, ENUM_SVP_ERR_LEVEL_ERROR,
|
||||
"type(%u) must be in [0, %u)!\n", type, OT_SVP_IMG_TYPE_BUTT);
|
||||
macro_svp_check_exps_return(width > OT_SAMPLE_IVE_MAX_WIDTH, ret, ENUM_SVP_ERR_LEVEL_ERROR,
|
||||
"width(%u) must be in [1, %u]!\n", width, OT_SAMPLE_IVE_MAX_WIDTH);
|
||||
macro_svp_check_exps_return(width > OT_SAMPLE_IVE_MAX_HEIGHT, ret, ENUM_SVP_ERR_LEVEL_ERROR,
|
||||
"width(%u) must be in [1, %u]!\n", width, OT_SAMPLE_IVE_MAX_HEIGHT);
|
||||
|
||||
img->type = type;
|
||||
img->width = width;
|
||||
img->height = height;
|
||||
img->stride[0] = libapi_common_ive_calc_stride(img->width, OT_IVE_ALIGN);
|
||||
|
||||
switch (type) {
|
||||
case OT_SVP_IMG_TYPE_U8C1:
|
||||
case OT_SVP_IMG_TYPE_S8C1:
|
||||
case OT_SVP_IMG_TYPE_YUV420SP:
|
||||
case OT_SVP_IMG_TYPE_YUV422SP:
|
||||
case OT_SVP_IMG_TYPE_S16C1:
|
||||
case OT_SVP_IMG_TYPE_U16C1:
|
||||
case OT_SVP_IMG_TYPE_U8C3_PACKAGE:
|
||||
case OT_SVP_IMG_TYPE_S32C1:
|
||||
case OT_SVP_IMG_TYPE_U32C1:
|
||||
case OT_SVP_IMG_TYPE_S64C1:
|
||||
case OT_SVP_IMG_TYPE_U64C1: {
|
||||
_comm_ive_get_loop_info(img, &loop_info);
|
||||
ret = _comm_ive_set_image_addr(img, &loop_info, is_mmz_cached);
|
||||
macro_svp_check_exps_return(ret != TD_SUCCESS, ret, ENUM_SVP_ERR_LEVEL_ERROR,
|
||||
"Err:%#x,_comm_ive_set_image_addr failed\n", ret);
|
||||
break;
|
||||
}
|
||||
case OT_SVP_IMG_TYPE_YUV420P:
|
||||
break;
|
||||
case OT_SVP_IMG_TYPE_YUV422P:
|
||||
break;
|
||||
case OT_SVP_IMG_TYPE_S8C2_PACKAGE:
|
||||
break;
|
||||
case OT_SVP_IMG_TYPE_S8C2_PLANAR:
|
||||
break;
|
||||
case OT_SVP_IMG_TYPE_U8C3_PLANAR:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
return TD_SUCCESS;
|
||||
}
|
||||
|
||||
td_s32 libapi_common_ive_create_image(ot_svp_img *img, ot_svp_img_type type,
|
||||
td_u32 width, td_u32 height)
|
||||
{
|
||||
return _common_ive_create_image_flag(img, type, width, height, TD_FALSE);
|
||||
}
|
||||
|
||||
td_s32 libapi_common_ive_destroy_image(ot_svp_img *img)
|
||||
{
|
||||
if (TD_NULL != img) macro_svp_mmz_free(img->phys_addr[0], img->virt_addr[0]);
|
||||
return TD_SUCCESS;
|
||||
}
|
||||
|
||||
/*
|
||||
* function : Create memory info
|
||||
*/
|
||||
td_s32 libapi_common_ive_create_mem_info(ot_svp_mem_info *mem_info, td_u32 size)
|
||||
{
|
||||
td_s32 ret = OT_ERR_IVE_NULL_PTR;
|
||||
td_void *virt_addr = TD_NULL;
|
||||
|
||||
macro_svp_check_exps_return(mem_info == TD_NULL, ret, ENUM_SVP_ERR_LEVEL_ERROR, "mem_info can't be null\n");
|
||||
|
||||
mem_info->size = size;
|
||||
ret = ss_mpi_sys_mmz_alloc((td_phys_addr_t *)&mem_info->phys_addr, (td_void **)&virt_addr, TD_NULL, TD_NULL, size);
|
||||
macro_svp_check_exps_return(ret != TD_SUCCESS, ret, ENUM_SVP_ERR_LEVEL_ERROR,
|
||||
"Mmz Alloc fail,Error(%#x)\n", ret);
|
||||
mem_info->virt_addr = macro_svp_convert_ptr_to_addr(td_u64, virt_addr);
|
||||
|
||||
return TD_SUCCESS;
|
||||
}
|
||||
|
||||
/*
|
||||
* function : Destroy memory info
|
||||
*/
|
||||
td_s32 libapi_common_ive_destroy_mem_info(ot_svp_mem_info *mem_info)
|
||||
{
|
||||
if (TD_NULL != mem_info) macro_svp_mmz_free(mem_info->phys_addr, mem_info->virt_addr);
|
||||
return TD_SUCCESS;
|
||||
}
|
||||
|
||||
/*
|
||||
* function : Create ive image by cached
|
||||
*/
|
||||
td_s32 libapi_common_ive_create_image_by_cached(ot_svp_img *img, ot_svp_img_type type,
|
||||
td_u32 width, td_u32 height)
|
||||
{
|
||||
return _common_ive_create_image_flag(img, type, width, height, TD_TRUE);
|
||||
}
|
||||
|
||||
/*
|
||||
* function : Dma frame info to ive image
|
||||
*/
|
||||
td_s32 libapi_common_ive_dma_image(ot_video_frame_info *frame_info, ot_svp_dst_img *dst,
|
||||
td_bool is_instant)
|
||||
{
|
||||
td_s32 ret = OT_ERR_IVE_NULL_PTR;
|
||||
ot_ive_handle handle;
|
||||
ot_svp_src_data src_data;
|
||||
ot_svp_dst_data dst_data;
|
||||
ot_ive_dma_ctrl ctrl = { OT_IVE_DMA_MODE_DIRECT_COPY, 0, 0, 0, 0 };
|
||||
td_bool is_finish = TD_FALSE;
|
||||
td_bool is_block = TD_TRUE;
|
||||
|
||||
macro_svp_check_exps_return(frame_info == TD_NULL, ret, ENUM_SVP_ERR_LEVEL_ERROR, "frame_info can't be null\n");
|
||||
macro_svp_check_exps_return(dst == TD_NULL, ret, ENUM_SVP_ERR_LEVEL_ERROR, "dst can't be null\n");
|
||||
macro_svp_check_exps_return(frame_info->video_frame.virt_addr == TD_NULL, ret, ENUM_SVP_ERR_LEVEL_ERROR,
|
||||
"frame_info->video_frame.virt_addr can't be null\n");
|
||||
ret = OT_ERR_IVE_ILLEGAL_PARAM;
|
||||
macro_svp_check_exps_return(frame_info->video_frame.phys_addr == 0, ret, ENUM_SVP_ERR_LEVEL_ERROR,
|
||||
"frame_info->video_frame.virt_addr can't be 0\n");
|
||||
macro_svp_check_exps_return(dst->virt_addr == 0, ret, ENUM_SVP_ERR_LEVEL_ERROR, "dst->virt_addr can't be 0\n");
|
||||
macro_svp_check_exps_return(dst->phys_addr == 0, ret, ENUM_SVP_ERR_LEVEL_ERROR, "dst->phys_addr can't be 0\n");
|
||||
|
||||
/* fill src */
|
||||
src_data.virt_addr = macro_svp_convert_ptr_to_addr(td_u64, frame_info->video_frame.virt_addr[0]);
|
||||
src_data.phys_addr = frame_info->video_frame.phys_addr[0];
|
||||
src_data.width = frame_info->video_frame.width;
|
||||
src_data.height = frame_info->video_frame.height;
|
||||
src_data.stride = frame_info->video_frame.stride[0];
|
||||
|
||||
/* fill dst */
|
||||
dst_data.virt_addr = dst->virt_addr[0];
|
||||
dst_data.phys_addr = dst->phys_addr[0];
|
||||
dst_data.width = dst->width;
|
||||
dst_data.height = dst->height;
|
||||
dst_data.stride = dst->stride[0];
|
||||
|
||||
ret = ss_mpi_ive_dma(&handle, &src_data, &dst_data, &ctrl, is_instant);
|
||||
macro_svp_check_exps_return(ret != TD_SUCCESS, ret, ENUM_SVP_ERR_LEVEL_ERROR,
|
||||
"Error(%#x),ss_mpi_ive_dma failed!\n", ret);
|
||||
|
||||
if (is_instant == TD_TRUE) {
|
||||
ret = ss_mpi_ive_query(handle, &is_finish, is_block);
|
||||
while (ret == OT_ERR_IVE_QUERY_TIMEOUT) {
|
||||
usleep(OT_SAMPLE_IVE_QUERY_SLEEP);
|
||||
ret = ss_mpi_ive_query(handle, &is_finish, is_block);
|
||||
}
|
||||
macro_svp_check_exps_return(ret != TD_SUCCESS, ret, ENUM_SVP_ERR_LEVEL_ERROR,
|
||||
"Error(%#x),ss_mpi_ive_query failed!\n", ret);
|
||||
}
|
||||
|
||||
return TD_SUCCESS;
|
||||
}
|
181
libapi/ive/libapi_common_ive.h
Executable file
@ -0,0 +1,181 @@
|
||||
/*
|
||||
Copyright (c), 2001-2022, Shenshu Tech. Co., Ltd.
|
||||
*/
|
||||
|
||||
#ifndef LIBAPI_COMMON_IVE_H
|
||||
#define LIBAPI_COMMON_IVE_H
|
||||
|
||||
#include "ot_common_svp.h"
|
||||
#include "ot_common_ive.h"
|
||||
#include "ss_mpi_ive.h"
|
||||
#include "sample_comm.h"
|
||||
#include "libapi_common_svp.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#include <signal.h>
|
||||
|
||||
#define OT_VIDEO_WIDTH 352
|
||||
#define OT_VIDEO_HEIGHT 288
|
||||
#define OT_IVE_ALIGN 16
|
||||
#define OT_IVE_CHAR_CALW 8
|
||||
#define OT_IVE_CHAR_CALH 8
|
||||
#define OT_IVE_CHAR_NUM (OT_IVE_CHAR_CALW * OT_IVE_CHAR_CALH)
|
||||
#define OT_IVE_FILE_NAME_LEN 256
|
||||
#define OT_VPSS_CHN_NUM 2
|
||||
|
||||
#define OT_MAX_LOOP_IMG_H 3
|
||||
|
||||
#define OT_MACRO_IVE_IMAGE_CHN_ONE 1
|
||||
#define OT_MACRO_IVE_IMAGE_CHN_TWO 2
|
||||
#define OT_MACRO_IVE_IMAGE_CHN_THREE 3
|
||||
#define OT_MACRO_IVE_IMAGE_CHN_FOUR 4
|
||||
#define OT_MACRO_IVE_MAX_CCL_REGION_NUM 254
|
||||
#define OT_MACRO_IVE_DIV_TWO 2
|
||||
#define OT_MACRO_POINT_IDX_ZERO 0
|
||||
#define OT_MACRO_POINT_IDX_ONE 1
|
||||
#define OT_MACRO_POINT_IDX_TWO 2
|
||||
#define OT_MACRO_POINT_IDX_THREE 3
|
||||
|
||||
#define OT_MACRO_ADDR_IDX_ZERO 0
|
||||
#define OT_MACRO_ADDR_IDX_ONE 1
|
||||
#define OT_MACRO_ADDR_IDX_TWO 2
|
||||
#define OT_MACRO_IVE_MAX_POOL_CNT 128
|
||||
#define OT_MACRO_IVE_DRAW_THICK 2
|
||||
|
||||
#define OT_MACRO_IVE_PIPE_IDX_ZERO 0
|
||||
#define OT_MACRO_IVE_PIPE_IDX_ONE 1
|
||||
#define OT_MACRO_IVE_PIPE_IDX_TWO 2
|
||||
#define OT_MACRO_IVE_PIPE_IDX_THREE 3
|
||||
|
||||
#define OT_MACRO_IVE_1080P_WIDTH 1920
|
||||
#define OT_MACRO_IVE_1080P_HEIGHT 1080
|
||||
|
||||
#define OT_MACRO_IVE_MASK_NUM 25
|
||||
#define OT_MACRO_IDX_ZERO 0
|
||||
#define OT_MACRO_IDX_ONE 1
|
||||
#define OT_MACRO_IDX_TWO 2
|
||||
#define OT_MACRO_IDX_THREE 3
|
||||
#define OT_MACRO_IDX_FOUR 4
|
||||
#define OT_MACRO_IDX_FIVE 5
|
||||
|
||||
#define OT_MACRO_NUM_ZERO 0
|
||||
#define OT_MACRO_NUM_ONE 1
|
||||
#define OT_MACRO_NUM_TWO 2
|
||||
#define OT_MACRO_NUM_THREE 3
|
||||
#define OT_MACRO_NUM_FOUR 4
|
||||
#define OT_MACRO_NUM_FIVE 5
|
||||
#define OT_MACRO_NUM_SEVEN 7
|
||||
#define OT_MACRO_QUARTER_OF_1M 256
|
||||
#define OT_MACRO_1M 1024
|
||||
#define OT_MACRO_4M (4 * 1024)
|
||||
#define OT_MACRO_MAX_SRC_FRAME_RATE 30
|
||||
#define OT_MACRO_MAX_DST_FRAME_RATE 30
|
||||
|
||||
#define ot_macro_align_back(x, a) ((a) * (((x) / (a))))
|
||||
#define ot_macro_ive_max(a, b) (((a) > (b)) ? (a) : (b))
|
||||
#define ot_macro_ive_min(a, b) (((a) < (b)) ? (a) : (b))
|
||||
|
||||
typedef struct {
|
||||
td_s32 linear_num;
|
||||
td_s32 thresh_num;
|
||||
ot_point *linear_point;
|
||||
} ot_struct_ive_linear_data;
|
||||
|
||||
typedef struct {
|
||||
td_u32 ele_size; /* element size */
|
||||
td_u32 loop_c; /* loop times of c dimension */
|
||||
td_u32 loop_h[OT_SVP_IMG_ADDR_NUM]; /* loop times of h dimension */
|
||||
} ot_struct_rw_image_loop_info;
|
||||
|
||||
typedef struct {
|
||||
ot_size src;
|
||||
ot_size dst;
|
||||
} ot_struct_src_dst_size;
|
||||
|
||||
/*
|
||||
* function : Mpi check init
|
||||
*/
|
||||
td_s32 libapi_common_ive_check_mpi_init(td_void);
|
||||
|
||||
/*
|
||||
* function : Mpi init
|
||||
*/
|
||||
td_s32 libapi_common_ive_mpi_init(td_void);
|
||||
|
||||
/*
|
||||
* function : Mpi exit
|
||||
*/
|
||||
td_void libapi_common_ive_mpi_exit(td_void);
|
||||
|
||||
/*
|
||||
* function :Read file
|
||||
*/
|
||||
td_s32 libapi_common_ive_read_file(ot_svp_img *img, FILE *fp);
|
||||
|
||||
/*
|
||||
* function :Write file
|
||||
*/
|
||||
td_s32 libapi_common_ive_write_file(ot_svp_img *img, FILE *fp);
|
||||
|
||||
/*
|
||||
* function :Read os_mem
|
||||
*/
|
||||
td_s32 libapi_common_ive_read_os_mem(ot_svp_img *img, td_void *src, td_u32 whidh, td_u32 height, td_u32 img_type);
|
||||
|
||||
/*
|
||||
* function :Write os_mem
|
||||
*/
|
||||
td_s32 libapi_common_ive_write_os_mem(ot_svp_img *img, td_void *tar);
|
||||
|
||||
/*
|
||||
* function :Calc stride
|
||||
*/
|
||||
td_u32 libapi_common_ive_calc_stride(td_u32 width, td_u8 align);
|
||||
|
||||
/*
|
||||
* function : Copy blob to rect
|
||||
*/
|
||||
td_s32 libapi_common_ive_blob_to_rect(ot_ive_ccblob *blob, ot_struct_svp_rect_info *rect,
|
||||
td_u16 rect_max_num, td_u16 area_thr_step, ot_struct_src_dst_size src_dst_size);
|
||||
|
||||
/*
|
||||
* function : Create ive image
|
||||
*/
|
||||
td_s32 libapi_common_ive_create_image(ot_svp_img *img, ot_svp_img_type type,
|
||||
td_u32 width, td_u32 height);
|
||||
|
||||
/*
|
||||
* function : Destroy ive image
|
||||
*/
|
||||
td_s32 libapi_common_ive_destroy_image(ot_svp_img *img);
|
||||
|
||||
/*
|
||||
* function : Create memory info
|
||||
*/
|
||||
td_s32 libapi_common_ive_create_mem_info(ot_svp_mem_info *mem_info, td_u32 size);
|
||||
|
||||
/*
|
||||
* function : Destroy memory info
|
||||
*/
|
||||
td_s32 libapi_common_ive_destroy_mem_info(ot_svp_mem_info *mem_info);
|
||||
|
||||
/*
|
||||
* function : Create ive image by cached
|
||||
*/
|
||||
td_s32 libapi_common_ive_create_image_by_cached(ot_svp_img *img,
|
||||
ot_svp_img_type type, td_u32 width, td_u32 height);
|
||||
|
||||
/*
|
||||
* function : Dma frame info to ive image
|
||||
*/
|
||||
td_s32 libapi_common_ive_dma_image(ot_video_frame_info *frame_info, ot_svp_dst_img *dst,
|
||||
td_bool is_instant);
|
||||
#endif
|
489
libapi/ive/libapi_ive_canny.c
Executable file
@ -0,0 +1,489 @@
|
||||
/*
|
||||
Copyright (c), 2001-2022, Shenshu Tech. Co., Ltd.
|
||||
*/
|
||||
#include "libapi_common_ive.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#include <signal.h>
|
||||
#include <semaphore.h>
|
||||
#include <pthread.h>
|
||||
#include <math.h>
|
||||
#include <limits.h>
|
||||
|
||||
#define OT_MACRO_IVE_CANNY_QUERY_SLEEP 100
|
||||
#define OT_MACRO_IVE_CANNY_HIGH_THR 150
|
||||
#define OT_MACRO_IVE_CANNY_LOW_THR 50
|
||||
#define OT_MACRO_IVE_THR_U16_HIGH_THR 100
|
||||
#define OT_MACRO_IVE_THR_U16_LOW_THR 100
|
||||
#define OT_MACRO_IVE_THR_U16_MAX_VAL 255
|
||||
#define OT_MACRO_IVE_CANNY_EDGE_NUM 3
|
||||
#define OT_MACRO_IVE_D1_WIDTH 720
|
||||
#define OT_MACRO_IVE_D1_HEIGHT 576
|
||||
|
||||
typedef struct {
|
||||
ot_svp_src_img src;
|
||||
ot_svp_dst_img edge;
|
||||
ot_svp_dst_img mag;
|
||||
ot_svp_mem_info stack;
|
||||
ot_ive_canny_hys_edge_ctrl canny_hys_edge_ctrl;
|
||||
ot_ive_mag_and_ang_ctrl mag_and_ang_ctrl;
|
||||
ot_ive_threshold_u16_ctrl thr_u16_ctrl;
|
||||
void *p_os_src_mem; // 必须是已经分配好得内存
|
||||
void *p_os_edge_mem; // 必须是已经分配好得内存
|
||||
td_u32 width;
|
||||
td_u32 height;
|
||||
td_u32 type;
|
||||
FILE *fp_src;
|
||||
FILE *fp_dst;
|
||||
} ot_struct_ive_canny_info;
|
||||
|
||||
static ot_struct_ive_canny_info g_canny_info;
|
||||
static td_bool g_stop_signal = TD_FALSE;
|
||||
|
||||
/*
|
||||
* function : Canny uninit
|
||||
*/
|
||||
static td_void _ive_canny_uninit(ot_struct_ive_canny_info *canny_info)
|
||||
{
|
||||
macro_svp_mmz_free(canny_info->src.phys_addr[0], canny_info->src.virt_addr[0]);
|
||||
macro_svp_mmz_free(canny_info->edge.phys_addr[0], canny_info->edge.virt_addr[0]);
|
||||
macro_svp_mmz_free(canny_info->mag.phys_addr[0], canny_info->mag.virt_addr[0]);
|
||||
macro_svp_mmz_free(canny_info->stack.phys_addr, canny_info->stack.virt_addr);
|
||||
macro_svp_mmz_free(canny_info->canny_hys_edge_ctrl.mem.phys_addr,
|
||||
canny_info->canny_hys_edge_ctrl.mem.virt_addr);
|
||||
|
||||
macro_svp_close_file(canny_info->fp_src);
|
||||
macro_svp_close_file(canny_info->fp_dst);
|
||||
}
|
||||
|
||||
static td_void _ive_canny_ctrl_init(ot_struct_ive_canny_info *canny_info)
|
||||
{
|
||||
canny_info->canny_hys_edge_ctrl.high_threshold = OT_MACRO_IVE_CANNY_HIGH_THR;
|
||||
canny_info->canny_hys_edge_ctrl.low_threshold = OT_MACRO_IVE_CANNY_LOW_THR;
|
||||
canny_info->mag_and_ang_ctrl.out_ctrl = OT_IVE_MAG_AND_ANG_OUT_CTRL_MAG;
|
||||
canny_info->mag_and_ang_ctrl.threshold = 0;
|
||||
canny_info->thr_u16_ctrl.mode = OT_IVE_THRESHOLD_U16_MODE_U16_TO_U8_MIN_MID_MAX;
|
||||
canny_info->thr_u16_ctrl.high_threshold = OT_MACRO_IVE_THR_U16_HIGH_THR;
|
||||
canny_info->thr_u16_ctrl.low_threshold = OT_MACRO_IVE_THR_U16_LOW_THR;
|
||||
canny_info->thr_u16_ctrl.max_val = OT_MACRO_IVE_THR_U16_MAX_VAL;
|
||||
canny_info->thr_u16_ctrl.mid_val = 0;
|
||||
canny_info->thr_u16_ctrl.min_val = 0;
|
||||
}
|
||||
|
||||
static td_void _ive_canny_ctrl_init_ex(ot_ive_canny_hys_edge_ctrl *canny_hys_edge_ctrl,
|
||||
ot_ive_mag_and_ang_ctrl *mag_and_ang_ctrl,
|
||||
ot_ive_threshold_u16_ctrl *thr_u16_ctrl)
|
||||
{
|
||||
canny_hys_edge_ctrl->high_threshold = OT_MACRO_IVE_CANNY_HIGH_THR;
|
||||
canny_hys_edge_ctrl->low_threshold = OT_MACRO_IVE_CANNY_LOW_THR;
|
||||
mag_and_ang_ctrl->out_ctrl = OT_IVE_MAG_AND_ANG_OUT_CTRL_MAG;
|
||||
mag_and_ang_ctrl->threshold = 0;
|
||||
thr_u16_ctrl->mode = OT_IVE_THRESHOLD_U16_MODE_U16_TO_U8_MIN_MID_MAX;
|
||||
thr_u16_ctrl->high_threshold = OT_MACRO_IVE_THR_U16_HIGH_THR;
|
||||
thr_u16_ctrl->low_threshold = OT_MACRO_IVE_THR_U16_LOW_THR;
|
||||
thr_u16_ctrl->max_val = OT_MACRO_IVE_THR_U16_MAX_VAL;
|
||||
thr_u16_ctrl->mid_val = 0;
|
||||
thr_u16_ctrl->min_val = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* function : Canny init
|
||||
*/
|
||||
static td_s32 _ive_canny_init(ot_struct_ive_canny_info *canny_info, td_u32 width,
|
||||
td_u32 height, td_char canny_complete)
|
||||
{
|
||||
td_s32 ret;
|
||||
td_u32 size;
|
||||
td_char path[PATH_MAX] = {0};
|
||||
td_char tmp_file[PATH_MAX] = {0};
|
||||
td_s8 mask[OT_IVE_MASK_NUM] = { 0, 0, 0, 0, 0, 0, -1, 0, 1, 0, 0, -2, 0, 2, 0, 0, -1, 0, 1, 0, 0, 0, 0, 0, 0 };
|
||||
const td_char *src_file = "./data/input/canny/canny.yuv";
|
||||
|
||||
macro_svp_check_exps_return((strlen(src_file) > PATH_MAX) || (realpath(src_file, path) == TD_NULL),
|
||||
OT_ERR_IVE_ILLEGAL_PARAM, ENUM_SVP_ERR_LEVEL_ERROR, "invalid file!\n");
|
||||
|
||||
(td_void)memset_s(canny_info, sizeof(ot_struct_ive_canny_info), 0, sizeof(ot_struct_ive_canny_info));
|
||||
ret = memcpy_s(canny_info->canny_hys_edge_ctrl.mask, OT_IVE_MASK_NUM, mask, OT_IVE_MASK_NUM);
|
||||
macro_svp_check_exps_return(ret != EOK, ret, ENUM_SVP_ERR_LEVEL_ERROR, "memcpy_s mask failed!\n");
|
||||
ret = memcpy_s(canny_info->mag_and_ang_ctrl.mask, OT_IVE_MASK_NUM, mask, OT_IVE_MASK_NUM);
|
||||
macro_svp_check_exps_return(ret != EOK, ret, ENUM_SVP_ERR_LEVEL_ERROR, "memcpy_s mask failed!\n");
|
||||
|
||||
_ive_canny_ctrl_init(canny_info);
|
||||
|
||||
ret = libapi_common_ive_create_image(&canny_info->src, OT_SVP_IMG_TYPE_U8C1, width, height);
|
||||
macro_svp_check_exps_goto(ret != TD_SUCCESS, fail, ENUM_SVP_ERR_LEVEL_ERROR, "Error,create src img failed!\n");
|
||||
|
||||
ret = libapi_common_ive_create_image(&canny_info->edge, OT_SVP_IMG_TYPE_U8C1, width, height);
|
||||
macro_svp_check_exps_goto(ret != TD_SUCCESS, fail, ENUM_SVP_ERR_LEVEL_ERROR, "Error,create edge img failed!\n");
|
||||
|
||||
ret = libapi_common_ive_create_image(&canny_info->mag, OT_SVP_IMG_TYPE_U16C1, width, height);
|
||||
macro_svp_check_exps_goto(ret != TD_SUCCESS, fail, ENUM_SVP_ERR_LEVEL_ERROR, "Error,create mag img failed!\n");
|
||||
|
||||
size = canny_info->src.stride[0] * canny_info->src.height * sizeof(ot_svp_point_u16) +
|
||||
sizeof(ot_ive_canny_stack_size);
|
||||
ret = libapi_common_ive_create_mem_info(&canny_info->stack, size);
|
||||
macro_svp_check_exps_goto(ret != TD_SUCCESS, fail, ENUM_SVP_ERR_LEVEL_ERROR,
|
||||
"Error,create stack mem_info failed!\n");
|
||||
|
||||
size = canny_info->src.stride[0] * canny_info->src.height * OT_MACRO_IVE_CANNY_EDGE_NUM;
|
||||
ret = libapi_common_ive_create_mem_info(&canny_info->canny_hys_edge_ctrl.mem, size);
|
||||
macro_svp_check_exps_goto(ret != TD_SUCCESS, fail, ENUM_SVP_ERR_LEVEL_ERROR,
|
||||
"Error,create canny_hys_edge_ctrl.mem failed!\n");
|
||||
|
||||
/* src file */
|
||||
ret = TD_FAILURE;
|
||||
canny_info->fp_src = fopen(path, "rb");
|
||||
macro_svp_check_exps_goto(canny_info->fp_src == TD_NULL, fail, ENUM_SVP_ERR_LEVEL_ERROR, "Open file failed!\n");
|
||||
|
||||
/* dst file */
|
||||
macro_svp_check_exps_goto(realpath("./data/output/canny", path) == TD_NULL, fail,
|
||||
ENUM_SVP_ERR_LEVEL_ERROR, "invalid file!\n");
|
||||
ret = snprintf_s(tmp_file, sizeof(tmp_file) - 1, sizeof(tmp_file) - 1, "/cannyout_complete_%c.yuv", canny_complete);
|
||||
macro_svp_check_exps_goto((ret < 0) || (ret > (td_s32)(sizeof(tmp_file) - 1)), fail,
|
||||
ENUM_SVP_ERR_LEVEL_ERROR, "Error,snprintf_s src file name failed!\n");
|
||||
|
||||
ret = strcat_s(path, PATH_MAX, tmp_file);
|
||||
macro_svp_check_exps_goto(ret != EOK, fail, ENUM_SVP_ERR_LEVEL_ERROR, "strcat_s failed!\n");
|
||||
ret = TD_FAILURE;
|
||||
canny_info->fp_dst = fopen(path, "wb");
|
||||
macro_svp_check_exps_goto(canny_info->fp_dst == TD_NULL, fail, ENUM_SVP_ERR_LEVEL_ERROR, "Open file failed!\n");
|
||||
|
||||
return TD_SUCCESS;
|
||||
fail:
|
||||
_ive_canny_uninit(canny_info);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* function : show complete canny demo
|
||||
*/
|
||||
static td_s32 _ive_complete_canny(ot_struct_ive_canny_info *canny_info)
|
||||
{
|
||||
td_s32 ret, i;
|
||||
td_bool is_instant = TD_TRUE;
|
||||
td_bool is_block = TD_TRUE;
|
||||
td_bool is_finish = TD_FALSE;
|
||||
ot_ive_handle handle;
|
||||
|
||||
for (i = 0; (i < 1) && (g_stop_signal == TD_FALSE); i++) {
|
||||
ret = libapi_common_ive_read_file(&(canny_info->src), canny_info->fp_src);
|
||||
macro_svp_check_exps_return(ret != TD_SUCCESS, ret, ENUM_SVP_ERR_LEVEL_ERROR,
|
||||
"Error(%#x),Read src file failed!\n", ret);
|
||||
|
||||
ret = ss_mpi_ive_canny_hys_edge(&handle, &canny_info->src, &canny_info->edge, &canny_info->stack,
|
||||
&canny_info->canny_hys_edge_ctrl, is_instant);
|
||||
macro_svp_check_exps_return(ret != TD_SUCCESS, ret, ENUM_SVP_ERR_LEVEL_ERROR,
|
||||
"Error(%#x),ss_mpi_ive_canny_hys_edge failed!\n", ret);
|
||||
|
||||
ret = ss_mpi_ive_query(handle, &is_finish, is_block);
|
||||
while (ret == OT_ERR_IVE_QUERY_TIMEOUT) {
|
||||
usleep(OT_MACRO_IVE_CANNY_QUERY_SLEEP);
|
||||
ret = ss_mpi_ive_query(handle, &is_finish, is_block);
|
||||
}
|
||||
macro_svp_check_exps_return(ret != TD_SUCCESS, ret, ENUM_SVP_ERR_LEVEL_ERROR,
|
||||
"Error(%#x),ss_mpi_ive_query failed!\n", ret);
|
||||
|
||||
ret = ss_mpi_ive_canny_edge(&canny_info->edge, &canny_info->stack);
|
||||
macro_svp_check_exps_return(ret != TD_SUCCESS, ret, ENUM_SVP_ERR_LEVEL_ERROR,
|
||||
"Error(%#x),ss_mpi_ive_canny_edge failed!\n", ret);
|
||||
|
||||
ret = libapi_common_ive_write_file(&canny_info->edge, canny_info->fp_dst);
|
||||
macro_svp_check_exps_return(ret != TD_SUCCESS, ret, ENUM_SVP_ERR_LEVEL_ERROR,
|
||||
"Error(%#x),Write edge file failed!\n", ret);
|
||||
}
|
||||
return TD_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* function : show part canny demo
|
||||
*/
|
||||
static td_s32 _ive_part_canny(ot_struct_ive_canny_info *canny_info)
|
||||
{
|
||||
td_s32 ret, i;
|
||||
td_bool is_instant = TD_FALSE;
|
||||
td_bool is_block = TD_TRUE;
|
||||
td_bool is_finish = TD_FALSE;
|
||||
ot_ive_handle handle;
|
||||
|
||||
for (i = 0; (i < 1) && (g_stop_signal == TD_FALSE); i++) {
|
||||
ret = libapi_common_ive_read_file(&canny_info->src, canny_info->fp_src);
|
||||
macro_svp_check_exps_return(ret != TD_SUCCESS, ret, ENUM_SVP_ERR_LEVEL_ERROR,
|
||||
"Error(%#x),Read src file failed!\n", ret);
|
||||
|
||||
ret = ss_mpi_ive_mag_and_ang(&handle, &canny_info->src, &canny_info->mag, TD_NULL,
|
||||
&canny_info->mag_and_ang_ctrl, is_instant);
|
||||
macro_svp_check_exps_return(ret != TD_SUCCESS, ret, ENUM_SVP_ERR_LEVEL_ERROR,
|
||||
"Error(%#x),ss_mpi_ive_mag_and_ang failed!\n", ret);
|
||||
|
||||
is_instant = TD_TRUE;
|
||||
ret = ss_mpi_ive_threshold_u16(&handle, &canny_info->mag, &canny_info->edge,
|
||||
&canny_info->thr_u16_ctrl, is_instant);
|
||||
macro_svp_check_exps_return(ret != TD_SUCCESS, ret, ENUM_SVP_ERR_LEVEL_ERROR,
|
||||
"Error(%#x),ss_mpi_ive_threshold_u16 failed!\n", ret);
|
||||
|
||||
ret = ss_mpi_ive_query(handle, &is_finish, is_block);
|
||||
while (ret == OT_ERR_IVE_QUERY_TIMEOUT) {
|
||||
usleep(OT_MACRO_IVE_CANNY_QUERY_SLEEP);
|
||||
ret = ss_mpi_ive_query(handle, &is_finish, is_block);
|
||||
}
|
||||
macro_svp_check_exps_return(ret != TD_SUCCESS, ret, ENUM_SVP_ERR_LEVEL_ERROR,
|
||||
"Error(%#x),ss_mpi_ive_query failed!\n", ret);
|
||||
|
||||
ret = libapi_common_ive_write_file(&canny_info->edge, canny_info->fp_dst);
|
||||
macro_svp_check_exps_return(ret != TD_SUCCESS, ret, ENUM_SVP_ERR_LEVEL_ERROR,
|
||||
"Error(%#x),Write edge file failed!\n", ret);
|
||||
}
|
||||
return TD_SUCCESS;
|
||||
}
|
||||
|
||||
static td_void _ive_canny_stop(td_void)
|
||||
{
|
||||
_ive_canny_uninit(&g_canny_info);
|
||||
(td_void)memset_s(&g_canny_info, sizeof(g_canny_info), 0, sizeof(g_canny_info));
|
||||
libapi_common_ive_mpi_exit();
|
||||
printf("\033[0;31mprogram termination abnormally!\033[0;39m\n");
|
||||
}
|
||||
|
||||
/*
|
||||
* function : show canny demo
|
||||
*/
|
||||
static td_void _libapi_ive_canny(td_char canny_complete)
|
||||
{
|
||||
const td_u16 width = OT_MACRO_IVE_D1_WIDTH;
|
||||
const td_u16 height = OT_MACRO_IVE_D1_HEIGHT;
|
||||
td_s32 ret;
|
||||
|
||||
(td_void)memset_s(&g_canny_info, sizeof(g_canny_info), 0, sizeof(g_canny_info));
|
||||
|
||||
ret = libapi_common_ive_check_mpi_init();
|
||||
macro_svp_check_exps_return_void(ret != TD_TRUE, ENUM_SVP_ERR_LEVEL_ERROR, "ive_check_mpi_init failed!\n");
|
||||
|
||||
ret = _ive_canny_init(&g_canny_info, width, height, canny_complete);
|
||||
macro_svp_check_exps_goto(ret != TD_SUCCESS, canny_fail, ENUM_SVP_ERR_LEVEL_ERROR,
|
||||
"Error(%#x),_ive_canny_init failed!\n", ret);
|
||||
|
||||
if (canny_complete == '0') {
|
||||
ret = _ive_part_canny(&g_canny_info);
|
||||
} else {
|
||||
ret = _ive_complete_canny(&g_canny_info);
|
||||
}
|
||||
|
||||
if (g_stop_signal == TD_TRUE) {
|
||||
_ive_canny_stop();
|
||||
return;
|
||||
}
|
||||
|
||||
if (ret == TD_SUCCESS) {
|
||||
macro_svp_trace_info("Process success!\n");
|
||||
}
|
||||
|
||||
g_stop_signal = TD_TRUE;
|
||||
_ive_canny_uninit(&g_canny_info);
|
||||
(td_void)memset_s(&g_canny_info, sizeof(g_canny_info), 0, sizeof(g_canny_info));
|
||||
|
||||
canny_fail:
|
||||
g_stop_signal = TD_TRUE;
|
||||
libapi_common_ive_mpi_exit();
|
||||
}
|
||||
|
||||
/*
|
||||
* function :Canny demo signal handle
|
||||
*/
|
||||
td_void libapi_ive_canny_handle_sig(td_void)
|
||||
{
|
||||
g_stop_signal = TD_TRUE;
|
||||
}
|
||||
|
||||
// 初始化 canny_info
|
||||
static td_s32 _ive_canny_init_self_define(ot_struct_ive_canny_info *canny_info, td_u32 width,
|
||||
td_u32 height, td_u32 type, td_char canny_complete)
|
||||
{
|
||||
td_s32 ret;
|
||||
td_u32 size;
|
||||
td_char path[PATH_MAX] = {0};
|
||||
td_char tmp_file[PATH_MAX] = {0};
|
||||
td_s8 mask[OT_IVE_MASK_NUM] = { 0, 0, 0, 0, 0, 0, -1, 0, 1, 0, 0, -2, 0, 2, 0, 0, -1, 0, 1, 0, 0, 0, 0, 0, 0 };
|
||||
|
||||
(td_void)memset_s(canny_info, sizeof(ot_struct_ive_canny_info), 0, sizeof(ot_struct_ive_canny_info));
|
||||
ret = memcpy_s(canny_info->canny_hys_edge_ctrl.mask, OT_IVE_MASK_NUM, mask, OT_IVE_MASK_NUM);
|
||||
macro_svp_check_exps_return(ret != EOK, ret, ENUM_SVP_ERR_LEVEL_ERROR, "memcpy_s mask failed!\n");
|
||||
ret = memcpy_s(canny_info->mag_and_ang_ctrl.mask, OT_IVE_MASK_NUM, mask, OT_IVE_MASK_NUM);
|
||||
macro_svp_check_exps_return(ret != EOK, ret, ENUM_SVP_ERR_LEVEL_ERROR, "memcpy_s mask failed!\n");
|
||||
|
||||
_ive_canny_ctrl_init(canny_info);
|
||||
canny_info->width = width;
|
||||
canny_info->height = height;
|
||||
canny_info->type = type;
|
||||
|
||||
ret = libapi_common_ive_create_image(&canny_info->src, type, width, height);
|
||||
macro_svp_check_exps_goto(ret != TD_SUCCESS, fail, ENUM_SVP_ERR_LEVEL_ERROR, "Error,create src img failed!\n");
|
||||
|
||||
|
||||
ret = libapi_common_ive_create_image(&canny_info->mag, OT_SVP_IMG_TYPE_U16C1, width, height);
|
||||
macro_svp_check_exps_goto(ret != TD_SUCCESS, fail, ENUM_SVP_ERR_LEVEL_ERROR, "Error,create mag img failed!\n");
|
||||
|
||||
ret = libapi_common_ive_create_image(&canny_info->edge, OT_SVP_IMG_TYPE_U8C1, width, height);
|
||||
macro_svp_check_exps_goto(ret != TD_SUCCESS, fail, ENUM_SVP_ERR_LEVEL_ERROR, "Error,create edge img failed!\n");
|
||||
|
||||
size = canny_info->src.stride[0] * canny_info->src.height * sizeof(ot_svp_point_u16) +
|
||||
sizeof(ot_ive_canny_stack_size);
|
||||
ret = libapi_common_ive_create_mem_info(&canny_info->stack, size);
|
||||
macro_svp_check_exps_goto(ret != TD_SUCCESS, fail, ENUM_SVP_ERR_LEVEL_ERROR,
|
||||
"Error,create stack mem_info failed!\n");
|
||||
|
||||
size = canny_info->src.stride[0] * canny_info->src.height * OT_MACRO_IVE_CANNY_EDGE_NUM;
|
||||
ret = libapi_common_ive_create_mem_info(&canny_info->canny_hys_edge_ctrl.mem, size);
|
||||
macro_svp_check_exps_goto(ret != TD_SUCCESS, fail, ENUM_SVP_ERR_LEVEL_ERROR,
|
||||
"Error,create canny_hys_edge_ctrl.mem failed!\n");
|
||||
|
||||
return TD_SUCCESS;
|
||||
fail:
|
||||
_ive_canny_uninit(canny_info);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* function : show part canny demo
|
||||
*/
|
||||
static td_s32 _ive_part_canny_self_define(ot_struct_ive_canny_info *canny_info)
|
||||
{
|
||||
td_s32 ret, i;
|
||||
td_bool is_instant = TD_FALSE;
|
||||
td_bool is_block = TD_TRUE;
|
||||
td_bool is_finish = TD_FALSE;
|
||||
ot_ive_handle handle;
|
||||
|
||||
for (i = 0; (i < 1) && (g_stop_signal == TD_FALSE); i++) {
|
||||
ret = libapi_common_ive_read_os_mem(&canny_info->src, canny_info->p_os_src_mem,
|
||||
canny_info->width, canny_info->height, canny_info->type);
|
||||
macro_svp_check_exps_return(ret != TD_SUCCESS, ret, ENUM_SVP_ERR_LEVEL_ERROR,
|
||||
"Error(%#x),Read src os mem failed!\n", ret);
|
||||
|
||||
ret = ss_mpi_ive_mag_and_ang(&handle, &canny_info->src, &canny_info->mag, TD_NULL,
|
||||
&canny_info->mag_and_ang_ctrl, is_instant);
|
||||
macro_svp_check_exps_return(ret != TD_SUCCESS, ret, ENUM_SVP_ERR_LEVEL_ERROR,
|
||||
"Error(%#x),ss_mpi_ive_mag_and_ang failed!\n", ret);
|
||||
|
||||
is_instant = TD_TRUE;
|
||||
ret = ss_mpi_ive_threshold_u16(&handle, &canny_info->mag, &canny_info->edge,
|
||||
&canny_info->thr_u16_ctrl, is_instant);
|
||||
macro_svp_check_exps_return(ret != TD_SUCCESS, ret, ENUM_SVP_ERR_LEVEL_ERROR,
|
||||
"Error(%#x),ss_mpi_ive_threshold_u16 failed!\n", ret);
|
||||
|
||||
ret = ss_mpi_ive_query(handle, &is_finish, is_block);
|
||||
while (ret == OT_ERR_IVE_QUERY_TIMEOUT) {
|
||||
usleep(OT_MACRO_IVE_CANNY_QUERY_SLEEP);
|
||||
ret = ss_mpi_ive_query(handle, &is_finish, is_block);
|
||||
}
|
||||
macro_svp_check_exps_return(ret != TD_SUCCESS, ret, ENUM_SVP_ERR_LEVEL_ERROR,
|
||||
"Error(%#x),ss_mpi_ive_query failed!\n", ret);
|
||||
|
||||
ret = libapi_common_ive_write_os_mem(&canny_info->edge, canny_info->p_os_edge_mem);
|
||||
macro_svp_check_exps_return(ret != TD_SUCCESS, ret, ENUM_SVP_ERR_LEVEL_ERROR,
|
||||
"Error(%#x),Write edge mem os failed!\n", ret);
|
||||
}
|
||||
return TD_SUCCESS;
|
||||
}
|
||||
|
||||
static td_s32 _ive_complete_canny_self_define(ot_struct_ive_canny_info *canny_info)
|
||||
{
|
||||
td_s32 ret, i;
|
||||
td_bool is_instant = TD_TRUE;
|
||||
td_bool is_block = TD_TRUE;
|
||||
td_bool is_finish = TD_FALSE;
|
||||
ot_ive_handle handle;
|
||||
|
||||
for (i = 0; (i < 1) && (g_stop_signal == TD_FALSE); i++) {
|
||||
ret = libapi_common_ive_read_os_mem(&canny_info->src, canny_info->p_os_src_mem,
|
||||
canny_info->width, canny_info->height, canny_info->type);
|
||||
macro_svp_check_exps_return(ret != TD_SUCCESS, ret, ENUM_SVP_ERR_LEVEL_ERROR,
|
||||
"Error(%#x),Read src os mem failed!\n", ret);
|
||||
|
||||
ret = ss_mpi_ive_canny_hys_edge(&handle, &canny_info->src, &canny_info->edge, &canny_info->stack,
|
||||
&canny_info->canny_hys_edge_ctrl, is_instant);
|
||||
macro_svp_check_exps_return(ret != TD_SUCCESS, ret, ENUM_SVP_ERR_LEVEL_ERROR,
|
||||
"Error(%#x),ss_mpi_ive_canny_hys_edge failed!\n", ret);
|
||||
|
||||
ret = ss_mpi_ive_query(handle, &is_finish, is_block);
|
||||
while (ret == OT_ERR_IVE_QUERY_TIMEOUT) {
|
||||
usleep(OT_MACRO_IVE_CANNY_QUERY_SLEEP);
|
||||
ret = ss_mpi_ive_query(handle, &is_finish, is_block);
|
||||
}
|
||||
macro_svp_check_exps_return(ret != TD_SUCCESS, ret, ENUM_SVP_ERR_LEVEL_ERROR,
|
||||
"Error(%#x),ss_mpi_ive_query failed!\n", ret);
|
||||
|
||||
ret = ss_mpi_ive_canny_edge(&canny_info->edge, &canny_info->stack);
|
||||
macro_svp_check_exps_return(ret != TD_SUCCESS, ret, ENUM_SVP_ERR_LEVEL_ERROR,
|
||||
"Error(%#x),ss_mpi_ive_canny_edge failed!\n", ret);
|
||||
|
||||
ret = libapi_common_ive_write_os_mem(&canny_info->edge, canny_info->p_os_edge_mem);
|
||||
macro_svp_check_exps_return(ret != TD_SUCCESS, ret, ENUM_SVP_ERR_LEVEL_ERROR,
|
||||
"Error(%#x),Write edge mem os failed!\n", ret);
|
||||
}
|
||||
return TD_SUCCESS;
|
||||
}
|
||||
|
||||
static td_void _ive_canny_stop_self_define(ot_struct_ive_canny_info *canny_info)
|
||||
{
|
||||
_ive_canny_uninit(&canny_info);
|
||||
(td_void)memset_s(&canny_info, sizeof(canny_info), 0, sizeof(canny_info));
|
||||
// libapi_common_ive_mpi_exit(); //for test
|
||||
printf("\033[0;31mprogram termination abnormally!\033[0;39m\n");
|
||||
}
|
||||
|
||||
/*
|
||||
* function :Canny api signal handle
|
||||
*/
|
||||
td_u32 libapi_ive_canny(td_void* src, td_u32 width, td_u32 height, td_u32 img_type,
|
||||
td_void* dst, td_char canny_complete)
|
||||
{
|
||||
td_s32 ret = TD_SUCCESS;
|
||||
static ot_struct_ive_canny_info canny_info;
|
||||
(td_void)memset_s(&canny_info, sizeof(canny_info), 0, sizeof(canny_info));
|
||||
|
||||
//for test
|
||||
// ret = libapi_common_ive_check_mpi_init();
|
||||
// macro_svp_check_exps_return_void(ret != TD_TRUE, ENUM_SVP_ERR_LEVEL_ERROR, "ive_check_mpi_init failed!\n");
|
||||
|
||||
ret = _ive_canny_init_self_define(&canny_info, width, height, img_type, canny_complete);
|
||||
canny_info.p_os_src_mem = src;
|
||||
canny_info.p_os_edge_mem = dst;
|
||||
|
||||
macro_svp_check_exps_goto(ret != TD_SUCCESS, canny_fail, ENUM_SVP_ERR_LEVEL_ERROR,
|
||||
"Error(%#x),_ive_canny_init failed!\n", ret);
|
||||
|
||||
if (canny_complete == '0') {
|
||||
ret = _ive_part_canny_self_define(&canny_info);
|
||||
} else {
|
||||
ret = _ive_complete_canny_self_define(&canny_info);
|
||||
}
|
||||
|
||||
if (g_stop_signal == TD_TRUE) {
|
||||
_ive_canny_stop_self_define(&canny_info);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (ret == TD_SUCCESS) {
|
||||
macro_svp_trace_info("Process success!\n");
|
||||
}
|
||||
|
||||
g_stop_signal = TD_TRUE;
|
||||
// 删除分配的物理内存
|
||||
_ive_canny_uninit(&canny_info);
|
||||
(td_void)memset_s(&canny_info, sizeof(canny_info), 0, sizeof(canny_info));
|
||||
|
||||
canny_fail:
|
||||
g_stop_signal = TD_TRUE;
|
||||
// for test
|
||||
// libapi_common_ive_mpi_exit();
|
||||
return ret;
|
||||
}
|
687
libapi/ive/libapi_ive_gmm2.c
Executable file
@ -0,0 +1,687 @@
|
||||
/*
|
||||
Copyright (c), 2001-2022, Shenshu Tech. Co., Ltd.
|
||||
*/
|
||||
#include "libapi_common_ive.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#include <signal.h>
|
||||
#include <semaphore.h>
|
||||
#include <pthread.h>
|
||||
#include <limits.h>
|
||||
|
||||
#define OT_MACRO_IVE_SRC_NUM 2
|
||||
#define OT_MACRO_IVE_GMM2_QUERY_SLEEP 100
|
||||
#define OT_MACRO_IVE_GMM2_FIRST_FRMAE_NUM 500
|
||||
#define OT_MACRO_IVE_GMM2_MAX_CCL_REGION 60
|
||||
#define OT_MACRO_IVE_GMM2_UPDATA_FACTOR_VAL1 16
|
||||
#define OT_MACRO_IVE_GMM2_UPDATA_FACTOR_VAL2 200
|
||||
#define OT_MACRO_IVE_GMM2_CHANGE_FACTOR_VAL1 20
|
||||
#define OT_MACRO_IVE_GMM2_CHANGE_FACTOR_VAL2 200
|
||||
#define OT_MACRO_IVE_GMM2_CREATE_FACTOR_VAL1 8
|
||||
#define OT_MACRO_IVE_GMM2_CREATE_FACTOR_VAL2 4
|
||||
#define OT_MACRO_IVE_GMM2_MAX_GRAD_SUM 10
|
||||
#define OT_MACRO_IVE_GMM2_RATIO_BETWEEN_GRAD_AND_FG 100
|
||||
#define OT_MACRO_IVE_16BIT_TO_8BIT_NUM 255
|
||||
#define OT_MACRO_IVE_16BIT_TO_8BIT_DEN (255 * 4)
|
||||
#define OT_MACRO_IVE_CCL_STEP 2
|
||||
#define OT_MACRO_IVE_CCL_INIT_AREA_THR 4
|
||||
#define OT_MACRO_IVE_GMM2_THRESH_LOW_THR 5
|
||||
#define OT_MACRO_IVE_GMM2_NUM_TWO 2
|
||||
#define OT_MACRO_IVE_GMM2_MODEL_NUM 3
|
||||
#define OT_MACRO_IVE_GMM2_MAX_VAR ((16 * 16)<<7)
|
||||
#define OT_MACRO_IVE_GMM2_MIN_VAR ((8 * 8)<<7)
|
||||
#define OT_MACRO_IVE_GMM2_GLB_SNS_FACTOR 8
|
||||
#define OT_MACRO_IVE_GMM2_FREQ_HTR 12000
|
||||
#define OT_MACRO_IVE_GMM2_FREQ_INIT_VAL 20000
|
||||
#define OT_MACRO_IVE_GMM2_LIFT_THR 500
|
||||
#define OT_MACRO_IVE_GMM2_NUM_THREE 3
|
||||
#define OT_MACRO_IVE_GMM2_CHANGE_FACTOR_ABS_THRESHOLD 10
|
||||
#define OT_MACRO_IVE_GMM2_FACTOR_MAX_VAL 8
|
||||
#define OT_MACRO_IVE_GMM2_NUM_TWO 2
|
||||
#define OT_MACRO_IVE_GMM2_CIF_WIDTH 352
|
||||
#define OT_MACRO_IVE_GMM2_CIF_HEIGHT 288
|
||||
#define OT_MACRO_IVE_TOTAL_FRAME 700
|
||||
|
||||
typedef struct {
|
||||
ot_svp_src_img src[OT_MACRO_IVE_SRC_NUM];
|
||||
ot_svp_dst_img fg;
|
||||
ot_svp_dst_img bg;
|
||||
ot_svp_src_img factor;
|
||||
ot_svp_dst_img match_model_info;
|
||||
ot_svp_src_img fg_mask;
|
||||
ot_svp_src_img last_image;
|
||||
ot_svp_dst_img diff_image;
|
||||
ot_svp_dst_img mag_image;
|
||||
ot_svp_dst_img cur_norm_mag;
|
||||
ot_svp_dst_img last_norm_mag;
|
||||
ot_svp_dst_mem_info model;
|
||||
ot_svp_dst_mem_info blob;
|
||||
ot_ive_gmm2_ctrl gmm2_ctrl;
|
||||
|
||||
FILE *fp_src;
|
||||
FILE *fp_fg;
|
||||
FILE *fp_bg;
|
||||
} ot_struct_ive_gmm2_info;
|
||||
|
||||
static ot_struct_ive_gmm2_info g_gmm2_info;
|
||||
static td_bool g_stop_signal = TD_FALSE;
|
||||
|
||||
/*
|
||||
* gmm2 uninit
|
||||
*/
|
||||
static td_void _ive_gmm2_uninit(ot_struct_ive_gmm2_info *gmm2)
|
||||
{
|
||||
td_u16 i;
|
||||
|
||||
macro_svp_check_exps_return_void(gmm2 == TD_NULL, ENUM_SVP_ERR_LEVEL_ERROR, "gmm2 can't be null\n");
|
||||
for (i = 0; i < OT_MACRO_IVE_SRC_NUM; i++) {
|
||||
macro_svp_mmz_free(gmm2->src[i].phys_addr[0], gmm2->src[i].virt_addr[0]);
|
||||
}
|
||||
macro_svp_mmz_free(gmm2->fg.phys_addr[0], gmm2->fg.virt_addr[0]);
|
||||
macro_svp_mmz_free(gmm2->bg.phys_addr[0], gmm2->bg.virt_addr[0]);
|
||||
macro_svp_mmz_free(gmm2->factor.phys_addr[0], gmm2->factor.virt_addr[0]);
|
||||
macro_svp_mmz_free(gmm2->match_model_info.phys_addr[0], gmm2->match_model_info.virt_addr[0]);
|
||||
macro_svp_mmz_free(gmm2->fg_mask.phys_addr[0], gmm2->fg_mask.virt_addr[0]);
|
||||
macro_svp_mmz_free(gmm2->diff_image.phys_addr[0], gmm2->diff_image.virt_addr[0]);
|
||||
macro_svp_mmz_free(gmm2->mag_image.phys_addr[0], gmm2->mag_image.virt_addr[0]);
|
||||
macro_svp_mmz_free(gmm2->cur_norm_mag.phys_addr[0], gmm2->cur_norm_mag.virt_addr[0]);
|
||||
macro_svp_mmz_free(gmm2->last_norm_mag.phys_addr[0], gmm2->last_norm_mag.virt_addr[0]);
|
||||
macro_svp_mmz_free(gmm2->model.phys_addr, gmm2->model.virt_addr);
|
||||
macro_svp_mmz_free(gmm2->blob.phys_addr, gmm2->blob.virt_addr);
|
||||
|
||||
macro_svp_close_file(gmm2->fp_src);
|
||||
macro_svp_close_file(gmm2->fp_fg);
|
||||
macro_svp_close_file(gmm2->fp_bg);
|
||||
}
|
||||
|
||||
/*
|
||||
* function: create gmm2 image memory
|
||||
*/
|
||||
static td_s32 _ive_gmm2_create_image(ot_struct_ive_gmm2_info *gmm2, ot_size pic_size)
|
||||
{
|
||||
td_s32 ret;
|
||||
td_u16 i, j;
|
||||
td_u8 *tmp_ptr = TD_NULL;
|
||||
(td_void)memset_s(gmm2, sizeof(ot_struct_ive_gmm2_info), 0, sizeof(ot_struct_ive_gmm2_info));
|
||||
|
||||
for (i = 0; i < OT_MACRO_IVE_SRC_NUM; i++) {
|
||||
ret = libapi_common_ive_create_image(&(gmm2->src[i]), OT_SVP_IMG_TYPE_U8C1, pic_size.width, pic_size.height);
|
||||
macro_svp_check_exps_return(ret != TD_SUCCESS, ret, ENUM_SVP_ERR_LEVEL_ERROR,
|
||||
"Error(%#x),Create src[%d] image failed!\n", ret, i);
|
||||
}
|
||||
|
||||
ret = libapi_common_ive_create_image(&(gmm2->fg), OT_SVP_IMG_TYPE_U8C1, pic_size.width, pic_size.height);
|
||||
macro_svp_check_exps_return(ret != TD_SUCCESS, ret, ENUM_SVP_ERR_LEVEL_ERROR,
|
||||
"Error(%#x),Create fg image failed!\n", ret);
|
||||
|
||||
ret = libapi_common_ive_create_image(&(gmm2->bg), OT_SVP_IMG_TYPE_U8C1, pic_size.width, pic_size.height);
|
||||
macro_svp_check_exps_return(ret != TD_SUCCESS, ret, ENUM_SVP_ERR_LEVEL_ERROR,
|
||||
"Error(%#x),Create bg image failed!\n", ret);
|
||||
|
||||
ret = libapi_common_ive_create_image(&(gmm2->factor), OT_SVP_IMG_TYPE_U16C1, pic_size.width, pic_size.height);
|
||||
macro_svp_check_exps_return(ret != TD_SUCCESS, ret, ENUM_SVP_ERR_LEVEL_ERROR,
|
||||
"Error(%#x),Create factor image failed!\n", ret);
|
||||
|
||||
tmp_ptr = macro_svp_convert_addr_to_ptr(td_u8, gmm2->factor.virt_addr[0]);
|
||||
for (i = 0; i < gmm2->factor.height; i++) {
|
||||
for (j = 0; j < gmm2->factor.width; j++) {
|
||||
tmp_ptr[OT_MACRO_IVE_GMM2_NUM_TWO * j] = OT_MACRO_IVE_GMM2_CREATE_FACTOR_VAL1;
|
||||
tmp_ptr[OT_MACRO_IVE_GMM2_NUM_TWO * j + 1] = OT_MACRO_IVE_GMM2_CREATE_FACTOR_VAL2;
|
||||
}
|
||||
tmp_ptr += gmm2->factor.stride[0] * sizeof(td_u16);
|
||||
}
|
||||
ret = libapi_common_ive_create_image(&(gmm2->match_model_info), OT_SVP_IMG_TYPE_U8C1,
|
||||
pic_size.width, pic_size.height);
|
||||
macro_svp_check_exps_return(ret != TD_SUCCESS, ret, ENUM_SVP_ERR_LEVEL_ERROR,
|
||||
"Error(%#x),Create match_model image failed!\n", ret);
|
||||
|
||||
ret = libapi_common_ive_create_image(&(gmm2->fg_mask), OT_SVP_IMG_TYPE_U8C1, pic_size.width, pic_size.height);
|
||||
macro_svp_check_exps_return(ret != TD_SUCCESS, ret, ENUM_SVP_ERR_LEVEL_ERROR,
|
||||
"Error(%#x),Create fg_mask image failed!\n", ret);
|
||||
|
||||
ret = libapi_common_ive_create_image(&(gmm2->diff_image), OT_SVP_IMG_TYPE_U8C1, pic_size.width, pic_size.height);
|
||||
macro_svp_check_exps_return(ret != TD_SUCCESS, ret, ENUM_SVP_ERR_LEVEL_ERROR,
|
||||
"Error(%#x),Create diff_image failed!\n", ret);
|
||||
|
||||
ret = libapi_common_ive_create_image(&(gmm2->mag_image), OT_SVP_IMG_TYPE_U16C1, pic_size.width, pic_size.height);
|
||||
macro_svp_check_exps_return(ret != TD_SUCCESS, ret, ENUM_SVP_ERR_LEVEL_ERROR,
|
||||
"Error(%#x),Create mag_image failed!\n", ret);
|
||||
|
||||
ret = libapi_common_ive_create_image(&(gmm2->cur_norm_mag), OT_SVP_IMG_TYPE_U8C1, pic_size.width, pic_size.height);
|
||||
macro_svp_check_exps_return(ret != TD_SUCCESS, ret, ENUM_SVP_ERR_LEVEL_ERROR,
|
||||
"Error(%#x),Create cur_nor_mag image failed!\n", ret);
|
||||
|
||||
ret = libapi_common_ive_create_image(&(gmm2->last_norm_mag), OT_SVP_IMG_TYPE_U8C1, pic_size.width, pic_size.height);
|
||||
macro_svp_check_exps_return(ret != TD_SUCCESS, ret, ENUM_SVP_ERR_LEVEL_ERROR,
|
||||
"Error(%#x),Create last_nor_mag image failed!\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* set gmm2 ctrl info
|
||||
*/
|
||||
static td_void _ive_gmm2_set_ctrl_info(ot_struct_ive_gmm2_info *gmm2)
|
||||
{
|
||||
gmm2->gmm2_ctrl.var_rate = 1;
|
||||
gmm2->gmm2_ctrl.model_num = OT_MACRO_IVE_GMM2_MODEL_NUM;
|
||||
gmm2->gmm2_ctrl.max_var = OT_MACRO_IVE_GMM2_MAX_VAR;
|
||||
gmm2->gmm2_ctrl.min_var = OT_MACRO_IVE_GMM2_MIN_VAR;
|
||||
gmm2->gmm2_ctrl.global_sns_factor = OT_MACRO_IVE_GMM2_GLB_SNS_FACTOR;
|
||||
gmm2->gmm2_ctrl.sns_factor_mode = OT_IVE_GMM2_SNS_FACTOR_MODE_PIXEL;
|
||||
gmm2->gmm2_ctrl.freq_threshold = OT_MACRO_IVE_GMM2_FREQ_HTR;
|
||||
gmm2->gmm2_ctrl.freq_init_val = OT_MACRO_IVE_GMM2_FREQ_INIT_VAL;
|
||||
gmm2->gmm2_ctrl.freq_add_factor = 0xEF;
|
||||
gmm2->gmm2_ctrl.freq_reduce_factor = 0xFF00;
|
||||
gmm2->gmm2_ctrl.life_threshold = OT_MACRO_IVE_GMM2_LIFT_THR;
|
||||
gmm2->gmm2_ctrl.life_update_factor_mode = OT_IVE_GMM2_LIFE_UPDATE_FACTOR_MODE_GLOBAL;
|
||||
}
|
||||
/*
|
||||
* function: init gmm2 data
|
||||
*/
|
||||
static td_s32 _ive_gmm2_init(ot_struct_ive_gmm2_info *gmm2, ot_size pic_size)
|
||||
{
|
||||
td_s32 ret = OT_ERR_IVE_NULL_PTR;
|
||||
td_u32 size;
|
||||
td_char path[PATH_MAX] = {0};
|
||||
const td_char *src_file = "./gmm2_352x288_sp400_frm1000.yuv";
|
||||
|
||||
macro_svp_check_exps_return(gmm2 == TD_NULL, ret, ENUM_SVP_ERR_LEVEL_ERROR, "gmm2 can't be null\n");
|
||||
macro_svp_check_exps_return((strlen(src_file) > PATH_MAX) || (realpath(src_file, path) == TD_NULL),
|
||||
OT_ERR_IVE_ILLEGAL_PARAM, ENUM_SVP_ERR_LEVEL_ERROR, "invalid file!\n");
|
||||
|
||||
/* create img memory */
|
||||
ret = _ive_gmm2_create_image(gmm2, pic_size);
|
||||
macro_svp_check_exps_goto(ret != TD_SUCCESS, fail, ENUM_SVP_ERR_LEVEL_ERROR,
|
||||
"_ive_gmm2_create_image failed\n");
|
||||
|
||||
/* set gmm2 ctrl info */
|
||||
_ive_gmm2_set_ctrl_info(gmm2);
|
||||
|
||||
/* create gmm2 model and blob mem_info */
|
||||
size = gmm2->gmm2_ctrl.model_num * sizeof(td_u64) * gmm2->src[0].width * gmm2->src[0].height;
|
||||
ret = libapi_common_ive_create_mem_info(&gmm2->model, size);
|
||||
macro_svp_check_exps_goto(ret != TD_SUCCESS, fail, ENUM_SVP_ERR_LEVEL_ERROR,
|
||||
"Error(%#x),Create model mem info failed!\n", ret);
|
||||
|
||||
(td_void)memset_s(macro_svp_convert_addr_to_ptr(td_void, gmm2->model.virt_addr),
|
||||
gmm2->model.size, 0, gmm2->model.size);
|
||||
size = sizeof(ot_ive_ccblob);
|
||||
ret = libapi_common_ive_create_mem_info(&gmm2->blob, size);
|
||||
macro_svp_check_exps_goto(ret != TD_SUCCESS, fail, ENUM_SVP_ERR_LEVEL_ERROR,
|
||||
"Error(%#x),Create blob mem info failed!\n", ret);
|
||||
|
||||
/* open src file */
|
||||
ret = TD_FAILURE;
|
||||
gmm2->fp_src = fopen(path, "rb");
|
||||
macro_svp_check_exps_goto(gmm2->fp_src == TD_NULL, fail, ENUM_SVP_ERR_LEVEL_ERROR, "Open file failed!\n");
|
||||
|
||||
/* open fg file */
|
||||
macro_svp_check_exps_goto(realpath("./", path) == TD_NULL, fail,
|
||||
ENUM_SVP_ERR_LEVEL_ERROR, "invalid path\n");
|
||||
ret = strcat_s(path, PATH_MAX, "/fg_352x288_sp400.yuv");
|
||||
macro_svp_check_exps_goto(ret != EOK, fail, ENUM_SVP_ERR_LEVEL_ERROR, "strcat_s failed!\n");
|
||||
ret = TD_FAILURE;
|
||||
gmm2->fp_fg = fopen(path, "wb");
|
||||
macro_svp_check_exps_goto(gmm2->fp_fg == TD_NULL, fail, ENUM_SVP_ERR_LEVEL_ERROR, "Open file failed!\n");
|
||||
|
||||
/* openc bg file */
|
||||
macro_svp_check_exps_goto(realpath("./", path) == TD_NULL, fail,
|
||||
ENUM_SVP_ERR_LEVEL_ERROR, "invalid path\n");
|
||||
ret = strcat_s(path, PATH_MAX, "/bg_352x288_sp400.yuv");
|
||||
macro_svp_check_exps_goto(ret != EOK, fail, ENUM_SVP_ERR_LEVEL_ERROR, "strcat_s failed!\n");
|
||||
ret = TD_FAILURE;
|
||||
gmm2->fp_bg = fopen(path, "wb");
|
||||
macro_svp_check_exps_goto(gmm2->fp_bg == TD_NULL, fail, ENUM_SVP_ERR_LEVEL_ERROR,
|
||||
"Error,Open file %s failed!\n", path);
|
||||
return TD_SUCCESS;
|
||||
fail:
|
||||
_ive_gmm2_uninit(gmm2);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static td_s32 _ive_gen_fg_mask(ot_svp_src_img *fg, ot_svp_dst_img *mask)
|
||||
{
|
||||
td_s32 ret;
|
||||
ot_ive_handle handle;
|
||||
ot_ive_threshold_ctrl ctrl;
|
||||
|
||||
ctrl.mode = OT_IVE_THRESHOLD_MODE_BINARY;
|
||||
ctrl.min_val = 0;
|
||||
ctrl.max_val = 1;
|
||||
ctrl.low_threshold = OT_MACRO_IVE_GMM2_THRESH_LOW_THR;
|
||||
ret = ss_mpi_ive_threshold(&handle, fg, mask, &ctrl, TD_FALSE);
|
||||
macro_svp_check_exps_return(ret != TD_SUCCESS, ret, ENUM_SVP_ERR_LEVEL_ERROR,
|
||||
"Error(%#x),ss_mpi_ive_thresh failed!\n", ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
/*
|
||||
* Reduce the factor gradually to the default value
|
||||
*/
|
||||
static td_void _ive_reduce_factor(ot_svp_img *factor)
|
||||
{
|
||||
td_u16 i, j;
|
||||
td_u8 *tmp_ptr = TD_NULL;
|
||||
|
||||
tmp_ptr = macro_svp_convert_addr_to_ptr(td_u8, factor->virt_addr[0]);
|
||||
for (i = 0; i < factor->height; i++) {
|
||||
for (j = 0; j < factor->width; j++) {
|
||||
tmp_ptr[j << 1] = ot_macro_ive_max(OT_MACRO_IVE_GMM2_FACTOR_MAX_VAL, tmp_ptr[i << 1] - 1);
|
||||
tmp_ptr[(i << 1) + 1] = ot_macro_ive_max(OT_MACRO_IVE_GMM2_FACTOR_MAX_VAL, tmp_ptr[(i << 1) + 1] -
|
||||
OT_MACRO_IVE_GMM2_NUM_TWO);
|
||||
}
|
||||
tmp_ptr += factor->stride[0] * sizeof(td_u16);
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Change factor by difference frame
|
||||
*/
|
||||
static td_bool _ive_change_factor_by_diff_frame(ot_svp_src_img *src_img,
|
||||
ot_svp_src_img *last_img, ot_svp_dst_img *diff_img, ot_svp_dst_img *factor)
|
||||
{
|
||||
td_s32 ret;
|
||||
ot_ive_handle handle;
|
||||
td_bool is_finish = TD_FALSE;
|
||||
td_bool is_block = TD_TRUE;
|
||||
td_u16 i, j;
|
||||
const td_s32 abs_thr = OT_MACRO_IVE_GMM2_CHANGE_FACTOR_ABS_THRESHOLD;
|
||||
td_u32 point_sum = 0;
|
||||
ot_ive_sub_ctrl sub_ctrl;
|
||||
td_u8 *tmp_ptr = TD_NULL;
|
||||
td_u8 *factor_ptr = TD_NULL;
|
||||
|
||||
sub_ctrl.mode = OT_IVE_SUB_MODE_ABS;
|
||||
ret = ss_mpi_ive_sub(&handle, src_img, last_img, diff_img, &sub_ctrl, TD_TRUE);
|
||||
macro_svp_check_exps_return(ret != TD_SUCCESS, TD_FALSE, ENUM_SVP_ERR_LEVEL_ERROR,
|
||||
"Error(%#x),ss_mpi_ive_sub failed!\n", ret);
|
||||
|
||||
/* Wait task finish */
|
||||
ret = ss_mpi_ive_query(handle, &is_finish, is_block);
|
||||
while (ret == OT_ERR_IVE_QUERY_TIMEOUT) {
|
||||
usleep(OT_MACRO_IVE_GMM2_QUERY_SLEEP);
|
||||
ret = ss_mpi_ive_query(handle, &is_finish, is_block);
|
||||
}
|
||||
macro_svp_check_exps_return(ret != TD_SUCCESS, TD_FALSE, ENUM_SVP_ERR_LEVEL_ERROR,
|
||||
"Error(%#x),ss_mpi_ive_query failed!\n", ret);
|
||||
|
||||
tmp_ptr = macro_svp_convert_addr_to_ptr(td_u8, diff_img->virt_addr[0]);
|
||||
for (i = 0; i < src_img->height; i++) {
|
||||
for (j = 0; j < src_img->width; j++) {
|
||||
point_sum += (tmp_ptr[j] > abs_thr);
|
||||
}
|
||||
tmp_ptr += diff_img->stride[0];
|
||||
}
|
||||
if ((point_sum * OT_MACRO_IVE_GMM2_NUM_THREE) <= (src_img->width * src_img->height * OT_MACRO_IVE_GMM2_NUM_TWO)) {
|
||||
return TD_FALSE;
|
||||
}
|
||||
|
||||
tmp_ptr = macro_svp_convert_addr_to_ptr(td_u8, diff_img->virt_addr[0]);
|
||||
factor_ptr = macro_svp_convert_addr_to_ptr(td_u8, factor->virt_addr[0]);
|
||||
for (i = 0; i < src_img->height; i++) {
|
||||
for (j = 0; j < src_img->width; j++) {
|
||||
if (tmp_ptr[j] > abs_thr) {
|
||||
factor_ptr[j << 1] = OT_MACRO_IVE_GMM2_CHANGE_FACTOR_VAL1;
|
||||
factor_ptr[(j << 1) + 1] = OT_MACRO_IVE_GMM2_CHANGE_FACTOR_VAL2;
|
||||
}
|
||||
}
|
||||
tmp_ptr += diff_img->stride[0];
|
||||
factor_ptr += factor->stride[0] * sizeof(td_u16);
|
||||
}
|
||||
return TD_TRUE;
|
||||
}
|
||||
|
||||
static td_s32 _ive_set_ctrl_info(ot_ive_ccl_ctrl *ccl_ctrl, ot_ive_mag_and_ang_ctrl *mag_and_ang_ctrl,
|
||||
ot_ive_16bit_to_8bit_ctrl *ctrl_16to8bit, ot_ive_sub_ctrl *sub_ctrl)
|
||||
{
|
||||
td_s32 ret;
|
||||
td_s8 mask[OT_IVE_MASK_NUM] = { 0, 0, 0, 0, 0, 0, -1, 0, 1, 0, 0, -2, 0, 2, 0, 0, -1, 0, 1, 0, 0, 0, 0, 0, 0 };
|
||||
/* set ccl ctrl info */
|
||||
ccl_ctrl->mode = OT_IVE_CCL_MODE_8C;
|
||||
ccl_ctrl->step = OT_MACRO_IVE_CCL_STEP;
|
||||
ccl_ctrl->init_area_threshold = OT_MACRO_IVE_CCL_INIT_AREA_THR;
|
||||
|
||||
/* set mag_and_ang ctrl info */
|
||||
ret = memcpy_s(mag_and_ang_ctrl->mask, OT_IVE_MASK_NUM, mask, OT_IVE_MASK_NUM);
|
||||
macro_svp_check_exps_return(ret != EOK, OT_ERR_IVE_ILLEGAL_PARAM, ENUM_SVP_ERR_LEVEL_ERROR,
|
||||
"memcpy_s mask failed!\n");
|
||||
mag_and_ang_ctrl->threshold = 0;
|
||||
mag_and_ang_ctrl->out_ctrl = OT_IVE_MAG_AND_ANG_OUT_CTRL_MAG;
|
||||
|
||||
/* set 16bit_to_8bit ctrl info */
|
||||
ctrl_16to8bit->bias = 0;
|
||||
ctrl_16to8bit->mode = OT_IVE_16BIT_TO_8BIT_MODE_U16_TO_U8;
|
||||
ctrl_16to8bit->num = OT_MACRO_IVE_16BIT_TO_8BIT_NUM;
|
||||
ctrl_16to8bit->denominator = OT_MACRO_IVE_16BIT_TO_8BIT_DEN;
|
||||
|
||||
/* set sub ctrl info */
|
||||
sub_ctrl->mode = OT_IVE_SUB_MODE_ABS;
|
||||
return TD_SUCCESS;
|
||||
}
|
||||
|
||||
static td_s32 _ive_calc_grad_diff_bewteen_img(ot_struct_ive_gmm2_info *gmm2, td_s32 cur_idx)
|
||||
{
|
||||
td_s32 ret;
|
||||
td_bool is_finish = TD_FALSE;
|
||||
td_bool is_block = TD_TRUE;
|
||||
ot_ive_handle handle;
|
||||
|
||||
ot_ive_ccl_ctrl ccl_ctrl;
|
||||
ot_ive_ccblob *ccl_blob = TD_NULL;
|
||||
ot_ive_mag_and_ang_ctrl mag_and_ang_ctrl;
|
||||
ot_ive_16bit_to_8bit_ctrl ctrl_16to8bit;
|
||||
ot_ive_sub_ctrl sub_ctrl;
|
||||
|
||||
ret = _ive_set_ctrl_info(&ccl_ctrl, &mag_and_ang_ctrl, &ctrl_16to8bit, &sub_ctrl);
|
||||
macro_svp_check_exps_return(ret != TD_SUCCESS, ret, ENUM_SVP_ERR_LEVEL_ERROR, "ive_set_ctrl_info failed!\n");
|
||||
|
||||
ret = ss_mpi_ive_ccl(&handle, &gmm2->fg_mask, &gmm2->blob, &ccl_ctrl, TD_TRUE);
|
||||
macro_svp_check_failed_err_level_return(ret, ret, "Error(%#x),ss_mpi_ive_ccl failed!\n", ret);
|
||||
|
||||
/* Wait task finish */
|
||||
ret = ss_mpi_ive_query(handle, &is_finish, is_block);
|
||||
while (ret == OT_ERR_IVE_QUERY_TIMEOUT) {
|
||||
usleep(OT_MACRO_IVE_GMM2_QUERY_SLEEP);
|
||||
ret = ss_mpi_ive_query(handle, &is_finish, is_block);
|
||||
}
|
||||
macro_svp_check_failed_err_level_return(ret, ret, "Error(%#x),ss_mpi_ive_query failed!\n", ret);
|
||||
|
||||
ccl_blob = macro_svp_convert_addr_to_ptr(ot_ive_ccblob, gmm2->blob.virt_addr);
|
||||
if (ccl_blob->info.bits.rgn_num > 0) {
|
||||
/* Calc the gradient difference of the current image and the last image */
|
||||
ret = ss_mpi_ive_mag_and_ang(&handle, &gmm2->src[cur_idx], &gmm2->mag_image,
|
||||
TD_NULL, &mag_and_ang_ctrl, TD_FALSE);
|
||||
macro_svp_check_failed_err_level_return(ret, ret, "Error(%#x),ss_mpi_ive_mag_and_ang failed!\n", ret);
|
||||
|
||||
ret = ss_mpi_ive_16bit_to_8bit(&handle, &gmm2->mag_image, &gmm2->cur_norm_mag, &ctrl_16to8bit, TD_FALSE);
|
||||
macro_svp_check_failed_err_level_return(ret, ret, "Error(%#x),ss_mpi_ive_16bit_to_8bit failed!\n", ret);
|
||||
|
||||
ret = ss_mpi_ive_mag_and_ang(&handle, &gmm2->src[1 - cur_idx], &gmm2->mag_image, TD_NULL,
|
||||
&mag_and_ang_ctrl, TD_FALSE);
|
||||
macro_svp_check_failed_err_level_return(ret, ret, "Error(%#x),ss_mpi_ive_mag_and_ang failed!\n", ret);
|
||||
|
||||
ret = ss_mpi_ive_16bit_to_8bit(&handle, &gmm2->mag_image, &gmm2->last_norm_mag, &ctrl_16to8bit, TD_FALSE);
|
||||
macro_svp_check_failed_err_level_return(ret, ret, "Error(%#x),ss_mpi_ive_16bit_to_8bit failed!\n", ret);
|
||||
|
||||
ret = ss_mpi_ive_sub(&handle, &gmm2->cur_norm_mag, &gmm2->last_norm_mag, &gmm2->diff_image, &sub_ctrl, TD_TRUE);
|
||||
macro_svp_check_failed_err_level_return(ret, ret, "Error(%#x),ss_mpi_ive_sub failed!\n", ret);
|
||||
|
||||
ret = ss_mpi_ive_query(handle, &is_finish, is_block);
|
||||
while (ret == OT_ERR_IVE_QUERY_TIMEOUT) {
|
||||
usleep(OT_MACRO_IVE_GMM2_QUERY_SLEEP);
|
||||
ret = ss_mpi_ive_query(handle, &is_finish, is_block);
|
||||
}
|
||||
macro_svp_check_failed_err_level_return(ret, ret, "Error(%#x),ss_mpi_ive_query failed!\n", ret);
|
||||
}
|
||||
return TD_SUCCESS;
|
||||
}
|
||||
|
||||
static td_void _ive_get_grad_and_fg_sum(ot_svp_src_img *fg_mask, ot_svp_src_img *diff_img,
|
||||
ot_svp_rect_u16 rect, td_s32 *fg_sum, td_s32 *grad_sum)
|
||||
{
|
||||
td_u8 *fg_cur_ptr = TD_NULL;
|
||||
td_u8 *grad_diff_ptr = TD_NULL;
|
||||
td_u16 top, left, right, bottom;
|
||||
td_u16 i, j;
|
||||
top = rect.x;
|
||||
left = rect.y;
|
||||
right = rect.width;
|
||||
bottom = rect.height;
|
||||
*fg_sum = 0;
|
||||
*grad_sum = 0;
|
||||
|
||||
fg_cur_ptr = (macro_svp_convert_addr_to_ptr(td_u8, fg_mask->virt_addr[0])) + top * fg_mask->stride[0];
|
||||
grad_diff_ptr = (macro_svp_convert_addr_to_ptr(td_u8, diff_img->virt_addr[0])) + top * diff_img->stride[0];
|
||||
for (i = top; i < bottom; i++) {
|
||||
for (j = left; j < right; j++) {
|
||||
if (fg_cur_ptr[j] != 0) {
|
||||
(*fg_sum)++;
|
||||
*grad_sum = grad_diff_ptr[j] ? (*grad_sum) + 1 : (*grad_sum) + 0;
|
||||
}
|
||||
}
|
||||
|
||||
fg_cur_ptr += fg_mask->stride[0];
|
||||
grad_diff_ptr += diff_img->stride[0];
|
||||
}
|
||||
}
|
||||
|
||||
static td_void _ive_update_mask_and_factor(ot_svp_rect_u16 rect, td_s32 fg_sum, td_s32 grad_sum,
|
||||
ot_svp_src_img *factor, ot_svp_src_img *mask)
|
||||
{
|
||||
td_u8 *fg_cur_ptr = TD_NULL;
|
||||
td_u8 *factor_ptr = TD_NULL;
|
||||
td_u16 top, left, right, bottom;
|
||||
td_u16 i, j;
|
||||
top = rect.x;
|
||||
left = rect.y;
|
||||
right = rect.width;
|
||||
bottom = rect.height;
|
||||
|
||||
if ((grad_sum >= OT_MACRO_IVE_GMM2_MAX_GRAD_SUM) &&
|
||||
(grad_sum * OT_MACRO_IVE_GMM2_RATIO_BETWEEN_GRAD_AND_FG >= fg_sum)) {
|
||||
return;
|
||||
}
|
||||
|
||||
factor_ptr = (macro_svp_convert_addr_to_ptr(td_u8, factor->virt_addr[0])) +
|
||||
sizeof(td_u16) * top * factor->stride[0];
|
||||
fg_cur_ptr = (macro_svp_convert_addr_to_ptr(td_u8, mask->virt_addr[0])) +
|
||||
top * mask->stride[0];
|
||||
for (i = top; i < bottom; i++) {
|
||||
for (j = left; j < right; j++) {
|
||||
if (fg_cur_ptr[j] != 0) {
|
||||
factor_ptr[j << 1] = OT_MACRO_IVE_GMM2_UPDATA_FACTOR_VAL1;
|
||||
factor_ptr[(j << 1) + 1] = OT_MACRO_IVE_GMM2_UPDATA_FACTOR_VAL2;
|
||||
}
|
||||
}
|
||||
fg_cur_ptr += mask->stride[0];
|
||||
factor_ptr += factor->stride[0] * sizeof(td_u16);
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Change factor by gradient
|
||||
*/
|
||||
static td_void _ive_change_factror_by_grad(ot_struct_ive_gmm2_info *gmm2, td_s32 cur_idx)
|
||||
{
|
||||
td_s32 ret;
|
||||
td_u16 k;
|
||||
td_s32 fg_sum, grad_sum;
|
||||
ot_ive_ccblob *ccl_blob = TD_NULL;
|
||||
ot_svp_rect_u16 rect;
|
||||
ret = _ive_calc_grad_diff_bewteen_img(gmm2, cur_idx);
|
||||
macro_svp_check_exps_return_void(ret != TD_SUCCESS, ENUM_SVP_ERR_LEVEL_ERROR,
|
||||
"_ive_calc_grad_diff_bewteen_cur_and_last_img failed\n");
|
||||
|
||||
ccl_blob = macro_svp_convert_addr_to_ptr(ot_ive_ccblob, gmm2->blob.virt_addr);
|
||||
|
||||
/* for each blob, analyze the gradient change */
|
||||
for (k = 0; k < OT_IVE_MAX_RGN_NUM; k++) {
|
||||
if (ccl_blob->rgn[k].area == 0) {
|
||||
continue;
|
||||
}
|
||||
rect.x = ccl_blob->rgn[k].top;
|
||||
rect.y = ccl_blob->rgn[k].left;
|
||||
rect.width = ccl_blob->rgn[k].right;
|
||||
rect.height = ccl_blob->rgn[k].bottom;
|
||||
if (((ccl_blob->rgn[k].right - ccl_blob->rgn[k].left) *
|
||||
(ccl_blob->rgn[k].bottom - ccl_blob->rgn[k].top)) < OT_MACRO_IVE_GMM2_MAX_CCL_REGION) {
|
||||
continue;
|
||||
}
|
||||
_ive_get_grad_and_fg_sum(&gmm2->fg_mask, &gmm2->diff_image, rect, &fg_sum, &grad_sum);
|
||||
|
||||
_ive_update_mask_and_factor(rect, fg_sum, grad_sum, &gmm2->factor, &gmm2->fg_mask);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Adjustment factor
|
||||
*/
|
||||
static td_void _ive_adjust_factor(ot_struct_ive_gmm2_info *gmm2, td_s32 cur_idx)
|
||||
{
|
||||
td_bool is_changed;
|
||||
/* First, reduce the factor gradually to the default value */
|
||||
_ive_reduce_factor(&gmm2->factor);
|
||||
|
||||
/*
|
||||
* Second, analyze the frame difference
|
||||
* When the number of changed pixels is more than the threshold, there maybe a light switch.
|
||||
* And then, we should set a big factor to adapt to it quickly.
|
||||
*/
|
||||
is_changed = _ive_change_factor_by_diff_frame(&gmm2->src[cur_idx], &gmm2->src[1 - cur_idx],
|
||||
&gmm2->diff_image, &gmm2->factor);
|
||||
if (is_changed == TD_TRUE) {
|
||||
return;
|
||||
}
|
||||
/*
|
||||
* Third, analyze the gradient for foreground blobs
|
||||
* When gradient change of a foreground blob is very small, it maybe a local illumination change,
|
||||
* a ghost, or a static object.
|
||||
* Here we try to reduce the influence by a local illumination change or a ghost only.
|
||||
*/
|
||||
(td_void)_ive_change_factror_by_grad(gmm2, cur_idx);
|
||||
}
|
||||
|
||||
static td_s32 _ive_gmm2_write_fg_bg_file(ot_struct_ive_gmm2_info *gmm2)
|
||||
{
|
||||
td_s32 ret;
|
||||
ret = libapi_common_ive_write_file(&(gmm2->fg), gmm2->fp_fg);
|
||||
macro_svp_check_exps_return(ret != TD_SUCCESS, ret, ENUM_SVP_ERR_LEVEL_ERROR,
|
||||
"Error(%#x),Write fg file failed!\n", ret);
|
||||
|
||||
ret = libapi_common_ive_write_file(&(gmm2->bg), gmm2->fp_bg);
|
||||
macro_svp_check_exps_return(ret != TD_SUCCESS, ret, ENUM_SVP_ERR_LEVEL_ERROR,
|
||||
"Error(%#x),Write bg file failed!\n", ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static td_s32 _ive_gmm2_proc(ot_struct_ive_gmm2_info *gmm2)
|
||||
{
|
||||
td_s32 ret = OT_ERR_IVE_NULL_PTR;
|
||||
ot_ive_handle handle;
|
||||
td_bool is_finish = TD_FALSE;
|
||||
td_bool is_block = TD_TRUE;
|
||||
td_bool is_instant = TD_TRUE;
|
||||
td_u32 frame_num;
|
||||
td_s32 cur_idx = 0;
|
||||
const td_u32 total_frame = OT_MACRO_IVE_TOTAL_FRAME;
|
||||
|
||||
macro_svp_check_exps_return(gmm2 == TD_NULL, ret, ENUM_SVP_ERR_LEVEL_ERROR, "gmm2 can't be null\n");
|
||||
|
||||
|
||||
for (frame_num = 1; (frame_num < total_frame) && (g_stop_signal == TD_FALSE); frame_num++) {
|
||||
macro_svp_trace_info("Proc Frame %u/%u\n", frame_num, total_frame);
|
||||
|
||||
ret = libapi_common_ive_read_file(&(gmm2->src[cur_idx]), gmm2->fp_src);
|
||||
macro_svp_check_exps_return(ret != TD_SUCCESS, ret, ENUM_SVP_ERR_LEVEL_ERROR,
|
||||
"Error(%#x),Read src file failed!\n", ret);
|
||||
|
||||
|
||||
/* To building a stable background model quickly at the begin, some parameters are set specially. */
|
||||
if (gmm2->gmm2_ctrl.model_num == 1) {
|
||||
/*
|
||||
* If the parameter u8ModelNum is set to 1, the parameter u16FreqReduFactor
|
||||
* is usually set to a small value at the first N frames. Here, N = 500.
|
||||
*/
|
||||
gmm2->gmm2_ctrl.freq_reduce_factor = (frame_num >= OT_MACRO_IVE_GMM2_FIRST_FRMAE_NUM) ? 0xFFA0 : 0xFC00;
|
||||
} else {
|
||||
/*
|
||||
* If the parameter u8ModelNum is more than 1, the global life mode should be used at the first N frames,
|
||||
* and the parameter u16GlbLifeUpdateFactor is usually set to a big value. Here, N = 500.
|
||||
*/
|
||||
if (frame_num >= OT_MACRO_IVE_GMM2_FIRST_FRMAE_NUM) {
|
||||
gmm2->gmm2_ctrl.life_update_factor_mode = OT_IVE_GMM2_LIFE_UPDATE_FACTOR_MODE_PIXEL;
|
||||
} else {
|
||||
gmm2->gmm2_ctrl.global_life_update_factor = 0xFFFF / frame_num;
|
||||
}
|
||||
}
|
||||
|
||||
ret = ss_mpi_ive_gmm2(&handle, &gmm2->src[cur_idx], &gmm2->factor, &gmm2->fg, &gmm2->bg,
|
||||
&gmm2->match_model_info, &gmm2->model, &gmm2->gmm2_ctrl, is_instant);
|
||||
macro_svp_check_exps_return(ret != TD_SUCCESS, ret, ENUM_SVP_ERR_LEVEL_ERROR,
|
||||
"Error(%#x),ss_mpi_ive_gmm2 failed!\n", ret);
|
||||
|
||||
/* factor adjustment */
|
||||
if (frame_num > 1) {
|
||||
ret = _ive_gen_fg_mask(&(gmm2->fg), &(gmm2->fg_mask));
|
||||
macro_svp_check_exps_return(ret != TD_SUCCESS, ret, ENUM_SVP_ERR_LEVEL_ERROR,
|
||||
"Error(%#x),_ive_gen_fg_mask failed!\n", ret);
|
||||
|
||||
_ive_adjust_factor(gmm2, cur_idx);
|
||||
} else {
|
||||
ret = ss_mpi_ive_query(handle, &is_finish, is_block);
|
||||
while (ret == OT_ERR_IVE_QUERY_TIMEOUT) {
|
||||
usleep(OT_MACRO_IVE_GMM2_QUERY_SLEEP);
|
||||
ret = ss_mpi_ive_query(handle, &is_finish, is_block);
|
||||
}
|
||||
macro_svp_check_exps_return(ret != TD_SUCCESS, ret, ENUM_SVP_ERR_LEVEL_ERROR,
|
||||
"Error(%#x),ss_mpi_ive_query failed!\n", ret);
|
||||
}
|
||||
// ret = _ive_gmm2_write_fg_bg_file(gmm2);
|
||||
// macro_svp_check_exps_return(ret != TD_SUCCESS, ret, ENUM_SVP_ERR_LEVEL_ERROR,
|
||||
// "Error(%#x),Write fg bg file failed!\n", ret);
|
||||
|
||||
cur_idx = 1 - cur_idx;
|
||||
}
|
||||
|
||||
return TD_SUCCESS;
|
||||
}
|
||||
|
||||
static td_void _ive_gmm2_stop(td_void)
|
||||
{
|
||||
_ive_gmm2_uninit(&g_gmm2_info);
|
||||
(td_void)memset_s(&g_gmm2_info, sizeof(g_gmm2_info), 0, sizeof(g_gmm2_info));
|
||||
// libapi_common_ive_mpi_exit();
|
||||
printf("\033[0;31mprogram termination abnormally!\033[0;39m\n");
|
||||
}
|
||||
|
||||
/*
|
||||
* function: gmm2 func
|
||||
*/
|
||||
td_void libapi_ive_gmm2(td_void)
|
||||
{
|
||||
td_s32 ret;
|
||||
ot_size pic_size = { OT_MACRO_IVE_GMM2_CIF_WIDTH, OT_MACRO_IVE_GMM2_CIF_HEIGHT };
|
||||
|
||||
(td_void)memset_s(&g_gmm2_info, sizeof(g_gmm2_info), 0, sizeof(g_gmm2_info));
|
||||
// ret = libapi_common_ive_check_mpi_init();
|
||||
// macro_svp_check_exps_return_void(ret != TD_TRUE, ENUM_SVP_ERR_LEVEL_ERROR, "ive_check_mpi_init failed!\n");
|
||||
|
||||
ret = _ive_gmm2_init(&g_gmm2_info, pic_size);
|
||||
macro_svp_check_exps_goto(ret != TD_SUCCESS, gmm2_fail, ENUM_SVP_ERR_LEVEL_ERROR,
|
||||
"Error(%#x),_ive_gmm2_init failed!\n", ret);
|
||||
|
||||
ret = _ive_gmm2_proc(&g_gmm2_info);
|
||||
if (g_stop_signal == TD_TRUE) {
|
||||
_ive_gmm2_stop();
|
||||
return;
|
||||
}
|
||||
|
||||
if (ret == TD_SUCCESS) {
|
||||
macro_svp_trace_info("Process success!\n");
|
||||
} else {
|
||||
macro_svp_trace_err("gmm2 process failed!\n");
|
||||
}
|
||||
|
||||
g_stop_signal = TD_TRUE;
|
||||
_ive_gmm2_uninit(&g_gmm2_info);
|
||||
(td_void)memset_s(&g_gmm2_info, sizeof(g_gmm2_info), 0, sizeof(g_gmm2_info));
|
||||
|
||||
gmm2_fail:
|
||||
g_stop_signal = TD_TRUE;
|
||||
// libapi_common_ive_mpi_exit();
|
||||
}
|
||||
|
||||
/*
|
||||
* function : Gmm2 signal handle
|
||||
*/
|
||||
td_void libapi_ive_gmm2_handle_sig(td_void)
|
||||
{
|
||||
g_stop_signal = TD_TRUE;
|
||||
}
|
1320
libapi/ive/libapi_ive_kcf.c
Executable file
103
libapi/ive/libapi_ive_main.h
Executable file
@ -0,0 +1,103 @@
|
||||
/*
|
||||
Copyright (c), 2001-2022, Shenshu Tech. Co., Ltd.
|
||||
*/
|
||||
|
||||
#ifndef LIBAPI_IVE_MAIN_H
|
||||
#define LIBAPI_IVE_MAIN_H
|
||||
#include "ot_type.h"
|
||||
#include "securec.h"
|
||||
|
||||
/*
|
||||
* function : show Canny demo
|
||||
* canny_complete: 0 : part canny; 1 : complete canny
|
||||
*/
|
||||
// td_void libapi_ive_canny(td_char canny_complete);
|
||||
td_u32 libapi_ive_canny(td_void* src, td_u32 width, td_u32 height, td_u32 img_type,
|
||||
td_void* dst, td_char canny_complete);
|
||||
|
||||
/*
|
||||
* function : show Gmm2 demo
|
||||
*/
|
||||
td_void libapi_ive_gmm2(td_void);
|
||||
|
||||
/*
|
||||
* function : show Test Memory demo
|
||||
*/
|
||||
td_void libapi_ive_test_memory(td_void);
|
||||
|
||||
/*
|
||||
* function : show Sobel demo
|
||||
*/
|
||||
td_void libapi_ive_sobel(td_void);
|
||||
|
||||
/*
|
||||
* function : show St Lk demo
|
||||
*/
|
||||
td_void libapi_ive_st_lk(td_void);
|
||||
|
||||
/*
|
||||
* function : show Occlusion detected demo
|
||||
*/
|
||||
td_void libapi_ive_od(td_void);
|
||||
|
||||
/*
|
||||
* function : show Md demo
|
||||
*/
|
||||
td_void libapi_ive_md(td_void);
|
||||
|
||||
/*
|
||||
* function : show PerspTrans demo
|
||||
*/
|
||||
td_void libapi_ive_persp_trans(td_void);
|
||||
|
||||
/*
|
||||
* function : show Kcf demo
|
||||
*/
|
||||
td_void libapi_ive_kcf(td_void);
|
||||
|
||||
/*
|
||||
* function :Canny demo signal handle
|
||||
*/
|
||||
td_void libapi_ive_canny_handle_sig(td_void);
|
||||
|
||||
/*
|
||||
* function : Gmm2 demo signal handle
|
||||
*/
|
||||
td_void libapi_ive_gmm2_handle_sig(td_void);
|
||||
|
||||
|
||||
/*
|
||||
* function : TestMemory demo signal handle
|
||||
*/
|
||||
td_void libapi_ive_test_memory_handle_sig(td_void);
|
||||
|
||||
/*
|
||||
* function : Sobel demo signal handle
|
||||
*/
|
||||
td_void libapi_ive_sobel_handle_sig(td_void);
|
||||
|
||||
/*
|
||||
* function : St_Lk demo signal handle
|
||||
*/
|
||||
td_void libapi_ive_st_lk_handle_sig(td_void);
|
||||
|
||||
/*
|
||||
* function : PerspTrans demo signal handle
|
||||
*/
|
||||
td_void libapi_ive_persp_trans_handle_sig(td_void);
|
||||
|
||||
/*
|
||||
* function : Od demo signal handle
|
||||
*/
|
||||
td_void libapi_ive_od_handle_sig(td_void);
|
||||
|
||||
/*
|
||||
* function : Md demo signal handle
|
||||
*/
|
||||
td_void libapi_ive_md_handle_sig(td_void);
|
||||
/*
|
||||
* function : kcf demo signal handle
|
||||
*/
|
||||
td_void libapi_ive_kcf_handle_sig(td_void);
|
||||
#endif
|
||||
|
304
libapi/ive/libapi_ive_md.c
Executable file
@ -0,0 +1,304 @@
|
||||
/*
|
||||
Copyright (c), 2001-2022, Shenshu Tech. Co., Ltd.
|
||||
*/
|
||||
#include "libapi_common_ive.h"
|
||||
#include "ot_ivs_md.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#include <signal.h>
|
||||
#include <semaphore.h>
|
||||
#include <pthread.h>
|
||||
#include <sys/prctl.h>
|
||||
|
||||
#define OT_MACRO_IVE_MD_IMAGE_NUM 2
|
||||
#define OT_MACRO_IVE_MD_MILLIC_SEC 20000
|
||||
#define OT_MACRO_IVE_MD_ADD_X_VAL 32768
|
||||
#define OT_MACRO_IVE_MD_ADD_Y_VAL 32768
|
||||
#define OT_MACRO_IVE_MD_THREAD_NAME_LEN 16
|
||||
#define OT_MACRO_IVE_MD_AREA_THR_STEP 8
|
||||
#define OT_MACRO_IVE_MD_VPSS_CHN 2
|
||||
#define OT_MACRO_IVE_MD_NUM_TWO 2
|
||||
#define OT_MACRO_IVE_SAD_THRESHOLD 100
|
||||
|
||||
typedef struct {
|
||||
ot_svp_src_img img[OT_MACRO_IVE_MD_IMAGE_NUM];
|
||||
ot_svp_dst_mem_info blob;
|
||||
ot_md_attr md_attr;
|
||||
ot_struct_svp_rect_info region;
|
||||
} ot_struct_ivs_md_info;
|
||||
|
||||
typedef struct {
|
||||
ot_md_chn md_chn;
|
||||
ot_vo_layer vo_layer;
|
||||
ot_vo_chn vo_chn;
|
||||
td_s32 vpss_grp;
|
||||
} ot_struct_md_vo_vpss_hld;
|
||||
|
||||
static td_bool g_stop_signal = TD_FALSE;
|
||||
static pthread_t g_md_thread;
|
||||
static ot_struct_ivs_md_info g_md_info;
|
||||
static ot_struct_svp_switch g_md_switch = { TD_FALSE, TD_TRUE };
|
||||
static struct_vi_cfg g_vi_config;
|
||||
static ot_struct_src_dst_size g_src_dst;
|
||||
|
||||
static td_void _ivs_md_uninit(ot_struct_ivs_md_info *md_info_ptr)
|
||||
{
|
||||
td_s32 i;
|
||||
td_s32 ret;
|
||||
|
||||
macro_svp_check_exps_return_void(md_info_ptr == TD_NULL, ENUM_SVP_ERR_LEVEL_ERROR, "md_inf_ptr can't be null\n");
|
||||
|
||||
for (i = 0; i < OT_MACRO_IVE_MD_IMAGE_NUM; i++) {
|
||||
macro_svp_mmz_free(md_info_ptr->img[i].phys_addr[0], md_info_ptr->img[i].virt_addr[0]);
|
||||
}
|
||||
|
||||
macro_svp_mmz_free(md_info_ptr->blob.phys_addr, md_info_ptr->blob.virt_addr);
|
||||
|
||||
ret = ot_ivs_md_exit();
|
||||
if (ret != TD_SUCCESS) {
|
||||
macro_svp_trace_err("ot_ivs_md_exit fail,Error(%#x)\n", ret);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static td_s32 _ivs_md_init(ot_struct_ivs_md_info *md_inf_ptr, td_u32 width, td_u32 height)
|
||||
{
|
||||
td_s32 ret = OT_ERR_IVE_NULL_PTR;
|
||||
td_s32 i;
|
||||
td_u32 size, sad_mode;
|
||||
td_u8 wnd_size;
|
||||
|
||||
macro_svp_check_exps_return(md_inf_ptr == TD_NULL, ret, ENUM_SVP_ERR_LEVEL_ERROR, "md_inf_ptr can't be null\n");
|
||||
|
||||
for (i = 0; i < OT_MACRO_IVE_MD_IMAGE_NUM; i++) {
|
||||
ret = libapi_common_ive_create_image(&md_inf_ptr->img[i], OT_SVP_IMG_TYPE_U8C1, width, height);
|
||||
macro_svp_check_exps_goto(ret != TD_SUCCESS, md_init_fail, ENUM_SVP_ERR_LEVEL_ERROR,
|
||||
"Error(%#x),Create img[%d] image failed!\n", ret, i);
|
||||
}
|
||||
size = sizeof(ot_ive_ccblob);
|
||||
ret = libapi_common_ive_create_mem_info(&md_inf_ptr->blob, size);
|
||||
macro_svp_check_exps_goto(ret != TD_SUCCESS, md_init_fail, ENUM_SVP_ERR_LEVEL_ERROR,
|
||||
"Error(%#x),Create blob mem info failed!\n", ret);
|
||||
|
||||
/* Set attr info */
|
||||
md_inf_ptr->md_attr.alg_mode = OT_MD_ALG_MODE_BG;
|
||||
md_inf_ptr->md_attr.sad_mode = OT_IVE_SAD_MODE_MB_4X4;
|
||||
md_inf_ptr->md_attr.sad_out_ctrl = OT_IVE_SAD_OUT_CTRL_THRESHOLD;
|
||||
md_inf_ptr->md_attr.sad_threshold = OT_MACRO_IVE_SAD_THRESHOLD * (1 << 1);
|
||||
md_inf_ptr->md_attr.width = width;
|
||||
md_inf_ptr->md_attr.height = height;
|
||||
md_inf_ptr->md_attr.add_ctrl.x = OT_MACRO_IVE_MD_ADD_X_VAL;
|
||||
md_inf_ptr->md_attr.add_ctrl.y = OT_MACRO_IVE_MD_ADD_Y_VAL;
|
||||
md_inf_ptr->md_attr.ccl_ctrl.mode = OT_IVE_CCL_MODE_4C;
|
||||
sad_mode = (td_u32)md_inf_ptr->md_attr.sad_mode;
|
||||
wnd_size = (1 << (OT_MACRO_IVE_MD_NUM_TWO + sad_mode));
|
||||
md_inf_ptr->md_attr.ccl_ctrl.init_area_threshold = wnd_size * wnd_size;
|
||||
md_inf_ptr->md_attr.ccl_ctrl.step = wnd_size;
|
||||
|
||||
ret = ot_ivs_md_init();
|
||||
macro_svp_check_exps_goto(ret != TD_SUCCESS, md_init_fail, ENUM_SVP_ERR_LEVEL_ERROR,
|
||||
"Error(%#x),ot_ivs_md_init failed!\n", ret);
|
||||
|
||||
md_init_fail:
|
||||
if (ret != TD_SUCCESS) {
|
||||
_ivs_md_uninit(md_inf_ptr);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static td_void _ivs_set_src_dst_size(ot_struct_src_dst_size *src_dst, td_u32 src_width,
|
||||
td_u32 src_height, td_u32 dst_width, td_u32 dst_height)
|
||||
{
|
||||
src_dst->src.width = src_width;
|
||||
src_dst->src.height = src_height;
|
||||
src_dst->dst.width = dst_width;
|
||||
src_dst->dst.height = dst_height;
|
||||
}
|
||||
|
||||
/* first frame just init reference frame, if not, change the frame idx */
|
||||
static td_s32 _ivs_md_dma_data(td_u32 cur_idx, ot_video_frame_info *frm,
|
||||
ot_struct_ivs_md_info *md_ptr, td_bool *is_first_frm)
|
||||
{
|
||||
td_s32 ret;
|
||||
td_bool is_instant = TD_TRUE;
|
||||
if (*is_first_frm != TD_TRUE) {
|
||||
ret = libapi_common_ive_dma_image(frm, &md_ptr->img[cur_idx], is_instant);
|
||||
macro_svp_check_exps_return(ret != TD_SUCCESS, ret, ENUM_SVP_ERR_LEVEL_ERROR,
|
||||
"sample_ive_dma_image fail,Err(%#x)\n", ret);
|
||||
} else {
|
||||
ret = libapi_common_ive_dma_image(frm, &md_ptr->img[1 - cur_idx], is_instant);
|
||||
macro_svp_check_exps_return(ret != TD_SUCCESS, ret, ENUM_SVP_ERR_LEVEL_ERROR,
|
||||
"sample_ive_dma_image fail,Err(%#x)\n", ret);
|
||||
|
||||
*is_first_frm = TD_FALSE;
|
||||
}
|
||||
return TD_SUCCESS;
|
||||
}
|
||||
|
||||
static td_void *_ivs_md_proc(td_void *args)
|
||||
{
|
||||
td_s32 ret;
|
||||
ot_struct_ivs_md_info *md_ptr = (ot_struct_ivs_md_info *)(args);
|
||||
ot_video_frame_info frm[OT_MACRO_IVE_MD_VPSS_CHN]; /* 0:base_frm, 1:ext_frm */
|
||||
ot_struct_md_vo_vpss_hld hld = {0};
|
||||
td_s32 vpss_chn[] = { OT_VPSS_CHN0, OT_VPSS_CHN1 };
|
||||
td_s32 cur_idx = 0;
|
||||
td_bool is_first_frm = TD_TRUE;
|
||||
|
||||
macro_svp_check_exps_return(md_ptr == TD_NULL, TD_NULL, ENUM_SVP_ERR_LEVEL_ERROR, "md_inf_ptr can't be null\n");
|
||||
|
||||
/* Create chn */
|
||||
ret = ot_ivs_md_create_chn(hld.md_chn, &(md_ptr->md_attr));
|
||||
macro_svp_check_exps_return(ret != TD_SUCCESS, TD_NULL, ENUM_SVP_ERR_LEVEL_ERROR, "ot_ivs_md_create_chn fail\n");
|
||||
|
||||
while (g_stop_signal == TD_FALSE) {
|
||||
ret = ss_mpi_vpss_get_chn_frame(hld.vpss_grp, vpss_chn[1], &frm[1], OT_MACRO_IVE_MD_MILLIC_SEC);
|
||||
macro_svp_check_exps_continue(ret != TD_SUCCESS, ENUM_SVP_ERR_LEVEL_ERROR,
|
||||
"Err(%#x),vpss_get_chn_frame failed, vpss_grp(%d), vpss_chn(%d)!\n", ret, hld.vpss_grp, vpss_chn[1]);
|
||||
|
||||
ret = ss_mpi_vpss_get_chn_frame(hld.vpss_grp, vpss_chn[0], &frm[0], OT_MACRO_IVE_MD_MILLIC_SEC);
|
||||
macro_svp_check_failed_goto(ret, ext_free, ENUM_SVP_ERR_LEVEL_ERROR,
|
||||
"Error(%#x),vpss_get_chn_frame failed, VPSS_GRP(%d), VPSS_CHN(%d)!\n", ret, hld.vpss_grp, vpss_chn[0]);
|
||||
|
||||
ret = _ivs_md_dma_data(cur_idx, &frm[1], md_ptr, &is_first_frm);
|
||||
macro_svp_check_failed_goto(ret, base_free, ENUM_SVP_ERR_LEVEL_ERROR, "dma data failed, Err(%#x)\n", ret);
|
||||
|
||||
/* change idx */
|
||||
if (is_first_frm == TD_TRUE) {
|
||||
goto change_idx;
|
||||
}
|
||||
|
||||
ret = ot_ivs_md_proc(hld.md_chn, &md_ptr->img[cur_idx], &md_ptr->img[1 - cur_idx], TD_NULL, &md_ptr->blob);
|
||||
macro_svp_check_failed_goto(ret, base_free, ENUM_SVP_ERR_LEVEL_ERROR, "ivs_md_proc fail,Err(%#x)\n", ret);
|
||||
|
||||
_ivs_set_src_dst_size(&g_src_dst, md_ptr->md_attr.width, md_ptr->md_attr.height,
|
||||
frm[0].video_frame.width, frm[0].video_frame.height);
|
||||
ret = libapi_common_ive_blob_to_rect(macro_svp_convert_addr_to_ptr(ot_ive_ccblob, md_ptr->blob.virt_addr),
|
||||
&(md_ptr->region), OT_SVP_RECT_NUM, OT_MACRO_IVE_MD_AREA_THR_STEP, g_src_dst);
|
||||
macro_svp_check_exps_goto(ret != TD_SUCCESS, base_free, ENUM_SVP_ERR_LEVEL_ERROR, "blob to rect failed!\n");
|
||||
|
||||
/* Draw rect */
|
||||
ret = sample_common_svp_vgs_fill_rect(&frm[0], &md_ptr->region, 0x0000FF00);
|
||||
macro_svp_check_failed_err_level_goto(ret, base_free, "sample_svp_vgs_fill_rect fail,Err(%#x)\n", ret);
|
||||
|
||||
ret = ss_mpi_vo_send_frame(hld.vo_layer, hld.vo_chn, &frm[0], OT_MACRO_IVE_MD_MILLIC_SEC);
|
||||
macro_svp_check_failed_err_level_goto(ret, base_free, "ss_mpi_vo_send_frame fail,Error(%#x)\n", ret);
|
||||
|
||||
change_idx:
|
||||
/* Change reference and current frame index */
|
||||
cur_idx = 1 - cur_idx;
|
||||
base_free:
|
||||
ret = ss_mpi_vpss_release_chn_frame(hld.vpss_grp, vpss_chn[0], &frm[0]);
|
||||
macro_svp_check_exps_trace(ret != TD_SUCCESS, ENUM_SVP_ERR_LEVEL_ERROR,
|
||||
"Err(%#x),release_frame failed,grp(%d) chn(%d)!\n", ret, hld.vpss_grp, vpss_chn[0]);
|
||||
|
||||
ext_free:
|
||||
ret = ss_mpi_vpss_release_chn_frame(hld.vpss_grp, vpss_chn[1], &frm[1]);
|
||||
macro_svp_check_exps_trace(ret != TD_SUCCESS, ENUM_SVP_ERR_LEVEL_ERROR,
|
||||
"Err(%#x),release_frame failed,grp(%d) chn(%d)!\n", ret, hld.vpss_grp, vpss_chn[1]);
|
||||
}
|
||||
|
||||
/* destroy */
|
||||
ret = ot_ivs_md_destroy_chn(hld.md_chn);
|
||||
macro_svp_check_failed_trace(ret, ENUM_SVP_ERR_LEVEL_ERROR, "ot_ivs_md_destroy_chn fail,Err(%#x)\n", ret);
|
||||
|
||||
return TD_NULL;
|
||||
}
|
||||
|
||||
static td_s32 _ive_md_pause(td_void)
|
||||
{
|
||||
printf("---------------press Enter key to exit!---------------\n");
|
||||
if (g_stop_signal == TD_TRUE) {
|
||||
if (g_md_thread != 0) {
|
||||
pthread_join(g_md_thread, TD_NULL);
|
||||
g_md_thread = 0;
|
||||
}
|
||||
_ivs_md_uninit(&(g_md_info));
|
||||
(td_void)memset_s(&g_md_info, sizeof(g_md_info), 0, sizeof(g_md_info));
|
||||
|
||||
sample_common_svp_stop_vi_vpss_venc_vo(&g_vi_config, &g_md_switch);
|
||||
printf("\033[0;31mprogram termination abnormally!\033[0;39m\n");
|
||||
return TD_TRUE;
|
||||
}
|
||||
|
||||
(void)getchar();
|
||||
|
||||
if (g_stop_signal == TD_TRUE) {
|
||||
if (g_md_thread != 0) {
|
||||
pthread_join(g_md_thread, TD_NULL);
|
||||
g_md_thread = 0;
|
||||
}
|
||||
_ivs_md_uninit(&(g_md_info));
|
||||
(td_void)memset_s(&g_md_info, sizeof(g_md_info), 0, sizeof(g_md_info));
|
||||
|
||||
sample_common_svp_stop_vi_vpss_venc_vo(&g_vi_config, &g_md_switch);
|
||||
printf("\033[0;31mprogram termination abnormally!\033[0;39m\n");
|
||||
return TD_TRUE;
|
||||
}
|
||||
return TD_FALSE;
|
||||
}
|
||||
|
||||
td_void libapi_ive_md(td_void)
|
||||
{
|
||||
ot_size pic_size;
|
||||
ot_enum_pic_size pic_type = PIC_1080P;
|
||||
td_s32 ret;
|
||||
|
||||
(td_void)memset_s(&g_md_info, sizeof(g_md_info), 0, sizeof(g_md_info));
|
||||
/*
|
||||
* step 1: start vi vpss venc vo
|
||||
*/
|
||||
ret = sample_common_svp_start_vi_vpss_venc_vo(&g_vi_config, &g_md_switch, &pic_type);
|
||||
macro_svp_check_exps_goto(ret != TD_SUCCESS, end_md_0, ENUM_SVP_ERR_LEVEL_ERROR,
|
||||
"Error(%#x),sample_common_svp_start_vi_vpss_venc_vo failed!\n", ret);
|
||||
|
||||
pic_type = PIC_1080P;
|
||||
ret = libapi_comm_sys_get_pic_size(pic_type, &pic_size);
|
||||
macro_svp_check_exps_goto(ret != TD_SUCCESS, end_md_0, ENUM_SVP_ERR_LEVEL_ERROR,
|
||||
"Error(%#x),libapi_comm_sys_get_pic_size failed!\n", ret);
|
||||
/*
|
||||
* step 2: Init Md
|
||||
*/
|
||||
ret = _ivs_md_init(&g_md_info, pic_size.width, pic_size.height);
|
||||
macro_svp_check_exps_goto(ret != TD_SUCCESS, end_md_0, ENUM_SVP_ERR_LEVEL_ERROR,
|
||||
" Error(%#x),_ivs_md_init failed!\n", ret);
|
||||
g_stop_signal = TD_FALSE;
|
||||
/*
|
||||
* step 3: Create work thread
|
||||
*/
|
||||
ret = prctl(PR_SET_NAME, "ive_md_proc", 0, 0, 0);
|
||||
macro_svp_check_exps_goto(ret != TD_SUCCESS, end_md_0, ENUM_SVP_ERR_LEVEL_ERROR, "set thread name failed!\n");
|
||||
ret = pthread_create(&g_md_thread, 0, _ivs_md_proc, (td_void *)&g_md_info);
|
||||
macro_svp_check_exps_goto(ret != TD_SUCCESS, end_md_0, ENUM_SVP_ERR_LEVEL_ERROR, "pthread_create failed!\n");
|
||||
|
||||
ret = _ive_md_pause();
|
||||
macro_svp_check_exps_return_void(ret == TD_TRUE, ENUM_SVP_ERR_LEVEL_ERROR, "md exist!\n");
|
||||
g_stop_signal = TD_TRUE;
|
||||
pthread_join(g_md_thread, TD_NULL);
|
||||
g_md_thread = 0;
|
||||
|
||||
_ivs_md_uninit(&(g_md_info));
|
||||
(td_void)memset_s(&g_md_info, sizeof(g_md_info), 0, sizeof(g_md_info));
|
||||
|
||||
end_md_0:
|
||||
g_md_thread = 0;
|
||||
g_stop_signal = TD_TRUE;
|
||||
sample_common_svp_stop_vi_vpss_venc_vo(&g_vi_config, &g_md_switch);
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* function : Md sample signal handle
|
||||
*/
|
||||
td_void libapi_ive_md_handle_sig(td_void)
|
||||
{
|
||||
g_stop_signal = TD_TRUE;
|
||||
}
|
351
libapi/ive/libapi_ive_od.c
Executable file
@ -0,0 +1,351 @@
|
||||
/*
|
||||
Copyright (c), 2001-2022, Shenshu Tech. Co., Ltd.
|
||||
*/
|
||||
#include "libapi_common_ive.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#include <signal.h>
|
||||
#include <semaphore.h>
|
||||
#include <pthread.h>
|
||||
#include <sys/prctl.h>
|
||||
#include <math.h>
|
||||
|
||||
#define OT_MACRO_IVE_OD_MILLI_SEC 20000
|
||||
#define OT_MACRO_IVE_OD_QUERY_SLEEP 100
|
||||
#define OT_MACRO_IVE_OD_LINEAR_NUM 2
|
||||
#define OT_MACRO_IVE_OD_LINEAR_POINT0_X 80
|
||||
#define OT_MACRO_IVE_OD_LINEAR_POINT0_Y 0
|
||||
#define OT_MACRO_IVE_OD_LINEAR_POINT1_X 80
|
||||
#define OT_MACRO_IVE_OD_LINEAR_POINT1_Y 20
|
||||
#define OT_MACRO_IVE_OD_THREAD_NAME_LEN 16
|
||||
#define OT_MACRO_IVE_OD_NUM_TWO 2
|
||||
#define OT_MACRO_IVE_OD_POINT_NUM 10
|
||||
#define OT_MACRO_IVE_RIGHT_SHIFT_TWENTY_EIGHT 28
|
||||
|
||||
typedef struct {
|
||||
ot_svp_src_img src;
|
||||
ot_svp_dst_img integ;
|
||||
ot_ive_integ_ctrl integ_ctrl;
|
||||
td_u32 width;
|
||||
td_u32 height;
|
||||
} ot_sample_ive_od_info;
|
||||
|
||||
static td_bool g_stop_signal = TD_FALSE;
|
||||
static pthread_t g_ive_thread = 0;
|
||||
static ot_sample_ive_od_info g_od_info;
|
||||
static ot_struct_svp_switch g_od_switch = { TD_FALSE, TD_TRUE };
|
||||
static struct_vi_cfg g_vi_config;
|
||||
|
||||
static td_void sample_ive_od_uninit(ot_sample_ive_od_info *od_info)
|
||||
{
|
||||
macro_svp_check_exps_return_void(od_info == TD_NULL, ENUM_SVP_ERR_LEVEL_ERROR, "od_info can't be null\n");
|
||||
macro_svp_mmz_free(od_info->src.phys_addr[0], od_info->src.virt_addr[0]);
|
||||
macro_svp_mmz_free(od_info->integ.phys_addr[0], od_info->integ.virt_addr[0]);
|
||||
}
|
||||
|
||||
static td_s32 sample_ive_od_init(ot_sample_ive_od_info *od_info, td_u32 width, td_u32 height)
|
||||
{
|
||||
td_s32 ret = OT_ERR_IVE_NULL_PTR;
|
||||
|
||||
macro_svp_check_exps_return(od_info == TD_NULL, ret, ENUM_SVP_ERR_LEVEL_ERROR, "od_info can't be null\n");
|
||||
|
||||
(td_void)memset_s(od_info, sizeof(ot_sample_ive_od_info), 0, sizeof(ot_sample_ive_od_info));
|
||||
|
||||
ret = libapi_common_ive_create_image(&od_info->src, OT_SVP_IMG_TYPE_U8C1, width, height);
|
||||
macro_svp_check_exps_goto(ret != TD_SUCCESS, od_init_fail, ENUM_SVP_ERR_LEVEL_ERROR,
|
||||
"Error(%#x),Create src image failed!\n", ret);
|
||||
|
||||
ret = libapi_common_ive_create_image(&od_info->integ, OT_SVP_IMG_TYPE_U64C1, width, height);
|
||||
macro_svp_check_exps_goto(ret != TD_SUCCESS, od_init_fail, ENUM_SVP_ERR_LEVEL_ERROR,
|
||||
"Error(%#x),Create integ image failed!\n", ret);
|
||||
|
||||
od_info->integ_ctrl.out_ctrl = OT_IVE_INTEG_OUT_CTRL_COMBINE;
|
||||
|
||||
od_info->width = width / OT_IVE_CHAR_CALW;
|
||||
od_info->height = height / OT_IVE_CHAR_CALH;
|
||||
|
||||
od_init_fail:
|
||||
if (ret != TD_SUCCESS) {
|
||||
sample_ive_od_uninit(od_info);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static td_s32 sample_ive_linear_2d_classifer(ot_point *char_point, td_s32 char_num, ot_point *linear_point,
|
||||
td_s32 linear_num)
|
||||
{
|
||||
td_s32 result_num;
|
||||
td_s32 i, j;
|
||||
td_bool test_flag;
|
||||
ot_point *next_linear_point = TD_NULL;
|
||||
|
||||
result_num = 0;
|
||||
next_linear_point = &linear_point[1];
|
||||
for (i = 0; i < char_num; i++) {
|
||||
test_flag = TD_TRUE;
|
||||
for (j = 0; j < (linear_num - 1); j++) {
|
||||
if (((char_point[i].y - linear_point[j].y) * (next_linear_point[j].x - linear_point[j].x) >
|
||||
(char_point[i].x - linear_point[j].x) * (next_linear_point[j].y - linear_point[j].y) &&
|
||||
(next_linear_point[j].x != linear_point[j].x)) ||
|
||||
((char_point[i].x > linear_point[j].x) && (next_linear_point[j].x == linear_point[j].x))) {
|
||||
test_flag = TD_FALSE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (test_flag == TD_TRUE) {
|
||||
result_num++;
|
||||
}
|
||||
}
|
||||
return result_num;
|
||||
}
|
||||
|
||||
static td_void sample_ive_prepare_dma_data(ot_sample_ive_od_info *od_ptr, ot_video_frame_info *ext_frm_info,
|
||||
ot_svp_data *src_data, ot_svp_data *dst_data)
|
||||
{
|
||||
src_data->virt_addr = macro_svp_convert_ptr_to_addr(td_u64, ext_frm_info->video_frame.virt_addr[0]);
|
||||
src_data->phys_addr = ext_frm_info->video_frame.phys_addr[0];
|
||||
src_data->stride = ext_frm_info->video_frame.stride[0];
|
||||
src_data->width = ext_frm_info->video_frame.width;
|
||||
src_data->height = ext_frm_info->video_frame.height;
|
||||
|
||||
dst_data->virt_addr = od_ptr->src.virt_addr[0];
|
||||
dst_data->phys_addr = od_ptr->src.phys_addr[0];
|
||||
dst_data->stride = ext_frm_info->video_frame.stride[0];
|
||||
dst_data->width = ext_frm_info->video_frame.width;
|
||||
dst_data->height = ext_frm_info->video_frame.height;
|
||||
}
|
||||
|
||||
static td_s32 sample_ive_query_task(ot_ive_handle handle)
|
||||
{
|
||||
td_s32 ret;
|
||||
td_bool is_block = TD_TRUE;
|
||||
td_bool is_finish = TD_FALSE;
|
||||
ret = ss_mpi_ive_query(handle, &is_finish, is_block);
|
||||
while (ret == OT_ERR_IVE_QUERY_TIMEOUT) {
|
||||
usleep(OT_MACRO_IVE_OD_QUERY_SLEEP);
|
||||
ret = ss_mpi_ive_query(handle, &is_finish, is_block);
|
||||
}
|
||||
macro_svp_check_exps_return(ret != TD_SUCCESS, ret, ENUM_SVP_ERR_LEVEL_ERROR,
|
||||
"Error(%#x),ss_mpi_ive_query failed!\n", ret);
|
||||
return TD_SUCCESS;
|
||||
}
|
||||
|
||||
static td_s32 sample_ive_get_char_point(ot_sample_ive_od_info *od_ptr, ot_point char_point[], td_u32 length)
|
||||
{
|
||||
td_u64 *vir_data = TD_NULL;
|
||||
td_u32 i, j;
|
||||
td_u64 top_left, top_right, btm_left, btm_right;
|
||||
td_u64 *top_row_ptr = TD_NULL;
|
||||
td_u64 *btm_row_ptr = TD_NULL;
|
||||
td_u64 block_sum, block_sqrt;
|
||||
td_float sqrt_val;
|
||||
vir_data = macro_svp_convert_addr_to_ptr(td_u64, od_ptr->integ.virt_addr[0]);
|
||||
macro_svp_check_exps_return(length > OT_IVE_CHAR_CALW * OT_IVE_CHAR_CALH, OT_ERR_IVE_ILLEGAL_PARAM,
|
||||
ENUM_SVP_ERR_LEVEL_ERROR, "length(%u) is larger than %u\n", length, OT_IVE_CHAR_CALW * OT_IVE_CHAR_CALH);
|
||||
|
||||
for (j = 0; (j < OT_IVE_CHAR_CALH) && (j < length); j++) {
|
||||
top_row_ptr = (0 == j) ? (vir_data) : (vir_data + (j * od_ptr->height - 1) * od_ptr->integ.stride[0]);
|
||||
btm_row_ptr = vir_data + ((j + 1) * od_ptr->height - 1) * od_ptr->integ.stride[0];
|
||||
|
||||
for (i = 0; i < OT_IVE_CHAR_CALW; i++) {
|
||||
top_left = (0 == j) ? (0) : ((0 == i) ? (0) : (top_row_ptr[i * od_ptr->width - 1]));
|
||||
top_right = (0 == j) ? (0) : (top_row_ptr[(i + 1) * od_ptr->width - 1]);
|
||||
btm_left = (0 == i) ? (0) : (btm_row_ptr[i * od_ptr->width - 1]);
|
||||
btm_right = btm_row_ptr[(i + 1) * od_ptr->width - 1];
|
||||
|
||||
block_sum = (top_left & 0xfffffffLL) + (btm_right & 0xfffffffLL) -
|
||||
(btm_left & 0xfffffffLL) - (top_right & 0xfffffffLL);
|
||||
|
||||
block_sqrt = (top_left >> OT_MACRO_IVE_RIGHT_SHIFT_TWENTY_EIGHT) +
|
||||
(btm_right >> OT_MACRO_IVE_RIGHT_SHIFT_TWENTY_EIGHT) -
|
||||
(btm_left >> OT_MACRO_IVE_RIGHT_SHIFT_TWENTY_EIGHT) -
|
||||
(top_right >> OT_MACRO_IVE_RIGHT_SHIFT_TWENTY_EIGHT);
|
||||
|
||||
/* mean */
|
||||
char_point[j * OT_IVE_CHAR_CALW + i].x = block_sum / (od_ptr->width * od_ptr->width);
|
||||
/* sigma=sqrt(1/(w*h)*sum((x(i,j)-mean)^2)= sqrt(sum(x(i,j)^2)/(w*h)-mean^2) */
|
||||
sqrt_val = block_sqrt / (od_ptr->width * od_ptr->height) - char_point[j * OT_IVE_CHAR_CALW + i].x *
|
||||
char_point[j * OT_IVE_CHAR_CALW + i].x;
|
||||
char_point[j * OT_IVE_CHAR_CALW + i].y = (td_u32)sqrt(sqrt_val);
|
||||
}
|
||||
}
|
||||
return TD_SUCCESS;
|
||||
}
|
||||
|
||||
static td_void sample_ive_set_linear_data(ot_struct_ive_linear_data *data)
|
||||
{
|
||||
data->linear_num = OT_MACRO_IVE_OD_LINEAR_NUM;
|
||||
data->thresh_num = OT_IVE_CHAR_NUM / OT_MACRO_IVE_OD_NUM_TWO;
|
||||
data->linear_point[0].x = OT_MACRO_IVE_OD_LINEAR_POINT0_X;
|
||||
data->linear_point[0].y = OT_MACRO_IVE_OD_LINEAR_POINT0_Y;
|
||||
data->linear_point[1].x = OT_MACRO_IVE_OD_LINEAR_POINT1_X;
|
||||
data->linear_point[1].y = OT_MACRO_IVE_OD_LINEAR_POINT1_Y;
|
||||
}
|
||||
|
||||
static td_void *sample_ive_od_proc(td_void *arg)
|
||||
{
|
||||
td_s32 ret;
|
||||
ot_sample_ive_od_info *od_ptr = TD_NULL;
|
||||
ot_video_frame_info base_frm_info, ext_frm_info;
|
||||
const td_s32 vpss_grp = 0;
|
||||
td_s32 vpss_chn[] = { OT_VPSS_CHN0, OT_VPSS_CHN1 };
|
||||
ot_svp_data src_data, dst_data;
|
||||
ot_ive_handle handle;
|
||||
ot_point points[OT_MACRO_IVE_OD_POINT_NUM] = {{ 0, 0 }};
|
||||
|
||||
ot_point char_point[OT_IVE_CHAR_NUM];
|
||||
ot_struct_ive_linear_data data;
|
||||
ot_ive_dma_ctrl dma_ctrl = { OT_IVE_DMA_MODE_DIRECT_COPY, 0, 0, 0, 0 };
|
||||
data.linear_point = &points[0];
|
||||
|
||||
od_ptr = (ot_sample_ive_od_info *)(arg);
|
||||
|
||||
macro_svp_check_exps_return(od_ptr == TD_NULL, TD_NULL, ENUM_SVP_ERR_LEVEL_ERROR, "od_ptr can't be null\n");
|
||||
/* init data */
|
||||
sample_ive_set_linear_data(&data);
|
||||
|
||||
while (g_stop_signal == TD_FALSE) {
|
||||
/* get frame */
|
||||
ret = ss_mpi_vpss_get_chn_frame(vpss_grp, vpss_chn[1], &ext_frm_info, OT_MACRO_IVE_OD_MILLI_SEC);
|
||||
macro_svp_check_exps_continue(ret != TD_SUCCESS, ENUM_SVP_ERR_LEVEL_DEBUG,
|
||||
"Error(%#x),ss_mpi_vpss_get_chn_frame failed, VPSS_GRP(%d), VPSS_CHN(%d)!\n", ret, vpss_grp, vpss_chn[1]);
|
||||
|
||||
ret = ss_mpi_vpss_get_chn_frame(vpss_grp, vpss_chn[0], &base_frm_info, OT_MACRO_IVE_OD_MILLI_SEC);
|
||||
macro_svp_check_failed_goto(ret, ext_free, ENUM_SVP_ERR_LEVEL_ERROR,
|
||||
"Error(%#x),ss_mpi_vpss_get_chn_frame failed, VPSS_GRP(%d), VPSS_CHN(%d)!\n", ret, vpss_grp, vpss_chn[0]);
|
||||
|
||||
/* prepare dma data */
|
||||
sample_ive_prepare_dma_data(od_ptr, &ext_frm_info, &src_data, &dst_data);
|
||||
|
||||
/* dma */
|
||||
ret = ss_mpi_ive_dma(&handle, &src_data, &dst_data, &dma_ctrl, TD_FALSE);
|
||||
macro_svp_check_failed_err_level_goto(ret, base_free, "Error(%#x),ss_mpi_ive_dma failed!\n", ret);
|
||||
|
||||
/* integ */
|
||||
ret = ss_mpi_ive_integ(&handle, &od_ptr->src, &od_ptr->integ, &od_ptr->integ_ctrl, TD_TRUE);
|
||||
macro_svp_check_failed_err_level_goto(ret, base_free, "Error(%#x),ss_mpi_ive_integ failed!\n", ret);
|
||||
|
||||
/* query task */
|
||||
ret = sample_ive_query_task(handle);
|
||||
macro_svp_check_failed_err_level_goto(ret, base_free, "ive_query_task failed!\n");
|
||||
|
||||
/* get result */
|
||||
ret = sample_ive_get_char_point(od_ptr, char_point, OT_IVE_CHAR_NUM);
|
||||
macro_svp_check_failed_err_level_goto(ret, base_free, "sample_ive_get_char_point failed!\n");
|
||||
|
||||
/* classify */
|
||||
ret = sample_ive_linear_2d_classifer(char_point, OT_IVE_CHAR_NUM, data.linear_point, data.linear_num);
|
||||
macro_svp_check_exps_trace(ret > data.thresh_num, ENUM_SVP_ERR_LEVEL_DEBUG,
|
||||
"\033[0;31m Occlusion detected!\033[0;39m\n");
|
||||
|
||||
/* send vo frame */
|
||||
ret = ss_mpi_vo_send_frame(0, 0, &base_frm_info, OT_MACRO_IVE_OD_MILLI_SEC);
|
||||
macro_svp_check_failed_err_level_goto(ret, base_free, "Error(%#x),sample_vo_send_frame failed!\n", ret);
|
||||
|
||||
base_free:
|
||||
ret = ss_mpi_vpss_release_chn_frame(vpss_grp, vpss_chn[0], &base_frm_info);
|
||||
macro_svp_check_exps_trace(ret != TD_SUCCESS, ENUM_SVP_ERR_LEVEL_DEBUG,
|
||||
"Error(%#x),release_frame failed,Grp(%d) chn(%d)!\n", ret, vpss_grp, vpss_chn[0]);
|
||||
|
||||
ext_free:
|
||||
ret = ss_mpi_vpss_release_chn_frame(vpss_grp, vpss_chn[1], &ext_frm_info);
|
||||
macro_svp_check_exps_trace(ret != TD_SUCCESS, ENUM_SVP_ERR_LEVEL_DEBUG,
|
||||
"Error(%#x),release_frame failed,Grp(%d) chn(%d)!\n", ret, vpss_grp, vpss_chn[1]);
|
||||
}
|
||||
return TD_NULL;
|
||||
}
|
||||
|
||||
static td_s32 sample_ive_od_pause(td_void)
|
||||
{
|
||||
printf("---------------press Enter key to exit!---------------\n");
|
||||
if (g_stop_signal == TD_TRUE) {
|
||||
if (g_ive_thread != 0) {
|
||||
pthread_join(g_ive_thread, TD_NULL);
|
||||
g_ive_thread = 0;
|
||||
}
|
||||
sample_ive_od_uninit(&(g_od_info));
|
||||
(td_void)memset_s(&g_od_info, sizeof(g_od_info), 0, sizeof(g_od_info));
|
||||
sample_common_svp_stop_vi_vpss_venc_vo(&g_vi_config, &g_od_switch);
|
||||
printf("\033[0;31mprogram termination abnormally!\033[0;39m\n");
|
||||
return TD_TRUE;
|
||||
}
|
||||
(void)getchar();
|
||||
if (g_stop_signal == TD_TRUE) {
|
||||
if (g_ive_thread != 0) {
|
||||
pthread_join(g_ive_thread, TD_NULL);
|
||||
g_ive_thread = 0;
|
||||
}
|
||||
sample_ive_od_uninit(&(g_od_info));
|
||||
(td_void)memset_s(&g_od_info, sizeof(g_od_info), 0, sizeof(g_od_info));
|
||||
sample_common_svp_stop_vi_vpss_venc_vo(&g_vi_config, &g_od_switch);
|
||||
printf("\033[0;31mprogram termination abnormally!\033[0;39m\n");
|
||||
return TD_TRUE;
|
||||
}
|
||||
return TD_FALSE;
|
||||
}
|
||||
|
||||
td_void libapi_ive_od(td_void)
|
||||
{
|
||||
td_s32 ret;
|
||||
ot_size pic_size;
|
||||
ot_enum_pic_size pic_type = PIC_1080P;
|
||||
|
||||
(td_void)memset_s(&g_od_info, sizeof(g_od_info), 0, sizeof(g_od_info));
|
||||
|
||||
/*
|
||||
* step 1: start vi vpss venc vo
|
||||
*/
|
||||
ret = sample_common_svp_start_vi_vpss_venc_vo(&g_vi_config, &g_od_switch, &pic_type);
|
||||
macro_svp_check_exps_goto(ret != TD_SUCCESS, end_od_0, ENUM_SVP_ERR_LEVEL_DEBUG,
|
||||
"Error(%#x),sample_common_svp_start_vi_vpss_venc_vo failed!\n", ret);
|
||||
|
||||
ret = libapi_comm_sys_get_pic_size(pic_type, &pic_size);
|
||||
macro_svp_check_exps_goto(ret != TD_SUCCESS, end_od_0, ENUM_SVP_ERR_LEVEL_DEBUG,
|
||||
"Error(%#x),libapi_comm_sys_get_pic_size failed!\n", ret);
|
||||
/*
|
||||
* step 2: Init OD
|
||||
*/
|
||||
ret = sample_ive_od_init(&g_od_info, pic_size.width, pic_size.height);
|
||||
macro_svp_check_exps_goto(ret != TD_SUCCESS, end_od_0, ENUM_SVP_ERR_LEVEL_DEBUG,
|
||||
"sample_ive_od_init failed, Error(%#x)!\n", ret);
|
||||
g_stop_signal = TD_FALSE;
|
||||
|
||||
/*
|
||||
* step 3: Create work thread
|
||||
*/
|
||||
ret = prctl(PR_SET_NAME, "ive_od_proc", 0, 0, 0);
|
||||
macro_svp_check_exps_goto(ret != TD_SUCCESS, end_od_0, ENUM_SVP_ERR_LEVEL_DEBUG, "set thread name failed!\n");
|
||||
ret = pthread_create(&g_ive_thread, 0, sample_ive_od_proc, (td_void *)&g_od_info);
|
||||
macro_svp_check_exps_goto(ret != TD_SUCCESS, end_od_0, ENUM_SVP_ERR_LEVEL_DEBUG, "pthread_create failed!\n");
|
||||
|
||||
ret = sample_ive_od_pause();
|
||||
macro_svp_check_exps_return_void(ret == TD_TRUE, ENUM_SVP_ERR_LEVEL_DEBUG, "od exit!\n");
|
||||
|
||||
g_stop_signal = TD_TRUE;
|
||||
pthread_join(g_ive_thread, TD_NULL);
|
||||
g_ive_thread = 0;
|
||||
sample_ive_od_uninit(&(g_od_info));
|
||||
(td_void)memset_s(&g_od_info, sizeof(g_od_info), 0, sizeof(g_od_info));
|
||||
|
||||
end_od_0:
|
||||
g_ive_thread = 0;
|
||||
g_stop_signal = TD_TRUE;
|
||||
sample_common_svp_stop_vi_vpss_venc_vo(&g_vi_config, &g_od_switch);
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* function : Od sample signal handle
|
||||
*/
|
||||
td_void libapi_ive_od_handle_sig(td_void)
|
||||
{
|
||||
g_stop_signal = TD_TRUE;
|
||||
}
|
240
libapi/ive/libapi_ive_persptrans.c
Executable file
@ -0,0 +1,240 @@
|
||||
/*
|
||||
Copyright (c), 2001-2022, Shenshu Tech. Co., Ltd.
|
||||
*/
|
||||
#include "libapi_common_ive.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#include <signal.h>
|
||||
#include <semaphore.h>
|
||||
#include <pthread.h>
|
||||
#include <limits.h>
|
||||
|
||||
#define OT_MACRO_IVE_PSP_ROI_NUM 64
|
||||
#define OT_MACRO_IVE_PSP_QUERY_SLEEP 100
|
||||
#define OT_MACRO_IVE_PSP_POINT_PAIR_NUM 5
|
||||
#define OT_PSP_NUM_TWO 2
|
||||
#define OT_PSP_NUM_THREE 3
|
||||
#define OT_PSP_NUM_FOUR 4
|
||||
#define OT_MACRO_IVE_PSP_LEFT_SHIT 2
|
||||
#define OT_MACRO_IVE_PSP_SRC_WIDTH 250
|
||||
#define OT_MACRO_IVE_PSP_SRC_HEIGHT 250
|
||||
#define OT_MACRO_IVE_PSP_DST_WIDTH 96
|
||||
#define OT_MACRO_IVE_PSP_DST_HEIGHT 112
|
||||
#define OT_MACRO_IVE_PSP_MAX_POINT_PAIR_NUM 68
|
||||
#define OT_MACRO_IVE_PSP_ROI_WIDTH 250
|
||||
#define OT_MACRO_IVE_PSP_ROI_HEIGHT 250
|
||||
|
||||
typedef struct {
|
||||
ot_svp_src_img src;
|
||||
ot_svp_rect_u32 roi[OT_MACRO_IVE_PSP_ROI_NUM];
|
||||
td_u16 roi_num;
|
||||
ot_svp_dst_img dst[OT_MACRO_IVE_PSP_ROI_NUM];
|
||||
ot_svp_src_mem_info point_pair[OT_MACRO_IVE_PSP_ROI_NUM];
|
||||
ot_ive_persp_trans_ctrl persp_trans_ctrl;
|
||||
|
||||
FILE *fp_src;
|
||||
FILE *fp_dst;
|
||||
} ot_struct_ive_persp_trans_info;
|
||||
|
||||
typedef struct {
|
||||
ot_svp_rect_u32 roi[OT_MACRO_IVE_PSP_ROI_NUM];
|
||||
td_u16 roi_num;
|
||||
td_u16 max_point_pair_num;
|
||||
} ot_struct_ive_psp_roi_info;
|
||||
|
||||
static ot_struct_ive_persp_trans_info g_persp_trans;
|
||||
static td_bool g_stop_signal = TD_FALSE;
|
||||
|
||||
static td_void _ive_persp_trans_uninit(ot_struct_ive_persp_trans_info *psp_info)
|
||||
{
|
||||
td_u16 i;
|
||||
|
||||
macro_svp_check_exps_return_void(psp_info == TD_NULL, ENUM_SVP_ERR_LEVEL_ERROR, "test_mem can't be null\n");
|
||||
|
||||
macro_svp_mmz_free(psp_info->src.phys_addr[0], psp_info->src.virt_addr[0]);
|
||||
|
||||
for (i = 0; i < psp_info->roi_num; i++) {
|
||||
macro_svp_mmz_free(psp_info->dst[i].phys_addr[0], psp_info->dst[i].virt_addr[0]);
|
||||
macro_svp_mmz_free(psp_info->point_pair[i].phys_addr, psp_info->point_pair[i].virt_addr);
|
||||
}
|
||||
|
||||
macro_svp_close_file(psp_info->fp_src);
|
||||
macro_svp_close_file(psp_info->fp_dst);
|
||||
}
|
||||
|
||||
static td_s32 _ive_persp_trans_proc(ot_struct_ive_persp_trans_info *persp_trans)
|
||||
{
|
||||
td_s32 ret = OT_ERR_IVE_NULL_PTR;
|
||||
ot_ive_handle handle;
|
||||
td_bool is_finish = TD_FALSE;
|
||||
td_bool is_block = TD_TRUE;
|
||||
td_bool is_instant = TD_TRUE;
|
||||
td_u32 i;
|
||||
|
||||
macro_svp_check_exps_return(persp_trans == TD_NULL, ret, ENUM_SVP_ERR_LEVEL_ERROR, "test_mem can't be null\n");
|
||||
for (i = 0; (i < 1) && (g_stop_signal == TD_FALSE); i++) {
|
||||
ret = libapi_common_ive_read_file(&(persp_trans->src), persp_trans->fp_src);
|
||||
macro_svp_check_exps_return(ret != TD_SUCCESS, ret, ENUM_SVP_ERR_LEVEL_ERROR,
|
||||
"Error(%#x),Read src file failed!\n", ret);
|
||||
|
||||
ret = ss_mpi_ive_persp_trans(&handle, &persp_trans->src, persp_trans->roi, persp_trans->point_pair,
|
||||
persp_trans->dst, &persp_trans->persp_trans_ctrl, is_instant);
|
||||
macro_svp_check_exps_return(ret != TD_SUCCESS, ret, ENUM_SVP_ERR_LEVEL_ERROR,
|
||||
"Error(%#x),ss_mpi_ive_persp_trans failed!\n", ret);
|
||||
|
||||
ret = ss_mpi_ive_query(handle, &is_finish, is_block);
|
||||
while (ret == OT_ERR_IVE_QUERY_TIMEOUT) {
|
||||
usleep(OT_MACRO_IVE_PSP_QUERY_SLEEP);
|
||||
ret = ss_mpi_ive_query(handle, &is_finish, is_block);
|
||||
}
|
||||
macro_svp_check_exps_return(ret != TD_SUCCESS, ret, ENUM_SVP_ERR_LEVEL_ERROR,
|
||||
"Error(%#x),ss_mpi_ive_query failed!\n", ret);
|
||||
|
||||
ret = libapi_common_ive_write_file(&persp_trans->dst[0], persp_trans->fp_dst);
|
||||
macro_svp_check_exps_return(ret != TD_SUCCESS, ret, ENUM_SVP_ERR_LEVEL_ERROR,
|
||||
"Error(%#x),Read src file failed!\n", ret);
|
||||
}
|
||||
return TD_SUCCESS;
|
||||
}
|
||||
|
||||
static td_void _ive_persp_trans_ctrl_init(ot_struct_ive_persp_trans_info *psp_info,
|
||||
ot_struct_ive_psp_roi_info psp_roi)
|
||||
{
|
||||
psp_info->persp_trans_ctrl.alg_mode = OT_IVE_PERSP_TRANS_ALG_MODE_AFFINE;
|
||||
psp_info->persp_trans_ctrl.csc_mode = OT_IVE_PERSP_TRANS_CSC_MODE_NONE;
|
||||
psp_info->persp_trans_ctrl.roi_num = psp_roi.roi_num;
|
||||
psp_info->persp_trans_ctrl.point_pair_num = OT_MACRO_IVE_PSP_POINT_PAIR_NUM;
|
||||
psp_info->roi_num = psp_roi.roi_num;
|
||||
}
|
||||
|
||||
static td_s32 _ive_persp_trans_init(ot_struct_ive_persp_trans_info *psp,
|
||||
ot_struct_src_dst_size data, ot_struct_ive_psp_roi_info psp_roi,
|
||||
const td_char *src_file, const td_char *dst_file)
|
||||
{
|
||||
td_s32 ret = OT_ERR_IVE_ILLEGAL_PARAM;
|
||||
td_u32 size, i, j;
|
||||
td_char path[PATH_MAX] = {0};
|
||||
td_u16 mark[] = { 107, 109, 30, 52, 149, 117, 66, 52, 123, 135, 48, 72, 99, 157, 34, 92, 144, 157, 63, 92 };
|
||||
ot_ive_persp_trans_point_pair *tmp = TD_NULL;
|
||||
|
||||
macro_svp_check_exps_return(psp == TD_NULL, OT_ERR_IVE_NULL_PTR, ENUM_SVP_ERR_LEVEL_ERROR, "psp is null\n");
|
||||
macro_svp_check_exps_return((strlen(src_file) > PATH_MAX) || (realpath(src_file, path) == TD_NULL),
|
||||
ret, ENUM_SVP_ERR_LEVEL_ERROR, "invalid file!\n");
|
||||
|
||||
size = sizeof(ot_svp_rect_u32) * psp_roi.roi_num;
|
||||
ret = memcpy_s(psp->roi, sizeof(ot_svp_rect_u32) * OT_MACRO_IVE_PSP_ROI_NUM, psp_roi.roi, size);
|
||||
macro_svp_check_exps_return(ret != EOK, OT_ERR_IVE_ILLEGAL_PARAM, ENUM_SVP_ERR_LEVEL_ERROR, "copy failed!\n");
|
||||
|
||||
ret = libapi_common_ive_create_image(&(psp->src), OT_SVP_IMG_TYPE_YUV420SP, data.src.width, data.src.height);
|
||||
macro_svp_check_failed_err_level_goto(ret, fail, "Error(%#x),Create src image failed!\n", ret);
|
||||
|
||||
for (i = 0; i < psp_roi.roi_num; i++) {
|
||||
ret = libapi_common_ive_create_image(&(psp->dst[i]), OT_SVP_IMG_TYPE_YUV420SP, data.dst.width, data.dst.height);
|
||||
macro_svp_check_failed_err_level_goto(ret, fail, "Error(%#x),Create src image failed!\n", ret);
|
||||
}
|
||||
|
||||
size = sizeof(ot_ive_persp_trans_point_pair) * psp_roi.max_point_pair_num;
|
||||
for (i = 0; i < psp_roi.roi_num; i++) {
|
||||
ret = libapi_common_ive_create_mem_info(&(psp->point_pair[i]), size);
|
||||
macro_svp_check_failed_err_level_goto(ret, fail, "Error(%#x),Create src image failed!\n", ret);
|
||||
}
|
||||
|
||||
_ive_persp_trans_ctrl_init(psp, psp_roi);
|
||||
for (i = 0; i < psp_roi.roi_num; i++) {
|
||||
tmp = (ot_ive_persp_trans_point_pair *)(td_uintptr_t)psp->point_pair[i].virt_addr;
|
||||
for (j = 0; (j < psp->persp_trans_ctrl.point_pair_num) && (j < OT_MACRO_IVE_PSP_POINT_PAIR_NUM); j++) {
|
||||
tmp->src_point.x = mark[j * OT_PSP_NUM_FOUR] << OT_MACRO_IVE_PSP_LEFT_SHIT;
|
||||
tmp->src_point.y = mark[j * OT_PSP_NUM_FOUR + 1] << OT_MACRO_IVE_PSP_LEFT_SHIT;
|
||||
tmp->src_point.x = mark[j * OT_PSP_NUM_FOUR + OT_PSP_NUM_TWO] << OT_MACRO_IVE_PSP_LEFT_SHIT;
|
||||
tmp->src_point.y = mark[j * OT_PSP_NUM_FOUR + OT_PSP_NUM_THREE] << OT_MACRO_IVE_PSP_LEFT_SHIT;
|
||||
tmp++;
|
||||
}
|
||||
}
|
||||
|
||||
/* open src file */
|
||||
ret = TD_FAILURE;
|
||||
psp->fp_src = fopen(path, "rb");
|
||||
macro_svp_check_exps_goto(psp->fp_src == TD_NULL, fail, ENUM_SVP_ERR_LEVEL_ERROR, "Open file failed!\n");
|
||||
|
||||
/* open dst file */
|
||||
macro_svp_check_exps_goto(realpath(dst_file, path) == NULL, fail, ENUM_SVP_ERR_LEVEL_ERROR, "invalid file!\n");
|
||||
ret = strcat_s(path, PATH_MAX, "/Amelia_Vega_Affine_96x112_420sp.yuv");
|
||||
macro_svp_check_exps_goto(ret != EOK, fail, ENUM_SVP_ERR_LEVEL_ERROR, "strcat_s failed!\n");
|
||||
ret = TD_FAILURE;
|
||||
psp->fp_dst = fopen(path, "wb");
|
||||
macro_svp_check_exps_goto(psp->fp_dst == TD_NULL, fail, ENUM_SVP_ERR_LEVEL_ERROR, "Open file failed!\n");
|
||||
|
||||
return TD_SUCCESS;
|
||||
fail:
|
||||
_ive_persp_trans_uninit(psp);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static td_void _ive_persp_trans_stop(td_void)
|
||||
{
|
||||
_ive_persp_trans_uninit(&g_persp_trans);
|
||||
(td_void)memset_s(&g_persp_trans, sizeof(g_persp_trans), 0, sizeof(g_persp_trans));
|
||||
libapi_common_ive_mpi_exit();
|
||||
printf("\033[0;31mprogram termination abnormally!\033[0;39m\n");
|
||||
}
|
||||
|
||||
td_void libapi_ive_persp_trans(td_void)
|
||||
{
|
||||
td_s32 ret;
|
||||
const td_char *src_file = "./data/input/psp/src/Amelia_Vega_250x250_420sp.yuv";
|
||||
const td_char *dst_file = "./data/output/psp";
|
||||
ot_struct_src_dst_size data;
|
||||
data.src.width = OT_MACRO_IVE_PSP_SRC_WIDTH;
|
||||
data.src.height = OT_MACRO_IVE_PSP_SRC_HEIGHT;
|
||||
data.dst.width = OT_MACRO_IVE_PSP_DST_WIDTH;
|
||||
data.dst.height = OT_MACRO_IVE_PSP_DST_HEIGHT;
|
||||
|
||||
ot_struct_ive_psp_roi_info psp_roi;
|
||||
psp_roi.roi_num = 1;
|
||||
psp_roi.max_point_pair_num = OT_MACRO_IVE_PSP_MAX_POINT_PAIR_NUM;
|
||||
psp_roi.roi[0].x = 0;
|
||||
psp_roi.roi[0].y = 0;
|
||||
psp_roi.roi[0].width = OT_MACRO_IVE_PSP_ROI_WIDTH;
|
||||
psp_roi.roi[0].height = OT_MACRO_IVE_PSP_ROI_HEIGHT;
|
||||
|
||||
(td_void)memset_s(&g_persp_trans, sizeof(g_persp_trans), 0, sizeof(g_persp_trans));
|
||||
ret = libapi_common_ive_check_mpi_init();
|
||||
macro_svp_check_exps_return_void(ret != TD_TRUE, ENUM_SVP_ERR_LEVEL_ERROR, "ive_check_mpi_init failed!\n");
|
||||
|
||||
ret = _ive_persp_trans_init(&g_persp_trans, data, psp_roi, src_file, dst_file);
|
||||
macro_svp_check_exps_goto(ret != TD_SUCCESS, persp_trans_fail, ENUM_SVP_ERR_LEVEL_ERROR,
|
||||
"Error(%#x),_ive_persp_trans_init failed!\n", ret);
|
||||
|
||||
ret = _ive_persp_trans_proc(&g_persp_trans);
|
||||
if (g_stop_signal == TD_TRUE) {
|
||||
_ive_persp_trans_stop();
|
||||
return;
|
||||
}
|
||||
if (ret == TD_SUCCESS) {
|
||||
macro_svp_trace_info("Process success!\n");
|
||||
}
|
||||
|
||||
g_stop_signal = TD_TRUE;
|
||||
_ive_persp_trans_uninit(&g_persp_trans);
|
||||
(td_void)memset_s(&g_persp_trans, sizeof(g_persp_trans), 0, sizeof(g_persp_trans));
|
||||
|
||||
persp_trans_fail:
|
||||
g_stop_signal = TD_TRUE;
|
||||
libapi_common_ive_mpi_exit();
|
||||
}
|
||||
|
||||
/*
|
||||
* function : PerspTrans sample signal handle
|
||||
*/
|
||||
td_void libapi_ive_persp_trans_handle_sig(td_void)
|
||||
{
|
||||
g_stop_signal = TD_TRUE;
|
||||
}
|
164
libapi/ive/libapi_ive_queue.c
Executable file
@ -0,0 +1,164 @@
|
||||
/*
|
||||
Copyright (c), 2001-2022, Shenshu Tech. Co., Ltd.
|
||||
*/
|
||||
#include "libapi_ive_queue.h"
|
||||
#include <malloc.h>
|
||||
#include "libapi_common_ive.h"
|
||||
|
||||
static td_s32 g_max_queue_len = 0;
|
||||
static td_s32 g_cur_queue_len = 0;
|
||||
|
||||
ot_struct_ive_queue *libapi_ive_create_queue(td_s32 len)
|
||||
{
|
||||
ot_struct_ive_queue *queue_head = TD_NULL;
|
||||
|
||||
if ((len < -1) || (len == 0)) {
|
||||
return TD_NULL;
|
||||
}
|
||||
g_cur_queue_len = 0;
|
||||
queue_head = (ot_struct_ive_queue *)malloc(sizeof(ot_struct_ive_queue));
|
||||
macro_svp_check_exps_return(queue_head == TD_NULL, TD_NULL, ENUM_SVP_ERR_LEVEL_ERROR, "malloc failed!\n");
|
||||
|
||||
queue_head->front = TD_NULL;
|
||||
queue_head->rear = TD_NULL;
|
||||
g_max_queue_len = len;
|
||||
|
||||
return queue_head;
|
||||
}
|
||||
|
||||
td_void libapi_ive_destory_queue(ot_struct_ive_queue **queue_head)
|
||||
{
|
||||
ot_struct_ive_node *queue_node_tmp = TD_NULL;
|
||||
if (queue_head == TD_NULL || (*queue_head) == TD_NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
queue_node_tmp = (*queue_head)->front;
|
||||
while (queue_node_tmp != TD_NULL) {
|
||||
(*queue_head)->front = queue_node_tmp->next;
|
||||
free(queue_node_tmp);
|
||||
queue_node_tmp = (*queue_head)->front;
|
||||
}
|
||||
(*queue_head)->rear = (*queue_head)->front;
|
||||
g_cur_queue_len = 0;
|
||||
free(*queue_head);
|
||||
(*queue_head) = TD_NULL;
|
||||
}
|
||||
|
||||
|
||||
td_void libapi_ive_clear_queue(ot_struct_ive_queue *queue_head)
|
||||
{
|
||||
ot_struct_ive_node *queue_node_tmp = TD_NULL;
|
||||
|
||||
if (queue_head == TD_NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
queue_node_tmp = queue_head->front;
|
||||
while (queue_node_tmp != TD_NULL) {
|
||||
queue_head->front = queue_node_tmp->next;
|
||||
free(queue_node_tmp);
|
||||
queue_node_tmp = queue_head->front;
|
||||
}
|
||||
queue_head->rear = queue_head->front;
|
||||
g_cur_queue_len = 0;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
td_bool libapi_ive_is_queue_empty(ot_struct_ive_queue *queue_head)
|
||||
{
|
||||
if (queue_head == TD_NULL) {
|
||||
return TD_TRUE;
|
||||
}
|
||||
|
||||
if (queue_head->front != TD_NULL) {
|
||||
return TD_FALSE;
|
||||
}
|
||||
|
||||
return TD_TRUE;
|
||||
}
|
||||
|
||||
td_s32 libapi_ive_queue_size(ot_struct_ive_queue *queue_head)
|
||||
{
|
||||
if (queue_head == TD_NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return g_cur_queue_len;
|
||||
}
|
||||
|
||||
td_s32 libapi_ive_add_queue_node(ot_struct_ive_queue *queue_head, ot_video_frame_info *added_frm_info)
|
||||
{
|
||||
ot_struct_ive_node *queue_node = TD_NULL;
|
||||
td_s32 ret;
|
||||
|
||||
if ((queue_head == TD_NULL) || (added_frm_info == TD_NULL)) {
|
||||
return QUEUE_NULL_POINTER;
|
||||
}
|
||||
|
||||
if ((g_max_queue_len != -1) && (g_cur_queue_len >= g_max_queue_len)) {
|
||||
return QUEUE_ILLEGAL_STATE;
|
||||
}
|
||||
|
||||
queue_node = (ot_struct_ive_node *)malloc(sizeof(ot_struct_ive_node));
|
||||
macro_svp_check_exps_return(queue_node == TD_NULL, QUEUE_OUT_OF_MEMORY,
|
||||
ENUM_SVP_ERR_LEVEL_ERROR, "malloc failed, out of memory!\n");
|
||||
|
||||
ret = memcpy_s(&queue_node->frame_info, sizeof(ot_video_frame_info),
|
||||
added_frm_info, sizeof(ot_video_frame_info));
|
||||
if (ret != EOK) {
|
||||
free(queue_node);
|
||||
macro_svp_check_exps_return(1, OT_ERR_IVE_ILLEGAL_PARAM,
|
||||
ENUM_SVP_ERR_LEVEL_ERROR, "memcpy_s node failed!\n");
|
||||
}
|
||||
queue_node->next = TD_NULL;
|
||||
if (libapi_ive_is_queue_empty(queue_head) != 0) {
|
||||
queue_head->front = queue_node;
|
||||
queue_head->rear = queue_node;
|
||||
} else {
|
||||
queue_head->rear->next = queue_node;
|
||||
queue_head->rear = queue_node;
|
||||
}
|
||||
|
||||
g_cur_queue_len++;
|
||||
|
||||
return TD_SUCCESS;
|
||||
}
|
||||
|
||||
ot_struct_ive_node *libapi_ive_get_queue_head_node(const ot_struct_ive_queue *queue_node)
|
||||
{
|
||||
if ((queue_node == TD_NULL) || (queue_node->front == TD_NULL)) {
|
||||
return TD_NULL;
|
||||
}
|
||||
|
||||
return queue_node->front;
|
||||
}
|
||||
|
||||
ot_struct_ive_node *libapi_ive_get_queue_node(ot_struct_ive_queue *queue_head)
|
||||
{
|
||||
ot_struct_ive_node *queue_node = TD_NULL;
|
||||
|
||||
if ((queue_head == TD_NULL) || (queue_head->front == TD_NULL)) {
|
||||
return TD_NULL;
|
||||
}
|
||||
|
||||
queue_node = queue_head->front;
|
||||
queue_head->front = queue_node->next;
|
||||
if (queue_head->front == TD_NULL) {
|
||||
queue_head->rear = queue_head->front;
|
||||
}
|
||||
g_cur_queue_len--;
|
||||
|
||||
return queue_node;
|
||||
}
|
||||
|
||||
td_void libapi_ive_free_queue_node(ot_struct_ive_node **free_node)
|
||||
{
|
||||
if (free_node != TD_NULL && (*free_node) != TD_NULL) {
|
||||
free(*free_node);
|
||||
*free_node = TD_NULL;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
50
libapi/ive/libapi_ive_queue.h
Executable file
@ -0,0 +1,50 @@
|
||||
/*
|
||||
Copyright (c), 2001-2022, Shenshu Tech. Co., Ltd.
|
||||
*/
|
||||
|
||||
#ifndef LIBAPI_IVE_QUEUE_H
|
||||
#define LIBAPI_IVE_QUEUE_H
|
||||
|
||||
#include "ot_type.h"
|
||||
#include "ot_common_video.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#endif /* __cplusplus */
|
||||
|
||||
typedef struct tag_ot_struct_ive_node {
|
||||
ot_video_frame_info frame_info;
|
||||
struct tag_ot_struct_ive_node *next;
|
||||
} ot_struct_ive_node;
|
||||
|
||||
typedef struct {
|
||||
ot_struct_ive_node *front, *rear;
|
||||
} ot_struct_ive_queue;
|
||||
|
||||
#define QUEUE_CORE_ERROR_BASE 1
|
||||
#define QUEUE_CORE_FRAMEWORK_ERROR_BASE (QUEUE_CORE_ERROR_BASE + 10000)
|
||||
|
||||
#define QUEUE_NULL_POINTER (QUEUE_CORE_FRAMEWORK_ERROR_BASE + 1)
|
||||
#define QUEUE_ILLEGAL_STATE (QUEUE_CORE_FRAMEWORK_ERROR_BASE + 2)
|
||||
#define QUEUE_OUT_OF_MEMORY (QUEUE_CORE_FRAMEWORK_ERROR_BASE + 3)
|
||||
|
||||
ot_struct_ive_queue *libapi_ive_create_queue(td_s32 len);
|
||||
td_void libapi_ive_destory_queue(ot_struct_ive_queue **queue_head);
|
||||
td_void libapi_ive_clear_queue(ot_struct_ive_queue *queue_head);
|
||||
td_bool libapi_ive_is_queue_empty(ot_struct_ive_queue *queue_head);
|
||||
td_s32 libapi_ive_queue_size(ot_struct_ive_queue *queue_head);
|
||||
td_s32 libapi_ive_add_queue_node(ot_struct_ive_queue *queue_head, ot_video_frame_info *added_frm_info);
|
||||
ot_struct_ive_node *libapi_ive_get_queue_head_node(const ot_struct_ive_queue *queue_head);
|
||||
ot_struct_ive_node *libapi_ive_get_queue_node(ot_struct_ive_queue *queue_head);
|
||||
td_void libapi_ive_free_queue_node(ot_struct_ive_node **free_node);
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* LIBAPI_IVE_QUEUE_H */
|
||||
|
295
libapi/ive/libapi_ive_sobel_with_cached_mem.c
Executable file
@ -0,0 +1,295 @@
|
||||
/*
|
||||
Copyright (c), 2001-2022, Shenshu Tech. Co., Ltd.
|
||||
*/
|
||||
#include "libapi_common_ive.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#include <signal.h>
|
||||
#include <semaphore.h>
|
||||
#include <pthread.h>
|
||||
#include <limits.h>
|
||||
#include <time.h>
|
||||
|
||||
#define OT_MACRO_IVE_SOBEL_QUERY_SLEEP 100
|
||||
#define OT_MACRO_IVE_SOBEL_SRC_WIDTH 720
|
||||
#define OT_MACRO_IVE_SOBEL_SRC_HEIGHT 576
|
||||
|
||||
typedef struct {
|
||||
ot_svp_src_img src1;
|
||||
ot_svp_src_img src2;
|
||||
ot_svp_dst_img dst_h1;
|
||||
ot_svp_dst_img dst_h2;
|
||||
ot_svp_dst_img dst_v1;
|
||||
ot_svp_dst_img dst_v2;
|
||||
ot_ive_sobel_ctrl sobel_ctrl;
|
||||
FILE *fp_src;
|
||||
FILE *fp_dst_h1;
|
||||
FILE *fp_dst_h2;
|
||||
FILE *fp_dst_v1;
|
||||
FILE *fp_dst_v2;
|
||||
} ot_struct_ive_sobel_info;
|
||||
|
||||
static td_bool g_is_flush_cached = TD_TRUE;
|
||||
static ot_struct_ive_sobel_info g_sobel_info;
|
||||
static td_bool g_stop_signal = TD_FALSE;
|
||||
|
||||
/*
|
||||
* function : show Sobel uninit
|
||||
*/
|
||||
static td_void _ive_sobel_uninit(ot_struct_ive_sobel_info *sobel)
|
||||
{
|
||||
macro_svp_check_exps_return_void(sobel == TD_NULL, ENUM_SVP_ERR_LEVEL_ERROR, "test_mem can't be null\n");
|
||||
|
||||
macro_svp_mmz_free(sobel->src1.phys_addr[0], sobel->src1.virt_addr[0]);
|
||||
macro_svp_mmz_free(sobel->src2.phys_addr[0], sobel->src2.virt_addr[0]);
|
||||
macro_svp_mmz_free(sobel->dst_h1.phys_addr[0], sobel->dst_h1.virt_addr[0]);
|
||||
macro_svp_mmz_free(sobel->dst_h2.phys_addr[0], sobel->dst_h2.virt_addr[0]);
|
||||
macro_svp_mmz_free(sobel->dst_v1.phys_addr[0], sobel->dst_v1.virt_addr[0]);
|
||||
macro_svp_mmz_free(sobel->dst_v2.phys_addr[0], sobel->dst_v2.virt_addr[0]);
|
||||
|
||||
macro_svp_close_file(sobel->fp_src);
|
||||
macro_svp_close_file(sobel->fp_dst_h1);
|
||||
macro_svp_close_file(sobel->fp_dst_h2);
|
||||
macro_svp_close_file(sobel->fp_dst_v1);
|
||||
macro_svp_close_file(sobel->fp_dst_v2);
|
||||
}
|
||||
|
||||
static td_s32 _ive_sobel_create_img(ot_struct_ive_sobel_info *sobel, td_u32 width, td_u32 height)
|
||||
{
|
||||
td_s32 ret;
|
||||
ret = libapi_common_ive_create_image_by_cached(&(sobel->src1), OT_SVP_IMG_TYPE_U8C1, width, height);
|
||||
macro_svp_check_exps_return(ret != TD_SUCCESS, ret, ENUM_SVP_ERR_LEVEL_ERROR,
|
||||
"Error(%#x),Create src1 image failed!\n", ret);
|
||||
|
||||
ret = libapi_common_ive_create_image_by_cached(&(sobel->src2), OT_SVP_IMG_TYPE_U8C1, width, height);
|
||||
macro_svp_check_exps_return(ret != TD_SUCCESS, ret, ENUM_SVP_ERR_LEVEL_ERROR,
|
||||
"Error(%#x),Create src2 image failed!\n", ret);
|
||||
|
||||
ret = libapi_common_ive_create_image(&(sobel->dst_h1), OT_SVP_IMG_TYPE_S16C1, width, height);
|
||||
macro_svp_check_exps_return(ret != TD_SUCCESS, ret, ENUM_SVP_ERR_LEVEL_ERROR,
|
||||
"Error(%#x),Create dstH1 image failed!\n", ret);
|
||||
|
||||
ret = libapi_common_ive_create_image(&(sobel->dst_h2), OT_SVP_IMG_TYPE_S16C1, width, height);
|
||||
macro_svp_check_exps_return(ret != TD_SUCCESS, ret, ENUM_SVP_ERR_LEVEL_ERROR,
|
||||
"Error(%#x),Create dstH2 image failed!\n", ret);
|
||||
|
||||
ret = libapi_common_ive_create_image(&(sobel->dst_v1), OT_SVP_IMG_TYPE_S16C1, width, height);
|
||||
macro_svp_check_exps_return(ret != TD_SUCCESS, ret, ENUM_SVP_ERR_LEVEL_ERROR,
|
||||
"Error(%#x),Create dstV1 image failed!\n", ret);
|
||||
|
||||
ret = libapi_common_ive_create_image(&(sobel->dst_v2), OT_SVP_IMG_TYPE_S16C1, width, height);
|
||||
macro_svp_check_exps_return(ret != TD_SUCCESS, ret, ENUM_SVP_ERR_LEVEL_ERROR,
|
||||
"Error(%#x),Create dstV2 image failed!\n", ret);
|
||||
return TD_SUCCESS;
|
||||
}
|
||||
|
||||
/*
|
||||
* function : show Sobel init
|
||||
*/
|
||||
static td_s32 _ive_sobel_init(ot_struct_ive_sobel_info *sobel, td_u32 width, td_u32 height)
|
||||
{
|
||||
td_s32 ret = OT_ERR_IVE_NULL_PTR;
|
||||
td_char path[PATH_MAX] = {0};
|
||||
td_s8 mask[OT_IVE_MASK_NUM] = { 0, 0, 0, 0, 0, 0, -1, 0, 1, 0, 0, -2, 0, 2, 0, 0, -1, 0, 1, 0, 0, 0, 0, 0, 0 };
|
||||
// const td_char *src_sobel = "./data/input/sobel/sobel.yuv";
|
||||
// const td_char *file = "./data/output/sobel";
|
||||
const td_char *src_sobel = "./sobel.yuv";
|
||||
const td_char *file = "./";
|
||||
|
||||
macro_svp_check_exps_return(sobel == TD_NULL, ret, ENUM_SVP_ERR_LEVEL_ERROR, "test_mem can't be null\n");
|
||||
(td_void)memset_s(sobel, sizeof(ot_struct_ive_sobel_info), 0, sizeof(ot_struct_ive_sobel_info));
|
||||
|
||||
sobel->sobel_ctrl.out_ctrl = OT_IVE_SOBEL_OUT_CTRL_BOTH;
|
||||
ret = memcpy_s(sobel->sobel_ctrl.mask, OT_IVE_MASK_NUM, mask, OT_IVE_MASK_NUM);
|
||||
macro_svp_check_exps_return(ret != EOK, OT_ERR_IVE_ILLEGAL_PARAM,
|
||||
ENUM_SVP_ERR_LEVEL_ERROR, "memcpy_s mask failed!\n");
|
||||
|
||||
ret = _ive_sobel_create_img(sobel, width, height);
|
||||
macro_svp_check_exps_goto(ret != TD_SUCCESS, fail, ENUM_SVP_ERR_LEVEL_ERROR,
|
||||
"Error(%#x),Sobel create image failed!\n", ret);
|
||||
|
||||
ret = TD_FAILURE;
|
||||
macro_svp_check_exps_goto((realpath(src_sobel, path) == NULL) || (strlen(src_sobel) > PATH_MAX),
|
||||
fail, ENUM_SVP_ERR_LEVEL_ERROR, "invalid file!\n");
|
||||
// macro_svp_trace_info("path:%s\n", path);
|
||||
sobel->fp_src = fopen(path, "rb");
|
||||
macro_svp_check_exps_goto(sobel->fp_src == TD_NULL, fail, ENUM_SVP_ERR_LEVEL_ERROR, "Open file failed!\n");
|
||||
|
||||
/* sobelh1 */
|
||||
macro_svp_check_exps_goto(realpath(file, path) == NULL, fail, ENUM_SVP_ERR_LEVEL_ERROR, "invalid file!\n");
|
||||
ret = strcat_s(path, PATH_MAX, "/sobelh1.dat");
|
||||
macro_svp_check_exps_goto(ret != EOK, fail, ENUM_SVP_ERR_LEVEL_ERROR, "strcat_s failed!\n");
|
||||
ret = TD_FAILURE;
|
||||
sobel->fp_dst_h1 = fopen(path, "wb");
|
||||
macro_svp_check_exps_goto(sobel->fp_dst_h1 == TD_NULL, fail, ENUM_SVP_ERR_LEVEL_ERROR, "Open file failed!\n");
|
||||
|
||||
/* sobelh2 */
|
||||
macro_svp_check_exps_goto(realpath(file, path) == NULL, fail, ENUM_SVP_ERR_LEVEL_ERROR, "invalid file!\n");
|
||||
ret = strcat_s(path, PATH_MAX, "/sobelh2.dat");
|
||||
macro_svp_check_exps_goto(ret != EOK, fail, ENUM_SVP_ERR_LEVEL_ERROR, "strcat_s failed!\n");
|
||||
ret = TD_FAILURE;
|
||||
sobel->fp_dst_h2 = fopen(path, "wb");
|
||||
macro_svp_check_exps_goto(sobel->fp_dst_h2 == TD_NULL, fail, ENUM_SVP_ERR_LEVEL_ERROR, "Open file failed!\n");
|
||||
|
||||
/* sobelv1 */
|
||||
macro_svp_check_exps_goto(realpath(file, path) == NULL, fail, ENUM_SVP_ERR_LEVEL_ERROR, "invalid file!\n");
|
||||
ret = strcat_s(path, PATH_MAX, "/sobelv1.dat");
|
||||
macro_svp_check_exps_goto(ret != EOK, fail, ENUM_SVP_ERR_LEVEL_ERROR, "strcat_s failed!\n");
|
||||
ret = TD_FAILURE;
|
||||
sobel->fp_dst_v1 = fopen(path, "wb");
|
||||
macro_svp_check_exps_goto(sobel->fp_dst_v1 == TD_NULL, fail, ENUM_SVP_ERR_LEVEL_ERROR, "Open file failed!\n");
|
||||
|
||||
/* sobelv2 */
|
||||
macro_svp_check_exps_goto(realpath(file, path) == NULL, fail, ENUM_SVP_ERR_LEVEL_ERROR, "invalid file!\n");
|
||||
ret = strcat_s(path, PATH_MAX, "/sobelv2.dat");
|
||||
macro_svp_check_exps_goto(ret != EOK, fail, ENUM_SVP_ERR_LEVEL_ERROR, "strcat_s failed!\n");
|
||||
ret = TD_FAILURE;
|
||||
sobel->fp_dst_v2 = fopen(path, "wb");
|
||||
macro_svp_check_exps_goto(sobel->fp_dst_v2 == TD_NULL, fail, ENUM_SVP_ERR_LEVEL_ERROR, "Open file failed!\n");
|
||||
|
||||
return TD_SUCCESS;
|
||||
fail:
|
||||
_ive_sobel_uninit(sobel);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static td_s32 _ive_sobel_query_task(ot_ive_handle handle)
|
||||
{
|
||||
td_s32 ret;
|
||||
td_bool is_block = TD_TRUE;
|
||||
td_bool is_finish = TD_FALSE;
|
||||
|
||||
ret = ss_mpi_ive_query(handle, &is_finish, is_block);
|
||||
while (ret == OT_ERR_IVE_QUERY_TIMEOUT) {
|
||||
usleep(OT_MACRO_IVE_SOBEL_QUERY_SLEEP);
|
||||
ret = ss_mpi_ive_query(handle, &is_finish, is_block);
|
||||
}
|
||||
macro_svp_check_exps_return(ret != TD_SUCCESS, ret, ENUM_SVP_ERR_LEVEL_ERROR,
|
||||
"Error(%#x),ss_mpi_ive_query failed!\n", ret);
|
||||
|
||||
return TD_SUCCESS;
|
||||
}
|
||||
/*
|
||||
* function : show Sobel proc
|
||||
*/
|
||||
static td_s32 _ive_sobel_proc(ot_struct_ive_sobel_info *sobel)
|
||||
{
|
||||
td_s32 ret = OT_ERR_IVE_NULL_PTR;
|
||||
td_bool is_instant = TD_TRUE;
|
||||
ot_ive_handle handle;
|
||||
td_u32 i;
|
||||
|
||||
macro_svp_check_exps_return(sobel == TD_NULL, ret, ENUM_SVP_ERR_LEVEL_ERROR, "test_mem can't be null\n");
|
||||
|
||||
for (i = 0; (i < 1) && (g_stop_signal == TD_FALSE); i++) {
|
||||
ret = libapi_common_ive_read_file(&(sobel->src1), sobel->fp_src);
|
||||
macro_svp_check_exps_return(ret != TD_SUCCESS, ret, ENUM_SVP_ERR_LEVEL_ERROR, "read src file failed!\n");
|
||||
|
||||
ret = memcpy_s(macro_svp_convert_addr_to_ptr(td_void, sobel->src2.virt_addr[0]),
|
||||
sobel->src2.stride[0] * sobel->src2.height,
|
||||
macro_svp_convert_addr_to_ptr(td_void, sobel->src1.virt_addr[0]),
|
||||
sobel->src2.stride[0] * sobel->src2.height);
|
||||
macro_svp_check_exps_return(ret != EOK, OT_ERR_IVE_ILLEGAL_PARAM,
|
||||
ENUM_SVP_ERR_LEVEL_ERROR, "memcpy_s src failed!\n");
|
||||
|
||||
ret = ss_mpi_sys_flush_cache(sobel->src1.phys_addr[0], macro_svp_convert_addr_to_ptr(td_void,
|
||||
sobel->src1.virt_addr[0]), sobel->src1.stride[0] * sobel->src1.height);
|
||||
macro_svp_check_exps_return(ret != TD_SUCCESS, ret, ENUM_SVP_ERR_LEVEL_ERROR,
|
||||
"Error(%#x),ss_mpi_sys_flush_cache failed!\n", ret);
|
||||
|
||||
ret = ss_mpi_ive_sobel(&handle, &sobel->src1, &sobel->dst_h1, &sobel->dst_v1, &sobel->sobel_ctrl, is_instant);
|
||||
macro_svp_check_exps_return(ret != TD_SUCCESS, ret, ENUM_SVP_ERR_LEVEL_ERROR, "ss_mpi_ive_sobel failed!\n");
|
||||
|
||||
ret = _ive_sobel_query_task(handle);
|
||||
macro_svp_check_exps_return(ret != TD_SUCCESS, ret, ENUM_SVP_ERR_LEVEL_ERROR, "sobel_query_task failed!\n");
|
||||
|
||||
ret = libapi_common_ive_write_file(&sobel->dst_h1, sobel->fp_dst_h1);
|
||||
macro_svp_check_exps_return(ret != TD_SUCCESS, ret, ENUM_SVP_ERR_LEVEL_ERROR, "write dstH1 failed!\n");
|
||||
|
||||
ret = libapi_common_ive_write_file(&sobel->dst_v1, sobel->fp_dst_v1);
|
||||
macro_svp_check_exps_return(ret != TD_SUCCESS, ret, ENUM_SVP_ERR_LEVEL_ERROR, "write dstV1 failed!\n");
|
||||
|
||||
/* The result of sobel my be error,if you do not call ss_mpi_sys_flush_cache to flush cache */
|
||||
if (g_is_flush_cached == TD_TRUE) {
|
||||
ret = ss_mpi_sys_flush_cache(sobel->src2.phys_addr[0], macro_svp_convert_addr_to_ptr(td_void,
|
||||
sobel->src2.virt_addr[0]), sobel->src2.stride[0] * sobel->src2.height);
|
||||
macro_svp_check_exps_return(ret != TD_SUCCESS, ret, ENUM_SVP_ERR_LEVEL_ERROR,
|
||||
"Error(%#x),ss_mpi_sys_flush_cache failed!\n", ret);
|
||||
}
|
||||
|
||||
ret = ss_mpi_ive_sobel(&handle, &sobel->src2, &sobel->dst_h2, &sobel->dst_v2, &sobel->sobel_ctrl, is_instant);
|
||||
macro_svp_check_exps_return(ret != TD_SUCCESS, ret, ENUM_SVP_ERR_LEVEL_ERROR, "ss_mpi_ive_sobel failed!\n");
|
||||
|
||||
ret = _ive_sobel_query_task(handle);
|
||||
macro_svp_check_exps_return(ret != TD_SUCCESS, ret, ENUM_SVP_ERR_LEVEL_ERROR, "sobel_query_task failed!\n");
|
||||
|
||||
ret = libapi_common_ive_write_file(&sobel->dst_h2, sobel->fp_dst_h2);
|
||||
macro_svp_check_exps_return(ret != TD_SUCCESS, ret, ENUM_SVP_ERR_LEVEL_ERROR, "write dstH2 failed!\n");
|
||||
|
||||
ret = libapi_common_ive_write_file(&sobel->dst_v2, sobel->fp_dst_v2);
|
||||
macro_svp_check_exps_return(ret != TD_SUCCESS, ret, ENUM_SVP_ERR_LEVEL_ERROR, "write dstV2 failed!\n");
|
||||
}
|
||||
return TD_SUCCESS;
|
||||
}
|
||||
|
||||
static td_void _ive_sobel_stop(td_void)
|
||||
{
|
||||
_ive_sobel_uninit(&g_sobel_info);
|
||||
(td_void)memset_s(&g_sobel_info, sizeof(g_sobel_info), 0, sizeof(g_sobel_info));
|
||||
libapi_common_ive_mpi_exit();
|
||||
printf("\033[0;31mprogram termination abnormally!\033[0;39m\n");
|
||||
}
|
||||
/*
|
||||
* function : show Sobel sample
|
||||
*/
|
||||
td_void libapi_ive_sobel(td_void)
|
||||
{
|
||||
macro_svp_trace_info("libapi_ive_sobel start!\n");
|
||||
td_s32 ret;
|
||||
const td_u32 width = OT_MACRO_IVE_SOBEL_SRC_WIDTH;
|
||||
const td_u32 height = OT_MACRO_IVE_SOBEL_SRC_HEIGHT;
|
||||
|
||||
(td_void)memset_s(&g_sobel_info, sizeof(g_sobel_info), 0, sizeof(g_sobel_info));
|
||||
ret = libapi_common_ive_check_mpi_init();
|
||||
macro_svp_check_exps_return_void(ret != TD_TRUE, ENUM_SVP_ERR_LEVEL_ERROR, "ive_check_mpi_init failed!\n");
|
||||
|
||||
ret = _ive_sobel_init(&g_sobel_info, width, height);
|
||||
macro_svp_check_exps_goto(ret != TD_SUCCESS, sobel_fail, ENUM_SVP_ERR_LEVEL_ERROR,
|
||||
"Error(%#x),_ive_sobel_init failed!\n", ret);
|
||||
|
||||
ret = _ive_sobel_proc(&g_sobel_info);
|
||||
if (g_stop_signal == TD_TRUE) {
|
||||
_ive_sobel_stop();
|
||||
return;
|
||||
}
|
||||
if (ret == TD_SUCCESS) {
|
||||
macro_svp_trace_info("Process success!\n");
|
||||
} else {
|
||||
macro_svp_trace_err("sobel process failed!\n");
|
||||
}
|
||||
|
||||
g_stop_signal = TD_TRUE;
|
||||
_ive_sobel_uninit(&g_sobel_info);
|
||||
(td_void)memset_s(&g_sobel_info, sizeof(g_sobel_info), 0, sizeof(g_sobel_info));
|
||||
|
||||
sobel_fail:
|
||||
g_stop_signal = TD_TRUE;
|
||||
libapi_common_ive_mpi_exit();
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* function : Sobel demo signal handle
|
||||
*/
|
||||
td_void libapi_ive_sobel_handle_sig(td_void)
|
||||
{
|
||||
g_stop_signal = TD_TRUE;
|
||||
}
|
480
libapi/ive/libapi_ive_st_and_lk.c
Executable file
@ -0,0 +1,480 @@
|
||||
/*
|
||||
Copyright (c), 2001-2022, Shenshu Tech. Co., Ltd.
|
||||
*/
|
||||
#include "libapi_common_ive.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#include <signal.h>
|
||||
#include <semaphore.h>
|
||||
#include <pthread.h>
|
||||
#include <limits.h>
|
||||
|
||||
#define OT_MACRO_IVE_LK_MAX_POINT_NUM 500
|
||||
#define OT_MACRO_IVE_LK_MIN_DIST 5
|
||||
#define OT_MACRO_IVE_LK_PYR_NUM 4
|
||||
#define OT_MACRO_IVE_LK_QUERY_SLEEP 100
|
||||
#define OT_MACRO_IVE_LK_MIN_EIG_VALUE 100
|
||||
#define OT_MACRO_IVE_LK_ITER_CNT 10
|
||||
#define OT_MACRO_IVE_LK_EPS 2
|
||||
#define OT_MACRO_IVE_LEFT_SHIFT_SEVEN 7
|
||||
#define OT_MACRO_IVE_ST_QUALITY_LEVEL 25
|
||||
#define OT_MACRO_IVE_LK_D1_WIDTH 720
|
||||
#define OT_MACRO_IVE_LK_D1_HEIGHT 576
|
||||
#define OT_MACRO_IVE_LK_MAX_LEVEL 3
|
||||
#define OT_MACRO_IVE_LK_FRAME_NUM 10
|
||||
|
||||
typedef struct {
|
||||
ot_svp_src_img prev_pyr[OT_MACRO_IVE_LK_PYR_NUM];
|
||||
ot_svp_src_img next_pyr[OT_MACRO_IVE_LK_PYR_NUM];
|
||||
ot_svp_src_mem_info prev_points;
|
||||
ot_svp_mem_info next_points;
|
||||
ot_svp_dst_mem_info status;
|
||||
ot_svp_dst_mem_info err;
|
||||
ot_ive_lk_optical_flow_pyr_ctrl lk_pyr_ctrl;
|
||||
|
||||
ot_svp_src_img src;
|
||||
ot_svp_img dst;
|
||||
ot_svp_dst_mem_info corner;
|
||||
ot_ive_st_cand_corner_ctrl cand_corner_ctrl;
|
||||
ot_ive_st_corner_ctrl corner_ctrl;
|
||||
|
||||
ot_svp_img pyr_tmp;
|
||||
ot_svp_img src_yuv;
|
||||
FILE *fp_src;
|
||||
} ot_struct_ive_st_lk_inf;
|
||||
|
||||
static ot_struct_ive_st_lk_inf g_lk_info;
|
||||
static td_bool g_stop_signal = TD_FALSE;
|
||||
|
||||
static td_s32 _ive_st_lk_dma(ot_ive_handle *ive_handle, ot_svp_src_img *src,
|
||||
ot_svp_dst_img *dst, ot_ive_dma_ctrl *dma_ctrl, td_bool is_instant)
|
||||
{
|
||||
td_s32 ret;
|
||||
ot_svp_src_data data_src;
|
||||
ot_svp_dst_data data_dst;
|
||||
|
||||
data_src.virt_addr = src->virt_addr[0];
|
||||
data_src.phys_addr = src->phys_addr[0];
|
||||
data_src.width = src->width;
|
||||
data_src.height = src->height;
|
||||
data_src.stride = src->stride[0];
|
||||
|
||||
data_dst.virt_addr = dst->virt_addr[0];
|
||||
data_dst.phys_addr = dst->phys_addr[0];
|
||||
data_dst.width = dst->width;
|
||||
data_dst.height = dst->height;
|
||||
data_dst.stride = dst->stride[0];
|
||||
ret = ss_mpi_ive_dma(ive_handle, &data_src, &data_dst, dma_ctrl, is_instant);
|
||||
macro_svp_check_exps_return(ret != TD_SUCCESS, ret, ENUM_SVP_ERR_LEVEL_ERROR,
|
||||
"Error(%#x),ss_mpi_ive_dma failed!\n", ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* function : Copy pyr
|
||||
*/
|
||||
static td_void _ive_st_lk_copy_pyr(ot_svp_src_img pyr_src[], ot_svp_dst_img pyr_dst[],
|
||||
td_u8 max_level)
|
||||
{
|
||||
td_u8 i;
|
||||
td_s32 ret;
|
||||
ot_ive_handle handle;
|
||||
|
||||
ot_ive_dma_ctrl dma_ctrl;
|
||||
(td_void)memset_s(&dma_ctrl, sizeof(dma_ctrl), 0, sizeof(dma_ctrl));
|
||||
dma_ctrl.mode = OT_IVE_DMA_MODE_DIRECT_COPY;
|
||||
|
||||
for (i = 0; i <= max_level; i++) {
|
||||
ret = _ive_st_lk_dma(&handle, &pyr_src[i], &pyr_dst[i], &dma_ctrl, TD_FALSE);
|
||||
if (ret != TD_SUCCESS) {
|
||||
macro_svp_trace_err("_ive_st_lk_dma fail,Error(%d)\n", ret);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* function : St lk uninit
|
||||
*/
|
||||
static td_void _ive_st_lk_uninit(ot_struct_ive_st_lk_inf *lk_info)
|
||||
{
|
||||
td_u16 i;
|
||||
|
||||
macro_svp_check_exps_return_void(lk_info == TD_NULL, ENUM_SVP_ERR_LEVEL_ERROR, "test_mem can't be null\n");
|
||||
|
||||
for (i = 0; i <= lk_info->lk_pyr_ctrl.max_level; i++) {
|
||||
macro_svp_mmz_free(lk_info->prev_pyr[i].phys_addr[0], lk_info->prev_pyr[i].virt_addr[0]);
|
||||
macro_svp_mmz_free(lk_info->next_pyr[i].phys_addr[0], lk_info->next_pyr[i].virt_addr[0]);
|
||||
}
|
||||
|
||||
macro_svp_mmz_free(lk_info->prev_points.phys_addr, lk_info->prev_points.virt_addr);
|
||||
macro_svp_mmz_free(lk_info->next_points.phys_addr, lk_info->next_points.virt_addr);
|
||||
macro_svp_mmz_free(lk_info->status.phys_addr, lk_info->status.virt_addr);
|
||||
macro_svp_mmz_free(lk_info->err.phys_addr, lk_info->err.virt_addr);
|
||||
|
||||
macro_svp_mmz_free(lk_info->src.phys_addr[0], lk_info->src.virt_addr[0]);
|
||||
macro_svp_mmz_free(lk_info->dst.phys_addr[0], lk_info->dst.virt_addr[0]);
|
||||
macro_svp_mmz_free(lk_info->corner.phys_addr, lk_info->corner.virt_addr);
|
||||
|
||||
macro_svp_mmz_free(lk_info->cand_corner_ctrl.mem.phys_addr, lk_info->cand_corner_ctrl.mem.virt_addr);
|
||||
|
||||
macro_svp_mmz_free(lk_info->pyr_tmp.phys_addr[0], lk_info->pyr_tmp.virt_addr[0]);
|
||||
macro_svp_mmz_free(lk_info->src_yuv.phys_addr[0], lk_info->src_yuv.virt_addr[0]);
|
||||
|
||||
macro_svp_close_file(lk_info->fp_src);
|
||||
}
|
||||
|
||||
static td_s32 _ive_lk_param_init(ot_struct_ive_st_lk_inf *lk_info, ot_size src_size, td_u8 max_level)
|
||||
{
|
||||
td_s32 ret;
|
||||
td_u32 size;
|
||||
td_u32 i;
|
||||
lk_info->lk_pyr_ctrl.out_mode = OT_IVE_LK_OPTICAL_FLOW_PYR_OUT_MODE_BOTH;
|
||||
lk_info->lk_pyr_ctrl.use_init_flow = TD_TRUE;
|
||||
lk_info->lk_pyr_ctrl.points_num = OT_MACRO_IVE_LK_MAX_POINT_NUM;
|
||||
lk_info->lk_pyr_ctrl.max_level = max_level;
|
||||
lk_info->lk_pyr_ctrl.min_eig_val_threshold = OT_MACRO_IVE_LK_MIN_EIG_VALUE;
|
||||
lk_info->lk_pyr_ctrl.iter_cnt = OT_MACRO_IVE_LK_ITER_CNT;
|
||||
lk_info->lk_pyr_ctrl.eps = OT_MACRO_IVE_LK_EPS;
|
||||
/* Init Pyr */
|
||||
for (i = 0; i <= max_level; i++) {
|
||||
ret = libapi_common_ive_create_image(&lk_info->prev_pyr[i], OT_SVP_IMG_TYPE_U8C1,
|
||||
src_size.width >> i, src_size.height >> i);
|
||||
macro_svp_check_exps_goto(ret != TD_SUCCESS, lk_init_fail, ENUM_SVP_ERR_LEVEL_ERROR,
|
||||
"Error(%#x),Create prevPyr[%d] image failed!\n", ret, i);
|
||||
|
||||
ret = libapi_common_ive_create_image(&lk_info->next_pyr[i], OT_SVP_IMG_TYPE_U8C1,
|
||||
lk_info->prev_pyr[i].width, lk_info->prev_pyr[i].height);
|
||||
macro_svp_check_exps_goto(ret != TD_SUCCESS, lk_init_fail, ENUM_SVP_ERR_LEVEL_ERROR,
|
||||
"Error(%#x),Create nextPyr[%d] image failed!\n", ret, i);
|
||||
}
|
||||
/* Init prev pts */
|
||||
size = sizeof(ot_svp_point_s25q7) * OT_MACRO_IVE_LK_MAX_POINT_NUM;
|
||||
size = libapi_common_ive_calc_stride(size, OT_IVE_ALIGN);
|
||||
ret = libapi_common_ive_create_mem_info(&(lk_info->prev_points), size);
|
||||
macro_svp_check_exps_goto(ret != TD_SUCCESS, lk_init_fail, ENUM_SVP_ERR_LEVEL_ERROR,
|
||||
"Error(%#x),Create prevPts mem info failed!\n", ret);
|
||||
/* Init next pts */
|
||||
ret = libapi_common_ive_create_mem_info(&(lk_info->next_points), size);
|
||||
macro_svp_check_exps_goto(ret != TD_SUCCESS, lk_init_fail, ENUM_SVP_ERR_LEVEL_ERROR,
|
||||
"Error(%#x),Create nextPts mem info failed!\n", ret);
|
||||
|
||||
/* Init status */
|
||||
size = sizeof(td_u8) * OT_MACRO_IVE_LK_MAX_POINT_NUM;
|
||||
size = libapi_common_ive_calc_stride(size, OT_IVE_ALIGN);
|
||||
ret = libapi_common_ive_create_mem_info(&(lk_info->status), size);
|
||||
macro_svp_check_exps_goto(ret != TD_SUCCESS, lk_init_fail, ENUM_SVP_ERR_LEVEL_ERROR,
|
||||
"Error(%#x),Create status mem info failed!\n", ret);
|
||||
|
||||
/* Init err */
|
||||
size = sizeof(td_u9q7) * OT_MACRO_IVE_LK_MAX_POINT_NUM;
|
||||
size = libapi_common_ive_calc_stride(size, OT_IVE_ALIGN);
|
||||
ret = libapi_common_ive_create_mem_info(&(lk_info->err), size);
|
||||
macro_svp_check_exps_goto(ret != TD_SUCCESS, lk_init_fail, ENUM_SVP_ERR_LEVEL_ERROR,
|
||||
"Error(%#x),Create err mem info failed!\n", ret);
|
||||
|
||||
lk_init_fail:
|
||||
if (ret != TD_SUCCESS) {
|
||||
_ive_st_lk_uninit(lk_info);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static td_s32 _ive_st_param_init(ot_struct_ive_st_lk_inf *lk_info, ot_size src_size, ot_size pyr_size)
|
||||
{
|
||||
td_s32 ret;
|
||||
td_u32 size;
|
||||
|
||||
ot_unused(pyr_size);
|
||||
/* Init St */
|
||||
ret = libapi_common_ive_create_image(&lk_info->src, OT_SVP_IMG_TYPE_U8C1, src_size.width, src_size.height);
|
||||
macro_svp_check_exps_goto(ret != TD_SUCCESS, st_init_fail, ENUM_SVP_ERR_LEVEL_ERROR,
|
||||
"Error(%#x),Create src image failed!\n", ret);
|
||||
|
||||
ret = libapi_common_ive_create_image(&lk_info->dst, OT_SVP_IMG_TYPE_U8C1, src_size.width, src_size.height);
|
||||
macro_svp_check_exps_goto(ret != TD_SUCCESS, st_init_fail, ENUM_SVP_ERR_LEVEL_ERROR,
|
||||
"Error(%#x),Create dst image failed!\n", ret);
|
||||
|
||||
lk_info->cand_corner_ctrl.quality_level = OT_MACRO_IVE_ST_QUALITY_LEVEL;
|
||||
size = sizeof(td_u32) * libapi_common_ive_calc_stride(src_size.width, OT_IVE_ALIGN) * src_size.height +
|
||||
sizeof(ot_ive_st_max_eig_val);
|
||||
ret = libapi_common_ive_create_mem_info(&(lk_info->cand_corner_ctrl.mem), size);
|
||||
macro_svp_check_exps_goto(ret != TD_SUCCESS, st_init_fail, ENUM_SVP_ERR_LEVEL_ERROR,
|
||||
"Error(%#x),Create CandiCornerCtrl.stMem mem info failed!\n", ret);
|
||||
|
||||
size = sizeof(ot_ive_st_corner_info);
|
||||
ret = libapi_common_ive_create_mem_info(&(lk_info->corner), size);
|
||||
macro_svp_check_exps_goto(ret != TD_SUCCESS, st_init_fail, ENUM_SVP_ERR_LEVEL_ERROR,
|
||||
"Error(%#x),Create corner mem info failed!\n", ret);
|
||||
|
||||
lk_info->corner_ctrl.max_corner_num = OT_MACRO_IVE_LK_MAX_POINT_NUM;
|
||||
lk_info->corner_ctrl.min_dist = OT_MACRO_IVE_LK_MIN_DIST;
|
||||
st_init_fail:
|
||||
if (ret != TD_SUCCESS) {
|
||||
_ive_st_lk_uninit(lk_info);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* function : St lk init
|
||||
*/
|
||||
static td_s32 _ive_st_lk_init(ot_struct_ive_st_lk_inf *lk_info, ot_size src_size,
|
||||
ot_size pyr_size, td_u8 max_level)
|
||||
{
|
||||
td_s32 ret = OT_ERR_IVE_NULL_PTR;
|
||||
td_char path[PATH_MAX] = {0};
|
||||
const td_char *src_file = "./data/input/stlk/st_lk_720x576_420sp.yuv";
|
||||
|
||||
macro_svp_check_exps_return(lk_info == TD_NULL, ret, ENUM_SVP_ERR_LEVEL_ERROR, "test_mem can't be null\n");
|
||||
macro_svp_check_exps_return((strlen(src_file) > PATH_MAX) || (realpath(src_file, path) == TD_NULL),
|
||||
OT_ERR_IVE_ILLEGAL_PARAM, ENUM_SVP_ERR_LEVEL_ERROR, "invalid file!\n");
|
||||
|
||||
/* max_level can't be large than OT_MACRO_IVE_LK_PYR_NUM */
|
||||
macro_svp_check_exps_return(max_level > (OT_MACRO_IVE_LK_PYR_NUM - 1), TD_FAILURE,
|
||||
ENUM_SVP_ERR_LEVEL_ERROR, "max_level can't be larger than %u\n", (OT_MACRO_IVE_LK_PYR_NUM - 1));
|
||||
(td_void)memset_s(lk_info, sizeof(ot_struct_ive_st_lk_inf), 0, sizeof(ot_struct_ive_st_lk_inf));
|
||||
/* lk param init */
|
||||
ret = _ive_lk_param_init(lk_info, src_size, max_level);
|
||||
macro_svp_check_exps_return(ret != TD_SUCCESS, ret, ENUM_SVP_ERR_LEVEL_ERROR,
|
||||
"_ive_lk_param_init failed\n");
|
||||
|
||||
/* st param init */
|
||||
ret = _ive_st_param_init(lk_info, src_size, pyr_size);
|
||||
macro_svp_check_exps_return(ret != TD_SUCCESS, ret, ENUM_SVP_ERR_LEVEL_ERROR,
|
||||
"_ive_st_param_init failed\n");
|
||||
|
||||
/* init pyr assist buff */
|
||||
ret = libapi_common_ive_create_image(&lk_info->pyr_tmp, OT_SVP_IMG_TYPE_U8C1, pyr_size.width, pyr_size.height);
|
||||
macro_svp_check_exps_goto(ret != TD_SUCCESS, st_lk_init_fail, ENUM_SVP_ERR_LEVEL_ERROR,
|
||||
"Error(%#x),Create pyrTmp image failed!\n", ret);
|
||||
|
||||
ret = libapi_common_ive_create_image(&lk_info->src_yuv, OT_SVP_IMG_TYPE_YUV420SP, src_size.width, src_size.height);
|
||||
macro_svp_check_exps_goto(ret != TD_SUCCESS, st_lk_init_fail, ENUM_SVP_ERR_LEVEL_ERROR,
|
||||
"Error(%#x),Create srcYuv image failed!\n", ret);
|
||||
|
||||
/* open file */
|
||||
lk_info->fp_src = fopen(path, "rb");
|
||||
macro_svp_check_exps_goto(lk_info->fp_src == TD_NULL, st_lk_init_fail, ENUM_SVP_ERR_LEVEL_ERROR,
|
||||
"Error,Open file %s failed!\n", path);
|
||||
|
||||
ret = TD_SUCCESS;
|
||||
|
||||
st_lk_init_fail:
|
||||
if (ret != TD_SUCCESS) {
|
||||
_ive_st_lk_uninit(lk_info);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* function : Pyr down
|
||||
*/
|
||||
static td_s32 _ive_st_lk_pyr_down(ot_struct_ive_st_lk_inf *lk_info, ot_svp_src_img *src,
|
||||
ot_svp_dst_img *dst)
|
||||
{
|
||||
td_s32 ret;
|
||||
ot_ive_handle handle;
|
||||
ot_ive_dma_ctrl dma_ctrl = { OT_IVE_DMA_MODE_INTERVAL_COPY, 0, 2, 1, 2 };
|
||||
ot_ive_filter_ctrl filter_ctrl = {
|
||||
{ 1, 2, 3, 2, 1, 2, 5, 6, 5, 2, 3, 6, 8, 6, 3, 2, 5, 6, 5, 2, 1, 2, 3, 2, 1 },
|
||||
7
|
||||
};
|
||||
|
||||
lk_info->pyr_tmp.width = src->width;
|
||||
lk_info->pyr_tmp.height = src->height;
|
||||
|
||||
ret = ss_mpi_ive_filter(&handle, src, &lk_info->pyr_tmp, &filter_ctrl, TD_FALSE);
|
||||
macro_svp_check_exps_return(ret != TD_SUCCESS, ret, ENUM_SVP_ERR_LEVEL_ERROR,
|
||||
"Error(%#x),ss_mpi_ive_filter failed!\n", ret);
|
||||
|
||||
ret = _ive_st_lk_dma(&handle, &lk_info->pyr_tmp, dst, &dma_ctrl, TD_FALSE);
|
||||
macro_svp_check_exps_return(ret != TD_SUCCESS, ret, ENUM_SVP_ERR_LEVEL_ERROR,
|
||||
"Error(%#x),_ive_st_lk_dma failed!\n", ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static td_s32 _ive_query_task(ot_ive_handle handle)
|
||||
{
|
||||
td_s32 ret;
|
||||
td_bool is_block = TD_TRUE;
|
||||
td_bool is_finish = TD_FALSE;
|
||||
ret = ss_mpi_ive_query(handle, &is_finish, is_block);
|
||||
while (ret == OT_ERR_IVE_QUERY_TIMEOUT) {
|
||||
usleep(OT_MACRO_IVE_LK_QUERY_SLEEP);
|
||||
ret = ss_mpi_ive_query(handle, &is_finish, is_block);
|
||||
}
|
||||
macro_svp_check_exps_return(ret != TD_SUCCESS, ret, ENUM_SVP_ERR_LEVEL_ERROR,
|
||||
"Error(%#x),ss_mpi_ive_query failed!\n", ret);
|
||||
return TD_SUCCESS;
|
||||
}
|
||||
|
||||
static td_s32 _ive_proc_frame(td_u32 i, ot_ive_handle handle, ot_struct_ive_st_lk_inf *lk)
|
||||
{
|
||||
td_s32 ret;
|
||||
td_u32 k;
|
||||
td_u32 rect_num;
|
||||
|
||||
ot_ive_st_corner_info *corner_info =
|
||||
macro_svp_convert_addr_to_ptr(ot_ive_st_corner_info, lk->corner.virt_addr);
|
||||
ot_svp_point_s25q7 *next_points =
|
||||
macro_svp_convert_addr_to_ptr(ot_svp_point_s25q7, lk->next_points.virt_addr);
|
||||
|
||||
if (i == 0) {
|
||||
ret = ss_mpi_ive_st_cand_corner(&handle, &lk->next_pyr[0], &lk->dst, &lk->cand_corner_ctrl, TD_TRUE);
|
||||
macro_svp_check_exps_return(ret != TD_SUCCESS, ret, ENUM_SVP_ERR_LEVEL_ERROR,
|
||||
"Error(%#x),ss_mpi_ive_st_cand_corner failed!\n", ret);
|
||||
|
||||
ret = _ive_query_task(handle);
|
||||
macro_svp_check_exps_return(ret != TD_SUCCESS, ret, ENUM_SVP_ERR_LEVEL_ERROR,
|
||||
"Error(%#x),_ive_query_task failed!\n", ret);
|
||||
|
||||
ret = ss_mpi_ive_st_corner(&lk->dst, &lk->corner, &lk->corner_ctrl);
|
||||
macro_svp_check_exps_return(ret != TD_SUCCESS, ret, ENUM_SVP_ERR_LEVEL_ERROR,
|
||||
"Error(%#x),ss_mpi_ive_st_corner failed!\n", ret);
|
||||
|
||||
lk->lk_pyr_ctrl.points_num = corner_info->corner_num;
|
||||
for (k = 0; k < lk->lk_pyr_ctrl.points_num; k++) {
|
||||
next_points[k].x = (td_s32)(corner_info->corner[k].x << OT_MACRO_IVE_LEFT_SHIFT_SEVEN);
|
||||
next_points[k].y = (td_s32)(corner_info->corner[k].y << OT_MACRO_IVE_LEFT_SHIFT_SEVEN);
|
||||
}
|
||||
} else {
|
||||
ret = ss_mpi_ive_lk_optical_flow_pyr(&handle, lk->prev_pyr, lk->next_pyr, &lk->prev_points,
|
||||
&lk->next_points, &lk->status, &lk->err, &lk->lk_pyr_ctrl, TD_TRUE);
|
||||
macro_svp_check_exps_return(ret != TD_SUCCESS, ret, ENUM_SVP_ERR_LEVEL_ERROR,
|
||||
"Error(%#x),ss_mpi_ive_lk_optical_flow_pyr failed!\n", ret);
|
||||
|
||||
ret = _ive_query_task(handle);
|
||||
macro_svp_check_exps_return(ret != TD_SUCCESS, ret, ENUM_SVP_ERR_LEVEL_ERROR,
|
||||
"Error(%#x),_ive_query_task failed!\n", ret);
|
||||
|
||||
rect_num = 0;
|
||||
for (k = 0; k < lk->lk_pyr_ctrl.points_num; k++) {
|
||||
if ((macro_svp_convert_addr_to_ptr(td_u8, lk->status.virt_addr))[k] == 0) {
|
||||
continue;
|
||||
}
|
||||
next_points[rect_num].x = next_points[k].x;
|
||||
next_points[rect_num].y = next_points[k].y;
|
||||
rect_num++;
|
||||
}
|
||||
|
||||
lk->lk_pyr_ctrl.points_num = rect_num;
|
||||
}
|
||||
return TD_SUCCESS;
|
||||
}
|
||||
/*
|
||||
* function : St lk proc
|
||||
*/
|
||||
static td_s32 _ive_st_lk_proc(ot_struct_ive_st_lk_inf *lk)
|
||||
{
|
||||
const td_u32 frame_num = OT_MACRO_IVE_LK_FRAME_NUM;
|
||||
td_u32 i, k;
|
||||
td_s32 ret = OT_ERR_IVE_NULL_PTR;
|
||||
ot_ive_handle handle;
|
||||
ot_ive_dma_ctrl dma_ctrl;
|
||||
|
||||
macro_svp_check_exps_return(lk == TD_NULL, ret, ENUM_SVP_ERR_LEVEL_ERROR, "test_mem can't be null\n");
|
||||
|
||||
(td_void)memset_s(&dma_ctrl, sizeof(dma_ctrl), 0, sizeof(dma_ctrl));
|
||||
dma_ctrl.mode = OT_IVE_DMA_MODE_DIRECT_COPY;
|
||||
|
||||
for (i = 0; (i < frame_num) && (g_stop_signal == TD_FALSE); i++) {
|
||||
macro_svp_trace_info("Proc frame %d\n", i);
|
||||
ret = libapi_common_ive_read_file(&lk->src_yuv, lk->fp_src);
|
||||
macro_svp_check_exps_return(ret != TD_SUCCESS, ret, ENUM_SVP_ERR_LEVEL_ERROR,
|
||||
"Error(%#x),Read src file failed!\n", ret);
|
||||
|
||||
ret = _ive_st_lk_dma(&handle, &lk->src_yuv, &lk->next_pyr[0], &dma_ctrl, TD_FALSE);
|
||||
macro_svp_check_exps_return(ret != TD_SUCCESS, ret, ENUM_SVP_ERR_LEVEL_ERROR,
|
||||
"Error(%#x),_ive_st_lk_dma failed!\n", ret);
|
||||
|
||||
/* buid pyr */
|
||||
for (k = 1; k <= lk->lk_pyr_ctrl.max_level; k++) {
|
||||
ret = _ive_st_lk_pyr_down(lk, &lk->next_pyr[k - 1], &lk->next_pyr[k]);
|
||||
macro_svp_check_exps_return(ret != TD_SUCCESS, ret, ENUM_SVP_ERR_LEVEL_ERROR,
|
||||
"Error(%#x),_ive_st_lk_pyr_down %d failed!\n", ret, k);
|
||||
}
|
||||
/* process frame */
|
||||
ret = _ive_proc_frame(i, handle, lk);
|
||||
macro_svp_check_exps_return(ret != TD_SUCCESS, ret, ENUM_SVP_ERR_LEVEL_ERROR,
|
||||
"Error(%#x),_ive_proc_frame failed!\n", ret);
|
||||
|
||||
ret = memcpy_s(macro_svp_convert_addr_to_ptr(td_void, lk->prev_points.virt_addr),
|
||||
sizeof(ot_svp_point_s25q7) * lk->lk_pyr_ctrl.points_num,
|
||||
macro_svp_convert_addr_to_ptr(td_void, lk->next_points.virt_addr),
|
||||
sizeof(ot_svp_point_s25q7) * lk->lk_pyr_ctrl.points_num);
|
||||
macro_svp_check_exps_return(ret != EOK, OT_ERR_IVE_ILLEGAL_PARAM,
|
||||
ENUM_SVP_ERR_LEVEL_ERROR, "Error,memcpy_s lk points failed!\n");
|
||||
|
||||
_ive_st_lk_copy_pyr(lk->next_pyr, lk->prev_pyr, lk->lk_pyr_ctrl.max_level);
|
||||
}
|
||||
|
||||
return TD_SUCCESS;
|
||||
}
|
||||
|
||||
static td_void _ive_lk_stop(td_void)
|
||||
{
|
||||
_ive_st_lk_uninit(&g_lk_info);
|
||||
(td_void)memset_s(&g_lk_info, sizeof(g_lk_info), 0, sizeof(g_lk_info));
|
||||
libapi_common_ive_mpi_exit();
|
||||
printf("\033[0;31mprogram termination abnormally!\033[0;39m\n");
|
||||
}
|
||||
/*
|
||||
* function : show St Lk demo
|
||||
*/
|
||||
td_void libapi_ive_st_lk(td_void)
|
||||
{
|
||||
ot_size src_size = { OT_MACRO_IVE_LK_D1_WIDTH, OT_MACRO_IVE_LK_D1_HEIGHT };
|
||||
ot_size pyr_size = { OT_MACRO_IVE_LK_D1_WIDTH, OT_MACRO_IVE_LK_D1_HEIGHT };
|
||||
|
||||
td_s32 ret;
|
||||
const td_u8 max_level = OT_MACRO_IVE_LK_MAX_LEVEL;
|
||||
|
||||
(td_void)memset_s(&g_lk_info, sizeof(g_lk_info), 0, sizeof(g_lk_info));
|
||||
ret = libapi_common_ive_check_mpi_init();
|
||||
macro_svp_check_exps_return_void(ret != TD_TRUE, ENUM_SVP_ERR_LEVEL_ERROR, "ive_check_mpi_init failed!\n");
|
||||
|
||||
ret = _ive_st_lk_init(&g_lk_info, src_size, pyr_size, max_level);
|
||||
macro_svp_check_exps_goto(ret != TD_SUCCESS, st_lk_fail, ENUM_SVP_ERR_LEVEL_ERROR,
|
||||
"Error(%#x),_ive_st_lk_init failed!\n", ret);
|
||||
|
||||
ret = _ive_st_lk_proc(&g_lk_info);
|
||||
if (g_stop_signal == TD_TRUE) {
|
||||
_ive_lk_stop();
|
||||
return;
|
||||
}
|
||||
if (ret == TD_SUCCESS) {
|
||||
macro_svp_trace_info("Process success!\n");
|
||||
} else {
|
||||
macro_svp_trace_err("st_lk process failed\n");
|
||||
}
|
||||
|
||||
g_stop_signal = TD_TRUE;
|
||||
_ive_st_lk_uninit(&g_lk_info);
|
||||
(td_void)memset_s(&g_lk_info, sizeof(g_lk_info), 0, sizeof(g_lk_info));
|
||||
|
||||
st_lk_fail:
|
||||
g_stop_signal = TD_TRUE;
|
||||
libapi_common_ive_mpi_exit();
|
||||
}
|
||||
|
||||
/*
|
||||
* function : St_Lk demo signal handle
|
||||
*/
|
||||
td_void libapi_ive_st_lk_handle_sig(td_void)
|
||||
{
|
||||
g_stop_signal = TD_TRUE;
|
||||
}
|
235
libapi/ive/libapi_ive_test_memory.c
Executable file
@ -0,0 +1,235 @@
|
||||
/*
|
||||
Copyright (c), 2001-2022, Shenshu Tech. Co., Ltd.
|
||||
*/
|
||||
#include "libapi_common_ive.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#include <signal.h>
|
||||
#include <semaphore.h>
|
||||
#include <pthread.h>
|
||||
#include <limits.h>
|
||||
|
||||
#define OT_MACRO_IVE_TEST_MEM_QUERY_SLEEP 100
|
||||
#define OT_MACRO_IVE_TEST_MEM_QUERY_D1_WIDTH 720
|
||||
#define OT_MACRO_IVE_TEST_MEM_QUERY_D1_HEIGHT 576
|
||||
|
||||
typedef struct {
|
||||
ot_svp_src_img src1;
|
||||
ot_svp_src_img src2;
|
||||
ot_svp_dst_img dst;
|
||||
ot_svp_dst_mem_info hist;
|
||||
ot_ive_sub_ctrl sub_ctrl;
|
||||
FILE *fp_src;
|
||||
FILE *fp_dst;
|
||||
} ot_test_memory_info;
|
||||
|
||||
static ot_test_memory_info g_test_mem_info;
|
||||
static td_bool g_stop_signal = TD_FALSE;
|
||||
|
||||
/*
|
||||
* function : test memory uninit
|
||||
*/
|
||||
static td_void _ive_test_memory_uninit(ot_test_memory_info *test_mem)
|
||||
{
|
||||
macro_svp_check_exps_return_void(test_mem == TD_NULL, ENUM_SVP_ERR_LEVEL_ERROR, "test_mem can't be null\n");
|
||||
macro_svp_mmz_free(test_mem->src1.phys_addr[0], test_mem->src1.virt_addr[0]);
|
||||
macro_svp_mmz_free(test_mem->src2.phys_addr[0], test_mem->src2.virt_addr[0]);
|
||||
macro_svp_mmz_free(test_mem->dst.phys_addr[0], test_mem->dst.virt_addr[0]);
|
||||
macro_svp_mmz_free(test_mem->hist.phys_addr, test_mem->hist.virt_addr);
|
||||
|
||||
macro_svp_close_file(test_mem->fp_src);
|
||||
macro_svp_close_file(test_mem->fp_dst);
|
||||
}
|
||||
|
||||
/*
|
||||
* function : test memory init
|
||||
*/
|
||||
static td_s32 _ive_test_memory_init(ot_test_memory_info *test_mem, td_u32 width, td_u32 height)
|
||||
{
|
||||
td_s32 ret = OT_ERR_IVE_NULL_PTR;
|
||||
td_u32 size;
|
||||
td_char path[PATH_MAX] = {0};
|
||||
const td_char *src_file = "./data/input/testmem/test_mem_in.yuv";
|
||||
|
||||
macro_svp_check_exps_return(test_mem == TD_NULL, ret, ENUM_SVP_ERR_LEVEL_ERROR, "test_mem can't be null\n");
|
||||
macro_svp_check_exps_return((strlen(src_file) > PATH_MAX) || (realpath(src_file, path) == TD_NULL),
|
||||
OT_ERR_IVE_ILLEGAL_PARAM, ENUM_SVP_ERR_LEVEL_ERROR, "invalid file!\n");
|
||||
|
||||
(td_void)memset_s(test_mem, sizeof(ot_test_memory_info), 0, sizeof(ot_test_memory_info));
|
||||
|
||||
ret = libapi_common_ive_create_image(&(test_mem->src1), OT_SVP_IMG_TYPE_U8C1, width, height);
|
||||
macro_svp_check_exps_goto(ret != TD_SUCCESS, fail, ENUM_SVP_ERR_LEVEL_ERROR,
|
||||
"Error(%#x),Create src1 image failed!\n", ret);
|
||||
|
||||
ret = libapi_common_ive_create_image(&(test_mem->src2), OT_SVP_IMG_TYPE_U8C1, width, height);
|
||||
macro_svp_check_exps_goto(ret != TD_SUCCESS, fail, ENUM_SVP_ERR_LEVEL_ERROR,
|
||||
"Error(%#x),Create src2 image failed!\n", ret);
|
||||
|
||||
ret = libapi_common_ive_create_image(&(test_mem->dst), OT_SVP_IMG_TYPE_U8C1, width, height);
|
||||
macro_svp_check_exps_goto(ret != TD_SUCCESS, fail, ENUM_SVP_ERR_LEVEL_ERROR,
|
||||
"Error(%#x),Create dst image failed!\n", ret);
|
||||
|
||||
size = OT_IVE_HIST_NUM * sizeof(td_u32);
|
||||
ret = libapi_common_ive_create_mem_info(&(test_mem->hist), size);
|
||||
macro_svp_check_exps_goto(ret != TD_SUCCESS, fail, ENUM_SVP_ERR_LEVEL_ERROR,
|
||||
"Error(%#x),Create hist meminfo failed!\n", ret);
|
||||
|
||||
test_mem->sub_ctrl.mode = OT_IVE_SUB_MODE_ABS;
|
||||
|
||||
/* open src file */
|
||||
ret = TD_FAILURE;
|
||||
test_mem->fp_src = fopen(path, "rb");
|
||||
macro_svp_check_exps_goto(test_mem->fp_src == TD_NULL, fail, ENUM_SVP_ERR_LEVEL_ERROR,
|
||||
"Error,Open file %s failed!\n", path);
|
||||
|
||||
/* open dst file */
|
||||
macro_svp_check_exps_goto(realpath("./data/output/testmem", path) == NULL, fail, ENUM_SVP_ERR_LEVEL_ERROR,
|
||||
"invalid file!\n");
|
||||
ret = strcat_s(path, PATH_MAX, "/test_mem_out.yuv");
|
||||
macro_svp_check_exps_goto(ret != EOK, fail, ENUM_SVP_ERR_LEVEL_ERROR, "strcat_s failed!\n");
|
||||
ret = TD_FAILURE;
|
||||
test_mem->fp_dst = fopen(path, "wb");
|
||||
macro_svp_check_exps_goto(test_mem->fp_dst == TD_NULL, fail, ENUM_SVP_ERR_LEVEL_ERROR,
|
||||
"Error,Open file %s failed!\n", path);
|
||||
|
||||
return TD_SUCCESS;
|
||||
fail:
|
||||
_ive_test_memory_uninit(test_mem);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static td_void _ive_test_memory_init_data(const ot_test_memory_info *test_mem, ot_svp_src_data *src_data,
|
||||
ot_svp_dst_data *dst_data)
|
||||
{
|
||||
src_data->virt_addr = test_mem->src1.virt_addr[0];
|
||||
src_data->phys_addr = test_mem->src1.phys_addr[0];
|
||||
src_data->width = test_mem->src1.width;
|
||||
src_data->height = test_mem->src1.height;
|
||||
src_data->stride = test_mem->src1.stride[0];
|
||||
|
||||
dst_data->virt_addr = test_mem->src2.virt_addr[0];
|
||||
dst_data->phys_addr = test_mem->src2.phys_addr[0];
|
||||
dst_data->width = test_mem->src2.width;
|
||||
dst_data->height = test_mem->src2.height;
|
||||
dst_data->stride = test_mem->src2.stride[0];
|
||||
}
|
||||
/*
|
||||
* function : test memory
|
||||
*/
|
||||
static td_s32 _ive_test_memory_proc(ot_test_memory_info *test_mem)
|
||||
{
|
||||
td_s32 ret;
|
||||
td_u32 *hist_ptr = TD_NULL;
|
||||
td_u32 i, j;
|
||||
ot_ive_handle handle;
|
||||
td_bool is_instant = TD_FALSE;
|
||||
td_bool is_finish = TD_FALSE;
|
||||
ot_svp_src_data src_data;
|
||||
ot_svp_dst_data dst_data;
|
||||
ot_ive_dma_ctrl dma_ctrl;
|
||||
|
||||
macro_svp_check_exps_return(test_mem == TD_NULL, OT_ERR_IVE_NULL_PTR,
|
||||
ENUM_SVP_ERR_LEVEL_ERROR, "test_mem can't be null\n");
|
||||
|
||||
for (j = 0; (j < 1) && (g_stop_signal == TD_FALSE); j++) {
|
||||
ret = libapi_common_ive_read_file(&(test_mem->src1), test_mem->fp_src);
|
||||
macro_svp_check_exps_return(ret != TD_SUCCESS, ret, ENUM_SVP_ERR_LEVEL_ERROR, "read src file failed!\n");
|
||||
|
||||
dma_ctrl.mode = OT_IVE_DMA_MODE_DIRECT_COPY;
|
||||
|
||||
_ive_test_memory_init_data(test_mem, &src_data, &dst_data);
|
||||
|
||||
ret = ss_mpi_ive_dma(&handle, &src_data, &dst_data, &dma_ctrl, is_instant);
|
||||
macro_svp_check_exps_return(ret != TD_SUCCESS, ret, ENUM_SVP_ERR_LEVEL_ERROR, "ss_mpi_ive_dma failed!\n");
|
||||
|
||||
ret = ss_mpi_ive_sub(&handle, &test_mem->src1, &test_mem->src2, &test_mem->dst,
|
||||
&test_mem->sub_ctrl, is_instant);
|
||||
macro_svp_check_exps_return(ret != TD_SUCCESS, ret, ENUM_SVP_ERR_LEVEL_ERROR,
|
||||
"Error(%#x),ss_mpi_ive_sub failed!\n", ret);
|
||||
|
||||
is_instant = TD_TRUE;
|
||||
ret = ss_mpi_ive_hist(&handle, &test_mem->dst, &test_mem->hist, is_instant);
|
||||
macro_svp_check_exps_return(ret != TD_SUCCESS, ret, ENUM_SVP_ERR_LEVEL_ERROR, "ss_mpi_ive_hist failed!\n");
|
||||
|
||||
ret = ss_mpi_ive_query(handle, &is_finish, TD_TRUE);
|
||||
while (ret == OT_ERR_IVE_QUERY_TIMEOUT) {
|
||||
usleep(OT_MACRO_IVE_TEST_MEM_QUERY_SLEEP);
|
||||
ret = ss_mpi_ive_query(handle, &is_finish, TD_TRUE);
|
||||
}
|
||||
macro_svp_check_exps_return(ret != TD_SUCCESS, ret, ENUM_SVP_ERR_LEVEL_ERROR, "ss_mpi_ive_query failed!\n");
|
||||
|
||||
ret = libapi_common_ive_write_file(&test_mem->dst, test_mem->fp_dst);
|
||||
macro_svp_check_exps_return(ret != TD_SUCCESS, ret, ENUM_SVP_ERR_LEVEL_ERROR, "write dst file failed!\n");
|
||||
|
||||
hist_ptr = macro_svp_convert_addr_to_ptr(td_u32, test_mem->hist.virt_addr);
|
||||
if (hist_ptr[0] != (test_mem->src1.width * test_mem->src1.height)) {
|
||||
ret = TD_FAILURE;
|
||||
macro_svp_trace_err("Test mem error,hist_ptr[0] = %d\n", hist_ptr[0]);
|
||||
for (i = 1; i < OT_IVE_HIST_NUM; i++) {
|
||||
macro_svp_check_exps_trace(hist_ptr[i] != 0, ENUM_SVP_ERR_LEVEL_ERROR,
|
||||
"Test mem error, hist_ptr[%d] = %d\n", i, hist_ptr[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
return TD_SUCCESS;
|
||||
}
|
||||
|
||||
static td_void _ive_test_mem_stop(td_void)
|
||||
{
|
||||
_ive_test_memory_uninit(&g_test_mem_info);
|
||||
(td_void)memset_s(&g_test_mem_info, sizeof(g_test_mem_info), 0, sizeof(g_test_mem_info));
|
||||
libapi_common_ive_mpi_exit();
|
||||
printf("\033[0;31mprogram termination abnormally!\033[0;39m\n");
|
||||
}
|
||||
/*
|
||||
* function : Show test memory demo
|
||||
*/
|
||||
td_void libapi_ive_test_memory(td_void)
|
||||
{
|
||||
td_s32 ret;
|
||||
const td_u32 width = OT_MACRO_IVE_TEST_MEM_QUERY_D1_WIDTH;
|
||||
const td_u32 height = OT_MACRO_IVE_TEST_MEM_QUERY_D1_HEIGHT;
|
||||
|
||||
(td_void)memset_s(&g_test_mem_info, sizeof(g_test_mem_info), 0, sizeof(g_test_mem_info));
|
||||
ret = libapi_common_ive_check_mpi_init();
|
||||
macro_svp_check_exps_return_void(ret != TD_TRUE, ENUM_SVP_ERR_LEVEL_ERROR, "ive_check_mpi_init failed!\n");
|
||||
|
||||
ret = _ive_test_memory_init(&g_test_mem_info, width, height);
|
||||
macro_svp_check_exps_goto(ret != TD_SUCCESS, test_memory_fail, ENUM_SVP_ERR_LEVEL_ERROR,
|
||||
"Error(%#x),_ive_test_memory_init failed!\n", ret);
|
||||
|
||||
ret = _ive_test_memory_proc(&g_test_mem_info);
|
||||
if (g_stop_signal == TD_TRUE) {
|
||||
_ive_test_mem_stop();
|
||||
return;
|
||||
}
|
||||
if (ret == TD_SUCCESS) {
|
||||
macro_svp_trace_info("Process success!\n");
|
||||
} else {
|
||||
macro_svp_trace_err("test_memory process failed\n");
|
||||
}
|
||||
|
||||
g_stop_signal = TD_TRUE;
|
||||
_ive_test_memory_uninit(&g_test_mem_info);
|
||||
(td_void)memset_s(&g_test_mem_info, sizeof(g_test_mem_info), 0, sizeof(g_test_mem_info));
|
||||
|
||||
test_memory_fail:
|
||||
g_stop_signal = TD_TRUE;
|
||||
libapi_common_ive_mpi_exit();
|
||||
}
|
||||
|
||||
/*
|
||||
* function : TestMemory demo signal handle
|
||||
*/
|
||||
td_void libapi_ive_test_memory_handle_sig(td_void)
|
||||
{
|
||||
g_stop_signal = TD_TRUE;
|
||||
}
|
BIN
libapi/ive/model/lstm.om
Executable file
BIN
libapi/ive/model/resnet50.om
Executable file
BIN
libapi/ive/model/rfcn.om
Executable file
BIN
libapi/ive/res/1080P.h265
Executable file
BIN
libapi/ive/res/3840x2160_8bit.h265
Executable file
BIN
libapi/ive/res/clut4.bmp
Executable file
After Width: | Height: | Size: 15 KiB |
BIN
libapi/ive/res/mm.bmp
Executable file
After Width: | Height: | Size: 76 KiB |
BIN
libapi/ive/res/mm16.bmp
Executable file
After Width: | Height: | Size: 13 KiB |
BIN
libapi/ive/res/mm2.bmp
Executable file
After Width: | Height: | Size: 15 KiB |
BIN
libapi/ive/res/vi_chn_0.bmp
Executable file
After Width: | Height: | Size: 24 KiB |
74
libapi/sort/include/kalman_filter.h
Executable file
@ -0,0 +1,74 @@
|
||||
#pragma once
|
||||
|
||||
#include <iostream>
|
||||
#include <eigen3/Eigen/Dense>
|
||||
|
||||
// abstract class for Kalman filter
|
||||
// implementation could be KF/EKF/UKF...
|
||||
class KalmanFilter {
|
||||
public:
|
||||
/**
|
||||
* user need to define H matrix & R matrix
|
||||
* @param num_states
|
||||
* @param num_obs
|
||||
*/
|
||||
// constructor
|
||||
explicit KalmanFilter(unsigned int num_states, unsigned int num_obs);
|
||||
|
||||
// destructor
|
||||
virtual ~KalmanFilter() = default;
|
||||
|
||||
/**
|
||||
* Coast state and state covariance using the process model
|
||||
* User can use this function without change the internal
|
||||
* tracking state x_
|
||||
*/
|
||||
virtual void Coast();
|
||||
|
||||
/**
|
||||
* Predict without measurement update
|
||||
*/
|
||||
void Predict();
|
||||
|
||||
/**
|
||||
* This function maps the true state space into the observed space
|
||||
* using the observation model
|
||||
* User can implement their own method for more complicated models
|
||||
*/
|
||||
virtual Eigen::VectorXd PredictionToObservation(const Eigen::VectorXd &state);
|
||||
|
||||
/**
|
||||
* Updates the state by using Extended Kalman Filter equations
|
||||
* @param z The measurement at k+1
|
||||
*/
|
||||
virtual void Update(const Eigen::VectorXd &z);
|
||||
|
||||
/**
|
||||
* Calculate marginal log-likelihood to evaluate different parameter choices
|
||||
*/
|
||||
float CalculateLogLikelihood(const Eigen::VectorXd& y, const Eigen::MatrixXd& S);
|
||||
|
||||
// State vector
|
||||
Eigen::VectorXd x_, x_predict_;
|
||||
|
||||
// Error covariance matrix
|
||||
Eigen::MatrixXd P_, P_predict_;
|
||||
|
||||
// State transition matrix
|
||||
Eigen::MatrixXd F_;
|
||||
|
||||
// Covariance matrix of process noise
|
||||
Eigen::MatrixXd Q_;
|
||||
|
||||
// measurement matrix
|
||||
Eigen::MatrixXd H_;
|
||||
|
||||
// covariance matrix of observation noise
|
||||
Eigen::MatrixXd R_;
|
||||
|
||||
unsigned int num_states_, num_obs_;
|
||||
|
||||
float log_likelihood_delta_;
|
||||
|
||||
float NIS_;
|
||||
};
|
237
libapi/sort/include/matrix.cpp
Executable file
@ -0,0 +1,237 @@
|
||||
/*
|
||||
* Copyright (c) 2007 John Weaver
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "matrix.h"
|
||||
|
||||
#include <cassert>
|
||||
#include <cstdlib>
|
||||
#include <algorithm>
|
||||
|
||||
/*export*/ template <class T>
|
||||
Matrix<T>::Matrix() {
|
||||
m_rows = 0;
|
||||
m_columns = 0;
|
||||
m_matrix = nullptr;
|
||||
}
|
||||
|
||||
|
||||
/*export*/ template <class T>
|
||||
Matrix<T>::Matrix(const std::initializer_list<std::initializer_list<T>> init) {
|
||||
m_matrix = nullptr;
|
||||
m_rows = init.size();
|
||||
if ( m_rows == 0 ) {
|
||||
m_columns = 0;
|
||||
} else {
|
||||
m_columns = init.begin()->size();
|
||||
if ( m_columns > 0 ) {
|
||||
resize(m_rows, m_columns);
|
||||
}
|
||||
}
|
||||
|
||||
size_t i = 0, j;
|
||||
for ( auto row = init.begin() ; row != init.end() ; ++row, ++i ) {
|
||||
assert ( row->size() == m_columns && "All rows must have the same number of columns." );
|
||||
j = 0;
|
||||
for ( auto value = row->begin() ; value != row->end() ; ++value, ++j ) {
|
||||
m_matrix[i][j] = *value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*export*/ template <class T>
|
||||
Matrix<T>::Matrix(const Matrix<T> &other) {
|
||||
if ( other.m_matrix != nullptr ) {
|
||||
// copy arrays
|
||||
m_matrix = nullptr;
|
||||
resize(other.m_rows, other.m_columns);
|
||||
for ( size_t i = 0 ; i < m_rows ; i++ ) {
|
||||
for ( size_t j = 0 ; j < m_columns ; j++ ) {
|
||||
m_matrix[i][j] = other.m_matrix[i][j];
|
||||
}
|
||||
}
|
||||
} else {
|
||||
m_matrix = nullptr;
|
||||
m_rows = 0;
|
||||
m_columns = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/*export*/ template <class T>
|
||||
Matrix<T>::Matrix(const size_t rows, const size_t columns) {
|
||||
m_matrix = nullptr;
|
||||
resize(rows, columns);
|
||||
}
|
||||
|
||||
/*export*/ template <class T>
|
||||
Matrix<T> &
|
||||
Matrix<T>::operator= (const Matrix<T> &other) {
|
||||
if ( other.m_matrix != nullptr ) {
|
||||
// copy arrays
|
||||
resize(other.m_rows, other.m_columns);
|
||||
for ( size_t i = 0 ; i < m_rows ; i++ ) {
|
||||
for ( size_t j = 0 ; j < m_columns ; j++ ) {
|
||||
m_matrix[i][j] = other.m_matrix[i][j];
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// free arrays
|
||||
for ( size_t i = 0 ; i < m_columns ; i++ ) {
|
||||
delete [] m_matrix[i];
|
||||
}
|
||||
|
||||
delete [] m_matrix;
|
||||
|
||||
m_matrix = nullptr;
|
||||
m_rows = 0;
|
||||
m_columns = 0;
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
/*export*/ template <class T>
|
||||
Matrix<T>::~Matrix() {
|
||||
if ( m_matrix != nullptr ) {
|
||||
// free arrays
|
||||
for ( size_t i = 0 ; i < m_rows ; i++ ) {
|
||||
delete [] m_matrix[i];
|
||||
}
|
||||
|
||||
delete [] m_matrix;
|
||||
}
|
||||
m_matrix = nullptr;
|
||||
}
|
||||
|
||||
/*export*/ template <class T>
|
||||
void
|
||||
Matrix<T>::resize(const size_t rows, const size_t columns, const T default_value) {
|
||||
assert ( rows > 0 && columns > 0 && "Columns and rows must exist." );
|
||||
|
||||
if ( m_matrix == nullptr ) {
|
||||
// alloc arrays
|
||||
m_matrix = new T*[rows]; // rows
|
||||
for ( size_t i = 0 ; i < rows ; i++ ) {
|
||||
m_matrix[i] = new T[columns]; // columns
|
||||
}
|
||||
|
||||
m_rows = rows;
|
||||
m_columns = columns;
|
||||
clear();
|
||||
} else {
|
||||
// save array pointer
|
||||
T **new_matrix;
|
||||
// alloc new arrays
|
||||
new_matrix = new T*[rows]; // rows
|
||||
for ( size_t i = 0 ; i < rows ; i++ ) {
|
||||
new_matrix[i] = new T[columns]; // columns
|
||||
for ( size_t j = 0 ; j < columns ; j++ ) {
|
||||
new_matrix[i][j] = default_value;
|
||||
}
|
||||
}
|
||||
|
||||
// copy data from saved pointer to new arrays
|
||||
size_t minrows = std::min(rows, m_rows);
|
||||
size_t mincols = std::min(columns, m_columns);
|
||||
for ( size_t x = 0 ; x < minrows ; x++ ) {
|
||||
for ( size_t y = 0 ; y < mincols ; y++ ) {
|
||||
new_matrix[x][y] = m_matrix[x][y];
|
||||
}
|
||||
}
|
||||
|
||||
// delete old arrays
|
||||
if ( m_matrix != nullptr ) {
|
||||
for ( size_t i = 0 ; i < m_rows ; i++ ) {
|
||||
delete [] m_matrix[i];
|
||||
}
|
||||
|
||||
delete [] m_matrix;
|
||||
}
|
||||
|
||||
m_matrix = new_matrix;
|
||||
}
|
||||
|
||||
m_rows = rows;
|
||||
m_columns = columns;
|
||||
}
|
||||
|
||||
/*export*/ template <class T>
|
||||
void
|
||||
Matrix<T>::clear() {
|
||||
assert( m_matrix != nullptr );
|
||||
|
||||
for ( size_t i = 0 ; i < m_rows ; i++ ) {
|
||||
for ( size_t j = 0 ; j < m_columns ; j++ ) {
|
||||
m_matrix[i][j] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*export*/ template <class T>
|
||||
inline T&
|
||||
Matrix<T>::operator ()(const size_t x, const size_t y) {
|
||||
assert ( x < m_rows );
|
||||
assert ( y < m_columns );
|
||||
assert ( m_matrix != nullptr );
|
||||
return m_matrix[x][y];
|
||||
}
|
||||
|
||||
|
||||
/*export*/ template <class T>
|
||||
inline const T&
|
||||
Matrix<T>::operator ()(const size_t x, const size_t y) const {
|
||||
assert ( x < m_rows );
|
||||
assert ( y < m_columns );
|
||||
assert ( m_matrix != nullptr );
|
||||
return m_matrix[x][y];
|
||||
}
|
||||
|
||||
|
||||
/*export*/ template <class T>
|
||||
const T
|
||||
Matrix<T>::min() const {
|
||||
assert( m_matrix != nullptr );
|
||||
assert ( m_rows > 0 );
|
||||
assert ( m_columns > 0 );
|
||||
T min = m_matrix[0][0];
|
||||
|
||||
for ( size_t i = 0 ; i < m_rows ; i++ ) {
|
||||
for ( size_t j = 0 ; j < m_columns ; j++ ) {
|
||||
min = std::min<T>(min, m_matrix[i][j]);
|
||||
}
|
||||
}
|
||||
|
||||
return min;
|
||||
}
|
||||
|
||||
|
||||
/*export*/ template <class T>
|
||||
const T
|
||||
Matrix<T>::max() const {
|
||||
assert( m_matrix != nullptr );
|
||||
assert ( m_rows > 0 );
|
||||
assert ( m_columns > 0 );
|
||||
T max = m_matrix[0][0];
|
||||
|
||||
for ( size_t i = 0 ; i < m_rows ; i++ ) {
|
||||
for ( size_t j = 0 ; j < m_columns ; j++ ) {
|
||||
max = std::max<T>(max, m_matrix[i][j]);
|
||||
}
|
||||
}
|
||||
|
||||
return max;
|
||||
}
|
73
libapi/sort/include/matrix.h
Executable file
@ -0,0 +1,73 @@
|
||||
/*
|
||||
* Copyright (c) 2007 John Weaver
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef _MATRIX_H_
|
||||
#define _MATRIX_H_
|
||||
|
||||
#include <initializer_list>
|
||||
#include <cstdlib>
|
||||
#include <ostream>
|
||||
|
||||
template <class T>
|
||||
class Matrix {
|
||||
public:
|
||||
Matrix();
|
||||
Matrix(const size_t rows, const size_t columns);
|
||||
Matrix(const std::initializer_list<std::initializer_list<T>> init);
|
||||
Matrix(const Matrix<T> &other);
|
||||
Matrix<T> & operator= (const Matrix<T> &other);
|
||||
~Matrix();
|
||||
// all operations modify the matrix in-place.
|
||||
void resize(const size_t rows, const size_t columns, const T default_value = 0);
|
||||
void clear();
|
||||
T& operator () (const size_t x, const size_t y);
|
||||
const T& operator () (const size_t x, const size_t y) const;
|
||||
const T min() const;
|
||||
const T max() const;
|
||||
inline size_t minsize() { return ((m_rows < m_columns) ? m_rows : m_columns); }
|
||||
inline size_t columns() const { return m_columns;}
|
||||
inline size_t rows() const { return m_rows;}
|
||||
|
||||
friend std::ostream& operator<<(std::ostream& os, const Matrix &matrix)
|
||||
{
|
||||
os << "Matrix:" << std::endl;
|
||||
for (size_t row = 0 ; row < matrix.rows() ; row++ )
|
||||
{
|
||||
for (size_t col = 0 ; col < matrix.columns() ; col++ )
|
||||
{
|
||||
os.width(8);
|
||||
os << matrix(row, col) << ",";
|
||||
}
|
||||
os << std::endl;
|
||||
}
|
||||
return os;
|
||||
}
|
||||
|
||||
private:
|
||||
T **m_matrix;
|
||||
size_t m_rows;
|
||||
size_t m_columns;
|
||||
};
|
||||
|
||||
#ifndef USE_EXPORT_KEYWORD
|
||||
#include "matrix.cpp"
|
||||
//#define export /*export*/
|
||||
#endif
|
||||
|
||||
#endif /* !defined(_MATRIX_H_) */
|
||||
|
464
libapi/sort/include/munkres.h
Executable file
@ -0,0 +1,464 @@
|
||||
/*
|
||||
* Copyright (c) 2007 John Weaver
|
||||
* Copyright (c) 2015 Miroslav Krajicek
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#if !defined(_MUNKRES_H_)
|
||||
#define _MUNKRES_H_
|
||||
|
||||
#include "matrix.h"
|
||||
|
||||
#include <list>
|
||||
#include <utility>
|
||||
#include <iostream>
|
||||
#include <cmath>
|
||||
#include <limits>
|
||||
|
||||
template<typename Data> class Munkres
|
||||
{
|
||||
static constexpr int NORMAL = 0;
|
||||
static constexpr int STAR = 1;
|
||||
static constexpr int PRIME = 2;
|
||||
public:
|
||||
|
||||
/*
|
||||
*
|
||||
* Linear assignment problem solution
|
||||
* [modifies matrix in-place.]
|
||||
* matrix(row,col): row major format assumed.
|
||||
*
|
||||
* Assignments are remaining 0 values
|
||||
* (extra 0 values are replaced with -1)
|
||||
*
|
||||
*/
|
||||
void solve(Matrix<Data> &m) {
|
||||
const size_t rows = m.rows(),
|
||||
columns = m.columns(),
|
||||
size = std::max(rows, columns);
|
||||
|
||||
#ifdef DEBUG
|
||||
std::cout << "Munkres input: " << m << std::endl;
|
||||
#endif
|
||||
|
||||
// Copy input matrix
|
||||
this->matrix = m;
|
||||
|
||||
if ( rows != columns ) {
|
||||
// If the input matrix isn't square, make it square
|
||||
// and fill the empty values with the largest value present
|
||||
// in the matrix.
|
||||
matrix.resize(size, size, matrix.max());
|
||||
}
|
||||
|
||||
|
||||
// STAR == 1 == starred, PRIME == 2 == primed
|
||||
mask_matrix.resize(size, size);
|
||||
|
||||
row_mask = new bool[size];
|
||||
col_mask = new bool[size];
|
||||
for ( size_t i = 0 ; i < size ; i++ ) {
|
||||
row_mask[i] = false;
|
||||
}
|
||||
|
||||
for ( size_t i = 0 ; i < size ; i++ ) {
|
||||
col_mask[i] = false;
|
||||
}
|
||||
|
||||
// Prepare the matrix values...
|
||||
|
||||
// If there were any infinities, replace them with a value greater
|
||||
// than the maximum value in the matrix.
|
||||
replace_infinites(matrix);
|
||||
|
||||
minimize_along_direction(matrix, rows >= columns);
|
||||
minimize_along_direction(matrix, rows < columns);
|
||||
|
||||
// Follow the steps
|
||||
int step = 1;
|
||||
while ( step ) {
|
||||
switch ( step ) {
|
||||
case 1:
|
||||
step = step1();
|
||||
// step is always 2
|
||||
break;
|
||||
case 2:
|
||||
step = step2();
|
||||
// step is always either 0 or 3
|
||||
break;
|
||||
case 3:
|
||||
step = step3();
|
||||
// step in [3, 4, 5]
|
||||
break;
|
||||
case 4:
|
||||
step = step4();
|
||||
// step is always 2
|
||||
break;
|
||||
case 5:
|
||||
step = step5();
|
||||
// step is always 3
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Store results
|
||||
for ( size_t row = 0 ; row < size ; row++ ) {
|
||||
for ( size_t col = 0 ; col < size ; col++ ) {
|
||||
if ( mask_matrix(row, col) == STAR ) {
|
||||
matrix(row, col) = 0;
|
||||
} else {
|
||||
matrix(row, col) = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
std::cout << "Munkres output: " << matrix << std::endl;
|
||||
#endif
|
||||
// Remove the excess rows or columns that we added to fit the
|
||||
// input to a square matrix.
|
||||
matrix.resize(rows, columns);
|
||||
|
||||
m = matrix;
|
||||
|
||||
delete [] row_mask;
|
||||
delete [] col_mask;
|
||||
}
|
||||
|
||||
static void replace_infinites(Matrix<Data> &matrix) {
|
||||
const size_t rows = matrix.rows(),
|
||||
columns = matrix.columns();
|
||||
assert( rows > 0 && columns > 0 );
|
||||
double max = matrix(0, 0);
|
||||
constexpr auto infinity = std::numeric_limits<double>::infinity();
|
||||
|
||||
// Find the greatest value in the matrix that isn't infinity.
|
||||
for ( size_t row = 0 ; row < rows ; row++ ) {
|
||||
for ( size_t col = 0 ; col < columns ; col++ ) {
|
||||
if ( matrix(row, col) != infinity ) {
|
||||
if ( max == infinity ) {
|
||||
max = matrix(row, col);
|
||||
} else {
|
||||
max = std::max<double>(max, matrix(row, col));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// a value higher than the maximum value present in the matrix.
|
||||
if ( max == infinity ) {
|
||||
// This case only occurs when all values are infinite.
|
||||
max = 0;
|
||||
} else {
|
||||
max++;
|
||||
}
|
||||
|
||||
for ( size_t row = 0 ; row < rows ; row++ ) {
|
||||
for ( size_t col = 0 ; col < columns ; col++ ) {
|
||||
if ( matrix(row, col) == infinity ) {
|
||||
matrix(row, col) = max;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static void minimize_along_direction(Matrix<Data> &matrix, const bool over_columns) {
|
||||
const size_t outer_size = over_columns ? matrix.columns() : matrix.rows(),
|
||||
inner_size = over_columns ? matrix.rows() : matrix.columns();
|
||||
|
||||
// Look for a minimum value to subtract from all values along
|
||||
// the "outer" direction.
|
||||
for ( size_t i = 0 ; i < outer_size ; i++ ) {
|
||||
double min = over_columns ? matrix(0, i) : matrix(i, 0);
|
||||
|
||||
// As long as the current minimum is greater than zero,
|
||||
// keep looking for the minimum.
|
||||
// Start at one because we already have the 0th value in min.
|
||||
for ( size_t j = 1 ; j < inner_size && min > 0 ; j++ ) {
|
||||
min = std::min<double>(
|
||||
min,
|
||||
over_columns ? matrix(j, i) : matrix(i, j));
|
||||
}
|
||||
|
||||
if ( min > 0 ) {
|
||||
for ( size_t j = 0 ; j < inner_size ; j++ ) {
|
||||
if ( over_columns ) {
|
||||
matrix(j, i) -= min;
|
||||
} else {
|
||||
matrix(i, j) -= min;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
inline bool find_uncovered_in_matrix(const double item, size_t &row, size_t &col) const {
|
||||
const size_t rows = matrix.rows(),
|
||||
columns = matrix.columns();
|
||||
|
||||
for ( row = 0 ; row < rows ; row++ ) {
|
||||
if ( !row_mask[row] ) {
|
||||
for ( col = 0 ; col < columns ; col++ ) {
|
||||
if ( !col_mask[col] ) {
|
||||
if ( matrix(row,col) == item ) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool pair_in_list(const std::pair<size_t,size_t> &needle, const std::list<std::pair<size_t,size_t> > &haystack) {
|
||||
for ( std::list<std::pair<size_t,size_t> >::const_iterator i = haystack.begin() ; i != haystack.end() ; i++ ) {
|
||||
if ( needle == *i ) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
int step1() {
|
||||
const size_t rows = matrix.rows(),
|
||||
columns = matrix.columns();
|
||||
|
||||
for ( size_t row = 0 ; row < rows ; row++ ) {
|
||||
for ( size_t col = 0 ; col < columns ; col++ ) {
|
||||
if ( 0 == matrix(row, col) ) {
|
||||
for ( size_t nrow = 0 ; nrow < row ; nrow++ )
|
||||
if ( STAR == mask_matrix(nrow,col) )
|
||||
goto next_column;
|
||||
|
||||
mask_matrix(row,col) = STAR;
|
||||
goto next_row;
|
||||
}
|
||||
next_column:;
|
||||
}
|
||||
next_row:;
|
||||
}
|
||||
|
||||
return 2;
|
||||
}
|
||||
|
||||
int step2() {
|
||||
const size_t rows = matrix.rows(),
|
||||
columns = matrix.columns();
|
||||
size_t covercount = 0;
|
||||
|
||||
for ( size_t row = 0 ; row < rows ; row++ )
|
||||
for ( size_t col = 0 ; col < columns ; col++ )
|
||||
if ( STAR == mask_matrix(row, col) ) {
|
||||
col_mask[col] = true;
|
||||
covercount++;
|
||||
}
|
||||
|
||||
if ( covercount >= matrix.minsize() ) {
|
||||
#ifdef DEBUG
|
||||
std::cout << "Final cover count: " << covercount << std::endl;
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
std::cout << "Munkres matrix has " << covercount << " of " << matrix.minsize() << " Columns covered:" << std::endl;
|
||||
std::cout << matrix << std::endl;
|
||||
#endif
|
||||
|
||||
|
||||
return 3;
|
||||
}
|
||||
|
||||
int step3() {
|
||||
/*
|
||||
Main Zero Search
|
||||
|
||||
1. Find an uncovered Z in the distance matrix and prime it. If no such zero exists, go to Step 5
|
||||
2. If No Z* exists in the row of the Z', go to Step 4.
|
||||
3. If a Z* exists, cover this row and uncover the column of the Z*. Return to Step 3.1 to find a new Z
|
||||
*/
|
||||
if ( find_uncovered_in_matrix(0, saverow, savecol) ) {
|
||||
mask_matrix(saverow,savecol) = PRIME; // prime it.
|
||||
} else {
|
||||
return 5;
|
||||
}
|
||||
|
||||
for ( size_t ncol = 0 ; ncol < matrix.columns() ; ncol++ ) {
|
||||
if ( mask_matrix(saverow,ncol) == STAR ) {
|
||||
row_mask[saverow] = true; //cover this row and
|
||||
col_mask[ncol] = false; // uncover the column containing the starred zero
|
||||
return 3; // repeat
|
||||
}
|
||||
}
|
||||
|
||||
return 4; // no starred zero in the row containing this primed zero
|
||||
}
|
||||
|
||||
int step4() {
|
||||
const size_t rows = matrix.rows(),
|
||||
columns = matrix.columns();
|
||||
|
||||
// seq contains pairs of row/column values where we have found
|
||||
// either a star or a prime that is part of the ``alternating sequence``.
|
||||
std::list<std::pair<size_t,size_t> > seq;
|
||||
// use saverow, savecol from step 3.
|
||||
std::pair<size_t,size_t> z0(saverow, savecol);
|
||||
seq.insert(seq.end(), z0);
|
||||
|
||||
// We have to find these two pairs:
|
||||
std::pair<size_t,size_t> z1(-1, -1);
|
||||
std::pair<size_t,size_t> z2n(-1, -1);
|
||||
|
||||
size_t row, col = savecol;
|
||||
/*
|
||||
Increment Set of Starred Zeros
|
||||
|
||||
1. Construct the ``alternating sequence'' of primed and starred zeros:
|
||||
|
||||
Z0 : Unpaired Z' from Step 4.2
|
||||
Z1 : The Z* in the column of Z0
|
||||
Z[2N] : The Z' in the row of Z[2N-1], if such a zero exists
|
||||
Z[2N+1] : The Z* in the column of Z[2N]
|
||||
|
||||
The sequence eventually terminates with an unpaired Z' = Z[2N] for some N.
|
||||
*/
|
||||
bool madepair;
|
||||
do {
|
||||
madepair = false;
|
||||
for ( row = 0 ; row < rows ; row++ ) {
|
||||
if ( mask_matrix(row,col) == STAR ) {
|
||||
z1.first = row;
|
||||
z1.second = col;
|
||||
if ( pair_in_list(z1, seq) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
madepair = true;
|
||||
seq.insert(seq.end(), z1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ( !madepair )
|
||||
break;
|
||||
|
||||
madepair = false;
|
||||
|
||||
for ( col = 0 ; col < columns ; col++ ) {
|
||||
if ( mask_matrix(row, col) == PRIME ) {
|
||||
z2n.first = row;
|
||||
z2n.second = col;
|
||||
if ( pair_in_list(z2n, seq) ) {
|
||||
continue;
|
||||
}
|
||||
madepair = true;
|
||||
seq.insert(seq.end(), z2n);
|
||||
break;
|
||||
}
|
||||
}
|
||||
} while ( madepair );
|
||||
|
||||
for ( std::list<std::pair<size_t,size_t> >::iterator i = seq.begin() ;
|
||||
i != seq.end() ;
|
||||
i++ ) {
|
||||
// 2. Unstar each starred zero of the sequence.
|
||||
if ( mask_matrix(i->first,i->second) == STAR )
|
||||
mask_matrix(i->first,i->second) = NORMAL;
|
||||
|
||||
// 3. Star each primed zero of the sequence,
|
||||
// thus increasing the number of starred zeros by one.
|
||||
if ( mask_matrix(i->first,i->second) == PRIME )
|
||||
mask_matrix(i->first,i->second) = STAR;
|
||||
}
|
||||
|
||||
// 4. Erase all primes, uncover all columns and rows,
|
||||
for ( size_t row = 0 ; row < mask_matrix.rows() ; row++ ) {
|
||||
for ( size_t col = 0 ; col < mask_matrix.columns() ; col++ ) {
|
||||
if ( mask_matrix(row,col) == PRIME ) {
|
||||
mask_matrix(row,col) = NORMAL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for ( size_t i = 0 ; i < rows ; i++ ) {
|
||||
row_mask[i] = false;
|
||||
}
|
||||
|
||||
for ( size_t i = 0 ; i < columns ; i++ ) {
|
||||
col_mask[i] = false;
|
||||
}
|
||||
|
||||
// and return to Step 2.
|
||||
return 2;
|
||||
}
|
||||
|
||||
int step5() {
|
||||
const size_t rows = matrix.rows(),
|
||||
columns = matrix.columns();
|
||||
/*
|
||||
New Zero Manufactures
|
||||
|
||||
1. Let h be the smallest uncovered entry in the (modified) distance matrix.
|
||||
2. Add h to all covered rows.
|
||||
3. Subtract h from all uncovered columns
|
||||
4. Return to Step 3, without altering stars, primes, or covers.
|
||||
*/
|
||||
double h = std::numeric_limits<double>::max();
|
||||
for ( size_t row = 0 ; row < rows ; row++ ) {
|
||||
if ( !row_mask[row] ) {
|
||||
for ( size_t col = 0 ; col < columns ; col++ ) {
|
||||
if ( !col_mask[col] ) {
|
||||
if ( h > matrix(row, col) && matrix(row, col) != 0 ) {
|
||||
h = matrix(row, col);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for ( size_t row = 0 ; row < rows ; row++ ) {
|
||||
if ( row_mask[row] ) {
|
||||
for ( size_t col = 0 ; col < columns ; col++ ) {
|
||||
matrix(row, col) += h;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for ( size_t col = 0 ; col < columns ; col++ ) {
|
||||
if ( !col_mask[col] ) {
|
||||
for ( size_t row = 0 ; row < rows ; row++ ) {
|
||||
matrix(row, col) -= h;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 3;
|
||||
}
|
||||
|
||||
Matrix<int> mask_matrix;
|
||||
Matrix<Data> matrix;
|
||||
bool *row_mask;
|
||||
bool *col_mask;
|
||||
size_t saverow = 0, savecol = 0;
|
||||
};
|
||||
|
||||
|
||||
#endif /* !defined(_MUNKRES_H_) */
|
27
libapi/sort/include/track.h
Executable file
@ -0,0 +1,27 @@
|
||||
#pragma once
|
||||
|
||||
#include <opencv2/core.hpp>
|
||||
#include "kalman_filter.h"
|
||||
|
||||
class Track {
|
||||
public:
|
||||
// Constructor
|
||||
Track();
|
||||
|
||||
// Destructor
|
||||
~Track() = default;
|
||||
|
||||
void Init(const cv::Rect& bbox);
|
||||
void Predict();
|
||||
void Update(const cv::Rect& bbox);
|
||||
cv::Rect GetStateAsBbox() const;
|
||||
float GetNIS() const;
|
||||
|
||||
int coast_cycles_ = 0, hit_streak_ = 0;
|
||||
|
||||
private:
|
||||
Eigen::VectorXd ConvertBboxToObservation(const cv::Rect& bbox) const;
|
||||
cv::Rect ConvertStateToBbox(const Eigen::VectorXd &state) const;
|
||||
|
||||
KalmanFilter kf_;
|
||||
};
|
46
libapi/sort/include/tracker.h
Executable file
@ -0,0 +1,46 @@
|
||||
#pragma once
|
||||
|
||||
#include <map>
|
||||
#include <opencv2/core.hpp>
|
||||
|
||||
#include "track.h"
|
||||
#include "munkres.h"
|
||||
#include "utils.h"
|
||||
|
||||
class Tracker {
|
||||
public:
|
||||
Tracker();
|
||||
~Tracker() = default;
|
||||
|
||||
static float CalculateIou(const cv::Rect& det, const Track& track);
|
||||
|
||||
static void HungarianMatching(const std::vector<std::vector<float>>& iou_matrix,
|
||||
size_t nrows, size_t ncols,
|
||||
std::vector<std::vector<float>>& association);
|
||||
|
||||
/**
|
||||
* Assigns detections to tracked object (both represented as bounding boxes)
|
||||
* Returns 2 lists of matches, unmatched_detections
|
||||
* @param detection
|
||||
* @param tracks
|
||||
* @param matched
|
||||
* @param unmatched_det
|
||||
* @param iou_threshold
|
||||
*/
|
||||
static void AssociateDetectionsToTrackers(const std::vector<cv::Rect>& detection,
|
||||
std::map<int, Track>& tracks,
|
||||
std::map<int, cv::Rect>& matched,
|
||||
std::vector<cv::Rect>& unmatched_det,
|
||||
float iou_threshold = 0.3);
|
||||
|
||||
void Run(const std::vector<cv::Rect>& detections);
|
||||
|
||||
std::map<int, Track> GetTracks();
|
||||
|
||||
private:
|
||||
// Hash-map between ID and corresponding tracker
|
||||
std::map<int, Track> tracks_;
|
||||
|
||||
// Assigned ID for each bounding box
|
||||
int id_;
|
||||
};
|
10
libapi/sort/include/utils.h
Executable file
@ -0,0 +1,10 @@
|
||||
#pragma once
|
||||
|
||||
constexpr int kNumColors = 32;
|
||||
|
||||
constexpr int kMaxCoastCycles = 1;
|
||||
|
||||
constexpr int kMinHits = 3;
|
||||
|
||||
// Set threshold to 0 to accept all detections
|
||||
constexpr float kMinConfidence = 0.6;
|
123
libapi/sort/src/kalman_filter.cpp
Executable file
@ -0,0 +1,123 @@
|
||||
#include "kalman_filter.h"
|
||||
|
||||
|
||||
KalmanFilter::KalmanFilter(unsigned int num_states, unsigned int num_obs) :
|
||||
num_states_(num_states), num_obs_(num_obs) {
|
||||
/*** Predict ***/
|
||||
// State vector
|
||||
x_ = Eigen::VectorXd::Zero(num_states);
|
||||
// Predicted(a prior) state vector
|
||||
x_predict_ = Eigen::VectorXd::Zero(num_states);
|
||||
|
||||
// State transition matrix F_
|
||||
F_ = Eigen::MatrixXd::Zero(num_states, num_states);
|
||||
|
||||
// Error covariance matrix P
|
||||
P_ = Eigen::MatrixXd::Zero(num_states, num_states);
|
||||
// Predicted(a prior) error covariance matrix
|
||||
P_predict_ = Eigen::MatrixXd::Zero(num_states, num_states);
|
||||
|
||||
// Covariance matrix of process noise
|
||||
Q_ = Eigen::MatrixXd::Zero(num_states, num_states);
|
||||
|
||||
/*** Update ***/
|
||||
// Observation matrix
|
||||
H_ = Eigen::MatrixXd::Zero(num_obs, num_states);
|
||||
|
||||
// Covariance matrix of observation noise
|
||||
R_ = Eigen::MatrixXd::Zero(num_obs, num_obs);
|
||||
|
||||
log_likelihood_delta_ = 0.0;
|
||||
NIS_ = 0.0;
|
||||
}
|
||||
|
||||
|
||||
void KalmanFilter::Coast() {
|
||||
x_predict_ = F_ * x_;
|
||||
P_predict_ = F_ * P_ * F_.transpose() + Q_;
|
||||
}
|
||||
|
||||
|
||||
void KalmanFilter::Predict() {
|
||||
Coast();
|
||||
x_ = x_predict_;
|
||||
P_ = P_predict_;
|
||||
}
|
||||
|
||||
|
||||
Eigen::VectorXd KalmanFilter::PredictionToObservation(const Eigen::VectorXd &state) {
|
||||
return (H_*state);
|
||||
}
|
||||
|
||||
|
||||
void KalmanFilter::Update(const Eigen::VectorXd& z) {
|
||||
Eigen::VectorXd z_predict = PredictionToObservation(x_predict_);
|
||||
|
||||
// y - innovation, z - real observation, z_predict - predicted observation
|
||||
Eigen::VectorXd y = z - z_predict;
|
||||
|
||||
Eigen::MatrixXd Ht = H_.transpose();
|
||||
|
||||
// S - innovation covariance
|
||||
Eigen::MatrixXd S = H_ * P_predict_ * Ht + R_;
|
||||
|
||||
NIS_ = y.transpose() * S.inverse() * y;
|
||||
|
||||
// std::cout << std::endl;
|
||||
// std::cout << "P_predict = " << std::endl;
|
||||
// std::cout << P_predict_ << std::endl;
|
||||
//
|
||||
//
|
||||
// std::cout << "Z = " << std::endl;
|
||||
// std::cout << z << std::endl;
|
||||
//
|
||||
// std::cout << "Z_pred = " << std::endl;
|
||||
// std::cout << z_predict << std::endl;
|
||||
//
|
||||
// std::cout << "y = " << std::endl;
|
||||
// std::cout << y << std::endl;
|
||||
//
|
||||
// std::cout << "S = " << std::endl;
|
||||
// std::cout << S << std::endl;
|
||||
//
|
||||
// std::cout << "NIS = " << NIS_ << std::endl;
|
||||
|
||||
|
||||
// K - Kalman gain
|
||||
Eigen::MatrixXd K = P_predict_ * Ht * S.inverse();
|
||||
|
||||
// Updated state estimation
|
||||
x_ = x_predict_ + K * y;
|
||||
|
||||
Eigen::MatrixXd I = Eigen::MatrixXd::Identity(num_states_, num_states_);
|
||||
// Joseph form
|
||||
//P_ = (I - K * H_) * P_predict_ * (I - K * H_).transpose() + K * R_ * K.transpose();
|
||||
// Optimal gain
|
||||
P_ = (I - K * H_) * P_predict_;
|
||||
}
|
||||
|
||||
|
||||
float KalmanFilter::CalculateLogLikelihood(const Eigen::VectorXd& y, const Eigen::MatrixXd& S) {
|
||||
float log_likelihood;
|
||||
|
||||
// Note: Computing log(M.determinant()) in Eigen C++ is risky for large matrices since it may overflow or underflow.
|
||||
// compute the Cholesky decomposition of the innovation covariance matrix, because it is symmetric
|
||||
// S = L * L^T = U^T * U
|
||||
// then retrieve factor L in the decomposition
|
||||
auto& L = S.llt().matrixL();
|
||||
|
||||
// find log determinant of innovation covariance matrix
|
||||
float log_determinant = 0;
|
||||
for (unsigned int i = 0; i < S.rows(); i++)
|
||||
log_determinant += log(L(i, i));
|
||||
log_determinant *= 2;
|
||||
|
||||
// log-likelihood expression for current iteration
|
||||
log_likelihood = -0.5 * (y.transpose() * S.inverse() * y + num_obs_ * log(2 * M_PI) + log_determinant);
|
||||
|
||||
if (std::isnan(log_likelihood)) {
|
||||
log_likelihood = -1e50;
|
||||
}
|
||||
|
||||
return log_likelihood;
|
||||
}
|
258
libapi/sort/src/main.cpp
Executable file
@ -0,0 +1,258 @@
|
||||
// /**
|
||||
// * SORT: A Simple, Online and Realtime Tracker
|
||||
// */
|
||||
|
||||
// #include <iostream>
|
||||
// #include <fstream>
|
||||
// #include <map>
|
||||
// #include <random>
|
||||
// #include <chrono>
|
||||
|
||||
// #include <opencv2/core.hpp>
|
||||
// #include <opencv2/imgproc.hpp>
|
||||
// #include <opencv2/highgui.hpp>
|
||||
|
||||
// #include <boost/program_options.hpp>
|
||||
// #include <boost/filesystem.hpp>
|
||||
|
||||
// #include "tracker.h"
|
||||
// #include "utils.h"
|
||||
|
||||
|
||||
// std::vector<std::vector<cv::Rect>> ProcessLabel(std::ifstream& label_file) {
|
||||
// // Process labels - group bounding boxes by frame index
|
||||
// std::vector<std::vector<cv::Rect>> bbox;
|
||||
// std::vector<cv::Rect> bbox_per_frame;
|
||||
// // Label index starts from 1
|
||||
// int current_frame_index = 1;
|
||||
// std::string line;
|
||||
|
||||
// while (std::getline(label_file, line)) {
|
||||
// std::stringstream ss(line);
|
||||
// // Label format <frame>, <id>, <bb_left>, <bb_top>, <bb_width>, <bb_height>, <conf>, <x>, <y>, <z>
|
||||
// std::vector<float> label;
|
||||
// std::string data;
|
||||
// while (getline(ss , data, ',')) {
|
||||
// label.push_back(std::stof(data));
|
||||
// }
|
||||
|
||||
// if (static_cast<int>(label[0]) != current_frame_index) {
|
||||
// current_frame_index = static_cast<int>(label[0]);
|
||||
// bbox.push_back(bbox_per_frame);
|
||||
// bbox_per_frame.clear();
|
||||
// }
|
||||
|
||||
// // Ignore low confidence detections
|
||||
// if (label[6] > kMinConfidence) {
|
||||
// bbox_per_frame.emplace_back(label[2], label[3], label[4], label[5]);
|
||||
// }
|
||||
// }
|
||||
// // Add bounding boxes from last frame
|
||||
// bbox.push_back(bbox_per_frame);
|
||||
// return bbox;
|
||||
// }
|
||||
|
||||
|
||||
// int main(int argc, const char *argv[]) {
|
||||
// // parse program input arguments
|
||||
// boost::program_options::options_description desc{"Options"};
|
||||
// desc.add_options()
|
||||
// ("help,h", "Help screen")
|
||||
// ("display,d", "Display online tracker output (slow) [False]");
|
||||
|
||||
// boost::program_options::variables_map vm;
|
||||
// boost::program_options::store(parse_command_line(argc, argv, desc), vm);
|
||||
// boost::program_options::notify(vm);
|
||||
|
||||
// if (vm.count("help")) {
|
||||
// std::cout << desc << '\n';
|
||||
// return -1;
|
||||
// }
|
||||
|
||||
// bool enable_display_flag = false;
|
||||
// if (vm.count("display")) {
|
||||
// enable_display_flag = true;
|
||||
// }
|
||||
|
||||
// std::vector<cv::Scalar> colors;
|
||||
// if (enable_display_flag) {
|
||||
// // Create a window to display original image
|
||||
// cv::namedWindow("Original", cv::WINDOW_AUTOSIZE);
|
||||
// // Create a window to display tracking result
|
||||
// cv::namedWindow("Tracking", cv::WINDOW_AUTOSIZE);
|
||||
|
||||
// // Generate random colors to visualize different bbox
|
||||
// std::random_device rd; //Will be used to obtain a seed for the random number engine
|
||||
// std::mt19937 gen(rd()); //Standard mersenne_twister_engine seeded with rd()
|
||||
// constexpr int max_random_value = 20;
|
||||
// std::uniform_int_distribution<> dis(0, max_random_value);
|
||||
// constexpr int factor = 255 / max_random_value;
|
||||
|
||||
// for (int n = 0; n < kNumColors; ++n) {
|
||||
// //Use dis to transform the random unsigned int generated by gen into an int in [0, 7]
|
||||
// colors.emplace_back(cv::Scalar(dis(gen) * factor, dis(gen) * factor, dis(gen) * factor));
|
||||
// }
|
||||
// }
|
||||
|
||||
// // All training dataset in MOT15
|
||||
// std::vector<std::string> dataset_names{"ADL-Rundle-6", "ADL-Rundle-8", "ETH-Bahnhof",
|
||||
// "ETH-Pedcross2", "ETH-Sunnyday", "KITTI-13",
|
||||
// "KITTI-17", "PETS09-S2L1", "TUD-Campus",
|
||||
// "TUD-Stadtmitte", "Venice-2"};
|
||||
|
||||
// // create SORT tracker
|
||||
// Tracker tracker;
|
||||
|
||||
// for (const auto& dataset_name : dataset_names) {
|
||||
// // Open label file and load detections from MOT dataset
|
||||
// // Note that it can also be replaced by detections from you own detector
|
||||
// std::string label_path = "../data/" + dataset_name + "/det.txt";
|
||||
// std::ifstream label_file(label_path);
|
||||
// if (!label_file.is_open()) {
|
||||
// std::cerr << "Could not open or find the label!!!" << std::endl;
|
||||
// return -1;
|
||||
// }
|
||||
// std::vector<std::vector<cv::Rect>> all_detections = ProcessLabel(label_file);
|
||||
// // Close label file
|
||||
// label_file.close();
|
||||
|
||||
// // Load image paths for visualization
|
||||
// std::vector<cv::String> images;
|
||||
// if (enable_display_flag) {
|
||||
// // Load images
|
||||
// cv::String path("../mot_benchmark/train/" + dataset_name + "/img1/*.jpg");
|
||||
// // Non-recursive
|
||||
// cv::glob(path, images);
|
||||
// }
|
||||
|
||||
// // Create output folder if it does not exist
|
||||
// std::string output_folder = "../output/";
|
||||
// boost::filesystem::path output_folder_path(output_folder);
|
||||
// if(boost::filesystem::create_directory(output_folder_path)) {
|
||||
// std::cerr<< "Directory Created: "<< output_folder <<std::endl;
|
||||
// }
|
||||
|
||||
// std::string output_path = output_folder + dataset_name + ".txt";
|
||||
// std::ofstream output_file(output_path);
|
||||
|
||||
// // std::string output_path_NIS = "../output/" + dataset_name + "-NIS.txt";
|
||||
// // std::ofstream output_file_NIS(output_path_NIS);
|
||||
|
||||
// if (output_file.is_open()) {
|
||||
// std::cout << "Result will be exported to " << output_path << std::endl;
|
||||
// } else {
|
||||
// std::cerr << "Unable to open output file" << std::endl;
|
||||
// return -1;
|
||||
// }
|
||||
|
||||
// size_t total_frames = all_detections.size();
|
||||
|
||||
// auto t1 = std::chrono::high_resolution_clock::now();
|
||||
// for (size_t i = 0; i < total_frames; i++) {
|
||||
// auto frame_index = i + 1;
|
||||
// std::cout << "************* NEW FRAME ************* " << std::endl;
|
||||
|
||||
// /*** Run SORT tracker ***/
|
||||
// const auto &detections = all_detections[i];
|
||||
// tracker.Run(detections);
|
||||
// const auto tracks = tracker.GetTracks();
|
||||
// /*** Tracker update done ***/
|
||||
|
||||
// std::cout << "Raw detections:" << std::endl;
|
||||
// for (const auto &det : detections) {
|
||||
// std::cout << frame_index << "," << "-1" << "," << det.tl().x << "," << det.tl().y
|
||||
// << "," << det.width << "," << det.height << std::endl;
|
||||
// }
|
||||
// std::cout << std::endl;
|
||||
|
||||
// for (auto &trk : tracks) {
|
||||
// const auto &bbox = trk.second.GetStateAsBbox();
|
||||
// // Note that we will not export coasted tracks
|
||||
// // If we export coasted tracks, the total number of false negative will decrease (and maybe ID switch)
|
||||
// // However, the total number of false positive will increase more (from experiments),
|
||||
// // which leads to MOTA decrease
|
||||
// // Developer can export coasted cycles if false negative tracks is critical in the system
|
||||
// if (trk.second.coast_cycles_ < kMaxCoastCycles
|
||||
// && (trk.second.hit_streak_ >= kMinHits || frame_index < kMinHits)) {
|
||||
// // Print to terminal for debugging
|
||||
// std::cout << frame_index << "," << trk.first << "," << bbox.tl().x << "," << bbox.tl().y
|
||||
// << "," << bbox.width << "," << bbox.height << ",1,-1,-1,-1"
|
||||
// << " Hit Streak = " << trk.second.hit_streak_
|
||||
// << " Coast Cycles = " << trk.second.coast_cycles_ << std::endl;
|
||||
|
||||
// // Export to text file for metrics evaluation
|
||||
// output_file << frame_index << "," << trk.first << "," << bbox.tl().x << "," << bbox.tl().y
|
||||
// << "," << bbox.width << "," << bbox.height << ",1,-1,-1,-1\n";
|
||||
|
||||
// // output_file_NIS << trk.second.GetNIS() << "\n";
|
||||
// }
|
||||
// }
|
||||
|
||||
// // Visualize tracking result
|
||||
// if (enable_display_flag) {
|
||||
// // Read image file
|
||||
// cv::Mat img = cv::imread(images[i]);
|
||||
// // Make a copy for display
|
||||
// cv::Mat img_tracking = img.clone();
|
||||
|
||||
// // Check for invalid input
|
||||
// if (img.empty()) {
|
||||
// std::cerr << "Could not open or find the image!!!" << std::endl;
|
||||
// return -1;
|
||||
// }
|
||||
|
||||
// for (const auto &det : detections) {
|
||||
// // Draw detections in red bounding box
|
||||
// cv::rectangle(img, det, cv::Scalar(0, 0, 255), 3);
|
||||
// }
|
||||
|
||||
// for (auto &trk : tracks) {
|
||||
// // only draw tracks which meet certain criteria
|
||||
// if (trk.second.coast_cycles_ < kMaxCoastCycles &&
|
||||
// (trk.second.hit_streak_ >= kMinHits || frame_index < kMinHits)) {
|
||||
// const auto &bbox = trk.second.GetStateAsBbox();
|
||||
// cv::putText(img_tracking, std::to_string(trk.first), cv::Point(bbox.tl().x, bbox.tl().y - 10),
|
||||
// cv::FONT_HERSHEY_DUPLEX, 2, cv::Scalar(255, 255, 255), 2);
|
||||
// cv::rectangle(img_tracking, bbox, colors[trk.first % kNumColors], 3);
|
||||
// }
|
||||
// }
|
||||
|
||||
// // Show detection and tracking result
|
||||
// cv::imshow("Original", img);
|
||||
// cv::imshow("Tracking", img_tracking);
|
||||
|
||||
// // Delay in ms
|
||||
// auto key = cv::waitKey(33);
|
||||
|
||||
// // Exit if ESC pressed
|
||||
// if (27 == key) {
|
||||
// return 0;
|
||||
// } else if (32 == key) {
|
||||
// // Press Space to pause and press it again to resume
|
||||
// while (true) {
|
||||
// key = cv::waitKey(0);
|
||||
// if (32 == key) {
|
||||
// break;
|
||||
// } else if (27 == key) {
|
||||
// return 0;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// } // end of enable_display_flag
|
||||
// } // end of iterating all frames
|
||||
|
||||
// auto t2 = std::chrono::high_resolution_clock::now();
|
||||
// std::chrono::duration<double> time_span = std::chrono::duration_cast<std::chrono::duration<double>>(t2 - t1);
|
||||
|
||||
// std::cout << "********************************" << std::endl;
|
||||
// std::cout << "Total tracking took: " << time_span.count() << " for " << total_frames << " frames" << std::endl;
|
||||
// std::cout << "FPS = " << total_frames / time_span.count() << std::endl;
|
||||
// if (enable_display_flag) {
|
||||
// std::cout << "Note: to get real runtime results run without the option: --display" << std::endl;
|
||||
// }
|
||||
// std::cout << "********************************" << std::endl;
|
||||
|
||||
// output_file.close();
|
||||
// } // end of iterating all dataset
|
||||
// return 0;
|
||||
// }
|
25
libapi/sort/src/munkres.cpp
Executable file
@ -0,0 +1,25 @@
|
||||
/*
|
||||
* Copyright (c) 2007 John Weaver
|
||||
* Copyright (c) 2015 Miroslav Krajicek
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "munkres.h"
|
||||
|
||||
template class Munkres<double>;
|
||||
template class Munkres<float>;
|
||||
template class Munkres<int>;
|
||||
|
139
libapi/sort/src/track.cpp
Executable file
@ -0,0 +1,139 @@
|
||||
#include "track.h"
|
||||
|
||||
|
||||
Track::Track() : kf_(8, 4) {
|
||||
|
||||
/*** Define constant velocity model ***/
|
||||
// state - center_x, center_y, width, height, v_cx, v_cy, v_width, v_height
|
||||
kf_.F_ <<
|
||||
1, 0, 0, 0, 1, 0, 0, 0,
|
||||
0, 1, 0, 0, 0, 1, 0, 0,
|
||||
0, 0, 1, 0, 0, 0, 1, 0,
|
||||
0, 0, 0, 1, 0, 0, 0, 1,
|
||||
0, 0, 0, 0, 1, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 1, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 1, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 1;
|
||||
|
||||
// Give high uncertainty to the unobservable initial velocities
|
||||
kf_.P_ <<
|
||||
10, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 10, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 10, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 10, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 10000, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 10000, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 10000, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 10000;
|
||||
|
||||
|
||||
kf_.H_ <<
|
||||
1, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 1, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 1, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 1, 0, 0, 0, 0;
|
||||
|
||||
kf_.Q_ <<
|
||||
1, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 1, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 1, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 1, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0.01, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0.01, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0.0001, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0.0001;
|
||||
|
||||
kf_.R_ <<
|
||||
1, 0, 0, 0,
|
||||
0, 1, 0, 0,
|
||||
0, 0, 10, 0,
|
||||
0, 0, 0, 10;
|
||||
}
|
||||
|
||||
|
||||
// Get predicted locations from existing trackers
|
||||
// dt is time elapsed between the current and previous measurements
|
||||
void Track::Predict() {
|
||||
kf_.Predict();
|
||||
|
||||
// hit streak count will be reset
|
||||
if (coast_cycles_ > 0) {
|
||||
hit_streak_ = 0;
|
||||
}
|
||||
// accumulate coast cycle count
|
||||
coast_cycles_++;
|
||||
}
|
||||
|
||||
|
||||
// Update matched trackers with assigned detections
|
||||
void Track::Update(const cv::Rect& bbox) {
|
||||
|
||||
// get measurement update, reset coast cycle count
|
||||
coast_cycles_ = 0;
|
||||
// accumulate hit streak count
|
||||
hit_streak_++;
|
||||
|
||||
// observation - center_x, center_y, area, ratio
|
||||
Eigen::VectorXd observation = ConvertBboxToObservation(bbox);
|
||||
kf_.Update(observation);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
// Create and initialize new trackers for unmatched detections, with initial bounding box
|
||||
void Track::Init(const cv::Rect &bbox) {
|
||||
kf_.x_.head(4) << ConvertBboxToObservation(bbox);
|
||||
hit_streak_++;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the current bounding box estimate
|
||||
* @return
|
||||
*/
|
||||
cv::Rect Track::GetStateAsBbox() const {
|
||||
return ConvertStateToBbox(kf_.x_);
|
||||
}
|
||||
|
||||
|
||||
float Track::GetNIS() const {
|
||||
return kf_.NIS_;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Takes a bounding box in the form [x, y, width, height] and returns z in the form
|
||||
* [x, y, s, r] where x,y is the centre of the box and s is the scale/area and r is
|
||||
* the aspect ratio
|
||||
*
|
||||
* @param bbox
|
||||
* @return
|
||||
*/
|
||||
Eigen::VectorXd Track::ConvertBboxToObservation(const cv::Rect& bbox) const{
|
||||
Eigen::VectorXd observation = Eigen::VectorXd::Zero(4);
|
||||
auto width = static_cast<float>(bbox.width);
|
||||
auto height = static_cast<float>(bbox.height);
|
||||
float center_x = bbox.x + width / 2;
|
||||
float center_y = bbox.y + height / 2;
|
||||
observation << center_x, center_y, width, height;
|
||||
return observation;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Takes a bounding box in the centre form [x,y,s,r] and returns it in the form
|
||||
* [x1,y1,x2,y2] where x1,y1 is the top left and x2,y2 is the bottom right
|
||||
*
|
||||
* @param state
|
||||
* @return
|
||||
*/
|
||||
cv::Rect Track::ConvertStateToBbox(const Eigen::VectorXd &state) const {
|
||||
// state - center_x, center_y, width, height, v_cx, v_cy, v_width, v_height
|
||||
auto width = std::max(0, static_cast<int>(state[2]));
|
||||
auto height = std::max(0, static_cast<int>(state[3]));
|
||||
auto tl_x = static_cast<int>(state[0] - width / 2.0);
|
||||
auto tl_y = static_cast<int>(state[1] - height / 2.0);
|
||||
cv::Rect rect(cv::Point(tl_x, tl_y), cv::Size(width, height));
|
||||
return rect;
|
||||
}
|
181
libapi/sort/src/tracker.cpp
Executable file
@ -0,0 +1,181 @@
|
||||
#include "tracker.h"
|
||||
|
||||
|
||||
Tracker::Tracker() {
|
||||
id_ = 0;
|
||||
}
|
||||
|
||||
float Tracker::CalculateIou(const cv::Rect& det, const Track& track) {
|
||||
auto trk = track.GetStateAsBbox();
|
||||
// get min/max points
|
||||
auto xx1 = std::max(det.tl().x, trk.tl().x);
|
||||
auto yy1 = std::max(det.tl().y, trk.tl().y);
|
||||
auto xx2 = std::min(det.br().x, trk.br().x);
|
||||
auto yy2 = std::min(det.br().y, trk.br().y);
|
||||
auto w = std::max(0, xx2 - xx1);
|
||||
auto h = std::max(0, yy2 - yy1);
|
||||
|
||||
// calculate area of intersection and union
|
||||
float det_area = det.area();
|
||||
float trk_area = trk.area();
|
||||
auto intersection_area = w * h;
|
||||
float union_area = det_area + trk_area - intersection_area;
|
||||
auto iou = intersection_area / union_area;
|
||||
return iou;
|
||||
}
|
||||
|
||||
|
||||
void Tracker::HungarianMatching(const std::vector<std::vector<float>>& iou_matrix,
|
||||
size_t nrows, size_t ncols,
|
||||
std::vector<std::vector<float>>& association) {
|
||||
Matrix<float> matrix(nrows, ncols);
|
||||
// Initialize matrix with IOU values
|
||||
for (size_t i = 0 ; i < nrows ; i++) {
|
||||
for (size_t j = 0 ; j < ncols ; j++) {
|
||||
// Multiply by -1 to find max cost
|
||||
if (iou_matrix[i][j] != 0) {
|
||||
matrix(i, j) = -iou_matrix[i][j];
|
||||
}
|
||||
else {
|
||||
// TODO: figure out why we have to assign value to get correct result
|
||||
matrix(i, j) = 1.0f;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// // Display begin matrix state.
|
||||
// for (size_t row = 0 ; row < nrows ; row++) {
|
||||
// for (size_t col = 0 ; col < ncols ; col++) {
|
||||
// std::cout.width(10);
|
||||
// std::cout << matrix(row,col) << ",";
|
||||
// }
|
||||
// std::cout << std::endl;
|
||||
// }
|
||||
// std::cout << std::endl;
|
||||
|
||||
|
||||
// Apply Kuhn-Munkres algorithm to matrix.
|
||||
Munkres<float> m;
|
||||
m.solve(matrix);
|
||||
|
||||
// // Display solved matrix.
|
||||
// for (size_t row = 0 ; row < nrows ; row++) {
|
||||
// for (size_t col = 0 ; col < ncols ; col++) {
|
||||
// std::cout.width(2);
|
||||
// std::cout << matrix(row,col) << ",";
|
||||
// }
|
||||
// std::cout << std::endl;
|
||||
// }
|
||||
// std::cout << std::endl;
|
||||
|
||||
for (size_t i = 0 ; i < nrows ; i++) {
|
||||
for (size_t j = 0 ; j < ncols ; j++) {
|
||||
association[i][j] = matrix(i, j);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Tracker::AssociateDetectionsToTrackers(const std::vector<cv::Rect>& detection,
|
||||
std::map<int, Track>& tracks,
|
||||
std::map<int, cv::Rect>& matched,
|
||||
std::vector<cv::Rect>& unmatched_det,
|
||||
float iou_threshold) {
|
||||
|
||||
// Set all detection as unmatched if no tracks existing
|
||||
if (tracks.empty()) {
|
||||
for (const auto& det : detection) {
|
||||
unmatched_det.push_back(det);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
std::vector<std::vector<float>> iou_matrix;
|
||||
// resize IOU matrix based on number of detection and tracks
|
||||
iou_matrix.resize(detection.size(), std::vector<float>(tracks.size()));
|
||||
|
||||
std::vector<std::vector<float>> association;
|
||||
// resize association matrix based on number of detection and tracks
|
||||
association.resize(detection.size(), std::vector<float>(tracks.size()));
|
||||
|
||||
|
||||
// row - detection, column - tracks
|
||||
for (size_t i = 0; i < detection.size(); i++) {
|
||||
size_t j = 0;
|
||||
for (const auto& trk : tracks) {
|
||||
iou_matrix[i][j] = CalculateIou(detection[i], trk.second);
|
||||
j++;
|
||||
}
|
||||
}
|
||||
|
||||
// Find association
|
||||
HungarianMatching(iou_matrix, detection.size(), tracks.size(), association);
|
||||
|
||||
for (size_t i = 0; i < detection.size(); i++) {
|
||||
bool matched_flag = false;
|
||||
size_t j = 0;
|
||||
for (const auto& trk : tracks) {
|
||||
if (0 == association[i][j]) {
|
||||
// Filter out matched with low IOU
|
||||
if (iou_matrix[i][j] >= iou_threshold) {
|
||||
matched[trk.first] = detection[i];
|
||||
matched_flag = true;
|
||||
}
|
||||
// It builds 1 to 1 association, so we can break from here
|
||||
break;
|
||||
}
|
||||
j++;
|
||||
}
|
||||
// if detection cannot match with any tracks
|
||||
if (!matched_flag) {
|
||||
unmatched_det.push_back(detection[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Tracker::Run(const std::vector<cv::Rect>& detections) {
|
||||
|
||||
/*** Predict internal tracks from previous frame ***/
|
||||
for (auto &track : tracks_) {
|
||||
track.second.Predict();
|
||||
}
|
||||
|
||||
// Hash-map between track ID and associated detection bounding box
|
||||
std::map<int, cv::Rect> matched;
|
||||
// vector of unassociated detections
|
||||
std::vector<cv::Rect> unmatched_det;
|
||||
|
||||
// return values - matched, unmatched_det
|
||||
if (!detections.empty()) {
|
||||
AssociateDetectionsToTrackers(detections, tracks_, matched, unmatched_det);
|
||||
}
|
||||
|
||||
/*** Update tracks with associated bbox ***/
|
||||
for (const auto &match : matched) {
|
||||
const auto &ID = match.first;
|
||||
tracks_[ID].Update(match.second);
|
||||
}
|
||||
|
||||
/*** Create new tracks for unmatched detections ***/
|
||||
for (const auto &det : unmatched_det) {
|
||||
Track tracker;
|
||||
tracker.Init(det);
|
||||
// Create new track and generate new ID
|
||||
tracks_[id_++] = tracker;
|
||||
}
|
||||
|
||||
/*** Delete lose tracked tracks ***/
|
||||
for (auto it = tracks_.begin(); it != tracks_.end();) {
|
||||
if (it->second.coast_cycles_ > kMaxCoastCycles) {
|
||||
it = tracks_.erase(it);
|
||||
} else {
|
||||
it++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
std::map<int, Track> Tracker::GetTracks() {
|
||||
return tracks_;
|
||||
}
|
688
libapi/svp_npu/libapi_npu_model.c
Executable file
@ -0,0 +1,688 @@
|
||||
/*
|
||||
Copyright (c), 2001-2022, Shenshu Tech. Co., Ltd.
|
||||
*/
|
||||
#include "wrapperncnn.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <signal.h>
|
||||
#include <semaphore.h>
|
||||
#include <pthread.h>
|
||||
#include <math.h>
|
||||
|
||||
#include <sys/mman.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include "ot_common_svp.h"
|
||||
#include "libapi_common_svp.h"
|
||||
#include "libapi_npu_model.h"
|
||||
|
||||
static npu_acl_model_t g_npu_acl_model[MAX_THREAD_NUM] = {0};
|
||||
|
||||
td_s32 libapi_npu_load_model_with_mem(const char *model_path, td_u32 model_index)
|
||||
{
|
||||
if (g_npu_acl_model[model_index].is_load_flag) {
|
||||
macro_svp_trace_err("has already loaded a model\n");
|
||||
return TD_FAILURE;
|
||||
}
|
||||
|
||||
td_s32 ret = aclmdlQuerySize(model_path, &g_npu_acl_model[model_index].model_mem_size,
|
||||
&g_npu_acl_model[model_index].model_weight_size);
|
||||
if (ret != ACL_ERROR_NONE) {
|
||||
macro_svp_trace_err("query model failed, model file is %s\n", model_path);
|
||||
return TD_FAILURE;
|
||||
}
|
||||
|
||||
ret = aclrtMalloc(&g_npu_acl_model[model_index].model_mem_ptr, g_npu_acl_model[model_index].model_mem_size,
|
||||
ACL_MEM_MALLOC_HUGE_FIRST);
|
||||
if (ret != ACL_ERROR_NONE) {
|
||||
macro_svp_trace_err("malloc buffer for mem failed, require size is %lu\n",
|
||||
g_npu_acl_model[model_index].model_mem_size);
|
||||
return TD_FAILURE;
|
||||
}
|
||||
|
||||
ret = aclrtMalloc(&g_npu_acl_model[model_index].model_weight_ptr, g_npu_acl_model[model_index].model_weight_size,
|
||||
ACL_MEM_MALLOC_HUGE_FIRST);
|
||||
if (ret != ACL_ERROR_NONE) {
|
||||
macro_svp_trace_err("malloc buffer for weight fail, require size is %lu\n",
|
||||
g_npu_acl_model[model_index].model_weight_size);
|
||||
return TD_FAILURE;
|
||||
}
|
||||
|
||||
ret = aclmdlLoadFromFileWithMem(model_path, &g_npu_acl_model[model_index].model_id,
|
||||
g_npu_acl_model[model_index].model_mem_ptr, g_npu_acl_model[model_index].model_mem_size,
|
||||
g_npu_acl_model[model_index].model_weight_ptr, g_npu_acl_model[model_index].model_weight_size);
|
||||
if (ret != ACL_ERROR_NONE) {
|
||||
macro_svp_trace_err("load model from file failed, model file is %s\n", model_path);
|
||||
return TD_FAILURE;
|
||||
}
|
||||
|
||||
macro_svp_trace_info("load mem_size:%lu weight_size:%lu id:%d\n", g_npu_acl_model[model_index].model_mem_size,
|
||||
g_npu_acl_model[model_index].model_weight_size, g_npu_acl_model[model_index].model_id);
|
||||
|
||||
g_npu_acl_model[model_index].is_load_flag = TD_TRUE;
|
||||
macro_svp_trace_info("load model %s success\n", model_path);
|
||||
|
||||
return TD_SUCCESS;
|
||||
}
|
||||
|
||||
td_s32 libapi_npu_load_model_with_mem_cached(const char *model_path, td_u32 model_index)
|
||||
{
|
||||
if (g_npu_acl_model[model_index].is_load_flag) {
|
||||
macro_svp_trace_err("has already loaded a model\n");
|
||||
return TD_FAILURE;
|
||||
}
|
||||
|
||||
td_s32 ret = aclmdlQuerySize(model_path, &g_npu_acl_model[model_index].model_mem_size,
|
||||
&g_npu_acl_model[model_index].model_weight_size);
|
||||
if (ret != ACL_ERROR_NONE) {
|
||||
macro_svp_trace_err("query model failed, model file is %s\n", model_path);
|
||||
return TD_FAILURE;
|
||||
}
|
||||
|
||||
ret = ss_mpi_sys_mmz_alloc_cached(&g_npu_acl_model[model_index].model_mem_phy_addr,
|
||||
&g_npu_acl_model[model_index].model_mem_ptr, "model_mem", NULL, g_npu_acl_model[model_index].model_mem_size);
|
||||
if (ret != ACL_ERROR_NONE) {
|
||||
macro_svp_trace_err("malloc buffer for mem failed\n");
|
||||
return TD_FAILURE;
|
||||
}
|
||||
memset_s(g_npu_acl_model[model_index].model_mem_ptr, g_npu_acl_model[model_index].model_mem_size, 0,
|
||||
g_npu_acl_model[model_index].model_mem_size);
|
||||
ss_mpi_sys_flush_cache(g_npu_acl_model[model_index].model_mem_phy_addr, g_npu_acl_model[model_index].model_mem_ptr,
|
||||
g_npu_acl_model[model_index].model_mem_size);
|
||||
|
||||
ret = ss_mpi_sys_mmz_alloc_cached(&g_npu_acl_model[model_index].model_weight_phy_addr,
|
||||
&g_npu_acl_model[model_index].model_weight_ptr, "model_weight",
|
||||
NULL, g_npu_acl_model[model_index].model_weight_size);
|
||||
if (ret != ACL_ERROR_NONE) {
|
||||
macro_svp_trace_err("malloc buffer for weight fail\n");
|
||||
return TD_FAILURE;
|
||||
}
|
||||
memset_s(g_npu_acl_model[model_index].model_weight_ptr, g_npu_acl_model[model_index].model_weight_size, 0,
|
||||
g_npu_acl_model[model_index].model_weight_size);
|
||||
ss_mpi_sys_flush_cache(g_npu_acl_model[model_index].model_weight_phy_addr,
|
||||
g_npu_acl_model[model_index].model_weight_ptr, g_npu_acl_model[model_index].model_weight_size);
|
||||
|
||||
ret = aclmdlLoadFromFileWithMem(model_path, &g_npu_acl_model[model_index].model_id,
|
||||
g_npu_acl_model[model_index].model_mem_ptr, g_npu_acl_model[model_index].model_mem_size,
|
||||
g_npu_acl_model[model_index].model_weight_ptr, g_npu_acl_model[model_index].model_weight_size);
|
||||
if (ret != ACL_ERROR_NONE) {
|
||||
macro_svp_trace_err("load model from file failed, model file is %s\n", model_path);
|
||||
return TD_FAILURE;
|
||||
}
|
||||
|
||||
macro_svp_trace_info("load mem_size:%lu weight_size:%lu id:%d\n", g_npu_acl_model[model_index].model_mem_size,
|
||||
g_npu_acl_model[model_index].model_weight_size, g_npu_acl_model[model_index].model_id);
|
||||
|
||||
g_npu_acl_model[model_index].is_load_flag = TD_TRUE;
|
||||
macro_svp_trace_info("load model %s success\n", model_path);
|
||||
|
||||
return TD_SUCCESS;
|
||||
}
|
||||
|
||||
td_s32 libapi_npu_create_desc(td_u32 model_index)
|
||||
{
|
||||
td_s32 ret;
|
||||
|
||||
g_npu_acl_model[model_index].model_desc = aclmdlCreateDesc();
|
||||
if (g_npu_acl_model[model_index].model_desc == TD_NULL) {
|
||||
macro_svp_trace_err("create model description failed\n");
|
||||
return TD_FAILURE;
|
||||
}
|
||||
|
||||
ret = aclmdlGetDesc(g_npu_acl_model[model_index].model_desc, g_npu_acl_model[model_index].model_id);
|
||||
if (ret != ACL_ERROR_NONE) {
|
||||
macro_svp_trace_err("get model description failed\n");
|
||||
return TD_FAILURE;
|
||||
}
|
||||
|
||||
macro_svp_trace_info("create model description success\n");
|
||||
|
||||
return TD_SUCCESS;
|
||||
}
|
||||
|
||||
td_void libapi_npu_destroy_desc(td_u32 model_index)
|
||||
{
|
||||
if (g_npu_acl_model[model_index].model_desc != TD_NULL) {
|
||||
(td_void)aclmdlDestroyDesc(g_npu_acl_model[model_index].model_desc);
|
||||
g_npu_acl_model[model_index].model_desc = TD_NULL;
|
||||
}
|
||||
|
||||
macro_svp_trace_info("destroy model description success\n");
|
||||
}
|
||||
|
||||
td_s32 libapi_npu_get_input_size_by_index(const td_u32 index, size_t *input_size, td_u32 model_index)
|
||||
{
|
||||
if (g_npu_acl_model[model_index].model_desc == TD_NULL) {
|
||||
macro_svp_trace_err("no model description, create input failed\n");
|
||||
return TD_FAILURE;
|
||||
}
|
||||
|
||||
*input_size = aclmdlGetInputSizeByIndex(g_npu_acl_model[model_index].model_desc, index);
|
||||
|
||||
return TD_SUCCESS;
|
||||
}
|
||||
|
||||
td_s32 libapi_npu_create_input_dataset(td_u32 model_index)
|
||||
{
|
||||
/* om used in this sample has only one input */
|
||||
if (g_npu_acl_model[model_index].model_desc == TD_NULL) {
|
||||
macro_svp_trace_err("no model description, create input failed\n");
|
||||
return TD_FAILURE;
|
||||
}
|
||||
|
||||
g_npu_acl_model[model_index].input_dataset = aclmdlCreateDataset();
|
||||
if (g_npu_acl_model[model_index].input_dataset == TD_NULL) {
|
||||
macro_svp_trace_err("can't create dataset, create input failed\n");
|
||||
return TD_FAILURE;
|
||||
}
|
||||
|
||||
macro_svp_trace_info("create model input dataset success\n");
|
||||
return TD_SUCCESS;
|
||||
}
|
||||
|
||||
td_void libapi_npu_destroy_input_dataset(td_u32 model_index)
|
||||
{
|
||||
if (g_npu_acl_model[model_index].input_dataset == TD_NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
aclmdlDestroyDataset(g_npu_acl_model[model_index].input_dataset);
|
||||
g_npu_acl_model[model_index].input_dataset = TD_NULL;
|
||||
|
||||
macro_svp_trace_info("destroy model input dataset success\n");
|
||||
}
|
||||
|
||||
td_s32 libapi_npu_create_input_databuf(td_void *data_buf, size_t data_len, td_u32 model_index)
|
||||
{
|
||||
/* om used in this sample has only one input */
|
||||
if (g_npu_acl_model[model_index].model_desc == TD_NULL) {
|
||||
macro_svp_trace_err("no model description, create input failed\n");
|
||||
return TD_FAILURE;
|
||||
}
|
||||
|
||||
size_t input_size = aclmdlGetInputSizeByIndex(g_npu_acl_model[model_index].model_desc, 0);
|
||||
if (data_len != input_size) {
|
||||
macro_svp_trace_err("input image size[%zu] != model input size[%zu]\n", data_len, input_size);
|
||||
return TD_FAILURE;
|
||||
}
|
||||
|
||||
aclDataBuffer *input_data = aclCreateDataBuffer(data_buf, data_len);
|
||||
if (input_data == TD_NULL) {
|
||||
macro_svp_trace_err("can't create data buffer, create input failed\n");
|
||||
return TD_FAILURE;
|
||||
}
|
||||
|
||||
aclError ret = aclmdlAddDatasetBuffer(g_npu_acl_model[model_index].input_dataset, input_data);
|
||||
if (ret != ACL_SUCCESS) {
|
||||
macro_svp_trace_err("add input dataset buffer failed, ret is %d\n", ret);
|
||||
(void)aclDestroyDataBuffer(input_data);
|
||||
input_data = TD_NULL;
|
||||
return TD_FAILURE;
|
||||
}
|
||||
macro_svp_trace_info("create model input success\n");
|
||||
|
||||
return TD_SUCCESS;
|
||||
}
|
||||
|
||||
td_void libapi_npu_destroy_input_databuf(td_u32 model_index)
|
||||
{
|
||||
td_u32 i;
|
||||
|
||||
if (g_npu_acl_model[model_index].input_dataset == TD_NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < aclmdlGetDatasetNumBuffers(g_npu_acl_model[model_index].input_dataset); ++i) {
|
||||
aclDataBuffer *data_buffer = aclmdlGetDatasetBuffer(g_npu_acl_model[model_index].input_dataset, i);
|
||||
aclDestroyDataBuffer(data_buffer);
|
||||
}
|
||||
|
||||
macro_svp_trace_info("destroy model input data buf success\n");
|
||||
}
|
||||
|
||||
td_s32 libapi_npu_create_cached_input(td_u32 model_index)
|
||||
{
|
||||
td_u32 input_size;
|
||||
if (g_npu_acl_model[model_index].model_desc == TD_NULL) {
|
||||
macro_svp_trace_err("no model description, create input failed\n");
|
||||
return TD_FAILURE;
|
||||
}
|
||||
|
||||
g_npu_acl_model[model_index].input_dataset = aclmdlCreateDataset();
|
||||
if (g_npu_acl_model[model_index].input_dataset == TD_NULL) {
|
||||
macro_svp_trace_err("can't create dataset, create input failed\n");
|
||||
return TD_FAILURE;
|
||||
}
|
||||
|
||||
input_size = aclmdlGetNumInputs(g_npu_acl_model[model_index].model_desc);
|
||||
for (td_u32 i = 0; i < input_size; i++) {
|
||||
td_u32 buffer_size = aclmdlGetInputSizeByIndex(g_npu_acl_model[model_index].model_desc, i);
|
||||
td_void *input_buffer = TD_NULL;
|
||||
|
||||
td_s32 ret = ss_mpi_sys_mmz_alloc_cached(&g_npu_acl_model[model_index].input_phy_addr[i],
|
||||
&input_buffer, "input", NULL, buffer_size);
|
||||
if (ret != ACL_ERROR_NONE) {
|
||||
macro_svp_trace_err("can't malloc buffer, size is %u, create input failed\n", buffer_size);
|
||||
return TD_FAILURE;
|
||||
}
|
||||
memset_s(input_buffer, buffer_size, 0, buffer_size);
|
||||
ss_mpi_sys_flush_cache(g_npu_acl_model[model_index].input_phy_addr[i], input_buffer, buffer_size);
|
||||
|
||||
aclDataBuffer *input_data = aclCreateDataBuffer(input_buffer, buffer_size);
|
||||
if (input_data == TD_NULL) {
|
||||
macro_svp_trace_err("can't create data buffer, create input failed\n");
|
||||
aclrtFree(input_buffer);
|
||||
return TD_FAILURE;
|
||||
}
|
||||
|
||||
ret = aclmdlAddDatasetBuffer(g_npu_acl_model[model_index].input_dataset, input_data);
|
||||
if (ret != ACL_ERROR_NONE) {
|
||||
macro_svp_trace_err("can't add data buffer, create input failed\n");
|
||||
aclrtFree(input_buffer);
|
||||
aclDestroyDataBuffer(input_data);
|
||||
return TD_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
macro_svp_trace_info("create model input cached TD_SUCCESS\n");
|
||||
return TD_SUCCESS;
|
||||
}
|
||||
|
||||
td_s32 libapi_npu_create_cached_output(td_u32 model_index)
|
||||
{
|
||||
td_u32 output_size;
|
||||
|
||||
if (g_npu_acl_model[model_index].model_desc == TD_NULL) {
|
||||
macro_svp_trace_err("no model description, create output failed\n");
|
||||
return TD_FAILURE;
|
||||
}
|
||||
|
||||
g_npu_acl_model[model_index].output_dataset = aclmdlCreateDataset();
|
||||
if (g_npu_acl_model[model_index].output_dataset == TD_NULL) {
|
||||
macro_svp_trace_err("can't create dataset, create output failed\n");
|
||||
return TD_FAILURE;
|
||||
}
|
||||
|
||||
output_size = aclmdlGetNumOutputs(g_npu_acl_model[model_index].model_desc);
|
||||
for (td_u32 i = 0; i < output_size; ++i) {
|
||||
td_u32 buffer_size = aclmdlGetOutputSizeByIndex(g_npu_acl_model[model_index].model_desc, i);
|
||||
td_void *output_buffer = TD_NULL;
|
||||
|
||||
td_s32 ret = ss_mpi_sys_mmz_alloc_cached(&g_npu_acl_model[model_index].output_phy_addr[i],
|
||||
&output_buffer, "output", NULL, buffer_size);
|
||||
if (ret != ACL_ERROR_NONE) {
|
||||
macro_svp_trace_err("can't malloc buffer, size is %u, create output failed\n", buffer_size);
|
||||
return TD_FAILURE;
|
||||
}
|
||||
memset_s(output_buffer, buffer_size, 0, buffer_size);
|
||||
ss_mpi_sys_flush_cache(g_npu_acl_model[model_index].output_phy_addr[i], output_buffer, buffer_size);
|
||||
|
||||
aclDataBuffer *output_data = aclCreateDataBuffer(output_buffer, buffer_size);
|
||||
if (output_data == TD_NULL) {
|
||||
macro_svp_trace_err("can't create data buffer, create output failed\n");
|
||||
aclrtFree(output_buffer);
|
||||
return TD_FAILURE;
|
||||
}
|
||||
|
||||
ret = aclmdlAddDatasetBuffer(g_npu_acl_model[model_index].output_dataset, output_data);
|
||||
if (ret != ACL_ERROR_NONE) {
|
||||
macro_svp_trace_err("can't add data buffer, create output failed\n");
|
||||
aclrtFree(output_buffer);
|
||||
aclDestroyDataBuffer(output_data);
|
||||
return TD_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
macro_svp_trace_info("create model output cached TD_SUCCESS\n");
|
||||
return TD_SUCCESS;
|
||||
}
|
||||
|
||||
td_void libapi_npu_destroy_cached_input(td_u32 model_index)
|
||||
{
|
||||
if (g_npu_acl_model[model_index].input_dataset == TD_NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (td_u32 i = 0; i < aclmdlGetDatasetNumBuffers(g_npu_acl_model[model_index].input_dataset); ++i) {
|
||||
aclDataBuffer *data_buffer = aclmdlGetDatasetBuffer(g_npu_acl_model[model_index].input_dataset, i);
|
||||
td_void *data = aclGetDataBufferAddr(data_buffer);
|
||||
ss_mpi_sys_mmz_free(g_npu_acl_model[model_index].input_phy_addr[i], data);
|
||||
(td_void)aclDestroyDataBuffer(data_buffer);
|
||||
}
|
||||
|
||||
(td_void)aclmdlDestroyDataset(g_npu_acl_model[model_index].input_dataset);
|
||||
g_npu_acl_model[model_index].input_dataset = TD_NULL;
|
||||
}
|
||||
|
||||
td_void libapi_npu_destroy_cached_output(td_u32 model_index)
|
||||
{
|
||||
if (g_npu_acl_model[model_index].output_dataset == TD_NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (td_u32 i = 0; i < aclmdlGetDatasetNumBuffers(g_npu_acl_model[model_index].output_dataset); ++i) {
|
||||
aclDataBuffer *data_buffer = aclmdlGetDatasetBuffer(g_npu_acl_model[model_index].output_dataset, i);
|
||||
td_void *data = aclGetDataBufferAddr(data_buffer);
|
||||
ss_mpi_sys_mmz_free(g_npu_acl_model[model_index].output_phy_addr[i], data);
|
||||
(td_void)aclDestroyDataBuffer(data_buffer);
|
||||
}
|
||||
|
||||
(td_void)aclmdlDestroyDataset(g_npu_acl_model[model_index].output_dataset);
|
||||
g_npu_acl_model[model_index].output_dataset = TD_NULL;
|
||||
}
|
||||
|
||||
td_s32 libapi_npu_create_output(td_u32 model_index)
|
||||
{
|
||||
td_u32 output_size;
|
||||
|
||||
if (g_npu_acl_model[model_index].model_desc == TD_NULL) {
|
||||
macro_svp_trace_err("no model description, create output failed\n");
|
||||
return TD_FAILURE;
|
||||
}
|
||||
|
||||
g_npu_acl_model[model_index].output_dataset = aclmdlCreateDataset();
|
||||
if (g_npu_acl_model[model_index].output_dataset == TD_NULL) {
|
||||
macro_svp_trace_err("can't create dataset, create output failed\n");
|
||||
return TD_FAILURE;
|
||||
}
|
||||
|
||||
output_size = aclmdlGetNumOutputs(g_npu_acl_model[model_index].model_desc);
|
||||
for (td_u32 i = 0; i < output_size; ++i) {
|
||||
td_u32 buffer_size = aclmdlGetOutputSizeByIndex(g_npu_acl_model[model_index].model_desc, i);
|
||||
|
||||
td_void *output_buffer = TD_NULL;
|
||||
td_s32 ret = aclrtMalloc(&output_buffer, buffer_size, ACL_MEM_MALLOC_NORMAL_ONLY);
|
||||
if (ret != ACL_ERROR_NONE) {
|
||||
macro_svp_trace_err("can't malloc buffer, size is %u, create output failed\n", buffer_size);
|
||||
return TD_FAILURE;
|
||||
}
|
||||
|
||||
aclDataBuffer *output_data = aclCreateDataBuffer(output_buffer, buffer_size);
|
||||
if (output_data == TD_NULL) {
|
||||
macro_svp_trace_err("can't create data buffer, create output failed\n");
|
||||
aclrtFree(output_buffer);
|
||||
return TD_FAILURE;
|
||||
}
|
||||
|
||||
ret = aclmdlAddDatasetBuffer(g_npu_acl_model[model_index].output_dataset, output_data);
|
||||
if (ret != ACL_ERROR_NONE) {
|
||||
macro_svp_trace_err("can't add data buffer, create output failed\n");
|
||||
aclrtFree(output_buffer);
|
||||
aclDestroyDataBuffer(output_data);
|
||||
return TD_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
macro_svp_trace_info("create model output TD_SUCCESS\n");
|
||||
return TD_SUCCESS;
|
||||
}
|
||||
|
||||
/* print the top 5 confidence values with indexes */
|
||||
#define SHOW_TOP_NUM 5
|
||||
static td_void slibapi_npu_sort_output_result(const td_float *src, td_u32 src_len,
|
||||
td_float *dst, td_u32 dst_len)
|
||||
{
|
||||
td_u32 i, j;
|
||||
|
||||
if (src == TD_NULL || dst == TD_NULL || src_len == 0 || dst_len == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < src_len; i++) {
|
||||
td_bool charge = TD_FALSE;
|
||||
td_u32 index;
|
||||
|
||||
for (j = 0; j < dst_len; j++) {
|
||||
if (src[i] > dst[j]) {
|
||||
index = j;
|
||||
charge = TD_TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (charge == TD_TRUE) {
|
||||
for (j = dst_len - 1; j > index; j--) {
|
||||
dst[j] = dst[j - 1];
|
||||
}
|
||||
dst[index] = src[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// #include "wrapperncnn.h"
|
||||
#include <time.h>
|
||||
td_void libapi_npu_output_model_result(td_u32 model_index)
|
||||
{
|
||||
aclDataBuffer *data_buffer = TD_NULL;
|
||||
td_void *data = TD_NULL;
|
||||
td_u32 len;
|
||||
td_u32 i, j;
|
||||
td_float top[SHOW_TOP_NUM] = { 0.0 };
|
||||
|
||||
|
||||
clock_t start, end;
|
||||
double cpu_time_used;
|
||||
|
||||
for (i = 0; i < aclmdlGetDatasetNumBuffers(g_npu_acl_model[model_index].output_dataset); ++i) {
|
||||
// 如果需要精度,修改此处,但是时间会长
|
||||
// for test
|
||||
// if (i == 0) continue;
|
||||
data_buffer = aclmdlGetDatasetBuffer(g_npu_acl_model[model_index].output_dataset, i);
|
||||
if (data_buffer == TD_NULL) {
|
||||
macro_svp_trace_err("get data buffer null.\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
data = aclGetDataBufferAddr(data_buffer);
|
||||
len = aclGetDataBufferSizeV2(data_buffer);
|
||||
if (data == TD_NULL || len == 0) {
|
||||
macro_svp_trace_err("get data null.\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
start = clock();
|
||||
ncnn_result(data,len/sizeof(float));
|
||||
end = clock();
|
||||
cpu_time_used = ((double) (end - start)) / CLOCKS_PER_SEC;
|
||||
printf("[运行时间] ncnn_result 运行时间: %f 秒\n", cpu_time_used);
|
||||
|
||||
// slibapi_npu_sort_output_result(data, (len / sizeof(td_float)), top, SHOW_TOP_NUM);
|
||||
|
||||
// for (j = 0; j < SHOW_TOP_NUM; j++) {
|
||||
// macro_svp_trace_info("top %d: value[%lf]\n", j, top[j]);
|
||||
// }
|
||||
}
|
||||
|
||||
macro_svp_trace_info("output data success\n");
|
||||
return;
|
||||
}
|
||||
|
||||
td_void libapi_npu_destroy_output(td_u32 model_index)
|
||||
{
|
||||
if (g_npu_acl_model[model_index].output_dataset == TD_NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (td_u32 i = 0; i < aclmdlGetDatasetNumBuffers(g_npu_acl_model[model_index].output_dataset); ++i) {
|
||||
aclDataBuffer *data_buffer = aclmdlGetDatasetBuffer(g_npu_acl_model[model_index].output_dataset, i);
|
||||
td_void *data = aclGetDataBufferAddr(data_buffer);
|
||||
(td_void)aclrtFree(data);
|
||||
(td_void)aclDestroyDataBuffer(data_buffer);
|
||||
}
|
||||
|
||||
(td_void)aclmdlDestroyDataset(g_npu_acl_model[model_index].output_dataset);
|
||||
g_npu_acl_model[model_index].output_dataset = TD_NULL;
|
||||
}
|
||||
|
||||
td_s32 libapi_npu_model_execute(td_u32 model_index)
|
||||
{
|
||||
td_s32 ret;
|
||||
ret = aclmdlExecute(g_npu_acl_model[model_index].model_id, g_npu_acl_model[model_index].input_dataset,
|
||||
g_npu_acl_model[model_index].output_dataset);
|
||||
macro_svp_trace_info("end aclmdlExecute, modelId is %u\n", g_npu_acl_model[model_index].model_id);
|
||||
return ret;
|
||||
}
|
||||
|
||||
td_void libapi_npu_unload_model(td_u32 model_index)
|
||||
{
|
||||
if (!g_npu_acl_model[model_index].is_load_flag) {
|
||||
macro_svp_trace_info("no model had been loaded.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
td_s32 ret = aclmdlUnload(g_npu_acl_model[model_index].model_id);
|
||||
if (ret != ACL_ERROR_NONE) {
|
||||
macro_svp_trace_err("unload model failed, modelId is %u\n", g_npu_acl_model[model_index].model_id);
|
||||
}
|
||||
|
||||
if (g_npu_acl_model[model_index].model_desc != TD_NULL) {
|
||||
(td_void)aclmdlDestroyDesc(g_npu_acl_model[model_index].model_desc);
|
||||
g_npu_acl_model[model_index].model_desc = TD_NULL;
|
||||
}
|
||||
|
||||
if (g_npu_acl_model[model_index].model_mem_ptr != TD_NULL) {
|
||||
aclrtFree(g_npu_acl_model[model_index].model_mem_ptr);
|
||||
g_npu_acl_model[model_index].model_mem_ptr = TD_NULL;
|
||||
g_npu_acl_model[model_index].model_mem_size = 0;
|
||||
}
|
||||
|
||||
if (g_npu_acl_model[model_index].model_weight_ptr != TD_NULL) {
|
||||
aclrtFree(g_npu_acl_model[model_index].model_weight_ptr);
|
||||
g_npu_acl_model[model_index].model_weight_ptr = TD_NULL;
|
||||
g_npu_acl_model[model_index].model_weight_size = 0;
|
||||
}
|
||||
|
||||
g_npu_acl_model[model_index].is_load_flag = TD_FALSE;
|
||||
macro_svp_trace_info("unload model SUCCESS, modelId is %u\n", g_npu_acl_model[model_index].model_id);
|
||||
}
|
||||
|
||||
td_void libapi_npu_unload_model_cached(td_u32 model_index)
|
||||
{
|
||||
if (!g_npu_acl_model[model_index].is_load_flag) {
|
||||
macro_svp_trace_info("no model had been loaded.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
td_s32 ret = aclmdlUnload(g_npu_acl_model[model_index].model_id);
|
||||
if (ret != ACL_ERROR_NONE) {
|
||||
macro_svp_trace_err("unload model failed, modelId is %u\n", g_npu_acl_model[model_index].model_id);
|
||||
}
|
||||
|
||||
if (g_npu_acl_model[model_index].model_desc != TD_NULL) {
|
||||
(td_void)aclmdlDestroyDesc(g_npu_acl_model[model_index].model_desc);
|
||||
g_npu_acl_model[model_index].model_desc = TD_NULL;
|
||||
}
|
||||
|
||||
if (g_npu_acl_model[model_index].model_mem_ptr != TD_NULL) {
|
||||
ss_mpi_sys_mmz_free(g_npu_acl_model[model_index].model_mem_phy_addr,
|
||||
g_npu_acl_model[model_index].model_mem_ptr);
|
||||
g_npu_acl_model[model_index].model_mem_ptr = TD_NULL;
|
||||
g_npu_acl_model[model_index].model_mem_size = 0;
|
||||
}
|
||||
|
||||
if (g_npu_acl_model[model_index].model_weight_ptr != TD_NULL) {
|
||||
ss_mpi_sys_mmz_free(g_npu_acl_model[model_index].model_weight_phy_addr,
|
||||
g_npu_acl_model[model_index].model_weight_ptr);
|
||||
g_npu_acl_model[model_index].model_weight_ptr = TD_NULL;
|
||||
g_npu_acl_model[model_index].model_weight_size = 0;
|
||||
}
|
||||
|
||||
g_npu_acl_model[model_index].is_load_flag = TD_FALSE;
|
||||
macro_svp_trace_info("unload model SUCCESS, modelId is %u\n", g_npu_acl_model[model_index].model_id);
|
||||
}
|
||||
|
||||
#define MAX_BATCH_COUNT 100
|
||||
static td_s32 libapi_svp_npuget_dynamicbatch(td_u32 model_index, td_u32 *batchs, td_u32 *count)
|
||||
{
|
||||
aclmdlBatch batch;
|
||||
if (g_npu_acl_model[model_index].model_desc == TD_NULL) {
|
||||
macro_svp_trace_err("no model description, create input failed\n");
|
||||
return TD_FAILURE;
|
||||
}
|
||||
aclError ret = aclmdlGetDynamicBatch(g_npu_acl_model[model_index].model_desc, &batch);
|
||||
if (ret != ACL_ERROR_NONE) {
|
||||
macro_svp_trace_err("aclmdlGetDynamicBatch failed, modelId is %u, errorCode is %d\n",
|
||||
g_npu_acl_model[model_index].model_id, (int32_t)ret);
|
||||
return TD_FAILURE;
|
||||
}
|
||||
macro_svp_trace_info("aclmdlGetDynamicBatch batch count = %d\n", (int32_t)(batch.batchCount));
|
||||
*count = batch.batchCount;
|
||||
if (*count >= MAX_BATCH_COUNT) {
|
||||
macro_svp_trace_err("dynamic batch count[%u] is larger than max count[%u]\n", *count, MAX_BATCH_COUNT);
|
||||
return TD_FAILURE;
|
||||
}
|
||||
for (td_u32 i = 0; i < batch.batchCount; i++) {
|
||||
macro_svp_trace_info("aclmdlGetDynamicBatch index = %d batch = %lu\n", i, batch.batch[i]);
|
||||
batchs[i] = batch.batch[i];
|
||||
}
|
||||
return TD_SUCCESS;
|
||||
}
|
||||
|
||||
static td_void libapi_npu_set_input_data(int model_index, td_u32 value)
|
||||
{
|
||||
aclDataBuffer *data_buffer = aclmdlGetDatasetBuffer(g_npu_acl_model[model_index].input_dataset, 0);
|
||||
td_void *data = aclGetDataBufferAddr(data_buffer);
|
||||
td_u32 buffer_size = aclmdlGetInputSizeByIndex(g_npu_acl_model[model_index].model_desc, 0);
|
||||
memset_s(data, buffer_size, value, buffer_size);
|
||||
ss_mpi_sys_flush_cache(g_npu_acl_model[model_index].input_phy_addr[0], data, buffer_size);
|
||||
}
|
||||
|
||||
td_s32 libapi_svp_npu_loop_execute_dynamicbatch(td_u32 model_index)
|
||||
{
|
||||
td_u32 batchs[MAX_BATCH_COUNT];
|
||||
td_u32 count = 0;
|
||||
td_s32 ret = libapi_svp_npuget_dynamicbatch(model_index, batchs, &count);
|
||||
if (ret != TD_SUCCESS) {
|
||||
macro_svp_trace_err("libapi_svp_npuget_dynamicbatch fail\n");
|
||||
return TD_FAILURE;
|
||||
}
|
||||
|
||||
/* memset_s input as 1 */
|
||||
libapi_npu_set_input_data(model_index, 1);
|
||||
|
||||
/* loop execute with every batch num */
|
||||
size_t index;
|
||||
for (td_u32 i = 0; i < count; i++) {
|
||||
ret = aclmdlGetInputIndexByName(g_npu_acl_model[model_index].model_desc, ACL_DYNAMIC_TENSOR_NAME, &index);
|
||||
if (ret != ACL_ERROR_NONE) {
|
||||
macro_svp_trace_err("aclmdlGetInputIndexByName failed, modelId is %u, errorCode is %d\n",
|
||||
g_npu_acl_model[model_index].model_id, (int32_t)(ret));
|
||||
return TD_FAILURE;
|
||||
}
|
||||
macro_svp_trace_info("aclmdlSetDynamicBatchSize , batchSize is %u\n", batchs[i]);
|
||||
ret = aclmdlSetDynamicBatchSize(g_npu_acl_model[model_index].model_id,
|
||||
g_npu_acl_model[model_index].input_dataset, index, batchs[i]);
|
||||
if (ret != ACL_ERROR_NONE) {
|
||||
macro_svp_trace_err("aclmdlSetDynamicBatchSize failed, modelId is %u, errorCode is %d\n",
|
||||
g_npu_acl_model[model_index].model_id, (int32_t)(ret));
|
||||
return TD_FAILURE;
|
||||
}
|
||||
|
||||
/* ater set dynamic batch size, flush the mem */
|
||||
aclDataBuffer *input_data_buffer = aclmdlGetDatasetBuffer(g_npu_acl_model[model_index].input_dataset, index);
|
||||
td_void *data = aclGetDataBufferAddr(input_data_buffer);
|
||||
td_u32 buffer_size = aclmdlGetInputSizeByIndex(g_npu_acl_model[model_index].model_desc, index);
|
||||
|
||||
ss_mpi_sys_flush_cache(g_npu_acl_model[model_index].input_phy_addr[index], data, buffer_size);
|
||||
|
||||
ret = aclmdlExecute(g_npu_acl_model[model_index].model_id, g_npu_acl_model[model_index].input_dataset,
|
||||
g_npu_acl_model[model_index].output_dataset);
|
||||
if (ret != ACL_ERROR_NONE) {
|
||||
macro_svp_trace_err("execute model failed, modelId is %u, errorCode is %d\n",
|
||||
g_npu_acl_model[model_index].model_id, (int32_t)(ret));
|
||||
return TD_FAILURE;
|
||||
}
|
||||
aclDataBuffer *output_data_buffer = aclmdlGetDatasetBuffer(g_npu_acl_model[model_index].output_dataset, 0);
|
||||
data = aclGetDataBufferAddr(output_data_buffer);
|
||||
buffer_size = aclmdlGetOutputSizeByIndex(g_npu_acl_model[model_index].model_desc, 0);
|
||||
ss_mpi_sys_flush_cache(g_npu_acl_model[model_index].output_phy_addr[0], data, buffer_size);
|
||||
}
|
||||
macro_svp_trace_info("loop execute dynamicbatch success\n");
|
||||
return TD_SUCCESS;
|
||||
}
|
60
libapi/svp_npu/libapi_npu_model.h
Executable file
@ -0,0 +1,60 @@
|
||||
/*
|
||||
Copyright (c), 2001-2022, Shenshu Tech. Co., Ltd.
|
||||
*/
|
||||
|
||||
#ifndef SAMPLE_NPU_MODEL_H
|
||||
#define SAMPLE_NPU_MODEL_H
|
||||
#include <stddef.h>
|
||||
#include "ot_type.h"
|
||||
#include "acl.h"
|
||||
#include "ss_mpi_sys.h"
|
||||
|
||||
#define MAX_THREAD_NUM 20
|
||||
#define MAX_INPUT_NUM 5
|
||||
#define MAX_OUTPUT_NUM 5
|
||||
|
||||
typedef struct npu_acl_model {
|
||||
td_u32 model_id;
|
||||
td_ulong model_mem_size;
|
||||
td_ulong model_weight_size;
|
||||
td_void *model_mem_ptr;
|
||||
td_void *model_weight_ptr;
|
||||
td_phys_addr_t model_mem_phy_addr;
|
||||
td_phys_addr_t model_weight_phy_addr;
|
||||
td_bool is_load_flag;
|
||||
aclmdlDesc *model_desc;
|
||||
aclmdlDataset *input_dataset;
|
||||
aclmdlDataset *output_dataset;
|
||||
td_phys_addr_t output_phy_addr[MAX_OUTPUT_NUM];
|
||||
td_phys_addr_t input_phy_addr[MAX_INPUT_NUM];
|
||||
} npu_acl_model_t;
|
||||
|
||||
td_s32 libapi_npu_load_model_with_mem(const char *model_path, td_u32 model_index);
|
||||
td_s32 libapi_npu_load_model_with_mem_cached(const char *model_path, td_u32 model_index);
|
||||
|
||||
td_s32 libapi_npu_create_desc(td_u32 model_index);
|
||||
td_void libapi_npu_destroy_desc(td_u32 model_index);
|
||||
|
||||
td_s32 libapi_npu_get_input_size_by_index(const td_u32 index, size_t *inputSize, td_u32 model_index);
|
||||
td_s32 libapi_npu_create_input_dataset(td_u32 model_index);
|
||||
td_void libapi_npu_destroy_input_dataset(td_u32 model_index);
|
||||
td_s32 libapi_npu_create_input_databuf(td_void *data_buf, size_t data_len, td_u32 model_index);
|
||||
td_void libapi_npu_destroy_input_databuf(td_u32 model_index);
|
||||
|
||||
td_s32 libapi_npu_create_output(td_u32 model_index);
|
||||
td_void libapi_npu_output_model_result(td_u32 model_index);
|
||||
td_void libapi_npu_destroy_output(td_u32 model_index);
|
||||
|
||||
td_s32 libapi_npu_model_execute(td_u32 model_index);
|
||||
|
||||
td_void libapi_npu_unload_model(td_u32 model_index);
|
||||
td_void libapi_npu_unload_model_cached(td_u32 model_index);
|
||||
|
||||
td_s32 libapi_npu_create_cached_input(td_u32 model_index);
|
||||
td_s32 libapi_npu_create_cached_output(td_u32 model_index);
|
||||
td_void libapi_npu_destroy_cached_input(td_u32 model_index);
|
||||
td_void libapi_npu_destroy_cached_output(td_u32 model_index);
|
||||
|
||||
td_s32 libapi_svp_npu_loop_execute_dynamicbatch(td_u32 model_index);
|
||||
|
||||
#endif
|
510
libapi/svp_npu/libapi_npu_process.c
Executable file
@ -0,0 +1,510 @@
|
||||
/*
|
||||
Copyright (c), 2001-2022, Shenshu Tech. Co., Ltd.
|
||||
*/
|
||||
|
||||
#include "libapi_npu_process.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <signal.h>
|
||||
#include <semaphore.h>
|
||||
#include <pthread.h>
|
||||
#include <limits.h>
|
||||
|
||||
#include "ot_common_svp.h"
|
||||
#include "libapi_common_svp.h"
|
||||
#include "libapi_npu_model.h"
|
||||
|
||||
static td_u32 g_npu_dev_id = 0;
|
||||
static td_s32 libapi_svp_npu_fill_input_data(td_void *dev_buf, size_t buf_size)
|
||||
{
|
||||
td_s32 ret;
|
||||
td_char path[PATH_MAX] = { 0 };
|
||||
size_t file_size;
|
||||
|
||||
if (realpath("testyuv.sp420", path) == TD_NULL) {
|
||||
macro_svp_trace_err("Invalid file!.\n");
|
||||
return TD_FAILURE;
|
||||
}
|
||||
|
||||
FILE *fp = fopen(path, "rb");
|
||||
macro_svp_check_exps_return(fp == TD_NULL, TD_FAILURE, ENUM_SVP_ERR_LEVEL_ERROR,
|
||||
"open image file failed!\n");
|
||||
|
||||
ret = fseek(fp, 0L, SEEK_END);
|
||||
macro_svp_check_exps_goto(ret == -1, end, ENUM_SVP_ERR_LEVEL_ERROR, "Fseek failed!\n");
|
||||
file_size = ftell(fp);
|
||||
macro_svp_check_exps_goto(file_size == 0, end, ENUM_SVP_ERR_LEVEL_ERROR, "Ftell failed!\n");
|
||||
ret = fseek(fp, 0L, SEEK_SET);
|
||||
macro_svp_check_exps_goto(ret == -1, end, ENUM_SVP_ERR_LEVEL_ERROR, "Fseek failed!\n");
|
||||
|
||||
file_size = (file_size > buf_size) ? buf_size : file_size;
|
||||
ret = fread(dev_buf, file_size, 1, fp);
|
||||
macro_svp_check_exps_goto(ret != 1, end, ENUM_SVP_ERR_LEVEL_ERROR, "Read file failed!\n");
|
||||
|
||||
if (fp != TD_NULL) {
|
||||
fclose(fp);
|
||||
}
|
||||
return TD_SUCCESS;
|
||||
|
||||
end:
|
||||
if (fp != TD_NULL) {
|
||||
fclose(fp);
|
||||
}
|
||||
return TD_FAILURE;
|
||||
}
|
||||
|
||||
static td_void libapi_svp_npu_destroy_resource(td_void)
|
||||
{
|
||||
aclError ret;
|
||||
|
||||
ret = aclrtResetDevice(g_npu_dev_id);
|
||||
if (ret != ACL_ERROR_NONE) {
|
||||
macro_svp_trace_err("reset device fail\n");
|
||||
}
|
||||
macro_svp_trace_info("end to reset device is %d\n", g_npu_dev_id);
|
||||
|
||||
ret = aclFinalize();
|
||||
if (ret != ACL_ERROR_NONE) {
|
||||
macro_svp_trace_err("finalize acl fail\n");
|
||||
}
|
||||
macro_svp_trace_info("end to finalize acl\n");
|
||||
}
|
||||
|
||||
static td_s32 libapi_svp_npu_init_resource(td_void)
|
||||
{
|
||||
/* ACL init */
|
||||
const char *acl_config_path = "";
|
||||
aclrtRunMode run_mode;
|
||||
td_s32 ret;
|
||||
|
||||
ret = aclInit(acl_config_path);
|
||||
if (ret != ACL_ERROR_NONE) {
|
||||
macro_svp_trace_err("acl init fail.\n");
|
||||
return TD_FAILURE;
|
||||
}
|
||||
macro_svp_trace_info("acl init success.\n");
|
||||
|
||||
/* open device */
|
||||
ret = aclrtSetDevice(g_npu_dev_id);
|
||||
if (ret != ACL_ERROR_NONE) {
|
||||
macro_svp_trace_err("acl open device %d fail.\n", g_npu_dev_id);
|
||||
return TD_FAILURE;
|
||||
}
|
||||
macro_svp_trace_info("open device %d success.\n", g_npu_dev_id);
|
||||
|
||||
/* get run mode */
|
||||
ret = aclrtGetRunMode(&run_mode);
|
||||
if ((ret != ACL_ERROR_NONE) || (run_mode != ACL_DEVICE)) {
|
||||
macro_svp_trace_err("acl get run mode fail.\n");
|
||||
return TD_FAILURE;
|
||||
}
|
||||
macro_svp_trace_info("get run mode success\n");
|
||||
|
||||
return TD_SUCCESS;
|
||||
}
|
||||
|
||||
static td_void libapi_svp_npu_acl_resnet50_stop(td_void)
|
||||
{
|
||||
libapi_svp_npu_destroy_resource();
|
||||
printf("\033[0;31mprogram termination abnormally!\033[0;39m\n");
|
||||
}
|
||||
|
||||
static td_s32 libapi_svp_npu_acl_prepare_init()
|
||||
{
|
||||
td_s32 ret;
|
||||
|
||||
ret = libapi_svp_npu_init_resource();
|
||||
if (ret != TD_SUCCESS) {
|
||||
libapi_svp_npu_destroy_resource();
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static td_void libapi_svp_npu_acl_prepare_exit(td_u32 thread_num)
|
||||
{
|
||||
for (td_u32 model_index = 0; model_index < thread_num; model_index++) {
|
||||
libapi_npu_destroy_desc(model_index);
|
||||
libapi_npu_unload_model(model_index);
|
||||
}
|
||||
libapi_svp_npu_destroy_resource();
|
||||
}
|
||||
|
||||
static td_s32 libapi_svp_npu_load_model(const char* om_model_path, td_u32 model_index, td_bool is_cached)
|
||||
{
|
||||
td_char path[PATH_MAX] = { 0 };
|
||||
td_s32 ret;
|
||||
|
||||
if (sizeof(om_model_path) > PATH_MAX) {
|
||||
macro_svp_trace_err("pathname too long!.\n");
|
||||
return TD_NULL;
|
||||
}
|
||||
if (realpath(om_model_path, path) == TD_NULL) {
|
||||
macro_svp_trace_err("invalid file!.\n");
|
||||
return TD_NULL;
|
||||
}
|
||||
|
||||
if (is_cached == TD_TRUE) {
|
||||
ret = libapi_npu_load_model_with_mem_cached(path, model_index);
|
||||
} else {
|
||||
ret = libapi_npu_load_model_with_mem(path, model_index);
|
||||
}
|
||||
|
||||
if (ret != TD_SUCCESS) {
|
||||
macro_svp_trace_err("execute load model fail, model_index is:%d.\n", model_index);
|
||||
goto acl_prepare_end1;
|
||||
}
|
||||
ret = libapi_npu_create_desc(model_index);
|
||||
if (ret != TD_SUCCESS) {
|
||||
macro_svp_trace_err("execute create desc fail.\n");
|
||||
goto acl_prepare_end2;
|
||||
}
|
||||
|
||||
return TD_SUCCESS;
|
||||
|
||||
acl_prepare_end2:
|
||||
libapi_npu_destroy_desc(model_index);
|
||||
|
||||
acl_prepare_end1:
|
||||
libapi_npu_unload_model(model_index);
|
||||
return ret;
|
||||
}
|
||||
static td_s32 libapi_svp_npu_dataset_prepare_init(td_u32 model_index)
|
||||
{
|
||||
td_s32 ret;
|
||||
|
||||
ret = libapi_npu_create_input_dataset(model_index);
|
||||
if (ret != TD_SUCCESS) {
|
||||
macro_svp_trace_err("execute create input fail.\n");
|
||||
return TD_FAILURE;
|
||||
}
|
||||
ret = libapi_npu_create_output(model_index);
|
||||
if (ret != TD_SUCCESS) {
|
||||
libapi_npu_destroy_input_dataset(model_index);
|
||||
macro_svp_trace_err("execute create output fail.\n");
|
||||
return TD_FAILURE;
|
||||
}
|
||||
return TD_SUCCESS;
|
||||
}
|
||||
|
||||
static td_s32 libapi_svp_npu_create_cached_input_output(td_u32 model_index)
|
||||
{
|
||||
td_s32 ret;
|
||||
|
||||
ret = libapi_npu_create_cached_input(model_index);
|
||||
if (ret != TD_SUCCESS) {
|
||||
macro_svp_trace_err("execute create input fail.\n");
|
||||
return TD_FAILURE;
|
||||
}
|
||||
ret = libapi_npu_create_cached_output(model_index);
|
||||
if (ret != TD_SUCCESS) {
|
||||
libapi_npu_destroy_cached_input(model_index);
|
||||
macro_svp_trace_err("execute create output fail.\n");
|
||||
return TD_FAILURE;
|
||||
}
|
||||
return TD_SUCCESS;
|
||||
}
|
||||
|
||||
static td_void libapi_svp_npu_dataset_prepare_exit(td_u32 thread_num)
|
||||
{
|
||||
for (td_u32 model_index = 0; model_index < thread_num; model_index++) {
|
||||
libapi_npu_destroy_output(model_index);
|
||||
libapi_npu_destroy_input_dataset(model_index);
|
||||
}
|
||||
}
|
||||
|
||||
static td_void libapi_svp_npu_release_input_data(td_void **data_buf, size_t *data_len, td_u32 thread_num)
|
||||
{
|
||||
for (td_u32 model_index = 0; model_index < thread_num; model_index++) {
|
||||
ot_unused(data_len[model_index]);
|
||||
(td_void)aclrtFree(data_buf[model_index]);
|
||||
}
|
||||
}
|
||||
|
||||
static td_s32 libapi_svp_npu_get_input_data(td_void **data_buf, size_t *data_len, td_u32 model_index)
|
||||
{
|
||||
size_t buf_size;
|
||||
td_s32 ret;
|
||||
|
||||
ret = libapi_npu_get_input_size_by_index(0, &buf_size, model_index);
|
||||
if (ret != TD_SUCCESS) {
|
||||
macro_svp_trace_err("execute get input size fail.\n");
|
||||
return TD_FAILURE;
|
||||
}
|
||||
|
||||
ret = aclrtMalloc(data_buf, buf_size, ACL_MEM_MALLOC_NORMAL_ONLY);
|
||||
if (ret != ACL_ERROR_NONE) {
|
||||
macro_svp_trace_err("malloc device buffer fail. size is %zu, errorCode is %d.\n", buf_size, ret);
|
||||
return TD_FAILURE;
|
||||
}
|
||||
|
||||
// ret = libapi_svp_npu_fill_input_data(*data_buf, buf_size);
|
||||
// if (ret != TD_SUCCESS) {
|
||||
// macro_svp_trace_err("memcpy_s device buffer fail.\n");
|
||||
// (td_void)aclrtFree(data_buf);
|
||||
// return TD_FAILURE;
|
||||
// }
|
||||
|
||||
*data_len = buf_size;
|
||||
|
||||
macro_svp_trace_info("get input data success\n");
|
||||
|
||||
return TD_SUCCESS;
|
||||
}
|
||||
|
||||
static td_s32 libapi_svp_npu_create_input_databuf(td_void *data_buf, size_t data_len, td_u32 model_index)
|
||||
{
|
||||
return libapi_npu_create_input_databuf(data_buf, data_len, model_index);
|
||||
}
|
||||
|
||||
static td_void libapi_svp_npu_destroy_input_databuf(td_u32 thread_num)
|
||||
{
|
||||
for (td_u32 model_index = 0; model_index < thread_num; model_index++) {
|
||||
libapi_npu_destroy_input_databuf(model_index);
|
||||
}
|
||||
}
|
||||
|
||||
void *libapi_svp_execute_func_contious(void *args)
|
||||
{
|
||||
td_s32 ret;
|
||||
td_u32 model_index = *(td_u32 *)args;
|
||||
|
||||
ret = aclrtSetDevice(g_npu_dev_id);
|
||||
if (ret != ACL_ERROR_NONE) {
|
||||
macro_svp_trace_err("acl open device %d fail.\n", g_npu_dev_id);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
macro_svp_trace_info("open device %d success.\n", g_npu_dev_id);
|
||||
|
||||
ret = libapi_npu_model_execute(model_index);
|
||||
if (ret != ACL_ERROR_NONE) {
|
||||
macro_svp_trace_err("execute inference failed of thread[%d].\n", model_index);
|
||||
}
|
||||
|
||||
ret = aclrtResetDevice(g_npu_dev_id);
|
||||
if (ret != ACL_ERROR_NONE) {
|
||||
macro_svp_trace_err("model[%d]reset device failed\n", model_index);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static td_void libapi_svp_npu_model_execute_multithread()
|
||||
{
|
||||
pthread_t execute_threads[MAX_THREAD_NUM] = {0};
|
||||
td_u32 index[MAX_THREAD_NUM];
|
||||
td_u32 model_index;
|
||||
|
||||
for (model_index = 0; model_index < MAX_THREAD_NUM; model_index++) {
|
||||
index[model_index] = model_index;
|
||||
pthread_create(&execute_threads[model_index], NULL, libapi_svp_execute_func_contious,
|
||||
(void *)&index[model_index]);
|
||||
}
|
||||
|
||||
void *waitret[MAX_THREAD_NUM];
|
||||
for (model_index = 0; model_index < MAX_THREAD_NUM; model_index++) {
|
||||
pthread_join(execute_threads[model_index], &waitret[model_index]);
|
||||
}
|
||||
|
||||
for (model_index = 0; model_index < MAX_THREAD_NUM; model_index++) {
|
||||
libapi_npu_output_model_result(model_index);
|
||||
}
|
||||
}
|
||||
|
||||
/* function : show the sample of npu resnet50_multithread */
|
||||
td_void libapi_svp_npu_acl_resnet50_multithread(td_void)
|
||||
{
|
||||
td_void *data_buf[MAX_THREAD_NUM] = {TD_NULL};
|
||||
size_t buf_size[MAX_THREAD_NUM];
|
||||
td_u32 model_index;
|
||||
td_s32 ret;
|
||||
|
||||
const char *om_model_path = "./data/model/resnet50.om";
|
||||
ret = libapi_svp_npu_acl_prepare_init();
|
||||
if (ret != TD_SUCCESS) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (model_index = 0; model_index < MAX_THREAD_NUM; model_index++) {
|
||||
ret = libapi_svp_npu_load_model(om_model_path, model_index, TD_FALSE);
|
||||
if (ret != TD_SUCCESS) {
|
||||
goto acl_process_end0;
|
||||
}
|
||||
|
||||
ret = libapi_svp_npu_dataset_prepare_init(model_index);
|
||||
if (ret != TD_SUCCESS) {
|
||||
goto acl_process_end1;
|
||||
}
|
||||
|
||||
ret = libapi_svp_npu_get_input_data(&data_buf[model_index], &buf_size[model_index], model_index);
|
||||
if (ret != TD_SUCCESS) {
|
||||
macro_svp_trace_err("execute create input fail.\n");
|
||||
goto acl_process_end2;
|
||||
}
|
||||
|
||||
ret = libapi_svp_npu_create_input_databuf(data_buf[model_index], buf_size[model_index], model_index);
|
||||
if (ret != TD_SUCCESS) {
|
||||
macro_svp_trace_err("memcpy_s device buffer fail.\n");
|
||||
goto acl_process_end3;
|
||||
}
|
||||
}
|
||||
|
||||
libapi_svp_npu_model_execute_multithread();
|
||||
|
||||
acl_process_end3:
|
||||
libapi_svp_npu_destroy_input_databuf(MAX_THREAD_NUM);
|
||||
acl_process_end2:
|
||||
libapi_svp_npu_release_input_data(data_buf, buf_size, MAX_THREAD_NUM);
|
||||
acl_process_end1:
|
||||
libapi_svp_npu_dataset_prepare_exit(MAX_THREAD_NUM);
|
||||
acl_process_end0:
|
||||
libapi_svp_npu_acl_prepare_exit(MAX_THREAD_NUM);
|
||||
}
|
||||
|
||||
td_void libapi_svp_npu_acl_mobilenet_v3_dynamicbatch(td_void)
|
||||
{
|
||||
td_s32 ret;
|
||||
const char *om_model_path = "./data/model/mobilenet_v3_dynamic_batch.om";
|
||||
ret = libapi_svp_npu_acl_prepare_init();
|
||||
if (ret != TD_SUCCESS) {
|
||||
return;
|
||||
}
|
||||
|
||||
ret = libapi_svp_npu_load_model(om_model_path, 0, TD_TRUE);
|
||||
if (ret != TD_SUCCESS) {
|
||||
goto acl_process_end0;
|
||||
}
|
||||
|
||||
ret = libapi_svp_npu_create_cached_input_output(0);
|
||||
if (ret != TD_SUCCESS) {
|
||||
goto acl_process_end0;
|
||||
}
|
||||
|
||||
libapi_svp_npu_loop_execute_dynamicbatch(0);
|
||||
|
||||
libapi_npu_destroy_cached_input(0);
|
||||
libapi_npu_destroy_cached_output(0);
|
||||
acl_process_end0:
|
||||
libapi_npu_destroy_desc(0);
|
||||
libapi_npu_unload_model_cached(0);
|
||||
}
|
||||
|
||||
/* function : show the sample of npu resnet50 */
|
||||
td_void libapi_svp_npu_acl_resnet50(td_void)
|
||||
{
|
||||
td_void *data_buf = TD_NULL;
|
||||
size_t buf_size;
|
||||
td_s32 ret;
|
||||
|
||||
// const char *om_model_path = "./data/model/resnet50.om";
|
||||
const char *om_model_path = "yolov5s_v6.2.om";
|
||||
ret = libapi_svp_npu_acl_prepare_init(om_model_path);
|
||||
if (ret != TD_SUCCESS) {
|
||||
return;
|
||||
}
|
||||
|
||||
ret = libapi_svp_npu_load_model(om_model_path, 0, TD_FALSE);
|
||||
if (ret != TD_SUCCESS) {
|
||||
goto acl_process_end0;
|
||||
}
|
||||
|
||||
ret = libapi_svp_npu_dataset_prepare_init(0);
|
||||
if (ret != TD_SUCCESS) {
|
||||
goto acl_process_end0;
|
||||
}
|
||||
|
||||
ret = libapi_svp_npu_get_input_data(&data_buf, &buf_size, 0);
|
||||
if (ret != TD_SUCCESS) {
|
||||
macro_svp_trace_err("execute create input fail.\n");
|
||||
goto acl_process_end1;
|
||||
}
|
||||
|
||||
ret = libapi_svp_npu_create_input_databuf(data_buf, buf_size, 0);
|
||||
if (ret != TD_SUCCESS) {
|
||||
macro_svp_trace_err("memcpy_s device buffer fail.\n");
|
||||
goto acl_process_end2;
|
||||
}
|
||||
|
||||
ret = libapi_npu_model_execute(0);
|
||||
if (ret != TD_SUCCESS) {
|
||||
macro_svp_trace_err("execute inference fail.\n");
|
||||
goto acl_process_end3;
|
||||
}
|
||||
|
||||
libapi_npu_output_model_result(0);
|
||||
|
||||
acl_process_end3:
|
||||
libapi_svp_npu_destroy_input_databuf(1);
|
||||
acl_process_end2:
|
||||
libapi_svp_npu_release_input_data(&data_buf, &buf_size, 1);
|
||||
acl_process_end1:
|
||||
libapi_svp_npu_dataset_prepare_exit(1);
|
||||
acl_process_end0:
|
||||
libapi_svp_npu_acl_prepare_exit(1);
|
||||
}
|
||||
|
||||
/* function : npu resnet50 sample signal handle */
|
||||
td_void libapi_svp_npu_acl_resnet50_handle_sig(td_void)
|
||||
{
|
||||
libapi_svp_npu_acl_resnet50_stop();
|
||||
}
|
||||
|
||||
|
||||
// /* function : show the sample of npu resnet50 */
|
||||
// td_void libapi_svp_npu_acl_resnet50(const char* om_model_path)
|
||||
// {
|
||||
// td_void *data_buf = TD_NULL;
|
||||
// size_t buf_size;
|
||||
// td_s32 ret;
|
||||
|
||||
// // const char *om_model_path = "./data/model/resnet50.om";
|
||||
// const char *om_model_path = "yolov5s_v6.2.om";
|
||||
// ret = libapi_svp_npu_acl_prepare_init(om_model_path);
|
||||
// if (ret != TD_SUCCESS) {
|
||||
// return;
|
||||
// }
|
||||
|
||||
// ret = libapi_svp_npu_load_model(om_model_path, 0, TD_FALSE);
|
||||
// if (ret != TD_SUCCESS) {
|
||||
// goto acl_process_end0;
|
||||
// }
|
||||
|
||||
// ret = libapi_svp_npu_dataset_prepare_init(0);
|
||||
// if (ret != TD_SUCCESS) {
|
||||
// goto acl_process_end0;
|
||||
// }
|
||||
|
||||
// ret = libapi_svp_npu_get_input_data(&data_buf, &buf_size, 0);
|
||||
// if (ret != TD_SUCCESS) {
|
||||
// macro_svp_trace_err("execute create input fail.\n");
|
||||
// goto acl_process_end1;
|
||||
// }
|
||||
|
||||
// ret = libapi_svp_npu_create_input_databuf(data_buf, buf_size, 0);
|
||||
// if (ret != TD_SUCCESS) {
|
||||
// macro_svp_trace_err("memcpy_s device buffer fail.\n");
|
||||
// goto acl_process_end2;
|
||||
// }
|
||||
|
||||
// ret = libapi_npu_model_execute(0);
|
||||
// if (ret != TD_SUCCESS) {
|
||||
// macro_svp_trace_err("execute inference fail.\n");
|
||||
// goto acl_process_end3;
|
||||
// }
|
||||
|
||||
// libapi_npu_output_model_result(0);
|
||||
|
||||
// acl_process_end3:
|
||||
// libapi_svp_npu_destroy_input_databuf(1);
|
||||
// acl_process_end2:
|
||||
// libapi_svp_npu_release_input_data(&data_buf, &buf_size, 1);
|
||||
// acl_process_end1:
|
||||
// libapi_svp_npu_dataset_prepare_exit(1);
|
||||
// acl_process_end0:
|
||||
// libapi_svp_npu_acl_prepare_exit(1);
|
||||
// }
|
23
libapi/svp_npu/libapi_npu_process.h
Executable file
@ -0,0 +1,23 @@
|
||||
/*
|
||||
Copyright (c), 2001-2022, Shenshu Tech. Co., Ltd.
|
||||
*/
|
||||
|
||||
#ifndef SAMPLE_NPU_PROCESS_H
|
||||
#define SAMPLE_NPU_PROCESS_H
|
||||
|
||||
#include "ot_type.h"
|
||||
|
||||
/* function : show the sample of acl resnet50 */
|
||||
td_void libapi_svp_npu_acl_resnet50(td_void);
|
||||
// td_void libapi_svp_npu_acl_resnet50(const char* om_model_path);
|
||||
|
||||
/* function : show the sample of acl resnet50_multithread */
|
||||
td_void libapi_svp_npu_acl_resnet50_multithread(td_void);
|
||||
|
||||
/* function : show the sample of acl resnet50 sign handle */
|
||||
td_void libapi_svp_npu_acl_resnet50_handle_sig(td_void);
|
||||
|
||||
/* function : show the sample of acl mobilenet_v3 dyanamicbatch with mmz cached */
|
||||
td_void libapi_svp_npu_acl_mobilenet_v3_dynamicbatch(td_void);
|
||||
|
||||
#endif
|
27
libapi/svp_npu/wrapperncnn.h
Executable file
@ -0,0 +1,27 @@
|
||||
#ifndef _WRAPPERNCNN_H__
|
||||
#define _WRAPPERNCNN_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// #define TEST_FLAG
|
||||
|
||||
/*
|
||||
JPG or PNG chang to yuv420sp W=640 scale
|
||||
*/
|
||||
const void* ncnn_get_syuv_param(); // YuvStuct* psyuv = (YuvStuct*)get_syuv_param();
|
||||
const void* ncnn_get_objects_param(); // std::vector<Object>* objs = (std::vector<Object>*)get_objects_param();
|
||||
const void* ncnn_get_cur_bgr(); // ((cv::Mat*)ncnn_get_cur_bgr())->cols
|
||||
void ncnn_clear_objects_param();
|
||||
void ncnn_clear_proposals_param();
|
||||
const char** ncnn_get_class_name();
|
||||
|
||||
int ncnn_convertimg_yolov5s(const char* jpg,const char* yuvpath);
|
||||
int ncnn_convertimg_yolov5s_by_cvim(void* cvim);
|
||||
int ncnn_result(const float *src,unsigned int len);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
1029
libapi/svp_npu/yolov5 copy.bak
Executable file
1044
libapi/svp_npu/yolov5.cpp
Executable file
132
libapi/sys/libapi_mem.c
Executable file
@ -0,0 +1,132 @@
|
||||
// #include <stdio.h>
|
||||
// #include <stdlib.h> /* rand, srand */
|
||||
// #include <string.h>
|
||||
// #include <assert.h>
|
||||
// #include <sys/time.h>
|
||||
// #include <time.h> /* time() */
|
||||
// /*
|
||||
// * 在uncache区域memcpy时通常很慢,下面是一些优化:
|
||||
// */
|
||||
// /* arm下的memcpy实现: */
|
||||
|
||||
// void memcpy_neon(volatile void *dst, volatile void *src, int sz)
|
||||
// {
|
||||
// if (sz & 63) {
|
||||
// sz = (sz & -64) + 64;
|
||||
// }
|
||||
// asm volatile (
|
||||
// "NEONCopy: \n"
|
||||
// " VLDM %[src]!,{d0-d7} \n"
|
||||
// " VSTM %[dst]!,{d0-d7} \n"
|
||||
// " SUBS %[sz],%[sz],#0x40 \n"
|
||||
// " BGT NEONCopy \n"
|
||||
// : [dst]"+r"(dst), [src]"+r"(src), [sz]"+r"(sz) : : "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7", "cc", "memory");
|
||||
// }
|
||||
|
||||
|
||||
// /*
|
||||
// * arm64
|
||||
// */
|
||||
// /* uncached 区域: */
|
||||
// void memcpy_uncached(volatile void *dst, volatile void *src, int sz)
|
||||
// {
|
||||
// if (sz & 63) {
|
||||
// sz = (sz & -64) + 64;
|
||||
// }
|
||||
// asm volatile (
|
||||
// "sub %[dst], %[dst], #64 \n"
|
||||
// "1: \n"
|
||||
// "ldnp q0, q1, [%[src]] \n"
|
||||
// "ldnp q2, q3, [%[src], #32] \n"
|
||||
// "add %[dst], %[dst], #64 \n"
|
||||
// "subs %[sz], %[sz], #64 \n"
|
||||
// "add %[src], %[src], #64 \n"
|
||||
// "stnp q0, q1, [%[dst]] \n"
|
||||
// "stnp q2, q3, [%[dst], #32] \n"
|
||||
// "b.gt 1b \n"
|
||||
// : [dst]"+r"(dst), [src]"+r"(src), [sz]"+r"(sz) : : "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7", "cc", "memory");
|
||||
// }
|
||||
|
||||
// /* cached 区域: */
|
||||
// void memcpy_cached(volatile void *dst, volatile void *src, int sz)
|
||||
// {
|
||||
// if (sz & 63) {
|
||||
// sz = (sz & -64) + 64;
|
||||
// }
|
||||
// asm volatile (
|
||||
// "sub %[src], %[src], #32 \n"
|
||||
// "sub %[dst], %[dst], #32 \n"
|
||||
// "1: \n"
|
||||
// "ldp q0, q1, [%[src], #32] \n"
|
||||
// "ldp q2, q3, [%[src], #64]! \n"
|
||||
// "subs %[sz], %[sz], #64 \n"
|
||||
// "stp q0, q1, [%[dst], #32] \n"
|
||||
// "stp q2, q3, [%[dst], #64]! \n"
|
||||
// "b.gt 1b \n"
|
||||
// : [dst]"+r"(dst), [src]"+r"(src), [sz]"+r"(sz) : : "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7", "cc", "memory");
|
||||
// }
|
||||
|
||||
// static void get_rand_bytes(unsigned char *data, int len)
|
||||
// {
|
||||
// int i;
|
||||
|
||||
// srand((unsigned)time(NULL)); //种下随机种子
|
||||
// for (i = 0; i < len; i++) {
|
||||
// data[i] = rand() % 255; //取随机数,并保证数在0-255之间
|
||||
// //printf("%02X ", data[i]);
|
||||
// }
|
||||
// }
|
||||
|
||||
// static int get_cur_time_us(void)
|
||||
// {
|
||||
// struct timeval tv;
|
||||
|
||||
// gettimeofday(&tv, NULL); //使用gettimeofday获取当前系统时间
|
||||
|
||||
// return (tv.tv_sec * 1000 * 1000 + tv.tv_usec); //利用struct timeval结构体将时间转换为ms
|
||||
// }
|
||||
|
||||
// #define ARRAY_SIZE(n) sizeof(n) / sizeof(n[0])
|
||||
|
||||
// // int main(void)
|
||||
// // {
|
||||
// // int size_list[] = {
|
||||
// // 1024 * 1024 * 10, // 10MB
|
||||
// // 1024 * 1024 * 1, // 1MB
|
||||
// // 1024 * 100, // 100KB
|
||||
// // 1024 * 10, // 10KB
|
||||
// // 1024 * 1, // 1KB
|
||||
// // };
|
||||
// // char *data1;
|
||||
// // char *data2;
|
||||
// // int t1;
|
||||
// // int t2;
|
||||
// // int i = 0;
|
||||
|
||||
// // data1 = (char *)malloc(size_list[0]);
|
||||
// // data2 = (char *)malloc(size_list[0]);
|
||||
|
||||
// // get_rand_bytes((unsigned char *)data1, size_list[0]);
|
||||
|
||||
// // for (i = 0; i < ARRAY_SIZE(size_list); i++) {
|
||||
// // t1 = get_cur_time_us();
|
||||
// // memcpy(data2, data1, size_list[i]);
|
||||
// // t2 = get_cur_time_us();
|
||||
// // printf("copy %d bytes, memcpy waste time %dus\n", size_list[i], t2 - t1);
|
||||
|
||||
// // t1 = get_cur_time_us();
|
||||
// // memcpy_uncached(data2, data1, size_list[i]);
|
||||
// // t2 = get_cur_time_us();
|
||||
// // printf("copy %d bytes, memcpy_uncached waste time %dus\n", size_list[i], t2 - t1);
|
||||
|
||||
// // t1 = get_cur_time_us();
|
||||
// // memcpy_cached(data2, data1, size_list[i]);
|
||||
// // t2 = get_cur_time_us();
|
||||
// // printf("copy %d bytes, memcpy_cached waste time %dus\n\n", size_list[i], t2 - t1);
|
||||
// // }
|
||||
|
||||
// // free(data1);
|
||||
// // free(data2);
|
||||
|
||||
// // return 0;
|
||||
// // }
|
3
libapi/sys/libapi_mem.h
Executable file
@ -0,0 +1,3 @@
|
||||
// void memcpy_neon(volatile void *dst, volatile void *src, int sz);
|
||||
// void memcpy_uncached(volatile void *dst, volatile void *src, int sz);
|
||||
// void memcpy_cached(volatile void *dst, volatile void *src, int sz);
|
313
libapi/thead/SafeQueue.h
Executable file
@ -0,0 +1,313 @@
|
||||
/*
|
||||
* SafeQueue.hpp
|
||||
* Copyright (C) 2019 Alfredo Pons Menargues <apons@linucleus.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef SAFEQUEUE_HPP_
|
||||
#define SAFEQUEUE_HPP_
|
||||
|
||||
#include <queue>
|
||||
#include <list>
|
||||
#include <mutex>
|
||||
#include <thread>
|
||||
#include <cstdint>
|
||||
#include <condition_variable>
|
||||
|
||||
|
||||
|
||||
/** A thread-safe asynchronous queue */
|
||||
template <class T, class Container = std::list<T>>
|
||||
class SafeQueue
|
||||
{
|
||||
|
||||
typedef typename Container::value_type value_type;
|
||||
typedef typename Container::size_type size_type;
|
||||
typedef Container container_type;
|
||||
|
||||
public:
|
||||
|
||||
/*! Create safe queue. */
|
||||
SafeQueue() = default;
|
||||
SafeQueue (SafeQueue&& sq)
|
||||
{
|
||||
m_queue = std::move (sq.m_queue);
|
||||
}
|
||||
SafeQueue (const SafeQueue& sq)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock (sq.m_mutex);
|
||||
m_queue = sq.m_queue;
|
||||
}
|
||||
|
||||
/*! Destroy safe queue. */
|
||||
~SafeQueue()
|
||||
{
|
||||
std::lock_guard<std::mutex> lock (m_mutex);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the maximum number of items in the queue. Defaults is 0: No limit
|
||||
* \param[in] item An item.
|
||||
*/
|
||||
void set_max_num_items (unsigned int max_num_items)
|
||||
{
|
||||
m_max_num_items = max_num_items;
|
||||
}
|
||||
|
||||
/**
|
||||
* Pushes the item into the queue.
|
||||
* \param[in] item An item.
|
||||
* \return true if an item was pushed into the queue
|
||||
*/
|
||||
bool push (const value_type& item)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock (m_mutex);
|
||||
|
||||
if (m_max_num_items > 0 && m_queue.size() > m_max_num_items)
|
||||
return false;
|
||||
|
||||
m_queue.push (item);
|
||||
m_condition.notify_one();
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Pushes the item into the queue.
|
||||
* \param[in] item An item.
|
||||
* \return true if an item was pushed into the queue
|
||||
*/
|
||||
bool push (const value_type&& item)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock (m_mutex);
|
||||
|
||||
if (m_max_num_items > 0 && m_queue.size() > m_max_num_items)
|
||||
return false;
|
||||
|
||||
m_queue.push (item);
|
||||
m_condition.notify_one();
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Pops item from the queue. If queue is empty, this function blocks until item becomes available.
|
||||
* \param[out] item The item.
|
||||
*/
|
||||
void pop (value_type& item)
|
||||
{
|
||||
std::unique_lock<std::mutex> lock (m_mutex);
|
||||
m_condition.wait (lock, [this]() // Lambda funct
|
||||
{
|
||||
return !m_queue.empty();
|
||||
});
|
||||
item = m_queue.front();
|
||||
m_queue.pop();
|
||||
}
|
||||
|
||||
/**
|
||||
* Pops item from the queue using the contained type's move assignment operator, if it has one..
|
||||
* This method is identical to the pop() method if that type has no move assignment operator.
|
||||
* If queue is empty, this function blocks until item becomes available.
|
||||
* \param[out] item The item.
|
||||
*/
|
||||
void move_pop (value_type& item)
|
||||
{
|
||||
std::unique_lock<std::mutex> lock (m_mutex);
|
||||
m_condition.wait (lock, [this]() // Lambda funct
|
||||
{
|
||||
return !m_queue.empty();
|
||||
});
|
||||
item = std::move (m_queue.front());
|
||||
m_queue.pop();
|
||||
}
|
||||
|
||||
/**
|
||||
* Tries to pop item from the queue.
|
||||
* \param[out] item The item.
|
||||
* \return False is returned if no item is available.
|
||||
*/
|
||||
bool try_pop (value_type& item)
|
||||
{
|
||||
std::unique_lock<std::mutex> lock (m_mutex);
|
||||
|
||||
if (m_queue.empty())
|
||||
return false;
|
||||
|
||||
item = m_queue.front();
|
||||
m_queue.pop();
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tries to pop item from the queue using the contained type's move assignment operator, if it has one..
|
||||
* This method is identical to the try_pop() method if that type has no move assignment operator.
|
||||
* \param[out] item The item.
|
||||
* \return False is returned if no item is available.
|
||||
*/
|
||||
bool try_move_pop (value_type& item)
|
||||
{
|
||||
std::unique_lock<std::mutex> lock (m_mutex);
|
||||
|
||||
if (m_queue.empty())
|
||||
return false;
|
||||
|
||||
item = std::move (m_queue.front());
|
||||
m_queue.pop();
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Pops item from the queue. If the queue is empty, blocks for timeout microseconds, or until item becomes available.
|
||||
* \param[out] t An item.
|
||||
* \param[in] timeout The number of microseconds to wait.
|
||||
* \return true if get an item from the queue, false if no item is received before the timeout.
|
||||
*/
|
||||
bool timeout_pop (value_type& item, std::uint64_t timeout)
|
||||
{
|
||||
std::unique_lock<std::mutex> lock (m_mutex);
|
||||
|
||||
if (m_queue.empty())
|
||||
{
|
||||
if (timeout == 0)
|
||||
return false;
|
||||
|
||||
if (m_condition.wait_for (lock, std::chrono::microseconds (timeout)) == std::cv_status::timeout)
|
||||
return false;
|
||||
}
|
||||
|
||||
item = m_queue.front();
|
||||
m_queue.pop();
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Pops item from the queue using the contained type's move assignment operator, if it has one..
|
||||
* If the queue is empty, blocks for timeout microseconds, or until item becomes available.
|
||||
* This method is identical to the try_pop() method if that type has no move assignment operator.
|
||||
* \param[out] t An item.
|
||||
* \param[in] timeout The number of microseconds to wait.
|
||||
* \return true if get an item from the queue, false if no item is received before the timeout.
|
||||
*/
|
||||
bool timeout_move_pop (value_type& item, std::uint64_t timeout)
|
||||
{
|
||||
std::unique_lock<std::mutex> lock (m_mutex);
|
||||
|
||||
if (m_queue.empty())
|
||||
{
|
||||
if (timeout == 0)
|
||||
return false;
|
||||
|
||||
if (m_condition.wait_for (lock, std::chrono::microseconds (timeout)) == std::cv_status::timeout)
|
||||
return false;
|
||||
}
|
||||
|
||||
item = std::move (m_queue.front());
|
||||
m_queue.pop();
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the number of items in the queue.
|
||||
* \return Number of items in the queue.
|
||||
*/
|
||||
size_type size() const
|
||||
{
|
||||
std::lock_guard<std::mutex> lock (m_mutex);
|
||||
return m_queue.size();
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the queue is empty.
|
||||
* \return true if queue is empty.
|
||||
*/
|
||||
bool empty() const
|
||||
{
|
||||
std::lock_guard<std::mutex> lock (m_mutex);
|
||||
return m_queue.empty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Swaps the contents.
|
||||
* \param[out] sq The SafeQueue to swap with 'this'.
|
||||
*/
|
||||
void swap (SafeQueue& sq)
|
||||
{
|
||||
if (this != &sq)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock1 (m_mutex);
|
||||
std::lock_guard<std::mutex> lock2 (sq.m_mutex);
|
||||
m_queue.swap (sq.m_queue);
|
||||
|
||||
if (!m_queue.empty())
|
||||
m_condition.notify_all();
|
||||
|
||||
if (!sq.m_queue.empty())
|
||||
sq.m_condition.notify_all();
|
||||
}
|
||||
}
|
||||
|
||||
/*! The copy assignment operator */
|
||||
SafeQueue& operator= (const SafeQueue& sq)
|
||||
{
|
||||
if (this != &sq)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock1 (m_mutex);
|
||||
std::lock_guard<std::mutex> lock2 (sq.m_mutex);
|
||||
std::queue<T, Container> temp {sq.m_queue};
|
||||
m_queue.swap (temp);
|
||||
|
||||
if (!m_queue.empty())
|
||||
m_condition.notify_all();
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
/*! The move assignment operator */
|
||||
SafeQueue& operator= (SafeQueue && sq)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock (m_mutex);
|
||||
m_queue = std::move (sq.m_queue);
|
||||
|
||||
if (!m_queue.empty()) m_condition.notify_all();
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
|
||||
std::queue<T, Container> m_queue;
|
||||
mutable std::mutex m_mutex;
|
||||
std::condition_variable m_condition;
|
||||
unsigned int m_max_num_items = 0;
|
||||
};
|
||||
|
||||
/*! Swaps the contents of two SafeQueue objects. */
|
||||
template <class T, class Container>
|
||||
void swap (SafeQueue<T, Container>& q1, SafeQueue<T, Container>& q2)
|
||||
{
|
||||
q1.swap (q2);
|
||||
}
|
||||
#endif /* SAFEQUEUE_HPP_ */
|
||||
|
||||
// #include <SafeQueue.hpp>
|
||||
|
||||
// int main()
|
||||
// {
|
||||
// SafeQueue <int> my_queue;
|
||||
|
||||
// my_queue.push(1);
|
||||
|
||||
// return 0;
|
||||
// }
|
48
libapi/thead/SafeThread.cpp
Executable file
@ -0,0 +1,48 @@
|
||||
#include "UmThread.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <atlbase.h>
|
||||
#include<sys/timeb.h>
|
||||
|
||||
UmThread::UmThread(IRunnable* runnable)
|
||||
: mIsRunning(false), mpRunnable(runnable) {
|
||||
|
||||
}
|
||||
|
||||
UmThread::~UmThread() {
|
||||
delete mpRunnable;
|
||||
}
|
||||
|
||||
UINT UmThread::ThreadFunc(LPVOID lpParam) {
|
||||
UmThread* pThread = (UmThread*)lpParam;
|
||||
if (pThread == NULL) {
|
||||
return -1;
|
||||
}
|
||||
pThread->mIsRunning = true;
|
||||
pThread->OnRun();
|
||||
pThread->mIsRunning = false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int UmThread::Start() {
|
||||
mHandle = CreateThread(NULL, 0,
|
||||
(LPTHREAD_START_ROUTINE)ThreadFunc, (VOID*)this,
|
||||
0, &mThreadID);
|
||||
::CloseHandle(mHandle); // http://guanyue7613.blog.163.com/blog/static/885147420127353735454/
|
||||
return 0;
|
||||
}
|
||||
|
||||
int UmThread::Stop() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
void UmThread::OnRun() {
|
||||
if (mpRunnable == 0) { return ; }
|
||||
mpRunnable->OnRun();
|
||||
};
|
||||
|
||||
void UmThread::Sleep(int milliSec) {
|
||||
::Sleep(milliSec);
|
||||
}
|
45
libapi/thead/SafeThread.h
Executable file
@ -0,0 +1,45 @@
|
||||
/*
|
||||
**************************************************************************************
|
||||
* Filename: SafeThread.h
|
||||
* Description: header file
|
||||
*
|
||||
* Version: 1.0
|
||||
* Created:
|
||||
* Author:
|
||||
*
|
||||
* Revision: initial draft;
|
||||
**************************************************************************************
|
||||
*/
|
||||
#pragma once
|
||||
#include <thread>
|
||||
|
||||
class IRunnable {
|
||||
public:
|
||||
virtual void OnRun() = 0;
|
||||
};
|
||||
|
||||
class SafeThread {
|
||||
public:
|
||||
SafeThread(IRunnable* runnable = NULL);
|
||||
virtual ~SafeThread();
|
||||
|
||||
public:
|
||||
int Start();
|
||||
bool IsRunning() const { return mIsRunning; };
|
||||
|
||||
protected:
|
||||
int Stop();
|
||||
|
||||
public:
|
||||
static void Sleep(int millSec);
|
||||
|
||||
public:
|
||||
virtual void OnRun();
|
||||
|
||||
private:
|
||||
static UINT ThreadFunc(LPVOID lpParam);
|
||||
HANDLE mHandle;
|
||||
DWORD mThreadID;
|
||||
IRunnable* mpRunnable;
|
||||
bool mIsRunning;
|
||||
};
|
112
libapi/thead/ThreadPool.h
Executable file
@ -0,0 +1,112 @@
|
||||
#ifndef THREAD_POOL_H
|
||||
#define THREAD_POOL_H
|
||||
|
||||
#include <vector>
|
||||
#include <queue>
|
||||
#include <memory>
|
||||
#include <thread>
|
||||
#include <mutex>
|
||||
#include <condition_variable>
|
||||
#include <future>
|
||||
#include <functional>
|
||||
#include <stdexcept>
|
||||
|
||||
class ThreadPool {
|
||||
public:
|
||||
explicit ThreadPool(size_t);
|
||||
template<class F, class... Args>//可变参数模版
|
||||
//值得注意的是这里F&&表示universal reference而不是右值引用
|
||||
//如果存在推断类型如template或auto那么&&即表示universal reference,具体是左值引用还是右值引用由初始化决定
|
||||
auto enqueue(F&& f, Args&&... args)//f是函数名,args是参数
|
||||
->std::future<decltype(f(args...))>;//尾置返回类型,返回 函数f返回值类型的future
|
||||
~ThreadPool();
|
||||
private:
|
||||
// need to keep track of threads so we can join them
|
||||
std::vector< std::thread > workers;
|
||||
// the task queue
|
||||
std::queue< std::function<void()> > tasks;//std::function通用的函数封装,要求一个返回值类型为void的无参函数
|
||||
|
||||
// synchronization
|
||||
std::mutex queue_mutex;//锁,负责保护任务队列和stop
|
||||
std::condition_variable condition;//条件变量
|
||||
bool stop;
|
||||
};
|
||||
|
||||
// the constructor just launches some amount of workers
|
||||
inline ThreadPool::ThreadPool(size_t threads)//构造时设定线程数量
|
||||
: stop(false)
|
||||
{
|
||||
for(size_t i = 0;i<threads;++i)
|
||||
workers.emplace_back(//push_back的优化版本
|
||||
[this]//lambda表达式捕获this指针
|
||||
{
|
||||
for(;;)//比while(1)更优
|
||||
{
|
||||
std::function<void()> task;
|
||||
{//{}内相当于新的作用域
|
||||
std::unique_lock<std::mutex> lock(this->queue_mutex);
|
||||
//在等待任务队列中出现任务的过程中解锁queue_mutex
|
||||
//由notify_one或notify_all唤醒
|
||||
//线程池初始化后将有threads个线程在此处等待,每个线程执行完分配到的任务将执行循环,再取任务执行或等待任务加入队列
|
||||
/* 我们需要知道这么做的目的是,std::thread本身仅能绑定一个函数,而我们需要仅用threads个线程去帮我们执行m个任务,
|
||||
* 而不是每执行一个任务创建一个线程,如果这样我们将创建m个线程,而创建线程是需要开销的,这引起了不必要的浪费,线程池就是为此而生的
|
||||
* 通过这种方式,每个std::thread仍然是只绑定了一个函数,但是这一个函数会执行我们想要的多个任务
|
||||
*/
|
||||
this->condition.wait(lock,
|
||||
[this]{ return this->stop || !this->tasks.empty(); });
|
||||
if(this->stop && this->tasks.empty())//stop=true,仍需执行任务队列中剩余任务
|
||||
return;
|
||||
task = std::move(this->tasks.front());//std::move避免拷贝
|
||||
this->tasks.pop();
|
||||
}
|
||||
|
||||
task();//执行任务
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
// add new work item to the pool
|
||||
template<class F, class... Args>
|
||||
auto ThreadPool::enqueue(F&& f, Args&&... args)
|
||||
-> std::future<decltype(f(args...))>
|
||||
{
|
||||
using return_type = decltype(f(args...));
|
||||
|
||||
//基本类型是std::shared_ptr,指向类型是std::packaged_task,类型是返回值类型为return_type的无参函数
|
||||
auto task = std::make_shared< std::packaged_task<return_type()> >(
|
||||
/* 现在该说说为什么std::packaged_task的类型是一个返回值为return_type的无参数函数了
|
||||
* 返回值是return_type这没有问题,至于参数消失的原因是因为:std::bind
|
||||
* 在这里它创建了一个无参数(参数均被指定)版本的函数f
|
||||
*/
|
||||
//std::forward配合universal reference使用,完美转发,实际效果是如果是右值引用那么还是右值引用,如果是左值引用那么还是左值引用
|
||||
std::bind(std::forward<F>(f), std::forward<Args>(args)...)
|
||||
);
|
||||
|
||||
std::future<return_type> res = task->get_future();//任务函数实际执行后的返回值
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(queue_mutex);
|
||||
|
||||
// don't allow enqueueing after stopping the pool
|
||||
if(stop)
|
||||
throw std::runtime_error("enqueue on stopped ThreadPool");
|
||||
|
||||
tasks.emplace([task](){ (*task)(); });//往tasks队列压入一个无参无返回值的函数,函数体内调用task(不要忘记task是shared_ptr类型)
|
||||
}
|
||||
//任务压入队列,唤醒等待的线程
|
||||
condition.notify_one();
|
||||
return res;
|
||||
}
|
||||
|
||||
// the destructor joins all threads
|
||||
inline ThreadPool::~ThreadPool()
|
||||
{
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(queue_mutex);
|
||||
stop = true;
|
||||
}
|
||||
condition.notify_all();//唤醒所有等待的进程
|
||||
for(std::thread &worker: workers)
|
||||
worker.join();//等待所有线程结束
|
||||
}
|
||||
|
||||
#endif
|
11
ss928sdk/common/Makefile
Executable file
@ -0,0 +1,11 @@
|
||||
param_file=$(realpath $(dir $(firstword $(MAKEFILE_LIST))))/../Makefile.param
|
||||
include $(param_file)
|
||||
|
||||
.PHONY : clean all
|
||||
all:$(COMM_OBJ)
|
||||
|
||||
clean:
|
||||
@rm $(COMM_OBJ) -f
|
||||
|
||||
%.o:%.c
|
||||
@$(CC) $(COMM_INC) $(CFLAGS) -c $< -o $@
|
1586
ss928sdk/common/audio/adp/audio_aac_adp.c
Executable file
107
ss928sdk/common/audio/adp/audio_aac_adp.h
Executable file
@ -0,0 +1,107 @@
|
||||
/*
|
||||
Copyright (c), 2001-2022, Shenshu Tech. Co., Ltd.
|
||||
*/
|
||||
|
||||
#ifndef AUDIO_AAC_ADP_H
|
||||
#define AUDIO_AAC_ADP_H
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "ss_mpi_audio.h"
|
||||
#include "ot_common_aenc.h"
|
||||
#include "ot_common_adec.h"
|
||||
#include "ot_common_aio.h"
|
||||
#include "ot_aacdec.h"
|
||||
#include "ot_aacenc.h"
|
||||
|
||||
/* samples per frame for AACLC and aacPlus */
|
||||
#define AACLD_SAMPLES_PER_FRAME 512
|
||||
#define AACLC_SAMPLES_PER_FRAME 1024
|
||||
#define AACPLUS_SAMPLES_PER_FRAME 2048
|
||||
|
||||
/* max length of AAC stream by bytes */
|
||||
#define MAX_AAC_MAINBUF_SIZE (768 * 2)
|
||||
|
||||
typedef enum {
|
||||
OT_AAC_TYPE_AACLC = 0, /* AAC LC */
|
||||
OT_AAC_TYPE_EAAC = 1, /* EAAC(HEAAC or AAC+ or aac_plus_v1) */
|
||||
OT_AAC_TYPE_EAACPLUS = 2, /* EAAC+(AAC++ or aac_plus_v2) */
|
||||
OT_AAC_TYPE_AACLD = 3,
|
||||
OT_AAC_TYPE_AACELD = 4,
|
||||
OT_AAC_TYPE_BUTT,
|
||||
} ot_aac_type;
|
||||
|
||||
typedef enum {
|
||||
OT_AAC_BPS_8K = 8000,
|
||||
OT_AAC_BPS_16K = 16000,
|
||||
OT_AAC_BPS_22K = 22000,
|
||||
OT_AAC_BPS_24K = 24000,
|
||||
OT_AAC_BPS_32K = 32000,
|
||||
OT_AAC_BPS_48K = 48000,
|
||||
OT_AAC_BPS_64K = 64000,
|
||||
OT_AAC_BPS_96K = 96000,
|
||||
OT_AAC_BPS_128K = 128000,
|
||||
OT_AAC_BPS_256K = 256000,
|
||||
OT_AAC_BPS_320K = 320000,
|
||||
OT_AAC_BPS_BUTT
|
||||
} ot_aac_bps;
|
||||
|
||||
typedef enum {
|
||||
OT_AAC_TRANSPORT_TYPE_ADTS = 0,
|
||||
OT_AAC_TRANSPORT_TYPE_LOAS = 1,
|
||||
OT_AAC_TRANSPORT_TYPE_LATM_MCP1 = 2,
|
||||
OT_AAC_TRANSPORT_TYPE_BUTT
|
||||
} ot_aac_transport_type;
|
||||
|
||||
typedef struct {
|
||||
td_s32 sample_rate; /* sample rate */
|
||||
td_s32 bit_rate; /* bitrate */
|
||||
td_s32 profile; /* profile */
|
||||
td_s32 tns_used; /* TNS tools */
|
||||
td_s32 pns_used; /* PNS tools */
|
||||
td_s32 chn_num; /* channel num */
|
||||
} aacdec_frame_info;
|
||||
|
||||
/*
|
||||
* AAC commendatory parameter:
|
||||
* sampling rate(HZ) LC bit_rate(kbit/s) EAAC bit_rate (kbit/s) EAAC+ bit_rate (kbit/s)
|
||||
* 48000 128 48 32,24
|
||||
* 44100 128 48 32,24
|
||||
* 32000 96 22 16
|
||||
* 24000 64
|
||||
* 22050 64
|
||||
* 16000 48
|
||||
*/
|
||||
typedef struct {
|
||||
ot_aac_type aac_type; /* AAC profile type */
|
||||
ot_aac_bps bit_rate; /* AAC bitrate(LC:16~320, EAAC:24~128, EAAC+:16~64, AACLD:16~320, AACELD:32~320) */
|
||||
ot_audio_sample_rate sample_rate; /* AAC sample rate(LC:8~48, EAAC:16~48, EAAC+:16~48, AACLD:8~48, AACELD:8~48) */
|
||||
ot_audio_bit_width bit_width; /* AAC bit width (only support 16bit) */
|
||||
ot_audio_snd_mode snd_mode; /* sound mode of inferent audio frame */
|
||||
ot_aac_transport_type transport_type;
|
||||
td_s16 band_width; /* targeted audio bandwidth in hz (0 or 1000~smp_rate/2), the default is 0 */
|
||||
} ot_aenc_attr_aac;
|
||||
|
||||
typedef struct {
|
||||
ot_aac_encoder *aac_state;
|
||||
ot_aenc_attr_aac aac_attr;
|
||||
} aenc_aac_encoder;
|
||||
|
||||
typedef struct {
|
||||
ot_aac_transport_type transport_type;
|
||||
} ot_adec_attr_aac;
|
||||
|
||||
typedef struct {
|
||||
ot_aac_decoder aac_state;
|
||||
ot_adec_attr_aac aac_attr;
|
||||
} adec_aac_decoder;
|
||||
|
||||
td_s32 ss_mpi_aenc_aac_init(td_void);
|
||||
|
||||
td_s32 ss_mpi_aenc_aac_deinit(td_void);
|
||||
|
||||
td_s32 ss_mpi_adec_aac_init(td_void);
|
||||
|
||||
td_s32 ss_mpi_adec_aac_deinit(td_void);
|
||||
|
||||
#endif
|
88
ss928sdk/common/audio/adp/audio_dl_adp.c
Executable file
@ -0,0 +1,88 @@
|
||||
/*
|
||||
Copyright (c), 2001-2022, Shenshu Tech. Co., Ltd.
|
||||
*/
|
||||
|
||||
#include "audio_dl_adp.h"
|
||||
#include <stdio.h>
|
||||
#ifndef __LITEOS__
|
||||
#include <dlfcn.h>
|
||||
#else
|
||||
#include <los_ld_elflib.h>
|
||||
#endif
|
||||
|
||||
td_s32 audio_dlpath(td_char *lib_path)
|
||||
{
|
||||
#ifndef __LITEOS__
|
||||
(td_void)lib_path;
|
||||
#else
|
||||
if (LOS_PathAdd(lib_path) != TD_SUCCESS) {
|
||||
printf("add path %s failed!\n", lib_path);
|
||||
return TD_FAILURE;
|
||||
}
|
||||
#endif
|
||||
|
||||
return TD_SUCCESS;
|
||||
}
|
||||
|
||||
td_s32 audio_dlopen(td_void **lib_handle, td_char *lib_name)
|
||||
{
|
||||
if ((lib_handle == TD_NULL) || (lib_name == TD_NULL)) {
|
||||
return TD_FAILURE;
|
||||
}
|
||||
|
||||
*lib_handle = TD_NULL;
|
||||
#ifndef __LITEOS__
|
||||
*lib_handle = dlopen(lib_name, RTLD_LAZY | RTLD_LOCAL);
|
||||
#else
|
||||
*lib_handle = LOS_SoLoad(lib_name);
|
||||
#endif
|
||||
|
||||
if (*lib_handle == TD_NULL) {
|
||||
printf("dlopen %s failed!\n", lib_name);
|
||||
return TD_FAILURE;
|
||||
}
|
||||
|
||||
return TD_SUCCESS;
|
||||
}
|
||||
|
||||
td_s32 audio_dlsym(td_void **func_handle, td_void *lib_handle, td_char *func_name)
|
||||
{
|
||||
if (lib_handle == TD_NULL) {
|
||||
printf("LibHandle is empty!");
|
||||
return TD_FAILURE;
|
||||
}
|
||||
|
||||
*func_handle = TD_NULL;
|
||||
#ifndef __LITEOS__
|
||||
*func_handle = dlsym(lib_handle, func_name);
|
||||
#else
|
||||
*func_handle = LOS_FindSymByName(lib_handle, func_name);
|
||||
#endif
|
||||
|
||||
if (*func_handle == TD_NULL) {
|
||||
#ifndef __LITEOS__
|
||||
printf("dlsym %s fail, error msg is %s!\n", func_name, dlerror());
|
||||
#else
|
||||
printf("dlsym %s fail!\n", func_name);
|
||||
#endif
|
||||
return TD_FAILURE;
|
||||
}
|
||||
|
||||
return TD_SUCCESS;
|
||||
}
|
||||
|
||||
td_s32 audio_dlclose(td_void *lib_handle)
|
||||
{
|
||||
if (lib_handle == TD_NULL) {
|
||||
printf("LibHandle is empty!");
|
||||
return TD_FAILURE;
|
||||
}
|
||||
|
||||
#ifndef __LITEOS__
|
||||
dlclose(lib_handle);
|
||||
#else
|
||||
LOS_ModuleUnload(lib_handle);
|
||||
#endif
|
||||
|
||||
return TD_SUCCESS;
|
||||
}
|
18
ss928sdk/common/audio/adp/audio_dl_adp.h
Executable file
@ -0,0 +1,18 @@
|
||||
/*
|
||||
Copyright (c), 2001-2022, Shenshu Tech. Co., Ltd.
|
||||
*/
|
||||
|
||||
#ifndef __AUDIO_DL_ADP_H__
|
||||
#define __AUDIO_DL_ADP_H__
|
||||
|
||||
#include "ot_type.h"
|
||||
|
||||
td_s32 audio_dlpath(td_char *lib_path);
|
||||
|
||||
td_s32 audio_dlopen(td_void **lib_handle, td_char *lib_name);
|
||||
|
||||
td_s32 audio_dlsym(td_void **func_handle, td_void *lib_handle, td_char *func_name);
|
||||
|
||||
td_s32 audio_dlclose(td_void *lib_handle);
|
||||
|
||||
#endif
|
720
ss928sdk/common/loadbmp.c
Executable file
@ -0,0 +1,720 @@
|
||||
/*
|
||||
Copyright (c), 2001-2022, Shenshu Tech. Co., Ltd.
|
||||
*/
|
||||
|
||||
#include "loadbmp.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "securec.h"
|
||||
#include <limits.h>
|
||||
#include "sample_comm.h"
|
||||
|
||||
#define BITS_NUM_PER_BYTE 8
|
||||
#define BYTE_PER_PIX_1555 2
|
||||
#define BYTE_PER_PIX_8888 4
|
||||
#define PIX_PER_BYTE_CLUT2 4
|
||||
#define PIX_PER_BYTE_CLUT4 2
|
||||
#define STRIDE_ALIGN 4
|
||||
#define MAX_BIT_COUNT 32
|
||||
#define MAX_OFF_BITS 118
|
||||
#define MAX_WIDTH 16384
|
||||
#define MAX_HEIGHT 8192
|
||||
#ifndef align_up
|
||||
#define align_up(x, a) ((((x) + ((a) - 1)) / (a)) * (a))
|
||||
#endif
|
||||
|
||||
osd_component_info g_osd_comp_info[OSD_COLOR_FORMAT_BUTT] = {
|
||||
{ 0, 4, 4, 4 }, /* RGB444 */
|
||||
{ 4, 4, 4, 4 }, /* ARGB4444 */
|
||||
{ 0, 5, 5, 5 }, /* RGB555 */
|
||||
{ 0, 5, 6, 5 }, /* RGB565 */
|
||||
{ 1, 5, 5, 5 }, /* ARGB1555 */
|
||||
{ 0, 0, 0, 0 }, /* RESERVED */
|
||||
{ 0, 8, 8, 8 }, /* RGB888 */
|
||||
{ 8, 8, 8, 8 } /* ARGB8888 */
|
||||
};
|
||||
|
||||
td_u16 osd_make_color_u16(td_u8 r, td_u8 g, td_u8 b, osd_component_info comp_info)
|
||||
{
|
||||
td_u8 r1, g1, b1;
|
||||
td_u16 pixel = 0;
|
||||
td_u32 tmp = 15; /* 15bit color data */
|
||||
|
||||
r1 = r >> (BITS_NUM_PER_BYTE - comp_info.r_len);
|
||||
g1 = g >> (BITS_NUM_PER_BYTE - comp_info.g_len);
|
||||
b1 = b >> (BITS_NUM_PER_BYTE - comp_info.b_len);
|
||||
while (comp_info.a_len) {
|
||||
pixel |= (1 << tmp);
|
||||
tmp--;
|
||||
comp_info.a_len--;
|
||||
}
|
||||
|
||||
pixel |= (r1 | (g1 << comp_info.b_len) | (b1 << (comp_info.b_len + comp_info.g_len)));
|
||||
return pixel;
|
||||
}
|
||||
|
||||
td_s32 get_bmp_info(const td_char *filename, osd_bit_map_file_header *bmp_file_header, osd_bit_map_info *bmp_info)
|
||||
{
|
||||
FILE *file = TD_NULL;
|
||||
td_u16 bf_type;
|
||||
td_char *path = TD_NULL;
|
||||
|
||||
check_null_ptr_return(filename);
|
||||
check_null_ptr_return(bmp_file_header);
|
||||
check_null_ptr_return(bmp_info);
|
||||
|
||||
if (strlen(filename) > PATH_MAX - 1) {
|
||||
printf("file name Extra long\n");
|
||||
return TD_FAILURE;
|
||||
}
|
||||
path = realpath(filename, TD_NULL);
|
||||
if (path == TD_NULL) {
|
||||
return TD_FAILURE;
|
||||
}
|
||||
|
||||
file = fopen(path, "rb");
|
||||
if (file == TD_NULL) {
|
||||
printf("Open file failed:%s!\n", filename);
|
||||
goto read_bmp_failed;
|
||||
}
|
||||
|
||||
(td_void)fread(&bf_type, 1, sizeof(bf_type), file);
|
||||
if (bf_type != 0x4d42) { /* BM */
|
||||
printf("not bitmap file\n");
|
||||
fclose(file);
|
||||
goto read_bmp_failed;
|
||||
}
|
||||
|
||||
(td_void)fread(bmp_file_header, 1, sizeof(osd_bit_map_file_header), file);
|
||||
(td_void)fread(bmp_info, 1, sizeof(osd_bit_map_info), file);
|
||||
|
||||
fclose(file);
|
||||
free(path);
|
||||
return TD_SUCCESS;
|
||||
|
||||
read_bmp_failed:
|
||||
free(path);
|
||||
return TD_FAILURE;
|
||||
}
|
||||
|
||||
static td_bool is_support_bmp_file(const osd_bit_map_info *bmp_info, td_u16 bpp_threshold)
|
||||
{
|
||||
td_u16 bpp;
|
||||
|
||||
bpp = bmp_info->bmp_header.bi_bit_count / BITS_NUM_PER_BYTE;
|
||||
if (bpp_threshold != 0 && bpp < bpp_threshold) {
|
||||
printf("bitmap format not supported!\n");
|
||||
return TD_FALSE;
|
||||
}
|
||||
|
||||
if (bmp_info->bmp_header.bi_compression != 0) {
|
||||
printf("not support compressed bitmap file!\n");
|
||||
return TD_FALSE;
|
||||
}
|
||||
|
||||
if (bmp_info->bmp_header.bi_height < 0) {
|
||||
printf("bmp_info.bmp_header.bi_height < 0\n");
|
||||
return TD_FALSE;
|
||||
}
|
||||
|
||||
return TD_TRUE;
|
||||
}
|
||||
|
||||
static td_s32 read_bmp_data(const osd_bit_map_file_header *bmp_file_header, const osd_bit_map_info *bmp_info,
|
||||
FILE *file, osd_logo *video_logo)
|
||||
{
|
||||
td_u8 *rgb_buf = video_logo->rgb_buf;
|
||||
td_u8 *orig_bmp_buf = NULL;
|
||||
td_u32 bmp_data_stride;
|
||||
td_u32 bmp_data_size;
|
||||
td_u16 bpp, dst_bpp;
|
||||
td_u16 i, j;
|
||||
td_s32 ret;
|
||||
|
||||
bpp = bmp_info->bmp_header.bi_bit_count / BITS_NUM_PER_BYTE;
|
||||
dst_bpp = (bpp > 2) ? 4 : 2; /* RGB1555: 2byte, RGB8888: 4byte */
|
||||
|
||||
video_logo->width = bmp_info->bmp_header.bi_width;
|
||||
video_logo->height = bmp_info->bmp_header.bi_height;
|
||||
if (video_logo->stride == 0) {
|
||||
video_logo->stride = video_logo->width * dst_bpp;
|
||||
}
|
||||
|
||||
bmp_data_stride = video_logo->width * bpp;
|
||||
bmp_data_stride = align_up(bmp_data_stride, STRIDE_ALIGN);
|
||||
bmp_data_size = video_logo->height * bmp_data_stride;
|
||||
|
||||
/* RGB8888 or RGB1555 */
|
||||
orig_bmp_buf = (td_u8 *)malloc(bmp_data_size);
|
||||
if (orig_bmp_buf == NULL) {
|
||||
printf("not enough memory to malloc!\n");
|
||||
return TD_FAILURE;
|
||||
}
|
||||
|
||||
fseek(file, bmp_file_header->bf_off_bits, 0);
|
||||
if (fread(orig_bmp_buf, 1, bmp_data_size, file) != bmp_data_size) {
|
||||
printf("fread error!line:%d\n", __LINE__);
|
||||
perror("fread:");
|
||||
}
|
||||
|
||||
for (i = 0; i < video_logo->height; i++) {
|
||||
for (j = 0; j < video_logo->width; ++j) {
|
||||
ret = memcpy_s(rgb_buf + i * video_logo->stride + j * dst_bpp, bpp,
|
||||
orig_bmp_buf + ((video_logo->height - 1) - i) * bmp_data_stride + j * bpp, bpp);
|
||||
if (ret != EOK) {
|
||||
free(orig_bmp_buf);
|
||||
printf("copy bmp failed!line:%d\n", __LINE__);
|
||||
return TD_FAILURE;
|
||||
}
|
||||
if (dst_bpp == 4) { /* 4: RGB8888 */
|
||||
*(rgb_buf + i * video_logo->stride + j * dst_bpp + 3) = 0x80; /* 3: alpha offset */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
free(orig_bmp_buf);
|
||||
|
||||
return TD_SUCCESS;
|
||||
}
|
||||
|
||||
td_s32 load_bmp(const td_char *filename, osd_logo *video_logo)
|
||||
{
|
||||
osd_bit_map_file_header bmp_file_header;
|
||||
osd_bit_map_info bmp_info;
|
||||
FILE *file = TD_NULL;
|
||||
td_char *path = TD_NULL;
|
||||
|
||||
if (filename == TD_NULL || video_logo == TD_NULL) {
|
||||
printf("load_bmp: null ptr args!\n");
|
||||
return TD_FAILURE;
|
||||
}
|
||||
if (strlen(filename) > PATH_MAX - 1) {
|
||||
printf("file name Extra long\n");
|
||||
return TD_FAILURE;
|
||||
}
|
||||
path = realpath(filename, TD_NULL);
|
||||
if (path == TD_NULL) {
|
||||
return TD_FAILURE;
|
||||
}
|
||||
if (get_bmp_info(path, &bmp_file_header, &bmp_info) < 0) {
|
||||
goto read_bmp_failed;
|
||||
}
|
||||
if (bmp_info.bmp_header.bi_bit_count > MAX_BIT_COUNT || bmp_info.bmp_header.bi_width > MAX_WIDTH ||
|
||||
bmp_info.bmp_header.bi_height > MAX_HEIGHT || bmp_file_header.bf_off_bits > MAX_OFF_BITS) {
|
||||
printf("bmp info error!");
|
||||
goto read_bmp_failed;
|
||||
}
|
||||
if (is_support_bmp_file(&bmp_info, 2) != TD_TRUE) { /* each pixel should takes 2 (or more) bytes */
|
||||
goto read_bmp_failed;
|
||||
}
|
||||
|
||||
file = fopen(path, "rb");
|
||||
if (file == TD_NULL) {
|
||||
printf("Open file failed:%s!\n", filename);
|
||||
goto read_bmp_failed;
|
||||
}
|
||||
|
||||
if (read_bmp_data(&bmp_file_header, &bmp_info, file, video_logo) != TD_SUCCESS) {
|
||||
fclose(file);
|
||||
goto read_bmp_failed;
|
||||
}
|
||||
fclose(file);
|
||||
free(path);
|
||||
return TD_SUCCESS;
|
||||
|
||||
read_bmp_failed:
|
||||
free(path);
|
||||
return TD_FAILURE;
|
||||
}
|
||||
|
||||
static td_void updata_osd_logo_size_info(const osd_bit_map_info *bmp_info, osd_color_format fmt, osd_logo *video_logo)
|
||||
{
|
||||
video_logo->width = bmp_info->bmp_header.bi_width;
|
||||
video_logo->height = bmp_info->bmp_header.bi_height;
|
||||
|
||||
switch (fmt) {
|
||||
case OSD_COLOR_FORMAT_RGB444:
|
||||
case OSD_COLOR_FORMAT_RGB555:
|
||||
case OSD_COLOR_FORMAT_RGB565:
|
||||
case OSD_COLOR_FORMAT_RGB1555:
|
||||
case OSD_COLOR_FORMAT_RGB4444:
|
||||
video_logo->stride = video_logo->width * BYTE_PER_PIX_1555;
|
||||
return;
|
||||
case OSD_COLOR_FORMAT_RGB888:
|
||||
case OSD_COLOR_FORMAT_RGB8888:
|
||||
video_logo->stride = video_logo->width * BYTE_PER_PIX_8888;
|
||||
return;
|
||||
case OSD_COLOR_FORMAT_CLUT2:
|
||||
video_logo->stride = video_logo->width / PIX_PER_BYTE_CLUT2;
|
||||
return;
|
||||
case OSD_COLOR_FORMAT_CLUT4:
|
||||
video_logo->stride = video_logo->width / PIX_PER_BYTE_CLUT4;
|
||||
return;
|
||||
default:
|
||||
printf("file(%s), line(%d), no such format!\n", __FILE__, __LINE__);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static td_s32 copy_original_bmp_data(td_u16 bpp, const td_u8 *data, const bmp_data_size_info *data_size_info,
|
||||
osd_logo *video_logo)
|
||||
{
|
||||
td_u32 i, j;
|
||||
td_s32 ret;
|
||||
td_u8 *rgb_buf = video_logo->rgb_buf;
|
||||
|
||||
for (i = 0; i < data_size_info->height; ++i) {
|
||||
for (j = 0; j < data_size_info->width; ++j) {
|
||||
ret = memcpy_s(rgb_buf + i * video_logo->stride + j * bpp, bpp,
|
||||
data + ((data_size_info->height - 1) - i) * data_size_info->stride + j * bpp, bpp);
|
||||
if (ret != EOK) {
|
||||
printf("copy bmp failed!line:%d\n", __LINE__);
|
||||
return TD_FAILURE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return TD_SUCCESS;
|
||||
}
|
||||
|
||||
static td_s32 copy_clut_bmp_data(td_u16 bpp, osd_color_format fmt, const td_u8 *data,
|
||||
const bmp_data_size_info *data_size_info, osd_logo *video_logo)
|
||||
{
|
||||
td_u32 i, j;
|
||||
td_s32 ret;
|
||||
td_u8 *rgb_buf = video_logo->rgb_buf;
|
||||
td_u32 width = data_size_info->width;
|
||||
|
||||
if (fmt == OSD_COLOR_FORMAT_CLUT4) {
|
||||
width /= PIX_PER_BYTE_CLUT4;
|
||||
} else if (fmt == OSD_COLOR_FORMAT_CLUT2) {
|
||||
width /= PIX_PER_BYTE_CLUT2;
|
||||
} else {
|
||||
}
|
||||
|
||||
for (i = 0; i < data_size_info->height; ++i) {
|
||||
for (j = 0; j < width; ++j) {
|
||||
ret = memcpy_s(rgb_buf + i * video_logo->stride + j, bpp,
|
||||
data + ((data_size_info->height - 1) - i) * data_size_info->stride + j, bpp);
|
||||
if (ret != EOK) {
|
||||
printf("copy bmp failed!line:%d\n", __LINE__);
|
||||
return TD_FAILURE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return TD_SUCCESS;
|
||||
}
|
||||
|
||||
static td_s32 copy_2byte_bmp(td_u16 bpp, osd_color_format fmt, const td_u8 *data,
|
||||
const bmp_data_size_info *data_size_info, osd_logo *video_logo)
|
||||
{
|
||||
td_u32 i, j;
|
||||
td_u8 *rgb_buf = video_logo->rgb_buf;
|
||||
td_u8 r, g, b;
|
||||
td_u8 *start = TD_NULL;
|
||||
td_u16 *dst = TD_NULL;
|
||||
|
||||
/* start color convert */
|
||||
for (i = 0; i < data_size_info->height; ++i) {
|
||||
for (j = 0; j < data_size_info->width; ++j) {
|
||||
start = (td_u8 *)(data + ((data_size_info->height - 1) - i) * data_size_info->stride + j * bpp);
|
||||
dst = (td_u16 *)(rgb_buf + i * video_logo->stride + j * 2); /* 2 bytes */
|
||||
r = *(start);
|
||||
g = *(start + 1);
|
||||
b = *(start + 2); /* 2 bytes offset */
|
||||
*dst = osd_make_color_u16(r, g, b, g_osd_comp_info[fmt]);
|
||||
}
|
||||
}
|
||||
return TD_SUCCESS;
|
||||
}
|
||||
|
||||
static td_s32 copy_4byte_bmp(td_u16 bpp, const td_u8 *data, const bmp_data_size_info *data_size_info,
|
||||
osd_logo *video_logo)
|
||||
{
|
||||
td_u32 i, j;
|
||||
td_s32 ret;
|
||||
td_u8 *rgb_buf = video_logo->rgb_buf;
|
||||
|
||||
for (i = 0; i < data_size_info->height; ++i) {
|
||||
for (j = 0; j < data_size_info->width; ++j) {
|
||||
ret = memcpy_s(rgb_buf + i * video_logo->stride + j * 4, bpp, /* offset 4 bytes */
|
||||
data + ((data_size_info->height - 1) - i) * data_size_info->stride + j * bpp, bpp);
|
||||
if (ret != EOK) {
|
||||
printf("copy bmp failed!line:%d\n", __LINE__);
|
||||
return TD_FAILURE;
|
||||
}
|
||||
*(rgb_buf + i * video_logo->stride + j * 4 + 3) = 0xff; /* 4 bytes data, alpha offset is 3 */
|
||||
}
|
||||
}
|
||||
return TD_SUCCESS;
|
||||
}
|
||||
|
||||
static td_s32 copy_original_bmp_data_and_fill_alpha(td_u16 bpp, osd_color_format fmt, const td_u8 *data,
|
||||
const bmp_data_size_info *data_size_info, osd_logo *video_logo)
|
||||
{
|
||||
switch (fmt) {
|
||||
case OSD_COLOR_FORMAT_RGB444:
|
||||
case OSD_COLOR_FORMAT_RGB555:
|
||||
case OSD_COLOR_FORMAT_RGB565:
|
||||
case OSD_COLOR_FORMAT_RGB1555:
|
||||
case OSD_COLOR_FORMAT_RGB4444:
|
||||
return copy_2byte_bmp(bpp, fmt, data, data_size_info, video_logo);
|
||||
case OSD_COLOR_FORMAT_RGB888:
|
||||
case OSD_COLOR_FORMAT_RGB8888:
|
||||
return copy_4byte_bmp(bpp, data, data_size_info, video_logo);
|
||||
default:
|
||||
printf("file(%s), line(%d), no such format!\n", __FILE__, __LINE__);
|
||||
return TD_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
static td_s32 read_bmp_data_ex(const osd_bit_map_file_header *bmp_file_header, const osd_bit_map_info *bmp_info,
|
||||
FILE *file, osd_logo *video_logo, osd_color_format fmt)
|
||||
{
|
||||
td_u8 *orig_bmp_buf = NULL;
|
||||
td_u16 bpp = bmp_info->bmp_header.bi_bit_count / BITS_NUM_PER_BYTE;
|
||||
td_u32 bmp_data_stride;
|
||||
td_u32 bmp_data_size;
|
||||
td_s32 ret = TD_SUCCESS;
|
||||
bmp_data_size_info data_size_info;
|
||||
|
||||
updata_osd_logo_size_info(bmp_info, fmt, video_logo);
|
||||
|
||||
bmp_data_stride = (bpp == 0) ? video_logo->stride : (video_logo->width * bpp);
|
||||
bmp_data_stride = align_up(bmp_data_stride, STRIDE_ALIGN);
|
||||
bmp_data_size = video_logo->height * bmp_data_stride;
|
||||
|
||||
data_size_info.width = video_logo->width;
|
||||
data_size_info.height = video_logo->height;
|
||||
data_size_info.stride = bmp_data_stride;
|
||||
|
||||
orig_bmp_buf = (td_u8 *)malloc(bmp_data_size);
|
||||
if (orig_bmp_buf == NULL) {
|
||||
printf("not enough memory to malloc!\n");
|
||||
return TD_FAILURE;
|
||||
}
|
||||
|
||||
fseek(file, bmp_file_header->bf_off_bits, 0);
|
||||
if (fread(orig_bmp_buf, 1, bmp_data_size, file) != bmp_data_size) {
|
||||
printf("fread error!line:%d\n", __LINE__);
|
||||
perror("fread:");
|
||||
}
|
||||
|
||||
/* copy bmp data to rgb_buf according bpp (and fmt) */
|
||||
if (bpp == 2 || bpp == 4) { /* each pixel takes 2 (or 4) bytes */
|
||||
ret = copy_original_bmp_data(bpp, orig_bmp_buf, &data_size_info, video_logo);
|
||||
goto copy_over_exit;
|
||||
}
|
||||
|
||||
if (bpp <= 1) { /* such as clut2 or clut 4, or 2BPP... */
|
||||
ret = copy_clut_bmp_data(bpp, fmt, orig_bmp_buf, &data_size_info, video_logo);
|
||||
goto copy_over_exit;
|
||||
}
|
||||
|
||||
/* bpp should equal to 3 here */
|
||||
ret = copy_original_bmp_data_and_fill_alpha(bpp, fmt, orig_bmp_buf, &data_size_info, video_logo);
|
||||
|
||||
copy_over_exit:
|
||||
free(orig_bmp_buf);
|
||||
return ret;
|
||||
}
|
||||
|
||||
td_s32 load_bmp_ex(const td_char *filename, osd_logo *video_logo, osd_color_format fmt)
|
||||
{
|
||||
osd_bit_map_file_header bmp_file_header;
|
||||
osd_bit_map_info bmp_info;
|
||||
FILE *file = TD_NULL;
|
||||
td_char *path = TD_NULL;
|
||||
|
||||
if (filename == TD_NULL || video_logo == TD_NULL) {
|
||||
printf("load_bmp_ex: null ptr args!\n");
|
||||
return TD_FAILURE;
|
||||
}
|
||||
if (strlen(filename) > PATH_MAX - 1) {
|
||||
printf("file name Extra long\n");
|
||||
return TD_FAILURE;
|
||||
}
|
||||
path = realpath(filename, TD_NULL);
|
||||
if (path == TD_NULL) {
|
||||
return TD_FAILURE;
|
||||
}
|
||||
if (get_bmp_info(path, &bmp_file_header, &bmp_info) < 0) {
|
||||
goto read_bmp_failed;
|
||||
}
|
||||
if (bmp_info.bmp_header.bi_bit_count > MAX_BIT_COUNT || bmp_info.bmp_header.bi_width > MAX_WIDTH ||
|
||||
bmp_info.bmp_header.bi_height > MAX_HEIGHT || bmp_file_header.bf_off_bits > MAX_OFF_BITS) {
|
||||
printf("bmp info error!");
|
||||
goto read_bmp_failed;
|
||||
}
|
||||
if (is_support_bmp_file(&bmp_info, 0) != TD_TRUE) {
|
||||
goto read_bmp_failed;
|
||||
}
|
||||
|
||||
file = fopen(path, "rb");
|
||||
if (file == TD_NULL) {
|
||||
printf("Open file failed:%s!\n", filename);
|
||||
goto read_bmp_failed;
|
||||
}
|
||||
|
||||
if (read_bmp_data_ex(&bmp_file_header, &bmp_info, file, video_logo, fmt) != TD_SUCCESS) {
|
||||
fclose(file);
|
||||
goto read_bmp_failed;
|
||||
}
|
||||
fclose(file);
|
||||
free(path);
|
||||
return TD_SUCCESS;
|
||||
|
||||
read_bmp_failed:
|
||||
free(path);
|
||||
return TD_FAILURE;
|
||||
}
|
||||
|
||||
static td_s32 read_bmp_canvas(const osd_bit_map_file_header *bmp_file_header, const osd_bit_map_info *bmp_info,
|
||||
FILE *file, osd_logo *video_logo, osd_color_format fmt)
|
||||
{
|
||||
td_u8 *orig_bmp_buf = NULL;
|
||||
td_u16 bpp = bmp_info->bmp_header.bi_bit_count / BITS_NUM_PER_BYTE;
|
||||
td_u32 bmp_data_size;
|
||||
td_s32 ret = TD_SUCCESS;
|
||||
bmp_data_size_info data_size_info;
|
||||
|
||||
data_size_info.width = bmp_info->bmp_header.bi_width;
|
||||
data_size_info.height = bmp_info->bmp_header.bi_height;
|
||||
|
||||
if (bpp == 0) {
|
||||
if (fmt == OSD_COLOR_FORMAT_CLUT2) {
|
||||
data_size_info.stride = data_size_info.width / PIX_PER_BYTE_CLUT2;
|
||||
} else if (fmt == OSD_COLOR_FORMAT_CLUT4) {
|
||||
data_size_info.stride = data_size_info.width / PIX_PER_BYTE_CLUT4;
|
||||
} else {
|
||||
data_size_info.stride = video_logo->stride;
|
||||
}
|
||||
} else {
|
||||
data_size_info.stride = data_size_info.width * bpp;
|
||||
data_size_info.stride = align_up(data_size_info.stride, STRIDE_ALIGN);
|
||||
}
|
||||
|
||||
bmp_data_size = data_size_info.height * data_size_info.stride;
|
||||
orig_bmp_buf = (td_u8 *)malloc(bmp_data_size);
|
||||
if (orig_bmp_buf == NULL) {
|
||||
printf("not enough memory to malloc!\n");
|
||||
return TD_FAILURE;
|
||||
}
|
||||
|
||||
fseek(file, bmp_file_header->bf_off_bits, 0);
|
||||
if (fread(orig_bmp_buf, 1, bmp_data_size, file) != bmp_data_size) {
|
||||
printf("fread error!line:%d\n", __LINE__);
|
||||
perror("fread:");
|
||||
}
|
||||
|
||||
/* copy bmp data to rgb_buf according bpp (and fmt) */
|
||||
if (bpp == 2 || bpp == 4) { /* each pixel takes 2 (or 4) bytes */
|
||||
ret = copy_original_bmp_data(bpp, orig_bmp_buf, &data_size_info, video_logo);
|
||||
goto copy_over_exit;
|
||||
}
|
||||
|
||||
if (bpp <= 1) { /* such as clut2 or clut 4, or 2BPP... */
|
||||
ret = copy_clut_bmp_data(bpp, fmt, orig_bmp_buf, &data_size_info, video_logo);
|
||||
goto copy_over_exit;
|
||||
}
|
||||
|
||||
/* bpp should equal to 3 here */
|
||||
ret = copy_original_bmp_data_and_fill_alpha(bpp, fmt, orig_bmp_buf, &data_size_info, video_logo);
|
||||
|
||||
copy_over_exit:
|
||||
free(orig_bmp_buf);
|
||||
return ret;
|
||||
}
|
||||
|
||||
td_s32 load_bmp_canvas(const td_char *filename, osd_logo *video_logo, osd_color_format fmt)
|
||||
{
|
||||
osd_bit_map_file_header bmp_file_header;
|
||||
osd_bit_map_info bmp_info;
|
||||
FILE *file = TD_NULL;
|
||||
td_char *path = TD_NULL;
|
||||
|
||||
if (filename == TD_NULL || video_logo == TD_NULL) {
|
||||
printf("load_bmp_canvas: null ptr args!\n");
|
||||
return TD_FAILURE;
|
||||
}
|
||||
if (strlen(filename) > PATH_MAX - 1) {
|
||||
printf("file name Extra long\n");
|
||||
return TD_FAILURE;
|
||||
}
|
||||
path = realpath(filename, TD_NULL);
|
||||
if (path == TD_NULL) {
|
||||
return TD_FAILURE;
|
||||
}
|
||||
if (get_bmp_info(path, &bmp_file_header, &bmp_info) < 0) {
|
||||
goto read_bmp_failed;
|
||||
}
|
||||
if (bmp_info.bmp_header.bi_bit_count > MAX_BIT_COUNT || bmp_info.bmp_header.bi_width > MAX_WIDTH ||
|
||||
bmp_info.bmp_header.bi_height > MAX_HEIGHT || bmp_file_header.bf_off_bits > MAX_OFF_BITS) {
|
||||
printf("bmp info error!");
|
||||
goto read_bmp_failed;
|
||||
}
|
||||
if (is_support_bmp_file(&bmp_info, 0) != TD_TRUE) {
|
||||
goto read_bmp_failed;
|
||||
}
|
||||
|
||||
file = fopen(path, "rb");
|
||||
if (file == TD_NULL) {
|
||||
printf("Open file failed:%s!\n", filename);
|
||||
goto read_bmp_failed;
|
||||
}
|
||||
|
||||
if (read_bmp_canvas(&bmp_file_header, &bmp_info, file, video_logo, fmt) != TD_SUCCESS) {
|
||||
fclose(file);
|
||||
goto read_bmp_failed;
|
||||
}
|
||||
fclose(file);
|
||||
free(path);
|
||||
return TD_SUCCESS;
|
||||
|
||||
read_bmp_failed:
|
||||
free(path);
|
||||
return TD_FAILURE;
|
||||
}
|
||||
|
||||
td_char *get_ext_name(const td_char *filename)
|
||||
{
|
||||
td_char *pret = TD_NULL;
|
||||
size_t len;
|
||||
|
||||
if (filename == TD_NULL) {
|
||||
printf("filename can't be null!");
|
||||
return TD_NULL;
|
||||
}
|
||||
|
||||
len = strlen(filename);
|
||||
while (len) {
|
||||
pret = (td_char *)(filename + len);
|
||||
if (*pret == '.') {
|
||||
return (pret + 1);
|
||||
}
|
||||
|
||||
len--;
|
||||
}
|
||||
|
||||
return pret;
|
||||
}
|
||||
|
||||
td_s32 load_image(const td_char *filename, osd_logo *video_logo)
|
||||
{
|
||||
td_char *ext = get_ext_name(filename);
|
||||
if (ext == TD_NULL) {
|
||||
printf("get_ext_name error!\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (strcmp(ext, "bmp") == 0) {
|
||||
if (load_bmp(filename, video_logo) != 0) {
|
||||
printf("load_bmp error!\n");
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
printf("not supported image file!\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
td_s32 load_image_ex(const td_char *filename, osd_logo *video_logo, osd_color_format fmt)
|
||||
{
|
||||
td_char *ext = get_ext_name(filename);
|
||||
if (ext == TD_NULL) {
|
||||
printf("load_image_ex error!\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (strcmp(ext, "bmp") == 0) {
|
||||
if (load_bmp_ex(filename, video_logo, fmt) != 0) {
|
||||
printf("load_bmp_ex error!\n");
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
printf("not supported image file!\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
td_s32 load_canvas_ex(const td_char *filename, osd_logo *video_logo, osd_color_format fmt)
|
||||
{
|
||||
td_char *ext = get_ext_name(filename);
|
||||
if (ext == TD_NULL) {
|
||||
printf("load_canvas_ex error!\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (strcmp(ext, "bmp") == 0) {
|
||||
if (load_bmp_canvas(filename, video_logo, fmt) != 0) {
|
||||
printf("OSD_LoadBMP error!\n");
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
printf("not supported image file!\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
td_s32 load_bit_map_to_surface(const td_char *file_name, const osd_surface *surface, td_u8 *virt)
|
||||
{
|
||||
osd_logo logo;
|
||||
check_null_ptr_return(file_name);
|
||||
check_null_ptr_return(surface);
|
||||
logo.stride = surface->stride;
|
||||
logo.rgb_buf = virt;
|
||||
|
||||
return load_image(file_name, &logo);
|
||||
}
|
||||
|
||||
td_s32 create_surface_by_bit_map(const td_char *file_name, osd_surface *surface, td_u8 *virt)
|
||||
{
|
||||
osd_logo logo;
|
||||
|
||||
check_null_ptr_return(file_name);
|
||||
check_null_ptr_return(surface);
|
||||
logo.rgb_buf = virt;
|
||||
if (load_image_ex(file_name, &logo, surface->color_format) < 0) {
|
||||
printf("load bmp error!\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
surface->height = logo.height;
|
||||
surface->width = logo.width;
|
||||
surface->stride = logo.stride;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
td_s32 create_surface_by_canvas(const td_char *file_name, osd_surface *surface, td_u8 *virt,
|
||||
const canvas_size_info *canvas_size)
|
||||
{
|
||||
osd_logo logo;
|
||||
|
||||
check_null_ptr_return(file_name);
|
||||
check_null_ptr_return(surface);
|
||||
check_null_ptr_return(canvas_size);
|
||||
logo.rgb_buf = virt;
|
||||
logo.width = canvas_size->width;
|
||||
logo.height = canvas_size->height;
|
||||
logo.stride = canvas_size->stride;
|
||||
if (load_canvas_ex(file_name, &logo, surface->color_format) < 0) {
|
||||
printf("load bmp error!\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
surface->height = canvas_size->height;
|
||||
surface->width = canvas_size->width;
|
||||
surface->stride = canvas_size->stride;
|
||||
|
||||
return 0;
|
||||
}
|
110
ss928sdk/common/loadbmp.h
Executable file
@ -0,0 +1,110 @@
|
||||
/*
|
||||
Copyright (c), 2001-2022, Shenshu Tech. Co., Ltd.
|
||||
*/
|
||||
|
||||
#ifndef __LOAD_BMP_H__
|
||||
#define __LOAD_BMP_H__
|
||||
|
||||
#include "ot_type.h"
|
||||
|
||||
/* the color format OSD supported */
|
||||
typedef enum {
|
||||
OSD_COLOR_FORMAT_RGB444 = 0,
|
||||
OSD_COLOR_FORMAT_RGB4444 = 1,
|
||||
OSD_COLOR_FORMAT_RGB555 = 2,
|
||||
OSD_COLOR_FORMAT_RGB565 = 3,
|
||||
OSD_COLOR_FORMAT_RGB1555 = 4,
|
||||
OSD_COLOR_FORMAT_RGB888 = 6,
|
||||
OSD_COLOR_FORMAT_RGB8888 = 7,
|
||||
OSD_COLOR_FORMAT_CLUT2 = 8,
|
||||
OSD_COLOR_FORMAT_CLUT4 = 9,
|
||||
OSD_COLOR_FORMAT_BUTT
|
||||
} osd_color_format;
|
||||
|
||||
typedef struct {
|
||||
td_u8 r;
|
||||
td_u8 g;
|
||||
td_u8 b;
|
||||
td_u8 reserved;
|
||||
} osd_rgb;
|
||||
|
||||
typedef struct {
|
||||
osd_color_format color_format; /* color format */
|
||||
td_u16 height; /* operation height */
|
||||
td_u16 width; /* operation width */
|
||||
td_u16 stride; /* surface stride */
|
||||
td_u16 reserved;
|
||||
td_u8 *virt_addr; /* virtual address */
|
||||
} osd_surface;
|
||||
|
||||
typedef struct {
|
||||
td_u32 width; /* out */
|
||||
td_u32 height; /* out */
|
||||
td_u32 stride; /* in */
|
||||
td_u8 *rgb_buf; /* in/out */
|
||||
} osd_logo;
|
||||
|
||||
typedef struct {
|
||||
td_u16 bi_size;
|
||||
td_u32 bi_width;
|
||||
td_s32 bi_height;
|
||||
td_u16 bi_planes;
|
||||
td_u16 bi_bit_count;
|
||||
td_u32 bi_compression;
|
||||
td_u32 bi_size_image;
|
||||
td_u32 bi_x_pels_per_meter;
|
||||
td_u32 bi_y_pels_per_meter;
|
||||
td_u32 bi_clr_used;
|
||||
td_u32 bi_clr_important;
|
||||
} osd_bit_map_info_header;
|
||||
|
||||
typedef struct {
|
||||
td_u32 bf_size;
|
||||
td_u16 bf_reserved1;
|
||||
td_u16 bf_reserved2;
|
||||
td_u32 bf_off_bits;
|
||||
} osd_bit_map_file_header;
|
||||
|
||||
typedef struct {
|
||||
td_u8 blue;
|
||||
td_u8 green;
|
||||
td_u8 red;
|
||||
td_u8 reserved;
|
||||
} osd_rgb_quad;
|
||||
|
||||
typedef struct {
|
||||
osd_bit_map_info_header bmp_header;
|
||||
osd_rgb_quad bmp_colors[1];
|
||||
} osd_bit_map_info;
|
||||
|
||||
typedef struct {
|
||||
td_u8 a_len;
|
||||
td_u8 r_len;
|
||||
td_u8 g_len;
|
||||
td_u8 b_len;
|
||||
} osd_component_info;
|
||||
|
||||
typedef struct {
|
||||
td_u32 width;
|
||||
td_u32 height;
|
||||
td_u32 stride;
|
||||
} canvas_size_info;
|
||||
|
||||
typedef canvas_size_info bmp_data_size_info;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
td_s32 load_image(const td_char *filename, osd_logo *video_logo);
|
||||
td_s32 load_bit_map_to_surface(const td_char *file_name, const osd_surface *surface, td_u8 *virt);
|
||||
td_s32 create_surface_by_bit_map(const td_char *file_name, osd_surface *surface, td_u8 *virt);
|
||||
td_s32 create_surface_by_canvas(const td_char *file_name, osd_surface *surface, td_u8 *virt,
|
||||
const canvas_size_info *canvas_size);
|
||||
td_s32 get_bmp_info(const td_char *filename, osd_bit_map_file_header *bmp_file_header, osd_bit_map_info *bmp_info);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* End of #ifndef __LOAD_BMP_H__ */
|
831
ss928sdk/common/sample_comm.h
Executable file
@ -0,0 +1,831 @@
|
||||
/*
|
||||
Copyright (c), 2001-2022, Shenshu Tech. Co., Ltd.
|
||||
*/
|
||||
|
||||
#ifndef __SAMPLE_COMM_H__
|
||||
#define __SAMPLE_COMM_H__
|
||||
|
||||
#include <pthread.h>
|
||||
|
||||
#include "ot_common.h"
|
||||
#include "ot_math.h"
|
||||
#include "ot_buffer.h"
|
||||
#include "ot_defines.h"
|
||||
#include "securec.h"
|
||||
#include "ot_mipi_rx.h"
|
||||
#include "ot_mipi_tx.h"
|
||||
#include "ot_common_sys.h"
|
||||
#include "ot_common_vb.h"
|
||||
#include "ot_common_isp.h"
|
||||
#include "ot_common_vi.h"
|
||||
#include "ot_common_vo.h"
|
||||
#include "ot_common_venc.h"
|
||||
#include "ot_common_vdec.h"
|
||||
#include "ot_common_vpss.h"
|
||||
#include "ot_common_region.h"
|
||||
#include "ot_common_adec.h"
|
||||
#include "ot_common_aenc.h"
|
||||
#include "ot_common_aio.h"
|
||||
#include "ot_common_hdmi.h"
|
||||
#include "ot_common_vgs.h"
|
||||
|
||||
#include "ss_mpi_sys.h"
|
||||
#include "ss_mpi_vb.h"
|
||||
#include "ss_mpi_vi.h"
|
||||
#include "ss_mpi_isp.h"
|
||||
#include "ss_mpi_vo.h"
|
||||
#include "ss_mpi_venc.h"
|
||||
#include "ss_mpi_vdec.h"
|
||||
#include "ss_mpi_vpss.h"
|
||||
#include "ss_mpi_region.h"
|
||||
#include "ss_mpi_audio.h"
|
||||
#include "ss_mpi_hdmi.h"
|
||||
#include "ss_mpi_vgs.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif /* end of #ifdef __cplusplus */
|
||||
|
||||
/* macro define */
|
||||
#define FILE_NAME_LEN 128
|
||||
#define FILE_PATH_LEN 128
|
||||
|
||||
#define SAMPLE_PIXEL_FORMAT OT_PIXEL_FORMAT_YVU_SEMIPLANAR_420
|
||||
|
||||
#define COLOR_RGB_RED 0xFF0000
|
||||
#define COLOR_RGB_GREEN 0x00FF00
|
||||
#define COLOR_RGB_BLUE 0x0000FF
|
||||
#define COLOR_RGB_BLACK 0x000000
|
||||
#define COLOR_RGB_YELLOW 0xFFFF00
|
||||
#define COLOR_RGB_CYN 0x00ffff
|
||||
#define COLOR_RGB_WHITE 0xffffff
|
||||
|
||||
#define SAMPLE_VO_DEV_DHD0 0 /* VO's device HD0 */
|
||||
#define SAMPLE_VO_DEV_DHD1 1 /* VO's device HD1 */
|
||||
#define SAMPLE_VO_DEV_DSD0 2 /* VO's device SD0 */
|
||||
#define SAMPLE_VO_DEV_UHD SAMPLE_VO_DEV_DHD0 /* VO's ultra HD device:HD0 */
|
||||
#define SAMPLE_VO_DEV_HD SAMPLE_VO_DEV_DHD1 /* VO's HD device:HD1 */
|
||||
#define SAMPLE_VO_LAYER_VHD0 0
|
||||
#define SAMPLE_VO_LAYER_VHD1 1
|
||||
#define SAMPLE_VO_LAYER_VHD2 2
|
||||
#define SAMPLE_VO_LAYER_PIP SAMPLE_VO_LAYER_VHD2
|
||||
#define SAMPLE_RGN_HANDLE_NUM_MAX 16
|
||||
#define SAMPLE_RGN_HANDLE_NUM_MIN 1
|
||||
|
||||
#define SAMPLE_AUDIO_EXTERN_AI_DEV 0
|
||||
#define SAMPLE_AUDIO_EXTERN_AO_DEV 0
|
||||
#define SAMPLE_AUDIO_INNER_AI_DEV 0
|
||||
#define SAMPLE_AUDIO_INNER_AO_DEV 0
|
||||
#define SAMPLE_AUDIO_INNER_HDMI_AO_DEV 1
|
||||
|
||||
#define SAMPLE_AUDIO_POINT_NUM_PER_FRAME 480
|
||||
|
||||
#define WDR_MAX_PIPE_NUM 4
|
||||
|
||||
#define CHN_NUM_PRE_DEV 4
|
||||
#define SECOND_CHN_OFFSET_2MUX 2
|
||||
|
||||
#define D1_WIDTH 720
|
||||
#define D1_HEIGHT_PAL 576
|
||||
#define D1_HEIGHT_NTSC 480
|
||||
|
||||
#define _960H_WIDTH 960
|
||||
#define _960H_HEIGHT_PAL 576
|
||||
#define _960H_HEIGHT_NTSC 480
|
||||
|
||||
#define HD_WIDTH 1280
|
||||
#define HD_HEIGHT 720
|
||||
|
||||
#define FHD_WIDTH 1920
|
||||
#define FHD_HEIGHT 1080
|
||||
|
||||
#define _4K_WIDTH 3840
|
||||
#define _4K_HEIGHT 2160
|
||||
|
||||
#define WIDTH_2688 2688
|
||||
#define WIDTH_2592 2592
|
||||
#define HEIGHT_1520 1520
|
||||
|
||||
#define AD_NVP6158 0
|
||||
#define AD_TP2856 1
|
||||
|
||||
#define SAMPLE_AD_TYPE AD_TP2856
|
||||
|
||||
#define NVP6158_FILE "/dev/nc_vdec"
|
||||
#define TP2856_FILE "/dev/tp2802dev"
|
||||
#define TP2828_FILE "/dev/tp2823dev"
|
||||
|
||||
#define ACODEC_FILE "/dev/acodec"
|
||||
|
||||
#define ES8388_FILE "/dev/es8388"
|
||||
#define ES8388_CHIP_ID 0
|
||||
|
||||
#define VO_LT8618SX 0
|
||||
#define LT8618SX_DEV_NAME "/dev/lt8618sx"
|
||||
|
||||
#define VO_MIPI_SUPPORT 1
|
||||
#define MIPI_TX_DEV_NAME "/dev/ot_mipi_tx"
|
||||
|
||||
#define SAMPLE_FRAME_BUF_RATIO_MAX 100
|
||||
#define SAMPLE_FRAME_BUF_RATIO_MIN 70
|
||||
|
||||
#define minor_chn(vi_chn) ((vi_chn) + 1)
|
||||
|
||||
#define sample_pause() \
|
||||
do { \
|
||||
printf("---------------press enter key to exit!---------------\n"); \
|
||||
getchar(); \
|
||||
} while (0)
|
||||
|
||||
#define sample_print(fmt...) \
|
||||
do { \
|
||||
printf("[%s]-%d: ", __FUNCTION__, __LINE__); \
|
||||
printf(fmt); \
|
||||
} while (0)
|
||||
|
||||
#define check_null_ptr_return(ptr) \
|
||||
do { \
|
||||
if ((ptr) == TD_NULL) { \
|
||||
printf("func:%s,line:%d, NULL pointer\n", __FUNCTION__, __LINE__); \
|
||||
return TD_FAILURE; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define check_chn_return(express, chn, name) \
|
||||
do { \
|
||||
td_s32 ret_ = (express); \
|
||||
if (ret_ != TD_SUCCESS) { \
|
||||
printf("\033[0;31m%s chn %d failed at %s: LINE: %d with %#x!\033[0;39m\n", \
|
||||
(name), (chn), __FUNCTION__, __LINE__, ret_); \
|
||||
fflush(stdout); \
|
||||
return ret_; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define check_return(express, name) \
|
||||
do { \
|
||||
td_s32 ret_ = (express); \
|
||||
if (ret_ != TD_SUCCESS) { \
|
||||
printf("\033[0;31m%s failed at %s: LINE: %d with %#x!\033[0;39m\n", \
|
||||
(name), __FUNCTION__, __LINE__, ret_); \
|
||||
return ret_; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define rgn_check_handle_num_return(handle_num) \
|
||||
do { \
|
||||
if (((handle_num) < SAMPLE_RGN_HANDLE_NUM_MIN) || ((handle_num) > SAMPLE_RGN_HANDLE_NUM_MAX)) { \
|
||||
sample_print("handle_num(%d) should be in [%d, %d].\n", \
|
||||
(handle_num), SAMPLE_RGN_HANDLE_NUM_MIN, SAMPLE_RGN_HANDLE_NUM_MAX); \
|
||||
return TD_FAILURE; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
typedef enum {
|
||||
PIC_CIF,
|
||||
PIC_360P, /* 640 * 360 */
|
||||
PIC_D1_PAL, /* 720 * 576 */
|
||||
PIC_D1_NTSC, /* 720 * 480 */
|
||||
PIC_960H, /* 960 * 576 */
|
||||
PIC_720P, /* 1280 * 720 */
|
||||
PIC_1080P, /* 1920 * 1080 */
|
||||
PIC_480P,
|
||||
PIC_576P,
|
||||
PIC_800X600,
|
||||
PIC_1024X768,
|
||||
PIC_1280X1024,
|
||||
PIC_1366X768,
|
||||
PIC_1440X900,
|
||||
PIC_1280X800,
|
||||
PIC_1600X1200,
|
||||
PIC_1680X1050,
|
||||
PIC_1920X1200,
|
||||
PIC_640X480,
|
||||
PIC_1920X2160,
|
||||
PIC_2560X1440,
|
||||
PIC_2560X1600,
|
||||
PIC_2592X1520,
|
||||
PIC_2592X1944,
|
||||
PIC_2688X1520,
|
||||
PIC_3840X2160,
|
||||
PIC_4096X2160,
|
||||
PIC_3000X3000,
|
||||
PIC_4000X3000,
|
||||
PIC_6080X2800,
|
||||
PIC_7680X4320,
|
||||
PIC_3840X8640,
|
||||
PIC_BUTT
|
||||
} ot_enum_pic_size;
|
||||
|
||||
typedef enum {
|
||||
OV_OS08A20_MIPI_8M_30FPS_12BIT,
|
||||
OV_OS08A20_MIPI_8M_30FPS_12BIT_WDR2TO1,
|
||||
OV_OS04A10_MIPI_4M_30FPS_12BIT,
|
||||
OV_OS08B10_MIPI_8M_30FPS_12BIT,
|
||||
OV_OS08B10_MIPI_8M_30FPS_12BIT_WDR2TO1,
|
||||
OV_OS05A10_SLAVE_MIPI_4M_30FPS_12BIT,
|
||||
SONY_IMX347_SLAVE_MIPI_4M_30FPS_12BIT,
|
||||
SONY_IMX485_MIPI_8M_30FPS_12BIT,
|
||||
SONY_IMX485_MIPI_8M_30FPS_10BIT_WDR3TO1,
|
||||
SNS_TYPE_BUTT,
|
||||
} struct_sns_type;
|
||||
|
||||
typedef struct {
|
||||
struct_sns_type sns_type;
|
||||
td_u32 sns_clk_src;
|
||||
td_u32 sns_rst_src;
|
||||
td_u32 bus_id;
|
||||
} struct_sns_info;
|
||||
|
||||
typedef struct {
|
||||
td_s32 mipi_dev;
|
||||
lane_divide_mode_t divide_mode;
|
||||
combo_dev_attr_t combo_dev_attr;
|
||||
ext_data_type_t ext_data_type_attr;
|
||||
} struct_mipi_info;
|
||||
|
||||
typedef struct {
|
||||
ot_vi_dev vi_dev;
|
||||
ot_vi_dev_attr dev_attr;
|
||||
ot_vi_bas_attr bas_attr;
|
||||
} struct_vi_dev_info;
|
||||
|
||||
typedef struct {
|
||||
ot_isp_pub_attr isp_pub_attr;
|
||||
} struct_isp_info;
|
||||
|
||||
typedef struct {
|
||||
td_u32 grp_num;
|
||||
ot_vi_grp fusion_grp[OT_VI_MAX_WDR_FUSION_GRP_NUM];
|
||||
ot_vi_wdr_fusion_grp_attr fusion_grp_attr[OT_VI_MAX_WDR_FUSION_GRP_NUM];
|
||||
} struct_vi_grp_info;
|
||||
|
||||
typedef struct {
|
||||
ot_vi_chn vi_chn;
|
||||
ot_vi_chn_attr chn_attr;
|
||||
} struct_vi_chn_info;
|
||||
|
||||
typedef struct {
|
||||
ot_vi_pipe_attr pipe_attr;
|
||||
|
||||
td_bool pipe_need_start;
|
||||
td_bool isp_need_run;
|
||||
struct_isp_info isp_info;
|
||||
|
||||
td_u32 chn_num;
|
||||
struct_vi_chn_info chn_info[OT_VI_MAX_PHYS_CHN_NUM];
|
||||
} struct_vi_pipe_info;
|
||||
|
||||
typedef struct {
|
||||
struct_sns_info sns_info;
|
||||
struct_mipi_info mipi_info;
|
||||
struct_vi_dev_info dev_info;
|
||||
ot_vi_bind_pipe bind_pipe;
|
||||
struct_vi_grp_info grp_info;
|
||||
struct_vi_pipe_info pipe_info[OT_VI_MAX_PHYS_PIPE_NUM];
|
||||
} struct_vi_cfg;
|
||||
|
||||
typedef struct {
|
||||
ot_vb_blk vb_blk;
|
||||
td_u32 blk_size;
|
||||
ot_video_frame_info frame_info;
|
||||
} struct_vi_user_frame_info;
|
||||
|
||||
typedef struct {
|
||||
ot_size size;
|
||||
ot_pixel_format pixel_format;
|
||||
ot_video_format video_format;
|
||||
ot_compress_mode compress_mode;
|
||||
ot_dynamic_range dynamic_range;
|
||||
} struct_vi_get_frame_vb_cfg;
|
||||
|
||||
typedef struct {
|
||||
td_u32 threshold;
|
||||
td_u32 frame_num;
|
||||
ot_isp_fpn_type fpn_type;
|
||||
ot_pixel_format pixel_format;
|
||||
ot_compress_mode compress_mode;
|
||||
} struct_vi_fpn_calibration_cfg;
|
||||
|
||||
typedef struct {
|
||||
ot_op_mode op_mode;
|
||||
ot_isp_fpn_type fpn_type;
|
||||
td_u32 strength;
|
||||
ot_pixel_format pixel_format;
|
||||
ot_compress_mode compress_mode;
|
||||
struct_vi_user_frame_info user_frame_info;
|
||||
} struct_vi_fpn_correction_cfg;
|
||||
|
||||
typedef struct {
|
||||
td_u32 offset;
|
||||
} struct_scene_fpn_offset_cfg;
|
||||
|
||||
typedef enum {
|
||||
VI_USER_PIC_FRAME = 0,
|
||||
VI_USER_PIC_BGCOLOR,
|
||||
} enum_vi_user_pic_type;
|
||||
|
||||
typedef enum {
|
||||
VO_MODE_1MUX = 0,
|
||||
VO_MODE_2MUX,
|
||||
VO_MODE_4MUX,
|
||||
VO_MODE_8MUX,
|
||||
VO_MODE_9MUX,
|
||||
VO_MODE_16MUX,
|
||||
VO_MODE_25MUX,
|
||||
VO_MODE_36MUX,
|
||||
VO_MODE_49MUX,
|
||||
VO_MODE_64MUX,
|
||||
VO_MODE_2X4,
|
||||
VO_MODE_BUTT
|
||||
} enum_vo_mode;
|
||||
|
||||
typedef enum {
|
||||
SAMPLE_RC_CBR = 0,
|
||||
SAMPLE_RC_VBR,
|
||||
SAMPLE_RC_AVBR,
|
||||
SAMPLE_RC_CVBR,
|
||||
SAMPLE_RC_QVBR,
|
||||
SAMPLE_RC_QPMAP,
|
||||
SAMPLE_RC_FIXQP
|
||||
} enum_rc;
|
||||
|
||||
/* structure define */
|
||||
typedef struct {
|
||||
td_bool thread_start;
|
||||
ot_venc_chn venc_chn[OT_VENC_MAX_CHN_NUM];
|
||||
td_s32 cnt;
|
||||
td_bool save_heif;
|
||||
} struct_venc_getstream_para;
|
||||
|
||||
typedef struct {
|
||||
td_bool thread_start;
|
||||
ot_venc_chn venc_chn[OT_VENC_MAX_CHN_NUM];
|
||||
td_s32 cnt;
|
||||
ot_vpss_grp vpss_grp;
|
||||
ot_vpss_chn vpss_chn[OT_VENC_MAX_CHN_NUM];
|
||||
} struct_venc_rateauto_para;
|
||||
|
||||
typedef struct {
|
||||
td_bool thread_start;
|
||||
ot_vpss_grp vpss_grp;
|
||||
ot_venc_chn venc_chn[OT_VENC_MAX_CHN_NUM];
|
||||
ot_vpss_chn vpss_chn[OT_VPSS_MAX_PHYS_CHN_NUM];
|
||||
ot_size size[OT_VENC_MAX_CHN_NUM];
|
||||
td_s32 cnt;
|
||||
} struct_venc_qpmap_sendframe_para;
|
||||
|
||||
typedef struct {
|
||||
td_bool thread_start;
|
||||
ot_vpss_grp vpss_grp;
|
||||
ot_venc_chn venc_chn[OT_VENC_MAX_CHN_NUM];
|
||||
ot_vpss_chn vpss_chn[OT_VPSS_MAX_PHYS_CHN_NUM];
|
||||
ot_size size[OT_VENC_MAX_CHN_NUM];
|
||||
ot_venc_jpeg_roi_attr roi_attr[OT_VENC_MAX_CHN_NUM];
|
||||
td_s32 cnt;
|
||||
} struct_venc_roimap_frame_para;
|
||||
|
||||
typedef struct {
|
||||
ot_vo_intf_sync intf_sync;
|
||||
td_u32 width;
|
||||
td_u32 height;
|
||||
td_u32 frame_rate;
|
||||
} struct_vo_sync_info;
|
||||
|
||||
typedef struct {
|
||||
enum_vo_mode mode;
|
||||
td_u32 wnd_num;
|
||||
td_u32 square;
|
||||
td_u32 row;
|
||||
td_u32 col;
|
||||
} struct_vo_wnd_info;
|
||||
|
||||
typedef struct {
|
||||
ot_vo_wbc_src_type source_type;
|
||||
ot_dynamic_range dynamic_range;
|
||||
ot_compress_mode compress_mode;
|
||||
td_s32 depth;
|
||||
|
||||
td_s32 vo_wbc;
|
||||
ot_vo_wbc_attr wbc_attr;
|
||||
ot_vo_wbc_src wbc_source;
|
||||
ot_vo_wbc_mode wbc_mode;
|
||||
} struct_vo_wbc_cfg;
|
||||
|
||||
typedef struct {
|
||||
/* for layer */
|
||||
ot_vo_layer vo_layer;
|
||||
ot_vo_intf_sync intf_sync;
|
||||
ot_rect display_rect;
|
||||
ot_size image_size;
|
||||
ot_pixel_format pix_format;
|
||||
|
||||
td_u32 dis_buf_len;
|
||||
ot_dynamic_range dst_dynamic_range;
|
||||
|
||||
/* for chn */
|
||||
enum_vo_mode vo_mode;
|
||||
} struct_comm_vo_layer_cfg;
|
||||
|
||||
typedef struct {
|
||||
/* for device */
|
||||
ot_vo_dev vo_dev;
|
||||
ot_vo_intf_type vo_intf_type;
|
||||
ot_vo_intf_sync intf_sync;
|
||||
ot_enum_pic_size pic_size;
|
||||
td_u32 bg_color;
|
||||
|
||||
/* for layer */
|
||||
ot_pixel_format pix_format;
|
||||
ot_rect disp_rect;
|
||||
ot_size image_size;
|
||||
ot_vo_partition_mode vo_part_mode;
|
||||
ot_compress_mode compress_mode;
|
||||
|
||||
td_u32 dis_buf_len;
|
||||
ot_dynamic_range dst_dynamic_range;
|
||||
|
||||
/* for channel */
|
||||
enum_vo_mode vo_mode;
|
||||
|
||||
/* for user sync */
|
||||
ot_vo_sync_info sync_info;
|
||||
ot_vo_user_sync_info user_sync;
|
||||
td_u32 dev_frame_rate;
|
||||
} struct_vo_cfg;
|
||||
|
||||
#if VO_MIPI_SUPPORT
|
||||
|
||||
typedef enum {
|
||||
OT_MIPI_TX_OUT_576P50 = OT_VO_OUT_576P50,
|
||||
OT_MIPI_TX_OUT_1024X768_60 = OT_VO_OUT_1024x768_60,
|
||||
OT_MIPI_TX_OUT_720P50 = OT_VO_OUT_720P50,
|
||||
OT_MIPI_TX_OUT_720P60 = OT_VO_OUT_720P60,
|
||||
OT_MIPI_TX_OUT_1280X1024_60 = OT_VO_OUT_1280x1024_60,
|
||||
OT_MIPI_TX_OUT_1080P24 = OT_VO_OUT_1080P24,
|
||||
OT_MIPI_TX_OUT_1080P25 = OT_VO_OUT_1080P25,
|
||||
OT_MIPI_TX_OUT_1080P30 = OT_VO_OUT_1080P30,
|
||||
OT_MIPI_TX_OUT_1080P50 = OT_VO_OUT_1080P50,
|
||||
OT_MIPI_TX_OUT_1080P60 = OT_VO_OUT_1080P60,
|
||||
OT_MIPI_TX_OUT_3840X2160_24 = OT_VO_OUT_3840x2160_24,
|
||||
OT_MIPI_TX_OUT_3840X2160_25 = OT_VO_OUT_3840x2160_25,
|
||||
OT_MIPI_TX_OUT_3840X2160_30 = OT_VO_OUT_3840x2160_30,
|
||||
OT_MIPI_TX_OUT_3840X2160_50 = OT_VO_OUT_3840x2160_50,
|
||||
OT_MIPI_TX_OUT_3840X2160_60 = OT_VO_OUT_3840x2160_60,
|
||||
|
||||
OT_MIPI_TX_OUT_720X1280_60 = OT_VO_OUT_720x1280_60,
|
||||
OT_MIPI_TX_OUT_1080X1920_60 = OT_VO_OUT_1080x1920_60,
|
||||
|
||||
OT_MIPI_TX_OUT_USER = OT_VO_OUT_USER,
|
||||
|
||||
OT_MIPI_TX_OUT_BUTT = OT_VO_OUT_BUTT,
|
||||
} enum_mipi_tx_intf_sync;
|
||||
|
||||
typedef struct {
|
||||
cmd_info_t cmd_info;
|
||||
td_u32 usleep_value;
|
||||
}struct_mipi_tx_cmd_info;
|
||||
|
||||
typedef struct {
|
||||
/* for combo dev config */
|
||||
enum_mipi_tx_intf_sync intf_sync;
|
||||
|
||||
/* for screen cmd */
|
||||
td_u32 cmd_count;
|
||||
struct_mipi_tx_cmd_info *cmd_info;
|
||||
|
||||
/* for user sync */
|
||||
combo_dev_cfg_t combo_dev_cfg;
|
||||
} struct_mipi_tx_config;
|
||||
|
||||
typedef struct {
|
||||
struct_vo_cfg vo_config;
|
||||
struct_mipi_tx_config tx_config;
|
||||
} struct_vo_mipi_tx_cfg;
|
||||
|
||||
#endif
|
||||
|
||||
typedef enum {
|
||||
THREAD_CTRL_START,
|
||||
THREAD_CTRL_PAUSE,
|
||||
THREAD_CTRL_STOP,
|
||||
} enum_thread_contrl;
|
||||
|
||||
typedef struct {
|
||||
ot_enum_pic_size pic_size;
|
||||
ot_vo_intf_sync intf_sync;
|
||||
ot_vo_intf_type intf_type;
|
||||
} struct_vdec_display_cfg;
|
||||
|
||||
typedef struct {
|
||||
td_s32 chn_id;
|
||||
ot_payload_type type;
|
||||
td_char c_file_path[FILE_PATH_LEN];
|
||||
td_char c_file_name[FILE_NAME_LEN];
|
||||
td_s32 stream_mode;
|
||||
td_s32 milli_sec;
|
||||
td_s32 min_buf_size;
|
||||
td_s32 interval_time;
|
||||
enum_thread_contrl e_thread_ctrl;
|
||||
td_u64 pts_init;
|
||||
td_u64 pts_increase;
|
||||
td_bool circle_send;
|
||||
td_u64 last_time;
|
||||
td_u64 time_gap;
|
||||
td_u64 fps;
|
||||
} struct_vdec_thread_param;
|
||||
|
||||
typedef struct {
|
||||
td_u32 pic_buf_size;
|
||||
td_u32 tmv_buf_size;
|
||||
td_bool pic_buf_alloc;
|
||||
td_bool tmv_buf_alloc;
|
||||
} struct_vdec_buf;
|
||||
|
||||
typedef struct {
|
||||
ot_video_dec_mode dec_mode;
|
||||
td_u32 ref_frame_num;
|
||||
ot_data_bit_width bit_width;
|
||||
} struct_vdec_video_attr;
|
||||
|
||||
typedef struct {
|
||||
ot_pixel_format pixel_format;
|
||||
td_u32 alpha;
|
||||
} struct_vdec_pic_attr;
|
||||
|
||||
typedef struct {
|
||||
ot_payload_type type;
|
||||
ot_vdec_send_mode mode;
|
||||
td_u32 width;
|
||||
td_u32 height;
|
||||
td_u32 frame_buf_cnt;
|
||||
td_u32 display_frame_num;
|
||||
union {
|
||||
struct_vdec_video_attr member_vdec_video; /* structure with video (h265/h264) */
|
||||
struct_vdec_pic_attr member_vdec_picture; /* structure with picture (jpeg/mjpeg) */
|
||||
};
|
||||
} struct_vdec_attr;
|
||||
|
||||
typedef struct {
|
||||
ot_video_format video_format;
|
||||
ot_pixel_format pixel_format;
|
||||
td_u32 width;
|
||||
td_u32 height;
|
||||
td_u32 align;
|
||||
ot_compress_mode compress_mode;
|
||||
} struct_vb_base_info;
|
||||
|
||||
typedef struct {
|
||||
td_u32 vb_size;
|
||||
td_u32 head_stride;
|
||||
td_u32 head_size;
|
||||
td_u32 head_y_size;
|
||||
td_u32 main_stride;
|
||||
td_u32 main_size;
|
||||
td_u32 main_y_size;
|
||||
td_u32 ext_stride;
|
||||
td_u32 ext_y_size;
|
||||
} struct_vb_cal_config;
|
||||
|
||||
typedef struct {
|
||||
td_u32 frame_rate;
|
||||
td_u32 stats_time;
|
||||
td_u32 gop;
|
||||
ot_size venc_size;
|
||||
ot_enum_pic_size size;
|
||||
td_u32 profile;
|
||||
td_bool is_rcn_ref_share_buf;
|
||||
ot_venc_gop_attr gop_attr;
|
||||
ot_payload_type type;
|
||||
enum_rc rc_mode;
|
||||
} struct_comm_venc_chn_param;
|
||||
|
||||
typedef struct {
|
||||
ot_vpss_chn *vpss_chn;
|
||||
ot_venc_chn *venc_chn;
|
||||
td_s32 cnt;
|
||||
} struct_venc_roimap_chn_info;
|
||||
|
||||
typedef struct {
|
||||
ot_audio_sample_rate out_sample_rate;
|
||||
td_bool resample_en;
|
||||
td_void *ai_vqe_attr;
|
||||
td_u32 ai_vqe_type;
|
||||
} struct_comm_ai_vqe_param;
|
||||
|
||||
/* function announce */
|
||||
#ifndef __LITEOS__
|
||||
td_void libapi_sys_signal(void (*func)(int));
|
||||
#endif
|
||||
|
||||
td_s32 libapi_comm_sys_get_pic_size(ot_enum_pic_size pic_size, ot_size *size);
|
||||
ot_enum_pic_size libapi_comm_sys_get_pic_enum(const ot_size *size);
|
||||
td_s32 libapi_comm_sys_mem_config(td_void);
|
||||
td_void libapi_comm_sys_exit(td_void);
|
||||
td_s32 libapi_comm_sys_init(const ot_vb_cfg *vb_cfg);
|
||||
td_s32 libapi_comm_sys_init_with_vb_supplement(const ot_vb_cfg *vb_cfg, td_u32 supplement_config);
|
||||
|
||||
td_s32 libapi_comm_vi_bind_vo(ot_vi_pipe vi_pipe, ot_vi_chn vi_chn, ot_vo_layer vo_layer, ot_vo_chn vo_chn);
|
||||
td_s32 libapi_comm_vi_un_bind_vo(ot_vi_pipe vi_pipe, ot_vi_chn vi_chn, ot_vo_layer vo_layer, ot_vo_chn vo_chn);
|
||||
td_s32 libapi_comm_vi_bind_vpss(ot_vi_pipe vi_pipe, ot_vi_chn vi_chn, ot_vpss_grp vpss_grp, ot_vpss_chn vpss_chn);
|
||||
td_s32 libapi_comm_vi_un_bind_vpss(ot_vi_pipe vi_pipe, ot_vi_chn vi_chn, ot_vpss_grp vpss_grp, ot_vpss_chn vpss_chn);
|
||||
td_s32 libapi_comm_vi_bind_venc(ot_vi_pipe vi_pipe, ot_vi_chn vi_chn, ot_venc_chn venc_chn);
|
||||
td_s32 libapi_comm_vi_un_bind_venc(ot_vi_pipe vi_pipe, ot_vi_chn vi_chn, ot_venc_chn venc_chn);
|
||||
td_s32 libapi_comm_avs_bind_venc(ot_avs_grp avs_grp, ot_avs_chn avs_chn, ot_venc_chn venc_chn);
|
||||
td_s32 libapi_comm_avs_un_bind_venc(ot_avs_grp avs_grp, ot_avs_chn avs_chn, ot_venc_chn venc_chn);
|
||||
td_s32 libapi_comm_avs_bind_vo(ot_avs_grp avs_grp, ot_avs_chn avs_chn, ot_vo_layer vo_layer, ot_vo_chn vo_chn);
|
||||
td_s32 libapi_comm_avs_un_bind_vo(ot_avs_grp avs_grp, ot_avs_chn avs_chn, ot_vo_layer vo_layer, ot_vo_chn vo_chn);
|
||||
|
||||
td_s32 libapi_comm_vi_switch_isp_mode(const struct_vi_cfg *vi_cfg);
|
||||
td_s32 libapi_comm_vi_switch_isp_resolution(const struct_vi_cfg *vi_cfg, const ot_size *size);
|
||||
td_void libapi_comm_vi_mode_switch_stop_vi(const struct_vi_cfg *vi_cfg);
|
||||
td_s32 libapi_comm_vi_mode_switch_start_vi(const struct_vi_cfg *vi_cfg, td_bool chg_resolution, const ot_size *size);
|
||||
|
||||
td_s32 libapi_comm_vpss_bind_vo(ot_vpss_grp vpss_grp, ot_vpss_chn vpss_chn, ot_vo_layer vo_layer, ot_vo_chn vo_chn);
|
||||
td_s32 libapi_comm_vpss_un_bind_vo(ot_vpss_grp vpss_grp, ot_vpss_chn vpss_chn, ot_vo_layer vo_layer, ot_vo_chn vo_chn);
|
||||
td_s32 libapi_comm_vpss_bind_avs(ot_vpss_grp vpss_grp, ot_vpss_chn vpss_chn, ot_avs_grp avs_grp, ot_avs_pipe avs_pipe);
|
||||
td_s32 libapi_comm_vpss_un_bind_avs(ot_vpss_grp vpss_grp, ot_vpss_chn vpss_chn,
|
||||
ot_avs_grp avs_grp, ot_avs_pipe avs_pipe);
|
||||
td_s32 libapi_comm_vpss_bind_venc(ot_vpss_grp vpss_grp, ot_vpss_chn vpss_chn, ot_venc_chn venc_chn);
|
||||
td_s32 libapi_comm_vpss_un_bind_venc(ot_vpss_grp vpss_grp, ot_vpss_chn vpss_chn, ot_venc_chn venc_chn);
|
||||
|
||||
td_s32 libapi_comm_vdec_bind_vpss(ot_vdec_chn vdec_chn, ot_vpss_grp vpss_grp);
|
||||
td_s32 libapi_comm_vdec_un_bind_vpss(ot_vdec_chn vdec_chn, ot_vpss_grp vpss_grp);
|
||||
td_s32 libapi_comm_vo_bind_vo(ot_vo_layer src_vo_layer, ot_vo_chn src_vo_chn,
|
||||
ot_vo_layer dst_vo_layer, ot_vo_chn dst_vo_chn);
|
||||
td_s32 libapi_comm_vo_un_bind_vo(ot_vo_layer dst_vo_layer, ot_vo_chn dst_vo_chn);
|
||||
|
||||
td_s32 libapi_comm_isp_sensor_regiter_callback(ot_isp_dev isp_dev, struct_sns_type sns_type);
|
||||
td_s32 libapi_comm_isp_sensor_unregiter_callback(ot_isp_dev isp_dev);
|
||||
td_s32 libapi_comm_isp_bind_sns(ot_isp_dev isp_dev, struct_sns_type sns_type, td_s8 sns_dev);
|
||||
td_s32 libapi_comm_isp_ae_lib_callback(ot_isp_dev isp_dev);
|
||||
td_s32 libapi_comm_isp_ae_lib_uncallback(ot_isp_dev isp_dev);
|
||||
td_s32 libapi_comm_isp_awb_lib_callback(ot_isp_dev isp_dev);
|
||||
td_s32 libapi_comm_isp_awb_lib_uncallback(ot_isp_dev isp_dev);
|
||||
td_s32 libapi_comm_isp_run(ot_isp_dev isp_dev);
|
||||
td_void libapi_comm_isp_stop(ot_isp_dev isp_dev);
|
||||
td_void libapi_comm_all_isp_stop(td_void);
|
||||
td_s32 libapi_comm_isp_get_pub_attr_by_sns(struct_sns_type sns_type, ot_isp_pub_attr *pub_attr);
|
||||
ot_isp_sns_type libapi_comm_get_sns_bus_type(struct_sns_type sns_type);
|
||||
td_s32 libapi_comm_isp_sensor_founction_cfg(ot_vi_pipe vi_pipe, struct_sns_type sns_type);
|
||||
|
||||
td_void libapi_comm_vi_get_size_by_sns_type(struct_sns_type sns_type, ot_size *size);
|
||||
td_void libapi_comm_vi_get_default_vi_cfg(struct_sns_type sns_type, struct_vi_cfg *vi_cfg);
|
||||
td_void libapi_comm_vi_init_vi_cfg(struct_sns_type sns_type, ot_size *size, struct_vi_cfg *vi_cfg);
|
||||
|
||||
td_s32 libapi_comm_vi_set_vi_vpss_mode(ot_vi_vpss_mode_type mode_type, ot_vi_video_mode video_mode);
|
||||
td_s32 libapi_comm_vi_start_vi(const struct_vi_cfg *vi_cfg);
|
||||
td_void libapi_comm_vi_stop_vi(const struct_vi_cfg *vi_cfg);
|
||||
td_void libapi_comm_vi_stop_four_vi(const struct_vi_cfg *vi_cfg, td_s32 route_num);
|
||||
td_s32 libapi_comm_vi_fpn_calibrate(ot_vi_pipe vi_pipe, struct_vi_fpn_calibration_cfg *calibration_cfg);
|
||||
td_s32 libapi_comm_vi_enable_fpn_correction(ot_vi_pipe vi_pipe, struct_vi_fpn_correction_cfg *correction_cfg);
|
||||
td_s32 libapi_comm_vi_disable_fpn_correction(ot_vi_pipe vi_pipe, struct_vi_fpn_correction_cfg *correction_cfg);
|
||||
|
||||
td_s32 libapi_comm_vi_enable_fpn_correction_for_scene(ot_vi_pipe vi_pipe, struct_vi_fpn_correction_cfg *correction_cfg,
|
||||
td_u32 iso, struct_scene_fpn_offset_cfg *scene_fpn_offset_cfg, const td_char *dir_name);
|
||||
|
||||
td_s32 libapi_comm_vi_start_virt_pipe(const struct_vi_cfg *vi_cfg);
|
||||
td_void libapi_comm_vi_stop_virt_pipe(const struct_vi_cfg *vi_cfg);
|
||||
td_s32 libapi_common_vi_load_user_pic(ot_vi_pipe vi_pipe, enum_vi_user_pic_type user_pic_type,
|
||||
struct_vi_user_frame_info *user_frame_info);
|
||||
td_void libapi_common_vi_unload_user_pic(struct_vi_user_frame_info *user_frame_info);
|
||||
td_s32 libapi_comm_vi_send_wdr_frame(ot_vi_bind_pipe *bind_pipe);
|
||||
|
||||
td_void libapi_comm_vpss_get_default_grp_attr(ot_vpss_grp_attr *grp_attr);
|
||||
td_void libapi_comm_vpss_get_default_chn_attr(ot_vpss_chn_attr *chn_attr);
|
||||
td_s32 libapi_common_vpss_start(ot_vpss_grp grp, const td_bool *chn_enable,
|
||||
const ot_vpss_grp_attr *grp_attr, const ot_vpss_chn_attr *chn_attr, td_u32 chn_array_size);
|
||||
td_s32 libapi_common_vpss_stop(ot_vpss_grp grp, const td_bool *chn_enable, td_u32 chn_array_size);
|
||||
|
||||
td_s32 libapi_comm_vo_get_width_height(ot_vo_intf_sync intf_sync, td_u32 *width, td_u32 *height,
|
||||
td_u32 *frame_rate);
|
||||
td_s32 libapi_comm_vo_mem_config(ot_vo_dev vo_dev, td_char *pc_mmz_name);
|
||||
td_s32 libapi_comm_vo_start_dev(ot_vo_dev vo_dev,
|
||||
const ot_vo_pub_attr *pub_attr,
|
||||
const ot_vo_user_sync_info *sync_info,
|
||||
td_u32 dev_frame_rate);
|
||||
|
||||
td_s32 libapi_comm_vo_stop_dev(ot_vo_dev vo_dev);
|
||||
td_s32 libapi_comm_vo_start_layer(ot_vo_layer vo_layer, const ot_vo_video_layer_attr *layer_attr);
|
||||
td_s32 libapi_comm_vo_stop_layer(ot_vo_layer vo_layer);
|
||||
td_s32 libapi_comm_vo_get_wnd_info(enum_vo_mode mode, struct_vo_wnd_info *wnd_info);
|
||||
td_s32 libapi_comm_vo_get_chn_attr(struct_vo_wnd_info *wnd_info, ot_vo_video_layer_attr *layer_attr,
|
||||
td_s32 chn, ot_vo_chn_attr *chn_attr);
|
||||
td_s32 libapi_comm_vo_start_chn(ot_vo_layer vo_layer, enum_vo_mode mode);
|
||||
td_s32 libapi_comm_vo_stop_chn(ot_vo_layer vo_layer, enum_vo_mode mode);
|
||||
td_s32 libapi_comm_vo_start_wbc(struct_vo_wbc_cfg *wbc_config);
|
||||
td_s32 libapi_comm_vo_stop_wbc(struct_vo_wbc_cfg *wbc_config);
|
||||
td_s32 libapi_comm_vo_get_def_wbc_config(struct_vo_wbc_cfg *wbc_config);
|
||||
td_s32 libapi_comm_vo_bind_vi(ot_vo_layer vo_layer, ot_vo_chn vo_chn, ot_vi_chn vi_chn);
|
||||
td_s32 libapi_comm_vo_un_bind_vi(ot_vo_layer vo_layer, ot_vo_chn vo_chn);
|
||||
td_s32 libapi_comm_vo_bt1120_start(ot_vo_dev vo_dev, ot_vo_pub_attr *pub_attr);
|
||||
td_s32 libapi_comm_vo_hdmi_start(ot_vo_intf_sync intf_sync);
|
||||
td_s32 libapi_comm_vo_hdmi_stop(td_void);
|
||||
td_s32 libapi_comm_start_mipi_tx(const struct_mipi_tx_config *tx_config);
|
||||
td_void libapi_comm_stop_mipi_tx(ot_vo_intf_type intf_type);
|
||||
td_s32 libapi_comm_vo_get_def_config(struct_vo_cfg *vo_config);
|
||||
td_s32 libapi_comm_vo_stop_vo(const struct_vo_cfg *vo_config);
|
||||
td_void libapi_comm_vo_set_hdmi_rgb_mode(td_bool enable);
|
||||
td_s32 libapi_comm_vo_start_vo(const struct_vo_cfg *vo_config);
|
||||
td_s32 sample_comm_vo_stop_pip(const struct_vo_cfg *vo_config);
|
||||
td_s32 sample_comm_vo_start_pip(struct_vo_cfg *vo_config);
|
||||
td_s32 sample_comm_vo_get_def_layer_config(struct_comm_vo_layer_cfg *vo_layer_config);
|
||||
td_s32 sample_comm_vo_start_layer_chn(struct_comm_vo_layer_cfg *vo_layer_config);
|
||||
td_s32 sample_comm_vo_stop_layer_chn(struct_comm_vo_layer_cfg *vo_layer_config);
|
||||
|
||||
td_s32 sample_comm_venc_mem_config(td_void);
|
||||
td_s32 sample_comm_venc_create(ot_venc_chn venc_chn, struct_comm_venc_chn_param *chn_param);
|
||||
td_s32 sample_comm_venc_start(ot_venc_chn venc_chn, struct_comm_venc_chn_param *chn_param);
|
||||
td_s32 sample_comm_venc_stop(ot_venc_chn venc_chn);
|
||||
td_s32 sample_comm_venc_snap_start(ot_venc_chn venc_chn, ot_size *size, td_bool support_dcf);
|
||||
td_s32 sample_comm_venc_photo_start(ot_venc_chn venc_chn, ot_size *size, td_bool support_dcf);
|
||||
td_s32 sample_comm_venc_snap_process(ot_venc_chn venc_chn, td_u32 snap_cnt, td_bool save_jpg, td_bool save_thm);
|
||||
td_s32 sample_comm_venc_save_jpeg(ot_venc_chn venc_chn, td_u32 snap_cnt);
|
||||
td_s32 sample_comm_venc_snap_stop(ot_venc_chn venc_chn);
|
||||
td_s32 sample_comm_venc_start_get_stream(ot_venc_chn ve_chn[], td_s32 cnt);
|
||||
td_s32 sample_comm_venc_stop_get_stream(td_s32 chn_num);
|
||||
td_s32 sample_comm_venc_start_get_stream_svc_t(td_s32 cnt);
|
||||
td_s32 sample_comm_venc_get_gop_attr(ot_venc_gop_mode gop_mode, ot_venc_gop_attr *gop_attr);
|
||||
td_s32 sample_comm_venc_qpmap_send_frame(ot_vpss_grp vpss_grp, ot_vpss_chn vpss_chn[],
|
||||
ot_venc_chn venc_chn[], td_s32 cnt, ot_size size[]);
|
||||
td_s32 sample_comm_venc_stop_send_qpmap_frame(td_void);
|
||||
td_s32 sample_comm_venc_rateauto_start(ot_venc_chn ve_chn[], td_s32 cnt, ot_vpss_grp vpss_grp, ot_vpss_chn vpss_chn[]);
|
||||
td_s32 sample_comm_venc_stop_rateauto(ot_venc_chn ve_chn[], td_s32 cnt);
|
||||
|
||||
td_s32 sample_comm_venc_send_roimap_frame(ot_vpss_grp vpss_grp, struct_venc_roimap_chn_info roimap_chn_info,
|
||||
ot_size size[], ot_venc_jpeg_roi_attr roi_attr[]);
|
||||
td_s32 sample_comm_venc_stop_send_roimap_frame(td_void);
|
||||
td_s32 sample_comm_venc_save_stream(FILE *fd, ot_venc_stream *stream);
|
||||
|
||||
td_s32 sample_comm_region_create(td_s32 handle_num, ot_rgn_type type);
|
||||
td_s32 sample_comm_region_destroy(td_s32 handle_num, ot_rgn_type type);
|
||||
td_s32 sample_comm_region_attach_to_chn(td_s32 handle_num, ot_rgn_type type, ot_mpp_chn *mpp_chn);
|
||||
td_s32 sample_comm_check_min(td_s32 min_handle);
|
||||
td_s32 sample_comm_region_detach_frm_chn(td_s32 handle_num, ot_rgn_type type, ot_mpp_chn *mpp_chn);
|
||||
td_s32 sample_comm_region_set_bit_map(ot_rgn_handle handle, const td_char *bmp_path);
|
||||
td_s32 sample_comm_region_get_up_canvas(ot_rgn_handle handle, const td_char *bmp_path);
|
||||
td_s32 sample_comm_region_get_min_handle(ot_rgn_type type);
|
||||
|
||||
td_s32 sample_comm_audio_creat_trd_ai_ao(ot_audio_dev ai_dev, ot_ai_chn ai_chn, ot_audio_dev ao_dev, ot_ao_chn ao_chn);
|
||||
td_s32 sample_comm_audio_creat_trd_ai_aenc(ot_audio_dev ai_dev, ot_ai_chn ai_chn, ot_aenc_chn ae_chn);
|
||||
td_s32 sample_comm_audio_creat_trd_aenc_adec(ot_aenc_chn ae_chn, ot_adec_chn ad_chn, FILE *aenc_fd);
|
||||
td_s32 sample_comm_audio_creat_trd_file_adec(ot_adec_chn ad_chn, FILE *adec_fd);
|
||||
td_s32 sample_comm_audio_creat_trd_ao_vol_ctrl(ot_audio_dev ao_dev);
|
||||
td_s32 sample_comm_audio_destory_trd_ai(ot_audio_dev ai_dev, ot_ai_chn ai_chn);
|
||||
td_s32 sample_comm_audio_destory_trd_aenc_adec(ot_aenc_chn ae_chn);
|
||||
td_s32 sample_comm_audio_destory_trd_file_adec(ot_adec_chn ad_chn);
|
||||
td_s32 sample_comm_audio_destory_trd_ao_vol_ctrl(ot_audio_dev ao_dev);
|
||||
td_s32 sample_comm_audio_destory_all_trd(td_void);
|
||||
td_s32 sample_comm_audio_ao_bind_adec(ot_audio_dev ao_dev, ot_ao_chn ao_chn, ot_adec_chn ad_chn);
|
||||
td_s32 sample_comm_audio_ao_unbind_adec(ot_audio_dev ao_dev, ot_ao_chn ao_chn, ot_adec_chn ad_chn);
|
||||
td_s32 sample_comm_audio_ao_bind_ai(ot_audio_dev ai_dev, ot_ai_chn ai_chn, ot_audio_dev ao_dev, ot_ao_chn ao_chn);
|
||||
td_s32 sample_comm_audio_ao_unbind_ai(ot_audio_dev ai_dev, ot_ai_chn ai_chn, ot_audio_dev ao_dev, ot_ao_chn ao_chn);
|
||||
td_s32 sample_comm_audio_aenc_bind_ai(ot_audio_dev ai_dev, ot_ai_chn ai_chn, ot_aenc_chn ae_chn);
|
||||
td_s32 sample_comm_audio_aenc_unbind_ai(ot_audio_dev ai_dev, ot_ai_chn ai_chn, ot_aenc_chn ae_chn);
|
||||
td_s32 sample_comm_audio_start_ai(ot_audio_dev ai_dev_id, td_u32 ai_chn_cnt, ot_aio_attr *aio_attr,
|
||||
const struct_comm_ai_vqe_param *ai_vqe_param, ot_audio_dev ao_dev_id);
|
||||
td_s32 sample_comm_audio_stop_ai(ot_audio_dev ai_dev_id, td_u32 ai_chn_cnt, td_bool resample_en, td_bool vqe_en);
|
||||
td_s32 sample_comm_audio_start_ao(ot_audio_dev ao_dev_id, td_u32 ao_chn_cnt,
|
||||
ot_aio_attr *aio_attr, ot_audio_sample_rate in_sample_rate, td_bool resample_en);
|
||||
td_s32 sample_comm_audio_stop_ao(ot_audio_dev ao_dev_id, td_u32 ao_chn_cnt, td_bool resample_en);
|
||||
td_s32 sample_comm_audio_start_aenc(td_u32 aenc_chn_cnt, const ot_aio_attr *aio_attr, ot_payload_type type);
|
||||
td_s32 sample_comm_audio_stop_aenc(td_u32 aenc_chn_cnt);
|
||||
td_s32 sample_comm_audio_start_adec(td_u32 adec_chn_cnt, ot_payload_type type);
|
||||
td_s32 sample_comm_audio_stop_adec(ot_adec_chn ad_chn);
|
||||
td_s32 sample_comm_audio_cfg_acodec(const ot_aio_attr *aio_attr);
|
||||
|
||||
td_s32 sample_comm_vdec_init_vb_pool(td_u32 chn_num, struct_vdec_attr *past_sample_vdec, td_u32 arr_len);
|
||||
td_void sample_comm_vdec_exit_vb_pool(td_void);
|
||||
td_void sample_comm_vdec_cmd_ctrl(td_s32 chn_num, struct_vdec_thread_param *vdec_send, pthread_t *vdec_thread,
|
||||
td_u32 send_arr_len, td_u32 thread_arr_len);
|
||||
td_void sample_comm_vdec_start_send_stream(td_s32 chn_num, struct_vdec_thread_param *vdec_send, pthread_t *vdec_thread,
|
||||
td_u32 send_arr_len, td_u32 thread_arr_len);
|
||||
td_void sample_comm_vdec_stop_send_stream(td_s32 chn_num, struct_vdec_thread_param *vdec_send, pthread_t *vdec_thread,
|
||||
td_u32 send_arr_len, td_u32 thread_arr_len);
|
||||
td_void *sample_comm_vdec_send_stream(td_void *args);
|
||||
td_s32 sample_comm_vdec_start(td_s32 chn_num, struct_vdec_attr *past_sample_vdec, td_u32 arr_len);
|
||||
td_s32 sample_comm_vdec_stop(td_s32 chn_num);
|
||||
td_void sample_comm_vdec_cmd_not_circle_send(td_u32 chn_num, struct_vdec_thread_param *vdec_send, pthread_t *vdec_thread,
|
||||
td_u32 send_arr_len, td_u32 thread_arr_len);
|
||||
td_void sample_comm_vdec_print_chn_status(td_s32 chn, ot_vdec_chn_status status);
|
||||
td_bool sample_comm_vdec_get_lowdelay_en(td_void);
|
||||
td_void sample_comm_vdec_set_lowdelay_en(td_bool enable);
|
||||
|
||||
td_s32 sample_comm_venc_get_file_postfix(ot_payload_type payload, td_char *file_postfix, td_u8 len);
|
||||
td_void sample_comm_vi_get_default_sns_info(struct_sns_type sns_type, struct_sns_info *sns_info);
|
||||
td_void sample_comm_vi_get_default_pipe_info(struct_sns_type sns_type, ot_vi_bind_pipe *bind_pipe,
|
||||
struct_vi_pipe_info pipe_info[]);
|
||||
td_void sample_comm_vi_init_pipe_info(struct_sns_type sns_type, const ot_size *size, ot_vi_bind_pipe *bind_pipe,
|
||||
struct_vi_pipe_info pipe_info[]);
|
||||
|
||||
td_void sample_comm_vi_get_default_mipi_info(struct_sns_type sns_type, struct_mipi_info *mipi_info);
|
||||
td_void sample_comm_vi_get_default_dev_info(struct_sns_type sns_type, struct_vi_dev_info *dev_info);
|
||||
td_void sample_comm_vi_get_mipi_info_by_dev_id(struct_sns_type sns_type, ot_vi_dev vi_dev,
|
||||
struct_mipi_info *mipi_info);
|
||||
td_void sample_comm_venc_set_save_heif(td_bool save_heif);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* end of #ifdef __cplusplus */
|
||||
|
||||
#endif /* end of #ifndef __SAMPLE_COMMON_H__ */
|
1854
ss928sdk/common/sample_comm_audio.c
Executable file
518
ss928sdk/common/sample_comm_isp.c
Executable file
@ -0,0 +1,518 @@
|
||||
/*
|
||||
Copyright (c), 2001-2022, Shenshu Tech. Co., Ltd.
|
||||
*/
|
||||
|
||||
#ifndef __USE_GNU
|
||||
#define __USE_GNU
|
||||
#endif
|
||||
#define _GNU_SOURCE
|
||||
|
||||
#include <sched.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/poll.h>
|
||||
#ifdef __LITEOS__
|
||||
#include <sys/select.h>
|
||||
#endif
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <pthread.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/mman.h>
|
||||
#include <signal.h>
|
||||
#include <math.h>
|
||||
#include <poll.h>
|
||||
#include <sys/prctl.h>
|
||||
|
||||
#include "ss_mpi_awb.h"
|
||||
#include "ss_mpi_ae.h"
|
||||
#include "ot_sns_ctrl.h"
|
||||
#include "ss_mpi_isp.h"
|
||||
#include "ot_common_isp.h"
|
||||
#include "ot_common_video.h"
|
||||
#include "sample_comm.h"
|
||||
|
||||
static ot_isp_sns_type g_sns_type[OT_VI_MAX_PIPE_NUM] = {SNS_TYPE_BUTT};
|
||||
static pthread_t g_isp_pid[OT_VI_MAX_DEV_NUM] = {0};
|
||||
|
||||
extern ot_isp_sns_obj g_sns_os08a20_obj;
|
||||
extern ot_isp_sns_obj g_sns_os05a10_2l_slave_obj;
|
||||
extern ot_isp_sns_obj g_sns_imx347_slave_obj;
|
||||
extern ot_isp_sns_obj g_sns_imx485_obj;
|
||||
extern ot_isp_sns_obj g_sns_os04a10_obj;
|
||||
|
||||
/* IspPub attr */
|
||||
static ot_isp_pub_attr g_isp_pub_attr_os08a20_mipi_8m_30fps = {
|
||||
{0, 24, 3840, 2160},
|
||||
{3840, 2160},
|
||||
30,
|
||||
OT_ISP_BAYER_BGGR,
|
||||
OT_WDR_MODE_NONE,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
{
|
||||
0,
|
||||
{0, 0, 3840, 2180},
|
||||
},
|
||||
};
|
||||
|
||||
static ot_isp_pub_attr g_isp_pub_attr_os08a20_mipi_8m_30fps_wdr2to1 = {
|
||||
{0, 24, 3840, 2160},
|
||||
{3840, 2160},
|
||||
30,
|
||||
OT_ISP_BAYER_BGGR,
|
||||
OT_WDR_MODE_2To1_LINE,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
{
|
||||
0,
|
||||
{0, 0, 3840, 2180},
|
||||
},
|
||||
};
|
||||
|
||||
static ot_isp_pub_attr g_isp_pub_attr_os04a10_mipi_4m_30fps = {
|
||||
{0, 0, WIDTH_2688, HEIGHT_1520},
|
||||
{WIDTH_2688, HEIGHT_1520},
|
||||
30,
|
||||
OT_ISP_BAYER_RGGB,
|
||||
OT_WDR_MODE_NONE,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
{
|
||||
0,
|
||||
{0, 0, 2688, 1520},
|
||||
},
|
||||
};
|
||||
|
||||
static ot_isp_pub_attr g_isp_pub_attr_os08b10_mipi_8m_30fps_wdr2to1 = {
|
||||
{0, 0, 3840, 2160},
|
||||
{3840, 2160},
|
||||
30,
|
||||
OT_ISP_BAYER_RGGB,
|
||||
OT_WDR_MODE_2To1_LINE,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
{
|
||||
0,
|
||||
{0, 0, 3840, 2160},
|
||||
},
|
||||
};
|
||||
|
||||
static ot_isp_pub_attr g_isp_pub_attr_os08b10_mipi_8m_30fps = {
|
||||
{0, 0, 3840, 2160},
|
||||
{3840, 2160},
|
||||
30,
|
||||
OT_ISP_BAYER_RGGB,
|
||||
OT_WDR_MODE_NONE,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
{
|
||||
0,
|
||||
{0, 0, 3840, 2160},
|
||||
},
|
||||
};
|
||||
|
||||
static ot_isp_pub_attr g_isp_pub_attr_os05a10_2l_mipi_4m_30fps = {
|
||||
{0, 0, 2688, 1520},
|
||||
{2688, 1520},
|
||||
30,
|
||||
OT_ISP_BAYER_BGGR,
|
||||
OT_WDR_MODE_NONE,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
{
|
||||
0,
|
||||
{0, 0, 2688, 1520},
|
||||
},
|
||||
};
|
||||
|
||||
static ot_isp_pub_attr g_isp_pub_attr_imx347_slave_mipi_4m_30fps = {
|
||||
{0, 20, WIDTH_2592, HEIGHT_1520},
|
||||
{WIDTH_2592, HEIGHT_1520},
|
||||
30,
|
||||
OT_ISP_BAYER_RGGB,
|
||||
OT_WDR_MODE_NONE,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
{
|
||||
0,
|
||||
{0, 0, 2592, 1540},
|
||||
},
|
||||
};
|
||||
|
||||
static ot_isp_pub_attr g_isp_pub_attr_imx485_mipi_8m_30fps = {
|
||||
{0, 20, 3840, 2160},
|
||||
{3840, 2160},
|
||||
30,
|
||||
OT_ISP_BAYER_RGGB,
|
||||
OT_WDR_MODE_NONE,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
{
|
||||
0,
|
||||
{0, 0, 3840, 2180},
|
||||
},
|
||||
};
|
||||
|
||||
static ot_isp_pub_attr g_isp_pub_attr_imx485_mipi_8m_30fps_wdr3to1 = {
|
||||
{0, 0, 3840, 2160},
|
||||
{3840, 2160},
|
||||
30,
|
||||
OT_ISP_BAYER_RGGB,
|
||||
OT_WDR_MODE_3To1_LINE,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
{
|
||||
0,
|
||||
{0, 0, 3840, 2160},
|
||||
},
|
||||
};
|
||||
|
||||
td_s32 libapi_comm_isp_get_pub_attr_by_sns(struct_sns_type sns_type, ot_isp_pub_attr *pub_attr)
|
||||
{
|
||||
switch (sns_type) {
|
||||
case OV_OS08A20_MIPI_8M_30FPS_12BIT:
|
||||
(td_void)memcpy_s(pub_attr, sizeof(ot_isp_pub_attr),
|
||||
&g_isp_pub_attr_os08a20_mipi_8m_30fps, sizeof(ot_isp_pub_attr));
|
||||
break;
|
||||
|
||||
case OV_OS08A20_MIPI_8M_30FPS_12BIT_WDR2TO1:
|
||||
(td_void)memcpy_s(pub_attr, sizeof(ot_isp_pub_attr),
|
||||
&g_isp_pub_attr_os08a20_mipi_8m_30fps_wdr2to1, sizeof(ot_isp_pub_attr));
|
||||
break;
|
||||
|
||||
case OV_OS04A10_MIPI_4M_30FPS_12BIT:
|
||||
(td_void)memcpy_s(pub_attr, sizeof(ot_isp_pub_attr),
|
||||
&g_isp_pub_attr_os04a10_mipi_4m_30fps, sizeof(ot_isp_pub_attr));
|
||||
break;
|
||||
|
||||
case OV_OS08B10_MIPI_8M_30FPS_12BIT:
|
||||
(td_void)memcpy_s(pub_attr, sizeof(ot_isp_pub_attr),
|
||||
&g_isp_pub_attr_os08b10_mipi_8m_30fps, sizeof(ot_isp_pub_attr));
|
||||
break;
|
||||
|
||||
case OV_OS08B10_MIPI_8M_30FPS_12BIT_WDR2TO1:
|
||||
(td_void)memcpy_s(pub_attr, sizeof(ot_isp_pub_attr),
|
||||
&g_isp_pub_attr_os08b10_mipi_8m_30fps_wdr2to1, sizeof(ot_isp_pub_attr));
|
||||
break;
|
||||
|
||||
case OV_OS05A10_SLAVE_MIPI_4M_30FPS_12BIT:
|
||||
(td_void)memcpy_s(pub_attr, sizeof(ot_isp_pub_attr),
|
||||
&g_isp_pub_attr_os05a10_2l_mipi_4m_30fps, sizeof(ot_isp_pub_attr));
|
||||
break;
|
||||
|
||||
case SONY_IMX347_SLAVE_MIPI_4M_30FPS_12BIT:
|
||||
(td_void)memcpy_s(pub_attr, sizeof(ot_isp_pub_attr),
|
||||
&g_isp_pub_attr_imx347_slave_mipi_4m_30fps, sizeof(ot_isp_pub_attr));
|
||||
break;
|
||||
|
||||
case SONY_IMX485_MIPI_8M_30FPS_12BIT:
|
||||
(td_void)memcpy_s(pub_attr, sizeof(ot_isp_pub_attr),
|
||||
&g_isp_pub_attr_imx485_mipi_8m_30fps, sizeof(ot_isp_pub_attr));
|
||||
break;
|
||||
|
||||
case SONY_IMX485_MIPI_8M_30FPS_10BIT_WDR3TO1:
|
||||
(td_void)memcpy_s(pub_attr, sizeof(ot_isp_pub_attr),
|
||||
&g_isp_pub_attr_imx485_mipi_8m_30fps_wdr3to1, sizeof(ot_isp_pub_attr));
|
||||
break;
|
||||
|
||||
default:
|
||||
(td_void)memcpy_s(pub_attr, sizeof(ot_isp_pub_attr),
|
||||
&g_isp_pub_attr_os08a20_mipi_8m_30fps, sizeof(ot_isp_pub_attr));
|
||||
break;
|
||||
}
|
||||
|
||||
return TD_SUCCESS;
|
||||
}
|
||||
|
||||
ot_isp_sns_obj *sample_comm_isp_get_sns_obj(struct_sns_type sns_type)
|
||||
{
|
||||
switch (sns_type) {
|
||||
case OV_OS08A20_MIPI_8M_30FPS_12BIT:
|
||||
case OV_OS08A20_MIPI_8M_30FPS_12BIT_WDR2TO1:
|
||||
return &g_sns_os08a20_obj;
|
||||
case OV_OS04A10_MIPI_4M_30FPS_12BIT:
|
||||
return &g_sns_os04a10_obj;
|
||||
case OV_OS08B10_MIPI_8M_30FPS_12BIT:
|
||||
case OV_OS08B10_MIPI_8M_30FPS_12BIT_WDR2TO1:
|
||||
return &g_sns_os08b10_obj;
|
||||
case OV_OS05A10_SLAVE_MIPI_4M_30FPS_12BIT:
|
||||
return &g_sns_os05a10_2l_slave_obj;
|
||||
case SONY_IMX347_SLAVE_MIPI_4M_30FPS_12BIT:
|
||||
return &g_sns_imx347_slave_obj;
|
||||
case SONY_IMX485_MIPI_8M_30FPS_12BIT:
|
||||
case SONY_IMX485_MIPI_8M_30FPS_10BIT_WDR3TO1:
|
||||
return &g_sns_imx485_obj;
|
||||
default:
|
||||
return TD_NULL;
|
||||
}
|
||||
}
|
||||
|
||||
ot_isp_sns_type libapi_comm_get_sns_bus_type(struct_sns_type sns_type)
|
||||
{
|
||||
ot_unused(sns_type);
|
||||
return OT_ISP_SNS_I2C_TYPE;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* funciton : ISP init
|
||||
******************************************************************************/
|
||||
td_s32 libapi_comm_isp_sensor_regiter_callback(ot_isp_dev isp_dev, struct_sns_type sns_type)
|
||||
{
|
||||
td_s32 ret;
|
||||
ot_isp_3a_alg_lib ae_lib;
|
||||
ot_isp_3a_alg_lib awb_lib;
|
||||
ot_isp_sns_obj *sns_obj;
|
||||
|
||||
sns_obj = sample_comm_isp_get_sns_obj(sns_type);
|
||||
if (sns_obj == TD_NULL) {
|
||||
printf("sensor %d not exist!\n", sns_type);
|
||||
return TD_FAILURE;
|
||||
}
|
||||
|
||||
ae_lib.id = isp_dev;
|
||||
awb_lib.id = isp_dev;
|
||||
strncpy_s(ae_lib.lib_name, sizeof(ae_lib.lib_name), OT_AE_LIB_NAME, sizeof(OT_AE_LIB_NAME));
|
||||
strncpy_s(awb_lib.lib_name, sizeof(awb_lib.lib_name), OT_AWB_LIB_NAME, sizeof(OT_AWB_LIB_NAME));
|
||||
if (sns_obj->pfn_register_callback != TD_NULL) {
|
||||
ret = sns_obj->pfn_register_callback(isp_dev, &ae_lib, &awb_lib);
|
||||
if (ret != TD_SUCCESS) {
|
||||
printf("sensor_register_callback failed with %#x!\n", ret);
|
||||
return ret;
|
||||
}
|
||||
} else {
|
||||
printf("sensor_register_callback failed with TD_NULL!\n");
|
||||
}
|
||||
|
||||
g_sns_type[isp_dev] = sns_type;
|
||||
|
||||
return TD_SUCCESS;
|
||||
}
|
||||
|
||||
td_s32 libapi_comm_isp_sensor_unregiter_callback(ot_isp_dev isp_dev)
|
||||
{
|
||||
ot_isp_3a_alg_lib ae_lib;
|
||||
ot_isp_3a_alg_lib awb_lib;
|
||||
ot_isp_sns_obj *sns_obj;
|
||||
td_s32 ret;
|
||||
|
||||
sns_obj = sample_comm_isp_get_sns_obj(g_sns_type[isp_dev]);
|
||||
if (sns_obj == TD_NULL) {
|
||||
printf("sensor %d not exist!\n", g_sns_type[isp_dev]);
|
||||
return TD_FAILURE;
|
||||
}
|
||||
|
||||
ae_lib.id = isp_dev;
|
||||
awb_lib.id = isp_dev;
|
||||
strncpy_s(ae_lib.lib_name, sizeof(ae_lib.lib_name), OT_AE_LIB_NAME, sizeof(OT_AE_LIB_NAME));
|
||||
strncpy_s(awb_lib.lib_name, sizeof(awb_lib.lib_name), OT_AWB_LIB_NAME, sizeof(OT_AWB_LIB_NAME));
|
||||
if (sns_obj->pfn_un_register_callback != TD_NULL) {
|
||||
ret = sns_obj->pfn_un_register_callback(isp_dev, &ae_lib, &awb_lib);
|
||||
if (ret != TD_SUCCESS) {
|
||||
printf("sensor_unregister_callback failed with %#x!\n", ret);
|
||||
return ret;
|
||||
}
|
||||
} else {
|
||||
printf("sensor_unregister_callback failed with TD_NULL!\n");
|
||||
}
|
||||
|
||||
g_sns_type[isp_dev] = SNS_TYPE_BUTT;
|
||||
|
||||
return TD_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
td_s32 libapi_comm_isp_bind_sns(ot_isp_dev isp_dev, struct_sns_type sns_type, td_s8 sns_dev)
|
||||
{
|
||||
ot_isp_sns_commbus sns_bus_info;
|
||||
ot_isp_sns_type bus_type;
|
||||
ot_isp_sns_obj *sns_obj;
|
||||
td_s32 ret;
|
||||
|
||||
sns_obj = sample_comm_isp_get_sns_obj(sns_type);
|
||||
if (sns_obj == TD_NULL) {
|
||||
printf("sensor %d not exist!\n", sns_type);
|
||||
return TD_FAILURE;
|
||||
}
|
||||
|
||||
bus_type = libapi_comm_get_sns_bus_type(sns_type);
|
||||
if (bus_type == OT_ISP_SNS_I2C_TYPE) {
|
||||
sns_bus_info.i2c_dev = sns_dev;
|
||||
} else {
|
||||
sns_bus_info.ssp_dev.bit4_ssp_dev = sns_dev;
|
||||
sns_bus_info.ssp_dev.bit4_ssp_cs = 0;
|
||||
}
|
||||
|
||||
if (sns_obj->pfn_set_bus_info != TD_NULL) {
|
||||
ret = sns_obj->pfn_set_bus_info(isp_dev, sns_bus_info);
|
||||
if (ret != TD_SUCCESS) {
|
||||
printf("set sensor bus info failed with %#x!\n", ret);
|
||||
return ret;
|
||||
}
|
||||
} else {
|
||||
printf("not support set sensor bus info!\n");
|
||||
return TD_FAILURE;
|
||||
}
|
||||
|
||||
return TD_SUCCESS;
|
||||
}
|
||||
|
||||
td_s32 libapi_comm_isp_ae_lib_callback(ot_isp_dev isp_dev)
|
||||
{
|
||||
td_s32 ret;
|
||||
ot_isp_3a_alg_lib ae_lib;
|
||||
|
||||
ae_lib.id = isp_dev;
|
||||
strncpy_s(ae_lib.lib_name, sizeof(ae_lib.lib_name), OT_AE_LIB_NAME, sizeof(OT_AE_LIB_NAME));
|
||||
|
||||
ret = ss_mpi_ae_register(isp_dev, &ae_lib);
|
||||
if (ret != TD_SUCCESS) {
|
||||
printf("ss_mpi_ae_register failed with %#x!\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return TD_SUCCESS;
|
||||
}
|
||||
|
||||
td_s32 libapi_comm_isp_ae_lib_uncallback(ot_isp_dev isp_dev)
|
||||
{
|
||||
td_s32 ret;
|
||||
ot_isp_3a_alg_lib ae_lib;
|
||||
|
||||
ae_lib.id = isp_dev;
|
||||
strncpy_s(ae_lib.lib_name, sizeof(ae_lib.lib_name), OT_AE_LIB_NAME, sizeof(OT_AE_LIB_NAME));
|
||||
|
||||
ret = ss_mpi_ae_unregister(isp_dev, &ae_lib);
|
||||
if (ret != TD_SUCCESS) {
|
||||
printf("ss_mpi_ae_unregister failed with %#x!\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return TD_SUCCESS;
|
||||
}
|
||||
|
||||
td_s32 libapi_comm_isp_awb_lib_callback(ot_isp_dev isp_dev)
|
||||
{
|
||||
td_s32 ret;
|
||||
ot_isp_3a_alg_lib awb_lib;
|
||||
|
||||
awb_lib.id = isp_dev;
|
||||
strncpy_s(awb_lib.lib_name, sizeof(awb_lib.lib_name), OT_AWB_LIB_NAME, sizeof(OT_AWB_LIB_NAME));
|
||||
|
||||
ret = ss_mpi_awb_register(isp_dev, &awb_lib);
|
||||
if (ret != TD_SUCCESS) {
|
||||
printf("ss_mpi_awb_register failed with %#x!\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return TD_SUCCESS;
|
||||
}
|
||||
|
||||
td_s32 libapi_comm_isp_awb_lib_uncallback(ot_isp_dev isp_dev)
|
||||
{
|
||||
td_s32 ret;
|
||||
ot_isp_3a_alg_lib awb_lib;
|
||||
|
||||
awb_lib.id = isp_dev;
|
||||
strncpy_s(awb_lib.lib_name, sizeof(awb_lib.lib_name), OT_AWB_LIB_NAME, sizeof(OT_AWB_LIB_NAME));
|
||||
ret = ss_mpi_awb_unregister(isp_dev, &awb_lib);
|
||||
if (ret != TD_SUCCESS) {
|
||||
printf("ss_mpi_awb_unregister failed with %#x!\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return TD_SUCCESS;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* funciton : ISP Run
|
||||
******************************************************************************/
|
||||
static void *sample_comm_isp_thread(td_void *param)
|
||||
{
|
||||
td_s32 ret;
|
||||
ot_isp_dev isp_dev;
|
||||
td_char thread_name[20];
|
||||
isp_dev = (ot_isp_dev)(td_ulong)param;
|
||||
errno_t err;
|
||||
|
||||
err = snprintf_s(thread_name, sizeof(thread_name)*20, 19, "ISP%d_RUN", isp_dev); /* 20,19 chars */
|
||||
if (err < 0) {
|
||||
return NULL;
|
||||
}
|
||||
prctl(PR_SET_NAME, thread_name, 0, 0, 0);
|
||||
|
||||
printf("ISP Dev %d running !\n", isp_dev);
|
||||
ret = ss_mpi_isp_run(isp_dev);
|
||||
if (ret != TD_SUCCESS) {
|
||||
printf("OT_MPI_ISP_Run failed with %#x!\n", ret);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
td_s32 libapi_comm_isp_sensor_founction_cfg(ot_vi_pipe vi_pipe, struct_sns_type sns_type)
|
||||
{
|
||||
ot_isp_sns_blc_clamp sns_blc_clamp;
|
||||
|
||||
sns_blc_clamp.blc_clamp_en = TD_FALSE;
|
||||
|
||||
switch (sns_type) {
|
||||
case SONY_IMX485_MIPI_8M_30FPS_12BIT:
|
||||
g_sns_imx485_obj.pfn_set_blc_clamp(vi_pipe, sns_blc_clamp);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return TD_SUCCESS;
|
||||
}
|
||||
|
||||
td_s32 libapi_comm_isp_run(ot_isp_dev isp_dev)
|
||||
{
|
||||
td_s32 ret;
|
||||
pthread_attr_t *thread_attr = NULL;
|
||||
|
||||
ret = pthread_create(&g_isp_pid[isp_dev], thread_attr, sample_comm_isp_thread, (td_void*)(td_ulong)isp_dev);
|
||||
if (ret != 0) {
|
||||
printf("create isp running thread failed!, error: %d\r\n", ret);
|
||||
}
|
||||
|
||||
if (thread_attr != TD_NULL) {
|
||||
pthread_attr_destroy(thread_attr);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
td_void libapi_comm_isp_stop(ot_isp_dev isp_dev)
|
||||
{
|
||||
if (g_isp_pid[isp_dev]) {
|
||||
pthread_join(g_isp_pid[isp_dev], NULL);
|
||||
g_isp_pid[isp_dev] = 0;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
td_void libapi_comm_all_isp_stop(td_void)
|
||||
{
|
||||
ot_isp_dev isp_dev;
|
||||
|
||||
for (isp_dev = 0; isp_dev < OT_VI_MAX_PIPE_NUM; isp_dev++) {
|
||||
libapi_comm_isp_stop(isp_dev);
|
||||
}
|
||||
}
|
596
ss928sdk/common/sample_comm_mipi_tx.c
Executable file
@ -0,0 +1,596 @@
|
||||
/*
|
||||
Copyright (c), 2001-2022, Shenshu Tech. Co., Ltd.
|
||||
*/
|
||||
|
||||
#include <sys/ioctl.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include "sample_comm.h"
|
||||
#include "ot_mipi_tx.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#endif /* end of #ifdef __cplusplus */
|
||||
|
||||
#if VO_MIPI_SUPPORT
|
||||
|
||||
#ifdef OT_FPGA
|
||||
#define SAMPLE_COMM_MIPI_TX_MAX_PHY_DATA_RATE 594
|
||||
#else
|
||||
#define SAMPLE_COMM_MIPI_TX_MAX_PHY_DATA_RATE 945
|
||||
#endif
|
||||
|
||||
static td_s32 g_sample_comm_mipi_fd = OT_INVALID_VALUE;
|
||||
|
||||
static const combo_dev_cfg_t g_sample_comm_mipi_tx_720x576_50_config = {
|
||||
.devno = 0,
|
||||
.lane_id = {0, 1, 2, 3},
|
||||
.out_mode = OUT_MODE_DSI_VIDEO,
|
||||
.out_format = OUT_FORMAT_RGB_24BIT,
|
||||
.video_mode = BURST_MODE,
|
||||
.sync_info = {
|
||||
.hsa_pixels = 64,
|
||||
.hbp_pixels = 68,
|
||||
.hact_pixels = 720,
|
||||
.hfp_pixels = 12,
|
||||
.vsa_lines = 5,
|
||||
.vbp_lines = 39,
|
||||
.vact_lines = 576,
|
||||
.vfp_lines = 5,
|
||||
},
|
||||
.phy_data_rate = 162,
|
||||
.pixel_clk = 27000,
|
||||
};
|
||||
|
||||
static const combo_dev_cfg_t g_sample_comm_mipi_tx_1024x768_60_config = {
|
||||
.devno = 0,
|
||||
.lane_id = {0, 1, 2, 3},
|
||||
.out_mode = OUT_MODE_DSI_VIDEO,
|
||||
.out_format = OUT_FORMAT_RGB_24BIT,
|
||||
.video_mode = BURST_MODE,
|
||||
.sync_info = {
|
||||
.hsa_pixels = 136,
|
||||
.hbp_pixels = 160,
|
||||
.hact_pixels = 1024,
|
||||
.hfp_pixels = 24,
|
||||
.vsa_lines = 6,
|
||||
.vbp_lines = 29,
|
||||
.vact_lines = 768,
|
||||
.vfp_lines = 3,
|
||||
},
|
||||
.phy_data_rate = 390,
|
||||
.pixel_clk = 65000,
|
||||
};
|
||||
|
||||
static const combo_dev_cfg_t g_sample_comm_mipi_tx_1280x720_50_config = {
|
||||
.devno = 0,
|
||||
.lane_id = {0, 1, 2, 3},
|
||||
.out_mode = OUT_MODE_DSI_VIDEO,
|
||||
.out_format = OUT_FORMAT_RGB_24BIT,
|
||||
.video_mode = BURST_MODE,
|
||||
.sync_info = {
|
||||
.hsa_pixels = 40,
|
||||
.hbp_pixels = 220,
|
||||
.hact_pixels = 1280,
|
||||
.hfp_pixels = 440,
|
||||
.vsa_lines = 5,
|
||||
.vbp_lines = 20,
|
||||
.vact_lines = 720,
|
||||
.vfp_lines = 5,
|
||||
},
|
||||
.phy_data_rate = 446,
|
||||
.pixel_clk = 74250,
|
||||
};
|
||||
|
||||
static const combo_dev_cfg_t g_sample_comm_mipi_tx_1280x720_60_config = {
|
||||
.devno = 0,
|
||||
.lane_id = {0, 1, 2, 3},
|
||||
.out_mode = OUT_MODE_DSI_VIDEO,
|
||||
.out_format = OUT_FORMAT_RGB_24BIT,
|
||||
.video_mode = BURST_MODE,
|
||||
.sync_info = {
|
||||
.hsa_pixels = 40,
|
||||
.hbp_pixels = 220,
|
||||
.hact_pixels = 1280,
|
||||
.hfp_pixels = 110,
|
||||
.vsa_lines = 5,
|
||||
.vbp_lines = 20,
|
||||
.vact_lines = 720,
|
||||
.vfp_lines = 5,
|
||||
},
|
||||
.phy_data_rate = 446,
|
||||
.pixel_clk = 74250,
|
||||
};
|
||||
|
||||
static const combo_dev_cfg_t g_sample_comm_mipi_tx_1280x1024_60_config = {
|
||||
.devno = 0,
|
||||
.lane_id = {0, 1, 2, 3},
|
||||
.out_mode = OUT_MODE_DSI_VIDEO,
|
||||
.out_format = OUT_FORMAT_RGB_24BIT,
|
||||
.video_mode = BURST_MODE,
|
||||
.sync_info = {
|
||||
.hsa_pixels = 112,
|
||||
.hbp_pixels = 248,
|
||||
.hact_pixels = 1280,
|
||||
.hfp_pixels = 48,
|
||||
.vsa_lines = 3,
|
||||
.vbp_lines = 38,
|
||||
.vact_lines = 1024,
|
||||
.vfp_lines = 1,
|
||||
},
|
||||
.phy_data_rate = 648, /* 486 */
|
||||
.pixel_clk = 108000,
|
||||
};
|
||||
|
||||
static const combo_dev_cfg_t g_sample_comm_mipi_tx_1920x1080_24_config = {
|
||||
.devno = 0,
|
||||
.lane_id = {0, 1, 2, 3},
|
||||
.out_mode = OUT_MODE_DSI_VIDEO,
|
||||
.out_format = OUT_FORMAT_RGB_24BIT,
|
||||
.video_mode = BURST_MODE,
|
||||
.sync_info = {
|
||||
.hsa_pixels = 44,
|
||||
.hbp_pixels = 148,
|
||||
.hact_pixels = 1920,
|
||||
.hfp_pixels = 638,
|
||||
.vsa_lines = 5,
|
||||
.vbp_lines = 36,
|
||||
.vact_lines = 1080,
|
||||
.vfp_lines = 4,
|
||||
},
|
||||
.phy_data_rate = 446,
|
||||
.pixel_clk = 74250,
|
||||
};
|
||||
|
||||
static const combo_dev_cfg_t g_sample_comm_mipi_tx_1920x1080_25_config = {
|
||||
.devno = 0,
|
||||
.lane_id = {0, 1, 2, 3},
|
||||
.out_mode = OUT_MODE_DSI_VIDEO,
|
||||
.out_format = OUT_FORMAT_RGB_24BIT,
|
||||
.video_mode = BURST_MODE,
|
||||
.sync_info = {
|
||||
.hsa_pixels = 44,
|
||||
.hbp_pixels = 148,
|
||||
.hact_pixels = 1920,
|
||||
.hfp_pixels = 528,
|
||||
.vsa_lines = 5,
|
||||
.vbp_lines = 36,
|
||||
.vact_lines = 1080,
|
||||
.vfp_lines = 4,
|
||||
},
|
||||
.phy_data_rate = 446,
|
||||
.pixel_clk = 74250,
|
||||
};
|
||||
|
||||
static const combo_dev_cfg_t g_sample_comm_mipi_tx_1920x1080_30_config = {
|
||||
.devno = 0,
|
||||
.lane_id = {0, 1, 2, 3},
|
||||
.out_mode = OUT_MODE_DSI_VIDEO,
|
||||
.out_format = OUT_FORMAT_RGB_24BIT,
|
||||
.video_mode = BURST_MODE,
|
||||
.sync_info = {
|
||||
.hsa_pixels = 44,
|
||||
.hbp_pixels = 148,
|
||||
.hact_pixels = 1920,
|
||||
.hfp_pixels = 88,
|
||||
.vsa_lines = 5,
|
||||
.vbp_lines = 36,
|
||||
.vact_lines = 1080,
|
||||
.vfp_lines = 4,
|
||||
},
|
||||
.phy_data_rate = 446,
|
||||
.pixel_clk = 74250,
|
||||
};
|
||||
|
||||
static const combo_dev_cfg_t g_sample_comm_mipi_tx_1920x1080_50_config = {
|
||||
.devno = 0,
|
||||
.lane_id = {0, 1, 2, 3},
|
||||
.out_mode = OUT_MODE_DSI_VIDEO,
|
||||
.out_format = OUT_FORMAT_RGB_24BIT,
|
||||
.video_mode = BURST_MODE,
|
||||
.sync_info = {
|
||||
.hsa_pixels = 44,
|
||||
.hbp_pixels = 148,
|
||||
.hact_pixels = 1920,
|
||||
.hfp_pixels = 528,
|
||||
.vsa_lines = 5,
|
||||
.vbp_lines = 36,
|
||||
.vact_lines = 1080,
|
||||
.vfp_lines = 4,
|
||||
},
|
||||
.phy_data_rate = 891,
|
||||
.pixel_clk = 148500,
|
||||
};
|
||||
|
||||
static const combo_dev_cfg_t g_sample_comm_mipi_tx_1920x1080_60_config = {
|
||||
.devno = 0,
|
||||
.lane_id = {0, 1, 2, 3},
|
||||
.out_mode = OUT_MODE_DSI_VIDEO,
|
||||
.out_format = OUT_FORMAT_RGB_24BIT,
|
||||
.video_mode = BURST_MODE,
|
||||
.sync_info = {
|
||||
.hsa_pixels = 44,
|
||||
.hbp_pixels = 148,
|
||||
.hact_pixels = 1920,
|
||||
.hfp_pixels = 88,
|
||||
.vsa_lines = 5,
|
||||
.vbp_lines = 36,
|
||||
.vact_lines = 1080,
|
||||
.vfp_lines = 4,
|
||||
},
|
||||
.phy_data_rate = 891,
|
||||
.pixel_clk = 148500,
|
||||
};
|
||||
|
||||
static const combo_dev_cfg_t g_sample_comm_mipi_tx_3840x2160_24_config = {
|
||||
.devno = 0,
|
||||
.lane_id = {0, 1, 2, 3},
|
||||
.out_mode = OUT_MODE_DSI_VIDEO,
|
||||
.out_format = OUT_FORMAT_RGB_24BIT,
|
||||
.video_mode = BURST_MODE,
|
||||
.sync_info = {
|
||||
.hsa_pixels = 88,
|
||||
.hbp_pixels = 296,
|
||||
.hact_pixels = 3840,
|
||||
.hfp_pixels = 1276,
|
||||
.vsa_lines = 10,
|
||||
.vbp_lines = 72,
|
||||
.vact_lines = 2160,
|
||||
.vfp_lines = 8,
|
||||
},
|
||||
.phy_data_rate = 1782,
|
||||
.pixel_clk = 297000,
|
||||
};
|
||||
|
||||
static const combo_dev_cfg_t g_sample_comm_mipi_tx_3840x2160_25_config = {
|
||||
.devno = 0,
|
||||
.lane_id = {0, 1, 2, 3},
|
||||
.out_mode = OUT_MODE_DSI_VIDEO,
|
||||
.out_format = OUT_FORMAT_RGB_24BIT,
|
||||
.video_mode = BURST_MODE,
|
||||
.sync_info = {
|
||||
.hsa_pixels = 88,
|
||||
.hbp_pixels = 296,
|
||||
.hact_pixels = 3840,
|
||||
.hfp_pixels = 1056,
|
||||
.vsa_lines = 10,
|
||||
.vbp_lines = 72,
|
||||
.vact_lines = 2160,
|
||||
.vfp_lines = 8,
|
||||
},
|
||||
.phy_data_rate = 1782,
|
||||
.pixel_clk = 297000,
|
||||
};
|
||||
|
||||
static const combo_dev_cfg_t g_sample_comm_mipi_tx_3840x2160_30_config = {
|
||||
.devno = 0,
|
||||
.lane_id = {0, 1, 2, 3},
|
||||
.out_mode = OUT_MODE_DSI_VIDEO,
|
||||
.out_format = OUT_FORMAT_RGB_24BIT,
|
||||
.video_mode = BURST_MODE,
|
||||
.sync_info = {
|
||||
.hsa_pixels = 88,
|
||||
.hbp_pixels = 296,
|
||||
.hact_pixels = 3840,
|
||||
.hfp_pixels = 176,
|
||||
.vsa_lines = 10,
|
||||
.vbp_lines = 72,
|
||||
.vact_lines = 2160,
|
||||
.vfp_lines = 8,
|
||||
},
|
||||
.phy_data_rate = 1782, /* lt9611's max data rate < 2000Mbps */
|
||||
.pixel_clk = 297000,
|
||||
};
|
||||
|
||||
static const combo_dev_cfg_t g_sample_comm_mipi_tx_3840x2160_50_config = {
|
||||
.devno = 0,
|
||||
.lane_id = {0, 1, 2, 3},
|
||||
.out_mode = OUT_MODE_CSI,
|
||||
.out_format = OUT_FORMAT_RAW_16BIT,
|
||||
.video_mode = BURST_MODE,
|
||||
.sync_info = {
|
||||
.hsa_pixels = 88,
|
||||
.hbp_pixels = 296,
|
||||
.hact_pixels = 3840,
|
||||
.hfp_pixels = 1056,
|
||||
.vsa_lines = 10,
|
||||
.vbp_lines = 72,
|
||||
.vact_lines = 2160,
|
||||
.vfp_lines = 8,
|
||||
},
|
||||
.phy_data_rate = 2259, /* 2376 is larger than the max 2259, set to 2259 */
|
||||
.pixel_clk = 594000,
|
||||
};
|
||||
|
||||
static const combo_dev_cfg_t g_sample_comm_mipi_tx_3840x2160_60_config = {
|
||||
.devno = 0,
|
||||
.lane_id = {0, 1, 2, 3},
|
||||
.out_mode = OUT_MODE_CSI,
|
||||
.out_format = OUT_FORMAT_RAW_16BIT,
|
||||
.video_mode = BURST_MODE,
|
||||
.sync_info = {
|
||||
.hsa_pixels = 88,
|
||||
.hbp_pixels = 296,
|
||||
.hact_pixels = 3840,
|
||||
.hfp_pixels = 176,
|
||||
.vsa_lines = 10,
|
||||
.vbp_lines = 72,
|
||||
.vact_lines = 2160,
|
||||
.vfp_lines = 8,
|
||||
},
|
||||
.phy_data_rate = 2259, /* 2376 is larger than the max 2259, set to 2259 */
|
||||
.pixel_clk = 594000,
|
||||
};
|
||||
|
||||
static const combo_dev_cfg_t g_sample_comm_mipi_tx_720x1280_60_config = {
|
||||
.devno = 0,
|
||||
.lane_id = {0, 1, 2, 3},
|
||||
.out_mode = OUT_MODE_DSI_VIDEO,
|
||||
.out_format = OUT_FORMAT_RGB_24BIT,
|
||||
.video_mode = BURST_MODE,
|
||||
.sync_info = {
|
||||
.hsa_pixels = 24,
|
||||
.hbp_pixels = 99,
|
||||
.hact_pixels = 720,
|
||||
.hfp_pixels = 99,
|
||||
.vsa_lines = 4,
|
||||
.vbp_lines = 20,
|
||||
.vact_lines = 1280,
|
||||
.vfp_lines = 8,
|
||||
},
|
||||
.phy_data_rate = 459,
|
||||
.pixel_clk = 74250,
|
||||
};
|
||||
|
||||
static const combo_dev_cfg_t g_sample_comm_mipi_tx_1080x1920_60_config = {
|
||||
.devno = 0,
|
||||
.lane_id = {0, 1, 2, 3},
|
||||
.out_mode = OUT_MODE_DSI_VIDEO,
|
||||
.out_format = OUT_FORMAT_RGB_24BIT,
|
||||
.video_mode = BURST_MODE,
|
||||
.sync_info = {
|
||||
.hsa_pixels = 8,
|
||||
.hbp_pixels = 20,
|
||||
.hact_pixels = 1080,
|
||||
.hfp_pixels = 130,
|
||||
.vsa_lines = 10,
|
||||
.vbp_lines = 26,
|
||||
.vact_lines = 1920,
|
||||
.vfp_lines = 16,
|
||||
},
|
||||
.phy_data_rate = 891,
|
||||
.pixel_clk = 148500,
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
enum_mipi_tx_intf_sync index;
|
||||
const combo_dev_cfg_t *mipi_tx_combo_dev_cfg;
|
||||
} mipi_tx_intf_sync_cfg;
|
||||
|
||||
typedef struct {
|
||||
ot_vo_intf_sync intf_sync;
|
||||
enum_mipi_tx_intf_sync mipi_tx_sync;
|
||||
td_char *mipi_fmt_name;
|
||||
} vo_mst_sync_mipi_tx;
|
||||
|
||||
static const mipi_tx_intf_sync_cfg g_sample_mipi_tx_timing[OT_MIPI_TX_OUT_USER] = {
|
||||
{OT_MIPI_TX_OUT_576P50, &g_sample_comm_mipi_tx_720x576_50_config},
|
||||
{OT_MIPI_TX_OUT_1024X768_60, &g_sample_comm_mipi_tx_1024x768_60_config},
|
||||
{OT_MIPI_TX_OUT_720P50, &g_sample_comm_mipi_tx_1280x720_50_config},
|
||||
{OT_MIPI_TX_OUT_720P60, &g_sample_comm_mipi_tx_1280x720_60_config},
|
||||
{OT_MIPI_TX_OUT_1280X1024_60, &g_sample_comm_mipi_tx_1280x1024_60_config},
|
||||
{OT_MIPI_TX_OUT_1080P24, &g_sample_comm_mipi_tx_1920x1080_24_config},
|
||||
{OT_MIPI_TX_OUT_1080P25, &g_sample_comm_mipi_tx_1920x1080_25_config},
|
||||
{OT_MIPI_TX_OUT_1080P30, &g_sample_comm_mipi_tx_1920x1080_30_config},
|
||||
{OT_MIPI_TX_OUT_1080P50, &g_sample_comm_mipi_tx_1920x1080_50_config},
|
||||
{OT_MIPI_TX_OUT_1080P60, &g_sample_comm_mipi_tx_1920x1080_60_config},
|
||||
{OT_MIPI_TX_OUT_3840X2160_24, &g_sample_comm_mipi_tx_3840x2160_24_config},
|
||||
{OT_MIPI_TX_OUT_3840X2160_25, &g_sample_comm_mipi_tx_3840x2160_25_config},
|
||||
{OT_MIPI_TX_OUT_3840X2160_30, &g_sample_comm_mipi_tx_3840x2160_30_config},
|
||||
{OT_MIPI_TX_OUT_3840X2160_50, &g_sample_comm_mipi_tx_3840x2160_50_config},
|
||||
{OT_MIPI_TX_OUT_3840X2160_60, &g_sample_comm_mipi_tx_3840x2160_60_config},
|
||||
|
||||
{OT_MIPI_TX_OUT_720X1280_60, &g_sample_comm_mipi_tx_720x1280_60_config},
|
||||
{OT_MIPI_TX_OUT_1080X1920_60, &g_sample_comm_mipi_tx_1080x1920_60_config},
|
||||
{0},
|
||||
};
|
||||
|
||||
static const combo_dev_cfg_t *sample_mipi_tx_get_combo_dev_config(enum_mipi_tx_intf_sync mipi_intf_sync)
|
||||
{
|
||||
td_u32 loop;
|
||||
td_u32 loop_num = sizeof(g_sample_mipi_tx_timing) / sizeof(mipi_tx_intf_sync_cfg);
|
||||
|
||||
for (loop = 0; loop < loop_num; loop++) {
|
||||
if (g_sample_mipi_tx_timing[loop].index == mipi_intf_sync) {
|
||||
return g_sample_mipi_tx_timing[loop].mipi_tx_combo_dev_cfg;
|
||||
}
|
||||
}
|
||||
return TD_NULL;
|
||||
}
|
||||
|
||||
static td_s32 vo_mst_mipi_tx_send_one_cmd(cmd_info_t *cmd_info)
|
||||
{
|
||||
td_s32 ret;
|
||||
ret = ioctl(g_sample_comm_mipi_fd, OT_MIPI_TX_SET_CMD, cmd_info);
|
||||
if (ret != TD_SUCCESS) {
|
||||
printf("MIPI_TX SET CMD failed\n");
|
||||
return TD_FAILURE;
|
||||
}
|
||||
|
||||
return TD_SUCCESS;
|
||||
}
|
||||
|
||||
static td_s32 vo_mst_mipi_tx_init_screen(const struct_mipi_tx_config *tx_config)
|
||||
{
|
||||
td_s32 ret;
|
||||
cmd_info_t ci = { 0 };
|
||||
td_u32 loop;
|
||||
td_u32 loop_num = tx_config->cmd_count;
|
||||
|
||||
for (loop = 0; loop < loop_num; loop++) {
|
||||
(td_void)memcpy_s(&ci, sizeof(cmd_info_t), &(tx_config->cmd_info[loop].cmd_info), sizeof(cmd_info_t));
|
||||
ret = vo_mst_mipi_tx_send_one_cmd(&ci);
|
||||
if (ret != TD_SUCCESS) {
|
||||
printf("loop(%d): MIPI_TX SET CMD failed\n", loop);
|
||||
|
||||
return TD_FAILURE;
|
||||
}
|
||||
usleep(tx_config->cmd_info[loop].usleep_value);
|
||||
}
|
||||
|
||||
return TD_SUCCESS;
|
||||
}
|
||||
|
||||
static td_s32 sample_comm_mipi_tx_check_config(const struct_mipi_tx_config *tx_config)
|
||||
{
|
||||
enum_mipi_tx_intf_sync mipi_intf_sync;
|
||||
|
||||
if (tx_config == NULL) {
|
||||
sample_print("tx_config is null\n");
|
||||
return TD_FAILURE;
|
||||
}
|
||||
|
||||
mipi_intf_sync = tx_config->intf_sync;
|
||||
if ((mipi_intf_sync >= OT_MIPI_TX_OUT_BUTT)) {
|
||||
sample_print("mipi tx sync illegal\n");
|
||||
return TD_FAILURE;
|
||||
}
|
||||
return TD_SUCCESS;
|
||||
}
|
||||
|
||||
static td_s32 sample_comm_mipi_tx_get_config(const struct_mipi_tx_config *tx_config,
|
||||
const combo_dev_cfg_t **mipi_tx_config)
|
||||
{
|
||||
enum_mipi_tx_intf_sync mipi_intf_sync;
|
||||
mipi_intf_sync = tx_config->intf_sync;
|
||||
|
||||
if (mipi_intf_sync == OT_MIPI_TX_OUT_USER) {
|
||||
*mipi_tx_config = &tx_config->combo_dev_cfg;
|
||||
if ((*mipi_tx_config)->phy_data_rate == 0) {
|
||||
printf("error: not set mipi tx user config\n");
|
||||
return TD_FAILURE;
|
||||
}
|
||||
} else {
|
||||
*mipi_tx_config = sample_mipi_tx_get_combo_dev_config(mipi_intf_sync);
|
||||
if (*mipi_tx_config == TD_NULL) {
|
||||
sample_print("error: mipi tx combo config is null\n");
|
||||
return TD_FAILURE;
|
||||
}
|
||||
}
|
||||
return TD_SUCCESS;
|
||||
}
|
||||
|
||||
static td_void sample_comm_mipi_tx_do_close_fd(td_void)
|
||||
{
|
||||
if (g_sample_comm_mipi_fd != OT_INVALID_VALUE) {
|
||||
close(g_sample_comm_mipi_fd);
|
||||
g_sample_comm_mipi_fd = OT_INVALID_VALUE;
|
||||
}
|
||||
}
|
||||
|
||||
td_s32 libapi_comm_start_mipi_tx(const struct_mipi_tx_config *tx_config)
|
||||
{
|
||||
enum_mipi_tx_intf_sync mipi_intf_sync;
|
||||
const combo_dev_cfg_t *combo_config = TD_NULL;
|
||||
td_s32 ret;
|
||||
|
||||
ret = sample_comm_mipi_tx_check_config(tx_config);
|
||||
if (ret != TD_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
g_sample_comm_mipi_fd = open(MIPI_TX_DEV_NAME, O_RDONLY);
|
||||
if (g_sample_comm_mipi_fd < 0) {
|
||||
printf("open mipi dev file (%s) fail\n", MIPI_TX_DEV_NAME);
|
||||
return TD_FAILURE;
|
||||
}
|
||||
|
||||
mipi_intf_sync = tx_config->intf_sync;
|
||||
printf("mipi intf sync = %d\n", mipi_intf_sync);
|
||||
|
||||
ret = sample_comm_mipi_tx_get_config(tx_config, &combo_config);
|
||||
if (ret != TD_SUCCESS) {
|
||||
printf("%s,%d, get mipi tx config fail\n", __FUNCTION__, __LINE__);
|
||||
sample_comm_mipi_tx_do_close_fd();
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* step1 */
|
||||
ret = ioctl(g_sample_comm_mipi_fd, OT_MIPI_TX_DISABLE, NULL);
|
||||
if (ret != TD_SUCCESS) {
|
||||
printf("%s,%d, ioctl mipi tx (%s) fail at ret(%d)\n", __FUNCTION__, __LINE__, MIPI_TX_DEV_NAME, ret);
|
||||
sample_comm_mipi_tx_do_close_fd();
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* step2 */
|
||||
ret = ioctl(g_sample_comm_mipi_fd, OT_MIPI_TX_SET_DEV_CFG, combo_config);
|
||||
if (ret != TD_SUCCESS) {
|
||||
printf("%s,%d, ioctl mipi tx (%s) fail at ret(%d)\n", __FUNCTION__, __LINE__, MIPI_TX_DEV_NAME, ret);
|
||||
sample_comm_mipi_tx_do_close_fd();
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* step3 */
|
||||
ret = vo_mst_mipi_tx_init_screen(tx_config);
|
||||
if (ret != TD_SUCCESS) {
|
||||
printf("%s,%d, init screen failed\n", __FUNCTION__, __LINE__);
|
||||
sample_comm_mipi_tx_do_close_fd();
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* step4 */
|
||||
ret = ioctl(g_sample_comm_mipi_fd, OT_MIPI_TX_ENABLE, NULL);
|
||||
if (ret != TD_SUCCESS) {
|
||||
printf("%s,%d, ioctl mipi tx (%s) fail at ret(%d)\n", __FUNCTION__, __LINE__, MIPI_TX_DEV_NAME, ret);
|
||||
}
|
||||
|
||||
sample_comm_mipi_tx_do_close_fd();
|
||||
return ret;
|
||||
}
|
||||
|
||||
td_void libapi_comm_stop_mipi_tx(ot_vo_intf_type intf_type)
|
||||
{
|
||||
if (!((intf_type & OT_VO_INTF_MIPI) ||
|
||||
(intf_type & OT_VO_INTF_MIPI_SLAVE))) {
|
||||
sample_print("intf is not mipi\n");
|
||||
return;
|
||||
}
|
||||
|
||||
g_sample_comm_mipi_fd = open(MIPI_TX_DEV_NAME, O_RDONLY);
|
||||
if (g_sample_comm_mipi_fd < 0) {
|
||||
printf("open mipi dev file (%s) fail\n", MIPI_TX_DEV_NAME);
|
||||
return;
|
||||
}
|
||||
|
||||
if (ioctl(g_sample_comm_mipi_fd, OT_MIPI_TX_DISABLE, NULL) < 0) {
|
||||
printf("ioctl mipi tx (%s) fail\n", MIPI_TX_DEV_NAME);
|
||||
return;
|
||||
}
|
||||
|
||||
close(g_sample_comm_mipi_fd);
|
||||
g_sample_comm_mipi_fd = OT_INVALID_VALUE;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
td_void sample_comm_mipi_tx_set_intf_sync(enum_mipi_tx_intf_sync intf_sync)
|
||||
{
|
||||
}
|
||||
|
||||
td_void libapi_comm_start_mipi_tx(ot_vo_pub_attr *pub_attr)
|
||||
{
|
||||
}
|
||||
|
||||
td_void libapi_comm_stop_mipi_tx(ot_vo_intf_type intf_type)
|
||||
{
|
||||
}
|
||||
#endif /* end of #if VO_MIPI_SUPPORT */
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* end of #ifdef __cplusplus */
|
1165
ss928sdk/common/sample_comm_region.c
Executable file
587
ss928sdk/common/sample_comm_sys.c
Executable file
@ -0,0 +1,587 @@
|
||||
/*
|
||||
Copyright (c), 2001-2022, Shenshu Tech. Co., Ltd.
|
||||
*/
|
||||
|
||||
#include "sample_comm.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/mman.h>
|
||||
#include <signal.h>
|
||||
|
||||
|
||||
static ot_mpp_chn g_sample_mpp_chn[] = {
|
||||
{OT_ID_VI, OT_VI_MAX_DEV_NUM, OT_VI_MAX_CHN_NUM},
|
||||
{OT_ID_VPSS, OT_VPSS_MAX_GRP_NUM, 1},
|
||||
{OT_ID_VENC, 1, OT_VENC_MAX_CHN_NUM},
|
||||
{OT_ID_VO, OT_VO_MAX_LAYER_NUM, OT_VO_MAX_CHN_NUM},
|
||||
{OT_ID_VDEC, 1, OT_VDEC_MAX_CHN_NUM}
|
||||
};
|
||||
|
||||
/* The order of g_sample_pic_size's element must be consistent with the enum value defined in "ot_enum_pic_size". */
|
||||
static ot_size g_sample_pic_size[PIC_BUTT] = {
|
||||
{ 352, 288 }, /* PIC_CIF */
|
||||
{ 640, 360 }, /* PIC_360P */
|
||||
{ 720, 576 }, /* PIC_D1_PAL */
|
||||
{ 720, 480 }, /* PIC_D1_NTSC */
|
||||
{ 960, 576 }, /* PIC_960H */
|
||||
{ 1280, 720 }, /* PIC_720P */
|
||||
{ 1920, 1080 }, /* PIC_1080P */
|
||||
{ 720, 480 }, /* PIC_480P */
|
||||
{ 720, 576 }, /* PIC_576P */
|
||||
{ 800, 600 }, /* PIC_800X600 */
|
||||
{ 1024, 768 }, /* PIC_1024X768 */
|
||||
{ 1280, 1024 }, /* PIC_1280X1024 */
|
||||
{ 1366, 768 }, /* PIC_1366X768 */
|
||||
{ 1440, 900 }, /* PIC_1440X900 */
|
||||
{ 1280, 800 }, /* PIC_1280X800 */
|
||||
{ 1600, 1200 }, /* PIC_1600X1200 */
|
||||
{ 1680, 1050 }, /* PIC_1680X1050 */
|
||||
{ 1920, 1200 }, /* PIC_1920X1200 */
|
||||
{ 640, 480 }, /* PIC_640X480 */
|
||||
{ 1920, 2160 }, /* PIC_1920X2160 */
|
||||
{ 2560, 1440 }, /* PIC_2560X1440 */
|
||||
{ 2560, 1600 }, /* PIC_2560X1600 */
|
||||
{ 2592, 1520 }, /* PIC_2592X1520 */
|
||||
{ 2592, 1944 }, /* PIC_2592X1944 */
|
||||
{ 2688, 1520 }, /* PIC_2688X1520 */
|
||||
{ 3840, 2160 }, /* PIC_3840X2160 */
|
||||
{ 4096, 2160 }, /* PIC_4096X2160 */
|
||||
{ 3000, 3000 }, /* PIC_3000X3000 */
|
||||
{ 4000, 3000 }, /* PIC_4000X3000 */
|
||||
{ 6080, 2800 }, /* PIC_6080X2800 */
|
||||
{ 7680, 4320 }, /* PIC_7680X4320 */
|
||||
{ 3840, 8640 } /* PIC_3840X8640 */
|
||||
};
|
||||
|
||||
#ifndef __LITEOS__
|
||||
td_void libapi_sys_signal(void (*func)(int))
|
||||
{
|
||||
struct sigaction sa = { 0 };
|
||||
|
||||
sa.sa_handler = func;
|
||||
sa.sa_flags = 0;
|
||||
sigaction(SIGINT, &sa, TD_NULL);
|
||||
sigaction(SIGTERM, &sa, TD_NULL);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* get picture size(w*h), according pic_size */
|
||||
td_s32 libapi_comm_sys_get_pic_size(ot_enum_pic_size pic_size, ot_size *size)
|
||||
{
|
||||
if (size == TD_NULL) {
|
||||
sample_print("null ptr arg!\n");
|
||||
return TD_FAILURE;
|
||||
}
|
||||
|
||||
if (pic_size >= PIC_BUTT) {
|
||||
sample_print("illegal pic_size!\n");
|
||||
return TD_FAILURE;
|
||||
}
|
||||
|
||||
size->width = g_sample_pic_size[pic_size].width;
|
||||
size->height = g_sample_pic_size[pic_size].height;
|
||||
|
||||
return TD_SUCCESS;
|
||||
}
|
||||
|
||||
ot_enum_pic_size libapi_comm_sys_get_pic_enum(const ot_size *size)
|
||||
{
|
||||
ot_enum_pic_size i;
|
||||
|
||||
for (i = PIC_CIF; i < PIC_BUTT; i++) {
|
||||
if ((g_sample_pic_size[i].width == size->width) &&
|
||||
(g_sample_pic_size[i].height == size->height)) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return PIC_1080P;
|
||||
}
|
||||
|
||||
static td_s32 sample_comm_sys_set_module_mem_config(td_u32 mod)
|
||||
{
|
||||
td_char *mmz_name = TD_NULL;
|
||||
ot_mpp_chn mpp_chn;
|
||||
td_u32 max_dev_num = g_sample_mpp_chn[mod].dev_id;
|
||||
td_u32 max_chn_num = g_sample_mpp_chn[mod].chn_id;
|
||||
td_u32 i, j;
|
||||
|
||||
mpp_chn.mod_id = g_sample_mpp_chn[mod].mod_id;
|
||||
|
||||
for (i = 0; i < max_dev_num; ++i) {
|
||||
mpp_chn.dev_id = i;
|
||||
|
||||
for (j = 0; j < max_chn_num; ++j) {
|
||||
mpp_chn.chn_id = j;
|
||||
if (ss_mpi_sys_set_mem_cfg(&mpp_chn, mmz_name) != TD_SUCCESS) {
|
||||
sample_print("ss_mpi_sys_set_mem_cfg ERR!\n");
|
||||
return TD_FAILURE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return TD_SUCCESS;
|
||||
}
|
||||
|
||||
/* set system memory location */
|
||||
td_s32 libapi_comm_sys_mem_config(td_void)
|
||||
{
|
||||
td_u32 i;
|
||||
|
||||
/* config memory */
|
||||
for (i = 0; i < sizeof(g_sample_mpp_chn) / sizeof(g_sample_mpp_chn[0]); ++i) {
|
||||
if (sample_comm_sys_set_module_mem_config(i) != TD_SUCCESS) {
|
||||
return TD_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
return TD_SUCCESS;
|
||||
}
|
||||
|
||||
/* vb init & MPI system init */
|
||||
td_s32 libapi_comm_sys_init(const ot_vb_cfg *vb_cfg)
|
||||
{
|
||||
td_s32 ret;
|
||||
|
||||
ss_mpi_sys_exit();
|
||||
ss_mpi_vb_exit();
|
||||
|
||||
if (vb_cfg == TD_NULL) {
|
||||
sample_print("input parameter is null, it is invalid!\n");
|
||||
return TD_FAILURE;
|
||||
}
|
||||
|
||||
ret = ss_mpi_vb_set_cfg(vb_cfg);
|
||||
if (ret != TD_SUCCESS) {
|
||||
sample_print("ss_mpi_vb_set_conf failed!\n");
|
||||
return TD_FAILURE;
|
||||
}
|
||||
|
||||
ret = ss_mpi_vb_init();
|
||||
if (ret != TD_SUCCESS) {
|
||||
sample_print("ss_mpi_vb_init failed!\n");
|
||||
return TD_FAILURE;
|
||||
}
|
||||
|
||||
ret = ss_mpi_sys_init();
|
||||
if (ret != TD_SUCCESS) {
|
||||
sample_print("ss_mpi_sys_init failed!\n");
|
||||
ss_mpi_vb_exit();
|
||||
return TD_FAILURE;
|
||||
}
|
||||
|
||||
return TD_SUCCESS;
|
||||
}
|
||||
|
||||
/* vb init with vb_supplement & MPI system init */
|
||||
td_s32 libapi_comm_sys_init_with_vb_supplement(const ot_vb_cfg *vb_conf, td_u32 supplement_config)
|
||||
{
|
||||
td_s32 ret;
|
||||
ot_vb_supplement_cfg supplement_conf = {0};
|
||||
|
||||
ss_mpi_sys_exit();
|
||||
ss_mpi_vb_exit();
|
||||
|
||||
if (vb_conf == TD_NULL) {
|
||||
sample_print("input parameter is null, it is invalid!\n");
|
||||
return TD_FAILURE;
|
||||
}
|
||||
|
||||
ret = ss_mpi_vb_set_cfg(vb_conf);
|
||||
if (ret != TD_SUCCESS) {
|
||||
sample_print("ss_mpi_vb_set_conf failed!\n");
|
||||
return TD_FAILURE;
|
||||
}
|
||||
|
||||
supplement_conf.supplement_cfg = supplement_config;
|
||||
ret = ss_mpi_vb_set_supplement_cfg(&supplement_conf);
|
||||
if (ret != TD_SUCCESS) {
|
||||
sample_print("ss_mpi_vb_set_supplement_conf failed!\n");
|
||||
return TD_FAILURE;
|
||||
}
|
||||
|
||||
ret = ss_mpi_vb_init();
|
||||
if (ret != TD_SUCCESS) {
|
||||
sample_print("ss_mpi_vb_init failed!\n");
|
||||
return TD_FAILURE;
|
||||
}
|
||||
|
||||
ret = ss_mpi_sys_init();
|
||||
if (ret != TD_SUCCESS) {
|
||||
sample_print("ss_mpi_sys_init failed!\n");
|
||||
return TD_FAILURE;
|
||||
}
|
||||
|
||||
return TD_SUCCESS;
|
||||
}
|
||||
|
||||
/* vb exit & MPI system exit */
|
||||
td_void libapi_comm_sys_exit(td_void)
|
||||
{
|
||||
ss_mpi_sys_exit();
|
||||
ss_mpi_vb_exit_mod_common_pool(OT_VB_UID_VDEC);
|
||||
ss_mpi_vb_exit();
|
||||
return;
|
||||
}
|
||||
|
||||
td_s32 libapi_comm_vi_bind_vo(ot_vi_pipe vi_pipe, ot_vi_chn vi_chn, ot_vo_layer vo_layer, ot_vo_chn vo_chn)
|
||||
{
|
||||
ot_mpp_chn src_chn;
|
||||
ot_mpp_chn dest_chn;
|
||||
|
||||
src_chn.mod_id = OT_ID_VI;
|
||||
src_chn.dev_id = vi_pipe;
|
||||
src_chn.chn_id = vi_chn;
|
||||
|
||||
dest_chn.mod_id = OT_ID_VO;
|
||||
dest_chn.dev_id = vo_layer;
|
||||
dest_chn.chn_id = vo_chn;
|
||||
|
||||
check_return(ss_mpi_sys_bind(&src_chn, &dest_chn), "ss_mpi_sys_bind(VI-VO)");
|
||||
|
||||
return TD_SUCCESS;
|
||||
}
|
||||
|
||||
td_s32 libapi_comm_vi_un_bind_vo(ot_vi_pipe vi_pipe, ot_vi_chn vi_chn, ot_vo_layer vo_layer, ot_vo_chn vo_chn)
|
||||
{
|
||||
ot_mpp_chn src_chn;
|
||||
ot_mpp_chn dest_chn;
|
||||
|
||||
src_chn.mod_id = OT_ID_VI;
|
||||
src_chn.dev_id = vi_pipe;
|
||||
src_chn.chn_id = vi_chn;
|
||||
|
||||
dest_chn.mod_id = OT_ID_VO;
|
||||
dest_chn.dev_id = vo_layer;
|
||||
dest_chn.chn_id = vo_chn;
|
||||
|
||||
check_return(ss_mpi_sys_unbind(&src_chn, &dest_chn), "ss_mpi_sys_unbind(VI-VO)");
|
||||
|
||||
return TD_SUCCESS;
|
||||
}
|
||||
|
||||
td_s32 libapi_comm_vi_bind_vpss(ot_vi_pipe vi_pipe, ot_vi_chn vi_chn, ot_vpss_grp vpss_grp, ot_vpss_chn vpss_chn)
|
||||
{
|
||||
ot_mpp_chn src_chn;
|
||||
ot_mpp_chn dest_chn;
|
||||
|
||||
src_chn.mod_id = OT_ID_VI;
|
||||
src_chn.dev_id = vi_pipe;
|
||||
src_chn.chn_id = vi_chn;
|
||||
|
||||
dest_chn.mod_id = OT_ID_VPSS;
|
||||
dest_chn.dev_id = vpss_grp;
|
||||
dest_chn.chn_id = vpss_chn;
|
||||
|
||||
check_return(ss_mpi_sys_bind(&src_chn, &dest_chn), "ss_mpi_sys_bind(VI-VPSS)");
|
||||
|
||||
return TD_SUCCESS;
|
||||
}
|
||||
|
||||
td_s32 libapi_comm_vi_un_bind_vpss(ot_vi_pipe vi_pipe, ot_vi_chn vi_chn, ot_vpss_grp vpss_grp, ot_vpss_chn vpss_chn)
|
||||
{
|
||||
ot_mpp_chn src_chn;
|
||||
ot_mpp_chn dest_chn;
|
||||
|
||||
src_chn.mod_id = OT_ID_VI;
|
||||
src_chn.dev_id = vi_pipe;
|
||||
src_chn.chn_id = vi_chn;
|
||||
|
||||
dest_chn.mod_id = OT_ID_VPSS;
|
||||
dest_chn.dev_id = vpss_grp;
|
||||
dest_chn.chn_id = vpss_chn;
|
||||
|
||||
check_return(ss_mpi_sys_unbind(&src_chn, &dest_chn), "ss_mpi_sys_unbind(VI-VPSS)");
|
||||
|
||||
return TD_SUCCESS;
|
||||
}
|
||||
|
||||
td_s32 libapi_comm_vi_bind_venc(ot_vi_pipe vi_pipe, ot_vi_chn vi_chn, ot_venc_chn venc_chn)
|
||||
{
|
||||
ot_mpp_chn src_chn;
|
||||
ot_mpp_chn dest_chn;
|
||||
|
||||
src_chn.mod_id = OT_ID_VI;
|
||||
src_chn.dev_id = vi_pipe;
|
||||
src_chn.chn_id = vi_chn;
|
||||
|
||||
dest_chn.mod_id = OT_ID_VENC;
|
||||
dest_chn.dev_id = 0;
|
||||
dest_chn.chn_id = venc_chn;
|
||||
|
||||
check_return(ss_mpi_sys_bind(&src_chn, &dest_chn), "ss_mpi_sys_bind(VI-VENC)");
|
||||
|
||||
return TD_SUCCESS;
|
||||
}
|
||||
|
||||
td_s32 libapi_comm_vi_un_bind_venc(ot_vi_pipe vi_pipe, ot_vi_chn vi_chn, ot_venc_chn venc_chn)
|
||||
{
|
||||
ot_mpp_chn src_chn;
|
||||
ot_mpp_chn dest_chn;
|
||||
|
||||
src_chn.mod_id = OT_ID_VI;
|
||||
src_chn.dev_id = vi_pipe;
|
||||
src_chn.chn_id = vi_chn;
|
||||
|
||||
dest_chn.mod_id = OT_ID_VENC;
|
||||
dest_chn.dev_id = 0;
|
||||
dest_chn.chn_id = venc_chn;
|
||||
|
||||
check_return(ss_mpi_sys_unbind(&src_chn, &dest_chn), "ss_mpi_sys_unbind(VI-VENC)");
|
||||
|
||||
return TD_SUCCESS;
|
||||
}
|
||||
|
||||
td_s32 libapi_comm_avs_bind_venc(ot_avs_grp avs_grp, ot_avs_chn avs_chn, ot_venc_chn venc_chn)
|
||||
{
|
||||
ot_mpp_chn src_chn;
|
||||
ot_mpp_chn dest_chn;
|
||||
|
||||
src_chn.mod_id = OT_ID_AVS;
|
||||
src_chn.dev_id = avs_grp;
|
||||
src_chn.chn_id = avs_chn;
|
||||
|
||||
dest_chn.mod_id = OT_ID_VENC;
|
||||
dest_chn.dev_id = 0;
|
||||
dest_chn.chn_id = venc_chn;
|
||||
|
||||
check_return(ss_mpi_sys_bind(&src_chn, &dest_chn), "ss_mpi_sys_bind(AVS-VENC)");
|
||||
|
||||
return TD_SUCCESS;
|
||||
}
|
||||
|
||||
td_s32 libapi_comm_avs_un_bind_venc(ot_avs_grp avs_grp, ot_avs_chn avs_chn, ot_venc_chn venc_chn)
|
||||
{
|
||||
ot_mpp_chn src_chn;
|
||||
ot_mpp_chn dest_chn;
|
||||
|
||||
src_chn.mod_id = OT_ID_AVS;
|
||||
src_chn.dev_id = avs_grp;
|
||||
src_chn.chn_id = avs_chn;
|
||||
|
||||
dest_chn.mod_id = OT_ID_VENC;
|
||||
dest_chn.dev_id = 0;
|
||||
dest_chn.chn_id = venc_chn;
|
||||
|
||||
check_return(ss_mpi_sys_unbind(&src_chn, &dest_chn), "ss_mpi_sys_unbind(AVS-VENC)");
|
||||
|
||||
return TD_SUCCESS;
|
||||
}
|
||||
|
||||
td_s32 libapi_comm_avs_bind_vo(ot_avs_grp avs_grp, ot_avs_chn avs_chn, ot_vo_layer vo_layer, ot_vo_chn vo_chn)
|
||||
{
|
||||
ot_mpp_chn src_chn;
|
||||
ot_mpp_chn dest_chn;
|
||||
|
||||
src_chn.mod_id = OT_ID_AVS;
|
||||
src_chn.dev_id = avs_grp;
|
||||
src_chn.chn_id = avs_chn;
|
||||
|
||||
dest_chn.mod_id = OT_ID_VO;
|
||||
dest_chn.dev_id = vo_layer;
|
||||
dest_chn.chn_id = vo_chn;
|
||||
|
||||
check_return(ss_mpi_sys_bind(&src_chn, &dest_chn), "ss_mpi_sys_bind(AVS-VO)");
|
||||
|
||||
return TD_SUCCESS;
|
||||
}
|
||||
|
||||
td_s32 libapi_comm_avs_un_bind_vo(ot_avs_grp avs_grp, ot_avs_chn avs_chn, ot_vo_layer vo_layer, ot_vo_chn vo_chn)
|
||||
{
|
||||
ot_mpp_chn src_chn;
|
||||
ot_mpp_chn dest_chn;
|
||||
|
||||
src_chn.mod_id = OT_ID_AVS;
|
||||
src_chn.dev_id = avs_grp;
|
||||
src_chn.chn_id = avs_chn;
|
||||
|
||||
dest_chn.mod_id = OT_ID_VO;
|
||||
dest_chn.dev_id = vo_layer;
|
||||
dest_chn.chn_id = vo_chn;
|
||||
|
||||
check_return(ss_mpi_sys_unbind(&src_chn, &dest_chn), "ss_mpi_sys_unbind(AVS-VO)");
|
||||
|
||||
return TD_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
td_s32 libapi_comm_vpss_bind_vo(ot_vpss_grp vpss_grp, ot_vpss_chn vpss_chn, ot_vo_layer vo_layer, ot_vo_chn vo_chn)
|
||||
{
|
||||
ot_mpp_chn src_chn;
|
||||
ot_mpp_chn dest_chn;
|
||||
|
||||
src_chn.mod_id = OT_ID_VPSS;
|
||||
src_chn.dev_id = vpss_grp;
|
||||
src_chn.chn_id = vpss_chn;
|
||||
|
||||
dest_chn.mod_id = OT_ID_VO;
|
||||
dest_chn.dev_id = vo_layer;
|
||||
dest_chn.chn_id = vo_chn;
|
||||
|
||||
check_return(ss_mpi_sys_bind(&src_chn, &dest_chn), "ss_mpi_sys_bind(VPSS-VO)");
|
||||
|
||||
return TD_SUCCESS;
|
||||
}
|
||||
|
||||
td_s32 libapi_comm_vpss_un_bind_vo(ot_vpss_grp vpss_grp, ot_vpss_chn vpss_chn, ot_vo_layer vo_layer, ot_vo_chn vo_chn)
|
||||
{
|
||||
ot_mpp_chn src_chn;
|
||||
ot_mpp_chn dest_chn;
|
||||
|
||||
src_chn.mod_id = OT_ID_VPSS;
|
||||
src_chn.dev_id = vpss_grp;
|
||||
src_chn.chn_id = vpss_chn;
|
||||
|
||||
dest_chn.mod_id = OT_ID_VO;
|
||||
dest_chn.dev_id = vo_layer;
|
||||
dest_chn.chn_id = vo_chn;
|
||||
|
||||
check_return(ss_mpi_sys_unbind(&src_chn, &dest_chn), "ss_mpi_sys_unbind(VPSS-VO)");
|
||||
|
||||
return TD_SUCCESS;
|
||||
}
|
||||
|
||||
td_s32 libapi_comm_vpss_bind_avs(ot_vpss_grp vpss_grp, ot_vpss_chn vpss_chn, ot_avs_grp avs_grp, ot_avs_pipe avs_pipe)
|
||||
{
|
||||
ot_mpp_chn src_chn;
|
||||
ot_mpp_chn dest_chn;
|
||||
|
||||
src_chn.mod_id = OT_ID_VPSS;
|
||||
src_chn.dev_id = vpss_grp;
|
||||
src_chn.chn_id = vpss_chn;
|
||||
|
||||
dest_chn.mod_id = OT_ID_AVS;
|
||||
dest_chn.dev_id = avs_grp;
|
||||
dest_chn.chn_id = avs_pipe;
|
||||
|
||||
check_return(ss_mpi_sys_bind(&src_chn, &dest_chn), "ss_mpi_sys_bind(VPSS-AVS)");
|
||||
|
||||
return TD_SUCCESS;
|
||||
}
|
||||
|
||||
td_s32 libapi_comm_vpss_un_bind_avs(ot_vpss_grp vpss_grp, ot_vpss_chn vpss_chn,
|
||||
ot_avs_grp avs_grp, ot_avs_pipe avs_pipe)
|
||||
{
|
||||
ot_mpp_chn src_chn;
|
||||
ot_mpp_chn dest_chn;
|
||||
|
||||
src_chn.mod_id = OT_ID_VPSS;
|
||||
src_chn.dev_id = vpss_grp;
|
||||
src_chn.chn_id = vpss_chn;
|
||||
|
||||
dest_chn.mod_id = OT_ID_AVS;
|
||||
dest_chn.dev_id = avs_grp;
|
||||
dest_chn.chn_id = avs_pipe;
|
||||
|
||||
check_return(ss_mpi_sys_unbind(&src_chn, &dest_chn), "ss_mpi_sys_unbind(VPSS-AVS)");
|
||||
|
||||
return TD_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
td_s32 libapi_comm_vpss_bind_venc(ot_vpss_grp vpss_grp, ot_vpss_chn vpss_chn, ot_venc_chn venc_chn)
|
||||
{
|
||||
ot_mpp_chn src_chn;
|
||||
ot_mpp_chn dest_chn;
|
||||
|
||||
src_chn.mod_id = OT_ID_VPSS;
|
||||
src_chn.dev_id = vpss_grp;
|
||||
src_chn.chn_id = vpss_chn;
|
||||
|
||||
dest_chn.mod_id = OT_ID_VENC;
|
||||
dest_chn.dev_id = 0;
|
||||
dest_chn.chn_id = venc_chn;
|
||||
|
||||
check_return(ss_mpi_sys_bind(&src_chn, &dest_chn), "ss_mpi_sys_bind(VPSS-VENC)");
|
||||
|
||||
return TD_SUCCESS;
|
||||
}
|
||||
|
||||
td_s32 libapi_comm_vpss_un_bind_venc(ot_vpss_grp vpss_grp, ot_vpss_chn vpss_chn, ot_venc_chn venc_chn)
|
||||
{
|
||||
ot_mpp_chn src_chn;
|
||||
ot_mpp_chn dest_chn;
|
||||
|
||||
src_chn.mod_id = OT_ID_VPSS;
|
||||
src_chn.dev_id = vpss_grp;
|
||||
src_chn.chn_id = vpss_chn;
|
||||
|
||||
dest_chn.mod_id = OT_ID_VENC;
|
||||
dest_chn.dev_id = 0;
|
||||
dest_chn.chn_id = venc_chn;
|
||||
|
||||
check_return(ss_mpi_sys_unbind(&src_chn, &dest_chn), "ss_mpi_sys_unbind(VPSS-VENC)");
|
||||
|
||||
return TD_SUCCESS;
|
||||
}
|
||||
|
||||
td_s32 libapi_comm_vdec_bind_vpss(ot_vdec_chn vdec_chn, ot_vpss_grp vpss_grp)
|
||||
{
|
||||
ot_mpp_chn src_chn;
|
||||
ot_mpp_chn dest_chn;
|
||||
|
||||
src_chn.mod_id = OT_ID_VDEC;
|
||||
src_chn.dev_id = 0;
|
||||
src_chn.chn_id = vdec_chn;
|
||||
|
||||
dest_chn.mod_id = OT_ID_VPSS;
|
||||
dest_chn.dev_id = vpss_grp;
|
||||
dest_chn.chn_id = 0;
|
||||
|
||||
check_return(ss_mpi_sys_bind(&src_chn, &dest_chn), "ss_mpi_sys_bind(VDEC-VPSS)");
|
||||
|
||||
return TD_SUCCESS;
|
||||
}
|
||||
|
||||
td_s32 libapi_comm_vdec_un_bind_vpss(ot_vdec_chn vdec_chn, ot_vpss_grp vpss_grp)
|
||||
{
|
||||
ot_mpp_chn src_chn;
|
||||
ot_mpp_chn dest_chn;
|
||||
|
||||
src_chn.mod_id = OT_ID_VDEC;
|
||||
src_chn.dev_id = 0;
|
||||
src_chn.chn_id = vdec_chn;
|
||||
|
||||
dest_chn.mod_id = OT_ID_VPSS;
|
||||
dest_chn.dev_id = vpss_grp;
|
||||
dest_chn.chn_id = 0;
|
||||
|
||||
check_return(ss_mpi_sys_unbind(&src_chn, &dest_chn), "ss_mpi_sys_unbind(VDEC-VPSS)");
|
||||
|
||||
return TD_SUCCESS;
|
||||
}
|
||||
|
||||
td_s32 libapi_comm_vo_bind_vo(ot_vo_layer src_vo_layer, ot_vo_chn src_vo_chn,
|
||||
ot_vo_layer dst_vo_layer, ot_vo_chn dst_vo_chn)
|
||||
{
|
||||
ot_mpp_chn src_chn, dest_chn;
|
||||
|
||||
src_chn.mod_id = OT_ID_VO;
|
||||
src_chn.dev_id = src_vo_layer;
|
||||
src_chn.chn_id = src_vo_chn;
|
||||
|
||||
dest_chn.mod_id = OT_ID_VO;
|
||||
dest_chn.dev_id = dst_vo_layer;
|
||||
dest_chn.chn_id = dst_vo_chn;
|
||||
|
||||
return ss_mpi_sys_bind(&src_chn, &dest_chn);
|
||||
}
|
||||
|
||||
td_s32 libapi_comm_vo_un_bind_vo(ot_vo_layer dst_vo_layer, ot_vo_chn dst_vo_chn)
|
||||
{
|
||||
ot_mpp_chn dest_chn;
|
||||
|
||||
dest_chn.mod_id = OT_ID_VO;
|
||||
dest_chn.dev_id = dst_vo_layer;
|
||||
dest_chn.chn_id = dst_vo_chn;
|
||||
|
||||
return ss_mpi_sys_unbind(TD_NULL, &dest_chn);
|
||||
}
|
861
ss928sdk/common/sample_comm_vdec.c
Executable file
@ -0,0 +1,861 @@
|
||||
/*
|
||||
Copyright (c), 2001-2022, Shenshu Tech. Co., Ltd.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/poll.h>
|
||||
#include <sys/time.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <pthread.h>
|
||||
#include <math.h>
|
||||
#include <unistd.h>
|
||||
#include <signal.h>
|
||||
#include <sys/prctl.h>
|
||||
#include <limits.h>
|
||||
#include "sample_comm.h"
|
||||
|
||||
#define SEND_STREAM_CNT 5
|
||||
#define VDEC_SECOND 1000000
|
||||
#define SAMPLE_VDEC_LOW_DELAY_LINE_CNT 16
|
||||
|
||||
static ot_vb_src g_vdec_vb_src = OT_VB_SRC_MOD;
|
||||
static td_bool g_vdec_line_ldy_en = TD_FALSE;
|
||||
|
||||
static ot_vb_pool g_pic_vb_pool[OT_VB_MAX_POOLS] = { [0 ... (OT_VB_MAX_POOLS - 1)] = OT_VB_INVALID_POOL_ID };
|
||||
static ot_vb_pool g_tmv_vb_pool[OT_VB_MAX_POOLS] = { [0 ... (OT_VB_MAX_POOLS - 1)] = OT_VB_INVALID_POOL_ID };
|
||||
|
||||
td_void sample_comm_vdec_print_chn_status(td_s32 chn, ot_vdec_chn_status status)
|
||||
{
|
||||
printf("\033[0;33m ---------------------------------------------------------------\033[0;39m\n");
|
||||
printf("\033[0;33m chn:%d, type:%d, start:%d, decode_frames:%d, left_pics:%d, left_bytes:%d, "
|
||||
"left_frames:%d, recv_frames:%d \033[0;39m\n",
|
||||
chn, (status).type, (status).is_started, (status).dec_stream_frames, (status).left_decoded_frames,
|
||||
(status).left_stream_bytes, (status).left_stream_frames, (status).recv_stream_frames);
|
||||
printf("\033[0;33m format_err:%d, pic_size_err_set:%d, stream_unsprt:%d, pack_err:%d, "
|
||||
"set_pic_size_err:%d, ref_err_set:%d, pic_buf_size_err_set:%d \033[0;39m\n",
|
||||
(status).dec_err.format_err, (status).dec_err.set_pic_size_err, (status).dec_err.stream_unsupport,
|
||||
(status).dec_err.pack_err, (status).dec_err.set_protocol_num_err, (status).dec_err.set_ref_num_err,
|
||||
(status).dec_err.set_pic_buf_size_err);
|
||||
printf("\033[0;33m -----------------------------------------------------------------\033[0;39m\n");
|
||||
return;
|
||||
}
|
||||
|
||||
td_bool sample_comm_vdec_get_lowdelay_en(td_void)
|
||||
{
|
||||
return g_vdec_line_ldy_en;
|
||||
}
|
||||
td_void sample_comm_vdec_set_lowdelay_en(td_bool enable)
|
||||
{
|
||||
g_vdec_line_ldy_en = enable;
|
||||
}
|
||||
|
||||
td_s32 sample_comm_vdec_init_user_vb_pool(td_u32 chn_num, struct_vdec_buf *vdec_buf,
|
||||
struct_vdec_attr *sample_vdec, td_u32 array_len)
|
||||
{
|
||||
td_u32 i;
|
||||
ot_vb_pool_cfg vb_pool_cfg;
|
||||
for (i = 0; (i < chn_num) && (i < array_len) && (i < OT_VB_MAX_POOLS); i++) {
|
||||
if ((vdec_buf[i].pic_buf_size != 0) && (sample_vdec[i].frame_buf_cnt != 0)) {
|
||||
(td_void)memset_s(&vb_pool_cfg, sizeof(ot_vb_pool_cfg), 0, sizeof(ot_vb_pool_cfg));
|
||||
vb_pool_cfg.blk_size = vdec_buf[i].pic_buf_size;
|
||||
vb_pool_cfg.blk_cnt = sample_vdec[i].frame_buf_cnt;
|
||||
vb_pool_cfg.remap_mode = OT_VB_REMAP_MODE_NONE;
|
||||
g_pic_vb_pool[i] = ss_mpi_vb_create_pool(&vb_pool_cfg);
|
||||
if (g_pic_vb_pool[i] == OT_VB_INVALID_POOL_ID) {
|
||||
return TD_FAILURE;
|
||||
}
|
||||
}
|
||||
if (vdec_buf[i].tmv_buf_size != 0) {
|
||||
(td_void)memset_s(&vb_pool_cfg, sizeof(ot_vb_pool_cfg), 0, sizeof(ot_vb_pool_cfg));
|
||||
vb_pool_cfg.blk_size = vdec_buf[i].tmv_buf_size;
|
||||
vb_pool_cfg.blk_cnt = sample_vdec[i].member_vdec_video.ref_frame_num + 1;
|
||||
vb_pool_cfg.remap_mode = OT_VB_REMAP_MODE_NONE;
|
||||
g_tmv_vb_pool[i] = ss_mpi_vb_create_pool(&vb_pool_cfg);
|
||||
if (g_tmv_vb_pool[i] == OT_VB_INVALID_POOL_ID) {
|
||||
return TD_FAILURE;
|
||||
}
|
||||
}
|
||||
}
|
||||
return TD_SUCCESS;
|
||||
}
|
||||
|
||||
td_void sample_comm_handle_init_vb_fail(td_s32 idx)
|
||||
{
|
||||
td_s32 ret;
|
||||
td_s32 i = idx;
|
||||
for (; (i >= 0) && (i < OT_VB_MAX_POOLS); i--) {
|
||||
if (g_pic_vb_pool[i] != OT_VB_INVALID_POOL_ID) {
|
||||
ret = ss_mpi_vb_destroy_pool(g_pic_vb_pool[i]);
|
||||
if (ret != TD_SUCCESS) {
|
||||
printf("vb destroy pool %d fail!\n", g_pic_vb_pool[i]);
|
||||
}
|
||||
g_pic_vb_pool[i] = OT_VB_INVALID_POOL_ID;
|
||||
}
|
||||
if (g_tmv_vb_pool[i] != OT_VB_INVALID_POOL_ID) {
|
||||
ret = ss_mpi_vb_destroy_pool(g_tmv_vb_pool[i]);
|
||||
if (ret != TD_SUCCESS) {
|
||||
printf("vb destroy pool %d fail!\n", g_tmv_vb_pool[i]);
|
||||
}
|
||||
g_tmv_vb_pool[i] = OT_VB_INVALID_POOL_ID;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
td_void sample_comm_vdec_cal_vb_size(td_u32 chn_num, struct_vdec_attr *sample_vdec,
|
||||
td_u32 sample_vdec_arr_len, struct_vdec_buf *vdec_buf)
|
||||
{
|
||||
td_u32 i;
|
||||
ot_pic_buf_attr buf_attr = { 0 };
|
||||
for (i = 0; (i < chn_num) && (i < sample_vdec_arr_len); i++) {
|
||||
buf_attr.align = 0;
|
||||
buf_attr.height = sample_vdec[i].height;
|
||||
buf_attr.width = sample_vdec[i].width;
|
||||
if (sample_vdec[i].type == OT_PT_H265) {
|
||||
buf_attr.bit_width = sample_vdec[i].member_vdec_video.bit_width;
|
||||
buf_attr.pixel_format = OT_PIXEL_FORMAT_YVU_SEMIPLANAR_420;
|
||||
vdec_buf[i].pic_buf_size = ot_vdec_get_pic_buf_size(sample_vdec[i].type, &buf_attr);
|
||||
vdec_buf[i].tmv_buf_size =
|
||||
ot_vdec_get_tmv_buf_size(sample_vdec[i].type, sample_vdec[i].width, sample_vdec[i].height);
|
||||
} else if (sample_vdec[i].type == OT_PT_H264) {
|
||||
buf_attr.bit_width = sample_vdec[i].member_vdec_video.bit_width;
|
||||
buf_attr.pixel_format = OT_PIXEL_FORMAT_YVU_SEMIPLANAR_420;
|
||||
vdec_buf[i].pic_buf_size = ot_vdec_get_pic_buf_size(sample_vdec[i].type, &buf_attr);
|
||||
if (sample_vdec[i].member_vdec_video.dec_mode == OT_VIDEO_DEC_MODE_IPB) {
|
||||
vdec_buf[i].tmv_buf_size =
|
||||
ot_vdec_get_tmv_buf_size(sample_vdec[i].type, sample_vdec[i].width, sample_vdec[i].height);
|
||||
}
|
||||
} else {
|
||||
buf_attr.bit_width = OT_DATA_BIT_WIDTH_8;
|
||||
buf_attr.pixel_format = sample_vdec[i].member_vdec_picture.pixel_format;
|
||||
vdec_buf[i].pic_buf_size = ot_vdec_get_pic_buf_size(sample_vdec[i].type, &buf_attr);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
td_s32 sample_comm_vdec_config_vb_pool(td_u32 chn_num, struct_vdec_attr *sample_vdec, td_u32 arr_len,
|
||||
struct_vdec_buf *vdec_buf, ot_vb_cfg *vb_conf)
|
||||
{
|
||||
td_u32 i, j;
|
||||
td_bool find_flag;
|
||||
td_s32 pos = 0;
|
||||
/* pic_buffer */
|
||||
for (j = 0; j < OT_VB_MAX_COMMON_POOLS; j++) {
|
||||
find_flag = TD_FALSE;
|
||||
for (i = 0; (i < chn_num) && (i < arr_len); i++) {
|
||||
if ((find_flag == TD_FALSE) && (vdec_buf[i].pic_buf_size != 0) && (vdec_buf[i].pic_buf_alloc == TD_FALSE)) {
|
||||
vb_conf->common_pool[j].blk_size = vdec_buf[i].pic_buf_size;
|
||||
vb_conf->common_pool[j].blk_cnt = sample_vdec[i].frame_buf_cnt;
|
||||
vdec_buf[i].pic_buf_alloc = TD_TRUE;
|
||||
find_flag = TD_TRUE;
|
||||
pos = j;
|
||||
}
|
||||
|
||||
if ((find_flag == TD_TRUE) && (vdec_buf[i].pic_buf_alloc == TD_FALSE) &&
|
||||
(vb_conf->common_pool[j].blk_size == vdec_buf[i].pic_buf_size)) {
|
||||
vb_conf->common_pool[j].blk_cnt += sample_vdec[i].frame_buf_cnt;
|
||||
vdec_buf[i].pic_buf_alloc = TD_TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* tmv_buffer */
|
||||
for (j = pos + 1; j < OT_VB_MAX_COMMON_POOLS; j++) {
|
||||
find_flag = TD_FALSE;
|
||||
for (i = 0; (i < chn_num) && (i < arr_len); i++) {
|
||||
if ((find_flag == TD_FALSE) && (vdec_buf[i].tmv_buf_size != 0) && (vdec_buf[i].tmv_buf_alloc == TD_FALSE)) {
|
||||
vb_conf->common_pool[j].blk_size = vdec_buf[i].tmv_buf_size;
|
||||
vb_conf->common_pool[j].blk_cnt = sample_vdec[i].member_vdec_video.ref_frame_num + 1;
|
||||
vdec_buf[i].tmv_buf_alloc = TD_TRUE;
|
||||
find_flag = TD_TRUE;
|
||||
pos = j;
|
||||
}
|
||||
|
||||
if ((find_flag == TD_TRUE) && (vdec_buf[i].tmv_buf_alloc == TD_FALSE) &&
|
||||
(vb_conf->common_pool[j].blk_size == vdec_buf[i].tmv_buf_size)) {
|
||||
vb_conf->common_pool[j].blk_cnt += sample_vdec[i].member_vdec_video.ref_frame_num + 1;
|
||||
vdec_buf[i].tmv_buf_alloc = TD_TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
vb_conf->max_pool_cnt = pos + 1;
|
||||
return i - 1;
|
||||
}
|
||||
|
||||
td_s32 sample_comm_vdec_init_vb_pool(td_u32 chn_num, struct_vdec_attr *sample_vdec, td_u32 arr_len)
|
||||
{
|
||||
ot_vb_cfg vb_conf;
|
||||
td_s32 i, ret;
|
||||
struct_vdec_buf vdec_buf[OT_VDEC_MAX_CHN_NUM];
|
||||
|
||||
check_null_ptr_return(sample_vdec);
|
||||
if (arr_len > OT_VDEC_MAX_CHN_NUM) {
|
||||
printf("struct_vdec_attr array len Invalid \n");
|
||||
return TD_FAILURE;
|
||||
}
|
||||
(td_void)memset_s(vdec_buf, sizeof(vdec_buf), 0, sizeof(struct_vdec_buf) * OT_VDEC_MAX_CHN_NUM);
|
||||
(td_void)memset_s(&vb_conf, sizeof(ot_vb_cfg), 0, sizeof(ot_vb_cfg));
|
||||
|
||||
sample_comm_vdec_cal_vb_size(chn_num, sample_vdec, arr_len, vdec_buf);
|
||||
|
||||
i = sample_comm_vdec_config_vb_pool(chn_num, sample_vdec, arr_len, vdec_buf, &vb_conf);
|
||||
|
||||
if (g_vdec_vb_src == OT_VB_SRC_MOD) {
|
||||
ss_mpi_vb_exit_mod_common_pool(OT_VB_UID_VDEC);
|
||||
check_return(ss_mpi_vb_set_mod_pool_cfg(OT_VB_UID_VDEC, &vb_conf), "vb set mod pool config");
|
||||
ret = ss_mpi_vb_init_mod_common_pool(OT_VB_UID_VDEC);
|
||||
if (ret != TD_SUCCESS) {
|
||||
printf("vb exit mod common pool fail for 0x%x\n", ret);
|
||||
ss_mpi_vb_exit_mod_common_pool(OT_VB_UID_VDEC);
|
||||
return TD_FAILURE;
|
||||
}
|
||||
} else if (g_vdec_vb_src == OT_VB_SRC_USER) {
|
||||
if (sample_comm_vdec_init_user_vb_pool(chn_num, &vdec_buf[0], &sample_vdec[0], OT_VDEC_MAX_CHN_NUM) !=
|
||||
TD_SUCCESS) {
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
|
||||
return TD_SUCCESS;
|
||||
|
||||
fail:
|
||||
sample_comm_handle_init_vb_fail(i);
|
||||
return TD_FAILURE;
|
||||
}
|
||||
|
||||
td_void sample_comm_vdec_exit_user_vb_pool(td_void)
|
||||
{
|
||||
td_s32 i, ret;
|
||||
for (i = OT_VB_MAX_POOLS - 1; i >= 0; i--) {
|
||||
if (g_pic_vb_pool[i] != OT_VB_INVALID_POOL_ID) {
|
||||
ret = ss_mpi_vb_destroy_pool(g_pic_vb_pool[i]);
|
||||
if (ret != TD_SUCCESS) {
|
||||
printf("vb destroy pool %d fail!\n", g_pic_vb_pool[i]);
|
||||
}
|
||||
g_pic_vb_pool[i] = OT_VB_INVALID_POOL_ID;
|
||||
}
|
||||
if (g_tmv_vb_pool[i] != OT_VB_INVALID_POOL_ID) {
|
||||
ret = ss_mpi_vb_destroy_pool(g_tmv_vb_pool[i]);
|
||||
if (ret != TD_SUCCESS) {
|
||||
printf("vb destroy pool %d fail!\n", g_tmv_vb_pool[i]);
|
||||
}
|
||||
g_tmv_vb_pool[i] = OT_VB_INVALID_POOL_ID;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
td_void sample_comm_vdec_exit_vb_pool(td_void)
|
||||
{
|
||||
if (g_vdec_vb_src == OT_VB_SRC_MOD) {
|
||||
ss_mpi_vb_exit_mod_common_pool(OT_VB_UID_VDEC);
|
||||
} else if (g_vdec_vb_src == OT_VB_SRC_USER) {
|
||||
sample_comm_vdec_exit_user_vb_pool();
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
td_void sample_comm_vdec_send_h264_frame_process(td_s32 *read_len, td_u8 *buf,
|
||||
struct_vdec_thread_param *thread_param, td_s32 used_bytes)
|
||||
{
|
||||
td_s32 i;
|
||||
td_bool find_start = TD_FALSE;
|
||||
td_bool find_end = TD_FALSE;
|
||||
td_bool new_pic;
|
||||
/* H264 frame start marker */
|
||||
if (*read_len > thread_param->min_buf_size) {
|
||||
sample_print("chn %d read_len %d is bigger than buf_size %u!\n", thread_param->chn_id, *read_len,
|
||||
thread_param->min_buf_size);
|
||||
return;
|
||||
}
|
||||
for (i = 0; i < *read_len - 8; i++) { /* 8:h264 frame start code length */
|
||||
int tmp = buf[i + 3] & 0x1F; /* 3:index 0x1F:frame start marker */
|
||||
new_pic = (buf[i] == 0 && buf[i + 1] == 0 && buf[i + 2] == 1 && /* 1 2:index */
|
||||
(((tmp == 0x5 || tmp == 0x1) && ((buf[i + 4] & 0x80) == 0x80)) || /* 4:index 0x5 0x80:frame start mark */
|
||||
(tmp == 20 && (buf[i + 7] & 0x80) == 0x80))); /* 20 0x1 0x80:frame start marker 7:index */
|
||||
if (new_pic == TD_TRUE) {
|
||||
find_start = TD_TRUE;
|
||||
i += 8; /* 8:h264 frame start code length */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (; i < *read_len - 8; i++) { /* 8:h264 frame start code length */
|
||||
int tmp = buf[i + 3] & 0x1F; /* 3:index 0x1F:frame start marker */
|
||||
new_pic = (buf[i] == 0 && buf[i + 1] == 0 && buf[i + 2] == 1 && /* 1 2:index */
|
||||
(tmp == 15 || tmp == 7 || tmp == 8 || tmp == 6 || /* 15 7 8 6:frame start marker */
|
||||
((tmp == 5 || tmp == 1) && ((buf[i + 4] & 0x80) == 0x80)) || /* 4:index 5 0x80:frame start marker */
|
||||
(tmp == 20 && (buf[i + 7] & 0x80) == 0x80))); /* 7:index 20 0x80:frame start marker */
|
||||
if (new_pic == TD_TRUE) {
|
||||
find_end = TD_TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (i > 0) {
|
||||
*read_len = i;
|
||||
}
|
||||
if (find_start == TD_FALSE) {
|
||||
sample_print("chn %d can not find H264 start code! read_len %d, used_bytes %d!\n", thread_param->chn_id,
|
||||
*read_len, used_bytes);
|
||||
}
|
||||
if (find_end == TD_FALSE) {
|
||||
*read_len = i + 8; /* 8:h264 frame start code length */
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
td_void sample_comm_vdec_send_mpeg4_frame_process(td_s32 *read_len, td_u8 *buf,
|
||||
struct_vdec_thread_param *thread_param, td_s32 used_bytes)
|
||||
{
|
||||
td_s32 i;
|
||||
td_bool find_start = TD_FALSE;
|
||||
td_bool find_end = TD_FALSE;
|
||||
/* MPEG4 frame start marker */
|
||||
if (*read_len > thread_param->min_buf_size) {
|
||||
sample_print("chn %d read_len %d is bigger than buf_size %u!\n", thread_param->chn_id, *read_len,
|
||||
thread_param->min_buf_size);
|
||||
return;
|
||||
}
|
||||
for (i = 0; i < *read_len - 4; i++) { /* 4:mpeg4 frame start code length */
|
||||
if (buf[i] == 0 && buf[i + 1] == 0 &&
|
||||
buf[i + 2] == 1 && buf[i + 3] == 0xB6) { /* 0xB6:frame start marker 2 3:index */
|
||||
find_start = TD_TRUE;
|
||||
i += 4; /* 4:mpeg4 frame start code length */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (; i < *read_len - 4; i++) { /* 4:mpeg4 frame start code length */
|
||||
if (buf[i] == 0 && buf[i + 1] == 0 &&
|
||||
buf[i + 2] == 1 && buf[i + 3] == 0xB6) { /* 2 3:index 0xB6:frame start marker */
|
||||
find_end = TD_TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (i > 0) {
|
||||
*read_len = i;
|
||||
}
|
||||
if (find_start == TD_FALSE) {
|
||||
sample_print("chn %d can not find MPEG4 start code! read_len %d, used_bytes %d!\n", thread_param->chn_id,
|
||||
*read_len, used_bytes);
|
||||
}
|
||||
if (find_end == TD_FALSE) {
|
||||
*read_len = i + 4; /* 4:mpeg4 frame start code length */
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
td_void sample_comm_vdec_send_h265_frame_process(td_s32 *read_len, td_u8 *buf,
|
||||
struct_vdec_thread_param *thread_param, td_s32 used_bytes)
|
||||
{
|
||||
td_s32 i;
|
||||
td_bool find_start = TD_FALSE;
|
||||
td_bool find_end = TD_FALSE;
|
||||
/* H265 frame start marker */
|
||||
td_bool new_pic;
|
||||
if (*read_len > thread_param->min_buf_size) {
|
||||
sample_print("chn %d read_len %d is bigger than buf_size %u!\n", thread_param->chn_id, *read_len,
|
||||
thread_param->min_buf_size);
|
||||
return;
|
||||
}
|
||||
for (i = 0; i < *read_len - 6; i++) { /* 6:h265 frame start code length */
|
||||
td_u32 tmp = (buf[i + 3] & 0x7E) >> 1; /* 0x7E:frame start marker 3:index */
|
||||
new_pic = (buf[i + 0] == 0 && buf[i + 1] == 0 && buf[i + 2] == 1 && /* 1 2:index */
|
||||
(tmp <= 21) && ((buf[i + 5] & 0x80) == 0x80)); /* 5:index 21 0x80:frame start marker */
|
||||
|
||||
if (new_pic) {
|
||||
find_start = TD_TRUE;
|
||||
i += 6; /* 6:h265 frame start code length */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (; i < *read_len - 6; i++) { /* 6:h265 frame start code length */
|
||||
td_u32 tmp = (buf[i + 3] & 0x7E) >> 1; /* 0x7E:frame start marker 3:index */
|
||||
new_pic = (buf[i + 0] == 0 && buf[i + 1] == 0 && buf[i + 2] == 1 && /* 1 2:index */
|
||||
(tmp == 32 || tmp == 33 || tmp == 34 || tmp == 39 || tmp == 40 || /* 32 33 34 39 40:frame start marker */
|
||||
((tmp <= 21) && (buf[i + 5] & 0x80) == 0x80))); /* 5:index 21 0x80:frame start marker */
|
||||
|
||||
if (new_pic) {
|
||||
find_end = TD_TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (i > 0) {
|
||||
*read_len = i;
|
||||
}
|
||||
|
||||
if (find_start == TD_FALSE) {
|
||||
sample_print("chn %d can not find H265 start code! read_len %d, used_bytes %d!\n", thread_param->chn_id,
|
||||
*read_len, used_bytes);
|
||||
}
|
||||
if (find_end == TD_FALSE) {
|
||||
*read_len = i + 6; /* 6:h265 frame start code length */
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
td_u32 sample_comm_vdec_send_jpeg_frame_process(td_s32 *read_len, td_u8 *buf,
|
||||
struct_vdec_thread_param *thread_param, td_s32 used_bytes)
|
||||
{
|
||||
td_s32 i;
|
||||
td_u32 len;
|
||||
td_u32 start = 0;
|
||||
td_bool find_start = TD_FALSE;
|
||||
if (*read_len > thread_param->min_buf_size) {
|
||||
sample_print("chn %d read_len %d is bigger than buf_size %u!\n", thread_param->chn_id, *read_len,
|
||||
thread_param->min_buf_size);
|
||||
return start;
|
||||
}
|
||||
/* JPEG frame start marker */
|
||||
for (i = 0; i < *read_len - 1; i++) {
|
||||
if (buf[i] == 0xFF && buf[i + 1] == 0xD8) { /* 0xFF 0xD8:frame start marker */
|
||||
start = i;
|
||||
find_start = TD_TRUE;
|
||||
i = i + 2; /* 2:offset */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (; i < *read_len - 3; i++) { /* 3:jpeg frame start code length */
|
||||
if ((buf[i] == 0xFF) && (buf[i + 1] & 0xF0) == 0xE0) { /* 0xFF 0xF0 0xE0:frame start marker */
|
||||
len = (buf[i + 2] << 8) + buf[i + 3]; /* 2 3:index 8:left shift length */
|
||||
i += 1 + len;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (; i < *read_len - 1; i++) {
|
||||
if (buf[i] == 0xFF && buf[i + 1] == 0xD9) { /* 0xFF 0xD9:frame start marker */
|
||||
break;
|
||||
}
|
||||
}
|
||||
*read_len = i + 2; /* 2:offset */
|
||||
|
||||
if (find_start == TD_FALSE) {
|
||||
sample_print("chn %d can not find JPEG start code! read_len %d, used_bytes %d!\n", thread_param->chn_id,
|
||||
*read_len, used_bytes);
|
||||
}
|
||||
return start;
|
||||
}
|
||||
|
||||
td_u32 sample_comm_vdec_cut_frame(td_s32 *read_len, td_u8 *buf, struct_vdec_thread_param *thread_param,
|
||||
td_s32 used_bytes, td_bool *end_of_stream)
|
||||
{
|
||||
td_u32 start = 0;
|
||||
if ((thread_param->stream_mode == OT_VDEC_SEND_MODE_FRAME ||
|
||||
thread_param->stream_mode == OT_VDEC_SEND_MODE_COMPAT) && thread_param->type == OT_PT_H264) {
|
||||
sample_comm_vdec_send_h264_frame_process(read_len, buf, thread_param, used_bytes);
|
||||
} else if ((thread_param->stream_mode == OT_VDEC_SEND_MODE_FRAME ||
|
||||
thread_param->stream_mode == OT_VDEC_SEND_MODE_COMPAT) && thread_param->type == OT_PT_H265) {
|
||||
sample_comm_vdec_send_h265_frame_process(read_len, buf, thread_param, used_bytes);
|
||||
} else if ((thread_param->stream_mode == OT_VDEC_SEND_MODE_FRAME ||
|
||||
thread_param->stream_mode == OT_VDEC_SEND_MODE_COMPAT) && thread_param->type == OT_PT_MP4VIDEO) {
|
||||
sample_comm_vdec_send_mpeg4_frame_process(read_len, buf, thread_param, used_bytes);
|
||||
} else if ((thread_param->stream_mode == OT_VDEC_SEND_MODE_FRAME ||
|
||||
thread_param->stream_mode == OT_VDEC_SEND_MODE_COMPAT) && (thread_param->type == OT_PT_MJPEG ||
|
||||
thread_param->type == OT_PT_JPEG)) {
|
||||
start = sample_comm_vdec_send_jpeg_frame_process(read_len, buf, thread_param, used_bytes);
|
||||
} else {
|
||||
if ((*read_len != 0) && (*read_len < thread_param->min_buf_size)) {
|
||||
*end_of_stream = TD_TRUE;
|
||||
}
|
||||
}
|
||||
return start;
|
||||
}
|
||||
|
||||
td_void sample_comm_vdec_send_stream_proc(struct_vdec_thread_param *thread_param,
|
||||
ot_vdec_stream *stream, td_bool end_of_stream)
|
||||
{
|
||||
td_s32 ret;
|
||||
td_s32 total_len = stream->len;
|
||||
td_s32 cur_len = 0;
|
||||
td_s32 i;
|
||||
td_u8 *base = stream->addr;
|
||||
td_s32 cnt = (thread_param->stream_mode == OT_VDEC_SEND_MODE_COMPAT) ? SEND_STREAM_CNT : 1;
|
||||
for (i = 0; i < cnt; i++) {
|
||||
stream->addr = base + cur_len;
|
||||
if (i == cnt - 1) {
|
||||
stream->len = total_len - cur_len;
|
||||
stream->end_of_frame = TD_TRUE;
|
||||
stream->end_of_stream = end_of_stream;
|
||||
} else {
|
||||
stream->len = total_len / cnt;
|
||||
cur_len += stream->len;
|
||||
stream->end_of_frame = TD_FALSE;
|
||||
stream->end_of_stream = TD_FALSE;
|
||||
}
|
||||
|
||||
ret = ss_mpi_vdec_send_stream(thread_param->chn_id, stream, thread_param->milli_sec);
|
||||
while ((ret != TD_SUCCESS) && (thread_param->e_thread_ctrl == THREAD_CTRL_START)) {
|
||||
usleep(thread_param->interval_time);
|
||||
ret = ss_mpi_vdec_send_stream(thread_param->chn_id, stream, thread_param->milli_sec);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
td_void sample_comm_vdec_handle_send_stream(struct_vdec_thread_param *thread_param, ot_vdec_stream *stream,
|
||||
td_bool *end_of_stream, td_u64 *pts)
|
||||
{
|
||||
td_u64 cur_time;
|
||||
|
||||
while (1) {
|
||||
if (thread_param->e_thread_ctrl != THREAD_CTRL_START) {
|
||||
break;
|
||||
}
|
||||
ss_mpi_sys_get_cur_pts(&cur_time);
|
||||
if ((thread_param->last_time == 0) ||
|
||||
((cur_time - thread_param->last_time) >= (VDEC_SECOND / thread_param->fps - thread_param->time_gap))) {
|
||||
sample_comm_vdec_send_stream_proc(thread_param, stream, *end_of_stream);
|
||||
*end_of_stream = TD_FALSE;
|
||||
*pts += thread_param->pts_increase;
|
||||
if (thread_param->last_time != 0) {
|
||||
thread_param->time_gap =
|
||||
((cur_time - thread_param->last_time) >= (VDEC_SECOND / thread_param->fps)) ?
|
||||
(cur_time - thread_param->last_time - (VDEC_SECOND / thread_param->fps)) : 0;
|
||||
thread_param->time_gap = (thread_param->time_gap > (VDEC_SECOND / thread_param->fps)) ?
|
||||
(VDEC_SECOND / thread_param->fps) : thread_param->time_gap;
|
||||
}
|
||||
|
||||
thread_param->last_time = cur_time;
|
||||
break;
|
||||
} else {
|
||||
usleep(thread_param->interval_time);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
td_void sample_comm_vdec_send_stream_process(struct_vdec_thread_param *thread_param, FILE *fp_strm,
|
||||
td_u8 *buf)
|
||||
{
|
||||
td_bool end_of_stream;
|
||||
td_s32 used_bytes = 0;
|
||||
td_s32 read_len;
|
||||
td_u64 pts = thread_param->pts_init;
|
||||
td_u32 start;
|
||||
ot_vdec_stream stream;
|
||||
|
||||
thread_param->last_time = 0;
|
||||
thread_param->time_gap = 0;
|
||||
while (1) {
|
||||
if (thread_param->e_thread_ctrl == THREAD_CTRL_STOP) {
|
||||
break;
|
||||
} else if (thread_param->e_thread_ctrl == THREAD_CTRL_PAUSE) {
|
||||
sleep(1);
|
||||
continue;
|
||||
}
|
||||
|
||||
end_of_stream = TD_FALSE;
|
||||
fseek(fp_strm, used_bytes, SEEK_SET);
|
||||
read_len = fread(buf, 1, thread_param->min_buf_size, fp_strm);
|
||||
if (read_len == 0) {
|
||||
if (thread_param->circle_send == TD_TRUE) {
|
||||
(td_void)memset_s(&stream, sizeof(ot_vdec_stream), 0, sizeof(ot_vdec_stream));
|
||||
stream.end_of_stream = TD_TRUE;
|
||||
ss_mpi_vdec_send_stream(thread_param->chn_id, &stream, -1);
|
||||
|
||||
used_bytes = 0;
|
||||
fseek(fp_strm, 0, SEEK_SET);
|
||||
read_len = fread(buf, 1, thread_param->min_buf_size, fp_strm);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
start = sample_comm_vdec_cut_frame(&read_len, buf, thread_param, used_bytes, &end_of_stream);
|
||||
|
||||
stream.pts = pts;
|
||||
stream.addr = buf + start;
|
||||
stream.len = read_len;
|
||||
stream.end_of_frame = (thread_param->stream_mode == OT_VDEC_SEND_MODE_FRAME ||
|
||||
thread_param->stream_mode == OT_VDEC_SEND_MODE_COMPAT) ? TD_TRUE : TD_FALSE;
|
||||
stream.end_of_stream = end_of_stream;
|
||||
stream.need_display = 1;
|
||||
|
||||
sample_comm_vdec_handle_send_stream(thread_param, &stream, &end_of_stream, &pts);
|
||||
used_bytes += read_len + start;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
td_s32 sample_comm_vdec_check_send_stream_param(struct_vdec_thread_param *thread_param,
|
||||
td_char *c_stream_file, td_u32 arr_len)
|
||||
{
|
||||
if (thread_param->c_file_path == TD_NULL || thread_param->c_file_name == TD_NULL) {
|
||||
sample_print("chn %d stream file path or stream file name is NULL\n", thread_param->chn_id);
|
||||
return TD_FAILURE;
|
||||
}
|
||||
|
||||
if (arr_len <= 1) {
|
||||
sample_print("chn %d arr length might be overflow\n", thread_param->chn_id);
|
||||
return TD_FAILURE;
|
||||
}
|
||||
|
||||
if (snprintf_s(c_stream_file, arr_len, arr_len - 1, "%s/%s", thread_param->c_file_path,
|
||||
thread_param->c_file_name) < 0) {
|
||||
sample_print("chn %d config stream file failed!\n", thread_param->chn_id);
|
||||
return TD_FAILURE;
|
||||
}
|
||||
|
||||
if (thread_param->min_buf_size <= 0) {
|
||||
sample_print("chn %d min_buf_size should greater than zero!\n", thread_param->chn_id);
|
||||
return TD_FAILURE;
|
||||
}
|
||||
|
||||
if (thread_param->fps <= 0 || thread_param->fps > 300) { /* 0~300:frame rate limit */
|
||||
sample_print("chn %d fps should be [1, 300]!\n", thread_param->chn_id);
|
||||
return TD_FAILURE;
|
||||
}
|
||||
return TD_SUCCESS;
|
||||
}
|
||||
|
||||
td_void *sample_comm_vdec_send_stream(td_void *args)
|
||||
{
|
||||
struct_vdec_thread_param *thread_param = (struct_vdec_thread_param *)args;
|
||||
FILE *fp_strm = TD_NULL;
|
||||
td_u8 *buf = TD_NULL;
|
||||
ot_vdec_stream stream;
|
||||
td_char c_stream_file[FILE_NAME_LEN];
|
||||
td_char *path = TD_NULL;
|
||||
|
||||
prctl(PR_SET_NAME, "video_send_stream", 0, 0, 0);
|
||||
|
||||
if (sample_comm_vdec_check_send_stream_param(thread_param, c_stream_file, FILE_NAME_LEN) != TD_SUCCESS) {
|
||||
return (td_void *)(TD_FAILURE);
|
||||
}
|
||||
|
||||
path = realpath(c_stream_file, TD_NULL);
|
||||
if (path == TD_NULL) {
|
||||
sample_print("chn %d Invalid stream path. Please check!\n", thread_param->chn_id);
|
||||
return (td_void *)(TD_FAILURE);
|
||||
}
|
||||
|
||||
fp_strm = fopen(path, "rb");
|
||||
if (fp_strm == TD_NULL) {
|
||||
sample_print("chn %d can't open file %s in send stream thread!\n", thread_param->chn_id, c_stream_file);
|
||||
goto end1;
|
||||
}
|
||||
printf("\n \033[0;36m chn %d, stream file:%s, userbufsize: %d \033[0;39m\n", thread_param->chn_id,
|
||||
thread_param->c_file_name, thread_param->min_buf_size);
|
||||
|
||||
buf = malloc(thread_param->min_buf_size);
|
||||
if (buf == TD_NULL) {
|
||||
sample_print("chn %d can't alloc %d in send stream thread!\n",
|
||||
thread_param->chn_id, thread_param->min_buf_size);
|
||||
goto end;
|
||||
}
|
||||
fflush(stdout);
|
||||
|
||||
sample_comm_vdec_send_stream_process(thread_param, fp_strm, buf);
|
||||
|
||||
/* send the flag of stream end */
|
||||
(td_void)memset_s(&stream, sizeof(ot_vdec_stream), 0, sizeof(ot_vdec_stream));
|
||||
stream.end_of_stream = TD_TRUE;
|
||||
ss_mpi_vdec_send_stream(thread_param->chn_id, &stream, -1);
|
||||
|
||||
printf("\033[0;35m chn %d send steam thread return ... \033[0;39m\n", thread_param->chn_id);
|
||||
fflush(stdout);
|
||||
if (buf != TD_NULL) {
|
||||
free(buf);
|
||||
buf = TD_NULL;
|
||||
}
|
||||
end:
|
||||
fclose(fp_strm);
|
||||
fp_strm = TD_NULL;
|
||||
end1:
|
||||
free(path);
|
||||
path = TD_NULL;
|
||||
return (td_void *)TD_SUCCESS;
|
||||
}
|
||||
|
||||
td_void sample_comm_vdec_cmd_not_circle_send(td_u32 chn_num, struct_vdec_thread_param *vdec_send,
|
||||
pthread_t *vdec_thread, td_u32 send_arr_len, td_u32 thread_arr_len)
|
||||
{
|
||||
td_u32 i;
|
||||
td_s32 ret;
|
||||
ot_vdec_chn_status status;
|
||||
printf("decoding..............");
|
||||
for (i = 0; (i < chn_num) && (i < send_arr_len) && (i < thread_arr_len); i++) {
|
||||
if (vdec_thread[i] != 0) {
|
||||
ret = pthread_join(vdec_thread[i], TD_NULL);
|
||||
if (ret == 0) {
|
||||
vdec_thread[i] = 0;
|
||||
}
|
||||
}
|
||||
vdec_thread[i] = 0;
|
||||
while (1) {
|
||||
ret = ss_mpi_vdec_query_status(vdec_send[i].chn_id, &status);
|
||||
if (ret != TD_SUCCESS) {
|
||||
printf("chn %d vdec query status fail!!\n", ret);
|
||||
return;
|
||||
}
|
||||
if ((status.left_stream_bytes == 0) && (status.left_stream_frames == 0)) {
|
||||
sample_comm_vdec_print_chn_status(vdec_send[i].chn_id, status);
|
||||
break;
|
||||
}
|
||||
usleep(1000); /* 1000:Decoding wait time */
|
||||
}
|
||||
}
|
||||
printf("end!\n");
|
||||
return;
|
||||
}
|
||||
|
||||
td_void sample_comm_vdec_start_send_stream(td_s32 chn_num, struct_vdec_thread_param *vdec_send,
|
||||
pthread_t *vdec_thread, td_u32 send_arr_len, td_u32 thread_arr_len)
|
||||
{
|
||||
td_u32 i;
|
||||
if ((vdec_send == TD_NULL) || (vdec_thread == TD_NULL)) {
|
||||
printf("vdec_send or vdec_thread can't be NULL!\n");
|
||||
return;
|
||||
}
|
||||
for (i = 0; (i < (td_u32)chn_num) && (i < send_arr_len) && (i < thread_arr_len); i++) {
|
||||
vdec_thread[i] = 0;
|
||||
pthread_create(&vdec_thread[i], 0, sample_comm_vdec_send_stream, (td_void *)&vdec_send[i]);
|
||||
}
|
||||
}
|
||||
|
||||
td_void sample_comm_vdec_stop_send_stream(td_s32 chn_num, struct_vdec_thread_param *vdec_send,
|
||||
pthread_t *vdec_thread, td_u32 send_arr_len, td_u32 thread_arr_len)
|
||||
{
|
||||
td_u32 i;
|
||||
if ((vdec_send == TD_NULL) || (vdec_thread == TD_NULL)) {
|
||||
printf("vdec_send or vdec_thread can't be NULL!\n");
|
||||
return;
|
||||
}
|
||||
for (i = 0; (i < (td_u32)chn_num) && (i < send_arr_len) && (i < thread_arr_len); i++) {
|
||||
vdec_send[i].e_thread_ctrl = THREAD_CTRL_STOP;
|
||||
if (vdec_thread[i] != 0) {
|
||||
pthread_join(vdec_thread[i], TD_NULL);
|
||||
vdec_thread[i] = 0;
|
||||
}
|
||||
ss_mpi_vdec_stop_recv_stream(i);
|
||||
}
|
||||
}
|
||||
|
||||
td_void sample_comm_vdec_config_attr(ot_vdec_chn_attr *chn_attr, struct_vdec_attr *sample_vdec)
|
||||
{
|
||||
ot_pic_buf_attr buf_attr = { 0 };
|
||||
chn_attr->type = sample_vdec->type;
|
||||
chn_attr->mode = sample_vdec->mode;
|
||||
chn_attr->pic_width = sample_vdec->width;
|
||||
chn_attr->pic_height = sample_vdec->height;
|
||||
chn_attr->stream_buf_size = sample_vdec->width * sample_vdec->height;
|
||||
chn_attr->frame_buf_cnt = sample_vdec->frame_buf_cnt;
|
||||
buf_attr.align = 0;
|
||||
buf_attr.height = sample_vdec->height;
|
||||
buf_attr.width = sample_vdec->width;
|
||||
|
||||
if (sample_vdec->type == OT_PT_H264 || sample_vdec->type == OT_PT_H265) {
|
||||
buf_attr.bit_width = sample_vdec->member_vdec_video.bit_width;
|
||||
buf_attr.pixel_format = OT_PIXEL_FORMAT_YVU_SEMIPLANAR_420;
|
||||
chn_attr->video_attr.ref_frame_num = sample_vdec->member_vdec_video.ref_frame_num;
|
||||
chn_attr->video_attr.temporal_mvp_en = 1;
|
||||
if ((sample_vdec->type == OT_PT_H264) &&
|
||||
(sample_vdec->member_vdec_video.dec_mode != OT_VIDEO_DEC_MODE_IPB)) {
|
||||
chn_attr->video_attr.temporal_mvp_en = 0;
|
||||
}
|
||||
chn_attr->frame_buf_size = ot_vdec_get_pic_buf_size(chn_attr->type, &buf_attr);
|
||||
} else if (sample_vdec->type == OT_PT_JPEG || sample_vdec->type == OT_PT_MJPEG) {
|
||||
chn_attr->mode = OT_VDEC_SEND_MODE_FRAME;
|
||||
buf_attr.bit_width = OT_DATA_BIT_WIDTH_8;
|
||||
buf_attr.pixel_format = sample_vdec->member_vdec_picture.pixel_format;
|
||||
chn_attr->frame_buf_size = ot_vdec_get_pic_buf_size(chn_attr->type, &buf_attr);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
td_s32 sample_comm_config_ldy_attr(td_s32 i, td_u32 height)
|
||||
{
|
||||
ot_low_delay_info ldy_attr;
|
||||
if (g_vdec_line_ldy_en == TD_TRUE) {
|
||||
check_chn_return(ss_mpi_vdec_get_low_delay_attr(i, &ldy_attr), i, "ss_mpi_vdec_get_low_delay_attr");
|
||||
ldy_attr.enable = TD_TRUE;
|
||||
ldy_attr.line_cnt = SAMPLE_VDEC_LOW_DELAY_LINE_CNT;
|
||||
check_chn_return(ss_mpi_vdec_set_low_delay_attr(i, &ldy_attr), i, "ss_mpi_vdec_set_low_delay_attr");
|
||||
check_chn_return(ss_mpi_vdec_set_display_mode(i, OT_VIDEO_DISPLAY_MODE_PREVIEW), i,
|
||||
"ss_mpi_vdec_set_display_mode");
|
||||
}
|
||||
return TD_SUCCESS;
|
||||
}
|
||||
|
||||
td_s32 sample_comm_vdec_start(td_s32 chn_num, struct_vdec_attr *sample_vdec, td_u32 arr_len)
|
||||
{
|
||||
td_s32 i, ret;
|
||||
ot_vdec_chn_attr chn_attr[OT_VDEC_MAX_CHN_NUM];
|
||||
ot_vdec_chn_pool pool;
|
||||
ot_vdec_chn_param chn_param;
|
||||
ot_vdec_mod_param mod_param;
|
||||
|
||||
check_null_ptr_return(sample_vdec);
|
||||
if (arr_len > OT_VDEC_MAX_CHN_NUM) {
|
||||
sample_print("array size(%u) of chn_attr need < %u!\n", arr_len, OT_VDEC_MAX_CHN_NUM);
|
||||
return TD_FAILURE;
|
||||
}
|
||||
|
||||
check_return(ss_mpi_vdec_get_mod_param(&mod_param), "vdec get mod param");
|
||||
mod_param.vb_src = g_vdec_vb_src;
|
||||
check_return(ss_mpi_vdec_set_mod_param(&mod_param), "vdec set mod param");
|
||||
|
||||
for (i = 0; (i < chn_num) && (i < (td_s32)arr_len); i++) {
|
||||
sample_comm_vdec_config_attr(&chn_attr[i], &sample_vdec[i]);
|
||||
|
||||
check_chn_return(ss_mpi_vdec_create_chn(i, &chn_attr[i]), i, "vdec create chn");
|
||||
|
||||
if ((g_vdec_vb_src == OT_VB_SRC_USER) && (i < OT_VB_MAX_POOLS)) {
|
||||
pool.pic_vb_pool = g_pic_vb_pool[i];
|
||||
pool.tmv_vb_pool = g_tmv_vb_pool[i];
|
||||
check_chn_return(ss_mpi_vdec_attach_vb_pool(i, &pool), i, "vdec attach vb pool");
|
||||
}
|
||||
|
||||
check_chn_return(ss_mpi_vdec_get_chn_param(i, &chn_param), i, "vdec get chn param");
|
||||
if (sample_vdec[i].type == OT_PT_H264 || sample_vdec[i].type == OT_PT_H265 ||
|
||||
sample_vdec[i].type == OT_PT_MP4VIDEO) {
|
||||
chn_param.video_param.dec_mode = sample_vdec[i].member_vdec_video.dec_mode;
|
||||
chn_param.video_param.compress_mode = OT_COMPRESS_MODE_NONE;
|
||||
chn_param.video_param.video_format = OT_VIDEO_FORMAT_LINEAR;
|
||||
if (chn_param.video_param.dec_mode == OT_VIDEO_DEC_MODE_IPB) {
|
||||
chn_param.video_param.out_order = OT_VIDEO_OUT_ORDER_DISPLAY;
|
||||
} else {
|
||||
chn_param.video_param.out_order = OT_VIDEO_OUT_ORDER_DEC;
|
||||
}
|
||||
chn_param.video_param.slice_input_en = sample_comm_vdec_get_lowdelay_en();
|
||||
} else {
|
||||
chn_param.pic_param.pixel_format = sample_vdec[i].member_vdec_picture.pixel_format;
|
||||
chn_param.pic_param.alpha = sample_vdec[i].member_vdec_picture.alpha;
|
||||
}
|
||||
chn_param.display_frame_num = sample_vdec[i].display_frame_num;
|
||||
check_chn_return(ss_mpi_vdec_set_chn_param(i, &chn_param), i, "vdec set chn param");
|
||||
|
||||
ret = sample_comm_config_ldy_attr(i, chn_attr[i].pic_height);
|
||||
if (ret != TD_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
check_chn_return(ss_mpi_vdec_start_recv_stream(i), i, "vdec start recv stream");
|
||||
}
|
||||
|
||||
return TD_SUCCESS;
|
||||
}
|
||||
|
||||
td_s32 sample_comm_vdec_stop(td_s32 chn_num)
|
||||
{
|
||||
td_s32 i;
|
||||
|
||||
for (i = 0; i < chn_num; i++) {
|
||||
check_chn_return(ss_mpi_vdec_stop_recv_stream(i), i, "vdec stop recv stream");
|
||||
check_chn_return(ss_mpi_vdec_destroy_chn(i), i, "vdec destroy chn");
|
||||
}
|
||||
|
||||
return TD_SUCCESS;
|
||||
}
|
3194
ss928sdk/common/sample_comm_venc.c
Executable file
2839
ss928sdk/common/sample_comm_vi.c
Executable file
1015
ss928sdk/common/sample_comm_vo.c
Executable file
169
ss928sdk/common/sample_comm_vpss.c
Executable file
@ -0,0 +1,169 @@
|
||||
/*
|
||||
Copyright (c), 2001-2022, Shenshu Tech. Co., Ltd.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
#include "sample_comm.h"
|
||||
|
||||
#define VPSS_DEFAULT_WIDTH 3840
|
||||
#define VPSS_DEFAULT_HEIGHT 2160
|
||||
|
||||
td_void libapi_comm_vpss_get_default_grp_attr(ot_vpss_grp_attr *grp_attr)
|
||||
{
|
||||
grp_attr->nr_en = TD_TRUE;
|
||||
grp_attr->ie_en = TD_FALSE;
|
||||
grp_attr->dci_en = TD_FALSE;
|
||||
grp_attr->buf_share_en = TD_FALSE;
|
||||
grp_attr->mcf_en = TD_FALSE;
|
||||
grp_attr->max_width = VPSS_DEFAULT_WIDTH;
|
||||
grp_attr->max_height = VPSS_DEFAULT_HEIGHT;
|
||||
grp_attr->max_dei_width = 0;
|
||||
grp_attr->max_dei_height = 0;
|
||||
grp_attr->dynamic_range = OT_DYNAMIC_RANGE_SDR8;
|
||||
grp_attr->pixel_format = OT_PIXEL_FORMAT_YVU_SEMIPLANAR_420;
|
||||
grp_attr->dei_mode = OT_VPSS_DEI_MODE_OFF;
|
||||
grp_attr->buf_share_chn = OT_VPSS_CHN0;
|
||||
grp_attr->nr_attr.nr_type = OT_VPSS_NR_TYPE_VIDEO_NORM;
|
||||
grp_attr->nr_attr.compress_mode = OT_COMPRESS_MODE_FRAME;
|
||||
grp_attr->nr_attr.nr_motion_mode = OT_VPSS_NR_MOTION_MODE_NORM;
|
||||
grp_attr->frame_rate.src_frame_rate = -1;
|
||||
grp_attr->frame_rate.dst_frame_rate = -1;
|
||||
}
|
||||
|
||||
td_void libapi_comm_vpss_get_default_chn_attr(ot_vpss_chn_attr *chn_attr)
|
||||
{
|
||||
chn_attr->mirror_en = TD_FALSE;
|
||||
chn_attr->flip_en = TD_FALSE;
|
||||
chn_attr->border_en = TD_FALSE;
|
||||
chn_attr->width = VPSS_DEFAULT_WIDTH;
|
||||
chn_attr->height = VPSS_DEFAULT_HEIGHT;
|
||||
chn_attr->depth = 0;
|
||||
chn_attr->chn_mode = OT_VPSS_CHN_MODE_USER;
|
||||
chn_attr->video_format = OT_VIDEO_FORMAT_LINEAR;
|
||||
chn_attr->dynamic_range = OT_DYNAMIC_RANGE_SDR8;
|
||||
chn_attr->pixel_format = OT_PIXEL_FORMAT_YVU_SEMIPLANAR_420;
|
||||
chn_attr->compress_mode = OT_COMPRESS_MODE_SEG;
|
||||
chn_attr->aspect_ratio.mode = OT_ASPECT_RATIO_NONE;
|
||||
chn_attr->frame_rate.src_frame_rate = -1;
|
||||
chn_attr->frame_rate.dst_frame_rate = -1;
|
||||
}
|
||||
|
||||
static td_s32 sample_common_vpss_start_chn(ot_vpss_grp grp, const td_bool *chn_enable,
|
||||
const ot_vpss_chn_attr *chn_attr, td_u32 chn_array_size)
|
||||
{
|
||||
ot_vpss_chn vpss_chn;
|
||||
td_s32 ret, i;
|
||||
|
||||
for (i = 0; i < (td_s32)chn_array_size; ++i) {
|
||||
if (chn_enable[i] == TD_TRUE) {
|
||||
vpss_chn = i;
|
||||
ret = ss_mpi_vpss_set_chn_attr(grp, vpss_chn, &chn_attr[vpss_chn]);
|
||||
if (ret != TD_SUCCESS) {
|
||||
sample_print("ss_mpi_vpss_set_chn_attr failed with %#x\n", ret);
|
||||
goto disable_chn;
|
||||
}
|
||||
ret = ss_mpi_vpss_enable_chn(grp, vpss_chn);
|
||||
if (ret != TD_SUCCESS) {
|
||||
sample_print("ss_mpi_vpss_enable_chn failed with %#x\n", ret);
|
||||
goto disable_chn;
|
||||
}
|
||||
}
|
||||
}
|
||||
return TD_SUCCESS;
|
||||
|
||||
disable_chn:
|
||||
for (i = i - 1; i >= 0; i--) {
|
||||
if (chn_enable[i] == TD_TRUE) {
|
||||
vpss_chn = i;
|
||||
ret = ss_mpi_vpss_disable_chn(grp, vpss_chn);
|
||||
if (ret != TD_SUCCESS) {
|
||||
sample_print("ss_mpi_vpss_disable_chn failed with %#x!\n", ret);
|
||||
}
|
||||
}
|
||||
}
|
||||
return TD_FAILURE;
|
||||
}
|
||||
|
||||
td_s32 libapi_common_vpss_start(ot_vpss_grp grp, const td_bool *chn_enable,
|
||||
const ot_vpss_grp_attr *grp_attr, const ot_vpss_chn_attr *chn_attr, td_u32 chn_array_size)
|
||||
{
|
||||
td_s32 ret;
|
||||
if (chn_array_size < OT_VPSS_MAX_PHYS_CHN_NUM) {
|
||||
sample_print("array size(%u) of chn_enable and chn_attr need > %u!\n",
|
||||
chn_array_size, OT_VPSS_MAX_PHYS_CHN_NUM);
|
||||
return TD_FAILURE;
|
||||
}
|
||||
ret = ss_mpi_vpss_create_grp(grp, grp_attr);
|
||||
if (ret != TD_SUCCESS) {
|
||||
sample_print("ss_mpi_vpss_create_grp(grp:%d) failed with %#x!\n", grp, ret);
|
||||
return TD_FAILURE;
|
||||
}
|
||||
ret = ss_mpi_vpss_start_grp(grp);
|
||||
if (ret != TD_SUCCESS) {
|
||||
sample_print("ss_mpi_vpss_start_grp failed with %#x\n", ret);
|
||||
goto destroy_grp;
|
||||
}
|
||||
|
||||
ret = sample_common_vpss_start_chn(grp, chn_enable, chn_attr, OT_VPSS_MAX_PHYS_CHN_NUM);
|
||||
if (ret != TD_SUCCESS) {
|
||||
goto stop_grp;
|
||||
}
|
||||
|
||||
return TD_SUCCESS;
|
||||
|
||||
stop_grp:
|
||||
ret = ss_mpi_vpss_stop_grp(grp);
|
||||
if (ret != TD_SUCCESS) {
|
||||
sample_print("ss_mpi_vpss_stop_grp failed with %#x!\n", ret);
|
||||
}
|
||||
destroy_grp:
|
||||
ret = ss_mpi_vpss_destroy_grp(grp);
|
||||
if (ret != TD_SUCCESS) {
|
||||
sample_print("ss_mpi_vpss_destroy_grp failed with %#x!\n", ret);
|
||||
}
|
||||
return TD_FAILURE;
|
||||
}
|
||||
|
||||
td_s32 libapi_common_vpss_stop(ot_vpss_grp grp, const td_bool *chn_enable, td_u32 chn_array_size)
|
||||
{
|
||||
td_s32 i;
|
||||
td_s32 ret;
|
||||
ot_vpss_chn vpss_chn;
|
||||
|
||||
if (chn_array_size < OT_VPSS_MAX_PHYS_CHN_NUM) {
|
||||
sample_print("array size(%u) of chn_enable need > %u!\n", chn_array_size, OT_VPSS_MAX_PHYS_CHN_NUM);
|
||||
return TD_FAILURE;
|
||||
}
|
||||
|
||||
for (i = 0; i < OT_VPSS_MAX_PHYS_CHN_NUM; ++i) {
|
||||
if (chn_enable[i] == TD_TRUE) {
|
||||
vpss_chn = i;
|
||||
ret = ss_mpi_vpss_disable_chn(grp, vpss_chn);
|
||||
if (ret != TD_SUCCESS) {
|
||||
sample_print("ss_mpi_vpss_disable_chn failed with %#x!\n", ret);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ret = ss_mpi_vpss_stop_grp(grp);
|
||||
if (ret != TD_SUCCESS) {
|
||||
sample_print("ss_mpi_vpss_stop_grp failed with %#x!\n", ret);
|
||||
}
|
||||
|
||||
ret = ss_mpi_vpss_destroy_grp(grp);
|
||||
if (ret != TD_SUCCESS) {
|
||||
sample_print("ss_mpi_vpss_destroy_grp failed with %#x!\n", ret);
|
||||
}
|
||||
|
||||
return TD_SUCCESS;
|
||||
}
|
444
ss928sdk/include/autoconf.h
Executable file
@ -0,0 +1,444 @@
|
||||
/*
|
||||
Copyright (c), 2001-2022, Shenshu Tech. Co., Ltd.
|
||||
*/
|
||||
#ifndef __AUTOCONF_H__
|
||||
#define __AUTOCONF_H__
|
||||
|
||||
#define AUTOCONF_TIMESTAMP "2022-12-28 11:55:55 CST"
|
||||
|
||||
/*
|
||||
* General Setup
|
||||
*/
|
||||
#define CONFIG_SS928V100 1
|
||||
#define CONFIG_OT_CHIP_TYPE 0x01090100
|
||||
#define CONFIG_OT_ARCH "ss928v100"
|
||||
#define CONFIG_SUBCHIP_SS928V100 1
|
||||
#define CONFIG_OT_SUBARCH "ss928v100"
|
||||
#define CONFIG_OT_SUBCHIP_TYPE 0x01090100
|
||||
#define CONFIG_SMP 1
|
||||
#define CONFIG_ARM_ARCH_TYPE "smp"
|
||||
#define CONFIG_A55 1
|
||||
#define CONFIG_CPU_TYPE "a55"
|
||||
#define CONFIG_VERSION_ASIC 1
|
||||
#define CONFIG_OT_FPGA "n"
|
||||
#define CONFIG_LINUX_OS 1
|
||||
#define CONFIG_OS_TYPE "linux"
|
||||
#define CONFIG_PHYS_ADDR_BIT_WIDTH_64 1
|
||||
#define CONFIG_LINUX_4_19_y 1
|
||||
#define CONFIG_KERNEL_VERSION "linux-4.19.y"
|
||||
#define CONFIG_KERNEL_AARCH64_MIX210 1
|
||||
#define CONFIG_OT_CROSS "aarch64-mix210-linux-"
|
||||
#define CONFIG_LIBC_TYPE "glibc"
|
||||
#define CONFIG_KERNEL_BIT "KERNEL_BIT_64"
|
||||
#define CONFIG_USER_AARCH64_MIX210 1
|
||||
#define CONFIG_OT_CROSS_LIB "aarch64-mix210-linux-"
|
||||
#define CONFIG_USER_BIT "USER_BIT_64"
|
||||
#define CONFIG_LINUX_STYLE 1
|
||||
#define CONFIG_CODE_SYTLE "USE_LINUX_STYLE"
|
||||
#define CONFIG_RELEASE_TYPE_RELEASE 1
|
||||
#define CONFIG_OT_RLS_MODE "OT_RELEASE"
|
||||
#define CONFIG_OT_PLATFORM_V8 1
|
||||
|
||||
/*
|
||||
* Media Modules Setup
|
||||
*/
|
||||
|
||||
/*
|
||||
* media audio config
|
||||
*/
|
||||
#define CONFIG_OT_AUDIO_SUPPORT 1
|
||||
#define CONFIG_OT_ACODEC_SUPPORT 1
|
||||
#define CONFIG_OT_ACODEC_VERSION "RemixV100"
|
||||
#define CONFIG_OT_ACODEC_MAX_GAIN 56
|
||||
#define CONFIG_OT_ACODEC_MIN_GAIN 0
|
||||
#define CONFIG_OT_ACODEC_GAIN_STEP 3
|
||||
#define CONFIG_OT_ACODEC_FAST_POWER_SUPPORT 1
|
||||
#define CONFIG_OT_DOWNVQE_SUPPORT 1
|
||||
#define CONFIG_OT_TALKVQE_SUPPORT 1
|
||||
#define CONFIG_OT_RECORDVQE_SUPPORT 1
|
||||
#define CONFIG_OT_TALKVQEV2_SUPPORT 1
|
||||
#define CONFIG_OT_TALKVQEV2_WNR_SUPPORT 1
|
||||
#define CONFIG_OT_AUDIO_STATIC_REGISTER_SUPPORT 1
|
||||
|
||||
/*
|
||||
* media base config
|
||||
*/
|
||||
#define CONFIG_OT_VB_EXTPOOL_SUPPORT 1
|
||||
#define CONFIG_OT_VB_SUPPLEMENT_MASK_SUPPORT 1
|
||||
#define CONFIG_OT_VB_ASYNC_SUPPORT 1
|
||||
|
||||
/*
|
||||
* media chnl config
|
||||
*/
|
||||
#define CONFIG_OT_CHNL_SUPPORT 1
|
||||
|
||||
/*
|
||||
* media dis config
|
||||
*/
|
||||
#define CONFIG_OT_DIS_SUPPORT 1
|
||||
#define CONFIG_OT_DIS_SUBMIT_TO_VGS_SUPPORT 1
|
||||
|
||||
/*
|
||||
* media gdc config
|
||||
*/
|
||||
#define CONFIG_OT_GDC_SUPPORT 1
|
||||
#define CONFIG_OT_GDC_LOWDELAY_SUPPORT 1
|
||||
#define CONFIG_OT_GDC_FISHEYE_LMF_SUPPORT 1
|
||||
#define CONFIG_OT_GDC_FISHEYE_SUPPORT 1
|
||||
#define CONFIG_OT_GDC_LDC_SUPPORT 1
|
||||
#define CONFIG_OT_GDC_LDC_V3_SUPPORT 1
|
||||
#define CONFIG_OT_GDC_SPREAD_SUPPORT 1
|
||||
|
||||
/*
|
||||
* media hdmi config
|
||||
*/
|
||||
#define CONFIG_OT_HDMI_SUPPORT 1
|
||||
|
||||
/*
|
||||
* media isp config
|
||||
*/
|
||||
#define CONFIG_OT_ISP_SUPPORT 1
|
||||
#define CONFIG_OT_ISP_AF_SUPPORT 1
|
||||
#define CONFIG_OT_ISP_CR_SUPPORT 1
|
||||
#define CONFIG_OT_ISP_PREGAMMA_SUPPORT 1
|
||||
#define CONFIG_OT_ISP_GCAC_SUPPORT 1
|
||||
#define CONFIG_OT_ISP_CA_SUPPORT 1
|
||||
#define CONFIG_OT_ISP_EDGEMARK_SUPPORT 1
|
||||
#define CONFIG_OT_ISP_HLC_SUPPORT 1
|
||||
#define CONFIG_OT_ISP_SPECAWB_SUPPORT 1
|
||||
#define CONFIG_OT_ISP_DPC_STATIC_TABLE_SUPPORT 1
|
||||
#define CONFIG_OT_PQP_SUPPORT 1
|
||||
#define CONFIG_OT_ISP_HNR_SUPPORT 1
|
||||
|
||||
/*
|
||||
* media region config
|
||||
*/
|
||||
#define CONFIG_OT_REGION_SUPPORT 1
|
||||
#define CONFIG_OT_RGN_CORNER_RECT_SUPPORT 1
|
||||
|
||||
/*
|
||||
* media sys config
|
||||
*/
|
||||
#define CONFIG_OT_SYS_SUPPORT 1
|
||||
#define CONFIG_OT_SYS_SCALE_COEF_SUPPORT 1
|
||||
#define CONFIG_OT_SYS_SCALE_COEF_ONLINE_SUPPORT 1
|
||||
#define CONFIG_OT_SYS_SMMU_SUPPORT 1
|
||||
|
||||
/*
|
||||
* media tde config
|
||||
*/
|
||||
#define CONFIG_OT_TDE_SUPPORT 1
|
||||
|
||||
/*
|
||||
* media vda config
|
||||
*/
|
||||
|
||||
/*
|
||||
* media vdec config
|
||||
*/
|
||||
#define CONFIG_OT_VDEC_SUPPORT 1
|
||||
#define CONFIG_OT_H265D_SUPPORT 1
|
||||
#define CONFIG_OT_H264D_SUPPORT 1
|
||||
#define CONFIG_OT_JPEGD_SUPPORT 1
|
||||
#define CONFIG_OT_DEC_SHVC_SUPPORT 1
|
||||
#define CONFIG_VDEC_IP "VDEC_IP_VDH"
|
||||
#define CONFIG_OT_JPEGD_SUPPORT 1
|
||||
#define CONFIG_OT_JPEGD_PROGRESSIVE 1
|
||||
#define CONFIG_VDEC_ROTATION_SUPPORT 1
|
||||
#define CONFIG_VDEC_USERPIC_SUPPORT 1
|
||||
#define CONFIG_VDEC_USERDATA_SUPPORT 1
|
||||
#define CONFIG_VDEC_LOWDELAY_SUPPORT 1
|
||||
|
||||
/*
|
||||
* media venc config
|
||||
*/
|
||||
#define CONFIG_OT_VENC_SUPPORT 1
|
||||
#define CONFIG_OT_H265E_SUPPORT 1
|
||||
#define CONFIG_OT_H265E_USERDATA_SUPPORT 1
|
||||
#define CONFIG_OT_H265E_INTRA_REFRESH_SUPPORT 1
|
||||
#define CONFIG_OT_H264E_SUPPORT 1
|
||||
#define CONFIG_OT_H264E_USERDATA_SUPPORT 1
|
||||
#define CONFIG_OT_H264E_INTRA_REFRESH_SUPPORT 1
|
||||
#define CONFIG_OT_JPEGE_SUPPORT 1
|
||||
#define CONFIG_OT_JPEGE_ROI_SUPPORT 1
|
||||
#define CONFIG_OT_MJPEGE_SUPPORT 1
|
||||
#define CONFIG_OT_JPEGE_MPF_DCF_SUPPORT 1
|
||||
#define CONFIG_OT_JPEGE_USERDATA_SUPPORT 1
|
||||
#define CONFIG_OT_VENC_LOWDELAY_SUPPORT 1
|
||||
#define CONFIG_OT_VENC_VPSSAUTO_SUPPORT 1
|
||||
#define CONFIG_OT_VENC_FRAMEBUF_RECYCLE_SUPPORT 1
|
||||
#define CONFIG_OT_VENC_VGS_SUPPORT 1
|
||||
#define CONFIG_OT_VENC_SVC_SUPPORT 1
|
||||
#define CONFIG_OT_VENC_SMARTP_SUPPORT 1
|
||||
#define CONFIG_OT_VENC_DUALP_SUPPORT 1
|
||||
#define CONFIG_OT_VENC_RCNREF_SHARE_SUPPORT 1
|
||||
#define CONFIG_OT_VENC_DEBREATH_SUPPORT 1
|
||||
#define CONFIG_OT_VENC_SKIPREF_SUPPORT 1
|
||||
#define CONFIG_OT_VENC_SCENE0_SUPPORT 1
|
||||
#define CONFIG_OT_VENC_SCENE1_SUPPORT 1
|
||||
#define CONFIG_OT_VENC_SCENE2_SUPPORT 1
|
||||
#define CONFIG_OT_RC_AVBR_SUPPORT 1
|
||||
#define CONFIG_OT_RC_QPMAP_SUPPORT 1
|
||||
#define CONFIG_OT_RC_QVBR_SUPPORT 1
|
||||
#define CONFIG_OT_RC_CVBR_SUPPORT 1
|
||||
#define CONFIG_OT_VENC_COMPOSITE_SUPPORT 1
|
||||
|
||||
/*
|
||||
* media vgs config
|
||||
*/
|
||||
#define CONFIG_OT_VGS_SUPPORT 1
|
||||
#define CONFIG_OT_VGS_STITCH_SUPPORT 1
|
||||
#define CONFIG_OT_VGS_LUMA_STAT_SUPPORT 1
|
||||
#define CONFIG_OT_VGS_CORNER_RECT_SUPPORT 1
|
||||
#define CONFIG_OT_VGS_SHBD_SUPPORT 1
|
||||
#define CONFIG_OT_VGS_MCF_SUPPORT 1
|
||||
#define CONFIG_OT_VGS_LOW_DELAY_SUPPORT 1
|
||||
#define CONFIG_OT_VGS_FPD_SUPPORT 1
|
||||
#define CONFIG_OT_VGS_MULTI_CHN_SUPPORT 1
|
||||
#define CONFIG_OT_VGS_GME_SUPPORT 1
|
||||
#define CONFIG_OT_VGS_MOSAIC_ONLINE_SUPPORT 1
|
||||
#define CONFIG_OT_VGS_USER_ONLINE_SUPPORT 1
|
||||
|
||||
/*
|
||||
* media vi config
|
||||
*/
|
||||
#define CONFIG_OT_VI_SUPPORT 1
|
||||
#define CONFIG_OT_VI_ALL_SUPPORT 1
|
||||
#define CONFIG_OT_VI_DEV_BAS 1
|
||||
#define CONFIG_OT_VI_DEV_SEND_FRAME 1
|
||||
#define CONFIG_OT_VI_DEV_GENERATE_TIMING 1
|
||||
#define CONFIG_OT_VI_DEV_GENERATE_DATA 1
|
||||
#define CONFIG_OT_VI_VIRT_PIPE 1
|
||||
#define CONFIG_OT_VI_PIPE_PRE_CROP 1
|
||||
#define CONFIG_OT_VI_PIPE_POST_CROP 1
|
||||
#define CONFIG_OT_VI_PIPE_DUMP_FRAME 1
|
||||
#define CONFIG_OT_VI_PIPE_DUMP_PRIVATE_DATA 1
|
||||
#define CONFIG_OT_VI_PIPE_BAS 1
|
||||
#define CONFIG_OT_VI_PIPE_SEND_FRAME 1
|
||||
#define CONFIG_OT_VI_PIPE_INTERRUPT_EN 1
|
||||
#define CONFIG_OT_VI_PIPE_LOW_DELAY 1
|
||||
#define CONFIG_OT_VI_PIPE_FRAME_INTERRUPT_TYPE 1
|
||||
#define CONFIG_OT_VI_PIPE_GET_COMPRESS_PARAM 1
|
||||
#define CONFIG_OT_VI_PIPE_USER_PIC 1
|
||||
#define CONFIG_OT_VI_PIPE_FPN 1
|
||||
#define CONFIG_OT_VI_PIPE_IR_ASSIST_NR 1
|
||||
#define CONFIG_OT_VI_PIPE_BNR 1
|
||||
#define CONFIG_OT_VI_PIPE_HNR 1
|
||||
#define CONFIG_OT_VI_CHN_LOW_DELAY 1
|
||||
#define CONFIG_OT_VI_CHN_DIS 1
|
||||
#define CONFIG_OT_VI_CHN_ROTATION 1
|
||||
#define CONFIG_OT_VI_CHN_LDC 1
|
||||
#define CONFIG_OT_VI_CHN_SPREAD 1
|
||||
#define CONFIG_OT_VI_CHN_RGN_LUMA 1
|
||||
#define CONFIG_OT_VI_CHN_FOV_CORRECTION 1
|
||||
#define CONFIG_OT_VI_CHN_FISHEYE 1
|
||||
#define CONFIG_OT_VI_EXT_CHN 1
|
||||
#define CONFIG_OT_VI_STITCH_GRP 1
|
||||
#define CONFIG_OT_VI_PTS 1
|
||||
|
||||
/*
|
||||
* media vo config
|
||||
*/
|
||||
#define CONFIG_OT_VO_SUPPORT 1
|
||||
#define CONFIG_OT_VO_HD 1
|
||||
#define CONFIG_OT_VO_VPSS_AUTO 1
|
||||
#define CONFIG_OT_VO_PLAY_CTL 1
|
||||
#define CONFIG_OT_VO_LUMA 1
|
||||
#define CONFIG_OT_VO_COVER_OSD_SUPPORT 1
|
||||
#define CONFIG_OT_VO_CORNER_RECT_SUPPORT 1
|
||||
#define CONFIG_OT_VO_VIRTDEV_SUPPORT 1
|
||||
#define CONFIG_OT_VO_VGS 1
|
||||
#define CONFIG_OT_VO_GRAPH 1
|
||||
#define CONFIG_OT_VO_BATCH 1
|
||||
#define CONFIG_OT_VO_LOW_DELAY 1
|
||||
#define CONFIG_OT_VO_BORDER_BY_COVER 1
|
||||
#define CONFIG_OT_VO_CVBS 1
|
||||
#define CONFIG_OT_VO_RGB 1
|
||||
#define CONFIG_OT_VO_BT1120 1
|
||||
#define CONFIG_OT_VO_MIPI 1
|
||||
#define CONFIG_OT_VO_HDMI 1
|
||||
#define CONFIG_OT_VO_DEV_BYPASS 1
|
||||
#define CONFIG_OT_VO_EXPORT_FUNCTION 1
|
||||
#define CONFIG_OT_VO_FB_SEPARATE 1
|
||||
|
||||
/*
|
||||
* media vpss config
|
||||
*/
|
||||
#define CONFIG_OT_VPSS_SUPPORT 1
|
||||
#define CONFIG_OT_VPSS_ONLINE_SUPPORT 1
|
||||
#define CONFIG_OT_VPSS_SLAVE_SUPPORT 1
|
||||
#define CONFIG_OT_VPSS_3DNR_SUPPORT 1
|
||||
#define CONFIG_OT_VPSS_3DNR_GAMMA_SUPPORT 1
|
||||
#define CONFIG_OT_VPSS_3DNR_BNR_LINKAGE_SUPPORT 1
|
||||
#define CONFIG_OT_VPSS_3DNR_DELAY_MODE_SUPPORT 1
|
||||
#define CONFIG_OT_VPSS_AUTO_SUPPORT 1
|
||||
#define CONFIG_OT_VPSS_BACKUP_SUPPORT 1
|
||||
#define CONFIG_OT_VPSS_COVER_SUPPORT 1
|
||||
#define CONFIG_OT_VPSS_MOSAIC_SUPPORT 1
|
||||
#define CONFIG_OT_VPSS_DELAY_SUPPORT 1
|
||||
#define CONFIG_OT_VPSS_2SCALE_SUPPORT 1
|
||||
#define CONFIG_OT_VPSS_VGS_GRP_SUPPORT 1
|
||||
#define CONFIG_OT_VPSS_BUFFER_REUSE_SUPPORT 1
|
||||
#define CONFIG_OT_VPSS_LOW_DELAY_SUPPORT 1
|
||||
#define CONFIG_OT_VPSS_IPC_SUPPORT 1
|
||||
#define CONFIG_OT_VPSS_EXT_CHN_SUPPORT 1
|
||||
#define CONFIG_OT_VPSS_CHN_CROP_SUPPORT 1
|
||||
#define CONFIG_OT_VPSS_MCF_SUPPORT 1
|
||||
#define CONFIG_OT_VPSS_CHN_LDC_SUPPORT 1
|
||||
#define CONFIG_OT_VPSS_CHN_SPREAD_SUPPORT 1
|
||||
#define CONFIG_OT_VPSS_2DOF_SUPPORT 1
|
||||
|
||||
/*
|
||||
* media avs config
|
||||
*/
|
||||
#define CONFIG_OT_AVS_SUPPORT 1
|
||||
|
||||
/*
|
||||
* media vpp config
|
||||
*/
|
||||
#define CONFIG_OT_VPP_SUPPORT 1
|
||||
#define CONFIG_OT_VPP_FOV_CORRECTION_SUPPORT 1
|
||||
#define CONFIG_OT_VPP_BNR_SUPPORT 1
|
||||
#define CONFIG_OT_VPP_VI_SUPPORT 1
|
||||
#define CONFIG_OT_VPP_COVEREX_RATIO_SUPPORT 1
|
||||
|
||||
/*
|
||||
* media dcc config
|
||||
*/
|
||||
|
||||
/*
|
||||
* media uvc config
|
||||
*/
|
||||
#define CONFIG_OT_UVC_SUPPORT 1
|
||||
|
||||
/*
|
||||
* Device Driver Setup
|
||||
*/
|
||||
|
||||
/*
|
||||
* drv config
|
||||
*/
|
||||
#define CONFIG_DRV 1
|
||||
#define CONFIG_EXTDRV 1
|
||||
#define CONFIG_INTERDRV 1
|
||||
#define CONFIG_OT_USER 1
|
||||
#define CONFIG_MIPI_TX 1
|
||||
#define CONFIG_MIPI_RX 1
|
||||
#define CONFIG_OT_IR 1
|
||||
#define CONFIG_OT_LSADC 1
|
||||
#define CONFIG_OT_WDG 1
|
||||
#define CONFIG_OT_SYSCFG 1
|
||||
|
||||
/*
|
||||
* Component Setup
|
||||
*/
|
||||
|
||||
/*
|
||||
* Component security_subsys Config
|
||||
*/
|
||||
#define CONFIG_OT_SECURITY_SUBSYS_SUPPORT 1
|
||||
#define CONFIG_OT_CIPHER_SUPPORT 1
|
||||
#define CONFIG_OT_OTP_SUPPORT 1
|
||||
#define CONFIG_OT_KLAD_SUPPORT 1
|
||||
|
||||
/*
|
||||
* Component gfbg Config
|
||||
*/
|
||||
#define CONFIG_OT_GFBG_SUPPORT 1
|
||||
#define CONFIG_GFBG_DPU_V3 1
|
||||
|
||||
/*
|
||||
* Component ot_syslink Config
|
||||
*/
|
||||
|
||||
/*
|
||||
* Component pciv Config
|
||||
*/
|
||||
#define CONFIG_OT_PCIV_SUPPORT 1
|
||||
|
||||
/*
|
||||
* Component avs lut Config
|
||||
*/
|
||||
#define CONFIG_OT_AVS_LUT_SUPPORT 1
|
||||
|
||||
/*
|
||||
* Component avs convert Config
|
||||
*/
|
||||
#define CONFIG_OT_AVS_CONVERT_SUPPORT 1
|
||||
|
||||
/*
|
||||
* Component pos_query Config
|
||||
*/
|
||||
#define CONFIG_OT_POS_QUERY_SUPPORT 1
|
||||
|
||||
/*
|
||||
* Component snap Config
|
||||
*/
|
||||
#define CONFIG_OT_SNAP_SUPPORT 1
|
||||
|
||||
/*
|
||||
* Component photo Config
|
||||
*/
|
||||
#define CONFIG_OT_PHOTO_SUPPORT 1
|
||||
|
||||
/*
|
||||
* Component heif Config
|
||||
*/
|
||||
#define CONFIG_OT_HEIF_SUPPORT 1
|
||||
|
||||
/*
|
||||
* Component svp Config
|
||||
*/
|
||||
#define CONFIG_OT_SVP_SUPPORT 1
|
||||
#define CONFIG_OT_SVP_DSP 1
|
||||
#define CONFIG_OT_SVP_LITEOS 1
|
||||
#define CONFIG_OT_SVP_IVE 1
|
||||
#define CONFIG_OT_SVP_IVE_CSC 1
|
||||
#define CONFIG_OT_SVP_IVE_FILTER_AND_CSC 1
|
||||
#define CONFIG_OT_SVP_IVE_NCC 1
|
||||
#define CONFIG_OT_SVP_IVE_LBP 1
|
||||
#define CONFIG_OT_SVP_IVE_NORM_GRAD 1
|
||||
#define CONFIG_OT_SVP_IVE_ST_CANDI_CORNER 1
|
||||
#define CONFIG_OT_SVP_IVE_RESIZE 1
|
||||
#define CONFIG_OT_SVP_IVE_PERSP_TRANS 1
|
||||
#define CONFIG_OT_SVP_IVE_KCF 1
|
||||
#define CONFIG_OT_SVP_IVE_HOG 1
|
||||
#define CONFIG_OT_SVP_MD 1
|
||||
#define CONFIG_OT_SVP_MAU 1
|
||||
#define CONFIG_OT_SVP_NPU_V1R1 1
|
||||
#define CONFIG_OT_SVP_NPU_V1R1_COMPILE 1
|
||||
#define CONFIG_OT_SVP_NPU_V2R1 1
|
||||
#define CONFIG_OT_SVP_DPU_RECT 1
|
||||
#define CONFIG_OT_SVP_DPU_MATCH 1
|
||||
|
||||
/*
|
||||
* Component motionfusion config
|
||||
*/
|
||||
#define CONFIG_OT_MOTIONFUSION_SUPPORT 1
|
||||
|
||||
/*
|
||||
* Component mcf Config
|
||||
*/
|
||||
#define CONFIG_OT_MCF_SUPPORT 1
|
||||
|
||||
/*
|
||||
* Component securec Config
|
||||
*/
|
||||
#define CONFIG_OT_SECUREC_SUPPORT 1
|
||||
|
||||
/*
|
||||
* Debug Config
|
||||
*/
|
||||
#define CONFIG_OT_GDB_NO 1
|
||||
#define CONFIG_OT_GDB "n"
|
||||
#define CONFIG_OT_PROC_SHOW_SUPPORT 1
|
||||
#define CONFIG_OT_LOG_TRACE_SUPPORT 1
|
||||
#define CONFIG_OT_LOG_TRACE_ALL 1
|
||||
#define CONFIG_OT_LOG_TRACE_LEVEL 7
|
||||
|
||||
/*
|
||||
* Test Config
|
||||
*/
|
||||
|
||||
#endif /* __AUTOCONF_H__ */
|
||||
|
38
ss928sdk/include/eigen3/.gitignore
vendored
Executable file
@ -0,0 +1,38 @@
|
||||
qrc_*cxx
|
||||
*.orig
|
||||
*.pyc
|
||||
*.diff
|
||||
diff
|
||||
*.save
|
||||
save
|
||||
*.old
|
||||
*.gmo
|
||||
*.qm
|
||||
core
|
||||
core.*
|
||||
*.bak
|
||||
*~
|
||||
*build*
|
||||
*.moc.*
|
||||
*.moc
|
||||
ui_*
|
||||
CMakeCache.txt
|
||||
tags
|
||||
.*.swp
|
||||
activity.png
|
||||
*.out
|
||||
*.php*
|
||||
*.log
|
||||
*.orig
|
||||
*.rej
|
||||
log
|
||||
patch
|
||||
*.patch
|
||||
a
|
||||
a.*
|
||||
lapack/testing
|
||||
lapack/reference
|
||||
.*project
|
||||
.settings
|
||||
Makefile
|
||||
!ci/build.gitlab-ci.yml
|
23
ss928sdk/include/eigen3/.gitlab-ci.yml
Executable file
@ -0,0 +1,23 @@
|
||||
# This file is part of Eigen, a lightweight C++ template library
|
||||
# for linear algebra.
|
||||
#
|
||||
# Copyright (C) 2020 Arm Ltd. and Contributors
|
||||
#
|
||||
# This Source Code Form is subject to the terms of the Mozilla
|
||||
# Public License v. 2.0. If a copy of the MPL was not distributed
|
||||
# with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
stages:
|
||||
- buildsmoketests
|
||||
- smoketests
|
||||
- build
|
||||
- test
|
||||
|
||||
variables:
|
||||
BUILDDIR: builddir
|
||||
EIGEN_CI_CMAKE_GENEATOR: "Ninja"
|
||||
|
||||
include:
|
||||
- "/ci/smoketests.gitlab-ci.yml"
|
||||
- "/ci/build.gitlab-ci.yml"
|
||||
- "/ci/test.gitlab-ci.yml"
|
69
ss928sdk/include/eigen3/.gitlab/issue_templates/Bug Report.md
Executable file
@ -0,0 +1,69 @@
|
||||
<!--
|
||||
Please read this!
|
||||
|
||||
Before opening a new issue, make sure to search for keywords in the issues
|
||||
filtered by "bug::confirmed" or "bug::unconfirmed" and "bugzilla" label:
|
||||
|
||||
- https://gitlab.com/libeigen/eigen/-/issues?scope=all&utf8=%E2%9C%93&state=opened&label_name[]=bug%3A%3Aconfirmed
|
||||
- https://gitlab.com/libeigen/eigen/-/issues?scope=all&utf8=%E2%9C%93&state=opened&label_name[]=bug%3A%3Aunconfirmed
|
||||
- https://gitlab.com/libeigen/eigen/-/issues?scope=all&utf8=%E2%9C%93&state=opened&label_name[]=bugzilla
|
||||
|
||||
and verify the issue you're about to submit isn't a duplicate. -->
|
||||
|
||||
### Summary
|
||||
<!-- Summarize the bug encountered concisely. -->
|
||||
|
||||
### Environment
|
||||
<!-- Please provide your development environment here -->
|
||||
- **Operating System** : Windows/Linux
|
||||
- **Architecture** : x64/Arm64/PowerPC ...
|
||||
- **Eigen Version** : 3.3.9
|
||||
- **Compiler Version** : Gcc7.0
|
||||
- **Compile Flags** : -O3 -march=native
|
||||
- **Vector Extension** : SSE/AVX/NEON ...
|
||||
|
||||
### Minimal Example
|
||||
<!-- If possible, please create a minimal example here that exhibits the problematic behavior.
|
||||
You can also link to [godbolt](https://godbolt.org). But please note that you need to click
|
||||
the "Share" button in the top right-hand corner of the godbolt page where you reproduce the sample
|
||||
code to get the share link instead of in your browser address bar.
|
||||
|
||||
You can read [the guidelines on stackoverflow](https://stackoverflow.com/help/minimal-reproducible-example)
|
||||
on how to create a good minimal example. -->
|
||||
|
||||
```cpp
|
||||
//show your code here
|
||||
```
|
||||
|
||||
### Steps to reproduce
|
||||
<!-- Describe how one can reproduce the issue - this is very important. Please use an ordered list. -->
|
||||
|
||||
1. first step
|
||||
2. second step
|
||||
3. ...
|
||||
|
||||
### What is the current *bug* behavior?
|
||||
<!-- Describe what actually happens. -->
|
||||
|
||||
### What is the expected *correct* behavior?
|
||||
<!-- Describe what you should see instead. -->
|
||||
|
||||
### Relevant logs
|
||||
<!-- Add relevant code snippets or program output within blocks marked by " ``` " -->
|
||||
|
||||
<!-- OPTIONAL: remove this section if you are not reporting a compilation warning issue.-->
|
||||
### Warning Messages
|
||||
<!-- Show us the warning messages you got! -->
|
||||
|
||||
<!-- OPTIONAL: remove this section if you are not reporting a performance issue. -->
|
||||
### Benchmark scripts and results
|
||||
<!-- Please share any benchmark scripts - either standalone, or using [Google Benchmark](https://github.com/google/benchmark). -->
|
||||
|
||||
### Anything else that might help
|
||||
<!-- It will be better to provide us more information to help narrow down the cause.
|
||||
Including but not limited to the following:
|
||||
- lines of code that might help us diagnose the problem.
|
||||
- potential ways to address the issue.
|
||||
- last known working/first broken version (release number or commit hash). -->
|
||||
|
||||
- [ ] Have a plan to fix this issue.
|
7
ss928sdk/include/eigen3/.gitlab/issue_templates/Feature Request.md
Executable file
@ -0,0 +1,7 @@
|
||||
### Describe the feature you would like to be implemented.
|
||||
|
||||
### Would such a feature be useful for other users? Why?
|
||||
|
||||
### Any hints on how to implement the requested feature?
|
||||
|
||||
### Additional resources
|