Рисование YUV-кадров с помощью OpenGL на Mac - PullRequest
0 голосов
/ 18 июля 2011

Я декодирую видео с помощью библиотек ffmpeg и храню декодированные кадры в массиве. Теперь я хочу нарисовать эти кадры на экране с помощью OpenGL. Я гуглил и обнаружил, что яблоко предлагает использовать формат GL_APPLE_ycbcr_422 для эффективного рисования. Поэтому я переключил кадры декодирования в ffmpeg в формат PIX_FMT_YUYV422 (упакованный YUV 4: 2: 2, 16bpp, Y0 Cb Y1 Cr), который, кажется, эквивалентен GL_APPLE_ycbcr_422 в OpenGL. Теперь я пытаюсь нарисовать кадры на поверхности с помощью этого кода:

GLsizei width = 2, height = 2;
uint8_t data[8] = {128,200,123,10,5,13,54,180}; 
GLuint texture_name;

glEnable(GL_TEXTURE_RECTANGLE_ARB);
assert(glGetError() == GL_NO_ERROR);

glGenTextures (1,&texture_name);
assert(glGetError() == GL_NO_ERROR);

glBindTexture(GL_TEXTURE_RECTANGLE_ARB, texture_name);
assert(glGetError() == GL_NO_ERROR);    

glTextureRangeAPPLE(GL_TEXTURE_RECTANGLE_ARB, width * height * 2, (void*)data);
assert(glGetError() == GL_NO_ERROR);

glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_STORAGE_HINT_APPLE , GL_STORAGE_SHARED_APPLE);
assert(glGetError() == GL_NO_ERROR);

glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, GL_TRUE);
assert(glGetError() == GL_NO_ERROR);

// not sure about code above    

glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
assert(glGetError() == GL_NO_ERROR);

glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
assert(glGetError() == GL_NO_ERROR);

glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
assert(glGetError() == GL_NO_ERROR);

glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
assert(glGetError() == GL_NO_ERROR);

glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
assert(glGetError() == GL_NO_ERROR);    

// end

glViewport(0, 0,  width,height);
assert(glGetError() == GL_NO_ERROR);

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);                    
assert(glGetError() == GL_NO_ERROR);

glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGB, width, height, 0,
             GL_YCBCR_422_APPLE,GL_UNSIGNED_SHORT_8_8_APPLE,
             (void*)data);
assert(glGetError() == GL_NO_ERROR);

glTexSubImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0, width, height,
                GL_YCBCR_422_APPLE,GL_UNSIGNED_SHORT_8_8_APPLE,
                (void*)data);
assert(glGetError() == GL_NO_ERROR);    

glMatrixMode(GL_PROJECTION); 
glLoadIdentity();

glScalef(1.0f, -1.0f, 1.0f);
glOrtho(0, width, 0, height, -1.0, 1.0);

glMatrixMode(GL_MODELVIEW);
glLoadIdentity();

glBegin(GL_QUADS);

glVertex3f(0, 0, -1.0f);
glVertex3f(width, 0, -1.0f);
glVertex3f(width, height, -1.0f);
glVertex3f(0, height, -1.0f);

glEnd();

Но я не вижу правильных кадров. Вместо этого я вижу искаженные фотографии моего дисплея. Так что я понимаю, что мое использование OpenGL не правильно и, возможно, я не понимаю некоторые фундаментальные вещи.

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

1 Ответ

1 голос
/ 18 июля 2011

Вот что я использую в одном из своих приложений для настройки текстурной цели YUV 4: 2: 2 для загружаемых данных из кадров YUV, снятых с камеры CCD:

glActiveTexture(GL_TEXTURE0);
glEnable(GL_TEXTURE_RECTANGLE_EXT);
glGenTextures(1, &textureName); 
glBindTexture(GL_TEXTURE_RECTANGLE_EXT, textureName);
glTextureRangeAPPLE(GL_TEXTURE_RECTANGLE_EXT, videoImageSize.width * videoImageSize.height * 2, videoTexture);
glTexParameteri(GL_TEXTURE_RECTANGLE_EXT, GL_TEXTURE_STORAGE_HINT_APPLE , GL_STORAGE_SHARED_APPLE);

glTexParameteri(GL_TEXTURE_RECTANGLE_EXT, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_RECTANGLE_EXT, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_RECTANGLE_EXT, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_RECTANGLE_EXT, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);

glTexImage2D(GL_TEXTURE_RECTANGLE_EXT, 0, GL_RGBA, videoImageSize.width, videoImageSize.height, 0, GL_YCBCR_422_APPLE, GL_UNSIGNED_SHORT_8_8_REV_APPLE, videoTexture);      
glBindTexture(GL_TEXTURE_RECTANGLE_EXT, 0);

Фактическая загрузка в текстуру выполняется с использованием следующего:

glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_RECTANGLE_EXT, textureName);
glTexSubImage2D (GL_TEXTURE_RECTANGLE_EXT, 0, 0, 0, videoImageSize.width, videoImageSize.height, GL_YCBCR_422_APPLE, GL_UNSIGNED_SHORT_8_8_REV_APPLE, videoTexture);

В приведенном выше примере videoTexture - это ячейка памяти необработанных байтов из захваченного кадра YUV с камеры. Я также использую подсказки от Apple, описанные выше, чтобы ускорить загрузку, хотя мне никогда не удавалось оптимизировать GL_UNPACK_CLIENT_STORAGE_APPLE, чтобы ускорить процесс.

Это было скопировано и вставлено из рабочего приложения, и единственное реальное различие, которое я вижу, - это использование GL_RGBA вместо GL_RGB в getTexImage2D() и использование GL_UNSIGNED_SHORT_8_8_REV_APPLE вместо GL_UNSIGNED_SHORT_8_8_APPLE , Расширения прямоугольника ARB и EXT разрешают одно и то же на Mac.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...