Squashed commit of audio changes from CodeAurora

libstagefright: Add QC specific media format

- Add QC specific media extensions
- Add QC specific media definitions

Change-Id: I7dca90be3b977701d9537f5e017117790a030f1f

audio: Compile AudioParameter as shared library

- AudioParameter as shared lib is needed by BT
  support in WFD source.

Change-Id: I464b428ace0cbb57ce6bf7bf3b57d51a7d56f032

libstagefright: Send flush on both i/p and o/p ports together

- ANR occurs in music due to race condition in OMX component if
  flush is issued separately for i/p and o/p ports as DSP only
  handles simultaneous flush on i/p and o/p ports.

Change-Id: I5b16cd5a9b57c857dc8bed489d2663b8f54769e3

libstagefright: Enable extended A\V format

- Add new files to support extended A\V format

Change-Id: I1e61d78d35b868d55fd8e99f95de8cab9c465db4

libstagefright: Framework to plug-in propritory parser

- Extend the current framework to plug-in propritory
  parser

Change-Id: Ia586a3048420ddf1515261f20035589447263b7b

audio: add support for QCOM audio formats

- Add support for EVRC, QCELP, and WMA formats.

Change-Id: Iaf80f982fc8b08617132dbd7d524a1748866745c

frameworks/av: Support Tunnel Playback

- Implement DirectTrack and DirectTrackClient
- DirectTrack exposes API to client so it can create a direct
  output.
- DirectTrackClient allows notifications to be sent to the
  client from DirectTrack
- DirectTrack is being used for Tunnel Audio

Change-Id: I2fbb18a781d8e44b8d65da9a357f6e39375f063a

frameworks/av: Support LPA Playback

Add support to enable Playback in LPA mode

Change-Id: I1b8ac4904f4735017d62f3757ede7bbb56e62fd3

audio: Send correct channel mask in voice call recording.

-Using popCount function to get channel count gives incorrect value on
voice call recording.
-Only STEREO and MONO bits to be considered to count
channels on input

Change-Id: I04c2c802422e868bdba0538ff8623dbf9eb659fe

libstagefright: Thumbnail mode initial commit

- use sync frame decoding mode when kClientNeedsFrameBuffer
  is set for hardware decoders
- hardware decoder will only expect I frames, OMXCodec will
  set EOS on first ETB to stop more frames from being pulled
- skip EOS check on FTB so that the first frame will be
  handled

Change-Id: I0e8974e088fdcc468e27764861c128cfe291499f

audio: Add support for QCOM's VOIP solution

Change-Id: I1150f536fa204b535ca4019fdaa84f33f4695d93

audio: define QCOM audio parameters

- Define QCOM audio paramters for FM, VOIP,
  fluence, SSR, and A2DP

Change-Id: I29d02e37685846f6d4f00dee02e2726b015eaae7

Add ifdefs for QCOM enhanced features

Change-Id: Ic8e5fe6ecc058466ced71030883b1af6c2bc055c
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 @@
       mIsTimed(false),
       mPreviousPriority(ANDROID_PRIORITY_NORMAL),
       mPreviousSchedulingGroup(SP_DEFAULT)
+#ifdef QCOM_HARDWARE
+      ,mAudioFlinger(NULL),
+      mObserver(NULL)
+#endif
 {
 }
 
@@ -114,6 +122,10 @@
       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 @@
     : 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 @@
       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 @@
             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 @@
         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 @@
     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);
-
-    if (status != NO_ERROR) {
-        if (mAudioTrackThread != 0) {
-            mAudioTrackThread->requestExit();
-            mAudioTrackThread.clear();
+#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;
         }
-        return status;
+        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();
+            }
+            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 @@
 
 uint32_t AudioTrack::latency() const
 {
+#ifdef QCOM_HARDWARE
+    if(mAudioDirectOutput != -1) {
+        return mAudioFlinger->latency(mAudioDirectOutput);
+    }
+#endif
     return mLatency;
 }
 
@@ -351,6 +441,11 @@
 
 uint32_t AudioTrack::frameCount() const
 {
+#ifdef QCOM_HARDWARE
+    if(mAudioDirectOutput != -1) {
+        return mAudioFlinger->frameCount(mAudioDirectOutput);
+    }
+#endif
     return mCblk->frameCount;
 }
 
@@ -372,6 +467,16 @@
 
 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 @@
 
     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();
+#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
         }
-        if (t != 0) {
-            t->pause();
-        } else {
-            setpriority(PRIO_PROCESS, 0, mPreviousPriority);
-            set_sched_policy(0, mPreviousSchedulingGroup);
-        }
+#endif
     }
 
 }
@@ -469,7 +583,12 @@
 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 @@
     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 @@
     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 @@
 
 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 @@
     }
 
     AutoMutex lock(mLock);
+#ifdef QCOM_HARDWARE
+    if(mAudioDirectOutput != -1) {
+        return mAudioFlinger->sampleRate(mAudioDirectOutput);
+    }
+#endif
     return mCblk->sampleRate;
 }
 
@@ -1076,7 +1224,12 @@
 
 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 @@
     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)