iphoneобработка кадров, записываемых камерой - PullRequest
2 голосов
/ 17 декабря 2010

У меня есть это приложение записи видео, и мне нужно запускать метод каждый раз, когда захватывается кадр.После того, как я ударился головой о стену, я решил попробовать следующее: создать очередь отправки, как если бы я брал видео с выхода, просто чтобы вызвать метод, когда камера записывает кадр.

Я пытаюсь понять раздел кода, созданного Apple для записи видео, чтобы понять, как мне добавить очередь отправки.Это код яблока, а раздел, отмеченный звездочками, - это то, что я добавил, чтобы создать очередь.Он компилируется без ошибок, но captureOutput: didOutputSampleBuffer: fromConnection: никогда не вызывается.

- (BOOL) setupSessionWithPreset:(NSString *)sessionPreset error:(NSError **)error
{
    BOOL success = NO;

    // Init the device inputs
    AVCaptureDeviceInput *videoInput = [[[AVCaptureDeviceInput alloc] initWithDevice:[self backFacingCamera] error:error] autorelease];
    [self setVideoInput:videoInput]; // stash this for later use if we need to switch cameras

    AVCaptureDeviceInput *audioInput = [[[AVCaptureDeviceInput alloc] initWithDevice:[self audioDevice] error:error] autorelease];
    [self setAudioInput:audioInput];

    AVCaptureMovieFileOutput *movieFileOutput = [[AVCaptureMovieFileOutput alloc] init];
    [self setMovieFileOutput:movieFileOutput];
    [movieFileOutput release];


    // Setup and start the capture session
    AVCaptureSession *session = [[AVCaptureSession alloc] init];

    if ([session canAddInput:videoInput]) {
        [session addInput:videoInput];
    }
    if ([session canAddInput:audioInput]) {
        [session addInput:audioInput];
    }
    if ([session canAddOutput:movieFileOutput]) {
        [session addOutput:movieFileOutput];
    }

    [session setSessionPreset:sessionPreset];


    //  I added this *****************
    dispatch_queue_t queue = dispatch_queue_create("myqueue", NULL);
    [[self videoDataOutput] setSampleBufferDelegate:self queue:queue];
    dispatch_release(queue);
    // ******************** end of my code      

    [session startRunning];
    [self setSession:session];
    [session release];
    success = YES;
    return success;
}

Мне нужен только метод, в котором я могу обрабатывать каждый записываемый кадр.

спасибо

Ответы [ 2 ]

2 голосов
/ 17 декабря 2010

Установив себя в качестве делегата, вы получите вызов:

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

Каждый раз, когда захватывается новый кадр. Вы можете поместить туда любой код, который хотите - просто будьте осторожны, потому что вас не будет в главном потоке. Вероятно, безопаснее всего сделать быстрый [target performSelectorOnMainThread:@selector(methodYouActuallyWant)] в -captureOutput:didOutputSampleBuffer:fromConnection:.

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

- (id)initWithSessionPreset:(NSString *)sessionPreset delegate:(id <AAVideoSourceDelegate>)aDelegate
{

#ifndef TARGET_OS_EMBEDDED
    return nil;
#else

    if(self = [super init])
    {
        delegate = aDelegate;

        NSError *error = nil;

        // create a low-quality capture session
        session = [[AVCaptureSession alloc] init];
        session.sessionPreset = sessionPreset;

        // grab a suitable device...
        device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];

        // ...and a device input
        AVCaptureDeviceInput *input = [AVCaptureDeviceInput deviceInputWithDevice:device error:&error];

        if(!input || error)
        {
            [self release];
            return nil;
        }
        [session addInput:input];

        // create a VideDataOutput to route output to us
        AVCaptureVideoDataOutput *output = [[AVCaptureVideoDataOutput alloc] init];
        [session addOutput:[output autorelease]];

        // create a suitable dispatch queue, GCD style, and hook self up as the delegate
        dispatch_queue_t queue = dispatch_queue_create("aQueue", NULL);
        [output setSampleBufferDelegate:self queue:queue];
        dispatch_release(queue);

        // set 32bpp BGRA pixel format, since I'll want to make sense of the frame
        output.videoSettings =
            [NSDictionary 
                dictionaryWithObject:[NSNumber numberWithInt:kCVPixelFormatType_32BGRA]
                forKey:(id)kCVPixelBufferPixelFormatTypeKey];

    }

    return self;
#endif
}

- (void)start
{
    [session startRunning];
}

- (void)stop
{
    [session stopRunning];
}
0 голосов
/ 03 октября 2013
// create a suitable dispatch queue, GCD style, and hook self up as the delegate
        dispatch_queue_t queue = dispatch_queue_create("aQueue", NULL);
        [output setSampleBufferDelegate:self queue:queue];
        dispatch_release(queue);

Также очень важно в

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

обязательно поместить

NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];в начале и [утечка пула] в конце, иначе произойдет сбой после слишком большого числа процессов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...