Пиксельные форматы, CVPixelBufferRefs и glReadPixels
я использую glReadPixels
для чтения данных в CVPixelBufferRef
. Я использую CVPixelBufferRef
в качестве параметра AVAssetWriter
. К сожалению, форматы пикселей, похоже, не совпадают.
Я думаю glReadPixels
возвращает пиксельные данные в RGBA и пока AVAssetWriter
хочет пиксельные данные в формате ARGB. Каков наилучший способ преобразования RGBA и to формате ARGB?
вот что я пробовал до сих пор:
- немного манипуляций по линиям argb = (rgba >> 8) | (rgba
- С помощью
CGImageRef
в качестве промежуточного шага
битовая манипуляция не сработала, потому что CVPixelBufferRef, похоже, не поддерживает индексы. The CGImageRef
промежуточный шаг работает... но я бы предпочел не иметь 50 дополнительных строк кода, которые потенциально могли бы быть удар по производительности.
5 ответов
лучше, чем использовать CPU для замены компонентов, было бы написать простой шейдер фрагментов, чтобы эффективно сделать это на GPU при рендеринге изображения.
и лучший лучший способ-полностью удалить этап копирования с помощью iOS5 CoreVideo CVOpenGLESTextureCache, который позволяет визуализировать прямо в CVPixelBufferRef, устраняя вызов glReadPixels.
p.s. Я уверен, что AVAssetWriter хочет получить данные в формате BGRA (на самом деле он, вероятно, хочет это в ЮВ, но это уже другая история).
UPDATE: что касается ссылок, doco, похоже, все еще находится под NDA, но есть две части свободно загружаемого кода примера:
сами заголовочные файлы содержат хорошую документацию, а эквивалент mac очень похож (CVOpenGLTextureCache), поэтому у вас должно быть много, чтобы начать работу.
Что касается битовой манипуляции, вы можете получить указатель на необработанные данные пиксельного буфера:
CVPixelBufferLockBaseAddress(buffer, 0);
size_t stride = CVPixelBufferGetBytesPerRow(buffer);
char *data = (char *)CVPixelBufferGetBaseAddress(buffer);
for (size_t y = 0; y < CVPixelBufferGetHeight(buffer); ++y) {
uint32_t *pixels = (uint32_t *)(data + stride * y);
for (size_t x = 0; x < CVPixelBufferGetWidth(buffer); ++x)
pixels[x] = (pixels[x] >> 8) | (pixels[x] << 24);
}
CVPixelBufferUnlockBaseAddress(buffer, 0);
это своего рода выстрел в темноте, но вы не пробовали GL_BGRA
на glReadPixels
С kCVPixelFormatType_32BGRA
на CVPixelBufferCreate
?
Я предлагаю это, потому что технические вопросы QA1501 не перечисляет поддерживаемый формат RGBA.
glReadPixels (0, 0, w*s, h*s, GL_BGRA, GL_UNSIGNED_BYTE, buffer);
используйте GL_BGRA в glReadPixels. Это работает, просто попробовал сам.
glReadPixels(0, 0, width, height, GL_BGRA, GL_UNSIGNED_BYTE, _buffer);
CVPixelBufferRef buffer = NULL;
CVReturn ret = CVPixelBufferCreateWithBytes(kCFAllocatorDefault,_size.width,_size.height,kCVPixelFormatType_32BGRA,glubyte,_size.width*4,NULL,NULL,NULL,&buffer);