From a53021f776d0c82271727e5817388936513feb92 Mon Sep 17 00:00:00 2001 From: Yin-Chia Yeh Date: Fri, 12 Sep 2014 14:50:27 -0700 Subject: [PATCH] Camera2: fix 4K recording Bug: 17484683 Change-Id: I09bb12698057555329286c777102b9b310452fb3 --- .../camera/libcameraservice/api1/Camera2Client.cpp | 85 +++++++++++++++++----- .../camera/libcameraservice/api1/Camera2Client.h | 3 + .../api1/client2/StreamingProcessor.cpp | 38 ++++++++++ .../api1/client2/StreamingProcessor.h | 3 + 4 files changed, 111 insertions(+), 18 deletions(-) diff --git a/services/camera/libcameraservice/api1/Camera2Client.cpp b/services/camera/libcameraservice/api1/Camera2Client.cpp index 6f4a507ac7..10038c540f 100644 --- a/services/camera/libcameraservice/api1/Camera2Client.cpp +++ b/services/camera/libcameraservice/api1/Camera2Client.cpp @@ -921,6 +921,13 @@ void Camera2Client::stopPreviewL() { "stop preview: %s (%d)", __FUNCTION__, mCameraId, strerror(-res), res); } + { + // Ideally we should recover the override after recording stopped, but + // right now recording stream will live until here, so we are forced to + // recover here. TODO: find a better way to handle that (b/17495165) + SharedParameters::Lock l(mParameters); + l.mParameters.recoverOverriddenJpegSize(); + } // no break case Parameters::WAITING_FOR_PREVIEW_WINDOW: { SharedParameters::Lock l(mParameters); @@ -1075,34 +1082,65 @@ status_t Camera2Client::startRecordingL(Parameters ¶ms, bool restart) { // and we can't fail record start without stagefright asserting. params.previewCallbackFlags = 0; - res = updateProcessorStream< - StreamingProcessor, - &StreamingProcessor::updateRecordingStream>(mStreamingProcessor, - params); + bool recordingStreamNeedsUpdate; + res = mStreamingProcessor->recordingStreamNeedsUpdate(params, &recordingStreamNeedsUpdate); if (res != OK) { - ALOGE("%s: Camera %d: Unable to update recording stream: %s (%d)", - __FUNCTION__, mCameraId, strerror(-res), res); + ALOGE("%s: Camera %d: Can't query recording stream", + __FUNCTION__, mCameraId); return res; } + if (recordingStreamNeedsUpdate) { + // Need to stop stream here in case updateRecordingStream fails + // Right now camera device cannot handle configureStream failure gracefully + // when device is streaming + res = mStreamingProcessor->stopStream(); + if (res != OK) { + ALOGE("%s: Camera %d: Can't stop streaming to update record stream", + __FUNCTION__, mCameraId); + return res; + } + res = mDevice->waitUntilDrained(); + if (res != OK) { + ALOGE("%s: Camera %d: Waiting to stop streaming failed: %s (%d)", + __FUNCTION__, mCameraId, strerror(-res), res); + } + res = updateProcessorStream< + StreamingProcessor, + &StreamingProcessor::updateRecordingStream>(mStreamingProcessor, + params); + + // updateRecordingStream might trigger a configureStream call and device might fail + // configureStream due to jpeg size > video size. Try again with jpeg size overridden + // to video size. + // TODO: This may not be needed after we add stop streaming above. Remove that if + // it's the case. + if (res == BAD_VALUE) { + overrideVideoSnapshotSize(params); + res = updateProcessorStream< + StreamingProcessor, + &StreamingProcessor::updateRecordingStream>(mStreamingProcessor, + params); + } + if (res != OK) { + ALOGE("%s: Camera %d: Unable to update recording stream: %s (%d)", + __FUNCTION__, mCameraId, strerror(-res), res); + return res; + } + } + Vector outputStreams; outputStreams.push(getPreviewStreamId()); outputStreams.push(getRecordingStreamId()); 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; - } + // startStream might trigger a configureStream call and device might fail + // configureStream due to jpeg size > video size. Try again with jpeg size overridden + // to video size. + if (res == BAD_VALUE) { + overrideVideoSnapshotSize(params); res = mStreamingProcessor->startStream(StreamingProcessor::RECORD, outputStreams); } @@ -1146,7 +1184,6 @@ 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", @@ -1923,6 +1960,18 @@ status_t Camera2Client::updateProcessorStream(sp processor, return res; } +status_t Camera2Client::overrideVideoSnapshotSize(Parameters ¶ms) { + ALOGV("%s: Camera %d: configure still size to video size before recording" + , __FUNCTION__, mCameraId); + params.overrideJpegSizeByVideoSize(); + status_t res = updateProcessorStream(mJpegProcessor, params); + if (res != OK) { + ALOGE("%s: Camera %d: Can't override video snapshot size to video size: %s (%d)", + __FUNCTION__, mCameraId, strerror(-res), res); + } + return res; +} + const char* Camera2Client::kAutofocusLabel = "autofocus"; const char* Camera2Client::kTakepictureLabel = "take_picture"; diff --git a/services/camera/libcameraservice/api1/Camera2Client.h b/services/camera/libcameraservice/api1/Camera2Client.h index f5c3a30fd9..d68bb29a72 100644 --- a/services/camera/libcameraservice/api1/Camera2Client.h +++ b/services/camera/libcameraservice/api1/Camera2Client.h @@ -208,6 +208,9 @@ private: // Wait until the camera device has received the latest control settings status_t syncWithDevice(); + + // Video snapshot jpeg size overriding helper function + status_t overrideVideoSnapshotSize(Parameters ¶ms); }; }; // namespace android diff --git a/services/camera/libcameraservice/api1/client2/StreamingProcessor.cpp b/services/camera/libcameraservice/api1/client2/StreamingProcessor.cpp index ab0af0d9bf..9e7fff8e32 100644 --- a/services/camera/libcameraservice/api1/client2/StreamingProcessor.cpp +++ b/services/camera/libcameraservice/api1/client2/StreamingProcessor.cpp @@ -318,6 +318,44 @@ status_t StreamingProcessor::updateRecordingRequest(const Parameters ¶ms) { return OK; } +status_t StreamingProcessor::recordingStreamNeedsUpdate( + const Parameters ¶ms, bool *needsUpdate) { + status_t res; + + if (needsUpdate == 0) { + ALOGE("%s: Camera %d: invalid argument", __FUNCTION__, mId); + return INVALID_OPERATION; + } + + if (mRecordingStreamId == NO_STREAM) { + *needsUpdate = true; + return OK; + } + + sp device = mDevice.promote(); + if (device == 0) { + ALOGE("%s: Camera %d: Device does not exist", __FUNCTION__, mId); + return INVALID_OPERATION; + } + + uint32_t currentWidth, currentHeight; + res = device->getStreamInfo(mRecordingStreamId, + ¤tWidth, ¤tHeight, 0); + if (res != OK) { + ALOGE("%s: Camera %d: Error querying recording output stream info: " + "%s (%d)", __FUNCTION__, mId, + strerror(-res), res); + return res; + } + + if (mRecordingConsumer == 0 || currentWidth != (uint32_t)params.videoWidth || + currentHeight != (uint32_t)params.videoHeight) { + *needsUpdate = true; + } + *needsUpdate = false; + return res; +} + status_t StreamingProcessor::updateRecordingStream(const Parameters ¶ms) { ATRACE_CALL(); status_t res; diff --git a/services/camera/libcameraservice/api1/client2/StreamingProcessor.h b/services/camera/libcameraservice/api1/client2/StreamingProcessor.h index 833bb8fcf2..8466af49df 100644 --- a/services/camera/libcameraservice/api1/client2/StreamingProcessor.h +++ b/services/camera/libcameraservice/api1/client2/StreamingProcessor.h @@ -54,6 +54,9 @@ class StreamingProcessor: status_t setRecordingBufferCount(size_t count); status_t updateRecordingRequest(const Parameters ¶ms); + // If needsUpdate is set to true, a updateRecordingStream call with params will recreate + // recording stream + status_t recordingStreamNeedsUpdate(const Parameters ¶ms, bool *needsUpdate); status_t updateRecordingStream(const Parameters ¶ms); status_t deleteRecordingStream(); int getRecordingStreamId() const; -- 2.11.0