diff --git a/projects/llm_framework/main_skel/Kconfig b/projects/llm_framework/main_skel/Kconfig new file mode 100644 index 0000000..e69de29 diff --git a/projects/llm_framework/main_skel/SConstruct b/projects/llm_framework/main_skel/SConstruct new file mode 100644 index 0000000..b6aeb01 --- /dev/null +++ b/projects/llm_framework/main_skel/SConstruct @@ -0,0 +1,47 @@ +import os + +Import('env') +with open(env['PROJECT_TOOL_S']) as f: + exec(f.read()) + +SRCS = append_srcs_dir(ADir('src')) +INCLUDE = [ADir('include'), ADir('.')] +PRIVATE_INCLUDE = [] +REQUIREMENTS = ['pthread', 'utilities', 'ax_msp', 'eventpp', 'StackFlow', 'ax-samples'] + +STATIC_LIB = [] +DYNAMIC_LIB = [] +DEFINITIONS = [] +DEFINITIONS_PRIVATE = [] +LDFLAGS = [] +LINK_SEARCH_PATH = [] +STATIC_FILES = [] + +DEFINITIONS += ['-std=c++17'] +LDFLAGS+=['-Wl,-rpath=/opt/m5stack/lib', '-Wl,-rpath=/usr/local/m5stack/lib', '-Wl,-rpath=/usr/local/m5stack/lib/gcc-10.3', '-Wl,-rpath=/opt/lib', '-Wl,-rpath=/opt/usr/lib', '-Wl,-rpath=./'] +LINK_SEARCH_PATH += [ADir('../static_lib')] +REQUIREMENTS += ['ax_engine', 'ax_interpreter', 'ax_sys'] +REQUIREMENTS += ['ax_skel', 'ax_engine', 'ax_venc', 'ax_vdec', 'ax_ivps', 'ax_proton'] + +INCLUDE += [ADir('../include'), ADir('src/runner'), ADir('../include/opencv4')] + +static_file = Glob('../static_lib/module-llm/libabsl_*') +static_file = Glob('../static_lib/libopencv-4.6-aarch64-none/lib/lib*') +STATIC_LIB += static_file * 2 + + + +env['COMPONENTS'].append({'target':'llm_skel', + 'SRCS':SRCS, + 'INCLUDE':INCLUDE, + 'PRIVATE_INCLUDE':PRIVATE_INCLUDE, + 'REQUIREMENTS':REQUIREMENTS, + 'STATIC_LIB':STATIC_LIB, + 'DYNAMIC_LIB':DYNAMIC_LIB, + 'DEFINITIONS':DEFINITIONS, + 'DEFINITIONS_PRIVATE':DEFINITIONS_PRIVATE, + 'LDFLAGS':LDFLAGS, + 'LINK_SEARCH_PATH':LINK_SEARCH_PATH, + 'STATIC_FILES':STATIC_FILES, + 'REGISTER':'project' + }) diff --git a/projects/llm_framework/main_skel/src/main.c b/projects/llm_framework/main_skel/src/main.c new file mode 100644 index 0000000..b1e9364 --- /dev/null +++ b/projects/llm_framework/main_skel/src/main.c @@ -0,0 +1,2285 @@ +/************************************************************************************************** + * + * Copyright (c) 2019-2024 Axera Semiconductor Co., Ltd. All Rights Reserved. + * + * This source file is the property of Axera Semiconductor Co., Ltd. and + * may not be copied or distributed in any isomorphic form without the prior + * written consent of Axera Semiconductor Co., Ltd. + * + **************************************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include "YuvHandler.h" +#include "ax_skel_api.h" +#include "ax_sys_api.h" +#include "ax_ivps_api.h" +#include "ax_venc_api.h" +#include "ax_buffer_tool.h" +#include "skel_log.h" +#include "ax_engine_api.h" +#include "frameMgr.h" +#include "attrParser.h" +#include "statMgr.h" +#include "common_vdec_api.h" + +#ifndef ALIGN_UP +#define ALIGN_UP(x, align) ((((x) + ((align) - 1)) / (align)) * (align)) +#endif + +#ifndef ALIGN_DOWN +#define ALIGN_DOWN(x, align) (((x) / (align)) * (align)) +#endif + +#ifndef AX_MAX +#define AX_MAX(a, b) (((a) > (b)) ? (a) : (b)) +#endif + +#ifndef AX_MIN +#define AX_MIN(a, b) (((a) < (b)) ? (a) : (b)) +#endif + +#define SKEL_SAMPLE_OUTPUT_BODY_PATH "body" +#define SKEL_SAMPLE_OUTPUT_VEHICLE_PATH "vehicle" +#define SKEL_SAMPLE_OUTPUT_CYCLE_PATH "cycle" +#define SKEL_SAMPLE_OUTPUT_FACE_PATH "face" +#define SKEL_SAMPLE_OUTPUT_PLATE_PATH "plate" +#define SKEL_SAMPLE_OUTPUT_LOG_FILE "output.txt" + +#define SAMPLE_SKEL_SHIFT_LEFT_ALIGN(a) (1 << (a)) +#define SAMPLE_SKEL_VDEC_WIDTH_ALIGN SAMPLE_SKEL_SHIFT_LEFT_ALIGN(8) +#define SAMPLE_SKEL_HEIGHT_ALIGN SAMPLE_SKEL_SHIFT_LEFT_ALIGN(6) + +#define RUN_COMMAND(format, ...) do { \ + char cmd[512]; \ + snprintf(cmd, 512, format, ##__VA_ARGS__); \ + system(cmd); \ + } while(0); + +AX_VOID LogSaveToFile(FILE *file, const char *fmt, ...) { + if (file) { + va_list args; + char szLog[1024] = {0}; + + va_start(args, fmt); + + AX_U32 len = vsnprintf(szLog, sizeof(szLog), (char *)fmt, args); + if (len < (AX_U32)sizeof(szLog)) { + szLog[len] = '\0'; + } else { + szLog[sizeof(szLog) - 1] = '\0'; + } + + fwrite((AX_U8 *)szLog, 1, strlen(szLog), file); + + va_end(args); + } +} +#define OUTPUT_LOG_SAVE(fmt, ...) LogSaveToFile(fpResultFile, fmt "\n", ##__VA_ARGS__) +#define BLACK_VIDEO_FRAME_COUNT 60 +#define SKEL_SAMPLE_OBJECT_SIZE 512 + +struct skeleton { + int connection[2]; + int left_right_neutral; +}; + +struct skeleton pairs[] = {{{15, 13}, 0}, {{13, 11}, 0}, {{16, 14}, 0}, {{14, 12}, 0}, {{11, 12}, 0}, + {{5, 11}, 0}, {{6, 12}, 0}, {{5, 6}, 0}, {{5, 7}, 0}, {{6, 8}, 0}, + {{7, 9}, 0}, {{8, 10}, 0}, {{1, 2}, 0}, {{0, 1}, 0}, {{0, 2}, 0}, + {{1, 3}, 0}, {{2, 4}, 0}, {{0, 5}, 0}, {{0, 6}, 0}}; + +#define DETECT_SKEL_POINT_COUNT 256 + +typedef struct _AI_Detection_Box_t { + AX_F32 fX, fY, fW, fH; +} AI_Detection_Box_t; + +typedef struct _AI_Detection_Point_t { + AX_F32 fX, fY; +} AI_Detection_Point_t; + +typedef struct _AI_Detection_SkelResult_t { + const AX_CHAR *pstrObjectCategory; + AX_U8 nPointNum; + AI_Detection_Point_t tPoint[DETECT_SKEL_POINT_COUNT]; + AI_Detection_Box_t tBox; +} AI_Detection_SkelResult_t; + +static AX_U64 get_tick_count(AX_VOID) { + struct timespec ts; + clock_gettime(CLOCK_MONOTONIC, &ts); + return (ts.tv_sec * 1000 + ts.tv_nsec / 1000000); +} + +// static AX_U64 get_tick_count_us(AX_VOID) { +// struct timespec ts; +// clock_gettime(CLOCK_MONOTONIC, &ts); +// return (ts.tv_sec * 1000000 + ts.tv_nsec / 1000); +// } + +static AX_VOID ShowUsage(AX_VOID) { + // printf("usage: ./%s ...\n", SAMPLE_SKEL_NAME); + printf("options:\n"); + printf("-i, \tInput File(yuv)\n"); + printf("-r, \tInput File Resolution(wxh)(yuv: should be input)\n"); + printf("-w, \tWrite result image to new jpg file((unsigned int), default=0)\n"); + printf("-o, \tSave result to file(file name)\n"); + printf("-m, \tModels deployment path(path name)\n"); + printf("-t, \tRepeat times((unsigned int), default=1)\n"); + printf("-I, \tInterval repeat time((unsigned int)ms, default=0)\n"); + printf("-c, \tConfidence((float: 0-1), default=0)\n"); + printf("-H, \tHuman track size limit((unsigned int), default=0)\n"); + printf("-V, \tVehicle track size limit((unsigned int), default=0)\n"); + printf("-C, \tCylcle track size limit((unsigned int), default=0)\n"); + printf("-d, \tSkel detect type((unsigned int), default=2)\n" + "\t\t0: detect only\n" + "\t\t1: detect + track\n" + "\t\t2: detect + track + push\n"); + printf("-u, \tSkel push strategy((unsigned int), default=3)\n" + "\t\t1: fast push strategy\n" + "\t\t2: push strategy\n" + "\t\t3: best push strategy\n"); + printf("-N, \tSkel NPU type((unsigned int), default=0(VNPU Disable)\n" + "\t\t0: VNPU Disable\n" + "\t\t1: STD-VNPU Default\n" + "\t\t2: STD-VNPU1\n" + "\t\t3: STD-VNPU2\n"); + printf("-p, \tSkel PPL((unsigned int), default=1)\n" + "\t\t1: AX_SKEL_PPL_HVCP\n" + "\t\t2: AX_SKEL_PPL_FACE\n"); + printf("-v, \tLog level((unsigned int), default=5)\n" + "\t\t0: LOG_EMERGENCY_LEVEL\n" + "\t\t1: LOG_ALERT_LEVEL\n" + "\t\t2: LOG_CRITICAL_LEVEL\n" + "\t\t3: LOG_ERROR_LEVEL\n" + "\t\t4: LOG_WARN_LEVEL\n" + "\t\t5: LOG_NOTICE_LEVEL\n" + "\t\t6: LOG_INFO_LEVEL\n" + "\t\t7: LOG_DEBUG_LEVEL\n"); + printf("-h, \tprint this message\n"); +} + +AX_S32 ParseConfigParam(const AX_SKEL_CONFIG_T *pstConfig) { + if (pstConfig->nSize > 0 && pstConfig->pstItems) { + for (size_t i = 0; i < pstConfig->nSize; i++) { + if (pstConfig->pstItems[i].pstrType && pstConfig->pstItems[i].pstrValue) { + // cmd: "body_max_target_count", value_type: AX_SKEL_COMMON_THRESHOLD_CONFIG_T * + if (strcmp(pstConfig->pstItems[i].pstrType, "body_max_target_count") == 0) { + if (pstConfig->pstItems[i].nValueSize == sizeof(AX_SKEL_COMMON_THRESHOLD_CONFIG_T)) { + AX_SKEL_COMMON_THRESHOLD_CONFIG_T *pstConf = + (AX_SKEL_COMMON_THRESHOLD_CONFIG_T *)pstConfig->pstItems[i].pstrValue; + ALOGI("SKEL get %s: %d", pstConfig->pstItems[i].pstrType, (AX_U8)pstConf->fValue); + } else { + ALOGE("SKEL %s size(%d) no match", pstConfig->pstItems[i].pstrType, pstConfig->pstItems[i].nValueSize); + } + } + // cmd: "vehicle_max_target_count", value_type: AX_SKEL_COMMON_THRESHOLD_CONFIG_T * + else if (strcmp(pstConfig->pstItems[i].pstrType, "vehicle_max_target_count") == 0) { + if (pstConfig->pstItems[i].nValueSize == sizeof(AX_SKEL_COMMON_THRESHOLD_CONFIG_T)) { + AX_SKEL_COMMON_THRESHOLD_CONFIG_T *pstConf = + (AX_SKEL_COMMON_THRESHOLD_CONFIG_T *)pstConfig->pstItems[i].pstrValue; + ALOGI("SKEL get %s: %d", pstConfig->pstItems[i].pstrType, (AX_U8)pstConf->fValue); + } else { + ALOGE("SKEL %s size(%d) no match", pstConfig->pstItems[i].pstrType, pstConfig->pstItems[i].nValueSize); + } + } + // cmd: "cycle_max_target_count", value_type: AX_SKEL_COMMON_THRESHOLD_CONFIG_T * + else if (strcmp(pstConfig->pstItems[i].pstrType, "cycle_max_target_count") == 0) { + if (pstConfig->pstItems[i].nValueSize == sizeof(AX_SKEL_COMMON_THRESHOLD_CONFIG_T)) { + AX_SKEL_COMMON_THRESHOLD_CONFIG_T *pstConf = + (AX_SKEL_COMMON_THRESHOLD_CONFIG_T *)pstConfig->pstItems[i].pstrValue; + ALOGI("SKEL get %s: %d", pstConfig->pstItems[i].pstrType, (AX_U8)pstConf->fValue); + } else { + ALOGE("SKEL %s size(%d) no match", pstConfig->pstItems[i].pstrType, pstConfig->pstItems[i].nValueSize); + } + } + // cmd: "body_confidence", value_type: AX_SKEL_COMMON_THRESHOLD_CONFIG_T * + else if (strcmp(pstConfig->pstItems[i].pstrType, "body_confidence") == 0) { + if (pstConfig->pstItems[i].nValueSize == sizeof(AX_SKEL_COMMON_THRESHOLD_CONFIG_T)) { + AX_SKEL_COMMON_THRESHOLD_CONFIG_T *pstConf = + (AX_SKEL_COMMON_THRESHOLD_CONFIG_T *)pstConfig->pstItems[i].pstrValue; + ALOGI("SKEL get %s: %f", pstConfig->pstItems[i].pstrType, pstConf->fValue); + } else { + ALOGE("SKEL %s size(%d) no match", pstConfig->pstItems[i].pstrType, pstConfig->pstItems[i].nValueSize); + } + } + // cmd: "face_confidence", value_type: AX_SKEL_COMMON_THRESHOLD_CONFIG_T * + else if (strcmp(pstConfig->pstItems[i].pstrType, "face_confidence") == 0) { + if (pstConfig->pstItems[i].nValueSize == sizeof(AX_SKEL_COMMON_THRESHOLD_CONFIG_T)) { + AX_SKEL_COMMON_THRESHOLD_CONFIG_T *pstConf = + (AX_SKEL_COMMON_THRESHOLD_CONFIG_T *)pstConfig->pstItems[i].pstrValue; + ALOGI("SKEL get %s: %f", pstConfig->pstItems[i].pstrType, pstConf->fValue); + } else { + ALOGE("SKEL %s size(%d) no match", pstConfig->pstItems[i].pstrType, pstConfig->pstItems[i].nValueSize); + } + } + // cmd: "vehicle_confidence", value_type: AX_SKEL_COMMON_THRESHOLD_CONFIG_T * + else if (strcmp(pstConfig->pstItems[i].pstrType, "vehicle_confidence") == 0) { + if (pstConfig->pstItems[i].nValueSize == sizeof(AX_SKEL_COMMON_THRESHOLD_CONFIG_T)) { + AX_SKEL_COMMON_THRESHOLD_CONFIG_T *pstConf = + (AX_SKEL_COMMON_THRESHOLD_CONFIG_T *)pstConfig->pstItems[i].pstrValue; + ALOGI("SKEL get %s: %f", pstConfig->pstItems[i].pstrType, pstConf->fValue); + } else { + ALOGE("SKEL %s size(%d) no match", pstConfig->pstItems[i].pstrType, pstConfig->pstItems[i].nValueSize); + } + } + // cmd: "cycle_confidence", value_type: AX_SKEL_COMMON_THRESHOLD_CONFIG_T * + else if (strcmp(pstConfig->pstItems[i].pstrType, "cycle_confidence") == 0) { + if (pstConfig->pstItems[i].nValueSize == sizeof(AX_SKEL_COMMON_THRESHOLD_CONFIG_T)) { + AX_SKEL_COMMON_THRESHOLD_CONFIG_T *pstConf = + (AX_SKEL_COMMON_THRESHOLD_CONFIG_T *)pstConfig->pstItems[i].pstrValue; + ALOGI("SKEL get %s: %f", pstConfig->pstItems[i].pstrType, pstConf->fValue); + } else { + ALOGE("SKEL %s size(%d) no match", pstConfig->pstItems[i].pstrType, pstConfig->pstItems[i].nValueSize); + } + } + // cmd: "plate_confidence", value_type: AX_SKEL_COMMON_THRESHOLD_CONFIG_T * + else if (strcmp(pstConfig->pstItems[i].pstrType, "plate_confidence") == 0) { + if (pstConfig->pstItems[i].nValueSize == sizeof(AX_SKEL_COMMON_THRESHOLD_CONFIG_T)) { + AX_SKEL_COMMON_THRESHOLD_CONFIG_T *pstConf = + (AX_SKEL_COMMON_THRESHOLD_CONFIG_T *)pstConfig->pstItems[i].pstrValue; + ALOGI("SKEL get %s: %f", pstConfig->pstItems[i].pstrType, pstConf->fValue); + } else { + ALOGE("SKEL %s size(%d) no match", pstConfig->pstItems[i].pstrType, pstConfig->pstItems[i].nValueSize); + } + } + // cmd: "crop_encoder_qpLevel", value_type: AX_SKEL_COMMON_THRESHOLD_CONFIG_T * + else if (strcmp(pstConfig->pstItems[i].pstrType, "crop_encoder_qpLevel") == 0) { + if (pstConfig->pstItems[i].nValueSize == sizeof(AX_SKEL_COMMON_THRESHOLD_CONFIG_T)) { + AX_SKEL_COMMON_THRESHOLD_CONFIG_T *pstConf = + (AX_SKEL_COMMON_THRESHOLD_CONFIG_T *)pstConfig->pstItems[i].pstrValue; + ALOGI("SKEL get %s: %f", pstConfig->pstItems[i].pstrType, pstConf->fValue); + } else { + ALOGE("SKEL %s size(%d) no match", pstConfig->pstItems[i].pstrType, pstConfig->pstItems[i].nValueSize); + } + } + // cmd: "body_min_size", value_type: AX_SKEL_OBJECT_SIZE_FILTER_CONFIG_T * + else if (strcmp(pstConfig->pstItems[i].pstrType, "body_min_size") == 0) { + if (pstConfig->pstItems[i].nValueSize == sizeof(AX_SKEL_OBJECT_SIZE_FILTER_CONFIG_T)) { + AX_SKEL_OBJECT_SIZE_FILTER_CONFIG_T *pstConf = + (AX_SKEL_OBJECT_SIZE_FILTER_CONFIG_T *)pstConfig->pstItems[i].pstrValue; + ALOGI("SKEL get %s %dx%d", pstConfig->pstItems[i].pstrType, pstConf->nWidth, pstConf->nHeight); + } else { + ALOGE("SKEL %s size(%d) no match", pstConfig->pstItems[i].pstrType, pstConfig->pstItems[i].nValueSize); + } + } + // cmd: "face_min_size", value_type: AX_SKEL_OBJECT_SIZE_FILTER_CONFIG_T * + else if (strcmp(pstConfig->pstItems[i].pstrType, "face_min_size") == 0) { + if (pstConfig->pstItems[i].nValueSize == sizeof(AX_SKEL_OBJECT_SIZE_FILTER_CONFIG_T)) { + AX_SKEL_OBJECT_SIZE_FILTER_CONFIG_T *pstConf = + (AX_SKEL_OBJECT_SIZE_FILTER_CONFIG_T *)pstConfig->pstItems[i].pstrValue; + ALOGI("SKEL get %s %dx%d", pstConfig->pstItems[i].pstrType, pstConf->nWidth, pstConf->nHeight); + } else { + ALOGE("SKEL %s size(%d) no match", pstConfig->pstItems[i].pstrType, pstConfig->pstItems[i].nValueSize); + } + } + // cmd: "vehicle_min_size", value_type: AX_SKEL_OBJECT_SIZE_FILTER_CONFIG_T * + else if (strcmp(pstConfig->pstItems[i].pstrType, "vehicle_min_size") == 0) { + if (pstConfig->pstItems[i].nValueSize == sizeof(AX_SKEL_OBJECT_SIZE_FILTER_CONFIG_T)) { + AX_SKEL_OBJECT_SIZE_FILTER_CONFIG_T *pstConf = + (AX_SKEL_OBJECT_SIZE_FILTER_CONFIG_T *)pstConfig->pstItems[i].pstrValue; + ALOGI("SKEL get %s %dx%d", pstConfig->pstItems[i].pstrType, pstConf->nWidth, pstConf->nHeight); + } else { + ALOGE("SKEL %s size(%d) no match", pstConfig->pstItems[i].pstrType, pstConfig->pstItems[i].nValueSize); + } + } + // cmd: "cycle_min_size", value_type: AX_SKEL_OBJECT_SIZE_FILTER_CONFIG_T * + else if (strcmp(pstConfig->pstItems[i].pstrType, "cycle_min_size") == 0) { + if (pstConfig->pstItems[i].nValueSize == sizeof(AX_SKEL_OBJECT_SIZE_FILTER_CONFIG_T)) { + AX_SKEL_OBJECT_SIZE_FILTER_CONFIG_T *pstConf = + (AX_SKEL_OBJECT_SIZE_FILTER_CONFIG_T *)pstConfig->pstItems[i].pstrValue; + ALOGI("SKEL get %s %dx%d", pstConfig->pstItems[i].pstrType, pstConf->nWidth, pstConf->nHeight); + } else { + ALOGE("SKEL %s size(%d) no match", pstConfig->pstItems[i].pstrType, pstConfig->pstItems[i].nValueSize); + } + } + // cmd: "plate_min_size", value_type: AX_SKEL_OBJECT_SIZE_FILTER_CONFIG_T * + else if (strcmp(pstConfig->pstItems[i].pstrType, "plate_min_size") == 0) { + if (pstConfig->pstItems[i].nValueSize == sizeof(AX_SKEL_OBJECT_SIZE_FILTER_CONFIG_T)) { + AX_SKEL_OBJECT_SIZE_FILTER_CONFIG_T *pstConf = + (AX_SKEL_OBJECT_SIZE_FILTER_CONFIG_T *)pstConfig->pstItems[i].pstrValue; + ALOGI("SKEL get %s %dx%d", pstConfig->pstItems[i].pstrType, pstConf->nWidth, pstConf->nHeight); + } else { + ALOGE("SKEL %s size(%d) no match", pstConfig->pstItems[i].pstrType, pstConfig->pstItems[i].nValueSize); + } + } + // cmd: "detect_roi_polygon", value_type: AX_SKEL_ROI_POLYGON_CONFIG_T * + else if (strcmp(pstConfig->pstItems[i].pstrType, "detect_roi_polygon") == 0) { + if (pstConfig->pstItems[i].nValueSize == sizeof(AX_SKEL_ROI_POLYGON_CONFIG_T)) { + AX_SKEL_ROI_POLYGON_CONFIG_T *pstConf = (AX_SKEL_ROI_POLYGON_CONFIG_T *)pstConfig->pstItems[i].pstrValue; + ALOGI("SKEL get %s [%d]: nPointNum[%d]", pstConfig->pstItems[i].pstrType, pstConf->bEnable, pstConf->nPointNum); + } else { + ALOGE("SKEL %s size(%d) no match", pstConfig->pstItems[i].pstrType, pstConfig->pstItems[i].nValueSize); + } + } + // cmd: "push_strategy", value_type: AX_SKEL_PUSH_STRATEGY_T * + else if (strcmp(pstConfig->pstItems[i].pstrType, "push_strategy") == 0) { + if (pstConfig->pstItems[i].nValueSize == sizeof(AX_SKEL_PUSH_STRATEGY_T)) { + AX_SKEL_PUSH_STRATEGY_T *pstConf = (AX_SKEL_PUSH_STRATEGY_T *)pstConfig->pstItems[i].pstrValue; + ALOGI("SKEL get %s [mode:%d, times:%d, count:%d, same:%d]", pstConfig->pstItems[i].pstrType, pstConf->ePushMode, pstConf->nIntervalTimes, + pstConf->nPushCounts, pstConf->bPushSameFrame); + } else { + ALOGE("SKEL %s size(%d) no match", pstConfig->pstItems[i].pstrType, pstConfig->pstItems[i].nValueSize); + } + } + // cmd: "body_crop_encoder", value_type: AX_SKEL_CROP_ENCODER_THRESHOLD_CONFIG_T * + else if (strcmp(pstConfig->pstItems[i].pstrType, "body_crop_encoder") == 0) { + if (pstConfig->pstItems[i].nValueSize == sizeof(AX_SKEL_CROP_ENCODER_THRESHOLD_CONFIG_T)) { + AX_SKEL_CROP_ENCODER_THRESHOLD_CONFIG_T *pstConf = (AX_SKEL_CROP_ENCODER_THRESHOLD_CONFIG_T *)pstConfig->pstItems[i].pstrValue; + ALOGI("SKEL get %s [%f, %f, %f, %f]", pstConfig->pstItems[i].pstrType, + pstConf->fScaleLeft, pstConf->fScaleRight, + pstConf->fScaleTop, pstConf->fScaleBottom); + } else { + ALOGE("SKEL %s size(%d) no match", pstConfig->pstItems[i].pstrType, pstConfig->pstItems[i].nValueSize); + } + } + // cmd: "vehicle_crop_encoder", value_type: AX_SKEL_CROP_ENCODER_THRESHOLD_CONFIG_T * + else if (strcmp(pstConfig->pstItems[i].pstrType, "vehicle_crop_encoder") == 0) { + if (pstConfig->pstItems[i].nValueSize == sizeof(AX_SKEL_CROP_ENCODER_THRESHOLD_CONFIG_T)) { + AX_SKEL_CROP_ENCODER_THRESHOLD_CONFIG_T *pstConf = (AX_SKEL_CROP_ENCODER_THRESHOLD_CONFIG_T *)pstConfig->pstItems[i].pstrValue; + ALOGI("SKEL get %s [%f, %f, %f, %f]", pstConfig->pstItems[i].pstrType, + pstConf->fScaleLeft, pstConf->fScaleRight, + pstConf->fScaleTop, pstConf->fScaleBottom); + } else { + ALOGE("SKEL %s size(%d) no match", pstConfig->pstItems[i].pstrType, pstConfig->pstItems[i].nValueSize); + } + } + // cmd: "cycle_crop_encoder", value_type: AX_SKEL_CROP_ENCODER_THRESHOLD_CONFIG_T * + else if (strcmp(pstConfig->pstItems[i].pstrType, "cycle_crop_encoder") == 0) { + if (pstConfig->pstItems[i].nValueSize == sizeof(AX_SKEL_CROP_ENCODER_THRESHOLD_CONFIG_T)) { + AX_SKEL_CROP_ENCODER_THRESHOLD_CONFIG_T *pstConf = (AX_SKEL_CROP_ENCODER_THRESHOLD_CONFIG_T *)pstConfig->pstItems[i].pstrValue; + ALOGI("SKEL get %s [%f, %f, %f, %f]", pstConfig->pstItems[i].pstrType, + pstConf->fScaleLeft, pstConf->fScaleRight, + pstConf->fScaleTop, pstConf->fScaleBottom); + } else { + ALOGE("SKEL %s size(%d) no match", pstConfig->pstItems[i].pstrType, pstConfig->pstItems[i].nValueSize); + } + } + // cmd: "face_crop_encoder", value_type: AX_SKEL_CROP_ENCODER_THRESHOLD_CONFIG_T * + else if (strcmp(pstConfig->pstItems[i].pstrType, "face_crop_encoder") == 0) { + if (pstConfig->pstItems[i].nValueSize == sizeof(AX_SKEL_CROP_ENCODER_THRESHOLD_CONFIG_T)) { + AX_SKEL_CROP_ENCODER_THRESHOLD_CONFIG_T *pstConf = (AX_SKEL_CROP_ENCODER_THRESHOLD_CONFIG_T *)pstConfig->pstItems[i].pstrValue; + ALOGI("SKEL get %s [%f, %f, %f, %f]", pstConfig->pstItems[i].pstrType, + pstConf->fScaleLeft, pstConf->fScaleRight, + pstConf->fScaleTop, pstConf->fScaleBottom); + } else { + ALOGE("SKEL %s size(%d) no match", pstConfig->pstItems[i].pstrType, pstConfig->pstItems[i].nValueSize); + } + } + // cmd: "plate_crop_encoder", value_type: AX_SKEL_CROP_ENCODER_THRESHOLD_CONFIG_T * + else if (strcmp(pstConfig->pstItems[i].pstrType, "plate_crop_encoder") == 0) { + if (pstConfig->pstItems[i].nValueSize == sizeof(AX_SKEL_CROP_ENCODER_THRESHOLD_CONFIG_T)) { + AX_SKEL_CROP_ENCODER_THRESHOLD_CONFIG_T *pstConf = (AX_SKEL_CROP_ENCODER_THRESHOLD_CONFIG_T *)pstConfig->pstItems[i].pstrValue; + ALOGI("SKEL get %s [%f, %f, %f, %f]", pstConfig->pstItems[i].pstrType, + pstConf->fScaleLeft, pstConf->fScaleRight, + pstConf->fScaleTop, pstConf->fScaleBottom); + } else { + ALOGE("SKEL %s size(%d) no match", pstConfig->pstItems[i].pstrType, pstConfig->pstItems[i].nValueSize); + } + } + // cmd: "push_panorama", value_type: AX_SKEL_PUSH_PANORAMA_CONFIG_T * + else if (strcmp(pstConfig->pstItems[i].pstrType, "push_panorama") == 0) { + if (pstConfig->pstItems[i].nValueSize == sizeof(AX_SKEL_PUSH_PANORAMA_CONFIG_T)) { + AX_SKEL_PUSH_PANORAMA_CONFIG_T *pstConf = (AX_SKEL_PUSH_PANORAMA_CONFIG_T *)pstConfig->pstItems[i].pstrValue; + ALOGI("SKEL get %s [Enable: %d, Quality: %d]", pstConfig->pstItems[i].pstrType, + pstConf->bEnable, pstConf->nQuality); + } else { + ALOGE("SKEL %s size(%d) no match", pstConfig->pstItems[i].pstrType, pstConfig->pstItems[i].nValueSize); + } + } + // cmd: "push_quality_body", value_type: AX_SKEL_ATTR_FILTER_CONFIG_T * + else if (strcmp(pstConfig->pstItems[i].pstrType, "push_quality_body") == 0) { + if (pstConfig->pstItems[i].nValueSize == sizeof(AX_SKEL_ATTR_FILTER_CONFIG_T)) { + AX_SKEL_ATTR_FILTER_CONFIG_T *pstConf = (AX_SKEL_ATTR_FILTER_CONFIG_T *)pstConfig->pstItems[i].pstrValue; + ALOGI("SKEL get %s [Q: %f]", pstConfig->pstItems[i].pstrType, pstConf->stCommonAttrFilterConfig.fQuality); + } else { + ALOGE("SKEL %s size(%d) no match", pstConfig->pstItems[i].pstrType, pstConfig->pstItems[i].nValueSize); + } + } + // cmd: "push_quality_vehicle", value_type: AX_SKEL_ATTR_FILTER_CONFIG_T * + else if (strcmp(pstConfig->pstItems[i].pstrType, "push_quality_vehicle") == 0) { + if (pstConfig->pstItems[i].nValueSize == sizeof(AX_SKEL_ATTR_FILTER_CONFIG_T)) { + AX_SKEL_ATTR_FILTER_CONFIG_T *pstConf = (AX_SKEL_ATTR_FILTER_CONFIG_T *)pstConfig->pstItems[i].pstrValue; + ALOGI("SKEL get %s [Q: %f]", pstConfig->pstItems[i].pstrType, pstConf->stCommonAttrFilterConfig.fQuality); + } else { + ALOGE("SKEL %s size(%d) no match", pstConfig->pstItems[i].pstrType, pstConfig->pstItems[i].nValueSize); + } + } + // cmd: "push_quality_cycle", value_type: AX_SKEL_ATTR_FILTER_CONFIG_T * + else if (strcmp(pstConfig->pstItems[i].pstrType, "push_quality_cycle") == 0) { + if (pstConfig->pstItems[i].nValueSize == sizeof(AX_SKEL_ATTR_FILTER_CONFIG_T)) { + AX_SKEL_ATTR_FILTER_CONFIG_T *pstConf = (AX_SKEL_ATTR_FILTER_CONFIG_T *)pstConfig->pstItems[i].pstrValue; + ALOGI("SKEL get %s [Q: %f]", pstConfig->pstItems[i].pstrType, pstConf->stCommonAttrFilterConfig.fQuality); + } else { + ALOGE("SKEL %s size(%d) no match", pstConfig->pstItems[i].pstrType, pstConfig->pstItems[i].nValueSize); + } + } + // cmd: "push_quality_face", value_type: AX_SKEL_ATTR_FILTER_CONFIG_T * + else if (strcmp(pstConfig->pstItems[i].pstrType, "push_quality_face") == 0) { + if (pstConfig->pstItems[i].nValueSize == sizeof(AX_SKEL_ATTR_FILTER_CONFIG_T)) { + AX_SKEL_ATTR_FILTER_CONFIG_T *pstConf = (AX_SKEL_ATTR_FILTER_CONFIG_T *)pstConfig->pstItems[i].pstrValue; + ALOGI("SKEL get %s [W: %d, H: %d, P: %f, Y: %f, R: %f, B: %f]", pstConfig->pstItems[i].pstrType, + pstConf->stFaceAttrFilterConfig.nWidth, pstConf->stFaceAttrFilterConfig.nHeight, + pstConf->stFaceAttrFilterConfig.stPoseblur.fPitch, pstConf->stFaceAttrFilterConfig.stPoseblur.fYaw, + pstConf->stFaceAttrFilterConfig.stPoseblur.fRoll, pstConf->stFaceAttrFilterConfig.stPoseblur.fBlur); + } else { + ALOGE("SKEL %s size(%d) no match", pstConfig->pstItems[i].pstrType, pstConfig->pstItems[i].nValueSize); + } + } + // cmd: "push_quality_plate", value_type: AX_SKEL_ATTR_FILTER_CONFIG_T * + else if (strcmp(pstConfig->pstItems[i].pstrType, "push_quality_plate") == 0) { + if (pstConfig->pstItems[i].nValueSize == sizeof(AX_SKEL_ATTR_FILTER_CONFIG_T)) { + AX_SKEL_ATTR_FILTER_CONFIG_T *pstConf = (AX_SKEL_ATTR_FILTER_CONFIG_T *)pstConfig->pstItems[i].pstrValue; + ALOGI("SKEL get %s [Q: %f]", pstConfig->pstItems[i].pstrType, pstConf->stCommonAttrFilterConfig.fQuality); + } else { + ALOGE("SKEL %s size(%d) no match", pstConfig->pstItems[i].pstrType, pstConfig->pstItems[i].nValueSize); + } + } + // cmd: "push_bind_enable", value_type: AX_SKEL_COMMON_THRESHOLD_CONFIG_T * + else if (strcmp(pstConfig->pstItems[i].pstrType, "push_bind_enable") == 0) { + if (pstConfig->pstItems[i].nValueSize == sizeof(AX_SKEL_COMMON_THRESHOLD_CONFIG_T)) { + AX_SKEL_COMMON_THRESHOLD_CONFIG_T *pstConf = (AX_SKEL_COMMON_THRESHOLD_CONFIG_T *)pstConfig->pstItems[i].pstrValue; + ALOGI("SKEL get %s : %f", pstConfig->pstItems[i].pstrType, pstConf->fValue); + } else { + ALOGE("SKEL %s size(%d) no match", pstConfig->pstItems[i].pstrType, pstConfig->pstItems[i].nValueSize); + } + } + // cmd: "track_enable", value_type: AX_SKEL_COMMON_ENABLE_CONFIG_S * + else if (strcmp(pstConfig->pstItems[i].pstrType, "track_enable") == 0) { + if (pstConfig->pstItems[i].nValueSize == sizeof(AX_SKEL_COMMON_ENABLE_CONFIG_T)) { + AX_SKEL_COMMON_ENABLE_CONFIG_T *pstConf = (AX_SKEL_COMMON_ENABLE_CONFIG_T *)pstConfig->pstItems[i].pstrValue; + ALOGI("SKEL get %s : %d", pstConfig->pstItems[i].pstrType, pstConf->bEnable); + } else { + ALOGE("SKEL %s size(%d) no match", pstConfig->pstItems[i].pstrType, pstConfig->pstItems[i].nValueSize); + } + } + // cmd: "push_enable", value_type: AX_SKEL_COMMON_ENABLE_CONFIG_S * + else if (strcmp(pstConfig->pstItems[i].pstrType, "push_enable") == 0) { + if (pstConfig->pstItems[i].nValueSize == sizeof(AX_SKEL_COMMON_ENABLE_CONFIG_T)) { + AX_SKEL_COMMON_ENABLE_CONFIG_T *pstConf = (AX_SKEL_COMMON_ENABLE_CONFIG_T *)pstConfig->pstItems[i].pstrValue; + ALOGI("SKEL get %s : %d", pstConfig->pstItems[i].pstrType, pstConf->bEnable); + } else { + ALOGE("SKEL %s size(%d) no match", pstConfig->pstItems[i].pstrType, pstConfig->pstItems[i].nValueSize); + } + } + // cmd: "target_config", value_type: AX_SKEL_TARGET_CONFIG_T * + else if (strcmp(pstConfig->pstItems[i].pstrType, "target_config") == 0) { + if (pstConfig->pstItems[i].nValueSize == sizeof(AX_SKEL_TARGET_CONFIG_T)) { + AX_SKEL_TARGET_CONFIG_T *pstConf = (AX_SKEL_TARGET_CONFIG_T *)pstConfig->pstItems[i].pstrValue; + if (pstConf->pstItems) { + for (AX_U32 j = 0; j < pstConf->nSize; j ++) { + if (pstConf->pstItems[j].pstrObjectCategory) { + ALOGI("SKEL set %s: [%d]%s", pstConfig->pstItems[i].pstrType, j, pstConf->pstItems[j].pstrObjectCategory); + } + } + } + else { + ALOGE("SKEL cmd: %s invalid param", pstConfig->pstItems[i].pstrType); + } + } else { + ALOGE("SKEL %s size(%d) no match", pstConfig->pstItems[i].pstrType, pstConfig->pstItems[i].nValueSize); + } + } + // cmd: "push_target_config", value_type: AX_SKEL_TARGET_CONFIG_S * + else if (strcmp(pstConfig->pstItems[i].pstrType, "push_target_config") == 0) { + if (pstConfig->pstItems[i].nValueSize == sizeof(AX_SKEL_TARGET_CONFIG_T)) { + AX_SKEL_TARGET_CONFIG_T *pstConf = (AX_SKEL_TARGET_CONFIG_T *)pstConfig->pstItems[i].pstrValue; + if (pstConf->pstItems) { + for (AX_U32 j = 0; j < pstConf->nSize; j ++) { + if (pstConf->pstItems[j].pstrObjectCategory) { + ALOGI("SKEL set %s: [%d]%s", pstConfig->pstItems[i].pstrType, j, pstConf->pstItems[j].pstrObjectCategory); + } + } + } + else { + ALOGE("SKEL cmd: %s invalid param", pstConfig->pstItems[i].pstrType); + } + } else { + ALOGE("SKEL %s size(%d) no match", pstConfig->pstItems[i].pstrType, pstConfig->pstItems[i].nValueSize); + } + } + // cmd: "analyzer_attr_config", value_type: AX_SKEL_ANALYZER_CONFIG_T * + else if (strcmp(pstConfig->pstItems[i].pstrType, "analyzer_attr_config") == 0) { + if (pstConfig->pstItems[i].nValueSize == sizeof(AX_SKEL_ANALYZER_CONFIG_T)) { + AX_SKEL_ANALYZER_CONFIG_T *pstConf = (AX_SKEL_ANALYZER_CONFIG_T *)pstConfig->pstItems[i].pstrValue; + if (pstConf->peItems) { + for (AX_U32 j = 0; j < pstConf->nSize; j ++) { + ALOGI("SKEL set %s: [%d]%d", pstConfig->pstItems[i].pstrType, j, pstConf->peItems[j]); + } + } + else { + ALOGE("SKEL cmd: %s invalid param", pstConfig->pstItems[i].pstrType); + } + } else { + ALOGE("SKEL %s size(%d) no match", pstConfig->pstItems[i].pstrType, pstConfig->pstItems[i].nValueSize); + } + } + // cmd: "venc_attr_config", value_type: AX_SKEL_COMMON_THRESHOLD_CONFIG_S * + else if (strcmp(pstConfig->pstItems[i].pstrType, "venc_attr_config") == 0) { + if (pstConfig->pstItems[i].nValueSize == sizeof(AX_SKEL_COMMON_THRESHOLD_CONFIG_T)) { + AX_SKEL_COMMON_THRESHOLD_CONFIG_T *pstConf = (AX_SKEL_COMMON_THRESHOLD_CONFIG_T *)pstConfig->pstItems[i].pstrValue; + ALOGI("SKEL set %s: %d", pstConfig->pstItems[i].pstrType, (AX_U32)pstConf->fValue); + } else { + ALOGE("SKEL %s size(%d) no match", pstConfig->pstItems[i].pstrType, pstConfig->pstItems[i].nValueSize); + } + } + // cmd: "push_attr_always", value_type: AX_SKEL_COMMON_ENABLE_CONFIG_S * + else if (strcmp(pstConfig->pstItems[i].pstrType, "push_attr_always") == 0) { + if (pstConfig->pstItems[i].nValueSize == sizeof(AX_SKEL_COMMON_ENABLE_CONFIG_T)) { + AX_SKEL_COMMON_ENABLE_CONFIG_T *pstConf = (AX_SKEL_COMMON_ENABLE_CONFIG_T *)pstConfig->pstItems[i].pstrValue; + ALOGI("SKEL set %s: %d", pstConfig->pstItems[i].pstrType, pstConf->bEnable); + } else { + ALOGE("SKEL %s size(%d) no match", pstConfig->pstItems[i].pstrType, pstConfig->pstItems[i].nValueSize); + } + } + else { + ALOGE("SKEL cmd: %s not support", pstConfig->pstItems[i].pstrType); + } + } + } + } + + return 0; +} + +FILE* LoadFile(const AX_CHAR *pFile, AX_U64 *pLen) +{ + /* Reading input file */ + FILE *f_in = fopen(pFile, "rb"); + + if (f_in) { + if (pLen) { + fseeko(f_in, 0L, SEEK_END); + AX_U64 nFileSize = ftello(f_in); + rewind(f_in); + + *pLen = (AX_U64)nFileSize; + } + } + + return f_in; +} + +int ReLoadFile(FILE* pFile) +{ + if (pFile) { + rewind(pFile); + return 0; + } + + return -1; +} + +int NV12ToStrideNV12(AX_U64 nSrcPhyAddr, + AX_VOID *pSrcVirAddr, + AX_U32 nSrcSize, + AX_U32 nSrcStride, + AX_U32 nSrcHeight, + AX_U64 nDstPhyAddr, + AX_VOID *pDstVirAddr, + AX_U32 nDstSize, + AX_U32 nDstStride, + AX_U32 nDstHeight + ) { + AX_U64 nStartTime = get_tick_count(); + + // src check + if (!pSrcVirAddr) { + return -1; + } + + if (nSrcSize != nSrcStride * nSrcHeight * 3 /2) { + return -1; + } + + // dst check + if (!pDstVirAddr) { + return -1; + } + + if (nDstSize != nDstStride * nDstHeight * 3 /2) { + return -1; + } + + if (nDstSize < nSrcSize) { + return -1; + } + + if (nDstStride < nSrcStride) { + return -1; + } + + if (nDstHeight != nSrcHeight) { + return -1; + } + + AX_VOID *src = pSrcVirAddr; + AX_VOID *dst = pDstVirAddr; + for(AX_U32 i = 0; i < nSrcHeight * 3 / 2; i++) { + memcpy(dst, src, nSrcStride); + src += nSrcStride; + dst += nDstStride; + } + + AX_U64 nProcessElasped = get_tick_count() - nStartTime; + + ALOGD("NV12ToStrideNV12 %dx%d=>%dx%d elapse: %lld ms", nSrcStride, nSrcHeight, nDstStride, nDstHeight, nProcessElasped); + + return 0; +} + +int LoadFileToMem(FILE *pFile, AX_U64 nPhyAddr, AX_VOID *pVirAddr, AX_S32 nSize) +{ + AX_S32 nReadSize = 0; + + if (pFile) { + if (nPhyAddr != 0 && pVirAddr) { + memset((AX_U8 *)pVirAddr, 0x00, nSize); + nReadSize = fread((AX_U8 *)pVirAddr, 1, nSize, pFile); + } + else { + fseeko(pFile, nSize, SEEK_CUR); + } + } + + return nReadSize; +} + +int DecodeJpeg(FILE* InputFileHandle, AX_U64 OneYUVDataPhy, AX_VOID* OneYUVDataVir, AX_U32 nWidth, AX_U32 nHeight) +{ + SAMPLE_INPUT_FILE_INFO_T stStreamInfo; + SAMPLE_STREAM_BUF_T stStreamBuf; + size_t nReadLen = 0; + AX_U64 streamPhyAddr = 0; + AX_VOID *pStreamVirAddr = NULL; + AX_VDEC_DEC_ONE_FRM_T decOneFrmParam; + size_t nFileSize = 0; + AX_U32 heightAlign = 0; + AX_U32 frmStride = 0; + frmStride = AX_COMM_ALIGN(nWidth * 8, AX_VDEC_WIDTH_ALIGN * 8) / 8; + heightAlign = ALIGN_UP(nHeight, 16); + AX_U32 nFrameSize = heightAlign * frmStride * 3 / 2; + + memset(&stStreamInfo, 0, sizeof(SAMPLE_INPUT_FILE_INFO_T)); + memset(&stStreamBuf, 0, sizeof(SAMPLE_STREAM_BUF_T)); + memset(&decOneFrmParam, 0, sizeof(AX_VDEC_DEC_ONE_FRM_T)); + + rewind(InputFileHandle); + fseek(InputFileHandle, 0, SEEK_END); + nFileSize = (size_t)ftello(InputFileHandle); + + stStreamInfo.fInput = InputFileHandle; + stStreamInfo.sFileSize = nFileSize; + + stStreamBuf.uBufSize = ((AX_U32)nFileSize) > STREAM_BUFFER_MAX_SIZE ? STREAM_BUFFER_MAX_SIZE : nFileSize; + int ret = AX_SYS_MemAlloc(&streamPhyAddr, (AX_VOID **)&pStreamVirAddr, + stStreamBuf.uBufSize, 0x100, (AX_S8 *)"vdec_input_stream"); + if (ret != AX_SUCCESS) { + ALOGE("AX_SYS_MemAlloc FAILED! uBufSize:0x%x ret:0x%x\n", + stStreamBuf.uBufSize, ret); + return -1; + } + + stStreamBuf.tBufAddr.pVirAddr = pStreamVirAddr; + stStreamBuf.tBufAddr.u64PhyAddr = streamPhyAddr; + + ret = StreamParserReadFrameJpeg(&stStreamInfo, &stStreamBuf, &nReadLen); + if (0 != ret) { + ALOGE("StreamParserReadFrameJpeg failed! ret = 0x%x", ret); + AX_SYS_MemFree(streamPhyAddr, pStreamVirAddr); + return -1; + } + + if (!nReadLen) { + ALOGE("read jpeg frame FAILED!\n"); + AX_SYS_MemFree(streamPhyAddr, pStreamVirAddr); + ret = AX_ERR_VDEC_STRM_ERROR; + return ret; + } + + decOneFrmParam.stStream.pu8Addr = (AX_U8*)stStreamBuf.tBufAddr.pVirAddr; + decOneFrmParam.stStream.u64PhyAddr = stStreamBuf.tBufAddr.u64PhyAddr; + decOneFrmParam.stStream.u32StreamPackLen = (AX_U32)nReadLen; + + decOneFrmParam.stFrame.u64VirAddr[0] = (AX_ULONG)OneYUVDataVir; + decOneFrmParam.stFrame.u64VirAddr[1] = (AX_ULONG)OneYUVDataVir + frmStride * heightAlign; + decOneFrmParam.stFrame.u64PhyAddr[0] = OneYUVDataPhy; + decOneFrmParam.stFrame.u64PhyAddr[1] = OneYUVDataPhy + frmStride * heightAlign; + decOneFrmParam.stFrame.u32FrameSize = nFrameSize; + + ret = AX_VDEC_JpegDecodeOneFrame(&decOneFrmParam); + if (ret != AX_SUCCESS) { + ALOGE("AX_VDEC_JpegDecodeOneFrame FAILED! ret:0x%x %s\n", + ret, SampleVdecRetStr(ret)); + AX_SYS_MemFree(streamPhyAddr, pStreamVirAddr); + return ret; + } + + AX_SYS_MemFree(streamPhyAddr, pStreamVirAddr); + + return 0; +} + +int LoadFileToMemExt(const AX_CHAR *pFile, AX_U64 *pPhyAddr, AX_VOID **ppVirAddr, AX_U32 *pLen) +{ + /* Reading input file */ + FILE *f_in = fopen(pFile, "rb"); + if (f_in == NULL) { + ALOGE("Unable to open input file\n"); + return -1; + } + + /* file i/o pointer to full */ + fseek(f_in, 0L, SEEK_END); + AX_U32 nFileSize = ftell(f_in); + rewind(f_in); + + if (pPhyAddr && ppVirAddr) { + AX_U64 nPhyAddr = 0; + AX_VOID *pVirAddr = NULL; + + // pVirAddr = (AX_VOID *)malloc(nFileSize); + AX_S32 nRet = AX_SYS_MemAlloc(&nPhyAddr, (AX_VOID **)&pVirAddr, nFileSize, 128, (AX_S8 *)"SKEL_TEST"); + + if (nRet != 0) { + fclose(f_in); + ALOGE("AX_SYS_MemAlloc failed"); + return -1; + } + + fread((AX_U8 *)pVirAddr, nFileSize, 1, f_in); + + *pPhyAddr = nPhyAddr; + *ppVirAddr = pVirAddr; + } + + if (pLen) { + *pLen = nFileSize; + } + + fclose(f_in); + + return 0; +} + +int EncodeOneFrameToJpeg(const AX_CHAR *dstFile, AX_U32 nStride, AX_U32 nWidth, AX_U32 nHeight, AX_U64 nPhyAddr, AX_VOID *pVirAddr, AX_U32 nLen) { + AX_S32 s32Ret = AX_SUCCESS; + + AX_U32 frameSize = nLen; + AX_JPEG_ENCODE_ONCE_PARAMS_T stJpegEncodeOnceParam; + memset(&stJpegEncodeOnceParam, 0, sizeof(stJpegEncodeOnceParam)); + + AX_U64 outPhyAddr = 0; + AX_VOID *outVirAddr = NULL; + + s32Ret = AX_SYS_MemAlloc(&outPhyAddr, &outVirAddr, frameSize, 128, (AX_S8 *)"SKEL-VENC"); + if (s32Ret) { + ALOGE("alloc mem err, size(%d).", frameSize); + return -1; + } + + // output + stJpegEncodeOnceParam.u32OutBufSize = frameSize; + stJpegEncodeOnceParam.ulPhyAddr = outPhyAddr; + stJpegEncodeOnceParam.pu8Addr = (AX_U8 *)outVirAddr; + + // input + stJpegEncodeOnceParam.stJpegParam.u32Qfactor = 90; + stJpegEncodeOnceParam.u32Width = nWidth; + stJpegEncodeOnceParam.u32Height = nHeight; + stJpegEncodeOnceParam.enImgFormat = AX_FORMAT_YUV420_SEMIPLANAR; + stJpegEncodeOnceParam.u32PicStride[0] = nStride; + stJpegEncodeOnceParam.u32PicStride[1] = stJpegEncodeOnceParam.u32PicStride[0]; + stJpegEncodeOnceParam.u32PicStride[2] = 0; + + stJpegEncodeOnceParam.u64PhyAddr[0] = nPhyAddr; + stJpegEncodeOnceParam.u64PhyAddr[1] = stJpegEncodeOnceParam.u64PhyAddr[0] + stJpegEncodeOnceParam.u32PicStride[0] * stJpegEncodeOnceParam.u32Height; + stJpegEncodeOnceParam.u64PhyAddr[2] = 0; + + stJpegEncodeOnceParam.u64VirAddr[0] = (AX_ULONG)pVirAddr; + stJpegEncodeOnceParam.u64VirAddr[1] = stJpegEncodeOnceParam.u64VirAddr[0] + stJpegEncodeOnceParam.u32PicStride[0] * stJpegEncodeOnceParam.u32Height; + stJpegEncodeOnceParam.u64VirAddr[2] = 0; + + s32Ret = AX_VENC_JpegEncodeOneFrame(&stJpegEncodeOnceParam); + if (AX_SUCCESS != s32Ret) { + ALOGE("AX_VENC_JpegEncodeOneFrame fail, ret=0x%x", s32Ret); + s32Ret = -1; + goto JENC_EXIT; + } + +JENC_EXIT: + if (0 == s32Ret && dstFile) { + FILE *fp_w = fopen(dstFile, "wb"); + + if (fp_w) { + ALOGN("\tWrite new JPG result image to file: %s", dstFile); + fwrite((AX_U8 *)stJpegEncodeOnceParam.pu8Addr, stJpegEncodeOnceParam.u32Len, 1, fp_w); + fclose(fp_w); + } + } + + if (outPhyAddr && (NULL != outVirAddr)) { + AX_SYS_MemFree(outPhyAddr, outVirAddr); + } + + return s32Ret; +} + +AX_BOOL FrameSkipCtrl(AX_S32 nSrcFrameRate, AX_S32 nDstFrameRate, AX_S32 nFrameSeqNum) { + if (nFrameSeqNum < 1) { + nFrameSeqNum = 1; + } + + if (nSrcFrameRate == nDstFrameRate) { + return AX_FALSE; + } + + if (nDstFrameRate > nSrcFrameRate) { + return AX_FALSE; + } + + if ((nFrameSeqNum * nDstFrameRate / (nSrcFrameRate)) > ((nFrameSeqNum - 1) * nDstFrameRate / (nSrcFrameRate))) { + return AX_FALSE; + } else { + return AX_TRUE; + } +} + +AX_S32 main(AX_S32 argc, AX_CHAR *argv[]) { + AX_S32 nRet = 0; + AX_S32 c; + AX_S32 isExit = 0; + AX_BOOL bJpgFile = AX_FALSE; + FILE *InputFileHandle = NULL; + const AX_CHAR *InputFile = NULL; + const AX_CHAR *InputResolution = NULL; + AX_S32 InputFileFrameCnt = 1; + const AX_CHAR *ReWritePath = NULL; + const AX_CHAR *SaveResultPath = NULL; + const AX_CHAR *ModelsPath = NULL; + FILE *fpResultFile = NULL; + AX_S32 nRepeatTimes = 1; + AX_S32 nPPL = AX_SKEL_PPL_HVCP; + AX_S32 nDetectType = 2; + AX_S32 nPushStrategy = 3; + AX_S32 nNpuType = 0; + AX_S32 nInterval = 0; + AX_U32 nStride = 1920; + AX_U32 nWidth = 1920; + AX_U32 nHeight = 1080; + AX_U32 nJencBufSize = 0; + AX_U32 nFrameDepth = 1; + AX_U32 nOneSize = 0; + AX_U64 OneYUVDataPhy = 0; + AX_VOID *OneYUVDataVir = NULL; + AX_U32 nFrameSize = nStride * nHeight * 3 / 2; + AX_U32 nCacheListDepth = 1; + AX_S32 nSrcFrameRate = 25; + AX_S32 nDstFrameRate = 25; + AX_VOID *YUVDataVir = NULL; + AX_U64 YUVDataPhy = 0; + AX_VOID *YUVDataWrVir = NULL; + AX_U64 YUVDataWrPhy = 0; + AX_SKEL_HANDLE pHandle = NULL; + AX_SKEL_FRAME_T stFrame = {0}; + AX_SKEL_RESULT_T *pstResult = NULL; + AX_U64 nFileSize = 0; + AX_U64 nStartTime = 0; + AX_U64 nInitElasped = 0; + AX_U64 nCreateElasped = 0; + AX_U64 nProcessElasped = 0; + AX_U64 nResultElasped = 0; + AX_U64 nResultElaspedMin = (AX_U64)-1; + AX_U64 nResultElaspedMax = 0; + AX_U64 nResultElaspedTotal = 0; + AX_F32 fConfidence = 0.0; + // AX_U32 nHumantracksize = 0; + // AX_U32 nVehicletracksize = 0; + // AX_U32 nCycletracksize = 0; + AX_U64 nSkelFrameId = 1; + +#if defined(SAMPLE_SKEL_BUILD_VERSION) + printf("SKEL sample: %s build: %s %s\n", SAMPLE_SKEL_BUILD_VERSION, __DATE__, __TIME__); +#endif + + while ((c = getopt(argc, argv, "i:r:I:w:o:m:t:d:u:p:j:v:c:N:H:V:C:h::")) != -1) { + isExit = 0; + switch (c) { + case 'i': + InputFile = (const AX_CHAR *)optarg; + break; + case 'r': + InputResolution = (const AX_CHAR *)optarg; + break; + case 'I': + nInterval = atoi(optarg); + break; + case 'w': + ReWritePath = (const AX_CHAR *)optarg; + break; + case 'o': + SaveResultPath = (const AX_CHAR *)optarg; + break; + case 'm': + ModelsPath = (const AX_CHAR *)optarg; + break; + case 't': + nRepeatTimes = atoi(optarg); + break; + case 'd': + nDetectType = atoi(optarg); + break; + case 'u': + nPushStrategy = atoi(optarg); + break; + case 'N': + nNpuType = atoi(optarg); + break; + case 'p': + nPPL = atoi(optarg); + break; + case 'j': + nJencBufSize = atoi(optarg); + break; + case 'c': + fConfidence = atof(optarg); + break; + // case 'H': + // nHumantracksize = atoi(optarg); + // break; + // case 'V': + // nVehicletracksize = atoi(optarg); + // break; + // case 'C': + // nCycletracksize = atoi(optarg); + // break; + case 'v': + log_level = atoi(optarg); + break; + case 'h': + isExit = 1; + break; + case 'D': + nCacheListDepth = atoi(optarg); + break; + default: + isExit = 1; + break; + } + } + + if (isExit || !InputFile || !InputResolution || (nPPL < AX_SKEL_PPL_HVCP) || (nPPL > AX_SKEL_PPL_MAX) + || (log_level < 0 || log_level >= SKEL_LOG_MAX) + || (fConfidence < 0 || fConfidence > 1) + || (nDetectType < 0 || nDetectType > 2) + || (nPushStrategy < 1 || nPushStrategy > 3) + || (nNpuType > 3)) { + ShowUsage(); + exit(0); + } + + if (InputFile) { + AX_U32 nInputFileLen = strlen(InputFile); + + if (nInputFileLen > 4 && (strcasecmp(&InputFile[nInputFileLen - 4], ".jpg") == 0)) { + bJpgFile = AX_TRUE; + } + } + + if (nRepeatTimes <= 0) { + nRepeatTimes = 1; + } + + if (nInterval < 0) { + nInterval = 0; + } + if (nCacheListDepth == 0) { + nCacheListDepth = 1; + } + nInterval = nInterval * 1000; + + if (access(InputFile, 0) != 0) { + ALOGE("%s not exist", InputFile); + exit(0); + } + + // clear output + if (SaveResultPath) { + RUN_COMMAND("rm -rf %s", SaveResultPath); + RUN_COMMAND("mkdir -p %s", SaveResultPath); + RUN_COMMAND("mkdir -p %s/%s", SaveResultPath, SKEL_SAMPLE_OUTPUT_BODY_PATH); + RUN_COMMAND("mkdir -p %s/%s", SaveResultPath, SKEL_SAMPLE_OUTPUT_VEHICLE_PATH); + RUN_COMMAND("mkdir -p %s/%s", SaveResultPath, SKEL_SAMPLE_OUTPUT_CYCLE_PATH); + RUN_COMMAND("mkdir -p %s/%s", SaveResultPath, SKEL_SAMPLE_OUTPUT_FACE_PATH); + RUN_COMMAND("mkdir -p %s/%s", SaveResultPath, SKEL_SAMPLE_OUTPUT_PLATE_PATH); + } + + if (ReWritePath) { + RUN_COMMAND("rm -rf %s", ReWritePath); + RUN_COMMAND("mkdir -p %s", ReWritePath); + } + + if (InputResolution) { + AX_CHAR *temp_p = strstr(InputResolution, "x"); + + if (!temp_p || strlen(temp_p) <= 1) { + ShowUsage(); + exit(0); + } + + nWidth = atoi(InputResolution); + nStride = nWidth; + nHeight = atoi(temp_p + 1); + } + + nRet = AX_SYS_Init(); + if (0 != nRet) { + ALOGE("AX_SYS_Init() fail, ret = 0x%x", nRet); + exit(0); + } + + nRet = AX_IVPS_Init(); + + ALOGI("AX_IVPS_Init nRet = 0x%x", nRet); + + AX_VENC_MOD_ATTR_T stVencModAttr; + memset(&stVencModAttr, 0x00, sizeof(stVencModAttr)); + stVencModAttr.enVencType = AX_VENC_MULTI_ENCODER; + stVencModAttr.stModThdAttr.u32TotalThreadNum = 1; + stVencModAttr.stModThdAttr.bExplicitSched = AX_FALSE; + nRet = AX_VENC_Init(&stVencModAttr); + if (AX_SUCCESS != nRet) { + ALOGE("AX_VENC_Init FAILED! ret:0x%x\n", nRet); + goto EXIT0; + } + + ALOGI("AX_VENC_Init nRet = 0x%x", nRet); + + nRet = AX_VDEC_Init(NULL); + if (AX_SUCCESS != nRet) { + ALOGE("AX_VDEC_Init FAILED! ret:0x%x\n", nRet); + goto EXIT0; + } + + ALOGI("AX_VDEC_Init nRet = 0x%x", nRet); + + // init engine + AX_ENGINE_NPU_ATTR_T npu_attr; + memset(&npu_attr, 0, sizeof(npu_attr)); +#if defined(CHIP_AX650) + if (nNpuType == 0) { + npu_attr.eHardMode = AX_ENGINE_VIRTUAL_NPU_DISABLE; + } + else if (nNpuType >= 1 && nNpuType <= 4) { + npu_attr.eHardMode = AX_ENGINE_VIRTUAL_NPU_STD; + } + else if (nNpuType >= 5 && nNpuType <= 7) { + npu_attr.eHardMode = AX_ENGINE_VIRTUAL_NPU_BIG_LITTLE; + } +#elif defined(CHIP_AX620E) + if (nNpuType == 0) { + npu_attr.eHardMode = AX_ENGINE_VIRTUAL_NPU_DISABLE; + } + else { + npu_attr.eHardMode = AX_ENGINE_VIRTUAL_NPU_ENABLE; + } +#else + // #error "NO CHIP SELECTED." +#endif + + nRet = AX_ENGINE_Init(&npu_attr); + if (0 != nRet) { + ALOGE("AX_NPU_SDK_EX_Init_with_attr() fail, ret = 0x%x", nRet); + goto EXIT0; + } + + nOneSize = nWidth * nHeight * 3 / 2; + nFrameSize = nStride * nHeight * 3 / 2; + + InputFileHandle = LoadFile(InputFile, &nFileSize); + + if (bJpgFile) { + InputFileFrameCnt = 1; + } + else { + if (!InputFileHandle + || (nFileSize % nOneSize) != 0) { + ALOGE("%s file is not %dx%d", InputFile, nWidth, nHeight); + goto EXIT1; + } + + InputFileFrameCnt = nFileSize / nOneSize; + } + + + if (nWidth%2 == 1 + || nHeight%2 == 1) { + ALOGE("wxh(%dx%d) should be even", nWidth, nHeight); + goto EXIT1; + } + + // YUVDataWrVir = (AX_VOID *)malloc(nFileSize); + nRet = AX_SYS_MemAlloc(&YUVDataWrPhy, &YUVDataWrVir, nFrameSize, 128, (const AX_S8 *)"SKEL_TEST"); + + if (!YUVDataWrVir) { + ALOGE("malloc fail nRet=0x%x", nRet); + goto EXIT1; + } + + if (SaveResultPath) { + AX_CHAR szPath[512] = {0}; + snprintf(szPath, 511, "%s/%s", SaveResultPath, SKEL_SAMPLE_OUTPUT_LOG_FILE); + fpResultFile = fopen(szPath, "a+"); + + if (!fpResultFile) { + ALOGE("%s file not exist", szPath); + goto EXIT1; + } + } + + nStartTime = get_tick_count(); + + AX_SKEL_INIT_PARAM_T stInitParam = {0}; + + if (ModelsPath) { + stInitParam.pStrModelDeploymentPath = ModelsPath; + } + else { + stInitParam.pStrModelDeploymentPath = "/opt/etc/skelModels"; + } + + nRet = AX_SKEL_Init(&stInitParam); + + nInitElasped = get_tick_count() - nStartTime; + + if (0 != nRet) { + ALOGE("SKEL init fail, ret = 0x%x", nRet); + + goto EXIT1; + } + + // get version + { + const AX_SKEL_VERSION_INFO_T *pstVersion = NULL; + + nRet = AX_SKEL_GetVersion(&pstVersion); + + if (0 != nRet) { + ALOGI("SKEL get version fail, ret = 0x%x", nRet); + + if (pstVersion) { + AX_SKEL_Release((AX_VOID *)pstVersion); + } + goto EXIT1; + } + + ALOGI("SKEL version: %s", pstVersion->pstrVersion); + + if (pstVersion) { + AX_SKEL_Release((AX_VOID *)pstVersion); + } + } + + // get capability + { + const AX_SKEL_CAPABILITY_T *pstCapability = NULL; + + nRet = AX_SKEL_GetCapability(&pstCapability); + + if (0 != nRet) { + ALOGI("SKEL get capability fail, ret = 0x%x", nRet); + + if (pstCapability) { + AX_SKEL_Release((AX_VOID *)pstCapability); + } + goto EXIT1; + } + + for (AX_U32 i = 0; i < pstCapability->nPPLConfigSize; i++) { + ALOGI("SKEL capability[%d]: (ePPL: %d, PPLConfigKey: %s)", i, pstCapability->pstPPLConfig[i].ePPL, + pstCapability->pstPPLConfig[i].pstrPPLConfigKey); + } + + if (pstCapability) { + AX_SKEL_Release((AX_VOID *)pstCapability); + } + } + + AX_SKEL_HANDLE_PARAM_T stHandleParam = {0}; + + stHandleParam.ePPL = (AX_SKEL_PPL_E)nPPL; + stHandleParam.nFrameDepth = nFrameDepth; + stHandleParam.nFrameCacheDepth = nCacheListDepth; + stHandleParam.nIoDepth = 0; + stHandleParam.nWidth = nWidth; + stHandleParam.nHeight = nHeight; + + // config settings (if need) + AX_SKEL_CONFIG_T stConfig = {0}; + AX_SKEL_CONFIG_ITEM_T stItems[16] = {0}; + AX_U8 itemIndex = 0; + stConfig.nSize = 0; + stConfig.pstItems = &stItems[0]; + + // venc_attr_config + // default will be system definition: w*h*3/8 + AX_SKEL_COMMON_THRESHOLD_CONFIG_T stVencAttrConfigThreshold = {0}; + if (nJencBufSize > 0) { + stConfig.pstItems[itemIndex].pstrType = (AX_CHAR *)"venc_attr_config"; + stVencAttrConfigThreshold.fValue = (AX_F32) nJencBufSize; + stConfig.pstItems[itemIndex].pstrValue = (AX_VOID *)&stVencAttrConfigThreshold; + stConfig.pstItems[itemIndex].nValueSize = sizeof(AX_SKEL_COMMON_THRESHOLD_CONFIG_T); + itemIndex++; + } + + AX_SKEL_COMMON_THRESHOLD_CONFIG_T stTrackEnableThreshold = {0}; + AX_SKEL_COMMON_THRESHOLD_CONFIG_T stPushEnableThreshold = {0}; + + // detect only (disable track + disable push) + if (nDetectType == 0) { + // track_disable + stConfig.pstItems[itemIndex].pstrType = (AX_CHAR *)"track_enable"; + stTrackEnableThreshold.fValue = 0; + stConfig.pstItems[itemIndex].pstrValue = (AX_VOID *)&stTrackEnableThreshold; + stConfig.pstItems[itemIndex].nValueSize = sizeof(AX_SKEL_COMMON_THRESHOLD_CONFIG_T); + itemIndex++; + + // push_disable + stConfig.pstItems[itemIndex].pstrType = (AX_CHAR *)"push_enable"; + stPushEnableThreshold.fValue = 0; + stConfig.pstItems[itemIndex].pstrValue = (AX_VOID *)&stPushEnableThreshold; + stConfig.pstItems[itemIndex].nValueSize = sizeof(AX_SKEL_COMMON_THRESHOLD_CONFIG_T); + itemIndex++; + } + // detect + track (disable push) + else if (nDetectType == 1) { + // push_disable + stConfig.pstItems[itemIndex].pstrType = (AX_CHAR *)"push_enable"; + stPushEnableThreshold.fValue = 0; + stConfig.pstItems[itemIndex].pstrValue = (AX_VOID *)&stPushEnableThreshold; + stConfig.pstItems[itemIndex].nValueSize = sizeof(AX_SKEL_COMMON_THRESHOLD_CONFIG_T); + itemIndex++; + } + + if (itemIndex > 0) { + stConfig.nSize = itemIndex; + stHandleParam.stConfig = stConfig; + } + + // default NPU + if (nNpuType == 0 || nNpuType == 1) { + stHandleParam.nNpuType = (AX_S32)AX_SKEL_NPU_DEFAULT; + } + // STD-NPU + else if (nNpuType == 2) { + stHandleParam.nNpuType = (AX_S32)AX_SKEL_STD_VNPU_1; + } + else if (nNpuType == 3) { + stHandleParam.nNpuType = (AX_S32)AX_SKEL_STD_VNPU_2; + } + + nStartTime = get_tick_count(); + + nRet = AX_SKEL_Create(&stHandleParam, &pHandle); + + nCreateElasped = get_tick_count() - nStartTime; + + if (0 != nRet) { + ALOGE("SKEL Create Handle fail, ret = 0x%x", nRet); + + goto EXIT2; + } + + if (fConfidence == 0) { + fConfidence = 0.5; + } + + // set config + { + AX_SKEL_CONFIG_T stConfig = {0}; + AX_SKEL_CONFIG_ITEM_T stItems[64] = {0}; + AX_U8 itemIndex = 0; + stConfig.nSize = 0; + stConfig.pstItems = &stItems[0]; +#if 0 + // body_max_target_count + stConfig.pstItems[itemIndex].pstrType = (AX_CHAR *)"body_max_target_count"; + AX_SKEL_COMMON_THRESHOLD_CONFIG_T stBodyMaxTargetCount = {0}; + stBodyMaxTargetCount.fValue = (AX_F32)nHumantracksize; + stConfig.pstItems[itemIndex].pstrValue = (AX_VOID *)&stBodyMaxTargetCount; + stConfig.pstItems[itemIndex].nValueSize = sizeof(AX_SKEL_COMMON_THRESHOLD_CONFIG_T); + itemIndex++; + + // vehicle_max_target_count + stConfig.pstItems[itemIndex].pstrType = (AX_CHAR *)"vehicle_max_target_count"; + AX_SKEL_COMMON_THRESHOLD_CONFIG_T stVehicleMaxTargetCount = {0}; + stVehicleMaxTargetCount.fValue = (AX_F32)nVehicletracksize; + stConfig.pstItems[itemIndex].pstrValue = (AX_VOID *)&stVehicleMaxTargetCount; + stConfig.pstItems[itemIndex].nValueSize = sizeof(AX_SKEL_COMMON_THRESHOLD_CONFIG_T); + itemIndex++; + + // cycle_max_target_count + stConfig.pstItems[itemIndex].pstrType = (AX_CHAR *)"cycle_max_target_count"; + AX_SKEL_COMMON_THRESHOLD_CONFIG_T stCycleMaxTargetCount = {0}; + stCycleMaxTargetCount.fValue = (AX_F32)nCycletracksize; + stConfig.pstItems[itemIndex].pstrValue = (AX_VOID *)&stCycleMaxTargetCount; + stConfig.pstItems[itemIndex].nValueSize = sizeof(AX_SKEL_COMMON_THRESHOLD_CONFIG_T); + itemIndex++; +#endif +#if 0 + // body_confidence + stConfig.pstItems[itemIndex].pstrType = (AX_CHAR *)"body_confidence"; + AX_SKEL_COMMON_THRESHOLD_CONFIG_T stBodyConfidence = {0}; + stBodyConfidence.fValue = fConfidence; + stConfig.pstItems[itemIndex].pstrValue = (AX_VOID *)&stBodyConfidence; + stConfig.pstItems[itemIndex].nValueSize = sizeof(AX_SKEL_COMMON_THRESHOLD_CONFIG_T); + itemIndex++; + + // face_confidence + stConfig.pstItems[itemIndex].pstrType = (AX_CHAR *)"face_confidence"; + AX_SKEL_COMMON_THRESHOLD_CONFIG_T stFaceConfidence = {0}; + stFaceConfidence.fValue = fConfidence; + stConfig.pstItems[itemIndex].pstrValue = (AX_VOID *)&stFaceConfidence; + stConfig.pstItems[itemIndex].nValueSize = sizeof(AX_SKEL_COMMON_THRESHOLD_CONFIG_T); + itemIndex++; + + // vehicle_confidence + stConfig.pstItems[itemIndex].pstrType = (AX_CHAR *)"vehicle_confidence"; + AX_SKEL_COMMON_THRESHOLD_CONFIG_T stVehicleConfidence = {0}; + stVehicleConfidence.fValue = fConfidence; + stConfig.pstItems[itemIndex].pstrValue = (AX_VOID *)&stVehicleConfidence; + stConfig.pstItems[itemIndex].nValueSize = sizeof(AX_SKEL_COMMON_THRESHOLD_CONFIG_T); + itemIndex++; + + // cycle_confidence + stConfig.pstItems[itemIndex].pstrType = (AX_CHAR *)"cycle_confidence"; + AX_SKEL_COMMON_THRESHOLD_CONFIG_T stCycleConfidence = {0}; + stCycleConfidence.fValue = fConfidence; + stConfig.pstItems[itemIndex].pstrValue = (AX_VOID *)&stCycleConfidence; + stConfig.pstItems[itemIndex].nValueSize = sizeof(AX_SKEL_COMMON_THRESHOLD_CONFIG_T); + itemIndex++; + + // plate_confidence + stConfig.pstItems[itemIndex].pstrType = (AX_CHAR *)"plate_confidence"; + AX_SKEL_COMMON_THRESHOLD_CONFIG_T stPlateConfidence = {0}; + stPlateConfidence.fValue = fConfidence; + stConfig.pstItems[itemIndex].pstrValue = (AX_VOID *)&stPlateConfidence; + stConfig.pstItems[itemIndex].nValueSize = sizeof(AX_SKEL_COMMON_THRESHOLD_CONFIG_T); + itemIndex++; +#endif + +#if 0 + // crop_encoder_qpLevel + stConfig.pstItems[itemIndex].pstrType = (AX_CHAR *)"crop_encoder_qpLevel"; + AX_SKEL_COMMON_THRESHOLD_CONFIG_T stCropEncoderQpLevelThreshold = {0}; + stCropEncoderQpLevelThreshold.fValue = 90; + stConfig.pstItems[itemIndex].pstrValue = (AX_VOID *)&stCropEncoderQpLevelThreshold; + stConfig.pstItems[itemIndex].nValueSize = sizeof(AX_SKEL_COMMON_THRESHOLD_CONFIG_T); + itemIndex++; +#endif + +#if 0 + // body_min_size + stConfig.pstItems[itemIndex].pstrType = (AX_CHAR *)"body_min_size"; + AX_SKEL_OBJECT_SIZE_FILTER_CONFIG_T stBodyMinSize = {0}; + stBodyMinSize.nWidth = 0; + stBodyMinSize.nHeight = 0; + stConfig.pstItems[itemIndex].pstrValue = (AX_VOID *)&stBodyMinSize; + stConfig.pstItems[itemIndex].nValueSize = sizeof(AX_SKEL_OBJECT_SIZE_FILTER_CONFIG_T); + itemIndex++; + + // face_min_size + stConfig.pstItems[itemIndex].pstrType = (AX_CHAR *)"face_min_size"; + AX_SKEL_OBJECT_SIZE_FILTER_CONFIG_T stFaceMinSize = {0}; + stFaceMinSize.nWidth = 0; + stFaceMinSize.nHeight = 0; + stConfig.pstItems[itemIndex].pstrValue = (AX_VOID *)&stFaceMinSize; + stConfig.pstItems[itemIndex].nValueSize = sizeof(AX_SKEL_OBJECT_SIZE_FILTER_CONFIG_T); + itemIndex++; + + // vehicle_min_size + stConfig.pstItems[itemIndex].pstrType = (AX_CHAR *)"vehicle_min_size"; + AX_SKEL_OBJECT_SIZE_FILTER_CONFIG_T stVehicleMinSize = {0}; + stVehicleMinSize.nWidth = 0; + stVehicleMinSize.nHeight = 0; + stConfig.pstItems[itemIndex].pstrValue = (AX_VOID *)&stVehicleMinSize; + stConfig.pstItems[itemIndex].nValueSize = sizeof(AX_SKEL_OBJECT_SIZE_FILTER_CONFIG_T); + itemIndex++; + + // cycle_min_size + stConfig.pstItems[itemIndex].pstrType = (AX_CHAR *)"cycle_min_size"; + AX_SKEL_OBJECT_SIZE_FILTER_CONFIG_T stCycleMinSize = {0}; + stCycleMinSize.nWidth = 0; + stCycleMinSize.nHeight = 0; + stConfig.pstItems[itemIndex].pstrValue = (AX_VOID *)&stCycleMinSize; + stConfig.pstItems[itemIndex].nValueSize = sizeof(AX_SKEL_OBJECT_SIZE_FILTER_CONFIG_T); + itemIndex++; + + // plate_min_size + stConfig.pstItems[itemIndex].pstrType = (AX_CHAR *)"plate_min_size"; + AX_SKEL_OBJECT_SIZE_FILTER_CONFIG_T stPlateMinSize = {0}; + stPlateMinSize.nWidth = 0; + stPlateMinSize.nHeight = 0; + stConfig.pstItems[itemIndex].pstrValue = (AX_VOID *)&stPlateMinSize; + stConfig.pstItems[itemIndex].nValueSize = sizeof(AX_SKEL_OBJECT_SIZE_FILTER_CONFIG_T); + itemIndex++; +#endif + + // detect_roi_polygon + AX_SKEL_ROI_POLYGON_CONFIG_T stDetectRoi = {0}; + stConfig.pstItems[itemIndex].pstrType = (AX_CHAR *)"detect_roi_polygon"; + stDetectRoi.bEnable = AX_FALSE; + stDetectRoi.nPointNum = 4; + AX_SKEL_POINT_T stPoint[4] = {{0, 0}, {nWidth, 0}, {nWidth, nHeight}, {0, nHeight}}; + stDetectRoi.pstPoint = (AX_SKEL_POINT_T *)stPoint; + stConfig.pstItems[itemIndex].pstrValue = (AX_VOID *)&stDetectRoi; + stConfig.pstItems[itemIndex].nValueSize = sizeof(AX_SKEL_ROI_POLYGON_CONFIG_T); + itemIndex++; + + // push_strategy + stConfig.pstItems[itemIndex].pstrType = (AX_CHAR *)"push_strategy"; + AX_SKEL_PUSH_STRATEGY_T stPushStrategy = {0}; + stPushStrategy.ePushMode = (AX_SKEL_PUSH_MODE_E)nPushStrategy; + stPushStrategy.nIntervalTimes = 2000; + stPushStrategy.nPushCounts = 1; + stPushStrategy.bPushSameFrame = AX_TRUE; + stConfig.pstItems[itemIndex].pstrValue = (AX_VOID *)&stPushStrategy; + stConfig.pstItems[itemIndex].nValueSize = sizeof(AX_SKEL_PUSH_STRATEGY_T); + itemIndex++; + + //4 crop_encoder +#if 0 + // body_crop_encoder + AX_SKEL_CROP_ENCODER_THRESHOLD_CONFIG_T stBodyCropEncoderThreshold = {0}; + stConfig.pstItems[itemIndex].pstrType = (AX_CHAR *)"body_crop_encoder"; + stBodyCropEncoderThreshold.fScaleLeft = 0; + stBodyCropEncoderThreshold.fScaleRight = 0; + stBodyCropEncoderThreshold.fScaleTop = 0; + stBodyCropEncoderThreshold.fScaleBottom = 0; + stConfig.pstItems[itemIndex].pstrValue = (AX_VOID *)&stBodyCropEncoderThreshold; + stConfig.pstItems[itemIndex].nValueSize = sizeof(AX_SKEL_CROP_ENCODER_THRESHOLD_CONFIG_T); + itemIndex++; + + // vehicle_crop_encoder + AX_SKEL_CROP_ENCODER_THRESHOLD_CONFIG_T stVehicleCropEncoderThreshold = {0}; + stConfig.pstItems[itemIndex].pstrType = (AX_CHAR *)"vehicle_crop_encoder"; + stVehicleCropEncoderThreshold.fScaleLeft = 0; + stVehicleCropEncoderThreshold.fScaleRight = 0; + stVehicleCropEncoderThreshold.fScaleTop = 0; + stVehicleCropEncoderThreshold.fScaleBottom = 0; + stConfig.pstItems[itemIndex].pstrValue = (AX_VOID *)&stVehicleCropEncoderThreshold; + stConfig.pstItems[itemIndex].nValueSize = sizeof(AX_SKEL_CROP_ENCODER_THRESHOLD_CONFIG_T); + itemIndex++; + + // cycle_crop_encoder + AX_SKEL_CROP_ENCODER_THRESHOLD_CONFIG_T stCycleCropEncoderThreshold = {0}; + stConfig.pstItems[itemIndex].pstrType = (AX_CHAR *)"cycle_crop_encoder"; + stCycleCropEncoderThreshold.fScaleLeft = 0; + stCycleCropEncoderThreshold.fScaleRight = 0; + stCycleCropEncoderThreshold.fScaleTop = 0; + stCycleCropEncoderThreshold.fScaleBottom = 0; + stConfig.pstItems[itemIndex].pstrValue = (AX_VOID *)&stCycleCropEncoderThreshold; + stConfig.pstItems[itemIndex].nValueSize = sizeof(AX_SKEL_CROP_ENCODER_THRESHOLD_CONFIG_T); + itemIndex++; + + // face_crop_encoder + AX_SKEL_CROP_ENCODER_THRESHOLD_CONFIG_T stFaceCropEncoderThreshold = {0}; + stConfig.pstItems[itemIndex].pstrType = (AX_CHAR *)"face_crop_encoder"; + stFaceCropEncoderThreshold.fScaleLeft = 0; + stFaceCropEncoderThreshold.fScaleRight = 0; + stFaceCropEncoderThreshold.fScaleTop = 0; + stFaceCropEncoderThreshold.fScaleBottom = 0; + stConfig.pstItems[itemIndex].pstrValue = (AX_VOID *)&stFaceCropEncoderThreshold; + stConfig.pstItems[itemIndex].nValueSize = sizeof(AX_SKEL_CROP_ENCODER_THRESHOLD_CONFIG_T); + itemIndex++; + + // plate_crop_encoder + AX_SKEL_CROP_ENCODER_THRESHOLD_CONFIG_T stPlateCropEncoderThreshold = {0}; + stConfig.pstItems[itemIndex].pstrType = (AX_CHAR *)"plate_crop_encoder"; + stPlateCropEncoderThreshold.fScaleLeft = 0; + stPlateCropEncoderThreshold.fScaleRight = 0; + stPlateCropEncoderThreshold.fScaleTop = 0; + stPlateCropEncoderThreshold.fScaleBottom = 0; + stConfig.pstItems[itemIndex].pstrValue = (AX_VOID *)&stPlateCropEncoderThreshold; + stConfig.pstItems[itemIndex].nValueSize = sizeof(AX_SKEL_CROP_ENCODER_THRESHOLD_CONFIG_T); + itemIndex++; +#endif + // push_panorama + stConfig.pstItems[itemIndex].pstrType = (AX_CHAR *)"push_panorama"; + AX_SKEL_PUSH_PANORAMA_CONFIG_T stPushPanoramaConfig = {0}; + stPushPanoramaConfig.bEnable = AX_FALSE; + stPushPanoramaConfig.nQuality = 0; + stConfig.pstItems[itemIndex].pstrValue = (AX_VOID *)&stPushPanoramaConfig; + stConfig.pstItems[itemIndex].nValueSize = sizeof(AX_SKEL_PUSH_PANORAMA_CONFIG_T); + itemIndex++; +#if 0 + // push_quality_body + stConfig.pstItems[itemIndex].pstrType = (AX_CHAR *)"push_quality_body"; + AX_SKEL_ATTR_FILTER_CONFIG_T stBodyAttrFilter = {0}; + stBodyAttrFilter.stCommonAttrFilterConfig.fQuality = 0; + stConfig.pstItems[itemIndex].pstrValue = (AX_VOID *)&stBodyAttrFilter; + stConfig.pstItems[itemIndex].nValueSize = sizeof(AX_SKEL_ATTR_FILTER_CONFIG_T); + itemIndex++; + + // push_quality_vehicle + stConfig.pstItems[itemIndex].pstrType = (AX_CHAR *)"push_quality_vehicle"; + AX_SKEL_ATTR_FILTER_CONFIG_T stVehicleAttrFilter = {0}; + stVehicleAttrFilter.stCommonAttrFilterConfig.fQuality = 0; + stConfig.pstItems[itemIndex].pstrValue = (AX_VOID *)&stVehicleAttrFilter; + stConfig.pstItems[itemIndex].nValueSize = sizeof(AX_SKEL_ATTR_FILTER_CONFIG_T); + itemIndex++; + + // push_quality_cycle + stConfig.pstItems[itemIndex].pstrType = (AX_CHAR *)"push_quality_cycle"; + AX_SKEL_ATTR_FILTER_CONFIG_T stCycleAttrFilter = {0}; + stCycleAttrFilter.stCommonAttrFilterConfig.fQuality = 0; + stConfig.pstItems[itemIndex].pstrValue = (AX_VOID *)&stCycleAttrFilter; + stConfig.pstItems[itemIndex].nValueSize = sizeof(AX_SKEL_ATTR_FILTER_CONFIG_T); + itemIndex++; + + // push_quality_face + stConfig.pstItems[itemIndex].pstrType = (AX_CHAR *)"push_quality_face"; + AX_SKEL_ATTR_FILTER_CONFIG_T stFaceAttrFilter = {0}; + stFaceAttrFilter.stFaceAttrFilterConfig.nWidth = 0; + stFaceAttrFilter.stFaceAttrFilterConfig.nHeight = 0; + stFaceAttrFilter.stFaceAttrFilterConfig.stPoseblur.fPitch = 180; + stFaceAttrFilter.stFaceAttrFilterConfig.stPoseblur.fYaw = 180; + stFaceAttrFilter.stFaceAttrFilterConfig.stPoseblur.fRoll = 180; + stFaceAttrFilter.stFaceAttrFilterConfig.stPoseblur.fBlur = 1.0; + stConfig.pstItems[itemIndex].nValueSize = sizeof(AX_SKEL_ATTR_FILTER_CONFIG_T); + stConfig.pstItems[itemIndex].pstrValue = (AX_VOID *)&stFaceAttrFilter; + itemIndex++; + + // push_quality_plate + stConfig.pstItems[itemIndex].pstrType = (AX_CHAR *)"push_quality_plate"; + AX_SKEL_ATTR_FILTER_CONFIG_T stPlateAttrFilter = {0}; + stPlateAttrFilter.stCommonAttrFilterConfig.fQuality = 0; + stConfig.pstItems[itemIndex].pstrValue = (AX_VOID *)&stPlateAttrFilter; + stConfig.pstItems[itemIndex].nValueSize = sizeof(AX_SKEL_ATTR_FILTER_CONFIG_T); + itemIndex++; +#endif +//#if 0 + // track_enable + stConfig.pstItems[itemIndex].pstrType = (AX_CHAR *)"track_enable"; + AX_SKEL_COMMON_ENABLE_CONFIG_T stTrackEnable = {0}; + stTrackEnable.bEnable = AX_TRUE; + stConfig.pstItems[itemIndex].pstrValue = (AX_VOID *)&stTrackEnable; + stConfig.pstItems[itemIndex].nValueSize = sizeof(AX_SKEL_COMMON_ENABLE_CONFIG_T); + itemIndex++; + + //push_enable + stConfig.pstItems[itemIndex].pstrType = (AX_CHAR *)"push_enable"; + AX_SKEL_COMMON_ENABLE_CONFIG_T stPushEnable = {0}; + stPushEnable.bEnable = AX_TRUE; + stConfig.pstItems[itemIndex].pstrValue = (AX_VOID *)&stPushEnable; + stConfig.pstItems[itemIndex].nValueSize = sizeof(AX_SKEL_COMMON_ENABLE_CONFIG_T); + itemIndex++; +//#endif +#if 0 + //target_config + stConfig.pstItems[itemIndex].pstrType = (AX_CHAR *)"target_config"; + AX_SKEL_TARGET_CONFIG_T stTarget = {0}; + + stTarget.nSize = 1; + AX_SKEL_TARGET_ITEM_T stItem = {0}; + stItem.pstrObjectCategory = "body"; + stTarget.pstItems = &stItem; + + stConfig.pstItems[itemIndex].pstrValue = (AX_VOID *)&stTarget; + stConfig.pstItems[itemIndex].nValueSize = sizeof(AX_SKEL_TARGET_CONFIG_T); + itemIndex++; + + //push_target_config + stConfig.pstItems[itemIndex].pstrType = (AX_CHAR *)"push_target_config"; + AX_SKEL_TARGET_CONFIG_T stTarget = {0}; + stTarget.nSize = 1; + AX_SKEL_TARGET_ITEM_T stItem = {0}; + stItem.pstrObjectCategory = "body"; + stTarget.pstItems = &stItem; + + stConfig.pstItems[itemIndex].pstrValue = (AX_VOID *)&stTarget; + stConfig.pstItems[itemIndex].nValueSize = sizeof(AX_SKEL_TARGET_CONFIG_T); + itemIndex++; + + // push_attr_always + stConfig.pstItems[itemIndex].pstrType = (AX_CHAR *)"push_attr_always"; + AX_SKEL_COMMON_ENABLE_CONFIG_T stPushAttrAlways = {0}; + stPushAttrAlways.bEnable = AX_TRUE; + stConfig.pstItems[itemIndex].pstrValue = (AX_VOID *)&stPushAttrAlways; + stConfig.pstItems[itemIndex].nValueSize = sizeof(AX_SKEL_COMMON_ENABLE_CONFIG_T); + itemIndex++; +#endif + //analyzer_attr_config + // stConfig.pstItems[itemIndex].pstrType = (AX_CHAR *)"analyzer_attr_config"; + // AX_SKEL_ANALYZER_CONFIG_T stAnalyze = {0}; + // //AX_SKEL_ANALYZER_ATTR_E analyze_attribute = AX_SKEL_ANALYZER_ATTR_NONE; + + // stAnalyze.nSize = 1; + // AX_SKEL_ANALYZER_ATTR_E analyze_attribute = AX_SKEL_ANALYZER_ATTR_FACE_ATTRIBUTE; + // stAnalyze.peItems = &analyze_attribute; + + // stConfig.pstItems[itemIndex].pstrValue = (AX_VOID *)&stAnalyze; + // stConfig.pstItems[itemIndex].nValueSize = sizeof(AX_SKEL_ANALYZER_CONFIG_T); + // itemIndex++; + + stConfig.nSize = itemIndex; + + nRet = AX_SKEL_SetConfig(pHandle, &stConfig); + + if (0 != nRet) { + ALOGE("SKEL AX_SKEL_SetConfig, ret = 0x%x", nRet); + + goto EXIT2; + } + } + + // get config + { + const AX_SKEL_CONFIG_T *pstConfig = NULL; + + nRet = AX_SKEL_GetConfig(pHandle, &pstConfig); + + if (0 != nRet) { + ALOGE("SKEL AX_SKEL_GetConfig, ret = 0x%x", nRet); + + if (pstConfig) { + AX_SKEL_Release((AX_VOID *)pstConfig); + } + + goto EXIT2; + } + + ParseConfigParam(pstConfig); + + if (pstConfig) { + AX_SKEL_Release((AX_VOID *)pstConfig); + } + } + + ALOGN("Task infomation:"); + ALOGN("\tInput file: %s", InputFile); + ALOGN("\tInput file resolution: %dx%d", nWidth, nHeight); + ALOGN("\tRepeat times: %d", nRepeatTimes); + ALOGN("SKEL Init Elapse:"); + ALOGN("\tAX_SKEL_Init: %lld ms", nInitElasped); + ALOGN("\tAX_SKEL_Create: %lld ms", nCreateElasped); + + OUTPUT_LOG_SAVE("==============================%s process result:==============================", InputFile); + + if (InputFileFrameCnt > 1) { + InputFileFrameCnt = InputFileFrameCnt + BLACK_VIDEO_FRAME_COUNT; + } + + // create frame mgr + FrameMgrCreate(nFrameSize, nFrameDepth + nCacheListDepth); + + for (AX_U32 nRepeat = 0; nRepeat < nRepeatTimes; nRepeat++) { + ALOGN("#####SKEL Process times: %d", nRepeat + 1); + + OUTPUT_LOG_SAVE("#####SKEL Process times: %d", nRepeat + 1); + + STAT_OBJECT_NUM_T tObjectTrackNum = {0}; + STAT_OBJECT_NUM_T tObjectPushNum = {0}; + + for (AX_U32 nFrameCnt = 0; nFrameCnt < InputFileFrameCnt; nFrameCnt++) { + AX_BLK blkId = AX_INVALID_BLOCKID; + + if (InputFileFrameCnt != 1) { + if (FrameSkipCtrl(nSrcFrameRate, nDstFrameRate, nSkelFrameId)) { + nSkelFrameId ++; + + LoadFileToMem(InputFileHandle, 0, NULL, nOneSize); + + if (nInterval > 0) { + usleep(nInterval); + } + continue; + } + else { + if (!FrameMgrGet(&YUVDataPhy, &YUVDataVir, nFrameSize, nSkelFrameId, &blkId)) { + + ALOGE("FrameMgrGet fail"); + + goto EXIT1; + } + + if (nOneSize != nFrameSize) { + LoadFileToMem(InputFileHandle, OneYUVDataPhy, OneYUVDataVir, nOneSize); + + NV12ToStrideNV12(OneYUVDataPhy, + OneYUVDataVir, + nOneSize, + nWidth, + nHeight, + YUVDataPhy, + YUVDataVir, + nFrameSize, + nStride, + nHeight + ); + } + else { + LoadFileToMem(InputFileHandle, YUVDataPhy, YUVDataVir, nOneSize); + } + } + } else { + FrameMgrGet(&YUVDataPhy, &YUVDataVir, nFrameSize, nSkelFrameId, &blkId); + + if (nRet != 0 + || YUVDataPhy == 0 + || YUVDataVir == NULL) { + ALOGE("Load input file fail"); + goto EXIT1; + } + + if (bJpgFile) { + nRet = DecodeJpeg(InputFileHandle, YUVDataPhy, YUVDataVir, nWidth, nHeight); + if (0 != nRet) { + ALOGE("DecodeJpeg failed!"); + goto EXIT3; + } + } + else { + if (nOneSize != nFrameSize) { + nRet = AX_SYS_MemAlloc(&OneYUVDataPhy, (AX_VOID **)&OneYUVDataVir, nOneSize, 256, (AX_S8 *)"SKEL_TEST"); + + nRet = LoadFileToMem(InputFileHandle, OneYUVDataPhy, OneYUVDataVir, nOneSize); + + NV12ToStrideNV12(OneYUVDataPhy, + OneYUVDataVir, + nOneSize, + nWidth, + nHeight, + YUVDataPhy, + YUVDataVir, + nFrameSize, + nStride, + nHeight + ); + } + else { + nRet = LoadFileToMem(InputFileHandle, YUVDataPhy, YUVDataVir, nFrameSize); + } + } + } + stFrame.stFrame.u32Width = nWidth; + stFrame.stFrame.u32Height = nHeight; + stFrame.stFrame.enImgFormat = AX_FORMAT_YUV420_SEMIPLANAR; + stFrame.stFrame.u32FrameSize = nFrameSize; + stFrame.stFrame.u32PicStride[0] = nStride; + stFrame.stFrame.u32PicStride[1] = nStride; + stFrame.stFrame.u32PicStride[2] = nStride; + stFrame.stFrame.u64PhyAddr[0] = YUVDataPhy; + stFrame.stFrame.u64PhyAddr[1] = YUVDataPhy + nStride * nHeight; + stFrame.stFrame.u64PhyAddr[2] = 0; + stFrame.stFrame.u64VirAddr[0] = (AX_ULONG)(YUVDataVir); + stFrame.stFrame.u64VirAddr[1] = (AX_ULONG)(YUVDataVir + nStride * nHeight); + stFrame.stFrame.u64VirAddr[2] = 0; + stFrame.stFrame.u32BlkId[0] = blkId; + stFrame.stFrame.u32BlkId[1] = 0; + stFrame.stFrame.u32BlkId[2] = 0; + ALOGN("*****SKEL Frame(%d) Process", nFrameCnt + 1); + + //OUTPUT_LOG_SAVE("*****SKEL Frame(%d) Process Start", nFrameCnt + 1); + + stFrame.nFrameId = nSkelFrameId ++; + nStartTime = get_tick_count(); + + while (1) { + nRet = AX_SKEL_SendFrame(pHandle, &stFrame, 0); + + if (nRet == 0) { + break; + } + + usleep(1000); + } + + FrameMgrRelease(blkId); + + nProcessElasped = get_tick_count() - nStartTime; + + if (0 != nRet) { + ALOGE("SKEL Process fail, ret = 0x%x", nRet); + + goto EXIT3; + } + + ALOGN("SKEL Process Elapse:"); + ALOGN("\tAX_SKEL_SendFrame: %lld ms", nProcessElasped); + + nStartTime = get_tick_count(); + + nRet = AX_SKEL_GetResult(pHandle, &pstResult, -1); + + nResultElasped = get_tick_count() - nStartTime; + + if (0 != nRet) { + ALOGE("SKEL get result fail, ret = 0x%x", nRet); + + goto EXIT3; + } + + ALOGN("\tAX_SKEL_GetResult: %lld ms", nResultElasped); + + nResultElaspedTotal += nResultElasped; + + if (nProcessElasped + nResultElasped > nResultElaspedMax) { + nResultElaspedMax = nProcessElasped + nResultElasped; + } + + if (nProcessElasped + nResultElasped < nResultElaspedMin) { + nResultElaspedMin = nProcessElasped + nResultElasped; + } + + ALOGN("SKEL Process Result:"); + + ALOGI("\tFrameId: %lld", pstResult->nFrameId); + ALOGI("\tnOriginal WxH: %dx%d", pstResult->nOriginalWidth, pstResult->nOriginalHeight); + + ALOGN("\tObject Num: %d", pstResult->nObjectSize); + + AX_U32 nSkelSize = 0; + AI_Detection_SkelResult_t Skels[SKEL_SAMPLE_OBJECT_SIZE] = {0}; + for (AX_U32 i = 0; i < pstResult->nObjectSize; i++) { + AX_SKEL_OBJECT_ITEM_T *pstItems = &pstResult->pstObjectItems[i]; + + ALOGI("\t\tFrameId: %lld", pstItems->nFrameId); + ALOGI("\t\tTrackId: %lld, TrackState: %d", pstItems->nTrackId, pstItems->eTrackState); + + ALOGN("\t\tRect[%d] %s: [%f, %f, %f, %f], Confidence: %f", i, pstItems->pstrObjectCategory, + pstItems->stRect.fX, + pstItems->stRect.fY, pstItems->stRect.fW, + pstItems->stRect.fH, pstItems->fConfidence); + StatTrackMgr(pstItems, &tObjectTrackNum); + StatPushMgr(pstItems, &tObjectPushNum); + + // get detect box only new or update state + if ((pstItems->eTrackState == AX_SKEL_TRACK_STATUS_NEW + || pstItems->eTrackState == AX_SKEL_TRACK_STATUS_UPDATE) + && nSkelSize < SKEL_SAMPLE_OBJECT_SIZE) { + Skels[nSkelSize].pstrObjectCategory = pstItems->pstrObjectCategory; + Skels[nSkelSize].tBox.fX = pstItems->stRect.fX; + Skels[nSkelSize].tBox.fY = pstItems->stRect.fY; + Skels[nSkelSize].tBox.fW = pstItems->stRect.fW; + Skels[nSkelSize].tBox.fH = pstItems->stRect.fH; + + OUTPUT_LOG_SAVE("\t\tObject[%d] %s: [%f, %f, %f, %f], Confidence: %f", + i, pstItems->pstrObjectCategory, + pstItems->stRect.fX, pstItems->stRect.fY, + pstItems->stRect.fW, pstItems->stRect.fH, + pstItems->fConfidence); + + ALOGN("\t\t[%d]Point Set Size: %d", i, pstItems->nPointSetSize); + + // point + Skels[nSkelSize].nPointNum = AX_MIN(DETECT_SKEL_POINT_COUNT, pstItems->nPointSetSize); + for (AX_U32 j = 0; j < Skels[i].nPointNum; j++) { + ALOGI("\t\t\tPoint[%d] %s: [%f, %f] Confidence: %f", j, pstItems->pstPointSet[j].pstrObjectCategory, + pstItems->pstPointSet[j].stPoint.fX, + pstItems->pstPointSet[j].stPoint.fY, + pstItems->pstPointSet[j].fConfidence); + Skels[nSkelSize].tPoint[j].fX = pstItems->pstPointSet[j].stPoint.fX; + Skels[nSkelSize].tPoint[j].fY = pstItems->pstPointSet[j].stPoint.fY; + + OUTPUT_LOG_SAVE("\t\t\tPoint[%d] %s: [%f, %f] Confidence: %f\n", + j, + pstItems->pstPointSet[j].pstrObjectCategory, + pstItems->pstPointSet[j].stPoint.fX, + pstItems->pstPointSet[j].stPoint.fY, + pstItems->pstPointSet[j].fConfidence); + } + + //face attr + if(nPPL == AX_SKEL_PPL_FACE){ + ALOGN("\t\tFace Attribute:"); + ALOGI("\t\t\tfYaw %f,",pstItems->stFaceAttr.fYaw); + ALOGI("\t\t\tfPitch %f,",pstItems->stFaceAttr.fPitch); + ALOGI("\t\t\tfRoll %f,",pstItems->stFaceAttr.fRoll); + ALOGI("\t\t\tfMask %f,",pstItems->stFaceAttr.fMask); + ALOGI("\t\t\tage %d",pstItems->stFaceAttr.nAge); + ALOGI("\t\t\tgender %d",pstItems->stFaceAttr.nGender); + } + nSkelSize ++; + } + + if (AX_SKEL_TRACK_STATUS_SELECT == pstItems->eTrackState) { + ATTRINFO_T AttrInfo; + memset(&AttrInfo, 0x00, sizeof(AttrInfo)); + AttrParser(pstItems, &AttrInfo); + + if (pstItems->bCropFrame + && pstItems->stCropFrame.pFrameData + && 0 < pstItems->stCropFrame.nFrameDataSize + && SaveResultPath) { + // save attribute + AX_CHAR arrDat[256] = {0}; + AX_CHAR strFile[512] = {0}; + if (AttrInfo.bExist && AttrInfo.eType == ATTR_TYPE_FACE) { + sprintf(arrDat, "frame%lld_crop_%s[%lld]_Gender[%s]_Age[%d]_Mask[%s]_Score[%f]_%dx%d", + pstItems->stCropFrame.nFrameId, + pstItems->pstrObjectCategory, + pstItems->nTrackId, + AttrInfo.tFaceInfo.szGender, + AttrInfo.tFaceInfo.nAge, + AttrInfo.tFaceInfo.szMask, + pstItems->fConfidence, + pstItems->stCropFrame.nFrameWidth, + pstItems->stCropFrame.nFrameHeight); + + OUTPUT_LOG_SAVE("\t\t[FACE ATTR] %s", arrDat); + } + else if (AttrInfo.bExist && AttrInfo.eType == ATTR_TYPE_PLATE) { + sprintf(arrDat, "frame%lld_crop_%s[%lld]_Valid[%d]_Num[%s]_Color[%s]_Score[%f]_%dx%d", + pstItems->stCropFrame.nFrameId, + pstItems->pstrObjectCategory, + pstItems->nTrackId, + AttrInfo.tPlateInfo.bValid, + AttrInfo.tPlateInfo.szNum, + AttrInfo.tPlateInfo.szColor, + pstItems->fConfidence, + pstItems->stCropFrame.nFrameWidth, + pstItems->stCropFrame.nFrameHeight); + + OUTPUT_LOG_SAVE("\t\t[PLATE ATTR] %s", arrDat); + } + else if (AttrInfo.bExist && AttrInfo.eType == ATTR_TYPE_VEHICLE) { + sprintf(arrDat, "frame%lld_crop_%s[%lld]_[plate_Valid[%d]_Num[%s]_Color[%s]]_Score[%f]_%dx%d", + pstItems->stCropFrame.nFrameId, + pstItems->pstrObjectCategory, + pstItems->nTrackId, + AttrInfo.tPlateInfo.bValid, + AttrInfo.tPlateInfo.szNum, + AttrInfo.tPlateInfo.szColor, + pstItems->fConfidence, + pstItems->stCropFrame.nFrameWidth, + pstItems->stCropFrame.nFrameHeight); + + OUTPUT_LOG_SAVE("\t\t[VEHICLE ATTR] %s", arrDat); + } + else { + sprintf(arrDat, "frame%lld_crop_%s[%lld]_Score[%f]_%dx%d", + pstItems->stCropFrame.nFrameId, + pstItems->pstrObjectCategory, + pstItems->nTrackId, + pstItems->fConfidence, + pstItems->stCropFrame.nFrameWidth, + pstItems->stCropFrame.nFrameHeight); + } + + sprintf(strFile, "%s/%s/%s.jpg", + SaveResultPath, + pstItems->pstrObjectCategory, + arrDat); + + FILE *fp_w = fopen(strFile, "wb"); + + if (fp_w) { + ALOGI("Write crop jpg to file: %s", strFile); + fwrite((AX_U8 *)pstItems->stCropFrame.pFrameData, 1, pstItems->stCropFrame.nFrameDataSize, fp_w); + fclose(fp_w); + } + + } + + // panora frame + if (pstItems->bPanoraFrame + && pstItems->stPanoraFrame.pFrameData + && 0 < pstItems->stPanoraFrame.nFrameDataSize + && SaveResultPath) { + AX_CHAR arrDat[256] = {0}; + AX_CHAR strFile[512] = {0}; + if (AttrInfo.bExist && AttrInfo.eType == ATTR_TYPE_FACE) { + sprintf(arrDat, "frame%lld_panora_%s[%lld]_Gender[%s]_Age[%d]_Mask[%s]_Score[%f]_%dx%d.jpg", + pstItems->stCropFrame.nFrameId, pstItems->pstrObjectCategory, pstItems->nTrackId, + AttrInfo.tFaceInfo.szGender, AttrInfo.tFaceInfo.nAge, AttrInfo.tFaceInfo.szMask, + pstItems->fConfidence, + pstItems->stCropFrame.nFrameWidth, pstItems->stCropFrame.nFrameHeight); + } + else if (AttrInfo.bExist && AttrInfo.eType == ATTR_TYPE_PLATE) { + sprintf(arrDat, "frame%lld_panora_%s[%lld]_Valid[%d]_Num[%s]_Color[%s]_Score[%f]_%dx%d.jpg", + pstItems->stCropFrame.nFrameId, pstItems->pstrObjectCategory, pstItems->nTrackId, + AttrInfo.tPlateInfo.bValid, AttrInfo.tPlateInfo.szNum, AttrInfo.tPlateInfo.szColor, + pstItems->fConfidence, + pstItems->stCropFrame.nFrameWidth, pstItems->stCropFrame.nFrameHeight); + } + else if (AttrInfo.bExist && AttrInfo.eType == ATTR_TYPE_VEHICLE) { + sprintf(arrDat, "frame%lld_panora_%s[%lld]_[plate_Valid[%d]_Num[%s]_Color[%s]]_Score[%f]_%dx%d.jpg", + pstItems->stCropFrame.nFrameId, pstItems->pstrObjectCategory, pstItems->nTrackId, + AttrInfo.tPlateInfo.bValid, AttrInfo.tPlateInfo.szNum, AttrInfo.tPlateInfo.szColor, + pstItems->fConfidence, + pstItems->stCropFrame.nFrameWidth, pstItems->stCropFrame.nFrameHeight); + } + else { + sprintf(arrDat, "frame%lld_panora_%s[%lld]_Score[%f]_%dx%d.jpg", + pstItems->stCropFrame.nFrameId, pstItems->pstrObjectCategory, pstItems->nTrackId, + pstItems->fConfidence, + pstItems->stCropFrame.nFrameWidth, pstItems->stCropFrame.nFrameHeight); + } + + sprintf(strFile, "%s/%s/%s.jpg", + SaveResultPath, + pstItems->pstrObjectCategory, + arrDat); + + FILE *fp_w = fopen(strFile, "wb"); + + if (fp_w) { + ALOGI("Write panora jpg to file: %s", strFile); + fwrite((AX_U8 *)pstItems->stPanoraFrame.pFrameData, 1, pstItems->stPanoraFrame.nFrameDataSize, fp_w); + fclose(fp_w); + } + } + } + + // feature + ALOGI("\t\tFeature Size: %d", pstItems->nFeatureSize); + if (pstItems->pstFeatureItem + && 0 < pstItems->nFeatureSize + && SaveResultPath) { + AX_CHAR strFile[256] = {0}; + sprintf(strFile, "%s/%s/frame%lld_feature_%s_%d.db", + SaveResultPath, pstItems->pstrObjectCategory, + pstItems->stCropFrame.nFrameId, + pstItems->pstrObjectCategory, i); + FILE *fp_w = fopen(strFile, "wb"); + + if (fp_w) { + ALOGI("\t\t\tWrite feature to file: %s, nValueSize: %d", + strFile, + pstItems->pstFeatureItem[0].nValueSize); + fwrite((AX_U8 *)pstItems->pstFeatureItem[0].pstrValue, 1, pstItems->pstFeatureItem[0].nValueSize, fp_w); + fclose(fp_w); + } + } + + // meta + ALOGI("\t\tMeta Size: %d", pstItems->nMetaInfoSize); + if (pstItems->pstMetaInfo + && 0 < pstItems->nMetaInfoSize) { + for (AX_U32 i = 0; i < pstItems->nMetaInfoSize; i++) { + ALOGI("\t\tMetaInfo[%d] %s: \n%s", i, pstItems->pstMetaInfo[i].pstrType, pstItems->pstMetaInfo[i].pstrValue); + } + } + + // binds + ALOGI("\t\tBind Size: %d", pstItems->nObjectBindSize); + if (pstItems->pstObjectBind + && 0 < pstItems->nObjectBindSize) { + for (AX_U32 i = 0; i < pstItems->nObjectBindSize; i++) { + ALOGI("\t\t[%s] [TrackId] %lld bind to ObjectBind[%d]: %s [TrackId] %lld", + pstItems->pstrObjectCategory, pstItems->nTrackId, i, + pstItems->pstObjectBind[i].pstrObjectCategoryBind, pstItems->pstObjectBind[i].nTrackId); + } + } + } + + ALOGI("\tnCacheListSize: %d", pstResult->nCacheListSize); + if (pstResult->pstCacheList) { + for (AX_U32 i = 0; i < pstResult->nCacheListSize; i++) { + ALOGI("\t\tCacheList[%d] FrameId: %lld", i, pstResult->pstCacheList[i].nFrameId); + } + } + + if (ReWritePath && pstResult->nObjectSize > 0) { + memcpy(YUVDataWrVir, YUVDataVir, nFrameSize); + + YUV_IMAGE_T YUVImage = {0}; + YUVImage.pImage = YUVDataWrVir; + YUVImage.nWidth = nWidth; + YUVImage.nHeight = nHeight; + YUVImage.stride = nStride; + YUVImage.nSize = nFrameSize; + YUVImage.eType = AX_FORMAT_YUV420_SEMIPLANAR; + + for (size_t i = 0; i < nSkelSize; i++) { + // draw rect + AX_CHAR ObjectCategory = Skels[i].pstrObjectCategory[0]; + AX_S16 x0 = Skels[i].tBox.fX; + AX_S16 y0 = Skels[i].tBox.fY; + AX_U16 w = Skels[i].tBox.fW; + AX_U16 h = Skels[i].tBox.fH; + YUV_COLOR RectColor = YUV_WHITE; + + switch(ObjectCategory){ + case 'b': //body + RectColor = YUV_WHITE; + break; + case 'v': //vehicle + RectColor = YUV_PURPLE; + break; + case 'c': //cycle + RectColor = YUV_GREEN; + break; + case 'f': //face + RectColor = YUV_YELLOW; + break; + case 'p': //plate + RectColor = YUV_RED; + break; + default : + RectColor = YUV_WHITE; + break; + } + + DrawRect(&YUVImage, x0, y0, w, h, RectColor); + + if (Skels[i].nPointNum > 0) { + // draw point + for (size_t j = 0; j < Skels[i].nPointNum; j++) { + x0 = Skels[i].tPoint[j].fX; + y0 = Skels[i].tPoint[j].fY; + + DrawPoint(&YUVImage, x0, y0, 4, x0 * (4 - 1), y0 * (4 - 1), YUV_DARK_GREEN); + } + } + } + + AX_CHAR arrWrFile[512] = {0}; + sprintf(arrWrFile, "%s_result_%d_%d.jpg", InputFile, nFrameCnt + 1, nRepeat + 1); + + AX_CHAR *fileName = NULL; + AX_U32 fileNameLen = strlen(arrWrFile); + AX_CHAR fullFileName[256] = {0}; + AX_S32 i = fileNameLen - 1; + + if (fileNameLen > 0) { + for (; i >= 0; i --) { + if (arrWrFile[i] == '/') { + break; + } + } + } + + if (i < 0) { + i = 0; + } + else if (i < fileNameLen - 1) { + i ++; + } + + fileName = (AX_CHAR *)&arrWrFile[i]; + + sprintf(fullFileName, "%s/%s", ReWritePath, fileName); + + EncodeOneFrameToJpeg((AX_CHAR *)fullFileName, nStride, nWidth, nHeight, YUVDataWrPhy, YUVDataWrVir, nFrameSize); + } + + if (pstResult) { + AX_SKEL_Release((AX_VOID *)pstResult); + } + + OUTPUT_LOG_SAVE("*****SKEL Frame(%d) Process End (Elasped: %lld ms)", nFrameCnt + 1, nProcessElasped); + + if (nInterval > 0) { + usleep(nInterval); + } + } + + ALOGN("SKEL Process Objects Statistics: Body[%d], Vehicle[%d], Cycle[%d], Face[%d], Plate[%d]", + tObjectTrackNum.nBodyNum, + tObjectTrackNum.nVehicleNum, + tObjectTrackNum.nCycleNum, + tObjectTrackNum.nFaceNum, + tObjectTrackNum.nPlateNum); + + OUTPUT_LOG_SAVE("\nSKEL Process Objects Statistics: Body[%d], Vehicle[%d], Cycle[%d], Face[%d], Plate[%d]", + tObjectTrackNum.nBodyNum, + tObjectTrackNum.nVehicleNum, + tObjectTrackNum.nCycleNum, + tObjectTrackNum.nFaceNum, + tObjectTrackNum.nPlateNum); + + ALOGN("SKEL Process Push Statistics: Body[%d], Vehicle[%d], Cycle[%d], Face[%d], Plate[%d]", + tObjectPushNum.nBodyNum, + tObjectPushNum.nVehicleNum, + tObjectPushNum.nCycleNum, + tObjectPushNum.nFaceNum, + tObjectPushNum.nPlateNum); + + OUTPUT_LOG_SAVE("SKEL Process Push Statistics: Body[%d], Vehicle[%d], Cycle[%d], Face[%d], Plate[%d]\n", + tObjectPushNum.nBodyNum, + tObjectPushNum.nVehicleNum, + tObjectPushNum.nCycleNum, + tObjectPushNum.nFaceNum, + tObjectPushNum.nPlateNum); + + if (InputFileHandle) { + ReLoadFile(InputFileHandle); + } + } + + // if(AX_SUCCESS != nRet){ + // ALOGE("AX_POOL_DestroyPool failed! Error Code:0x%X\n", nRet); + // } + + ALOGN("SKEL Process Elapsed Info: Repeats: %d, (min: %lld ms, avr: %lld ms, max: %lld ms)", + nRepeatTimes, + nResultElaspedMin, + (nSkelFrameId > 1) ? (nResultElaspedTotal / (nSkelFrameId - 1)) : 0, + nResultElaspedMax); + + OUTPUT_LOG_SAVE("SKEL Process Elapsed Info: Repeats: %d, (min: %lld ms, avr: %lld ms, max: %lld ms)", + nRepeatTimes, + nResultElaspedMin, + (nSkelFrameId > 1) ? (nResultElaspedTotal / (nSkelFrameId - 1)) : 0, + nResultElaspedMax); + +EXIT3: + if (pHandle) { + AX_SKEL_Destroy(pHandle); + } + +EXIT2: + AX_SKEL_DeInit(); + +EXIT1: + AX_ENGINE_Deinit(); + +EXIT0: + // if (YUVDataVir) { + // if (YUVDataPhy == 0) { + // free(YUVDataVir); + // } else { + // AX_SYS_MemFree(YUVDataPhy, YUVDataVir); + // } + // } + if (YUVDataWrVir) { + if (YUVDataWrPhy == 0) { + free(YUVDataWrVir); + } else { + AX_SYS_MemFree(YUVDataWrPhy, YUVDataWrVir); + } + } + + if (OneYUVDataVir) { + if (OneYUVDataPhy == 0) { + free(OneYUVDataVir); + } else { + AX_SYS_MemFree(OneYUVDataPhy, OneYUVDataVir); + } + } + + FrameMgrDestroy(); + + if (fpResultFile) { + fclose(fpResultFile); + } + + AX_VDEC_Deinit(); + + AX_VENC_Deinit(); + + AX_IVPS_Deinit(); + + AX_SYS_Deinit(); + + return (0 != nRet) ? -1 : 0; +} diff --git a/projects/llm_framework/main_skel/src/main.cpp.bak b/projects/llm_framework/main_skel/src/main.cpp.bak new file mode 100644 index 0000000..ff46984 --- /dev/null +++ b/projects/llm_framework/main_skel/src/main.cpp.bak @@ -0,0 +1,525 @@ +/* + * SPDX-FileCopyrightText: 2024 M5Stack Technology CO LTD + * + * SPDX-License-Identifier: MIT + */ +#include "StackFlow.h" +#include "common.hpp" +#include +#include +#include + +#include "../../../../SDK/components/utilities/include/sample_log.h" + +using namespace StackFlows; + +int main_exit_flage = 0; +static void __sigint(int iSigNo) +{ + SLOGW("llm_yolo will be exit!"); + main_exit_flage = 1; +} + +static std::string base_model_path_; +static std::string base_model_config_path_; + +typedef struct { + std::string yolo_model; + std::string model_type = "detect"; + std::vector cls_name; + int img_h = 640; + int img_w = 640; + int cls_num = 80; + float pron_threshold = 0.45f; + float nms_threshold = 0.45; +} yolo_config; + +typedef std::function &data, bool finish)> task_callback_t; + +#define CONFIG_AUTO_SET(obj, key) \ + if (config_body.contains(#key)) \ + mode_config_.key = config_body[#key]; \ + else if (obj.contains(#key)) \ + mode_config_.key = obj[#key]; + +class llm_task { +private: +public: + yolo_config mode_config_; + std::string model_; + // std::unique_ptr yolo_; + std::string response_format_; + std::vector inputs_; + std::vector image_data_; + bool enoutput_; + bool enstream_; + static int ax_init_flage_; + task_callback_t out_callback_; + + bool parse_config(const nlohmann::json &config_body) + { + try { + model_ = config_body.at("model"); + response_format_ = config_body.at("response_format"); + enoutput_ = config_body.at("enoutput"); + if (config_body.contains("input")) { + if (config_body["input"].is_string()) { + inputs_.push_back(config_body["input"].get()); + } else if (config_body["input"].is_array()) { + for (auto _in : config_body["input"]) { + inputs_.push_back(_in.get()); + } + } + } else + throw std::string("error"); + } catch (...) { + SLOGE("setup config_body error"); + return true; + } + enstream_ = response_format_.find("stream") == std::string::npos ? false : true; + return false; + } + + int load_model(const nlohmann::json &config_body) + { + if (parse_config(config_body)) { + return -1; + } + nlohmann::json file_body; + std::list config_file_paths; + config_file_paths.push_back(std::string("./") + model_ + ".json"); + config_file_paths.push_back(base_model_path_ + "../share/" + model_ + ".json"); + try { + for (auto file_name : config_file_paths) { + std::ifstream config_file(file_name); + if (!config_file.is_open()) { + SLOGW("config file :%s miss", file_name.c_str()); + continue; + } + config_file >> file_body; + config_file.close(); + break; + } + if (file_body.empty()) { + SLOGE("all config file miss"); + return -2; + } + std::string base_model = base_model_path_ + model_ + "/"; + SLOGI("base_model %s", base_model.c_str()); + CONFIG_AUTO_SET(file_body["mode_param"], yolo_model); + CONFIG_AUTO_SET(file_body["mode_param"], img_h); + CONFIG_AUTO_SET(file_body["mode_param"], img_w); + CONFIG_AUTO_SET(file_body["mode_param"], pron_threshold); + CONFIG_AUTO_SET(file_body["mode_param"], nms_threshold); + CONFIG_AUTO_SET(file_body["mode_param"], cls_name); + CONFIG_AUTO_SET(file_body["mode_param"], cls_num); + CONFIG_AUTO_SET(file_body["mode_param"], model_type); + mode_config_.yolo_model = base_model + mode_config_.yolo_model; + // skel_ = std::make_unique(); + // if (0 != skel_->Init(mode_config_.yolo_model.c_str())) { + // SLOGE("Init yolo_model model failed!\n"); + // return -5; + // } + } catch (...) { + SLOGE("config false"); + return -6; + } + return 0; + } + + std::string format_float(double value, int decimal_places) + { + std::ostringstream out; + out << std::fixed << std::setprecision(decimal_places) << value; + return out.str(); + } + + void set_output(task_callback_t out_callback) + { + out_callback_ = out_callback; + } + + bool inference(const std::string &msg) + { + try { + // SLOGI("msg:%s", msg.c_str()); + std::ofstream outFile("output.bin"); + outFile << msg; + outFile.close(); + cv::Mat src = cv::imdecode(std::vector(msg.begin(), msg.end()), cv::IMREAD_COLOR); + if (src.empty()) return true; + SLOGI(""); + std::vector image(mode_config_.img_w * mode_config_.img_h * 3, 0); + common::get_input_data_letterbox(src, image, mode_config_.img_w, mode_config_.img_h, true); + int ret = -1; + // yolo_->SetInput(image.data(), 0); + // if (0 != yolo_->RunSync()) { + // SLOGE("Run yolo model failed!\n"); + // throw std::string("yolo_ RunSync error"); + // } + // std::vector objects; + // yolo_->Post_Process(src, mode_config_.img_w, mode_config_.img_h, mode_config_.cls_num, + // mode_config_.pron_threshold, mode_config_.nms_threshold, objects, + // mode_config_.model_type); + std::vector yolo_output; + // for (size_t i = 0; i < objects.size(); i++) { + // const detection::Object &obj = objects[i]; + // nlohmann::json output; + // output["class"] = mode_config_.cls_name[obj.label]; + // output["confidence"] = format_float(obj.prob, 2); + // output["bbox"] = nlohmann::json::array(); + // output["bbox"].push_back(format_float(obj.rect.x, 0)); + // output["bbox"].push_back(format_float(obj.rect.y, 0)); + // output["bbox"].push_back(format_float(obj.rect.x + obj.rect.width, 0)); + // output["bbox"].push_back(format_float(obj.rect.y + obj.rect.height, 0)); + // if (mode_config_.model_type == "segment") output["mask"] = obj.mask_feat; + // if (mode_config_.model_type == "pose") output["kps"] = obj.kps_feat; + // if (mode_config_.model_type == "obb") output["angle"] = obj.angle; + // yolo_output.push_back(output); + // if (out_callback_) out_callback_(yolo_output, false); + // } + if (out_callback_) out_callback_(yolo_output, true); + } catch (...) { + SLOGW("yolo_->Run have error!"); + return true; + } + return false; + } + + void _ax_init() + { + if (!ax_init_flage_) { + int ret = AX_SYS_Init(); + if (0 != ret) { + fprintf(stderr, "AX_SYS_Init failed! ret = 0x%x\n", ret); + } + // AX_ENGINE_NPU_ATTR_T npu_attr; + // memset(&npu_attr, 0, sizeof(npu_attr)); + // ret = AX_ENGINE_Init(&npu_attr); + if (0 != ret) { + fprintf(stderr, "Init ax-engine failed{0x%8x}.\n", ret); + } + } + ax_init_flage_++; + } + + void _ax_deinit() + { + if (ax_init_flage_ > 0) { + --ax_init_flage_; + if (!ax_init_flage_) { + // AX_ENGINE_Deinit(); + AX_SYS_Deinit(); + } + } + } + + llm_task(const std::string &workid) + { + _ax_init(); + } + + ~llm_task() + { + _ax_deinit(); + } +}; +int llm_task::ax_init_flage_ = 0; +#undef CONFIG_AUTO_SET + +class llm_yolo : public StackFlow { +private: + int task_count_; + std::unordered_map> llm_task_; + int _load_config() + { + if (base_model_path_.empty()) { + base_model_path_ = sys_sql_select("config_base_mode_path"); + } + if (base_model_config_path_.empty()) { + base_model_config_path_ = sys_sql_select("config_base_mode_config_path"); + } + if (base_model_path_.empty() || base_model_config_path_.empty()) { + return -1; + } else { + SLOGI("llm_yolo::_load_config success"); + return 0; + } + } + +public: + llm_yolo() : StackFlow("yolo") + { + task_count_ = 1; + repeat_event(1000, std::bind(&llm_yolo::_load_config, this)); + } + + void task_output(const std::weak_ptr llm_task_obj_weak, + const std::weak_ptr llm_channel_weak, const std::vector &data, + bool finish) + { + auto llm_task_obj = llm_task_obj_weak.lock(); + auto llm_channel = llm_channel_weak.lock(); + if (!(llm_task_obj && llm_channel)) { + return; + } + if (llm_channel->enstream_) { + static int count = 0; + nlohmann::json data_body; + data_body["index"] = count++; + for (const auto &jsonObj : data) { + data_body["delta"].push_back(jsonObj); + } + if (!finish) + data_body["delta"] = data; + else + data_body["delta"] = std::string(""); + data_body["finish"] = finish; + if (finish) count = 0; + llm_channel->send(llm_task_obj->response_format_, data_body, LLM_NO_ERROR); + } else if (finish) { + llm_channel->send(llm_task_obj->response_format_, data, LLM_NO_ERROR); + } + } + + void task_user_data(const std::weak_ptr llm_task_obj_weak, + const std::weak_ptr llm_channel_weak, const std::string &object, + const std::string &data) + { + nlohmann::json error_body; + auto llm_task_obj = llm_task_obj_weak.lock(); + auto llm_channel = llm_channel_weak.lock(); + if (!(llm_task_obj && llm_channel)) { + error_body["code"] = -11; + error_body["message"] = "Model run failed."; + send("None", "None", error_body, unit_name_); + return; + } + if (data.empty() || (data == "None")) { + error_body["code"] = -24; + error_body["message"] = "The inference data is empty."; + send("None", "None", error_body, unit_name_); + return; + } + const std::string *next_data = &data; + bool enstream = (object.find("stream") == std::string::npos) ? false : true; + int ret; + std::string tmp_msg1; + if (enstream) { + static std::unordered_map stream_buff; + try { + if (decode_stream(data, tmp_msg1, stream_buff)) { + return; + }; + } catch (...) { + stream_buff.clear(); + error_body["code"] = -25; + error_body["message"] = "Stream data index error."; + send("None", "None", error_body, unit_name_); + return; + } + next_data = &tmp_msg1; + } + // must encode base64 + std::string tmp_msg2; + ret = decode_base64((*next_data), tmp_msg2); + if (ret == -1) { + error_body["code"] = -23; + error_body["message"] = "Base64 decoding error."; + send("None", "None", error_body, unit_name_); + return; + } + next_data = &tmp_msg2; + if (llm_task_obj->inference(*next_data)) { + error_body["code"] = -11; + error_body["message"] = "Model run failed."; + send("None", "None", error_body, unit_name_); + } + } + + int setup(const std::string &work_id, const std::string &object, const std::string &data) override + { + nlohmann::json error_body; + if ((llm_task_channel_.size() - 1) == task_count_) { + error_body["code"] = -21; + error_body["message"] = "task full"; + send("None", "None", error_body, unit_name_); + return -1; + } + + int work_id_num = sample_get_work_id_num(work_id); + auto llm_channel = get_channel(work_id); + auto llm_task_obj = std::make_shared(work_id); + + nlohmann::json config_body; + try { + config_body = nlohmann::json::parse(data); + } catch (...) { + SLOGE("setup json format error."); + error_body["code"] = -2; + error_body["message"] = "json format error."; + send("None", "None", error_body, unit_name_); + return -2; + } + int ret = llm_task_obj->load_model(config_body); + if (ret == 0) { + llm_channel->set_output(llm_task_obj->enoutput_); + llm_channel->set_stream(llm_task_obj->enstream_); + + llm_task_obj->set_output(std::bind(&llm_yolo::task_output, this, llm_task_obj, llm_channel, + std::placeholders::_1, std::placeholders::_2)); + + for (const auto input : llm_task_obj->inputs_) { + if (input.find("yolo") != std::string::npos) { + llm_channel->subscriber_work_id( + "", std::bind(&llm_yolo::task_user_data, this, std::weak_ptr(llm_task_obj), + std::weak_ptr(llm_channel), std::placeholders::_1, + std::placeholders::_2)); + } else if (input.find("sys") != std::string::npos) { + // TODO:... + } + llm_task_[work_id_num] = llm_task_obj; + SLOGI("load_mode success"); + send("None", "None", LLM_NO_ERROR, work_id); + return 0; + } + return 0; + } else { + SLOGE("load_mode Failed"); + error_body["code"] = -5; + error_body["message"] = "Model loading failed."; + send("None", "None", error_body, unit_name_); + return -1; + } + } + + void link(const std::string &work_id, const std::string &object, const std::string &data) override + { + SLOGI("llm_yolo::link:%s", data.c_str()); + int ret = 1; + nlohmann::json error_body; + int work_id_num = sample_get_work_id_num(work_id); + if (llm_task_.find(work_id_num) == llm_task_.end()) { + error_body["code"] = -6; + error_body["message"] = "Unit Does Not Exist"; + send("None", "None", error_body, work_id); + return; + } + auto llm_channel = get_channel(work_id); + auto llm_task_obj = llm_task_[work_id_num]; + if (data.find("yolo") != std::string::npos) { + ret = llm_channel->subscriber_work_id( + "", + std::bind(&llm_yolo::task_user_data, this, std::weak_ptr(llm_task_obj), + std::weak_ptr(llm_channel), std::placeholders::_1, std::placeholders::_2)); + llm_task_obj->inputs_.push_back(data); + } else if (data.find("sys") != std::string::npos) { + // TODO:... + } + if (ret) { + error_body["code"] = -20; + error_body["message"] = "link false"; + send("None", "None", error_body, work_id); + return; + } else { + send("None", "None", LLM_NO_ERROR, work_id); + } + } + + void unlink(const std::string &work_id, const std::string &object, const std::string &data) override + { + SLOGI("llm_yolo::unlink:%s", data.c_str()); + int ret = 0; + nlohmann::json error_body; + int work_id_num = sample_get_work_id_num(work_id); + if (llm_task_.find(work_id_num) == llm_task_.end()) { + error_body["code"] = -6; + error_body["message"] = "Unit Does Not Exist"; + send("None", "None", error_body, work_id); + return; + } + auto llm_channel = get_channel(work_id); + llm_channel->stop_subscriber_work_id(data); + auto llm_task_obj = llm_task_[work_id_num]; + for (auto it = llm_task_obj->inputs_.begin(); it != llm_task_obj->inputs_.end();) { + if (*it == data) { + it = llm_task_obj->inputs_.erase(it); + } else { + ++it; + } + } + send("None", "None", LLM_NO_ERROR, work_id); + } + + void taskinfo(const std::string &work_id, const std::string &object, const std::string &data) override + { + SLOGI("llm_yolo::taskinfo:%s", data.c_str()); + nlohmann::json req_body; + int work_id_num = sample_get_work_id_num(work_id); + if (WORK_ID_NONE == work_id_num) { + std::vector task_list; + std::transform(llm_task_channel_.begin(), llm_task_channel_.end(), std::back_inserter(task_list), + [](const auto task_channel) { return task_channel.second->work_id_; }); + req_body = task_list; + send("yolo.tasklist", req_body, LLM_NO_ERROR, work_id); + } else { + if (llm_task_.find(work_id_num) == llm_task_.end()) { + req_body["code"] = -6; + req_body["message"] = "Unit Does Not Exist"; + send("None", "None", req_body, work_id); + return; + } + auto llm_task_obj = llm_task_[work_id_num]; + req_body["model"] = llm_task_obj->model_; + req_body["response_format"] = llm_task_obj->response_format_; + req_body["enoutput"] = llm_task_obj->enoutput_; + req_body["inputs_"] = llm_task_obj->inputs_; + send("yolo.taskinfo", req_body, LLM_NO_ERROR, work_id); + } + } + + int exit(const std::string &work_id, const std::string &object, const std::string &data) override + { + SLOGI("llm_yolo::exit:%s", data.c_str()); + + nlohmann::json error_body; + int work_id_num = sample_get_work_id_num(work_id); + if (llm_task_.find(work_id_num) == llm_task_.end()) { + error_body["code"] = -6; + error_body["message"] = "Unit Does Not Exist"; + send("None", "None", error_body, work_id); + return -1; + } + auto llm_channel = get_channel(work_id_num); + llm_channel->stop_subscriber(""); + llm_task_.erase(work_id_num); + send("None", "None", LLM_NO_ERROR, work_id); + return 0; + } + + ~llm_yolo() + { + while (1) { + auto iteam = llm_task_.begin(); + if (iteam == llm_task_.end()) { + break; + } + get_channel(iteam->first)->stop_subscriber(""); + iteam->second.reset(); + llm_task_.erase(iteam->first); + } + } +}; + +int main() +{ + signal(SIGTERM, __sigint); + signal(SIGINT, __sigint); + mkdir("/tmp/llm", 0777); + llm_yolo llm; + while (!main_exit_flage) { + sleep(1); + } + llm.llm_firework_exit(); + return 0; +} \ No newline at end of file diff --git a/projects/llm_framework/main_skel/src/runner/YuvHandler.c b/projects/llm_framework/main_skel/src/runner/YuvHandler.c new file mode 100644 index 0000000..60d1fb4 --- /dev/null +++ b/projects/llm_framework/main_skel/src/runner/YuvHandler.c @@ -0,0 +1,269 @@ +/************************************************************************************************** + * + * Copyright (c) 2019-2024 Axera Semiconductor Co., Ltd. All Rights Reserved. + * + * This source file is the property of Axera Semiconductor Co., Ltd. and + * may not be copied or distributed in any isomorphic form without the prior + * written consent of Axera Semiconductor Co., Ltd. + * + **************************************************************************************************/ + +#include "YuvHandler.h" +#include +#include +#include +#include + +/// +typedef struct _YUV_COLOR_S { + AX_U8 Y; + AX_U8 U; + AX_U8 V; +} YUV_COLOR_S; + +YUV_COLOR_S g_YuvColors[YUV_COLOR_MAX] = { + {0x00, 0x00, 0x00}, // green + {0x00, 0x00, 0xff}, // red + {0x00, 0xff, 0x00}, // blue + {0x00, 0xff, 0xff}, // purple + {0xff, 0x00, 0x00}, // dark green + {0xff, 0x00, 0xff}, // yellow + {0xff, 0xff, 0x00}, // light blue + {0xff, 0xff, 0xff}, // light purple + {0x00, 0x80, 0x80}, // dark black + {0x80, 0x80, 0x80}, // gray + {0xff, 0x80, 0x80} // white +}; + +static AX_VOID DrawPointInternal(YUV_IMAGE_T *pstImage, AX_U8 *y, AX_U8 *u, AX_U8 *v, AX_U16 x0, AX_U16 y0, + YUV_COLOR eColor) { + if (!pstImage) { + return; + } + + AX_S16 m_stride = pstImage->stride; + AX_S16 m_eType = pstImage->eType; + + AX_U32 y_offset = 0; + AX_U32 u_offset = 0; + AX_U32 v_offset = 0; + switch (m_eType) { + case AX_FORMAT_YUV420_PLANAR: // YUV420 I420 + /* YYYY...UUUU...VVVV */ + y_offset = (AX_U32)(y0 * m_stride + x0); + u_offset = (AX_U32)((y0 / 2) * (m_stride / 2) + x0 / 2); + v_offset = u_offset; + + y[y_offset] = g_YuvColors[eColor].Y; + u[u_offset] = g_YuvColors[eColor].U; + v[v_offset] = g_YuvColors[eColor].V; + break; + + case AX_FORMAT_YUV420_SEMIPLANAR: // YUV420SP NV12 + /* YYYY...UVUV */ + y_offset = (AX_U32)(y0 * m_stride + x0); + u_offset = (AX_U32)((y0 / 2) * m_stride + x0 / 2 * 2); + v_offset = u_offset + 1; + + if (g_YuvColors[eColor].Y == 0xFF) { + y[y_offset] = g_YuvColors[eColor].Y; + } else { + u[u_offset] = g_YuvColors[eColor].U; + v[v_offset] = g_YuvColors[eColor].V; + } + break; + + case AX_FORMAT_YUV420_SEMIPLANAR_VU: // YUV420SP NV21 + /* YYYY...VUVU */ + y_offset = (AX_U32)(y0 * m_stride + x0); + v_offset = (AX_U32)((y0 / 2) * m_stride + x0 / 2 * 2); + u_offset = v_offset + 1; + + y[y_offset] = g_YuvColors[eColor].Y; + u[u_offset] = g_YuvColors[eColor].U; + v[v_offset] = g_YuvColors[eColor].V; + break; + + case AX_FORMAT_YUV422_INTERLEAVED_UYVY: + /* UYVYUYVY */ + u_offset = (AX_U32)(y0 * m_stride * 2 + x0 / 2 * 4); + v_offset = u_offset + 2; + y_offset = u_offset + 1; + y[y_offset] = g_YuvColors[eColor].Y; + y[y_offset + 2] = g_YuvColors[eColor].Y; + y[u_offset] = g_YuvColors[eColor].U; + y[v_offset] = g_YuvColors[eColor].V; + break; + + case AX_FORMAT_YUV422_INTERLEAVED_YUYV: + /* YUYVYUYV */ + y_offset = (AX_U32)(y0 * m_stride * 2 + x0 / 2 * 4); + u_offset = y_offset + 1; + v_offset = u_offset + 2; + + y[y_offset] = g_YuvColors[eColor].Y; + y[y_offset + 2] = g_YuvColors[eColor].Y; + y[u_offset] = g_YuvColors[eColor].U; + y[v_offset] = g_YuvColors[eColor].V; + break; + + default: + break; + } +} + +AX_VOID DrawPoint(YUV_IMAGE_T *pstImage, AX_S16 x, AX_S16 y, AX_U8 nScale /* = 1*/, AX_S16 x_offset /* = 0*/, + AX_S16 y_offset /* = 0*/, YUV_COLOR eColor /* = YUV_GREEN*/) { + if (!pstImage) { + return; + } + + AX_U8 *m_pImage = pstImage->pImage; + AX_S16 m_nWidth = pstImage->nWidth; + AX_S16 m_nHeight = pstImage->nHeight; + AX_S16 m_stride = pstImage->stride; + AX_S16 m_eType = pstImage->eType; + + AX_U8 *pY = NULL; + AX_U8 *pU = NULL; + AX_U8 *pV = NULL; + switch (m_eType) { + case AX_FORMAT_YUV420_PLANAR: + pY = m_pImage; + pU = m_pImage + m_stride * m_nHeight; + pV = pU + m_stride * m_nHeight / 4; + break; + case AX_FORMAT_YUV420_SEMIPLANAR: + case AX_FORMAT_YUV420_SEMIPLANAR_VU: + pY = m_pImage; + pU = m_pImage + m_stride * m_nHeight; + pV = pU; + break; + case AX_FORMAT_YUV422_INTERLEAVED_UYVY: + case AX_FORMAT_YUV422_INTERLEAVED_YUYV: + pY = m_pImage; + pU = pY; + pV = pY; + break; + default: + break; + } + + AX_S16 nXStart = 0; + AX_S16 nYStart = 0; + for (AX_U32 hScale = 0; hScale < nScale; hScale++) { + for (AX_U32 wScale = 0; wScale < nScale; wScale++) { + nXStart = x * nScale + hScale - x_offset; + nYStart = y * nScale + wScale - y_offset; + if (nXStart < 0 || nXStart > m_nWidth) { + break; + } + + if (nYStart < 0 || nYStart > m_nHeight) { + break; + } + + DrawPointInternal(pstImage, pY, pU, pV, nXStart, nYStart, eColor); + } + } +} + +AX_VOID DrawLine(YUV_IMAGE_T *pstImage, AX_S16 x0, AX_S16 y0, AX_S16 x1, AX_S16 y1, YUV_COLOR eColor /* = YUV_GREEN*/, + AX_U8 nScale /* = 1*/) + +{ + if (!pstImage) { + return; + } + + AX_U8 *m_pImage = pstImage->pImage; + AX_S16 m_nWidth = pstImage->nWidth; + AX_S16 m_nHeight = pstImage->nHeight; + AX_S16 m_stride = pstImage->stride; + AX_S16 m_eType = pstImage->eType; + + x0 = (x0 < 0) ? 0 : x0; + y0 = (y0 < 0) ? 0 : y0; + x1 = (x1 < 0) ? 0 : x1; + y1 = (y1 < 0) ? 0 : y1; + + x0 = (x0 >= m_nWidth) ? m_nWidth - 1 : x0; + y0 = (y0 >= m_nHeight) ? m_nHeight - 1 : y0; + x1 = (x1 >= m_nWidth) ? m_nWidth - 1 : x1; + y1 = (y1 >= m_nHeight) ? m_nHeight - 1 : y1; + + AX_U16 dx = (x0 > x1) ? (x0 - x1) : (x1 - x0); + AX_U16 dy = (y0 > y1) ? (y0 - y1) : (y1 - y0); + + AX_S16 xstep = (x0 < x1) ? 1 : -1; + AX_S16 ystep = (y0 < y1) ? 1 : -1; + AX_S16 nstep = 0, eps = 0; + + AX_U8 *pY = NULL; + AX_U8 *pU = NULL; + AX_U8 *pV = NULL; + switch (m_eType) { + case AX_FORMAT_YUV420_PLANAR: + pY = m_pImage; + pU = m_pImage + m_stride * m_nHeight; + pV = pU + m_stride * m_nHeight / 4; + break; + case AX_FORMAT_YUV420_SEMIPLANAR: + case AX_FORMAT_YUV420_SEMIPLANAR_VU: + pY = m_pImage; + pU = m_pImage + m_stride * m_nHeight; + pV = pU; + break; + case AX_FORMAT_YUV422_INTERLEAVED_UYVY: + case AX_FORMAT_YUV422_INTERLEAVED_YUYV: + pY = m_pImage; + pU = pY; + pV = pY; + break; + default: + break; + } + + AX_U16 x = x0; + AX_U16 y = y0; + if (dx > dy) { + while (nstep <= dx) { + if (nScale == 1) { + DrawPointInternal(pstImage, pY, pU, pV, x, y, eColor); + } else { + DrawPoint(pstImage, x, y, nScale, x * (nScale - 1), y * (nScale - 1), eColor); + } + eps += dy; + if ((eps << 1) >= dx) { + y += ystep; + eps -= dx; + } + x += xstep; + nstep++; + } + } else { + while (nstep <= dy) { + if (nScale == 1) { + DrawPointInternal(pstImage, pY, pU, pV, x, y, eColor); + } else { + DrawPoint(pstImage, x, y, nScale, x * (nScale - 1), y * (nScale - 1), eColor); + } + eps += dx; + if ((eps << 1) >= dy) { + x += xstep; + eps -= dy; + } + y += ystep; + nstep++; + } + } +} + +AX_VOID DrawRect(YUV_IMAGE_T *pstImage, AX_S16 x0, AX_S16 y0, AX_U16 w, AX_U16 h, YUV_COLOR eColor /* = YUV_GREEN*/) { + if (w > 0 && h > 0) { + DrawLine(pstImage, x0, y0, x0 + w, y0, eColor, 1); + DrawLine(pstImage, x0, y0, x0, y0 + h, eColor, 1); + DrawLine(pstImage, x0 + w, y0, x0 + w, y0 + h, eColor, 1); + DrawLine(pstImage, x0, y0 + h, x0 + w, y0 + h, eColor, 1); + } +} diff --git a/projects/llm_framework/main_skel/src/runner/YuvHandler.h b/projects/llm_framework/main_skel/src/runner/YuvHandler.h new file mode 100644 index 0000000..ce4f6d4 --- /dev/null +++ b/projects/llm_framework/main_skel/src/runner/YuvHandler.h @@ -0,0 +1,46 @@ +/************************************************************************************************** + * + * Copyright (c) 2019-2024 Axera Semiconductor Co., Ltd. All Rights Reserved. + * + * This source file is the property of Axera Semiconductor Co., Ltd. and + * may not be copied or distributed in any isomorphic form without the prior + * written consent of Axera Semiconductor Co., Ltd. + * + **************************************************************************************************/ + +#ifndef _YUV_HANDLER_H_ +#define _YUV_HANDLER_H_ + +#include "ax_global_type.h" +#include "ax_sys_api.h" + +typedef enum _YUV_COLOR { + YUV_GREEN = 0, + YUV_RED, + YUV_BLUE, + YUV_PURPLE, + YUV_DARK_GREEN, + YUV_YELLOW, + YUV_LIGHT_BLUE, + YUV_LIGHT_PURPLE, + YUV_DARK_BLACK, + YUV_GRAY, + YUV_WHITE, + YUV_COLOR_MAX, +} YUV_COLOR; + +typedef struct _YUV_IMAGE_T { + AX_U8 *pImage; + AX_U16 nWidth; + AX_U16 nHeight; + AX_S16 stride; + AX_U32 nSize; + AX_IMG_FORMAT_E eType; +} YUV_IMAGE_T; + +AX_VOID DrawLine(YUV_IMAGE_T *pstImage, AX_S16 x0, AX_S16 y0, AX_S16 x1, AX_S16 y1, YUV_COLOR eColor, AX_U8 nScale); +AX_VOID DrawRect(YUV_IMAGE_T *pstImage, AX_S16 x0, AX_S16 y0, AX_U16 w, AX_U16 h, YUV_COLOR eColor); +AX_VOID DrawPoint(YUV_IMAGE_T *pstImage, AX_S16 x, AX_S16 y, AX_U8 nScale, AX_S16 x_offset, AX_S16 y_offset, + YUV_COLOR eColor); + +#endif /* _YUV_HANDLER_H_ */ diff --git a/projects/llm_framework/main_skel/src/runner/attrParser.cpp b/projects/llm_framework/main_skel/src/runner/attrParser.cpp new file mode 100644 index 0000000..8e386a9 --- /dev/null +++ b/projects/llm_framework/main_skel/src/runner/attrParser.cpp @@ -0,0 +1,224 @@ +/************************************************************************************************** + * + * Copyright (c) 2019-2024 Axera Semiconductor Co., Ltd. All Rights Reserved. + * + * This source file is the property of Axera Semiconductor Co., Ltd. and + * may not be copied or distributed in any isomorphic form without the prior + * written consent of Axera Semiconductor Co., Ltd. + * + **************************************************************************************************/ + +#include "attrParser.h" +#include "picojson.h" + +#define PICO_OBJECT get() +#define PICO_OBJECT_SIZE PICO_OBJECT.size() +#define PICO_ARRAY get() +#define PICO_ARRAY_SIZE PICO_ARRAY.size() +#define PICO_VALUE get() +#define PICO_BOOL get() +#define PICO_STRING get() +#define PICO_ROOT obj.PICO_OBJECT + +typedef struct _AI_Face_Attr_t { + AX_F32 fYaw; + AX_F32 fPitch; + AX_F32 fRoll; + AX_F32 fMask; + AX_U8 age; + AX_U8 gender; + AX_F32 fScore; +} AI_Face_Attr_t; + +typedef struct _AI_Plate_Attr_t { + AX_BOOL bExist; + AX_BOOL bValid; + /* + string: + blue + yellow + black + white + green + small_new_energy + large_new_energy + absence + unknown + */ + std::string strPlateColor; + /* + string: + one_row + two_rows + unknown + */ + std::string strPlateType; + /* string: UTF8*/ + std::string strPlateCode; + + _AI_Plate_Attr_t() { + bExist = AX_FALSE; + bValid = AX_FALSE; + strPlateColor = ""; + strPlateType = ""; + strPlateCode = ""; + } +} AI_Plate_Attr_t; + +static AX_VOID FaceAttrResult(const AX_SKEL_OBJECT_ITEM_T *pstObjectItems, ATTRINFO_T *pAttrInfo) { + picojson::value obj; + AI_Face_Attr_t face_attr; + + pAttrInfo->eType = ATTR_TYPE_FACE; + + for (size_t i = 0; i < pstObjectItems->nMetaInfoSize; i++) { + if (!strcmp(pstObjectItems->pstMetaInfo[i].pstrType, "face_attr")) { + std::string value = pstObjectItems->pstMetaInfo[i].pstrValue; + std::string strParseRet = picojson::parse(obj, value); + if (!strParseRet.empty() || !obj.is()) { + break; + } + // age + face_attr.age = PICO_ROOT["age"].PICO_VALUE; + printf("ageis %d\n",face_attr.age); + // gender + face_attr.gender = PICO_ROOT["gender"].PICO_VALUE; + // yaw + face_attr.fYaw = PICO_ROOT["yaw"].PICO_VALUE; + // pitch + face_attr.fPitch = PICO_ROOT["pitch"].PICO_VALUE; + // roll + face_attr.fRoll = PICO_ROOT["roll"].PICO_VALUE; + // mask + face_attr.fMask = PICO_ROOT["mask"].PICO_VALUE; + // score + face_attr.fScore = PICO_ROOT["score"].PICO_VALUE; + printf("score is %f\n",face_attr.fScore); + } + } +} + +static AX_VOID PlateAttrResult(const AX_SKEL_OBJECT_ITEM_T *pstObjectItems, ATTRINFO_T *pAttrInfo) { + picojson::value obj; + AI_Plate_Attr_t plat_attr; + + pAttrInfo->eType = ATTR_TYPE_PLATE; + + plat_attr.bExist = AX_FALSE; + plat_attr.bValid = AX_FALSE; + plat_attr.strPlateColor = ""; + plat_attr.strPlateType = ""; + plat_attr.strPlateCode = ""; + + for (size_t i = 0; i < pstObjectItems->nMetaInfoSize; i++) { + if (!strcmp(pstObjectItems->pstMetaInfo[i].pstrType, "plate_attr")) { + std::string value = pstObjectItems->pstMetaInfo[i].pstrValue; + std::string strParseRet = picojson::parse(obj, value); + if (!strParseRet.empty() || !obj.is()) { + break; + } + + plat_attr.bExist = AX_TRUE; + // color + plat_attr.strPlateColor = "unknown"; + if (PICO_ROOT.end() != PICO_ROOT.find("color")) { + plat_attr.strPlateColor = PICO_ROOT["color"].PICO_OBJECT["name"].PICO_STRING; + } + + // style + plat_attr.strPlateType = "unknown"; + if (PICO_ROOT.end() != PICO_ROOT.find("style")) { + plat_attr.strPlateType = PICO_ROOT["style"].PICO_OBJECT["name"].PICO_STRING; + } + + // code + plat_attr.strPlateCode = PICO_ROOT["code_result"].PICO_STRING; + + if (PICO_ROOT["code_killed"].PICO_BOOL) { + plat_attr.bValid = AX_FALSE; + } else { + plat_attr.bValid = AX_TRUE; + } + + pAttrInfo->bExist = AX_TRUE; + + strncpy(pAttrInfo->tPlateInfo.szColor, (const AX_CHAR *)plat_attr.strPlateColor.c_str(), sizeof(pAttrInfo->tPlateInfo.szColor) - 1); + + pAttrInfo->tPlateInfo.bValid = plat_attr.bValid; + strncpy(pAttrInfo->tPlateInfo.szNum, (const AX_CHAR *)plat_attr.strPlateCode.c_str(), sizeof(pAttrInfo->tPlateInfo.szNum) - 1); + } + } +} + +static AX_VOID VehicleAttrResult(const AX_SKEL_OBJECT_ITEM_T *pstObjectItems, ATTRINFO_T *pAttrInfo) { + picojson::value obj; + AI_Plate_Attr_t plat_attr; + + pAttrInfo->eType = ATTR_TYPE_VEHICLE; + + plat_attr.bExist = AX_FALSE; + plat_attr.bValid = AX_FALSE; + plat_attr.strPlateColor = ""; + plat_attr.strPlateType = ""; + plat_attr.strPlateCode = ""; + + for (size_t i = 0; i < pstObjectItems->nMetaInfoSize; i++) { + if (!strcmp(pstObjectItems->pstMetaInfo[i].pstrType, "plate_attr")) { + std::string value = pstObjectItems->pstMetaInfo[i].pstrValue; + std::string strParseRet = picojson::parse(obj, value); + if (!strParseRet.empty() || !obj.is()) { + break; + } + + plat_attr.bExist = AX_TRUE; + // color + plat_attr.strPlateColor = "unknown"; + if (PICO_ROOT.end() != PICO_ROOT.find("color")) { + plat_attr.strPlateColor = PICO_ROOT["color"].PICO_OBJECT["name"].PICO_STRING; + } + + // style + plat_attr.strPlateType = "unknown"; + if (PICO_ROOT.end() != PICO_ROOT.find("style")) { + plat_attr.strPlateType = PICO_ROOT["style"].PICO_OBJECT["name"].PICO_STRING; + } + + // code + plat_attr.strPlateCode = PICO_ROOT["code_result"].PICO_STRING; + + if (PICO_ROOT["code_killed"].PICO_BOOL) { + plat_attr.bValid = AX_FALSE; + } else { + plat_attr.bValid = AX_TRUE; + } + + pAttrInfo->bExist = AX_TRUE; + + strncpy(pAttrInfo->tPlateInfo.szColor, (const AX_CHAR *)plat_attr.strPlateColor.c_str(), sizeof(pAttrInfo->tPlateInfo.szColor) - 1); + + pAttrInfo->tPlateInfo.bValid = plat_attr.bValid; + strncpy(pAttrInfo->tPlateInfo.szNum, (const AX_CHAR *)plat_attr.strPlateCode.c_str(), sizeof(pAttrInfo->tPlateInfo.szNum) - 1); + } + } +} + +AX_VOID AttrParser(const AX_SKEL_OBJECT_ITEM_T *pstObjectItems, ATTRINFO_T *pAttrInfo) { + if (!pstObjectItems || !pAttrInfo) { + return; + } + + pAttrInfo->bExist = AX_FALSE; + pAttrInfo->eType = ATTR_TYPE_BUTT; + + std::string strObjectCategory = pstObjectItems->pstrObjectCategory; + + if (strObjectCategory == "face") { + FaceAttrResult(pstObjectItems, pAttrInfo); + } + else if (strObjectCategory == "plate") { + PlateAttrResult(pstObjectItems, pAttrInfo); + } + else if (strObjectCategory == "vehicle") { + VehicleAttrResult(pstObjectItems, pAttrInfo); + } +} diff --git a/projects/llm_framework/main_skel/src/runner/attrParser.h b/projects/llm_framework/main_skel/src/runner/attrParser.h new file mode 100644 index 0000000..60646ef --- /dev/null +++ b/projects/llm_framework/main_skel/src/runner/attrParser.h @@ -0,0 +1,60 @@ +/************************************************************************************************** + * + * Copyright (c) 2019-2024 Axera Semiconductor Co., Ltd. All Rights Reserved. + * + * This source file is the property of Axera Semiconductor Co., Ltd. and + * may not be copied or distributed in any isomorphic form without the prior + * written consent of Axera Semiconductor Co., Ltd. + * + **************************************************************************************************/ + +#ifndef _ATTR_PARSER_H_ +#define _ATTR_PARSER_H_ +#include "ax_global_type.h" +#include "ax_sys_api.h" +#include "ax_skel_api.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum _ATTR_TYPE_E { + ATTR_TYPE_BODY = 0, + ATTR_TYPE_VEHICLE, + ATTR_TYPE_CYCLE, + ATTR_TYPE_FACE, + ATTR_TYPE_PLATE, + ATTR_TYPE_BUTT +} ATTR_TYPE_E; + +typedef struct _FACEINFO_T { + AX_U8 nGender; /* 0-female, 1-male */ + AX_U8 nAge; + AX_CHAR szMask[32]; + AX_CHAR szGender[32]; +} FACEINFO_T; + +typedef struct _PLATEINFO_T { + AX_BOOL bValid; + AX_CHAR szNum[16]; + AX_CHAR szColor[32]; +} PLATEINFO_T; + +typedef struct _ATTRINFO_T { + ATTR_TYPE_E eType; /* ATTR_TYPE_E */ + AX_BOOL bExist; + + union + { + FACEINFO_T tFaceInfo; + PLATEINFO_T tPlateInfo; + }; +} ATTRINFO_T; + +extern AX_VOID AttrParser(const AX_SKEL_OBJECT_ITEM_T *pstObjectItems, ATTRINFO_T *pAttrInfo); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/projects/llm_framework/main_skel/src/runner/common_vdec_utils.c b/projects/llm_framework/main_skel/src/runner/common_vdec_utils.c new file mode 100755 index 0000000..4fd522e --- /dev/null +++ b/projects/llm_framework/main_skel/src/runner/common_vdec_utils.c @@ -0,0 +1,2233 @@ +/************************************************************************************************** + * + * Copyright (c) 2019-2024 Axera Semiconductor Co., Ltd. All Rights Reserved. + * + * This source file is the property of Axera Semiconductor Co., Ltd. and + * may not be copied or distributed in any isomorphic form without the prior + * written consent of Axera Semiconductor Co., Ltd. + * + **************************************************************************************************/ + +#include +#include +#include +#include +#include +#include + +#include "common_vdec_utils.h" +#include "ax_vdec_api.h" +#include "common_arg_parse.h" +#include "common_vdec_api.h" + +#define AX_DEC_RET_STR_CASE(s32Ret) case (s32Ret): return(#s32Ret) + +const char *SampleVdecRetStr(AX_S32 s32Ret) +{ + switch (s32Ret) { + AX_DEC_RET_STR_CASE(AX_SUCCESS); + AX_DEC_RET_STR_CASE(AX_ERR_VDEC_INVALID_GRPID); + AX_DEC_RET_STR_CASE(AX_ERR_VDEC_INVALID_CHNID); + AX_DEC_RET_STR_CASE(AX_ERR_VDEC_ILLEGAL_PARAM); + AX_DEC_RET_STR_CASE(AX_ERR_VDEC_NULL_PTR); + AX_DEC_RET_STR_CASE(AX_ERR_VDEC_BAD_ADDR); + AX_DEC_RET_STR_CASE(AX_ERR_VDEC_SYS_NOTREADY); + AX_DEC_RET_STR_CASE(AX_ERR_VDEC_BUSY); + AX_DEC_RET_STR_CASE(AX_ERR_VDEC_NOT_INIT); + AX_DEC_RET_STR_CASE(AX_ERR_VDEC_NOT_CONFIG); + AX_DEC_RET_STR_CASE(AX_ERR_VDEC_NOT_SUPPORT); + AX_DEC_RET_STR_CASE(AX_ERR_VDEC_NOT_PERM); + AX_DEC_RET_STR_CASE(AX_ERR_VDEC_EXIST); + AX_DEC_RET_STR_CASE(AX_ERR_VDEC_UNEXIST); + AX_DEC_RET_STR_CASE(AX_ERR_VDEC_NOMEM); + AX_DEC_RET_STR_CASE(AX_ERR_VDEC_NOBUF); + AX_DEC_RET_STR_CASE(AX_ERR_VDEC_BUF_EMPTY); + AX_DEC_RET_STR_CASE(AX_ERR_VDEC_BUF_FULL); + AX_DEC_RET_STR_CASE(AX_ERR_VDEC_QUEUE_EMPTY); + AX_DEC_RET_STR_CASE(AX_ERR_VDEC_QUEUE_FULL); + AX_DEC_RET_STR_CASE(AX_ERR_VDEC_TIMED_OUT); + AX_DEC_RET_STR_CASE(AX_ERR_VDEC_FLOW_END); + AX_DEC_RET_STR_CASE(AX_ERR_VDEC_RUN_ERROR); + AX_DEC_RET_STR_CASE(AX_ERR_VDEC_STRM_ERROR); + AX_DEC_RET_STR_CASE(AX_ERR_POOL_UNEXIST); + AX_DEC_RET_STR_CASE(AX_ERR_POOL_ILLEGAL_PARAM); + AX_DEC_RET_STR_CASE(AX_ERR_POOL_NOT_SUPPORT); + AX_DEC_RET_STR_CASE(AX_ERR_POOL_NOT_PERM); + AX_DEC_RET_STR_CASE(AX_ERR_VDEC_NEED_REALLOC_BUF); + default: + SAMPLE_CRIT_LOG("Unknown return code. 0x%x", s32Ret); + return("unknown code."); + } +} + +typedef struct +{ + const uint8_t * data; // sps + int count; /* in parse */ + int index; /* in parse */ +} PARSE_STATE_T; + + + +#define PARSE_INIT(data, bytes) {(data), 8*(bytes), 0} + +#define PARSE_EOF(parse) ((parse)->index >= (parse)->count) + +static inline void __parse_init(PARSE_STATE_T *parse, const uint8_t *data, int bytes) +{ + parse->data = data; + parse->count = 8 * bytes; + parse->index = 0; +} + +static inline int __parse_get_bit(PARSE_STATE_T *parse) +{ + if (parse->index >= parse->count) + return 1; /* -> no infinite colomb's ... */ + + int bit = (parse->data[parse->index >> 3] >> (7 - (parse->index & 7))) & 1; + parse->index++; + return bit; +} + +static inline uint32_t __parse_get_bits(PARSE_STATE_T * parse, uint32_t cnt) +{ + uint32_t bit = 0; + while (cnt--) + bit = bit | (__parse_get_bit(parse) << cnt); + + return bit; +} + +#define PARSE_SKIP_BIT(parse) __parse_skip_bits(parse, 1) + +static inline void __parse_skip_bits(PARSE_STATE_T *parse, int cnt) +{ + parse->index += cnt; +} + +#define PARSE_GET_U8(parse) __parse_get_bits(parse, 8) +#define PARSE_GET_U16(parse) ((__parse_get_bits(parse, 8)<<8) | __parse_get_bits(parse, 8)) + +static inline uint32_t __parse_get_ue_golomb(PARSE_STATE_T * parse) +{ + int cnt = 0; + while (!__parse_get_bit(parse) && cnt < 32) + cnt++; + return cnt ? ((1 << cnt) - 1) + __parse_get_bits(parse, cnt) : 0; +} + +static inline int32_t __parse_get_se_golomb(PARSE_STATE_T * parse) +{ + uint32_t r = __parse_get_ue_golomb(parse) + 1; + return (r & 1) ? -(r >> 1) : (r >> 1); +} + +static inline void __parse_skip_golomb(PARSE_STATE_T * parse) +{ + int cnt = 0; + while (!__parse_get_bit(parse) && cnt < 32) + cnt++; + __parse_skip_bits(parse, cnt); +} + +#define PARSE_SKIP_UE_GOLOMB(parse) __parse_skip_golomb(parse) +#define PARSE_SKIP_SE_GOLOMB(parse) __parse_skip_golomb(parse) + +static const MPEG_RATIONAL_T aspect_ratios[] = +{ +/* page 213: */ +/* 0: unknown */ + {0, 1}, +/* 1...16: */ + {1, 1}, {12, 11 }, {10, 11}, {16, 11}, + {40, 33}, {24, 11}, {20, 11}, {32, 11}, + {80, 33}, {18, 11}, {15, 11}, {64, 33}, + {160, 99}, {4, 3}, {3, 2}, {2, 1} +}; + +int h264_parse_sps(const uint8_t *buf, int len, SAMPLE_H264_SPS_DATA_T *sps) +{ + int findSPS = -1; + int pos = 0; + + if (buf == NULL) { + SAMPLE_CRIT_LOG("buf == NULL"); + return -1; + } + + if (sps == NULL) { + SAMPLE_CRIT_LOG("sps == NULL"); + return -1; + } + + if (len < 16) { + SAMPLE_CRIT_LOG("len:%d < 16", len); + return -1; + } + + for (pos = 0; pos < len - 6; pos++) { + if ((buf[pos] == 0) && (buf[pos + 1] == 0) + && (buf[pos + 2] == 0x1) && ((buf[pos + 3] & 0x1f) == 0x7)) { + len -= (pos + 4); + buf += (pos + 4); + findSPS = AX_SUCCESS; + break; + } + } + + if (findSPS != AX_SUCCESS) { + SAMPLE_LOG_TMP("findSPS failed! Failed to parse width and height.\n" + "You can configure the '--res' parameter in case the program runs out of memory and cannot decode"); + return findSPS; + } + + PARSE_STATE_T parse = PARSE_INIT(buf, len); + int profile_idc, pic_order_cnt_type; + int frame_mbs_only; + int i, j; + + profile_idc = PARSE_GET_U8(&parse); + sps->profile = profile_idc; + SAMPLE_LOG_N("H.264 SPS: profile_idc %d", profile_idc); + /* constraint_set0_flag = __parse_get_bit(parse); */ + /* constraint_set1_flag = __parse_get_bit(parse); */ + /* constraint_set2_flag = __parse_get_bit(parse); */ + /* constraint_set3_flag = __parse_get_bit(parse); */ + /* reserved = __parse_get_bits(parse,4); */ + sps->level = PARSE_GET_U8(&parse); + __parse_skip_bits(&parse, 8); + PARSE_SKIP_UE_GOLOMB(&parse); /* seq_parameter_set_id */ + if (profile_idc >= 100) { + if (__parse_get_ue_golomb(&parse) == 3) {/* chroma_format_idc */ + PARSE_SKIP_BIT(&parse); /* residual_colour_transform_flag */ + } + PARSE_SKIP_UE_GOLOMB(&parse); /* bit_depth_luma - 8 */ + PARSE_SKIP_UE_GOLOMB(&parse); /* bit_depth_chroma - 8 */ + PARSE_SKIP_BIT(&parse); /* transform_bypass */ + if (__parse_get_bit(&parse)) { /* seq_scaling_matrix_present */ + for (i = 0; i < 8; i++) { + if (__parse_get_bit(&parse)) { + /* seq_scaling_list_present */ + int last = 8, next = 8, size = (i < 6) ? 16 : 64; + for (j = 0; j < size; j++) { + if (next) { + next = (last + __parse_get_se_golomb(&parse)) & 0xff; + } + last = next ? next : last; + } + } + } + } + } + + PARSE_SKIP_UE_GOLOMB(&parse); /* log2_max_frame_num - 4 */ + pic_order_cnt_type = __parse_get_ue_golomb(&parse); + if (pic_order_cnt_type == 0) { + PARSE_SKIP_UE_GOLOMB(&parse); /* log2_max_poc_lsb - 4 */ + } + else if (pic_order_cnt_type == 1) { + PARSE_SKIP_BIT(&parse); /* delta_pic_order_always_zero */ + PARSE_SKIP_SE_GOLOMB(&parse); /* offset_for_non_ref_pic */ + PARSE_SKIP_SE_GOLOMB(&parse); /* offset_for_top_to_bottom_field */ + j = __parse_get_ue_golomb(&parse); /* num_ref_frames_in_pic_order_cnt_cycle */ + for (i = 0; i < j; i++) { + PARSE_SKIP_SE_GOLOMB(&parse); /* offset_for_ref_frame[i] */ + } + + } + PARSE_SKIP_UE_GOLOMB(&parse); /* ref_frames */ + PARSE_SKIP_BIT(&parse); /* gaps_in_frame_num_allowed */ + sps->width /* mbs */ = __parse_get_ue_golomb(&parse) + 1; + sps->height /* mbs */ = __parse_get_ue_golomb(&parse) + 1; + frame_mbs_only = __parse_get_bit(&parse); + SAMPLE_LOG_N("H.264 SPS: pic_width: %u mbs", (unsigned)sps->width); + SAMPLE_LOG_N("H.264 SPS: pic_height: %u mbs", (unsigned)sps->height); + SAMPLE_LOG_N("H.264 SPS: frame only flag: %d", frame_mbs_only); + + sps->width *= 16; + sps->height *= 16 * (2 - frame_mbs_only); + + if (!frame_mbs_only) + if (__parse_get_bit(&parse)) /* mb_adaptive_frame_field_flag */ + SAMPLE_LOG_N("H.264 SPS: MBAFF"); + PARSE_SKIP_BIT(&parse); /* direct_8x8_inference_flag */ + if (__parse_get_bit(&parse)) { + /* frame_cropping_flag */ + uint32_t crop_left = __parse_get_ue_golomb(&parse); + uint32_t crop_right = __parse_get_ue_golomb(&parse); + uint32_t crop_top = __parse_get_ue_golomb(&parse); + uint32_t crop_bottom = __parse_get_ue_golomb(&parse); + SAMPLE_LOG_N("H.264 SPS: cropping %d %d %d %d", + crop_left, crop_top, crop_right, crop_bottom); + + sps->width -= 2 * (crop_left + crop_right); + if (frame_mbs_only) + sps->height -= 2 * (crop_top + crop_bottom); + else + sps->height -= 4 * (crop_top + crop_bottom); + } + + /* VUI parameters */ + sps->pixel_aspect.num = 0; + if (__parse_get_bit(&parse)) { + /* vui_parameters_present flag */ + if (__parse_get_bit(&parse)) { + /* aspect_ratio_info_present */ + uint32_t aspect_ratio_idc = PARSE_GET_U8(&parse); + SAMPLE_LOG_N("H.264 SPS: aspect_ratio_idc %d", aspect_ratio_idc); + + if (aspect_ratio_idc == 255 /* Extended_SAR */) { + sps->pixel_aspect.num = PARSE_GET_U16(&parse); /* sar_width */ + sps->pixel_aspect.den = PARSE_GET_U16(&parse); /* sar_height */ + SAMPLE_LOG_N("H.264 SPS: -> sar %dx%d", sps->pixel_aspect.num, sps->pixel_aspect.den); + } else { + if (aspect_ratio_idc < sizeof(aspect_ratios) / sizeof(aspect_ratios[0])) { + sps->pixel_aspect = aspect_ratios[aspect_ratio_idc]; + SAMPLE_LOG_N("H.264 SPS: -> aspect ratio %d / %d", sps->pixel_aspect.num, sps->pixel_aspect.den); + } else { + SAMPLE_LOG_N("H.264 SPS: aspect_ratio_idc out of range !"); + } + } + } + } + + SAMPLE_LOG_N("H.264 SPS: -> video size %dx%d, aspect %d:%d", + sps->width, sps->height, sps->pixel_aspect.num, sps->pixel_aspect.den); + + return findSPS; +} + + + +AX_PAYLOAD_TYPE_E DistinguishVideoType(const AX_U8 *stream, AX_U64 len) +{ + AX_U64 ReadLen = 0; + AX_U64 i = 0; + const AX_U8 *pu8Buf = stream; + + if (stream == NULL) { + SAMPLE_CRIT_LOG(" stream == NULL"); + return PT_BUTT; + } + + ReadLen = len; + + if (ReadLen <= 6) { + SAMPLE_CRIT_LOG(" len:%lld ReadLen:%lld", len, ReadLen); + return PT_BUTT; + } + + for (i = 0; i < ReadLen - 6; i++) + { + if ((pu8Buf[i+0] == 0) && (pu8Buf[i+1] == 0) && (pu8Buf[i+2] == 1)) { + if ((pu8Buf[i+3] & 0x1f) == 0x07) { + return PT_H264; + } + } + + if ((pu8Buf[i+0] == 0) && (pu8Buf[i+1] == 0) && (pu8Buf[i+2] == 0) && (pu8Buf[i+3] == 1)) { + if ((pu8Buf[i+4] == 0x40) && (pu8Buf[i+5] == 0x01)) { + return PT_H265; + } + } + } + + return PT_BUTT; +} + +static AX_S32 __MD5SumValidOnly(AX_U8 *p_lu, AX_U8 *p_ch, + AX_U32 coded_width, AX_U32 coded_height, + AX_U32 coded_width_ch, AX_U32 coded_height_ch, + AX_U32 pic_stride, AX_U32 pic_stride_ch, + AX_U32 planar, AX_U32 frame_number, char *md5_str) +{ +#if 0 + + unsigned char digest[16]; + MD5_CTX ctx; + int i = 0; + MD5_Init(&ctx); + AX_U8 *p_yuv = p_lu; + if (p_yuv) { + for (i = 0; i < coded_height; i++) { + MD5_Update(&ctx, p_yuv, coded_width); + p_yuv += pic_stride; + } + } + p_yuv = p_ch; + if (p_yuv) { + if (!planar) { + for (i = 0; i < coded_height_ch; i++) { + MD5_Update(&ctx, p_yuv, coded_width_ch); + p_yuv += pic_stride; + } + } else { + for (i = 0; i < coded_height_ch; i++) { + MD5_Update(&ctx, p_yuv, coded_width_ch / 2); + p_yuv += pic_stride_ch; + } + for (i = 0; i < coded_height_ch; i++) { + MD5_Update(&ctx, p_yuv, coded_width_ch / 2); + p_yuv += pic_stride_ch; + } + } + } + MD5_Final(digest, &ctx); + /* fprintf(f_out, "FRAME %d: ", frame_number);*/ + for (i = 0; i < 16; i++) { + snprintf(md5_str + i * 2, 2 + 1, "%02x", digest[i]); + } +#endif + return 0; +} + +int OutputFileCheckMD5(AX_VDEC_GRP VdGrp, const AX_VIDEO_FRAME_INFO_T *frameInfo, char *md5_str) +{ + AX_S32 sRet; + AX_S32 s32Ret = 0; + AX_VOID *pLumaVirAddr; + AX_VOID *pChromaVirAddr; + AX_U32 lumaMapSize; + AX_U32 chromaMapSize; + + if (frameInfo == NULL) { + s32Ret = AX_ERR_VDEC_NULL_PTR; + SAMPLE_CRIT_LOG("frameInfo == NULL\n"); + goto ERR_RET; + } + + if (md5_str == NULL) { + s32Ret = AX_ERR_VDEC_NULL_PTR; + SAMPLE_CRIT_LOG("md5_str == NULL\n"); + goto ERR_RET; + } + + if ((frameInfo->stVFrame.u64PhyAddr[0] == 0) || (frameInfo->stVFrame.u32PicStride[0] == 0)) { + SAMPLE_CRIT_LOG("VdGrp=%d, stVFrame.u64PhyAddr[0]:0x%llx stVFrame.u32PicStride[0]:%d\n", + VdGrp, frameInfo->stVFrame.u64PhyAddr[0], frameInfo->stVFrame.u32PicStride[0]); + s32Ret = 0; + goto ERR_RET; + } + + lumaMapSize = frameInfo->stVFrame.u32PicStride[0] * SIZE_ALIGN(frameInfo->stVFrame.u32Height, 16); + + pLumaVirAddr = AX_SYS_Mmap(frameInfo->stVFrame.u64PhyAddr[0], lumaMapSize); + if (!pLumaVirAddr) { + s32Ret = AX_ERR_VDEC_BAD_ADDR; + SAMPLE_CRIT_LOG("AX_SYS_Mmap luma FAILED\n"); + goto ERR_RET; + } + + SAMPLE_LOG("AX_SYS_Mmap luma success, pLumaVirAddr=%p,lumaMapSize=%d\n", + pLumaVirAddr, lumaMapSize); + + chromaMapSize = frameInfo->stVFrame.u32PicStride[0] * SIZE_ALIGN(frameInfo->stVFrame.u32Height, 16) / 2; + pChromaVirAddr = AX_SYS_Mmap(frameInfo->stVFrame.u64PhyAddr[1], chromaMapSize); + if (!pChromaVirAddr) { + s32Ret = AX_ERR_VDEC_BAD_ADDR; + SAMPLE_CRIT_LOG("AX_SYS_Mmap chroma FAILED\n"); + goto ERR_RET_CHROMA; + } + + SAMPLE_LOG("AX_SYS_Mmap chroma success, pChromaVirAddr=%p,chromaMapSize=%d\n", + pChromaVirAddr, chromaMapSize); + + AX_VOID *p_lu = pLumaVirAddr; + AX_VOID *p_ch = pChromaVirAddr; + AX_U32 coded_width = frameInfo->stVFrame.u32Width; + AX_U32 coded_height = frameInfo->stVFrame.u32Height; + AX_U32 pic_stride = frameInfo->stVFrame.u32PicStride[0]; + AX_U32 coded_width_ch = frameInfo->stVFrame.u32Width; + AX_U32 coded_h_ch = frameInfo->stVFrame.u32Height / 2; + AX_U32 pic_stride_ch = frameInfo->stVFrame.u32PicStride[1]; + s32Ret = __MD5SumValidOnly(p_lu, p_ch, coded_width, coded_height, coded_width_ch, coded_h_ch, + pic_stride, pic_stride_ch, 0, 0, md5_str); + if (s32Ret) { + SAMPLE_CRIT_LOG("__MD5SumValidOnly FAILED! s32Ret:0x%x", s32Ret); + goto ERR_RET_LUMA; + } + +ERR_RET_LUMA: + if (pLumaVirAddr) { + sRet = AX_SYS_Munmap(pLumaVirAddr, lumaMapSize); + if (sRet) { + s32Ret = sRet; + SAMPLE_CRIT_LOG("AX_SYS_Munmap luma FAILED,sRet=0x%x\n", sRet); + } else { + SAMPLE_LOG("AX_SYS_Munmap luma success,pLumaVirAddr=%p,lumaMapSize=%d\n", + pLumaVirAddr, lumaMapSize); + } + } +ERR_RET_CHROMA: + if (pChromaVirAddr) { + sRet = AX_SYS_Munmap(pChromaVirAddr, chromaMapSize); + if (sRet) { + s32Ret = sRet; + SAMPLE_CRIT_LOG("AX_SYS_Munmap chroma FAILED,sRet=0x%x\n", sRet); + } else { + SAMPLE_LOG("AX_SYS_Munmap chroma success,pChromaVirAddr=%p,chromaMapSize=%d\n", + pChromaVirAddr, chromaMapSize); + } + } +ERR_RET: + return s32Ret; +} + + +AX_S32 LoadOneFileToMem(const AX_CHAR *ps8File, AX_U8 **ppu8Mem, size_t *pLen) +{ + AX_S32 res = 0; + AX_U64 tmp_size = 0; + AX_U64 read_size = 0; + FILE *fInput = NULL; + + if (ps8File == NULL) { + SAMPLE_CRIT_LOG("ps8File == NULL\n"); + goto ERR_RET; + } + + if (ppu8Mem == NULL) { + SAMPLE_CRIT_LOG("ppu8Mem == NULL\n"); + goto ERR_RET; + } + + if (pLen == NULL) { + SAMPLE_CRIT_LOG("pLen == NULL\n"); + goto ERR_RET; + } + + fInput = fopen(ps8File, "rb"); + if (fInput == NULL) { + SAMPLE_CRIT_LOG("Unable to open input file:%s\n", ps8File); + res = AX_ERR_VDEC_RUN_ERROR; + goto ERR_RET; + } + + /* file i/o pointer to full */ + res = fseek(fInput, 0L, SEEK_END); + if (res) { + SAMPLE_CRIT_LOG("fseek FAILED! ret:%d\n", res); + goto ERR_RET; + } + + *pLen = ftello(fInput); + rewind(fInput); + + tmp_size = sizeof(AX_U8) * (*pLen); + *ppu8Mem = (AX_U8 *)malloc(tmp_size); + if (*ppu8Mem == NULL) { + SAMPLE_CRIT_LOG("malloc tmp_size:0x%llx FAILED!", tmp_size); + res = AX_ERR_VDEC_NOMEM; + goto ERR_RET_CLOSE; + } + + read_size = *pLen; + tmp_size = fread(*ppu8Mem, sizeof(AX_U8), read_size, fInput); + /* read input stream from file to buffer and close input file */ + if (tmp_size != read_size) { + SAMPLE_CRIT_LOG("fread FAILED! tmp_size:0x%llx != read_size:0x%llx\n", tmp_size, read_size); + res = AX_ERR_VDEC_STRM_ERROR; + goto ERR_RET_FREE; + } + +ERR_RET_FREE: + free((AX_VOID *)*ppu8Mem); + *ppu8Mem = NULL; +ERR_RET_CLOSE: + res = fclose(fInput); + if (res) { + SAMPLE_CRIT_LOG("fclose FAILED! ret:%d\n", res); + } +ERR_RET: + return res; +} + +FILE *OutputFileOpen(AX_CHAR **ppOutputFile, const SAMPLE_VDEC_OUTPUT_INFO_T *pInfo) +{ + FILE *fp_out = NULL; + int ret = 0; + AX_CHAR *file_path = NULL; + AX_CHAR *file_name = NULL; + AX_U32 slen = 0; + AX_CHAR *pFileOut = NULL; + + if (ppOutputFile == NULL) { + SAMPLE_CRIT_LOG("ppOutputFile == NULL"); + return NULL; + } + + if (*ppOutputFile == NULL) { + pFileOut = calloc(1, AX_VDEC_FILE_PATH_LEN); + if (pFileOut == NULL) { + SAMPLE_CRIT_LOG("malloc %d Bytes FAILED!\n", AX_VDEC_FILE_PATH_LEN); + return NULL; + } + *ppOutputFile = pFileOut; + + if (pInfo == NULL) { + ret = snprintf(pFileOut, AX_VDEC_FILE_NAME_LEN, "%s", "./out.yuv"); + } else { + if (pInfo->bOneShot) { + ret = snprintf(pFileOut, AX_VDEC_FILE_NAME_LEN, "oneShot_format%d_w_%d_h_%d.yuv", + pInfo->enImgFormat, pInfo->u32Width, pInfo->u32Height); + } else { + ret = snprintf(pFileOut, AX_VDEC_FILE_NAME_LEN, "group%d_format%d_w_%d_h_%d.yuv", + pInfo->VdGrp, pInfo->enImgFormat, pInfo->u32Width, pInfo->u32Height); + } + } + + if (ret < 0) { + SAMPLE_CRIT_LOG("snprintf FAILED! ret:0x%x pFileOut:%s AX_VDEC_FILE_NAME_LEN:%d\n", + ret, pFileOut, AX_VDEC_FILE_NAME_LEN); + goto ERR_RET_OUTPUTFILE; + } + + *ppOutputFile = pFileOut; + } else { + pFileOut = *ppOutputFile; + } + + SAMPLE_LOG("output_file_path >>>> pFileOut:%s", pFileOut); + slen = strlen(pFileOut); + ret = strncmp (pFileOut + slen - 1, "/", 1); + if (ret == 0) { + file_path = malloc(AX_VDEC_FILE_PATH_LEN); + if (NULL == file_path) { + SAMPLE_CRIT_LOG("malloc size:%d FAILED!", AX_VDEC_FILE_PATH_LEN); + goto ERR_RET_OUTPUTFILE; + } + + file_name = malloc(AX_VDEC_FILE_NAME_LEN); + if (NULL == file_name) { + SAMPLE_CRIT_LOG("malloc size:%d FAILED!", AX_VDEC_FILE_NAME_LEN); + goto ERR_RET_FILEPATH; + } + + if (pInfo == NULL) { + ret = snprintf(file_name, AX_VDEC_FILE_NAME_LEN, "%s", "out.yuv"); + } else { + if (pInfo->bOneShot) { + ret = snprintf(pFileOut, AX_VDEC_FILE_NAME_LEN, "oneShot_format%d_w_%d_h_%d.yuv", + pInfo->enImgFormat, pInfo->u32Width, pInfo->u32Height); + } else { + ret = snprintf(pFileOut, AX_VDEC_FILE_NAME_LEN, "group%d_format%d_w_%d_h_%d.yuv", + pInfo->VdGrp, pInfo->enImgFormat, pInfo->u32Width, pInfo->u32Height); + } + } + + if (ret < 0) { + SAMPLE_CRIT_LOG("snprintf FAILED! ret:0x%x file_name:%s AX_VDEC_FILE_NAME_LEN:%d\n", + ret, file_name, AX_VDEC_FILE_NAME_LEN); + goto ERR_RET_FILENAME; + } + + slen = strlen(file_name); + if (slen >= AX_VDEC_FILE_NAME_LEN) { + SAMPLE_CRIT_LOG("slen:%d >= AX_VDEC_FILE_NAME_LEN:%d\n", + slen, AX_VDEC_FILE_NAME_LEN); + goto ERR_RET_FILENAME; + } + + ret = snprintf(file_path, AX_VDEC_FILE_PATH_LEN, "%s%s", + pFileOut, file_name); + if (ret < 0) { + SAMPLE_CRIT_LOG("snprintf FAILED! ret:0x%x, pFileOut:%s, file_name:%s, AX_VDEC_FILE_PATH_LEN:%d\n", + ret, pFileOut, file_name, AX_VDEC_FILE_PATH_LEN); + goto ERR_RET_FILENAME; + } + + free(file_name); + free(pFileOut); + *ppOutputFile = file_path; + pFileOut = *ppOutputFile; + } + + slen = strlen(pFileOut); + ret = strncmp (pFileOut + slen - 1, "/", 1); + if (ret == 0) { + SAMPLE_CRIT_LOG("Please check pFileOut:%s, the last character cannot be '/' \n", pFileOut); + goto ERR_RET_FILENAME; + } + + if (access(pFileOut, F_OK) == 0) { + char new_name[AX_VDEC_FILE_PATH_LEN + AX_VDEC_FILE_NAME_LEN]; + memset(new_name, 0, sizeof(new_name)); + + struct timeval current_tv; + gettimeofday(¤t_tv, NULL); + + ret = sprintf(new_name, "%s_%lds_%ldus.bak", pFileOut, current_tv.tv_sec, current_tv.tv_usec); + if (ret < 0) { + SAMPLE_CRIT_LOG("snprintf FAILED! ret:0x%x, pFileOut:%s, AX_VDEC_FILE_PATH_LEN + AX_VDEC_FILE_NAME_LEN:%d\n", + ret, pFileOut, AX_VDEC_FILE_PATH_LEN + AX_VDEC_FILE_NAME_LEN); + goto ERR_RET_FILENAME; + } + // SAMPLE_LOG("new_name:%s ", new_name); + if (chmod(pFileOut, 0x777) != 0) { + SAMPLE_CRIT_LOG("chmod:%s FAILED", pFileOut); + } + + if (rename(pFileOut, new_name) == 0) { + SAMPLE_LOG("rename(pFileOut:%s, new_name:%s) success", + pFileOut, new_name); + } else { + SAMPLE_CRIT_LOG("rename(pFileOut:%s, new_name:%s) FAILED)", pFileOut, new_name); + } + } + + if (access(pFileOut, F_OK) == 0) { + if (chmod(pFileOut, 0x777) != 0) { + SAMPLE_CRIT_LOG("chmod:%s ", pFileOut); + } + + if (remove(pFileOut) == 0) { + if (access(pFileOut, F_OK) == 0) { + SAMPLE_CRIT_LOG("remove(pFileOut:%s FAIL)", pFileOut); + } + } else { + SAMPLE_CRIT_LOG("remove(pFileOut:%s FAIL)", pFileOut); + } + } + + fp_out = fopen(pFileOut, "w"); + if (fp_out == NULL) { + SAMPLE_CRIT_LOG("VdGrp=%d, fopen pFileOut:%s FAILED!", + pInfo->VdGrp, pFileOut); + } + + SAMPLE_LOG("output file name:%s, open fp_out:%p\n", pFileOut, fp_out); + return fp_out; + +ERR_RET_FILENAME: + if (file_name != NULL) { + free(file_name); + } +ERR_RET_FILEPATH: + if (file_path != NULL) { + free(file_path); + } +ERR_RET_OUTPUTFILE: + if (*ppOutputFile != NULL) { + free(*ppOutputFile); + *ppOutputFile = NULL; + } + + return NULL; +} + +static AX_S32 OutputSaveYUVFile(AX_VDEC_GRP VdGrp, const AX_VIDEO_FRAME_INFO_T *frameInfo, + FILE *fp_out, AX_CHAR *pOutputFilePath) +{ + int ret = 0; + AX_S32 sRet = 0; + AX_U32 i; + AX_VOID *p_lu = NULL; + AX_VOID *p_ch = NULL; + + AX_S32 s32Ret = 0; + AX_VOID *pLumaVirAddr = NULL; + AX_VOID *pChromaVirAddr = NULL; + AX_U32 lumaMapSize = 0; + AX_U32 chromaMapSize = 0; + int tmp_size = 0; + + if (NULL == frameInfo || NULL == fp_out) { + SAMPLE_CRIT_LOG("VdGrp=%d, NULL == frameInfo || NULL == fp_out\n", VdGrp); + s32Ret = AX_ERR_VDEC_NULL_PTR; + goto ERR_RET; + } + + if ((frameInfo->stVFrame.u64PhyAddr[0] == 0) || (frameInfo->stVFrame.u32PicStride[0] == 0)) { + SAMPLE_LOG("VdGrp=%d, stVFrame.u64PhyAddr[0]:0x%llx stVFrame.u32PicStride[0]:%d\n", + VdGrp, frameInfo->stVFrame.u64PhyAddr[0], frameInfo->stVFrame.u32PicStride[0]); + s32Ret = 0; + goto ERR_RET; + } + + lumaMapSize = frameInfo->stVFrame.u32PicStride[0] * SIZE_ALIGN(frameInfo->stVFrame.u32Height, 16); + pLumaVirAddr = AX_SYS_Mmap(frameInfo->stVFrame.u64PhyAddr[0], lumaMapSize); + if (NULL == pLumaVirAddr) { + SAMPLE_CRIT_LOG("VdGrp=%d, AX_SYS_Mmap luma FAILED! .u64PhyAddr[0]:0x%llx\n", + VdGrp, frameInfo->stVFrame.u64PhyAddr[0]); + s32Ret = AX_ERR_VDEC_BAD_ADDR; + goto ERR_RET; + } + + SAMPLE_LOG_N("AX_SYS_Mmap luma success, .u64PhyAddr[0]:0x%llx, pLumaVirAddr=%p, lumaMapSize=%d\n", + frameInfo->stVFrame.u64PhyAddr[0], pLumaVirAddr, lumaMapSize); + + p_lu = pLumaVirAddr; + + SAMPLE_LOG_N("p_lu: %p\n", p_lu); + SAMPLE_LOG_N("lu_buss: 0x%llx\n", frameInfo->stVFrame.u64PhyAddr[0]); + SAMPLE_LOG_N("ch_buss: 0x%llx\n", frameInfo->stVFrame.u64PhyAddr[1]); + + AX_U32 coded_width = frameInfo->stVFrame.u32Width; + AX_U32 coded_height = frameInfo->stVFrame.u32Height; + AX_U32 pic_stride = frameInfo->stVFrame.u32PicStride[0]; + AX_U32 coded_width_ch = frameInfo->stVFrame.u32Width; + AX_U32 coded_h_ch = frameInfo->stVFrame.u32Height / 2; + AX_U32 pic_stride_ch = frameInfo->stVFrame.u32PicStride[1]; + AX_U32 pic_format = frameInfo->stVFrame.enImgFormat; + + if (AX_FORMAT_YUV400 != pic_format) { + chromaMapSize = frameInfo->stVFrame.u32PicStride[0] * SIZE_ALIGN(frameInfo->stVFrame.u32Height, 16) / 2; + pChromaVirAddr = AX_SYS_Mmap(frameInfo->stVFrame.u64PhyAddr[1], chromaMapSize); + if (NULL == pChromaVirAddr) { + SAMPLE_CRIT_LOG("VdGrp=%d, AX_SYS_Mmap luma FAILED! .u64PhyAddr[1]:0x%llx\n", + VdGrp, frameInfo->stVFrame.u64PhyAddr[1]); + s32Ret = AX_ERR_VDEC_BAD_ADDR; + goto ERR_RET_MUNMAP_LUMA; + } + + p_ch = pChromaVirAddr; + + SAMPLE_LOG_N("AX_SYS_Mmap chroma success, .u64PhyAddr[1]:0x%llx, pChromaVirAddr=%p, chromaMapSize=%d\n", + frameInfo->stVFrame.u64PhyAddr[1], pChromaVirAddr, chromaMapSize); + SAMPLE_LOG_N("p_ch: %p\n", p_ch); + } + + SAMPLE_LOG_N("p_lu: %p, p_ch: %p, \n", p_lu, p_ch, ); + SAMPLE_LOG_N("coded_width: %u, coded_height: %u, pic_stride: %u, \n" + "coded_width_ch: %u, coded_h_ch: %u, pic_stride_ch: %u, pixel_bytes: %u, pic_format:%d\n", + coded_width, coded_height, pic_stride, + coded_width_ch, coded_h_ch, pic_stride_ch, 1, pic_format); + + SAMPLE_LOG_N("write Y\n"); + if (AX_FORMAT_YUV420_SEMIPLANAR_10BIT_P010 == pic_format) { + coded_width = coded_width * 2; + coded_width_ch = coded_width_ch * 2; + }else if (AX_FORMAT_YUV420_SEMIPLANAR_10BIT_P101010 == pic_format) { + coded_width = coded_width * 10 / 8; + coded_width_ch = coded_width_ch * 10 / 8; + } + + for (i = 0; i < coded_height; i++) { + tmp_size = fwrite(p_lu, 1, coded_width, fp_out); + if (tmp_size != coded_width) { + SAMPLE_CRIT_LOG("VdGrp=%d, fwrite FAILED! tmp_size:0x%x != coded_width:0x%x", + VdGrp, tmp_size, coded_width); + s32Ret = AX_ERR_VDEC_NOMEM; + } + p_lu += pic_stride; + } + + if (AX_FORMAT_YUV400 != pic_format) { + SAMPLE_LOG_N("write UV\n"); + for (i = 0; i < coded_h_ch; i++) { + tmp_size = fwrite(p_ch, 1, coded_width_ch, fp_out); + if (tmp_size != coded_width_ch) { + SAMPLE_CRIT_LOG("VdGrp=%d, fwrite FAILED! tmp_size:0x%x != coded_width_ch:0x%x", + VdGrp, tmp_size, coded_width_ch); + s32Ret = AX_ERR_VDEC_NOMEM; + } + p_ch += pic_stride_ch; + } + } + + ret = fflush(fp_out); + if (ret) { + SAMPLE_CRIT_LOG("VdGrp=%d, fflush FAILED! fp_out:%p", + VdGrp, fp_out); + s32Ret = AX_ERR_VDEC_RUN_ERROR; + } + + SAMPLE_LOG_N("VdGrp=%d, write YUV done! %s\n", VdGrp, pOutputFilePath); + + if (pChromaVirAddr) { + sRet = AX_SYS_Munmap(pChromaVirAddr, chromaMapSize); + if (sRet) { + SAMPLE_CRIT_LOG("VdGrp=%d, AX_SYS_Munmap chroma FAILED, sRet=0x%x\n", + VdGrp, sRet); + } + } + +ERR_RET_MUNMAP_LUMA: + if (pLumaVirAddr) { + sRet = AX_SYS_Munmap(pLumaVirAddr, lumaMapSize); + if (sRet) { + SAMPLE_CRIT_LOG("VdGrp=%d, AX_SYS_Munmap luma FAILED, sRet=0x%x\n", + VdGrp, sRet); + } + } +ERR_RET: + return s32Ret || sRet; +} + +AX_S32 OutputFileSaveYUV(AX_VDEC_GRP VdGrp, const AX_VIDEO_FRAME_INFO_T *frameInfo, FILE *fp_out, AX_CHAR *pOutputFilePath) +{ + AX_S32 s32Ret = 0; + + if (NULL == frameInfo) { + SAMPLE_CRIT_LOG("VdGrp=%d, NULL == frameInfo\n", VdGrp); + return -1; + } + + if (AX_COMPRESS_MODE_NONE != frameInfo->stVFrame.stCompressInfo.enCompressMode) { + SAMPLE_CRIT_LOG("VdGrp=%d, invalid enCompressMode: %d\n", VdGrp, + frameInfo->stVFrame.stCompressInfo.enCompressMode); + return -1; + } + + s32Ret = OutputSaveYUVFile(VdGrp, frameInfo, fp_out, pOutputFilePath); + + return s32Ret; +} + +static off_t __FindFileNextStartCode(const SAMPLE_INPUT_FILE_INFO_T *pstBsInfo, AX_U32 *puZeroCount, AX_U32 *pNalType) +{ + AX_S32 i; + off_t sStart; + off_t oFileStart; + off_t oFileOffset = 0; + AX_U32 uLeftFileSize, uFileReadLen = 0; + AX_CHAR tmp_buf[VDEC_BS_PARSER_BUF_SIZE] = {0}; + AX_U8 byte; + int ret_val; + int ret; + + oFileStart = ftello(pstBsInfo->fInput); + sStart = oFileStart; + *puZeroCount = 0; + + while (1) { + assert(sStart <= pstBsInfo->sFileSize); + + uLeftFileSize = pstBsInfo->sFileSize - sStart; + if (uLeftFileSize == 0) { + oFileOffset = pstBsInfo->sFileSize - 1; + break; + } + + uFileReadLen = VDEC_BS_PARSER_BUF_SIZE < uLeftFileSize ? VDEC_BS_PARSER_BUF_SIZE : uLeftFileSize; + fread(tmp_buf, 1, uFileReadLen, pstBsInfo->fInput); + /* Scan for the beginning of the packet. */ + for (i = 0; i < uFileReadLen; i++) { + ret_val = tmp_buf[i]; + oFileOffset = sStart + i; + if (ret_val == EOF) { + sStart = oFileOffset - 1; + SAMPLE_LOG_N("sStart:%ld, i:%d, oFileOffset:%d, *puZeroCount:%d", + sStart, i, oFileOffset, *puZeroCount); + + ret = fseeko(pstBsInfo->fInput, 0, SEEK_END); + if (ret) { + SAMPLE_CRIT_LOG("fseeko FAILED! ret:0x%x", ret); + sStart = AX_ERR_VDEC_RUN_ERROR; + } + + return sStart; + } + + byte = (unsigned char)ret_val; + switch (byte) { + case 0: + *puZeroCount = *puZeroCount + 1; + break; + case 1: + /* If there's more than three leading zeros, consider only three + * of them to be part of this packet and the rest to be part of + * the previous packet. */ + if (*puZeroCount > 3) { + *puZeroCount = 3; + } + + if (*puZeroCount >= 2) { + SAMPLE_LOG_N("sStart:%ld, i:%d, oFileOffset:%d, *puZeroCount:%d", + sStart, i, oFileOffset, *puZeroCount); + if (i < uFileReadLen - 1) { + ret_val = (tmp_buf[i + 1] & 0x1f); + if (ret_val == 0x1 || ret_val == 0x7 || ret_val == 0x5) { + sStart = oFileOffset - *puZeroCount; + *pNalType = ret_val; + goto FUNC_RET; + } + } + } + *puZeroCount = 0; + break; + default: + *puZeroCount = 0; + break; + } + } + + ret = fseeko(pstBsInfo->fInput, oFileOffset, SEEK_SET); + if (ret) { + SAMPLE_CRIT_LOG("fseeko FAILED! ret:0x%x", ret); + sStart = AX_ERR_VDEC_RUN_ERROR; + } + sStart = oFileOffset + 1; + } + +FUNC_RET: + + ret = fseeko(pstBsInfo->fInput, oFileOffset + 1, SEEK_SET); + if (ret) { + SAMPLE_CRIT_LOG("fseeko FAILED! ret:0x%x", ret); + sStart = AX_ERR_VDEC_RUN_ERROR; + } + SAMPLE_LOG_N("func end, ftello(pstBsInfo->fInput):%d uFileReadLen:%d", + ftello(pstBsInfo->fInput), uFileReadLen); + return sStart; +} + +static int __CheckFileAccessUnitBoundary(const SAMPLE_INPUT_FILE_INFO_T *pstBsInfo, off_t oNalBegin, SAMPLE_BSBOUNDARY_TYPE_E *penBoundary) +{ + int ret = 0; + int iNalType, iVal; + SAMPLE_BSBOUNDARY_TYPE_E enBoundary = BSPARSER_NO_BOUNDARY; + + FILE *fInput = pstBsInfo->fInput; + off_t sStart = ftello(fInput); + + off_t tmp_offset = oNalBegin + 1; + ret = fseeko(fInput, tmp_offset, SEEK_SET); + if (ret) { + SAMPLE_CRIT_LOG("fseeko FAILED! ret:0x%x", ret); + return ret; + } + + AX_PAYLOAD_TYPE_E enDecType = pstBsInfo->enDecType; + + if (enDecType == PT_H264) { + iNalType = (getc(fInput) & 0x1F); + + if (iNalType > NAL_CODED_SLICE_IDR) { + enBoundary = BSPARSER_BOUNDARY_NON_SLICE_NAL; + } else { + iVal = getc(fInput); + /* Check if first mb in slice is 0(ue(v)). */ + if (iVal & 0x80) { + enBoundary = BSPARSER_BOUNDARY; + } + } + } else if (enDecType == PT_H265) { + iNalType = (getc(fInput) & 0x7E) >> 1; + + if (iNalType > NAL_CODED_SLICE_CRA) { + enBoundary = BSPARSER_BOUNDARY_NON_SLICE_NAL; + } else { + iVal = getc(fInput); // nothing interesting here... + iVal = getc(fInput); + /* Check if first slice segment in picture */ + if (iVal & 0x80) { + enBoundary = BSPARSER_BOUNDARY; + } + } + } + + ret = fseeko(fInput, sStart, SEEK_SET); + if (ret) { + SAMPLE_CRIT_LOG("fseeko FAILED! ret:0x%x", ret); + return ret; + } + + *penBoundary = enBoundary; + return 0; +} + + +static AX_S32 __StreamReadFrameInRingBuf(const SAMPLE_INPUT_FILE_INFO_T *pstBsInfo, SAMPLE_STREAM_BUF_T *pstStreamBuf, + size_t oStreamLen, size_t *pReadLen) +{ + off_t oOffset = 0; + AX_U8 *pBufRd = NULL; + AX_U8 *pBufStart = NULL; + AX_U32 uBufSize = 0; + AX_S32 sRet = 0; + AX_U32 sReadLen = 0; + AX_U32 tmp_len = 0, right_len = 0, left_len = 0; + + if (pstBsInfo == NULL) { + SAMPLE_CRIT_LOG("pstBsInfo == NULL\n"); + sRet = AX_ERR_VDEC_NULL_PTR; + goto ERR_RET; + } + + if (pstStreamBuf == NULL) { + SAMPLE_CRIT_LOG("pstStreamBuf == NULL\n"); + sRet = AX_ERR_VDEC_NULL_PTR; + goto ERR_RET; + } + + pBufRd = pstStreamBuf->pBufAfterFill; + pBufStart = pstStreamBuf->tBufAddr.pVirAddr; + uBufSize = pstStreamBuf->uBufSize; + if (pBufStart == NULL) { + SAMPLE_CRIT_LOG("pBufStart == NULL\n"); + sRet = AX_ERR_VDEC_BAD_ADDR; + goto ERR_RET; + } + + if (uBufSize < oStreamLen) { + SAMPLE_CRIT_LOG("uBufSize:0x%x < oStreamLen:0x%x", uBufSize, (AX_U32)oStreamLen); + sRet = AX_ERR_VDEC_NOMEM; + goto ERR_RET; + } + + *pReadLen = 0; + oOffset = (off_t)(pBufRd - pBufStart); + pstStreamBuf->pBufBeforeFill = pstStreamBuf->pBufAfterFill; + if ((oOffset + oStreamLen) < uBufSize) { + sReadLen = fread(pBufRd, 1, oStreamLen, pstBsInfo->fInput); + if (sReadLen != oStreamLen) { + SAMPLE_CRIT_LOG("fread FAILED! sReadLen:0x%x != oStreamLen:0x%x", sReadLen, (AX_U32)oStreamLen); + sRet = AX_ERR_VDEC_RUN_ERROR; + goto ERR_RET; + } + + pstStreamBuf->pBufAfterFill = pBufRd + sReadLen; + } else { + /* turnaround */ + right_len = uBufSize - oOffset; + sReadLen = fread(pBufRd, 1, right_len, pstBsInfo->fInput); + if (sReadLen != uBufSize - oOffset) { + SAMPLE_CRIT_LOG("fread FAILED! sReadLen:0x%x != (uBufSize:0x%x - oOffset:0x%llx):0x%x", + sReadLen, uBufSize, (AX_U64)oOffset, right_len); + sRet = AX_ERR_VDEC_RUN_ERROR; + goto ERR_RET; + } + + left_len = oStreamLen - (uBufSize - oOffset); + tmp_len = fread(pBufStart, 1, left_len, pstBsInfo->fInput); + if (tmp_len != left_len) { + SAMPLE_CRIT_LOG("fread FAILED! tmp_len:0x%x != left_len:0x%x, oStreamLen:0x%x uBufSize:0x%x oOffset:0x%llx", + tmp_len, left_len, (AX_U32)oStreamLen, uBufSize, (AX_U64)oOffset); + sRet = AX_ERR_VDEC_RUN_ERROR; + goto ERR_RET; + } + + sReadLen += tmp_len; + pstStreamBuf->pBufAfterFill = pBufStart + tmp_len; + } + + *pReadLen = sReadLen; +ERR_RET: + return sRet; +} + +AX_S32 StreamFileParserReadFrame(const SAMPLE_INPUT_FILE_INFO_T *pstBsInfo, SAMPLE_STREAM_BUF_T *pstStreamBuf, size_t *pReadLen) +{ + int ret = 0; + AX_S32 sRet = 0; + AX_U32 uZeroCount = 0; + SAMPLE_BSBOUNDARY_TYPE_E enBoundary = BSPARSER_NO_BOUNDARY; + off_t oNalBegin, oStreamLen; + off_t oBegin, oEnd, oTmpEnd; + AX_U32 sReadLen = 0; + AX_U32 uBufSize; + AX_U8 *pBufStart = NULL; + AX_U32 u32NalType = 0; + + if (pstBsInfo == NULL) { + SAMPLE_CRIT_LOG("pstBsInfo == NULL\n"); + sRet = AX_ERR_VDEC_NULL_PTR; + goto ERR_RET; + } + + if (pstStreamBuf == NULL) { + SAMPLE_CRIT_LOG("pstStreamBuf == NULL\n"); + sRet = AX_ERR_VDEC_NULL_PTR; + goto ERR_RET; + } + + if (pstStreamBuf->tBufAddr.pVirAddr == NULL) { + SAMPLE_CRIT_LOG("pstStreamBuf->tBufAddr.pVirAddr == NULL\n"); + sRet = AX_ERR_VDEC_BAD_ADDR; + goto ERR_RET; + } + + if (pReadLen == NULL) { + SAMPLE_CRIT_LOG("pReadLen == NULL\n"); + sRet = AX_ERR_VDEC_NULL_PTR; + goto ERR_RET; + } + + oBegin = __FindFileNextStartCode(pstBsInfo, &uZeroCount, &u32NalType); + + /* Check for non-slice type in current NAL. non slice NALs are + * decoded one-by-one */ + oNalBegin = oBegin + uZeroCount; + ret = __CheckFileAccessUnitBoundary(pstBsInfo, oNalBegin, &enBoundary); + if (ret) { + SAMPLE_CRIT_LOG("__CheckFileAccessUnitBoundary FAILED! ret:0x%x", ret); + sRet = AX_ERR_VDEC_STRM_ERROR; + goto ERR_RET; + } + + if (u32NalType == 0x7) { /* get i frm video nal */ + oNalBegin = __FindFileNextStartCode(pstBsInfo, &uZeroCount, &u32NalType); + + /* Check for non-slice type in current NAL. non slice NALs are + * decoded one-by-one */ + oNalBegin = oNalBegin + uZeroCount; + ret = __CheckFileAccessUnitBoundary(pstBsInfo, oNalBegin, &enBoundary); + if (ret) { + SAMPLE_CRIT_LOG("__CheckFileAccessUnitBoundary FAILED! ret:0x%x", ret); + sRet = AX_ERR_VDEC_STRM_ERROR; + goto ERR_RET; + } + } + + oEnd = oNalBegin = __FindFileNextStartCode(pstBsInfo, &uZeroCount, &u32NalType); + + if (oEnd == oBegin) { + *pReadLen = 0; + return 0; /* End of stream */ + } + + /* if there is more stream and a slice type NAL */ + if (enBoundary != BSPARSER_BOUNDARY_NON_SLICE_NAL) { + while (1) { + oEnd = oNalBegin; + oNalBegin += uZeroCount; + + /* Check access unit boundary for next NAL */ + ret = __CheckFileAccessUnitBoundary(pstBsInfo, oNalBegin, &enBoundary); + if (ret) { + SAMPLE_CRIT_LOG("__CheckFileAccessUnitBoundary FAILED! ret:0x%x", ret); + sRet = AX_ERR_VDEC_STRM_ERROR; + goto ERR_RET; + } + + if (enBoundary == BSPARSER_NO_BOUNDARY) { + oNalBegin = __FindFileNextStartCode(pstBsInfo, &uZeroCount, &u32NalType); + } + else if (enBoundary == BSPARSER_BOUNDARY_NON_SLICE_NAL) { + while (1) { + oNalBegin = __FindFileNextStartCode(pstBsInfo, &uZeroCount, &u32NalType); + oTmpEnd = oNalBegin; + oNalBegin += uZeroCount; + ret = __CheckFileAccessUnitBoundary(pstBsInfo, oNalBegin, &enBoundary); + if (ret) { + SAMPLE_CRIT_LOG("__CheckFileAccessUnitBoundary FAILED! ret:0x%x", ret); + sRet = AX_ERR_VDEC_STRM_ERROR; + goto ERR_RET; + } + + if (enBoundary != BSPARSER_BOUNDARY_NON_SLICE_NAL) { + break; + } + + if (oTmpEnd == oNalBegin) { + break; + } + } + + if (oTmpEnd == oNalBegin) { + break; + } + + if (enBoundary == BSPARSER_NO_BOUNDARY) { + oNalBegin = __FindFileNextStartCode(pstBsInfo, &uZeroCount, &u32NalType); + } + } + + if (enBoundary == BSPARSER_BOUNDARY) { + break; + } + + if (oEnd == oNalBegin) { + break; + } + } + } + + ret = fseeko(pstBsInfo->fInput, oBegin, SEEK_SET); + if (ret) { + SAMPLE_CRIT_LOG("fseeko FAILED! ret:0x%x", ret); + sRet = AX_ERR_VDEC_RUN_ERROR; + goto ERR_RET; + } + + oStreamLen = oEnd - oBegin; + uBufSize = pstStreamBuf->uBufSize; + if (uBufSize < oStreamLen) { + SAMPLE_CRIT_LOG("uBufSize:0x%x < oStreamLen:0x%x. bufSize is not enough, please increase STREAM_BUFFER_MAX_SIZE", + uBufSize, (AX_U32)oStreamLen); + sRet = AX_ERR_VDEC_NOMEM; + goto ERR_RET; + } + + pBufStart = pstStreamBuf->tBufAddr.pVirAddr; + + sReadLen = fread(pBufStart, 1, oStreamLen, pstBsInfo->fInput); + if (sReadLen != oStreamLen) { + SAMPLE_CRIT_LOG("fread FAILED! sReadLen:0x%x != oStreamLen:0x%x", sReadLen, (AX_U32)oStreamLen); + sRet = AX_ERR_VDEC_RUN_ERROR; + goto ERR_RET; + } + + pstStreamBuf->pBufBeforeFill = pBufStart; + pstStreamBuf->pBufAfterFill = pBufStart + sReadLen; + + SAMPLE_LOG("sReadLen:0x%lx, uBufSize:0x%x", sReadLen, uBufSize); + *pReadLen = sReadLen; + return 0; +ERR_RET: + return sRet; +} + +static AX_U8 imgGetBytes(FILE *fInput, size_t pos) +{ + AX_U8 data = 0; + AX_U8 readLen = 0; + + fseeko(fInput, pos, SEEK_SET); + readLen = fread(&data, 1, 1, fInput); + if(1 != readLen) + SAMPLE_CRIT_LOG(" read file failed\n"); + + return data; +} + +AX_S32 StreamParserReadFrameJpeg(SAMPLE_INPUT_FILE_INFO_T *pstBsInfo, SAMPLE_STREAM_BUF_T *pstStreamBuf, size_t *pReadLen) +{ + size_t i,j; + AX_U32 jpeg_thumb_in_stream = 0; + AX_U64 tmp, tmp1, tmp_total = 0; + size_t curPos = 0; + AX_U32 imgLen = 0; + AX_S32 s32Ret = 0; + size_t stream_length = 0; + AX_U8 *pBufStart = NULL; + size_t sReadLen = 0; + + pBufStart = pstStreamBuf->tBufAddr.pVirAddr; + if (pBufStart == NULL) { + SAMPLE_CRIT_LOG("pBufStart == NULL\n"); + return -1; + } + + stream_length = pstBsInfo->sFileSize; + for (i = pstBsInfo->curPos; i < stream_length; ++i) { + if (0xFF == imgGetBytes(pstBsInfo->fInput, i)) { + /* if 0xFFE1 to 0xFFFD ==> skip */ + if ((((i + 1) < stream_length) && + 0xE1 == imgGetBytes(pstBsInfo->fInput, i + 1)) || + (((i + 1) < stream_length) && + 0xE2 == imgGetBytes(pstBsInfo->fInput, i + 1)) || + (((i + 1) < stream_length) && + 0xE3 == imgGetBytes(pstBsInfo->fInput, i + 1)) || + (((i + 1) < stream_length) && + 0xE4 == imgGetBytes(pstBsInfo->fInput, i + 1)) || + (((i + 1) < stream_length) && + 0xE5 == imgGetBytes(pstBsInfo->fInput, i + 1)) || + (((i + 1) < stream_length) && + 0xE6 == imgGetBytes(pstBsInfo->fInput, i + 1)) || + (((i + 1) < stream_length) && + 0xE7 == imgGetBytes(pstBsInfo->fInput, i + 1)) || + (((i + 1) < stream_length) && + 0xE8 == imgGetBytes(pstBsInfo->fInput, i + 1)) || + (((i + 1) < stream_length) && + 0xE9 == imgGetBytes(pstBsInfo->fInput, i + 1)) || + (((i + 1) < stream_length) && + 0xEA == imgGetBytes(pstBsInfo->fInput, i + 1)) || + (((i + 1) < stream_length) && + 0xEB == imgGetBytes(pstBsInfo->fInput, i + 1)) || + (((i + 1) < stream_length) && + 0xEC == imgGetBytes(pstBsInfo->fInput, i + 1)) || + (((i + 1) < stream_length) && + 0xED == imgGetBytes(pstBsInfo->fInput, i + 1)) || + (((i + 1) < stream_length) && + 0xEE == imgGetBytes(pstBsInfo->fInput, i + 1)) || + (((i + 1) < stream_length) && + 0xEF == imgGetBytes(pstBsInfo->fInput, i + 1))) { + /* increase counter */ + i += 2; + + /* check length vs. data */ + if ((i + 1) > (stream_length)) { + s32Ret = AX_ERR_VDEC_STRM_ERROR; + goto ret; + } + + /* get length */ + tmp = imgGetBytes(pstBsInfo->fInput, i); + tmp1 = imgGetBytes(pstBsInfo->fInput, i + 1); + tmp_total = (tmp << 8) | tmp1; + + /* check length vs. data */ + if ((tmp_total + i) > (stream_length)) { + s32Ret = AX_ERR_VDEC_STRM_ERROR; + goto ret; + } + /* update */ + i += tmp_total-1; + continue; + } + + /* if 0xFFC2 to 0xFFCB ==> skip */ + if ((((i + 1) < stream_length) && + 0xC1 == imgGetBytes(pstBsInfo->fInput, i + 1)) || + (((i + 1) < stream_length) && + 0xC2 == imgGetBytes(pstBsInfo->fInput, i + 1)) || + (((i + 1) < stream_length) && + 0xC3 == imgGetBytes(pstBsInfo->fInput, i + 1)) || + (((i + 1) < stream_length) && + 0xC5 == imgGetBytes(pstBsInfo->fInput, i + 1)) || + (((i + 1) < stream_length) && + 0xC6 == imgGetBytes(pstBsInfo->fInput, i + 1)) || + (((i + 1) < stream_length) && + 0xC7 == imgGetBytes(pstBsInfo->fInput, i + 1)) || + (((i + 1) < stream_length) && + 0xC8 == imgGetBytes(pstBsInfo->fInput, i + 1)) || + (((i + 1) < stream_length) && + 0xC9 == imgGetBytes(pstBsInfo->fInput, i + 1)) || + (((i + 1) < stream_length) && + 0xCA == imgGetBytes(pstBsInfo->fInput, i + 1)) || + (((i + 1) < stream_length) && + 0xCB == imgGetBytes(pstBsInfo->fInput, i + 1)) ) { + /* increase counter */ + i += 2; + + /* check length vs. data */ + if ((i + 1) > (stream_length)) { + s32Ret = AX_ERR_VDEC_STRM_ERROR; + goto ret; + } + + /* get length */ + tmp = imgGetBytes(pstBsInfo->fInput, i); + tmp1 = imgGetBytes(pstBsInfo->fInput, i + 1); + tmp_total = (tmp << 8) | tmp1; + + /* check length vs. data */ + if ((tmp_total + i) > (stream_length)) { + s32Ret = AX_ERR_VDEC_STRM_ERROR; + goto ret; + } + /* update */ + i += tmp_total-1; + + /* look for EOI */ + for(j = i; j < stream_length; ++j) { + if (0xFF == imgGetBytes(pstBsInfo->fInput, j)) { + /* EOI */ + if (((j + 1) < stream_length) && + 0xD9 == imgGetBytes(pstBsInfo->fInput, j + 1)) { + /* check length vs. data */ + if ((j + 2) >= (stream_length)) { + curPos = j + 2; + s32Ret = 0; + goto ret; + } + /* update */ + i = j; + /* stil data left ==> continue */ + continue; + } + } + } + } + + /* check if thumbnails in stream */ + if (((i + 1) < stream_length) && + 0xE0 == imgGetBytes(pstBsInfo->fInput, i + 1)) { + if (((i + 9) < stream_length) && + 0x4A == imgGetBytes(pstBsInfo->fInput, i + 4) && + 0x46 == imgGetBytes(pstBsInfo->fInput, i + 5) && + 0x58 == imgGetBytes(pstBsInfo->fInput, i + 6) && + 0x58 == imgGetBytes(pstBsInfo->fInput, i + 7) && + 0x00 == imgGetBytes(pstBsInfo->fInput, i + 8) && + 0x10 == imgGetBytes(pstBsInfo->fInput, i + 9)) { + jpeg_thumb_in_stream = 1; + } + } + + /* EOI */ + if (((i + 1) < stream_length) && + 0xD9 == imgGetBytes(pstBsInfo->fInput, i + 1)) { + curPos = i + 2; + /* update amount of thumbnail or full resolution image */ + if (jpeg_thumb_in_stream) { + jpeg_thumb_in_stream = 0; + } else { + s32Ret = 0; + goto ret; + } + } + } + } + +ret: + imgLen = curPos > pstBsInfo->curPos ? curPos - pstBsInfo->curPos : 0; + if(0 == s32Ret) { + fseeko(pstBsInfo->fInput, pstBsInfo->curPos, SEEK_SET); + if (pstStreamBuf->bRingbuf == AX_TRUE) { + s32Ret = __StreamReadFrameInRingBuf(pstBsInfo, pstStreamBuf, imgLen, &sReadLen); + if (s32Ret) { + SAMPLE_CRIT_LOG("__StreamReadFrameInRingBuf FAILED! ret:0x%x", s32Ret); + return -1; + } + } else { + if (imgLen > pstStreamBuf->uBufSize) { + SAMPLE_CRIT_LOG("bufSize is not enough(imgLen %d > bufSize %d), please increase STREAM_BUFFER_MAX_SIZE", + imgLen, pstStreamBuf->uBufSize); + return -1; + } + sReadLen = fread(pBufStart, 1, imgLen, pstBsInfo->fInput); + if (sReadLen != imgLen) { + SAMPLE_CRIT_LOG("fread FAILED! sReadLen:0x%x != imgLen:0x%x", (AX_U32)sReadLen, imgLen); + return -1; + } + + pstStreamBuf->pBufBeforeFill = pBufStart; + pstStreamBuf->pBufAfterFill = pBufStart + sReadLen; + } + pstBsInfo->curPos += sReadLen; + } + + *pReadLen = imgLen; + return s32Ret; +} + +static AX_S32 __VdecUsrPicRead(FILE *pFileIn, AX_VIDEO_FRAME_T *pstFrame) +{ + AX_S32 sRet = 0; + AX_U32 i = 0, rows = 0, realRead = 0; + AX_S32 widthSrc = 0, strideSrc = 0, heightSrc = 0; + AX_IMG_FORMAT_E eFmt; + AX_VOID *pVaddr = NULL; + + if (pFileIn == NULL) { + SAMPLE_CRIT_LOG("pFileIn == NULL\n"); + sRet = AX_ERR_VDEC_NULL_PTR; + goto ERR_RET; + } + + if (pstFrame == NULL) { + SAMPLE_CRIT_LOG("pstFrame == NULL\n"); + sRet = AX_ERR_VDEC_NULL_PTR; + goto ERR_RET; + } + + widthSrc = pstFrame->u32Width; + heightSrc = pstFrame->u32Height; + strideSrc = pstFrame->u32PicStride[0]; + eFmt = pstFrame->enImgFormat; + pVaddr = (AX_VOID *)(AX_ULONG)pstFrame->u64VirAddr[0]; + switch (eFmt) { + case AX_FORMAT_YUV420_SEMIPLANAR: + case AX_FORMAT_YUV420_SEMIPLANAR_VU: + rows = heightSrc * 3 / 2; + for (i = 0; i < rows; i++) { + realRead = fread(pVaddr, 1, widthSrc, pFileIn); + if (realRead < widthSrc) { + SAMPLE_CRIT_LOG("fread failed! line %d realRead=%d < widthSrc=%d\n", i, realRead, widthSrc); + sRet = AX_ERR_VDEC_STRM_ERROR; + goto ERR_RET; + } + pVaddr += strideSrc; + } + break; + default: + SAMPLE_CRIT_LOG("Invalid format, eFmt = %d\n", eFmt); + } + +ERR_RET: + return sRet; +} + +static AX_S32 __VdecUsrPicInfoFill(SAMPLE_VDEC_USRPIC_ARGS_T *pstUsrPicArgs, SAMPLE_VDEC_USERPIC_T *pstVdecUserPic) +{ + AX_POOL_CONFIG_T stPoolConfig; + AX_U32 FrameSize = 0; + AX_BLK blkId = AX_INVALID_BLOCKID; + AX_VDEC_USRPIC_T *pstUserPic = NULL; + FILE *fpUserYUV = NULL; + AX_S32 sRet = 0; + AX_S32 ret = 0; + AX_VDEC_GRP VdGrp = 0; + AX_U32 uWidth = 0; + AX_U32 u32FrameStride = 0; + + if (pstUsrPicArgs == NULL) { + SAMPLE_CRIT_LOG("pstUsrPicArgs == NULL\n"); + sRet = AX_ERR_VDEC_NULL_PTR; + goto ERR_RET; + } + + VdGrp = pstUsrPicArgs->VdGrp; + SAMPLE_LOG("VdGrp=%d begin\n", VdGrp); + + memset(&stPoolConfig, 0x0, sizeof(AX_POOL_CONFIG_T)); + + if (pstUsrPicArgs->tPicParam.bUserPicEnable) { + if ((AX_FORMAT_YUV420_SEMIPLANAR != pstUsrPicArgs->tPicParam.enImgFormat) && + (AX_FORMAT_YUV420_SEMIPLANAR_VU != pstUsrPicArgs->tPicParam.enImgFormat)) { + SAMPLE_CRIT_LOG("VdGrp=%d, unsupport enImgFormat:%d\n", + VdGrp, pstUsrPicArgs->tPicParam.enImgFormat); + sRet = AX_ERR_VDEC_NOT_SUPPORT; + goto ERR_RET; + } + uWidth = pstUsrPicArgs->tPicParam.u32PicWidth; + u32FrameStride = AX_COMM_ALIGN(uWidth, AX_VDEC_WIDTH_ALIGN); + pstVdecUserPic->pUsrPicFilePath = pstUsrPicArgs->tPicParam.pUsrPicFilePath; + FrameSize = AX_VDEC_GetPicBufferSize(u32FrameStride, + pstUsrPicArgs->tPicParam.u32PicHeight, + pstUsrPicArgs->enDecType); + + stPoolConfig.MetaSize = 512; + stPoolConfig.BlkCnt = 1; + + stPoolConfig.BlkSize = FrameSize; + stPoolConfig.CacheMode = AX_POOL_CACHE_MODE_NONCACHE; + snprintf((AX_CHAR *)stPoolConfig.PartitionName, AX_MAX_PARTITION_NAME_LEN, "anonymous"); + pstVdecUserPic->PoolId = AX_POOL_CreatePool(&stPoolConfig); + if (AX_INVALID_POOLID == pstVdecUserPic->PoolId) { + SAMPLE_CRIT_LOG("VdGrp=%d, AX_POOL_CreatePool FAILED! BlkCnt:%d, BlkSize:0x%llx\n", + VdGrp, stPoolConfig.BlkCnt, stPoolConfig.BlkSize); + sRet = AX_ERR_VDEC_NOBUF; + goto ERR_RET_DESTROY; + } + + blkId = AX_POOL_GetBlock(pstVdecUserPic->PoolId, FrameSize, NULL); + if (AX_INVALID_BLOCKID == blkId) { + SAMPLE_CRIT_LOG("VdGrp=%d, AX_POOL_GetBlock FAILED! PoolId:%d, BlkSize:0x%llx\n", + VdGrp, pstVdecUserPic->PoolId, stPoolConfig.BlkSize); + sRet = AX_ERR_VDEC_NOBUF; + goto ERR_RET_DESTROY; + } + + pstVdecUserPic->BlkId = blkId; + pstUserPic = &pstVdecUserPic->stUserPic; + pstUserPic->bEnable = AX_TRUE; + pstUserPic->bInstant = pstUsrPicArgs->bUsrInstant; + pstUserPic->stFrmInfo.bEndOfStream = AX_TRUE; + pstUserPic->stFrmInfo.enModId = AX_ID_VDEC; + pstUserPic->stFrmInfo.stVFrame.u32BlkId[0] = blkId; + pstUserPic->stFrmInfo.stVFrame.u32FrameSize = FrameSize; + pstUserPic->stFrmInfo.stVFrame.u32Width = pstUsrPicArgs->tPicParam.u32PicWidth; + pstUserPic->stFrmInfo.stVFrame.u32Height = pstUsrPicArgs->tPicParam.u32PicHeight; + pstUserPic->stFrmInfo.stVFrame.enImgFormat = pstUsrPicArgs->tPicParam.enImgFormat; + pstUserPic->stFrmInfo.stVFrame.enVscanFormat = AX_VSCAN_FORMAT_RASTER; + pstUserPic->stFrmInfo.stVFrame.stCompressInfo.enCompressMode = AX_COMPRESS_MODE_NONE; + pstUserPic->stFrmInfo.stVFrame.u64PhyAddr[0] = AX_POOL_Handle2PhysAddr(blkId); + pstUserPic->stFrmInfo.stVFrame.u64VirAddr[0] = (AX_ULONG)AX_POOL_GetBlockVirAddr(blkId); + pstUserPic->stFrmInfo.stVFrame.u32PicStride[0] = u32FrameStride; + pstUserPic->stFrmInfo.stVFrame.u32PicStride[1] = u32FrameStride; + pstUserPic->stFrmInfo.stVFrame.u64PhyAddr[1] = pstUserPic->stFrmInfo.stVFrame.u64PhyAddr[0] + + pstUserPic->stFrmInfo.stVFrame.u32PicStride[0] * + pstUserPic->stFrmInfo.stVFrame.u32Height; + pstUserPic->stFrmInfo.stVFrame.u64PhyAddr[2] = 0; + pstUserPic->stFrmInfo.stVFrame.u64VirAddr[1] = pstUserPic->stFrmInfo.stVFrame.u64VirAddr[0] + + pstUserPic->stFrmInfo.stVFrame.u32PicStride[0] * + pstUserPic->stFrmInfo.stVFrame.u32Height; + pstUserPic->stFrmInfo.stVFrame.u64VirAddr[2] = 0; + pstUserPic->stFrmInfo.stVFrame.u64PTS = 0; + } + + if (pstUsrPicArgs->tPicParam.enImgFormat) { + uWidth = pstUserPic->stFrmInfo.stVFrame.u32Width; + pstVdecUserPic->fpUsrPic = fopen(pstVdecUserPic->pUsrPicFilePath,"rb"); + if (pstVdecUserPic->fpUsrPic == NULL) { + SAMPLE_CRIT_LOG("VdGrp=%d, can't open file %s in VDEC_PREPARE_USERPIC.\n", + VdGrp, pstVdecUserPic->pUsrPicFilePath); + sRet = AX_ERR_VDEC_RUN_ERROR; + goto ERR_RET_FREE; + } + + fpUserYUV = pstVdecUserPic->fpUsrPic; + + sRet = __VdecUsrPicRead(fpUserYUV, &pstUserPic->stFrmInfo.stVFrame); + if (sRet) { + SAMPLE_CRIT_LOG("__VdecUsrPicRead FAILED! ret:%d\n", sRet); + goto ERR_RET_FREE; + } + + sRet = fclose(fpUserYUV); + if (sRet) { + SAMPLE_CRIT_LOG("fclose FAILED! ret:%d\n", sRet); + sRet = AX_ERR_VDEC_RUN_ERROR; + goto ERR_RET_FREE; + } + + fpUserYUV = NULL; + SAMPLE_LOG("VdGrp=%d, .u64PhyAddr[0]:%llx .u64VirAddr[0]:%llx .u64PhyAddr[1]:%llx .u64VirAddr[1]:%llx\n", + VdGrp, + pstUserPic->stFrmInfo.stVFrame.u64PhyAddr[0], + pstUserPic->stFrmInfo.stVFrame.u64VirAddr[0], + pstUserPic->stFrmInfo.stVFrame.u64PhyAddr[1], + pstUserPic->stFrmInfo.stVFrame.u64VirAddr[1]); + } + + return AX_SUCCESS; + +ERR_RET_FREE: + if (fpUserYUV) { + fclose(fpUserYUV); + fpUserYUV = NULL; + } + +ERR_RET_DESTROY: + if (pstUsrPicArgs->tPicParam.bUserPicEnable) { + if (pstVdecUserPic->BlkId != AX_INVALID_BLOCKID) { + ret = AX_POOL_ReleaseBlock(pstVdecUserPic->BlkId); + if (ret) + SAMPLE_CRIT_LOG("VdGrp=%d, PoolI:%d, AX_POOL_ReleaseBlock FAILED! ret:0x%x %s", + VdGrp, pstVdecUserPic->BlkId, ret, SampleVdecRetStr(ret)); + } + if (pstVdecUserPic->PoolId != AX_INVALID_POOLID) { + ret = AX_POOL_DestroyPool(pstVdecUserPic->PoolId); + if (ret) + SAMPLE_CRIT_LOG("VdGrp=%d, PoolId:%d, AX_POOL_DestroyPool FAILED! ret:0x%x %s", + VdGrp, pstVdecUserPic->PoolId, ret, SampleVdecRetStr(ret)); + } + } + +ERR_RET: + return sRet; +} + +AX_S32 __VdecUsrPicCreat(SAMPLE_VDEC_USRPIC_ARGS_T *pstUsrPicArgs, SAMPLE_VDEC_USERPIC_T *pstVdecUserPic) +{ + AX_S32 s32Ret = AX_SUCCESS; + AX_VDEC_GRP VdGrp = 0; + + if (pstVdecUserPic == NULL) { + SAMPLE_CRIT_LOG("null pointer\n"); + s32Ret = AX_ERR_VDEC_NULL_PTR; + goto ERR_RET; + } + + if (pstUsrPicArgs == NULL) { + SAMPLE_CRIT_LOG("pstUsrPicArgs == NULL\n"); + s32Ret = AX_ERR_VDEC_NULL_PTR; + goto ERR_RET; + } + + VdGrp = pstUsrPicArgs->VdGrp; + SAMPLE_LOG("VdGrp=%d begin\n", VdGrp); + + if (pstUsrPicArgs->tPicParam.bUserPicEnable == AX_FALSE) { + pstVdecUserPic->PoolId = AX_INVALID_POOLID; + goto ERR_RET; + } + + s32Ret = __VdecUsrPicInfoFill(pstUsrPicArgs, pstVdecUserPic); + if (s32Ret != AX_SUCCESS) { + SAMPLE_CRIT_LOG("VdGrp=%d, __VdecUsrPicInfoFill FAILED!\n",VdGrp); + goto ERR_RET; + } + + s32Ret = AX_VDEC_DisableUserPic(VdGrp); + if (s32Ret != AX_SUCCESS) { + SAMPLE_CRIT_LOG("VdGrp=%d, AX_VDEC_DisableUserPic FAILED! ret:0x%x %s\n", + VdGrp, s32Ret, SampleVdecRetStr(s32Ret)); + goto ERR_RET; + } + + s32Ret = AX_VDEC_SetUserPic(VdGrp, &pstVdecUserPic->stUserPic); + if (s32Ret != AX_SUCCESS) { + SAMPLE_CRIT_LOG("VdGrp=%d, AX_VDEC_SetUserPic FAILED! ret:0x%x %s\n", + VdGrp, s32Ret, SampleVdecRetStr(s32Ret)); + goto ERR_RET; + } + +ERR_RET: + return s32Ret; +} + +AX_S32 VdecUserPicEnable(AX_VDEC_GRP VdGrp, SAMPLE_VDEC_USERPIC_T *pstVdecUserPic, + AX_BOOL *pContSendStm, SAMPLE_VDEC_CONTEXT_T *pstCtx) +{ + AX_S32 sRet = AX_SUCCESS; + AX_VDEC_RECV_PIC_PARAM_T tRecvParam; + + if (pstVdecUserPic->stUserPic.bEnable) { + sRet = AX_VDEC_StopRecvStream(VdGrp); + if (sRet) { + SAMPLE_CRIT_LOG("VdGrp=%d, AX_VDEC_StopRecvStream FAILED! ret:0x%x %s\n", + VdGrp, sRet, SampleVdecRetStr(sRet)); + goto ERR_RET; + } else { + pstCtx->GrpStatus[VdGrp] = AX_VDEC_GRP_STOP_RECV; + } + + if (!pstVdecUserPic->stUserPic.bInstant) + sleep(1); + + sRet = AX_VDEC_EnableUserPic(VdGrp); + if (sRet) { + SAMPLE_CRIT_LOG("VdGrp=%d, AX_VDEC_EnableUserPic FAILED! ret:0x%x %s\n", + VdGrp, sRet, SampleVdecRetStr(sRet)); + goto ERR_RET; + } + + if (pstVdecUserPic->recvStmAfUsrPic) { + *pContSendStm = AX_TRUE; + } else { + *pContSendStm = AX_FALSE; + } + + SAMPLE_LOG("VdGrp=%d, AX_VDEC_EnableUserPic finish!\n", VdGrp); + + memset(&tRecvParam, 0, sizeof(tRecvParam)); + tRecvParam.s32RecvPicNum = pstVdecUserPic->s32RecvPicNumBak; + sRet = AX_VDEC_StartRecvStream(VdGrp, &tRecvParam); + if (sRet) { + SAMPLE_CRIT_LOG("VdGrp=%d, AX_VDEC_StartRecvStream FAILED! ret:0x%x %s\n", + VdGrp, sRet, SampleVdecRetStr(sRet)); + goto ERR_RET; + } else { + pstCtx->GrpStatus[VdGrp] = AX_VDEC_GRP_START_RECV; + } + } + +ERR_RET: + return sRet; +} + +AX_VOID VdecUserPicDestroy(AX_VDEC_GRP VdGrp, SAMPLE_VDEC_USERPIC_T *pstVdecUserPic) +{ + AX_S32 ret = AX_SUCCESS; + + if (pstVdecUserPic->stUserPic.bEnable) { + if (pstVdecUserPic->BlkId != AX_INVALID_BLOCKID) { + ret = AX_POOL_ReleaseBlock(pstVdecUserPic->BlkId); + if (ret) + SAMPLE_CRIT_LOG("VdGrp=%d, BlkId:%d, AX_POOL_ReleaseBlock FAILED! ret:0x%x %s", + VdGrp, pstVdecUserPic->BlkId, ret, SampleVdecRetStr(ret)); + } + if (pstVdecUserPic->PoolId != AX_INVALID_POOLID) { + ret = AX_POOL_DestroyPool(pstVdecUserPic->PoolId); + if (ret) + SAMPLE_CRIT_LOG("VdGrp=%d, PoolId:%d, AX_POOL_DestroyPool FAILED! ret:0x%x %s", + VdGrp, pstVdecUserPic->PoolId, ret, SampleVdecRetStr(ret)); + } + } + + if (pstVdecUserPic->stUserPic.bEnable) { + ret = AX_VDEC_DisableUserPic(VdGrp); + if (ret) + SAMPLE_CRIT_LOG("VdGrp=%d, AX_VDEC_DisableUserPic FAILED! ret:0x%x %s", + VdGrp, ret, SampleVdecRetStr(ret)); + } +} + + +int VdecCommonPoolPrintf(AX_VOID) +{ + return 0; + AX_S32 s32Ret = 0; + AX_POOL_FLOORPLAN_T PoolFloorPlan; + + memset(&PoolFloorPlan, 0, sizeof(AX_POOL_FLOORPLAN_T)); + + s32Ret = AX_POOL_GetConfig(&PoolFloorPlan); + if (s32Ret) { + SAMPLE_CRIT_LOG("AX_POOL_SetConfig FAILED! 0x%x\n", s32Ret); + goto ERR_RET; + } + + for (int pi = 0; pi < AX_MAX_COMM_POOLS; pi++) { + SAMPLE_LOG("PoolFloorPlan.CommPool[%d].MetaSize:0x%llx", pi, PoolFloorPlan.CommPool[pi].MetaSize); + SAMPLE_LOG("PoolFloorPlan.CommPool[%d].BlkSize:0x%llx", pi, PoolFloorPlan.CommPool[pi].BlkSize); + SAMPLE_LOG("PoolFloorPlan.CommPool[%d].BlkCnt:0x%x", pi, PoolFloorPlan.CommPool[pi].BlkCnt); + SAMPLE_LOG("PoolFloorPlan.CommPool[%d].IsMergeMode:0x%x", pi, PoolFloorPlan.CommPool[pi].IsMergeMode); + SAMPLE_LOG("PoolFloorPlan.CommPool[%d].CacheMode:0x%x", pi, PoolFloorPlan.CommPool[pi].CacheMode); + SAMPLE_LOG("PoolFloorPlan.CommPool[%d].PartitionName:%s", pi, PoolFloorPlan.CommPool[pi].PartitionName); + } + +ERR_RET: + return s32Ret; +} + +#ifdef AX_VDEC_FFMPEG_ENABLE +AX_S32 SampleVdecFfmpegDeinit(SAMPLE_FFMPEG_T *pstFfmpeg, AX_VDEC_GRP VdGrp) +{ + AX_S32 s32Ret = AX_SUCCESS; + + SAMPLE_LOG("stream %d +++", VdGrp); + + if (pstFfmpeg == NULL) { + SAMPLE_CRIT_LOG("pstFfmpeg == NULL"); + s32Ret = AX_ERR_VDEC_NULL_PTR; + goto ERR_RET; + } + + if (pstFfmpeg->pstAvPkt) { + // av_packet_unref(pstFfmpeg->pstAvPkt); + av_packet_free(&pstFfmpeg->pstAvPkt); + pstFfmpeg->pstAvPkt = NULL; + } + + if (pstFfmpeg->pstAvBSFCtx) { + av_bsf_free(&pstFfmpeg->pstAvBSFCtx); + pstFfmpeg->pstAvBSFCtx = NULL; + } + + if (pstFfmpeg->pstAvFmtCtx) { + avformat_close_input(&pstFfmpeg->pstAvFmtCtx); + pstFfmpeg->pstAvFmtCtx = NULL; + } + + SAMPLE_LOG("stream %d ---", VdGrp); + +ERR_RET: + return s32Ret; +} + +AX_S32 SampleVdecFfmpegInit(SAMPLE_FFMPEG_T *pstFfmpeg, const AX_CHAR *pcInputFilePath, + SAMPLE_BITSTREAM_INFO_T *pstBitStreamInfo) +{ + AX_S32 s32Ret = AX_SUCCESS; + int ret; + enum AVCodecID eCodecID = AV_CODEC_ID_H264; + AX_VDEC_GRP VdGrp = 0; + + if (pstFfmpeg == NULL) { + SAMPLE_CRIT_LOG("pstFfmpeg == NULL"); + s32Ret = AX_ERR_VDEC_NULL_PTR; + goto ERR_RET; + } + + if (pcInputFilePath == NULL) { + SAMPLE_CRIT_LOG("pcInputFilePath == NULL"); + s32Ret = AX_ERR_VDEC_NULL_PTR; + goto ERR_RET; + } + + if (pstBitStreamInfo == NULL) { + SAMPLE_CRIT_LOG("pstBitStreamInfo == NULL"); + s32Ret = AX_ERR_VDEC_NULL_PTR; + goto ERR_RET; + } + + VdGrp = pstBitStreamInfo->VdGrp; + + pstFfmpeg->s32VideoIndex = -1; + pstFfmpeg->pstAvFmtCtx = avformat_alloc_context(); + if (pstFfmpeg->pstAvFmtCtx == NULL) { + SAMPLE_CRIT_LOG("avformat_alloc_context() failed!"); + s32Ret = AX_ERR_VDEC_RUN_ERROR; + goto ERR_RET; + } + + ret = avformat_open_input(&pstFfmpeg->pstAvFmtCtx, pcInputFilePath, NULL, NULL); + if (ret < 0) { + AX_CHAR szError[64] = {0}; + av_strerror(ret, szError, 64); + SAMPLE_CRIT_LOG("open %s fail, error: %d, %s", pcInputFilePath, ret, szError); + goto ERR_RET; + } + + ret = avformat_find_stream_info(pstFfmpeg->pstAvFmtCtx, NULL); + if (ret < 0) { + SAMPLE_CRIT_LOG("avformat_find_stream_info fail, error = %d", ret); + goto ERR_RET; + } + + for (int i = 0; i < pstFfmpeg->pstAvFmtCtx->nb_streams; i++) { + if (AVMEDIA_TYPE_VIDEO == pstFfmpeg->pstAvFmtCtx->streams[i]->codecpar->codec_type) { + pstFfmpeg->s32VideoIndex = i; + break; + } + } + + if (-1 == pstFfmpeg->s32VideoIndex) { + SAMPLE_CRIT_LOG("%s has no video stream!", pcInputFilePath); + goto ERR_RET; + } else { + AVStream *pAvs = pstFfmpeg->pstAvFmtCtx->streams[pstFfmpeg->s32VideoIndex]; + eCodecID = pAvs->codecpar->codec_id; + switch (eCodecID) { + case AV_CODEC_ID_H264: + pstBitStreamInfo->eVideoType = PT_H264; + break; + case AV_CODEC_ID_HEVC: + pstBitStreamInfo->eVideoType = PT_H265; + break; + default: + SAMPLE_CRIT_LOG("Current Only support H264 or HEVC stream %d!", VdGrp); + goto ERR_RET; + } + + pstBitStreamInfo->nWidth = pAvs->codecpar->width; + pstBitStreamInfo->nHeight = pAvs->codecpar->height; + pstBitStreamInfo->nFps = av_q2d(pAvs->r_frame_rate); + if (0 == pstBitStreamInfo->nFps) { + pstBitStreamInfo->nFps = 30; + SAMPLE_LOG("stream %d fps is 0, set to %d fps", VdGrp, pstBitStreamInfo->nFps); + } + + SAMPLE_LOG("stream %d: vcodec %d, %dx%d, fps %d", + VdGrp, pstBitStreamInfo->eVideoType, pstBitStreamInfo->nWidth, pstBitStreamInfo->nHeight, + pstBitStreamInfo->nFps); + } + + pstFfmpeg->pstAvPkt = av_packet_alloc(); + if (!pstFfmpeg->pstAvPkt) { + SAMPLE_CRIT_LOG("Create packet(stream %d) fail!", VdGrp); + goto ERR_RET; + } + + if ((AV_CODEC_ID_H264 == eCodecID) || (AV_CODEC_ID_HEVC == eCodecID)) { + const AVBitStreamFilter *pstBSFilter = av_bsf_get_by_name((AV_CODEC_ID_H264 == eCodecID) ? + "h264_mp4toannexb" : "hevc_mp4toannexb"); + if (!pstBSFilter) { + SAMPLE_CRIT_LOG("av_bsf_get_by_name(stream %d) fail!", VdGrp); + goto ERR_RET; + } + + ret = av_bsf_alloc(pstBSFilter, &pstFfmpeg->pstAvBSFCtx); + if (ret < 0) { + SAMPLE_CRIT_LOG("av_bsf_alloc(stream %d) fail, error:%d", VdGrp, ret); + goto ERR_RET; + } + + ret = avcodec_parameters_copy(pstFfmpeg->pstAvBSFCtx->par_in, + pstFfmpeg->pstAvFmtCtx->streams[pstFfmpeg->s32VideoIndex]->codecpar); + if (ret < 0) { + SAMPLE_CRIT_LOG("avcodec_parameters_copy(stream %d) fail, error:%d", VdGrp, ret); + goto ERR_RET; + } else { + pstFfmpeg->pstAvBSFCtx->time_base_in = pstFfmpeg->pstAvFmtCtx->streams[pstFfmpeg->s32VideoIndex]->time_base; + } + + ret = av_bsf_init(pstFfmpeg->pstAvBSFCtx); + if (ret < 0) { + SAMPLE_CRIT_LOG("av_bsf_init(stream %d) fail, error:%d", VdGrp, ret); + goto ERR_RET; + } + } + + return s32Ret; + +ERR_RET: + SampleVdecFfmpegDeinit(pstFfmpeg, VdGrp); + return s32Ret; +} + +AX_S32 SampleVdecFfmpegExtractOnePic(SAMPLE_FFMPEG_T *pstFfmpeg, SAMPLE_BITSTREAM_INFO_T *pstBitStreamInfo, + SAMPLE_STREAM_BUF_T *pstStreamBuf, size_t *pReadLen) +{ + AX_S32 s32Ret = AX_SUCCESS; + int ret; + AVFormatContext *pstAvFmtCtx = NULL; + AVBSFContext *pstAvBSFCtx = NULL; + AVPacket *pstAvPkt = NULL; + static AX_U64 u64FrameCnt = 0; + AX_VDEC_GRP VdGrp = 0; + + if (pstFfmpeg == NULL) { + SAMPLE_CRIT_LOG("pstFfmpeg == NULL"); + s32Ret = AX_ERR_VDEC_NULL_PTR; + goto ERR_RET; + } + + pstAvFmtCtx = pstFfmpeg->pstAvFmtCtx; + if (pstAvFmtCtx == NULL) { + SAMPLE_CRIT_LOG("pstAvFmtCtx == NULL"); + s32Ret = AX_ERR_VDEC_NULL_PTR; + goto ERR_RET; + } + + pstAvBSFCtx = pstFfmpeg->pstAvBSFCtx; + if (pstAvBSFCtx == NULL) { + SAMPLE_CRIT_LOG("pstAvBSFCtx == NULL"); + s32Ret = AX_ERR_VDEC_NULL_PTR; + goto ERR_RET; + } + + pstAvPkt = pstFfmpeg->pstAvPkt; + if (pstAvPkt == NULL) { + SAMPLE_CRIT_LOG("pstAvPkt == NULL"); + s32Ret = AX_ERR_VDEC_NULL_PTR; + goto ERR_RET; + } + + if (pstBitStreamInfo == NULL) { + SAMPLE_CRIT_LOG("pstBitStreamInfo == NULL"); + s32Ret = AX_ERR_VDEC_NULL_PTR; + goto ERR_RET; + } + + if (pstStreamBuf == NULL) { + SAMPLE_CRIT_LOG("pstStreamBuf == NULL\n"); + s32Ret = AX_ERR_VDEC_NULL_PTR; + goto ERR_RET; + } + + if (pstStreamBuf->tBufAddr.pVirAddr == NULL) { + SAMPLE_CRIT_LOG("pstStreamBuf->tBufAddr.pVirAddr == NULL\n"); + s32Ret = AX_ERR_VDEC_BAD_ADDR; + goto ERR_RET; + } + + if (pReadLen == NULL) { + SAMPLE_CRIT_LOG("pReadLen == NULL\n"); + s32Ret = AX_ERR_VDEC_NULL_PTR; + goto ERR_RET; + } + + VdGrp = pstBitStreamInfo->VdGrp; + + while (1) { + ret = av_read_frame(pstAvFmtCtx, pstAvPkt); + if (ret < 0) { + if (AVERROR_EOF == ret) { + SAMPLE_LOG("reach eof of stream %d ", VdGrp); + *pReadLen = 0; + break; + } else { + SAMPLE_CRIT_LOG("av_read_frame(stream %d) fail, error: %d", VdGrp, ret); + s32Ret = AX_ERR_VDEC_STRM_ERROR; + break; + } + } else { + if (pstAvPkt->stream_index == pstFfmpeg->s32VideoIndex) { + ret = av_bsf_send_packet(pstAvBSFCtx, pstAvPkt); + if (ret < 0) { + av_packet_unref(pstAvPkt); + SAMPLE_CRIT_LOG("av_bsf_send_packet(stream %d) fail, error: %d", VdGrp, ret); + s32Ret = AX_ERR_VDEC_RUN_ERROR; + break; + } + + while (ret >= 0) { + ret = av_bsf_receive_packet(pstAvBSFCtx, pstAvPkt); + if (ret < 0) { + if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) { + break; + } + + av_packet_unref(pstAvPkt); + SAMPLE_CRIT_LOG("av_bsf_receive_packet(stream %d) fail, error: %d", VdGrp, ret); + s32Ret = AX_ERR_VDEC_RUN_ERROR; + goto ERR_RET; + } + + if (pstStreamBuf->uBufSize < pstAvPkt->size) { + SAMPLE_CRIT_LOG("uBufSize:0x%x < pstAvPkt->size:0x%x. " + "bufSize is not enough, please increase STREAM_BUFFER_MAX_SIZE", + pstStreamBuf->uBufSize, pstAvPkt->size); + s32Ret = AX_ERR_VDEC_STRM_ERROR; + goto ERR_RET; + } + + u64FrameCnt++; + *pReadLen = pstAvPkt->size; + memcpy(pstStreamBuf->tBufAddr.pVirAddr, pstAvPkt->data, pstAvPkt->size); + + SAMPLE_LOG_N("u64FrameCnt:%lld, pstAvPkt->size:%d", u64FrameCnt, pstAvPkt->size); + } + } + + av_packet_unref(pstAvPkt); + } + + break; + } + +ERR_RET: + return s32Ret; +} +#endif + +AX_U32 SampleVdecSearchStartCode(AX_U8 *uStrAddr, AX_U32 uLen, AX_U32 *puReadBytes, AX_U32 *puZeroCount) +{ + AX_U32 i = 0; + + if (AX_NULL == uStrAddr) { + return AX_FALSE; + } + + if (uLen < 4) { + return AX_FALSE; + } + + if (AX_NULL == puReadBytes) { + return AX_FALSE; + } + + if (AX_NULL == puZeroCount) { + return AX_FALSE; + } + + *puReadBytes = 0; + *puZeroCount = 0; + + for (i = 0; i < uLen - 4; i++) { + if ((uStrAddr[i] == 0) + && (uStrAddr[i + 1] == 0) + && (uStrAddr[i + 2] == 0) + && (uStrAddr[i + 3] == 1)) { + *puReadBytes = i; + *puZeroCount = 3; + return AX_TRUE; + } else if ((uStrAddr[i] == 0) + && (uStrAddr[i + 1] == 0) + && (uStrAddr[i + 2] == 1)) { + *puReadBytes = i; + *puZeroCount = 2; + return AX_TRUE; + } + } + + return AX_FALSE; +} + +AX_VOID SampelVdecSetThreadName(const char *nameFmt, ...) +{ + AX_CHAR name[16]; + va_list args; + + va_start(args, nameFmt); + vsnprintf(name, sizeof(name), nameFmt, args); + va_end(args); + + prctl(PR_SET_NAME, name, NULL, NULL, NULL); +} + +AX_U64 SampleGetFileSize(char * pFileName) +{ + AX_CHAR cmd[256] = {0}; + FILE *pInfo = NULL; + AX_U64 fileSize = 0; + AX_S32 ret = 0; + AX_U32 i = 0; + + SAMPLE_LOG_TMP("calu file: %s\n", pFileName); + sprintf(cmd, "stat %s > fileInfo.txt", pFileName); + + ret = system(cmd); + if (ret) + return -1; + + pInfo = fopen("fileInfo.txt", "rb"); + if (NULL == pInfo) + return -1; + + fgets(cmd, 256, pInfo); + SAMPLE_LOG_TMP("file: %s\n", cmd); + fgets(cmd, 256, pInfo); + SAMPLE_LOG_TMP("info: %s\n", cmd); + fclose(pInfo); + + if (strlen(cmd) < 10) { + return -1; + } + + while(cmd[i]) { + if (('0' <= cmd[i]) && ('9' >= cmd[i])) + break; + + SAMPLE_LOG_TMP("pos %d char %c\n", i, cmd[i]); + i++; + } + + while(cmd[i]) { + SAMPLE_LOG_TMP("pos %d char %c\n", i, cmd[i]); + if (('0' > cmd[i]) || ('9' < cmd[i])) + break; + + fileSize = fileSize * 10 + (cmd[i] - '0'); + i++; + } + + return fileSize; +} diff --git a/projects/llm_framework/main_skel/src/runner/frameMgr.cpp b/projects/llm_framework/main_skel/src/runner/frameMgr.cpp new file mode 100644 index 0000000..bb5138d --- /dev/null +++ b/projects/llm_framework/main_skel/src/runner/frameMgr.cpp @@ -0,0 +1,72 @@ +/************************************************************************************************** + * + * Copyright (c) 2019-2024 Axera Semiconductor Co., Ltd. All Rights Reserved. + * + * This source file is the property of Axera Semiconductor Co., Ltd. and + * may not be copied or distributed in any isomorphic form without the prior + * written consent of Axera Semiconductor Co., Ltd. + * + **************************************************************************************************/ + +#include +#include +#include +#include +#include +#include "frameMgr.h" +#include + +AX_BOOL g_bSkel_frame_mgr_inited = AX_FALSE; +AX_POOL g_skel_frame_poolId = AX_INVALID_POOLID; + +AX_VOID FrameMgrCreate(AX_U32 nFrameSize, AX_U32 nDepth) { + AX_POOL_CONFIG_T stPoolConfig; + + memset(&stPoolConfig, 0, sizeof(AX_POOL_CONFIG_T)); + stPoolConfig.MetaSize = 4096; + stPoolConfig.BlkCnt = nDepth; + stPoolConfig.BlkSize = nFrameSize; + stPoolConfig.CacheMode = AX_POOL_CACHE_MODE_NONCACHE; + memset(stPoolConfig.PartitionName, 0, sizeof(stPoolConfig.PartitionName)); + strcpy((AX_CHAR *)stPoolConfig.PartitionName, "anonymous"); + + g_skel_frame_poolId = AX_POOL_CreatePool(&stPoolConfig); + g_bSkel_frame_mgr_inited = AX_TRUE; +} + +AX_BOOL FrameMgrGet(AX_U64 *YUVDataPhy, AX_VOID **YUVDataVir, AX_U32 nFrameSize, AX_U64 nFrameId, AX_BLK *nBlkId) { + if (!g_bSkel_frame_mgr_inited + || g_skel_frame_poolId == AX_INVALID_POOLID) { + return AX_FALSE; + } + + AX_BLK blkId = AX_POOL_GetBlock(g_skel_frame_poolId, nFrameSize, NULL); + + if (blkId != AX_INVALID_BLOCKID) { + *YUVDataPhy = AX_POOL_Handle2PhysAddr(blkId); + *YUVDataVir = AX_POOL_GetBlockVirAddr(blkId); + *nBlkId = blkId; + + return AX_TRUE; + } + + return AX_FALSE; +} + +AX_VOID FrameMgrRelease(AX_BLK blkId) { + if (blkId != AX_INVALID_BLOCKID) { + blkId = AX_POOL_ReleaseBlock(blkId); + } +} + +AX_VOID FrameMgrDestroy(AX_VOID) { + if (!g_bSkel_frame_mgr_inited + || g_skel_frame_poolId == AX_INVALID_POOLID) { + return; + } + + AX_POOL_DestroyPool(g_skel_frame_poolId); + + g_skel_frame_poolId = AX_INVALID_POOLID; + g_bSkel_frame_mgr_inited = AX_FALSE; +} diff --git a/projects/llm_framework/main_skel/src/runner/frameMgr.h b/projects/llm_framework/main_skel/src/runner/frameMgr.h new file mode 100644 index 0000000..ce3fbd4 --- /dev/null +++ b/projects/llm_framework/main_skel/src/runner/frameMgr.h @@ -0,0 +1,33 @@ +/************************************************************************************************** + * + * Copyright (c) 2019-2024 Axera Semiconductor Co., Ltd. All Rights Reserved. + * + * This source file is the property of Axera Semiconductor Co., Ltd. and + * may not be copied or distributed in any isomorphic form without the prior + * written consent of Axera Semiconductor Co., Ltd. + * + **************************************************************************************************/ + +#ifndef _FRAME_MGR_H_ +#define _FRAME_MGR_H_ +#include "ax_global_type.h" +#include "ax_sys_api.h" +#include "ax_skel_api.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define SKEL_FRAME_BUF_DEFAULT_DEPTH 2 + +AX_VOID FrameMgrCreate(AX_U32 nFrameSize, AX_U32 nDepth); +AX_BOOL FrameMgrGet(AX_U64 *YUVDataPhy, AX_VOID **YUVDataVir, AX_U32 nFrameSize, AX_U64 nFrameId, AX_BLK *nBlkId); +AX_VOID FrameMgrRelease(AX_BLK nBlkId); +AX_VOID FrameMgrDestroy(AX_VOID); + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/projects/llm_framework/main_skel/src/runner/picojson.h b/projects/llm_framework/main_skel/src/runner/picojson.h new file mode 100644 index 0000000..04dab8b --- /dev/null +++ b/projects/llm_framework/main_skel/src/runner/picojson.h @@ -0,0 +1,1151 @@ +/************************************************************************************************** + * + * Copyright (c) 2019-2024 Axera Semiconductor Co., Ltd. All Rights Reserved. + * + * This source file is the property of Axera Semiconductor Co., Ltd. and + * may not be copied or distributed in any isomorphic form without the prior + * written consent of Axera Semiconductor Co., Ltd. + * + **************************************************************************************************/ + +#ifndef picojson_h +#define picojson_h + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// for isnan/isinf +#if __cplusplus >= 201103L +#include +#else +extern "C" { +#ifdef _MSC_VER +#include +#elif defined(__INTEL_COMPILER) +#include +#else +#include +#endif +} +#endif + +#ifndef PICOJSON_USE_RVALUE_REFERENCE +#if (defined(__cpp_rvalue_references) && __cpp_rvalue_references >= 200610) || (defined(_MSC_VER) && _MSC_VER >= 1600) +#define PICOJSON_USE_RVALUE_REFERENCE 1 +#else +#define PICOJSON_USE_RVALUE_REFERENCE 0 +#endif +#endif // PICOJSON_USE_RVALUE_REFERENCE + +#ifndef PICOJSON_NOEXCEPT +#if PICOJSON_USE_RVALUE_REFERENCE +#define PICOJSON_NOEXCEPT noexcept +#else +#define PICOJSON_NOEXCEPT throw() +#endif +#endif + +// experimental support for int64_t (see README.mkdn for detail) +#ifdef PICOJSON_USE_INT64 +#define __STDC_FORMAT_MACROS +#include +#include +#endif + +// to disable the use of localeconv(3), set PICOJSON_USE_LOCALE to 0 +#ifndef PICOJSON_USE_LOCALE +#define PICOJSON_USE_LOCALE 1 +#endif +#if PICOJSON_USE_LOCALE +extern "C" { +#include +} +#endif + +#ifndef PICOJSON_ASSERT +#define PICOJSON_ASSERT(e) \ + do { \ + if (!(e)) \ + throw std::runtime_error(#e); \ + } while (0) +#endif + +#ifdef _MSC_VER +#define SNPRINTF _snprintf_s +#pragma warning(push) +#pragma warning(disable : 4244) // conversion from int to char +#pragma warning(disable : 4127) // conditional expression is constant +#pragma warning(disable : 4702) // unreachable code +#else +#define SNPRINTF snprintf +#endif + +namespace picojson { + +enum { + null_type, + boolean_type, + number_type, + string_type, + array_type, + object_type +#ifdef PICOJSON_USE_INT64 + , + int64_type +#endif +}; + +enum { INDENT_WIDTH = 2 }; + +struct null {}; + +class value { +public: + typedef std::vector array; + typedef std::map object; + union _storage { + bool boolean_; + double number_; +#ifdef PICOJSON_USE_INT64 + int64_t int64_; +#endif + std::string *string_; + array *array_; + object *object_; + }; + +protected: + int type_; + _storage u_; + +public: + value(); + value(int type, bool); + explicit value(bool b); +#ifdef PICOJSON_USE_INT64 + explicit value(int64_t i); +#endif + explicit value(double n); + explicit value(const std::string &s); + explicit value(const array &a); + explicit value(const object &o); +#if PICOJSON_USE_RVALUE_REFERENCE + explicit value(std::string &&s); + explicit value(array &&a); + explicit value(object &&o); +#endif + explicit value(const char *s); + value(const char *s, size_t len); + ~value(); + value(const value &x); + value &operator=(const value &x); +#if PICOJSON_USE_RVALUE_REFERENCE + value(value &&x) PICOJSON_NOEXCEPT; + value &operator=(value &&x) PICOJSON_NOEXCEPT; +#endif + void swap(value &x) PICOJSON_NOEXCEPT; + template bool is() const; + template const T &get() const; + template T &get(); + template void set(const T &); +#if PICOJSON_USE_RVALUE_REFERENCE + template void set(T &&); +#endif + bool evaluate_as_boolean() const; + const value &get(const size_t idx) const; + const value &get(const std::string &key) const; + value &get(const size_t idx); + value &get(const std::string &key); + + bool contains(const size_t idx) const; + bool contains(const std::string &key) const; + std::string to_str() const; + template void serialize(Iter os, bool prettify = false) const; + std::string serialize(bool prettify = false) const; + +private: + template value(const T *); // intentionally defined to block implicit conversion of pointer to bool + template static void _indent(Iter os, int indent); + template void _serialize(Iter os, int indent) const; + std::string _serialize(int indent) const; + void clear(); +}; + +typedef value::array array; +typedef value::object object; + +inline value::value() : type_(null_type), u_() { +} + +inline value::value(int type, bool) : type_(type), u_() { + switch (type) { +#define INIT(p, v) \ + case p##type: \ + u_.p = v; \ + break + INIT(boolean_, false); + INIT(number_, 0.0); +#ifdef PICOJSON_USE_INT64 + INIT(int64_, 0); +#endif + INIT(string_, new std::string()); + INIT(array_, new array()); + INIT(object_, new object()); +#undef INIT + default: + break; + } +} + +inline value::value(bool b) : type_(boolean_type), u_() { + u_.boolean_ = b; +} + +#ifdef PICOJSON_USE_INT64 +inline value::value(int64_t i) : type_(int64_type), u_() { + u_.int64_ = i; +} +#endif + +inline value::value(double n) : type_(number_type), u_() { + if ( +#ifdef _MSC_VER + !_finite(n) +#elif __cplusplus >= 201103L || !(defined(isnan) && defined(isinf)) + std::isnan(n) || std::isinf(n) +#else + isnan(n) || isinf(n) +#endif + ) { + throw std::overflow_error(""); + } + u_.number_ = n; +} + +inline value::value(const std::string &s) : type_(string_type), u_() { + u_.string_ = new std::string(s); +} + +inline value::value(const array &a) : type_(array_type), u_() { + u_.array_ = new array(a); +} + +inline value::value(const object &o) : type_(object_type), u_() { + u_.object_ = new object(o); +} + +#if PICOJSON_USE_RVALUE_REFERENCE +inline value::value(std::string &&s) : type_(string_type), u_() { + u_.string_ = new std::string(std::move(s)); +} + +inline value::value(array &&a) : type_(array_type), u_() { + u_.array_ = new array(std::move(a)); +} + +inline value::value(object &&o) : type_(object_type), u_() { + u_.object_ = new object(std::move(o)); +} +#endif + +inline value::value(const char *s) : type_(string_type), u_() { + u_.string_ = new std::string(s); +} + +inline value::value(const char *s, size_t len) : type_(string_type), u_() { + u_.string_ = new std::string(s, len); +} + +inline void value::clear() { + switch (type_) { +#define DEINIT(p) \ + case p##type: \ + delete u_.p; \ + break + DEINIT(string_); + DEINIT(array_); + DEINIT(object_); +#undef DEINIT + default: + break; + } +} + +inline value::~value() { + clear(); +} + +inline value::value(const value &x) : type_(x.type_), u_() { + switch (type_) { +#define INIT(p, v) \ + case p##type: \ + u_.p = v; \ + break + INIT(string_, new std::string(*x.u_.string_)); + INIT(array_, new array(*x.u_.array_)); + INIT(object_, new object(*x.u_.object_)); +#undef INIT + default: + u_ = x.u_; + break; + } +} + +inline value &value::operator=(const value &x) { + if (this != &x) { + value t(x); + swap(t); + } + return *this; +} + +#if PICOJSON_USE_RVALUE_REFERENCE +inline value::value(value &&x) PICOJSON_NOEXCEPT : type_(null_type), u_() { + swap(x); +} +inline value &value::operator=(value &&x) PICOJSON_NOEXCEPT { + swap(x); + return *this; +} +#endif +inline void value::swap(value &x) PICOJSON_NOEXCEPT { + std::swap(type_, x.type_); + std::swap(u_, x.u_); +} + +#define IS(ctype, jtype) \ + template <> inline bool value::is() const { \ + return type_ == jtype##_type; \ + } +IS(null, null) +IS(bool, boolean) +#ifdef PICOJSON_USE_INT64 +IS(int64_t, int64) +#endif +IS(std::string, string) +IS(array, array) +IS(object, object) +#undef IS +template <> inline bool value::is() const { + return type_ == number_type +#ifdef PICOJSON_USE_INT64 + || type_ == int64_type +#endif + ; +} + +#define GET(ctype, var) \ + template <> inline const ctype &value::get() const { \ + PICOJSON_ASSERT("type mismatch! call is() before get()" && is()); \ + return var; \ + } \ + template <> inline ctype &value::get() { \ + PICOJSON_ASSERT("type mismatch! call is() before get()" && is()); \ + return var; \ + } +GET(bool, u_.boolean_) +GET(std::string, *u_.string_) +GET(array, *u_.array_) +GET(object, *u_.object_) +#ifdef PICOJSON_USE_INT64 +GET(double, + (type_ == int64_type && (const_cast(this)->type_ = number_type, const_cast(this)->u_.number_ = u_.int64_), + u_.number_)) +GET(int64_t, u_.int64_) +#else +GET(double, u_.number_) +#endif +#undef GET + +#define SET(ctype, jtype, setter) \ + template <> inline void value::set(const ctype &_val) { \ + clear(); \ + type_ = jtype##_type; \ + setter \ + } +SET(bool, boolean, u_.boolean_ = _val;) +SET(std::string, string, u_.string_ = new std::string(_val);) +SET(array, array, u_.array_ = new array(_val);) +SET(object, object, u_.object_ = new object(_val);) +SET(double, number, u_.number_ = _val;) +#ifdef PICOJSON_USE_INT64 +SET(int64_t, int64, u_.int64_ = _val;) +#endif +#undef SET + +#if PICOJSON_USE_RVALUE_REFERENCE +#define MOVESET(ctype, jtype, setter) \ + template <> inline void value::set(ctype && _val) { \ + clear(); \ + type_ = jtype##_type; \ + setter \ + } +MOVESET(std::string, string, u_.string_ = new std::string(std::move(_val));) +MOVESET(array, array, u_.array_ = new array(std::move(_val));) +MOVESET(object, object, u_.object_ = new object(std::move(_val));) +#undef MOVESET +#endif + +inline bool value::evaluate_as_boolean() const { + switch (type_) { + case null_type: + return false; + case boolean_type: + return u_.boolean_; + case number_type: + return u_.number_ != 0; +#ifdef PICOJSON_USE_INT64 + case int64_type: + return u_.int64_ != 0; +#endif + case string_type: + return !u_.string_->empty(); + default: + return true; + } +} + +inline const value &value::get(const size_t idx) const { + static value s_null; + PICOJSON_ASSERT(is()); + return idx < u_.array_->size() ? (*u_.array_)[idx] : s_null; +} + +inline value &value::get(const size_t idx) { + static value s_null; + PICOJSON_ASSERT(is()); + return idx < u_.array_->size() ? (*u_.array_)[idx] : s_null; +} + +inline const value &value::get(const std::string &key) const { + static value s_null; + PICOJSON_ASSERT(is()); + object::const_iterator i = u_.object_->find(key); + return i != u_.object_->end() ? i->second : s_null; +} + +inline value &value::get(const std::string &key) { + static value s_null; + PICOJSON_ASSERT(is()); + object::iterator i = u_.object_->find(key); + return i != u_.object_->end() ? i->second : s_null; +} + +inline bool value::contains(const size_t idx) const { + PICOJSON_ASSERT(is()); + return idx < u_.array_->size(); +} + +inline bool value::contains(const std::string &key) const { + PICOJSON_ASSERT(is()); + object::const_iterator i = u_.object_->find(key); + return i != u_.object_->end(); +} + +inline std::string value::to_str() const { + switch (type_) { + case null_type: + return "null"; + case boolean_type: + return u_.boolean_ ? "true" : "false"; +#ifdef PICOJSON_USE_INT64 + case int64_type: { + char buf[sizeof("-9223372036854775808")]; + SNPRINTF(buf, sizeof(buf), "%" PRId64, u_.int64_); + return buf; + } +#endif + case number_type: { + char buf[256]; + double tmp; + SNPRINTF(buf, sizeof(buf), fabs(u_.number_) < (1ULL << 53) && modf(u_.number_, &tmp) == 0 ? "%.f" : "%.17g", u_.number_); +#if PICOJSON_USE_LOCALE + char *decimal_point = localeconv()->decimal_point; + if (strcmp(decimal_point, ".") != 0) { + size_t decimal_point_len = strlen(decimal_point); + for (char *p = buf; *p != '\0'; ++p) { + if (strncmp(p, decimal_point, decimal_point_len) == 0) { + return std::string(buf, p) + "." + (p + decimal_point_len); + } + } + } +#endif + return buf; + } + case string_type: + return *u_.string_; + case array_type: + return "array"; + case object_type: + return "object"; + default: + PICOJSON_ASSERT(0); +#ifdef _MSC_VER + __assume(0); +#endif + } + return std::string(); +} + +template void copy(const std::string &s, Iter oi) { + std::copy(s.begin(), s.end(), oi); +} + +template struct serialize_str_char { + Iter oi; + void operator()(char c) { + switch (c) { +#define MAP(val, sym) \ + case val: \ + copy(sym, oi); \ + break + MAP('"', "\\\""); + MAP('\\', "\\\\"); + MAP('/', "\\/"); + MAP('\b', "\\b"); + MAP('\f', "\\f"); + MAP('\n', "\\n"); + MAP('\r', "\\r"); + MAP('\t', "\\t"); +#undef MAP + default: + if (static_cast(c) < 0x20 || c == 0x7f) { + char buf[7]; + SNPRINTF(buf, sizeof(buf), "\\u%04x", c & 0xff); + copy(buf, buf + 6, oi); + } else { + *oi++ = c; + } + break; + } + } +}; + +template void serialize_str(const std::string &s, Iter oi) { + *oi++ = '"'; + serialize_str_char process_char = {oi}; + std::for_each(s.begin(), s.end(), process_char); + *oi++ = '"'; +} + +template void value::serialize(Iter oi, bool prettify) const { + return _serialize(oi, prettify ? 0 : -1); +} + +inline std::string value::serialize(bool prettify) const { + return _serialize(prettify ? 0 : -1); +} + +template void value::_indent(Iter oi, int indent) { + *oi++ = '\n'; + for (int i = 0; i < indent * INDENT_WIDTH; ++i) { + *oi++ = ' '; + } +} + +template void value::_serialize(Iter oi, int indent) const { + switch (type_) { + case string_type: + serialize_str(*u_.string_, oi); + break; + case array_type: { + *oi++ = '['; + if (indent != -1) { + ++indent; + } + for (array::const_iterator i = u_.array_->begin(); i != u_.array_->end(); ++i) { + if (i != u_.array_->begin()) { + *oi++ = ','; + } + if (indent != -1) { + _indent(oi, indent); + } + i->_serialize(oi, indent); + } + if (indent != -1) { + --indent; + if (!u_.array_->empty()) { + _indent(oi, indent); + } + } + *oi++ = ']'; + break; + } + case object_type: { + *oi++ = '{'; + if (indent != -1) { + ++indent; + } + for (object::const_iterator i = u_.object_->begin(); i != u_.object_->end(); ++i) { + if (i != u_.object_->begin()) { + *oi++ = ','; + } + if (indent != -1) { + _indent(oi, indent); + } + serialize_str(i->first, oi); + *oi++ = ':'; + if (indent != -1) { + *oi++ = ' '; + } + i->second._serialize(oi, indent); + } + if (indent != -1) { + --indent; + if (!u_.object_->empty()) { + _indent(oi, indent); + } + } + *oi++ = '}'; + break; + } + default: + copy(to_str(), oi); + break; + } + if (indent == 0) { + *oi++ = '\n'; + } +} + +inline std::string value::_serialize(int indent) const { + std::string s; + _serialize(std::back_inserter(s), indent); + return s; +} + +template class input { +protected: + Iter cur_, end_; + bool consumed_; + int line_; + +public: + input(const Iter &first, const Iter &last) : cur_(first), end_(last), consumed_(false), line_(1) { + } + int getc() { + if (consumed_) { + if (*cur_ == '\n') { + ++line_; + } + ++cur_; + } + if (cur_ == end_) { + consumed_ = false; + return -1; + } + consumed_ = true; + return *cur_ & 0xff; + } + void ungetc() { + consumed_ = false; + } + Iter cur() const { + if (consumed_) { + input *self = const_cast *>(this); + self->consumed_ = false; + ++self->cur_; + } + return cur_; + } + int line() const { + return line_; + } + void skip_ws() { + while (1) { + int ch = getc(); + if (!(ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r')) { + ungetc(); + break; + } + } + } + bool expect(const int expected) { + skip_ws(); + if (getc() != expected) { + ungetc(); + return false; + } + return true; + } + bool match(const std::string &pattern) { + for (std::string::const_iterator pi(pattern.begin()); pi != pattern.end(); ++pi) { + if (getc() != *pi) { + ungetc(); + return false; + } + } + return true; + } +}; + +template inline int _parse_quadhex(input &in) { + int uni_ch = 0, hex; + for (int i = 0; i < 4; i++) { + if ((hex = in.getc()) == -1) { + return -1; + } + if ('0' <= hex && hex <= '9') { + hex -= '0'; + } else if ('A' <= hex && hex <= 'F') { + hex -= 'A' - 0xa; + } else if ('a' <= hex && hex <= 'f') { + hex -= 'a' - 0xa; + } else { + in.ungetc(); + return -1; + } + uni_ch = uni_ch * 16 + hex; + } + return uni_ch; +} + +template inline bool _parse_codepoint(String &out, input &in) { + int uni_ch; + if ((uni_ch = _parse_quadhex(in)) == -1) { + return false; + } + if (0xd800 <= uni_ch && uni_ch <= 0xdfff) { + if (0xdc00 <= uni_ch) { + // a second 16-bit of a surrogate pair appeared + return false; + } + // first 16-bit of surrogate pair, get the next one + if (in.getc() != '\\' || in.getc() != 'u') { + in.ungetc(); + return false; + } + int second = _parse_quadhex(in); + if (!(0xdc00 <= second && second <= 0xdfff)) { + return false; + } + uni_ch = ((uni_ch - 0xd800) << 10) | ((second - 0xdc00) & 0x3ff); + uni_ch += 0x10000; + } + if (uni_ch < 0x80) { + out.push_back(static_cast(uni_ch)); + } else { + if (uni_ch < 0x800) { + out.push_back(static_cast(0xc0 | (uni_ch >> 6))); + } else { + if (uni_ch < 0x10000) { + out.push_back(static_cast(0xe0 | (uni_ch >> 12))); + } else { + out.push_back(static_cast(0xf0 | (uni_ch >> 18))); + out.push_back(static_cast(0x80 | ((uni_ch >> 12) & 0x3f))); + } + out.push_back(static_cast(0x80 | ((uni_ch >> 6) & 0x3f))); + } + out.push_back(static_cast(0x80 | (uni_ch & 0x3f))); + } + return true; +} + +template inline bool _parse_string(String &out, input &in) { + while (1) { + int ch = in.getc(); + if (ch < ' ') { + in.ungetc(); + return false; + } else if (ch == '"') { + return true; + } else if (ch == '\\') { + if ((ch = in.getc()) == -1) { + return false; + } + switch (ch) { +#define MAP(sym, val) \ + case sym: \ + out.push_back(val); \ + break + MAP('"', '\"'); + MAP('\\', '\\'); + MAP('/', '/'); + MAP('b', '\b'); + MAP('f', '\f'); + MAP('n', '\n'); + MAP('r', '\r'); + MAP('t', '\t'); +#undef MAP + case 'u': + if (!_parse_codepoint(out, in)) { + return false; + } + break; + default: + return false; + } + } else { + out.push_back(static_cast(ch)); + } + } + return false; +} + +template inline bool _parse_array(Context &ctx, input &in) { + if (!ctx.parse_array_start()) { + return false; + } + size_t idx = 0; + if (in.expect(']')) { + return ctx.parse_array_stop(idx); + } + do { + if (!ctx.parse_array_item(in, idx)) { + return false; + } + idx++; + } while (in.expect(',')); + return in.expect(']') && ctx.parse_array_stop(idx); +} + +template inline bool _parse_object(Context &ctx, input &in) { + if (!ctx.parse_object_start()) { + return false; + } + if (in.expect('}')) { + return true; + } + do { + std::string key; + if (!in.expect('"') || !_parse_string(key, in) || !in.expect(':')) { + return false; + } + if (!ctx.parse_object_item(in, key)) { + return false; + } + } while (in.expect(',')); + return in.expect('}'); +} + +template inline std::string _parse_number(input &in) { + std::string num_str; + while (1) { + int ch = in.getc(); + if (('0' <= ch && ch <= '9') || ch == '+' || ch == '-' || ch == 'e' || ch == 'E') { + num_str.push_back(static_cast(ch)); + } else if (ch == '.') { +#if PICOJSON_USE_LOCALE + num_str += localeconv()->decimal_point; +#else + num_str.push_back('.'); +#endif + } else { + in.ungetc(); + break; + } + } + return num_str; +} + +template inline bool _parse(Context &ctx, input &in) { + in.skip_ws(); + int ch = in.getc(); + switch (ch) { +#define IS(ch, text, op) \ + case ch: \ + if (in.match(text) && op) { \ + return true; \ + } else { \ + return false; \ + } + IS('n', "ull", ctx.set_null()); + IS('f', "alse", ctx.set_bool(false)); + IS('t', "rue", ctx.set_bool(true)); +#undef IS + case '"': + return ctx.parse_string(in); + case '[': + return _parse_array(ctx, in); + case '{': + return _parse_object(ctx, in); + default: + if (('0' <= ch && ch <= '9') || ch == '-') { + double f; + char *endp; + in.ungetc(); + std::string num_str(_parse_number(in)); + if (num_str.empty()) { + return false; + } +#ifdef PICOJSON_USE_INT64 + { + errno = 0; + intmax_t ival = strtoimax(num_str.c_str(), &endp, 10); + if (errno == 0 && std::numeric_limits::min() <= ival && ival <= std::numeric_limits::max() && + endp == num_str.c_str() + num_str.size()) { + ctx.set_int64(ival); + return true; + } + } +#endif + f = strtod(num_str.c_str(), &endp); + if (endp == num_str.c_str() + num_str.size()) { + ctx.set_number(f); + return true; + } + return false; + } + break; + } + in.ungetc(); + return false; +} + +class deny_parse_context { +public: + bool set_null() { + return false; + } + bool set_bool(bool) { + return false; + } +#ifdef PICOJSON_USE_INT64 + bool set_int64(int64_t) { + return false; + } +#endif + bool set_number(double) { + return false; + } + template bool parse_string(input &) { + return false; + } + bool parse_array_start() { + return false; + } + template bool parse_array_item(input &, size_t) { + return false; + } + bool parse_array_stop(size_t) { + return false; + } + bool parse_object_start() { + return false; + } + template bool parse_object_item(input &, const std::string &) { + return false; + } +}; + +class default_parse_context { +protected: + value *out_; + +public: + default_parse_context(value *out) : out_(out) { + } + bool set_null() { + *out_ = value(); + return true; + } + bool set_bool(bool b) { + *out_ = value(b); + return true; + } +#ifdef PICOJSON_USE_INT64 + bool set_int64(int64_t i) { + *out_ = value(i); + return true; + } +#endif + bool set_number(double f) { + *out_ = value(f); + return true; + } + template bool parse_string(input &in) { + *out_ = value(string_type, false); + return _parse_string(out_->get(), in); + } + bool parse_array_start() { + *out_ = value(array_type, false); + return true; + } + template bool parse_array_item(input &in, size_t) { + array &a = out_->get(); + a.push_back(value()); + default_parse_context ctx(&a.back()); + return _parse(ctx, in); + } + bool parse_array_stop(size_t) { + return true; + } + bool parse_object_start() { + *out_ = value(object_type, false); + return true; + } + template bool parse_object_item(input &in, const std::string &key) { + object &o = out_->get(); + default_parse_context ctx(&o[key]); + return _parse(ctx, in); + } + +private: + default_parse_context(const default_parse_context &); + default_parse_context &operator=(const default_parse_context &); +}; + +class null_parse_context { +public: + struct dummy_str { + void push_back(int) { + } + }; + +public: + null_parse_context() { + } + bool set_null() { + return true; + } + bool set_bool(bool) { + return true; + } +#ifdef PICOJSON_USE_INT64 + bool set_int64(int64_t) { + return true; + } +#endif + bool set_number(double) { + return true; + } + template bool parse_string(input &in) { + dummy_str s; + return _parse_string(s, in); + } + bool parse_array_start() { + return true; + } + template bool parse_array_item(input &in, size_t) { + return _parse(*this, in); + } + bool parse_array_stop(size_t) { + return true; + } + bool parse_object_start() { + return true; + } + template bool parse_object_item(input &in, const std::string &) { + return _parse(*this, in); + } + +private: + null_parse_context(const null_parse_context &); + null_parse_context &operator=(const null_parse_context &); +}; + +// obsolete, use the version below +template inline std::string parse(value &out, Iter &pos, const Iter &last) { + std::string err; + pos = parse(out, pos, last, &err); + return err; +} + +template inline Iter _parse(Context &ctx, const Iter &first, const Iter &last, std::string *err) { + input in(first, last); + if (!_parse(ctx, in) && err != NULL) { + char buf[64]; + SNPRINTF(buf, sizeof(buf), "syntax error at line %d near: ", in.line()); + *err = buf; + while (1) { + int ch = in.getc(); + if (ch == -1 || ch == '\n') { + break; + } else if (ch >= ' ') { + err->push_back(static_cast(ch)); + } + } + } + return in.cur(); +} + +template inline Iter parse(value &out, const Iter &first, const Iter &last, std::string *err) { + default_parse_context ctx(&out); + return _parse(ctx, first, last, err); +} + +inline std::string parse(value &out, const std::string &s) { + std::string err; + parse(out, s.begin(), s.end(), &err); + return err; +} + +inline std::string parse(value &out, std::istream &is) { + std::string err; + parse(out, std::istreambuf_iterator(is.rdbuf()), std::istreambuf_iterator(), &err); + return err; +} + +template struct last_error_t { static std::string s; }; +template std::string last_error_t::s; + +inline void set_last_error(const std::string &s) { + last_error_t::s = s; +} + +inline const std::string &get_last_error() { + return last_error_t::s; +} + +inline bool operator==(const value &x, const value &y) { + if (x.is()) + return y.is(); +#define PICOJSON_CMP(type) \ + if (x.is()) \ + return y.is() && x.get() == y.get() + PICOJSON_CMP(bool); + PICOJSON_CMP(double); + PICOJSON_CMP(std::string); + PICOJSON_CMP(array); + PICOJSON_CMP(object); +#undef PICOJSON_CMP + PICOJSON_ASSERT(0); +#ifdef _MSC_VER + __assume(0); +#endif + return false; +} + +inline bool operator!=(const value &x, const value &y) { + return !(x == y); +} +} + +#if !PICOJSON_USE_RVALUE_REFERENCE +namespace std { +template <> inline void swap(picojson::value &x, picojson::value &y) { + x.swap(y); +} +} +#endif + +inline std::istream &operator>>(std::istream &is, picojson::value &x) { + picojson::set_last_error(std::string()); + const std::string err(picojson::parse(x, is)); + if (!err.empty()) { + picojson::set_last_error(err); + is.setstate(std::ios::failbit); + } + return is; +} + +inline std::ostream &operator<<(std::ostream &os, const picojson::value &x) { + x.serialize(std::ostream_iterator(os)); + return os; +} +#ifdef _MSC_VER +#pragma warning(pop) +#endif + +#endif diff --git a/projects/llm_framework/main_skel/src/runner/sample_skel.c b/projects/llm_framework/main_skel/src/runner/sample_skel.c new file mode 100644 index 0000000..b1e9364 --- /dev/null +++ b/projects/llm_framework/main_skel/src/runner/sample_skel.c @@ -0,0 +1,2285 @@ +/************************************************************************************************** + * + * Copyright (c) 2019-2024 Axera Semiconductor Co., Ltd. All Rights Reserved. + * + * This source file is the property of Axera Semiconductor Co., Ltd. and + * may not be copied or distributed in any isomorphic form without the prior + * written consent of Axera Semiconductor Co., Ltd. + * + **************************************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include "YuvHandler.h" +#include "ax_skel_api.h" +#include "ax_sys_api.h" +#include "ax_ivps_api.h" +#include "ax_venc_api.h" +#include "ax_buffer_tool.h" +#include "skel_log.h" +#include "ax_engine_api.h" +#include "frameMgr.h" +#include "attrParser.h" +#include "statMgr.h" +#include "common_vdec_api.h" + +#ifndef ALIGN_UP +#define ALIGN_UP(x, align) ((((x) + ((align) - 1)) / (align)) * (align)) +#endif + +#ifndef ALIGN_DOWN +#define ALIGN_DOWN(x, align) (((x) / (align)) * (align)) +#endif + +#ifndef AX_MAX +#define AX_MAX(a, b) (((a) > (b)) ? (a) : (b)) +#endif + +#ifndef AX_MIN +#define AX_MIN(a, b) (((a) < (b)) ? (a) : (b)) +#endif + +#define SKEL_SAMPLE_OUTPUT_BODY_PATH "body" +#define SKEL_SAMPLE_OUTPUT_VEHICLE_PATH "vehicle" +#define SKEL_SAMPLE_OUTPUT_CYCLE_PATH "cycle" +#define SKEL_SAMPLE_OUTPUT_FACE_PATH "face" +#define SKEL_SAMPLE_OUTPUT_PLATE_PATH "plate" +#define SKEL_SAMPLE_OUTPUT_LOG_FILE "output.txt" + +#define SAMPLE_SKEL_SHIFT_LEFT_ALIGN(a) (1 << (a)) +#define SAMPLE_SKEL_VDEC_WIDTH_ALIGN SAMPLE_SKEL_SHIFT_LEFT_ALIGN(8) +#define SAMPLE_SKEL_HEIGHT_ALIGN SAMPLE_SKEL_SHIFT_LEFT_ALIGN(6) + +#define RUN_COMMAND(format, ...) do { \ + char cmd[512]; \ + snprintf(cmd, 512, format, ##__VA_ARGS__); \ + system(cmd); \ + } while(0); + +AX_VOID LogSaveToFile(FILE *file, const char *fmt, ...) { + if (file) { + va_list args; + char szLog[1024] = {0}; + + va_start(args, fmt); + + AX_U32 len = vsnprintf(szLog, sizeof(szLog), (char *)fmt, args); + if (len < (AX_U32)sizeof(szLog)) { + szLog[len] = '\0'; + } else { + szLog[sizeof(szLog) - 1] = '\0'; + } + + fwrite((AX_U8 *)szLog, 1, strlen(szLog), file); + + va_end(args); + } +} +#define OUTPUT_LOG_SAVE(fmt, ...) LogSaveToFile(fpResultFile, fmt "\n", ##__VA_ARGS__) +#define BLACK_VIDEO_FRAME_COUNT 60 +#define SKEL_SAMPLE_OBJECT_SIZE 512 + +struct skeleton { + int connection[2]; + int left_right_neutral; +}; + +struct skeleton pairs[] = {{{15, 13}, 0}, {{13, 11}, 0}, {{16, 14}, 0}, {{14, 12}, 0}, {{11, 12}, 0}, + {{5, 11}, 0}, {{6, 12}, 0}, {{5, 6}, 0}, {{5, 7}, 0}, {{6, 8}, 0}, + {{7, 9}, 0}, {{8, 10}, 0}, {{1, 2}, 0}, {{0, 1}, 0}, {{0, 2}, 0}, + {{1, 3}, 0}, {{2, 4}, 0}, {{0, 5}, 0}, {{0, 6}, 0}}; + +#define DETECT_SKEL_POINT_COUNT 256 + +typedef struct _AI_Detection_Box_t { + AX_F32 fX, fY, fW, fH; +} AI_Detection_Box_t; + +typedef struct _AI_Detection_Point_t { + AX_F32 fX, fY; +} AI_Detection_Point_t; + +typedef struct _AI_Detection_SkelResult_t { + const AX_CHAR *pstrObjectCategory; + AX_U8 nPointNum; + AI_Detection_Point_t tPoint[DETECT_SKEL_POINT_COUNT]; + AI_Detection_Box_t tBox; +} AI_Detection_SkelResult_t; + +static AX_U64 get_tick_count(AX_VOID) { + struct timespec ts; + clock_gettime(CLOCK_MONOTONIC, &ts); + return (ts.tv_sec * 1000 + ts.tv_nsec / 1000000); +} + +// static AX_U64 get_tick_count_us(AX_VOID) { +// struct timespec ts; +// clock_gettime(CLOCK_MONOTONIC, &ts); +// return (ts.tv_sec * 1000000 + ts.tv_nsec / 1000); +// } + +static AX_VOID ShowUsage(AX_VOID) { + // printf("usage: ./%s ...\n", SAMPLE_SKEL_NAME); + printf("options:\n"); + printf("-i, \tInput File(yuv)\n"); + printf("-r, \tInput File Resolution(wxh)(yuv: should be input)\n"); + printf("-w, \tWrite result image to new jpg file((unsigned int), default=0)\n"); + printf("-o, \tSave result to file(file name)\n"); + printf("-m, \tModels deployment path(path name)\n"); + printf("-t, \tRepeat times((unsigned int), default=1)\n"); + printf("-I, \tInterval repeat time((unsigned int)ms, default=0)\n"); + printf("-c, \tConfidence((float: 0-1), default=0)\n"); + printf("-H, \tHuman track size limit((unsigned int), default=0)\n"); + printf("-V, \tVehicle track size limit((unsigned int), default=0)\n"); + printf("-C, \tCylcle track size limit((unsigned int), default=0)\n"); + printf("-d, \tSkel detect type((unsigned int), default=2)\n" + "\t\t0: detect only\n" + "\t\t1: detect + track\n" + "\t\t2: detect + track + push\n"); + printf("-u, \tSkel push strategy((unsigned int), default=3)\n" + "\t\t1: fast push strategy\n" + "\t\t2: push strategy\n" + "\t\t3: best push strategy\n"); + printf("-N, \tSkel NPU type((unsigned int), default=0(VNPU Disable)\n" + "\t\t0: VNPU Disable\n" + "\t\t1: STD-VNPU Default\n" + "\t\t2: STD-VNPU1\n" + "\t\t3: STD-VNPU2\n"); + printf("-p, \tSkel PPL((unsigned int), default=1)\n" + "\t\t1: AX_SKEL_PPL_HVCP\n" + "\t\t2: AX_SKEL_PPL_FACE\n"); + printf("-v, \tLog level((unsigned int), default=5)\n" + "\t\t0: LOG_EMERGENCY_LEVEL\n" + "\t\t1: LOG_ALERT_LEVEL\n" + "\t\t2: LOG_CRITICAL_LEVEL\n" + "\t\t3: LOG_ERROR_LEVEL\n" + "\t\t4: LOG_WARN_LEVEL\n" + "\t\t5: LOG_NOTICE_LEVEL\n" + "\t\t6: LOG_INFO_LEVEL\n" + "\t\t7: LOG_DEBUG_LEVEL\n"); + printf("-h, \tprint this message\n"); +} + +AX_S32 ParseConfigParam(const AX_SKEL_CONFIG_T *pstConfig) { + if (pstConfig->nSize > 0 && pstConfig->pstItems) { + for (size_t i = 0; i < pstConfig->nSize; i++) { + if (pstConfig->pstItems[i].pstrType && pstConfig->pstItems[i].pstrValue) { + // cmd: "body_max_target_count", value_type: AX_SKEL_COMMON_THRESHOLD_CONFIG_T * + if (strcmp(pstConfig->pstItems[i].pstrType, "body_max_target_count") == 0) { + if (pstConfig->pstItems[i].nValueSize == sizeof(AX_SKEL_COMMON_THRESHOLD_CONFIG_T)) { + AX_SKEL_COMMON_THRESHOLD_CONFIG_T *pstConf = + (AX_SKEL_COMMON_THRESHOLD_CONFIG_T *)pstConfig->pstItems[i].pstrValue; + ALOGI("SKEL get %s: %d", pstConfig->pstItems[i].pstrType, (AX_U8)pstConf->fValue); + } else { + ALOGE("SKEL %s size(%d) no match", pstConfig->pstItems[i].pstrType, pstConfig->pstItems[i].nValueSize); + } + } + // cmd: "vehicle_max_target_count", value_type: AX_SKEL_COMMON_THRESHOLD_CONFIG_T * + else if (strcmp(pstConfig->pstItems[i].pstrType, "vehicle_max_target_count") == 0) { + if (pstConfig->pstItems[i].nValueSize == sizeof(AX_SKEL_COMMON_THRESHOLD_CONFIG_T)) { + AX_SKEL_COMMON_THRESHOLD_CONFIG_T *pstConf = + (AX_SKEL_COMMON_THRESHOLD_CONFIG_T *)pstConfig->pstItems[i].pstrValue; + ALOGI("SKEL get %s: %d", pstConfig->pstItems[i].pstrType, (AX_U8)pstConf->fValue); + } else { + ALOGE("SKEL %s size(%d) no match", pstConfig->pstItems[i].pstrType, pstConfig->pstItems[i].nValueSize); + } + } + // cmd: "cycle_max_target_count", value_type: AX_SKEL_COMMON_THRESHOLD_CONFIG_T * + else if (strcmp(pstConfig->pstItems[i].pstrType, "cycle_max_target_count") == 0) { + if (pstConfig->pstItems[i].nValueSize == sizeof(AX_SKEL_COMMON_THRESHOLD_CONFIG_T)) { + AX_SKEL_COMMON_THRESHOLD_CONFIG_T *pstConf = + (AX_SKEL_COMMON_THRESHOLD_CONFIG_T *)pstConfig->pstItems[i].pstrValue; + ALOGI("SKEL get %s: %d", pstConfig->pstItems[i].pstrType, (AX_U8)pstConf->fValue); + } else { + ALOGE("SKEL %s size(%d) no match", pstConfig->pstItems[i].pstrType, pstConfig->pstItems[i].nValueSize); + } + } + // cmd: "body_confidence", value_type: AX_SKEL_COMMON_THRESHOLD_CONFIG_T * + else if (strcmp(pstConfig->pstItems[i].pstrType, "body_confidence") == 0) { + if (pstConfig->pstItems[i].nValueSize == sizeof(AX_SKEL_COMMON_THRESHOLD_CONFIG_T)) { + AX_SKEL_COMMON_THRESHOLD_CONFIG_T *pstConf = + (AX_SKEL_COMMON_THRESHOLD_CONFIG_T *)pstConfig->pstItems[i].pstrValue; + ALOGI("SKEL get %s: %f", pstConfig->pstItems[i].pstrType, pstConf->fValue); + } else { + ALOGE("SKEL %s size(%d) no match", pstConfig->pstItems[i].pstrType, pstConfig->pstItems[i].nValueSize); + } + } + // cmd: "face_confidence", value_type: AX_SKEL_COMMON_THRESHOLD_CONFIG_T * + else if (strcmp(pstConfig->pstItems[i].pstrType, "face_confidence") == 0) { + if (pstConfig->pstItems[i].nValueSize == sizeof(AX_SKEL_COMMON_THRESHOLD_CONFIG_T)) { + AX_SKEL_COMMON_THRESHOLD_CONFIG_T *pstConf = + (AX_SKEL_COMMON_THRESHOLD_CONFIG_T *)pstConfig->pstItems[i].pstrValue; + ALOGI("SKEL get %s: %f", pstConfig->pstItems[i].pstrType, pstConf->fValue); + } else { + ALOGE("SKEL %s size(%d) no match", pstConfig->pstItems[i].pstrType, pstConfig->pstItems[i].nValueSize); + } + } + // cmd: "vehicle_confidence", value_type: AX_SKEL_COMMON_THRESHOLD_CONFIG_T * + else if (strcmp(pstConfig->pstItems[i].pstrType, "vehicle_confidence") == 0) { + if (pstConfig->pstItems[i].nValueSize == sizeof(AX_SKEL_COMMON_THRESHOLD_CONFIG_T)) { + AX_SKEL_COMMON_THRESHOLD_CONFIG_T *pstConf = + (AX_SKEL_COMMON_THRESHOLD_CONFIG_T *)pstConfig->pstItems[i].pstrValue; + ALOGI("SKEL get %s: %f", pstConfig->pstItems[i].pstrType, pstConf->fValue); + } else { + ALOGE("SKEL %s size(%d) no match", pstConfig->pstItems[i].pstrType, pstConfig->pstItems[i].nValueSize); + } + } + // cmd: "cycle_confidence", value_type: AX_SKEL_COMMON_THRESHOLD_CONFIG_T * + else if (strcmp(pstConfig->pstItems[i].pstrType, "cycle_confidence") == 0) { + if (pstConfig->pstItems[i].nValueSize == sizeof(AX_SKEL_COMMON_THRESHOLD_CONFIG_T)) { + AX_SKEL_COMMON_THRESHOLD_CONFIG_T *pstConf = + (AX_SKEL_COMMON_THRESHOLD_CONFIG_T *)pstConfig->pstItems[i].pstrValue; + ALOGI("SKEL get %s: %f", pstConfig->pstItems[i].pstrType, pstConf->fValue); + } else { + ALOGE("SKEL %s size(%d) no match", pstConfig->pstItems[i].pstrType, pstConfig->pstItems[i].nValueSize); + } + } + // cmd: "plate_confidence", value_type: AX_SKEL_COMMON_THRESHOLD_CONFIG_T * + else if (strcmp(pstConfig->pstItems[i].pstrType, "plate_confidence") == 0) { + if (pstConfig->pstItems[i].nValueSize == sizeof(AX_SKEL_COMMON_THRESHOLD_CONFIG_T)) { + AX_SKEL_COMMON_THRESHOLD_CONFIG_T *pstConf = + (AX_SKEL_COMMON_THRESHOLD_CONFIG_T *)pstConfig->pstItems[i].pstrValue; + ALOGI("SKEL get %s: %f", pstConfig->pstItems[i].pstrType, pstConf->fValue); + } else { + ALOGE("SKEL %s size(%d) no match", pstConfig->pstItems[i].pstrType, pstConfig->pstItems[i].nValueSize); + } + } + // cmd: "crop_encoder_qpLevel", value_type: AX_SKEL_COMMON_THRESHOLD_CONFIG_T * + else if (strcmp(pstConfig->pstItems[i].pstrType, "crop_encoder_qpLevel") == 0) { + if (pstConfig->pstItems[i].nValueSize == sizeof(AX_SKEL_COMMON_THRESHOLD_CONFIG_T)) { + AX_SKEL_COMMON_THRESHOLD_CONFIG_T *pstConf = + (AX_SKEL_COMMON_THRESHOLD_CONFIG_T *)pstConfig->pstItems[i].pstrValue; + ALOGI("SKEL get %s: %f", pstConfig->pstItems[i].pstrType, pstConf->fValue); + } else { + ALOGE("SKEL %s size(%d) no match", pstConfig->pstItems[i].pstrType, pstConfig->pstItems[i].nValueSize); + } + } + // cmd: "body_min_size", value_type: AX_SKEL_OBJECT_SIZE_FILTER_CONFIG_T * + else if (strcmp(pstConfig->pstItems[i].pstrType, "body_min_size") == 0) { + if (pstConfig->pstItems[i].nValueSize == sizeof(AX_SKEL_OBJECT_SIZE_FILTER_CONFIG_T)) { + AX_SKEL_OBJECT_SIZE_FILTER_CONFIG_T *pstConf = + (AX_SKEL_OBJECT_SIZE_FILTER_CONFIG_T *)pstConfig->pstItems[i].pstrValue; + ALOGI("SKEL get %s %dx%d", pstConfig->pstItems[i].pstrType, pstConf->nWidth, pstConf->nHeight); + } else { + ALOGE("SKEL %s size(%d) no match", pstConfig->pstItems[i].pstrType, pstConfig->pstItems[i].nValueSize); + } + } + // cmd: "face_min_size", value_type: AX_SKEL_OBJECT_SIZE_FILTER_CONFIG_T * + else if (strcmp(pstConfig->pstItems[i].pstrType, "face_min_size") == 0) { + if (pstConfig->pstItems[i].nValueSize == sizeof(AX_SKEL_OBJECT_SIZE_FILTER_CONFIG_T)) { + AX_SKEL_OBJECT_SIZE_FILTER_CONFIG_T *pstConf = + (AX_SKEL_OBJECT_SIZE_FILTER_CONFIG_T *)pstConfig->pstItems[i].pstrValue; + ALOGI("SKEL get %s %dx%d", pstConfig->pstItems[i].pstrType, pstConf->nWidth, pstConf->nHeight); + } else { + ALOGE("SKEL %s size(%d) no match", pstConfig->pstItems[i].pstrType, pstConfig->pstItems[i].nValueSize); + } + } + // cmd: "vehicle_min_size", value_type: AX_SKEL_OBJECT_SIZE_FILTER_CONFIG_T * + else if (strcmp(pstConfig->pstItems[i].pstrType, "vehicle_min_size") == 0) { + if (pstConfig->pstItems[i].nValueSize == sizeof(AX_SKEL_OBJECT_SIZE_FILTER_CONFIG_T)) { + AX_SKEL_OBJECT_SIZE_FILTER_CONFIG_T *pstConf = + (AX_SKEL_OBJECT_SIZE_FILTER_CONFIG_T *)pstConfig->pstItems[i].pstrValue; + ALOGI("SKEL get %s %dx%d", pstConfig->pstItems[i].pstrType, pstConf->nWidth, pstConf->nHeight); + } else { + ALOGE("SKEL %s size(%d) no match", pstConfig->pstItems[i].pstrType, pstConfig->pstItems[i].nValueSize); + } + } + // cmd: "cycle_min_size", value_type: AX_SKEL_OBJECT_SIZE_FILTER_CONFIG_T * + else if (strcmp(pstConfig->pstItems[i].pstrType, "cycle_min_size") == 0) { + if (pstConfig->pstItems[i].nValueSize == sizeof(AX_SKEL_OBJECT_SIZE_FILTER_CONFIG_T)) { + AX_SKEL_OBJECT_SIZE_FILTER_CONFIG_T *pstConf = + (AX_SKEL_OBJECT_SIZE_FILTER_CONFIG_T *)pstConfig->pstItems[i].pstrValue; + ALOGI("SKEL get %s %dx%d", pstConfig->pstItems[i].pstrType, pstConf->nWidth, pstConf->nHeight); + } else { + ALOGE("SKEL %s size(%d) no match", pstConfig->pstItems[i].pstrType, pstConfig->pstItems[i].nValueSize); + } + } + // cmd: "plate_min_size", value_type: AX_SKEL_OBJECT_SIZE_FILTER_CONFIG_T * + else if (strcmp(pstConfig->pstItems[i].pstrType, "plate_min_size") == 0) { + if (pstConfig->pstItems[i].nValueSize == sizeof(AX_SKEL_OBJECT_SIZE_FILTER_CONFIG_T)) { + AX_SKEL_OBJECT_SIZE_FILTER_CONFIG_T *pstConf = + (AX_SKEL_OBJECT_SIZE_FILTER_CONFIG_T *)pstConfig->pstItems[i].pstrValue; + ALOGI("SKEL get %s %dx%d", pstConfig->pstItems[i].pstrType, pstConf->nWidth, pstConf->nHeight); + } else { + ALOGE("SKEL %s size(%d) no match", pstConfig->pstItems[i].pstrType, pstConfig->pstItems[i].nValueSize); + } + } + // cmd: "detect_roi_polygon", value_type: AX_SKEL_ROI_POLYGON_CONFIG_T * + else if (strcmp(pstConfig->pstItems[i].pstrType, "detect_roi_polygon") == 0) { + if (pstConfig->pstItems[i].nValueSize == sizeof(AX_SKEL_ROI_POLYGON_CONFIG_T)) { + AX_SKEL_ROI_POLYGON_CONFIG_T *pstConf = (AX_SKEL_ROI_POLYGON_CONFIG_T *)pstConfig->pstItems[i].pstrValue; + ALOGI("SKEL get %s [%d]: nPointNum[%d]", pstConfig->pstItems[i].pstrType, pstConf->bEnable, pstConf->nPointNum); + } else { + ALOGE("SKEL %s size(%d) no match", pstConfig->pstItems[i].pstrType, pstConfig->pstItems[i].nValueSize); + } + } + // cmd: "push_strategy", value_type: AX_SKEL_PUSH_STRATEGY_T * + else if (strcmp(pstConfig->pstItems[i].pstrType, "push_strategy") == 0) { + if (pstConfig->pstItems[i].nValueSize == sizeof(AX_SKEL_PUSH_STRATEGY_T)) { + AX_SKEL_PUSH_STRATEGY_T *pstConf = (AX_SKEL_PUSH_STRATEGY_T *)pstConfig->pstItems[i].pstrValue; + ALOGI("SKEL get %s [mode:%d, times:%d, count:%d, same:%d]", pstConfig->pstItems[i].pstrType, pstConf->ePushMode, pstConf->nIntervalTimes, + pstConf->nPushCounts, pstConf->bPushSameFrame); + } else { + ALOGE("SKEL %s size(%d) no match", pstConfig->pstItems[i].pstrType, pstConfig->pstItems[i].nValueSize); + } + } + // cmd: "body_crop_encoder", value_type: AX_SKEL_CROP_ENCODER_THRESHOLD_CONFIG_T * + else if (strcmp(pstConfig->pstItems[i].pstrType, "body_crop_encoder") == 0) { + if (pstConfig->pstItems[i].nValueSize == sizeof(AX_SKEL_CROP_ENCODER_THRESHOLD_CONFIG_T)) { + AX_SKEL_CROP_ENCODER_THRESHOLD_CONFIG_T *pstConf = (AX_SKEL_CROP_ENCODER_THRESHOLD_CONFIG_T *)pstConfig->pstItems[i].pstrValue; + ALOGI("SKEL get %s [%f, %f, %f, %f]", pstConfig->pstItems[i].pstrType, + pstConf->fScaleLeft, pstConf->fScaleRight, + pstConf->fScaleTop, pstConf->fScaleBottom); + } else { + ALOGE("SKEL %s size(%d) no match", pstConfig->pstItems[i].pstrType, pstConfig->pstItems[i].nValueSize); + } + } + // cmd: "vehicle_crop_encoder", value_type: AX_SKEL_CROP_ENCODER_THRESHOLD_CONFIG_T * + else if (strcmp(pstConfig->pstItems[i].pstrType, "vehicle_crop_encoder") == 0) { + if (pstConfig->pstItems[i].nValueSize == sizeof(AX_SKEL_CROP_ENCODER_THRESHOLD_CONFIG_T)) { + AX_SKEL_CROP_ENCODER_THRESHOLD_CONFIG_T *pstConf = (AX_SKEL_CROP_ENCODER_THRESHOLD_CONFIG_T *)pstConfig->pstItems[i].pstrValue; + ALOGI("SKEL get %s [%f, %f, %f, %f]", pstConfig->pstItems[i].pstrType, + pstConf->fScaleLeft, pstConf->fScaleRight, + pstConf->fScaleTop, pstConf->fScaleBottom); + } else { + ALOGE("SKEL %s size(%d) no match", pstConfig->pstItems[i].pstrType, pstConfig->pstItems[i].nValueSize); + } + } + // cmd: "cycle_crop_encoder", value_type: AX_SKEL_CROP_ENCODER_THRESHOLD_CONFIG_T * + else if (strcmp(pstConfig->pstItems[i].pstrType, "cycle_crop_encoder") == 0) { + if (pstConfig->pstItems[i].nValueSize == sizeof(AX_SKEL_CROP_ENCODER_THRESHOLD_CONFIG_T)) { + AX_SKEL_CROP_ENCODER_THRESHOLD_CONFIG_T *pstConf = (AX_SKEL_CROP_ENCODER_THRESHOLD_CONFIG_T *)pstConfig->pstItems[i].pstrValue; + ALOGI("SKEL get %s [%f, %f, %f, %f]", pstConfig->pstItems[i].pstrType, + pstConf->fScaleLeft, pstConf->fScaleRight, + pstConf->fScaleTop, pstConf->fScaleBottom); + } else { + ALOGE("SKEL %s size(%d) no match", pstConfig->pstItems[i].pstrType, pstConfig->pstItems[i].nValueSize); + } + } + // cmd: "face_crop_encoder", value_type: AX_SKEL_CROP_ENCODER_THRESHOLD_CONFIG_T * + else if (strcmp(pstConfig->pstItems[i].pstrType, "face_crop_encoder") == 0) { + if (pstConfig->pstItems[i].nValueSize == sizeof(AX_SKEL_CROP_ENCODER_THRESHOLD_CONFIG_T)) { + AX_SKEL_CROP_ENCODER_THRESHOLD_CONFIG_T *pstConf = (AX_SKEL_CROP_ENCODER_THRESHOLD_CONFIG_T *)pstConfig->pstItems[i].pstrValue; + ALOGI("SKEL get %s [%f, %f, %f, %f]", pstConfig->pstItems[i].pstrType, + pstConf->fScaleLeft, pstConf->fScaleRight, + pstConf->fScaleTop, pstConf->fScaleBottom); + } else { + ALOGE("SKEL %s size(%d) no match", pstConfig->pstItems[i].pstrType, pstConfig->pstItems[i].nValueSize); + } + } + // cmd: "plate_crop_encoder", value_type: AX_SKEL_CROP_ENCODER_THRESHOLD_CONFIG_T * + else if (strcmp(pstConfig->pstItems[i].pstrType, "plate_crop_encoder") == 0) { + if (pstConfig->pstItems[i].nValueSize == sizeof(AX_SKEL_CROP_ENCODER_THRESHOLD_CONFIG_T)) { + AX_SKEL_CROP_ENCODER_THRESHOLD_CONFIG_T *pstConf = (AX_SKEL_CROP_ENCODER_THRESHOLD_CONFIG_T *)pstConfig->pstItems[i].pstrValue; + ALOGI("SKEL get %s [%f, %f, %f, %f]", pstConfig->pstItems[i].pstrType, + pstConf->fScaleLeft, pstConf->fScaleRight, + pstConf->fScaleTop, pstConf->fScaleBottom); + } else { + ALOGE("SKEL %s size(%d) no match", pstConfig->pstItems[i].pstrType, pstConfig->pstItems[i].nValueSize); + } + } + // cmd: "push_panorama", value_type: AX_SKEL_PUSH_PANORAMA_CONFIG_T * + else if (strcmp(pstConfig->pstItems[i].pstrType, "push_panorama") == 0) { + if (pstConfig->pstItems[i].nValueSize == sizeof(AX_SKEL_PUSH_PANORAMA_CONFIG_T)) { + AX_SKEL_PUSH_PANORAMA_CONFIG_T *pstConf = (AX_SKEL_PUSH_PANORAMA_CONFIG_T *)pstConfig->pstItems[i].pstrValue; + ALOGI("SKEL get %s [Enable: %d, Quality: %d]", pstConfig->pstItems[i].pstrType, + pstConf->bEnable, pstConf->nQuality); + } else { + ALOGE("SKEL %s size(%d) no match", pstConfig->pstItems[i].pstrType, pstConfig->pstItems[i].nValueSize); + } + } + // cmd: "push_quality_body", value_type: AX_SKEL_ATTR_FILTER_CONFIG_T * + else if (strcmp(pstConfig->pstItems[i].pstrType, "push_quality_body") == 0) { + if (pstConfig->pstItems[i].nValueSize == sizeof(AX_SKEL_ATTR_FILTER_CONFIG_T)) { + AX_SKEL_ATTR_FILTER_CONFIG_T *pstConf = (AX_SKEL_ATTR_FILTER_CONFIG_T *)pstConfig->pstItems[i].pstrValue; + ALOGI("SKEL get %s [Q: %f]", pstConfig->pstItems[i].pstrType, pstConf->stCommonAttrFilterConfig.fQuality); + } else { + ALOGE("SKEL %s size(%d) no match", pstConfig->pstItems[i].pstrType, pstConfig->pstItems[i].nValueSize); + } + } + // cmd: "push_quality_vehicle", value_type: AX_SKEL_ATTR_FILTER_CONFIG_T * + else if (strcmp(pstConfig->pstItems[i].pstrType, "push_quality_vehicle") == 0) { + if (pstConfig->pstItems[i].nValueSize == sizeof(AX_SKEL_ATTR_FILTER_CONFIG_T)) { + AX_SKEL_ATTR_FILTER_CONFIG_T *pstConf = (AX_SKEL_ATTR_FILTER_CONFIG_T *)pstConfig->pstItems[i].pstrValue; + ALOGI("SKEL get %s [Q: %f]", pstConfig->pstItems[i].pstrType, pstConf->stCommonAttrFilterConfig.fQuality); + } else { + ALOGE("SKEL %s size(%d) no match", pstConfig->pstItems[i].pstrType, pstConfig->pstItems[i].nValueSize); + } + } + // cmd: "push_quality_cycle", value_type: AX_SKEL_ATTR_FILTER_CONFIG_T * + else if (strcmp(pstConfig->pstItems[i].pstrType, "push_quality_cycle") == 0) { + if (pstConfig->pstItems[i].nValueSize == sizeof(AX_SKEL_ATTR_FILTER_CONFIG_T)) { + AX_SKEL_ATTR_FILTER_CONFIG_T *pstConf = (AX_SKEL_ATTR_FILTER_CONFIG_T *)pstConfig->pstItems[i].pstrValue; + ALOGI("SKEL get %s [Q: %f]", pstConfig->pstItems[i].pstrType, pstConf->stCommonAttrFilterConfig.fQuality); + } else { + ALOGE("SKEL %s size(%d) no match", pstConfig->pstItems[i].pstrType, pstConfig->pstItems[i].nValueSize); + } + } + // cmd: "push_quality_face", value_type: AX_SKEL_ATTR_FILTER_CONFIG_T * + else if (strcmp(pstConfig->pstItems[i].pstrType, "push_quality_face") == 0) { + if (pstConfig->pstItems[i].nValueSize == sizeof(AX_SKEL_ATTR_FILTER_CONFIG_T)) { + AX_SKEL_ATTR_FILTER_CONFIG_T *pstConf = (AX_SKEL_ATTR_FILTER_CONFIG_T *)pstConfig->pstItems[i].pstrValue; + ALOGI("SKEL get %s [W: %d, H: %d, P: %f, Y: %f, R: %f, B: %f]", pstConfig->pstItems[i].pstrType, + pstConf->stFaceAttrFilterConfig.nWidth, pstConf->stFaceAttrFilterConfig.nHeight, + pstConf->stFaceAttrFilterConfig.stPoseblur.fPitch, pstConf->stFaceAttrFilterConfig.stPoseblur.fYaw, + pstConf->stFaceAttrFilterConfig.stPoseblur.fRoll, pstConf->stFaceAttrFilterConfig.stPoseblur.fBlur); + } else { + ALOGE("SKEL %s size(%d) no match", pstConfig->pstItems[i].pstrType, pstConfig->pstItems[i].nValueSize); + } + } + // cmd: "push_quality_plate", value_type: AX_SKEL_ATTR_FILTER_CONFIG_T * + else if (strcmp(pstConfig->pstItems[i].pstrType, "push_quality_plate") == 0) { + if (pstConfig->pstItems[i].nValueSize == sizeof(AX_SKEL_ATTR_FILTER_CONFIG_T)) { + AX_SKEL_ATTR_FILTER_CONFIG_T *pstConf = (AX_SKEL_ATTR_FILTER_CONFIG_T *)pstConfig->pstItems[i].pstrValue; + ALOGI("SKEL get %s [Q: %f]", pstConfig->pstItems[i].pstrType, pstConf->stCommonAttrFilterConfig.fQuality); + } else { + ALOGE("SKEL %s size(%d) no match", pstConfig->pstItems[i].pstrType, pstConfig->pstItems[i].nValueSize); + } + } + // cmd: "push_bind_enable", value_type: AX_SKEL_COMMON_THRESHOLD_CONFIG_T * + else if (strcmp(pstConfig->pstItems[i].pstrType, "push_bind_enable") == 0) { + if (pstConfig->pstItems[i].nValueSize == sizeof(AX_SKEL_COMMON_THRESHOLD_CONFIG_T)) { + AX_SKEL_COMMON_THRESHOLD_CONFIG_T *pstConf = (AX_SKEL_COMMON_THRESHOLD_CONFIG_T *)pstConfig->pstItems[i].pstrValue; + ALOGI("SKEL get %s : %f", pstConfig->pstItems[i].pstrType, pstConf->fValue); + } else { + ALOGE("SKEL %s size(%d) no match", pstConfig->pstItems[i].pstrType, pstConfig->pstItems[i].nValueSize); + } + } + // cmd: "track_enable", value_type: AX_SKEL_COMMON_ENABLE_CONFIG_S * + else if (strcmp(pstConfig->pstItems[i].pstrType, "track_enable") == 0) { + if (pstConfig->pstItems[i].nValueSize == sizeof(AX_SKEL_COMMON_ENABLE_CONFIG_T)) { + AX_SKEL_COMMON_ENABLE_CONFIG_T *pstConf = (AX_SKEL_COMMON_ENABLE_CONFIG_T *)pstConfig->pstItems[i].pstrValue; + ALOGI("SKEL get %s : %d", pstConfig->pstItems[i].pstrType, pstConf->bEnable); + } else { + ALOGE("SKEL %s size(%d) no match", pstConfig->pstItems[i].pstrType, pstConfig->pstItems[i].nValueSize); + } + } + // cmd: "push_enable", value_type: AX_SKEL_COMMON_ENABLE_CONFIG_S * + else if (strcmp(pstConfig->pstItems[i].pstrType, "push_enable") == 0) { + if (pstConfig->pstItems[i].nValueSize == sizeof(AX_SKEL_COMMON_ENABLE_CONFIG_T)) { + AX_SKEL_COMMON_ENABLE_CONFIG_T *pstConf = (AX_SKEL_COMMON_ENABLE_CONFIG_T *)pstConfig->pstItems[i].pstrValue; + ALOGI("SKEL get %s : %d", pstConfig->pstItems[i].pstrType, pstConf->bEnable); + } else { + ALOGE("SKEL %s size(%d) no match", pstConfig->pstItems[i].pstrType, pstConfig->pstItems[i].nValueSize); + } + } + // cmd: "target_config", value_type: AX_SKEL_TARGET_CONFIG_T * + else if (strcmp(pstConfig->pstItems[i].pstrType, "target_config") == 0) { + if (pstConfig->pstItems[i].nValueSize == sizeof(AX_SKEL_TARGET_CONFIG_T)) { + AX_SKEL_TARGET_CONFIG_T *pstConf = (AX_SKEL_TARGET_CONFIG_T *)pstConfig->pstItems[i].pstrValue; + if (pstConf->pstItems) { + for (AX_U32 j = 0; j < pstConf->nSize; j ++) { + if (pstConf->pstItems[j].pstrObjectCategory) { + ALOGI("SKEL set %s: [%d]%s", pstConfig->pstItems[i].pstrType, j, pstConf->pstItems[j].pstrObjectCategory); + } + } + } + else { + ALOGE("SKEL cmd: %s invalid param", pstConfig->pstItems[i].pstrType); + } + } else { + ALOGE("SKEL %s size(%d) no match", pstConfig->pstItems[i].pstrType, pstConfig->pstItems[i].nValueSize); + } + } + // cmd: "push_target_config", value_type: AX_SKEL_TARGET_CONFIG_S * + else if (strcmp(pstConfig->pstItems[i].pstrType, "push_target_config") == 0) { + if (pstConfig->pstItems[i].nValueSize == sizeof(AX_SKEL_TARGET_CONFIG_T)) { + AX_SKEL_TARGET_CONFIG_T *pstConf = (AX_SKEL_TARGET_CONFIG_T *)pstConfig->pstItems[i].pstrValue; + if (pstConf->pstItems) { + for (AX_U32 j = 0; j < pstConf->nSize; j ++) { + if (pstConf->pstItems[j].pstrObjectCategory) { + ALOGI("SKEL set %s: [%d]%s", pstConfig->pstItems[i].pstrType, j, pstConf->pstItems[j].pstrObjectCategory); + } + } + } + else { + ALOGE("SKEL cmd: %s invalid param", pstConfig->pstItems[i].pstrType); + } + } else { + ALOGE("SKEL %s size(%d) no match", pstConfig->pstItems[i].pstrType, pstConfig->pstItems[i].nValueSize); + } + } + // cmd: "analyzer_attr_config", value_type: AX_SKEL_ANALYZER_CONFIG_T * + else if (strcmp(pstConfig->pstItems[i].pstrType, "analyzer_attr_config") == 0) { + if (pstConfig->pstItems[i].nValueSize == sizeof(AX_SKEL_ANALYZER_CONFIG_T)) { + AX_SKEL_ANALYZER_CONFIG_T *pstConf = (AX_SKEL_ANALYZER_CONFIG_T *)pstConfig->pstItems[i].pstrValue; + if (pstConf->peItems) { + for (AX_U32 j = 0; j < pstConf->nSize; j ++) { + ALOGI("SKEL set %s: [%d]%d", pstConfig->pstItems[i].pstrType, j, pstConf->peItems[j]); + } + } + else { + ALOGE("SKEL cmd: %s invalid param", pstConfig->pstItems[i].pstrType); + } + } else { + ALOGE("SKEL %s size(%d) no match", pstConfig->pstItems[i].pstrType, pstConfig->pstItems[i].nValueSize); + } + } + // cmd: "venc_attr_config", value_type: AX_SKEL_COMMON_THRESHOLD_CONFIG_S * + else if (strcmp(pstConfig->pstItems[i].pstrType, "venc_attr_config") == 0) { + if (pstConfig->pstItems[i].nValueSize == sizeof(AX_SKEL_COMMON_THRESHOLD_CONFIG_T)) { + AX_SKEL_COMMON_THRESHOLD_CONFIG_T *pstConf = (AX_SKEL_COMMON_THRESHOLD_CONFIG_T *)pstConfig->pstItems[i].pstrValue; + ALOGI("SKEL set %s: %d", pstConfig->pstItems[i].pstrType, (AX_U32)pstConf->fValue); + } else { + ALOGE("SKEL %s size(%d) no match", pstConfig->pstItems[i].pstrType, pstConfig->pstItems[i].nValueSize); + } + } + // cmd: "push_attr_always", value_type: AX_SKEL_COMMON_ENABLE_CONFIG_S * + else if (strcmp(pstConfig->pstItems[i].pstrType, "push_attr_always") == 0) { + if (pstConfig->pstItems[i].nValueSize == sizeof(AX_SKEL_COMMON_ENABLE_CONFIG_T)) { + AX_SKEL_COMMON_ENABLE_CONFIG_T *pstConf = (AX_SKEL_COMMON_ENABLE_CONFIG_T *)pstConfig->pstItems[i].pstrValue; + ALOGI("SKEL set %s: %d", pstConfig->pstItems[i].pstrType, pstConf->bEnable); + } else { + ALOGE("SKEL %s size(%d) no match", pstConfig->pstItems[i].pstrType, pstConfig->pstItems[i].nValueSize); + } + } + else { + ALOGE("SKEL cmd: %s not support", pstConfig->pstItems[i].pstrType); + } + } + } + } + + return 0; +} + +FILE* LoadFile(const AX_CHAR *pFile, AX_U64 *pLen) +{ + /* Reading input file */ + FILE *f_in = fopen(pFile, "rb"); + + if (f_in) { + if (pLen) { + fseeko(f_in, 0L, SEEK_END); + AX_U64 nFileSize = ftello(f_in); + rewind(f_in); + + *pLen = (AX_U64)nFileSize; + } + } + + return f_in; +} + +int ReLoadFile(FILE* pFile) +{ + if (pFile) { + rewind(pFile); + return 0; + } + + return -1; +} + +int NV12ToStrideNV12(AX_U64 nSrcPhyAddr, + AX_VOID *pSrcVirAddr, + AX_U32 nSrcSize, + AX_U32 nSrcStride, + AX_U32 nSrcHeight, + AX_U64 nDstPhyAddr, + AX_VOID *pDstVirAddr, + AX_U32 nDstSize, + AX_U32 nDstStride, + AX_U32 nDstHeight + ) { + AX_U64 nStartTime = get_tick_count(); + + // src check + if (!pSrcVirAddr) { + return -1; + } + + if (nSrcSize != nSrcStride * nSrcHeight * 3 /2) { + return -1; + } + + // dst check + if (!pDstVirAddr) { + return -1; + } + + if (nDstSize != nDstStride * nDstHeight * 3 /2) { + return -1; + } + + if (nDstSize < nSrcSize) { + return -1; + } + + if (nDstStride < nSrcStride) { + return -1; + } + + if (nDstHeight != nSrcHeight) { + return -1; + } + + AX_VOID *src = pSrcVirAddr; + AX_VOID *dst = pDstVirAddr; + for(AX_U32 i = 0; i < nSrcHeight * 3 / 2; i++) { + memcpy(dst, src, nSrcStride); + src += nSrcStride; + dst += nDstStride; + } + + AX_U64 nProcessElasped = get_tick_count() - nStartTime; + + ALOGD("NV12ToStrideNV12 %dx%d=>%dx%d elapse: %lld ms", nSrcStride, nSrcHeight, nDstStride, nDstHeight, nProcessElasped); + + return 0; +} + +int LoadFileToMem(FILE *pFile, AX_U64 nPhyAddr, AX_VOID *pVirAddr, AX_S32 nSize) +{ + AX_S32 nReadSize = 0; + + if (pFile) { + if (nPhyAddr != 0 && pVirAddr) { + memset((AX_U8 *)pVirAddr, 0x00, nSize); + nReadSize = fread((AX_U8 *)pVirAddr, 1, nSize, pFile); + } + else { + fseeko(pFile, nSize, SEEK_CUR); + } + } + + return nReadSize; +} + +int DecodeJpeg(FILE* InputFileHandle, AX_U64 OneYUVDataPhy, AX_VOID* OneYUVDataVir, AX_U32 nWidth, AX_U32 nHeight) +{ + SAMPLE_INPUT_FILE_INFO_T stStreamInfo; + SAMPLE_STREAM_BUF_T stStreamBuf; + size_t nReadLen = 0; + AX_U64 streamPhyAddr = 0; + AX_VOID *pStreamVirAddr = NULL; + AX_VDEC_DEC_ONE_FRM_T decOneFrmParam; + size_t nFileSize = 0; + AX_U32 heightAlign = 0; + AX_U32 frmStride = 0; + frmStride = AX_COMM_ALIGN(nWidth * 8, AX_VDEC_WIDTH_ALIGN * 8) / 8; + heightAlign = ALIGN_UP(nHeight, 16); + AX_U32 nFrameSize = heightAlign * frmStride * 3 / 2; + + memset(&stStreamInfo, 0, sizeof(SAMPLE_INPUT_FILE_INFO_T)); + memset(&stStreamBuf, 0, sizeof(SAMPLE_STREAM_BUF_T)); + memset(&decOneFrmParam, 0, sizeof(AX_VDEC_DEC_ONE_FRM_T)); + + rewind(InputFileHandle); + fseek(InputFileHandle, 0, SEEK_END); + nFileSize = (size_t)ftello(InputFileHandle); + + stStreamInfo.fInput = InputFileHandle; + stStreamInfo.sFileSize = nFileSize; + + stStreamBuf.uBufSize = ((AX_U32)nFileSize) > STREAM_BUFFER_MAX_SIZE ? STREAM_BUFFER_MAX_SIZE : nFileSize; + int ret = AX_SYS_MemAlloc(&streamPhyAddr, (AX_VOID **)&pStreamVirAddr, + stStreamBuf.uBufSize, 0x100, (AX_S8 *)"vdec_input_stream"); + if (ret != AX_SUCCESS) { + ALOGE("AX_SYS_MemAlloc FAILED! uBufSize:0x%x ret:0x%x\n", + stStreamBuf.uBufSize, ret); + return -1; + } + + stStreamBuf.tBufAddr.pVirAddr = pStreamVirAddr; + stStreamBuf.tBufAddr.u64PhyAddr = streamPhyAddr; + + ret = StreamParserReadFrameJpeg(&stStreamInfo, &stStreamBuf, &nReadLen); + if (0 != ret) { + ALOGE("StreamParserReadFrameJpeg failed! ret = 0x%x", ret); + AX_SYS_MemFree(streamPhyAddr, pStreamVirAddr); + return -1; + } + + if (!nReadLen) { + ALOGE("read jpeg frame FAILED!\n"); + AX_SYS_MemFree(streamPhyAddr, pStreamVirAddr); + ret = AX_ERR_VDEC_STRM_ERROR; + return ret; + } + + decOneFrmParam.stStream.pu8Addr = (AX_U8*)stStreamBuf.tBufAddr.pVirAddr; + decOneFrmParam.stStream.u64PhyAddr = stStreamBuf.tBufAddr.u64PhyAddr; + decOneFrmParam.stStream.u32StreamPackLen = (AX_U32)nReadLen; + + decOneFrmParam.stFrame.u64VirAddr[0] = (AX_ULONG)OneYUVDataVir; + decOneFrmParam.stFrame.u64VirAddr[1] = (AX_ULONG)OneYUVDataVir + frmStride * heightAlign; + decOneFrmParam.stFrame.u64PhyAddr[0] = OneYUVDataPhy; + decOneFrmParam.stFrame.u64PhyAddr[1] = OneYUVDataPhy + frmStride * heightAlign; + decOneFrmParam.stFrame.u32FrameSize = nFrameSize; + + ret = AX_VDEC_JpegDecodeOneFrame(&decOneFrmParam); + if (ret != AX_SUCCESS) { + ALOGE("AX_VDEC_JpegDecodeOneFrame FAILED! ret:0x%x %s\n", + ret, SampleVdecRetStr(ret)); + AX_SYS_MemFree(streamPhyAddr, pStreamVirAddr); + return ret; + } + + AX_SYS_MemFree(streamPhyAddr, pStreamVirAddr); + + return 0; +} + +int LoadFileToMemExt(const AX_CHAR *pFile, AX_U64 *pPhyAddr, AX_VOID **ppVirAddr, AX_U32 *pLen) +{ + /* Reading input file */ + FILE *f_in = fopen(pFile, "rb"); + if (f_in == NULL) { + ALOGE("Unable to open input file\n"); + return -1; + } + + /* file i/o pointer to full */ + fseek(f_in, 0L, SEEK_END); + AX_U32 nFileSize = ftell(f_in); + rewind(f_in); + + if (pPhyAddr && ppVirAddr) { + AX_U64 nPhyAddr = 0; + AX_VOID *pVirAddr = NULL; + + // pVirAddr = (AX_VOID *)malloc(nFileSize); + AX_S32 nRet = AX_SYS_MemAlloc(&nPhyAddr, (AX_VOID **)&pVirAddr, nFileSize, 128, (AX_S8 *)"SKEL_TEST"); + + if (nRet != 0) { + fclose(f_in); + ALOGE("AX_SYS_MemAlloc failed"); + return -1; + } + + fread((AX_U8 *)pVirAddr, nFileSize, 1, f_in); + + *pPhyAddr = nPhyAddr; + *ppVirAddr = pVirAddr; + } + + if (pLen) { + *pLen = nFileSize; + } + + fclose(f_in); + + return 0; +} + +int EncodeOneFrameToJpeg(const AX_CHAR *dstFile, AX_U32 nStride, AX_U32 nWidth, AX_U32 nHeight, AX_U64 nPhyAddr, AX_VOID *pVirAddr, AX_U32 nLen) { + AX_S32 s32Ret = AX_SUCCESS; + + AX_U32 frameSize = nLen; + AX_JPEG_ENCODE_ONCE_PARAMS_T stJpegEncodeOnceParam; + memset(&stJpegEncodeOnceParam, 0, sizeof(stJpegEncodeOnceParam)); + + AX_U64 outPhyAddr = 0; + AX_VOID *outVirAddr = NULL; + + s32Ret = AX_SYS_MemAlloc(&outPhyAddr, &outVirAddr, frameSize, 128, (AX_S8 *)"SKEL-VENC"); + if (s32Ret) { + ALOGE("alloc mem err, size(%d).", frameSize); + return -1; + } + + // output + stJpegEncodeOnceParam.u32OutBufSize = frameSize; + stJpegEncodeOnceParam.ulPhyAddr = outPhyAddr; + stJpegEncodeOnceParam.pu8Addr = (AX_U8 *)outVirAddr; + + // input + stJpegEncodeOnceParam.stJpegParam.u32Qfactor = 90; + stJpegEncodeOnceParam.u32Width = nWidth; + stJpegEncodeOnceParam.u32Height = nHeight; + stJpegEncodeOnceParam.enImgFormat = AX_FORMAT_YUV420_SEMIPLANAR; + stJpegEncodeOnceParam.u32PicStride[0] = nStride; + stJpegEncodeOnceParam.u32PicStride[1] = stJpegEncodeOnceParam.u32PicStride[0]; + stJpegEncodeOnceParam.u32PicStride[2] = 0; + + stJpegEncodeOnceParam.u64PhyAddr[0] = nPhyAddr; + stJpegEncodeOnceParam.u64PhyAddr[1] = stJpegEncodeOnceParam.u64PhyAddr[0] + stJpegEncodeOnceParam.u32PicStride[0] * stJpegEncodeOnceParam.u32Height; + stJpegEncodeOnceParam.u64PhyAddr[2] = 0; + + stJpegEncodeOnceParam.u64VirAddr[0] = (AX_ULONG)pVirAddr; + stJpegEncodeOnceParam.u64VirAddr[1] = stJpegEncodeOnceParam.u64VirAddr[0] + stJpegEncodeOnceParam.u32PicStride[0] * stJpegEncodeOnceParam.u32Height; + stJpegEncodeOnceParam.u64VirAddr[2] = 0; + + s32Ret = AX_VENC_JpegEncodeOneFrame(&stJpegEncodeOnceParam); + if (AX_SUCCESS != s32Ret) { + ALOGE("AX_VENC_JpegEncodeOneFrame fail, ret=0x%x", s32Ret); + s32Ret = -1; + goto JENC_EXIT; + } + +JENC_EXIT: + if (0 == s32Ret && dstFile) { + FILE *fp_w = fopen(dstFile, "wb"); + + if (fp_w) { + ALOGN("\tWrite new JPG result image to file: %s", dstFile); + fwrite((AX_U8 *)stJpegEncodeOnceParam.pu8Addr, stJpegEncodeOnceParam.u32Len, 1, fp_w); + fclose(fp_w); + } + } + + if (outPhyAddr && (NULL != outVirAddr)) { + AX_SYS_MemFree(outPhyAddr, outVirAddr); + } + + return s32Ret; +} + +AX_BOOL FrameSkipCtrl(AX_S32 nSrcFrameRate, AX_S32 nDstFrameRate, AX_S32 nFrameSeqNum) { + if (nFrameSeqNum < 1) { + nFrameSeqNum = 1; + } + + if (nSrcFrameRate == nDstFrameRate) { + return AX_FALSE; + } + + if (nDstFrameRate > nSrcFrameRate) { + return AX_FALSE; + } + + if ((nFrameSeqNum * nDstFrameRate / (nSrcFrameRate)) > ((nFrameSeqNum - 1) * nDstFrameRate / (nSrcFrameRate))) { + return AX_FALSE; + } else { + return AX_TRUE; + } +} + +AX_S32 main(AX_S32 argc, AX_CHAR *argv[]) { + AX_S32 nRet = 0; + AX_S32 c; + AX_S32 isExit = 0; + AX_BOOL bJpgFile = AX_FALSE; + FILE *InputFileHandle = NULL; + const AX_CHAR *InputFile = NULL; + const AX_CHAR *InputResolution = NULL; + AX_S32 InputFileFrameCnt = 1; + const AX_CHAR *ReWritePath = NULL; + const AX_CHAR *SaveResultPath = NULL; + const AX_CHAR *ModelsPath = NULL; + FILE *fpResultFile = NULL; + AX_S32 nRepeatTimes = 1; + AX_S32 nPPL = AX_SKEL_PPL_HVCP; + AX_S32 nDetectType = 2; + AX_S32 nPushStrategy = 3; + AX_S32 nNpuType = 0; + AX_S32 nInterval = 0; + AX_U32 nStride = 1920; + AX_U32 nWidth = 1920; + AX_U32 nHeight = 1080; + AX_U32 nJencBufSize = 0; + AX_U32 nFrameDepth = 1; + AX_U32 nOneSize = 0; + AX_U64 OneYUVDataPhy = 0; + AX_VOID *OneYUVDataVir = NULL; + AX_U32 nFrameSize = nStride * nHeight * 3 / 2; + AX_U32 nCacheListDepth = 1; + AX_S32 nSrcFrameRate = 25; + AX_S32 nDstFrameRate = 25; + AX_VOID *YUVDataVir = NULL; + AX_U64 YUVDataPhy = 0; + AX_VOID *YUVDataWrVir = NULL; + AX_U64 YUVDataWrPhy = 0; + AX_SKEL_HANDLE pHandle = NULL; + AX_SKEL_FRAME_T stFrame = {0}; + AX_SKEL_RESULT_T *pstResult = NULL; + AX_U64 nFileSize = 0; + AX_U64 nStartTime = 0; + AX_U64 nInitElasped = 0; + AX_U64 nCreateElasped = 0; + AX_U64 nProcessElasped = 0; + AX_U64 nResultElasped = 0; + AX_U64 nResultElaspedMin = (AX_U64)-1; + AX_U64 nResultElaspedMax = 0; + AX_U64 nResultElaspedTotal = 0; + AX_F32 fConfidence = 0.0; + // AX_U32 nHumantracksize = 0; + // AX_U32 nVehicletracksize = 0; + // AX_U32 nCycletracksize = 0; + AX_U64 nSkelFrameId = 1; + +#if defined(SAMPLE_SKEL_BUILD_VERSION) + printf("SKEL sample: %s build: %s %s\n", SAMPLE_SKEL_BUILD_VERSION, __DATE__, __TIME__); +#endif + + while ((c = getopt(argc, argv, "i:r:I:w:o:m:t:d:u:p:j:v:c:N:H:V:C:h::")) != -1) { + isExit = 0; + switch (c) { + case 'i': + InputFile = (const AX_CHAR *)optarg; + break; + case 'r': + InputResolution = (const AX_CHAR *)optarg; + break; + case 'I': + nInterval = atoi(optarg); + break; + case 'w': + ReWritePath = (const AX_CHAR *)optarg; + break; + case 'o': + SaveResultPath = (const AX_CHAR *)optarg; + break; + case 'm': + ModelsPath = (const AX_CHAR *)optarg; + break; + case 't': + nRepeatTimes = atoi(optarg); + break; + case 'd': + nDetectType = atoi(optarg); + break; + case 'u': + nPushStrategy = atoi(optarg); + break; + case 'N': + nNpuType = atoi(optarg); + break; + case 'p': + nPPL = atoi(optarg); + break; + case 'j': + nJencBufSize = atoi(optarg); + break; + case 'c': + fConfidence = atof(optarg); + break; + // case 'H': + // nHumantracksize = atoi(optarg); + // break; + // case 'V': + // nVehicletracksize = atoi(optarg); + // break; + // case 'C': + // nCycletracksize = atoi(optarg); + // break; + case 'v': + log_level = atoi(optarg); + break; + case 'h': + isExit = 1; + break; + case 'D': + nCacheListDepth = atoi(optarg); + break; + default: + isExit = 1; + break; + } + } + + if (isExit || !InputFile || !InputResolution || (nPPL < AX_SKEL_PPL_HVCP) || (nPPL > AX_SKEL_PPL_MAX) + || (log_level < 0 || log_level >= SKEL_LOG_MAX) + || (fConfidence < 0 || fConfidence > 1) + || (nDetectType < 0 || nDetectType > 2) + || (nPushStrategy < 1 || nPushStrategy > 3) + || (nNpuType > 3)) { + ShowUsage(); + exit(0); + } + + if (InputFile) { + AX_U32 nInputFileLen = strlen(InputFile); + + if (nInputFileLen > 4 && (strcasecmp(&InputFile[nInputFileLen - 4], ".jpg") == 0)) { + bJpgFile = AX_TRUE; + } + } + + if (nRepeatTimes <= 0) { + nRepeatTimes = 1; + } + + if (nInterval < 0) { + nInterval = 0; + } + if (nCacheListDepth == 0) { + nCacheListDepth = 1; + } + nInterval = nInterval * 1000; + + if (access(InputFile, 0) != 0) { + ALOGE("%s not exist", InputFile); + exit(0); + } + + // clear output + if (SaveResultPath) { + RUN_COMMAND("rm -rf %s", SaveResultPath); + RUN_COMMAND("mkdir -p %s", SaveResultPath); + RUN_COMMAND("mkdir -p %s/%s", SaveResultPath, SKEL_SAMPLE_OUTPUT_BODY_PATH); + RUN_COMMAND("mkdir -p %s/%s", SaveResultPath, SKEL_SAMPLE_OUTPUT_VEHICLE_PATH); + RUN_COMMAND("mkdir -p %s/%s", SaveResultPath, SKEL_SAMPLE_OUTPUT_CYCLE_PATH); + RUN_COMMAND("mkdir -p %s/%s", SaveResultPath, SKEL_SAMPLE_OUTPUT_FACE_PATH); + RUN_COMMAND("mkdir -p %s/%s", SaveResultPath, SKEL_SAMPLE_OUTPUT_PLATE_PATH); + } + + if (ReWritePath) { + RUN_COMMAND("rm -rf %s", ReWritePath); + RUN_COMMAND("mkdir -p %s", ReWritePath); + } + + if (InputResolution) { + AX_CHAR *temp_p = strstr(InputResolution, "x"); + + if (!temp_p || strlen(temp_p) <= 1) { + ShowUsage(); + exit(0); + } + + nWidth = atoi(InputResolution); + nStride = nWidth; + nHeight = atoi(temp_p + 1); + } + + nRet = AX_SYS_Init(); + if (0 != nRet) { + ALOGE("AX_SYS_Init() fail, ret = 0x%x", nRet); + exit(0); + } + + nRet = AX_IVPS_Init(); + + ALOGI("AX_IVPS_Init nRet = 0x%x", nRet); + + AX_VENC_MOD_ATTR_T stVencModAttr; + memset(&stVencModAttr, 0x00, sizeof(stVencModAttr)); + stVencModAttr.enVencType = AX_VENC_MULTI_ENCODER; + stVencModAttr.stModThdAttr.u32TotalThreadNum = 1; + stVencModAttr.stModThdAttr.bExplicitSched = AX_FALSE; + nRet = AX_VENC_Init(&stVencModAttr); + if (AX_SUCCESS != nRet) { + ALOGE("AX_VENC_Init FAILED! ret:0x%x\n", nRet); + goto EXIT0; + } + + ALOGI("AX_VENC_Init nRet = 0x%x", nRet); + + nRet = AX_VDEC_Init(NULL); + if (AX_SUCCESS != nRet) { + ALOGE("AX_VDEC_Init FAILED! ret:0x%x\n", nRet); + goto EXIT0; + } + + ALOGI("AX_VDEC_Init nRet = 0x%x", nRet); + + // init engine + AX_ENGINE_NPU_ATTR_T npu_attr; + memset(&npu_attr, 0, sizeof(npu_attr)); +#if defined(CHIP_AX650) + if (nNpuType == 0) { + npu_attr.eHardMode = AX_ENGINE_VIRTUAL_NPU_DISABLE; + } + else if (nNpuType >= 1 && nNpuType <= 4) { + npu_attr.eHardMode = AX_ENGINE_VIRTUAL_NPU_STD; + } + else if (nNpuType >= 5 && nNpuType <= 7) { + npu_attr.eHardMode = AX_ENGINE_VIRTUAL_NPU_BIG_LITTLE; + } +#elif defined(CHIP_AX620E) + if (nNpuType == 0) { + npu_attr.eHardMode = AX_ENGINE_VIRTUAL_NPU_DISABLE; + } + else { + npu_attr.eHardMode = AX_ENGINE_VIRTUAL_NPU_ENABLE; + } +#else + // #error "NO CHIP SELECTED." +#endif + + nRet = AX_ENGINE_Init(&npu_attr); + if (0 != nRet) { + ALOGE("AX_NPU_SDK_EX_Init_with_attr() fail, ret = 0x%x", nRet); + goto EXIT0; + } + + nOneSize = nWidth * nHeight * 3 / 2; + nFrameSize = nStride * nHeight * 3 / 2; + + InputFileHandle = LoadFile(InputFile, &nFileSize); + + if (bJpgFile) { + InputFileFrameCnt = 1; + } + else { + if (!InputFileHandle + || (nFileSize % nOneSize) != 0) { + ALOGE("%s file is not %dx%d", InputFile, nWidth, nHeight); + goto EXIT1; + } + + InputFileFrameCnt = nFileSize / nOneSize; + } + + + if (nWidth%2 == 1 + || nHeight%2 == 1) { + ALOGE("wxh(%dx%d) should be even", nWidth, nHeight); + goto EXIT1; + } + + // YUVDataWrVir = (AX_VOID *)malloc(nFileSize); + nRet = AX_SYS_MemAlloc(&YUVDataWrPhy, &YUVDataWrVir, nFrameSize, 128, (const AX_S8 *)"SKEL_TEST"); + + if (!YUVDataWrVir) { + ALOGE("malloc fail nRet=0x%x", nRet); + goto EXIT1; + } + + if (SaveResultPath) { + AX_CHAR szPath[512] = {0}; + snprintf(szPath, 511, "%s/%s", SaveResultPath, SKEL_SAMPLE_OUTPUT_LOG_FILE); + fpResultFile = fopen(szPath, "a+"); + + if (!fpResultFile) { + ALOGE("%s file not exist", szPath); + goto EXIT1; + } + } + + nStartTime = get_tick_count(); + + AX_SKEL_INIT_PARAM_T stInitParam = {0}; + + if (ModelsPath) { + stInitParam.pStrModelDeploymentPath = ModelsPath; + } + else { + stInitParam.pStrModelDeploymentPath = "/opt/etc/skelModels"; + } + + nRet = AX_SKEL_Init(&stInitParam); + + nInitElasped = get_tick_count() - nStartTime; + + if (0 != nRet) { + ALOGE("SKEL init fail, ret = 0x%x", nRet); + + goto EXIT1; + } + + // get version + { + const AX_SKEL_VERSION_INFO_T *pstVersion = NULL; + + nRet = AX_SKEL_GetVersion(&pstVersion); + + if (0 != nRet) { + ALOGI("SKEL get version fail, ret = 0x%x", nRet); + + if (pstVersion) { + AX_SKEL_Release((AX_VOID *)pstVersion); + } + goto EXIT1; + } + + ALOGI("SKEL version: %s", pstVersion->pstrVersion); + + if (pstVersion) { + AX_SKEL_Release((AX_VOID *)pstVersion); + } + } + + // get capability + { + const AX_SKEL_CAPABILITY_T *pstCapability = NULL; + + nRet = AX_SKEL_GetCapability(&pstCapability); + + if (0 != nRet) { + ALOGI("SKEL get capability fail, ret = 0x%x", nRet); + + if (pstCapability) { + AX_SKEL_Release((AX_VOID *)pstCapability); + } + goto EXIT1; + } + + for (AX_U32 i = 0; i < pstCapability->nPPLConfigSize; i++) { + ALOGI("SKEL capability[%d]: (ePPL: %d, PPLConfigKey: %s)", i, pstCapability->pstPPLConfig[i].ePPL, + pstCapability->pstPPLConfig[i].pstrPPLConfigKey); + } + + if (pstCapability) { + AX_SKEL_Release((AX_VOID *)pstCapability); + } + } + + AX_SKEL_HANDLE_PARAM_T stHandleParam = {0}; + + stHandleParam.ePPL = (AX_SKEL_PPL_E)nPPL; + stHandleParam.nFrameDepth = nFrameDepth; + stHandleParam.nFrameCacheDepth = nCacheListDepth; + stHandleParam.nIoDepth = 0; + stHandleParam.nWidth = nWidth; + stHandleParam.nHeight = nHeight; + + // config settings (if need) + AX_SKEL_CONFIG_T stConfig = {0}; + AX_SKEL_CONFIG_ITEM_T stItems[16] = {0}; + AX_U8 itemIndex = 0; + stConfig.nSize = 0; + stConfig.pstItems = &stItems[0]; + + // venc_attr_config + // default will be system definition: w*h*3/8 + AX_SKEL_COMMON_THRESHOLD_CONFIG_T stVencAttrConfigThreshold = {0}; + if (nJencBufSize > 0) { + stConfig.pstItems[itemIndex].pstrType = (AX_CHAR *)"venc_attr_config"; + stVencAttrConfigThreshold.fValue = (AX_F32) nJencBufSize; + stConfig.pstItems[itemIndex].pstrValue = (AX_VOID *)&stVencAttrConfigThreshold; + stConfig.pstItems[itemIndex].nValueSize = sizeof(AX_SKEL_COMMON_THRESHOLD_CONFIG_T); + itemIndex++; + } + + AX_SKEL_COMMON_THRESHOLD_CONFIG_T stTrackEnableThreshold = {0}; + AX_SKEL_COMMON_THRESHOLD_CONFIG_T stPushEnableThreshold = {0}; + + // detect only (disable track + disable push) + if (nDetectType == 0) { + // track_disable + stConfig.pstItems[itemIndex].pstrType = (AX_CHAR *)"track_enable"; + stTrackEnableThreshold.fValue = 0; + stConfig.pstItems[itemIndex].pstrValue = (AX_VOID *)&stTrackEnableThreshold; + stConfig.pstItems[itemIndex].nValueSize = sizeof(AX_SKEL_COMMON_THRESHOLD_CONFIG_T); + itemIndex++; + + // push_disable + stConfig.pstItems[itemIndex].pstrType = (AX_CHAR *)"push_enable"; + stPushEnableThreshold.fValue = 0; + stConfig.pstItems[itemIndex].pstrValue = (AX_VOID *)&stPushEnableThreshold; + stConfig.pstItems[itemIndex].nValueSize = sizeof(AX_SKEL_COMMON_THRESHOLD_CONFIG_T); + itemIndex++; + } + // detect + track (disable push) + else if (nDetectType == 1) { + // push_disable + stConfig.pstItems[itemIndex].pstrType = (AX_CHAR *)"push_enable"; + stPushEnableThreshold.fValue = 0; + stConfig.pstItems[itemIndex].pstrValue = (AX_VOID *)&stPushEnableThreshold; + stConfig.pstItems[itemIndex].nValueSize = sizeof(AX_SKEL_COMMON_THRESHOLD_CONFIG_T); + itemIndex++; + } + + if (itemIndex > 0) { + stConfig.nSize = itemIndex; + stHandleParam.stConfig = stConfig; + } + + // default NPU + if (nNpuType == 0 || nNpuType == 1) { + stHandleParam.nNpuType = (AX_S32)AX_SKEL_NPU_DEFAULT; + } + // STD-NPU + else if (nNpuType == 2) { + stHandleParam.nNpuType = (AX_S32)AX_SKEL_STD_VNPU_1; + } + else if (nNpuType == 3) { + stHandleParam.nNpuType = (AX_S32)AX_SKEL_STD_VNPU_2; + } + + nStartTime = get_tick_count(); + + nRet = AX_SKEL_Create(&stHandleParam, &pHandle); + + nCreateElasped = get_tick_count() - nStartTime; + + if (0 != nRet) { + ALOGE("SKEL Create Handle fail, ret = 0x%x", nRet); + + goto EXIT2; + } + + if (fConfidence == 0) { + fConfidence = 0.5; + } + + // set config + { + AX_SKEL_CONFIG_T stConfig = {0}; + AX_SKEL_CONFIG_ITEM_T stItems[64] = {0}; + AX_U8 itemIndex = 0; + stConfig.nSize = 0; + stConfig.pstItems = &stItems[0]; +#if 0 + // body_max_target_count + stConfig.pstItems[itemIndex].pstrType = (AX_CHAR *)"body_max_target_count"; + AX_SKEL_COMMON_THRESHOLD_CONFIG_T stBodyMaxTargetCount = {0}; + stBodyMaxTargetCount.fValue = (AX_F32)nHumantracksize; + stConfig.pstItems[itemIndex].pstrValue = (AX_VOID *)&stBodyMaxTargetCount; + stConfig.pstItems[itemIndex].nValueSize = sizeof(AX_SKEL_COMMON_THRESHOLD_CONFIG_T); + itemIndex++; + + // vehicle_max_target_count + stConfig.pstItems[itemIndex].pstrType = (AX_CHAR *)"vehicle_max_target_count"; + AX_SKEL_COMMON_THRESHOLD_CONFIG_T stVehicleMaxTargetCount = {0}; + stVehicleMaxTargetCount.fValue = (AX_F32)nVehicletracksize; + stConfig.pstItems[itemIndex].pstrValue = (AX_VOID *)&stVehicleMaxTargetCount; + stConfig.pstItems[itemIndex].nValueSize = sizeof(AX_SKEL_COMMON_THRESHOLD_CONFIG_T); + itemIndex++; + + // cycle_max_target_count + stConfig.pstItems[itemIndex].pstrType = (AX_CHAR *)"cycle_max_target_count"; + AX_SKEL_COMMON_THRESHOLD_CONFIG_T stCycleMaxTargetCount = {0}; + stCycleMaxTargetCount.fValue = (AX_F32)nCycletracksize; + stConfig.pstItems[itemIndex].pstrValue = (AX_VOID *)&stCycleMaxTargetCount; + stConfig.pstItems[itemIndex].nValueSize = sizeof(AX_SKEL_COMMON_THRESHOLD_CONFIG_T); + itemIndex++; +#endif +#if 0 + // body_confidence + stConfig.pstItems[itemIndex].pstrType = (AX_CHAR *)"body_confidence"; + AX_SKEL_COMMON_THRESHOLD_CONFIG_T stBodyConfidence = {0}; + stBodyConfidence.fValue = fConfidence; + stConfig.pstItems[itemIndex].pstrValue = (AX_VOID *)&stBodyConfidence; + stConfig.pstItems[itemIndex].nValueSize = sizeof(AX_SKEL_COMMON_THRESHOLD_CONFIG_T); + itemIndex++; + + // face_confidence + stConfig.pstItems[itemIndex].pstrType = (AX_CHAR *)"face_confidence"; + AX_SKEL_COMMON_THRESHOLD_CONFIG_T stFaceConfidence = {0}; + stFaceConfidence.fValue = fConfidence; + stConfig.pstItems[itemIndex].pstrValue = (AX_VOID *)&stFaceConfidence; + stConfig.pstItems[itemIndex].nValueSize = sizeof(AX_SKEL_COMMON_THRESHOLD_CONFIG_T); + itemIndex++; + + // vehicle_confidence + stConfig.pstItems[itemIndex].pstrType = (AX_CHAR *)"vehicle_confidence"; + AX_SKEL_COMMON_THRESHOLD_CONFIG_T stVehicleConfidence = {0}; + stVehicleConfidence.fValue = fConfidence; + stConfig.pstItems[itemIndex].pstrValue = (AX_VOID *)&stVehicleConfidence; + stConfig.pstItems[itemIndex].nValueSize = sizeof(AX_SKEL_COMMON_THRESHOLD_CONFIG_T); + itemIndex++; + + // cycle_confidence + stConfig.pstItems[itemIndex].pstrType = (AX_CHAR *)"cycle_confidence"; + AX_SKEL_COMMON_THRESHOLD_CONFIG_T stCycleConfidence = {0}; + stCycleConfidence.fValue = fConfidence; + stConfig.pstItems[itemIndex].pstrValue = (AX_VOID *)&stCycleConfidence; + stConfig.pstItems[itemIndex].nValueSize = sizeof(AX_SKEL_COMMON_THRESHOLD_CONFIG_T); + itemIndex++; + + // plate_confidence + stConfig.pstItems[itemIndex].pstrType = (AX_CHAR *)"plate_confidence"; + AX_SKEL_COMMON_THRESHOLD_CONFIG_T stPlateConfidence = {0}; + stPlateConfidence.fValue = fConfidence; + stConfig.pstItems[itemIndex].pstrValue = (AX_VOID *)&stPlateConfidence; + stConfig.pstItems[itemIndex].nValueSize = sizeof(AX_SKEL_COMMON_THRESHOLD_CONFIG_T); + itemIndex++; +#endif + +#if 0 + // crop_encoder_qpLevel + stConfig.pstItems[itemIndex].pstrType = (AX_CHAR *)"crop_encoder_qpLevel"; + AX_SKEL_COMMON_THRESHOLD_CONFIG_T stCropEncoderQpLevelThreshold = {0}; + stCropEncoderQpLevelThreshold.fValue = 90; + stConfig.pstItems[itemIndex].pstrValue = (AX_VOID *)&stCropEncoderQpLevelThreshold; + stConfig.pstItems[itemIndex].nValueSize = sizeof(AX_SKEL_COMMON_THRESHOLD_CONFIG_T); + itemIndex++; +#endif + +#if 0 + // body_min_size + stConfig.pstItems[itemIndex].pstrType = (AX_CHAR *)"body_min_size"; + AX_SKEL_OBJECT_SIZE_FILTER_CONFIG_T stBodyMinSize = {0}; + stBodyMinSize.nWidth = 0; + stBodyMinSize.nHeight = 0; + stConfig.pstItems[itemIndex].pstrValue = (AX_VOID *)&stBodyMinSize; + stConfig.pstItems[itemIndex].nValueSize = sizeof(AX_SKEL_OBJECT_SIZE_FILTER_CONFIG_T); + itemIndex++; + + // face_min_size + stConfig.pstItems[itemIndex].pstrType = (AX_CHAR *)"face_min_size"; + AX_SKEL_OBJECT_SIZE_FILTER_CONFIG_T stFaceMinSize = {0}; + stFaceMinSize.nWidth = 0; + stFaceMinSize.nHeight = 0; + stConfig.pstItems[itemIndex].pstrValue = (AX_VOID *)&stFaceMinSize; + stConfig.pstItems[itemIndex].nValueSize = sizeof(AX_SKEL_OBJECT_SIZE_FILTER_CONFIG_T); + itemIndex++; + + // vehicle_min_size + stConfig.pstItems[itemIndex].pstrType = (AX_CHAR *)"vehicle_min_size"; + AX_SKEL_OBJECT_SIZE_FILTER_CONFIG_T stVehicleMinSize = {0}; + stVehicleMinSize.nWidth = 0; + stVehicleMinSize.nHeight = 0; + stConfig.pstItems[itemIndex].pstrValue = (AX_VOID *)&stVehicleMinSize; + stConfig.pstItems[itemIndex].nValueSize = sizeof(AX_SKEL_OBJECT_SIZE_FILTER_CONFIG_T); + itemIndex++; + + // cycle_min_size + stConfig.pstItems[itemIndex].pstrType = (AX_CHAR *)"cycle_min_size"; + AX_SKEL_OBJECT_SIZE_FILTER_CONFIG_T stCycleMinSize = {0}; + stCycleMinSize.nWidth = 0; + stCycleMinSize.nHeight = 0; + stConfig.pstItems[itemIndex].pstrValue = (AX_VOID *)&stCycleMinSize; + stConfig.pstItems[itemIndex].nValueSize = sizeof(AX_SKEL_OBJECT_SIZE_FILTER_CONFIG_T); + itemIndex++; + + // plate_min_size + stConfig.pstItems[itemIndex].pstrType = (AX_CHAR *)"plate_min_size"; + AX_SKEL_OBJECT_SIZE_FILTER_CONFIG_T stPlateMinSize = {0}; + stPlateMinSize.nWidth = 0; + stPlateMinSize.nHeight = 0; + stConfig.pstItems[itemIndex].pstrValue = (AX_VOID *)&stPlateMinSize; + stConfig.pstItems[itemIndex].nValueSize = sizeof(AX_SKEL_OBJECT_SIZE_FILTER_CONFIG_T); + itemIndex++; +#endif + + // detect_roi_polygon + AX_SKEL_ROI_POLYGON_CONFIG_T stDetectRoi = {0}; + stConfig.pstItems[itemIndex].pstrType = (AX_CHAR *)"detect_roi_polygon"; + stDetectRoi.bEnable = AX_FALSE; + stDetectRoi.nPointNum = 4; + AX_SKEL_POINT_T stPoint[4] = {{0, 0}, {nWidth, 0}, {nWidth, nHeight}, {0, nHeight}}; + stDetectRoi.pstPoint = (AX_SKEL_POINT_T *)stPoint; + stConfig.pstItems[itemIndex].pstrValue = (AX_VOID *)&stDetectRoi; + stConfig.pstItems[itemIndex].nValueSize = sizeof(AX_SKEL_ROI_POLYGON_CONFIG_T); + itemIndex++; + + // push_strategy + stConfig.pstItems[itemIndex].pstrType = (AX_CHAR *)"push_strategy"; + AX_SKEL_PUSH_STRATEGY_T stPushStrategy = {0}; + stPushStrategy.ePushMode = (AX_SKEL_PUSH_MODE_E)nPushStrategy; + stPushStrategy.nIntervalTimes = 2000; + stPushStrategy.nPushCounts = 1; + stPushStrategy.bPushSameFrame = AX_TRUE; + stConfig.pstItems[itemIndex].pstrValue = (AX_VOID *)&stPushStrategy; + stConfig.pstItems[itemIndex].nValueSize = sizeof(AX_SKEL_PUSH_STRATEGY_T); + itemIndex++; + + //4 crop_encoder +#if 0 + // body_crop_encoder + AX_SKEL_CROP_ENCODER_THRESHOLD_CONFIG_T stBodyCropEncoderThreshold = {0}; + stConfig.pstItems[itemIndex].pstrType = (AX_CHAR *)"body_crop_encoder"; + stBodyCropEncoderThreshold.fScaleLeft = 0; + stBodyCropEncoderThreshold.fScaleRight = 0; + stBodyCropEncoderThreshold.fScaleTop = 0; + stBodyCropEncoderThreshold.fScaleBottom = 0; + stConfig.pstItems[itemIndex].pstrValue = (AX_VOID *)&stBodyCropEncoderThreshold; + stConfig.pstItems[itemIndex].nValueSize = sizeof(AX_SKEL_CROP_ENCODER_THRESHOLD_CONFIG_T); + itemIndex++; + + // vehicle_crop_encoder + AX_SKEL_CROP_ENCODER_THRESHOLD_CONFIG_T stVehicleCropEncoderThreshold = {0}; + stConfig.pstItems[itemIndex].pstrType = (AX_CHAR *)"vehicle_crop_encoder"; + stVehicleCropEncoderThreshold.fScaleLeft = 0; + stVehicleCropEncoderThreshold.fScaleRight = 0; + stVehicleCropEncoderThreshold.fScaleTop = 0; + stVehicleCropEncoderThreshold.fScaleBottom = 0; + stConfig.pstItems[itemIndex].pstrValue = (AX_VOID *)&stVehicleCropEncoderThreshold; + stConfig.pstItems[itemIndex].nValueSize = sizeof(AX_SKEL_CROP_ENCODER_THRESHOLD_CONFIG_T); + itemIndex++; + + // cycle_crop_encoder + AX_SKEL_CROP_ENCODER_THRESHOLD_CONFIG_T stCycleCropEncoderThreshold = {0}; + stConfig.pstItems[itemIndex].pstrType = (AX_CHAR *)"cycle_crop_encoder"; + stCycleCropEncoderThreshold.fScaleLeft = 0; + stCycleCropEncoderThreshold.fScaleRight = 0; + stCycleCropEncoderThreshold.fScaleTop = 0; + stCycleCropEncoderThreshold.fScaleBottom = 0; + stConfig.pstItems[itemIndex].pstrValue = (AX_VOID *)&stCycleCropEncoderThreshold; + stConfig.pstItems[itemIndex].nValueSize = sizeof(AX_SKEL_CROP_ENCODER_THRESHOLD_CONFIG_T); + itemIndex++; + + // face_crop_encoder + AX_SKEL_CROP_ENCODER_THRESHOLD_CONFIG_T stFaceCropEncoderThreshold = {0}; + stConfig.pstItems[itemIndex].pstrType = (AX_CHAR *)"face_crop_encoder"; + stFaceCropEncoderThreshold.fScaleLeft = 0; + stFaceCropEncoderThreshold.fScaleRight = 0; + stFaceCropEncoderThreshold.fScaleTop = 0; + stFaceCropEncoderThreshold.fScaleBottom = 0; + stConfig.pstItems[itemIndex].pstrValue = (AX_VOID *)&stFaceCropEncoderThreshold; + stConfig.pstItems[itemIndex].nValueSize = sizeof(AX_SKEL_CROP_ENCODER_THRESHOLD_CONFIG_T); + itemIndex++; + + // plate_crop_encoder + AX_SKEL_CROP_ENCODER_THRESHOLD_CONFIG_T stPlateCropEncoderThreshold = {0}; + stConfig.pstItems[itemIndex].pstrType = (AX_CHAR *)"plate_crop_encoder"; + stPlateCropEncoderThreshold.fScaleLeft = 0; + stPlateCropEncoderThreshold.fScaleRight = 0; + stPlateCropEncoderThreshold.fScaleTop = 0; + stPlateCropEncoderThreshold.fScaleBottom = 0; + stConfig.pstItems[itemIndex].pstrValue = (AX_VOID *)&stPlateCropEncoderThreshold; + stConfig.pstItems[itemIndex].nValueSize = sizeof(AX_SKEL_CROP_ENCODER_THRESHOLD_CONFIG_T); + itemIndex++; +#endif + // push_panorama + stConfig.pstItems[itemIndex].pstrType = (AX_CHAR *)"push_panorama"; + AX_SKEL_PUSH_PANORAMA_CONFIG_T stPushPanoramaConfig = {0}; + stPushPanoramaConfig.bEnable = AX_FALSE; + stPushPanoramaConfig.nQuality = 0; + stConfig.pstItems[itemIndex].pstrValue = (AX_VOID *)&stPushPanoramaConfig; + stConfig.pstItems[itemIndex].nValueSize = sizeof(AX_SKEL_PUSH_PANORAMA_CONFIG_T); + itemIndex++; +#if 0 + // push_quality_body + stConfig.pstItems[itemIndex].pstrType = (AX_CHAR *)"push_quality_body"; + AX_SKEL_ATTR_FILTER_CONFIG_T stBodyAttrFilter = {0}; + stBodyAttrFilter.stCommonAttrFilterConfig.fQuality = 0; + stConfig.pstItems[itemIndex].pstrValue = (AX_VOID *)&stBodyAttrFilter; + stConfig.pstItems[itemIndex].nValueSize = sizeof(AX_SKEL_ATTR_FILTER_CONFIG_T); + itemIndex++; + + // push_quality_vehicle + stConfig.pstItems[itemIndex].pstrType = (AX_CHAR *)"push_quality_vehicle"; + AX_SKEL_ATTR_FILTER_CONFIG_T stVehicleAttrFilter = {0}; + stVehicleAttrFilter.stCommonAttrFilterConfig.fQuality = 0; + stConfig.pstItems[itemIndex].pstrValue = (AX_VOID *)&stVehicleAttrFilter; + stConfig.pstItems[itemIndex].nValueSize = sizeof(AX_SKEL_ATTR_FILTER_CONFIG_T); + itemIndex++; + + // push_quality_cycle + stConfig.pstItems[itemIndex].pstrType = (AX_CHAR *)"push_quality_cycle"; + AX_SKEL_ATTR_FILTER_CONFIG_T stCycleAttrFilter = {0}; + stCycleAttrFilter.stCommonAttrFilterConfig.fQuality = 0; + stConfig.pstItems[itemIndex].pstrValue = (AX_VOID *)&stCycleAttrFilter; + stConfig.pstItems[itemIndex].nValueSize = sizeof(AX_SKEL_ATTR_FILTER_CONFIG_T); + itemIndex++; + + // push_quality_face + stConfig.pstItems[itemIndex].pstrType = (AX_CHAR *)"push_quality_face"; + AX_SKEL_ATTR_FILTER_CONFIG_T stFaceAttrFilter = {0}; + stFaceAttrFilter.stFaceAttrFilterConfig.nWidth = 0; + stFaceAttrFilter.stFaceAttrFilterConfig.nHeight = 0; + stFaceAttrFilter.stFaceAttrFilterConfig.stPoseblur.fPitch = 180; + stFaceAttrFilter.stFaceAttrFilterConfig.stPoseblur.fYaw = 180; + stFaceAttrFilter.stFaceAttrFilterConfig.stPoseblur.fRoll = 180; + stFaceAttrFilter.stFaceAttrFilterConfig.stPoseblur.fBlur = 1.0; + stConfig.pstItems[itemIndex].nValueSize = sizeof(AX_SKEL_ATTR_FILTER_CONFIG_T); + stConfig.pstItems[itemIndex].pstrValue = (AX_VOID *)&stFaceAttrFilter; + itemIndex++; + + // push_quality_plate + stConfig.pstItems[itemIndex].pstrType = (AX_CHAR *)"push_quality_plate"; + AX_SKEL_ATTR_FILTER_CONFIG_T stPlateAttrFilter = {0}; + stPlateAttrFilter.stCommonAttrFilterConfig.fQuality = 0; + stConfig.pstItems[itemIndex].pstrValue = (AX_VOID *)&stPlateAttrFilter; + stConfig.pstItems[itemIndex].nValueSize = sizeof(AX_SKEL_ATTR_FILTER_CONFIG_T); + itemIndex++; +#endif +//#if 0 + // track_enable + stConfig.pstItems[itemIndex].pstrType = (AX_CHAR *)"track_enable"; + AX_SKEL_COMMON_ENABLE_CONFIG_T stTrackEnable = {0}; + stTrackEnable.bEnable = AX_TRUE; + stConfig.pstItems[itemIndex].pstrValue = (AX_VOID *)&stTrackEnable; + stConfig.pstItems[itemIndex].nValueSize = sizeof(AX_SKEL_COMMON_ENABLE_CONFIG_T); + itemIndex++; + + //push_enable + stConfig.pstItems[itemIndex].pstrType = (AX_CHAR *)"push_enable"; + AX_SKEL_COMMON_ENABLE_CONFIG_T stPushEnable = {0}; + stPushEnable.bEnable = AX_TRUE; + stConfig.pstItems[itemIndex].pstrValue = (AX_VOID *)&stPushEnable; + stConfig.pstItems[itemIndex].nValueSize = sizeof(AX_SKEL_COMMON_ENABLE_CONFIG_T); + itemIndex++; +//#endif +#if 0 + //target_config + stConfig.pstItems[itemIndex].pstrType = (AX_CHAR *)"target_config"; + AX_SKEL_TARGET_CONFIG_T stTarget = {0}; + + stTarget.nSize = 1; + AX_SKEL_TARGET_ITEM_T stItem = {0}; + stItem.pstrObjectCategory = "body"; + stTarget.pstItems = &stItem; + + stConfig.pstItems[itemIndex].pstrValue = (AX_VOID *)&stTarget; + stConfig.pstItems[itemIndex].nValueSize = sizeof(AX_SKEL_TARGET_CONFIG_T); + itemIndex++; + + //push_target_config + stConfig.pstItems[itemIndex].pstrType = (AX_CHAR *)"push_target_config"; + AX_SKEL_TARGET_CONFIG_T stTarget = {0}; + stTarget.nSize = 1; + AX_SKEL_TARGET_ITEM_T stItem = {0}; + stItem.pstrObjectCategory = "body"; + stTarget.pstItems = &stItem; + + stConfig.pstItems[itemIndex].pstrValue = (AX_VOID *)&stTarget; + stConfig.pstItems[itemIndex].nValueSize = sizeof(AX_SKEL_TARGET_CONFIG_T); + itemIndex++; + + // push_attr_always + stConfig.pstItems[itemIndex].pstrType = (AX_CHAR *)"push_attr_always"; + AX_SKEL_COMMON_ENABLE_CONFIG_T stPushAttrAlways = {0}; + stPushAttrAlways.bEnable = AX_TRUE; + stConfig.pstItems[itemIndex].pstrValue = (AX_VOID *)&stPushAttrAlways; + stConfig.pstItems[itemIndex].nValueSize = sizeof(AX_SKEL_COMMON_ENABLE_CONFIG_T); + itemIndex++; +#endif + //analyzer_attr_config + // stConfig.pstItems[itemIndex].pstrType = (AX_CHAR *)"analyzer_attr_config"; + // AX_SKEL_ANALYZER_CONFIG_T stAnalyze = {0}; + // //AX_SKEL_ANALYZER_ATTR_E analyze_attribute = AX_SKEL_ANALYZER_ATTR_NONE; + + // stAnalyze.nSize = 1; + // AX_SKEL_ANALYZER_ATTR_E analyze_attribute = AX_SKEL_ANALYZER_ATTR_FACE_ATTRIBUTE; + // stAnalyze.peItems = &analyze_attribute; + + // stConfig.pstItems[itemIndex].pstrValue = (AX_VOID *)&stAnalyze; + // stConfig.pstItems[itemIndex].nValueSize = sizeof(AX_SKEL_ANALYZER_CONFIG_T); + // itemIndex++; + + stConfig.nSize = itemIndex; + + nRet = AX_SKEL_SetConfig(pHandle, &stConfig); + + if (0 != nRet) { + ALOGE("SKEL AX_SKEL_SetConfig, ret = 0x%x", nRet); + + goto EXIT2; + } + } + + // get config + { + const AX_SKEL_CONFIG_T *pstConfig = NULL; + + nRet = AX_SKEL_GetConfig(pHandle, &pstConfig); + + if (0 != nRet) { + ALOGE("SKEL AX_SKEL_GetConfig, ret = 0x%x", nRet); + + if (pstConfig) { + AX_SKEL_Release((AX_VOID *)pstConfig); + } + + goto EXIT2; + } + + ParseConfigParam(pstConfig); + + if (pstConfig) { + AX_SKEL_Release((AX_VOID *)pstConfig); + } + } + + ALOGN("Task infomation:"); + ALOGN("\tInput file: %s", InputFile); + ALOGN("\tInput file resolution: %dx%d", nWidth, nHeight); + ALOGN("\tRepeat times: %d", nRepeatTimes); + ALOGN("SKEL Init Elapse:"); + ALOGN("\tAX_SKEL_Init: %lld ms", nInitElasped); + ALOGN("\tAX_SKEL_Create: %lld ms", nCreateElasped); + + OUTPUT_LOG_SAVE("==============================%s process result:==============================", InputFile); + + if (InputFileFrameCnt > 1) { + InputFileFrameCnt = InputFileFrameCnt + BLACK_VIDEO_FRAME_COUNT; + } + + // create frame mgr + FrameMgrCreate(nFrameSize, nFrameDepth + nCacheListDepth); + + for (AX_U32 nRepeat = 0; nRepeat < nRepeatTimes; nRepeat++) { + ALOGN("#####SKEL Process times: %d", nRepeat + 1); + + OUTPUT_LOG_SAVE("#####SKEL Process times: %d", nRepeat + 1); + + STAT_OBJECT_NUM_T tObjectTrackNum = {0}; + STAT_OBJECT_NUM_T tObjectPushNum = {0}; + + for (AX_U32 nFrameCnt = 0; nFrameCnt < InputFileFrameCnt; nFrameCnt++) { + AX_BLK blkId = AX_INVALID_BLOCKID; + + if (InputFileFrameCnt != 1) { + if (FrameSkipCtrl(nSrcFrameRate, nDstFrameRate, nSkelFrameId)) { + nSkelFrameId ++; + + LoadFileToMem(InputFileHandle, 0, NULL, nOneSize); + + if (nInterval > 0) { + usleep(nInterval); + } + continue; + } + else { + if (!FrameMgrGet(&YUVDataPhy, &YUVDataVir, nFrameSize, nSkelFrameId, &blkId)) { + + ALOGE("FrameMgrGet fail"); + + goto EXIT1; + } + + if (nOneSize != nFrameSize) { + LoadFileToMem(InputFileHandle, OneYUVDataPhy, OneYUVDataVir, nOneSize); + + NV12ToStrideNV12(OneYUVDataPhy, + OneYUVDataVir, + nOneSize, + nWidth, + nHeight, + YUVDataPhy, + YUVDataVir, + nFrameSize, + nStride, + nHeight + ); + } + else { + LoadFileToMem(InputFileHandle, YUVDataPhy, YUVDataVir, nOneSize); + } + } + } else { + FrameMgrGet(&YUVDataPhy, &YUVDataVir, nFrameSize, nSkelFrameId, &blkId); + + if (nRet != 0 + || YUVDataPhy == 0 + || YUVDataVir == NULL) { + ALOGE("Load input file fail"); + goto EXIT1; + } + + if (bJpgFile) { + nRet = DecodeJpeg(InputFileHandle, YUVDataPhy, YUVDataVir, nWidth, nHeight); + if (0 != nRet) { + ALOGE("DecodeJpeg failed!"); + goto EXIT3; + } + } + else { + if (nOneSize != nFrameSize) { + nRet = AX_SYS_MemAlloc(&OneYUVDataPhy, (AX_VOID **)&OneYUVDataVir, nOneSize, 256, (AX_S8 *)"SKEL_TEST"); + + nRet = LoadFileToMem(InputFileHandle, OneYUVDataPhy, OneYUVDataVir, nOneSize); + + NV12ToStrideNV12(OneYUVDataPhy, + OneYUVDataVir, + nOneSize, + nWidth, + nHeight, + YUVDataPhy, + YUVDataVir, + nFrameSize, + nStride, + nHeight + ); + } + else { + nRet = LoadFileToMem(InputFileHandle, YUVDataPhy, YUVDataVir, nFrameSize); + } + } + } + stFrame.stFrame.u32Width = nWidth; + stFrame.stFrame.u32Height = nHeight; + stFrame.stFrame.enImgFormat = AX_FORMAT_YUV420_SEMIPLANAR; + stFrame.stFrame.u32FrameSize = nFrameSize; + stFrame.stFrame.u32PicStride[0] = nStride; + stFrame.stFrame.u32PicStride[1] = nStride; + stFrame.stFrame.u32PicStride[2] = nStride; + stFrame.stFrame.u64PhyAddr[0] = YUVDataPhy; + stFrame.stFrame.u64PhyAddr[1] = YUVDataPhy + nStride * nHeight; + stFrame.stFrame.u64PhyAddr[2] = 0; + stFrame.stFrame.u64VirAddr[0] = (AX_ULONG)(YUVDataVir); + stFrame.stFrame.u64VirAddr[1] = (AX_ULONG)(YUVDataVir + nStride * nHeight); + stFrame.stFrame.u64VirAddr[2] = 0; + stFrame.stFrame.u32BlkId[0] = blkId; + stFrame.stFrame.u32BlkId[1] = 0; + stFrame.stFrame.u32BlkId[2] = 0; + ALOGN("*****SKEL Frame(%d) Process", nFrameCnt + 1); + + //OUTPUT_LOG_SAVE("*****SKEL Frame(%d) Process Start", nFrameCnt + 1); + + stFrame.nFrameId = nSkelFrameId ++; + nStartTime = get_tick_count(); + + while (1) { + nRet = AX_SKEL_SendFrame(pHandle, &stFrame, 0); + + if (nRet == 0) { + break; + } + + usleep(1000); + } + + FrameMgrRelease(blkId); + + nProcessElasped = get_tick_count() - nStartTime; + + if (0 != nRet) { + ALOGE("SKEL Process fail, ret = 0x%x", nRet); + + goto EXIT3; + } + + ALOGN("SKEL Process Elapse:"); + ALOGN("\tAX_SKEL_SendFrame: %lld ms", nProcessElasped); + + nStartTime = get_tick_count(); + + nRet = AX_SKEL_GetResult(pHandle, &pstResult, -1); + + nResultElasped = get_tick_count() - nStartTime; + + if (0 != nRet) { + ALOGE("SKEL get result fail, ret = 0x%x", nRet); + + goto EXIT3; + } + + ALOGN("\tAX_SKEL_GetResult: %lld ms", nResultElasped); + + nResultElaspedTotal += nResultElasped; + + if (nProcessElasped + nResultElasped > nResultElaspedMax) { + nResultElaspedMax = nProcessElasped + nResultElasped; + } + + if (nProcessElasped + nResultElasped < nResultElaspedMin) { + nResultElaspedMin = nProcessElasped + nResultElasped; + } + + ALOGN("SKEL Process Result:"); + + ALOGI("\tFrameId: %lld", pstResult->nFrameId); + ALOGI("\tnOriginal WxH: %dx%d", pstResult->nOriginalWidth, pstResult->nOriginalHeight); + + ALOGN("\tObject Num: %d", pstResult->nObjectSize); + + AX_U32 nSkelSize = 0; + AI_Detection_SkelResult_t Skels[SKEL_SAMPLE_OBJECT_SIZE] = {0}; + for (AX_U32 i = 0; i < pstResult->nObjectSize; i++) { + AX_SKEL_OBJECT_ITEM_T *pstItems = &pstResult->pstObjectItems[i]; + + ALOGI("\t\tFrameId: %lld", pstItems->nFrameId); + ALOGI("\t\tTrackId: %lld, TrackState: %d", pstItems->nTrackId, pstItems->eTrackState); + + ALOGN("\t\tRect[%d] %s: [%f, %f, %f, %f], Confidence: %f", i, pstItems->pstrObjectCategory, + pstItems->stRect.fX, + pstItems->stRect.fY, pstItems->stRect.fW, + pstItems->stRect.fH, pstItems->fConfidence); + StatTrackMgr(pstItems, &tObjectTrackNum); + StatPushMgr(pstItems, &tObjectPushNum); + + // get detect box only new or update state + if ((pstItems->eTrackState == AX_SKEL_TRACK_STATUS_NEW + || pstItems->eTrackState == AX_SKEL_TRACK_STATUS_UPDATE) + && nSkelSize < SKEL_SAMPLE_OBJECT_SIZE) { + Skels[nSkelSize].pstrObjectCategory = pstItems->pstrObjectCategory; + Skels[nSkelSize].tBox.fX = pstItems->stRect.fX; + Skels[nSkelSize].tBox.fY = pstItems->stRect.fY; + Skels[nSkelSize].tBox.fW = pstItems->stRect.fW; + Skels[nSkelSize].tBox.fH = pstItems->stRect.fH; + + OUTPUT_LOG_SAVE("\t\tObject[%d] %s: [%f, %f, %f, %f], Confidence: %f", + i, pstItems->pstrObjectCategory, + pstItems->stRect.fX, pstItems->stRect.fY, + pstItems->stRect.fW, pstItems->stRect.fH, + pstItems->fConfidence); + + ALOGN("\t\t[%d]Point Set Size: %d", i, pstItems->nPointSetSize); + + // point + Skels[nSkelSize].nPointNum = AX_MIN(DETECT_SKEL_POINT_COUNT, pstItems->nPointSetSize); + for (AX_U32 j = 0; j < Skels[i].nPointNum; j++) { + ALOGI("\t\t\tPoint[%d] %s: [%f, %f] Confidence: %f", j, pstItems->pstPointSet[j].pstrObjectCategory, + pstItems->pstPointSet[j].stPoint.fX, + pstItems->pstPointSet[j].stPoint.fY, + pstItems->pstPointSet[j].fConfidence); + Skels[nSkelSize].tPoint[j].fX = pstItems->pstPointSet[j].stPoint.fX; + Skels[nSkelSize].tPoint[j].fY = pstItems->pstPointSet[j].stPoint.fY; + + OUTPUT_LOG_SAVE("\t\t\tPoint[%d] %s: [%f, %f] Confidence: %f\n", + j, + pstItems->pstPointSet[j].pstrObjectCategory, + pstItems->pstPointSet[j].stPoint.fX, + pstItems->pstPointSet[j].stPoint.fY, + pstItems->pstPointSet[j].fConfidence); + } + + //face attr + if(nPPL == AX_SKEL_PPL_FACE){ + ALOGN("\t\tFace Attribute:"); + ALOGI("\t\t\tfYaw %f,",pstItems->stFaceAttr.fYaw); + ALOGI("\t\t\tfPitch %f,",pstItems->stFaceAttr.fPitch); + ALOGI("\t\t\tfRoll %f,",pstItems->stFaceAttr.fRoll); + ALOGI("\t\t\tfMask %f,",pstItems->stFaceAttr.fMask); + ALOGI("\t\t\tage %d",pstItems->stFaceAttr.nAge); + ALOGI("\t\t\tgender %d",pstItems->stFaceAttr.nGender); + } + nSkelSize ++; + } + + if (AX_SKEL_TRACK_STATUS_SELECT == pstItems->eTrackState) { + ATTRINFO_T AttrInfo; + memset(&AttrInfo, 0x00, sizeof(AttrInfo)); + AttrParser(pstItems, &AttrInfo); + + if (pstItems->bCropFrame + && pstItems->stCropFrame.pFrameData + && 0 < pstItems->stCropFrame.nFrameDataSize + && SaveResultPath) { + // save attribute + AX_CHAR arrDat[256] = {0}; + AX_CHAR strFile[512] = {0}; + if (AttrInfo.bExist && AttrInfo.eType == ATTR_TYPE_FACE) { + sprintf(arrDat, "frame%lld_crop_%s[%lld]_Gender[%s]_Age[%d]_Mask[%s]_Score[%f]_%dx%d", + pstItems->stCropFrame.nFrameId, + pstItems->pstrObjectCategory, + pstItems->nTrackId, + AttrInfo.tFaceInfo.szGender, + AttrInfo.tFaceInfo.nAge, + AttrInfo.tFaceInfo.szMask, + pstItems->fConfidence, + pstItems->stCropFrame.nFrameWidth, + pstItems->stCropFrame.nFrameHeight); + + OUTPUT_LOG_SAVE("\t\t[FACE ATTR] %s", arrDat); + } + else if (AttrInfo.bExist && AttrInfo.eType == ATTR_TYPE_PLATE) { + sprintf(arrDat, "frame%lld_crop_%s[%lld]_Valid[%d]_Num[%s]_Color[%s]_Score[%f]_%dx%d", + pstItems->stCropFrame.nFrameId, + pstItems->pstrObjectCategory, + pstItems->nTrackId, + AttrInfo.tPlateInfo.bValid, + AttrInfo.tPlateInfo.szNum, + AttrInfo.tPlateInfo.szColor, + pstItems->fConfidence, + pstItems->stCropFrame.nFrameWidth, + pstItems->stCropFrame.nFrameHeight); + + OUTPUT_LOG_SAVE("\t\t[PLATE ATTR] %s", arrDat); + } + else if (AttrInfo.bExist && AttrInfo.eType == ATTR_TYPE_VEHICLE) { + sprintf(arrDat, "frame%lld_crop_%s[%lld]_[plate_Valid[%d]_Num[%s]_Color[%s]]_Score[%f]_%dx%d", + pstItems->stCropFrame.nFrameId, + pstItems->pstrObjectCategory, + pstItems->nTrackId, + AttrInfo.tPlateInfo.bValid, + AttrInfo.tPlateInfo.szNum, + AttrInfo.tPlateInfo.szColor, + pstItems->fConfidence, + pstItems->stCropFrame.nFrameWidth, + pstItems->stCropFrame.nFrameHeight); + + OUTPUT_LOG_SAVE("\t\t[VEHICLE ATTR] %s", arrDat); + } + else { + sprintf(arrDat, "frame%lld_crop_%s[%lld]_Score[%f]_%dx%d", + pstItems->stCropFrame.nFrameId, + pstItems->pstrObjectCategory, + pstItems->nTrackId, + pstItems->fConfidence, + pstItems->stCropFrame.nFrameWidth, + pstItems->stCropFrame.nFrameHeight); + } + + sprintf(strFile, "%s/%s/%s.jpg", + SaveResultPath, + pstItems->pstrObjectCategory, + arrDat); + + FILE *fp_w = fopen(strFile, "wb"); + + if (fp_w) { + ALOGI("Write crop jpg to file: %s", strFile); + fwrite((AX_U8 *)pstItems->stCropFrame.pFrameData, 1, pstItems->stCropFrame.nFrameDataSize, fp_w); + fclose(fp_w); + } + + } + + // panora frame + if (pstItems->bPanoraFrame + && pstItems->stPanoraFrame.pFrameData + && 0 < pstItems->stPanoraFrame.nFrameDataSize + && SaveResultPath) { + AX_CHAR arrDat[256] = {0}; + AX_CHAR strFile[512] = {0}; + if (AttrInfo.bExist && AttrInfo.eType == ATTR_TYPE_FACE) { + sprintf(arrDat, "frame%lld_panora_%s[%lld]_Gender[%s]_Age[%d]_Mask[%s]_Score[%f]_%dx%d.jpg", + pstItems->stCropFrame.nFrameId, pstItems->pstrObjectCategory, pstItems->nTrackId, + AttrInfo.tFaceInfo.szGender, AttrInfo.tFaceInfo.nAge, AttrInfo.tFaceInfo.szMask, + pstItems->fConfidence, + pstItems->stCropFrame.nFrameWidth, pstItems->stCropFrame.nFrameHeight); + } + else if (AttrInfo.bExist && AttrInfo.eType == ATTR_TYPE_PLATE) { + sprintf(arrDat, "frame%lld_panora_%s[%lld]_Valid[%d]_Num[%s]_Color[%s]_Score[%f]_%dx%d.jpg", + pstItems->stCropFrame.nFrameId, pstItems->pstrObjectCategory, pstItems->nTrackId, + AttrInfo.tPlateInfo.bValid, AttrInfo.tPlateInfo.szNum, AttrInfo.tPlateInfo.szColor, + pstItems->fConfidence, + pstItems->stCropFrame.nFrameWidth, pstItems->stCropFrame.nFrameHeight); + } + else if (AttrInfo.bExist && AttrInfo.eType == ATTR_TYPE_VEHICLE) { + sprintf(arrDat, "frame%lld_panora_%s[%lld]_[plate_Valid[%d]_Num[%s]_Color[%s]]_Score[%f]_%dx%d.jpg", + pstItems->stCropFrame.nFrameId, pstItems->pstrObjectCategory, pstItems->nTrackId, + AttrInfo.tPlateInfo.bValid, AttrInfo.tPlateInfo.szNum, AttrInfo.tPlateInfo.szColor, + pstItems->fConfidence, + pstItems->stCropFrame.nFrameWidth, pstItems->stCropFrame.nFrameHeight); + } + else { + sprintf(arrDat, "frame%lld_panora_%s[%lld]_Score[%f]_%dx%d.jpg", + pstItems->stCropFrame.nFrameId, pstItems->pstrObjectCategory, pstItems->nTrackId, + pstItems->fConfidence, + pstItems->stCropFrame.nFrameWidth, pstItems->stCropFrame.nFrameHeight); + } + + sprintf(strFile, "%s/%s/%s.jpg", + SaveResultPath, + pstItems->pstrObjectCategory, + arrDat); + + FILE *fp_w = fopen(strFile, "wb"); + + if (fp_w) { + ALOGI("Write panora jpg to file: %s", strFile); + fwrite((AX_U8 *)pstItems->stPanoraFrame.pFrameData, 1, pstItems->stPanoraFrame.nFrameDataSize, fp_w); + fclose(fp_w); + } + } + } + + // feature + ALOGI("\t\tFeature Size: %d", pstItems->nFeatureSize); + if (pstItems->pstFeatureItem + && 0 < pstItems->nFeatureSize + && SaveResultPath) { + AX_CHAR strFile[256] = {0}; + sprintf(strFile, "%s/%s/frame%lld_feature_%s_%d.db", + SaveResultPath, pstItems->pstrObjectCategory, + pstItems->stCropFrame.nFrameId, + pstItems->pstrObjectCategory, i); + FILE *fp_w = fopen(strFile, "wb"); + + if (fp_w) { + ALOGI("\t\t\tWrite feature to file: %s, nValueSize: %d", + strFile, + pstItems->pstFeatureItem[0].nValueSize); + fwrite((AX_U8 *)pstItems->pstFeatureItem[0].pstrValue, 1, pstItems->pstFeatureItem[0].nValueSize, fp_w); + fclose(fp_w); + } + } + + // meta + ALOGI("\t\tMeta Size: %d", pstItems->nMetaInfoSize); + if (pstItems->pstMetaInfo + && 0 < pstItems->nMetaInfoSize) { + for (AX_U32 i = 0; i < pstItems->nMetaInfoSize; i++) { + ALOGI("\t\tMetaInfo[%d] %s: \n%s", i, pstItems->pstMetaInfo[i].pstrType, pstItems->pstMetaInfo[i].pstrValue); + } + } + + // binds + ALOGI("\t\tBind Size: %d", pstItems->nObjectBindSize); + if (pstItems->pstObjectBind + && 0 < pstItems->nObjectBindSize) { + for (AX_U32 i = 0; i < pstItems->nObjectBindSize; i++) { + ALOGI("\t\t[%s] [TrackId] %lld bind to ObjectBind[%d]: %s [TrackId] %lld", + pstItems->pstrObjectCategory, pstItems->nTrackId, i, + pstItems->pstObjectBind[i].pstrObjectCategoryBind, pstItems->pstObjectBind[i].nTrackId); + } + } + } + + ALOGI("\tnCacheListSize: %d", pstResult->nCacheListSize); + if (pstResult->pstCacheList) { + for (AX_U32 i = 0; i < pstResult->nCacheListSize; i++) { + ALOGI("\t\tCacheList[%d] FrameId: %lld", i, pstResult->pstCacheList[i].nFrameId); + } + } + + if (ReWritePath && pstResult->nObjectSize > 0) { + memcpy(YUVDataWrVir, YUVDataVir, nFrameSize); + + YUV_IMAGE_T YUVImage = {0}; + YUVImage.pImage = YUVDataWrVir; + YUVImage.nWidth = nWidth; + YUVImage.nHeight = nHeight; + YUVImage.stride = nStride; + YUVImage.nSize = nFrameSize; + YUVImage.eType = AX_FORMAT_YUV420_SEMIPLANAR; + + for (size_t i = 0; i < nSkelSize; i++) { + // draw rect + AX_CHAR ObjectCategory = Skels[i].pstrObjectCategory[0]; + AX_S16 x0 = Skels[i].tBox.fX; + AX_S16 y0 = Skels[i].tBox.fY; + AX_U16 w = Skels[i].tBox.fW; + AX_U16 h = Skels[i].tBox.fH; + YUV_COLOR RectColor = YUV_WHITE; + + switch(ObjectCategory){ + case 'b': //body + RectColor = YUV_WHITE; + break; + case 'v': //vehicle + RectColor = YUV_PURPLE; + break; + case 'c': //cycle + RectColor = YUV_GREEN; + break; + case 'f': //face + RectColor = YUV_YELLOW; + break; + case 'p': //plate + RectColor = YUV_RED; + break; + default : + RectColor = YUV_WHITE; + break; + } + + DrawRect(&YUVImage, x0, y0, w, h, RectColor); + + if (Skels[i].nPointNum > 0) { + // draw point + for (size_t j = 0; j < Skels[i].nPointNum; j++) { + x0 = Skels[i].tPoint[j].fX; + y0 = Skels[i].tPoint[j].fY; + + DrawPoint(&YUVImage, x0, y0, 4, x0 * (4 - 1), y0 * (4 - 1), YUV_DARK_GREEN); + } + } + } + + AX_CHAR arrWrFile[512] = {0}; + sprintf(arrWrFile, "%s_result_%d_%d.jpg", InputFile, nFrameCnt + 1, nRepeat + 1); + + AX_CHAR *fileName = NULL; + AX_U32 fileNameLen = strlen(arrWrFile); + AX_CHAR fullFileName[256] = {0}; + AX_S32 i = fileNameLen - 1; + + if (fileNameLen > 0) { + for (; i >= 0; i --) { + if (arrWrFile[i] == '/') { + break; + } + } + } + + if (i < 0) { + i = 0; + } + else if (i < fileNameLen - 1) { + i ++; + } + + fileName = (AX_CHAR *)&arrWrFile[i]; + + sprintf(fullFileName, "%s/%s", ReWritePath, fileName); + + EncodeOneFrameToJpeg((AX_CHAR *)fullFileName, nStride, nWidth, nHeight, YUVDataWrPhy, YUVDataWrVir, nFrameSize); + } + + if (pstResult) { + AX_SKEL_Release((AX_VOID *)pstResult); + } + + OUTPUT_LOG_SAVE("*****SKEL Frame(%d) Process End (Elasped: %lld ms)", nFrameCnt + 1, nProcessElasped); + + if (nInterval > 0) { + usleep(nInterval); + } + } + + ALOGN("SKEL Process Objects Statistics: Body[%d], Vehicle[%d], Cycle[%d], Face[%d], Plate[%d]", + tObjectTrackNum.nBodyNum, + tObjectTrackNum.nVehicleNum, + tObjectTrackNum.nCycleNum, + tObjectTrackNum.nFaceNum, + tObjectTrackNum.nPlateNum); + + OUTPUT_LOG_SAVE("\nSKEL Process Objects Statistics: Body[%d], Vehicle[%d], Cycle[%d], Face[%d], Plate[%d]", + tObjectTrackNum.nBodyNum, + tObjectTrackNum.nVehicleNum, + tObjectTrackNum.nCycleNum, + tObjectTrackNum.nFaceNum, + tObjectTrackNum.nPlateNum); + + ALOGN("SKEL Process Push Statistics: Body[%d], Vehicle[%d], Cycle[%d], Face[%d], Plate[%d]", + tObjectPushNum.nBodyNum, + tObjectPushNum.nVehicleNum, + tObjectPushNum.nCycleNum, + tObjectPushNum.nFaceNum, + tObjectPushNum.nPlateNum); + + OUTPUT_LOG_SAVE("SKEL Process Push Statistics: Body[%d], Vehicle[%d], Cycle[%d], Face[%d], Plate[%d]\n", + tObjectPushNum.nBodyNum, + tObjectPushNum.nVehicleNum, + tObjectPushNum.nCycleNum, + tObjectPushNum.nFaceNum, + tObjectPushNum.nPlateNum); + + if (InputFileHandle) { + ReLoadFile(InputFileHandle); + } + } + + // if(AX_SUCCESS != nRet){ + // ALOGE("AX_POOL_DestroyPool failed! Error Code:0x%X\n", nRet); + // } + + ALOGN("SKEL Process Elapsed Info: Repeats: %d, (min: %lld ms, avr: %lld ms, max: %lld ms)", + nRepeatTimes, + nResultElaspedMin, + (nSkelFrameId > 1) ? (nResultElaspedTotal / (nSkelFrameId - 1)) : 0, + nResultElaspedMax); + + OUTPUT_LOG_SAVE("SKEL Process Elapsed Info: Repeats: %d, (min: %lld ms, avr: %lld ms, max: %lld ms)", + nRepeatTimes, + nResultElaspedMin, + (nSkelFrameId > 1) ? (nResultElaspedTotal / (nSkelFrameId - 1)) : 0, + nResultElaspedMax); + +EXIT3: + if (pHandle) { + AX_SKEL_Destroy(pHandle); + } + +EXIT2: + AX_SKEL_DeInit(); + +EXIT1: + AX_ENGINE_Deinit(); + +EXIT0: + // if (YUVDataVir) { + // if (YUVDataPhy == 0) { + // free(YUVDataVir); + // } else { + // AX_SYS_MemFree(YUVDataPhy, YUVDataVir); + // } + // } + if (YUVDataWrVir) { + if (YUVDataWrPhy == 0) { + free(YUVDataWrVir); + } else { + AX_SYS_MemFree(YUVDataWrPhy, YUVDataWrVir); + } + } + + if (OneYUVDataVir) { + if (OneYUVDataPhy == 0) { + free(OneYUVDataVir); + } else { + AX_SYS_MemFree(OneYUVDataPhy, OneYUVDataVir); + } + } + + FrameMgrDestroy(); + + if (fpResultFile) { + fclose(fpResultFile); + } + + AX_VDEC_Deinit(); + + AX_VENC_Deinit(); + + AX_IVPS_Deinit(); + + AX_SYS_Deinit(); + + return (0 != nRet) ? -1 : 0; +} diff --git a/projects/llm_framework/main_skel/src/runner/skel_log.h b/projects/llm_framework/main_skel/src/runner/skel_log.h new file mode 100644 index 0000000..ffb495e --- /dev/null +++ b/projects/llm_framework/main_skel/src/runner/skel_log.h @@ -0,0 +1,61 @@ +/************************************************************************************************** + * + * Copyright (c) 2019-2024 Axera Semiconductor Co., Ltd. All Rights Reserved. + * + * This source file is the property of Axera Semiconductor Co., Ltd. and + * may not be copied or distributed in any isomorphic form without the prior + * written consent of Axera Semiconductor Co., Ltd. + * + **************************************************************************************************/ + +#ifndef _SAMPLE_SKEL_LOG_H_ +#define _SAMPLE_SKEL_LOG_H_ + +#include + +typedef enum { + SKEL_LOG_MIN = -1, + SKEL_LOG_EMERGENCY = 0, + SKEL_LOG_ALERT = 1, + SKEL_LOG_CRITICAL = 2, + SKEL_LOG_ERROR = 3, + SKEL_LOG_WARN = 4, + SKEL_LOG_NOTICE = 5, + SKEL_LOG_INFO = 6, + SKEL_LOG_DEBUG = 7, + SKEL_LOG_MAX +} SKEL_LOG_LEVEL_E; + +static SKEL_LOG_LEVEL_E log_level = SKEL_LOG_NOTICE; + +#if 1 +#define MACRO_BLACK "\033[1;30;30m" +#define MACRO_RED "\033[1;30;31m" +#define MACRO_GREEN "\033[1;30;32m" +#define MACRO_YELLOW "\033[1;30;33m" +#define MACRO_BLUE "\033[1;30;34m" +#define MACRO_PURPLE "\033[1;30;35m" +#define MACRO_WHITE "\033[1;30;37m" +#define MACRO_END "\033[0m" +#else +#define MACRO_BLACK +#define MACRO_RED +#define MACRO_GREEN +#define MACRO_YELLOW +#define MACRO_BLUE +#define MACRO_PURPLE +#define MACRO_WHITE +#define MACRO_END +#endif + +#define ALOGE(fmt, ...) printf(MACRO_RED "[E][%32s][%4d]: " fmt MACRO_END "\n", __FUNCTION__, __LINE__, ##__VA_ARGS__) +#define ALOGW(fmt, ...) if (log_level >= SKEL_LOG_WARN) \ + printf(MACRO_YELLOW "[W][%32s][%4d]: " fmt MACRO_END "\n", __FUNCTION__, __LINE__, ##__VA_ARGS__) +#define ALOGI(fmt, ...) if (log_level >= SKEL_LOG_INFO) \ + printf(MACRO_GREEN "[I][%32s][%4d]: " fmt MACRO_END "\n", __FUNCTION__, __LINE__, ##__VA_ARGS__) +#define ALOGD(fmt, ...) if (log_level >= SKEL_LOG_DEBUG) \ + printf(MACRO_WHITE "[D][%32s][%4d]: " fmt MACRO_END "\n", __FUNCTION__, __LINE__, ##__VA_ARGS__) +#define ALOGN(fmt, ...) if (log_level >= SKEL_LOG_NOTICE) \ + printf(MACRO_PURPLE "[N][%32s][%4d]: " fmt MACRO_END "\n", __FUNCTION__, __LINE__, ##__VA_ARGS__) + +#endif /* _SAMPLE_SKEL_TRACE_H_ */ diff --git a/projects/llm_framework/main_skel/src/runner/statMgr.cpp b/projects/llm_framework/main_skel/src/runner/statMgr.cpp new file mode 100644 index 0000000..c3a7101 --- /dev/null +++ b/projects/llm_framework/main_skel/src/runner/statMgr.cpp @@ -0,0 +1,65 @@ +/************************************************************************************************** + * + * Copyright (c) 2019-2024 Axera Semiconductor Co., Ltd. All Rights Reserved. + * + * This source file is the property of Axera Semiconductor Co., Ltd. and + * may not be copied or distributed in any isomorphic form without the prior + * written consent of Axera Semiconductor Co., Ltd. + * + **************************************************************************************************/ + +#include +#include "statMgr.h" +#include + +AX_VOID StatTrackMgr(const AX_SKEL_OBJECT_ITEM_T *pstObjectItems, STAT_OBJECT_NUM_T *pObjectNum) { + if (!pstObjectItems || !pObjectNum) { + return; + } + + std::string strObjectCategory = pstObjectItems->pstrObjectCategory; + + if (pstObjectItems->eTrackState == AX_SKEL_TRACK_STATUS_NEW) { + if (strObjectCategory == "body") { + pObjectNum->nBodyNum ++; + } + else if (strObjectCategory == "vehicle") { + pObjectNum->nVehicleNum ++; + } + else if (strObjectCategory == "cycle") { + pObjectNum->nCycleNum ++; + } + else if (strObjectCategory == "face") { + pObjectNum->nFaceNum ++; + } + else if (strObjectCategory == "plate") { + pObjectNum->nPlateNum ++; + } + } +} + +AX_VOID StatPushMgr(const AX_SKEL_OBJECT_ITEM_T *pstObjectItems, STAT_OBJECT_NUM_T *pObjectNum) { + if (!pstObjectItems || !pObjectNum) { + return; + } + + std::string strObjectCategory = pstObjectItems->pstrObjectCategory; + + if (pstObjectItems->eTrackState == AX_SKEL_TRACK_STATUS_SELECT) { + if (strObjectCategory == "body") { + pObjectNum->nBodyNum ++; + } + else if (strObjectCategory == "vehicle") { + pObjectNum->nVehicleNum ++; + } + else if (strObjectCategory == "cycle") { + pObjectNum->nCycleNum ++; + } + else if (strObjectCategory == "face") { + pObjectNum->nFaceNum ++; + } + else if (strObjectCategory == "plate") { + pObjectNum->nPlateNum ++; + } + } +} diff --git a/projects/llm_framework/main_skel/src/runner/statMgr.h b/projects/llm_framework/main_skel/src/runner/statMgr.h new file mode 100644 index 0000000..8cad1f6 --- /dev/null +++ b/projects/llm_framework/main_skel/src/runner/statMgr.h @@ -0,0 +1,36 @@ +/************************************************************************************************** + * + * Copyright (c) 2019-2024 Axera Semiconductor Co., Ltd. All Rights Reserved. + * + * This source file is the property of Axera Semiconductor Co., Ltd. and + * may not be copied or distributed in any isomorphic form without the prior + * written consent of Axera Semiconductor Co., Ltd. + * + **************************************************************************************************/ + +#ifndef _STAT_MGR_H_ +#define _STAT_MGR_H_ +#include "ax_global_type.h" +#include "ax_sys_api.h" +#include "ax_skel_api.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct _STAT_OBJECT_NUM_T { + AX_U32 nBodyNum; + AX_U32 nVehicleNum; + AX_U32 nCycleNum; + AX_U32 nFaceNum; + AX_U32 nPlateNum; +} STAT_OBJECT_NUM_T; + +extern AX_VOID StatTrackMgr(const AX_SKEL_OBJECT_ITEM_T *pstObjectItems, STAT_OBJECT_NUM_T *pObjectNum); +extern AX_VOID StatPushMgr(const AX_SKEL_OBJECT_ITEM_T *pstObjectItems, STAT_OBJECT_NUM_T *pObjectNum); + +#ifdef __cplusplus +} +#endif + +#endif