0

ARMプロセッサとWayland + Qtをウィンドウサブシステムとして使用した独自のカスタムボード用のgstreamerフレームワークに基づいて、単純なビデオレコーダーを作成しようとしています。rec_start スロットと rec_stop パブリック メソッドを使用してクラス RecordBin を作成しました。

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 メインループ コンテキストが Qt メイン ウィンドウをブロックしないようにします。rec_stop メソッドをスロットとして使用できません。rec_loop がメッセージ処理をブロックし、記録が開始されたときにシグナルを介して停止できないためです。ただし、rec_stop の直接呼び出しはスレッドセーフではありません。

1.別のスレッドからパイプラインの状態を変更するにはどうすればよいですか? 2. パイプラインの状態を NULL に変更して記録を停止するのは正しいですか? おそらく、バス上で EOS 信号を送信して処理する必要がありますか?

4

1 に答える 1

0

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

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

于 2017-03-09T10:34:13.233 に答える