From 0f82bcd6159b8913dc30c156c8365efcb3597e85 Mon Sep 17 00:00:00 2001 From: Mingke Wang Date: Mon, 7 Mar 2016 18:13:39 +0800 Subject: [PATCH 1/3] fix QCamera can't set container/A/V format with gstreamer backend. 1. set container/A/V format before gstreamer pipeline restart 2. set to NULL state if video-profile changes since gstreamer camerbin only rebuild its encodebin during NULL to READY state change 3. set original A/V encoding from gstreamer pipeline if only container format changes Signed-off-by: Mingke Wang diff --git a/src/multimedia/camera/qcamera.cpp b/src/multimedia/camera/qcamera.cpp old mode 100644 new mode 100755 index ea1b6be..082f308 --- a/src/multimedia/camera/qcamera.cpp +++ b/src/multimedia/camera/qcamera.cpp @@ -151,7 +151,17 @@ void QCameraPrivate::_q_preparePropertyChange(int changeType) return; restartPending = true; - control->setState(QCamera::LoadedState); + + if (changeType == QCameraControl::VideoEncodingSettings && + qstrcmp(control->metaObject()->className(), "CameraBinControl") == 0) { + // for gstreamer backend (camerabin), need to set state to NULL to make + // the codec setting taking effect + control->setState(QCamera::UnloadedState); + control->setState(QCamera::LoadedState); + } else { + control->setState(QCamera::LoadedState); + } + QMetaObject::invokeMethod(q_ptr, "_q_restartCamera", Qt::QueuedConnection); } diff --git a/src/multimedia/recording/qmediarecorder.cpp b/src/multimedia/recording/qmediarecorder.cpp old mode 100644 new mode 100755 index e1c01e3..6166c46 --- a/src/multimedia/recording/qmediarecorder.cpp +++ b/src/multimedia/recording/qmediarecorder.cpp @@ -817,7 +817,11 @@ void QMediaRecorder::setEncodingSettings(const QAudioEncoderSettings &audio, { Q_D(QMediaRecorder); - d->restartCamera(); + // for gstreamer backend (camerabin), need to set encoding profile before + // pipeline restart + if (qstrcmp(d->control->metaObject()->className(), "CameraBinRecorder") != 0){ + d->restartCamera(); + } if (d->audioControl) d->audioControl->setAudioSettings(audio); @@ -828,6 +832,10 @@ void QMediaRecorder::setEncodingSettings(const QAudioEncoderSettings &audio, if (d->formatControl) d->formatControl->setContainerFormat(container); + if (qstrcmp(d->control->metaObject()->className(), "CameraBinRecorder") == 0){ + d->restartCamera(); + } + d->applySettingsLater(); } diff --git a/src/plugins/gstreamer/camerabin/camerabinrecorder.cpp b/src/plugins/gstreamer/camerabin/camerabinrecorder.cpp old mode 100644 new mode 100755 index 4154e1d..747dcd5 --- a/src/plugins/gstreamer/camerabin/camerabinrecorder.cpp +++ b/src/plugins/gstreamer/camerabin/camerabinrecorder.cpp @@ -190,6 +190,29 @@ GstEncodingContainerProfile *CameraBinRecorder::videoProfile() if (!gst_encoding_container_profile_add_profile(containerProfile, videoProfile)) gst_encoding_profile_unref(videoProfile); } + + if (!audioProfile || !videoProfile) { + GstEncodingContainerProfile *profile = NULL; + g_object_get (G_OBJECT(m_session->cameraBin()), "video-profile", &profile, NULL); + if (profile) { + const GList *list; + for (list = + gst_encoding_container_profile_get_profiles ((GstEncodingContainerProfile + *) profile); list; list = g_list_next (list)) { + GstEncodingProfile *enc_profile = (GstEncodingProfile *) list->data; + + if (!audioProfile && GST_IS_ENCODING_AUDIO_PROFILE (enc_profile)) { + audioProfile = enc_profile; + gst_encoding_container_profile_add_profile(containerProfile, audioProfile); + } + + if (!videoProfile && GST_IS_ENCODING_VIDEO_PROFILE (enc_profile)) { + videoProfile = enc_profile; + gst_encoding_container_profile_add_profile(containerProfile, videoProfile); + } + } + } + } } return containerProfile; diff --git a/src/plugins/gstreamer/camerabin/camerabinsession.cpp b/src/plugins/gstreamer/camerabin/camerabinsession.cpp old mode 100644 new mode 100755 index a0e9f75..f4e2be9 --- a/src/plugins/gstreamer/camerabin/camerabinsession.cpp +++ b/src/plugins/gstreamer/camerabin/camerabinsession.cpp @@ -763,6 +763,19 @@ void CameraBinSession::load() return; } + m_recorderControl->applySettings(); + + GstEncodingContainerProfile *profile = m_recorderControl->videoProfile(); + + if (profile) { + g_object_set (G_OBJECT(m_camerabin), "video-profile", profile, NULL); + gst_encoding_profile_unref(profile); + } + + setAudioCaptureCaps(); + + setupCaptureResolution(); + gst_element_set_state(m_camerabin, GST_STATE_READY); } @@ -796,19 +809,6 @@ void CameraBinSession::start() setStatus(QCamera::StartingStatus); - m_recorderControl->applySettings(); - - GstEncodingContainerProfile *profile = m_recorderControl->videoProfile(); - g_object_set (G_OBJECT(m_camerabin), - "video-profile", - profile, - NULL); - gst_encoding_profile_unref(profile); - - setAudioCaptureCaps(); - - setupCaptureResolution(); - gst_element_set_state(m_camerabin, GST_STATE_PLAYING); } diff --git a/src/plugins/gstreamer/camerabin/camerabinvideoencoder.cpp b/src/plugins/gstreamer/camerabin/camerabinvideoencoder.cpp old mode 100644 new mode 100755 index f80ba4a..55e849c --- a/src/plugins/gstreamer/camerabin/camerabinvideoencoder.cpp +++ b/src/plugins/gstreamer/camerabin/camerabinvideoencoder.cpp @@ -158,7 +158,7 @@ GstEncodingProfile *CameraBinVideoEncoder::createProfile() GstCaps *caps; if (codec.isEmpty()) - caps = 0; + return 0; else caps = gst_caps_from_string(codec.toLatin1()); -- 1.9.1