Пиксельные форматы, CVPixelBufferRefs и glReadPixels - PullRequest
6 голосов
/ 26 октября 2011

Я использую glReadPixels для чтения данных в CVPixelBufferRef. Я использую CVPixelBufferRef в качестве ввода в AVAssetWriter. К сожалению, форматы пикселей, похоже, не соответствуют друг другу.

Я думаю, glReadPixels возвращает данные пикселей в формате RGBA , а AVAssetWriter хочет данные пикселей в формате ARGB . Какой лучший способ конвертировать RGBA в ARGB ?

Вот что я пробовал до сих пор:

  • манипулирование битами по типу argb = (rgba >> 8) | (rgba << 24) </li>
  • с использованием CGImageRef в качестве промежуточного шага

Битовая манипуляция не сработала, потому что CVPixelBufferRef, похоже, не поддерживает подписки. Промежуточный шаг CGImageRef работает ... но я бы предпочел не иметь 50 дополнительных строк кода, которые потенциально могли бы повлиять на производительность.

Ответы [ 5 ]

6 голосов
/ 26 октября 2011

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

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);
6 голосов
/ 26 октября 2011

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

И лучший лучший способ - полностью удалить этап копирования с помощью iOS5 CoreVideo CVOpenGLESTextureCache, который позволяет выполнять рендеринг прямо в CVPixelBufferRef, исключая вызов glReadPixels.

ps Япочти уверен, что AVAssetWriter хочет данные в формате BGRA (на самом деле он, вероятно, хочет это в yuv, но это другая история).

ОБНОВЛЕНИЕ: что касается ссылок, документ, похоже, все еще находится под NDA, но есть два свободно доступных примера кода:

GLCameraRipple и RosyWriter

Сами заголовочные файлы содержат хорошую документацию, и эквивалент Mac очень похож (CVOpenGLTextureCache), поэтому у вас должно быть достаточно для начала работы.

2 голосов
/ 26 октября 2011

Это своего рода выстрел в темноте, но вы пробовали GL_BGRA для glReadPixels с kCVPixelFormatType_32BGRA для CVPixelBufferCreate?

Я предлагаю это, потому что Технические вопросы и ответы QA1501 не отображает какой-либо формат RGBA как поддерживаемый.

1 голос
/ 22 декабря 2012
    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);
1 голос
/ 12 ноября 2011

glReadPixels (0, 0, ш * с, ч * с, GL_BGRA, GL_UNSIGNED_BYTE, буфер);

Используйте GL_BGRA в glReadPixels. Работает, просто попробовал сам.

...