2011-12-19 9 views
9

私が持っている問題は、次のコードにも関する:コードは罰金コンパイルハスケルのGStreamerティー要素(1-N)トラブル

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 

、カメラLEDはONスイッチとファイルが作成されるが、その後何もありません。ティーとキューの要素がなければ 、記録のための別のセットアップ/ビデオは、私は、GST-打ち上げでそれをテストする場合fine.Also、同じパイプラインは完璧に動作だけで動作し表示します。 gstreamerの仕組みについては、ここで何か不足していますが、何が分かりません。

さらに、私が助けてくれれば、私はArchLinuxを使って次のようにビルドしています。
- GHC 7.0.3;
- のgstreamer-バインディング0.12.1;
- gtk2hs 0.12.2。
- 0.10.35-1のgstreamer。
- glib 1.2.10-9。

+0

あなたは答えとしてあなたの発見を追加し、その答えを受け入れる必要があります...行きます。ここであなた自身の質問に答えるのは失礼だとは思われません。もしあなたが何が間違っていたかを知る最初の人であれば、より多くの力をあなたに! –

答えて

10

を解決し、私は私の解決策を見つけ、そして以下は、長い記事ですが、私と一緒に裸、私は誰かと私の欲求不満を共有する必要がありますしてください。

は、より多くのバグの試行後、私は戻って、GST-打ち上げを使用して、いくつかのセットアップをテストするに行くことにしました。 これは私がセットアップに私が思う正しいビデオフォーマットを別のffmpegcolorspace要素を必要とfilesinkに行くの部分をバッファキュー要素の後にあることを見つけるために私を助けました。 この時点で、私はこの事をハスケルからもう一度試してみることに戻っていませんでした。私は私がCでそれを試してみるために、私は「もっと近く」になる必要があると思った。 サイドノートとして、構文を理解することができますが、それはそれについてです...そして良さのために、私は今、ハスケルを学ぼうとしています。 私はパッドがキューにリンクすることを確認することができますので、私はまた、GSelementGetCompatiblePad 'ティー要素で使用することを試みることにしました。

iが一緒にステッチCコードは以下です:使用するために

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

} 


は私が手これら4本の関連するラインを切り替えるように、第1の待ち行列の要素から静的パッドを取得しなければならなかった「gst_element_get_compatible_pad」。 私はそれを試して、Abracadabra ...ああ、いや、待って...カメラが始まると、ファイルが作成され、 'ビデオ'ポップスを持つウィンドウが黒いまま黒いウィンドウ!


gst-debug-level = 5(=))を使ってプログラムを実行しても問題ありません)よろしいですか、出力全体を読むことを試みてください。私は諦めています。一緒に作業していない私のパイプラインの要素で行うのですが、C言語で別のパイプラインを作成しますが、今度はオーディオファイルだけでもっと簡単です。
私は同じ結果を得たので、もう一度tuデバッグを決定しました。今回はランレベル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"); 


『のすべての出現置き換えることすべてが始まっところこれは、』あなたはなじるを;深呼吸する ;結局のところ、これはデバッガが私がコンパイルするので、私は実行し、Voilaについて不平を言うものです。私は私の解決策を見つけた。


これらの4つのラインを逆にしなければならなかったので、最初にスタティックパッドへの参照を取得してから、teeエレメントの「要求」パッドへの参照を要求する必要がありました。
は、私がいなくても黒い画面、ちょうどthat..nothingのように...カメラはファイルが作成され、開始し、立ち上げて、幸せman.Iは私のソリューションを実装するのhaskellコンパイルに戻ります。私はちょうど私が要求パッドを解放する行をコメントアウトしてコンパイルしてもう一度実行することを決定した怒りに満ち
は、私の首には、しばらく前に傷つけるし始めました。
もう一度、魔法によってそれはすべて動作します、私は画面上とファイル内にビデオを持っています。
私はHaskellは単にきつく保持するのが好き、時にはあなただけの意味がない何かで行かなければならないと思います。 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 


は、/私はこれを見ている可能性がなければなりませんか?
はそれはことは明らかでしたか?


これは、これが私をより注意深く見せてくれると嬉しく思います。

は、このすべての結論として、私はそれが私にささやくと、私は耳を傾けなければならないことを学んだ、gstreamerのデバッグオプションについて学びました。私はGDBが強制的に使用されていることを知っていました。なぜなら、Cコードをステッチし始めたとき、私が得たものはすべて「seg fault」だったからです。
私は、レイジー評価と純粋なハスケルコードを愛することを学びました。
ハスケルの少し、おそらくCの小さなビットとより多くの経験。 は、半日程度三つのクラスと睡眠の数時間を「失われた」が、すべての後に... は、だから、

関連する問題