2011-12-19 14 views
9

समस्या मेरे पास है कोड का निम्न भाग से संबंधित है:हास्केल GStreamer टी तत्व (1-एन) मुसीबत

module Main(main) where 

import qualified Media.Streaming.GStreamer as GS 
import Data.Maybe 
import System.IO 
import System.Exit 
import System.Glib.MainLoop as Glib 
import System.Glib.Signals as Glib 
import System.Glib.Properties as Glib 


makeElement:: String → String → IO GS.Element 
makeElement elementType elementName = do 
    element ← GS.elementFactoryMake elementType (Just elementName) 
    case element of 
     Just element' → return element' 
     Nothing → do 
      hPutStrLn stdout ("Cannot create element!") 
      hFlush stdout 
      exitFailure 

player = do 
    GS.init 

    pipeline ← GS.pipelineNew "video-stream" 

    source ← makeElement "v4l2src" "video-source" 
    color ← makeElement "ffmpegcolorspace" "video-color" 
    tee  ← makeElement "tee" "stream-tee" 
    rQ  ← makeElement "queue" "record-queue" 
    vQ  ← makeElement "queue" "video-queue" 
    encoder ← makeElement "y4menc" "video-encoder" 
    rSink ← makeElement "filesink" "record-sink" 
    sink ← makeElement "ximagesink" "video-sink" 

    let elements = [source,color,encoder,rSink,vQ,rQ,sink,tee] 

    Glib.objectSetPropertyString "location" rSink "rec" 

    mapM_ (GS.binAdd (GS.castToBin pipeline)) elements 

    -- Request Pads from tee 
    dPad ← GS.elementGetRequestPad tee "src%d" 
    rPad ← GS.elementGetRequestPad tee "src%d" 
    -- Request Static Pads from queue 
    sDPad ← GS.elementGetStaticPad vQ "sink" 
    sRPad ← GS.elementGetStaticPad rQ "sink" 
    -- Link tee source to queue sink 
    GS.padLink (fromJust dPad) (fromJust sDPad) 
    GS.padLink (fromJust rPad) (fromJust sRPad) 

    GS.elementReleaseRequestPad tee $ fromJust dPad 
    GS.elementReleaseRequestPad tee $ fromJust rPad 

    GS.elementLink source color 
    GS.elementLink color tee 
    GS.elementLink vQ sink 
    GS.elementLink rQ encoder 
    GS.elementLink encoder rSink 


    GS.elementSetState pipeline GS.StatePlaying 

main = do 
    loop ← Glib.mainLoopNew Nothing False 
    player 
    Glib.mainLoopRun loop 

कोड ठीक संकलित, कैमरा एलईडी पर स्विच और फ़ाइल बनाई लेकिन तब है कुछ भी तो नहीं। टी और कतार तत्वों के बिना, वीडियो रिकॉर्डिंग/प्रदर्शित करने के लिए अलग सेटअप बस ठीक काम करता है। इसके अलावा, यदि मैं जीएसटी-लॉन्च के साथ परीक्षण करता हूं तो वही पाइपलाइन पूरी तरह से काम करती है। मुझे यहां कुछ याद आ रहा है कि gstreamer कैसे काम करता है लेकिन मैं यह नहीं समझ सकता कि क्या।

इसके अलावा, अगर यह मदद करता है, तो मैं आर्किंक्स पर निर्माण कर रहा हूं:
- जीएचसी 7.0.3;
- gstreamer-bindings 0.12.1;
- gtk2hs 0.12.2;
- gstreamer 0.10.35-1;
- ग्लिब 1.2.10-9।

+0

आपने एक उत्तर के रूप में अपने खोजों जोड़ सकते हैं और है कि इसका जवाब को स्वीकार करना चाहिए। इसे अपने स्वयं के प्रश्न का उत्तर देने के लिए कठोर नहीं माना जाता है - यदि आप गलत क्या खोजते हैं, तो आपको सबसे अधिक शक्ति मिलती है! –

उत्तर

10

मैं अपने समाधान समाधान हो गया और क्या इस प्रकार एक लंबी पोस्ट है, लेकिन कृपया, मेरे साथ नंगे, मैं किसी के साथ मेरी हताशा साझा करना होगा।

