diff options
Diffstat (limited to 'src/multimedia/platform/gstreamer/mediacapture/qgstreamermediaencoder.cpp')
-rw-r--r-- | src/multimedia/platform/gstreamer/mediacapture/qgstreamermediaencoder.cpp | 79 |
1 files changed, 34 insertions, 45 deletions
diff --git a/src/multimedia/platform/gstreamer/mediacapture/qgstreamermediaencoder.cpp b/src/multimedia/platform/gstreamer/mediacapture/qgstreamermediaencoder.cpp index 7fba45341..54caca0d6 100644 --- a/src/multimedia/platform/gstreamer/mediacapture/qgstreamermediaencoder.cpp +++ b/src/multimedia/platform/gstreamer/mediacapture/qgstreamermediaencoder.cpp @@ -42,6 +42,7 @@ #include "private/qgstreamerformatinfo_p.h" #include "private/qgstpipeline_p.h" #include "private/qgstreamermessage_p.h" +#include "private/qplatformcamera_p.h" #include "qaudiodevice.h" #include "qmediastoragelocation_p.h" @@ -123,6 +124,7 @@ bool QGstreamerMediaEncoder::processBusMessage(const QGstreamerMessage &message) error(QMediaRecorder::ResourceError, QString::fromUtf8(err->message)); g_error_free(err); g_free(debug); + finalize(); } if (GST_MESSAGE_SRC(gm) == gstEncoder.object()) { @@ -283,6 +285,14 @@ void QGstreamerMediaEncoder::record(QMediaEncoderSettings &settings) if (!m_session || state() != QMediaRecorder::StoppedState) return; + const auto hasVideo = m_session->camera() && m_session->camera()->isActive(); + const auto hasAudio = m_session->audioInput() != nullptr; + + if (!hasVideo && !hasAudio) { + error(QMediaRecorder::ResourceError, QMediaRecorder::tr("No camera or audio input")); + return; + } + const auto audioOnly = settings.videoCodec() == QMediaFormat::VideoCodec::Unspecified; auto primaryLocation = audioOnly ? QStandardPaths::MusicLocation : QStandardPaths::MoviesLocation; @@ -294,10 +304,6 @@ void QGstreamerMediaEncoder::record(QMediaEncoderSettings &settings) Q_ASSERT(!actualSink.isEmpty()); - gstPipeline.dumpGraph("before-recording"); - - gstPipeline.beginConfig(); - gstEncoder = QGstElement("encodebin", "encodebin"); auto *encodingProfile = createEncodingProfile(settings); g_object_set (gstEncoder.object(), "profile", encodingProfile, nullptr); @@ -305,30 +311,33 @@ void QGstreamerMediaEncoder::record(QMediaEncoderSettings &settings) gstFileSink = QGstElement("filesink", "filesink"); gstFileSink.set("location", QFile::encodeName(actualSink.toLocalFile()).constData()); + gstFileSink.set("async", false); - gstPipeline.add(gstEncoder, gstFileSink); - gstEncoder.link(gstFileSink); - - gstEncoder.setState(GST_STATE_PAUSED); - gstFileSink.setState(GST_STATE_PAUSED); + QGstPad audioSink = {}; + QGstPad videoSink = {}; - audioSrcPad = m_session->getAudioPad(); - if (!audioSrcPad.isNull()) { - QGstPad audioPad = gstEncoder.getRequestPad("audio_%u"); - audioPauseControl.installOn(audioPad); - audioSrcPad.link(audioPad); + if (hasAudio) { + audioSink = gstEncoder.getRequestPad("audio_%u"); + if (audioSink.isNull()) + qWarning() << "Unsupported audio codec"; + else + audioPauseControl.installOn(audioSink); } - if (settings.videoCodec() != QMediaFormat::VideoCodec::Unspecified) { - videoSrcPad = m_session->getVideoPad(); - if (!videoSrcPad.isNull()) { - QGstPad videoPad = gstEncoder.getRequestPad("video_%u"); - videoPauseControl.installOn(videoPad); - videoSrcPad.link(videoPad); - } + if (hasVideo) { + videoSink = gstEncoder.getRequestPad("video_%u"); + if (videoSink.isNull()) + qWarning() << "Unsupported video codec"; + else + videoPauseControl.installOn(videoSink); } - gstPipeline.endConfig(); + gstPipeline.add(gstEncoder, gstFileSink); + gstEncoder.link(gstFileSink); + m_session->linkEncoder(audioSink, videoSink); + + gstEncoder.syncStateWithParent(); + gstFileSink.syncStateWithParent(); m_duration.start(); heartbeat.start(); @@ -344,8 +353,6 @@ void QGstreamerMediaEncoder::pause() return; heartbeat.stop(); gstPipeline.dumpGraph("before-pause"); - gstEncoder.setState(GST_STATE_PAUSED); - stateChanged(QMediaRecorder::PausedState); } @@ -355,7 +362,6 @@ void QGstreamerMediaEncoder::resume() if (!m_session || state() != QMediaRecorder::PausedState) return; heartbeat.start(); - gstEncoder.setState(GST_STATE_PLAYING); stateChanged(QMediaRecorder::RecordingState); } @@ -365,46 +371,29 @@ void QGstreamerMediaEncoder::stop() return; qCDebug(qLcMediaEncoder) << "stop"; - gstPipeline.beginConfig(); - - if (!audioSrcPad.isNull()) { - audioSrcPad.unlinkPeer(); - m_session->releaseAudioPad(audioSrcPad); - audioSrcPad = {}; - } - if (!videoSrcPad.isNull()) { - videoSrcPad.unlinkPeer(); - m_session->releaseVideoPad(videoSrcPad); - videoSrcPad = {}; - } - - gstPipeline.endConfig(); + m_session->unlinkEncoder(); //with live sources it's necessary to send EOS even to pipeline //before going to STOPPED state qCDebug(qLcMediaEncoder) << ">>>>>>>>>>>>> sending EOS"; - gstEncoder.sendEos(); - stateChanged(QMediaRecorder::StoppedState); } void QGstreamerMediaEncoder::finalize() { if (!m_session || gstEncoder.isNull()) return; - qCDebug(qLcMediaEncoder) << "finalize"; + qCDebug(qLcMediaEncoder) << "finalize"; heartbeat.stop(); - // The filesink can only be used once, replace it with a new one - gstPipeline.beginConfig(); gstEncoder.setState(GST_STATE_NULL); gstFileSink.setState(GST_STATE_NULL); gstPipeline.remove(gstEncoder); gstPipeline.remove(gstFileSink); gstFileSink = {}; gstEncoder = {}; - gstPipeline.endConfig(); + stateChanged(QMediaRecorder::StoppedState); } void QGstreamerMediaEncoder::setMetaData(const QMediaMetaData &metaData) |