From 879b73996c1911602308aeb84b708a5fb379e0ac Mon Sep 17 00:00:00 2001 From: Eric Laurent Date: Tue, 10 Dec 2013 17:20:46 -0800 Subject: Revert "stagefright: fix TimedEventQueue wakelock" This reverts commit aef04853de0ce27222cf6250b2ba4fa9fc6a72a8. --- media/libstagefright/TimedEventQueue.cpp | 11 ++++++----- media/libstagefright/include/TimedEventQueue.h | 12 ++---------- 2 files changed, 8 insertions(+), 15 deletions(-) diff --git a/media/libstagefright/TimedEventQueue.cpp b/media/libstagefright/TimedEventQueue.cpp index da23fea..1a9a26b 100644 --- a/media/libstagefright/TimedEventQueue.cpp +++ b/media/libstagefright/TimedEventQueue.cpp @@ -127,6 +127,7 @@ TimedEventQueue::event_id TimedEventQueue::postTimedEvent( QueueItem item; item.event = event; item.realtime_us = realtime_us; + item.has_wakelock = false; if (it == mQueue.begin()) { mQueueHeadChangedCondition.signal(); @@ -134,7 +135,7 @@ TimedEventQueue::event_id TimedEventQueue::postTimedEvent( if (realtime_us > ALooper::GetNowUs() + kWakelockMinDelay) { acquireWakeLock_l(); - event->setWakeLock(); + item.has_wakelock = true; } mQueue.insert(it, item); @@ -190,7 +191,7 @@ void TimedEventQueue::cancelEvents( ALOGV("cancelling event %d", (*it).event->eventID()); (*it).event->setEventID(0); - if ((*it).event->hasWakeLock()) { + if ((*it).has_wakelock) { releaseWakeLock_l(); } it = mQueue.erase(it); @@ -288,9 +289,6 @@ void TimedEventQueue::threadEntry() { if (event != NULL) { // Fire event with the lock NOT held. event->fire(this, now_us); - if (event->hasWakeLock()) { - releaseWakeLock_l(); - } } } } @@ -302,6 +300,9 @@ sp TimedEventQueue::removeEventFromQueue_l( if ((*it).event->eventID() == id) { sp event = (*it).event; event->setEventID(0); + if ((*it).has_wakelock) { + releaseWakeLock_l(); + } mQueue.erase(it); return event; } diff --git a/media/libstagefright/include/TimedEventQueue.h b/media/libstagefright/include/TimedEventQueue.h index 4e8912d..38a08b1 100644 --- a/media/libstagefright/include/TimedEventQueue.h +++ b/media/libstagefright/include/TimedEventQueue.h @@ -33,7 +33,7 @@ struct TimedEventQueue { struct Event : public RefBase { Event() - : mEventID(0), mHasWakeLock(false) { + : mEventID(0) { } virtual ~Event() {} @@ -42,14 +42,6 @@ struct TimedEventQueue { return mEventID; } - void setWakeLock() { - mHasWakeLock = true; - } - - bool hasWakeLock() { - return mHasWakeLock; - } - protected: virtual void fire(TimedEventQueue *queue, int64_t now_us) = 0; @@ -57,7 +49,6 @@ struct TimedEventQueue { friend class TimedEventQueue; event_id mEventID; - bool mHasWakeLock; void setEventID(event_id id) { mEventID = id; @@ -127,6 +118,7 @@ private: struct QueueItem { sp event; int64_t realtime_us; + bool has_wakelock; }; struct StopEvent : public TimedEventQueue::Event { -- cgit v1.1 From b1ead9cf519a267c4c67022d6c06f7e8fd708a04 Mon Sep 17 00:00:00 2001 From: Haynes Mathew George Date: Fri, 6 Dec 2013 11:31:57 -0800 Subject: libstagefright: Delay release of wakelock in TimedEventQueue Delay release of wakelock in the TimedEventQueue to after an event has been processed. This ensures AP shutdown does not happen while an event is ready but hasn't been processed yet. Bug: 11976087. Change-Id: I71a5f3ac4a57e1d05dd5d9ab5c6f91ed7bb64c87 --- media/libstagefright/TimedEventQueue.cpp | 13 ++++++++----- media/libstagefright/include/TimedEventQueue.h | 2 +- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/media/libstagefright/TimedEventQueue.cpp b/media/libstagefright/TimedEventQueue.cpp index 1a9a26b..dedd186 100644 --- a/media/libstagefright/TimedEventQueue.cpp +++ b/media/libstagefright/TimedEventQueue.cpp @@ -217,6 +217,7 @@ void TimedEventQueue::threadEntry() { for (;;) { int64_t now_us = 0; sp event; + bool wakeLocked = false; { Mutex::Autolock autoLock(mLock); @@ -283,26 +284,28 @@ void TimedEventQueue::threadEntry() { // removeEventFromQueue_l will return NULL. // Otherwise, the QueueItem will be removed // from the queue and the referenced event returned. - event = removeEventFromQueue_l(eventID); + event = removeEventFromQueue_l(eventID, &wakeLocked); } if (event != NULL) { // Fire event with the lock NOT held. event->fire(this, now_us); + if (wakeLocked) { + Mutex::Autolock autoLock(mLock); + releaseWakeLock_l(); + } } } } sp TimedEventQueue::removeEventFromQueue_l( - event_id id) { + event_id id, bool *wakeLocked) { for (List::iterator it = mQueue.begin(); it != mQueue.end(); ++it) { if ((*it).event->eventID() == id) { sp event = (*it).event; event->setEventID(0); - if ((*it).has_wakelock) { - releaseWakeLock_l(); - } + *wakeLocked = (*it).has_wakelock; mQueue.erase(it); return event; } diff --git a/media/libstagefright/include/TimedEventQueue.h b/media/libstagefright/include/TimedEventQueue.h index 38a08b1..3e84256 100644 --- a/media/libstagefright/include/TimedEventQueue.h +++ b/media/libstagefright/include/TimedEventQueue.h @@ -145,7 +145,7 @@ private: static void *ThreadWrapper(void *me); void threadEntry(); - sp removeEventFromQueue_l(event_id id); + sp removeEventFromQueue_l(event_id id, bool *wakeLocked); void acquireWakeLock_l(); void releaseWakeLock_l(bool force = false); -- cgit v1.1 From b5a3462c8b86e8d74025d1d650e3eb8dec8616b8 Mon Sep 17 00:00:00 2001 From: Brian Carlstrom Date: Thu, 30 Jan 2014 13:14:01 -0800 Subject: frameworks/av: Rename persist.sys.dalvik.vm.lib to allow new default Bug: 12798969 Change-Id: I2db14a7ee28db2449ec6e2384ade21944284528d --- cmds/screenrecord/Overlay.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmds/screenrecord/Overlay.cpp b/cmds/screenrecord/Overlay.cpp index 96e25b8..2e98874 100644 --- a/cmds/screenrecord/Overlay.cpp +++ b/cmds/screenrecord/Overlay.cpp @@ -47,7 +47,7 @@ const char* Overlay::kPropertyNames[] = { "ro.revision", "dalvik.vm.heapgrowthlimit", "dalvik.vm.heapsize", - "persist.sys.dalvik.vm.lib", + "persist.sys.dalvik.vm.lib.1", //"ro.product.cpu.abi", //"ro.bootloader", //"this-never-appears!", -- cgit v1.1 From a401354a8990fa3d01941de906603bf642df225b Mon Sep 17 00:00:00 2001 From: Andreas Huber Date: Mon, 10 Feb 2014 14:40:45 -0800 Subject: Support "data:" URIs again in mediaplayer... Change-Id: I6dac35c7e606f738a60f985f6dca977dc92c82a4 related-to-bug: 12957757 --- include/media/stagefright/DataURISource.h | 49 +++++++++++++ media/libstagefright/Android.mk | 1 + media/libstagefright/DataSource.cpp | 3 + media/libstagefright/DataURISource.cpp | 109 +++++++++++++++++++++++++++++ media/libstagefright/foundation/base64.cpp | 6 +- 5 files changed, 167 insertions(+), 1 deletion(-) create mode 100644 include/media/stagefright/DataURISource.h create mode 100644 media/libstagefright/DataURISource.cpp diff --git a/include/media/stagefright/DataURISource.h b/include/media/stagefright/DataURISource.h new file mode 100644 index 0000000..693562e --- /dev/null +++ b/include/media/stagefright/DataURISource.h @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef DATA_URI_SOURCE_H_ + +#define DATA_URI_SOURCE_H_ + +#include +#include + +namespace android { + +struct ABuffer; + +struct DataURISource : public DataSource { + static sp Create(const char *uri); + + virtual status_t initCheck() const; + virtual ssize_t readAt(off64_t offset, void *data, size_t size); + virtual status_t getSize(off64_t *size); + +protected: + virtual ~DataURISource(); + +private: + sp mBuffer; + + DataURISource(const sp &buffer); + + DISALLOW_EVIL_CONSTRUCTORS(DataURISource); +}; + +} // namespace android + +#endif // DATA_URI_SOURCE_H_ + diff --git a/media/libstagefright/Android.mk b/media/libstagefright/Android.mk index 63f9399..f94f136 100644 --- a/media/libstagefright/Android.mk +++ b/media/libstagefright/Android.mk @@ -15,6 +15,7 @@ LOCAL_SRC_FILES:= \ CameraSource.cpp \ CameraSourceTimeLapse.cpp \ DataSource.cpp \ + DataURISource.cpp \ DRMExtractor.cpp \ ESDS.cpp \ FileSource.cpp \ diff --git a/media/libstagefright/DataSource.cpp b/media/libstagefright/DataSource.cpp index 2704b74..6e0f37a 100644 --- a/media/libstagefright/DataSource.cpp +++ b/media/libstagefright/DataSource.cpp @@ -35,6 +35,7 @@ #include #include #include +#include #include #include #include @@ -221,6 +222,8 @@ sp DataSource::CreateFromURI( // in the widevine:// case. source = httpSource; } + } else if (!strncasecmp("data:", uri, 5)) { + source = DataURISource::Create(uri); } else { // Assume it's a filename. source = new FileSource(uri); diff --git a/media/libstagefright/DataURISource.cpp b/media/libstagefright/DataURISource.cpp new file mode 100644 index 0000000..377bc85 --- /dev/null +++ b/media/libstagefright/DataURISource.cpp @@ -0,0 +1,109 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include + +#include +#include +#include + +namespace android { + +// static +sp DataURISource::Create(const char *uri) { + if (strncasecmp("data:", uri, 5)) { + return NULL; + } + + char *commaPos = strrchr(uri, ','); + + if (commaPos == NULL) { + return NULL; + } + + sp buffer; + + AString tmp(&uri[5], commaPos - &uri[5]); + + if (tmp.endsWith(";base64")) { + AString encoded(commaPos + 1); + + // Strip CR and LF... + for (size_t i = encoded.size(); i-- > 0;) { + if (encoded.c_str()[i] == '\r' || encoded.c_str()[i] == '\n') { + encoded.erase(i, 1); + } + } + + buffer = decodeBase64(encoded); + + if (buffer == NULL) { + ALOGE("Malformed base64 encoded content found."); + return NULL; + } + } else { +#if 0 + size_t dataLen = strlen(uri) - tmp.size() - 6; + buffer = new ABuffer(dataLen); + memcpy(buffer->data(), commaPos + 1, dataLen); + + // unescape +#else + // MediaPlayer doesn't care for this right now as we don't + // play any text-based media. + return NULL; +#endif + } + + // We don't really care about charset or mime type. + + return new DataURISource(buffer); +} + +DataURISource::DataURISource(const sp &buffer) + : mBuffer(buffer) { +} + +DataURISource::~DataURISource() { +} + +status_t DataURISource::initCheck() const { + return OK; +} + +ssize_t DataURISource::readAt(off64_t offset, void *data, size_t size) { + if (offset >= mBuffer->size()) { + return 0; + } + + size_t copy = mBuffer->size() - offset; + if (copy > size) { + copy = size; + } + + memcpy(data, mBuffer->data() + offset, copy); + + return copy; +} + +status_t DataURISource::getSize(off64_t *size) { + *size = mBuffer->size(); + + return OK; +} + +} // namespace android + diff --git a/media/libstagefright/foundation/base64.cpp b/media/libstagefright/foundation/base64.cpp index d5fb4e0..dcf5bef 100644 --- a/media/libstagefright/foundation/base64.cpp +++ b/media/libstagefright/foundation/base64.cpp @@ -33,6 +33,10 @@ sp decodeBase64(const AString &s) { if (n >= 2 && s.c_str()[n - 2] == '=') { padding = 2; + + if (n >= 3 && s.c_str()[n - 3] == '=') { + padding = 3; + } } } @@ -71,7 +75,7 @@ sp decodeBase64(const AString &s) { if (((i + 1) % 4) == 0) { out[j++] = (accum >> 16); - if (j < outLen) { out[j++] = (accum >> 8) & 0xff; } + if (j < outLen) { out[j++] = (accum >> 8) & 0xff; } if (j < outLen) { out[j++] = accum & 0xff; } accum = 0; -- cgit v1.1 From 80002f4d2d1601710840e5dc4cad4d4c78092dee Mon Sep 17 00:00:00 2001 From: Eric Laurent Date: Thu, 20 Feb 2014 16:26:11 -0800 Subject: audioflinger: fix race condition in SyncEvent callback Now that the SyncEvent callback is implemented by the RecordTrack instead of the RecordThread, there is a possibility that the callback is called after the track deletion. SyncEvent callback now uses a weak pointer instead of a raw pointer as cookie. This allows the callback implementer to acquire a strong reference on the object pointed to by the cookie. Bug: 13114128. Change-Id: Id61b8f06044ed1e52c6f7e7c666cdede68340de2 --- services/audioflinger/AudioFlinger.cpp | 2 +- services/audioflinger/AudioFlinger.h | 8 ++++---- services/audioflinger/Threads.cpp | 7 +++++-- 3 files changed, 10 insertions(+), 7 deletions(-) diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp index 788559d..6f2dce3 100644 --- a/services/audioflinger/AudioFlinger.cpp +++ b/services/audioflinger/AudioFlinger.cpp @@ -2094,7 +2094,7 @@ sp AudioFlinger::createSyncEvent(AudioSystem::sync_even int triggerSession, int listenerSession, sync_event_callback_t callBack, - void *cookie) + wp cookie) { Mutex::Autolock _l(mLock); diff --git a/services/audioflinger/AudioFlinger.h b/services/audioflinger/AudioFlinger.h index 4799beb..c5b8d33 100644 --- a/services/audioflinger/AudioFlinger.h +++ b/services/audioflinger/AudioFlinger.h @@ -253,7 +253,7 @@ public: int triggerSession, int listenerSession, sync_event_callback_t callBack, - void *cookie) + wp cookie) : mType(type), mTriggerSession(triggerSession), mListenerSession(listenerSession), mCallback(callBack), mCookie(cookie) {} @@ -266,14 +266,14 @@ public: AudioSystem::sync_event_t type() const { return mType; } int triggerSession() const { return mTriggerSession; } int listenerSession() const { return mListenerSession; } - void *cookie() const { return mCookie; } + wp cookie() const { return mCookie; } private: const AudioSystem::sync_event_t mType; const int mTriggerSession; const int mListenerSession; sync_event_callback_t mCallback; - void * const mCookie; + const wp mCookie; mutable Mutex mLock; }; @@ -281,7 +281,7 @@ public: int triggerSession, int listenerSession, sync_event_callback_t callBack, - void *cookie); + wp cookie); private: class AudioHwDevice; // fwd declaration for findSuitableHwDev_l diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp index 33c1178..9145a0e 100644 --- a/services/audioflinger/Threads.cpp +++ b/services/audioflinger/Threads.cpp @@ -5095,8 +5095,11 @@ void AudioFlinger::RecordThread::syncStartEventCallback(const wp& eve sp strongEvent = event.promote(); if (strongEvent != 0) { - RecordTrack *recordTrack = (RecordTrack *)strongEvent->cookie(); - recordTrack->handleSyncStartEvent(strongEvent); + sp ptr = strongEvent->cookie().promote(); + if (ptr != 0) { + RecordTrack *recordTrack = (RecordTrack *)ptr.get(); + recordTrack->handleSyncStartEvent(strongEvent); + } } } -- cgit v1.1 From 62a6331faeac5b22117359af8eea6e44c8596a98 Mon Sep 17 00:00:00 2001 From: Marco Nelissen Date: Mon, 10 Mar 2014 11:21:43 -0700 Subject: Fix freeze on pause isOffloaded() tries to lock mLock again. We should be calling isOffloaded_l() b/13394633 Change-Id: I155be6fee937f894d8e6c974e593223ab6014ade --- media/libmedia/AudioTrack.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/media/libmedia/AudioTrack.cpp b/media/libmedia/AudioTrack.cpp index 3217171..ae47201 100644 --- a/media/libmedia/AudioTrack.cpp +++ b/media/libmedia/AudioTrack.cpp @@ -555,7 +555,7 @@ void AudioTrack::pause() mProxy->interrupt(); mAudioTrack->pause(); - if (isOffloaded()) { + if (isOffloaded_l()) { if (mOutput != 0) { uint32_t halFrames; // OffloadThread sends HAL pause in its threadLoop.. time saved -- cgit v1.1 From ab5e3286d8e8406f86be28250fbbb4f1cb57de59 Mon Sep 17 00:00:00 2001 From: Eric Laurent Date: Thu, 13 Mar 2014 10:44:14 -0700 Subject: Revert "Convert AudioFlinger mSinkBuffer to flexible format" This reverts commit e7e676fd2866fa4898712c4effa9e624e969c182. Bug: 13450717. Change-Id: Ib80b0d14428fecce33c62003a1fcf83f71cee03b --- services/audioflinger/Threads.cpp | 54 ++++++++++++++------------------------- services/audioflinger/Threads.h | 9 +++---- 2 files changed, 22 insertions(+), 41 deletions(-) diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp index 8aee194..82c516c 100644 --- a/services/audioflinger/Threads.cpp +++ b/services/audioflinger/Threads.cpp @@ -1145,7 +1145,7 @@ AudioFlinger::PlaybackThread::PlaybackThread(const sp& audioFlinge AudioFlinger::PlaybackThread::~PlaybackThread() { mAudioFlinger->unregisterWriter(mNBLogWriter); - free(mSinkBuffer); + delete[] mSinkBuffer; free(mMixerBuffer); free(mEffectBuffer); } @@ -1782,13 +1782,11 @@ void AudioFlinger::PlaybackThread::readOutputParameters_l() ALOGI("HAL output buffer size %u frames, normal sink buffer size %u frames", mFrameCount, mNormalFrameCount); - // mSinkBuffer is the sink buffer. Size is always multiple-of-16 frames. - // Originally this was int16_t[] array, need to remove legacy implications. - free(mSinkBuffer); - mSinkBuffer = NULL; - const size_t sinkBufferSize = mNormalFrameCount * mChannelCount - * audio_bytes_per_sample(mFormat); - (void)posix_memalign(&mSinkBuffer, 32, sinkBufferSize); + delete[] mSinkBuffer; + size_t normalBufferSize = mNormalFrameCount * mFrameSize; + // For historical reasons mSinkBuffer is int16_t[], but mFrameSize can be odd (such as 1) + mSinkBuffer = new int16_t[(normalBufferSize + 1) >> 1]; + memset(mSinkBuffer, 0, normalBufferSize); // We resize the mMixerBuffer according to the requirements of the sink buffer which // drives the output. @@ -1986,12 +1984,12 @@ ssize_t AudioFlinger::PlaybackThread::threadLoop_write() mLastWriteTime = systemTime(); mInWrite = true; ssize_t bytesWritten; - const size_t offset = mCurrentWriteLength - mBytesRemaining; // If an NBAIO sink is present, use it to write the normal mixer's submix if (mNormalSink != 0) { - const size_t count = mBytesRemaining / mFrameSize; - +#define mBitShift 2 // FIXME + size_t count = mBytesRemaining >> mBitShift; + size_t offset = (mCurrentWriteLength - mBytesRemaining) >> 1; ATRACE_BEGIN("write"); // update the setpoint when AudioFlinger::mScreenState changes uint32_t screenState = AudioFlinger::mScreenState; @@ -2003,10 +2001,10 @@ ssize_t AudioFlinger::PlaybackThread::threadLoop_write() (pipe->maxFrames() * 7) / 8 : mNormalFrameCount * 2); } } - ssize_t framesWritten = mNormalSink->write((char *)mSinkBuffer + offset, count); + ssize_t framesWritten = mNormalSink->write(mSinkBuffer + offset, count); ATRACE_END(); if (framesWritten > 0) { - bytesWritten = framesWritten * mFrameSize; + bytesWritten = framesWritten << mBitShift; } else { bytesWritten = framesWritten; } @@ -2021,7 +2019,7 @@ ssize_t AudioFlinger::PlaybackThread::threadLoop_write() // otherwise use the HAL / AudioStreamOut directly } else { // Direct output and offload threads - + size_t offset = (mCurrentWriteLength - mBytesRemaining); if (mUseAsyncWrite) { ALOGW_IF(mWriteAckSequence & 1, "threadLoop_write(): out of sequence write request"); mWriteAckSequence += 2; @@ -2113,8 +2111,8 @@ void AudioFlinger::PlaybackThread::invalidateTracks(audio_stream_type_t streamTy status_t AudioFlinger::PlaybackThread::addEffectChain_l(const sp& chain) { int session = chain->sessionId(); - int16_t* buffer = reinterpret_cast(mEffectBufferEnabled - ? mEffectBuffer : mSinkBuffer); + int16_t *buffer = mEffectBufferEnabled + ? reinterpret_cast(mEffectBuffer) : mSinkBuffer; bool ownsBuffer = false; ALOGV("addEffectChain_l() %p on thread %p for session %d", chain.get(), this, session); @@ -2154,8 +2152,8 @@ status_t AudioFlinger::PlaybackThread::addEffectChain_l(const sp& c } chain->setInBuffer(buffer, ownsBuffer); - chain->setOutBuffer(reinterpret_cast(mEffectBufferEnabled - ? mEffectBuffer : mSinkBuffer)); + chain->setOutBuffer(mEffectBufferEnabled + ? reinterpret_cast(mEffectBuffer) : mSinkBuffer); // Effect chain for session AUDIO_SESSION_OUTPUT_STAGE is inserted at end of effect // chains list in order to be processed last as it contains output stage effects // Effect chain for session AUDIO_SESSION_OUTPUT_MIX is inserted before @@ -2205,7 +2203,7 @@ size_t AudioFlinger::PlaybackThread::removeEffectChain_l(const sp& for (size_t i = 0; i < mTracks.size(); ++i) { sp track = mTracks[i]; if (session == track->sessionId()) { - track->setMainBuffer(reinterpret_cast(mSinkBuffer)); + track->setMainBuffer(mSinkBuffer); chain->decTrackCnt(); } } @@ -4473,15 +4471,7 @@ void AudioFlinger::DuplicatingThread::threadLoop_sleepTime() ssize_t AudioFlinger::DuplicatingThread::threadLoop_write() { for (size_t i = 0; i < outputTracks.size(); i++) { - // We convert the duplicating thread format to AUDIO_FORMAT_PCM_16_BIT - // for delivery downstream as needed. This in-place conversion is safe as - // AUDIO_FORMAT_PCM_16_BIT is smaller than any other supported format - // (AUDIO_FORMAT_PCM_8_BIT is not allowed here). - if (mFormat != AUDIO_FORMAT_PCM_16_BIT) { - memcpy_by_audio_format(mSinkBuffer, AUDIO_FORMAT_PCM_16_BIT, - mSinkBuffer, mFormat, writeFrames * mChannelCount); - } - outputTracks[i]->write(reinterpret_cast(mSinkBuffer), writeFrames); + outputTracks[i]->write(mSinkBuffer, writeFrames); } mStandby = false; return (ssize_t)mSinkBufferSize; @@ -4510,16 +4500,10 @@ void AudioFlinger::DuplicatingThread::addOutputTrack(MixerThread *thread) Mutex::Autolock _l(mLock); // FIXME explain this formula size_t frameCount = (3 * mNormalFrameCount * mSampleRate) / thread->sampleRate(); - // OutputTrack is forced to AUDIO_FORMAT_PCM_16_BIT regardless of mFormat - // due to current usage case and restrictions on the AudioBufferProvider. - // Actual buffer conversion is done in threadLoop_write(). - // - // TODO: This may change in the future, depending on multichannel - // (and non int16_t*) support on AF::PlaybackThread::OutputTrack OutputTrack *outputTrack = new OutputTrack(thread, this, mSampleRate, - AUDIO_FORMAT_PCM_16_BIT, + mFormat, mChannelMask, frameCount, IPCThreadState::self()->getCallingUid()); diff --git a/services/audioflinger/Threads.h b/services/audioflinger/Threads.h index 59d5c66..3af4874 100644 --- a/services/audioflinger/Threads.h +++ b/services/audioflinger/Threads.h @@ -450,11 +450,8 @@ public: virtual String8 getParameters(const String8& keys); virtual void audioConfigChanged_l(int event, int param = 0); status_t getRenderPosition(uint32_t *halFrames, uint32_t *dspFrames); - // FIXME rename mixBuffer() to sinkBuffer() and remove int16_t* dependency. - // Consider also removing and passing an explicit mMainBuffer initialization - // parameter to AF::PlaybackThread::Track::Track(). - int16_t *mixBuffer() const { - return reinterpret_cast(mSinkBuffer); }; + // TODO: rename mixBuffer() to sinkBuffer() or try to remove external use. + int16_t *mixBuffer() const { return mSinkBuffer; }; virtual void detachAuxEffect_l(int effectId); status_t attachAuxEffect(const sp track, @@ -485,7 +482,7 @@ protected: // updated by readOutputParameters_l() size_t mNormalFrameCount; // normal mixer and effects - void* mSinkBuffer; // frame size aligned sink buffer + int16_t* mSinkBuffer; // frame size aligned sink buffer // TODO: // Rearrange the buffer info into a struct/class with -- cgit v1.1 From cc08675fcb69af218f73eaac07e776abf4d1a4c1 Mon Sep 17 00:00:00 2001 From: Ruben Brunk Date: Mon, 10 Mar 2014 18:59:38 -0700 Subject: camera3: Remove old vendor tag ops dependencies. Bug: 12134423 Change-Id: I7acdf76d4c0674bdb1cc939592d4620687c785c3 --- services/camera/libcameraservice/device2/Camera2Device.cpp | 14 -------------- services/camera/libcameraservice/device2/Camera2Device.h | 1 - 2 files changed, 15 deletions(-) diff --git a/services/camera/libcameraservice/device2/Camera2Device.cpp b/services/camera/libcameraservice/device2/Camera2Device.cpp index dc97c47..f60ca98 100644 --- a/services/camera/libcameraservice/device2/Camera2Device.cpp +++ b/services/camera/libcameraservice/device2/Camera2Device.cpp @@ -112,20 +112,6 @@ status_t Camera2Device::initialize(camera_module_t *module) return res; } - res = device->ops->get_metadata_vendor_tag_ops(device, &mVendorTagOps); - if (res != OK ) { - ALOGE("%s: Camera %d: Unable to retrieve tag ops from device: %s (%d)", - __FUNCTION__, mId, strerror(-res), res); - device->common.close(&device->common); - return res; - } - res = set_camera_metadata_vendor_tag_ops(mVendorTagOps); - if (res != OK) { - ALOGE("%s: Camera %d: Unable to set tag ops: %s (%d)", - __FUNCTION__, mId, strerror(-res), res); - device->common.close(&device->common); - return res; - } res = device->ops->set_notify_callback(device, notificationCallback, NULL); if (res != OK) { diff --git a/services/camera/libcameraservice/device2/Camera2Device.h b/services/camera/libcameraservice/device2/Camera2Device.h index 1f53c56..5b91f88 100644 --- a/services/camera/libcameraservice/device2/Camera2Device.h +++ b/services/camera/libcameraservice/device2/Camera2Device.h @@ -78,7 +78,6 @@ class Camera2Device: public CameraDeviceBase { camera2_device_t *mHal2Device; CameraMetadata mDeviceInfo; - vendor_tag_query_ops_t *mVendorTagOps; /** * Queue class for both sending requests to a camera2 device, and for -- cgit v1.1 From 12c7a4104cea8d8da4fd37fbf077b4605bc3ba7f Mon Sep 17 00:00:00 2001 From: Lajos Molnar Date: Wed, 19 Mar 2014 12:22:01 -0700 Subject: stagefright: allow for minUndequeuedBufs to be one less Bug: 13533477 Change-Id: I909324e3e24f65d8051e0d5474267620efcfc729 --- media/libstagefright/ACodec.cpp | 7 ++++--- media/libstagefright/OMXCodec.cpp | 10 ++++++---- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/media/libstagefright/ACodec.cpp b/media/libstagefright/ACodec.cpp index e9e96d1..9164e5c 100644 --- a/media/libstagefright/ACodec.cpp +++ b/media/libstagefright/ACodec.cpp @@ -644,8 +644,8 @@ status_t ACodec::configureOutputBuffersFromNativeWindow( // FIXME: assume that surface is controlled by app (native window // returns the number for the case when surface is not controlled by app) - (*minUndequeuedBuffers)++; - + // FIXME2: This means that minUndeqeueudBufs can be 1 larger than reported + // For now, try to allocate 1 more buffer, but don't fail if unsuccessful // Use conservative allocation while also trying to reduce starvation // @@ -653,7 +653,8 @@ status_t ACodec::configureOutputBuffersFromNativeWindow( // minimum needed for the consumer to be able to work // 2. try to allocate two (2) additional buffers to reduce starvation from // the consumer - for (OMX_U32 extraBuffers = 2; /* condition inside loop */; extraBuffers--) { + // plus an extra buffer to account for incorrect minUndequeuedBufs + for (OMX_U32 extraBuffers = 2 + 1; /* condition inside loop */; extraBuffers--) { OMX_U32 newBufferCount = def.nBufferCountMin + *minUndequeuedBuffers + extraBuffers; def.nBufferCountActual = newBufferCount; diff --git a/media/libstagefright/OMXCodec.cpp b/media/libstagefright/OMXCodec.cpp index 545ca9d..1cfe6c0 100644 --- a/media/libstagefright/OMXCodec.cpp +++ b/media/libstagefright/OMXCodec.cpp @@ -1806,7 +1806,8 @@ status_t OMXCodec::allocateOutputBuffersFromNativeWindow() { } // FIXME: assume that surface is controlled by app (native window // returns the number for the case when surface is not controlled by app) - minUndequeuedBufs++; + // FIXME2: This means that minUndeqeueudBufs can be 1 larger than reported + // For now, try to allocate 1 more buffer, but don't fail if unsuccessful // Use conservative allocation while also trying to reduce starvation // @@ -1814,10 +1815,11 @@ status_t OMXCodec::allocateOutputBuffersFromNativeWindow() { // minimum needed for the consumer to be able to work // 2. try to allocate two (2) additional buffers to reduce starvation from // the consumer - CODEC_LOGI("OMX-buffers: min=%u actual=%u undeq=%d", + // plus an extra buffer to account for incorrect minUndequeuedBufs + CODEC_LOGI("OMX-buffers: min=%u actual=%u undeq=%d+1", def.nBufferCountMin, def.nBufferCountActual, minUndequeuedBufs); - for (OMX_U32 extraBuffers = 2; /* condition inside loop */; extraBuffers--) { + for (OMX_U32 extraBuffers = 2 + 1; /* condition inside loop */; extraBuffers--) { OMX_U32 newBufferCount = def.nBufferCountMin + minUndequeuedBufs + extraBuffers; def.nBufferCountActual = newBufferCount; @@ -1836,7 +1838,7 @@ status_t OMXCodec::allocateOutputBuffersFromNativeWindow() { return err; } } - CODEC_LOGI("OMX-buffers: min=%u actual=%u undeq=%d", + CODEC_LOGI("OMX-buffers: min=%u actual=%u undeq=%d+1", def.nBufferCountMin, def.nBufferCountActual, minUndequeuedBufs); err = native_window_set_buffer_count( -- cgit v1.1 From 681d65aeffb34993b5f13a78a60b1ec9ff7802e1 Mon Sep 17 00:00:00 2001 From: Eino-Ville Talvala Date: Wed, 26 Mar 2014 18:10:09 +0000 Subject: Revert "camera: Fix setParameters for Preview FPS single/range values" Causes a regression on some devices, so reverting until we're in a position to fix those devices. This reverts commit 9078a1b3b9f9c0c48046ade0e8e18b0d79a659db. Bug: 13563098 Change-Id: I7aedd01fde8b8fdee77e972ec395f0ecadbf8ccb --- camera/CameraParameters.cpp | 53 +------ include/camera/CameraParameters.h | 104 +------------- .../libcameraservice/api1/client2/Parameters.cpp | 157 ++++++--------------- 3 files changed, 47 insertions(+), 267 deletions(-) diff --git a/camera/CameraParameters.cpp b/camera/CameraParameters.cpp index 99e5df4..af091f4 100644 --- a/camera/CameraParameters.cpp +++ b/camera/CameraParameters.cpp @@ -16,7 +16,6 @@ */ #define LOG_TAG "CameraParams" -// #define LOG_NDEBUG 0 #include #include @@ -199,8 +198,6 @@ String8 CameraParameters::flatten() const flattened += ";"; } - ALOGV("%s: Flattened params = %s", __FUNCTION__, flattened.string()); - return flattened; } @@ -250,9 +247,7 @@ void CameraParameters::set(const char *key, const char *value) return; } - // Replacing a value updates the key's order to be the new largest order - ssize_t res = mMap.replaceValueFor(String8(key), String8(value)); - LOG_ALWAYS_FATAL_IF(res < 0, "replaceValueFor(%s,%s) failed", key, value); + mMap.replaceValueFor(String8(key), String8(value)); } void CameraParameters::set(const char *key, int value) @@ -271,12 +266,10 @@ void CameraParameters::setFloat(const char *key, float value) const char *CameraParameters::get(const char *key) const { - ssize_t idx = mMap.indexOfKey(String8(key)); - if (idx < 0) { - return NULL; - } else { - return mMap.valueAt(idx).string(); - } + String8 v = mMap.valueFor(String8(key)); + if (v.length() == 0) + return 0; + return v.string(); } int CameraParameters::getInt(const char *key) const @@ -294,36 +287,6 @@ float CameraParameters::getFloat(const char *key) const return strtof(v, 0); } -status_t CameraParameters::compareSetOrder(const char *key1, const char *key2, - int *order) const { - if (key1 == NULL) { - ALOGE("%s: key1 must not be NULL", __FUNCTION__); - return BAD_VALUE; - } else if (key2 == NULL) { - ALOGE("%s: key2 must not be NULL", __FUNCTION__); - return BAD_VALUE; - } else if (order == NULL) { - ALOGE("%s: order must not be NULL", __FUNCTION__); - return BAD_VALUE; - } - - ssize_t index1 = mMap.indexOfKey(String8(key1)); - ssize_t index2 = mMap.indexOfKey(String8(key2)); - if (index1 < 0) { - ALOGW("%s: Key1 (%s) was not set", __FUNCTION__, key1); - return NAME_NOT_FOUND; - } else if (index2 < 0) { - ALOGW("%s: Key2 (%s) was not set", __FUNCTION__, key2); - return NAME_NOT_FOUND; - } - - *order = (index1 == index2) ? 0 : - (index1 < index2) ? -1 : - 1; - - return OK; -} - void CameraParameters::remove(const char *key) { mMap.removeItem(String8(key)); @@ -449,12 +412,6 @@ void CameraParameters::getPreviewFpsRange(int *min_fps, int *max_fps) const parse_pair(p, min_fps, max_fps, ','); } -void CameraParameters::setPreviewFpsRange(int min_fps, int max_fps) -{ - String8 str = String8::format("%d,%d", min_fps, max_fps); - set(KEY_PREVIEW_FPS_RANGE, str.string()); -} - void CameraParameters::setPreviewFormat(const char *format) { set(KEY_PREVIEW_FORMAT, format); diff --git a/include/camera/CameraParameters.h b/include/camera/CameraParameters.h index 833ba76..d521543 100644 --- a/include/camera/CameraParameters.h +++ b/include/camera/CameraParameters.h @@ -18,7 +18,6 @@ #define ANDROID_HARDWARE_CAMERA_PARAMETERS_H #include -#include #include namespace android { @@ -51,26 +50,10 @@ public: void set(const char *key, const char *value); void set(const char *key, int value); void setFloat(const char *key, float value); - // Look up string value by key. - // -- The string remains valid until the next set/remove of the same key, - // or until the map gets cleared. const char *get(const char *key) const; int getInt(const char *key) const; float getFloat(const char *key) const; - // Compare the order that key1 was set vs the order that key2 was set. - // - // Sets the order parameter to an integer less than, equal to, or greater - // than zero if key1's set order was respectively, to be less than, to - // match, or to be greater than key2's set order. - // - // Error codes: - // * NAME_NOT_FOUND - if either key has not been set previously - // * BAD_VALUE - if any of the parameters are NULL - status_t compareSetOrder(const char *key1, const char *key2, - /*out*/ - int *order) const; - void remove(const char *key); void setPreviewSize(int width, int height); @@ -108,7 +91,6 @@ public: void setPreviewFrameRate(int fps); int getPreviewFrameRate() const; void getPreviewFpsRange(int *min_fps, int *max_fps) const; - void setPreviewFpsRange(int min_fps, int max_fps); void setPreviewFormat(const char *format); const char *getPreviewFormat() const; void setPictureSize(int width, int height); @@ -693,91 +675,7 @@ public: static const char LIGHTFX_HDR[]; private: - - // Quick and dirty map that maintains insertion order - template - struct OrderedKeyedVector { - - ssize_t add(const KeyT& key, const ValueT& value) { - return mList.add(Pair(key, value)); - } - - size_t size() const { - return mList.size(); - } - - const KeyT& keyAt(size_t idx) const { - return mList[idx].mKey; - } - - const ValueT& valueAt(size_t idx) const { - return mList[idx].mValue; - } - - const ValueT& valueFor(const KeyT& key) const { - ssize_t i = indexOfKey(key); - LOG_ALWAYS_FATAL_IF(i<0, "%s: key not found", __PRETTY_FUNCTION__); - - return valueAt(i); - } - - ssize_t indexOfKey(const KeyT& key) const { - size_t vectorIdx = 0; - for (; vectorIdx < mList.size(); ++vectorIdx) { - if (mList[vectorIdx].mKey == key) { - return (ssize_t) vectorIdx; - } - } - - return NAME_NOT_FOUND; - } - - ssize_t removeItem(const KeyT& key) { - size_t vectorIdx = (size_t) indexOfKey(key); - - if (vectorIdx < 0) { - return vectorIdx; - } - - return mList.removeAt(vectorIdx); - } - - void clear() { - mList.clear(); - } - - // Same as removing and re-adding. The key's index changes to max. - ssize_t replaceValueFor(const KeyT& key, const ValueT& value) { - removeItem(key); - return add(key, value); - } - - private: - - struct Pair { - Pair() : mKey(), mValue() {} - Pair(const KeyT& key, const ValueT& value) : - mKey(key), - mValue(value) {} - KeyT mKey; - ValueT mValue; - }; - - Vector mList; - }; - - /** - * Order matters: Keys that are set() later are stored later in the map. - * - * If two keys have meaning that conflict, then the later-set key - * wins. - * - * For example, preview FPS and preview FPS range conflict since only - * we only want to use the FPS range if that's the last thing that was set. - * So in that case, only use preview FPS range if it was set later than - * the preview FPS. - */ - OrderedKeyedVector mMap; + DefaultKeyedVector mMap; }; }; // namespace android diff --git a/services/camera/libcameraservice/api1/client2/Parameters.cpp b/services/camera/libcameraservice/api1/client2/Parameters.cpp index d5be58c..5bfb969 100644 --- a/services/camera/libcameraservice/api1/client2/Parameters.cpp +++ b/services/camera/libcameraservice/api1/client2/Parameters.cpp @@ -16,7 +16,7 @@ #define LOG_TAG "Camera2-Parameters" #define ATRACE_TAG ATRACE_TAG_CAMERA -// #define LOG_NDEBUG 0 +//#define LOG_NDEBUG 0 #include #include @@ -92,6 +92,26 @@ status_t Parameters::initialize(const CameraMetadata *info) { staticInfo(ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES, 2); if (!availableFpsRanges.count) return NO_INIT; + previewFpsRange[0] = availableFpsRanges.data.i32[0]; + previewFpsRange[1] = availableFpsRanges.data.i32[1]; + + params.set(CameraParameters::KEY_PREVIEW_FPS_RANGE, + String8::format("%d,%d", + previewFpsRange[0] * kFpsToApiScale, + previewFpsRange[1] * kFpsToApiScale)); + + { + String8 supportedPreviewFpsRange; + for (size_t i=0; i < availableFpsRanges.count; i += 2) { + if (i != 0) supportedPreviewFpsRange += ","; + supportedPreviewFpsRange += String8::format("(%d,%d)", + availableFpsRanges.data.i32[i] * kFpsToApiScale, + availableFpsRanges.data.i32[i+1] * kFpsToApiScale); + } + params.set(CameraParameters::KEY_SUPPORTED_PREVIEW_FPS_RANGE, + supportedPreviewFpsRange); + } + previewFormat = HAL_PIXEL_FORMAT_YCrCb_420_SP; params.set(CameraParameters::KEY_PREVIEW_FORMAT, formatEnumToString(previewFormat)); // NV21 @@ -159,9 +179,6 @@ status_t Parameters::initialize(const CameraMetadata *info) { supportedPreviewFormats); } - previewFpsRange[0] = availableFpsRanges.data.i32[0]; - previewFpsRange[1] = availableFpsRanges.data.i32[1]; - // PREVIEW_FRAME_RATE / SUPPORTED_PREVIEW_FRAME_RATES are deprecated, but // still have to do something sane for them @@ -170,27 +187,6 @@ status_t Parameters::initialize(const CameraMetadata *info) { params.set(CameraParameters::KEY_PREVIEW_FRAME_RATE, previewFps); - // PREVIEW_FPS_RANGE - // -- Order matters. Set range after single value to so that a roundtrip - // of setParameters(getParameters()) would keep the FPS range in higher - // order. - params.set(CameraParameters::KEY_PREVIEW_FPS_RANGE, - String8::format("%d,%d", - previewFpsRange[0] * kFpsToApiScale, - previewFpsRange[1] * kFpsToApiScale)); - - { - String8 supportedPreviewFpsRange; - for (size_t i=0; i < availableFpsRanges.count; i += 2) { - if (i != 0) supportedPreviewFpsRange += ","; - supportedPreviewFpsRange += String8::format("(%d,%d)", - availableFpsRanges.data.i32[i] * kFpsToApiScale, - availableFpsRanges.data.i32[i+1] * kFpsToApiScale); - } - params.set(CameraParameters::KEY_SUPPORTED_PREVIEW_FPS_RANGE, - supportedPreviewFpsRange); - } - { SortedVector sortedPreviewFrameRates; @@ -1131,72 +1127,29 @@ status_t Parameters::set(const String8& paramString) { // RECORDING_HINT (always supported) validatedParams.recordingHint = boolFromString( newParams.get(CameraParameters::KEY_RECORDING_HINT) ); - IF_ALOGV() { // Avoid unused variable warning - bool recordingHintChanged = - validatedParams.recordingHint != recordingHint; - if (recordingHintChanged) { - ALOGV("%s: Recording hint changed to %d", - __FUNCTION__, validatedParams.recordingHint); - } - } + bool recordingHintChanged = validatedParams.recordingHint != recordingHint; + ALOGV_IF(recordingHintChanged, "%s: Recording hint changed to %d", + __FUNCTION__, recordingHintChanged); // PREVIEW_FPS_RANGE + bool fpsRangeChanged = false; + int32_t lastSetFpsRange[2]; - /** - * Use the single FPS value if it was set later than the range. - * Otherwise, use the range value. - */ - bool fpsUseSingleValue; - { - const char *fpsRange, *fpsSingle; - - fpsRange = params.get(CameraParameters::KEY_PREVIEW_FRAME_RATE); - fpsSingle = params.get(CameraParameters::KEY_PREVIEW_FPS_RANGE); + params.getPreviewFpsRange(&lastSetFpsRange[0], &lastSetFpsRange[1]); + lastSetFpsRange[0] /= kFpsToApiScale; + lastSetFpsRange[1] /= kFpsToApiScale; - /** - * Pick either the range or the single key if only one was set. - * - * If both are set, pick the one that has greater set order. - */ - if (fpsRange == NULL && fpsSingle == NULL) { - ALOGE("%s: FPS was not set. One of %s or %s must be set.", - __FUNCTION__, CameraParameters::KEY_PREVIEW_FRAME_RATE, - CameraParameters::KEY_PREVIEW_FPS_RANGE); - return BAD_VALUE; - } else if (fpsRange == NULL) { - fpsUseSingleValue = true; - ALOGV("%s: FPS range not set, using FPS single value", - __FUNCTION__); - } else if (fpsSingle == NULL) { - fpsUseSingleValue = false; - ALOGV("%s: FPS single not set, using FPS range value", - __FUNCTION__); - } else { - int fpsKeyOrder; - res = params.compareSetOrder( - CameraParameters::KEY_PREVIEW_FRAME_RATE, - CameraParameters::KEY_PREVIEW_FPS_RANGE, - &fpsKeyOrder); - LOG_ALWAYS_FATAL_IF(res != OK, "Impossibly bad FPS keys"); - - fpsUseSingleValue = (fpsKeyOrder > 0); - - } - - ALOGV("%s: Preview FPS value is used from '%s'", - __FUNCTION__, fpsUseSingleValue ? "single" : "range"); - } newParams.getPreviewFpsRange(&validatedParams.previewFpsRange[0], &validatedParams.previewFpsRange[1]); validatedParams.previewFpsRange[0] /= kFpsToApiScale; validatedParams.previewFpsRange[1] /= kFpsToApiScale; - // Ignore the FPS range if the FPS single has higher precedence - if (!fpsUseSingleValue) { - ALOGV("%s: Preview FPS range (%d, %d)", __FUNCTION__, - validatedParams.previewFpsRange[0], - validatedParams.previewFpsRange[1]); + // Compare the FPS range value from the last set() to the current set() + // to determine if the client has changed it + if (validatedParams.previewFpsRange[0] != lastSetFpsRange[0] || + validatedParams.previewFpsRange[1] != lastSetFpsRange[1]) { + fpsRangeChanged = true; camera_metadata_ro_entry_t availablePreviewFpsRanges = staticInfo(ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES, 2); for (i = 0; i < availablePreviewFpsRanges.count; i += 2) { @@ -1247,13 +1200,14 @@ status_t Parameters::set(const String8& paramString) { } } - // PREVIEW_FRAME_RATE Deprecated - // - Use only if the single FPS value was set later than the FPS range - if (fpsUseSingleValue) { + // PREVIEW_FRAME_RATE Deprecated, only use if the preview fps range is + // unchanged this time. The single-value FPS is the same as the minimum of + // the range. To detect whether the application has changed the value of + // previewFps, compare against their last-set preview FPS. + if (!fpsRangeChanged) { int previewFps = newParams.getPreviewFrameRate(); - ALOGV("%s: Preview FPS single value requested: %d", - __FUNCTION__, previewFps); - { + int lastSetPreviewFps = params.getPreviewFrameRate(); + if (previewFps != lastSetPreviewFps || recordingHintChanged) { camera_metadata_ro_entry_t availableFrameRates = staticInfo(ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES); /** @@ -1322,35 +1276,6 @@ status_t Parameters::set(const String8& paramString) { } } - /** - * Update Preview FPS and Preview FPS ranges based on - * what we actually set. - * - * This updates the API-visible (Camera.Parameters#getParameters) values of - * the FPS fields, not only the internal versions. - * - * Order matters: The value that was set last takes precedence. - * - If the client does a setParameters(getParameters()) we retain - * the same order for preview FPS. - */ - if (!fpsUseSingleValue) { - // Set fps single, then fps range (range wins) - validatedParams.params.setPreviewFrameRate( - fpsFromRange(/*min*/validatedParams.previewFpsRange[0], - /*max*/validatedParams.previewFpsRange[1])); - validatedParams.params.setPreviewFpsRange( - validatedParams.previewFpsRange[0], - validatedParams.previewFpsRange[1]); - } else { - // Set fps range, then fps single (single wins) - validatedParams.params.setPreviewFpsRange( - validatedParams.previewFpsRange[0], - validatedParams.previewFpsRange[1]); - validatedParams.params.setPreviewFrameRate( - fpsFromRange(/*min*/validatedParams.previewFpsRange[0], - /*max*/validatedParams.previewFpsRange[1])); - } - // PICTURE_SIZE newParams.getPictureSize(&validatedParams.pictureWidth, &validatedParams.pictureHeight); -- cgit v1.1