mirror of
https://github.com/LuckfoxTECH/luckfox-pico.git
synced 2026-01-18 03:28:19 +01:00
Pullrequest mis5001 clear patch 0305 (#242)
* project/app : Add uvc_app_tiny application Signed-off-by: luckfox-eng29 <eng29@luckfox.com> * project/cfg/BoardConfig_IPC/overlay : Add Ubuntu system support for Rockit and RKNN libraries Signed-off-by: luckfox-eng29 <eng29@luckfox.com> * sysdrv/source/kernel/drivers/of : Add support for dynamic device tree Signed-off-by: eng29 <eng29@luckfox.com> * sysdrv/source/kernel/drivers/usb/serial : Add CH343 driver support Signed-off-by: eng29 <eng29@luckfox.com> * sysdrv/source/kernel/drivers/staging : Disable partial logging of fbtft Signed-off-by: eng29 <eng29@luckfox.com> * sysdrv/source/kernel/drivers/pinctrl/pinctrl-rockchip.h : Fix pinctrl configuration failure issue Signed-off-by: eng29 <eng29@luckfox.com> * sysdrv/source/kernel/include/dt-bindings/soc/rockchip,boot-mode.h : Add support for the reboot U-Boot command in the BusyBox system Signed-off-by: eng29 <eng29@luckfox.com> * sysdrv/source/kernel/drivers/video : Add logo display support for LF40-480480-ARK and LF40-720720-ARK Signed-off-by: eng29 <eng29@luckfox.com> * sysdrv/source/kernel/arch/arm/boot/dts : Add device tree files for the Luckfox RV1103/RV1106 series boards Signed-off-by: eng29 <eng29@luckfox.com> * sysdrv/source/kernel/arch/arm/configs : Add device tree files for the Luckfox RV1103/RV1106 series boards Signed-off-by: eng29 <eng29@luckfox.com> * sysdrv/source/uboot/u-boot/drivers/mmc/mmc.c : Fix the issue where some Micro SD cards fail to boot Signed-off-by: eng29 <eng29@luckfox.com> * sysdrv/source/uboot/u-boot/common/image-fit.c : Add U-Boot support for luckfox-config Signed-off-by: eng29 <eng29@luckfox.com> * sysdrv/source/uboot/rkbin/bin/rv11 : Add firmware with a serial baud rate of 115200 and back up the original firmware Signed-off-by: eng29 <eng29@luckfox.com> * sysdrv/source/uboot/u-boot/arch/arm/dts : Add device tree files for the Luckfox RV1103/RV1106 series boards Signed-off-by: eng29 <eng29@luckfox.com> * sysdrv/source/uboot/u-boot/configs : Add defconfig files for the Luckfox RV1103/RV1106 series boards Signed-off-by: eng29 <eng29@luckfox.com> * sysdrv/source/uboot/u-boot : Add support for the reboot U-Boot command in the BusyBox system Signed-off-by: eng29 <eng29@luckfox.com> * sysdrv/source/kernel/drivers/media/i2c : Add MIS5001 driver support Signed-off-by: eng29 <eng29@luckfox.com> * sysdrv/source/kernel/arch/arm : Add default support for MIS5001 on Luckfox RV1106 series boards Signed-off-by: eng29 <eng29@luckfox.com> * sysdrv/tools/board : Delete irrelevant overwrite files and patch files Signed-off-by: eng29 <eng29@luckfox.com> * sysdrv/drv_ko/insmod_ko.sh : Register mis5001 driver during boot process Signed-off-by: luckfox-eng29 <eng29@luckfox.com> * media/isp/release_camera_engine_rkaiq_rv1106_arm-rockchip830-linux-uclibcgnueabihf/isp_iqfiles : Add mis5001 iqfile Signed-off-by: luckfox-eng29 <eng29@luckfox.com> * project/app/rkipc/rkipc/src/rv1106_ipc : Add rkipc application support for mis5001 sensor Signed-off-by: eng29 <eng29@luckfox.com> * project/cfg/BoardConfig_IPC : Enable default retrieval of mis5001 iqfile and include ROCKIT and RKNN libraries of RV1106 series board Signed-off-by: luckfox-eng29 <eng29@luckfox.com> * project/build.sh : Remove operations related to applying and deleting patches Signed-off-by: eng29 <eng29@luckfox.com> * project/build.sh : Modify build system menu description; Apply lightweight system processing only during Buildroot and BusyBox system compilation Signed-off-by: eng29 <eng29@luckfox.com> * sysdrv/tools/board/buildroot/luckfox_pico_w_defconfig : Add pppd and pgrep for 4G module Signed-off-by: luckfox-eng29 <eng29@luckfox.com> * sysdrv/tools/board/kernel/rv1106-luckfox-pico-ultra-ipc.dtsi : Add uart4m1 support for lastest luckfox-config tool Signed-off-by: eng29 <eng29@luckfox.com> --------- Signed-off-by: luckfox-eng29 <eng29@luckfox.com> Signed-off-by: eng29 <eng29@luckfox.com>
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -69,6 +69,7 @@ install(TARGETS ${PROJECT_NAME} RUNTIME DESTINATION bin)
|
||||
install(FILES rkipc-300w.ini DESTINATION share)
|
||||
install(FILES rkipc-400w.ini DESTINATION share)
|
||||
install(FILES rkipc-500w.ini DESTINATION share)
|
||||
install(FILES rkipc-mis5001-500w.ini DESTINATION share)
|
||||
install(FILES rkipc-800w.ini DESTINATION share)
|
||||
install(FILES ../../common/speaker_test.wav DESTINATION share)
|
||||
install(PROGRAMS RkLunch.sh DESTINATION bin)
|
||||
|
||||
@@ -73,6 +73,10 @@ post_chk() {
|
||||
default_rkipc_ini=/tmp/rkipc-factory-config.ini
|
||||
|
||||
if [ ! -f "/oem/usr/share/rkipc.ini" ]; then
|
||||
lsmod | grep mis5001
|
||||
if [ $? -eq 0 ]; then
|
||||
ln -s -f /oem/usr/share/rkipc-mis5001-500w.ini $default_rkipc_ini
|
||||
fi
|
||||
lsmod | grep sc530ai
|
||||
if [ $? -eq 0 ]; then
|
||||
ln -s -f /oem/usr/share/rkipc-500w.ini $default_rkipc_ini
|
||||
|
||||
542
project/app/rkipc/rkipc/src/rv1106_ipc/rkipc-mis5001-500w.ini
Normal file
542
project/app/rkipc/rkipc/src/rv1106_ipc/rkipc-mis5001-500w.ini
Normal file
@@ -0,0 +1,542 @@
|
||||
[audio.0]
|
||||
enable = 0
|
||||
card_name = hw:0,0
|
||||
encode_type = G711A
|
||||
format = S16
|
||||
sample_rate = 8000
|
||||
channels = 1
|
||||
frame_size = 1152
|
||||
bit_rate = 16000
|
||||
input = mic_in
|
||||
volume = 50
|
||||
enable_aed = 0
|
||||
enable_bcd = 0
|
||||
enable_vqe = 1
|
||||
vqe_cfg = /oem/usr/share/vqefiles/config_aivqe.json
|
||||
|
||||
[video.source]
|
||||
enable_aiq = 1
|
||||
enable_vo = 0
|
||||
vo_dev_id = 3 ; 0 is hdmi, 3 is mipi
|
||||
enable_ivs = 1
|
||||
enable_jpeg = 1
|
||||
enable_venc_0 = 1
|
||||
enable_venc_1 = 1
|
||||
enable_venc_2 = 0
|
||||
enable_npu = 0
|
||||
npu_fps = 10
|
||||
enable_rtsp = 1
|
||||
enable_rtmp = 0
|
||||
rotation = 0 ; available value:0 90 180 270
|
||||
|
||||
[video.0]
|
||||
buffer_size = 2519424 ; w * h / 2
|
||||
buffer_count = 4
|
||||
enable_refer_buffer_share = 1
|
||||
stream_type = mainStream
|
||||
video_type = compositeStream
|
||||
max_width = 2592
|
||||
max_height = 1944
|
||||
width = 2592
|
||||
height = 1944
|
||||
rc_mode = CBR
|
||||
rc_quality = high
|
||||
src_frame_rate_den = 1
|
||||
src_frame_rate_num = 25
|
||||
dst_frame_rate_den = 1
|
||||
dst_frame_rate_num = 25
|
||||
target_rate = 0
|
||||
mid_rate = 2048
|
||||
max_rate = 4096
|
||||
min_rate = 0
|
||||
output_data_type = H.265
|
||||
smart = close
|
||||
h264_profile = high
|
||||
gop = 50
|
||||
smartp_viridrlen = 25
|
||||
gop_mode = normalP
|
||||
stream_smooth = 50
|
||||
enable_motion_deblur = 1
|
||||
motion_deblur_strength = 3
|
||||
enable_motion_static_switch = 0
|
||||
frame_min_i_qp = 26
|
||||
frame_min_qp = 28
|
||||
frame_max_i_qp = 51
|
||||
frame_max_qp = 51
|
||||
scalinglist = 0
|
||||
enable_debreath_effect = 0
|
||||
debreath_effect_strength = 16
|
||||
thrd_i = 0,0,0,0,3,3,5,5,8,8,8,15,15,20,25,25
|
||||
thrd_p = 0,0,0,0,3,3,5,5,8,8,8,15,15,20,25,25
|
||||
aq_step_i = -8,-7,-6,-5,-4,-3,-2,-1,0,1,2,3,4,5,7,8
|
||||
aq_step_p = -8,-7,-6,-5,-4,-3,-2,-1,0,1,2,3,4,5,7,8
|
||||
qbias_enable = 1
|
||||
qbias_i = 171
|
||||
qbias_p = 85
|
||||
flt_str_i = 0
|
||||
flt_str_p = 0
|
||||
cu_dqp = 1
|
||||
anti_ring = 2
|
||||
anti_line = 2
|
||||
lambds = 4
|
||||
|
||||
[video.1]
|
||||
input_buffer_count = 2 ; only wrap can use one buffer
|
||||
buffer_size = 202752 ; w * h / 2
|
||||
buffer_count = 4
|
||||
enable_refer_buffer_share = 1
|
||||
stream_type = subStream
|
||||
video_type = compositeStream
|
||||
max_width = 704
|
||||
max_height = 576
|
||||
width = 704
|
||||
height = 576
|
||||
rc_mode = CBR
|
||||
rc_quality = high
|
||||
src_frame_rate_den = 1
|
||||
src_frame_rate_num = 25
|
||||
dst_frame_rate_den = 1
|
||||
dst_frame_rate_num = 25
|
||||
target_rate = 0
|
||||
mid_rate = 256
|
||||
max_rate = 512
|
||||
min_rate = 0
|
||||
output_data_type = H.265
|
||||
smart = close
|
||||
h264_profile = high
|
||||
gop = 50
|
||||
smartp_viridrlen = 25
|
||||
gop_mode = normalP
|
||||
stream_smooth = 50
|
||||
enable_motion_deblur = 1
|
||||
motion_deblur_strength = 3
|
||||
enable_motion_static_switch = 0
|
||||
frame_min_i_qp = 26
|
||||
frame_min_qp = 28
|
||||
frame_max_i_qp = 51
|
||||
frame_max_qp = 51
|
||||
scalinglist = 0
|
||||
enable_debreath_effect = 0
|
||||
debreath_effect_strength = 16
|
||||
cu_dqp = 1
|
||||
anti_ring = 2
|
||||
anti_line = 2
|
||||
lambds = 4
|
||||
|
||||
[video.2]
|
||||
max_width = 960
|
||||
max_height = 540
|
||||
width = 960
|
||||
height = 540
|
||||
|
||||
[ivs]
|
||||
smear = 0
|
||||
weightp = 0
|
||||
md = 1
|
||||
od = 1
|
||||
md_sensibility = 3 ;available: 1 2 3,max 3
|
||||
|
||||
[video.jpeg]
|
||||
width = 1920
|
||||
height = 1080
|
||||
jpeg_buffer_size = 1048576 ; 1024KB
|
||||
jpeg_qfactor = 70
|
||||
enable_cycle_snapshot = 0
|
||||
snapshot_interval_ms = 1000
|
||||
|
||||
[isp]
|
||||
scenario = normal ; normal or custom1
|
||||
init_form_ini = 1
|
||||
normal_scene = day
|
||||
custom1_scene = night
|
||||
ircut_open_gpio = 36
|
||||
ircut_close_gpio = 35
|
||||
|
||||
; isp.0
|
||||
[isp.0.adjustment]
|
||||
contrast = 50
|
||||
brightness = 50
|
||||
saturation = 50
|
||||
sharpness = 50
|
||||
fps = 25
|
||||
hue = 50
|
||||
|
||||
[isp.0.exposure]
|
||||
iris_type = auto
|
||||
exposure_mode = auto
|
||||
gain_mode = auto
|
||||
auto_iris_level = 5
|
||||
auto_exposure_enabled = 1
|
||||
audo_gain_enabled = 1
|
||||
exposure_time = 1/6
|
||||
exposure_gain = 1
|
||||
|
||||
[isp.0.night_to_day]
|
||||
night_to_day = day
|
||||
night_to_day_filter_level = 5
|
||||
night_to_day_filter_time = 5
|
||||
dawn_time = 07:00:00
|
||||
dusk_time = 18:00:00
|
||||
ircut_filter_action = day
|
||||
over_exposure_suppress = open
|
||||
over_exposure_suppress_type = auto
|
||||
fill_light_mode = IR
|
||||
brightness_adjustment_mode = auto
|
||||
light_brightness = 1
|
||||
distance_level = 1
|
||||
|
||||
[isp.0.blc]
|
||||
blc_region = close
|
||||
blc_strength = 1
|
||||
wdr = close
|
||||
wdr_level = 0
|
||||
hdr = close
|
||||
hdr_level = 1
|
||||
hlc = close
|
||||
hlc_level = 0
|
||||
dark_boost_level = 0
|
||||
position_x = 0
|
||||
position_y = 0
|
||||
blc_region_width = 120
|
||||
blc_region_high = 92
|
||||
|
||||
[isp.0.white_blance]
|
||||
white_blance_style = autoWhiteBalance
|
||||
white_blance_red = 50
|
||||
white_blance_green = 50
|
||||
white_blance_blue = 50
|
||||
|
||||
[isp.0.enhancement]
|
||||
noise_reduce_mode = close
|
||||
denoise_level = 50
|
||||
spatial_denoise_level = 50
|
||||
temporal_denoise_level = 50
|
||||
dehaze = close
|
||||
dehaze_level = 0
|
||||
dis = close
|
||||
gray_scale_mode = [0-255]
|
||||
distortion_correction = close
|
||||
ldch_level = 0
|
||||
|
||||
[isp.0.video_adjustment]
|
||||
image_flip = close
|
||||
scene_mode = indoor
|
||||
power_line_frequency_mode = PAL(50HZ)
|
||||
|
||||
[isp.0.auto_focus]
|
||||
af_mode = semi-auto
|
||||
zoom_level = 0
|
||||
focus_level = 0
|
||||
|
||||
; isp.1
|
||||
[isp.1.adjustment]
|
||||
contrast = 50
|
||||
brightness = 75
|
||||
saturation = 50
|
||||
sharpness = 50
|
||||
fps = 25
|
||||
hue = 50
|
||||
|
||||
[isp.1.exposure]
|
||||
iris_type = auto
|
||||
exposure_mode = auto
|
||||
gain_mode = auto
|
||||
auto_iris_level = 5
|
||||
auto_exposure_enabled = 1
|
||||
audo_gain_enabled = 1
|
||||
exposure_time = 1/6
|
||||
exposure_gain = 1
|
||||
|
||||
[isp.1.night_to_day]
|
||||
night_to_day = day
|
||||
night_to_day_filter_level = 5
|
||||
night_to_day_filter_time = 5
|
||||
dawn_time = 07:00:00
|
||||
dusk_time = 18:00:00
|
||||
ircut_filter_action = day
|
||||
over_exposure_suppress = open
|
||||
over_exposure_suppress_type = auto
|
||||
fill_light_mode = IR
|
||||
brightness_adjustment_mode = auto
|
||||
light_brightness = 1
|
||||
distance_level = 1
|
||||
|
||||
[isp.1.blc]
|
||||
blc_region = close
|
||||
blc_strength = 1
|
||||
wdr = close
|
||||
wdr_level = 0
|
||||
hdr = close
|
||||
hdr_level = 1
|
||||
hlc = close
|
||||
hlc_level = 0
|
||||
dark_boost_level = 0
|
||||
position_x = 0
|
||||
position_y = 0
|
||||
blc_region_width = 120
|
||||
blc_region_high = 92
|
||||
|
||||
[isp.1.white_blance]
|
||||
white_blance_style = autoWhiteBalance
|
||||
white_blance_red = 50
|
||||
white_blance_green = 50
|
||||
white_blance_blue = 50
|
||||
|
||||
[isp.1.enhancement]
|
||||
noise_reduce_mode = close
|
||||
denoise_level = 50
|
||||
spatial_denoise_level = 50
|
||||
temporal_denoise_level = 50
|
||||
dehaze = close
|
||||
dehaze_level = 0
|
||||
dis = close
|
||||
gray_scale_mode = [0-255]
|
||||
distortion_correction = close
|
||||
ldch_level = 0
|
||||
|
||||
[isp.1.video_adjustment]
|
||||
image_flip = close
|
||||
scene_mode = indoor
|
||||
power_line_frequency_mode = PAL(50HZ)
|
||||
|
||||
[isp.1.auto_focus]
|
||||
af_mode = semi-auto
|
||||
zoom_level = 0
|
||||
focus_level = 0
|
||||
|
||||
[storage]
|
||||
mount_path = /userdata
|
||||
free_size_del_min = 500; MB
|
||||
free_size_del_max = 1000; MB
|
||||
num_limit_enable = 1; limit by file num
|
||||
|
||||
[storage.0]
|
||||
enable = 0
|
||||
folder_name = video0
|
||||
file_format = mp4 ; flv,ts
|
||||
file_duration = 60
|
||||
video_quota = 30
|
||||
file_max_num = 300
|
||||
|
||||
[storage.1]
|
||||
enable = 0
|
||||
folder_name = video1
|
||||
file_format = mp4 ; flv,ts
|
||||
file_duration = 60
|
||||
video_quota = 30
|
||||
file_max_num = 300
|
||||
|
||||
[storage.2]
|
||||
enable = 0
|
||||
folder_name = video2
|
||||
file_format = mp4 ; flv,ts
|
||||
file_duration = 60
|
||||
video_quota = 30
|
||||
file_max_num = 300
|
||||
|
||||
[system.device_info]
|
||||
deivce_name = RK IP Camera
|
||||
telecontrol_id = 88
|
||||
model = RK-003
|
||||
serial_number = RK-003-A
|
||||
firmware_version = V0.2.6 build 202108
|
||||
encoder_version = V1.0 build 202108
|
||||
web_version = V2.12.2 build 202108
|
||||
plugin_version = V1.0.0.0
|
||||
channels_number = 1
|
||||
hard_disks_number = 1
|
||||
alarm_inputs_number = 0
|
||||
alarm_outputs_number = 0
|
||||
firmware_version_info = CP-3-B
|
||||
manufacturer = Rockchip
|
||||
hardware_id = c3d9b8674f4b94f6
|
||||
user_num = 1
|
||||
|
||||
[capability.video]
|
||||
0 = {"disabled":[{"name":"sStreamType","options":{"subStream":{"sSmart":"close"},"thirdStream":{"sSmart":"close"}},"type":"disabled/limit"},{"name":"sRCMode","options":{"CBR":{"sRCQuality":null}},"type":"disabled"},{"name":"sOutputDataType","options":{"H.265":{"sH264Profile":null}},"type":"disabled"},{"name":"unspport","options":{"iStreamSmooth":null,"sVideoType":null},"type":"disabled"}],"dynamic":{"sSmart":{"open":{"iMinRate":{"dynamicRange":{"max":"iMaxRate","maxRate":1,"min":"iMaxRate","minRate":0.125},"type":"dynamicRange"}}},"sStreamType":{"mainStream":{"iMaxRate":{"options":[256,512,1024,2048,3072,4096,6144],"type":"options"},"sResolution":{"options":["2880*1616","1920*1080","1280*720","960*540","640*360","320*240"],"type":"options"}},"subStream":{"iMaxRate"
|
||||
1 = :{"options":[128,256,512],"type":"options"},"sResolution":{"options":["704*576","640*480","352*288","320*240"],"type":"options"}},"thirdStream":{"iMaxRate":{"options":[256,512],"type":"options"},"sResolution":{"options":["416*416"],"type":"options"}}}},"layout":{"encoder":["sStreamType","sVideoType","sResolution","sRCMode","sRCQuality","sFrameRate","sOutputDataType","sSmart","sH264Profile","sGOPMode","iMaxRate","iGOP","iStreamSmooth"]},"static":{"iGOP":{"range":{"max":400,"min":1},"type":"range"},"iStreamSmooth":{"range":{"max":100,"min":1,"step":1},"type":"range"},"sFrameRate":{"dynamicRange":{"max":"sFrameRateIn","maxRate":1},"options":["1/2","1","2","4","6","8","10","12","14","16","18","20","25","30"],"type":"options/dynamicRange"},"sH264Profile":{"options":["high","main","baseline"],"type":"options"},"sOutputDataType":{"options"
|
||||
2 = :["H.264","H.265"],"type":"options"},"sRCMode":{"options":["CBR","VBR"],"type":"options"},"sRCQuality":{"options":["lowest","lower","low","medium","high","higher","highest"],"type":"options"},"sGOPMode":{"options":["normalP","smartP"],"type":"options"},"sSmart":{"options":["open","close"],"type":"options"},"sStreamType":{"options":["mainStream","subStream","thirdStream"],"type":"options"},"sVideoType":{"options":["videoStream","compositeStream"],"type":"options"}}}
|
||||
|
||||
[capability.image_adjustment]
|
||||
0 = {"layout":{"image_adjustment":["iBrightness","iContrast","iSaturation","iSharpness","iHue"]},"static":{"iBrightness":{"range":{"max":100,"min":0,"step":1},"type":"range"},"iContrast":{"range":{"max":100,"min":0,"step":1},"type":"range"},"iHue":{"range":{"max":100,"min":0,"step":1},"type":"range"},"iSaturation":{"range":{"max":100,"min":0,"step":1},"type":"range"},"iSharpness":{"range":{"max":100,"min":0,"step":1},"type":"range"}}}
|
||||
|
||||
[capability.image_blc]
|
||||
0 = {"disabled":[{"name":"sHLC","options":{"open":{"sBLCRegion":null}},"type":"disabled"},{"name":"sBLCRegion","options":{"open":{"iDarkBoostLevel":null,"iHLCLevel":null,"sHLC":null}},"type":"disabled"}],"dynamic":{"sBLCRegion":{"open":{"iBLCStrength":{"range":{"max":100,"min":0,"step":1},"type":"range"}}},"sHDR":{"HDR2":{"iHDRLevel":{"options":[1,2,3,4],"type":"options"}},"close":{"sBLCRegion":{"options":["close","open"],"type":"options"},"sHLC":{"options"
|
||||
1 = :["close","open"],"type":"options"}}},"sHLC":{"open":{"iDarkBoostLevel":{"range":{"max":100,"min":0,"step":1},"type":"range"},"iHLCLevel":{"range":{"max":100,"min":0,"step":1},"type":"range"}}},"sWDR":{"open":{"iWDRLevel":{"range":{"max":100,"min":0,"step":1},"type":"range"}}}},"layout":{"image_blc":["sHDR","iHDRLevel","sBLCRegion","iBLCStrength","sHLC","iHLCLevel"]},"static":{"sHDR":{"options":["close","HDR2"],"type":"options"}}}
|
||||
|
||||
[capability.image_enhancement]
|
||||
0 = {"dynamic":{"sDehaze":{"open":{"iDehazeLevel":{"range":{"max":10,"min":0,"step":1},"type":"range"}}},"sDistortionCorrection":{"FEC":{"iFecLevel":{"range":{"max":100,"min":0,"step":1},"type":"range"}},"LDCH":{"iLdchLevel":{"range":{"max":100,"min":0,"step":1},"type":"range"}}},"sNoiseReduceMode":{"2dnr":{"iSpatialDenoiseLevel":{"range":{"max":100,"min":0,"step":1},"type":"range"}},"3dnr":{"iTemporalDenoiseLevel":{"range":{"max":100,"min":0,"step":1},"type":"range"}},"mixnr":{"iSpatialDenoiseLevel":{"range":{"max":100,"min":0,"step":1},"type":"range"},"iTemporalDenoiseLevel":{"range":{"max":100,"min":0,"step":1},"type":"range"}}}},"layout"
|
||||
1 = :{"image_enhancement":["sNoiseReduceMode","iSpatialDenoiseLevel","iTemporalDenoiseLevel","sDehaze","iDehazeLevel","sGrayScaleMode","sDistortionCorrection","iLdchLevel","iFecLevel"]},"static":{"sDIS":{"options":["open","close"],"type":"options"},"sDehaze":{"options":["open","close","auto"],"type":"options"},"sDistortionCorrection":{"options":["LDCH","close"],"type":"options"},"sFEC":{"options":["open","close"],"type":"options"},"sGrayScaleMode":{"options":["[0-255]","[16-235]"],"type":"options"},"sNoiseReduceMode":{"options":["close","2dnr","3dnr","mixnr"],"type":"options"}}}
|
||||
|
||||
[capability.image_exposure]
|
||||
0 = {"dynamic":{"sExposureMode":{"auto":{"iAutoIrisLevel":{"range":{"max":100,"min":0,"step":1},"type":"range"}},"manual":{"sExposureTime":{"options":["1","1/3","1/6","1/12","1/25","1/50","1/100","1/150","1/200","1/250","1/500","1/750","1/1000","1/2000","1/4000","1/10000","1/100000"],"type":"options"},"sGainMode":{"options":["auto","manual"],"type":"options"}}},"sGainMode":{"manual":{"iExposureGain":{"range":{"max":100,"min":1,"step":1},"type":"range"}}}},"layout":{"image_exposure":["sExposureMode","sExposureTime","sGainMode","iExposureGain","iFPS"]},"static":{"sExposureMode":{"options":["auto","manual"],"type":"options"},"iFPS":{"range":{"max":30,"min":0,"step":1},"type":"range"}}}
|
||||
|
||||
[capability.image_night_to_day]
|
||||
0 = {"disabled":[{"name":"sNightToDay","options":{"day":{"iLightBrightness":null,"sFillLightMode":null},"night":{"iDarkBoostLevel":null,"iHDRLevel":null,"iHLCLevel":null,"sHDR":null,"sHLC":"close"}},"type":"disabled"}],"dynamic":{"sNightToDay":{"auto":{"iNightToDayFilterLevel":{"options":[0,1,2,3,4,5,6,7],"type":"options"},"iNightToDayFilterTime":{"range":{"max":10,"min":3,"step":1},"type":"range"}},"schedule":{"sDawnTime":{"input":"time","type":"input"},"sDuskTime":{"input":"time","type":"input"}}},"sOverexposeSuppress":{"open"
|
||||
1 = :{"sOverexposeSuppressType":{"options":["auto","manual"],"type":"options"}}},"sOverexposeSuppressType":{"manual":{"iDistanceLevel":{"range":{"max":100,"min":0,"step":1},"type":"range"}}}},"layout":{"image_night_to_day":["sNightToDay","iNightToDayFilterLevel","iNightToDayFilterTime","sDawnTime","sDuskTime","sFillLightMode","iLightBrightness"]},"static":{"iLightBrightness":{"range":{"max":100,"min":0,"step":10},"type":"range"},"sNightToDay":{"options":["day","night"],"type":"options"},"sFillLightMode":{"type":"options","options":["IR"]}}}
|
||||
|
||||
[capability.image_video_adjustment]
|
||||
0 = {"layout":{"image_video_adjustment":["sPowerLineFrequencyMode","sImageFlip","iImageRotation"]},"static":{"sImageFlip":{"options":["close","flip","mirror","centrosymmetric"],"type":"options"},"sPowerLineFrequencyMode":{"options":["PAL(50HZ)","NTSC(60HZ)"],"type":"options"},"sSceneMode":{"options":["indoor","outdoor"],"type":"options"},"iImageRotation":{"options":[0,90,180,270],"type":"options"}}}
|
||||
|
||||
[capability.image_white_blance]
|
||||
0 = {"dynamic":{"sWhiteBlanceStyle":{"manualWhiteBalance":{"iWhiteBalanceBlue":{"range":{"max":100,"min":0,"step":1},"type":"range"},"iWhiteBalanceGreen":{"range":{"max":100,"min":0,"step":1},"type":"range"},"iWhiteBalanceRed":{"range":{"max":100,"min":0,"step":1},"type":"range"}}}},"layout":{"image_white_blance":["sWhiteBlanceStyle","iWhiteBalanceRed","iWhiteBalanceGreen","iWhiteBalanceBlue"]},"static":{"sWhiteBlanceStyle":{"options":["manualWhiteBalance","autoWhiteBalance","lockingWhiteBalance","fluorescentLamp","incandescent","warmLight","naturalLight"],"type":"options"}}}
|
||||
|
||||
[user.0]
|
||||
user_name = admin
|
||||
password = YWRtaW4=
|
||||
user_level = 1 ; administrator=0 operator=1 user=2
|
||||
|
||||
[osd.common]
|
||||
enable_osd = 1
|
||||
is_presistent_text = 1
|
||||
attribute = transparent/not-flashing
|
||||
font_size = 32
|
||||
font_color_mode = customize
|
||||
font_color = fff799
|
||||
alignment = customize
|
||||
boundary = 0
|
||||
font_path = /oem/usr/share/simsun_en.ttf
|
||||
normalized_screen_width = 704
|
||||
normalized_screen_height = 480
|
||||
|
||||
[osd.0]
|
||||
type = channelName
|
||||
enabled = 0
|
||||
position_x = 1104
|
||||
position_y = 640
|
||||
display_text = Camera 01
|
||||
|
||||
[osd.1]
|
||||
type = dateTime
|
||||
enabled = 1
|
||||
position_x = 16
|
||||
position_y = 16
|
||||
date_style = CHR-YYYY-MM-DD
|
||||
time_style = 24hour
|
||||
display_week_enabled = 0
|
||||
|
||||
[osd.2]
|
||||
type = character
|
||||
enabled = 0
|
||||
position_x = 0
|
||||
position_y = 0
|
||||
display_text = null
|
||||
|
||||
[osd.3]
|
||||
type = character
|
||||
enabled = 0
|
||||
position_x = 0
|
||||
position_y = 0
|
||||
display_text = null
|
||||
|
||||
[osd.4]
|
||||
type = privacyMask
|
||||
enabled = 0
|
||||
position_x = 0
|
||||
position_y = 0
|
||||
width = 0
|
||||
height = 0
|
||||
|
||||
[osd.5]
|
||||
type = privacyMask
|
||||
enabled = 0
|
||||
position_x = 0
|
||||
position_y = 0
|
||||
width = 0
|
||||
height = 0
|
||||
|
||||
[osd.6]
|
||||
type = image
|
||||
enabled = 0
|
||||
position_x = 16
|
||||
position_y = 640
|
||||
image_path = /userdata/image.bmp
|
||||
|
||||
[event.regional_invasion]
|
||||
enabled = 1
|
||||
position_x = 0
|
||||
position_y = 0
|
||||
width = 700
|
||||
height = 560
|
||||
proportion = 1
|
||||
sensitivity_level = 90
|
||||
time_threshold = 1
|
||||
rockiva_model_type = small ;big medium small
|
||||
|
||||
[roi.0]
|
||||
stream_type = mainStream
|
||||
id = 1
|
||||
enabled = 0
|
||||
name = test
|
||||
position_x = 0
|
||||
position_y = 0
|
||||
width = 0
|
||||
height = 0
|
||||
quality_level = 3
|
||||
|
||||
[roi.1]
|
||||
stream_type = mainStream
|
||||
id = 2
|
||||
enabled = 0
|
||||
name = test
|
||||
position_x = 0
|
||||
position_y = 0
|
||||
width = 0
|
||||
height = 0
|
||||
quality_level = 3
|
||||
|
||||
[roi.2]
|
||||
stream_type = subStream
|
||||
id = 1
|
||||
enabled = 0
|
||||
name = test
|
||||
position_x = 0
|
||||
position_y = 0
|
||||
width = 0
|
||||
height = 0
|
||||
quality_level = 3
|
||||
|
||||
[roi.3]
|
||||
stream_type = subStream
|
||||
id = 2
|
||||
enabled = 0
|
||||
name = test
|
||||
position_x = 0
|
||||
position_y = 0
|
||||
width = 0
|
||||
height = 0
|
||||
quality_level = 3
|
||||
|
||||
[roi.4]
|
||||
stream_type = thirdStream
|
||||
id = 1
|
||||
enabled = 0
|
||||
name = test
|
||||
position_x = 0
|
||||
position_y = 0
|
||||
width = 0
|
||||
height = 0
|
||||
quality_level = 3
|
||||
|
||||
[roi.5]
|
||||
stream_type = thirdStream
|
||||
id = 2
|
||||
enabled = 0
|
||||
name = test
|
||||
position_x = 0
|
||||
position_y = 0
|
||||
width = 0
|
||||
height = 0
|
||||
quality_level = 3
|
||||
|
||||
[region_clip.1]
|
||||
enabled = 0
|
||||
position_x = 0
|
||||
position_y = 0
|
||||
width = 640
|
||||
height = 480
|
||||
|
||||
[network.ntp]
|
||||
enable = 1
|
||||
refresh_time_s = 60
|
||||
ntp_server = 119.28.183.184
|
||||
2
project/app/uvc_app_tiny/.gitignore
vendored
Normal file
2
project/app/uvc_app_tiny/.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
out/
|
||||
build/
|
||||
102
project/app/uvc_app_tiny/Makefile
Normal file
102
project/app/uvc_app_tiny/Makefile
Normal file
@@ -0,0 +1,102 @@
|
||||
|
||||
ifeq ($(APP_PARAM), )
|
||||
APP_PARAM:=../Makefile.param
|
||||
include $(APP_PARAM)
|
||||
endif
|
||||
|
||||
export LC_ALL=C
|
||||
SHELL:=/bin/bash
|
||||
|
||||
CURRENT_DIR := $(shell pwd)
|
||||
|
||||
PKG_NAME := uvc_app
|
||||
PKG_BIN ?= out
|
||||
PKG_BUILD ?= build
|
||||
|
||||
# debug: build cmake with more message
|
||||
# PKG_CONF_OPTS += -DCMAKE_VERBOSE_MAKEFILE=ON
|
||||
#
|
||||
RK_UVC_APP_CONFIG :=
|
||||
|
||||
ifeq ($(RK_ENABLE_FASTBOOT),y)
|
||||
PKG_CONF_OPTS += -DRK_ENABLE_FASTBOOT=ON
|
||||
RK_APP_OPTS += -DRK_ENABLE_FASTBOOT
|
||||
endif
|
||||
|
||||
ifeq ($(RK_APP_CHIP), rv1106)
|
||||
ifneq (, $(filter UVC_TINY, $(RK_APP_TYPE)))
|
||||
RK_UVC_APP_CONFIG := -DCOMPILE_FOR_MPI=ON
|
||||
else
|
||||
$(info ### disable make uvc demo)
|
||||
endif
|
||||
else
|
||||
$(info ### unknow RK_APP_CHIP)
|
||||
endif
|
||||
|
||||
RK_APP_CFLAGS = -I $(RK_APP_MEDIA_INCLUDE_PATH) \
|
||||
-I $(RK_APP_MEDIA_INCLUDE_PATH)/libdrm \
|
||||
-I $(RK_APP_MEDIA_INCLUDE_PATH)/rkaiq \
|
||||
-I $(RK_APP_MEDIA_INCLUDE_PATH)/rkaiq/uAPI \
|
||||
-I $(RK_APP_MEDIA_INCLUDE_PATH)/rkaiq/uAPI2 \
|
||||
-I $(RK_APP_MEDIA_INCLUDE_PATH)/rkaiq/algos \
|
||||
-I $(RK_APP_MEDIA_INCLUDE_PATH)/rkaiq/common \
|
||||
-I $(RK_APP_MEDIA_INCLUDE_PATH)/rkaiq/xcore \
|
||||
-I $(RK_APP_MEDIA_INCLUDE_PATH)/rkaiq/iq_parser \
|
||||
-I $(RK_APP_MEDIA_INCLUDE_PATH)/rkaiq/iq_parser_v2 \
|
||||
-I $(RK_APP_MEDIA_INCLUDE_PATH)/easymedia
|
||||
RK_APP_LDFLAGS = -L $(RK_APP_MEDIA_LIBS_PATH)
|
||||
|
||||
RK_APP_OPTS += -Wl,-rpath-link,$(RK_APP_MEDIA_LIBS_PATH):$(RK_APP_PATH_LIB_INCLUDE)/root/usr/lib
|
||||
PKG_CONF_OPTS += -DCMAKE_C_FLAGS="$(RK_APP_CFLAGS) $(RK_APP_LDFLAGS) $(RK_APP_OPTS)" \
|
||||
-DCMAKE_CXX_FLAGS="$(RK_APP_CFLAGS) $(RK_APP_LDFLAGS) $(RK_APP_OPTS)"
|
||||
|
||||
PKG_CONF_OPTS += -DUVC_APP_CROSS_COMPILE="$(RK_APP_CROSS)"
|
||||
|
||||
# define project/cfg/BoardConfig*.mk
|
||||
ifneq ($(RK_UVC_APP_CONFIG),)
|
||||
PKG_TARGET := uvc_app-build
|
||||
$(info ** $(PKG_NAME) build $(RK_APP_TYPE) **)
|
||||
endif
|
||||
|
||||
ifeq ($(PKG_BIN),)
|
||||
$(error ### $(CURRENT_DIR): PKG_BIN is NULL, Please Check !!!)
|
||||
endif
|
||||
|
||||
all: $(PKG_TARGET)
|
||||
@echo "build $(PKG_NAME) done"
|
||||
|
||||
uvc_app-build:
|
||||
@echo "RK_APP_CHIP is $(RK_APP_CHIP)"
|
||||
@echo "RK_APP_TYPE is $(RK_APP_TYPE)"
|
||||
rm -rf $(PKG_BIN) $(PKG_BUILD); \
|
||||
mkdir -p $(PKG_BIN);
|
||||
mkdir -p $(PKG_BUILD);
|
||||
pushd $(PKG_BUILD)/; \
|
||||
rm -rf CMakeCache.txt; \
|
||||
cmake $(CURRENT_DIR)/$(PKG_NAME)/ \
|
||||
-DCMAKE_C_COMPILER=$(RK_APP_CROSS)-gcc \
|
||||
-DCMAKE_CXX_COMPILER=$(RK_APP_CROSS)-g++ \
|
||||
-DCMAKE_INSTALL_PREFIX="$(CURRENT_DIR)/$(PKG_BIN)" \
|
||||
-DCMAKE_BUILD_TYPE=Release \
|
||||
-DCMAKE_COLOR_MAKEFILE=OFF \
|
||||
-DCMAKE_SYSTEM_NAME=Linux \
|
||||
$(RK_UVC_APP_CONFIG) \
|
||||
$(PKG_CONF_OPTS) ;\
|
||||
make -j$(RK_APP_JOBS) || exit -1; \
|
||||
make install; \
|
||||
popd;
|
||||
$(call MAROC_COPY_PKG_TO_APP_OUTPUT, $(RK_APP_OUTPUT), $(PKG_BIN))
|
||||
|
||||
clean:
|
||||
@rm -rf $(PKG_BIN) $(PKG_BUILD)
|
||||
|
||||
distclean: clean
|
||||
|
||||
info:
|
||||
ifneq ($(RK_UVC_APP_CONFIG),)
|
||||
@echo -e "$(C_YELLOW)-------------------------------------------------------------------------$(C_NORMAL)"
|
||||
@echo -e "RK_APP_TYPE=$(RK_APP_TYPE)"
|
||||
@echo -e "option support as follow:"
|
||||
@echo -e " UVC"
|
||||
@echo -e "$(C_YELLOW)-------------------------------------------------------------------------$(C_NORMAL)"
|
||||
endif
|
||||
81
project/app/uvc_app_tiny/config_ini/rkuvc.ini
Executable file
81
project/app/uvc_app_tiny/config_ini/rkuvc.ini
Executable file
@@ -0,0 +1,81 @@
|
||||
[video.source]
|
||||
enable_aiq = 1
|
||||
enable_vo = 0
|
||||
enable_npu = 0
|
||||
enable_uac = 0
|
||||
enable_2uvc = 0
|
||||
|
||||
[isp.0.adjustment]
|
||||
contrast = 50
|
||||
brightness = 50
|
||||
saturation = 50
|
||||
sharpness = 50
|
||||
fps = 30
|
||||
hue = 50
|
||||
|
||||
[isp.0.exposure]
|
||||
iris_type = auto
|
||||
exposure_mode = auto
|
||||
gain_mode = auto
|
||||
auto_iris_level = 5
|
||||
auto_exposure_enabled = 1
|
||||
audo_gain_enabled = 1
|
||||
exposure_time = 1/6
|
||||
exposure_gain = 1
|
||||
|
||||
[isp.0.night_to_day]
|
||||
night_to_day = day
|
||||
night_to_day_filter_level = 5
|
||||
night_to_day_filter_time = 5
|
||||
dawn_time = 07:00:00
|
||||
dusk_time = 18:00:00
|
||||
ircut_filter_action = day
|
||||
over_exposure_suppress = open
|
||||
over_exposure_suppress_type = auto
|
||||
fill_light_mode = IR
|
||||
brightness_adjustment_mode = auto
|
||||
light_brightness = 1
|
||||
distance_level = 1
|
||||
|
||||
[isp.0.blc]
|
||||
blc_region = close
|
||||
blc_strength = 1
|
||||
wdr = close
|
||||
wdr_level = 0
|
||||
hdr = close
|
||||
hdr_level = 1
|
||||
hlc = close
|
||||
hlc_level = 0
|
||||
dark_boost_level = 0
|
||||
position_x = 0
|
||||
position_y = 0
|
||||
blc_region_width = 120
|
||||
blc_region_high = 92
|
||||
|
||||
[isp.0.white_blance]
|
||||
white_blance_style = autoWhiteBalance
|
||||
white_blance_ct = 5000
|
||||
|
||||
[isp.0.enhancement]
|
||||
noise_reduce_mode = close
|
||||
denoise_level = 50
|
||||
spatial_denoise_level = 50
|
||||
temporal_denoise_level = 50
|
||||
dehaze = close
|
||||
dehaze_level = 0
|
||||
dis = close
|
||||
gray_scale_mode = [0-255]
|
||||
image_rotation = 0
|
||||
distortion_correction = close
|
||||
ldch_level = 0
|
||||
|
||||
[isp.0.video_adjustment]
|
||||
image_flip = close
|
||||
scene_mode = indoor
|
||||
power_line_frequency_mode = PAL(50HZ)
|
||||
|
||||
[isp.0.auto_focus]
|
||||
af_mode = semi-auto
|
||||
zoom_level = 0
|
||||
focus_level = 0
|
||||
|
||||
728
project/app/uvc_app_tiny/config_ini/uvc_mpi_cfg.conf
Executable file
728
project/app/uvc_app_tiny/config_ini/uvc_mpi_cfg.conf
Executable file
@@ -0,0 +1,728 @@
|
||||
{
|
||||
"index_0": {
|
||||
"version" : 1,
|
||||
"common_cfg": {
|
||||
"version" : 1,
|
||||
"property" : {
|
||||
"param_init": {
|
||||
"check_param_change_thread": "off",
|
||||
"uvc_debug": "off",
|
||||
"yuyv_debug": "off",
|
||||
"nn_enable": "off",
|
||||
"uvc_debug_file_name": "/data/uvc.bin",
|
||||
"uvc_debug_file_cnt": 0,
|
||||
"nn_debug_file_name": "/data/nn.bin",
|
||||
"nn_debug_file_cnt": 0,
|
||||
"uvc_enable_vpss": "off",
|
||||
"geometric_output": "16:9"
|
||||
},
|
||||
"param_change": {
|
||||
}
|
||||
}
|
||||
},
|
||||
"eptz_cfg": {
|
||||
"version" : 2,
|
||||
"param_init": {
|
||||
"enable": "on",
|
||||
"enable_boot": "off",
|
||||
"debug": "off",
|
||||
"align": 2,
|
||||
"zoom_speed": 3,
|
||||
"fast_move_frame_judge": 40,
|
||||
"zoom_frame_judge": 40,
|
||||
"iterate_x": 10,
|
||||
"iterate_y": 5,
|
||||
"ratio": 0.4
|
||||
},
|
||||
"param_change": {
|
||||
}
|
||||
},
|
||||
"vi_cfg": {
|
||||
"version" : 1,
|
||||
"uvc" : {
|
||||
"param_init": {
|
||||
"dev_id": 0,
|
||||
"channel_id": 0,
|
||||
"buf_cnt": 1,
|
||||
"assign_width": 0,
|
||||
"assign_height": 0,
|
||||
"min_width": 1920,
|
||||
"min_height": 1080,
|
||||
"max_width": 2880,
|
||||
"max_height": 1616,
|
||||
"format": "nv12",
|
||||
"dev_name": "null",
|
||||
"fps": "0:0",
|
||||
"memory_type": 4,
|
||||
"fbc": "off",
|
||||
"rotation": 0,
|
||||
"mirror": 0
|
||||
},
|
||||
"param_change": {
|
||||
}
|
||||
},
|
||||
"nn" : {
|
||||
"param_init": {
|
||||
"dev_id": 0,
|
||||
"channel_id": 1,
|
||||
"assign_width": 512,
|
||||
"assign_height": 288,
|
||||
"format": "nv12",
|
||||
"buf_cnt": 1,
|
||||
"dev_name": "null",
|
||||
"fps": "0:0",
|
||||
"memory_type": 4,
|
||||
"fbc": "off",
|
||||
"rotation": 0,
|
||||
"mirror": 0
|
||||
},
|
||||
"param_change": {
|
||||
}
|
||||
}
|
||||
},
|
||||
"vpss_cfg": {
|
||||
"version" : 1,
|
||||
"uvc" : {
|
||||
"param_init": {
|
||||
"group_id": 0,
|
||||
"channel_id": 0,
|
||||
"buf_cnt": 1,
|
||||
"fps": "0:0",
|
||||
"fbc": "off",
|
||||
"rotation": 0,
|
||||
"mirror": 0
|
||||
},
|
||||
"param_change": {
|
||||
}
|
||||
},
|
||||
"nn" : {
|
||||
"param_init": {
|
||||
"group_id": 1,
|
||||
"channel_id": 0,
|
||||
"format": "bgr888",
|
||||
"assign_width": 512,
|
||||
"assign_height": 288,
|
||||
"buf_cnt": 1,
|
||||
"fps": "0:0",
|
||||
"fbc": "off",
|
||||
"rotation": 0,
|
||||
"mirror": 0
|
||||
},
|
||||
"param_change": {
|
||||
}
|
||||
}
|
||||
},
|
||||
"venc_cfg": {
|
||||
"version" : 1,
|
||||
"common" : {
|
||||
"param_init": {
|
||||
"channel_id": 0,
|
||||
"rotation": 0,
|
||||
"mirror": 0
|
||||
},
|
||||
"param_change": {
|
||||
}
|
||||
},
|
||||
"mjpeg": {
|
||||
"param_init": {
|
||||
"default": {
|
||||
"buf_cnt": 2,
|
||||
"fbc": "off",
|
||||
"rc_mode": "fixqp",
|
||||
"fps": "0:0",
|
||||
"range": "full",
|
||||
"sei": "off",
|
||||
"qfactor": 85,
|
||||
"qfactor_min": 30,
|
||||
"qfactor_max": 99,
|
||||
"bps": 60000
|
||||
},
|
||||
"1280*720p30": {
|
||||
"qfactor": 80,
|
||||
"qfactor_min": 60,
|
||||
"qfactor_max": 90,
|
||||
"bps": 70000
|
||||
},
|
||||
"1920*1080p30": {
|
||||
"qfactor": 75,
|
||||
"qfactor_min": 50,
|
||||
"qfactor_max": 90,
|
||||
"bps": 80000
|
||||
},
|
||||
"2560*1440p30": {
|
||||
"qfactor": 70,
|
||||
"qfactor_min": 50,
|
||||
"qfactor_max": 90,
|
||||
"bps": 90000
|
||||
},
|
||||
"2880*1616@30": {
|
||||
"qfactor": 70,
|
||||
"qfactor_min": 50,
|
||||
"qfactor_max": 90,
|
||||
"bps": 90000
|
||||
}
|
||||
},
|
||||
"param_change": {
|
||||
}
|
||||
},
|
||||
"h264" : {
|
||||
"param_init": {
|
||||
"default": {
|
||||
"buf_cnt": 2,
|
||||
"fbc": "off",
|
||||
"gop": 60,
|
||||
"rc_mode": "cbr",
|
||||
"fps": "0:0",
|
||||
"range": "full",
|
||||
"qp": "26:4:20:40:8:48:2:1",
|
||||
"sei": "off",
|
||||
"profile": 100,
|
||||
"vi_len": 30,
|
||||
"gop_mode": 0,
|
||||
"bps": 10000,
|
||||
"force_idr": "5:5:20000"
|
||||
},
|
||||
"1920*1080p30": {
|
||||
"bps": 10000,
|
||||
"force_idr": "5:5:30000"
|
||||
},
|
||||
"2880*1616p30": {
|
||||
"bps": 15000,
|
||||
"force_idr": "5:5:40000"
|
||||
},
|
||||
"2560*1440p30": {
|
||||
"bps": 15000,
|
||||
"force_idr": "5:5:40000"
|
||||
}
|
||||
},
|
||||
"param_change": {
|
||||
}
|
||||
},
|
||||
"h265" : {
|
||||
"param_init": {
|
||||
"default": {
|
||||
"buf_cnt": 2,
|
||||
"fbc": "off",
|
||||
"gop": 60,
|
||||
"rc_mode": "cbr",
|
||||
"fps": "0:0",
|
||||
"range": "full",
|
||||
"qp": "26:4:20:40:8:48:2:1",
|
||||
"sei": "off",
|
||||
"vi_len": 30,
|
||||
"gop_mode": 0,
|
||||
"bps": 10000,
|
||||
"force_idr": "5:5:20000"
|
||||
},
|
||||
"1920*1080p30": {
|
||||
"bps": 10000,
|
||||
"force_idr": "5:5:30000"
|
||||
},
|
||||
"2560*1440p30": {
|
||||
"bps": 15000,
|
||||
"force_idr": "5:5:40000"
|
||||
},
|
||||
"2880*1616p30": {
|
||||
"bps": 15000,
|
||||
"force_idr": "5:5:40000"
|
||||
}
|
||||
},
|
||||
"param_change": {
|
||||
}
|
||||
}
|
||||
},
|
||||
"osd_cfg": {
|
||||
"version" : 1,
|
||||
"param_init": {
|
||||
"enable": "off",
|
||||
"force_use_vpss": "off"
|
||||
},
|
||||
"param_change": {
|
||||
}
|
||||
}
|
||||
},
|
||||
"index_1": {
|
||||
"version" : 1,
|
||||
"common_cfg": {
|
||||
"version" : 1,
|
||||
"property" : {
|
||||
"param_init": {
|
||||
"check_param_change_thread": "off",
|
||||
"uvc_debug": "off",
|
||||
"yuyv_debug": "off",
|
||||
"nn_enable": "off",
|
||||
"uvc_debug_file_name": "/data/uvc1.bin",
|
||||
"uvc_debug_file_cnt": 0,
|
||||
"nn_debug_file_name": "/data/nn1.bin",
|
||||
"nn_debug_file_cnt": 0,
|
||||
"uvc_enable_vpss": "off",
|
||||
"geometric_output": "16:9"
|
||||
},
|
||||
"param_change": {
|
||||
}
|
||||
}
|
||||
},
|
||||
"eptz_cfg": {
|
||||
"version" : 2,
|
||||
"param_init": {
|
||||
"enable": "on",
|
||||
"enable_boot": "off",
|
||||
"debug": "off",
|
||||
"align": 2,
|
||||
"zoom_speed": 3,
|
||||
"fast_move_frame_judge": 40,
|
||||
"zoom_frame_judge": 40,
|
||||
"iterate_x": 10,
|
||||
"iterate_y": 5,
|
||||
"ratio": 0.4
|
||||
},
|
||||
"param_change": {
|
||||
}
|
||||
},
|
||||
"vi_cfg": {
|
||||
"version" : 1,
|
||||
"uvc" : {
|
||||
"param_init": {
|
||||
"dev_id": 1,
|
||||
"channel_id": 0,
|
||||
"buf_cnt": 1,
|
||||
"assign_width": 0,
|
||||
"assign_height": 0,
|
||||
"min_width": 1280,
|
||||
"min_height": 720,
|
||||
"max_width": 2880,
|
||||
"max_height": 1616,
|
||||
"format": "nv12",
|
||||
"dev_name": "null",
|
||||
"fps": "0:0",
|
||||
"memory_type": 4,
|
||||
"fbc": "off",
|
||||
"rotation": 0,
|
||||
"mirror": 0
|
||||
},
|
||||
"param_change": {
|
||||
}
|
||||
},
|
||||
"nn" : {
|
||||
"param_init": {
|
||||
"dev_id": 1,
|
||||
"channel_id": 1,
|
||||
"assign_width": 512,
|
||||
"assign_height": 288,
|
||||
"format": "nv12",
|
||||
"buf_cnt": 1,
|
||||
"dev_name": "null",
|
||||
"fps": "0:0",
|
||||
"memory_type": 4,
|
||||
"fbc": "off",
|
||||
"rotation": 0,
|
||||
"mirror": 0
|
||||
},
|
||||
"param_change": {
|
||||
}
|
||||
}
|
||||
},
|
||||
"vpss_cfg": {
|
||||
"version" : 1,
|
||||
"uvc" : {
|
||||
"param_init": {
|
||||
"group_id": 1,
|
||||
"channel_id": 0,
|
||||
"buf_cnt": 1,
|
||||
"fps": "0:0",
|
||||
"fbc": "off",
|
||||
"rotation": 0,
|
||||
"mirror": 0
|
||||
},
|
||||
"param_change": {
|
||||
}
|
||||
},
|
||||
"nn" : {
|
||||
"param_init": {
|
||||
"group_id": 1,
|
||||
"channel_id": 0,
|
||||
"format": "bgr888",
|
||||
"assign_width": 512,
|
||||
"assign_height": 288,
|
||||
"buf_cnt": 1,
|
||||
"fps": "0:0",
|
||||
"fbc": "off",
|
||||
"rotation": 0,
|
||||
"mirror": 0
|
||||
},
|
||||
"param_change": {
|
||||
}
|
||||
}
|
||||
},
|
||||
"venc_cfg": {
|
||||
"version" : 1,
|
||||
"common" : {
|
||||
"param_init": {
|
||||
"channel_id": 1,
|
||||
"rotation": 0,
|
||||
"mirror": 0
|
||||
},
|
||||
"param_change": {
|
||||
}
|
||||
},
|
||||
"mjpeg": {
|
||||
"param_init": {
|
||||
"default": {
|
||||
"buf_cnt": 2,
|
||||
"fbc": "off",
|
||||
"rc_mode": "fixqp",
|
||||
"fps": "0:0",
|
||||
"range": "full",
|
||||
"sei": "off",
|
||||
"qfactor": 85,
|
||||
"qfactor_min": 30,
|
||||
"qfactor_max": 99,
|
||||
"bps": 60000
|
||||
},
|
||||
"1280*720p30": {
|
||||
"qfactor": 80,
|
||||
"qfactor_min": 60,
|
||||
"qfactor_max": 90,
|
||||
"bps": 70000
|
||||
},
|
||||
"1920*1080p30": {
|
||||
"qfactor": 75,
|
||||
"qfactor_min": 50,
|
||||
"qfactor_max": 90,
|
||||
"bps": 80000
|
||||
},
|
||||
"2560*1440p30": {
|
||||
"qfactor": 70,
|
||||
"qfactor_min": 50,
|
||||
"qfactor_max": 90,
|
||||
"bps": 90000
|
||||
},
|
||||
"2880*1616@30": {
|
||||
"qfactor": 70,
|
||||
"qfactor_min": 50,
|
||||
"qfactor_max": 90,
|
||||
"bps": 90000
|
||||
}
|
||||
},
|
||||
"param_change": {
|
||||
}
|
||||
},
|
||||
"h264" : {
|
||||
"param_init": {
|
||||
"default": {
|
||||
"buf_cnt": 2,
|
||||
"fbc": "off",
|
||||
"gop": 60,
|
||||
"rc_mode": "cbr",
|
||||
"fps": "0:0",
|
||||
"range": "full",
|
||||
"qp": "26:4:20:40:8:48:2:1",
|
||||
"sei": "off",
|
||||
"profile": 100,
|
||||
"vi_len": 30,
|
||||
"gop_mode": 0,
|
||||
"bps": 10000,
|
||||
"force_idr": "5:5:20000"
|
||||
},
|
||||
"1920*1080p30": {
|
||||
"bps": 10000,
|
||||
"force_idr": "5:5:30000"
|
||||
},
|
||||
"2560*1440p30": {
|
||||
"bps": 15000,
|
||||
"force_idr": "5:5:40000"
|
||||
},
|
||||
"2880*1616p30": {
|
||||
"bps": 15000,
|
||||
"force_idr": "5:5:40000"
|
||||
}
|
||||
},
|
||||
"param_change": {
|
||||
}
|
||||
},
|
||||
"h265" : {
|
||||
"param_init": {
|
||||
"default": {
|
||||
"buf_cnt": 2,
|
||||
"fbc": "off",
|
||||
"gop": 60,
|
||||
"rc_mode": "cbr",
|
||||
"fps": "0:0",
|
||||
"range": "full",
|
||||
"qp": "26:4:20:40:8:48:2:1",
|
||||
"sei": "off",
|
||||
"vi_len": 30,
|
||||
"gop_mode": 0,
|
||||
"bps": 10000,
|
||||
"force_idr": "5:5:20000"
|
||||
},
|
||||
"1920*1080p30": {
|
||||
"bps": 10000,
|
||||
"force_idr": "5:5:30000"
|
||||
},
|
||||
"2560*1440p30": {
|
||||
"bps": 15000,
|
||||
"force_idr": "5:5:40000"
|
||||
},
|
||||
"2880*1616p30": {
|
||||
"bps": 15000,
|
||||
"force_idr": "5:5:40000"
|
||||
}
|
||||
},
|
||||
"param_change": {
|
||||
}
|
||||
}
|
||||
},
|
||||
"osd_cfg": {
|
||||
"version" : 1,
|
||||
"param_init": {
|
||||
"enable": "off",
|
||||
"force_use_vpss": "off"
|
||||
},
|
||||
"param_change": {
|
||||
}
|
||||
}
|
||||
},
|
||||
"index_2": {
|
||||
"version" : 1,
|
||||
"common_cfg": {
|
||||
"version" : 1,
|
||||
"property" : {
|
||||
"param_init": {
|
||||
"check_param_change_thread": "off",
|
||||
"uvc_debug": "off",
|
||||
"yuyv_debug": "off",
|
||||
"nn_enable": "off",
|
||||
"uvc_debug_file_name": "/data/uvc2.bin",
|
||||
"uvc_debug_file_cnt": 0,
|
||||
"nn_debug_file_name": "/data/nn2.bin",
|
||||
"nn_debug_file_cnt": 0,
|
||||
"uvc_enable_vpss": "off",
|
||||
"geometric_output": "16:9"
|
||||
},
|
||||
"param_change": {
|
||||
}
|
||||
}
|
||||
},
|
||||
"eptz_cfg": {
|
||||
"version" : 2,
|
||||
"param_init": {
|
||||
"enable": "on",
|
||||
"enable_boot": "off",
|
||||
"debug": "off",
|
||||
"align": 2,
|
||||
"zoom_speed": 3,
|
||||
"fast_move_frame_judge": 40,
|
||||
"zoom_frame_judge": 40,
|
||||
"iterate_x": 10,
|
||||
"iterate_y": 5,
|
||||
"ratio": 0.4
|
||||
},
|
||||
"param_change": {
|
||||
}
|
||||
},
|
||||
"vi_cfg": {
|
||||
"version" : 1,
|
||||
"uvc" : {
|
||||
"param_init": {
|
||||
"dev_id": 2,
|
||||
"channel_id": 0,
|
||||
"buf_cnt": 1,
|
||||
"assign_width": 0,
|
||||
"assign_height": 0,
|
||||
"min_width": 640,
|
||||
"min_height": 480,
|
||||
"max_width": 2880,
|
||||
"max_height": 1616,
|
||||
"format": "nv12",
|
||||
"dev_name": "null",
|
||||
"fps": "0:0",
|
||||
"memory_type": 4,
|
||||
"fbc": "off",
|
||||
"rotation": 0,
|
||||
"mirror": 0
|
||||
},
|
||||
"param_change": {
|
||||
}
|
||||
},
|
||||
"nn" : {
|
||||
"param_init": {
|
||||
"dev_id": 2,
|
||||
"channel_id": 1,
|
||||
"assign_width": 512,
|
||||
"assign_height": 288,
|
||||
"format": "nv12",
|
||||
"buf_cnt": 1,
|
||||
"dev_name": "null",
|
||||
"fps": "0:0",
|
||||
"memory_type": 4,
|
||||
"fbc": "off",
|
||||
"rotation": 0,
|
||||
"mirror": 0
|
||||
},
|
||||
"param_change": {
|
||||
}
|
||||
}
|
||||
},
|
||||
"vpss_cfg": {
|
||||
"version" : 1,
|
||||
"uvc" : {
|
||||
"param_init": {
|
||||
"group_id": 2,
|
||||
"channel_id": 0,
|
||||
"buf_cnt": 1,
|
||||
"fps": "0:0",
|
||||
"fbc": "off",
|
||||
"rotation": 0,
|
||||
"mirror": 0
|
||||
},
|
||||
"param_change": {
|
||||
}
|
||||
},
|
||||
"nn" : {
|
||||
"param_init": {
|
||||
"group_id": 1,
|
||||
"channel_id": 0,
|
||||
"format": "bgr888",
|
||||
"assign_width": 512,
|
||||
"assign_height": 288,
|
||||
"buf_cnt": 1,
|
||||
"fps": "0:0",
|
||||
"fbc": "off",
|
||||
"rotation": 0,
|
||||
"mirror": 0
|
||||
},
|
||||
"param_change": {
|
||||
}
|
||||
}
|
||||
},
|
||||
"venc_cfg": {
|
||||
"version" : 1,
|
||||
"common" : {
|
||||
"param_init": {
|
||||
"channel_id": 2,
|
||||
"rotation": 0,
|
||||
"mirror": 0
|
||||
},
|
||||
"param_change": {
|
||||
}
|
||||
},
|
||||
"mjpeg": {
|
||||
"param_init": {
|
||||
"default": {
|
||||
"buf_cnt": 2,
|
||||
"fbc": "off",
|
||||
"rc_mode": "fixqp",
|
||||
"fps": "0:0",
|
||||
"range": "full",
|
||||
"sei": "off",
|
||||
"qfactor": 85,
|
||||
"qfactor_min": 30,
|
||||
"qfactor_max": 99,
|
||||
"bps": 60000
|
||||
},
|
||||
"1280*720p30": {
|
||||
"qfactor": 80,
|
||||
"qfactor_min": 60,
|
||||
"qfactor_max": 90,
|
||||
"bps": 70000
|
||||
},
|
||||
"1920*1080p30": {
|
||||
"qfactor": 75,
|
||||
"qfactor_min": 50,
|
||||
"qfactor_max": 90,
|
||||
"bps": 80000
|
||||
},
|
||||
"2560*1440p30": {
|
||||
"qfactor": 70,
|
||||
"qfactor_min": 50,
|
||||
"qfactor_max": 90,
|
||||
"bps": 90000
|
||||
},
|
||||
"2880*1616@30": {
|
||||
"qfactor": 70,
|
||||
"qfactor_min": 50,
|
||||
"qfactor_max": 90,
|
||||
"bps": 90000
|
||||
}
|
||||
},
|
||||
"param_change": {
|
||||
}
|
||||
},
|
||||
"h264" : {
|
||||
"param_init": {
|
||||
"default": {
|
||||
"buf_cnt": 2,
|
||||
"fbc": "off",
|
||||
"gop": 60,
|
||||
"rc_mode": "cbr",
|
||||
"fps": "0:0",
|
||||
"range": "full",
|
||||
"qp": "26:4:20:40:8:48:2:1",
|
||||
"sei": "off",
|
||||
"profile": 100,
|
||||
"vi_len": 30,
|
||||
"gop_mode": 0,
|
||||
"bps": 10000,
|
||||
"force_idr": "5:5:20000"
|
||||
},
|
||||
"1920*1080p30": {
|
||||
"bps": 10000,
|
||||
"force_idr": "5:5:30000"
|
||||
},
|
||||
"2560*1440p30": {
|
||||
"bps": 15000,
|
||||
"force_idr": "5:5:40000"
|
||||
},
|
||||
"2880*1616p30": {
|
||||
"bps": 15000,
|
||||
"force_idr": "5:5:40000"
|
||||
}
|
||||
},
|
||||
"param_change": {
|
||||
}
|
||||
},
|
||||
"h265" : {
|
||||
"param_init": {
|
||||
"default": {
|
||||
"buf_cnt": 2,
|
||||
"fbc": "off",
|
||||
"gop": 60,
|
||||
"rc_mode": "cbr",
|
||||
"fps": "0:0",
|
||||
"range": "full",
|
||||
"qp": "26:4:20:40:8:48:2:1",
|
||||
"sei": "off",
|
||||
"vi_len": 30,
|
||||
"gop_mode": 0,
|
||||
"bps": 10000,
|
||||
"force_idr": "5:5:20000"
|
||||
},
|
||||
"1920*1080p30": {
|
||||
"bps": 10000,
|
||||
"force_idr": "5:5:30000"
|
||||
},
|
||||
"2560*1440p30": {
|
||||
"bps": 15000,
|
||||
"force_idr": "5:5:40000"
|
||||
},
|
||||
"2880*1616p30": {
|
||||
"bps": 15000,
|
||||
"force_idr": "5:5:40000"
|
||||
}
|
||||
},
|
||||
"param_change": {
|
||||
}
|
||||
}
|
||||
},
|
||||
"osd_cfg": {
|
||||
"version" : 1,
|
||||
"param_init": {
|
||||
"enable": "off",
|
||||
"force_use_vpss": "off"
|
||||
},
|
||||
"param_change": {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
116
project/app/uvc_app_tiny/uvc_app/CMakeLists.txt
Executable file
116
project/app/uvc_app_tiny/uvc_app/CMakeLists.txt
Executable file
@@ -0,0 +1,116 @@
|
||||
cmake_minimum_required(VERSION 2.8.0 FATAL_ERROR)
|
||||
set(CMAKE_CXX_STANDARD 11)
|
||||
add_definitions(-DDBUG)
|
||||
add_definitions(-g)
|
||||
PROJECT(rk_mpi_uvc)
|
||||
include(FindPkgConfig)
|
||||
|
||||
include_directories(uvc)
|
||||
include_directories(uvc/cJSON)
|
||||
include_directories(isp)
|
||||
include_directories(param)
|
||||
|
||||
include_directories(${PROJECT_SOURCE_DIR}/include
|
||||
${CMAKE_SYSROOT}/usr/include/rkaiq/
|
||||
${CMAKE_SYSROOT}/usr/include/rkaiq/uAPI
|
||||
${CMAKE_SYSROOT}/usr/include/rkaiq/uAPI2
|
||||
${CMAKE_SYSROOT}/usr/include/rkaiq/algos
|
||||
${CMAKE_SYSROOT}/usr/include/rkaiq/common
|
||||
${CMAKE_SYSROOT}/usr/include/rkaiq/xcore
|
||||
${CMAKE_SYSROOT}/usr/include/rkaiq/iq_parser
|
||||
${CMAKE_SYSROOT}/usr/include/rkaiq/iq_parser_v2
|
||||
${CMAKE_SYSROOT}/usr/include/libdrm
|
||||
)
|
||||
|
||||
option(COMPILE_FOR_UVC_UAC "compile for uac" OFF)
|
||||
if(COMPILE_FOR_UVC_UAC)
|
||||
include(uac/uac.cmake)
|
||||
endif()
|
||||
|
||||
set(LIB_SOURCE
|
||||
uvc/uvc-gadget.c
|
||||
uvc/uvc_video.cpp
|
||||
uvc/uvc_control.cpp
|
||||
uvc/uvc_process.cpp
|
||||
uvc/uvc_mpi_config.c
|
||||
uvc/uvc_mpi_venc.cpp
|
||||
uvc/uvc_mpi_vi.cpp
|
||||
uvc/uvc_mpi_vpss.cpp
|
||||
uvc/uevent.c
|
||||
uvc/uvc_configfs.c
|
||||
uvc/camera_control.c
|
||||
uvc/camera_pu_control.c
|
||||
uvc/cJSON/cJSON.c
|
||||
uvc/osd.c
|
||||
isp/isp.c
|
||||
param/dictionary.c
|
||||
param/iniparser.c
|
||||
param/param.c
|
||||
)
|
||||
|
||||
if(COMPILE_FOR_UVC_UAC)
|
||||
add_definitions(-DCOMPILE_FOR_UVC_UAC)
|
||||
set(SOURCE
|
||||
main.c
|
||||
${LIB_SOURCE}
|
||||
${UAC_SOURCE}
|
||||
)
|
||||
|
||||
else()
|
||||
|
||||
set(SOURCE
|
||||
main.c
|
||||
${LIB_SOURCE}
|
||||
)
|
||||
|
||||
endif()
|
||||
|
||||
if (RK_ENABLE_FASTBOOT)
|
||||
set(RK_MPI_UVC_DEPENDENT_LIBS
|
||||
pthread
|
||||
rt
|
||||
rkaiq
|
||||
librockit.a
|
||||
librockchip_mpp.a
|
||||
librkaudio_detect.a
|
||||
libaec_bf_process.a
|
||||
librga.a
|
||||
)
|
||||
message(STATUS "RK_ENABLE_FASTBOOT is enabled.")
|
||||
else()
|
||||
set(RK_MPI_UVC_DEPENDENT_LIBS
|
||||
pthread
|
||||
rt
|
||||
rkaiq
|
||||
rockit
|
||||
)
|
||||
message(STATUS "RK_ENABLE_FASTBOOT is disabled.")
|
||||
endif()
|
||||
set(RK_MPI_UVC_INC
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/uvc/
|
||||
)
|
||||
|
||||
add_definitions(-fno-rtti)
|
||||
|
||||
ADD_EXECUTABLE(rk_mpi_uvc ${SOURCE})
|
||||
link_directories(${PROJECT_SOURCE_DIR}/lib/)
|
||||
target_link_libraries(rk_mpi_uvc ${RK_MPI_UVC_DEPENDENT_LIBS})
|
||||
|
||||
install(DIRECTORY ./uvc DESTINATION include
|
||||
FILES_MATCHING PATTERN "*.h")
|
||||
|
||||
install(TARGETS rk_mpi_uvc DESTINATION bin)
|
||||
install(FILES uvc_mpi_cfg.conf DESTINATION share)
|
||||
install(FILES rkuvc.ini DESTINATION share)
|
||||
install(FILES usb_config.sh DESTINATION bin
|
||||
PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE
|
||||
GROUP_READ GROUP_WRITE GROUP_EXECUTE
|
||||
WORLD_READ WORLD_WRITE WORLD_EXECUTE)
|
||||
#install(FILES RkLunch.sh DESTINATION bin
|
||||
# PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE
|
||||
# GROUP_READ GROUP_WRITE GROUP_EXECUTE
|
||||
# WORLD_READ WORLD_WRITE WORLD_EXECUTE)
|
||||
#install(FILES RkLunch-stop.sh DESTINATION bin
|
||||
# PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE
|
||||
# GROUP_READ GROUP_WRITE GROUP_EXECUTE
|
||||
# WORLD_READ WORLD_WRITE WORLD_EXECUTE)
|
||||
28
project/app/uvc_app_tiny/uvc_app/LICENSE
Executable file
28
project/app/uvc_app_tiny/uvc_app/LICENSE
Executable file
@@ -0,0 +1,28 @@
|
||||
// Copyright 2021 Rockchip Electronics Co.,Ltd.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are met:
|
||||
//
|
||||
// 1. Redistributions of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
//
|
||||
// 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
// this list of conditions and the following disclaimer in the documentation
|
||||
// and/or other materials provided with the distribution.
|
||||
//
|
||||
// 3. Neither the name of the copyright holder nor the names of its contributors
|
||||
// may be used to endorse or promote products derived from this software without
|
||||
// specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
// POSSIBILITY OF SUCH DAMAGE.
|
||||
30
project/app/uvc_app_tiny/uvc_app/RkLunch-stop.sh
Executable file
30
project/app/uvc_app_tiny/uvc_app/RkLunch-stop.sh
Executable file
@@ -0,0 +1,30 @@
|
||||
#!/bin/sh
|
||||
program_kill()
|
||||
{
|
||||
P_PID=`ps | grep $1 | grep -v grep | awk '{print $1}'`
|
||||
test -z ${P_PID} || kill -9 ${P_PID}
|
||||
}
|
||||
|
||||
echo "Stop Application ..."
|
||||
program_kill RkLunch.sh
|
||||
killall rk_mpi_uvc &
|
||||
|
||||
cnt=0
|
||||
while [ 1 ];
|
||||
do
|
||||
sleep 1
|
||||
cnt=$(( cnt + 1 ))
|
||||
if [ $cnt -eq 8 ]; then
|
||||
echo "killall -9 rk_mpi_uvc"
|
||||
killall -9 rk_mpi_uvc
|
||||
sleep 0.1
|
||||
break
|
||||
fi
|
||||
ps|grep rk_mpi_uvc|grep -v grep
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "rk_mpi_uvc exit"
|
||||
break
|
||||
else
|
||||
echo "rk_mpi_uvc active"
|
||||
fi
|
||||
done
|
||||
105
project/app/uvc_app_tiny/uvc_app/RkLunch.sh
Executable file
105
project/app/uvc_app_tiny/uvc_app/RkLunch.sh
Executable file
@@ -0,0 +1,105 @@
|
||||
#!/bin/sh
|
||||
check_usb_state()
|
||||
{
|
||||
if [[ ! -f "/oem/usr/bin/rk_mpi_uvc" && ! -f "/usr/bin/rk_mpi_uvc" ]]; then
|
||||
return 1
|
||||
fi
|
||||
PID=`ps |grep rk_mpi_uvc |grep -v grep | wc -l`
|
||||
if [ $PID -le 0 ];then
|
||||
echo " exit rk_mpi_uvc ,restart it for uvc recovery..."
|
||||
killall adbd
|
||||
sleep 1
|
||||
killall -9 adbd
|
||||
rm -rf /sys/kernel/config/usb_gadget/rockchip/configs/b.1/f*
|
||||
echo none > /sys/kernel/config/usb_gadget/rockchip/UDC
|
||||
rmdir /sys/kernel/config/usb_gadget/rockchip/functions/ffs.adb
|
||||
rmdir /sys/kernel/config/usb_gadget/rockchip/functions/uac*
|
||||
UDC=`ls /sys/class/udc/| awk '{print $1}'`
|
||||
echo $UDC > /sys/bus/platform/drivers/dwc3/unbind
|
||||
echo $UDC > /sys/bus/platform/drivers/dwc3/bind
|
||||
/oem/usr/bin/usb_config.sh uac1 #off #disable adb
|
||||
if [ -d "/oem/usr/share/iqfiles" ];then
|
||||
rk_mpi_uvc -c /tmp/rkuvc.ini -a /oem/usr/share/iqfiles &
|
||||
else
|
||||
rk_mpi_uvc &
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
post_chk()
|
||||
{
|
||||
#TODO: ensure /userdata mount done
|
||||
cnt=0
|
||||
while [ $cnt -lt 30 ];
|
||||
do
|
||||
cnt=$(( cnt + 1 ))
|
||||
if mount | grep -w userdata; then
|
||||
break
|
||||
fi
|
||||
sleep .1
|
||||
done
|
||||
|
||||
# if ko exist, install ko first
|
||||
default_ko_dir=/ko
|
||||
if [ -f "/oem/usr/ko/insmod_ko.sh" ];then
|
||||
default_ko_dir=/oem/usr/ko
|
||||
fi
|
||||
if [ -f "$default_ko_dir/insmod_ko.sh" ];then
|
||||
cd $default_ko_dir && sh insmod_ko.sh && cd -
|
||||
fi
|
||||
|
||||
# if /data/rkuvc not exist, cp /usr/share
|
||||
rkuvc_ini=/tmp/rkuvc.ini
|
||||
default_rkuvc_ini=/usr/share/rkuvc.ini
|
||||
if [ ! -f "$default_rkuvc_ini" ];then
|
||||
default_rkuvc_ini=/oem/usr/share/rkuvc.ini
|
||||
fi
|
||||
if [ ! -f "$default_rkuvc_ini" ];then
|
||||
echo "Error: not found rkuvc.ini !!!"
|
||||
exit -1
|
||||
fi
|
||||
if [ ! -f "$rkuvc_ini" ]; then
|
||||
cp $default_rkuvc_ini $rkuvc_ini -f
|
||||
fi
|
||||
|
||||
export rt_log_level=3
|
||||
export rk_mpi_uvc_log_level=2
|
||||
export uac_app_log_level=2
|
||||
|
||||
touch /tmp/uvc_no_timeout
|
||||
/oem/usr/bin/usb_config.sh uac1
|
||||
ifconfig lo 127.0.0.1
|
||||
|
||||
if [ -d "/oem/usr/share/iqfiles" ];then
|
||||
rk_mpi_uvc -c /tmp/rkuvc.ini -a /oem/usr/share/iqfiles &
|
||||
else
|
||||
rk_mpi_uvc &
|
||||
fi
|
||||
|
||||
while true
|
||||
do
|
||||
sleep 2
|
||||
if [ -f "/tmp/uvc_stop_check" ]; then
|
||||
echo " stop check usb state sh " && break
|
||||
else
|
||||
check_usb_state
|
||||
fi
|
||||
|
||||
if [ -f "/tmp/reboot_loader" ]; then
|
||||
echo "exec reboot loader cmd..."
|
||||
reboot loader &
|
||||
fi
|
||||
done
|
||||
}
|
||||
start_app()
|
||||
{
|
||||
if [ -f "/etc/init.d/S50usbdevice" ];then
|
||||
mv /etc/init.d/S50usbdevice /etc/S50usbdevice -f
|
||||
fi
|
||||
echo "##### start uvc app ..."
|
||||
post_chk &
|
||||
}
|
||||
ulimit -c unlimited
|
||||
echo "/data/core-%p-%e" > /proc/sys/kernel/core_pattern
|
||||
|
||||
start_app
|
||||
9
project/app/uvc_app_tiny/uvc_app/format.sh
Executable file
9
project/app/uvc_app_tiny/uvc_app/format.sh
Executable file
@@ -0,0 +1,9 @@
|
||||
#!/bin/bash
|
||||
##
|
||||
## Copyright 2019 Fuzhou Rockchip Electronics Co., Ltd. All rights reserved.
|
||||
## Use of this source code is governed by a BSD-style license that can be
|
||||
## found in the LICENSE file.
|
||||
##
|
||||
|
||||
find . -name "*.c" -o -name "*.h" | xargs clang-format -style=file -i
|
||||
find . -name "*.cpp" -o -name "*.h" | xargs clang-format -style=file -i
|
||||
1293
project/app/uvc_app_tiny/uvc_app/isp/isp.c
Normal file
1293
project/app/uvc_app_tiny/uvc_app/isp/isp.c
Normal file
File diff suppressed because it is too large
Load Diff
79
project/app/uvc_app_tiny/uvc_app/isp/isp.h
Normal file
79
project/app/uvc_app_tiny/uvc_app/isp/isp.h
Normal file
@@ -0,0 +1,79 @@
|
||||
int rk_isp_init(int cam_id, char *iqfile_path);
|
||||
int rk_isp_deinit(int cam_id);
|
||||
int rk_isp_group_init(int cam_group_id, char *iqfile_path);
|
||||
int rk_isp_group_deinit(int cam_group_id);
|
||||
int rk_isp_set_frame_rate(int cam_id, int value);
|
||||
// image adjustment
|
||||
int rk_isp_get_contrast(int cam_id, int *value);
|
||||
int rk_isp_set_contrast(int cam_id, int value);
|
||||
int rk_isp_get_brightness(int cam_id, int *value);
|
||||
int rk_isp_set_brightness(int cam_id, int value);
|
||||
int rk_isp_get_saturation(int cam_id, int *value);
|
||||
int rk_isp_set_saturation(int cam_id, int value);
|
||||
int rk_isp_get_sharpness(int cam_id, int *value);
|
||||
int rk_isp_set_sharpness(int cam_id, int value);
|
||||
int rk_isp_get_hue(int cam_id, int *value);
|
||||
int rk_isp_set_hue(int cam_id, int value);
|
||||
int rk_isp_get_hue_mode(int cam_id, int *value);
|
||||
int rk_isp_set_hue_mode(int cam_id, int value);
|
||||
// exposure
|
||||
int rk_isp_get_exposure_mode(int cam_id, const char **value);
|
||||
int rk_isp_set_exposure_mode(int cam_id, const char *value);
|
||||
int rk_isp_get_gain_mode(int cam_id, const char **value);
|
||||
int rk_isp_set_gain_mode(int cam_id, const char *value);
|
||||
int rk_isp_get_exposure_time(int cam_id, const char **value);
|
||||
int rk_isp_set_exposure_time(int cam_id, const char *value);
|
||||
int rk_isp_get_exposure_gain(int cam_id, int *value);
|
||||
int rk_isp_set_exposure_gain(int cam_id, int value);
|
||||
// blc
|
||||
int rk_isp_get_hdr(int cam_id, const char **value);
|
||||
int rk_isp_set_hdr(int cam_id, const char *value);
|
||||
int rk_isp_get_blc_region(int cam_id, const char **value);
|
||||
int rk_isp_set_blc_region(int cam_id, const char *value);
|
||||
int rk_isp_get_hlc(int cam_id, const char **value);
|
||||
int rk_isp_set_hlc(int cam_id, const char *value);
|
||||
int rk_isp_get_hdr_level(int cam_id, int *value);
|
||||
int rk_isp_set_hdr_level(int cam_id, int value);
|
||||
int rk_isp_get_blc_strength(int cam_id, int *value);
|
||||
int rk_isp_set_blc_strength(int cam_id, int value);
|
||||
int rk_isp_get_hlc_level(int cam_id, int *value);
|
||||
int rk_isp_set_hlc_level(int cam_id, int value);
|
||||
int rk_isp_get_dark_boost_level(int cam_id, int *value);
|
||||
int rk_isp_set_dark_boost_level(int cam_id, int value);
|
||||
// white_blance
|
||||
int rk_isp_get_white_blance_style(int cam_id, const char **value);
|
||||
int rk_isp_set_white_blance_style(int cam_id, const char *value);
|
||||
int rk_isp_get_white_blance_ct(int cam_id, int *value);
|
||||
int rk_isp_set_white_blance_ct(int cam_id, int value);
|
||||
// enhancement
|
||||
int rk_isp_get_noise_reduce_mode(int cam_id, const char **value);
|
||||
int rk_isp_set_noise_reduce_mode(int cam_id, const char *value);
|
||||
int rk_isp_get_dehaze(int cam_id, const char **value);
|
||||
int rk_isp_set_dehaze(int cam_id, const char *value);
|
||||
int rk_isp_get_gray_scale_mode(int cam_id, const char **value);
|
||||
// int rk_isp_set_gray_scale_mode(int cam_id, const char *value);
|
||||
int rk_isp_get_distortion_correction(int cam_id, const char **value);
|
||||
int rk_isp_set_distortion_correction(int cam_id, const char *value);
|
||||
int rk_isp_get_spatial_denoise_level(int cam_id, int *value);
|
||||
int rk_isp_set_spatial_denoise_level(int cam_id, int value);
|
||||
int rk_isp_get_temporal_denoise_level(int cam_id, int *value);
|
||||
int rk_isp_set_temporal_denoise_level(int cam_id, int value);
|
||||
int rk_isp_get_dehaze_level(int cam_id, int *value);
|
||||
int rk_isp_set_dehaze_level(int cam_id, int value);
|
||||
int rk_isp_get_ldch_level(int cam_id, int *value);
|
||||
int rk_isp_set_ldch_level(int cam_id, int value);
|
||||
// video_adjustment
|
||||
int rk_isp_get_power_line_frequency_mode(int cam_id, const char **value);
|
||||
int rk_isp_set_power_line_frequency_mode(int cam_id, const char *value);
|
||||
int rk_isp_get_image_flip(int cam_id, const char **value);
|
||||
int rk_isp_set_image_flip(int cam_id, const char *value);
|
||||
// auto focus
|
||||
int rk_isp_get_af_mode(int cam_id, const char **value);
|
||||
int rk_isp_set_af_mode(int cam_id, const char *value);
|
||||
int rk_isp_get_zoom_level(int cam_id, int *value);
|
||||
int rk_isp_get_focus_level(int cam_id, int *value);
|
||||
int rk_isp_af_zoom_in(int cam_id);
|
||||
int rk_isp_af_zoom_out(int cam_id);
|
||||
int rk_isp_af_focus_in(int cam_id);
|
||||
int rk_isp_af_focus_out(int cam_id);
|
||||
int rk_isp_af_focus_once(int cam_id);
|
||||
189
project/app/uvc_app_tiny/uvc_app/main.c
Executable file
189
project/app/uvc_app_tiny/uvc_app/main.c
Executable file
@@ -0,0 +1,189 @@
|
||||
#include "camera_control.h"
|
||||
#include "isp.h"
|
||||
#include "param.h"
|
||||
#include "rk_mpi_sys.h"
|
||||
#include "uevent.h"
|
||||
#include "uevent.h"
|
||||
#include "uvc_control.h"
|
||||
#include "uvc_log.h"
|
||||
#include "uvc_video.h"
|
||||
#include <getopt.h>
|
||||
#include <signal.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#ifdef COMPILE_FOR_UVC_UAC
|
||||
#include "uac_control.h"
|
||||
#include "uac_log.h"
|
||||
#include "uac_uevent.h"
|
||||
#include <pthread.h>
|
||||
#include <sys/prctl.h>
|
||||
#endif
|
||||
|
||||
#define LOG_TAG "rk_mpi_uvc"
|
||||
#define UVC_VERSION "SDK V2.01"
|
||||
enum { LOG_ERROR, LOG_WARN, LOG_INFO, LOG_DEBUG };
|
||||
int rkuvc_log_level = LOG_DEBUG;
|
||||
char *rkuvc_ini_path_ = NULL;
|
||||
char *rkuvc_iq_file_path_ = NULL;
|
||||
// int enable_minilog = 0;
|
||||
// int rk_mpi_uvc_log_level = LOG_LEVEL_INFO;
|
||||
// int app_quit;
|
||||
|
||||
static const char short_options[] = "c:a:l:";
|
||||
static const struct option long_options[] = {
|
||||
{"config", required_argument, NULL, 'c'},
|
||||
{"aiq_file", no_argument, NULL, 'a'},
|
||||
{"log_level", no_argument, NULL, 'l'},
|
||||
{"help", no_argument, NULL, 'h'},
|
||||
{0, 0, 0, 0}};
|
||||
|
||||
static void usage_tip(FILE *fp, int argc, char **argv) {
|
||||
fprintf(fp, "Usage: %s [options]\n"
|
||||
"Version %s\n"
|
||||
"Options:\n"
|
||||
"-c | --config rkuvc ini file, default is "
|
||||
"/userdata/rkuvc.ini, need to be writable\n"
|
||||
"-a | --aiq_file aiq file dir path, default is /etc/iqfiles\n"
|
||||
"-l | --log_level log_level [0/1/2/3], default is 2\n"
|
||||
"-h | --help for help \n\n"
|
||||
"\n",
|
||||
argv[0], "V1.0");
|
||||
}
|
||||
|
||||
#ifdef COMPILE_FOR_UVC_UAC
|
||||
|
||||
void *uac_app_thread(void *arg) {
|
||||
prctl(PR_SET_NAME, "uac_pthread", 0, 0, 0);
|
||||
|
||||
LOG_INFO("uac uevent version = 1.0\n");
|
||||
// create uac control
|
||||
char *ch;
|
||||
int type = 0; // UAC_API_MPI;
|
||||
// rkuac_get_opt(argc, argv);
|
||||
|
||||
int result = uac_control_create(type);
|
||||
if (result < 0) {
|
||||
LOG_ERROR("uac_control_create fail\n");
|
||||
goto err_monitor;
|
||||
}
|
||||
|
||||
// register uevent monitor
|
||||
uac_uevent_monitor_run();
|
||||
|
||||
while (1) {
|
||||
usleep(100000);
|
||||
}
|
||||
|
||||
err_monitor:
|
||||
pthread_detach(pthread_self());
|
||||
pthread_exit(NULL);
|
||||
}
|
||||
int uac_app_run() {
|
||||
pthread_t tid;
|
||||
|
||||
return pthread_create(&tid, NULL, uac_app_thread, NULL);
|
||||
}
|
||||
#endif
|
||||
|
||||
void rkuvc_get_opt(int argc, char *argv[]) {
|
||||
for (;;) {
|
||||
int idx;
|
||||
int c;
|
||||
c = getopt_long(argc, argv, short_options, long_options, &idx);
|
||||
if (-1 == c)
|
||||
break;
|
||||
switch (c) {
|
||||
case 0: /* getopt_long() flag */
|
||||
break;
|
||||
case 'c':
|
||||
rkuvc_ini_path_ = optarg;
|
||||
break;
|
||||
case 'a':
|
||||
rkuvc_iq_file_path_ = optarg;
|
||||
break;
|
||||
case 'l':
|
||||
rkuvc_log_level = atoi(optarg);
|
||||
break;
|
||||
case 'h':
|
||||
usage_tip(stdout, argc, argv);
|
||||
exit(EXIT_SUCCESS);
|
||||
default:
|
||||
usage_tip(stderr, argc, argv);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
}
|
||||
void sigterm_handler(int sig) {
|
||||
LOG_INFO("signal %d\n", sig);
|
||||
app_quit = sig;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
int fd;
|
||||
int ret;
|
||||
unsigned int handle;
|
||||
char *buffer;
|
||||
int handle_fd;
|
||||
size_t size;
|
||||
int i = 0;
|
||||
int width, height;
|
||||
int y, uv;
|
||||
int extra_cnt = 0;
|
||||
uint32_t flags = 0;
|
||||
int media_set = 0;
|
||||
RK_S32 s32Ret = RK_FAILURE;
|
||||
rk_mpi_uvc_log_level = LOG_LEVEL_INFO;
|
||||
app_quit = 0;
|
||||
signal(SIGQUIT, sigterm_handler);
|
||||
signal(SIGTERM, sigterm_handler);
|
||||
char *log_level = getenv("rk_mpi_uvc_log_level");
|
||||
if (log_level) {
|
||||
LOG_INFO("rk_mpi_uvc_log_level=%d", atoi(log_level));
|
||||
rk_mpi_uvc_log_level = atoi(log_level);
|
||||
}
|
||||
LOG_INFO("VERSION:%s %s %s \n", UVC_VERSION, __DATE__, __TIME__);
|
||||
rkuvc_get_opt(argc, argv);
|
||||
LOG_INFO("rkuvc_ini_path_ is %s, rkuvc_iq_file_path_ is %s, rkuvc_log_level "
|
||||
"is %d\n",
|
||||
rkuvc_ini_path_, rkuvc_iq_file_path_, rkuvc_log_level);
|
||||
rk_param_init(rkuvc_ini_path_);
|
||||
camera_control_init();
|
||||
s32Ret = RK_MPI_SYS_Init();
|
||||
if (s32Ret != RK_SUCCESS) {
|
||||
LOG_ERROR("RK_MPI_SYS_Init %x\n", s32Ret);
|
||||
return -1;
|
||||
}
|
||||
uvc_control_start_setcallback(camera_control_start);
|
||||
uvc_control_stop_setcallback(camera_control_stop);
|
||||
uevent_monitor_run(UVC_CONTROL_CAMERA);
|
||||
uvc_control_run(UVC_CONTROL_CAMERA);
|
||||
|
||||
#ifdef COMPILE_FOR_UVC_UAC
|
||||
uac_app_log_level = LOG_DEBUG;
|
||||
char *uac_log_level = getenv("uac_app_log_level");
|
||||
if (uac_log_level) {
|
||||
uac_app_log_level = atoi(uac_log_level);
|
||||
}
|
||||
if (rk_param_get_int("video.source:enable_uac", 0))
|
||||
uac_app_run();
|
||||
#endif
|
||||
|
||||
while (1) {
|
||||
if (0 == uvc_control_loop())
|
||||
break;
|
||||
usleep(100000);
|
||||
}
|
||||
uvc_video_id_exit_all();
|
||||
camera_control_deinit();
|
||||
#ifdef COMPILE_FOR_UVC_UAC
|
||||
if (rk_param_get_int("video.source:enable_uac", 0)) {
|
||||
LOG_INFO("uac control destory...\n");
|
||||
uac_control_destory();
|
||||
}
|
||||
#endif
|
||||
RK_MPI_SYS_Exit();
|
||||
rk_param_deinit();
|
||||
LOG_INFO("uvc_app exit.\n");
|
||||
return 0;
|
||||
}
|
||||
375
project/app/uvc_app_tiny/uvc_app/param/dictionary.c
Normal file
375
project/app/uvc_app_tiny/uvc_app/param/dictionary.c
Normal file
@@ -0,0 +1,375 @@
|
||||
/*-------------------------------------------------------------------------*/
|
||||
/**
|
||||
@file dictionary.c
|
||||
@author N. Devillard
|
||||
@brief Implements a dictionary for string variables.
|
||||
|
||||
This module implements a simple dictionary object, i.e. a list
|
||||
of string/string associations. This object is useful to store e.g.
|
||||
informations retrieved from a configuration file (ini files).
|
||||
*/
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
/*---------------------------------------------------------------------------
|
||||
Includes
|
||||
---------------------------------------------------------------------------*/
|
||||
#include "dictionary.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
/** Maximum value size for integers and doubles. */
|
||||
#define MAXVALSZ 1024
|
||||
|
||||
/** Minimal allocated number of entries in a dictionary */
|
||||
#define DICTMINSZ 128
|
||||
|
||||
/** Invalid key token */
|
||||
#define DICT_INVALID_KEY ((char *)-1)
|
||||
|
||||
/*---------------------------------------------------------------------------
|
||||
Private functions
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief Duplicate a string
|
||||
@param s String to duplicate
|
||||
@return Pointer to a newly allocated string, to be freed with free()
|
||||
|
||||
This is a replacement for strdup(). This implementation is provided
|
||||
for systems that do not have it.
|
||||
*/
|
||||
/*--------------------------------------------------------------------------*/
|
||||
static char *xstrdup(const char *s) {
|
||||
char *t;
|
||||
size_t len;
|
||||
if (!s)
|
||||
return NULL;
|
||||
|
||||
len = strlen(s) + 1;
|
||||
t = (char *)malloc(len);
|
||||
if (t) {
|
||||
memcpy(t, s, len);
|
||||
}
|
||||
return t;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief Double the size of the dictionary
|
||||
@param d Dictionary to grow
|
||||
@return This function returns non-zero in case of failure
|
||||
*/
|
||||
/*--------------------------------------------------------------------------*/
|
||||
static int dictionary_grow(dictionary *d) {
|
||||
char **new_val;
|
||||
char **new_key;
|
||||
unsigned *new_hash;
|
||||
|
||||
new_val = (char **)calloc(d->size * 2, sizeof *d->val);
|
||||
new_key = (char **)calloc(d->size * 2, sizeof *d->key);
|
||||
new_hash = (unsigned *)calloc(d->size * 2, sizeof *d->hash);
|
||||
if (!new_val || !new_key || !new_hash) {
|
||||
/* An allocation failed, leave the dictionary unchanged */
|
||||
if (new_val)
|
||||
free(new_val);
|
||||
if (new_key)
|
||||
free(new_key);
|
||||
if (new_hash)
|
||||
free(new_hash);
|
||||
return -1;
|
||||
}
|
||||
/* Initialize the newly allocated space */
|
||||
memcpy(new_val, d->val, d->size * sizeof(char *));
|
||||
memcpy(new_key, d->key, d->size * sizeof(char *));
|
||||
memcpy(new_hash, d->hash, d->size * sizeof(unsigned));
|
||||
/* Delete previous data */
|
||||
free(d->val);
|
||||
free(d->key);
|
||||
free(d->hash);
|
||||
/* Actually update the dictionary */
|
||||
d->size *= 2;
|
||||
d->val = new_val;
|
||||
d->key = new_key;
|
||||
d->hash = new_hash;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------
|
||||
Function codes
|
||||
---------------------------------------------------------------------------*/
|
||||
/*-------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief Compute the hash key for a string.
|
||||
@param key Character string to use for key.
|
||||
@return 1 unsigned int on at least 32 bits.
|
||||
|
||||
This hash function has been taken from an Article in Dr Dobbs Journal.
|
||||
This is normally a collision-free function, distributing keys evenly.
|
||||
The key is stored anyway in the struct so that collision can be avoided
|
||||
by comparing the key itself in last resort.
|
||||
*/
|
||||
/*--------------------------------------------------------------------------*/
|
||||
unsigned dictionary_hash(const char *key) {
|
||||
size_t len;
|
||||
unsigned hash;
|
||||
size_t i;
|
||||
|
||||
if (!key)
|
||||
return 0;
|
||||
|
||||
len = strlen(key);
|
||||
for (hash = 0, i = 0; i < len; i++) {
|
||||
hash += (unsigned)key[i];
|
||||
hash += (hash << 10);
|
||||
hash ^= (hash >> 6);
|
||||
}
|
||||
hash += (hash << 3);
|
||||
hash ^= (hash >> 11);
|
||||
hash += (hash << 15);
|
||||
return hash;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief Create a new dictionary object.
|
||||
@param size Optional initial size of the dictionary.
|
||||
@return 1 newly allocated dictionary object.
|
||||
|
||||
This function allocates a new dictionary object of given size and returns
|
||||
it. If you do not know in advance (roughly) the number of entries in the
|
||||
dictionary, give size=0.
|
||||
*/
|
||||
/*-------------------------------------------------------------------------*/
|
||||
dictionary *dictionary_new(size_t size) {
|
||||
dictionary *d;
|
||||
|
||||
/* If no size was specified, allocate space for DICTMINSZ */
|
||||
if (size < DICTMINSZ)
|
||||
size = DICTMINSZ;
|
||||
|
||||
d = (dictionary *)calloc(1, sizeof *d);
|
||||
|
||||
if (d) {
|
||||
d->size = size;
|
||||
d->val = (char **)calloc(size, sizeof *d->val);
|
||||
d->key = (char **)calloc(size, sizeof *d->key);
|
||||
d->hash = (unsigned *)calloc(size, sizeof *d->hash);
|
||||
}
|
||||
return d;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief Delete a dictionary object
|
||||
@param d dictionary object to deallocate.
|
||||
@return void
|
||||
|
||||
Deallocate a dictionary object and all memory associated to it.
|
||||
*/
|
||||
/*--------------------------------------------------------------------------*/
|
||||
void dictionary_del(dictionary *d) {
|
||||
ssize_t i;
|
||||
|
||||
if (d == NULL)
|
||||
return;
|
||||
for (i = 0; i < d->size; i++) {
|
||||
if (d->key[i] != NULL)
|
||||
free(d->key[i]);
|
||||
if (d->val[i] != NULL)
|
||||
free(d->val[i]);
|
||||
}
|
||||
free(d->val);
|
||||
free(d->key);
|
||||
free(d->hash);
|
||||
free(d);
|
||||
return;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief Get a value from a dictionary.
|
||||
@param d dictionary object to search.
|
||||
@param key Key to look for in the dictionary.
|
||||
@param def Default value to return if key not found.
|
||||
@return 1 pointer to internally allocated character string.
|
||||
|
||||
This function locates a key in a dictionary and returns a pointer to its
|
||||
value, or the passed 'def' pointer if no such key can be found in
|
||||
dictionary. The returned character pointer points to data internal to the
|
||||
dictionary object, you should not try to free it or modify it.
|
||||
*/
|
||||
/*--------------------------------------------------------------------------*/
|
||||
const char *dictionary_get(const dictionary *d, const char *key,
|
||||
const char *def) {
|
||||
unsigned hash;
|
||||
ssize_t i;
|
||||
|
||||
hash = dictionary_hash(key);
|
||||
for (i = 0; i < d->size; i++) {
|
||||
if (d->key[i] == NULL)
|
||||
continue;
|
||||
/* Compare hash */
|
||||
if (hash == d->hash[i]) {
|
||||
/* Compare string, to avoid hash collisions */
|
||||
if (!strcmp(key, d->key[i])) {
|
||||
return d->val[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
return def;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief Set a value in a dictionary.
|
||||
@param d dictionary object to modify.
|
||||
@param key Key to modify or add.
|
||||
@param val Value to add.
|
||||
@return int 0 if Ok, anything else otherwise
|
||||
|
||||
If the given key is found in the dictionary, the associated value is
|
||||
replaced by the provided one. If the key cannot be found in the
|
||||
dictionary, it is added to it.
|
||||
|
||||
It is Ok to provide a NULL value for val, but NULL values for the dictionary
|
||||
or the key are considered as errors: the function will return immediately
|
||||
in such a case.
|
||||
|
||||
Notice that if you dictionary_set a variable to NULL, a call to
|
||||
dictionary_get will return a NULL value: the variable will be found, and
|
||||
its value (NULL) is returned. In other words, setting the variable
|
||||
content to NULL is equivalent to deleting the variable from the
|
||||
dictionary. It is not possible (in this implementation) to have a key in
|
||||
the dictionary without value.
|
||||
|
||||
This function returns non-zero in case of failure.
|
||||
*/
|
||||
/*--------------------------------------------------------------------------*/
|
||||
int dictionary_set(dictionary *d, const char *key, const char *val) {
|
||||
ssize_t i;
|
||||
unsigned hash;
|
||||
|
||||
if (d == NULL || key == NULL)
|
||||
return -1;
|
||||
|
||||
/* Compute hash for this key */
|
||||
hash = dictionary_hash(key);
|
||||
/* Find if value is already in dictionary */
|
||||
if (d->n > 0) {
|
||||
for (i = 0; i < d->size; i++) {
|
||||
if (d->key[i] == NULL)
|
||||
continue;
|
||||
if (hash == d->hash[i]) { /* Same hash value */
|
||||
if (!strcmp(key, d->key[i])) { /* Same key */
|
||||
/* Found a value: modify and return */
|
||||
if (d->val[i] != NULL)
|
||||
free(d->val[i]);
|
||||
d->val[i] = (val ? xstrdup(val) : NULL);
|
||||
/* Value has been modified: return */
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/* Add a new value */
|
||||
/* See if dictionary needs to grow */
|
||||
if (d->n == d->size) {
|
||||
/* Reached maximum size: reallocate dictionary */
|
||||
if (dictionary_grow(d) != 0)
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Insert key in the first empty slot. Start at d->n and wrap at
|
||||
d->size. Because d->n < d->size this will necessarily
|
||||
terminate. */
|
||||
for (i = d->n; d->key[i];) {
|
||||
if (++i == d->size)
|
||||
i = 0;
|
||||
}
|
||||
/* Copy key */
|
||||
d->key[i] = xstrdup(key);
|
||||
d->val[i] = (val ? xstrdup(val) : NULL);
|
||||
d->hash[i] = hash;
|
||||
d->n++;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief Delete a key in a dictionary
|
||||
@param d dictionary object to modify.
|
||||
@param key Key to remove.
|
||||
@return void
|
||||
|
||||
This function deletes a key in a dictionary. Nothing is done if the
|
||||
key cannot be found.
|
||||
*/
|
||||
/*--------------------------------------------------------------------------*/
|
||||
void dictionary_unset(dictionary *d, const char *key) {
|
||||
unsigned hash;
|
||||
ssize_t i;
|
||||
|
||||
if (key == NULL || d == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
hash = dictionary_hash(key);
|
||||
for (i = 0; i < d->size; i++) {
|
||||
if (d->key[i] == NULL)
|
||||
continue;
|
||||
/* Compare hash */
|
||||
if (hash == d->hash[i]) {
|
||||
/* Compare string, to avoid hash collisions */
|
||||
if (!strcmp(key, d->key[i])) {
|
||||
/* Found key */
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (i >= d->size)
|
||||
/* Key not found */
|
||||
return;
|
||||
|
||||
free(d->key[i]);
|
||||
d->key[i] = NULL;
|
||||
if (d->val[i] != NULL) {
|
||||
free(d->val[i]);
|
||||
d->val[i] = NULL;
|
||||
}
|
||||
d->hash[i] = 0;
|
||||
d->n--;
|
||||
return;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief Dump a dictionary to an opened file pointer.
|
||||
@param d Dictionary to dump
|
||||
@param f Opened file pointer.
|
||||
@return void
|
||||
|
||||
Dumps a dictionary onto an opened file pointer. Key pairs are printed out
|
||||
as @c [Key]=[Value], one per line. It is Ok to provide stdout or stderr as
|
||||
output file pointers.
|
||||
*/
|
||||
/*--------------------------------------------------------------------------*/
|
||||
void dictionary_dump(const dictionary *d, FILE *out) {
|
||||
ssize_t i;
|
||||
|
||||
if (d == NULL || out == NULL)
|
||||
return;
|
||||
if (d->n < 1) {
|
||||
fprintf(out, "empty dictionary\n");
|
||||
return;
|
||||
}
|
||||
for (i = 0; i < d->size; i++) {
|
||||
if (d->key[i]) {
|
||||
fprintf(out, "%20s\t[%s]\n", d->key[i], d->val[i] ? d->val[i] : "UNDEF");
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
170
project/app/uvc_app_tiny/uvc_app/param/dictionary.h
Normal file
170
project/app/uvc_app_tiny/uvc_app/param/dictionary.h
Normal file
@@ -0,0 +1,170 @@
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
/**
|
||||
@file dictionary.h
|
||||
@author N. Devillard
|
||||
@brief Implements a dictionary for string variables.
|
||||
|
||||
This module implements a simple dictionary object, i.e. a list
|
||||
of string/string associations. This object is useful to store e.g.
|
||||
informations retrieved from a configuration file (ini files).
|
||||
*/
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef _DICTIONARY_H_
|
||||
#define _DICTIONARY_H_
|
||||
|
||||
/*---------------------------------------------------------------------------
|
||||
Includes
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*---------------------------------------------------------------------------
|
||||
New types
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief Dictionary object
|
||||
|
||||
This object contains a list of string/string associations. Each
|
||||
association is identified by a unique string key. Looking up values
|
||||
in the dictionary is speeded up by the use of a (hopefully collision-free)
|
||||
hash function.
|
||||
*/
|
||||
/*-------------------------------------------------------------------------*/
|
||||
typedef struct _dictionary_ {
|
||||
int n; /** Number of entries in dictionary */
|
||||
ssize_t size; /** Storage size */
|
||||
char **val; /** List of string values */
|
||||
char **key; /** List of string keys */
|
||||
unsigned *hash; /** List of hash values for keys */
|
||||
} dictionary;
|
||||
|
||||
/*---------------------------------------------------------------------------
|
||||
Function prototypes
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief Compute the hash key for a string.
|
||||
@param key Character string to use for key.
|
||||
@return 1 unsigned int on at least 32 bits.
|
||||
|
||||
This hash function has been taken from an Article in Dr Dobbs Journal.
|
||||
This is normally a collision-free function, distributing keys evenly.
|
||||
The key is stored anyway in the struct so that collision can be avoided
|
||||
by comparing the key itself in last resort.
|
||||
*/
|
||||
/*--------------------------------------------------------------------------*/
|
||||
unsigned dictionary_hash(const char *key);
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief Create a new dictionary object.
|
||||
@param size Optional initial size of the dictionary.
|
||||
@return 1 newly allocated dictionary object.
|
||||
|
||||
This function allocates a new dictionary object of given size and returns
|
||||
it. If you do not know in advance (roughly) the number of entries in the
|
||||
dictionary, give size=0.
|
||||
*/
|
||||
/*--------------------------------------------------------------------------*/
|
||||
dictionary *dictionary_new(size_t size);
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief Delete a dictionary object
|
||||
@param d dictionary object to deallocate.
|
||||
@return void
|
||||
|
||||
Deallocate a dictionary object and all memory associated to it.
|
||||
*/
|
||||
/*--------------------------------------------------------------------------*/
|
||||
void dictionary_del(dictionary *vd);
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief Get a value from a dictionary.
|
||||
@param d dictionary object to search.
|
||||
@param key Key to look for in the dictionary.
|
||||
@param def Default value to return if key not found.
|
||||
@return 1 pointer to internally allocated character string.
|
||||
|
||||
This function locates a key in a dictionary and returns a pointer to its
|
||||
value, or the passed 'def' pointer if no such key can be found in
|
||||
dictionary. The returned character pointer points to data internal to the
|
||||
dictionary object, you should not try to free it or modify it.
|
||||
*/
|
||||
/*--------------------------------------------------------------------------*/
|
||||
const char *dictionary_get(const dictionary *d, const char *key,
|
||||
const char *def);
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief Set a value in a dictionary.
|
||||
@param d dictionary object to modify.
|
||||
@param key Key to modify or add.
|
||||
@param val Value to add.
|
||||
@return int 0 if Ok, anything else otherwise
|
||||
|
||||
If the given key is found in the dictionary, the associated value is
|
||||
replaced by the provided one. If the key cannot be found in the
|
||||
dictionary, it is added to it.
|
||||
|
||||
It is Ok to provide a NULL value for val, but NULL values for the dictionary
|
||||
or the key are considered as errors: the function will return immediately
|
||||
in such a case.
|
||||
|
||||
Notice that if you dictionary_set a variable to NULL, a call to
|
||||
dictionary_get will return a NULL value: the variable will be found, and
|
||||
its value (NULL) is returned. In other words, setting the variable
|
||||
content to NULL is equivalent to deleting the variable from the
|
||||
dictionary. It is not possible (in this implementation) to have a key in
|
||||
the dictionary without value.
|
||||
|
||||
This function returns non-zero in case of failure.
|
||||
*/
|
||||
/*--------------------------------------------------------------------------*/
|
||||
int dictionary_set(dictionary *vd, const char *key, const char *val);
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief Delete a key in a dictionary
|
||||
@param d dictionary object to modify.
|
||||
@param key Key to remove.
|
||||
@return void
|
||||
|
||||
This function deletes a key in a dictionary. Nothing is done if the
|
||||
key cannot be found.
|
||||
*/
|
||||
/*--------------------------------------------------------------------------*/
|
||||
void dictionary_unset(dictionary *d, const char *key);
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief Dump a dictionary to an opened file pointer.
|
||||
@param d Dictionary to dump
|
||||
@param f Opened file pointer.
|
||||
@return void
|
||||
|
||||
Dumps a dictionary onto an opened file pointer. Key pairs are printed out
|
||||
as @c [Key]=[Value], one per line. It is Ok to provide stdout or stderr as
|
||||
output file pointers.
|
||||
*/
|
||||
/*--------------------------------------------------------------------------*/
|
||||
void dictionary_dump(const dictionary *d, FILE *out);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
820
project/app/uvc_app_tiny/uvc_app/param/iniparser.c
Normal file
820
project/app/uvc_app_tiny/uvc_app/param/iniparser.c
Normal file
@@ -0,0 +1,820 @@
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
/**
|
||||
@file iniparser.c
|
||||
@author N. Devillard
|
||||
@brief Parser for ini files.
|
||||
*/
|
||||
/*--------------------------------------------------------------------------*/
|
||||
/*---------------------------- Includes ------------------------------------*/
|
||||
#include "iniparser.h"
|
||||
#include <ctype.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
/*---------------------------- Defines -------------------------------------*/
|
||||
#define ASCIILINESZ (1024)
|
||||
#define INI_INVALID_KEY ((char *)-1)
|
||||
|
||||
/*---------------------------------------------------------------------------
|
||||
Private to this module
|
||||
---------------------------------------------------------------------------*/
|
||||
/**
|
||||
* This enum stores the status for each parsed line (internal use only).
|
||||
*/
|
||||
typedef enum _line_status_ {
|
||||
LINE_UNPROCESSED,
|
||||
LINE_ERROR,
|
||||
LINE_EMPTY,
|
||||
LINE_COMMENT,
|
||||
LINE_SECTION,
|
||||
LINE_VALUE
|
||||
} line_status;
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief Convert a string to lowercase.
|
||||
@param in String to convert.
|
||||
@param out Output buffer.
|
||||
@param len Size of the out buffer.
|
||||
@return ptr to the out buffer or NULL if an error occured.
|
||||
|
||||
This function convert a string into lowercase.
|
||||
At most len - 1 elements of the input string will be converted.
|
||||
*/
|
||||
/*--------------------------------------------------------------------------*/
|
||||
static const char *strlwc(const char *in, char *out, unsigned len) {
|
||||
unsigned i;
|
||||
|
||||
if (in == NULL || out == NULL || len == 0)
|
||||
return NULL;
|
||||
i = 0;
|
||||
while (in[i] != '\0' && i < len - 1) {
|
||||
out[i] = (char)tolower((int)in[i]);
|
||||
i++;
|
||||
}
|
||||
out[i] = '\0';
|
||||
return out;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief Duplicate a string
|
||||
@param s String to duplicate
|
||||
@return Pointer to a newly allocated string, to be freed with free()
|
||||
|
||||
This is a replacement for strdup(). This implementation is provided
|
||||
for systems that do not have it.
|
||||
*/
|
||||
/*--------------------------------------------------------------------------*/
|
||||
static char *xstrdup(const char *s) {
|
||||
char *t;
|
||||
size_t len;
|
||||
if (!s)
|
||||
return NULL;
|
||||
|
||||
len = strlen(s) + 1;
|
||||
t = (char *)malloc(len);
|
||||
if (t) {
|
||||
memcpy(t, s, len);
|
||||
}
|
||||
return t;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief Remove blanks at the beginning and the end of a string.
|
||||
@param str String to parse and alter.
|
||||
@return unsigned New size of the string.
|
||||
*/
|
||||
/*--------------------------------------------------------------------------*/
|
||||
static unsigned strstrip(char *s) {
|
||||
char *last = NULL;
|
||||
char *dest = s;
|
||||
|
||||
if (s == NULL)
|
||||
return 0;
|
||||
|
||||
last = s + strlen(s);
|
||||
while (isspace((int)*s) && *s)
|
||||
s++;
|
||||
while (last > s) {
|
||||
if (!isspace((int)*(last - 1)))
|
||||
break;
|
||||
last--;
|
||||
}
|
||||
*last = (char)0;
|
||||
|
||||
memmove(dest, s, last - s + 1);
|
||||
return last - s;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief Default error callback for iniparser: wraps `fprintf(stderr, ...)`.
|
||||
*/
|
||||
/*--------------------------------------------------------------------------*/
|
||||
static int default_error_callback(const char *format, ...) {
|
||||
int ret;
|
||||
va_list argptr;
|
||||
va_start(argptr, format);
|
||||
ret = vfprintf(stderr, format, argptr);
|
||||
va_end(argptr);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int (*iniparser_error_callback)(const char *,
|
||||
...) = default_error_callback;
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief Configure a function to receive the error messages.
|
||||
@param errback Function to call.
|
||||
|
||||
By default, the error will be printed on stderr. If a null pointer is passed
|
||||
as errback the error callback will be switched back to default.
|
||||
*/
|
||||
/*--------------------------------------------------------------------------*/
|
||||
void iniparser_set_error_callback(int (*errback)(const char *, ...)) {
|
||||
if (errback) {
|
||||
iniparser_error_callback = errback;
|
||||
} else {
|
||||
iniparser_error_callback = default_error_callback;
|
||||
}
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief Get number of sections in a dictionary
|
||||
@param d Dictionary to examine
|
||||
@return int Number of sections found in dictionary
|
||||
|
||||
This function returns the number of sections found in a dictionary.
|
||||
The test to recognize sections is done on the string stored in the
|
||||
dictionary: a section name is given as "section" whereas a key is
|
||||
stored as "section:key", thus the test looks for entries that do not
|
||||
contain a colon.
|
||||
|
||||
This clearly fails in the case a section name contains a colon, but
|
||||
this should simply be avoided.
|
||||
|
||||
This function returns -1 in case of error.
|
||||
*/
|
||||
/*--------------------------------------------------------------------------*/
|
||||
int iniparser_getnsec(const dictionary *d) {
|
||||
int i;
|
||||
int nsec;
|
||||
|
||||
if (d == NULL)
|
||||
return -1;
|
||||
nsec = 0;
|
||||
for (i = 0; i < d->size; i++) {
|
||||
if (d->key[i] == NULL)
|
||||
continue;
|
||||
if (strchr(d->key[i], ':') == NULL) {
|
||||
nsec++;
|
||||
}
|
||||
}
|
||||
return nsec;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief Get name for section n in a dictionary.
|
||||
@param d Dictionary to examine
|
||||
@param n Section number (from 0 to nsec-1).
|
||||
@return Pointer to char string
|
||||
|
||||
This function locates the n-th section in a dictionary and returns
|
||||
its name as a pointer to a string statically allocated inside the
|
||||
dictionary. Do not free or modify the returned string!
|
||||
|
||||
This function returns NULL in case of error.
|
||||
*/
|
||||
/*--------------------------------------------------------------------------*/
|
||||
const char *iniparser_getsecname(const dictionary *d, int n) {
|
||||
int i;
|
||||
int foundsec;
|
||||
|
||||
if (d == NULL || n < 0)
|
||||
return NULL;
|
||||
foundsec = 0;
|
||||
for (i = 0; i < d->size; i++) {
|
||||
if (d->key[i] == NULL)
|
||||
continue;
|
||||
if (strchr(d->key[i], ':') == NULL) {
|
||||
foundsec++;
|
||||
if (foundsec > n)
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (foundsec <= n) {
|
||||
return NULL;
|
||||
}
|
||||
return d->key[i];
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief Dump a dictionary to an opened file pointer.
|
||||
@param d Dictionary to dump.
|
||||
@param f Opened file pointer to dump to.
|
||||
@return void
|
||||
|
||||
This function prints out the contents of a dictionary, one element by
|
||||
line, onto the provided file pointer. It is OK to specify @c stderr
|
||||
or @c stdout as output files. This function is meant for debugging
|
||||
purposes mostly.
|
||||
*/
|
||||
/*--------------------------------------------------------------------------*/
|
||||
void iniparser_dump(const dictionary *d, FILE *f) {
|
||||
int i;
|
||||
|
||||
if (d == NULL || f == NULL)
|
||||
return;
|
||||
for (i = 0; i < d->size; i++) {
|
||||
if (d->key[i] == NULL)
|
||||
continue;
|
||||
if (d->val[i] != NULL) {
|
||||
fprintf(f, "[%s]=[%s]\n", d->key[i], d->val[i]);
|
||||
} else {
|
||||
fprintf(f, "[%s]=UNDEF\n", d->key[i]);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief Save a dictionary to a loadable ini file
|
||||
@param d Dictionary to dump
|
||||
@param f Opened file pointer to dump to
|
||||
@return void
|
||||
|
||||
This function dumps a given dictionary into a loadable ini file.
|
||||
It is Ok to specify @c stderr or @c stdout as output files.
|
||||
*/
|
||||
/*--------------------------------------------------------------------------*/
|
||||
void iniparser_dump_ini(const dictionary *d, FILE *f) {
|
||||
int i;
|
||||
int nsec;
|
||||
const char *secname;
|
||||
|
||||
if (d == NULL || f == NULL)
|
||||
return;
|
||||
|
||||
nsec = iniparser_getnsec(d);
|
||||
if (nsec < 1) {
|
||||
/* No section in file: dump all keys as they are */
|
||||
for (i = 0; i < d->size; i++) {
|
||||
if (d->key[i] == NULL)
|
||||
continue;
|
||||
fprintf(f, "%s = %s\n", d->key[i], d->val[i]);
|
||||
}
|
||||
return;
|
||||
}
|
||||
for (i = 0; i < nsec; i++) {
|
||||
secname = iniparser_getsecname(d, i);
|
||||
iniparser_dumpsection_ini(d, secname, f);
|
||||
}
|
||||
fprintf(f, "\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief Save a dictionary section to a loadable ini file
|
||||
@param d Dictionary to dump
|
||||
@param s Section name of dictionary to dump
|
||||
@param f Opened file pointer to dump to
|
||||
@return void
|
||||
|
||||
This function dumps a given section of a given dictionary into a loadable ini
|
||||
file. It is Ok to specify @c stderr or @c stdout as output files.
|
||||
*/
|
||||
/*--------------------------------------------------------------------------*/
|
||||
void iniparser_dumpsection_ini(const dictionary *d, const char *s, FILE *f) {
|
||||
int j;
|
||||
char keym[ASCIILINESZ + 1];
|
||||
int seclen;
|
||||
|
||||
if (d == NULL || f == NULL)
|
||||
return;
|
||||
if (!iniparser_find_entry(d, s))
|
||||
return;
|
||||
|
||||
seclen = (int)strlen(s);
|
||||
fprintf(f, "\n[%s]\n", s);
|
||||
sprintf(keym, "%s:", s);
|
||||
for (j = 0; j < d->size; j++) {
|
||||
if (d->key[j] == NULL)
|
||||
continue;
|
||||
if (!strncmp(d->key[j], keym, seclen + 1)) {
|
||||
fprintf(f, "%-30s = %s\n", d->key[j] + seclen + 1,
|
||||
d->val[j] ? d->val[j] : "");
|
||||
}
|
||||
}
|
||||
fprintf(f, "\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief Get the number of keys in a section of a dictionary.
|
||||
@param d Dictionary to examine
|
||||
@param s Section name of dictionary to examine
|
||||
@return Number of keys in section
|
||||
*/
|
||||
/*--------------------------------------------------------------------------*/
|
||||
int iniparser_getsecnkeys(const dictionary *d, const char *s) {
|
||||
int seclen, nkeys;
|
||||
char keym[ASCIILINESZ + 1];
|
||||
int j;
|
||||
|
||||
nkeys = 0;
|
||||
|
||||
if (d == NULL)
|
||||
return nkeys;
|
||||
if (!iniparser_find_entry(d, s))
|
||||
return nkeys;
|
||||
|
||||
seclen = (int)strlen(s);
|
||||
strlwc(s, keym, sizeof(keym));
|
||||
keym[seclen] = ':';
|
||||
|
||||
for (j = 0; j < d->size; j++) {
|
||||
if (d->key[j] == NULL)
|
||||
continue;
|
||||
if (!strncmp(d->key[j], keym, seclen + 1))
|
||||
nkeys++;
|
||||
}
|
||||
|
||||
return nkeys;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief Get the number of keys in a section of a dictionary.
|
||||
@param d Dictionary to examine
|
||||
@param s Section name of dictionary to examine
|
||||
@param keys Already allocated array to store the keys in
|
||||
@return The pointer passed as `keys` argument or NULL in case of error
|
||||
|
||||
This function queries a dictionary and finds all keys in a given section.
|
||||
The keys argument should be an array of pointers which size has been
|
||||
determined by calling `iniparser_getsecnkeys` function prior to this one.
|
||||
|
||||
Each pointer in the returned char pointer-to-pointer is pointing to
|
||||
a string allocated in the dictionary; do not free or modify them.
|
||||
*/
|
||||
/*--------------------------------------------------------------------------*/
|
||||
const char **iniparser_getseckeys(const dictionary *d, const char *s,
|
||||
const char **keys) {
|
||||
int i, j, seclen;
|
||||
char keym[ASCIILINESZ + 1];
|
||||
|
||||
if (d == NULL || keys == NULL)
|
||||
return NULL;
|
||||
if (!iniparser_find_entry(d, s))
|
||||
return NULL;
|
||||
|
||||
seclen = (int)strlen(s);
|
||||
strlwc(s, keym, sizeof(keym));
|
||||
keym[seclen] = ':';
|
||||
|
||||
i = 0;
|
||||
|
||||
for (j = 0; j < d->size; j++) {
|
||||
if (d->key[j] == NULL)
|
||||
continue;
|
||||
if (!strncmp(d->key[j], keym, seclen + 1)) {
|
||||
keys[i] = d->key[j];
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
return keys;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief Get the string associated to a key
|
||||
@param d Dictionary to search
|
||||
@param key Key string to look for
|
||||
@param def Default value to return if key not found.
|
||||
@return pointer to statically allocated character string
|
||||
|
||||
This function queries a dictionary for a key. A key as read from an
|
||||
ini file is given as "section:key". If the key cannot be found,
|
||||
the pointer passed as 'def' is returned.
|
||||
The returned char pointer is pointing to a string allocated in
|
||||
the dictionary, do not free or modify it.
|
||||
*/
|
||||
/*--------------------------------------------------------------------------*/
|
||||
const char *iniparser_getstring(const dictionary *d, const char *key,
|
||||
const char *def) {
|
||||
const char *lc_key;
|
||||
const char *sval;
|
||||
char tmp_str[ASCIILINESZ + 1];
|
||||
|
||||
if (d == NULL || key == NULL)
|
||||
return def;
|
||||
|
||||
lc_key = strlwc(key, tmp_str, sizeof(tmp_str));
|
||||
sval = dictionary_get(d, lc_key, def);
|
||||
return sval;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief Get the string associated to a key, convert to an long int
|
||||
@param d Dictionary to search
|
||||
@param key Key string to look for
|
||||
@param notfound Value to return in case of error
|
||||
@return long integer
|
||||
|
||||
This function queries a dictionary for a key. A key as read from an
|
||||
ini file is given as "section:key". If the key cannot be found,
|
||||
the notfound value is returned.
|
||||
|
||||
Supported values for integers include the usual C notation
|
||||
so decimal, octal (starting with 0) and hexadecimal (starting with 0x)
|
||||
are supported. Examples:
|
||||
|
||||
"42" -> 42
|
||||
"042" -> 34 (octal -> decimal)
|
||||
"0x42" -> 66 (hexa -> decimal)
|
||||
|
||||
Warning: the conversion may overflow in various ways. Conversion is
|
||||
totally outsourced to strtol(), see the associated man page for overflow
|
||||
handling.
|
||||
|
||||
Credits: Thanks to A. Becker for suggesting strtol()
|
||||
*/
|
||||
/*--------------------------------------------------------------------------*/
|
||||
long int iniparser_getlongint(const dictionary *d, const char *key,
|
||||
long int notfound) {
|
||||
const char *str;
|
||||
|
||||
str = iniparser_getstring(d, key, INI_INVALID_KEY);
|
||||
if (str == INI_INVALID_KEY)
|
||||
return notfound;
|
||||
return strtol(str, NULL, 0);
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief Get the string associated to a key, convert to an int
|
||||
@param d Dictionary to search
|
||||
@param key Key string to look for
|
||||
@param notfound Value to return in case of error
|
||||
@return integer
|
||||
|
||||
This function queries a dictionary for a key. A key as read from an
|
||||
ini file is given as "section:key". If the key cannot be found,
|
||||
the notfound value is returned.
|
||||
|
||||
Supported values for integers include the usual C notation
|
||||
so decimal, octal (starting with 0) and hexadecimal (starting with 0x)
|
||||
are supported. Examples:
|
||||
|
||||
"42" -> 42
|
||||
"042" -> 34 (octal -> decimal)
|
||||
"0x42" -> 66 (hexa -> decimal)
|
||||
|
||||
Warning: the conversion may overflow in various ways. Conversion is
|
||||
totally outsourced to strtol(), see the associated man page for overflow
|
||||
handling.
|
||||
|
||||
Credits: Thanks to A. Becker for suggesting strtol()
|
||||
*/
|
||||
/*--------------------------------------------------------------------------*/
|
||||
int iniparser_getint(const dictionary *d, const char *key, int notfound) {
|
||||
return (int)iniparser_getlongint(d, key, notfound);
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief Get the string associated to a key, convert to a double
|
||||
@param d Dictionary to search
|
||||
@param key Key string to look for
|
||||
@param notfound Value to return in case of error
|
||||
@return double
|
||||
|
||||
This function queries a dictionary for a key. A key as read from an
|
||||
ini file is given as "section:key". If the key cannot be found,
|
||||
the notfound value is returned.
|
||||
*/
|
||||
/*--------------------------------------------------------------------------*/
|
||||
double iniparser_getdouble(const dictionary *d, const char *key,
|
||||
double notfound) {
|
||||
const char *str;
|
||||
|
||||
str = iniparser_getstring(d, key, INI_INVALID_KEY);
|
||||
if (str == INI_INVALID_KEY)
|
||||
return notfound;
|
||||
return atof(str);
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief Get the string associated to a key, convert to a boolean
|
||||
@param d Dictionary to search
|
||||
@param key Key string to look for
|
||||
@param notfound Value to return in case of error
|
||||
@return integer
|
||||
|
||||
This function queries a dictionary for a key. A key as read from an
|
||||
ini file is given as "section:key". If the key cannot be found,
|
||||
the notfound value is returned.
|
||||
|
||||
A true boolean is found if one of the following is matched:
|
||||
|
||||
- A string starting with 'y'
|
||||
- A string starting with 'Y'
|
||||
- A string starting with 't'
|
||||
- A string starting with 'T'
|
||||
- A string starting with '1'
|
||||
|
||||
A false boolean is found if one of the following is matched:
|
||||
|
||||
- A string starting with 'n'
|
||||
- A string starting with 'N'
|
||||
- A string starting with 'f'
|
||||
- A string starting with 'F'
|
||||
- A string starting with '0'
|
||||
|
||||
The notfound value returned if no boolean is identified, does not
|
||||
necessarily have to be 0 or 1.
|
||||
*/
|
||||
/*--------------------------------------------------------------------------*/
|
||||
int iniparser_getboolean(const dictionary *d, const char *key, int notfound) {
|
||||
int ret;
|
||||
const char *c;
|
||||
|
||||
c = iniparser_getstring(d, key, INI_INVALID_KEY);
|
||||
if (c == INI_INVALID_KEY)
|
||||
return notfound;
|
||||
if (c[0] == 'y' || c[0] == 'Y' || c[0] == '1' || c[0] == 't' || c[0] == 'T') {
|
||||
ret = 1;
|
||||
} else if (c[0] == 'n' || c[0] == 'N' || c[0] == '0' || c[0] == 'f' ||
|
||||
c[0] == 'F') {
|
||||
ret = 0;
|
||||
} else {
|
||||
ret = notfound;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief Finds out if a given entry exists in a dictionary
|
||||
@param ini Dictionary to search
|
||||
@param entry Name of the entry to look for
|
||||
@return integer 1 if entry exists, 0 otherwise
|
||||
|
||||
Finds out if a given entry exists in the dictionary. Since sections
|
||||
are stored as keys with NULL associated values, this is the only way
|
||||
of querying for the presence of sections in a dictionary.
|
||||
*/
|
||||
/*--------------------------------------------------------------------------*/
|
||||
int iniparser_find_entry(const dictionary *ini, const char *entry) {
|
||||
int found = 0;
|
||||
if (iniparser_getstring(ini, entry, INI_INVALID_KEY) != INI_INVALID_KEY) {
|
||||
found = 1;
|
||||
}
|
||||
return found;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief Set an entry in a dictionary.
|
||||
@param ini Dictionary to modify.
|
||||
@param entry Entry to modify (entry name)
|
||||
@param val New value to associate to the entry.
|
||||
@return int 0 if Ok, -1 otherwise.
|
||||
|
||||
If the given entry can be found in the dictionary, it is modified to
|
||||
contain the provided value. If it cannot be found, the entry is created.
|
||||
It is Ok to set val to NULL.
|
||||
*/
|
||||
/*--------------------------------------------------------------------------*/
|
||||
int iniparser_set(dictionary *ini, const char *entry, const char *val) {
|
||||
char tmp_str[ASCIILINESZ + 1];
|
||||
return dictionary_set(ini, strlwc(entry, tmp_str, sizeof(tmp_str)), val);
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief Delete an entry in a dictionary
|
||||
@param ini Dictionary to modify
|
||||
@param entry Entry to delete (entry name)
|
||||
@return void
|
||||
|
||||
If the given entry can be found, it is deleted from the dictionary.
|
||||
*/
|
||||
/*--------------------------------------------------------------------------*/
|
||||
void iniparser_unset(dictionary *ini, const char *entry) {
|
||||
char tmp_str[ASCIILINESZ + 1];
|
||||
dictionary_unset(ini, strlwc(entry, tmp_str, sizeof(tmp_str)));
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief Load a single line from an INI file
|
||||
@param input_line Input line, may be concatenated multi-line input
|
||||
@param section Output space to store section
|
||||
@param key Output space to store key
|
||||
@param value Output space to store value
|
||||
@return line_status value
|
||||
*/
|
||||
/*--------------------------------------------------------------------------*/
|
||||
static line_status iniparser_line(const char *input_line, char *section,
|
||||
char *key, char *value) {
|
||||
line_status sta;
|
||||
char *line = NULL;
|
||||
size_t len;
|
||||
|
||||
line = xstrdup(input_line);
|
||||
len = strstrip(line);
|
||||
|
||||
sta = LINE_UNPROCESSED;
|
||||
if (len < 1) {
|
||||
/* Empty line */
|
||||
sta = LINE_EMPTY;
|
||||
} else if (line[0] == '#' || line[0] == ';') {
|
||||
/* Comment line */
|
||||
sta = LINE_COMMENT;
|
||||
} else if (line[0] == '[' && line[len - 1] == ']') {
|
||||
/* Section name */
|
||||
sscanf(line, "[%[^]]", section);
|
||||
strstrip(section);
|
||||
strlwc(section, section, len);
|
||||
sta = LINE_SECTION;
|
||||
} else if (sscanf(line, "%[^=] = \"%[^\"]\"", key, value) == 2 ||
|
||||
sscanf(line, "%[^=] = '%[^\']'", key, value) == 2) {
|
||||
/* Usual key=value with quotes, with or without comments */
|
||||
strstrip(key);
|
||||
strlwc(key, key, len);
|
||||
/* Don't strip spaces from values surrounded with quotes */
|
||||
sta = LINE_VALUE;
|
||||
} else if (sscanf(line, "%[^=] = %[^;#]", key, value) == 2) {
|
||||
/* Usual key=value without quotes, with or without comments */
|
||||
strstrip(key);
|
||||
strlwc(key, key, len);
|
||||
strstrip(value);
|
||||
/*
|
||||
* sscanf cannot handle '' or "" as empty values
|
||||
* this is done here
|
||||
*/
|
||||
if (!strcmp(value, "\"\"") || (!strcmp(value, "''"))) {
|
||||
value[0] = 0;
|
||||
}
|
||||
sta = LINE_VALUE;
|
||||
} else if (sscanf(line, "%[^=] = %[;#]", key, value) == 2 ||
|
||||
sscanf(line, "%[^=] %[=]", key, value) == 2) {
|
||||
/*
|
||||
* Special cases:
|
||||
* key=
|
||||
* key=;
|
||||
* key=#
|
||||
*/
|
||||
strstrip(key);
|
||||
strlwc(key, key, len);
|
||||
value[0] = 0;
|
||||
sta = LINE_VALUE;
|
||||
} else {
|
||||
/* Generate syntax error */
|
||||
sta = LINE_ERROR;
|
||||
}
|
||||
|
||||
free(line);
|
||||
return sta;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief Parse an ini file and return an allocated dictionary object
|
||||
@param ininame Name of the ini file to read.
|
||||
@return Pointer to newly allocated dictionary
|
||||
|
||||
This is the parser for ini files. This function is called, providing
|
||||
the name of the file to be read. It returns a dictionary object that
|
||||
should not be accessed directly, but through accessor functions
|
||||
instead.
|
||||
|
||||
The returned dictionary must be freed using iniparser_freedict().
|
||||
*/
|
||||
/*--------------------------------------------------------------------------*/
|
||||
dictionary *iniparser_load(const char *ininame) {
|
||||
FILE *in;
|
||||
|
||||
char line[ASCIILINESZ + 1];
|
||||
char section[ASCIILINESZ + 1];
|
||||
char key[ASCIILINESZ + 1];
|
||||
char tmp[(ASCIILINESZ * 2) + 2];
|
||||
char val[ASCIILINESZ + 1];
|
||||
|
||||
int last = 0;
|
||||
int len;
|
||||
int lineno = 0;
|
||||
int errs = 0;
|
||||
int mem_err = 0;
|
||||
|
||||
dictionary *dict;
|
||||
|
||||
if ((in = fopen(ininame, "r")) == NULL) {
|
||||
iniparser_error_callback("iniparser: cannot open %s\n", ininame);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
dict = dictionary_new(0);
|
||||
if (!dict) {
|
||||
fclose(in);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
memset(line, 0, ASCIILINESZ);
|
||||
memset(section, 0, ASCIILINESZ);
|
||||
memset(key, 0, ASCIILINESZ);
|
||||
memset(val, 0, ASCIILINESZ);
|
||||
last = 0;
|
||||
|
||||
while (fgets(line + last, ASCIILINESZ - last, in) != NULL) {
|
||||
lineno++;
|
||||
len = (int)strlen(line) - 1;
|
||||
if (len <= 0)
|
||||
continue;
|
||||
/* Safety check against buffer overflows */
|
||||
if (line[len] != '\n' && !feof(in)) {
|
||||
iniparser_error_callback("iniparser: input line too long in %s (%d)\n",
|
||||
ininame, lineno);
|
||||
dictionary_del(dict);
|
||||
fclose(in);
|
||||
return NULL;
|
||||
}
|
||||
/* Get rid of \n and spaces at end of line */
|
||||
while ((len >= 0) && ((line[len] == '\n') || (isspace(line[len])))) {
|
||||
line[len] = 0;
|
||||
len--;
|
||||
}
|
||||
if (len < 0) { /* Line was entirely \n and/or spaces */
|
||||
len = 0;
|
||||
}
|
||||
/* Detect multi-line */
|
||||
if (line[len] == '\\') {
|
||||
/* Multi-line value */
|
||||
last = len;
|
||||
continue;
|
||||
} else {
|
||||
last = 0;
|
||||
}
|
||||
switch (iniparser_line(line, section, key, val)) {
|
||||
case LINE_EMPTY:
|
||||
case LINE_COMMENT:
|
||||
break;
|
||||
|
||||
case LINE_SECTION:
|
||||
mem_err = dictionary_set(dict, section, NULL);
|
||||
break;
|
||||
|
||||
case LINE_VALUE:
|
||||
sprintf(tmp, "%s:%s", section, key);
|
||||
mem_err = dictionary_set(dict, tmp, val);
|
||||
break;
|
||||
|
||||
case LINE_ERROR:
|
||||
iniparser_error_callback("iniparser: syntax error in %s (%d):\n-> %s\n",
|
||||
ininame, lineno, line);
|
||||
errs++;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
memset(line, 0, ASCIILINESZ);
|
||||
last = 0;
|
||||
if (mem_err < 0) {
|
||||
iniparser_error_callback("iniparser: memory allocation failure\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (errs) {
|
||||
dictionary_del(dict);
|
||||
dict = NULL;
|
||||
}
|
||||
fclose(in);
|
||||
return dict;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief Free all memory associated to an ini dictionary
|
||||
@param d Dictionary to free
|
||||
@return void
|
||||
|
||||
Free all memory associated to an ini dictionary.
|
||||
It is mandatory to call this function before the dictionary object
|
||||
gets out of the current context.
|
||||
*/
|
||||
/*--------------------------------------------------------------------------*/
|
||||
void iniparser_freedict(dictionary *d) { dictionary_del(d); }
|
||||
356
project/app/uvc_app_tiny/uvc_app/param/iniparser.h
Normal file
356
project/app/uvc_app_tiny/uvc_app/param/iniparser.h
Normal file
@@ -0,0 +1,356 @@
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
/**
|
||||
@file iniparser.h
|
||||
@author N. Devillard
|
||||
@brief Parser for ini files.
|
||||
*/
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef _INIPARSER_H_
|
||||
#define _INIPARSER_H_
|
||||
|
||||
/*---------------------------------------------------------------------------
|
||||
Includes
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
/*
|
||||
* The following #include is necessary on many Unixes but not Linux.
|
||||
* It is not needed for Windows platforms.
|
||||
* Uncomment it if needed.
|
||||
*/
|
||||
/* #include <unistd.h> */
|
||||
|
||||
#include "dictionary.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief Configure a function to receive the error messages.
|
||||
@param errback Function to call.
|
||||
|
||||
By default, the error will be printed on stderr. If a null pointer is passed
|
||||
as errback the error callback will be switched back to default.
|
||||
*/
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
void iniparser_set_error_callback(int (*errback)(const char *, ...));
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief Get number of sections in a dictionary
|
||||
@param d Dictionary to examine
|
||||
@return int Number of sections found in dictionary
|
||||
|
||||
This function returns the number of sections found in a dictionary.
|
||||
The test to recognize sections is done on the string stored in the
|
||||
dictionary: a section name is given as "section" whereas a key is
|
||||
stored as "section:key", thus the test looks for entries that do not
|
||||
contain a colon.
|
||||
|
||||
This clearly fails in the case a section name contains a colon, but
|
||||
this should simply be avoided.
|
||||
|
||||
This function returns -1 in case of error.
|
||||
*/
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
int iniparser_getnsec(const dictionary *d);
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief Get name for section n in a dictionary.
|
||||
@param d Dictionary to examine
|
||||
@param n Section number (from 0 to nsec-1).
|
||||
@return Pointer to char string
|
||||
|
||||
This function locates the n-th section in a dictionary and returns
|
||||
its name as a pointer to a string statically allocated inside the
|
||||
dictionary. Do not free or modify the returned string!
|
||||
|
||||
This function returns NULL in case of error.
|
||||
*/
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
const char *iniparser_getsecname(const dictionary *d, int n);
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief Save a dictionary to a loadable ini file
|
||||
@param d Dictionary to dump
|
||||
@param f Opened file pointer to dump to
|
||||
@return void
|
||||
|
||||
This function dumps a given dictionary into a loadable ini file.
|
||||
It is Ok to specify @c stderr or @c stdout as output files.
|
||||
*/
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
void iniparser_dump_ini(const dictionary *d, FILE *f);
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief Save a dictionary section to a loadable ini file
|
||||
@param d Dictionary to dump
|
||||
@param s Section name of dictionary to dump
|
||||
@param f Opened file pointer to dump to
|
||||
@return void
|
||||
|
||||
This function dumps a given section of a given dictionary into a loadable ini
|
||||
file. It is Ok to specify @c stderr or @c stdout as output files.
|
||||
*/
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
void iniparser_dumpsection_ini(const dictionary *d, const char *s, FILE *f);
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief Dump a dictionary to an opened file pointer.
|
||||
@param d Dictionary to dump.
|
||||
@param f Opened file pointer to dump to.
|
||||
@return void
|
||||
|
||||
This function prints out the contents of a dictionary, one element by
|
||||
line, onto the provided file pointer. It is OK to specify @c stderr
|
||||
or @c stdout as output files. This function is meant for debugging
|
||||
purposes mostly.
|
||||
*/
|
||||
/*--------------------------------------------------------------------------*/
|
||||
void iniparser_dump(const dictionary *d, FILE *f);
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief Get the number of keys in a section of a dictionary.
|
||||
@param d Dictionary to examine
|
||||
@param s Section name of dictionary to examine
|
||||
@return Number of keys in section
|
||||
*/
|
||||
/*--------------------------------------------------------------------------*/
|
||||
int iniparser_getsecnkeys(const dictionary *d, const char *s);
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief Get the number of keys in a section of a dictionary.
|
||||
@param d Dictionary to examine
|
||||
@param s Section name of dictionary to examine
|
||||
@param keys Already allocated array to store the keys in
|
||||
@return The pointer passed as `keys` argument or NULL in case of error
|
||||
|
||||
This function queries a dictionary and finds all keys in a given section.
|
||||
The keys argument should be an array of pointers which size has been
|
||||
determined by calling `iniparser_getsecnkeys` function prior to this one.
|
||||
|
||||
Each pointer in the returned char pointer-to-pointer is pointing to
|
||||
a string allocated in the dictionary; do not free or modify them.
|
||||
*/
|
||||
/*--------------------------------------------------------------------------*/
|
||||
const char **iniparser_getseckeys(const dictionary *d, const char *s,
|
||||
const char **keys);
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief Get the string associated to a key
|
||||
@param d Dictionary to search
|
||||
@param key Key string to look for
|
||||
@param def Default value to return if key not found.
|
||||
@return pointer to statically allocated character string
|
||||
|
||||
This function queries a dictionary for a key. A key as read from an
|
||||
ini file is given as "section:key". If the key cannot be found,
|
||||
the pointer passed as 'def' is returned.
|
||||
The returned char pointer is pointing to a string allocated in
|
||||
the dictionary, do not free or modify it.
|
||||
*/
|
||||
/*--------------------------------------------------------------------------*/
|
||||
const char *iniparser_getstring(const dictionary *d, const char *key,
|
||||
const char *def);
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief Get the string associated to a key, convert to an int
|
||||
@param d Dictionary to search
|
||||
@param key Key string to look for
|
||||
@param notfound Value to return in case of error
|
||||
@return integer
|
||||
|
||||
This function queries a dictionary for a key. A key as read from an
|
||||
ini file is given as "section:key". If the key cannot be found,
|
||||
the notfound value is returned.
|
||||
|
||||
Supported values for integers include the usual C notation
|
||||
so decimal, octal (starting with 0) and hexadecimal (starting with 0x)
|
||||
are supported. Examples:
|
||||
|
||||
- "42" -> 42
|
||||
- "042" -> 34 (octal -> decimal)
|
||||
- "0x42" -> 66 (hexa -> decimal)
|
||||
|
||||
Warning: the conversion may overflow in various ways. Conversion is
|
||||
totally outsourced to strtol(), see the associated man page for overflow
|
||||
handling.
|
||||
|
||||
Credits: Thanks to A. Becker for suggesting strtol()
|
||||
*/
|
||||
/*--------------------------------------------------------------------------*/
|
||||
int iniparser_getint(const dictionary *d, const char *key, int notfound);
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief Get the string associated to a key, convert to an long int
|
||||
@param d Dictionary to search
|
||||
@param key Key string to look for
|
||||
@param notfound Value to return in case of error
|
||||
@return integer
|
||||
|
||||
This function queries a dictionary for a key. A key as read from an
|
||||
ini file is given as "section:key". If the key cannot be found,
|
||||
the notfound value is returned.
|
||||
|
||||
Supported values for integers include the usual C notation
|
||||
so decimal, octal (starting with 0) and hexadecimal (starting with 0x)
|
||||
are supported. Examples:
|
||||
|
||||
- "42" -> 42
|
||||
- "042" -> 34 (octal -> decimal)
|
||||
- "0x42" -> 66 (hexa -> decimal)
|
||||
|
||||
Warning: the conversion may overflow in various ways. Conversion is
|
||||
totally outsourced to strtol(), see the associated man page for overflow
|
||||
handling.
|
||||
*/
|
||||
/*--------------------------------------------------------------------------*/
|
||||
long int iniparser_getlongint(const dictionary *d, const char *key,
|
||||
long int notfound);
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief Get the string associated to a key, convert to a double
|
||||
@param d Dictionary to search
|
||||
@param key Key string to look for
|
||||
@param notfound Value to return in case of error
|
||||
@return double
|
||||
|
||||
This function queries a dictionary for a key. A key as read from an
|
||||
ini file is given as "section:key". If the key cannot be found,
|
||||
the notfound value is returned.
|
||||
*/
|
||||
/*--------------------------------------------------------------------------*/
|
||||
double iniparser_getdouble(const dictionary *d, const char *key,
|
||||
double notfound);
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief Get the string associated to a key, convert to a boolean
|
||||
@param d Dictionary to search
|
||||
@param key Key string to look for
|
||||
@param notfound Value to return in case of error
|
||||
@return integer
|
||||
|
||||
This function queries a dictionary for a key. A key as read from an
|
||||
ini file is given as "section:key". If the key cannot be found,
|
||||
the notfound value is returned.
|
||||
|
||||
A true boolean is found if one of the following is matched:
|
||||
|
||||
- A string starting with 'y'
|
||||
- A string starting with 'Y'
|
||||
- A string starting with 't'
|
||||
- A string starting with 'T'
|
||||
- A string starting with '1'
|
||||
|
||||
A false boolean is found if one of the following is matched:
|
||||
|
||||
- A string starting with 'n'
|
||||
- A string starting with 'N'
|
||||
- A string starting with 'f'
|
||||
- A string starting with 'F'
|
||||
- A string starting with '0'
|
||||
|
||||
The notfound value returned if no boolean is identified, does not
|
||||
necessarily have to be 0 or 1.
|
||||
*/
|
||||
/*--------------------------------------------------------------------------*/
|
||||
int iniparser_getboolean(const dictionary *d, const char *key, int notfound);
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief Set an entry in a dictionary.
|
||||
@param ini Dictionary to modify.
|
||||
@param entry Entry to modify (entry name)
|
||||
@param val New value to associate to the entry.
|
||||
@return int 0 if Ok, -1 otherwise.
|
||||
|
||||
If the given entry can be found in the dictionary, it is modified to
|
||||
contain the provided value. If it cannot be found, the entry is created.
|
||||
It is Ok to set val to NULL.
|
||||
*/
|
||||
/*--------------------------------------------------------------------------*/
|
||||
int iniparser_set(dictionary *ini, const char *entry, const char *val);
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief Delete an entry in a dictionary
|
||||
@param ini Dictionary to modify
|
||||
@param entry Entry to delete (entry name)
|
||||
@return void
|
||||
|
||||
If the given entry can be found, it is deleted from the dictionary.
|
||||
*/
|
||||
/*--------------------------------------------------------------------------*/
|
||||
void iniparser_unset(dictionary *ini, const char *entry);
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief Finds out if a given entry exists in a dictionary
|
||||
@param ini Dictionary to search
|
||||
@param entry Name of the entry to look for
|
||||
@return integer 1 if entry exists, 0 otherwise
|
||||
|
||||
Finds out if a given entry exists in the dictionary. Since sections
|
||||
are stored as keys with NULL associated values, this is the only way
|
||||
of querying for the presence of sections in a dictionary.
|
||||
*/
|
||||
/*--------------------------------------------------------------------------*/
|
||||
int iniparser_find_entry(const dictionary *ini, const char *entry);
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief Parse an ini file and return an allocated dictionary object
|
||||
@param ininame Name of the ini file to read.
|
||||
@return Pointer to newly allocated dictionary
|
||||
|
||||
This is the parser for ini files. This function is called, providing
|
||||
the name of the file to be read. It returns a dictionary object that
|
||||
should not be accessed directly, but through accessor functions
|
||||
instead.
|
||||
|
||||
The returned dictionary must be freed using iniparser_freedict().
|
||||
*/
|
||||
/*--------------------------------------------------------------------------*/
|
||||
dictionary *iniparser_load(const char *ininame);
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief Free all memory associated to an ini dictionary
|
||||
@param d Dictionary to free
|
||||
@return void
|
||||
|
||||
Free all memory associated to an ini dictionary.
|
||||
It is mandatory to call this function before the dictionary object
|
||||
gets out of the current context.
|
||||
*/
|
||||
/*--------------------------------------------------------------------------*/
|
||||
void iniparser_freedict(dictionary *d);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
139
project/app/uvc_app_tiny/uvc_app/param/param.c
Normal file
139
project/app/uvc_app_tiny/uvc_app/param/param.c
Normal file
@@ -0,0 +1,139 @@
|
||||
// Copyright 2021 Rockchip Electronics Co., Ltd. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
#include "iniparser.h"
|
||||
#include "uvc_log.h"
|
||||
#include <pthread.h>
|
||||
#ifdef LOG_TAG
|
||||
#undef LOG_TAG
|
||||
#endif
|
||||
#define LOG_TAG "param.c"
|
||||
|
||||
char g_ini_path_[256];
|
||||
dictionary *g_ini_d_;
|
||||
static pthread_mutex_t g_param_mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
|
||||
int rk_param_dump() {
|
||||
const char *section_name;
|
||||
const char *keys[32];
|
||||
int section_keys;
|
||||
int section_num = iniparser_getnsec(g_ini_d_);
|
||||
LOG_INFO("section_num is %d\n", section_num);
|
||||
|
||||
for (int i = 0; i < section_num; i++) {
|
||||
section_name = iniparser_getsecname(g_ini_d_, i);
|
||||
LOG_INFO("section_name is %s\n", section_name);
|
||||
section_keys = iniparser_getsecnkeys(g_ini_d_, section_name);
|
||||
for (int j = 0; j < section_keys; j++) {
|
||||
iniparser_getseckeys(g_ini_d_, section_name, keys);
|
||||
LOG_INFO("%s = %s\n", keys[j],
|
||||
iniparser_getstring(g_ini_d_, keys[j], ""));
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int rk_param_save() {
|
||||
FILE *fp = fopen(g_ini_path_, "w");
|
||||
if (fp == NULL) {
|
||||
LOG_ERROR("%s, fopen error!\n", g_ini_path_);
|
||||
iniparser_freedict(g_ini_d_);
|
||||
g_ini_d_ = NULL;
|
||||
return -1;
|
||||
}
|
||||
iniparser_dump_ini(g_ini_d_, fp);
|
||||
|
||||
fflush(fp);
|
||||
fclose(fp);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int rk_param_get_int(const char *entry, int default_val) {
|
||||
int ret;
|
||||
pthread_mutex_lock(&g_param_mutex);
|
||||
ret = iniparser_getint(g_ini_d_, entry, default_val);
|
||||
pthread_mutex_unlock(&g_param_mutex);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int rk_param_set_int(const char *entry, int val) {
|
||||
char tmp[8];
|
||||
sprintf(tmp, "%d", val);
|
||||
pthread_mutex_lock(&g_param_mutex);
|
||||
iniparser_set(g_ini_d_, entry, tmp);
|
||||
rk_param_save();
|
||||
pthread_mutex_unlock(&g_param_mutex);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
const char *rk_param_get_string(const char *entry, const char *default_val) {
|
||||
const char *ret;
|
||||
pthread_mutex_lock(&g_param_mutex);
|
||||
ret = iniparser_getstring(g_ini_d_, entry, default_val);
|
||||
pthread_mutex_unlock(&g_param_mutex);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int rk_param_set_string(const char *entry, const char *val) {
|
||||
pthread_mutex_lock(&g_param_mutex);
|
||||
iniparser_set(g_ini_d_, entry, val);
|
||||
rk_param_save();
|
||||
pthread_mutex_unlock(&g_param_mutex);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int rk_param_init(char *ini_path) {
|
||||
LOG_INFO("%s\n", __func__);
|
||||
pthread_mutex_lock(&g_param_mutex);
|
||||
g_ini_d_ = NULL;
|
||||
if (ini_path)
|
||||
memcpy(g_ini_path_, ini_path, strlen(ini_path));
|
||||
else
|
||||
memcpy(g_ini_path_, "/oem/usr/share/rkuvc.ini", strlen("/oem/usr/share/rkuvc.ini"));
|
||||
LOG_INFO("g_ini_path_ is %s\n", g_ini_path_);
|
||||
|
||||
g_ini_d_ = iniparser_load(g_ini_path_);
|
||||
if (g_ini_d_ == NULL) {
|
||||
LOG_ERROR("iniparser_load error!\n");
|
||||
return -1;
|
||||
}
|
||||
rk_param_dump();
|
||||
pthread_mutex_unlock(&g_param_mutex);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int rk_param_deinit() {
|
||||
LOG_INFO("%s\n", __func__);
|
||||
if (g_ini_d_ == NULL)
|
||||
return 0;
|
||||
pthread_mutex_lock(&g_param_mutex);
|
||||
rk_param_save();
|
||||
if (g_ini_d_)
|
||||
iniparser_freedict(g_ini_d_);
|
||||
pthread_mutex_unlock(&g_param_mutex);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int rk_param_reload() {
|
||||
LOG_INFO("%s\n", __func__);
|
||||
pthread_mutex_lock(&g_param_mutex);
|
||||
if (g_ini_d_)
|
||||
iniparser_freedict(g_ini_d_);
|
||||
g_ini_d_ = iniparser_load(g_ini_path_);
|
||||
if (g_ini_d_ == NULL) {
|
||||
LOG_ERROR("iniparser_load error!\n");
|
||||
return -1;
|
||||
}
|
||||
rk_param_dump();
|
||||
pthread_mutex_unlock(&g_param_mutex);
|
||||
|
||||
return 0;
|
||||
}
|
||||
28
project/app/uvc_app_tiny/uvc_app/param/param.h
Normal file
28
project/app/uvc_app_tiny/uvc_app/param/param.h
Normal file
@@ -0,0 +1,28 @@
|
||||
// Copyright 2021 Rockchip Electronics Co., Ltd. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#include "iniparser.h"
|
||||
|
||||
extern dictionary *g_ini_d_;
|
||||
|
||||
int rk_param_get_int(const char *entry, int default_val);
|
||||
int rk_param_set_int(const char *entry, int val);
|
||||
const char *rk_param_get_string(const char *entry, const char *default_val);
|
||||
int rk_param_set_string(const char *entry, const char *val);
|
||||
int rk_param_save();
|
||||
int rk_param_init(char *ini_path);
|
||||
int rk_param_deinit();
|
||||
int rk_param_reload();
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* __cplusplus */
|
||||
82
project/app/uvc_app_tiny/uvc_app/rkuvc.ini
Normal file
82
project/app/uvc_app_tiny/uvc_app/rkuvc.ini
Normal file
@@ -0,0 +1,82 @@
|
||||
[video.source]
|
||||
enable_aiq = 1
|
||||
enable_vo = 0
|
||||
enable_npu = 0
|
||||
enable_uac = 0
|
||||
|
||||
[isp.0.adjustment]
|
||||
contrast = 50
|
||||
brightness = 50
|
||||
saturation = 50
|
||||
sharpness = 50
|
||||
fps = 30
|
||||
hue = 50
|
||||
|
||||
[isp.0.exposure]
|
||||
iris_type = auto
|
||||
exposure_mode = auto
|
||||
gain_mode = auto
|
||||
auto_iris_level = 5
|
||||
auto_exposure_enabled = 1
|
||||
audo_gain_enabled = 1
|
||||
exposure_time = 1/6
|
||||
exposure_gain = 1
|
||||
|
||||
[isp.0.night_to_day]
|
||||
night_to_day = day
|
||||
night_to_day_filter_level = 5
|
||||
night_to_day_filter_time = 5
|
||||
dawn_time = 07:00:00
|
||||
dusk_time = 18:00:00
|
||||
ircut_filter_action = day
|
||||
over_exposure_suppress = open
|
||||
over_exposure_suppress_type = auto
|
||||
fill_light_mode = IR
|
||||
brightness_adjustment_mode = auto
|
||||
light_brightness = 1
|
||||
distance_level = 1
|
||||
|
||||
[isp.0.blc]
|
||||
blc_region = close
|
||||
blc_strength = 1
|
||||
wdr = close
|
||||
wdr_level = 0
|
||||
hdr = close
|
||||
hdr_level = 1
|
||||
hlc = close
|
||||
hlc_level = 0
|
||||
dark_boost_level = 0
|
||||
position_x = 0
|
||||
position_y = 0
|
||||
blc_region_width = 120
|
||||
blc_region_high = 92
|
||||
|
||||
[isp.0.white_blance]
|
||||
white_blance_style = autoWhiteBalance
|
||||
white_blance_red = 50
|
||||
white_blance_green = 50
|
||||
white_blance_blue = 50
|
||||
|
||||
[isp.0.enhancement]
|
||||
noise_reduce_mode = close
|
||||
denoise_level = 50
|
||||
spatial_denoise_level = 50
|
||||
temporal_denoise_level = 50
|
||||
dehaze = close
|
||||
dehaze_level = 0
|
||||
dis = close
|
||||
gray_scale_mode = [0-255]
|
||||
image_rotation = 0
|
||||
distortion_correction = close
|
||||
ldch_level = 0
|
||||
|
||||
[isp.0.video_adjustment]
|
||||
image_flip = close
|
||||
scene_mode = indoor
|
||||
power_line_frequency_mode = PAL(50HZ)
|
||||
|
||||
[isp.0.auto_focus]
|
||||
af_mode = semi-auto
|
||||
zoom_level = 0
|
||||
focus_level = 0
|
||||
|
||||
79
project/app/uvc_app_tiny/uvc_app/uac/configs/configs_skv.json
Executable file
79
project/app/uvc_app_tiny/uvc_app/uac/configs/configs_skv.json
Executable file
@@ -0,0 +1,79 @@
|
||||
{
|
||||
"skv_configs": {
|
||||
"aec": {
|
||||
"status" : "disable",
|
||||
"drop_ref_channel" : 0,
|
||||
"delay_len" : 0,
|
||||
"look_ahead" : 0
|
||||
},
|
||||
"bf": {
|
||||
"status" : "enable",
|
||||
"targ" : 0,
|
||||
"drop_ref_channel" : 0
|
||||
},
|
||||
"fast_aec": {
|
||||
"status" : "enable"
|
||||
},
|
||||
"aes": {
|
||||
"status" : "enable",
|
||||
"beta_up": "float:0.0005",
|
||||
"beta_down": "float:0.01"
|
||||
},
|
||||
"gsc": {
|
||||
"status" : "disable",
|
||||
"method" : 0
|
||||
},
|
||||
"agc": {
|
||||
"status" : "enable",
|
||||
"attack_time" : "float:100.0",
|
||||
"release_time" : "float:400.0",
|
||||
"attenuate_time" : "float:1000",
|
||||
"max_gain" : "float:30.0",
|
||||
"max_peak" : "float:-1.0",
|
||||
"fRth0": "float:-65",
|
||||
"fRth1" : "float:-50",
|
||||
"fRth2" : "float:-35",
|
||||
"fRk0" : "float:2.5",
|
||||
"fRk1" : "float:0.8",
|
||||
"fRk2" : "float:0.4",
|
||||
"fLineGainDb" : "float:10.0",
|
||||
"swSmL0" : 40,
|
||||
"swSmL1" : 80,
|
||||
"swSmL2" : 80
|
||||
},
|
||||
"anr": {
|
||||
"status" : "enable",
|
||||
"noiseFactor" : "float:0.88",
|
||||
"swU" : 10,
|
||||
"psiMin" : "float:0.02",
|
||||
"psiMax" : "float:0.516",
|
||||
"fGmin" : "float:0.1"
|
||||
},
|
||||
"nlp": {
|
||||
"status" : "disable",
|
||||
"band_pass_thd" : "10,10,10,5,5,5,0,0",
|
||||
"super_est_factor" : "6,10,10,10,10,10,6,6"
|
||||
},
|
||||
"dereverb": {
|
||||
"status" : "disable",
|
||||
"rlsLg" : 4,
|
||||
"curveLg" : 10,
|
||||
"delay" : 2,
|
||||
"forgetting" : "float:0.98",
|
||||
"t60" : "float:1.5",
|
||||
"coCoeff" : "float:2.0"
|
||||
},
|
||||
"cng": {
|
||||
"status" : "disable",
|
||||
"fGain" : "float:2.0",
|
||||
"fMpy" : "float:5",
|
||||
"fSmoothAlpha" : "float:0.92",
|
||||
"fSpeechGain" : "float:0.3"
|
||||
},
|
||||
"dtd": {
|
||||
"status" : "disable",
|
||||
"ksiThd_high" : "float:0.7",
|
||||
"ksiThd_low" : "float:0.5"
|
||||
}
|
||||
}
|
||||
}
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,93 @@
|
||||
/*
|
||||
* Copyright 2022 Rockchip Electronics Co. LTD
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
#ifndef SRC_MPI_MPI_CONTROL_H_
|
||||
#define SRC_MPI_MPI_CONTROL_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
#include "uac_common_def.h"
|
||||
#include <rk_comm_af.h>
|
||||
#include <rk_comm_aio.h>
|
||||
#include <rk_debug.h>
|
||||
#include <rk_mpi_af.h>
|
||||
#include <rk_mpi_ai.h>
|
||||
#include <rk_mpi_amix.h>
|
||||
#include <rk_mpi_ao.h>
|
||||
#include <rk_mpi_sys.h>
|
||||
#include <rk_type.h>
|
||||
|
||||
#define UAC_MPI_ENABLE (1 << 1)
|
||||
#define MIC_SPK_SOUNDCARD_INDEX 0
|
||||
|
||||
typedef enum _UacMpiType {
|
||||
UAC_MPI_TYPE_AI = 0,
|
||||
UAC_MPI_TYPE_AO = 1,
|
||||
UAC_MPI_TYPE_AF_VQE = 2,
|
||||
UAC_MPI_TYPE_MAX
|
||||
} UacMpiType;
|
||||
|
||||
typedef enum _UacMpiAODevId {
|
||||
AO_USB_DEV, // ao[0]
|
||||
AO_SPK_DEV, // ao[1]
|
||||
} UacMpiAODevId;
|
||||
|
||||
typedef enum _UacMpiAIDevId {
|
||||
AI_MIC_DEV, // ai[0]
|
||||
AI_USB_DEV, // ai[1]
|
||||
} UacMpiAIDevId;
|
||||
|
||||
typedef enum _UacMpiAFChnId {
|
||||
AF_VQE_CHN, // af[0]
|
||||
} UacMpiAFChnId;
|
||||
|
||||
typedef struct _UacMpiIdConfig {
|
||||
AUDIO_DEV aoDevId;
|
||||
AUDIO_DEV aiDevId;
|
||||
AO_CHN aoChnId;
|
||||
AI_CHN aiChnId;
|
||||
AF_CHN vqeChnId;
|
||||
} UacMpiIdConfig;
|
||||
|
||||
typedef struct _UacMpiStream {
|
||||
int flag;
|
||||
UacMpiIdConfig idCfg;
|
||||
UacAudioConfig config;
|
||||
} UacMpiStream;
|
||||
|
||||
class UacMpiUtil {
|
||||
public:
|
||||
static const char *getSndCardName(UacMpiType type, int mode);
|
||||
static RK_U32 getSndCardChannels(UacMpiType type, int mode);
|
||||
static RK_U32 getSndCardSampleRate(UacMpiType type, int mode);
|
||||
static AUDIO_BIT_WIDTH_E getSndCardbitWidth(UacMpiType type, int mode);
|
||||
static RK_U32 getDataSamplerate(UacMpiType type, int mode);
|
||||
static AUDIO_BIT_WIDTH_E getDataBitwidth(UacMpiType type, int mode);
|
||||
static AUDIO_SOUND_MODE_E getDataSoundmode(UacMpiType type, int mode);
|
||||
static const char *getVqeCfgPath();
|
||||
static RK_U32 getVqeSampleRate();
|
||||
static RK_U32 getVqeChannels();
|
||||
static RK_U32 getVqeChnLayout();
|
||||
static RK_U32 getVqeRefLayout();
|
||||
static RK_U32 getVqeMicLayout();
|
||||
};
|
||||
|
||||
void mpi_set_samplerate(int type, UacMpiStream &streamCfg);
|
||||
void mpi_set_volume(int type, UacMpiStream &streamCfg);
|
||||
void mpi_set_ppm(int type, UacMpiStream &streamCfg);
|
||||
|
||||
#endif
|
||||
#endif // SRC_MPI_MPI_CONTROL_H_
|
||||
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* Copyright 2022 Rockchip Electronics Co. LTD
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef SRC_MPI_MPI_UAC_AMIXER_H_
|
||||
#define SRC_MPI_MPI_UAC_AMIXER_H_
|
||||
|
||||
#include "rk_common.h"
|
||||
|
||||
typedef enum _HARDWARE_REF_MODE {
|
||||
HARDWARE_REF_DISABLE = 0, // disable hardware ref channel
|
||||
HARDWARE_REF_MODE1, // 4chn: 2 mic + 1 ref
|
||||
HARDWARE_REF_MODE2, // 2chn: 1 mic + 1 ref
|
||||
HARDWARE_REF_MODE2_SWAP // 2chn: 1 ref + 1 mic
|
||||
} HARDWARE_REF_MODE;
|
||||
|
||||
typedef struct _MpiChnAttrConfigMap {
|
||||
RK_U32 u32Index;
|
||||
RK_U32 u32Channels;
|
||||
RK_U32 u32MicLayout;
|
||||
RK_U32 u32RefLayout;
|
||||
const char *chMode;
|
||||
} MpiChnAttrConfigMap;
|
||||
|
||||
// the hardware of our RV1106's evb board support mode2
|
||||
const static int sRefMode = HARDWARE_REF_MODE2;
|
||||
const static MpiChnAttrConfigMap sChnAttrCfgs[] = {
|
||||
{HARDWARE_REF_DISABLE, 2, 0x3, 0x0,
|
||||
"Disable"}, // disable hardware ref channel
|
||||
{HARDWARE_REF_MODE1, 4, 0x3, 0xc, "Mode1"}, // 4chn: 2 mic + 1 ref
|
||||
{HARDWARE_REF_MODE2, 2, 0x1, 0x2,
|
||||
"Mode2"}, // 2chn: 1 mic(ADC Left) + 1 ref(DAC Right)
|
||||
{HARDWARE_REF_MODE2_SWAP, 2, 0x2, 0x1,
|
||||
"Mode2 Swap"}, // 2chn: 1 ref(DAC Left) + 1 mic(ADC Right)
|
||||
};
|
||||
|
||||
class UACAmixer {
|
||||
public:
|
||||
static RK_S32 set(AUDIO_DEV AmixDevId, const char *ctrlName,
|
||||
const char *value);
|
||||
static RK_S32 get(AUDIO_DEV AmixDevId, const char *ctrlName);
|
||||
static void dumpContents(AUDIO_DEV AmixDevId);
|
||||
};
|
||||
|
||||
RK_S32 amix_set_ref_mode(AUDIO_DEV AoDevId);
|
||||
RK_S32 amix_set_ppm(AUDIO_DEV AoDevId, RK_S32 ppm);
|
||||
|
||||
#endif // SRC_MPI_MPI_UAC_AMIXER_H_
|
||||
@@ -0,0 +1,87 @@
|
||||
/*
|
||||
* Copyright 2022 Rockchip Electronics Co. LTD
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
#ifndef SRC_INCLUDE_UAC_COMMON_DEF_H_
|
||||
#define SRC_INCLUDE_UAC_COMMON_DEF_H_
|
||||
#ifdef __cplusplus
|
||||
|
||||
#include <dirent.h>
|
||||
#include <errno.h>
|
||||
#include <math.h>
|
||||
#include <pthread.h>
|
||||
#include <pwd.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/prctl.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#define OPT_SAMPLE_RATE "opt_samaple_rate"
|
||||
#define OPT_CHANNELS "opt_channel"
|
||||
#define OPT_VOLUME "opt_volume"
|
||||
#define OPT_MUTE "opt_mute"
|
||||
#define OPT_CONFIGS "opt_configs"
|
||||
#define OPT_PPM "opt_ppm"
|
||||
|
||||
#define OPT_SET_ALSA_CAPTURE "set_capture_config"
|
||||
#define OPT_SET_RESAMPLE "set_resample_config"
|
||||
#define OPT_SET_VOLUME "set_volume_config"
|
||||
#define OPT_SET_CONFIG "set_config"
|
||||
#define OPT_SET_PPM "set_ppm"
|
||||
|
||||
#define ARRAY_ELEMS(a) (sizeof(a) / sizeof((a)[0]))
|
||||
|
||||
#define GET_ENTRY_VALUE(INPUT1, INPUT2, MAP, KEY1, KEY2, VALUE) \
|
||||
do { \
|
||||
for (size_t i = 0; i < ARRAY_ELEMS(MAP); i++) { \
|
||||
if (INPUT1 == MAP[i].KEY1 && INPUT2 == MAP[i].KEY2) \
|
||||
return MAP[i].VALUE; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
enum UacStreamType {
|
||||
// our device record datas from usb, pc/remote->our device
|
||||
UAC_STREAM_RECORD = 0,
|
||||
// play datas to usb, our device->pc/remote
|
||||
UAC_STREAM_PLAYBACK,
|
||||
UAC_STREAM_MAX
|
||||
};
|
||||
|
||||
typedef struct _UacAudioConfig {
|
||||
int samplerate;
|
||||
union {
|
||||
int intVol;
|
||||
float floatVol;
|
||||
};
|
||||
int mute;
|
||||
int ppm;
|
||||
} UacAudioConfig;
|
||||
|
||||
uint64_t getRelativeTimeMs();
|
||||
uint64_t getRelativeTimeUs();
|
||||
#endif
|
||||
#endif // SRC_INCLUDE_UAC_COMMON_DEF_H_
|
||||
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright 2020 Rockchip Electronics Co. LTD
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
#ifndef SRC_INCLUDE_UAC_CONTROL_H_
|
||||
#define SRC_INCLUDE_UAC_CONTROL_H_
|
||||
|
||||
#include "uac_common_def.h"
|
||||
|
||||
enum UacApiType { UAC_API_MPI = 0, UAC_API_GRAPH = 1, UAC_API_MAX };
|
||||
|
||||
#ifdef __cplusplus
|
||||
class UACControl {
|
||||
public:
|
||||
UACControl() {}
|
||||
virtual ~UACControl() {}
|
||||
|
||||
public:
|
||||
virtual int uacStart() = 0;
|
||||
virtual void uacStop() = 0;
|
||||
virtual void uacSetSampleRate(int sampleRate) = 0;
|
||||
virtual void uacSetVolume(int volume) = 0;
|
||||
virtual void uacSetMute(int mute) = 0;
|
||||
virtual void uacSetPpm(int ppm) = 0;
|
||||
};
|
||||
#endif
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
int uac_start(int mode);
|
||||
void uac_stop(int mode);
|
||||
void uac_set_sample_rate(int mode, int samplerate);
|
||||
void uac_set_volume(int mode, int volume);
|
||||
void uac_set_mute(int mode, int mute);
|
||||
void uac_set_ppm(int mode, int ppm);
|
||||
|
||||
int uac_control_create(int type);
|
||||
void uac_control_destory();
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // SRC_INCLUDE_UAC_CONTROL_H_
|
||||
28
project/app/uvc_app_tiny/uvc_app/uac/src/include/uac_control_factory.h
Executable file
28
project/app/uvc_app_tiny/uvc_app/uac/src/include/uac_control_factory.h
Executable file
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Copyright 2022 Rockchip Electronics Co. LTD
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
#ifndef SRC_INCLUDE_UAC_CONTROL_FACTORY_H
|
||||
#define SRC_INCLUDE_UAC_CONTROL_FACTORY_H
|
||||
#ifdef __cplusplus
|
||||
#include "uac_common_def.h"
|
||||
#include "uac_control.h"
|
||||
|
||||
class UacControlFactory {
|
||||
public:
|
||||
static UACControl *create(UacApiType type, int mode);
|
||||
};
|
||||
#endif
|
||||
#endif // SRC_INCLUDE_UAC_CONTROL_FACTORY_H
|
||||
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright 2022 Rockchip Electronics Co. LTD
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
#ifndef SRC_INCLUDE_UAC_CONTROL_GRAPH_H_
|
||||
#define SRC_INCLUDE_UAC_CONTROL_GRAPH_H_
|
||||
#ifdef __cplusplus
|
||||
|
||||
#include "uac_control.h"
|
||||
|
||||
class UACControlGraph : public UACControl {
|
||||
public:
|
||||
UACControlGraph(int mode);
|
||||
virtual ~UACControlGraph();
|
||||
|
||||
public:
|
||||
virtual int uacStart();
|
||||
virtual void uacStop();
|
||||
virtual void uacSetSampleRate(int sampleRate);
|
||||
virtual void uacSetVolume(int volume);
|
||||
virtual void uacSetMute(int mute);
|
||||
virtual void uacSetPpm(int ppm);
|
||||
|
||||
private:
|
||||
void *mCtx;
|
||||
};
|
||||
#endif
|
||||
#endif // SRC_INCLUDE_UAC_CONTROL_GRAPH_H_
|
||||
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Copyright 2022 Rockchip Electronics Co. LTD
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
#ifndef SRC_INCLUDE_UAC_CONTROL_MPI_H_
|
||||
#define SRC_INCLUDE_UAC_CONTROL_MPI_H_
|
||||
#ifdef __cplusplus
|
||||
#include "uac_control.h"
|
||||
|
||||
class UACControlMpi : public UACControl {
|
||||
public:
|
||||
UACControlMpi(int mode);
|
||||
virtual ~UACControlMpi();
|
||||
|
||||
public:
|
||||
virtual int uacStart();
|
||||
virtual void uacStop();
|
||||
virtual void uacSetSampleRate(int sampleRate);
|
||||
virtual void uacSetVolume(int volume);
|
||||
virtual void uacSetMute(int mute);
|
||||
virtual void uacSetPpm(int ppm);
|
||||
|
||||
protected:
|
||||
int startAi();
|
||||
int startVqe();
|
||||
int startAo();
|
||||
void streamBind();
|
||||
int stopAi();
|
||||
int stopVqe();
|
||||
int stopAo();
|
||||
void streamUnBind();
|
||||
|
||||
private:
|
||||
void *mCtx;
|
||||
};
|
||||
#endif
|
||||
#endif // SRC_INCLUDE_UAC_CONTROL_MPI_H_
|
||||
63
project/app/uvc_app_tiny/uvc_app/uac/src/include/uac_log.h
Normal file
63
project/app/uvc_app_tiny/uvc_app/uac/src/include/uac_log.h
Normal file
@@ -0,0 +1,63 @@
|
||||
// Copyright 2019 Fuzhou Rockchip Electronics Co., Ltd. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef SRC_INCLUDE_UAC_LOGGER_H_
|
||||
#define SRC_INCLUDE_UAC_LOGGER_H_
|
||||
//#ifdef __cplusplus
|
||||
|
||||
#ifdef uac_minilogGER
|
||||
#include "minilogger/log.h"
|
||||
#else
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <sys/time.h>
|
||||
#define uac_minilog_warn(...)
|
||||
#define uac_minilog_error(...)
|
||||
#define uac_minilog_info(...)
|
||||
#define uac_minilog_debug(...)
|
||||
#define __uac_minilog_log_init(...)
|
||||
#endif
|
||||
|
||||
extern int uac_app_log_level;
|
||||
|
||||
#define LOG_LEVEL_ERROR 0
|
||||
#define LOG_LEVEL_WARN 1
|
||||
#define LOG_LEVEL_INFO 2
|
||||
#define LOG_LEVEL_DEBUG 3
|
||||
|
||||
#ifndef LOG_TAG
|
||||
#define LOG_TAG "uac_app"
|
||||
#endif
|
||||
|
||||
#define ALOGI(format, ...) \
|
||||
do { \
|
||||
if (uac_app_log_level < LOG_LEVEL_INFO) \
|
||||
break; \
|
||||
\ fprintf(stderr, "[%s][%s]:" format, LOG_TAG, __FUNCTION__, \
|
||||
##__VA_ARGS__); \
|
||||
} while (0)
|
||||
|
||||
#define ALOGW(format, ...) \
|
||||
do { \
|
||||
if (uac_app_log_level < LOG_LEVEL_WARN) \
|
||||
break; \
|
||||
\ fprintf(stderr, "[%s][%s]:" format, LOG_TAG, __FUNCTION__, \
|
||||
##__VA_ARGS__); \
|
||||
} while (0)
|
||||
|
||||
#define ALOGE(format, ...) \
|
||||
do { \
|
||||
if (uac_app_log_level < LOG_LEVEL_ERROR) \
|
||||
break; \
|
||||
fprintf(stderr, "[%s][%s]:" format, LOG_TAG, __FUNCTION__, ##__VA_ARGS__); \
|
||||
} while (0)
|
||||
|
||||
#define ALOGD(format, ...) \
|
||||
do { \
|
||||
if (uac_app_log_level < LOG_LEVEL_DEBUG) \
|
||||
break; \
|
||||
fprintf(stderr, "[%s][%s]:" format, LOG_TAG, __FUNCTION__, ##__VA_ARGS__); \
|
||||
} while (0)
|
||||
//#endif
|
||||
#endif // SRC_INCLUDE_UAC_LOGGER_H_
|
||||
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Copyright (C) 2019 Rockchip Electronics Co., Ltd.
|
||||
*
|
||||
* This software is available to you under a choice of one of two
|
||||
* licenses. You may choose to be licensed under the terms of the GNU
|
||||
* General Public License (GPL), available from the file
|
||||
* COPYING in the main directory of this source tree, or the
|
||||
* OpenIB.org BSD license below:
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or
|
||||
* without modification, are permitted provided that the following
|
||||
* conditions are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer.
|
||||
*
|
||||
* - Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef SRC_INCLUDE_UEVENT_H_
|
||||
#define SRC_INCLUDE_UEVENT_H_
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
|
||||
struct _uevent {
|
||||
char *strs[30];
|
||||
int size;
|
||||
};
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
int uac_uevent_monitor_run();
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // SRC_INCLUDE_UEVENT_H_
|
||||
536
project/app/uvc_app_tiny/uvc_app/uac/src/mpi/uac_control_mpi.cpp
Normal file
536
project/app/uvc_app_tiny/uvc_app/uac/src/mpi/uac_control_mpi.cpp
Normal file
@@ -0,0 +1,536 @@
|
||||
/*
|
||||
* Copyright 2022 Rockchip Electronics Co. LTD
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
//#ifdef __cplusplus
|
||||
|
||||
#include "uac_control_mpi.h"
|
||||
#include "mpi_control_common.h"
|
||||
#include "uac_amixer.h"
|
||||
#include "uac_log.h"
|
||||
|
||||
#ifdef LOG_TAG
|
||||
#undef LOG_TAG
|
||||
#define LOG_TAG "uac_mpi"
|
||||
#endif
|
||||
|
||||
#define OPEN_VQE 1
|
||||
|
||||
typedef struct _UacControlMpi {
|
||||
int mode;
|
||||
UacMpiStream stream;
|
||||
} UacControlMpi;
|
||||
|
||||
UacControlMpi *getContextMpi(void *context) {
|
||||
UacControlMpi *ctx = reinterpret_cast<UacControlMpi *>(context);
|
||||
return ctx;
|
||||
}
|
||||
|
||||
UACControlMpi::UACControlMpi(int mode) {
|
||||
UacControlMpi *ctx = (UacControlMpi *)calloc(1, sizeof(UacControlMpi));
|
||||
memset(ctx, 0, sizeof(UacControlMpi));
|
||||
|
||||
ctx->mode = mode;
|
||||
ctx->stream.config.intVol = 100;
|
||||
ctx->stream.config.mute = 0;
|
||||
ctx->stream.config.ppm = 0;
|
||||
|
||||
if (mode == UAC_STREAM_PLAYBACK) {
|
||||
ctx->stream.idCfg.aiDevId = (AUDIO_DEV)AI_MIC_DEV;
|
||||
ctx->stream.idCfg.aoDevId = (AUDIO_DEV)AO_USB_DEV;
|
||||
ctx->stream.config.samplerate =
|
||||
UacMpiUtil::getDataSamplerate(UAC_MPI_TYPE_AO, ctx->mode);
|
||||
} else if (mode == UAC_STREAM_RECORD) {
|
||||
ctx->stream.idCfg.aiDevId = (AUDIO_DEV)AI_USB_DEV;
|
||||
ctx->stream.idCfg.aoDevId = (AUDIO_DEV)AO_SPK_DEV;
|
||||
ctx->stream.config.samplerate =
|
||||
UacMpiUtil::getDataSamplerate(UAC_MPI_TYPE_AI, ctx->mode);
|
||||
|
||||
// always set index of spk's sound card(hw:0,0)
|
||||
amix_set_ref_mode(MIC_SPK_SOUNDCARD_INDEX);
|
||||
}
|
||||
|
||||
mCtx = reinterpret_cast<void *>(ctx);
|
||||
}
|
||||
|
||||
UACControlMpi::~UACControlMpi() {
|
||||
UacControlMpi *ctx = getContextMpi(mCtx);
|
||||
if (ctx) {
|
||||
free(ctx);
|
||||
}
|
||||
|
||||
mCtx = NULL;
|
||||
}
|
||||
|
||||
void UACControlMpi::uacSetSampleRate(int sampleRate) {
|
||||
UacControlMpi *ctx = getContextMpi(mCtx);
|
||||
ctx->stream.config.samplerate = sampleRate;
|
||||
ALOGD("mode = %d, sampleRate = %d\n", ctx->mode, sampleRate);
|
||||
if ((ctx->stream.flag &= UAC_MPI_ENABLE) == UAC_MPI_ENABLE) {
|
||||
mpi_set_samplerate(ctx->mode, ctx->stream);
|
||||
}
|
||||
}
|
||||
|
||||
void UACControlMpi::uacSetVolume(int volume) {
|
||||
UacControlMpi *ctx = getContextMpi(mCtx);
|
||||
ALOGD("mode = %d, volume = %d\n", ctx->mode, volume);
|
||||
ctx->stream.config.intVol = volume;
|
||||
if ((ctx->stream.flag &= UAC_MPI_ENABLE) == UAC_MPI_ENABLE) {
|
||||
mpi_set_volume(ctx->mode, ctx->stream);
|
||||
}
|
||||
}
|
||||
|
||||
void UACControlMpi::uacSetMute(int mute) {
|
||||
UacControlMpi *ctx = getContextMpi(mCtx);
|
||||
ALOGD("mode = %d, mute = %d\n", ctx->mode, mute);
|
||||
ctx->stream.config.mute = mute;
|
||||
if ((ctx->stream.flag &= UAC_MPI_ENABLE) == UAC_MPI_ENABLE) {
|
||||
mpi_set_volume(ctx->mode, ctx->stream);
|
||||
}
|
||||
}
|
||||
|
||||
void UACControlMpi::uacSetPpm(int ppm) {
|
||||
ALOGD("ppm = %d\n", ppm);
|
||||
UacControlMpi *ctx = getContextMpi(mCtx);
|
||||
ctx->stream.config.ppm = ppm;
|
||||
if ((ctx->stream.flag &= UAC_MPI_ENABLE) == UAC_MPI_ENABLE) {
|
||||
mpi_set_ppm(ctx->mode, ctx->stream);
|
||||
}
|
||||
}
|
||||
|
||||
int UACControlMpi::uacStart() {
|
||||
uacStop();
|
||||
int ret = 0;
|
||||
UacControlMpi *ctx = getContextMpi(mCtx);
|
||||
ret = startAi();
|
||||
if (ret != 0) {
|
||||
goto __FAILED;
|
||||
}
|
||||
|
||||
/*
|
||||
* only add 3A process in playback(data flow: 1106's mic-->pc/host),
|
||||
* do not add 3A process in record(data flow: pc/host-->1106's spk )
|
||||
* for avoid sound like music process by 3A
|
||||
*/
|
||||
if (OPEN_VQE && ctx->mode == UAC_STREAM_PLAYBACK) {
|
||||
ret = startVqe();
|
||||
if (ret != 0) {
|
||||
goto __FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
ret = startAo();
|
||||
if (ret != 0) {
|
||||
goto __FAILED;
|
||||
}
|
||||
|
||||
mpi_set_samplerate(ctx->mode, ctx->stream);
|
||||
mpi_set_volume(ctx->mode, ctx->stream);
|
||||
mpi_set_ppm(ctx->mode, ctx->stream);
|
||||
|
||||
streamBind();
|
||||
ctx->stream.flag |= UAC_MPI_ENABLE;
|
||||
return 0;
|
||||
|
||||
__FAILED:
|
||||
return -1;
|
||||
}
|
||||
|
||||
void UACControlMpi::uacStop() {
|
||||
UacControlMpi *ctx = getContextMpi(mCtx);
|
||||
ALOGD("stop mode = %d, flag = %d\n", ctx->mode, ctx->stream.flag);
|
||||
if ((ctx->stream.flag &= UAC_MPI_ENABLE) == UAC_MPI_ENABLE) {
|
||||
streamUnBind();
|
||||
stopAi();
|
||||
if (OPEN_VQE && ctx->mode == UAC_STREAM_PLAYBACK) {
|
||||
stopVqe();
|
||||
}
|
||||
stopAo();
|
||||
ctx->stream.flag &= (~UAC_MPI_ENABLE);
|
||||
}
|
||||
}
|
||||
|
||||
int UACControlMpi::startAi() {
|
||||
UacControlMpi *ctx = getContextMpi(mCtx);
|
||||
AUDIO_DEV aiDevId = ctx->stream.idCfg.aiDevId;
|
||||
AI_CHN aiChn = ctx->stream.idCfg.aiChnId;
|
||||
ALOGD("this:%p, startAi(dev:%d, chn:%d), mode : %d\n", this, aiDevId, aiChn,
|
||||
ctx->mode);
|
||||
const char *cardName = RK_NULL;
|
||||
RK_S32 result = 0;
|
||||
AUDIO_SAMPLE_RATE_E rate;
|
||||
AIO_ATTR_S aiAttr;
|
||||
memset(&aiAttr, 0, sizeof(AIO_ATTR_S));
|
||||
|
||||
cardName = UacMpiUtil::getSndCardName(UAC_MPI_TYPE_AI, ctx->mode);
|
||||
snprintf(reinterpret_cast<char *>(aiAttr.u8CardName),
|
||||
sizeof(aiAttr.u8CardName), "%s", cardName);
|
||||
aiAttr.soundCard.channels =
|
||||
UacMpiUtil::getSndCardChannels(UAC_MPI_TYPE_AI, ctx->mode);
|
||||
aiAttr.soundCard.sampleRate =
|
||||
UacMpiUtil::getSndCardSampleRate(UAC_MPI_TYPE_AI, ctx->mode);
|
||||
aiAttr.soundCard.bitWidth =
|
||||
UacMpiUtil::getSndCardbitWidth(UAC_MPI_TYPE_AI, ctx->mode);
|
||||
|
||||
/*
|
||||
* 1. if datas are sended from pc to uac device, the ai device is usb,
|
||||
* we set the samplerate which uevent report.
|
||||
* 2. if datas are sended from uac device to pc, the ai device is mic,
|
||||
we use the a fix samplerate like 16000.
|
||||
*/
|
||||
if (ctx->mode == UAC_STREAM_PLAYBACK) {
|
||||
if (OPEN_VQE) {
|
||||
rate = (AUDIO_SAMPLE_RATE_E)UacMpiUtil::getVqeSampleRate();
|
||||
} else {
|
||||
rate = (AUDIO_SAMPLE_RATE_E)UacMpiUtil::getSndCardSampleRate(
|
||||
UAC_MPI_TYPE_AI, ctx->mode);
|
||||
}
|
||||
} else {
|
||||
rate = (AUDIO_SAMPLE_RATE_E)ctx->stream.config.samplerate;
|
||||
// update samplerate of usb cards which coming from uevent
|
||||
aiAttr.soundCard.sampleRate = rate;
|
||||
}
|
||||
|
||||
aiAttr.enBitwidth = UacMpiUtil::getDataBitwidth(UAC_MPI_TYPE_AI, ctx->mode);
|
||||
aiAttr.enSamplerate = rate;
|
||||
aiAttr.enSoundmode = UacMpiUtil::getDataSoundmode(UAC_MPI_TYPE_AI, ctx->mode);
|
||||
ALOGD("this:%p, startAi(dev:%d, chn:%d), enSamplerate : %d\n", this, aiDevId,
|
||||
aiChn, aiAttr.enSamplerate);
|
||||
aiAttr.u32FrmNum = 4;
|
||||
aiAttr.u32PtNumPerFrm = 1024;
|
||||
aiAttr.u32EXFlag = 0;
|
||||
aiAttr.u32ChnCnt = 2;
|
||||
result = RK_MPI_AI_SetPubAttr(aiDevId, &aiAttr);
|
||||
if (result != 0) {
|
||||
ALOGE("ai set attr(dev:%d) fail, reason = %x\n", aiDevId, result);
|
||||
goto __FAILED;
|
||||
}
|
||||
|
||||
result = RK_MPI_AI_Enable(aiDevId);
|
||||
if (result != 0) {
|
||||
ALOGE("ai enable(dev:%d) fail, reason = %x\n", aiDevId, result);
|
||||
goto __FAILED;
|
||||
}
|
||||
|
||||
result = RK_MPI_AI_EnableChn(aiDevId, aiChn);
|
||||
if (result != 0) {
|
||||
ALOGE("ai enable channel(dev:%d, chn:%d) fail, reason = %x\n", aiDevId,
|
||||
aiChn, result);
|
||||
return RK_FAILURE;
|
||||
}
|
||||
|
||||
/*
|
||||
* If 3A filter is after ai, and the samplerate of ai's datas is not support
|
||||
* by 3A,
|
||||
* enable resample to convert the samplerate.
|
||||
*/
|
||||
if (OPEN_VQE && ctx->mode == UAC_STREAM_PLAYBACK) {
|
||||
result = RK_MPI_AI_EnableReSmp(aiDevId, aiChn, aiAttr.enSamplerate);
|
||||
if (result != 0) {
|
||||
ALOGE("ai enable resample(dev:%d, chn:%d) fail, reason = %x\n", aiDevId,
|
||||
aiChn, result);
|
||||
return RK_FAILURE;
|
||||
}
|
||||
} else {
|
||||
// disable resample in ai, this means the samplerate of output of ai is the
|
||||
// samplerate of sound card
|
||||
result = RK_MPI_AI_DisableReSmp(aiDevId, aiChn);
|
||||
if (result != 0) {
|
||||
ALOGE("ai disable resample(dev:%d, chn:%d) fail, reason = %x\n", aiDevId,
|
||||
aiChn, result);
|
||||
return RK_FAILURE;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
__FAILED:
|
||||
return -1;
|
||||
}
|
||||
|
||||
// init 3A filter
|
||||
int UACControlMpi::startVqe() {
|
||||
UacControlMpi *ctx = getContextMpi(mCtx);
|
||||
AF_CHN vqeChnId = ctx->stream.idCfg.vqeChnId;
|
||||
RK_S32 result;
|
||||
AF_ATTR_S attr;
|
||||
ALOGD("this:%p, startVqe(chn:%d), mode : %d\n", this, vqeChnId, ctx->mode);
|
||||
memset(&attr, 0, sizeof(AF_ATTR_S));
|
||||
|
||||
attr.enType = AUDIO_FILTER_3A;
|
||||
attr.u32InBufCount = 2;
|
||||
attr.u32OutBufCount = 2;
|
||||
|
||||
snprintf(reinterpret_cast<char *>(attr.st3AAttr.cfgPath),
|
||||
sizeof(attr.st3AAttr.cfgPath), "%s", UacMpiUtil::getVqeCfgPath());
|
||||
attr.st3AAttr.u32SampleRate = UacMpiUtil::getVqeSampleRate();
|
||||
attr.st3AAttr.enBitWidth = AUDIO_BIT_WIDTH_16;
|
||||
attr.st3AAttr.u32Channels = UacMpiUtil::getVqeChannels();
|
||||
attr.st3AAttr.u32ChnLayout = UacMpiUtil::getVqeChnLayout();
|
||||
attr.st3AAttr.u32RecLayout = UacMpiUtil::getVqeMicLayout();
|
||||
attr.st3AAttr.u32RefLayout = UacMpiUtil::getVqeRefLayout();
|
||||
result = RK_MPI_AF_Create(vqeChnId, &attr);
|
||||
if (result != RK_SUCCESS) {
|
||||
ALOGE("create af vqe(chn:%d) fail, reason = %x\n", vqeChnId, result);
|
||||
return RK_FAILURE;
|
||||
}
|
||||
|
||||
return 0;
|
||||
__FAILED:
|
||||
return -1;
|
||||
}
|
||||
|
||||
int UACControlMpi::startAo() {
|
||||
UacControlMpi *ctx = getContextMpi(mCtx);
|
||||
AUDIO_DEV aoDevId = ctx->stream.idCfg.aoDevId;
|
||||
AO_CHN aoChn = ctx->stream.idCfg.aoChnId;
|
||||
ALOGD("this:%p, startAo(dev:%d, chn:%d), mode : %d\n", this, aoDevId, aoChn,
|
||||
ctx->mode);
|
||||
const char *cardName = RK_NULL;
|
||||
RK_S32 result;
|
||||
AIO_ATTR_S aoAttr;
|
||||
AUDIO_SAMPLE_RATE_E rate;
|
||||
AUDIO_SOUND_MODE_E soundMode;
|
||||
memset(&aoAttr, 0, sizeof(AIO_ATTR_S));
|
||||
|
||||
cardName = UacMpiUtil::getSndCardName(UAC_MPI_TYPE_AO, ctx->mode);
|
||||
snprintf(reinterpret_cast<char *>(aoAttr.u8CardName),
|
||||
sizeof(aoAttr.u8CardName), "%s", cardName);
|
||||
|
||||
/*
|
||||
* 1. if datas is from pc to uac device, the ao device is spk,
|
||||
we use the a fix samplerate like 48000.
|
||||
* 2. if datas is from uac device to pc, the ao device is usb,
|
||||
* we set the samplerate which uevent report.
|
||||
*/
|
||||
if (ctx->mode == UAC_STREAM_RECORD) {
|
||||
rate = (AUDIO_SAMPLE_RATE_E)UacMpiUtil::getSndCardSampleRate(
|
||||
UAC_MPI_TYPE_AO, ctx->mode);
|
||||
} else {
|
||||
rate = (AUDIO_SAMPLE_RATE_E)ctx->stream.config.samplerate;
|
||||
}
|
||||
|
||||
aoAttr.soundCard.channels =
|
||||
UacMpiUtil::getSndCardChannels(UAC_MPI_TYPE_AO, ctx->mode);
|
||||
aoAttr.soundCard.sampleRate = rate;
|
||||
aoAttr.soundCard.bitWidth =
|
||||
UacMpiUtil::getSndCardbitWidth(UAC_MPI_TYPE_AO, ctx->mode);
|
||||
|
||||
aoAttr.enBitwidth = UacMpiUtil::getDataBitwidth(UAC_MPI_TYPE_AO, ctx->mode);
|
||||
if (OPEN_VQE && ctx->mode == UAC_STREAM_PLAYBACK) {
|
||||
rate = (AUDIO_SAMPLE_RATE_E)UacMpiUtil::getVqeSampleRate();
|
||||
}
|
||||
aoAttr.enSamplerate = rate;
|
||||
soundMode = UacMpiUtil::getDataSoundmode(UAC_MPI_TYPE_AO, ctx->mode);
|
||||
if (OPEN_VQE && ctx->mode == UAC_STREAM_PLAYBACK) {
|
||||
soundMode = AUDIO_SOUND_MODE_MONO;
|
||||
}
|
||||
aoAttr.enSoundmode = soundMode;
|
||||
ALOGD("this:%p, startAo(dev:%d, chn:%d), mode : %d, enSamplerate = %d\n",
|
||||
this, aoDevId, aoChn, ctx->mode, aoAttr.enSamplerate);
|
||||
aoAttr.u32FrmNum = 4;
|
||||
aoAttr.u32PtNumPerFrm = 1024;
|
||||
aoAttr.u32EXFlag = 0;
|
||||
aoAttr.u32ChnCnt = 2;
|
||||
result = RK_MPI_AO_SetPubAttr(aoDevId, &aoAttr);
|
||||
if (result != 0) {
|
||||
ALOGE("ao set attr(dev:%d) fail, reason = %x\n", aoDevId, result);
|
||||
goto __FAILED;
|
||||
}
|
||||
|
||||
result = RK_MPI_AO_Enable(aoDevId);
|
||||
if (result != 0) {
|
||||
ALOGE("ao enable(dev:%d) fail, reason = %x\n", aoDevId, result);
|
||||
goto __FAILED;
|
||||
}
|
||||
|
||||
result = RK_MPI_AO_EnableChn(aoDevId, aoChn);
|
||||
if (result != 0) {
|
||||
ALOGE("ao enable channel(dev:%d, chn:%d) fail, reason = %x\n", aoDevId,
|
||||
aoChn, result);
|
||||
return RK_FAILURE;
|
||||
}
|
||||
|
||||
result = RK_MPI_AO_EnableReSmp(aoDevId, aoChn, aoAttr.enSamplerate);
|
||||
if (result != 0) {
|
||||
ALOGE("ao enable resample(dev:%d, chn:%d) fail, reason = %x\n", aoDevId,
|
||||
aoChn, result);
|
||||
return RK_FAILURE;
|
||||
}
|
||||
|
||||
if (OPEN_VQE && ctx->mode == UAC_STREAM_PLAYBACK) {
|
||||
result = RK_MPI_AO_SetTrackMode(aoDevId, AUDIO_TRACK_OUT_STEREO);
|
||||
if (result != 0) {
|
||||
ALOGE("ao enable track mode(dev:%d, chn:%d) fail, reason = %x\n", aoDevId,
|
||||
aoChn, result);
|
||||
return RK_FAILURE;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
__FAILED:
|
||||
return -1;
|
||||
}
|
||||
|
||||
void UACControlMpi::streamBind() {
|
||||
UacControlMpi *ctx = getContextMpi(mCtx);
|
||||
MPP_CHN_S stSrcChn, stDstChn;
|
||||
// have af, the data flow is ai-->af-->ao
|
||||
if (OPEN_VQE && ctx->mode == UAC_STREAM_PLAYBACK) {
|
||||
// ai bind af, this means data from ai to af
|
||||
stSrcChn.enModId = RK_ID_AI;
|
||||
stSrcChn.s32DevId = ctx->stream.idCfg.aiDevId;
|
||||
stSrcChn.s32ChnId = ctx->stream.idCfg.aiChnId;
|
||||
|
||||
stDstChn.enModId = RK_ID_AF;
|
||||
stDstChn.s32DevId = 0;
|
||||
stDstChn.s32ChnId = ctx->stream.idCfg.vqeChnId;
|
||||
ALOGD("AiBindVqe(mode:%d) : src(%d,%d), dst(%d,%d)\n", ctx->mode,
|
||||
stSrcChn.s32DevId, stSrcChn.s32ChnId, stDstChn.s32DevId,
|
||||
stDstChn.s32ChnId);
|
||||
RK_MPI_SYS_Bind(&stSrcChn, &stDstChn);
|
||||
|
||||
// af bind ao, this means data from af to ao
|
||||
stSrcChn.enModId = RK_ID_AF;
|
||||
stSrcChn.s32DevId = 0;
|
||||
stSrcChn.s32ChnId = ctx->stream.idCfg.vqeChnId;
|
||||
|
||||
stDstChn.enModId = RK_ID_AO;
|
||||
stDstChn.s32DevId = ctx->stream.idCfg.aoDevId;
|
||||
stDstChn.s32ChnId = ctx->stream.idCfg.aoChnId;
|
||||
ALOGD("VqeBindAo(mode:%d) : src(%d,%d), dst(%d,%d)\n", ctx->mode,
|
||||
stSrcChn.s32DevId, stSrcChn.s32ChnId, stDstChn.s32DevId,
|
||||
stDstChn.s32ChnId);
|
||||
RK_MPI_SYS_Bind(&stSrcChn, &stDstChn);
|
||||
} else {
|
||||
// no af, the data flow is ai-->ao
|
||||
stSrcChn.enModId = RK_ID_AI;
|
||||
stSrcChn.s32DevId = ctx->stream.idCfg.aiDevId;
|
||||
stSrcChn.s32ChnId = ctx->stream.idCfg.aiChnId;
|
||||
|
||||
stDstChn.enModId = RK_ID_AO;
|
||||
stDstChn.s32DevId = ctx->stream.idCfg.aoDevId;
|
||||
stDstChn.s32ChnId = ctx->stream.idCfg.aoChnId;
|
||||
ALOGD("AiBindAO(mode:%d) : src(%d,%d), dst(%d,%d)\n", ctx->mode,
|
||||
stSrcChn.s32DevId, stSrcChn.s32ChnId, stDstChn.s32DevId,
|
||||
stDstChn.s32ChnId);
|
||||
RK_MPI_SYS_Bind(&stSrcChn, &stDstChn);
|
||||
}
|
||||
}
|
||||
|
||||
int UACControlMpi::stopAi() {
|
||||
UacControlMpi *ctx = getContextMpi(mCtx);
|
||||
AUDIO_DEV aiDevId = ctx->stream.idCfg.aiDevId;
|
||||
AI_CHN aiChn = ctx->stream.idCfg.aiChnId;
|
||||
ALOGD("this:%p, stopAi(dev:%d, chn:%d), mode : %d\n", this, aiDevId, aiChn,
|
||||
ctx->mode);
|
||||
RK_MPI_AI_DisableReSmp(aiDevId, aiChn);
|
||||
RK_S32 result = RK_MPI_AI_DisableChn(aiDevId, aiChn);
|
||||
if (result != 0) {
|
||||
ALOGE("ai disable channel(dev:%d, chn:%d) fail, reason = %x\n", aiDevId,
|
||||
aiChn, result);
|
||||
return RK_FAILURE;
|
||||
}
|
||||
|
||||
result = RK_MPI_AI_Disable(aiDevId);
|
||||
if (result != 0) {
|
||||
ALOGE("ai disable(dev:%d) fail, reason = %x\n", aiDevId, result);
|
||||
return RK_FAILURE;
|
||||
}
|
||||
|
||||
return 0;
|
||||
__FAILED:
|
||||
return -1;
|
||||
}
|
||||
|
||||
int UACControlMpi::stopVqe() {
|
||||
UacControlMpi *ctx = getContextMpi(mCtx);
|
||||
AF_CHN vqeChn = ctx->stream.idCfg.vqeChnId;
|
||||
ALOGD("this:%p, stopVqe(chn:%d), mode : %d\n", this, vqeChn, ctx->mode);
|
||||
RK_S32 result = RK_MPI_AF_Destroy(vqeChn);
|
||||
if (result != 0) {
|
||||
ALOGE("vqe disable(dev:%d) fail, reason = %x\n", vqeChn, result);
|
||||
return RK_FAILURE;
|
||||
}
|
||||
|
||||
return 0;
|
||||
__FAILED:
|
||||
return -1;
|
||||
}
|
||||
|
||||
int UACControlMpi::stopAo() {
|
||||
UacControlMpi *ctx = getContextMpi(mCtx);
|
||||
AUDIO_DEV aoDevId = ctx->stream.idCfg.aoDevId;
|
||||
AO_CHN aoChn = ctx->stream.idCfg.aoChnId;
|
||||
ALOGD("this:%p, stopAo(dev:%d, chn:%d), mode : %d\n", this, aoDevId, aoChn,
|
||||
ctx->mode);
|
||||
RK_MPI_AO_DisableReSmp(aoDevId, aoChn);
|
||||
RK_S32 result = RK_MPI_AO_DisableChn(aoDevId, aoChn);
|
||||
if (result != 0) {
|
||||
ALOGE("ao disable channel(dev:%d, chn:%d) fail, reason = %x\n", aoDevId,
|
||||
aoChn, result);
|
||||
return RK_FAILURE;
|
||||
}
|
||||
|
||||
result = RK_MPI_AO_Disable(aoDevId);
|
||||
if (result != 0) {
|
||||
ALOGE("ao disable(dev:%d) fail, reason = %x\n", aoDevId, result);
|
||||
return RK_FAILURE;
|
||||
}
|
||||
|
||||
return 0;
|
||||
__FAILED:
|
||||
return -1;
|
||||
}
|
||||
|
||||
void UACControlMpi::streamUnBind() {
|
||||
UacControlMpi *ctx = getContextMpi(mCtx);
|
||||
MPP_CHN_S stSrcChn, stDstChn;
|
||||
if (OPEN_VQE && ctx->mode == UAC_STREAM_PLAYBACK) {
|
||||
stSrcChn.enModId = RK_ID_AI;
|
||||
stSrcChn.s32DevId = ctx->stream.idCfg.aiDevId;
|
||||
stSrcChn.s32ChnId = ctx->stream.idCfg.aiChnId;
|
||||
|
||||
stDstChn.enModId = RK_ID_AF;
|
||||
stDstChn.s32DevId = 0;
|
||||
stDstChn.s32ChnId = ctx->stream.idCfg.vqeChnId;
|
||||
ALOGD("AiUnBindVqe(mode:%d) : src(%d,%d), dst(%d,%d)\n", ctx->mode,
|
||||
stSrcChn.s32DevId, stSrcChn.s32ChnId, stDstChn.s32DevId,
|
||||
stDstChn.s32ChnId);
|
||||
RK_MPI_SYS_UnBind(&stSrcChn, &stDstChn);
|
||||
|
||||
stSrcChn.enModId = RK_ID_AF;
|
||||
stSrcChn.s32DevId = 0;
|
||||
stSrcChn.s32ChnId = ctx->stream.idCfg.vqeChnId;
|
||||
|
||||
stDstChn.enModId = RK_ID_AO;
|
||||
stDstChn.s32DevId = ctx->stream.idCfg.aoDevId;
|
||||
stDstChn.s32ChnId = ctx->stream.idCfg.aoChnId;
|
||||
ALOGD("VqeUnBindAo(mode:%d) : src(%d,%d), dst(%d,%d)\n", ctx->mode,
|
||||
stSrcChn.s32DevId, stSrcChn.s32ChnId, stDstChn.s32DevId,
|
||||
stDstChn.s32ChnId);
|
||||
RK_MPI_SYS_UnBind(&stSrcChn, &stDstChn);
|
||||
} else {
|
||||
stSrcChn.enModId = RK_ID_AI;
|
||||
stSrcChn.s32DevId = ctx->stream.idCfg.aiDevId;
|
||||
stSrcChn.s32ChnId = ctx->stream.idCfg.aiChnId;
|
||||
|
||||
stDstChn.enModId = RK_ID_AO;
|
||||
stDstChn.s32DevId = ctx->stream.idCfg.aoDevId;
|
||||
stDstChn.s32ChnId = ctx->stream.idCfg.aoChnId;
|
||||
ALOGD("AiUnBindAO(mode:%d) : src(%d,%d), dst(%d,%d)\n", ctx->mode,
|
||||
stSrcChn.s32DevId, stSrcChn.s32ChnId, stDstChn.s32DevId,
|
||||
stDstChn.s32ChnId);
|
||||
RK_MPI_SYS_UnBind(&stSrcChn, &stDstChn);
|
||||
}
|
||||
}
|
||||
//#endif
|
||||
174
project/app/uvc_app_tiny/uvc_app/uac/src/mpi_common/mpi_control_common.cpp
Executable file
174
project/app/uvc_app_tiny/uvc_app/uac/src/mpi_common/mpi_control_common.cpp
Executable file
@@ -0,0 +1,174 @@
|
||||
/*
|
||||
* Copyright 2022 Rockchip Electronics Co. LTD
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
//#ifdef __cplusplus
|
||||
|
||||
#include "mpi_control_common.h"
|
||||
#include "uac_amixer.h"
|
||||
#include "uac_log.h"
|
||||
#include "uac_log.h"
|
||||
|
||||
#ifdef LOG_TAG
|
||||
#undef LOG_TAG
|
||||
#define LOG_TAG "mpi_contol_comm"
|
||||
#endif
|
||||
|
||||
typedef struct _MpiAioDeviceAttrConfigMap {
|
||||
UacMpiType mpiType;
|
||||
int uacMode;
|
||||
|
||||
const char *sndCardname;
|
||||
RK_U32 sndCardChannels;
|
||||
RK_U32 sndCardSampleRate;
|
||||
AUDIO_BIT_WIDTH_E sndCardbitWidth;
|
||||
|
||||
RK_U32 dataSamplerate;
|
||||
AUDIO_BIT_WIDTH_E dataBitwidth;
|
||||
AUDIO_SOUND_MODE_E dataSoundmode;
|
||||
} MpiAioDeviceAttrConfigMap;
|
||||
|
||||
const static MpiAioDeviceAttrConfigMap sAioDevAttrCfgs[] = {
|
||||
// usb
|
||||
{UAC_MPI_TYPE_AI, UAC_STREAM_RECORD, "hw:1,0", 2, 44100, AUDIO_BIT_WIDTH_16,
|
||||
44100, AUDIO_BIT_WIDTH_16, AUDIO_SOUND_MODE_STEREO},
|
||||
// mic
|
||||
{UAC_MPI_TYPE_AI, UAC_STREAM_PLAYBACK, "hw:0,0", 2, 16000,
|
||||
AUDIO_BIT_WIDTH_16, 16000, AUDIO_BIT_WIDTH_16, AUDIO_SOUND_MODE_STEREO},
|
||||
// spk
|
||||
{UAC_MPI_TYPE_AO, UAC_STREAM_RECORD, "hw:0,0", 2, 16000, AUDIO_BIT_WIDTH_16,
|
||||
16000, AUDIO_BIT_WIDTH_16, AUDIO_SOUND_MODE_STEREO},
|
||||
// usb
|
||||
{UAC_MPI_TYPE_AO, UAC_STREAM_PLAYBACK, "hw:1,0", 2, 44100,
|
||||
AUDIO_BIT_WIDTH_16, 44100, AUDIO_BIT_WIDTH_16, AUDIO_SOUND_MODE_STEREO},
|
||||
};
|
||||
|
||||
const static char *sAfVqeCfgPath = "/oem/usr/share/uac_app/configs_skv.json";
|
||||
#define VQE_SAMPLERATE 16000
|
||||
RK_U32 UacMpiUtil::getSndCardSampleRate(UacMpiType type, int mode) {
|
||||
GET_ENTRY_VALUE(type, mode, sAioDevAttrCfgs, mpiType, uacMode,
|
||||
sndCardSampleRate);
|
||||
return 0;
|
||||
}
|
||||
|
||||
const char *UacMpiUtil::getSndCardName(UacMpiType type, int mode) {
|
||||
GET_ENTRY_VALUE(type, mode, sAioDevAttrCfgs, mpiType, uacMode, sndCardname);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
RK_U32 UacMpiUtil::getSndCardChannels(UacMpiType type, int mode) {
|
||||
GET_ENTRY_VALUE(type, mode, sAioDevAttrCfgs, mpiType, uacMode,
|
||||
sndCardChannels);
|
||||
return 0;
|
||||
}
|
||||
|
||||
AUDIO_BIT_WIDTH_E UacMpiUtil::getSndCardbitWidth(UacMpiType type, int mode) {
|
||||
GET_ENTRY_VALUE(type, mode, sAioDevAttrCfgs, mpiType, uacMode,
|
||||
sndCardbitWidth);
|
||||
return AUDIO_BIT_WIDTH_BUTT;
|
||||
}
|
||||
|
||||
RK_U32 UacMpiUtil::getDataSamplerate(UacMpiType type, int mode) {
|
||||
GET_ENTRY_VALUE(type, mode, sAioDevAttrCfgs, mpiType, uacMode,
|
||||
dataSamplerate);
|
||||
return 0;
|
||||
}
|
||||
|
||||
AUDIO_BIT_WIDTH_E UacMpiUtil::getDataBitwidth(UacMpiType type, int mode) {
|
||||
GET_ENTRY_VALUE(type, mode, sAioDevAttrCfgs, mpiType, uacMode, dataBitwidth);
|
||||
return AUDIO_BIT_WIDTH_BUTT;
|
||||
}
|
||||
|
||||
AUDIO_SOUND_MODE_E UacMpiUtil::getDataSoundmode(UacMpiType type, int mode) {
|
||||
GET_ENTRY_VALUE(type, mode, sAioDevAttrCfgs, mpiType, uacMode, dataSoundmode);
|
||||
return AUDIO_SOUND_MODE_BUTT;
|
||||
}
|
||||
|
||||
const char *UacMpiUtil::getVqeCfgPath() { return sAfVqeCfgPath; }
|
||||
|
||||
RK_U32 UacMpiUtil::getVqeSampleRate() { return VQE_SAMPLERATE; }
|
||||
|
||||
RK_U32 UacMpiUtil::getVqeChannels() {
|
||||
return sChnAttrCfgs[sRefMode].u32Channels;
|
||||
}
|
||||
|
||||
RK_U32 UacMpiUtil::getVqeChnLayout() {
|
||||
RK_U32 layout =
|
||||
sChnAttrCfgs[sRefMode].u32MicLayout + sChnAttrCfgs[sRefMode].u32RefLayout;
|
||||
return layout;
|
||||
}
|
||||
|
||||
RK_U32 UacMpiUtil::getVqeRefLayout() {
|
||||
return sChnAttrCfgs[sRefMode].u32RefLayout;
|
||||
}
|
||||
|
||||
RK_U32 UacMpiUtil::getVqeMicLayout() {
|
||||
return sChnAttrCfgs[sRefMode].u32MicLayout;
|
||||
}
|
||||
|
||||
void mpi_set_samplerate(int type, UacMpiStream &streamCfg) {
|
||||
int sampleRate = streamCfg.config.samplerate;
|
||||
if (sampleRate == 0)
|
||||
return;
|
||||
AUDIO_DEV aiDevId = streamCfg.idCfg.aiDevId;
|
||||
AI_CHN aiChn = streamCfg.idCfg.aiChnId;
|
||||
AUDIO_DEV aoDevId = streamCfg.idCfg.aoDevId;
|
||||
AO_CHN aoChn = streamCfg.idCfg.aoChnId;
|
||||
ALOGD("type = %d, sampleRate = %d\n", type, sampleRate);
|
||||
/*
|
||||
* 1. for usb capture, we update audio config to capture
|
||||
* 2. for usb playback, if there is resample before usb playback,
|
||||
* we set audio config to this resample, the new config will
|
||||
* pass to usb playback from resample to usb playback when
|
||||
* the datas move from resample to usb.
|
||||
* 3. we alway use samperate=48K to open mic and speaker,
|
||||
* because usually, they use the same group i2s, and
|
||||
* not allowned to use diffrent samplerate.
|
||||
*/
|
||||
if (type == UAC_STREAM_RECORD) {
|
||||
// the usb record always the first node
|
||||
AI_CHN_ATTR_S params;
|
||||
memset(¶ms, 0, sizeof(AI_CHN_ATTR_S));
|
||||
params.u32SampleRate = sampleRate;
|
||||
params.enChnAttr = AUDIO_CHN_ATTR_RATE;
|
||||
RK_MPI_AI_SetChnAttr(aiDevId, aiChn, ¶ms);
|
||||
} else {
|
||||
// find the resample before usb playback
|
||||
AO_CHN_ATTR_S params;
|
||||
memset(¶ms, 0, sizeof(AO_CHN_ATTR_S));
|
||||
params.u32SampleRate = sampleRate;
|
||||
params.enChnAttr = AUDIO_CHN_ATTR_RATE;
|
||||
RK_MPI_AO_SetChnAttr(aoDevId, aoChn, ¶ms);
|
||||
}
|
||||
}
|
||||
|
||||
void mpi_set_volume(int type, UacMpiStream &streamCfg) {
|
||||
int mute = streamCfg.config.mute;
|
||||
int volume = streamCfg.config.intVol;
|
||||
AUDIO_DEV aoDevId = streamCfg.idCfg.aoDevId;
|
||||
ALOGD("type = %d, mute = %d, volume = %d\n", type, mute, volume);
|
||||
AUDIO_FADE_S aFade;
|
||||
memset(&aFade, 0, sizeof(AUDIO_FADE_S));
|
||||
|
||||
RK_BOOL bMute = (mute == 0) ? RK_FALSE : RK_TRUE;
|
||||
RK_MPI_AO_SetMute(aoDevId, bMute, &aFade);
|
||||
RK_MPI_AO_SetVolume(aoDevId, volume);
|
||||
}
|
||||
|
||||
void mpi_set_ppm(int type, UacMpiStream &streamCfg) {
|
||||
int ppm = streamCfg.config.ppm;
|
||||
amix_set_ppm(MIC_SPK_SOUNDCARD_INDEX, ppm);
|
||||
}
|
||||
//#endif
|
||||
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Copyright 2022 Rockchip Electronics Co. LTD
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "uac_amixer.h"
|
||||
#include "rk_mpi_amix.h"
|
||||
#include "uac_log.h"
|
||||
|
||||
#ifdef LOG_TAG
|
||||
#undef LOG_TAG
|
||||
#define LOG_TAG "amixer"
|
||||
#endif
|
||||
|
||||
const static char *sRefCtrlName = "I2STDM Digital Loopback Mode";
|
||||
const static char *sPpmCtrlName = "PCM Clk Compensation In PPM";
|
||||
|
||||
RK_S32 UACAmixer::set(AUDIO_DEV AmixDevId, const char *ctrlName,
|
||||
const char *value) {
|
||||
ALOGD("AmixDevId = %d, ctrl = %s, value = %s", AmixDevId, ctrlName, value);
|
||||
return RK_MPI_AMIX_SetControl(AmixDevId, ctrlName, (char *)value);
|
||||
}
|
||||
|
||||
RK_S32 UACAmixer::get(AUDIO_DEV AmixDevId, const char *ctrlName) {
|
||||
return RK_MPI_AMIX_GetControl(AmixDevId, ctrlName, NULL);
|
||||
}
|
||||
|
||||
void UACAmixer::dumpContents(AUDIO_DEV AmixDevId) {
|
||||
RK_MPI_AMIX_ListContents(AmixDevId);
|
||||
}
|
||||
|
||||
RK_S32 amix_set_ref_mode(AUDIO_DEV AoDevId) {
|
||||
return UACAmixer::set(AoDevId, sRefCtrlName, sChnAttrCfgs[sRefMode].chMode);
|
||||
}
|
||||
|
||||
RK_S32 amix_set_ppm(AUDIO_DEV AoDevId, RK_S32 ppm) {
|
||||
char str[64];
|
||||
snprintf(str, sizeof(str), "%d", ppm);
|
||||
return UACAmixer::set(AoDevId, sPpmCtrlName, str);
|
||||
}
|
||||
30
project/app/uvc_app_tiny/uvc_app/uac/src/uac_common_def.cpp
Normal file
30
project/app/uvc_app_tiny/uvc_app/uac/src/uac_common_def.cpp
Normal file
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Copyright 2022 Rockchip Electronics Co. LTD
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
//#ifdef __cplusplus
|
||||
#include "uac_common_def.h"
|
||||
|
||||
uint64_t getRelativeTimeMs() {
|
||||
return getRelativeTimeUs() / 1000; /* milliseconds */
|
||||
}
|
||||
|
||||
uint64_t getRelativeTimeUs() {
|
||||
struct timespec time = {0, 0};
|
||||
clock_gettime(CLOCK_MONOTONIC, &time);
|
||||
return (uint64_t)time.tv_sec * 1000000LL +
|
||||
(uint64_t)time.tv_nsec / 1000; /* microseconds */
|
||||
}
|
||||
//#endif
|
||||
147
project/app/uvc_app_tiny/uvc_app/uac/src/uac_control.cpp
Normal file
147
project/app/uvc_app_tiny/uvc_app/uac/src/uac_control.cpp
Normal file
@@ -0,0 +1,147 @@
|
||||
/*
|
||||
* Copyright 2020 Rockchip Electronics Co. LTD
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
//#ifdef __cplusplus
|
||||
|
||||
#include "uac_control.h"
|
||||
#include "uac_control_factory.h"
|
||||
#include "uac_log.h"
|
||||
#ifdef UAC_MPI
|
||||
#include "mpi_control_common.h"
|
||||
#endif
|
||||
|
||||
int uac_app_log_level;
|
||||
|
||||
typedef struct _UacControls {
|
||||
int mode;
|
||||
UACControl *uac;
|
||||
pthread_mutex_t mutex;
|
||||
} UacControls;
|
||||
|
||||
static UacControls *gUAControl = NULL;
|
||||
int uac_control_create(int type) {
|
||||
int i = 0;
|
||||
char *ch = NULL;
|
||||
if (type == UAC_API_GRAPH) {
|
||||
ch = (char *)"graph";
|
||||
} else if (type == UAC_API_MPI) {
|
||||
ch = (char *)"mpi";
|
||||
}
|
||||
|
||||
ALOGD("-------------uac use %s--------------\n", ch);
|
||||
if (!gUAControl) {
|
||||
uac_control_destory();
|
||||
}
|
||||
|
||||
gUAControl = (UacControls *)calloc(UAC_STREAM_MAX, sizeof(UacControls));
|
||||
if (!gUAControl) {
|
||||
ALOGE("fail to malloc memory!\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
memset(gUAControl, 0, sizeof(UacControls));
|
||||
for (i = 0; i < UAC_STREAM_MAX; i++) {
|
||||
gUAControl[i].mode = i;
|
||||
pthread_mutex_init(&gUAControl[i].mutex, NULL);
|
||||
|
||||
gUAControl[i].uac = UacControlFactory::create((UacApiType)type, i);
|
||||
if (!gUAControl[i].uac) {
|
||||
uac_control_destory();
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void uac_control_destory() {
|
||||
if (gUAControl == NULL)
|
||||
return;
|
||||
|
||||
int i = 0;
|
||||
UACControl *uac = NULL;
|
||||
if (gUAControl) {
|
||||
for (i = 0; i < UAC_STREAM_MAX; i++) {
|
||||
uac = gUAControl[i].uac;
|
||||
if (uac)
|
||||
delete uac;
|
||||
gUAControl[i].uac = NULL;
|
||||
pthread_mutex_destroy(&gUAControl[i].mutex);
|
||||
}
|
||||
}
|
||||
|
||||
free(gUAControl);
|
||||
gUAControl = NULL;
|
||||
}
|
||||
|
||||
UacControls *getControlContext(int mode) { return &gUAControl[mode]; }
|
||||
|
||||
int uac_start(int mode) {
|
||||
int ret = 0;
|
||||
UacControls *uacs = getControlContext(mode);
|
||||
pthread_mutex_lock(&uacs->mutex);
|
||||
if (mode == uacs->mode) {
|
||||
ret = uacs->uac->uacStart();
|
||||
}
|
||||
pthread_mutex_unlock(&uacs->mutex);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void uac_stop(int mode) {
|
||||
UacControls *uacs = getControlContext(mode);
|
||||
pthread_mutex_lock(&uacs->mutex);
|
||||
if (mode == uacs->mode) {
|
||||
uacs->uac->uacStop();
|
||||
}
|
||||
pthread_mutex_unlock(&uacs->mutex);
|
||||
}
|
||||
|
||||
void uac_set_sample_rate(int mode, int samplerate) {
|
||||
UacControls *uacs = getControlContext(mode);
|
||||
pthread_mutex_lock(&uacs->mutex);
|
||||
if (mode == uacs->mode) {
|
||||
uacs->uac->uacSetSampleRate(samplerate);
|
||||
}
|
||||
pthread_mutex_unlock(&uacs->mutex);
|
||||
}
|
||||
|
||||
void uac_set_volume(int mode, int volume) {
|
||||
UacControls *uacs = getControlContext(mode);
|
||||
pthread_mutex_lock(&uacs->mutex);
|
||||
if (mode == uacs->mode) {
|
||||
uacs->uac->uacSetVolume(volume);
|
||||
}
|
||||
pthread_mutex_unlock(&uacs->mutex);
|
||||
}
|
||||
|
||||
void uac_set_mute(int mode, int mute) {
|
||||
UacControls *uacs = getControlContext(mode);
|
||||
pthread_mutex_lock(&uacs->mutex);
|
||||
if (mode == uacs->mode) {
|
||||
uacs->uac->uacSetMute(mute);
|
||||
}
|
||||
pthread_mutex_unlock(&uacs->mutex);
|
||||
}
|
||||
|
||||
void uac_set_ppm(int mode, int ppm) {
|
||||
UacControls *uacs = getControlContext(mode);
|
||||
pthread_mutex_lock(&uacs->mutex);
|
||||
if (mode == uacs->mode) {
|
||||
uacs->uac->uacSetPpm(ppm);
|
||||
}
|
||||
pthread_mutex_unlock(&uacs->mutex);
|
||||
}
|
||||
//#endif
|
||||
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright 2022 Rockchip Electronics Co. LTD
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
//#ifdef __cplusplus
|
||||
|
||||
#include "uac_control_factory.h"
|
||||
#include "uac_control_graph.h"
|
||||
#include "uac_control_mpi.h"
|
||||
#include "uac_log.h"
|
||||
|
||||
UACControl *createUacGraph(int mode) {
|
||||
UACControl *uac = NULL;
|
||||
#ifdef UAC_GRAPH
|
||||
uac = new UACControlGraph(mode);
|
||||
#endif
|
||||
return uac;
|
||||
}
|
||||
|
||||
UACControl *createUacMpi(int mode) {
|
||||
UACControl *uac = NULL;
|
||||
#ifdef UAC_MPI
|
||||
uac = new UACControlMpi(mode);
|
||||
#endif
|
||||
return uac;
|
||||
}
|
||||
|
||||
UACControl *UacControlFactory::create(UacApiType type, int mode) {
|
||||
UACControl *uac = NULL;
|
||||
switch (type) {
|
||||
case UAC_API_MPI:
|
||||
uac = createUacMpi(mode);
|
||||
break;
|
||||
case UAC_API_GRAPH:
|
||||
uac = createUacGraph(mode);
|
||||
break;
|
||||
default:
|
||||
ALOGD("unkown UacApiType(%d), please check!\n", type);
|
||||
break;
|
||||
}
|
||||
|
||||
return uac;
|
||||
}
|
||||
//#endif
|
||||
427
project/app/uvc_app_tiny/uvc_app/uac/src/uac_uevent.cpp
Normal file
427
project/app/uvc_app_tiny/uvc_app/uac/src/uac_uevent.cpp
Normal file
@@ -0,0 +1,427 @@
|
||||
/*
|
||||
* Copyright (C) 2019 Rockchip Electronics Co., Ltd.
|
||||
*
|
||||
* This software is available to you under a choice of one of two
|
||||
* licenses. You may choose to be licensed under the terms of the GNU
|
||||
* General Public License (GPL), available from the file
|
||||
* COPYING in the main directory of this source tree, or the
|
||||
* OpenIB.org BSD license below:
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or
|
||||
* without modification, are permitted provided that the following
|
||||
* conditions are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer.
|
||||
*
|
||||
* - Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
//#ifdef __cplusplus
|
||||
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <pthread.h>
|
||||
#include <signal.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/prctl.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "uac_control.h"
|
||||
#include "uac_log.h"
|
||||
#include "uac_uevent.h"
|
||||
#include <linux/netlink.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
#ifdef LOG_TAG
|
||||
#undef LOG_TAG
|
||||
#define LOG_TAG "audio_event"
|
||||
#endif
|
||||
|
||||
/*
|
||||
* case 1:
|
||||
* the UAC1 uevent when pc/remote close(play sound of usb close)
|
||||
*
|
||||
* strs[0] = ACTION=change
|
||||
* strs[1] = DEVPATH=/devices/virtual/u_audio/UAC1_Gadget 0 // UAC2_Gadget
|
||||
* strs[2] = SUBSYSTEM=u_audio
|
||||
* strs[3] = USB_STATE=SET_INTERFACE
|
||||
* strs[4] = STREAM_DIRECTION=OUT
|
||||
* strs[5] = STREAM_STATE=OFF
|
||||
*
|
||||
*
|
||||
* case 2:
|
||||
* the UAC1 uevent when pc/remote play start(play sound of usb open)
|
||||
*
|
||||
* strs[0] = ACTION=change
|
||||
* strs[1] = DEVPATH=/devices/virtual/u_audio/UAC1_Gadget 0
|
||||
* strs[2] = SUBSYSTEM=u_audio
|
||||
* strs[3] = USB_STATE=SET_INTERFACE
|
||||
* strs[4] = STREAM_DIRECTION=OUT
|
||||
* strs[5] = STREAM_STATE=ON
|
||||
*
|
||||
*
|
||||
* case 3:
|
||||
* the UAC1 uevent when pc/remote capture start(record sound of usb open)
|
||||
*
|
||||
* strs[0] = ACTION=change
|
||||
* strs[1] = DEVPATH=/devices/virtual/u_audio/UAC1_Gadget 0
|
||||
* strs[2] = SUBSYSTEM=u_audio
|
||||
* strs[3] = USB_STATE=SET_INTERFACE
|
||||
* strs[4] = STREAM_DIRECTION=IN
|
||||
* strs[5] = STREAM_STATE=ON
|
||||
*
|
||||
*
|
||||
* case 4:
|
||||
* the UAC1 uevent when pc/remote capture stop(record sound of usb open)
|
||||
*
|
||||
* strs[0] = ACTION=change
|
||||
* strs[1] = DEVPATH=/devices/virtual/u_audio/UAC1_Gadget 0
|
||||
* strs[2] = SUBSYSTEM=u_audio
|
||||
* strs[3] = USB_STATE=SET_INTERFACE
|
||||
* strs[4] = STREAM_DIRECTION=IN
|
||||
* strs[5] = STREAM_STATE=OFF
|
||||
*
|
||||
*
|
||||
* case 5:
|
||||
* the UAC1 uevent
|
||||
*
|
||||
* strs[0] = ACTION=change
|
||||
* strs[1] = DEVPATH=/devices/virtual/u_audio/UAC1_Gadget 0
|
||||
* strs[2] = SUBSYSTEM=u_audio
|
||||
* strs[3] = USB_STATE=SET_SAMPLE_RATE
|
||||
* strs[4] = STREAM_DIRECTION=IN
|
||||
* strs[5] = SAMPLE_RATE=48000
|
||||
*/
|
||||
#define UAC_UEVENT_AUDIO "SUBSYSTEM=u_audio"
|
||||
#define UAC_UEVENT_SET_INTERFACE "USB_STATE=SET_INTERFACE"
|
||||
#define UAC_UEVENT_SET_SAMPLE_RATE "USB_STATE=SET_SAMPLE_RATE"
|
||||
#define UAC_UEVENT_SET_VOLUME "USB_STATE=SET_VOLUME"
|
||||
#define UAC_UEVENT_SET_MUTE "USB_STATE=SET_MUTE"
|
||||
#define UAC_UEVENT_SET_AUDIO_CLK "USB_STATE=SET_AUDIO_CLK"
|
||||
|
||||
#define UAC_STREAM_DIRECT "STREAM_DIRECTION="
|
||||
#define UAC_STREAM_STATE "STREAM_STATE="
|
||||
#define UAC_SAMPLE_RATE "SAMPLE_RATE="
|
||||
#define UAC_SET_VOLUME "VOLUME="
|
||||
#define UAC_SET_MUTE "MUTE="
|
||||
#define UAC_PPM "PPM="
|
||||
|
||||
// remote device/pc->our device
|
||||
#define UAC_REMOTE_PLAY "OUT"
|
||||
|
||||
// our device->remote device/pc
|
||||
#define UAC_REMOTE_CAPTURE "IN"
|
||||
|
||||
// sound card is opened
|
||||
#define UAC_STREAM_START "ON"
|
||||
|
||||
// sound card is closed
|
||||
#define UAC_STREAM_STOP "OFF"
|
||||
|
||||
enum UAC_UEVENT_KEY {
|
||||
UAC_KEY_AUDIO = 2,
|
||||
UAC_KEY_USB_STATE = 3,
|
||||
UAC_KEY_DIRECTION = 4,
|
||||
UAC_KEY_PPM = 4,
|
||||
UAC_KEY_STREAM_STATE = 5,
|
||||
UAC_KEY_SAMPLE_RATE = UAC_KEY_STREAM_STATE,
|
||||
UAC_KEY_VOLUME = UAC_KEY_STREAM_STATE,
|
||||
UAC_KEY_MUTE = UAC_KEY_STREAM_STATE,
|
||||
};
|
||||
|
||||
bool compare(const char *dst, const char *srt) {
|
||||
if ((dst == NULL) || (srt == NULL))
|
||||
return false;
|
||||
|
||||
if (!strncmp(dst, srt, strlen(srt))) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void audio_play(const struct _uevent *uevent) {
|
||||
char *direct = uevent->strs[UAC_KEY_DIRECTION];
|
||||
char *status = uevent->strs[UAC_KEY_STREAM_STATE];
|
||||
|
||||
if (compare(direct, UAC_STREAM_DIRECT) && compare(status, UAC_STREAM_STATE)) {
|
||||
char *device = &direct[strlen(UAC_STREAM_DIRECT)];
|
||||
char *state = &status[strlen(UAC_STREAM_STATE)];
|
||||
// remote device/pc open/close usb sound card to write data
|
||||
if (compare(device, UAC_REMOTE_PLAY)) {
|
||||
if (compare(UAC_STREAM_START, state)) {
|
||||
// stream start, we need to open usb card to record datas
|
||||
ALOGD("remote device/pc start to play data to us, we need to open usb "
|
||||
"to capture datas\n");
|
||||
uac_start(UAC_STREAM_RECORD);
|
||||
} else if (compare(UAC_STREAM_STOP, state)) {
|
||||
ALOGD("remote device/pc stop to play data to us, we need to stop "
|
||||
"capture datas\n");
|
||||
uac_stop(UAC_STREAM_RECORD);
|
||||
}
|
||||
} else if (compare(device, UAC_REMOTE_CAPTURE)) {
|
||||
// our device->remote device/pc
|
||||
if (compare(UAC_STREAM_START, state)) {
|
||||
// stream start, we need to open usb card to record datas
|
||||
ALOGD("remote device/pc start to record from us, we need to open usb "
|
||||
"to send datas\n");
|
||||
uac_start(UAC_STREAM_PLAYBACK);
|
||||
} else if (compare(UAC_STREAM_STOP, state)) {
|
||||
ALOGD("remote device/pc stop to record from us, we need to stop write "
|
||||
"datas to usb\n");
|
||||
uac_stop(UAC_STREAM_PLAYBACK);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void audio_set_samplerate(const struct _uevent *uevent) {
|
||||
char *direct = uevent->strs[UAC_KEY_DIRECTION];
|
||||
char *samplerate = uevent->strs[UAC_KEY_SAMPLE_RATE];
|
||||
ALOGD("%s: %s\n", __FUNCTION__, direct);
|
||||
ALOGD("%s: %s\n", __FUNCTION__, samplerate);
|
||||
if (compare(direct, UAC_STREAM_DIRECT)) {
|
||||
char *device = &direct[strlen(UAC_STREAM_DIRECT)];
|
||||
char *rate = &samplerate[strlen(UAC_SAMPLE_RATE)];
|
||||
int sampleRate = atoi(rate);
|
||||
if (compare(device, UAC_REMOTE_PLAY)) {
|
||||
ALOGD("set samplerate %d to usb record\n", sampleRate);
|
||||
uac_set_sample_rate(UAC_STREAM_RECORD, sampleRate);
|
||||
} else if (compare(device, UAC_REMOTE_CAPTURE)) {
|
||||
ALOGD("set samplerate %d to usb playback\n", sampleRate);
|
||||
uac_set_sample_rate(UAC_STREAM_PLAYBACK, sampleRate);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* strs[0] = ACTION=change
|
||||
* strs[1] = DEVPATH=/devicges/virtual/u_audio/UAC1_Gadgeta 0
|
||||
* strs[2] = SUBSYSTEM=u_audio
|
||||
* strs[3] = USB_STATE=SET_VOLUME
|
||||
* strs[4] = STREAM_DIRECTION=OUT
|
||||
* strs[5] = VOLUME=0x7FFF
|
||||
* index db
|
||||
* 0x7FFF: 127.9961
|
||||
* ......
|
||||
* 0x0100: 1.0000
|
||||
* ......
|
||||
* 0x0002: 0.0078
|
||||
* 0x0001: 0.0039
|
||||
* 0x0000: 0.0000
|
||||
* 0xFFFF: -0.0039
|
||||
* 0xFFFE: -0.0078
|
||||
* ......
|
||||
* 0xFE00: -1.0000
|
||||
* ......
|
||||
* 0x8002: -127.9922
|
||||
* 0x8001: -127.9961
|
||||
*
|
||||
*/
|
||||
void audio_set_volume(const struct _uevent *uevent) {
|
||||
char *direct = uevent->strs[UAC_KEY_DIRECTION];
|
||||
char *volumeStr = uevent->strs[UAC_KEY_VOLUME];
|
||||
int unit = 0x100;
|
||||
ALOGD("direct = %s volume = %s\n", direct, volumeStr);
|
||||
if (compare(direct, UAC_STREAM_DIRECT)) {
|
||||
char *device = &direct[strlen(UAC_STREAM_DIRECT)];
|
||||
short volume = 0;
|
||||
float db = 0;
|
||||
sscanf(volumeStr, "VOLUME=0x%x", &volume);
|
||||
db = volume / (float)unit;
|
||||
double precent = pow(10, db / 10);
|
||||
int precentInt = (int)(precent * 100);
|
||||
ALOGD("set db = %f, precent = %lf, precentInt = %d\n", db, precent,
|
||||
precentInt);
|
||||
if (compare(device, UAC_REMOTE_PLAY)) {
|
||||
ALOGD("set volume %d to usb record\n", precentInt);
|
||||
uac_set_volume(UAC_STREAM_RECORD, precentInt);
|
||||
} else if (compare(device, UAC_REMOTE_CAPTURE)) {
|
||||
ALOGD("set volume %d to usb playback\n", precentInt);
|
||||
uac_set_volume(UAC_STREAM_PLAYBACK, precentInt);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* strs[0] = ACTION=change
|
||||
* strs[1] = DEVPATH=/devices/virtual/u_audio/UAC1_Gadget 0
|
||||
* strs[2] = SUBSYSTEM=u_audio
|
||||
* strs[3] = USB_STATE=SET_MUTE
|
||||
* strs[4] = STREAM_DIRECTION=OUT
|
||||
* strs[5] = MUTE=1
|
||||
*/
|
||||
void audio_set_mute(const struct _uevent *uevent) {
|
||||
char *direct = uevent->strs[UAC_KEY_DIRECTION];
|
||||
char *muteStr = uevent->strs[UAC_KEY_MUTE];
|
||||
ALOGD("direct = %s mute = %s\n", direct, muteStr);
|
||||
|
||||
if (compare(direct, UAC_STREAM_DIRECT)) {
|
||||
char *device = &direct[strlen(UAC_STREAM_DIRECT)];
|
||||
int mute = 0;
|
||||
sscanf(muteStr, "MUTE=%d", &mute);
|
||||
if (compare(device, UAC_REMOTE_PLAY)) {
|
||||
ALOGD("set mute = %d to usb record\n", mute);
|
||||
uac_set_mute(UAC_STREAM_RECORD, mute);
|
||||
} else if (compare(device, UAC_REMOTE_CAPTURE)) {
|
||||
ALOGD("set mute = %d to usb playback\n", mute);
|
||||
uac_set_mute(UAC_STREAM_PLAYBACK, mute);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* strs[0] = ACTION=change
|
||||
* strs[1] = DEVPATH=/devices/virtual/u_audio/UAC1_Gadget 0
|
||||
* strs[2] = SUBSYSTEM=u_audio
|
||||
* strs[3] = USB_STATE=SET_AUDIO_CLK
|
||||
* strs[4] = PPM=-21
|
||||
* strs[5] = SEQNUM=1573
|
||||
*/
|
||||
void audio_set_ppm(const struct _uevent *uevent) {
|
||||
char *ppmStr = uevent->strs[UAC_KEY_PPM];
|
||||
|
||||
if (compare(ppmStr, UAC_PPM)) {
|
||||
int ppm = 0;
|
||||
sscanf(ppmStr, "PPM=%d", &ppm);
|
||||
uac_set_ppm(UAC_STREAM_RECORD, ppm);
|
||||
uac_set_ppm(UAC_STREAM_PLAYBACK, ppm);
|
||||
}
|
||||
}
|
||||
|
||||
void audio_event(const struct _uevent *uevent) {
|
||||
char *event = uevent->strs[UAC_KEY_USB_STATE];
|
||||
char *direct = uevent->strs[UAC_KEY_DIRECTION];
|
||||
char *status = uevent->strs[UAC_KEY_STREAM_STATE];
|
||||
ALOGD("event = %s\n", event);
|
||||
ALOGD("direct = %s\n", direct);
|
||||
ALOGD("status = %s\n", status);
|
||||
if ((event == NULL) || (direct == NULL) || (status == NULL)) {
|
||||
return;
|
||||
}
|
||||
|
||||
bool setInterface = compare(event, UAC_UEVENT_SET_INTERFACE);
|
||||
bool setSampleRate = compare(event, UAC_UEVENT_SET_SAMPLE_RATE);
|
||||
bool setVolume = compare(event, UAC_UEVENT_SET_VOLUME);
|
||||
bool setMute = compare(event, UAC_UEVENT_SET_MUTE);
|
||||
bool setClk = compare(event, UAC_UEVENT_SET_AUDIO_CLK);
|
||||
if (!setInterface && !setSampleRate && !setVolume && !setMute && !setClk) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (setInterface) {
|
||||
ALOGD("uevent---------------audio_play\n");
|
||||
audio_play(uevent);
|
||||
} else if (setSampleRate) {
|
||||
ALOGD("uevent---------------audio_set_samplerate\n");
|
||||
audio_set_samplerate(uevent);
|
||||
} else if (setVolume) {
|
||||
ALOGD("uevent---------------setVolume\n");
|
||||
audio_set_volume(uevent);
|
||||
} else if (setMute) {
|
||||
ALOGD("uevent---------------setMute\n");
|
||||
audio_set_mute(uevent);
|
||||
} else if (setClk) {
|
||||
ALOGD("uevent---------------setClk\n");
|
||||
audio_set_ppm(uevent);
|
||||
}
|
||||
}
|
||||
|
||||
static void parse_event(const struct _uevent *event) {
|
||||
if (event->size <= 0)
|
||||
return;
|
||||
|
||||
#if 0
|
||||
for (int i = 0 ; i < 10; i++) {
|
||||
if (event->strs[i] != NULL) {
|
||||
ALOGD("strs[%d] = %s\n", i, event->strs[i]);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (compare(event->strs[UAC_KEY_AUDIO], UAC_UEVENT_AUDIO)) {
|
||||
audio_event(event);
|
||||
}
|
||||
}
|
||||
|
||||
static void *uac_event_monitor_thread(void *arg) {
|
||||
int sockfd;
|
||||
int i, j, len;
|
||||
char buf[512];
|
||||
struct iovec iov;
|
||||
struct msghdr msg;
|
||||
struct sockaddr_nl sa;
|
||||
struct _uevent event;
|
||||
// uint32_t flags = *(uint32_t *)arg;
|
||||
|
||||
prctl(PR_SET_NAME, "event_monitor", 0, 0, 0);
|
||||
|
||||
memset(&sa, 0, sizeof(sa));
|
||||
sa.nl_family = AF_NETLINK;
|
||||
sa.nl_groups = NETLINK_KOBJECT_UEVENT;
|
||||
sa.nl_pid = 0;
|
||||
memset(&msg, 0, sizeof(msg));
|
||||
iov.iov_base = (void *)buf;
|
||||
iov.iov_len = sizeof(buf);
|
||||
msg.msg_name = (void *)&sa;
|
||||
msg.msg_namelen = sizeof(sa);
|
||||
msg.msg_iov = &iov;
|
||||
msg.msg_iovlen = 1;
|
||||
|
||||
sockfd = socket(AF_NETLINK, SOCK_RAW, NETLINK_KOBJECT_UEVENT);
|
||||
if (sockfd == -1) {
|
||||
ALOGE("socket creating failed:%s\n", strerror(errno));
|
||||
goto err_event_monitor;
|
||||
}
|
||||
|
||||
if (bind(sockfd, (struct sockaddr *)&sa, sizeof(sa)) == -1) {
|
||||
ALOGE("bind error:%s\n", strerror(errno));
|
||||
goto err_event_monitor;
|
||||
}
|
||||
|
||||
while (1) {
|
||||
event.size = 0;
|
||||
len = recvmsg(sockfd, &msg, 0);
|
||||
if (len < 0) {
|
||||
ALOGD("receive error\n");
|
||||
} else if (len < 32 || len > sizeof(buf)) {
|
||||
ALOGD("invalid message");
|
||||
} else {
|
||||
for (i = 0, j = 0; i < len; i++) {
|
||||
if (*(buf + i) == '\0' && (i + 1) != len) {
|
||||
event.strs[j++] = buf + i + 1;
|
||||
event.size = j;
|
||||
}
|
||||
}
|
||||
}
|
||||
parse_event(&event);
|
||||
}
|
||||
|
||||
err_event_monitor:
|
||||
pthread_detach(pthread_self());
|
||||
pthread_exit(NULL);
|
||||
}
|
||||
|
||||
int uac_uevent_monitor_run() {
|
||||
pthread_t tid;
|
||||
|
||||
return pthread_create(&tid, NULL, uac_event_monitor_thread, NULL);
|
||||
}
|
||||
//#endif
|
||||
BIN
project/app/uvc_app_tiny/uvc_app/uac/test/Sine1k_48k_16b.wav
Executable file
BIN
project/app/uvc_app_tiny/uvc_app/uac/test/Sine1k_48k_16b.wav
Executable file
Binary file not shown.
BIN
project/app/uvc_app_tiny/uvc_app/uac/test/mute.wav
Executable file
BIN
project/app/uvc_app_tiny/uvc_app/uac/test/mute.wav
Executable file
Binary file not shown.
BIN
project/app/uvc_app_tiny/uvc_app/uac/test/swp_48k_16b.wav
Executable file
BIN
project/app/uvc_app_tiny/uvc_app/uac/test/swp_48k_16b.wav
Executable file
Binary file not shown.
BIN
project/app/uvc_app_tiny/uvc_app/uac/test/white_noise.wav
Executable file
BIN
project/app/uvc_app_tiny/uvc_app/uac/test/white_noise.wav
Executable file
Binary file not shown.
BIN
project/app/uvc_app_tiny/uvc_app/uac/test/需求模板_语音算法_rk3xxx_xx客户.xlsx
Executable file
BIN
project/app/uvc_app_tiny/uvc_app/uac/test/需求模板_语音算法_rk3xxx_xx客户.xlsx
Executable file
Binary file not shown.
BIN
project/app/uvc_app_tiny/uvc_app/uac/tools/tinycap
Executable file
BIN
project/app/uvc_app_tiny/uvc_app/uac/tools/tinycap
Executable file
Binary file not shown.
BIN
project/app/uvc_app_tiny/uvc_app/uac/tools/tinymix
Executable file
BIN
project/app/uvc_app_tiny/uvc_app/uac/tools/tinymix
Executable file
Binary file not shown.
BIN
project/app/uvc_app_tiny/uvc_app/uac/tools/tinyplay
Executable file
BIN
project/app/uvc_app_tiny/uvc_app/uac/tools/tinyplay
Executable file
Binary file not shown.
61
project/app/uvc_app_tiny/uvc_app/uac/uac.cmake
Executable file
61
project/app/uvc_app_tiny/uvc_app/uac/uac.cmake
Executable file
@@ -0,0 +1,61 @@
|
||||
##PROJECT(uac)
|
||||
|
||||
include_directories(uac/src)
|
||||
include_directories(uac/src/include)
|
||||
|
||||
option(UAC_GRAPH "uac open graph" OFF)
|
||||
option(UAC_MPI "uac open mpi" ON)
|
||||
|
||||
if (${UAC_GRAPH})
|
||||
add_definitions(-DUAC_GRAPH)
|
||||
set(SOURCE_FILES_GRAPH
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/graph/graph_control.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/graph/uac_control_graph.cpp
|
||||
)
|
||||
message(STATUS "Build With Rockit Graph")
|
||||
else()
|
||||
message(STATUS "Build None Rockit Graph")
|
||||
endif()
|
||||
|
||||
if (${UAC_MPI})
|
||||
add_definitions(-DUAC_MPI)
|
||||
set(SOURCE_FILES_MPI
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/mpi/uac_control_mpi.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/mpi_common/uac_amixer.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/mpi_common/mpi_control_common.cpp
|
||||
)
|
||||
message(STATUS "Build With Rockit Mpi")
|
||||
else()
|
||||
message(STATUS "Build None Rockit Mpi")
|
||||
endif()
|
||||
|
||||
set(UAC_SOURCE
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/uac_uevent.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/uac_control.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/uac_common_def.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/uac_control_factory.cpp
|
||||
${SOURCE_FILES_GRAPH}
|
||||
${SOURCE_FILES_MPI}
|
||||
)
|
||||
|
||||
#set(UAC_DEPENDENT_LIBS
|
||||
# pthread
|
||||
# rockit
|
||||
#)
|
||||
|
||||
#set(UAC_AUDIO_ALGORITHM
|
||||
# ${CMAKE_CURRENT_LIST_DIR}/libs/libaec_bf_process.so)
|
||||
#install(FILES ${UAC_AUDIO_ALGORITHM} DESTINATION lib)
|
||||
|
||||
#ADD_EXECUTABLE(uac_app ${UAC_SOURCE})
|
||||
#target_link_libraries(uac_app ${UAC_APP_DEPENDENT_LIBS})
|
||||
|
||||
install(DIRECTORY ./uac DESTINATION include
|
||||
FILES_MATCHING PATTERN "*.h")
|
||||
|
||||
option(ENABLE_DEMO_BOARD "use demo board conf" OFF)
|
||||
if (${ENABLE_DEMO_BOARD})
|
||||
install(DIRECTORY ${CMAKE_CURRENT_LIST_DIR}/configs/demo/ DESTINATION share/uac_app FILES_MATCHING PATTERN "*.json")
|
||||
else()
|
||||
install(DIRECTORY ${CMAKE_CURRENT_LIST_DIR}/configs/ DESTINATION share/uac_app FILES_MATCHING PATTERN "configs_skv.json")
|
||||
endif()
|
||||
406
project/app/uvc_app_tiny/uvc_app/usb_config.sh
Executable file
406
project/app/uvc_app_tiny/uvc_app/usb_config.sh
Executable file
@@ -0,0 +1,406 @@
|
||||
#!/bin/sh
|
||||
|
||||
# UVC_MULTI_OPTIONS: Defines the options for UVC_MULTI variable.
|
||||
# Available options: off (close), one (Expand a device), two (Expand two devices)
|
||||
UVC_MULTI=one
|
||||
|
||||
CDC_ENABLE=NO
|
||||
USB_FUNCTIONS_DIR=/sys/kernel/config/usb_gadget/rockchip/functions
|
||||
USB_CONFIGS_DIR=/sys/kernel/config/usb_gadget/rockchip/configs/b.1
|
||||
|
||||
configure_uvc_resolution_yuyv()
|
||||
{
|
||||
UVC_DISPLAY_W=$1
|
||||
UVC_DISPLAY_H=$2
|
||||
UVC_DISPLAY_DIR=${USB_FUNCTIONS_DIR}/$UVC_GS/streaming/uncompressed/u/${UVC_DISPLAY_W}_${UVC_DISPLAY_H}p
|
||||
mkdir ${UVC_DISPLAY_DIR}
|
||||
echo $UVC_DISPLAY_W > ${UVC_DISPLAY_DIR}/wWidth
|
||||
echo $UVC_DISPLAY_H > ${UVC_DISPLAY_DIR}/wHeight
|
||||
echo 333333 > ${UVC_DISPLAY_DIR}/dwDefaultFrameInterval
|
||||
echo $((UVC_DISPLAY_W*UVC_DISPLAY_H*20)) > ${UVC_DISPLAY_DIR}/dwMinBitRate
|
||||
echo $((UVC_DISPLAY_W*UVC_DISPLAY_H*20)) > ${UVC_DISPLAY_DIR}/dwMaxBitRate
|
||||
echo $((UVC_DISPLAY_W*UVC_DISPLAY_H*2)) > ${UVC_DISPLAY_DIR}/dwMaxVideoFrameBufferSize
|
||||
echo -e "333333\n666666\n1000000\n2000000" > ${UVC_DISPLAY_DIR}/dwFrameInterval
|
||||
}
|
||||
|
||||
configure_uvc_resolution_yuyv_720p()
|
||||
{
|
||||
UVC_DISPLAY_W=$1
|
||||
UVC_DISPLAY_H=$2
|
||||
UVC_DISPLAY_DIR=${USB_FUNCTIONS_DIR}/$UVC_GS/streaming/uncompressed/u/${UVC_DISPLAY_W}_${UVC_DISPLAY_H}p
|
||||
mkdir ${UVC_DISPLAY_DIR}
|
||||
echo $UVC_DISPLAY_W > ${UVC_DISPLAY_DIR}/wWidth
|
||||
echo $UVC_DISPLAY_H > ${UVC_DISPLAY_DIR}/wHeight
|
||||
echo 1000000 > ${UVC_DISPLAY_DIR}/dwDefaultFrameInterval
|
||||
echo $((UVC_DISPLAY_W*UVC_DISPLAY_H*20)) > ${UVC_DISPLAY_DIR}/dwMinBitRate
|
||||
echo $((UVC_DISPLAY_W*UVC_DISPLAY_H*20)) > ${UVC_DISPLAY_DIR}/dwMaxBitRate
|
||||
echo $((UVC_DISPLAY_W*UVC_DISPLAY_H*2)) > ${UVC_DISPLAY_DIR}/dwMaxVideoFrameBufferSize
|
||||
echo -e "1000000\n2000000" > ${UVC_DISPLAY_DIR}/dwFrameInterval
|
||||
}
|
||||
|
||||
configure_uvc_resolution_yuyv_1080p()
|
||||
{
|
||||
UVC_DISPLAY_W=$1
|
||||
UVC_DISPLAY_H=$2
|
||||
UVC_DISPLAY_DIR=${USB_FUNCTIONS_DIR}/$UVC_GS/streaming/uncompressed/u/${UVC_DISPLAY_W}_${UVC_DISPLAY_H}p
|
||||
mkdir ${UVC_DISPLAY_DIR}
|
||||
echo $UVC_DISPLAY_W > ${UVC_DISPLAY_DIR}/wWidth
|
||||
echo $UVC_DISPLAY_H > ${UVC_DISPLAY_DIR}/wHeight
|
||||
echo 2500000 > ${UVC_DISPLAY_DIR}/dwDefaultFrameInterval
|
||||
echo $((UVC_DISPLAY_W*UVC_DISPLAY_H*20)) > ${UVC_DISPLAY_DIR}/dwMinBitRate
|
||||
echo $((UVC_DISPLAY_W*UVC_DISPLAY_H*20)) > ${UVC_DISPLAY_DIR}/dwMaxBitRate
|
||||
echo $((UVC_DISPLAY_W*UVC_DISPLAY_H*2)) > ${UVC_DISPLAY_DIR}/dwMaxVideoFrameBufferSize
|
||||
echo -e "2500000\n5000000" > ${UVC_DISPLAY_DIR}/dwFrameInterval
|
||||
}
|
||||
|
||||
configure_uvc_resolution_mjpeg()
|
||||
{
|
||||
UVC_DISPLAY_W=$1
|
||||
UVC_DISPLAY_H=$2
|
||||
UVC_DISPLAY_DIR=${USB_FUNCTIONS_DIR}/$UVC_GS/streaming/mjpeg/m/${UVC_DISPLAY_W}_${UVC_DISPLAY_H}p
|
||||
mkdir ${UVC_DISPLAY_DIR}
|
||||
echo $UVC_DISPLAY_W > ${UVC_DISPLAY_DIR}/wWidth
|
||||
echo $UVC_DISPLAY_H > ${UVC_DISPLAY_DIR}/wHeight
|
||||
echo 333333 > ${UVC_DISPLAY_DIR}/dwDefaultFrameInterval
|
||||
echo $((UVC_DISPLAY_W*UVC_DISPLAY_H*20)) > ${UVC_DISPLAY_DIR}/dwMinBitRate
|
||||
echo $((UVC_DISPLAY_W*UVC_DISPLAY_H*20)) > ${UVC_DISPLAY_DIR}/dwMaxBitRate
|
||||
echo $((UVC_DISPLAY_W*UVC_DISPLAY_H*2)) > ${UVC_DISPLAY_DIR}/dwMaxVideoFrameBufferSize
|
||||
echo -e "333333\n666666\n1000000\n2000000" > ${UVC_DISPLAY_DIR}/dwFrameInterval
|
||||
}
|
||||
configure_uvc_resolution_h264()
|
||||
{
|
||||
UVC_DISPLAY_W=$1
|
||||
UVC_DISPLAY_H=$2
|
||||
UVC_DISPLAY_DIR=${USB_FUNCTIONS_DIR}/$UVC_GS/streaming/framebased/f1/${UVC_DISPLAY_W}_${UVC_DISPLAY_H}p
|
||||
mkdir ${UVC_DISPLAY_DIR}
|
||||
echo $UVC_DISPLAY_W > ${UVC_DISPLAY_DIR}/wWidth
|
||||
echo $UVC_DISPLAY_H > ${UVC_DISPLAY_DIR}/wHeight
|
||||
echo 333333 > ${UVC_DISPLAY_DIR}/dwDefaultFrameInterval
|
||||
echo $((UVC_DISPLAY_W*UVC_DISPLAY_H*10)) > ${UVC_DISPLAY_DIR}/dwMinBitRate
|
||||
echo $((UVC_DISPLAY_W*UVC_DISPLAY_H*10)) > ${UVC_DISPLAY_DIR}/dwMaxBitRate
|
||||
echo -e "333333\n400000\n500000\n666666\n1000000\n2000000" > ${UVC_DISPLAY_DIR}/dwFrameInterval
|
||||
echo -ne \\x48\\x32\\x36\\x34\\x00\\x00\\x10\\x00\\x80\\x00\\x00\\xaa\\x00\\x38\\x9b\\x71 > ${USB_FUNCTIONS_DIR}/$UVC_GS/streaming/framebased/f1/guidFormat
|
||||
}
|
||||
configure_uvc_resolution_h265()
|
||||
{
|
||||
UVC_DISPLAY_W=$1
|
||||
UVC_DISPLAY_H=$2
|
||||
UVC_DISPLAY_DIR=${USB_FUNCTIONS_DIR}/$UVC_GS/streaming/framebased/f2/${UVC_DISPLAY_W}_${UVC_DISPLAY_H}p
|
||||
mkdir ${UVC_DISPLAY_DIR}
|
||||
echo $UVC_DISPLAY_W > ${UVC_DISPLAY_DIR}/wWidth
|
||||
echo $UVC_DISPLAY_H > ${UVC_DISPLAY_DIR}/wHeight
|
||||
echo 333333 > ${UVC_DISPLAY_DIR}/dwDefaultFrameInterval
|
||||
echo $((UVC_DISPLAY_W*UVC_DISPLAY_H*10)) > ${UVC_DISPLAY_DIR}/dwMinBitRate
|
||||
echo $((UVC_DISPLAY_W*UVC_DISPLAY_H*10)) > ${UVC_DISPLAY_DIR}/dwMaxBitRate
|
||||
echo -e "333333\n400000\n500000\n666666" > ${UVC_DISPLAY_DIR}/dwFrameInterval
|
||||
echo -ne \\x48\\x32\\x36\\x35\\x00\\x00\\x10\\x00\\x80\\x00\\x00\\xaa\\x00\\x38\\x9b\\x71 > ${USB_FUNCTIONS_DIR}/$UVC_GS/streaming/framebased/f2/guidFormat
|
||||
}
|
||||
|
||||
cdc_device_config()
|
||||
{
|
||||
mkdir ${USB_FUNCTIONS_DIR}/acm.g0
|
||||
CONFIG_STR=`cat /sys/kernel/config/usb_gadget/rockchip/configs/b.1/strings/0x409/configuration`
|
||||
STR=${CONFIG_STR}_acm
|
||||
echo $STR > ${USB_CONFIGS_DIR}/strings/0x409/configuration
|
||||
USB_CNT=`echo $STR | awk -F"_" '{print NF-1}'`
|
||||
let USB_CNT=USB_CNT+2
|
||||
if [ $UVC_MULTI = one ];then
|
||||
let USB_CNT=USB_CNT+1
|
||||
elif [ $UVC_MULTI = two ];then
|
||||
let USB_CNT=USB_CNT+2
|
||||
fi
|
||||
echo "acm on++++++ ${USB_CNT}"
|
||||
ln -s ${USB_FUNCTIONS_DIR}/acm.g0 ${USB_CONFIGS_DIR}/f${USB_CNT}
|
||||
}
|
||||
|
||||
uvc_device_config()
|
||||
{
|
||||
UVC_GS=$1
|
||||
UVC_NAME=$2
|
||||
mkdir ${USB_FUNCTIONS_DIR}/$UVC_GS
|
||||
echo $UVC_NAME > ${USB_FUNCTIONS_DIR}/$UVC_GS/device_name
|
||||
echo $UVC_NAME > ${USB_FUNCTIONS_DIR}/$UVC_GS/function_name
|
||||
if [ $UVC_MULTI = one ];then
|
||||
echo 2048 > ${USB_FUNCTIONS_DIR}/$UVC_GS/streaming_maxpacket
|
||||
elif [ $UVC_MULTI = two ];then
|
||||
echo 1024 > ${USB_FUNCTIONS_DIR}/$UVC_GS/streaming_maxpacket
|
||||
else
|
||||
echo 3072 > ${USB_FUNCTIONS_DIR}/$UVC_GS/streaming_maxpacket
|
||||
fi
|
||||
echo 2 > ${USB_FUNCTIONS_DIR}/$UVC_GS/uvc_num_request
|
||||
#echo 1 > /sys/kernel/config/usb_gadget/rockchip/functions/$UVC_GS/streaming_bulk
|
||||
|
||||
mkdir ${USB_FUNCTIONS_DIR}/$UVC_GS/control/header/h
|
||||
ln -s ${USB_FUNCTIONS_DIR}/$UVC_GS/control/header/h ${USB_FUNCTIONS_DIR}/$UVC_GS/control/class/fs/h
|
||||
ln -s ${USB_FUNCTIONS_DIR}/$UVC_GS/control/header/h ${USB_FUNCTIONS_DIR}/$UVC_GS/control/class/ss/h
|
||||
##YUYV support config
|
||||
mkdir /sys/kernel/config/usb_gadget/rockchip/functions/$UVC_GS/streaming/uncompressed/u
|
||||
configure_uvc_resolution_yuyv 320 240
|
||||
configure_uvc_resolution_yuyv 640 480
|
||||
configure_uvc_resolution_yuyv_720p 1280 720
|
||||
#configure_uvc_resolution_yuyv_1080p 1920 1080
|
||||
|
||||
##mjpeg support config
|
||||
mkdir ${USB_FUNCTIONS_DIR}/$UVC_GS/streaming/mjpeg/m
|
||||
configure_uvc_resolution_mjpeg 320 240
|
||||
configure_uvc_resolution_mjpeg 640 360
|
||||
configure_uvc_resolution_mjpeg 640 480
|
||||
configure_uvc_resolution_mjpeg 768 448
|
||||
configure_uvc_resolution_mjpeg 1280 720
|
||||
configure_uvc_resolution_mjpeg 1024 768
|
||||
configure_uvc_resolution_mjpeg 1920 1080
|
||||
configure_uvc_resolution_mjpeg 2048 1536
|
||||
# configure_uvc_resolution_mjpeg 2560 1440
|
||||
|
||||
## h.264 support config
|
||||
mkdir ${USB_FUNCTIONS_DIR}/$UVC_GS/streaming/framebased/f1
|
||||
configure_uvc_resolution_h264 640 480
|
||||
configure_uvc_resolution_h264 1280 720
|
||||
configure_uvc_resolution_h264 1920 1080
|
||||
configure_uvc_resolution_h264 2048 1536
|
||||
# configure_uvc_resolution_h264 2560 1440
|
||||
|
||||
## h.265 support config
|
||||
mkdir ${USB_FUNCTIONS_DIR}/$UVC_GS/streaming/framebased/f2
|
||||
configure_uvc_resolution_h265 640 480
|
||||
configure_uvc_resolution_h265 1280 720
|
||||
configure_uvc_resolution_h265 1920 1080
|
||||
configure_uvc_resolution_h265 2048 1536
|
||||
#configure_uvc_resolution_h265 2560 1440
|
||||
|
||||
mkdir /sys/kernel/config/usb_gadget/rockchip/functions/$UVC_GS/streaming/header/h
|
||||
ln -s ${USB_FUNCTIONS_DIR}/$UVC_GS/streaming/uncompressed/u ${USB_FUNCTIONS_DIR}/$UVC_GS/streaming/header/h/u
|
||||
ln -s ${USB_FUNCTIONS_DIR}/$UVC_GS/streaming/mjpeg/m ${USB_FUNCTIONS_DIR}/$UVC_GS/streaming/header/h/m
|
||||
ln -s ${USB_FUNCTIONS_DIR}/$UVC_GS/streaming/framebased/f1 ${USB_FUNCTIONS_DIR}/$UVC_GS/streaming/header/h/f1
|
||||
ln -s ${USB_FUNCTIONS_DIR}/$UVC_GS/streaming/framebased/f2 ${USB_FUNCTIONS_DIR}/$UVC_GS/streaming/header/h/f2
|
||||
ln -s ${USB_FUNCTIONS_DIR}/$UVC_GS/streaming/header/h ${USB_FUNCTIONS_DIR}/$UVC_GS/streaming/class/fs/h
|
||||
ln -s ${USB_FUNCTIONS_DIR}/$UVC_GS/streaming/header/h ${USB_FUNCTIONS_DIR}/$UVC_GS/streaming/class/hs/h
|
||||
ln -s ${USB_FUNCTIONS_DIR}/$UVC_GS/streaming/header/h ${USB_FUNCTIONS_DIR}/$UVC_GS/streaming/class/ss/h
|
||||
}
|
||||
uac1_device_config()
|
||||
{
|
||||
UAC=$1
|
||||
mkdir ${USB_FUNCTIONS_DIR}/${UAC}.gs0
|
||||
UAC_GS0=${USB_FUNCTIONS_DIR}/${UAC}.gs0
|
||||
echo 3 > ${UAC_GS0}/p_chmask
|
||||
echo 2 > ${UAC_GS0}/p_ssize
|
||||
echo 1 > ${UAC_GS0}/p_mute_present
|
||||
echo 1 > ${UAC_GS0}/p_volume_present
|
||||
echo -5120 > ${UAC_GS0}/p_volume_min #-20db min must > -96db
|
||||
echo 8000,16000,44100,48000 > ${UAC_GS0}/p_srate
|
||||
|
||||
echo 3 > ${UAC_GS0}/c_chmask
|
||||
echo 2 > ${UAC_GS0}/c_ssize
|
||||
echo 4 > ${UAC_GS0}/req_number
|
||||
echo 1 > ${UAC_GS0}/c_mute_present
|
||||
echo 1 > ${UAC_GS0}/c_volume_present
|
||||
echo -3200 > ${UAC_GS0}/c_volume_min #-12.5db
|
||||
echo 0 > ${UAC_GS0}/c_volume_max #0db
|
||||
echo 32 > ${UAC_GS0}/c_volume_res #0.125db
|
||||
echo 8000,16000,44100,48000 > ${UAC_GS0}/c_srate
|
||||
|
||||
if [ $UVC_MULTI = one ];then
|
||||
ln -s ${UAC_GS0} ${USB_CONFIGS_DIR}/f3
|
||||
elif [ $UVC_MULTI = two ];then
|
||||
ln -s ${UAC_GS0} ${USB_CONFIGS_DIR}/f4
|
||||
else
|
||||
ln -s ${UAC_GS0} ${USB_CONFIGS_DIR}/f2
|
||||
fi
|
||||
}
|
||||
uac2_device_config()
|
||||
{
|
||||
UAC=$1
|
||||
mkdir ${USB_FUNCTIONS_DIR}/${UAC}.gs0
|
||||
UAC_GS0=${USB_FUNCTIONS_DIR}/${UAC}.gs0
|
||||
echo 3 > ${UAC_GS0}/p_chmask
|
||||
echo 2 > ${UAC_GS0}/p_ssize
|
||||
echo 1 > ${UAC_GS0}/p_mute_present
|
||||
echo 1 > ${UAC_GS0}/p_volume_present
|
||||
echo -5120 > ${UAC_GS0}/p_volume_min #-20db min must > -96db
|
||||
echo 8000,16000,44100,48000 > ${UAC_GS0}/p_srate
|
||||
|
||||
echo 3 > ${UAC_GS0}/c_chmask
|
||||
echo 2 > ${UAC_GS0}/c_ssize
|
||||
echo 4 > ${UAC_GS0}/req_number
|
||||
echo 1 > ${UAC_GS0}/c_mute_present
|
||||
echo 1 > ${UAC_GS0}/c_volume_present
|
||||
echo -3200 > ${UAC_GS0}/c_volume_min #-12.5db
|
||||
echo 0 > ${UAC_GS0}/c_volume_max #0db
|
||||
echo 32 > ${UAC_GS0}/c_volume_res #0.125db
|
||||
echo 8000,16000,44100,48000 > ${UAC_GS0}/c_srate
|
||||
|
||||
if [ $UVC_MULTI = one ];then
|
||||
ln -s ${UAC_GS0} ${USB_CONFIGS_DIR}/f3
|
||||
elif [ $UVC_MULTI = two ];then
|
||||
ln -s ${UAC_GS0} ${USB_CONFIGS_DIR}/f4
|
||||
else
|
||||
ln -s ${UAC_GS0} ${USB_CONFIGS_DIR}/f2
|
||||
fi
|
||||
}
|
||||
pre_run_rndis()
|
||||
{
|
||||
RNDIS_STR="rndis"
|
||||
if ( echo $1 |grep -q "rndis" ); then
|
||||
#sleep 1
|
||||
IP_FILE=/data/uvc_xu_ip_save
|
||||
echo "config usb0 IP..."
|
||||
if [ -f $IP_FILE ]; then
|
||||
for line in `cat $IP_FILE`
|
||||
do
|
||||
echo "save ip is: $line"
|
||||
ifconfig usb0 $line
|
||||
done
|
||||
else
|
||||
ifconfig usb0 172.16.110.6
|
||||
fi
|
||||
ifconfig usb0 up
|
||||
fi
|
||||
}
|
||||
|
||||
insmod /oem/usr/ko/usb-common.ko
|
||||
insmod /oem/usr/ko/usbcore.ko
|
||||
insmod /oem/usr/ko/udc-core.ko
|
||||
insmod /oem/usr/ko/libcomposite.ko
|
||||
insmod /oem/usr/ko/usb_f_fs.ko
|
||||
|
||||
#UAC
|
||||
insmod /oem/usr/ko/u_audio.ko
|
||||
insmod /oem/usr/ko/usb_f_uac2.ko
|
||||
insmod /oem/usr/ko/usb_f_uac1.ko
|
||||
|
||||
#UVC
|
||||
insmod /oem/usr/ko/usb_f_uvc.ko
|
||||
|
||||
if [ "$CDC_ENABLE" = "YES" ];then
|
||||
insmod /oem/usr/ko/u_serial.ko
|
||||
insmod /oem/usr/ko/usb_f_acm.ko
|
||||
fi
|
||||
insmod /oem/usr/ko/phy-rockchip-inno-usb2.ko
|
||||
insmod /oem/usr/ko/dwc3-of-simple.ko
|
||||
insmod /oem/usr/ko/dwc3.ko
|
||||
|
||||
##main
|
||||
#init usb config
|
||||
ifconfig lo up # for adb ok
|
||||
/etc/init.d/S10udev stop
|
||||
umount /sys/kernel/config
|
||||
mkdir /dev/usb-ffs
|
||||
mount -t configfs none /sys/kernel/config
|
||||
mkdir -p /sys/kernel/config/usb_gadget/rockchip
|
||||
mkdir -p /sys/kernel/config/usb_gadget/rockchip/strings/0x409
|
||||
mkdir -p ${USB_CONFIGS_DIR}/strings/0x409
|
||||
echo 0x2207 > /sys/kernel/config/usb_gadget/rockchip/idVendor
|
||||
echo 0x0310 > /sys/kernel/config/usb_gadget/rockchip/bcdDevice
|
||||
echo 0x0200 > /sys/kernel/config/usb_gadget/rockchip/bcdUSB
|
||||
echo 239 > /sys/kernel/config/usb_gadget/rockchip/bDeviceClass
|
||||
echo 2 > /sys/kernel/config/usb_gadget/rockchip/bDeviceSubClass
|
||||
echo 1 > /sys/kernel/config/usb_gadget/rockchip/bDeviceProtocol
|
||||
SERIAL_NUM=`cat /proc/cpuinfo |grep Serial | awk -F ":" '{print $2}'`
|
||||
echo "serialnumber is $SERIAL_NUM"
|
||||
echo $SERIAL_NUM > /sys/kernel/config/usb_gadget/rockchip/strings/0x409/serialnumber
|
||||
echo "rockchip" > /sys/kernel/config/usb_gadget/rockchip/strings/0x409/manufacturer
|
||||
echo "UVC" > /sys/kernel/config/usb_gadget/rockchip/strings/0x409/product
|
||||
echo 0x1 > /sys/kernel/config/usb_gadget/rockchip/os_desc/b_vendor_code
|
||||
echo "MSFT100" > /sys/kernel/config/usb_gadget/rockchip/os_desc/qw_sign
|
||||
echo 500 > /sys/kernel/config/usb_gadget/rockchip/configs/b.1/MaxPower
|
||||
#ln -s /sys/kernel/config/usb_gadget/rockchip/configs/b.1 /sys/kernel/config/usb_gadget/rockchip/os_desc/b.1
|
||||
|
||||
#Windows computers will remember the device by default.
|
||||
#Changing the pid does not require re-uninstalling and loading the windows driver.
|
||||
echo 0x0016 > /sys/kernel/config/usb_gadget/rockchip/idProduct
|
||||
if [ $UVC_MULTI = one ];then
|
||||
echo 0x0018 > /sys/kernel/config/usb_gadget/rockchip/idProduct
|
||||
elif [ $UVC_MULTI = two ];then
|
||||
echo 0x001A > /sys/kernel/config/usb_gadget/rockchip/idProduct
|
||||
fi
|
||||
|
||||
#uvc config init
|
||||
uvc_device_config uvc.gs1 "UVC RGB"
|
||||
if [ $UVC_MULTI = one ];then
|
||||
uvc_device_config uvc.gs2 "RK UVC"
|
||||
elif [ $UVC_MULTI = two ];then
|
||||
uvc_device_config uvc.gs2 "RK UVC 1"
|
||||
uvc_device_config uvc.gs3 "RK UVC 2"
|
||||
fi
|
||||
##reset config,del default adb config
|
||||
if [ -e ${USB_CONFIGS_DIR}/ffs.adb ]; then
|
||||
#for rk1808 kernel 4.4
|
||||
rm -f ${USB_CONFIGS_DIR}/ffs.adb
|
||||
else
|
||||
ls ${USB_CONFIGS_DIR} | grep f[0-9] | xargs -I {} rm ${USB_CONFIGS_DIR}/{}
|
||||
fi
|
||||
|
||||
case "$1" in
|
||||
rndis)
|
||||
# config rndis
|
||||
mkdir /sys/kernel/config/usb_gadget/rockchip/functions/rndis.gs0
|
||||
echo "uvc_rndis" > ${USB_CONFIGS_DIR}/strings/0x409/configuration
|
||||
if [ $UVC_MULTI = one ];then
|
||||
ln -s ${USB_FUNCTIONS_DIR}/rndis.gs0 ${USB_CONFIGS_DIR}/f3
|
||||
elif [ $UVC_MULTI = two ];then
|
||||
ln -s ${USB_FUNCTIONS_DIR}/rndis.gs0 ${USB_CONFIGS_DIR}/f4
|
||||
else
|
||||
ln -s ${USB_FUNCTIONS_DIR}/rndis.gs0 ${USB_CONFIGS_DIR}/f2
|
||||
fi
|
||||
echo "config uvc and rndis..."
|
||||
;;
|
||||
uac1)
|
||||
uac1_device_config uac1
|
||||
echo "uvc_uac1" > ${USB_CONFIGS_DIR}/strings/0x409/configuration
|
||||
echo "config uvc and uac1..."
|
||||
;;
|
||||
uac2)
|
||||
uac2_device_config uac2
|
||||
echo "uvc_uac2" > ${USB_CONFIGS_DIR}/strings/0x409/configuration
|
||||
echo "config uvc and uac2..."
|
||||
;;
|
||||
uac1_rndis)
|
||||
#uac_device_config uac1
|
||||
mkdir /sys/kernel/config/usb_gadget/rockchip/functions/rndis.gs0
|
||||
if [ $UVC_MULTI = one ];then
|
||||
ln -s ${USB_FUNCTIONS_DIR}/rndis.gs0 ${USB_CONFIGS_DIR}/f4
|
||||
elif [ $UVC_MULTI = two ];then
|
||||
ln -s ${USB_FUNCTIONS_DIR}/rndis.gs0 ${USB_CONFIGS_DIR}/f5
|
||||
else
|
||||
ln -s ${USB_FUNCTIONS_DIR}/rndis.gs0 ${USB_CONFIGS_DIR}/f3
|
||||
fi
|
||||
uac1_device_config uac1
|
||||
echo "uvc_uac1_rndis" > ${USB_CONFIGS_DIR}/strings/0x409/configuration
|
||||
echo "config uvc and uac1 rndis..."
|
||||
;;
|
||||
uac2_rndis)
|
||||
#uac_device_config uac2
|
||||
mkdir /sys/kernel/config/usb_gadget/rockchip/functions/rndis.gs0
|
||||
if [ $UVC_MULTI = one ];then
|
||||
ln -s ${USB_FUNCTIONS_DIR}/rndis.gs0 ${USB_CONFIGS_DIR}/f4
|
||||
elif [ $UVC_MULTI = two ];then
|
||||
ln -s ${USB_FUNCTIONS_DIR}/rndis.gs0 ${USB_CONFIGS_DIR}/f5
|
||||
else
|
||||
ln -s ${USB_FUNCTIONS_DIR}/rndis.gs0 ${USB_CONFIGS_DIR}/f3
|
||||
fi
|
||||
uac2_device_config uac2
|
||||
echo "uvc_uac2_rndis" > ${USB_CONFIGS_DIR}/strings/0x409/configuration
|
||||
echo "config uvc and uac2 rndis..."
|
||||
;;
|
||||
*)
|
||||
echo "uvc" > ${USB_CONFIGS_DIR}/strings/0x409/configuration
|
||||
echo "config uvc ..."
|
||||
esac
|
||||
|
||||
ln -s ${USB_FUNCTIONS_DIR}/uvc.gs1 ${USB_CONFIGS_DIR}/f1
|
||||
if [ $UVC_MULTI = one ];then
|
||||
ln -s ${USB_FUNCTIONS_DIR}/uvc.gs2 ${USB_CONFIGS_DIR}/f2
|
||||
elif [ $UVC_MULTI = two ];then
|
||||
ln -s ${USB_FUNCTIONS_DIR}/uvc.gs2 ${USB_CONFIGS_DIR}/f2
|
||||
ln -s ${USB_FUNCTIONS_DIR}/uvc.gs3 ${USB_CONFIGS_DIR}/f3
|
||||
fi
|
||||
if [ "$CDC_ENABLE" = "YES" ];then
|
||||
cdc_device_config
|
||||
fi
|
||||
|
||||
UDC=`ls /sys/class/udc/| awk '{print $1}'`
|
||||
echo $UDC > /sys/kernel/config/usb_gadget/rockchip/UDC
|
||||
|
||||
if [ "$1" ]; then
|
||||
pre_run_rndis $1
|
||||
fi
|
||||
1095
project/app/uvc_app_tiny/uvc_app/uvc/cJSON/cJSON.c
Normal file
1095
project/app/uvc_app_tiny/uvc_app/uvc/cJSON/cJSON.c
Normal file
File diff suppressed because it is too large
Load Diff
171
project/app/uvc_app_tiny/uvc_app/uvc/cJSON/cJSON.h
Normal file
171
project/app/uvc_app_tiny/uvc_app/uvc/cJSON/cJSON.h
Normal file
@@ -0,0 +1,171 @@
|
||||
/*
|
||||
Copyright (c) 2009 Dave Gamble
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
#ifndef cJSON__h
|
||||
#define cJSON__h
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#include <stddef.h>
|
||||
|
||||
/* cJSON Types: */
|
||||
#define cJSON_False 0
|
||||
#define cJSON_True 1
|
||||
#define cJSON_NULL 2
|
||||
#define cJSON_Number 3
|
||||
#define cJSON_String 4
|
||||
#define cJSON_Array 5
|
||||
#define cJSON_Object 6
|
||||
|
||||
#define cJSON_IsReference 256
|
||||
|
||||
/* The cJSON structure: */
|
||||
typedef struct cJSON {
|
||||
struct cJSON *next,
|
||||
*prev; /* next/prev allow you to walk array/object chains. Alternatively,
|
||||
use GetArraySize/GetArrayItem/GetObjectItem */
|
||||
struct cJSON
|
||||
*child; /* An array or object item will have a child pointer pointing
|
||||
to a chain of the items in the array/object. */
|
||||
|
||||
int type; /* The type of the item, as above. */
|
||||
|
||||
char *valuestring; /* The item's string, if type==cJSON_String */
|
||||
int valueint; /* The item's number, if type==cJSON_Number */
|
||||
double valuedouble; /* The item's number, if type==cJSON_Number */
|
||||
|
||||
char *string; /* The item's name string, if this item is the child of, or is
|
||||
in the list of subitems of an object. */
|
||||
} cJSON;
|
||||
|
||||
typedef struct cJSON_Hooks {
|
||||
void *(*malloc_fn)(size_t sz);
|
||||
void (*free_fn)(void *ptr);
|
||||
} cJSON_Hooks;
|
||||
|
||||
/* Supply malloc, realloc and free functions to cJSON */
|
||||
extern void cJSON_InitHooks(cJSON_Hooks *hooks);
|
||||
|
||||
/* Supply a block of JSON, and this returns a cJSON object you can interrogate.
|
||||
* Call cJSON_Delete when finished. */
|
||||
extern cJSON *cJSON_Parse(const char *value);
|
||||
/* Render a cJSON entity to text for transfer/storage. Free the char* when
|
||||
* finished. */
|
||||
extern char *cJSON_Print(cJSON *item);
|
||||
/* Render a cJSON entity to text for transfer/storage without any formatting.
|
||||
* Free the char* when finished. */
|
||||
extern char *cJSON_PrintUnformatted(cJSON *item);
|
||||
/* Delete a cJSON entity and all subentities. */
|
||||
extern void cJSON_Delete(cJSON *c);
|
||||
|
||||
/* Returns the number of items in an array (or object). */
|
||||
extern int cJSON_GetArraySize(cJSON *array);
|
||||
/* Retrieve item number "item" from array "array". Returns NULL if unsuccessful.
|
||||
*/
|
||||
extern cJSON *cJSON_GetArrayItem(cJSON *array, int item);
|
||||
/* Get item "string" from object. Case insensitive. */
|
||||
extern cJSON *cJSON_GetObjectItem(cJSON *object, const char *string);
|
||||
|
||||
/* For analysing failed parses. This returns a pointer to the parse error.
|
||||
* You'll probably need to look a few chars back to make sense of it. Defined
|
||||
* when cJSON_Parse() returns 0. 0 when cJSON_Parse() succeeds. */
|
||||
extern const char *cJSON_GetErrorPtr(void);
|
||||
|
||||
/* These calls create a cJSON item of the appropriate type. */
|
||||
extern cJSON *cJSON_CreateNull(void);
|
||||
extern cJSON *cJSON_CreateTrue(void);
|
||||
extern cJSON *cJSON_CreateFalse(void);
|
||||
extern cJSON *cJSON_CreateBool(int b);
|
||||
extern cJSON *cJSON_CreateNumber(double num);
|
||||
extern cJSON *cJSON_CreateString(const char *string);
|
||||
extern cJSON *cJSON_CreateArray(void);
|
||||
extern cJSON *cJSON_CreateObject(void);
|
||||
|
||||
/* These utilities create an Array of count items. */
|
||||
extern cJSON *cJSON_CreateIntArray(const int *numbers, int count);
|
||||
extern cJSON *cJSON_CreateFloatArray(const float *numbers, int count);
|
||||
extern cJSON *cJSON_CreateDoubleArray(const double *numbers, int count);
|
||||
extern cJSON *cJSON_CreateStringArray(const char **strings, int count);
|
||||
|
||||
/* Append item to the specified array/object. */
|
||||
extern void cJSON_AddItemToArray(cJSON *array, cJSON *item);
|
||||
extern void cJSON_AddItemToObject(cJSON *object, const char *string,
|
||||
cJSON *item);
|
||||
/* Append reference to item to the specified array/object. Use this when you
|
||||
* want to add an existing cJSON to a new cJSON, but don't want to corrupt your
|
||||
* existing cJSON. */
|
||||
extern void cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item);
|
||||
extern void cJSON_AddItemReferenceToObject(cJSON *object, const char *string,
|
||||
cJSON *item);
|
||||
|
||||
/* Remove/Detatch items from Arrays/Objects. */
|
||||
extern cJSON *cJSON_DetachItemFromArray(cJSON *array, int which);
|
||||
extern void cJSON_DeleteItemFromArray(cJSON *array, int which);
|
||||
extern cJSON *cJSON_DetachItemFromObject(cJSON *object, const char *string);
|
||||
extern void cJSON_DeleteItemFromObject(cJSON *object, const char *string);
|
||||
|
||||
/* Update array items. */
|
||||
extern void cJSON_ReplaceItemInArray(cJSON *array, int which, cJSON *newitem);
|
||||
extern void cJSON_ReplaceItemInObject(cJSON *object, const char *string,
|
||||
cJSON *newitem);
|
||||
|
||||
/* Duplicate a cJSON item */
|
||||
extern cJSON *cJSON_Duplicate(cJSON *item, int recurse);
|
||||
/* Duplicate will create a new, identical cJSON item to the one you pass, in new
|
||||
memory that will
|
||||
need to be released. With recurse!=0, it will duplicate any children connected
|
||||
to the item.
|
||||
The item->next and ->prev pointers are always zero on return from Duplicate. */
|
||||
|
||||
/* ParseWithOpts allows you to require (and check) that the JSON is null
|
||||
* terminated, and to retrieve the pointer to the final byte parsed. */
|
||||
extern cJSON *cJSON_ParseWithOpts(const char *value,
|
||||
const char **return_parse_end,
|
||||
int require_null_terminated);
|
||||
|
||||
extern void cJSON_Minify(char *json);
|
||||
|
||||
/* Macros for creating things quickly. */
|
||||
#define cJSON_AddNullToObject(object, name) \
|
||||
cJSON_AddItemToObject(object, name, cJSON_CreateNull())
|
||||
#define cJSON_AddTrueToObject(object, name) \
|
||||
cJSON_AddItemToObject(object, name, cJSON_CreateTrue())
|
||||
#define cJSON_AddFalseToObject(object, name) \
|
||||
cJSON_AddItemToObject(object, name, cJSON_CreateFalse())
|
||||
#define cJSON_AddBoolToObject(object, name, b) \
|
||||
cJSON_AddItemToObject(object, name, cJSON_CreateBool(b))
|
||||
#define cJSON_AddNumberToObject(object, name, n) \
|
||||
cJSON_AddItemToObject(object, name, cJSON_CreateNumber(n))
|
||||
#define cJSON_AddStringToObject(object, name, s) \
|
||||
cJSON_AddItemToObject(object, name, cJSON_CreateString(s))
|
||||
|
||||
/* When assigning an integer value, it needs to be propagated to valuedouble
|
||||
* too. */
|
||||
#define cJSON_SetIntValue(object, val) \
|
||||
((object) ? (object)->valueint = (object)->valuedouble = (val) : (val))
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
103
project/app/uvc_app_tiny/uvc_app/uvc/camera_control.c
Normal file
103
project/app/uvc_app_tiny/uvc_app/uvc/camera_control.c
Normal file
@@ -0,0 +1,103 @@
|
||||
/*
|
||||
* Copyright (C) 2019 Rockchip Electronics Co., Ltd.
|
||||
*
|
||||
* This software is available to you under a choice of one of two
|
||||
* licenses. You may choose to be licensed under the terms of the GNU
|
||||
* General Public License (GPL), available from the file
|
||||
* COPYING in the main directory of this source tree, or the
|
||||
* OpenIB.org BSD license below:
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or
|
||||
* without modification, are permitted provided that the following
|
||||
* conditions are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer.
|
||||
*
|
||||
* - Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "camera_control.h"
|
||||
#include "isp.h"
|
||||
#include "param.h"
|
||||
#include "uvc_log.h"
|
||||
|
||||
extern char *rkuvc_iq_file_path_;
|
||||
|
||||
struct Camera_Stream {};
|
||||
|
||||
void video_record_signal(struct Camera_Stream *stream) {}
|
||||
|
||||
static void camera_stop(struct Camera_Stream *stream) {
|
||||
LOG_INFO("%s \n", __func__);
|
||||
}
|
||||
|
||||
static void *uvc_camera(void *arg) {}
|
||||
|
||||
int camera_control_start(int id, int width, int height, int fps, int format,
|
||||
int eptz) {
|
||||
if (rk_param_get_int("video.source:enable_aiq", 1))
|
||||
camera_control_set_rate(id, fps);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void camera_control_stop(int id) {
|
||||
LOG_INFO("%s: id:%d\n", __func__, id);
|
||||
int ret = 0;
|
||||
if (rk_param_get_int("video.source:enable_aiq", 1))
|
||||
ret |= rk_isp_deinit(id);
|
||||
if (rk_param_get_int("video.source:enable_aiq", 1))
|
||||
ret |= rk_isp_init(id, rkuvc_iq_file_path_);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void camera_control_init() {
|
||||
LOG_INFO("%s \n", __func__);
|
||||
if (rk_param_get_int("video.source:enable_aiq", 1)) {
|
||||
rk_isp_init(0, rkuvc_iq_file_path_);
|
||||
rk_isp_set_frame_rate(0, rk_param_get_int("isp.0.adjustment:fps", 30));
|
||||
if (rk_param_get_int("video.source:enable_2uvc", 0))
|
||||
rk_isp_init(1, rkuvc_iq_file_path_);
|
||||
} else {
|
||||
LOG_INFO("%s disabled aiq \n", __func__);
|
||||
}
|
||||
}
|
||||
|
||||
void camera_control_set_rate(int index, int rate) {
|
||||
LOG_INFO("camera index:%d rate:%d \n", index, rate);
|
||||
if (rk_param_get_int("video.source:enable_aiq", 1)) {
|
||||
rk_isp_set_frame_rate(index, rate);
|
||||
}
|
||||
}
|
||||
void camera_control_set_zoom(int val) { LOG_INFO("set_zoom:%d\n", val); }
|
||||
|
||||
void camera_control_set_pan(int val) { LOG_INFO("set_pan:%d\n", val); }
|
||||
|
||||
void camera_control_set_tilt(int val) { LOG_INFO("set_tilt:%d\n", val); }
|
||||
|
||||
void camera_control_set_roll(int val) {
|
||||
LOG_INFO("set_roll:%d\n", val);
|
||||
// todo
|
||||
}
|
||||
|
||||
void camera_control_deinit() {
|
||||
LOG_INFO("%s \n", __func__);
|
||||
if (rk_param_get_int("video.source:enable_aiq", 1)) {
|
||||
rk_isp_deinit(0);
|
||||
if (rk_param_get_int("video.source:enable_2uvc", 0))
|
||||
rk_isp_deinit(1);
|
||||
}
|
||||
}
|
||||
58
project/app/uvc_app_tiny/uvc_app/uvc/camera_control.h
Executable file
58
project/app/uvc_app_tiny/uvc_app/uvc/camera_control.h
Executable file
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Copyright (C) 2019 Rockchip Electronics Co., Ltd.
|
||||
*
|
||||
* This software is available to you under a choice of one of two
|
||||
* licenses. You may choose to be licensed under the terms of the GNU
|
||||
* General Public License (GPL), available from the file
|
||||
* COPYING in the main directory of this source tree, or the
|
||||
* OpenIB.org BSD license below:
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or
|
||||
* without modification, are permitted provided that the following
|
||||
* conditions are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer.
|
||||
*
|
||||
* - Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef __CARERA_CONTROL_H__
|
||||
#define __CARERA_CONTROL_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "isp.h"
|
||||
#include "param.h"
|
||||
#include <unistd.h>
|
||||
|
||||
void camera_control_init();
|
||||
void camera_control_deinit();
|
||||
int camera_control_start(int id, int width, int height, int fps, int format,
|
||||
int eptz);
|
||||
void camera_control_stop(int id);
|
||||
void camera_control_set_zoom(int val);
|
||||
void camera_control_set_pan(int val);
|
||||
void camera_control_set_tilt(int val);
|
||||
void camera_control_set_roll(int val);
|
||||
void camera_control_set_rate(int index, int rate);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
255
project/app/uvc_app_tiny/uvc_app/uvc/camera_pu_control.c
Normal file
255
project/app/uvc_app_tiny/uvc_app/uvc/camera_pu_control.c
Normal file
@@ -0,0 +1,255 @@
|
||||
/*
|
||||
* Copyright (C) 2019 Rockchip Electronics Co., Ltd.
|
||||
*
|
||||
* This software is available to you under a choice of one of two
|
||||
* licenses. You may choose to be licensed under the terms of the GNU
|
||||
* General Public License (GPL), available from the file
|
||||
* COPYING in the main directory of this source tree, or the
|
||||
* OpenIB.org BSD license below:
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or
|
||||
* without modification, are permitted provided that the following
|
||||
* conditions are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer.
|
||||
*
|
||||
* - Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
#include "camera_pu_control.h"
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/select.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <pthread.h>
|
||||
#include <sched.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "uvc_log.h"
|
||||
#include <pthread.h>
|
||||
|
||||
int video_record_set_brightness(int brightness) {
|
||||
rk_isp_set_brightness(0, brightness);
|
||||
LOG_INFO("%s \n", __func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int video_record_set_contrast(int contrast) {
|
||||
rk_isp_set_contrast(0, contrast);
|
||||
LOG_INFO("%s \n", __func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int video_record_set_hue(int hue) {
|
||||
rk_isp_set_hue(0, hue);
|
||||
LOG_INFO("%s \n", __func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int video_record_set_staturation(int staturation) {
|
||||
rk_isp_set_saturation(0, staturation);
|
||||
LOG_INFO("%s \n", __func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int video_record_set_sharpness(int sharpness) {
|
||||
rk_isp_set_sharpness(0, sharpness);
|
||||
LOG_INFO("%s \n", __func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int video_record_set_fps(int fixfps) {
|
||||
rk_isp_set_frame_rate(0, fixfps);
|
||||
LOG_INFO("%s \n", __func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int video_record_set_gamma(int gamma) {
|
||||
LOG_INFO("%s \n", __func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int video_record_set_white_balance_temperature(int balance) {
|
||||
//[2800,6500]
|
||||
LOG_INFO("WhiteBalance color temperature is %d \n", balance);
|
||||
rk_isp_set_white_blance_ct(0, balance);
|
||||
LOG_INFO("%s \n", __func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int video_record_set_white_balance_temperature_auto(int balance) {
|
||||
if (balance == 1)
|
||||
rk_isp_set_white_blance_style(0, "autoWhiteBalance");
|
||||
else
|
||||
rk_isp_set_white_blance_style(0, "manualWhiteBalance");
|
||||
LOG_INFO("%s \n", __func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int video_record_set_gain(int gain) {
|
||||
rk_isp_set_exposure_gain(0, gain);
|
||||
LOG_INFO("%s \n", __func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int video_record_set_hue_auto(int hue_auto) {
|
||||
rk_isp_set_hue_mode(0, hue_auto);
|
||||
LOG_INFO("%s \n", __func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int video_record_set_frequency_mode(int mode) {
|
||||
if (mode == 1)
|
||||
rk_isp_set_power_line_frequency_mode(0, "PAL(50HZ)");
|
||||
else
|
||||
rk_isp_set_power_line_frequency_mode(0, "NTSC(60HZ)");
|
||||
LOG_INFO("%s \n", __func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int video_record_set_roll_mode(int mode) {
|
||||
switch (mode) {
|
||||
case 0: {
|
||||
rk_isp_set_image_flip(0, "close");
|
||||
break;
|
||||
}
|
||||
case 1: {
|
||||
rk_isp_set_image_flip(0, "flip");
|
||||
break;
|
||||
}
|
||||
case 2: {
|
||||
rk_isp_set_image_flip(0, "centrosymmetric");
|
||||
break;
|
||||
}
|
||||
case 3: {
|
||||
rk_isp_set_image_flip(0, "mirror");
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
rk_isp_set_image_flip(0, "close");
|
||||
break;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int video_record_set_exposure_time(int time) {
|
||||
char str[8];
|
||||
sprintf(str, "%f", ((float)time / 10000));
|
||||
rk_isp_set_exposure_time(0, str);
|
||||
LOG_INFO("%s \n", __func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int video_record_set_ae_mode(int mode) {
|
||||
if (mode == 2) {
|
||||
LOG_DEBUG("AE:set auto mode!!\n");
|
||||
rk_isp_set_exposure_mode(0, "auto");
|
||||
} else {
|
||||
LOG_DEBUG("AE:set manual mode!!\n");
|
||||
rk_isp_set_exposure_mode(0, "manual");
|
||||
}
|
||||
LOG_INFO("%s \n", __func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void camera_pu_control_init(int type, int def, int min, int max) {
|
||||
LOG_DEBUG("%s!\n", __func__);
|
||||
}
|
||||
|
||||
int camera_pu_control_get(int type, int def) {
|
||||
LOG_DEBUG("%s!\n", __func__);
|
||||
return def;
|
||||
}
|
||||
|
||||
int check_ispserver_work() {
|
||||
if (rk_param_get_int("video.source:enable_aiq", 1))
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
int camera_pu_control_set(int type, int value) {
|
||||
LOG_DEBUG("%s! type is %d,value is %d\n", __func__, type, value);
|
||||
if (!check_ispserver_work()) {
|
||||
LOG_INFO("check ispserver is no ready,pu set fail!\n");
|
||||
return 0;
|
||||
}
|
||||
switch (type) {
|
||||
case UVC_PU_BRIGHTNESS_CONTROL:
|
||||
video_record_set_brightness(value);
|
||||
break;
|
||||
case UVC_PU_CONTRAST_CONTROL:
|
||||
video_record_set_contrast(value);
|
||||
break;
|
||||
case UVC_PU_HUE_CONTROL:
|
||||
video_record_set_hue(value);
|
||||
break;
|
||||
case UVC_PU_SATURATION_CONTROL:
|
||||
video_record_set_staturation(value);
|
||||
break;
|
||||
case UVC_PU_SHARPNESS_CONTROL:
|
||||
video_record_set_sharpness(value);
|
||||
break;
|
||||
case UVC_PU_GAMMA_CONTROL:
|
||||
// video_record_set_gamma(value);
|
||||
break;
|
||||
case UVC_PU_WHITE_BALANCE_TEMPERATURE_CONTROL:
|
||||
video_record_set_white_balance_temperature(value);
|
||||
break;
|
||||
case UVC_PU_WHITE_BALANCE_TEMPERATURE_AUTO_CONTROL:
|
||||
video_record_set_white_balance_temperature_auto(value);
|
||||
break;
|
||||
case UVC_PU_GAIN_CONTROL:
|
||||
video_record_set_gain(value);
|
||||
break;
|
||||
case UVC_PU_HUE_AUTO_CONTROL:
|
||||
video_record_set_hue_auto(value);
|
||||
break;
|
||||
case UVC_PU_POWER_LINE_FREQUENCY_CONTROL:
|
||||
video_record_set_frequency_mode(value);
|
||||
break;
|
||||
case UVC_PU_FPS_CONTROL:
|
||||
video_record_set_fps(value);
|
||||
break;
|
||||
case UVC_PU_ROLL_CONTROL:
|
||||
video_record_set_roll_mode(value);
|
||||
break;
|
||||
case UVC_PU_EXPOSURE_TIME_CONTROL:
|
||||
video_record_set_exposure_time(value);
|
||||
break;
|
||||
case UVC_PU_AE_MODE_CONTROL:
|
||||
video_record_set_ae_mode(value);
|
||||
break;
|
||||
default:
|
||||
LOG_DEBUG("====unknow pu cmd.\n");
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int camera_pu_control_check(int deviceid) {
|
||||
LOG_DEBUG("%s!\n", __func__);
|
||||
return 0;
|
||||
}
|
||||
44
project/app/uvc_app_tiny/uvc_app/uvc/camera_pu_control.h
Executable file
44
project/app/uvc_app_tiny/uvc_app/uvc/camera_pu_control.h
Executable file
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright (C) 2019 Rockchip Electronics Co., Ltd.
|
||||
*
|
||||
* This software is available to you under a choice of one of two
|
||||
* licenses. You may choose to be licensed under the terms of the GNU
|
||||
* General Public License (GPL), available from the file
|
||||
* COPYING in the main directory of this source tree, or the
|
||||
* OpenIB.org BSD license below:
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or
|
||||
* without modification, are permitted provided that the following
|
||||
* conditions are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer.
|
||||
*
|
||||
* - Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef __CARERA_PU_CONTROL_H__
|
||||
#define __CARERA_PU_CONTROL_H__
|
||||
#include "camera_control.h"
|
||||
#include <uvc-gadget.h>
|
||||
|
||||
void camera_pu_control_init(int type, int def, int min, int max);
|
||||
int camera_pu_control_get(int type, int def);
|
||||
int camera_pu_control_set(int type, int value);
|
||||
int camera_pu_control_check(int deviceid);
|
||||
int check_ispserver_work();
|
||||
|
||||
#endif
|
||||
237
project/app/uvc_app_tiny/uvc_app/uvc/osd.c
Executable file
237
project/app/uvc_app_tiny/uvc_app/uvc/osd.c
Executable file
@@ -0,0 +1,237 @@
|
||||
/*
|
||||
* Copyright (C) 2019 Rockchip Electronics Co., Ltd.
|
||||
*
|
||||
* This software is available to you under a choice of one of two
|
||||
* licenses. You may choose to be licensed under the terms of the GNU
|
||||
* General Public License (GPL), available from the file
|
||||
* COPYING in the main directory of this source tree, or the
|
||||
* OpenIB.org BSD license below:
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or
|
||||
* without modification, are permitted provided that the following
|
||||
* conditions are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer.
|
||||
*
|
||||
* - Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "osd.h"
|
||||
#include "osd_rockchip_logo.h"
|
||||
#include "uvc_log.h"
|
||||
#include "uvc_mpi_config.h"
|
||||
#include "uvc_video.h"
|
||||
|
||||
static RK_S32 osd_create(RGN_HANDLE handle, MPP_CHN_S *mppChn, RK_U32 layer,
|
||||
RECT_S *rect) {
|
||||
RK_S32 s32Ret = RK_SUCCESS;
|
||||
RGN_ATTR_S stRgnAttr;
|
||||
RGN_CHN_ATTR_S stRgnChnAttr;
|
||||
if (mppChn->enModId == RK_ID_VPSS)
|
||||
stRgnAttr.enType = OVERLAY_EX_RGN;
|
||||
else
|
||||
stRgnAttr.enType = OVERLAY_RGN;
|
||||
stRgnAttr.unAttr.stOverlay.enPixelFmt = RK_FMT_RGBA8888;
|
||||
stRgnAttr.unAttr.stOverlay.stSize.u32Width = rect->u32Width;
|
||||
stRgnAttr.unAttr.stOverlay.stSize.u32Height = rect->u32Height;
|
||||
stRgnAttr.unAttr.stOverlay.u32ClutNum = 0;
|
||||
|
||||
s32Ret = RK_MPI_RGN_Create(handle, &stRgnAttr);
|
||||
if (RK_SUCCESS != s32Ret) {
|
||||
LOG_ERROR("RK_MPI_RGN_Create (%d) failed with %#x!\n", handle, s32Ret);
|
||||
RK_MPI_RGN_Destroy(handle);
|
||||
return s32Ret;
|
||||
}
|
||||
memset(&stRgnChnAttr, 0, sizeof(stRgnChnAttr));
|
||||
stRgnChnAttr.bShow = RK_TRUE;
|
||||
stRgnChnAttr.enType = stRgnAttr.enType;
|
||||
stRgnChnAttr.unChnAttr.stOverlayChn.stPoint.s32X = rect->s32X;
|
||||
stRgnChnAttr.unChnAttr.stOverlayChn.stPoint.s32Y = rect->s32Y;
|
||||
stRgnChnAttr.unChnAttr.stOverlayChn.u32BgAlpha = 0;
|
||||
stRgnChnAttr.unChnAttr.stOverlayChn.u32FgAlpha = 255;
|
||||
stRgnChnAttr.unChnAttr.stOverlayChn.u32Layer = layer;
|
||||
stRgnChnAttr.unChnAttr.stOverlayChn.stQpInfo.bEnable = RK_FALSE;
|
||||
|
||||
s32Ret = RK_MPI_RGN_AttachToChn(handle, mppChn, &stRgnChnAttr);
|
||||
if (RK_SUCCESS != s32Ret) {
|
||||
LOG_ERROR("RK_MPI_RGN_AttachToChn (%d) failed with %#x!\n", handle, s32Ret);
|
||||
}
|
||||
|
||||
return s32Ret;
|
||||
}
|
||||
|
||||
static RK_S32 osd_destroy(RGN_HANDLE handle, MPP_CHN_S *mppChn) {
|
||||
RK_S32 s32Ret = RK_SUCCESS;
|
||||
|
||||
s32Ret = RK_MPI_RGN_DetachFromChn(handle, mppChn);
|
||||
if (RK_SUCCESS != s32Ret) {
|
||||
LOG_ERROR("RK_MPI_RGN_DetachFrmChn (%d) failed with %#x!\n", handle,
|
||||
s32Ret);
|
||||
}
|
||||
s32Ret = RK_MPI_RGN_Destroy(handle);
|
||||
if (RK_SUCCESS != s32Ret) {
|
||||
LOG_ERROR("RK_MPI_RGN_Destroy [%d] failed with %#x\n", handle, s32Ret);
|
||||
}
|
||||
|
||||
return s32Ret;
|
||||
}
|
||||
|
||||
static RK_S32 osd_show_or_hide(RGN_HANDLE handle, const MPP_CHN_S *mppChn,
|
||||
RK_BOOL bShow) {
|
||||
RGN_CHN_ATTR_S stChnAttr;
|
||||
RK_S32 s32Ret = RK_SUCCESS;
|
||||
|
||||
if (RK_NULL == mppChn) {
|
||||
LOG_ERROR("input parameter is null. it is invaild!\n");
|
||||
return RK_FAILURE;
|
||||
}
|
||||
|
||||
s32Ret = RK_MPI_RGN_GetDisplayAttr(handle, mppChn, &stChnAttr);
|
||||
if (RK_SUCCESS != s32Ret) {
|
||||
LOG_ERROR("RK_MPI_RGN_GetDisplayAttr (%d)) failed with %#x!\n", handle,
|
||||
s32Ret);
|
||||
return RK_FAILURE;
|
||||
}
|
||||
|
||||
stChnAttr.bShow = bShow;
|
||||
|
||||
s32Ret = RK_MPI_RGN_SetDisplayAttr(handle, mppChn, &stChnAttr);
|
||||
if (RK_SUCCESS != s32Ret) {
|
||||
LOG_ERROR("RK_MPI_RGN_SetDisplayAttr (%d)) failed with %#x!\n", handle,
|
||||
s32Ret);
|
||||
return RK_FAILURE;
|
||||
}
|
||||
|
||||
return RK_SUCCESS;
|
||||
}
|
||||
|
||||
static RK_S32 osd_test_show_rockchip_logo(RGN_HANDLE handle) {
|
||||
RK_S32 s32Ret = RK_SUCCESS;
|
||||
RGN_CANVAS_INFO_S stCanvasInfo;
|
||||
RK_U32 *data;
|
||||
FILE *p;
|
||||
|
||||
LOG_ERROR("test show rockchip logo\n");
|
||||
memset(&stCanvasInfo, 0, sizeof(RGN_CANVAS_INFO_S));
|
||||
|
||||
s32Ret = RK_MPI_RGN_GetCanvasInfo(handle, &stCanvasInfo);
|
||||
if (s32Ret != RK_SUCCESS) {
|
||||
LOG_ERROR("RK_MPI_RGN_GetCanvasInfo failed with %#x!\n", s32Ret);
|
||||
}
|
||||
|
||||
data = (RK_U32 *)stCanvasInfo.u64VirAddr;
|
||||
p = fopen("/data/rockchip-logo-320-96.rgba", "r");
|
||||
if (p) {
|
||||
fread(data, 4, stCanvasInfo.u32VirWidth * stCanvasInfo.u32VirHeight, p);
|
||||
fclose(p);
|
||||
} else {
|
||||
// no osd file, copy array to rgn
|
||||
#if 1 // test rgba data to set 0
|
||||
memcpy(data, u32BGRA8888RKLOGO,
|
||||
stCanvasInfo.u32VirWidth * stCanvasInfo.u32VirHeight * 4);
|
||||
#else // test rgba data
|
||||
for (RK_U32 i = 0; i < stCanvasInfo.u32VirWidth * stCanvasInfo.u32VirHeight;
|
||||
i++) {
|
||||
// RK_FMT_RGBA8888
|
||||
if (i < stCanvasInfo.u32VirWidth * stCanvasInfo.u32VirHeight / 4)
|
||||
data[i] = 0xff000000; // black
|
||||
else if (i < stCanvasInfo.u32VirWidth * stCanvasInfo.u32VirHeight / 2)
|
||||
data[i] = 0xffff0000; // blue
|
||||
else if (i < stCanvasInfo.u32VirWidth * stCanvasInfo.u32VirHeight / 4 * 3)
|
||||
data[i] = 0xff00ff00; // green
|
||||
else
|
||||
data[i] = 0xff0000ff; // red
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
s32Ret = RK_MPI_RGN_UpdateCanvas(handle);
|
||||
if (s32Ret != RK_SUCCESS) {
|
||||
LOG_ERROR("RK_MPI_RGN_UpdateCanvas failed with %#x!\n", s32Ret);
|
||||
}
|
||||
|
||||
return s32Ret;
|
||||
}
|
||||
|
||||
static RK_S32 osd_test_init(UVC_MPI_CFG *uvcCfg) {
|
||||
RGN_HANDLE handle = 0;
|
||||
MPP_CHN_S mppChn;
|
||||
RK_U32 layer = 0;
|
||||
RECT_S rect;
|
||||
RK_S32 s32Ret;
|
||||
|
||||
if (uvcCfg->uvc_cfg.fcc == V4L2_PIX_FMT_YUYV ||
|
||||
uvcCfg->osd_cfg.force_use_vpss) {
|
||||
mppChn.enModId = RK_ID_VPSS;
|
||||
mppChn.s32DevId = uvcCfg->vpss_cfg[MPI_VPSS_CHANNEL_TYPE_UVC].group_id;
|
||||
mppChn.s32ChnId = uvcCfg->vpss_cfg[MPI_VPSS_CHANNEL_TYPE_UVC].channel_id;
|
||||
} else {
|
||||
mppChn.enModId = RK_ID_VENC;
|
||||
mppChn.s32DevId = 0;
|
||||
mppChn.s32ChnId = uvcCfg->venc_cfg.common_cfg.channel_id;
|
||||
}
|
||||
rect.s32X = 100;
|
||||
rect.s32Y = 200;
|
||||
rect.u32Width = 320; // need align 16
|
||||
rect.u32Height = 96; // need align 16
|
||||
|
||||
s32Ret = osd_create(handle, &mppChn, layer, &rect);
|
||||
s32Ret = osd_test_show_rockchip_logo(handle);
|
||||
// defalut is show, if want hide this osd, refer to below setting
|
||||
// osd_show_or_hide(handle, &mppChn, RK_FALSE);
|
||||
|
||||
return s32Ret;
|
||||
}
|
||||
|
||||
static RK_S32 osd_test_deinit(UVC_MPI_CFG *uvcCfg) {
|
||||
RK_S32 s32Ret;
|
||||
MPP_CHN_S mppChn;
|
||||
RGN_HANDLE handle = 0;
|
||||
|
||||
if (uvcCfg->uvc_cfg.fcc == V4L2_PIX_FMT_YUYV ||
|
||||
uvcCfg->osd_cfg.force_use_vpss) {
|
||||
mppChn.enModId = RK_ID_VPSS;
|
||||
mppChn.s32DevId = uvcCfg->vpss_cfg[MPI_VPSS_CHANNEL_TYPE_UVC].group_id;
|
||||
mppChn.s32ChnId = uvcCfg->vpss_cfg[MPI_VPSS_CHANNEL_TYPE_UVC].channel_id;
|
||||
} else {
|
||||
mppChn.enModId = RK_ID_VENC;
|
||||
mppChn.s32DevId = 0;
|
||||
mppChn.s32ChnId = uvcCfg->venc_cfg.common_cfg.channel_id;
|
||||
}
|
||||
|
||||
return osd_destroy(handle, &mppChn);
|
||||
}
|
||||
|
||||
RK_S32 osd_start(UVC_MPI_CFG *uvcCfg) {
|
||||
RK_S32 s32Ret;
|
||||
|
||||
// now just for test run
|
||||
s32Ret = osd_test_init(uvcCfg);
|
||||
|
||||
// TODO(user) you can comment the code above, and implement it yourself
|
||||
return s32Ret;
|
||||
}
|
||||
|
||||
RK_S32 osd_stop(UVC_MPI_CFG *uvcCfg) {
|
||||
RK_S32 s32Ret;
|
||||
|
||||
// now just for test run
|
||||
s32Ret = osd_test_deinit(uvcCfg);
|
||||
|
||||
// TODO(user) you can comment the code above, and implement it yourself
|
||||
return s32Ret;
|
||||
}
|
||||
50
project/app/uvc_app_tiny/uvc_app/uvc/osd.h
Executable file
50
project/app/uvc_app_tiny/uvc_app/uvc/osd.h
Executable file
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright (C) 2019 Rockchip Electronics Co., Ltd.
|
||||
*
|
||||
* This software is available to you under a choice of one of two
|
||||
* licenses. You may choose to be licensed under the terms of the GNU
|
||||
* General Public License (GPL), available from the file
|
||||
* COPYING in the main directory of this source tree, or the
|
||||
* OpenIB.org BSD license below:
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or
|
||||
* without modification, are permitted provided that the following
|
||||
* conditions are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer.
|
||||
*
|
||||
* - Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef __OSD_H__
|
||||
#define __OSD_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#include "rk_common.h"
|
||||
#include "rk_mpi_rgn.h"
|
||||
#include "uvc_mpi_config.h"
|
||||
|
||||
RK_S32 osd_start(UVC_MPI_CFG *uvcCfg);
|
||||
RK_S32 osd_stop(UVC_MPI_CFG *uvcCfg);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
5167
project/app/uvc_app_tiny/uvc_app/uvc/osd_rockchip_logo.h
Executable file
5167
project/app/uvc_app_tiny/uvc_app/uvc/osd_rockchip_logo.h
Executable file
File diff suppressed because it is too large
Load Diff
BIN
project/app/uvc_app_tiny/uvc_app/uvc/rockchip-logo-320-96.rgba
Executable file
BIN
project/app/uvc_app_tiny/uvc_app/uvc/rockchip-logo-320-96.rgba
Executable file
Binary file not shown.
161
project/app/uvc_app_tiny/uvc_app/uvc/uevent.c
Normal file
161
project/app/uvc_app_tiny/uvc_app/uvc/uevent.c
Normal file
@@ -0,0 +1,161 @@
|
||||
/*
|
||||
* Copyright (C) 2019 Rockchip Electronics Co., Ltd.
|
||||
*
|
||||
* This software is available to you under a choice of one of two
|
||||
* licenses. You may choose to be licensed under the terms of the GNU
|
||||
* General Public License (GPL), available from the file
|
||||
* COPYING in the main directory of this source tree, or the
|
||||
* OpenIB.org BSD license below:
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or
|
||||
* without modification, are permitted provided that the following
|
||||
* conditions are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer.
|
||||
*
|
||||
* - Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <pthread.h>
|
||||
#include <signal.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <sys/prctl.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <linux/netlink.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
#include "uevent.h"
|
||||
#include "uvc_control.h"
|
||||
#include "uvc_log.h"
|
||||
|
||||
extern int app_quit;
|
||||
|
||||
static void handle_uvc_event(struct uevent *uevent) {
|
||||
if (strcmp(uevent->subsystem, "android_usb"))
|
||||
return;
|
||||
|
||||
if (!strcmp(uevent->usb_state, "DISCONNECTED")) {
|
||||
LOG_INFO("udc disconnected\n");
|
||||
app_quit = 1;
|
||||
} else if (!strcmp(uevent->usb_state, "CONNECTED")) {
|
||||
LOG_INFO("udc connected\n");
|
||||
} else if (!strcmp(uevent->usb_state, "CONFIGURED")) {
|
||||
LOG_INFO("udc configured\n");
|
||||
} else {
|
||||
LOG_INFO("unknow usb event\n");
|
||||
}
|
||||
}
|
||||
|
||||
static void parse_event(const char *msg, struct uevent *uevent) {
|
||||
uevent->action = "";
|
||||
uevent->path = "";
|
||||
uevent->subsystem = "";
|
||||
uevent->usb_state = "";
|
||||
uevent->device_name = "";
|
||||
|
||||
while (*msg) {
|
||||
if (!strncmp(msg, "ACTION=", 7)) {
|
||||
msg += 7;
|
||||
uevent->action = msg;
|
||||
} else if (!strncmp(msg, "DEVPATH=", 8)) {
|
||||
msg += 8;
|
||||
uevent->path = msg;
|
||||
} else if (!strncmp(msg, "SUBSYSTEM=", 10)) {
|
||||
msg += 10;
|
||||
uevent->subsystem = msg;
|
||||
} else if (!strncmp(msg, "USB_STATE=", 10)) {
|
||||
msg += 10;
|
||||
uevent->usb_state = msg;
|
||||
} else if (!strncmp(msg, "DEVNAME=", 8)) {
|
||||
msg += 8;
|
||||
uevent->device_name = msg;
|
||||
}
|
||||
/* advance to after the next \0 */
|
||||
while (*msg++)
|
||||
;
|
||||
}
|
||||
|
||||
LOG_DEBUG("event { '%s', '%s', '%s', '%s', '%s' }\n", uevent->action,
|
||||
uevent->path, uevent->subsystem, uevent->usb_state,
|
||||
uevent->device_name);
|
||||
handle_uvc_event(uevent);
|
||||
}
|
||||
|
||||
static void *event_monitor_thread(void *arg) {
|
||||
int sockfd;
|
||||
int i, j, len;
|
||||
char buf[1024 + 2];
|
||||
struct iovec iov;
|
||||
struct msghdr msg;
|
||||
struct sockaddr_nl sa;
|
||||
struct uevent uevent;
|
||||
uint32_t flags = *(uint32_t *)arg;
|
||||
|
||||
prctl(PR_SET_NAME, "event_monitor", 0, 0, 0);
|
||||
|
||||
memset(&sa, 0, sizeof(sa));
|
||||
sa.nl_family = AF_NETLINK;
|
||||
sa.nl_groups = NETLINK_KOBJECT_UEVENT;
|
||||
sa.nl_pid = 0;
|
||||
memset(&msg, 0, sizeof(msg));
|
||||
iov.iov_base = (void *)buf;
|
||||
iov.iov_len = sizeof(buf);
|
||||
msg.msg_name = (void *)&sa;
|
||||
msg.msg_namelen = sizeof(sa);
|
||||
msg.msg_iov = &iov;
|
||||
msg.msg_iovlen = 1;
|
||||
|
||||
sockfd = socket(AF_NETLINK, SOCK_RAW, NETLINK_KOBJECT_UEVENT);
|
||||
if (sockfd == -1) {
|
||||
LOG_ERROR("socket creating failed:%s\n", strerror(errno));
|
||||
goto err_event_monitor;
|
||||
}
|
||||
|
||||
if (bind(sockfd, (struct sockaddr *)&sa, sizeof(sa)) == -1) {
|
||||
LOG_ERROR("bind error:%s\n", strerror(errno));
|
||||
goto err_event_monitor;
|
||||
}
|
||||
|
||||
while (1) {
|
||||
len = recvmsg(sockfd, &msg, 0);
|
||||
if (len < 0) {
|
||||
LOG_ERROR("receive error\n");
|
||||
} else if (len < 32 || len > sizeof(buf)) {
|
||||
LOG_INFO("invalid message");
|
||||
} else {
|
||||
buf[len] = '\0';
|
||||
buf[len + 1] = '\0';
|
||||
parse_event(buf, &uevent);
|
||||
}
|
||||
}
|
||||
|
||||
err_event_monitor:
|
||||
pthread_detach(pthread_self());
|
||||
pthread_exit(NULL);
|
||||
}
|
||||
|
||||
int uevent_monitor_run(uint32_t flags) {
|
||||
pthread_t tid;
|
||||
|
||||
return pthread_create(&tid, NULL, event_monitor_thread, &flags);
|
||||
}
|
||||
50
project/app/uvc_app_tiny/uvc_app/uvc/uevent.h
Normal file
50
project/app/uvc_app_tiny/uvc_app/uvc/uevent.h
Normal file
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright (C) 2019 Rockchip Electronics Co., Ltd.
|
||||
*
|
||||
* This software is available to you under a choice of one of two
|
||||
* licenses. You may choose to be licensed under the terms of the GNU
|
||||
* General Public License (GPL), available from the file
|
||||
* COPYING in the main directory of this source tree, or the
|
||||
* OpenIB.org BSD license below:
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or
|
||||
* without modification, are permitted provided that the following
|
||||
* conditions are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer.
|
||||
*
|
||||
* - Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef __UEVENT_H__
|
||||
#define __UEVENT_H__
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
|
||||
struct uevent {
|
||||
const char *action;
|
||||
const char *path;
|
||||
const char *subsystem;
|
||||
const char *usb_state;
|
||||
const char *device_name;
|
||||
};
|
||||
|
||||
int uevent_monitor_run(uint32_t flags);
|
||||
|
||||
#endif
|
||||
3942
project/app/uvc_app_tiny/uvc_app/uvc/uvc-gadget.c
Normal file
3942
project/app/uvc_app_tiny/uvc_app/uvc/uvc-gadget.c
Normal file
File diff suppressed because it is too large
Load Diff
253
project/app/uvc_app_tiny/uvc_app/uvc/uvc-gadget.h
Executable file
253
project/app/uvc_app_tiny/uvc_app/uvc/uvc-gadget.h
Executable file
@@ -0,0 +1,253 @@
|
||||
/*
|
||||
* Copyright (C) 2019 Rockchip Electronics Co., Ltd.
|
||||
*
|
||||
* This software is available to you under a choice of one of two
|
||||
* licenses. You may choose to be licensed under the terms of the GNU
|
||||
* General Public License (GPL), available from the file
|
||||
* COPYING in the main directory of this source tree, or the
|
||||
* OpenIB.org BSD license below:
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or
|
||||
* without modification, are permitted provided that the following
|
||||
* conditions are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer.
|
||||
*
|
||||
* - Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef _UVC_GADGET_H_
|
||||
#define _UVC_GADGET_H_
|
||||
|
||||
#include <linux/ioctl.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/usb/ch9.h>
|
||||
|
||||
#define UVC_EVENT_FIRST (V4L2_EVENT_PRIVATE_START + 0)
|
||||
#define UVC_EVENT_CONNECT (V4L2_EVENT_PRIVATE_START + 0)
|
||||
#define UVC_EVENT_DISCONNECT (V4L2_EVENT_PRIVATE_START + 1)
|
||||
#define UVC_EVENT_STREAMON (V4L2_EVENT_PRIVATE_START + 2)
|
||||
#define UVC_EVENT_STREAMOFF (V4L2_EVENT_PRIVATE_START + 3)
|
||||
#define UVC_EVENT_SETUP (V4L2_EVENT_PRIVATE_START + 4)
|
||||
#define UVC_EVENT_DATA (V4L2_EVENT_PRIVATE_START + 5)
|
||||
#define UVC_EVENT_SUSPEND (V4L2_EVENT_PRIVATE_START + 6)
|
||||
#define UVC_EVENT_RESUME (V4L2_EVENT_PRIVATE_START + 7)
|
||||
#define UVC_EVENT_LAST (V4L2_EVENT_PRIVATE_START + 8)
|
||||
|
||||
#define MAX_UVC_REQUEST_DATA_LENGTH 60
|
||||
|
||||
#define UVC_CTRL_INTERFACE_ID 0x00
|
||||
#define UVC_CTRL_CAMERA_TERMINAL_ID 0x01
|
||||
#define UVC_CTRL_PROCESSING_UNIT_ID 0x02
|
||||
#define UVC_CTRL_EXTENSION_UNIT_ID 0x03
|
||||
#define UVC_CTRL_OUTPUT_TERMINAL_ID 0x04
|
||||
#define UVC_CTRL_XU_UNIT_ID 0x06
|
||||
|
||||
struct uvc_request_data {
|
||||
__s32 length;
|
||||
__u8 data[60];
|
||||
};
|
||||
|
||||
struct uvc_event {
|
||||
union {
|
||||
enum usb_device_speed speed;
|
||||
struct usb_ctrlrequest req;
|
||||
struct uvc_request_data data;
|
||||
};
|
||||
};
|
||||
|
||||
#define UVCIOC_SEND_RESPONSE _IOW('U', 1, struct uvc_request_data)
|
||||
|
||||
#define UVC_INTF_CONTROL 0
|
||||
#define UVC_INTF_STREAMING 1
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "uvc_control.h"
|
||||
#include "uvc_video.h"
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "uvc_configfs.h"
|
||||
#include <linux/usb/ch9.h>
|
||||
#include <linux/usb/video.h>
|
||||
#include <linux/videodev2.h>
|
||||
|
||||
#define V4L2_PIX_FMT_H265 \
|
||||
v4l2_fourcc('H', '2', '6', '5') /* H265 with start codes */
|
||||
#define UVC_PU_FPS_CONTROL 0xff
|
||||
#define UVC_PU_ROLL_CONTROL 0xfd
|
||||
#define UVC_PU_EXPOSURE_TIME_CONTROL 0xfc
|
||||
#define UVC_PU_AE_MODE_CONTROL 0xfb
|
||||
|
||||
/* ---------------------------------------------------------------------------
|
||||
* Generic stuff
|
||||
*/
|
||||
|
||||
enum XuCmd {
|
||||
CMD_TOOLS_CTRL_1 = 0x01,
|
||||
CMD_GET_CAMERA_VERSION,
|
||||
CMD_SHUTDOWN_CAMERA,
|
||||
CMD_RESET_CAMERA,
|
||||
CMD_SET_MOTOR_RATE = 0x06,
|
||||
CMD_SET_MOTOR_BY_STEPS = 0x07,
|
||||
CMD_SET_MOTOR_BY_USER = 0x08,
|
||||
CMD_STOP_MOTOR_BY_USER = 0x09,
|
||||
CMD_SET_CAMERA_IP = 0x0a,
|
||||
CMD_SET_H265 = 0x0b,
|
||||
CMD_MAX_NUM = CMD_SET_H265,
|
||||
};
|
||||
|
||||
/* IO methods supported */
|
||||
enum io_method {
|
||||
IO_METHOD_MMAP,
|
||||
IO_METHOD_USERPTR,
|
||||
IO_METHOD_DMA_BUFF,
|
||||
};
|
||||
|
||||
#define UVC_IO_METHOD_MMAP 0
|
||||
#define UVC_IO_METHOD_USERPTR 1
|
||||
#define UVC_IO_METHOD_DMA_BUFF 2
|
||||
|
||||
#define USE_MPI_BUF_TO_UVC_VIDEO_BUFFER 1
|
||||
#define UVC_IO_METHOD UVC_IO_METHOD_USERPTR
|
||||
|
||||
/* Buffer representing one video frame */
|
||||
struct buffer {
|
||||
struct v4l2_buffer buf;
|
||||
void *start;
|
||||
size_t length;
|
||||
};
|
||||
|
||||
struct v4l2_buffer_info {
|
||||
// struct uvc_buffer *uvc_buf;
|
||||
void *frame; // mb
|
||||
int fd;
|
||||
int index;
|
||||
unsigned long userptr;
|
||||
};
|
||||
|
||||
enum USB_STATE {
|
||||
USB_STATE_INIT,
|
||||
USB_STATE_FIRST_CMD,
|
||||
USB_STATE_FIRST_GET_READY,
|
||||
USB_STATE_FIRST_GET_OK,
|
||||
USB_STATE_FIRST_SEND_OK,
|
||||
USB_STATE_NORMAL_RUN
|
||||
};
|
||||
|
||||
/* Represents a UVC based video output device */
|
||||
struct uvc_device {
|
||||
int video_id;
|
||||
/* uvc device specific */
|
||||
int uvc_fd;
|
||||
int is_streaming;
|
||||
int run_standalone;
|
||||
char *uvc_devname;
|
||||
struct uvc_function_config *fc;
|
||||
int suspend;
|
||||
int need_bypass;
|
||||
/* uvc control request specific */
|
||||
struct uvc_streaming_control probe;
|
||||
struct uvc_streaming_control commit;
|
||||
int control;
|
||||
struct uvc_request_data request_error_code;
|
||||
unsigned int brightness_val;
|
||||
unsigned short contrast_val;
|
||||
int hue_val;
|
||||
unsigned int saturation_val;
|
||||
unsigned int sharpness_val;
|
||||
unsigned int gamma_val;
|
||||
unsigned int white_balance_temperature_val;
|
||||
unsigned int white_balance_temperature_auto_val;
|
||||
unsigned int gain_val;
|
||||
unsigned int hue_auto_val;
|
||||
unsigned int zoom_val;
|
||||
int pan_val;
|
||||
int tilt_val;
|
||||
short roll_val;
|
||||
short iris_val;
|
||||
int exposure_time_val;
|
||||
unsigned char ae_mode_val;
|
||||
unsigned char power_line_frequency_val;
|
||||
unsigned char ex_tool_ctrl1[4];
|
||||
unsigned char ex_sn_data[MAX_UVC_REQUEST_DATA_LENGTH];
|
||||
unsigned char ex_ip_data[MAX_UVC_REQUEST_DATA_LENGTH]; //
|
||||
unsigned char ex_date_data[MAX_UVC_REQUEST_DATA_LENGTH];
|
||||
unsigned int eptz_flag;
|
||||
unsigned int xu_h265;
|
||||
|
||||
/* uvc buffer specific */
|
||||
enum io_method io;
|
||||
struct buffer *mem;
|
||||
struct buffer *dummy_buf;
|
||||
int nbufs;
|
||||
unsigned int fcc;
|
||||
unsigned int width;
|
||||
unsigned int height;
|
||||
unsigned int fps;
|
||||
|
||||
unsigned int bulk;
|
||||
uint8_t color;
|
||||
unsigned int imgsize;
|
||||
void *imgdata;
|
||||
|
||||
/* USB speed specific */
|
||||
int mult;
|
||||
int burst;
|
||||
int maxpkt;
|
||||
enum usb_device_speed speed;
|
||||
|
||||
/* uvc specific flags */
|
||||
int first_buffer_queued;
|
||||
int uvc_shutdown_requested;
|
||||
|
||||
/* uvc buffer queue and dequeue counters */
|
||||
unsigned long long int qbuf_count;
|
||||
unsigned long long int dqbuf_count;
|
||||
|
||||
/* v4l2 device hook */
|
||||
struct v4l2_device *vdev;
|
||||
uint8_t cs;
|
||||
uint8_t entity_id;
|
||||
struct v4l2_buffer ubuf;
|
||||
|
||||
struct v4l2_buffer_info *vbuf_info;
|
||||
int drop_count;
|
||||
int try_count;
|
||||
enum USB_STATE usb_state;
|
||||
unsigned int first_usb_get_ready_pts;
|
||||
unsigned int first_usb_get_ok_pts;
|
||||
unsigned int first_usb_send_ok_pts;
|
||||
unsigned int first_cmd_pts;
|
||||
unsigned int stream_on_pts;
|
||||
int get_buf_count;
|
||||
};
|
||||
|
||||
int uvc_gadget_main(struct uvc_function_config *fc);
|
||||
int uvc_video_reqbufs(struct uvc_device *dev, int nbufs);
|
||||
int uvc_video_stream(struct uvc_device *dev, int enable);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _UVC_GADGET_H_ */
|
||||
693
project/app/uvc_app_tiny/uvc_app/uvc/uvc_configfs.c
Normal file
693
project/app/uvc_app_tiny/uvc_app/uvc/uvc_configfs.c
Normal file
@@ -0,0 +1,693 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
/*
|
||||
* ConfigFS Gadget device handling
|
||||
*
|
||||
* Copyright (C) 2020 Rockchip Electronics Co., Ltd.
|
||||
*
|
||||
*/
|
||||
|
||||
/* To provide basename and asprintf from the GNU library. */
|
||||
#define _GNU_SOURCE
|
||||
|
||||
#include <dirent.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <glob.h>
|
||||
#include <linux/videodev2.h>
|
||||
#include <pthread.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "uvc_configfs.h"
|
||||
|
||||
#define V4L2_PIX_FMT_H265 \
|
||||
v4l2_fourcc('H', '2', '6', '5') /* H265 with start codes */
|
||||
|
||||
#define UVC_FUNCTION_NAME "uvc*"
|
||||
|
||||
#define UVC_GUID_FORMAT_MJPEG \
|
||||
{ \
|
||||
'M', 'J', 'P', 'G', 0x00, 0x00, 0x10, 0x00, 0x80, 0x00, 0x00, 0xaa, 0x00, \
|
||||
0x38, 0x9b, 0x71 \
|
||||
}
|
||||
#define UVC_GUID_FORMAT_YUY2 \
|
||||
{ \
|
||||
'Y', 'U', 'Y', '2', 0x00, 0x00, 0x10, 0x00, 0x80, 0x00, 0x00, 0xaa, 0x00, \
|
||||
0x38, 0x9b, 0x71 \
|
||||
}
|
||||
#define UVC_GUID_FORMAT_NV12 \
|
||||
{ \
|
||||
'N', 'V', '1', '2', 0x00, 0x00, 0x10, 0x00, 0x80, 0x00, 0x00, 0xaa, 0x00, \
|
||||
0x38, 0x9b, 0x71 \
|
||||
}
|
||||
#define UVC_GUID_FORMAT_H264 \
|
||||
{ \
|
||||
'H', '2', '6', '4', 0x00, 0x00, 0x10, 0x00, 0x80, 0x00, 0x00, 0xaa, 0x00, \
|
||||
0x38, 0x9b, 0x71 \
|
||||
}
|
||||
#define UVC_GUID_FORMAT_H265 \
|
||||
{ \
|
||||
'H', '2', '6', '5', 0x00, 0x00, 0x10, 0x00, 0x80, 0x00, 0x00, 0xaa, 0x00, \
|
||||
0x38, 0x9b, 0x71 \
|
||||
}
|
||||
|
||||
#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
|
||||
|
||||
struct uvc_function_format_info {
|
||||
uint8_t guid[16];
|
||||
uint32_t fcc;
|
||||
};
|
||||
|
||||
static struct uvc_function_format_info uvc_formats[] = {
|
||||
{
|
||||
.guid = UVC_GUID_FORMAT_YUY2, .fcc = V4L2_PIX_FMT_YUYV,
|
||||
},
|
||||
{
|
||||
.guid = UVC_GUID_FORMAT_MJPEG, .fcc = V4L2_PIX_FMT_MJPEG,
|
||||
},
|
||||
{
|
||||
.guid = UVC_GUID_FORMAT_H264, .fcc = V4L2_PIX_FMT_H264,
|
||||
},
|
||||
{
|
||||
.guid = UVC_GUID_FORMAT_H265, .fcc = V4L2_PIX_FMT_H265,
|
||||
},
|
||||
{
|
||||
.guid = UVC_GUID_FORMAT_NV12, .fcc = V4L2_PIX_FMT_NV12,
|
||||
}};
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
* Path handling and support
|
||||
*/
|
||||
static char *path_join(const char *dirname, const char *name) {
|
||||
char *path;
|
||||
int ret;
|
||||
|
||||
ret = asprintf(&path, "%s/%s", dirname, name);
|
||||
|
||||
/*
|
||||
* asprintf returns -1 on allocation or other errors, leaving 'path'
|
||||
* undefined. We shouldn't even call free(path) here. We want to return
|
||||
* NULL on error, so we must manually set it.
|
||||
*/
|
||||
if (ret < 0)
|
||||
path = NULL;
|
||||
|
||||
return path;
|
||||
}
|
||||
|
||||
static char *path_glob_index_match(const char *g, unsigned int index) {
|
||||
glob_t globbuf;
|
||||
char *match = NULL;
|
||||
|
||||
glob(g, 0, NULL, &globbuf);
|
||||
|
||||
if (globbuf.gl_pathc > index)
|
||||
match = strdup(globbuf.gl_pathv[index]);
|
||||
|
||||
globfree(&globbuf);
|
||||
|
||||
return match;
|
||||
}
|
||||
|
||||
/*
|
||||
* Find and return the full path of the first directory entry that satisfies
|
||||
* the match function.
|
||||
*/
|
||||
static char *dir_first_match(const char *dir,
|
||||
int (*match)(const struct dirent *)) {
|
||||
struct dirent **entries;
|
||||
unsigned int i;
|
||||
int n_entries;
|
||||
char *path;
|
||||
|
||||
n_entries = scandir(dir, &entries, match, alphasort);
|
||||
if (n_entries < 0)
|
||||
return NULL;
|
||||
|
||||
if (n_entries == 0) {
|
||||
free(entries);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
path = path_join(dir, entries[0]->d_name);
|
||||
|
||||
for (i = 0; i < (unsigned int)n_entries; ++i)
|
||||
free(entries[i]);
|
||||
|
||||
free(entries);
|
||||
|
||||
return path;
|
||||
}
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
* Attribute handling
|
||||
*/
|
||||
static int attribute_read(const char *path, const char *file, void *buf,
|
||||
unsigned int len) {
|
||||
char *f;
|
||||
int ret;
|
||||
int fd;
|
||||
|
||||
f = path_join(path, file);
|
||||
if (!f)
|
||||
return -ENOMEM;
|
||||
|
||||
fd = open(f, O_RDONLY);
|
||||
free(f);
|
||||
if (fd == -1) {
|
||||
printf("Failed to open attribute %s: %s\n", file, strerror(errno));
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
ret = read(fd, buf, len);
|
||||
close(fd);
|
||||
|
||||
if (ret < 0) {
|
||||
printf("Failed to read attribute %s: %s\n", file, strerror(errno));
|
||||
return -ENODATA;
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
static int attribute_read_uint(const char *path, const char *file,
|
||||
unsigned int *val) {
|
||||
char buf[11] = {0};
|
||||
char *endptr;
|
||||
int ret;
|
||||
|
||||
ret = attribute_read(path, file, buf, sizeof(buf) - 1);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
buf[ret] = '\0';
|
||||
errno = 0;
|
||||
|
||||
/* base 0: Autodetect hex, octal, decimal. */
|
||||
*val = strtoul(buf, &endptr, 0);
|
||||
if (errno)
|
||||
return -errno;
|
||||
|
||||
if (endptr == buf)
|
||||
return -ENODATA;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static char *attribute_read_str(const char *path, const char *file) {
|
||||
char buf[1024] = {0};
|
||||
char *p;
|
||||
int ret;
|
||||
|
||||
ret = attribute_read(path, file, buf, sizeof(buf) - 1);
|
||||
if (ret < 0)
|
||||
return NULL;
|
||||
|
||||
buf[ret] = '\0';
|
||||
|
||||
p = strrchr(buf, '\n');
|
||||
if (p == NULL)
|
||||
return NULL;
|
||||
if (p != buf)
|
||||
*p = '\0';
|
||||
|
||||
return strdup(buf);
|
||||
}
|
||||
|
||||
static char *configfs_find_uvc_function(unsigned int index) {
|
||||
const char *target = UVC_FUNCTION_NAME;
|
||||
const char *format;
|
||||
char *func_path;
|
||||
char *path;
|
||||
int ret;
|
||||
|
||||
format = "%s/usb_gadget/*/functions/%s";
|
||||
ret = asprintf(&path, format, "/sys/kernel/config", target);
|
||||
if (!ret)
|
||||
return NULL;
|
||||
|
||||
func_path = path_glob_index_match(path, index);
|
||||
|
||||
free(path);
|
||||
|
||||
return func_path;
|
||||
}
|
||||
|
||||
static int udc_find_video_device(const char *udc, const char *function) {
|
||||
char *vpath;
|
||||
char *video = NULL;
|
||||
glob_t globbuf;
|
||||
int video_id = -1;
|
||||
unsigned int i;
|
||||
int ret;
|
||||
|
||||
ret = asprintf(&vpath, "/sys/class/udc/%s/device/gadget/video4linux/video*",
|
||||
udc ? udc : "*");
|
||||
if (!ret)
|
||||
return -1;
|
||||
|
||||
glob(vpath, 0, NULL, &globbuf);
|
||||
free(vpath);
|
||||
|
||||
for (i = 0; i < globbuf.gl_pathc; ++i) {
|
||||
char *config;
|
||||
bool match;
|
||||
|
||||
/* Match on the first if no search string. */
|
||||
if (!function)
|
||||
break;
|
||||
|
||||
config = attribute_read_str(globbuf.gl_pathv[i], "function_name");
|
||||
match = strcmp(function, config) == 0;
|
||||
free(config);
|
||||
if (match)
|
||||
break;
|
||||
}
|
||||
|
||||
if (i < globbuf.gl_pathc) {
|
||||
const char *v = basename(globbuf.gl_pathv[i]);
|
||||
video = path_join("/dev", v);
|
||||
if (sscanf(video, "/dev/video%d", &video_id) != 1)
|
||||
video_id = -1;
|
||||
free(video);
|
||||
}
|
||||
|
||||
globfree(&globbuf);
|
||||
|
||||
return video_id;
|
||||
}
|
||||
|
||||
/*
|
||||
* configfs_free_uvc_function - Free a uvc_function_config object
|
||||
* @fc: The uvc_function_config to be freed
|
||||
*
|
||||
* Free the given @fc function previously allocated by a call to
|
||||
* configfs_parse_uvc_function().
|
||||
*/
|
||||
void configfs_free_uvc_function(struct uvc_function_config *fc) {
|
||||
unsigned int i, j;
|
||||
|
||||
free(fc->udc);
|
||||
free(fc->dev_name);
|
||||
|
||||
for (i = 0; i < fc->streaming.num_formats; ++i) {
|
||||
struct uvc_function_config_format *format = &fc->streaming.formats[i];
|
||||
|
||||
for (j = 0; j < format->num_frames; ++j) {
|
||||
struct uvc_function_config_frame *frame = &format->frames[j];
|
||||
|
||||
free(frame->intervals);
|
||||
}
|
||||
free(format->frames);
|
||||
}
|
||||
free(fc->streaming.formats);
|
||||
free(fc);
|
||||
}
|
||||
|
||||
#define configfs_parse_child(parent, child, cfg, parse) \
|
||||
({ \
|
||||
char *__path; \
|
||||
int __ret; \
|
||||
\
|
||||
__path = path_join((parent), (child)); \
|
||||
if (__path) { \
|
||||
__ret = parse(__path, (cfg)); \
|
||||
free(__path); \
|
||||
} else { \
|
||||
__ret = -ENOMEM; \
|
||||
} \
|
||||
\
|
||||
__ret; \
|
||||
})
|
||||
|
||||
static int configfs_parse_interface(const char *path,
|
||||
struct uvc_function_config_interface *cfg) {
|
||||
int ret;
|
||||
|
||||
ret = attribute_read_uint(path, "bInterfaceNumber", &cfg->bInterfaceNumber);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int configfs_parse_control(const char *path,
|
||||
struct uvc_function_config_control *cfg) {
|
||||
int ret;
|
||||
|
||||
ret = configfs_parse_interface(path, &cfg->intf);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
configfs_parse_streaming_frame(const char *path,
|
||||
struct uvc_function_config_frame *frame) {
|
||||
char *intervals;
|
||||
char *p;
|
||||
int ret = 0;
|
||||
|
||||
ret = ret ?: attribute_read_uint(path, "bFrameIndex", &frame->index);
|
||||
ret = ret ?: attribute_read_uint(path, "wWidth", &frame->width);
|
||||
ret = ret ?: attribute_read_uint(path, "wHeight", &frame->height);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
intervals = attribute_read_str(path, "dwFrameInterval");
|
||||
if (!intervals)
|
||||
return -EINVAL;
|
||||
|
||||
for (p = intervals; *p;) {
|
||||
unsigned int interval;
|
||||
unsigned int *mem;
|
||||
char *endp;
|
||||
size_t size;
|
||||
|
||||
interval = strtoul(p, &endp, 10);
|
||||
if (*endp != '\0' && *endp != '\n') {
|
||||
ret = -EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
p = *endp ? endp + 1 : endp;
|
||||
|
||||
size = sizeof *frame->intervals * (frame->num_intervals + 1);
|
||||
mem = realloc(frame->intervals, size);
|
||||
if (!mem) {
|
||||
ret = -ENOMEM;
|
||||
break;
|
||||
}
|
||||
frame->intervals = mem;
|
||||
frame->intervals[frame->num_intervals++] = interval;
|
||||
}
|
||||
free(intervals);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int frame_filter(const struct dirent *ent) {
|
||||
/* Accept all directories but "." and "..". */
|
||||
if (ent->d_type != DT_DIR)
|
||||
return 0;
|
||||
if (!strcmp(ent->d_name, "."))
|
||||
return 0;
|
||||
if (!strcmp(ent->d_name, ".."))
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int frame_compare(const void *a, const void *b) {
|
||||
const struct uvc_function_config_frame *fa = a;
|
||||
const struct uvc_function_config_frame *fb = b;
|
||||
|
||||
if (fa->index < fb->index)
|
||||
return -1;
|
||||
else if (fa->index == fb->index)
|
||||
return 0;
|
||||
else
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
configfs_parse_streaming_format(const char *path,
|
||||
struct uvc_function_config_format *format) {
|
||||
struct dirent **entries;
|
||||
char link_target[1024] = {0};
|
||||
char *segment;
|
||||
unsigned int i;
|
||||
int n_entries;
|
||||
int ret;
|
||||
|
||||
ret = attribute_read_uint(path, "bFormatIndex", &format->index);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = readlink(path, link_target, sizeof(link_target) - 1);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
link_target[ret] = '\0';
|
||||
|
||||
/*
|
||||
* Extract the second-to-last path component of the link target,
|
||||
* which contains the format descriptor type name as exposed by
|
||||
* the UVC function driver.
|
||||
*/
|
||||
segment = strrchr(link_target, '/');
|
||||
if (!segment)
|
||||
return -EINVAL;
|
||||
*segment = '\0';
|
||||
segment = strrchr(link_target, '/');
|
||||
if (!segment)
|
||||
return -EINVAL;
|
||||
segment++;
|
||||
if (!strcmp(segment, "framebased")) {
|
||||
ret =
|
||||
attribute_read(path, "guidFormat", format->guid, sizeof(format->guid));
|
||||
} else if (!strcmp(segment, "mjpeg")) {
|
||||
static const uint8_t guid[16] = UVC_GUID_FORMAT_MJPEG;
|
||||
memcpy(format->guid, guid, 16);
|
||||
} else if (!strcmp(segment, "uncompressed")) {
|
||||
ret =
|
||||
attribute_read(path, "guidFormat", format->guid, sizeof(format->guid));
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
} else {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(uvc_formats); ++i) {
|
||||
if (!memcmp(uvc_formats[i].guid, format->guid, 16)) {
|
||||
format->fcc = uvc_formats[i].fcc;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Find all entries corresponding to a frame and parse them. */
|
||||
n_entries = scandir(path, &entries, frame_filter, alphasort);
|
||||
if (n_entries < 0)
|
||||
return -errno;
|
||||
|
||||
if (n_entries == 0) {
|
||||
free(entries);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
format->num_frames = n_entries;
|
||||
format->frames = calloc(sizeof *format->frames, format->num_frames);
|
||||
if (!format->frames)
|
||||
return -ENOMEM;
|
||||
|
||||
for (i = 0; i < (unsigned int)n_entries; ++i) {
|
||||
char *frame;
|
||||
|
||||
frame = path_join(path, entries[i]->d_name);
|
||||
if (!frame) {
|
||||
ret = -ENOMEM;
|
||||
goto done;
|
||||
}
|
||||
|
||||
ret = configfs_parse_streaming_frame(frame, &format->frames[i]);
|
||||
free(frame);
|
||||
if (ret < 0)
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* Sort the frames by index. */
|
||||
qsort(format->frames, format->num_frames, sizeof *format->frames,
|
||||
frame_compare);
|
||||
|
||||
done:
|
||||
for (i = 0; i < (unsigned int)n_entries; ++i)
|
||||
free(entries[i]);
|
||||
free(entries);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int format_filter(const struct dirent *ent) {
|
||||
char *path;
|
||||
bool valid;
|
||||
|
||||
/*
|
||||
* Accept all links that point to a directory containing a
|
||||
* "bFormatIndex" file.
|
||||
*/
|
||||
if (ent->d_type != DT_LNK)
|
||||
return 0;
|
||||
|
||||
path = path_join(ent->d_name, "bFormatIndex");
|
||||
if (!path)
|
||||
return 0;
|
||||
|
||||
valid = access(path, R_OK);
|
||||
free(path);
|
||||
return valid;
|
||||
}
|
||||
|
||||
static int format_compare(const void *a, const void *b) {
|
||||
const struct uvc_function_config_format *fa = a;
|
||||
const struct uvc_function_config_format *fb = b;
|
||||
|
||||
if (fa->index < fb->index)
|
||||
return -1;
|
||||
else if (fa->index == fb->index)
|
||||
return 0;
|
||||
else
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
configfs_parse_streaming_header(const char *path,
|
||||
struct uvc_function_config_streaming *cfg) {
|
||||
struct dirent **entries;
|
||||
unsigned int i;
|
||||
int n_entries;
|
||||
int ret;
|
||||
|
||||
/* Find all entries corresponding to a format and parse them. */
|
||||
n_entries = scandir(path, &entries, format_filter, alphasort);
|
||||
if (n_entries < 0)
|
||||
return -errno;
|
||||
|
||||
if (n_entries == 0) {
|
||||
free(entries);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
cfg->num_formats = n_entries;
|
||||
cfg->formats = calloc(sizeof *cfg->formats, cfg->num_formats);
|
||||
if (!cfg->formats)
|
||||
return -ENOMEM;
|
||||
|
||||
for (i = 0; i < (unsigned int)n_entries; ++i) {
|
||||
char *format;
|
||||
|
||||
format = path_join(path, entries[i]->d_name);
|
||||
if (!format) {
|
||||
ret = -ENOMEM;
|
||||
goto done;
|
||||
}
|
||||
|
||||
ret = configfs_parse_streaming_format(format, &cfg->formats[i]);
|
||||
free(format);
|
||||
if (ret < 0)
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* Sort the formats by index. */
|
||||
qsort(cfg->formats, cfg->num_formats, sizeof *cfg->formats, format_compare);
|
||||
|
||||
done:
|
||||
for (i = 0; i < (unsigned int)n_entries; ++i)
|
||||
free(entries[i]);
|
||||
free(entries);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int link_filter(const struct dirent *ent) {
|
||||
/* Accept all links. */
|
||||
return ent->d_type == DT_LNK;
|
||||
}
|
||||
|
||||
static int configfs_parse_streaming(const char *path,
|
||||
struct uvc_function_config_streaming *cfg) {
|
||||
char *header;
|
||||
char *class;
|
||||
int ret;
|
||||
|
||||
ret = configfs_parse_interface(path, &cfg->intf);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
/*
|
||||
* Handle the high-speed class descriptors only for now. Find the first
|
||||
* link to the class descriptors.
|
||||
*/
|
||||
class = path_join(path, "class/hs");
|
||||
if (!class)
|
||||
return -ENOMEM;
|
||||
|
||||
header = dir_first_match(class, link_filter);
|
||||
free(class);
|
||||
if (!header)
|
||||
return -EINVAL;
|
||||
|
||||
ret = configfs_parse_streaming_header(header, cfg);
|
||||
free(header);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int configfs_parse_uvc(const char *fpath,
|
||||
struct uvc_function_config *fc) {
|
||||
int ret = 0;
|
||||
|
||||
ret = ret ?: configfs_parse_child(fpath, "control", &fc->control,
|
||||
configfs_parse_control);
|
||||
ret = ret ?: configfs_parse_child(fpath, "streaming", &fc->streaming,
|
||||
configfs_parse_streaming);
|
||||
|
||||
/*
|
||||
* These parameters should be part of the streaming interface in
|
||||
* ConfigFS, but for legacy reasons they are located directly in the
|
||||
* function directory.
|
||||
*/
|
||||
ret = ret ?: attribute_read_uint(fpath, "streaming_interval",
|
||||
&fc->streaming.ep.bInterval);
|
||||
ret = ret ?: attribute_read_uint(fpath, "streaming_maxburst",
|
||||
&fc->streaming.ep.bMaxBurst);
|
||||
ret = ret ?: attribute_read_uint(fpath, "streaming_maxpacket",
|
||||
&fc->streaming.ep.wMaxPacketSize);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
struct uvc_function_config *configfs_parse_uvc_function(unsigned int index) {
|
||||
struct uvc_function_config *fc;
|
||||
char *fpath;
|
||||
char *function;
|
||||
int ret = 0;
|
||||
|
||||
fc = malloc(sizeof *fc);
|
||||
if (fc == NULL)
|
||||
return NULL;
|
||||
|
||||
memset(fc, 0, sizeof *fc);
|
||||
|
||||
/* Find the function in ConfigFS. */
|
||||
fpath = configfs_find_uvc_function(index);
|
||||
if (!fpath) {
|
||||
free(fc);
|
||||
printf("[configfs_parse_uvc_function] configfs_find_uvc_function error!\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
function = basename(fpath);
|
||||
|
||||
fc->dev_name = attribute_read_str(fpath, "device_name");
|
||||
if (fc->dev_name == NULL)
|
||||
fc->dev_name = "UVC CAMERA";
|
||||
fc->udc = attribute_read_str(fpath, "../../UDC");
|
||||
fc->video = udc_find_video_device(fc->udc, function);
|
||||
printf("fc->dev_name:%s, fc->udc:%s, fc->video:%d \n", fc->dev_name, fc->udc,
|
||||
fc->video);
|
||||
if (fc->video < 0) {
|
||||
ret = -ENODEV;
|
||||
goto done;
|
||||
}
|
||||
fc->index = index;
|
||||
|
||||
ret = configfs_parse_uvc(fpath, fc);
|
||||
|
||||
done:
|
||||
if (ret) {
|
||||
configfs_free_uvc_function(fc);
|
||||
printf("[configfs_parse_uvc_function] configfs_free_uvc_function\n");
|
||||
fc = NULL;
|
||||
}
|
||||
|
||||
free(fpath);
|
||||
|
||||
return fc;
|
||||
}
|
||||
117
project/app/uvc_app_tiny/uvc_app/uvc/uvc_configfs.h
Normal file
117
project/app/uvc_app_tiny/uvc_app/uvc/uvc_configfs.h
Normal file
@@ -0,0 +1,117 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
/*
|
||||
* ConfigFS Gadget device handling
|
||||
*
|
||||
* Copyright (C) 2020 Rockchip Electronics Co., Ltd.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __UVC_CONFIGFS_H__
|
||||
#define __UVC_CONFIGFS_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
/*
|
||||
* struct uvc_function_config_endpoint - Endpoint parameters
|
||||
* @bInterval: Transfer interval (interrupt and isochronous only)
|
||||
* @bMaxBurst: Transfer burst size (super-speed only)
|
||||
* @wMaxPacketSize: Maximum packet size (including the multiplier)
|
||||
*/
|
||||
struct uvc_function_config_endpoint {
|
||||
unsigned int bInterval;
|
||||
unsigned int bMaxBurst;
|
||||
unsigned int wMaxPacketSize;
|
||||
};
|
||||
|
||||
/*
|
||||
* struct uvc_function_config_interface - Interface parameters
|
||||
* @bInterfaceNumber: Interface number
|
||||
*/
|
||||
struct uvc_function_config_interface {
|
||||
unsigned int bInterfaceNumber;
|
||||
};
|
||||
|
||||
/*
|
||||
* struct uvc_function_config_control - Control interface parameters
|
||||
* @intf: Generic interface parameters
|
||||
*/
|
||||
struct uvc_function_config_control {
|
||||
struct uvc_function_config_interface intf;
|
||||
};
|
||||
|
||||
/*
|
||||
* struct uvc_function_config_frame - Streaming frame parameters
|
||||
* @index: Frame index in the UVC descriptors
|
||||
* @width: Frame width in pixels
|
||||
* @height: Frame height in pixels
|
||||
* @num_intervals: Number of entries in the intervals array
|
||||
* @intervals: Array of frame intervals
|
||||
*/
|
||||
struct uvc_function_config_frame {
|
||||
unsigned int index;
|
||||
unsigned int width;
|
||||
unsigned int height;
|
||||
unsigned int num_intervals;
|
||||
unsigned int *intervals;
|
||||
};
|
||||
|
||||
/*
|
||||
* struct uvc_function_config_format - Streaming format parameters
|
||||
* @index: Format index in the UVC descriptors
|
||||
* @guid: Format GUID
|
||||
* @fcc: V4L2 pixel format
|
||||
* @num_frames: Number of entries in the frames array
|
||||
* @frames: Array of frame descriptors
|
||||
*/
|
||||
struct uvc_function_config_format {
|
||||
unsigned int index;
|
||||
uint8_t guid[16];
|
||||
unsigned int fcc;
|
||||
unsigned int num_frames;
|
||||
struct uvc_function_config_frame *frames;
|
||||
};
|
||||
|
||||
/*
|
||||
* struct uvc_function_config_streaming - Streaming interface parameters
|
||||
* @intf: Generic interface parameters
|
||||
* @ep: Endpoint parameters
|
||||
* @num_formats: Number of entries in the formats array
|
||||
* @formats: Array of format descriptors
|
||||
*/
|
||||
struct uvc_function_config_streaming {
|
||||
struct uvc_function_config_interface intf;
|
||||
struct uvc_function_config_endpoint ep;
|
||||
|
||||
unsigned int num_formats;
|
||||
struct uvc_function_config_format *formats;
|
||||
};
|
||||
|
||||
/*
|
||||
* struct uvc_function_config - UVC function configuration parameters
|
||||
* @video: Full path to the video device node
|
||||
* @udc: UDC name
|
||||
* @control: Control interface configuration
|
||||
* @streaming: Streaming interface configuration
|
||||
*/
|
||||
struct uvc_function_config {
|
||||
int video;
|
||||
int video_src;
|
||||
unsigned int index;
|
||||
char *udc;
|
||||
char *dev_name;
|
||||
|
||||
struct uvc_function_config_control control;
|
||||
struct uvc_function_config_streaming streaming;
|
||||
};
|
||||
|
||||
struct uvc_function_config *configfs_parse_uvc_function(unsigned int index);
|
||||
void configfs_free_uvc_function(struct uvc_function_config *fc);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
403
project/app/uvc_app_tiny/uvc_app/uvc/uvc_control.cpp
Normal file
403
project/app/uvc_app_tiny/uvc_app/uvc/uvc_control.cpp
Normal file
@@ -0,0 +1,403 @@
|
||||
/*
|
||||
* Copyright (C) 2019 Rockchip Electronics Co., Ltd.
|
||||
*
|
||||
* This software is available to you under a choice of one of two
|
||||
* licenses. You may choose to be licensed under the terms of the GNU
|
||||
* General Public License (GPL), available from the file
|
||||
* COPYING in the main directory of this source tree, or the
|
||||
* OpenIB.org BSD license below:
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or
|
||||
* without modification, are permitted provided that the following
|
||||
* conditions are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer.
|
||||
*
|
||||
* - Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "uvc_control.h"
|
||||
#include "camera_control.h"
|
||||
#include "uevent.h"
|
||||
#include "uvc-gadget.h"
|
||||
#include "uvc_configfs.h"
|
||||
#include "uvc_log.h"
|
||||
#include "uvc_process_unit.h"
|
||||
#include "uvc_video.h"
|
||||
#include <fcntl.h>
|
||||
#include <map>
|
||||
#include <pthread.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#define UVC_STREAMING_INTF_PATH \
|
||||
"/sys/kernel/config/usb_gadget/rockchip/functions/uvc.gs6/streaming/" \
|
||||
"bInterfaceNumber"
|
||||
|
||||
#define UVC_STREAMING_MAXPACKET_PATH \
|
||||
"/sys/kernel/config/usb_gadget/rockchip/functions/uvc.gs6/" \
|
||||
"streaming_maxpacket"
|
||||
int enable_minilog;
|
||||
int rk_mpi_uvc_log_level;
|
||||
int app_quit;
|
||||
int uvc_ir_cnt;
|
||||
int uvc_rgb_cnt;
|
||||
|
||||
static int (*camera_start_callback)(int id, int width, int height, int fps,
|
||||
int format, int eptz);
|
||||
static void (*camera_stop_callback)(int id);
|
||||
uvc_pu_control_callback_t uvc_pu_control_cb = NULL;
|
||||
|
||||
struct uvc_ctrl {
|
||||
int id;
|
||||
bool start;
|
||||
bool stop;
|
||||
int width;
|
||||
int height;
|
||||
int fps;
|
||||
int format;
|
||||
int eptz;
|
||||
int suspend;
|
||||
struct uvc_function_config *fc;
|
||||
};
|
||||
|
||||
static struct uvc_ctrl uvc_ctrl[CAM_MAX_NUM] = {
|
||||
{.id = -1, .start = false, .stop = false, .width = -1, .height = -1, .fps = -1, .format = 1, .eptz = 0, .suspend = 0, .fc = NULL},
|
||||
{.id = -1, .start = false, .stop = false, .width = -1, .height = -1, .fps = -1, .format = 1, .eptz = 0, .suspend = 0, .fc = NULL},
|
||||
{.id = -1, .start = false, .stop = false, .width = -1, .height = -1, .fps = -1, .format = 1, .eptz = 0, .suspend = 0, .fc = NULL},
|
||||
};
|
||||
|
||||
static std::map<int, UVC_CTRL_INFO> gUVCIdCtlInfoMap;
|
||||
static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
|
||||
static int uvc_streaming_intf = -1;
|
||||
static int uvc_streaming_maxpacket = 1024;
|
||||
|
||||
bool uvc_process_init_flag = false;
|
||||
bool uvc_process_config_flag = false;
|
||||
|
||||
static pthread_t run_id = 0;
|
||||
static bool uvc_restart = false;
|
||||
static bool run_flag = true;
|
||||
static uint32_t uvc_flags = UVC_CONTROL_CAMERA;
|
||||
|
||||
static pthread_mutex_t run_mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
static pthread_cond_t run_cond = PTHREAD_COND_INITIALIZER;
|
||||
static pthread_cond_t video_added = PTHREAD_COND_INITIALIZER;
|
||||
|
||||
static int32_t g_suspend;
|
||||
|
||||
static void query_uvc_streaming_maxpacket(void) {
|
||||
int fd;
|
||||
|
||||
fd = open(UVC_STREAMING_MAXPACKET_PATH, O_RDONLY);
|
||||
if (fd >= 0) {
|
||||
char intf[32] = {0};
|
||||
read(fd, intf, sizeof(intf) - 1);
|
||||
uvc_streaming_maxpacket = atoi(intf);
|
||||
if (uvc_streaming_maxpacket < 1023)
|
||||
uvc_streaming_maxpacket = 1024;
|
||||
LOG_DEBUG("uvc_streaming_maxpacket = %d\n", uvc_streaming_maxpacket);
|
||||
close(fd);
|
||||
} else {
|
||||
LOG_ERROR("open %s failed!\n", UVC_STREAMING_MAXPACKET_PATH);
|
||||
}
|
||||
}
|
||||
|
||||
int get_uvc_streaming_maxpacket(void) { return uvc_streaming_maxpacket; }
|
||||
|
||||
static void query_uvc_streaming_intf(void) {
|
||||
int fd;
|
||||
|
||||
fd = open(UVC_STREAMING_INTF_PATH, O_RDONLY);
|
||||
if (fd >= 0) {
|
||||
char intf[32] = {0};
|
||||
read(fd, intf, sizeof(intf) - 1);
|
||||
uvc_streaming_intf = atoi(intf);
|
||||
LOG_DEBUG("uvc_streaming_intf = %d\n", uvc_streaming_intf);
|
||||
close(fd);
|
||||
} else {
|
||||
LOG_ERROR("open %s failed!\n", UVC_STREAMING_INTF_PATH);
|
||||
}
|
||||
}
|
||||
|
||||
void register_uvc_pu_control_callback(uvc_pu_control_callback_t cb) {
|
||||
uvc_pu_control_cb = cb;
|
||||
}
|
||||
|
||||
void uvc_control_start_setcallback(int (*callback)(int fd, int width,
|
||||
int height, int fps,
|
||||
int format, int eptz)) {
|
||||
camera_start_callback = callback;
|
||||
}
|
||||
|
||||
void uvc_control_stop_setcallback(void (*callback)(int fd)) {
|
||||
camera_stop_callback = callback;
|
||||
}
|
||||
|
||||
static void get_uvc_index_to_name(unsigned int index, char *name) {
|
||||
if (strstr(name, "depth") || strstr(name, "DEPTH") || strstr(name, "ir") ||
|
||||
strstr(name, "IR")) {
|
||||
uvc_ir_cnt = index;
|
||||
LOG_DEBUG("uvc_ir_cnt = %d, name:%s\n", uvc_ir_cnt, name);
|
||||
} else if (strstr(name, "rgb") || strstr(name, "RGB")) {
|
||||
uvc_rgb_cnt = index;
|
||||
LOG_DEBUG("uvc_rgb_cnt = %d, name:%s\n", uvc_rgb_cnt, name);
|
||||
}
|
||||
}
|
||||
|
||||
int check_uvc_video_id(void) {
|
||||
bool find_dev = false;
|
||||
struct uvc_function_config *fc[CAM_MAX_NUM] = {};
|
||||
for (uint32_t i = 0; i < CAM_MAX_NUM; i++) {
|
||||
fc[i] = configfs_parse_uvc_function(i);
|
||||
if (fc[i]) {
|
||||
get_uvc_index_to_name(fc[i]->index, fc[i]->dev_name);
|
||||
uvc_ctrl[i].id = fc[i]->video;
|
||||
uvc_ctrl[i].fc = fc[i];
|
||||
find_dev = true;
|
||||
LOG_DEBUG("uvc_function_config fc->video:%d,fc->streaming.num_formats:%d",
|
||||
fc[i]->video, uvc_ctrl[i].fc->streaming.num_formats);
|
||||
}
|
||||
}
|
||||
|
||||
if (false == find_dev) {
|
||||
LOG_WARN("Please configure uvc...\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void add_uvc_video() {
|
||||
for (uint32_t i = 0; i < CAM_MAX_NUM; i++) {
|
||||
if (uvc_ctrl[i].id >= 0) {
|
||||
uvc_video_id_add(uvc_ctrl[i].fc);
|
||||
LOG_INFO("uvc_ctrl:%u, id:%d, fc->video:%d\n",i , uvc_ctrl[i].id, uvc_ctrl[i].fc->video);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int uvc_control_loop(void) {
|
||||
if (uvc_restart) {
|
||||
// uvc_video_id_exit_all();
|
||||
// add_uvc_video();
|
||||
uvc_restart = false;
|
||||
return 0;
|
||||
}
|
||||
unsigned int i;
|
||||
for (i = 0; i < CAM_MAX_NUM; i++) {
|
||||
if (uvc_ctrl[i].stop) {
|
||||
if (camera_stop_callback)
|
||||
camera_stop_callback(i);
|
||||
uvc_ctrl[i].stop = false;
|
||||
}
|
||||
|
||||
if (uvc_ctrl[i].start) {
|
||||
LOG_INFO("%s: video_id:%d, width:%d,height:%d,fps:%d,format:%d,eptz:%d !\n",
|
||||
__func__, uvc_ctrl[i].id, uvc_ctrl[i].width, uvc_ctrl[i].height,
|
||||
uvc_ctrl[i].fps, uvc_ctrl[i].format, uvc_ctrl[i].eptz);
|
||||
if (camera_start_callback) {
|
||||
LOG_INFO("%s camera_start_callback start!\n", __func__);
|
||||
camera_start_callback(i, uvc_ctrl[i].width, uvc_ctrl[i].height,
|
||||
uvc_ctrl[i].fps, uvc_ctrl[i].format,
|
||||
uvc_ctrl[i].eptz);
|
||||
}
|
||||
uvc_ctrl[i].start = false;
|
||||
}
|
||||
}
|
||||
if (g_suspend) {
|
||||
if (access("/tmp/uvc_no_suspend", 0)) {
|
||||
sleep(5);
|
||||
if (g_suspend) {
|
||||
LOG_INFO("uvc ready to suspend...\n");
|
||||
g_suspend = 0;
|
||||
system("touch /tmp/uvc_goto_suspend");
|
||||
}
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int uvc_control_run(uint32_t flags) {
|
||||
uvc_ir_cnt = -1;
|
||||
uvc_rgb_cnt = -1;
|
||||
uvc_flags = flags;
|
||||
if ((flags & UVC_CONTROL_CHECK_STRAIGHT) || (flags & UVC_CONTROL_CAMERA)) {
|
||||
if (!check_uvc_video_id()) {
|
||||
add_uvc_video();
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void set_uvc_control_suspend(int suspend) {
|
||||
LOG_INFO("suspend is %d\n", suspend);
|
||||
g_suspend = suspend;
|
||||
if ((suspend == 0) && !access("/tmp/uvc_goto_suspend", 0))
|
||||
system("rm /tmp/uvc_goto_suspend");
|
||||
}
|
||||
|
||||
// TODO: use video id start uvc_ctrl
|
||||
void set_uvc_control_start(int video_id, int width, int height, int fps,
|
||||
int format, int eptz) {
|
||||
LOG_DEBUG("%s: video_id:%d\n", __func__, video_id);
|
||||
for (int i = 0; i < CAM_MAX_NUM; i++) {
|
||||
if (uvc_ctrl[i].id == video_id) {
|
||||
LOG_DEBUG("%s: camera:%d, video_id:%d, width:%d,height:%d,fps:%d,eptz:%d!\n",
|
||||
__func__, i, video_id, width, height, fps, eptz);
|
||||
uvc_ctrl[i].id = video_id;
|
||||
uvc_ctrl[i].width = width;
|
||||
uvc_ctrl[i].height = height;
|
||||
uvc_ctrl[i].fps = fps;
|
||||
uvc_ctrl[i].format = format;
|
||||
uvc_ctrl[i].start = true;
|
||||
uvc_ctrl[i].eptz = eptz;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: use video id stop uvc_ctrl
|
||||
void set_uvc_control_stop(int video_id) {
|
||||
LOG_INFO("%s:video_id:%d\n", __func__, video_id);
|
||||
for (int i = 0; i < CAM_MAX_NUM; i++) {
|
||||
if (uvc_ctrl[i].id == video_id)
|
||||
uvc_ctrl[i].stop = true;
|
||||
}
|
||||
}
|
||||
|
||||
void set_uvc_control_restart(void) {
|
||||
if (uvc_flags & UVC_CONTROL_CAMERA) {
|
||||
LOG_INFO("received uvc to exit,restart to recovery now!\n");
|
||||
// system("killall -9 uvc_app &");
|
||||
uvc_restart = true;
|
||||
}
|
||||
}
|
||||
|
||||
UVC_CTRL_INFO uvc_find_uvc_ctrl_info_by_id(int id) {
|
||||
for (std::map<int, UVC_CTRL_INFO>::iterator iter = gUVCIdCtlInfoMap.begin();
|
||||
iter != gUVCIdCtlInfoMap.end(); ++iter) {
|
||||
if (iter->first == id) {
|
||||
LOG_DEBUG("index:%d find uvc_enc:%p by id:%d\n", iter->second.index,
|
||||
&iter->second, id);
|
||||
// iter->second.index = index;
|
||||
return iter->second;
|
||||
}
|
||||
}
|
||||
UVC_CTRL_INFO uvc_ctrl_info;
|
||||
for (int i = 0; i < CAM_MAX_NUM; i++) {
|
||||
if (uvc_ctrl[i].id == id)
|
||||
uvc_ctrl_info.index = i;
|
||||
}
|
||||
// uvc_ctrl_info.index = gUVCIdCtlInfoMap.size();
|
||||
gUVCIdCtlInfoMap.insert(std::map<int, UVC_CTRL_INFO>::value_type(id, uvc_ctrl_info));
|
||||
|
||||
LOG_INFO("index:%d new uvc_ctrl_info:%p by id:%d\n", uvc_ctrl_info.index,
|
||||
&uvc_ctrl_info, id);
|
||||
|
||||
return uvc_ctrl_info;
|
||||
}
|
||||
|
||||
void uvc_control_config(struct uvc_device *dev) {
|
||||
pthread_mutex_lock(&lock);
|
||||
UVC_CTRL_INFO uvc_ctrl_info = uvc_find_uvc_ctrl_info_by_id(dev->video_id);
|
||||
uvc_ctrl_info.width = dev->width;
|
||||
uvc_ctrl_info.height = dev->height;
|
||||
uvc_ctrl_info.fcc = dev->fcc;
|
||||
uvc_ctrl_info.fps = dev->fps;
|
||||
uvc_ctrl_info.eptz[UVC_EPTZ_AUTO] = dev->eptz_flag; // read by cfg
|
||||
uvc_ctrl_info.video_id = dev->video_id;
|
||||
uvc_ctrl_info.eptz[UVC_EPTZ_ZOOM] = 10;
|
||||
uvc_ctrl_info.eptz[UVC_EPTZ_PAN] = 0;
|
||||
uvc_ctrl_info.eptz[UVC_EPTZ_TILT] = 0;
|
||||
// camera_control_set_rate(uvc_ctrl_info.index, dev->fps);
|
||||
dev->nbufs = uvc_process_config(uvc_ctrl_info);
|
||||
if (dev->nbufs <= 0) {
|
||||
LOG_ERROR("%s fail!\n", __func__);
|
||||
abort();
|
||||
}
|
||||
LOG_INFO("uvc_enc->video_id:%d dev->nbufs:%d\n", uvc_ctrl_info.video_id,
|
||||
dev->nbufs);
|
||||
uvc_process_init_flag = true;
|
||||
uvc_process_config_flag = true;
|
||||
pthread_mutex_unlock(&lock);
|
||||
}
|
||||
|
||||
void uvc_control_streamon(struct uvc_device *dev) {
|
||||
pthread_mutex_lock(&lock);
|
||||
UVC_CTRL_INFO uvc_ctrl_info = uvc_find_uvc_ctrl_info_by_id(dev->video_id);
|
||||
uvc_ctrl_info.width = dev->width;
|
||||
uvc_ctrl_info.height = dev->height;
|
||||
uvc_ctrl_info.fcc = dev->fcc;
|
||||
uvc_ctrl_info.fps = dev->fps;
|
||||
uvc_ctrl_info.eptz[UVC_EPTZ_AUTO] = dev->eptz_flag;
|
||||
uvc_ctrl_info.video_id = dev->video_id;
|
||||
// uvc_ctrl_info->zoom = dev->zoom_val; // init have not zoom info
|
||||
if (uvc_process_start(uvc_ctrl_info)) {
|
||||
LOG_ERROR("%s fail!\n", __func__);
|
||||
abort();
|
||||
}
|
||||
LOG_INFO("uvc_enc->video_id:%d", uvc_ctrl_info.video_id);
|
||||
uvc_process_init_flag = true;
|
||||
pthread_mutex_unlock(&lock);
|
||||
}
|
||||
|
||||
void uvc_control_inbuf_deinit() {
|
||||
pthread_mutex_lock(&lock);
|
||||
// if(uvc_process_init_flag)
|
||||
// uvc_encode_inbuf_deinit(&uvc_enc);
|
||||
pthread_mutex_unlock(&lock);
|
||||
}
|
||||
|
||||
void uvc_control_streamoff(int video_id) {
|
||||
pthread_mutex_lock(&lock);
|
||||
if (uvc_process_init_flag) {
|
||||
UVC_CTRL_INFO uvc_ctrl_info = uvc_find_uvc_ctrl_info_by_id(video_id);
|
||||
uvc_process_stop(uvc_ctrl_info);
|
||||
}
|
||||
uvc_process_init_flag = false;
|
||||
pthread_mutex_unlock(&lock);
|
||||
}
|
||||
|
||||
void uvc_control_delete(int video_id) {
|
||||
pthread_mutex_lock(&lock);
|
||||
if (uvc_process_config_flag) {
|
||||
UVC_CTRL_INFO uvc_ctrl_info = uvc_find_uvc_ctrl_info_by_id(video_id);
|
||||
uvc_process_delete(uvc_ctrl_info);
|
||||
}
|
||||
uvc_process_config_flag = false;
|
||||
pthread_mutex_unlock(&lock);
|
||||
}
|
||||
|
||||
void uvc_control_release_frame_nonlock(struct uvc_device *dev, void *frame) {
|
||||
int ret = 0;
|
||||
|
||||
UVC_CTRL_INFO uvc_ctrl_info = uvc_find_uvc_ctrl_info_by_id(dev->video_id);
|
||||
ret = uvc_process_release_frame(uvc_ctrl_info, frame);
|
||||
if (ret < 0) {
|
||||
LOG_ERROR("%s fail: %d!\n", __func__, ret);
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
void uvc_control_release_frame(struct uvc_device *dev, void *frame) {
|
||||
pthread_mutex_lock(&lock);
|
||||
uvc_control_release_frame_nonlock(dev, frame);
|
||||
pthread_mutex_unlock(&lock);
|
||||
}
|
||||
89
project/app/uvc_app_tiny/uvc_app/uvc/uvc_control.h
Executable file
89
project/app/uvc_app_tiny/uvc_app/uvc/uvc_control.h
Executable file
@@ -0,0 +1,89 @@
|
||||
/*
|
||||
* Copyright (C) 2019 Rockchip Electronics Co., Ltd.
|
||||
*
|
||||
* This software is available to you under a choice of one of two
|
||||
* licenses. You may choose to be licensed under the terms of the GNU
|
||||
* General Public License (GPL), available from the file
|
||||
* COPYING in the main directory of this source tree, or the
|
||||
* OpenIB.org BSD license below:
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or
|
||||
* without modification, are permitted provided that the following
|
||||
* conditions are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer.
|
||||
*
|
||||
* - Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef __UVC_CONTROL_H__
|
||||
#define __UVC_CONTROL_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#include "uvc_process_unit.h"
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef USE_RK_MODULE
|
||||
#define ISP_SEQ 1
|
||||
#define ISP_FMT HAL_FRMAE_FMT_NV12
|
||||
#define CIF_SEQ 0
|
||||
#define CIF_FMT HAL_FRMAE_FMT_SBGGR10
|
||||
#else
|
||||
#define ISP_SEQ 0
|
||||
#define ISP_FMT HAL_FRMAE_FMT_SBGGR8
|
||||
#define CIF_SEQ 1
|
||||
#define CIF_FMT HAL_FRMAE_FMT_NV12
|
||||
#endif
|
||||
|
||||
#define UVC_CONTROL_LOOP_ONCE (1 << 0)
|
||||
#define UVC_CONTROL_CHECK_STRAIGHT (1 << 1)
|
||||
#define UVC_CONTROL_CAMERA (1 << 2)
|
||||
|
||||
extern int app_quit;
|
||||
|
||||
typedef void (*uvc_pu_control_callback_t)(unsigned char cs, unsigned int val);
|
||||
void register_uvc_pu_control_callback(uvc_pu_control_callback_t cb);
|
||||
extern uvc_pu_control_callback_t uvc_pu_control_cb;
|
||||
|
||||
void add_uvc_video();
|
||||
int uvc_control_loop(void);
|
||||
int check_uvc_video_id(void);
|
||||
void set_uvc_control_start(int video_id, int width, int height, int fps,
|
||||
int format, int eptz);
|
||||
void set_uvc_control_stop(int video_id);
|
||||
void set_uvc_control_restart(void);
|
||||
void uvc_control_start_setcallback(int (*callback)(int id, int width,
|
||||
int height, int fps,
|
||||
int format, int eptz));
|
||||
void uvc_control_stop_setcallback(void (*callback)(int id));
|
||||
void uvc_control_config(struct uvc_device *dev);
|
||||
void uvc_control_streamon(struct uvc_device *dev);
|
||||
void uvc_control_streamoff(int video_id);
|
||||
void uvc_control_delete(int video_id);
|
||||
void uvc_control_inbuf_deinit();
|
||||
int uvc_control_run(uint32_t flags);
|
||||
void set_uvc_control_suspend(int suspend);
|
||||
void uvc_control_release_frame(struct uvc_device *dev, void *frame);
|
||||
void uvc_control_release_frame_nonlock(struct uvc_device *dev, void *frame);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
52
project/app/uvc_app_tiny/uvc_app/uvc/uvc_ipc_ext.h
Normal file
52
project/app/uvc_app_tiny/uvc_app/uvc/uvc_ipc_ext.h
Normal file
@@ -0,0 +1,52 @@
|
||||
#ifndef __UVC_IPC_EXT_H__
|
||||
#define __UVC_IPC_EXT_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#if DBUG
|
||||
#define UVC_DYNAMIC_DEBUG_USE_TIME 1 // release version can set to 0
|
||||
#define UVC_DYNAMIC_DEBUG_USE_TIME_CHECK "/tmp/uvc_use_time"
|
||||
#else
|
||||
#define UVC_DYNAMIC_DEBUG_USE_TIME 0
|
||||
#endif
|
||||
|
||||
enum UVC_IPC_EVENT {
|
||||
UVC_IPC_EVENT_START = 1,
|
||||
UVC_IPC_EVENT_STOP = 2,
|
||||
UVC_IPC_EVENT_ENABLE_ETPTZ = 3,
|
||||
UVC_IPC_EVENT_SET_ZOOM = 4,
|
||||
UVC_IPC_EVENT_RET_TRANSPORT_BUF = 5,
|
||||
UVC_IPC_EVENT_CONFIG_CAMERA = 6,
|
||||
UVC_IPC_EVENT_SET_EPTZ_PAN = 7,
|
||||
UVC_IPC_EVENT_SET_EPTZ_TILT = 8,
|
||||
UVC_IPC_EVENT_ENABLE_BYPASS = 9
|
||||
};
|
||||
|
||||
enum UVC_IPC_ENC_TYPE {
|
||||
UVC_IPC_ENC_YUV = 0,
|
||||
UVC_IPC_ENC_MJPEG_NORMAL,
|
||||
UVC_IPC_ENC_MJPEG_LOW_LATENCY,
|
||||
UVC_IPC_ENC_H264,
|
||||
UVC_IPC_ENC_H265
|
||||
};
|
||||
|
||||
struct CAMERA_INFO {
|
||||
int width;
|
||||
int height;
|
||||
int vir_width;
|
||||
int vir_height;
|
||||
int buf_size;
|
||||
int range;
|
||||
enum UVC_IPC_ENC_TYPE encode_type;
|
||||
int uvc_fps_set;
|
||||
};
|
||||
|
||||
extern void uvc_ipc_event(enum UVC_IPC_EVENT event, void *data);
|
||||
extern void uvc_ipc_reconnect(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
91
project/app/uvc_app_tiny/uvc_app/uvc/uvc_log.h
Normal file
91
project/app/uvc_app_tiny/uvc_app/uvc/uvc_log.h
Normal file
@@ -0,0 +1,91 @@
|
||||
// Copyright 2019 Fuzhou Rockchip Electronics Co., Ltd. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef _RK_LOGGER_H_
|
||||
#define _RK_LOGGER_H_
|
||||
|
||||
#ifdef ENABLE_MINILOGGER
|
||||
#include "minilogger/log.h"
|
||||
#else
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <sys/time.h>
|
||||
#define minilog_warn(...)
|
||||
#define minilog_error(...)
|
||||
#define minilog_info(...)
|
||||
#define minilog_debug(...)
|
||||
#define __minilog_log_init(...)
|
||||
#endif
|
||||
|
||||
extern int enable_minilog;
|
||||
extern int rk_mpi_uvc_log_level;
|
||||
|
||||
#define LOG_LEVEL_ERROR 0
|
||||
#define LOG_LEVEL_WARN 1
|
||||
#define LOG_LEVEL_INFO 2
|
||||
#define LOG_LEVEL_DEBUG 3
|
||||
|
||||
#ifndef LOG_TAG
|
||||
#define LOG_TAG "rk_mpi_uvc"
|
||||
#endif // LOG_TAG
|
||||
|
||||
//#define ENABLE_BUFFER_TIME_DEBUG
|
||||
|
||||
#define LOG_INFO(format, ...) \
|
||||
do { \
|
||||
if (rk_mpi_uvc_log_level < LOG_LEVEL_INFO) \
|
||||
break; \
|
||||
if (enable_minilog) \
|
||||
minilog_info("[%s][%s]:" format, LOG_TAG, __FUNCTION__, ##__VA_ARGS__); \
|
||||
else { \
|
||||
struct timeval tv; \
|
||||
gettimeofday(&tv, NULL); \
|
||||
fprintf(stderr, "[%d.%06d][%s][%s][%d]:" format, tv.tv_sec, tv.tv_usec, \
|
||||
LOG_TAG, __FUNCTION__, __LINE__, ##__VA_ARGS__); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define LOG_WARN(format, ...) \
|
||||
do { \
|
||||
if (rk_mpi_uvc_log_level < LOG_LEVEL_WARN) \
|
||||
break; \
|
||||
if (enable_minilog) \
|
||||
minilog_warn("[%s][%s]:" format, LOG_TAG, __FUNCTION__, ##__VA_ARGS__); \
|
||||
else { \
|
||||
struct timeval tv; \
|
||||
gettimeofday(&tv, NULL); \
|
||||
fprintf(stderr, "[%d.%06d][%s][%s][%d]:" format, tv.tv_sec, tv.tv_usec, \
|
||||
LOG_TAG, __FUNCTION__, __LINE__, ##__VA_ARGS__); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define LOG_ERROR(format, ...) \
|
||||
do { \
|
||||
if (rk_mpi_uvc_log_level < LOG_LEVEL_ERROR) \
|
||||
break; \
|
||||
if (enable_minilog) \
|
||||
minilog_error("[%s][%s]:" format, LOG_TAG, __FUNCTION__, ##__VA_ARGS__); \
|
||||
else { \
|
||||
struct timeval tv; \
|
||||
gettimeofday(&tv, NULL); \
|
||||
fprintf(stderr, "[%d.%06d][%s][%s][%d]:" format, tv.tv_sec, tv.tv_usec, \
|
||||
LOG_TAG, __FUNCTION__, __LINE__, ##__VA_ARGS__); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define LOG_DEBUG(format, ...) \
|
||||
do { \
|
||||
if (rk_mpi_uvc_log_level < LOG_LEVEL_DEBUG) \
|
||||
break; \
|
||||
if (enable_minilog) \
|
||||
minilog_debug("[%s][%s]:" format, LOG_TAG, __FUNCTION__, ##__VA_ARGS__); \
|
||||
else { \
|
||||
struct timeval tv; \
|
||||
gettimeofday(&tv, NULL); \
|
||||
fprintf(stderr, "[%d.%06d][%s][%s][%d]:" format, tv.tv_sec, tv.tv_usec, \
|
||||
LOG_TAG, __FUNCTION__, __LINE__, ##__VA_ARGS__); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#endif
|
||||
1638
project/app/uvc_app_tiny/uvc_app/uvc/uvc_mpi_config.c
Executable file
1638
project/app/uvc_app_tiny/uvc_app/uvc/uvc_mpi_config.c
Executable file
File diff suppressed because it is too large
Load Diff
376
project/app/uvc_app_tiny/uvc_app/uvc/uvc_mpi_config.h
Executable file
376
project/app/uvc_app_tiny/uvc_app/uvc/uvc_mpi_config.h
Executable file
@@ -0,0 +1,376 @@
|
||||
/*
|
||||
* Copyright (C) 2019 Rockchip Electronics Co., Ltd.
|
||||
*
|
||||
* This software is available to you under a choice of one of two
|
||||
* licenses. You may choose to be licensed under the terms of the GNU
|
||||
* General Public License (GPL), available from the file
|
||||
* COPYING in the main directory of this source tree, or the
|
||||
* OpenIB.org BSD license below:
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or
|
||||
* without modification, are permitted provided that the following
|
||||
* conditions are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer.
|
||||
*
|
||||
* - Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef __UVC_MPI_CONFIG_H__
|
||||
#define __UVC_MPI_CONFIG_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "rk_mpi_vi.h"
|
||||
#include "rk_mpi_vpss.h"
|
||||
#include <rk_mpi_venc.h>
|
||||
|
||||
#define UVC_MPI_CFG_CHANGE_BIT(x) (1 << x)
|
||||
#define UVC_MPI_STREAM_SAVE_FILE_LEN 32
|
||||
#define VPSS_MAX_CHN 1 // now only support one chn.
|
||||
|
||||
typedef enum _MpiUvcCommonCfgChange {
|
||||
MPI_UVC_COMMON_CFG_NEED_CHECK = UVC_MPI_CFG_CHANGE_BIT(0),
|
||||
MPI_UVC_COMMON_CFG_UVC_DEBUG = UVC_MPI_CFG_CHANGE_BIT(1),
|
||||
MPI_UVC_COMMON_CFG_UVC_DEBUG_FILE_NAME = UVC_MPI_CFG_CHANGE_BIT(2),
|
||||
MPI_UVC_COMMON_CFG_UVC_DEBUG_FILE_CNT = UVC_MPI_CFG_CHANGE_BIT(3),
|
||||
MPI_UVC_COMMON_CFG_GEOMETRIC_OUT = UVC_MPI_CFG_CHANGE_BIT(4),
|
||||
MPI_UVC_COMMON_CFG_UVC_YUYV_DEBUG = UVC_MPI_CFG_CHANGE_BIT(5),
|
||||
MPI_UVC_COMMON_CFG_UVC_NN_ENABLE = UVC_MPI_CFG_CHANGE_BIT(6),
|
||||
MPI_UVC_COMMON_CFG_NN_DEBUG_FILE_NAME = UVC_MPI_CFG_CHANGE_BIT(7),
|
||||
MPI_UVC_COMMON_CFG_NN_DEBUG_FILE_CNT = UVC_MPI_CFG_CHANGE_BIT(8),
|
||||
MPI_UVC_COMMON_CFG_UVC_ENABLE_VPSS = UVC_MPI_CFG_CHANGE_BIT(9),
|
||||
MPI_UVC_COMMON_CFG_CHANGE_ALL = (0xffffffff),
|
||||
} MpiUvcCommonCfgChange;
|
||||
|
||||
typedef enum _MpiViCfgChange {
|
||||
MPI_VI_CFG_CHANGE_DEV_ID = UVC_MPI_CFG_CHANGE_BIT(0),
|
||||
MPI_VI_CFG_CHANGE_CHANNEL_ID = UVC_MPI_CFG_CHANGE_BIT(1),
|
||||
MPI_VI_CFG_CHANGE_BUF_CNT = UVC_MPI_CFG_CHANGE_BIT(2),
|
||||
MPI_VI_CFG_CHANGE_FBC = UVC_MPI_CFG_CHANGE_BIT(3),
|
||||
MPI_VI_CFG_CHANGE_MEMORY_TYPE = UVC_MPI_CFG_CHANGE_BIT(4),
|
||||
MPI_VI_CFG_CHANGE_ROTATION = UVC_MPI_CFG_CHANGE_BIT(5),
|
||||
MPI_VI_CFG_CHANGE_MIRROR = UVC_MPI_CFG_CHANGE_BIT(6),
|
||||
MPI_VI_CFG_CHANGE_DEV_NAME = UVC_MPI_CFG_CHANGE_BIT(7),
|
||||
MPI_VI_CFG_CHANGE_FPS = UVC_MPI_CFG_CHANGE_BIT(8),
|
||||
MPI_VI_CFG_CHANGE_ASSIGN_WIDTH = UVC_MPI_CFG_CHANGE_BIT(9),
|
||||
MPI_VI_CFG_CHANGE_ASSIGN_HEIGHT = UVC_MPI_CFG_CHANGE_BIT(10),
|
||||
MPI_VI_CFG_CHANGE_MIN_WIDTH = UVC_MPI_CFG_CHANGE_BIT(11),
|
||||
MPI_VI_CFG_CHANGE_MIN_HEIGHT = UVC_MPI_CFG_CHANGE_BIT(12),
|
||||
MPI_VI_CFG_CHANGE_MAX_WIDTH = UVC_MPI_CFG_CHANGE_BIT(13),
|
||||
MPI_VI_CFG_CHANGE_MAX_HEIGHT = UVC_MPI_CFG_CHANGE_BIT(14),
|
||||
MPI_VI_CFG_CHANGE_FORMAT = UVC_MPI_CFG_CHANGE_BIT(15),
|
||||
MPI_VI_CFG_CHANGE_ALL = (0xffffffff),
|
||||
} MpiViCfgChange;
|
||||
|
||||
typedef enum _MpiVpssCfgChange {
|
||||
MPI_VPSS_CFG_CHANGE_GROUP_ID = UVC_MPI_CFG_CHANGE_BIT(0),
|
||||
MPI_VPSS_CFG_CHANGE_CHANNEL_ID = UVC_MPI_CFG_CHANGE_BIT(1),
|
||||
MPI_VPSS_CFG_CHANGE_BUF_CNT = UVC_MPI_CFG_CHANGE_BIT(2),
|
||||
MPI_VPSS_CFG_CHANGE_FBC = UVC_MPI_CFG_CHANGE_BIT(3),
|
||||
MPI_VPSS_CFG_CHANGE_ROTATION = UVC_MPI_CFG_CHANGE_BIT(4),
|
||||
MPI_VPSS_CFG_CHANGE_MIRROR = UVC_MPI_CFG_CHANGE_BIT(5),
|
||||
MPI_VPSS_CFG_CHANGE_FPS = UVC_MPI_CFG_CHANGE_BIT(6),
|
||||
MPI_VPSS_CFG_CHANGE_FORMAT = UVC_MPI_CFG_CHANGE_BIT(7),
|
||||
MPI_VPSS_CFG_CHANGE_ASSIGN_WIDTH = UVC_MPI_CFG_CHANGE_BIT(8),
|
||||
MPI_VPSS_CFG_CHANGE_ASSIGN_HEIGHT = UVC_MPI_CFG_CHANGE_BIT(9),
|
||||
MPI_VPSS_CFG_CHANGE_ALL = (0xffffffff),
|
||||
} MpiVpssCfgChange;
|
||||
|
||||
typedef enum _MpiVencCommonCfgChange {
|
||||
MPI_VENC_COMMON_CFG_CHANGE_CREATE = UVC_MPI_CFG_CHANGE_BIT(0),
|
||||
MPI_VENC_COMMON_CFG_CHANGE_ROTATION = UVC_MPI_CFG_CHANGE_BIT(1),
|
||||
MPI_VENC_COMMON_CFG_CHANGE_MIRROR = UVC_MPI_CFG_CHANGE_BIT(2),
|
||||
MPI_VENC_COMMON_CFG_CHANGE_CHN_ATTR = UVC_MPI_CFG_CHANGE_BIT(3),
|
||||
MPI_VENC_COMMON_CFG_CHANGE_ALL = (0xffffffff),
|
||||
} MpiVencCommonCfgChange;
|
||||
|
||||
typedef enum _MpiVencMjpegCfgChange {
|
||||
MPI_VENC_MJPEG_CFG_CHANGE_RC_MODE = UVC_MPI_CFG_CHANGE_BIT(0),
|
||||
MPI_VENC_MJPEG_CFG_CHANGE_QFACTOR = UVC_MPI_CFG_CHANGE_BIT(1),
|
||||
MPI_VENC_MJPEG_CFG_CHANGE_QFACTOR_MIN = UVC_MPI_CFG_CHANGE_BIT(2), // reserver
|
||||
MPI_VENC_MJPEG_CFG_CHANGE_QFACTOR_MAX = UVC_MPI_CFG_CHANGE_BIT(3), // reserver
|
||||
MPI_VENC_MJPEG_CFG_CHANGE_BPS = UVC_MPI_CFG_CHANGE_BIT(4),
|
||||
MPI_VENC_MJPEG_CFG_CHANGE_FPS = UVC_MPI_CFG_CHANGE_BIT(5),
|
||||
MPI_VENC_MJPEG_CFG_CHANGE_BUF_CNT = UVC_MPI_CFG_CHANGE_BIT(6),
|
||||
MPI_VENC_MJPEG_CFG_CHANGE_SEI = UVC_MPI_CFG_CHANGE_BIT(7),
|
||||
MPI_VENC_MJPEG_CFG_CHANGE_RANGE = UVC_MPI_CFG_CHANGE_BIT(8),
|
||||
MPI_VENC_MJPEG_CFG_CHANGE_FBC = UVC_MPI_CFG_CHANGE_BIT(9),
|
||||
MPI_VENC_MJPEG_CFG_CHANGE_ALL = (0xffffffff),
|
||||
} MpiVencMjpegCfgChange;
|
||||
|
||||
typedef enum _MpiVencH264CfgChange {
|
||||
MPI_VENC_H264_CFG_CHANGE_GOP = UVC_MPI_CFG_CHANGE_BIT(0),
|
||||
MPI_VENC_H264_CFG_CHANGE_RC_MODE = UVC_MPI_CFG_CHANGE_BIT(1),
|
||||
MPI_VENC_H264_CFG_CHANGE_BPS = UVC_MPI_CFG_CHANGE_BIT(2),
|
||||
MPI_VENC_H264_CFG_CHANGE_GOP_MODE = UVC_MPI_CFG_CHANGE_BIT(3),
|
||||
MPI_VENC_H264_CFG_CHANGE_VI_LEN = UVC_MPI_CFG_CHANGE_BIT(4),
|
||||
MPI_VENC_H264_CFG_CHANGE_FPS = UVC_MPI_CFG_CHANGE_BIT(5),
|
||||
MPI_VENC_H264_CFG_CHANGE_BUF_CNT = UVC_MPI_CFG_CHANGE_BIT(6),
|
||||
MPI_VENC_H264_CFG_CHANGE_RANGE = UVC_MPI_CFG_CHANGE_BIT(7),
|
||||
MPI_VENC_H264_CFG_CHANGE_SEI = UVC_MPI_CFG_CHANGE_BIT(8),
|
||||
MPI_VENC_H264_CFG_CHANGE_PROFILE = UVC_MPI_CFG_CHANGE_BIT(9),
|
||||
MPI_VENC_H264_CFG_CHANGE_FBC = UVC_MPI_CFG_CHANGE_BIT(10),
|
||||
MPI_VENC_H264_CFG_CHANGE_QP = UVC_MPI_CFG_CHANGE_BIT(11),
|
||||
MPI_VENC_H264_CFG_CHANGE_ALL = (0xffffffff),
|
||||
} MpiVencH264CfgChange;
|
||||
|
||||
typedef enum _MpiVencH265CfgChange {
|
||||
MPI_VENC_H265_CFG_CHANGE_GOP = UVC_MPI_CFG_CHANGE_BIT(0),
|
||||
MPI_VENC_H265_CFG_CHANGE_RC_MODE = UVC_MPI_CFG_CHANGE_BIT(1),
|
||||
MPI_VENC_H265_CFG_CHANGE_BPS = UVC_MPI_CFG_CHANGE_BIT(2),
|
||||
MPI_VENC_H265_CFG_CHANGE_GOP_MODE = UVC_MPI_CFG_CHANGE_BIT(3),
|
||||
MPI_VENC_H265_CFG_CHANGE_VI_LEN = UVC_MPI_CFG_CHANGE_BIT(4),
|
||||
MPI_VENC_H265_CFG_CHANGE_FPS = UVC_MPI_CFG_CHANGE_BIT(5),
|
||||
MPI_VENC_H265_CFG_CHANGE_BUF_CNT = UVC_MPI_CFG_CHANGE_BIT(6),
|
||||
MPI_VENC_H265_CFG_CHANGE_RANGE = UVC_MPI_CFG_CHANGE_BIT(7),
|
||||
MPI_VENC_H265_CFG_CHANGE_SEI = UVC_MPI_CFG_CHANGE_BIT(8),
|
||||
MPI_VENC_H265_CFG_CHANGE_PROFILE = UVC_MPI_CFG_CHANGE_BIT(9),
|
||||
MPI_VENC_H265_CFG_CHANGE_FBC = UVC_MPI_CFG_CHANGE_BIT(10),
|
||||
MPI_VENC_H265_CFG_CHANGE_QP = UVC_MPI_CFG_CHANGE_BIT(11),
|
||||
MPI_VENC_H265_CFG_CHANGE_ALL = (0xffffffff),
|
||||
} MpiVencH265CfgChange;
|
||||
|
||||
typedef enum _MpiEptzCfgChange {
|
||||
MPI_EPTZ_CFG_CHANGE_ENABLE_EPTZ = UVC_MPI_CFG_CHANGE_BIT(0),
|
||||
MPI_EPTZ_CFG_CHANGE_ENABLE_EPTZ_BOOT = UVC_MPI_CFG_CHANGE_BIT(1),
|
||||
MPI_EPTZ_CFG_CHANGE_ENABLE_DEBUG = UVC_MPI_CFG_CHANGE_BIT(2),
|
||||
MPI_EPTZ_CFG_CHANGE_ALIGN = UVC_MPI_CFG_CHANGE_BIT(3),
|
||||
MPI_EPTZ_CFG_CHANGE_ZOOM_SPEED = UVC_MPI_CFG_CHANGE_BIT(4),
|
||||
MPI_EPTZ_CFG_CHANGE_FAST_MOVE_FRAME_JUDGE = UVC_MPI_CFG_CHANGE_BIT(5),
|
||||
MPI_EPTZ_CFG_CHANGE_ZOOM_FRAME_JUDGE = UVC_MPI_CFG_CHANGE_BIT(6),
|
||||
MPI_EPTZ_CFG_CHANGE_ITERATE_X = UVC_MPI_CFG_CHANGE_BIT(7),
|
||||
MPI_EPTZ_CFG_CHANGE_ITERATE_Y = UVC_MPI_CFG_CHANGE_BIT(8),
|
||||
MPI_EPTZ_CFG_CHANGE_RATIO = UVC_MPI_CFG_CHANGE_BIT(9),
|
||||
MPI_EPTZ_CFG_CHANGE_ALL = (0xffffffff),
|
||||
} MpiEptzCfgChange;
|
||||
|
||||
typedef enum _MpiOsdCfgChange {
|
||||
MPI_OSD_CFG_CHANGE_ENABLE_OSD = UVC_MPI_CFG_CHANGE_BIT(0),
|
||||
MPI_OSD_CFG_CHANGE_FORCE_USE_VPSS = UVC_MPI_CFG_CHANGE_BIT(1),
|
||||
MPI_OSD_CFG_CHANGE_ALL = (0xffffffff),
|
||||
} MpiOsdCfgChange;
|
||||
|
||||
typedef enum _MpiViChannelType {
|
||||
MPI_VI_CHANNEL_TYPE_UVC = 0,
|
||||
MPI_VI_CHANNEL_TYPE_NN = 1,
|
||||
MPI_VI_CHANNEL_TYPE_MAX = 2,
|
||||
} MpiViChannelType;
|
||||
|
||||
typedef enum _MpiVpssChannelType {
|
||||
MPI_VPSS_CHANNEL_TYPE_UVC = 0,
|
||||
MPI_VPSS_CHANNEL_TYPE_NN = 1,
|
||||
MPI_VPSS_CHANNEL_TYPE_MAX = 2,
|
||||
} MpiVpssChannelType;
|
||||
|
||||
typedef struct {
|
||||
RK_U32 change;
|
||||
RK_U32 channel_id;
|
||||
// idr begin
|
||||
RK_U32 idr_gop;
|
||||
RK_U32 idr_cnt;
|
||||
RK_U32 idr_bps;
|
||||
RK_U32 normal_gop;
|
||||
RK_U32 normal_bps;
|
||||
// idr end
|
||||
RK_U32 enable_vpss;
|
||||
ROTATION_E rotation;
|
||||
MIRROR_E mirror;
|
||||
} MpiVencCommonCfg;
|
||||
|
||||
typedef struct {
|
||||
RK_U32 change;
|
||||
RK_U32 qfactor_min;
|
||||
RK_U32 qfactor_max;
|
||||
RK_U32 range_full;
|
||||
RK_U32 bps;
|
||||
RK_U32 sei;
|
||||
RK_U32 buf_cnt;
|
||||
RK_S32 fps_in;
|
||||
RK_S32 fps_out;
|
||||
COMPRESS_MODE_E fbc;
|
||||
VENC_RC_MODE_E rc_mode;
|
||||
VENC_RC_PARAM_S qp;
|
||||
} MpiVencMjpegCfg;
|
||||
|
||||
typedef struct {
|
||||
RK_U32 change;
|
||||
RK_U32 gop;
|
||||
RK_U32 range_full;
|
||||
RK_U32 sei;
|
||||
RK_U32 profile;
|
||||
RK_U32 bps;
|
||||
RK_U32 buf_cnt;
|
||||
RK_S32 fps_in;
|
||||
RK_S32 fps_out;
|
||||
COMPRESS_MODE_E fbc;
|
||||
VENC_RC_MODE_E rc_mode;
|
||||
VENC_RC_PARAM_S qp;
|
||||
VENC_GOP_ATTR_S gop_mode;
|
||||
} MpiVencH264Cfg;
|
||||
|
||||
typedef struct {
|
||||
RK_U32 change;
|
||||
RK_U32 gop;
|
||||
RK_U32 range_full;
|
||||
RK_U32 sei;
|
||||
RK_U32 profile;
|
||||
RK_U32 bps;
|
||||
RK_U32 buf_cnt;
|
||||
RK_S32 fps_in;
|
||||
RK_S32 fps_out;
|
||||
COMPRESS_MODE_E fbc;
|
||||
VENC_RC_MODE_E rc_mode;
|
||||
VENC_RC_PARAM_S qp;
|
||||
VENC_GOP_ATTR_S gop_mode;
|
||||
} MpiVencH265Cfg;
|
||||
|
||||
#if 0
|
||||
#define MPP_ENC_OSD_IMAGE_PATH_LEN 32
|
||||
typedef struct {
|
||||
bool set_ok;
|
||||
bool enable; //dynamic on/off set this
|
||||
enum OSD_REGION_TYPE type;
|
||||
RK_U32 start_x;
|
||||
RK_U32 start_y;
|
||||
char image_path[MPP_ENC_OSD_IMAGE_PATH_LEN];//*image_path;//
|
||||
// for mjpeg rga osd
|
||||
RK_U32 width;
|
||||
RK_U32 height;
|
||||
int rga_osd_fd;
|
||||
unsigned int handle; // for drm handle
|
||||
uint8_t *buffer;
|
||||
int drm_size;
|
||||
// for mjpeg rga osd
|
||||
} MpiEncOSDCfg;
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
RK_U32 version;
|
||||
MpiVencCommonCfg common_cfg;
|
||||
MpiVencMjpegCfg mjpeg_cfg;
|
||||
MpiVencH264Cfg h264_cfg;
|
||||
MpiVencH265Cfg h265_cfg;
|
||||
} MpiVencCfg;
|
||||
|
||||
typedef struct {
|
||||
RK_U32 version;
|
||||
RK_U32 change;
|
||||
RK_U32 dev_id;
|
||||
RK_U32 channel_id;
|
||||
RK_U32 buf_cnt;
|
||||
RK_U32 assign_width;
|
||||
RK_U32 assign_height;
|
||||
RK_U32 min_width;
|
||||
RK_U32 min_height;
|
||||
RK_U32 max_width;
|
||||
RK_U32 max_height;
|
||||
RK_S32 fps_in;
|
||||
RK_S32 fps_out;
|
||||
PIXEL_FORMAT_E format;
|
||||
COMPRESS_MODE_E fbc;
|
||||
VI_V4L2_MEMORY_TYPE memory_type;
|
||||
ROTATION_E rotation;
|
||||
MIRROR_E mirror;
|
||||
RK_CHAR dev_name[MAX_VI_ENTITY_NAME_LEN];
|
||||
} MpiViCfg;
|
||||
|
||||
typedef struct {
|
||||
RK_U32 version;
|
||||
RK_U32 change;
|
||||
RK_U32 group_id;
|
||||
RK_U32 channel_id;
|
||||
RK_U32 buf_cnt;
|
||||
RK_S32 fps_in;
|
||||
RK_S32 fps_out;
|
||||
RK_U32 assign_width;
|
||||
RK_U32 assign_height;
|
||||
PIXEL_FORMAT_E format;
|
||||
COMPRESS_MODE_E fbc;
|
||||
ROTATION_E rotation;
|
||||
MIRROR_E mirror;
|
||||
} MpiVpssCfg;
|
||||
|
||||
typedef struct {
|
||||
RK_U32 version;
|
||||
RK_U32 change;
|
||||
RK_U32 need_check;
|
||||
RK_U32 uvc_debug_cnt;
|
||||
RK_U32 nn_debug_cnt;
|
||||
RK_U32 uvc_debug;
|
||||
RK_U32 yuyv_debug;
|
||||
RK_U32 nn_enable;
|
||||
RK_U32 geometric_output_num;
|
||||
RK_U32 geometric_output_den;
|
||||
RK_U32 uvc_enable_vpss;
|
||||
RK_U32 eptz_enable;
|
||||
RK_U32 eptz_enable_boot;
|
||||
RK_CHAR uvc_debug_file[UVC_MPI_STREAM_SAVE_FILE_LEN];
|
||||
RK_CHAR nn_debug_file[UVC_MPI_STREAM_SAVE_FILE_LEN];
|
||||
} MpiUvcCommonCfg;
|
||||
|
||||
typedef struct {
|
||||
RK_U32 version;
|
||||
RK_U32 change;
|
||||
RK_U32 enable;
|
||||
RK_U32 enable_boot;
|
||||
RK_U32 debug;
|
||||
RK_S32 align;
|
||||
RK_S32 zoom_speed;
|
||||
RK_S32 fast_move_frame_judge;
|
||||
RK_S32 zoom_frame_judge;
|
||||
RK_S32 iterate_x;
|
||||
RK_S32 iterate_y;
|
||||
RK_FLOAT ratio;
|
||||
} MpiUvcEptzCfg;
|
||||
|
||||
typedef struct {
|
||||
RK_U32 version;
|
||||
RK_U32 change;
|
||||
RK_U32 enable;
|
||||
RK_U32 force_use_vpss;
|
||||
} MpiOsdCfg;
|
||||
|
||||
typedef struct {
|
||||
RK_S32 width;
|
||||
RK_S32 height;
|
||||
RK_S32 fcc;
|
||||
RK_U32 fps;
|
||||
} MpiUvcCfg;
|
||||
|
||||
typedef struct _rkUvcMpiCfg {
|
||||
RK_U32 index;
|
||||
RK_U32 version;
|
||||
MpiUvcCfg uvc_cfg; // for uvc setting
|
||||
MpiUvcCommonCfg common_cfg;
|
||||
MpiUvcEptzCfg eptz_cfg;
|
||||
MpiOsdCfg osd_cfg;
|
||||
MpiViCfg vi_cfg[MPI_VI_CHANNEL_TYPE_MAX];
|
||||
MpiVpssCfg vpss_cfg[MPI_VPSS_CHANNEL_TYPE_MAX];
|
||||
MpiVencCfg venc_cfg;
|
||||
} UVC_MPI_CFG;
|
||||
|
||||
int check_uvc_mpi_cfg_file_init(UVC_MPI_CFG *cfg);
|
||||
void uvc_mpi_cfg_set_default(UVC_MPI_CFG *mpiCfg);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
528
project/app/uvc_app_tiny/uvc_app/uvc/uvc_mpi_venc.cpp
Executable file
528
project/app/uvc_app_tiny/uvc_app/uvc/uvc_mpi_venc.cpp
Executable file
@@ -0,0 +1,528 @@
|
||||
/*
|
||||
* Copyright (C) 2019 Rockchip Electronics Co., Ltd.
|
||||
*
|
||||
* This software is available to you under a choice of one of two
|
||||
* licenses. You may choose to be licensed under the terms of the GNU
|
||||
* General Public License (GPL), available from the file
|
||||
* COPYING in the main directory of this source tree, or the
|
||||
* OpenIB.org BSD license below:
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or
|
||||
* without modification, are permitted provided that the following
|
||||
* conditions are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer.
|
||||
*
|
||||
* - Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
#include "uvc_mpi_venc.h"
|
||||
#include "rk_mpi_sys.h"
|
||||
#include "uvc_log.h"
|
||||
#include "uvc_video.h"
|
||||
#include <cstring>
|
||||
|
||||
// config
|
||||
static RK_S32 venc_set_gopsize(VENC_RC_ATTR_S *pRcAttr, RK_U32 u32GopSize);
|
||||
static RK_S32 venc_set_bitrate(VENC_RC_ATTR_S *pRcAttr, RK_U32 u32BitRate);
|
||||
static RK_S32 venc_set_framerate(VENC_RC_ATTR_S *pRcAttr, RK_U32 u32FpsIn,
|
||||
RK_U32 u32FpsOut);
|
||||
static RK_S32 venc_set_fixqp(VENC_RC_ATTR_S *pRcAttr, RK_U32 u32FixIQp,
|
||||
RK_U32 u32FixPQp, RK_U32 u32FixBQp);
|
||||
static RK_S32 venc_set_qp(VENC_RC_ATTR_S *pRcAttr, VENC_RC_PARAM_S qp);
|
||||
static RK_S32 config_venc_chn_attr(UVC_MPI_CFG uvcCfg);
|
||||
static RK_S32 config_venc_rc_param(UVC_MPI_CFG uvcCfg);
|
||||
|
||||
UVC_VENC_CHN_CTX_S uvc_get_venc_chn_ctx(UVC_MPI_CFG uvcCfg) {
|
||||
UVC_VENC_CHN_CTX_S vencChnCtx;
|
||||
memset(&vencChnCtx, 0, sizeof(UVC_VENC_CHN_CTX_S));
|
||||
|
||||
vencChnCtx.devId = 0;
|
||||
vencChnCtx.channelId = uvcCfg.venc_cfg.common_cfg.channel_id;
|
||||
|
||||
return vencChnCtx;
|
||||
}
|
||||
|
||||
static void set_venc_mjpeg_attr(VENC_CHN_ATTR_S *vencAttr, UVC_MPI_CFG uvcCfg) {
|
||||
vencAttr->stVencAttr.enType = RK_VIDEO_ID_MJPEG;
|
||||
vencAttr->stVencAttr.u32StreamBufCnt = uvcCfg.venc_cfg.mjpeg_cfg.buf_cnt;
|
||||
vencAttr->stRcAttr.enRcMode = uvcCfg.venc_cfg.mjpeg_cfg.rc_mode;
|
||||
|
||||
venc_set_bitrate(&vencAttr->stRcAttr, uvcCfg.venc_cfg.mjpeg_cfg.bps);
|
||||
venc_set_framerate(&vencAttr->stRcAttr, uvcCfg.venc_cfg.mjpeg_cfg.fps_in,
|
||||
uvcCfg.venc_cfg.mjpeg_cfg.fps_out);
|
||||
venc_set_qp(&vencAttr->stRcAttr, uvcCfg.venc_cfg.mjpeg_cfg.qp);
|
||||
}
|
||||
|
||||
static void set_venc_h264_attr(VENC_CHN_ATTR_S *vencAttr, UVC_MPI_CFG uvcCfg) {
|
||||
vencAttr->stVencAttr.enType = RK_VIDEO_ID_AVC;
|
||||
vencAttr->stVencAttr.u32Profile = uvcCfg.venc_cfg.h264_cfg.profile;
|
||||
vencAttr->stVencAttr.u32StreamBufCnt = uvcCfg.venc_cfg.h264_cfg.buf_cnt;
|
||||
vencAttr->stRcAttr.enRcMode = uvcCfg.venc_cfg.h264_cfg.rc_mode;
|
||||
vencAttr->stGopAttr = uvcCfg.venc_cfg.h264_cfg.gop_mode;
|
||||
|
||||
venc_set_gopsize(&vencAttr->stRcAttr, uvcCfg.venc_cfg.h264_cfg.gop);
|
||||
venc_set_bitrate(&vencAttr->stRcAttr, uvcCfg.venc_cfg.h264_cfg.bps);
|
||||
venc_set_framerate(&vencAttr->stRcAttr, uvcCfg.venc_cfg.h264_cfg.fps_in,
|
||||
uvcCfg.venc_cfg.h264_cfg.fps_out);
|
||||
venc_set_qp(&vencAttr->stRcAttr, uvcCfg.venc_cfg.h264_cfg.qp);
|
||||
|
||||
LOG_INFO("venc gop:%d bps:%d\n", uvcCfg.venc_cfg.h264_cfg.gop,
|
||||
uvcCfg.venc_cfg.h264_cfg.bps);
|
||||
}
|
||||
|
||||
static void set_venc_h265_attr(VENC_CHN_ATTR_S *vencAttr, UVC_MPI_CFG uvcCfg) {
|
||||
vencAttr->stVencAttr.enType = RK_VIDEO_ID_HEVC;
|
||||
vencAttr->stVencAttr.u32Profile = uvcCfg.venc_cfg.h265_cfg.profile;
|
||||
vencAttr->stVencAttr.u32StreamBufCnt = uvcCfg.venc_cfg.h265_cfg.buf_cnt;
|
||||
vencAttr->stRcAttr.enRcMode = uvcCfg.venc_cfg.h265_cfg.rc_mode;
|
||||
vencAttr->stGopAttr = uvcCfg.venc_cfg.h265_cfg.gop_mode;
|
||||
|
||||
venc_set_gopsize(&vencAttr->stRcAttr, uvcCfg.venc_cfg.h265_cfg.gop);
|
||||
venc_set_bitrate(&vencAttr->stRcAttr, uvcCfg.venc_cfg.h265_cfg.bps);
|
||||
venc_set_framerate(&vencAttr->stRcAttr, uvcCfg.venc_cfg.h265_cfg.fps_in,
|
||||
uvcCfg.venc_cfg.h265_cfg.fps_out);
|
||||
venc_set_qp(&vencAttr->stRcAttr, uvcCfg.venc_cfg.h265_cfg.qp);
|
||||
}
|
||||
|
||||
static VENC_CHN_ATTR_S get_venc_chn_attr(UVC_MPI_CFG uvcCfg) {
|
||||
VENC_CHN_ATTR_S vencAttr;
|
||||
memset(&vencAttr, 0, sizeof(VENC_CHN_ATTR_S));
|
||||
|
||||
switch (uvcCfg.uvc_cfg.fcc) {
|
||||
case V4L2_PIX_FMT_MJPEG:
|
||||
set_venc_mjpeg_attr(&vencAttr, uvcCfg);
|
||||
break;
|
||||
case V4L2_PIX_FMT_H264:
|
||||
set_venc_h264_attr(&vencAttr, uvcCfg);
|
||||
break;
|
||||
case V4L2_PIX_FMT_H265:
|
||||
set_venc_h265_attr(&vencAttr, uvcCfg);
|
||||
break;
|
||||
default:
|
||||
LOG_ERROR("venc not support this fcc 0x%x\n", uvcCfg.uvc_cfg.fcc);
|
||||
break;
|
||||
}
|
||||
|
||||
vencAttr.stVencAttr.enPixelFormat = RK_FMT_YUV420SP;
|
||||
vencAttr.stVencAttr.enMirror = uvcCfg.venc_cfg.common_cfg.mirror;
|
||||
vencAttr.stVencAttr.u32PicWidth = uvcCfg.uvc_cfg.width;
|
||||
vencAttr.stVencAttr.u32PicHeight = uvcCfg.uvc_cfg.height;
|
||||
vencAttr.stVencAttr.u32VirWidth = uvcCfg.uvc_cfg.width;
|
||||
vencAttr.stVencAttr.u32VirHeight = uvcCfg.uvc_cfg.height;
|
||||
vencAttr.stVencAttr.u32BufSize =
|
||||
uvcCfg.uvc_cfg.width * uvcCfg.uvc_cfg.height * 2;
|
||||
|
||||
return vencAttr;
|
||||
}
|
||||
|
||||
static VENC_RC_PARAM_S get_venc_rc_param(UVC_MPI_CFG uvcCfg) {
|
||||
VENC_RC_PARAM_S vencRcParam;
|
||||
memset(&vencRcParam, 0, sizeof(VENC_RC_PARAM_S));
|
||||
|
||||
switch (uvcCfg.uvc_cfg.fcc) {
|
||||
case V4L2_PIX_FMT_MJPEG:
|
||||
vencRcParam = uvcCfg.venc_cfg.mjpeg_cfg.qp;
|
||||
break;
|
||||
case V4L2_PIX_FMT_H264:
|
||||
vencRcParam = uvcCfg.venc_cfg.h264_cfg.qp;
|
||||
break;
|
||||
case V4L2_PIX_FMT_H265:
|
||||
vencRcParam = uvcCfg.venc_cfg.h265_cfg.qp;
|
||||
break;
|
||||
default:
|
||||
LOG_ERROR("venc not support this fcc 0x%x\n", uvcCfg.uvc_cfg.fcc);
|
||||
break;
|
||||
}
|
||||
|
||||
return vencRcParam;
|
||||
}
|
||||
|
||||
static RK_S32 config_venc_chn_attr(UVC_MPI_CFG uvcCfg) {
|
||||
RK_S32 s32Ret = RK_FAILURE;
|
||||
UVC_VENC_CHN_CTX_S vencChnCtx = uvc_get_venc_chn_ctx(uvcCfg);
|
||||
VENC_CHN_ATTR_S vencAttr = get_venc_chn_attr(uvcCfg);
|
||||
|
||||
s32Ret = RK_MPI_VENC_SetChnAttr(vencChnCtx.channelId, &vencAttr);
|
||||
|
||||
return s32Ret;
|
||||
}
|
||||
|
||||
static RK_S32 config_venc_rc_param(UVC_MPI_CFG uvcCfg) {
|
||||
RK_S32 s32Ret = RK_FAILURE;
|
||||
UVC_VENC_CHN_CTX_S vencChnCtx = uvc_get_venc_chn_ctx(uvcCfg);
|
||||
VENC_RC_PARAM_S vencRcParam = get_venc_rc_param(uvcCfg);
|
||||
|
||||
s32Ret = RK_MPI_VENC_SetRcParam(vencChnCtx.channelId, &vencRcParam);
|
||||
|
||||
return s32Ret;
|
||||
}
|
||||
|
||||
static RK_S32 venc_set_bitrate(VENC_RC_ATTR_S *pRcAttr, RK_U32 u32BitRate) {
|
||||
switch (pRcAttr->enRcMode) {
|
||||
case VENC_RC_MODE_MJPEGCBR:
|
||||
pRcAttr->stMjpegCbr.u32BitRate = u32BitRate;
|
||||
break;
|
||||
case VENC_RC_MODE_H264CBR:
|
||||
pRcAttr->stH264Cbr.u32BitRate = u32BitRate;
|
||||
break;
|
||||
case VENC_RC_MODE_H265CBR:
|
||||
pRcAttr->stH265Cbr.u32BitRate = u32BitRate;
|
||||
break;
|
||||
case VENC_RC_MODE_MJPEGVBR:
|
||||
pRcAttr->stMjpegVbr.u32BitRate = u32BitRate;
|
||||
break;
|
||||
case VENC_RC_MODE_H264VBR:
|
||||
pRcAttr->stH264Vbr.u32BitRate = u32BitRate;
|
||||
break;
|
||||
case VENC_RC_MODE_H265VBR:
|
||||
pRcAttr->stH265Vbr.u32BitRate = u32BitRate;
|
||||
break;
|
||||
case VENC_RC_MODE_H264AVBR:
|
||||
pRcAttr->stH264Avbr.u32BitRate = u32BitRate;
|
||||
break;
|
||||
case VENC_RC_MODE_H265AVBR:
|
||||
pRcAttr->stH265Avbr.u32BitRate = u32BitRate;
|
||||
break;
|
||||
default:
|
||||
return RK_ERR_VENC_NOT_SUPPORT;
|
||||
}
|
||||
|
||||
return RK_SUCCESS;
|
||||
}
|
||||
|
||||
static RK_S32 venc_set_gopsize(VENC_RC_ATTR_S *pRcAttr, RK_U32 u32GopSize) {
|
||||
switch (pRcAttr->enRcMode) {
|
||||
case VENC_RC_MODE_H264CBR:
|
||||
pRcAttr->stH264Cbr.u32Gop = u32GopSize;
|
||||
break;
|
||||
case VENC_RC_MODE_H265CBR:
|
||||
pRcAttr->stH265Cbr.u32Gop = u32GopSize;
|
||||
break;
|
||||
case VENC_RC_MODE_H264VBR:
|
||||
pRcAttr->stH264Vbr.u32Gop = u32GopSize;
|
||||
break;
|
||||
case VENC_RC_MODE_H265VBR:
|
||||
pRcAttr->stH265Vbr.u32Gop = u32GopSize;
|
||||
break;
|
||||
case VENC_RC_MODE_H264AVBR:
|
||||
pRcAttr->stH264Avbr.u32Gop = u32GopSize;
|
||||
break;
|
||||
case VENC_RC_MODE_H265AVBR:
|
||||
pRcAttr->stH265Avbr.u32Gop = u32GopSize;
|
||||
break;
|
||||
case VENC_RC_MODE_H264FIXQP:
|
||||
pRcAttr->stH264FixQp.u32Gop = u32GopSize;
|
||||
break;
|
||||
case VENC_RC_MODE_H265FIXQP:
|
||||
pRcAttr->stH265FixQp.u32Gop = u32GopSize;
|
||||
break;
|
||||
default:
|
||||
return RK_ERR_VENC_NOT_SUPPORT;
|
||||
}
|
||||
|
||||
return RK_SUCCESS;
|
||||
}
|
||||
|
||||
static RK_S32 venc_set_framerate(VENC_RC_ATTR_S *pRcAttr, RK_U32 u32FpsIn,
|
||||
RK_U32 u32FpsOut) {
|
||||
switch (pRcAttr->enRcMode) {
|
||||
case VENC_RC_MODE_MJPEGCBR:
|
||||
pRcAttr->stMjpegCbr.u32SrcFrameRateNum = u32FpsIn;
|
||||
pRcAttr->stMjpegCbr.u32SrcFrameRateDen = 1;
|
||||
pRcAttr->stMjpegCbr.fr32DstFrameRateNum = u32FpsOut;
|
||||
pRcAttr->stMjpegCbr.fr32DstFrameRateDen = 1;
|
||||
break;
|
||||
case VENC_RC_MODE_H264CBR:
|
||||
pRcAttr->stH264Cbr.u32SrcFrameRateNum = u32FpsIn;
|
||||
pRcAttr->stH264Cbr.u32SrcFrameRateDen = 1;
|
||||
pRcAttr->stH264Cbr.fr32DstFrameRateNum = u32FpsOut;
|
||||
pRcAttr->stH264Cbr.fr32DstFrameRateDen = 1;
|
||||
break;
|
||||
case VENC_RC_MODE_H265CBR:
|
||||
pRcAttr->stH265Cbr.u32SrcFrameRateNum = u32FpsIn;
|
||||
pRcAttr->stH265Cbr.u32SrcFrameRateDen = 1;
|
||||
pRcAttr->stH265Cbr.fr32DstFrameRateNum = u32FpsOut;
|
||||
pRcAttr->stH265Cbr.fr32DstFrameRateDen = 1;
|
||||
break;
|
||||
case VENC_RC_MODE_MJPEGVBR:
|
||||
pRcAttr->stMjpegVbr.u32SrcFrameRateNum = u32FpsIn;
|
||||
pRcAttr->stMjpegVbr.u32SrcFrameRateDen = 1;
|
||||
pRcAttr->stMjpegVbr.fr32DstFrameRateNum = u32FpsOut;
|
||||
pRcAttr->stMjpegVbr.fr32DstFrameRateDen = 1;
|
||||
break;
|
||||
case VENC_RC_MODE_H264VBR:
|
||||
pRcAttr->stH264Vbr.u32SrcFrameRateNum = u32FpsIn;
|
||||
pRcAttr->stH264Vbr.u32SrcFrameRateDen = 1;
|
||||
pRcAttr->stH264Vbr.fr32DstFrameRateNum = u32FpsOut;
|
||||
pRcAttr->stH264Vbr.fr32DstFrameRateDen = 1;
|
||||
break;
|
||||
case VENC_RC_MODE_H265VBR:
|
||||
pRcAttr->stH265Vbr.u32SrcFrameRateNum = u32FpsIn;
|
||||
pRcAttr->stH265Vbr.u32SrcFrameRateDen = 1;
|
||||
pRcAttr->stH265Vbr.fr32DstFrameRateNum = u32FpsOut;
|
||||
pRcAttr->stH265Vbr.fr32DstFrameRateDen = 1;
|
||||
break;
|
||||
case VENC_RC_MODE_H264AVBR:
|
||||
pRcAttr->stH264Avbr.u32SrcFrameRateNum = u32FpsIn;
|
||||
pRcAttr->stH264Avbr.u32SrcFrameRateDen = 1;
|
||||
pRcAttr->stH264Avbr.fr32DstFrameRateNum = u32FpsOut;
|
||||
pRcAttr->stH264Avbr.fr32DstFrameRateDen = 1;
|
||||
break;
|
||||
case VENC_RC_MODE_H265AVBR:
|
||||
pRcAttr->stH265Avbr.u32SrcFrameRateNum = u32FpsIn;
|
||||
pRcAttr->stH265Avbr.u32SrcFrameRateDen = 1;
|
||||
pRcAttr->stH265Avbr.fr32DstFrameRateNum = u32FpsOut;
|
||||
pRcAttr->stH265Avbr.fr32DstFrameRateDen = 1;
|
||||
break;
|
||||
case VENC_RC_MODE_MJPEGFIXQP:
|
||||
pRcAttr->stMjpegFixQp.u32SrcFrameRateNum = u32FpsIn;
|
||||
pRcAttr->stMjpegFixQp.u32SrcFrameRateDen = 1;
|
||||
pRcAttr->stMjpegFixQp.fr32DstFrameRateNum = u32FpsOut;
|
||||
pRcAttr->stMjpegFixQp.fr32DstFrameRateDen = 1;
|
||||
break;
|
||||
case VENC_RC_MODE_H264FIXQP:
|
||||
pRcAttr->stH264FixQp.u32SrcFrameRateNum = u32FpsIn;
|
||||
pRcAttr->stH264FixQp.u32SrcFrameRateDen = 1;
|
||||
pRcAttr->stH264FixQp.fr32DstFrameRateNum = u32FpsOut;
|
||||
pRcAttr->stH264FixQp.fr32DstFrameRateDen = 1;
|
||||
break;
|
||||
case VENC_RC_MODE_H265FIXQP:
|
||||
pRcAttr->stH265FixQp.u32SrcFrameRateNum = u32FpsIn;
|
||||
pRcAttr->stH265FixQp.u32SrcFrameRateDen = 1;
|
||||
pRcAttr->stH265FixQp.fr32DstFrameRateNum = u32FpsOut;
|
||||
pRcAttr->stH265FixQp.fr32DstFrameRateDen = 1;
|
||||
break;
|
||||
|
||||
default:
|
||||
return RK_ERR_VENC_NOT_SUPPORT;
|
||||
}
|
||||
|
||||
return RK_SUCCESS;
|
||||
}
|
||||
|
||||
static RK_S32 venc_set_fixqp(VENC_RC_ATTR_S *pRcAttr, RK_U32 u32FixIQp,
|
||||
RK_U32 u32FixPQp, RK_U32 u32FixBQp) {
|
||||
switch (pRcAttr->enRcMode) {
|
||||
case VENC_RC_MODE_MJPEGFIXQP:
|
||||
pRcAttr->stMjpegFixQp.u32Qfactor = u32FixIQp;
|
||||
break;
|
||||
case VENC_RC_MODE_H264FIXQP:
|
||||
pRcAttr->stH264FixQp.u32IQp = u32FixIQp;
|
||||
pRcAttr->stH264FixQp.u32PQp = u32FixPQp;
|
||||
pRcAttr->stH264FixQp.u32BQp = u32FixBQp;
|
||||
break;
|
||||
case VENC_RC_MODE_H265FIXQP:
|
||||
pRcAttr->stH265FixQp.u32IQp = u32FixIQp;
|
||||
pRcAttr->stH265FixQp.u32PQp = u32FixPQp;
|
||||
pRcAttr->stH265FixQp.u32BQp = u32FixBQp;
|
||||
break;
|
||||
default:
|
||||
return RK_ERR_VENC_NOT_SUPPORT;
|
||||
}
|
||||
|
||||
return RK_SUCCESS;
|
||||
}
|
||||
|
||||
static RK_S32 venc_set_qp(VENC_RC_ATTR_S *pRcAttr, VENC_RC_PARAM_S qp) {
|
||||
switch (pRcAttr->enRcMode) {
|
||||
case VENC_RC_MODE_MJPEGFIXQP:
|
||||
venc_set_fixqp(pRcAttr, qp.stParamMjpeg.u32Qfactor,
|
||||
qp.stParamMjpeg.u32Qfactor, qp.stParamMjpeg.u32Qfactor);
|
||||
break;
|
||||
case VENC_RC_MODE_H264FIXQP:
|
||||
venc_set_fixqp(pRcAttr, qp.stParamH264.u32MinIQp, qp.stParamH264.u32MinQp,
|
||||
qp.stParamH264.u32MinQp);
|
||||
break;
|
||||
case VENC_RC_MODE_H265FIXQP:
|
||||
venc_set_fixqp(pRcAttr, qp.stParamH265.u32MinIQp, qp.stParamH265.u32MinQp,
|
||||
qp.stParamH265.u32MinQp);
|
||||
break;
|
||||
case VENC_RC_MODE_MJPEGCBR:
|
||||
case VENC_RC_MODE_MJPEGVBR:
|
||||
case VENC_RC_MODE_H264CBR:
|
||||
case VENC_RC_MODE_H264VBR:
|
||||
case VENC_RC_MODE_H264AVBR:
|
||||
case VENC_RC_MODE_H265CBR:
|
||||
case VENC_RC_MODE_H265VBR:
|
||||
case VENC_RC_MODE_H265AVBR:
|
||||
// just call RK_MPI_VENC_SetRcParam
|
||||
break;
|
||||
default:
|
||||
return RK_ERR_VENC_NOT_SUPPORT;
|
||||
}
|
||||
|
||||
return RK_SUCCESS;
|
||||
}
|
||||
|
||||
static RK_S32 config_venc_common(UVC_MPI_CFG *uvcCfg) {
|
||||
RK_S32 s32Ret = RK_FAILURE;
|
||||
UVC_VENC_CHN_CTX_S vencChnCtx = uvc_get_venc_chn_ctx(*uvcCfg);
|
||||
|
||||
if (uvcCfg->venc_cfg.common_cfg.change & MPI_VENC_COMMON_CFG_CHANGE_CREATE) {
|
||||
VENC_CHN_ATTR_S vencAttr = get_venc_chn_attr(*uvcCfg);
|
||||
s32Ret = RK_MPI_VENC_CreateChn(vencChnCtx.channelId, &vencAttr);
|
||||
if (s32Ret != RK_SUCCESS) {
|
||||
LOG_ERROR("RK_MPI_VENC_CreateChn fail 0x%x\n", s32Ret);
|
||||
goto __FAILED;
|
||||
} else {
|
||||
LOG_INFO("RK_MPI_VENC_CreateChn %d\n", vencChnCtx.channelId);
|
||||
}
|
||||
uvcCfg->venc_cfg.common_cfg.change &= (~MPI_VENC_COMMON_CFG_CHANGE_CREATE);
|
||||
uvcCfg->venc_cfg.common_cfg.change &=
|
||||
(~MPI_VENC_COMMON_CFG_CHANGE_CHN_ATTR);
|
||||
} else {
|
||||
if (uvcCfg->venc_cfg.common_cfg.change &
|
||||
MPI_VENC_COMMON_CFG_CHANGE_CHN_ATTR) {
|
||||
s32Ret = config_venc_chn_attr(*uvcCfg);
|
||||
if (s32Ret != RK_SUCCESS) {
|
||||
LOG_ERROR("config_venc_chn_attr fail 0x%x\n", s32Ret);
|
||||
goto __FAILED;
|
||||
} else {
|
||||
LOG_INFO("config_venc_chn_attr %d\n", vencChnCtx.channelId);
|
||||
}
|
||||
uvcCfg->venc_cfg.common_cfg.change &=
|
||||
(~MPI_VENC_COMMON_CFG_CHANGE_CHN_ATTR);
|
||||
}
|
||||
}
|
||||
if (uvcCfg->venc_cfg.common_cfg.change &
|
||||
MPI_VENC_COMMON_CFG_CHANGE_ROTATION) {
|
||||
s32Ret = RK_MPI_VENC_SetChnRotation(vencChnCtx.channelId,
|
||||
uvcCfg->venc_cfg.common_cfg.rotation);
|
||||
if (s32Ret != RK_SUCCESS) {
|
||||
LOG_ERROR("RK_MPI_VENC_CreateChn fail 0x%x\n", s32Ret);
|
||||
goto __FAILED;
|
||||
}
|
||||
uvcCfg->venc_cfg.common_cfg.change &=
|
||||
(~MPI_VENC_COMMON_CFG_CHANGE_ROTATION);
|
||||
}
|
||||
|
||||
__FAILED:
|
||||
return s32Ret;
|
||||
}
|
||||
|
||||
static RK_S32 config_venc_mjpeg(UVC_MPI_CFG *uvcCfg) {
|
||||
RK_S32 s32Ret = RK_FAILURE;
|
||||
|
||||
if (uvcCfg->venc_cfg.mjpeg_cfg.change & MPI_VENC_MJPEG_CFG_CHANGE_QFACTOR) {
|
||||
s32Ret = config_venc_rc_param(*uvcCfg);
|
||||
if (s32Ret != RK_SUCCESS) {
|
||||
LOG_ERROR("RK_MPI_VENC_CreateChn fail 0x%x\n", s32Ret);
|
||||
goto __FAILED;
|
||||
}
|
||||
uvcCfg->venc_cfg.mjpeg_cfg.change &= (~MPI_VENC_MJPEG_CFG_CHANGE_QFACTOR);
|
||||
}
|
||||
|
||||
__FAILED:
|
||||
return s32Ret;
|
||||
}
|
||||
|
||||
static RK_S32 config_venc_h264(UVC_MPI_CFG *uvcCfg) {
|
||||
RK_S32 s32Ret = RK_FAILURE;
|
||||
|
||||
if (uvcCfg->venc_cfg.h264_cfg.change & MPI_VENC_H264_CFG_CHANGE_QP) {
|
||||
s32Ret = config_venc_rc_param(*uvcCfg);
|
||||
if (s32Ret != RK_SUCCESS) {
|
||||
LOG_ERROR("RK_MPI_VENC_CreateChn fail 0x%x\n", s32Ret);
|
||||
goto __FAILED;
|
||||
}
|
||||
uvcCfg->venc_cfg.h264_cfg.change &= (~MPI_VENC_H264_CFG_CHANGE_QP);
|
||||
}
|
||||
|
||||
__FAILED:
|
||||
return s32Ret;
|
||||
}
|
||||
|
||||
static RK_S32 config_venc_h265(UVC_MPI_CFG *uvcCfg) {
|
||||
RK_S32 s32Ret = RK_FAILURE;
|
||||
|
||||
if (uvcCfg->venc_cfg.h265_cfg.change & MPI_VENC_H265_CFG_CHANGE_QP) {
|
||||
s32Ret = config_venc_rc_param(*uvcCfg);
|
||||
if (s32Ret != RK_SUCCESS) {
|
||||
LOG_ERROR("RK_MPI_VENC_CreateChn fail 0x%x\n", s32Ret);
|
||||
goto __FAILED;
|
||||
}
|
||||
uvcCfg->venc_cfg.h265_cfg.change &= (~MPI_VENC_H265_CFG_CHANGE_QP);
|
||||
}
|
||||
|
||||
__FAILED:
|
||||
return s32Ret;
|
||||
}
|
||||
|
||||
RK_S32 uvc_venc_config(UVC_MPI_CFG *uvcCfg) {
|
||||
RK_S32 s32Ret = RK_FAILURE;
|
||||
|
||||
config_venc_common(uvcCfg);
|
||||
|
||||
switch (uvcCfg->uvc_cfg.fcc) {
|
||||
case V4L2_PIX_FMT_MJPEG:
|
||||
config_venc_mjpeg(uvcCfg);
|
||||
break;
|
||||
case V4L2_PIX_FMT_H264:
|
||||
config_venc_h264(uvcCfg);
|
||||
break;
|
||||
case V4L2_PIX_FMT_H265:
|
||||
config_venc_h265(uvcCfg);
|
||||
break;
|
||||
default:
|
||||
LOG_ERROR("venc not support this fcc 0x%x\n", uvcCfg->uvc_cfg.fcc);
|
||||
break;
|
||||
}
|
||||
|
||||
__FAILED:
|
||||
return s32Ret;
|
||||
}
|
||||
|
||||
RK_S32 uvc_venc_start(UVC_MPI_CFG uvcCfg) {
|
||||
RK_S32 s32Ret = RK_FAILURE;
|
||||
VENC_RECV_PIC_PARAM_S stRecvParam;
|
||||
UVC_VENC_CHN_CTX_S vencChnCtx = uvc_get_venc_chn_ctx(uvcCfg);
|
||||
|
||||
stRecvParam.s32RecvPicNum = -1;
|
||||
LOG_INFO("RK_MPI_VENC_StartRecvFrame %d\n", vencChnCtx.channelId);
|
||||
s32Ret = RK_MPI_VENC_StartRecvFrame(vencChnCtx.channelId, &stRecvParam);
|
||||
if (s32Ret != RK_SUCCESS) {
|
||||
LOG_ERROR("RK_MPI_VENC_StartRecvFrame fail 0x%x\n", s32Ret);
|
||||
goto __FAILED;
|
||||
}
|
||||
|
||||
__FAILED:
|
||||
return s32Ret;
|
||||
}
|
||||
|
||||
RK_S32 uvc_venc_stop(UVC_MPI_CFG uvcCfg) {
|
||||
RK_S32 s32Ret = RK_FAILURE;
|
||||
UVC_VENC_CHN_CTX_S vencChnCtx = uvc_get_venc_chn_ctx(uvcCfg);
|
||||
|
||||
s32Ret = RK_MPI_VENC_StopRecvFrame(vencChnCtx.channelId);
|
||||
if (s32Ret != RK_SUCCESS) {
|
||||
return s32Ret;
|
||||
}
|
||||
LOG_INFO("reset enc chn:%d\n", vencChnCtx.channelId);
|
||||
s32Ret = RK_MPI_VENC_ResetChn(vencChnCtx.channelId);
|
||||
if (s32Ret != RK_SUCCESS) {
|
||||
return s32Ret;
|
||||
}
|
||||
LOG_INFO("destroy enc chn:%d\n", vencChnCtx.channelId);
|
||||
s32Ret = RK_MPI_VENC_DestroyChn(vencChnCtx.channelId);
|
||||
if (s32Ret != RK_SUCCESS) {
|
||||
LOG_ERROR("RK_MPI_VDEC_DestroyChn :%d fail %x", vencChnCtx.channelId,
|
||||
s32Ret);
|
||||
}
|
||||
|
||||
__FAILED:
|
||||
return s32Ret;
|
||||
}
|
||||
50
project/app/uvc_app_tiny/uvc_app/uvc/uvc_mpi_venc.h
Normal file
50
project/app/uvc_app_tiny/uvc_app/uvc/uvc_mpi_venc.h
Normal file
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright (C) 2019 Rockchip Electronics Co., Ltd.
|
||||
*
|
||||
* This software is available to you under a choice of one of two
|
||||
* licenses. You may choose to be licensed under the terms of the GNU
|
||||
* General Public License (GPL), available from the file
|
||||
* COPYING in the main directory of this source tree, or the
|
||||
* OpenIB.org BSD license below:
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or
|
||||
* without modification, are permitted provided that the following
|
||||
* conditions are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer.
|
||||
*
|
||||
* - Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef __UVC_MPI_VENC_H__
|
||||
#define __UVC_MPI_VENC_H__
|
||||
|
||||
#include "rk_mpi_venc.h"
|
||||
#include "uvc_mpi_config.h"
|
||||
|
||||
typedef struct _uvcVencChnCtx {
|
||||
RK_S32 devId;
|
||||
RK_S32 channelId;
|
||||
} UVC_VENC_CHN_CTX_S;
|
||||
|
||||
UVC_VENC_CHN_CTX_S uvc_get_venc_chn_ctx(UVC_MPI_CFG uvcCfg);
|
||||
|
||||
RK_S32 uvc_venc_config(UVC_MPI_CFG *uvcCfg);
|
||||
RK_S32 uvc_venc_start(UVC_MPI_CFG uvcCfg);
|
||||
RK_S32 uvc_venc_stop(UVC_MPI_CFG uvcCfg);
|
||||
|
||||
#endif
|
||||
259
project/app/uvc_app_tiny/uvc_app/uvc/uvc_mpi_vi.cpp
Normal file
259
project/app/uvc_app_tiny/uvc_app/uvc/uvc_mpi_vi.cpp
Normal file
@@ -0,0 +1,259 @@
|
||||
/*
|
||||
* Copyright (C) 2019 Rockchip Electronics Co., Ltd.
|
||||
*
|
||||
* This software is available to you under a choice of one of two
|
||||
* licenses. You may choose to be licensed under the terms of the GNU
|
||||
* General Public License (GPL), available from the file
|
||||
* COPYING in the main directory of this source tree, or the
|
||||
* OpenIB.org BSD license below:
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or
|
||||
* without modification, are permitted provided that the following
|
||||
* conditions are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer.
|
||||
*
|
||||
* - Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
#include "uvc_mpi_vi.h"
|
||||
#include "rk_mpi_sys.h"
|
||||
#include "rk_mpi_vi.h"
|
||||
#include "uvc_log.h"
|
||||
#include "uvc_video.h"
|
||||
#include <cstring>
|
||||
|
||||
typedef struct _rkMpiVICtx {
|
||||
UVC_VI_CHN_CTX_S stChnCtx;
|
||||
COMPRESS_MODE_E enCompressMode;
|
||||
VI_DEV_ATTR_S stDevAttr;
|
||||
VI_DEV_BIND_PIPE_S stBindPipe;
|
||||
VI_CHN_ATTR_S stChnAttr;
|
||||
VI_CHN_STATUS_S stChnStatus;
|
||||
} MPI_VI_CTX_S;
|
||||
|
||||
UVC_VI_CHN_CTX_S uvc_get_vi_chn_ctx(UVC_MPI_CFG uvcCfg,
|
||||
MpiViChannelType chnType) {
|
||||
UVC_VI_CHN_CTX_S viChnCtx;
|
||||
memset(&viChnCtx, 0, sizeof(UVC_VI_CHN_CTX_S));
|
||||
|
||||
viChnCtx.devId = uvcCfg.vi_cfg[chnType].dev_id;
|
||||
viChnCtx.pipeId = viChnCtx.devId;
|
||||
viChnCtx.channelId = uvcCfg.vi_cfg[chnType].channel_id;
|
||||
|
||||
return viChnCtx;
|
||||
}
|
||||
|
||||
static MPI_VI_CTX_S uvc_get_vi_ctx(UVC_MPI_CFG *uvcCfg,
|
||||
MpiViChannelType chnType) {
|
||||
MPI_VI_CTX_S viCtx;
|
||||
memset(&viCtx, 0, sizeof(MPI_VI_CTX_S));
|
||||
|
||||
LOG_INFO("chnType:%d uvc out:%dx%d, vi assign_resolution:%dx%d vi_name:%s\n",
|
||||
chnType, uvcCfg->uvc_cfg.width, uvcCfg->uvc_cfg.height,
|
||||
uvcCfg->vi_cfg[chnType].assign_width,
|
||||
uvcCfg->vi_cfg[chnType].assign_height,
|
||||
uvcCfg->vi_cfg[chnType].dev_name);
|
||||
|
||||
// this is for uvc vi/nn vi different cfg.
|
||||
switch (chnType) {
|
||||
case MPI_VI_CHANNEL_TYPE_UVC:
|
||||
if (uvcCfg->vi_cfg[chnType].assign_width <= 0 ||
|
||||
uvcCfg->vi_cfg[chnType].assign_height <=
|
||||
0) { // not assign the vi uvc output
|
||||
if (uvcCfg->uvc_cfg.width < uvcCfg->vi_cfg[chnType].min_width ||
|
||||
uvcCfg->uvc_cfg.height <
|
||||
uvcCfg->vi_cfg[chnType]
|
||||
.min_height) { // not support this resolution(too small)
|
||||
uvcCfg->vi_cfg[chnType].assign_width =
|
||||
uvcCfg->vi_cfg[chnType].min_width;
|
||||
uvcCfg->vi_cfg[chnType].assign_height =
|
||||
uvcCfg->vi_cfg[chnType].min_height;
|
||||
LOG_INFO("uvc out:%dx%d, the min resolution:%dx%d\n",
|
||||
uvcCfg->uvc_cfg.width, uvcCfg->uvc_cfg.height,
|
||||
uvcCfg->vi_cfg[chnType].min_width,
|
||||
uvcCfg->vi_cfg[chnType].min_height);
|
||||
} else if (uvcCfg->uvc_cfg.width > uvcCfg->vi_cfg[chnType].max_width ||
|
||||
uvcCfg->uvc_cfg.height >
|
||||
uvcCfg->vi_cfg[chnType].max_height) { // not support this
|
||||
// resolution(too
|
||||
// large)
|
||||
uvcCfg->vi_cfg[chnType].assign_width =
|
||||
uvcCfg->vi_cfg[chnType].max_width;
|
||||
uvcCfg->vi_cfg[chnType].assign_height =
|
||||
uvcCfg->vi_cfg[chnType].max_height;
|
||||
LOG_INFO("uvc out:%dx%d, the max resolution:%dx%d\n",
|
||||
uvcCfg->uvc_cfg.width, uvcCfg->uvc_cfg.height,
|
||||
uvcCfg->vi_cfg[chnType].max_width,
|
||||
uvcCfg->vi_cfg[chnType].max_height);
|
||||
} else {
|
||||
uvcCfg->vi_cfg[chnType].assign_width = uvcCfg->uvc_cfg.width;
|
||||
uvcCfg->vi_cfg[chnType].assign_height = uvcCfg->uvc_cfg.height;
|
||||
}
|
||||
}
|
||||
|
||||
switch (uvcCfg->uvc_cfg.fcc) {
|
||||
case V4L2_PIX_FMT_YUYV:
|
||||
case V4L2_PIX_FMT_NV12: // reserver
|
||||
#if 0
|
||||
if (uvcCfg->uvc_cfg.width == 1280) {
|
||||
LOG_ERROR("vi workaround and here alloc 1 buf count!!!\n");
|
||||
uvcCfg->vi_cfg[chnType].buf_cnt =
|
||||
1; // workaround for 1280*720 vpss stuck
|
||||
}
|
||||
#endif
|
||||
viCtx.stChnAttr.enPixelFormat =
|
||||
uvcCfg->vi_cfg[chnType].format; // RK_FMT_YUV422_YUYV;
|
||||
viCtx.stChnAttr.u32Depth = 0; // viCtx.stChnAttr.stIspOpt.u32BufCount; //
|
||||
// bind 0; not bind u32BufCount;
|
||||
break;
|
||||
case V4L2_PIX_FMT_MJPEG:
|
||||
case V4L2_PIX_FMT_H264:
|
||||
case V4L2_PIX_FMT_H265:
|
||||
viCtx.stChnAttr.enPixelFormat = RK_FMT_YUV420SP;
|
||||
viCtx.stChnAttr.u32Depth = 0; // bind 0; not bind u32BufCount;
|
||||
break;
|
||||
default:
|
||||
LOG_ERROR("vi not support this fcc 0x%x\n", uvcCfg->uvc_cfg.fcc);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case MPI_VI_CHANNEL_TYPE_NN:
|
||||
viCtx.stChnAttr.enPixelFormat = uvcCfg->vi_cfg[chnType].format;
|
||||
viCtx.stChnAttr.u32Depth = 0;
|
||||
break;
|
||||
default:
|
||||
LOG_ERROR("vi not support this chnType 0x%x\n", chnType);
|
||||
break;
|
||||
}
|
||||
|
||||
// common cfg
|
||||
viCtx.stChnCtx = uvc_get_vi_chn_ctx(*uvcCfg, chnType);
|
||||
viCtx.stChnAttr.stIspOpt.bNoUseLibV4L2 = RK_FALSE;
|
||||
viCtx.stChnAttr.stIspOpt.u32BufCount = uvcCfg->vi_cfg[chnType].buf_cnt;
|
||||
viCtx.stChnAttr.stIspOpt.u32BufSize =
|
||||
0; // uvcCfg.vi_cfg[chnType].width * uvcCfg.vi_cfg[chnType].height * 2;
|
||||
// uvcCfg.uvc_cfg.width * uvcCfg.uvc_cfg.height;
|
||||
viCtx.stChnAttr.stIspOpt.enMemoryType = uvcCfg->vi_cfg[chnType].memory_type;
|
||||
if (strncmp(uvcCfg->vi_cfg[chnType].dev_name, "null", strlen("null"))) {
|
||||
memcpy(viCtx.stChnAttr.stIspOpt.aEntityName,
|
||||
uvcCfg->vi_cfg[chnType].dev_name,
|
||||
strlen(uvcCfg->vi_cfg[chnType].dev_name));
|
||||
}
|
||||
viCtx.stChnAttr.stFrameRate.s32SrcFrameRate =
|
||||
uvcCfg->vi_cfg[chnType].fps_in > 0 ? uvcCfg->vi_cfg[chnType].fps_in : -1;
|
||||
viCtx.stChnAttr.stFrameRate.s32DstFrameRate =
|
||||
uvcCfg->vi_cfg[chnType].fps_out > 0 ? uvcCfg->vi_cfg[chnType].fps_out
|
||||
: -1;
|
||||
viCtx.stChnAttr.stSize.u32Width = uvcCfg->vi_cfg[chnType].assign_width;
|
||||
viCtx.stChnAttr.stSize.u32Height = uvcCfg->vi_cfg[chnType].assign_height;
|
||||
LOG_INFO("chnType:%d uvc out:%dx%d, vi resolution:%dx%d name:%s\n", chnType,
|
||||
uvcCfg->uvc_cfg.width, uvcCfg->uvc_cfg.height,
|
||||
viCtx.stChnAttr.stSize.u32Width, viCtx.stChnAttr.stSize.u32Height,
|
||||
viCtx.stChnAttr.stIspOpt.aEntityName);
|
||||
|
||||
return viCtx;
|
||||
}
|
||||
|
||||
// todo: multi vi from cfg.
|
||||
RK_S32 uvc_vi_config(UVC_MPI_CFG *uvcCfg, MpiViChannelType chnType) {
|
||||
RK_S32 s32Ret = RK_FAILURE;
|
||||
MPI_VI_CTX_S ctx;
|
||||
ctx = uvc_get_vi_ctx(uvcCfg, chnType);
|
||||
|
||||
// 0. get dev config status
|
||||
s32Ret = RK_MPI_VI_GetDevAttr(ctx.stChnCtx.devId, &ctx.stDevAttr);
|
||||
if (s32Ret == RK_ERR_VI_NOT_CONFIG) {
|
||||
// 0-1.config dev
|
||||
s32Ret = RK_MPI_VI_SetDevAttr(ctx.stChnCtx.devId, &ctx.stDevAttr);
|
||||
if (s32Ret != RK_SUCCESS) {
|
||||
LOG_ERROR("RK_MPI_VI_SetDevAttr %x\n", s32Ret);
|
||||
goto __FAILED;
|
||||
}
|
||||
}
|
||||
// 1.get dev enable status
|
||||
s32Ret = RK_MPI_VI_GetDevIsEnable(ctx.stChnCtx.devId);
|
||||
if (s32Ret != RK_SUCCESS) {
|
||||
// 1-2.enable dev
|
||||
s32Ret = RK_MPI_VI_EnableDev(ctx.stChnCtx.devId);
|
||||
if (s32Ret != RK_SUCCESS) {
|
||||
LOG_ERROR("RK_MPI_VI_EnableDev %x\n", s32Ret);
|
||||
goto __FAILED;
|
||||
}
|
||||
// 1-3.bind dev/pipe
|
||||
ctx.stBindPipe.u32Num = ctx.stChnCtx.pipeId;
|
||||
ctx.stBindPipe.PipeId[0] = ctx.stChnCtx.pipeId;
|
||||
s32Ret = RK_MPI_VI_SetDevBindPipe(ctx.stChnCtx.devId, &ctx.stBindPipe);
|
||||
if (s32Ret != RK_SUCCESS) {
|
||||
LOG_ERROR("RK_MPI_VI_SetDevBindPipe %x\n", s32Ret);
|
||||
goto __FAILED;
|
||||
}
|
||||
}
|
||||
// 2.config channel
|
||||
s32Ret = RK_MPI_VI_SetChnAttr(ctx.stChnCtx.pipeId, ctx.stChnCtx.channelId,
|
||||
&ctx.stChnAttr);
|
||||
if (s32Ret != RK_SUCCESS) {
|
||||
LOG_ERROR("RK_MPI_VI_SetChnAttr %x\n", s32Ret);
|
||||
goto __FAILED;
|
||||
}
|
||||
|
||||
__FAILED:
|
||||
return s32Ret;
|
||||
}
|
||||
|
||||
RK_S32 uvc_vi_start(UVC_MPI_CFG uvcCfg, MpiViChannelType chnType) {
|
||||
RK_S32 s32Ret = RK_FAILURE;
|
||||
UVC_VI_CHN_CTX_S ctx;
|
||||
ctx = uvc_get_vi_chn_ctx(uvcCfg, chnType);
|
||||
|
||||
// isp&aiq init here
|
||||
|
||||
// 3.enable channel
|
||||
LOG_INFO("RK_MPI_VI_EnableChn %x %d %d\n", ctx.devId, ctx.pipeId,
|
||||
ctx.channelId);
|
||||
s32Ret = RK_MPI_VI_EnableChn(ctx.pipeId, ctx.channelId);
|
||||
if (s32Ret != RK_SUCCESS) {
|
||||
LOG_ERROR("RK_MPI_VI_EnableChn %x\n", s32Ret);
|
||||
goto __FAILED;
|
||||
}
|
||||
|
||||
__FAILED:
|
||||
return s32Ret;
|
||||
}
|
||||
|
||||
RK_S32 uvc_vi_stop(UVC_MPI_CFG uvcCfg, MpiViChannelType chnType) {
|
||||
RK_S32 s32Ret = RK_FAILURE;
|
||||
UVC_VI_CHN_CTX_S ctx;
|
||||
ctx = uvc_get_vi_chn_ctx(uvcCfg, chnType);
|
||||
|
||||
// 5. disable one chn
|
||||
s32Ret = RK_MPI_VI_DisableChn(ctx.pipeId, ctx.channelId);
|
||||
if (s32Ret != RK_SUCCESS) {
|
||||
LOG_ERROR("RK_MPI_VI_DisableChn %x\n", s32Ret);
|
||||
goto __FAILED;
|
||||
}
|
||||
// 6.disable dev(will diabled all chn)
|
||||
s32Ret = RK_MPI_VI_DisableDev(ctx.devId);
|
||||
if (s32Ret != RK_SUCCESS) {
|
||||
LOG_ERROR("RK_MPI_VI_DisableDev %x\n", s32Ret);
|
||||
goto __FAILED;
|
||||
}
|
||||
|
||||
// isp&aiq deinit here
|
||||
|
||||
__FAILED:
|
||||
return s32Ret;
|
||||
}
|
||||
50
project/app/uvc_app_tiny/uvc_app/uvc/uvc_mpi_vi.h
Normal file
50
project/app/uvc_app_tiny/uvc_app/uvc/uvc_mpi_vi.h
Normal file
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright (C) 2019 Rockchip Electronics Co., Ltd.
|
||||
*
|
||||
* This software is available to you under a choice of one of two
|
||||
* licenses. You may choose to be licensed under the terms of the GNU
|
||||
* General Public License (GPL), available from the file
|
||||
* COPYING in the main directory of this source tree, or the
|
||||
* OpenIB.org BSD license below:
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or
|
||||
* without modification, are permitted provided that the following
|
||||
* conditions are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer.
|
||||
*
|
||||
* - Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef __UVC_MPI_VI_H__
|
||||
#define __UVC_MPI_VI_H__
|
||||
|
||||
#include "uvc_mpi_config.h"
|
||||
|
||||
typedef struct _uvcViChnCtx {
|
||||
RK_S32 devId;
|
||||
RK_S32 pipeId;
|
||||
RK_S32 channelId;
|
||||
} UVC_VI_CHN_CTX_S;
|
||||
|
||||
RK_S32 uvc_vi_config(UVC_MPI_CFG *uvcCfg, MpiViChannelType chnType);
|
||||
RK_S32 uvc_vi_start(UVC_MPI_CFG uvcCfg, MpiViChannelType chnType);
|
||||
RK_S32 uvc_vi_stop(UVC_MPI_CFG uvcCfg, MpiViChannelType chnType);
|
||||
UVC_VI_CHN_CTX_S uvc_get_vi_chn_ctx(UVC_MPI_CFG uvcCfg,
|
||||
MpiViChannelType chnType);
|
||||
|
||||
#endif
|
||||
215
project/app/uvc_app_tiny/uvc_app/uvc/uvc_mpi_vpss.cpp
Executable file
215
project/app/uvc_app_tiny/uvc_app/uvc/uvc_mpi_vpss.cpp
Executable file
@@ -0,0 +1,215 @@
|
||||
/*
|
||||
* Copyright (C) 2019 Rockchip Electronics Co., Ltd.
|
||||
*
|
||||
* This software is available to you under a choice of one of two
|
||||
* licenses. You may choose to be licensed under the terms of the GNU
|
||||
* General Public License (GPL), available from the file
|
||||
* COPYING in the main directory of this source tree, or the
|
||||
* OpenIB.org BSD license below:
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or
|
||||
* without modification, are permitted provided that the following
|
||||
* conditions are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer.
|
||||
*
|
||||
* - Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
#include "uvc_mpi_vpss.h"
|
||||
#include "rk_mpi_sys.h"
|
||||
#include "rk_mpi_vpss.h"
|
||||
#include "uvc_log.h"
|
||||
#include "uvc_video.h"
|
||||
#include <cstring>
|
||||
|
||||
typedef struct _rkVpssCfg {
|
||||
RK_U32 u32VpssChnCnt;
|
||||
VPSS_GRP_ATTR_S stGrpVpssAttr;
|
||||
VPSS_CHN_ATTR_S stVpssChnAttr[VPSS_MAX_CHN_NUM];
|
||||
} VPSS_CFG_S;
|
||||
|
||||
typedef struct _rkMpiVpssCtx {
|
||||
UVC_VPSS_CHN_CTX_S stChnCtx;
|
||||
VPSS_CFG_S stVpssCfg;
|
||||
} MPI_VPSS_CTX_S;
|
||||
|
||||
UVC_VPSS_CHN_CTX_S uvc_get_vpss_chn_ctx(UVC_MPI_CFG uvcCfg,
|
||||
MpiVpssChannelType chnType) {
|
||||
UVC_VPSS_CHN_CTX_S vpssChnCtx;
|
||||
memset(&vpssChnCtx, 0, sizeof(UVC_VPSS_CHN_CTX_S));
|
||||
|
||||
vpssChnCtx.group = uvcCfg.vpss_cfg[chnType].group_id;
|
||||
vpssChnCtx.channelId = uvcCfg.vpss_cfg[chnType].channel_id;
|
||||
|
||||
return vpssChnCtx;
|
||||
}
|
||||
|
||||
// todo: read cfg
|
||||
static MPI_VPSS_CTX_S uvc_get_vpss_ctx(UVC_MPI_CFG uvcCfg,
|
||||
MpiVpssChannelType chnType) {
|
||||
MPI_VPSS_CTX_S vpssCtx;
|
||||
PIXEL_FORMAT_E outFormat = RK_FMT_YUV420SP;
|
||||
int chn = uvcCfg.vpss_cfg[chnType].channel_id;
|
||||
|
||||
memset(&vpssCtx, 0, sizeof(MPI_VPSS_CTX_S));
|
||||
switch (chnType) {
|
||||
case MPI_VPSS_CHANNEL_TYPE_UVC:
|
||||
switch (uvcCfg.uvc_cfg.fcc) {
|
||||
case V4L2_PIX_FMT_YUYV:
|
||||
outFormat = RK_FMT_YUV422_YUYV;
|
||||
vpssCtx.stVpssCfg.stVpssChnAttr[chn].u32Depth =
|
||||
uvcCfg.vpss_cfg[chnType].buf_cnt;
|
||||
break;
|
||||
case V4L2_PIX_FMT_NV12:
|
||||
outFormat = RK_FMT_YUV420SP;
|
||||
vpssCtx.stVpssCfg.stVpssChnAttr[chn].u32Depth =
|
||||
uvcCfg.vpss_cfg[chnType].buf_cnt;
|
||||
break;
|
||||
case V4L2_PIX_FMT_MJPEG:
|
||||
case V4L2_PIX_FMT_H264:
|
||||
case V4L2_PIX_FMT_H265:
|
||||
outFormat = RK_FMT_YUV420SP;
|
||||
vpssCtx.stVpssCfg.stVpssChnAttr[chn].u32Depth = 0; // bind venc.
|
||||
break;
|
||||
default:
|
||||
LOG_ERROR("vpss not support this fcc 0x%x\n", uvcCfg.uvc_cfg.fcc);
|
||||
break;
|
||||
}
|
||||
vpssCtx.stVpssCfg.stVpssChnAttr[chn].u32Width = uvcCfg.uvc_cfg.width;
|
||||
vpssCtx.stVpssCfg.stVpssChnAttr[chn].u32Height = uvcCfg.uvc_cfg.height;
|
||||
break;
|
||||
case MPI_VPSS_CHANNEL_TYPE_NN:
|
||||
outFormat = uvcCfg.vpss_cfg[chnType].format;
|
||||
vpssCtx.stVpssCfg.stVpssChnAttr[chn].u32Width =
|
||||
uvcCfg.vpss_cfg[chnType].assign_width;
|
||||
vpssCtx.stVpssCfg.stVpssChnAttr[chn].u32Height =
|
||||
uvcCfg.vpss_cfg[chnType].assign_height;
|
||||
vpssCtx.stVpssCfg.stVpssChnAttr[chn].u32Depth =
|
||||
uvcCfg.vpss_cfg[chnType].buf_cnt;
|
||||
break;
|
||||
default:
|
||||
LOG_ERROR("vpss not support this type 0x%x\n", chnType);
|
||||
break;
|
||||
}
|
||||
|
||||
vpssCtx.stChnCtx = uvc_get_vpss_chn_ctx(uvcCfg, chnType);
|
||||
vpssCtx.stVpssCfg.stGrpVpssAttr.u32MaxW = 4096;
|
||||
vpssCtx.stVpssCfg.stGrpVpssAttr.u32MaxH = 4096;
|
||||
vpssCtx.stVpssCfg.stGrpVpssAttr.enPixelFormat = outFormat;
|
||||
vpssCtx.stVpssCfg.stGrpVpssAttr.stFrameRate.s32SrcFrameRate =
|
||||
uvcCfg.vpss_cfg[chnType].fps_in;
|
||||
vpssCtx.stVpssCfg.stGrpVpssAttr.stFrameRate.s32DstFrameRate =
|
||||
uvcCfg.vpss_cfg[chnType].fps_out;
|
||||
vpssCtx.stVpssCfg.stGrpVpssAttr.enCompressMode = uvcCfg.vpss_cfg[chnType].fbc;
|
||||
{ // chn
|
||||
vpssCtx.stVpssCfg.stVpssChnAttr[chn].enChnMode = VPSS_CHN_MODE_USER;
|
||||
vpssCtx.stVpssCfg.stVpssChnAttr[chn].enDynamicRange = DYNAMIC_RANGE_SDR8;
|
||||
vpssCtx.stVpssCfg.stVpssChnAttr[chn].enPixelFormat = outFormat;
|
||||
vpssCtx.stVpssCfg.stVpssChnAttr[chn].stFrameRate.s32SrcFrameRate = -1;
|
||||
vpssCtx.stVpssCfg.stVpssChnAttr[chn].stFrameRate.s32DstFrameRate = -1;
|
||||
vpssCtx.stVpssCfg.stVpssChnAttr[chn].enCompressMode =
|
||||
uvcCfg.vpss_cfg[chnType].fbc;
|
||||
vpssCtx.stVpssCfg.stVpssChnAttr[chn].u32FrameBufCnt =
|
||||
uvcCfg.vpss_cfg[chnType].buf_cnt;
|
||||
}
|
||||
|
||||
return vpssCtx;
|
||||
}
|
||||
|
||||
RK_S32 uvc_vpss_config(UVC_MPI_CFG *uvcCfg, MpiVpssChannelType chnType) {
|
||||
RK_S32 s32Ret = RK_FAILURE;
|
||||
MPI_VPSS_CTX_S ctx;
|
||||
ctx = uvc_get_vpss_ctx(*uvcCfg, chnType);
|
||||
|
||||
s32Ret =
|
||||
RK_MPI_VPSS_CreateGrp(ctx.stChnCtx.group, &ctx.stVpssCfg.stGrpVpssAttr);
|
||||
if (s32Ret != RK_SUCCESS) {
|
||||
LOG_ERROR("RK_MPI_VPSS_CreateGrp fail 0x%x\n", s32Ret);
|
||||
return s32Ret;
|
||||
}
|
||||
|
||||
s32Ret = RK_MPI_VPSS_SetChnAttr(
|
||||
ctx.stChnCtx.group, ctx.stChnCtx.channelId,
|
||||
&ctx.stVpssCfg.stVpssChnAttr[ctx.stChnCtx.channelId]);
|
||||
if (s32Ret != RK_SUCCESS) {
|
||||
LOG_ERROR("RK_MPI_VPSS_SetChnAttr fail 0x%x\n", s32Ret);
|
||||
return s32Ret;
|
||||
}
|
||||
|
||||
return RK_SUCCESS;
|
||||
}
|
||||
|
||||
// from the data.
|
||||
RK_S32 uvc_vpss_config_crop(UVC_MPI_CFG uvcCfg, VPSS_CROP_INFO_S stCropInfo,
|
||||
MpiVpssChannelType chnType) {
|
||||
RK_S32 s32Ret = RK_FAILURE;
|
||||
UVC_VPSS_CHN_CTX_S ctx;
|
||||
ctx = uvc_get_vpss_chn_ctx(uvcCfg, chnType);
|
||||
|
||||
s32Ret = RK_MPI_VPSS_SetChnCrop(ctx.group, ctx.channelId, &stCropInfo);
|
||||
if (s32Ret != RK_SUCCESS) {
|
||||
LOG_ERROR("RK_MPI_VPSS_SetChnCrop fail 0x%x\n", s32Ret);
|
||||
return s32Ret;
|
||||
}
|
||||
|
||||
return RK_SUCCESS;
|
||||
}
|
||||
|
||||
RK_S32 uvc_vpss_start(UVC_MPI_CFG uvcCfg, MpiVpssChannelType chnType) {
|
||||
RK_S32 s32Ret = RK_FAILURE;
|
||||
UVC_VPSS_CHN_CTX_S ctx;
|
||||
ctx = uvc_get_vpss_chn_ctx(uvcCfg, chnType);
|
||||
|
||||
s32Ret = RK_MPI_VPSS_EnableChn(ctx.group, ctx.channelId);
|
||||
if (s32Ret != RK_SUCCESS) {
|
||||
LOG_ERROR("RK_MPI_VPSS_EnableChn fail 0x%x\n", s32Ret);
|
||||
return s32Ret;
|
||||
}
|
||||
s32Ret = RK_MPI_VPSS_StartGrp(ctx.group);
|
||||
if (s32Ret != RK_SUCCESS) {
|
||||
LOG_ERROR("RK_MPI_VPSS_StartGrp fail 0x%x\n", s32Ret);
|
||||
return s32Ret;
|
||||
}
|
||||
|
||||
return RK_SUCCESS;
|
||||
}
|
||||
|
||||
RK_S32 uvc_vpss_stop(UVC_MPI_CFG uvcCfg, MpiVpssChannelType chnType) {
|
||||
RK_S32 s32Ret = RK_FAILURE;
|
||||
UVC_VPSS_CHN_CTX_S ctx;
|
||||
ctx = uvc_get_vpss_chn_ctx(uvcCfg, chnType);
|
||||
|
||||
s32Ret = RK_MPI_VPSS_StopGrp(ctx.group);
|
||||
if (s32Ret != RK_SUCCESS) {
|
||||
LOG_ERROR("RK_MPI_VPSS_StopGrp fail 0x%x\n", s32Ret);
|
||||
return s32Ret;
|
||||
}
|
||||
|
||||
s32Ret = RK_MPI_VPSS_DisableChn(ctx.group, ctx.channelId);
|
||||
if (s32Ret != RK_SUCCESS) {
|
||||
LOG_ERROR("RK_MPI_VPSS_DisableChn fail 0x%x\n", s32Ret);
|
||||
return s32Ret;
|
||||
}
|
||||
|
||||
s32Ret = RK_MPI_VPSS_DestroyGrp(ctx.group);
|
||||
if (s32Ret != RK_SUCCESS) {
|
||||
LOG_ERROR("RK_MPI_VPSS_DestroyGrp fail 0x%x\n", s32Ret);
|
||||
return s32Ret;
|
||||
}
|
||||
|
||||
return RK_SUCCESS;
|
||||
}
|
||||
59
project/app/uvc_app_tiny/uvc_app/uvc/uvc_mpi_vpss.h
Executable file
59
project/app/uvc_app_tiny/uvc_app/uvc/uvc_mpi_vpss.h
Executable file
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright (C) 2019 Rockchip Electronics Co., Ltd.
|
||||
*
|
||||
* This software is available to you under a choice of one of two
|
||||
* licenses. You may choose to be licensed under the terms of the GNU
|
||||
* General Public License (GPL), available from the file
|
||||
* COPYING in the main directory of this source tree, or the
|
||||
* OpenIB.org BSD license below:
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or
|
||||
* without modification, are permitted provided that the following
|
||||
* conditions are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer.
|
||||
*
|
||||
* - Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef __UVC_MPI_VPSS_H__
|
||||
#define __UVC_MPI_VPSS_H__
|
||||
|
||||
#include "uvc_mpi_config.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct _uvcVpssChnCtx {
|
||||
RK_S32 group;
|
||||
RK_S32 channelId;
|
||||
} UVC_VPSS_CHN_CTX_S;
|
||||
|
||||
RK_S32 uvc_vpss_config(UVC_MPI_CFG *uvcCfg, MpiVpssChannelType chnType);
|
||||
RK_S32 uvc_vpss_config_crop(UVC_MPI_CFG uvcCfg, VPSS_CROP_INFO_S stCropInfo,
|
||||
MpiVpssChannelType chnType);
|
||||
RK_S32 uvc_vpss_start(UVC_MPI_CFG uvcCfg, MpiVpssChannelType chnType);
|
||||
RK_S32 uvc_vpss_stop(UVC_MPI_CFG uvcCfg, MpiVpssChannelType chnType);
|
||||
UVC_VPSS_CHN_CTX_S uvc_get_vpss_chn_ctx(UVC_MPI_CFG uvcCfg,
|
||||
MpiVpssChannelType chnType);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
1036
project/app/uvc_app_tiny/uvc_app/uvc/uvc_process.cpp
Normal file
1036
project/app/uvc_app_tiny/uvc_app/uvc/uvc_process.cpp
Normal file
File diff suppressed because it is too large
Load Diff
83
project/app/uvc_app_tiny/uvc_app/uvc/uvc_process.h
Executable file
83
project/app/uvc_app_tiny/uvc_app/uvc/uvc_process.h
Executable file
@@ -0,0 +1,83 @@
|
||||
/*
|
||||
* Copyright (C) 2019 Rockchip Electronics Co., Ltd.
|
||||
*
|
||||
* This software is available to you under a choice of one of two
|
||||
* licenses. You may choose to be licensed under the terms of the GNU
|
||||
* General Public License (GPL), available from the file
|
||||
* COPYING in the main directory of this source tree, or the
|
||||
* OpenIB.org BSD license below:
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or
|
||||
* without modification, are permitted provided that the following
|
||||
* conditions are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer.
|
||||
*
|
||||
* - Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef __UVC_PROCESS_H__
|
||||
#define __UVC_PROCESS_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#include "rk_comm_video.h"
|
||||
#include "uvc_process_unit.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
class UVCProcess {
|
||||
public:
|
||||
explicit UVCProcess();
|
||||
~UVCProcess();
|
||||
void *getCtx() { return mCtx; }
|
||||
int configProcess(UVC_CTRL_INFO uvc_ctrl_info);
|
||||
int startProcess();
|
||||
int stopProcess();
|
||||
int doProcess();
|
||||
int releaseFrame(void *frame);
|
||||
|
||||
private:
|
||||
int initialize();
|
||||
int deinitialize();
|
||||
int configVi();
|
||||
int startVi();
|
||||
int stopVi();
|
||||
int configVenc();
|
||||
int startVenc();
|
||||
int stopVenc();
|
||||
int resetCtx();
|
||||
int configVpss();
|
||||
int configCropScale(RECT_S src, RECT_S dst);
|
||||
int startVpss();
|
||||
int stopVpss();
|
||||
int bindViVenc();
|
||||
int unBindViVenc();
|
||||
int bindViVpss();
|
||||
int unBindViVpss();
|
||||
int bindVpssVenc();
|
||||
int unBindVpssVenc();
|
||||
static void *threadLoop(void *arg);
|
||||
|
||||
private:
|
||||
void *mCtx;
|
||||
};
|
||||
|
||||
#endif
|
||||
86
project/app/uvc_app_tiny/uvc_app/uvc/uvc_process_unit.h
Executable file
86
project/app/uvc_app_tiny/uvc_app/uvc/uvc_process_unit.h
Executable file
@@ -0,0 +1,86 @@
|
||||
/*
|
||||
* Copyright (C) 2019 Rockchip Electronics Co., Ltd.
|
||||
*
|
||||
* This software is available to you under a choice of one of two
|
||||
* licenses. You may choose to be licensed under the terms of the GNU
|
||||
* General Public License (GPL), available from the file
|
||||
* COPYING in the main directory of this source tree, or the
|
||||
* OpenIB.org BSD license below:
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or
|
||||
* without modification, are permitted provided that the following
|
||||
* conditions are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer.
|
||||
*
|
||||
* - Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef __UVC_PROCESS_UNIT_H__
|
||||
#define __UVC_PROCESS_UNIT_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define CAM_MAX_NUM 3
|
||||
|
||||
typedef enum _UVC_EPTZ_TYPE {
|
||||
UVC_EPTZ_ZOOM = 0,
|
||||
UVC_EPTZ_PAN = 1,
|
||||
UVC_EPTZ_TILT = 2,
|
||||
UVC_EPTZ_ROLL = 3, // reserve
|
||||
UVC_EPTZ_AUTO = 4,
|
||||
UVC_EPTZ_MAX,
|
||||
} UVC_EPTZ_TYPE;
|
||||
|
||||
typedef enum _UVC_RATIO_TYPE {
|
||||
VERTICAL = 0,
|
||||
HORIZONTAL = 1,
|
||||
UVC_RATIO_MAX,
|
||||
} UVC_RATIO_TYPE;
|
||||
|
||||
typedef enum _UVC_RET_TYPE {
|
||||
UVC_RET_ERR = -1,
|
||||
UVC_RET_OK = 0,
|
||||
UVC_RET_WAT = 1,
|
||||
UVC_RET_MAX,
|
||||
} UVC_RET_TYPE;
|
||||
|
||||
typedef struct uvc_ctrl_info {
|
||||
int index;
|
||||
int width;
|
||||
int height;
|
||||
int video_id;
|
||||
int fcc;
|
||||
unsigned int fps;
|
||||
UVC_EPTZ_TYPE type;
|
||||
int eptz[UVC_EPTZ_MAX];
|
||||
} UVC_CTRL_INFO;
|
||||
|
||||
int uvc_process_config(UVC_CTRL_INFO uvc_ctrl_info);
|
||||
int uvc_process_start(UVC_CTRL_INFO uvc_ctrl_info);
|
||||
void uvc_process_stop(UVC_CTRL_INFO uvc_ctrl_info);
|
||||
void uvc_process_delete(UVC_CTRL_INFO uvcCtrlInfo);
|
||||
int uvc_process_release_frame(UVC_CTRL_INFO uvcCtrlInfo, void *frame);
|
||||
int nn_process_release_frame_by_id(int frameId);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
1155
project/app/uvc_app_tiny/uvc_app/uvc/uvc_video.cpp
Normal file
1155
project/app/uvc_app_tiny/uvc_app/uvc/uvc_video.cpp
Normal file
File diff suppressed because it is too large
Load Diff
156
project/app/uvc_app_tiny/uvc_app/uvc/uvc_video.h
Executable file
156
project/app/uvc_app_tiny/uvc_app/uvc/uvc_video.h
Executable file
@@ -0,0 +1,156 @@
|
||||
/*
|
||||
* Copyright (C) 2019 Rockchip Electronics Co., Ltd.
|
||||
*
|
||||
* This software is available to you under a choice of one of two
|
||||
* licenses. You may choose to be licensed under the terms of the GNU
|
||||
* General Public License (GPL), available from the file
|
||||
* COPYING in the main directory of this source tree, or the
|
||||
* OpenIB.org BSD license below:
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or
|
||||
* without modification, are permitted provided that the following
|
||||
* conditions are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer.
|
||||
*
|
||||
* - Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef __UVC_VIDEO_H__
|
||||
#define __UVC_VIDEO_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "uvc-gadget.h"
|
||||
#include <linux/videodev2.h>
|
||||
#include <pthread.h>
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#define V4L2_PIX_FMT_H265 \
|
||||
v4l2_fourcc('H', '2', '6', '5') /* H265 with start codes */
|
||||
|
||||
#define YUYV_AS_RAW 0
|
||||
|
||||
#define UVC_DYNAMIC_DEBUG_USE_TIME 1 // release version can set to 0
|
||||
#define UVC_DYNAMIC_DEBUG_USE_TIME_CHECK "/tmp/uvc_use_time"
|
||||
|
||||
#define UVC_DYNAMIC_DEBUG_FPS 1 // release version can set to 0
|
||||
#define UVC_DYNAMIC_DEBUG_ISP_FPS_CHECK "/tmp/uvc_isp_fps"
|
||||
#define UVC_DYNAMIC_DEBUG_IPC_FPS_CHECK "/tmp/uvc_ipc_fps"
|
||||
|
||||
#if UVC_DYNAMIC_DEBUG_FPS
|
||||
struct uvc_debug_info_def {
|
||||
bool first_frm;
|
||||
bool debug_isp_fps;
|
||||
bool debug_ipc_fps;
|
||||
float fps;
|
||||
int ipc_frm;
|
||||
int isp_frm;
|
||||
struct timeval enter_time;
|
||||
unsigned int stream_on_pts;
|
||||
};
|
||||
|
||||
extern struct uvc_debug_info_def uvc_debug_info;
|
||||
#endif
|
||||
|
||||
struct uvc_device;
|
||||
|
||||
struct uvc_buffer {
|
||||
void *buffer;
|
||||
size_t size; // encode out size
|
||||
size_t total_size;
|
||||
unsigned int offset;
|
||||
int width;
|
||||
int height;
|
||||
int video_id;
|
||||
int fd;
|
||||
unsigned int pts;
|
||||
unsigned int seq;
|
||||
int index;
|
||||
void *frame;
|
||||
};
|
||||
|
||||
struct uvc_user {
|
||||
unsigned int width;
|
||||
unsigned int height;
|
||||
bool run;
|
||||
unsigned int fcc;
|
||||
};
|
||||
|
||||
struct uvc_video {
|
||||
int id;
|
||||
bool uvc_process;
|
||||
pthread_t uvc_pid;
|
||||
struct video_uvc *uvc;
|
||||
pthread_mutex_t buffer_mutex;
|
||||
pthread_mutex_t user_mutex;
|
||||
struct uvc_user uvc_user;
|
||||
int uvc_buf_cnt;
|
||||
int idle_cnt;
|
||||
int drop_frame_cnt;
|
||||
bool can_exit;
|
||||
unsigned int last_pts;
|
||||
unsigned int now_pts;
|
||||
unsigned int last_seq;
|
||||
struct uvc_device *dev;
|
||||
};
|
||||
|
||||
int uvc_gadget_pthread_create(struct uvc_function_config *fc);
|
||||
|
||||
int uvc_video_id_check(int id);
|
||||
int uvc_video_id_add(struct uvc_function_config *fc);
|
||||
void uvc_video_id_remove(int id);
|
||||
void uvc_video_id_exit_all();
|
||||
int uvc_video_id_get(unsigned int seq);
|
||||
|
||||
void uvc_video_set_uvc_process(int id, bool state);
|
||||
bool uvc_video_get_uvc_process(int id);
|
||||
|
||||
int uvc_buffer_init(struct uvc_device *dev);
|
||||
void uvc_buffer_deinit(int id);
|
||||
bool uvc_buffer_write_enable(int id);
|
||||
void uvc_set_user_resolution(int width, int height, int id);
|
||||
void uvc_get_user_resolution(int *width, int *height, int id);
|
||||
bool uvc_get_user_run_state(int id);
|
||||
void uvc_set_user_run_state(bool state, int id);
|
||||
void uvc_set_user_fcc(unsigned int fcc, int id);
|
||||
unsigned int uvc_get_user_fcc(int id);
|
||||
void uvc_memset_uvc_user(int id);
|
||||
pthread_t *uvc_video_get_uvc_pid(int id);
|
||||
struct uvc_buffer *uvc_user_fill_buffer(struct uvc_device *dev,
|
||||
struct v4l2_buffer *buf, int id);
|
||||
struct uvc_buffer *uvc_get_enc_data(struct uvc_device *dev, struct uvc_video *v,
|
||||
bool init);
|
||||
int uvc_video_qbuf_index(struct uvc_device *dev, struct uvc_buffer *send_buf,
|
||||
int index, int len);
|
||||
void uvc_user_release_cache_buffer(struct uvc_device *dev,
|
||||
struct v4l2_buffer *buf, int id);
|
||||
bool uvc_buffer_read_enable(int id);
|
||||
struct uvc_buffer *uvc_buffer_write_get(int id);
|
||||
void uvc_buffer_write_set(int id, struct uvc_buffer *buf);
|
||||
void uvc_buffer_read_set(int id, struct uvc_buffer *buf);
|
||||
void uvc_buffer_cache_set(int id, struct uvc_buffer *buf);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
212
project/app/uvc_app_tiny/uvc_app/uvc_mpi_cfg.conf
Normal file
212
project/app/uvc_app_tiny/uvc_app/uvc_mpi_cfg.conf
Normal file
@@ -0,0 +1,212 @@
|
||||
{
|
||||
"index_0": {
|
||||
"version" : 1,
|
||||
"common_cfg": {
|
||||
"version" : 1,
|
||||
"property" : {
|
||||
"param_init": {
|
||||
"check_param_change_thread": "off",
|
||||
"uvc_debug": "off",
|
||||
"yuyv_debug": "off",
|
||||
"nn_enable": "off",
|
||||
"uvc_debug_file_name": "/data/uvc.bin",
|
||||
"uvc_debug_file_cnt": 0,
|
||||
"nn_debug_file_name": "/data/nn.bin",
|
||||
"nn_debug_file_cnt": 0,
|
||||
"uvc_enable_vpss": "on",
|
||||
"geometric_output": "16:9"
|
||||
},
|
||||
"param_change": {
|
||||
}
|
||||
}
|
||||
},
|
||||
"eptz_cfg": {
|
||||
"version" : 1,
|
||||
"param_init": {
|
||||
"enable": "on",
|
||||
"enable_boot": "off",
|
||||
"debug": "off"
|
||||
},
|
||||
"param_change": {
|
||||
}
|
||||
},
|
||||
"vi_cfg": {
|
||||
"version" : 1,
|
||||
"uvc" : {
|
||||
"param_init": {
|
||||
"dev_id": 0,
|
||||
"channel_id": 1,
|
||||
"buf_cnt": 1,
|
||||
"assign_width": 0,
|
||||
"assign_height": 0,
|
||||
"min_width": 640,
|
||||
"min_height": 480,
|
||||
"max_width": 1920,
|
||||
"max_height": 1080,
|
||||
"format": "nv12",
|
||||
"dev_name": "null",
|
||||
"fps": "0:0",
|
||||
"memory_type": 4,
|
||||
"fbc": "off",
|
||||
"rotation": 0,
|
||||
"mirror": 0
|
||||
},
|
||||
"param_change": {
|
||||
}
|
||||
},
|
||||
"nn" : {
|
||||
"param_init": {
|
||||
"dev_id": 0,
|
||||
"channel_id": 1,
|
||||
"assign_width": 512,
|
||||
"assign_height": 288,
|
||||
"format": "nv12",
|
||||
"buf_cnt": 1,
|
||||
"dev_name": "null",
|
||||
"fps": "0:0",
|
||||
"memory_type": 4,
|
||||
"fbc": "off",
|
||||
"rotation": 0,
|
||||
"mirror": 0
|
||||
},
|
||||
"param_change": {
|
||||
}
|
||||
}
|
||||
},
|
||||
"vpss_cfg": {
|
||||
"version" : 1,
|
||||
"uvc" : {
|
||||
"param_init": {
|
||||
"group_id": 0,
|
||||
"channel_id": 0,
|
||||
"buf_cnt": 1,
|
||||
"fps": "0:0",
|
||||
"fbc": "off",
|
||||
"rotation": 0,
|
||||
"mirror": 0
|
||||
},
|
||||
"param_change": {
|
||||
}
|
||||
},
|
||||
"nn" : {
|
||||
"param_init": {
|
||||
"group_id": 1,
|
||||
"channel_id": 0,
|
||||
"format": "bgr888",
|
||||
"assign_width": 512,
|
||||
"assign_height": 288,
|
||||
"buf_cnt": 1,
|
||||
"fps": "0:0",
|
||||
"fbc": "off",
|
||||
"rotation": 0,
|
||||
"mirror": 0
|
||||
},
|
||||
"param_change": {
|
||||
}
|
||||
}
|
||||
},
|
||||
"venc_cfg": {
|
||||
"version" : 1,
|
||||
"common" : {
|
||||
"param_init": {
|
||||
"channel_id": 1,
|
||||
"rotation": 0,
|
||||
"mirror": 0
|
||||
},
|
||||
"param_change": {
|
||||
}
|
||||
},
|
||||
"mjpeg": {
|
||||
"param_init": {
|
||||
"default": {
|
||||
"buf_cnt": 1,
|
||||
"fbc": "off",
|
||||
"rc_mode": "fixqp",
|
||||
"fps": "0:0",
|
||||
"range": "full",
|
||||
"sei": "off",
|
||||
"qfactor": 85,
|
||||
"qfactor_min": 30,
|
||||
"qfactor_max": 99,
|
||||
"bps": 60000
|
||||
},
|
||||
"1280*720p30": {
|
||||
"qfactor": 80,
|
||||
"qfactor_min": 60,
|
||||
"qfactor_max": 90,
|
||||
"bps": 70000
|
||||
},
|
||||
"1920*1080p30": {
|
||||
"qfactor": 75,
|
||||
"qfactor_min": 50,
|
||||
"qfactor_max": 90,
|
||||
"bps": 80000
|
||||
}
|
||||
},
|
||||
"param_change": {
|
||||
}
|
||||
},
|
||||
"h264" : {
|
||||
"param_init": {
|
||||
"default": {
|
||||
"buf_cnt": 2,
|
||||
"fbc": "off",
|
||||
"gop": 60,
|
||||
"rc_mode": "cbr",
|
||||
"fps": "0:0",
|
||||
"range": "full",
|
||||
"qp": "26:4:20:40:8:48:2:1",
|
||||
"sei": "off",
|
||||
"profile": 100,
|
||||
"vi_len": 30,
|
||||
"gop_mode": 0,
|
||||
"bps": 10000,
|
||||
"force_idr": "5:5:20000"
|
||||
},
|
||||
"1920*1080p30": {
|
||||
"bps": 10000,
|
||||
"force_idr": "5:5:30000"
|
||||
}
|
||||
},
|
||||
"param_change": {
|
||||
}
|
||||
},
|
||||
"h265" : {
|
||||
"param_init": {
|
||||
"default": {
|
||||
"buf_cnt": 2,
|
||||
"fbc": "off",
|
||||
"gop": 60,
|
||||
"rc_mode": "cbr",
|
||||
"fps": "0:0",
|
||||
"range": "full",
|
||||
"qp": "26:4:20:40:8:48:2:1",
|
||||
"sei": "off",
|
||||
"vi_len": 30,
|
||||
"gop_mode": 0,
|
||||
"bps": 10000,
|
||||
"force_idr": "5:5:20000"
|
||||
},
|
||||
"1920*1080p30": {
|
||||
"bps": 10000,
|
||||
"force_idr": "5:5:30000"
|
||||
},
|
||||
"2560*1440p30": {
|
||||
"bps": 15000,
|
||||
"force_idr": "5:5:40000"
|
||||
}
|
||||
},
|
||||
"param_change": {
|
||||
}
|
||||
}
|
||||
},
|
||||
"osd_cfg": {
|
||||
"version" : 1,
|
||||
"param_init": {
|
||||
"enable": "off"
|
||||
},
|
||||
"param_change": {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -312,12 +312,12 @@ function choose_target_board() {
|
||||
echo -e "${C_GREEN} "${space8}选择系统版本:"${C_NORMAL}"
|
||||
|
||||
if (("$BM_INDEX" == 1)); then
|
||||
echo "${space8}${space8}[0] Buildroot(Support Rockchip official features) "
|
||||
echo "${space8}${space8}[0] Buildroot "
|
||||
read -p "Which would you like? [0~1][default:0]: " SYS_INDEX
|
||||
MAX_SYS_INDEX=0
|
||||
elif (("$BM_INDEX" == 0)); then
|
||||
echo "${space8}${space8}[0] Buildroot(Support Rockchip official features) "
|
||||
echo "${space8}${space8}[1] Ubuntu(Support for the apt package management tool)"
|
||||
echo "${space8}${space8}[0] Buildroot "
|
||||
echo "${space8}${space8}[1] Ubuntu "
|
||||
read -p "Which would you like? [0~1][default:0]: " SYS_INDEX
|
||||
MAX_SYS_INDEX=1
|
||||
fi
|
||||
@@ -689,24 +689,6 @@ function build_uboot() {
|
||||
echo "TARGET_UBOOT_CONFIG=$RK_UBOOT_DEFCONFIG $RK_UBOOT_DEFCONFIG_FRAGMENT"
|
||||
echo "========================================="
|
||||
|
||||
#Apply patch
|
||||
if [ ! -f ${SDK_SYSDRV_DIR}/source/.uboot_patch ]; then
|
||||
echo "============Apply Uboot Patch============"
|
||||
cd ${SDK_ROOT_DIR}
|
||||
git apply ${SDK_SYSDRV_DIR}/tools/board/uboot/*.patch
|
||||
if [ $? -eq 0 ]; then
|
||||
msg_info "Patch applied successfully."
|
||||
touch ${SDK_SYSDRV_DIR}/source/.uboot_patch
|
||||
else
|
||||
msg_error "Failed to apply the patch."
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
cp ${SDK_SYSDRV_DIR}/tools/board/uboot/*_defconfig ${SDK_SYSDRV_DIR}/source/uboot/u-boot/configs
|
||||
cp ${SDK_SYSDRV_DIR}/tools/board/uboot/*.dts ${SDK_SYSDRV_DIR}/source/uboot/u-boot/arch/arm/dts
|
||||
cp ${SDK_SYSDRV_DIR}/tools/board/uboot/*.dtsi ${SDK_SYSDRV_DIR}/source/uboot/u-boot/arch/arm/dts
|
||||
|
||||
local uboot_rkbin_ini tempfile target_ini_dir
|
||||
tempfile="$SDK_SYSDRV_DIR/source/uboot/rkbin/$RK_UBOOT_RKBIN_INI_OVERLAY"
|
||||
if [ -f "$tempfile" ]; then
|
||||
@@ -841,24 +823,6 @@ function build_sysdrv() {
|
||||
}
|
||||
|
||||
function build_kernel() {
|
||||
#Apply patch
|
||||
if [ ! -f ${SDK_SYSDRV_DIR}/source/.kernel_patch ]; then
|
||||
echo "============Apply Kernel Patch============"
|
||||
cd ${SDK_ROOT_DIR}
|
||||
git apply --verbose ${SDK_SYSDRV_DIR}/tools/board/kernel/*.patch
|
||||
if [ $? -eq 0 ]; then
|
||||
msg_info "Patch applied successfully."
|
||||
cp ${SDK_SYSDRV_DIR}/tools/board/kernel/*_defconfig ${KERNEL_PATH}/arch/arm/configs/
|
||||
cp ${SDK_SYSDRV_DIR}/tools/board/kernel/*.config ${KERNEL_PATH}/arch/arm/configs/
|
||||
cp ${SDK_SYSDRV_DIR}/tools/board/kernel/kernel-drivers-video-logo_linux_clut224.ppm ${KERNEL_PATH}/drivers/video/logo/logo_linux_clut224.ppm
|
||||
cp ${SDK_SYSDRV_DIR}/tools/board/kernel/*.dts ${KERNEL_PATH}/arch/arm/boot/dts
|
||||
cp ${SDK_SYSDRV_DIR}/tools/board/kernel/*.dtsi ${KERNEL_PATH}/arch/arm/boot/dts
|
||||
touch ${SDK_SYSDRV_DIR}/source/.kernel_patch
|
||||
else
|
||||
msg_error "Failed to apply the patch."
|
||||
fi
|
||||
fi
|
||||
|
||||
check_config RK_KERNEL_DTS RK_KERNEL_DEFCONFIG || return 0
|
||||
|
||||
echo "============Start building kernel============"
|
||||
@@ -1318,25 +1282,6 @@ function build_clean() {
|
||||
recovery)
|
||||
make kernel_clean -C ${SDK_SYSDRV_DIR} SYSDRV_BUILD_RECOVERY=y
|
||||
;;
|
||||
patch)
|
||||
cd ${SDK_ROOT_DIR}
|
||||
make uboot_clean -C ${SDK_SYSDRV_DIR}
|
||||
if [ -f ${SDK_SYSDRV_DIR}/source/.uboot_patch ]; then
|
||||
git apply -R --verbose ${SDK_SYSDRV_DIR}/tools/board/uboot/*.patch
|
||||
rm -rf ${SDK_SYSDRV_DIR}/source/uboot/u-boot/arch/arm/dts/*luckfox*
|
||||
rm -rf ${SDK_SYSDRV_DIR}/source/uboot/u-boot/configs/*luckfox*
|
||||
rm ${SDK_SYSDRV_DIR}/source/.uboot_patch
|
||||
fi
|
||||
|
||||
make kernel_clean -C ${SDK_SYSDRV_DIR}
|
||||
if [ -f ${SDK_SYSDRV_DIR}/source/.kernel_patch ]; then
|
||||
git apply -R --verbose ${SDK_SYSDRV_DIR}/tools/board/kernel/*.patch
|
||||
cp ${SDK_SYSDRV_DIR}/tools/board/kernel/logo_linux_clut224.ppm ${SDK_SYSDRV_DIR}/source/kernel/drivers/video/logo/logo_linux_clut224.ppm
|
||||
rm -rf ${SDK_SYSDRV_DIR}/source/kernel/arch/arm/configs/*luckfox*
|
||||
rm -rf ${SDK_SYSDRV_DIR}/source/kernel/arch/arm/boot/dts/*luckfox*
|
||||
rm ${SDK_SYSDRV_DIR}/source/.kernel_patch
|
||||
fi
|
||||
;;
|
||||
all)
|
||||
make distclean -C ${SDK_SYSDRV_DIR}
|
||||
make distclean -C ${SDK_MEDIA_DIR}
|
||||
@@ -2212,23 +2157,6 @@ __LINK_DEFCONFIG_FROM_BOARD_CFG() {
|
||||
sudo chmod a+rw $SDK_CONFIG_DIR
|
||||
fi
|
||||
|
||||
if [ ! -f ${SDK_SYSDRV_DIR}/source/.kernel_patch ]; then
|
||||
echo "============Apply Kernel Patch============"
|
||||
cd ${SDK_ROOT_DIR}
|
||||
git apply ${SDK_SYSDRV_DIR}/tools/board/kernel/*.patch
|
||||
if [ $? -eq 0 ]; then
|
||||
msg_info "Patch applied successfully."
|
||||
cp ${SDK_SYSDRV_DIR}/tools/board/kernel/*_defconfig ${KERNEL_PATH}/arch/arm/configs/
|
||||
cp ${SDK_SYSDRV_DIR}/tools/board/kernel/*.config ${KERNEL_PATH}/arch/arm/configs/
|
||||
cp ${SDK_SYSDRV_DIR}/tools/board/kernel/kernel-drivers-video-logo_linux_clut224.ppm ${KERNEL_PATH}/drivers/video/logo/logo_linux_clut224.ppm
|
||||
cp ${SDK_SYSDRV_DIR}/tools/board/kernel/*.dts ${KERNEL_PATH}/arch/arm/boot/dts
|
||||
cp ${SDK_SYSDRV_DIR}/tools/board/kernel/*.dtsi ${KERNEL_PATH}/arch/arm/boot/dts
|
||||
touch ${SDK_SYSDRV_DIR}/source/.kernel_patch
|
||||
else
|
||||
msg_error "Failed to apply the patch."
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ -n "$RK_KERNEL_DTS" ]; then
|
||||
rm -f $DTS_CONFIG
|
||||
ln -rfs $SDK_SYSDRV_DIR/source/kernel/arch/arm/boot/dts/$RK_KERNEL_DTS $DTS_CONFIG
|
||||
@@ -2295,7 +2223,9 @@ function build_mkimg() {
|
||||
fs_type="\$${fs_type}"
|
||||
fs_type=$(eval "echo ${fs_type}")
|
||||
|
||||
if [ "$LF_TARGET_ROOTFS" == "buildroot" ] || [ "$LF_TARGT_ROOTFS" == "busybox" ]; then
|
||||
__RELEASE_FILESYSTEM_FILES $src
|
||||
fi
|
||||
|
||||
msg_info "src=$src"
|
||||
msg_info "dst=$dst"
|
||||
|
||||
@@ -90,7 +90,7 @@ export RK_KERNEL_DEFCONFIG=luckfox_rv1106_linux_defconfig
|
||||
# RK_CAMERA_SENSOR_IQFILES format:
|
||||
# "iqfile1 iqfile2 iqfile3 ..."
|
||||
# ./build.sh media and copy <SDK root dir>/output/out/media_out/isp_iqfiles/$RK_CAMERA_SENSOR_IQFILES
|
||||
export RK_CAMERA_SENSOR_IQFILES="sc4336_OT01_40IRC_F16.json sc3336_CMK-OT2119-PC1_30IRC-F16.json"
|
||||
export RK_CAMERA_SENSOR_IQFILES="sc4336_OT01_40IRC_F16.json sc3336_CMK-OT2119-PC1_30IRC-F16.json mis5001_CMK-OT2115-PC1_30IRC-F16.json"
|
||||
#export RK_CAMERA_SENSOR_IQFILES="sc4336_OT01_40IRC_F16.json sc3336_CMK-OT2119-PC1_30IRC-F16.json sc530ai_CMK-OT2115-PC1_30IRC-F16.json"
|
||||
|
||||
# Config sensor lens CAC calibrattion bin files
|
||||
|
||||
@@ -90,7 +90,7 @@ export RK_KERNEL_DEFCONFIG_FRAGMENT=rv1106-bt.config
|
||||
# RK_CAMERA_SENSOR_IQFILES format:
|
||||
# "iqfile1 iqfile2 iqfile3 ..."
|
||||
# ./build.sh media and copy <SDK root dir>/output/out/media_out/isp_iqfiles/$RK_CAMERA_SENSOR_IQFILES
|
||||
export RK_CAMERA_SENSOR_IQFILES="sc4336_OT01_40IRC_F16.json sc3336_CMK-OT2119-PC1_30IRC-F16.json"
|
||||
export RK_CAMERA_SENSOR_IQFILES="sc4336_OT01_40IRC_F16.json sc3336_CMK-OT2119-PC1_30IRC-F16.json mis5001_CMK-OT2115-PC1_30IRC-F16.json"
|
||||
#export RK_CAMERA_SENSOR_IQFILES="sc4336_OT01_40IRC_F16.json sc3336_CMK-OT2119-PC1_30IRC-F16.json sc530ai_CMK-OT2115-PC1_30IRC-F16.json"
|
||||
|
||||
# Config sensor lens CAC calibrattion bin files
|
||||
|
||||
@@ -11,7 +11,7 @@ export RK_CHIP=rv1106
|
||||
# export RK_APP_TYPE=RKIPC_RV1106
|
||||
|
||||
# Config CMA size in environment
|
||||
export RK_BOOTARGS_CMA_SIZE="1M"
|
||||
export RK_BOOTARGS_CMA_SIZE="36M"
|
||||
|
||||
# Kernel dts
|
||||
export RK_KERNEL_DTS=rv1106g-luckfox-pico-ultra.dts
|
||||
@@ -90,7 +90,7 @@ export RK_KERNEL_DEFCONFIG=luckfox_rv1106_linux_defconfig
|
||||
# RK_CAMERA_SENSOR_IQFILES format:
|
||||
# "iqfile1 iqfile2 iqfile3 ..."
|
||||
# ./build.sh media and copy <SDK root dir>/output/out/media_out/isp_iqfiles/$RK_CAMERA_SENSOR_IQFILES
|
||||
export RK_CAMERA_SENSOR_IQFILES="sc4336_OT01_40IRC_F16.json sc3336_CMK-OT2119-PC1_30IRC-F16.json"
|
||||
export RK_CAMERA_SENSOR_IQFILES="sc4336_OT01_40IRC_F16.json sc3336_CMK-OT2119-PC1_30IRC-F16.json mis5001_CMK-OT2115-PC1_30IRC-F16.json"
|
||||
#export RK_CAMERA_SENSOR_IQFILES="sc4336_OT01_40IRC_F16.json sc3336_CMK-OT2119-PC1_30IRC-F16.json sc530ai_CMK-OT2115-PC1_30IRC-F16.json"
|
||||
|
||||
# Config sensor lens CAC calibrattion bin files
|
||||
@@ -120,4 +120,4 @@ export RK_PRE_BUILD_OEM_SCRIPT=luckfox-buildroot-oem-pre.sh
|
||||
export RK_PRE_BUILD_USERDATA_SCRIPT=luckfox-userdata-pre.sh
|
||||
|
||||
# declare overlay directory
|
||||
export RK_POST_OVERLAY="overlay-luckfox-config overlay-luckfox-ubuntu-config overlay-luckfox-ubuntu-ultra"
|
||||
export RK_POST_OVERLAY="overlay-luckfox-config overlay-luckfox-ubuntu-config overlay-luckfox-ubuntu-ultra overlay-luckfox-ubuntu-rockchip"
|
||||
@@ -11,7 +11,7 @@ export RK_CHIP=rv1106
|
||||
# export RK_APP_TYPE=RKIPC_RV1106
|
||||
|
||||
# Config CMA size in environment
|
||||
export RK_BOOTARGS_CMA_SIZE="1M"
|
||||
export RK_BOOTARGS_CMA_SIZE="36M"
|
||||
|
||||
# Kernel dts
|
||||
export RK_KERNEL_DTS=rv1106g-luckfox-pico-ultra-w.dts
|
||||
@@ -93,7 +93,7 @@ export RK_KERNEL_DEFCONFIG_FRAGMENT=rv1106-bt.config
|
||||
# RK_CAMERA_SENSOR_IQFILES format:
|
||||
# "iqfile1 iqfile2 iqfile3 ..."
|
||||
# ./build.sh media and copy <SDK root dir>/output/out/media_out/isp_iqfiles/$RK_CAMERA_SENSOR_IQFILES
|
||||
export RK_CAMERA_SENSOR_IQFILES="sc4336_OT01_40IRC_F16.json sc3336_CMK-OT2119-PC1_30IRC-F16.json"
|
||||
export RK_CAMERA_SENSOR_IQFILES="sc4336_OT01_40IRC_F16.json sc3336_CMK-OT2119-PC1_30IRC-F16.json mis5001_CMK-OT2115-PC1_30IRC-F16.json"
|
||||
#export RK_CAMERA_SENSOR_IQFILES="sc4336_OT01_40IRC_F16.json sc3336_CMK-OT2119-PC1_30IRC-F16.json sc530ai_CMK-OT2115-PC1_30IRC-F16.json"
|
||||
|
||||
# Config sensor lens CAC calibrattion bin files
|
||||
@@ -128,4 +128,4 @@ export RK_PRE_BUILD_OEM_SCRIPT=luckfox-buildroot-oem-pre.sh
|
||||
export RK_PRE_BUILD_USERDATA_SCRIPT=luckfox-userdata-pre.sh
|
||||
|
||||
# declare overlay directory
|
||||
export RK_POST_OVERLAY="overlay-luckfox-config overlay-luckfox-ubuntu-config overlay-luckfox-ubuntu-ultra"
|
||||
export RK_POST_OVERLAY="overlay-luckfox-config overlay-luckfox-ubuntu-config overlay-luckfox-ubuntu-ultra overlay-luckfox-ubuntu-rockchip"
|
||||
|
||||
@@ -87,7 +87,7 @@ export RK_KERNEL_DEFCONFIG=luckfox_rv1106_linux_defconfig
|
||||
# RK_CAMERA_SENSOR_IQFILES format:
|
||||
# "iqfile1 iqfile2 iqfile3 ..."
|
||||
# ./build.sh media and copy <SDK root dir>/output/out/media_out/isp_iqfiles/$RK_CAMERA_SENSOR_IQFILES
|
||||
export RK_CAMERA_SENSOR_IQFILES="sc4336_OT01_40IRC_F16.json sc3336_CMK-OT2119-PC1_30IRC-F16.json"
|
||||
export RK_CAMERA_SENSOR_IQFILES="sc4336_OT01_40IRC_F16.json sc3336_CMK-OT2119-PC1_30IRC-F16.json mis5001_CMK-OT2115-PC1_30IRC-F16.json"
|
||||
#export RK_CAMERA_SENSOR_IQFILES="sc4336_OT01_40IRC_F16.json sc3336_CMK-OT2119-PC1_30IRC-F16.json sc530ai_CMK-OT2115-PC1_30IRC-F16.json"
|
||||
|
||||
# Config sensor lens CAC calibrattion bin files
|
||||
|
||||
@@ -87,7 +87,7 @@ export RK_KERNEL_DEFCONFIG=luckfox_rv1106_linux_defconfig
|
||||
# RK_CAMERA_SENSOR_IQFILES format:
|
||||
# "iqfile1 iqfile2 iqfile3 ..."
|
||||
# ./build.sh media and copy <SDK root dir>/output/out/media_out/isp_iqfiles/$RK_CAMERA_SENSOR_IQFILES
|
||||
export RK_CAMERA_SENSOR_IQFILES="sc4336_OT01_40IRC_F16.json sc3336_CMK-OT2119-PC1_30IRC-F16.json"
|
||||
export RK_CAMERA_SENSOR_IQFILES="sc4336_OT01_40IRC_F16.json sc3336_CMK-OT2119-PC1_30IRC-F16.json mis5001_CMK-OT2115-PC1_30IRC-F16.json"
|
||||
#export RK_CAMERA_SENSOR_IQFILES="sc4336_OT01_40IRC_F16.json sc3336_CMK-OT2119-PC1_30IRC-F16.json sc530ai_CMK-OT2115-PC1_30IRC-F16.json"
|
||||
|
||||
# Config sensor lens CAC calibrattion bin files
|
||||
|
||||
@@ -11,7 +11,7 @@ export RK_CHIP=rv1106
|
||||
# export RK_APP_TYPE=RKIPC_RV1106
|
||||
|
||||
# Config CMA size in environment
|
||||
export RK_BOOTARGS_CMA_SIZE="1M"
|
||||
export RK_BOOTARGS_CMA_SIZE="36M"
|
||||
|
||||
# Kernel dts
|
||||
export RK_KERNEL_DTS=rv1106g-luckfox-pico-max.dts
|
||||
@@ -90,7 +90,7 @@ export RK_KERNEL_DEFCONFIG=luckfox_rv1106_linux_defconfig
|
||||
# RK_CAMERA_SENSOR_IQFILES format:
|
||||
# "iqfile1 iqfile2 iqfile3 ..."
|
||||
# ./build.sh media and copy <SDK root dir>/output/out/media_out/isp_iqfiles/$RK_CAMERA_SENSOR_IQFILES
|
||||
export RK_CAMERA_SENSOR_IQFILES="sc4336_OT01_40IRC_F16.json sc3336_CMK-OT2119-PC1_30IRC-F16.json"
|
||||
export RK_CAMERA_SENSOR_IQFILES="sc4336_OT01_40IRC_F16.json sc3336_CMK-OT2119-PC1_30IRC-F16.json mis5001_CMK-OT2115-PC1_30IRC-F16.json"
|
||||
#export RK_CAMERA_SENSOR_IQFILES="sc4336_OT01_40IRC_F16.json sc3336_CMK-OT2119-PC1_30IRC-F16.json sc530ai_CMK-OT2115-PC1_30IRC-F16.json"
|
||||
|
||||
# Config sensor lens CAC calibrattion bin files
|
||||
@@ -117,4 +117,4 @@ export RK_PRE_BUILD_OEM_SCRIPT=luckfox-ubuntu-oem-pre.sh
|
||||
export RK_PRE_BUILD_USERDATA_SCRIPT=luckfox-userdata-pre.sh
|
||||
|
||||
# declare overlay directory
|
||||
export RK_POST_OVERLAY="overlay-luckfox-config overlay-luckfox-ubuntu overlay-luckfox-ubuntu-config"
|
||||
export RK_POST_OVERLAY="overlay-luckfox-config overlay-luckfox-ubuntu overlay-luckfox-ubuntu-config overlay-luckfox-ubuntu-rockchip"
|
||||
@@ -11,7 +11,7 @@ export RK_CHIP=rv1106
|
||||
# export RK_APP_TYPE=RKIPC_RV1106
|
||||
|
||||
# Config CMA size in environment
|
||||
export RK_BOOTARGS_CMA_SIZE="1M"
|
||||
export RK_BOOTARGS_CMA_SIZE="36M"
|
||||
|
||||
# Kernel dts
|
||||
export RK_KERNEL_DTS=rv1106g-luckfox-pico-pro.dts
|
||||
@@ -90,7 +90,7 @@ export RK_KERNEL_DEFCONFIG=luckfox_rv1106_linux_defconfig
|
||||
# RK_CAMERA_SENSOR_IQFILES format:
|
||||
# "iqfile1 iqfile2 iqfile3 ..."
|
||||
# ./build.sh media and copy <SDK root dir>/output/out/media_out/isp_iqfiles/$RK_CAMERA_SENSOR_IQFILES
|
||||
export RK_CAMERA_SENSOR_IQFILES="sc4336_OT01_40IRC_F16.json sc3336_CMK-OT2119-PC1_30IRC-F16.json"
|
||||
export RK_CAMERA_SENSOR_IQFILES="sc4336_OT01_40IRC_F16.json sc3336_CMK-OT2119-PC1_30IRC-F16.json mis5001_CMK-OT2115-PC1_30IRC-F16.json"
|
||||
#export RK_CAMERA_SENSOR_IQFILES="sc4336_OT01_40IRC_F16.json sc3336_CMK-OT2119-PC1_30IRC-F16.json sc530ai_CMK-OT2115-PC1_30IRC-F16.json"
|
||||
|
||||
# Config sensor lens CAC calibrattion bin files
|
||||
@@ -117,4 +117,4 @@ export RK_PRE_BUILD_OEM_SCRIPT=luckfox-ubuntu-oem-pre.sh
|
||||
export RK_PRE_BUILD_USERDATA_SCRIPT=luckfox-userdata-pre.sh
|
||||
|
||||
# declare overlay directory
|
||||
export RK_POST_OVERLAY="overlay-luckfox-config overlay-luckfox-ubuntu overlay-luckfox-ubuntu-config"
|
||||
export RK_POST_OVERLAY="overlay-luckfox-config overlay-luckfox-ubuntu overlay-luckfox-ubuntu-config overlay-luckfox-ubuntu-rockchip"
|
||||
@@ -87,7 +87,7 @@ export RK_KERNEL_DEFCONFIG=luckfox_rv1106_linux_defconfig
|
||||
# RK_CAMERA_SENSOR_IQFILES format:
|
||||
# "iqfile1 iqfile2 iqfile3 ..."
|
||||
# ./build.sh media and copy <SDK root dir>/output/out/media_out/isp_iqfiles/$RK_CAMERA_SENSOR_IQFILES
|
||||
export RK_CAMERA_SENSOR_IQFILES="sc4336_OT01_40IRC_F16.json sc3336_CMK-OT2119-PC1_30IRC-F16.json"
|
||||
export RK_CAMERA_SENSOR_IQFILES="sc4336_OT01_40IRC_F16.json sc3336_CMK-OT2119-PC1_30IRC-F16.json mis5001_CMK-OT2115-PC1_30IRC-F16.json"
|
||||
#export RK_CAMERA_SENSOR_IQFILES="sc4336_OT01_40IRC_F16.json sc3336_CMK-OT2119-PC1_30IRC-F16.json sc530ai_CMK-OT2115-PC1_30IRC-F16.json"
|
||||
|
||||
# Config sensor lens CAC calibrattion bin files
|
||||
|
||||
@@ -87,7 +87,7 @@ export RK_KERNEL_DEFCONFIG=luckfox_rv1106_linux_defconfig
|
||||
# RK_CAMERA_SENSOR_IQFILES format:
|
||||
# "iqfile1 iqfile2 iqfile3 ..."
|
||||
# ./build.sh media and copy <SDK root dir>/output/out/media_out/isp_iqfiles/$RK_CAMERA_SENSOR_IQFILES
|
||||
export RK_CAMERA_SENSOR_IQFILES="sc4336_OT01_40IRC_F16.json sc3336_CMK-OT2119-PC1_30IRC-F16.json"
|
||||
export RK_CAMERA_SENSOR_IQFILES="sc4336_OT01_40IRC_F16.json sc3336_CMK-OT2119-PC1_30IRC-F16.json mis5001_CMK-OT2115-PC1_30IRC-F16.json"
|
||||
#export RK_CAMERA_SENSOR_IQFILES="sc4336_OT01_40IRC_F16.json sc3336_CMK-OT2119-PC1_30IRC-F16.json sc530ai_CMK-OT2115-PC1_30IRC-F16.json"
|
||||
|
||||
# Config sensor lens CAC calibrattion bin files
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user