J'utilise Camera 2 API pour enregistrer des images JPEG sur disque. J'ai actuellement 3-4 fps sur mon Nexus 5X, je voudrais l'améliorer à 20-30. C'est possible?Appareil photo 2, augmentation FPS
Changement du format de l'image en YUV Je parviens à générer 30 fps. Est-il possible de les enregistrer à cette fréquence, ou devrais-je abandonner et vivre avec mes 3-4 fps?
De toute évidence, je peux partager du code si nécessaire, mais si tout le monde est d'accord que ce n'est pas possible, je vais abandonner. Utiliser le NDK (avec libjpeg par exemple) est une option (mais évidemment je préférerais l'éviter ...).
Merci
EDIT: voici comment je convertir YUV android.media.Image à un seul octet []:
private byte[] toByteArray(Image image, File destination) {
ByteBuffer buffer0 = image.getPlanes()[0].getBuffer();
ByteBuffer buffer2 = image.getPlanes()[2].getBuffer();
int buffer0_size = buffer0.remaining();
int buffer2_size = buffer2.remaining();
byte[] bytes = new byte[buffer0_size + buffer2_size];
buffer0.get(bytes, 0, buffer0_size);
buffer2.get(bytes, buffer0_size, buffer2_size);
return bytes;
}
EDIT 2: une autre méthode que je trouve pour convertir l'image en YUV un octet []:
private byte[] toByteArray(Image image, File destination) {
Image.Plane yPlane = image.getPlanes()[0];
Image.Plane uPlane = image.getPlanes()[1];
Image.Plane vPlane = image.getPlanes()[2];
int ySize = yPlane.getBuffer().remaining();
// be aware that this size does not include the padding at the end, if there is any
// (e.g. if pixel stride is 2 the size is ySize/2 - 1)
int uSize = uPlane.getBuffer().remaining();
int vSize = vPlane.getBuffer().remaining();
byte[] data = new byte[ySize + (ySize/2)];
yPlane.getBuffer().get(data, 0, ySize);
ByteBuffer ub = uPlane.getBuffer();
ByteBuffer vb = vPlane.getBuffer();
int uvPixelStride = uPlane.getPixelStride(); //stride guaranteed to be the same for u and v planes
if (uvPixelStride == 1) {
uPlane.getBuffer().get(data, ySize, uSize);
vPlane.getBuffer().get(data, ySize + uSize, vSize);
}
else {
// if pixel stride is 2 there is padding between each pixel
// converting it to NV21 by filling the gaps of the v plane with the u values
vb.get(data, ySize, vSize);
for (int i = 0; i < uSize; i += 2) {
data[ySize + i + 1] = ub.get(i);
}
}
return data;
}
Avez-vous utilisé la méthode de traçage ou d'autres techniques pour déterminer avec précision où votre temps est passé? Quelle résolution utilisez-vous? Est-ce que vous faites votre disque E/S sur un thread séparé? – CommonsWare
Oui, le temps est passé dans la conversion YUV -> JPEG et dans les E/S disque. J'utilise la résolution maximale (4000 * 3000 ou plus). Et oui, les E/S disque sont enfilées. Mais si je multi-thread l'enregistrement de l'image, et si cela prend plus de temps que la création d'image, Ill probablement courir dans OOME (ou pas d'espace disque), non? –
"le temps est passé dans la conversion YUV -> JPEG" - quelle conversion YUV-> JPEG? Pourquoi Camera2 ne vous donne-t-il pas le JPEG directement, en profitant du matériel de périphérique dédié à cette conversion? – CommonsWare