Skip to content

Instantly share code, notes, and snippets.

@alexcohn
Created September 29, 2020 12:49
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save alexcohn/7697892f78f960e823ab8a6e019ce4bb to your computer and use it in GitHub Desktop.
Save alexcohn/7697892f78f960e823ab8a6e019ce4bb to your computer and use it in GitHub Desktop.
JNIEXPORT jbyteArray JNICALL
Java_com_company_app_tools_NV21FrameRotator_rotateNV21(JNIEnv *env, jclass thiz,
jbyteArray data, jbyteArray output,
jint width, jint height, jint rotation) {
clock_t start, end;
double cpu_time_used;
start = clock();
jbyte *dataPtr = (*env)->GetByteArrayElements(env, data, NULL);
jbyte *outputPtr = (*env)->GetByteArrayElements(env, output, NULL);
unsigned int frameSize = width * height;
bool swap = rotation % 180 != 0;
bool xflip = rotation % 270 != 0;
bool yflip = rotation >= 180;
for (unsigned int j = 0; j < height; j++) {
for (unsigned int i = 0; i < width; i++) {
unsigned int yIn = j * width + i;
unsigned int wOut = swap ? height : width;
unsigned int hOut = swap ? width : height;
unsigned int iSwapped = swap ? j : i;
unsigned int jSwapped = swap ? i : j;
unsigned int iOut = xflip ? wOut - iSwapped - 1 : iSwapped;
unsigned int jOut = yflip ? hOut - jSwapped - 1 : jSwapped;
unsigned int yOut = jOut * wOut + iOut;
outputPtr[yOut] = (jbyte) (0xff & dataPtr[yIn]);
}
}
for (unsigned int j = 0; j < height; j+=2) {
for (unsigned int i = 0; i < width; i+=2) {
unsigned int uIn = frameSize + (j >> 1u) * width + (i & ~1u);
unsigned int vIn = uIn + 1;
unsigned int wOut = swap ? height : width;
unsigned int hOut = swap ? width : height;
unsigned int iSwapped = swap ? j : i;
unsigned int jSwapped = swap ? i : j;
unsigned int iOut = xflip ? wOut - iSwapped - 1 : iSwapped;
unsigned int jOut = yflip ? hOut - jSwapped - 1 : jSwapped;
unsigned int uOut = frameSize + (jOut >> 1u) * wOut + (iOut & ~1u);
unsigned int vOut = uOut + 1;
outputPtr[uOut] = (jbyte) (0xff & dataPtr[uIn]);
outputPtr[vOut] = (jbyte) (0xff & dataPtr[vIn]);
}
}
(*env)->ReleaseByteArrayElements(env, data, dataPtr, JNI_ABORT);
(*env)->ReleaseByteArrayElements(env, output, outputPtr, 0);
end = clock();
cpu_time_used = ((double) (end - start)) / CLOCKS_PER_SEC;
char str[10];
sprintf(str, "%f", cpu_time_used * 1000);
__android_log_write(ANDROID_LOG_ERROR, "NV21FrameRotator", str);
return output;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment