android - Camera2api如何解决?E/BufferQueueProducer: dequeueBuffer: 试图超过最大出队缓冲区计数 (4)
问题描述
我正在使用
带有 sdk 28的 Samsung-A10
我正在尝试使用 camera2api 拍摄图像,但总是在收集 14 帧后我得到
I/com.oculid.daq: NativeAlloc concurrent copying GC freed 3481(447KB) AllocSpace objects, 33(1580KB) LOS objects, 49% free, 3MB/7MB, paused 149us total 174.997ms
D/NetworkManagementSocketTagger: tagSocket(92) with statsTag=0xffffffff, statsUid=-1
D/NetworkManagementSocketTagger: tagSocket(100) with statsTag=0xffffffff, statsUid=-1
D/NetworkManagementSocketTagger: tagSocket(96) with statsTag=0xffffffff, statsUid=-1
D/NetworkManagementSocketTagger: tagSocket(101) with statsTag=0xffffffff, statsUid=-1
D/NetworkManagementSocketTagger: tagSocket(106) with statsTag=0xffffffff, statsUid=-1
D/IR_CAMERA: camera stateCallback onError
E/BufferQueueProducer: [ImageReader-1280x720f100m1-965-0] dequeueBuffer: attempting to exceed the max dequeued buffer count (4)
我可以在某些手机型号中看到这种行为,我正在尝试了解此错误的含义以及如何解决它,我会为任何线索感到高兴。
我在这里附上我的 OnimageAvailable 以防万一
private ImageReader.OnImageAvailableListener readerListener = new ImageReader.OnImageAvailableListener() {
@RequiresApi(api = Build.VERSION_CODES.P)
@Override
/*
* gets a the "reader" the callback is associated with.
* transfer to bytes
*/
public void onImageAvailable(ImageReader reader) {
//Log.i(TAG,"readerListener on onImageAvailable");
long imageReaderTime = SystemClock.elapsedRealtimeNanos();
frameIndexForFileName++;
//Log.i(TAG, String.format("Frame index: %08d", frameIndexForFileName));
try (Image image = reader.acquireNextImage()) {
//convert the image to bytes
ByteBuffer buffer = image.getPlanes()[0].getBuffer();
byte[] bytes = new byte[buffer.capacity()];
buffer.get(bytes);
double frameCaptureDuration = (double) (SystemClock.elapsedRealtimeNanos() - imageReaderTime) / 1000000;
Log.i(TAG, String.format("TIME_MEASUREMENT: Capture of frame %08d took %f ms", frameIndexForFileName, frameCaptureDuration));
Bitmap bmp = BitmapFactory.decodeByteArray(bytes,0,bytes.length);
ByteArrayOutputStream stream = new ByteArrayOutputStream();
bmp.compress(Bitmap.CompressFormat.JPEG, 60, stream);
byte[] compressImage = stream.toByteArray();
bmp.recycle();
//image.close();
//reader.discardFreeBuffers();
imageListener.onImage(compressImage, imageReaderTime);
} catch (Exception e) {
e.printStackTrace();
Log.e(TAG, "!!!!!!!!!!!!!!!!onImageAvailable: " + e );
}
}
};
谢谢
解决方案
我找到了解决缓冲区问题的方法。将 ImageReader ImageFormat 从 JPEG 更改为原始格式(YUV_420_888 通常也用于视频)并将图像稍后转换为 RGB 用于 jpeg 解决了三星 A10 的问题,我还在三星 A5 和华为上对其进行了测试, Fairphone 和 Pocophone。它似乎适用于所有电话。我已经阅读了很多关于实时相机应用程序的内容,由于性能优势,似乎建议对单帧使用 raw。
推荐阅读
- python - 如何加入 Pandas Dataframes 并多次保留左列?
- dart - 如何将 photo_reference 值存储为字符串?
- android - Drawable array from xml into int for recycler adapter
- ruby-on-rails - Create data from another model
- node.js - Analog `fs.readdirSync` node.js without recursive
- sql - 如果在 Laravel 5.4 中每个用户一次有超过 1 个会话,则自动注销
- javascript - 将 D3 圆形包装图从 V3 升级到 V4
- php - 从 php 中的 json 数据中检索 longurl
- python - Tensorflow Eager 和 Tensorboard 图?
- r - 如何在R中用一个因子操作两个变量