tiankong2017 2017-04-01 06:33 采纳率: 0%
浏览 4696

安卓摄像头丢帧:onPreviewFrame()可以保证每33ms(即30fps)给出图像数据吗?

问题:
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上。

  • 写回答

1条回答 默认 最新

  • 薛定谔的DFA 2017-08-03 02:50
    关注

    我也遇到这个问题了,魅族的也会丢一帧,请问您解决了吗?

    评论

报告相同问题?

悬赏问题

  • ¥15 kafka 分区副本增加会导致消息丢失或者不可用吗?
  • ¥15 微信公众号自制会员卡没有收款渠道啊
  • ¥15 stable diffusion
  • ¥100 Jenkins自动化部署—悬赏100元
  • ¥15 关于#python#的问题:求帮写python代码
  • ¥20 MATLAB画图图形出现上下震荡的线条
  • ¥15 关于#windows#的问题:怎么用WIN 11系统的电脑 克隆WIN NT3.51-4.0系统的硬盘
  • ¥15 perl MISA分析p3_in脚本出错
  • ¥15 k8s部署jupyterlab,jupyterlab保存不了文件
  • ¥15 ubuntu虚拟机打包apk错误