Camerabin camera service: configure default video settings

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>
This commit is contained in:
Dmytro Poplavskiy
2012-07-13 11:12:06 +10:00
committed by Qt by Nokia
parent b6a8c713bc
commit 864ab3a39a
9 changed files with 108 additions and 27 deletions

View File

@@ -81,24 +81,31 @@ QAudioEncoderSettings CameraBinAudioEncoder::audioSettings() const
void CameraBinAudioEncoder::setAudioSettings(const QAudioEncoderSettings &settings) void CameraBinAudioEncoder::setAudioSettings(const QAudioEncoderSettings &settings)
{ {
m_userSettings = settings; if (m_audioSettings != settings) {
m_audioSettings = settings; m_audioSettings = settings;
m_actualAudioSettings = settings;
emit settingsChanged(); emit settingsChanged();
}
}
QAudioEncoderSettings CameraBinAudioEncoder::actualAudioSettings() const
{
return m_actualAudioSettings;
} }
void CameraBinAudioEncoder::setActualAudioSettings(const QAudioEncoderSettings &settings) void CameraBinAudioEncoder::setActualAudioSettings(const QAudioEncoderSettings &settings)
{ {
m_audioSettings = settings; m_actualAudioSettings = settings;
} }
void CameraBinAudioEncoder::resetActualSettings() void CameraBinAudioEncoder::resetActualSettings()
{ {
m_audioSettings = m_userSettings; m_actualAudioSettings = m_audioSettings;
} }
GstEncodingProfile *CameraBinAudioEncoder::createProfile() GstEncodingProfile *CameraBinAudioEncoder::createProfile()
{ {
QString codec = m_audioSettings.codec(); QString codec = m_actualAudioSettings.codec();
GstCaps *caps; GstCaps *caps;
if (codec.isEmpty()) if (codec.isEmpty())

View File

@@ -80,6 +80,7 @@ public:
QAudioEncoderSettings audioSettings() const; QAudioEncoderSettings audioSettings() const;
void setAudioSettings(const QAudioEncoderSettings&); void setAudioSettings(const QAudioEncoderSettings&);
QAudioEncoderSettings actualAudioSettings() const;
void setActualAudioSettings(const QAudioEncoderSettings&); void setActualAudioSettings(const QAudioEncoderSettings&);
void resetActualSettings(); void resetActualSettings();
@@ -91,8 +92,8 @@ Q_SIGNALS:
private: private:
QGstCodecsInfo m_codecs; QGstCodecsInfo m_codecs;
QAudioEncoderSettings m_actualAudioSettings;
QAudioEncoderSettings m_audioSettings; QAudioEncoderSettings m_audioSettings;
QAudioEncoderSettings m_userSettings;
}; };
QT_END_NAMESPACE QT_END_NAMESPACE

View File

