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/include/media/AudioParameter.h b/include/media/AudioParameter.h
index 891bc4b..d29c699 100644
--- a/include/media/AudioParameter.h
+++ b/include/media/AudioParameter.h
@@ -1,5 +1,6 @@
 /*
  * Copyright (C) 2008-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.
@@ -48,6 +49,13 @@
     static const char * const keyFrameCount;
     static const char * const keyInputSource;
     static const char * const keyScreenState;
+#ifdef QCOM_HARDWARE
+    static const char * const keyHandleFm;
+    static const char * const keyVoipCheck;
+    static const char * const keyFluenceType;
+    static const char * const keySSR;
+    static const char * const keyHandleA2dpDevice;
+#endif
 
     String8 toString();
 
diff --git a/include/media/AudioSystem.h b/include/media/AudioSystem.h
index 49e1afc..e66fc3a 100644
--- a/include/media/AudioSystem.h
+++ b/include/media/AudioSystem.h
@@ -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) 2008 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -144,6 +148,9 @@
         INPUT_CLOSED,
         INPUT_CONFIG_CHANGED,
         STREAM_CONFIG_CHANGED,
+#ifdef QCOM_HARDWARE
+        EFFECT_CONFIG_CHANGED,
+#endif
         NUM_CONFIG_EVENTS
     };
 
diff --git a/include/media/AudioTrack.h b/include/media/AudioTrack.h
index 34108b3..77a0b26 100644
--- a/include/media/AudioTrack.h
+++ b/include/media/AudioTrack.h
@@ -31,6 +31,10 @@
 #include <cutils/sched_policy.h>
 #include <utils/threads.h>
 
+#ifdef QCOM_HARDWARE
+#include <media/IDirectTrackClient.h>
+#endif
+
 namespace android {
 
 // ----------------------------------------------------------------------------
@@ -39,7 +43,11 @@
 
 // ----------------------------------------------------------------------------
 
-class AudioTrack : virtual public RefBase
+class AudioTrack :
+#ifdef QCOM_HARDWARE
+                   public BnDirectTrackClient,
+#endif
+                   virtual public RefBase
 {
 public:
     enum channel_index {
@@ -451,6 +459,11 @@
      */
             status_t dump(int fd, const Vector<String16>& args) const;
 
+#ifdef QCOM_HARDWARE
+            virtual void notify(int msg);
+            virtual status_t getTimeStamp(uint64_t *tstamp);
+#endif
+
 protected:
     /* copying audio tracks is not allowed */
                         AudioTrack(const AudioTrack& other);
@@ -496,6 +509,9 @@
             status_t restoreTrack_l(audio_track_cblk_t*& cblk, bool fromStart);
             bool stopped_l() const { return !mActive; }
 
+#ifdef QCOM_HARDWARE
+    sp<IDirectTrack>        mDirectTrack;
+#endif
     sp<IAudioTrack>         mAudioTrack;
     sp<IMemory>             mCblkMemory;
     sp<AudioTrackThread>    mAudioTrackThread;
@@ -529,10 +545,17 @@
     uint32_t                mUpdatePeriod;
     bool                    mFlushed; // FIXME will be made obsolete by making flush() synchronous
     audio_output_flags_t    mFlags;
+#ifdef QCOM_HARDWARE
+    sp<IAudioFlinger>       mAudioFlinger;
+    audio_io_handle_t       mAudioDirectOutput;
+#endif
     int                     mSessionId;
     int                     mAuxEffectId;
     mutable Mutex           mLock;
     status_t                mRestoreStatus;
+#ifdef QCOM_HARDWARE
+    void*                   mObserver;
+#endif
     bool                    mIsTimed;
     int                     mPreviousPriority;          // before start()
     SchedPolicy             mPreviousSchedulingGroup;
diff --git a/include/media/IAudioFlinger.h b/include/media/IAudioFlinger.h
index 5170a87..c895c13 100644
--- a/include/media/IAudioFlinger.h
+++ b/include/media/IAudioFlinger.h
@@ -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) 2007 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -24,6 +28,10 @@
 #include <utils/RefBase.h>
 #include <utils/Errors.h>
 #include <binder/IInterface.h>
+#ifdef QCOM_HARDWARE
+#include <media/IDirectTrack.h>
+#include <media/IDirectTrackClient.h>
+#endif
 #include <media/IAudioTrack.h>
 #include <media/IAudioRecord.h>
 #include <media/IAudioFlingerClient.h>
@@ -69,6 +77,21 @@
                                 int *sessionId,
                                 status_t *status) = 0;
 
