Camerabin camera service: configure default video settings
authorDmytro Poplavskiy <dmytro.poplavskiy@nokia.com>
Fri, 13 Jul 2012 01:12:06 +0000 (11:12 +1000)
committerQt by Nokia <qt-info@nokia.com>
Mon, 16 Jul 2012 05:18:15 +0000 (07:18 +0200)
encodebin doesn't like the encoding profile with ANY
container caps, if container and codecs are not specified
try to find a commonly used supported combination

Change-Id: Icbde042bd17d9682112fb8bbb8f0d506f6ddebe1
Reviewed-by: Michael Goddard <michael.goddard@nokia.com>
src/plugins/gstreamer/camerabin/camerabinaudioencoder.cpp
src/plugins/gstreamer/camerabin/camerabinaudioencoder.h
src/plugins/gstreamer/camerabin/camerabincontainer.cpp
src/plugins/gstreamer/camerabin/camerabincontainer.h
src/plugins/gstreamer/camerabin/camerabinrecorder.cpp
src/plugins/gstreamer/camerabin/camerabinsession.cpp
src/plugins/gstreamer/camerabin/camerabinvideoencoder.cpp
src/plugins/gstreamer/camerabin/camerabinvideoencoder.h
tests/auto/integration/qcamerabackend/tst_qcamerabackend.cpp

index bfd22a3..ebbadd1 100644 (file)
@@ -81,24 +81,31 @@ QAudioEncoderSettings CameraBinAudioEncoder::audioSettings() const
 
 void CameraBinAudioEncoder::setAudioSettings(const QAudioEncoderSettings &settings)
 {
-    m_userSettings = settings;
-    m_audioSettings = settings;
-    emit settingsChanged();
+    if (m_audioSettings != settings) {
+        m_audioSettings = settings;
+        m_actualAudioSettings = settings;
+        emit settingsChanged();
+    }
+}
+
+QAudioEncoderSettings CameraBinAudioEncoder::actualAudioSettings() const
+{
+    return m_actualAudioSettings;
 }
 
 void CameraBinAudioEncoder::setActualAudioSettings(const QAudioEncoderSettings &settings)
 {
-    m_audioSettings = settings;
+    m_actualAudioSettings = settings;
 }
 
 void CameraBinAudioEncoder::resetActualSettings()
 {
-    m_audioSettings = m_userSettings;
+    m_actualAudioSettings = m_audioSettings;
 }
 
 GstEncodingProfile *CameraBinAudioEncoder::createProfile()
 {
-    QString codec = m_audioSettings.codec();
+    QString codec = m_actualAudioSettings.codec();
     GstCaps *caps;
 
     if (codec.isEmpty())
index b3157d7..bbc4ab2 100644 (file)
@@ -80,6 +80,7 @@ public:
     QAudioEncoderSettings audioSettings() const;
     void setAudioSettings(const QAudioEncoderSettings&);
 
+    QAudioEncoderSettings actualAudioSettings() const;
     void setActualAudioSettings(const QAudioEncoderSettings&);
     void resetActualSettings();
 
@@ -91,8 +92,8 @@ Q_SIGNALS:
 private:
     QGstCodecsInfo m_codecs;
 
+    QAudioEncoderSettings m_actualAudioSettings;
     QAudioEncoderSettings m_audioSettings;
-    QAudioEncoderSettings m_userSettings;
 };
 
 QT_END_NAMESPACE
index c24e20a..7b9a138 100644 (file)
@@ -79,24 +79,40 @@ void CameraBinContainer::setContainerFormat(const QString &format)
 {
     if (m_format != format) {
         m_format = format;
+        m_actualFormat = format;
         emit settingsChanged();
     }
 }
 
