2

AVCaptureSessionPhotoユーザーが高解像度の写真を撮れるようにするために使用します。写真を撮ると、captureOutput:didOutputSampleBuffer:fromConnection:メソッドを使用して、キャプチャ時にサムネイルを取得します。ただし、delegate メソッドで最小限の作業を実行しようとしていますが、アプリは一種の遅延になります (まだ使用できるため、一種と言います)。また、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;

}
4

2 に答える 2

1

minFrameDuration は非推奨です。これでうまくいくかもしれません:

AVCaptureConnection *stillImageConnection = [stillImageOutput connectionWithMediaType:AVMediaTypeVideo];
stillImageConnection.videoMinFrameDuration = CMTimeMake(1, 10);
于 2013-05-30T16:06:49.547 に答える
0

改善するには、次の方法でセットアップする必要がありますAVCaptureVideoDataOutput

output.minFrameDuration = CMTimeMake(1, 10);

各フレームの最小期間を指定します (メモリの問題が発生する可能性があるため、キューで待機するフレームが多すぎるのを避けるために、この設定で遊んでください)。これは、最大フレームレートの逆数に似ています。この例では、最小フレーム期間を 1/10 秒に設定しているため、最大フレームレートは 10fps です。毎秒 10 フレームを超える処理はできないと言われています。

その助けを願っています!

于 2012-11-27T02:37:26.507 に答える