Как отобразить видеокадр RGB24 с помощью opengl

Моя задача - отрендерить набор из 50 кадров RGB с использованием библиотеки openGL's glut.

Я пробовал: при вращении трехмерного куба у меня есть набор вершин, с помощью которых я визуализирую его в окне. Но что делать в случае рендеринга RGB-кадров? Ниже приведен код, с помощью которого я визуализирую свой 3D-куб:

#include <glut.h>

GLfloat vertices[24]={-1.0,-1.0,-1.0,1.0,-1.0,-1.0,1.0,1.0,-1.0,-1.0,1.0,-1.0,-1.0,-1.0,1.0,1.0,-1.0,1.0,1.0,1.0,1.0,-1.0,1.0,1.0};
GLfloat colors[24]={-1.0,-1.0,-1.0,1.0,-1.0,-1.0,1.0,1.0,-1.0,-1.0,1.0,-1.0,-1.0,-1.0,1.0,1.0,-1.0,1.0,1.0,1.0,1.0,-1.0,1.0,1.0};
GLubyte cubeIndices[24]={0,3,2,1,2,3,7,6,0,4,7,3,1,2,6,5,4,5,6,7,0,1,5,4};
static GLfloat theta[3]={0,0,0};
static GLint axis=2;

void display()
{
    glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);

    glLoadIdentity();
    glRotatef(theta[0],1.0,0.0,0.0);
    glRotatef(theta[1],0.0,1.0,0.0);
    glRotatef(theta[2],0.0,0.0,1.0);

    glDrawElements(GL_QUADS,24,GL_UNSIGNED_BYTE,cubeIndices);

    glutSwapBuffers();
    glFlush();
}

void spinCude()
{
    theta[axis]+=2.0;
    if(theta[axis]>360.0)
        theta[axis]-=360.0;
    display();
}
void init()
{
    glMatrixMode(GL_PROJECTION);
    glOrtho(-2.0,2.0,-2.0,2.0,-10.0,10.0);
    glMatrixMode(GL_MODELVIEW);
}

void mouse(int btn,int state, int x,int y)
{
    if(btn==GLUT_LEFT_BUTTON&& state==GLUT_DOWN) axis=0;
    if(btn==GLUT_MIDDLE_BUTTON&& state==GLUT_DOWN) axis=1;
    if(btn==GLUT_RIGHT_BUTTON&& state==GLUT_DOWN) axis=2;
}

void main(int argc, char **argv)
{
    glutInit(&argc,argv);
    glutInitDisplayMode(GLUT_DOUBLE|GLUT_RGB|GLUT_DEPTH);

    glutInitWindowSize(500,500);
    glutCreateWindow("Simple YUV Player");
    init();
    glutDisplayFunc(display);

    glutIdleFunc(spinCude);
    glutMouseFunc(mouse);
    glEnable(GL_DEPTH_TEST);

    glEnableClientState(GL_VERTEX_ARRAY);
    glVertexPointer(3,GL_FLOAT,0,vertices);

    //glEnableClientState(GL_COLOR_ARRAY);
    glVertexPointer(3,GL_FLOAT,0,colors);

    glutMainLoop();

}

Может ли кто-нибудь предложить мне какой-нибудь пример или учебник, чтобы я мог изменить приведенный выше код для отображения кадров RGB.


person sam    schedule 14.10.2013    source источник


Ответы (2)


Когда у вас есть RGB-кадр в виде необработанных данных в памяти, все становится довольно просто. Создайте текстуру с помощью glGenTextures, свяжите ее с помощью glBindTexture и загрузите данные с помощью glTexImage2D или glTexSubImage2D. Затем визуализируйте полноэкранный четырехугольник или что угодно с этой текстурой. Преимущество этого состоит в том, что вы можете визуализировать несколько «виртуальных» телевизоров в своей сцене, просто визуализируя несколько квадратов с одной и той же текстурой, представьте себе TV-Store, где одно и то же видео воспроизводится на дюжине телевизоров. glDrawPixels тоже может работать, но он гораздо менее универсален.

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

person Marius    schedule 14.10.2013
comment
Спасибо за ваш ответ. Это действительно хорошая информация. Но мне нужен простой пример или фрагмент кода, включающий приведенные выше инструкции. Пожалуйста, предложите ссылку или код, и я приму ваш ответ. Пожалуйста помоги. - person sam; 14.10.2013
comment
Подойдет любой базовый учебник по текстурированию. Их множество в сети, например nehe.gamedev.net/tutorial/texture_mapping/ 12038 - person Marius; 14.10.2013

Как уже предложил Мариус, сначала реализуйте наложение текстуры. Совершенно очевидно, что любой учебник по наложению текстуры подойдет.

Рендеринг кадров с OpenGL не самый лучший, вы должны стараться избегать их, насколько это возможно, поскольку это может включать в себя копию клиент -> память хоста, что действительно дорого (занимает слишком много времени) или просто занимает слишком много памяти. В любом случае, если вам действительно нужно это сделать, просто сгенерируйте столько текстур, сколько вам нужно, с помощью glGenTextures, загрузите их с текстурами с помощью glTexImage2D, а затем переверните кадры с помощью простого цикла в каждом кадре.

P.S. Судя по названию вашего приложения «YUV Player», вам также может потребоваться преобразовать входные данные, поскольку OpenGL в основном использует RGB, а не YUV.

person DrakkLord    schedule 14.10.2013
comment
Клиент - ›передача памяти хоста не обязательно слишком затратна. PCIe является стандартом уже много лет, и вы можете легко передавать несколько десятков мегапикселей на кадр, при этом сохраняя скорость 60 кадров в секунду. Обратите внимание, что если входные данные находятся в формате YUV с субдискретизацией цветности (что вполне вероятно для цифрового видео), полосу пропускания можно уменьшить еще больше, используя данные YUV и выполняя преобразование в RGB на графическом процессоре. Создание 50 текстур заранее, как вы предлагаете (или использование трехмерной текстуры или массива текстур), может потребовать много памяти (в зависимости от разрешения изображения). - person derhass; 14.10.2013
comment
Принимая во внимание, что это приложение, вероятно, является тестовым приложением, вы правы, хотя, если это должно быть живое приложение, вы можете избежать передачи кадров в реальном времени, даже если PCIe быстрый, у него также есть ограничения. И да 3D текстуры я про них забыл! - person DrakkLord; 14.10.2013
comment
@derhass, какое решение быстрее? Допустим, я декодировал поток h264 с использованием аппаратного api декодирования - у меня есть вектор uint_8 - что мне делать дальше, чтобы отобразить кадр, не копируя его в память хоста? Я новичок в этой теме. Спасибо! - person Oleksandr Papchenko; 21.08.2018
comment
@OleksandrPapchenko Я не знаю, почему вы спрашиваете об этом в каком-то комментарии, адресованном мне. Даже если он был опубликован как реальный вопрос, я бы проголосовал за него как за слишком широкий (по крайней мере, на неспецифическом уровне, который был задан). Если вы хотите использовать GL для отображения видео, вам сначала нужно изучить GL, а статья о stackoverflow не может этому научить, да и не предназначена для этого. - person derhass; 21.08.2018