कई और छोटी गाड़ी कोशिश करने के बाद मैंने जीएसटी-लॉन्च का उपयोग करके कुछ सेटअप का परीक्षण करने के लिए वापस जाने का फैसला किया। इससे मुझे यह पता लगाने में मदद मिली कि कतार तत्व के बाद जो कि फाइलिंक पर जाने वाले भाग को बफर करता है, मुझे लगता है कि सही वीडियो प्रारूप को स्थापित करने के लिए मुझे एक और ffmpegcolorspace तत्व चाहिए। इस बिंदु पर मैं इस बात की कोशिश करने के लिए वापस नहीं जा रहा था, इसे फिर से हास्केल से बाहर, मैंने सोचा कि मुझे 'करीब' पाने की ज़रूरत है इसलिए मैंने इसे सी में कोशिश करने का फैसला किया, एक साइड नोट के रूप में, मुझे सी नहीं पता, मैं सिंटैक्स को समझ सकते हैं लेकिन यह इसके बारे में है ... और भलाई के लिए मैं अभी हास्केल सीखने की कोशिश कर रहा हूं। जारी रखने के लिए, मैंने टीई तत्व पर 'GS.elementGetCompatiblePad' का उपयोग करने का भी प्रयास करने का निर्णय लिया ताकि मैं सुनिश्चित कर सकूं कि पैड कतार से लिंक होंगे।

सी कोड मैं एक साथ लगाया गया यह है:

#include <gst/gst.h> 
#include <glib.h> 

int 
main (int argc,char *argv[]) 
{ 

    GstElement *pipeline, *source, *color, *color2 , *color3, *tee, *rQ, *vQ, *encoder, *fSink , *sink; 
    GMainLoop *loop; 
    loop = g_main_loop_new (NULL,FALSE); 
    /* initialize gstreamer */ 
    gst_init(&argc,&argv); 

    /* creating elements */ 
    pipeline = gst_pipeline_new("stream-pipeline"); 

    source = gst_element_factory_make ("v4l2src","stream-source"); 
    color = gst_element_factory_make ("ffmpegcolorspace","video-color"); 
    tee = gst_element_factory_make ("tee","stream-tee"); 
    rQ = gst_element_factory_make ("queue","record-queue"); 
    vQ = gst_element_factory_make ("queue","video-queue"); 
    encoder = gst_element_factory_make ("theoraenc","video-encoder"); 
    fSink = gst_element_factory_make ("filesink","record-sink"); 
    sink = gst_element_factory_make ("ximagesink","video-sink"); 
    color2 = gst_element_factory_make ("ffmpegcolorspace","video-color2"); 
    color3 = gst_element_factory_make ("ffmpegcolorspace","video-color3"); 
    /*check that the elements were created */ 

    if (!source || !color || !tee || !rQ || !vQ || !encoder || !fSink || !sink){ 
     g_printerr("One element could not be created!"); 
     return -1; 
    } 
    /*set file output location */ 
    g_object_set(G_OBJECT (fSink),"location","rec",NULL); 

    gst_bin_add_many (GST_BIN(pipeline), 
         source,color,color2,color3,tee,rQ,vQ,encoder,fSink,sink,NULL); 

    /* get request pads */ 
    GstPad *dPad, *rPad, *sDPad, *sRPad; 

    sDPad = gst_element_get_static_pad(vQ,"sink"); 
    sRPad = gst_element_get_static_pad(rQ,"sink"); 
    dPad = gst_element_get_compatible_pad(tee,sDPad,GST_CAPS_ANY); 
    rPad = gst_element_get_compatible_pad(tee,sRPad,GST_CAPS_ANY); 

    /*link pads*/ 
    gst_pad_link(dPad,sDPad); 
    gst_pad_link(rPad,sRPad); 

    /*unref pads */ 
    gst_object_unref(GST_OBJECT(dPad)); 
    gst_object_unref(GST_OBJECT(rPad)); 
    gst_object_unref(GST_OBJECT(sDPad)); 
    gst_object_unref(GST_OBJECT(sRPad)); 

    /*link elements */ 
    gst_element_link(source,tee); 
    gst_element_link_many(rQ,color2,encoder,fSink,NULL); 
    gst_element_link_many(vQ,color3,sink),NULL; 

    /*set the pipeline state to playing */ 
    gst_element_set_state(pipeline,GST_STATE_PLAYING); 

    g_main_loop_run (loop); 

    gst_element_set_state(pipeline,GST_STATE_NULL); 
    gst_object_unref(GST_OBJECT(pipeline)); 

    return 0; 

} 


