2011-03-25 4 views
5

두 번째 AVCaptureSession을 만들 때 자동 초점이 첫 번째 AVCaptureSession에서 작동하지 않습니다. 생성 된 두 번째 세션은 자동 초점이 작동하고 처음 생성 된 세션은 자동 초점을 수행하지 않는 세션입니다.세션을 재생성하지 않고 두 번째 AVCaptureSession에서 오토 포커스가 작동하도록하려면 어떻게해야합니까?

두 세션 모두 자동 화이트 밸런스 및 자동 노출이 작동하는 것과 같은 방식으로 다른 세션이 중지 된 후에 세션이 자동 포커스 될 수 있다고 기대합니다. 아래 샘플 코드로 로그 창을 보면 키 - 값 관측 메시지를 볼 수 있습니다. 하지만 최상위 세션이 실행 중일 때 포커스 메시지가 바뀌지는 않습니다.

사이드 노트 : 안타깝게도 제 3 자 라이브러리에 버그가 있습니다. 제 3 자 라이브러리에있는 버그로 인해 세션을 완전히 다시 만들지 못하게됩니다. 결국 AVCaptureSessions가 누출되어 결국 앱이 종료됩니다. 전체 이야기는이 라이브러리가 나를위한 캡쳐 세션 중 하나를 만들고 있으며 세션을 시작하고 중지 할 수있는 공개 API가 있으며 다른 세션을 만들고 싶습니다. 아래 코드는 타사 라이브러리를 사용하지 않고도 문제를 보여줍니다.

아래에 나열된 코드와 문제를 나타내는 switchSessions 메서드에 연결된 단추와 두 개의보기가있는 XIB 파일을 사용하여 테스트 응용 프로그램을 만들었습니다.

Focus (Autofocus) not working in camera (AVFoundation AVCaptureSession) 여기에 설명 된 문제와 관련이있을 수 있지만 2 회의 캡처 세션은 언급되지 않았습니다.

헤더 파일 :

#import <UIKit/UIKit.h> 

@class AVCaptureSession; 
@class AVCaptureStillImageOutput; 
@class AVCaptureVideoPreviewLayer; 
@class AVCaptureDevice; 
@class AVCaptureDeviceInput; 

@interface AVCaptureSessionFocusBugViewController : UIViewController { 

    IBOutlet UIView *_topView; 
    IBOutlet UIView *_bottomView; 

    AVCaptureDevice *_device; 

    AVCaptureSession *_topSession; 

    AVCaptureStillImageOutput *_outputTopSession; 
    AVCaptureVideoPreviewLayer *_previewLayerTopSession; 
    AVCaptureDeviceInput *_inputTopSession; 

    AVCaptureSession *_bottomSession; 

    AVCaptureStillImageOutput *_outputBottomSession; 
    AVCaptureVideoPreviewLayer *_previewLayerBottomSession; 
    AVCaptureDeviceInput *_inputBottomSession; 
} 

- (IBAction)switchSessions:(id)sender; 

@end 

실행 파일 :

#import "AVCaptureSessionFocusBugViewController.h" 
#import <AVFoundation/AVFoundation.h> 

@interface AVCaptureSessionFocusBugViewController() 

- (void)setupCaptureSession:(AVCaptureSession **)session 
        output:(AVCaptureStillImageOutput **)output 
       previewLayer:(AVCaptureVideoPreviewLayer **)previewLayer 
         input:(AVCaptureDeviceInput **)input 
         view:(UIView *)view; 

- (void)tearDownSession:(AVCaptureSession **)session 
       output:(AVCaptureStillImageOutput **)output 
      previewLayer:(AVCaptureVideoPreviewLayer **)previewLayer 
        input:(AVCaptureDeviceInput **)input 
        view:(UIView *)view; 

@end 

@implementation AVCaptureSessionFocusBugViewController 

- (IBAction)switchSessions:(id)sender 
{ 
    if ([_topSession isRunning]) { 
     [_topSession stopRunning]; 
     [_bottomSession startRunning]; 
     NSLog(@"Bottom session now running."); 
    } 
    else { 
     [_bottomSession stopRunning]; 
     [_topSession startRunning]; 
     NSLog(@"Top session now running."); 
    } 
} 