@@ -79,24 +79,40 @@ void CameraBinContainer::setContainerFormat(const QString &format)
{ {
if (m_format != format) { if (m_format != format) {
m_format = format; m_format = format;
m_actualFormat = format;
emit settingsChanged(); 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() GstEncodingContainerProfile *CameraBinContainer::createProfile()
{ {
GstCaps *caps; GstCaps *caps;
if (m_format.isEmpty()) { if (m_actualFormat.isEmpty()) {
caps = gst_caps_new_any(); caps = gst_caps_new_any();
} else { } else {
QString format = m_format; QString format = m_actualFormat;
QStringList supportedFormats = m_supportedContainers.supportedCodecs(); QStringList supportedFormats = m_supportedContainers.supportedCodecs();
//if format is not in the list of supported gstreamer mime types, //if format is not in the list of supported gstreamer mime types,
//try to find the mime type with matching extension //try to find the mime type with matching extension
if (!supportedFormats.contains(format)) { if (!supportedFormats.contains(format)) {
QString extension = suggestedFileExtension(m_format); QString extension = suggestedFileExtension(m_actualFormat);
foreach (const QString &formatCandidate, supportedFormats) { foreach (const QString &formatCandidate, supportedFormats) {
if (suggestedFileExtension(formatCandidate) == extension) { if (suggestedFileExtension(formatCandidate) == extension) {
format = formatCandidate; format = formatCandidate;

View File

@@ -68,6 +68,10 @@ public:
virtual QString containerFormat() const; virtual QString containerFormat() const;
virtual void setContainerFormat(const QString &format); virtual void setContainerFormat(const QString &format);
QString actualContainerFormat() const;
void setActualContainerFormat(const QString &containerFormat);
void resetActualContainerFormat();
QString suggestedFileExtension(const QString &containerFormat) const; QString suggestedFileExtension(const QString &containerFormat) const;
GstEncodingContainerProfile *createProfile(); GstEncodingContainerProfile *createProfile();
@@ -76,7 +80,8 @@ Q_SIGNALS:
void settingsChanged(); void settingsChanged();
private: private:
QString m_format; // backend selected format, using m_userFormat QString m_format;
QString m_actualFormat;
QMap<QString, QString> m_fileExtensions; QMap<QString, QString> m_fileExtensions;
QGstCodecsInfo m_supportedContainers; QGstCodecsInfo m_supportedContainers;

View File

@@ -130,7 +130,49 @@ qint64 CameraBinRecorder::duration() const
void CameraBinRecorder::applySettings() 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() GstEncodingContainerProfile *CameraBinRecorder::videoProfile()

View File

@@ -338,7 +338,7 @@ void CameraBinSession::setupCaptureResolution()
} }
if (m_captureMode == QCamera::CaptureVideo) { if (m_captureMode == QCamera::CaptureVideo) {
QSize resolution = m_videoEncodeControl->videoSettings().resolution(); QSize resolution = m_videoEncodeControl->actualVideoSettings().resolution();
//qreal framerate = m_videoEncodeControl->videoSettings().frameRate(); //qreal framerate = m_videoEncodeControl->videoSettings().frameRate();
if (resolution.isEmpty()) { if (resolution.isEmpty()) {
@@ -644,12 +644,16 @@ void CameraBinSession::setState(QCamera::State newState)
GstState pending = GST_STATE_NULL; GstState pending = GST_STATE_NULL;
gst_element_get_state(m_camerabin, &binState, &pending, 0); 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), g_object_set (G_OBJECT(m_camerabin),
"video-profile", "video-profile",
m_recorderControl->videoProfile(), m_recorderControl->videoProfile(),
NULL); NULL);
}
setupCaptureResolution();
gst_element_set_state(m_camerabin, GST_STATE_PLAYING); gst_element_set_state(m_camerabin, GST_STATE_PLAYING);
} }
@@ -947,7 +951,7 @@ void CameraBinSession::recordVideo()
m_recordingActive = true; m_recordingActive = true;
m_actualSink = m_sink; m_actualSink = m_sink;
if (m_actualSink.isEmpty()) { 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)); m_actualSink = QUrl::fromLocalFile(generateFileName("clip_", defaultDir(QCamera::CaptureVideo), ext));
} else if (!m_actualSink.isLocalFile()) { } else if (!m_actualSink.isLocalFile()) {
m_actualSink = QUrl::fromLocalFile(m_actualSink.toEncoded()); m_actualSink = QUrl::fromLocalFile(m_actualSink.toEncoded());

View File

@@ -103,19 +103,26 @@ QVideoEncoderSettings CameraBinVideoEncoder::videoSettings() const
void CameraBinVideoEncoder::setVideoSettings(const QVideoEncoderSettings &settings) void CameraBinVideoEncoder::setVideoSettings(const QVideoEncoderSettings &settings)
{ {
if (m_videoSettings != settings) {
m_actualVideoSettings = settings;
m_videoSettings = settings; m_videoSettings = settings;
m_userSettings = settings;
emit settingsChanged(); emit settingsChanged();
}
}
QVideoEncoderSettings CameraBinVideoEncoder::actualVideoSettings() const
{
return m_actualVideoSettings;
} }
void CameraBinVideoEncoder::setActualVideoSettings(const QVideoEncoderSettings &settings) void CameraBinVideoEncoder::setActualVideoSettings(const QVideoEncoderSettings &settings)
{ {
m_videoSettings = settings; m_actualVideoSettings = settings;
} }
void CameraBinVideoEncoder::resetActualSettings() 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() GstEncodingProfile *CameraBinVideoEncoder::createProfile()
{ {
QString codec = m_videoSettings.codec(); QString codec = m_actualVideoSettings.codec();
GstCaps *caps; GstCaps *caps;
if (codec.isEmpty()) if (codec.isEmpty())

View File

@@ -78,6 +78,7 @@ public:
QVideoEncoderSettings videoSettings() const; QVideoEncoderSettings videoSettings() const;
void setVideoSettings(const QVideoEncoderSettings &settings); void setVideoSettings(const QVideoEncoderSettings &settings);
QVideoEncoderSettings actualVideoSettings() const;
void setActualVideoSettings(const QVideoEncoderSettings&); void setActualVideoSettings(const QVideoEncoderSettings&);
void resetActualSettings(); void resetActualSettings();
@@ -91,8 +92,8 @@ private:
QGstCodecsInfo m_codecs; QGstCodecsInfo m_codecs;
QVideoEncoderSettings m_videoSettings; // backend selected settings, using m_userSettings QVideoEncoderSettings m_actualVideoSettings;
QVideoEncoderSettings m_userSettings; QVideoEncoderSettings m_videoSettings;
}; };
QT_END_NAMESPACE QT_END_NAMESPACE

View File

@@ -602,11 +602,9 @@ void tst_QCameraBackend::testVideoRecording()
camera->setCaptureMode(QCamera::CaptureVideo); camera->setCaptureMode(QCamera::CaptureVideo);
QVideoEncoderSettings videoSettings; QVideoEncoderSettings videoSettings;
videoSettings.setResolution(640, 480); videoSettings.setResolution(320, 240);
recorder.setVideoSettings(videoSettings); recorder.setVideoSettings(videoSettings);
recorder.setContainerFormat("ogg");
QCOMPARE(recorder.status(), QMediaRecorder::UnloadedStatus); QCOMPARE(recorder.status(), QMediaRecorder::UnloadedStatus);
camera->start(); camera->start();