+#ifdef QCOM_HARDWARE
+    /* create a direct audio track and registers it with AudioFlinger.
+     * return null if the track cannot be created.
+     */
+    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) = 0;
+#endif
+
     virtual sp<IAudioRecord> openRecord(
                                 pid_t pid,
                                 audio_io_handle_t input,
diff --git a/include/media/IDirectTrack.h b/include/media/IDirectTrack.h
new file mode 100644
index 0000000..c1f4f09
--- /dev/null
+++ b/include/media/IDirectTrack.h
@@ -0,0 +1,93 @@
+/*
+ * 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) 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 ANDROID_IDIRECTTRACK_H
+#define ANDROID_IDIRECTTRACK_H
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <utils/RefBase.h>
+#include <utils/Errors.h>
+#include <binder/IInterface.h>
+#include <binder/IMemory.h>
+
+
+namespace android {
+
+// ----------------------------------------------------------------------------
+
+class IDirectTrack : public IInterface
+{
+public:
+    DECLARE_META_INTERFACE(DirectTrack);
+
+    /* After it's created the track is not active. Call start() to
+     * make it active. If set, the callback will start being called.
+     */
+    virtual status_t    start() = 0;
+
+    /* Stop a track. If set, the callback will cease being called and
+     * obtainBuffer will return an error. Buffers that are already released
+     * will be processed, unless flush() is called.
+     */
+    virtual void        stop() = 0;
+
+    /* flush a stopped track. All pending buffers are discarded.
+     * This function has no effect if the track is not stoped.
+     */
+    virtual void        flush() = 0;
+
+    /* mute or unmutes this track.
+     * While mutted, the callback, if set, is still called.
+     */
+    virtual void        mute(bool) = 0;
+
+    /* Pause a track. If set, the callback will cease being called and
+     * obtainBuffer will return an error. Buffers that are already released
+     * will be processed, unless flush() is called.
+     */
+    virtual void        pause() = 0;
+
+    /* set volume for both left and right channels.
+     */
+    virtual void        setVolume(float l, float r) = 0;
+
+    virtual ssize_t     write(const void*, size_t) =  0;
+
+    virtual int64_t     getTimeStamp() =  0;
+};
+
+// ----------------------------------------------------------------------------
+
+class BnDirectTrack : public BnInterface<IDirectTrack>
+{
+public:
+    virtual status_t    onTransact( uint32_t code,
+                                    const Parcel& data,
+                                    Parcel* reply,
+                                    uint32_t flags = 0);
+};
+
+// ----------------------------------------------------------------------------
+
+}; // namespace android
+
+#endif // ANDROID_IAUDIOTRACK_H
diff --git a/include/media/IDirectTrackClient.h b/include/media/IDirectTrackClient.h
new file mode 100644
index 0000000..9383690
--- /dev/null
+++ b/include/media/IDirectTrackClient.h
@@ -0,0 +1,51 @@
+/*
+ * 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) 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 ANDROID_IDIRECTTRACKCLIENT_H
+#define ANDROID_IDIRECTTRACKCLIENT_H
+
+#include <utils/RefBase.h>
+#include <binder/IInterface.h>
+#include <binder/Parcel.h>
+
+namespace android {
+
+class IDirectTrackClient: public IInterface
+{
+public:
+    DECLARE_META_INTERFACE(DirectTrackClient);
+
+    virtual void notify(int msg) = 0;
+};
+
+// ----------------------------------------------------------------------------
+
+class BnDirectTrackClient: public BnInterface<IDirectTrackClient>
+{
+public:
+    virtual status_t    onTransact( uint32_t code,
+                                    const Parcel& data,
+                                    Parcel* reply,
+                                    uint32_t flags = 0);
+};
+
+}; // namespace android
+
+#endif // ANDROID_IDIRECTTRACKCLIENT_H
diff --git a/include/media/MediaPlayerInterface.h b/include/media/MediaPlayerInterface.h
index b7bee3f..a7570d6 100644
--- a/include/media/MediaPlayerInterface.h
+++ b/include/media/MediaPlayerInterface.h
@@ -110,6 +110,10 @@
 
         virtual status_t    setPlaybackRatePermille(int32_t rate) { return INVALID_OPERATION; }
         virtual bool        needsTrailingPadding() { return true; }
+#ifdef QCOM_HARDWARE
+        virtual ssize_t     sampleRate() const {return 0;};
+        virtual status_t    getTimeStamp(uint64_t *tstamp) {return 0;};
+#endif
     };
 
                         MediaPlayerBase() : mCookie(0), mNotify(0) {}
diff --git a/include/media/MediaProfiles.h b/include/media/MediaProfiles.h
index 60d6bef..0df9fd4 100644
--- a/include/media/MediaProfiles.h
+++ b/include/media/MediaProfiles.h
@@ -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.
@@ -461,6 +462,10 @@
     static VideoEncoderCap* createDefaultH263VideoEncoderCap();
     static VideoEncoderCap* createDefaultM4vVideoEncoderCap();
     static AudioEncoderCap* createDefaultAmrNBEncoderCap();
+#ifdef QCOM_HARDWARE
+    static AudioEncoderCap* createDefaultAacEncoderCap();
+    static AudioEncoderCap* createDefaultLpcmEncoderCap();
+#endif
 
     static int findTagForName(const NameToTagMap *map, size_t nMappings, const char *name);
 
diff --git a/include/media/mediarecorder.h b/include/media/mediarecorder.h
index 3c2e700..6dfa5d9 100644
--- a/include/media/mediarecorder.h
+++ b/include/media/mediarecorder.h
@@ -1,5 +1,6 @@
 /*
  ** Copyright (C) 2008 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.
@@ -67,6 +68,12 @@
     /* H.264/AAC data encapsulated in MPEG2/TS */
     OUTPUT_FORMAT_MPEG2TS = 8,
 
+#ifdef QCOM_HARDWARE
+    OUTPUT_FORMAT_QCP = 9, // QCP file format
+    OUTPUT_FORMAT_THREE_GPP2 = 10, /*3GPP2*/
+    OUTPUT_FORMAT_WAVE = 11, /*WAVE*/
+#endif
+
     OUTPUT_FORMAT_LIST_END // must be last - used to validate format type
 };
 
