我正在研究延迟至关重要的实时视频流应用程序。我使用的设备是搭载Android 7.1.2的相机。现在,我正在尝试从应该访问30fps的摄像机访问原始帧,因此我希望使用摄像机预览在不到50ms的时间内获取帧。问题是我得到的延迟太高(超过200毫秒)。我不确定这是否是获取原始帧的正确方法,还是有一种更有效的方法来更快地读取它们。
我正在使用的获取框架的代码如下。我正在传递一个回调缓冲区,以避免发生enter link description here中所述的GC调用,任何帮助或提示都非常受欢迎。
public void start(SurfaceTexture surfaceTexture) {
thread = new Thread() {
@Override
public void run() {
try {
startCamera(surfaceTexture);
} catch (Exception e) {
e.printStackTrace();
}
}
};
thread.start();
}
private void startCamera(SurfaceTexture surfaceTexture){
if (mCamera == null) {
int numberOfCameras = Camera.getNumberOfCameras();
for (int i = 0; i < numberOfCameras; i++) {
Camera.CameraInfo info = new Camera.CameraInfo();
Camera.getCameraInfo(i, info);
if (info.facing == Camera.CameraInfo.CAMERA_FACING_BACK) {
mCameraId = i;
}
try {
mCamera = Camera.open(mCameraId);
} catch (Exception e) {
Timber.d(e.getMessage());
}
}
mCamera.setErrorCallback(mErrorCallback);
mParameters = mCamera.getParameters();
mParameters.setPreviewSize(1920, 960);
mCamera.setParameters(mParameters);
mCamera.setDisplayOrientation(0);
try {
mCamera.setPreviewTexture(surfaceTexture);
int numBytes = 300000;
mCamera.addCallbackBuffer(new byte[numBytes]);
mCamera.setPreviewCallback(new android.hardware.Camera.PreviewCallback() {
@Override
public void onPreviewFrame(byte[] data, Camera camera) {
long ntpTimestamp = SntpClock.getInstance().getCurrentMilliseconds();
Camera.Parameters parameters = camera.getParameters();
Camera.Size size = parameters.getPreviewSize();
YuvImage image = new YuvImage(data, ImageFormat.NV21, size.width, size.height, null);
Rect rectangle = new Rect();
rectangle.bottom = size.height;
rectangle.top = 0;
rectangle.left = 0;
rectangle.right = size.width;
try{
File sdCard = Environment.getExternalStorageDirectory();
File dir = new File (sdCard.getAbsolutePath() + "/images/");
File file = new File(dir, "preview-"+ntpTimestamp+".jpg");
FileOutputStream output = new FileOutputStream(file);
image.compressToJpeg(rectangle, 100, output);
output.flush();
output.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
});
} catch (IOException e) {
Timber.d(e.getMessage());
}
mCamera.startPreview();
}
}