2013-02-11 32 views
5

Tôi đã ở đây để hỏi, làm thế nào tôi có thể chuyển đổi một AVFrame thành một kết cấu opengl. Trên thực tế, tôi đã tạo trình kết xuất kết quả đầu ra cho tôi âm thanh (Âm thanh đang hoạt động) và video, nhưng video không xuất ra. Đây là mã của tôi:FFMPEG to OpenGL Texture

tạo Texture:

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

Mã Thông tin: _texture biến là một GLuint mà giữ kết cấu ID

Chức năng này sẽ nhận được AVFrame và chuyển nó sang 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; 
} 

Thông tin mã: Có hàng đợi nơi một luồng lưu trữ các hình ảnh AVFrames, chức năng này thường được gọi để nhận được các hình ảnh AVFrames, cho đến khi nó nhận được một NULL nó dừng lại để được gọi.

Điều đó thực sự không hoạt động. (Tôi đã cố gắng xem xét một số câu hỏi trong ngăn xếp tràn, nó vẫn không hoạt động) Bất kỳ ví dụ nào, hoặc ai đó giúp tôi sửa bất kỳ lỗi nào ở đó?

dữ liệu bổ sung: tôi đã cố gắng để thay đổi GL_RGB để GL_RGBA và bắt đầu chơi với các định dạng, dù sao nó bị treo khi tôi cố gắng GL_RGBA (Bởi vì chiều rộng và chiều cao là rất lớn, dù sao tôi đã cố gắng để thay đổi kích cỡ chúng). Tôi đã cố gắng thay đổi kích cỡ thành Power Of 2, ảnh tĩnh không hoạt động.

1 Chỉnh sửa:

Chủ đề chức năng: chức năng tạo

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

Ðề tài:

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

đâu này đề cập đến các lớp có chứa các NextVideoFrame, và các thành viên _texture.

quyết:

Tôi đi theo một số lời khuyên datenwolf, và bây giờ video được hiển thị chính xác với audio/video:

Screenshot took

+0

Có phải 'NextVideoFrame()' đang chạy trên chuỗi phụ mà bạn đã đề cập hoặc trên chuỗi chính không? – genpfault

+0

Tôi sẽ đăng chủ đề CreateThread và chủ đề, Tốt hơn là bạn không nên xem nó ở mã – Spamdark

+0

Chủ đề thứ cấp chỉ lưu AVFrame vào hàng đợi, NextVideoFrame được gọi ở một vị trí khác, một hàm cập nhật kết cấu với NextVideoFrame và sau đó vẽ nó lên màn hình (opengl) – Spamdark

Trả lời

5

OpenGL với đa luồng là một chút khéo léo. Chỉ có một hoặc không có ngữ cảnh OpenGL hoạt động cho mỗi chủ đề ngữ cảnh OpenGL đã cho có thể hoạt động chỉ trong một chuỗi tại một thời điểm. Di chuyển một bối cảnh giữa các chủ đề là có thể, nhưng bạn không nên chơi OpenGL-context-potato nóng giữa các luồng.

Có hai cách có thể:

  • Sử dụng bộ nhớ ánh xạ Pixel Buffer Objects (bản đồ trong một thread, cập nhật trong khác)

  • Sử dụng một bối cảnh OpenGL thứ, chia sẻ kết cấu của nó với khác. Sau đó, liên kết một ngữ cảnh với mỗi chuỗi (bạn có thể sử dụng cùng một đối tượng drawable, nghĩa là HDC trên Windows). Sau đó, bạn có thể cập nhật các kết cấu trong một chủ đề trong khi khác rút ra nó.Bản cập nhật kết cấu giới thiệu các điểm đồng bộ giữa các chuỗi, vì vậy bạn không thể vô tình ghi vào một kết cấu trong khi nó đang được truy cập để vẽ.

+0

Ý tưởng tuyệt vời! Gần đây tôi đã xem xét một trong các câu trả lời của bạn về một câu hỏi [stackoverflow] (http://stackoverflow.com/questions/6495523/ffmpeg-video-to-opengl-texture) và nó đã giúp tôi rất nhiều. Đây là một ảnh chụp màn hình! Nó hoạt động tốt ngay bây giờ! [Screenshot] (http://oi45.tinypic.com/71ldh3.jpg) – Spamdark

+0

Tâm trí chia sẻ mã của bạn với chúng tôi bây giờ bạn đã sửa nó? –

+0

@MikeVersteeg: Điều đó có hướng vào tôi hoặc Spamdark không? Nếu sau này bạn phải thêm '@' trước tên người dùng để thông báo cho họ. – datenwolf