first commit

This commit is contained in:
Your Name 2024-12-16 13:31:45 +08:00
commit 9e9bb7036c
2259 changed files with 471801 additions and 0 deletions

4
.gitignore vendored Executable file
View File

@ -0,0 +1,4 @@
bin
build
.vscode
output

3
.idea/.gitignore generated vendored Normal file
View File

@ -0,0 +1,3 @@
# Default ignored files
/shelf/
/workspace.xml

View 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
View 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
View 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
View 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
View 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
View 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
View 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
View File

@ -0,0 +1,8 @@
####!/bin/sh
mkdir -p build/
pushd build/
cmake ..
make -j8
popd

24
cmake/cmakebase.cmake Executable file
View 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
View 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
View 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
View 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
View 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

Binary file not shown.

BIN
doc/atc/yolov5s_v6.2.onnx Executable file

Binary file not shown.

BIN
doc/image.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1020 KiB

View 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")

View 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
View 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

Binary file not shown.

After

Width:  |  Height:  |  Size: 80 KiB

BIN
doc/other/wx.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 101 KiB

11
doc/rundemo.sh Executable file
View 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

Binary file not shown.

After

Width:  |  Height:  |  Size: 407 KiB

1166
libapi/LibApi.cpp Executable file

File diff suppressed because it is too large Load Diff

84
libapi/LibApi.h Executable file
View 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
View 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
View 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
View 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
View 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

File diff suppressed because it is too large Load Diff

103
libapi/ive/libapi_ive_main.h Executable file
View 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
View 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
View 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;
}

View 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
View 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
View 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 */

View 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
View 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;
}

View 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

Binary file not shown.

BIN
libapi/ive/model/resnet50.om Executable file

Binary file not shown.

BIN
libapi/ive/model/rfcn.om Executable file

Binary file not shown.

BIN
libapi/ive/res/1080P.h265 Executable file

Binary file not shown.

Binary file not shown.

BIN
libapi/ive/res/clut4.bmp Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

BIN
libapi/ive/res/mm.bmp Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 76 KiB

BIN
libapi/ive/res/mm16.bmp Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

BIN
libapi/ive/res/mm2.bmp Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

BIN
libapi/ive/res/vi_chn_0.bmp Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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;
}

View 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

View 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);
// }

View 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
View 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

File diff suppressed because it is too large Load Diff

1044
libapi/svp_npu/yolov5.cpp Executable file

File diff suppressed because it is too large Load Diff

132
libapi/sys/libapi_mem.c Executable file
View 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
View 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
View 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
View 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
View 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
View 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
View 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 $@

File diff suppressed because it is too large Load Diff

View 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

View 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;
}

View 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
View 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
View 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
View 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__ */

File diff suppressed because it is too large Load Diff

518
ss928sdk/common/sample_comm_isp.c Executable file
View 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);
}
}

View 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 */

File diff suppressed because it is too large Load Diff

587
ss928sdk/common/sample_comm_sys.c Executable file
View 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);
}

View 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

File diff suppressed because it is too large Load Diff

2839
ss928sdk/common/sample_comm_vi.c Executable file

File diff suppressed because it is too large Load Diff

1015
ss928sdk/common/sample_comm_vo.c Executable file

File diff suppressed because it is too large Load Diff

View 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
View 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
View 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

View 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"

View 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.

View 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

Some files were not shown because too many files have changed in this diff Show More