opencv_processor.cpp
1.9 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
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
53
54
55
56
57
58
59
60
61
#include <jni.h>
#include <opencv2/core.hpp>
#include <opencv2/imgproc.hpp>
using namespace cv;
extern "C" JNIEXPORT jobjectArray JNICALL
Java_io_livekit_android_room_track_video_OpenCVVideoProcessor_processI420(
JNIEnv *env,
jobject thiz,
jbyteArray y,
jbyteArray u,
jbyteArray v,
jint width,
jint height,
jint rotation,
jlong timestamp) {
jbyte* yPtr = env->GetByteArrayElements(y, NULL);
jbyte* uPtr = env->GetByteArrayElements(u, NULL);
jbyte* vPtr = env->GetByteArrayElements(v, NULL);
Mat yuvMat(height + height / 2, width, CV_8UC1);
memcpy(yuvMat.data, yPtr, height * width);
memcpy(yuvMat.data + height * width, uPtr, (height / 2) * (width / 2));
memcpy(yuvMat.data + height * width + (height / 2) * (width / 2), vPtr, (height / 2) * (width / 2));
Mat rgbMat;
cvtColor(yuvMat, rgbMat, COLOR_YUV2RGB_I420);
Mat grayMat;
cvtColor(rgbMat, grayMat, COLOR_RGB2GRAY);
cvtColor(grayMat, rgbMat, COLOR_GRAY2RGB);
Mat newYuvMat;
cvtColor(rgbMat, newYuvMat, COLOR_RGB2YUV_I420);
int ySize = height * width;
int uvSize = (height / 2) * (width / 2);
jbyteArray newY = env->NewByteArray(ySize);
env->SetByteArrayRegion(newY, 0, ySize, (jbyte*)newYuvMat.data);
jbyteArray newU = env->NewByteArray(uvSize);
env->SetByteArrayRegion(newU, 0, uvSize, (jbyte*)(newYuvMat.data + ySize));
jbyteArray newV = env->NewByteArray(uvSize);
env->SetByteArrayRegion(newV, 0, uvSize, (jbyte*)(newYuvMat.data + ySize + uvSize));
jclass byteArrayClass = env->FindClass("[B");
jobjectArray result = env->NewObjectArray(3, byteArrayClass, NULL);
env->SetObjectArrayElement(result, 0, newY);
env->SetObjectArrayElement(result, 1, newU);
env->SetObjectArrayElement(result, 2, newV);
env->ReleaseByteArrayElements(y, yPtr, 0);
env->ReleaseByteArrayElements(u, uPtr, 0);
env->ReleaseByteArrayElements(v, vPtr, 0);
return result;
}