@@ -77,6 +84,11 @@
     AUDIO_ENCODER_AAC = 3,
     AUDIO_ENCODER_HE_AAC = 4,
     AUDIO_ENCODER_AAC_ELD = 5,
+#ifdef QCOM_HARDWARE
+    AUDIO_ENCODER_EVRC = 6,
+    AUDIO_ENCODER_QCELP = 7,
+    AUDIO_ENCODER_LPCM = 8,
+#endif
 
     AUDIO_ENCODER_LIST_END // must be the last - used to validate the audio encoder type
 };
diff --git a/include/media/stagefright/AudioPlayer.h b/include/media/stagefright/AudioPlayer.h
index 1dc408f..624fe3e 100644
--- a/include/media/stagefright/AudioPlayer.h
+++ b/include/media/stagefright/AudioPlayer.h
@@ -43,27 +43,27 @@
     virtual ~AudioPlayer();
 
     // Caller retains ownership of "source".
-    void setSource(const sp<MediaSource> &source);
+    virtual void setSource(const sp<MediaSource> &source);
 
     // Return time in us.
     virtual int64_t getRealTimeUs();
 
-    status_t start(bool sourceAlreadyStarted = false);
+    virtual status_t start(bool sourceAlreadyStarted = false);
 
-    void pause(bool playPendingSamples = false);
-    void resume();
+    virtual void pause(bool playPendingSamples = false);
+    virtual void resume();
 
     // Returns the timestamp of the last buffer played (in us).
-    int64_t getMediaTimeUs();
+    virtual int64_t getMediaTimeUs();
 
     // Returns true iff a mapping is established, i.e. the AudioPlayer
     // has played at least one frame of audio.
-    bool getMediaTimeMapping(int64_t *realtime_us, int64_t *mediatime_us);
+    virtual bool getMediaTimeMapping(int64_t *realtime_us, int64_t *mediatime_us);
 
-    status_t seekTo(int64_t time_us);
+    virtual status_t seekTo(int64_t time_us);
 
-    bool isSeeking();
-    bool reachedEOS(status_t *finalStatus);
+    virtual bool isSeeking();
+    virtual bool reachedEOS(status_t *finalStatus);
 
     status_t setPlaybackRatePermille(int32_t ratePermille);
 
@@ -91,6 +91,9 @@
     int64_t mSeekTimeUs;
 
     bool mStarted;
+#ifdef QCOM_HARDWARE
+    bool mSourcePaused;
+#endif
 
     bool mIsFirstBuffer;
     status_t mFirstBufferResult;