+QString CameraBinContainer::actualContainerFormat() const
+{
+    return m_actualFormat;
+}
+
+void CameraBinContainer::setActualContainerFormat(const QString &containerFormat)
+{
+    m_actualFormat = containerFormat;
+}
+
+void CameraBinContainer::resetActualContainerFormat()
+{
+    m_actualFormat = m_format;
+}
+
 GstEncodingContainerProfile *CameraBinContainer::createProfile()
 {
     GstCaps *caps;
 
-    if (m_format.isEmpty()) {
+    if (m_actualFormat.isEmpty()) {
         caps = gst_caps_new_any();
     } else {
-        QString format = m_format;
+        QString format = m_actualFormat;
         QStringList supportedFormats = m_supportedContainers.supportedCodecs();
 
         //if format is not in the list of supported gstreamer mime types,
         //try to find the mime type with matching extension
         if (!supportedFormats.contains(format)) {
-            QString extension = suggestedFileExtension(m_format);
+            QString extension = suggestedFileExtension(m_actualFormat);
             foreach (const QString &formatCandidate, supportedFormats) {
                 if (suggestedFileExtension(formatCandidate) == extension) {
                     format = formatCandidate;
index 7830516..c9dcd94 100644 (file)
@@ -68,6 +68,10 @@ public:
     virtual QString containerFormat() const;
     virtual void setContainerFormat(const QString &format);
 
+    QString actualContainerFormat() const;
+    void setActualContainerFormat(const QString &containerFormat);
+    void resetActualContainerFormat();
+
     QString suggestedFileExtension(const QString &containerFormat) const;
 
     GstEncodingContainerProfile *createProfile();
@@ -76,7 +80,8 @@ Q_SIGNALS:
     void settingsChanged();
 
 private:
-    QString m_format; // backend selected format, using m_userFormat
+    QString m_format;
+    QString m_actualFormat;
     QMap<QString, QString> m_fileExtensions;
 
     QGstCodecsInfo m_supportedContainers;
index 8e75e71..90cf3ce 100644 (file)
@@ -130,7 +130,49 @@ qint64 CameraBinRecorder::duration() const
 
 void CameraBinRecorder::applySettings()
 {
-    //settings are applied during camera startup
+    CameraBinContainer *containerControl = m_session->mediaContainerControl();
+    CameraBinAudioEncoder *audioEncoderControl = m_session->audioEncodeControl();
+    CameraBinVideoEncoder *videoEncoderControl = m_session->videoEncodeControl();
+
+    containerControl->resetActualContainerFormat();
+    audioEncoderControl->resetActualSettings();
+    videoEncoderControl->resetActualSettings();
+
+    //encodebin doesn't like the encoding profile with ANY caps,
+    //if container and codecs are not specified,
+    //try to find a commonly used supported combination
+    if (containerControl->containerFormat().isEmpty() &&
+            audioEncoderControl->audioSettings().codec().isEmpty() &&
+            videoEncoderControl->videoSettings().codec().isEmpty()) {
+
+        QList<QStringList> candidates;
+        candidates.append(QStringList() << "video/x-matroska" << "video/x-h264" << "audio/mpeg, mpegversion=(int)4");
+        candidates.append(QStringList() << "video/webm" << "video/x-vp8" << "audio/x-vorbis");
+        candidates.append(QStringList() << "application/ogg" << "video/x-theora" << "audio/x-vorbis");
+        candidates.append(QStringList() << "video/quicktime" << "video/x-h264" << "audio/mpeg, mpegversion=(int)4");
+        candidates.append(QStringList() << "video/quicktime" << "video/x-h264" << "audio/mpeg");
+        candidates.append(QStringList() << "video/x-msvideo" << "video/x-divx" << "audio/mpeg");
+
+        foreach (const QStringList &candidate, candidates) {
+            if (containerControl->supportedContainers().contains(candidate[0]) &&
+                    videoEncoderControl->supportedVideoCodecs().contains(candidate[1]) &&
+                    audioEncoderControl->supportedAudioCodecs().contains(candidate[2])) {
+                containerControl->setActualContainerFormat(candidate[0]);
+
+                QVideoEncoderSettings videoSettings = videoEncoderControl->videoSettings();
+                videoSettings.setCodec(candidate[1]);
+                if (videoSettings.resolution().isEmpty())
+                    videoSettings.setResolution(640, 480);
+                videoEncoderControl->setActualVideoSettings(videoSettings);
+
+                QAudioEncoderSettings audioSettings = audioEncoderControl->audioSettings();
+                audioSettings.setCodec(candidate[2]);
+                audioEncoderControl->setActualAudioSettings(audioSettings);
+
+                break;
+            }
+        }
+    }
 }
 
 GstEncodingContainerProfile *CameraBinRecorder::videoProfile()
index 2c26427..c5c4a50 100644 (file)
@@ -338,7 +338,7 @@ void CameraBinSession::setupCaptureResolution()
     }
 
     if (m_captureMode == QCamera::CaptureVideo) {
-        QSize resolution = m_videoEncodeControl->videoSettings().resolution();
+        QSize resolution = m_videoEncodeControl->actualVideoSettings().resolution();
         //qreal framerate = m_videoEncodeControl->videoSettings().frameRate();
 
         if (resolution.isEmpty()) {
@@ -644,12 +644,16 @@ void CameraBinSession::setState(QCamera::State newState)
             GstState pending = GST_STATE_NULL;
             gst_element_get_state(m_camerabin, &binState, &pending, 0);
 
-            setupCaptureResolution();
-            if (captureMode() == QCamera::CaptureVideo)
+            if (captureMode() == QCamera::CaptureVideo) {
+                m_recorderControl->applySettings();
+
                 g_object_set (G_OBJECT(m_camerabin),
                               "video-profile",
                               m_recorderControl->videoProfile(),
                               NULL);
+            }
+
+            setupCaptureResolution();
 
             gst_element_set_state(m_camerabin, GST_STATE_PLAYING);
         }
@@ -947,7 +951,7 @@ void CameraBinSession::recordVideo()
     m_recordingActive = true;
     m_actualSink = m_sink;
     if (m_actualSink.isEmpty()) {
-        QString ext = m_mediaContainerControl->suggestedFileExtension(m_mediaContainerControl->containerFormat());
+        QString ext = m_mediaContainerControl->suggestedFileExtension(m_mediaContainerControl->actualContainerFormat());
         m_actualSink = QUrl::fromLocalFile(generateFileName("clip_", defaultDir(QCamera::CaptureVideo), ext));
     } else if (!m_actualSink.isLocalFile()) {
         m_actualSink = QUrl::fromLocalFile(m_actualSink.toEncoded());
index 085b9a1..e756030 100644 (file)
@@ -103,19 +103,26 @@ QVideoEncoderSettings CameraBinVideoEncoder::videoSettings() const
 
 void CameraBinVideoEncoder::setVideoSettings(const QVideoEncoderSettings &settings)
 {
-    m_videoSettings = settings;
-    m_userSettings = settings;
-    emit settingsChanged();
+    if (m_videoSettings != settings) {
+        m_actualVideoSettings = settings;
+        m_videoSettings = settings;
+        emit settingsChanged();
+    }
+}
+
+QVideoEncoderSettings CameraBinVideoEncoder::actualVideoSettings() const
+{
+    return m_actualVideoSettings;
 }
 
 void CameraBinVideoEncoder::setActualVideoSettings(const QVideoEncoderSettings &settings)
 {
-    m_videoSettings = settings;
+    m_actualVideoSettings = settings;
 }
 
 void CameraBinVideoEncoder::resetActualSettings()
 {
-    m_videoSettings = m_userSettings;
+    m_actualVideoSettings = m_videoSettings;
 }
 
 
@@ -152,7 +159,7 @@ QPair<int,int> CameraBinVideoEncoder::rateAsRational(qreal frameRate) const
 
 GstEncodingProfile *CameraBinVideoEncoder::createProfile()
 {
-    QString codec = m_videoSettings.codec();
+    QString codec = m_actualVideoSettings.codec();
     GstCaps *caps;
 
     if (codec.isEmpty())
index 9a9dae1..5ab1ae0 100644 (file)
@@ -78,6 +78,7 @@ public:
     QVideoEncoderSettings videoSettings() const;
     void setVideoSettings(const QVideoEncoderSettings &settings);
 
+    QVideoEncoderSettings actualVideoSettings() const;
     void setActualVideoSettings(const QVideoEncoderSettings&);
     void resetActualSettings();
 
@@ -91,8 +92,8 @@ private:
 
     QGstCodecsInfo m_codecs;
 
-    QVideoEncoderSettings m_videoSettings; // backend selected settings, using m_userSettings
-    QVideoEncoderSettings m_userSettings;
+    QVideoEncoderSettings m_actualVideoSettings;
+    QVideoEncoderSettings m_videoSettings;
 };
 
 QT_END_NAMESPACE
index 830d03d..f46ba9b 100644 (file)
@@ -602,11 +602,9 @@ void tst_QCameraBackend::testVideoRecording()
     camera->setCaptureMode(QCamera::CaptureVideo);
 
     QVideoEncoderSettings videoSettings;
-    videoSettings.setResolution(640, 480);
+    videoSettings.setResolution(320, 240);
     recorder.setVideoSettings(videoSettings);
 
-    recorder.setContainerFormat("ogg");
-
     QCOMPARE(recorder.status(), QMediaRecorder::UnloadedStatus);
 
     camera->start();