Wie man raw-Daten anzeigen von Kamera-Objekt mindestens 15 frames pro Sekunde in Android?
Ich benötigen raw-Daten anzeigen von Kamera-Objekt mindestens 15 Rahmen pro Sekunde, aber ich kann nur ein Bild in 110 Millisekunden, die kann ich nur 9 Bilder pro Sekunde. Ich kurzen meinen code unten.
Camera mCamera = Camera.open();
Camera.Parameters parameters = mCamera.getParameters();
parameters.setPreviewFrameRate(30);
parameters.setPreviewFpsRange(15000,30000);
mCamera.setParameters(parameters);
mCamera.addCallbackBuffer(new byte[dataBufferSize]);
//dataBufferSize stands for the byte size for a picture frame
mCamera.addCallbackBuffer(new byte[dataBufferSize]);
mCamera.addCallbackBuffer(new byte[dataBufferSize]);
mCamera.setPreviewDisplay(videoCaptureViewHolder);
//videoCaptureViewHolder is a SurfaceHolder object
mCamera.setPreviewCallbackWithBuffer(new Camera.PreviewCallback() {
private long timestamp=0;
public synchronized void onPreviewFrame(byte[] data, Camera camera) {
Log.v("CameraTest","Time Gap = "+(System.currentTimeMillis()-timestamp));
timestamp=System.currentTimeMillis();
//do picture data process
camera.addCallbackBuffer(data);
return;
}
}
mCamera.startPreview();
In der eingewiesene code oben, dataBufferSize und videoCaptureViewHolder definiert und berechnet oder zugewiesen, in der anderen Aussagen.
Ich mein code, ich kann sehen, dass die Vorschau auf dem Bildschirm und ich bekomme den log unten:
...
V/CameraTest( 5396): Time Gap = 105
V/CameraTest( 5396): Time Gap = 112
V/CameraTest( 5396): Time Gap = 113
V/CameraTest( 5396): Time Gap = 115
V/CameraTest( 5396): Time Gap = 116
V/CameraTest( 5396): Time Gap = 113
V/CameraTest( 5396): Time Gap = 115
...
Dies bedeutet onPreviewFrame(byte[] data, Camera camera) heißt alle 110 Millisekunden, so kann ich bekommen nicht mehr als 9 Bildern pro Sekunde. Und egal, was die Vorschau-frame rate ich vom Thema setPreviewFrameRate() und was Album Vorhören Fps Bereich ich vom Thema setPreviewFpsRange(), das Protokoll ist das gleiche.
Würde jemand mir etwas Hilfe zu diesem problem? Ich brauche zu erhalten, raw-Vorschau-Daten aus Kamera-Objekt mindestens 15 frames pro Sekunde. Vielen Dank im Voraus.
Ich legte meinen ganzen code.
CameraTest.java
package test.cameratest;
import java.io.IOException;
import java.util.Iterator;
import java.util.List;
import android.app.Activity;
import android.graphics.ImageFormat;
import android.hardware.Camera;
import android.hardware.Camera.ErrorCallback;
import android.hardware.Camera.Parameters;
import android.hardware.Camera.Size;
import android.os.Bundle;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.SurfaceHolder.Callback;
public class CameraTestActivity extends Activity {
SurfaceView mVideoCaptureView;
Camera mCamera;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mVideoCaptureView = (SurfaceView) findViewById(R.id.video_capture_surface);
SurfaceHolder videoCaptureViewHolder = mVideoCaptureView.getHolder();
videoCaptureViewHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
videoCaptureViewHolder.addCallback(new Callback() {
public void surfaceDestroyed(SurfaceHolder holder) {
}
public void surfaceCreated(SurfaceHolder holder) {
startVideo();
}
public void surfaceChanged(SurfaceHolder holder, int format,
int width, int height) {
}
});
}
private void startVideo() {
SurfaceHolder videoCaptureViewHolder = null;
try {
mCamera = Camera.open();
} catch (RuntimeException e) {
Log.e("CameraTest", "Camera Open filed");
return;
}
mCamera.setErrorCallback(new ErrorCallback() {
public void onError(int error, Camera camera) {
}
});
Camera.Parameters parameters = mCamera.getParameters();
parameters.setPreviewFrameRate(30);
parameters.setPreviewFpsRange(15000,30000);
List<int[]> supportedPreviewFps=parameters.getSupportedPreviewFpsRange();
Iterator<int[]> supportedPreviewFpsIterator=supportedPreviewFps.iterator();
while(supportedPreviewFpsIterator.hasNext()){
int[] tmpRate=supportedPreviewFpsIterator.next();
StringBuffer sb=new StringBuffer();
sb.append("supportedPreviewRate: ");
for(int i=tmpRate.length,j=0;j<i;j++){
sb.append(tmpRate[j]+", ");
}
Log.v("CameraTest",sb.toString());
}
List<Size> supportedPreviewSizes=parameters.getSupportedPreviewSizes();
Iterator<Size> supportedPreviewSizesIterator=supportedPreviewSizes.iterator();
while(supportedPreviewSizesIterator.hasNext()){
Size tmpSize=supportedPreviewSizesIterator.next();
Log.v("CameraTest","supportedPreviewSize.width = "+tmpSize.width+"supportedPreviewSize.height = "+tmpSize.height);
}
mCamera.setParameters(parameters);
if (null != mVideoCaptureView)
videoCaptureViewHolder = mVideoCaptureView.getHolder();
try {
mCamera.setPreviewDisplay(videoCaptureViewHolder);
} catch (Throwable t) {
}
Log.v("CameraTest","Camera PreviewFrameRate = "+mCamera.getParameters().getPreviewFrameRate());
Size previewSize=mCamera.getParameters().getPreviewSize();
int dataBufferSize=(int)(previewSize.height*previewSize.width*
(ImageFormat.getBitsPerPixel(mCamera.getParameters().getPreviewFormat())/8.0));
mCamera.addCallbackBuffer(new byte[dataBufferSize]);
mCamera.addCallbackBuffer(new byte[dataBufferSize]);
mCamera.addCallbackBuffer(new byte[dataBufferSize]);
mCamera.setPreviewCallbackWithBuffer(new Camera.PreviewCallback() {
private long timestamp=0;
public synchronized void onPreviewFrame(byte[] data, Camera camera) {
Log.v("CameraTest","Time Gap = "+(System.currentTimeMillis()-timestamp));
timestamp=System.currentTimeMillis();
try{
camera.addCallbackBuffer(data);
}catch (Exception e) {
Log.e("CameraTest", "addCallbackBuffer error");
return;
}
return;
}
});
try {
mCamera.startPreview();
} catch (Throwable e) {
mCamera.release();
mCamera = null;
return;
}
}
private void stopVideo() {
if(null==mCamera)
return;
try {
mCamera.stopPreview();
mCamera.setPreviewDisplay(null);
mCamera.setPreviewCallbackWithBuffer(null);
mCamera.release();
} catch (IOException e) {
e.printStackTrace();
return;
}
mCamera = null;
}
public void finish(){
stopVideo();
super.finish();
};
}
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="test.cameratest"
android:versionCode="1"
android:versionName="1.0">
<uses-sdk android:minSdkVersion="9" android:targetSdkVersion="10" android:maxSdkVersion="10"/>
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>
<uses-permission android:name="android.permission.READ_CONTACTS"/>
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS"/>
<uses-permission android:name="android.permission.CALL_PHONE"/>
<uses-permission android:name="android.permission.BOOT_COMPLETED"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_SETTINGS" />
<application android:icon="@drawable/icon" android:label="@string/app_name">
<activity android:name=".CameraTestActivity"
android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
- hi, hast du eine Lösung gefunden für dieses Problem? vielen Dank
- Die Quelle oben hat ein problem: die Verwendung von nicht unterstützten Werte in
Camera.Parameters.setPreviewFrameRate()
undCamera.Parameters.setPreviewFpsRange()
ist schlimmer, als nicht den Aufruf dieser Methoden überhaupt. Also, rufen Sie zunächst die Liste der unterstützten FPS (oder Bereiche), und wählen Sie das beste, statt hardcoding 30, wie im obigen Beispiel. - eine neuere Verwandte Frage (und Antwort): stackoverflow.com/questions/23678701/.... Spoiler: verwenden Sie eine neue Event thread... Zwei und ein halbes Jahr später, die Lösung ist noch nicht gut verstanden.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Ich bin Angst, Sie können nicht. Album Vorhören framerate-Einstellung Hinweis für die Kamera appplication ( die läuft in separatem Prozess) - und es ist kostenlos zu akzeptieren oder stillschweigend ignorieren. Es ist auch nicht im Zusammenhang mit der Vorschau-frame-retrieval
Wenn Sie die Vorschau-frame, sagen Sie einfach externe Anwendung, die Sie möchten, es zu haben. Puffer für ihn reserviert ist in der Kamera-Anwendung und dann übergeben, um Ihre Aktivitäten über mmaped-memory-segment - und das kostet Zeit.
Bekommen Sie die gewünschte Leistung bei einigen Geräten, aber nicht unbedingt auf einen, spielen Sie mit.
Wenn Sie müssen den vorgegebenen frame-rate, die Sie haben, um ein video aufzunehmen und dann analysieren /Dekomprimieren resultierenden binären Datenstrom.
Mir Erfahrung mit der Kamera Sachen wurden fummelig und abhängig von der hardware. Also versuchen Sie es auf andere hardware irgendwann, wenn du kannst.
Könnte auch einen Versuch Wert, etwas mehr Kamera-Einstellungen.
setRecordingHint (boolean Hinweis).
Vielen Dank für mit einem code-Beispiel btw.
Sollte dies kein problem sein. Meine androangelo (in den Markt) app zu bekommen ist, bis zu 30 frames pro Sekunde (zumindest habe ich umgesetzt, eine Tempo-Bremse zu verlangsamen).
Überprüfen Sie bitte sorgfältig, ob Ihre log ist voll mit Müll-Sammler Aussagen. Dies ist der Fall, wenn zu wenige Puffer Hinzugefügt werden. Dieser hatte den trick für mich. Zumindest kam ich bis zu hinzufügen 20! Puffer der Kamera.
Dann wird der Verarbeitung jedes Frames stattfinden sollte in einem separaten thread. Während ein Bild in den thread für die Verarbeitung, der Rückruf sollte überspringen den aktuellen frame.
In meinem Verständnis, Android nicht zulassen, Benutzer, um einen Satz einer festen framerate, noch Garantie für den Wert der fps, die Sie angeben, wird respektiert, ist aufgrund der frame-Belichtungszeit, die von der Kamera hardware oder firmware. Die frame-rate, die Sie beobachten, kann die Funktion der Beleuchtung. Zum Beispiel eine bestimmte Telefonnummer geben Sie ein 30fps Album Vorhören rate in einem Tag leicht, aber nur 7 fps wenn Sie Dreharbeiten in einem low-light-Zustand.
Eine Sache, die scheint zu erhöhen, die Flüssigkeit der Vorschau, wenn nicht die tatsächliche FPS notwendigerweise, ist die Einstellung der previewFormat zu YV12, wenn unterstützt. Es ist weniger bytes zu kopieren, 16-byte-ausgerichtet, und möglicherweise optimiert in anderer Hinsicht:
http://developer.android.com/reference/android/graphics/ImageFormat.html#YV12 beschreibt das format. Das, plus ein paar Ersatz-Puffer gibt mir "Zeit-Lücken" von so niedrig wie 80...das ist noch nicht "gut genug", aber ... besser? (tatsächlich habe ich einen an der 69...aber wirklich, Sie sind eher rund 90 im Durchschnitt). Nicht sicher, wie viel die Protokollierung verlangsamt Dinge nach unten?
Einstellung der previewSize 320x240 (statt 1280x720) bekommt, Dinge auf die 50-70msec Bereich...also vielleicht das ist, was Sie tun müssen? Zugegeben, dass wenig Daten möglicherweise sehr viel weniger nützlich.
//alle getestet auf Nexus4
Ich in der Regel deklarieren Sie eine Globale boolean lockCameraUse. Die callback-Funktion in der Regel sieht das so aus.