- (void)observeValueForKeyPath:(NSString *)keyPath 
         ofObject:(id)object 
         change:(NSDictionary *)change 
         context:(void *)context 
{ 
    NSLog(@"Observed value for key at key path %@.", keyPath); 
    // Enable to confirm that the focusMode is set correctly. 
    //NSLog(@"Autofocus for the device is set to %d.", [_device focusMode]); 
} 

- (void)viewDidLoad { 
    [super viewDidLoad]; 

    _device = [[AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo] retain]; 

    [self setupCaptureSession:&_topSession 
         output:&_outputTopSession 
       previewLayer:&_previewLayerTopSession 
         input:&_inputTopSession 
         view:_topView]; 

    [self setupCaptureSession:&_bottomSession 
         output:&_outputBottomSession 
       previewLayer:&_previewLayerBottomSession 
         input:&_inputBottomSession 
         view:_bottomView]; 

    // NB: We only need to observe one device, since the top and bottom sessions use the same device. 
    [_device addObserver:self forKeyPath:@"adjustingFocus" options:NSKeyValueObservingOptionNew context:nil]; 
    [_device addObserver:self forKeyPath:@"adjustingExposure" options:NSKeyValueObservingOptionNew context:nil]; 
    [_device addObserver:self forKeyPath:@"adjustingWhiteBalance" options:NSKeyValueObservingOptionNew context:nil]; 

    [_topSession startRunning]; 
    NSLog(@"Starting top session."); 
} 


- (void)setupCaptureSession:(AVCaptureSession **)session 
        output:(AVCaptureStillImageOutput **)output 
       previewLayer:(AVCaptureVideoPreviewLayer **)previewLayer 
         input:(AVCaptureDeviceInput **)input 
         view:(UIView *)view 
{  
    *session = [[AVCaptureSession alloc] init]; 

    // Create the preview layer. 
    *previewLayer = [[AVCaptureVideoPreviewLayer layerWithSession:*session] retain]; 

    [*previewLayer setVideoGravity:AVLayerVideoGravityResizeAspectFill]; 

    [*previewLayer setFrame:[view bounds]]; 

    [[view layer] addSublayer:*previewLayer]; 

    // Configure the inputs and outputs. 
    [*session setSessionPreset:AVCaptureSessionPresetMedium]; 

    NSError *error = nil; 

    *input = [[AVCaptureDeviceInput deviceInputWithDevice:_device error:&error] retain]; 

    if (!*input) { 
     NSLog(@"Error creating input device:%@", [error localizedDescription]); 
     return; 
    } 

    [*session addInput:*input]; 

    *output = [[AVCaptureStillImageOutput alloc] init]; 

    [*session addOutput:*output]; 

    NSDictionary *outputSettings = [[NSDictionary alloc] initWithObjectsAndKeys:AVVideoCodecJPEG, AVVideoCodecKey, nil]; 

    [*output setOutputSettings:outputSettings]; 

    [outputSettings release]; 
} 

- (void)viewDidUnload { 
    [_topView release]; 
    _topView = nil; 

    [_bottomView release]; 
    _bottomView = nil; 

    [_device release]; 
    _device = nil; 

    [self tearDownSession:&_topSession 
        output:&_outputTopSession 
      previewLayer:&_previewLayerTopSession 
        input:&_inputTopSession 
        view:_topView]; 

    [self tearDownSession:&_bottomSession 
         output:&_outputBottomSession 
       previewLayer:&_previewLayerBottomSession 
         input:&_inputBottomSession 
         view:_bottomView]; 
} 

- (void)tearDownSession:(AVCaptureSession **)session 
       output:(AVCaptureStillImageOutput **)output 
      previewLayer:(AVCaptureVideoPreviewLayer **)previewLayer 
        input:(AVCaptureDeviceInput **)input 
        view:(UIView *)view 
{ 
    if ([*session isRunning]) { 
     [*session stopRunning]; 
    } 

    [*session removeOutput:*output]; 

    [*output release]; 
    *output = nil; 

    [*session removeInput:*input]; 

    [*input release]; 
    *input = nil; 

    [*previewLayer removeFromSuperlayer]; 

    [*previewLayer release]; 
    *previewLayer = nil; 

    [*session release]; 
    *session = nil; 
} 

@end 

답변

8

애플 기술 지원이 개 동시 캡처 세션을 생성이 지원되지 않는다는 것을 확인했다. 하나를 분해 한 다음 다른 하나를 만들어야합니다.

+1

출처/견적을 제공 할 수 있습니까? –

관련 문제