J'essaye de faire un peu de traitement d'image sur iPhone. J'utilise http://developer.apple.com/library/ios/#qa/qa2010/qa1702.html pour capturer les cadres de la caméra. Mon problème est que lorsque j'essaie d'accéder au tampon capturé, le FPS de la caméra tombe de 30 à environ 20. Est-ce que quelqu'un sait comment je peux le réparer?Faible FPS lors de l'accès au tampon d'image de sortie vidéo de l'iPhone
J'utilise la qualité de capture la plus faible que j'ai pu trouver (AVCaptureSessionPresetLow = 192x144) au format kCVPixelFormatType_32BGRA. Si quelqu'un connaît une qualité inférieure que je pourrais utiliser, je suis prêt à l'essayer.
Lorsque je fais le même accès à l'image sur d'autres plateformes, comme Symbian, cela fonctionne correctement.
Voici mon code:
#pragma mark -
#pragma mark AVCaptureSession delegate
- (void)captureOutput:(AVCaptureOutput *)captureOutput
didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer
fromConnection:(AVCaptureConnection *)connection
{
/*We create an autorelease pool because as we are not in the main_queue our code is
not executed in the main thread. So we have to create an autorelease pool for the thread we are in*/
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
CVImageBufferRef imageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer);
//Lock the image buffer
if (CVPixelBufferLockBaseAddress(imageBuffer, 0) == kCVReturnSuccess)
{
// calculate FPS and display it using main thread
[self performSelectorOnMainThread:@selector(updateFps:) withObject: (id) nil waitUntilDone:NO];
UInt8 *base = (UInt8 *)CVPixelBufferGetBaseAddress(imageBuffer); //image buffer start address
size_t width = CVPixelBufferGetWidth(imageBuffer);
size_t height = CVPixelBufferGetHeight(imageBuffer);
int size = (height*width);
UInt8* pRGBtmp = m_pRGBimage;
/*
Here is the problem; m_pRGBimage is RGB image I want to process.
In the 'for' loop I convert the image from BGRA to RGB. As a resault, the FPS drops to 20.
*/
for (int i=0;i<size;i++)
{
pRGBtmp[0] = base[2];
pRGBtmp[1] = base[1];
pRGBtmp[2] = base[0];
base = base+4;
pRGBtmp = pRGBtmp+3;
}
// Display received action
[self performSelectorOnMainThread:@selector(displayAction:) withObject: (id) nil waitUntilDone:NO];
//[self displayAction:&eyePlayOutput];
//saveFrame(imageBuffer);
//unlock the image buffer
CVPixelBufferUnlockBaseAddress(imageBuffer,0);
}
[pool drain];
}
Comme suite à la réponse, je dois traiter l'image en temps réel, il est affiché.
je remarquai que lorsque j'utilise AVCaptureSessionPresetHigh, la chose la plus simple que je fais, comme:
for (int i=0;i<size;i++)
x = base[0];
provoque le framerate tomber à 4-5 FPS. Je suppose que c'est parce qu'une image de cette taille n'est pas mise en cache.
Fondamentalement, j'ai besoin d'image 96x48. Y at-il un moyen simple de réduire l'image de sortie de la caméra, un moyen qui utilise l'accélération matérielle, afin que je puisse travailler avec le petit?
Je suis d'accord qu'il est très probable que le ralentissement du traitement entraîne le ralentissement de l'ensemble de la capture, mais je ne suis pas sûr que le simple fait de lâcher le verrou tôt fera beaucoup pour aider. Pour traiter les trames à 30 FPS, le rappel pour chaque trame devra se terminer en moins de 1/30ème de seconde. Si ce n'est pas le cas, les opérations de traitement vont simplement bloquer le fil sur lequel ils tournent. –
Pas si cela fonctionnait en tant que producteur -> modèle de consommateur - les rappels seraient juste mis en file d'attente - tout dépend de ce qu'il fait avec l'image modifiée. Si c'est juste en train de le sauvegarder alors bon, laissez-le sauvegarder dans un tampon quelque part. Si c'est affiché alors il a un problème :) – deanWombourne
J'ai essayé le memcpy sur un tampon dédié, mais cela n'a pas aidé du tout, en fait c'était plus lent :( – akaru