I have created an android service which exposes an interface to the applications to accept a camera frame byte array. The service uses a native library to process this camera frame and returns some data about the camera frame. The goal is to be able to process camera preview frames in real time.
Problem - My AIDL file has an API called initFrame(in byte[] frame). Whenever I call this API from an application(running in a separate process), I get an exception - TransactionTooLargeException
This is because the size of the byte array is > 1MB and the binder transaction buffer has a limited fixed size of 1MB. Even if the size limit was bigger, it is very inefficient to copy large buffers for real time processing.
Question - Is there a way in android to share memory between two dalvik processes which can help solve the problem? I looked at MemoryFile but it seems MemoryFile can only be used to share memory between processes using hidden APIs at this point.
Context switching between processes is more expensive. Processes don't share memory with other processes. Threads share memory with other threads of the same process.
To share big data: named shared-memory The fastest way to handle this is to create a file mapping object, map the file object into memory space, notify the parent process of the file mapping handle and data size, and then dump the data to the mapped buffer for the parent process to read.
I would use a socket connection between the 2 processes for this type of transaction. Both sides can stream the data and buffer as necessary, without tying up a lot of resources. It should be relatively easy for your service to listen on a socket and to have the clients connect to the socket and send data.
Take a look at ashmem subsystem which is a shared memory allocator, similar to POSIX SHM but with different behavior and sporting a simpler file-based API.
Perhaps it is what you are looking for:
int ashmem_create_region(const char *name, size_t size);
int ashmem_set_prot_region(int fd, int prot);
int ashmem_pin_region(int fd, size_t offset, size_t len);
int ashmem_unpin_region(int fd, size_t offset, size_t len);
int ashmem_get_size_region(int fd);
this is defined in system/core/include/cutils/ashmem.h
.
If you are able to modify Android system, you can enlarge the transaction size. The Binder transaction buffer has a limited fixed size, currently 1Mb
There is a parameter in ProcessState.cpp
#define BINDER_VM_SIZE ((1*1024*1024) - (4096 *2))
please try to increase this value.
If you are not able to do this, try to separate your data into several transactions.
Moreover, you can take other IPC mechanism like employing native code to use ashmem in system/core/include/cutils/ashmem.h
. It is not difficult. As far as I know, some vendors use ashmem to implement binder transactions on some kernels without binder driver support. You can also use socket.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With