Java – Understanding and accelerating addCallbackBuffer

Understanding and accelerating addCallbackBuffer… here is a solution to the problem.

Understanding and accelerating addCallbackBuffer

I would like to understand how the preview buffer passed to addCallbackBuffer has to do with the byte[] array passed by onPreviewFrame, and the following related question is raised.

Q1。 I’m guessing that the buffer passed in addCallbackBuffer is used to store new camera frames, and before onPreviewFrame is called, the buffer is copied into the data buffer passed through >onPreviewFrame. If that’s the case, it means I can reuse my preview frame buffer by calling addCallbackBuffer as soon as onPreviewFrame is entered, and note at the end of the function when I’m done processing the buffer returned by onPreviewFrame. Is that right?

Q2。 I’m also unclear about the mechanism for using two preview framebuffers. Let’s say I add two private byte[] preview buffers during initialization, like this:

addCallbackBuffer(mPreviewBuffer1);
addCallbackBuffer(mPreviewBuffer2);

How do I know which preview buffer is used in onPreviewFrame so that I can re-add the correct preview frame buffer using addCallbackBuffer again?

private byte[] mPreviewBuffer1;
private byte[] mPreviewBuffer1;
...
public void onPreviewFrame(byte[] camera, Camera c) {
  ...
   how do I decide which buffer to re-add?
  c.addCallbackBuffer(mPreviewBuffer1);
  c.addCallbackBuffer(mPreviewBuffer2);
  ...
}

Q3。 Do I correctly understand that another thread is responsible for fetching the framebuffer, i.e. we capture frames when onPreviewFrame executes as long as there is a preview buffer in the queue? If that’s not the case, then having two callback buffers won’t help speed, right?

Solution

Q1 Yes, if you don’t care about its contents, you can return the buffer to the camera in advance. After calling addCallbackBuffer() for it, you may not be able to read data from that buffer, or you can read but the pixel data will be wrong.


Q2 You can simply return the buffer you received in the callback to the camera, ie

@Override public void onPreviewFrame(byte[] data, Camera camera) {
  ...
  camera.addCallbackBuffer(data);
}

In this case, you don’t care about data == mPreviewBuffer1 or data == mPreviewBuffer2. But the following code is also fine:

private byte[][] mPrevieBuffers = new byte[4][];
@Override public void onPreviewFrame(byte[] data, Camera camera) {
  for (int i=0; i<mPreviewBuffers.length; i++) {
    if (data == mPreviewBuffers[i]) {
       processData(i);
    }
  }
}

Q3 is correct, onPreviewFrame() executes in parallel with filling other buffers, but all onPreviewFrame() callbacks call the line at the same time. If you want to process as many preview frames as possible, you should a) delegate processing to the worker (especially on multicore devices). Note that you can safely call addCallbackBuffer() from other threads; b) start the camera on a separate Looper make onPreviewFrame() Detached from the UI thread.

Related Problems and Solutions