I'm developing a Gstreamer (v1.14.4) application where I serve a live video stream over RTSP and alongside record it on-device with a different bitrate. To serve the RTSP stream, I use gst-rtsp-server. In order to both stream and record, I have a tee and a proxysink in the lauch line I give to the RTSP server and a second pipeline with a proxysrc and a filesink:
RTPS pipeline:
v4l2src --> tee --> proxysink
|--> queue --> omxh264enc --> h264parse --> rtph264pay pt=96 name=pay0
Recording pipeline:
proxysrc --> omxh264enc --> h264parse --> matroskamux --> filesink
When a client connects, I link the two proxy elements in the RTSP media factory's "media-configure" callback. Both streaming and writing to file works, except that the file is not seekable, I assume because it's not properly finalized.
I am trying to finalize it when I get a "teardown-request" from the GstRTSPClient by calling the following function (CustomData is a struct holding pointers to all the Gstreamer elements I need.):
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");
}
}
Everything works as expected here and "got EOS on bus" is printed. However, the file is not seekable. Besides what's shown in the above function I have tried:
- sending the EOS not to the sinkpad of the filesink, but to the filesink element itself. Then I do not get the message on the bus (
gst_bus_timed_pop_filteredhangs indefinitely) - sending the EOS not to the filesink, but to the whole record pipeline. Again, no EOS on the bus.
- trying all of the above just after ensuring the record pipeline is in the playing state. That makes no difference.
I've successfully written to properly finalized video files before, but never in conjunction with gst-rtsp-streamer. I suspect the issue lies there, maybe because the recording pipeline is not getting new data from the streaming pipeline at the time when I try to finalize the recording.
What am I doing wrong?
Thanks for your help.