我正在开发一个 Gstreamer (v1.14.4) 应用程序,我在其中通过 RTSP 提供实时视频流,并在设备上以不同的比特率记录它。为了提供 RTSP 流,我使用 gst-rtsp-server。为了同时进行流式传输和录制,我在提供给 RTSP 服务器的 lauch 行中有 atee
和 a以及带有 a和 a的第二个管道:proxysink
proxysrc
filesink
RTPS管道:
v4l2src --> tee --> proxysink
|--> queue --> omxh264enc --> h264parse --> rtph264pay pt=96 name=pay0
录制管道:
proxysrc --> omxh264enc --> h264parse --> matroskamux --> filesink
当客户端连接时,我在 RTSP 媒体工厂的"media-configure"
回调中链接两个代理元素。流式传输和写入文件都有效,除了文件不可搜索,我认为是因为它没有正确完成。
当我通过调用以下函数(是一个包含指向我需要的所有 Gstreamer 元素的指针的结构)获得 a"teardown-request"
时,我试图完成它:GstRTSPClient
CustomData
void stop_recording(CustomData *data)
{
if (data == NULL) {
GST_ERROR("Got NULL CustomData!");
return;
}
if (data->record_writer != NULL) { // record_writer is the filesink element
GstPad *sink_pad = gst_element_get_static_pad(data->record_writer, "sink");
if (sink_pad == NULL) {
g_print("sink pad is null");
return;
}
int send_eos = gst_pad_send_event(sink_pad, gst_event_new_eos());
// DEBUG: check that the EOS reaches the end of the pipeline
GstBus *bus = gst_pipeline_get_bus(GST_PIPELINE(data->record_pipeline));
GstMessage *msg = gst_bus_timed_pop_filtered(bus, GST_CLOCK_TIME_NONE, GST_MESSAGE_EOS);
gst_object_unref(bus);
if (GST_MESSAGE_TYPE(msg) == GST_MESSAGE_EOS) {
g_print("got EOS on bus\n");
} else {
g_print("got something else on bus %d\n", GST_MESSAGE_TYPE(msg));
}
gst_message_unref(msg);
} else {
g_print("Can't stop recording, record_pipeline not initialized\n");
}
}
这里的一切都按预期工作,并打印了“got EOS on bus”。但是,该文件不可查找。除了上述功能中显示的内容外,我还尝试过:
- 不是将 EOS 发送到 filesink 的 sinkpad,而是发送到 filesink 元素本身。然后我没有在公共汽车上收到消息(
gst_bus_timed_pop_filtered
无限期挂起) - 不是将 EOS 发送到文件接收器,而是发送到整个记录管道。同样,总线上没有 EOS。
- 在确保记录管道处于播放状态之后尝试上述所有操作。这没什么区别。
我之前已经成功写入正确完成的视频文件,但从未与 gst-rtsp-streamer 结合使用。我怀疑问题出在那儿,可能是因为在我尝试完成录制时,录制管道没有从流管道中获取新数据。
我究竟做错了什么?
谢谢你的帮助。