Рендеринг CVPixelBuffer в NSView (macOS)

У меня есть CVPixelBuffer, который я пытаюсь эффективно нарисовать на экране.

Неэффективный способ превращения в NSImage работает, но очень медленно, пропуская около 40% моих кадров.

Поэтому я попытался отобразить его на экране с помощью CIContext drawImage:inRect:fromRect. CIContext был инициализирован с помощью NSOpenGLContext, представление которого было настроено на представление моего VC. Когда у меня есть новое изображение, я вызываю метод drawImage, который не выдает никаких ошибок... но и ничего не отображает на экране (он регистрировал ошибки, когда мои контексты были настроены неправильно).

Я пытался найти пример того, как это делается в MacOS, но в настоящее время все кажется для iOS.

РЕДАКТИРОВАТЬ:

Вот часть кода, который я использую. Я пропустил ненужные разделы

viewDidLoad я запускаю контексты GL и CI

NSOpenGLPixelFormatAttribute pixelFormatAttr[] = {
  kCGLPFAAllRenderers, 0
};
NSOpenGLPixelFormat *glPixelFormat = [[NSOpenGLPixelFormat alloc] initWithAttributes: pixelFormatAttr];
NSOpenGLContext *glContext = [[NSOpenGLContext alloc] initWithFormat:glPixelFormat shareContext:nil];
glContext.view = self.view;

self.ciContext = [CIContext contextWithCGLContext:glContext.CGLContextObj pixelFormat:glPixelFormat.CGLPixelFormatObj colorSpace:nil options:nil];

Затем, когда новый кадр готов, я делаю:

dispatch_async(dispatch_get_main_queue(), ^{
       [vc.ciContext drawImage:ciImage inRect:vc.view.bounds fromRect:ciImage.extent];
        vc.isRendering = NO;
});

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


person CatalinM    schedule 19.09.2017    source источник
comment
Привет и добро пожаловать в ТАК. Прежде чем ваш вопрос будет помечен как закрытый, я предлагаю вам переписать его, потому что в его текущем состоянии он не вписывается в формат SO Q&A. Пожалуйста, добавьте свой реальный код, изображающий конкретную проблему.   -  person Michael IV    schedule 19.09.2017
comment
Я добавил используемый код... но его немного.   -  person CatalinM    schedule 20.09.2017
comment
Я не очень хорошо разбираюсь в OSX, но я думаю, что вы должны установить gl-контекст как текущий (используйте [glContext makeCurrentContext];. И не забудьте поменять местами буферы ( [glContext flushBuffer];) после рендеринга.   -  person Ripi2    schedule 20.09.2017
comment
В этом есть логика, но она не работает (уже пробовал). Я сделал небольшой прорыв, переместив весь этот код внутрь NSOpenGLView и вызвав метод drawImage: в его методе drawRect:... и вызвав glFlush() в конце. Однако изображение отображалось в правом верхнем углу экрана и было очень размытым. Позиционирование напоминает мне о том, как работает рендерер GL на iOS... так что у меня есть идея, как это исправить.   -  person CatalinM    schedule 20.09.2017
comment
Мне кажется, вы смешиваете OpenGL и OpenGL-ES (этот контекст CI). Много информации можно найти на странице Сайт разработчиков Apple   -  person Ripi2    schedule 20.09.2017
comment
Я получил информацию из документации Apple. Суть в том, что drawImage: CIContext работает только с контекстами, созданными из CGLContext или CGContext. glFlush() — это стандартный вызов OpenGL, которому, по общему признанию, не было места в моей настройке как таковому... в любом случае, если мне не удастся найти простой способ рендеринга этого через CIContext, я сделаю чистая реализация OpenGL и покончим с этим.   -  person CatalinM    schedule 20.09.2017
comment
CGLContext является какао. AGLContext — это углерод   -  person CatalinM    schedule 20.09.2017


Ответы (1)


Если CVPixelBuffer имеет атрибут kCVPixelBufferIOSurfaceCoreAnimationCompatibilityKey, поддержка IOSurface (полученная через CVPixelBufferGetIOSurface) может быть передана непосредственно в свойство contents CALayer.

Это, вероятно, самый эффективный способ отображения CVPixelBuffer.

person fumoboy007    schedule 22.01.2019
comment
Это интересно, я посмотрю как можно скорее, чтобы проверить, работает это или нет. Это довольно старое решение, но я помню, что нашел решение, полностью перейдя на OpenGL (написание рендерера с собственным шейдером и все такое) — работало безупречно и очень быстро, но для этого было много кода. - person CatalinM; 22.01.2019