Telefondaki kameradan ön izlemeyi bir GLSurfaceView
numaralı telefondan gerçekleştiriyorum ve mümkün olan en kısa sürede kareleri kaydetmek istiyorum. Çerçeveleri sd kartına kaydettiğinizde, iki onFrameAvailable
çağrı arasındaki süreden çok daha fazla zaman geçtiğinden, ekrandan pikselleri okuduktan sonra bunu başka bir iş parçacığında yapıyorum.Java, arabelleği okuma arabelleği ile senkronize etme
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();
}
}
Benim sorunum iplik gerisinde başladığında, bazen bir çerçeve için hangi okuma başlar olur ki:
final int[] pixels = new int[intBuffer.capacity()];
intBuffer.rewind();
intBuffer.get(pixels);
sonraki geri arama ateşlenir
ve intBuffer.clear()
çalıştırılır, böylece dinlenme bozuldu. İş parçacığı, arabellek dolduğunda çalışacak ve iş parçacığı çalışırken arabelleğin temizlenmemesine neden olacak şekilde nasıl eşitlenir?