From 3ea3fcd0822b2f43d87f1d8f67d7bf145864b201 Mon Sep 17 00:00:00 2001 From: Yin-Chia Yeh Date: Fri, 5 Sep 2014 14:14:44 -0700 Subject: Camera2: reconfigure video snapshot size if needed When recording fails to start due to stream configuration failed, try configure stream again by setting jpeg stream to video size. Bug: 16162133 Change-Id: Ib20271e787ae07719ce419f0b15c7f86434f7ebb --- .../camera/libcameraservice/api1/Camera2Client.cpp | 17 +++++++ .../libcameraservice/api1/client2/Parameters.cpp | 54 +++++++++++++++++++++- .../libcameraservice/api1/client2/Parameters.h | 15 ++++++ .../libcameraservice/device3/Camera3Device.cpp | 8 ++++ .../libcameraservice/device3/Camera3Stream.cpp | 3 +- 5 files changed, 93 insertions(+), 4 deletions(-) (limited to 'services') diff --git a/services/camera/libcameraservice/api1/Camera2Client.cpp b/services/camera/libcameraservice/api1/Camera2Client.cpp index bc40971..d59ee51 100644 --- a/services/camera/libcameraservice/api1/Camera2Client.cpp +++ b/services/camera/libcameraservice/api1/Camera2Client.cpp @@ -1088,6 +1088,22 @@ status_t Camera2Client::startRecordingL(Parameters ¶ms, bool restart) { res = mStreamingProcessor->startStream(StreamingProcessor::RECORD, outputStreams); + // try to reconfigure jpeg to video size if configureStreams failed + if (res == BAD_VALUE) { + + ALOGV("%s: Camera %d: configure still size to video size before recording" + , __FUNCTION__, mCameraId); + params.overrideJpegSizeByVideoSize(); + res = updateProcessorStream(mJpegProcessor, params); + if (res != OK) { + ALOGE("%s: Camera %d: Can't configure still image size to video size: %s (%d)", + __FUNCTION__, mCameraId, strerror(-res), res); + return res; + } + res = mStreamingProcessor->startStream(StreamingProcessor::RECORD, + outputStreams); + } + if (res != OK) { ALOGE("%s: Camera %d: Unable to start recording stream: %s (%d)", __FUNCTION__, mCameraId, strerror(-res), res); @@ -1127,6 +1143,7 @@ void Camera2Client::stopRecording() { mCameraService->playSound(CameraService::SOUND_RECORDING); + l.mParameters.recoverOverriddenJpegSize(); res = startPreviewL(l.mParameters, true); if (res != OK) { ALOGE("%s: Camera %d: Unable to return to preview", diff --git a/services/camera/libcameraservice/api1/client2/Parameters.cpp b/services/camera/libcameraservice/api1/client2/Parameters.cpp index e7f9a78..8d00590 100644 --- a/services/camera/libcameraservice/api1/client2/Parameters.cpp +++ b/services/camera/libcameraservice/api1/client2/Parameters.cpp @@ -249,6 +249,9 @@ status_t Parameters::initialize(const CameraMetadata *info, int deviceVersion) { // TODO: Pick maximum pictureWidth = availableJpegSizes[0].width; pictureHeight = availableJpegSizes[0].height; + pictureWidthLastSet = pictureWidth; + pictureHeightLastSet = pictureHeight; + pictureSizeOverriden = false; params.setPictureSize(pictureWidth, pictureHeight); @@ -1381,8 +1384,8 @@ status_t Parameters::set(const String8& paramString) { // PICTURE_SIZE newParams.getPictureSize(&validatedParams.pictureWidth, &validatedParams.pictureHeight); - if (validatedParams.pictureWidth == pictureWidth || - validatedParams.pictureHeight == pictureHeight) { + if (validatedParams.pictureWidth != pictureWidth || + validatedParams.pictureHeight != pictureHeight) { Vector availablePictureSizes = getAvailableJpegSizes(); for (i = 0; i < availablePictureSizes.size(); i++) { if ((availablePictureSizes[i].width == @@ -1798,6 +1801,7 @@ status_t Parameters::set(const String8& paramString) { /** Update internal parameters */ *this = validatedParams; + updateOverriddenJpegSize(); /** Update external parameters calculated from the internal ones */ @@ -2115,6 +2119,52 @@ status_t Parameters::updateRequestJpeg(CameraMetadata *request) const { return OK; } +status_t Parameters::overrideJpegSizeByVideoSize() { + if (pictureSizeOverriden) { + ALOGV("Picture size has been overridden. Skip overriding"); + return OK; + } + + pictureSizeOverriden = true; + pictureWidthLastSet = pictureWidth; + pictureHeightLastSet = pictureHeight; + pictureWidth = videoWidth; + pictureHeight = videoHeight; + // This change of picture size is invisible to app layer. + // Do not update app visible params + return OK; +} + +status_t Parameters::updateOverriddenJpegSize() { + if (!pictureSizeOverriden) { + ALOGV("Picture size has not been overridden. Skip checking"); + return OK; + } + + pictureWidthLastSet = pictureWidth; + pictureHeightLastSet = pictureHeight; + + if (pictureWidth <= videoWidth && pictureHeight <= videoHeight) { + // Picture size is now smaller than video size. No need to override anymore + return recoverOverriddenJpegSize(); + } + + pictureWidth = videoWidth; + pictureHeight = videoHeight; + + return OK; +} + +status_t Parameters::recoverOverriddenJpegSize() { + if (!pictureSizeOverriden) { + ALOGV("Picture size has not been overridden. Skip recovering"); + return OK; + } + pictureSizeOverriden = false; + pictureWidth = pictureWidthLastSet; + pictureHeight = pictureHeightLastSet; + return OK; +} const char* Parameters::getStateName(State state) { #define CASE_ENUM_TO_CHAR(x) case x: return(#x); break; diff --git a/services/camera/libcameraservice/api1/client2/Parameters.h b/services/camera/libcameraservice/api1/client2/Parameters.h index d9d33c4..5e6e6ab 100644 --- a/services/camera/libcameraservice/api1/client2/Parameters.h +++ b/services/camera/libcameraservice/api1/client2/Parameters.h @@ -52,6 +52,9 @@ struct Parameters { int previewTransform; // set by CAMERA_CMD_SET_DISPLAY_ORIENTATION int pictureWidth, pictureHeight; + // Store the picture size before they are overriden by video snapshot + int pictureWidthLastSet, pictureHeightLastSet; + bool pictureSizeOverriden; int32_t jpegThumbSize[2]; uint8_t jpegQuality, jpegThumbQuality; @@ -253,6 +256,12 @@ struct Parameters { // Add/update JPEG entries in metadata status_t updateRequestJpeg(CameraMetadata *request) const; + /* Helper functions to override jpeg size for video snapshot */ + // Override jpeg size by video size. Called during startRecording. + status_t overrideJpegSizeByVideoSize(); + // Recover overridden jpeg size. Called during stopRecording. + status_t recoverOverriddenJpegSize(); + // Calculate the crop region rectangle based on current stream sizes struct CropRegion { float left; @@ -348,6 +357,12 @@ private: // Get max size (from the size array) that matches the given aspect ratio. Size getMaxSizeForRatio(float ratio, const int32_t* sizeArray, size_t count); + // Helper function for overriding jpeg size for video snapshot + // Check if overridden jpeg size needs to be updated after Parameters::set. + // The behavior of this function is tailored to the implementation of Parameters::set. + // Do not use this function for other purpose. + status_t updateOverriddenJpegSize(); + struct StreamConfiguration { int32_t format; int32_t width; diff --git a/services/camera/libcameraservice/device3/Camera3Device.cpp b/services/camera/libcameraservice/device3/Camera3Device.cpp index 6f78db5..fafe349 100644 --- a/services/camera/libcameraservice/device3/Camera3Device.cpp +++ b/services/camera/libcameraservice/device3/Camera3Device.cpp @@ -601,10 +601,18 @@ sp Camera3Device::setUpRequestLocked( if (mStatus == STATUS_UNCONFIGURED || mNeedConfig) { res = configureStreamsLocked(); + // Stream configuration failed due to unsupported configuration. + // Device back to unconfigured state. Client might try other configuraitons + if (res == BAD_VALUE && mStatus == STATUS_UNCONFIGURED) { + CLOGE("No streams configured"); + return NULL; + } + // Stream configuration failed for other reason. Fatal. if (res != OK) { SET_ERR_L("Can't set up streams: %s (%d)", strerror(-res), res); return NULL; } + // Stream configuration successfully configure to empty stream configuration. if (mStatus == STATUS_UNCONFIGURED) { CLOGE("No streams configured"); return NULL; diff --git a/services/camera/libcameraservice/device3/Camera3Stream.cpp b/services/camera/libcameraservice/device3/Camera3Stream.cpp index 29ce38c..3c0e908 100644 --- a/services/camera/libcameraservice/device3/Camera3Stream.cpp +++ b/services/camera/libcameraservice/device3/Camera3Stream.cpp @@ -233,8 +233,7 @@ status_t Camera3Stream::cancelConfiguration() { camera3_stream::usage = oldUsage; camera3_stream::max_buffers = oldMaxBuffers; - mState = STATE_CONSTRUCTED; - + mState = (mState == STATE_IN_RECONFIG) ? STATE_CONFIGURED : STATE_CONSTRUCTED; return OK; } -- cgit v1.1