问题:
1)安卓摄像头丢帧:onPreviewFrame()可以保证每33ms(即30fps)给出图像数据吗?尤其是华为/荣耀的安卓手机?
2)或者,在安卓手机上还有其它什么方法保证每33ms(即30fps)获取图像数据?
3)谁有在其它品牌的手机上测试过onPreviewFrame()的性能?
我的测试方法:
1)锁定AutoExposureLock
if (parameters.isAutoWhiteBalanceLockSupported()) {
parameters.setAutoWhiteBalanceLock(true);
}
else{
Toast.makeText(mContext, "Not AutoWhiteBalanceLockSupported!", Toast.LENGTH_LONG).show();
}
if (parameters.isAutoExposureLockSupported()) {
parameters.setAutoExposureLock(true); // true:lock
}
else{
Toast.makeText(mContext, "Not AutoExposureLockSupported!", Toast.LENGTH_LONG).show();
}
2)固定30fps
if (m_strModel.contains("NEM-AL10")){ // (Honor)NEM-AL10
parameters.set("preview-frame-rate", "30");
}
else if (m_strModel.contains("H60-L01")){ // (Honor)H60-L01
parameters.set("preview-frame-rate", "30");
}
else if (m_strModel.contains("EVA-AL00")){ // (HuaWei)EVA-AL00
parameters.set("preview-frame-rate", "30");
}
else if (m_strModel.contains("Redmi Note 2")){ // (Xiaomi)Redmi Note 2
parameters.set("preview-frame-rate", "30");
}
else { // Others
parameters.setPreviewFpsRange(30000, 30000);
}
3)在onPreviewFrame()检查是否为30fps,即间隔为1/30=fps~=33ms
private Camera mCamera = null;
private long catchTimeMillis2 = System.nanoTime()/1000000L;
private long passedFramesTimeMillis = 0;
private int countAverage = 0;
private String strFrameTime2 = "";
private String strFrameTime2_average = "";
@Override
public void onPreviewFrame(final byte[] data, Camera camera) {
if (mResultHandler == null || handleThread == null || detectHandler == null) {
return;
}
if (mCamera == null){
mCamera = camera;
}
if (true) {
// 帧间间隔测试
long currentTime = System.nanoTime() / 10000;
final long passedOneFrameTimeMillis = currentTime - catchTimeMillis2;
catchTimeMillis2 = currentTime; // backup
passedFramesTimeMillis += passedOneFrameTimeMillis; // for average
strFrameTime2 = "2FI=" + passedOneFrameTimeMillis/100 + "." + passedOneFrameTimeMillis%100;
if (true){
// 平均的帧间间隔测试
countAverage++;
if (countAverage >= 16){
passedFramesTimeMillis = passedFramesTimeMillis >> 4;
strFrameTime2_average = " Ave=" + passedFramesTimeMillis/100 + "." + passedFramesTimeMillis%100;
passedFramesTimeMillis = 0;
countAverage = 0;
}
}
Log.e("TEST", strFrameTime2 + strFrameTime2_average);
}
mCameraData = data;
camera.addCallbackBuffer(des);
}
4)在onSurfaceTextureUpdated()检查是否为30fps,即间隔为1/30=fps~=33ms
@Override
public void onSurfaceTextureUpdated(SurfaceTexture surfaceTexture) {
if(mCameraWrapper == null || mSurfaceTexture == null) {
return;
}
long currentTimesStamp;
int version = android.os.Build.VERSION.SDK_INT;
currentTimesStamp = surfaceTexture.getTimestamp()/10000; // *10
long temp = currentTimesStamp - mOldTimesStamp;
Log.i("TEST", "1FI=" + temp/100 + "." + temp%100);
mOldTimesStamp = currentTimesStamp;
}
我的测试现象:
1)我测试发现,在安卓手机上(包括华为/荣耀的安卓手机),摄像头没法保证在onPreviewFrame()上稳定地每33ms给出数据,
而是有时会丢掉1帧(你会看到有的帧间隔约为66ms)甚至2帧(你会看到有的帧间隔约为100ms)。
2)但你会发现onSurfaceTextureUpdated()的打印信息非常好的保持在33ms上。