summaryrefslogtreecommitdiffstats
path: root/media/libmedia
diff options
context:
space:
mode:
Diffstat (limited to 'media/libmedia')
-rw-r--r--media/libmedia/Android.mk21
-rw-r--r--media/libmedia/AudioParameter.cpp8
-rw-r--r--media/libmedia/AudioRecord.cpp5
-rw-r--r--media/libmedia/AudioTrack.cpp266
-rw-r--r--media/libmedia/IAudioFlinger.cpp69
-rw-r--r--media/libmedia/IAudioFlingerClient.cpp10
-rw-r--r--media/libmedia/IDirectTrack.cpp178
-rw-r--r--media/libmedia/IDirectTrackClient.cpp69
-rw-r--r--media/libmedia/MediaProfiles.cpp26
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)
{