1

我正在开发一个 Gstreamer (v1.14.4) 应用程序,我在其中通过 RTSP 提供实时视频流,并在设备上以不同的比特率记录它。为了提供 RTSP 流,我使用 gst-rtsp-server。为了同时进行流式传输和录制,我在提供给 RTSP 服务器的 lauch 行中有 atee和 a以及带有 a和 a的第二个管道:proxysinkproxysrcfilesink

RTPS管道:

v4l2src --> tee  --> proxysink
                 |--> queue --> omxh264enc --> h264parse --> rtph264pay pt=96 name=pay0

录制管道:

proxysrc --> omxh264enc --> h264parse --> matroskamux --> filesink 

当客户端连接时,我在 RTSP 媒体工厂的"media-configure"回调中链接两个代理元素。流式传输和写入文件都有效,除了文件不可搜索,我认为是因为它没有正确完成。

当我通过调用以下函数(是一个包含指向我需要的所有 Gstreamer 元素的指针的结构)获得 a"teardown-request"时,我试图完成它:GstRTSPClientCustomData

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 结合使用。我怀疑问题出在那儿,可能是因为在我尝试完成录制时,录制管道没有从流管道中获取新数据。

我究竟做错了什么?

谢谢你的帮助。

4

0 回答 0