आदेश में 'gst_element_get_compatible_pad' का उपयोग करने के मैं पहले उन चार सम्बंधित लाइन स्विच करने के लिए तो मैं हाथ कतार तत्वों से स्थिर पैड पाने के लिए था। मैं इसे आज़माता हूं, और अब्राकदबरा ... ओह नहीं, प्रतीक्षा करें ... कैमरा शुरू होता है, फ़ाइल बनाई जाती है और 'वीडियो' पॉप वाली खिड़की होती है, लेकिन एक काला खिड़की जो काला बनी हुई है!


कोई बात नहीं मैं जीएसटी-डिबग स्तर के साथ कार्यक्रम चलाने का कहना है, = 5 (=))) हां, ठीक है, पढ़ने पूरे output.I पल के लिए छोड़ देना कोशिश करते हैं और मैं शायद सोचा था कि यह कुछ करने के लिए है मेरी पाइपलाइन के तत्वों के साथ एक साथ काम नहीं कर रहे हैं इसलिए मैं सी में एक और पाइपलाइन कोड करता हूं लेकिन इस बार ऑडियो फ़ाइलों के साथ कुछ और आसान है।
मेरे पास एक ही परिणाम था इसलिए मैंने फिर से डीयूग डीबग का फैसला किया, इस बार रनलेवल 3 के साथ और मैंने पूरी चीज को लाइन से लाइन पढ़ना शुरू कर दिया।src0 और रिकार्ड कतार: सिंक
से जोड़ने के लिए धारा-टी की कोशिश कर रहा: src0 और वीडियो कतार


से जोड़ने के लिए धारा-टी की कोशिश कर रहा: वहाँ में


कहीं मैं इस पाया: सिंक


कुछ बुरा हो रहा है यहाँ


जुड़ा हुआ धारा-टी: src0 और वीडियो कतार: सिंक, सफल
से जोड़ने के लिए धारा-टी की कोशिश कर रहा: src0 और रिकार्ड कतार: सिंक
src धारा-टी: src0 पहले से ही वीडियो-पंक्ति से जोड़ा जाता था: सिंक


और यह छोड़ देता है!
मुझे लगता है कि मुझे gst_element_get_request_pad का उपयोग करके वापस जाना होगा, लेकिन मैंने पहले से ही कोशिश नहीं की है? तो मैं वापस vim को 'अनुरोध समकक्ष के साथ तो जैसे gst_element_get_compatible_pad:

sDPad = gst_element_get_static_pad(vQ,"sink"); 
sRPad = gst_element_get_static_pad(rQ,"sink"); 
dPad = gst_element_get_request_pad(tee,"src%d"); 
rPad = gst_element_get_request_pad(tee,"src%d"); 


मैं इस कोड पर टकटकी और मैं अपने आप को कहते हैं' स्विच और की सभी घटनाओं की जगह आप निंदा ', यह वह जगह है जहाँ यह सब शुरू कर दिया ; एक गहरी सास लो ; आखिरकार डीबगर शिकायत करता है कि मैं संकलित करता हूं, मैं दौड़ता हूं, और वोला। मुझे मेरा समाधान मिला।


उन चार लाइनों को उलट दिया जाना था, मुझे पहले स्थिर पैड का संदर्भ प्राप्त करना था और फिर टी तत्व पर 'अनुरोध' पैड के संदर्भ का अनुरोध करना था।
मैं एक खुश आदमी को हैकेल पर वापस जाता हूं। मैं अपना समाधान लागू करता हूं, संकलित करता हूं, आग लगता हूं, कैमरा शुरू होता है, फ़ाइल बनाई जाती है और ... बस इसी तरह .. कुछ भी नहीं, यहां तक ​​कि काली स्क्रीन भी नहीं।
क्रोध से भरा हुआ मैं सिर्फ उन पंक्तियों पर टिप्पणी करता हूं जहां मैं अनुरोध पैड जारी करता हूं और एक बार फिर संकलन और चलाने का फैसला करता हूं, मेरी गर्दन थोड़ी देर पहले चोट लगने लगी।
फिर, जादू से यह सब काम करता है, मेरे पास स्क्रीन पर और फ़ाइल में वीडियो है।
मुझे लगता है कि हास्केल को कड़ा पकड़ना पसंद है और कभी-कभी आपको किसी ऐसी चीज के साथ जाना पड़ता है जो समझ में नहीं आता है। Gstreamer दस्तावेज़ राज्य स्पष्ट रूप से रिलीज, रिलीज, रिलीज।

