Неверное количество счетчиков, количество которых не определено

Я использую SurfaceTexture для получения кадров предварительного просмотра следующим образом.

Сначала я установил текстуру предварительного просмотра:

camera.setPreviewTexture(new SurfaceTexture(0));

Затем, перед запуском предварительного просмотра, а затем каждый раз, когда вызывается onPreviewFrame, я устанавливаю буфер обратного вызова следующим образом:

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

Это работает. Иногда я делаю снимок с помощью camera.takePicture(null, null, callback), что приводит к успешному вызову onPictureTaken. Изображение сохраняется. Поскольку я хочу перезапустить предварительный просмотр после того, как изображение было снято, я делаю следующее:

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

Предварительный просмотр перезапускается, и все кажется прекрасным. Но в моем Logcat появляется следующая ошибка, по-видимому, после перезапуска предварительного просмотра:

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

Я что-то упустил? Должен ли я отпустить старую текстуру в какой-то момент?

Конфигурация: Samsung Galaxy S4, Samsung Galaxy S5, Nexus 5, работающая на Android KitKat.

EDIT: Я не уверен, что это связано или нет, но через некоторое время мое приложение больше не снимает фотографии, и в моем 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: Если вместо new SurfaceTexture(0), я всегда использую тот же SurfaceTexture (который я сохраняю как член), затем некоторые ошибки исчезают, и приложение продолжает работать. Ошибка min undequeued buffer count exceeded и предупреждение Too many preview buffer is locked by surfaceflinger.

Ответ 1

Кажется, что камера держит что-то в своем буфере, которое не удаляется вашей деятельностью. Вы должны найти способ очистить буфер камеры при запуске нового предварительного просмотра.

Как вы можете найти в документации на Android о классе камеры:

Буферная очередь будет очищена, если вызывается этот метод [setPreviewCallbackWithBuffer] с нулевым обратным вызовом, вызывается setPreviewCallback (Camera.PreviewCallback) или вызывается setOneShotPreviewCallback (Camera.PreviewCallback).

Поэтому, возможно, этого достаточно, чтобы удалить ваш обратный вызов, когда вы делаете снимок, а затем восстанавливайте его при перезапуске предварительного просмотра.