diff options
-rw-r--r-- | include/media/AudioSystem.h | 1 | ||||
-rw-r--r-- | include/media/IAudioFlinger.h | 6 | ||||
-rw-r--r-- | media/libmedia/AudioSystem.cpp | 7 | ||||
-rw-r--r-- | media/libmedia/IAudioFlinger.cpp | 18 | ||||
-rw-r--r-- | media/libmediaplayerservice/MediaPlayerService.cpp | 35 | ||||
-rw-r--r-- | media/libstagefright/include/OMXNodeInstance.h | 10 | ||||
-rw-r--r-- | media/libstagefright/omx/OMX.cpp | 2 | ||||
-rw-r--r-- | media/libstagefright/omx/OMXNodeInstance.cpp | 89 |
8 files changed, 163 insertions, 5 deletions
diff --git a/include/media/AudioSystem.h b/include/media/AudioSystem.h index 57f8102..a7c8a0a 100644 --- a/include/media/AudioSystem.h +++ b/include/media/AudioSystem.h @@ -220,6 +220,7 @@ public: static status_t getInputBufferSize(uint32_t sampleRate, int format, int channelCount, size_t* buffSize); + static status_t setVoiceVolume(float volume); // // AudioPolicyService interface diff --git a/include/media/IAudioFlinger.h b/include/media/IAudioFlinger.h index 8018568..a46c727 100644 --- a/include/media/IAudioFlinger.h +++ b/include/media/IAudioFlinger.h @@ -102,10 +102,10 @@ public: virtual status_t setParameters(int ioHandle, const String8& keyValuePairs) = 0; virtual String8 getParameters(int ioHandle, const String8& keys) = 0; - + // register a current process for audio output change notifications virtual void registerClient(const sp<IAudioFlingerClient>& client) = 0; - + // retrieve the audio recording buffer size virtual size_t getInputBufferSize(uint32_t sampleRate, int format, int channelCount) = 0; @@ -128,6 +128,8 @@ public: virtual status_t closeInput(int input) = 0; virtual status_t setStreamOutput(uint32_t stream, int output) = 0; + + virtual status_t setVoiceVolume(float volume) = 0; }; diff --git a/media/libmedia/AudioSystem.cpp b/media/libmedia/AudioSystem.cpp index bd1b2d7..5352234 100644 --- a/media/libmedia/AudioSystem.cpp +++ b/media/libmedia/AudioSystem.cpp @@ -335,6 +335,13 @@ status_t AudioSystem::getInputBufferSize(uint32_t sampleRate, int format, int ch return NO_ERROR; } +status_t AudioSystem::setVoiceVolume(float value) +{ + const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger(); + if (af == 0) return PERMISSION_DENIED; + return af->setVoiceVolume(value); +} + // --------------------------------------------------------------------------- void AudioSystem::AudioFlingerClient::binderDied(const wp<IBinder>& who) { diff --git a/media/libmedia/IAudioFlinger.cpp b/media/libmedia/IAudioFlinger.cpp index 5089157..0eff205 100644 --- a/media/libmedia/IAudioFlinger.cpp +++ b/media/libmedia/IAudioFlinger.cpp @@ -59,7 +59,8 @@ enum { RESTORE_OUTPUT, OPEN_INPUT, CLOSE_INPUT, - SET_STREAM_OUTPUT + SET_STREAM_OUTPUT, + SET_VOICE_VOLUME }; class BpAudioFlinger : public BpInterface<IAudioFlinger> @@ -455,6 +456,15 @@ public: remote()->transact(SET_STREAM_OUTPUT, data, &reply); return reply.readInt32(); } + + virtual status_t setVoiceVolume(float volume) + { + Parcel data, reply; + data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor()); + data.writeFloat(volume); + remote()->transact(SET_VOICE_VOLUME, data, &reply); + return reply.readInt32(); + } }; IMPLEMENT_META_INTERFACE(AudioFlinger, "android.media.IAudioFlinger"); @@ -700,6 +710,12 @@ status_t BnAudioFlinger::onTransact( reply->writeInt32(setStreamOutput(stream, output)); return NO_ERROR; } break; + case SET_VOICE_VOLUME: { + CHECK_INTERFACE(IAudioFlinger, data, reply); + float volume = data.readFloat(); + reply->writeInt32( setVoiceVolume(volume) ); + return NO_ERROR; + } break; default: return BBinder::onTransact(code, data, reply, flags); } diff --git a/media/libmediaplayerservice/MediaPlayerService.cpp b/media/libmediaplayerservice/MediaPlayerService.cpp index ab759df..64267de 100644 --- a/media/libmediaplayerservice/MediaPlayerService.cpp +++ b/media/libmediaplayerservice/MediaPlayerService.cpp @@ -356,11 +356,44 @@ extern "C" void get_malloc_leak_info(uint8_t** info, size_t* overallSize, size_t* infoSize, size_t* totalMemory, size_t* backtraceSize); extern "C" void free_malloc_leak_info(uint8_t* info); +// Use the String-class below instead of String8 to allocate all memory +// beforehand and not reenter the heap while we are examining it... +struct MyString8 { + static const size_t MAX_SIZE = 256 * 1024; + + MyString8() + : mPtr((char *)malloc(MAX_SIZE)) { + *mPtr = '\0'; + } + + ~MyString8() { + free(mPtr); + } + + void append(const char *s) { + strcat(mPtr, s); + } + + const char *string() const { + return mPtr; + } + + size_t size() const { + return strlen(mPtr); + } + +private: + char *mPtr; + + MyString8(const MyString8 &); + MyString8 &operator=(const MyString8 &); +}; + void memStatus(int fd, const Vector<String16>& args) { const size_t SIZE = 256; char buffer[SIZE]; - String8 result; + MyString8 result; typedef struct { size_t size; diff --git a/media/libstagefright/include/OMXNodeInstance.h b/media/libstagefright/include/OMXNodeInstance.h index 181742e..09a8816 100644 --- a/media/libstagefright/include/OMXNodeInstance.h +++ b/media/libstagefright/include/OMXNodeInstance.h @@ -85,8 +85,18 @@ private: OMX_HANDLETYPE mHandle; sp<IOMXObserver> mObserver; + struct ActiveBuffer { + OMX_U32 mPortIndex; + OMX::buffer_id mID; + }; + Vector<ActiveBuffer> mActiveBuffers; + ~OMXNodeInstance(); + void addActiveBuffer(OMX_U32 portIndex, OMX::buffer_id id); + void removeActiveBuffer(OMX_U32 portIndex, OMX::buffer_id id); + void freeActiveBuffers(); + static OMX_ERRORTYPE OnEvent( OMX_IN OMX_HANDLETYPE hComponent, OMX_IN OMX_PTR pAppData, diff --git a/media/libstagefright/omx/OMX.cpp b/media/libstagefright/omx/OMX.cpp index 3800a26..e361018 100644 --- a/media/libstagefright/omx/OMX.cpp +++ b/media/libstagefright/omx/OMX.cpp @@ -98,7 +98,7 @@ void OMX::CallbackDispatcher::post(const omx_message &msg) { void OMX::CallbackDispatcher::dispatch(const omx_message &msg) { OMXNodeInstance *instance = mOwner->findInstance(msg.node); if (instance == NULL) { - LOGW("Would have dispatched a message to a node that's already gone."); + LOGV("Would have dispatched a message to a node that's already gone."); return; } instance->onMessage(msg); diff --git a/media/libstagefright/omx/OMXNodeInstance.cpp b/media/libstagefright/omx/OMXNodeInstance.cpp index d5d45d7..ab8be53 100644 --- a/media/libstagefright/omx/OMXNodeInstance.cpp +++ b/media/libstagefright/omx/OMXNodeInstance.cpp @@ -107,6 +107,55 @@ static status_t StatusFromOMXError(OMX_ERRORTYPE err) { } status_t OMXNodeInstance::freeNode() { + // Transition the node from its current state all the way down + // to "Loaded". + // This ensures that all active buffers are properly freed even + // for components that don't do this themselves on a call to + // "FreeHandle". + + OMX_STATETYPE state; + CHECK_EQ(OMX_GetState(mHandle, &state), OMX_ErrorNone); + switch (state) { + case OMX_StateExecuting: + { + LOGV("forcing Executing->Idle"); + sendCommand(OMX_CommandStateSet, OMX_StateIdle); + OMX_ERRORTYPE err; + while ((err = OMX_GetState(mHandle, &state)) == OMX_ErrorNone + && state != OMX_StateIdle) { + usleep(100000); + } + CHECK_EQ(err, OMX_ErrorNone); + + // fall through + } + + case OMX_StateIdle: + { + LOGV("forcing Idle->Loaded"); + sendCommand(OMX_CommandStateSet, OMX_StateLoaded); + + freeActiveBuffers(); + + OMX_ERRORTYPE err; + while ((err = OMX_GetState(mHandle, &state)) == OMX_ErrorNone + && state != OMX_StateLoaded) { + LOGV("waiting for Loaded state..."); + usleep(100000); + } + CHECK_EQ(err, OMX_ErrorNone); + + // fall through + } + + case OMX_StateLoaded: + break; + + default: + CHECK(!"should not be here, unknown state."); + break; + } + OMX_ERRORTYPE err = OMX_MasterFreeHandle(mHandle); mHandle = NULL; @@ -193,6 +242,8 @@ status_t OMXNodeInstance::useBuffer( *buffer = header; + addActiveBuffer(portIndex, *buffer); + return OK; } @@ -220,6 +271,8 @@ status_t OMXNodeInstance::allocateBuffer( *buffer = header; + addActiveBuffer(portIndex, *buffer); + return OK; } @@ -248,6 +301,8 @@ status_t OMXNodeInstance::allocateBufferWithBackup( *buffer = header; + addActiveBuffer(portIndex, *buffer); + return OK; } @@ -255,6 +310,8 @@ status_t OMXNodeInstance::freeBuffer( OMX_U32 portIndex, OMX::buffer_id buffer) { Mutex::Autolock autoLock(mLock); + removeActiveBuffer(portIndex, buffer); + OMX_BUFFERHEADERTYPE *header = (OMX_BUFFERHEADERTYPE *)buffer; BufferMeta *buffer_meta = static_cast<BufferMeta *>(header->pAppPrivate); @@ -367,5 +424,37 @@ OMX_ERRORTYPE OMXNodeInstance::OnFillBufferDone( return instance->owner()->OnFillBufferDone(instance->nodeID(), pBuffer); } +void OMXNodeInstance::addActiveBuffer(OMX_U32 portIndex, OMX::buffer_id id) { + ActiveBuffer active; + active.mPortIndex = portIndex; + active.mID = id; + mActiveBuffers.push(active); +} + +void OMXNodeInstance::removeActiveBuffer( + OMX_U32 portIndex, OMX::buffer_id id) { + bool found = false; + for (size_t i = 0; i < mActiveBuffers.size(); ++i) { + if (mActiveBuffers[i].mPortIndex == portIndex + && mActiveBuffers[i].mID == id) { + found = true; + mActiveBuffers.removeItemsAt(i); + break; + } + } + + if (!found) { + LOGW("Attempt to remove an active buffer we know nothing about..."); + } +} + +void OMXNodeInstance::freeActiveBuffers() { + // Make sure to count down here, as freeBuffer will in turn remove + // the active buffer from the vector... + for (size_t i = mActiveBuffers.size(); i--;) { + freeBuffer(mActiveBuffers[i].mPortIndex, mActiveBuffers[i].mID); + } +} + } // namespace android |