Предварительный просмотр изображения очень медленный на Nexus4
Мне нужно увеличить частоту кадров в моем приложении. Теперь у меня от 6 до 10 кадров в секунду, что очень мало, потому что у меня Nexus4. Поэтому я решил переключиться с setPreviewCallback на setPreviewCallbackWithBuffer, но я не вижу НИКАКОЙ разницы в частоте кадров. В журнале видно, что адреса буферов меняются по кругу, но все равно у меня всего 6 - 10 кадров в секунду (иногда 12, но редко)... Не могли бы вы дать мне несколько советов? КСТАТИ. У меня есть Android 4.4, и я попробовал OpenCV, но результат почти тот же... Мой код:
public class XPreview extends SurfaceView implements SurfaceHolder.Callback, Camera.PreviewCallback {
private SurfaceHolder mHolder;
private Camera mCamera;
long mTimer = 0;
public XPreview(Context context, Camera camera) {
super(context);
mCamera = camera;
mHolder = getHolder();
mHolder.addCallback(this);
}
public void surfaceCreated(SurfaceHolder holder) {
}
public void surfaceDestroyed(SurfaceHolder holder) {
}
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
if (mHolder.getSurface() == null){
// preview surface does not exist
return;
}
// stop preview before making changes
try {
mCamera.stopPreview();
} catch (Exception e){
// ignore: tried to stop a non-existent preview
}
try {
int formatt = mCamera.getParameters().getPreviewFormat();
int bytesPerPx = ImageFormat.getBitsPerPixel( formatt );
int width = mCamera.getParameters().getPreviewSize().width;
int height = mCamera.getParameters().getPreviewSize().height;
int size = (int)( ( width * height * bytesPerPx ) / 8.0);
Parameters params = mCamera.getParameters();
mCamera.setParameters(params);
Log.d(TAG, "Data: " + formatt + " " + bytesPerPx + " " + width + "x" + height + " " + size );
mCamera.setPreviewDisplay(mHolder);
mCamera.setPreviewCallbackWithBuffer(this);
mCamera.addCallbackBuffer( new byte[size] );
mCamera.addCallbackBuffer( new byte[size] );
mCamera.addCallbackBuffer( new byte[size] );
mCamera.addCallbackBuffer( new byte[size] );
mCamera.addCallbackBuffer( new byte[size] );
mCamera.startPreview();
} catch (Exception e){
Log.d(TAG, "Error starting camera preview: " + e.getMessage());
}
}
@Override
public void onPreviewFrame(byte[] data, Camera camera) {
long time = System.currentTimeMillis();
Log.d( TAG, "Time between frames: " + ( time - mTimer ) + "ms, FPS: " + ( 1000.0 / (time - mTimer )) + ", data " + data );
mTimer = time;
camera.addCallbackBuffer(data);
}
}
Деятельность:
public class RTP extends Activity {
private Camera mCamera;
private XPreview mPreview;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mCamera = Camera.open();
mPreview = new XPreview(this, mCamera);
FrameLayout preview = (FrameLayout) findViewById( R.id.frameLayout1 );
preview.addView(mPreview);
}
@Override
public void onPause(){
super.onPause();
if( mCamera != null ){
mCamera.stopPreview();
mCamera.release();
mCamera = null;
}
}
}
Редактировать:
Parameters params = mCamera.getParameters();
params.setRecordingHint(true);
mCamera.setParameters(params);
Это уменьшило задержку между кадрами до ~30 мс с версией с буферами и уменьшило задержку до приблизительно 60 с версией без буфера. В любом случае, я был бы рад, если бы кто-нибудь дал мне еще несколько советов.
Несколько более глубокие тесты показывают, что теперь у меня есть от 24 до 31 кадра в секунду, используя версию с буферизацией и два буфера, и между 15 и 22, используя версию по умолчанию.