Hello, I create a pipeline with parse launch, I have a bit tee structure on it and I have a recorder structure that starts at the beginning while showing my broadcast with videosink and I have a button on the qml side, I trigger the stoprecording function here, but whenever I trigger it, the image in the videosink structure freezes and stops flowing while the file is being recorded, I have tried many methods, when I give the eosu to the filesink, my whole application freezes when I press the stop button, I need help because I am new to gstreamer, thanks in advance. @Joe
QString pipelineDescription = QString(
"rtspsrc location=%1 latency=0 udp-reconnect=1 ! "
"rtpjitterbuffer latency=50 ! "
"rtph264depay ! "
"h264parse ! "
"avdec_h264 ! "
"videoconvert ! "
"tee name=t "
"t. ! queue ! "
"glupload ! "
"glcolorconvert ! "
"qmlglsink name=video_sink "
"t. ! queue ! "
"valve name =recording_valve ! "
"videoconvert ! "
"video/x-raw,format=I420 ! "
"x264enc tune=zerolatency ! "
"mp4mux ! "
"filesink name= file_sink location=/home/user/stream_record.mp4"
).arg(url);
GError *error = nullptr;
pipeline = gst_parse_launch(qPrintable(pipelineDescription), &error);
if (!pipeline || error) {
qCritical() << "Failed to create pipeline:" << (error ? error->message : "unknown error");
if (error) g_error_free(error);
return;
}
GstElement *videoSink = gst_bin_get_by_name(GST_BIN(pipeline), "video_sink");
if (!videoSink) {
qCritical() << "Failed to find qmlglsink in pipeline.";
gst_object_unref(pipeline);
pipeline = nullptr;
return;
}
g_object_set(G_OBJECT(videoSink), "widget", videoItem, nullptr);
gst_object_unref(videoSink);
GstBus *bus = gst_element_get_bus(pipeline);
gst_bus_add_watch(bus, (GstBusFunc)GStreamerQmlSink::busCall, this);
gst_object_unref(bus);
GstStateChangeReturn ret = gst_element_set_state(pipeline, GST_STATE_PLAYING);
if (ret == GST_STATE_CHANGE_FAILURE) {
qCritical() << "Failed to set pipeline to PLAYING.";
gst_object_unref(pipeline);
pipeline = nullptr;
return;
}
qInfo() << "Pipeline started successfully.";
}
void GStreamerQmlSink::stopRecording()
{
if (!pipeline) {
qWarning() << "No active pipeline.";
return;
}
GstElement *fileSink = gst_bin_get_by_name(GST_BIN(pipeline), "file_sink");
if (!fileSink) {
qWarning() << "No active recording found.";
return;
}
qInfo() << "Stopping recording...";
GstEvent *eos_event = gst_event_new_eos();
gst_element_send_event(pipeline, eos_event);
GstBus *bus = gst_element_get_bus(pipeline);
GstMessage *msg = gst_bus_timed_pop_filtered(bus, GST_CLOCK_TIME_NONE, GST_MESSAGE_EOS);
if (msg)
gst_message_unref(msg);
gst_object_unref(bus);
gst_element_set_state(fileSink, GST_STATE_NULL);
qInfo() << "Recording stopped successfully. MP4 file is now valid.";
}