ByteBuffer pixelsBuffer = (ByteBuffer) GLES30.glMapBufferRange(GLES30.GL_PIXEL_PACK_BUFFER, 0, mViewWidth * mViewHeight * 4, GLES30.GL_MAP_READ_BIT);
if(mSkipFirstFrame)
{
// Skip the first frame as the PBO's have nothing in them until the second render cycle
try {
// this make weird error (or even only pixelsBuffer.array() also make weird error)
System.arraycopy(pixelsBuffer.array(), 0, arrayForTest, 0, mViewWidth * mViewHeight * 4);
// ... SOME CODE AT HERE WILL BE NOT EXCUTE
// this work perfectly
// Bitmap bm = Bitmap.createBitmap(frameWidth, frameHeight, Bitmap.Config.ARGB_8888);
// bm.copyPixelsFromBuffer(pixelsBuffer);
// save bm to file
} catch (Exception e) { log exception}
// ... SOME CODE AT HERE WILL BE EXCUTE
}
If I store pixelsBuffer to file, then everything work perfectly.
Else if I copy pixelsBuffer to byte array or other ByteBuffer (using System.arraycopy), then this make weird error. Are there any way (fastest speed) to copy pixelsBuffer ?
ByteBuffer.array() will throw UnsupportedOperationException if the buffer isn’t backed by an array (byte[]) (and a mapped region won’t be). You’re supposed to call .hasArray() to check that it’s backed by an array before calling .array(). Reference.
If you want to copy the contents of a ByteBuffer to a byte[], use the .get() method.
Thanks @GClements , I tried get() method, it worked, but its runtime too slow (150 ms), even slower than store to file (70 ms). Frame resolution is 1920x1080. Are there fastest way to copy it ?
My task is draw filter (skin smooth) and encode it (with software encoder). Currently, applied filter frame is stored in pixelsBuffer. So I need send it to JNI (JNI will convert rgba to I420 for encoder), then wakeup encoder thread excute encode incoming frame (encoder must be Software Encoder)
I found bottleneck point. It slow because copying data bytebuffer.get(dest).
This not happen when I dont use PBO. Because after glReadPixels call, I got bytebuffer that has array backs this buffer. So I pass bytebuffer.array() to JNI. This verry fast.