Camera onPreviewFrame() is not called on some devices (no preview display present)

Trigary :

On one of my two devices, onPreviewFrame is not called, despite me using the same code.

I am trying to get, process (with OpenCV) and then display the camera frames using the deprecated camera API. (Because I am using a LEGACY device and the deprecated API provides better performance for it.)

This means that I do not want to directly display the preview frames, but I was able to determine that on this device, setting a display is necessary for previews to be taken. This means I have to set some sort of high-performance dummy display. My options are: setPreviewDisplay -> SurfaceHolder and setPreviewTexture -> SurfaceTexture.

Another thing I learned is that setPreviewCallbackWithBuffer does not work either on this device: I have to use setPreviewCallback.

Ideally, I would want to detect whether I need these extra steps for previews to work: if not necessary, I do not want to do these on devices which do not require them.

I was unable to find a dummy SurfaceHolder for the setPreviewDisplay method, therefore I wasn't able to get preview callbacks to be called using that. On the other hand, setPreviewTexture with a new SurfaceTexture does make the onPreviewFrame get called, but I am constantly getting "BufferQueue has been abandoned" errors and the preview data seems incorrect as well: while I set the image format, the image created from said data is incorrect. Looking at different colors causes the image to show different colors. Again, the same code worked on another device and I set the image format, therefore the output should be valid.

My current code, where onPreviewFrame is called, but with invalid data:

camera = Camera.open();
camera.setPreviewTexture(new SurfaceTexture(1));
camera.setPreviewCallback(this);
camera.setParameters(configurator.getParameters()); //sets the resolution (same on both devices), the fps range and the format to ImageFormat.YV12 (or NV21, makes no difference)
camera.startPreview();

The phone for which a preview display is not necessary: Doogee X5 MAX
The phone which had issues: Samsung Galaxy J3 (2016)

Alex Cohn :

Re: dummy preview texture, this is the best workaround you can get. The official API requires that preview must go somewhere, and most devices enforce this policy.

There is no way to check at runtime whether the device delivers live preview without a 'sink' (surface or texture) to draw upon. In other similar situations, we are forced to maintain white-lists and black-lists of devices, based on QA lab experiments and end-user complaints. For some features, the technique is to try the optimal setup on the first run of your app (on the specific device), and, if it crashes or fails otherwise, use a less efficient alternative on the second attempt, and keep this flag in SharedPreferences for future launches.

Luckily, adding a dummy SurfaceTexture does not negatively effect performance even on devices that can work without it.

To avoid "BufferQueue has been abandoned" errors, add the dummy SurfaceTexture as a field in your activity or fragment.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=152662&siteId=1