feat: sync from v4 - bbox colour by class, collision warning debounce, clean build option
This commit is contained in:
parent
839100c0e1
commit
b9b298e466
12
.gitignore
vendored
Normal file
12
.gitignore
vendored
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
# Build artifacts
|
||||||
|
build/*.o
|
||||||
|
build/kp_firmware_host_stream
|
||||||
|
build/*.nef
|
||||||
|
|
||||||
|
# Python
|
||||||
|
__pycache__/
|
||||||
|
*.pyc
|
||||||
|
*.pyo
|
||||||
|
|
||||||
|
# Editor
|
||||||
|
.vscode/
|
||||||
@ -284,51 +284,4 @@ def main():
|
|||||||
parser.add_argument("--no-copy",action="store_true",
|
parser.add_argument("--no-copy",action="store_true",
|
||||||
help="不要複製 binary 到網路資料夾")
|
help="不要複製 binary 到網路資料夾")
|
||||||
parser.add_argument("--no-serve", action="store_true",
|
parser.add_argument("--no-serve", action="store_true",
|
||||||
help="只 build + check,不啟動 HTTP server")
|
|
||||||
parser.add_argument("--port", type=int, default=8080,
|
|
||||||
help="HTTP server port (default: 8080)")
|
|
||||||
parser.add_argument("--image", default=DOCKER_IMAGE,
|
|
||||||
help=f"Docker image name (default: {DOCKER_IMAGE})")
|
|
||||||
args = parser.parse_args()
|
|
||||||
|
|
||||||
|
|
||||||
DOCKER_IMAGE = args.image
|
|
||||||
|
|
||||||
print(head("KL630 Build & Serve"))
|
|
||||||
print(f" Root : {SCRIPT_DIR}")
|
|
||||||
print(f" Binary : {BINARY_PATH}")
|
|
||||||
print(f" Port : {args.port}")
|
|
||||||
print(f" Copy : {args.copy_dst}")
|
|
||||||
|
|
||||||
# ===== Clean only =====
|
|
||||||
if args.clean:
|
|
||||||
step_clean()
|
|
||||||
sys.exit(0)
|
|
||||||
|
|
||||||
# ===== Clean then build =====
|
|
||||||
if args.clean_build:
|
|
||||||
step_clean()
|
|
||||||
|
|
||||||
# ===== Step 1: Build =====
|
|
||||||
if not args.no_build:
|
|
||||||
if not step_ensure_image():
|
|
||||||
sys.exit(1)
|
|
||||||
if not step_build():
|
|
||||||
sys.exit(1)
|
|
||||||
# ===== Step 2: Check =====
|
|
||||||
if not args.no_check:
|
|
||||||
if not step_check():
|
|
||||||
if args.no_build:
|
|
||||||
print(warn(" (使用 --no-build 時 binary 可能是舊的)"))
|
|
||||||
else:
|
|
||||||
sys.exit(1)
|
|
||||||
# ===== Step 3: Copy(重點)=====
|
|
||||||
if not args.no_copy:
|
|
||||||
if not step_copy_to_network(args.copy_dst):
|
|
||||||
sys.exit(1)
|
|
||||||
# ===== Step 4: Serve =====
|
|
||||||
if not args.no_serve:
|
|
||||||
step_serve(args.port)
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
main()
|
|
||||||
File diff suppressed because it is too large
Load Diff
@ -507,26 +507,4 @@ void bt_uart_set_identity(const char *aresx_version, const char *bt_name)
|
|||||||
if (aresx_version && *aresx_version)
|
if (aresx_version && *aresx_version)
|
||||||
snprintf(s_ares_version, sizeof(s_ares_version), "%s", aresx_version);
|
snprintf(s_ares_version, sizeof(s_ares_version), "%s", aresx_version);
|
||||||
if (bt_name && *bt_name)
|
if (bt_name && *bt_name)
|
||||||
snprintf(s_bt_name, sizeof(s_bt_name), "%s", bt_name);
|
snprintf(s_bt_name, siz
|
||||||
printf("[BT] identity: version=%s name=%s\n", s_ares_version, s_bt_name);
|
|
||||||
}
|
|
||||||
|
|
||||||
int bt_uart_get_rent_status(void)
|
|
||||||
{
|
|
||||||
pthread_mutex_lock(&s_rent_mtx);
|
|
||||||
int st = s_rent_status;
|
|
||||||
pthread_mutex_unlock(&s_rent_mtx);
|
|
||||||
return st;
|
|
||||||
}
|
|
||||||
|
|
||||||
void bt_uart_set_rent_status(int status)
|
|
||||||
{
|
|
||||||
pthread_mutex_lock(&s_rent_mtx);
|
|
||||||
s_rent_status = status;
|
|
||||||
pthread_mutex_unlock(&s_rent_mtx);
|
|
||||||
}
|
|
||||||
|
|
||||||
void bt_uart_set_intervention_cb(bt_intervention_fn fn)
|
|
||||||
{
|
|
||||||
s_intervention_cb = fn;
|
|
||||||
}
|
|
||||||
@ -871,27 +871,4 @@ void event_recorder_provide_frame(void)
|
|||||||
|
|
||||||
if (snap_lazy_init() != 0) return;
|
if (snap_lazy_init() != 0) return;
|
||||||
|
|
||||||
uint8_t *jpeg = (uint8_t *)MemBroker_GetMemory(SNAP_BUF_SIZE, VMF_ALIGN_TYPE_DEFAULT);
|
uint8_t *jpeg = (uint8_t *)MemBroker_GetMemory(SNAP_BU
|
||||||
if (!jpeg) {
|
|
||||||
printf("[EVT] snap: MemBroker_GetMemory failed\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
int jpeg_size = VMF_SNAP_ProcessOneFrame(s_snap, 1920, 1080, SNAP_BUF_SIZE, jpeg);
|
|
||||||
int snap_ok = (jpeg_size > 0);
|
|
||||||
if (snap_ok) {
|
|
||||||
char out_path[384];
|
|
||||||
snprintf(out_path, sizeof(out_path), "%s/%s", req.work_dir, req.filename);
|
|
||||||
save_jpeg(out_path, jpeg, jpeg_size);
|
|
||||||
} else {
|
|
||||||
printf("[EVT] snap: ProcessOneFrame failed (%d) — upload will proceed without image\n", jpeg_size);
|
|
||||||
}
|
|
||||||
MemBroker_FreeMemory(jpeg);
|
|
||||||
|
|
||||||
if (req.immediate_upload) {
|
|
||||||
const char imgs[4][64] = { "snapshot.jpg", "", "", "" };
|
|
||||||
int image_count = snap_ok ? 1 : 0;
|
|
||||||
launch_upload(req.work_dir, req.event_id, req.event_type,
|
|
||||||
req.max_level, 0.0f, imgs, image_count, 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -440,8 +440,8 @@ static int init_video_source(HOST_STREAM_INIT_OPT_T* pHostStreamInit)
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/* FEC passthrough (no lens correction). Load FEC config for gFecDefValue defaults only.
|
/* FEC passthrough (no lens correction). Load FEC config for gFecDefValue defaults only.
|
||||||
* Pass NULL for ptFrontConfig ??skips lens curve node loading (not needed for passthrough).
|
* Pass NULL for ptFrontConfig — skips lens curve node loading (not needed for passthrough).
|
||||||
* Do NOT set ptFecConfig here ??SDK sets only eFecMethod=GTR (below) for this case. */
|
* Do NOT set ptFecConfig here — SDK sets only eFecMethod=GTR (below) for this case. */
|
||||||
if(loadFECConfig(pHostStreamInit, NULL) == -1){
|
if(loadFECConfig(pHostStreamInit, NULL) == -1){
|
||||||
printf("[%s] No fec config file, using defaults\n", __func__);
|
printf("[%s] No fec config file, using defaults\n", __func__);
|
||||||
}
|
}
|
||||||
@ -535,14 +535,14 @@ void set_data_to_yuv(unsigned char* pucYBuff, unsigned int dwWidth, unsigned int
|
|||||||
dwOffsetV = dwOffsetU + dwPlaneSize ;
|
dwOffsetV = dwOffsetU + dwPlaneSize ;
|
||||||
|
|
||||||
/* YCbCr colour table indexed by YOLO class number (BT.601 full-range).
|
/* YCbCr colour table indexed by YOLO class number (BT.601 full-range).
|
||||||
* class=0 person ??green (Y=149, Cb= 43, Cr= 21)
|
* class=0 person → green (Y=149, Cb= 43, Cr= 21)
|
||||||
* class=1 (other) ??white (Y=235, Cb=128, Cr=128)
|
* class=1 (other) → white (Y=235, Cb=128, Cr=128)
|
||||||
* class=2 vehicle ??red (Y= 76, Cb= 84, Cr=255)
|
* class=2 vehicle → red (Y= 76, Cb= 84, Cr=255)
|
||||||
* fallback ??white */
|
* fallback → white */
|
||||||
static const unsigned char CLASS_YUV[][3] = {
|
static const unsigned char CLASS_YUV[][3] = {
|
||||||
{149, 43, 21}, /* 0: person ??green */
|
{149, 43, 21}, /* 0: person – green */
|
||||||
{235, 128, 128}, /* 1: other ??white */
|
{235, 128, 128}, /* 1: other – white */
|
||||||
{ 76, 84, 255}, /* 2: vehicle ??red */
|
{ 76, 84, 255}, /* 2: vehicle – red */
|
||||||
};
|
};
|
||||||
const unsigned char *yuv;
|
const unsigned char *yuv;
|
||||||
if (iColor >= 0 && iColor < (int)(sizeof(CLASS_YUV)/sizeof(CLASS_YUV[0])))
|
if (iColor >= 0 && iColor < (int)(sizeof(CLASS_YUV)/sizeof(CLASS_YUV[0])))
|
||||||
@ -669,7 +669,7 @@ void draw_rect(YUV_BUFF_INFO_T* yuvBuffInfo, DETECT_INFO *ptDetInfo, int iColor)
|
|||||||
* Per-class YCbCr colours for STDC segmentation overlay (BT.601 full-range).
|
* Per-class YCbCr colours for STDC segmentation overlay (BT.601 full-range).
|
||||||
* Order matches STDC_CLASS_* indices:
|
* Order matches STDC_CLASS_* indices:
|
||||||
* 0=bunker 1=car 2=grass 3=greenery 4=person 5=pond 6=road 7=tree
|
* 0=bunker 1=car 2=grass 3=greenery 4=person 5=pond 6=road 7=tree
|
||||||
* road (class 6) is left transparent ??it occupies most of the frame and adds
|
* road (class 6) is left transparent — it occupies most of the frame and adds
|
||||||
* visual noise rather than information.
|
* visual noise rather than information.
|
||||||
*/
|
*/
|
||||||
static const uint8_t s_stdc_yuv[STDC_NUM_CLASSES][3] = {
|
static const uint8_t s_stdc_yuv[STDC_NUM_CLASSES][3] = {
|
||||||
@ -679,7 +679,7 @@ static const uint8_t s_stdc_yuv[STDC_NUM_CLASSES][3] = {
|
|||||||
{137, 104, 55}, /* greenery #22c55e */
|
{137, 104, 55}, /* greenery #22c55e */
|
||||||
{144, 59, 203}, /* person #f97316 */
|
{144, 59, 203}, /* person #f97316 */
|
||||||
{154, 182, 87}, /* pond #60a5fa */
|
{154, 182, 87}, /* pond #60a5fa */
|
||||||
{ 0, 0, 0}, /* road ??transparent (unused) */
|
{ 0, 0, 0}, /* road — transparent (unused) */
|
||||||
{ 88, 113, 80}, /* tree #15803d */
|
{ 88, 113, 80}, /* tree #15803d */
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -710,7 +710,7 @@ static void stdc_paint_seg_overlay(unsigned char *base_buf,
|
|||||||
uint32_t y_stride = info->dwYStride;
|
uint32_t y_stride = info->dwYStride;
|
||||||
uint32_t uv_stride = info->dwYStride >> 1;
|
uint32_t uv_stride = info->dwYStride >> 1;
|
||||||
|
|
||||||
/* Pre-compute column mapping: output x ??seg col index */
|
/* Pre-compute column mapping: output x → seg col index */
|
||||||
uint8_t col_lut[1920];
|
uint8_t col_lut[1920];
|
||||||
uint32_t fx_max = (frame_w < 1920) ? frame_w : 1920;
|
uint32_t fx_max = (frame_w < 1920) ? frame_w : 1920;
|
||||||
for (uint32_t fx = 0; fx < fx_max; fx++)
|
for (uint32_t fx = 0; fx < fx_max; fx++)
|
||||||
@ -721,7 +721,7 @@ static void stdc_paint_seg_overlay(unsigned char *base_buf,
|
|||||||
const uint8_t *seg_row = local_map + seg_r * seg_w;
|
const uint8_t *seg_row = local_map + seg_r * seg_w;
|
||||||
uint8_t *y_row = y_buf + fy * y_stride;
|
uint8_t *y_row = y_buf + fy * y_stride;
|
||||||
|
|
||||||
/* Y plane ??every pixel */
|
/* Y plane — every pixel */
|
||||||
for (uint32_t fx = 0; fx < fx_max; fx++) {
|
for (uint32_t fx = 0; fx < fx_max; fx++) {
|
||||||
uint8_t cls = seg_row[col_lut[fx]];
|
uint8_t cls = seg_row[col_lut[fx]];
|
||||||
if (cls == STDC_CLASS_ROAD || cls >= STDC_NUM_CLASSES) continue;
|
if (cls == STDC_CLASS_ROAD || cls >= STDC_NUM_CLASSES) continue;
|
||||||
@ -729,7 +729,7 @@ static void stdc_paint_seg_overlay(unsigned char *base_buf,
|
|||||||
y_row[fx] = (uint8_t)(((uint16_t)y_row[fx] + col[0]) >> 1);
|
y_row[fx] = (uint8_t)(((uint16_t)y_row[fx] + col[0]) >> 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* UV plane ??every other row, every other column */
|
/* UV plane — every other row, every other column */
|
||||||
if ((fy & 1) == 0) {
|
if ((fy & 1) == 0) {
|
||||||
uint8_t *cb_row = cb_buf + (fy >> 1) * uv_stride;
|
uint8_t *cb_row = cb_buf + (fy >> 1) * uv_stride;
|
||||||
uint8_t *cr_row = cr_buf + (fy >> 1) * uv_stride;
|
uint8_t *cr_row = cr_buf + (fy >> 1) * uv_stride;
|
||||||
@ -1543,8 +1543,8 @@ void *kdp2_host_voc_thread(void *arg)
|
|||||||
if (vsrc_ssm_info.dwOffset[0] != 0 && vsrc_ssm_info.dwOffset[1] != 0) {
|
if (vsrc_ssm_info.dwOffset[0] != 0 && vsrc_ssm_info.dwOffset[1] != 0) {
|
||||||
abuf[q_idx].apdwData[0] = ssm_buf[q_idx].buffer + vsrc_ssm_info.dwOffset[0];
|
abuf[q_idx].apdwData[0] = ssm_buf[q_idx].buffer + vsrc_ssm_info.dwOffset[0];
|
||||||
abuf[q_idx].apdwData[1] = ssm_buf[q_idx].buffer + vsrc_ssm_info.dwOffset[1];
|
abuf[q_idx].apdwData[1] = ssm_buf[q_idx].buffer + vsrc_ssm_info.dwOffset[1];
|
||||||
/* NV12 (semi-planar): offset[2]==0 means no separate Cr plane ??NULL.
|
/* NV12 (semi-planar): offset[2]==0 means no separate Cr plane → NULL.
|
||||||
* YM12 (planar): offset[2]!=0 ??Cr plane pointer. */
|
* YM12 (planar): offset[2]!=0 → Cr plane pointer. */
|
||||||
abuf[q_idx].apdwData[2] = vsrc_ssm_info.dwOffset[2]
|
abuf[q_idx].apdwData[2] = vsrc_ssm_info.dwOffset[2]
|
||||||
? (ssm_buf[q_idx].buffer + vsrc_ssm_info.dwOffset[2]) : NULL;
|
? (ssm_buf[q_idx].buffer + vsrc_ssm_info.dwOffset[2]) : NULL;
|
||||||
} else {
|
} else {
|
||||||
@ -1672,7 +1672,7 @@ void *kdp2_host_stream_image_thread(void *arg)
|
|||||||
* VOC thread unblocks on g_dwInitBind and immediately checks g_dwDrawBoxType
|
* VOC thread unblocks on g_dwInitBind and immediately checks g_dwDrawBoxType
|
||||||
* to decide which SSM pin to read from. If draw box is enabled on stream 0,
|
* to decide which SSM pin to read from. If draw box is enabled on stream 0,
|
||||||
* it must see g_dwDrawBoxType=1 so it reads from VENC_VSRC_B_PIN (overlay
|
* it must see g_dwDrawBoxType=1 so it reads from VENC_VSRC_B_PIN (overlay
|
||||||
* output) rather than the raw ISP SSM ??fixes intermittent HDMI no-overlay. */
|
* output) rather than the raw ISP SSM — fixes intermittent HDMI no-overlay. */
|
||||||
if (pHostStreamInit->bDrawBoxEnable && pHostStreamInit->dwEncodeStreamCount > 0)
|
if (pHostStreamInit->bDrawBoxEnable && pHostStreamInit->dwEncodeStreamCount > 0)
|
||||||
g_dwDrawBoxType = 1;
|
g_dwDrawBoxType = 1;
|
||||||
g_dwInitBind = 1;
|
g_dwInitBind = 1;
|
||||||
@ -1879,58 +1879,4 @@ EXIT_MIPI_IMAGE_THREAD:
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void *kdp2_host_update_result_thread(void *arg)
|
void *kdp2_host_updat
|
||||||
{
|
|
||||||
HOST_STREAM_INIT_OPT_T* pHostStreamInit = (HOST_STREAM_INIT_OPT_T*)arg;
|
|
||||||
uint32_t buf_addr = 0;
|
|
||||||
uint32_t phy_buf_addr = 0;
|
|
||||||
int buf_size = 0;
|
|
||||||
int sts = 0;
|
|
||||||
|
|
||||||
dbg_log("[%s] starting ..\n", __FUNCTION__);
|
|
||||||
if (app_hdr_recv_inf_cb == NULL) {
|
|
||||||
printf("[%s] recv_inf_cb is NULL \n", __FUNCTION__);
|
|
||||||
goto EXIT_UPDATE_RESULT_THREAD;
|
|
||||||
}
|
|
||||||
|
|
||||||
g_dwRoiX = pHostStreamInit->dwRoiX;
|
|
||||||
g_dwRoiY = pHostStreamInit->dwRoiY;
|
|
||||||
g_dwDrawBoxEnable = pHostStreamInit->bDrawBoxEnable;
|
|
||||||
g_dwOnlyPerson = pHostStreamInit->dwOnlyPerson;
|
|
||||||
|
|
||||||
while (true == _blResultRunning) {
|
|
||||||
// get result data from queue blocking wait
|
|
||||||
int ret = VMF_NNM_Fifoq_Manager_Result_Dequeue(&buf_addr, &phy_buf_addr, &buf_size, -1);
|
|
||||||
|
|
||||||
if (KP_FW_FIFOQ_ACCESS_FAILED_125 == ret) {
|
|
||||||
continue;
|
|
||||||
} else if (KP_SUCCESS != ret) {
|
|
||||||
printf("[%s] Error: FIFO queue error %d.\n", __FUNCTION__, sts);
|
|
||||||
goto EXIT_UPDATE_RESULT_THREAD;
|
|
||||||
}
|
|
||||||
|
|
||||||
//dbg_log("[%s] buf 0x%x len %d -- usb --> host\n", __FUNCTION__, buf_addr, header_stamp->total_size);
|
|
||||||
sts = app_hdr_recv_inf_cb(buf_addr, &_blResultRunning); //printf result
|
|
||||||
if (KP_SUCCESS != sts) {
|
|
||||||
printf("[%s] Error: callback function error (%d)\n", __FUNCTION__, sts);
|
|
||||||
goto EXIT_UPDATE_RESULT_THREAD;
|
|
||||||
}
|
|
||||||
|
|
||||||
// return free buf back to queue
|
|
||||||
ret = VMF_NNM_Fifoq_Manager_Result_Put_Free_Buffer(buf_addr, phy_buf_addr, buf_size, -1);
|
|
||||||
if (KP_FW_FIFOQ_ACCESS_FAILED_125 == ret) {
|
|
||||||
continue;
|
|
||||||
} else if (KP_SUCCESS != ret) {
|
|
||||||
goto EXIT_UPDATE_RESULT_THREAD;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
EXIT_UPDATE_RESULT_THREAD:
|
|
||||||
if (NULL != g_pm_buf) {
|
|
||||||
MemBroker_FreeMemory(g_pm_buf);
|
|
||||||
g_pm_buf = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
dbg_log("[%s] exit ..\n", __FUNCTION__);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
Loading…
x
Reference in New Issue
Block a user