videopipe_rk3568.cpp 5.28 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13
//
// Created by dizi on 2024/8/2.
//

#include "videopipe_rk3568.h"


JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved) {
    global_jvm = vm;
    JNIEnv *env;
    if (vm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6) != JNI_OK) {
        return JNI_ERR;
    }
14
    java_class_video_pipe_manager = (jclass)env->NewGlobalRef(env->FindClass("com/wmdigit/feature/ai/videopipe/VideoPipeRepository"));
15 16 17 18 19 20 21 22 23

    return JNI_VERSION_1_6;
}

/**
 * 算法初始化
 */
extern "C"
JNIEXPORT jint JNICALL
24
Java_com_wmdigit_feature_ai_videopipe_VideoPipeRepository_init(JNIEnv *env, jobject thiz,
25 26
                                                         jstring modelBackBonePath,
                                                         jstring modelC3dPath) {
27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52
    int size_back_bone, size_c3d;
    unsigned char* data_back_bone = read_file_byte(env, modelBackBonePath, size_back_bone);
    unsigned char* data_c3d = read_file_byte(env, modelC3dPath, size_c3d);
    init_info.lat3d_backbone_model_data = data_back_bone;
    init_info.lat3d_backbone_model_len = size_back_bone;
    init_info.lat3d_c3d_model_data = data_c3d;
    init_info.lat3d_c3d_model_len = size_c3d;
    init_info.lat3d_enable = true;
    init_info.gpu_enable = true;

    motion = new libvideopipe::MotionVideoPipe();
    // 初始化
    int ret_init = motion->Init(init_info);
    // 设置回调
    if (ret_init == 0){
        libvideopipe::VideoPipeCallback callback = trace_result_callback;
        motion->SetResultCallback(callback, &user);
    }
    return ret_init;
}

/**
 * 配置空盘图
 */
extern "C"
JNIEXPORT jint JNICALL
53
Java_com_wmdigit_feature_ai_videopipe_VideoPipeRepository_setMarkMat(JNIEnv *env, jobject thiz,
54
                                                               jobject bitmap) {
55 56 57 58 59 60 61 62 63 64 65
    // Bitmap转mat
    cv::Mat mat = convert_bitmap_to_mat(env, bitmap);
    // RGBA转RGB
    cv::Mat mat_rgb = cv::Mat();
    cv::cvtColor(mat, mat_rgb, CV_RGBA2RGB);
    // 设置空盘图
    return motion->SetMarkMat(mat_rgb.clone());
}

extern "C"
JNIEXPORT void JNICALL
66
Java_com_wmdigit_feature_ai_videopipe_VideoPipeRepository_feedFrame(JNIEnv *env, jobject thiz,
67
                                                              jobject bitmap) {
68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116
    // Bitmap转mat
    cv::Mat mat = convert_bitmap_to_mat(env, bitmap);
    // rgba转rgb
    cv::Mat mat_rgb = cv::Mat();
    cv::cvtColor(mat, mat_rgb, CV_RGBA2RGB);
    // 组装入参
    libvideopipe::MOTION_VIDEOPIPE_INPUT input;
    input.img = mat_rgb.clone();
    input.pts = get_timestamp();
    input.debug_mode = false;

    motion->FeedFrame(input);
}

/**
 * FeedFrame的回调
 * @param data
 * @param len
 * @param user
 */
void trace_result_callback(const char* data, int len, void* user)
{
    auto* output = (libvideopipe::MOTION_VIDEOPIPE_OUTPUT*) data;
    if (output->status == libvideopipe::MOTION_STATUS_TYPES::MOTION_IN)
    {
        LOGD("进入");
        feed_frame_callback(2);
    }
    else if (output->status == libvideopipe::MOTION_STATUS_TYPES::MOTION_OUT)
    {
        LOGD("离开");
        feed_frame_callback(3);
    }
    else if (output->status == libvideopipe::MOTION_STATUS_TYPES::MOTION_STATIC_EMPTY)
    {
    }
    else if (output->status == libvideopipe::MOTION_STATUS_TYPES::MOTION_STATIC_FULL)
    {
    }
    else{
    }
}

void feed_frame_callback(int state){
    JNIEnv *env;
    global_jvm->GetEnv((void**)&env, JNI_VERSION_1_6);
    jmethodID j_method_instance = env->GetStaticMethodID(
            java_class_video_pipe_manager,
            "getInstance",
117
            "()Lcom/wmdigit/feature/ai/videopipe/VideoPipeRepository;"
118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172
    );
    jobject instance=env->CallStaticObjectMethod(java_class_video_pipe_manager, j_method_instance);
    jmethodID j_method_in_out;
    if (state == 2){
        j_method_in_out = env->GetMethodID(java_class_video_pipe_manager, "objectIn", "()V");
    }
    else{
        j_method_in_out = env->GetMethodID(java_class_video_pipe_manager, "objectOut", "()V");
    }
    env->CallVoidMethod(instance, j_method_in_out);
    env->DeleteLocalRef(instance);
}


/**
 * 读本地文件,用于加载模型
 * @param env
 * @param file_path
 * @return
 */
unsigned char* read_file_byte(JNIEnv *env, jstring file_path, int& size){
    const char *jpath = env->GetStringUTFChars(file_path, nullptr);
    FILE *pFile;
    pFile = fopen(jpath, "rw");
    if (pFile == nullptr) {
        env->ReleaseStringUTFChars(file_path, jpath);
        return nullptr;
    }
    unsigned char *pBuf;  //定义文件指针
    fseek(pFile, 0, SEEK_END); //把指针移动到文件的结尾 ,获取文件长度
    size = (int) ftell(pFile); //获取文件长度
    LOGD("size:%d", size);
    pBuf = new unsigned char[size + 1]; //定义数组长度
    rewind(pFile); //把指针移动到文件开头 因为我们一开始把指针移动到结尾,如果不移动回来 会出错
    fread(pBuf, 1, (size_t) size, pFile); //读文件
    pBuf[size] = 0; //把读到的文件最后一位 写为0 要不然系统会一直寻找到0后才结束
    fclose(pFile); // 关闭文件
    env->ReleaseStringUTFChars(file_path, jpath);
    return pBuf;
}

/**
 * 获取时间戳
 * @return
 */
long long get_timestamp()
{
    long long tmp;
    struct timeval tv;
    gettimeofday(&tv, nullptr);
    tmp = tv.tv_sec;
    tmp = tmp * 1000;
    tmp = tmp + (tv.tv_usec / 1000);
    return tmp;
}