Захват буфера камеры в Mac / Какао - PullRequest
1 голос
/ 06 декабря 2011

В моем приложении мне нужно захватить буфер изображения с камеры и передать его другому концу по сети,

Я использовал следующий код,

-(void)startVideoSessionInSubThread{
    // Create the capture session

    pPool = [[NSAutoreleasePool alloc]init];

    mCaptureSession = [[QTCaptureSession alloc] init] ;

    // Connect inputs and outputs to the session    
    BOOL success = NO;
    NSError *error;

    // Find a video device  

    QTCaptureDevice *videoDevice = [QTCaptureDevice defaultInputDeviceWithMediaType:QTMediaTypeVideo];
    success = [videoDevice open:&error];


    // If a video input device can't be found or opened, try to find and open a muxed input device

    if (!success) {
        videoDevice = [QTCaptureDevice defaultInputDeviceWithMediaType:QTMediaTypeMuxed];
        success = [videoDevice open:&error];

    }

    if (!success) {
        videoDevice = nil;
        // Handle error


    }

    if (videoDevice) {
        //Add the video device to the session as a device input

        mCaptureVideoDeviceInput = [[QTCaptureDeviceInput alloc] initWithDevice:videoDevice];
        success = [mCaptureSession addInput:mCaptureVideoDeviceInput error:&error];
        if (!success) {
            // Handle error
        }


        mCaptureDecompressedVideoOutput = [[QTCaptureDecompressedVideoOutput alloc] init];

        [mCaptureDecompressedVideoOutput setPixelBufferAttributes:[NSDictionary dictionaryWithObjectsAndKeys:
                                                                   [NSNumber numberWithDouble:320.0], (id)kCVPixelBufferWidthKey,
                                                                   [NSNumber numberWithDouble:240.0], (id)kCVPixelBufferHeightKey,
                                                                   [NSNumber numberWithUnsignedInt:kCVPixelFormatType_32BGRA], (id)kCVPixelBufferPixelFormatTypeKey,
                                                                   //   kCVPixelFormatType_32BGRA , (id)kCVPixelBufferPixelFormatTypeKey,      
                                                                   nil]];

        [mCaptureDecompressedVideoOutput setDelegate:self];

        [mCaptureDecompressedVideoOutput setMinimumVideoFrameInterval:0.0333333333333]; // to have video effect, 33 fps 

        success = [mCaptureSession addOutput:mCaptureDecompressedVideoOutput error:&error];

        if (!success) {
            [[NSAlert alertWithError:error] runModal];
            return;
        }

        [mCaptureView setCaptureSession:mCaptureSession];
        bVideoStart = NO;
        [mCaptureSession startRunning];
        bVideoStart = NO;

    }

}
-(void)startVideoSession{
    // start video from different session 
    [NSThread detachNewThreadSelector:@selector(startVideoSessionInSubThread) toTarget:self withObject:nil];
}

в функции обратного вызова

// Do something with the buffer 
- (void)captureOutput:(QTCaptureOutput *)captureOutput didOutputVideoFrame:(CVImageBufferRef)videoFrame 
     withSampleBuffer:(QTSampleBuffer *)sampleBuffer 
       fromConnection:(QTCaptureConnection *)connection


    [self processImageBufferNew:videoFrame];

    return;
}

В функции processImageBufferNew я добавляю изображение в очередь, ее очередь синхронизации, Теперь есть отдельный поток для чтения очереди и обработки буфера

Что происходит, если я вижу журнал, элемент управления очень часто поступает при обратном вызове Capture, поэтому отправка кадра становится очень медленной, а размер очереди очень быстро увеличивается

Есть предложения по дизайну?

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

Есть ли какая-либо другая логика, которую я должен использовать для захвата кадра камеры?

1 Ответ

1 голос
/ 09 декабря 2011

Если вы не можете отправлять кадры по сети так же быстро, как они поступают с помощью метода делегата QTCaptureDecompressedVideoOutput captureOutput: didOutputVideoFrame: withSampleBuffer: fromConnection:], вам придется начинать отбрасывать кадры в определенный момент (когда у вас заканчивается память,когда вам не хватает места на массиве фиксированных узлов для отправки кадров и т. д.).

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

...