diff options
Diffstat (limited to 'media/libmedia')
| -rw-r--r-- | media/libmedia/Android.mk | 15 | ||||
| -rw-r--r-- | media/libmedia/AudioEffect.cpp | 1 | ||||
| -rw-r--r-- | media/libmedia/AudioParameter.cpp | 179 | ||||
| -rw-r--r-- | media/libmedia/AudioRecord.cpp | 41 | ||||
| -rw-r--r-- | media/libmedia/AudioSystem.cpp | 361 | ||||
| -rw-r--r-- | media/libmedia/AudioTrack.cpp | 157 | ||||
| -rw-r--r-- | media/libmedia/IAudioPolicyService.cpp | 94 | ||||
| -rw-r--r-- | media/libmedia/IMediaMetadataRetriever.cpp | 29 | ||||
| -rw-r--r-- | media/libmedia/IMediaPlayer.cpp | 48 | ||||
| -rw-r--r-- | media/libmedia/IMediaPlayerClient.cpp | 12 | ||||
| -rw-r--r-- | media/libmedia/JetPlayer.cpp | 4 | ||||
| -rw-r--r-- | media/libmedia/MediaProfiles.cpp | 23 | ||||
| -rw-r--r-- | media/libmedia/MemoryLeakTrackUtil.cpp | 169 | ||||
| -rw-r--r-- | media/libmedia/ToneGenerator.cpp | 4 | ||||
| -rw-r--r-- | media/libmedia/Visualizer.cpp | 4 | ||||
| -rw-r--r-- | media/libmedia/mediametadataretriever.cpp | 5 | ||||
| -rw-r--r-- | media/libmedia/mediaplayer.cpp | 33 |
17 files changed, 718 insertions, 461 deletions
diff --git a/media/libmedia/Android.mk b/media/libmedia/Android.mk index fd4c6c6..121e38a4 100644 --- a/media/libmedia/Android.mk +++ b/media/libmedia/Android.mk @@ -1,4 +1,14 @@ LOCAL_PATH:= $(call my-dir) + +include $(CLEAR_VARS) + +LOCAL_SRC_FILES:= \ + AudioParameter.cpp +LOCAL_MODULE:= libmedia_helper +LOCAL_MODULE_TAGS := optional + +include $(BUILD_STATIC_LIBRARY) + include $(CLEAR_VARS) LOCAL_SRC_FILES:= \ @@ -33,13 +43,16 @@ LOCAL_SRC_FILES:= \ IEffectClient.cpp \ AudioEffect.cpp \ Visualizer.cpp \ + MemoryLeakTrackUtil.cpp \ fixedfft.cpp.arm LOCAL_SHARED_LIBRARIES := \ libui libcutils libutils libbinder libsonivox libicuuc libexpat \ - libsurfaceflinger_client libcamera_client libstagefright_foundation \ + libcamera_client libstagefright_foundation \ libgui +LOCAL_WHOLE_STATIC_LIBRARY := libmedia_helper + LOCAL_MODULE:= libmedia ifeq ($(TARGET_OS)-$(TARGET_SIMULATOR),linux-true) diff --git a/media/libmedia/AudioEffect.cpp b/media/libmedia/AudioEffect.cpp index aadeba5..a043329 100644 --- a/media/libmedia/AudioEffect.cpp +++ b/media/libmedia/AudioEffect.cpp @@ -170,7 +170,6 @@ AudioEffect::~AudioEffect() LOGV("Destructor %p", this); if (mStatus == NO_ERROR || mStatus == ALREADY_EXISTS) { - setEnabled(false); if (mIEffect != NULL) { mIEffect->disconnect(); mIEffect->asBinder()->unlinkToDeath(mIEffectClient); diff --git a/media/libmedia/AudioParameter.cpp b/media/libmedia/AudioParameter.cpp new file mode 100644 index 0000000..59ccfd0 --- /dev/null +++ b/media/libmedia/AudioParameter.cpp @@ -0,0 +1,179 @@ +/* + * Copyright (C) 2006-2011 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. + */ + +#define LOG_TAG "AudioParameter" +//#define LOG_NDEBUG 0 + +#include <utils/Log.h> + +#include <media/AudioParameter.h> + +namespace android { + +const char *AudioParameter::keyRouting = "routing"; +const char *AudioParameter::keySamplingRate = "sampling_rate"; +const char *AudioParameter::keyFormat = "format"; +const char *AudioParameter::keyChannels = "channels"; +const char *AudioParameter::keyFrameCount = "frame_count"; +const char *AudioParameter::keyInputSource = "input_source"; + +AudioParameter::AudioParameter(const String8& keyValuePairs) +{ + char *str = new char[keyValuePairs.length()+1]; + mKeyValuePairs = keyValuePairs; + + strcpy(str, keyValuePairs.string()); + char *pair = strtok(str, ";"); + while (pair != NULL) { + if (strlen(pair) != 0) { + size_t eqIdx = strcspn(pair, "="); + String8 key = String8(pair, eqIdx); + String8 value; + if (eqIdx == strlen(pair)) { + value = String8(""); + } else { + value = String8(pair + eqIdx + 1); + } + if (mParameters.indexOfKey(key) < 0) { + mParameters.add(key, value); + } else { + mParameters.replaceValueFor(key, value); + } + } else { + LOGV("AudioParameter() cstor empty key value pair"); + } + pair = strtok(NULL, ";"); + } + + delete[] str; +} + +AudioParameter::~AudioParameter() +{ + mParameters.clear(); +} + +String8 AudioParameter::toString() +{ + String8 str = String8(""); + + size_t size = mParameters.size(); + for (size_t i = 0; i < size; i++) { + str += mParameters.keyAt(i); + str += "="; + str += mParameters.valueAt(i); + if (i < (size - 1)) str += ";"; + } + return str; +} + +status_t AudioParameter::add(const String8& key, const String8& value) +{ + if (mParameters.indexOfKey(key) < 0) { + mParameters.add(key, value); + return NO_ERROR; + } else { + mParameters.replaceValueFor(key, value); + return ALREADY_EXISTS; + } +} + +status_t AudioParameter::addInt(const String8& key, const int value) +{ + char str[12]; + if (snprintf(str, 12, "%d", value) > 0) { + String8 str8 = String8(str); + return add(key, str8); + } else { + return BAD_VALUE; + } +} + +status_t AudioParameter::addFloat(const String8& key, const float value) +{ + char str[23]; + if (snprintf(str, 23, "%.10f", value) > 0) { + String8 str8 = String8(str); + return add(key, str8); + } else { + return BAD_VALUE; + } +} + +status_t AudioParameter::remove(const String8& key) +{ + if (mParameters.indexOfKey(key) >= 0) { + mParameters.removeItem(key); + return NO_ERROR; + } else { + return BAD_VALUE; + } +} + +status_t AudioParameter::get(const String8& key, String8& value) +{ + if (mParameters.indexOfKey(key) >= 0) { + value = mParameters.valueFor(key); + return NO_ERROR; + } else { + return BAD_VALUE; + } +} + +status_t AudioParameter::getInt(const String8& key, int& value) +{ + String8 str8; + status_t result = get(key, str8); + value = 0; + if (result == NO_ERROR) { + int val; + if (sscanf(str8.string(), "%d", &val) == 1) { + value = val; + } else { + result = INVALID_OPERATION; + } + } + return result; +} + +status_t AudioParameter::getFloat(const String8& key, float& value) +{ + String8 str8; + status_t result = get(key, str8); + value = 0; + if (result == NO_ERROR) { + float val; + if (sscanf(str8.string(), "%f", &val) == 1) { + value = val; + } else { + result = INVALID_OPERATION; + } + } + return result; +} + +status_t AudioParameter::getAt(size_t index, String8& key, String8& value) +{ + if (mParameters.size() > index) { + key = mParameters.keyAt(index); + value = mParameters.valueAt(index); + return NO_ERROR; + } else { + return BAD_VALUE; + } +} + +}; // namespace android diff --git a/media/libmedia/AudioRecord.cpp b/media/libmedia/AudioRecord.cpp index a18bedb..446e3df 100644 --- a/media/libmedia/AudioRecord.cpp +++ b/media/libmedia/AudioRecord.cpp @@ -35,6 +35,10 @@ #include <binder/Parcel.h> #include <binder/IPCThreadState.h> #include <utils/Timers.h> +#include <utils/Atomic.h> + +#include <system/audio.h> +#include <cutils/bitops.h> #define LIKELY( exp ) (__builtin_expect( (exp) != 0, true )) #define UNLIKELY( exp ) (__builtin_expect( (exp) != 0, false )) @@ -65,8 +69,8 @@ status_t AudioRecord::getMinFrameCount( // We double the size of input buffer for ping pong use of record buffer. size <<= 1; - if (AudioSystem::isLinearPCM(format)) { - size /= channelCount * (format == AudioSystem::PCM_16_BIT ? 2 : 1); + if (audio_is_linear_pcm(format)) { + size /= channelCount * (format == AUDIO_FORMAT_PCM_16_BIT ? 2 : 1); } *frameCount = size; @@ -144,22 +148,22 @@ status_t AudioRecord::set( } // these below should probably come from the audioFlinger too... if (format == 0) { - format = AudioSystem::PCM_16_BIT; + format = AUDIO_FORMAT_PCM_16_BIT; } // validate parameters - if (!AudioSystem::isValidFormat(format)) { + if (!audio_is_valid_format(format)) { LOGE("Invalid format"); return BAD_VALUE; } - if (!AudioSystem::isInputChannel(channels)) { + if (!audio_is_input_channel(channels)) { return BAD_VALUE; } - int channelCount = AudioSystem::popCount(channels); + int channelCount = popcount(channels); audio_io_handle_t input = AudioSystem::getInput(inputSource, - sampleRate, format, channels, (AudioSystem::audio_in_acoustics)flags); + sampleRate, format, channels, (audio_in_acoustics_t)flags); if (input == 0) { LOGE("Could not get audio input for record source %d", inputSource); return BAD_VALUE; @@ -253,8 +257,8 @@ uint32_t AudioRecord::frameCount() const int AudioRecord::frameSize() const { - if (AudioSystem::isLinearPCM(mFormat)) { - return channelCount()*((format() == AudioSystem::PCM_8_BIT) ? sizeof(uint8_t) : sizeof(int16_t)); + if (audio_is_linear_pcm(mFormat)) { + return channelCount()*((format() == AUDIO_FORMAT_PCM_8_BIT) ? sizeof(uint8_t) : sizeof(int16_t)); } else { return sizeof(uint8_t); } @@ -299,7 +303,7 @@ status_t AudioRecord::start() ret = mAudioRecord->start(); cblk->lock.lock(); if (ret == DEAD_OBJECT) { - cblk->flags |= CBLK_INVALID_MSK; + android_atomic_or(CBLK_INVALID_ON, &cblk->flags); } } if (cblk->flags & CBLK_INVALID_MSK) { @@ -467,7 +471,7 @@ status_t AudioRecord::openRecord_l( mCblkMemory = cblk; mCblk = static_cast<audio_track_cblk_t*>(cblk->pointer()); mCblk->buffers = (char*)mCblk + sizeof(audio_track_cblk_t); - mCblk->flags &= ~CBLK_DIRECTION_MSK; + android_atomic_and(~CBLK_DIRECTION_MSK, &mCblk->flags); mCblk->bufferTimeoutMs = MAX_RUN_TIMEOUT_MS; mCblk->waitTimeMs = 0; return NO_ERROR; @@ -522,7 +526,7 @@ status_t AudioRecord::obtainBuffer(Buffer* audioBuffer, int32_t waitCount) result = mAudioRecord->start(); cblk->lock.lock(); if (result == DEAD_OBJECT) { - cblk->flags |= CBLK_INVALID_MSK; + android_atomic_or(CBLK_INVALID_ON, &cblk->flags); create_new_record: result = AudioRecord::restoreRecord_l(cblk); } @@ -586,7 +590,7 @@ audio_io_handle_t AudioRecord::getInput_l() mInput = AudioSystem::getInput(mInputSource, mCblk->sampleRate, mFormat, mChannels, - (AudioSystem::audio_in_acoustics)mFlags); + (audio_in_acoustics_t)mFlags); return mInput; } @@ -722,9 +726,8 @@ bool AudioRecord::processAudioBuffer(const sp<ClientRecordThread>& thread) // Manage overrun callback if (mActive && (cblk->framesAvailable() == 0)) { LOGV("Overrun user: %x, server: %x, flags %04x", cblk->user, cblk->server, cblk->flags); - if ((cblk->flags & CBLK_UNDERRUN_MSK) == CBLK_UNDERRUN_OFF) { + if (!(android_atomic_or(CBLK_UNDERRUN_ON, &cblk->flags) & CBLK_UNDERRUN_MSK)) { mCbf(EVENT_OVERRUN, mUserData, 0); - cblk->flags |= CBLK_UNDERRUN_ON; } } @@ -743,10 +746,8 @@ status_t AudioRecord::restoreRecord_l(audio_track_cblk_t*& cblk) { status_t result; - if (!(cblk->flags & CBLK_RESTORING_MSK)) { + if (!(android_atomic_or(CBLK_RESTORING_ON, &cblk->flags) & CBLK_RESTORING_MSK)) { LOGW("dead IAudioRecord, creating a new one"); - - cblk->flags |= CBLK_RESTORING_ON; // signal old cblk condition so that other threads waiting for available buffers stop // waiting now cblk->cv.broadcast(); @@ -765,10 +766,8 @@ status_t AudioRecord::restoreRecord_l(audio_track_cblk_t*& cblk) } // signal old cblk condition for other threads waiting for restore completion - cblk->lock.lock(); - cblk->flags |= CBLK_RESTORED_MSK; + android_atomic_or(CBLK_RESTORED_ON, &cblk->flags); cblk->cv.broadcast(); - cblk->lock.unlock(); } else { if (!(cblk->flags & CBLK_RESTORED_MSK)) { LOGW("dead IAudioRecord, waiting for a new one to be created"); diff --git a/media/libmedia/AudioSystem.cpp b/media/libmedia/AudioSystem.cpp index 2f694ba..8a180d8 100644 --- a/media/libmedia/AudioSystem.cpp +++ b/media/libmedia/AudioSystem.cpp @@ -23,6 +23,8 @@ #include <media/IAudioPolicyService.h> #include <math.h> +#include <system/audio.h> + // ---------------------------------------------------------------------------- // the sim build doesn't have gettid @@ -45,7 +47,7 @@ DefaultKeyedVector<audio_io_handle_t, AudioSystem::OutputDescriptor *> AudioSyst // Cached values for recording queries uint32_t AudioSystem::gPrevInSamplingRate = 16000; -int AudioSystem::gPrevInFormat = AudioSystem::PCM_16_BIT; +int AudioSystem::gPrevInFormat = AUDIO_FORMAT_PCM_16_BIT; int AudioSystem::gPrevInChannelCount = 1; size_t AudioSystem::gInBuffSize = 0; @@ -127,7 +129,7 @@ status_t AudioSystem::getMasterMute(bool* mute) status_t AudioSystem::setStreamVolume(int stream, float value, int output) { - if (uint32_t(stream) >= NUM_STREAM_TYPES) return BAD_VALUE; + if (uint32_t(stream) >= AUDIO_STREAM_CNT) return BAD_VALUE; const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger(); if (af == 0) return PERMISSION_DENIED; af->setStreamVolume(stream, value, output); @@ -136,7 +138,7 @@ status_t AudioSystem::setStreamVolume(int stream, float value, int output) status_t AudioSystem::setStreamMute(int stream, bool mute) { - if (uint32_t(stream) >= NUM_STREAM_TYPES) return BAD_VALUE; + if (uint32_t(stream) >= AUDIO_STREAM_CNT) return BAD_VALUE; const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger(); if (af == 0) return PERMISSION_DENIED; af->setStreamMute(stream, mute); @@ -145,7 +147,7 @@ status_t AudioSystem::setStreamMute(int stream, bool mute) status_t AudioSystem::getStreamVolume(int stream, float* volume, int output) { - if (uint32_t(stream) >= NUM_STREAM_TYPES) return BAD_VALUE; + if (uint32_t(stream) >= AUDIO_STREAM_CNT) return BAD_VALUE; const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger(); if (af == 0) return PERMISSION_DENIED; *volume = af->streamVolume(stream, output); @@ -154,7 +156,7 @@ status_t AudioSystem::getStreamVolume(int stream, float* volume, int output) status_t AudioSystem::getStreamMute(int stream, bool* mute) { - if (uint32_t(stream) >= NUM_STREAM_TYPES) return BAD_VALUE; + if (uint32_t(stream) >= AUDIO_STREAM_CNT) return BAD_VALUE; const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger(); if (af == 0) return PERMISSION_DENIED; *mute = af->streamMute(stream); @@ -163,7 +165,7 @@ status_t AudioSystem::getStreamMute(int stream, bool* mute) status_t AudioSystem::setMode(int mode) { - if (mode >= NUM_MODES) return BAD_VALUE; + if (mode >= AUDIO_MODE_CNT) return BAD_VALUE; const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger(); if (af == 0) return PERMISSION_DENIED; return af->setMode(mode); @@ -213,11 +215,11 @@ status_t AudioSystem::getOutputSamplingRate(int* samplingRate, int streamType) OutputDescriptor *outputDesc; audio_io_handle_t output; - if (streamType == DEFAULT) { - streamType = MUSIC; + if (streamType == AUDIO_STREAM_DEFAULT) { + streamType = AUDIO_STREAM_MUSIC; } - output = getOutput((stream_type)streamType); + output = getOutput((audio_stream_type_t)streamType); if (output == 0) { return PERMISSION_DENIED; } @@ -246,11 +248,11 @@ status_t AudioSystem::getOutputFrameCount(int* frameCount, int streamType) OutputDescriptor *outputDesc; audio_io_handle_t output; - if (streamType == DEFAULT) { - streamType = MUSIC; + if (streamType == AUDIO_STREAM_DEFAULT) { + streamType = AUDIO_STREAM_MUSIC; } - output = getOutput((stream_type)streamType); + output = getOutput((audio_stream_type_t)streamType); if (output == 0) { return PERMISSION_DENIED; } @@ -277,11 +279,11 @@ status_t AudioSystem::getOutputLatency(uint32_t* latency, int streamType) OutputDescriptor *outputDesc; audio_io_handle_t output; - if (streamType == DEFAULT) { - streamType = MUSIC; + if (streamType == AUDIO_STREAM_DEFAULT) { + streamType = AUDIO_STREAM_MUSIC; } - output = getOutput((stream_type)streamType); + output = getOutput((audio_stream_type_t)streamType); if (output == 0) { return PERMISSION_DENIED; } @@ -338,11 +340,11 @@ status_t AudioSystem::getRenderPosition(uint32_t *halFrames, uint32_t *dspFrames const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger(); if (af == 0) return PERMISSION_DENIED; - if (stream == DEFAULT) { - stream = MUSIC; + if (stream == AUDIO_STREAM_DEFAULT) { + stream = AUDIO_STREAM_MUSIC; } - return af->getRenderPosition(halFrames, dspFrames, getOutput((stream_type)stream)); + return af->getRenderPosition(halFrames, dspFrames, getOutput((audio_stream_type_t)stream)); } unsigned int AudioSystem::getInputFramesLost(audio_io_handle_t ioHandle) { @@ -455,10 +457,10 @@ void AudioSystem::setErrorCallback(audio_error_callback cb) { bool AudioSystem::routedToA2dpOutput(int streamType) { switch(streamType) { - case MUSIC: - case VOICE_CALL: - case BLUETOOTH_SCO: - case SYSTEM: + case AUDIO_STREAM_MUSIC: + case AUDIO_STREAM_VOICE_CALL: + case AUDIO_STREAM_BLUETOOTH_SCO: + case AUDIO_STREAM_SYSTEM: return true; default: return false; @@ -497,9 +499,9 @@ const sp<IAudioPolicyService>& AudioSystem::get_audio_policy_service() return gAudioPolicyService; } -status_t AudioSystem::setDeviceConnectionState(audio_devices device, - device_connection_state state, - const char *device_address) +status_t AudioSystem::setDeviceConnectionState(audio_devices_t device, + audio_policy_dev_state_t state, + const char *device_address) { const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service(); if (aps == 0) return PERMISSION_DENIED; @@ -507,11 +509,11 @@ status_t AudioSystem::setDeviceConnectionState(audio_devices device, return aps->setDeviceConnectionState(device, state, device_address); } -AudioSystem::device_connection_state AudioSystem::getDeviceConnectionState(audio_devices device, +audio_policy_dev_state_t AudioSystem::getDeviceConnectionState(audio_devices_t device, const char *device_address) { const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service(); - if (aps == 0) return DEVICE_STATE_UNAVAILABLE; + if (aps == 0) return AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE; return aps->getDeviceConnectionState(device, device_address); } @@ -531,26 +533,26 @@ status_t AudioSystem::setRingerMode(uint32_t mode, uint32_t mask) return aps->setRingerMode(mode, mask); } -status_t AudioSystem::setForceUse(force_use usage, forced_config config) +status_t AudioSystem::setForceUse(audio_policy_force_use_t usage, audio_policy_forced_cfg_t config) { const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service(); if (aps == 0) return PERMISSION_DENIED; return aps->setForceUse(usage, config); } -AudioSystem::forced_config AudioSystem::getForceUse(force_use usage) +audio_policy_forced_cfg_t AudioSystem::getForceUse(audio_policy_force_use_t usage) { const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service(); - if (aps == 0) return FORCE_NONE; + if (aps == 0) return AUDIO_POLICY_FORCE_NONE; return aps->getForceUse(usage); } -audio_io_handle_t AudioSystem::getOutput(stream_type stream, +audio_io_handle_t AudioSystem::getOutput(audio_stream_type_t stream, uint32_t samplingRate, uint32_t format, uint32_t channels, - output_flags flags) + audio_policy_output_flags_t flags) { audio_io_handle_t output = 0; // Do not use stream to output map cache if the direct output @@ -561,9 +563,9 @@ audio_io_handle_t AudioSystem::getOutput(stream_type stream, // be reworked for proper operation with direct outputs. This code is too specific // to the first use case we want to cover (Voice Recognition and Voice Dialer over // Bluetooth SCO - if ((flags & AudioSystem::OUTPUT_FLAG_DIRECT) == 0 && - ((stream != AudioSystem::VOICE_CALL && stream != AudioSystem::BLUETOOTH_SCO) || - channels != AudioSystem::CHANNEL_OUT_MONO || + if ((flags & AUDIO_POLICY_OUTPUT_FLAG_DIRECT) == 0 && + ((stream != AUDIO_STREAM_VOICE_CALL && stream != AUDIO_STREAM_BLUETOOTH_SCO) || + channels != AUDIO_CHANNEL_OUT_MONO || (samplingRate != 8000 && samplingRate != 16000))) { Mutex::Autolock _l(gLock); output = AudioSystem::gStreamOutputMap.valueFor(stream); @@ -573,7 +575,7 @@ audio_io_handle_t AudioSystem::getOutput(stream_type stream, const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service(); if (aps == 0) return 0; output = aps->getOutput(stream, samplingRate, format, channels, flags); - if ((flags & AudioSystem::OUTPUT_FLAG_DIRECT) == 0) { + if ((flags & AUDIO_POLICY_OUTPUT_FLAG_DIRECT) == 0) { Mutex::Autolock _l(gLock); AudioSystem::gStreamOutputMap.add(stream, output); } @@ -582,7 +584,7 @@ audio_io_handle_t AudioSystem::getOutput(stream_type stream, } status_t AudioSystem::startOutput(audio_io_handle_t output, - AudioSystem::stream_type stream, + audio_stream_type_t stream, int session) { const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service(); @@ -591,7 +593,7 @@ status_t AudioSystem::startOutput(audio_io_handle_t output, } status_t AudioSystem::stopOutput(audio_io_handle_t output, - AudioSystem::stream_type stream, + audio_stream_type_t stream, int session) { const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service(); @@ -610,7 +612,7 @@ audio_io_handle_t AudioSystem::getInput(int inputSource, uint32_t samplingRate, uint32_t format, uint32_t channels, - audio_in_acoustics acoustics) + audio_in_acoustics_t acoustics) { const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service(); if (aps == 0) return 0; @@ -638,7 +640,7 @@ void AudioSystem::releaseInput(audio_io_handle_t input) aps->releaseInput(input); } -status_t AudioSystem::initStreamVolume(stream_type stream, +status_t AudioSystem::initStreamVolume(audio_stream_type_t stream, int indexMin, int indexMax) { @@ -647,28 +649,28 @@ status_t AudioSystem::initStreamVolume(stream_type stream, return aps->initStreamVolume(stream, indexMin, indexMax); } -status_t AudioSystem::setStreamVolumeIndex(stream_type stream, int index) +status_t AudioSystem::setStreamVolumeIndex(audio_stream_type_t stream, int index) { const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service(); if (aps == 0) return PERMISSION_DENIED; return aps->setStreamVolumeIndex(stream, index); } -status_t AudioSystem::getStreamVolumeIndex(stream_type stream, int *index) +status_t AudioSystem::getStreamVolumeIndex(audio_stream_type_t stream, int *index) { const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service(); if (aps == 0) return PERMISSION_DENIED; return aps->getStreamVolumeIndex(stream, index); } -uint32_t AudioSystem::getStrategyForStream(AudioSystem::stream_type stream) +uint32_t AudioSystem::getStrategyForStream(audio_stream_type_t stream) { const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service(); if (aps == 0) return 0; return aps->getStrategyForStream(stream); } -uint32_t AudioSystem::getDevicesForStream(AudioSystem::stream_type stream) +uint32_t AudioSystem::getDevicesForStream(audio_stream_type_t stream) { const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service(); if (aps == 0) return 0; @@ -717,276 +719,5 @@ void AudioSystem::AudioPolicyServiceClient::binderDied(const wp<IBinder>& who) { LOGW("AudioPolicyService server died!"); } -// --------------------------------------------------------------------------- - - -// use emulated popcount optimization -// http://www.df.lth.se/~john_e/gems/gem002d.html -uint32_t AudioSystem::popCount(uint32_t u) -{ - u = ((u&0x55555555) + ((u>>1)&0x55555555)); - u = ((u&0x33333333) + ((u>>2)&0x33333333)); - u = ((u&0x0f0f0f0f) + ((u>>4)&0x0f0f0f0f)); - u = ((u&0x00ff00ff) + ((u>>8)&0x00ff00ff)); - u = ( u&0x0000ffff) + (u>>16); - return u; -} - -bool AudioSystem::isOutputDevice(audio_devices device) -{ - if ((popCount(device) == 1 ) && - ((device & ~AudioSystem::DEVICE_OUT_ALL) == 0)) { - return true; - } else { - return false; - } -} - -bool AudioSystem::isInputDevice(audio_devices device) -{ - if ((popCount(device) == 1 ) && - ((device & ~AudioSystem::DEVICE_IN_ALL) == 0)) { - return true; - } else { - return false; - } -} - -bool AudioSystem::isA2dpDevice(audio_devices device) -{ - if ((popCount(device) == 1 ) && - (device & (AudioSystem::DEVICE_OUT_BLUETOOTH_A2DP | - AudioSystem::DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES | - AudioSystem::DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER))) { - return true; - } else { - return false; - } -} - -bool AudioSystem::isBluetoothScoDevice(audio_devices device) -{ - if ((popCount(device) == 1 ) && - (device & (AudioSystem::DEVICE_OUT_BLUETOOTH_SCO | - AudioSystem::DEVICE_OUT_BLUETOOTH_SCO_HEADSET | - AudioSystem::DEVICE_OUT_BLUETOOTH_SCO_CARKIT | - AudioSystem::DEVICE_IN_BLUETOOTH_SCO_HEADSET))) { - return true; - } else { - return false; - } -} - -bool AudioSystem::isLowVisibility(stream_type stream) -{ - if (stream == AudioSystem::SYSTEM || - stream == AudioSystem::NOTIFICATION || - stream == AudioSystem::RING) { - return true; - } else { - return false; - } -} - -bool AudioSystem::isInputChannel(uint32_t channel) -{ - if ((channel & ~AudioSystem::CHANNEL_IN_ALL) == 0) { - return true; - } else { - return false; - } -} - -bool AudioSystem::isOutputChannel(uint32_t channel) -{ - if ((channel & ~AudioSystem::CHANNEL_OUT_ALL) == 0) { - return true; - } else { - return false; - } -} - -bool AudioSystem::isValidFormat(uint32_t format) -{ - switch (format & MAIN_FORMAT_MASK) { - case PCM: - case MP3: - case AMR_NB: - case AMR_WB: - case AAC: - case HE_AAC_V1: - case HE_AAC_V2: - case VORBIS: - return true; - default: - return false; - } -} - -bool AudioSystem::isLinearPCM(uint32_t format) -{ - switch (format) { - case PCM_16_BIT: - case PCM_8_BIT: - return true; - default: - return false; - } -} - -//------------------------- AudioParameter class implementation --------------- - -const char *AudioParameter::keyRouting = "routing"; -const char *AudioParameter::keySamplingRate = "sampling_rate"; -const char *AudioParameter::keyFormat = "format"; -const char *AudioParameter::keyChannels = "channels"; -const char *AudioParameter::keyFrameCount = "frame_count"; -const char *AudioParameter::keyInputSource = "input_source"; - -AudioParameter::AudioParameter(const String8& keyValuePairs) -{ - char *str = new char[keyValuePairs.length()+1]; - mKeyValuePairs = keyValuePairs; - - strcpy(str, keyValuePairs.string()); - char *pair = strtok(str, ";"); - while (pair != NULL) { - if (strlen(pair) != 0) { - size_t eqIdx = strcspn(pair, "="); - String8 key = String8(pair, eqIdx); - String8 value; - if (eqIdx == strlen(pair)) { - value = String8(""); - } else { - value = String8(pair + eqIdx + 1); - } - if (mParameters.indexOfKey(key) < 0) { - mParameters.add(key, value); - } else { - mParameters.replaceValueFor(key, value); - } - } else { - LOGV("AudioParameter() cstor empty key value pair"); - } - pair = strtok(NULL, ";"); - } - - delete[] str; -} - -AudioParameter::~AudioParameter() -{ - mParameters.clear(); -} - -String8 AudioParameter::toString() -{ - String8 str = String8(""); - - size_t size = mParameters.size(); - for (size_t i = 0; i < size; i++) { - str += mParameters.keyAt(i); - str += "="; - str += mParameters.valueAt(i); - if (i < (size - 1)) str += ";"; - } - return str; -} - -status_t AudioParameter::add(const String8& key, const String8& value) -{ - if (mParameters.indexOfKey(key) < 0) { - mParameters.add(key, value); - return NO_ERROR; - } else { - mParameters.replaceValueFor(key, value); - return ALREADY_EXISTS; - } -} - -status_t AudioParameter::addInt(const String8& key, const int value) -{ - char str[12]; - if (snprintf(str, 12, "%d", value) > 0) { - String8 str8 = String8(str); - return add(key, str8); - } else { - return BAD_VALUE; - } -} - -status_t AudioParameter::addFloat(const String8& key, const float value) -{ - char str[23]; - if (snprintf(str, 23, "%.10f", value) > 0) { - String8 str8 = String8(str); - return add(key, str8); - } else { - return BAD_VALUE; - } -} - -status_t AudioParameter::remove(const String8& key) -{ - if (mParameters.indexOfKey(key) >= 0) { - mParameters.removeItem(key); - return NO_ERROR; - } else { - return BAD_VALUE; - } -} - -status_t AudioParameter::get(const String8& key, String8& value) -{ - if (mParameters.indexOfKey(key) >= 0) { - value = mParameters.valueFor(key); - return NO_ERROR; - } else { - return BAD_VALUE; - } -} - -status_t AudioParameter::getInt(const String8& key, int& value) -{ - String8 str8; - status_t result = get(key, str8); - value = 0; - if (result == NO_ERROR) { - int val; - if (sscanf(str8.string(), "%d", &val) == 1) { - value = val; - } else { - result = INVALID_OPERATION; - } - } - return result; -} - -status_t AudioParameter::getFloat(const String8& key, float& value) -{ - String8 str8; - status_t result = get(key, str8); - value = 0; - if (result == NO_ERROR) { - float val; - if (sscanf(str8.string(), "%f", &val) == 1) { - value = val; - } else { - result = INVALID_OPERATION; - } - } - return result; -} - -status_t AudioParameter::getAt(size_t index, String8& key, String8& value) -{ - if (mParameters.size() > index) { - key = mParameters.keyAt(index); - value = mParameters.valueAt(index); - return NO_ERROR; - } else { - return BAD_VALUE; - } -} }; // namespace android diff --git a/media/libmedia/AudioTrack.cpp b/media/libmedia/AudioTrack.cpp index 8d8f67b..7520ed9 100644 --- a/media/libmedia/AudioTrack.cpp +++ b/media/libmedia/AudioTrack.cpp @@ -35,6 +35,12 @@ #include <binder/Parcel.h> #include <binder/IPCThreadState.h> #include <utils/Timers.h> +#include <utils/Atomic.h> + +#include <cutils/bitops.h> + +#include <system/audio.h> +#include <hardware/audio_policy.h> #define LIKELY( exp ) (__builtin_expect( (exp) != 0, true )) #define UNLIKELY( exp ) (__builtin_expect( (exp) != 0, false )) @@ -164,39 +170,41 @@ status_t AudioTrack::set( } // handle default values first. - if (streamType == AudioSystem::DEFAULT) { - streamType = AudioSystem::MUSIC; + if (streamType == AUDIO_STREAM_DEFAULT) { + streamType = AUDIO_STREAM_MUSIC; } if (sampleRate == 0) { sampleRate = afSampleRate; } // these below should probably come from the audioFlinger too... if (format == 0) { - format = AudioSystem::PCM_16_BIT; + format = AUDIO_FORMAT_PCM_16_BIT; } if (channels == 0) { - channels = AudioSystem::CHANNEL_OUT_STEREO; + channels = AUDIO_CHANNEL_OUT_STEREO; } // validate parameters - if (!AudioSystem::isValidFormat(format)) { + if (!audio_is_valid_format(format)) { LOGE("Invalid format"); return BAD_VALUE; } // force direct flag if format is not linear PCM - if (!AudioSystem::isLinearPCM(format)) { - flags |= AudioSystem::OUTPUT_FLAG_DIRECT; + if (!audio_is_linear_pcm(format)) { + flags |= AUDIO_POLICY_OUTPUT_FLAG_DIRECT; } - if (!AudioSystem::isOutputChannel(channels)) { + if (!audio_is_output_channel(channels)) { LOGE("Invalid channel mask"); return BAD_VALUE; } - uint32_t channelCount = AudioSystem::popCount(channels); + uint32_t channelCount = popcount(channels); - audio_io_handle_t output = AudioSystem::getOutput((AudioSystem::stream_type)streamType, - sampleRate, format, channels, (AudioSystem::output_flags)flags); + audio_io_handle_t output = AudioSystem::getOutput( + (audio_stream_type_t)streamType, + sampleRate,format, channels, + (audio_policy_output_flags_t)flags); if (output == 0) { LOGE("Could not get audio output for stream type %d", streamType); @@ -289,8 +297,8 @@ uint32_t AudioTrack::frameCount() const int AudioTrack::frameSize() const { - if (AudioSystem::isLinearPCM(mFormat)) { - return channelCount()*((format() == AudioSystem::PCM_8_BIT) ? sizeof(uint8_t) : sizeof(int16_t)); + if (audio_is_linear_pcm(mFormat)) { + return channelCount()*((format() == AUDIO_FORMAT_PCM_8_BIT) ? sizeof(uint8_t) : sizeof(int16_t)); } else { return sizeof(uint8_t); } @@ -329,9 +337,10 @@ void AudioTrack::start() if (mActive == 0) { mActive = 1; mNewPosition = cblk->server + mUpdatePeriod; + cblk->lock.lock(); cblk->bufferTimeoutMs = MAX_STARTUP_TIMEOUT_MS; cblk->waitTimeMs = 0; - cblk->flags &= ~CBLK_DISABLED_ON; + android_atomic_and(~CBLK_DISABLED_ON, &cblk->flags); if (t != 0) { t->run("AudioTrackThread", THREAD_PRIORITY_AUDIO_CLIENT); } else { @@ -339,13 +348,12 @@ void AudioTrack::start() } LOGV("start %p before lock cblk %p", this, mCblk); - cblk->lock.lock(); if (!(cblk->flags & CBLK_INVALID_MSK)) { cblk->lock.unlock(); status = mAudioTrack->start(); cblk->lock.lock(); if (status == DEAD_OBJECT) { - cblk->flags |= CBLK_INVALID_MSK; + android_atomic_or(CBLK_INVALID_ON, &cblk->flags); } } if (cblk->flags & CBLK_INVALID_MSK) { @@ -546,12 +554,13 @@ status_t AudioTrack::setLoop_l(uint32_t loopStart, uint32_t loopEnd, int loopCou } if (loopStart >= loopEnd || - loopEnd - loopStart > cblk->frameCount) { + loopEnd - loopStart > cblk->frameCount || + cblk->server > loopStart) { LOGE("setLoop invalid value: loopStart %d, loopEnd %d, loopCount %d, framecount %d, user %d", loopStart, loopEnd, loopCount, cblk->frameCount, cblk->user); return BAD_VALUE; } - if ((mSharedBuffer != 0) && (loopEnd > cblk->frameCount)) { + if ((mSharedBuffer != 0) && (loopEnd > cblk->frameCount)) { LOGE("setLoop invalid value: loop markers beyond data: loopStart %d, loopEnd %d, framecount %d", loopStart, loopEnd, cblk->frameCount); return BAD_VALUE; @@ -635,7 +644,7 @@ status_t AudioTrack::setPosition(uint32_t position) if (position > mCblk->user) return BAD_VALUE; mCblk->server = position; - mCblk->flags |= CBLK_FORCEREADY_ON; + android_atomic_or(CBLK_FORCEREADY_ON, &mCblk->flags); return NO_ERROR; } @@ -671,8 +680,8 @@ audio_io_handle_t AudioTrack::getOutput() // must be called with mLock held audio_io_handle_t AudioTrack::getOutput_l() { - return AudioSystem::getOutput((AudioSystem::stream_type)mStreamType, - mCblk->sampleRate, mFormat, mChannels, (AudioSystem::output_flags)mFlags); + return AudioSystem::getOutput((audio_stream_type_t)mStreamType, + mCblk->sampleRate, mFormat, mChannels, (audio_policy_output_flags_t)mFlags); } int AudioTrack::getSessionId() @@ -725,7 +734,7 @@ status_t AudioTrack::createTrack_l( } mNotificationFramesAct = mNotificationFramesReq; - if (!AudioSystem::isLinearPCM(format)) { + if (!audio_is_linear_pcm(format)) { if (sharedBuffer != 0) { frameCount = sharedBuffer->size(); } @@ -792,7 +801,7 @@ status_t AudioTrack::createTrack_l( mCblkMemory.clear(); mCblkMemory = cblk; mCblk = static_cast<audio_track_cblk_t*>(cblk->pointer()); - mCblk->flags |= CBLK_DIRECTION_OUT; + android_atomic_or(CBLK_DIRECTION_OUT, &mCblk->flags); if (sharedBuffer == 0) { mCblk->buffers = (char*)mCblk + sizeof(audio_track_cblk_t); } else { @@ -825,6 +834,12 @@ status_t AudioTrack::obtainBuffer(Buffer* audioBuffer, int32_t waitCount) uint32_t framesAvail = cblk->framesAvailable(); + cblk->lock.lock(); + if (cblk->flags & CBLK_INVALID_MSK) { + goto create_new_track; + } + cblk->lock.unlock(); + if (framesAvail == 0) { cblk->lock.lock(); goto start_loop_here; @@ -866,7 +881,7 @@ status_t AudioTrack::obtainBuffer(Buffer* audioBuffer, int32_t waitCount) result = mAudioTrack->start(); cblk->lock.lock(); if (result == DEAD_OBJECT) { - cblk->flags |= CBLK_INVALID_MSK; + android_atomic_or(CBLK_INVALID_ON, &cblk->flags); create_new_track: result = restoreTrack_l(cblk, false); } @@ -893,7 +908,7 @@ create_new_track: // restart track if it was disabled by audioflinger due to previous underrun if (mActive && (cblk->flags & CBLK_DISABLED_MSK)) { - cblk->flags &= ~CBLK_DISABLED_ON; + android_atomic_and(~CBLK_DISABLED_ON, &cblk->flags); LOGW("obtainBuffer() track %p disabled, restarting", this); mAudioTrack->start(); } @@ -915,8 +930,8 @@ create_new_track: audioBuffer->channelCount = mChannelCount; audioBuffer->frameCount = framesReq; audioBuffer->size = framesReq * cblk->frameSize; - if (AudioSystem::isLinearPCM(mFormat)) { - audioBuffer->format = AudioSystem::PCM_16_BIT; + if (audio_is_linear_pcm(mFormat)) { + audioBuffer->format = AUDIO_FORMAT_PCM_16_BIT; } else { audioBuffer->format = mFormat; } @@ -957,9 +972,10 @@ ssize_t AudioTrack::write(const void* buffer, size_t userSize) ssize_t written = 0; const int8_t *src = (const int8_t *)buffer; Buffer audioBuffer; + size_t frameSz = (size_t)frameSize(); do { - audioBuffer.frameCount = userSize/frameSize(); + audioBuffer.frameCount = userSize/frameSz; // Calling obtainBuffer() with a negative wait count causes // an (almost) infinite wait time. @@ -973,7 +989,7 @@ ssize_t AudioTrack::write(const void* buffer, size_t userSize) size_t toWrite; - if (mFormat == AudioSystem::PCM_8_BIT && !(mFlags & AudioSystem::OUTPUT_FLAG_DIRECT)) { + if (mFormat == AUDIO_FORMAT_PCM_8_BIT && !(mFlags & AUDIO_POLICY_OUTPUT_FLAG_DIRECT)) { // Divide capacity by 2 to take expansion into account toWrite = audioBuffer.size>>1; // 8 to 16 bit conversion @@ -991,7 +1007,7 @@ ssize_t AudioTrack::write(const void* buffer, size_t userSize) written += toWrite; releaseBuffer(&audioBuffer); - } while (userSize); + } while (userSize >= frameSz); return written; } @@ -1013,14 +1029,13 @@ bool AudioTrack::processAudioBuffer(const sp<AudioTrackThread>& thread) mLock.unlock(); // Manage underrun callback - if (mActive && (cblk->framesReady() == 0)) { + if (mActive && (cblk->framesAvailable() == cblk->frameCount)) { LOGV("Underrun user: %x, server: %x, flags %04x", cblk->user, cblk->server, cblk->flags); - if ((cblk->flags & CBLK_UNDERRUN_MSK) == CBLK_UNDERRUN_OFF) { + if (!(android_atomic_or(CBLK_UNDERRUN_ON, &cblk->flags) & CBLK_UNDERRUN_MSK)) { mCbf(EVENT_UNDERRUN, mUserData, 0); if (cblk->server == cblk->frameCount) { mCbf(EVENT_BUFFER_END, mUserData, 0); } - cblk->flags |= CBLK_UNDERRUN_ON; if (mSharedBuffer != 0) return false; } } @@ -1077,7 +1092,7 @@ bool AudioTrack::processAudioBuffer(const sp<AudioTrackThread>& thread) // Divide buffer size by 2 to take into account the expansion // due to 8 to 16 bit conversion: the callback must fill only half // of the destination buffer - if (mFormat == AudioSystem::PCM_8_BIT && !(mFlags & AudioSystem::OUTPUT_FLAG_DIRECT)) { + if (mFormat == AUDIO_FORMAT_PCM_8_BIT && !(mFlags & AUDIO_POLICY_OUTPUT_FLAG_DIRECT)) { audioBuffer.size >>= 1; } @@ -1096,7 +1111,7 @@ bool AudioTrack::processAudioBuffer(const sp<AudioTrackThread>& thread) } if (writtenSize > reqSize) writtenSize = reqSize; - if (mFormat == AudioSystem::PCM_8_BIT && !(mFlags & AudioSystem::OUTPUT_FLAG_DIRECT)) { + if (mFormat == AUDIO_FORMAT_PCM_8_BIT && !(mFlags & AUDIO_POLICY_OUTPUT_FLAG_DIRECT)) { // 8 to 16 bit conversion const int8_t *src = audioBuffer.i8 + writtenSize-1; int count = writtenSize; @@ -1134,11 +1149,10 @@ status_t AudioTrack::restoreTrack_l(audio_track_cblk_t*& cblk, bool fromStart) { status_t result; - if (!(cblk->flags & CBLK_RESTORING_MSK)) { + if (!(android_atomic_or(CBLK_RESTORING_ON, &cblk->flags) & CBLK_RESTORING_MSK)) { LOGW("dead IAudioTrack, creating a new one from %s", fromStart ? "start()" : "obtainBuffer()"); - cblk->flags |= CBLK_RESTORING_ON; // signal old cblk condition so that other threads waiting for available buffers stop // waiting now cblk->cv.broadcast(); @@ -1158,10 +1172,20 @@ status_t AudioTrack::restoreTrack_l(audio_track_cblk_t*& cblk, bool fromStart) false); if (result == NO_ERROR) { + // restore write index and set other indexes to reflect empty buffer status + mCblk->user = cblk->user; + mCblk->server = cblk->user; + mCblk->userBase = cblk->user; + mCblk->serverBase = cblk->user; + // restore loop: this is not guaranteed to succeed if new frame count is not + // compatible with loop length + setLoop_l(cblk->loopStart, cblk->loopEnd, cblk->loopCount); if (!fromStart) { mCblk->bufferTimeoutMs = MAX_RUN_TIMEOUT_MS; } - result = mAudioTrack->start(); + if (mActive) { + result = mAudioTrack->start(); + } if (fromStart && result == NO_ERROR) { mNewPosition = mCblk->server + mUpdatePeriod; } @@ -1171,10 +1195,8 @@ status_t AudioTrack::restoreTrack_l(audio_track_cblk_t*& cblk, bool fromStart) } // signal old cblk condition for other threads waiting for restore completion - cblk->lock.lock(); - cblk->flags |= CBLK_RESTORED_MSK; + android_atomic_or(CBLK_RESTORED_ON, &cblk->flags); cblk->cv.broadcast(); - cblk->lock.unlock(); } else { if (!(cblk->flags & CBLK_RESTORED_MSK)) { LOGW("dead IAudioTrack, waiting for a new one"); @@ -1248,11 +1270,12 @@ void AudioTrack::AudioTrackThread::onFirstRef() // ========================================================================= + audio_track_cblk_t::audio_track_cblk_t() : lock(Mutex::SHARED), cv(Condition::SHARED), user(0), server(0), userBase(0), serverBase(0), buffers(0), frameCount(0), loopStart(UINT_MAX), loopEnd(UINT_MAX), loopCount(0), volumeLR(0), - flags(0), sendLevel(0) + sendLevel(0), flags(0) { } @@ -1279,25 +1302,17 @@ uint32_t audio_track_cblk_t::stepUser(uint32_t frameCount) this->user = u; // Clear flow control error condition as new data has been written/read to/from buffer. - flags &= ~CBLK_UNDERRUN_MSK; + if (flags & CBLK_UNDERRUN_MSK) { + android_atomic_and(~CBLK_UNDERRUN_MSK, &flags); + } return u; } bool audio_track_cblk_t::stepServer(uint32_t frameCount) { - // the code below simulates lock-with-timeout - // we MUST do this to protect the AudioFlinger server - // as this lock is shared with the client. - status_t err; - - err = lock.tryLock(); - if (err == -EBUSY) { // just wait a bit - usleep(1000); - err = lock.tryLock(); - } - if (err != NO_ERROR) { - // probably, the client just died. + if (!tryLock()) { + LOGW("stepServer() could not lock cblk"); return false; } @@ -1374,18 +1389,42 @@ uint32_t audio_track_cblk_t::framesReady() if (u < loopEnd) { return u - s; } else { - Mutex::Autolock _l(lock); + // do not block on mutex shared with client on AudioFlinger side + if (!tryLock()) { + LOGW("framesReady() could not lock cblk"); + return 0; + } + uint32_t frames = UINT_MAX; if (loopCount >= 0) { - return (loopEnd - loopStart)*loopCount + u - s; - } else { - return UINT_MAX; + frames = (loopEnd - loopStart)*loopCount + u - s; } + lock.unlock(); + return frames; } } else { return s - u; } } +bool audio_track_cblk_t::tryLock() +{ + // the code below simulates lock-with-timeout + // we MUST do this to protect the AudioFlinger server + // as this lock is shared with the client. + status_t err; + + err = lock.tryLock(); + if (err == -EBUSY) { // just wait a bit + usleep(1000); + err = lock.tryLock(); + } + if (err != NO_ERROR) { + // probably, the client just died. + return false; + } + return true; +} + // ------------------------------------------------------------------------- }; // namespace android diff --git a/media/libmedia/IAudioPolicyService.cpp b/media/libmedia/IAudioPolicyService.cpp index b89a278..9fbcee0 100644 --- a/media/libmedia/IAudioPolicyService.cpp +++ b/media/libmedia/IAudioPolicyService.cpp @@ -25,6 +25,8 @@ #include <media/IAudioPolicyService.h> +#include <system/audio.h> + namespace android { enum { @@ -62,8 +64,8 @@ public: } virtual status_t setDeviceConnectionState( - AudioSystem::audio_devices device, - AudioSystem::device_connection_state state, + audio_devices_t device, + audio_policy_dev_state_t state, const char *device_address) { Parcel data, reply; @@ -75,8 +77,8 @@ public: return static_cast <status_t> (reply.readInt32()); } - virtual AudioSystem::device_connection_state getDeviceConnectionState( - AudioSystem::audio_devices device, + virtual audio_policy_dev_state_t getDeviceConnectionState( + audio_devices_t device, const char *device_address) { Parcel data, reply; @@ -84,7 +86,7 @@ public: data.writeInt32(static_cast <uint32_t>(device)); data.writeCString(device_address); remote()->transact(GET_DEVICE_CONNECTION_STATE, data, &reply); - return static_cast <AudioSystem::device_connection_state>(reply.readInt32()); + return static_cast <audio_policy_dev_state_t>(reply.readInt32()); } virtual status_t setPhoneState(int state) @@ -106,7 +108,7 @@ public: return static_cast <status_t> (reply.readInt32()); } - virtual status_t setForceUse(AudioSystem::force_use usage, AudioSystem::forced_config config) + virtual status_t setForceUse(audio_policy_force_use_t usage, audio_policy_forced_cfg_t config) { Parcel data, reply; data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor()); @@ -116,21 +118,21 @@ public: return static_cast <status_t> (reply.readInt32()); } - virtual AudioSystem::forced_config getForceUse(AudioSystem::force_use usage) + virtual audio_policy_forced_cfg_t getForceUse(audio_policy_force_use_t usage) { Parcel data, reply; data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor()); data.writeInt32(static_cast <uint32_t>(usage)); remote()->transact(GET_FORCE_USE, data, &reply); - return static_cast <AudioSystem::forced_config> (reply.readInt32()); + return static_cast <audio_policy_forced_cfg_t> (reply.readInt32()); } virtual audio_io_handle_t getOutput( - AudioSystem::stream_type stream, + audio_stream_type_t stream, uint32_t samplingRate, uint32_t format, uint32_t channels, - AudioSystem::output_flags flags) + audio_policy_output_flags_t flags) { Parcel data, reply; data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor()); @@ -144,7 +146,7 @@ public: } virtual status_t startOutput(audio_io_handle_t output, - AudioSystem::stream_type stream, + audio_stream_type_t stream, int session) { Parcel data, reply; @@ -157,7 +159,7 @@ public: } virtual status_t stopOutput(audio_io_handle_t output, - AudioSystem::stream_type stream, + audio_stream_type_t stream, int session) { Parcel data, reply; @@ -182,7 +184,7 @@ public: uint32_t samplingRate, uint32_t format, uint32_t channels, - AudioSystem::audio_in_acoustics acoustics) + audio_in_acoustics_t acoustics) { Parcel data, reply; data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor()); @@ -221,7 +223,7 @@ public: remote()->transact(RELEASE_INPUT, data, &reply); } - virtual status_t initStreamVolume(AudioSystem::stream_type stream, + virtual status_t initStreamVolume(audio_stream_type_t stream, int indexMin, int indexMax) { @@ -234,7 +236,7 @@ public: return static_cast <status_t> (reply.readInt32()); } - virtual status_t setStreamVolumeIndex(AudioSystem::stream_type stream, int index) + virtual status_t setStreamVolumeIndex(audio_stream_type_t stream, int index) { Parcel data, reply; data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor()); @@ -244,7 +246,7 @@ public: return static_cast <status_t> (reply.readInt32()); } - virtual status_t getStreamVolumeIndex(AudioSystem::stream_type stream, int *index) + virtual status_t getStreamVolumeIndex(audio_stream_type_t stream, int *index) { Parcel data, reply; data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor()); @@ -255,7 +257,7 @@ public: return static_cast <status_t> (reply.readInt32()); } - virtual uint32_t getStrategyForStream(AudioSystem::stream_type stream) + virtual uint32_t getStrategyForStream(audio_stream_type_t stream) { Parcel data, reply; data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor()); @@ -264,7 +266,7 @@ public: return reply.readInt32(); } - virtual uint32_t getDevicesForStream(AudioSystem::stream_type stream) + virtual uint32_t getDevicesForStream(audio_stream_type_t stream) { Parcel data, reply; data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor()); @@ -330,10 +332,10 @@ status_t BnAudioPolicyService::onTransact( switch(code) { case SET_DEVICE_CONNECTION_STATE: { CHECK_INTERFACE(IAudioPolicyService, data, reply); - AudioSystem::audio_devices device = - static_cast <AudioSystem::audio_devices>(data.readInt32()); - AudioSystem::device_connection_state state = - static_cast <AudioSystem::device_connection_state>(data.readInt32()); + audio_devices_t device = + static_cast <audio_devices_t>(data.readInt32()); + audio_policy_dev_state_t state = + static_cast <audio_policy_dev_state_t>(data.readInt32()); const char *device_address = data.readCString(); reply->writeInt32(static_cast<uint32_t> (setDeviceConnectionState(device, state, @@ -343,8 +345,8 @@ status_t BnAudioPolicyService::onTransact( case GET_DEVICE_CONNECTION_STATE: { CHECK_INTERFACE(IAudioPolicyService, data, reply); - AudioSystem::audio_devices device = - static_cast<AudioSystem::audio_devices> (data.readInt32()); + audio_devices_t device = + static_cast<audio_devices_t> (data.readInt32()); const char *device_address = data.readCString(); reply->writeInt32(static_cast<uint32_t> (getDeviceConnectionState(device, device_address))); @@ -367,29 +369,29 @@ status_t BnAudioPolicyService::onTransact( case SET_FORCE_USE: { CHECK_INTERFACE(IAudioPolicyService, data, reply); - AudioSystem::force_use usage = static_cast <AudioSystem::force_use>(data.readInt32()); - AudioSystem::forced_config config = - static_cast <AudioSystem::forced_config>(data.readInt32()); + audio_policy_force_use_t usage = static_cast <audio_policy_force_use_t>(data.readInt32()); + audio_policy_forced_cfg_t config = + static_cast <audio_policy_forced_cfg_t>(data.readInt32()); reply->writeInt32(static_cast <uint32_t>(setForceUse(usage, config))); return NO_ERROR; } break; case GET_FORCE_USE: { CHECK_INTERFACE(IAudioPolicyService, data, reply); - AudioSystem::force_use usage = static_cast <AudioSystem::force_use>(data.readInt32()); + audio_policy_force_use_t usage = static_cast <audio_policy_force_use_t>(data.readInt32()); reply->writeInt32(static_cast <uint32_t>(getForceUse(usage))); return NO_ERROR; } break; case GET_OUTPUT: { CHECK_INTERFACE(IAudioPolicyService, data, reply); - AudioSystem::stream_type stream = - static_cast <AudioSystem::stream_type>(data.readInt32()); + audio_stream_type_t stream = + static_cast <audio_stream_type_t>(data.readInt32()); uint32_t samplingRate = data.readInt32(); uint32_t format = data.readInt32(); uint32_t channels = data.readInt32(); - AudioSystem::output_flags flags = - static_cast <AudioSystem::output_flags>(data.readInt32()); + audio_policy_output_flags_t flags = + static_cast <audio_policy_output_flags_t>(data.readInt32()); audio_io_handle_t output = getOutput(stream, samplingRate, @@ -406,7 +408,7 @@ status_t BnAudioPolicyService::onTransact( uint32_t stream = data.readInt32(); int session = data.readInt32(); reply->writeInt32(static_cast <uint32_t>(startOutput(output, - (AudioSystem::stream_type)stream, + (audio_stream_type_t)stream, session))); return NO_ERROR; } break; @@ -417,7 +419,7 @@ status_t BnAudioPolicyService::onTransact( uint32_t stream = data.readInt32(); int session = data.readInt32(); reply->writeInt32(static_cast <uint32_t>(stopOutput(output, - (AudioSystem::stream_type)stream, + (audio_stream_type_t)stream, session))); return NO_ERROR; } break; @@ -435,8 +437,8 @@ status_t BnAudioPolicyService::onTransact( uint32_t samplingRate = data.readInt32(); uint32_t format = data.readInt32(); uint32_t channels = data.readInt32(); - AudioSystem::audio_in_acoustics acoustics = - static_cast <AudioSystem::audio_in_acoustics>(data.readInt32()); + audio_in_acoustics_t acoustics = + static_cast <audio_in_acoustics_t>(data.readInt32()); audio_io_handle_t input = getInput(inputSource, samplingRate, format, @@ -469,8 +471,8 @@ status_t BnAudioPolicyService::onTransact( case INIT_STREAM_VOLUME: { CHECK_INTERFACE(IAudioPolicyService, data, reply); - AudioSystem::stream_type stream = - static_cast <AudioSystem::stream_type>(data.readInt32()); + audio_stream_type_t stream = + static_cast <audio_stream_type_t>(data.readInt32()); int indexMin = data.readInt32(); int indexMax = data.readInt32(); reply->writeInt32(static_cast <uint32_t>(initStreamVolume(stream, indexMin,indexMax))); @@ -479,8 +481,8 @@ status_t BnAudioPolicyService::onTransact( case SET_STREAM_VOLUME: { CHECK_INTERFACE(IAudioPolicyService, data, reply); - AudioSystem::stream_type stream = - static_cast <AudioSystem::stream_type>(data.readInt32()); + audio_stream_type_t stream = + static_cast <audio_stream_type_t>(data.readInt32()); int index = data.readInt32(); reply->writeInt32(static_cast <uint32_t>(setStreamVolumeIndex(stream, index))); return NO_ERROR; @@ -488,8 +490,8 @@ status_t BnAudioPolicyService::onTransact( case GET_STREAM_VOLUME: { CHECK_INTERFACE(IAudioPolicyService, data, reply); - AudioSystem::stream_type stream = - static_cast <AudioSystem::stream_type>(data.readInt32()); + audio_stream_type_t stream = + static_cast <audio_stream_type_t>(data.readInt32()); int index; status_t status = getStreamVolumeIndex(stream, &index); reply->writeInt32(index); @@ -499,16 +501,16 @@ status_t BnAudioPolicyService::onTransact( case GET_STRATEGY_FOR_STREAM: { CHECK_INTERFACE(IAudioPolicyService, data, reply); - AudioSystem::stream_type stream = - static_cast <AudioSystem::stream_type>(data.readInt32()); + audio_stream_type_t stream = + static_cast <audio_stream_type_t>(data.readInt32()); reply->writeInt32(getStrategyForStream(stream)); return NO_ERROR; } break; case GET_DEVICES_FOR_STREAM: { CHECK_INTERFACE(IAudioPolicyService, data, reply); - AudioSystem::stream_type stream = - static_cast <AudioSystem::stream_type>(data.readInt32()); + audio_stream_type_t stream = + static_cast <audio_stream_type_t>(data.readInt32()); reply->writeInt32(static_cast <int>(getDevicesForStream(stream))); return NO_ERROR; } break; diff --git a/media/libmedia/IMediaMetadataRetriever.cpp b/media/libmedia/IMediaMetadataRetriever.cpp index d5298c9..ebe821f 100644 --- a/media/libmedia/IMediaMetadataRetriever.cpp +++ b/media/libmedia/IMediaMetadataRetriever.cpp @@ -20,6 +20,7 @@ #include <binder/Parcel.h> #include <SkBitmap.h> #include <media/IMediaMetadataRetriever.h> +#include <utils/String8.h> // The binder is supposed to propagate the scheduler group across // the binder interface so that remote calls are executed with @@ -102,11 +103,24 @@ public: remote()->transact(DISCONNECT, data, &reply); } - status_t setDataSource(const char* srcUrl) + status_t setDataSource( + const char *srcUrl, const KeyedVector<String8, String8> *headers) { Parcel data, reply; data.writeInterfaceToken(IMediaMetadataRetriever::getInterfaceDescriptor()); data.writeCString(srcUrl); + + if (headers == NULL) { + data.writeInt32(0); + } else { + // serialize the headers + data.writeInt32(headers->size()); + for (size_t i = 0; i < headers->size(); ++i) { + data.writeString8(headers->keyAt(i)); + data.writeString8(headers->valueAt(i)); + } + } + remote()->transact(SET_DATA_SOURCE_URL, data, &reply); return reply.readInt32(); } @@ -188,7 +202,18 @@ status_t BnMediaMetadataRetriever::onTransact( case SET_DATA_SOURCE_URL: { CHECK_INTERFACE(IMediaMetadataRetriever, data, reply); const char* srcUrl = data.readCString(); - reply->writeInt32(setDataSource(srcUrl)); + + KeyedVector<String8, String8> headers; + int32_t numHeaders = data.readInt32(); + for (int i = 0; i < numHeaders; ++i) { + String8 key = data.readString8(); + String8 value = data.readString8(); + headers.add(key, value); + } + + reply->writeInt32( + setDataSource(srcUrl, numHeaders > 0 ? &headers : NULL)); + return NO_ERROR; } break; case SET_DATA_SOURCE_FD: { diff --git a/media/libmedia/IMediaPlayer.cpp b/media/libmedia/IMediaPlayer.cpp index 2399216..76a8a91 100644 --- a/media/libmedia/IMediaPlayer.cpp +++ b/media/libmedia/IMediaPlayer.cpp @@ -48,6 +48,8 @@ enum { SET_AUX_EFFECT_SEND_LEVEL, ATTACH_AUX_EFFECT, SET_VIDEO_SURFACETEXTURE, + SET_PARAMETER, + GET_PARAMETER, }; class BpMediaPlayer: public BpInterface<IMediaPlayer> @@ -192,8 +194,9 @@ public: } status_t invoke(const Parcel& request, Parcel *reply) - { // Avoid doing any extra copy. The interface descriptor should - // have been set by MediaPlayer.java. + { + // Avoid doing any extra copy. The interface descriptor should + // have been set by MediaPlayer.java. return remote()->transact(INVOKE, request, reply); } @@ -235,6 +238,26 @@ public: return reply.readInt32(); } + status_t setParameter(int key, const Parcel& request) + { + Parcel data, reply; + data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor()); + data.writeInt32(key); + if (request.dataSize() > 0) { + data.appendFrom(const_cast<Parcel *>(&request), 0, request.dataSize()); + } + remote()->transact(SET_PARAMETER, data, &reply); + return reply.readInt32(); + } + + status_t getParameter(int key, Parcel *reply) + { + Parcel data; + data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor()); + data.writeInt32(key); + return remote()->transact(GET_PARAMETER, data, reply); + } + }; IMPLEMENT_META_INTERFACE(MediaPlayer, "android.media.IMediaPlayer"); @@ -334,8 +357,8 @@ status_t BnMediaPlayer::onTransact( } break; case INVOKE: { CHECK_INTERFACE(IMediaPlayer, data, reply); - invoke(data, reply); - return NO_ERROR; + status_t result = invoke(data, reply); + return result; } break; case SET_METADATA_FILTER: { CHECK_INTERFACE(IMediaPlayer, data, reply); @@ -360,6 +383,23 @@ status_t BnMediaPlayer::onTransact( reply->writeInt32(attachAuxEffect(data.readInt32())); return NO_ERROR; } break; + case SET_PARAMETER: { + CHECK_INTERFACE(IMediaPlayer, data, reply); + int key = data.readInt32(); + + Parcel request; + if (data.dataAvail() > 0) { + request.appendFrom( + const_cast<Parcel *>(&data), data.dataPosition(), data.dataAvail()); + } + request.setDataPosition(0); + reply->writeInt32(setParameter(key, request)); + return NO_ERROR; + } break; + case GET_PARAMETER: { + CHECK_INTERFACE(IMediaPlayer, data, reply); + return getParameter(data.readInt32(), reply); + } break; default: return BBinder::onTransact(code, data, reply, flags); } diff --git a/media/libmedia/IMediaPlayerClient.cpp b/media/libmedia/IMediaPlayerClient.cpp index bf51829..1f135c4 100644 --- a/media/libmedia/IMediaPlayerClient.cpp +++ b/media/libmedia/IMediaPlayerClient.cpp @@ -35,13 +35,16 @@ public: { } - virtual void notify(int msg, int ext1, int ext2) + virtual void notify(int msg, int ext1, int ext2, const Parcel *obj) { Parcel data, reply; data.writeInterfaceToken(IMediaPlayerClient::getInterfaceDescriptor()); data.writeInt32(msg); data.writeInt32(ext1); data.writeInt32(ext2); + if (obj && obj->dataSize() > 0) { + data.appendFrom(const_cast<Parcel *>(obj), 0, obj->dataSize()); + } remote()->transact(NOTIFY, data, &reply, IBinder::FLAG_ONEWAY); } }; @@ -59,7 +62,12 @@ status_t BnMediaPlayerClient::onTransact( int msg = data.readInt32(); int ext1 = data.readInt32(); int ext2 = data.readInt32(); - notify(msg, ext1, ext2); + Parcel obj; + if (data.dataAvail() > 0) { + obj.appendFrom(const_cast<Parcel *>(&data), data.dataPosition(), data.dataAvail()); + } + + notify(msg, ext1, ext2, &obj); return NO_ERROR; } break; default: diff --git a/media/libmedia/JetPlayer.cpp b/media/libmedia/JetPlayer.cpp index ee9e1d8..88157d2 100644 --- a/media/libmedia/JetPlayer.cpp +++ b/media/libmedia/JetPlayer.cpp @@ -96,10 +96,10 @@ int JetPlayer::init() // create the output AudioTrack mAudioTrack = new AudioTrack(); - mAudioTrack->set(AudioSystem::MUSIC, //TODO parametrize this + mAudioTrack->set(AUDIO_STREAM_MUSIC, //TODO parametrize this pLibConfig->sampleRate, 1, // format = PCM 16bits per sample, - (pLibConfig->numChannels == 2) ? AudioSystem::CHANNEL_OUT_STEREO : AudioSystem::CHANNEL_OUT_MONO, + (pLibConfig->numChannels == 2) ? AUDIO_CHANNEL_OUT_STEREO : AUDIO_CHANNEL_OUT_MONO, mTrackBufferSize, 0); diff --git a/media/libmedia/MediaProfiles.cpp b/media/libmedia/MediaProfiles.cpp index e6f3a33..069bbb7 100644 --- a/media/libmedia/MediaProfiles.cpp +++ b/media/libmedia/MediaProfiles.cpp @@ -356,6 +356,18 @@ MediaProfiles::getCameraId(const char** atts) return atoi(atts[1]); } +void MediaProfiles::addStartTimeOffset(int cameraId, const char** atts) +{ + int offsetTimeMs = 700; + if (atts[2]) { + CHECK(!strcmp("startOffsetMs", atts[2])); + offsetTimeMs = atoi(atts[3]); + } + + LOGV("%s: cameraId=%d, offset=%d ms", __func__, cameraId, offsetTimeMs); + mStartTimeOffsets.replaceValueFor(cameraId, offsetTimeMs); +} + /*static*/ void MediaProfiles::startElementHandler(void *userData, const char *name, const char **atts) { @@ -380,6 +392,7 @@ MediaProfiles::startElementHandler(void *userData, const char *name, const char profiles->mEncoderOutputFileFormats.add(createEncoderOutputFileFormat(atts)); } else if (strcmp("CamcorderProfiles", name) == 0) { profiles->mCurrentCameraId = getCameraId(atts); + profiles->addStartTimeOffset(profiles->mCurrentCameraId, atts); } else if (strcmp("EncoderProfile", name) == 0) { profiles->mCamcorderProfiles.add( createCamcorderProfile(profiles->mCurrentCameraId, atts, profiles->mCameraIds)); @@ -997,6 +1010,16 @@ Vector<int> MediaProfiles::getImageEncodingQualityLevels(int cameraId) const return result; } +int MediaProfiles::getStartTimeOffsetMs(int cameraId) const { + int offsetTimeMs = -1; + ssize_t index = mStartTimeOffsets.indexOfKey(cameraId); + if (index >= 0) { + offsetTimeMs = mStartTimeOffsets.valueFor(cameraId); + } + LOGV("%s: offsetTime=%d ms and cameraId=%d", offsetTimeMs, cameraId); + return offsetTimeMs; +} + MediaProfiles::~MediaProfiles() { CHECK("destructor should never be called" == 0); diff --git a/media/libmedia/MemoryLeakTrackUtil.cpp b/media/libmedia/MemoryLeakTrackUtil.cpp new file mode 100644 index 0000000..6a108ae --- /dev/null +++ b/media/libmedia/MemoryLeakTrackUtil.cpp @@ -0,0 +1,169 @@ +/* + * Copyright 2011, 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 <media/MemoryLeakTrackUtil.h> + +#include <stdio.h> +#include <sys/types.h> +#include <unistd.h> + +/* + * The code here originally resided in MediaPlayerService.cpp and was + * shamelessly copied over to support memory leak tracking from + * multiple places. + */ +namespace android { + +#if defined(__arm__) + +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 dumpMemoryAddresses(int fd) +{ + const size_t SIZE = 256; + char buffer[SIZE]; + MyString8 result; + + typedef struct { + size_t size; + size_t dups; + intptr_t * backtrace; + } AllocEntry; + + uint8_t *info = NULL; + size_t overallSize = 0; + size_t infoSize = 0; + size_t totalMemory = 0; + size_t backtraceSize = 0; + + get_malloc_leak_info(&info, &overallSize, &infoSize, &totalMemory, &backtraceSize); + if (info) { + uint8_t *ptr = info; + size_t count = overallSize / infoSize; + + snprintf(buffer, SIZE, " Allocation count %i\n", count); + result.append(buffer); + snprintf(buffer, SIZE, " Total memory %i\n", totalMemory); + result.append(buffer); + + AllocEntry * entries = new AllocEntry[count]; + + for (size_t i = 0; i < count; i++) { + // Each entry should be size_t, size_t, intptr_t[backtraceSize] + AllocEntry *e = &entries[i]; + + e->size = *reinterpret_cast<size_t *>(ptr); + ptr += sizeof(size_t); + + e->dups = *reinterpret_cast<size_t *>(ptr); + ptr += sizeof(size_t); + + e->backtrace = reinterpret_cast<intptr_t *>(ptr); + ptr += sizeof(intptr_t) * backtraceSize; + } + + // Now we need to sort the entries. They come sorted by size but + // not by stack trace which causes problems using diff. + bool moved; + do { + moved = false; + for (size_t i = 0; i < (count - 1); i++) { + AllocEntry *e1 = &entries[i]; + AllocEntry *e2 = &entries[i+1]; + + bool swap = e1->size < e2->size; + if (e1->size == e2->size) { + for(size_t j = 0; j < backtraceSize; j++) { + if (e1->backtrace[j] == e2->backtrace[j]) { + continue; + } + swap = e1->backtrace[j] < e2->backtrace[j]; + break; + } + } + if (swap) { + AllocEntry t = entries[i]; + entries[i] = entries[i+1]; + entries[i+1] = t; + moved = true; + } + } + } while (moved); + + for (size_t i = 0; i < count; i++) { + AllocEntry *e = &entries[i]; + + snprintf(buffer, SIZE, "size %8i, dup %4i, ", e->size, e->dups); + result.append(buffer); + for (size_t ct = 0; (ct < backtraceSize) && e->backtrace[ct]; ct++) { + if (ct) { + result.append(", "); + } + snprintf(buffer, SIZE, "0x%08x", e->backtrace[ct]); + result.append(buffer); + } + result.append("\n"); + } + + delete[] entries; + free_malloc_leak_info(info); + } + + write(fd, result.string(), result.size()); +} + +#else +// Does nothing +void dumpMemoryAddresses(int fd) {} + +#endif +} // namespace android diff --git a/media/libmedia/ToneGenerator.cpp b/media/libmedia/ToneGenerator.cpp index 82fe2d4..9f1b3d6 100644 --- a/media/libmedia/ToneGenerator.cpp +++ b/media/libmedia/ToneGenerator.cpp @@ -1026,8 +1026,8 @@ bool ToneGenerator::initAudioTrack() { mpAudioTrack->set(mStreamType, 0, - AudioSystem::PCM_16_BIT, - AudioSystem::CHANNEL_OUT_MONO, + AUDIO_FORMAT_PCM_16_BIT, + AUDIO_CHANNEL_OUT_MONO, 0, 0, audioCallback, diff --git a/media/libmedia/Visualizer.cpp b/media/libmedia/Visualizer.cpp index 43571cf..366707c 100644 --- a/media/libmedia/Visualizer.cpp +++ b/media/libmedia/Visualizer.cpp @@ -24,6 +24,8 @@ #include <sys/types.h> #include <limits.h> +#include <cutils/bitops.h> + #include <media/Visualizer.h> extern void fixed_fft_real(int n, int32_t *v); @@ -127,7 +129,7 @@ status_t Visualizer::setCaptureSize(uint32_t size) { if (size > VISUALIZER_CAPTURE_SIZE_MAX || size < VISUALIZER_CAPTURE_SIZE_MIN || - AudioSystem::popCount(size) != 1) { + popcount(size) != 1) { return BAD_VALUE; } diff --git a/media/libmedia/mediametadataretriever.cpp b/media/libmedia/mediametadataretriever.cpp index 8dfcb3b..cee06ab 100644 --- a/media/libmedia/mediametadataretriever.cpp +++ b/media/libmedia/mediametadataretriever.cpp @@ -92,7 +92,8 @@ void MediaMetadataRetriever::disconnect() } } -status_t MediaMetadataRetriever::setDataSource(const char* srcUrl) +status_t MediaMetadataRetriever::setDataSource( + const char *srcUrl, const KeyedVector<String8, String8> *headers) { LOGV("setDataSource"); Mutex::Autolock _l(mLock); @@ -105,7 +106,7 @@ status_t MediaMetadataRetriever::setDataSource(const char* srcUrl) return UNKNOWN_ERROR; } LOGV("data source (%s)", srcUrl); - return mRetriever->setDataSource(srcUrl); + return mRetriever->setDataSource(srcUrl, headers); } status_t MediaMetadataRetriever::setDataSource(int fd, int64_t offset, int64_t length) diff --git a/media/libmedia/mediaplayer.cpp b/media/libmedia/mediaplayer.cpp index 0ee0249..7b7ba74 100644 --- a/media/libmedia/mediaplayer.cpp +++ b/media/libmedia/mediaplayer.cpp @@ -37,6 +37,8 @@ #include <utils/KeyedVector.h> #include <utils/String8.h> +#include <system/audio.h> + namespace android { MediaPlayer::MediaPlayer() @@ -45,7 +47,7 @@ MediaPlayer::MediaPlayer() mListener = NULL; mCookie = NULL; mDuration = -1; - mStreamType = AudioSystem::MUSIC; + mStreamType = AUDIO_STREAM_MUSIC; mCurrentPosition = -1; mSeekPosition = -1; mCurrentState = MEDIA_PLAYER_IDLE; @@ -551,7 +553,29 @@ status_t MediaPlayer::attachAuxEffect(int effectId) return mPlayer->attachAuxEffect(effectId); } -void MediaPlayer::notify(int msg, int ext1, int ext2) +status_t MediaPlayer::setParameter(int key, const Parcel& request) +{ + LOGV("MediaPlayer::setParameter(%d)", key); + Mutex::Autolock _l(mLock); + if (mPlayer != NULL) { + return mPlayer->setParameter(key, request); + } + LOGV("setParameter: no active player"); + return INVALID_OPERATION; +} + +status_t MediaPlayer::getParameter(int key, Parcel *reply) +{ + LOGV("MediaPlayer::getParameter(%d)", key); + Mutex::Autolock _l(mLock); + if (mPlayer != NULL) { + return mPlayer->getParameter(key, reply); + } + LOGV("getParameter: no active player"); + return INVALID_OPERATION; +} + +void MediaPlayer::notify(int msg, int ext1, int ext2, const Parcel *obj) { LOGV("message received msg=%d, ext1=%d, ext2=%d", msg, ext1, ext2); bool send = true; @@ -641,6 +665,9 @@ void MediaPlayer::notify(int msg, int ext1, int ext2) mVideoWidth = ext1; mVideoHeight = ext2; break; + case MEDIA_TIMED_TEXT: + LOGV("Received timed text message"); + break; default: LOGV("unrecognized message: (%d, %d, %d)", msg, ext1, ext2); break; @@ -653,7 +680,7 @@ void MediaPlayer::notify(int msg, int ext1, int ext2) if ((listener != 0) && send) { Mutex::Autolock _l(mNotifyLock); LOGV("callback application"); - listener->notify(msg, ext1, ext2); + listener->notify(msg, ext1, ext2, obj); LOGV("back from callback"); } } |
