summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorAndrew den Exter <andrew.den.exter@jollamobile.com>2014-07-17 06:34:30 +0000
committerYoann Lopes <yoann.lopes@digia.com>2014-09-11 11:41:06 +0200
commit55ce8ed07233efbfc224a0bfd6d45ad81b24ac99 (patch)
tree4f937f5d66194430ad5b83aa92fcbdac184b13b4 /src
parent9c020cd39ad9e81239a0953fb3039b79cbee0433 (diff)
Implement encoder settings in camerabin backend.
This is not comprehensive since different encoders have different names and representations for many settings, but it should cover bit rate for most encoders, and quality and encodingMode for a number of common encoders. Change-Id: I0ba4e70c2f234e0deaaa02bdecc0f5198122c1e9 Reviewed-by: Yoann Lopes <yoann.lopes@digia.com>
Diffstat (limited to 'src')
-rw-r--r--src/plugins/gstreamer/camerabin/camerabinaudioencoder.cpp24
-rw-r--r--src/plugins/gstreamer/camerabin/camerabinaudioencoder.h2
-rw-r--r--src/plugins/gstreamer/camerabin/camerabinsession.cpp37
-rw-r--r--src/plugins/gstreamer/camerabin/camerabinsession.h4
-rw-r--r--src/plugins/gstreamer/camerabin/camerabinvideoencoder.cpp42
-rw-r--r--src/plugins/gstreamer/camerabin/camerabinvideoencoder.h2
6 files changed, 111 insertions, 0 deletions
diff --git a/src/plugins/gstreamer/camerabin/camerabinaudioencoder.cpp b/src/plugins/gstreamer/camerabin/camerabinaudioencoder.cpp
index fe8098a02..865a764a8 100644
--- a/src/plugins/gstreamer/camerabin/camerabinaudioencoder.cpp
+++ b/src/plugins/gstreamer/camerabin/camerabinaudioencoder.cpp
@@ -117,4 +117,28 @@ GstEncodingProfile *CameraBinAudioEncoder::createProfile()
return profile;
}
+void CameraBinAudioEncoder::applySettings(GstElement *encoder)
+{
+ GObjectClass * const objectClass = G_OBJECT_GET_CLASS(encoder);
+ const char * const name = gst_plugin_feature_get_name(
+ GST_PLUGIN_FEATURE(gst_element_get_factory(encoder)));
+
+ const bool isVorbis = qstrcmp(name, "vorbisenc") == 0;
+
+ const int bitRate = m_actualAudioSettings.bitRate();
+ if (!isVorbis && bitRate == -1) {
+ // Bit rate is invalid, don't evaluate the remaining conditions unless the encoder is
+ // vorbisenc which is known to accept -1 as an unspecified bitrate.
+ } else if (g_object_class_find_property(objectClass, "bitrate")) {
+ g_object_set(G_OBJECT(encoder), "bitrate", bitRate, NULL);
+ } else if (g_object_class_find_property(objectClass, "target-bitrate")) {
+ g_object_set(G_OBJECT(encoder), "target-bitrate", bitRate, NULL);
+ }
+
+ if (isVorbis) {
+ static const double qualities[] = { 0.1, 0.3, 0.5, 0.7, 1.0 };
+ g_object_set(G_OBJECT(encoder), "quality", qualities[m_actualAudioSettings.quality()], NULL);
+ }
+}
+
QT_END_NAMESPACE
diff --git a/src/plugins/gstreamer/camerabin/camerabinaudioencoder.h b/src/plugins/gstreamer/camerabin/camerabinaudioencoder.h
index 46f812a67..f71436552 100644
--- a/src/plugins/gstreamer/camerabin/camerabinaudioencoder.h
+++ b/src/plugins/gstreamer/camerabin/camerabinaudioencoder.h
@@ -78,6 +78,8 @@ public:
GstEncodingProfile *createProfile();
+ void applySettings(GstElement *element);
+
Q_SIGNALS:
void settingsChanged();
diff --git a/src/plugins/gstreamer/camerabin/camerabinsession.cpp b/src/plugins/gstreamer/camerabin/camerabinsession.cpp
index 420ce5853..850f8c16c 100644
--- a/src/plugins/gstreamer/camerabin/camerabinsession.cpp
+++ b/src/plugins/gstreamer/camerabin/camerabinsession.cpp
@@ -133,6 +133,7 @@ CameraBinSession::CameraBinSession(GstElementFactory *sourceFactory, QObject *pa
m_capsFilter(0),
m_fileSink(0),
m_audioEncoder(0),
+ m_videoEncoder(0),
m_muxer(0)
{
if (m_sourceFactory)
@@ -140,6 +141,8 @@ CameraBinSession::CameraBinSession(GstElementFactory *sourceFactory, QObject *pa
m_camerabin = gst_element_factory_make("camerabin2", "camerabin2");
g_signal_connect(G_OBJECT(m_camerabin), "notify::idle", G_CALLBACK(updateBusyStatus), this);
+ g_signal_connect(G_OBJECT(m_camerabin), "element-added", G_CALLBACK(elementAdded), this);
+ g_signal_connect(G_OBJECT(m_camerabin), "element-removed", G_CALLBACK(elementRemoved), this);
qt_gst_object_ref_sink(m_camerabin);
m_bus = gst_element_get_bus(m_camerabin);
@@ -344,6 +347,9 @@ void CameraBinSession::setupCaptureResolution()
} else {
g_object_set(m_camerabin, VIEWFINDER_CAPS_PROPERTY, NULL, NULL);
}
+
+ if (m_videoEncoder)
+ m_videoEncodeControl->applySettings(m_videoEncoder);
}
void CameraBinSession::setAudioCaptureCaps()
@@ -370,6 +376,9 @@ void CameraBinSession::setAudioCaptureCaps()
GstCaps *caps = gst_caps_new_full(structure, NULL);
g_object_set(G_OBJECT(m_camerabin), AUDIO_CAPTURE_CAPS_PROPERTY, caps, NULL);
gst_caps_unref(caps);
+
+ if (m_audioEncoder)
+ m_audioEncodeControl->applySettings(m_audioEncoder);
}
GstElement *CameraBinSession::buildCameraSource()
@@ -1293,4 +1302,32 @@ QList<QSize> CameraBinSession::supportedResolutions(QPair<int,int> rate,
return res;
}
+void CameraBinSession::elementAdded(GstBin *, GstElement *element, CameraBinSession *session)
+{
+ GstElementFactory *factory = gst_element_get_factory(element);
+
+ if (GST_IS_BIN(element)) {
+ g_signal_connect(G_OBJECT(element), "element-added", G_CALLBACK(elementAdded), session);
+ g_signal_connect(G_OBJECT(element), "element-removed", G_CALLBACK(elementRemoved), session);
+ } else if (!factory) {
+ // no-op
+ } else if (gst_element_factory_list_is_type(factory, GST_ELEMENT_FACTORY_TYPE_AUDIO_ENCODER)) {
+ session->m_audioEncoder = element;
+
+ session->m_audioEncodeControl->applySettings(element);
+ } else if (gst_element_factory_list_is_type(factory, GST_ELEMENT_FACTORY_TYPE_VIDEO_ENCODER)) {
+ session->m_videoEncoder = element;
+
+ session->m_videoEncodeControl->applySettings(element);
+ }
+}
+
+void CameraBinSession::elementRemoved(GstBin *, GstElement *element, CameraBinSession *session)
+{
+ if (element == session->m_audioEncoder)
+ session->m_audioEncoder = 0;
+ else if (element == session->m_videoEncoder)
+ session->m_videoEncoder = 0;
+}
+
QT_END_NAMESPACE
diff --git a/src/plugins/gstreamer/camerabin/camerabinsession.h b/src/plugins/gstreamer/camerabin/camerabinsession.h
index 42ed0e988..7e8a46dee 100644
--- a/src/plugins/gstreamer/camerabin/camerabinsession.h
+++ b/src/plugins/gstreamer/camerabin/camerabinsession.h
@@ -190,6 +190,9 @@ private:
void setAudioCaptureCaps();
static void updateBusyStatus(GObject *o, GParamSpec *p, gpointer d);
+ static void elementAdded(GstBin *bin, GstElement *element, CameraBinSession *session);
+ static void elementRemoved(GstBin *bin, GstElement *element, CameraBinSession *session);
+
QUrl m_sink;
QUrl m_actualSink;
bool m_recordingActive;
@@ -241,6 +244,7 @@ private:
GstElement *m_capsFilter;
GstElement *m_fileSink;
GstElement *m_audioEncoder;
+ GstElement *m_videoEncoder;
GstElement *m_muxer;
public:
diff --git a/src/plugins/gstreamer/camerabin/camerabinvideoencoder.cpp b/src/plugins/gstreamer/camerabin/camerabinvideoencoder.cpp
index 228054318..554437047 100644
--- a/src/plugins/gstreamer/camerabin/camerabinvideoencoder.cpp
+++ b/src/plugins/gstreamer/camerabin/camerabinvideoencoder.cpp
@@ -175,4 +175,46 @@ GstEncodingProfile *CameraBinVideoEncoder::createProfile()
return (GstEncodingProfile *)profile;
}
+void CameraBinVideoEncoder::applySettings(GstElement *encoder)
+{
+ GObjectClass * const objectClass = G_OBJECT_GET_CLASS(encoder);
+ const char * const name = gst_plugin_feature_get_name(
+ GST_PLUGIN_FEATURE(gst_element_get_factory(encoder)));
+
+ const int bitRate = m_actualVideoSettings.bitRate();
+ if (bitRate == -1) {
+ // Bit rate is invalid, don't evaluate the remaining conditions.
+ } else if (g_object_class_find_property(objectClass, "bitrate")) {
+ g_object_set(G_OBJECT(encoder), "bitrate", bitRate, NULL);
+ } else if (g_object_class_find_property(objectClass, "target-bitrate")) {
+ g_object_set(G_OBJECT(encoder), "target-bitrate", bitRate, NULL);
+ }
+
+ if (qstrcmp(name, "theoraenc") == 0) {
+ static const int qualities[] = { 8, 16, 32, 45, 60 };
+ g_object_set(G_OBJECT(encoder), "quality", qualities[m_actualVideoSettings.quality()], NULL);
+ } else if (qstrncmp(name, "avenc_", 6) == 0) {
+ if (g_object_class_find_property(objectClass, "pass")) {
+ static const int modes[] = { 0, 2, 512, 1024 };
+ g_object_set(G_OBJECT(encoder), "pass", modes[m_actualVideoSettings.encodingMode()], NULL);
+ }
+ if (g_object_class_find_property(objectClass, "quantizer")) {
+ static const double qualities[] = { 20, 8.0, 3.0, 2.5, 2.0 };
+ g_object_set(G_OBJECT(encoder), "quantizer", qualities[m_actualVideoSettings.quality()], NULL);
+ }
+ } else if (qstrncmp(name, "omx", 3) == 0) {
+ if (!g_object_class_find_property(objectClass, "control-rate")) {
+ } else switch (m_actualVideoSettings.encodingMode()) {
+ case QMultimedia::ConstantBitRateEncoding:
+ g_object_set(G_OBJECT(encoder), "control-rate", 2, NULL);
+ break;
+ case QMultimedia::AverageBitRateEncoding:
+ g_object_set(G_OBJECT(encoder), "control-rate", 1, NULL);
+ break;
+ default:
+ g_object_set(G_OBJECT(encoder), "control-rate", 0, NULL);
+ }
+ }
+}
+
QT_END_NAMESPACE
diff --git a/src/plugins/gstreamer/camerabin/camerabinvideoencoder.h b/src/plugins/gstreamer/camerabin/camerabinvideoencoder.h
index 0838ba651..dabe098ab 100644
--- a/src/plugins/gstreamer/camerabin/camerabinvideoencoder.h
+++ b/src/plugins/gstreamer/camerabin/camerabinvideoencoder.h
@@ -76,6 +76,8 @@ public:
GstEncodingProfile *createProfile();
+ void applySettings(GstElement *encoder);
+
Q_SIGNALS:
void settingsChanged();