Используя пиксельные буферы

Эта статья описывает методы, которые Ваш исходный объект видеоданных должен реализовать для использования пиксельных буферов для iChat Theater. Считайте Установку Источника Видеоданных для того, как установить исходный объект видеоданных прежде, чем считать эту статью. Если Ваш источник видеоданных использует OpenGL, читайте Используя Буферы OpenGL.

Получение формата видео

Ваш исходный объект видеоданных должен реализовать getPixelBufferPixelFormat: IMVideoDataSource метод протокола для возврата формата пикселя для видеоконтента. IMAVManager возразите нуждается в этой информации, чтобы должным образом вывести на экран и передать видео. Это getPixelBufferPixelFormat: реализация возвращается kCVPixelFormatType_32ARGB формат пикселя, подходящий для Базовых Видео пиксельных буферов, из которых графические контексты получены, как показано в Рендеринге Видеокадров:

- (void)getPixelBufferPixelFormat:(OSType *)pixelFormatOut {
    *pixelFormatOut = kCVPixelFormatType_32ARGB;
}

Формат пикселя, возвращенный этим методом, является форматом CVPixelBufferRef объект, передающийся renderIntoPixelBuffer:forTime: IMVideoDataSource метод протокола.

Рендеринг видеокадров

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

Если видеокадр не изменился начиная с последнего кадра — например, в слайд-шоу тот же кадр выведен на экран в течение нескольких секунд — тогда renderIntoPixelBuffer:forTime: метод должен возвратиться NO так, чтобы передача кадров могла быть более эффективной.

Этот фрагмент кода блокирует пиксельный буфер использование CVPixelBufferLockBaseAddress функция:

// Lock the pixel buffer's base address so that we can draw into it.
if((err = CVPixelBufferLockBaseAddress(buffer, 0)) != kCVReturnSuccess) {
    // Rarely is a lock refused. Return NO if this happens.
    NSLog(@"Warning: could not lock pixel buffer base address in %s - error %ld", __func__, (long)err);
    return NO;
}

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

size_t width = CVPixelBufferGetWidth(buffer);
size_t height = CVPixelBufferGetHeight(buffer);
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
CGContextRef cgContext = CGBitmapContextCreate(CVPixelBufferGetBaseAddress(buffer),
                                               width, height,
                                               8,
                                               CVPixelBufferGetBytesPerRow(buffer),
                                               colorSpace,
                                               kCGImageAlphaPremultipliedFirst);
CGColorSpaceRelease(colorSpace);

При создании видеоконтента с помощью методов рисования Какао можно создать NSGraphicsContext, сделайте его текущим, и вызовите методы рисования — например, drawInRect:fromRect:operation:fraction: NSImage метод или drawAtPoint: NSAttributedString метод — для рендеринга следующего кадра в пикселе буферизует как показано здесь:

NSGraphicsContext *context = [NSGraphicsContext graphicsContextWithGraphicsPort:cgContext flipped:NO];
[NSGraphicsContext setCurrentContext:context];
// Insert drawing methods here
[context flushGraphics];

Наконец, необходимо выпустить все объекты и разблокировать пиксельный буфер как показано здесь:

CGContextRelease(cgContext);
CVPixelBufferUnlockBaseAddress(buffer, 0);

См. Базовое Видео Руководство по программированию для получения дополнительной информации об использовании Базового Видео.