diff options
Diffstat (limited to 'media/libmedia')
42 files changed, 0 insertions, 17794 deletions
diff --git a/media/libmedia/Android.mk b/media/libmedia/Android.mk deleted file mode 100644 index c8e1dc7..0000000 --- a/media/libmedia/Android.mk +++ /dev/null @@ -1,68 +0,0 @@ -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:= \ - AudioTrack.cpp \ - IAudioFlinger.cpp \ - IAudioFlingerClient.cpp \ - IAudioTrack.cpp \ - IAudioRecord.cpp \ - ICrypto.cpp \ - AudioRecord.cpp \ - AudioSystem.cpp \ - mediaplayer.cpp \ - IMediaPlayerService.cpp \ - IMediaPlayerClient.cpp \ - IMediaRecorderClient.cpp \ - IMediaPlayer.cpp \ - IMediaRecorder.cpp \ - IStreamSource.cpp \ - Metadata.cpp \ - mediarecorder.cpp \ - IMediaMetadataRetriever.cpp \ - mediametadataretriever.cpp \ - ToneGenerator.cpp \ - JetPlayer.cpp \ - IOMX.cpp \ - IAudioPolicyService.cpp \ - MediaScanner.cpp \ - MediaScannerClient.cpp \ - autodetect.cpp \ - IMediaDeathNotifier.cpp \ - MediaProfiles.cpp \ - IEffect.cpp \ - IEffectClient.cpp \ - AudioEffect.cpp \ - Visualizer.cpp \ - MemoryLeakTrackUtil.cpp \ - SoundPool.cpp \ - SoundPoolThread.cpp - -LOCAL_SHARED_LIBRARIES := \ - libui libcutils libutils libbinder libsonivox libicuuc libexpat \ - libcamera_client libstagefright_foundation \ - libgui libdl libaudioutils libmedia_native - -LOCAL_WHOLE_STATIC_LIBRARY := libmedia_helper - -LOCAL_MODULE:= libmedia - -LOCAL_C_INCLUDES := \ - $(call include-path-for, graphics corecg) \ - $(TOP)/frameworks/native/include/media/openmax \ - external/icu4c/common \ - external/expat/lib \ - $(call include-path-for, audio-effects) \ - $(call include-path-for, audio-utils) - -include $(BUILD_SHARED_LIBRARY) diff --git a/media/libmedia/AudioEffect.cpp b/media/libmedia/AudioEffect.cpp deleted file mode 100644 index 34451ca..0000000 --- a/media/libmedia/AudioEffect.cpp +++ /dev/null @@ -1,482 +0,0 @@ -/* -** -** Copyright 2010, 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_NDEBUG 0 -#define LOG_TAG "AudioEffect" - -#include <stdint.h> -#include <sys/types.h> -#include <limits.h> - -#include <private/media/AudioEffectShared.h> -#include <media/AudioEffect.h> - -#include <utils/Log.h> -#include <binder/IPCThreadState.h> - - - -namespace android { - -// --------------------------------------------------------------------------- - -AudioEffect::AudioEffect() - : mStatus(NO_INIT) -{ -} - - -AudioEffect::AudioEffect(const effect_uuid_t *type, - const effect_uuid_t *uuid, - int32_t priority, - effect_callback_t cbf, - void* user, - int sessionId, - audio_io_handle_t io - ) - : mStatus(NO_INIT) -{ - mStatus = set(type, uuid, priority, cbf, user, sessionId, io); -} - -AudioEffect::AudioEffect(const char *typeStr, - const char *uuidStr, - int32_t priority, - effect_callback_t cbf, - void* user, - int sessionId, - audio_io_handle_t io - ) - : mStatus(NO_INIT) -{ - effect_uuid_t type; - effect_uuid_t *pType = NULL; - effect_uuid_t uuid; - effect_uuid_t *pUuid = NULL; - - ALOGV("Constructor string\n - type: %s\n - uuid: %s", typeStr, uuidStr); - - if (typeStr != NULL) { - if (stringToGuid(typeStr, &type) == NO_ERROR) { - pType = &type; - } - } - - if (uuidStr != NULL) { - if (stringToGuid(uuidStr, &uuid) == NO_ERROR) { - pUuid = &uuid; - } - } - - mStatus = set(pType, pUuid, priority, cbf, user, sessionId, io); -} - -status_t AudioEffect::set(const effect_uuid_t *type, - const effect_uuid_t *uuid, - int32_t priority, - effect_callback_t cbf, - void* user, - int sessionId, - audio_io_handle_t io) -{ - sp<IEffect> iEffect; - sp<IMemory> cblk; - int enabled; - - ALOGV("set %p mUserData: %p uuid: %p timeLow %08x", this, user, type, type ? type->timeLow : 0); - - if (mIEffect != 0) { - ALOGW("Effect already in use"); - return INVALID_OPERATION; - } - - const sp<IAudioFlinger>& audioFlinger = AudioSystem::get_audio_flinger(); - if (audioFlinger == 0) { - ALOGE("set(): Could not get audioflinger"); - return NO_INIT; - } - - if (type == NULL && uuid == NULL) { - ALOGW("Must specify at least type or uuid"); - return BAD_VALUE; - } - - mPriority = priority; - mCbf = cbf; - mUserData = user; - mSessionId = sessionId; - - memset(&mDescriptor, 0, sizeof(effect_descriptor_t)); - memcpy(&mDescriptor.type, EFFECT_UUID_NULL, sizeof(effect_uuid_t)); - memcpy(&mDescriptor.uuid, EFFECT_UUID_NULL, sizeof(effect_uuid_t)); - - if (type != NULL) { - memcpy(&mDescriptor.type, type, sizeof(effect_uuid_t)); - } - if (uuid != NULL) { - memcpy(&mDescriptor.uuid, uuid, sizeof(effect_uuid_t)); - } - - mIEffectClient = new EffectClient(this); - - iEffect = audioFlinger->createEffect(getpid(), (effect_descriptor_t *)&mDescriptor, - mIEffectClient, priority, io, mSessionId, &mStatus, &mId, &enabled); - - if (iEffect == 0 || (mStatus != NO_ERROR && mStatus != ALREADY_EXISTS)) { - ALOGE("set(): AudioFlinger could not create effect, status: %d", mStatus); - return mStatus; - } - - mEnabled = (volatile int32_t)enabled; - - mIEffect = iEffect; - cblk = iEffect->getCblk(); - if (cblk == 0) { - mStatus = NO_INIT; - ALOGE("Could not get control block"); - return mStatus; - } - - mIEffect = iEffect; - mCblkMemory = cblk; - mCblk = static_cast<effect_param_cblk_t*>(cblk->pointer()); - int bufOffset = ((sizeof(effect_param_cblk_t) - 1) / sizeof(int) + 1) * sizeof(int); - mCblk->buffer = (uint8_t *)mCblk + bufOffset; - - iEffect->asBinder()->linkToDeath(mIEffectClient); - ALOGV("set() %p OK effect: %s id: %d status %d enabled %d", this, mDescriptor.name, mId, mStatus, mEnabled); - - return mStatus; -} - - -AudioEffect::~AudioEffect() -{ - ALOGV("Destructor %p", this); - - if (mStatus == NO_ERROR || mStatus == ALREADY_EXISTS) { - if (mIEffect != NULL) { - mIEffect->disconnect(); - mIEffect->asBinder()->unlinkToDeath(mIEffectClient); - } - IPCThreadState::self()->flushCommands(); - } - mIEffect.clear(); - mIEffectClient.clear(); - mCblkMemory.clear(); -} - - -status_t AudioEffect::initCheck() const -{ - return mStatus; -} - -// ------------------------------------------------------------------------- - -effect_descriptor_t AudioEffect::descriptor() const -{ - return mDescriptor; -} - -bool AudioEffect::getEnabled() const -{ - return (mEnabled != 0); -} - -status_t AudioEffect::setEnabled(bool enabled) -{ - if (mStatus != NO_ERROR) { - return (mStatus == ALREADY_EXISTS) ? (status_t) INVALID_OPERATION : mStatus; - } - - status_t status = NO_ERROR; - - AutoMutex lock(mLock); - if (enabled != mEnabled) { - if (enabled) { - ALOGV("enable %p", this); - status = mIEffect->enable(); - } else { - ALOGV("disable %p", this); - status = mIEffect->disable(); - } - if (status == NO_ERROR) { - mEnabled = enabled; - } - } - return status; -} - -status_t AudioEffect::command(uint32_t cmdCode, - uint32_t cmdSize, - void *cmdData, - uint32_t *replySize, - void *replyData) -{ - if (mStatus != NO_ERROR && mStatus != ALREADY_EXISTS) { - ALOGV("command() bad status %d", mStatus); - return mStatus; - } - - if (cmdCode == EFFECT_CMD_ENABLE || cmdCode == EFFECT_CMD_DISABLE) { - if (mEnabled == (cmdCode == EFFECT_CMD_ENABLE)) { - return NO_ERROR; - } - if (replySize == NULL || *replySize != sizeof(status_t) || replyData == NULL) { - return BAD_VALUE; - } - mLock.lock(); - } - - status_t status = mIEffect->command(cmdCode, cmdSize, cmdData, replySize, replyData); - - if (cmdCode == EFFECT_CMD_ENABLE || cmdCode == EFFECT_CMD_DISABLE) { - if (status == NO_ERROR) { - status = *(status_t *)replyData; - } - if (status == NO_ERROR) { - mEnabled = (cmdCode == EFFECT_CMD_ENABLE); - } - mLock.unlock(); - } - - return status; -} - - -status_t AudioEffect::setParameter(effect_param_t *param) -{ - if (mStatus != NO_ERROR) { - return (mStatus == ALREADY_EXISTS) ? (status_t) INVALID_OPERATION : mStatus; - } - - if (param == NULL || param->psize == 0 || param->vsize == 0) { - return BAD_VALUE; - } - - uint32_t size = sizeof(int); - uint32_t psize = ((param->psize - 1) / sizeof(int) + 1) * sizeof(int) + param->vsize; - - ALOGV("setParameter: param: %d, param2: %d", *(int *)param->data, (param->psize == 8) ? *((int *)param->data + 1): -1); - - return mIEffect->command(EFFECT_CMD_SET_PARAM, sizeof (effect_param_t) + psize, param, &size, ¶m->status); -} - -status_t AudioEffect::setParameterDeferred(effect_param_t *param) -{ - if (mStatus != NO_ERROR) { - return (mStatus == ALREADY_EXISTS) ? (status_t) INVALID_OPERATION : mStatus; - } - - if (param == NULL || param->psize == 0 || param->vsize == 0) { - return BAD_VALUE; - } - - Mutex::Autolock _l(mCblk->lock); - - int psize = ((param->psize - 1) / sizeof(int) + 1) * sizeof(int) + param->vsize; - int size = ((sizeof(effect_param_t) + psize - 1) / sizeof(int) + 1) * sizeof(int); - - if (mCblk->clientIndex + size > EFFECT_PARAM_BUFFER_SIZE) { - return NO_MEMORY; - } - int *p = (int *)(mCblk->buffer + mCblk->clientIndex); - *p++ = size; - memcpy(p, param, sizeof(effect_param_t) + psize); - mCblk->clientIndex += size; - - return NO_ERROR; -} - -status_t AudioEffect::setParameterCommit() -{ - if (mStatus != NO_ERROR) { - return (mStatus == ALREADY_EXISTS) ? (status_t) INVALID_OPERATION : mStatus; - } - - Mutex::Autolock _l(mCblk->lock); - if (mCblk->clientIndex == 0) { - return INVALID_OPERATION; - } - uint32_t size = 0; - return mIEffect->command(EFFECT_CMD_SET_PARAM_COMMIT, 0, NULL, &size, NULL); -} - -status_t AudioEffect::getParameter(effect_param_t *param) -{ - if (mStatus != NO_ERROR && mStatus != ALREADY_EXISTS) { - return mStatus; - } - - if (param == NULL || param->psize == 0 || param->vsize == 0) { - return BAD_VALUE; - } - - ALOGV("getParameter: param: %d, param2: %d", *(int *)param->data, (param->psize == 8) ? *((int *)param->data + 1): -1); - - uint32_t psize = sizeof(effect_param_t) + ((param->psize - 1) / sizeof(int) + 1) * sizeof(int) + param->vsize; - - return mIEffect->command(EFFECT_CMD_GET_PARAM, sizeof(effect_param_t) + param->psize, param, &psize, param); -} - - -// ------------------------------------------------------------------------- - -void AudioEffect::binderDied() -{ - ALOGW("IEffect died"); - mStatus = DEAD_OBJECT; - if (mCbf != NULL) { - status_t status = DEAD_OBJECT; - mCbf(EVENT_ERROR, mUserData, &status); - } - mIEffect.clear(); -} - -// ------------------------------------------------------------------------- - -void AudioEffect::controlStatusChanged(bool controlGranted) -{ - ALOGV("controlStatusChanged %p control %d callback %p mUserData %p", this, controlGranted, mCbf, mUserData); - if (controlGranted) { - if (mStatus == ALREADY_EXISTS) { - mStatus = NO_ERROR; - } - } else { - if (mStatus == NO_ERROR) { - mStatus = ALREADY_EXISTS; - } - } - if (mCbf != NULL) { - mCbf(EVENT_CONTROL_STATUS_CHANGED, mUserData, &controlGranted); - } -} - -void AudioEffect::enableStatusChanged(bool enabled) -{ - ALOGV("enableStatusChanged %p enabled %d mCbf %p", this, enabled, mCbf); - if (mStatus == ALREADY_EXISTS) { - mEnabled = enabled; - if (mCbf != NULL) { - mCbf(EVENT_ENABLE_STATUS_CHANGED, mUserData, &enabled); - } - } -} - -void AudioEffect::commandExecuted(uint32_t cmdCode, - uint32_t cmdSize, - void *cmdData, - uint32_t replySize, - void *replyData) -{ - if (cmdData == NULL || replyData == NULL) { - return; - } - - if (mCbf != NULL && cmdCode == EFFECT_CMD_SET_PARAM) { - effect_param_t *cmd = (effect_param_t *)cmdData; - cmd->status = *(int32_t *)replyData; - mCbf(EVENT_PARAMETER_CHANGED, mUserData, cmd); - } -} - -// ------------------------------------------------------------------------- - -status_t AudioEffect::queryNumberEffects(uint32_t *numEffects) -{ - const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger(); - if (af == 0) return PERMISSION_DENIED; - return af->queryNumberEffects(numEffects); -} - -status_t AudioEffect::queryEffect(uint32_t index, effect_descriptor_t *descriptor) -{ - const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger(); - if (af == 0) return PERMISSION_DENIED; - return af->queryEffect(index, descriptor); -} - -status_t AudioEffect::getEffectDescriptor(const effect_uuid_t *uuid, - effect_descriptor_t *descriptor) /*const*/ -{ - const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger(); - if (af == 0) return PERMISSION_DENIED; - return af->getEffectDescriptor(uuid, descriptor); -} - - -status_t AudioEffect::queryDefaultPreProcessing(int audioSession, - effect_descriptor_t *descriptors, - uint32_t *count) -{ - const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service(); - if (aps == 0) return PERMISSION_DENIED; - return aps->queryDefaultPreProcessing(audioSession, descriptors, count); -} -// ------------------------------------------------------------------------- - -status_t AudioEffect::stringToGuid(const char *str, effect_uuid_t *guid) -{ - if (str == NULL || guid == NULL) { - return BAD_VALUE; - } - - int tmp[10]; - - if (sscanf(str, "%08x-%04x-%04x-%04x-%02x%02x%02x%02x%02x%02x", - tmp, tmp+1, tmp+2, tmp+3, tmp+4, tmp+5, tmp+6, tmp+7, tmp+8, tmp+9) < 10) { - return BAD_VALUE; - } - guid->timeLow = (uint32_t)tmp[0]; - guid->timeMid = (uint16_t)tmp[1]; - guid->timeHiAndVersion = (uint16_t)tmp[2]; - guid->clockSeq = (uint16_t)tmp[3]; - guid->node[0] = (uint8_t)tmp[4]; - guid->node[1] = (uint8_t)tmp[5]; - guid->node[2] = (uint8_t)tmp[6]; - guid->node[3] = (uint8_t)tmp[7]; - guid->node[4] = (uint8_t)tmp[8]; - guid->node[5] = (uint8_t)tmp[9]; - - return NO_ERROR; -} - -status_t AudioEffect::guidToString(const effect_uuid_t *guid, char *str, size_t maxLen) -{ - if (guid == NULL || str == NULL) { - return BAD_VALUE; - } - - snprintf(str, maxLen, "%08x-%04x-%04x-%04x-%02x%02x%02x%02x%02x%02x", - guid->timeLow, - guid->timeMid, - guid->timeHiAndVersion, - guid->clockSeq, - guid->node[0], - guid->node[1], - guid->node[2], - guid->node[3], - guid->node[4], - guid->node[5]); - - return NO_ERROR; -} - - -}; // namespace android diff --git a/media/libmedia/AudioParameter.cpp b/media/libmedia/AudioParameter.cpp deleted file mode 100644 index abc7b3f..0000000 --- a/media/libmedia/AudioParameter.cpp +++ /dev/null @@ -1,179 +0,0 @@ -/* - * 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 { - ALOGV("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 deleted file mode 100644 index 70ec593..0000000 --- a/media/libmedia/AudioRecord.cpp +++ /dev/null @@ -1,844 +0,0 @@ -/* -** -** Copyright 2008, 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_NDEBUG 0 -#define LOG_TAG "AudioRecord" - -#include <stdint.h> -#include <sys/types.h> - -#include <sched.h> -#include <sys/resource.h> - -#include <private/media/AudioTrackShared.h> - -#include <media/AudioSystem.h> -#include <media/AudioRecord.h> -#include <media/mediarecorder.h> - -#include <binder/IServiceManager.h> -#include <utils/Log.h> -#include <binder/Parcel.h> -#include <binder/IPCThreadState.h> -#include <utils/Timers.h> -#include <utils/Atomic.h> - -#include <system/audio.h> -#include <cutils/bitops.h> -#include <cutils/compiler.h> - -namespace android { -// --------------------------------------------------------------------------- - -// static -status_t AudioRecord::getMinFrameCount( - int* frameCount, - uint32_t sampleRate, - audio_format_t format, - int channelCount) -{ - size_t size = 0; - if (AudioSystem::getInputBufferSize(sampleRate, format, channelCount, &size) - != NO_ERROR) { - ALOGE("AudioSystem could not query the input buffer size."); - return NO_INIT; - } - - if (size == 0) { - ALOGE("Unsupported configuration: sampleRate %d, format %d, channelCount %d", - sampleRate, format, channelCount); - return BAD_VALUE; - } - - // We double the size of input buffer for ping pong use of record buffer. - size <<= 1; - - if (audio_is_linear_pcm(format)) { - size /= channelCount * audio_bytes_per_sample(format); - } - - *frameCount = size; - return NO_ERROR; -} - -// --------------------------------------------------------------------------- - -AudioRecord::AudioRecord() - : mStatus(NO_INIT), mSessionId(0), - mPreviousPriority(ANDROID_PRIORITY_NORMAL), mPreviousSchedulingGroup(ANDROID_TGROUP_DEFAULT) -{ -} - -AudioRecord::AudioRecord( - audio_source_t inputSource, - uint32_t sampleRate, - audio_format_t format, - uint32_t channelMask, - int frameCount, - record_flags flags, - callback_t cbf, - void* user, - int notificationFrames, - int sessionId) - : mStatus(NO_INIT), mSessionId(0), - mPreviousPriority(ANDROID_PRIORITY_NORMAL), mPreviousSchedulingGroup(ANDROID_TGROUP_DEFAULT) -{ - mStatus = set(inputSource, sampleRate, format, channelMask, - frameCount, flags, cbf, user, notificationFrames, sessionId); -} - -AudioRecord::~AudioRecord() -{ - if (mStatus == NO_ERROR) { - // Make sure that callback function exits in the case where - // it is looping on buffer empty condition in obtainBuffer(). - // Otherwise the callback thread will never exit. - stop(); - if (mClientRecordThread != 0) { - mClientRecordThread->requestExitAndWait(); - mClientRecordThread.clear(); - } - mAudioRecord.clear(); - IPCThreadState::self()->flushCommands(); - AudioSystem::releaseAudioSessionId(mSessionId); - } -} - -status_t AudioRecord::set( - audio_source_t inputSource, - uint32_t sampleRate, - audio_format_t format, - uint32_t channelMask, - int frameCount, - record_flags flags, - callback_t cbf, - void* user, - int notificationFrames, - bool threadCanCallJava, - int sessionId) -{ - - ALOGV("set(): sampleRate %d, channelMask %d, frameCount %d",sampleRate, channelMask, frameCount); - - AutoMutex lock(mLock); - - if (mAudioRecord != 0) { - return INVALID_OPERATION; - } - - if (inputSource == AUDIO_SOURCE_DEFAULT) { - inputSource = AUDIO_SOURCE_MIC; - } - - if (sampleRate == 0) { - sampleRate = DEFAULT_SAMPLE_RATE; - } - // these below should probably come from the audioFlinger too... - if (format == AUDIO_FORMAT_DEFAULT) { - format = AUDIO_FORMAT_PCM_16_BIT; - } - // validate parameters - if (!audio_is_valid_format(format)) { - ALOGE("Invalid format"); - return BAD_VALUE; - } - - if (!audio_is_input_channel(channelMask)) { - return BAD_VALUE; - } - - int channelCount = popcount(channelMask); - - if (sessionId == 0 ) { - mSessionId = AudioSystem::newAudioSessionId(); - } else { - mSessionId = sessionId; - } - ALOGV("set(): mSessionId %d", mSessionId); - - audio_io_handle_t input = AudioSystem::getInput(inputSource, - sampleRate, - format, - channelMask, - (audio_in_acoustics_t)flags, - mSessionId); - if (input == 0) { - ALOGE("Could not get audio input for record source %d", inputSource); - return BAD_VALUE; - } - - // validate framecount - int minFrameCount = 0; - status_t status = getMinFrameCount(&minFrameCount, sampleRate, format, channelCount); - if (status != NO_ERROR) { - return status; - } - ALOGV("AudioRecord::set() minFrameCount = %d", minFrameCount); - - if (frameCount == 0) { - frameCount = minFrameCount; - } else if (frameCount < minFrameCount) { - return BAD_VALUE; - } - - if (notificationFrames == 0) { - notificationFrames = frameCount/2; - } - - // create the IAudioRecord - status = openRecord_l(sampleRate, format, channelMask, - frameCount, input); - if (status != NO_ERROR) { - return status; - } - - if (cbf != NULL) { - mClientRecordThread = new ClientRecordThread(*this, threadCanCallJava); - } - - mStatus = NO_ERROR; - - mFormat = format; - // Update buffer size in case it has been limited by AudioFlinger during track creation - mFrameCount = mCblk->frameCount; - mChannelCount = (uint8_t)channelCount; - mChannelMask = channelMask; - mActive = 0; - mCbf = cbf; - mNotificationFrames = notificationFrames; - mRemainingFrames = notificationFrames; - mUserData = user; - // TODO: add audio hardware input latency here - mLatency = (1000*mFrameCount) / sampleRate; - mMarkerPosition = 0; - mMarkerReached = false; - mNewPosition = 0; - mUpdatePeriod = 0; - mInputSource = inputSource; - mFlags = flags; - mInput = input; - AudioSystem::acquireAudioSessionId(mSessionId); - - return NO_ERROR; -} - -status_t AudioRecord::initCheck() const -{ - return mStatus; -} - -// ------------------------------------------------------------------------- - -uint32_t AudioRecord::latency() const -{ - return mLatency; -} - -audio_format_t AudioRecord::format() const -{ - return mFormat; -} - -int AudioRecord::channelCount() const -{ - return mChannelCount; -} - -uint32_t AudioRecord::frameCount() const -{ - return mFrameCount; -} - -size_t AudioRecord::frameSize() const -{ - if (audio_is_linear_pcm(mFormat)) { - return channelCount()*audio_bytes_per_sample(mFormat); - } else { - return sizeof(uint8_t); - } -} - -audio_source_t AudioRecord::inputSource() const -{ - return mInputSource; -} - -// ------------------------------------------------------------------------- - -status_t AudioRecord::start() -{ - status_t ret = NO_ERROR; - sp<ClientRecordThread> t = mClientRecordThread; - - ALOGV("start"); - - if (t != 0) { - if (t->exitPending()) { - if (t->requestExitAndWait() == WOULD_BLOCK) { - ALOGE("AudioRecord::start called from thread"); - return WOULD_BLOCK; - } - } - } - - AutoMutex lock(mLock); - // acquire a strong reference on the IAudioRecord and IMemory so that they cannot be destroyed - // while we are accessing the cblk - sp<IAudioRecord> audioRecord = mAudioRecord; - sp<IMemory> iMem = mCblkMemory; - audio_track_cblk_t* cblk = mCblk; - if (mActive == 0) { - mActive = 1; - - pid_t tid; - if (t != 0) { - mReadyToRun = WOULD_BLOCK; - t->run("AudioRecord", ANDROID_PRIORITY_AUDIO); - tid = t->getTid(); // pid_t is unknown until run() - ALOGV("getTid=%d", tid); - if (tid == -1) { - tid = 0; - } - // thread blocks in readyToRun() - } else { - tid = 0; // not gettid() - } - - cblk->lock.lock(); - if (!(cblk->flags & CBLK_INVALID_MSK)) { - cblk->lock.unlock(); - ALOGV("mAudioRecord->start(tid=%d)", tid); - ret = mAudioRecord->start(tid); - cblk->lock.lock(); - if (ret == DEAD_OBJECT) { - android_atomic_or(CBLK_INVALID_ON, &cblk->flags); - } - } - if (cblk->flags & CBLK_INVALID_MSK) { - ret = restoreRecord_l(cblk); - } - cblk->lock.unlock(); - if (ret == NO_ERROR) { - mNewPosition = cblk->user + mUpdatePeriod; - cblk->bufferTimeoutMs = MAX_RUN_TIMEOUT_MS; - cblk->waitTimeMs = 0; - if (t != 0) { - // thread unblocks in readyToRun() and returns NO_ERROR - mReadyToRun = NO_ERROR; - mCondition.signal(); - } else { - mPreviousPriority = getpriority(PRIO_PROCESS, 0); - mPreviousSchedulingGroup = androidGetThreadSchedulingGroup(0); - androidSetThreadPriority(0, ANDROID_PRIORITY_AUDIO); - } - } else { - mActive = 0; - // thread unblocks in readyToRun() and returns NO_INIT - mReadyToRun = NO_INIT; - mCondition.signal(); - } - } - - return ret; -} - -status_t AudioRecord::stop() -{ - sp<ClientRecordThread> t = mClientRecordThread; - - ALOGV("stop"); - - AutoMutex lock(mLock); - if (mActive == 1) { - mActive = 0; - mCblk->cv.signal(); - mAudioRecord->stop(); - // the record head position will reset to 0, so if a marker is set, we need - // to activate it again - mMarkerReached = false; - if (t != 0) { - t->requestExit(); - } else { - setpriority(PRIO_PROCESS, 0, mPreviousPriority); - androidSetThreadSchedulingGroup(0, mPreviousSchedulingGroup); - } - } - - return NO_ERROR; -} - -bool AudioRecord::stopped() const -{ - return !mActive; -} - -uint32_t AudioRecord::getSampleRate() const -{ - AutoMutex lock(mLock); - return mCblk->sampleRate; -} - -status_t AudioRecord::setMarkerPosition(uint32_t marker) -{ - if (mCbf == NULL) return INVALID_OPERATION; - - mMarkerPosition = marker; - mMarkerReached = false; - - return NO_ERROR; -} - -status_t AudioRecord::getMarkerPosition(uint32_t *marker) const -{ - if (marker == NULL) return BAD_VALUE; - - *marker = mMarkerPosition; - - return NO_ERROR; -} - -status_t AudioRecord::setPositionUpdatePeriod(uint32_t updatePeriod) -{ - if (mCbf == NULL) return INVALID_OPERATION; - - uint32_t curPosition; - getPosition(&curPosition); - mNewPosition = curPosition + updatePeriod; - mUpdatePeriod = updatePeriod; - - return NO_ERROR; -} - -status_t AudioRecord::getPositionUpdatePeriod(uint32_t *updatePeriod) const -{ - if (updatePeriod == NULL) return BAD_VALUE; - - *updatePeriod = mUpdatePeriod; - - return NO_ERROR; -} - -status_t AudioRecord::getPosition(uint32_t *position) const -{ - if (position == NULL) return BAD_VALUE; - - AutoMutex lock(mLock); - *position = mCblk->user; - - return NO_ERROR; -} - -unsigned int AudioRecord::getInputFramesLost() const -{ - if (mActive) - return AudioSystem::getInputFramesLost(mInput); - else - return 0; -} - -// ------------------------------------------------------------------------- - -// must be called with mLock held -status_t AudioRecord::openRecord_l( - uint32_t sampleRate, - audio_format_t format, - uint32_t channelMask, - int frameCount, - audio_io_handle_t input) -{ - status_t status; - const sp<IAudioFlinger>& audioFlinger = AudioSystem::get_audio_flinger(); - if (audioFlinger == 0) { - return NO_INIT; - } - - sp<IAudioRecord> record = audioFlinger->openRecord(getpid(), input, - sampleRate, format, - channelMask, - frameCount, - IAudioFlinger::TRACK_DEFAULT, - &mSessionId, - &status); - - if (record == 0) { - ALOGE("AudioFlinger could not create record track, status: %d", status); - return status; - } - sp<IMemory> cblk = record->getCblk(); - if (cblk == 0) { - ALOGE("Could not get control block"); - return NO_INIT; - } - mAudioRecord.clear(); - mAudioRecord = record; - mCblkMemory.clear(); - mCblkMemory = cblk; - mCblk = static_cast<audio_track_cblk_t*>(cblk->pointer()); - mCblk->buffers = (char*)mCblk + sizeof(audio_track_cblk_t); - android_atomic_and(~CBLK_DIRECTION_MSK, &mCblk->flags); - mCblk->bufferTimeoutMs = MAX_RUN_TIMEOUT_MS; - mCblk->waitTimeMs = 0; - return NO_ERROR; -} - -status_t AudioRecord::obtainBuffer(Buffer* audioBuffer, int32_t waitCount) -{ - AutoMutex lock(mLock); - int active; - status_t result = NO_ERROR; - audio_track_cblk_t* cblk = mCblk; - uint32_t framesReq = audioBuffer->frameCount; - uint32_t waitTimeMs = (waitCount < 0) ? cblk->bufferTimeoutMs : WAIT_PERIOD_MS; - - audioBuffer->frameCount = 0; - audioBuffer->size = 0; - - uint32_t framesReady = cblk->framesReady(); - - if (framesReady == 0) { - cblk->lock.lock(); - goto start_loop_here; - while (framesReady == 0) { - active = mActive; - if (CC_UNLIKELY(!active)) { - cblk->lock.unlock(); - return NO_MORE_BUFFERS; - } - if (CC_UNLIKELY(!waitCount)) { - cblk->lock.unlock(); - return WOULD_BLOCK; - } - if (!(cblk->flags & CBLK_INVALID_MSK)) { - mLock.unlock(); - result = cblk->cv.waitRelative(cblk->lock, milliseconds(waitTimeMs)); - cblk->lock.unlock(); - mLock.lock(); - if (mActive == 0) { - return status_t(STOPPED); - } - cblk->lock.lock(); - } - if (cblk->flags & CBLK_INVALID_MSK) { - goto create_new_record; - } - if (CC_UNLIKELY(result != NO_ERROR)) { - cblk->waitTimeMs += waitTimeMs; - if (cblk->waitTimeMs >= cblk->bufferTimeoutMs) { - ALOGW( "obtainBuffer timed out (is the CPU pegged?) " - "user=%08x, server=%08x", cblk->user, cblk->server); - cblk->lock.unlock(); - result = mAudioRecord->start(0); // callback thread hasn't changed - cblk->lock.lock(); - if (result == DEAD_OBJECT) { - android_atomic_or(CBLK_INVALID_ON, &cblk->flags); -create_new_record: - result = AudioRecord::restoreRecord_l(cblk); - } - if (result != NO_ERROR) { - ALOGW("obtainBuffer create Track error %d", result); - cblk->lock.unlock(); - return result; - } - cblk->waitTimeMs = 0; - } - if (--waitCount == 0) { - cblk->lock.unlock(); - return TIMED_OUT; - } - } - // read the server count again - start_loop_here: - framesReady = cblk->framesReady(); - } - cblk->lock.unlock(); - } - - cblk->waitTimeMs = 0; - - if (framesReq > framesReady) { - framesReq = framesReady; - } - - uint32_t u = cblk->user; - uint32_t bufferEnd = cblk->userBase + cblk->frameCount; - - if (u + framesReq > bufferEnd) { - framesReq = bufferEnd - u; - } - - audioBuffer->flags = 0; - audioBuffer->channelCount= mChannelCount; - audioBuffer->format = mFormat; - audioBuffer->frameCount = framesReq; - audioBuffer->size = framesReq*cblk->frameSize; - audioBuffer->raw = (int8_t*)cblk->buffer(u); - active = mActive; - return active ? status_t(NO_ERROR) : status_t(STOPPED); -} - -void AudioRecord::releaseBuffer(Buffer* audioBuffer) -{ - AutoMutex lock(mLock); - mCblk->stepUser(audioBuffer->frameCount); -} - -audio_io_handle_t AudioRecord::getInput() const -{ - AutoMutex lock(mLock); - return mInput; -} - -// must be called with mLock held -audio_io_handle_t AudioRecord::getInput_l() -{ - mInput = AudioSystem::getInput(mInputSource, - mCblk->sampleRate, - mFormat, - mChannelMask, - (audio_in_acoustics_t)mFlags, - mSessionId); - return mInput; -} - -int AudioRecord::getSessionId() const -{ - return mSessionId; -} - -// ------------------------------------------------------------------------- - -ssize_t AudioRecord::read(void* buffer, size_t userSize) -{ - ssize_t read = 0; - Buffer audioBuffer; - int8_t *dst = static_cast<int8_t*>(buffer); - - if (ssize_t(userSize) < 0) { - // sanity-check. user is most-likely passing an error code. - ALOGE("AudioRecord::read(buffer=%p, size=%u (%d)", - buffer, userSize, userSize); - return BAD_VALUE; - } - - mLock.lock(); - // acquire a strong reference on the IAudioRecord and IMemory so that they cannot be destroyed - // while we are accessing the cblk - sp<IAudioRecord> audioRecord = mAudioRecord; - sp<IMemory> iMem = mCblkMemory; - mLock.unlock(); - - do { - - audioBuffer.frameCount = userSize/frameSize(); - - // By using a wait count corresponding to twice the timeout period in - // obtainBuffer() we give a chance to recover once for a read timeout - // (if media_server crashed for instance) before returning a length of - // 0 bytes read to the client - status_t err = obtainBuffer(&audioBuffer, ((2 * MAX_RUN_TIMEOUT_MS) / WAIT_PERIOD_MS)); - if (err < 0) { - // out of buffers, return #bytes written - if (err == status_t(NO_MORE_BUFFERS)) - break; - if (err == status_t(TIMED_OUT)) - err = 0; - return ssize_t(err); - } - - size_t bytesRead = audioBuffer.size; - memcpy(dst, audioBuffer.i8, bytesRead); - - dst += bytesRead; - userSize -= bytesRead; - read += bytesRead; - - releaseBuffer(&audioBuffer); - } while (userSize); - - return read; -} - -// ------------------------------------------------------------------------- - -bool AudioRecord::processAudioBuffer(const sp<ClientRecordThread>& thread) -{ - Buffer audioBuffer; - uint32_t frames = mRemainingFrames; - size_t readSize; - - mLock.lock(); - // acquire a strong reference on the IAudioRecord and IMemory so that they cannot be destroyed - // while we are accessing the cblk - sp<IAudioRecord> audioRecord = mAudioRecord; - sp<IMemory> iMem = mCblkMemory; - audio_track_cblk_t* cblk = mCblk; - mLock.unlock(); - - // Manage marker callback - if (!mMarkerReached && (mMarkerPosition > 0)) { - if (cblk->user >= mMarkerPosition) { - mCbf(EVENT_MARKER, mUserData, (void *)&mMarkerPosition); - mMarkerReached = true; - } - } - - // Manage new position callback - if (mUpdatePeriod > 0) { - while (cblk->user >= mNewPosition) { - mCbf(EVENT_NEW_POS, mUserData, (void *)&mNewPosition); - mNewPosition += mUpdatePeriod; - } - } - - do { - audioBuffer.frameCount = frames; - // Calling obtainBuffer() with a wait count of 1 - // limits wait time to WAIT_PERIOD_MS. This prevents from being - // stuck here not being able to handle timed events (position, markers). - status_t err = obtainBuffer(&audioBuffer, 1); - if (err < NO_ERROR) { - if (err != TIMED_OUT) { - ALOGE_IF(err != status_t(NO_MORE_BUFFERS), "Error obtaining an audio buffer, giving up."); - return false; - } - break; - } - if (err == status_t(STOPPED)) return false; - - size_t reqSize = audioBuffer.size; - mCbf(EVENT_MORE_DATA, mUserData, &audioBuffer); - readSize = audioBuffer.size; - - // Sanity check on returned size - if (ssize_t(readSize) <= 0) { - // The callback is done filling buffers - // Keep this thread going to handle timed events and - // still try to get more data in intervals of WAIT_PERIOD_MS - // but don't just loop and block the CPU, so wait - usleep(WAIT_PERIOD_MS*1000); - break; - } - if (readSize > reqSize) readSize = reqSize; - - audioBuffer.size = readSize; - audioBuffer.frameCount = readSize/frameSize(); - frames -= audioBuffer.frameCount; - - releaseBuffer(&audioBuffer); - - } while (frames); - - - // Manage overrun callback - if (mActive && (cblk->framesAvailable() == 0)) { - ALOGV("Overrun user: %x, server: %x, flags %04x", cblk->user, cblk->server, cblk->flags); - if (!(android_atomic_or(CBLK_UNDERRUN_ON, &cblk->flags) & CBLK_UNDERRUN_MSK)) { - mCbf(EVENT_OVERRUN, mUserData, 0); - } - } - - if (frames == 0) { - mRemainingFrames = mNotificationFrames; - } else { - mRemainingFrames = frames; - } - return true; -} - -// must be called with mLock and cblk.lock held. Callers must also hold strong references on -// the IAudioRecord and IMemory in case they are recreated here. -// If the IAudioRecord is successfully restored, the cblk pointer is updated -status_t AudioRecord::restoreRecord_l(audio_track_cblk_t*& cblk) -{ - status_t result; - - if (!(android_atomic_or(CBLK_RESTORING_ON, &cblk->flags) & CBLK_RESTORING_MSK)) { - ALOGW("dead IAudioRecord, creating a new one"); - // signal old cblk condition so that other threads waiting for available buffers stop - // waiting now - cblk->cv.broadcast(); - cblk->lock.unlock(); - - // if the new IAudioRecord is created, openRecord_l() will modify the - // following member variables: mAudioRecord, mCblkMemory and mCblk. - // It will also delete the strong references on previous IAudioRecord and IMemory - result = openRecord_l(cblk->sampleRate, mFormat, mChannelMask, - mFrameCount, getInput_l()); - if (result == NO_ERROR) { - result = mAudioRecord->start(0); // callback thread hasn't changed - } - if (result != NO_ERROR) { - mActive = false; - } - - // signal old cblk condition for other threads waiting for restore completion - android_atomic_or(CBLK_RESTORED_ON, &cblk->flags); - cblk->cv.broadcast(); - } else { - if (!(cblk->flags & CBLK_RESTORED_MSK)) { - ALOGW("dead IAudioRecord, waiting for a new one to be created"); - mLock.unlock(); - result = cblk->cv.waitRelative(cblk->lock, milliseconds(RESTORE_TIMEOUT_MS)); - cblk->lock.unlock(); - mLock.lock(); - } else { - ALOGW("dead IAudioRecord, already restored"); - result = NO_ERROR; - cblk->lock.unlock(); - } - if (result != NO_ERROR || mActive == 0) { - result = status_t(STOPPED); - } - } - ALOGV("restoreRecord_l() status %d mActive %d cblk %p, old cblk %p flags %08x old flags %08x", - result, mActive, mCblk, cblk, mCblk->flags, cblk->flags); - - if (result == NO_ERROR) { - // from now on we switch to the newly created cblk - cblk = mCblk; - } - cblk->lock.lock(); - - ALOGW_IF(result != NO_ERROR, "restoreRecord_l() error %d", result); - - return result; -} - -// ========================================================================= - -AudioRecord::ClientRecordThread::ClientRecordThread(AudioRecord& receiver, bool bCanCallJava) - : Thread(bCanCallJava), mReceiver(receiver) -{ -} - -bool AudioRecord::ClientRecordThread::threadLoop() -{ - return mReceiver.processAudioBuffer(this); -} - -status_t AudioRecord::ClientRecordThread::readyToRun() -{ - AutoMutex(mReceiver.mLock); - while (mReceiver.mReadyToRun == WOULD_BLOCK) { - mReceiver.mCondition.wait(mReceiver.mLock); - } - return mReceiver.mReadyToRun; -} - -// ------------------------------------------------------------------------- - -}; // namespace android diff --git a/media/libmedia/AudioSystem.cpp b/media/libmedia/AudioSystem.cpp deleted file mode 100644 index 33c7d03..0000000 --- a/media/libmedia/AudioSystem.cpp +++ /dev/null @@ -1,770 +0,0 @@ -/* - * Copyright (C) 2006-2007 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 "AudioSystem" -//#define LOG_NDEBUG 0 - -#include <utils/Log.h> -#include <binder/IServiceManager.h> -#include <media/AudioSystem.h> -#include <media/IAudioPolicyService.h> -#include <math.h> - -#include <system/audio.h> - -// ---------------------------------------------------------------------------- - -namespace android { - -// client singleton for AudioFlinger binder interface -Mutex AudioSystem::gLock; -sp<IAudioFlinger> AudioSystem::gAudioFlinger; -sp<AudioSystem::AudioFlingerClient> AudioSystem::gAudioFlingerClient; -audio_error_callback AudioSystem::gAudioErrorCallback = NULL; -// Cached values - -DefaultKeyedVector<audio_stream_type_t, audio_io_handle_t> AudioSystem::gStreamOutputMap(0); -DefaultKeyedVector<audio_io_handle_t, AudioSystem::OutputDescriptor *> AudioSystem::gOutputs(0); - -// Cached values for recording queries, all protected by gLock -uint32_t AudioSystem::gPrevInSamplingRate = 16000; -audio_format_t AudioSystem::gPrevInFormat = AUDIO_FORMAT_PCM_16_BIT; -int AudioSystem::gPrevInChannelCount = 1; -size_t AudioSystem::gInBuffSize = 0; - - -// establish binder interface to AudioFlinger service -const sp<IAudioFlinger>& AudioSystem::get_audio_flinger() -{ - Mutex::Autolock _l(gLock); - if (gAudioFlinger == 0) { - sp<IServiceManager> sm = defaultServiceManager(); - sp<IBinder> binder; - do { - binder = sm->getService(String16("media.audio_flinger")); - if (binder != 0) - break; - ALOGW("AudioFlinger not published, waiting..."); - usleep(500000); // 0.5 s - } while (true); - if (gAudioFlingerClient == NULL) { - gAudioFlingerClient = new AudioFlingerClient(); - } else { - if (gAudioErrorCallback) { - gAudioErrorCallback(NO_ERROR); - } - } - binder->linkToDeath(gAudioFlingerClient); - gAudioFlinger = interface_cast<IAudioFlinger>(binder); - gAudioFlinger->registerClient(gAudioFlingerClient); - } - ALOGE_IF(gAudioFlinger==0, "no AudioFlinger!?"); - - return gAudioFlinger; -} - -status_t AudioSystem::muteMicrophone(bool state) { - const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger(); - if (af == 0) return PERMISSION_DENIED; - return af->setMicMute(state); -} - -status_t AudioSystem::isMicrophoneMuted(bool* state) { - const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger(); - if (af == 0) return PERMISSION_DENIED; - *state = af->getMicMute(); - return NO_ERROR; -} - -status_t AudioSystem::setMasterVolume(float value) -{ - const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger(); - if (af == 0) return PERMISSION_DENIED; - af->setMasterVolume(value); - return NO_ERROR; -} - -status_t AudioSystem::setMasterMute(bool mute) -{ - const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger(); - if (af == 0) return PERMISSION_DENIED; - af->setMasterMute(mute); - return NO_ERROR; -} - -status_t AudioSystem::getMasterVolume(float* volume) -{ - const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger(); - if (af == 0) return PERMISSION_DENIED; - *volume = af->masterVolume(); - return NO_ERROR; -} - -status_t AudioSystem::getMasterMute(bool* mute) -{ - const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger(); - if (af == 0) return PERMISSION_DENIED; - *mute = af->masterMute(); - return NO_ERROR; -} - -status_t AudioSystem::setStreamVolume(audio_stream_type_t stream, float value, - audio_io_handle_t output) -{ - 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); - return NO_ERROR; -} - -status_t AudioSystem::setStreamMute(audio_stream_type_t stream, bool mute) -{ - 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); - return NO_ERROR; -} - -status_t AudioSystem::getStreamVolume(audio_stream_type_t stream, float* volume, - audio_io_handle_t output) -{ - 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); - return NO_ERROR; -} - -status_t AudioSystem::getStreamMute(audio_stream_type_t stream, bool* mute) -{ - 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); - return NO_ERROR; -} - -status_t AudioSystem::setMode(audio_mode_t mode) -{ - if (uint32_t(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); -} - -status_t AudioSystem::setParameters(audio_io_handle_t ioHandle, const String8& keyValuePairs) { - const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger(); - if (af == 0) return PERMISSION_DENIED; - return af->setParameters(ioHandle, keyValuePairs); -} - -String8 AudioSystem::getParameters(audio_io_handle_t ioHandle, const String8& keys) { - const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger(); - String8 result = String8(""); - if (af == 0) return result; - - result = af->getParameters(ioHandle, keys); - return result; -} - -// convert volume steps to natural log scale - -// change this value to change volume scaling -static const float dBPerStep = 0.5f; -// shouldn't need to touch these -static const float dBConvert = -dBPerStep * 2.302585093f / 20.0f; -static const float dBConvertInverse = 1.0f / dBConvert; - -float AudioSystem::linearToLog(int volume) -{ - // float v = volume ? exp(float(100 - volume) * dBConvert) : 0; - // ALOGD("linearToLog(%d)=%f", volume, v); - // return v; - return volume ? exp(float(100 - volume) * dBConvert) : 0; -} - -int AudioSystem::logToLinear(float volume) -{ - // int v = volume ? 100 - int(dBConvertInverse * log(volume) + 0.5) : 0; - // ALOGD("logTolinear(%d)=%f", v, volume); - // return v; - return volume ? 100 - int(dBConvertInverse * log(volume) + 0.5) : 0; -} - -// DEPRECATED -status_t AudioSystem::getOutputSamplingRate(int* samplingRate, int streamType) { - return getOutputSamplingRate(samplingRate, (audio_stream_type_t)streamType); -} - -status_t AudioSystem::getOutputSamplingRate(int* samplingRate, audio_stream_type_t streamType) -{ - OutputDescriptor *outputDesc; - audio_io_handle_t output; - - if (streamType == AUDIO_STREAM_DEFAULT) { - streamType = AUDIO_STREAM_MUSIC; - } - - output = getOutput(streamType); - if (output == 0) { - return PERMISSION_DENIED; - } - - gLock.lock(); - outputDesc = AudioSystem::gOutputs.valueFor(output); - if (outputDesc == NULL) { - ALOGV("getOutputSamplingRate() no output descriptor for output %d in gOutputs", output); - gLock.unlock(); - const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger(); - if (af == 0) return PERMISSION_DENIED; - *samplingRate = af->sampleRate(output); - } else { - ALOGV("getOutputSamplingRate() reading from output desc"); - *samplingRate = outputDesc->samplingRate; - gLock.unlock(); - } - - ALOGV("getOutputSamplingRate() streamType %d, output %d, sampling rate %d", streamType, output, *samplingRate); - - return NO_ERROR; -} - -// DEPRECATED -status_t AudioSystem::getOutputFrameCount(int* frameCount, int streamType) { - return getOutputFrameCount(frameCount, (audio_stream_type_t)streamType); -} - -status_t AudioSystem::getOutputFrameCount(int* frameCount, audio_stream_type_t streamType) -{ - OutputDescriptor *outputDesc; - audio_io_handle_t output; - - if (streamType == AUDIO_STREAM_DEFAULT) { - streamType = AUDIO_STREAM_MUSIC; - } - - output = getOutput(streamType); - if (output == 0) { - return PERMISSION_DENIED; - } - - gLock.lock(); - outputDesc = AudioSystem::gOutputs.valueFor(output); - if (outputDesc == NULL) { - gLock.unlock(); - const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger(); - if (af == 0) return PERMISSION_DENIED; - *frameCount = af->frameCount(output); - } else { - *frameCount = outputDesc->frameCount; - gLock.unlock(); - } - - ALOGV("getOutputFrameCount() streamType %d, output %d, frameCount %d", streamType, output, *frameCount); - - return NO_ERROR; -} - -status_t AudioSystem::getOutputLatency(uint32_t* latency, audio_stream_type_t streamType) -{ - OutputDescriptor *outputDesc; - audio_io_handle_t output; - - if (streamType == AUDIO_STREAM_DEFAULT) { - streamType = AUDIO_STREAM_MUSIC; - } - - output = getOutput(streamType); - if (output == 0) { - return PERMISSION_DENIED; - } - - gLock.lock(); - outputDesc = AudioSystem::gOutputs.valueFor(output); - if (outputDesc == NULL) { - gLock.unlock(); - const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger(); - if (af == 0) return PERMISSION_DENIED; - *latency = af->latency(output); - } else { - *latency = outputDesc->latency; - gLock.unlock(); - } - - ALOGV("getOutputLatency() streamType %d, output %d, latency %d", streamType, output, *latency); - - return NO_ERROR; -} - -status_t AudioSystem::getInputBufferSize(uint32_t sampleRate, audio_format_t format, int channelCount, - size_t* buffSize) -{ - gLock.lock(); - // Do we have a stale gInBufferSize or are we requesting the input buffer size for new values - size_t inBuffSize = gInBuffSize; - if ((inBuffSize == 0) || (sampleRate != gPrevInSamplingRate) || (format != gPrevInFormat) - || (channelCount != gPrevInChannelCount)) { - gLock.unlock(); - const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger(); - if (af == 0) { - return PERMISSION_DENIED; - } - inBuffSize = af->getInputBufferSize(sampleRate, format, channelCount); - gLock.lock(); - // save the request params - gPrevInSamplingRate = sampleRate; - gPrevInFormat = format; - gPrevInChannelCount = channelCount; - - gInBuffSize = inBuffSize; - } - gLock.unlock(); - *buffSize = inBuffSize; - - 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); -} - -status_t AudioSystem::getRenderPosition(uint32_t *halFrames, uint32_t *dspFrames, audio_stream_type_t stream) -{ - const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger(); - if (af == 0) return PERMISSION_DENIED; - - if (stream == AUDIO_STREAM_DEFAULT) { - stream = AUDIO_STREAM_MUSIC; - } - - return af->getRenderPosition(halFrames, dspFrames, getOutput(stream)); -} - -unsigned int AudioSystem::getInputFramesLost(audio_io_handle_t ioHandle) { - const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger(); - unsigned int result = 0; - if (af == 0) return result; - if (ioHandle == 0) return result; - - result = af->getInputFramesLost(ioHandle); - return result; -} - -int AudioSystem::newAudioSessionId() { - const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger(); - if (af == 0) return 0; - return af->newAudioSessionId(); -} - -void AudioSystem::acquireAudioSessionId(int audioSession) { - const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger(); - if (af != 0) { - af->acquireAudioSessionId(audioSession); - } -} - -void AudioSystem::releaseAudioSessionId(int audioSession) { - const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger(); - if (af != 0) { - af->releaseAudioSessionId(audioSession); - } -} - -// --------------------------------------------------------------------------- - -void AudioSystem::AudioFlingerClient::binderDied(const wp<IBinder>& who) { - Mutex::Autolock _l(AudioSystem::gLock); - - AudioSystem::gAudioFlinger.clear(); - // clear output handles and stream to output map caches - AudioSystem::gStreamOutputMap.clear(); - AudioSystem::gOutputs.clear(); - - if (gAudioErrorCallback) { - gAudioErrorCallback(DEAD_OBJECT); - } - ALOGW("AudioFlinger server died!"); -} - -void AudioSystem::AudioFlingerClient::ioConfigChanged(int event, audio_io_handle_t ioHandle, - const void *param2) { - ALOGV("ioConfigChanged() event %d", event); - const OutputDescriptor *desc; - audio_stream_type_t stream; - - if (ioHandle == 0) return; - - Mutex::Autolock _l(AudioSystem::gLock); - - switch (event) { - case STREAM_CONFIG_CHANGED: - if (param2 == NULL) break; - stream = *(const audio_stream_type_t *)param2; - ALOGV("ioConfigChanged() STREAM_CONFIG_CHANGED stream %d, output %d", stream, ioHandle); - if (gStreamOutputMap.indexOfKey(stream) >= 0) { - gStreamOutputMap.replaceValueFor(stream, ioHandle); - } - break; - case OUTPUT_OPENED: { - if (gOutputs.indexOfKey(ioHandle) >= 0) { - ALOGV("ioConfigChanged() opening already existing output! %d", ioHandle); - break; - } - if (param2 == NULL) break; - desc = (const OutputDescriptor *)param2; - - OutputDescriptor *outputDesc = new OutputDescriptor(*desc); - gOutputs.add(ioHandle, outputDesc); - ALOGV("ioConfigChanged() new output samplingRate %d, format %d channels %d frameCount %d latency %d", - outputDesc->samplingRate, outputDesc->format, outputDesc->channels, outputDesc->frameCount, outputDesc->latency); - } break; - case OUTPUT_CLOSED: { - if (gOutputs.indexOfKey(ioHandle) < 0) { - ALOGW("ioConfigChanged() closing unknow output! %d", ioHandle); - break; - } - ALOGV("ioConfigChanged() output %d closed", ioHandle); - - gOutputs.removeItem(ioHandle); - for (int i = gStreamOutputMap.size() - 1; i >= 0 ; i--) { - if (gStreamOutputMap.valueAt(i) == ioHandle) { - gStreamOutputMap.removeItemsAt(i); - } - } - } break; - - case OUTPUT_CONFIG_CHANGED: { - int index = gOutputs.indexOfKey(ioHandle); - if (index < 0) { - ALOGW("ioConfigChanged() modifying unknow output! %d", ioHandle); - break; - } - if (param2 == NULL) break; - desc = (const OutputDescriptor *)param2; - - ALOGV("ioConfigChanged() new config for output %d samplingRate %d, format %d channels %d frameCount %d latency %d", - ioHandle, desc->samplingRate, desc->format, - desc->channels, desc->frameCount, desc->latency); - OutputDescriptor *outputDesc = gOutputs.valueAt(index); - delete outputDesc; - outputDesc = new OutputDescriptor(*desc); - gOutputs.replaceValueFor(ioHandle, outputDesc); - } break; - case INPUT_OPENED: - case INPUT_CLOSED: - case INPUT_CONFIG_CHANGED: - break; - - } -} - -void AudioSystem::setErrorCallback(audio_error_callback cb) { - Mutex::Autolock _l(gLock); - gAudioErrorCallback = cb; -} - -bool AudioSystem::routedToA2dpOutput(audio_stream_type_t streamType) { - switch (streamType) { - case AUDIO_STREAM_MUSIC: - case AUDIO_STREAM_VOICE_CALL: - case AUDIO_STREAM_BLUETOOTH_SCO: - case AUDIO_STREAM_SYSTEM: - return true; - default: - return false; - } -} - - -// client singleton for AudioPolicyService binder interface -sp<IAudioPolicyService> AudioSystem::gAudioPolicyService; -sp<AudioSystem::AudioPolicyServiceClient> AudioSystem::gAudioPolicyServiceClient; - - -// establish binder interface to AudioFlinger service -const sp<IAudioPolicyService>& AudioSystem::get_audio_policy_service() -{ - gLock.lock(); - if (gAudioPolicyService == 0) { - sp<IServiceManager> sm = defaultServiceManager(); - sp<IBinder> binder; - do { - binder = sm->getService(String16("media.audio_policy")); - if (binder != 0) - break; - ALOGW("AudioPolicyService not published, waiting..."); - usleep(500000); // 0.5 s - } while (true); - if (gAudioPolicyServiceClient == NULL) { - gAudioPolicyServiceClient = new AudioPolicyServiceClient(); - } - binder->linkToDeath(gAudioPolicyServiceClient); - gAudioPolicyService = interface_cast<IAudioPolicyService>(binder); - gLock.unlock(); - } else { - gLock.unlock(); - } - return gAudioPolicyService; -} - -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(); - const char *address = ""; - - if (aps == 0) return PERMISSION_DENIED; - - if (device_address != NULL) { - address = device_address; - } - - return aps->setDeviceConnectionState(device, state, address); -} - -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 AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE; - - return aps->getDeviceConnectionState(device, device_address); -} - -status_t AudioSystem::setPhoneState(audio_mode_t state) -{ - if (uint32_t(state) >= AUDIO_MODE_CNT) return BAD_VALUE; - const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service(); - if (aps == 0) return PERMISSION_DENIED; - - return aps->setPhoneState(state); -} - -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); -} - -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 AUDIO_POLICY_FORCE_NONE; - return aps->getForceUse(usage); -} - - -audio_io_handle_t AudioSystem::getOutput(audio_stream_type_t stream, - uint32_t samplingRate, - audio_format_t format, - uint32_t channels, - audio_policy_output_flags_t flags) -{ - audio_io_handle_t output = 0; - // Do not use stream to output map cache if the direct output - // flag is set or if we are likely to use a direct output - // (e.g voice call stream @ 8kHz could use BT SCO device and be routed to - // a direct output on some platforms). - // TODO: the output cache and stream to output mapping implementation needs to - // 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 & 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); - ALOGV_IF((output != 0), "getOutput() read %d from cache for stream %d", output, stream); - } - if (output == 0) { - const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service(); - if (aps == 0) return 0; - output = aps->getOutput(stream, samplingRate, format, channels, flags); - if ((flags & AUDIO_POLICY_OUTPUT_FLAG_DIRECT) == 0) { - Mutex::Autolock _l(gLock); - AudioSystem::gStreamOutputMap.add(stream, output); - } - } - return output; -} - -status_t AudioSystem::startOutput(audio_io_handle_t output, - audio_stream_type_t stream, - int session) -{ - const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service(); - if (aps == 0) return PERMISSION_DENIED; - return aps->startOutput(output, stream, session); -} - -status_t AudioSystem::stopOutput(audio_io_handle_t output, - audio_stream_type_t stream, - int session) -{ - const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service(); - if (aps == 0) return PERMISSION_DENIED; - return aps->stopOutput(output, stream, session); -} - -void AudioSystem::releaseOutput(audio_io_handle_t output) -{ - const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service(); - if (aps == 0) return; - aps->releaseOutput(output); -} - -audio_io_handle_t AudioSystem::getInput(audio_source_t inputSource, - uint32_t samplingRate, - audio_format_t format, - uint32_t channels, - audio_in_acoustics_t acoustics, - int sessionId) -{ - const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service(); - if (aps == 0) return 0; - return aps->getInput(inputSource, samplingRate, format, channels, acoustics, sessionId); -} - -status_t AudioSystem::startInput(audio_io_handle_t input) -{ - const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service(); - if (aps == 0) return PERMISSION_DENIED; - return aps->startInput(input); -} - -status_t AudioSystem::stopInput(audio_io_handle_t input) -{ - const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service(); - if (aps == 0) return PERMISSION_DENIED; - return aps->stopInput(input); -} - -void AudioSystem::releaseInput(audio_io_handle_t input) -{ - const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service(); - if (aps == 0) return; - aps->releaseInput(input); -} - -status_t AudioSystem::initStreamVolume(audio_stream_type_t stream, - int indexMin, - int indexMax) -{ - const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service(); - if (aps == 0) return PERMISSION_DENIED; - return aps->initStreamVolume(stream, indexMin, indexMax); -} - -status_t AudioSystem::setStreamVolumeIndex(audio_stream_type_t stream, - int index, - audio_devices_t device) -{ - const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service(); - if (aps == 0) return PERMISSION_DENIED; - return aps->setStreamVolumeIndex(stream, index, device); -} - -status_t AudioSystem::getStreamVolumeIndex(audio_stream_type_t stream, - int *index, - audio_devices_t device) -{ - const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service(); - if (aps == 0) return PERMISSION_DENIED; - return aps->getStreamVolumeIndex(stream, index, device); -} - -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); -} - -audio_devices_t AudioSystem::getDevicesForStream(audio_stream_type_t stream) -{ - const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service(); - if (aps == 0) return (audio_devices_t)0; - return aps->getDevicesForStream(stream); -} - -audio_io_handle_t AudioSystem::getOutputForEffect(effect_descriptor_t *desc) -{ - const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service(); - if (aps == 0) return PERMISSION_DENIED; - return aps->getOutputForEffect(desc); -} - -status_t AudioSystem::registerEffect(effect_descriptor_t *desc, - audio_io_handle_t io, - uint32_t strategy, - int session, - int id) -{ - const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service(); - if (aps == 0) return PERMISSION_DENIED; - return aps->registerEffect(desc, io, strategy, session, id); -} - -status_t AudioSystem::unregisterEffect(int id) -{ - const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service(); - if (aps == 0) return PERMISSION_DENIED; - return aps->unregisterEffect(id); -} - -status_t AudioSystem::setEffectEnabled(int id, bool enabled) -{ - const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service(); - if (aps == 0) return PERMISSION_DENIED; - return aps->setEffectEnabled(id, enabled); -} - -status_t AudioSystem::isStreamActive(audio_stream_type_t stream, bool* state, uint32_t inPastMs) -{ - const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service(); - if (aps == 0) return PERMISSION_DENIED; - if (state == NULL) return BAD_VALUE; - *state = aps->isStreamActive(stream, inPastMs); - return NO_ERROR; -} - - -void AudioSystem::clearAudioConfigCache() -{ - Mutex::Autolock _l(gLock); - ALOGV("clearAudioConfigCache()"); - gStreamOutputMap.clear(); - gOutputs.clear(); -} - -// --------------------------------------------------------------------------- - -void AudioSystem::AudioPolicyServiceClient::binderDied(const wp<IBinder>& who) { - Mutex::Autolock _l(AudioSystem::gLock); - AudioSystem::gAudioPolicyService.clear(); - - ALOGW("AudioPolicyService server died!"); -} - -}; // namespace android diff --git a/media/libmedia/AudioTrack.cpp b/media/libmedia/AudioTrack.cpp deleted file mode 100644 index bafde3a..0000000 --- a/media/libmedia/AudioTrack.cpp +++ /dev/null @@ -1,1531 +0,0 @@ -/* -** -** Copyright 2007, 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_NDEBUG 0 -#define LOG_TAG "AudioTrack" - -#include <stdint.h> -#include <sys/types.h> -#include <limits.h> - -#include <sched.h> -#include <sys/resource.h> - -#include <private/media/AudioTrackShared.h> - -#include <media/AudioSystem.h> -#include <media/AudioTrack.h> - -#include <utils/Log.h> -#include <binder/Parcel.h> -#include <binder/IPCThreadState.h> -#include <utils/Timers.h> -#include <utils/Atomic.h> - -#include <cutils/bitops.h> -#include <cutils/compiler.h> - -#include <system/audio.h> -#include <system/audio_policy.h> - -#include <audio_utils/primitives.h> - -namespace android { -// --------------------------------------------------------------------------- - -// static -status_t AudioTrack::getMinFrameCount( - int* frameCount, - audio_stream_type_t streamType, - uint32_t sampleRate) -{ - int afSampleRate; - if (AudioSystem::getOutputSamplingRate(&afSampleRate, streamType) != NO_ERROR) { - return NO_INIT; - } - int afFrameCount; - if (AudioSystem::getOutputFrameCount(&afFrameCount, streamType) != NO_ERROR) { - return NO_INIT; - } - uint32_t afLatency; - if (AudioSystem::getOutputLatency(&afLatency, streamType) != NO_ERROR) { - return NO_INIT; - } - - // Ensure that buffer depth covers at least audio hardware latency - uint32_t minBufCount = afLatency / ((1000 * afFrameCount) / afSampleRate); - if (minBufCount < 2) minBufCount = 2; - - *frameCount = (sampleRate == 0) ? afFrameCount * minBufCount : - afFrameCount * minBufCount * sampleRate / afSampleRate; - return NO_ERROR; -} - -// --------------------------------------------------------------------------- - -AudioTrack::AudioTrack() - : mStatus(NO_INIT), - mIsTimed(false), - mPreviousPriority(ANDROID_PRIORITY_NORMAL), - mPreviousSchedulingGroup(ANDROID_TGROUP_DEFAULT) -{ -} - -AudioTrack::AudioTrack( - audio_stream_type_t streamType, - uint32_t sampleRate, - audio_format_t format, - int channelMask, - int frameCount, - audio_policy_output_flags_t flags, - callback_t cbf, - void* user, - int notificationFrames, - int sessionId) - : mStatus(NO_INIT), - mIsTimed(false), - mPreviousPriority(ANDROID_PRIORITY_NORMAL), - mPreviousSchedulingGroup(ANDROID_TGROUP_DEFAULT) -{ - mStatus = set(streamType, sampleRate, format, channelMask, - frameCount, flags, cbf, user, notificationFrames, - 0 /*sharedBuffer*/, false /*threadCanCallJava*/, sessionId); -} - -// DEPRECATED -AudioTrack::AudioTrack( - int streamType, - uint32_t sampleRate, - int format, - int channelMask, - int frameCount, - uint32_t flags, - callback_t cbf, - void* user, - int notificationFrames, - int sessionId) - : mStatus(NO_INIT), - mIsTimed(false), - mPreviousPriority(ANDROID_PRIORITY_NORMAL), mPreviousSchedulingGroup(ANDROID_TGROUP_DEFAULT) -{ - mStatus = set((audio_stream_type_t)streamType, sampleRate, (audio_format_t)format, channelMask, - frameCount, (audio_policy_output_flags_t)flags, cbf, user, notificationFrames, - 0 /*sharedBuffer*/, false /*threadCanCallJava*/, sessionId); -} - -AudioTrack::AudioTrack( - audio_stream_type_t streamType, - uint32_t sampleRate, - audio_format_t format, - int channelMask, - const sp<IMemory>& sharedBuffer, - audio_policy_output_flags_t flags, - callback_t cbf, - void* user, - int notificationFrames, - int sessionId) - : mStatus(NO_INIT), - mIsTimed(false), - mPreviousPriority(ANDROID_PRIORITY_NORMAL), - mPreviousSchedulingGroup(ANDROID_TGROUP_DEFAULT) -{ - mStatus = set(streamType, sampleRate, format, channelMask, - 0 /*frameCount*/, flags, cbf, user, notificationFrames, - sharedBuffer, false /*threadCanCallJava*/, sessionId); -} - -AudioTrack::~AudioTrack() -{ - ALOGV_IF(mSharedBuffer != 0, "Destructor sharedBuffer: %p", mSharedBuffer->pointer()); - - if (mStatus == NO_ERROR) { - // Make sure that callback function exits in the case where - // it is looping on buffer full condition in obtainBuffer(). - // Otherwise the callback thread will never exit. - stop(); - if (mAudioTrackThread != 0) { - mAudioTrackThread->requestExitAndWait(); - mAudioTrackThread.clear(); - } - mAudioTrack.clear(); - IPCThreadState::self()->flushCommands(); - AudioSystem::releaseAudioSessionId(mSessionId); - } -} - -status_t AudioTrack::set( - audio_stream_type_t streamType, - uint32_t sampleRate, - audio_format_t format, - int channelMask, - int frameCount, - audio_policy_output_flags_t flags, - callback_t cbf, - void* user, - int notificationFrames, - const sp<IMemory>& sharedBuffer, - bool threadCanCallJava, - int sessionId) -{ - - ALOGV_IF(sharedBuffer != 0, "sharedBuffer: %p, size: %d", sharedBuffer->pointer(), sharedBuffer->size()); - - AutoMutex lock(mLock); - if (mAudioTrack != 0) { - ALOGE("Track already in use"); - return INVALID_OPERATION; - } - - int afSampleRate; - if (AudioSystem::getOutputSamplingRate(&afSampleRate, streamType) != NO_ERROR) { - return NO_INIT; - } - - uint32_t afLatency; - if (AudioSystem::getOutputLatency(&afLatency, streamType) != NO_ERROR) { - return NO_INIT; - } - - // handle default values first. - 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 == AUDIO_FORMAT_DEFAULT) { - format = AUDIO_FORMAT_PCM_16_BIT; - } - if (channelMask == 0) { - channelMask = AUDIO_CHANNEL_OUT_STEREO; - } - - // validate parameters - if (!audio_is_valid_format(format)) { - ALOGE("Invalid format"); - return BAD_VALUE; - } - - // force direct flag if format is not linear PCM - if (!audio_is_linear_pcm(format)) { - flags = (audio_policy_output_flags_t) (flags | AUDIO_POLICY_OUTPUT_FLAG_DIRECT); - } - - if (!audio_is_output_channel(channelMask)) { - ALOGE("Invalid channel mask"); - return BAD_VALUE; - } - uint32_t channelCount = popcount(channelMask); - - audio_io_handle_t output = AudioSystem::getOutput( - streamType, - sampleRate, format, channelMask, - flags); - - if (output == 0) { - ALOGE("Could not get audio output for stream type %d", streamType); - return BAD_VALUE; - } - - mVolume[LEFT] = 1.0f; - mVolume[RIGHT] = 1.0f; - mSendLevel = 0.0f; - mFrameCount = frameCount; - mNotificationFramesReq = notificationFrames; - mSessionId = sessionId; - mAuxEffectId = 0; - - // create the IAudioTrack - status_t status = createTrack_l(streamType, - sampleRate, - format, - (uint32_t)channelMask, - frameCount, - flags, - sharedBuffer, - output); - - if (status != NO_ERROR) { - return status; - } - - if (cbf != NULL) { - mAudioTrackThread = new AudioTrackThread(*this, threadCanCallJava); - } - - mStatus = NO_ERROR; - - mStreamType = streamType; - mFormat = format; - mChannelMask = (uint32_t)channelMask; - mChannelCount = channelCount; - mSharedBuffer = sharedBuffer; - mMuted = false; - mActive = false; - mCbf = cbf; - mUserData = user; - mLoopCount = 0; - mMarkerPosition = 0; - mMarkerReached = false; - mNewPosition = 0; - mUpdatePeriod = 0; - mFlushed = false; - mFlags = flags; - AudioSystem::acquireAudioSessionId(mSessionId); - mRestoreStatus = NO_ERROR; - return NO_ERROR; -} - -status_t AudioTrack::initCheck() const -{ - return mStatus; -} - -// ------------------------------------------------------------------------- - -uint32_t AudioTrack::latency() const -{ - return mLatency; -} - -audio_stream_type_t AudioTrack::streamType() const -{ - return mStreamType; -} - -audio_format_t AudioTrack::format() const -{ - return mFormat; -} - -int AudioTrack::channelCount() const -{ - return mChannelCount; -} - -uint32_t AudioTrack::frameCount() const -{ - return mCblk->frameCount; -} - -size_t AudioTrack::frameSize() const -{ - if (audio_is_linear_pcm(mFormat)) { - return channelCount()*audio_bytes_per_sample(mFormat); - } else { - return sizeof(uint8_t); - } -} - -sp<IMemory>& AudioTrack::sharedBuffer() -{ - return mSharedBuffer; -} - -// ------------------------------------------------------------------------- - -void AudioTrack::start() -{ - sp<AudioTrackThread> t = mAudioTrackThread; - status_t status = NO_ERROR; - - ALOGV("start %p", this); - if (t != 0) { - if (t->exitPending()) { - if (t->requestExitAndWait() == WOULD_BLOCK) { - ALOGE("AudioTrack::start called from thread"); - return; - } - } - } - - AutoMutex lock(mLock); - // acquire a strong reference on the IMemory and IAudioTrack so that they cannot be destroyed - // while we are accessing the cblk - sp<IAudioTrack> audioTrack = mAudioTrack; - sp<IMemory> iMem = mCblkMemory; - audio_track_cblk_t* cblk = mCblk; - - if (!mActive) { - mFlushed = false; - mActive = true; - mNewPosition = cblk->server + mUpdatePeriod; - cblk->lock.lock(); - cblk->bufferTimeoutMs = MAX_STARTUP_TIMEOUT_MS; - cblk->waitTimeMs = 0; - android_atomic_and(~CBLK_DISABLED_ON, &cblk->flags); - pid_t tid; - if (t != 0) { - t->run("AudioTrack", ANDROID_PRIORITY_AUDIO); - tid = t->getTid(); // pid_t is unknown until run() - ALOGV("getTid=%d", tid); - if (tid == -1) { - tid = 0; - } - } else { - mPreviousPriority = getpriority(PRIO_PROCESS, 0); - mPreviousSchedulingGroup = androidGetThreadSchedulingGroup(0); - androidSetThreadPriority(0, ANDROID_PRIORITY_AUDIO); - tid = 0; // not gettid() - } - - ALOGV("start %p before lock cblk %p", this, mCblk); - if (!(cblk->flags & CBLK_INVALID_MSK)) { - cblk->lock.unlock(); - ALOGV("mAudioTrack->start(tid=%d)", tid); - status = mAudioTrack->start(tid); - cblk->lock.lock(); - if (status == DEAD_OBJECT) { - android_atomic_or(CBLK_INVALID_ON, &cblk->flags); - } - } - if (cblk->flags & CBLK_INVALID_MSK) { - status = restoreTrack_l(cblk, true); - } - cblk->lock.unlock(); - if (status != NO_ERROR) { - ALOGV("start() failed"); - mActive = false; - if (t != 0) { - t->requestExit(); - } else { - setpriority(PRIO_PROCESS, 0, mPreviousPriority); - androidSetThreadSchedulingGroup(0, mPreviousSchedulingGroup); - } - } - } - -} - -void AudioTrack::stop() -{ - sp<AudioTrackThread> t = mAudioTrackThread; - - ALOGV("stop %p", this); - - AutoMutex lock(mLock); - if (mActive) { - mActive = false; - mCblk->cv.signal(); - mAudioTrack->stop(); - // Cancel loops (If we are in the middle of a loop, playback - // would not stop until loopCount reaches 0). - setLoop_l(0, 0, 0); - // the playback head position will reset to 0, so if a marker is set, we need - // to activate it again - mMarkerReached = false; - // Force flush if a shared buffer is used otherwise audioflinger - // will not stop before end of buffer is reached. - if (mSharedBuffer != 0) { - flush_l(); - } - if (t != 0) { - t->requestExit(); - } else { - setpriority(PRIO_PROCESS, 0, mPreviousPriority); - androidSetThreadSchedulingGroup(0, mPreviousSchedulingGroup); - } - } - -} - -bool AudioTrack::stopped() const -{ - AutoMutex lock(mLock); - return stopped_l(); -} - -void AudioTrack::flush() -{ - AutoMutex lock(mLock); - flush_l(); -} - -// must be called with mLock held -void AudioTrack::flush_l() -{ - ALOGV("flush"); - - // clear playback marker and periodic update counter - mMarkerPosition = 0; - mMarkerReached = false; - mUpdatePeriod = 0; - - if (!mActive) { - mFlushed = true; - mAudioTrack->flush(); - // Release AudioTrack callback thread in case it was waiting for new buffers - // in AudioTrack::obtainBuffer() - mCblk->cv.signal(); - } -} - -void AudioTrack::pause() -{ - ALOGV("pause"); - AutoMutex lock(mLock); - if (mActive) { - mActive = false; - mAudioTrack->pause(); - } -} - -void AudioTrack::mute(bool e) -{ - mAudioTrack->mute(e); - mMuted = e; -} - -bool AudioTrack::muted() const -{ - return mMuted; -} - -status_t AudioTrack::setVolume(float left, float right) -{ - if (left < 0.0f || left > 1.0f || right < 0.0f || right > 1.0f) { - return BAD_VALUE; - } - - AutoMutex lock(mLock); - mVolume[LEFT] = left; - mVolume[RIGHT] = right; - - mCblk->setVolumeLR((uint32_t(uint16_t(right * 0x1000)) << 16) | uint16_t(left * 0x1000)); - - return NO_ERROR; -} - -void AudioTrack::getVolume(float* left, float* right) const -{ - if (left != NULL) { - *left = mVolume[LEFT]; - } - if (right != NULL) { - *right = mVolume[RIGHT]; - } -} - -status_t AudioTrack::setAuxEffectSendLevel(float level) -{ - ALOGV("setAuxEffectSendLevel(%f)", level); - if (level < 0.0f || level > 1.0f) { - return BAD_VALUE; - } - AutoMutex lock(mLock); - - mSendLevel = level; - - mCblk->setSendLevel(level); - - return NO_ERROR; -} - -void AudioTrack::getAuxEffectSendLevel(float* level) const -{ - if (level != NULL) { - *level = mSendLevel; - } -} - -status_t AudioTrack::setSampleRate(int rate) -{ - int afSamplingRate; - - if (mIsTimed) { - return INVALID_OPERATION; - } - - if (AudioSystem::getOutputSamplingRate(&afSamplingRate, mStreamType) != NO_ERROR) { - return NO_INIT; - } - // Resampler implementation limits input sampling rate to 2 x output sampling rate. - if (rate <= 0 || rate > afSamplingRate*2 ) return BAD_VALUE; - - AutoMutex lock(mLock); - mCblk->sampleRate = rate; - return NO_ERROR; -} - -uint32_t AudioTrack::getSampleRate() const -{ - if (mIsTimed) { - return INVALID_OPERATION; - } - - AutoMutex lock(mLock); - return mCblk->sampleRate; -} - -status_t AudioTrack::setLoop(uint32_t loopStart, uint32_t loopEnd, int loopCount) -{ - AutoMutex lock(mLock); - return setLoop_l(loopStart, loopEnd, loopCount); -} - -// must be called with mLock held -status_t AudioTrack::setLoop_l(uint32_t loopStart, uint32_t loopEnd, int loopCount) -{ - audio_track_cblk_t* cblk = mCblk; - - Mutex::Autolock _l(cblk->lock); - - if (loopCount == 0) { - cblk->loopStart = UINT_MAX; - cblk->loopEnd = UINT_MAX; - cblk->loopCount = 0; - mLoopCount = 0; - return NO_ERROR; - } - - if (mIsTimed) { - return INVALID_OPERATION; - } - - if (loopStart >= loopEnd || - loopEnd - loopStart > cblk->frameCount || - cblk->server > loopStart) { - ALOGE("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)) { - ALOGE("setLoop invalid value: loop markers beyond data: loopStart %d, loopEnd %d, framecount %d", - loopStart, loopEnd, cblk->frameCount); - return BAD_VALUE; - } - - cblk->loopStart = loopStart; - cblk->loopEnd = loopEnd; - cblk->loopCount = loopCount; - mLoopCount = loopCount; - - return NO_ERROR; -} - -status_t AudioTrack::setMarkerPosition(uint32_t marker) -{ - if (mCbf == NULL) return INVALID_OPERATION; - - mMarkerPosition = marker; - mMarkerReached = false; - - return NO_ERROR; -} - -status_t AudioTrack::getMarkerPosition(uint32_t *marker) const -{ - if (marker == NULL) return BAD_VALUE; - - *marker = mMarkerPosition; - - return NO_ERROR; -} - -status_t AudioTrack::setPositionUpdatePeriod(uint32_t updatePeriod) -{ - if (mCbf == NULL) return INVALID_OPERATION; - - uint32_t curPosition; - getPosition(&curPosition); - mNewPosition = curPosition + updatePeriod; - mUpdatePeriod = updatePeriod; - - return NO_ERROR; -} - -status_t AudioTrack::getPositionUpdatePeriod(uint32_t *updatePeriod) const -{ - if (updatePeriod == NULL) return BAD_VALUE; - - *updatePeriod = mUpdatePeriod; - - return NO_ERROR; -} - -status_t AudioTrack::setPosition(uint32_t position) -{ - if (mIsTimed) return INVALID_OPERATION; - - AutoMutex lock(mLock); - - if (!stopped_l()) return INVALID_OPERATION; - - Mutex::Autolock _l(mCblk->lock); - - if (position > mCblk->user) return BAD_VALUE; - - mCblk->server = position; - android_atomic_or(CBLK_FORCEREADY_ON, &mCblk->flags); - - return NO_ERROR; -} - -status_t AudioTrack::getPosition(uint32_t *position) -{ - if (position == NULL) return BAD_VALUE; - AutoMutex lock(mLock); - *position = mFlushed ? 0 : mCblk->server; - - return NO_ERROR; -} - -status_t AudioTrack::reload() -{ - AutoMutex lock(mLock); - - if (!stopped_l()) return INVALID_OPERATION; - - flush_l(); - - mCblk->stepUser(mCblk->frameCount); - - return NO_ERROR; -} - -audio_io_handle_t AudioTrack::getOutput() -{ - AutoMutex lock(mLock); - return getOutput_l(); -} - -// must be called with mLock held -audio_io_handle_t AudioTrack::getOutput_l() -{ - return AudioSystem::getOutput(mStreamType, - mCblk->sampleRate, mFormat, mChannelMask, mFlags); -} - -int AudioTrack::getSessionId() const -{ - return mSessionId; -} - -status_t AudioTrack::attachAuxEffect(int effectId) -{ - ALOGV("attachAuxEffect(%d)", effectId); - status_t status = mAudioTrack->attachAuxEffect(effectId); - if (status == NO_ERROR) { - mAuxEffectId = effectId; - } - return status; -} - -// ------------------------------------------------------------------------- - -// must be called with mLock held -status_t AudioTrack::createTrack_l( - audio_stream_type_t streamType, - uint32_t sampleRate, - audio_format_t format, - uint32_t channelMask, - int frameCount, - audio_policy_output_flags_t flags, - const sp<IMemory>& sharedBuffer, - audio_io_handle_t output) -{ - status_t status; - const sp<IAudioFlinger>& audioFlinger = AudioSystem::get_audio_flinger(); - if (audioFlinger == 0) { - ALOGE("Could not get audioflinger"); - return NO_INIT; - } - - int afSampleRate; - if (AudioSystem::getOutputSamplingRate(&afSampleRate, streamType) != NO_ERROR) { - return NO_INIT; - } - int afFrameCount; - if (AudioSystem::getOutputFrameCount(&afFrameCount, streamType) != NO_ERROR) { - return NO_INIT; - } - uint32_t afLatency; - if (AudioSystem::getOutputLatency(&afLatency, streamType) != NO_ERROR) { - return NO_INIT; - } - - mNotificationFramesAct = mNotificationFramesReq; - if (!audio_is_linear_pcm(format)) { - if (sharedBuffer != 0) { - frameCount = sharedBuffer->size(); - } - } else { - // Ensure that buffer depth covers at least audio hardware latency - uint32_t minBufCount = afLatency / ((1000 * afFrameCount)/afSampleRate); - if (minBufCount < 2) minBufCount = 2; - - int minFrameCount = (afFrameCount*sampleRate*minBufCount)/afSampleRate; - - if (sharedBuffer == 0) { - if (frameCount == 0) { - frameCount = minFrameCount; - } - if (mNotificationFramesAct == 0) { - mNotificationFramesAct = frameCount/2; - } - // Make sure that application is notified with sufficient margin - // before underrun - if (mNotificationFramesAct > (uint32_t)frameCount/2) { - mNotificationFramesAct = frameCount/2; - } - if (frameCount < minFrameCount) { - // not ALOGW because it happens all the time when playing key clicks over A2DP - ALOGV("Minimum buffer size corrected from %d to %d", - frameCount, minFrameCount); - frameCount = minFrameCount; - } - } else { - // Ensure that buffer alignment matches channelCount - int channelCount = popcount(channelMask); - if (((uint32_t)sharedBuffer->pointer() & (channelCount | 1)) != 0) { - ALOGE("Invalid buffer alignement: address %p, channelCount %d", sharedBuffer->pointer(), channelCount); - return BAD_VALUE; - } - frameCount = sharedBuffer->size()/channelCount/sizeof(int16_t); - } - } - - IAudioFlinger::track_flags_t trackFlags = IAudioFlinger::TRACK_DEFAULT; - if (mIsTimed) { - trackFlags |= IAudioFlinger::TRACK_TIMED; - } - sp<IAudioTrack> track = audioFlinger->createTrack(getpid(), - streamType, - sampleRate, - format, - channelMask, - frameCount, - trackFlags, - sharedBuffer, - output, - &mSessionId, - &status); - - if (track == 0) { - ALOGE("AudioFlinger could not create track, status: %d", status); - return status; - } - sp<IMemory> cblk = track->getCblk(); - if (cblk == 0) { - ALOGE("Could not get control block"); - return NO_INIT; - } - mAudioTrack = track; - mCblkMemory = cblk; - mCblk = static_cast<audio_track_cblk_t*>(cblk->pointer()); - android_atomic_or(CBLK_DIRECTION_OUT, &mCblk->flags); - if (sharedBuffer == 0) { - mCblk->buffers = (char*)mCblk + sizeof(audio_track_cblk_t); - } else { - mCblk->buffers = sharedBuffer->pointer(); - // Force buffer full condition as data is already present in shared memory - mCblk->stepUser(mCblk->frameCount); - } - - mCblk->setVolumeLR((uint32_t(uint16_t(mVolume[RIGHT] * 0x1000)) << 16) | uint16_t(mVolume[LEFT] * 0x1000)); - mCblk->setSendLevel(mSendLevel); - mAudioTrack->attachAuxEffect(mAuxEffectId); - mCblk->bufferTimeoutMs = MAX_STARTUP_TIMEOUT_MS; - mCblk->waitTimeMs = 0; - mRemainingFrames = mNotificationFramesAct; - mLatency = afLatency + (1000*mCblk->frameCount) / sampleRate; - return NO_ERROR; -} - -status_t AudioTrack::obtainBuffer(Buffer* audioBuffer, int32_t waitCount) -{ - AutoMutex lock(mLock); - bool active; - status_t result = NO_ERROR; - audio_track_cblk_t* cblk = mCblk; - uint32_t framesReq = audioBuffer->frameCount; - uint32_t waitTimeMs = (waitCount < 0) ? cblk->bufferTimeoutMs : WAIT_PERIOD_MS; - - audioBuffer->frameCount = 0; - audioBuffer->size = 0; - - 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; - while (framesAvail == 0) { - active = mActive; - if (CC_UNLIKELY(!active)) { - ALOGV("Not active and NO_MORE_BUFFERS"); - cblk->lock.unlock(); - return NO_MORE_BUFFERS; - } - if (CC_UNLIKELY(!waitCount)) { - cblk->lock.unlock(); - return WOULD_BLOCK; - } - if (!(cblk->flags & CBLK_INVALID_MSK)) { - mLock.unlock(); - result = cblk->cv.waitRelative(cblk->lock, milliseconds(waitTimeMs)); - cblk->lock.unlock(); - mLock.lock(); - if (!mActive) { - return status_t(STOPPED); - } - cblk->lock.lock(); - } - - if (cblk->flags & CBLK_INVALID_MSK) { - goto create_new_track; - } - if (CC_UNLIKELY(result != NO_ERROR)) { - cblk->waitTimeMs += waitTimeMs; - if (cblk->waitTimeMs >= cblk->bufferTimeoutMs) { - // timing out when a loop has been set and we have already written upto loop end - // is a normal condition: no need to wake AudioFlinger up. - if (cblk->user < cblk->loopEnd) { - ALOGW( "obtainBuffer timed out (is the CPU pegged?) %p " - "user=%08x, server=%08x", this, cblk->user, cblk->server); - //unlock cblk mutex before calling mAudioTrack->start() (see issue #1617140) - cblk->lock.unlock(); - result = mAudioTrack->start(0); // callback thread hasn't changed - cblk->lock.lock(); - if (result == DEAD_OBJECT) { - android_atomic_or(CBLK_INVALID_ON, &cblk->flags); -create_new_track: - result = restoreTrack_l(cblk, false); - } - if (result != NO_ERROR) { - ALOGW("obtainBuffer create Track error %d", result); - cblk->lock.unlock(); - return result; - } - } - cblk->waitTimeMs = 0; - } - - if (--waitCount == 0) { - cblk->lock.unlock(); - return TIMED_OUT; - } - } - // read the server count again - start_loop_here: - framesAvail = cblk->framesAvailable_l(); - } - cblk->lock.unlock(); - } - - // restart track if it was disabled by audioflinger due to previous underrun - if (mActive && (cblk->flags & CBLK_DISABLED_MSK)) { - android_atomic_and(~CBLK_DISABLED_ON, &cblk->flags); - ALOGW("obtainBuffer() track %p disabled, restarting", this); - mAudioTrack->start(0); // callback thread hasn't changed - } - - cblk->waitTimeMs = 0; - - if (framesReq > framesAvail) { - framesReq = framesAvail; - } - - uint32_t u = cblk->user; - uint32_t bufferEnd = cblk->userBase + cblk->frameCount; - - if (u + framesReq > bufferEnd) { - framesReq = bufferEnd - u; - } - - audioBuffer->flags = mMuted ? Buffer::MUTE : 0; - audioBuffer->channelCount = mChannelCount; - audioBuffer->frameCount = framesReq; - audioBuffer->size = framesReq * cblk->frameSize; - if (audio_is_linear_pcm(mFormat)) { - audioBuffer->format = AUDIO_FORMAT_PCM_16_BIT; - } else { - audioBuffer->format = mFormat; - } - audioBuffer->raw = (int8_t *)cblk->buffer(u); - active = mActive; - return active ? status_t(NO_ERROR) : status_t(STOPPED); -} - -void AudioTrack::releaseBuffer(Buffer* audioBuffer) -{ - AutoMutex lock(mLock); - mCblk->stepUser(audioBuffer->frameCount); -} - -// ------------------------------------------------------------------------- - -ssize_t AudioTrack::write(const void* buffer, size_t userSize) -{ - - if (mSharedBuffer != 0) return INVALID_OPERATION; - if (mIsTimed) return INVALID_OPERATION; - - if (ssize_t(userSize) < 0) { - // Sanity-check: user is most-likely passing an error code, and it would - // make the return value ambiguous (actualSize vs error). - ALOGE("AudioTrack::write(buffer=%p, size=%u (%d)", - buffer, userSize, userSize); - return BAD_VALUE; - } - - ALOGV("write %p: %d bytes, mActive=%d", this, userSize, mActive); - - // acquire a strong reference on the IMemory and IAudioTrack so that they cannot be destroyed - // while we are accessing the cblk - mLock.lock(); - sp<IAudioTrack> audioTrack = mAudioTrack; - sp<IMemory> iMem = mCblkMemory; - mLock.unlock(); - - ssize_t written = 0; - const int8_t *src = (const int8_t *)buffer; - Buffer audioBuffer; - size_t frameSz = frameSize(); - - do { - audioBuffer.frameCount = userSize/frameSz; - - status_t err = obtainBuffer(&audioBuffer, -1); - if (err < 0) { - // out of buffers, return #bytes written - if (err == status_t(NO_MORE_BUFFERS)) - break; - return ssize_t(err); - } - - size_t toWrite; - - 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; - memcpy_to_i16_from_u8(audioBuffer.i16, (const uint8_t *) src, toWrite); - } else { - toWrite = audioBuffer.size; - memcpy(audioBuffer.i8, src, toWrite); - src += toWrite; - } - userSize -= toWrite; - written += toWrite; - - releaseBuffer(&audioBuffer); - } while (userSize >= frameSz); - - return written; -} - -// ------------------------------------------------------------------------- - -TimedAudioTrack::TimedAudioTrack() { - mIsTimed = true; -} - -status_t TimedAudioTrack::allocateTimedBuffer(size_t size, sp<IMemory>* buffer) -{ - status_t result = UNKNOWN_ERROR; - - // If the track is not invalid already, try to allocate a buffer. alloc - // fails indicating that the server is dead, flag the track as invalid so - // we can attempt to restore in in just a bit. - if (!(mCblk->flags & CBLK_INVALID_MSK)) { - result = mAudioTrack->allocateTimedBuffer(size, buffer); - if (result == DEAD_OBJECT) { - android_atomic_or(CBLK_INVALID_ON, &mCblk->flags); - } - } - - // If the track is invalid at this point, attempt to restore it. and try the - // allocation one more time. - if (mCblk->flags & CBLK_INVALID_MSK) { - mCblk->lock.lock(); - result = restoreTrack_l(mCblk, false); - mCblk->lock.unlock(); - - if (result == OK) - result = mAudioTrack->allocateTimedBuffer(size, buffer); - } - - return result; -} - -status_t TimedAudioTrack::queueTimedBuffer(const sp<IMemory>& buffer, - int64_t pts) -{ - // restart track if it was disabled by audioflinger due to previous underrun - if (mActive && (mCblk->flags & CBLK_DISABLED_MSK)) { - android_atomic_and(~CBLK_DISABLED_ON, &mCblk->flags); - ALOGW("queueTimedBuffer() track %p disabled, restarting", this); - mAudioTrack->start(0); - } - - return mAudioTrack->queueTimedBuffer(buffer, pts); -} - -status_t TimedAudioTrack::setMediaTimeTransform(const LinearTransform& xform, - TargetTimeline target) -{ - return mAudioTrack->setMediaTimeTransform(xform, target); -} - -// ------------------------------------------------------------------------- - -bool AudioTrack::processAudioBuffer(const sp<AudioTrackThread>& thread) -{ - Buffer audioBuffer; - uint32_t frames; - size_t writtenSize; - - mLock.lock(); - // acquire a strong reference on the IMemory and IAudioTrack so that they cannot be destroyed - // while we are accessing the cblk - sp<IAudioTrack> audioTrack = mAudioTrack; - sp<IMemory> iMem = mCblkMemory; - audio_track_cblk_t* cblk = mCblk; - bool active = mActive; - mLock.unlock(); - - // Manage underrun callback - if (active && (cblk->framesAvailable() == cblk->frameCount)) { - ALOGV("Underrun user: %x, server: %x, flags %04x", cblk->user, cblk->server, cblk->flags); - 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); - } - if (mSharedBuffer != 0) return false; - } - } - - // Manage loop end callback - while (mLoopCount > cblk->loopCount) { - int loopCount = -1; - mLoopCount--; - if (mLoopCount >= 0) loopCount = mLoopCount; - - mCbf(EVENT_LOOP_END, mUserData, (void *)&loopCount); - } - - // Manage marker callback - if (!mMarkerReached && (mMarkerPosition > 0)) { - if (cblk->server >= mMarkerPosition) { - mCbf(EVENT_MARKER, mUserData, (void *)&mMarkerPosition); - mMarkerReached = true; - } - } - - // Manage new position callback - if (mUpdatePeriod > 0) { - while (cblk->server >= mNewPosition) { - mCbf(EVENT_NEW_POS, mUserData, (void *)&mNewPosition); - mNewPosition += mUpdatePeriod; - } - } - - // If Shared buffer is used, no data is requested from client. - if (mSharedBuffer != 0) { - frames = 0; - } else { - frames = mRemainingFrames; - } - - // See description of waitCount parameter at declaration of obtainBuffer(). - // The logic below prevents us from being stuck below at obtainBuffer() - // not being able to handle timed events (position, markers, loops). - int32_t waitCount = -1; - if (mUpdatePeriod || (!mMarkerReached && mMarkerPosition) || mLoopCount) { - waitCount = 1; - } - - do { - - audioBuffer.frameCount = frames; - - status_t err = obtainBuffer(&audioBuffer, waitCount); - if (err < NO_ERROR) { - if (err != TIMED_OUT) { - ALOGE_IF(err != status_t(NO_MORE_BUFFERS), "Error obtaining an audio buffer, giving up."); - return false; - } - break; - } - if (err == status_t(STOPPED)) return false; - - // 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 == AUDIO_FORMAT_PCM_8_BIT && !(mFlags & AUDIO_POLICY_OUTPUT_FLAG_DIRECT)) { - audioBuffer.size >>= 1; - } - - size_t reqSize = audioBuffer.size; - mCbf(EVENT_MORE_DATA, mUserData, &audioBuffer); - writtenSize = audioBuffer.size; - - // Sanity check on returned size - if (ssize_t(writtenSize) <= 0) { - // The callback is done filling buffers - // Keep this thread going to handle timed events and - // still try to get more data in intervals of WAIT_PERIOD_MS - // but don't just loop and block the CPU, so wait - usleep(WAIT_PERIOD_MS*1000); - break; - } - if (writtenSize > reqSize) writtenSize = reqSize; - - if (mFormat == AUDIO_FORMAT_PCM_8_BIT && !(mFlags & AUDIO_POLICY_OUTPUT_FLAG_DIRECT)) { - // 8 to 16 bit conversion, note that source and destination are the same address - memcpy_to_i16_from_u8(audioBuffer.i16, (const uint8_t *) audioBuffer.i8, writtenSize); - writtenSize <<= 1; - } - - audioBuffer.size = writtenSize; - // NOTE: mCblk->frameSize is not equal to AudioTrack::frameSize() for - // 8 bit PCM data: in this case, mCblk->frameSize is based on a sample size of - // 16 bit. - audioBuffer.frameCount = writtenSize/mCblk->frameSize; - - frames -= audioBuffer.frameCount; - - releaseBuffer(&audioBuffer); - } - while (frames); - - if (frames == 0) { - mRemainingFrames = mNotificationFramesAct; - } else { - mRemainingFrames = frames; - } - return true; -} - -// must be called with mLock and cblk.lock held. Callers must also hold strong references on -// the IAudioTrack and IMemory in case they are recreated here. -// If the IAudioTrack is successfully restored, the cblk pointer is updated -status_t AudioTrack::restoreTrack_l(audio_track_cblk_t*& cblk, bool fromStart) -{ - status_t result; - - if (!(android_atomic_or(CBLK_RESTORING_ON, &cblk->flags) & CBLK_RESTORING_MSK)) { - ALOGW("dead IAudioTrack, creating a new one from %s TID %d", - fromStart ? "start()" : "obtainBuffer()", gettid()); - - // signal old cblk condition so that other threads waiting for available buffers stop - // waiting now - cblk->cv.broadcast(); - cblk->lock.unlock(); - - // refresh the audio configuration cache in this process to make sure we get new - // output parameters in getOutput_l() and createTrack_l() - AudioSystem::clearAudioConfigCache(); - - // if the new IAudioTrack is created, createTrack_l() will modify the - // following member variables: mAudioTrack, mCblkMemory and mCblk. - // It will also delete the strong references on previous IAudioTrack and IMemory - result = createTrack_l(mStreamType, - cblk->sampleRate, - mFormat, - mChannelMask, - mFrameCount, - mFlags, - mSharedBuffer, - getOutput_l()); - - if (result == NO_ERROR) { - uint32_t user = cblk->user; - uint32_t server = cblk->server; - // restore write index and set other indexes to reflect empty buffer status - mCblk->user = user; - mCblk->server = user; - mCblk->userBase = user; - mCblk->serverBase = 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; - // Make sure that a client relying on callback events indicating underrun or - // the actual amount of audio frames played (e.g SoundPool) receives them. - if (mSharedBuffer == 0) { - uint32_t frames = 0; - if (user > server) { - frames = ((user - server) > mCblk->frameCount) ? - mCblk->frameCount : (user - server); - memset(mCblk->buffers, 0, frames * mCblk->frameSize); - } - // restart playback even if buffer is not completely filled. - android_atomic_or(CBLK_FORCEREADY_ON, &mCblk->flags); - // stepUser() clears CBLK_UNDERRUN_ON flag enabling underrun callbacks to - // the client - mCblk->stepUser(frames); - } - } - if (mActive) { - result = mAudioTrack->start(0); // callback thread hasn't changed - ALOGW_IF(result != NO_ERROR, "restoreTrack_l() start() failed status %d", result); - } - if (fromStart && result == NO_ERROR) { - mNewPosition = mCblk->server + mUpdatePeriod; - } - } - if (result != NO_ERROR) { - android_atomic_and(~CBLK_RESTORING_ON, &cblk->flags); - ALOGW_IF(result != NO_ERROR, "restoreTrack_l() failed status %d", result); - } - mRestoreStatus = result; - // signal old cblk condition for other threads waiting for restore completion - android_atomic_or(CBLK_RESTORED_ON, &cblk->flags); - cblk->cv.broadcast(); - } else { - if (!(cblk->flags & CBLK_RESTORED_MSK)) { - ALOGW("dead IAudioTrack, waiting for a new one TID %d", gettid()); - mLock.unlock(); - result = cblk->cv.waitRelative(cblk->lock, milliseconds(RESTORE_TIMEOUT_MS)); - if (result == NO_ERROR) { - result = mRestoreStatus; - } - cblk->lock.unlock(); - mLock.lock(); - } else { - ALOGW("dead IAudioTrack, already restored TID %d", gettid()); - result = mRestoreStatus; - cblk->lock.unlock(); - } - } - ALOGV("restoreTrack_l() status %d mActive %d cblk %p, old cblk %p flags %08x old flags %08x", - result, mActive, mCblk, cblk, mCblk->flags, cblk->flags); - - if (result == NO_ERROR) { - // from now on we switch to the newly created cblk - cblk = mCblk; - } - cblk->lock.lock(); - - ALOGW_IF(result != NO_ERROR, "restoreTrack_l() error %d TID %d", result, gettid()); - - return result; -} - -status_t AudioTrack::dump(int fd, const Vector<String16>& args) const -{ - - const size_t SIZE = 256; - char buffer[SIZE]; - String8 result; - - result.append(" AudioTrack::dump\n"); - snprintf(buffer, 255, " stream type(%d), left - right volume(%f, %f)\n", mStreamType, mVolume[0], mVolume[1]); - result.append(buffer); - snprintf(buffer, 255, " format(%d), channel count(%d), frame count(%d)\n", mFormat, mChannelCount, mCblk->frameCount); - result.append(buffer); - snprintf(buffer, 255, " sample rate(%d), status(%d), muted(%d)\n", (mCblk == 0) ? 0 : mCblk->sampleRate, mStatus, mMuted); - result.append(buffer); - snprintf(buffer, 255, " active(%d), latency (%d)\n", mActive, mLatency); - result.append(buffer); - ::write(fd, result.string(), result.size()); - return NO_ERROR; -} - -// ========================================================================= - -AudioTrack::AudioTrackThread::AudioTrackThread(AudioTrack& receiver, bool bCanCallJava) - : Thread(bCanCallJava), mReceiver(receiver) -{ -} - -bool AudioTrack::AudioTrackThread::threadLoop() -{ - return mReceiver.processAudioBuffer(this); -} - -status_t AudioTrack::AudioTrackThread::readyToRun() -{ - return NO_ERROR; -} - -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(NULL), frameCount(0), - loopStart(UINT_MAX), loopEnd(UINT_MAX), loopCount(0), mVolumeLR(0x10001000), - mSendLevel(0), flags(0) -{ -} - -uint32_t audio_track_cblk_t::stepUser(uint32_t frameCount) -{ - uint32_t u = user; - - u += frameCount; - // Ensure that user is never ahead of server for AudioRecord - if (flags & CBLK_DIRECTION_MSK) { - // If stepServer() has been called once, switch to normal obtainBuffer() timeout period - if (bufferTimeoutMs == MAX_STARTUP_TIMEOUT_MS-1) { - bufferTimeoutMs = MAX_RUN_TIMEOUT_MS; - } - } else if (u > server) { - ALOGW("stepServer occurred after track reset"); - u = server; - } - - if (u >= userBase + this->frameCount) { - userBase += this->frameCount; - } - - user = u; - - // Clear flow control error condition as new data has been written/read to/from buffer. - if (flags & CBLK_UNDERRUN_MSK) { - android_atomic_and(~CBLK_UNDERRUN_MSK, &flags); - } - - return u; -} - -bool audio_track_cblk_t::stepServer(uint32_t frameCount) -{ - if (!tryLock()) { - ALOGW("stepServer() could not lock cblk"); - return false; - } - - uint32_t s = server; - - s += frameCount; - if (flags & CBLK_DIRECTION_MSK) { - // Mark that we have read the first buffer so that next time stepUser() is called - // we switch to normal obtainBuffer() timeout period - if (bufferTimeoutMs == MAX_STARTUP_TIMEOUT_MS) { - bufferTimeoutMs = MAX_STARTUP_TIMEOUT_MS - 1; - } - // It is possible that we receive a flush() - // while the mixer is processing a block: in this case, - // stepServer() is called After the flush() has reset u & s and - // we have s > u - if (s > user) { - ALOGW("stepServer occurred after track reset"); - s = user; - } - } - - if (s >= loopEnd) { - ALOGW_IF(s > loopEnd, "stepServer: s %u > loopEnd %u", s, loopEnd); - s = loopStart; - if (--loopCount == 0) { - loopEnd = UINT_MAX; - loopStart = UINT_MAX; - } - } - if (s >= serverBase + this->frameCount) { - serverBase += this->frameCount; - } - - server = s; - - if (!(flags & CBLK_INVALID_MSK)) { - cv.signal(); - } - lock.unlock(); - return true; -} - -void* audio_track_cblk_t::buffer(uint32_t offset) const -{ - return (int8_t *)buffers + (offset - userBase) * frameSize; -} - -uint32_t audio_track_cblk_t::framesAvailable() -{ - Mutex::Autolock _l(lock); - return framesAvailable_l(); -} - -uint32_t audio_track_cblk_t::framesAvailable_l() -{ - uint32_t u = user; - uint32_t s = server; - - if (flags & CBLK_DIRECTION_MSK) { - uint32_t limit = (s < loopStart) ? s : loopStart; - return limit + frameCount - u; - } else { - return frameCount + u - s; - } -} - -uint32_t audio_track_cblk_t::framesReady() -{ - uint32_t u = user; - uint32_t s = server; - - if (flags & CBLK_DIRECTION_MSK) { - if (u < loopEnd) { - return u - s; - } else { - // do not block on mutex shared with client on AudioFlinger side - if (!tryLock()) { - ALOGW("framesReady() could not lock cblk"); - return 0; - } - uint32_t frames = UINT_MAX; - if (loopCount >= 0) { - 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/IAudioFlinger.cpp b/media/libmedia/IAudioFlinger.cpp deleted file mode 100644 index ce10c8e..0000000 --- a/media/libmedia/IAudioFlinger.cpp +++ /dev/null @@ -1,1025 +0,0 @@ -/* -** -** Copyright 2007, 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 "IAudioFlinger" -//#define LOG_NDEBUG 0 -#include <utils/Log.h> - -#include <stdint.h> -#include <sys/types.h> - -#include <binder/Parcel.h> - -#include <media/IAudioFlinger.h> - -namespace android { - -enum { - CREATE_TRACK = IBinder::FIRST_CALL_TRANSACTION, - OPEN_RECORD, - SAMPLE_RATE, - CHANNEL_COUNT, - FORMAT, - FRAME_COUNT, - LATENCY, - SET_MASTER_VOLUME, - SET_MASTER_MUTE, - MASTER_VOLUME, - MASTER_MUTE, - SET_STREAM_VOLUME, - SET_STREAM_MUTE, - STREAM_VOLUME, - STREAM_MUTE, - SET_MODE, - SET_MIC_MUTE, - GET_MIC_MUTE, - SET_PARAMETERS, - GET_PARAMETERS, - REGISTER_CLIENT, - GET_INPUTBUFFERSIZE, - OPEN_OUTPUT, - OPEN_DUPLICATE_OUTPUT, - CLOSE_OUTPUT, - SUSPEND_OUTPUT, - RESTORE_OUTPUT, - OPEN_INPUT, - CLOSE_INPUT, - SET_STREAM_OUTPUT, - SET_VOICE_VOLUME, - GET_RENDER_POSITION, - GET_INPUT_FRAMES_LOST, - NEW_AUDIO_SESSION_ID, - ACQUIRE_AUDIO_SESSION_ID, - RELEASE_AUDIO_SESSION_ID, - QUERY_NUM_EFFECTS, - QUERY_EFFECT, - GET_EFFECT_DESCRIPTOR, - CREATE_EFFECT, - MOVE_EFFECTS -}; - -class BpAudioFlinger : public BpInterface<IAudioFlinger> -{ -public: - BpAudioFlinger(const sp<IBinder>& impl) - : BpInterface<IAudioFlinger>(impl) - { - } - - virtual sp<IAudioTrack> createTrack( - pid_t pid, - audio_stream_type_t streamType, - uint32_t sampleRate, - audio_format_t format, - uint32_t channelMask, - int frameCount, - track_flags_t flags, - const sp<IMemory>& sharedBuffer, - audio_io_handle_t output, - int *sessionId, - status_t *status) - { - Parcel data, reply; - sp<IAudioTrack> track; - data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor()); - data.writeInt32(pid); - data.writeInt32((int32_t) streamType); - data.writeInt32(sampleRate); - data.writeInt32(format); - data.writeInt32(channelMask); - data.writeInt32(frameCount); - data.writeInt32((int32_t) flags); - data.writeStrongBinder(sharedBuffer->asBinder()); - data.writeInt32((int32_t) output); - int lSessionId = 0; - if (sessionId != NULL) { - lSessionId = *sessionId; - } - data.writeInt32(lSessionId); - status_t lStatus = remote()->transact(CREATE_TRACK, data, &reply); - if (lStatus != NO_ERROR) { - ALOGE("createTrack error: %s", strerror(-lStatus)); - } else { - lSessionId = reply.readInt32(); - if (sessionId != NULL) { - *sessionId = lSessionId; - } - lStatus = reply.readInt32(); - track = interface_cast<IAudioTrack>(reply.readStrongBinder()); - } - if (status) { - *status = lStatus; - } - return track; - } - - virtual sp<IAudioRecord> openRecord( - pid_t pid, - audio_io_handle_t input, - uint32_t sampleRate, - audio_format_t format, - uint32_t channelMask, - int frameCount, - track_flags_t flags, - int *sessionId, - status_t *status) - { - Parcel data, reply; - sp<IAudioRecord> record; - data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor()); - data.writeInt32(pid); - data.writeInt32((int32_t) input); - data.writeInt32(sampleRate); - data.writeInt32(format); - data.writeInt32(channelMask); - data.writeInt32(frameCount); - data.writeInt32(flags); - int lSessionId = 0; - if (sessionId != NULL) { - lSessionId = *sessionId; - } - data.writeInt32(lSessionId); - status_t lStatus = remote()->transact(OPEN_RECORD, data, &reply); - if (lStatus != NO_ERROR) { - ALOGE("openRecord error: %s", strerror(-lStatus)); - } else { - lSessionId = reply.readInt32(); - if (sessionId != NULL) { - *sessionId = lSessionId; - } - lStatus = reply.readInt32(); - record = interface_cast<IAudioRecord>(reply.readStrongBinder()); - } - if (status) { - *status = lStatus; - } - return record; - } - - virtual uint32_t sampleRate(audio_io_handle_t output) const - { - Parcel data, reply; - data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor()); - data.writeInt32((int32_t) output); - remote()->transact(SAMPLE_RATE, data, &reply); - return reply.readInt32(); - } - - virtual int channelCount(audio_io_handle_t output) const - { - Parcel data, reply; - data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor()); - data.writeInt32((int32_t) output); - remote()->transact(CHANNEL_COUNT, data, &reply); - return reply.readInt32(); - } - - virtual audio_format_t format(audio_io_handle_t output) const - { - Parcel data, reply; - data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor()); - data.writeInt32((int32_t) output); - remote()->transact(FORMAT, data, &reply); - return (audio_format_t) reply.readInt32(); - } - - virtual size_t frameCount(audio_io_handle_t output) const - { - Parcel data, reply; - data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor()); - data.writeInt32((int32_t) output); - remote()->transact(FRAME_COUNT, data, &reply); - return reply.readInt32(); - } - - virtual uint32_t latency(audio_io_handle_t output) const - { - Parcel data, reply; - data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor()); - data.writeInt32((int32_t) output); - remote()->transact(LATENCY, data, &reply); - return reply.readInt32(); - } - - virtual status_t setMasterVolume(float value) - { - Parcel data, reply; - data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor()); - data.writeFloat(value); - remote()->transact(SET_MASTER_VOLUME, data, &reply); - return reply.readInt32(); - } - - virtual status_t setMasterMute(bool muted) - { - Parcel data, reply; - data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor()); - data.writeInt32(muted); - remote()->transact(SET_MASTER_MUTE, data, &reply); - return reply.readInt32(); - } - - virtual float masterVolume() const - { - Parcel data, reply; - data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor()); - remote()->transact(MASTER_VOLUME, data, &reply); - return reply.readFloat(); - } - - virtual bool masterMute() const - { - Parcel data, reply; - data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor()); - remote()->transact(MASTER_MUTE, data, &reply); - return reply.readInt32(); - } - - virtual status_t setStreamVolume(audio_stream_type_t stream, float value, - audio_io_handle_t output) - { - Parcel data, reply; - data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor()); - data.writeInt32((int32_t) stream); - data.writeFloat(value); - data.writeInt32((int32_t) output); - remote()->transact(SET_STREAM_VOLUME, data, &reply); - return reply.readInt32(); - } - - virtual status_t setStreamMute(audio_stream_type_t stream, bool muted) - { - Parcel data, reply; - data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor()); - data.writeInt32((int32_t) stream); - data.writeInt32(muted); - remote()->transact(SET_STREAM_MUTE, data, &reply); - return reply.readInt32(); - } - - virtual float streamVolume(audio_stream_type_t stream, audio_io_handle_t output) const - { - Parcel data, reply; - data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor()); - data.writeInt32((int32_t) stream); - data.writeInt32((int32_t) output); - remote()->transact(STREAM_VOLUME, data, &reply); - return reply.readFloat(); - } - - virtual bool streamMute(audio_stream_type_t stream) const - { - Parcel data, reply; - data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor()); - data.writeInt32((int32_t) stream); - remote()->transact(STREAM_MUTE, data, &reply); - return reply.readInt32(); - } - - virtual status_t setMode(audio_mode_t mode) - { - Parcel data, reply; - data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor()); - data.writeInt32(mode); - remote()->transact(SET_MODE, data, &reply); - return reply.readInt32(); - } - - virtual status_t setMicMute(bool state) - { - Parcel data, reply; - data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor()); - data.writeInt32(state); - remote()->transact(SET_MIC_MUTE, data, &reply); - return reply.readInt32(); - } - - virtual bool getMicMute() const - { - Parcel data, reply; - data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor()); - remote()->transact(GET_MIC_MUTE, data, &reply); - return reply.readInt32(); - } - - virtual status_t setParameters(audio_io_handle_t ioHandle, const String8& keyValuePairs) - { - Parcel data, reply; - data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor()); - data.writeInt32((int32_t) ioHandle); - data.writeString8(keyValuePairs); - remote()->transact(SET_PARAMETERS, data, &reply); - return reply.readInt32(); - } - - virtual String8 getParameters(audio_io_handle_t ioHandle, const String8& keys) const - { - Parcel data, reply; - data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor()); - data.writeInt32((int32_t) ioHandle); - data.writeString8(keys); - remote()->transact(GET_PARAMETERS, data, &reply); - return reply.readString8(); - } - - virtual void registerClient(const sp<IAudioFlingerClient>& client) - { - Parcel data, reply; - data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor()); - data.writeStrongBinder(client->asBinder()); - remote()->transact(REGISTER_CLIENT, data, &reply); - } - - virtual size_t getInputBufferSize(uint32_t sampleRate, audio_format_t format, int channelCount) const - { - Parcel data, reply; - data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor()); - data.writeInt32(sampleRate); - data.writeInt32(format); - data.writeInt32(channelCount); - remote()->transact(GET_INPUTBUFFERSIZE, data, &reply); - return reply.readInt32(); - } - - virtual audio_io_handle_t openOutput(uint32_t *pDevices, - uint32_t *pSamplingRate, - audio_format_t *pFormat, - uint32_t *pChannels, - uint32_t *pLatencyMs, - audio_policy_output_flags_t flags) - { - Parcel data, reply; - uint32_t devices = pDevices ? *pDevices : 0; - uint32_t samplingRate = pSamplingRate ? *pSamplingRate : 0; - audio_format_t format = pFormat ? *pFormat : AUDIO_FORMAT_DEFAULT; - uint32_t channels = pChannels ? *pChannels : 0; - uint32_t latency = pLatencyMs ? *pLatencyMs : 0; - - data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor()); - data.writeInt32(devices); - data.writeInt32(samplingRate); - data.writeInt32(format); - data.writeInt32(channels); - data.writeInt32(latency); - data.writeInt32((int32_t) flags); - remote()->transact(OPEN_OUTPUT, data, &reply); - audio_io_handle_t output = (audio_io_handle_t) reply.readInt32(); - ALOGV("openOutput() returned output, %d", output); - devices = reply.readInt32(); - if (pDevices) *pDevices = devices; - samplingRate = reply.readInt32(); - if (pSamplingRate) *pSamplingRate = samplingRate; - format = (audio_format_t) reply.readInt32(); - if (pFormat) *pFormat = format; - channels = reply.readInt32(); - if (pChannels) *pChannels = channels; - latency = reply.readInt32(); - if (pLatencyMs) *pLatencyMs = latency; - return output; - } - - virtual audio_io_handle_t openDuplicateOutput(audio_io_handle_t output1, - audio_io_handle_t output2) - { - Parcel data, reply; - data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor()); - data.writeInt32((int32_t) output1); - data.writeInt32((int32_t) output2); - remote()->transact(OPEN_DUPLICATE_OUTPUT, data, &reply); - return (audio_io_handle_t) reply.readInt32(); - } - - virtual status_t closeOutput(audio_io_handle_t output) - { - Parcel data, reply; - data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor()); - data.writeInt32((int32_t) output); - remote()->transact(CLOSE_OUTPUT, data, &reply); - return reply.readInt32(); - } - - virtual status_t suspendOutput(audio_io_handle_t output) - { - Parcel data, reply; - data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor()); - data.writeInt32((int32_t) output); - remote()->transact(SUSPEND_OUTPUT, data, &reply); - return reply.readInt32(); - } - - virtual status_t restoreOutput(audio_io_handle_t output) - { - Parcel data, reply; - data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor()); - data.writeInt32((int32_t) output); - remote()->transact(RESTORE_OUTPUT, data, &reply); - return reply.readInt32(); - } - - virtual audio_io_handle_t openInput(uint32_t *pDevices, - uint32_t *pSamplingRate, - audio_format_t *pFormat, - uint32_t *pChannels, - audio_in_acoustics_t acoustics) - { - Parcel data, reply; - uint32_t devices = pDevices ? *pDevices : 0; - uint32_t samplingRate = pSamplingRate ? *pSamplingRate : 0; - audio_format_t format = pFormat ? *pFormat : AUDIO_FORMAT_DEFAULT; - uint32_t channels = pChannels ? *pChannels : 0; - - data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor()); - data.writeInt32(devices); - data.writeInt32(samplingRate); - data.writeInt32(format); - data.writeInt32(channels); - data.writeInt32((int32_t) acoustics); - remote()->transact(OPEN_INPUT, data, &reply); - audio_io_handle_t input = (audio_io_handle_t) reply.readInt32(); - devices = reply.readInt32(); - if (pDevices) *pDevices = devices; - samplingRate = reply.readInt32(); - if (pSamplingRate) *pSamplingRate = samplingRate; - format = (audio_format_t) reply.readInt32(); - if (pFormat) *pFormat = format; - channels = reply.readInt32(); - if (pChannels) *pChannels = channels; - return input; - } - - virtual status_t closeInput(int input) - { - Parcel data, reply; - data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor()); - data.writeInt32(input); - remote()->transact(CLOSE_INPUT, data, &reply); - return reply.readInt32(); - } - - virtual status_t setStreamOutput(audio_stream_type_t stream, audio_io_handle_t output) - { - Parcel data, reply; - data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor()); - data.writeInt32((int32_t) stream); - data.writeInt32((int32_t) output); - 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(); - } - - virtual status_t getRenderPosition(uint32_t *halFrames, uint32_t *dspFrames, - audio_io_handle_t output) const - { - Parcel data, reply; - data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor()); - data.writeInt32((int32_t) output); - remote()->transact(GET_RENDER_POSITION, data, &reply); - status_t status = reply.readInt32(); - if (status == NO_ERROR) { - uint32_t tmp = reply.readInt32(); - if (halFrames) { - *halFrames = tmp; - } - tmp = reply.readInt32(); - if (dspFrames) { - *dspFrames = tmp; - } - } - return status; - } - - virtual unsigned int getInputFramesLost(audio_io_handle_t ioHandle) const - { - Parcel data, reply; - data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor()); - data.writeInt32((int32_t) ioHandle); - remote()->transact(GET_INPUT_FRAMES_LOST, data, &reply); - return reply.readInt32(); - } - - virtual int newAudioSessionId() - { - Parcel data, reply; - data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor()); - status_t status = remote()->transact(NEW_AUDIO_SESSION_ID, data, &reply); - int id = 0; - if (status == NO_ERROR) { - id = reply.readInt32(); - } - return id; - } - - virtual void acquireAudioSessionId(int audioSession) - { - Parcel data, reply; - data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor()); - data.writeInt32(audioSession); - remote()->transact(ACQUIRE_AUDIO_SESSION_ID, data, &reply); - } - - virtual void releaseAudioSessionId(int audioSession) - { - Parcel data, reply; - data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor()); - data.writeInt32(audioSession); - remote()->transact(RELEASE_AUDIO_SESSION_ID, data, &reply); - } - - virtual status_t queryNumberEffects(uint32_t *numEffects) const - { - Parcel data, reply; - data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor()); - status_t status = remote()->transact(QUERY_NUM_EFFECTS, data, &reply); - if (status != NO_ERROR) { - return status; - } - status = reply.readInt32(); - if (status != NO_ERROR) { - return status; - } - if (numEffects != NULL) { - *numEffects = (uint32_t)reply.readInt32(); - } - return NO_ERROR; - } - - virtual status_t queryEffect(uint32_t index, effect_descriptor_t *pDescriptor) const - { - if (pDescriptor == NULL) { - return BAD_VALUE; - } - Parcel data, reply; - data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor()); - data.writeInt32(index); - status_t status = remote()->transact(QUERY_EFFECT, data, &reply); - if (status != NO_ERROR) { - return status; - } - status = reply.readInt32(); - if (status != NO_ERROR) { - return status; - } - reply.read(pDescriptor, sizeof(effect_descriptor_t)); - return NO_ERROR; - } - - virtual status_t getEffectDescriptor(const effect_uuid_t *pUuid, - effect_descriptor_t *pDescriptor) const - { - if (pUuid == NULL || pDescriptor == NULL) { - return BAD_VALUE; - } - Parcel data, reply; - data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor()); - data.write(pUuid, sizeof(effect_uuid_t)); - status_t status = remote()->transact(GET_EFFECT_DESCRIPTOR, data, &reply); - if (status != NO_ERROR) { - return status; - } - status = reply.readInt32(); - if (status != NO_ERROR) { - return status; - } - reply.read(pDescriptor, sizeof(effect_descriptor_t)); - return NO_ERROR; - } - - virtual sp<IEffect> createEffect(pid_t pid, - effect_descriptor_t *pDesc, - const sp<IEffectClient>& client, - int32_t priority, - audio_io_handle_t output, - int sessionId, - status_t *status, - int *id, - int *enabled) - { - Parcel data, reply; - sp<IEffect> effect; - - if (pDesc == NULL) { - return effect; - if (status) { - *status = BAD_VALUE; - } - } - - data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor()); - data.writeInt32(pid); - data.write(pDesc, sizeof(effect_descriptor_t)); - data.writeStrongBinder(client->asBinder()); - data.writeInt32(priority); - data.writeInt32((int32_t) output); - data.writeInt32(sessionId); - - status_t lStatus = remote()->transact(CREATE_EFFECT, data, &reply); - if (lStatus != NO_ERROR) { - ALOGE("createEffect error: %s", strerror(-lStatus)); - } else { - lStatus = reply.readInt32(); - int tmp = reply.readInt32(); - if (id) { - *id = tmp; - } - tmp = reply.readInt32(); - if (enabled != NULL) { - *enabled = tmp; - } - effect = interface_cast<IEffect>(reply.readStrongBinder()); - reply.read(pDesc, sizeof(effect_descriptor_t)); - } - if (status) { - *status = lStatus; - } - - return effect; - } - - virtual status_t moveEffects(int session, audio_io_handle_t srcOutput, - audio_io_handle_t dstOutput) - { - Parcel data, reply; - data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor()); - data.writeInt32(session); - data.writeInt32((int32_t) srcOutput); - data.writeInt32((int32_t) dstOutput); - remote()->transact(MOVE_EFFECTS, data, &reply); - return reply.readInt32(); - } -}; - -IMPLEMENT_META_INTERFACE(AudioFlinger, "android.media.IAudioFlinger"); - -// ---------------------------------------------------------------------- - -status_t BnAudioFlinger::onTransact( - uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) -{ - switch (code) { - case CREATE_TRACK: { - CHECK_INTERFACE(IAudioFlinger, data, reply); - pid_t pid = data.readInt32(); - int streamType = data.readInt32(); - uint32_t sampleRate = data.readInt32(); - audio_format_t format = (audio_format_t) data.readInt32(); - int channelCount = data.readInt32(); - size_t bufferCount = data.readInt32(); - track_flags_t flags = (track_flags_t) data.readInt32(); - sp<IMemory> buffer = interface_cast<IMemory>(data.readStrongBinder()); - audio_io_handle_t output = (audio_io_handle_t) data.readInt32(); - int sessionId = data.readInt32(); - status_t status; - sp<IAudioTrack> track = createTrack(pid, - (audio_stream_type_t) streamType, sampleRate, format, - channelCount, bufferCount, flags, buffer, output, &sessionId, &status); - reply->writeInt32(sessionId); - reply->writeInt32(status); - reply->writeStrongBinder(track->asBinder()); - return NO_ERROR; - } break; - case OPEN_RECORD: { - CHECK_INTERFACE(IAudioFlinger, data, reply); - pid_t pid = data.readInt32(); - audio_io_handle_t input = (audio_io_handle_t) data.readInt32(); - uint32_t sampleRate = data.readInt32(); - audio_format_t format = (audio_format_t) data.readInt32(); - int channelCount = data.readInt32(); - size_t bufferCount = data.readInt32(); - track_flags_t flags = (track_flags_t) data.readInt32(); - int sessionId = data.readInt32(); - status_t status; - sp<IAudioRecord> record = openRecord(pid, input, - sampleRate, format, channelCount, bufferCount, flags, &sessionId, &status); - reply->writeInt32(sessionId); - reply->writeInt32(status); - reply->writeStrongBinder(record->asBinder()); - return NO_ERROR; - } break; - case SAMPLE_RATE: { - CHECK_INTERFACE(IAudioFlinger, data, reply); - reply->writeInt32( sampleRate((audio_io_handle_t) data.readInt32()) ); - return NO_ERROR; - } break; - case CHANNEL_COUNT: { - CHECK_INTERFACE(IAudioFlinger, data, reply); - reply->writeInt32( channelCount((audio_io_handle_t) data.readInt32()) ); - return NO_ERROR; - } break; - case FORMAT: { - CHECK_INTERFACE(IAudioFlinger, data, reply); - reply->writeInt32( format((audio_io_handle_t) data.readInt32()) ); - return NO_ERROR; - } break; - case FRAME_COUNT: { - CHECK_INTERFACE(IAudioFlinger, data, reply); - reply->writeInt32( frameCount((audio_io_handle_t) data.readInt32()) ); - return NO_ERROR; - } break; - case LATENCY: { - CHECK_INTERFACE(IAudioFlinger, data, reply); - reply->writeInt32( latency((audio_io_handle_t) data.readInt32()) ); - return NO_ERROR; - } break; - case SET_MASTER_VOLUME: { - CHECK_INTERFACE(IAudioFlinger, data, reply); - reply->writeInt32( setMasterVolume(data.readFloat()) ); - return NO_ERROR; - } break; - case SET_MASTER_MUTE: { - CHECK_INTERFACE(IAudioFlinger, data, reply); - reply->writeInt32( setMasterMute(data.readInt32()) ); - return NO_ERROR; - } break; - case MASTER_VOLUME: { - CHECK_INTERFACE(IAudioFlinger, data, reply); - reply->writeFloat( masterVolume() ); - return NO_ERROR; - } break; - case MASTER_MUTE: { - CHECK_INTERFACE(IAudioFlinger, data, reply); - reply->writeInt32( masterMute() ); - return NO_ERROR; - } break; - case SET_STREAM_VOLUME: { - CHECK_INTERFACE(IAudioFlinger, data, reply); - int stream = data.readInt32(); - float volume = data.readFloat(); - audio_io_handle_t output = (audio_io_handle_t) data.readInt32(); - reply->writeInt32( setStreamVolume((audio_stream_type_t) stream, volume, output) ); - return NO_ERROR; - } break; - case SET_STREAM_MUTE: { - CHECK_INTERFACE(IAudioFlinger, data, reply); - int stream = data.readInt32(); - reply->writeInt32( setStreamMute((audio_stream_type_t) stream, data.readInt32()) ); - return NO_ERROR; - } break; - case STREAM_VOLUME: { - CHECK_INTERFACE(IAudioFlinger, data, reply); - int stream = data.readInt32(); - int output = data.readInt32(); - reply->writeFloat( streamVolume((audio_stream_type_t) stream, output) ); - return NO_ERROR; - } break; - case STREAM_MUTE: { - CHECK_INTERFACE(IAudioFlinger, data, reply); - int stream = data.readInt32(); - reply->writeInt32( streamMute((audio_stream_type_t) stream) ); - return NO_ERROR; - } break; - case SET_MODE: { - CHECK_INTERFACE(IAudioFlinger, data, reply); - audio_mode_t mode = (audio_mode_t) data.readInt32(); - reply->writeInt32( setMode(mode) ); - return NO_ERROR; - } break; - case SET_MIC_MUTE: { - CHECK_INTERFACE(IAudioFlinger, data, reply); - int state = data.readInt32(); - reply->writeInt32( setMicMute(state) ); - return NO_ERROR; - } break; - case GET_MIC_MUTE: { - CHECK_INTERFACE(IAudioFlinger, data, reply); - reply->writeInt32( getMicMute() ); - return NO_ERROR; - } break; - case SET_PARAMETERS: { - CHECK_INTERFACE(IAudioFlinger, data, reply); - audio_io_handle_t ioHandle = (audio_io_handle_t) data.readInt32(); - String8 keyValuePairs(data.readString8()); - reply->writeInt32(setParameters(ioHandle, keyValuePairs)); - return NO_ERROR; - } break; - case GET_PARAMETERS: { - CHECK_INTERFACE(IAudioFlinger, data, reply); - audio_io_handle_t ioHandle = (audio_io_handle_t) data.readInt32(); - String8 keys(data.readString8()); - reply->writeString8(getParameters(ioHandle, keys)); - return NO_ERROR; - } break; - - case REGISTER_CLIENT: { - CHECK_INTERFACE(IAudioFlinger, data, reply); - sp<IAudioFlingerClient> client = interface_cast<IAudioFlingerClient>(data.readStrongBinder()); - registerClient(client); - return NO_ERROR; - } break; - case GET_INPUTBUFFERSIZE: { - CHECK_INTERFACE(IAudioFlinger, data, reply); - uint32_t sampleRate = data.readInt32(); - audio_format_t format = (audio_format_t) data.readInt32(); - int channelCount = data.readInt32(); - reply->writeInt32( getInputBufferSize(sampleRate, format, channelCount) ); - return NO_ERROR; - } break; - case OPEN_OUTPUT: { - CHECK_INTERFACE(IAudioFlinger, data, reply); - uint32_t devices = data.readInt32(); - uint32_t samplingRate = data.readInt32(); - audio_format_t format = (audio_format_t) data.readInt32(); - uint32_t channels = data.readInt32(); - uint32_t latency = data.readInt32(); - audio_policy_output_flags_t flags = (audio_policy_output_flags_t) data.readInt32(); - audio_io_handle_t output = openOutput(&devices, - &samplingRate, - &format, - &channels, - &latency, - flags); - ALOGV("OPEN_OUTPUT output, %p", output); - reply->writeInt32((int32_t) output); - reply->writeInt32(devices); - reply->writeInt32(samplingRate); - reply->writeInt32(format); - reply->writeInt32(channels); - reply->writeInt32(latency); - return NO_ERROR; - } break; - case OPEN_DUPLICATE_OUTPUT: { - CHECK_INTERFACE(IAudioFlinger, data, reply); - audio_io_handle_t output1 = (audio_io_handle_t) data.readInt32(); - audio_io_handle_t output2 = (audio_io_handle_t) data.readInt32(); - reply->writeInt32((int32_t) openDuplicateOutput(output1, output2)); - return NO_ERROR; - } break; - case CLOSE_OUTPUT: { - CHECK_INTERFACE(IAudioFlinger, data, reply); - reply->writeInt32(closeOutput((audio_io_handle_t) data.readInt32())); - return NO_ERROR; - } break; - case SUSPEND_OUTPUT: { - CHECK_INTERFACE(IAudioFlinger, data, reply); - reply->writeInt32(suspendOutput((audio_io_handle_t) data.readInt32())); - return NO_ERROR; - } break; - case RESTORE_OUTPUT: { - CHECK_INTERFACE(IAudioFlinger, data, reply); - reply->writeInt32(restoreOutput((audio_io_handle_t) data.readInt32())); - return NO_ERROR; - } break; - case OPEN_INPUT: { - CHECK_INTERFACE(IAudioFlinger, data, reply); - uint32_t devices = data.readInt32(); - uint32_t samplingRate = data.readInt32(); - audio_format_t format = (audio_format_t) data.readInt32(); - uint32_t channels = data.readInt32(); - audio_in_acoustics_t acoustics = (audio_in_acoustics_t) data.readInt32(); - - audio_io_handle_t input = openInput(&devices, - &samplingRate, - &format, - &channels, - acoustics); - reply->writeInt32((int32_t) input); - reply->writeInt32(devices); - reply->writeInt32(samplingRate); - reply->writeInt32(format); - reply->writeInt32(channels); - return NO_ERROR; - } break; - case CLOSE_INPUT: { - CHECK_INTERFACE(IAudioFlinger, data, reply); - reply->writeInt32(closeInput((audio_io_handle_t) data.readInt32())); - return NO_ERROR; - } break; - case SET_STREAM_OUTPUT: { - CHECK_INTERFACE(IAudioFlinger, data, reply); - uint32_t stream = data.readInt32(); - audio_io_handle_t output = (audio_io_handle_t) data.readInt32(); - reply->writeInt32(setStreamOutput((audio_stream_type_t) 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; - case GET_RENDER_POSITION: { - CHECK_INTERFACE(IAudioFlinger, data, reply); - audio_io_handle_t output = (audio_io_handle_t) data.readInt32(); - uint32_t halFrames; - uint32_t dspFrames; - status_t status = getRenderPosition(&halFrames, &dspFrames, output); - reply->writeInt32(status); - if (status == NO_ERROR) { - reply->writeInt32(halFrames); - reply->writeInt32(dspFrames); - } - return NO_ERROR; - } - case GET_INPUT_FRAMES_LOST: { - CHECK_INTERFACE(IAudioFlinger, data, reply); - audio_io_handle_t ioHandle = (audio_io_handle_t) data.readInt32(); - reply->writeInt32(getInputFramesLost(ioHandle)); - return NO_ERROR; - } break; - case NEW_AUDIO_SESSION_ID: { - CHECK_INTERFACE(IAudioFlinger, data, reply); - reply->writeInt32(newAudioSessionId()); - return NO_ERROR; - } break; - case ACQUIRE_AUDIO_SESSION_ID: { - CHECK_INTERFACE(IAudioFlinger, data, reply); - int audioSession = data.readInt32(); - acquireAudioSessionId(audioSession); - return NO_ERROR; - } break; - case RELEASE_AUDIO_SESSION_ID: { - CHECK_INTERFACE(IAudioFlinger, data, reply); - int audioSession = data.readInt32(); - releaseAudioSessionId(audioSession); - return NO_ERROR; - } break; - case QUERY_NUM_EFFECTS: { - CHECK_INTERFACE(IAudioFlinger, data, reply); - uint32_t numEffects; - status_t status = queryNumberEffects(&numEffects); - reply->writeInt32(status); - if (status == NO_ERROR) { - reply->writeInt32((int32_t)numEffects); - } - return NO_ERROR; - } - case QUERY_EFFECT: { - CHECK_INTERFACE(IAudioFlinger, data, reply); - effect_descriptor_t desc; - status_t status = queryEffect(data.readInt32(), &desc); - reply->writeInt32(status); - if (status == NO_ERROR) { - reply->write(&desc, sizeof(effect_descriptor_t)); - } - return NO_ERROR; - } - case GET_EFFECT_DESCRIPTOR: { - CHECK_INTERFACE(IAudioFlinger, data, reply); - effect_uuid_t uuid; - data.read(&uuid, sizeof(effect_uuid_t)); - effect_descriptor_t desc; - status_t status = getEffectDescriptor(&uuid, &desc); - reply->writeInt32(status); - if (status == NO_ERROR) { - reply->write(&desc, sizeof(effect_descriptor_t)); - } - return NO_ERROR; - } - case CREATE_EFFECT: { - CHECK_INTERFACE(IAudioFlinger, data, reply); - pid_t pid = data.readInt32(); - effect_descriptor_t desc; - data.read(&desc, sizeof(effect_descriptor_t)); - sp<IEffectClient> client = interface_cast<IEffectClient>(data.readStrongBinder()); - int32_t priority = data.readInt32(); - audio_io_handle_t output = (audio_io_handle_t) data.readInt32(); - int sessionId = data.readInt32(); - status_t status; - int id; - int enabled; - - sp<IEffect> effect = createEffect(pid, &desc, client, priority, output, sessionId, &status, &id, &enabled); - reply->writeInt32(status); - reply->writeInt32(id); - reply->writeInt32(enabled); - reply->writeStrongBinder(effect->asBinder()); - reply->write(&desc, sizeof(effect_descriptor_t)); - return NO_ERROR; - } break; - case MOVE_EFFECTS: { - CHECK_INTERFACE(IAudioFlinger, data, reply); - int session = data.readInt32(); - audio_io_handle_t srcOutput = (audio_io_handle_t) data.readInt32(); - audio_io_handle_t dstOutput = (audio_io_handle_t) data.readInt32(); - reply->writeInt32(moveEffects(session, srcOutput, dstOutput)); - return NO_ERROR; - } break; - default: - return BBinder::onTransact(code, data, reply, flags); - } -} - -// ---------------------------------------------------------------------------- - -}; // namespace android diff --git a/media/libmedia/IAudioFlingerClient.cpp b/media/libmedia/IAudioFlingerClient.cpp deleted file mode 100644 index 4178b29..0000000 --- a/media/libmedia/IAudioFlingerClient.cpp +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Copyright (C) 2009 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 "IAudioFlingerClient" -#include <utils/Log.h> - -#include <stdint.h> -#include <sys/types.h> - -#include <binder/Parcel.h> - -#include <media/IAudioFlingerClient.h> -#include <media/AudioSystem.h> - -namespace android { - -enum { - IO_CONFIG_CHANGED = IBinder::FIRST_CALL_TRANSACTION -}; - -class BpAudioFlingerClient : public BpInterface<IAudioFlingerClient> -{ -public: - BpAudioFlingerClient(const sp<IBinder>& impl) - : BpInterface<IAudioFlingerClient>(impl) - { - } - - void ioConfigChanged(int event, audio_io_handle_t ioHandle, const void *param2) - { - Parcel data, reply; - data.writeInterfaceToken(IAudioFlingerClient::getInterfaceDescriptor()); - data.writeInt32(event); - data.writeInt32((int32_t) ioHandle); - if (event == AudioSystem::STREAM_CONFIG_CHANGED) { - uint32_t stream = *(const uint32_t *)param2; - ALOGV("ioConfigChanged stream %d", stream); - data.writeInt32(stream); - } else if (event != AudioSystem::OUTPUT_CLOSED && event != AudioSystem::INPUT_CLOSED) { - const AudioSystem::OutputDescriptor *desc = (const AudioSystem::OutputDescriptor *)param2; - data.writeInt32(desc->samplingRate); - data.writeInt32(desc->format); - data.writeInt32(desc->channels); - data.writeInt32(desc->frameCount); - data.writeInt32(desc->latency); - } - remote()->transact(IO_CONFIG_CHANGED, data, &reply, IBinder::FLAG_ONEWAY); - } -}; - -IMPLEMENT_META_INTERFACE(AudioFlingerClient, "android.media.IAudioFlingerClient"); - -// ---------------------------------------------------------------------- - -status_t BnAudioFlingerClient::onTransact( - uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) -{ - switch (code) { - case IO_CONFIG_CHANGED: { - CHECK_INTERFACE(IAudioFlingerClient, data, reply); - int event = data.readInt32(); - audio_io_handle_t ioHandle = (audio_io_handle_t) data.readInt32(); - const void *param2 = NULL; - AudioSystem::OutputDescriptor desc; - uint32_t stream; - if (event == AudioSystem::STREAM_CONFIG_CHANGED) { - stream = data.readInt32(); - param2 = &stream; - ALOGV("STREAM_CONFIG_CHANGED stream %d", stream); - } else if (event != AudioSystem::OUTPUT_CLOSED && event != AudioSystem::INPUT_CLOSED) { - desc.samplingRate = data.readInt32(); - desc.format = data.readInt32(); - desc.channels = data.readInt32(); - desc.frameCount = data.readInt32(); - desc.latency = data.readInt32(); - param2 = &desc; - } - ioConfigChanged(event, ioHandle, param2); - return NO_ERROR; - } break; - default: - return BBinder::onTransact(code, data, reply, flags); - } -} - -// ---------------------------------------------------------------------------- - -}; // namespace android diff --git a/media/libmedia/IAudioPolicyService.cpp b/media/libmedia/IAudioPolicyService.cpp deleted file mode 100644 index 5040bd9..0000000 --- a/media/libmedia/IAudioPolicyService.cpp +++ /dev/null @@ -1,630 +0,0 @@ -/* -** -** Copyright 2009, 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 "IAudioPolicyService" -#include <utils/Log.h> - -#include <stdint.h> -#include <sys/types.h> - -#include <binder/Parcel.h> - -#include <media/IAudioPolicyService.h> - -#include <system/audio.h> - -namespace android { - -enum { - SET_DEVICE_CONNECTION_STATE = IBinder::FIRST_CALL_TRANSACTION, - GET_DEVICE_CONNECTION_STATE, - SET_PHONE_STATE, - SET_RINGER_MODE, // reserved, no longer used - SET_FORCE_USE, - GET_FORCE_USE, - GET_OUTPUT, - START_OUTPUT, - STOP_OUTPUT, - RELEASE_OUTPUT, - GET_INPUT, - START_INPUT, - STOP_INPUT, - RELEASE_INPUT, - INIT_STREAM_VOLUME, - SET_STREAM_VOLUME, - GET_STREAM_VOLUME, - GET_STRATEGY_FOR_STREAM, - GET_OUTPUT_FOR_EFFECT, - REGISTER_EFFECT, - UNREGISTER_EFFECT, - IS_STREAM_ACTIVE, - GET_DEVICES_FOR_STREAM, - QUERY_DEFAULT_PRE_PROCESSING, - SET_EFFECT_ENABLED -}; - -class BpAudioPolicyService : public BpInterface<IAudioPolicyService> -{ -public: - BpAudioPolicyService(const sp<IBinder>& impl) - : BpInterface<IAudioPolicyService>(impl) - { - } - - virtual status_t setDeviceConnectionState( - audio_devices_t device, - audio_policy_dev_state_t state, - const char *device_address) - { - Parcel data, reply; - data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor()); - data.writeInt32(static_cast <uint32_t>(device)); - data.writeInt32(static_cast <uint32_t>(state)); - data.writeCString(device_address); - remote()->transact(SET_DEVICE_CONNECTION_STATE, data, &reply); - return static_cast <status_t> (reply.readInt32()); - } - - virtual audio_policy_dev_state_t getDeviceConnectionState( - audio_devices_t device, - const char *device_address) - { - Parcel data, reply; - data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor()); - data.writeInt32(static_cast <uint32_t>(device)); - data.writeCString(device_address); - remote()->transact(GET_DEVICE_CONNECTION_STATE, data, &reply); - return static_cast <audio_policy_dev_state_t>(reply.readInt32()); - } - - virtual status_t setPhoneState(audio_mode_t state) - { - Parcel data, reply; - data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor()); - data.writeInt32(state); - remote()->transact(SET_PHONE_STATE, data, &reply); - return static_cast <status_t> (reply.readInt32()); - } - - virtual status_t setForceUse(audio_policy_force_use_t usage, audio_policy_forced_cfg_t config) - { - Parcel data, reply; - data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor()); - data.writeInt32(static_cast <uint32_t>(usage)); - data.writeInt32(static_cast <uint32_t>(config)); - remote()->transact(SET_FORCE_USE, data, &reply); - return static_cast <status_t> (reply.readInt32()); - } - - 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 <audio_policy_forced_cfg_t> (reply.readInt32()); - } - - virtual audio_io_handle_t getOutput( - audio_stream_type_t stream, - uint32_t samplingRate, - audio_format_t format, - uint32_t channels, - audio_policy_output_flags_t flags) - { - Parcel data, reply; - data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor()); - data.writeInt32(static_cast <uint32_t>(stream)); - data.writeInt32(samplingRate); - data.writeInt32(static_cast <uint32_t>(format)); - data.writeInt32(channels); - data.writeInt32(static_cast <uint32_t>(flags)); - remote()->transact(GET_OUTPUT, data, &reply); - return static_cast <audio_io_handle_t> (reply.readInt32()); - } - - virtual status_t startOutput(audio_io_handle_t output, - audio_stream_type_t stream, - int session) - { - Parcel data, reply; - data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor()); - data.writeInt32(output); - data.writeInt32((int32_t) stream); - data.writeInt32(session); - remote()->transact(START_OUTPUT, data, &reply); - return static_cast <status_t> (reply.readInt32()); - } - - virtual status_t stopOutput(audio_io_handle_t output, - audio_stream_type_t stream, - int session) - { - Parcel data, reply; - data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor()); - data.writeInt32(output); - data.writeInt32((int32_t) stream); - data.writeInt32(session); - remote()->transact(STOP_OUTPUT, data, &reply); - return static_cast <status_t> (reply.readInt32()); - } - - virtual void releaseOutput(audio_io_handle_t output) - { - Parcel data, reply; - data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor()); - data.writeInt32(output); - remote()->transact(RELEASE_OUTPUT, data, &reply); - } - - virtual audio_io_handle_t getInput( - audio_source_t inputSource, - uint32_t samplingRate, - audio_format_t format, - uint32_t channels, - audio_in_acoustics_t acoustics, - int audioSession) - { - Parcel data, reply; - data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor()); - data.writeInt32((int32_t) inputSource); - data.writeInt32(samplingRate); - data.writeInt32(static_cast <uint32_t>(format)); - data.writeInt32(channels); - data.writeInt32(static_cast <uint32_t>(acoustics)); - data.writeInt32(audioSession); - remote()->transact(GET_INPUT, data, &reply); - return static_cast <audio_io_handle_t> (reply.readInt32()); - } - - virtual status_t startInput(audio_io_handle_t input) - { - Parcel data, reply; - data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor()); - data.writeInt32(input); - remote()->transact(START_INPUT, data, &reply); - return static_cast <status_t> (reply.readInt32()); - } - - virtual status_t stopInput(audio_io_handle_t input) - { - Parcel data, reply; - data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor()); - data.writeInt32(input); - remote()->transact(STOP_INPUT, data, &reply); - return static_cast <status_t> (reply.readInt32()); - } - - virtual void releaseInput(audio_io_handle_t input) - { - Parcel data, reply; - data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor()); - data.writeInt32(input); - remote()->transact(RELEASE_INPUT, data, &reply); - } - - virtual status_t initStreamVolume(audio_stream_type_t stream, - int indexMin, - int indexMax) - { - Parcel data, reply; - data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor()); - data.writeInt32(static_cast <uint32_t>(stream)); - data.writeInt32(indexMin); - data.writeInt32(indexMax); - remote()->transact(INIT_STREAM_VOLUME, data, &reply); - return static_cast <status_t> (reply.readInt32()); - } - - virtual status_t setStreamVolumeIndex(audio_stream_type_t stream, - int index, - audio_devices_t device) - { - Parcel data, reply; - data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor()); - data.writeInt32(static_cast <uint32_t>(stream)); - data.writeInt32(index); - data.writeInt32(static_cast <uint32_t>(device)); - remote()->transact(SET_STREAM_VOLUME, data, &reply); - return static_cast <status_t> (reply.readInt32()); - } - - virtual status_t getStreamVolumeIndex(audio_stream_type_t stream, - int *index, - audio_devices_t device) - { - Parcel data, reply; - data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor()); - data.writeInt32(static_cast <uint32_t>(stream)); - data.writeInt32(static_cast <uint32_t>(device)); - - remote()->transact(GET_STREAM_VOLUME, data, &reply); - int lIndex = reply.readInt32(); - if (index) *index = lIndex; - return static_cast <status_t> (reply.readInt32()); - } - - virtual uint32_t getStrategyForStream(audio_stream_type_t stream) - { - Parcel data, reply; - data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor()); - data.writeInt32(static_cast <uint32_t>(stream)); - remote()->transact(GET_STRATEGY_FOR_STREAM, data, &reply); - return reply.readInt32(); - } - - virtual audio_devices_t getDevicesForStream(audio_stream_type_t stream) - { - Parcel data, reply; - data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor()); - data.writeInt32(static_cast <uint32_t>(stream)); - remote()->transact(GET_DEVICES_FOR_STREAM, data, &reply); - return (audio_devices_t) reply.readInt32(); - } - - virtual audio_io_handle_t getOutputForEffect(effect_descriptor_t *desc) - { - Parcel data, reply; - data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor()); - data.write(desc, sizeof(effect_descriptor_t)); - remote()->transact(GET_OUTPUT_FOR_EFFECT, data, &reply); - return static_cast <audio_io_handle_t> (reply.readInt32()); - } - - virtual status_t registerEffect(effect_descriptor_t *desc, - audio_io_handle_t io, - uint32_t strategy, - int session, - int id) - { - Parcel data, reply; - data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor()); - data.write(desc, sizeof(effect_descriptor_t)); - data.writeInt32(io); - data.writeInt32(strategy); - data.writeInt32(session); - data.writeInt32(id); - remote()->transact(REGISTER_EFFECT, data, &reply); - return static_cast <status_t> (reply.readInt32()); - } - - virtual status_t unregisterEffect(int id) - { - Parcel data, reply; - data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor()); - data.writeInt32(id); - remote()->transact(UNREGISTER_EFFECT, data, &reply); - return static_cast <status_t> (reply.readInt32()); - } - - virtual status_t setEffectEnabled(int id, bool enabled) - { - Parcel data, reply; - data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor()); - data.writeInt32(id); - data.writeInt32(enabled); - remote()->transact(SET_EFFECT_ENABLED, data, &reply); - return static_cast <status_t> (reply.readInt32()); - } - - virtual bool isStreamActive(audio_stream_type_t stream, uint32_t inPastMs) const - { - Parcel data, reply; - data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor()); - data.writeInt32((int32_t) stream); - data.writeInt32(inPastMs); - remote()->transact(IS_STREAM_ACTIVE, data, &reply); - return reply.readInt32(); - } - - virtual status_t queryDefaultPreProcessing(int audioSession, - effect_descriptor_t *descriptors, - uint32_t *count) - { - if (descriptors == NULL || count == NULL) { - return BAD_VALUE; - } - Parcel data, reply; - data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor()); - data.writeInt32(audioSession); - data.writeInt32(*count); - status_t status = remote()->transact(QUERY_DEFAULT_PRE_PROCESSING, data, &reply); - if (status != NO_ERROR) { - return status; - } - status = static_cast <status_t> (reply.readInt32()); - uint32_t retCount = reply.readInt32(); - if (retCount != 0) { - uint32_t numDesc = (retCount < *count) ? retCount : *count; - reply.read(descriptors, sizeof(effect_descriptor_t) * numDesc); - } - *count = retCount; - return status; - } -}; - -IMPLEMENT_META_INTERFACE(AudioPolicyService, "android.media.IAudioPolicyService"); - -// ---------------------------------------------------------------------- - - -status_t BnAudioPolicyService::onTransact( - uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) -{ - switch (code) { - case SET_DEVICE_CONNECTION_STATE: { - CHECK_INTERFACE(IAudioPolicyService, data, reply); - 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, - device_address))); - return NO_ERROR; - } break; - - case GET_DEVICE_CONNECTION_STATE: { - CHECK_INTERFACE(IAudioPolicyService, data, reply); - 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))); - return NO_ERROR; - } break; - - case SET_PHONE_STATE: { - CHECK_INTERFACE(IAudioPolicyService, data, reply); - reply->writeInt32(static_cast <uint32_t>(setPhoneState((audio_mode_t) data.readInt32()))); - return NO_ERROR; - } break; - - case SET_FORCE_USE: { - CHECK_INTERFACE(IAudioPolicyService, data, reply); - 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); - 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); - audio_stream_type_t stream = - static_cast <audio_stream_type_t>(data.readInt32()); - uint32_t samplingRate = data.readInt32(); - audio_format_t format = (audio_format_t) data.readInt32(); - uint32_t channels = 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, - format, - channels, - flags); - reply->writeInt32(static_cast <int>(output)); - return NO_ERROR; - } break; - - case START_OUTPUT: { - CHECK_INTERFACE(IAudioPolicyService, data, reply); - audio_io_handle_t output = static_cast <audio_io_handle_t>(data.readInt32()); - uint32_t stream = data.readInt32(); - int session = data.readInt32(); - reply->writeInt32(static_cast <uint32_t>(startOutput(output, - (audio_stream_type_t)stream, - session))); - return NO_ERROR; - } break; - - case STOP_OUTPUT: { - CHECK_INTERFACE(IAudioPolicyService, data, reply); - audio_io_handle_t output = static_cast <audio_io_handle_t>(data.readInt32()); - uint32_t stream = data.readInt32(); - int session = data.readInt32(); - reply->writeInt32(static_cast <uint32_t>(stopOutput(output, - (audio_stream_type_t)stream, - session))); - return NO_ERROR; - } break; - - case RELEASE_OUTPUT: { - CHECK_INTERFACE(IAudioPolicyService, data, reply); - audio_io_handle_t output = static_cast <audio_io_handle_t>(data.readInt32()); - releaseOutput(output); - return NO_ERROR; - } break; - - case GET_INPUT: { - CHECK_INTERFACE(IAudioPolicyService, data, reply); - audio_source_t inputSource = (audio_source_t) data.readInt32(); - uint32_t samplingRate = data.readInt32(); - audio_format_t format = (audio_format_t) data.readInt32(); - uint32_t channels = data.readInt32(); - audio_in_acoustics_t acoustics = - static_cast <audio_in_acoustics_t>(data.readInt32()); - int audioSession = data.readInt32(); - audio_io_handle_t input = getInput(inputSource, - samplingRate, - format, - channels, - acoustics, - audioSession); - reply->writeInt32(static_cast <int>(input)); - return NO_ERROR; - } break; - - case START_INPUT: { - CHECK_INTERFACE(IAudioPolicyService, data, reply); - audio_io_handle_t input = static_cast <audio_io_handle_t>(data.readInt32()); - reply->writeInt32(static_cast <uint32_t>(startInput(input))); - return NO_ERROR; - } break; - - case STOP_INPUT: { - CHECK_INTERFACE(IAudioPolicyService, data, reply); - audio_io_handle_t input = static_cast <audio_io_handle_t>(data.readInt32()); - reply->writeInt32(static_cast <uint32_t>(stopInput(input))); - return NO_ERROR; - } break; - - case RELEASE_INPUT: { - CHECK_INTERFACE(IAudioPolicyService, data, reply); - audio_io_handle_t input = static_cast <audio_io_handle_t>(data.readInt32()); - releaseInput(input); - return NO_ERROR; - } break; - - case INIT_STREAM_VOLUME: { - CHECK_INTERFACE(IAudioPolicyService, data, reply); - 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))); - return NO_ERROR; - } break; - - case SET_STREAM_VOLUME: { - CHECK_INTERFACE(IAudioPolicyService, data, reply); - audio_stream_type_t stream = - static_cast <audio_stream_type_t>(data.readInt32()); - int index = data.readInt32(); - audio_devices_t device = static_cast <audio_devices_t>(data.readInt32()); - reply->writeInt32(static_cast <uint32_t>(setStreamVolumeIndex(stream, - index, - device))); - return NO_ERROR; - } break; - - case GET_STREAM_VOLUME: { - CHECK_INTERFACE(IAudioPolicyService, data, reply); - audio_stream_type_t stream = - static_cast <audio_stream_type_t>(data.readInt32()); - audio_devices_t device = static_cast <audio_devices_t>(data.readInt32()); - int index; - status_t status = getStreamVolumeIndex(stream, &index, device); - reply->writeInt32(index); - reply->writeInt32(static_cast <uint32_t>(status)); - return NO_ERROR; - } break; - - case GET_STRATEGY_FOR_STREAM: { - CHECK_INTERFACE(IAudioPolicyService, data, reply); - 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); - audio_stream_type_t stream = - static_cast <audio_stream_type_t>(data.readInt32()); - reply->writeInt32(static_cast <int>(getDevicesForStream(stream))); - return NO_ERROR; - } break; - - case GET_OUTPUT_FOR_EFFECT: { - CHECK_INTERFACE(IAudioPolicyService, data, reply); - effect_descriptor_t desc; - data.read(&desc, sizeof(effect_descriptor_t)); - audio_io_handle_t output = getOutputForEffect(&desc); - reply->writeInt32(static_cast <int>(output)); - return NO_ERROR; - } break; - - case REGISTER_EFFECT: { - CHECK_INTERFACE(IAudioPolicyService, data, reply); - effect_descriptor_t desc; - data.read(&desc, sizeof(effect_descriptor_t)); - audio_io_handle_t io = data.readInt32(); - uint32_t strategy = data.readInt32(); - int session = data.readInt32(); - int id = data.readInt32(); - reply->writeInt32(static_cast <int32_t>(registerEffect(&desc, - io, - strategy, - session, - id))); - return NO_ERROR; - } break; - - case UNREGISTER_EFFECT: { - CHECK_INTERFACE(IAudioPolicyService, data, reply); - int id = data.readInt32(); - reply->writeInt32(static_cast <int32_t>(unregisterEffect(id))); - return NO_ERROR; - } break; - - case SET_EFFECT_ENABLED: { - CHECK_INTERFACE(IAudioPolicyService, data, reply); - int id = data.readInt32(); - bool enabled = static_cast <bool>(data.readInt32()); - reply->writeInt32(static_cast <int32_t>(setEffectEnabled(id, enabled))); - return NO_ERROR; - } break; - - case IS_STREAM_ACTIVE: { - CHECK_INTERFACE(IAudioPolicyService, data, reply); - audio_stream_type_t stream = (audio_stream_type_t) data.readInt32(); - uint32_t inPastMs = (uint32_t)data.readInt32(); - reply->writeInt32( isStreamActive((audio_stream_type_t) stream, inPastMs) ); - return NO_ERROR; - } break; - - case QUERY_DEFAULT_PRE_PROCESSING: { - CHECK_INTERFACE(IAudioPolicyService, data, reply); - int audioSession = data.readInt32(); - uint32_t count = data.readInt32(); - uint32_t retCount = count; - effect_descriptor_t *descriptors = - (effect_descriptor_t *)new char[count * sizeof(effect_descriptor_t)]; - status_t status = queryDefaultPreProcessing(audioSession, descriptors, &retCount); - reply->writeInt32(status); - if (status != NO_ERROR && status != NO_MEMORY) { - retCount = 0; - } - reply->writeInt32(retCount); - if (retCount) { - if (retCount < count) { - count = retCount; - } - reply->write(descriptors, sizeof(effect_descriptor_t) * count); - } - delete[] descriptors; - return status; - } - - default: - return BBinder::onTransact(code, data, reply, flags); - } -} - -// ---------------------------------------------------------------------------- - -}; // namespace android diff --git a/media/libmedia/IAudioRecord.cpp b/media/libmedia/IAudioRecord.cpp deleted file mode 100644 index 377b9a8..0000000 --- a/media/libmedia/IAudioRecord.cpp +++ /dev/null @@ -1,107 +0,0 @@ -/* -** -** Copyright 2007, 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 "IAudioRecord" -//#define LOG_NDEBUG 0 -#include <utils/Log.h> - -#include <stdint.h> -#include <sys/types.h> - -#include <binder/Parcel.h> - -#include <media/IAudioRecord.h> - -namespace android { - -enum { - GET_CBLK = IBinder::FIRST_CALL_TRANSACTION, - START, - STOP -}; - -class BpAudioRecord : public BpInterface<IAudioRecord> -{ -public: - BpAudioRecord(const sp<IBinder>& impl) - : BpInterface<IAudioRecord>(impl) - { - } - - virtual status_t start(pid_t tid) - { - Parcel data, reply; - data.writeInterfaceToken(IAudioRecord::getInterfaceDescriptor()); - data.writeInt32(tid); - status_t status = remote()->transact(START, data, &reply); - if (status == NO_ERROR) { - status = reply.readInt32(); - } else { - ALOGW("start() error: %s", strerror(-status)); - } - return status; - } - - virtual void stop() - { - Parcel data, reply; - data.writeInterfaceToken(IAudioRecord::getInterfaceDescriptor()); - remote()->transact(STOP, data, &reply); - } - - virtual sp<IMemory> getCblk() const - { - Parcel data, reply; - sp<IMemory> cblk; - data.writeInterfaceToken(IAudioRecord::getInterfaceDescriptor()); - status_t status = remote()->transact(GET_CBLK, data, &reply); - if (status == NO_ERROR) { - cblk = interface_cast<IMemory>(reply.readStrongBinder()); - } - return cblk; - } -}; - -IMPLEMENT_META_INTERFACE(AudioRecord, "android.media.IAudioRecord"); - -// ---------------------------------------------------------------------- - -status_t BnAudioRecord::onTransact( - uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) -{ - switch (code) { - case GET_CBLK: { - CHECK_INTERFACE(IAudioRecord, data, reply); - reply->writeStrongBinder(getCblk()->asBinder()); - return NO_ERROR; - } break; - case START: { - CHECK_INTERFACE(IAudioRecord, data, reply); - reply->writeInt32(start(data.readInt32())); - return NO_ERROR; - } break; - case STOP: { - CHECK_INTERFACE(IAudioRecord, data, reply); - stop(); - return NO_ERROR; - } break; - default: - return BBinder::onTransact(code, data, reply, flags); - } -} - -}; // namespace android diff --git a/media/libmedia/IAudioTrack.cpp b/media/libmedia/IAudioTrack.cpp deleted file mode 100644 index 09f31a7..0000000 --- a/media/libmedia/IAudioTrack.cpp +++ /dev/null @@ -1,245 +0,0 @@ -/* -** -** Copyright 2007, 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 "IAudioTrack" -//#define LOG_NDEBUG 0 -#include <utils/Log.h> - -#include <stdint.h> -#include <sys/types.h> - -#include <binder/Parcel.h> - -#include <media/IAudioTrack.h> - -namespace android { - -enum { - GET_CBLK = IBinder::FIRST_CALL_TRANSACTION, - START, - STOP, - FLUSH, - MUTE, - PAUSE, - ATTACH_AUX_EFFECT, - ALLOCATE_TIMED_BUFFER, - QUEUE_TIMED_BUFFER, - SET_MEDIA_TIME_TRANSFORM, -}; - -class BpAudioTrack : public BpInterface<IAudioTrack> -{ -public: - BpAudioTrack(const sp<IBinder>& impl) - : BpInterface<IAudioTrack>(impl) - { - } - - virtual sp<IMemory> getCblk() const - { - Parcel data, reply; - sp<IMemory> cblk; - data.writeInterfaceToken(IAudioTrack::getInterfaceDescriptor()); - status_t status = remote()->transact(GET_CBLK, data, &reply); - if (status == NO_ERROR) { - cblk = interface_cast<IMemory>(reply.readStrongBinder()); - } - return cblk; - } - - virtual status_t start(pid_t tid) - { - Parcel data, reply; - data.writeInterfaceToken(IAudioTrack::getInterfaceDescriptor()); - data.writeInt32(tid); - status_t status = remote()->transact(START, data, &reply); - if (status == NO_ERROR) { - status = reply.readInt32(); - } else { - ALOGW("start() error: %s", strerror(-status)); - } - return status; - } - - virtual void stop() - { - Parcel data, reply; - data.writeInterfaceToken(IAudioTrack::getInterfaceDescriptor()); - remote()->transact(STOP, data, &reply); - } - - virtual void flush() - { - Parcel data, reply; - data.writeInterfaceToken(IAudioTrack::getInterfaceDescriptor()); - remote()->transact(FLUSH, data, &reply); - } - - virtual void mute(bool e) - { - Parcel data, reply; - data.writeInterfaceToken(IAudioTrack::getInterfaceDescriptor()); - data.writeInt32(e); - remote()->transact(MUTE, data, &reply); - } - - virtual void pause() - { - Parcel data, reply; - data.writeInterfaceToken(IAudioTrack::getInterfaceDescriptor()); - remote()->transact(PAUSE, data, &reply); - } - - virtual status_t attachAuxEffect(int effectId) - { - Parcel data, reply; - data.writeInterfaceToken(IAudioTrack::getInterfaceDescriptor()); - data.writeInt32(effectId); - status_t status = remote()->transact(ATTACH_AUX_EFFECT, data, &reply); - if (status == NO_ERROR) { - status = reply.readInt32(); - } else { - ALOGW("attachAuxEffect() error: %s", strerror(-status)); - } - return status; - } - - virtual status_t allocateTimedBuffer(size_t size, sp<IMemory>* buffer) { - Parcel data, reply; - data.writeInterfaceToken(IAudioTrack::getInterfaceDescriptor()); - data.writeInt32(size); - status_t status = remote()->transact(ALLOCATE_TIMED_BUFFER, - data, &reply); - if (status == NO_ERROR) { - status = reply.readInt32(); - if (status == NO_ERROR) { - *buffer = interface_cast<IMemory>(reply.readStrongBinder()); - } - } - return status; - } - - virtual status_t queueTimedBuffer(const sp<IMemory>& buffer, - int64_t pts) { - Parcel data, reply; - data.writeInterfaceToken(IAudioTrack::getInterfaceDescriptor()); - data.writeStrongBinder(buffer->asBinder()); - data.writeInt64(pts); - status_t status = remote()->transact(QUEUE_TIMED_BUFFER, - data, &reply); - if (status == NO_ERROR) { - status = reply.readInt32(); - } - return status; - } - - virtual status_t setMediaTimeTransform(const LinearTransform& xform, - int target) { - Parcel data, reply; - data.writeInterfaceToken(IAudioTrack::getInterfaceDescriptor()); - data.writeInt64(xform.a_zero); - data.writeInt64(xform.b_zero); - data.writeInt32(xform.a_to_b_numer); - data.writeInt32(xform.a_to_b_denom); - data.writeInt32(target); - status_t status = remote()->transact(SET_MEDIA_TIME_TRANSFORM, - data, &reply); - if (status == NO_ERROR) { - status = reply.readInt32(); - } - return status; - } -}; - -IMPLEMENT_META_INTERFACE(AudioTrack, "android.media.IAudioTrack"); - -// ---------------------------------------------------------------------- - -status_t BnAudioTrack::onTransact( - uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) -{ - switch (code) { - case GET_CBLK: { - CHECK_INTERFACE(IAudioTrack, data, reply); - reply->writeStrongBinder(getCblk()->asBinder()); - return NO_ERROR; - } break; - case START: { - CHECK_INTERFACE(IAudioTrack, data, reply); - reply->writeInt32(start(data.readInt32())); - return NO_ERROR; - } break; - case STOP: { - CHECK_INTERFACE(IAudioTrack, data, reply); - stop(); - return NO_ERROR; - } break; - case FLUSH: { - CHECK_INTERFACE(IAudioTrack, data, reply); - flush(); - return NO_ERROR; - } break; - case MUTE: { - CHECK_INTERFACE(IAudioTrack, data, reply); - mute( data.readInt32() ); - return NO_ERROR; - } break; - case PAUSE: { - CHECK_INTERFACE(IAudioTrack, data, reply); - pause(); - return NO_ERROR; - } - case ATTACH_AUX_EFFECT: { - CHECK_INTERFACE(IAudioTrack, data, reply); - reply->writeInt32(attachAuxEffect(data.readInt32())); - return NO_ERROR; - } break; - case ALLOCATE_TIMED_BUFFER: { - CHECK_INTERFACE(IAudioTrack, data, reply); - sp<IMemory> buffer; - status_t status = allocateTimedBuffer(data.readInt32(), &buffer); - reply->writeInt32(status); - if (status == NO_ERROR) { - reply->writeStrongBinder(buffer->asBinder()); - } - return NO_ERROR; - } break; - case QUEUE_TIMED_BUFFER: { - CHECK_INTERFACE(IAudioTrack, data, reply); - sp<IMemory> buffer = interface_cast<IMemory>( - data.readStrongBinder()); - uint64_t pts = data.readInt64(); - reply->writeInt32(queueTimedBuffer(buffer, pts)); - return NO_ERROR; - } break; - case SET_MEDIA_TIME_TRANSFORM: { - CHECK_INTERFACE(IAudioTrack, data, reply); - LinearTransform xform; - xform.a_zero = data.readInt64(); - xform.b_zero = data.readInt64(); - xform.a_to_b_numer = data.readInt32(); - xform.a_to_b_denom = data.readInt32(); - int target = data.readInt32(); - reply->writeInt32(setMediaTimeTransform(xform, target)); - return NO_ERROR; - } break; - default: - return BBinder::onTransact(code, data, reply, flags); - } -} - -}; // namespace android diff --git a/media/libmedia/ICrypto.cpp b/media/libmedia/ICrypto.cpp deleted file mode 100644 index 827d7af..0000000 --- a/media/libmedia/ICrypto.cpp +++ /dev/null @@ -1,293 +0,0 @@ -/* - * Copyright (C) 2012 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_NDEBUG 0 -#define LOG_TAG "ICrypto" -#include <utils/Log.h> - -#include <binder/Parcel.h> -#include <media/ICrypto.h> -#include <media/stagefright/foundation/ADebug.h> - -namespace android { - -enum { - INITIALIZE = IBinder::FIRST_CALL_TRANSACTION, - TERMINATE, - SET_ENTITLEMENT_KEY, - SET_ECM, - DECRYPT_VIDEO, - DECRYPT_AUDIO, -}; - -struct BpCrypto : public BpInterface<ICrypto> { - BpCrypto(const sp<IBinder> &impl) - : BpInterface<ICrypto>(impl) { - } - - virtual status_t initialize() { - Parcel data, reply; - data.writeInterfaceToken(ICrypto::getInterfaceDescriptor()); - remote()->transact(INITIALIZE, data, &reply); - - return reply.readInt32(); - } - - virtual status_t terminate() { - Parcel data, reply; - data.writeInterfaceToken(ICrypto::getInterfaceDescriptor()); - remote()->transact(TERMINATE, data, &reply); - - return reply.readInt32(); - } - - virtual status_t setEntitlementKey( - const void *key, size_t keyLength) { - Parcel data, reply; - data.writeInterfaceToken(ICrypto::getInterfaceDescriptor()); - data.writeInt32(keyLength); - data.write(key, keyLength); - remote()->transact(SET_ENTITLEMENT_KEY, data, &reply); - - return reply.readInt32(); - } - - virtual status_t setEntitlementControlMessage( - const void *msg, size_t msgLength) { - Parcel data, reply; - data.writeInterfaceToken(ICrypto::getInterfaceDescriptor()); - data.writeInt32(msgLength); - data.write(msg, msgLength); - remote()->transact(SET_ECM, data, &reply); - - return reply.readInt32(); - } - - virtual ssize_t decryptVideo( - const void *iv, size_t ivLength, - const void *srcData, size_t srcDataSize, - void *dstData, size_t dstDataOffset) { - Parcel data, reply; - data.writeInterfaceToken(ICrypto::getInterfaceDescriptor()); - if (iv == NULL) { - if (ivLength > 0) { - return -EINVAL; - } - - data.writeInt32(-1); - } else { - data.writeInt32(ivLength); - data.write(iv, ivLength); - } - - data.writeInt32(srcDataSize); - data.write(srcData, srcDataSize); - - data.writeIntPtr((intptr_t)dstData); - data.writeInt32(dstDataOffset); - - remote()->transact(DECRYPT_VIDEO, data, &reply); - - return reply.readInt32(); - } - - virtual ssize_t decryptAudio( - const void *iv, size_t ivLength, - const void *srcData, size_t srcDataSize, - void *dstData, size_t dstDataSize) { - Parcel data, reply; - data.writeInterfaceToken(ICrypto::getInterfaceDescriptor()); - if (iv == NULL) { - if (ivLength > 0) { - return -EINVAL; - } - - data.writeInt32(-1); - } else { - data.writeInt32(ivLength); - data.write(iv, ivLength); - } - - data.writeInt32(srcDataSize); - data.write(srcData, srcDataSize); - data.writeInt32(dstDataSize); - - remote()->transact(DECRYPT_AUDIO, data, &reply); - - ssize_t res = reply.readInt32(); - - if (res <= 0) { - return res; - } - - reply.read(dstData, res); - - return res; - } - -private: - DISALLOW_EVIL_CONSTRUCTORS(BpCrypto); -}; - -IMPLEMENT_META_INTERFACE(Crypto, "android.hardware.ICrypto"); - -//////////////////////////////////////////////////////////////////////////////// - -status_t BnCrypto::onTransact( - uint32_t code, const Parcel &data, Parcel *reply, uint32_t flags) { - switch (code) { - case INITIALIZE: - { - CHECK_INTERFACE(ICrypto, data, reply); - reply->writeInt32(initialize()); - - return OK; - } - - case TERMINATE: - { - CHECK_INTERFACE(ICrypto, data, reply); - reply->writeInt32(terminate()); - - return OK; - } - - case SET_ENTITLEMENT_KEY: - { - CHECK_INTERFACE(ICrypto, data, reply); - - size_t keyLength = data.readInt32(); - void *key = malloc(keyLength); - data.read(key, keyLength); - - reply->writeInt32(setEntitlementKey(key, keyLength)); - - free(key); - key = NULL; - - return OK; - } - - case SET_ECM: - { - CHECK_INTERFACE(ICrypto, data, reply); - - size_t msgLength = data.readInt32(); - void *msg = malloc(msgLength); - data.read(msg, msgLength); - - reply->writeInt32(setEntitlementControlMessage(msg, msgLength)); - - free(msg); - msg = NULL; - - return OK; - } - - case DECRYPT_VIDEO: - { - CHECK_INTERFACE(ICrypto, data, reply); - - void *iv = NULL; - - int32_t ivLength = data.readInt32(); - if (ivLength >= 0) { - iv = malloc(ivLength); - data.read(iv, ivLength); - } - - size_t srcDataSize = data.readInt32(); - void *srcData = malloc(srcDataSize); - data.read(srcData, srcDataSize); - - void *dstData = (void *)data.readIntPtr(); - size_t dstDataOffset = data.readInt32(); - - reply->writeInt32( - decryptVideo( - iv, - ivLength < 0 ? 0 : ivLength, - srcData, - srcDataSize, - dstData, - dstDataOffset)); - - free(srcData); - srcData = NULL; - - if (iv != NULL) { - free(iv); - iv = NULL; - } - - return OK; - } - - case DECRYPT_AUDIO: - { - CHECK_INTERFACE(ICrypto, data, reply); - - void *iv = NULL; - - int32_t ivLength = data.readInt32(); - if (ivLength >= 0) { - iv = malloc(ivLength); - data.read(iv, ivLength); - } - - size_t srcDataSize = data.readInt32(); - void *srcData = malloc(srcDataSize); - data.read(srcData, srcDataSize); - - size_t dstDataSize = data.readInt32(); - void *dstData = malloc(dstDataSize); - - ssize_t res = - decryptAudio( - iv, - ivLength < 0 ? 0 : ivLength, - srcData, - srcDataSize, - dstData, - dstDataSize); - - reply->writeInt32(res); - - if (res > 0) { - reply->write(dstData, res); - } - - free(dstData); - dstData = NULL; - - free(srcData); - srcData = NULL; - - if (iv != NULL) { - free(iv); - iv = NULL; - } - - return OK; - } - - default: - return BBinder::onTransact(code, data, reply, flags); - } -} - -} // namespace android - diff --git a/media/libmedia/IEffect.cpp b/media/libmedia/IEffect.cpp deleted file mode 100644 index a303a8f..0000000 --- a/media/libmedia/IEffect.cpp +++ /dev/null @@ -1,201 +0,0 @@ -/* -** -** Copyright 2010, 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_NDEBUG 0 -#define LOG_TAG "IEffect" -#include <utils/Log.h> -#include <stdint.h> -#include <sys/types.h> -#include <binder/Parcel.h> -#include <media/IEffect.h> - -namespace android { - -enum { - ENABLE = IBinder::FIRST_CALL_TRANSACTION, - DISABLE, - COMMAND, - DISCONNECT, - GET_CBLK -}; - -class BpEffect: public BpInterface<IEffect> -{ -public: - BpEffect(const sp<IBinder>& impl) - : BpInterface<IEffect>(impl) - { - } - - status_t enable() - { - ALOGV("enable"); - Parcel data, reply; - data.writeInterfaceToken(IEffect::getInterfaceDescriptor()); - remote()->transact(ENABLE, data, &reply); - return reply.readInt32(); - } - - status_t disable() - { - ALOGV("disable"); - Parcel data, reply; - data.writeInterfaceToken(IEffect::getInterfaceDescriptor()); - remote()->transact(DISABLE, data, &reply); - return reply.readInt32(); - } - - status_t command(uint32_t cmdCode, - uint32_t cmdSize, - void *pCmdData, - uint32_t *pReplySize, - void *pReplyData) - { - ALOGV("command"); - Parcel data, reply; - data.writeInterfaceToken(IEffect::getInterfaceDescriptor()); - data.writeInt32(cmdCode); - int size = cmdSize; - if (pCmdData == NULL) { - size = 0; - } - data.writeInt32(size); - if (size) { - data.write(pCmdData, size); - } - if (pReplySize == NULL) { - size = 0; - } else { - size = *pReplySize; - } - data.writeInt32(size); - - status_t status = remote()->transact(COMMAND, data, &reply); - if (status != NO_ERROR) { - if (pReplySize != NULL) - *pReplySize = 0; - return status; - } - - status = reply.readInt32(); - size = reply.readInt32(); - if (size != 0 && pReplyData != NULL && pReplySize != NULL) { - reply.read(pReplyData, size); - *pReplySize = size; - } - return status; - } - - void disconnect() - { - ALOGV("disconnect"); - Parcel data, reply; - data.writeInterfaceToken(IEffect::getInterfaceDescriptor()); - remote()->transact(DISCONNECT, data, &reply); - return; - } - - virtual sp<IMemory> getCblk() const - { - Parcel data, reply; - sp<IMemory> cblk; - data.writeInterfaceToken(IEffect::getInterfaceDescriptor()); - status_t status = remote()->transact(GET_CBLK, data, &reply); - if (status == NO_ERROR) { - cblk = interface_cast<IMemory>(reply.readStrongBinder()); - } - return cblk; - } - }; - -IMPLEMENT_META_INTERFACE(Effect, "android.media.IEffect"); - -// ---------------------------------------------------------------------- - -status_t BnEffect::onTransact( - uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) -{ - switch (code) { - case ENABLE: { - ALOGV("ENABLE"); - CHECK_INTERFACE(IEffect, data, reply); - reply->writeInt32(enable()); - return NO_ERROR; - } break; - - case DISABLE: { - ALOGV("DISABLE"); - CHECK_INTERFACE(IEffect, data, reply); - reply->writeInt32(disable()); - return NO_ERROR; - } break; - - case COMMAND: { - ALOGV("COMMAND"); - CHECK_INTERFACE(IEffect, data, reply); - uint32_t cmdCode = data.readInt32(); - uint32_t cmdSize = data.readInt32(); - char *cmd = NULL; - if (cmdSize) { - cmd = (char *)malloc(cmdSize); - data.read(cmd, cmdSize); - } - uint32_t replySize = data.readInt32(); - uint32_t replySz = replySize; - char *resp = NULL; - if (replySize) { - resp = (char *)malloc(replySize); - } - status_t status = command(cmdCode, cmdSize, cmd, &replySz, resp); - reply->writeInt32(status); - if (replySz < replySize) { - replySize = replySz; - } - reply->writeInt32(replySize); - if (replySize) { - reply->write(resp, replySize); - } - if (cmd) { - free(cmd); - } - if (resp) { - free(resp); - } - return NO_ERROR; - } break; - - case DISCONNECT: { - ALOGV("DISCONNECT"); - CHECK_INTERFACE(IEffect, data, reply); - disconnect(); - return NO_ERROR; - } break; - - case GET_CBLK: { - CHECK_INTERFACE(IEffect, data, reply); - reply->writeStrongBinder(getCblk()->asBinder()); - return NO_ERROR; - } break; - - default: - return BBinder::onTransact(code, data, reply, flags); - } -} - -// ---------------------------------------------------------------------------- - -}; // namespace android diff --git a/media/libmedia/IEffectClient.cpp b/media/libmedia/IEffectClient.cpp deleted file mode 100644 index aef4371..0000000 --- a/media/libmedia/IEffectClient.cpp +++ /dev/null @@ -1,144 +0,0 @@ -/* -** -** Copyright 2010, 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_NDEBUG 0 -#define LOG_TAG "IEffectClient" -#include <utils/Log.h> -#include <stdint.h> -#include <sys/types.h> -#include <media/IEffectClient.h> - -namespace android { - -enum { - CONTROL_STATUS_CHANGED = IBinder::FIRST_CALL_TRANSACTION, - ENABLE_STATUS_CHANGED, - COMMAND_EXECUTED -}; - -class BpEffectClient: public BpInterface<IEffectClient> -{ -public: - BpEffectClient(const sp<IBinder>& impl) - : BpInterface<IEffectClient>(impl) - { - } - - void controlStatusChanged(bool controlGranted) - { - ALOGV("controlStatusChanged"); - Parcel data, reply; - data.writeInterfaceToken(IEffectClient::getInterfaceDescriptor()); - data.writeInt32((uint32_t)controlGranted); - remote()->transact(CONTROL_STATUS_CHANGED, data, &reply, IBinder::FLAG_ONEWAY); - } - - void enableStatusChanged(bool enabled) - { - ALOGV("enableStatusChanged"); - Parcel data, reply; - data.writeInterfaceToken(IEffectClient::getInterfaceDescriptor()); - data.writeInt32((uint32_t)enabled); - remote()->transact(ENABLE_STATUS_CHANGED, data, &reply, IBinder::FLAG_ONEWAY); - } - - void commandExecuted(uint32_t cmdCode, - uint32_t cmdSize, - void *pCmdData, - uint32_t replySize, - void *pReplyData) - { - ALOGV("commandExecuted"); - Parcel data, reply; - data.writeInterfaceToken(IEffectClient::getInterfaceDescriptor()); - data.writeInt32(cmdCode); - int size = cmdSize; - if (pCmdData == NULL) { - size = 0; - } - data.writeInt32(size); - if (size) { - data.write(pCmdData, size); - } - size = replySize; - if (pReplyData == NULL) { - size = 0; - } - data.writeInt32(size); - if (size) { - data.write(pReplyData, size); - } - remote()->transact(COMMAND_EXECUTED, data, &reply, IBinder::FLAG_ONEWAY); - } - -}; - -IMPLEMENT_META_INTERFACE(EffectClient, "android.media.IEffectClient"); - -// ---------------------------------------------------------------------- - -status_t BnEffectClient::onTransact( - uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) -{ - switch (code) { - case CONTROL_STATUS_CHANGED: { - ALOGV("CONTROL_STATUS_CHANGED"); - CHECK_INTERFACE(IEffectClient, data, reply); - bool hasControl = (bool)data.readInt32(); - controlStatusChanged(hasControl); - return NO_ERROR; - } break; - case ENABLE_STATUS_CHANGED: { - ALOGV("ENABLE_STATUS_CHANGED"); - CHECK_INTERFACE(IEffectClient, data, reply); - bool enabled = (bool)data.readInt32(); - enableStatusChanged(enabled); - return NO_ERROR; - } break; - case COMMAND_EXECUTED: { - ALOGV("COMMAND_EXECUTED"); - CHECK_INTERFACE(IEffectClient, data, reply); - uint32_t cmdCode = data.readInt32(); - uint32_t cmdSize = data.readInt32(); - char *cmd = NULL; - if (cmdSize) { - cmd = (char *)malloc(cmdSize); - data.read(cmd, cmdSize); - } - uint32_t replySize = data.readInt32(); - char *resp = NULL; - if (replySize) { - resp = (char *)malloc(replySize); - data.read(resp, replySize); - } - commandExecuted(cmdCode, cmdSize, cmd, replySize, resp); - if (cmd) { - free(cmd); - } - if (resp) { - free(resp); - } - return NO_ERROR; - } break; - default: - return BBinder::onTransact(code, data, reply, flags); - } -} - -// ---------------------------------------------------------------------------- - -}; // namespace android diff --git a/media/libmedia/IMediaDeathNotifier.cpp b/media/libmedia/IMediaDeathNotifier.cpp deleted file mode 100644 index 9199db6..0000000 --- a/media/libmedia/IMediaDeathNotifier.cpp +++ /dev/null @@ -1,111 +0,0 @@ -/* -** Copyright 2010, 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_NDEBUG 0 -#define LOG_TAG "IMediaDeathNotifier" -#include <utils/Log.h> - -#include <binder/IServiceManager.h> -#include <binder/IPCThreadState.h> -#include <media/IMediaDeathNotifier.h> - -namespace android { - -// client singleton for binder interface to services -Mutex IMediaDeathNotifier::sServiceLock; -sp<IMediaPlayerService> IMediaDeathNotifier::sMediaPlayerService; -sp<IMediaDeathNotifier::DeathNotifier> IMediaDeathNotifier::sDeathNotifier; -SortedVector< wp<IMediaDeathNotifier> > IMediaDeathNotifier::sObitRecipients; - -// establish binder interface to MediaPlayerService -/*static*/const sp<IMediaPlayerService>& -IMediaDeathNotifier::getMediaPlayerService() -{ - ALOGV("getMediaPlayerService"); - Mutex::Autolock _l(sServiceLock); - if (sMediaPlayerService == 0) { - sp<IServiceManager> sm = defaultServiceManager(); - sp<IBinder> binder; - do { - binder = sm->getService(String16("media.player")); - if (binder != 0) { - break; - } - ALOGW("Media player service not published, waiting..."); - usleep(500000); // 0.5 s - } while (true); - - if (sDeathNotifier == NULL) { - sDeathNotifier = new DeathNotifier(); - } - binder->linkToDeath(sDeathNotifier); - sMediaPlayerService = interface_cast<IMediaPlayerService>(binder); - } - ALOGE_IF(sMediaPlayerService == 0, "no media player service!?"); - return sMediaPlayerService; -} - -/*static*/ void -IMediaDeathNotifier::addObitRecipient(const wp<IMediaDeathNotifier>& recipient) -{ - ALOGV("addObitRecipient"); - Mutex::Autolock _l(sServiceLock); - sObitRecipients.add(recipient); -} - -/*static*/ void -IMediaDeathNotifier::removeObitRecipient(const wp<IMediaDeathNotifier>& recipient) -{ - ALOGV("removeObitRecipient"); - Mutex::Autolock _l(sServiceLock); - sObitRecipients.remove(recipient); -} - -void -IMediaDeathNotifier::DeathNotifier::binderDied(const wp<IBinder>& who) { - ALOGW("media server died"); - - // Need to do this with the lock held - SortedVector< wp<IMediaDeathNotifier> > list; - { - Mutex::Autolock _l(sServiceLock); - sMediaPlayerService.clear(); - list = sObitRecipients; - } - - // Notify application when media server dies. - // Don't hold the static lock during callback in case app - // makes a call that needs the lock. - size_t count = list.size(); - for (size_t iter = 0; iter < count; ++iter) { - sp<IMediaDeathNotifier> notifier = list[iter].promote(); - if (notifier != 0) { - notifier->died(); - } - } -} - -IMediaDeathNotifier::DeathNotifier::~DeathNotifier() -{ - ALOGV("DeathNotifier::~DeathNotifier"); - Mutex::Autolock _l(sServiceLock); - sObitRecipients.clear(); - if (sMediaPlayerService != 0) { - sMediaPlayerService->asBinder()->unlinkToDeath(this); - } -} - -}; // namespace android diff --git a/media/libmedia/IMediaMetadataRetriever.cpp b/media/libmedia/IMediaMetadataRetriever.cpp deleted file mode 100644 index 7e6d54b..0000000 --- a/media/libmedia/IMediaMetadataRetriever.cpp +++ /dev/null @@ -1,268 +0,0 @@ -/* -** -** Copyright (C) 2008 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 <stdint.h> -#include <sys/types.h> -#include <binder/Parcel.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 -// the same priority as local calls. This is currently not working -// so this change puts in a temporary hack to fix the issue with -// metadata retrieval which can be a huge CPU hit if done on a -// foreground thread. -#ifndef DISABLE_GROUP_SCHEDULE_HACK - -#undef LOG_TAG -#define LOG_TAG "IMediaMetadataRetriever" -#include <utils/Log.h> -#include <cutils/sched_policy.h> - -namespace android { - -static void sendSchedPolicy(Parcel& data) -{ - SchedPolicy policy; - get_sched_policy(gettid(), &policy); - data.writeInt32(policy); -} - -static void setSchedPolicy(const Parcel& data) -{ - SchedPolicy policy = (SchedPolicy) data.readInt32(); - set_sched_policy(gettid(), policy); -} -static void restoreSchedPolicy() -{ - set_sched_policy(gettid(), SP_FOREGROUND); -} -}; // end namespace android -#endif - -namespace android { - -enum { - DISCONNECT = IBinder::FIRST_CALL_TRANSACTION, - SET_DATA_SOURCE_URL, - SET_DATA_SOURCE_FD, - GET_FRAME_AT_TIME, - EXTRACT_ALBUM_ART, - EXTRACT_METADATA, -}; - -class BpMediaMetadataRetriever: public BpInterface<IMediaMetadataRetriever> -{ -public: - BpMediaMetadataRetriever(const sp<IBinder>& impl) - : BpInterface<IMediaMetadataRetriever>(impl) - { - } - - // disconnect from media metadata retriever service - void disconnect() - { - Parcel data, reply; - data.writeInterfaceToken(IMediaMetadataRetriever::getInterfaceDescriptor()); - remote()->transact(DISCONNECT, data, &reply); - } - - 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(); - } - - status_t setDataSource(int fd, int64_t offset, int64_t length) - { - Parcel data, reply; - data.writeInterfaceToken(IMediaMetadataRetriever::getInterfaceDescriptor()); - data.writeFileDescriptor(fd); - data.writeInt64(offset); - data.writeInt64(length); - remote()->transact(SET_DATA_SOURCE_FD, data, &reply); - return reply.readInt32(); - } - - sp<IMemory> getFrameAtTime(int64_t timeUs, int option) - { - ALOGV("getTimeAtTime: time(%lld us) and option(%d)", timeUs, option); - Parcel data, reply; - data.writeInterfaceToken(IMediaMetadataRetriever::getInterfaceDescriptor()); - data.writeInt64(timeUs); - data.writeInt32(option); -#ifndef DISABLE_GROUP_SCHEDULE_HACK - sendSchedPolicy(data); -#endif - remote()->transact(GET_FRAME_AT_TIME, data, &reply); - status_t ret = reply.readInt32(); - if (ret != NO_ERROR) { - return NULL; - } - return interface_cast<IMemory>(reply.readStrongBinder()); - } - - sp<IMemory> extractAlbumArt() - { - Parcel data, reply; - data.writeInterfaceToken(IMediaMetadataRetriever::getInterfaceDescriptor()); -#ifndef DISABLE_GROUP_SCHEDULE_HACK - sendSchedPolicy(data); -#endif - remote()->transact(EXTRACT_ALBUM_ART, data, &reply); - status_t ret = reply.readInt32(); - if (ret != NO_ERROR) { - return NULL; - } - return interface_cast<IMemory>(reply.readStrongBinder()); - } - - const char* extractMetadata(int keyCode) - { - Parcel data, reply; - data.writeInterfaceToken(IMediaMetadataRetriever::getInterfaceDescriptor()); -#ifndef DISABLE_GROUP_SCHEDULE_HACK - sendSchedPolicy(data); -#endif - data.writeInt32(keyCode); - remote()->transact(EXTRACT_METADATA, data, &reply); - status_t ret = reply.readInt32(); - if (ret != NO_ERROR) { - return NULL; - } - return reply.readCString(); - } -}; - -IMPLEMENT_META_INTERFACE(MediaMetadataRetriever, "android.media.IMediaMetadataRetriever"); - -// ---------------------------------------------------------------------- - -status_t BnMediaMetadataRetriever::onTransact( - uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) -{ - switch (code) { - case DISCONNECT: { - CHECK_INTERFACE(IMediaMetadataRetriever, data, reply); - disconnect(); - return NO_ERROR; - } break; - case SET_DATA_SOURCE_URL: { - CHECK_INTERFACE(IMediaMetadataRetriever, data, reply); - const char* srcUrl = data.readCString(); - - 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: { - CHECK_INTERFACE(IMediaMetadataRetriever, data, reply); - int fd = dup(data.readFileDescriptor()); - int64_t offset = data.readInt64(); - int64_t length = data.readInt64(); - reply->writeInt32(setDataSource(fd, offset, length)); - return NO_ERROR; - } break; - case GET_FRAME_AT_TIME: { - CHECK_INTERFACE(IMediaMetadataRetriever, data, reply); - int64_t timeUs = data.readInt64(); - int option = data.readInt32(); - ALOGV("getTimeAtTime: time(%lld us) and option(%d)", timeUs, option); -#ifndef DISABLE_GROUP_SCHEDULE_HACK - setSchedPolicy(data); -#endif - sp<IMemory> bitmap = getFrameAtTime(timeUs, option); - if (bitmap != 0) { // Don't send NULL across the binder interface - reply->writeInt32(NO_ERROR); - reply->writeStrongBinder(bitmap->asBinder()); - } else { - reply->writeInt32(UNKNOWN_ERROR); - } -#ifndef DISABLE_GROUP_SCHEDULE_HACK - restoreSchedPolicy(); -#endif - return NO_ERROR; - } break; - case EXTRACT_ALBUM_ART: { - CHECK_INTERFACE(IMediaMetadataRetriever, data, reply); -#ifndef DISABLE_GROUP_SCHEDULE_HACK - setSchedPolicy(data); -#endif - sp<IMemory> albumArt = extractAlbumArt(); - if (albumArt != 0) { // Don't send NULL across the binder interface - reply->writeInt32(NO_ERROR); - reply->writeStrongBinder(albumArt->asBinder()); - } else { - reply->writeInt32(UNKNOWN_ERROR); - } -#ifndef DISABLE_GROUP_SCHEDULE_HACK - restoreSchedPolicy(); -#endif - return NO_ERROR; - } break; - case EXTRACT_METADATA: { - CHECK_INTERFACE(IMediaMetadataRetriever, data, reply); -#ifndef DISABLE_GROUP_SCHEDULE_HACK - setSchedPolicy(data); -#endif - int keyCode = data.readInt32(); - const char* value = extractMetadata(keyCode); - if (value != NULL) { // Don't send NULL across the binder interface - reply->writeInt32(NO_ERROR); - reply->writeCString(value); - } else { - reply->writeInt32(UNKNOWN_ERROR); - } -#ifndef DISABLE_GROUP_SCHEDULE_HACK - restoreSchedPolicy(); -#endif - return NO_ERROR; - } break; - default: - return BBinder::onTransact(code, data, reply, flags); - } -} - -// ---------------------------------------------------------------------------- - -}; // namespace android diff --git a/media/libmedia/IMediaPlayer.cpp b/media/libmedia/IMediaPlayer.cpp deleted file mode 100644 index 0bb237d..0000000 --- a/media/libmedia/IMediaPlayer.cpp +++ /dev/null @@ -1,515 +0,0 @@ -/* -** -** Copyright 2008, 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 <arpa/inet.h> -#include <stdint.h> -#include <sys/types.h> - -#include <binder/Parcel.h> - -#include <media/IMediaPlayer.h> -#include <media/IStreamSource.h> - -#include <gui/ISurfaceTexture.h> -#include <utils/String8.h> - -namespace android { - -enum { - DISCONNECT = IBinder::FIRST_CALL_TRANSACTION, - SET_DATA_SOURCE_URL, - SET_DATA_SOURCE_FD, - SET_DATA_SOURCE_STREAM, - PREPARE_ASYNC, - START, - STOP, - IS_PLAYING, - PAUSE, - SEEK_TO, - GET_CURRENT_POSITION, - GET_DURATION, - RESET, - SET_AUDIO_STREAM_TYPE, - SET_LOOPING, - SET_VOLUME, - INVOKE, - SET_METADATA_FILTER, - GET_METADATA, - SET_AUX_EFFECT_SEND_LEVEL, - ATTACH_AUX_EFFECT, - SET_VIDEO_SURFACETEXTURE, - SET_PARAMETER, - GET_PARAMETER, - SET_RETRANSMIT_ENDPOINT, - SET_NEXT_PLAYER, -}; - -class BpMediaPlayer: public BpInterface<IMediaPlayer> -{ -public: - BpMediaPlayer(const sp<IBinder>& impl) - : BpInterface<IMediaPlayer>(impl) - { - } - - // disconnect from media player service - void disconnect() - { - Parcel data, reply; - data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor()); - remote()->transact(DISCONNECT, data, &reply); - } - - status_t setDataSource(const char* url, - const KeyedVector<String8, String8>* headers) - { - Parcel data, reply; - data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor()); - data.writeCString(url); - 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(); - } - - status_t setDataSource(int fd, int64_t offset, int64_t length) { - Parcel data, reply; - data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor()); - data.writeFileDescriptor(fd); - data.writeInt64(offset); - data.writeInt64(length); - remote()->transact(SET_DATA_SOURCE_FD, data, &reply); - return reply.readInt32(); - } - - status_t setDataSource(const sp<IStreamSource> &source) { - Parcel data, reply; - data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor()); - data.writeStrongBinder(source->asBinder()); - remote()->transact(SET_DATA_SOURCE_STREAM, data, &reply); - return reply.readInt32(); - } - - // pass the buffered ISurfaceTexture to the media player service - status_t setVideoSurfaceTexture(const sp<ISurfaceTexture>& surfaceTexture) - { - Parcel data, reply; - data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor()); - sp<IBinder> b(surfaceTexture->asBinder()); - data.writeStrongBinder(b); - remote()->transact(SET_VIDEO_SURFACETEXTURE, data, &reply); - return reply.readInt32(); - } - - status_t prepareAsync() - { - Parcel data, reply; - data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor()); - remote()->transact(PREPARE_ASYNC, data, &reply); - return reply.readInt32(); - } - - status_t start() - { - Parcel data, reply; - data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor()); - remote()->transact(START, data, &reply); - return reply.readInt32(); - } - - status_t stop() - { - Parcel data, reply; - data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor()); - remote()->transact(STOP, data, &reply); - return reply.readInt32(); - } - - status_t isPlaying(bool* state) - { - Parcel data, reply; - data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor()); - remote()->transact(IS_PLAYING, data, &reply); - *state = reply.readInt32(); - return reply.readInt32(); - } - - status_t pause() - { - Parcel data, reply; - data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor()); - remote()->transact(PAUSE, data, &reply); - return reply.readInt32(); - } - - status_t seekTo(int msec) - { - Parcel data, reply; - data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor()); - data.writeInt32(msec); - remote()->transact(SEEK_TO, data, &reply); - return reply.readInt32(); - } - - status_t getCurrentPosition(int* msec) - { - Parcel data, reply; - data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor()); - remote()->transact(GET_CURRENT_POSITION, data, &reply); - *msec = reply.readInt32(); - return reply.readInt32(); - } - - status_t getDuration(int* msec) - { - Parcel data, reply; - data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor()); - remote()->transact(GET_DURATION, data, &reply); - *msec = reply.readInt32(); - return reply.readInt32(); - } - - status_t reset() - { - Parcel data, reply; - data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor()); - remote()->transact(RESET, data, &reply); - return reply.readInt32(); - } - - status_t setAudioStreamType(audio_stream_type_t stream) - { - Parcel data, reply; - data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor()); - data.writeInt32((int32_t) stream); - remote()->transact(SET_AUDIO_STREAM_TYPE, data, &reply); - return reply.readInt32(); - } - - status_t setLooping(int loop) - { - Parcel data, reply; - data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor()); - data.writeInt32(loop); - remote()->transact(SET_LOOPING, data, &reply); - return reply.readInt32(); - } - - status_t setVolume(float leftVolume, float rightVolume) - { - Parcel data, reply; - data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor()); - data.writeFloat(leftVolume); - data.writeFloat(rightVolume); - remote()->transact(SET_VOLUME, data, &reply); - return reply.readInt32(); - } - - status_t invoke(const Parcel& request, Parcel *reply) - { - // Avoid doing any extra copy. The interface descriptor should - // have been set by MediaPlayer.java. - return remote()->transact(INVOKE, request, reply); - } - - status_t setMetadataFilter(const Parcel& request) - { - Parcel reply; - // Avoid doing any extra copy of the request. The interface - // descriptor should have been set by MediaPlayer.java. - remote()->transact(SET_METADATA_FILTER, request, &reply); - return reply.readInt32(); - } - - status_t getMetadata(bool update_only, bool apply_filter, Parcel *reply) - { - Parcel request; - request.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor()); - // TODO: Burning 2 ints for 2 boolean. Should probably use flags in an int here. - request.writeInt32(update_only); - request.writeInt32(apply_filter); - remote()->transact(GET_METADATA, request, reply); - return reply->readInt32(); - } - - status_t setAuxEffectSendLevel(float level) - { - Parcel data, reply; - data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor()); - data.writeFloat(level); - remote()->transact(SET_AUX_EFFECT_SEND_LEVEL, data, &reply); - return reply.readInt32(); - } - - status_t attachAuxEffect(int effectId) - { - Parcel data, reply; - data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor()); - data.writeInt32(effectId); - remote()->transact(ATTACH_AUX_EFFECT, data, &reply); - 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); - } - - status_t setRetransmitEndpoint(const struct sockaddr_in* endpoint) { - Parcel data, reply; - status_t err; - - data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor()); - if (NULL != endpoint) { - data.writeInt32(sizeof(*endpoint)); - data.write(endpoint, sizeof(*endpoint)); - } else { - data.writeInt32(0); - } - - err = remote()->transact(SET_RETRANSMIT_ENDPOINT, data, &reply); - if (OK != err) { - return err; - } - return reply.readInt32(); - } - - status_t setNextPlayer(const sp<IMediaPlayer>& player) { - Parcel data, reply; - data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor()); - sp<IBinder> b(player->asBinder()); - data.writeStrongBinder(b); - remote()->transact(SET_NEXT_PLAYER, data, &reply); - return reply.readInt32(); - } -}; - -IMPLEMENT_META_INTERFACE(MediaPlayer, "android.media.IMediaPlayer"); - -// ---------------------------------------------------------------------- - -status_t BnMediaPlayer::onTransact( - uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) -{ - switch (code) { - case DISCONNECT: { - CHECK_INTERFACE(IMediaPlayer, data, reply); - disconnect(); - return NO_ERROR; - } break; - case SET_DATA_SOURCE_URL: { - CHECK_INTERFACE(IMediaPlayer, data, reply); - const char* url = data.readCString(); - 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(url, numHeaders > 0 ? &headers : NULL)); - return NO_ERROR; - } break; - case SET_DATA_SOURCE_FD: { - CHECK_INTERFACE(IMediaPlayer, data, reply); - int fd = data.readFileDescriptor(); - int64_t offset = data.readInt64(); - int64_t length = data.readInt64(); - reply->writeInt32(setDataSource(fd, offset, length)); - return NO_ERROR; - } - case SET_DATA_SOURCE_STREAM: { - CHECK_INTERFACE(IMediaPlayer, data, reply); - sp<IStreamSource> source = - interface_cast<IStreamSource>(data.readStrongBinder()); - reply->writeInt32(setDataSource(source)); - return NO_ERROR; - } - case SET_VIDEO_SURFACETEXTURE: { - CHECK_INTERFACE(IMediaPlayer, data, reply); - sp<ISurfaceTexture> surfaceTexture = - interface_cast<ISurfaceTexture>(data.readStrongBinder()); - reply->writeInt32(setVideoSurfaceTexture(surfaceTexture)); - return NO_ERROR; - } break; - case PREPARE_ASYNC: { - CHECK_INTERFACE(IMediaPlayer, data, reply); - reply->writeInt32(prepareAsync()); - return NO_ERROR; - } break; - case START: { - CHECK_INTERFACE(IMediaPlayer, data, reply); - reply->writeInt32(start()); - return NO_ERROR; - } break; - case STOP: { - CHECK_INTERFACE(IMediaPlayer, data, reply); - reply->writeInt32(stop()); - return NO_ERROR; - } break; - case IS_PLAYING: { - CHECK_INTERFACE(IMediaPlayer, data, reply); - bool state; - status_t ret = isPlaying(&state); - reply->writeInt32(state); - reply->writeInt32(ret); - return NO_ERROR; - } break; - case PAUSE: { - CHECK_INTERFACE(IMediaPlayer, data, reply); - reply->writeInt32(pause()); - return NO_ERROR; - } break; - case SEEK_TO: { - CHECK_INTERFACE(IMediaPlayer, data, reply); - reply->writeInt32(seekTo(data.readInt32())); - return NO_ERROR; - } break; - case GET_CURRENT_POSITION: { - CHECK_INTERFACE(IMediaPlayer, data, reply); - int msec; - status_t ret = getCurrentPosition(&msec); - reply->writeInt32(msec); - reply->writeInt32(ret); - return NO_ERROR; - } break; - case GET_DURATION: { - CHECK_INTERFACE(IMediaPlayer, data, reply); - int msec; - status_t ret = getDuration(&msec); - reply->writeInt32(msec); - reply->writeInt32(ret); - return NO_ERROR; - } break; - case RESET: { - CHECK_INTERFACE(IMediaPlayer, data, reply); - reply->writeInt32(reset()); - return NO_ERROR; - } break; - case SET_AUDIO_STREAM_TYPE: { - CHECK_INTERFACE(IMediaPlayer, data, reply); - reply->writeInt32(setAudioStreamType((audio_stream_type_t) data.readInt32())); - return NO_ERROR; - } break; - case SET_LOOPING: { - CHECK_INTERFACE(IMediaPlayer, data, reply); - reply->writeInt32(setLooping(data.readInt32())); - return NO_ERROR; - } break; - case SET_VOLUME: { - CHECK_INTERFACE(IMediaPlayer, data, reply); - float leftVolume = data.readFloat(); - float rightVolume = data.readFloat(); - reply->writeInt32(setVolume(leftVolume, rightVolume)); - return NO_ERROR; - } break; - case INVOKE: { - CHECK_INTERFACE(IMediaPlayer, data, reply); - status_t result = invoke(data, reply); - return result; - } break; - case SET_METADATA_FILTER: { - CHECK_INTERFACE(IMediaPlayer, data, reply); - reply->writeInt32(setMetadataFilter(data)); - return NO_ERROR; - } break; - case GET_METADATA: { - CHECK_INTERFACE(IMediaPlayer, data, reply); - bool update_only = static_cast<bool>(data.readInt32()); - bool apply_filter = static_cast<bool>(data.readInt32()); - const status_t retcode = getMetadata(update_only, apply_filter, reply); - reply->setDataPosition(0); - reply->writeInt32(retcode); - reply->setDataPosition(0); - return NO_ERROR; - } break; - case SET_AUX_EFFECT_SEND_LEVEL: { - CHECK_INTERFACE(IMediaPlayer, data, reply); - reply->writeInt32(setAuxEffectSendLevel(data.readFloat())); - return NO_ERROR; - } break; - case ATTACH_AUX_EFFECT: { - CHECK_INTERFACE(IMediaPlayer, data, reply); - 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; - case SET_RETRANSMIT_ENDPOINT: { - CHECK_INTERFACE(IMediaPlayer, data, reply); - - struct sockaddr_in endpoint; - int amt = data.readInt32(); - if (amt == sizeof(endpoint)) { - data.read(&endpoint, sizeof(struct sockaddr_in)); - reply->writeInt32(setRetransmitEndpoint(&endpoint)); - } else { - reply->writeInt32(setRetransmitEndpoint(NULL)); - } - return NO_ERROR; - } break; - case SET_NEXT_PLAYER: { - CHECK_INTERFACE(IMediaPlayer, data, reply); - reply->writeInt32(setNextPlayer(interface_cast<IMediaPlayer>(data.readStrongBinder()))); - return NO_ERROR; - } break; - default: - return BBinder::onTransact(code, data, reply, flags); - } -} - -// ---------------------------------------------------------------------------- - -}; // namespace android diff --git a/media/libmedia/IMediaPlayerClient.cpp b/media/libmedia/IMediaPlayerClient.cpp deleted file mode 100644 index a670c96..0000000 --- a/media/libmedia/IMediaPlayerClient.cpp +++ /dev/null @@ -1,78 +0,0 @@ -/* -** -** Copyright 2008, 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 <utils/RefBase.h> -#include <binder/IInterface.h> -#include <binder/Parcel.h> - -#include <media/IMediaPlayerClient.h> - -namespace android { - -enum { - NOTIFY = IBinder::FIRST_CALL_TRANSACTION, -}; - -class BpMediaPlayerClient: public BpInterface<IMediaPlayerClient> -{ -public: - BpMediaPlayerClient(const sp<IBinder>& impl) - : BpInterface<IMediaPlayerClient>(impl) - { - } - - 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); - } -}; - -IMPLEMENT_META_INTERFACE(MediaPlayerClient, "android.media.IMediaPlayerClient"); - -// ---------------------------------------------------------------------- - -status_t BnMediaPlayerClient::onTransact( - uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) -{ - switch (code) { - case NOTIFY: { - CHECK_INTERFACE(IMediaPlayerClient, data, reply); - int msg = data.readInt32(); - int ext1 = data.readInt32(); - int ext2 = data.readInt32(); - 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: - return BBinder::onTransact(code, data, reply, flags); - } -} - -}; // namespace android diff --git a/media/libmedia/IMediaPlayerService.cpp b/media/libmedia/IMediaPlayerService.cpp deleted file mode 100644 index 9120617..0000000 --- a/media/libmedia/IMediaPlayerService.cpp +++ /dev/null @@ -1,227 +0,0 @@ -/* -** -** Copyright 2008, 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 <stdint.h> -#include <sys/types.h> - -#include <binder/Parcel.h> -#include <binder/IMemory.h> -#include <media/ICrypto.h> -#include <media/IMediaPlayerService.h> -#include <media/IMediaRecorder.h> -#include <media/IOMX.h> -#include <media/IStreamSource.h> - -#include <utils/Errors.h> // for status_t - -namespace android { - -enum { - CREATE = IBinder::FIRST_CALL_TRANSACTION, - DECODE_URL, - DECODE_FD, - CREATE_MEDIA_RECORDER, - CREATE_METADATA_RETRIEVER, - GET_OMX, - MAKE_CRYPTO, - ADD_BATTERY_DATA, - PULL_BATTERY_DATA -}; - -class BpMediaPlayerService: public BpInterface<IMediaPlayerService> -{ -public: - BpMediaPlayerService(const sp<IBinder>& impl) - : BpInterface<IMediaPlayerService>(impl) - { - } - - virtual sp<IMediaMetadataRetriever> createMetadataRetriever(pid_t pid) - { - Parcel data, reply; - data.writeInterfaceToken(IMediaPlayerService::getInterfaceDescriptor()); - data.writeInt32(pid); - remote()->transact(CREATE_METADATA_RETRIEVER, data, &reply); - return interface_cast<IMediaMetadataRetriever>(reply.readStrongBinder()); - } - - virtual sp<IMediaPlayer> create( - pid_t pid, const sp<IMediaPlayerClient>& client, int audioSessionId) { - Parcel data, reply; - data.writeInterfaceToken(IMediaPlayerService::getInterfaceDescriptor()); - data.writeInt32(pid); - data.writeStrongBinder(client->asBinder()); - data.writeInt32(audioSessionId); - - remote()->transact(CREATE, data, &reply); - return interface_cast<IMediaPlayer>(reply.readStrongBinder()); - } - - virtual sp<IMediaRecorder> createMediaRecorder(pid_t pid) - { - Parcel data, reply; - data.writeInterfaceToken(IMediaPlayerService::getInterfaceDescriptor()); - data.writeInt32(pid); - remote()->transact(CREATE_MEDIA_RECORDER, data, &reply); - return interface_cast<IMediaRecorder>(reply.readStrongBinder()); - } - - virtual sp<IMemory> decode(const char* url, uint32_t *pSampleRate, int* pNumChannels, audio_format_t* pFormat) - { - Parcel data, reply; - data.writeInterfaceToken(IMediaPlayerService::getInterfaceDescriptor()); - data.writeCString(url); - remote()->transact(DECODE_URL, data, &reply); - *pSampleRate = uint32_t(reply.readInt32()); - *pNumChannels = reply.readInt32(); - *pFormat = (audio_format_t) reply.readInt32(); - return interface_cast<IMemory>(reply.readStrongBinder()); - } - - virtual sp<IMemory> decode(int fd, int64_t offset, int64_t length, uint32_t *pSampleRate, int* pNumChannels, audio_format_t* pFormat) - { - Parcel data, reply; - data.writeInterfaceToken(IMediaPlayerService::getInterfaceDescriptor()); - data.writeFileDescriptor(fd); - data.writeInt64(offset); - data.writeInt64(length); - remote()->transact(DECODE_FD, data, &reply); - *pSampleRate = uint32_t(reply.readInt32()); - *pNumChannels = reply.readInt32(); - *pFormat = (audio_format_t) reply.readInt32(); - return interface_cast<IMemory>(reply.readStrongBinder()); - } - - virtual sp<IOMX> getOMX() { - Parcel data, reply; - data.writeInterfaceToken(IMediaPlayerService::getInterfaceDescriptor()); - remote()->transact(GET_OMX, data, &reply); - return interface_cast<IOMX>(reply.readStrongBinder()); - } - - virtual sp<ICrypto> makeCrypto() { - Parcel data, reply; - data.writeInterfaceToken(IMediaPlayerService::getInterfaceDescriptor()); - remote()->transact(MAKE_CRYPTO, data, &reply); - return interface_cast<ICrypto>(reply.readStrongBinder()); - } - - virtual void addBatteryData(uint32_t params) { - Parcel data, reply; - data.writeInterfaceToken(IMediaPlayerService::getInterfaceDescriptor()); - data.writeInt32(params); - remote()->transact(ADD_BATTERY_DATA, data, &reply); - } - - virtual status_t pullBatteryData(Parcel* reply) { - Parcel data; - data.writeInterfaceToken(IMediaPlayerService::getInterfaceDescriptor()); - return remote()->transact(PULL_BATTERY_DATA, data, reply); - } -}; - -IMPLEMENT_META_INTERFACE(MediaPlayerService, "android.media.IMediaPlayerService"); - -// ---------------------------------------------------------------------- - -status_t BnMediaPlayerService::onTransact( - uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) -{ - switch (code) { - case CREATE: { - CHECK_INTERFACE(IMediaPlayerService, data, reply); - pid_t pid = data.readInt32(); - sp<IMediaPlayerClient> client = - interface_cast<IMediaPlayerClient>(data.readStrongBinder()); - int audioSessionId = data.readInt32(); - sp<IMediaPlayer> player = create(pid, client, audioSessionId); - reply->writeStrongBinder(player->asBinder()); - return NO_ERROR; - } break; - case DECODE_URL: { - CHECK_INTERFACE(IMediaPlayerService, data, reply); - const char* url = data.readCString(); - uint32_t sampleRate; - int numChannels; - audio_format_t format; - sp<IMemory> player = decode(url, &sampleRate, &numChannels, &format); - reply->writeInt32(sampleRate); - reply->writeInt32(numChannels); - reply->writeInt32((int32_t) format); - reply->writeStrongBinder(player->asBinder()); - return NO_ERROR; - } break; - case DECODE_FD: { - CHECK_INTERFACE(IMediaPlayerService, data, reply); - int fd = dup(data.readFileDescriptor()); - int64_t offset = data.readInt64(); - int64_t length = data.readInt64(); - uint32_t sampleRate; - int numChannels; - audio_format_t format; - sp<IMemory> player = decode(fd, offset, length, &sampleRate, &numChannels, &format); - reply->writeInt32(sampleRate); - reply->writeInt32(numChannels); - reply->writeInt32((int32_t) format); - reply->writeStrongBinder(player->asBinder()); - return NO_ERROR; - } break; - case CREATE_MEDIA_RECORDER: { - CHECK_INTERFACE(IMediaPlayerService, data, reply); - pid_t pid = data.readInt32(); - sp<IMediaRecorder> recorder = createMediaRecorder(pid); - reply->writeStrongBinder(recorder->asBinder()); - return NO_ERROR; - } break; - case CREATE_METADATA_RETRIEVER: { - CHECK_INTERFACE(IMediaPlayerService, data, reply); - pid_t pid = data.readInt32(); - sp<IMediaMetadataRetriever> retriever = createMetadataRetriever(pid); - reply->writeStrongBinder(retriever->asBinder()); - return NO_ERROR; - } break; - case GET_OMX: { - CHECK_INTERFACE(IMediaPlayerService, data, reply); - sp<IOMX> omx = getOMX(); - reply->writeStrongBinder(omx->asBinder()); - return NO_ERROR; - } break; - case MAKE_CRYPTO: { - CHECK_INTERFACE(IMediaPlayerService, data, reply); - sp<ICrypto> crypto = makeCrypto(); - reply->writeStrongBinder(crypto->asBinder()); - return NO_ERROR; - } break; - case ADD_BATTERY_DATA: { - CHECK_INTERFACE(IMediaPlayerService, data, reply); - uint32_t params = data.readInt32(); - addBatteryData(params); - return NO_ERROR; - } break; - case PULL_BATTERY_DATA: { - CHECK_INTERFACE(IMediaPlayerService, data, reply); - pullBatteryData(reply); - return NO_ERROR; - } break; - default: - return BBinder::onTransact(code, data, reply, flags); - } -} - -// ---------------------------------------------------------------------------- - -}; // namespace android diff --git a/media/libmedia/IMediaRecorder.cpp b/media/libmedia/IMediaRecorder.cpp deleted file mode 100644 index a710fd7..0000000 --- a/media/libmedia/IMediaRecorder.cpp +++ /dev/null @@ -1,463 +0,0 @@ -/* - ** - ** Copyright 2008, 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_NDEBUG 0 -#define LOG_TAG "IMediaRecorder" -#include <utils/Log.h> -#include <binder/Parcel.h> -#include <camera/ICamera.h> -#include <media/IMediaRecorderClient.h> -#include <media/IMediaRecorder.h> -#include <gui/Surface.h> -#include <gui/ISurfaceTexture.h> -#include <unistd.h> - - -namespace android { - -enum { - RELEASE = IBinder::FIRST_CALL_TRANSACTION, - INIT, - CLOSE, - QUERY_SURFACE_MEDIASOURCE, - RESET, - STOP, - START, - PREPARE, - GET_MAX_AMPLITUDE, - SET_VIDEO_SOURCE, - SET_AUDIO_SOURCE, - SET_OUTPUT_FORMAT, - SET_VIDEO_ENCODER, - SET_AUDIO_ENCODER, - SET_OUTPUT_FILE_PATH, - SET_OUTPUT_FILE_FD, - SET_VIDEO_SIZE, - SET_VIDEO_FRAMERATE, - SET_PARAMETERS, - SET_PREVIEW_SURFACE, - SET_CAMERA, - SET_LISTENER -}; - -class BpMediaRecorder: public BpInterface<IMediaRecorder> -{ -public: - BpMediaRecorder(const sp<IBinder>& impl) - : BpInterface<IMediaRecorder>(impl) - { - } - - status_t setCamera(const sp<ICamera>& camera, const sp<ICameraRecordingProxy>& proxy) - { - ALOGV("setCamera(%p,%p)", camera.get(), proxy.get()); - Parcel data, reply; - data.writeInterfaceToken(IMediaRecorder::getInterfaceDescriptor()); - data.writeStrongBinder(camera->asBinder()); - data.writeStrongBinder(proxy->asBinder()); - remote()->transact(SET_CAMERA, data, &reply); - return reply.readInt32(); - } - - sp<ISurfaceTexture> querySurfaceMediaSource() - { - ALOGV("Query SurfaceMediaSource"); - Parcel data, reply; - data.writeInterfaceToken(IMediaRecorder::getInterfaceDescriptor()); - remote()->transact(QUERY_SURFACE_MEDIASOURCE, data, &reply); - int returnedNull = reply.readInt32(); - if (returnedNull) { - return NULL; - } - return interface_cast<ISurfaceTexture>(reply.readStrongBinder()); - } - - status_t setPreviewSurface(const sp<Surface>& surface) - { - ALOGV("setPreviewSurface(%p)", surface.get()); - Parcel data, reply; - data.writeInterfaceToken(IMediaRecorder::getInterfaceDescriptor()); - Surface::writeToParcel(surface, &data); - remote()->transact(SET_PREVIEW_SURFACE, data, &reply); - return reply.readInt32(); - } - - status_t init() - { - ALOGV("init"); - Parcel data, reply; - data.writeInterfaceToken(IMediaRecorder::getInterfaceDescriptor()); - remote()->transact(INIT, data, &reply); - return reply.readInt32(); - } - - status_t setVideoSource(int vs) - { - ALOGV("setVideoSource(%d)", vs); - Parcel data, reply; - data.writeInterfaceToken(IMediaRecorder::getInterfaceDescriptor()); - data.writeInt32(vs); - remote()->transact(SET_VIDEO_SOURCE, data, &reply); - return reply.readInt32(); - } - - status_t setAudioSource(int as) - { - ALOGV("setAudioSource(%d)", as); - Parcel data, reply; - data.writeInterfaceToken(IMediaRecorder::getInterfaceDescriptor()); - data.writeInt32(as); - remote()->transact(SET_AUDIO_SOURCE, data, &reply); - return reply.readInt32(); - } - - status_t setOutputFormat(int of) - { - ALOGV("setOutputFormat(%d)", of); - Parcel data, reply; - data.writeInterfaceToken(IMediaRecorder::getInterfaceDescriptor()); - data.writeInt32(of); - remote()->transact(SET_OUTPUT_FORMAT, data, &reply); - return reply.readInt32(); - } - - status_t setVideoEncoder(int ve) - { - ALOGV("setVideoEncoder(%d)", ve); - Parcel data, reply; - data.writeInterfaceToken(IMediaRecorder::getInterfaceDescriptor()); - data.writeInt32(ve); - remote()->transact(SET_VIDEO_ENCODER, data, &reply); - return reply.readInt32(); - } - - status_t setAudioEncoder(int ae) - { - ALOGV("setAudioEncoder(%d)", ae); - Parcel data, reply; - data.writeInterfaceToken(IMediaRecorder::getInterfaceDescriptor()); - data.writeInt32(ae); - remote()->transact(SET_AUDIO_ENCODER, data, &reply); - return reply.readInt32(); - } - - status_t setOutputFile(const char* path) - { - ALOGV("setOutputFile(%s)", path); - Parcel data, reply; - data.writeInterfaceToken(IMediaRecorder::getInterfaceDescriptor()); - data.writeCString(path); - remote()->transact(SET_OUTPUT_FILE_PATH, data, &reply); - return reply.readInt32(); - } - - status_t setOutputFile(int fd, int64_t offset, int64_t length) { - ALOGV("setOutputFile(%d, %lld, %lld)", fd, offset, length); - Parcel data, reply; - data.writeInterfaceToken(IMediaRecorder::getInterfaceDescriptor()); - data.writeFileDescriptor(fd); - data.writeInt64(offset); - data.writeInt64(length); - remote()->transact(SET_OUTPUT_FILE_FD, data, &reply); - return reply.readInt32(); - } - - status_t setVideoSize(int width, int height) - { - ALOGV("setVideoSize(%dx%d)", width, height); - Parcel data, reply; - data.writeInterfaceToken(IMediaRecorder::getInterfaceDescriptor()); - data.writeInt32(width); - data.writeInt32(height); - remote()->transact(SET_VIDEO_SIZE, data, &reply); - return reply.readInt32(); - } - - status_t setVideoFrameRate(int frames_per_second) - { - ALOGV("setVideoFrameRate(%d)", frames_per_second); - Parcel data, reply; - data.writeInterfaceToken(IMediaRecorder::getInterfaceDescriptor()); - data.writeInt32(frames_per_second); - remote()->transact(SET_VIDEO_FRAMERATE, data, &reply); - return reply.readInt32(); - } - - status_t setParameters(const String8& params) - { - ALOGV("setParameter(%s)", params.string()); - Parcel data, reply; - data.writeInterfaceToken(IMediaRecorder::getInterfaceDescriptor()); - data.writeString8(params); - remote()->transact(SET_PARAMETERS, data, &reply); - return reply.readInt32(); - } - - status_t setListener(const sp<IMediaRecorderClient>& listener) - { - ALOGV("setListener(%p)", listener.get()); - Parcel data, reply; - data.writeInterfaceToken(IMediaRecorder::getInterfaceDescriptor()); - data.writeStrongBinder(listener->asBinder()); - remote()->transact(SET_LISTENER, data, &reply); - return reply.readInt32(); - } - - status_t prepare() - { - ALOGV("prepare"); - Parcel data, reply; - data.writeInterfaceToken(IMediaRecorder::getInterfaceDescriptor()); - remote()->transact(PREPARE, data, &reply); - return reply.readInt32(); - } - - status_t getMaxAmplitude(int* max) - { - ALOGV("getMaxAmplitude"); - Parcel data, reply; - data.writeInterfaceToken(IMediaRecorder::getInterfaceDescriptor()); - remote()->transact(GET_MAX_AMPLITUDE, data, &reply); - *max = reply.readInt32(); - return reply.readInt32(); - } - - status_t start() - { - ALOGV("start"); - Parcel data, reply; - data.writeInterfaceToken(IMediaRecorder::getInterfaceDescriptor()); - remote()->transact(START, data, &reply); - return reply.readInt32(); - } - - status_t stop() - { - ALOGV("stop"); - Parcel data, reply; - data.writeInterfaceToken(IMediaRecorder::getInterfaceDescriptor()); - remote()->transact(STOP, data, &reply); - return reply.readInt32(); - } - - status_t reset() - { - ALOGV("reset"); - Parcel data, reply; - data.writeInterfaceToken(IMediaRecorder::getInterfaceDescriptor()); - remote()->transact(RESET, data, &reply); - return reply.readInt32(); - } - - status_t close() - { - ALOGV("close"); - Parcel data, reply; - data.writeInterfaceToken(IMediaRecorder::getInterfaceDescriptor()); - remote()->transact(CLOSE, data, &reply); - return reply.readInt32(); - } - - status_t release() - { - ALOGV("release"); - Parcel data, reply; - data.writeInterfaceToken(IMediaRecorder::getInterfaceDescriptor()); - remote()->transact(RELEASE, data, &reply); - return reply.readInt32(); - } -}; - -IMPLEMENT_META_INTERFACE(MediaRecorder, "android.media.IMediaRecorder"); - -// ---------------------------------------------------------------------- - -status_t BnMediaRecorder::onTransact( - uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) -{ - switch (code) { - case RELEASE: { - ALOGV("RELEASE"); - CHECK_INTERFACE(IMediaRecorder, data, reply); - reply->writeInt32(release()); - return NO_ERROR; - } break; - case INIT: { - ALOGV("INIT"); - CHECK_INTERFACE(IMediaRecorder, data, reply); - reply->writeInt32(init()); - return NO_ERROR; - } break; - case CLOSE: { - ALOGV("CLOSE"); - CHECK_INTERFACE(IMediaRecorder, data, reply); - reply->writeInt32(close()); - return NO_ERROR; - } break; - case RESET: { - ALOGV("RESET"); - CHECK_INTERFACE(IMediaRecorder, data, reply); - reply->writeInt32(reset()); - return NO_ERROR; - } break; - case STOP: { - ALOGV("STOP"); - CHECK_INTERFACE(IMediaRecorder, data, reply); - reply->writeInt32(stop()); - return NO_ERROR; - } break; - case START: { - ALOGV("START"); - CHECK_INTERFACE(IMediaRecorder, data, reply); - reply->writeInt32(start()); - return NO_ERROR; - } break; - case PREPARE: { - ALOGV("PREPARE"); - CHECK_INTERFACE(IMediaRecorder, data, reply); - reply->writeInt32(prepare()); - return NO_ERROR; - } break; - case GET_MAX_AMPLITUDE: { - ALOGV("GET_MAX_AMPLITUDE"); - CHECK_INTERFACE(IMediaRecorder, data, reply); - int max = 0; - status_t ret = getMaxAmplitude(&max); - reply->writeInt32(max); - reply->writeInt32(ret); - return NO_ERROR; - } break; - case SET_VIDEO_SOURCE: { - ALOGV("SET_VIDEO_SOURCE"); - CHECK_INTERFACE(IMediaRecorder, data, reply); - int vs = data.readInt32(); - reply->writeInt32(setVideoSource(vs)); - return NO_ERROR; - } break; - case SET_AUDIO_SOURCE: { - ALOGV("SET_AUDIO_SOURCE"); - CHECK_INTERFACE(IMediaRecorder, data, reply); - int as = data.readInt32(); - reply->writeInt32(setAudioSource(as)); - return NO_ERROR; - } break; - case SET_OUTPUT_FORMAT: { - ALOGV("SET_OUTPUT_FORMAT"); - CHECK_INTERFACE(IMediaRecorder, data, reply); - int of = data.readInt32(); - reply->writeInt32(setOutputFormat(of)); - return NO_ERROR; - } break; - case SET_VIDEO_ENCODER: { - ALOGV("SET_VIDEO_ENCODER"); - CHECK_INTERFACE(IMediaRecorder, data, reply); - int ve = data.readInt32(); - reply->writeInt32(setVideoEncoder(ve)); - return NO_ERROR; - } break; - case SET_AUDIO_ENCODER: { - ALOGV("SET_AUDIO_ENCODER"); - CHECK_INTERFACE(IMediaRecorder, data, reply); - int ae = data.readInt32(); - reply->writeInt32(setAudioEncoder(ae)); - return NO_ERROR; - - } break; - case SET_OUTPUT_FILE_PATH: { - ALOGV("SET_OUTPUT_FILE_PATH"); - CHECK_INTERFACE(IMediaRecorder, data, reply); - const char* path = data.readCString(); - reply->writeInt32(setOutputFile(path)); - return NO_ERROR; - } break; - case SET_OUTPUT_FILE_FD: { - ALOGV("SET_OUTPUT_FILE_FD"); - CHECK_INTERFACE(IMediaRecorder, data, reply); - int fd = dup(data.readFileDescriptor()); - int64_t offset = data.readInt64(); - int64_t length = data.readInt64(); - reply->writeInt32(setOutputFile(fd, offset, length)); - ::close(fd); - return NO_ERROR; - } break; - case SET_VIDEO_SIZE: { - ALOGV("SET_VIDEO_SIZE"); - CHECK_INTERFACE(IMediaRecorder, data, reply); - int width = data.readInt32(); - int height = data.readInt32(); - reply->writeInt32(setVideoSize(width, height)); - return NO_ERROR; - } break; - case SET_VIDEO_FRAMERATE: { - ALOGV("SET_VIDEO_FRAMERATE"); - CHECK_INTERFACE(IMediaRecorder, data, reply); - int frames_per_second = data.readInt32(); - reply->writeInt32(setVideoFrameRate(frames_per_second)); - return NO_ERROR; - } break; - case SET_PARAMETERS: { - ALOGV("SET_PARAMETER"); - CHECK_INTERFACE(IMediaRecorder, data, reply); - reply->writeInt32(setParameters(data.readString8())); - return NO_ERROR; - } break; - case SET_LISTENER: { - ALOGV("SET_LISTENER"); - CHECK_INTERFACE(IMediaRecorder, data, reply); - sp<IMediaRecorderClient> listener = - interface_cast<IMediaRecorderClient>(data.readStrongBinder()); - reply->writeInt32(setListener(listener)); - return NO_ERROR; - } break; - case SET_PREVIEW_SURFACE: { - ALOGV("SET_PREVIEW_SURFACE"); - CHECK_INTERFACE(IMediaRecorder, data, reply); - sp<Surface> surface = Surface::readFromParcel(data); - reply->writeInt32(setPreviewSurface(surface)); - return NO_ERROR; - } break; - case SET_CAMERA: { - ALOGV("SET_CAMERA"); - CHECK_INTERFACE(IMediaRecorder, data, reply); - sp<ICamera> camera = interface_cast<ICamera>(data.readStrongBinder()); - sp<ICameraRecordingProxy> proxy = - interface_cast<ICameraRecordingProxy>(data.readStrongBinder()); - reply->writeInt32(setCamera(camera, proxy)); - return NO_ERROR; - } break; - case QUERY_SURFACE_MEDIASOURCE: { - ALOGV("QUERY_SURFACE_MEDIASOURCE"); - CHECK_INTERFACE(IMediaRecorder, data, reply); - // call the mediaserver side to create - // a surfacemediasource - sp<ISurfaceTexture> surfaceMediaSource = querySurfaceMediaSource(); - // The mediaserver might have failed to create a source - int returnedNull= (surfaceMediaSource == NULL) ? 1 : 0 ; - reply->writeInt32(returnedNull); - if (!returnedNull) { - reply->writeStrongBinder(surfaceMediaSource->asBinder()); - } - return NO_ERROR; - } break; - default: - return BBinder::onTransact(code, data, reply, flags); - } -} - -// ---------------------------------------------------------------------------- - -}; // namespace android diff --git a/media/libmedia/IMediaRecorderClient.cpp b/media/libmedia/IMediaRecorderClient.cpp deleted file mode 100644 index e7907e3..0000000 --- a/media/libmedia/IMediaRecorderClient.cpp +++ /dev/null @@ -1,70 +0,0 @@ -/* -** -** Copyright 2010, 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 <utils/RefBase.h> -#include <binder/IInterface.h> -#include <binder/Parcel.h> - -#include <media/IMediaRecorderClient.h> - -namespace android { - -enum { - NOTIFY = IBinder::FIRST_CALL_TRANSACTION, -}; - -class BpMediaRecorderClient: public BpInterface<IMediaRecorderClient> -{ -public: - BpMediaRecorderClient(const sp<IBinder>& impl) - : BpInterface<IMediaRecorderClient>(impl) - { - } - - virtual void notify(int msg, int ext1, int ext2) - { - Parcel data, reply; - data.writeInterfaceToken(IMediaRecorderClient::getInterfaceDescriptor()); - data.writeInt32(msg); - data.writeInt32(ext1); - data.writeInt32(ext2); - remote()->transact(NOTIFY, data, &reply, IBinder::FLAG_ONEWAY); - } -}; - -IMPLEMENT_META_INTERFACE(MediaRecorderClient, "android.media.IMediaRecorderClient"); - -// ---------------------------------------------------------------------- - -status_t BnMediaRecorderClient::onTransact( - uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) -{ - switch (code) { - case NOTIFY: { - CHECK_INTERFACE(IMediaRecorderClient, data, reply); - int msg = data.readInt32(); - int ext1 = data.readInt32(); - int ext2 = data.readInt32(); - notify(msg, ext1, ext2); - return NO_ERROR; - } break; - default: - return BBinder::onTransact(code, data, reply, flags); - } -} - -}; // namespace android diff --git a/media/libmedia/IOMX.cpp b/media/libmedia/IOMX.cpp deleted file mode 100644 index 48e427a..0000000 --- a/media/libmedia/IOMX.cpp +++ /dev/null @@ -1,788 +0,0 @@ -/* - * Copyright (c) 2009 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_NDEBUG 0 -#define LOG_TAG "IOMX" -#include <utils/Log.h> - -#include <binder/IMemory.h> -#include <binder/Parcel.h> -#include <media/IOMX.h> -#include <media/stagefright/foundation/ADebug.h> - -namespace android { - -enum { - CONNECT = IBinder::FIRST_CALL_TRANSACTION, - LIVES_LOCALLY, - LIST_NODES, - ALLOCATE_NODE, - FREE_NODE, - SEND_COMMAND, - GET_PARAMETER, - SET_PARAMETER, - GET_CONFIG, - SET_CONFIG, - GET_STATE, - ENABLE_GRAPHIC_BUFFERS, - USE_BUFFER, - USE_GRAPHIC_BUFFER, - STORE_META_DATA_IN_BUFFERS, - ALLOC_BUFFER, - ALLOC_BUFFER_WITH_BACKUP, - FREE_BUFFER, - FILL_BUFFER, - EMPTY_BUFFER, - GET_EXTENSION_INDEX, - OBSERVER_ON_MSG, - GET_GRAPHIC_BUFFER_USAGE, -}; - -class BpOMX : public BpInterface<IOMX> { -public: - BpOMX(const sp<IBinder> &impl) - : BpInterface<IOMX>(impl) { - } - - virtual bool livesLocally(node_id node, pid_t pid) { - Parcel data, reply; - data.writeInterfaceToken(IOMX::getInterfaceDescriptor()); - data.writeIntPtr((intptr_t)node); - data.writeInt32(pid); - remote()->transact(LIVES_LOCALLY, data, &reply); - - return reply.readInt32() != 0; - } - - virtual status_t listNodes(List<ComponentInfo> *list) { - list->clear(); - - Parcel data, reply; - data.writeInterfaceToken(IOMX::getInterfaceDescriptor()); - remote()->transact(LIST_NODES, data, &reply); - - int32_t n = reply.readInt32(); - for (int32_t i = 0; i < n; ++i) { - list->push_back(ComponentInfo()); - ComponentInfo &info = *--list->end(); - - info.mName = reply.readString8(); - int32_t numRoles = reply.readInt32(); - for (int32_t j = 0; j < numRoles; ++j) { - info.mRoles.push_back(reply.readString8()); - } - } - - return OK; - } - - virtual status_t allocateNode( - const char *name, const sp<IOMXObserver> &observer, node_id *node) { - Parcel data, reply; - data.writeInterfaceToken(IOMX::getInterfaceDescriptor()); - data.writeCString(name); - data.writeStrongBinder(observer->asBinder()); - remote()->transact(ALLOCATE_NODE, data, &reply); - - status_t err = reply.readInt32(); - if (err == OK) { - *node = (void*)reply.readIntPtr(); - } else { - *node = 0; - } - - return err; - } - - virtual status_t freeNode(node_id node) { - Parcel data, reply; - data.writeInterfaceToken(IOMX::getInterfaceDescriptor()); - data.writeIntPtr((intptr_t)node); - remote()->transact(FREE_NODE, data, &reply); - - return reply.readInt32(); - } - - virtual status_t sendCommand( - node_id node, OMX_COMMANDTYPE cmd, OMX_S32 param) { - Parcel data, reply; - data.writeInterfaceToken(IOMX::getInterfaceDescriptor()); - data.writeIntPtr((intptr_t)node); - data.writeInt32(cmd); - data.writeInt32(param); - remote()->transact(SEND_COMMAND, data, &reply); - - return reply.readInt32(); - } - - virtual status_t getParameter( - node_id node, OMX_INDEXTYPE index, - void *params, size_t size) { - Parcel data, reply; - data.writeInterfaceToken(IOMX::getInterfaceDescriptor()); - data.writeIntPtr((intptr_t)node); - data.writeInt32(index); - data.writeInt32(size); - data.write(params, size); - remote()->transact(GET_PARAMETER, data, &reply); - - status_t err = reply.readInt32(); - if (err != OK) { - return err; - } - - reply.read(params, size); - - return OK; - } - - virtual status_t setParameter( - node_id node, OMX_INDEXTYPE index, - const void *params, size_t size) { - Parcel data, reply; - data.writeInterfaceToken(IOMX::getInterfaceDescriptor()); - data.writeIntPtr((intptr_t)node); - data.writeInt32(index); - data.writeInt32(size); - data.write(params, size); - remote()->transact(SET_PARAMETER, data, &reply); - - return reply.readInt32(); - } - - virtual status_t getConfig( - node_id node, OMX_INDEXTYPE index, - void *params, size_t size) { - Parcel data, reply; - data.writeInterfaceToken(IOMX::getInterfaceDescriptor()); - data.writeIntPtr((intptr_t)node); - data.writeInt32(index); - data.writeInt32(size); - data.write(params, size); - remote()->transact(GET_CONFIG, data, &reply); - - status_t err = reply.readInt32(); - if (err != OK) { - return err; - } - - reply.read(params, size); - - return OK; - } - - virtual status_t setConfig( - node_id node, OMX_INDEXTYPE index, - const void *params, size_t size) { - Parcel data, reply; - data.writeInterfaceToken(IOMX::getInterfaceDescriptor()); - data.writeIntPtr((intptr_t)node); - data.writeInt32(index); - data.writeInt32(size); - data.write(params, size); - remote()->transact(SET_CONFIG, data, &reply); - - return reply.readInt32(); - } - - virtual status_t getState( - node_id node, OMX_STATETYPE* state) { - Parcel data, reply; - data.writeInterfaceToken(IOMX::getInterfaceDescriptor()); - data.writeIntPtr((intptr_t)node); - remote()->transact(GET_STATE, data, &reply); - - *state = static_cast<OMX_STATETYPE>(reply.readInt32()); - return reply.readInt32(); - } - - virtual status_t enableGraphicBuffers( - node_id node, OMX_U32 port_index, OMX_BOOL enable) { - Parcel data, reply; - data.writeInterfaceToken(IOMX::getInterfaceDescriptor()); - data.writeIntPtr((intptr_t)node); - data.writeInt32(port_index); - data.writeInt32((uint32_t)enable); - remote()->transact(ENABLE_GRAPHIC_BUFFERS, data, &reply); - - status_t err = reply.readInt32(); - return err; - } - - virtual status_t getGraphicBufferUsage( - node_id node, OMX_U32 port_index, OMX_U32* usage) { - Parcel data, reply; - data.writeInterfaceToken(IOMX::getInterfaceDescriptor()); - data.writeIntPtr((intptr_t)node); - data.writeInt32(port_index); - remote()->transact(GET_GRAPHIC_BUFFER_USAGE, data, &reply); - - status_t err = reply.readInt32(); - *usage = reply.readInt32(); - return err; - } - - virtual status_t useBuffer( - node_id node, OMX_U32 port_index, const sp<IMemory> ¶ms, - buffer_id *buffer) { - Parcel data, reply; - data.writeInterfaceToken(IOMX::getInterfaceDescriptor()); - data.writeIntPtr((intptr_t)node); - data.writeInt32(port_index); - data.writeStrongBinder(params->asBinder()); - remote()->transact(USE_BUFFER, data, &reply); - - status_t err = reply.readInt32(); - if (err != OK) { - *buffer = 0; - - return err; - } - - *buffer = (void*)reply.readIntPtr(); - - return err; - } - - - virtual status_t useGraphicBuffer( - node_id node, OMX_U32 port_index, - const sp<GraphicBuffer> &graphicBuffer, buffer_id *buffer) { - Parcel data, reply; - data.writeInterfaceToken(IOMX::getInterfaceDescriptor()); - data.writeIntPtr((intptr_t)node); - data.writeInt32(port_index); - data.write(*graphicBuffer); - remote()->transact(USE_GRAPHIC_BUFFER, data, &reply); - - status_t err = reply.readInt32(); - if (err != OK) { - *buffer = 0; - - return err; - } - - *buffer = (void*)reply.readIntPtr(); - - return err; - } - - virtual status_t storeMetaDataInBuffers( - node_id node, OMX_U32 port_index, OMX_BOOL enable) { - Parcel data, reply; - data.writeInterfaceToken(IOMX::getInterfaceDescriptor()); - data.writeIntPtr((intptr_t)node); - data.writeInt32(port_index); - data.writeInt32((uint32_t)enable); - remote()->transact(STORE_META_DATA_IN_BUFFERS, data, &reply); - - status_t err = reply.readInt32(); - return err; - } - - virtual status_t allocateBuffer( - node_id node, OMX_U32 port_index, size_t size, - buffer_id *buffer, void **buffer_data) { - Parcel data, reply; - data.writeInterfaceToken(IOMX::getInterfaceDescriptor()); - data.writeIntPtr((intptr_t)node); - data.writeInt32(port_index); - data.writeInt32(size); - remote()->transact(ALLOC_BUFFER, data, &reply); - - status_t err = reply.readInt32(); - if (err != OK) { - *buffer = 0; - - return err; - } - - *buffer = (void *)reply.readIntPtr(); - *buffer_data = (void *)reply.readIntPtr(); - - return err; - } - - virtual status_t allocateBufferWithBackup( - node_id node, OMX_U32 port_index, const sp<IMemory> ¶ms, - buffer_id *buffer) { - Parcel data, reply; - data.writeInterfaceToken(IOMX::getInterfaceDescriptor()); - data.writeIntPtr((intptr_t)node); - data.writeInt32(port_index); - data.writeStrongBinder(params->asBinder()); - remote()->transact(ALLOC_BUFFER_WITH_BACKUP, data, &reply); - - status_t err = reply.readInt32(); - if (err != OK) { - *buffer = 0; - - return err; - } - - *buffer = (void*)reply.readIntPtr(); - - return err; - } - - virtual status_t freeBuffer( - node_id node, OMX_U32 port_index, buffer_id buffer) { - Parcel data, reply; - data.writeInterfaceToken(IOMX::getInterfaceDescriptor()); - data.writeIntPtr((intptr_t)node); - data.writeInt32(port_index); - data.writeIntPtr((intptr_t)buffer); - remote()->transact(FREE_BUFFER, data, &reply); - - return reply.readInt32(); - } - - virtual status_t fillBuffer(node_id node, buffer_id buffer) { - Parcel data, reply; - data.writeInterfaceToken(IOMX::getInterfaceDescriptor()); - data.writeIntPtr((intptr_t)node); - data.writeIntPtr((intptr_t)buffer); - remote()->transact(FILL_BUFFER, data, &reply); - - return reply.readInt32(); - } - - virtual status_t emptyBuffer( - node_id node, - buffer_id buffer, - OMX_U32 range_offset, OMX_U32 range_length, - OMX_U32 flags, OMX_TICKS timestamp) { - Parcel data, reply; - data.writeInterfaceToken(IOMX::getInterfaceDescriptor()); - data.writeIntPtr((intptr_t)node); - data.writeIntPtr((intptr_t)buffer); - data.writeInt32(range_offset); - data.writeInt32(range_length); - data.writeInt32(flags); - data.writeInt64(timestamp); - remote()->transact(EMPTY_BUFFER, data, &reply); - - return reply.readInt32(); - } - - virtual status_t getExtensionIndex( - node_id node, - const char *parameter_name, - OMX_INDEXTYPE *index) { - Parcel data, reply; - data.writeInterfaceToken(IOMX::getInterfaceDescriptor()); - data.writeIntPtr((intptr_t)node); - data.writeCString(parameter_name); - - remote()->transact(GET_EXTENSION_INDEX, data, &reply); - - status_t err = reply.readInt32(); - if (err == OK) { - *index = static_cast<OMX_INDEXTYPE>(reply.readInt32()); - } else { - *index = OMX_IndexComponentStartUnused; - } - - return err; - } -}; - -IMPLEMENT_META_INTERFACE(OMX, "android.hardware.IOMX"); - -//////////////////////////////////////////////////////////////////////////////// - -#define CHECK_INTERFACE(interface, data, reply) \ - do { if (!data.enforceInterface(interface::getInterfaceDescriptor())) { \ - ALOGW("Call incorrectly routed to " #interface); \ - return PERMISSION_DENIED; \ - } } while (0) - -status_t BnOMX::onTransact( - uint32_t code, const Parcel &data, Parcel *reply, uint32_t flags) { - switch (code) { - case LIVES_LOCALLY: - { - CHECK_INTERFACE(IOMX, data, reply); - node_id node = (void *)data.readIntPtr(); - pid_t pid = (pid_t)data.readInt32(); - reply->writeInt32(livesLocally(node, pid)); - - return OK; - } - - case LIST_NODES: - { - CHECK_INTERFACE(IOMX, data, reply); - - List<ComponentInfo> list; - listNodes(&list); - - reply->writeInt32(list.size()); - for (List<ComponentInfo>::iterator it = list.begin(); - it != list.end(); ++it) { - ComponentInfo &cur = *it; - - reply->writeString8(cur.mName); - reply->writeInt32(cur.mRoles.size()); - for (List<String8>::iterator role_it = cur.mRoles.begin(); - role_it != cur.mRoles.end(); ++role_it) { - reply->writeString8(*role_it); - } - } - - return NO_ERROR; - } - - case ALLOCATE_NODE: - { - CHECK_INTERFACE(IOMX, data, reply); - - const char *name = data.readCString(); - - sp<IOMXObserver> observer = - interface_cast<IOMXObserver>(data.readStrongBinder()); - - node_id node; - - status_t err = allocateNode(name, observer, &node); - reply->writeInt32(err); - if (err == OK) { - reply->writeIntPtr((intptr_t)node); - } - - return NO_ERROR; - } - - case FREE_NODE: - { - CHECK_INTERFACE(IOMX, data, reply); - - node_id node = (void*)data.readIntPtr(); - - reply->writeInt32(freeNode(node)); - - return NO_ERROR; - } - - case SEND_COMMAND: - { - CHECK_INTERFACE(IOMX, data, reply); - - node_id node = (void*)data.readIntPtr(); - - OMX_COMMANDTYPE cmd = - static_cast<OMX_COMMANDTYPE>(data.readInt32()); - - OMX_S32 param = data.readInt32(); - reply->writeInt32(sendCommand(node, cmd, param)); - - return NO_ERROR; - } - - case GET_PARAMETER: - case SET_PARAMETER: - case GET_CONFIG: - case SET_CONFIG: - { - CHECK_INTERFACE(IOMX, data, reply); - - node_id node = (void*)data.readIntPtr(); - OMX_INDEXTYPE index = static_cast<OMX_INDEXTYPE>(data.readInt32()); - - size_t size = data.readInt32(); - - void *params = malloc(size); - data.read(params, size); - - status_t err; - switch (code) { - case GET_PARAMETER: - err = getParameter(node, index, params, size); - break; - case SET_PARAMETER: - err = setParameter(node, index, params, size); - break; - case GET_CONFIG: - err = getConfig(node, index, params, size); - break; - case SET_CONFIG: - err = setConfig(node, index, params, size); - break; - default: - TRESPASS(); - } - - reply->writeInt32(err); - - if ((code == GET_PARAMETER || code == GET_CONFIG) && err == OK) { - reply->write(params, size); - } - - free(params); - params = NULL; - - return NO_ERROR; - } - - case GET_STATE: - { - CHECK_INTERFACE(IOMX, data, reply); - - node_id node = (void*)data.readIntPtr(); - OMX_STATETYPE state = OMX_StateInvalid; - - status_t err = getState(node, &state); - reply->writeInt32(state); - reply->writeInt32(err); - - return NO_ERROR; - } - - case ENABLE_GRAPHIC_BUFFERS: - { - CHECK_INTERFACE(IOMX, data, reply); - - node_id node = (void*)data.readIntPtr(); - OMX_U32 port_index = data.readInt32(); - OMX_BOOL enable = (OMX_BOOL)data.readInt32(); - - status_t err = enableGraphicBuffers(node, port_index, enable); - reply->writeInt32(err); - - return NO_ERROR; - } - - case GET_GRAPHIC_BUFFER_USAGE: - { - CHECK_INTERFACE(IOMX, data, reply); - - node_id node = (void*)data.readIntPtr(); - OMX_U32 port_index = data.readInt32(); - - OMX_U32 usage = 0; - status_t err = getGraphicBufferUsage(node, port_index, &usage); - reply->writeInt32(err); - reply->writeInt32(usage); - - return NO_ERROR; - } - - case USE_BUFFER: - { - CHECK_INTERFACE(IOMX, data, reply); - - node_id node = (void*)data.readIntPtr(); - OMX_U32 port_index = data.readInt32(); - sp<IMemory> params = - interface_cast<IMemory>(data.readStrongBinder()); - - buffer_id buffer; - status_t err = useBuffer(node, port_index, params, &buffer); - reply->writeInt32(err); - - if (err == OK) { - reply->writeIntPtr((intptr_t)buffer); - } - - return NO_ERROR; - } - - case USE_GRAPHIC_BUFFER: - { - CHECK_INTERFACE(IOMX, data, reply); - - node_id node = (void*)data.readIntPtr(); - OMX_U32 port_index = data.readInt32(); - sp<GraphicBuffer> graphicBuffer = new GraphicBuffer(); - data.read(*graphicBuffer); - - buffer_id buffer; - status_t err = useGraphicBuffer( - node, port_index, graphicBuffer, &buffer); - reply->writeInt32(err); - - if (err == OK) { - reply->writeIntPtr((intptr_t)buffer); - } - - return NO_ERROR; - } - - case STORE_META_DATA_IN_BUFFERS: - { - CHECK_INTERFACE(IOMX, data, reply); - - node_id node = (void*)data.readIntPtr(); - OMX_U32 port_index = data.readInt32(); - OMX_BOOL enable = (OMX_BOOL)data.readInt32(); - - status_t err = storeMetaDataInBuffers(node, port_index, enable); - reply->writeInt32(err); - - return NO_ERROR; - } - - case ALLOC_BUFFER: - { - CHECK_INTERFACE(IOMX, data, reply); - - node_id node = (void*)data.readIntPtr(); - OMX_U32 port_index = data.readInt32(); - size_t size = data.readInt32(); - - buffer_id buffer; - void *buffer_data; - status_t err = allocateBuffer( - node, port_index, size, &buffer, &buffer_data); - reply->writeInt32(err); - - if (err == OK) { - reply->writeIntPtr((intptr_t)buffer); - reply->writeIntPtr((intptr_t)buffer_data); - } - - return NO_ERROR; - } - - case ALLOC_BUFFER_WITH_BACKUP: - { - CHECK_INTERFACE(IOMX, data, reply); - - node_id node = (void*)data.readIntPtr(); - OMX_U32 port_index = data.readInt32(); - sp<IMemory> params = - interface_cast<IMemory>(data.readStrongBinder()); - - buffer_id buffer; - status_t err = allocateBufferWithBackup( - node, port_index, params, &buffer); - - reply->writeInt32(err); - - if (err == OK) { - reply->writeIntPtr((intptr_t)buffer); - } - - return NO_ERROR; - } - - case FREE_BUFFER: - { - CHECK_INTERFACE(IOMX, data, reply); - - node_id node = (void*)data.readIntPtr(); - OMX_U32 port_index = data.readInt32(); - buffer_id buffer = (void*)data.readIntPtr(); - reply->writeInt32(freeBuffer(node, port_index, buffer)); - - return NO_ERROR; - } - - case FILL_BUFFER: - { - CHECK_INTERFACE(IOMX, data, reply); - - node_id node = (void*)data.readIntPtr(); - buffer_id buffer = (void*)data.readIntPtr(); - reply->writeInt32(fillBuffer(node, buffer)); - - return NO_ERROR; - } - - case EMPTY_BUFFER: - { - CHECK_INTERFACE(IOMX, data, reply); - - node_id node = (void*)data.readIntPtr(); - buffer_id buffer = (void*)data.readIntPtr(); - OMX_U32 range_offset = data.readInt32(); - OMX_U32 range_length = data.readInt32(); - OMX_U32 flags = data.readInt32(); - OMX_TICKS timestamp = data.readInt64(); - - reply->writeInt32( - emptyBuffer( - node, buffer, range_offset, range_length, - flags, timestamp)); - - return NO_ERROR; - } - - case GET_EXTENSION_INDEX: - { - CHECK_INTERFACE(IOMX, data, reply); - - node_id node = (void*)data.readIntPtr(); - const char *parameter_name = data.readCString(); - - OMX_INDEXTYPE index; - status_t err = getExtensionIndex(node, parameter_name, &index); - - reply->writeInt32(err); - - if (err == OK) { - reply->writeInt32(index); - } - - return OK; - } - - default: - return BBinder::onTransact(code, data, reply, flags); - } -} - -//////////////////////////////////////////////////////////////////////////////// - -class BpOMXObserver : public BpInterface<IOMXObserver> { -public: - BpOMXObserver(const sp<IBinder> &impl) - : BpInterface<IOMXObserver>(impl) { - } - - virtual void onMessage(const omx_message &msg) { - Parcel data, reply; - data.writeInterfaceToken(IOMXObserver::getInterfaceDescriptor()); - data.write(&msg, sizeof(msg)); - - remote()->transact(OBSERVER_ON_MSG, data, &reply, IBinder::FLAG_ONEWAY); - } -}; - -IMPLEMENT_META_INTERFACE(OMXObserver, "android.hardware.IOMXObserver"); - -status_t BnOMXObserver::onTransact( - uint32_t code, const Parcel &data, Parcel *reply, uint32_t flags) { - switch (code) { - case OBSERVER_ON_MSG: - { - CHECK_INTERFACE(IOMXObserver, data, reply); - - omx_message msg; - data.read(&msg, sizeof(msg)); - - // XXX Could use readInplace maybe? - onMessage(msg); - - return NO_ERROR; - } - - default: - return BBinder::onTransact(code, data, reply, flags); - } -} - -} // namespace android diff --git a/media/libmedia/IStreamSource.cpp b/media/libmedia/IStreamSource.cpp deleted file mode 100644 index 078be94..0000000 --- a/media/libmedia/IStreamSource.cpp +++ /dev/null @@ -1,192 +0,0 @@ -/* - * Copyright (C) 2010 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_NDEBUG 0 -#define LOG_TAG "IStreamSource" -#include <utils/Log.h> - -#include <media/IStreamSource.h> -#include <media/stagefright/foundation/AMessage.h> - -#include <binder/IMemory.h> -#include <binder/Parcel.h> - -namespace android { - -// static -const char *const IStreamListener::kKeyResumeAtPTS = "resume-at-PTS"; - -// static -const char *const IStreamListener::kKeyDiscontinuityMask = "discontinuity-mask"; - -enum { - // IStreamSource - SET_LISTENER = IBinder::FIRST_CALL_TRANSACTION, - SET_BUFFERS, - ON_BUFFER_AVAILABLE, - - // IStreamListener - QUEUE_BUFFER, - ISSUE_COMMAND, -}; - -struct BpStreamSource : public BpInterface<IStreamSource> { - BpStreamSource(const sp<IBinder> &impl) - : BpInterface<IStreamSource>(impl) { - } - - virtual void setListener(const sp<IStreamListener> &listener) { - Parcel data, reply; - data.writeInterfaceToken(IStreamSource::getInterfaceDescriptor()); - data.writeStrongBinder(listener->asBinder()); - remote()->transact(SET_LISTENER, data, &reply); - } - - virtual void setBuffers(const Vector<sp<IMemory> > &buffers) { - Parcel data, reply; - data.writeInterfaceToken(IStreamSource::getInterfaceDescriptor()); - data.writeInt32(static_cast<int32_t>(buffers.size())); - for (size_t i = 0; i < buffers.size(); ++i) { - data.writeStrongBinder(buffers.itemAt(i)->asBinder()); - } - remote()->transact(SET_BUFFERS, data, &reply); - } - - virtual void onBufferAvailable(size_t index) { - Parcel data, reply; - data.writeInterfaceToken(IStreamSource::getInterfaceDescriptor()); - data.writeInt32(static_cast<int32_t>(index)); - remote()->transact( - ON_BUFFER_AVAILABLE, data, &reply, IBinder::FLAG_ONEWAY); - } -}; - -IMPLEMENT_META_INTERFACE(StreamSource, "android.hardware.IStreamSource"); - -status_t BnStreamSource::onTransact( - uint32_t code, const Parcel &data, Parcel *reply, uint32_t flags) { - switch (code) { - case SET_LISTENER: - { - CHECK_INTERFACE(IStreamSource, data, reply); - setListener( - interface_cast<IStreamListener>(data.readStrongBinder())); - break; - } - - case SET_BUFFERS: - { - CHECK_INTERFACE(IStreamSource, data, reply); - size_t n = static_cast<size_t>(data.readInt32()); - Vector<sp<IMemory> > buffers; - for (size_t i = 0; i < n; ++i) { - sp<IMemory> mem = - interface_cast<IMemory>(data.readStrongBinder()); - - buffers.push(mem); - } - setBuffers(buffers); - break; - } - - case ON_BUFFER_AVAILABLE: - { - CHECK_INTERFACE(IStreamSource, data, reply); - onBufferAvailable(static_cast<size_t>(data.readInt32())); - break; - } - - default: - return BBinder::onTransact(code, data, reply, flags); - } - - return OK; -} - -//////////////////////////////////////////////////////////////////////////////// - -struct BpStreamListener : public BpInterface<IStreamListener> { - BpStreamListener(const sp<IBinder> &impl) - : BpInterface<IStreamListener>(impl) { - } - - virtual void queueBuffer(size_t index, size_t size) { - Parcel data, reply; - data.writeInterfaceToken(IStreamListener::getInterfaceDescriptor()); - data.writeInt32(static_cast<int32_t>(index)); - data.writeInt32(static_cast<int32_t>(size)); - - remote()->transact(QUEUE_BUFFER, data, &reply, IBinder::FLAG_ONEWAY); - } - - virtual void issueCommand( - Command cmd, bool synchronous, const sp<AMessage> &msg) { - Parcel data, reply; - data.writeInterfaceToken(IStreamListener::getInterfaceDescriptor()); - data.writeInt32(static_cast<int32_t>(cmd)); - data.writeInt32(static_cast<int32_t>(synchronous)); - - if (msg != NULL) { - data.writeInt32(1); - msg->writeToParcel(&data); - } else { - data.writeInt32(0); - } - - remote()->transact(ISSUE_COMMAND, data, &reply, IBinder::FLAG_ONEWAY); - } -}; - -IMPLEMENT_META_INTERFACE(StreamListener, "android.hardware.IStreamListener"); - -status_t BnStreamListener::onTransact( - uint32_t code, const Parcel &data, Parcel *reply, uint32_t flags) { - switch (code) { - case QUEUE_BUFFER: - { - CHECK_INTERFACE(IStreamListener, data, reply); - size_t index = static_cast<size_t>(data.readInt32()); - size_t size = static_cast<size_t>(data.readInt32()); - - queueBuffer(index, size); - break; - } - - case ISSUE_COMMAND: - { - CHECK_INTERFACE(IStreamListener, data, reply); - Command cmd = static_cast<Command>(data.readInt32()); - - bool synchronous = static_cast<bool>(data.readInt32()); - - sp<AMessage> msg; - - if (data.readInt32()) { - msg = AMessage::FromParcel(data); - } - - issueCommand(cmd, synchronous, msg); - break; - } - - default: - return BBinder::onTransact(code, data, reply, flags); - } - - return OK; -} - -} // namespace android diff --git a/media/libmedia/JetPlayer.cpp b/media/libmedia/JetPlayer.cpp deleted file mode 100644 index 52aee49..0000000 --- a/media/libmedia/JetPlayer.cpp +++ /dev/null @@ -1,480 +0,0 @@ -/* - * Copyright (C) 2008 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_NDEBUG 0 -#define LOG_TAG "JetPlayer-C" - -#include <utils/Log.h> -#include <utils/threads.h> - -#include <media/JetPlayer.h> - - -namespace android -{ - -static const int MIX_NUM_BUFFERS = 4; -static const S_EAS_LIB_CONFIG* pLibConfig = NULL; - -//------------------------------------------------------------------------------------------------- -JetPlayer::JetPlayer(void *javaJetPlayer, int maxTracks, int trackBufferSize) : - mEventCallback(NULL), - mJavaJetPlayerRef(javaJetPlayer), - mTid(-1), - mRender(false), - mPaused(false), - mMaxTracks(maxTracks), - mEasData(NULL), - mEasJetFileLoc(NULL), - mAudioTrack(NULL), - mTrackBufferSize(trackBufferSize) -{ - ALOGV("JetPlayer constructor"); - mPreviousJetStatus.currentUserID = -1; - mPreviousJetStatus.segmentRepeatCount = -1; - mPreviousJetStatus.numQueuedSegments = -1; - mPreviousJetStatus.paused = true; -} - -//------------------------------------------------------------------------------------------------- -JetPlayer::~JetPlayer() -{ - ALOGV("~JetPlayer"); - release(); - -} - -//------------------------------------------------------------------------------------------------- -int JetPlayer::init() -{ - //Mutex::Autolock lock(&mMutex); - - EAS_RESULT result; - - // retrieve the EAS library settings - if (pLibConfig == NULL) - pLibConfig = EAS_Config(); - if (pLibConfig == NULL) { - ALOGE("JetPlayer::init(): EAS library configuration could not be retrieved, aborting."); - return EAS_FAILURE; - } - - // init the EAS library - result = EAS_Init(&mEasData); - if (result != EAS_SUCCESS) { - ALOGE("JetPlayer::init(): Error initializing Sonivox EAS library, aborting."); - mState = EAS_STATE_ERROR; - return result; - } - // init the JET library with the default app event controller range - result = JET_Init(mEasData, NULL, sizeof(S_JET_CONFIG)); - if (result != EAS_SUCCESS) { - ALOGE("JetPlayer::init(): Error initializing JET library, aborting."); - mState = EAS_STATE_ERROR; - return result; - } - - // create the output AudioTrack - mAudioTrack = new AudioTrack(); - mAudioTrack->set(AUDIO_STREAM_MUSIC, //TODO parameterize this - pLibConfig->sampleRate, - AUDIO_FORMAT_PCM_16_BIT, - audio_channel_out_mask_from_count(pLibConfig->numChannels), - mTrackBufferSize, - AUDIO_POLICY_OUTPUT_FLAG_NONE); - - // create render and playback thread - { - Mutex::Autolock l(mMutex); - ALOGV("JetPlayer::init(): trying to start render thread"); - mThread = new JetPlayerThread(this); - mThread->run("jetRenderThread", ANDROID_PRIORITY_AUDIO); - mCondition.wait(mMutex); - } - if (mTid > 0) { - // render thread started, we're ready - ALOGV("JetPlayer::init(): render thread(%d) successfully started.", mTid); - mState = EAS_STATE_READY; - } else { - ALOGE("JetPlayer::init(): failed to start render thread."); - mState = EAS_STATE_ERROR; - return EAS_FAILURE; - } - - return EAS_SUCCESS; -} - -void JetPlayer::setEventCallback(jetevent_callback eventCallback) -{ - Mutex::Autolock l(mMutex); - mEventCallback = eventCallback; -} - -//------------------------------------------------------------------------------------------------- -int JetPlayer::release() -{ - ALOGV("JetPlayer::release()"); - Mutex::Autolock lock(mMutex); - mPaused = true; - mRender = false; - if (mEasData) { - JET_Pause(mEasData); - JET_CloseFile(mEasData); - JET_Shutdown(mEasData); - EAS_Shutdown(mEasData); - } - if (mEasJetFileLoc) { - free(mEasJetFileLoc); - mEasJetFileLoc = NULL; - } - if (mAudioTrack) { - mAudioTrack->stop(); - mAudioTrack->flush(); - delete mAudioTrack; - mAudioTrack = NULL; - } - if (mAudioBuffer) { - delete mAudioBuffer; - mAudioBuffer = NULL; - } - mEasData = NULL; - - return EAS_SUCCESS; -} - - -//------------------------------------------------------------------------------------------------- -int JetPlayer::render() { - EAS_RESULT result = EAS_FAILURE; - EAS_I32 count; - int temp; - bool audioStarted = false; - - ALOGV("JetPlayer::render(): entering"); - - // allocate render buffer - mAudioBuffer = - new EAS_PCM[pLibConfig->mixBufferSize * pLibConfig->numChannels * MIX_NUM_BUFFERS]; - - // signal main thread that we started - { - Mutex::Autolock l(mMutex); - mTid = gettid(); - ALOGV("JetPlayer::render(): render thread(%d) signal", mTid); - mCondition.signal(); - } - - while (1) { - - mMutex.lock(); // [[[[[[[[ LOCK --------------------------------------- - - if (mEasData == NULL) { - mMutex.unlock(); - ALOGV("JetPlayer::render(): NULL EAS data, exiting render."); - goto threadExit; - } - - // nothing to render, wait for client thread to wake us up - while (!mRender) - { - ALOGV("JetPlayer::render(): signal wait"); - if (audioStarted) { - mAudioTrack->pause(); - // we have to restart the playback once we start rendering again - audioStarted = false; - } - mCondition.wait(mMutex); - ALOGV("JetPlayer::render(): signal rx'd"); - } - - // render midi data into the input buffer - int num_output = 0; - EAS_PCM* p = mAudioBuffer; - for (int i = 0; i < MIX_NUM_BUFFERS; i++) { - result = EAS_Render(mEasData, p, pLibConfig->mixBufferSize, &count); - if (result != EAS_SUCCESS) { - ALOGE("JetPlayer::render(): EAS_Render returned error %ld", result); - } - p += count * pLibConfig->numChannels; - num_output += count * pLibConfig->numChannels * sizeof(EAS_PCM); - - // send events that were generated (if any) to the event callback - fireEventsFromJetQueue(); - } - - // update playback state - //ALOGV("JetPlayer::render(): updating state"); - JET_Status(mEasData, &mJetStatus); - fireUpdateOnStatusChange(); - mPaused = mJetStatus.paused; - - mMutex.unlock(); // UNLOCK ]]]]]]]] ----------------------------------- - - // check audio output track - if (mAudioTrack == NULL) { - ALOGE("JetPlayer::render(): output AudioTrack was not created"); - goto threadExit; - } - - // Write data to the audio hardware - //ALOGV("JetPlayer::render(): writing to audio output"); - if ((temp = mAudioTrack->write(mAudioBuffer, num_output)) < 0) { - ALOGE("JetPlayer::render(): Error in writing:%d",temp); - return temp; - } - - // start audio output if necessary - if (!audioStarted) { - ALOGV("JetPlayer::render(): starting audio playback"); - mAudioTrack->start(); - audioStarted = true; - } - - }//while (1) - -threadExit: - if (mAudioTrack != NULL) { - mAudioTrack->stop(); - mAudioTrack->flush(); - } - delete [] mAudioBuffer; - mAudioBuffer = NULL; - mMutex.lock(); - mTid = -1; - mCondition.signal(); - mMutex.unlock(); - return result; -} - - -//------------------------------------------------------------------------------------------------- -// fire up an update if any of the status fields has changed -// precondition: mMutex locked -void JetPlayer::fireUpdateOnStatusChange() -{ - if ( (mJetStatus.currentUserID != mPreviousJetStatus.currentUserID) - ||(mJetStatus.segmentRepeatCount != mPreviousJetStatus.segmentRepeatCount) ) { - if (mEventCallback) { - mEventCallback( - JetPlayer::JET_USERID_UPDATE, - mJetStatus.currentUserID, - mJetStatus.segmentRepeatCount, - mJavaJetPlayerRef); - } - mPreviousJetStatus.currentUserID = mJetStatus.currentUserID; - mPreviousJetStatus.segmentRepeatCount = mJetStatus.segmentRepeatCount; - } - - if (mJetStatus.numQueuedSegments != mPreviousJetStatus.numQueuedSegments) { - if (mEventCallback) { - mEventCallback( - JetPlayer::JET_NUMQUEUEDSEGMENT_UPDATE, - mJetStatus.numQueuedSegments, - -1, - mJavaJetPlayerRef); - } - mPreviousJetStatus.numQueuedSegments = mJetStatus.numQueuedSegments; - } - - if (mJetStatus.paused != mPreviousJetStatus.paused) { - if (mEventCallback) { - mEventCallback(JetPlayer::JET_PAUSE_UPDATE, - mJetStatus.paused, - -1, - mJavaJetPlayerRef); - } - mPreviousJetStatus.paused = mJetStatus.paused; - } - -} - - -//------------------------------------------------------------------------------------------------- -// fire up all the JET events in the JET engine queue (until the queue is empty) -// precondition: mMutex locked -void JetPlayer::fireEventsFromJetQueue() -{ - if (!mEventCallback) { - // no callback, just empty the event queue - while (JET_GetEvent(mEasData, NULL, NULL)) { } - return; - } - - EAS_U32 rawEvent; - while (JET_GetEvent(mEasData, &rawEvent, NULL)) { - mEventCallback( - JetPlayer::JET_EVENT, - rawEvent, - -1, - mJavaJetPlayerRef); - } -} - - -//------------------------------------------------------------------------------------------------- -int JetPlayer::loadFromFile(const char* path) -{ - ALOGV("JetPlayer::loadFromFile(): path=%s", path); - - Mutex::Autolock lock(mMutex); - - mEasJetFileLoc = (EAS_FILE_LOCATOR) malloc(sizeof(EAS_FILE)); - strncpy(mJetFilePath, path, sizeof(mJetFilePath)); - mJetFilePath[sizeof(mJetFilePath) - 1] = '\0'; - mEasJetFileLoc->path = mJetFilePath; - - mEasJetFileLoc->fd = 0; - mEasJetFileLoc->length = 0; - mEasJetFileLoc->offset = 0; - - EAS_RESULT result = JET_OpenFile(mEasData, mEasJetFileLoc); - if (result != EAS_SUCCESS) - mState = EAS_STATE_ERROR; - else - mState = EAS_STATE_OPEN; - return( result ); -} - - -//------------------------------------------------------------------------------------------------- -int JetPlayer::loadFromFD(const int fd, const long long offset, const long long length) -{ - ALOGV("JetPlayer::loadFromFD(): fd=%d offset=%lld length=%lld", fd, offset, length); - - Mutex::Autolock lock(mMutex); - - mEasJetFileLoc = (EAS_FILE_LOCATOR) malloc(sizeof(EAS_FILE)); - mEasJetFileLoc->fd = fd; - mEasJetFileLoc->offset = offset; - mEasJetFileLoc->length = length; - mEasJetFileLoc->path = NULL; - - EAS_RESULT result = JET_OpenFile(mEasData, mEasJetFileLoc); - if (result != EAS_SUCCESS) - mState = EAS_STATE_ERROR; - else - mState = EAS_STATE_OPEN; - return( result ); -} - - -//------------------------------------------------------------------------------------------------- -int JetPlayer::closeFile() -{ - Mutex::Autolock lock(mMutex); - return JET_CloseFile(mEasData); -} - - -//------------------------------------------------------------------------------------------------- -int JetPlayer::play() -{ - ALOGV("JetPlayer::play(): entering"); - Mutex::Autolock lock(mMutex); - - EAS_RESULT result = JET_Play(mEasData); - - mPaused = false; - mRender = true; - - JET_Status(mEasData, &mJetStatus); - this->dumpJetStatus(&mJetStatus); - - fireUpdateOnStatusChange(); - - // wake up render thread - ALOGV("JetPlayer::play(): wakeup render thread"); - mCondition.signal(); - - return result; -} - -//------------------------------------------------------------------------------------------------- -int JetPlayer::pause() -{ - Mutex::Autolock lock(mMutex); - mPaused = true; - EAS_RESULT result = JET_Pause(mEasData); - - mRender = false; - - JET_Status(mEasData, &mJetStatus); - this->dumpJetStatus(&mJetStatus); - fireUpdateOnStatusChange(); - - - return result; -} - - -//------------------------------------------------------------------------------------------------- -int JetPlayer::queueSegment(int segmentNum, int libNum, int repeatCount, int transpose, - EAS_U32 muteFlags, EAS_U8 userID) -{ - ALOGV("JetPlayer::queueSegment segmentNum=%d, libNum=%d, repeatCount=%d, transpose=%d", - segmentNum, libNum, repeatCount, transpose); - Mutex::Autolock lock(mMutex); - return JET_QueueSegment(mEasData, segmentNum, libNum, repeatCount, transpose, muteFlags, userID); -} - -//------------------------------------------------------------------------------------------------- -int JetPlayer::setMuteFlags(EAS_U32 muteFlags, bool sync) -{ - Mutex::Autolock lock(mMutex); - return JET_SetMuteFlags(mEasData, muteFlags, sync); -} - -//------------------------------------------------------------------------------------------------- -int JetPlayer::setMuteFlag(int trackNum, bool muteFlag, bool sync) -{ - Mutex::Autolock lock(mMutex); - return JET_SetMuteFlag(mEasData, trackNum, muteFlag, sync); -} - -//------------------------------------------------------------------------------------------------- -int JetPlayer::triggerClip(int clipId) -{ - ALOGV("JetPlayer::triggerClip clipId=%d", clipId); - Mutex::Autolock lock(mMutex); - return JET_TriggerClip(mEasData, clipId); -} - -//------------------------------------------------------------------------------------------------- -int JetPlayer::clearQueue() -{ - ALOGV("JetPlayer::clearQueue"); - Mutex::Autolock lock(mMutex); - return JET_Clear_Queue(mEasData); -} - -//------------------------------------------------------------------------------------------------- -void JetPlayer::dump() -{ - ALOGE("JetPlayer dump: JET file=%s", mEasJetFileLoc->path); -} - -void JetPlayer::dumpJetStatus(S_JET_STATUS* pJetStatus) -{ - if (pJetStatus!=NULL) - ALOGV(">> current JET player status: userID=%d segmentRepeatCount=%d numQueuedSegments=%d paused=%d", - pJetStatus->currentUserID, pJetStatus->segmentRepeatCount, - pJetStatus->numQueuedSegments, pJetStatus->paused); - else - ALOGE(">> JET player status is NULL"); -} - - -} // end namespace android diff --git a/media/libmedia/MODULE_LICENSE_APACHE2 b/media/libmedia/MODULE_LICENSE_APACHE2 deleted file mode 100644 index e69de29..0000000 --- a/media/libmedia/MODULE_LICENSE_APACHE2 +++ /dev/null diff --git a/media/libmedia/MediaProfiles.cpp b/media/libmedia/MediaProfiles.cpp deleted file mode 100644 index c224f06..0000000 --- a/media/libmedia/MediaProfiles.cpp +++ /dev/null @@ -1,1182 +0,0 @@ -/* -** -** Copyright 2010, 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_NDEBUG 0 -#define LOG_TAG "MediaProfiles" - -#include <stdlib.h> -#include <utils/Log.h> -#include <utils/Vector.h> -#include <cutils/properties.h> -#include <expat.h> -#include <media/MediaProfiles.h> -#include <media/stagefright/foundation/ADebug.h> -#include <OMX_Video.h> - -namespace android { - -Mutex MediaProfiles::sLock; -bool MediaProfiles::sIsInitialized = false; -MediaProfiles *MediaProfiles::sInstance = NULL; - -const MediaProfiles::NameToTagMap MediaProfiles::sVideoEncoderNameMap[] = { - {"h263", VIDEO_ENCODER_H263}, - {"h264", VIDEO_ENCODER_H264}, - {"m4v", VIDEO_ENCODER_MPEG_4_SP} -}; - -const MediaProfiles::NameToTagMap MediaProfiles::sAudioEncoderNameMap[] = { - {"amrnb", AUDIO_ENCODER_AMR_NB}, - {"amrwb", AUDIO_ENCODER_AMR_WB}, - {"aac", AUDIO_ENCODER_AAC}, -}; - -const MediaProfiles::NameToTagMap MediaProfiles::sFileFormatMap[] = { - {"3gp", OUTPUT_FORMAT_THREE_GPP}, - {"mp4", OUTPUT_FORMAT_MPEG_4} -}; - -const MediaProfiles::NameToTagMap MediaProfiles::sVideoDecoderNameMap[] = { - {"wmv", VIDEO_DECODER_WMV} -}; - -const MediaProfiles::NameToTagMap MediaProfiles::sAudioDecoderNameMap[] = { - {"wma", AUDIO_DECODER_WMA} -}; - -const MediaProfiles::NameToTagMap MediaProfiles::sCamcorderQualityNameMap[] = { - {"low", CAMCORDER_QUALITY_LOW}, - {"high", CAMCORDER_QUALITY_HIGH}, - {"qcif", CAMCORDER_QUALITY_QCIF}, - {"cif", CAMCORDER_QUALITY_CIF}, - {"480p", CAMCORDER_QUALITY_480P}, - {"720p", CAMCORDER_QUALITY_720P}, - {"1080p", CAMCORDER_QUALITY_1080P}, - {"qvga", CAMCORDER_QUALITY_QVGA}, - - {"timelapselow", CAMCORDER_QUALITY_TIME_LAPSE_LOW}, - {"timelapsehigh", CAMCORDER_QUALITY_TIME_LAPSE_HIGH}, - {"timelapseqcif", CAMCORDER_QUALITY_TIME_LAPSE_QCIF}, - {"timelapsecif", CAMCORDER_QUALITY_TIME_LAPSE_CIF}, - {"timelapse480p", CAMCORDER_QUALITY_TIME_LAPSE_480P}, - {"timelapse720p", CAMCORDER_QUALITY_TIME_LAPSE_720P}, - {"timelapse1080p", CAMCORDER_QUALITY_TIME_LAPSE_1080P}, - {"timelapseqvga", CAMCORDER_QUALITY_TIME_LAPSE_QVGA}, -}; - -/*static*/ void -MediaProfiles::logVideoCodec(const MediaProfiles::VideoCodec& codec) -{ - ALOGV("video codec:"); - ALOGV("codec = %d", codec.mCodec); - ALOGV("bit rate: %d", codec.mBitRate); - ALOGV("frame width: %d", codec.mFrameWidth); - ALOGV("frame height: %d", codec.mFrameHeight); - ALOGV("frame rate: %d", codec.mFrameRate); -} - -/*static*/ void -MediaProfiles::logAudioCodec(const MediaProfiles::AudioCodec& codec) -{ - ALOGV("audio codec:"); - ALOGV("codec = %d", codec.mCodec); - ALOGV("bit rate: %d", codec.mBitRate); - ALOGV("sample rate: %d", codec.mSampleRate); - ALOGV("number of channels: %d", codec.mChannels); -} - -/*static*/ void -MediaProfiles::logVideoEncoderCap(const MediaProfiles::VideoEncoderCap& cap) -{ - ALOGV("video encoder cap:"); - ALOGV("codec = %d", cap.mCodec); - ALOGV("bit rate: min = %d and max = %d", cap.mMinBitRate, cap.mMaxBitRate); - ALOGV("frame width: min = %d and max = %d", cap.mMinFrameWidth, cap.mMaxFrameWidth); - ALOGV("frame height: min = %d and max = %d", cap.mMinFrameHeight, cap.mMaxFrameHeight); - ALOGV("frame rate: min = %d and max = %d", cap.mMinFrameRate, cap.mMaxFrameRate); -} - -/*static*/ void -MediaProfiles::logAudioEncoderCap(const MediaProfiles::AudioEncoderCap& cap) -{ - ALOGV("audio encoder cap:"); - ALOGV("codec = %d", cap.mCodec); - ALOGV("bit rate: min = %d and max = %d", cap.mMinBitRate, cap.mMaxBitRate); - ALOGV("sample rate: min = %d and max = %d", cap.mMinSampleRate, cap.mMaxSampleRate); - ALOGV("number of channels: min = %d and max = %d", cap.mMinChannels, cap.mMaxChannels); -} - -/*static*/ void -MediaProfiles::logVideoDecoderCap(const MediaProfiles::VideoDecoderCap& cap) -{ - ALOGV("video decoder cap:"); - ALOGV("codec = %d", cap.mCodec); -} - -/*static*/ void -MediaProfiles::logAudioDecoderCap(const MediaProfiles::AudioDecoderCap& cap) -{ - ALOGV("audio codec cap:"); - ALOGV("codec = %d", cap.mCodec); -} - -/*static*/ void -MediaProfiles::logVideoEditorCap(const MediaProfiles::VideoEditorCap& cap) -{ - ALOGV("videoeditor cap:"); - ALOGV("mMaxInputFrameWidth = %d", cap.mMaxInputFrameWidth); - ALOGV("mMaxInputFrameHeight = %d", cap.mMaxInputFrameHeight); - ALOGV("mMaxOutputFrameWidth = %d", cap.mMaxOutputFrameWidth); - ALOGV("mMaxOutputFrameHeight = %d", cap.mMaxOutputFrameHeight); -} - -/*static*/ int -MediaProfiles::findTagForName(const MediaProfiles::NameToTagMap *map, size_t nMappings, const char *name) -{ - int tag = -1; - for (size_t i = 0; i < nMappings; ++i) { - if (!strcmp(map[i].name, name)) { - tag = map[i].tag; - break; - } - } - return tag; -} - -/*static*/ MediaProfiles::VideoCodec* -MediaProfiles::createVideoCodec(const char **atts, MediaProfiles *profiles) -{ - CHECK(!strcmp("codec", atts[0]) && - !strcmp("bitRate", atts[2]) && - !strcmp("width", atts[4]) && - !strcmp("height", atts[6]) && - !strcmp("frameRate", atts[8])); - - const size_t nMappings = sizeof(sVideoEncoderNameMap)/sizeof(sVideoEncoderNameMap[0]); - const int codec = findTagForName(sVideoEncoderNameMap, nMappings, atts[1]); - CHECK(codec != -1); - - MediaProfiles::VideoCodec *videoCodec = - new MediaProfiles::VideoCodec(static_cast<video_encoder>(codec), - atoi(atts[3]), atoi(atts[5]), atoi(atts[7]), atoi(atts[9])); - logVideoCodec(*videoCodec); - - size_t nCamcorderProfiles; - CHECK((nCamcorderProfiles = profiles->mCamcorderProfiles.size()) >= 1); - profiles->mCamcorderProfiles[nCamcorderProfiles - 1]->mVideoCodec = videoCodec; - return videoCodec; -} - -/*static*/ MediaProfiles::AudioCodec* -MediaProfiles::createAudioCodec(const char **atts, MediaProfiles *profiles) -{ - CHECK(!strcmp("codec", atts[0]) && - !strcmp("bitRate", atts[2]) && - !strcmp("sampleRate", atts[4]) && - !strcmp("channels", atts[6])); - const size_t nMappings = sizeof(sAudioEncoderNameMap)/sizeof(sAudioEncoderNameMap[0]); - const int codec = findTagForName(sAudioEncoderNameMap, nMappings, atts[1]); - CHECK(codec != -1); - - MediaProfiles::AudioCodec *audioCodec = - new MediaProfiles::AudioCodec(static_cast<audio_encoder>(codec), - atoi(atts[3]), atoi(atts[5]), atoi(atts[7])); - logAudioCodec(*audioCodec); - - size_t nCamcorderProfiles; - CHECK((nCamcorderProfiles = profiles->mCamcorderProfiles.size()) >= 1); - profiles->mCamcorderProfiles[nCamcorderProfiles - 1]->mAudioCodec = audioCodec; - return audioCodec; -} -/*static*/ MediaProfiles::AudioDecoderCap* -MediaProfiles::createAudioDecoderCap(const char **atts) -{ - CHECK(!strcmp("name", atts[0]) && - !strcmp("enabled", atts[2])); - - const size_t nMappings = sizeof(sAudioDecoderNameMap)/sizeof(sAudioDecoderNameMap[0]); - const int codec = findTagForName(sAudioDecoderNameMap, nMappings, atts[1]); - CHECK(codec != -1); - - MediaProfiles::AudioDecoderCap *cap = - new MediaProfiles::AudioDecoderCap(static_cast<audio_decoder>(codec)); - logAudioDecoderCap(*cap); - return cap; -} - -/*static*/ MediaProfiles::VideoDecoderCap* -MediaProfiles::createVideoDecoderCap(const char **atts) -{ - CHECK(!strcmp("name", atts[0]) && - !strcmp("enabled", atts[2])); - - const size_t nMappings = sizeof(sVideoDecoderNameMap)/sizeof(sVideoDecoderNameMap[0]); - const int codec = findTagForName(sVideoDecoderNameMap, nMappings, atts[1]); - CHECK(codec != -1); - - MediaProfiles::VideoDecoderCap *cap = - new MediaProfiles::VideoDecoderCap(static_cast<video_decoder>(codec)); - logVideoDecoderCap(*cap); - return cap; -} - -/*static*/ MediaProfiles::VideoEncoderCap* -MediaProfiles::createVideoEncoderCap(const char **atts) -{ - CHECK(!strcmp("name", atts[0]) && - !strcmp("enabled", atts[2]) && - !strcmp("minBitRate", atts[4]) && - !strcmp("maxBitRate", atts[6]) && - !strcmp("minFrameWidth", atts[8]) && - !strcmp("maxFrameWidth", atts[10]) && - !strcmp("minFrameHeight", atts[12]) && - !strcmp("maxFrameHeight", atts[14]) && - !strcmp("minFrameRate", atts[16]) && - !strcmp("maxFrameRate", atts[18])); - - const size_t nMappings = sizeof(sVideoEncoderNameMap)/sizeof(sVideoEncoderNameMap[0]); - const int codec = findTagForName(sVideoEncoderNameMap, nMappings, atts[1]); - CHECK(codec != -1); - - MediaProfiles::VideoEncoderCap *cap = - new MediaProfiles::VideoEncoderCap(static_cast<video_encoder>(codec), - atoi(atts[5]), atoi(atts[7]), atoi(atts[9]), atoi(atts[11]), atoi(atts[13]), - atoi(atts[15]), atoi(atts[17]), atoi(atts[19])); - logVideoEncoderCap(*cap); - return cap; -} - -/*static*/ MediaProfiles::AudioEncoderCap* -MediaProfiles::createAudioEncoderCap(const char **atts) -{ - CHECK(!strcmp("name", atts[0]) && - !strcmp("enabled", atts[2]) && - !strcmp("minBitRate", atts[4]) && - !strcmp("maxBitRate", atts[6]) && - !strcmp("minSampleRate", atts[8]) && - !strcmp("maxSampleRate", atts[10]) && - !strcmp("minChannels", atts[12]) && - !strcmp("maxChannels", atts[14])); - - const size_t nMappings = sizeof(sAudioEncoderNameMap)/sizeof(sAudioEncoderNameMap[0]); - const int codec = findTagForName(sAudioEncoderNameMap, nMappings, atts[1]); - CHECK(codec != -1); - - MediaProfiles::AudioEncoderCap *cap = - new MediaProfiles::AudioEncoderCap(static_cast<audio_encoder>(codec), atoi(atts[5]), atoi(atts[7]), - atoi(atts[9]), atoi(atts[11]), atoi(atts[13]), - atoi(atts[15])); - logAudioEncoderCap(*cap); - return cap; -} - -/*static*/ output_format -MediaProfiles::createEncoderOutputFileFormat(const char **atts) -{ - CHECK(!strcmp("name", atts[0])); - - const size_t nMappings =sizeof(sFileFormatMap)/sizeof(sFileFormatMap[0]); - const int format = findTagForName(sFileFormatMap, nMappings, atts[1]); - CHECK(format != -1); - - return static_cast<output_format>(format); -} - -static bool isCameraIdFound(int cameraId, const Vector<int>& cameraIds) { - for (int i = 0, n = cameraIds.size(); i < n; ++i) { - if (cameraId == cameraIds[i]) { - return true; - } - } - return false; -} - -/*static*/ MediaProfiles::CamcorderProfile* -MediaProfiles::createCamcorderProfile(int cameraId, const char **atts, Vector<int>& cameraIds) -{ - CHECK(!strcmp("quality", atts[0]) && - !strcmp("fileFormat", atts[2]) && - !strcmp("duration", atts[4])); - - const size_t nProfileMappings = sizeof(sCamcorderQualityNameMap)/sizeof(sCamcorderQualityNameMap[0]); - const int quality = findTagForName(sCamcorderQualityNameMap, nProfileMappings, atts[1]); - CHECK(quality != -1); - - const size_t nFormatMappings = sizeof(sFileFormatMap)/sizeof(sFileFormatMap[0]); - const int fileFormat = findTagForName(sFileFormatMap, nFormatMappings, atts[3]); - CHECK(fileFormat != -1); - - MediaProfiles::CamcorderProfile *profile = new MediaProfiles::CamcorderProfile; - profile->mCameraId = cameraId; - if (!isCameraIdFound(cameraId, cameraIds)) { - cameraIds.add(cameraId); - } - profile->mFileFormat = static_cast<output_format>(fileFormat); - profile->mQuality = static_cast<camcorder_quality>(quality); - profile->mDuration = atoi(atts[5]); - return profile; -} - -MediaProfiles::ImageEncodingQualityLevels* -MediaProfiles::findImageEncodingQualityLevels(int cameraId) const -{ - int n = mImageEncodingQualityLevels.size(); - for (int i = 0; i < n; i++) { - ImageEncodingQualityLevels *levels = mImageEncodingQualityLevels[i]; - if (levels->mCameraId == cameraId) { - return levels; - } - } - return NULL; -} - -void MediaProfiles::addImageEncodingQualityLevel(int cameraId, const char** atts) -{ - CHECK(!strcmp("quality", atts[0])); - int quality = atoi(atts[1]); - ALOGV("%s: cameraId=%d, quality=%d", __func__, cameraId, quality); - ImageEncodingQualityLevels *levels = findImageEncodingQualityLevels(cameraId); - - if (levels == NULL) { - levels = new ImageEncodingQualityLevels(); - levels->mCameraId = cameraId; - mImageEncodingQualityLevels.add(levels); - } - - levels->mLevels.add(quality); -} - -/*static*/ int -MediaProfiles::getCameraId(const char** atts) -{ - if (!atts[0]) return 0; // default cameraId = 0 - CHECK(!strcmp("cameraId", atts[0])); - 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]); - } - - ALOGV("%s: cameraId=%d, offset=%d ms", __func__, cameraId, offsetTimeMs); - mStartTimeOffsets.replaceValueFor(cameraId, offsetTimeMs); -} -/*static*/ MediaProfiles::ExportVideoProfile* -MediaProfiles::createExportVideoProfile(const char **atts) -{ - CHECK(!strcmp("name", atts[0]) && - !strcmp("profile", atts[2]) && - !strcmp("level", atts[4])); - - const size_t nMappings = - sizeof(sVideoEncoderNameMap)/sizeof(sVideoEncoderNameMap[0]); - const int codec = findTagForName(sVideoEncoderNameMap, nMappings, atts[1]); - CHECK(codec != -1); - - MediaProfiles::ExportVideoProfile *profile = - new MediaProfiles::ExportVideoProfile( - codec, atoi(atts[3]), atoi(atts[5])); - - return profile; -} -/*static*/ MediaProfiles::VideoEditorCap* -MediaProfiles::createVideoEditorCap(const char **atts, MediaProfiles *profiles) -{ - CHECK(!strcmp("maxInputFrameWidth", atts[0]) && - !strcmp("maxInputFrameHeight", atts[2]) && - !strcmp("maxOutputFrameWidth", atts[4]) && - !strcmp("maxOutputFrameHeight", atts[6]) && - !strcmp("maxPrefetchYUVFrames", atts[8])); - - MediaProfiles::VideoEditorCap *pVideoEditorCap = - new MediaProfiles::VideoEditorCap(atoi(atts[1]), atoi(atts[3]), - atoi(atts[5]), atoi(atts[7]), atoi(atts[9])); - - logVideoEditorCap(*pVideoEditorCap); - profiles->mVideoEditorCap = pVideoEditorCap; - - return pVideoEditorCap; -} - -/*static*/ void -MediaProfiles::startElementHandler(void *userData, const char *name, const char **atts) -{ - MediaProfiles *profiles = (MediaProfiles *) userData; - if (strcmp("Video", name) == 0) { - createVideoCodec(atts, profiles); - } else if (strcmp("Audio", name) == 0) { - createAudioCodec(atts, profiles); - } else if (strcmp("VideoEncoderCap", name) == 0 && - strcmp("true", atts[3]) == 0) { - profiles->mVideoEncoders.add(createVideoEncoderCap(atts)); - } else if (strcmp("AudioEncoderCap", name) == 0 && - strcmp("true", atts[3]) == 0) { - profiles->mAudioEncoders.add(createAudioEncoderCap(atts)); - } else if (strcmp("VideoDecoderCap", name) == 0 && - strcmp("true", atts[3]) == 0) { - profiles->mVideoDecoders.add(createVideoDecoderCap(atts)); - } else if (strcmp("AudioDecoderCap", name) == 0 && - strcmp("true", atts[3]) == 0) { - profiles->mAudioDecoders.add(createAudioDecoderCap(atts)); - } else if (strcmp("EncoderOutputFileFormat", name) == 0) { - 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)); - } else if (strcmp("ImageEncoding", name) == 0) { - profiles->addImageEncodingQualityLevel(profiles->mCurrentCameraId, atts); - } else if (strcmp("VideoEditorCap", name) == 0) { - createVideoEditorCap(atts, profiles); - } else if (strcmp("ExportVideoProfile", name) == 0) { - profiles->mVideoEditorExportProfiles.add(createExportVideoProfile(atts)); - } -} - -static bool isCamcorderProfile(camcorder_quality quality) { - return quality >= CAMCORDER_QUALITY_LIST_START && - quality <= CAMCORDER_QUALITY_LIST_END; -} - -static bool isTimelapseProfile(camcorder_quality quality) { - return quality >= CAMCORDER_QUALITY_TIME_LAPSE_LIST_START && - quality <= CAMCORDER_QUALITY_TIME_LAPSE_LIST_END; -} - -void MediaProfiles::initRequiredProfileRefs(const Vector<int>& cameraIds) { - ALOGV("Number of camera ids: %d", cameraIds.size()); - CHECK(cameraIds.size() > 0); - mRequiredProfileRefs = new RequiredProfiles[cameraIds.size()]; - for (size_t i = 0, n = cameraIds.size(); i < n; ++i) { - mRequiredProfileRefs[i].mCameraId = cameraIds[i]; - for (size_t j = 0; j < kNumRequiredProfiles; ++j) { - mRequiredProfileRefs[i].mRefs[j].mHasRefProfile = false; - mRequiredProfileRefs[i].mRefs[j].mRefProfileIndex = -1; - if ((j & 1) == 0) { // low resolution - mRequiredProfileRefs[i].mRefs[j].mResolutionProduct = 0x7FFFFFFF; - } else { // high resolution - mRequiredProfileRefs[i].mRefs[j].mResolutionProduct = 0; - } - } - } -} - -int MediaProfiles::getRequiredProfileRefIndex(int cameraId) { - for (size_t i = 0, n = mCameraIds.size(); i < n; ++i) { - if (mCameraIds[i] == cameraId) { - return i; - } - } - return -1; -} - -void MediaProfiles::checkAndAddRequiredProfilesIfNecessary() { - if (sIsInitialized) { - return; - } - - initRequiredProfileRefs(mCameraIds); - - for (size_t i = 0, n = mCamcorderProfiles.size(); i < n; ++i) { - int product = mCamcorderProfiles[i]->mVideoCodec->mFrameWidth * - mCamcorderProfiles[i]->mVideoCodec->mFrameHeight; - - camcorder_quality quality = mCamcorderProfiles[i]->mQuality; - int cameraId = mCamcorderProfiles[i]->mCameraId; - int index = -1; - int refIndex = getRequiredProfileRefIndex(cameraId); - CHECK(refIndex != -1); - RequiredProfileRefInfo *info; - camcorder_quality refQuality; - VideoCodec *codec = NULL; - - // Check high and low from either camcorder profile or timelapse profile - // but not both. Default, check camcorder profile - size_t j = 0; - size_t n = 2; - if (isTimelapseProfile(quality)) { - // Check timelapse profile instead. - j = 2; - n = kNumRequiredProfiles; - } else { - // Must be camcorder profile. - CHECK(isCamcorderProfile(quality)); - } - for (; j < n; ++j) { - info = &(mRequiredProfileRefs[refIndex].mRefs[j]); - if ((j % 2 == 0 && product > info->mResolutionProduct) || // low - (j % 2 != 0 && product < info->mResolutionProduct)) { // high - continue; - } - switch (j) { - case 0: - refQuality = CAMCORDER_QUALITY_LOW; - break; - case 1: - refQuality = CAMCORDER_QUALITY_HIGH; - break; - case 2: - refQuality = CAMCORDER_QUALITY_TIME_LAPSE_LOW; - break; - case 3: - refQuality = CAMCORDER_QUALITY_TIME_LAPSE_HIGH; - break; - default: - CHECK(!"Should never reach here"); - } - - if (!info->mHasRefProfile) { - index = getCamcorderProfileIndex(cameraId, refQuality); - } - if (index == -1) { - // New high or low quality profile is found. - // Update its reference. - info->mHasRefProfile = true; - info->mRefProfileIndex = i; - info->mResolutionProduct = product; - } - } - } - - for (size_t cameraId = 0; cameraId < mCameraIds.size(); ++cameraId) { - for (size_t j = 0; j < kNumRequiredProfiles; ++j) { - int refIndex = getRequiredProfileRefIndex(cameraId); - CHECK(refIndex != -1); - RequiredProfileRefInfo *info = - &mRequiredProfileRefs[refIndex].mRefs[j]; - - if (info->mHasRefProfile) { - - CamcorderProfile *profile = - new CamcorderProfile( - *mCamcorderProfiles[info->mRefProfileIndex]); - - // Overwrite the quality - switch (j % kNumRequiredProfiles) { - case 0: - profile->mQuality = CAMCORDER_QUALITY_LOW; - break; - case 1: - profile->mQuality = CAMCORDER_QUALITY_HIGH; - break; - case 2: - profile->mQuality = CAMCORDER_QUALITY_TIME_LAPSE_LOW; - break; - case 3: - profile->mQuality = CAMCORDER_QUALITY_TIME_LAPSE_HIGH; - break; - default: - CHECK(!"Should never come here"); - } - - int index = getCamcorderProfileIndex(cameraId, profile->mQuality); - if (index != -1) { - ALOGV("Profile quality %d for camera %d already exists", - profile->mQuality, cameraId); - CHECK(index == refIndex); - continue; - } - - // Insert the new profile - ALOGV("Add a profile: quality %d=>%d for camera %d", - mCamcorderProfiles[info->mRefProfileIndex]->mQuality, - profile->mQuality, cameraId); - - mCamcorderProfiles.add(profile); - } - } - } -} - -/*static*/ MediaProfiles* -MediaProfiles::getInstance() -{ - ALOGV("getInstance"); - Mutex::Autolock lock(sLock); - if (!sIsInitialized) { - char value[PROPERTY_VALUE_MAX]; - if (property_get("media.settings.xml", value, NULL) <= 0) { - const char *defaultXmlFile = "/etc/media_profiles.xml"; - FILE *fp = fopen(defaultXmlFile, "r"); - if (fp == NULL) { - ALOGW("could not find media config xml file"); - sInstance = createDefaultInstance(); - } else { - fclose(fp); // close the file first. - sInstance = createInstanceFromXmlFile(defaultXmlFile); - } - } else { - sInstance = createInstanceFromXmlFile(value); - } - CHECK(sInstance != NULL); - sInstance->checkAndAddRequiredProfilesIfNecessary(); - sIsInitialized = true; - } - - return sInstance; -} - -/*static*/ MediaProfiles::VideoEncoderCap* -MediaProfiles::createDefaultH263VideoEncoderCap() -{ - return new MediaProfiles::VideoEncoderCap( - VIDEO_ENCODER_H263, 192000, 420000, 176, 352, 144, 288, 1, 20); -} - -/*static*/ MediaProfiles::VideoEncoderCap* -MediaProfiles::createDefaultM4vVideoEncoderCap() -{ - return new MediaProfiles::VideoEncoderCap( - VIDEO_ENCODER_MPEG_4_SP, 192000, 420000, 176, 352, 144, 288, 1, 20); -} - - -/*static*/ void -MediaProfiles::createDefaultVideoEncoders(MediaProfiles *profiles) -{ - profiles->mVideoEncoders.add(createDefaultH263VideoEncoderCap()); - profiles->mVideoEncoders.add(createDefaultM4vVideoEncoderCap()); -} - -/*static*/ MediaProfiles::CamcorderProfile* -MediaProfiles::createDefaultCamcorderTimeLapseQcifProfile(camcorder_quality quality) -{ - MediaProfiles::VideoCodec *videoCodec = - new MediaProfiles::VideoCodec(VIDEO_ENCODER_H263, 1000000, 176, 144, 20); - - AudioCodec *audioCodec = new AudioCodec(AUDIO_ENCODER_AMR_NB, 12200, 8000, 1); - CamcorderProfile *profile = new MediaProfiles::CamcorderProfile; - profile->mCameraId = 0; - profile->mFileFormat = OUTPUT_FORMAT_THREE_GPP; - profile->mQuality = quality; - profile->mDuration = 60; - profile->mVideoCodec = videoCodec; - profile->mAudioCodec = audioCodec; - return profile; -} - -/*static*/ MediaProfiles::CamcorderProfile* -MediaProfiles::createDefaultCamcorderTimeLapse480pProfile(camcorder_quality quality) -{ - MediaProfiles::VideoCodec *videoCodec = - new MediaProfiles::VideoCodec(VIDEO_ENCODER_H263, 20000000, 720, 480, 20); - - AudioCodec *audioCodec = new AudioCodec(AUDIO_ENCODER_AMR_NB, 12200, 8000, 1); - CamcorderProfile *profile = new MediaProfiles::CamcorderProfile; - profile->mCameraId = 0; - profile->mFileFormat = OUTPUT_FORMAT_THREE_GPP; - profile->mQuality = quality; - profile->mDuration = 60; - profile->mVideoCodec = videoCodec; - profile->mAudioCodec = audioCodec; - return profile; -} - -/*static*/ void -MediaProfiles::createDefaultCamcorderTimeLapseLowProfiles( - MediaProfiles::CamcorderProfile **lowTimeLapseProfile, - MediaProfiles::CamcorderProfile **lowSpecificTimeLapseProfile) { - *lowTimeLapseProfile = createDefaultCamcorderTimeLapseQcifProfile(CAMCORDER_QUALITY_TIME_LAPSE_LOW); - *lowSpecificTimeLapseProfile = createDefaultCamcorderTimeLapseQcifProfile(CAMCORDER_QUALITY_TIME_LAPSE_QCIF); -} - -/*static*/ void -MediaProfiles::createDefaultCamcorderTimeLapseHighProfiles( - MediaProfiles::CamcorderProfile **highTimeLapseProfile, - MediaProfiles::CamcorderProfile **highSpecificTimeLapseProfile) { - *highTimeLapseProfile = createDefaultCamcorderTimeLapse480pProfile(CAMCORDER_QUALITY_TIME_LAPSE_HIGH); - *highSpecificTimeLapseProfile = createDefaultCamcorderTimeLapse480pProfile(CAMCORDER_QUALITY_TIME_LAPSE_480P); -} - -/*static*/ MediaProfiles::CamcorderProfile* -MediaProfiles::createDefaultCamcorderQcifProfile(camcorder_quality quality) -{ - MediaProfiles::VideoCodec *videoCodec = - new MediaProfiles::VideoCodec(VIDEO_ENCODER_H263, 192000, 176, 144, 20); - - MediaProfiles::AudioCodec *audioCodec = - new MediaProfiles::AudioCodec(AUDIO_ENCODER_AMR_NB, 12200, 8000, 1); - - MediaProfiles::CamcorderProfile *profile = new MediaProfiles::CamcorderProfile; - profile->mCameraId = 0; - profile->mFileFormat = OUTPUT_FORMAT_THREE_GPP; - profile->mQuality = quality; - profile->mDuration = 30; - profile->mVideoCodec = videoCodec; - profile->mAudioCodec = audioCodec; - return profile; -} - -/*static*/ MediaProfiles::CamcorderProfile* -MediaProfiles::createDefaultCamcorderCifProfile(camcorder_quality quality) -{ - MediaProfiles::VideoCodec *videoCodec = - new MediaProfiles::VideoCodec(VIDEO_ENCODER_H263, 360000, 352, 288, 20); - - AudioCodec *audioCodec = new AudioCodec(AUDIO_ENCODER_AMR_NB, 12200, 8000, 1); - CamcorderProfile *profile = new MediaProfiles::CamcorderProfile; - profile->mCameraId = 0; - profile->mFileFormat = OUTPUT_FORMAT_THREE_GPP; - profile->mQuality = quality; - profile->mDuration = 60; - profile->mVideoCodec = videoCodec; - profile->mAudioCodec = audioCodec; - return profile; -} - -/*static*/ void -MediaProfiles::createDefaultCamcorderLowProfiles( - MediaProfiles::CamcorderProfile **lowProfile, - MediaProfiles::CamcorderProfile **lowSpecificProfile) { - *lowProfile = createDefaultCamcorderQcifProfile(CAMCORDER_QUALITY_LOW); - *lowSpecificProfile = createDefaultCamcorderQcifProfile(CAMCORDER_QUALITY_QCIF); -} - -/*static*/ void -MediaProfiles::createDefaultCamcorderHighProfiles( - MediaProfiles::CamcorderProfile **highProfile, - MediaProfiles::CamcorderProfile **highSpecificProfile) { - *highProfile = createDefaultCamcorderCifProfile(CAMCORDER_QUALITY_HIGH); - *highSpecificProfile = createDefaultCamcorderCifProfile(CAMCORDER_QUALITY_CIF); -} - -/*static*/ void -MediaProfiles::createDefaultCamcorderProfiles(MediaProfiles *profiles) -{ - // low camcorder profiles. - MediaProfiles::CamcorderProfile *lowProfile, *lowSpecificProfile; - createDefaultCamcorderLowProfiles(&lowProfile, &lowSpecificProfile); - profiles->mCamcorderProfiles.add(lowProfile); - profiles->mCamcorderProfiles.add(lowSpecificProfile); - - // high camcorder profiles. - MediaProfiles::CamcorderProfile* highProfile, *highSpecificProfile; - createDefaultCamcorderHighProfiles(&highProfile, &highSpecificProfile); - profiles->mCamcorderProfiles.add(highProfile); - profiles->mCamcorderProfiles.add(highSpecificProfile); - - // low camcorder time lapse profiles. - MediaProfiles::CamcorderProfile *lowTimeLapseProfile, *lowSpecificTimeLapseProfile; - createDefaultCamcorderTimeLapseLowProfiles(&lowTimeLapseProfile, &lowSpecificTimeLapseProfile); - profiles->mCamcorderProfiles.add(lowTimeLapseProfile); - profiles->mCamcorderProfiles.add(lowSpecificTimeLapseProfile); - - // high camcorder time lapse profiles. - MediaProfiles::CamcorderProfile *highTimeLapseProfile, *highSpecificTimeLapseProfile; - createDefaultCamcorderTimeLapseHighProfiles(&highTimeLapseProfile, &highSpecificTimeLapseProfile); - profiles->mCamcorderProfiles.add(highTimeLapseProfile); - profiles->mCamcorderProfiles.add(highSpecificTimeLapseProfile); - - // For emulator and other legacy devices which does not have a - // media_profiles.xml file, We assume that the default camera id - // is 0 and that is the only camera available. - profiles->mCameraIds.push(0); -} - -/*static*/ void -MediaProfiles::createDefaultAudioEncoders(MediaProfiles *profiles) -{ - profiles->mAudioEncoders.add(createDefaultAmrNBEncoderCap()); -} - -/*static*/ void -MediaProfiles::createDefaultVideoDecoders(MediaProfiles *profiles) -{ - MediaProfiles::VideoDecoderCap *cap = - new MediaProfiles::VideoDecoderCap(VIDEO_DECODER_WMV); - - profiles->mVideoDecoders.add(cap); -} - -/*static*/ void -MediaProfiles::createDefaultAudioDecoders(MediaProfiles *profiles) -{ - MediaProfiles::AudioDecoderCap *cap = - new MediaProfiles::AudioDecoderCap(AUDIO_DECODER_WMA); - - profiles->mAudioDecoders.add(cap); -} - -/*static*/ void -MediaProfiles::createDefaultEncoderOutputFileFormats(MediaProfiles *profiles) -{ - profiles->mEncoderOutputFileFormats.add(OUTPUT_FORMAT_THREE_GPP); - profiles->mEncoderOutputFileFormats.add(OUTPUT_FORMAT_MPEG_4); -} - -/*static*/ MediaProfiles::AudioEncoderCap* -MediaProfiles::createDefaultAmrNBEncoderCap() -{ - return new MediaProfiles::AudioEncoderCap( - AUDIO_ENCODER_AMR_NB, 5525, 12200, 8000, 8000, 1, 1); -} - -/*static*/ void -MediaProfiles::createDefaultImageEncodingQualityLevels(MediaProfiles *profiles) -{ - ImageEncodingQualityLevels *levels = new ImageEncodingQualityLevels(); - levels->mCameraId = 0; - levels->mLevels.add(70); - levels->mLevels.add(80); - levels->mLevels.add(90); - profiles->mImageEncodingQualityLevels.add(levels); -} - -/*static*/ void -MediaProfiles::createDefaultVideoEditorCap(MediaProfiles *profiles) -{ - profiles->mVideoEditorCap = - new MediaProfiles::VideoEditorCap( - VIDEOEDITOR_DEFAULT_MAX_INPUT_FRAME_WIDTH, - VIDEOEDITOR_DEFUALT_MAX_INPUT_FRAME_HEIGHT, - VIDEOEDITOR_DEFAULT_MAX_OUTPUT_FRAME_WIDTH, - VIDEOEDITOR_DEFUALT_MAX_OUTPUT_FRAME_HEIGHT, - VIDEOEDITOR_DEFAULT_MAX_PREFETCH_YUV_FRAMES); -} -/*static*/ void -MediaProfiles::createDefaultExportVideoProfiles(MediaProfiles *profiles) -{ - // Create default video export profiles - profiles->mVideoEditorExportProfiles.add( - new ExportVideoProfile(VIDEO_ENCODER_H263, - OMX_VIDEO_H263ProfileBaseline, OMX_VIDEO_H263Level10)); - profiles->mVideoEditorExportProfiles.add( - new ExportVideoProfile(VIDEO_ENCODER_MPEG_4_SP, - OMX_VIDEO_MPEG4ProfileSimple, OMX_VIDEO_MPEG4Level1)); - profiles->mVideoEditorExportProfiles.add( - new ExportVideoProfile(VIDEO_ENCODER_H264, - OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel13)); -} - -/*static*/ MediaProfiles* -MediaProfiles::createDefaultInstance() -{ - MediaProfiles *profiles = new MediaProfiles; - createDefaultCamcorderProfiles(profiles); - createDefaultVideoEncoders(profiles); - createDefaultAudioEncoders(profiles); - createDefaultVideoDecoders(profiles); - createDefaultAudioDecoders(profiles); - createDefaultEncoderOutputFileFormats(profiles); - createDefaultImageEncodingQualityLevels(profiles); - createDefaultVideoEditorCap(profiles); - createDefaultExportVideoProfiles(profiles); - return profiles; -} - -/*static*/ MediaProfiles* -MediaProfiles::createInstanceFromXmlFile(const char *xml) -{ - FILE *fp = NULL; - CHECK((fp = fopen(xml, "r"))); - - XML_Parser parser = ::XML_ParserCreate(NULL); - CHECK(parser != NULL); - - MediaProfiles *profiles = new MediaProfiles(); - ::XML_SetUserData(parser, profiles); - ::XML_SetElementHandler(parser, startElementHandler, NULL); - - /* - FIXME: - expat is not compiled with -DXML_DTD. We don't have DTD parsing support. - - if (!::XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS)) { - ALOGE("failed to enable DTD support in the xml file"); - return UNKNOWN_ERROR; - } - - */ - - const int BUFF_SIZE = 512; - for (;;) { - void *buff = ::XML_GetBuffer(parser, BUFF_SIZE); - if (buff == NULL) { - ALOGE("failed to in call to XML_GetBuffer()"); - delete profiles; - profiles = NULL; - goto exit; - } - - int bytes_read = ::fread(buff, 1, BUFF_SIZE, fp); - if (bytes_read < 0) { - ALOGE("failed in call to read"); - delete profiles; - profiles = NULL; - goto exit; - } - - CHECK(::XML_ParseBuffer(parser, bytes_read, bytes_read == 0)); - - if (bytes_read == 0) break; // done parsing the xml file - } - -exit: - ::XML_ParserFree(parser); - ::fclose(fp); - return profiles; -} - -Vector<output_format> MediaProfiles::getOutputFileFormats() const -{ - return mEncoderOutputFileFormats; // copy out -} - -Vector<video_encoder> MediaProfiles::getVideoEncoders() const -{ - Vector<video_encoder> encoders; - for (size_t i = 0; i < mVideoEncoders.size(); ++i) { - encoders.add(mVideoEncoders[i]->mCodec); - } - return encoders; // copy out -} - -int MediaProfiles::getVideoEncoderParamByName(const char *name, video_encoder codec) const -{ - ALOGV("getVideoEncoderParamByName: %s for codec %d", name, codec); - int index = -1; - for (size_t i = 0, n = mVideoEncoders.size(); i < n; ++i) { - if (mVideoEncoders[i]->mCodec == codec) { - index = i; - break; - } - } - if (index == -1) { - ALOGE("The given video encoder %d is not found", codec); - return -1; - } - - if (!strcmp("enc.vid.width.min", name)) return mVideoEncoders[index]->mMinFrameWidth; - if (!strcmp("enc.vid.width.max", name)) return mVideoEncoders[index]->mMaxFrameWidth; - if (!strcmp("enc.vid.height.min", name)) return mVideoEncoders[index]->mMinFrameHeight; - if (!strcmp("enc.vid.height.max", name)) return mVideoEncoders[index]->mMaxFrameHeight; - if (!strcmp("enc.vid.bps.min", name)) return mVideoEncoders[index]->mMinBitRate; - if (!strcmp("enc.vid.bps.max", name)) return mVideoEncoders[index]->mMaxBitRate; - if (!strcmp("enc.vid.fps.min", name)) return mVideoEncoders[index]->mMinFrameRate; - if (!strcmp("enc.vid.fps.max", name)) return mVideoEncoders[index]->mMaxFrameRate; - - ALOGE("The given video encoder param name %s is not found", name); - return -1; -} -int MediaProfiles::getVideoEditorExportParamByName( - const char *name, int codec) const -{ - ALOGV("getVideoEditorExportParamByName: name %s codec %d", name, codec); - ExportVideoProfile *exportProfile = NULL; - int index = -1; - for (size_t i =0; i < mVideoEditorExportProfiles.size(); i++) { - exportProfile = mVideoEditorExportProfiles[i]; - if (exportProfile->mCodec == codec) { - index = i; - break; - } - } - if (index == -1) { - ALOGE("The given video decoder %d is not found", codec); - return -1; - } - if (!strcmp("videoeditor.export.profile", name)) - return exportProfile->mProfile; - if (!strcmp("videoeditor.export.level", name)) - return exportProfile->mLevel; - - ALOGE("The given video editor export param name %s is not found", name); - return -1; -} -int MediaProfiles::getVideoEditorCapParamByName(const char *name) const -{ - ALOGV("getVideoEditorCapParamByName: %s", name); - - if (mVideoEditorCap == NULL) { - ALOGE("The mVideoEditorCap is not created, then create default cap."); - createDefaultVideoEditorCap(sInstance); - } - - if (!strcmp("videoeditor.input.width.max", name)) - return mVideoEditorCap->mMaxInputFrameWidth; - if (!strcmp("videoeditor.input.height.max", name)) - return mVideoEditorCap->mMaxInputFrameHeight; - if (!strcmp("videoeditor.output.width.max", name)) - return mVideoEditorCap->mMaxOutputFrameWidth; - if (!strcmp("videoeditor.output.height.max", name)) - return mVideoEditorCap->mMaxOutputFrameHeight; - if (!strcmp("maxPrefetchYUVFrames", name)) - return mVideoEditorCap->mMaxPrefetchYUVFrames; - - ALOGE("The given video editor param name %s is not found", name); - return -1; -} - -Vector<audio_encoder> MediaProfiles::getAudioEncoders() const -{ - Vector<audio_encoder> encoders; - for (size_t i = 0; i < mAudioEncoders.size(); ++i) { - encoders.add(mAudioEncoders[i]->mCodec); - } - return encoders; // copy out -} - -int MediaProfiles::getAudioEncoderParamByName(const char *name, audio_encoder codec) const -{ - ALOGV("getAudioEncoderParamByName: %s for codec %d", name, codec); - int index = -1; - for (size_t i = 0, n = mAudioEncoders.size(); i < n; ++i) { - if (mAudioEncoders[i]->mCodec == codec) { - index = i; - break; - } - } - if (index == -1) { - ALOGE("The given audio encoder %d is not found", codec); - return -1; - } - - if (!strcmp("enc.aud.ch.min", name)) return mAudioEncoders[index]->mMinChannels; - if (!strcmp("enc.aud.ch.max", name)) return mAudioEncoders[index]->mMaxChannels; - if (!strcmp("enc.aud.bps.min", name)) return mAudioEncoders[index]->mMinBitRate; - if (!strcmp("enc.aud.bps.max", name)) return mAudioEncoders[index]->mMaxBitRate; - if (!strcmp("enc.aud.hz.min", name)) return mAudioEncoders[index]->mMinSampleRate; - if (!strcmp("enc.aud.hz.max", name)) return mAudioEncoders[index]->mMaxSampleRate; - - ALOGE("The given audio encoder param name %s is not found", name); - return -1; -} - -Vector<video_decoder> MediaProfiles::getVideoDecoders() const -{ - Vector<video_decoder> decoders; - for (size_t i = 0; i < mVideoDecoders.size(); ++i) { - decoders.add(mVideoDecoders[i]->mCodec); - } - return decoders; // copy out -} - -Vector<audio_decoder> MediaProfiles::getAudioDecoders() const -{ - Vector<audio_decoder> decoders; - for (size_t i = 0; i < mAudioDecoders.size(); ++i) { - decoders.add(mAudioDecoders[i]->mCodec); - } - return decoders; // copy out -} - -int MediaProfiles::getCamcorderProfileIndex(int cameraId, camcorder_quality quality) const -{ - int index = -1; - for (size_t i = 0, n = mCamcorderProfiles.size(); i < n; ++i) { - if (mCamcorderProfiles[i]->mCameraId == cameraId && - mCamcorderProfiles[i]->mQuality == quality) { - index = i; - break; - } - } - return index; -} - -int MediaProfiles::getCamcorderProfileParamByName(const char *name, - int cameraId, - camcorder_quality quality) const -{ - ALOGV("getCamcorderProfileParamByName: %s for camera %d, quality %d", - name, cameraId, quality); - - int index = getCamcorderProfileIndex(cameraId, quality); - if (index == -1) { - ALOGE("The given camcorder profile camera %d quality %d is not found", - cameraId, quality); - return -1; - } - - if (!strcmp("duration", name)) return mCamcorderProfiles[index]->mDuration; - if (!strcmp("file.format", name)) return mCamcorderProfiles[index]->mFileFormat; - if (!strcmp("vid.codec", name)) return mCamcorderProfiles[index]->mVideoCodec->mCodec; - if (!strcmp("vid.width", name)) return mCamcorderProfiles[index]->mVideoCodec->mFrameWidth; - if (!strcmp("vid.height", name)) return mCamcorderProfiles[index]->mVideoCodec->mFrameHeight; - if (!strcmp("vid.bps", name)) return mCamcorderProfiles[index]->mVideoCodec->mBitRate; - if (!strcmp("vid.fps", name)) return mCamcorderProfiles[index]->mVideoCodec->mFrameRate; - if (!strcmp("aud.codec", name)) return mCamcorderProfiles[index]->mAudioCodec->mCodec; - if (!strcmp("aud.bps", name)) return mCamcorderProfiles[index]->mAudioCodec->mBitRate; - if (!strcmp("aud.ch", name)) return mCamcorderProfiles[index]->mAudioCodec->mChannels; - if (!strcmp("aud.hz", name)) return mCamcorderProfiles[index]->mAudioCodec->mSampleRate; - - ALOGE("The given camcorder profile param id %d name %s is not found", cameraId, name); - return -1; -} - -bool MediaProfiles::hasCamcorderProfile(int cameraId, camcorder_quality quality) const -{ - return (getCamcorderProfileIndex(cameraId, quality) != -1); -} - -Vector<int> MediaProfiles::getImageEncodingQualityLevels(int cameraId) const -{ - Vector<int> result; - ImageEncodingQualityLevels *levels = findImageEncodingQualityLevels(cameraId); - if (levels != NULL) { - result = levels->mLevels; // copy out - } - return result; -} - -int MediaProfiles::getStartTimeOffsetMs(int cameraId) const { - int offsetTimeMs = -1; - ssize_t index = mStartTimeOffsets.indexOfKey(cameraId); - if (index >= 0) { - offsetTimeMs = mStartTimeOffsets.valueFor(cameraId); - } - ALOGV("offsetTime=%d ms and cameraId=%d", offsetTimeMs, cameraId); - return offsetTimeMs; -} - -MediaProfiles::~MediaProfiles() -{ - CHECK("destructor should never be called" == 0); -#if 0 - for (size_t i = 0; i < mAudioEncoders.size(); ++i) { - delete mAudioEncoders[i]; - } - mAudioEncoders.clear(); - - for (size_t i = 0; i < mVideoEncoders.size(); ++i) { - delete mVideoEncoders[i]; - } - mVideoEncoders.clear(); - - for (size_t i = 0; i < mVideoDecoders.size(); ++i) { - delete mVideoDecoders[i]; - } - mVideoDecoders.clear(); - - for (size_t i = 0; i < mAudioDecoders.size(); ++i) { - delete mAudioDecoders[i]; - } - mAudioDecoders.clear(); - - for (size_t i = 0; i < mCamcorderProfiles.size(); ++i) { - delete mCamcorderProfiles[i]; - } - mCamcorderProfiles.clear(); -#endif -} -} // namespace android diff --git a/media/libmedia/MediaScanner.cpp b/media/libmedia/MediaScanner.cpp deleted file mode 100644 index 28b5aa7..0000000 --- a/media/libmedia/MediaScanner.cpp +++ /dev/null @@ -1,240 +0,0 @@ -/* - * Copyright (C) 2009 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_NDEBUG 0 -#define LOG_TAG "MediaScanner" -#include <cutils/properties.h> -#include <utils/Log.h> - -#include <media/mediascanner.h> - -#include <sys/stat.h> -#include <dirent.h> - -namespace android { - -MediaScanner::MediaScanner() - : mLocale(NULL), mSkipList(NULL), mSkipIndex(NULL) { - loadSkipList(); -} - -MediaScanner::~MediaScanner() { - setLocale(NULL); - free(mSkipList); - free(mSkipIndex); -} - -void MediaScanner::setLocale(const char *locale) { - if (mLocale) { - free(mLocale); - mLocale = NULL; - } - if (locale) { - mLocale = strdup(locale); - } -} - -const char *MediaScanner::locale() const { - return mLocale; -} - -void MediaScanner::loadSkipList() { - mSkipList = (char *)malloc(PROPERTY_VALUE_MAX * sizeof(char)); - if (mSkipList) { - property_get("testing.mediascanner.skiplist", mSkipList, ""); - } - if (!mSkipList || (strlen(mSkipList) == 0)) { - free(mSkipList); - mSkipList = NULL; - return; - } - mSkipIndex = (int *)malloc(PROPERTY_VALUE_MAX * sizeof(int)); - if (mSkipIndex) { - // dup it because strtok will modify the string - char *skipList = strdup(mSkipList); - if (skipList) { - char * path = strtok(skipList, ","); - int i = 0; - while (path) { - mSkipIndex[i++] = strlen(path); - path = strtok(NULL, ","); - } - mSkipIndex[i] = -1; - free(skipList); - } - } -} - -MediaScanResult MediaScanner::processDirectory( - const char *path, MediaScannerClient &client) { - int pathLength = strlen(path); - if (pathLength >= PATH_MAX) { - return MEDIA_SCAN_RESULT_SKIPPED; - } - char* pathBuffer = (char *)malloc(PATH_MAX + 1); - if (!pathBuffer) { - return MEDIA_SCAN_RESULT_ERROR; - } - - int pathRemaining = PATH_MAX - pathLength; - strcpy(pathBuffer, path); - if (pathLength > 0 && pathBuffer[pathLength - 1] != '/') { - pathBuffer[pathLength] = '/'; - pathBuffer[pathLength + 1] = 0; - --pathRemaining; - } - - client.setLocale(locale()); - - MediaScanResult result = doProcessDirectory(pathBuffer, pathRemaining, client, false); - - free(pathBuffer); - - return result; -} - -bool MediaScanner::shouldSkipDirectory(char *path) { - if (path && mSkipList && mSkipIndex) { - int len = strlen(path); - int idx = 0; - // track the start position of next path in the comma - // separated list obtained from getprop - int startPos = 0; - while (mSkipIndex[idx] != -1) { - // no point to match path name if strlen mismatch - if ((len == mSkipIndex[idx]) - // pick out the path segment from comma separated list - // to compare against current path parameter - && (strncmp(path, &mSkipList[startPos], len) == 0)) { - return true; - } - startPos += mSkipIndex[idx] + 1; // extra char for the delimiter - idx++; - } - } - return false; -} - -MediaScanResult MediaScanner::doProcessDirectory( - char *path, int pathRemaining, MediaScannerClient &client, bool noMedia) { - // place to copy file or directory name - char* fileSpot = path + strlen(path); - struct dirent* entry; - - if (shouldSkipDirectory(path)) { - ALOGD("Skipping: %s", path); - return MEDIA_SCAN_RESULT_OK; - } - - // Treat all files as non-media in directories that contain a ".nomedia" file - if (pathRemaining >= 8 /* strlen(".nomedia") */ ) { - strcpy(fileSpot, ".nomedia"); - if (access(path, F_OK) == 0) { - ALOGV("found .nomedia, setting noMedia flag"); - noMedia = true; - } - - // restore path - fileSpot[0] = 0; - } - - DIR* dir = opendir(path); - if (!dir) { - ALOGW("Error opening directory '%s', skipping: %s.", path, strerror(errno)); - return MEDIA_SCAN_RESULT_SKIPPED; - } - - MediaScanResult result = MEDIA_SCAN_RESULT_OK; - while ((entry = readdir(dir))) { - if (doProcessDirectoryEntry(path, pathRemaining, client, noMedia, entry, fileSpot) - == MEDIA_SCAN_RESULT_ERROR) { - result = MEDIA_SCAN_RESULT_ERROR; - break; - } - } - closedir(dir); - return result; -} - -MediaScanResult MediaScanner::doProcessDirectoryEntry( - char *path, int pathRemaining, MediaScannerClient &client, bool noMedia, - struct dirent* entry, char* fileSpot) { - struct stat statbuf; - const char* name = entry->d_name; - - // ignore "." and ".." - if (name[0] == '.' && (name[1] == 0 || (name[1] == '.' && name[2] == 0))) { - return MEDIA_SCAN_RESULT_SKIPPED; - } - - int nameLength = strlen(name); - if (nameLength + 1 > pathRemaining) { - // path too long! - return MEDIA_SCAN_RESULT_SKIPPED; - } - strcpy(fileSpot, name); - - int type = entry->d_type; - if (type == DT_UNKNOWN) { - // If the type is unknown, stat() the file instead. - // This is sometimes necessary when accessing NFS mounted filesystems, but - // could be needed in other cases well. - if (stat(path, &statbuf) == 0) { - if (S_ISREG(statbuf.st_mode)) { - type = DT_REG; - } else if (S_ISDIR(statbuf.st_mode)) { - type = DT_DIR; - } - } else { - ALOGD("stat() failed for %s: %s", path, strerror(errno) ); - } - } - if (type == DT_DIR) { - bool childNoMedia = noMedia; - // set noMedia flag on directories with a name that starts with '.' - // for example, the Mac ".Trashes" directory - if (name[0] == '.') - childNoMedia = true; - - // report the directory to the client - if (stat(path, &statbuf) == 0) { - status_t status = client.scanFile(path, statbuf.st_mtime, 0, - true /*isDirectory*/, childNoMedia); - if (status) { - return MEDIA_SCAN_RESULT_ERROR; - } - } - - // and now process its contents - strcat(fileSpot, "/"); - MediaScanResult result = doProcessDirectory(path, pathRemaining - nameLength - 1, - client, childNoMedia); - if (result == MEDIA_SCAN_RESULT_ERROR) { - return MEDIA_SCAN_RESULT_ERROR; - } - } else if (type == DT_REG) { - stat(path, &statbuf); - status_t status = client.scanFile(path, statbuf.st_mtime, statbuf.st_size, - false /*isDirectory*/, noMedia); - if (status) { - return MEDIA_SCAN_RESULT_ERROR; - } - } - - return MEDIA_SCAN_RESULT_OK; -} - -} // namespace android diff --git a/media/libmedia/MediaScannerClient.cpp b/media/libmedia/MediaScannerClient.cpp deleted file mode 100644 index e1e3348..0000000 --- a/media/libmedia/MediaScannerClient.cpp +++ /dev/null @@ -1,230 +0,0 @@ -/* - * Copyright (C) 2009 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/mediascanner.h> - -#include <utils/StringArray.h> - -#include "autodetect.h" -#include "unicode/ucnv.h" -#include "unicode/ustring.h" - -namespace android { - -MediaScannerClient::MediaScannerClient() - : mNames(NULL), - mValues(NULL), - mLocaleEncoding(kEncodingNone) -{ -} - -MediaScannerClient::~MediaScannerClient() -{ - delete mNames; - delete mValues; -} - -void MediaScannerClient::setLocale(const char* locale) -{ - if (!locale) return; - - if (!strncmp(locale, "ja", 2)) - mLocaleEncoding = kEncodingShiftJIS; - else if (!strncmp(locale, "ko", 2)) - mLocaleEncoding = kEncodingEUCKR; - else if (!strncmp(locale, "zh", 2)) { - if (!strcmp(locale, "zh_CN")) { - // simplified chinese for mainland China - mLocaleEncoding = kEncodingGBK; - } else { - // assume traditional for non-mainland Chinese locales (Taiwan, Hong Kong, Singapore) - mLocaleEncoding = kEncodingBig5; - } - } -} - -void MediaScannerClient::beginFile() -{ - mNames = new StringArray; - mValues = new StringArray; -} - -status_t MediaScannerClient::addStringTag(const char* name, const char* value) -{ - if (mLocaleEncoding != kEncodingNone) { - // don't bother caching strings that are all ASCII. - // call handleStringTag directly instead. - // check to see if value (which should be utf8) has any non-ASCII characters - bool nonAscii = false; - const char* chp = value; - char ch; - while ((ch = *chp++)) { - if (ch & 0x80) { - nonAscii = true; - break; - } - } - - if (nonAscii) { - // save the strings for later so they can be used for native encoding detection - mNames->push_back(name); - mValues->push_back(value); - return OK; - } - // else fall through - } - - // autodetection is not necessary, so no need to cache the values - // pass directly to the client instead - return handleStringTag(name, value); -} - -static uint32_t possibleEncodings(const char* s) -{ - uint32_t result = kEncodingAll; - // if s contains a native encoding, then it was mistakenly encoded in utf8 as if it were latin-1 - // so we need to reverse the latin-1 -> utf8 conversion to get the native chars back - uint8_t ch1, ch2; - uint8_t* chp = (uint8_t *)s; - - while ((ch1 = *chp++)) { - if (ch1 & 0x80) { - ch2 = *chp++; - ch1 = ((ch1 << 6) & 0xC0) | (ch2 & 0x3F); - // ch1 is now the first byte of the potential native char - - ch2 = *chp++; - if (ch2 & 0x80) - ch2 = ((ch2 << 6) & 0xC0) | (*chp++ & 0x3F); - // ch2 is now the second byte of the potential native char - int ch = (int)ch1 << 8 | (int)ch2; - result &= findPossibleEncodings(ch); - } - // else ASCII character, which could be anything - } - - return result; -} - -void MediaScannerClient::convertValues(uint32_t encoding) -{ - const char* enc = NULL; - switch (encoding) { - case kEncodingShiftJIS: - enc = "shift-jis"; - break; - case kEncodingGBK: - enc = "gbk"; - break; - case kEncodingBig5: - enc = "Big5"; - break; - case kEncodingEUCKR: - enc = "EUC-KR"; - break; - } - - if (enc) { - UErrorCode status = U_ZERO_ERROR; - - UConverter *conv = ucnv_open(enc, &status); - if (U_FAILURE(status)) { - ALOGE("could not create UConverter for %s", enc); - return; - } - UConverter *utf8Conv = ucnv_open("UTF-8", &status); - if (U_FAILURE(status)) { - ALOGE("could not create UConverter for UTF-8"); - ucnv_close(conv); - return; - } - - // for each value string, convert from native encoding to UTF-8 - for (int i = 0; i < mNames->size(); i++) { - // first we need to untangle the utf8 and convert it back to the original bytes - // since we are reducing the length of the string, we can do this in place - uint8_t* src = (uint8_t *)mValues->getEntry(i); - int len = strlen((char *)src); - uint8_t* dest = src; - - uint8_t uch; - while ((uch = *src++)) { - if (uch & 0x80) - *dest++ = ((uch << 6) & 0xC0) | (*src++ & 0x3F); - else - *dest++ = uch; - } - *dest = 0; - - // now convert from native encoding to UTF-8 - const char* source = mValues->getEntry(i); - int targetLength = len * 3 + 1; - char* buffer = new char[targetLength]; - // don't normally check for NULL, but in this case targetLength may be large - if (!buffer) - break; - char* target = buffer; - - ucnv_convertEx(utf8Conv, conv, &target, target + targetLength, - &source, (const char *)dest, NULL, NULL, NULL, NULL, TRUE, TRUE, &status); - if (U_FAILURE(status)) { - ALOGE("ucnv_convertEx failed: %d", status); - mValues->setEntry(i, "???"); - } else { - // zero terminate - *target = 0; - mValues->setEntry(i, buffer); - } - - delete[] buffer; - } - - ucnv_close(conv); - ucnv_close(utf8Conv); - } -} - -void MediaScannerClient::endFile() -{ - if (mLocaleEncoding != kEncodingNone) { - int size = mNames->size(); - uint32_t encoding = kEncodingAll; - - // compute a bit mask containing all possible encodings - for (int i = 0; i < mNames->size(); i++) - encoding &= possibleEncodings(mValues->getEntry(i)); - - // if the locale encoding matches, then assume we have a native encoding. - if (encoding & mLocaleEncoding) - convertValues(mLocaleEncoding); - - // finally, push all name/value pairs to the client - for (int i = 0; i < mNames->size(); i++) { - status_t status = handleStringTag(mNames->getEntry(i), mValues->getEntry(i)); - if (status) { - break; - } - } - } - // else addStringTag() has done all the work so we have nothing to do - - delete mNames; - delete mValues; - mNames = NULL; - mValues = NULL; -} - -} // namespace android diff --git a/media/libmedia/MemoryLeakTrackUtil.cpp b/media/libmedia/MemoryLeakTrackUtil.cpp deleted file mode 100644 index 6a108ae..0000000 --- a/media/libmedia/MemoryLeakTrackUtil.cpp +++ /dev/null @@ -1,169 +0,0 @@ -/* - * 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/Metadata.cpp b/media/libmedia/Metadata.cpp deleted file mode 100644 index ef8a9ed..0000000 --- a/media/libmedia/Metadata.cpp +++ /dev/null @@ -1,167 +0,0 @@ -/* - * Copyright (C) 2009 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_NDEBUG 0 -#define LOG_TAG "Metadata" -#include <utils/Log.h> - -#include <sys/types.h> -#include <media/Metadata.h> -#include <binder/Parcel.h> -#include <utils/Errors.h> -#include <utils/RefBase.h> - -// This file contains code to serialize Metadata triples (key, type, -// value) into a parcel. The Parcel is destinated to be decoded by the -// Metadata.java class. - -namespace { -// All these constants below must be kept in sync with Metadata.java. -enum MetadataId { - FIRST_SYSTEM_ID = 1, - LAST_SYSTEM_ID = 31, - FIRST_CUSTOM_ID = 8192 -}; - -// Types -enum Types { - STRING_VAL = 1, - INTEGER_VAL, - BOOLEAN_VAL, - LONG_VAL, - DOUBLE_VAL, - DATE_VAL, - BYTE_ARRAY_VAL, -}; - -const size_t kRecordHeaderSize = 3 * sizeof(int32_t); -const int32_t kMetaMarker = 0x4d455441; // 'M' 'E' 'T' 'A' - -} // anonymous namespace - -namespace android { -namespace media { - -Metadata::Metadata(Parcel *p) - :mData(p), - mBegin(p->dataPosition()) { } - -Metadata::~Metadata() { } - -void Metadata::resetParcel() -{ - mData->setDataPosition(mBegin); -} - -// Update the 4 bytes int at the beginning of the parcel which holds -// the number of bytes written so far. -void Metadata::updateLength() -{ - const size_t end = mData->dataPosition(); - - mData->setDataPosition(mBegin); - mData->writeInt32(end - mBegin); - mData->setDataPosition(end); -} - -// Write the header. The java layer will look for the marker. -bool Metadata::appendHeader() -{ - bool ok = true; - - // Placeholder for the length of the metadata - ok = ok && mData->writeInt32(-1) == OK; - ok = ok && mData->writeInt32(kMetaMarker) == OK; - return ok; -} - -bool Metadata::appendBool(int key, bool val) -{ - if (!checkKey(key)) { - return false; - } - - const size_t begin = mData->dataPosition(); - bool ok = true; - - // 4 int32s: size, key, type, value. - ok = ok && mData->writeInt32(4 * sizeof(int32_t)) == OK; - ok = ok && mData->writeInt32(key) == OK; - ok = ok && mData->writeInt32(BOOLEAN_VAL) == OK; - ok = ok && mData->writeInt32(val ? 1 : 0) == OK; - if (!ok) { - mData->setDataPosition(begin); - } - return ok; -} - -bool Metadata::appendInt32(int key, int32_t val) -{ - if (!checkKey(key)) { - return false; - } - - const size_t begin = mData->dataPosition(); - bool ok = true; - - // 4 int32s: size, key, type, value. - ok = ok && mData->writeInt32(4 * sizeof(int32_t)) == OK; - ok = ok && mData->writeInt32(key) == OK; - ok = ok && mData->writeInt32(INTEGER_VAL) == OK; - ok = ok && mData->writeInt32(val) == OK; - if (!ok) { - mData->setDataPosition(begin); - } - return ok; -} - -// Check the key (i.e metadata id) is valid if it is a system one. -// Loop over all the exiting ones in the Parcel to check for duplicate -// (not allowed). -bool Metadata::checkKey(int key) -{ - if (key < FIRST_SYSTEM_ID || - (LAST_SYSTEM_ID < key && key < FIRST_CUSTOM_ID)) { - ALOGE("Bad key %d", key); - return false; - } - size_t curr = mData->dataPosition(); - // Loop over the keys to check if it has been used already. - mData->setDataPosition(mBegin); - - bool error = false; - size_t left = curr - mBegin; - while (left > 0) { - size_t pos = mData->dataPosition(); - size_t size = mData->readInt32(); - if (size < kRecordHeaderSize || size > left) { - error = true; - break; - } - if (mData->readInt32() == key) { - ALOGE("Key exists already %d", key); - error = true; - break; - } - mData->setDataPosition(pos + size); - left -= size; - } - mData->setDataPosition(curr); - return !error; -} - -} // namespace android::media -} // namespace android diff --git a/media/libmedia/NOTICE b/media/libmedia/NOTICE deleted file mode 100644 index c5b1efa..0000000 --- a/media/libmedia/NOTICE +++ /dev/null @@ -1,190 +0,0 @@ - - Copyright (c) 2005-2008, 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. - - 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. - - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - diff --git a/media/libmedia/SoundPool.cpp b/media/libmedia/SoundPool.cpp deleted file mode 100644 index 306c57d..0000000 --- a/media/libmedia/SoundPool.cpp +++ /dev/null @@ -1,908 +0,0 @@ -/* - * Copyright (C) 2007 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_NDEBUG 0 -#define LOG_TAG "SoundPool" -#include <utils/Log.h> - -//#define USE_SHARED_MEM_BUFFER - -// XXX needed for timing latency -#include <utils/Timers.h> - -#include <media/AudioTrack.h> -#include <media/mediaplayer.h> - -#include <system/audio.h> - -#include "SoundPool.h" -#include "SoundPoolThread.h" - -namespace android -{ - -int kDefaultBufferCount = 4; -uint32_t kMaxSampleRate = 48000; -uint32_t kDefaultSampleRate = 44100; -uint32_t kDefaultFrameCount = 1200; - -SoundPool::SoundPool(int maxChannels, audio_stream_type_t streamType, int srcQuality) -{ - ALOGV("SoundPool constructor: maxChannels=%d, streamType=%d, srcQuality=%d", - maxChannels, streamType, srcQuality); - - // check limits - mMaxChannels = maxChannels; - if (mMaxChannels < 1) { - mMaxChannels = 1; - } - else if (mMaxChannels > 32) { - mMaxChannels = 32; - } - ALOGW_IF(maxChannels != mMaxChannels, "App requested %d channels", maxChannels); - - mQuit = false; - mDecodeThread = 0; - mStreamType = streamType; - mSrcQuality = srcQuality; - mAllocated = 0; - mNextSampleID = 0; - mNextChannelID = 0; - - mCallback = 0; - mUserData = 0; - - mChannelPool = new SoundChannel[mMaxChannels]; - for (int i = 0; i < mMaxChannels; ++i) { - mChannelPool[i].init(this); - mChannels.push_back(&mChannelPool[i]); - } - - // start decode thread - startThreads(); -} - -SoundPool::~SoundPool() -{ - ALOGV("SoundPool destructor"); - mDecodeThread->quit(); - quit(); - - Mutex::Autolock lock(&mLock); - - mChannels.clear(); - if (mChannelPool) - delete [] mChannelPool; - // clean up samples - ALOGV("clear samples"); - mSamples.clear(); - - if (mDecodeThread) - delete mDecodeThread; -} - -void SoundPool::addToRestartList(SoundChannel* channel) -{ - Mutex::Autolock lock(&mRestartLock); - if (!mQuit) { - mRestart.push_back(channel); - mCondition.signal(); - } -} - -void SoundPool::addToStopList(SoundChannel* channel) -{ - Mutex::Autolock lock(&mRestartLock); - if (!mQuit) { - mStop.push_back(channel); - mCondition.signal(); - } -} - -int SoundPool::beginThread(void* arg) -{ - SoundPool* p = (SoundPool*)arg; - return p->run(); -} - -int SoundPool::run() -{ - mRestartLock.lock(); - while (!mQuit) { - mCondition.wait(mRestartLock); - ALOGV("awake"); - if (mQuit) break; - - while (!mStop.empty()) { - SoundChannel* channel; - ALOGV("Getting channel from stop list"); - List<SoundChannel* >::iterator iter = mStop.begin(); - channel = *iter; - mStop.erase(iter); - mRestartLock.unlock(); - if (channel != 0) { - Mutex::Autolock lock(&mLock); - channel->stop(); - } - mRestartLock.lock(); - if (mQuit) break; - } - - while (!mRestart.empty()) { - SoundChannel* channel; - ALOGV("Getting channel from list"); - List<SoundChannel*>::iterator iter = mRestart.begin(); - channel = *iter; - mRestart.erase(iter); - mRestartLock.unlock(); - if (channel != 0) { - Mutex::Autolock lock(&mLock); - channel->nextEvent(); - } - mRestartLock.lock(); - if (mQuit) break; - } - } - - mStop.clear(); - mRestart.clear(); - mCondition.signal(); - mRestartLock.unlock(); - ALOGV("goodbye"); - return 0; -} - -void SoundPool::quit() -{ - mRestartLock.lock(); - mQuit = true; - mCondition.signal(); - mCondition.wait(mRestartLock); - ALOGV("return from quit"); - mRestartLock.unlock(); -} - -bool SoundPool::startThreads() -{ - createThreadEtc(beginThread, this, "SoundPool"); - if (mDecodeThread == NULL) - mDecodeThread = new SoundPoolThread(this); - return mDecodeThread != NULL; -} - -SoundChannel* SoundPool::findChannel(int channelID) -{ - for (int i = 0; i < mMaxChannels; ++i) { - if (mChannelPool[i].channelID() == channelID) { - return &mChannelPool[i]; - } - } - return NULL; -} - -SoundChannel* SoundPool::findNextChannel(int channelID) -{ - for (int i = 0; i < mMaxChannels; ++i) { - if (mChannelPool[i].nextChannelID() == channelID) { - return &mChannelPool[i]; - } - } - return NULL; -} - -int SoundPool::load(const char* path, int priority) -{ - ALOGV("load: path=%s, priority=%d", path, priority); - Mutex::Autolock lock(&mLock); - sp<Sample> sample = new Sample(++mNextSampleID, path); - mSamples.add(sample->sampleID(), sample); - doLoad(sample); - return sample->sampleID(); -} - -int SoundPool::load(int fd, int64_t offset, int64_t length, int priority) -{ - ALOGV("load: fd=%d, offset=%lld, length=%lld, priority=%d", - fd, offset, length, priority); - Mutex::Autolock lock(&mLock); - sp<Sample> sample = new Sample(++mNextSampleID, fd, offset, length); - mSamples.add(sample->sampleID(), sample); - doLoad(sample); - return sample->sampleID(); -} - -void SoundPool::doLoad(sp<Sample>& sample) -{ - ALOGV("doLoad: loading sample sampleID=%d", sample->sampleID()); - sample->startLoad(); - mDecodeThread->loadSample(sample->sampleID()); -} - -bool SoundPool::unload(int sampleID) -{ - ALOGV("unload: sampleID=%d", sampleID); - Mutex::Autolock lock(&mLock); - return mSamples.removeItem(sampleID); -} - -int SoundPool::play(int sampleID, float leftVolume, float rightVolume, - int priority, int loop, float rate) -{ - ALOGV("play sampleID=%d, leftVolume=%f, rightVolume=%f, priority=%d, loop=%d, rate=%f", - sampleID, leftVolume, rightVolume, priority, loop, rate); - sp<Sample> sample; - SoundChannel* channel; - int channelID; - - Mutex::Autolock lock(&mLock); - - if (mQuit) { - return 0; - } - // is sample ready? - sample = findSample(sampleID); - if ((sample == 0) || (sample->state() != Sample::READY)) { - ALOGW(" sample %d not READY", sampleID); - return 0; - } - - dump(); - - // allocate a channel - channel = allocateChannel_l(priority); - - // no channel allocated - return 0 - if (!channel) { - ALOGV("No channel allocated"); - return 0; - } - - channelID = ++mNextChannelID; - - ALOGV("play channel %p state = %d", channel, channel->state()); - channel->play(sample, channelID, leftVolume, rightVolume, priority, loop, rate); - return channelID; -} - -SoundChannel* SoundPool::allocateChannel_l(int priority) -{ - List<SoundChannel*>::iterator iter; - SoundChannel* channel = NULL; - - // allocate a channel - if (!mChannels.empty()) { - iter = mChannels.begin(); - if (priority >= (*iter)->priority()) { - channel = *iter; - mChannels.erase(iter); - ALOGV("Allocated active channel"); - } - } - - // update priority and put it back in the list - if (channel) { - channel->setPriority(priority); - for (iter = mChannels.begin(); iter != mChannels.end(); ++iter) { - if (priority < (*iter)->priority()) { - break; - } - } - mChannels.insert(iter, channel); - } - return channel; -} - -// move a channel from its current position to the front of the list -void SoundPool::moveToFront_l(SoundChannel* channel) -{ - for (List<SoundChannel*>::iterator iter = mChannels.begin(); iter != mChannels.end(); ++iter) { - if (*iter == channel) { - mChannels.erase(iter); - mChannels.push_front(channel); - break; - } - } -} - -void SoundPool::pause(int channelID) -{ - ALOGV("pause(%d)", channelID); - Mutex::Autolock lock(&mLock); - SoundChannel* channel = findChannel(channelID); - if (channel) { - channel->pause(); - } -} - -void SoundPool::autoPause() -{ - ALOGV("autoPause()"); - Mutex::Autolock lock(&mLock); - for (int i = 0; i < mMaxChannels; ++i) { - SoundChannel* channel = &mChannelPool[i]; - channel->autoPause(); - } -} - -void SoundPool::resume(int channelID) -{ - ALOGV("resume(%d)", channelID); - Mutex::Autolock lock(&mLock); - SoundChannel* channel = findChannel(channelID); - if (channel) { - channel->resume(); - } -} - -void SoundPool::autoResume() -{ - ALOGV("autoResume()"); - Mutex::Autolock lock(&mLock); - for (int i = 0; i < mMaxChannels; ++i) { - SoundChannel* channel = &mChannelPool[i]; - channel->autoResume(); - } -} - -void SoundPool::stop(int channelID) -{ - ALOGV("stop(%d)", channelID); - Mutex::Autolock lock(&mLock); - SoundChannel* channel = findChannel(channelID); - if (channel) { - channel->stop(); - } else { - channel = findNextChannel(channelID); - if (channel) - channel->clearNextEvent(); - } -} - -void SoundPool::setVolume(int channelID, float leftVolume, float rightVolume) -{ - Mutex::Autolock lock(&mLock); - SoundChannel* channel = findChannel(channelID); - if (channel) { - channel->setVolume(leftVolume, rightVolume); - } -} - -void SoundPool::setPriority(int channelID, int priority) -{ - ALOGV("setPriority(%d, %d)", channelID, priority); - Mutex::Autolock lock(&mLock); - SoundChannel* channel = findChannel(channelID); - if (channel) { - channel->setPriority(priority); - } -} - -void SoundPool::setLoop(int channelID, int loop) -{ - ALOGV("setLoop(%d, %d)", channelID, loop); - Mutex::Autolock lock(&mLock); - SoundChannel* channel = findChannel(channelID); - if (channel) { - channel->setLoop(loop); - } -} - -void SoundPool::setRate(int channelID, float rate) -{ - ALOGV("setRate(%d, %f)", channelID, rate); - Mutex::Autolock lock(&mLock); - SoundChannel* channel = findChannel(channelID); - if (channel) { - channel->setRate(rate); - } -} - -// call with lock held -void SoundPool::done_l(SoundChannel* channel) -{ - ALOGV("done_l(%d)", channel->channelID()); - // if "stolen", play next event - if (channel->nextChannelID() != 0) { - ALOGV("add to restart list"); - addToRestartList(channel); - } - - // return to idle state - else { - ALOGV("move to front"); - moveToFront_l(channel); - } -} - -void SoundPool::setCallback(SoundPoolCallback* callback, void* user) -{ - Mutex::Autolock lock(&mCallbackLock); - mCallback = callback; - mUserData = user; -} - -void SoundPool::notify(SoundPoolEvent event) -{ - Mutex::Autolock lock(&mCallbackLock); - if (mCallback != NULL) { - mCallback(event, this, mUserData); - } -} - -void SoundPool::dump() -{ - for (int i = 0; i < mMaxChannels; ++i) { - mChannelPool[i].dump(); - } -} - - -Sample::Sample(int sampleID, const char* url) -{ - init(); - mSampleID = sampleID; - mUrl = strdup(url); - ALOGV("create sampleID=%d, url=%s", mSampleID, mUrl); -} - -Sample::Sample(int sampleID, int fd, int64_t offset, int64_t length) -{ - init(); - mSampleID = sampleID; - mFd = dup(fd); - mOffset = offset; - mLength = length; - ALOGV("create sampleID=%d, fd=%d, offset=%lld, length=%lld", mSampleID, mFd, mLength, mOffset); -} - -void Sample::init() -{ - mData = 0; - mSize = 0; - mRefCount = 0; - mSampleID = 0; - mState = UNLOADED; - mFd = -1; - mOffset = 0; - mLength = 0; - mUrl = 0; -} - -Sample::~Sample() -{ - ALOGV("Sample::destructor sampleID=%d, fd=%d", mSampleID, mFd); - if (mFd > 0) { - ALOGV("close(%d)", mFd); - ::close(mFd); - } - mData.clear(); - delete mUrl; -} - -status_t Sample::doLoad() -{ - uint32_t sampleRate; - int numChannels; - audio_format_t format; - sp<IMemory> p; - ALOGV("Start decode"); - if (mUrl) { - p = MediaPlayer::decode(mUrl, &sampleRate, &numChannels, &format); - } else { - p = MediaPlayer::decode(mFd, mOffset, mLength, &sampleRate, &numChannels, &format); - ALOGV("close(%d)", mFd); - ::close(mFd); - mFd = -1; - } - if (p == 0) { - ALOGE("Unable to load sample: %s", mUrl); - return -1; - } - ALOGV("pointer = %p, size = %u, sampleRate = %u, numChannels = %d", - p->pointer(), p->size(), sampleRate, numChannels); - - if (sampleRate > kMaxSampleRate) { - ALOGE("Sample rate (%u) out of range", sampleRate); - return - 1; - } - - if ((numChannels < 1) || (numChannels > 2)) { - ALOGE("Sample channel count (%d) out of range", numChannels); - return - 1; - } - - //_dumpBuffer(p->pointer(), p->size()); - uint8_t* q = static_cast<uint8_t*>(p->pointer()) + p->size() - 10; - //_dumpBuffer(q, 10, 10, false); - - mData = p; - mSize = p->size(); - mSampleRate = sampleRate; - mNumChannels = numChannels; - mFormat = format; - mState = READY; - return 0; -} - - -void SoundChannel::init(SoundPool* soundPool) -{ - mSoundPool = soundPool; -} - -// call with sound pool lock held -void SoundChannel::play(const sp<Sample>& sample, int nextChannelID, float leftVolume, - float rightVolume, int priority, int loop, float rate) -{ - AudioTrack* oldTrack; - AudioTrack* newTrack; - status_t status; - - { // scope for the lock - Mutex::Autolock lock(&mLock); - - ALOGV("SoundChannel::play %p: sampleID=%d, channelID=%d, leftVolume=%f, rightVolume=%f," - " priority=%d, loop=%d, rate=%f", - this, sample->sampleID(), nextChannelID, leftVolume, rightVolume, - priority, loop, rate); - - // if not idle, this voice is being stolen - if (mState != IDLE) { - ALOGV("channel %d stolen - event queued for channel %d", channelID(), nextChannelID); - mNextEvent.set(sample, nextChannelID, leftVolume, rightVolume, priority, loop, rate); - stop_l(); - return; - } - - // initialize track - int afFrameCount; - int afSampleRate; - audio_stream_type_t streamType = mSoundPool->streamType(); - if (AudioSystem::getOutputFrameCount(&afFrameCount, streamType) != NO_ERROR) { - afFrameCount = kDefaultFrameCount; - } - if (AudioSystem::getOutputSamplingRate(&afSampleRate, streamType) != NO_ERROR) { - afSampleRate = kDefaultSampleRate; - } - int numChannels = sample->numChannels(); - uint32_t sampleRate = uint32_t(float(sample->sampleRate()) * rate + 0.5); - uint32_t totalFrames = (kDefaultBufferCount * afFrameCount * sampleRate) / afSampleRate; - uint32_t bufferFrames = (totalFrames + (kDefaultBufferCount - 1)) / kDefaultBufferCount; - uint32_t frameCount = 0; - - if (loop) { - frameCount = sample->size()/numChannels/ - ((sample->format() == AUDIO_FORMAT_PCM_16_BIT) ? sizeof(int16_t) : sizeof(uint8_t)); - } - -#ifndef USE_SHARED_MEM_BUFFER - // Ensure minimum audio buffer size in case of short looped sample - if(frameCount < totalFrames) { - frameCount = totalFrames; - } -#endif - - // mToggle toggles each time a track is started on a given channel. - // The toggle is concatenated with the SoundChannel address and passed to AudioTrack - // as callback user data. This enables the detection of callbacks received from the old - // audio track while the new one is being started and avoids processing them with - // wrong audio audio buffer size (mAudioBufferSize) - unsigned long toggle = mToggle ^ 1; - void *userData = (void *)((unsigned long)this | toggle); - uint32_t channels = (numChannels == 2) ? - AUDIO_CHANNEL_OUT_STEREO : AUDIO_CHANNEL_OUT_MONO; - - // do not create a new audio track if current track is compatible with sample parameters -#ifdef USE_SHARED_MEM_BUFFER - newTrack = new AudioTrack(streamType, sampleRate, sample->format(), - channels, sample->getIMemory(), AUDIO_POLICY_OUTPUT_FLAG_NONE, callback, userData); -#else - newTrack = new AudioTrack(streamType, sampleRate, sample->format(), - channels, frameCount, AUDIO_POLICY_OUTPUT_FLAG_NONE, callback, userData, - bufferFrames); -#endif - oldTrack = mAudioTrack; - status = newTrack->initCheck(); - if (status != NO_ERROR) { - ALOGE("Error creating AudioTrack"); - goto exit; - } - ALOGV("setVolume %p", newTrack); - newTrack->setVolume(leftVolume, rightVolume); - newTrack->setLoop(0, frameCount, loop); - - // From now on, AudioTrack callbacks received with previous toggle value will be ignored. - mToggle = toggle; - mAudioTrack = newTrack; - mPos = 0; - mSample = sample; - mChannelID = nextChannelID; - mPriority = priority; - mLoop = loop; - mLeftVolume = leftVolume; - mRightVolume = rightVolume; - mNumChannels = numChannels; - mRate = rate; - clearNextEvent(); - mState = PLAYING; - mAudioTrack->start(); - mAudioBufferSize = newTrack->frameCount()*newTrack->frameSize(); - } - -exit: - ALOGV("delete oldTrack %p", oldTrack); - delete oldTrack; - if (status != NO_ERROR) { - delete newTrack; - mAudioTrack = NULL; - } -} - -void SoundChannel::nextEvent() -{ - sp<Sample> sample; - int nextChannelID; - float leftVolume; - float rightVolume; - int priority; - int loop; - float rate; - - // check for valid event - { - Mutex::Autolock lock(&mLock); - nextChannelID = mNextEvent.channelID(); - if (nextChannelID == 0) { - ALOGV("stolen channel has no event"); - return; - } - - sample = mNextEvent.sample(); - leftVolume = mNextEvent.leftVolume(); - rightVolume = mNextEvent.rightVolume(); - priority = mNextEvent.priority(); - loop = mNextEvent.loop(); - rate = mNextEvent.rate(); - } - - ALOGV("Starting stolen channel %d -> %d", channelID(), nextChannelID); - play(sample, nextChannelID, leftVolume, rightVolume, priority, loop, rate); -} - -void SoundChannel::callback(int event, void* user, void *info) -{ - SoundChannel* channel = static_cast<SoundChannel*>((void *)((unsigned long)user & ~1)); - - channel->process(event, info, (unsigned long)user & 1); -} - -void SoundChannel::process(int event, void *info, unsigned long toggle) -{ - //ALOGV("process(%d)", mChannelID); - - Mutex::Autolock lock(&mLock); - - AudioTrack::Buffer* b = NULL; - if (event == AudioTrack::EVENT_MORE_DATA) { - b = static_cast<AudioTrack::Buffer *>(info); - } - - if (mToggle != toggle) { - ALOGV("process wrong toggle %p channel %d", this, mChannelID); - if (b != NULL) { - b->size = 0; - } - return; - } - - sp<Sample> sample = mSample; - -// ALOGV("SoundChannel::process event %d", event); - - if (event == AudioTrack::EVENT_MORE_DATA) { - - // check for stop state - if (b->size == 0) return; - - if (mState == IDLE) { - b->size = 0; - return; - } - - if (sample != 0) { - // fill buffer - uint8_t* q = (uint8_t*) b->i8; - size_t count = 0; - - if (mPos < (int)sample->size()) { - uint8_t* p = sample->data() + mPos; - count = sample->size() - mPos; - if (count > b->size) { - count = b->size; - } - memcpy(q, p, count); -// ALOGV("fill: q=%p, p=%p, mPos=%u, b->size=%u, count=%d", q, p, mPos, b->size, count); - } else if (mPos < mAudioBufferSize) { - count = mAudioBufferSize - mPos; - if (count > b->size) { - count = b->size; - } - memset(q, 0, count); -// ALOGV("fill extra: q=%p, mPos=%u, b->size=%u, count=%d", q, mPos, b->size, count); - } - - mPos += count; - b->size = count; - //ALOGV("buffer=%p, [0]=%d", b->i16, b->i16[0]); - } - } else if (event == AudioTrack::EVENT_UNDERRUN) { - ALOGV("process %p channel %d EVENT_UNDERRUN", this, mChannelID); - mSoundPool->addToStopList(this); - } else if (event == AudioTrack::EVENT_LOOP_END) { - ALOGV("End loop %p channel %d count %d", this, mChannelID, *(int *)info); - } -} - - -// call with lock held -bool SoundChannel::doStop_l() -{ - if (mState != IDLE) { - setVolume_l(0, 0); - ALOGV("stop"); - mAudioTrack->stop(); - mSample.clear(); - mState = IDLE; - mPriority = IDLE_PRIORITY; - return true; - } - return false; -} - -// call with lock held and sound pool lock held -void SoundChannel::stop_l() -{ - if (doStop_l()) { - mSoundPool->done_l(this); - } -} - -// call with sound pool lock held -void SoundChannel::stop() -{ - bool stopped; - { - Mutex::Autolock lock(&mLock); - stopped = doStop_l(); - } - - if (stopped) { - mSoundPool->done_l(this); - } -} - -//FIXME: Pause is a little broken right now -void SoundChannel::pause() -{ - Mutex::Autolock lock(&mLock); - if (mState == PLAYING) { - ALOGV("pause track"); - mState = PAUSED; - mAudioTrack->pause(); - } -} - -void SoundChannel::autoPause() -{ - Mutex::Autolock lock(&mLock); - if (mState == PLAYING) { - ALOGV("pause track"); - mState = PAUSED; - mAutoPaused = true; - mAudioTrack->pause(); - } -} - -void SoundChannel::resume() -{ - Mutex::Autolock lock(&mLock); - if (mState == PAUSED) { - ALOGV("resume track"); - mState = PLAYING; - mAutoPaused = false; - mAudioTrack->start(); - } -} - -void SoundChannel::autoResume() -{ - Mutex::Autolock lock(&mLock); - if (mAutoPaused && (mState == PAUSED)) { - ALOGV("resume track"); - mState = PLAYING; - mAutoPaused = false; - mAudioTrack->start(); - } -} - -void SoundChannel::setRate(float rate) -{ - Mutex::Autolock lock(&mLock); - if (mAudioTrack != NULL && mSample != 0) { - uint32_t sampleRate = uint32_t(float(mSample->sampleRate()) * rate + 0.5); - mAudioTrack->setSampleRate(sampleRate); - mRate = rate; - } -} - -// call with lock held -void SoundChannel::setVolume_l(float leftVolume, float rightVolume) -{ - mLeftVolume = leftVolume; - mRightVolume = rightVolume; - if (mAudioTrack != NULL) - mAudioTrack->setVolume(leftVolume, rightVolume); -} - -void SoundChannel::setVolume(float leftVolume, float rightVolume) -{ - Mutex::Autolock lock(&mLock); - setVolume_l(leftVolume, rightVolume); -} - -void SoundChannel::setLoop(int loop) -{ - Mutex::Autolock lock(&mLock); - if (mAudioTrack != NULL && mSample != 0) { - uint32_t loopEnd = mSample->size()/mNumChannels/ - ((mSample->format() == AUDIO_FORMAT_PCM_16_BIT) ? sizeof(int16_t) : sizeof(uint8_t)); - mAudioTrack->setLoop(0, loopEnd, loop); - mLoop = loop; - } -} - -SoundChannel::~SoundChannel() -{ - ALOGV("SoundChannel destructor %p", this); - { - Mutex::Autolock lock(&mLock); - clearNextEvent(); - doStop_l(); - } - // do not call AudioTrack destructor with mLock held as it will wait for the AudioTrack - // callback thread to exit which may need to execute process() and acquire the mLock. - delete mAudioTrack; -} - -void SoundChannel::dump() -{ - ALOGV("mState = %d mChannelID=%d, mNumChannels=%d, mPos = %d, mPriority=%d, mLoop=%d", - mState, mChannelID, mNumChannels, mPos, mPriority, mLoop); -} - -void SoundEvent::set(const sp<Sample>& sample, int channelID, float leftVolume, - float rightVolume, int priority, int loop, float rate) -{ - mSample = sample; - mChannelID = channelID; - mLeftVolume = leftVolume; - mRightVolume = rightVolume; - mPriority = priority; - mLoop = loop; - mRate =rate; -} - -} // end namespace android diff --git a/media/libmedia/SoundPool.h b/media/libmedia/SoundPool.h deleted file mode 100644 index 002b045..0000000 --- a/media/libmedia/SoundPool.h +++ /dev/null @@ -1,238 +0,0 @@ -/* - * Copyright (C) 2007 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 SOUNDPOOL_H_ -#define SOUNDPOOL_H_ - -#include <utils/threads.h> -#include <utils/List.h> -#include <utils/Vector.h> -#include <utils/KeyedVector.h> -#include <media/AudioTrack.h> - -namespace android { - -static const int IDLE_PRIORITY = -1; - -// forward declarations -class SoundEvent; -class SoundPoolThread; -class SoundPool; - -// for queued events -class SoundPoolEvent { -public: - SoundPoolEvent(int msg, int arg1=0, int arg2=0) : - mMsg(msg), mArg1(arg1), mArg2(arg2) {} - int mMsg; - int mArg1; - int mArg2; - enum MessageType { INVALID, SAMPLE_LOADED }; -}; - -// callback function prototype -typedef void SoundPoolCallback(SoundPoolEvent event, SoundPool* soundPool, void* user); - -// tracks samples used by application -class Sample : public RefBase { -public: - enum sample_state { UNLOADED, LOADING, READY, UNLOADING }; - Sample(int sampleID, const char* url); - Sample(int sampleID, int fd, int64_t offset, int64_t length); - ~Sample(); - int sampleID() { return mSampleID; } - int numChannels() { return mNumChannels; } - int sampleRate() { return mSampleRate; } - audio_format_t format() { return mFormat; } - size_t size() { return mSize; } - int state() { return mState; } - uint8_t* data() { return static_cast<uint8_t*>(mData->pointer()); } - status_t doLoad(); - void startLoad() { mState = LOADING; } - sp<IMemory> getIMemory() { return mData; } - - // hack - void init(int numChannels, int sampleRate, audio_format_t format, size_t size, sp<IMemory> data ) { - mNumChannels = numChannels; mSampleRate = sampleRate; mFormat = format; mSize = size; mData = data; } - -private: - void init(); - - size_t mSize; - volatile int32_t mRefCount; - uint16_t mSampleID; - uint16_t mSampleRate; - uint8_t mState : 3; - uint8_t mNumChannels : 2; - audio_format_t mFormat; - int mFd; - int64_t mOffset; - int64_t mLength; - char* mUrl; - sp<IMemory> mData; -}; - -// stores pending events for stolen channels -class SoundEvent -{ -public: - SoundEvent() : mChannelID(0), mLeftVolume(0), mRightVolume(0), - mPriority(IDLE_PRIORITY), mLoop(0), mRate(0) {} - void set(const sp<Sample>& sample, int channelID, float leftVolume, - float rightVolume, int priority, int loop, float rate); - sp<Sample> sample() { return mSample; } - int channelID() { return mChannelID; } - float leftVolume() { return mLeftVolume; } - float rightVolume() { return mRightVolume; } - int priority() { return mPriority; } - int loop() { return mLoop; } - float rate() { return mRate; } - void clear() { mChannelID = 0; mSample.clear(); } - -protected: - sp<Sample> mSample; - int mChannelID; - float mLeftVolume; - float mRightVolume; - int mPriority; - int mLoop; - float mRate; -}; - -// for channels aka AudioTracks -class SoundChannel : public SoundEvent { -public: - enum state { IDLE, RESUMING, STOPPING, PAUSED, PLAYING }; - SoundChannel() : mAudioTrack(NULL), mState(IDLE), mNumChannels(1), - mPos(0), mToggle(0), mAutoPaused(false) {} - ~SoundChannel(); - void init(SoundPool* soundPool); - void play(const sp<Sample>& sample, int channelID, float leftVolume, float rightVolume, - int priority, int loop, float rate); - void setVolume_l(float leftVolume, float rightVolume); - void setVolume(float leftVolume, float rightVolume); - void stop_l(); - void stop(); - void pause(); - void autoPause(); - void resume(); - void autoResume(); - void setRate(float rate); - int state() { return mState; } - void setPriority(int priority) { mPriority = priority; } - void setLoop(int loop); - int numChannels() { return mNumChannels; } - void clearNextEvent() { mNextEvent.clear(); } - void nextEvent(); - int nextChannelID() { return mNextEvent.channelID(); } - void dump(); - -private: - static void callback(int event, void* user, void *info); - void process(int event, void *info, unsigned long toggle); - bool doStop_l(); - - SoundPool* mSoundPool; - AudioTrack* mAudioTrack; - SoundEvent mNextEvent; - Mutex mLock; - int mState; - int mNumChannels; - int mPos; - int mAudioBufferSize; - unsigned long mToggle; - bool mAutoPaused; -}; - -// application object for managing a pool of sounds -class SoundPool { - friend class SoundPoolThread; - friend class SoundChannel; -public: - SoundPool(int maxChannels, audio_stream_type_t streamType, int srcQuality); - ~SoundPool(); - int load(const char* url, int priority); - int load(int fd, int64_t offset, int64_t length, int priority); - bool unload(int sampleID); - int play(int sampleID, float leftVolume, float rightVolume, int priority, - int loop, float rate); - void pause(int channelID); - void autoPause(); - void resume(int channelID); - void autoResume(); - void stop(int channelID); - void setVolume(int channelID, float leftVolume, float rightVolume); - void setPriority(int channelID, int priority); - void setLoop(int channelID, int loop); - void setRate(int channelID, float rate); - audio_stream_type_t streamType() const { return mStreamType; } - int srcQuality() const { return mSrcQuality; } - - // called from SoundPoolThread - void sampleLoaded(int sampleID); - - // called from AudioTrack thread - void done_l(SoundChannel* channel); - - // callback function - void setCallback(SoundPoolCallback* callback, void* user); - void* getUserData() { return mUserData; } - -private: - SoundPool() {} // no default constructor - bool startThreads(); - void doLoad(sp<Sample>& sample); - sp<Sample> findSample(int sampleID) { return mSamples.valueFor(sampleID); } - SoundChannel* findChannel (int channelID); - SoundChannel* findNextChannel (int channelID); - SoundChannel* allocateChannel_l(int priority); - void moveToFront_l(SoundChannel* channel); - void notify(SoundPoolEvent event); - void dump(); - - // restart thread - void addToRestartList(SoundChannel* channel); - void addToStopList(SoundChannel* channel); - static int beginThread(void* arg); - int run(); - void quit(); - - Mutex mLock; - Mutex mRestartLock; - Condition mCondition; - SoundPoolThread* mDecodeThread; - SoundChannel* mChannelPool; - List<SoundChannel*> mChannels; - List<SoundChannel*> mRestart; - List<SoundChannel*> mStop; - DefaultKeyedVector< int, sp<Sample> > mSamples; - int mMaxChannels; - audio_stream_type_t mStreamType; - int mSrcQuality; - int mAllocated; - int mNextSampleID; - int mNextChannelID; - bool mQuit; - - // callback - Mutex mCallbackLock; - SoundPoolCallback* mCallback; - void* mUserData; -}; - -} // end namespace android - -#endif /*SOUNDPOOL_H_*/ diff --git a/media/libmedia/SoundPoolThread.cpp b/media/libmedia/SoundPoolThread.cpp deleted file mode 100644 index ba3b482..0000000 --- a/media/libmedia/SoundPoolThread.cpp +++ /dev/null @@ -1,114 +0,0 @@ -/* - * Copyright (C) 2007 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_NDEBUG 0 -#define LOG_TAG "SoundPoolThread" -#include "utils/Log.h" - -#include "SoundPoolThread.h" - -namespace android { - -void SoundPoolThread::write(SoundPoolMsg msg) { - Mutex::Autolock lock(&mLock); - while (mMsgQueue.size() >= maxMessages) { - mCondition.wait(mLock); - } - - // if thread is quitting, don't add to queue - if (mRunning) { - mMsgQueue.push(msg); - mCondition.signal(); - } -} - -const SoundPoolMsg SoundPoolThread::read() { - Mutex::Autolock lock(&mLock); - while (mMsgQueue.size() == 0) { - mCondition.wait(mLock); - } - SoundPoolMsg msg = mMsgQueue[0]; - mMsgQueue.removeAt(0); - mCondition.signal(); - return msg; -} - -void SoundPoolThread::quit() { - Mutex::Autolock lock(&mLock); - if (mRunning) { - mRunning = false; - mMsgQueue.clear(); - mMsgQueue.push(SoundPoolMsg(SoundPoolMsg::KILL, 0)); - mCondition.signal(); - mCondition.wait(mLock); - } - ALOGV("return from quit"); -} - -SoundPoolThread::SoundPoolThread(SoundPool* soundPool) : - mSoundPool(soundPool) -{ - mMsgQueue.setCapacity(maxMessages); - if (createThreadEtc(beginThread, this, "SoundPoolThread")) { - mRunning = true; - } -} - -SoundPoolThread::~SoundPoolThread() -{ - quit(); -} - -int SoundPoolThread::beginThread(void* arg) { - ALOGV("beginThread"); - SoundPoolThread* soundPoolThread = (SoundPoolThread*)arg; - return soundPoolThread->run(); -} - -int SoundPoolThread::run() { - ALOGV("run"); - for (;;) { - SoundPoolMsg msg = read(); - ALOGV("Got message m=%d, mData=%d", msg.mMessageType, msg.mData); - switch (msg.mMessageType) { - case SoundPoolMsg::KILL: - ALOGV("goodbye"); - return NO_ERROR; - case SoundPoolMsg::LOAD_SAMPLE: - doLoadSample(msg.mData); - break; - default: - ALOGW("run: Unrecognized message %d\n", - msg.mMessageType); - break; - } - } -} - -void SoundPoolThread::loadSample(int sampleID) { - write(SoundPoolMsg(SoundPoolMsg::LOAD_SAMPLE, sampleID)); -} - -void SoundPoolThread::doLoadSample(int sampleID) { - sp <Sample> sample = mSoundPool->findSample(sampleID); - status_t status = -1; - if (sample != 0) { - status = sample->doLoad(); - } - mSoundPool->notify(SoundPoolEvent(SoundPoolEvent::SAMPLE_LOADED, sampleID, status)); -} - -} // end namespace android diff --git a/media/libmedia/SoundPoolThread.h b/media/libmedia/SoundPoolThread.h deleted file mode 100644 index d388388..0000000 --- a/media/libmedia/SoundPoolThread.h +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright (C) 2007 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 SOUNDPOOLTHREAD_H_ -#define SOUNDPOOLTHREAD_H_ - -#include <utils/threads.h> -#include <utils/Vector.h> -#include <media/AudioTrack.h> - -#include "SoundPool.h" - -namespace android { - -class SoundPoolMsg { -public: - enum MessageType { INVALID, KILL, LOAD_SAMPLE }; - SoundPoolMsg() : mMessageType(INVALID), mData(0) {} - SoundPoolMsg(MessageType MessageType, int data) : - mMessageType(MessageType), mData(data) {} - uint16_t mMessageType; - uint16_t mData; -}; - -/* - * This class handles background requests from the SoundPool - */ -class SoundPoolThread { -public: - SoundPoolThread(SoundPool* SoundPool); - ~SoundPoolThread(); - void loadSample(int sampleID); - void quit(); - void write(SoundPoolMsg msg); - -private: - static const size_t maxMessages = 5; - - static int beginThread(void* arg); - int run(); - void doLoadSample(int sampleID); - const SoundPoolMsg read(); - - Mutex mLock; - Condition mCondition; - Vector<SoundPoolMsg> mMsgQueue; - SoundPool* mSoundPool; - bool mRunning; -}; - -} // end namespace android - -#endif /*SOUNDPOOLTHREAD_H_*/ diff --git a/media/libmedia/ToneGenerator.cpp b/media/libmedia/ToneGenerator.cpp deleted file mode 100644 index 717d316..0000000 --- a/media/libmedia/ToneGenerator.cpp +++ /dev/null @@ -1,1580 +0,0 @@ -/* - * Copyright (C) 2008 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_NDEBUG 0 -#define LOG_TAG "ToneGenerator" -#include <utils/threads.h> - -#include <stdio.h> -#include <math.h> -#include <utils/Log.h> -#include <utils/RefBase.h> -#include <utils/Timers.h> -#include <cutils/properties.h> -#include "media/ToneGenerator.h" - - -namespace android { - - -// Descriptors for all available tones (See ToneGenerator::ToneDescriptor class declaration for details) -const ToneGenerator::ToneDescriptor ToneGenerator::sToneDescriptors[] = { - { segments: {{ duration: ToneGenerator::TONEGEN_INF, waveFreq: { 1336, 941, 0 }, 0, 0}, - { duration: 0 , waveFreq: { 0 }, 0, 0}}, - repeatCnt: ToneGenerator::TONEGEN_INF, - repeatSegment: 0 }, // TONE_DTMF_0 - { segments: { { duration: ToneGenerator::TONEGEN_INF, waveFreq: { 1209, 697, 0 }, 0, 0 }, - { duration: 0 , waveFreq: { 0 }, 0, 0}}, - repeatCnt: ToneGenerator::TONEGEN_INF, - repeatSegment: 0 }, // TONE_DTMF_1 - { segments: { { duration: ToneGenerator::TONEGEN_INF, waveFreq: { 1336, 697, 0 }, 0, 0 }, - { duration: 0 , waveFreq: { 0 }, 0, 0}}, - repeatCnt: ToneGenerator::TONEGEN_INF, - repeatSegment: 0 }, // TONE_DTMF_2 - { segments: { { duration: ToneGenerator::TONEGEN_INF, waveFreq: { 1477, 697, 0 }, 0, 0 }, - { duration: 0 , waveFreq: { 0 }, 0, 0}}, - repeatCnt: ToneGenerator::TONEGEN_INF, - repeatSegment: 0 }, // TONE_DTMF_3 - { segments: { { duration: ToneGenerator::TONEGEN_INF, waveFreq: { 1209, 770, 0 }, 0, 0 }, - { duration: 0 , waveFreq: { 0 }, 0, 0}}, - repeatCnt: ToneGenerator::TONEGEN_INF, - repeatSegment: 0 }, // TONE_DTMF_4 - { segments: { { duration: ToneGenerator::TONEGEN_INF, waveFreq: { 1336, 770, 0 }, 0, 0 }, - { duration: 0 , waveFreq: { 0 }, 0, 0}}, - repeatCnt: ToneGenerator::TONEGEN_INF, - repeatSegment: 0 }, // TONE_DTMF_5 - { segments: { { duration: ToneGenerator::TONEGEN_INF, waveFreq: { 1477, 770, 0 }, 0, 0 }, - { duration: 0 , waveFreq: { 0 }, 0, 0}}, - repeatCnt: ToneGenerator::TONEGEN_INF, - repeatSegment: 0 }, // TONE_DTMF_6 - { segments: { { duration: ToneGenerator::TONEGEN_INF, waveFreq: { 1209, 852, 0 }, 0, 0 }, - { duration: 0 , waveFreq: { 0 }, 0, 0}}, - repeatCnt: ToneGenerator::TONEGEN_INF, - repeatSegment: 0 }, // TONE_DTMF_7 - { segments: { { duration: ToneGenerator::TONEGEN_INF, waveFreq: { 1336, 852, 0 }, 0, 0 }, - { duration: 0 , waveFreq: { 0 }, 0, 0}}, - repeatCnt: ToneGenerator::TONEGEN_INF, - repeatSegment: 0 }, // TONE_DTMF_8 - { segments: { { duration: ToneGenerator::TONEGEN_INF, waveFreq: { 1477, 852, 0 }, 0, 0 }, - { duration: 0 , waveFreq: { 0 }, 0, 0}}, - repeatCnt: ToneGenerator::TONEGEN_INF, - repeatSegment: 0 }, // TONE_DTMF_9 - { segments: { { duration: ToneGenerator::TONEGEN_INF, waveFreq: { 1209, 941, 0 }, 0, 0 }, - { duration: 0 , waveFreq: { 0 }, 0, 0}}, - repeatCnt: ToneGenerator::TONEGEN_INF, - repeatSegment: 0 }, // TONE_DTMF_S - { segments: { { duration: ToneGenerator::TONEGEN_INF, waveFreq: { 1477, 941, 0 }, 0, 0 }, - { duration: 0 , waveFreq: { 0 }, 0, 0}}, - repeatCnt: ToneGenerator::TONEGEN_INF, - repeatSegment: 0 }, // TONE_DTMF_P - { segments: { { duration: ToneGenerator::TONEGEN_INF, waveFreq: { 1633, 697, 0 }, 0, 0 }, - { duration: 0 , waveFreq: { 0 }, 0, 0}}, - repeatCnt: ToneGenerator::TONEGEN_INF, - repeatSegment: 0 }, // TONE_DTMF_A - { segments: { { duration: ToneGenerator::TONEGEN_INF, waveFreq: { 1633, 770, 0 }, 0, 0 }, - { duration: 0 , waveFreq: { 0 }, 0, 0}}, - repeatCnt: ToneGenerator::TONEGEN_INF, - repeatSegment: 0 }, // TONE_DTMF_B - { segments: { { duration: ToneGenerator::TONEGEN_INF, waveFreq: { 1633, 852, 0 }, 0, 0 }, - { duration: 0 , waveFreq: { 0 }, 0, 0}}, - repeatCnt: ToneGenerator::TONEGEN_INF, - repeatSegment: 0 }, // TONE_DTMF_C - { segments: { { duration: ToneGenerator::TONEGEN_INF, waveFreq: { 1633, 941, 0 }, 0, 0 }, - { duration: 0 , waveFreq: { 0 }, 0, 0}}, - repeatCnt: ToneGenerator::TONEGEN_INF, - repeatSegment: 0 }, // TONE_DTMF_D - { segments: { { duration: ToneGenerator::TONEGEN_INF, waveFreq: { 425, 0 }, 0, 0 }, - { duration: 0 , waveFreq: { 0 }, 0, 0}}, - repeatCnt: ToneGenerator::TONEGEN_INF, - repeatSegment: 0 }, // TONE_SUP_DIAL - { segments: { { duration: 500 , waveFreq: { 425, 0 }, 0, 0}, - { duration: 500, waveFreq: { 0 }, 0, 0}, - { duration: 0 , waveFreq: { 0 }, 0, 0}}, - repeatCnt: ToneGenerator::TONEGEN_INF, - repeatSegment: 0 }, // TONE_SUP_BUSY - { segments: { { duration: 200, waveFreq: { 425, 0 }, 0, 0 }, - { duration: 200, waveFreq: { 0 }, 0, 0 }, - { duration: 0 , waveFreq: { 0 }, 0, 0}}, - repeatCnt: ToneGenerator::TONEGEN_INF, - repeatSegment: 0 }, // TONE_SUP_CONGESTION - { segments: { { duration: 200, waveFreq: { 425, 0 }, 0, 0 }, - { duration: 0 , waveFreq: { 0 }, 0, 0}}, - repeatCnt: 0, - repeatSegment: 0 }, // TONE_SUP_RADIO_ACK - { segments: { { duration: 200, waveFreq: { 425, 0 }, 0, 0}, - { duration: 200, waveFreq: { 0 }, 0, 0}, - { duration: 0 , waveFreq: { 0 }, 0, 0}}, - repeatCnt: 2, - repeatSegment: 0 }, // TONE_SUP_RADIO_NOTAVAIL - { segments: { { duration: 330, waveFreq: { 950, 1400, 1800, 0 }, 0, 0}, - { duration: 1000, waveFreq: { 0 }, 0, 0}, - { duration: 0 , waveFreq: { 0 }, 0, 0}}, - repeatCnt: ToneGenerator::TONEGEN_INF, - repeatSegment: 0 }, // TONE_SUP_ERROR - { segments: { { duration: 200, waveFreq: { 425, 0 }, 0, 0 }, - { duration: 600, waveFreq: { 0 }, 0, 0 }, - { duration: 200, waveFreq: { 425, 0 }, 0, 0 }, - { duration: 3000, waveFreq: { 0 }, 0, 0 }, - { duration: 0 , waveFreq: { 0 }, 0, 0}}, - repeatCnt: ToneGenerator::TONEGEN_INF, - repeatSegment: 0 }, // TONE_SUP_CALL_WAITING - { segments: { { duration: 1000, waveFreq: { 425, 0 }, 0, 0 }, - { duration: 4000, waveFreq: { 0 }, 0, 0 }, - { duration: 0 , waveFreq: { 0 }, 0, 0}}, - repeatCnt: ToneGenerator::TONEGEN_INF, - repeatSegment: 0 }, // TONE_SUP_RINGTONE - { segments: { { duration: 40, waveFreq: { 400, 1200, 0 }, 0, 0 }, - { duration: 0 , waveFreq: { 0 }, 0, 0}}, - repeatCnt: 0, - repeatSegment: 0 }, // TONE_PROP_BEEP - { segments: { { duration: 100, waveFreq: { 1200, 0 }, 0, 0 }, - { duration: 100, waveFreq: { 0 }, 0, 0 }, - { duration: 0 , waveFreq: { 0 }, 0, 0}}, - repeatCnt: 1, - repeatSegment: 0 }, // TONE_PROP_ACK - { segments: { { duration: 400, waveFreq: { 300, 400, 500, 0 }, 0, 0 }, - { duration: 0 , waveFreq: { 0 }, 0, 0}}, - repeatCnt: 0, - repeatSegment: 0 }, // TONE_PROP_NACK - { segments: { { duration: 200, waveFreq: { 400, 1200, 0 }, 0, 0 }, - { duration: 0 , waveFreq: { 0 }, 0, 0}}, - repeatCnt: 0, - repeatSegment: 0 }, // TONE_PROP_PROMPT - { segments: { { duration: 40, waveFreq: { 400, 1200, 0 }, 0, 0 }, - { duration: 200, waveFreq: { 0 }, 0, 0 }, - { duration: 40, waveFreq: { 400, 1200, 0 }, 0, 0 }, - { duration: 0 , waveFreq: { 0 }, 0, 0}}, - repeatCnt: 0, - repeatSegment: 0 }, // TONE_PROP_BEEP2 - { segments: { { duration: 250, waveFreq: { 440, 0 }, 0, 0 }, - { duration: 250, waveFreq: { 620, 0 }, 0, 0 }, - { duration: 0 , waveFreq: { 0 }, 0, 0 }}, - repeatCnt: ToneGenerator::TONEGEN_INF, - repeatSegment: 0 }, // TONE_SUP_INTERCEPT - { segments: { { duration: 250, waveFreq: { 440, 0 }, 0, 0 }, - { duration: 250, waveFreq: { 620, 0 }, 0, 0 }, - { duration: 0 , waveFreq: { 0 }, 0, 0}}, - repeatCnt: 7, - repeatSegment: 0 }, // TONE_SUP_INTERCEPT_ABBREV - { segments: { { duration: 250, waveFreq: { 480, 620, 0 }, 0, 0 }, - { duration: 250, waveFreq: { 0 }, 0, 0 }, - { duration: 0 , waveFreq: { 0 }, 0, 0}}, - repeatCnt: 7, - repeatSegment: 0 }, // TONE_SUP_CONGESTION_ABBREV - { segments: { { duration: 100, waveFreq: { 350, 440, 0 }, 0, 0 }, - { duration: 100, waveFreq: { 0 }, 0, 0 }, - { duration: 0 , waveFreq: { 0 }, 0, 0}}, - repeatCnt: 2, - repeatSegment: 0 }, // TONE_SUP_CONFIRM - { segments: { { duration: 100, waveFreq: { 480, 0 }, 0, 0 }, - { duration: 100, waveFreq: { 0 }, 0, 0 }, - { duration: 0 , waveFreq: { 0 }, 0, 0}}, - repeatCnt: 3, - repeatSegment: 0 }, // TONE_SUP_PIP - { segments: {{ duration: ToneGenerator::TONEGEN_INF, waveFreq: { 425, 0 }, 0, 0}, - { duration: 0 , waveFreq: { 0 }, 0, 0}}, - repeatCnt: ToneGenerator::TONEGEN_INF, - repeatSegment: 0 }, // TONE_CDMA_DIAL_TONE_LITE - { segments: { { duration: 2000, waveFreq: { 440, 480, 0 }, 0, 0 }, - { duration: 4000, waveFreq: { 0 }, 0, 0 }, - { duration: 0 , waveFreq: { 0 }, 0, 0}}, - repeatCnt: ToneGenerator::TONEGEN_INF, - repeatSegment: 0 }, // TONE_CDMA_NETWORK_USA_RINGBACK - { segments: { { duration: 250, waveFreq: { 440, 0 }, 0, 0 }, - { duration: 250, waveFreq: { 620, 0 }, 0, 0 }, - { duration: 0 , waveFreq: { 0 }, 0, 0}}, - repeatCnt: ToneGenerator::TONEGEN_INF, - repeatSegment: 0 }, // TONE_CDMA_INTERCEPT - { segments: { { duration: 250, waveFreq: { 440, 0 }, 0, 0 }, - { duration: 250, waveFreq: { 620, 0 }, 0, 0 }, - { duration: 0 , waveFreq: { 0 }, 0, 0}}, - repeatCnt: 0, - repeatSegment: 0 }, // TONE_CDMA_ABBR_INTERCEPT - { segments: { { duration: 250, waveFreq: { 480, 620, 0 }, 0, 0 }, - { duration: 250, waveFreq: { 0 }, 0, 0 }, - { duration: 0 , waveFreq: { 0 }, 0, 0}}, - repeatCnt: ToneGenerator::TONEGEN_INF, - repeatSegment: 0 }, // TONE_CDMA_REORDER - { segments: { { duration: 250, waveFreq: { 480, 620, 0 }, 0, 0 }, - { duration: 250, waveFreq: { 0 }, 0, 0 }, - { duration: 0 , waveFreq: { 0 }, 0, 0}}, - repeatCnt: 7, - repeatSegment: 0 }, // TONE_CDMA_ABBR_REORDER - { segments: { { duration: 500, waveFreq: { 480, 620, 0 }, 0, 0 }, - { duration: 500, waveFreq: { 0 }, 0, 0 }, - { duration: 0 , waveFreq: { 0 }, 0, 0}}, - repeatCnt: ToneGenerator::TONEGEN_INF, - repeatSegment: 0 }, // TONE_CDMA_NETWORK_BUSY - { segments: { { duration: 100, waveFreq: { 350, 440, 0 }, 0, 0 }, - { duration: 100, waveFreq: { 0 }, 0, 0 }, - { duration: 0 , waveFreq: { 0 }, 0, 0}}, - repeatCnt: 2, - repeatSegment: 0 }, // TONE_CDMA_CONFIRM - { segments: { { duration: 500, waveFreq: { 660, 1000, 0 }, 0, 0 }, - { duration: 0 , waveFreq: { 0 }, 0, 0}}, - repeatCnt: 0, - repeatSegment: 0 }, // TONE_CDMA_ANSWER - { segments: { { duration: 300, waveFreq: { 440, 0 }, 0, 0 }, - { duration: 0 , waveFreq: { 0 }, 0, 0}}, - repeatCnt: 0, - repeatSegment: 0 }, // TONE_CDMA_NETWORK_CALLWAITING - { segments: { { duration: 100, waveFreq: { 480, 0 }, 0, 0 }, - { duration: 100, waveFreq: { 0 }, 0, 0 }, - { duration: 0 , waveFreq: { 0 }, 0, 0}}, - repeatCnt: 3, - repeatSegment: 0 }, // TONE_CDMA_PIP - - { segments: { { duration: 32, waveFreq: { 2091, 0}, 0, 0 }, - { duration: 64, waveFreq: { 2556, 0}, 19, 0}, - { duration: 32, waveFreq: { 2091, 0}, 0, 0}, - { duration: 48, waveFreq: { 2556, 0}, 0, 0}, - { duration: 4000, waveFreq: { 0 }, 0, 0}, - { duration: 0, waveFreq: { 0 }, 0, 0}}, - repeatCnt: 0, - repeatSegment: 0 }, // TONE_CDMA_CALL_SIGNAL_ISDN_NORMAL - { segments: { { duration: 32, waveFreq: { 2091, 0}, 0, 0 }, - { duration: 64, waveFreq: { 2556, 0}, 7, 0 }, - { duration: 32, waveFreq: { 2091, 0}, 0, 0 }, - { duration: 400, waveFreq: { 0 }, 0, 0 }, - { duration: 32, waveFreq: { 2091, 0}, 0, 0 }, - { duration: 64, waveFreq: { 2556, 0}, 7, 4 }, - { duration: 32, waveFreq: { 2091, 0}, 0, 0 }, - { duration: 4000, waveFreq: { 0 }, 0, 0 }, - { duration: 0, waveFreq: { 0 }, 0, 0 } }, - repeatCnt: 0, - repeatSegment: 0 }, // TONE_CDMA_CALL_SIGNAL_ISDN_INTERGROUP - { segments: { { duration: 32, waveFreq: { 2091, 0}, 0, 0 }, - { duration: 64, waveFreq: { 2556, 0}, 3, 0 }, - { duration: 16, waveFreq: { 2091, 0}, 0, 0 }, - { duration: 200, waveFreq: { 0 }, 0, 0 }, - { duration: 32, waveFreq: { 2091, 0}, 0, 0 }, - { duration: 64, waveFreq: { 2556, 0}, 3, 4 }, - { duration: 16, waveFreq: { 2091, 0}, 0, 0 }, - { duration: 200, waveFreq: { 0 }, 0, 0 }, - { duration: 0, waveFreq: { 0 }, 0, 0 } }, - repeatCnt: 0, - repeatSegment: 0 }, // TONE_CDMA_CALL_SIGNAL_ISDN_SP_PRI - { segments: { { duration: 0, waveFreq: { 0 }, 0, 0} }, - repeatCnt: 0, - repeatSegment: 0 }, // TONE_CDMA_CALL_SIGNAL_ISDN_PAT3 - { segments: { { duration: 32, waveFreq: { 2091, 0 }, 0, 0 }, - { duration: 64, waveFreq: { 2556, 0 }, 4, 0 }, - { duration: 20, waveFreq: { 2091, 0 }, 0, 0 }, - { duration: 0, waveFreq: { 0 } , 0, 0 } }, - repeatCnt: 0, - repeatSegment: 0 }, // TONE_CDMA_CALL_SIGNAL_ISDN_PING_RING - { segments: { { duration: 0, waveFreq: { 0 }, 0, 0} }, - repeatCnt: 0, - repeatSegment: 0 }, // TONE_CDMA_CALL_SIGNAL_ISDN_PAT5 - { segments: { { duration: 0, waveFreq: { 0 }, 0, 0} }, - repeatCnt: 0, - repeatSegment: 0 }, // TONE_CDMA_CALL_SIGNAL_ISDN_PAT6 - { segments: { { duration: 0, waveFreq: { 0 }, 0, 0} }, - repeatCnt: 0, - repeatSegment: 0 }, // TONE_CDMA_CALL_SIGNAL_ISDN_PAT7 - - { segments: { { duration: 25, waveFreq: { 3700, 0 }, 0, 0 }, - { duration: 25, waveFreq: { 4000, 0 }, 39, 0 }, - { duration: 4000, waveFreq: { 0 }, 0, 0 }, - { duration: 0, waveFreq: { 0 }, 0, 0 } }, - repeatCnt: ToneGenerator::TONEGEN_INF, - repeatSegment: 0 }, // TONE_CDMA_HIGH_L - { segments: { { duration: 25, waveFreq: { 2600, 0 }, 0, 0 }, - { duration: 25, waveFreq: { 2900, 0 }, 39, 0 }, - { duration: 4000, waveFreq: { 0 }, 0, 0 }, - { duration: 0, waveFreq: { 0 }, 0, 0 } }, - repeatCnt: ToneGenerator::TONEGEN_INF, - repeatSegment: 0 }, // TONE_CDMA_MED_L - { segments: { { duration: 25, waveFreq: { 1300, 0 }, 0, 0 }, - { duration: 25, waveFreq: { 1450, 0 }, 39, 0 }, - { duration: 4000, waveFreq: { 0 }, 0, 0 }, - { duration: 0, waveFreq: { 0 }, 0, 0 } }, - repeatCnt: ToneGenerator::TONEGEN_INF, - repeatSegment: 0 }, // TONE_CDMA_LOW_L - { segments: { { duration: 25, waveFreq: { 3700, 0 }, 0, 0 }, - { duration: 25, waveFreq: { 4000, 0 }, 15, 0 }, - { duration: 400, waveFreq: { 0 }, 0, 0 }, - { duration: 0, waveFreq: { 0 }, 0, 0 } }, - repeatCnt: ToneGenerator::TONEGEN_INF, - repeatSegment: 0 }, // TONE_CDMA_HIGH_SS - { segments: { { duration: 25, waveFreq: { 2600, 0 }, 0, 0 }, - { duration: 25, waveFreq: { 2900, 0 }, 15, 0 }, - { duration: 400, waveFreq: { 0 }, 0, 0 }, - { duration: 0, waveFreq: { 0 }, 0, 0 }}, - repeatCnt: ToneGenerator::TONEGEN_INF, - repeatSegment: 0 }, // TONE_CDMA_MED_SS - { segments: { { duration: 25, waveFreq: { 1300, 0 }, 0, 0 }, - { duration: 25, waveFreq: { 1450, 0 }, 15, 0 }, - { duration: 400, waveFreq: { 0 }, 0, 0 }, - { duration: 0, waveFreq: { 0 }, 0, 0 }}, - repeatCnt: ToneGenerator::TONEGEN_INF, - repeatSegment: 0 }, // TONE_CDMA_LOW_SS - { segments: { { duration: 25, waveFreq: { 3700, 0 }, 0, 0 }, - { duration: 25, waveFreq: { 4000, 0 }, 7, 0 }, - { duration: 200, waveFreq: { 0 }, 0, 0 }, - { duration: 25, waveFreq: { 3700, 0 }, 0, 0 }, - { duration: 25, waveFreq: { 4000, 0 }, 7, 3 }, - { duration: 200, waveFreq: { 0 }, 0, 0 }, - { duration: 25, waveFreq: { 3700, 0 }, 0, 0 }, - { duration: 25, waveFreq: { 4000, 0 }, 15, 6 }, - { duration: 4000, waveFreq: { 0 }, 0, 0 }, - { duration: 0, waveFreq: { 0 }, 0, 0 }}, - repeatCnt: ToneGenerator::TONEGEN_INF, - repeatSegment: 0 }, // TONE_CDMA_HIGH_SSL - { segments: { { duration: 25, waveFreq: { 2600, 0 }, 0, 0 }, - { duration: 25, waveFreq: { 2900, 0 }, 7, 0 }, - { duration: 200, waveFreq: { 0 }, 0, 0 }, - { duration: 25, waveFreq: { 2600, 0 }, 0, 0 }, - { duration: 25, waveFreq: { 2900, 0 }, 7, 3 }, - { duration: 200, waveFreq: { 0 }, 0, 0 }, - { duration: 25, waveFreq: { 2600, 0 }, 0, 0 }, - { duration: 25, waveFreq: { 2900, 0 }, 15, 6 }, - { duration: 4000, waveFreq: { 0 }, 0, 0 }, - { duration: 0, waveFreq: { 0 }, 0, 0 }}, - repeatCnt: ToneGenerator::TONEGEN_INF, - repeatSegment: 0 }, // TONE_CDMA_MED_SSL - { segments: { { duration: 25, waveFreq: { 1300, 0 }, 0, 0 }, - { duration: 25, waveFreq: { 1450, 0 }, 7, 0 }, - { duration: 200, waveFreq: { 0 }, 0, 0 }, - { duration: 25, waveFreq: { 1300, 0 }, 0, 0 }, - { duration: 25, waveFreq: { 1450, 0 }, 7, 3 }, - { duration: 200, waveFreq: { 0 }, 0, 0 }, - { duration: 25, waveFreq: { 1300, 0 }, 0, 0 }, - { duration: 25, waveFreq: { 1450, 0 }, 15, 6 }, - { duration: 4000, waveFreq: { 0 }, 0, 0 }, - { duration: 0, waveFreq: { 0 }, 0, 0 }}, - repeatCnt: ToneGenerator::TONEGEN_INF, - repeatSegment: 0 }, // TONE_CDMA_LOW_SSL - { segments: { { duration: 25, waveFreq: { 3700, 0 }, 0, 0 }, - { duration: 25, waveFreq: { 4000, 0 }, 19, 0 }, - { duration: 1000, waveFreq: { 0 }, 0, 0 }, - { duration: 25, waveFreq: { 3700, 0 }, 0, 0 }, - { duration: 25, waveFreq: { 4000, 0 }, 19, 3 }, - { duration: 3000, waveFreq: { 0 }, 0, 0 }, - { duration: 0, waveFreq: { 0 }, 0, 0 }}, - repeatCnt: ToneGenerator::TONEGEN_INF, - repeatSegment: 0 }, // TONE_CDMA_HIGH_SS_2 - { segments: { { duration: 25, waveFreq: { 2600, 0 }, 0, 0 }, - { duration: 25, waveFreq: { 2900, 0 }, 19, 0 }, - { duration: 1000, waveFreq: { 0 }, 0, 0 }, - { duration: 25, waveFreq: { 2600, 0 }, 0, 0 }, - { duration: 25, waveFreq: { 2900, 0 }, 19, 3 }, - { duration: 3000, waveFreq: { 0 }, 0, 0 }, - { duration: 0, waveFreq: { 0 }, 0, 0 }}, - repeatCnt: ToneGenerator::TONEGEN_INF, - repeatSegment: 0 }, // TONE_CDMA_MED_SS_2 - { segments: { { duration: 25, waveFreq: { 1300, 0 }, 0, 0 }, - { duration: 25, waveFreq: { 1450, 0 }, 19, 0 }, - { duration: 1000, waveFreq: { 0 }, 0, 0 }, - { duration: 25, waveFreq: { 1300, 0 }, 0, 0 }, - { duration: 25, waveFreq: { 1450, 0 }, 19, 3 }, - { duration: 3000, waveFreq: { 0 }, 0, 0 }, - { duration: 0, waveFreq: { 0 }, 0, 0 }}, - repeatCnt: ToneGenerator::TONEGEN_INF, - repeatSegment: 0 }, // TONE_CDMA_LOW_SS_2 - { segments: { { duration: 25, waveFreq: { 3700, 0 }, 0, 0 }, - { duration: 25, waveFreq: { 4000, 0 }, 9, 0 }, - { duration: 500, waveFreq: { 0 }, 0, 0 }, - { duration: 25, waveFreq: { 3700, 0 }, 0, 0 }, - { duration: 25, waveFreq: { 4000, 0 }, 19, 3 }, - { duration: 500, waveFreq: { 0 }, 0, 0 }, - { duration: 25, waveFreq: { 3700, 0 }, 0, 0 }, - { duration: 25, waveFreq: { 4000, 0 }, 9, 6 }, - { duration: 3000, waveFreq: { 0 }, 0, 0 }, - { duration: 0, waveFreq: { 0 }, 0, 0 }}, - repeatCnt: ToneGenerator::TONEGEN_INF, - repeatSegment: 0 }, // TONE_CDMA_HIGH_SLS - { segments: { { duration: 25, waveFreq: { 2600, 0 }, 0, 0 }, - { duration: 25, waveFreq: { 2900, 0 }, 9, 0 }, - { duration: 500, waveFreq: { 0 }, 0, 0 }, - { duration: 25, waveFreq: { 2600, 0 }, 0, 0 }, - { duration: 25, waveFreq: { 2900, 0 }, 19, 3 }, - { duration: 500, waveFreq: { 0 }, 0, 0 }, - { duration: 25, waveFreq: { 2600, 0 }, 0, 0 }, - { duration: 25, waveFreq: { 2900, 0 }, 9, 6 }, - { duration: 3000, waveFreq: { 0 }, 0, 0 }, - { duration: 0, waveFreq: { 0 }, 0, 0 }}, - repeatCnt: ToneGenerator::TONEGEN_INF, - repeatSegment: 0 }, // TONE_CDMA_MED_SLS - { segments: { { duration: 25, waveFreq: { 1300, 0 }, 0, 0 }, - { duration: 25, waveFreq: { 1450, 0 }, 9, 0 }, - { duration: 500, waveFreq: { 0 }, 0, 0 }, - { duration: 25, waveFreq: { 1300, 0 }, 0, 0 }, - { duration: 25, waveFreq: { 1450, 0 }, 19, 3 }, - { duration: 500, waveFreq: { 0 }, 0, 0 }, - { duration: 25, waveFreq: { 1300, 0 }, 0, 0 }, - { duration: 25, waveFreq: { 1450, 0 }, 9, 6 }, - { duration: 3000, waveFreq: { 0 }, 0, 0 }, - { duration: 0, waveFreq: { 0 }, 0, 0 }}, - repeatCnt: ToneGenerator::TONEGEN_INF, - repeatSegment: 0 }, // TONE_CDMA_LOW_SLS - { segments: { { duration: 25, waveFreq: { 3700, 0 }, 0, 0 }, - { duration: 25, waveFreq: { 4000, 0 }, 9, 0 }, - { duration: 500, waveFreq: { 0 }, 0, 0 }, - { duration: 25, waveFreq: { 3700, 0 }, 0, 0 }, - { duration: 25, waveFreq: { 4000, 0 }, 9, 3 }, - { duration: 500, waveFreq: { 0 }, 0, 0 }, - { duration: 25, waveFreq: { 3700, 0 }, 0, 0 }, - { duration: 25, waveFreq: { 4000, 0 }, 9, 6 }, - { duration: 500, waveFreq: { 0 }, 0, 0 }, - { duration: 25, waveFreq: { 3700, 0 }, 0, 0 }, - { duration: 25, waveFreq: { 4000, 0 }, 9, 9 }, - { duration: 2500, waveFreq: { 0 }, 0, 0 }, - { duration: 0, waveFreq: { 0 }, 0, 0 }}, - repeatCnt: ToneGenerator::TONEGEN_INF, - repeatSegment: 0 }, // TONE_CDMA_HIGH_S_X4 - { segments: { { duration: 25, waveFreq: { 2600, 0 }, 0, 0 }, - { duration: 25, waveFreq: { 2900, 0 }, 9, 0 }, - { duration: 500, waveFreq: { 0 }, 0, 0 }, - { duration: 25, waveFreq: { 2600, 0 }, 0, 0 }, - { duration: 25, waveFreq: { 2900, 0 }, 9, 3 }, - { duration: 500, waveFreq: { 0 }, 0, 0 }, - { duration: 25, waveFreq: { 2600, 0 }, 0, 0 }, - { duration: 25, waveFreq: { 2900, 0 }, 9, 6 }, - { duration: 500, waveFreq: { 0 }, 0, 0 }, - { duration: 25, waveFreq: { 2600, 0 }, 0, 0 }, - { duration: 25, waveFreq: { 2900, 0 }, 9, 9 }, - { duration: 2500, waveFreq: { 0 }, 0, 0 }, - { duration: 0, waveFreq: { 0 }, 0, 0 }}, - repeatCnt: ToneGenerator::TONEGEN_INF, - repeatSegment: 0 }, // TONE_CDMA_MED_S_X4 - { segments: { { duration: 25, waveFreq: { 1300, 0 }, 0, 0 }, - { duration: 25, waveFreq: { 1450, 0 }, 9, 0 }, - { duration: 500, waveFreq: { 0 }, 0, 0 }, - { duration: 25, waveFreq: { 1300, 0 }, 0, 0 }, - { duration: 25, waveFreq: { 1450, 0 }, 9, 3 }, - { duration: 500, waveFreq: { 0 }, 0, 0 }, - { duration: 25, waveFreq: { 1300, 0 }, 0, 0 }, - { duration: 25, waveFreq: { 1450, 0 }, 9, 6 }, - { duration: 500, waveFreq: { 0 }, 0, 0 }, - { duration: 25, waveFreq: { 1300, 0 }, 0, 0 }, - { duration: 25, waveFreq: { 1450, 0 }, 9, 9 }, - { duration: 2500, waveFreq: { 0 }, 0, 0 }, - { duration: 0, waveFreq: { 0 }, 0, 0 }}, - repeatCnt: ToneGenerator::TONEGEN_INF, - repeatSegment: 0 }, // TONE_CDMA_LOW_S_X4 - { segments: { { duration: 25, waveFreq: { 3700, 0 }, 0, 0 }, - { duration: 25, waveFreq: { 4000, 0 }, 19, 0 }, - { duration: 2000, waveFreq: { 0 }, 0, 0 }, - { duration: 0, waveFreq: { 0 }, 0, 0 }}, - repeatCnt: ToneGenerator::TONEGEN_INF, - repeatSegment: 0 }, // TONE_CDMA_HIGH_PBX_L - { segments: { { duration: 25, waveFreq: { 2600, 0 }, 0, 0 }, - { duration: 25, waveFreq: { 2900, 0 }, 19, 0 }, - { duration: 2000, waveFreq: { 0 }, 0, 0 }, - { duration: 0, waveFreq: { 0 }, 0, 0 }}, - repeatCnt: ToneGenerator::TONEGEN_INF, - repeatSegment: 0 }, // TONE_CDMA_MED_PBX_L - { segments: { { duration: 25, waveFreq: { 1300, 0 }, 0, 0 }, - { duration: 25, waveFreq: { 1450, 0 }, 19, 0 }, - { duration: 2000, waveFreq: { 0 }, 0, 0 }, - { duration: 0, waveFreq: { 0 }, 0, 0 }}, - repeatCnt: ToneGenerator::TONEGEN_INF, - repeatSegment: 0 }, // TONE_CDMA_LOW_PBX_L - { segments: { { duration: 25, waveFreq: { 3700, 0 }, 0, 0 }, - { duration: 25, waveFreq: { 4000, 0 }, 7, 0 }, - { duration: 200, waveFreq: { 0 }, 0, 0 }, - { duration: 25, waveFreq: { 3700, 0 }, 0, 0 }, - { duration: 25, waveFreq: { 4000, 0 }, 7, 3 }, - { duration: 2000, waveFreq: { 0 }, 0, 0 }, - { duration: 0, waveFreq: { 0 }, 0, 0 }}, - repeatCnt: ToneGenerator::TONEGEN_INF, - repeatSegment: 0 }, // TONE_CDMA_HIGH_PBX_SS - { segments: { { duration: 25, waveFreq: { 2600, 0 }, 0, 0 }, - { duration: 25, waveFreq: { 2900, 0 }, 7, 0 }, - { duration: 200, waveFreq: { 0 }, 0, 0 }, - { duration: 25, waveFreq: { 2600, 0 }, 0, 0 }, - { duration: 25, waveFreq: { 2900, 0 }, 7, 3 }, - { duration: 2000, waveFreq: { 0 }, 0, 0 }, - { duration: 0, waveFreq: { 0 }, 0, 0 }}, - repeatCnt: ToneGenerator::TONEGEN_INF, - repeatSegment: 0 }, // TONE_CDMA_MED_PBX_SS - { segments: { { duration: 25, waveFreq: { 1300, 0 }, 0, 0 }, - { duration: 25, waveFreq: { 1450, 0 }, 7, 0 }, - { duration: 200, waveFreq: { 0 }, 0, 0 }, - { duration: 25, waveFreq: { 1300, 0 }, 0, 0 }, - { duration: 25, waveFreq: { 1450, 0 }, 7, 3 }, - { duration: 2000, waveFreq: { 0 }, 0, 0 }, - { duration: 0, waveFreq: { 0 }, 0, 0 }}, - repeatCnt: ToneGenerator::TONEGEN_INF, - repeatSegment: 0 }, // TONE_CDMA_LOW_PBX_SS - { segments: { { duration: 25, waveFreq: { 3700, 0 }, 0, 0 }, - { duration: 25, waveFreq: { 4000, 0 }, 7, 0 }, - { duration: 200, waveFreq: { 0 }, 0, 0 }, - { duration: 25, waveFreq: { 3700, 0 }, 0, 0 }, - { duration: 25, waveFreq: { 4000, 0 }, 7, 3 }, - { duration: 200, waveFreq: { 0 }, 0, 0 }, - { duration: 25, waveFreq: { 3700, 0 }, 0, 0 }, - { duration: 25, waveFreq: { 4000, 0 }, 15, 6 }, - { duration: 1000, waveFreq: { 0 }, 0, 0 }, - { duration: 0, waveFreq: { 0 }, 0, 0 }}, - repeatCnt: ToneGenerator::TONEGEN_INF, - repeatSegment: 0 }, // TONE_CDMA_HIGH_PBX_SSL - { segments: { { duration: 25, waveFreq: { 2600, 0 }, 0, 0 }, - { duration: 25, waveFreq: { 2900, 0 }, 7, 0 }, - { duration: 200, waveFreq: { 0 }, 0, 0 }, - { duration: 25, waveFreq: { 2600, 0 }, 0, 0 }, - { duration: 25, waveFreq: { 2900, 0 }, 7, 3 }, - { duration: 200, waveFreq: { 0 }, 0, 0 }, - { duration: 25, waveFreq: { 2600, 0 }, 0, 0 }, - { duration: 25, waveFreq: { 2900, 0 }, 15, 6 }, - { duration: 1000, waveFreq: { 0 }, 0, 0 }, - { duration: 0, waveFreq: { 0 }, 0, 0 }}, - repeatCnt: ToneGenerator::TONEGEN_INF, - repeatSegment: 0 }, // TONE_CDMA_MED_PBX_SSL - { segments: { { duration: 25, waveFreq: { 1300, 0 }, 0, 0 }, - { duration: 25, waveFreq: { 1450, 0 }, 7, 0 }, - { duration: 200, waveFreq: { 0 }, 0, 0 }, - { duration: 25, waveFreq: { 1300, 0 }, 0, 0 }, - { duration: 25, waveFreq: { 1450, 0 }, 7, 3 }, - { duration: 200, waveFreq: { 0 }, 0, 0 }, - { duration: 25, waveFreq: { 1300, 0 }, 0, 0 }, - { duration: 25, waveFreq: { 1450, 0 }, 15, 6 }, - { duration: 1000, waveFreq: { 0 }, 0, 0 }, - { duration: 0, waveFreq: { 0 }, 0, 0 }}, - repeatCnt: ToneGenerator::TONEGEN_INF, - repeatSegment: 0 }, // TONE_CDMA_LOW_PBX_SSL - { segments: { { duration: 25, waveFreq: { 3700, 0 }, 0, 0 }, - { duration: 25, waveFreq: { 4000, 0 }, 7, 0 }, - { duration: 200, waveFreq: { 0 }, 0, 0 }, - { duration: 25, waveFreq: { 3700, 0 }, 0, 0 }, - { duration: 25, waveFreq: { 4000, 0 }, 15, 3 }, - { duration: 200, waveFreq: { 0 }, 0, 0 }, - { duration: 25, waveFreq: { 3700, 0 }, 0, 0 }, - { duration: 25, waveFreq: { 4000, 0 }, 7, 6 }, - { duration: 1000, waveFreq: { 0 }, 0, 0 }, - { duration: 0, waveFreq: { 0 }, 0, 0 }}, - repeatCnt: ToneGenerator::TONEGEN_INF, - repeatSegment: 0 }, // TONE_CDMA_HIGH_PBX_SLS - { segments: { { duration: 25, waveFreq: { 2600, 0 }, 0, 0 }, - { duration: 25, waveFreq: { 2900, 0 }, 7, 0 }, - { duration: 200, waveFreq: { 0 }, 0, 0 }, - { duration: 25, waveFreq: { 2600, 0 }, 0, 0 }, - { duration: 25, waveFreq: { 2900, 0 }, 15, 3 }, - { duration: 200, waveFreq: { 0 }, 0, 0 }, - { duration: 25, waveFreq: { 2600, 0 }, 0, 0 }, - { duration: 25, waveFreq: { 2900, 0 }, 7, 6 }, - { duration: 1000, waveFreq: { 0 }, 0, 0 }, - { duration: 0, waveFreq: { 0 }, 0, 0 }}, - repeatCnt: ToneGenerator::TONEGEN_INF, - repeatSegment: 0 }, // TONE_CDMA_MED_PBX_SLS - { segments: { { duration: 25, waveFreq: { 1300, 0 }, 0, 0 }, - { duration: 25, waveFreq: { 1450, 0 }, 7, 0 }, - { duration: 200, waveFreq: { 0 }, 0, 0 }, - { duration: 25, waveFreq: { 1300, 0 }, 0, 0 }, - { duration: 25, waveFreq: { 1450, 0 }, 15, 3 }, - { duration: 200, waveFreq: { 0 }, 0, 0 }, - { duration: 25, waveFreq: { 1300, 0 }, 0, 0 }, - { duration: 25, waveFreq: { 1450, 0 }, 7, 6 }, - { duration: 1000, waveFreq: { 0 }, 0, 0 }, - { duration: 0, waveFreq: { 0 }, 0, 0 }}, - repeatCnt: ToneGenerator::TONEGEN_INF, - repeatSegment: 0 }, // TONE_CDMA_LOW_PBX_SLS - { segments: { { duration: 25, waveFreq: { 3700, 0 }, 0, 0 }, - { duration: 25, waveFreq: { 4000, 0 }, 7, 0 }, - { duration: 200, waveFreq: { 0 }, 0, 0 }, - { duration: 25, waveFreq: { 3700, 0 }, 0, 0 }, - { duration: 25, waveFreq: { 4000, 0 }, 7, 3 }, - { duration: 200, waveFreq: { 0 }, 0, 0 }, - { duration: 25, waveFreq: { 3700, 0 }, 0, 0 }, - { duration: 25, waveFreq: { 4000, 0 }, 7, 6 }, - { duration: 200, waveFreq: { 0 }, 0, 0 }, - { duration: 25, waveFreq: { 3700, 0 }, 0, 0 }, - { duration: 25, waveFreq: { 4000, 0 }, 7, 9 }, - { duration: 800, waveFreq: { 0 }, 0, 0 }, - { duration: 0, waveFreq: { 0 }, 0, 0 }}, - repeatCnt: ToneGenerator::TONEGEN_INF, - repeatSegment: 0 }, // TONE_CDMA_HIGH_PBX_S_X4 - { segments: { { duration: 25, waveFreq: { 2600, 0 }, 0, 0 }, - { duration: 25, waveFreq: { 2900, 0 }, 7, 0 }, - { duration: 200, waveFreq: { 0 }, 0, 0 }, - { duration: 25, waveFreq: { 2600, 0 }, 0, 0 }, - { duration: 25, waveFreq: { 2900, 0 }, 7, 3 }, - { duration: 200, waveFreq: { 0 }, 0, 0 }, - { duration: 25, waveFreq: { 2600, 0 }, 0, 0 }, - { duration: 25, waveFreq: { 2900, 0 }, 7, 6 }, - { duration: 200, waveFreq: { 0 }, 0, 0 }, - { duration: 25, waveFreq: { 2600, 0 }, 0, 0 }, - { duration: 25, waveFreq: { 2900, 0 }, 7, 9 }, - { duration: 800, waveFreq: { 0 }, 0, 0 }, - { duration: 0, waveFreq: { 0 }, 0, 0 }}, - repeatCnt: ToneGenerator::TONEGEN_INF, - repeatSegment: 0 }, // TONE_CDMA_MED_PBX_S_X4 - { segments: { { duration: 25, waveFreq: { 1300, 0 }, 0, 0 }, - { duration: 25, waveFreq: { 1450, 0 }, 7, 0 }, - { duration: 200, waveFreq: { 0 }, 0, 0 }, - { duration: 25, waveFreq: { 1300, 0 }, 0, 0 }, - { duration: 25, waveFreq: { 1450, 0 }, 7, 3 }, - { duration: 200, waveFreq: { 0 }, 0, 0 }, - { duration: 25, waveFreq: { 1300, 0 }, 0, 0 }, - { duration: 25, waveFreq: { 1450, 0 }, 7, 6 }, - { duration: 200, waveFreq: { 0 }, 0, 0 }, - { duration: 25, waveFreq: { 1300, 0 }, 0, 0 }, - { duration: 25, waveFreq: { 1450, 0 }, 7, 9 }, - { duration: 800, waveFreq: { 0 }, 0, 0 }, - { duration: 0, waveFreq: { 0 }, 0, 0 }}, - repeatCnt: ToneGenerator::TONEGEN_INF, - repeatSegment: 0 }, // TONE_CDMA_LOW_PBX_S_X4 - - { segments: { { duration: 62, waveFreq: { 1109, 0 }, 0, 0 }, - { duration: 62, waveFreq: { 784, 0 }, 0, 0 }, - { duration: 62, waveFreq: { 740, 0 }, 0, 0 }, - { duration: 62, waveFreq: { 622, 0 }, 0, 0 }, - { duration: 62, waveFreq: { 1109, 0 }, 0, 0 }, - { duration: 0, waveFreq: { 0 }, 0, 0 } }, - repeatCnt: 0, - repeatSegment: 0 }, // TONE_CDMA_ALERT_NETWORK_LITE - { segments: { { duration: 62, waveFreq: { 1245, 0 }, 0, 0 }, - { duration: 62, waveFreq: { 659, 0 }, 2, 0 }, - { duration: 62, waveFreq: { 1245, 0 }, 0, 0 }, - { duration: 0, waveFreq: { 0 }, 0, 0 } }, - repeatCnt: 0, - repeatSegment: 0 }, // TONE_CDMA_ALERT_AUTOREDIAL_LITE - { segments: { { duration: 400, waveFreq: { 1150, 770, 0 }, 0, 0 }, - { duration: 0, waveFreq: { 0 }, 0, 0 } }, - repeatCnt: 0, - repeatSegment: 0 }, // TONE_CDMA_ONE_MIN_BEEP - { segments: { { duration: 120, waveFreq: { 941, 1477, 0 }, 0, 0 }, - { duration: 0, waveFreq: { 0 }, 0, 0 } }, - repeatCnt: 0, - repeatSegment: 0 }, // TONE_CDMA_KEYPAD_VOLUME_KEY_LITE - { segments: { { duration: 375, waveFreq: { 587, 0 }, 0, 0 }, - { duration: 125, waveFreq: { 1175, 0 }, 0, 0 }, - { duration: 0, waveFreq: { 0 }, 0, 0 } }, - repeatCnt: 0, - repeatSegment: 0 }, // TONE_CDMA_PRESSHOLDKEY_LITE - { segments: { { duration: 62, waveFreq: { 587, 0 }, 0, 0 }, - { duration: 62, waveFreq: { 784, 0 }, 0, 0 }, - { duration: 62, waveFreq: { 831, 0 }, 0, 0 }, - { duration: 62, waveFreq: { 784, 0 }, 0, 0 }, - { duration: 62, waveFreq: { 1109, 0 }, 0, 0 }, - { duration: 62, waveFreq: { 784, 0 }, 0, 0 }, - { duration: 62, waveFreq: { 831, 0 }, 0, 0 }, - { duration: 62, waveFreq: { 784, 0 }, 0, 0 }, - { duration: 0, waveFreq: { 0 }, 0, 0 } }, - repeatCnt: 0, - repeatSegment: 0 }, // TONE_CDMA_ALERT_INCALL_LITE - { segments: { { duration: 125, waveFreq: { 941, 0 }, 0, 0 }, - { duration: 10, waveFreq: { 0 }, 2, 0 }, - { duration: 4990, waveFreq: { 0 }, 0, 0 }, - { duration: 0, waveFreq: { 0 }, 0, 0 } }, - repeatCnt: ToneGenerator::TONEGEN_INF, - repeatSegment: 0 }, // TONE_CDMA_EMERGENCY_RINGBACK - { segments: { { duration: 125, waveFreq: { 1319, 0 }, 0, 0 }, - { duration: 125, waveFreq: { 0 }, 0, 0 }, - { duration: 0, waveFreq: { 0 }, 0, 0 } }, - repeatCnt: 2, - repeatSegment: 0 }, // TONE_CDMA_ALERT_CALL_GUARD - { segments: { { duration: 125, waveFreq: { 1047, 0 }, 0, 0 }, - { duration: 125, waveFreq: { 370, 0 }, 0, 0 }, - { duration: 0, waveFreq: { 0 }, 0, 0 } }, - repeatCnt: 0, - repeatSegment: 0 }, // TONE_CDMA_SOFT_ERROR_LITE - { segments: { { duration: 125, waveFreq: { 1480, 0 }, 0, 0 }, - { duration: 125, waveFreq: { 1397, 0 }, 0, 0 }, - { duration: 125, waveFreq: { 784, 0 }, 0, 0 }, - { duration: 0, waveFreq: { 0 }, 0, 0 } }, - repeatCnt: 0, - repeatSegment: 0 }, // TONE_CDMA_CALLDROP_LITE - - { segments: { { duration: 500, waveFreq: { 425, 0 }, 0, 0 }, - { duration: 500, waveFreq: { 0 }, 0, 0 }, - { duration: 0, waveFreq: { 0 }, 0, 0 }}, - repeatCnt: 0, - repeatSegment: 0 }, // TONE_CDMA_NETWORK_BUSY_ONE_SHOT - { segments: { { duration: 400, waveFreq: { 1150, 770 }, 0, 0 }, - { duration: 0, waveFreq: { 0 }, 0, 0 }}, - repeatCnt: 0, - repeatSegment: 0 }, // TONE_CDMA_ABBR_ALERT - { segments: { { duration: 0, waveFreq: { 0 }, 0, 0 }}, - repeatCnt: 0, - repeatSegment: 0 }, // TONE_CDMA_SIGNAL_OFF - - { segments: { { duration: ToneGenerator::TONEGEN_INF, waveFreq: { 350, 440, 0 }, 0, 0 }, - { duration: 0 , waveFreq: { 0 }, 0, 0}}, - repeatCnt: ToneGenerator::TONEGEN_INF, - repeatSegment: 0 }, // TONE_ANSI_DIAL - { segments: { { duration: 500, waveFreq: { 480, 620, 0 }, 0, 0 }, - { duration: 500, waveFreq: { 0 }, 0, 0 }, - { duration: 0 , waveFreq: { 0 }, 0, 0}}, - repeatCnt: ToneGenerator::TONEGEN_INF, - repeatSegment: 0 }, // TONE_ANSI_BUSY - { segments: { { duration: 250, waveFreq: { 480, 620, 0 }, 0, 0 }, - { duration: 250, waveFreq: { 0 }, 0, 0 }, - { duration: 0 , waveFreq: { 0 }, 0, 0}}, - repeatCnt: ToneGenerator::TONEGEN_INF, - repeatSegment: 0 }, // TONE_ANSI_CONGESTION - { segments: { { duration: 300, waveFreq: { 440, 0 }, 0, 0 }, - { duration: 9700, waveFreq: { 0 }, 0, 0 }, - { duration: 100, waveFreq: { 440, 0 }, 0, 0 }, - { duration: 100, waveFreq: { 0 }, 0, 0 }, - { duration: 100, waveFreq: { 440, 0 }, 0, 0 }, - { duration: 0 , waveFreq: { 0 }, 0, 0}}, - repeatCnt: ToneGenerator::TONEGEN_INF, - repeatSegment: 1 }, // TONE_ANSI_CALL_WAITING - { segments: { { duration: 2000, waveFreq: { 440, 480, 0 }, 0, 0 }, - { duration: 4000, waveFreq: { 0 }, 0, 0 }, - { duration: 0 , waveFreq: { 0 }, 0, 0}}, - repeatCnt: ToneGenerator::TONEGEN_INF, - repeatSegment: 0 }, // TONE_ANSI_RINGTONE - { segments: { { duration: ToneGenerator::TONEGEN_INF, waveFreq: { 400, 0 }, 0, 0 }, - { duration: 0 , waveFreq: { 0 }, 0, 0}}, - repeatCnt: ToneGenerator::TONEGEN_INF, - repeatSegment: 0 }, // TONE_JAPAN_DIAL - { segments: { { duration: 500, waveFreq: { 400, 0 }, 0, 0 }, - { duration: 500, waveFreq: { 0 }, 0, 0 }, - { duration: 0 , waveFreq: { 0 }, 0, 0}}, - repeatCnt: ToneGenerator::TONEGEN_INF, - repeatSegment: 0 }, // TONE_JAPAN_BUSY - { segments: { { duration: 1000, waveFreq: { 400, 0 }, 0, 0 }, - { duration: 2000, waveFreq: { 0 }, 0, 0 }, - { duration: 0 , waveFreq: { 0 }, 0, 0}}, - repeatCnt: ToneGenerator::TONEGEN_INF, - repeatSegment: 0 }, // TONE_JAPAN_RADIO_ACK - - - -}; - -// Used by ToneGenerator::getToneForRegion() to convert user specified supervisory tone type -// to actual tone for current region. -const unsigned char /*tone_type*/ ToneGenerator::sToneMappingTable[NUM_REGIONS-1][NUM_SUP_TONES] = { - { // ANSI - TONE_ANSI_DIAL, // TONE_SUP_DIAL - TONE_ANSI_BUSY, // TONE_SUP_BUSY - TONE_ANSI_CONGESTION, // TONE_SUP_CONGESTION - TONE_SUP_RADIO_ACK, // TONE_SUP_RADIO_ACK - TONE_SUP_RADIO_NOTAVAIL, // TONE_SUP_RADIO_NOTAVAIL - TONE_SUP_ERROR, // TONE_SUP_ERROR - TONE_ANSI_CALL_WAITING, // TONE_SUP_CALL_WAITING - TONE_ANSI_RINGTONE // TONE_SUP_RINGTONE - }, - { // JAPAN - TONE_JAPAN_DIAL, // TONE_SUP_DIAL - TONE_JAPAN_BUSY, // TONE_SUP_BUSY - TONE_SUP_CONGESTION, // TONE_SUP_CONGESTION - TONE_JAPAN_RADIO_ACK, // TONE_SUP_RADIO_ACK - TONE_SUP_RADIO_NOTAVAIL, // TONE_SUP_RADIO_NOTAVAIL - TONE_SUP_ERROR, // TONE_SUP_ERROR - TONE_SUP_CALL_WAITING, // TONE_SUP_CALL_WAITING - TONE_SUP_RINGTONE // TONE_SUP_RINGTONE - } -}; - - -//////////////////////////////////////////////////////////////////////////////// -// ToneGenerator class Implementation -//////////////////////////////////////////////////////////////////////////////// - - -//---------------------------------- public methods ---------------------------- - - -//////////////////////////////////////////////////////////////////////////////// -// -// Method: ToneGenerator::ToneGenerator() -// -// Description: Constructor. Initializes the tone sequencer, intantiates required sine wave -// generators, instantiates output audio track. -// -// Input: -// streamType: Type of stream used for tone playback -// volume: volume applied to tone (0.0 to 1.0) -// -// Output: -// none -// -//////////////////////////////////////////////////////////////////////////////// -ToneGenerator::ToneGenerator(audio_stream_type_t streamType, float volume, bool threadCanCallJava) { - - ALOGV("ToneGenerator constructor: streamType=%d, volume=%f", streamType, volume); - - mState = TONE_IDLE; - - if (AudioSystem::getOutputSamplingRate(&mSamplingRate, streamType) != NO_ERROR) { - ALOGE("Unable to marshal AudioFlinger"); - return; - } - mThreadCanCallJava = threadCanCallJava; - mStreamType = streamType; - mVolume = volume; - mpAudioTrack = NULL; - mpToneDesc = NULL; - mpNewToneDesc = NULL; - // Generate tone by chunks of 20 ms to keep cadencing precision - mProcessSize = (mSamplingRate * 20) / 1000; - - char value[PROPERTY_VALUE_MAX]; - property_get("gsm.operator.iso-country", value, ""); - if (strcmp(value,"us") == 0 || - strcmp(value,"ca") == 0) { - mRegion = ANSI; - } else if (strcmp(value,"jp") == 0) { - mRegion = JAPAN; - } else { - mRegion = CEPT; - } - - if (initAudioTrack()) { - ALOGV("ToneGenerator INIT OK, time: %d", (unsigned int)(systemTime()/1000000)); - } else { - ALOGV("!!!ToneGenerator INIT FAILED!!!"); - } -} - - - - -//////////////////////////////////////////////////////////////////////////////// -// -// Method: ToneGenerator::~ToneGenerator() -// -// Description: Destructor. Stop sound playback and delete audio track if -// needed and delete sine wave generators. -// -// Input: -// none -// -// Output: -// none -// -//////////////////////////////////////////////////////////////////////////////// -ToneGenerator::~ToneGenerator() { - ALOGV("ToneGenerator destructor"); - - if (mpAudioTrack != NULL) { - stopTone(); - ALOGV("Delete Track: %p", mpAudioTrack); - delete mpAudioTrack; - } -} - -//////////////////////////////////////////////////////////////////////////////// -// -// Method: ToneGenerator::startTone() -// -// Description: Starts tone playback. -// -// Input: -// toneType: Type of tone generated (values in enum tone_type) -// durationMs: The tone duration in milliseconds. If the tone is limited in time by definition, -// the actual duration will be the minimum of durationMs and the defined tone duration. -// Ommiting or setting durationMs to -1 does not limit tone duration. -// -// Output: -// none -// -//////////////////////////////////////////////////////////////////////////////// -bool ToneGenerator::startTone(tone_type toneType, int durationMs) { - bool lResult = false; - status_t lStatus; - - if ((toneType < 0) || (toneType >= NUM_TONES)) - return lResult; - - if (mState == TONE_IDLE) { - ALOGV("startTone: try to re-init AudioTrack"); - if (!initAudioTrack()) { - return lResult; - } - } - - ALOGV("startTone"); - - mLock.lock(); - - // Get descriptor for requested tone - toneType = getToneForRegion(toneType); - mpNewToneDesc = &sToneDescriptors[toneType]; - - mDurationMs = durationMs; - - if (mState == TONE_STOPPED) { - ALOGV("Start waiting for previous tone to stop"); - lStatus = mWaitCbkCond.waitRelative(mLock, seconds(3)); - if (lStatus != NO_ERROR) { - ALOGE("--- start wait for stop timed out, status %d", lStatus); - mState = TONE_IDLE; - mLock.unlock(); - return lResult; - } - } - - if (mState == TONE_INIT) { - if (prepareWave()) { - ALOGV("Immediate start, time %d", (unsigned int)(systemTime()/1000000)); - lResult = true; - mState = TONE_STARTING; - mLock.unlock(); - mpAudioTrack->start(); - mLock.lock(); - if (mState == TONE_STARTING) { - ALOGV("Wait for start callback"); - lStatus = mWaitCbkCond.waitRelative(mLock, seconds(3)); - if (lStatus != NO_ERROR) { - ALOGE("--- Immediate start timed out, status %d", lStatus); - mState = TONE_IDLE; - lResult = false; - } - } - } else { - mState = TONE_IDLE; - } - } else { - ALOGV("Delayed start"); - mState = TONE_RESTARTING; - lStatus = mWaitCbkCond.waitRelative(mLock, seconds(3)); - if (lStatus == NO_ERROR) { - if (mState != TONE_IDLE) { - lResult = true; - } - ALOGV("cond received"); - } else { - ALOGE("--- Delayed start timed out, status %d", lStatus); - mState = TONE_IDLE; - } - } - mLock.unlock(); - - ALOGV_IF(lResult, "Tone started, time %d", (unsigned int)(systemTime()/1000000)); - ALOGW_IF(!lResult, "Tone start failed!!!, time %d", (unsigned int)(systemTime()/1000000)); - - return lResult; -} - -//////////////////////////////////////////////////////////////////////////////// -// -// Method: ToneGenerator::stopTone() -// -// Description: Stops tone playback. -// -// Input: -// none -// -// Output: -// none -// -//////////////////////////////////////////////////////////////////////////////// -void ToneGenerator::stopTone() { - ALOGV("stopTone"); - - mLock.lock(); - if (mState == TONE_PLAYING || mState == TONE_STARTING || mState == TONE_RESTARTING) { - mState = TONE_STOPPING; - ALOGV("waiting cond"); - status_t lStatus = mWaitCbkCond.waitRelative(mLock, seconds(3)); - if (lStatus == NO_ERROR) { - ALOGV("track stop complete, time %d", (unsigned int)(systemTime()/1000000)); - } else { - ALOGE("--- Stop timed out"); - mState = TONE_IDLE; - mpAudioTrack->stop(); - } - } - - clearWaveGens(); - - mLock.unlock(); -} - -//---------------------------------- private methods --------------------------- - - - - -//////////////////////////////////////////////////////////////////////////////// -// -// Method: ToneGenerator::initAudioTrack() -// -// Description: Allocates and configures AudioTrack used for PCM output. -// -// Input: -// none -// -// Output: -// none -// -//////////////////////////////////////////////////////////////////////////////// -bool ToneGenerator::initAudioTrack() { - - if (mpAudioTrack) { - delete mpAudioTrack; - mpAudioTrack = NULL; - } - - // Open audio track in mono, PCM 16bit, default sampling rate, default buffer size - mpAudioTrack = new AudioTrack(); - ALOGV("Create Track: %p", mpAudioTrack); - - mpAudioTrack->set(mStreamType, - 0, - AUDIO_FORMAT_PCM_16_BIT, - AUDIO_CHANNEL_OUT_MONO, - 0, - AUDIO_POLICY_OUTPUT_FLAG_NONE, - audioCallback, - this, - 0, - 0, - mThreadCanCallJava); - - if (mpAudioTrack->initCheck() != NO_ERROR) { - ALOGE("AudioTrack->initCheck failed"); - goto initAudioTrack_exit; - } - - mpAudioTrack->setVolume(mVolume, mVolume); - - mState = TONE_INIT; - - return true; - -initAudioTrack_exit: - - // Cleanup - if (mpAudioTrack != NULL) { - ALOGV("Delete Track I: %p", mpAudioTrack); - delete mpAudioTrack; - mpAudioTrack = NULL; - } - - return false; -} - - -//////////////////////////////////////////////////////////////////////////////// -// -// Method: ToneGenerator::audioCallback() -// -// Description: AudioTrack callback implementation. Generates a block of -// PCM samples -// and manages tone generator sequencer: tones pulses, tone duration... -// -// Input: -// user reference (pointer to our ToneGenerator) -// info audio buffer descriptor -// -// Output: -// returned value: always true. -// -//////////////////////////////////////////////////////////////////////////////// -void ToneGenerator::audioCallback(int event, void* user, void *info) { - - if (event != AudioTrack::EVENT_MORE_DATA) return; - - AudioTrack::Buffer *buffer = static_cast<AudioTrack::Buffer *>(info); - ToneGenerator *lpToneGen = static_cast<ToneGenerator *>(user); - short *lpOut = buffer->i16; - unsigned int lNumSmp = buffer->size/sizeof(short); - const ToneDescriptor *lpToneDesc = lpToneGen->mpToneDesc; - - if (buffer->size == 0) return; - - - // Clear output buffer: WaveGenerator accumulates into lpOut buffer - memset(lpOut, 0, buffer->size); - - while (lNumSmp) { - unsigned int lReqSmp = lNumSmp < lpToneGen->mProcessSize*2 ? lNumSmp : lpToneGen->mProcessSize; - unsigned int lGenSmp; - unsigned int lWaveCmd = WaveGenerator::WAVEGEN_CONT; - bool lSignal = false; - - lpToneGen->mLock.lock(); - - - // Update pcm frame count and end time (current time at the end of this process) - lpToneGen->mTotalSmp += lReqSmp; - - // Update tone gen state machine and select wave gen command - switch (lpToneGen->mState) { - case TONE_PLAYING: - lWaveCmd = WaveGenerator::WAVEGEN_CONT; - break; - case TONE_STARTING: - ALOGV("Starting Cbk"); - - lWaveCmd = WaveGenerator::WAVEGEN_START; - break; - case TONE_STOPPING: - case TONE_RESTARTING: - ALOGV("Stop/restart Cbk"); - - lWaveCmd = WaveGenerator::WAVEGEN_STOP; - lpToneGen->mNextSegSmp = TONEGEN_INF; // forced to skip state machine management below - break; - case TONE_STOPPED: - ALOGV("Stopped Cbk"); - goto audioCallback_EndLoop; - default: - ALOGV("Extra Cbk"); - goto audioCallback_EndLoop; - } - - // Exit if tone sequence is over - if (lpToneDesc->segments[lpToneGen->mCurSegment].duration == 0 || - lpToneGen->mTotalSmp > lpToneGen->mMaxSmp) { - if (lpToneGen->mState == TONE_PLAYING) { - lpToneGen->mState = TONE_STOPPING; - } - if (lpToneDesc->segments[lpToneGen->mCurSegment].duration == 0) { - goto audioCallback_EndLoop; - } - // fade out before stopping if maximum duration reached - lWaveCmd = WaveGenerator::WAVEGEN_STOP; - lpToneGen->mNextSegSmp = TONEGEN_INF; // forced to skip state machine management below - } - - if (lpToneGen->mTotalSmp > lpToneGen->mNextSegSmp) { - // Time to go to next sequence segment - - ALOGV("End Segment, time: %d", (unsigned int)(systemTime()/1000000)); - - lGenSmp = lReqSmp; - - // If segment, ON -> OFF transition : ramp volume down - if (lpToneDesc->segments[lpToneGen->mCurSegment].waveFreq[0] != 0) { - lWaveCmd = WaveGenerator::WAVEGEN_STOP; - unsigned int lFreqIdx = 0; - unsigned short lFrequency = lpToneDesc->segments[lpToneGen->mCurSegment].waveFreq[lFreqIdx]; - - while (lFrequency != 0) { - WaveGenerator *lpWaveGen = lpToneGen->mWaveGens.valueFor(lFrequency); - lpWaveGen->getSamples(lpOut, lGenSmp, lWaveCmd); - lFrequency = lpToneDesc->segments[lpToneGen->mCurSegment].waveFreq[++lFreqIdx]; - } - ALOGV("ON->OFF, lGenSmp: %d, lReqSmp: %d", lGenSmp, lReqSmp); - } - - // check if we need to loop and loop for the reqd times - if (lpToneDesc->segments[lpToneGen->mCurSegment].loopCnt) { - if (lpToneGen->mLoopCounter < lpToneDesc->segments[lpToneGen->mCurSegment].loopCnt) { - ALOGV ("in if loop loopCnt(%d) loopctr(%d), CurSeg(%d)", - lpToneDesc->segments[lpToneGen->mCurSegment].loopCnt, - lpToneGen->mLoopCounter, - lpToneGen->mCurSegment); - lpToneGen->mCurSegment = lpToneDesc->segments[lpToneGen->mCurSegment].loopIndx; - ++lpToneGen->mLoopCounter; - } else { - // completed loop. go to next segment - lpToneGen->mLoopCounter = 0; - lpToneGen->mCurSegment++; - ALOGV ("in else loop loopCnt(%d) loopctr(%d), CurSeg(%d)", - lpToneDesc->segments[lpToneGen->mCurSegment].loopCnt, - lpToneGen->mLoopCounter, - lpToneGen->mCurSegment); - } - } else { - lpToneGen->mCurSegment++; - ALOGV ("Goto next seg loopCnt(%d) loopctr(%d), CurSeg(%d)", - lpToneDesc->segments[lpToneGen->mCurSegment].loopCnt, - lpToneGen->mLoopCounter, - lpToneGen->mCurSegment); - - } - - // Handle loop if last segment reached - if (lpToneDesc->segments[lpToneGen->mCurSegment].duration == 0) { - ALOGV("Last Seg: %d", lpToneGen->mCurSegment); - - // Pre increment loop count and restart if total count not reached. Stop sequence otherwise - if (++lpToneGen->mCurCount <= lpToneDesc->repeatCnt) { - ALOGV("Repeating Count: %d", lpToneGen->mCurCount); - - lpToneGen->mCurSegment = lpToneDesc->repeatSegment; - if (lpToneDesc->segments[lpToneDesc->repeatSegment].waveFreq[0] != 0) { - lWaveCmd = WaveGenerator::WAVEGEN_START; - } - - ALOGV("New segment %d, Next Time: %d", lpToneGen->mCurSegment, - (lpToneGen->mNextSegSmp*1000)/lpToneGen->mSamplingRate); - - } else { - lGenSmp = 0; - ALOGV("End repeat, time: %d", (unsigned int)(systemTime()/1000000)); - } - } else { - ALOGV("New segment %d, Next Time: %d", lpToneGen->mCurSegment, - (lpToneGen->mNextSegSmp*1000)/lpToneGen->mSamplingRate); - if (lpToneDesc->segments[lpToneGen->mCurSegment].waveFreq[0] != 0) { - // If next segment is not silent, OFF -> ON transition : reset wave generator - lWaveCmd = WaveGenerator::WAVEGEN_START; - - ALOGV("OFF->ON, lGenSmp: %d, lReqSmp: %d", lGenSmp, lReqSmp); - } else { - lGenSmp = 0; - } - } - - // Update next segment transition position. No harm to do it also for last segment as lpToneGen->mNextSegSmp won't be used any more - lpToneGen->mNextSegSmp - += (lpToneDesc->segments[lpToneGen->mCurSegment].duration * lpToneGen->mSamplingRate) / 1000; - - } else { - // Inside a segment keep tone ON or OFF - if (lpToneDesc->segments[lpToneGen->mCurSegment].waveFreq[0] == 0) { - lGenSmp = 0; // If odd segment, tone is currently OFF - } else { - lGenSmp = lReqSmp; // If event segment, tone is currently ON - } - } - - if (lGenSmp) { - // If samples must be generated, call all active wave generators and acumulate waves in lpOut - unsigned int lFreqIdx = 0; - unsigned short lFrequency = lpToneDesc->segments[lpToneGen->mCurSegment].waveFreq[lFreqIdx]; - - while (lFrequency != 0) { - WaveGenerator *lpWaveGen = lpToneGen->mWaveGens.valueFor(lFrequency); - lpWaveGen->getSamples(lpOut, lGenSmp, lWaveCmd); - lFrequency = lpToneDesc->segments[lpToneGen->mCurSegment].waveFreq[++lFreqIdx]; - } - } - - lNumSmp -= lReqSmp; - lpOut += lReqSmp; - -audioCallback_EndLoop: - - switch (lpToneGen->mState) { - case TONE_RESTARTING: - ALOGV("Cbk restarting track"); - if (lpToneGen->prepareWave()) { - lpToneGen->mState = TONE_STARTING; - // must reload lpToneDesc as prepareWave() may change mpToneDesc - lpToneDesc = lpToneGen->mpToneDesc; - } else { - ALOGW("Cbk restarting prepareWave() failed"); - lpToneGen->mState = TONE_IDLE; - lpToneGen->mpAudioTrack->stop(); - // Force loop exit - lNumSmp = 0; - } - lSignal = true; - break; - case TONE_STOPPING: - ALOGV("Cbk Stopping"); - lpToneGen->mState = TONE_STOPPED; - // Force loop exit - lNumSmp = 0; - break; - case TONE_STOPPED: - lpToneGen->mState = TONE_INIT; - ALOGV("Cbk Stopped track"); - lpToneGen->mpAudioTrack->stop(); - // Force loop exit - lNumSmp = 0; - buffer->size = 0; - lSignal = true; - break; - case TONE_STARTING: - ALOGV("Cbk starting track"); - lpToneGen->mState = TONE_PLAYING; - lSignal = true; - break; - case TONE_PLAYING: - break; - default: - // Force loop exit - lNumSmp = 0; - buffer->size = 0; - break; - } - - if (lSignal) - lpToneGen->mWaitCbkCond.signal(); - lpToneGen->mLock.unlock(); - } -} - - -//////////////////////////////////////////////////////////////////////////////// -// -// Method: ToneGenerator::prepareWave() -// -// Description: Prepare wave generators and reset tone sequencer state machine. -// mpNewToneDesc must have been initialized before calling this function. -// Input: -// none -// -// Output: -// returned value: true if wave generators have been created, false otherwise -// -//////////////////////////////////////////////////////////////////////////////// -bool ToneGenerator::prepareWave() { - unsigned int segmentIdx = 0; - - if (mpNewToneDesc == NULL) { - return false; - } - - // Remove existing wave generators if any - clearWaveGens(); - - mpToneDesc = mpNewToneDesc; - - if (mDurationMs == -1) { - mMaxSmp = TONEGEN_INF; - } else { - if (mDurationMs > (int)(TONEGEN_INF / mSamplingRate)) { - mMaxSmp = (mDurationMs / 1000) * mSamplingRate; - } else { - mMaxSmp = (mDurationMs * mSamplingRate) / 1000; - } - ALOGV("prepareWave, duration limited to %d ms", mDurationMs); - } - - while (mpToneDesc->segments[segmentIdx].duration) { - // Get total number of sine waves: needed to adapt sine wave gain. - unsigned int lNumWaves = numWaves(segmentIdx); - unsigned int freqIdx = 0; - unsigned int frequency = mpToneDesc->segments[segmentIdx].waveFreq[freqIdx]; - while (frequency) { - // Instantiate a wave generator if ot already done for this frequency - if (mWaveGens.indexOfKey(frequency) == NAME_NOT_FOUND) { - ToneGenerator::WaveGenerator *lpWaveGen = - new ToneGenerator::WaveGenerator((unsigned short)mSamplingRate, - frequency, - TONEGEN_GAIN/lNumWaves); - mWaveGens.add(frequency, lpWaveGen); - } - frequency = mpNewToneDesc->segments[segmentIdx].waveFreq[++freqIdx]; - } - segmentIdx++; - } - - // Initialize tone sequencer - mTotalSmp = 0; - mCurSegment = 0; - mCurCount = 0; - mLoopCounter = 0; - if (mpToneDesc->segments[0].duration == TONEGEN_INF) { - mNextSegSmp = TONEGEN_INF; - } else{ - mNextSegSmp = (mpToneDesc->segments[0].duration * mSamplingRate) / 1000; - } - - return true; -} - - -//////////////////////////////////////////////////////////////////////////////// -// -// Method: ToneGenerator::numWaves() -// -// Description: Count number of sine waves needed to generate a tone segment (e.g 2 for DTMF). -// -// Input: -// segmentIdx tone segment index -// -// Output: -// returned value: nummber of sine waves -// -//////////////////////////////////////////////////////////////////////////////// -unsigned int ToneGenerator::numWaves(unsigned int segmentIdx) { - unsigned int lCnt = 0; - - if (mpToneDesc->segments[segmentIdx].duration) { - while (mpToneDesc->segments[segmentIdx].waveFreq[lCnt]) { - lCnt++; - } - lCnt++; - } - - return lCnt; -} - - -//////////////////////////////////////////////////////////////////////////////// -// -// Method: ToneGenerator::clearWaveGens() -// -// Description: Removes all wave generators. -// -// Input: -// none -// -// Output: -// none -// -//////////////////////////////////////////////////////////////////////////////// -void ToneGenerator::clearWaveGens() { - ALOGV("Clearing mWaveGens:"); - - for (size_t lIdx = 0; lIdx < mWaveGens.size(); lIdx++) { - delete mWaveGens.valueAt(lIdx); - } - mWaveGens.clear(); -} - -//////////////////////////////////////////////////////////////////////////////// -// -// Method: ToneGenerator::getToneForRegion() -// -// Description: Get correct ringtone type according to current region. -// The corrected ring tone type is the tone descriptor index in sToneDescriptors[]. -// -// Input: -// none -// -// Output: -// none -// -//////////////////////////////////////////////////////////////////////////////// -ToneGenerator::tone_type ToneGenerator::getToneForRegion(tone_type toneType) { - tone_type regionTone; - - if (mRegion == CEPT || toneType < FIRST_SUP_TONE || toneType > LAST_SUP_TONE) { - regionTone = toneType; - } else { - regionTone = (tone_type) sToneMappingTable[mRegion][toneType - FIRST_SUP_TONE]; - } - - ALOGV("getToneForRegion, tone %d, region %d, regionTone %d", toneType, mRegion, regionTone); - - return regionTone; -} - - -//////////////////////////////////////////////////////////////////////////////// -// WaveGenerator::WaveGenerator class Implementation -//////////////////////////////////////////////////////////////////////////////// - -//---------------------------------- public methods ---------------------------- - -//////////////////////////////////////////////////////////////////////////////// -// -// Method: WaveGenerator::WaveGenerator() -// -// Description: Constructor. -// -// Input: -// samplingRate: Output sampling rate in Hz -// frequency: Frequency of the sine wave to generate in Hz -// volume: volume (0.0 to 1.0) -// -// Output: -// none -// -//////////////////////////////////////////////////////////////////////////////// -ToneGenerator::WaveGenerator::WaveGenerator(unsigned short samplingRate, - unsigned short frequency, float volume) { - double d0; - double F_div_Fs; // frequency / samplingRate - - F_div_Fs = frequency / (double)samplingRate; - d0 = - (float)GEN_AMP * sin(2 * M_PI * F_div_Fs); - mS2_0 = (short)d0; - mS1 = 0; - mS2 = mS2_0; - - mAmplitude_Q15 = (short)(32767. * 32767. * volume / GEN_AMP); - // take some margin for amplitude fluctuation - if (mAmplitude_Q15 > 32500) - mAmplitude_Q15 = 32500; - - d0 = 32768.0 * cos(2 * M_PI * F_div_Fs); // Q14*2*cos() - if (d0 > 32767) - d0 = 32767; - mA1_Q14 = (short) d0; - - ALOGV("WaveGenerator init, mA1_Q14: %d, mS2_0: %d, mAmplitude_Q15: %d", - mA1_Q14, mS2_0, mAmplitude_Q15); -} - -//////////////////////////////////////////////////////////////////////////////// -// -// Method: WaveGenerator::~WaveGenerator() -// -// Description: Destructor. -// -// Input: -// none -// -// Output: -// none -// -//////////////////////////////////////////////////////////////////////////////// -ToneGenerator::WaveGenerator::~WaveGenerator() { -} - -//////////////////////////////////////////////////////////////////////////////// -// -// Method: WaveGenerator::getSamples() -// -// Description: Generates count samples of a sine wave and accumulates -// result in outBuffer. -// -// Input: -// outBuffer: Output buffer where to accumulate samples. -// count: number of samples to produce. -// command: special action requested (see enum gen_command). -// -// Output: -// none -// -//////////////////////////////////////////////////////////////////////////////// -void ToneGenerator::WaveGenerator::getSamples(short *outBuffer, - unsigned int count, unsigned int command) { - long lS1, lS2; - long lA1, lAmplitude; - long Sample; // current sample - - // init local - if (command == WAVEGEN_START) { - lS1 = (long)0; - lS2 = (long)mS2_0; - } else { - lS1 = (long)mS1; - lS2 = (long)mS2; - } - lA1 = (long)mA1_Q14; - lAmplitude = (long)mAmplitude_Q15; - - if (command == WAVEGEN_STOP) { - lAmplitude <<= 16; - if (count == 0) { - return; - } - long dec = lAmplitude/count; - // loop generation - while (count--) { - Sample = ((lA1 * lS1) >> S_Q14) - lS2; - // shift delay - lS2 = lS1; - lS1 = Sample; - Sample = ((lAmplitude>>16) * Sample) >> S_Q15; - *(outBuffer++) += (short)Sample; // put result in buffer - lAmplitude -= dec; - } - } else { - // loop generation - while (count--) { - Sample = ((lA1 * lS1) >> S_Q14) - lS2; - // shift delay - lS2 = lS1; - lS1 = Sample; - Sample = (lAmplitude * Sample) >> S_Q15; - *(outBuffer++) += (short)Sample; // put result in buffer - } - } - - // save status - mS1 = (short)lS1; - mS2 = (short)lS2; -} - -} // end namespace android diff --git a/media/libmedia/Visualizer.cpp b/media/libmedia/Visualizer.cpp deleted file mode 100644 index bcd6ae4..0000000 --- a/media/libmedia/Visualizer.cpp +++ /dev/null @@ -1,322 +0,0 @@ -/* -** -** Copyright 2010, 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_NDEBUG 0 -#define LOG_TAG "Visualizer" -#include <utils/Log.h> - -#include <stdint.h> -#include <sys/types.h> -#include <limits.h> - -#include <cutils/bitops.h> - -#include <media/Visualizer.h> -#include <audio_utils/fixedfft.h> - -namespace android { - -// --------------------------------------------------------------------------- - -Visualizer::Visualizer (int32_t priority, - effect_callback_t cbf, - void* user, - int sessionId) - : AudioEffect(SL_IID_VISUALIZATION, NULL, priority, cbf, user, sessionId), - mCaptureRate(CAPTURE_RATE_DEF), - mCaptureSize(CAPTURE_SIZE_DEF), - mSampleRate(44100000), - mCaptureCallBack(NULL), - mCaptureCbkUser(NULL) -{ - initCaptureSize(); -} - -Visualizer::~Visualizer() -{ -} - -status_t Visualizer::setEnabled(bool enabled) -{ - Mutex::Autolock _l(mCaptureLock); - - sp<CaptureThread> t = mCaptureThread; - if (t != 0) { - if (enabled) { - if (t->exitPending()) { - if (t->requestExitAndWait() == WOULD_BLOCK) { - ALOGE("Visualizer::enable() called from thread"); - return INVALID_OPERATION; - } - } - } - t->mLock.lock(); - } - - status_t status = AudioEffect::setEnabled(enabled); - - if (status == NO_ERROR) { - if (t != 0) { - if (enabled) { - t->run("Visualizer"); - } else { - t->requestExit(); - } - } - } - - if (t != 0) { - t->mLock.unlock(); - } - - return status; -} - -status_t Visualizer::setCaptureCallBack(capture_cbk_t cbk, void* user, uint32_t flags, uint32_t rate) -{ - if (rate > CAPTURE_RATE_MAX) { - return BAD_VALUE; - } - Mutex::Autolock _l(mCaptureLock); - - if (mEnabled) { - return INVALID_OPERATION; - } - - sp<CaptureThread> t = mCaptureThread; - if (t != 0) { - t->mLock.lock(); - } - mCaptureThread.clear(); - mCaptureCallBack = cbk; - mCaptureCbkUser = user; - mCaptureFlags = flags; - mCaptureRate = rate; - - if (t != 0) { - t->mLock.unlock(); - } - - if (cbk != NULL) { - mCaptureThread = new CaptureThread(*this, rate, ((flags & CAPTURE_CALL_JAVA) != 0)); - } - ALOGV("setCaptureCallBack() rate: %d thread %p flags 0x%08x", - rate, mCaptureThread.get(), mCaptureFlags); - return NO_ERROR; -} - -status_t Visualizer::setCaptureSize(uint32_t size) -{ - if (size > VISUALIZER_CAPTURE_SIZE_MAX || - size < VISUALIZER_CAPTURE_SIZE_MIN || - popcount(size) != 1) { - return BAD_VALUE; - } - - Mutex::Autolock _l(mCaptureLock); - if (mEnabled) { - return INVALID_OPERATION; - } - - uint32_t buf32[sizeof(effect_param_t) / sizeof(uint32_t) + 2]; - effect_param_t *p = (effect_param_t *)buf32; - - p->psize = sizeof(uint32_t); - p->vsize = sizeof(uint32_t); - *(int32_t *)p->data = VISUALIZER_PARAM_CAPTURE_SIZE; - *((int32_t *)p->data + 1)= size; - status_t status = setParameter(p); - - ALOGV("setCaptureSize size %d status %d p->status %d", size, status, p->status); - - if (status == NO_ERROR) { - status = p->status; - } - if (status == NO_ERROR) { - mCaptureSize = size; - } - - return status; -} - -status_t Visualizer::getWaveForm(uint8_t *waveform) -{ - if (waveform == NULL) { - return BAD_VALUE; - } - if (mCaptureSize == 0) { - return NO_INIT; - } - - status_t status = NO_ERROR; - if (mEnabled) { - uint32_t replySize = mCaptureSize; - status = command(VISUALIZER_CMD_CAPTURE, 0, NULL, &replySize, waveform); - ALOGV("getWaveForm() command returned %d", status); - if ((status == NO_ERROR) && (replySize == 0)) { - status = NOT_ENOUGH_DATA; - } - } else { - ALOGV("getWaveForm() disabled"); - memset(waveform, 0x80, mCaptureSize); - } - return status; -} - -status_t Visualizer::getFft(uint8_t *fft) -{ - if (fft == NULL) { - return BAD_VALUE; - } - if (mCaptureSize == 0) { - return NO_INIT; - } - - status_t status = NO_ERROR; - if (mEnabled) { - uint8_t buf[mCaptureSize]; - status = getWaveForm(buf); - if (status == NO_ERROR) { - status = doFft(fft, buf); - } - } else { - memset(fft, 0, mCaptureSize); - } - return status; -} - -status_t Visualizer::doFft(uint8_t *fft, uint8_t *waveform) -{ - int32_t workspace[mCaptureSize >> 1]; - int32_t nonzero = 0; - - for (uint32_t i = 0; i < mCaptureSize; i += 2) { - workspace[i >> 1] = - ((waveform[i] ^ 0x80) << 24) | ((waveform[i + 1] ^ 0x80) << 8); - nonzero |= workspace[i >> 1]; - } - - if (nonzero) { - fixed_fft_real(mCaptureSize >> 1, workspace); - } - - for (uint32_t i = 0; i < mCaptureSize; i += 2) { - short tmp = workspace[i >> 1] >> 21; - while (tmp > 127 || tmp < -128) tmp >>= 1; - fft[i] = tmp; - tmp = workspace[i >> 1]; - tmp >>= 5; - while (tmp > 127 || tmp < -128) tmp >>= 1; - fft[i + 1] = tmp; - } - - return NO_ERROR; -} - -void Visualizer::periodicCapture() -{ - Mutex::Autolock _l(mCaptureLock); - ALOGV("periodicCapture() %p mCaptureCallBack %p mCaptureFlags 0x%08x", - this, mCaptureCallBack, mCaptureFlags); - if (mCaptureCallBack != NULL && - (mCaptureFlags & (CAPTURE_WAVEFORM|CAPTURE_FFT)) && - mCaptureSize != 0) { - uint8_t waveform[mCaptureSize]; - status_t status = getWaveForm(waveform); - if (status != NO_ERROR) { - return; - } - uint8_t fft[mCaptureSize]; - if (mCaptureFlags & CAPTURE_FFT) { - status = doFft(fft, waveform); - } - if (status != NO_ERROR) { - return; - } - uint8_t *wavePtr = NULL; - uint8_t *fftPtr = NULL; - uint32_t waveSize = 0; - uint32_t fftSize = 0; - if (mCaptureFlags & CAPTURE_WAVEFORM) { - wavePtr = waveform; - waveSize = mCaptureSize; - } - if (mCaptureFlags & CAPTURE_FFT) { - fftPtr = fft; - fftSize = mCaptureSize; - } - mCaptureCallBack(mCaptureCbkUser, waveSize, wavePtr, fftSize, fftPtr, mSampleRate); - } -} - -uint32_t Visualizer::initCaptureSize() -{ - uint32_t buf32[sizeof(effect_param_t) / sizeof(uint32_t) + 2]; - effect_param_t *p = (effect_param_t *)buf32; - - p->psize = sizeof(uint32_t); - p->vsize = sizeof(uint32_t); - *(int32_t *)p->data = VISUALIZER_PARAM_CAPTURE_SIZE; - status_t status = getParameter(p); - - if (status == NO_ERROR) { - status = p->status; - } - - uint32_t size = 0; - if (status == NO_ERROR) { - size = *((int32_t *)p->data + 1); - } - mCaptureSize = size; - - ALOGV("initCaptureSize size %d status %d", mCaptureSize, status); - - return size; -} - -//------------------------------------------------------------------------- - -Visualizer::CaptureThread::CaptureThread(Visualizer& receiver, uint32_t captureRate, bool bCanCallJava) - : Thread(bCanCallJava), mReceiver(receiver) -{ - mSleepTimeUs = 1000000000 / captureRate; - ALOGV("CaptureThread cstor %p captureRate %d mSleepTimeUs %d", this, captureRate, mSleepTimeUs); -} - -bool Visualizer::CaptureThread::threadLoop() -{ - ALOGV("CaptureThread %p enter", this); - while (!exitPending()) - { - usleep(mSleepTimeUs); - mReceiver.periodicCapture(); - } - ALOGV("CaptureThread %p exiting", this); - return false; -} - -status_t Visualizer::CaptureThread::readyToRun() -{ - return NO_ERROR; -} - -void Visualizer::CaptureThread::onFirstRef() -{ -} - -}; // namespace android diff --git a/media/libmedia/autodetect.cpp b/media/libmedia/autodetect.cpp deleted file mode 100644 index be5c3b2..0000000 --- a/media/libmedia/autodetect.cpp +++ /dev/null @@ -1,885 +0,0 @@ -/* - * Copyright (C) 2008 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 "autodetect.h" - -struct CharRange { - uint16_t first; - uint16_t last; -}; - -#define ARRAY_SIZE(x) (sizeof(x) / sizeof(*x)) - -// generated from http://unicode.org/Public/MAPPINGS/VENDORS/MICSFT/WINDOWS/CP932.TXT -static const CharRange kShiftJISRanges[] = { - { 0x8140, 0x817E }, - { 0x8180, 0x81AC }, - { 0x81B8, 0x81BF }, - { 0x81C8, 0x81CE }, - { 0x81DA, 0x81E8 }, - { 0x81F0, 0x81F7 }, - { 0x81FC, 0x81FC }, - { 0x824F, 0x8258 }, - { 0x8260, 0x8279 }, - { 0x8281, 0x829A }, - { 0x829F, 0x82F1 }, - { 0x8340, 0x837E }, - { 0x8380, 0x8396 }, - { 0x839F, 0x83B6 }, - { 0x83BF, 0x83D6 }, - { 0x8440, 0x8460 }, - { 0x8470, 0x847E }, - { 0x8480, 0x8491 }, - { 0x849F, 0x84BE }, - { 0x8740, 0x875D }, - { 0x875F, 0x8775 }, - { 0x877E, 0x877E }, - { 0x8780, 0x879C }, - { 0x889F, 0x88FC }, - { 0x8940, 0x897E }, - { 0x8980, 0x89FC }, - { 0x8A40, 0x8A7E }, - { 0x8A80, 0x8AFC }, - { 0x8B40, 0x8B7E }, - { 0x8B80, 0x8BFC }, - { 0x8C40, 0x8C7E }, - { 0x8C80, 0x8CFC }, - { 0x8D40, 0x8D7E }, - { 0x8D80, 0x8DFC }, - { 0x8E40, 0x8E7E }, - { 0x8E80, 0x8EFC }, - { 0x8F40, 0x8F7E }, - { 0x8F80, 0x8FFC }, - { 0x9040, 0x907E }, - { 0x9080, 0x90FC }, - { 0x9140, 0x917E }, - { 0x9180, 0x91FC }, - { 0x9240, 0x927E }, - { 0x9280, 0x92FC }, - { 0x9340, 0x937E }, - { 0x9380, 0x93FC }, - { 0x9440, 0x947E }, - { 0x9480, 0x94FC }, - { 0x9540, 0x957E }, - { 0x9580, 0x95FC }, - { 0x9640, 0x967E }, - { 0x9680, 0x96FC }, - { 0x9740, 0x977E }, - { 0x9780, 0x97FC }, - { 0x9840, 0x9872 }, - { 0x989F, 0x98FC }, - { 0x9940, 0x997E }, - { 0x9980, 0x99FC }, - { 0x9A40, 0x9A7E }, - { 0x9A80, 0x9AFC }, - { 0x9B40, 0x9B7E }, - { 0x9B80, 0x9BFC }, - { 0x9C40, 0x9C7E }, - { 0x9C80, 0x9CFC }, - { 0x9D40, 0x9D7E }, - { 0x9D80, 0x9DFC }, - { 0x9E40, 0x9E7E }, - { 0x9E80, 0x9EFC }, - { 0x9F40, 0x9F7E }, - { 0x9F80, 0x9FFC }, - { 0xE040, 0xE07E }, - { 0xE080, 0xE0FC }, - { 0xE140, 0xE17E }, - { 0xE180, 0xE1FC }, - { 0xE240, 0xE27E }, - { 0xE280, 0xE2FC }, - { 0xE340, 0xE37E }, - { 0xE380, 0xE3FC }, - { 0xE440, 0xE47E }, - { 0xE480, 0xE4FC }, - { 0xE540, 0xE57E }, - { 0xE580, 0xE5FC }, - { 0xE640, 0xE67E }, - { 0xE680, 0xE6FC }, - { 0xE740, 0xE77E }, - { 0xE780, 0xE7FC }, - { 0xE840, 0xE87E }, - { 0xE880, 0xE8FC }, - { 0xE940, 0xE97E }, - { 0xE980, 0xE9FC }, - { 0xEA40, 0xEA7E }, - { 0xEA80, 0xEAA4 }, - { 0xED40, 0xED7E }, - { 0xED80, 0xEDFC }, - { 0xEE40, 0xEE7E }, - { 0xEE80, 0xEEEC }, - { 0xEEEF, 0xEEFC }, - { 0xFA40, 0xFA7E }, - { 0xFA80, 0xFAFC }, - { 0xFB40, 0xFB7E }, - { 0xFB80, 0xFBFC }, - { 0xFC40, 0xFC4B }, -}; - -// generated from http://unicode.org/Public/MAPPINGS/VENDORS/MICSFT/WINDOWS/CP936.TXT -static const CharRange kGBKRanges[] = { - { 0x8140, 0x817E }, - { 0x8180, 0x81FE }, - { 0x8240, 0x827E }, - { 0x8280, 0x82FE }, - { 0x8340, 0x837E }, - { 0x8380, 0x83FE }, - { 0x8440, 0x847E }, - { 0x8480, 0x84FE }, - { 0x8540, 0x857E }, - { 0x8580, 0x85FE }, - { 0x8640, 0x867E }, - { 0x8680, 0x86FE }, - { 0x8740, 0x877E }, - { 0x8780, 0x87FE }, - { 0x8840, 0x887E }, - { 0x8880, 0x88FE }, - { 0x8940, 0x897E }, - { 0x8980, 0x89FE }, - { 0x8A40, 0x8A7E }, - { 0x8A80, 0x8AFE }, - { 0x8B40, 0x8B7E }, - { 0x8B80, 0x8BFE }, - { 0x8C40, 0x8C7E }, - { 0x8C80, 0x8CFE }, - { 0x8D40, 0x8D7E }, - { 0x8D80, 0x8DFE }, - { 0x8E40, 0x8E7E }, - { 0x8E80, 0x8EFE }, - { 0x8F40, 0x8F7E }, - { 0x8F80, 0x8FFE }, - { 0x9040, 0x907E }, - { 0x9080, 0x90FE }, - { 0x9140, 0x917E }, - { 0x9180, 0x91FE }, - { 0x9240, 0x927E }, - { 0x9280, 0x92FE }, - { 0x9340, 0x937E }, - { 0x9380, 0x93FE }, - { 0x9440, 0x947E }, - { 0x9480, 0x94FE }, - { 0x9540, 0x957E }, - { 0x9580, 0x95FE }, - { 0x9640, 0x967E }, - { 0x9680, 0x96FE }, - { 0x9740, 0x977E }, - { 0x9780, 0x97FE }, - { 0x9840, 0x987E }, - { 0x9880, 0x98FE }, - { 0x9940, 0x997E }, - { 0x9980, 0x99FE }, - { 0x9A40, 0x9A7E }, - { 0x9A80, 0x9AFE }, - { 0x9B40, 0x9B7E }, - { 0x9B80, 0x9BFE }, - { 0x9C40, 0x9C7E }, - { 0x9C80, 0x9CFE }, - { 0x9D40, 0x9D7E }, - { 0x9D80, 0x9DFE }, - { 0x9E40, 0x9E7E }, - { 0x9E80, 0x9EFE }, - { 0x9F40, 0x9F7E }, - { 0x9F80, 0x9FFE }, - { 0xA040, 0xA07E }, - { 0xA080, 0xA0FE }, - { 0xA1A1, 0xA1FE }, - { 0xA2A1, 0xA2AA }, - { 0xA2B1, 0xA2E2 }, - { 0xA2E5, 0xA2EE }, - { 0xA2F1, 0xA2FC }, - { 0xA3A1, 0xA3FE }, - { 0xA4A1, 0xA4F3 }, - { 0xA5A1, 0xA5F6 }, - { 0xA6A1, 0xA6B8 }, - { 0xA6C1, 0xA6D8 }, - { 0xA6E0, 0xA6EB }, - { 0xA6EE, 0xA6F2 }, - { 0xA6F4, 0xA6F5 }, - { 0xA7A1, 0xA7C1 }, - { 0xA7D1, 0xA7F1 }, - { 0xA840, 0xA87E }, - { 0xA880, 0xA895 }, - { 0xA8A1, 0xA8BB }, - { 0xA8BD, 0xA8BE }, - { 0xA8C0, 0xA8C0 }, - { 0xA8C5, 0xA8E9 }, - { 0xA940, 0xA957 }, - { 0xA959, 0xA95A }, - { 0xA95C, 0xA95C }, - { 0xA960, 0xA97E }, - { 0xA980, 0xA988 }, - { 0xA996, 0xA996 }, - { 0xA9A4, 0xA9EF }, - { 0xAA40, 0xAA7E }, - { 0xAA80, 0xAAA0 }, - { 0xAB40, 0xAB7E }, - { 0xAB80, 0xABA0 }, - { 0xAC40, 0xAC7E }, - { 0xAC80, 0xACA0 }, - { 0xAD40, 0xAD7E }, - { 0xAD80, 0xADA0 }, - { 0xAE40, 0xAE7E }, - { 0xAE80, 0xAEA0 }, - { 0xAF40, 0xAF7E }, - { 0xAF80, 0xAFA0 }, - { 0xB040, 0xB07E }, - { 0xB080, 0xB0FE }, - { 0xB140, 0xB17E }, - { 0xB180, 0xB1FE }, - { 0xB240, 0xB27E }, - { 0xB280, 0xB2FE }, - { 0xB340, 0xB37E }, - { 0xB380, 0xB3FE }, - { 0xB440, 0xB47E }, - { 0xB480, 0xB4FE }, - { 0xB540, 0xB57E }, - { 0xB580, 0xB5FE }, - { 0xB640, 0xB67E }, - { 0xB680, 0xB6FE }, - { 0xB740, 0xB77E }, - { 0xB780, 0xB7FE }, - { 0xB840, 0xB87E }, - { 0xB880, 0xB8FE }, - { 0xB940, 0xB97E }, - { 0xB980, 0xB9FE }, - { 0xBA40, 0xBA7E }, - { 0xBA80, 0xBAFE }, - { 0xBB40, 0xBB7E }, - { 0xBB80, 0xBBFE }, - { 0xBC40, 0xBC7E }, - { 0xBC80, 0xBCFE }, - { 0xBD40, 0xBD7E }, - { 0xBD80, 0xBDFE }, - { 0xBE40, 0xBE7E }, - { 0xBE80, 0xBEFE }, - { 0xBF40, 0xBF7E }, - { 0xBF80, 0xBFFE }, - { 0xC040, 0xC07E }, - { 0xC080, 0xC0FE }, - { 0xC140, 0xC17E }, - { 0xC180, 0xC1FE }, - { 0xC240, 0xC27E }, - { 0xC280, 0xC2FE }, - { 0xC340, 0xC37E }, - { 0xC380, 0xC3FE }, - { 0xC440, 0xC47E }, - { 0xC480, 0xC4FE }, - { 0xC540, 0xC57E }, - { 0xC580, 0xC5FE }, - { 0xC640, 0xC67E }, - { 0xC680, 0xC6FE }, - { 0xC740, 0xC77E }, - { 0xC780, 0xC7FE }, - { 0xC840, 0xC87E }, - { 0xC880, 0xC8FE }, - { 0xC940, 0xC97E }, - { 0xC980, 0xC9FE }, - { 0xCA40, 0xCA7E }, - { 0xCA80, 0xCAFE }, - { 0xCB40, 0xCB7E }, - { 0xCB80, 0xCBFE }, - { 0xCC40, 0xCC7E }, - { 0xCC80, 0xCCFE }, - { 0xCD40, 0xCD7E }, - { 0xCD80, 0xCDFE }, - { 0xCE40, 0xCE7E }, - { 0xCE80, 0xCEFE }, - { 0xCF40, 0xCF7E }, - { 0xCF80, 0xCFFE }, - { 0xD040, 0xD07E }, - { 0xD080, 0xD0FE }, - { 0xD140, 0xD17E }, - { 0xD180, 0xD1FE }, - { 0xD240, 0xD27E }, - { 0xD280, 0xD2FE }, - { 0xD340, 0xD37E }, - { 0xD380, 0xD3FE }, - { 0xD440, 0xD47E }, - { 0xD480, 0xD4FE }, - { 0xD540, 0xD57E }, - { 0xD580, 0xD5FE }, - { 0xD640, 0xD67E }, - { 0xD680, 0xD6FE }, - { 0xD740, 0xD77E }, - { 0xD780, 0xD7F9 }, - { 0xD840, 0xD87E }, - { 0xD880, 0xD8FE }, - { 0xD940, 0xD97E }, - { 0xD980, 0xD9FE }, - { 0xDA40, 0xDA7E }, - { 0xDA80, 0xDAFE }, - { 0xDB40, 0xDB7E }, - { 0xDB80, 0xDBFE }, - { 0xDC40, 0xDC7E }, - { 0xDC80, 0xDCFE }, - { 0xDD40, 0xDD7E }, - { 0xDD80, 0xDDFE }, - { 0xDE40, 0xDE7E }, - { 0xDE80, 0xDEFE }, - { 0xDF40, 0xDF7E }, - { 0xDF80, 0xDFFE }, - { 0xE040, 0xE07E }, - { 0xE080, 0xE0FE }, - { 0xE140, 0xE17E }, - { 0xE180, 0xE1FE }, - { 0xE240, 0xE27E }, - { 0xE280, 0xE2FE }, - { 0xE340, 0xE37E }, - { 0xE380, 0xE3FE }, - { 0xE440, 0xE47E }, - { 0xE480, 0xE4FE }, - { 0xE540, 0xE57E }, - { 0xE580, 0xE5FE }, - { 0xE640, 0xE67E }, - { 0xE680, 0xE6FE }, - { 0xE740, 0xE77E }, - { 0xE780, 0xE7FE }, - { 0xE840, 0xE87E }, - { 0xE880, 0xE8FE }, - { 0xE940, 0xE97E }, - { 0xE980, 0xE9FE }, - { 0xEA40, 0xEA7E }, - { 0xEA80, 0xEAFE }, - { 0xEB40, 0xEB7E }, - { 0xEB80, 0xEBFE }, - { 0xEC40, 0xEC7E }, - { 0xEC80, 0xECFE }, - { 0xED40, 0xED7E }, - { 0xED80, 0xEDFE }, - { 0xEE40, 0xEE7E }, - { 0xEE80, 0xEEFE }, - { 0xEF40, 0xEF7E }, - { 0xEF80, 0xEFFE }, - { 0xF040, 0xF07E }, - { 0xF080, 0xF0FE }, - { 0xF140, 0xF17E }, - { 0xF180, 0xF1FE }, - { 0xF240, 0xF27E }, - { 0xF280, 0xF2FE }, - { 0xF340, 0xF37E }, - { 0xF380, 0xF3FE }, - { 0xF440, 0xF47E }, - { 0xF480, 0xF4FE }, - { 0xF540, 0xF57E }, - { 0xF580, 0xF5FE }, - { 0xF640, 0xF67E }, - { 0xF680, 0xF6FE }, - { 0xF740, 0xF77E }, - { 0xF780, 0xF7FE }, - { 0xF840, 0xF87E }, - { 0xF880, 0xF8A0 }, - { 0xF940, 0xF97E }, - { 0xF980, 0xF9A0 }, - { 0xFA40, 0xFA7E }, - { 0xFA80, 0xFAA0 }, - { 0xFB40, 0xFB7E }, - { 0xFB80, 0xFBA0 }, - { 0xFC40, 0xFC7E }, - { 0xFC80, 0xFCA0 }, - { 0xFD40, 0xFD7E }, - { 0xFD80, 0xFDA0 }, - { 0xFE40, 0xFE4F }, -}; - -// generated from http://unicode.org/Public/MAPPINGS/VENDORS/MICSFT/WINDOWS/CP949.TXT -static const CharRange kEUCKRRanges[] = { - { 0x8141, 0x815A }, - { 0x8161, 0x817A }, - { 0x8181, 0x81FE }, - { 0x8241, 0x825A }, - { 0x8261, 0x827A }, - { 0x8281, 0x82FE }, - { 0x8341, 0x835A }, - { 0x8361, 0x837A }, - { 0x8381, 0x83FE }, - { 0x8441, 0x845A }, - { 0x8461, 0x847A }, - { 0x8481, 0x84FE }, - { 0x8541, 0x855A }, - { 0x8561, 0x857A }, - { 0x8581, 0x85FE }, - { 0x8641, 0x865A }, - { 0x8661, 0x867A }, - { 0x8681, 0x86FE }, - { 0x8741, 0x875A }, - { 0x8761, 0x877A }, - { 0x8781, 0x87FE }, - { 0x8841, 0x885A }, - { 0x8861, 0x887A }, - { 0x8881, 0x88FE }, - { 0x8941, 0x895A }, - { 0x8961, 0x897A }, - { 0x8981, 0x89FE }, - { 0x8A41, 0x8A5A }, - { 0x8A61, 0x8A7A }, - { 0x8A81, 0x8AFE }, - { 0x8B41, 0x8B5A }, - { 0x8B61, 0x8B7A }, - { 0x8B81, 0x8BFE }, - { 0x8C41, 0x8C5A }, - { 0x8C61, 0x8C7A }, - { 0x8C81, 0x8CFE }, - { 0x8D41, 0x8D5A }, - { 0x8D61, 0x8D7A }, - { 0x8D81, 0x8DFE }, - { 0x8E41, 0x8E5A }, - { 0x8E61, 0x8E7A }, - { 0x8E81, 0x8EFE }, - { 0x8F41, 0x8F5A }, - { 0x8F61, 0x8F7A }, - { 0x8F81, 0x8FFE }, - { 0x9041, 0x905A }, - { 0x9061, 0x907A }, - { 0x9081, 0x90FE }, - { 0x9141, 0x915A }, - { 0x9161, 0x917A }, - { 0x9181, 0x91FE }, - { 0x9241, 0x925A }, - { 0x9261, 0x927A }, - { 0x9281, 0x92FE }, - { 0x9341, 0x935A }, - { 0x9361, 0x937A }, - { 0x9381, 0x93FE }, - { 0x9441, 0x945A }, - { 0x9461, 0x947A }, - { 0x9481, 0x94FE }, - { 0x9541, 0x955A }, - { 0x9561, 0x957A }, - { 0x9581, 0x95FE }, - { 0x9641, 0x965A }, - { 0x9661, 0x967A }, - { 0x9681, 0x96FE }, - { 0x9741, 0x975A }, - { 0x9761, 0x977A }, - { 0x9781, 0x97FE }, - { 0x9841, 0x985A }, - { 0x9861, 0x987A }, - { 0x9881, 0x98FE }, - { 0x9941, 0x995A }, - { 0x9961, 0x997A }, - { 0x9981, 0x99FE }, - { 0x9A41, 0x9A5A }, - { 0x9A61, 0x9A7A }, - { 0x9A81, 0x9AFE }, - { 0x9B41, 0x9B5A }, - { 0x9B61, 0x9B7A }, - { 0x9B81, 0x9BFE }, - { 0x9C41, 0x9C5A }, - { 0x9C61, 0x9C7A }, - { 0x9C81, 0x9CFE }, - { 0x9D41, 0x9D5A }, - { 0x9D61, 0x9D7A }, - { 0x9D81, 0x9DFE }, - { 0x9E41, 0x9E5A }, - { 0x9E61, 0x9E7A }, - { 0x9E81, 0x9EFE }, - { 0x9F41, 0x9F5A }, - { 0x9F61, 0x9F7A }, - { 0x9F81, 0x9FFE }, - { 0xA041, 0xA05A }, - { 0xA061, 0xA07A }, - { 0xA081, 0xA0FE }, - { 0xA141, 0xA15A }, - { 0xA161, 0xA17A }, - { 0xA181, 0xA1FE }, - { 0xA241, 0xA25A }, - { 0xA261, 0xA27A }, - { 0xA281, 0xA2E7 }, - { 0xA341, 0xA35A }, - { 0xA361, 0xA37A }, - { 0xA381, 0xA3FE }, - { 0xA441, 0xA45A }, - { 0xA461, 0xA47A }, - { 0xA481, 0xA4FE }, - { 0xA541, 0xA55A }, - { 0xA561, 0xA57A }, - { 0xA581, 0xA5AA }, - { 0xA5B0, 0xA5B9 }, - { 0xA5C1, 0xA5D8 }, - { 0xA5E1, 0xA5F8 }, - { 0xA641, 0xA65A }, - { 0xA661, 0xA67A }, - { 0xA681, 0xA6E4 }, - { 0xA741, 0xA75A }, - { 0xA761, 0xA77A }, - { 0xA781, 0xA7EF }, - { 0xA841, 0xA85A }, - { 0xA861, 0xA87A }, - { 0xA881, 0xA8A4 }, - { 0xA8A6, 0xA8A6 }, - { 0xA8A8, 0xA8AF }, - { 0xA8B1, 0xA8FE }, - { 0xA941, 0xA95A }, - { 0xA961, 0xA97A }, - { 0xA981, 0xA9FE }, - { 0xAA41, 0xAA5A }, - { 0xAA61, 0xAA7A }, - { 0xAA81, 0xAAF3 }, - { 0xAB41, 0xAB5A }, - { 0xAB61, 0xAB7A }, - { 0xAB81, 0xABF6 }, - { 0xAC41, 0xAC5A }, - { 0xAC61, 0xAC7A }, - { 0xAC81, 0xACC1 }, - { 0xACD1, 0xACF1 }, - { 0xAD41, 0xAD5A }, - { 0xAD61, 0xAD7A }, - { 0xAD81, 0xADA0 }, - { 0xAE41, 0xAE5A }, - { 0xAE61, 0xAE7A }, - { 0xAE81, 0xAEA0 }, - { 0xAF41, 0xAF5A }, - { 0xAF61, 0xAF7A }, - { 0xAF81, 0xAFA0 }, - { 0xB041, 0xB05A }, - { 0xB061, 0xB07A }, - { 0xB081, 0xB0FE }, - { 0xB141, 0xB15A }, - { 0xB161, 0xB17A }, - { 0xB181, 0xB1FE }, - { 0xB241, 0xB25A }, - { 0xB261, 0xB27A }, - { 0xB281, 0xB2FE }, - { 0xB341, 0xB35A }, - { 0xB361, 0xB37A }, - { 0xB381, 0xB3FE }, - { 0xB441, 0xB45A }, - { 0xB461, 0xB47A }, - { 0xB481, 0xB4FE }, - { 0xB541, 0xB55A }, - { 0xB561, 0xB57A }, - { 0xB581, 0xB5FE }, - { 0xB641, 0xB65A }, - { 0xB661, 0xB67A }, - { 0xB681, 0xB6FE }, - { 0xB741, 0xB75A }, - { 0xB761, 0xB77A }, - { 0xB781, 0xB7FE }, - { 0xB841, 0xB85A }, - { 0xB861, 0xB87A }, - { 0xB881, 0xB8FE }, - { 0xB941, 0xB95A }, - { 0xB961, 0xB97A }, - { 0xB981, 0xB9FE }, - { 0xBA41, 0xBA5A }, - { 0xBA61, 0xBA7A }, - { 0xBA81, 0xBAFE }, - { 0xBB41, 0xBB5A }, - { 0xBB61, 0xBB7A }, - { 0xBB81, 0xBBFE }, - { 0xBC41, 0xBC5A }, - { 0xBC61, 0xBC7A }, - { 0xBC81, 0xBCFE }, - { 0xBD41, 0xBD5A }, - { 0xBD61, 0xBD7A }, - { 0xBD81, 0xBDFE }, - { 0xBE41, 0xBE5A }, - { 0xBE61, 0xBE7A }, - { 0xBE81, 0xBEFE }, - { 0xBF41, 0xBF5A }, - { 0xBF61, 0xBF7A }, - { 0xBF81, 0xBFFE }, - { 0xC041, 0xC05A }, - { 0xC061, 0xC07A }, - { 0xC081, 0xC0FE }, - { 0xC141, 0xC15A }, - { 0xC161, 0xC17A }, - { 0xC181, 0xC1FE }, - { 0xC241, 0xC25A }, - { 0xC261, 0xC27A }, - { 0xC281, 0xC2FE }, - { 0xC341, 0xC35A }, - { 0xC361, 0xC37A }, - { 0xC381, 0xC3FE }, - { 0xC441, 0xC45A }, - { 0xC461, 0xC47A }, - { 0xC481, 0xC4FE }, - { 0xC541, 0xC55A }, - { 0xC561, 0xC57A }, - { 0xC581, 0xC5FE }, - { 0xC641, 0xC652 }, - { 0xC6A1, 0xC6FE }, - { 0xC7A1, 0xC7FE }, - { 0xC8A1, 0xC8FE }, - { 0xCAA1, 0xCAFE }, - { 0xCBA1, 0xCBFE }, - { 0xCCA1, 0xCCFE }, - { 0xCDA1, 0xCDFE }, - { 0xCEA1, 0xCEFE }, - { 0xCFA1, 0xCFFE }, - { 0xD0A1, 0xD0FE }, - { 0xD1A1, 0xD1FE }, - { 0xD2A1, 0xD2FE }, - { 0xD3A1, 0xD3FE }, - { 0xD4A1, 0xD4FE }, - { 0xD5A1, 0xD5FE }, - { 0xD6A1, 0xD6FE }, - { 0xD7A1, 0xD7FE }, - { 0xD8A1, 0xD8FE }, - { 0xD9A1, 0xD9FE }, - { 0xDAA1, 0xDAFE }, - { 0xDBA1, 0xDBFE }, - { 0xDCA1, 0xDCFE }, - { 0xDDA1, 0xDDFE }, - { 0xDEA1, 0xDEFE }, - { 0xDFA1, 0xDFFE }, - { 0xE0A1, 0xE0FE }, - { 0xE1A1, 0xE1FE }, - { 0xE2A1, 0xE2FE }, - { 0xE3A1, 0xE3FE }, - { 0xE4A1, 0xE4FE }, - { 0xE5A1, 0xE5FE }, - { 0xE6A1, 0xE6FE }, - { 0xE7A1, 0xE7FE }, - { 0xE8A1, 0xE8FE }, - { 0xE9A1, 0xE9FE }, - { 0xEAA1, 0xEAFE }, - { 0xEBA1, 0xEBFE }, - { 0xECA1, 0xECFE }, - { 0xEDA1, 0xEDFE }, - { 0xEEA1, 0xEEFE }, - { 0xEFA1, 0xEFFE }, - { 0xF0A1, 0xF0FE }, - { 0xF1A1, 0xF1FE }, - { 0xF2A1, 0xF2FE }, - { 0xF3A1, 0xF3FE }, - { 0xF4A1, 0xF4FE }, - { 0xF5A1, 0xF5FE }, - { 0xF6A1, 0xF6FE }, - { 0xF7A1, 0xF7FE }, - { 0xF8A1, 0xF8FE }, - { 0xF9A1, 0xF9FE }, - { 0xFAA1, 0xFAFE }, - { 0xFBA1, 0xFBFE }, - { 0xFCA1, 0xFCFE }, - { 0xFDA1, 0xFDFE }, -}; - -// generated from http://unicode.org/Public/MAPPINGS/VENDORS/MICSFT/WINDOWS/CP950.TXT -static const CharRange kBig5Ranges[] = { - { 0xA140, 0xA17E }, - { 0xA1A1, 0xA1FE }, - { 0xA240, 0xA27E }, - { 0xA2A1, 0xA2FE }, - { 0xA340, 0xA37E }, - { 0xA3A1, 0xA3BF }, - { 0xA3E1, 0xA3E1 }, - { 0xA440, 0xA47E }, - { 0xA4A1, 0xA4FE }, - { 0xA540, 0xA57E }, - { 0xA5A1, 0xA5FE }, - { 0xA640, 0xA67E }, - { 0xA6A1, 0xA6FE }, - { 0xA740, 0xA77E }, - { 0xA7A1, 0xA7FE }, - { 0xA840, 0xA87E }, - { 0xA8A1, 0xA8FE }, - { 0xA940, 0xA97E }, - { 0xA9A1, 0xA9FE }, - { 0xAA40, 0xAA7E }, - { 0xAAA1, 0xAAFE }, - { 0xAB40, 0xAB7E }, - { 0xABA1, 0xABFE }, - { 0xAC40, 0xAC7E }, - { 0xACA1, 0xACFE }, - { 0xAD40, 0xAD7E }, - { 0xADA1, 0xADFE }, - { 0xAE40, 0xAE7E }, - { 0xAEA1, 0xAEFE }, - { 0xAF40, 0xAF7E }, - { 0xAFA1, 0xAFFE }, - { 0xB040, 0xB07E }, - { 0xB0A1, 0xB0FE }, - { 0xB140, 0xB17E }, - { 0xB1A1, 0xB1FE }, - { 0xB240, 0xB27E }, - { 0xB2A1, 0xB2FE }, - { 0xB340, 0xB37E }, - { 0xB3A1, 0xB3FE }, - { 0xB440, 0xB47E }, - { 0xB4A1, 0xB4FE }, - { 0xB540, 0xB57E }, - { 0xB5A1, 0xB5FE }, - { 0xB640, 0xB67E }, - { 0xB6A1, 0xB6FE }, - { 0xB740, 0xB77E }, - { 0xB7A1, 0xB7FE }, - { 0xB840, 0xB87E }, - { 0xB8A1, 0xB8FE }, - { 0xB940, 0xB97E }, - { 0xB9A1, 0xB9FE }, - { 0xBA40, 0xBA7E }, - { 0xBAA1, 0xBAFE }, - { 0xBB40, 0xBB7E }, - { 0xBBA1, 0xBBFE }, - { 0xBC40, 0xBC7E }, - { 0xBCA1, 0xBCFE }, - { 0xBD40, 0xBD7E }, - { 0xBDA1, 0xBDFE }, - { 0xBE40, 0xBE7E }, - { 0xBEA1, 0xBEFE }, - { 0xBF40, 0xBF7E }, - { 0xBFA1, 0xBFFE }, - { 0xC040, 0xC07E }, - { 0xC0A1, 0xC0FE }, - { 0xC140, 0xC17E }, - { 0xC1A1, 0xC1FE }, - { 0xC240, 0xC27E }, - { 0xC2A1, 0xC2FE }, - { 0xC340, 0xC37E }, - { 0xC3A1, 0xC3FE }, - { 0xC440, 0xC47E }, - { 0xC4A1, 0xC4FE }, - { 0xC540, 0xC57E }, - { 0xC5A1, 0xC5FE }, - { 0xC640, 0xC67E }, - { 0xC940, 0xC97E }, - { 0xC9A1, 0xC9FE }, - { 0xCA40, 0xCA7E }, - { 0xCAA1, 0xCAFE }, - { 0xCB40, 0xCB7E }, - { 0xCBA1, 0xCBFE }, - { 0xCC40, 0xCC7E }, - { 0xCCA1, 0xCCFE }, - { 0xCD40, 0xCD7E }, - { 0xCDA1, 0xCDFE }, - { 0xCE40, 0xCE7E }, - { 0xCEA1, 0xCEFE }, - { 0xCF40, 0xCF7E }, - { 0xCFA1, 0xCFFE }, - { 0xD040, 0xD07E }, - { 0xD0A1, 0xD0FE }, - { 0xD140, 0xD17E }, - { 0xD1A1, 0xD1FE }, - { 0xD240, 0xD27E }, - { 0xD2A1, 0xD2FE }, - { 0xD340, 0xD37E }, - { 0xD3A1, 0xD3FE }, - { 0xD440, 0xD47E }, - { 0xD4A1, 0xD4FE }, - { 0xD540, 0xD57E }, - { 0xD5A1, 0xD5FE }, - { 0xD640, 0xD67E }, - { 0xD6A1, 0xD6FE }, - { 0xD740, 0xD77E }, - { 0xD7A1, 0xD7FE }, - { 0xD840, 0xD87E }, - { 0xD8A1, 0xD8FE }, - { 0xD940, 0xD97E }, - { 0xD9A1, 0xD9FE }, - { 0xDA40, 0xDA7E }, - { 0xDAA1, 0xDAFE }, - { 0xDB40, 0xDB7E }, - { 0xDBA1, 0xDBFE }, - { 0xDC40, 0xDC7E }, - { 0xDCA1, 0xDCFE }, - { 0xDD40, 0xDD7E }, - { 0xDDA1, 0xDDFE }, - { 0xDE40, 0xDE7E }, - { 0xDEA1, 0xDEFE }, - { 0xDF40, 0xDF7E }, - { 0xDFA1, 0xDFFE }, - { 0xE040, 0xE07E }, - { 0xE0A1, 0xE0FE }, - { 0xE140, 0xE17E }, - { 0xE1A1, 0xE1FE }, - { 0xE240, 0xE27E }, - { 0xE2A1, 0xE2FE }, - { 0xE340, 0xE37E }, - { 0xE3A1, 0xE3FE }, - { 0xE440, 0xE47E }, - { 0xE4A1, 0xE4FE }, - { 0xE540, 0xE57E }, - { 0xE5A1, 0xE5FE }, - { 0xE640, 0xE67E }, - { 0xE6A1, 0xE6FE }, - { 0xE740, 0xE77E }, - { 0xE7A1, 0xE7FE }, - { 0xE840, 0xE87E }, - { 0xE8A1, 0xE8FE }, - { 0xE940, 0xE97E }, - { 0xE9A1, 0xE9FE }, - { 0xEA40, 0xEA7E }, - { 0xEAA1, 0xEAFE }, - { 0xEB40, 0xEB7E }, - { 0xEBA1, 0xEBFE }, - { 0xEC40, 0xEC7E }, - { 0xECA1, 0xECFE }, - { 0xED40, 0xED7E }, - { 0xEDA1, 0xEDFE }, - { 0xEE40, 0xEE7E }, - { 0xEEA1, 0xEEFE }, - { 0xEF40, 0xEF7E }, - { 0xEFA1, 0xEFFE }, - { 0xF040, 0xF07E }, - { 0xF0A1, 0xF0FE }, - { 0xF140, 0xF17E }, - { 0xF1A1, 0xF1FE }, - { 0xF240, 0xF27E }, - { 0xF2A1, 0xF2FE }, - { 0xF340, 0xF37E }, - { 0xF3A1, 0xF3FE }, - { 0xF440, 0xF47E }, - { 0xF4A1, 0xF4FE }, - { 0xF540, 0xF57E }, - { 0xF5A1, 0xF5FE }, - { 0xF640, 0xF67E }, - { 0xF6A1, 0xF6FE }, - { 0xF740, 0xF77E }, - { 0xF7A1, 0xF7FE }, - { 0xF840, 0xF87E }, - { 0xF8A1, 0xF8FE }, - { 0xF940, 0xF97E }, - { 0xF9A1, 0xF9FE }, -}; - -static bool charMatchesEncoding(int ch, const CharRange* encodingRanges, int rangeCount) { - // Use binary search to see if the character is contained in the encoding - int low = 0; - int high = rangeCount; - - while (low < high) { - int i = (low + high) / 2; - const CharRange* range = &encodingRanges[i]; - if (ch >= range->first && ch <= range->last) - return true; - if (ch > range->last) - low = i + 1; - else - high = i; - } - - return false; -} - -extern uint32_t findPossibleEncodings(int ch) -{ - // ASCII matches everything - if (ch < 256) return kEncodingAll; - - int result = kEncodingNone; - - if (charMatchesEncoding(ch, kShiftJISRanges, ARRAY_SIZE(kShiftJISRanges))) - result |= kEncodingShiftJIS; - if (charMatchesEncoding(ch, kGBKRanges, ARRAY_SIZE(kGBKRanges))) - result |= kEncodingGBK; - if (charMatchesEncoding(ch, kBig5Ranges, ARRAY_SIZE(kBig5Ranges))) - result |= kEncodingBig5; - if (charMatchesEncoding(ch, kEUCKRRanges, ARRAY_SIZE(kEUCKRRanges))) - result |= kEncodingEUCKR; - - return result; -} diff --git a/media/libmedia/autodetect.h b/media/libmedia/autodetect.h deleted file mode 100644 index 9675db3..0000000 --- a/media/libmedia/autodetect.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright (C) 2008 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 AUTODETECT_H -#define AUTODETECT_H - -#include <inttypes.h> - -// flags used for native encoding detection -enum { - kEncodingNone = 0, - kEncodingShiftJIS = (1 << 0), - kEncodingGBK = (1 << 1), - kEncodingBig5 = (1 << 2), - kEncodingEUCKR = (1 << 3), - - kEncodingAll = (kEncodingShiftJIS | kEncodingGBK | kEncodingBig5 | kEncodingEUCKR), -}; - - -// returns a bitfield containing the possible native encodings for the given character -extern uint32_t findPossibleEncodings(int ch); - -#endif // AUTODETECT_H diff --git a/media/libmedia/mediametadataretriever.cpp b/media/libmedia/mediametadataretriever.cpp deleted file mode 100644 index b0241aa..0000000 --- a/media/libmedia/mediametadataretriever.cpp +++ /dev/null @@ -1,174 +0,0 @@ -/* -** -** Copyright 2008, 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_NDEBUG 0 -#define LOG_TAG "MediaMetadataRetriever" - -#include <binder/IServiceManager.h> -#include <binder/IPCThreadState.h> -#include <media/mediametadataretriever.h> -#include <media/IMediaPlayerService.h> -#include <utils/Log.h> -#include <dlfcn.h> - -namespace android { - -// client singleton for binder interface to service -Mutex MediaMetadataRetriever::sServiceLock; -sp<IMediaPlayerService> MediaMetadataRetriever::sService; -sp<MediaMetadataRetriever::DeathNotifier> MediaMetadataRetriever::sDeathNotifier; - -const sp<IMediaPlayerService>& MediaMetadataRetriever::getService() -{ - Mutex::Autolock lock(sServiceLock); - if (sService == 0) { - sp<IServiceManager> sm = defaultServiceManager(); - sp<IBinder> binder; - do { - binder = sm->getService(String16("media.player")); - if (binder != 0) { - break; - } - ALOGW("MediaPlayerService not published, waiting..."); - usleep(500000); // 0.5 s - } while (true); - if (sDeathNotifier == NULL) { - sDeathNotifier = new DeathNotifier(); - } - binder->linkToDeath(sDeathNotifier); - sService = interface_cast<IMediaPlayerService>(binder); - } - ALOGE_IF(sService == 0, "no MediaPlayerService!?"); - return sService; -} - -MediaMetadataRetriever::MediaMetadataRetriever() -{ - ALOGV("constructor"); - const sp<IMediaPlayerService>& service(getService()); - if (service == 0) { - ALOGE("failed to obtain MediaMetadataRetrieverService"); - return; - } - sp<IMediaMetadataRetriever> retriever(service->createMetadataRetriever(getpid())); - if (retriever == 0) { - ALOGE("failed to create IMediaMetadataRetriever object from server"); - } - mRetriever = retriever; -} - -MediaMetadataRetriever::~MediaMetadataRetriever() -{ - ALOGV("destructor"); - disconnect(); - IPCThreadState::self()->flushCommands(); -} - -void MediaMetadataRetriever::disconnect() -{ - ALOGV("disconnect"); - sp<IMediaMetadataRetriever> retriever; - { - Mutex::Autolock _l(mLock); - retriever = mRetriever; - mRetriever.clear(); - } - if (retriever != 0) { - retriever->disconnect(); - } -} - -status_t MediaMetadataRetriever::setDataSource( - const char *srcUrl, const KeyedVector<String8, String8> *headers) -{ - ALOGV("setDataSource"); - Mutex::Autolock _l(mLock); - if (mRetriever == 0) { - ALOGE("retriever is not initialized"); - return INVALID_OPERATION; - } - if (srcUrl == NULL) { - ALOGE("data source is a null pointer"); - return UNKNOWN_ERROR; - } - ALOGV("data source (%s)", srcUrl); - return mRetriever->setDataSource(srcUrl, headers); -} - -status_t MediaMetadataRetriever::setDataSource(int fd, int64_t offset, int64_t length) -{ - ALOGV("setDataSource(%d, %lld, %lld)", fd, offset, length); - Mutex::Autolock _l(mLock); - if (mRetriever == 0) { - ALOGE("retriever is not initialized"); - return INVALID_OPERATION; - } - if (fd < 0 || offset < 0 || length < 0) { - ALOGE("Invalid negative argument"); - return UNKNOWN_ERROR; - } - return mRetriever->setDataSource(fd, offset, length); -} - -sp<IMemory> MediaMetadataRetriever::getFrameAtTime(int64_t timeUs, int option) -{ - ALOGV("getFrameAtTime: time(%lld us) option(%d)", timeUs, option); - Mutex::Autolock _l(mLock); - if (mRetriever == 0) { - ALOGE("retriever is not initialized"); - return NULL; - } - return mRetriever->getFrameAtTime(timeUs, option); -} - -const char* MediaMetadataRetriever::extractMetadata(int keyCode) -{ - ALOGV("extractMetadata(%d)", keyCode); - Mutex::Autolock _l(mLock); - if (mRetriever == 0) { - ALOGE("retriever is not initialized"); - return NULL; - } - return mRetriever->extractMetadata(keyCode); -} - -sp<IMemory> MediaMetadataRetriever::extractAlbumArt() -{ - ALOGV("extractAlbumArt"); - Mutex::Autolock _l(mLock); - if (mRetriever == 0) { - ALOGE("retriever is not initialized"); - return NULL; - } - return mRetriever->extractAlbumArt(); -} - -void MediaMetadataRetriever::DeathNotifier::binderDied(const wp<IBinder>& who) { - Mutex::Autolock lock(MediaMetadataRetriever::sServiceLock); - MediaMetadataRetriever::sService.clear(); - ALOGW("MediaMetadataRetriever server died!"); -} - -MediaMetadataRetriever::DeathNotifier::~DeathNotifier() -{ - Mutex::Autolock lock(sServiceLock); - if (sService != 0) { - sService->asBinder()->unlinkToDeath(this); - } -} - -}; // namespace android diff --git a/media/libmedia/mediaplayer.cpp b/media/libmedia/mediaplayer.cpp deleted file mode 100644 index b52a37d..0000000 --- a/media/libmedia/mediaplayer.cpp +++ /dev/null @@ -1,798 +0,0 @@ -/* -** -** Copyright 2006, 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_NDEBUG 0 -#define LOG_TAG "MediaPlayer" -#include <utils/Log.h> - -#include <sys/types.h> -#include <sys/stat.h> -#include <unistd.h> -#include <fcntl.h> - -#include <binder/IServiceManager.h> -#include <binder/IPCThreadState.h> - -#include <gui/SurfaceTextureClient.h> - -#include <media/mediaplayer.h> -#include <media/AudioSystem.h> - -#include <binder/MemoryBase.h> - -#include <utils/KeyedVector.h> -#include <utils/String8.h> - -#include <system/audio.h> -#include <system/window.h> - -namespace android { - -MediaPlayer::MediaPlayer() -{ - ALOGV("constructor"); - mListener = NULL; - mCookie = NULL; - mDuration = -1; - mStreamType = AUDIO_STREAM_MUSIC; - mCurrentPosition = -1; - mSeekPosition = -1; - mCurrentState = MEDIA_PLAYER_IDLE; - mPrepareSync = false; - mPrepareStatus = NO_ERROR; - mLoop = false; - mLeftVolume = mRightVolume = 1.0; - mVideoWidth = mVideoHeight = 0; - mLockThreadId = 0; - mAudioSessionId = AudioSystem::newAudioSessionId(); - AudioSystem::acquireAudioSessionId(mAudioSessionId); - mSendLevel = 0; - mRetransmitEndpointValid = false; -} - -MediaPlayer::~MediaPlayer() -{ - ALOGV("destructor"); - AudioSystem::releaseAudioSessionId(mAudioSessionId); - disconnect(); - IPCThreadState::self()->flushCommands(); -} - -void MediaPlayer::disconnect() -{ - ALOGV("disconnect"); - sp<IMediaPlayer> p; - { - Mutex::Autolock _l(mLock); - p = mPlayer; - mPlayer.clear(); - } - - if (p != 0) { - p->disconnect(); - } -} - -// always call with lock held -void MediaPlayer::clear_l() -{ - mDuration = -1; - mCurrentPosition = -1; - mSeekPosition = -1; - mVideoWidth = mVideoHeight = 0; - mRetransmitEndpointValid = false; -} - -status_t MediaPlayer::setListener(const sp<MediaPlayerListener>& listener) -{ - ALOGV("setListener"); - Mutex::Autolock _l(mLock); - mListener = listener; - return NO_ERROR; -} - - -status_t MediaPlayer::attachNewPlayer(const sp<IMediaPlayer>& player) -{ - status_t err = UNKNOWN_ERROR; - sp<IMediaPlayer> p; - { // scope for the lock - Mutex::Autolock _l(mLock); - - if ( !( (mCurrentState & MEDIA_PLAYER_IDLE) || - (mCurrentState == MEDIA_PLAYER_STATE_ERROR ) ) ) { - ALOGE("attachNewPlayer called in state %d", mCurrentState); - return INVALID_OPERATION; - } - - clear_l(); - p = mPlayer; - mPlayer = player; - if (player != 0) { - mCurrentState = MEDIA_PLAYER_INITIALIZED; - err = NO_ERROR; - } else { - ALOGE("Unable to to create media player"); - } - } - - if (p != 0) { - p->disconnect(); - } - - return err; -} - -status_t MediaPlayer::setDataSource( - const char *url, const KeyedVector<String8, String8> *headers) -{ - ALOGV("setDataSource(%s)", url); - status_t err = BAD_VALUE; - if (url != NULL) { - const sp<IMediaPlayerService>& service(getMediaPlayerService()); - if (service != 0) { - sp<IMediaPlayer> player(service->create(getpid(), this, mAudioSessionId)); - if ((NO_ERROR != doSetRetransmitEndpoint(player)) || - (NO_ERROR != player->setDataSource(url, headers))) { - player.clear(); - } - err = attachNewPlayer(player); - } - } - return err; -} - -status_t MediaPlayer::setDataSource(int fd, int64_t offset, int64_t length) -{ - ALOGV("setDataSource(%d, %lld, %lld)", fd, offset, length); - status_t err = UNKNOWN_ERROR; - const sp<IMediaPlayerService>& service(getMediaPlayerService()); - if (service != 0) { - sp<IMediaPlayer> player(service->create(getpid(), this, mAudioSessionId)); - if ((NO_ERROR != doSetRetransmitEndpoint(player)) || - (NO_ERROR != player->setDataSource(fd, offset, length))) { - player.clear(); - } - err = attachNewPlayer(player); - } - return err; -} - -status_t MediaPlayer::setDataSource(const sp<IStreamSource> &source) -{ - ALOGV("setDataSource"); - status_t err = UNKNOWN_ERROR; - const sp<IMediaPlayerService>& service(getMediaPlayerService()); - if (service != 0) { - sp<IMediaPlayer> player(service->create(getpid(), this, mAudioSessionId)); - if ((NO_ERROR != doSetRetransmitEndpoint(player)) || - (NO_ERROR != player->setDataSource(source))) { - player.clear(); - } - err = attachNewPlayer(player); - } - return err; -} - -status_t MediaPlayer::invoke(const Parcel& request, Parcel *reply) -{ - Mutex::Autolock _l(mLock); - const bool hasBeenInitialized = - (mCurrentState != MEDIA_PLAYER_STATE_ERROR) && - ((mCurrentState & MEDIA_PLAYER_IDLE) != MEDIA_PLAYER_IDLE); - if ((mPlayer != NULL) && hasBeenInitialized) { - ALOGV("invoke %d", request.dataSize()); - return mPlayer->invoke(request, reply); - } - ALOGE("invoke failed: wrong state %X", mCurrentState); - return INVALID_OPERATION; -} - -status_t MediaPlayer::setMetadataFilter(const Parcel& filter) -{ - ALOGD("setMetadataFilter"); - Mutex::Autolock lock(mLock); - if (mPlayer == NULL) { - return NO_INIT; - } - return mPlayer->setMetadataFilter(filter); -} - -status_t MediaPlayer::getMetadata(bool update_only, bool apply_filter, Parcel *metadata) -{ - ALOGD("getMetadata"); - Mutex::Autolock lock(mLock); - if (mPlayer == NULL) { - return NO_INIT; - } - return mPlayer->getMetadata(update_only, apply_filter, metadata); -} - -status_t MediaPlayer::setVideoSurfaceTexture( - const sp<ISurfaceTexture>& surfaceTexture) -{ - ALOGV("setVideoSurfaceTexture"); - Mutex::Autolock _l(mLock); - if (mPlayer == 0) return NO_INIT; - return mPlayer->setVideoSurfaceTexture(surfaceTexture); -} - -// must call with lock held -status_t MediaPlayer::prepareAsync_l() -{ - if ( (mPlayer != 0) && ( mCurrentState & ( MEDIA_PLAYER_INITIALIZED | MEDIA_PLAYER_STOPPED) ) ) { - mPlayer->setAudioStreamType(mStreamType); - mCurrentState = MEDIA_PLAYER_PREPARING; - return mPlayer->prepareAsync(); - } - ALOGE("prepareAsync called in state %d", mCurrentState); - return INVALID_OPERATION; -} - -// TODO: In case of error, prepareAsync provides the caller with 2 error codes, -// one defined in the Android framework and one provided by the implementation -// that generated the error. The sync version of prepare returns only 1 error -// code. -status_t MediaPlayer::prepare() -{ - ALOGV("prepare"); - Mutex::Autolock _l(mLock); - mLockThreadId = getThreadId(); - if (mPrepareSync) { - mLockThreadId = 0; - return -EALREADY; - } - mPrepareSync = true; - status_t ret = prepareAsync_l(); - if (ret != NO_ERROR) { - mLockThreadId = 0; - return ret; - } - - if (mPrepareSync) { - mSignal.wait(mLock); // wait for prepare done - mPrepareSync = false; - } - ALOGV("prepare complete - status=%d", mPrepareStatus); - mLockThreadId = 0; - return mPrepareStatus; -} - -status_t MediaPlayer::prepareAsync() -{ - ALOGV("prepareAsync"); - Mutex::Autolock _l(mLock); - return prepareAsync_l(); -} - -status_t MediaPlayer::start() -{ - ALOGV("start"); - Mutex::Autolock _l(mLock); - if (mCurrentState & MEDIA_PLAYER_STARTED) - return NO_ERROR; - if ( (mPlayer != 0) && ( mCurrentState & ( MEDIA_PLAYER_PREPARED | - MEDIA_PLAYER_PLAYBACK_COMPLETE | MEDIA_PLAYER_PAUSED ) ) ) { - mPlayer->setLooping(mLoop); - mPlayer->setVolume(mLeftVolume, mRightVolume); - mPlayer->setAuxEffectSendLevel(mSendLevel); - mCurrentState = MEDIA_PLAYER_STARTED; - status_t ret = mPlayer->start(); - if (ret != NO_ERROR) { - mCurrentState = MEDIA_PLAYER_STATE_ERROR; - } else { - if (mCurrentState == MEDIA_PLAYER_PLAYBACK_COMPLETE) { - ALOGV("playback completed immediately following start()"); - } - } - return ret; - } - ALOGE("start called in state %d", mCurrentState); - return INVALID_OPERATION; -} - -status_t MediaPlayer::stop() -{ - ALOGV("stop"); - Mutex::Autolock _l(mLock); - if (mCurrentState & MEDIA_PLAYER_STOPPED) return NO_ERROR; - if ( (mPlayer != 0) && ( mCurrentState & ( MEDIA_PLAYER_STARTED | MEDIA_PLAYER_PREPARED | - MEDIA_PLAYER_PAUSED | MEDIA_PLAYER_PLAYBACK_COMPLETE ) ) ) { - status_t ret = mPlayer->stop(); - if (ret != NO_ERROR) { - mCurrentState = MEDIA_PLAYER_STATE_ERROR; - } else { - mCurrentState = MEDIA_PLAYER_STOPPED; - } - return ret; - } - ALOGE("stop called in state %d", mCurrentState); - return INVALID_OPERATION; -} - -status_t MediaPlayer::pause() -{ - ALOGV("pause"); - Mutex::Autolock _l(mLock); - if (mCurrentState & (MEDIA_PLAYER_PAUSED|MEDIA_PLAYER_PLAYBACK_COMPLETE)) - return NO_ERROR; - if ((mPlayer != 0) && (mCurrentState & MEDIA_PLAYER_STARTED)) { - status_t ret = mPlayer->pause(); - if (ret != NO_ERROR) { - mCurrentState = MEDIA_PLAYER_STATE_ERROR; - } else { - mCurrentState = MEDIA_PLAYER_PAUSED; - } - return ret; - } - ALOGE("pause called in state %d", mCurrentState); - return INVALID_OPERATION; -} - -bool MediaPlayer::isPlaying() -{ - Mutex::Autolock _l(mLock); - if (mPlayer != 0) { - bool temp = false; - mPlayer->isPlaying(&temp); - ALOGV("isPlaying: %d", temp); - if ((mCurrentState & MEDIA_PLAYER_STARTED) && ! temp) { - ALOGE("internal/external state mismatch corrected"); - mCurrentState = MEDIA_PLAYER_PAUSED; - } - return temp; - } - ALOGV("isPlaying: no active player"); - return false; -} - -status_t MediaPlayer::getVideoWidth(int *w) -{ - ALOGV("getVideoWidth"); - Mutex::Autolock _l(mLock); - if (mPlayer == 0) return INVALID_OPERATION; - *w = mVideoWidth; - return NO_ERROR; -} - -status_t MediaPlayer::getVideoHeight(int *h) -{ - ALOGV("getVideoHeight"); - Mutex::Autolock _l(mLock); - if (mPlayer == 0) return INVALID_OPERATION; - *h = mVideoHeight; - return NO_ERROR; -} - -status_t MediaPlayer::getCurrentPosition(int *msec) -{ - ALOGV("getCurrentPosition"); - Mutex::Autolock _l(mLock); - if (mPlayer != 0) { - if (mCurrentPosition >= 0) { - ALOGV("Using cached seek position: %d", mCurrentPosition); - *msec = mCurrentPosition; - return NO_ERROR; - } - return mPlayer->getCurrentPosition(msec); - } - return INVALID_OPERATION; -} - -status_t MediaPlayer::getDuration_l(int *msec) -{ - ALOGV("getDuration"); - bool isValidState = (mCurrentState & (MEDIA_PLAYER_PREPARED | MEDIA_PLAYER_STARTED | MEDIA_PLAYER_PAUSED | MEDIA_PLAYER_STOPPED | MEDIA_PLAYER_PLAYBACK_COMPLETE)); - if (mPlayer != 0 && isValidState) { - status_t ret = NO_ERROR; - if (mDuration <= 0) - ret = mPlayer->getDuration(&mDuration); - if (msec) - *msec = mDuration; - return ret; - } - ALOGE("Attempt to call getDuration without a valid mediaplayer"); - return INVALID_OPERATION; -} - -status_t MediaPlayer::getDuration(int *msec) -{ - Mutex::Autolock _l(mLock); - return getDuration_l(msec); -} - -status_t MediaPlayer::seekTo_l(int msec) -{ - ALOGV("seekTo %d", msec); - if ((mPlayer != 0) && ( mCurrentState & ( MEDIA_PLAYER_STARTED | MEDIA_PLAYER_PREPARED | MEDIA_PLAYER_PAUSED | MEDIA_PLAYER_PLAYBACK_COMPLETE) ) ) { - if ( msec < 0 ) { - ALOGW("Attempt to seek to invalid position: %d", msec); - msec = 0; - } else if ((mDuration > 0) && (msec > mDuration)) { - ALOGW("Attempt to seek to past end of file: request = %d, EOF = %d", msec, mDuration); - msec = mDuration; - } - // cache duration - mCurrentPosition = msec; - if (mSeekPosition < 0) { - getDuration_l(NULL); - mSeekPosition = msec; - return mPlayer->seekTo(msec); - } - else { - ALOGV("Seek in progress - queue up seekTo[%d]", msec); - return NO_ERROR; - } - } - ALOGE("Attempt to perform seekTo in wrong state: mPlayer=%p, mCurrentState=%u", mPlayer.get(), mCurrentState); - return INVALID_OPERATION; -} - -status_t MediaPlayer::seekTo(int msec) -{ - mLockThreadId = getThreadId(); - Mutex::Autolock _l(mLock); - status_t result = seekTo_l(msec); - mLockThreadId = 0; - - return result; -} - -status_t MediaPlayer::reset_l() -{ - mLoop = false; - if (mCurrentState == MEDIA_PLAYER_IDLE) return NO_ERROR; - mPrepareSync = false; - if (mPlayer != 0) { - status_t ret = mPlayer->reset(); - if (ret != NO_ERROR) { - ALOGE("reset() failed with return code (%d)", ret); - mCurrentState = MEDIA_PLAYER_STATE_ERROR; - } else { - mCurrentState = MEDIA_PLAYER_IDLE; - } - // setDataSource has to be called again to create a - // new mediaplayer. - mPlayer = 0; - return ret; - } - clear_l(); - return NO_ERROR; -} - -status_t MediaPlayer::doSetRetransmitEndpoint(const sp<IMediaPlayer>& player) { - Mutex::Autolock _l(mLock); - - if (player == NULL) { - return UNKNOWN_ERROR; - } - - if (mRetransmitEndpointValid) { - return player->setRetransmitEndpoint(&mRetransmitEndpoint); - } - - return OK; -} - -status_t MediaPlayer::reset() -{ - ALOGV("reset"); - Mutex::Autolock _l(mLock); - return reset_l(); -} - -status_t MediaPlayer::setAudioStreamType(audio_stream_type_t type) -{ - ALOGV("MediaPlayer::setAudioStreamType"); - Mutex::Autolock _l(mLock); - if (mStreamType == type) return NO_ERROR; - if (mCurrentState & ( MEDIA_PLAYER_PREPARED | MEDIA_PLAYER_STARTED | - MEDIA_PLAYER_PAUSED | MEDIA_PLAYER_PLAYBACK_COMPLETE ) ) { - // Can't change the stream type after prepare - ALOGE("setAudioStream called in state %d", mCurrentState); - return INVALID_OPERATION; - } - // cache - mStreamType = type; - return OK; -} - -status_t MediaPlayer::setLooping(int loop) -{ - ALOGV("MediaPlayer::setLooping"); - Mutex::Autolock _l(mLock); - mLoop = (loop != 0); - if (mPlayer != 0) { - return mPlayer->setLooping(loop); - } - return OK; -} - -bool MediaPlayer::isLooping() { - ALOGV("isLooping"); - Mutex::Autolock _l(mLock); - if (mPlayer != 0) { - return mLoop; - } - ALOGV("isLooping: no active player"); - return false; -} - -status_t MediaPlayer::setVolume(float leftVolume, float rightVolume) -{ - ALOGV("MediaPlayer::setVolume(%f, %f)", leftVolume, rightVolume); - Mutex::Autolock _l(mLock); - mLeftVolume = leftVolume; - mRightVolume = rightVolume; - if (mPlayer != 0) { - return mPlayer->setVolume(leftVolume, rightVolume); - } - return OK; -} - -status_t MediaPlayer::setAudioSessionId(int sessionId) -{ - ALOGV("MediaPlayer::setAudioSessionId(%d)", sessionId); - Mutex::Autolock _l(mLock); - if (!(mCurrentState & MEDIA_PLAYER_IDLE)) { - ALOGE("setAudioSessionId called in state %d", mCurrentState); - return INVALID_OPERATION; - } - if (sessionId < 0) { - return BAD_VALUE; - } - if (sessionId != mAudioSessionId) { - AudioSystem::releaseAudioSessionId(mAudioSessionId); - AudioSystem::acquireAudioSessionId(sessionId); - mAudioSessionId = sessionId; - } - return NO_ERROR; -} - -int MediaPlayer::getAudioSessionId() -{ - Mutex::Autolock _l(mLock); - return mAudioSessionId; -} - -status_t MediaPlayer::setAuxEffectSendLevel(float level) -{ - ALOGV("MediaPlayer::setAuxEffectSendLevel(%f)", level); - Mutex::Autolock _l(mLock); - mSendLevel = level; - if (mPlayer != 0) { - return mPlayer->setAuxEffectSendLevel(level); - } - return OK; -} - -status_t MediaPlayer::attachAuxEffect(int effectId) -{ - ALOGV("MediaPlayer::attachAuxEffect(%d)", effectId); - Mutex::Autolock _l(mLock); - if (mPlayer == 0 || - (mCurrentState & MEDIA_PLAYER_IDLE) || - (mCurrentState == MEDIA_PLAYER_STATE_ERROR )) { - ALOGE("attachAuxEffect called in state %d", mCurrentState); - return INVALID_OPERATION; - } - - return mPlayer->attachAuxEffect(effectId); -} - -status_t MediaPlayer::setParameter(int key, const Parcel& request) -{ - ALOGV("MediaPlayer::setParameter(%d)", key); - Mutex::Autolock _l(mLock); - if (mPlayer != NULL) { - return mPlayer->setParameter(key, request); - } - ALOGV("setParameter: no active player"); - return INVALID_OPERATION; -} - -status_t MediaPlayer::getParameter(int key, Parcel *reply) -{ - ALOGV("MediaPlayer::getParameter(%d)", key); - Mutex::Autolock _l(mLock); - if (mPlayer != NULL) { - return mPlayer->getParameter(key, reply); - } - ALOGV("getParameter: no active player"); - return INVALID_OPERATION; -} - -status_t MediaPlayer::setRetransmitEndpoint(const char* addrString, - uint16_t port) { - ALOGV("MediaPlayer::setRetransmitEndpoint(%s:%hu)", - addrString ? addrString : "(null)", port); - - Mutex::Autolock _l(mLock); - if ((mPlayer != NULL) || (mCurrentState != MEDIA_PLAYER_IDLE)) - return INVALID_OPERATION; - - if (NULL == addrString) { - mRetransmitEndpointValid = false; - return OK; - } - - struct in_addr saddr; - if(!inet_aton(addrString, &saddr)) { - return BAD_VALUE; - } - - memset(&mRetransmitEndpoint, 0, sizeof(&mRetransmitEndpoint)); - mRetransmitEndpoint.sin_family = AF_INET; - mRetransmitEndpoint.sin_addr = saddr; - mRetransmitEndpoint.sin_port = htons(port); - mRetransmitEndpointValid = true; - - return OK; -} - -void MediaPlayer::notify(int msg, int ext1, int ext2, const Parcel *obj) -{ - ALOGV("message received msg=%d, ext1=%d, ext2=%d", msg, ext1, ext2); - bool send = true; - bool locked = false; - - // TODO: In the future, we might be on the same thread if the app is - // running in the same process as the media server. In that case, - // this will deadlock. - // - // The threadId hack below works around this for the care of prepare - // and seekTo within the same process. - // FIXME: Remember, this is a hack, it's not even a hack that is applied - // consistently for all use-cases, this needs to be revisited. - if (mLockThreadId != getThreadId()) { - mLock.lock(); - locked = true; - } - - // Allows calls from JNI in idle state to notify errors - if (!(msg == MEDIA_ERROR && mCurrentState == MEDIA_PLAYER_IDLE) && mPlayer == 0) { - ALOGV("notify(%d, %d, %d) callback on disconnected mediaplayer", msg, ext1, ext2); - if (locked) mLock.unlock(); // release the lock when done. - return; - } - - switch (msg) { - case MEDIA_NOP: // interface test message - break; - case MEDIA_PREPARED: - ALOGV("prepared"); - mCurrentState = MEDIA_PLAYER_PREPARED; - if (mPrepareSync) { - ALOGV("signal application thread"); - mPrepareSync = false; - mPrepareStatus = NO_ERROR; - mSignal.signal(); - } - break; - case MEDIA_PLAYBACK_COMPLETE: - ALOGV("playback complete"); - if (mCurrentState == MEDIA_PLAYER_IDLE) { - ALOGE("playback complete in idle state"); - } - if (!mLoop) { - mCurrentState = MEDIA_PLAYER_PLAYBACK_COMPLETE; - } - break; - case MEDIA_ERROR: - // Always log errors. - // ext1: Media framework error code. - // ext2: Implementation dependant error code. - ALOGE("error (%d, %d)", ext1, ext2); - mCurrentState = MEDIA_PLAYER_STATE_ERROR; - if (mPrepareSync) - { - ALOGV("signal application thread"); - mPrepareSync = false; - mPrepareStatus = ext1; - mSignal.signal(); - send = false; - } - break; - case MEDIA_INFO: - // ext1: Media framework error code. - // ext2: Implementation dependant error code. - if (ext1 != MEDIA_INFO_VIDEO_TRACK_LAGGING) { - ALOGW("info/warning (%d, %d)", ext1, ext2); - } - break; - case MEDIA_SEEK_COMPLETE: - ALOGV("Received seek complete"); - if (mSeekPosition != mCurrentPosition) { - ALOGV("Executing queued seekTo(%d)", mSeekPosition); - mSeekPosition = -1; - seekTo_l(mCurrentPosition); - } - else { - ALOGV("All seeks complete - return to regularly scheduled program"); - mCurrentPosition = mSeekPosition = -1; - } - break; - case MEDIA_BUFFERING_UPDATE: - ALOGV("buffering %d", ext1); - break; - case MEDIA_SET_VIDEO_SIZE: - ALOGV("New video size %d x %d", ext1, ext2); - mVideoWidth = ext1; - mVideoHeight = ext2; - break; - case MEDIA_TIMED_TEXT: - ALOGV("Received timed text message"); - break; - default: - ALOGV("unrecognized message: (%d, %d, %d)", msg, ext1, ext2); - break; - } - - sp<MediaPlayerListener> listener = mListener; - if (locked) mLock.unlock(); - - // this prevents re-entrant calls into client code - if ((listener != 0) && send) { - Mutex::Autolock _l(mNotifyLock); - ALOGV("callback application"); - listener->notify(msg, ext1, ext2, obj); - ALOGV("back from callback"); - } -} - -/*static*/ sp<IMemory> MediaPlayer::decode(const char* url, uint32_t *pSampleRate, int* pNumChannels, audio_format_t* pFormat) -{ - ALOGV("decode(%s)", url); - sp<IMemory> p; - const sp<IMediaPlayerService>& service = getMediaPlayerService(); - if (service != 0) { - p = service->decode(url, pSampleRate, pNumChannels, pFormat); - } else { - ALOGE("Unable to locate media service"); - } - return p; - -} - -void MediaPlayer::died() -{ - ALOGV("died"); - notify(MEDIA_ERROR, MEDIA_ERROR_SERVER_DIED, 0); -} - -/*static*/ sp<IMemory> MediaPlayer::decode(int fd, int64_t offset, int64_t length, uint32_t *pSampleRate, int* pNumChannels, audio_format_t* pFormat) -{ - ALOGV("decode(%d, %lld, %lld)", fd, offset, length); - sp<IMemory> p; - const sp<IMediaPlayerService>& service = getMediaPlayerService(); - if (service != 0) { - p = service->decode(fd, offset, length, pSampleRate, pNumChannels, pFormat); - } else { - ALOGE("Unable to locate media service"); - } - return p; - -} - -status_t MediaPlayer::setNextMediaPlayer(const sp<MediaPlayer>& next) { - if (mPlayer == NULL) { - return NO_INIT; - } - return mPlayer->setNextPlayer(next == NULL ? NULL : next->mPlayer); -} - -}; // namespace android diff --git a/media/libmedia/mediarecorder.cpp b/media/libmedia/mediarecorder.cpp deleted file mode 100644 index 9541015..0000000 --- a/media/libmedia/mediarecorder.cpp +++ /dev/null @@ -1,682 +0,0 @@ -/* - ** - ** Copyright (c) 2008 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_NDEBUG 0 -#define LOG_TAG "MediaRecorder" -#include <utils/Log.h> -#include <media/mediarecorder.h> -#include <binder/IServiceManager.h> -#include <utils/String8.h> -#include <media/IMediaPlayerService.h> -#include <media/IMediaRecorder.h> -#include <media/mediaplayer.h> // for MEDIA_ERROR_SERVER_DIED -#include <gui/ISurfaceTexture.h> - -namespace android { - -status_t MediaRecorder::setCamera(const sp<ICamera>& camera, const sp<ICameraRecordingProxy>& proxy) -{ - ALOGV("setCamera(%p,%p)", camera.get(), proxy.get()); - if (mMediaRecorder == NULL) { - ALOGE("media recorder is not initialized yet"); - return INVALID_OPERATION; - } - if (!(mCurrentState & MEDIA_RECORDER_IDLE)) { - ALOGE("setCamera called in an invalid state(%d)", mCurrentState); - return INVALID_OPERATION; - } - - status_t ret = mMediaRecorder->setCamera(camera, proxy); - if (OK != ret) { - ALOGV("setCamera failed: %d", ret); - mCurrentState = MEDIA_RECORDER_ERROR; - return ret; - } - return ret; -} - -status_t MediaRecorder::setPreviewSurface(const sp<Surface>& surface) -{ - ALOGV("setPreviewSurface(%p)", surface.get()); - if (mMediaRecorder == NULL) { - ALOGE("media recorder is not initialized yet"); - return INVALID_OPERATION; - } - if (!(mCurrentState & MEDIA_RECORDER_DATASOURCE_CONFIGURED)) { - ALOGE("setPreviewSurface called in an invalid state(%d)", mCurrentState); - return INVALID_OPERATION; - } - if (!mIsVideoSourceSet) { - ALOGE("try to set preview surface without setting the video source first"); - return INVALID_OPERATION; - } - - status_t ret = mMediaRecorder->setPreviewSurface(surface); - if (OK != ret) { - ALOGV("setPreviewSurface failed: %d", ret); - mCurrentState = MEDIA_RECORDER_ERROR; - return ret; - } - return ret; -} - -status_t MediaRecorder::init() -{ - ALOGV("init"); - if (mMediaRecorder == NULL) { - ALOGE("media recorder is not initialized yet"); - return INVALID_OPERATION; - } - if (!(mCurrentState & MEDIA_RECORDER_IDLE)) { - ALOGE("init called in an invalid state(%d)", mCurrentState); - return INVALID_OPERATION; - } - - status_t ret = mMediaRecorder->init(); - if (OK != ret) { - ALOGV("init failed: %d", ret); - mCurrentState = MEDIA_RECORDER_ERROR; - return ret; - } - - ret = mMediaRecorder->setListener(this); - if (OK != ret) { - ALOGV("setListener failed: %d", ret); - mCurrentState = MEDIA_RECORDER_ERROR; - return ret; - } - - mCurrentState = MEDIA_RECORDER_INITIALIZED; - return ret; -} - -status_t MediaRecorder::setVideoSource(int vs) -{ - ALOGV("setVideoSource(%d)", vs); - if (mMediaRecorder == NULL) { - ALOGE("media recorder is not initialized yet"); - return INVALID_OPERATION; - } - if (mIsVideoSourceSet) { - ALOGE("video source has already been set"); - return INVALID_OPERATION; - } - if (mCurrentState & MEDIA_RECORDER_IDLE) { - ALOGV("Call init() since the media recorder is not initialized yet"); - status_t ret = init(); - if (OK != ret) { - return ret; - } - } - if (!(mCurrentState & MEDIA_RECORDER_INITIALIZED)) { - ALOGE("setVideoSource called in an invalid state(%d)", mCurrentState); - return INVALID_OPERATION; - } - - // following call is made over the Binder Interface - status_t ret = mMediaRecorder->setVideoSource(vs); - - if (OK != ret) { - ALOGV("setVideoSource failed: %d", ret); - mCurrentState = MEDIA_RECORDER_ERROR; - return ret; - } - mIsVideoSourceSet = true; - return ret; -} - -status_t MediaRecorder::setAudioSource(int as) -{ - ALOGV("setAudioSource(%d)", as); - if (mMediaRecorder == NULL) { - ALOGE("media recorder is not initialized yet"); - return INVALID_OPERATION; - } - if (mCurrentState & MEDIA_RECORDER_IDLE) { - ALOGV("Call init() since the media recorder is not initialized yet"); - status_t ret = init(); - if (OK != ret) { - return ret; - } - } - if (mIsAudioSourceSet) { - ALOGE("audio source has already been set"); - return INVALID_OPERATION; - } - if (!(mCurrentState & MEDIA_RECORDER_INITIALIZED)) { - ALOGE("setAudioSource called in an invalid state(%d)", mCurrentState); - return INVALID_OPERATION; - } - - status_t ret = mMediaRecorder->setAudioSource(as); - if (OK != ret) { - ALOGV("setAudioSource failed: %d", ret); - mCurrentState = MEDIA_RECORDER_ERROR; - return ret; - } - mIsAudioSourceSet = true; - return ret; -} - -status_t MediaRecorder::setOutputFormat(int of) -{ - ALOGV("setOutputFormat(%d)", of); - if (mMediaRecorder == NULL) { - ALOGE("media recorder is not initialized yet"); - return INVALID_OPERATION; - } - if (!(mCurrentState & MEDIA_RECORDER_INITIALIZED)) { - ALOGE("setOutputFormat called in an invalid state: %d", mCurrentState); - return INVALID_OPERATION; - } - if (mIsVideoSourceSet && of >= OUTPUT_FORMAT_AUDIO_ONLY_START && of != OUTPUT_FORMAT_RTP_AVP && of != OUTPUT_FORMAT_MPEG2TS) { //first non-video output format - ALOGE("output format (%d) is meant for audio recording only and incompatible with video recording", of); - return INVALID_OPERATION; - } - - status_t ret = mMediaRecorder->setOutputFormat(of); - if (OK != ret) { - ALOGE("setOutputFormat failed: %d", ret); - mCurrentState = MEDIA_RECORDER_ERROR; - return ret; - } - mCurrentState = MEDIA_RECORDER_DATASOURCE_CONFIGURED; - return ret; -} - -status_t MediaRecorder::setVideoEncoder(int ve) -{ - ALOGV("setVideoEncoder(%d)", ve); - if (mMediaRecorder == NULL) { - ALOGE("media recorder is not initialized yet"); - return INVALID_OPERATION; - } - if (!mIsVideoSourceSet) { - ALOGE("try to set the video encoder without setting the video source first"); - return INVALID_OPERATION; - } - if (mIsVideoEncoderSet) { - ALOGE("video encoder has already been set"); - return INVALID_OPERATION; - } - if (!(mCurrentState & MEDIA_RECORDER_DATASOURCE_CONFIGURED)) { - ALOGE("setVideoEncoder called in an invalid state(%d)", mCurrentState); - return INVALID_OPERATION; - } - - status_t ret = mMediaRecorder->setVideoEncoder(ve); - if (OK != ret) { - ALOGV("setVideoEncoder failed: %d", ret); - mCurrentState = MEDIA_RECORDER_ERROR; - return ret; - } - mIsVideoEncoderSet = true; - return ret; -} - -status_t MediaRecorder::setAudioEncoder(int ae) -{ - ALOGV("setAudioEncoder(%d)", ae); - if (mMediaRecorder == NULL) { - ALOGE("media recorder is not initialized yet"); - return INVALID_OPERATION; - } - if (!mIsAudioSourceSet) { - ALOGE("try to set the audio encoder without setting the audio source first"); - return INVALID_OPERATION; - } - if (mIsAudioEncoderSet) { - ALOGE("audio encoder has already been set"); - return INVALID_OPERATION; - } - if (!(mCurrentState & MEDIA_RECORDER_DATASOURCE_CONFIGURED)) { - ALOGE("setAudioEncoder called in an invalid state(%d)", mCurrentState); - return INVALID_OPERATION; - } - - status_t ret = mMediaRecorder->setAudioEncoder(ae); - if (OK != ret) { - ALOGV("setAudioEncoder failed: %d", ret); - mCurrentState = MEDIA_RECORDER_ERROR; - return ret; - } - mIsAudioEncoderSet = true; - return ret; -} - -status_t MediaRecorder::setOutputFile(const char* path) -{ - ALOGV("setOutputFile(%s)", path); - if (mMediaRecorder == NULL) { - ALOGE("media recorder is not initialized yet"); - return INVALID_OPERATION; - } - if (mIsOutputFileSet) { - ALOGE("output file has already been set"); - return INVALID_OPERATION; - } - if (!(mCurrentState & MEDIA_RECORDER_DATASOURCE_CONFIGURED)) { - ALOGE("setOutputFile called in an invalid state(%d)", mCurrentState); - return INVALID_OPERATION; - } - - status_t ret = mMediaRecorder->setOutputFile(path); - if (OK != ret) { - ALOGV("setOutputFile failed: %d", ret); - mCurrentState = MEDIA_RECORDER_ERROR; - return ret; - } - mIsOutputFileSet = true; - return ret; -} - -status_t MediaRecorder::setOutputFile(int fd, int64_t offset, int64_t length) -{ - ALOGV("setOutputFile(%d, %lld, %lld)", fd, offset, length); - if (mMediaRecorder == NULL) { - ALOGE("media recorder is not initialized yet"); - return INVALID_OPERATION; - } - if (mIsOutputFileSet) { - ALOGE("output file has already been set"); - return INVALID_OPERATION; - } - if (!(mCurrentState & MEDIA_RECORDER_DATASOURCE_CONFIGURED)) { - ALOGE("setOutputFile called in an invalid state(%d)", mCurrentState); - return INVALID_OPERATION; - } - - // It appears that if an invalid file descriptor is passed through - // binder calls, the server-side of the inter-process function call - // is skipped. As a result, the check at the server-side to catch - // the invalid file descritpor never gets invoked. This is to workaround - // this issue by checking the file descriptor first before passing - // it through binder call. - if (fd < 0) { - ALOGE("Invalid file descriptor: %d", fd); - return BAD_VALUE; - } - - status_t ret = mMediaRecorder->setOutputFile(fd, offset, length); - if (OK != ret) { - ALOGV("setOutputFile failed: %d", ret); - mCurrentState = MEDIA_RECORDER_ERROR; - return ret; - } - mIsOutputFileSet = true; - return ret; -} - -status_t MediaRecorder::setVideoSize(int width, int height) -{ - ALOGV("setVideoSize(%d, %d)", width, height); - if (mMediaRecorder == NULL) { - ALOGE("media recorder is not initialized yet"); - return INVALID_OPERATION; - } - if (!(mCurrentState & MEDIA_RECORDER_DATASOURCE_CONFIGURED)) { - ALOGE("setVideoSize called in an invalid state: %d", mCurrentState); - return INVALID_OPERATION; - } - if (!mIsVideoSourceSet) { - ALOGE("Cannot set video size without setting video source first"); - return INVALID_OPERATION; - } - - status_t ret = mMediaRecorder->setVideoSize(width, height); - if (OK != ret) { - ALOGE("setVideoSize failed: %d", ret); - mCurrentState = MEDIA_RECORDER_ERROR; - return ret; - } - - return ret; -} - -// Query a SurfaceMediaSurface through the Mediaserver, over the -// binder interface. This is used by the Filter Framework (MeidaEncoder) -// to get an <ISurfaceTexture> object to hook up to ANativeWindow. -sp<ISurfaceTexture> MediaRecorder:: - querySurfaceMediaSourceFromMediaServer() -{ - Mutex::Autolock _l(mLock); - mSurfaceMediaSource = - mMediaRecorder->querySurfaceMediaSource(); - if (mSurfaceMediaSource == NULL) { - ALOGE("SurfaceMediaSource could not be initialized!"); - } - return mSurfaceMediaSource; -} - - - -status_t MediaRecorder::setVideoFrameRate(int frames_per_second) -{ - ALOGV("setVideoFrameRate(%d)", frames_per_second); - if (mMediaRecorder == NULL) { - ALOGE("media recorder is not initialized yet"); - return INVALID_OPERATION; - } - if (!(mCurrentState & MEDIA_RECORDER_DATASOURCE_CONFIGURED)) { - ALOGE("setVideoFrameRate called in an invalid state: %d", mCurrentState); - return INVALID_OPERATION; - } - if (!mIsVideoSourceSet) { - ALOGE("Cannot set video frame rate without setting video source first"); - return INVALID_OPERATION; - } - - status_t ret = mMediaRecorder->setVideoFrameRate(frames_per_second); - if (OK != ret) { - ALOGE("setVideoFrameRate failed: %d", ret); - mCurrentState = MEDIA_RECORDER_ERROR; - return ret; - } - return ret; -} - -status_t MediaRecorder::setParameters(const String8& params) { - ALOGV("setParameters(%s)", params.string()); - if (mMediaRecorder == NULL) { - ALOGE("media recorder is not initialized yet"); - return INVALID_OPERATION; - } - - bool isInvalidState = (mCurrentState & - (MEDIA_RECORDER_PREPARED | - MEDIA_RECORDER_RECORDING | - MEDIA_RECORDER_ERROR)); - if (isInvalidState) { - ALOGE("setParameters is called in an invalid state: %d", mCurrentState); - return INVALID_OPERATION; - } - - status_t ret = mMediaRecorder->setParameters(params); - if (OK != ret) { - ALOGE("setParameters(%s) failed: %d", params.string(), ret); - // Do not change our current state to MEDIA_RECORDER_ERROR, failures - // of the only currently supported parameters, "max-duration" and - // "max-filesize" are _not_ fatal. - } - - return ret; -} - -status_t MediaRecorder::prepare() -{ - ALOGV("prepare"); - if (mMediaRecorder == NULL) { - ALOGE("media recorder is not initialized yet"); - return INVALID_OPERATION; - } - if (!(mCurrentState & MEDIA_RECORDER_DATASOURCE_CONFIGURED)) { - ALOGE("prepare called in an invalid state: %d", mCurrentState); - return INVALID_OPERATION; - } - if (mIsAudioSourceSet != mIsAudioEncoderSet) { - if (mIsAudioSourceSet) { - ALOGE("audio source is set, but audio encoder is not set"); - } else { // must not happen, since setAudioEncoder checks this already - ALOGE("audio encoder is set, but audio source is not set"); - } - return INVALID_OPERATION; - } - - if (mIsVideoSourceSet != mIsVideoEncoderSet) { - if (mIsVideoSourceSet) { - ALOGE("video source is set, but video encoder is not set"); - } else { // must not happen, since setVideoEncoder checks this already - ALOGE("video encoder is set, but video source is not set"); - } - return INVALID_OPERATION; - } - - status_t ret = mMediaRecorder->prepare(); - if (OK != ret) { - ALOGE("prepare failed: %d", ret); - mCurrentState = MEDIA_RECORDER_ERROR; - return ret; - } - mCurrentState = MEDIA_RECORDER_PREPARED; - return ret; -} - -status_t MediaRecorder::getMaxAmplitude(int* max) -{ - ALOGV("getMaxAmplitude"); - if (mMediaRecorder == NULL) { - ALOGE("media recorder is not initialized yet"); - return INVALID_OPERATION; - } - if (mCurrentState & MEDIA_RECORDER_ERROR) { - ALOGE("getMaxAmplitude called in an invalid state: %d", mCurrentState); - return INVALID_OPERATION; - } - - status_t ret = mMediaRecorder->getMaxAmplitude(max); - if (OK != ret) { - ALOGE("getMaxAmplitude failed: %d", ret); - mCurrentState = MEDIA_RECORDER_ERROR; - return ret; - } - return ret; -} - -status_t MediaRecorder::start() -{ - ALOGV("start"); - if (mMediaRecorder == NULL) { - ALOGE("media recorder is not initialized yet"); - return INVALID_OPERATION; - } - if (!(mCurrentState & MEDIA_RECORDER_PREPARED)) { - ALOGE("start called in an invalid state: %d", mCurrentState); - return INVALID_OPERATION; - } - - status_t ret = mMediaRecorder->start(); - if (OK != ret) { - ALOGE("start failed: %d", ret); - mCurrentState = MEDIA_RECORDER_ERROR; - return ret; - } - mCurrentState = MEDIA_RECORDER_RECORDING; - return ret; -} - -status_t MediaRecorder::stop() -{ - ALOGV("stop"); - if (mMediaRecorder == NULL) { - ALOGE("media recorder is not initialized yet"); - return INVALID_OPERATION; - } - if (!(mCurrentState & MEDIA_RECORDER_RECORDING)) { - ALOGE("stop called in an invalid state: %d", mCurrentState); - return INVALID_OPERATION; - } - - status_t ret = mMediaRecorder->stop(); - if (OK != ret) { - ALOGE("stop failed: %d", ret); - mCurrentState = MEDIA_RECORDER_ERROR; - return ret; - } - - // FIXME: - // stop and reset are semantically different. - // We treat them the same for now, and will change this in the future. - doCleanUp(); - mCurrentState = MEDIA_RECORDER_IDLE; - return ret; -} - -// Reset should be OK in any state -status_t MediaRecorder::reset() -{ - ALOGV("reset"); - if (mMediaRecorder == NULL) { - ALOGE("media recorder is not initialized yet"); - return INVALID_OPERATION; - } - - doCleanUp(); - status_t ret = UNKNOWN_ERROR; - switch (mCurrentState) { - case MEDIA_RECORDER_IDLE: - ret = OK; - break; - - case MEDIA_RECORDER_RECORDING: - case MEDIA_RECORDER_DATASOURCE_CONFIGURED: - case MEDIA_RECORDER_PREPARED: - case MEDIA_RECORDER_ERROR: { - ret = doReset(); - if (OK != ret) { - return ret; // No need to continue - } - } // Intentional fall through - case MEDIA_RECORDER_INITIALIZED: - ret = close(); - break; - - default: { - ALOGE("Unexpected non-existing state: %d", mCurrentState); - break; - } - } - return ret; -} - -status_t MediaRecorder::close() -{ - ALOGV("close"); - if (!(mCurrentState & MEDIA_RECORDER_INITIALIZED)) { - ALOGE("close called in an invalid state: %d", mCurrentState); - return INVALID_OPERATION; - } - status_t ret = mMediaRecorder->close(); - if (OK != ret) { - ALOGE("close failed: %d", ret); - mCurrentState = MEDIA_RECORDER_ERROR; - return UNKNOWN_ERROR; - } else { - mCurrentState = MEDIA_RECORDER_IDLE; - } - return ret; -} - -status_t MediaRecorder::doReset() -{ - ALOGV("doReset"); - status_t ret = mMediaRecorder->reset(); - if (OK != ret) { - ALOGE("doReset failed: %d", ret); - mCurrentState = MEDIA_RECORDER_ERROR; - return ret; - } else { - mCurrentState = MEDIA_RECORDER_INITIALIZED; - } - return ret; -} - -void MediaRecorder::doCleanUp() -{ - ALOGV("doCleanUp"); - mIsAudioSourceSet = false; - mIsVideoSourceSet = false; - mIsAudioEncoderSet = false; - mIsVideoEncoderSet = false; - mIsOutputFileSet = false; -} - -// Release should be OK in any state -status_t MediaRecorder::release() -{ - ALOGV("release"); - if (mMediaRecorder != NULL) { - return mMediaRecorder->release(); - } - return INVALID_OPERATION; -} - -MediaRecorder::MediaRecorder() : mSurfaceMediaSource(NULL) -{ - ALOGV("constructor"); - - const sp<IMediaPlayerService>& service(getMediaPlayerService()); - if (service != NULL) { - mMediaRecorder = service->createMediaRecorder(getpid()); - } - if (mMediaRecorder != NULL) { - mCurrentState = MEDIA_RECORDER_IDLE; - } - - - doCleanUp(); -} - -status_t MediaRecorder::initCheck() -{ - return mMediaRecorder != 0 ? NO_ERROR : NO_INIT; -} - -MediaRecorder::~MediaRecorder() -{ - ALOGV("destructor"); - if (mMediaRecorder != NULL) { - mMediaRecorder.clear(); - } - - if (mSurfaceMediaSource != NULL) { - mSurfaceMediaSource.clear(); - } -} - -status_t MediaRecorder::setListener(const sp<MediaRecorderListener>& listener) -{ - ALOGV("setListener"); - Mutex::Autolock _l(mLock); - mListener = listener; - - return NO_ERROR; -} - -void MediaRecorder::notify(int msg, int ext1, int ext2) -{ - ALOGV("message received msg=%d, ext1=%d, ext2=%d", msg, ext1, ext2); - - sp<MediaRecorderListener> listener; - mLock.lock(); - listener = mListener; - mLock.unlock(); - - if (listener != NULL) { - Mutex::Autolock _l(mNotifyLock); - ALOGV("callback application"); - listener->notify(msg, ext1, ext2); - ALOGV("back from callback"); - } -} - -void MediaRecorder::died() -{ - ALOGV("died"); - notify(MEDIA_RECORDER_EVENT_ERROR, MEDIA_ERROR_SERVER_DIED, 0); -} - -}; // namespace android |