Операция ON CPU. И glTexImage2D - дорогостоящая операция. Оба они являются узкими местами, причем генерация пирамиды изображений является большей (на несколько порядков величины); С glTexImage2D нельзя пренебрегать.

аюсь визуализировать кадры, захваченные и конвертированные из видео с помощью ffmpeg, в текстуру OpenGL для размещения на четырехугольнике. Я в значительной степени исчерпал Google и не нашел ответа, ну, я нашел ответы, но ни один из них, кажется, не работал.

В основном я используюavcodec_decode_video2() декодировать кадр, а затемsws_scale() преобразовать кадр в RGB, а затемglTexSubImage2D() создать из нее текстуру openGL, но, похоже, ничего не получится.

Я убедился, что AVFrame «назначения» имеет мощность 2-х измерений в настройке SWS Context. Вот мой код:

SwsContext *img_convert_ctx = sws_getContext(pCodecCtx->width,
                pCodecCtx->height, pCodecCtx->pix_fmt, 512,
                256, PIX_FMT_RGB24, SWS_BICUBIC, NULL,
                NULL, NULL);

//While still frames to read
while(av_read_frame(pFormatCtx, &packet)>=0) {
    glClear(GL_COLOR_BUFFER_BIT);

    //If the packet is from the video stream
    if(packet.stream_index == videoStream) {
        //Decode the video
        avcodec_decode_video2(pCodecCtx, pFrame, &frameFinished, &packet);

        //If we got a frame then convert it and put it into RGB buffer
        if(frameFinished) {
            printf("frame finished: %i\n", number);
            sws_scale(img_convert_ctx, pFrame->data, pFrame->linesize, 0, pCodecCtx->height, pFrameRGB->data, pFrameRGB->linesize);

            glBindTexture(GL_TEXTURE_2D, texture);
            //gluBuild2DMipmaps(GL_TEXTURE_2D, 3, pCodecCtx->width, pCodecCtx->height, GL_RGB, GL_UNSIGNED_INT, pFrameRGB->data);
            glTexSubImage2D(GL_TEXTURE_2D, 0, 0,0, 512, 256, GL_RGB, GL_UNSIGNED_BYTE, pFrameRGB->data[0]);
            SaveFrame(pFrameRGB, pCodecCtx->width, pCodecCtx->height, number);
            number++;
        }
    }

    glColor3f(1,1,1);
    glBindTexture(GL_TEXTURE_2D, texture);
    glBegin(GL_QUADS);
        glTexCoord2f(0,1);
        glVertex3f(0,0,0);

        glTexCoord2f(1,1);
        glVertex3f(pCodecCtx->width,0,0);

        glTexCoord2f(1,0);
        glVertex3f(pCodecCtx->width, pCodecCtx->height,0);

        glTexCoord2f(0,0);
        glVertex3f(0,pCodecCtx->height,0);

    glEnd();

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

Используемый файл - .wmv в 854x480, это могло быть проблемой? То, что я просто говорю, чтобы это было 512x256?

Постскриптум Я смотрел на этоВопрос переполнения стека но это не помогло

Также у меня естьglEnable(GL_TEXTURE_2D) а также и проверил это, просто загрузив в нормальном BMP.

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

Сейчас я получаю изображение на экране, но это искаженный беспорядок, я предполагаю, что что-то делать с изменением в степени 2 (в декодировании,swscontext а такжеgluBuild2DMipmaps как показано в моем коде). Я обычно почти такой же код, как показано выше, только я изменилglTexSubImage2D вgluBuild2DMipmaps и изменил типы наGL_RGBA.

Вот как выглядит рамка:

ИЗМЕНИТЬ СНОВА

Просто понял, что я не показал код для настройки pFrameRGB:

//Allocate video frame for 24bit RGB that we convert to.
AVFrame *pFrameRGB;
pFrameRGB = avcodec_alloc_frame();

if(pFrameRGB == NULL) {
    return -1;
}

//Allocate memory for the raw data we get when converting.
uint8_t *buffer;
int numBytes;
numBytes = avpicture_get_size(PIX_FMT_RGB24, pCodecCtx->width, pCodecCtx->height);
buffer = (uint8_t *) av_malloc(numBytes*sizeof(uint8_t));

//Associate frame with our buffer
avpicture_fill((AVPicture *) pFrameRGB, buffer, PIX_FMT_RGB24,
    pCodecCtx->width, pCodecCtx->height);

Теперь, когда я изменилPixelFormat вavgpicture_get_size вPIX_FMT_RGB24Я сделал это вSwsContext так же и поменялGluBuild2DMipmaps вGL_RGB и я получаю немного лучшее изображение, но похоже, что мне все еще не хватает линий, и оно все еще немного растянуто:

Другое Править

После следования совету Макке и передачи фактического разрешения в OpenGL я получаю кадры почти правильными, но все же немного искаженными и черно-белыми, а теперь он получает только 6 кадров в секунду вместо 110 кадров в секунду:

Постскриптум

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

ПОСЛЕДНИЕ РЕДАКТИРОВАТЬ

Работает! Хорошо, у меня это работает сейчас, в основном я не разлагаю текстуру до степени 2, а просто использую разрешение видео.

Я получил правильное отображение текстуры с удачным предположением в правильном glPixelStorei ()

glPixelStorei(GL_UNPACK_ALIGNMENT, 2);

Кроме того, если у кого-то естьsubimage() показывая пустую проблему, как я, вы должны заполнить текстуру хотя бы один разglTexImage2D() и поэтому я использую его один раз в цикле, а затем использоватьglTexSubImage2D() после того.

Спасибо Маке и datenwolf за вашу помощь.

Ответы на вопрос(0)

Ваш ответ на вопрос