NDK java 與 c++ byte數組轉遞

  1. 實現一個文件的拷貝操作通過JNI 調用
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.lang.Thread;

public class LocalFileProduce extends Thread implements IDataProduce
{
    public File file = null;
    public FileInputStream input = null;

    @Override
    public void produceData() {

        byte[] data = new byte[1024];

        file = new File("/storage/emulated/0/1/123.mp4");
        try {
            input = new FileInputStream(file);
            int n = -1;
            while((n = input.read(data, 0, data.length)) != -1){
                produceData(data, n);
            }

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    public void run(){
        produceData();
        stopWork();
    }

    public native void produceData(byte[] data, int len);

    public native void stopWork();

}

2.在C++開啓線程,異步寫文件

#include <jni.h>
#include <string>
#include "AndroidLog.h"
#include "pthread.h"
#include "queue"
#include "unistd.h"

#include <sys/stat.h>
#include <sys/time.h>
#include <stdlib.h>
#include <fcntl.h>




pthread_t produc;
pthread_t custom;
pthread_mutex_t mutex;
pthread_cond_t cond;
bool isStop = false;

struct MData{
    jbyte* data;
    int len;
};

std::queue<MData> queue;

static const char* const filename = "/storage/emulated/0/1/123_dat.mp4";
int fd = 0;




extern "C"
JNIEXPORT void JNICALL
 Java_com_syf_videoplay_LocalFileProduce_produceData(JNIEnv *env, jobject thiz, jbyteArray data,
                                                    jint len) {
    //jbyte* bytedata = env->GetByteArrayElements(data, 0); //C++ 寫法

    jsize size = env->GetArrayLength(data);
    if(size != len)
        size = len;


    MData mData;
    jbyte* dst = (jbyte*) malloc(size* sizeof(jbyte));
    memset(dst, 0, sizeof(jbyte)*size);
    env->GetByteArrayRegion(data, 0, size, dst);

    //memcpy(bytedata,dst, size);
    //mData.data = bytedata;
    mData.data = dst;
    mData.len = size;


    pthread_mutex_lock(&mutex);
    queue.push(mData);
    pthread_cond_signal(&cond);
    pthread_mutex_unlock(&mutex);
    usleep(1);

    //env->ReleaseByteArrayElements(data, bytedata,JNI_COMMIT);

}




void *customRun(void *data){
    DEBUG__TIME0;

    while(!isStop){
        pthread_mutex_lock(&mutex);

        if(queue.size() > 0){
            MData tmp = queue.front();
            if(fd != 0){
                write(fd, tmp.data, tmp.len);
                free(tmp.data);
                tmp.data = NULL;
            }

            queue.pop();
        }else {
            //LOGD("custom wait");
            pthread_cond_wait(&cond, &mutex);
        }

        pthread_mutex_unlock(&mutex);
        usleep(1);
    }

    DEBUG__TIME1;


    //%4.4f 前面4表示總數字位爲4,不滿4則右對齊,後面的4表示小數點後保留4位有效數字
    LOGD("Running times:detect facedetect %4.4fms" , RUN_TIME(TIME1 - TIME0));
    pthread_exit(&custom);
}



extern "C"
JNIEXPORT void JNICALL
Java_com_syf_videoplay_LocalFileProduce_stopWork(JNIEnv *env, jobject thiz) {
    pthread_mutex_lock(&mutex);
    isStop = true;
    pthread_cond_signal(&cond);
    pthread_mutex_unlock(&mutex);
    close(fd);
}




extern "C"
JNIEXPORT void JNICALL
Java_com_syf_videoplay_MainActivity_perpareWork(JNIEnv *env, jobject thiz) {

    fd = open(filename, O_CREAT  | O_RDWR, 0666);
    LOGD("file fd %d", fd);
    pthread_mutex_init(&mutex, NULL);
    pthread_cond_init(&cond, NULL);

    //pthread_create(&produc, NULL, produceRun, NULL);
    pthread_create(&custom, NULL, customRun, NULL);

}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章