From 23fa175907e19ecf1b33acab5751662bff0070b2 Mon Sep 17 00:00:00 2001 From: Piotr Srebrny Date: Mon, 27 Sep 2021 14:29:31 +0200 Subject: GStreamer: wait to finalize recording before detaching from the session When disconnecting the recorder from the session, the recording was abruptly terminated with a call to finalize(). Instead we should call stop() and wait until the recording is finalized. Pick-to: 6.2 Change-Id: Ib93f2ddc7bd49dbf67cbe703eb18a0f82eb127d9 Reviewed-by: Lars Knoll --- .../mediacapture/qgstreamermediaencoder.cpp | 24 ++++++++++++++-------- .../mediacapture/qgstreamermediaencoder_p.h | 2 ++ src/multimedia/platform/qplatformmediarecorder_p.h | 2 ++ 3 files changed, 20 insertions(+), 8 deletions(-) diff --git a/src/multimedia/platform/gstreamer/mediacapture/qgstreamermediaencoder.cpp b/src/multimedia/platform/gstreamer/mediacapture/qgstreamermediaencoder.cpp index 1c82f5128..618544d0d 100644 --- a/src/multimedia/platform/gstreamer/mediacapture/qgstreamermediaencoder.cpp +++ b/src/multimedia/platform/gstreamer/mediacapture/qgstreamermediaencoder.cpp @@ -47,6 +47,7 @@ #include "qmediastoragelocation_p.h" #include +#include #include #include #include @@ -123,6 +124,8 @@ bool QGstreamerMediaEncoder::processBusMessage(const QGstreamerMessage &message) error(QMediaRecorder::ResourceError, QString::fromUtf8(err->message)); g_error_free(err); g_free(debug); + if (!m_finalizing) + stop(); finalize(); } @@ -282,7 +285,7 @@ GstPadProbeReturn QGstreamerMediaEncoder::PauseControl::processBuffer(QGstPad, G void QGstreamerMediaEncoder::record(QMediaEncoderSettings &settings) { - if (!m_session || state() != QMediaRecorder::StoppedState) + if (!m_session ||m_finalizing || state() != QMediaRecorder::StoppedState) return; const auto hasVideo = m_session->camera() && m_session->camera()->isActive(); @@ -351,7 +354,7 @@ void QGstreamerMediaEncoder::record(QMediaEncoderSettings &settings) void QGstreamerMediaEncoder::pause() { - if (!m_session || state() != QMediaRecorder::RecordingState) + if (!m_session || m_finalizing || state() != QMediaRecorder::RecordingState) return; signalDurationChangedTimer.stop(); gstPipeline.dumpGraph("before-pause"); @@ -361,7 +364,7 @@ void QGstreamerMediaEncoder::pause() void QGstreamerMediaEncoder::resume() { gstPipeline.dumpGraph("before-resume"); - if (!m_session || state() != QMediaRecorder::PausedState) + if (!m_session || m_finalizing || state() != QMediaRecorder::PausedState) return; signalDurationChangedTimer.start(); stateChanged(QMediaRecorder::RecordingState); @@ -369,15 +372,13 @@ void QGstreamerMediaEncoder::resume() void QGstreamerMediaEncoder::stop() { - if (!m_session || state() == QMediaRecorder::StoppedState) + if (!m_session || m_finalizing || state() == QMediaRecorder::StoppedState) return; qCDebug(qLcMediaEncoder) << "stop"; - + m_finalizing = true; m_session->unlinkEncoder(); signalDurationChangedTimer.stop(); - //with live sources it's necessary to send EOS even to pipeline - //before going to STOPPED state qCDebug(qLcMediaEncoder) << ">>>>>>>>>>>>> sending EOS"; gstEncoder.sendEos(); } @@ -395,6 +396,7 @@ void QGstreamerMediaEncoder::finalize() gstPipeline.remove(gstFileSink); gstFileSink = {}; gstEncoder = {}; + m_finalizing = false; stateChanged(QMediaRecorder::StoppedState); } @@ -419,7 +421,13 @@ void QGstreamerMediaEncoder::setCaptureSession(QPlatformMediaCaptureSession *ses return; if (m_session) { - finalize(); + stop(); + if (m_finalizing) { + QEventLoop loop; + loop.connect(mediaRecorder(), SIGNAL(recorderStateChanged(RecorderState)), SLOT(quit())); + loop.exec(); + } + gstPipeline.removeMessageFilter(this); gstPipeline = {}; } diff --git a/src/multimedia/platform/gstreamer/mediacapture/qgstreamermediaencoder_p.h b/src/multimedia/platform/gstreamer/mediacapture/qgstreamermediaencoder_p.h index 4c4feb729..3d529d6b3 100644 --- a/src/multimedia/platform/gstreamer/mediacapture/qgstreamermediaencoder_p.h +++ b/src/multimedia/platform/gstreamer/mediacapture/qgstreamermediaencoder_p.h @@ -118,6 +118,8 @@ private: QGstPipeline gstPipeline; QGstBin gstEncoder; QGstElement gstFileSink; + + bool m_finalizing = false; }; QT_END_NAMESPACE diff --git a/src/multimedia/platform/qplatformmediarecorder_p.h b/src/multimedia/platform/qplatformmediarecorder_p.h index 450a5fccc..2cd70f682 100644 --- a/src/multimedia/platform/qplatformmediarecorder_p.h +++ b/src/multimedia/platform/qplatformmediarecorder_p.h @@ -168,6 +168,8 @@ protected: void error(QMediaRecorder::Error error, const QString &errorString); void metaDataChanged(); + QMediaRecorder *mediaRecorder() { return q; } + private: QMediaRecorder *q = nullptr; QMediaRecorder::Error m_error = QMediaRecorder::NoError; -- cgit v1.2.3