gstreamer-1.0通过GUI停止和开始记录管道

时间:2017-03-09 09:48:43

标签: qt gstreamer-1.0

我正在尝试编写简单的录像机,基于gstreamer框架,用于我自己的自定义板,ARM处理器和Wayland + Qt作为窗口子系统。 我用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信号并进行处理?

1 个答案:

答案 0 :(得分:0)

gst_element_set_state()被标记为MT安全,因此可以从任何线程停止。我将gst_element_set_state()设置为NULL时出现问题:管道末端的filesink未正确完成输出文件(必须使用EOS并捕获另一个确认{{1}的事件已经得到了EOS)。但NULL适用于玩家。

总的来说,我已经摆脱了滑稽的主循环。您可以使用filesink设置回调。在回调中,向gst_bus_set_sync_handler()发出Qt信号。 RecordBin将是RecordBin,它位于主Qt主题中。在其位置处理到达的QObject