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)
{
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())

View 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

View 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;

View 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;

View 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()

View 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());

View 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())

View 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

View 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();