diff options
Diffstat (limited to 'media/libmedia')
-rw-r--r-- | media/libmedia/Android.mk | 21 | ||||
-rw-r--r-- | media/libmedia/AudioParameter.cpp | 8 | ||||
-rw-r--r-- | media/libmedia/AudioRecord.cpp | 5 | ||||
-rw-r--r-- | media/libmedia/AudioTrack.cpp | 266 | ||||
-rw-r--r-- | media/libmedia/IAudioFlinger.cpp | 69 | ||||
-rw-r--r-- | media/libmedia/IAudioFlingerClient.cpp | 10 | ||||
-rw-r--r-- | media/libmedia/IDirectTrack.cpp | 178 | ||||
-rw-r--r-- | media/libmedia/IDirectTrackClient.cpp | 69 | ||||
-rw-r--r-- | media/libmedia/MediaProfiles.cpp | 26 |
9 files changed, 602 insertions, 50 deletions
diff --git a/media/libmedia/Android.mk b/media/libmedia/Android.mk index 54666fb..69361fa 100644 --- a/media/libmedia/Android.mk +++ b/media/libmedia/Android.mk @@ -11,6 +11,17 @@ include $(BUILD_STATIC_LIBRARY) include $(CLEAR_VARS) +ifeq ($(BOARD_USES_QCOM_HARDWARE),true) +LOCAL_SRC_FILES:= AudioParameter.cpp +LOCAL_MODULE:= libaudioparameter +LOCAL_MODULE_TAGS := optional +LOCAL_SHARED_LIBRARIES := libutils + +include $(BUILD_SHARED_LIBRARY) + +include $(CLEAR_VARS) +endif + LOCAL_SRC_FILES:= \ AudioTrack.cpp \ IAudioFlinger.cpp \ @@ -51,6 +62,16 @@ LOCAL_SRC_FILES:= \ SoundPool.cpp \ SoundPoolThread.cpp +ifeq ($(BOARD_USES_QCOM_HARDWARE),true) +LOCAL_SRC_FILES += \ + IDirectTrack.cpp \ + IDirectTrackClient.cpp + +ifeq ($(TARGET_QCOM_AUDIO_VARIANT),caf) +LOCAL_CFLAGS += -DQCOM_ENHANCED_AUDIO +endif +endif + LOCAL_SHARED_LIBRARIES := \ libui libcutils libutils libbinder libsonivox libicuuc libexpat \ libcamera_client libstagefright_foundation \ diff --git a/media/libmedia/AudioParameter.cpp b/media/libmedia/AudioParameter.cpp index e3fea77..fbb34f4 100644 --- a/media/libmedia/AudioParameter.cpp +++ b/media/libmedia/AudioParameter.cpp @@ -1,5 +1,6 @@ /* * Copyright (C) 2006-2011 The Android Open Source Project + * Copyright (c) 2012, The Linux Foundation. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -32,6 +33,13 @@ const char * const AudioParameter::keyChannels = AUDIO_PARAMETER_STREAM_CHANNELS const char * const AudioParameter::keyFrameCount = AUDIO_PARAMETER_STREAM_FRAME_COUNT; const char * const AudioParameter::keyInputSource = AUDIO_PARAMETER_STREAM_INPUT_SOURCE; const char * const AudioParameter::keyScreenState = AUDIO_PARAMETER_KEY_SCREEN_STATE; +#ifdef QCOM_HARDWARE +const char * const AudioParameter::keyHandleFm = AUDIO_PARAMETER_KEY_HANDLE_FM; +const char * const AudioParameter::keyVoipCheck = AUDIO_PARAMETER_KEY_VOIP_CHECK; +const char * const AudioParameter::keyFluenceType = AUDIO_PARAMETER_KEY_FLUENCE_TYPE; +const char * const AudioParameter::keySSR = AUDIO_PARAMETER_KEY_SSR; +const char * const AudioParameter::keyHandleA2dpDevice = AUDIO_PARAMETER_KEY_HANDLE_A2DP_DEVICE; +#endif AudioParameter::AudioParameter(const String8& keyValuePairs) { diff --git a/media/libmedia/AudioRecord.cpp b/media/libmedia/AudioRecord.cpp index 8ea6306..ce03754 100644 --- a/media/libmedia/AudioRecord.cpp +++ b/media/libmedia/AudioRecord.cpp @@ -1,6 +1,7 @@ /* ** ** Copyright 2008, The Android Open Source Project +** Copyright (c) 2011-2012, The Linux Foundation. All rights reserved. ** ** Licensed under the Apache License, Version 2.0 (the "License"); ** you may not use this file except in compliance with the License. @@ -156,7 +157,11 @@ status_t AudioRecord::set( return BAD_VALUE; } +#ifdef QCOM_HARDWARE + int channelCount = popcount((channelMask) & (AUDIO_CHANNEL_IN_STEREO | AUDIO_CHANNEL_IN_MONO | AUDIO_CHANNEL_IN_5POINT1)); +#else int channelCount = popcount(channelMask); +#endif if (sessionId == 0 ) { mSessionId = AudioSystem::newAudioSessionId(); diff --git a/media/libmedia/AudioTrack.cpp b/media/libmedia/AudioTrack.cpp index fa52fa9..a2172c9 100644 --- a/media/libmedia/AudioTrack.cpp +++ b/media/libmedia/AudioTrack.cpp @@ -2,6 +2,10 @@ ** ** Copyright 2007, The Android Open Source Project ** +** Copyright (c) 2012, The Linux Foundation. All rights reserved. +** Not a Contribution, Apache license notifications and license are retained +** for attribution purposes only. + ** 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 @@ -96,6 +100,10 @@ AudioTrack::AudioTrack() mIsTimed(false), mPreviousPriority(ANDROID_PRIORITY_NORMAL), mPreviousSchedulingGroup(SP_DEFAULT) +#ifdef QCOM_HARDWARE + ,mAudioFlinger(NULL), + mObserver(NULL) +#endif { } @@ -114,6 +122,10 @@ AudioTrack::AudioTrack( mIsTimed(false), mPreviousPriority(ANDROID_PRIORITY_NORMAL), mPreviousSchedulingGroup(SP_DEFAULT) +#ifdef QCOM_HARDWARE + ,mAudioFlinger(NULL), + mObserver(NULL) +#endif { mStatus = set(streamType, sampleRate, format, channelMask, frameCount, flags, cbf, user, notificationFrames, @@ -135,6 +147,10 @@ AudioTrack::AudioTrack( : mStatus(NO_INIT), mIsTimed(false), mPreviousPriority(ANDROID_PRIORITY_NORMAL), mPreviousSchedulingGroup(SP_DEFAULT) +#ifdef QCOM_HARDWARE + ,mAudioFlinger(NULL), + mObserver(NULL) +#endif { mStatus = set((audio_stream_type_t)streamType, sampleRate, (audio_format_t)format, (audio_channel_mask_t) channelMask, @@ -157,6 +173,10 @@ AudioTrack::AudioTrack( mIsTimed(false), mPreviousPriority(ANDROID_PRIORITY_NORMAL), mPreviousSchedulingGroup(SP_DEFAULT) +#ifdef QCOM_HARDWARE + ,mAudioFlinger(NULL), + mObserver(NULL) +#endif { mStatus = set(streamType, sampleRate, format, channelMask, 0 /*frameCount*/, flags, cbf, user, notificationFrames, @@ -177,9 +197,22 @@ AudioTrack::~AudioTrack() mAudioTrackThread->requestExitAndWait(); mAudioTrackThread.clear(); } +#ifdef QCOM_HARDWARE + if (mAudioTrack != 0) { + mAudioTrack.clear(); + AudioSystem::releaseAudioSessionId(mSessionId); + } + + if (mDirectTrack != 0) { + mDirectTrack.clear(); + } +#else mAudioTrack.clear(); +#endif IPCThreadState::self()->flushCommands(); +#ifndef QCOM_HARDWARE AudioSystem::releaseAudioSessionId(mSessionId); +#endif } } @@ -252,12 +285,24 @@ status_t AudioTrack::set( flags = (audio_output_flags_t)(flags &~AUDIO_OUTPUT_FLAG_DEEP_BUFFER); } +#ifdef QCOM_ENHANCED_AUDIO + if ((streamType == AUDIO_STREAM_VOICE_CALL) + && (channelMask == AUDIO_CHANNEL_OUT_MONO) + && ((sampleRate == 8000 || sampleRate == 16000))) + { + ALOGD("Turn on Direct Output for VOIP RX"); + flags = (audio_output_flags_t)(flags | AUDIO_OUTPUT_FLAG_VOIP_RX|AUDIO_OUTPUT_FLAG_DIRECT); + } +#endif + if (!audio_is_output_channel(channelMask)) { ALOGE("Invalid channel mask %#x", channelMask); return BAD_VALUE; } uint32_t channelCount = popcount(channelMask); + ALOGV("AudioTrack getOutput streamType %d, sampleRate %d, format %d, channelMask %d, flags %x", + streamType, sampleRate, format, channelMask, flags); audio_io_handle_t output = AudioSystem::getOutput( streamType, sampleRate, format, channelMask, @@ -278,46 +323,86 @@ status_t AudioTrack::set( mFlags = flags; mCbf = cbf; - if (cbf != NULL) { - mAudioTrackThread = new AudioTrackThread(*this, threadCanCallJava); - mAudioTrackThread->run("AudioTrack", ANDROID_PRIORITY_AUDIO, 0 /*stack*/); - } - - // create the IAudioTrack - status_t status = createTrack_l(streamType, - sampleRate, - format, - channelMask, - frameCount, - flags, - sharedBuffer, - output); +#ifdef QCOM_HARDWARE + if (flags & AUDIO_OUTPUT_FLAG_LPA || flags & AUDIO_OUTPUT_FLAG_TUNNEL) { + ALOGV("Creating Direct Track"); + const sp<IAudioFlinger>& audioFlinger = AudioSystem::get_audio_flinger(); + if (audioFlinger == 0) { + ALOGE("Could not get audioflinger"); + return NO_INIT; + } + mAudioFlinger = audioFlinger; + status_t status = NO_ERROR; + mAudioDirectOutput = output; + mDirectTrack = audioFlinger->createDirectTrack( getpid(), + sampleRate, + channelMask, + mAudioDirectOutput, + &mSessionId, + this, + streamType, + &status); + if(status != NO_ERROR) { + ALOGE("createDirectTrack returned with status %d", status); + return status; + } + mAudioTrack = NULL; + mSharedBuffer = NULL; + } + else { +#endif + if (cbf != NULL) { + mAudioTrackThread = new AudioTrackThread(*this, threadCanCallJava); + mAudioTrackThread->run("AudioTrack", ANDROID_PRIORITY_AUDIO, 0 /*stack*/); + } + // create the IAudioTrack + status_t status = createTrack_l(streamType, + sampleRate, + format, + channelMask, + frameCount, + flags, + sharedBuffer, + output); - if (status != NO_ERROR) { - if (mAudioTrackThread != 0) { - mAudioTrackThread->requestExit(); - mAudioTrackThread.clear(); + if (status != NO_ERROR) { + if (mAudioTrackThread != 0) { + mAudioTrackThread->requestExit(); + mAudioTrackThread.clear(); + } + return status; } - return status; +#ifdef QCOM_HARDWARE + AudioSystem::acquireAudioSessionId(mSessionId); + mAudioDirectOutput = -1; + mDirectTrack = NULL; + mSharedBuffer = sharedBuffer; } - + mUserData = user; +#endif mStatus = NO_ERROR; mStreamType = streamType; mFormat = format; mChannelMask = channelMask; mChannelCount = channelCount; - mSharedBuffer = sharedBuffer; + mMuted = false; mActive = false; - mUserData = user; + mLoopCount = 0; mMarkerPosition = 0; mMarkerReached = false; mNewPosition = 0; mUpdatePeriod = 0; mFlushed = false; + +#ifndef QCOM_HARDWARE + mSharedBuffer = sharedBuffer; + mUserData = user; AudioSystem::acquireAudioSessionId(mSessionId); +#endif + mRestoreStatus = NO_ERROR; return NO_ERROR; } @@ -331,6 +416,11 @@ status_t AudioTrack::initCheck() const uint32_t AudioTrack::latency() const { +#ifdef QCOM_HARDWARE + if(mAudioDirectOutput != -1) { + return mAudioFlinger->latency(mAudioDirectOutput); + } +#endif return mLatency; } @@ -351,6 +441,11 @@ int AudioTrack::channelCount() const uint32_t AudioTrack::frameCount() const { +#ifdef QCOM_HARDWARE + if(mAudioDirectOutput != -1) { + return mAudioFlinger->frameCount(mAudioDirectOutput); + } +#endif return mCblk->frameCount; } @@ -372,6 +467,16 @@ sp<IMemory>& AudioTrack::sharedBuffer() void AudioTrack::start() { +#ifdef QCOM_HARDWARE + if (mDirectTrack != NULL) { + if(mActive == 0) { + mActive = 1; + mDirectTrack->start(); + } + return; + } +#endif + sp<AudioTrackThread> t = mAudioTrackThread; ALOGV("start %p", this); @@ -436,26 +541,35 @@ void AudioTrack::stop() 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->pause(); - } else { - setpriority(PRIO_PROCESS, 0, mPreviousPriority); - set_sched_policy(0, mPreviousSchedulingGroup); +#ifdef QCOM_HARDWARE + if(mDirectTrack != NULL) { + mActive = false; + mDirectTrack->stop(); + } else if (mAudioTrack != NULL) { +#endif + 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->pause(); + } else { + setpriority(PRIO_PROCESS, 0, mPreviousPriority); + set_sched_policy(0, mPreviousSchedulingGroup); + } +#ifdef QCOM_HARDWARE } +#endif } } @@ -469,7 +583,12 @@ bool AudioTrack::stopped() const void AudioTrack::flush() { AutoMutex lock(mLock); - flush_l(); +#ifdef QCOM_HARDWARE + if(mDirectTrack != NULL) { + mDirectTrack->flush(); + } else +#endif + flush_l(); } // must be called with mLock held @@ -497,14 +616,28 @@ void AudioTrack::pause() AutoMutex lock(mLock); if (mActive) { mActive = false; - mCblk->cv.signal(); - mAudioTrack->pause(); +#ifdef QCOM_HARDWARE + if(mDirectTrack != NULL) { + ALOGV("mDirectTrack pause"); + mDirectTrack->pause(); + } else { +#endif + mCblk->cv.signal(); + mAudioTrack->pause(); +#ifdef QCOM_HARDWARE + } +#endif } } void AudioTrack::mute(bool e) { - mAudioTrack->mute(e); +#ifdef QCOM_HARDWARE + if(mDirectTrack != NULL) { + mDirectTrack->mute(e); + } else +#endif + mAudioTrack->mute(e); mMuted = e; } @@ -522,8 +655,13 @@ status_t AudioTrack::setVolume(float left, float right) AutoMutex lock(mLock); mVolume[LEFT] = left; mVolume[RIGHT] = right; - - mCblk->setVolumeLR((uint32_t(uint16_t(right * 0x1000)) << 16) | uint16_t(left * 0x1000)); +#ifdef QCOM_HARDWARE + if(mDirectTrack != NULL) { + ALOGV("mDirectTrack->setVolume(left = %f , right = %f)", left,right); + mDirectTrack->setVolume(left, right); + } else +#endif + mCblk->setVolumeLR((uint32_t(uint16_t(right * 0x1000)) << 16) | uint16_t(left * 0x1000)); return NO_ERROR; } @@ -540,6 +678,11 @@ void AudioTrack::getVolume(float* left, float* right) const status_t AudioTrack::setAuxEffectSendLevel(float level) { +#ifdef QCOM_HARDWARE + if (mDirectTrack != NULL) { + return NO_ERROR; + } +#endif ALOGV("setAuxEffectSendLevel(%f)", level); if (level < 0.0f || level > 1.0f) { return BAD_VALUE; @@ -586,6 +729,11 @@ uint32_t AudioTrack::getSampleRate() const } AutoMutex lock(mLock); +#ifdef QCOM_HARDWARE + if(mAudioDirectOutput != -1) { + return mAudioFlinger->sampleRate(mAudioDirectOutput); + } +#endif return mCblk->sampleRate; } @@ -1076,7 +1224,12 @@ void AudioTrack::releaseBuffer(Buffer* audioBuffer) ssize_t AudioTrack::write(const void* buffer, size_t userSize) { - +#ifdef QCOM_HARDWARE + if (mDirectTrack != NULL) { + mDirectTrack->write(buffer,userSize); + return userSize; + } +#endif if (mSharedBuffer != 0) return INVALID_OPERATION; if (mIsTimed) return INVALID_OPERATION; @@ -1456,6 +1609,23 @@ status_t AudioTrack::dump(int fd, const Vector<String16>& args) const return NO_ERROR; } +#ifdef QCOM_HARDWARE +void AudioTrack::notify(int msg) { + if (msg == EVENT_UNDERRUN) { + ALOGV("Posting event underrun to Audio Sink."); + mCbf(EVENT_UNDERRUN, mUserData, 0); + } +} + +status_t AudioTrack::getTimeStamp(uint64_t *tstamp) { + if (mDirectTrack != NULL) { + *tstamp = mDirectTrack->getTimeStamp(); + ALOGV("Timestamp %lld ", *tstamp); + } + return NO_ERROR; +} +#endif + // ========================================================================= AudioTrack::AudioTrackThread::AudioTrackThread(AudioTrack& receiver, bool bCanCallJava) diff --git a/media/libmedia/IAudioFlinger.cpp b/media/libmedia/IAudioFlinger.cpp index ce8ffc4..cc6a75c 100644 --- a/media/libmedia/IAudioFlinger.cpp +++ b/media/libmedia/IAudioFlinger.cpp @@ -1,6 +1,9 @@ /* ** ** Copyright 2007, The Android Open Source Project +** Copyright (c) 2012, The Linux Foundation. All rights reserved. +** Not a Contribution, Apache license notifications and license are retained +** for attribution purposes only. ** ** Licensed under the Apache License, Version 2.0 (the "License"); ** you may not use this file except in compliance with the License. @@ -73,6 +76,9 @@ enum { LOAD_HW_MODULE, GET_PRIMARY_OUTPUT_SAMPLING_RATE, GET_PRIMARY_OUTPUT_FRAME_COUNT, +#ifdef QCOM_HARDWARE + CREATE_DIRECT_TRACK +#endif }; class BpAudioFlinger : public BpInterface<IAudioFlinger> @@ -132,6 +138,49 @@ public: return track; } +#ifdef QCOM_HARDWARE + virtual sp<IDirectTrack> createDirectTrack( + pid_t pid, + uint32_t sampleRate, + audio_channel_mask_t channelMask, + audio_io_handle_t output, + int *sessionId, + IDirectTrackClient* client, + audio_stream_type_t streamType, + status_t *status) + { + Parcel data, reply; + sp<IDirectTrack> track; + data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor()); + data.writeInt32(pid); + data.writeInt32(sampleRate); + data.writeInt32(channelMask); + data.writeInt32((int32_t)output); + int lSessionId = 0; + if (sessionId != NULL) { + lSessionId = *sessionId; + } + data.writeInt32(lSessionId); + data.write(client, sizeof(IDirectTrackClient)); + data.writeInt32((int32_t) streamType); + status_t lStatus = remote()->transact(CREATE_DIRECT_TRACK, data, &reply); + if (lStatus != NO_ERROR) { + ALOGE("createDirectTrack error: %s", strerror(-lStatus)); + } else { + lSessionId = reply.readInt32(); + if (sessionId != NULL) { + *sessionId = lSessionId; + } + lStatus = reply.readInt32(); + track = interface_cast<IDirectTrack>(reply.readStrongBinder()); + } + if (status) { + *status = lStatus; + } + return track; + } +#endif + virtual sp<IAudioRecord> openRecord( pid_t pid, audio_io_handle_t input, @@ -738,6 +787,26 @@ status_t BnAudioFlinger::onTransact( reply->writeStrongBinder(track->asBinder()); return NO_ERROR; } break; +#ifdef QCOM_HARDWARE + case CREATE_DIRECT_TRACK: { + CHECK_INTERFACE(IAudioFlinger, data, reply); + pid_t pid = data.readInt32(); + uint32_t sampleRate = data.readInt32(); + audio_channel_mask_t channelMask = data.readInt32(); + audio_io_handle_t output = (audio_io_handle_t) data.readInt32(); + int sessionId = data.readInt32(); + IDirectTrackClient* client; + data.read(client,sizeof(IDirectTrackClient)); + int streamType = data.readInt32(); + status_t status; + sp<IDirectTrack> track = createDirectTrack(pid, + sampleRate, channelMask, output, &sessionId, client,(audio_stream_type_t) streamType, &status); + reply->writeInt32(sessionId); + reply->writeInt32(status); + reply->writeStrongBinder(track->asBinder()); + return NO_ERROR; + } break; +#endif case OPEN_RECORD: { CHECK_INTERFACE(IAudioFlinger, data, reply); pid_t pid = data.readInt32(); diff --git a/media/libmedia/IAudioFlingerClient.cpp b/media/libmedia/IAudioFlingerClient.cpp index 4178b29..e289703 100644 --- a/media/libmedia/IAudioFlingerClient.cpp +++ b/media/libmedia/IAudioFlingerClient.cpp @@ -1,4 +1,8 @@ /* + * Copyright (c) 2012, The Linux Foundation. All rights reserved. + * Not a Contribution, Apache license notifications and license are retained + * for attribution purposes only. + * * Copyright (C) 2009 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -49,7 +53,11 @@ public: 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) { + } else if (event != AudioSystem::OUTPUT_CLOSED && +#ifdef QCOM_HARDWARE + event != AudioSystem::EFFECT_CONFIG_CHANGED && +#endif + event != AudioSystem::INPUT_CLOSED) { const AudioSystem::OutputDescriptor *desc = (const AudioSystem::OutputDescriptor *)param2; data.writeInt32(desc->samplingRate); data.writeInt32(desc->format); diff --git a/media/libmedia/IDirectTrack.cpp b/media/libmedia/IDirectTrack.cpp new file mode 100644 index 0000000..480761f --- /dev/null +++ b/media/libmedia/IDirectTrack.cpp @@ -0,0 +1,178 @@ +/* +** Copyright (c) 2012, The Linux Foundation. All rights reserved. +** Not a Contribution, Apache license notifications and license are retained +** for attribution purposes only. +** +** 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 "IDirectTrack" +//#define LOG_NDEBUG 0 +#include <utils/Log.h> + +#include <stdint.h> +#include <sys/types.h> + +#include <binder/Parcel.h> + +#include <media/IDirectTrack.h> + +namespace android { + +enum { + START = IBinder::FIRST_CALL_TRANSACTION, + STOP, + FLUSH, + MUTE, + PAUSE, + SET_VOLUME, + WRITE, + GET_TIMESTAMP +}; + +class BpDirectTrack : public BpInterface<IDirectTrack> +{ +public: + BpDirectTrack(const sp<IBinder>& impl) + : BpInterface<IDirectTrack>(impl) + { + } + + virtual status_t start() + { + Parcel data, reply; + data.writeInterfaceToken(IDirectTrack::getInterfaceDescriptor()); + 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(IDirectTrack::getInterfaceDescriptor()); + remote()->transact(STOP, data, &reply); + } + + virtual void flush() + { + Parcel data, reply; + data.writeInterfaceToken(IDirectTrack::getInterfaceDescriptor()); + remote()->transact(FLUSH, data, &reply); + } + + virtual void mute(bool e) + { + Parcel data, reply; + data.writeInterfaceToken(IDirectTrack::getInterfaceDescriptor()); + data.writeInt32(e); + remote()->transact(MUTE, data, &reply); + } + + virtual void pause() + { + Parcel data, reply; + data.writeInterfaceToken(IDirectTrack::getInterfaceDescriptor()); + remote()->transact(PAUSE, data, &reply); + } + + virtual void setVolume(float left, float right) + { + Parcel data, reply; + data.writeInterfaceToken(IDirectTrack::getInterfaceDescriptor()); + remote()->transact(SET_VOLUME, data, &reply); + } + + virtual ssize_t write(const void* buffer, size_t bytes) + { + Parcel data, reply; + data.writeInterfaceToken(IDirectTrack::getInterfaceDescriptor()); + ssize_t bytesWritten = remote()->transact(WRITE, data, &reply); + return bytesWritten; + } + + virtual int64_t getTimeStamp() { + Parcel data, reply; + data.writeInterfaceToken(IDirectTrack::getInterfaceDescriptor()); + int64_t tstamp = remote()->transact(GET_TIMESTAMP, data, &reply); + return tstamp; + } +}; + +IMPLEMENT_META_INTERFACE(DirectTrack, "android.media.IDirectTrack"); + +// ---------------------------------------------------------------------- + +status_t BnDirectTrack::onTransact( + uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) +{ + switch(code) { + case START: { + CHECK_INTERFACE(IDirectTrack, data, reply); + reply->writeInt32(start()); + return NO_ERROR; + } break; + case STOP: { + CHECK_INTERFACE(IDirectTrack, data, reply); + stop(); + return NO_ERROR; + } break; + case FLUSH: { + CHECK_INTERFACE(IDirectTrack, data, reply); + flush(); + return NO_ERROR; + } break; + case MUTE: { + CHECK_INTERFACE(IDirectTrack, data, reply); + mute( data.readInt32() ); + return NO_ERROR; + } break; + case PAUSE: { + CHECK_INTERFACE(IDirectTrack, data, reply); + pause(); + return NO_ERROR; + } + case SET_VOLUME: { + CHECK_INTERFACE(IDirectTrack, data, reply); + float left = 1.0; + float right = 1.0; + setVolume(left, right); + return NO_ERROR; + } + case WRITE: { + CHECK_INTERFACE(IDirectTrack, data, reply); + const void *buffer = (void *)data.readInt32(); + size_t bytes = data.readInt32(); + ssize_t bytesWritten = write(buffer, bytes); + reply->writeInt32(bytesWritten); + return NO_ERROR; + } + case GET_TIMESTAMP: { + CHECK_INTERFACE(IDirectTrack, data, reply); + int64_t time = getTimeStamp(); + reply->writeInt32(time); + return NO_ERROR; + } + default: + return BBinder::onTransact(code, data, reply, flags); + } +} + +}; // namespace android + diff --git a/media/libmedia/IDirectTrackClient.cpp b/media/libmedia/IDirectTrackClient.cpp new file mode 100644 index 0000000..86a47ec --- /dev/null +++ b/media/libmedia/IDirectTrackClient.cpp @@ -0,0 +1,69 @@ +/* +** Copyright (c) 2012, The Linux Foundation. All rights reserved. +** Not a Contribution, Apache license notifications and license are retained +** for attribution purposes only. +** +** 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. +*/ + +#include <utils/RefBase.h> +#include <binder/IInterface.h> +#include <binder/Parcel.h> + +#include <media/IDirectTrackClient.h> + +namespace android { + +enum { + NOTIFY = IBinder::FIRST_CALL_TRANSACTION, +}; + +class BpDirectTrackClient: public BpInterface<IDirectTrackClient> +{ +public: + BpDirectTrackClient(const sp<IBinder>& impl) + : BpInterface<IDirectTrackClient>(impl) + { + } + + virtual void notify(int msg) + { + Parcel data, reply; + data.writeInterfaceToken(IDirectTrackClient::getInterfaceDescriptor()); + data.writeInt32(msg); + remote()->transact(NOTIFY, data, &reply, IBinder::FLAG_ONEWAY); + } +}; + +IMPLEMENT_META_INTERFACE(DirectTrackClient, "android.media.IDirectTrackClient"); + +// ---------------------------------------------------------------------- + +status_t BnDirectTrackClient::onTransact( + uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) +{ + switch (code) { + case NOTIFY: { + CHECK_INTERFACE(IDirectTrackClient, data, reply); + int msg = data.readInt32(); + notify(msg); + return NO_ERROR; + } break; + default: + return BBinder::onTransact(code, data, reply, flags); + } +} + +}; // namespace android diff --git a/media/libmedia/MediaProfiles.cpp b/media/libmedia/MediaProfiles.cpp index f69dbea..fa536a6 100644 --- a/media/libmedia/MediaProfiles.cpp +++ b/media/libmedia/MediaProfiles.cpp @@ -1,6 +1,7 @@ /* ** ** Copyright 2010, The Android Open Source Project +** Copyright (c) 2010 - 2012, The Linux Foundation. All rights reserved. ** ** Licensed under the Apache License, Version 2.0 (the "License"); ** you may not use this file except in compliance with the License. @@ -45,7 +46,10 @@ const MediaProfiles::NameToTagMap MediaProfiles::sAudioEncoderNameMap[] = { {"amrwb", AUDIO_ENCODER_AMR_WB}, {"aac", AUDIO_ENCODER_AAC}, {"heaac", AUDIO_ENCODER_HE_AAC}, - {"aaceld", AUDIO_ENCODER_AAC_ELD} + {"aaceld", AUDIO_ENCODER_AAC_ELD}, +#ifdef QCOM_HARDWARE + {"lpcm", AUDIO_ENCODER_LPCM}, +#endif }; const MediaProfiles::NameToTagMap MediaProfiles::sFileFormatMap[] = { @@ -804,6 +808,10 @@ MediaProfiles::createDefaultCamcorderProfiles(MediaProfiles *profiles) MediaProfiles::createDefaultAudioEncoders(MediaProfiles *profiles) { profiles->mAudioEncoders.add(createDefaultAmrNBEncoderCap()); +#ifdef QCOM_HARDWARE + profiles->mAudioEncoders.add(createDefaultAacEncoderCap()); + profiles->mAudioEncoders.add(createDefaultLpcmEncoderCap()); +#endif } /*static*/ void @@ -838,6 +846,22 @@ MediaProfiles::createDefaultAmrNBEncoderCap() AUDIO_ENCODER_AMR_NB, 5525, 12200, 8000, 8000, 1, 1); } +#ifdef QCOM_HARDWARE +/*static*/ MediaProfiles::AudioEncoderCap* +MediaProfiles::createDefaultAacEncoderCap() +{ + return new MediaProfiles::AudioEncoderCap( + AUDIO_ENCODER_AAC, 64000, 156000, 8000, 48000, 1, 2); +} + +/*static*/ MediaProfiles::AudioEncoderCap* +MediaProfiles::createDefaultLpcmEncoderCap() +{ + return new MediaProfiles::AudioEncoderCap( + AUDIO_ENCODER_LPCM, 768000, 4608000, 48000, 48000, 1, 6); +} +#endif + /*static*/ void MediaProfiles::createDefaultImageEncodingQualityLevels(MediaProfiles *profiles) { |