2013-02-11 12 views
5

मैं यहां पूछने के लिए था, मैं एक एवीफ़्रेम को ओपनग्ल बनावट में कैसे परिवर्तित कर सकता हूं। असल में, मैंने एक रेंडरर बनाया जो मुझे ऑडियो (ऑडियो काम कर रहा है) और वीडियो आउटपुट करता है, लेकिन वीडियो आउटपुट नहीं कर रहा है। यहाँ मेरी कोड है:ओपनजीएल बनावट के लिए एफएफएमपीईजी

बनावट सृजन:

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 हो जाता है और यह ओपन बनावट में बदलने का रहता है :

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 प्राप्त करने के लिए बुलाया जाता है, जब तक कि यह न्यूल हो जाता है, इसे कॉल करने के लिए रोक दिया जाता है।

यह वास्तव में काम नहीं कर रहा है। (मैंने स्टैक ओवरफ़्लो में कुछ प्रश्नों को देखने का प्रयास किया, यह अभी भी काम नहीं कर रहा है) कोई उदाहरण, या कोई ऐसा जो मुझे किसी भी त्रुटि को सही करने में मदद करता है?

अतिरिक्त डाटा: मैं GL_RGBA को GL_RGB बदलने की कोशिश की और प्रारूपों के साथ खेलना शुरू किया, वैसे भी यह दुर्घटनाओं जब मैं GL_RGBA कोशिश (क्योंकि चौड़ाई और ऊंचाई बहुत विशाल हैं, वैसे भी मैं उन्हें आकार बदलने के लिए करने की कोशिश की)। मैंने आकारों को 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 सुझावों में से कुछ का पालन किया है, और अब वीडियो ऑडियो/वीडियो के साथ सही ढंग से प्रदर्शित कर रहा है:

Screenshot took

+0

क्या आपके द्वारा उल्लिखित माध्यमिक धागे पर या अगला धागे पर 'NextVideoFrame()' चल रहा है? – genpfault

+0

मैं CreateThread और थ्रेड पोस्ट करूंगा, यह कोड – Spamdark

+0

कोड को देखकर बेहतर नहीं है। द्वितीयक थ्रेड केवल कतार में AVFrame को संग्रहीत करता है, NextVideoFrame को किसी अन्य स्थान पर कॉल किया जाता है, एक फ़ंक्शन जो NextVideoFrame के साथ बनावट को अद्यतन करता है और फिर इसे स्क्रीन पर खींचता है (opengl) – Spamdark

उत्तर

5

multithreading के साथ ओपन थोड़ा मुश्किल है। प्रति थ्रेड और पर केवल एक या कोई सक्रिय OpenGL संदर्भ नहीं है, एक दिया गया OpenGL संदर्भ एक समय में केवल एक थ्रेड में सक्रिय हो सकता है। धागे के बीच एक संदर्भ माइग्रेट करना संभव है, लेकिन आपको धागे के बीच गर्म ओपनजीएल-संदर्भ-आलू नहीं खेलना चाहिए।

  • उपयोग स्मृति मैप किए गए पिक्सेल बफर ऑब्जेक्ट (एक सूत्र में नक्शा, अद्यतन अन्य में)

  • एक माध्यमिक ओपन संदर्भ का प्रयोग करें, के साथ अपने बनावट साझा करने:

    इसके दो संभावित तरीके हैं अन्य। फिर प्रत्येक थ्रेड पर एक संदर्भ बांधें (आप उसी ड्रॉइंग का उपयोग कर सकते हैं, यानी विंडोज़ पर एचडीसी)। फिर आप एक थ्रेड में बनावट को अपडेट कर सकते हैं जबकि दूसरा इसे खींचता है।बनावट अपडेट थ्रेड के बीच सिंक्रनाइज़ेशन पॉइंट्स पेश करते हैं, इसलिए ड्राइंग के लिए इसे एक्सेस करते समय आप गलती से बनावट में लिख नहीं सकते हैं।

+0

ग्रेट आइडिया! मैंने हाल ही में [stackoverflow प्रश्न] (http://stackoverflow.com/questions/6495523/ffmpeg-video-to-opengl-texture) पर अपने उत्तरों में से एक में देखा है और इससे मुझे बहुत मदद मिली है। यहां एक स्क्रीनशॉट है! यह ठीक काम कर रहा है! [स्क्रीनशॉट] (http://oi45.tinypic.com/71ldh3.jpg) – Spamdark

+0

माइंड हमारे साथ अपना कोड साझा कर रहा है अब आपने इसे ठीक कर दिया है? –

+0

@ माइकवर्स्टीग: क्या वह मुझ पर या स्पैमडर्क निर्देशित था? यदि बाद में आपको उसे नोटिस करने के लिए उपयोगकर्ता नाम के सामने '@' जोड़ना होगा। – datenwolf

संबंधित मुद्दे