2017-03-09 81 views
0

私は自分のカスタムボードのgstreamerフレームワークに基づいて、ARMプロセッサとWayland + Qtをウィンドウサブシステムとして使って簡単なビデオレコーダーを作成しようとしています。私はrec_startスロットとクラスRecordBinを作成し、パブリックメソッドrec_stopまし :これは遊びのためのメインウィンドウでの私のスロットは、ボタンのクリックストップ/gstreamer-1.0 GUIを使って録画パイプラインを停止して開始する

void RecordBin::rec_start() 
{ 
    /* Set pipeline to the PLAYING state */ 
    gst_element_set_state (record_pipeline, GST_STATE_PLAYING); 
    g_print ("setting playing state\n"); 

    /* Start main loop context */ 
    g_main_loop_run (rec_loop); 
} 

void RecordBin::rec_stop() 
{ 
    /* Set pipeline to the NULL state */ 
    change_ret = gst_element_set_state (record_pipeline, GST_STATE_NULL); 

    /* Quit from main loop context */ 
    g_main_loop_quit (rec_loop); 
} 

です:

void MainWindow::on_recordButton_clicked() 
{ 
    if (!is_recording) { 
    if (window_is_opened == false) { 
     cout << "start recording" << endl; 

     /* Start recording */ 
     window_is_opened = true; 
     emit start_recording(); 
    } else { 
     cout << "playing window already opened" << endl; 
    } 
    } else { 
    cout << "recording reset" << endl; 

    /* Stop recording */ 
    record_bin->rec_stop(); 
    window_is_opened = false; 
    } 
} 

RecordBinクラスは別のスレッドで働いています(これはQThreadを介して実現されています)、glib mainloopコンテキストはQtメインウィンドウをブロックしません。 rec_stopメソッドをスロットとして使用することはできません。なぜなら、rec_loopはメッセージ処理をブロックし、録音が開始されるとシグナルで停止することができないからです。 しかし、ダイレクトコールrec_stopはスレッドが安全ではありません。

誰でも2つの質問で私を助けることができます: 1.パイプラインの状態を別のスレッドからどのように変更する必要がありますか? 2.パイプライン状態をNULLに変更して記録を停止するのは正しいですか?おそらく私はEOS信号をバスに送り、それを処理するべきでしょうか?

答えて

0

gst_element_set_state()はMTセーフとしてマークされているため、どのスレッドからでも停止できます。 gst_element_set_state()をNULLに設定すると問題が発生しました。パイプラインの最後のfilesinkが出力ファイルを正しく完了していない(EOSを使用して、filesinkにEOSがあることを確認していた別のイベントをキャッチする必要がありました)。しかしNULLはプレーヤーにとってうまくいきます。

全体として、私はglibメインループを取り除くだろう。 gst_bus_set_sync_handler()を使用してコールバックを設定できます。コールバックでQt信号をRecordBinに送ります。 RecordBinは、メインのQtスレッドに存在するQObjectになります。そのスロットに到着したGstMessage*を処理します。

関連する問題