FFMPEG для OpenGL текстуры

Я был здесь, чтобы спросить, как я могу преобразовать AVFrame в текстуру OpenGL. На самом деле, я создал рендерер, который выводит мне аудио (звук работает) и видео, но видео не выводится. Вот мой код:

Создание текстуры:

glGenTextures(1,&_texture);
glBindTexture(GL_TEXTURE_2D,_texture);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);

glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );

Информация о коде: переменная _texture — это GLuint, который хранит идентификатор текстуры

Функция, которая получает AVFrame и конвертирует его в OpenGL Texture:

int VideoGL::NextVideoFrame(){
// Get a packet from the queue
AVPacket *videopacket = this->DEQUEUE(VIDEO);
int frameFinished;
if(videopacket!=0){
avcodec_decode_video2(_codec_context_video, _std_frame,&frameFinished,videopacket);

if(frameFinished){

sws_scale(sws_ctx, _std_frame->data, _std_frame->linesize, 0, _codec_context_video->height, _rgb_frame->data, _rgb_frame->linesize);

if(_firstrendering){
glBindTexture(GL_TEXTURE_2D,_texture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, _codec_context_video->width,_codec_context_video->height,0,GL_RGB,GL_UNSIGNED_BYTE,_rgb_frame->data[0]);

_firstrendering = false;

}else{

glActiveTexture(_texture);
glBindTexture(GL_TEXTURE_2D,_texture);
glTexSubImage2D(GL_TEXTURE_2D,0,0,0,_codec_context_video->width,_codec_context_video->height,GL_RGB,GL_UNSIGNED_BYTE,_rgb_frame->data[0]);

}
av_free_packet(videopacket);
return 0;
}else{

av_free_packet(videopacket);
return -1;
}

}else{
return -1;
}
return 0;
}

Информация о коде: существует очередь, в которой поток хранит AVFrames, эта функция часто вызывается для получения AVFrames, пока он не получит значение NULL, которое перестает вызываться.

Это на самом деле не работает. (Я попытался посмотреть на некоторые вопросы переполнения стека, он все еще не работает)
Любой пример, или кто-то, кто помогает мне исправить любую ошибку там?

Дополнительная информация: Я попытался изменить GL_RGB на GL_RGBA и начал играть с форматами, во всяком случае, он падает, когда я пытаюсь GL_RGBA (поскольку ширина и высота очень большие, в любом случае я пытался изменить их размер). Я попытался изменить размеры на Power Of 2, все еще не работает.

1 Изменить:

Функция резьбы:

DWORD WINAPI VideoGL::VidThread(LPVOID myparam){

VideoGL * instance = (VideoGL*) myparam;
instance->wave_audio->Start();

int quantity=0;

AVPacket packet;
while(av_read_frame(instance->_format_context,&packet) >= 0){
if(packet.stream_index==instance->videoStream){
instance->ENQUEUE(VIDEO,&packet);
}
if(packet.stream_index==instance->audioStream){
instance->ENQUEUE(AUDIO,&packet);
}
}

instance->ENQUEUE(AUDIO,NULL);
instance->ENQUEUE(VIDEO,NULL);

return 0;
}

Функция создания потока:

CreateThread(NULL, 0, VidThread, this, NULL, NULL);

Где это относится к классу, который содержит NextVideoFrame и члены _texture.

Решено:

Я следовал некоторым советам datenwolf, и теперь видео отображается правильно с аудио / видео:

Снял скриншот

5

Решение

OpenGL с многопоточностью немного сложнее. В каждом потоке только один активный контекст OpenGL или его нет а также данный контекст OpenGL может быть активным только в одном потоке за раз. Миграция контекста между потоками возможна, но вы не должны играть в горячий OpenGL-context-potato между потоками.

Есть два возможных пути:

  • Используйте объекты Pixel Buffer, отображенные в памяти (карта в одном потоке, обновление в другом)

  • Используйте вторичный контекст OpenGL, разделяя его текстуры с другим. Затем привяжите один контекст к каждому потоку (вы можете использовать один и тот же объект рисования, т.е. HDC в Windows). Затем вы можете обновить текстуру в одном потоке, в то время как другой рисует его. Обновления текстуры вводят точки синхронизации между потоками, поэтому вы не можете случайно записать текстуру, когда она доступна для рисования.

5

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]