我正在尝试基于 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 信号并处理它?