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:
committed by
Qt by Nokia
parent
b6a8c713bc
commit
864ab3a39a
@@ -81,24 +81,31 @@ QAudioEncoderSettings CameraBinAudioEncoder::audioSettings() const
|
||||
|
||||
void CameraBinAudioEncoder::setAudioSettings(const QAudioEncoderSettings &settings)
|
||||
{
|
||||
m_userSettings = settings;
|
||||
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())
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -103,19 +103,26 @@ QVideoEncoderSettings CameraBinVideoEncoder::videoSettings() const
|
||||
|
||||
void CameraBinVideoEncoder::setVideoSettings(const QVideoEncoderSettings &settings)
|
||||
{
|
||||
if (m_videoSettings != settings) {
|
||||
m_actualVideoSettings = settings;
|
||||
m_videoSettings = settings;
|
||||
m_userSettings = 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())
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user