I have a native function which signature is like -
void onRecvData(const unsigned char* pData, int length)
I need to pass this pData
from C++ to a Java method public void OnrecvData(byte[] data)
without copying the data. Currently I am doing this by allocating jByteBuffer
and using SetByteArrayRegion
. But I think this approach doesn't avoid copy. I am looking for an approach like the other way GetDirectBufferAddress
and pass a pointer to a starting address and length to avoid copy.
Thanks in advance!
EDIT 1
I won't modify the data in Java layer. Read-only access will be okay.
EDIT 2
You can dequeueInputBuffer(), pass that buffer into native code, and memcpy() the data. I'm 99% sure the MediaCodec buffers are direct ByteBuffers, so you can get the address and length using JNI functions. How you call dequeueInputBuffer() is up to you. You have to use the buffers returned by MediaCodec, so one copy is unavoidable, but at least it's the encoded data. (For the output side, you want to use a Surface, for multiple reasons.)
My current code is like this -
// ..................
// ..................
int inIndex = mMediaCodec.dequeueInputBuffer(mTimeoutUs);
if (inIndex >= 0) {
ByteBuffer buffer;
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
buffer = mMediaCodec.getInputBuffers()[inIndex];
buffer.clear();
} else {
buffer = mMediaCodec.getInputBuffer(inIndex);
}
if (buffer != null) {
buffer.put(encodedData, 0, encodedDataLength);
long presentationTimeUs = System.nanoTime() / 1000l;
mMediaCodec.queueInputBuffer(inIndex, 0, encodedDataLength, presentationTimeUs, 0);
}
}
Here encodedData
is byte[]
which is being received from native layer from unsigned char*
using one time memory allocation and doing SetByteArrayRegion
every time. So I am requiring one copy in my current implementation like memcpy
way you suggested. Both these approach require one copy, but is my current implementation is less efficient than your suggested one (sending dequeueInputBuffer
address reference and memcpy
)? Like put
ing byte[]
onto ByteBuffer
I did in Java Layer?
EDIT 3
Well, ByteBuffer.put(byte[], offset, offsetLength)
seems like copying whole byte[]
array into ByteBuffer
like memcpy
. So its another copy in Java layer also. I am going to implement your idea now. Thanks :)