Ich render die Vorschau von der Handy-Kamera in Android GLSurfaceView
und möchte Frames speichern, sobald sie verfügbar sind. Da das Speichern der Frames auf der SD-Karte viel mehr Zeit in Anspruch nimmt als die Zeit zwischen zwei onFrameAvailable
Calls, mache ich es in einem anderen Thread, nachdem ich die Pixel vom Bildschirm gelesen habe.Java synchronisieren Thread mit Puffer lesen
public void onDrawFrame(GL10 gl) {
//Process the frame, display it on the screen and other stuff
//Read pixels from the screen into my buffer
glReadPixels(0, 0, offscreenSize_.x, offscreenSize_.y, GL_RGBA, GL_UNSIGNED_BYTE,
intBuffer.clear());
// At the moment this has a counter and happens every 150ms
if(saveImage)
{
Thread thread = new Thread() {
@Override
public void run() {
// Convert to an array for Bitmap.createBitmap().
final int[] pixels = new int[intBuffer.capacity()];
intBuffer.rewind();
intBuffer.get(pixels);
try {
// Create/access a pictures subdirectory.
File directory = new File(
Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES),
"TangoFrames");
if (!directory.mkdirs() && !directory.isDirectory()) {
Log.d("WRITE ERR", "Couldn't create directory");
return;
}
// Get the current capture index to construct a unique filename.
SharedPreferences prefs = activity_.getPreferences(Context.MODE_PRIVATE);
int index = prefs.getInt("index", 0);
SharedPreferences.Editor prefsEditor = prefs.edit();
prefsEditor.putInt("index", index + 1);
prefsEditor.apply();
// Create the capture file.
File file = new File(directory, String.format("tango%05d.png", index));
FileOutputStream fileOutputStream = new FileOutputStream(file);
// Bitmap conveniently provides file output.
Bitmap bitmap = Bitmap.createBitmap(pixels, offscreenSize_.x, offscreenSize_.y, Bitmap.Config.ARGB_8888);
bitmap.compress(Bitmap.CompressFormat.PNG, 90, fileOutputStream);
fileOutputStream.close();
numberOfFrames++;
}
catch (Exception e) {
e.printStackTrace();
}
}
};
thread.start();
}
}
Mein Problem ist, dass, wenn der Faden hinter fallen beginnt, kommt es vor, dass für die für einen Rahmen der Lesung beginnt:
final int[] pixels = new int[intBuffer.capacity()];
intBuffer.rewind();
intBuffer.get(pixels);
Der nächste Rückruf ausgelöst wird und intBuffer.clear()
ausgeführt wird, so dass die Der Rest wird beschädigt. Wie kann ich den Thread so synchronisieren, dass er nur ausgeführt wird, wenn der Puffer voll ist, und darauf achten, dass der Puffer nicht gelöscht wird, während der Thread läuft?