Min undequeued buffer count exceeded

2019-06-16 02:19发布

问题:

I am using a SurfaceTexture to get preview frames in the following way.

First, I set a preview texture:

camera.setPreviewTexture(new SurfaceTexture(0));

Then, just before starting the preview and then each time onPreviewFrame is called, I set the callback buffer like this:

camera.addCallbackBuffer(buffer);
camera.setPreviewCallbackWithBuffer(this);

It works. Sometimes, I take a picture using camera.takePicture(null, null, callback), which results in calling onPictureTaken successfully. The image is saved. Since I want to restart the preview after the picture has been taken, I do the following:

try
{
    camera.setPreviewTexture(new SurfaceTexture(0));
    camera.startPreview();
}
...

The preview restarts and everything seems to be fine. But the following error is reported in my Logcat, seemingly after the preview has be restarted:

E/BufferQueue﹕ [unnamed-5682-5] dequeueBuffer: min undequeued buffer count (2) exceeded (dequeued=5 undequeudCount=1)

Am I missing something? Should I release the old texture at some point?

Configuration: Samsung Galaxy S4, Samsung Galaxy S5, Nexus 5, running on Android KitKat.

EDIT: I am not sure wether it is linked or not, but after a while, my App does not take pictures anymore and the following messages appear continuously in my Logcat:

E/LocSvc_api_v02(  318): I/---> locClientSendReq line 2332         QMI_LOC_INJECT_SENSOR_DATA_REQ_V02
E/gsiff_dmn(  318): I/loc_api_resp_ind_callback: Received LocAPI Resp ind = 77
E/LocSvc_api_v02(  318): D/loc_sync_process_ind:172]: loc_sync_array not in use 
E/LocSvc_utils_q(  318): D/msg_q_rcv: Received message 0xB899D940 rv = 0
E/gsiff_dmn(  318): I/gsiff_data_task: Handling message type = 4
E/gsiff_dmn(  318): I/gsiff_daemon_inject_sensor_data_handler: Sending Sensor Data to     LocApi. opaque_id = 1226

E/LocSvc_api_v02(  318): I/---> locClientSendReq line 2332 QMI_LOC_INJECT_SENSOR_DATA_REQ_V02
E/gsiff_dmn(  318): I/loc_api_resp_ind_callback: Received LocAPI Resp ind = 77
E/LocSvc_api_v02(  318): D/loc_sync_process_ind:172]: loc_sync_array not in use 
E/mm-camera(  284): [cpp_hardware_process_frame:997] Too many cpp frames dropped!!
E/mm-camera(  284): cpp_thread_handle_process_buf_event:224] get buffer fail. drop frame id:1845 identity:0x20002

W/QCamera2HWI(  269): [CHECK_BUF_LOCK] Too many preview buffer is locked by     surfaceflinger : 29
E/mm-camera(  284): [cpp_hardware_process_frame:997] Too many cpp frames dropped!!
E/mm-camera(  284): cpp_thread_handle_process_buf_event:224] get buffer fail. drop frame     id:1846 identity:0x20002

EDIT 2: If, instead of a new SurfaceTexture(0), I always use the same SurfaceTexture (that I keep as a member), then some errors disappear and the App continues to work. The min undequeued buffer count exceeded error and the Too many preview buffer is locked by surfaceflinger warning stay.

回答1:

It seems that the camera is holding something in its buffer that is not dequeued by your activity. You have to find the way to clear the camera buffer when you start a new preview.

As you can find in Android documentation about Camera class :

The buffer queue will be cleared if this method [setPreviewCallbackWithBuffer] is called with a null callback, setPreviewCallback(Camera.PreviewCallback) is called, or setOneShotPreviewCallback(Camera.PreviewCallback) is called.

So maybe it is enough to remove your callback when you take a picture and then reinstatiate it when you restart your preview.