Можете ли вы предоставить источник / цитату?

окус не работает на первом AVCaptureSession, когда я создаю второй AVCaptureSession. Второй сеанс, который должен быть создан, - это тот, в котором работает автофокус, а первый созданный не имеет автофокусировки.

Я ожидаю, что один из сеансов сможет автоматически фокусироваться при запуске после того, как другой будет остановлен таким же образом, как автоматический баланс белого и автоэкспозиция работают для обоих сеансов. Если вы наблюдаете окно журнала с примером кода ниже, вы можете видеть поступающие сообщения наблюдения значения ключа; но никогда не изменяющееся сообщение фокуса, когда запущен верхний сеанс.

Sidenote: К сожалению, у меня есть ошибка в сторонней библиотеке, которую я использую, которая не позволяет мне просто воссоздавать сеансы полностью, когда я переключаюсь между ними (из-за утечки AVCaptureSessions, которая в конечном итоге приводит к уничтожению приложения). Вся история в том, что эта библиотека создает один из сеансов захвата для меня, у нее есть открытый API для запуска и остановки сеанса, и я хочу создать другой сеанс. Приведенный ниже код демонстрирует проблему, хотя и без использования сторонней библиотеки.

Я создал тестовое приложение с кодом, перечисленным ниже, и файлом XIB, который имеет два представления, одно над другим, и кнопку, подключенную к методу switchSessions, который демонстрирует проблему.

Это может быть связано с проблемой, описанной здесь,Фокус (автофокус) не работает в камере (AVFoundation AVCaptureSession)хотя не упоминается о двух сессиях захвата.

Заголовочный файл:

#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

Ответы на вопрос(1)

Ваш ответ на вопрос