diff --git a/include/media/stagefright/ExtendedWriter.h b/include/media/stagefright/ExtendedWriter.h
new file mode 100644
index 0000000..23944b0
--- /dev/null
+++ b/include/media/stagefright/ExtendedWriter.h
@@ -0,0 +1,143 @@
+/*
+ * 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
+ *
+ *      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 EXTENDED_WRITER_H_
+
+#define EXTENDED_WRITER_H_
+
+#include <stdio.h>
+
+#include <media/stagefright/MediaWriter.h>
+#include <utils/threads.h>
+#include <cutils/log.h>
+
+#define LITERAL_TO_STRING_INTERNAL(x)    #x
+#define LITERAL_TO_STRING(x) LITERAL_TO_STRING_INTERNAL(x)
+
+#define CHECK_EQ(x,y)                                                   \
+    LOG_ALWAYS_FATAL_IF(                                                \
+            (x) != (y),                                                 \
+            __FILE__ ":" LITERAL_TO_STRING(__LINE__) " " #x " != " #y)
+
+#define CHECK(x)                                                        \
+    LOG_ALWAYS_FATAL_IF(                                                \
+            !(x),                                                       \
+            __FILE__ ":" LITERAL_TO_STRING(__LINE__) " " #x)
+
+namespace android {
+
+struct MediaSource;
+struct MetaData;
+
+struct ExtendedWriter : public MediaWriter {
+    ExtendedWriter(const char *filename);
+    ExtendedWriter(int fd);
+
+    status_t initCheck() const;
+
+    virtual status_t addSource(const sp<MediaSource> &source);
+    virtual bool reachedEOS();
+    virtual status_t start(MetaData *params = NULL);
+    virtual status_t stop();
+    virtual status_t pause();
+
+protected:
+    virtual ~ExtendedWriter();
+
+private:
+    FILE *mFile;
+    status_t mInitCheck;
+    sp<MediaSource> mSource;
+    bool mStarted;
+    volatile bool mPaused;
+    volatile bool mResumed;
+    volatile bool mDone;
+    volatile bool mReachedEOS;
+    pthread_t mThread;
+    int64_t mEstimatedSizeBytes;
+    int64_t mEstimatedDurationUs;
+
+    int32_t mFormat;
+
+    //QCP/EVRC header
+    struct QCPEVRCHeader
+    {
+        /* RIFF Section */
+        char riff[4];
+        unsigned int s_riff;
+        char qlcm[4];
+
+        /* Format chunk */
+        char fmt[4];
+        unsigned int s_fmt;
+        char mjr;
+        char mnr;
+        unsigned int data1;
+
+        /* UNIQUE ID of the codec */
+        unsigned short data2;
+        unsigned short data3;
+        char data4[8];
+        unsigned short ver;
+
+        /* Codec Info */
+        char name[80];
+        unsigned short abps;
+
+        /* average bits per sec of the codec */
+        unsigned short bytes_per_pkt;
+        unsigned short samp_per_block;
+        unsigned short samp_per_sec;
+        unsigned short bits_per_samp;
+        unsigned char vr_num_of_rates;
+
+        /* Rate Header fmt info */
+        unsigned char rvd1[3];
+        unsigned short vr_bytes_per_pkt[8];
+        unsigned int rvd2[5];
+
+        /* Vrat chunk */
+        unsigned char vrat[4];
+        unsigned int s_vrat;
+        unsigned int v_rate;
+        unsigned int size_in_pkts;
+
+        /* Data chunk */
+        unsigned char data[4];
+        unsigned int s_data;
+    } __attribute__ ((packed));
+
+    struct QCPEVRCHeader mHeader;
+    off_t mOffset; //note off_t
+
+    static void *ThreadWrapper(void *);
+    status_t threadFunc();
+    bool exceedsFileSizeLimit();
+    bool exceedsFileDurationLimit();
+
+    ExtendedWriter(const ExtendedWriter &);
+    ExtendedWriter &operator=(const ExtendedWriter &);
+
+    status_t writeQCPHeader( );
+    status_t writeEVRCHeader( );
+};
+
+}  // namespace android
+
+#endif  // AMR_WRITER_H_
diff --git a/include/media/stagefright/LPAPlayer.h b/include/media/stagefright/LPAPlayer.h
new file mode 100644
index 0000000..c351211
--- /dev/null
+++ b/include/media/stagefright/LPAPlayer.h
@@ -0,0 +1,290 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ * Copyright (c) 2009-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
+ *
+ *      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 LPA_PLAYER_H_
+
+#define LPA_PLAYER_H_
+
+#include "AudioPlayer.h"
+#include <media/IAudioFlinger.h>
+#include <utils/threads.h>
+#include <utils/List.h>
+#include <utils/Vector.h>
+#include <fcntl.h>
+#include <pthread.h>
+#include <binder/IServiceManager.h>
+#include <linux/unistd.h>
+#include <include/TimedEventQueue.h>
+#include <binder/BinderService.h>
+#include <binder/MemoryDealer.h>
+#include <powermanager/IPowerManager.h>
+
+// Pause timeout = 3sec
+#define LPA_PAUSE_TIMEOUT_USEC 3000000
+
+namespace android {
+
+class LPAPlayer : public AudioPlayer  {
+public:
+    enum {
+        REACHED_EOS,
+        SEEK_COMPLETE
+    };
+
+    enum {
+        TRACK_DIRECT,
+        TRACK_REGULAR,
+        TRACK_NONE
+    };
+
+    LPAPlayer(const sp<MediaPlayerBase::AudioSink> &audioSink, bool &initCheck,
+                AwesomePlayer *audioObserver = NULL);
+
+    virtual ~LPAPlayer();
+
+    // Caller retains ownership of "source".
+    virtual void setSource(const sp<MediaSource> &source);
+
+    // Return time in us.
+    virtual int64_t getRealTimeUs();
+
+    virtual status_t start(bool sourceAlreadyStarted = false);
+
+    virtual void pause(bool playPendingSamples = false);
+    virtual void resume();
+
+    // Returns the timestamp of the last buffer played (in us).
+    virtual int64_t getMediaTimeUs();
+
+    // Returns true iff a mapping is established, i.e. the LPAPlayer
+    // has played at least one frame of audio.
+    virtual bool getMediaTimeMapping(int64_t *realtime_us, int64_t *mediatime_us);
+
+    virtual status_t seekTo(int64_t time_us);
+
+    virtual bool isSeeking();
+    virtual bool reachedEOS(status_t *finalStatus);
+
+    static int objectsAlive;
+private:
+    int64_t mPositionTimeMediaUs;
+    int64_t mPositionTimeRealUs;
+    bool mInternalSeeking;
+    bool mIsAudioRouted;
+    bool mStarted;
+    bool mPaused;
+    bool mA2DPEnabled;
+    int32_t mChannelMask;
+    int32_t numChannels;
+    int32_t mSampleRate;
+    int64_t mLatencyUs;
+    size_t mFrameSize;
+    int64_t mTimeStarted;
+    int64_t mTimePlayed;
+    int64_t mNumFramesPlayed;
+    int64_t mNumFramesPlayedSysTimeUs;
+    int64_t mNumA2DPBytesPlayed;
+
+    void clearPowerManager();
+
+    class PMDeathRecipient : public IBinder::DeathRecipient {
+        public:
+                        PMDeathRecipient(void *obj){parentClass = (LPAPlayer *)obj;}
+            virtual     ~PMDeathRecipient() {}
+
+            // IBinder::DeathRecipient
+            virtual     void        binderDied(const wp<IBinder>& who);
+
+        private:
+                        LPAPlayer *parentClass;
+                        PMDeathRecipient(const PMDeathRecipient&);
+                        PMDeathRecipient& operator = (const PMDeathRecipient&);
+
+        friend class LPAPlayer;
+    };
+
+    friend class PMDeathRecipient;
+
+    void        acquireWakeLock();
+    void        releaseWakeLock();
+
+    sp<IPowerManager>       mPowerManager;
+    sp<IBinder>             mWakeLockToken;
+    sp<PMDeathRecipient>    mDeathRecipient;
+
+    pthread_t decoderThread;
+
+    pthread_t A2DPNotificationThread;
+
+    //Kill Thread boolean
+    bool killDecoderThread;
+
+
+
+    bool killA2DPNotificationThread;
+
+    //Thread alive boolean
+    bool decoderThreadAlive;
+
+
+    bool a2dpNotificationThreadAlive;
+
+    //Declare the condition Variables and Mutex
+
+    pthread_mutex_t decoder_mutex;
+
+    pthread_mutex_t audio_sink_setup_mutex;
+
+    pthread_mutex_t a2dp_notification_mutex;
+
+
+
+    pthread_cond_t decoder_cv;
+
+
+    pthread_cond_t a2dp_notification_cv;
+
+
+    // make sure Decoder thread has exited
+    void requestAndWaitForDecoderThreadExit();
+
+
+    // make sure the Effects thread also exited
+    void requestAndWaitForA2DPNotificationThreadExit();
+
+    static void *decoderThreadWrapper(void *me);
+    void decoderThreadEntry();
+    static void *A2DPNotificationThreadWrapper(void *me);
+    void A2DPNotificationThreadEntry();
+
+    void createThreads();
+
+    volatile bool mIsA2DPEnabled;
+
+    //Structure to recieve the BT notification from the flinger.
+    class AudioFlingerLPAdecodeClient: public IBinder::DeathRecipient, public BnAudioFlingerClient {
+    public:
+        AudioFlingerLPAdecodeClient(void *obj);
+
+        LPAPlayer *pBaseClass;
+        // DeathRecipient
+        virtual void binderDied(const wp<IBinder>& who);
+
+        // IAudioFlingerClient
+
+        // indicate a change in the configuration of an output or input: keeps the cached
+        // values for output/input parameters upto date in client process
+        virtual void ioConfigChanged(int event, audio_io_handle_t ioHandle, const void *param2);
+
+        friend class LPAPlayer;
+    };
+
+    sp<IAudioFlinger> mAudioFlinger;
+
+    // helper function to obtain AudioFlinger service handle
+    void getAudioFlinger();
+
+    void handleA2DPSwitch();
+    void onPauseTimeOut();
+
+    sp<AudioFlingerLPAdecodeClient> AudioFlingerClient;
+    friend class AudioFlingerLPAdecodeClient;
+    Mutex AudioFlingerLock;
+    sp<MediaSource> mSource;
+
+    MediaBuffer *mInputBuffer;
+
+    Mutex mLock;
+    Mutex mResumeLock;
+
+    bool mSeeking;
+    bool mReachedEOS;
+    bool mReachedOutputEOS;
+    status_t mFinalStatus;
+    int64_t mSeekTimeUs;
+    int64_t mPauseTime;
+
+
+    bool mIsFirstBuffer;
+    status_t mFirstBufferResult;
+    MediaBuffer *mFirstBuffer;
+    TimedEventQueue mQueue;
+    bool            mQueueStarted;
+    sp<TimedEventQueue::Event>  mPauseEvent;
+    bool                        mPauseEventPending;
+
+    sp<MediaPlayerBase::AudioSink> mAudioSink;
+    AwesomePlayer *mObserver;
+    int mTrackType;
+
+    static size_t AudioSinkCallback(
+        MediaPlayerBase::AudioSink *audioSink,
+        void *data, size_t size, void *me);
+
+    enum A2DPState {
+        A2DP_ENABLED,
+        A2DP_DISABLED,
+        A2DP_CONNECT,
+        A2DP_DISCONNECT
+    };
+
+    int64_t getTimeStamp(A2DPState state);
+
+    size_t fillBuffer(void *data, size_t size);
+
+    int64_t getRealTimeUsLocked();
+
+    void reset();
+
+    status_t setupAudioSink();
+    static size_t AudioCallback(
+        MediaPlayerBase::AudioSink *audioSink,
+        void *buffer, size_t size, void *cookie);
+    size_t AudioCallback(void *cookie, void *data, size_t size);
+
+    LPAPlayer(const LPAPlayer &);
+    LPAPlayer &operator=(const LPAPlayer &);
+};
+
+struct TimedEvent : public TimedEventQueue::Event {
+    TimedEvent(LPAPlayer *player,
+               void (LPAPlayer::*method)())
+        : mPlayer(player),
+          mMethod(method) {
+    }
+
+protected:
+    virtual ~TimedEvent() {}
+
+    virtual void fire(TimedEventQueue *queue, int64_t /* now_us */) {
+        (mPlayer->*mMethod)();
+    }
+
+private:
+    LPAPlayer *mPlayer;
+    void (LPAPlayer::*mMethod)();
+
+    TimedEvent(const TimedEvent &);
+    TimedEvent &operator=(const TimedEvent &);
+};
+
+}  // namespace android
+
+#endif  // LPA_PLAYER_H_
+
diff --git a/include/media/stagefright/OMXCodec.h b/include/media/stagefright/OMXCodec.h
index 2439be6..aad8844 100644
--- a/include/media/stagefright/OMXCodec.h
+++ b/include/media/stagefright/OMXCodec.h
@@ -1,5 +1,6 @@
 /*
  * Copyright (C) 2009 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.
@@ -22,6 +23,9 @@
 #include <media/IOMX.h>
 #include <media/stagefright/MediaBuffer.h>
 #include <media/stagefright/MediaSource.h>
+#ifdef QCOM_HARDWARE
+#include <media/stagefright/QCOMXCodec.h>
+#endif
 #include <utils/threads.h>
 
 #include <OMX_Audio.h>
@@ -100,6 +104,10 @@
         kSupportsMultipleFramesPerInputBuffer = 1024,
         kRequiresLargerEncoderOutputBuffer    = 2048,
         kOutputBuffersAreUnreadable           = 4096,
+#ifdef QCOM_HARDWARE
+        kRequiresGlobalFlush                  = 0x20000000, // 2^29
+        kRequiresWMAProComponent              = 0x40000000, //2^30
+#endif
     };
 
     struct CodecNameAndQuirks {
@@ -127,6 +135,11 @@
     // Make sure mLock is accessible to OMXCodecObserver
     friend class OMXCodecObserver;
 
+#ifdef QCOM_HARDWARE
+    // QCOMXCodec can access variables of OMXCodec
+    friend class QCOMXCodec;
+#endif
+
     // Call this with mLock hold
     void on_message(const omx_message &msg);
 
@@ -143,6 +156,9 @@
     };
 
     enum {
+#ifdef QCOM_HARDWARE
+        kPortIndexBoth   = -1,
+#endif
         kPortIndexInput  = 0,
         kPortIndexOutput = 1
     };
@@ -250,6 +266,11 @@
 
     void setG711Format(int32_t numChannels);
 
+#ifdef QCOM_HARDWARE
+    void setEVRCFormat( int32_t sampleRate, int32_t numChannels, int32_t bitRate);
+    void setQCELPFormat( int32_t sampleRate, int32_t numChannels, int32_t bitRate);
+#endif
+
     status_t setVideoPortFormatType(
             OMX_U32 portIndex,
             OMX_VIDEO_CODINGTYPE compressionFormat,
@@ -361,6 +382,11 @@
 
     OMXCodec(const OMXCodec &);
     OMXCodec &operator=(const OMXCodec &);
+
+#ifdef QCOM_HARDWARE
+    status_t setWMAFormat(const sp<MetaData> &inputFormat);
+    void setAC3Format(int32_t numChannels, int32_t sampleRate);
+#endif
 };
 
 struct CodecCapabilities {
diff --git a/include/media/stagefright/QCOMXCodec.h b/include/media/stagefright/QCOMXCodec.h
new file mode 100644
index 0000000..7259af9
--- /dev/null
+++ b/include/media/stagefright/QCOMXCodec.h
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 2012, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *     * Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ *       copyright notice, this list of conditions and the following
+ *       disclaimer in the documentation and/or other materials provided
+ *      with the distribution.
+ *     * Neither the name of The Linux Foundation nor the names of its
+ *      contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef QC_OMX_CODEC_H_
+
+#define QC_OMX_CODEC_H_
+
+#include <android/native_window.h>
+#include <media/IOMX.h>
+#include <media/stagefright/MediaBuffer.h>
+#include <media/stagefright/MediaSource.h>
+#include <media/stagefright/foundation/AString.h>
+#include <utils/threads.h>
+
+#include <OMX_Audio.h>
+
+namespace android {
+
+struct MediaCodecList;
+struct OMXCodec;
+
+enum{
+    kRequiresWMAProComponent = 0x40000000,
+};
+
+
+struct QCOMXCodec {
+
+    static uint32_t getQCComponentQuirks(const MediaCodecList *list, size_t index);
+
+    static status_t configureDIVXCodec(const sp<MetaData> &meta, char* mime,
+                          sp<IOMX> OMXhandle,IOMX::node_id nodeID, int port_index);
+
+    static status_t setQCFormat(const sp<MetaData> &meta, char* mime,
+                                sp<IOMX> OMXhandle,IOMX::node_id nodeID,
+                                       OMXCodec *handle, bool isEncoder);
+
+    static status_t setWMAFormat(const sp<MetaData> &meta, sp<IOMX> OMXhandle,
+                                        IOMX::node_id nodeID, bool isEncoder );
+
+    static status_t setQCVideoInputFormat(const char *mime,
+                                          OMX_VIDEO_CODINGTYPE *compressionFormat);
+
+    static status_t setQCVideoOutputFormat(const char *mime,
+                                           OMX_VIDEO_CODINGTYPE *compressionFormat);
+
+    static status_t checkQCFormats(int format, AString* meta);
+
+    static void     setASFQuirks(uint32_t quirks, const sp<MetaData> &meta,
+                                                 const char* componentName);
+
+    static void     checkAndAddRawFormat(OMXCodec *handle, const sp<MetaData> &meta);
+
+    static void     setEVRCFormat(int32_t numChannels, int32_t sampleRate,
+                                  sp<IOMX> OMXhandle, IOMX::node_id nodeID,
+                                        OMXCodec *handle,  bool isEncoder );
+
+    static void     setQCELPFormat(int32_t numChannels, int32_t sampleRate,
+                                   sp<IOMX> OMXhandle, IOMX::node_id nodeID,
+                                         OMXCodec *handle,  bool isEncoder );
+
+    static void     setAC3Format(int32_t numChannels, int32_t sampleRate,
+                                 sp<IOMX> OMXhandle, IOMX::node_id nodeID);
+
+    static void     checkQCRole(const sp<IOMX> &omx, IOMX::node_id node,
+                                        bool isEncoder,const char *mime);
+
+};
+
+}
+#endif /*QC_OMX_CODEC_H_ */
+
diff --git a/include/media/stagefright/TunnelPlayer.h b/include/media/stagefright/TunnelPlayer.h
new file mode 100644
index 0000000..71c4f10
--- /dev/null
+++ b/include/media/stagefright/TunnelPlayer.h
@@ -0,0 +1,251 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Copyright (c) 2009-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
+ *
+ *      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 TUNNEL_PLAYER_H_
+
+#define TUNNEL_PLAYER_H_
+
+#include "AudioPlayer.h"
+#include <media/IAudioFlinger.h>
+#include <utils/threads.h>
+#include <utils/List.h>
+#include <utils/Vector.h>
+#include <fcntl.h>
+#include <pthread.h>
+#include <binder/IServiceManager.h>
+#include <linux/unistd.h>
+#include <include/TimedEventQueue.h>
+#include <binder/BinderService.h>
+#include <binder/MemoryDealer.h>
+#include <powermanager/IPowerManager.h>
+
+// Pause timeout = 3sec
+#define TUNNEL_PAUSE_TIMEOUT_USEC 3000000
+namespace android {
+
+class TunnelPlayer : public AudioPlayer  {
+public:
+    enum {
+        REACHED_EOS,
+        SEEK_COMPLETE
+    };
+
+    TunnelPlayer(const sp<MediaPlayerBase::AudioSink> &audioSink, bool &initCheck,
+                AwesomePlayer *audioObserver = NULL, bool hasVideo = false);
+
+    virtual ~TunnelPlayer();
+
+    // Caller retains ownership of "source".
+    virtual void setSource(const sp<MediaSource> &source);
+
+    // Return time in us.
+    virtual int64_t getRealTimeUs();
+
+    virtual status_t start(bool sourceAlreadyStarted = false);
+
+    virtual void pause(bool playPendingSamples = false);
+    virtual void resume();
+
+    // Returns the timestamp of the last buffer played (in us).
+    virtual int64_t getMediaTimeUs();
+
+    // Returns true iff a mapping is established, i.e. the TunnelPlayer
+    // has played at least one frame of audio.
+    virtual bool getMediaTimeMapping(int64_t *realtime_us, int64_t *mediatime_us);
+
+    virtual status_t seekTo(int64_t time_us);
+
+    virtual bool isSeeking();
+    virtual bool reachedEOS(status_t *finalStatus);
+
+
+    static int mTunnelObjectsAlive;
+private:
+    int64_t mPositionTimeMediaUs;
+    int64_t mPositionTimeRealUs;
+    bool mInternalSeeking;
+    bool mIsAudioRouted;
+    bool mStarted;
+    bool mPaused;
+    bool mA2DPEnabled;
+    int32_t mChannelMask;
+    int32_t numChannels;
+    int32_t mSampleRate;
+    int64_t mLatencyUs;
+    size_t mFrameSize;
+    int64_t mNumFramesPlayed;
+    int64_t mNumFramesPlayedSysTimeUs;
+    audio_format_t mFormat;
+    bool mHasVideo;
+    void clearPowerManager();
+
+    class PMDeathRecipient : public IBinder::DeathRecipient {
+        public:
+                        PMDeathRecipient(void *obj){parentClass = (TunnelPlayer *)obj;}
+            virtual     ~PMDeathRecipient() {}
+
+            // IBinder::DeathRecipient
+            virtual     void        binderDied(const wp<IBinder>& who);
+
+        private:
+                        TunnelPlayer *parentClass;
+                        PMDeathRecipient(const PMDeathRecipient&);
+                        PMDeathRecipient& operator = (const PMDeathRecipient&);
+
+        friend class TunnelPlayer;
+    };
+
+    friend class PMDeathRecipient;
+
+    void        acquireWakeLock();
+    void        releaseWakeLock();
+
+    sp<IPowerManager>       mPowerManager;
+    sp<IBinder>             mWakeLockToken;
+    sp<PMDeathRecipient>    mDeathRecipient;
+
+    pthread_t extractorThread;
+
+    //Kill Thread boolean
+    bool killExtractorThread;
+
+    //Thread alive boolean
+    bool extractorThreadAlive;
+
+
+    //Declare the condition Variables and Mutex
+
+    pthread_mutex_t extractor_mutex;
+    pthread_cond_t extractor_cv;
+
+
+    // make sure Decoder thread has exited
+    void requestAndWaitForExtractorThreadExit();
+
+
+    static void *extractorThreadWrapper(void *me);
+    void extractorThreadEntry();
+
+    void createThreads();
+
+    volatile bool mIsA2DPEnabled;
+
+    //Structure to recieve the BT notification from the flinger.
+    class AudioFlingerTunneldecodeClient: public IBinder::DeathRecipient, public BnAudioFlingerClient {
+    public:
+        AudioFlingerTunneldecodeClient(void *obj);
+
+        TunnelPlayer *pBaseClass;
+        // DeathRecipient
+        virtual void binderDied(const wp<IBinder>& who);
+
+        // IAudioFlingerClient
+
+        // indicate a change in the configuration of an output or input: keeps the cached
+        // values for output/input parameters upto date in client process
+        virtual void ioConfigChanged(int event, audio_io_handle_t ioHandle, const void *param2);
+
+        friend class TunnelPlayer;
+    };
+
+    sp<IAudioFlinger> mAudioFlinger;
+
+    // helper function to obtain AudioFlinger service handle
+    void getAudioFlinger();
+    void onPauseTimeOut();
+
+    sp<AudioFlingerTunneldecodeClient> mAudioFlingerClient;
+    friend class AudioFlingerTunneldecodeClient;
+    Mutex mAudioFlingerLock;
+    sp<MediaSource> mSource;
+
+    MediaBuffer *mInputBuffer;
+
+    Mutex pmLock;
+    Mutex mLock;
+
+    bool mSeeking;
+    bool mReachedEOS;
+    bool mReachedOutputEOS;
+    status_t mFinalStatus;
+    int64_t mSeekTimeUs;
+    int64_t mPauseTime;
+
+
+    bool mIsFirstBuffer;
+    status_t mFirstBufferResult;
+    MediaBuffer *mFirstBuffer;
+    TimedEventQueue mQueue;
+    bool            mQueueStarted;
+    sp<TimedEventQueue::Event>  mPauseEvent;
+    bool                        mPauseEventPending;
+
+    sp<MediaPlayerBase::AudioSink> mAudioSink;
+    AwesomePlayer *mObserver;
+
+    static size_t AudioSinkCallback(
+        MediaPlayerBase::AudioSink *audioSink,
+        void *data, size_t size, void *me);
+
+    enum A2DPState {
+        A2DP_ENABLED,
+        A2DP_DISABLED,
+        A2DP_CONNECT,
+        A2DP_DISCONNECT
+    };
+
+    int64_t getTimeStamp(A2DPState state);
+
+    size_t fillBuffer(void *data, size_t size);
+
+    int64_t getRealTimeUsLocked();
+
+    void reset();
+
+    TunnelPlayer(const TunnelPlayer &);
+    TunnelPlayer &operator=(const TunnelPlayer &);
+};
+
+struct TunnelEvent : public TimedEventQueue::Event {
+    TunnelEvent(TunnelPlayer *player,
+               void (TunnelPlayer::*method)())
+        : mPlayer(player),
+          mMethod(method) {
+    }
+
+protected:
+    virtual ~TunnelEvent() {}
+
+    virtual void fire(TimedEventQueue *queue, int64_t /* now_us */) {
+        (mPlayer->*mMethod)();
+    }
+
+private:
+    TunnelPlayer *mPlayer;
+    void (TunnelPlayer::*mMethod)();
+
+    TunnelEvent(const TunnelEvent &);
+    TunnelEvent &operator=(const TunnelEvent &);
+};
+
+}  // namespace android
+
+#endif  // LPA_PLAYER_H_
diff --git a/include/media/stagefright/WAVEWriter.h b/include/media/stagefright/WAVEWriter.h
new file mode 100644
index 0000000..766d8f4
--- /dev/null
+++ b/include/media/stagefright/WAVEWriter.h
@@ -0,0 +1,108 @@
+/*
+ * Copyright (c) 2012, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ *       copyright notice, this list of conditions and the following
+ *       disclaimer in the documentation and/or other materials provided
+ *       with the distribution.
+ *     * Neither the name of The Linux Foundation nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef WAVE_WRITER_H_
+
+#define WAVE_WRITER_H_
+
+#include <stdio.h>
+
+#include <media/stagefright/MediaWriter.h>
+#include <utils/threads.h>
+
+namespace android {
+
+
+#define ID_RIFF 0x46464952
+#define ID_WAVE 0x45564157
+#define ID_FMT  0x20746d66
+#define ID_DATA 0x61746164
+#define FORMAT_PCM 1
+
+
+struct MediaSource;
+struct MetaData;
+
+struct wav_header {
+    uint32_t riff_id;
+    uint32_t riff_sz;
+    uint32_t riff_fmt;
+    uint32_t fmt_id;
+    uint32_t fmt_sz;
+    uint16_t audio_format;
+    uint16_t num_channels;
+    uint32_t sample_rate;
+    uint32_t byte_rate;       /* sample_rate * num_channels * bps / 8 */
+    uint16_t block_align;     /* num_channels * bps / 8 */
+    uint16_t bits_per_sample;
+    uint32_t data_id;
+    uint32_t data_sz;
+};
+
+
+struct WAVEWriter : public MediaWriter {
+    WAVEWriter(const char *filename);
+    WAVEWriter(int fd);
+
+    status_t initCheck() const;
+
+    virtual status_t addSource(const sp<MediaSource> &source);
+    virtual bool reachedEOS();
+    virtual status_t start(MetaData *params = NULL);
+    virtual status_t stop();
+    virtual status_t pause();
+
+protected:
+    virtual ~WAVEWriter();
+
+private:
+    int   mFd;
+    status_t mInitCheck;
+    sp<MediaSource> mSource;
+    bool mStarted;
+    volatile bool mPaused;
+    volatile bool mResumed;
+    volatile bool mDone;
+    volatile bool mReachedEOS;
+    pthread_t mThread;
+    int64_t mEstimatedSizeBytes;
+    int64_t mEstimatedDurationUs;
+
+    static void *ThreadWrapper(void *);
+    status_t threadFunc();
+    bool exceedsFileSizeLimit();
+    bool exceedsFileDurationLimit();
+
+    WAVEWriter(const WAVEWriter &);
+    WAVEWriter &operator=(const WAVEWriter &);
+};
+
+}  // namespace android
+
+#endif  // WAVE_WRITER_H_