summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorZhijun He <zhijunhe@google.com>2014-09-13 18:58:02 +0000
committerAndroid (Google) Code Review <android-gerrit@google.com>2014-09-13 18:58:02 +0000
commit0e40a83936d42a34788bbce1c113c404d727fe47 (patch)
treecdc989fc92e14c59d7a978ce78d8d93043d72870
parent4d22f2085141374fd88dba4142a8135f1bd9165c (diff)
parenta53021f776d0c82271727e5817388936513feb92 (diff)
downloadframeworks_av-0e40a83936d42a34788bbce1c113c404d727fe47.zip
frameworks_av-0e40a83936d42a34788bbce1c113c404d727fe47.tar.gz
frameworks_av-0e40a83936d42a34788bbce1c113c404d727fe47.tar.bz2
Merge "Camera2: fix 4K recording" into lmp-dev
-rw-r--r--services/camera/libcameraservice/api1/Camera2Client.cpp85
-rw-r--r--services/camera/libcameraservice/api1/Camera2Client.h3
-rw-r--r--services/camera/libcameraservice/api1/client2/StreamingProcessor.cpp38
-rw-r--r--services/camera/libcameraservice/api1/client2/StreamingProcessor.h3
4 files changed, 111 insertions, 18 deletions
diff --git a/services/camera/libcameraservice/api1/Camera2Client.cpp b/services/camera/libcameraservice/api1/Camera2Client.cpp
index 6f4a507..10038c5 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 &params, 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<int32_t> 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<ProcessorT> processor,
return res;
}
+status_t Camera2Client::overrideVideoSnapshotSize(Parameters &params) {
+ 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 f5c3a30..d68bb29 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 &params);
};
}; // namespace android
diff --git a/services/camera/libcameraservice/api1/client2/StreamingProcessor.cpp b/services/camera/libcameraservice/api1/client2/StreamingProcessor.cpp
index ab0af0d..9e7fff8 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 &params) {
return OK;
}
+status_t StreamingProcessor::recordingStreamNeedsUpdate(
+ const Parameters &params, 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<CameraDeviceBase> 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,
+ &currentWidth, &currentHeight, 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 &params) {
ATRACE_CALL();
status_t res;
diff --git a/services/camera/libcameraservice/api1/client2/StreamingProcessor.h b/services/camera/libcameraservice/api1/client2/StreamingProcessor.h
index 833bb8f..8466af4 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 &params);
+ // If needsUpdate is set to true, a updateRecordingStream call with params will recreate
+ // recording stream
+ status_t recordingStreamNeedsUpdate(const Parameters &params, bool *needsUpdate);
status_t updateRecordingStream(const Parameters &params);
status_t deleteRecordingStream();
int getRecordingStreamId() const;