CaptureOutput: didOutputSampleBuffer: fromConnection Performance Issues

72
9

Я использую AVCaptureSessionPhoto, чтобы позволить пользователю делать фотографии с высоким разрешением. При съемке я использую метод captureOutput:didOutputSampleBuffer:fromConnection: для получения миниатюры во время захвата. Однако, хотя я пытаюсь выполнить минимальную работу в методе делегата, приложение становится вроде laggy (я говорю, потому что он по-прежнему доступен). Кроме того, iPhone имеет тенденцию работать горячим.


Есть ли способ уменьшить объем работы iPhone?


Я установил AVCaptureVideoDataOutput, выполнив следующие действия:


self.videoDataOutput = [[AVCaptureVideoDataOutput alloc] init]; 
self.videoDataOutput.alwaysDiscardsLateVideoFrames = YES;

// Specify the pixel format
dispatch_queue_t queue = dispatch_queue_create("com.myapp.videoDataOutput", NULL);
[self.videoDataOutput setSampleBufferDelegate:self queue:queue];
dispatch_release(queue);
self.videoDataOutput.videoSettings = [NSDictionary dictionaryWithObject: [NSNumber numberWithInt:kCVPixelFormatType_32BGRA]
forKey:(id)kCVPixelBufferPixelFormatTypeKey];


Здесь мой captureOutput:didOutputSampleBuffer:fromConnection (и вспомогательный метод imageRefFromSampleBuffer):


- (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer 
fromConnection:(AVCaptureConnection *)connection {

NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
if (videoDataOutputConnection == nil) {
videoDataOutputConnection = connection;
}
if (getThumbnail > 0) {
getThumbnail--;
CGImageRef tempThumbnail = [self imageRefFromSampleBuffer:sampleBuffer];
UIImage *image;
if (self.prevLayer.mirrored) {
image = [[UIImage alloc] initWithCGImage:tempThumbnail scale:1.0 orientation:UIImageOrientationLeftMirrored];
}
else {
image = [[UIImage alloc] initWithCGImage:tempThumbnail scale:1.0 orientation:UIImageOrientationRight];
}
[self.cameraThumbnailArray insertObject:image atIndex:0];
dispatch_async(dispatch_get_main_queue(), ^{
self.freezeCameraView.image = image;
});
CFRelease(tempThumbnail);
}
sampleBuffer = nil;
[pool release];

}

-(CGImageRef)imageRefFromSampleBuffer:(CMSampleBufferRef)sampleBuffer {

CVImageBufferRef imageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer);
CVPixelBufferLockBaseAddress(imageBuffer,0);
uint8_t *baseAddress = (uint8_t *)CVPixelBufferGetBaseAddress(imageBuffer);
size_t bytesPerRow = CVPixelBufferGetBytesPerRow(imageBuffer);
size_t width = CVPixelBufferGetWidth(imageBuffer);
size_t height = CVPixelBufferGetHeight(imageBuffer);

CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
CGContextRef context = CGBitmapContextCreate(baseAddress, width, height, 8, bytesPerRow, colorSpace, kCGBitmapByteOrder32Little | kCGImageAlphaPremultipliedFirst);
CGImageRef newImage = CGBitmapContextCreateImage(context);
CVPixelBufferUnlockBaseAddress(imageBuffer,0);
CGContextRelease(context);
CGColorSpaceRelease(colorSpace);
return newImage;

}

спросил(а) 2011-05-08T04:17:00+04:00 9 лет, 5 месяцев назад
1
Решение
58

minFrameDuration устарел, это может сработать:

AVCaptureConnection *stillImageConnection = [stillImageOutput connectionWithMediaType:AVMediaTypeVideo];
stillImageConnection.videoMinFrameDuration = CMTimeMake(1, 10);

ответил(а) 2013-05-30T19:06:00+04:00 7 лет, 5 месяцев назад
41

Чтобы улучшить, мы должны настроить наш AVCaptureVideoDataOutput на:


output.minFrameDuration = CMTimeMake(1, 10);

Мы указываем минимальную продолжительность для каждого кадра (играйте с этими настройками, чтобы избежать слишком большого количества кадров, ожидающих в очереди, поскольку это может вызвать проблемы с памятью). Он похож на инверсию максимальной частоты кадров. В этом примере мы устанавливаем длительность минимального кадра 1/10 секунд, поэтому максимальная частота кадров составляет 10 кадров в секунду. Мы говорим, что мы не можем обрабатывать более 10 кадров в секунду.


Надеюсь, что поможет!

ответил(а) 2012-11-27T05:37:00+04:00 7 лет, 11 месяцев назад
Ваш ответ
Введите минимум 50 символов
Чтобы , пожалуйста,
Выберите тему жалобы:

Другая проблема