Merge "Allows MediaMetadataRetriever to retrieve video rotation angle" into jb-mr1-dev
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index fe9d09d..a921ad6 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -868,16 +868,19 @@
if (mBtNrecIsOff != btNrecIsOff) {
for (size_t i = 0; i < mRecordThreads.size(); i++) {
sp<RecordThread> thread = mRecordThreads.valueAt(i);
- RecordThread::RecordTrack *track = thread->track();
- if (track != NULL) {
- audio_devices_t device = thread->device() & AUDIO_DEVICE_IN_ALL;
- bool suspend = audio_is_bluetooth_sco_device(device) && btNrecIsOff;
+ audio_devices_t device = thread->device() & AUDIO_DEVICE_IN_ALL;
+ bool suspend = audio_is_bluetooth_sco_device(device) && btNrecIsOff;
+ // collect all of the thread's session IDs
+ KeyedVector<int, bool> ids = thread->sessionIds();
+ // suspend effects associated with those session IDs
+ for (size_t j = 0; j < ids.size(); ++j) {
+ int sessionId = ids.keyAt(j);
thread->setEffectSuspended(FX_IID_AEC,
suspend,
- track->sessionId());
+ sessionId);
thread->setEffectSuspended(FX_IID_NS,
suspend,
- track->sessionId());
+ sessionId);
}
}
mBtNrecIsOff = btNrecIsOff;
@@ -4277,11 +4280,6 @@
AudioFlinger::PlaybackThread::Track::~Track()
{
ALOGV("PlaybackThread::Track destructor");
- sp<ThreadBase> thread = mThread.promote();
- if (thread != 0) {
- Mutex::Autolock _l(thread->mLock);
- mState = TERMINATED;
- }
}
void AudioFlinger::PlaybackThread::Track::destroy()
@@ -5301,10 +5299,7 @@
AudioFlinger::RecordThread::RecordTrack::~RecordTrack()
{
- sp<ThreadBase> thread = mThread.promote();
- if (thread != 0) {
- AudioSystem::releaseInput(thread->id());
- }
+ ALOGV("%s", __func__);
}
// AudioBufferProvider interface
@@ -5377,6 +5372,11 @@
}
}
+/*static*/ void AudioFlinger::RecordThread::RecordTrack::appendDumpHeader(String8& result)
+{
+ result.append(" Clien Fmt Chn mask Session Buf S SRate Serv User\n");
+}
+
void AudioFlinger::RecordThread::RecordTrack::dump(char* buffer, size_t size)
{
snprintf(buffer, size, " %05d %03u 0x%08x %05d %04u %01d %05u %08x %08x\n",
@@ -5861,6 +5861,7 @@
AudioFlinger::RecordHandle::~RecordHandle() {
stop_nonvirtual();
+ mRecordTrack->destroy();
}
sp<IMemory> AudioFlinger::RecordHandle::getCblk() const {
@@ -5896,7 +5897,7 @@
audio_io_handle_t id,
audio_devices_t device) :
ThreadBase(audioFlinger, id, device, RECORD),
- mInput(input), mTrack(NULL), mResampler(NULL), mRsmpOutBuffer(NULL), mRsmpInBuffer(NULL),
+ mInput(input), mResampler(NULL), mRsmpOutBuffer(NULL), mRsmpInBuffer(NULL),
// mRsmpInIndex and mInputBytes set by readInputParameters()
mReqChannelCount(popcount(channelMask)),
mReqSampleRate(sampleRate)
@@ -5980,6 +5981,9 @@
mStartStopCond.broadcast();
}
mStandby = false;
+ } else if (mActiveTrack->mState == TrackBase::TERMINATED) {
+ removeTrack_l(mActiveTrack);
+ mActiveTrack.clear();
}
}
lockEffectChains_l(effectChains);
@@ -6168,8 +6172,8 @@
lStatus = NO_MEMORY;
goto Exit;
}
+ mTracks.add(track);
- mTrack = track.get();
// disable AEC and NS if the device is a BT SCO headset supporting those pre processings
bool suspend = audio_is_bluetooth_sco_device(mDevice & AUDIO_DEVICE_IN_ALL) &&
mAudioFlinger->btNrecIsOff();
@@ -6320,17 +6324,64 @@
return BAD_VALUE;
}
+ int eventSession = event->triggerSession();
+ status_t ret = NAME_NOT_FOUND;
+
Mutex::Autolock _l(mLock);
- if (mTrack != NULL && event->triggerSession() == mTrack->sessionId()) {
- mTrack->setSyncEvent(event);
- return NO_ERROR;
+ for (size_t i = 0; i < mTracks.size(); i++) {
+ sp<RecordTrack> track = mTracks[i];
+ if (eventSession == track->sessionId()) {
+ track->setSyncEvent(event);
+ ret = NO_ERROR;
+ }
}
- return NAME_NOT_FOUND;
+ return ret;
+}
+
+void AudioFlinger::RecordThread::RecordTrack::destroy()
+{
+ // see comments at AudioFlinger::PlaybackThread::Track::destroy()
+ sp<RecordTrack> keep(this);
+ {
+ sp<ThreadBase> thread = mThread.promote();
+ if (thread != 0) {
+ if (mState == ACTIVE || mState == RESUMING) {
+ AudioSystem::stopInput(thread->id());
+ }
+ AudioSystem::releaseInput(thread->id());
+ Mutex::Autolock _l(thread->mLock);
+ RecordThread *recordThread = (RecordThread *) thread.get();
+ recordThread->destroyTrack_l(this);
+ }
+ }
+}
+
+// destroyTrack_l() must be called with ThreadBase::mLock held
+void AudioFlinger::RecordThread::destroyTrack_l(const sp<RecordTrack>& track)
+{
+ track->mState = TrackBase::TERMINATED;
+ // active tracks are removed by threadLoop()
+ if (mActiveTrack != track) {
+ removeTrack_l(track);
+ }
+}
+
+void AudioFlinger::RecordThread::removeTrack_l(const sp<RecordTrack>& track)
+{
+ mTracks.remove(track);
+ // need anything related to effects here?
}
void AudioFlinger::RecordThread::dump(int fd, const Vector<String16>& args)
{
+ dumpInternals(fd, args);
+ dumpTracks(fd, args);
+ dumpEffectChains(fd, args);
+}
+
+void AudioFlinger::RecordThread::dumpInternals(int fd, const Vector<String16>& args)
+{
const size_t SIZE = 256;
char buffer[SIZE];
String8 result;
@@ -6339,11 +6390,6 @@
result.append(buffer);
if (mActiveTrack != 0) {
- result.append("Active Track:\n");
- result.append(" Clien Fmt Chn mask Session Buf S SRate Serv User\n");
- mActiveTrack->dump(buffer, SIZE);
- result.append(buffer);
-
snprintf(buffer, SIZE, "In index: %d\n", mRsmpInIndex);
result.append(buffer);
snprintf(buffer, SIZE, "In size: %d\n", mInputBytes);
@@ -6354,15 +6400,41 @@
result.append(buffer);
snprintf(buffer, SIZE, "Out sample rate: %d\n", mReqSampleRate);
result.append(buffer);
-
-
} else {
- result.append("No record client\n");
+ result.append("No active record client\n");
}
+
write(fd, result.string(), result.size());
dumpBase(fd, args);
- dumpEffectChains(fd, args);
+}
+
+void AudioFlinger::RecordThread::dumpTracks(int fd, const Vector<String16>& args)
+{
+ const size_t SIZE = 256;
+ char buffer[SIZE];
+ String8 result;
+
+ snprintf(buffer, SIZE, "Input thread %p tracks\n", this);
+ result.append(buffer);
+ RecordTrack::appendDumpHeader(result);
+ for (size_t i = 0; i < mTracks.size(); ++i) {
+ sp<RecordTrack> track = mTracks[i];
+ if (track != 0) {
+ track->dump(buffer, SIZE);
+ result.append(buffer);
+ }
+ }
+
+ if (mActiveTrack != 0) {
+ snprintf(buffer, SIZE, "\nInput thread %p active tracks\n", this);
+ result.append(buffer);
+ RecordTrack::appendDumpHeader(result);
+ mActiveTrack->dump(buffer, SIZE);
+ result.append(buffer);
+
+ }
+ write(fd, result.string(), result.size());
}
// AudioBufferProvider interface
@@ -6462,11 +6534,14 @@
} else {
newDevice &= ~(value & AUDIO_DEVICE_IN_ALL);
// disable AEC and NS if the device is a BT SCO headset supporting those pre processings
- if (mTrack != NULL) {
+ if (mTracks.size() > 0) {
bool suspend = audio_is_bluetooth_sco_device(
(audio_devices_t)value) && mAudioFlinger->btNrecIsOff();
- setEffectSuspended_l(FX_IID_AEC, suspend, mTrack->sessionId());
- setEffectSuspended_l(FX_IID_NS, suspend, mTrack->sessionId());
+ for (size_t i = 0; i < mTracks.size(); i++) {
+ sp<RecordTrack> track = mTracks[i];
+ setEffectSuspended_l(FX_IID_AEC, suspend, track->sessionId());
+ setEffectSuspended_l(FX_IID_NS, suspend, track->sessionId());
+ }
}
}
newDevice |= value;
@@ -6605,17 +6680,28 @@
result = EFFECT_SESSION;
}
- if (mTrack != NULL && sessionId == mTrack->sessionId()) {
- result |= TRACK_SESSION;
+ for (size_t i = 0; i < mTracks.size(); ++i) {
+ if (sessionId == mTracks[i]->sessionId()) {
+ result |= TRACK_SESSION;
+ break;
+ }
}
return result;
}
-AudioFlinger::RecordThread::RecordTrack* AudioFlinger::RecordThread::track()
+KeyedVector<int, bool> AudioFlinger::RecordThread::sessionIds()
{
+ KeyedVector<int, bool> ids;
Mutex::Autolock _l(mLock);
- return mTrack;
+ for (size_t j = 0; j < mTracks.size(); ++j) {
+ sp<RecordThread::RecordTrack> track = mTracks[j];
+ int sessionId = track->sessionId();
+ if (ids.indexOfKey(sessionId) < 0) {
+ ids.add(sessionId, true);
+ }
+ }
+ return ids;
}
AudioFlinger::AudioStreamIn* AudioFlinger::RecordThread::clearInput()
diff --git a/services/audioflinger/AudioFlinger.h b/services/audioflinger/AudioFlinger.h
index e629533..2b6d00f 100644
--- a/services/audioflinger/AudioFlinger.h
+++ b/services/audioflinger/AudioFlinger.h
@@ -1381,11 +1381,14 @@
virtual status_t start(AudioSystem::sync_event_t event, int triggerSession);
virtual void stop();
+ void destroy();
+
// clear the buffer overflow flag
void clearOverflow() { mOverflow = false; }
// set the buffer overflow flag and return previous value
bool setOverflow() { bool tmp = mOverflow; mOverflow = true; return tmp; }
+ static void appendDumpHeader(String8& result);
void dump(char* buffer, size_t size);
private:
@@ -1409,6 +1412,13 @@
audio_devices_t device);
virtual ~RecordThread();
+ // no addTrack_l ?
+ void destroyTrack_l(const sp<RecordTrack>& track);
+ void removeTrack_l(const sp<RecordTrack>& track);
+
+ void dumpInternals(int fd, const Vector<String16>& args);
+ void dumpTracks(int fd, const Vector<String16>& args);
+
// Thread
virtual bool threadLoop();
virtual status_t readyToRun();
@@ -1453,7 +1463,11 @@
virtual status_t addEffectChain_l(const sp<EffectChain>& chain);
virtual size_t removeEffectChain_l(const sp<EffectChain>& chain);
virtual uint32_t hasAudioSession(int sessionId);
- RecordTrack* track();
+
+ // Return the set of unique session IDs across all tracks.
+ // The keys are the session IDs, and the associated values are meaningless.
+ // FIXME replace by Set [and implement Bag/Multiset for other uses].
+ KeyedVector<int, bool> sessionIds();
virtual status_t setSyncEvent(const sp<SyncEvent>& event);
virtual bool isValidSyncEvent(const sp<SyncEvent>& event);
@@ -1471,7 +1485,9 @@
void inputStandBy();
AudioStreamIn *mInput;
- RecordTrack* mTrack;
+ SortedVector < sp<RecordTrack> > mTracks;
+ // mActiveTrack has dual roles: it indicates the current active track, and
+ // is used together with mStartStopCond to indicate start()/stop() progress
sp<RecordTrack> mActiveTrack;
Condition mStartStopCond;
AudioResampler *mResampler;
diff --git a/services/camera/libcameraservice/Camera2Client.cpp b/services/camera/libcameraservice/Camera2Client.cpp
index 47d1588..62741d5 100644
--- a/services/camera/libcameraservice/Camera2Client.cpp
+++ b/services/camera/libcameraservice/Camera2Client.cpp
@@ -86,9 +86,10 @@
}
if (gLogLevel >= 1) {
+ LockedParameters::Key k(mParameters);
ALOGD("%s: Default parameters converted from camera %d:", __FUNCTION__,
mCameraId);
- ALOGD("%s", mParamsFlattened.string());
+ ALOGD("%s", k.mParameters.paramsFlattened.string());
}
mState = STOPPED;
@@ -115,38 +116,40 @@
result.append(" State: ");
#define CASE_APPEND_ENUM(x) case x: result.append(#x "\n"); break;
+ const Parameters& p = mParameters.unsafeUnlock();
+
result.append(getStateName(mState));
result.append("\n Current parameters:\n");
result.appendFormat(" Preview size: %d x %d\n",
- mParameters.previewWidth, mParameters.previewHeight);
+ p.previewWidth, p.previewHeight);
result.appendFormat(" Preview FPS range: %d - %d\n",
- mParameters.previewFpsRange[0], mParameters.previewFpsRange[1]);
+ p.previewFpsRange[0], p.previewFpsRange[1]);
result.appendFormat(" Preview HAL pixel format: 0x%x\n",
- mParameters.previewFormat);
+ p.previewFormat);
result.appendFormat(" Preview transform: %x\n",
- mParameters.previewTransform);
+ p.previewTransform);
result.appendFormat(" Picture size: %d x %d\n",
- mParameters.pictureWidth, mParameters.pictureHeight);
+ p.pictureWidth, p.pictureHeight);
result.appendFormat(" Jpeg thumbnail size: %d x %d\n",
- mParameters.jpegThumbSize[0], mParameters.jpegThumbSize[1]);
+ p.jpegThumbSize[0], p.jpegThumbSize[1]);
result.appendFormat(" Jpeg quality: %d, thumbnail quality: %d\n",
- mParameters.jpegQuality, mParameters.jpegThumbQuality);
- result.appendFormat(" Jpeg rotation: %d\n", mParameters.jpegRotation);
+ p.jpegQuality, p.jpegThumbQuality);
+ result.appendFormat(" Jpeg rotation: %d\n", p.jpegRotation);
result.appendFormat(" GPS tags %s\n",
- mParameters.gpsEnabled ? "enabled" : "disabled");
- if (mParameters.gpsEnabled) {
+ p.gpsEnabled ? "enabled" : "disabled");
+ if (p.gpsEnabled) {
result.appendFormat(" GPS lat x long x alt: %f x %f x %f\n",
- mParameters.gpsCoordinates[0], mParameters.gpsCoordinates[1],
- mParameters.gpsCoordinates[2]);
+ p.gpsCoordinates[0], p.gpsCoordinates[1],
+ p.gpsCoordinates[2]);
result.appendFormat(" GPS timestamp: %lld\n",
- mParameters.gpsTimestamp);
+ p.gpsTimestamp);
result.appendFormat(" GPS processing method: %s\n",
- mParameters.gpsProcessingMethod.string());
+ p.gpsProcessingMethod.string());
}
result.append(" White balance mode: ");
- switch (mParameters.wbMode) {
+ switch (p.wbMode) {
CASE_APPEND_ENUM(ANDROID_CONTROL_AWB_AUTO)
CASE_APPEND_ENUM(ANDROID_CONTROL_AWB_INCANDESCENT)
CASE_APPEND_ENUM(ANDROID_CONTROL_AWB_FLUORESCENT)
@@ -159,7 +162,7 @@
}
result.append(" Effect mode: ");
- switch (mParameters.effectMode) {
+ switch (p.effectMode) {
CASE_APPEND_ENUM(ANDROID_CONTROL_EFFECT_OFF)
CASE_APPEND_ENUM(ANDROID_CONTROL_EFFECT_MONO)
CASE_APPEND_ENUM(ANDROID_CONTROL_EFFECT_NEGATIVE)
@@ -173,7 +176,7 @@
}
result.append(" Antibanding mode: ");
- switch (mParameters.antibandingMode) {
+ switch (p.antibandingMode) {
CASE_APPEND_ENUM(ANDROID_CONTROL_AE_ANTIBANDING_AUTO)
CASE_APPEND_ENUM(ANDROID_CONTROL_AE_ANTIBANDING_OFF)
CASE_APPEND_ENUM(ANDROID_CONTROL_AE_ANTIBANDING_50HZ)
@@ -182,7 +185,7 @@
}
result.append(" Scene mode: ");
- switch (mParameters.sceneMode) {
+ switch (p.sceneMode) {
case ANDROID_CONTROL_SCENE_MODE_UNSUPPORTED:
result.append("AUTO\n"); break;
CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_ACTION)
@@ -204,7 +207,7 @@
}
result.append(" Flash mode: ");
- switch (mParameters.flashMode) {
+ switch (p.flashMode) {
CASE_APPEND_ENUM(Parameters::FLASH_MODE_OFF)
CASE_APPEND_ENUM(Parameters::FLASH_MODE_AUTO)
CASE_APPEND_ENUM(Parameters::FLASH_MODE_ON)
@@ -215,7 +218,7 @@
}
result.append(" Focus mode: ");
- switch (mParameters.focusMode) {
+ switch (p.focusMode) {
CASE_APPEND_ENUM(Parameters::FOCUS_MODE_AUTO)
CASE_APPEND_ENUM(Parameters::FOCUS_MODE_MACRO)
CASE_APPEND_ENUM(Parameters::FOCUS_MODE_CONTINUOUS_VIDEO)
@@ -228,51 +231,52 @@
}
result.append(" Focusing areas:\n");
- for (size_t i = 0; i < mParameters.focusingAreas.size(); i++) {
+ for (size_t i = 0; i < p.focusingAreas.size(); i++) {
result.appendFormat(" [ (%d, %d, %d, %d), weight %d ]\n",
- mParameters.focusingAreas[i].left,
- mParameters.focusingAreas[i].top,
- mParameters.focusingAreas[i].right,
- mParameters.focusingAreas[i].bottom,
- mParameters.focusingAreas[i].weight);
+ p.focusingAreas[i].left,
+ p.focusingAreas[i].top,
+ p.focusingAreas[i].right,
+ p.focusingAreas[i].bottom,
+ p.focusingAreas[i].weight);
}
result.appendFormat(" Exposure compensation index: %d\n",
- mParameters.exposureCompensation);
+ p.exposureCompensation);
result.appendFormat(" AE lock %s, AWB lock %s\n",
- mParameters.autoExposureLock ? "enabled" : "disabled",
- mParameters.autoWhiteBalanceLock ? "enabled" : "disabled" );
+ p.autoExposureLock ? "enabled" : "disabled",
+ p.autoWhiteBalanceLock ? "enabled" : "disabled" );
result.appendFormat(" Metering areas:\n");
- for (size_t i = 0; i < mParameters.meteringAreas.size(); i++) {
+ for (size_t i = 0; i < p.meteringAreas.size(); i++) {
result.appendFormat(" [ (%d, %d, %d, %d), weight %d ]\n",
- mParameters.meteringAreas[i].left,
- mParameters.meteringAreas[i].top,
- mParameters.meteringAreas[i].right,
- mParameters.meteringAreas[i].bottom,
- mParameters.meteringAreas[i].weight);
+ p.meteringAreas[i].left,
+ p.meteringAreas[i].top,
+ p.meteringAreas[i].right,
+ p.meteringAreas[i].bottom,
+ p.meteringAreas[i].weight);
}
- result.appendFormat(" Zoom index: %d\n", mParameters.zoom);
- result.appendFormat(" Video size: %d x %d\n", mParameters.videoWidth,
- mParameters.videoHeight);
+ result.appendFormat(" Zoom index: %d\n", p.zoom);
+ result.appendFormat(" Video size: %d x %d\n", p.videoWidth,
+ p.videoHeight);
result.appendFormat(" Recording hint is %s\n",
- mParameters.recordingHint ? "set" : "not set");
+ p.recordingHint ? "set" : "not set");
result.appendFormat(" Video stabilization is %s\n",
- mParameters.videoStabilization ? "enabled" : "disabled");
+ p.videoStabilization ? "enabled" : "disabled");
result.append(" Current streams:\n");
result.appendFormat(" Preview stream ID: %d\n", mPreviewStreamId);
result.appendFormat(" Capture stream ID: %d\n", mCaptureStreamId);
+ result.appendFormat(" Recording stream ID: %d\n", mRecordingStreamId);
result.append(" Current requests:\n");
if (mPreviewRequest != NULL) {
result.append(" Preview request:\n");
write(fd, result.string(), result.size());
- dump_camera_metadata(mPreviewRequest, fd, 2);
+ dump_indented_camera_metadata(mPreviewRequest, fd, 2, 6);
} else {
result.append(" Preview request: undefined\n");
write(fd, result.string(), result.size());
@@ -281,12 +285,21 @@
if (mCaptureRequest != NULL) {
result = " Capture request:\n";
write(fd, result.string(), result.size());
- dump_camera_metadata(mCaptureRequest, fd, 2);
+ dump_indented_camera_metadata(mCaptureRequest, fd, 2, 6);
} else {
result = " Capture request: undefined\n";
write(fd, result.string(), result.size());
}
+ if (mRecordingRequest != NULL) {
+ result = " Recording request:\n";
+ write(fd, result.string(), result.size());
+ dump_indented_camera_metadata(mRecordingRequest, fd, 2, 6);
+ } else {
+ result = " Recording request: undefined\n";
+ write(fd, result.string(), result.size());
+ }
+
result = " Device dump:\n";
write(fd, result.string(), result.size());
@@ -524,9 +537,9 @@
}
mState = STOPPED;
- Mutex::Autolock pl(mParamsLock);
+ LockedParameters::Key k(mParameters);
- res = updatePreviewStream();
+ res = updatePreviewStream(k.mParameters);
if (res != OK) {
ALOGE("%s: Camera %d: Unable to update preview stream: %s (%d)",
__FUNCTION__, mCameraId, strerror(-res), res);
@@ -534,7 +547,7 @@
}
if (mPreviewRequest == NULL) {
- res = updatePreviewRequest();
+ res = updatePreviewRequest(k.mParameters);
if (res != OK) {
ALOGE("%s: Camera %d: Unable to create preview request: %s (%d)",
__FUNCTION__, mCameraId, strerror(-res), res);
@@ -622,9 +635,9 @@
// OK
break;
}
- Mutex::Autolock pl(mParamsLock);
+ LockedParameters::Key k(mParameters);
- mParameters.storeMetadataInBuffers = enabled;
+ k.mParameters.storeMetadataInBuffers = enabled;
return OK;
}
@@ -653,16 +666,16 @@
return INVALID_OPERATION;
};
- Mutex::Autolock pl(mParamsLock);
+ LockedParameters::Key k(mParameters);
- if (!mParameters.storeMetadataInBuffers) {
+ if (!k.mParameters.storeMetadataInBuffers) {
ALOGE("%s: Camera %d: Recording only supported in metadata mode, but "
"non-metadata recording mode requested!", __FUNCTION__,
mCameraId);
return INVALID_OPERATION;
}
- res = updateRecordingStream();
+ res = updateRecordingStream(k.mParameters);
if (res != OK) {
ALOGE("%s: Camera %d: Unable to update recording stream: %s (%d)",
__FUNCTION__, mCameraId, strerror(-res), res);
@@ -670,7 +683,7 @@
}
if (mRecordingRequest == NULL) {
- res = updateRecordingRequest();
+ res = updateRecordingRequest(k.mParameters);
if (res != OK) {
ALOGE("%s: Camera %d: Unable to create recording request: %s (%d)",
__FUNCTION__, mCameraId, strerror(-res), res);
@@ -816,9 +829,9 @@
return INVALID_OPERATION;
}
- Mutex::Autolock pl(mParamsLock);
+ LockedParameters::Key k(mParameters);
- res = updateCaptureStream();
+ res = updateCaptureStream(k.mParameters);
if (res != OK) {
ALOGE("%s: Camera %d: Can't set up still image stream: %s (%d)",
__FUNCTION__, mCameraId, strerror(-res), res);
@@ -826,7 +839,7 @@
}
if (mCaptureRequest == NULL) {
- res = updateCaptureRequest();
+ res = updateCaptureRequest(k.mParameters);
if (res != OK) {
ALOGE("%s: Camera %d: Can't create still image capture request: "
"%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
@@ -904,7 +917,7 @@
ATRACE_CALL();
ALOGV("%s: E", __FUNCTION__);
Mutex::Autolock icl(mICameraLock);
- Mutex::Autolock pl(mParamsLock);
+ LockedParameters::Key k(mParameters);
status_t res;
CameraParameters newParams(params);
@@ -921,13 +934,13 @@
int previewWidth, previewHeight;
newParams.getPreviewSize(&previewWidth, &previewHeight);
- if (previewWidth != mParameters.previewWidth ||
- previewHeight != mParameters.previewHeight) {
+ if (previewWidth != k.mParameters.previewWidth ||
+ previewHeight != k.mParameters.previewHeight) {
if (mState >= PREVIEW) {
ALOGE("%s: Preview size cannot be updated when preview "
"is active! (Currently %d x %d, requested %d x %d",
__FUNCTION__,
- mParameters.previewWidth, mParameters.previewHeight,
+ k.mParameters.previewWidth, k.mParameters.previewHeight,
previewWidth, previewHeight);
return BAD_VALUE;
}
@@ -949,8 +962,8 @@
int previewFps = 0;
bool fpsRangeChanged = false;
newParams.getPreviewFpsRange(&previewFpsRange[0], &previewFpsRange[1]);
- if (previewFpsRange[0] != mParameters.previewFpsRange[0] ||
- previewFpsRange[1] != mParameters.previewFpsRange[1]) {
+ if (previewFpsRange[0] != k.mParameters.previewFpsRange[0] ||
+ previewFpsRange[1] != k.mParameters.previewFpsRange[1]) {
fpsRangeChanged = true;
camera_metadata_entry_t availablePreviewFpsRanges =
staticInfo(ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES, 2);
@@ -972,7 +985,7 @@
// PREVIEW_FORMAT
int previewFormat = formatStringToEnum(newParams.getPreviewFormat());
- if (previewFormat != mParameters.previewFormat) {
+ if (previewFormat != k.mParameters.previewFormat) {
if (mState >= PREVIEW) {
ALOGE("%s: Preview format cannot be updated when preview "
"is active!", __FUNCTION__);
@@ -995,7 +1008,7 @@
// The single-value FPS is the same as the minimum of the range.
if (!fpsRangeChanged) {
previewFps = newParams.getPreviewFrameRate();
- if (previewFps != mParameters.previewFps) {
+ if (previewFps != k.mParameters.previewFps) {
camera_metadata_entry_t availableFrameRates =
staticInfo(ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES);
for (i = 0; i < availableFrameRates.count; i+=2) {
@@ -1014,8 +1027,8 @@
// PICTURE_SIZE
int pictureWidth, pictureHeight;
newParams.getPictureSize(&pictureWidth, &pictureHeight);
- if (pictureWidth == mParameters.pictureWidth ||
- pictureHeight == mParameters.pictureHeight) {
+ if (pictureWidth == k.mParameters.pictureWidth ||
+ pictureHeight == k.mParameters.pictureHeight) {
camera_metadata_entry_t availablePictureSizes =
staticInfo(ANDROID_SCALER_AVAILABLE_JPEG_SIZES);
for (i = 0; i < availablePictureSizes.count; i+=2) {
@@ -1035,8 +1048,8 @@
newParams.getInt(CameraParameters::KEY_JPEG_THUMBNAIL_WIDTH);
jpegThumbSize[1] =
newParams.getInt(CameraParameters::KEY_JPEG_THUMBNAIL_HEIGHT);
- if (jpegThumbSize[0] != mParameters.jpegThumbSize[0] ||
- jpegThumbSize[1] != mParameters.jpegThumbSize[1]) {
+ if (jpegThumbSize[0] != k.mParameters.jpegThumbSize[0] ||
+ jpegThumbSize[1] != k.mParameters.jpegThumbSize[1]) {
camera_metadata_entry_t availableJpegThumbSizes =
staticInfo(ANDROID_JPEG_AVAILABLE_THUMBNAIL_SIZES);
for (i = 0; i < availableJpegThumbSizes.count; i+=2) {
@@ -1140,7 +1153,7 @@
// WHITE_BALANCE
int wbMode = wbModeStringToEnum(
newParams.get(CameraParameters::KEY_WHITE_BALANCE) );
- if (wbMode != mParameters.wbMode) {
+ if (wbMode != k.mParameters.wbMode) {
camera_metadata_entry_t availableWbModes =
staticInfo(ANDROID_CONTROL_AWB_AVAILABLE_MODES);
for (i = 0; i < availableWbModes.count; i++) {
@@ -1157,7 +1170,7 @@
// EFFECT
int effectMode = effectModeStringToEnum(
newParams.get(CameraParameters::KEY_EFFECT) );
- if (effectMode != mParameters.effectMode) {
+ if (effectMode != k.mParameters.effectMode) {
camera_metadata_entry_t availableEffectModes =
staticInfo(ANDROID_CONTROL_AVAILABLE_EFFECTS);
for (i = 0; i < availableEffectModes.count; i++) {
@@ -1174,7 +1187,7 @@
// ANTIBANDING
int antibandingMode = abModeStringToEnum(
newParams.get(CameraParameters::KEY_ANTIBANDING) );
- if (antibandingMode != mParameters.antibandingMode) {
+ if (antibandingMode != k.mParameters.antibandingMode) {
camera_metadata_entry_t availableAbModes =
staticInfo(ANDROID_CONTROL_AE_AVAILABLE_ANTIBANDING_MODES);
for (i = 0; i < availableAbModes.count; i++) {
@@ -1191,7 +1204,7 @@
// SCENE_MODE
int sceneMode = sceneModeStringToEnum(
newParams.get(CameraParameters::KEY_SCENE_MODE) );
- if (sceneMode != mParameters.sceneMode) {
+ if (sceneMode != k.mParameters.sceneMode) {
camera_metadata_entry_t availableSceneModes =
staticInfo(ANDROID_CONTROL_AVAILABLE_SCENE_MODES);
for (i = 0; i < availableSceneModes.count; i++) {
@@ -1208,7 +1221,7 @@
// FLASH_MODE
Parameters::flashMode_t flashMode = flashModeStringToEnum(
newParams.get(CameraParameters::KEY_FLASH_MODE) );
- if (flashMode != mParameters.flashMode) {
+ if (flashMode != k.mParameters.flashMode) {
camera_metadata_entry_t flashAvailable =
staticInfo(ANDROID_FLASH_AVAILABLE, 1, 1);
if (!flashAvailable.data.u8[0] &&
@@ -1240,7 +1253,7 @@
// FOCUS_MODE
Parameters::focusMode_t focusMode = focusModeStringToEnum(
newParams.get(CameraParameters::KEY_FOCUS_MODE));
- if (focusMode != mParameters.focusMode) {
+ if (focusMode != k.mParameters.focusMode) {
if (focusMode != Parameters::FOCUS_MODE_FIXED) {
camera_metadata_entry_t minFocusDistance =
staticInfo(ANDROID_LENS_MINIMUM_FOCUS_DISTANCE);
@@ -1322,8 +1335,8 @@
// VIDEO_SIZE
int videoWidth, videoHeight;
newParams.getVideoSize(&videoWidth, &videoHeight);
- if (videoWidth != mParameters.videoWidth ||
- videoHeight != mParameters.videoHeight) {
+ if (videoWidth != k.mParameters.videoWidth ||
+ videoHeight != k.mParameters.videoHeight) {
if (mState == RECORD) {
ALOGE("%s: Video size cannot be updated when recording is active!",
__FUNCTION__);
@@ -1357,63 +1370,63 @@
/** Update internal parameters */
- mParameters.previewWidth = previewWidth;
- mParameters.previewHeight = previewHeight;
- mParameters.previewFpsRange[0] = previewFpsRange[0];
- mParameters.previewFpsRange[1] = previewFpsRange[1];
- mParameters.previewFps = previewFps;
- mParameters.previewFormat = previewFormat;
+ k.mParameters.previewWidth = previewWidth;
+ k.mParameters.previewHeight = previewHeight;
+ k.mParameters.previewFpsRange[0] = previewFpsRange[0];
+ k.mParameters.previewFpsRange[1] = previewFpsRange[1];
+ k.mParameters.previewFps = previewFps;
+ k.mParameters.previewFormat = previewFormat;
- mParameters.pictureWidth = pictureWidth;
- mParameters.pictureHeight = pictureHeight;
+ k.mParameters.pictureWidth = pictureWidth;
+ k.mParameters.pictureHeight = pictureHeight;
- mParameters.jpegThumbSize[0] = jpegThumbSize[0];
- mParameters.jpegThumbSize[1] = jpegThumbSize[1];
- mParameters.jpegQuality = jpegQuality;
- mParameters.jpegThumbQuality = jpegThumbQuality;
+ k.mParameters.jpegThumbSize[0] = jpegThumbSize[0];
+ k.mParameters.jpegThumbSize[1] = jpegThumbSize[1];
+ k.mParameters.jpegQuality = jpegQuality;
+ k.mParameters.jpegThumbQuality = jpegThumbQuality;
- mParameters.gpsEnabled = gpsEnabled;
- mParameters.gpsCoordinates[0] = gpsCoordinates[0];
- mParameters.gpsCoordinates[1] = gpsCoordinates[1];
- mParameters.gpsCoordinates[2] = gpsCoordinates[2];
- mParameters.gpsTimestamp = gpsTimestamp;
- mParameters.gpsProcessingMethod = gpsProcessingMethod;
+ k.mParameters.gpsEnabled = gpsEnabled;
+ k.mParameters.gpsCoordinates[0] = gpsCoordinates[0];
+ k.mParameters.gpsCoordinates[1] = gpsCoordinates[1];
+ k.mParameters.gpsCoordinates[2] = gpsCoordinates[2];
+ k.mParameters.gpsTimestamp = gpsTimestamp;
+ k.mParameters.gpsProcessingMethod = gpsProcessingMethod;
- mParameters.wbMode = wbMode;
- mParameters.effectMode = effectMode;
- mParameters.antibandingMode = antibandingMode;
- mParameters.sceneMode = sceneMode;
+ k.mParameters.wbMode = wbMode;
+ k.mParameters.effectMode = effectMode;
+ k.mParameters.antibandingMode = antibandingMode;
+ k.mParameters.sceneMode = sceneMode;
- mParameters.flashMode = flashMode;
- mParameters.focusMode = focusMode;
+ k.mParameters.flashMode = flashMode;
+ k.mParameters.focusMode = focusMode;
- mParameters.focusingAreas = focusingAreas;
- mParameters.exposureCompensation = exposureCompensation;
- mParameters.autoExposureLock = autoExposureLock;
- mParameters.autoWhiteBalanceLock = autoWhiteBalanceLock;
- mParameters.meteringAreas = meteringAreas;
- mParameters.zoom = zoom;
+ k.mParameters.focusingAreas = focusingAreas;
+ k.mParameters.exposureCompensation = exposureCompensation;
+ k.mParameters.autoExposureLock = autoExposureLock;
+ k.mParameters.autoWhiteBalanceLock = autoWhiteBalanceLock;
+ k.mParameters.meteringAreas = meteringAreas;
+ k.mParameters.zoom = zoom;
- mParameters.videoWidth = videoWidth;
- mParameters.videoHeight = videoHeight;
+ k.mParameters.videoWidth = videoWidth;
+ k.mParameters.videoHeight = videoHeight;
- mParameters.recordingHint = recordingHint;
- mParameters.videoStabilization = videoStabilization;
+ k.mParameters.recordingHint = recordingHint;
+ k.mParameters.videoStabilization = videoStabilization;
- res = updatePreviewRequest();
+ res = updatePreviewRequest(k.mParameters);
if (res != OK) {
ALOGE("%s: Camera %d: Unable to update preview request: %s (%d)",
__FUNCTION__, mCameraId, strerror(-res), res);
return res;
}
- res = updateCaptureRequest();
+ res = updateCaptureRequest(k.mParameters);
if (res != OK) {
ALOGE("%s: Camera %d: Unable to update capture request: %s (%d)",
__FUNCTION__, mCameraId, strerror(-res), res);
return res;
}
- res = updateRecordingRequest();
+ res = updateRecordingRequest(k.mParameters);
if (res != OK) {
ALOGE("%s: Camera %d: Unable to update recording request: %s (%d)",
__FUNCTION__, mCameraId, strerror(-res), res);
@@ -1436,7 +1449,7 @@
}
}
- mParamsFlattened = params;
+ k.mParameters.paramsFlattened = params;
return OK;
}
@@ -1445,10 +1458,10 @@
ATRACE_CALL();
Mutex::Autolock icl(mICameraLock);
- Mutex::Autolock pl(mParamsLock);
+ LockedParameters::ReadKey k(mParameters);
// TODO: Deal with focus distances
- return mParamsFlattened;
+ return k.mParameters.paramsFlattened;
}
status_t Camera2Client::sendCommand(int32_t cmd, int32_t arg1, int32_t arg2) {
@@ -1459,6 +1472,7 @@
cmd, arg1, arg2);
if (cmd == CAMERA_CMD_SET_DISPLAY_ORIENTATION) {
+ LockedParameters::Key k(mParameters);
int transform = degToTransform(arg1,
mCameraFacing == CAMERA_FACING_FRONT);
if (transform == -1) {
@@ -1466,11 +1480,11 @@
__FUNCTION__, mCameraId, arg1);
return BAD_VALUE;
}
- if (transform != mParameters.previewTransform &&
+ if (transform != k.mParameters.previewTransform &&
mPreviewStreamId != NO_STREAM) {
mDevice->setStreamTransform(mPreviewStreamId, transform);
}
- mParameters.previewTransform = transform;
+ k.mParameters.previewTransform = transform;
return OK;
}
@@ -1673,7 +1687,7 @@
status_t Camera2Client::buildDefaultParameters() {
ATRACE_CALL();
- Mutex::Autolock pl(mParamsLock);
+ LockedParameters::Key k(mParameters);
status_t res;
CameraParameters params;
@@ -1683,16 +1697,16 @@
if (!availableProcessedSizes.count) return NO_INIT;
// TODO: Pick more intelligently
- mParameters.previewWidth = availableProcessedSizes.data.i32[0];
- mParameters.previewHeight = availableProcessedSizes.data.i32[1];
- mParameters.videoWidth = mParameters.previewWidth;
- mParameters.videoHeight = mParameters.previewHeight;
+ k.mParameters.previewWidth = availableProcessedSizes.data.i32[0];
+ k.mParameters.previewHeight = availableProcessedSizes.data.i32[1];
+ k.mParameters.videoWidth = k.mParameters.previewWidth;
+ k.mParameters.videoHeight = k.mParameters.previewHeight;
- params.setPreviewSize(mParameters.previewWidth, mParameters.previewHeight);
- params.setVideoSize(mParameters.videoWidth, mParameters.videoHeight);
+ params.setPreviewSize(k.mParameters.previewWidth, k.mParameters.previewHeight);
+ params.setVideoSize(k.mParameters.videoWidth, k.mParameters.videoHeight);
params.set(CameraParameters::KEY_PREFERRED_PREVIEW_SIZE_FOR_VIDEO,
String8::format("%dx%d",
- mParameters.previewWidth, mParameters.previewHeight));
+ k.mParameters.previewWidth, k.mParameters.previewHeight));
{
String8 supportedPreviewSizes;
for (size_t i=0; i < availableProcessedSizes.count; i += 2) {
@@ -1711,13 +1725,13 @@
staticInfo(ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES, 2);
if (!availableFpsRanges.count) return NO_INIT;
- mParameters.previewFpsRange[0] = availableFpsRanges.data.i32[0];
- mParameters.previewFpsRange[1] = availableFpsRanges.data.i32[1];
+ k.mParameters.previewFpsRange[0] = availableFpsRanges.data.i32[0];
+ k.mParameters.previewFpsRange[1] = availableFpsRanges.data.i32[1];
params.set(CameraParameters::KEY_PREVIEW_FPS_RANGE,
String8::format("%d,%d",
- mParameters.previewFpsRange[0],
- mParameters.previewFpsRange[1]));
+ k.mParameters.previewFpsRange[0],
+ k.mParameters.previewFpsRange[1]));
{
String8 supportedPreviewFpsRange;
@@ -1731,11 +1745,11 @@
supportedPreviewFpsRange);
}
- mParameters.previewFormat = HAL_PIXEL_FORMAT_YCrCb_420_SP;
+ k.mParameters.previewFormat = HAL_PIXEL_FORMAT_YCrCb_420_SP;
params.set(CameraParameters::KEY_PREVIEW_FORMAT,
- formatEnumToString(mParameters.previewFormat)); // NV21
+ formatEnumToString(k.mParameters.previewFormat)); // NV21
- mParameters.previewTransform = degToTransform(0,
+ k.mParameters.previewTransform = degToTransform(0,
mCameraFacing == CAMERA_FACING_FRONT);
camera_metadata_entry_t availableFormats =
@@ -1793,7 +1807,7 @@
// still have to do something sane for them
params.set(CameraParameters::KEY_PREVIEW_FRAME_RATE,
- mParameters.previewFpsRange[0]);
+ k.mParameters.previewFpsRange[0]);
{
String8 supportedPreviewFrameRates;
@@ -1811,11 +1825,11 @@
if (!availableJpegSizes.count) return NO_INIT;
// TODO: Pick maximum
- mParameters.pictureWidth = availableJpegSizes.data.i32[0];
- mParameters.pictureHeight = availableJpegSizes.data.i32[1];
+ k.mParameters.pictureWidth = availableJpegSizes.data.i32[0];
+ k.mParameters.pictureHeight = availableJpegSizes.data.i32[1];
- params.setPictureSize(mParameters.pictureWidth,
- mParameters.pictureHeight);
+ params.setPictureSize(k.mParameters.pictureWidth,
+ k.mParameters.pictureHeight);
{
String8 supportedPictureSizes;
@@ -1838,13 +1852,13 @@
if (!availableJpegThumbnailSizes.count) return NO_INIT;
// TODO: Pick default thumbnail size sensibly
- mParameters.jpegThumbSize[0] = availableJpegThumbnailSizes.data.i32[0];
- mParameters.jpegThumbSize[1] = availableJpegThumbnailSizes.data.i32[1];
+ k.mParameters.jpegThumbSize[0] = availableJpegThumbnailSizes.data.i32[0];
+ k.mParameters.jpegThumbSize[1] = availableJpegThumbnailSizes.data.i32[1];
params.set(CameraParameters::KEY_JPEG_THUMBNAIL_WIDTH,
- mParameters.jpegThumbSize[0]);
+ k.mParameters.jpegThumbSize[0]);
params.set(CameraParameters::KEY_JPEG_THUMBNAIL_HEIGHT,
- mParameters.jpegThumbSize[1]);
+ k.mParameters.jpegThumbSize[1]);
{
String8 supportedJpegThumbSizes;
@@ -1858,21 +1872,21 @@
supportedJpegThumbSizes);
}
- mParameters.jpegThumbQuality = 90;
+ k.mParameters.jpegThumbQuality = 90;
params.set(CameraParameters::KEY_JPEG_THUMBNAIL_QUALITY,
- mParameters.jpegThumbQuality);
- mParameters.jpegQuality = 90;
+ k.mParameters.jpegThumbQuality);
+ k.mParameters.jpegQuality = 90;
params.set(CameraParameters::KEY_JPEG_QUALITY,
- mParameters.jpegQuality);
- mParameters.jpegRotation = 0;
+ k.mParameters.jpegQuality);
+ k.mParameters.jpegRotation = 0;
params.set(CameraParameters::KEY_ROTATION,
- mParameters.jpegRotation);
+ k.mParameters.jpegRotation);
- mParameters.gpsEnabled = false;
- mParameters.gpsProcessingMethod = "unknown";
+ k.mParameters.gpsEnabled = false;
+ k.mParameters.gpsProcessingMethod = "unknown";
// GPS fields in CameraParameters are not set by implementation
- mParameters.wbMode = ANDROID_CONTROL_AWB_AUTO;
+ k.mParameters.wbMode = ANDROID_CONTROL_AWB_AUTO;
params.set(CameraParameters::KEY_WHITE_BALANCE,
CameraParameters::WHITE_BALANCE_AUTO);
@@ -1933,7 +1947,7 @@
supportedWhiteBalance);
}
- mParameters.effectMode = ANDROID_CONTROL_EFFECT_OFF;
+ k.mParameters.effectMode = ANDROID_CONTROL_EFFECT_OFF;
params.set(CameraParameters::KEY_EFFECT,
CameraParameters::EFFECT_NONE);
@@ -1993,7 +2007,7 @@
params.set(CameraParameters::KEY_SUPPORTED_EFFECTS, supportedEffects);
}
- mParameters.antibandingMode = ANDROID_CONTROL_AE_ANTIBANDING_AUTO;
+ k.mParameters.antibandingMode = ANDROID_CONTROL_AE_ANTIBANDING_AUTO;
params.set(CameraParameters::KEY_ANTIBANDING,
CameraParameters::ANTIBANDING_AUTO);
@@ -2035,7 +2049,7 @@
supportedAntibanding);
}
- mParameters.sceneMode = ANDROID_CONTROL_OFF;
+ k.mParameters.sceneMode = ANDROID_CONTROL_OFF;
params.set(CameraParameters::KEY_SCENE_MODE,
CameraParameters::SCENE_MODE_AUTO);
@@ -2140,7 +2154,7 @@
if (!availableAeModes.count) return NO_INIT;
if (flashAvailable.data.u8[0]) {
- mParameters.flashMode = Parameters::FLASH_MODE_AUTO;
+ k.mParameters.flashMode = Parameters::FLASH_MODE_AUTO;
params.set(CameraParameters::KEY_FLASH_MODE,
CameraParameters::FLASH_MODE_AUTO);
@@ -2160,7 +2174,7 @@
params.set(CameraParameters::KEY_SUPPORTED_FLASH_MODES,
supportedFlashModes);
} else {
- mParameters.flashMode = Parameters::FLASH_MODE_OFF;
+ k.mParameters.flashMode = Parameters::FLASH_MODE_OFF;
params.set(CameraParameters::KEY_FLASH_MODE,
CameraParameters::FLASH_MODE_OFF);
params.set(CameraParameters::KEY_SUPPORTED_FLASH_MODES,
@@ -2177,13 +2191,13 @@
if (minFocusDistance.data.f[0] == 0) {
// Fixed-focus lens
- mParameters.focusMode = Parameters::FOCUS_MODE_FIXED;
+ k.mParameters.focusMode = Parameters::FOCUS_MODE_FIXED;
params.set(CameraParameters::KEY_FOCUS_MODE,
CameraParameters::FOCUS_MODE_FIXED);
params.set(CameraParameters::KEY_SUPPORTED_FOCUS_MODES,
CameraParameters::FOCUS_MODE_FIXED);
} else {
- mParameters.focusMode = Parameters::FOCUS_MODE_AUTO;
+ k.mParameters.focusMode = Parameters::FOCUS_MODE_AUTO;
params.set(CameraParameters::KEY_FOCUS_MODE,
CameraParameters::FOCUS_MODE_AUTO);
String8 supportedFocusModes(CameraParameters::FOCUS_MODE_FIXED);
@@ -2238,8 +2252,8 @@
max3aRegions.data.i32[0]);
params.set(CameraParameters::KEY_FOCUS_AREAS,
"(0,0,0,0,0)");
- mParameters.focusingAreas.clear();
- mParameters.focusingAreas.add(Parameters::Area(0,0,0,0,0));
+ k.mParameters.focusingAreas.clear();
+ k.mParameters.focusingAreas.add(Parameters::Area(0,0,0,0,0));
camera_metadata_entry_t availableFocalLengths =
staticInfo(ANDROID_LENS_AVAILABLE_FOCAL_LENGTHS);
@@ -2260,9 +2274,9 @@
params.setFloat(CameraParameters::KEY_HORIZONTAL_VIEW_ANGLE, horizFov);
params.setFloat(CameraParameters::KEY_VERTICAL_VIEW_ANGLE, vertFov);
- mParameters.exposureCompensation = 0;
+ k.mParameters.exposureCompensation = 0;
params.set(CameraParameters::KEY_EXPOSURE_COMPENSATION,
- mParameters.exposureCompensation);
+ k.mParameters.exposureCompensation);
camera_metadata_entry_t exposureCompensationRange =
staticInfo(ANDROID_CONTROL_AE_EXP_COMPENSATION_RANGE, 2, 2);
@@ -2281,26 +2295,26 @@
exposureCompensationStep.data.r[0].numerator /
exposureCompensationStep.data.r[0].denominator);
- mParameters.autoExposureLock = false;
+ k.mParameters.autoExposureLock = false;
params.set(CameraParameters::KEY_AUTO_EXPOSURE_LOCK,
CameraParameters::FALSE);
params.set(CameraParameters::KEY_AUTO_EXPOSURE_LOCK_SUPPORTED,
CameraParameters::TRUE);
- mParameters.autoWhiteBalanceLock = false;
+ k.mParameters.autoWhiteBalanceLock = false;
params.set(CameraParameters::KEY_AUTO_WHITEBALANCE_LOCK,
CameraParameters::FALSE);
params.set(CameraParameters::KEY_AUTO_WHITEBALANCE_LOCK_SUPPORTED,
CameraParameters::TRUE);
- mParameters.meteringAreas.add(Parameters::Area(0, 0, 0, 0, 0));
+ k.mParameters.meteringAreas.add(Parameters::Area(0, 0, 0, 0, 0));
params.set(CameraParameters::KEY_MAX_NUM_METERING_AREAS,
max3aRegions.data.i32[0]);
params.set(CameraParameters::KEY_METERING_AREAS,
"(0,0,0,0,0)");
- mParameters.zoom = 0;
- params.set(CameraParameters::KEY_ZOOM, mParameters.zoom);
+ k.mParameters.zoom = 0;
+ params.set(CameraParameters::KEY_ZOOM, k.mParameters.zoom);
params.set(CameraParameters::KEY_MAX_ZOOM, NUM_ZOOM_STEPS - 1);
camera_metadata_entry_t maxDigitalZoom =
@@ -2362,16 +2376,17 @@
}
// Always use metadata mode for recording
- mParameters.storeMetadataInBuffers = true;
+ k.mParameters.storeMetadataInBuffers = true;
- mParamsFlattened = params.flatten();
+ k.mParameters.paramsFlattened = params.flatten();
return OK;
}
-status_t Camera2Client::updatePreviewStream() {
+status_t Camera2Client::updatePreviewStream(const Parameters ¶ms) {
ATRACE_CALL();
status_t res;
+
if (mPreviewStreamId != NO_STREAM) {
// Check if stream parameters have to change
uint32_t currentWidth, currentHeight;
@@ -2382,11 +2397,11 @@
"%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
return res;
}
- if (currentWidth != (uint32_t)mParameters.previewWidth ||
- currentHeight != (uint32_t)mParameters.previewHeight) {
+ if (currentWidth != (uint32_t)params.previewWidth ||
+ currentHeight != (uint32_t)params.previewHeight) {
ALOGV("%s: Camera %d: Preview size switch: %d x %d -> %d x %d",
__FUNCTION__, mCameraId, currentWidth, currentHeight,
- mParameters.previewWidth, mParameters.previewHeight);
+ params.previewWidth, params.previewHeight);
res = mDevice->waitUntilDrained();
if (res != OK) {
ALOGE("%s: Camera %d: Error waiting for preview to drain: "
@@ -2406,7 +2421,7 @@
if (mPreviewStreamId == NO_STREAM) {
res = mDevice->createStream(mPreviewWindow,
- mParameters.previewWidth, mParameters.previewHeight,
+ params.previewWidth, params.previewHeight,
CAMERA2_HAL_PIXEL_FORMAT_OPAQUE, 0,
&mPreviewStreamId);
if (res != OK) {
@@ -2417,7 +2432,7 @@
}
res = mDevice->setStreamTransform(mPreviewStreamId,
- mParameters.previewTransform);
+ params.previewTransform);
if (res != OK) {
ALOGE("%s: Camera %d: Unable to set preview stream transform: "
"%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
@@ -2427,7 +2442,7 @@
return OK;
}
-status_t Camera2Client::updatePreviewRequest() {
+status_t Camera2Client::updatePreviewRequest(const Parameters ¶ms) {
ATRACE_CALL();
status_t res;
if (mPreviewRequest == NULL) {
@@ -2440,7 +2455,7 @@
}
}
- res = updateRequestCommon(mPreviewRequest);
+ res = updateRequestCommon(mPreviewRequest, params);
if (res != OK) {
ALOGE("%s: Camera %d: Unable to update common entries of preview "
"request: %s (%d)", __FUNCTION__, mCameraId,
@@ -2451,7 +2466,7 @@
return OK;
}
-status_t Camera2Client::updateCaptureStream() {
+status_t Camera2Client::updateCaptureStream(const Parameters ¶ms) {
ATRACE_CALL();
status_t res;
// Find out buffer size for JPEG
@@ -2490,8 +2505,8 @@
"%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
return res;
}
- if (currentWidth != (uint32_t)mParameters.pictureWidth ||
- currentHeight != (uint32_t)mParameters.pictureHeight) {
+ if (currentWidth != (uint32_t)params.pictureWidth ||
+ currentHeight != (uint32_t)params.pictureHeight) {
res = mDevice->deleteStream(mCaptureStreamId);
if (res != OK) {
ALOGE("%s: Camera %d: Unable to delete old output stream "
@@ -2506,7 +2521,7 @@
if (mCaptureStreamId == NO_STREAM) {
// Create stream for HAL production
res = mDevice->createStream(mCaptureWindow,
- mParameters.pictureWidth, mParameters.pictureHeight,
+ params.pictureWidth, params.pictureHeight,
HAL_PIXEL_FORMAT_BLOB, maxJpegSize.data.i32[0],
&mCaptureStreamId);
if (res != OK) {
@@ -2519,7 +2534,7 @@
return OK;
}
-status_t Camera2Client::updateCaptureRequest() {
+status_t Camera2Client::updateCaptureRequest(const Parameters ¶ms) {
ATRACE_CALL();
status_t res;
if (mCaptureRequest == NULL) {
@@ -2532,7 +2547,7 @@
}
}
- res = updateRequestCommon(mCaptureRequest);
+ res = updateRequestCommon(mCaptureRequest, params);
if (res != OK) {
ALOGE("%s: Camera %d: Unable to update common entries of capture "
"request: %s (%d)", __FUNCTION__, mCameraId,
@@ -2542,34 +2557,34 @@
res = updateEntry(mCaptureRequest,
ANDROID_JPEG_THUMBNAIL_SIZE,
- mParameters.jpegThumbSize, 2);
+ params.jpegThumbSize, 2);
if (res != OK) return res;
res = updateEntry(mCaptureRequest,
ANDROID_JPEG_THUMBNAIL_QUALITY,
- &mParameters.jpegThumbQuality, 1);
+ ¶ms.jpegThumbQuality, 1);
if (res != OK) return res;
res = updateEntry(mCaptureRequest,
ANDROID_JPEG_QUALITY,
- &mParameters.jpegQuality, 1);
+ ¶ms.jpegQuality, 1);
if (res != OK) return res;
res = updateEntry(mCaptureRequest,
ANDROID_JPEG_ORIENTATION,
- &mParameters.jpegRotation, 1);
+ ¶ms.jpegRotation, 1);
if (res != OK) return res;
- if (mParameters.gpsEnabled) {
+ if (params.gpsEnabled) {
res = updateEntry(mCaptureRequest,
ANDROID_JPEG_GPS_COORDINATES,
- mParameters.gpsCoordinates, 3);
+ params.gpsCoordinates, 3);
if (res != OK) return res;
res = updateEntry(mCaptureRequest,
ANDROID_JPEG_GPS_TIMESTAMP,
- &mParameters.gpsTimestamp, 1);
+ ¶ms.gpsTimestamp, 1);
if (res != OK) return res;
res = updateEntry(mCaptureRequest,
ANDROID_JPEG_GPS_PROCESSING_METHOD,
- mParameters.gpsProcessingMethod.string(),
- mParameters.gpsProcessingMethod.size());
+ params.gpsProcessingMethod.string(),
+ params.gpsProcessingMethod.size());
if (res != OK) return res;
} else {
res = deleteEntry(mCaptureRequest,
@@ -2586,7 +2601,7 @@
return OK;
}
-status_t Camera2Client::updateRecordingRequest() {
+status_t Camera2Client::updateRecordingRequest(const Parameters ¶ms) {
ATRACE_CALL();
status_t res;
if (mRecordingRequest == NULL) {
@@ -2599,7 +2614,7 @@
}
}
- res = updateRequestCommon(mRecordingRequest);
+ res = updateRequestCommon(mRecordingRequest, params);
if (res != OK) {
ALOGE("%s: Camera %d: Unable to update common entries of recording "
"request: %s (%d)", __FUNCTION__, mCameraId,
@@ -2610,7 +2625,7 @@
return OK;
}
-status_t Camera2Client::updateRecordingStream() {
+status_t Camera2Client::updateRecordingStream(const Parameters ¶ms) {
status_t res;
if (mRecordingConsumer == 0) {
@@ -2633,8 +2648,8 @@
"%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
return res;
}
- if (currentWidth != (uint32_t)mParameters.videoWidth ||
- currentHeight != (uint32_t)mParameters.videoHeight) {
+ if (currentWidth != (uint32_t)params.videoWidth ||
+ currentHeight != (uint32_t)params.videoHeight) {
// TODO: Should wait to be sure previous recording has finished
res = mDevice->deleteStream(mRecordingStreamId);
if (res != OK) {
@@ -2649,7 +2664,7 @@
if (mRecordingStreamId == NO_STREAM) {
res = mDevice->createStream(mRecordingWindow,
- mParameters.videoWidth, mParameters.videoHeight,
+ params.videoWidth, params.videoHeight,
CAMERA2_HAL_PIXEL_FORMAT_OPAQUE, 0, &mRecordingStreamId);
if (res != OK) {
ALOGE("%s: Camera %d: Can't create output stream for recording: "
@@ -2661,28 +2676,29 @@
return OK;
}
-status_t Camera2Client::updateRequestCommon(camera_metadata_t *request) {
+status_t Camera2Client::updateRequestCommon(camera_metadata_t *request,
+ const Parameters ¶ms) {
ATRACE_CALL();
status_t res;
res = updateEntry(request,
- ANDROID_CONTROL_AE_TARGET_FPS_RANGE, mParameters.previewFpsRange, 2);
+ ANDROID_CONTROL_AE_TARGET_FPS_RANGE, params.previewFpsRange, 2);
if (res != OK) return res;
- uint8_t wbMode = mParameters.autoWhiteBalanceLock ?
- ANDROID_CONTROL_AWB_LOCKED : mParameters.wbMode;
+ uint8_t wbMode = params.autoWhiteBalanceLock ?
+ ANDROID_CONTROL_AWB_LOCKED : params.wbMode;
res = updateEntry(request,
ANDROID_CONTROL_AWB_MODE, &wbMode, 1);
if (res != OK) return res;
res = updateEntry(request,
- ANDROID_CONTROL_EFFECT_MODE, &mParameters.effectMode, 1);
+ ANDROID_CONTROL_EFFECT_MODE, ¶ms.effectMode, 1);
if (res != OK) return res;
res = updateEntry(request,
ANDROID_CONTROL_AE_ANTIBANDING_MODE,
- &mParameters.antibandingMode, 1);
+ ¶ms.antibandingMode, 1);
if (res != OK) return res;
uint8_t controlMode =
- (mParameters.sceneMode == ANDROID_CONTROL_SCENE_MODE_UNSUPPORTED) ?
+ (params.sceneMode == ANDROID_CONTROL_SCENE_MODE_UNSUPPORTED) ?
ANDROID_CONTROL_AUTO : ANDROID_CONTROL_USE_SCENE_MODE;
res = updateEntry(request,
ANDROID_CONTROL_MODE, &controlMode, 1);
@@ -2690,13 +2706,13 @@
if (controlMode == ANDROID_CONTROL_USE_SCENE_MODE) {
res = updateEntry(request,
ANDROID_CONTROL_SCENE_MODE,
- &mParameters.sceneMode, 1);
+ ¶ms.sceneMode, 1);
if (res != OK) return res;
}
uint8_t flashMode = ANDROID_FLASH_OFF;
uint8_t aeMode;
- switch (mParameters.flashMode) {
+ switch (params.flashMode) {
case Parameters::FLASH_MODE_OFF:
aeMode = ANDROID_CONTROL_AE_ON; break;
case Parameters::FLASH_MODE_AUTO:
@@ -2711,10 +2727,10 @@
aeMode = ANDROID_CONTROL_AE_ON_AUTO_FLASH_REDEYE; break;
default:
ALOGE("%s: Camera %d: Unknown flash mode %d", __FUNCTION__,
- mCameraId, mParameters.flashMode);
+ mCameraId, params.flashMode);
return BAD_VALUE;
}
- if (mParameters.autoExposureLock) aeMode = ANDROID_CONTROL_AE_LOCKED;
+ if (params.autoExposureLock) aeMode = ANDROID_CONTROL_AE_LOCKED;
res = updateEntry(request,
ANDROID_FLASH_MODE, &flashMode, 1);
@@ -2725,13 +2741,13 @@
float focusDistance = 0; // infinity focus in diopters
uint8_t focusMode;
- switch (mParameters.focusMode) {
+ switch (params.focusMode) {
case Parameters::FOCUS_MODE_AUTO:
case Parameters::FOCUS_MODE_MACRO:
case Parameters::FOCUS_MODE_CONTINUOUS_VIDEO:
case Parameters::FOCUS_MODE_CONTINUOUS_PICTURE:
case Parameters::FOCUS_MODE_EDOF:
- focusMode = mParameters.focusMode;
+ focusMode = params.focusMode;
break;
case Parameters::FOCUS_MODE_INFINITY:
case Parameters::FOCUS_MODE_FIXED:
@@ -2739,7 +2755,7 @@
break;
default:
ALOGE("%s: Camera %d: Unknown focus mode %d", __FUNCTION__,
- mCameraId, mParameters.focusMode);
+ mCameraId, params.focusMode);
return BAD_VALUE;
}
res = updateEntry(request,
@@ -2749,14 +2765,14 @@
ANDROID_CONTROL_AF_MODE, &focusMode, 1);
if (res != OK) return res;
- size_t focusingAreasSize = mParameters.focusingAreas.size() * 5;
+ size_t focusingAreasSize = params.focusingAreas.size() * 5;
int32_t *focusingAreas = new int32_t[focusingAreasSize];
for (size_t i = 0; i < focusingAreasSize; i += 5) {
- focusingAreas[i + 0] = mParameters.focusingAreas[i].left;
- focusingAreas[i + 1] = mParameters.focusingAreas[i].top;
- focusingAreas[i + 2] = mParameters.focusingAreas[i].right;
- focusingAreas[i + 3] = mParameters.focusingAreas[i].bottom;
- focusingAreas[i + 4] = mParameters.focusingAreas[i].weight;
+ focusingAreas[i + 0] = params.focusingAreas[i].left;
+ focusingAreas[i + 1] = params.focusingAreas[i].top;
+ focusingAreas[i + 2] = params.focusingAreas[i].right;
+ focusingAreas[i + 3] = params.focusingAreas[i].bottom;
+ focusingAreas[i + 4] = params.focusingAreas[i].weight;
}
res = updateEntry(request,
ANDROID_CONTROL_AF_REGIONS, focusingAreas,focusingAreasSize);
@@ -2765,17 +2781,17 @@
res = updateEntry(request,
ANDROID_CONTROL_AE_EXP_COMPENSATION,
- &mParameters.exposureCompensation, 1);
+ ¶ms.exposureCompensation, 1);
if (res != OK) return res;
- size_t meteringAreasSize = mParameters.meteringAreas.size() * 5;
+ size_t meteringAreasSize = params.meteringAreas.size() * 5;
int32_t *meteringAreas = new int32_t[meteringAreasSize];
for (size_t i = 0; i < meteringAreasSize; i += 5) {
- meteringAreas[i + 0] = mParameters.meteringAreas[i].left;
- meteringAreas[i + 1] = mParameters.meteringAreas[i].top;
- meteringAreas[i + 2] = mParameters.meteringAreas[i].right;
- meteringAreas[i + 3] = mParameters.meteringAreas[i].bottom;
- meteringAreas[i + 4] = mParameters.meteringAreas[i].weight;
+ meteringAreas[i + 0] = params.meteringAreas[i].left;
+ meteringAreas[i + 1] = params.meteringAreas[i].top;
+ meteringAreas[i + 2] = params.meteringAreas[i].right;
+ meteringAreas[i + 3] = params.meteringAreas[i].bottom;
+ meteringAreas[i + 4] = params.meteringAreas[i].weight;
}
res = updateEntry(request,
ANDROID_CONTROL_AE_REGIONS, meteringAreas, meteringAreasSize);
@@ -2793,21 +2809,21 @@
staticInfo(ANDROID_SCALER_AVAILABLE_MAX_ZOOM);
float zoomIncrement = (maxDigitalZoom.data.f[0] - 1) /
(NUM_ZOOM_STEPS-1);
- float zoomRatio = 1 + zoomIncrement * mParameters.zoom;
+ float zoomRatio = 1 + zoomIncrement * params.zoom;
camera_metadata_entry_t activePixelArraySize =
staticInfo(ANDROID_SENSOR_ACTIVE_ARRAY_SIZE, 2, 2);
int32_t arrayWidth = activePixelArraySize.data.i32[0];
int32_t arrayHeight = activePixelArraySize.data.i32[1];
float zoomLeft, zoomTop, zoomWidth, zoomHeight;
- if (mParameters.previewWidth >= mParameters.previewHeight) {
+ if (params.previewWidth >= params.previewHeight) {
zoomWidth = arrayWidth / zoomRatio;
zoomHeight = zoomWidth *
- mParameters.previewHeight / mParameters.previewWidth;
+ params.previewHeight / params.previewWidth;
} else {
zoomHeight = arrayHeight / zoomRatio;
zoomWidth = zoomHeight *
- mParameters.previewWidth / mParameters.previewHeight;
+ params.previewWidth / params.previewHeight;
}
zoomLeft = (arrayWidth - zoomWidth) / 2;
zoomTop = (arrayHeight - zoomHeight) / 2;
@@ -2819,7 +2835,7 @@
// TODO: Decide how to map recordingHint, or whether just to ignore it
- uint8_t vstabMode = mParameters.videoStabilization ?
+ uint8_t vstabMode = params.videoStabilization ?
ANDROID_CONTROL_VIDEO_STABILIZATION_ON :
ANDROID_CONTROL_VIDEO_STABILIZATION_OFF;
res = updateEntry(request,
@@ -2873,6 +2889,7 @@
}
return res;
}
+
int Camera2Client::formatStringToEnum(const char *format) {
return
!strcmp(format, CameraParameters::PIXEL_FORMAT_YUV422SP) ?
diff --git a/services/camera/libcameraservice/Camera2Client.h b/services/camera/libcameraservice/Camera2Client.h
index 83fe94e..3494114 100644
--- a/services/camera/libcameraservice/Camera2Client.h
+++ b/services/camera/libcameraservice/Camera2Client.h
@@ -89,7 +89,7 @@
// Ensures serialization between incoming ICamera calls
mutable Mutex mICameraLock;
- // The following must be called with mICamaeraLock already locked
+ // The following must be called with mICameraLock already locked
status_t setPreviewWindowLocked(const sp<IBinder>& binder,
sp<ANativeWindow> window);
@@ -97,9 +97,6 @@
void stopPreviewLocked();
status_t startPreviewLocked();
- // Mutex that must be locked before accessing mParameters, mParamsFlattened
- mutable Mutex mParamsLock;
- String8 mParamsFlattened;
// Current camera state; this is the contents of the CameraParameters object
// in a more-efficient format. The enum values are mostly based off the
// corresponding camera2 enums, not the camera1 strings. A few are defined
@@ -173,6 +170,59 @@
bool videoStabilization;
bool storeMetadataInBuffers;
+
+ String8 paramsFlattened;
+ };
+
+ class LockedParameters {
+ public:
+ class Key {
+ public:
+ Key(LockedParameters &p):
+ mParameters(p.mParameters),
+ mLockedParameters(p) {
+ mLockedParameters.mLock.lock();
+ }
+
+ ~Key() {
+ mLockedParameters.mLock.unlock();
+ }
+ Parameters &mParameters;
+ private:
+ // Disallow copying, default construction
+ Key();
+ Key(const Key &);
+ Key &operator=(const Key &);
+ LockedParameters &mLockedParameters;
+ };
+ class ReadKey {
+ public:
+ ReadKey(const LockedParameters &p):
+ mParameters(p.mParameters),
+ mLockedParameters(p) {
+ mLockedParameters.mLock.lock();
+ }
+
+ ~ReadKey() {
+ mLockedParameters.mLock.unlock();
+ }
+ const Parameters &mParameters;
+ private:
+ // Disallow copying, default construction
+ ReadKey();
+ ReadKey(const ReadKey &);
+ ReadKey &operator=(const ReadKey &);
+ const LockedParameters &mLockedParameters;
+ };
+
+ // Only use for dumping or other debugging
+ const Parameters &unsafeUnlock() {
+ return mParameters;
+ }
+ private:
+ Parameters mParameters;
+ mutable Mutex mLock;
+
} mParameters;
/** Camera device-related private members */
@@ -190,10 +240,9 @@
camera_metadata_t *mPreviewRequest;
sp<IBinder> mPreviewSurface;
sp<ANativeWindow> mPreviewWindow;
- // Update preview request based on mParameters
- status_t updatePreviewRequest();
- // Update preview stream based on mParameters
- status_t updatePreviewStream();
+
+ status_t updatePreviewRequest(const Parameters ¶ms);
+ status_t updatePreviewStream(const Parameters ¶ms);
/* Still image capture related members */
@@ -214,10 +263,9 @@
sp<Camera2Heap> mCaptureHeap;
// Handle captured image buffers
void onCaptureAvailable();
- // Update capture request based on mParameters
- status_t updateCaptureRequest();
- // Update capture stream based on mParameters
- status_t updateCaptureStream();
+
+ status_t updateCaptureRequest(const Parameters ¶ms);
+ status_t updateCaptureStream(const Parameters ¶ms);
/* Recording related members */
@@ -244,10 +292,9 @@
size_t mRecordingHeapHead, mRecordingHeapFree;
// Handle new recording image buffers
void onRecordingFrameAvailable();
- // Update recording request based on mParameters
- status_t updateRecordingRequest();
- // Update recording stream based on mParameters
- status_t updateRecordingStream();
+
+ status_t updateRecordingRequest(const Parameters ¶ms);
+ status_t updateRecordingStream(const Parameters ¶ms);
/** Camera2Device instance wrapping HAL2 entry */
@@ -293,7 +340,7 @@
status_t buildDefaultParameters();
// Update parameters all requests use, based on mParameters
- status_t updateRequestCommon(camera_metadata_t *request);
+ status_t updateRequestCommon(camera_metadata_t *request, const Parameters ¶ms);
// Update specific metadata entry with new values. Adds entry if it does not
// exist, which will invalidate sorting
diff --git a/services/camera/libcameraservice/Camera2Device.cpp b/services/camera/libcameraservice/Camera2Device.cpp
index f42e3a5..d760313 100644
--- a/services/camera/libcameraservice/Camera2Device.cpp
+++ b/services/camera/libcameraservice/Camera2Device.cpp
@@ -120,7 +120,7 @@
result.appendFormat(" Static camera information metadata:\n");
write(fd, result.string(), result.size());
- dump_camera_metadata(mDeviceInfo, fd, 2);
+ dump_indented_camera_metadata(mDeviceInfo, fd, 2, 6);
result = " Request queue contents:\n";
write(fd, result.string(), result.size());
@@ -487,7 +487,7 @@
r != mStreamSlot.end(); r++) {
result = String8::format(" Stream slot buffer %d:\n", i);
write(fd, result.string(), result.size());
- dump_camera_metadata(*r, fd, 2);
+ dump_indented_camera_metadata(*r, fd, 2, 10);
i++;
}
}
@@ -502,7 +502,7 @@
r != mEntries.end(); r++) {
result = String8::format(" Queue entry %d:\n", i);
write(fd, result.string(), result.size());
- dump_camera_metadata(*r, fd, 2);
+ dump_indented_camera_metadata(*r, fd, 2, 10);
i++;
}
}
diff --git a/services/camera/libcameraservice/CameraService.cpp b/services/camera/libcameraservice/CameraService.cpp
index a83c28f..878afde 100644
--- a/services/camera/libcameraservice/CameraService.cpp
+++ b/services/camera/libcameraservice/CameraService.cpp
@@ -472,7 +472,8 @@
if (deviceVersion >= CAMERA_DEVICE_API_VERSION_2_0) {
result.appendFormat(" Device static metadata:\n");
write(fd, result.string(), result.size());
- dump_camera_metadata(info.static_camera_characteristics, fd, 2);
+ dump_indented_camera_metadata(info.static_camera_characteristics,
+ fd, 2, 4);
} else {
write(fd, result.string(), result.size());
}