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:
@@ -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}")
|
||||
|
||||
__RELEASE_FILESYSTEM_FILES $src
|
||||
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.
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