अंतिम Haskell कोड:

module Main(main) where 

import qualified Media.Streaming.GStreamer as GS 
import Data.Maybe 
import System.Exit 
import System.Glib.MainLoop as Glib 
import System.Glib.Signals as Glib 
import System.Glib.Properties as Glib 

makeElement:: String → String → IO GS.Element 
makeElement elementType elementName = do 
     element ← GS.elementFactoryMake elementType (Just elementName) 
     case element of 
      Just element' → return element' 
      Nothing → do 
        putStrLn "Cannot create element!" 
        exitFailure 

linkSPadToStaticSink::(GS.ElementClass object, GS.ElementClass elementT) ⇒ object →  elementT → IO (Glib.ConnectId object) 
linkSPadToStaticSink elSrc elSink = do 
      Glib.on elSrc GS.elementPadAdded (λpad → do 
                sinkPad ← GS.elementGetStaticPad elSink "sink" 
                GS.padLink pad (fromJust sinkPad) 
                return ∅) 

player = do 
     GS.init 
     pipeline ← GS.pipelineNew "video-stream" 
     source ← makeElement "v4l2src" "video-source" 
     color ← makeElement "ffmpegcolorspace" "video-color" 
     color2 ← makeElement "ffmpegcolorspace" "video-color2" 
     tee ← makeElement "tee" "stream-tee" 
     rQ ← makeElement "queue" "record-queue" 
     vQ ← makeElement "queue" "video-queue" 
     encoder ← makeElement "y4menc" "video-encoder" 
     rSink ← makeElement "filesink" "record-sink" 
     sink ← makeElement "ximagesink" "video-sink" 

     let elements = [source,color,color2,encoder,rSink,vQ,rQ,sink,tee] 

     Glib.objectSetPropertyString "location" rSink "rec" 

     mapM_ (GS.binAdd (GS.castToBin pipeline)) elements 

     -- Get static pads from queue elements 
     sDPad ← GS.elementGetStaticPad vQ "sink" 
     sRPad ← GS.elementGetStaticPad rQ "sink" 
     -- Request pads from tee element 
     dPad ← GS.elementGetRequestPad tee "src%d" 
     rPad ← GS.elementGetRequestPad tee "src%d" 
     -- Link tee source to queue sink 
     GS.padLink (fromJust dPad) (fromJust sDPad) 
     GS.padLink (fromJust rPad) (fromJust sRPad) 

     GS.elementLink source color 
     GS.elementLink color tee 
     GS.elementLink vQ sink 
     GS.elementLink rQ color2 
     GS.elementLink color2 encoder 
     GS.elementLink encoder rSink 

     GS.elementSetState pipeline GS.StatePlaying 

main = do 
    loop ← Glib.mainLoopNew Nothing False 
    player 
    Glib.mainLoopRun loop 


अब मैं आप से पूछना,/मैं इस देखा जा सकता था चाहिए?
क्या यह स्पष्ट था?


मुझे खुशी है कि इससे मुझे और सावधान रहना होगा और इतनी स्पष्ट जगहों पर नज़र डालेंगे ... eww।

इन सबके निष्कर्ष में, मैंने gstreamer डीबग विकल्पों के बारे में सीखा, मैंने सीखा कि यह मेरे लिए फुसफुसाता है और मुझे सुनना चाहिए। मैंने जीडीबी को इस्तेमाल करने के लिए मजबूर होने के बारे में सीखा क्योंकि जब मैंने सी कोड सिलाई शुरू की तो मुझे एक 'सेग गलती' मिली।
मुझे आलसी-eval और शुद्ध हास्केल कोड प्यार करना सीखा।
हास्केल का एक छोटा सा, शायद सी का एक छोटा सा हिस्सा और अधिक अनुभव। 'खोया' एक दिन के बारे में आधे, तीन वर्गों और नींद की कई घंटे लेकिन सब के बाद ... तो यह जाता है ...