初始化+sdk路径

static USB_DEVICE_INFO *dev_list = NULL;   /* USB 枚举结果列表 */
static int dev_count = 0;                  /* 检测到的 USB 设备数 */
/*
 * 将工作目录切到可执行文件所在目录。
 * HCUsbSDK 通过 dlopen 加载同目录下的 .so 文件,必须运行在 .so 所在目录。
 */
static void setup_chdir(void)
{
    char exe[PATH_MAX], *p;
    ssize_t n = readlink("/proc/self/exe", exe, sizeof(exe) - 1);
    if (n <= 0) return;
    exe[n] = 0;
    p = strrchr(exe, '/');
    if (!p) return;
    *p = 0;
    if (access(exe, F_OK) == 0) (void)chdir(exe);
}
int camera_init(void)
{
    LONG login_id; /
    USB_USER_LOGIN_INFO login_info = {0}; //登录配置结构体
    USB_DEVICE_REG_RES reg_result = {0}; //注册成功结构体

    setup_chdir(); //设置路径
    if (!USB_Init()) return -1; //usb初始化,摄像头会切换到usb模式

    dev_count = USB_GetDeviceCount(); //获取连接的usb摄像头数量
    if (dev_count <= 0) { USB_Cleanup(); return -1; }
    printf("Devices: %d\n", dev_count);

    dev_list = malloc(dev_count * sizeof(USB_DEVICE_INFO)); //为每个设备分配内存
    USB_EnumDevices(dev_count, dev_list);

    login_info.dwSize = sizeof(login_info); //配置登录信息
    login_info.dwTimeout = 5000;
    login_info.dwVID = dev_list[0].dwVID;
    login_info.dwPID = dev_list[0].dwPID;
    login_info.byLoginMode = 1;
    memcpy(login_info.szSerialNumber, dev_list[0].szSerialNumber, sizeof(login_info.szSerialNumber));
    memcpy(login_info.szUserName, "admin", 5);
    memcpy(login_info.szPassword, "12345", 5);

    reg_result.dwSize = sizeof(reg_result);
    login_id = USB_Login(&login_info, &reg_result); //登录测试
    if (login_id < 0) { printf("Login fail\n"); camera_shutdown(-1, -1); return -1; }
    printf("Login OK login_id=%ld\n", (long)uid);
    return (int)login_id;
}

配置

int camera_configure(LONG uid)
{
    USB_COMMON_COND channel_cond = {0};
    USB_CONFIG_INPUT_INFO input_info = {0};
    USB_CONFIG_OUTPUT_INFO output_info = {0};

    channel_cond.dwSize = sizeof(channel_cond);
    channel_cond.byChannelID = USB_CHANNEL_IR;

    /* ---- 配置测温流(coding type 8 = 测温+YUV) ---- */
    USB_THERMAL_STREAM_PARAM thermal_param = {0};
    thermal_param.dwSize = sizeof(thermal_param);
    thermal_param.byVideoCodingType = 8; //模式
    thermal_param.dwWidth  = 4;    /* 根据 YUV_MODE 选择传输帧宽 */
    thermal_param.dwHeight = 5188;    /* 根据 YUV_MODE 选择传输帧高 */
    thermal_param.dwFrameRate = 25;  //帧数
    input_info.lpCondBuffer = &channel_cond;
    input_info.dwCondBufferSize = sizeof(channel_cond);
    input_info.lpInBuffer = &thermal_param;
    input_info.dwInBufferSize = sizeof(thermal_param);
    if (!USB_SetDeviceConfig(uid, USB_SET_THERMAL_STREAM_PARAM, &input_info, &output_info))
        { printf("Set thermal param fail\n"); return 0; }

    /* ---- 配置视频格式为 YUY2 ---- */
    USB_VIDEO_PARAM video_param = {0};
    video_param.dwVideoFormat = USB_STREAM_YUY2;
    video_param.dwWidth  = 4;
    video_param.dwHeight = 5188;
    video_param.dwFramerate = 25;
    memset(&input_info, 0, sizeof(input_info));
    memset(&output_info, 0, sizeof(output_info));
    input_info.lpCondBuffer = &channel_cond;
    input_info.dwCondBufferSize = sizeof(channel_cond);
    input_info.lpInBuffer = &video_param;
    input_info.dwInBufferSize = sizeof(video_param);
    if (!USB_SetDeviceConfig(login_id, USB_SET_VIDEO_PARAM, &input_info, &output_info))
        { printf("Set video param fail\n"); return 0; }
    return 1;
}

回调开启

/* 完整帧数据(协议头 + 测温区 + YUY2,按 YUV_MODE 定长) */
static uint8_t frame_data[HEADER_BYTES + TEMP_BYTES + YUV_BYTES];
static pthread_mutex_t frame_mutex = PTHREAD_MUTEX_INITIALIZER;  /* 保护 frame_data/frame_ready/ */
static volatile int frame_ready = 0;   /* 新帧到达标志:on_frame 置 1,camera_get_frame 消费后置 0 */
void CALLBACK on_frame(LONG handle, USB_FRAME_INFO *frame, void *user)
{
    (void)handle;
    (void)user;
    if (!frame || !frame->pBuf) return;
    if (frame->dwBufSize < YUV_OFFSET + YUV_BYTES) return;

    pthread_mutex_lock(&frame_mutex);
    memcpy(frame_data, frame->pBuf, YUV_OFFSET + YUV_BYTES);
    frame_ready = 1;
    pthread_mutex_unlock(&frame_mutex);
}
int camera_start_stream(LONG uid)
{
    USB_STREAM_CALLBACK_PARAM callback_param = {0};
    callback_param.dwSize = sizeof(callback_param);
    callback_param.dwStreamType = USB_STREAM_YUY2;
    callback_param.funcStreamCallBack = on_frame;
    LONG stream_handle = USB_StartStreamCallback(uid, &callback_param);
    if (stream_handle < 0) { printf("Start stream fail\n"); return -1; }
    printf("Stream started\n");
    return (int)stream_handle;
}

其他地方获取回调

int camera_get_frame(uint8_t *buf)
{
    int ready;
    pthread_mutex_lock(&frame_mutex);
    ready = frame_ready;
    if (ready) {
        memcpy(buf, frame_data + YUV_OFFSET, YUV_BYTES);
        frame_ready = 0;
    }
    pthread_mutex_unlock(&frame_mutex);
    return ready;
}

结束

void camera_shutdown(LONG uid, int stream_handle)
{
    if (stream_handle >= 0) USB_StopChannel(uid, (DWORD)stream_handle);
    if (uid >= 0) USB_Logout(uid);
    free(dev_list);
    dev_list = NULL;
    USB_Cleanup();
}