2013-02-11 16 views
5

Byłem tutaj, aby zapytać, w jaki sposób mogę przekonwertować AVFrame na tekst OpenGL. Właściwie stworzyłem renderer, który daje mi audio (Audio działa) i wideo, ale wideo nie jest wyprowadzane. Tu jest mój kodu:FFMPEG do OpenGL Texture

tworzenie Tekstura:

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); 

Kod Info: zmienna _texture jest GLuint że utrzymuje Numer ID tekstury

funkcję, która pobiera AVFrame i przekształcić ją w OpenGL tekstury :

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; 
} 

Informacje o kodzie: Jest kolejka gdzie wątek przechowuje ramki AVFrame, funkcja ta jest często wywoływana w celu uzyskania ramek AVFrame, dopóki nie uzyska NULL, która przestaje być wywoływana.

To w rzeczywistości nie działa. (Próbowałem spojrzeć na kilka pytań w przepełnieniu stosu, wciąż nie działa). Każdy przykład, czy ktoś, kto pomaga mi poprawić błąd?

Dodatkowe dane: Próbowałem zmienić GL_RGB do GL_RGBA i zaczął grać z formatów, w każdym razie to zawiesza się przy próbie GL_RGBA (Ponieważ szerokość i wysokość są bardzo duże, w każdym razie próbowałem ich rozmiaru). Próbowałem zmienić rozmiary na Power Of 2, cisza nie działa.

1 Edycja:

funkcja Temat: tworzenie funkcji

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; 
} 

Temat:

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

Gdzie ten odnosi się do klasy, która zawiera NextVideoFrame, a członkowie _texture.

rozwiązany:

Śledziłem niektóre porady datenwolf, a teraz film jest wyświetlany poprawnie z audio/wideo:

Screenshot took

+0

Czy "NextVideoFrame()" działa w wątku dodatkowym, o którym wspomniałeś, lub w głównym wątku? – genpfault

+0

Opublikuję CreateThread i wątek, Lepiej go rozwiąż, patrząc na kod – Spamdark

+0

Drugi wątek przechowuje tylko AVFrame do kolejki, NextVideoFrame jest wywoływana w innym miejscu, funkcja aktualizująca teksturę za pomocą NextVideoFrame, a następnie rysuje go na ekranie (opengl) – Spamdark

Odpowiedz

5

OpenGL z wielowątkowości jest nieco kłopotliwe. Jest tylko jeden lub żaden aktywny kontekst OpenGL dla jednego wątku, a dany kontekst OpenGL może być aktywny tylko w jednym wątku naraz. Migracja kontekstu między wątkami jest możliwa, ale nie powinieneś rozgrywać gorącego kontekstowego ziemniaka OpenGL między wątkami.

Istnieją dwa możliwe sposoby:

  • Wykorzystanie pamięci mapowane Pixel Buffer Objects (mapa w jednym wątku, aktualizacja w drugiej)

  • Użyj wtórny kontekst OpenGL, dzieląc swoje tekstury z inny. Następnie połącz jeden kontekst z każdym wątkiem (możesz użyć tego samego losowania, np. HDC w systemie Windows). Następnie możesz zaktualizować teksturę w jednym wątku, podczas gdy druga ją narysuje.Aktualizacje tekstury wprowadzają punkty synchronizacji między wątkami, więc nie można przypadkowo zapisać tekstury podczas jej uzyskiwania podczas rysowania.

+0

Świetny pomysł! Niedawno zaglądałem do jednej z twoich odpowiedzi na pytanie [stackoverflow] (http://stackoverflow.com/questions/6495523/ffmpeg-video-to-opengl-texture) i bardzo mi to pomogło. Oto zrzut ekranu! Teraz działa dobrze! [Zrzut ekranu] (http://oi45.tinypic.com/71ldh3.jpg) – Spamdark

+0

Umysł, który dzieli się z nami swoim kodem, teraz go naprawiłeś? –

+0

@MikeVersteeg: Czy to było skierowane na mnie, czy na Spamdark? Jeśli później musisz dodać znak "@" przed nazwą użytkownika, aby go zauważyć. – datenwolf