summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLev Zelenskiy <lev.zelenskiy@nokia.com>2012-02-15 14:45:18 +1000
committerQt by Nokia <qt-info@nokia.com>2012-02-16 07:18:27 +0100
commit16aef591875becad3e6f388af0a2f029cb68b775 (patch)
tree45af5b903258966e89aa44449c33705fffbd3c3c
parent0374f0de5ec881569e463505b232b3870c0fd9d2 (diff)
QMediaRecorder: GStreamer backend changes for media probing API.
QGstreamerCaptureSession: Using GStreamer buffer probe to access media data. Change-Id: I2ee38e864fbd69fcba9efe90d4dcf138528e00c0 Reviewed-by: Michael Goddard <michael.goddard@nokia.com>
-rw-r--r--src/plugins/gstreamer/mediacapture/qgstreamercaptureservice.cpp18
-rw-r--r--src/plugins/gstreamer/mediacapture/qgstreamercapturesession.cpp81
-rw-r--r--src/plugins/gstreamer/mediacapture/qgstreamercapturesession.h14
3 files changed, 113 insertions, 0 deletions
diff --git a/src/plugins/gstreamer/mediacapture/qgstreamercaptureservice.cpp b/src/plugins/gstreamer/mediacapture/qgstreamercaptureservice.cpp
index 95b4444f..405cc577 100644
--- a/src/plugins/gstreamer/mediacapture/qgstreamercaptureservice.cpp
+++ b/src/plugins/gstreamer/mediacapture/qgstreamercaptureservice.cpp
@@ -54,6 +54,7 @@
#include "qgstreameraudioinputendpointselector.h"
#include "qgstreamervideoinputdevicecontrol.h"
#include "qgstreamerimagecapturecontrol.h"
+#include "qgstreameraudioprobecontrol.h"
#include "qgstreamervideorenderer.h"
@@ -162,6 +163,15 @@ QMediaControl *QGstreamerCaptureService::requestControl(const char *name)
if (qstrcmp(name, QCameraImageCaptureControl_iid) == 0)
return m_imageCaptureControl;
+ if (qstrcmp(name,QMediaAudioProbeControl_iid) == 0) {
+ if (m_captureSession) {
+ QGstreamerAudioProbeControl *probe = new QGstreamerAudioProbeControl(this);
+ m_captureSession->addProbe(probe);
+ return probe;
+ }
+ return 0;
+ }
+
if (!m_videoOutput) {
if (qstrcmp(name, QVideoRendererControl_iid) == 0) {
m_videoOutput = m_videoRenderer;
@@ -189,6 +199,14 @@ void QGstreamerCaptureService::releaseControl(QMediaControl *control)
m_videoOutput = 0;
m_captureSession->setVideoPreview(0);
}
+
+ QGstreamerAudioProbeControl* audioProbe = qobject_cast<QGstreamerAudioProbeControl*>(control);
+ if (audioProbe) {
+ if (m_captureSession)
+ m_captureSession->removeProbe(audioProbe);
+ delete audioProbe;
+ return;
+ }
}
QT_END_NAMESPACE
diff --git a/src/plugins/gstreamer/mediacapture/qgstreamercapturesession.cpp b/src/plugins/gstreamer/mediacapture/qgstreamercapturesession.cpp
index 68f4444c..60cda07b 100644
--- a/src/plugins/gstreamer/mediacapture/qgstreamercapturesession.cpp
+++ b/src/plugins/gstreamer/mediacapture/qgstreamercapturesession.cpp
@@ -46,6 +46,7 @@
#include "qgstreameraudioencode.h"
#include "qgstreamervideoencode.h"
#include "qgstreamerimageencode.h"
+#include "qgstreameraudioprobecontrol.h"
#include <qmediarecorder.h>
#include <private/qgstreamerbushelper_p.h>
@@ -73,6 +74,7 @@ QGstreamerCaptureSession::QGstreamerCaptureSession(QGstreamerCaptureSession::Cap
m_waitingForEos(false),
m_pipelineMode(EmptyPipeline),
m_captureMode(captureMode),
+ m_audioBufferProbeId(-1),
m_audioInputFactory(0),
m_audioPreviewFactory(0),
m_videoInputFactory(0),
@@ -530,6 +532,7 @@ void QGstreamerCaptureSession::captureImage(int requestId, const QString &fileNa
bool QGstreamerCaptureSession::rebuildGraph(QGstreamerCaptureSession::PipelineMode newMode)
{
+ removeAudioBufferProbe();
REMOVE_ELEMENT(m_audioSrc);
REMOVE_ELEMENT(m_audioPreview);
REMOVE_ELEMENT(m_audioPreviewQueue);
@@ -669,6 +672,7 @@ bool QGstreamerCaptureSession::rebuildGraph(QGstreamerCaptureSession::PipelineMo
}
if (ok) {
+ addAudioBufferProbe();
m_pipelineMode = newMode;
} else {
m_pipelineMode = EmptyPipeline;
@@ -1024,4 +1028,81 @@ void QGstreamerCaptureSession::setMuted(bool muted)
}
}
+void QGstreamerCaptureSession::addProbe(QGstreamerAudioProbeControl* probe)
+{
+ QMutexLocker locker(&m_audioProbeMutex);
+
+ if (m_audioProbes.contains(probe))
+ return;
+
+ m_audioProbes.append(probe);
+}
+
+void QGstreamerCaptureSession::removeProbe(QGstreamerAudioProbeControl* probe)
+{
+ QMutexLocker locker(&m_audioProbeMutex);
+ m_audioProbes.removeOne(probe);
+}
+
+gboolean QGstreamerCaptureSession::padAudioBufferProbe(GstPad *pad, GstBuffer *buffer, gpointer user_data)
+{
+ Q_UNUSED(pad);
+
+ QGstreamerCaptureSession *session = reinterpret_cast<QGstreamerCaptureSession*>(user_data);
+ QMutexLocker locker(&session->m_audioProbeMutex);
+
+ if (session->m_audioProbes.isEmpty())
+ return TRUE;
+
+ foreach (QGstreamerAudioProbeControl* probe, session->m_audioProbes)
+ probe->bufferProbed(buffer);
+
+ return TRUE;
+}
+
+GstPad *QGstreamerCaptureSession::getAudioProbePad()
+{
+ // first see if preview element is available
+ if (m_audioPreview) {
+ GstPad *pad = gst_element_get_static_pad(m_audioPreview, "sink");
+ if (pad)
+ return pad;
+ }
+
+ // preview element is not available,
+ // try to use sink pin of audio encoder.
+ if (m_encodeBin) {
+ GstElement *audioEncoder = gst_bin_get_by_name(GST_BIN(m_encodeBin), "audio-encoder-bin");
+ if (audioEncoder) {
+ GstPad *pad = gst_element_get_static_pad(audioEncoder, "sink");
+ gst_object_unref(audioEncoder);
+ if (pad)
+ return pad;
+ }
+ }
+
+ return 0;
+}
+
+void QGstreamerCaptureSession::removeAudioBufferProbe()
+{
+ if (m_audioBufferProbeId == -1)
+ return;
+
+ GstPad *pad = getAudioProbePad();
+ if (pad)
+ gst_pad_remove_buffer_probe(pad, m_audioBufferProbeId);
+
+ m_audioBufferProbeId = -1;
+}
+
+void QGstreamerCaptureSession::addAudioBufferProbe()
+{
+ Q_ASSERT(m_audioBufferProbeId == -1);
+
+ GstPad *pad = getAudioProbePad();
+ if (pad)
+ m_audioBufferProbeId = gst_pad_add_buffer_probe(pad, G_CALLBACK(padAudioBufferProbe), this);
+}
+
QT_END_NAMESPACE
diff --git a/src/plugins/gstreamer/mediacapture/qgstreamercapturesession.h b/src/plugins/gstreamer/mediacapture/qgstreamercapturesession.h
index 2c2fd025..cb03b173 100644
--- a/src/plugins/gstreamer/mediacapture/qgstreamercapturesession.h
+++ b/src/plugins/gstreamer/mediacapture/qgstreamercapturesession.h
@@ -45,6 +45,7 @@
#include <qmediarecordercontrol.h>
#include <qmediarecorder.h>
+#include <QtCore/qmutex.h>
#include <QtCore/qurl.h>
#include <gst/gst.h>
@@ -61,6 +62,7 @@ class QGstreamerImageEncode;
class QGstreamerRecorderControl;
class QGstreamerMediaContainerControl;
class QGstreamerVideoRendererInterface;
+class QGstreamerAudioProbeControl;
class QGstreamerElementFactory
{
@@ -127,6 +129,10 @@ public:
bool processBusMessage(const QGstreamerMessage &message);
+ void addProbe(QGstreamerAudioProbeControl* probe);
+ void removeProbe(QGstreamerAudioProbeControl* probe);
+ static gboolean padAudioBufferProbe(GstPad *pad, GstBuffer *buffer, gpointer user_data);
+
signals:
void stateChanged(QGstreamerCaptureSession::State state);
void durationChanged(qint64 duration);
@@ -160,6 +166,10 @@ private:
void waitForStopped();
bool rebuildGraph(QGstreamerCaptureSession::PipelineMode newMode);
+ GstPad *getAudioProbePad();
+ void removeAudioBufferProbe();
+ void addAudioBufferProbe();
+
QUrl m_sink;
QString m_captureDevice;
State m_state;
@@ -169,6 +179,10 @@ private:
QGstreamerCaptureSession::CaptureMode m_captureMode;
QMap<QByteArray, QVariant> m_metaData;
+ QList<QGstreamerAudioProbeControl*> m_audioProbes;
+ QMutex m_audioProbeMutex;
+ int m_audioBufferProbeId;
+
QGstreamerElementFactory *m_audioInputFactory;
QGstreamerElementFactory *m_audioPreviewFactory;
QGstreamerVideoInput *m_videoInputFactory;