Skip to content

Instantly share code, notes, and snippets.

@novodimaporo
Created September 13, 2017 05:48
Show Gist options
  • Save novodimaporo/37bfe09b59f513820ee8b3056d93dc5f to your computer and use it in GitHub Desktop.
Save novodimaporo/37bfe09b59f513820ee8b3056d93dc5f to your computer and use it in GitHub Desktop.
NV21 Utils, convert nv21 byte[] to dlib array2d
void convertNV21ToArray2d(JNIEnv* env, dlib::array2d<dlib::rgb_pixel>& out,
jbyteArray data, jint width, jint height) {
jbyte* yuv = env->GetByteArrayElements(data, 0);
int frameSize = width * height;
int y, u, v, uvIndex;
int r, g, b;
out.set_size((long) height, (long) width);
for(int row = 0; row < height; row++) {
for(int column = 0; column < width; column++) {
uvIndex = frameSize + (row >> 1) * width + (column & ~1);
y = 0xff & yuv[row * width + column] - 16;
v = 0xff & yuv[uvIndex] - 128;
u = 0xff & yuv[uvIndex+1] - 128;
y = y < 0 ? 0 : 1164 * y;
r = y + 1596 * v;
g = y - 813 * v - 391 * u;
b = y + 2018 * u;
out[row][column].red = (unsigned char)(r < 0 ? 0 : r > 255000 ? 255 : r/1000);
out[row][column].green = (unsigned char)(g < 0 ? 0 : g > 255000 ? 255 : g/1000);
out[row][column].blue = (unsigned char)(b < 0 ? 0 : b > 255000 ? 255 : b/1000);
}
}
}
void downScaleNV21(JNIEnv* env, jclass obj,
jbyteArray data, jint width, jint height) {
int width_ds = width/2;
int height_ds = height/2;
jbyte* yuv = env->GetByteArrayElements(data, 0);
jbyte* yuv_ds = new jbyte[((width/2) * (height/2) * 3) / 2];
int frameSize = width * height;
int frameSize_ds = width_ds * height_ds;
int y1, y2, y3, y4;
int u, v;
int uvIndex, uvIndex1, uvIndex2, uvIndex3, uvIndex4;
for(int row =0, row_ds = 0; row < height; row=+4, row_ds+=2) {
for(int column = 0, column_ds = 0; column < width; column=+4, column_ds+=2) {
// 0 1 2 3
// ______________________
// 0 | y1a | y1b | y2a | y2b |
// |-----+-----|-----+-----| ____ ____
// 1 | y1c | y1d | y2c | y2d | | y1 | y2 |
// -----------+----------- -> ----+----
// 2 | y3a | y3b | y4a | y4b | | y3 | y4 |
// |-----+-----|-----+-----| ---- ----
// 3 | y3c | y3d | y4c | y4d |
// ----------- -----------
y1 = (yuv[row * width + column] + // y1a
yuv[row * width + (column + 1)] + // y1b
yuv[(row + 1) * width + column] + // y1c
yuv[(row + 1) * width + (column + 1)])/4; // y1d
y2 = (yuv[row * width + (column + 2)] + // y2a
yuv[row * width + (column + 3)] + // y2b
yuv[(row + 1) * width + (column + 2)] + // y2c
yuv[(row + 1) * width + (column + 3)])/4; // y2d
y3 = (yuv[(row + 2) * width + column] + // y3a
yuv[(row + 2) * width + (column + 1)] + // y3b
yuv[(row + 3) * width + column] + // y3c
yuv[(row + 3) * width + (column + 1)])/4; // y3d
y4 = (yuv[(row + 2) * width + (column + 2)] + // y4a
yuv[(row + 2) * width + (column + 3)] + // y4b
yuv[(row + 3) * width + (column + 2)] + // y4c
yuv[(row + 3) * width + (column + 3)])/4; // y4d
uvIndex1 = frameSize + (row >> 1) * width + (column & ~1);
uvIndex2 = frameSize + (row >> 1) * width + ((column + 2) & ~1);
uvIndex3 = frameSize + ((row + 2) >> 1) * width + (column & ~1);
uvIndex4 = frameSize + ((row + 2) >> 1) * width + ((column + 2) & ~1);
uvIndex = frameSize_ds + (row_ds >> 1) * width_ds + (column_ds & ~1);
v = (yuv[uvIndex1] + yuv[uvIndex2] + yuv[uvIndex3] + yuv[uvIndex4])/4;
u = (yuv[uvIndex1+1] + yuv[uvIndex2+1] + yuv[uvIndex3+1] + yuv[uvIndex4+1])/4;
yuv_ds[row * width + column] = (jbyte) y1;
yuv_ds[row * width + (column + 1)] = (jbyte) y2;
yuv_ds[(row + 1) * width + column] = (jbyte) y3;
yuv_ds[(row + 1) * width + (column + 1)] = (jbyte) y4;
yuv_ds[uvIndex] = (jbyte) v;
yuv_ds[uvIndex + 1] = (jbyte) u;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment