summaryrefslogtreecommitdiffstats
path: root/src/plugins/gstreamer/mediacapture
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/gstreamer/mediacapture')
-rw-r--r--src/plugins/gstreamer/mediacapture/mediacapturecamera.json2
-rw-r--r--src/plugins/gstreamer/mediacapture/qgstreameraudioencode.cpp3
-rw-r--r--src/plugins/gstreamer/mediacapture/qgstreamercaptureservice.cpp58
-rw-r--r--src/plugins/gstreamer/mediacapture/qgstreamercaptureservice.h3
-rw-r--r--src/plugins/gstreamer/mediacapture/qgstreamercaptureserviceplugin.cpp90
-rw-r--r--src/plugins/gstreamer/mediacapture/qgstreamercapturesession.cpp285
-rw-r--r--src/plugins/gstreamer/mediacapture/qgstreamercapturesession.h19
-rw-r--r--src/plugins/gstreamer/mediacapture/qgstreamervideoencode.cpp39
8 files changed, 157 insertions, 342 deletions
diff --git a/src/plugins/gstreamer/mediacapture/mediacapturecamera.json b/src/plugins/gstreamer/mediacapture/mediacapturecamera.json
index af9f3575f..f5fba17e6 100644
--- a/src/plugins/gstreamer/mediacapture/mediacapturecamera.json
+++ b/src/plugins/gstreamer/mediacapture/mediacapturecamera.json
@@ -1,4 +1,4 @@
{
- "Keys": ["gstreamermediacapture"]
+ "Keys": ["gstreamermediacapture"],
"Services": ["org.qt-project.qt.audiosource", "org.qt-project.qt.camera"]
}
diff --git a/src/plugins/gstreamer/mediacapture/qgstreameraudioencode.cpp b/src/plugins/gstreamer/mediacapture/qgstreameraudioencode.cpp
index d05df4997..8881445f8 100644
--- a/src/plugins/gstreamer/mediacapture/qgstreameraudioencode.cpp
+++ b/src/plugins/gstreamer/mediacapture/qgstreameraudioencode.cpp
@@ -34,6 +34,7 @@
#include "qgstreameraudioencode.h"
#include "qgstreamercapturesession.h"
#include "qgstreamermediacontainercontrol.h"
+#include <private/qgstutils_p.h>
#include <QtCore/qdebug.h>
@@ -175,7 +176,7 @@ GstElement *QGstreamerAudioEncode::createEncoder()
if (m_audioSettings.sampleRate() > 0 || m_audioSettings.channelCount() > 0) {
GstCaps *caps = gst_caps_new_empty();
- GstStructure *structure = gst_structure_new("audio/x-raw-int", NULL);
+ GstStructure *structure = qt_gst_structure_new_empty(QT_GSTREAMER_RAW_AUDIO_MIME);
if (m_audioSettings.sampleRate() > 0)
gst_structure_set(structure, "rate", G_TYPE_INT, m_audioSettings.sampleRate(), NULL );
diff --git a/src/plugins/gstreamer/mediacapture/qgstreamercaptureservice.cpp b/src/plugins/gstreamer/mediacapture/qgstreamercaptureservice.cpp
index 97a165dca..1ab98cd4a 100644
--- a/src/plugins/gstreamer/mediacapture/qgstreamercaptureservice.cpp
+++ b/src/plugins/gstreamer/mediacapture/qgstreamercaptureservice.cpp
@@ -62,27 +62,25 @@
QT_BEGIN_NAMESPACE
-QGstreamerCaptureService::QGstreamerCaptureService(const QString &service, QObject *parent):
- QMediaService(parent)
-{
- m_captureSession = 0;
- m_cameraControl = 0;
- m_metaDataControl = 0;
-
+QGstreamerCaptureService::QGstreamerCaptureService(const QString &service, QObject *parent)
+ : QMediaService(parent)
+ , m_captureSession(0)
+ , m_cameraControl(0)
#if defined(USE_GSTREAMER_CAMERA)
- m_videoInput = 0;
+ , m_videoInput(0)
#endif
- m_audioInputSelector = 0;
- m_videoInputDevice = 0;
-
- m_videoOutput = 0;
- m_videoRenderer = 0;
- m_videoWindow = 0;
+ , m_metaDataControl(0)
+ , m_audioInputSelector(0)
+ , m_videoInputDevice(0)
+ , m_videoOutput(0)
+ , m_videoRenderer(0)
+ , m_videoWindow(0)
#if defined(HAVE_WIDGETS)
- m_videoWidgetControl = 0;
+ , m_videoWidgetControl(0)
#endif
- m_imageCaptureControl = 0;
-
+ , m_imageCaptureControl(0)
+ , m_audioProbeControl(0)
+{
if (service == Q_MEDIASERVICE_AUDIOSOURCE) {
m_captureSession = new QGstreamerCaptureSession(QGstreamerCaptureSession::Audio, this);
}
@@ -163,12 +161,12 @@ QMediaControl *QGstreamerCaptureService::requestControl(const char *name)
return m_imageCaptureControl;
if (qstrcmp(name,QMediaAudioProbeControl_iid) == 0) {
- if (m_captureSession) {
- QGstreamerAudioProbeControl *probe = new QGstreamerAudioProbeControl(this);
- m_captureSession->addProbe(probe);
- return probe;
+ if (!m_audioProbeControl) {
+ m_audioProbeControl = new QGstreamerAudioProbeControl(this);
+ m_captureSession->addProbe(m_audioProbeControl);
}
- return 0;
+ m_audioProbeControl->ref.ref();
+ return m_audioProbeControl;
}
if (!m_videoOutput) {
@@ -194,17 +192,15 @@ QMediaControl *QGstreamerCaptureService::requestControl(const char *name)
void QGstreamerCaptureService::releaseControl(QMediaControl *control)
{
- if (control && control == m_videoOutput) {
+ if (!control) {
+ return;
+ } else if (control == m_videoOutput) {
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;
+ } else if (control == m_audioProbeControl && !m_audioProbeControl->ref.deref()) {
+ m_captureSession->removeProbe(m_audioProbeControl);
+ delete m_audioProbeControl;
+ m_audioProbeControl = 0;
}
}
diff --git a/src/plugins/gstreamer/mediacapture/qgstreamercaptureservice.h b/src/plugins/gstreamer/mediacapture/qgstreamercaptureservice.h
index 7ff8ce253..e0cf4ee42 100644
--- a/src/plugins/gstreamer/mediacapture/qgstreamercaptureservice.h
+++ b/src/plugins/gstreamer/mediacapture/qgstreamercaptureservice.h
@@ -43,6 +43,7 @@ QT_BEGIN_NAMESPACE
class QAudioInputSelectorControl;
class QVideoDeviceSelectorControl;
+class QGstreamerAudioProbeControl;
class QGstreamerCaptureSession;
class QGstreamerCameraControl;
class QGstreamerMessage;
@@ -86,6 +87,8 @@ private:
QMediaControl *m_videoWidgetControl;
#endif
QGstreamerImageCaptureControl *m_imageCaptureControl;
+
+ QGstreamerAudioProbeControl *m_audioProbeControl;
};
QT_END_NAMESPACE
diff --git a/src/plugins/gstreamer/mediacapture/qgstreamercaptureserviceplugin.cpp b/src/plugins/gstreamer/mediacapture/qgstreamercaptureserviceplugin.cpp
index 0ac34ee72..85ed687d3 100644
--- a/src/plugins/gstreamer/mediacapture/qgstreamercaptureserviceplugin.cpp
+++ b/src/plugins/gstreamer/mediacapture/qgstreamercaptureserviceplugin.cpp
@@ -110,90 +110,16 @@ QMultimedia::SupportEstimate QGstreamerCaptureServicePlugin::hasSupport(const QS
return QGstUtils::hasSupport(mimeType, codecs, m_supportedMimeTypeSet);
}
+
+static bool isEncoderOrMuxer(GstElementFactory *factory)
+{
+ return gst_element_factory_list_is_type(factory, GST_ELEMENT_FACTORY_TYPE_MUXER)
+ || gst_element_factory_list_is_type(factory, GST_ELEMENT_FACTORY_TYPE_ENCODER);
+}
+
void QGstreamerCaptureServicePlugin::updateSupportedMimeTypes() const
{
- //enumerate supported mime types
- gst_init(NULL, NULL);
-
- GList *plugins, *orig_plugins;
- orig_plugins = plugins = gst_default_registry_get_plugin_list ();
-
- while (plugins) {
- GList *features, *orig_features;
-
- GstPlugin *plugin = (GstPlugin *) (plugins->data);
- plugins = g_list_next (plugins);
-
- if (plugin->flags & (1<<1)) //GST_PLUGIN_FLAG_BLACKLISTED
- continue;
-
- orig_features = features = gst_registry_get_feature_list_by_plugin(gst_registry_get_default (),
- plugin->desc.name);
- while (features) {
- if (!G_UNLIKELY(features->data == NULL)) {
- GstPluginFeature *feature = GST_PLUGIN_FEATURE(features->data);
- if (GST_IS_ELEMENT_FACTORY (feature)) {
- GstElementFactory *factory = GST_ELEMENT_FACTORY(gst_plugin_feature_load(feature));
- if (factory
- && factory->numpadtemplates > 0
- && (qstrcmp(factory->details.klass, "Codec/Decoder/Audio") == 0
- || qstrcmp(factory->details.klass, "Codec/Decoder/Video") == 0
- || qstrcmp(factory->details.klass, "Codec/Demux") == 0 )) {
- const GList *pads = factory->staticpadtemplates;
- while (pads) {
- GstStaticPadTemplate *padtemplate = (GstStaticPadTemplate*)(pads->data);
- pads = g_list_next (pads);
- if (padtemplate->direction != GST_PAD_SINK)
- continue;
- if (padtemplate->static_caps.string) {
- GstCaps *caps = gst_static_caps_get(&padtemplate->static_caps);
- if (!gst_caps_is_any (caps) && ! gst_caps_is_empty (caps)) {
- for (guint i = 0; i < gst_caps_get_size(caps); i++) {
- GstStructure *structure = gst_caps_get_structure(caps, i);
- QString nameLowcase = QString(gst_structure_get_name (structure)).toLower();
-
- m_supportedMimeTypeSet.insert(nameLowcase);
- if (nameLowcase.contains("mpeg")) {
- //Because mpeg version number is only included in the detail
- //description, it is necessary to manually extract this information
- //in order to match the mime type of mpeg4.
- const GValue *value = gst_structure_get_value(structure, "mpegversion");
- if (value) {
- gchar *str = gst_value_serialize (value);
- QString versions(str);
- QStringList elements = versions.split(QRegExp("\\D+"), QString::SkipEmptyParts);
- foreach (const QString &e, elements)
- m_supportedMimeTypeSet.insert(nameLowcase + e);
- g_free (str);
- }
- }
- }
- }
- gst_caps_unref(caps);
- }
- }
- gst_object_unref (factory);
- }
- } else if (GST_IS_TYPE_FIND_FACTORY(feature)) {
- QString name(gst_plugin_feature_get_name(feature));
- if (name.contains('/')) //filter out any string without '/' which is obviously not a mime type
- m_supportedMimeTypeSet.insert(name.toLower());
- }
- }
- features = g_list_next (features);
- }
- gst_plugin_feature_list_free (orig_features);
- }
- gst_plugin_list_free (orig_plugins);
-
-#if defined QT_SUPPORTEDMIMETYPES_DEBUG
- QStringList list = m_supportedMimeTypeSet.toList();
- list.sort();
- if (qgetenv("QT_DEBUG_PLUGINS").toInt() > 0) {
- foreach (const QString &type, list)
- qDebug() << type;
- }
-#endif
+ m_supportedMimeTypeSet = QGstUtils::supportedMimeTypes(isEncoderOrMuxer);
}
QStringList QGstreamerCaptureServicePlugin::supportedMimeTypes() const
diff --git a/src/plugins/gstreamer/mediacapture/qgstreamercapturesession.cpp b/src/plugins/gstreamer/mediacapture/qgstreamercapturesession.cpp
index a2bd80de8..af5b339e5 100644
--- a/src/plugins/gstreamer/mediacapture/qgstreamercapturesession.cpp
+++ b/src/plugins/gstreamer/mediacapture/qgstreamercapturesession.cpp
@@ -45,6 +45,7 @@
#include <gst/gsttagsetter.h>
#include <gst/gstversion.h>
+#include <gst/video/video.h>
#include <QtCore/qdebug.h>
#include <QtCore/qurl.h>
@@ -52,7 +53,6 @@
#include <QCoreApplication>
#include <QtCore/qmetaobject.h>
#include <QtCore/qfile.h>
-
#include <QtGui/qimage.h>
QT_BEGIN_NAMESPACE
@@ -64,7 +64,7 @@ QGstreamerCaptureSession::QGstreamerCaptureSession(QGstreamerCaptureSession::Cap
m_waitingForEos(false),
m_pipelineMode(EmptyPipeline),
m_captureMode(captureMode),
- m_audioBufferProbeId(-1),
+ m_audioProbe(0),
m_audioInputFactory(0),
m_audioPreviewFactory(0),
m_videoInputFactory(0),
@@ -169,7 +169,7 @@ GstElement *QGstreamerCaptureSession::buildEncodeBin()
if (m_captureMode & Video) {
GstElement *videoQueue = gst_element_factory_make("queue", "video-encode-queue");
- GstElement *colorspace = gst_element_factory_make("ffmpegcolorspace", "ffmpegcolorspace-encoder");
+ GstElement *colorspace = gst_element_factory_make(QT_GSTREAMER_COLORCONVERSION_ELEMENT_NAME, "videoconvert-encoder");
GstElement *videoscale = gst_element_factory_make("videoscale","videoscale-encoder");
gst_bin_add_many(GST_BIN(encodeBin), videoQueue, colorspace, videoscale, NULL);
@@ -280,7 +280,7 @@ GstElement *QGstreamerCaptureSession::buildVideoPreview()
if (m_viewfinderInterface) {
GstElement *bin = gst_bin_new("video-preview-bin");
- GstElement *colorspace = gst_element_factory_make("ffmpegcolorspace", "ffmpegcolorspace-preview");
+ GstElement *colorspace = gst_element_factory_make(QT_GSTREAMER_COLORCONVERSION_ELEMENT_NAME, "videoconvert-preview");
GstElement *capsFilter = gst_element_factory_make("capsfilter", "capsfilter-video-preview");
GstElement *preview = m_viewfinderInterface->videoSink();
@@ -299,36 +299,25 @@ GstElement *QGstreamerCaptureSession::buildVideoPreview()
resolution = m_imageEncodeControl->imageSettings().resolution();
}
- if (!resolution.isEmpty() || frameRate > 0.001) {
- GstCaps *caps = gst_caps_new_empty();
- QStringList structureTypes;
- structureTypes << "video/x-raw-yuv" << "video/x-raw-rgb";
-
- foreach(const QString &structureType, structureTypes) {
- GstStructure *structure = gst_structure_new(structureType.toLatin1().constData(), NULL);
-
- if (!resolution.isEmpty()) {
- gst_structure_set(structure, "width", G_TYPE_INT, resolution.width(), NULL);
- gst_structure_set(structure, "height", G_TYPE_INT, resolution.height(), NULL);
- }
-
- if (frameRate > 0.001) {
- QPair<int,int> rate = m_videoEncodeControl->rateAsRational();
+ GstCaps *caps = QGstUtils::videoFilterCaps();
- //qDebug() << "frame rate:" << num << denum;
+ if (!resolution.isEmpty()) {
+ gst_caps_set_simple(caps, "width", G_TYPE_INT, resolution.width(), NULL);
+ gst_caps_set_simple(caps, "height", G_TYPE_INT, resolution.height(), NULL);
+ }
+ if (frameRate > 0.001) {
+ QPair<int,int> rate = m_videoEncodeControl->rateAsRational();
- gst_structure_set(structure, "framerate", GST_TYPE_FRACTION, rate.first, rate.second, NULL);
- }
+ //qDebug() << "frame rate:" << num << denum;
- gst_caps_append_structure(caps,structure);
- }
+ gst_caps_set_simple(caps, "framerate", GST_TYPE_FRACTION, rate.first, rate.second, NULL);
+ }
- //qDebug() << "set video preview caps filter:" << gst_caps_to_string(caps);
+ //qDebug() << "set video preview caps filter:" << gst_caps_to_string(caps);
- g_object_set(G_OBJECT(capsFilter), "caps", caps, NULL);
+ g_object_set(G_OBJECT(capsFilter), "caps", caps, NULL);
- gst_caps_unref(caps);
- }
+ gst_caps_unref(caps);
// add ghostpads
GstPad *pad = gst_element_get_static_pad(colorspace, "sink");
@@ -342,7 +331,7 @@ GstElement *QGstreamerCaptureSession::buildVideoPreview()
previewElement = gst_element_factory_make("fakesink", "video-preview");
#else
GstElement *bin = gst_bin_new("video-preview-bin");
- GstElement *colorspace = gst_element_factory_make("ffmpegcolorspace", "ffmpegcolorspace-preview");
+ GstElement *colorspace = gst_element_factory_make(QT_GSTREAMER_COLORCONVERSION_ELEMENT_NAME, "videoconvert-preview");
GstElement *preview = gst_element_factory_make("ximagesink", "video-preview");
gst_bin_add_many(GST_BIN(bin), colorspace, preview, NULL);
gst_element_link(colorspace,preview);
@@ -360,101 +349,49 @@ GstElement *QGstreamerCaptureSession::buildVideoPreview()
return previewElement;
}
-
-static gboolean passImageFilter(GstElement *element,
- GstBuffer *buffer,
- void *appdata)
+void QGstreamerCaptureSession::probeCaps(GstCaps *caps)
{
- Q_UNUSED(element);
- Q_UNUSED(buffer);
-
- QGstreamerCaptureSession *session = (QGstreamerCaptureSession *)appdata;
- if (session->m_passImage || session->m_passPrerollImage) {
- session->m_passImage = false;
-
- if (session->m_passPrerollImage) {
- session->m_passPrerollImage = false;
- return TRUE;
- }
- session->m_passPrerollImage = false;
-
- QImage img;
-
- GstCaps *caps = gst_buffer_get_caps(buffer);
- if (caps) {
- GstStructure *structure = gst_caps_get_structure (caps, 0);
- gint width = 0;
- gint height = 0;
-
- if (structure &&
- gst_structure_get_int(structure, "width", &width) &&
- gst_structure_get_int(structure, "height", &height) &&
- width > 0 && height > 0) {
- if (qstrcmp(gst_structure_get_name(structure), "video/x-raw-yuv") == 0) {
- guint32 fourcc = 0;
- gst_structure_get_fourcc(structure, "format", &fourcc);
-
- if (fourcc == GST_MAKE_FOURCC('I','4','2','0')) {
- img = QImage(width/2, height/2, QImage::Format_RGB32);
-
- const uchar *data = (const uchar *)buffer->data;
+#if GST_CHECK_VERSION(1,0,0)
+ gst_video_info_from_caps(&m_previewInfo, caps);
+#else
+ Q_UNUSED(caps);
+#endif
+}
- for (int y=0; y<height; y+=2) {
- const uchar *yLine = data + y*width;
- const uchar *uLine = data + width*height + y*width/4;
- const uchar *vLine = data + width*height*5/4 + y*width/4;
+bool QGstreamerCaptureSession::probeBuffer(GstBuffer *buffer)
+{
+ if (m_passPrerollImage) {
+ m_passImage = false;
+ m_passPrerollImage = false;
- for (int x=0; x<width; x+=2) {
- const qreal Y = 1.164*(yLine[x]-16);
- const int U = uLine[x/2]-128;
- const int V = vLine[x/2]-128;
+ return true;
+ } else if (!m_passImage) {
+ return false;
+ }
- int b = qBound(0, int(Y + 2.018*U), 255);
- int g = qBound(0, int(Y - 0.813*V - 0.391*U), 255);
- int r = qBound(0, int(Y + 1.596*V), 255);
+ m_passImage = false;
- img.setPixel(x/2,y/2,qRgb(r,g,b));
- }
- }
- }
+#if GST_CHECK_VERSION(1,0,0)
+ QImage img = QGstUtils::bufferToImage(buffer, m_previewInfo);
+#else
+ QImage img = QGstUtils::bufferToImage(buffer);
+#endif
- } else if (qstrcmp(gst_structure_get_name(structure), "video/x-raw-rgb") == 0) {
- QImage::Format format = QImage::Format_Invalid;
- int bpp = 0;
- gst_structure_get_int(structure, "bpp", &bpp);
-
- if (bpp == 24)
- format = QImage::Format_RGB888;
- else if (bpp == 32)
- format = QImage::Format_RGB32;
-
- if (format != QImage::Format_Invalid) {
- img = QImage((const uchar *)buffer->data,
- width,
- height,
- format);
- img.bits(); //detach
- }
- }
- }
- gst_caps_unref(caps);
- }
+ if (img.isNull())
+ return true;
- static QMetaMethod exposedSignal = QMetaMethod::fromSignal(&QGstreamerCaptureSession::imageExposed);
- exposedSignal.invoke(session,
- Qt::QueuedConnection,
- Q_ARG(int,session->m_imageRequestId));
+ static QMetaMethod exposedSignal = QMetaMethod::fromSignal(&QGstreamerCaptureSession::imageExposed);
+ exposedSignal.invoke(this,
+ Qt::QueuedConnection,
+ Q_ARG(int,m_imageRequestId));
- static QMetaMethod capturedSignal = QMetaMethod::fromSignal(&QGstreamerCaptureSession::imageCaptured);
- capturedSignal.invoke(session,
- Qt::QueuedConnection,
- Q_ARG(int,session->m_imageRequestId),
- Q_ARG(QImage,img));
+ static QMetaMethod capturedSignal = QMetaMethod::fromSignal(&QGstreamerCaptureSession::imageCaptured);
+ capturedSignal.invoke(this,
+ Qt::QueuedConnection,
+ Q_ARG(int,m_imageRequestId),
+ Q_ARG(QImage,img));
- return TRUE;
- } else {
- return FALSE;
- }
+ return true;
}
static gboolean saveImageFilter(GstElement *element,
@@ -471,7 +408,15 @@ static gboolean saveImageFilter(GstElement *element,
if (!fileName.isEmpty()) {
QFile f(fileName);
if (f.open(QFile::WriteOnly)) {
- f.write((const char *)buffer->data, buffer->size);
+#if GST_CHECK_VERSION(1,0,0)
+ GstMapInfo info;
+ if (gst_buffer_map(buffer, &info, GST_MAP_READ)) {
+ f.write(reinterpret_cast<const char *>(info.data), info.size);
+ gst_buffer_unmap(buffer, &info);
+ }
+#else
+ f.write(reinterpret_cast<const char *>(buffer->data), buffer->size);
+#endif
f.close();
static QMetaMethod savedSignal = QMetaMethod::fromSignal(&QGstreamerCaptureSession::imageSaved);
@@ -489,18 +434,19 @@ GstElement *QGstreamerCaptureSession::buildImageCapture()
{
GstElement *bin = gst_bin_new("image-capture-bin");
GstElement *queue = gst_element_factory_make("queue", "queue-image-capture");
- GstElement *colorspace = gst_element_factory_make("ffmpegcolorspace", "ffmpegcolorspace-image-capture");
+ GstElement *colorspace = gst_element_factory_make(QT_GSTREAMER_COLORCONVERSION_ELEMENT_NAME, "videoconvert-image-capture");
GstElement *encoder = gst_element_factory_make("jpegenc", "image-encoder");
GstElement *sink = gst_element_factory_make("fakesink","sink-image-capture");
GstPad *pad = gst_element_get_static_pad(queue, "src");
Q_ASSERT(pad);
- gst_pad_add_buffer_probe(pad, G_CALLBACK(passImageFilter), this);
+
+ addProbeToPad(pad, false);
+
gst_object_unref(GST_OBJECT(pad));
g_object_set(G_OBJECT(sink), "signal-handoffs", TRUE, NULL);
- g_signal_connect(G_OBJECT(sink), "handoff",
- G_CALLBACK(saveImageFilter), this);
+ g_signal_connect(G_OBJECT(sink), "handoff", G_CALLBACK(saveImageFilter), this);
gst_bin_add_many(GST_BIN(bin), queue, colorspace, encoder, sink, NULL);
gst_element_link_many(queue, colorspace, encoder, sink, NULL);
@@ -715,6 +661,8 @@ void QGstreamerCaptureSession::dumpGraph(const QString &fileName)
_gst_debug_bin_to_dot_file(GST_BIN(m_pipeline),
GstDebugGraphDetails(/*GST_DEBUG_GRAPH_SHOW_ALL |*/ GST_DEBUG_GRAPH_SHOW_MEDIA_TYPE | GST_DEBUG_GRAPH_SHOW_NON_DEFAULT_PARAMS | GST_DEBUG_GRAPH_SHOW_STATES),
fileName.toLatin1());
+#else
+ Q_UNUSED(fileName);
#endif
}
@@ -877,10 +825,8 @@ void QGstreamerCaptureSession::setState(QGstreamerCaptureSession::State newState
qint64 QGstreamerCaptureSession::duration() const
{
- GstFormat format = GST_FORMAT_TIME;
- gint64 duration = 0;
-
- if ( m_encodeBin && gst_element_query_position(m_encodeBin, &format, &duration))
+ gint64 duration = 0;
+ if (m_encodeBin && qt_gst_element_query_position(m_encodeBin, GST_FORMAT_TIME, &duration))
return duration / 1000000;
else
return 0;
@@ -896,50 +842,8 @@ void QGstreamerCaptureSession::setMetaData(const QMap<QByteArray, QVariant> &dat
//qDebug() << "QGstreamerCaptureSession::setMetaData" << data;
m_metaData = data;
- if (m_encodeBin) {
- GstIterator *elements = gst_bin_iterate_all_by_interface(GST_BIN(m_encodeBin), GST_TYPE_TAG_SETTER);
- GstElement *element = 0;
- while (gst_iterator_next(elements, (void**)&element) == GST_ITERATOR_OK) {
- //qDebug() << "found element with tag setter interface:" << gst_element_get_name(element);
- QMapIterator<QByteArray, QVariant> it(data);
- while (it.hasNext()) {
- it.next();
- const QString tagName = it.key();
- const QVariant tagValue = it.value();
-
-
- switch(tagValue.type()) {
- case QVariant::String:
- gst_tag_setter_add_tags(GST_TAG_SETTER(element),
- GST_TAG_MERGE_REPLACE_ALL,
- tagName.toUtf8().constData(),
- tagValue.toString().toUtf8().constData(),
- NULL);
- break;
- case QVariant::Int:
- case QVariant::LongLong:
- gst_tag_setter_add_tags(GST_TAG_SETTER(element),
- GST_TAG_MERGE_REPLACE_ALL,
- tagName.toUtf8().constData(),
- tagValue.toInt(),
- NULL);
- break;
- case QVariant::Double:
- gst_tag_setter_add_tags(GST_TAG_SETTER(element),
- GST_TAG_MERGE_REPLACE_ALL,
- tagName.toUtf8().constData(),
- tagValue.toDouble(),
- NULL);
- break;
- default:
- break;
- }
-
- }
-
- }
- gst_iterator_free(elements);
- }
+ if (m_encodeBin)
+ QGstUtils::setMetaData(GST_BIN(m_encodeBin), data);
}
bool QGstreamerCaptureSession::processBusMessage(const QGstreamerMessage &message)
@@ -1058,34 +962,16 @@ void QGstreamerCaptureSession::setVolume(qreal volume)
void QGstreamerCaptureSession::addProbe(QGstreamerAudioProbeControl* probe)
{
- QMutexLocker locker(&m_audioProbeMutex);
-
- if (m_audioProbes.contains(probe))
- return;
-
- m_audioProbes.append(probe);
+ Q_ASSERT(!m_audioProbe);
+ m_audioProbe = probe;
+ addAudioBufferProbe();
}
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;
+ Q_ASSERT(m_audioProbe == probe);
+ removeAudioBufferProbe();
+ m_audioProbe = 0;
}
GstPad *QGstreamerCaptureSession::getAudioProbePad()
@@ -1114,26 +1000,25 @@ GstPad *QGstreamerCaptureSession::getAudioProbePad()
void QGstreamerCaptureSession::removeAudioBufferProbe()
{
- if (m_audioBufferProbeId == -1)
+ if (!m_audioProbe)
return;
GstPad *pad = getAudioProbePad();
if (pad) {
- gst_pad_remove_buffer_probe(pad, m_audioBufferProbeId);
- gst_object_unref(G_OBJECT(pad));
+ m_audioProbe->removeProbeFromPad(pad);
+ gst_object_unref(GST_OBJECT(pad));
}
-
- m_audioBufferProbeId = -1;
}
void QGstreamerCaptureSession::addAudioBufferProbe()
{
- Q_ASSERT(m_audioBufferProbeId == -1);
+ if (!m_audioProbe)
+ return;
GstPad *pad = getAudioProbePad();
if (pad) {
- m_audioBufferProbeId = gst_pad_add_buffer_probe(pad, G_CALLBACK(padAudioBufferProbe), this);
- gst_object_unref(G_OBJECT(pad));
+ m_audioProbe->addProbeToPad(pad);
+ gst_object_unref(GST_OBJECT(pad));
}
}
diff --git a/src/plugins/gstreamer/mediacapture/qgstreamercapturesession.h b/src/plugins/gstreamer/mediacapture/qgstreamercapturesession.h
index a759f22e5..ad26327e7 100644
--- a/src/plugins/gstreamer/mediacapture/qgstreamercapturesession.h
+++ b/src/plugins/gstreamer/mediacapture/qgstreamercapturesession.h
@@ -41,8 +41,10 @@
#include <QtCore/qurl.h>
#include <gst/gst.h>
+#include <gst/video/video.h>
#include <private/qgstreamerbushelper_p.h>
+#include <private/qgstreamerbufferprobe_p.h>
QT_BEGIN_NAMESPACE
@@ -70,7 +72,10 @@ public:
virtual QList<QSize> supportedResolutions(qreal frameRate = -1) const = 0;
};
-class QGstreamerCaptureSession : public QObject, public QGstreamerBusMessageFilter
+class QGstreamerCaptureSession
+ : public QObject
+ , public QGstreamerBusMessageFilter
+ , private QGstreamerBufferProbe
{
Q_OBJECT
Q_PROPERTY(qint64 duration READ duration NOTIFY durationChanged)
@@ -131,7 +136,6 @@ public:
void addProbe(QGstreamerAudioProbeControl* probe);
void removeProbe(QGstreamerAudioProbeControl* probe);
- static gboolean padAudioBufferProbe(GstPad *pad, GstBuffer *buffer, gpointer user_data);
signals:
void stateChanged(QGstreamerCaptureSession::State state);
@@ -156,6 +160,9 @@ public slots:
void setVolume(qreal volume);
private:
+ void probeCaps(GstCaps *caps);
+ bool probeBuffer(GstBuffer *buffer);
+
enum PipelineMode { EmptyPipeline, PreviewPipeline, RecordingPipeline, PreviewAndRecordingPipeline };
GstElement *buildEncodeBin();
@@ -180,9 +187,7 @@ private:
QGstreamerCaptureSession::CaptureMode m_captureMode;
QMap<QByteArray, QVariant> m_metaData;
- QList<QGstreamerAudioProbeControl*> m_audioProbes;
- QMutex m_audioProbeMutex;
- int m_audioBufferProbeId;
+ QGstreamerAudioProbeControl *m_audioProbe;
QGstreamerElementFactory *m_audioInputFactory;
QGstreamerElementFactory *m_audioPreviewFactory;
@@ -217,6 +222,10 @@ private:
GstElement *m_encodeBin;
+#if GST_CHECK_VERSION(1,0,0)
+ GstVideoInfo m_previewInfo;
+#endif
+
public:
bool m_passImage;
bool m_passPrerollImage;
diff --git a/src/plugins/gstreamer/mediacapture/qgstreamervideoencode.cpp b/src/plugins/gstreamer/mediacapture/qgstreamervideoencode.cpp
index 2f0d0ee76..81b85d7b0 100644
--- a/src/plugins/gstreamer/mediacapture/qgstreamervideoencode.cpp
+++ b/src/plugins/gstreamer/mediacapture/qgstreamervideoencode.cpp
@@ -34,7 +34,7 @@
#include "qgstreamervideoencode.h"
#include "qgstreamercapturesession.h"
#include "qgstreamermediacontainercontrol.h"
-
+#include <private/qgstutils_p.h>
#include <QtCore/qdebug.h>
#include <math.h>
@@ -147,7 +147,7 @@ GstElement *QGstreamerVideoEncode::createEncoder()
GstElement *capsFilter = gst_element_factory_make("capsfilter", "capsfilter-video");
gst_bin_add(encoderBin, capsFilter);
- GstElement *colorspace = gst_element_factory_make("ffmpegcolorspace", NULL);
+ GstElement *colorspace = gst_element_factory_make(QT_GSTREAMER_COLORCONVERSION_ELEMENT_NAME, NULL);
gst_bin_add(encoderBin, colorspace);
gst_bin_add(encoderBin, encoderElement);
@@ -252,27 +252,22 @@ GstElement *QGstreamerVideoEncode::createEncoder()
}
if (!m_videoSettings.resolution().isEmpty() || m_videoSettings.frameRate() > 0.001) {
- GstCaps *caps = gst_caps_new_empty();
- QStringList structureTypes;
- structureTypes << "video/x-raw-yuv" << "video/x-raw-rgb";
-
- foreach(const QString &structureType, structureTypes) {
- GstStructure *structure = gst_structure_new(structureType.toLatin1().constData(), NULL);
-
- if (!m_videoSettings.resolution().isEmpty()) {
- gst_structure_set(structure, "width", G_TYPE_INT, m_videoSettings.resolution().width(), NULL);
- gst_structure_set(structure, "height", G_TYPE_INT, m_videoSettings.resolution().height(), NULL);
- }
-
- if (m_videoSettings.frameRate() > 0.001) {
- QPair<int,int> rate = rateAsRational();
-
- //qDebug() << "frame rate:" << num << denum;
-
- gst_structure_set(structure, "framerate", GST_TYPE_FRACTION, rate.first, rate.second, NULL);
- }
+ GstCaps *caps = QGstUtils::videoFilterCaps();
+
+ if (!m_videoSettings.resolution().isEmpty()) {
+ gst_caps_set_simple(
+ caps,
+ "width", G_TYPE_INT, m_videoSettings.resolution().width(),
+ "height", G_TYPE_INT, m_videoSettings.resolution().height(),
+ NULL);
+ }
- gst_caps_append_structure(caps,structure);
+ if (m_videoSettings.frameRate() > 0.001) {
+ QPair<int,int> rate = rateAsRational();
+ gst_caps_set_simple(
+ caps,
+ "framerate", GST_TYPE_FRACTION, rate.first, rate.second,
+ NULL);
}
//qDebug() << "set video caps filter:" << gst_caps_to_string(caps);