Merge tag 'android-6.0.0_r26' into HEAD

Android 6.0.0 release 26

* tag 'android-6.0.0_r26': (104 commits)
  ID3: check possible integer overflow for extendedHeaderSize and paddingSize.
  AudioTrack: Prevent stop() from reissuing last marker event
  Check NAL size before use
  MPEG4Extractor: ensure buffer size is not less than 8 for LastCommentData.
  ID3: check possible integer overflow for extendedHeaderSize and paddingSize.
  Don't crash when there's no conceal frame
  AudioSystem: Fix race condition in accessing ioDescriptors
  OMX: allow only secure codec to remotely call allocateBuffer.
  MPEG4Extractor: ensure buffer size is not less than 8 for LastCommentData.
  Camera3Device: Change HFR request thread priority to 1
  Camera3Device: Bookkeeping reprocess shutters separately
  CameraService: Use SCHED_FIFO for request queue thread in HFR
  CameraService: Use SCHED_FIFO for request queue thread in HFR
  DO NOT MERGE stagefright: fix AMessage::FromParcel
  stagefright: fix AMessage::FromParcel
  stagefright: fix AMessage::FromParcel
  SoftAVCDec: Reduced memory requirements
  AudioPolicyService: fix race in AudioCommandThread
  DO NOT MERGE - Fix build for commit 69ae6a87
  audio policy: fix preemtible capture race
  ...

Conflicts:
	media/libmedia/ICrypto.cpp
	media/libmedia/IEffect.cpp
	media/libmediaplayerservice/nuplayer/GenericSource.cpp
	media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp
	media/libstagefright/DataSource.cpp
	media/libstagefright/OggExtractor.cpp
	media/libstagefright/data/media_codecs_google_video.xml
	media/libstagefright/include/OMXNodeInstance.h
	media/libstagefright/omx/OMXNodeInstance.cpp

Change-Id: I4e64767638a163004031d2ace602360119349bb5
diff --git a/camera/ICameraClient.cpp b/camera/ICameraClient.cpp
index 179a341..4f43796 100644
--- a/camera/ICameraClient.cpp
+++ b/camera/ICameraClient.cpp
@@ -46,7 +46,12 @@
         data.writeInterfaceToken(ICameraClient::getInterfaceDescriptor());
         data.writeInt32(msgType);
         data.writeInt32(ext1);
-        data.writeInt32(ext2);
+        if ((msgType == CAMERA_MSG_PREVIEW_FRAME) && (ext1 == CAMERA_FRAME_DATA_FD)) {
+            ALOGD("notifyCallback: CAMERA_MSG_PREVIEW_FRAME fd = %d", ext2);
+            data.writeFileDescriptor(ext2);
+        } else {
+            data.writeInt32(ext2);
+        }
         remote()->transact(NOTIFY_CALLBACK, data, &reply, IBinder::FLAG_ONEWAY);
     }
 
@@ -91,8 +96,14 @@
             ALOGV("NOTIFY_CALLBACK");
             CHECK_INTERFACE(ICameraClient, data, reply);
             int32_t msgType = data.readInt32();
-            int32_t ext1 = data.readInt32();
-            int32_t ext2 = data.readInt32();
+            int32_t ext1    = data.readInt32();
+            int32_t ext2    = 0;
+            if ((msgType == CAMERA_MSG_PREVIEW_FRAME) && (ext1 == CAMERA_FRAME_DATA_FD)) {
+                ext2 = data.readFileDescriptor();
+                ALOGD("onTransact: CAMERA_MSG_PREVIEW_FRAME fd = %d", ext2);
+            } else {
+                ext2 = data.readInt32();
+            }
             notifyCallback(msgType, ext1, ext2);
             return NO_ERROR;
         } break;
diff --git a/cmds/stagefright/stagefright.cpp b/cmds/stagefright/stagefright.cpp
index a9c6eda..7413254 100644
--- a/cmds/stagefright/stagefright.cpp
+++ b/cmds/stagefright/stagefright.cpp
@@ -12,6 +12,25 @@
  * 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.
+ *
+ * This file was modified by Dolby Laboratories, Inc. The portions of the
+ * code that are surrounded by "DOLBY..." are copyrighted and
+ * licensed separately, as follows:
+ *
+ *  (C) 2011-2015 Dolby Laboratories, Inc.
+ *
+ * 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 <inttypes.h>
@@ -626,6 +645,11 @@
         MEDIA_MIMETYPE_AUDIO_MPEG, MEDIA_MIMETYPE_AUDIO_G711_MLAW,
         MEDIA_MIMETYPE_AUDIO_G711_ALAW, MEDIA_MIMETYPE_AUDIO_VORBIS,
         MEDIA_MIMETYPE_VIDEO_VP8, MEDIA_MIMETYPE_VIDEO_VP9
+#ifdef DOLBY_ENABLE
+        ,
+        MEDIA_MIMETYPE_AUDIO_AC3,
+        MEDIA_MIMETYPE_AUDIO_EAC3
+#endif // DOLBY_END
     };
 
     const char *codecType = queryDecoders? "decoder" : "encoder";
diff --git a/drm/libdrmframework/Android.mk b/drm/libdrmframework/Android.mk
index 33f9d3b..b7eb70b 100644
--- a/drm/libdrmframework/Android.mk
+++ b/drm/libdrmframework/Android.mk
@@ -31,7 +31,7 @@
     libbinder \
     libdl
 
-LOCAL_STATIC_LIBRARIES := \
+LOCAL_WHOLE_STATIC_LIBRARIES := \
     libdrmframeworkcommon
 
 LOCAL_C_INCLUDES += \
diff --git a/include/media/AudioParameter.h b/include/media/AudioParameter.h
index 891bc4b..c769c4b 100644
--- a/include/media/AudioParameter.h
+++ b/include/media/AudioParameter.h
@@ -48,6 +48,7 @@
     static const char * const keyFrameCount;
     static const char * const keyInputSource;
     static const char * const keyScreenState;
+    static const char * const keyDevShutdown;
 
     String8 toString();
 
diff --git a/include/media/AudioTrack.h b/include/media/AudioTrack.h
index e02f1b7..191802d 100644
--- a/include/media/AudioTrack.h
+++ b/include/media/AudioTrack.h
@@ -31,6 +31,7 @@
 struct audio_track_cblk_t;
 class AudioTrackClientProxy;
 class StaticAudioTrackClientProxy;
+struct ExtendedMediaUtils;
 
 // ----------------------------------------------------------------------------
 
@@ -623,6 +624,7 @@
      */
             status_t    obtainBuffer(Buffer* audioBuffer, const struct timespec *requested,
                                      struct timespec *elapsed = NULL, size_t *nonContig = NULL);
+     friend struct ExtendedMediaUtils;
 public:
 
     /* Public API for TRANSFER_OBTAIN mode.
@@ -940,6 +942,8 @@
     // For Device Selection API
     //  a value of AUDIO_PORT_HANDLE_NONE indicated default (AudioPolicyManager) routing.
     audio_port_handle_t     mSelectedDeviceId;
+    bool                    mPlaybackRateSet;
+    bool                    mTrackOffloaded;
 
 private:
     class DeathNotifier : public IBinder::DeathRecipient {
@@ -957,6 +961,7 @@
     pid_t                   mClientPid;
 
     sp<AudioSystem::AudioDeviceCallback> mDeviceCallback;
+    friend struct ExtendedMediaUtils;
 };
 
 class TimedAudioTrack : public AudioTrack
diff --git a/include/media/MediaPlayerInterface.h b/include/media/MediaPlayerInterface.h
index de82554..745151b 100644
--- a/include/media/MediaPlayerInterface.h
+++ b/include/media/MediaPlayerInterface.h
@@ -46,12 +46,12 @@
 template<typename T> class SortedVector;
 
 enum player_type {
-    STAGEFRIGHT_PLAYER = 3,
     NU_PLAYER = 4,
     // Test players are available only in the 'test' and 'eng' builds.
     // The shared library with the test player is passed passed as an
     // argument to the 'test:' url in the setDataSource call.
     TEST_PLAYER = 5,
+    DASH_PLAYER = 6,
 };
 
 
diff --git a/include/media/MediaProfiles.h b/include/media/MediaProfiles.h
index e02918f..b1c7c15 100644
--- a/include/media/MediaProfiles.h
+++ b/include/media/MediaProfiles.h
@@ -56,6 +56,20 @@
     CAMCORDER_QUALITY_HIGH_SPEED_1080P = 2004,
     CAMCORDER_QUALITY_HIGH_SPEED_2160P = 2005,
     CAMCORDER_QUALITY_HIGH_SPEED_LIST_END = 2005,
+
+    CAMCORDER_QUALITY_VENDOR_START = 10000,
+    CAMCORDER_QUALITY_VGA = 10000,
+    CAMCORDER_QUALITY_4KDCI = 10001,
+    CAMCORDER_QUALITY_TIME_LAPSE_VGA = 10002,
+    CAMCORDER_QUALITY_TIME_LAPSE_4KDCI = 10003,
+    CAMCORDER_QUALITY_HIGH_SPEED_CIF = 10004,
+    CAMCORDER_QUALITY_HIGH_SPEED_VGA = 10005,
+    CAMCORDER_QUALITY_HIGH_SPEED_4KDCI = 10006,
+    CAMCORDER_QUALITY_QHD = 10007,
+    CAMCORDER_QUALITY_2k = 10008,
+    CAMCORDER_QUALITY_TIME_LAPSE_QHD = 10009,
+    CAMCORDER_QUALITY_TIME_LAPSE_2k = 10010,
+    CAMCORDER_QUALITY_VENDOR_END = 10010,
 };
 
 enum video_decoder {
@@ -392,6 +406,7 @@
     static VideoEncoderCap* createDefaultH263VideoEncoderCap();
     static VideoEncoderCap* createDefaultM4vVideoEncoderCap();
     static AudioEncoderCap* createDefaultAmrNBEncoderCap();
+    static AudioEncoderCap* createDefaultLpcmEncoderCap();
 
     static int findTagForName(const NameToTagMap *map, size_t nMappings, const char *name);
 
diff --git a/include/media/mediaplayer.h b/include/media/mediaplayer.h
index 3fe749c..1f6ddad 100644
--- a/include/media/mediaplayer.h
+++ b/include/media/mediaplayer.h
@@ -53,7 +53,7 @@
     MEDIA_ERROR             = 100,
     MEDIA_INFO              = 200,
     MEDIA_SUBTITLE_DATA     = 201,
-    MEDIA_META_DATA         = 202,
+    MEDIA_META_DATA         = 202
 };
 
 // Generic error codes for the media player framework.  Errors are fatal, the
@@ -209,7 +209,7 @@
             void            died();
             void            disconnect();
 
-            status_t        setDataSource(
+    virtual status_t        setDataSource(
                     const sp<IMediaHTTPService> &httpService,
                     const char *url,
                     const KeyedVector<String8, String8> *headers);
@@ -224,7 +224,7 @@
             status_t        prepareAsync();
             status_t        start();
             status_t        stop();
-            status_t        pause();
+    virtual status_t        pause();
             bool            isPlaying();
             status_t        setPlaybackSettings(const AudioPlaybackRate& rate);
             status_t        getPlaybackSettings(AudioPlaybackRate* rate /* nonnull */);
@@ -234,7 +234,7 @@
                                     float* videoFps /* nonnull */);
             status_t        getVideoWidth(int *w);
             status_t        getVideoHeight(int *h);
-            status_t        seekTo(int msec);
+    virtual status_t        seekTo(int msec);
             status_t        getCurrentPosition(int *msec);
             status_t        getDuration(int *msec);
             status_t        reset();
@@ -243,7 +243,7 @@
             status_t        setLooping(int loop);
             bool            isLooping();
             status_t        setVolume(float leftVolume, float rightVolume);
-            void            notify(int msg, int ext1, int ext2, const Parcel *obj = NULL);
+    virtual void            notify(int msg, int ext1, int ext2, const Parcel *obj = NULL);
             status_t        invoke(const Parcel& request, Parcel *reply);
             status_t        setMetadataFilter(const Parcel& filter);
             status_t        getMetadata(bool update_only, bool apply_filter, Parcel *metadata);
@@ -289,6 +289,7 @@
     float                       mSendLevel;
     struct sockaddr_in          mRetransmitEndpoint;
     bool                        mRetransmitEndpointValid;
+    friend class QCMediaPlayer;
 };
 
 }; // namespace android
diff --git a/include/media/mediarecorder.h b/include/media/mediarecorder.h
index 15ff82d..6ace36d 100644
--- a/include/media/mediarecorder.h
+++ b/include/media/mediarecorder.h
@@ -74,6 +74,9 @@
     /* VP8/VORBIS data in a WEBM container */
     OUTPUT_FORMAT_WEBM = 9,
 
+    OUTPUT_FORMAT_QCP = 20,
+    OUTPUT_FORMAT_WAVE = 21,
+
     OUTPUT_FORMAT_LIST_END // must be last - used to validate format type
 };
 
@@ -86,6 +89,10 @@
     AUDIO_ENCODER_AAC_ELD = 5,
     AUDIO_ENCODER_VORBIS = 6,
 
+    AUDIO_ENCODER_EVRC = 10,
+    AUDIO_ENCODER_QCELP = 11,
+    AUDIO_ENCODER_LPCM = 12,
+
     AUDIO_ENCODER_LIST_END // must be the last - used to validate the audio encoder type
 };
 
@@ -96,7 +103,11 @@
     VIDEO_ENCODER_MPEG_4_SP = 3,
     VIDEO_ENCODER_VP8 = 4,
 
-    VIDEO_ENCODER_LIST_END // must be the last - used to validate the video encoder type
+    VIDEO_ENCODER_LIST_END, // must be the last - used to validate the video encoder type
+
+    VIDEO_ENCODER_LIST_VENDOR_START = 1000,
+    VIDEO_ENCODER_H265 = 1001,
+    VIDEO_ENCODER_LIST_VENDOR_END,
 };
 
 /*
@@ -225,13 +236,13 @@
     status_t    setOutputFile(int fd, int64_t offset, int64_t length);
     status_t    setVideoSize(int width, int height);
     status_t    setVideoFrameRate(int frames_per_second);
-    status_t    setParameters(const String8& params);
+    virtual status_t    setParameters(const String8& params);
     status_t    setListener(const sp<MediaRecorderListener>& listener);
     status_t    setClientName(const String16& clientName);
     status_t    prepare();
     status_t    getMaxAmplitude(int* max);
-    status_t    start();
-    status_t    stop();
+    virtual status_t    start();
+    virtual status_t    stop();
     status_t    reset();
     status_t    init();
     status_t    close();
@@ -240,7 +251,7 @@
     status_t    setInputSurface(const sp<PersistentSurface>& surface);
     sp<IGraphicBufferProducer>     querySurfaceMediaSourceFromMediaServer();
 
-private:
+protected:
     void                    doCleanUp();
     status_t                doReset();
 
diff --git a/include/media/stagefright/ACodec.h b/include/media/stagefright/ACodec.h
index 8b5b862..ebfdc7b 100644
--- a/include/media/stagefright/ACodec.h
+++ b/include/media/stagefright/ACodec.h
@@ -12,6 +12,25 @@
  * 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.
+ *
+ * This file was modified by Dolby Laboratories, Inc. The portions of the
+ * code that are surrounded by "DOLBY..." are copyrighted and
+ * licensed separately, as follows:
+ *
+ *  (C) 2015 Dolby Laboratories, Inc.
+ *
+ * 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 A_CODEC_H_
@@ -93,8 +112,11 @@
 
 protected:
     virtual ~ACodec();
+    virtual status_t setupCustomCodec(
+            status_t err, const char *mime, const sp<AMessage> &msg);
+    virtual status_t GetVideoCodingTypeFromMime(
+            const char *mime, OMX_VIDEO_CODINGTYPE *codingType);
 
-private:
     struct BaseState;
     struct UninitializedState;
     struct LoadedState;
@@ -152,6 +174,7 @@
     };
 
     struct BufferInfo {
+        BufferInfo() : mCustomData(-1) {}
         enum Status {
             OWNED_BY_US,
             OWNED_BY_COMPONENT,
@@ -173,6 +196,7 @@
         sp<GraphicBuffer> mGraphicBuffer;
         int mFenceFd;
         FrameRenderTracker::Info *mRenderInfo;
+        int mCustomData;
 
         // The following field and 4 methods are used for debugging only
         bool mIsReadFence;
@@ -271,7 +295,7 @@
     status_t setCyclicIntraMacroblockRefresh(const sp<AMessage> &msg, int32_t mode);
     status_t allocateBuffersOnPort(OMX_U32 portIndex);
     status_t freeBuffersOnPort(OMX_U32 portIndex);
-    status_t freeBuffer(OMX_U32 portIndex, size_t i);
+    virtual status_t freeBuffer(OMX_U32 portIndex, size_t i);
 
     status_t handleSetSurface(const sp<Surface> &surface);
     status_t setupNativeWindowSizeFormatAndUsage(
@@ -300,8 +324,8 @@
             uint32_t portIndex, IOMX::buffer_id bufferID,
             ssize_t *index = NULL);
 
-    status_t setComponentRole(bool isEncoder, const char *mime);
-    status_t configureCodec(const char *mime, const sp<AMessage> &msg);
+    virtual status_t setComponentRole(bool isEncoder, const char *mime);
+    virtual status_t configureCodec(const char *mime, const sp<AMessage> &msg);
 
     status_t configureTunneledVideoPlayback(int32_t audioHwSync,
             const sp<ANativeWindow> &nativeWindow);
@@ -314,10 +338,10 @@
 
     status_t setSupportedOutputFormat(bool getLegacyFlexibleFormat);
 
-    status_t setupVideoDecoder(
+    virtual status_t setupVideoDecoder(
             const char *mime, const sp<AMessage> &msg, bool usingNativeBuffers);
 
-    status_t setupVideoEncoder(
+    virtual status_t setupVideoEncoder(
             const char *mime, const sp<AMessage> &msg);
 
     status_t setVideoFormatOnPort(
@@ -372,7 +396,7 @@
     status_t configureBitrate(
             int32_t bitrate, OMX_VIDEO_CONTROLRATETYPE bitrateMode);
 
-    status_t setupErrorCorrectionParameters();
+    virtual status_t setupErrorCorrectionParameters();
 
     status_t initNativeWindow();
 
@@ -408,7 +432,7 @@
             bool dropIncomplete = false, FrameRenderTracker::Info *until = NULL);
 
     void sendFormatChange(const sp<AMessage> &reply);
-    status_t getPortFormat(OMX_U32 portIndex, sp<AMessage> &notify);
+    virtual status_t getPortFormat(OMX_U32 portIndex, sp<AMessage> &notify);
 
     void signalError(
             OMX_ERRORTYPE error = OMX_ErrorUndefined,
@@ -420,11 +444,41 @@
         DescribeColorFormatParams &describeParams);
 
     status_t requestIDRFrame();
-    status_t setParameters(const sp<AMessage> &params);
+    virtual status_t setParameters(const sp<AMessage> &params);
 
     // Send EOS on input stream.
     void onSignalEndOfInputStream();
 
+    virtual void setBFrames(OMX_VIDEO_PARAM_MPEG4TYPE *mpeg4type) {}
+    virtual void setBFrames(OMX_VIDEO_PARAM_AVCTYPE *h264type,
+        const int32_t iFramesInterval, const int32_t frameRate) {}
+
+    virtual status_t getVQZIPInfo(const sp<AMessage> &msg) {
+        return OK;
+    }
+    virtual bool canAllocateBuffer(OMX_U32 /* portIndex */) {
+        return false;
+    }
+    virtual void enableCustomAllocationMode(const sp<AMessage> &/* msg */) {}
+    virtual status_t allocateBuffer(
+        OMX_U32 portIndex, size_t bufSize, BufferInfo &info);
+
+    virtual status_t setDSModeHint(sp<AMessage>& msg,
+        OMX_U32 flags, int64_t timeUs) {
+        return UNKNOWN_ERROR;
+    }
+
+    virtual bool getDSModeHint(const sp<AMessage>& msg) {
+        return false;
+    }
+
+    sp<IOMXObserver> createObserver();
+#ifdef DOLBY_ENABLE
+    status_t setDolbyParameterOnEndpChange();
+    void     setDolbyParameter(const sp<AMessage> &msg);
+    status_t setDolbyParameterOnProcessedAudio(const sp<AMessage> &params);
+#endif // DOLBY_END
+
     DISALLOW_EVIL_CONSTRUCTORS(ACodec);
 };
 
diff --git a/include/media/stagefright/AudioPlayer.h b/include/media/stagefright/AudioPlayer.h
index e0cd965..20ce4a4 100644
--- a/include/media/stagefright/AudioPlayer.h
+++ b/include/media/stagefright/AudioPlayer.h
@@ -12,6 +12,25 @@
  * 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.
+ *
+ * This file was modified by Dolby Laboratories, Inc. The portions of the
+ * code that are surrounded by "DOLBY..." are copyrighted and
+ * licensed separately, as follows:
+ *
+ *  (C) 2015 Dolby Laboratories, Inc.
+ *
+ * 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 AUDIO_PLAYER_H_
@@ -138,6 +157,9 @@
 
     AudioPlayer(const AudioPlayer &);
     AudioPlayer &operator=(const AudioPlayer &);
+#ifdef DOLBY_ENABLE
+    void setDolbyProcessedAudio(sp<MetaData> &format);
+#endif // DOLBY_END
 };
 
 }  // namespace android
diff --git a/include/media/stagefright/AudioSource.h b/include/media/stagefright/AudioSource.h
index 3074910..9750bcd 100644
--- a/include/media/stagefright/AudioSource.h
+++ b/include/media/stagefright/AudioSource.h
@@ -46,6 +46,8 @@
     virtual status_t stop() { return reset(); }
     virtual sp<MetaData> getFormat();
 
+    virtual status_t pause() { return ERROR_UNSUPPORTED; }
+
     // Returns the maximum amplitude since last call.
     int16_t getMaxAmplitude();
 
@@ -58,9 +60,11 @@
 protected:
     virtual ~AudioSource();
 
-private:
+protected:
     enum {
-        kMaxBufferSize = 2048,
+        //calculated for max duration 80 msec with 48K sampling rate.
+        kMaxBufferSize = 30720,
+
 
         // After the initial mute, we raise the volume linearly
         // over kAutoRampDurationUs.
@@ -68,7 +72,7 @@
 
         // This is the initial mute duration to suppress
         // the video recording signal tone
-        kAutoRampStartUs = 0,
+        kAutoRampStartUs = 500000,
     };
 
     Mutex mLock;
@@ -100,10 +104,10 @@
         int32_t startFrame, int32_t rampDurationFrames,
         uint8_t *data,   size_t bytes);
 
-    void queueInputBuffer_l(MediaBuffer *buffer, int64_t timeUs);
+    virtual void queueInputBuffer_l(MediaBuffer *buffer, int64_t timeUs);
     void releaseQueuedFrames_l();
     void waitOutstandingEncodingFrames_l();
-    status_t reset();
+    virtual status_t reset();
 
     AudioSource(const AudioSource &);
     AudioSource &operator=(const AudioSource &);
diff --git a/include/media/stagefright/CameraSource.h b/include/media/stagefright/CameraSource.h
index 069e897..527ee15 100644
--- a/include/media/stagefright/CameraSource.h
+++ b/include/media/stagefright/CameraSource.h
@@ -92,6 +92,8 @@
     virtual status_t read(
             MediaBuffer **buffer, const ReadOptions *options = NULL);
 
+    virtual status_t pause() { return ERROR_UNSUPPORTED; }
+
     /**
      * Check whether a CameraSource object is properly initialized.
      * Must call this method before stop().
@@ -189,7 +191,7 @@
 
     void releaseCamera();
 
-private:
+protected:
     friend struct CameraSourceListener;
 
     Mutex mLock;
diff --git a/include/media/stagefright/CameraSourceTimeLapse.h b/include/media/stagefright/CameraSourceTimeLapse.h
index 34213be..f264d98 100644
--- a/include/media/stagefright/CameraSourceTimeLapse.h
+++ b/include/media/stagefright/CameraSourceTimeLapse.h
@@ -20,6 +20,7 @@
 
 #include <pthread.h>
 
+#include <media/stagefright/CameraSource.h>
 #include <utils/RefBase.h>
 #include <utils/threads.h>
 #include <utils/String16.h>
@@ -56,7 +57,7 @@
     // returning quickly.
     void startQuickReadReturns();
 
-private:
+protected:
     // size of the encoded video.
     int32_t mVideoWidth;
     int32_t mVideoHeight;
@@ -152,7 +153,7 @@
     // the frame needs to be encoded, it returns false and also modifies
     // the time stamp to be one frame time ahead of the last encoded
     // frame's time stamp.
-    bool skipFrameAndModifyTimeStamp(int64_t *timestampUs);
+    virtual bool skipFrameAndModifyTimeStamp(int64_t *timestampUs);
 
     // Wrapper to enter threadTimeLapseEntry()
     static void *ThreadTimeLapseWrapper(void *me);
diff --git a/include/media/stagefright/DataSource.h b/include/media/stagefright/DataSource.h
index dcde36f..0c31e72 100644
--- a/include/media/stagefright/DataSource.h
+++ b/include/media/stagefright/DataSource.h
@@ -51,7 +51,8 @@
             const char *uri,
             const KeyedVector<String8, String8> *headers = NULL,
             String8 *contentType = NULL,
-            HTTPBase *httpSource = NULL);
+            HTTPBase *httpSource = NULL,
+            bool useExtendedCache = false);
 
     static sp<DataSource> CreateMediaHTTP(const sp<IMediaHTTPService> &httpService);
     static sp<DataSource> CreateFromIDataSource(const sp<IDataSource> &source);
diff --git a/include/media/stagefright/ExtendedMediaDefs.h b/include/media/stagefright/ExtendedMediaDefs.h
new file mode 100644
index 0000000..18b5e9a
--- /dev/null
+++ b/include/media/stagefright/ExtendedMediaDefs.h
@@ -0,0 +1,69 @@
+/*Copyright (c) 2015, 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 _EXTENDED_MEDIA_DEFS_H_
+#define _EXTENDED_MEDIA_DEFS_H_
+
+namespace android {
+
+extern const char *MEDIA_MIMETYPE_AUDIO_EVRC;
+extern const char *MEDIA_MIMETYPE_VIDEO_WMV;
+extern const char *MEDIA_MIMETYPE_VIDEO_WMV_VC1;
+extern const char *MEDIA_MIMETYPE_AUDIO_WMA;
+extern const char *MEDIA_MIMETYPE_AUDIO_WMA_PRO;
+extern const char *MEDIA_MIMETYPE_AUDIO_WMA_LOSSLESS;
+extern const char *MEDIA_MIMETYPE_CONTAINER_ASF;
+extern const char *MEDIA_MIMETYPE_VIDEO_DIVX;
+extern const char *MEDIA_MIMETYPE_CONTAINER_AAC;
+extern const char *MEDIA_MIMETYPE_CONTAINER_QCP;
+extern const char *MEDIA_MIMETYPE_VIDEO_DIVX311;
+extern const char *MEDIA_MIMETYPE_VIDEO_DIVX4;
+extern const char *MEDIA_MIMETYPE_CONTAINER_MPEG2;
+extern const char *MEDIA_MIMETYPE_CONTAINER_3G2;
+extern const char *MEDIA_MIMETYPE_AUDIO_DTS;
+extern const char *MEDIA_MIMETYPE_AUDIO_DTS_LBR;
+extern const char *MEDIA_MIMETYPE_AUDIO_AMR_WB_PLUS;
+extern const char *MEDIA_MIMETYPE_AUDIO_AIFF;
+extern const char *MEDIA_MIMETYPE_AUDIO_ALAC;
+extern const char *MEDIA_MIMETYPE_AUDIO_APE;
+extern const char *MEDIA_MIMETYPE_CONTAINER_QCAMR_NB;
+extern const char *MEDIA_MIMETYPE_CONTAINER_QCAMR_WB;
+extern const char *MEDIA_MIMETYPE_CONTAINER_QCMPEG;
+extern const char *MEDIA_MIMETYPE_CONTAINER_QCWAV;
+extern const char *MEDIA_MIMETYPE_CONTAINER_QCMPEG2TS;
+extern const char *MEDIA_MIMETYPE_CONTAINER_QCMPEG2PS;
+extern const char *MEDIA_MIMETYPE_CONTAINER_QCMPEG4;
+extern const char *MEDIA_MIMETYPE_CONTAINER_QCMATROSKA;
+extern const char *MEDIA_MIMETYPE_CONTAINER_QCOGG;
+extern const char *MEDIA_MIMETYPE_CONTAINER_QCFLV;
+extern const char *MEDIA_MIMETYPE_VIDEO_VPX;
+extern const char *MEDIA_MIMETYPE_CONTAINER_QTIFLAC;
+extern const char *MEDIA_MIMETYPE_VIDEO_MPEG4_DP;
+
+}  // namespace android
+
+#endif // _EXTENDED_MEDIA_DEFS_H_
diff --git a/include/media/stagefright/MPEG4Writer.h b/include/media/stagefright/MPEG4Writer.h
index a195fe8..055c079 100644
--- a/include/media/stagefright/MPEG4Writer.h
+++ b/include/media/stagefright/MPEG4Writer.h
@@ -108,6 +108,8 @@
 
     sp<AMessage> mMetaKeys;
 
+    bool mIsVideoHEVC;
+
     void setStartTimestampUs(int64_t timeUs);
     int64_t getStartTimestampUs();  // Not const
     status_t startTracks(MetaData *params);
@@ -181,6 +183,9 @@
     // By default, real time recording is on.
     bool isRealTimeRecording() const;
 
+    // To use 3gp4 box for clips with AMR audio
+    bool mIsAudioAMR;
+
     void lock();
     void unlock();
 
diff --git a/include/media/stagefright/MediaCodec.h b/include/media/stagefright/MediaCodec.h
index c10963d..9c489e5 100644
--- a/include/media/stagefright/MediaCodec.h
+++ b/include/media/stagefright/MediaCodec.h
@@ -51,6 +51,8 @@
         BUFFER_FLAG_SYNCFRAME   = 1,
         BUFFER_FLAG_CODECCONFIG = 2,
         BUFFER_FLAG_EOS         = 4,
+        BUFFER_FLAG_EXTRADATA   = 0x1000,
+        BUFFER_FLAG_DATACORRUPT = 0x2000,
     };
 
     enum {
diff --git a/include/media/stagefright/MediaCodecSource.h b/include/media/stagefright/MediaCodecSource.h
index 71f58a9..d41d87b 100644
--- a/include/media/stagefright/MediaCodecSource.h
+++ b/include/media/stagefright/MediaCodecSource.h
@@ -28,7 +28,7 @@
 struct AReplyToken;
 class IGraphicBufferProducer;
 class IGraphicBufferConsumer;
-class MediaCodec;
+struct MediaCodec;
 class MetaData;
 
 struct MediaCodecSource : public MediaSource,
diff --git a/include/media/stagefright/MediaDefs.h b/include/media/stagefright/MediaDefs.h
index 21eb04a..21e7704 100644
--- a/include/media/stagefright/MediaDefs.h
+++ b/include/media/stagefright/MediaDefs.h
@@ -12,6 +12,25 @@
  * 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.
+ *
+ * This file was modified by Dolby Laboratories, Inc. The portions of the
+ * code that are surrounded by "DOLBY..." are copyrighted and
+ * licensed separately, as follows:
+ *
+ *  (C) 2011-2015 Dolby Laboratories, Inc.
+ *
+ * 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 MEDIA_DEFS_H_
@@ -49,6 +68,9 @@
 extern const char *MEDIA_MIMETYPE_AUDIO_MSGSM;
 extern const char *MEDIA_MIMETYPE_AUDIO_AC3;
 extern const char *MEDIA_MIMETYPE_AUDIO_EAC3;
+#ifdef DOLBY_ENABLE
+extern const char *MEDIA_MIMETYPE_AUDIO_EAC3_JOC;
+#endif // DOLBY_END
 
 extern const char *MEDIA_MIMETYPE_CONTAINER_MPEG4;
 extern const char *MEDIA_MIMETYPE_CONTAINER_WAV;
@@ -68,4 +90,6 @@
 
 }  // namespace android
 
+#include <media/stagefright/ExtendedMediaDefs.h>
+
 #endif  // MEDIA_DEFS_H_
diff --git a/include/media/stagefright/MediaExtractor.h b/include/media/stagefright/MediaExtractor.h
index 183933a..32925ca 100644
--- a/include/media/stagefright/MediaExtractor.h
+++ b/include/media/stagefright/MediaExtractor.h
@@ -29,7 +29,8 @@
 class MediaExtractor : public RefBase {
 public:
     static sp<MediaExtractor> Create(
-            const sp<DataSource> &source, const char *mime = NULL);
+            const sp<DataSource> &source, const char *mime = NULL,
+            const uint32_t flags = 0);
 
     virtual size_t countTracks() = 0;
     virtual sp<MediaSource> getTrack(size_t index) = 0;
@@ -67,6 +68,7 @@
     }
     virtual void setUID(uid_t uid) {
     }
+    virtual void setExtraFlags(uint32_t flag) {}
 
 protected:
     MediaExtractor() : mIsDrm(false) {}
diff --git a/include/media/stagefright/MediaHTTP.h b/include/media/stagefright/MediaHTTP.h
index 006d8d8..88683bd 100644
--- a/include/media/stagefright/MediaHTTP.h
+++ b/include/media/stagefright/MediaHTTP.h
@@ -54,7 +54,7 @@
     virtual String8 getUri();
     virtual String8 getMIMEType() const;
 
-private:
+protected:
     status_t mInitCheck;
     sp<IMediaHTTPConnection> mHTTPConnection;
 
diff --git a/include/media/stagefright/OMXCodec.h b/include/media/stagefright/OMXCodec.h
index 7fabcb3..5418df2 100644
--- a/include/media/stagefright/OMXCodec.h
+++ b/include/media/stagefright/OMXCodec.h
@@ -12,6 +12,25 @@
  * 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.
+ *
+ * This file was modified by Dolby Laboratories, Inc. The portions of the
+ * code that are surrounded by "DOLBY..." are copyrighted and
+ * licensed separately, as follows:
+ *
+ *  (C) 2015 Dolby Laboratories, Inc.
+ *
+ * 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 OMX_CODEC_H_
@@ -361,6 +380,10 @@
 
     OMXCodec(const OMXCodec &);
     OMXCodec &operator=(const OMXCodec &);
+#ifdef DOLBY_ENABLE
+    static uint32_t getDolbyComponentQuirks(const sp<MediaCodecInfo> &info);
+    void setDolbyProcessedAudio();
+#endif // DOLBY_END
 };
 
 struct CodecCapabilities {
diff --git a/media/libavextensions/Android.mk b/media/libavextensions/Android.mk
new file mode 100644
index 0000000..0380135
--- /dev/null
+++ b/media/libavextensions/Android.mk
@@ -0,0 +1,92 @@
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES:=                          \
+        stagefright/ExtendedMediaDefs.cpp  \
+        stagefright/AVUtils.cpp            \
+        stagefright/AVFactory.cpp          \
+
+LOCAL_C_INCLUDES:= \
+        $(TOP)/frameworks/av/include/media/ \
+        $(TOP)/frameworks/av/media/libavextensions \
+        $(TOP)/frameworks/native/include/media/hardware \
+        $(TOP)/frameworks/native/include/media/openmax \
+        $(TOP)/external/flac/include \
+        $(TOP)/hardware/qcom/media/mm-core/inc \
+        $(TOP)/frameworks/av/media/libstagefright \
+
+LOCAL_CFLAGS += -Wno-multichar -Werror
+
+ifeq ($(TARGET_ENABLE_QC_AV_ENHANCEMENTS),true)
+       LOCAL_CFLAGS += -DENABLE_AV_ENHANCEMENTS
+endif
+
+LOCAL_MODULE:= libavextensions
+LOCAL_CLANG := false
+
+LOCAL_MODULE_TAGS := optional
+
+include $(BUILD_STATIC_LIBRARY)
+
+########################################################
+
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES:=                          \
+        media/AVMediaUtils.cpp             \
+
+LOCAL_C_INCLUDES:= \
+        $(TOP)/frameworks/av/include/media/ \
+        $(TOP)/frameworks/av/media/libavextensions \
+        $(TOP)/frameworks/native/include/media/hardware \
+        $(TOP)/frameworks/native/include/media/openmax \
+        $(TOP)/external/flac/include \
+        $(TOP)/hardware/qcom/media/mm-core/inc
+
+LOCAL_CFLAGS += -Wno-multichar -Werror
+
+ifeq ($(TARGET_ENABLE_QC_AV_ENHANCEMENTS),true)
+       LOCAL_CFLAGS += -DENABLE_AV_ENHANCEMENTS
+endif
+
+LOCAL_MODULE:= libavmediaextentions
+LOCAL_CLANG := false
+
+LOCAL_MODULE_TAGS := optional
+
+include $(BUILD_STATIC_LIBRARY)
+
+########################################################
+
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES:=                                      \
+        mediaplayerservice/AVMediaServiceFactory.cpp   \
+        mediaplayerservice/AVMediaServiceUtils.cpp     \
+        mediaplayerservice/AVNuFactory.cpp             \
+        mediaplayerservice/AVNuUtils.cpp               \
+
+LOCAL_C_INCLUDES:= \
+        $(TOP)/frameworks/av/include/media/ \
+        $(TOP)/frameworks/av/media/libmediaplayerservice \
+        $(TOP)/frameworks/av/media/libavextensions \
+        $(TOP)/frameworks/av/media/libstagefright/include \
+        $(TOP)/frameworks/av/media/libstagefright/rtsp \
+        $(TOP)/frameworks/native/include/media/hardware \
+        $(TOP)/frameworks/native/include/media/openmax \
+        $(TOP)/external/flac/include \
+        $(TOP)/hardware/qcom/media/mm-core/inc
+
+LOCAL_CFLAGS += -Wno-multichar -Werror
+
+ifeq ($(TARGET_ENABLE_QC_AV_ENHANCEMENTS),true)
+       LOCAL_CFLAGS += -DENABLE_AV_ENHANCEMENTS
+endif
+
+LOCAL_MODULE:= libavmediaserviceextensions
+LOCAL_CLANG := false
+
+LOCAL_MODULE_TAGS := optional
+
+include $(BUILD_STATIC_LIBRARY)
+
diff --git a/media/libavextensions/common/AVExtensionsCommon.h b/media/libavextensions/common/AVExtensionsCommon.h
new file mode 100644
index 0000000..c39872e
--- /dev/null
+++ b/media/libavextensions/common/AVExtensionsCommon.h
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2013 - 2015, 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 _AV_EXTENSIONS_COMMON_H_
+#define _AV_EXTENSIONS_COMMON_H_
+
+namespace android {
+
+typedef void *(*createFunction_t)(void);
+
+template <typename T>
+struct ExtensionsLoader {
+
+    static T *createInstance(const char *createFunctionName);
+
+private:
+    static void loadLib();
+    static createFunction_t loadCreateFunction(const char *createFunctionName);
+    static void *mLibHandle;
+};
+
+/*
+ * Boiler-plate to declare the class as a singleton (with a static getter)
+ * which can be loaded (dlopen'd) via ExtensionsLoader
+ */
+#define DECLARE_LOADABLE_SINGLETON(className)   \
+protected:                                      \
+    className();                                \
+    virtual ~className();                       \
+    static className *sInst;                    \
+private:                                        \
+    className(const className&);                \
+    className &operator=(className &);          \
+public:                                         \
+    static className *get() {                   \
+        return sInst;                           \
+    }                                           \
+    friend struct ExtensionsLoader<className>;
+
+} //namespace android
+
+#endif // _AV_EXTENSIONS_COMMON_H_
diff --git a/media/libavextensions/common/ExtensionsLoader.hpp b/media/libavextensions/common/ExtensionsLoader.hpp
new file mode 100644
index 0000000..e03979c
--- /dev/null
+++ b/media/libavextensions/common/ExtensionsLoader.hpp
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 2013 - 2015, 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.
+ */
+#include <dlfcn.h>
+#include <common/AVExtensionsCommon.h>
+
+namespace android {
+
+static const char * CUSTOMIZATION_LIB_NAME = "libavenhancements.so";
+
+/*
+ * Create strongly-typed objects of type T
+ * If the customization library exists and does contain a "named" constructor,
+ *  invoke and create an instance
+ * Else create the object of type T itself
+ *
+ * Contains a static instance to dlopen'd library, But may end up
+ * opening the library mutiple times. Following snip from dlopen man page is
+ * reassuring "...Only a single copy of an object file is brought into the
+ * address space, even if dlopen() is invoked multiple times in reference to
+ * the file, and even if different pathnames are used to reference the file.."
+ */
+
+template <typename T>
+T *ExtensionsLoader<T>::createInstance(const char *createFunctionName) {
+        ALOGV("createInstance(%dbit) : %s", sizeof(intptr_t)*8, createFunctionName);
+        // create extended object if extensions-lib is available and
+        // AV_ENHANCEMENTS is enabled
+#if ENABLE_AV_ENHANCEMENTS
+        createFunction_t createFunc = loadCreateFunction(createFunctionName);
+        if (createFunc) {
+            return reinterpret_cast<T *>((*createFunc)());
+        }
+#endif
+        // Else, create the default object
+        return new T;
+}
+
+template <typename T>
+void ExtensionsLoader<T>::loadLib() {
+        if (!mLibHandle) {
+            mLibHandle = ::dlopen(CUSTOMIZATION_LIB_NAME, RTLD_LAZY);
+            if (!mLibHandle) {
+                ALOGV("%s", dlerror());
+                return;
+            }
+            ALOGV("Opened %s", CUSTOMIZATION_LIB_NAME);
+        }
+}
+
+template <typename T>
+createFunction_t ExtensionsLoader<T>::loadCreateFunction(const char *createFunctionName) {
+        loadLib();
+        if (!mLibHandle) {
+            return NULL;
+        }
+        createFunction_t func = (createFunction_t)dlsym(mLibHandle, createFunctionName);
+        if (!func) {
+            ALOGW("symbol %s not found:  %s",createFunctionName, dlerror());
+        }
+        return func;
+}
+
+//static
+template <typename T>
+void *ExtensionsLoader<T>::mLibHandle = NULL;
+
+} //namespace android
diff --git a/media/libavextensions/media/AVMediaExtensions.h b/media/libavextensions/media/AVMediaExtensions.h
new file mode 100644
index 0000000..9161fae
--- /dev/null
+++ b/media/libavextensions/media/AVMediaExtensions.h
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2013 - 2015, 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 _AV_MEDIA_EXTENSIONS_H_
+#define _AV_MEDIA_EXTENSIONS_H_
+
+#include <common/AVExtensionsCommon.h>
+#include <hardware/audio.h>
+#include <media/AudioTrack.h>
+
+namespace android {
+
+class MediaRecorder;
+class Parcel;
+/*
+ * Common delegate to the classes in libstagefright
+ */
+struct AVMediaUtils {
+
+    virtual bool AudioTrackIsPcmOffloaded(const audio_format_t /*format*/) {
+        return false;
+    }
+    virtual status_t AudioTrackGetPosition(AudioTrack* /*track*/,
+            uint32_t* /*position*/) {
+        return NO_INIT;
+    }
+
+    virtual status_t AudioTrackGetTimestamp(AudioTrack* /*track*/,
+            AudioTimestamp* /*timestamp*/) {
+        return NO_INIT;
+    }
+
+    virtual size_t AudioTrackGetOffloadFrameCount(size_t frameCount) {
+        return frameCount;
+    }
+
+    virtual bool AudioTrackIsTrackOffloaded(audio_io_handle_t /*output*/) {
+        return false;
+    }
+
+    virtual sp<MediaRecorder> createMediaRecorder(const String16& opPackageName);
+    virtual void writeCustomData(
+            Parcel * /* reply */, void * /* buffer_data */) {}
+    virtual void readCustomData(
+            const Parcel * /* reply */, void ** /*buffer_data */ ) {}
+    virtual void closeFileDescriptor(void * /* buffer_ptr */) {}
+    // ----- NO TRESSPASSING BEYOND THIS LINE ------
+    DECLARE_LOADABLE_SINGLETON(AVMediaUtils);
+};
+
+} //namespace android
+
+#endif //_AV_MEDIA_EXTENSIONS_H_
+
diff --git a/media/libavextensions/media/AVMediaUtils.cpp b/media/libavextensions/media/AVMediaUtils.cpp
new file mode 100644
index 0000000..0f9e9eb
--- /dev/null
+++ b/media/libavextensions/media/AVMediaUtils.cpp
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2013 - 2015, 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.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "AVMediaUtils"
+#include <utils/Log.h>
+
+#include <media/stagefright/foundation/ADebug.h>
+#include <media/stagefright/foundation/AMessage.h>
+#include <media/stagefright/foundation/ABuffer.h>
+#include <media/stagefright/MediaDefs.h>
+#include <media/stagefright/MediaCodecList.h>
+#include <media/stagefright/MetaData.h>
+#include <media/stagefright/ACodec.h>
+
+#include <media/AudioTrack.h>
+#include <media/mediarecorder.h>
+
+#include "common/ExtensionsLoader.hpp"
+#include "media/AVMediaExtensions.h"
+
+namespace android {
+
+// ----- NO TRESSPASSING BEYOND THIS LINE ------
+AVMediaUtils::AVMediaUtils() {
+}
+
+AVMediaUtils::~AVMediaUtils() {
+}
+
+sp<MediaRecorder> AVMediaUtils::createMediaRecorder(const String16& opPackageName) {
+    return new MediaRecorder(opPackageName);
+}
+
+//static
+AVMediaUtils *AVMediaUtils::sInst =
+        ExtensionsLoader<AVMediaUtils>::createInstance("createExtendedMediaUtils");
+
+} //namespace android
+
diff --git a/media/libavextensions/mediaplayerservice/AVMediaServiceExtensions.h b/media/libavextensions/mediaplayerservice/AVMediaServiceExtensions.h
new file mode 100644
index 0000000..f2c789e
--- /dev/null
+++ b/media/libavextensions/mediaplayerservice/AVMediaServiceExtensions.h
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 2013 - 2015, 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 _AV_MEDIA_SERVICE_EXTENSIONS_H_
+#define _AV_MEDIA_SERVICE_EXTENSIONS_H_
+
+#include <common/AVExtensionsCommon.h>
+#include <MediaPlayerFactory.h>
+
+#include <utils/List.h>
+#include <utils/RefBase.h>
+#include <utils/String16.h>
+
+#include <media/Metadata.h>
+
+namespace android {
+
+struct StagefrightRecorder;
+struct ARTSPConnection;
+struct ARTPConnection;
+struct AString;
+struct MyHandler;
+struct ABuffer;
+
+/*
+ * Factory to create objects of base-classes in libmediaplayerservice
+ */
+struct AVMediaServiceFactory {
+    virtual StagefrightRecorder *createStagefrightRecorder(const String16 &);
+
+    // RTSP extensions
+    virtual sp<ARTSPConnection> createARTSPConnection(bool uidValid, uid_t uid);
+    virtual sp<ARTPConnection> createARTPConnection();
+
+    // ----- NO TRESSPASSING BEYOND THIS LINE ------
+    DECLARE_LOADABLE_SINGLETON(AVMediaServiceFactory);
+};
+
+/*
+ * Common delegate to the classes in libmediaplayerservice
+ */
+struct AVMediaServiceUtils {
+    virtual void getDashPlayerFactory(MediaPlayerFactory::IFactory *&, player_type ) {}
+    // RTSP IPV6 utils
+    virtual bool pokeAHole(sp<MyHandler> handler, int rtpSocket, int rtcpSocket,
+            const AString &transport, const AString &sessionHost);
+    virtual void makePortPair(int *rtpSocket, int *rtcpSocket, unsigned *rtpPort,
+            bool isIPV6);
+    virtual const char* parseURL(AString *host);
+    // RTSP customization utils
+    virtual bool parseTrackURL(AString url, AString val);
+    virtual void appendRange(AString *request);
+    virtual void setServerTimeoutUs(int64_t timeout);
+    virtual void appendMeta(media::Metadata *meta);
+    virtual bool checkNPTMapping(uint32_t *rtpInfoTime, int64_t *playTimeUs,
+            bool *nptValid, uint32_t rtpTime);
+    virtual void addH263AdvancedPacket(const sp<ABuffer> &buffer,
+            List<sp<ABuffer>> *packets, uint32_t rtpTime);
+    virtual bool parseNTPRange(const char *s, float *npt1, float *npt2);
+
+    // ----- NO TRESSPASSING BEYOND THIS LINE ------
+    DECLARE_LOADABLE_SINGLETON(AVMediaServiceUtils);
+};
+
+}
+
+#endif // _AV_EXTENSIONS__H_
diff --git a/media/libavextensions/mediaplayerservice/AVMediaServiceFactory.cpp b/media/libavextensions/mediaplayerservice/AVMediaServiceFactory.cpp
new file mode 100644
index 0000000..10b66f5
--- /dev/null
+++ b/media/libavextensions/mediaplayerservice/AVMediaServiceFactory.cpp
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2013 - 2015, 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.
+ */
+
+#define LOG_TAG "AVMediaServiceFactory"
+#include <utils/Log.h>
+
+#include <media/stagefright/foundation/ADebug.h>
+#include <media/stagefright/foundation/AMessage.h>
+#include "ARTPConnection.h"
+#include "ARTSPConnection.h"
+
+#include "MediaRecorderClient.h"
+#include "MediaPlayerService.h"
+#include "StagefrightRecorder.h"
+
+#include "common/ExtensionsLoader.hpp"
+#include "mediaplayerservice/AVMediaServiceExtensions.h"
+
+namespace android {
+StagefrightRecorder *AVMediaServiceFactory::createStagefrightRecorder(
+        const String16 &opPackageName) {
+    return new StagefrightRecorder(opPackageName);
+}
+
+sp<ARTSPConnection> AVMediaServiceFactory::createARTSPConnection(
+        bool uidValid, uid_t uid) {
+    return new ARTSPConnection(uidValid, uid);
+}
+
+sp<ARTPConnection> AVMediaServiceFactory::createARTPConnection() {
+    return new ARTPConnection();
+}
+
+// ----- NO TRESSPASSING BEYOND THIS LINE ------
+AVMediaServiceFactory::AVMediaServiceFactory() {
+}
+
+AVMediaServiceFactory::~AVMediaServiceFactory() {
+}
+
+//static
+AVMediaServiceFactory *AVMediaServiceFactory::sInst =
+        ExtensionsLoader<AVMediaServiceFactory>::createInstance("createExtendedMediaServiceFactory");
+
+} //namespace android
+
diff --git a/media/libavextensions/mediaplayerservice/AVMediaServiceUtils.cpp b/media/libavextensions/mediaplayerservice/AVMediaServiceUtils.cpp
new file mode 100644
index 0000000..0e42367
--- /dev/null
+++ b/media/libavextensions/mediaplayerservice/AVMediaServiceUtils.cpp
@@ -0,0 +1,103 @@
+/*
+ * Copyright (c) 2013 - 2015, 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.
+ */
+
+#define LOG_TAG "AVMediaServiceUtils"
+#include <utils/Log.h>
+
+#include <media/stagefright/foundation/ADebug.h>
+#include "ARTPConnection.h"
+#include "ASessionDescription.h"
+#include "MyHandler.h"
+
+#include "common/ExtensionsLoader.hpp"
+#include "mediaplayerservice/AVMediaServiceExtensions.h"
+
+namespace android {
+
+bool AVMediaServiceUtils::pokeAHole(sp<MyHandler> handler, int rtpSocket, int rtcpSocket,
+        const AString &transport, const AString &/*sessionHost*/) {
+    if (handler == NULL) {
+        ALOGW("MyHandler is NULL");
+        return false;
+    }
+    return handler->pokeAHole(rtpSocket, rtcpSocket, transport);
+}
+
+void AVMediaServiceUtils::makePortPair(int *rtpSocket, int *rtcpSocket, unsigned *rtpPort,
+        bool /*isIPV6*/) {
+    return ARTPConnection::MakePortPair(rtpSocket, rtcpSocket, rtpPort);
+}
+
+const char* AVMediaServiceUtils::parseURL(AString *host) {
+    return strchr(host->c_str(), ':');
+}
+
+bool AVMediaServiceUtils::parseTrackURL(AString /*url*/, AString /*val*/) {
+    return false;
+}
+
+void AVMediaServiceUtils::appendRange(AString * /*request*/) {
+    return;
+}
+
+void AVMediaServiceUtils::setServerTimeoutUs(int64_t /*timeout*/) {
+    return;
+}
+
+void AVMediaServiceUtils::addH263AdvancedPacket(const sp<ABuffer> &/*buffer*/,
+        List<sp<ABuffer>> * /*packets*/, uint32_t /*rtpTime*/) {
+    return;
+}
+
+void AVMediaServiceUtils::appendMeta(media::Metadata * /*meta*/) {
+    return;
+}
+
+bool AVMediaServiceUtils::checkNPTMapping(uint32_t * /*rtpInfoTime*/, int64_t * /*playTimeUs*/,
+        bool * /*nptValid*/, uint32_t /*rtpTime*/) {
+    return false;
+}
+
+bool AVMediaServiceUtils::parseNTPRange(const char *s, float *npt1, float *npt2) {
+    return ASessionDescription::parseNTPRange(s, npt1, npt2);
+}
+
+// ----- NO TRESSPASSING BEYOND THIS LINE ------
+AVMediaServiceUtils::AVMediaServiceUtils() {
+}
+
+AVMediaServiceUtils::~AVMediaServiceUtils() {
+}
+
+//static
+AVMediaServiceUtils *AVMediaServiceUtils::sInst =
+        ExtensionsLoader<AVMediaServiceUtils>::createInstance("createExtendedMediaServiceUtils");
+
+} //namespace android
+
diff --git a/media/libavextensions/mediaplayerservice/AVNuExtensions.h b/media/libavextensions/mediaplayerservice/AVNuExtensions.h
new file mode 100644
index 0000000..d7e29d1
--- /dev/null
+++ b/media/libavextensions/mediaplayerservice/AVNuExtensions.h
@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) 2013 - 2015, 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 _AV_NU_EXTENSIONS_H_
+#define _AV_NU_EXTENSIONS_H_
+
+#include <common/AVExtensionsCommon.h>
+
+namespace android {
+
+struct NuPlayer;
+/*
+ * Factory to create extended NuPlayer objects
+ */
+struct AVNuFactory {
+    virtual sp<NuPlayer> createNuPlayer(pid_t pid);
+
+    virtual sp<NuPlayer::DecoderBase> createPassThruDecoder(
+            const sp<AMessage> &notify,
+            const sp<NuPlayer::Source> &source,
+            const sp<NuPlayer::Renderer> &renderer);
+
+    virtual sp<NuPlayer::DecoderBase> createDecoder(
+            const sp<AMessage> &notify,
+            const sp<NuPlayer::Source> &source,
+            pid_t pid,
+            const sp<NuPlayer::Renderer> &renderer);
+
+    virtual sp<NuPlayer::Renderer> createRenderer(
+            const sp<MediaPlayerBase::AudioSink> &sink,
+            const sp<AMessage> &notify,
+            uint32_t flags);
+
+    // ----- NO TRESSPASSING BEYOND THIS LINE ------
+    DECLARE_LOADABLE_SINGLETON(AVNuFactory);
+};
+
+/*
+ * Common delegate to the classes in NuPlayer
+ */
+struct AVNuUtils {
+
+    virtual sp<MetaData> createPCMMetaFromSource(const sp<MetaData> &);
+    virtual bool pcmOffloadException(const sp<MetaData> &);
+    virtual bool isRAWFormat(const sp<MetaData> &);
+    virtual bool isRAWFormat(const sp<AMessage> &);
+    virtual bool isVorbisFormat(const sp<MetaData> &);
+    virtual int updateAudioBitWidth(audio_format_t audioFormat,
+            const sp<AMessage> &);
+    virtual audio_format_t getKeyPCMFormat(const sp<MetaData> &);
+    virtual void setKeyPCMFormat(const sp<MetaData> &, audio_format_t audioFormat);
+    virtual audio_format_t getPCMFormat(const sp<AMessage> &);
+    virtual void setPCMFormat(const sp<AMessage> &, audio_format_t audioFormat);
+    virtual void setSourcePCMFormat(const sp<MetaData> &);
+    virtual void setDecodedPCMFormat(const sp<AMessage> &);
+    virtual status_t convertToSinkFormatIfNeeded(const sp<ABuffer> &, sp<ABuffer> &,
+            audio_format_t sinkFormat, bool isOffload);
+    virtual uint32_t getFlags();
+    virtual bool canUseSetBuffers(const sp<MetaData> &Meta);
+
+    virtual void printFileName(int fd);
+    virtual void checkFormatChange(bool *formatChange, const sp<ABuffer> &accessUnit);
+    virtual void addFlagsInMeta(const sp<ABuffer> &buffer, int32_t flags, bool isAudio);
+    virtual bool dropCorruptFrame();
+
+    // ----- NO TRESSPASSING BEYOND THIS LINE ------
+    DECLARE_LOADABLE_SINGLETON(AVNuUtils);
+};
+
+}
+
+#endif // _AV_EXTENSIONS__H_
diff --git a/media/libavextensions/mediaplayerservice/AVNuFactory.cpp b/media/libavextensions/mediaplayerservice/AVNuFactory.cpp
new file mode 100644
index 0000000..ff7c074
--- /dev/null
+++ b/media/libavextensions/mediaplayerservice/AVNuFactory.cpp
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 2013 - 2015, 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.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "AVNuFactory"
+#include <utils/Log.h>
+
+#include <media/stagefright/foundation/ADebug.h>
+#include <media/stagefright/foundation/AMessage.h>
+
+#include <nuplayer/NuPlayer.h>
+#include <nuplayer/NuPlayerDecoderBase.h>
+#include <nuplayer/NuPlayerDecoderPassThrough.h>
+#include <nuplayer/NuPlayerDecoder.h>
+#include <nuplayer/NuPlayerCCDecoder.h>
+#include <gui/Surface.h>
+#include <nuplayer/NuPlayerSource.h>
+#include <nuplayer/NuPlayerRenderer.h>
+
+#include "common/ExtensionsLoader.hpp"
+#include "mediaplayerservice/AVNuExtensions.h"
+
+namespace android {
+
+sp<NuPlayer> AVNuFactory::createNuPlayer(pid_t pid) {
+    return new NuPlayer(pid);
+}
+
+sp<NuPlayer::DecoderBase> AVNuFactory::createPassThruDecoder(
+            const sp<AMessage> &notify,
+            const sp<NuPlayer::Source> &source,
+            const sp<NuPlayer::Renderer> &renderer) {
+    return new NuPlayer::DecoderPassThrough(notify, source, renderer);
+}
+
+sp<NuPlayer::DecoderBase> AVNuFactory::createDecoder(
+            const sp<AMessage> &notify,
+            const sp<NuPlayer::Source> &source,
+            pid_t pid,
+            const sp<NuPlayer::Renderer> &renderer) {
+    return new NuPlayer::Decoder(notify, source, pid, renderer);
+}
+
+sp<NuPlayer::Renderer> AVNuFactory::createRenderer(
+            const sp<MediaPlayerBase::AudioSink> &sink,
+            const sp<AMessage> &notify,
+            uint32_t flags) {
+    return new NuPlayer::Renderer(sink, notify, flags);
+}
+
+// ----- NO TRESSPASSING BEYOND THIS LINE ------
+AVNuFactory::AVNuFactory() {
+}
+
+AVNuFactory::~AVNuFactory() {
+}
+
+//static
+AVNuFactory *AVNuFactory::sInst =
+        ExtensionsLoader<AVNuFactory>::createInstance("createExtendedNuFactory");
+
+} //namespace android
+
diff --git a/media/libavextensions/mediaplayerservice/AVNuUtils.cpp b/media/libavextensions/mediaplayerservice/AVNuUtils.cpp
new file mode 100644
index 0000000..6f1fa4d
--- /dev/null
+++ b/media/libavextensions/mediaplayerservice/AVNuUtils.cpp
@@ -0,0 +1,131 @@
+/*
+ * Copyright (c) 2013 - 2015, 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.
+ */
+
+#define LOG_TAG "AVNuUtils"
+#include <utils/Log.h>
+
+#include <media/stagefright/foundation/ADebug.h>
+#include <media/stagefright/foundation/AMessage.h>
+
+#include <nuplayer/NuPlayer.h>
+#include <nuplayer/NuPlayerDecoderBase.h>
+#include <nuplayer/NuPlayerDecoderPassThrough.h>
+#include <nuplayer/NuPlayerSource.h>
+#include <nuplayer/NuPlayerRenderer.h>
+
+#include "common/ExtensionsLoader.hpp"
+#include "mediaplayerservice/AVNuExtensions.h"
+
+namespace android {
+
+sp<MetaData> AVNuUtils::createPCMMetaFromSource(const sp<MetaData> &sMeta) {
+    return sMeta;
+}
+
+bool AVNuUtils::pcmOffloadException(const sp<MetaData> &) {
+    return true;
+}
+
+bool AVNuUtils::isRAWFormat(const sp<MetaData> &) {
+    return false;
+}
+
+bool AVNuUtils::isRAWFormat(const sp<AMessage> &) {
+    return false;
+}
+
+bool AVNuUtils::isVorbisFormat(const sp<MetaData> &) {
+    return false;
+}
+
+int AVNuUtils::updateAudioBitWidth(audio_format_t /*audioFormat*/,
+        const sp<AMessage> &){
+    return 16;
+}
+
+audio_format_t AVNuUtils::getKeyPCMFormat(const sp<MetaData> &) {
+    return AUDIO_FORMAT_INVALID;
+}
+
+void AVNuUtils::setKeyPCMFormat(const sp<MetaData> &, audio_format_t /*audioFormat*/) {
+
+}
+
+audio_format_t AVNuUtils::getPCMFormat(const sp<AMessage> &) {
+    return AUDIO_FORMAT_PCM_16_BIT;
+}
+
+void AVNuUtils::setPCMFormat(const sp<AMessage> &, audio_format_t /*audioFormat*/) {
+
+}
+
+void AVNuUtils::setSourcePCMFormat(const sp<MetaData> &) {
+
+}
+
+void AVNuUtils::setDecodedPCMFormat(const sp<AMessage> &) {
+
+}
+
+status_t AVNuUtils::convertToSinkFormatIfNeeded(const sp<ABuffer> &, sp<ABuffer> &,
+        audio_format_t /*sinkFormat*/, bool /*isOffload*/) {
+    return INVALID_OPERATION;
+}
+
+void AVNuUtils::printFileName(int) {}
+
+void AVNuUtils::checkFormatChange(bool * /*formatChange*/,
+        const sp<ABuffer> & /*accessUnit*/) {
+}
+
+void AVNuUtils::addFlagsInMeta(const sp<ABuffer> & /*buffer*/,
+        int32_t /*flags*/, bool /*isAudio*/) {
+}
+
+uint32_t AVNuUtils::getFlags() {
+    return 0;
+}
+
+bool AVNuUtils::canUseSetBuffers(const sp<MetaData> &/*Meta*/) {
+    return false;
+}
+
+bool AVNuUtils::dropCorruptFrame() { return false; }
+
+// ----- NO TRESSPASSING BEYOND THIS LINE ------
+AVNuUtils::AVNuUtils() {}
+
+AVNuUtils::~AVNuUtils() {}
+
+//static
+AVNuUtils *AVNuUtils::sInst =
+        ExtensionsLoader<AVNuUtils>::createInstance("createExtendedNuUtils");
+
+} //namespace android
+
diff --git a/media/libavextensions/stagefright/AVExtensions.h b/media/libavextensions/stagefright/AVExtensions.h
new file mode 100644
index 0000000..bb3f51a
--- /dev/null
+++ b/media/libavextensions/stagefright/AVExtensions.h
@@ -0,0 +1,215 @@
+/*
+ * Copyright (c) 2013 - 2015, 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 _AV_EXTENSIONS_H_
+#define _AV_EXTENSIONS_H_
+
+#include <media/stagefright/DataSource.h>
+#include <common/AVExtensionsCommon.h>
+#include <system/audio.h>
+#include <camera/ICamera.h>
+#include <media/mediarecorder.h>
+#include <media/IOMX.h>
+
+namespace android {
+
+class AudioParameter;
+class MetaData;
+class MediaExtractor;
+class MPEG4Writer;
+struct ABuffer;
+struct ACodec;
+struct ALooper;
+struct IMediaHTTPConnection;
+struct MediaCodec;
+struct MediaHTTP;
+struct NuCachedSource2;
+class CameraParameters;
+class MediaBuffer;
+struct AudioSource;
+class CameraSource;
+class CameraSourceTimeLapse;
+class ICamera;
+class ICameraRecordingProxy;
+class String16;
+class IGraphicBufferProducer;
+struct Size;
+
+/*
+ * Factory to create objects of base-classes in libstagefright
+ */
+struct AVFactory {
+    virtual sp<ACodec> createACodec();
+    virtual MediaExtractor* createExtendedExtractor(
+            const sp<DataSource> &source, const char *mime,
+            const sp<AMessage> &meta, const uint32_t flags);
+    virtual sp<MediaExtractor> updateExtractor(
+            sp<MediaExtractor> ext, const sp<DataSource> &source,
+            const char *mime, const sp<AMessage> &meta, const uint32_t flags);
+    virtual sp<NuCachedSource2> createCachedSource(
+            const sp<DataSource> &source,
+            const char *cacheConfig = NULL,
+            bool disconnectAtHighwatermark = false);
+    virtual MediaHTTP* createMediaHTTP(
+            const sp<IMediaHTTPConnection> &conn);
+
+    virtual AudioSource* createAudioSource(
+            audio_source_t inputSource,
+            const String16 &opPackageName,
+            uint32_t sampleRate,
+            uint32_t channels,
+            uint32_t outSampleRate = 0);
+
+    virtual CameraSource *CreateCameraSourceFromCamera(
+            const sp<ICamera> &camera,
+            const sp<ICameraRecordingProxy> &proxy,
+            int32_t cameraId,
+            const String16& clientName,
+            uid_t clientUid,
+            Size videoSize,
+            int32_t frameRate,
+            const sp<IGraphicBufferProducer>& surface,
+            bool storeMetaDataInVideoBuffers = true);
+
+    virtual CameraSourceTimeLapse *CreateCameraSourceTimeLapseFromCamera(
+            const sp<ICamera> &camera,
+            const sp<ICameraRecordingProxy> &proxy,
+            int32_t cameraId,
+            const String16& clientName,
+            uid_t clientUid,
+            Size videoSize,
+            int32_t videoFrameRate,
+            const sp<IGraphicBufferProducer>& surface,
+            int64_t timeBetweenFrameCaptureUs,
+            bool storeMetaDataInVideoBuffers = true);
+    // ----- NO TRESSPASSING BEYOND THIS LINE ------
+    DECLARE_LOADABLE_SINGLETON(AVFactory);
+};
+
+/*
+ * Common delegate to the classes in libstagefright
+ */
+struct AVUtils {
+
+    virtual status_t convertMetaDataToMessage(
+            const sp<MetaData> &meta, sp<AMessage> *format);
+    virtual DataSource::SnifferFunc getExtendedSniffer();
+    virtual status_t mapMimeToAudioFormat( audio_format_t& format, const char* mime);
+    virtual status_t sendMetaDataToHal(const sp<MetaData>& meta, AudioParameter *param);
+
+    virtual sp<MediaCodec> createCustomComponentByName(const sp<ALooper> &looper,
+                const char* mime, bool encoder, const sp<AMessage> &format);
+    virtual bool isEnhancedExtension(const char *extension);
+
+    virtual bool is24bitPCMOffloadEnabled();
+    virtual bool is16bitPCMOffloadEnabled();
+    virtual int getAudioSampleBits(const sp<MetaData> &);
+    virtual int getAudioSampleBits(const sp<AMessage> &);
+    virtual void setPcmSampleBits(const sp<MetaData> &, int32_t /*bitWidth*/);
+    virtual void setPcmSampleBits(const sp<AMessage> &, int32_t /*bitWidth*/);
+
+    virtual audio_format_t updateAudioFormat(audio_format_t audioFormat,
+            const sp<MetaData> &);
+
+    virtual audio_format_t updateAudioFormat(audio_format_t audioFormat,
+            const sp<AMessage> &);
+
+    virtual bool canOffloadAPE(const sp<MetaData> &meta);
+
+    virtual int32_t getAudioMaxInputBufferSize(audio_format_t audioFormat,
+            const sp<AMessage> &);
+
+    virtual bool mapAACProfileToAudioFormat(const sp<MetaData> &,
+            audio_format_t &,
+            uint64_t /*eAacProfile*/);
+
+    virtual bool mapAACProfileToAudioFormat(const sp<AMessage> &,
+            audio_format_t &,
+            uint64_t /*eAacProfile*/);
+
+    virtual void extractCustomCameraKeys(
+            const CameraParameters& /*params*/, sp<MetaData> &/*meta*/) {}
+    virtual void printFileName(int /*fd*/) {}
+    virtual void addDecodingTimesFromBatch(MediaBuffer * /*buf*/,
+            List<int64_t> &/*decodeTimeQueue*/) {}
+
+    virtual bool useQCHWEncoder(const sp<AMessage> &, AString &) { return false; }
+
+    virtual bool canDeferRelease(const sp<MetaData> &/*meta*/) { return false; }
+    virtual void setDeferRelease(sp<MetaData> &/*meta*/) {}
+
+    struct HEVCMuxer {
+
+        virtual bool reassembleHEVCCSD(const AString &mime, sp<ABuffer> csd0, sp<MetaData> &meta);
+
+        virtual void writeHEVCFtypBox(MPEG4Writer *writer);
+
+        virtual status_t makeHEVCCodecSpecificData(const uint8_t *data,
+                  size_t size, void** codecSpecificData,
+                  size_t *codecSpecificDataSize);
+
+        virtual const char *getFourCCForMime(const char *mime);
+
+        virtual void writeHvccBox(MPEG4Writer *writer,
+                  void* codecSpecificData, size_t codecSpecificDataSize,
+                  bool useNalLengthFour);
+
+        virtual bool isVideoHEVC(const char* mime);
+
+        virtual void getHEVCCodecSpecificDataFromInputFormatIfPossible(
+                  sp<MetaData> meta, void **codecSpecificData,
+                  size_t *codecSpecificDataSize, bool *gotAllCodecSpecificData);
+
+    protected:
+        HEVCMuxer() {};
+        virtual ~HEVCMuxer() {};
+        friend struct AVUtils;
+    };
+
+    virtual inline HEVCMuxer& HEVCMuxerUtils() {
+         return mHEVCMuxer;
+    }
+
+    virtual bool isAudioMuxFormatSupported(const char *mime);
+    virtual void cacheCaptureBuffers(sp<ICamera> camera, video_encoder encoder);
+    virtual const char *getCustomCodecsLocation();
+    virtual const char *getCustomCodecsPerformanceLocation();
+
+    virtual void setIntraPeriod(
+                int nPFrames, int nBFrames, const sp<IOMX> OMXhandle,
+                IOMX::node_id nodeID);
+
+private:
+    HEVCMuxer mHEVCMuxer;
+    // ----- NO TRESSPASSING BEYOND THIS LINE ------
+    DECLARE_LOADABLE_SINGLETON(AVUtils);
+};
+
+}
+
+#endif // _AV_EXTENSIONS__H_
diff --git a/media/libavextensions/stagefright/AVFactory.cpp b/media/libavextensions/stagefright/AVFactory.cpp
new file mode 100644
index 0000000..2a3810d
--- /dev/null
+++ b/media/libavextensions/stagefright/AVFactory.cpp
@@ -0,0 +1,135 @@
+/*
+ * Copyright (c) 2013 - 2015, 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.
+ */
+
+#define LOG_TAG "AVFactory"
+#include <utils/Log.h>
+
+#include <media/stagefright/foundation/ADebug.h>
+#include <media/stagefright/foundation/AMessage.h>
+#include <media/stagefright/foundation/ABuffer.h>
+#include <media/stagefright/MediaDefs.h>
+#include <media/stagefright/MediaCodecList.h>
+#include <media/stagefright/MetaData.h>
+#include <media/stagefright/ACodec.h>
+#include <media/stagefright/DataSource.h>
+#include <media/stagefright/MediaDefs.h>
+#include <media/stagefright/MediaExtractor.h>
+#include <media/stagefright/MediaHTTP.h>
+#include <media/stagefright/AudioSource.h>
+#include <media/stagefright/CameraSource.h>
+#include <media/stagefright/CameraSourceTimeLapse.h>
+#include <camera/CameraParameters.h>
+
+#include "common/ExtensionsLoader.hpp"
+#include "stagefright/AVExtensions.h"
+#include "include/NuCachedSource2.h"
+
+namespace android {
+
+sp<ACodec> AVFactory::createACodec() {
+    return new ACodec;
+}
+
+MediaExtractor* AVFactory::createExtendedExtractor(
+         const sp<DataSource> &, const char *, const sp<AMessage> &,
+         const uint32_t) {
+    return NULL;
+}
+
+sp<MediaExtractor> AVFactory::updateExtractor(
+            sp<MediaExtractor> ext, const sp<DataSource> &,
+            const char *, const sp<AMessage> &, const uint32_t) {
+    return ext;
+}
+
+sp<NuCachedSource2> AVFactory::createCachedSource(
+            const sp<DataSource> &source,
+            const char *cacheConfig,
+            bool disconnectAtHighwatermark) {
+    return new NuCachedSource2(source, cacheConfig, disconnectAtHighwatermark);
+}
+
+MediaHTTP* AVFactory::createMediaHTTP(
+         const sp<IMediaHTTPConnection> &conn) {
+    return new MediaHTTP(conn);
+}
+
+AudioSource* AVFactory::createAudioSource(
+            audio_source_t inputSource,
+            const String16 &opPackageName,
+            uint32_t sampleRate,
+            uint32_t channels,
+            uint32_t outSampleRate) {
+    return new AudioSource(inputSource, opPackageName, sampleRate,
+                            channels, outSampleRate);
+}
+
+CameraSource* AVFactory::CreateCameraSourceFromCamera(
+            const sp<ICamera> &camera,
+            const sp<ICameraRecordingProxy> &proxy,
+            int32_t cameraId,
+            const String16& clientName,
+            uid_t clientUid,
+            Size videoSize,
+            int32_t frameRate,
+            const sp<IGraphicBufferProducer>& surface,
+            bool storeMetaDataInVideoBuffers) {
+    return CameraSource::CreateFromCamera(camera, proxy, cameraId,
+            clientName, clientUid, videoSize, frameRate, surface,
+            storeMetaDataInVideoBuffers);
+}
+
+CameraSourceTimeLapse* AVFactory::CreateCameraSourceTimeLapseFromCamera(
+        const sp<ICamera> &camera,
+        const sp<ICameraRecordingProxy> &proxy,
+        int32_t cameraId,
+        const String16& clientName,
+        uid_t clientUid,
+        Size videoSize,
+        int32_t videoFrameRate,
+        const sp<IGraphicBufferProducer>& surface,
+        int64_t timeBetweenFrameCaptureUs,
+        bool storeMetaDataInVideoBuffers) {
+    return CameraSourceTimeLapse::CreateFromCamera(camera, proxy, cameraId,
+            clientName, clientUid, videoSize, videoFrameRate, surface,
+            timeBetweenFrameCaptureUs, storeMetaDataInVideoBuffers);
+}
+// ----- NO TRESSPASSING BEYOND THIS LINE ------
+AVFactory::AVFactory() {
+}
+
+AVFactory::~AVFactory() {
+}
+
+//static
+AVFactory *AVFactory::sInst =
+        ExtensionsLoader<AVFactory>::createInstance("createExtendedFactory");
+
+} //namespace android
+
diff --git a/media/libavextensions/stagefright/AVUtils.cpp b/media/libavextensions/stagefright/AVUtils.cpp
new file mode 100644
index 0000000..bf46aca
--- /dev/null
+++ b/media/libavextensions/stagefright/AVUtils.cpp
@@ -0,0 +1,192 @@
+/*
+ * Copyright (c) 2013 - 2015, 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.
+ */
+
+#define LOG_TAG "AVUtils"
+#include <utils/Log.h>
+
+#include <media/stagefright/foundation/ADebug.h>
+#include <media/stagefright/foundation/AMessage.h>
+#include <media/stagefright/foundation/ABuffer.h>
+#include <media/stagefright/MediaDefs.h>
+#include <media/stagefright/MediaCodecList.h>
+#include <media/stagefright/MetaData.h>
+#include <media/stagefright/ACodec.h>
+#include <media/stagefright/MediaCodec.h>
+
+#include "common/ExtensionsLoader.hpp"
+#include "stagefright/AVExtensions.h"
+
+namespace android {
+
+status_t AVUtils::convertMetaDataToMessage(
+        const sp<MetaData> &, sp<AMessage> *) {
+    return OK;
+}
+
+status_t AVUtils::mapMimeToAudioFormat(
+        audio_format_t&, const char* ) {
+        return OK;
+}
+
+status_t AVUtils::sendMetaDataToHal(
+        const sp<MetaData>&, AudioParameter *){
+        return OK;
+}
+
+bool AVUtils::is24bitPCMOffloadEnabled() {return false;}
+bool AVUtils::is16bitPCMOffloadEnabled() {return false;}
+
+int AVUtils::getAudioSampleBits(const sp<MetaData> &) {
+    return 16;
+}
+
+int AVUtils::getAudioSampleBits(const sp<AMessage> &) {
+    return 16;
+}
+
+void AVUtils::setPcmSampleBits(const sp<AMessage> &, int32_t /*bitWidth*/) {
+}
+
+void AVUtils::setPcmSampleBits(const sp<MetaData> &, int32_t /*bitWidth*/) {
+}
+
+audio_format_t AVUtils::updateAudioFormat(audio_format_t audioFormat,
+        const sp<MetaData> &){
+    return audioFormat;
+}
+
+audio_format_t AVUtils::updateAudioFormat(audio_format_t audioFormat,
+        const sp<AMessage> &){
+    return audioFormat;
+}
+
+static bool dumbSniffer(
+        const sp<DataSource> &, String8 *,
+        float *, sp<AMessage> *) {
+    return false;
+}
+
+DataSource::SnifferFunc AVUtils::getExtendedSniffer() {
+    return dumbSniffer;
+}
+
+sp<MediaCodec> AVUtils::createCustomComponentByName(
+        const sp<ALooper> &, const char* , bool, const sp<AMessage> &) {
+    return NULL;
+}
+
+bool AVUtils::canOffloadAPE(const sp<MetaData> &) {
+   return true;
+}
+
+int32_t AVUtils::getAudioMaxInputBufferSize(audio_format_t, const sp<AMessage> &) {
+    return 0;
+}
+
+bool AVUtils::mapAACProfileToAudioFormat(const sp<MetaData> &, audio_format_t &,
+                 uint64_t  /*eAacProfile*/) {
+    return false ;
+}
+
+bool AVUtils::mapAACProfileToAudioFormat(const sp<AMessage> &,  audio_format_t &,
+                 uint64_t  /*eAacProfile*/) {
+    return false ;
+}
+
+bool AVUtils::isEnhancedExtension(const char *) {
+    return false;
+}
+
+bool AVUtils::HEVCMuxer::reassembleHEVCCSD(const AString &/*mime*/, sp<ABuffer> /*csd0*/, sp<MetaData> &/*meta*/) {
+    return false;
+}
+
+void AVUtils::HEVCMuxer::writeHEVCFtypBox(MPEG4Writer * /*writer*/) {
+    return;
+}
+
+status_t AVUtils::HEVCMuxer::makeHEVCCodecSpecificData(const uint8_t * /*data*/,
+        size_t /*size*/, void ** /*codecSpecificData*/,
+        size_t * /*codecSpecificDataSize*/) {
+    return UNKNOWN_ERROR;
+}
+
+const char *AVUtils::HEVCMuxer::getFourCCForMime(const char * /*mime*/) {
+    return NULL;
+}
+
+void AVUtils::HEVCMuxer::writeHvccBox(MPEG4Writer * /*writer*/,
+        void * /*codecSpecificData*/, size_t /*codecSpecificDataSize*/,
+        bool /*useNalLengthFour*/) {
+    return;
+}
+
+bool AVUtils::HEVCMuxer::isVideoHEVC(const char * /*mime*/) {
+    return false;
+}
+
+void AVUtils::HEVCMuxer::getHEVCCodecSpecificDataFromInputFormatIfPossible(
+        sp<MetaData> /*meta*/, void ** /*codecSpecificData*/,
+        size_t * /*codecSpecificDataSize*/, bool * /*gotAllCodecSpecificData*/) {
+    return;
+}
+
+bool AVUtils::isAudioMuxFormatSupported(const char *) {
+    return true;
+}
+
+void AVUtils::cacheCaptureBuffers(sp<ICamera>, video_encoder) {
+    return;
+}
+
+const char *AVUtils::getCustomCodecsLocation() {
+    return "/etc/media_codecs.xml";
+}
+
+void AVUtils::setIntraPeriod(
+        int, int, const sp<IOMX>,
+        IOMX::node_id) {
+    return;
+}
+
+const char *AVUtils::getCustomCodecsPerformanceLocation() {
+    return "/etc/media_codecs_performance.xml";
+}
+
+// ----- NO TRESSPASSING BEYOND THIS LINE ------
+AVUtils::AVUtils() {}
+
+AVUtils::~AVUtils() {}
+
+//static
+AVUtils *AVUtils::sInst =
+        ExtensionsLoader<AVUtils>::createInstance("createExtendedUtils");
+
+} //namespace android
+
diff --git a/media/libavextensions/stagefright/ExtendedMediaDefs.cpp b/media/libavextensions/stagefright/ExtendedMediaDefs.cpp
new file mode 100644
index 0000000..cf2683c
--- /dev/null
+++ b/media/libavextensions/stagefright/ExtendedMediaDefs.cpp
@@ -0,0 +1,68 @@
+/*Copyright (c) 2012 - 2015, 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.
+ *
+ */
+
+#include <stagefright/ExtendedMediaDefs.h>
+
+namespace android {
+
+const char *MEDIA_MIMETYPE_AUDIO_EVRC = "audio/evrc";
+const char *MEDIA_MIMETYPE_VIDEO_WMV = "video/x-ms-wmv";
+const char *MEDIA_MIMETYPE_VIDEO_WMV_VC1 = "video/wvc1";
+const char *MEDIA_MIMETYPE_AUDIO_WMA = "audio/x-ms-wma";
+const char *MEDIA_MIMETYPE_AUDIO_WMA_PRO = "audio/x-ms-wma-pro";
+const char *MEDIA_MIMETYPE_AUDIO_WMA_LOSSLESS = "audio/x-ms-wma-lossless";
+const char *MEDIA_MIMETYPE_CONTAINER_ASF = "video/x-ms-asf";
+const char *MEDIA_MIMETYPE_VIDEO_DIVX = "video/divx";
+const char *MEDIA_MIMETYPE_CONTAINER_AAC = "audio/aac";
+const char *MEDIA_MIMETYPE_CONTAINER_QCP = "audio/vnd.qcelp";
+const char *MEDIA_MIMETYPE_VIDEO_DIVX311 = "video/divx311";
+const char *MEDIA_MIMETYPE_VIDEO_DIVX4 = "video/divx4";
+const char *MEDIA_MIMETYPE_CONTAINER_MPEG2 = "video/mp2";
+const char *MEDIA_MIMETYPE_CONTAINER_3G2 = "video/3g2";
+const char *MEDIA_MIMETYPE_AUDIO_DTS = "audio/dts";
+const char *MEDIA_MIMETYPE_AUDIO_DTS_LBR = "audio/dts-lbr";
+const char *MEDIA_MIMETYPE_AUDIO_AMR_WB_PLUS = "audio/amr-wb-plus";
+const char *MEDIA_MIMETYPE_AUDIO_AIFF = "audio/x-aiff";
+const char *MEDIA_MIMETYPE_AUDIO_ALAC = "audio/alac";
+const char *MEDIA_MIMETYPE_AUDIO_APE = "audio/x-ape";
+const char *MEDIA_MIMETYPE_CONTAINER_QCAMR_NB = "audio/qc-amr";
+const char *MEDIA_MIMETYPE_CONTAINER_QCAMR_WB = "audio/qc-amr-wb";
+const char *MEDIA_MIMETYPE_CONTAINER_QCMPEG = "audio/qc-mpeg";
+const char *MEDIA_MIMETYPE_CONTAINER_QCWAV = "audio/qc-wav";
+const char *MEDIA_MIMETYPE_CONTAINER_QCMPEG2TS = "video/qc-mp2ts";
+const char *MEDIA_MIMETYPE_CONTAINER_QCMPEG2PS = "video/qc-mp2ps";
+const char *MEDIA_MIMETYPE_CONTAINER_QCMPEG4 = "video/qc-mp4";
+const char *MEDIA_MIMETYPE_CONTAINER_QCMATROSKA = "video/qc-matroska";
+const char *MEDIA_MIMETYPE_CONTAINER_QCOGG = "video/qc-ogg";
+const char *MEDIA_MIMETYPE_CONTAINER_QCFLV = "video/qc-flv";
+const char *MEDIA_MIMETYPE_VIDEO_VPX = "video/x-vnd.on2.vp8"; //backward compatibility
+const char *MEDIA_MIMETYPE_CONTAINER_QTIFLAC = "audio/qti-flac";
+const char *MEDIA_MIMETYPE_VIDEO_MPEG4_DP = "video/mp4v-esdp";
+
+}  // namespace android
diff --git a/media/libeffects/data/audio_effects.conf b/media/libeffects/data/audio_effects.conf
index c3c4b67..5ae93d3 100644
--- a/media/libeffects/data/audio_effects.conf
+++ b/media/libeffects/data/audio_effects.conf
@@ -1,3 +1,22 @@
+#
+# This file was modified by Dolby Laboratories, Inc. The portions of the
+# code that are surrounded by "DOLBY..." are copyrighted and
+# licensed separately, as follows:
+#
+#  (C) 2012-2015 Dolby Laboratories, Inc.
+#
+# 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.
+#
 # List of effect libraries to load. Each library element must contain a "path" element
 # giving the full path of the library .so file.
 #    libraries {
@@ -38,6 +57,14 @@
   loudness_enhancer {
     path /system/lib/soundfx/libldnhncr.so
   }
+#DOLBY_DAP
+  ds_sw {
+    path /system/vendor/lib/soundfx/libswdap.so
+  }
+  ds_hw {
+    path /system/vendor/lib/soundfx/libhwdap.so
+  }
+#DOLBY_END
 }
 
 # Default pre-processing library. Add to audio_effect.conf "libraries" section if
@@ -129,6 +156,22 @@
     library loudness_enhancer
     uuid fa415329-2034-4bea-b5dc-5b381c8d1e2c
   }
+#DOLBY_DAP
+  ds {
+    library proxy
+    uuid 9d4921da-8225-4f29-aefa-39537a04bcaa
+
+    libsw {
+      library ds_sw
+      uuid 6ab06da4-c516-4611-8166-452799218539
+    }
+
+    libhw {
+      library ds_hw
+      uuid a0c30891-8246-4aef-b8ad-d53e26da0253
+    }
+  }
+#DOLBY_END
 }
 
 # Default pre-processing effects. Add to audio_effect.conf "effects" section if
diff --git a/media/libeffects/downmix/EffectDownmix.c b/media/libeffects/downmix/EffectDownmix.c
index 4a41037..18059b2 100644
--- a/media/libeffects/downmix/EffectDownmix.c
+++ b/media/libeffects/downmix/EffectDownmix.c
@@ -624,9 +624,12 @@
         pDownmixer->apply_volume_correction = false;
         pDownmixer->input_channel_count = 8; // matches default input of AUDIO_CHANNEL_OUT_7POINT1
     } else {
-        // when configuring the effect, do not allow a blank channel mask
-        if (pConfig->inputCfg.channels == 0) {
-            ALOGE("Downmix_Configure error: input channel mask can't be 0");
+        // when configuring the effect, do not allow a blank or unsupported channel mask
+        if ((pConfig->inputCfg.channels == 0) ||
+            (Downmix_foldGeneric(pConfig->inputCfg.channels,
+                                NULL, NULL, 0, false) == false)) {
+            ALOGE("Downmix_Configure error: input channel mask(0x%x) not supported",
+                                                        pConfig->inputCfg.channels);
             return -EINVAL;
         }
         pDownmixer->input_channel_count =
diff --git a/media/libeffects/lvm/wrapper/Bundle/EffectBundle.cpp b/media/libeffects/lvm/wrapper/Bundle/EffectBundle.cpp
index af904a6..e01c414 100644
--- a/media/libeffects/lvm/wrapper/Bundle/EffectBundle.cpp
+++ b/media/libeffects/lvm/wrapper/Bundle/EffectBundle.cpp
@@ -29,6 +29,7 @@
 #include "EffectBundle.h"
 #include "math.h"
 
+#include <media/stagefright/foundation/ADebug.h>
 
 // effect_handle_t interface implementation for bass boost
 extern "C" const struct effect_interface_s gLvmEffectInterface;
@@ -226,7 +227,7 @@
         pContext->pBundledContext->bVirtualizerTempDisabled = LVM_FALSE;
         pContext->pBundledContext->nOutputDevice            = AUDIO_DEVICE_NONE;
         pContext->pBundledContext->nVirtualizerForcedDevice = AUDIO_DEVICE_NONE;
-        pContext->pBundledContext->NumberEffectsEnabled     = 0;
+        pContext->pBundledContext->EffectsBitMap            = 0;
         pContext->pBundledContext->NumberEffectsCalled      = 0;
         pContext->pBundledContext->firstVolume              = LVM_TRUE;
         pContext->pBundledContext->volume                   = 0;
@@ -366,28 +367,28 @@
         ALOGV("\tEffectRelease LVM_BASS_BOOST Clearing global intstantiated flag");
         pSessionContext->bBassInstantiated = LVM_FALSE;
         if(pContext->pBundledContext->SamplesToExitCountBb > 0){
-            pContext->pBundledContext->NumberEffectsEnabled--;
+            pContext->pBundledContext->EffectsBitMap &= ~(1 << LVM_BASS_BOOST);
         }
         pContext->pBundledContext->SamplesToExitCountBb = 0;
     } else if(pContext->EffectType == LVM_VIRTUALIZER) {
         ALOGV("\tEffectRelease LVM_VIRTUALIZER Clearing global intstantiated flag");
         pSessionContext->bVirtualizerInstantiated = LVM_FALSE;
         if(pContext->pBundledContext->SamplesToExitCountVirt > 0){
-            pContext->pBundledContext->NumberEffectsEnabled--;
+            pContext->pBundledContext->EffectsBitMap &= ~(1 << LVM_VIRTUALIZER);
         }
         pContext->pBundledContext->SamplesToExitCountVirt = 0;
     } else if(pContext->EffectType == LVM_EQUALIZER) {
         ALOGV("\tEffectRelease LVM_EQUALIZER Clearing global intstantiated flag");
         pSessionContext->bEqualizerInstantiated =LVM_FALSE;
         if(pContext->pBundledContext->SamplesToExitCountEq > 0){
-            pContext->pBundledContext->NumberEffectsEnabled--;
+            pContext->pBundledContext->EffectsBitMap &= ~(1 << LVM_EQUALIZER);
         }
         pContext->pBundledContext->SamplesToExitCountEq = 0;
     } else if(pContext->EffectType == LVM_VOLUME) {
         ALOGV("\tEffectRelease LVM_VOLUME Clearing global intstantiated flag");
         pSessionContext->bVolumeInstantiated = LVM_FALSE;
         if (pContext->pBundledContext->bVolumeEnabled == LVM_TRUE){
-            pContext->pBundledContext->NumberEffectsEnabled--;
+            pContext->pBundledContext->EffectsBitMap &= ~(1 << LVM_VOLUME);
         }
     } else {
         ALOGV("\tLVM_ERROR : EffectRelease : Unsupported effect\n\n\n\n\n\n\n");
@@ -563,6 +564,7 @@
     for (int i=0; i<LVM_NR_MEMORY_REGIONS; i++){
         if (MemTab.Region[i].Size != 0){
             MemTab.Region[i].pBaseAddress = malloc(MemTab.Region[i].Size);
+            CHECK(MemTab.Region[i].pBaseAddress != NULL);
 
             if (MemTab.Region[i].pBaseAddress == LVM_NULL){
                 ALOGV("\tLVM_ERROR :LvmBundle_init CreateInstance Failed to allocate %" PRIu32
@@ -729,6 +731,7 @@
             }
             pContext->pBundledContext->workBuffer =
                     (LVM_INT16 *)malloc(frameCount * sizeof(LVM_INT16) * 2);
+            CHECK(pContext->pBundledContext->workBuffer != NULL);
             pContext->pBundledContext->frameCount = frameCount;
         }
         pOutTmp = pContext->pBundledContext->workBuffer;
@@ -2753,7 +2756,7 @@
                      return -EINVAL;
                 }
                 if(pContext->pBundledContext->SamplesToExitCountBb <= 0){
-                    pContext->pBundledContext->NumberEffectsEnabled++;
+                    pContext->pBundledContext->EffectsBitMap |= (1 << LVM_BASS_BOOST);
                 }
                 pContext->pBundledContext->SamplesToExitCountBb =
                      (LVM_INT32)(pContext->pBundledContext->SamplesPerSecond*0.1);
@@ -2766,7 +2769,7 @@
                     return -EINVAL;
                 }
                 if(pContext->pBundledContext->SamplesToExitCountEq <= 0){
-                    pContext->pBundledContext->NumberEffectsEnabled++;
+                    pContext->pBundledContext->EffectsBitMap |= (1 << LVM_EQUALIZER);
                 }
                 pContext->pBundledContext->SamplesToExitCountEq =
                      (LVM_INT32)(pContext->pBundledContext->SamplesPerSecond*0.1);
@@ -2778,7 +2781,7 @@
                     return -EINVAL;
                 }
                 if(pContext->pBundledContext->SamplesToExitCountVirt <= 0){
-                    pContext->pBundledContext->NumberEffectsEnabled++;
+                    pContext->pBundledContext->EffectsBitMap |= (1 << LVM_VIRTUALIZER);
                 }
                 pContext->pBundledContext->SamplesToExitCountVirt =
                      (LVM_INT32)(pContext->pBundledContext->SamplesPerSecond*0.1);
@@ -2790,7 +2793,7 @@
                     ALOGV("\tEffect_setEnabled() LVM_VOLUME is already enabled");
                     return -EINVAL;
                 }
-                pContext->pBundledContext->NumberEffectsEnabled++;
+                pContext->pBundledContext->EffectsBitMap |= (1 << LVM_VOLUME);
                 pContext->pBundledContext->bVolumeEnabled = LVM_TRUE;
                 break;
             default:
@@ -2807,6 +2810,9 @@
                     ALOGV("\tEffect_setEnabled() LVM_BASS_BOOST is already disabled");
                     return -EINVAL;
                 }
+                if(pContext->pBundledContext->SamplesToExitCountBb <= 0) {
+                    pContext->pBundledContext->EffectsBitMap &= ~(1 << LVM_BASS_BOOST);
+                }
                 pContext->pBundledContext->bBassEnabled = LVM_FALSE;
                 break;
             case LVM_EQUALIZER:
@@ -2814,6 +2820,9 @@
                     ALOGV("\tEffect_setEnabled() LVM_EQUALIZER is already disabled");
                     return -EINVAL;
                 }
+                if(pContext->pBundledContext->SamplesToExitCountEq <= 0) {
+                    pContext->pBundledContext->EffectsBitMap &= ~(1 << LVM_EQUALIZER);
+                }
                 pContext->pBundledContext->bEqualizerEnabled = LVM_FALSE;
                 break;
             case LVM_VIRTUALIZER:
@@ -2821,6 +2830,9 @@
                     ALOGV("\tEffect_setEnabled() LVM_VIRTUALIZER is already disabled");
                     return -EINVAL;
                 }
+                if(pContext->pBundledContext->SamplesToExitCountVirt <= 0) {
+                    pContext->pBundledContext->EffectsBitMap &= ~(1 << LVM_VIRTUALIZER);
+                }
                 pContext->pBundledContext->bVirtualizerEnabled = LVM_FALSE;
                 break;
             case LVM_VOLUME:
@@ -2828,6 +2840,7 @@
                     ALOGV("\tEffect_setEnabled() LVM_VOLUME is already disabled");
                     return -EINVAL;
                 }
+                pContext->pBundledContext->EffectsBitMap &= ~(1 << LVM_VOLUME);
                 pContext->pBundledContext->bVolumeEnabled = LVM_FALSE;
                 break;
             default:
@@ -2877,7 +2890,7 @@
     LVM_INT16   *out = (LVM_INT16 *)outBuffer->raw;
 
 //ALOGV("\tEffect_process Start : Enabled = %d     Called = %d (%8d %8d %8d)",
-//pContext->pBundledContext->NumberEffectsEnabled,pContext->pBundledContext->NumberEffectsCalled,
+//popcount(pContext->pBundledContext->EffectsBitMap), pContext->pBundledContext->NumberEffectsCalled,
 //    pContext->pBundledContext->SamplesToExitCountBb,
 //    pContext->pBundledContext->SamplesToExitCountVirt,
 //    pContext->pBundledContext->SamplesToExitCountEq);
@@ -2911,7 +2924,7 @@
         }
         if(pContext->pBundledContext->SamplesToExitCountBb <= 0) {
             status = -ENODATA;
-            pContext->pBundledContext->NumberEffectsEnabled--;
+            pContext->pBundledContext->EffectsBitMap &= ~(1 << LVM_BASS_BOOST);
             ALOGV("\tEffect_process() this is the last frame for LVM_BASS_BOOST");
         }
     }
@@ -2919,7 +2932,7 @@
         (pContext->EffectType == LVM_VOLUME)){
         //ALOGV("\tEffect_process() LVM_VOLUME Effect is not enabled");
         status = -ENODATA;
-        pContext->pBundledContext->NumberEffectsEnabled--;
+        pContext->pBundledContext->EffectsBitMap &= ~(1 << LVM_VOLUME);
     }
     if ((pContext->pBundledContext->bEqualizerEnabled == LVM_FALSE)&&
         (pContext->EffectType == LVM_EQUALIZER)){
@@ -2931,7 +2944,7 @@
         }
         if(pContext->pBundledContext->SamplesToExitCountEq <= 0) {
             status = -ENODATA;
-            pContext->pBundledContext->NumberEffectsEnabled--;
+            pContext->pBundledContext->EffectsBitMap &= ~(1 << LVM_EQUALIZER);
             ALOGV("\tEffect_process() this is the last frame for LVM_EQUALIZER");
         }
     }
@@ -2945,7 +2958,7 @@
         }
         if(pContext->pBundledContext->SamplesToExitCountVirt <= 0) {
             status = -ENODATA;
-            pContext->pBundledContext->NumberEffectsEnabled--;
+            pContext->pBundledContext->EffectsBitMap &= ~(1 << LVM_VIRTUALIZER);
             ALOGV("\tEffect_process() this is the last frame for LVM_VIRTUALIZER");
         }
     }
@@ -2955,9 +2968,9 @@
     }
 
     if(pContext->pBundledContext->NumberEffectsCalled ==
-       pContext->pBundledContext->NumberEffectsEnabled){
+       popcount(pContext->pBundledContext->EffectsBitMap)){
         //ALOGV("\tEffect_process     Calling process with %d effects enabled, %d called: Effect %d",
-        //pContext->pBundledContext->NumberEffectsEnabled,
+        //popcount(pContext->pBundledContext->EffectsBitMap),
         //pContext->pBundledContext->NumberEffectsCalled, pContext->EffectType);
 
         if(status == -ENODATA){
@@ -2976,7 +2989,7 @@
         }
     } else {
         //ALOGV("\tEffect_process Not Calling process with %d effects enabled, %d called: Effect %d",
-        //pContext->pBundledContext->NumberEffectsEnabled,
+        //popcount(pContext->pBundledContext->EffectsBitMap),
         //pContext->pBundledContext->NumberEffectsCalled, pContext->EffectType);
         // 2 is for stereo input
         if (pContext->config.outputCfg.accessMode == EFFECT_BUFFER_ACCESS_ACCUMULATE) {
@@ -3028,9 +3041,9 @@
     // called the number of effect called could be greater
     // pContext->pBundledContext->NumberEffectsCalled = 0;
 
-    //ALOGV("\tEffect_command NumberEffectsCalled = %d, NumberEffectsEnabled = %d",
-    //        pContext->pBundledContext->NumberEffectsCalled,
-    //        pContext->pBundledContext->NumberEffectsEnabled);
+    //ALOGV("\tEffect_command: Enabled = %d     Called = %d",
+    //        popcount(pContext->pBundledContext->EffectsBitMap),
+    //        pContext->pBundledContext->NumberEffectsCalled);
 
     switch (cmdCode){
         case EFFECT_CMD_INIT:
@@ -3311,7 +3324,7 @@
                         (device == AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER)){
                     ALOGV("\tEFFECT_CMD_SET_DEVICE device is invalid for LVM_BASS_BOOST %d",
                           *(int32_t *)pCmdData);
-                    ALOGV("\tEFFECT_CMD_SET_DEVICE temporary disable LVM_BAS_BOOST");
+                    ALOGV("\tEFFECT_CMD_SET_DEVICE temporary disable LVM_BASS_BOOST");
 
                     // If a device doesnt support bassboost the effect must be temporarily disabled
                     // the effect must still report its original state as this can only be changed
diff --git a/media/libeffects/lvm/wrapper/Bundle/EffectBundle.h b/media/libeffects/lvm/wrapper/Bundle/EffectBundle.h
index 9459b87..5fa5668 100644
--- a/media/libeffects/lvm/wrapper/Bundle/EffectBundle.h
+++ b/media/libeffects/lvm/wrapper/Bundle/EffectBundle.h
@@ -75,8 +75,8 @@
     bool                            bVirtualizerTempDisabled; /* Flag for effect to be re-enabled */
     audio_devices_t                 nOutputDevice;            /* Output device for the effect */
     audio_devices_t                 nVirtualizerForcedDevice; /* Forced device virtualization mode*/
-    int                             NumberEffectsEnabled;     /* Effects in this session */
     int                             NumberEffectsCalled;      /* Effects called so far */
+    uint32_t                        EffectsBitMap;            /* Effects enable bit mask */
     bool                            firstVolume;              /* No smoothing on first Vol change */
     // Saved parameters for each effect */
     // Bass Boost
diff --git a/media/libmedia/Android.mk b/media/libmedia/Android.mk
index a3c3d3c..74e4eb1 100644
--- a/media/libmedia/Android.mk
+++ b/media/libmedia/Android.mk
@@ -69,12 +69,21 @@
     StringArray.cpp \
     AudioPolicy.cpp
 
+
+#QTI Resampler
+ifeq ($(call is-vendor-board-platform,QCOM), true)
+ifeq ($(strip $(AUDIO_FEATURE_ENABLED_EXTN_RESAMPLER)), true)
+LOCAL_CFLAGS += -DQTI_RESAMPLER
+endif
+endif
+#QTI Resampler
+
 LOCAL_SHARED_LIBRARIES := \
 	libui liblog libcutils libutils libbinder libsonivox libicuuc libicui18n libexpat \
         libcamera_client libstagefright_foundation \
         libgui libdl libaudioutils libnbaio
 
-LOCAL_WHOLE_STATIC_LIBRARIES := libmedia_helper
+LOCAL_WHOLE_STATIC_LIBRARIES := libmedia_helper libavmediaextentions
 
 LOCAL_MODULE:= libmedia
 
@@ -84,6 +93,7 @@
     $(TOP)/frameworks/native/include/media/openmax \
     $(TOP)/frameworks/av/include/media/ \
     $(TOP)/frameworks/av/media/libstagefright \
+    $(TOP)/frameworks/av/media/libavextensions \
     $(call include-path-for, audio-effects) \
     $(call include-path-for, audio-utils)
 
diff --git a/media/libmedia/AudioParameter.cpp b/media/libmedia/AudioParameter.cpp
index 8c8cf45..535f459 100644
--- a/media/libmedia/AudioParameter.cpp
+++ b/media/libmedia/AudioParameter.cpp
@@ -32,6 +32,7 @@
 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;
+const char * const AudioParameter::keyDevShutdown = AUDIO_PARAMETER_KEY_DEV_SHUTDOWN;
 
 AudioParameter::AudioParameter(const String8& keyValuePairs)
 {
diff --git a/media/libmedia/AudioRecord.cpp b/media/libmedia/AudioRecord.cpp
index 011b31f..e84a770 100644
--- a/media/libmedia/AudioRecord.cpp
+++ b/media/libmedia/AudioRecord.cpp
@@ -26,6 +26,7 @@
 #include <utils/Log.h>
 #include <private/media/AudioTrackShared.h>
 #include <media/IAudioFlinger.h>
+#include "SeempLog.h"
 
 #define WAIT_PERIOD_MS          10
 
@@ -293,6 +294,7 @@
 status_t AudioRecord::start(AudioSystem::sync_event_t event, int triggerSession)
 {
     ALOGV("start, sync event %d trigger session %d", event, triggerSession);
+    SEEMPLOG_RECORD(71,"");
 
     AutoMutex lock(mLock);
     if (mActive) {
diff --git a/media/libmedia/AudioTrack.cpp b/media/libmedia/AudioTrack.cpp
index ab3d66a..e5f1f5f 100644
--- a/media/libmedia/AudioTrack.cpp
+++ b/media/libmedia/AudioTrack.cpp
@@ -30,6 +30,8 @@
 #include <media/IAudioFlinger.h>
 #include <media/AudioPolicyHelper.h>
 #include <media/AudioResamplerPublic.h>
+#include "media/AVMediaExtensions.h"
+#include <cutils/properties.h>
 
 #define WAIT_PERIOD_MS                  10
 #define WAIT_STREAM_END_TIMEOUT_SEC     120
@@ -167,7 +169,8 @@
       mPreviousPriority(ANDROID_PRIORITY_NORMAL),
       mPreviousSchedulingGroup(SP_DEFAULT),
       mPausedPosition(0),
-      mSelectedDeviceId(AUDIO_PORT_HANDLE_NONE)
+      mSelectedDeviceId(AUDIO_PORT_HANDLE_NONE),
+      mPlaybackRateSet(false)
 {
     mAttributes.content_type = AUDIO_CONTENT_TYPE_UNKNOWN;
     mAttributes.usage = AUDIO_USAGE_UNKNOWN;
@@ -197,7 +200,8 @@
       mPreviousPriority(ANDROID_PRIORITY_NORMAL),
       mPreviousSchedulingGroup(SP_DEFAULT),
       mPausedPosition(0),
-      mSelectedDeviceId(AUDIO_PORT_HANDLE_NONE)
+      mSelectedDeviceId(AUDIO_PORT_HANDLE_NONE),
+      mPlaybackRateSet(false)
 {
     mStatus = set(streamType, sampleRate, format, channelMask,
             frameCount, flags, cbf, user, notificationFrames,
@@ -227,7 +231,8 @@
       mPreviousPriority(ANDROID_PRIORITY_NORMAL),
       mPreviousSchedulingGroup(SP_DEFAULT),
       mPausedPosition(0),
-      mSelectedDeviceId(AUDIO_PORT_HANDLE_NONE)
+      mSelectedDeviceId(AUDIO_PORT_HANDLE_NONE),
+      mPlaybackRateSet(false)
 {
     mStatus = set(streamType, sampleRate, format, channelMask,
             0 /*frameCount*/, flags, cbf, user, notificationFrames,
@@ -541,6 +546,12 @@
         // force refresh of remaining frames by processAudioBuffer() as last
         // write before stop could be partial.
         mRefreshRemaining = true;
+
+       // for static track, clear the old flags when start from stopped state
+       if (mSharedBuffer != 0)
+           android_atomic_and(
+           ~(CBLK_LOOP_CYCLE | CBLK_LOOP_FINAL | CBLK_BUFFER_END),
+           &mCblk->mFlags);
     }
     mNewPosition = mPosition + mUpdatePeriod;
     int32_t flags = android_atomic_and(~CBLK_DISABLED, &mCblk->mFlags);
@@ -846,6 +857,14 @@
     //set effective rates
     mProxy->setPlaybackRate(playbackRateTemp);
     mProxy->setSampleRate(effectiveRate); // FIXME: not quite "atomic" with setPlaybackRate
+
+    // fallback out of Direct PCM if setPlaybackRate is called on a track offloaded
+    // session. Do this by setting mPlaybackRateSet to true
+    if (mTrackOffloaded) {
+        mPlaybackRateSet = true;
+        android_atomic_or(CBLK_INVALID, &mCblk->mFlags);
+    }
+
     return NO_ERROR;
 }
 
@@ -1001,10 +1020,18 @@
             return NO_ERROR;
         }
 
+        if (AVMediaUtils::get()->AudioTrackIsPcmOffloaded(mFormat) &&
+                AVMediaUtils::get()->AudioTrackGetPosition(this, position) == NO_ERROR) {
+            return NO_ERROR;
+        }
+
         if (mOutput != AUDIO_IO_HANDLE_NONE) {
             uint32_t halFrames; // actually unused
-            (void) AudioSystem::getRenderPosition(mOutput, &halFrames, &dspFrames);
-            // FIXME: on getRenderPosition() error, we return OK with frame position 0.
+            status_t status = AudioSystem::getRenderPosition(mOutput, &halFrames, &dspFrames);
+            if (status != NO_ERROR) {
+                ALOGW("failed to getRenderPosition for offload session status %d", status);
+                return INVALID_OPERATION;
+            }
         }
         // FIXME: dspFrames may not be zero in (mState == STATE_STOPPED || mState == STATE_FLUSHED)
         // due to hardware latency. We leave this behavior for now.
@@ -1129,11 +1156,16 @@
     audio_stream_type_t streamType = mStreamType;
     audio_attributes_t *attr = (mStreamType == AUDIO_STREAM_DEFAULT) ? &mAttributes : NULL;
 
-    status_t status;
-    status = AudioSystem::getOutputForAttr(attr, &output,
+    audio_offload_info_t tOffloadInfo = AUDIO_INFO_INITIALIZER;
+    if (mPlaybackRateSet == true && mOffloadInfo == NULL && mFormat == AUDIO_FORMAT_PCM_16_BIT) {
+        mOffloadInfo = &tOffloadInfo;
+    }
+    status_t status = AudioSystem::getOutputForAttr(attr, &output,
                                            (audio_session_t)mSessionId, &streamType, mClientUid,
                                            mSampleRate, mFormat, mChannelMask,
                                            mFlags, mSelectedDeviceId, mOffloadInfo);
+    //reset offload info if forced
+    mOffloadInfo = (mOffloadInfo == &tOffloadInfo) ? NULL : mOffloadInfo;
 
     if (status != NO_ERROR || output == AUDIO_IO_HANDLE_NONE) {
         ALOGE("Could not get audio output for session %d, stream type %d, usage %d, sample rate %u, format %#x,"
@@ -1141,6 +1173,7 @@
               mSessionId, streamType, mAttributes.usage, mSampleRate, mFormat, mChannelMask, mFlags);
         return BAD_VALUE;
     }
+    mTrackOffloaded = AVMediaUtils::get()->AudioTrackIsTrackOffloaded(output);
     {
     // Now that we have a reference to an I/O handle and have not yet handed it off to AudioFlinger,
     // we must release it ourselves if anything goes wrong.
@@ -1203,6 +1236,7 @@
             frameCount = mSharedBuffer->size();
         } else if (frameCount == 0) {
             frameCount = mAfFrameCount;
+            frameCount = AVMediaUtils::get()->AudioTrackGetOffloadFrameCount(frameCount);
         }
         if (mNotificationFramesAct != frameCount) {
             mNotificationFramesAct = frameCount;
@@ -1838,40 +1872,6 @@
     // get anchor time to account for callbacks.
     const nsecs_t timeBeforeCallbacks = systemTime();
 
-    if (waitStreamEnd) {
-        // FIXME:  Instead of blocking in proxy->waitStreamEndDone(), Callback thread
-        // should wait on proxy futex and handle CBLK_STREAM_END_DONE within this function
-        // (and make sure we don't callback for more data while we're stopping).
-        // This helps with position, marker notifications, and track invalidation.
-        struct timespec timeout;
-        timeout.tv_sec = WAIT_STREAM_END_TIMEOUT_SEC;
-        timeout.tv_nsec = 0;
-
-        status_t status = proxy->waitStreamEndDone(&timeout);
-        switch (status) {
-        case NO_ERROR:
-        case DEAD_OBJECT:
-        case TIMED_OUT:
-            mCbf(EVENT_STREAM_END, mUserData, NULL);
-            {
-                AutoMutex lock(mLock);
-                // The previously assigned value of waitStreamEnd is no longer valid,
-                // since the mutex has been unlocked and either the callback handler
-                // or another thread could have re-started the AudioTrack during that time.
-                waitStreamEnd = mState == STATE_STOPPING;
-                if (waitStreamEnd) {
-                    mState = STATE_STOPPED;
-                    mReleased = 0;
-                }
-            }
-            if (waitStreamEnd && status != DEAD_OBJECT) {
-               return NS_INACTIVE;
-            }
-            break;
-        }
-        return 0;
-    }
-
     // perform callbacks while unlocked
     if (newUnderrun) {
         mCbf(EVENT_UNDERRUN, mUserData, NULL);
@@ -1902,6 +1902,46 @@
         }
     }
 
+    if (waitStreamEnd) {
+        // FIXME:  Instead of blocking in proxy->waitStreamEndDone(), Callback thread
+        // should wait on proxy futex and handle CBLK_STREAM_END_DONE within this function
+        // (and make sure we don't callback for more data while we're stopping).
+        // This helps with position, marker notifications, and track invalidation.
+        struct timespec timeout;
+        timeout.tv_sec = WAIT_STREAM_END_TIMEOUT_SEC;
+        timeout.tv_nsec = 0;
+
+        status_t status = proxy->waitStreamEndDone(&timeout);
+        switch (status) {
+        case NO_ERROR:
+        case DEAD_OBJECT:
+        case TIMED_OUT:
+            if (isOffloaded_l()) {
+                if (mCblk->mFlags & (CBLK_INVALID)){
+                    // will trigger EVENT_STREAM_END in next iteration
+                    return 0;
+                }
+            }
+            mCbf(EVENT_STREAM_END, mUserData, NULL);
+            {
+                AutoMutex lock(mLock);
+                // The previously assigned value of waitStreamEnd is no longer valid,
+                // since the mutex has been unlocked and either the callback handler
+                // or another thread could have re-started the AudioTrack during that time.
+                waitStreamEnd = mState == STATE_STOPPING;
+                if (waitStreamEnd) {
+                    mState = STATE_STOPPED;
+                    mReleased = 0;
+                }
+            }
+            if (waitStreamEnd && status != DEAD_OBJECT) {
+               return NS_INACTIVE;
+            }
+            break;
+        }
+        return 0;
+    }
+
     // if inactive, then don't run me again until re-started
     if (!active) {
         return NS_INACTIVE;
@@ -2232,14 +2272,22 @@
         }
     }
 
-    // The presented frame count must always lag behind the consumed frame count.
-    // To avoid a race, read the presented frames first.  This ensures that presented <= consumed.
-    status_t status = mAudioTrack->getTimestamp(timestamp);
-    if (status != NO_ERROR) {
-        ALOGV_IF(status != WOULD_BLOCK, "getTimestamp error:%#x", status);
-        return status;
+    status_t status = UNKNOWN_ERROR;
+    //call Timestamp only if its NOT PCM offloaded and NOT Track Offloaded
+    if (!AVMediaUtils::get()->AudioTrackIsPcmOffloaded(mFormat) && !mTrackOffloaded) {
+        // The presented frame count must always lag behind the consumed frame count.
+        // To avoid a race, read the presented frames first.  This ensures that presented <= consumed.
+
+        status = mAudioTrack->getTimestamp(timestamp);
+        if (status != NO_ERROR) {
+            ALOGV_IF(status != WOULD_BLOCK, "getTimestamp error:%#x", status);
+            return status;
+        }
+
     }
-    if (isOffloadedOrDirect_l()) {
+
+    if (isOffloadedOrDirect_l() && !AVMediaUtils::get()->AudioTrackIsPcmOffloaded(mFormat)
+        && !mTrackOffloaded) {
         if (isOffloaded_l() && (mState == STATE_PAUSED || mState == STATE_PAUSED_STOPPING)) {
             // use cached paused position in case another offloaded track is running.
             timestamp.mPosition = mPausedPosition;
@@ -2297,6 +2345,11 @@
         }
     } else {
         // Update the mapping between local consumed (mPosition) and server consumed (mServer)
+
+        if (AVMediaUtils::get()->AudioTrackGetTimestamp(this, &timestamp) == NO_ERROR) {
+            return NO_ERROR;
+        }
+
         (void) updateAndGetPosition_l();
         // Server consumed (mServer) and presented both use the same server time base,
         // and server consumed is always >= presented.
diff --git a/media/libmedia/ICrypto.cpp b/media/libmedia/ICrypto.cpp
index a398ff7..24e027e 100644
--- a/media/libmedia/ICrypto.cpp
+++ b/media/libmedia/ICrypto.cpp
@@ -24,6 +24,7 @@
 #include <media/stagefright/MediaErrors.h>
 #include <media/stagefright/foundation/ADebug.h>
 #include <media/stagefright/foundation/AString.h>
+#include <media/AVMediaExtensions.h>
 
 namespace android {
 
@@ -136,6 +137,7 @@
 
         if (secure) {
             data.writeInt64(static_cast<uint64_t>(reinterpret_cast<uintptr_t>(dstPtr)));
+            AVMediaUtils::get()->writeCustomData(&data, dstPtr);
         }
 
         remote()->transact(DECRYPT, data, &reply);
@@ -235,6 +237,7 @@
 
             if (opaqueSize > 0) {
                 opaqueData = malloc(opaqueSize);
+                CHECK(opaqueData != NULL);
                 data.read(opaqueData, opaqueSize);
             }
 
@@ -296,8 +299,10 @@
             void *secureBufferId, *dstPtr;
             if (secure) {
                 secureBufferId = reinterpret_cast<void *>(static_cast<uintptr_t>(data.readInt64()));
+                AVMediaUtils::get()->readCustomData(&data, &secureBufferId);
             } else {
                 dstPtr = calloc(1, totalSize);
+                CHECK(dstPtr != NULL);
             }
 
             AString errorDetailMsg;
@@ -348,6 +353,8 @@
                 }
                 free(dstPtr);
                 dstPtr = NULL;
+            } else {
+                AVMediaUtils::get()->closeFileDescriptor(secureBufferId);
             }
 
             delete[] subSamples;
diff --git a/media/libmedia/IEffectClient.cpp b/media/libmedia/IEffectClient.cpp
index 1322e72..531f767 100644
--- a/media/libmedia/IEffectClient.cpp
+++ b/media/libmedia/IEffectClient.cpp
@@ -22,6 +22,8 @@
 #include <sys/types.h>
 #include <media/IEffectClient.h>
 
+#include <media/stagefright/foundation/ADebug.h>
+
 namespace android {
 
 enum {
@@ -117,12 +119,14 @@
             char *cmd = NULL;
             if (cmdSize) {
                 cmd = (char *)malloc(cmdSize);
+                CHECK(cmd != NULL);
                 data.read(cmd, cmdSize);
             }
             uint32_t replySize = data.readInt32();
             char *resp = NULL;
             if (replySize) {
                 resp = (char *)malloc(replySize);
+                CHECK(resp != NULL);
                 data.read(resp, replySize);
             }
             commandExecuted(cmdCode, cmdSize, cmd, replySize, resp);
diff --git a/media/libmedia/IMediaHTTPConnection.cpp b/media/libmedia/IMediaHTTPConnection.cpp
index 0dda0be..23fa084 100644
--- a/media/libmedia/IMediaHTTPConnection.cpp
+++ b/media/libmedia/IMediaHTTPConnection.cpp
@@ -124,6 +124,14 @@
             ALOGE("got %zu, but memory has %zu", len, mMemory->size());
             return ERROR_OUT_OF_RANGE;
         }
+        if(buffer == NULL) {
+           ALOGE("readAt got a NULL buffer");
+           return UNKNOWN_ERROR;
+        }
+        if (mMemory->pointer() == NULL) {
+           ALOGE("readAt got a NULL mMemory->pointer()");
+           return UNKNOWN_ERROR;
+        }
 
         memcpy(buffer, mMemory->pointer(), len);
 
diff --git a/media/libmedia/IOMX.cpp b/media/libmedia/IOMX.cpp
index 5423c2a..5356494 100644
--- a/media/libmedia/IOMX.cpp
+++ b/media/libmedia/IOMX.cpp
@@ -22,6 +22,7 @@
 #include <binder/Parcel.h>
 #include <media/IOMX.h>
 #include <media/stagefright/foundation/ADebug.h>
+#include <media/AVMediaExtensions.h>
 
 namespace android {
 
@@ -472,6 +473,7 @@
 
         *buffer = (buffer_id)reply.readInt32();
         *buffer_data = (void *)reply.readInt64();
+        AVMediaUtils::get()->readCustomData(&reply, buffer_data);
 
         return err;
     }
@@ -980,6 +982,7 @@
             if (err == OK) {
                 reply->writeInt32((int32_t)buffer);
                 reply->writeInt64((uintptr_t)buffer_data);
+                AVMediaUtils::get()->writeCustomData(reply, buffer_data);
             }
 
             return NO_ERROR;
diff --git a/media/libmedia/MediaProfiles.cpp b/media/libmedia/MediaProfiles.cpp
index c5790fb..bb13aed 100644
--- a/media/libmedia/MediaProfiles.cpp
+++ b/media/libmedia/MediaProfiles.cpp
@@ -37,7 +37,8 @@
 const MediaProfiles::NameToTagMap MediaProfiles::sVideoEncoderNameMap[] = {
     {"h263", VIDEO_ENCODER_H263},
     {"h264", VIDEO_ENCODER_H264},
-    {"m4v",  VIDEO_ENCODER_MPEG_4_SP}
+    {"m4v",  VIDEO_ENCODER_MPEG_4_SP},
+    {"h265", VIDEO_ENCODER_H265}
 };
 
 const MediaProfiles::NameToTagMap MediaProfiles::sAudioEncoderNameMap[] = {
@@ -45,7 +46,8 @@
     {"amrwb",  AUDIO_ENCODER_AMR_WB},
     {"aac",    AUDIO_ENCODER_AAC},
     {"heaac",  AUDIO_ENCODER_HE_AAC},
-    {"aaceld", AUDIO_ENCODER_AAC_ELD}
+    {"aaceld", AUDIO_ENCODER_AAC_ELD},
+    {"lpcm",  AUDIO_ENCODER_LPCM},
 };
 
 const MediaProfiles::NameToTagMap MediaProfiles::sFileFormatMap[] = {
@@ -88,6 +90,19 @@
     {"highspeed720p", CAMCORDER_QUALITY_HIGH_SPEED_720P},
     {"highspeed1080p", CAMCORDER_QUALITY_HIGH_SPEED_1080P},
     {"highspeed2160p", CAMCORDER_QUALITY_HIGH_SPEED_2160P},
+
+    // Vendor-specific profiles
+    {"vga", CAMCORDER_QUALITY_VGA},
+    {"4kdci", CAMCORDER_QUALITY_4KDCI},
+    {"timelapsevga", CAMCORDER_QUALITY_TIME_LAPSE_VGA},
+    {"timelapse4kdci", CAMCORDER_QUALITY_TIME_LAPSE_4KDCI},
+    {"highspeedcif", CAMCORDER_QUALITY_HIGH_SPEED_CIF},
+    {"highspeedvga", CAMCORDER_QUALITY_HIGH_SPEED_VGA},
+    {"highspeed4kdci", CAMCORDER_QUALITY_HIGH_SPEED_4KDCI},
+    {"qhd", CAMCORDER_QUALITY_QHD},
+    {"2k", CAMCORDER_QUALITY_2k},
+    {"timelapseqhd", CAMCORDER_QUALITY_TIME_LAPSE_QHD},
+    {"timelapse2k", CAMCORDER_QUALITY_TIME_LAPSE_2k},
 };
 
 #if LOG_NDEBUG
@@ -423,8 +438,10 @@
 }
 
 static bool isCamcorderProfile(camcorder_quality quality) {
-    return quality >= CAMCORDER_QUALITY_LIST_START &&
-           quality <= CAMCORDER_QUALITY_LIST_END;
+    return (quality >= CAMCORDER_QUALITY_LIST_START &&
+           quality <= CAMCORDER_QUALITY_LIST_END) ||
+           (quality >= CAMCORDER_QUALITY_VENDOR_START &&
+           quality <= CAMCORDER_QUALITY_VENDOR_END);
 }
 
 static bool isTimelapseProfile(camcorder_quality quality) {
@@ -778,6 +795,7 @@
 MediaProfiles::createDefaultAudioEncoders(MediaProfiles *profiles)
 {
     profiles->mAudioEncoders.add(createDefaultAmrNBEncoderCap());
+    profiles->mAudioEncoders.add(createDefaultLpcmEncoderCap());
 }
 
 /*static*/ void
@@ -812,6 +830,14 @@
         AUDIO_ENCODER_AMR_NB, 5525, 12200, 8000, 8000, 1, 1);
 }
 
+
+/*static*/ MediaProfiles::AudioEncoderCap*
+MediaProfiles::createDefaultLpcmEncoderCap()
+{
+    return new MediaProfiles::AudioEncoderCap(
+        AUDIO_ENCODER_LPCM, 768000, 4608000, 8000, 48000, 1, 6);
+}
+
 /*static*/ void
 MediaProfiles::createDefaultImageEncodingQualityLevels(MediaProfiles *profiles)
 {
diff --git a/media/libmedia/MediaScanner.cpp b/media/libmedia/MediaScanner.cpp
index dcbb769..dac0a9e 100644
--- a/media/libmedia/MediaScanner.cpp
+++ b/media/libmedia/MediaScanner.cpp
@@ -24,6 +24,8 @@
 #include <sys/stat.h>
 #include <dirent.h>
 
+#include <media/stagefright/foundation/ADebug.h>
+
 namespace android {
 
 MediaScanner::MediaScanner()
@@ -240,6 +242,7 @@
 MediaAlbumArt *MediaAlbumArt::clone() {
     size_t byte_size = this->size() + sizeof(MediaAlbumArt);
     MediaAlbumArt *result = reinterpret_cast<MediaAlbumArt *>(malloc(byte_size));
+    CHECK(result != NULL);
     result->mSize = this->size();
     memcpy(&result->mData[0], &this->mData[0], this->size());
     return result;
@@ -253,6 +256,7 @@
 MediaAlbumArt *MediaAlbumArt::fromData(int32_t dataSize, const void* data) {
     size_t byte_size = sizeof(MediaAlbumArt) + dataSize;
     MediaAlbumArt *result = reinterpret_cast<MediaAlbumArt *>(malloc(byte_size));
+    CHECK(result != NULL);
     init(result, dataSize, data);
     return result;
 }
diff --git a/media/libmedia/ToneGenerator.cpp b/media/libmedia/ToneGenerator.cpp
index 6da5348..53b229e 100644
--- a/media/libmedia/ToneGenerator.cpp
+++ b/media/libmedia/ToneGenerator.cpp
@@ -804,6 +804,12 @@
         ALOGE("Unable to marshal AudioFlinger");
         return;
     }
+
+    if (mSamplingRate > 48000) {
+        ALOGW("mSamplingRate %d . limit to 48k", mSamplingRate);
+        mSamplingRate = 48000;
+    }
+
     mThreadCanCallJava = threadCanCallJava;
     mStreamType = streamType;
     mVolume = volume;
@@ -1046,7 +1052,7 @@
     ALOGV("Create Track: %p", mpAudioTrack.get());
 
     mpAudioTrack->set(mStreamType,
-                      0,    // sampleRate
+                      mSamplingRate,
                       AUDIO_FORMAT_PCM_16_BIT,
                       AUDIO_CHANNEL_OUT_MONO,
                       0,    // frameCount
diff --git a/media/libmediaplayerservice/Android.mk b/media/libmediaplayerservice/Android.mk
index 4d1b587..c4c5b47 100644
--- a/media/libmediaplayerservice/Android.mk
+++ b/media/libmediaplayerservice/Android.mk
@@ -18,7 +18,6 @@
     MetadataRetrieverClient.cpp \
     RemoteDisplay.cpp           \
     SharedLibrary.cpp           \
-    StagefrightPlayer.cpp       \
     StagefrightRecorder.cpp     \
     TestPlayerStub.cpp          \
 
@@ -46,6 +45,9 @@
     libstagefright_nuplayer     \
     libstagefright_rtsp         \
 
+LOCAL_WHOLE_STATIC_LIBRARIES := \
+    libavmediaserviceextensions \
+
 LOCAL_C_INCLUDES :=                                                 \
     $(TOP)/frameworks/av/media/libstagefright/include               \
     $(TOP)/frameworks/av/media/libstagefright/rtsp                  \
@@ -53,13 +55,14 @@
     $(TOP)/frameworks/av/media/libstagefright/webm                  \
     $(TOP)/frameworks/native/include/media/openmax                  \
     $(TOP)/external/tremolo/Tremolo                                 \
+    $(TOP)/frameworks/av/media/libavextensions                      \
 
 LOCAL_CFLAGS += -Werror -Wno-error=deprecated-declarations -Wall
 LOCAL_CLANG := true
 
 LOCAL_MODULE:= libmediaplayerservice
 
-LOCAL_32_BIT_ONLY := true
+#LOCAL_32_BIT_ONLY := true
 
 include $(BUILD_SHARED_LIBRARY)
 
diff --git a/media/libmediaplayerservice/MediaPlayerFactory.cpp b/media/libmediaplayerservice/MediaPlayerFactory.cpp
index d5d12f7..f0afc5a 100644
--- a/media/libmediaplayerservice/MediaPlayerFactory.cpp
+++ b/media/libmediaplayerservice/MediaPlayerFactory.cpp
@@ -31,8 +31,8 @@
 #include "MediaPlayerFactory.h"
 
 #include "TestPlayerStub.h"
-#include "StagefrightPlayer.h"
 #include "nuplayer/NuPlayerDriver.h"
+#include <mediaplayerservice/AVMediaServiceExtensions.h>
 
 namespace android {
 
@@ -64,12 +64,6 @@
 }
 
 static player_type getDefaultPlayerType() {
-    char value[PROPERTY_VALUE_MAX];
-    if (property_get("media.stagefright.use-awesome", value, NULL)
-            && (!strcmp("1", value) || !strcasecmp("true", value))) {
-        return STAGEFRIGHT_PLAYER;
-    }
-
     return NU_PLAYER;
 }
 
@@ -87,7 +81,7 @@
 #define GET_PLAYER_TYPE_IMPL(a...)                      \
     Mutex::Autolock lock_(&sLock);                      \
                                                         \
-    player_type ret = STAGEFRIGHT_PLAYER;               \
+    player_type ret = NU_PLAYER;                        \
     float bestScore = 0.0;                              \
                                                         \
     for (size_t i = 0; i < sFactoryMap.size(); ++i) {   \
@@ -176,63 +170,6 @@
  *                                                                           *
  *****************************************************************************/
 
-class StagefrightPlayerFactory :
-    public MediaPlayerFactory::IFactory {
-  public:
-    virtual float scoreFactory(const sp<IMediaPlayer>& /*client*/,
-                               int fd,
-                               int64_t offset,
-                               int64_t length,
-                               float /*curScore*/) {
-        if (legacyDrm()) {
-            sp<DataSource> source = new FileSource(dup(fd), offset, length);
-            String8 mimeType;
-            float confidence;
-            if (SniffWVM(source, &mimeType, &confidence, NULL /* format */)) {
-                return 1.0;
-            }
-        }
-
-        if (getDefaultPlayerType() == STAGEFRIGHT_PLAYER) {
-            char buf[20];
-            lseek(fd, offset, SEEK_SET);
-            read(fd, buf, sizeof(buf));
-            lseek(fd, offset, SEEK_SET);
-
-            uint32_t ident = *((uint32_t*)buf);
-
-            // Ogg vorbis?
-            if (ident == 0x5367674f) // 'OggS'
-                return 1.0;
-        }
-
-        return 0.0;
-    }
-
-    virtual float scoreFactory(const sp<IMediaPlayer>& /*client*/,
-                               const char* url,
-                               float /*curScore*/) {
-        if (legacyDrm() && !strncasecmp("widevine://", url, 11)) {
-            return 1.0;
-        }
-        return 0.0;
-    }
-
-    virtual sp<MediaPlayerBase> createPlayer(pid_t /* pid */) {
-        ALOGV(" create StagefrightPlayer");
-        return new StagefrightPlayer();
-    }
-  private:
-    bool legacyDrm() {
-        char value[PROPERTY_VALUE_MAX];
-        if (property_get("persist.sys.media.legacy-drm", value, NULL)
-                && (!strcmp("1", value) || !strcasecmp("true", value))) {
-            return true;
-        }
-        return false;
-    }
-};
-
 class NuPlayerFactory : public MediaPlayerFactory::IFactory {
   public:
     virtual float scoreFactory(const sp<IMediaPlayer>& /*client*/,
@@ -305,14 +242,20 @@
 };
 
 void MediaPlayerFactory::registerBuiltinFactories() {
+
+    MediaPlayerFactory::IFactory* pCustomFactory = NULL;
     Mutex::Autolock lock_(&sLock);
 
     if (sInitComplete)
         return;
 
-    registerFactory_l(new StagefrightPlayerFactory(), STAGEFRIGHT_PLAYER);
     registerFactory_l(new NuPlayerFactory(), NU_PLAYER);
     registerFactory_l(new TestPlayerFactory(), TEST_PLAYER);
+    AVMediaServiceUtils::get()->getDashPlayerFactory(pCustomFactory, DASH_PLAYER);
+    if(pCustomFactory != NULL) {
+        ALOGV("Registering DASH_PLAYER");
+        registerFactory_l(pCustomFactory, DASH_PLAYER);
+    }
 
     sInitComplete = true;
 }
diff --git a/media/libmediaplayerservice/MediaPlayerService.cpp b/media/libmediaplayerservice/MediaPlayerService.cpp
index bcfd83a..820b3c3 100644
--- a/media/libmediaplayerservice/MediaPlayerService.cpp
+++ b/media/libmediaplayerservice/MediaPlayerService.cpp
@@ -13,6 +13,25 @@
 ** 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.
+**
+** This file was modified by Dolby Laboratories, Inc. The portions of the
+** code that are surrounded by "DOLBY..." are copyrighted and
+** licensed separately, as follows:
+**
+**  (C) 2011-2015 Dolby Laboratories, Inc.
+**
+** 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.
+**
 */
 
 // Proxy for media player implementations
@@ -21,6 +40,7 @@
 #define LOG_TAG "MediaPlayerService"
 #include <utils/Log.h>
 
+#include <inttypes.h>
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <sys/time.h>
@@ -73,7 +93,6 @@
 #include "MediaPlayerFactory.h"
 
 #include "TestPlayerStub.h"
-#include "StagefrightPlayer.h"
 #include "nuplayer/NuPlayerDriver.h"
 
 #include <OMX.h>
@@ -83,6 +102,9 @@
 #include "HDCP.h"
 #include "HTTPBase.h"
 #include "RemoteDisplay.h"
+#ifdef DOLBY_ENABLE
+#include "DolbyMediaPlayerServiceExtImpl.h"
+#endif // DOLBY_END
 
 namespace {
 using android::media::Metadata;
@@ -148,7 +170,7 @@
 
     if (p.dataAvail() < size)
     {
-        ALOGE("Filter too short expected %d but got %d", size, p.dataAvail());
+        ALOGE("Filter too short expected %zu but got %zu", size, p.dataAvail());
         *status = NOT_ENOUGH_DATA;
         return false;
     }
@@ -733,7 +755,7 @@
 
 status_t MediaPlayerService::Client::setDataSource(int fd, int64_t offset, int64_t length)
 {
-    ALOGV("setDataSource fd=%d, offset=%lld, length=%lld", fd, offset, length);
+    ALOGV("setDataSource fd=%d, offset=%" PRId64 ", length=%" PRId64 "", fd, offset, length);
     struct stat sb;
     int ret = fstat(fd, &sb);
     if (ret != 0) {
@@ -741,11 +763,11 @@
         return UNKNOWN_ERROR;
     }
 
-    ALOGV("st_dev  = %llu", static_cast<uint64_t>(sb.st_dev));
+    ALOGV("st_dev  = %" PRIu64 "", static_cast<uint64_t>(sb.st_dev));
     ALOGV("st_mode = %u", sb.st_mode);
     ALOGV("st_uid  = %lu", static_cast<unsigned long>(sb.st_uid));
     ALOGV("st_gid  = %lu", static_cast<unsigned long>(sb.st_gid));
-    ALOGV("st_size = %llu", sb.st_size);
+    ALOGV("st_size = %" PRId64 "", sb.st_size);
 
     if (offset >= sb.st_size) {
         ALOGE("offset error");
@@ -754,7 +776,7 @@
     }
     if (offset + length > sb.st_size) {
         length = sb.st_size - offset;
-        ALOGV("calculated length = %lld", length);
+        ALOGV("calculated length = %" PRId64 "", length);
     }
 
     player_type playerType = MediaPlayerFactory::getPlayerType(this,
@@ -1249,8 +1271,17 @@
         if (msg == MEDIA_PLAYBACK_COMPLETE && client->mNextClient != NULL) {
             if (client->mAudioOutput != NULL)
                 client->mAudioOutput->switchToNextOutput();
-            client->mNextClient->start();
-            client->mNextClient->mClient->notify(MEDIA_INFO, MEDIA_INFO_STARTED_AS_NEXT, 0, obj);
+            ALOGD("gapless:current track played back");
+            ALOGD("gapless:try to do a gapless switch to next track");
+            status_t ret;
+            ret = client->mNextClient->start();
+            if (ret == NO_ERROR) {
+                client->mNextClient->mClient->notify(MEDIA_INFO,
+                        MEDIA_INFO_STARTED_AS_NEXT, 0, obj);
+            } else {
+                client->mClient->notify(MEDIA_ERROR, MEDIA_ERROR_UNKNOWN , 0, obj);
+                ALOGW("gapless:start playback for next track failed");
+            }
         }
     }
 
@@ -1366,6 +1397,10 @@
     }
 
     setMinBufferCount();
+    mBitWidth = 16;
+#ifdef DOLBY_ENABLE
+    mProcessedAudio = false;
+#endif // DOLBY_END
 }
 
 MediaPlayerService::AudioOutput::~AudioOutput()
@@ -1465,6 +1500,9 @@
 status_t MediaPlayerService::AudioOutput::setParameters(const String8& keyValuePairs)
 {
     Mutex::Autolock lock(mLock);
+#ifdef DOLBY_ENABLE
+    setDolbyParameters(keyValuePairs);
+#endif // DOLBY_END
     if (mTrack == 0) return NO_INIT;
     return mTrack->setParameters(keyValuePairs);
 }
@@ -1622,6 +1660,15 @@
         } else if (mRecycledTrack->format() != format) {
             reuse = false;
         }
+
+        if (bothOffloaded) {
+            if (mBitWidth != offloadInfo->bit_width) {
+                ALOGV("output bit width differs %d v/s %d",
+                      mBitWidth, offloadInfo->bit_width);
+                reuse = false;
+            }
+        }
+
     } else {
         ALOGV("no track available to recycle");
     }
@@ -1702,7 +1749,7 @@
 
         if (!bothOffloaded) {
             if (mRecycledTrack->frameCount() != t->frameCount()) {
-                ALOGV("framecount differs: %u/%u frames",
+                ALOGV("framecount differs: %zu/%zu frames",
                       mRecycledTrack->frameCount(), t->frameCount());
                 reuse = false;
             }
@@ -1717,6 +1764,9 @@
                 mCallbackData->setOutput(this);
             }
             delete newcbd;
+#ifdef DOLBY_ENABLE
+            updateTrackOnAudioProcessed(mTrack, reuse);
+#endif // DOLBY_END
             return OK;
         }
     }
@@ -1737,6 +1787,13 @@
     mFlags = flags;
     mMsecsPerFrame = 1E3f / (mPlaybackRate.mSpeed * sampleRate);
     mFrameSize = t->frameSize();
+
+    if (offloadInfo) {
+        mBitWidth = offloadInfo->bit_width;
+    } else {
+        mBitWidth = 16;
+    }
+
     uint32_t pos;
     if (t->getPosition(&pos) == OK) {
         mBytesWritten = uint64_t(pos) * mFrameSize;
@@ -1753,6 +1810,9 @@
             res = t->attachAuxEffect(mAuxEffectId);
         }
     }
+#ifdef DOLBY_ENABLE
+    updateTrackOnAudioProcessed(t, false);
+#endif // DOLBY_END
     ALOGV("open() DONE status %d", res);
     return res;
 }
@@ -1837,6 +1897,7 @@
                 mNextOutput->mBytesWritten = mBytesWritten;
                 mNextOutput->mFlags = mFlags;
                 mNextOutput->mFrameSize = mFrameSize;
+                mNextOutput->mBitWidth = mBitWidth;
                 close_l();
                 mCallbackData = NULL;  // destruction handled by mNextOutput
             } else {
@@ -2101,6 +2162,7 @@
     if (mBuffer == NULL) {
         mBufferSize = sink->bufferSize();
         mBuffer = malloc(mBufferSize);
+        CHECK(mBuffer != NULL);
     }
 
     size_t actualSize =
diff --git a/media/libmediaplayerservice/MediaPlayerService.h b/media/libmediaplayerservice/MediaPlayerService.h
index 60d4617..e92c0d3 100644
--- a/media/libmediaplayerservice/MediaPlayerService.h
+++ b/media/libmediaplayerservice/MediaPlayerService.h
@@ -13,6 +13,25 @@
 ** 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.
+**
+** This file was modified by Dolby Laboratories, Inc. The portions of the
+** code that are surrounded by "DOLBY..." are copyrighted and
+** licensed separately, as follows:
+**
+**  (C) 2011-2015 Dolby Laboratories, Inc.
+**
+** 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_MEDIAPLAYERSERVICE_H
@@ -133,6 +152,11 @@
                 int event, void *me, void *info);
                void             deleteRecycledTrack_l();
                void             close_l();
+#ifdef DOLBY_ENABLE
+               void             setDolbyParameters(const String8& keyValuePairs);
+               void             updateTrackOnAudioProcessed(sp<AudioTrack> t, bool trackReused);
+               bool             mProcessedAudio;
+#endif // DOLBY_END
 
         sp<AudioTrack>          mTrack;
         sp<AudioTrack>          mRecycledTrack;
@@ -160,6 +184,7 @@
         // static variables below not protected by mutex
         static bool             mIsOnEmulator;
         static int              mMinBufferCount;  // 12 for emulator; otherwise 4
+        uint16_t                mBitWidth;
 
         // CallbackData is what is passed to the AudioTrack as the "user" data.
         // We need to be able to target this to a different Output on the fly,
diff --git a/media/libmediaplayerservice/MediaRecorderClient.cpp b/media/libmediaplayerservice/MediaRecorderClient.cpp
index f761dec..6f242e5 100644
--- a/media/libmediaplayerservice/MediaRecorderClient.cpp
+++ b/media/libmediaplayerservice/MediaRecorderClient.cpp
@@ -18,6 +18,7 @@
 #define LOG_TAG "MediaRecorderService"
 #include <utils/Log.h>
 
+#include <inttypes.h>
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <dirent.h>
@@ -39,6 +40,7 @@
 
 #include "StagefrightRecorder.h"
 #include <gui/IGraphicBufferProducer.h>
+#include "mediaplayerservice/AVMediaServiceExtensions.h"
 
 namespace android {
 
@@ -166,7 +168,7 @@
 
 status_t MediaRecorderClient::setOutputFile(int fd, int64_t offset, int64_t length)
 {
-    ALOGV("setOutputFile(%d, %lld, %lld)", fd, offset, length);
+    ALOGV("setOutputFile(%d, %" PRId64 ", %" PRId64 ")", fd, offset, length);
     Mutex::Autolock lock(mLock);
     if (mRecorder == NULL) {
         ALOGE("recorder is not initialized");
@@ -305,7 +307,7 @@
 {
     ALOGV("Client constructor");
     mPid = pid;
-    mRecorder = new StagefrightRecorder(opPackageName);
+    mRecorder = AVMediaServiceFactory::get()->createStagefrightRecorder(opPackageName);
     mMediaPlayerService = service;
 }
 
diff --git a/media/libmediaplayerservice/MetadataRetrieverClient.cpp b/media/libmediaplayerservice/MetadataRetrieverClient.cpp
index a5a1fa5..894a855 100644
--- a/media/libmediaplayerservice/MetadataRetrieverClient.cpp
+++ b/media/libmediaplayerservice/MetadataRetrieverClient.cpp
@@ -19,6 +19,7 @@
 #define LOG_TAG "MetadataRetrieverClient"
 #include <utils/Log.h>
 
+#include <inttypes.h>
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <dirent.h>
@@ -84,7 +85,6 @@
 {
     sp<MediaMetadataRetrieverBase> p;
     switch (playerType) {
-        case STAGEFRIGHT_PLAYER:
         case NU_PLAYER:
         {
             p = new StagefrightMetadataRetriever;
@@ -133,7 +133,7 @@
 
 status_t MetadataRetrieverClient::setDataSource(int fd, int64_t offset, int64_t length)
 {
-    ALOGV("setDataSource fd=%d, offset=%lld, length=%lld", fd, offset, length);
+    ALOGV("setDataSource fd=%d, offset=%" PRId64 ", length=%" PRId64 "", fd, offset, length);
     Mutex::Autolock lock(mLock);
     struct stat sb;
     int ret = fstat(fd, &sb);
@@ -141,20 +141,20 @@
         ALOGE("fstat(%d) failed: %d, %s", fd, ret, strerror(errno));
         return BAD_VALUE;
     }
-    ALOGV("st_dev  = %llu", static_cast<uint64_t>(sb.st_dev));
+    ALOGV("st_dev  = %" PRIu64 "", static_cast<uint64_t>(sb.st_dev));
     ALOGV("st_mode = %u", sb.st_mode);
     ALOGV("st_uid  = %lu", static_cast<unsigned long>(sb.st_uid));
     ALOGV("st_gid  = %lu", static_cast<unsigned long>(sb.st_gid));
-    ALOGV("st_size = %llu", sb.st_size);
+    ALOGV("st_size = %" PRIu64 "", sb.st_size);
 
     if (offset >= sb.st_size) {
-        ALOGE("offset (%lld) bigger than file size (%llu)", offset, sb.st_size);
+        ALOGE("offset (%" PRId64 ") bigger than file size (%" PRIu64 ")", offset, sb.st_size);
         ::close(fd);
         return BAD_VALUE;
     }
     if (offset + length > sb.st_size) {
         length = sb.st_size - offset;
-        ALOGV("calculated length = %lld", length);
+        ALOGV("calculated length = %" PRId64 "", length);
     }
 
     player_type playerType =
@@ -195,7 +195,7 @@
 
 sp<IMemory> MetadataRetrieverClient::getFrameAtTime(int64_t timeUs, int option)
 {
-    ALOGV("getFrameAtTime: time(%lld us) option(%d)", timeUs, option);
+    ALOGV("getFrameAtTime: time(%" PRId64 " us) option(%d)", timeUs, option);
     Mutex::Autolock lock(mLock);
     Mutex::Autolock glock(sLock);
     mThumbnail.clear();
@@ -217,7 +217,7 @@
     }
     mThumbnail = new MemoryBase(heap, 0, size);
     if (mThumbnail == NULL) {
-        ALOGE("not enough memory for VideoFrame size=%u", size);
+        ALOGE("not enough memory for VideoFrame size=%zu", size);
         delete frame;
         return NULL;
     }
@@ -258,7 +258,7 @@
     }
     mAlbumArt = new MemoryBase(heap, 0, size);
     if (mAlbumArt == NULL) {
-        ALOGE("not enough memory for MediaAlbumArt size=%u", size);
+        ALOGE("not enough memory for MediaAlbumArt size=%zu", size);
         delete albumArt;
         return NULL;
     }
diff --git a/media/libmediaplayerservice/StagefrightPlayer.cpp b/media/libmediaplayerservice/StagefrightPlayer.cpp
deleted file mode 100644
index 3fedd9b..0000000
--- a/media/libmediaplayerservice/StagefrightPlayer.cpp
+++ /dev/null
@@ -1,230 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-//#define LOG_NDEBUG 0
-#define LOG_TAG "StagefrightPlayer"
-#include <utils/Log.h>
-
-#include "StagefrightPlayer.h"
-
-#include "AwesomePlayer.h"
-
-#include <media/Metadata.h>
-#include <media/stagefright/MediaExtractor.h>
-
-namespace android {
-
-StagefrightPlayer::StagefrightPlayer()
-    : mPlayer(new AwesomePlayer) {
-    ALOGV("StagefrightPlayer");
-
-    mPlayer->setListener(this);
-}
-
-StagefrightPlayer::~StagefrightPlayer() {
-    ALOGV("~StagefrightPlayer");
-    reset();
-
-    delete mPlayer;
-    mPlayer = NULL;
-}
-
-status_t StagefrightPlayer::initCheck() {
-    ALOGV("initCheck");
-    return OK;
-}
-
-status_t StagefrightPlayer::setUID(uid_t uid) {
-    mPlayer->setUID(uid);
-
-    return OK;
-}
-
-status_t StagefrightPlayer::setDataSource(
-        const sp<IMediaHTTPService> &httpService,
-        const char *url,
-        const KeyedVector<String8, String8> *headers) {
-    return mPlayer->setDataSource(httpService, url, headers);
-}
-
-// Warning: The filedescriptor passed into this method will only be valid until
-// the method returns, if you want to keep it, dup it!
-status_t StagefrightPlayer::setDataSource(int fd, int64_t offset, int64_t length) {
-    ALOGV("setDataSource(%d, %lld, %lld)", fd, offset, length);
-    return mPlayer->setDataSource(dup(fd), offset, length);
-}
-
-status_t StagefrightPlayer::setDataSource(const sp<IStreamSource> &source) {
-    return mPlayer->setDataSource(source);
-}
-
-status_t StagefrightPlayer::setVideoSurfaceTexture(
-        const sp<IGraphicBufferProducer> &bufferProducer) {
-    ALOGV("setVideoSurfaceTexture");
-
-    return mPlayer->setSurfaceTexture(bufferProducer);
-}
-
-status_t StagefrightPlayer::prepare() {
-    return mPlayer->prepare();
-}
-
-status_t StagefrightPlayer::prepareAsync() {
-    return mPlayer->prepareAsync();
-}
-
-status_t StagefrightPlayer::start() {
-    ALOGV("start");
-
-    return mPlayer->play();
-}
-
-status_t StagefrightPlayer::stop() {
-    ALOGV("stop");
-
-    return pause();  // what's the difference?
-}
-
-status_t StagefrightPlayer::pause() {
-    ALOGV("pause");
-
-    return mPlayer->pause();
-}
-
-bool StagefrightPlayer::isPlaying() {
-    ALOGV("isPlaying");
-    return mPlayer->isPlaying();
-}
-
-status_t StagefrightPlayer::seekTo(int msec) {
-    ALOGV("seekTo %.2f secs", msec / 1E3);
-
-    status_t err = mPlayer->seekTo((int64_t)msec * 1000);
-
-    return err;
-}
-
-status_t StagefrightPlayer::getCurrentPosition(int *msec) {
-    ALOGV("getCurrentPosition");
-
-    int64_t positionUs;
-    status_t err = mPlayer->getPosition(&positionUs);
-
-    if (err != OK) {
-        return err;
-    }
-
-    *msec = (positionUs + 500) / 1000;
-
-    return OK;
-}
-
-status_t StagefrightPlayer::getDuration(int *msec) {
-    ALOGV("getDuration");
-
-    int64_t durationUs;
-    status_t err = mPlayer->getDuration(&durationUs);
-
-    if (err != OK) {
-        *msec = 0;
-        return OK;
-    }
-
-    *msec = (durationUs + 500) / 1000;
-
-    return OK;
-}
-
-status_t StagefrightPlayer::reset() {
-    ALOGV("reset");
-
-    mPlayer->reset();
-
-    return OK;
-}
-
-status_t StagefrightPlayer::setLooping(int loop) {
-    ALOGV("setLooping");
-
-    return mPlayer->setLooping(loop);
-}
-
-player_type StagefrightPlayer::playerType() {
-    ALOGV("playerType");
-    return STAGEFRIGHT_PLAYER;
-}
-
-status_t StagefrightPlayer::invoke(const Parcel &request, Parcel *reply) {
-    ALOGV("invoke()");
-    return mPlayer->invoke(request, reply);
-}
-
-void StagefrightPlayer::setAudioSink(const sp<AudioSink> &audioSink) {
-    MediaPlayerInterface::setAudioSink(audioSink);
-
-    mPlayer->setAudioSink(audioSink);
-}
-
-status_t StagefrightPlayer::setParameter(int key, const Parcel &request) {
-    ALOGV("setParameter(key=%d)", key);
-    return mPlayer->setParameter(key, request);
-}
-
-status_t StagefrightPlayer::getParameter(int key, Parcel *reply) {
-    ALOGV("getParameter");
-    return mPlayer->getParameter(key, reply);
-}
-
-status_t StagefrightPlayer::setPlaybackSettings(const AudioPlaybackRate &rate) {
-    return mPlayer->setPlaybackSettings(rate);
-}
-
-status_t StagefrightPlayer::getPlaybackSettings(AudioPlaybackRate *rate /* nonnull */) {
-    return mPlayer->getPlaybackSettings(rate);
-}
-
-status_t StagefrightPlayer::getMetadata(
-        const media::Metadata::Filter& /* ids */, Parcel *records) {
-    using media::Metadata;
-
-    uint32_t flags = mPlayer->flags();
-
-    Metadata metadata(records);
-
-    metadata.appendBool(
-            Metadata::kPauseAvailable,
-            flags & MediaExtractor::CAN_PAUSE);
-
-    metadata.appendBool(
-            Metadata::kSeekBackwardAvailable,
-            flags & MediaExtractor::CAN_SEEK_BACKWARD);
-
-    metadata.appendBool(
-            Metadata::kSeekForwardAvailable,
-            flags & MediaExtractor::CAN_SEEK_FORWARD);
-
-    metadata.appendBool(
-            Metadata::kSeekAvailable,
-            flags & MediaExtractor::CAN_SEEK);
-
-    return OK;
-}
-
-status_t StagefrightPlayer::dump(int fd, const Vector<String16> &args) const {
-    return mPlayer->dump(fd, args);
-}
-
-}  // namespace android
diff --git a/media/libmediaplayerservice/StagefrightPlayer.h b/media/libmediaplayerservice/StagefrightPlayer.h
deleted file mode 100644
index 96013df..0000000
--- a/media/libmediaplayerservice/StagefrightPlayer.h
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
-**
-** Copyright 2009, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
-
-#ifndef ANDROID_STAGEFRIGHTPLAYER_H
-#define ANDROID_STAGEFRIGHTPLAYER_H
-
-#include <media/MediaPlayerInterface.h>
-
-namespace android {
-
-struct AwesomePlayer;
-
-class StagefrightPlayer : public MediaPlayerInterface {
-public:
-    StagefrightPlayer();
-    virtual ~StagefrightPlayer();
-
-    virtual status_t initCheck();
-
-    virtual status_t setUID(uid_t uid);
-
-    virtual status_t setDataSource(
-            const sp<IMediaHTTPService> &httpService,
-            const char *url,
-            const KeyedVector<String8, String8> *headers);
-
-    virtual status_t setDataSource(int fd, int64_t offset, int64_t length);
-
-    virtual status_t setDataSource(const sp<IStreamSource> &source);
-
-    virtual status_t setVideoSurfaceTexture(
-            const sp<IGraphicBufferProducer> &bufferProducer);
-    virtual status_t prepare();
-    virtual status_t prepareAsync();
-    virtual status_t start();
-    virtual status_t stop();
-    virtual status_t pause();
-    virtual bool isPlaying();
-    virtual status_t seekTo(int msec);
-    virtual status_t getCurrentPosition(int *msec);
-    virtual status_t getDuration(int *msec);
-    virtual status_t reset();
-    virtual status_t setLooping(int loop);
-    virtual player_type playerType();
-    virtual status_t invoke(const Parcel &request, Parcel *reply);
-    virtual void setAudioSink(const sp<AudioSink> &audioSink);
-    virtual status_t setParameter(int key, const Parcel &request);
-    virtual status_t getParameter(int key, Parcel *reply);
-    virtual status_t setPlaybackSettings(const AudioPlaybackRate &rate);
-    virtual status_t getPlaybackSettings(AudioPlaybackRate *rate /* nonnull */);
-
-    virtual status_t getMetadata(
-            const media::Metadata::Filter& ids, Parcel *records);
-
-    virtual status_t dump(int fd, const Vector<String16> &args) const;
-
-private:
-    AwesomePlayer *mPlayer;
-
-    StagefrightPlayer(const StagefrightPlayer &);
-    StagefrightPlayer &operator=(const StagefrightPlayer &);
-};
-
-}  // namespace android
-
-#endif  // ANDROID_STAGEFRIGHTPLAYER_H
diff --git a/media/libmediaplayerservice/StagefrightRecorder.cpp b/media/libmediaplayerservice/StagefrightRecorder.cpp
index e521fae..80d5ac2 100644
--- a/media/libmediaplayerservice/StagefrightRecorder.cpp
+++ b/media/libmediaplayerservice/StagefrightRecorder.cpp
@@ -19,6 +19,7 @@
 #include <inttypes.h>
 #include <utils/Log.h>
 
+#include <inttypes.h>
 #include "WebmWriter.h"
 #include "StagefrightRecorder.h"
 
@@ -55,9 +56,12 @@
 #include <system/audio.h>
 
 #include "ARTPWriter.h"
+#include <stagefright/AVExtensions.h>
 
 namespace android {
 
+static const int64_t kMax32BitFileSize = 0x00ffffffffLL; // 4GB
+
 // To collect the encoder usage for the battery app
 static void addBatteryData(uint32_t params) {
     sp<IBinder> binder =
@@ -249,7 +253,7 @@
 }
 
 status_t StagefrightRecorder::setOutputFile(int fd, int64_t offset, int64_t length) {
-    ALOGV("setOutputFile: %d, %lld, %lld", fd, offset, length);
+    ALOGV("setOutputFile: %d, %" PRId64 ", %" PRId64 "", fd, offset, length);
     // These don't make any sense, do they?
     CHECK_EQ(offset, 0ll);
     CHECK_EQ(length, 0ll);
@@ -364,7 +368,7 @@
 
 status_t StagefrightRecorder::setParamAudioNumberOfChannels(int32_t channels) {
     ALOGV("setParamAudioNumberOfChannels: %d", channels);
-    if (channels <= 0 || channels >= 3) {
+    if (channels <= 0 || channels >= 7) {
         ALOGE("Invalid number of audio channels: %d", channels);
         return BAD_VALUE;
     }
@@ -416,42 +420,46 @@
 }
 
 status_t StagefrightRecorder::setParamMaxFileDurationUs(int64_t timeUs) {
-    ALOGV("setParamMaxFileDurationUs: %lld us", timeUs);
+    ALOGV("setParamMaxFileDurationUs: %" PRId64 " us", timeUs);
 
     // This is meant for backward compatibility for MediaRecorder.java
     if (timeUs <= 0) {
-        ALOGW("Max file duration is not positive: %lld us. Disabling duration limit.", timeUs);
+        ALOGW("Max file duration is not positive: %" PRId64 " us. Disabling duration limit.", timeUs);
         timeUs = 0; // Disable the duration limit for zero or negative values.
     } else if (timeUs <= 100000LL) {  // XXX: 100 milli-seconds
-        ALOGE("Max file duration is too short: %lld us", timeUs);
+        ALOGE("Max file duration is too short: %" PRId64 " us", timeUs);
         return BAD_VALUE;
     }
 
     if (timeUs <= 15 * 1000000LL) {
-        ALOGW("Target duration (%lld us) too short to be respected", timeUs);
+        ALOGW("Target duration (%" PRId64 " us) too short to be respected", timeUs);
     }
     mMaxFileDurationUs = timeUs;
     return OK;
 }
 
 status_t StagefrightRecorder::setParamMaxFileSizeBytes(int64_t bytes) {
-    ALOGV("setParamMaxFileSizeBytes: %lld bytes", bytes);
+    ALOGV("setParamMaxFileSizeBytes: %" PRId64 " bytes", bytes);
 
     // This is meant for backward compatibility for MediaRecorder.java
     if (bytes <= 0) {
-        ALOGW("Max file size is not positive: %lld bytes. "
+        ALOGW("Max file size is not positive: %" PRId64 " bytes. "
              "Disabling file size limit.", bytes);
         bytes = 0; // Disable the file size limit for zero or negative values.
     } else if (bytes <= 1024) {  // XXX: 1 kB
-        ALOGE("Max file size is too small: %lld bytes", bytes);
+        ALOGE("Max file size is too small: %" PRId64 " bytes", bytes);
         return BAD_VALUE;
     }
 
     if (bytes <= 100 * 1024) {
-        ALOGW("Target file size (%lld bytes) is too small to be respected", bytes);
+        ALOGW("Target file size (%" PRId64 " bytes) is too small to be respected", bytes);
     }
 
     mMaxFileSizeBytes = bytes;
+
+    // If requested size is >4GB, force 64-bit offsets
+    mUse64BitFileOffset |= (bytes >= kMax32BitFileSize);
+
     return OK;
 }
 
@@ -500,9 +508,9 @@
 }
 
 status_t StagefrightRecorder::setParamTrackTimeStatus(int64_t timeDurationUs) {
-    ALOGV("setParamTrackTimeStatus: %lld", timeDurationUs);
+    ALOGV("setParamTrackTimeStatus: %" PRId64 "", timeDurationUs);
     if (timeDurationUs < 20000) {  // Infeasible if shorter than 20 ms?
-        ALOGE("Tracking time duration too short: %lld us", timeDurationUs);
+        ALOGE("Tracking time duration too short: %" PRId64 " us", timeDurationUs);
         return BAD_VALUE;
     }
     mTrackEveryTimeDurationUs = timeDurationUs;
@@ -581,11 +589,11 @@
 status_t StagefrightRecorder::setParamCaptureFps(float fps) {
     ALOGV("setParamCaptureFps: %.2f", fps);
 
-    int64_t timeUs = (int64_t) (1000000.0 / fps + 0.5f);
+    int64_t timeUs = (int64_t) (1000000.0f / fps + 0.5f);
 
     // Not allowing time more than a day
     if (timeUs <= 0 || timeUs > 86400*1E6) {
-        ALOGE("Time between frame capture (%lld) is out of range [0, 1 Day]", timeUs);
+        ALOGE("Time between frame capture (%" PRId64 ") is out of range [0, 1 Day]", timeUs);
         return BAD_VALUE;
     }
 
@@ -814,8 +822,10 @@
             break;
 
         default:
-            ALOGE("Unsupported output file format: %d", mOutputFormat);
-            status = UNKNOWN_ERROR;
+            if (handleCustomRecording() != OK) {
+                ALOGE("Unsupported output file format: %d", mOutputFormat);
+                status = UNKNOWN_ERROR;
+            }
             break;
     }
 
@@ -879,8 +889,10 @@
 
         default:
         {
-            ALOGE("Unsupported output file format: %d", mOutputFormat);
-            status = UNKNOWN_ERROR;
+            if (handleCustomOutputFormats() != OK) {
+                ALOGE("Unsupported output file format: %d", mOutputFormat);
+                status = UNKNOWN_ERROR;
+            }
             break;
         }
     }
@@ -927,13 +939,12 @@
         }
     }
 
-    sp<AudioSource> audioSource =
-        new AudioSource(
-                mAudioSource,
-                mOpPackageName,
-                sourceSampleRate,
-                mAudioChannels,
-                mSampleRate);
+    sp<AudioSource> audioSource = AVFactory::get()->createAudioSource(
+        mAudioSource,
+        mOpPackageName,
+        sourceSampleRate,
+        mAudioChannels,
+        mSampleRate);
 
     status_t err = audioSource->initCheck();
 
@@ -965,8 +976,10 @@
             break;
 
         default:
-            ALOGE("Unknown audio encoder: %d", mAudioEncoder);
-            return NULL;
+            if (handleCustomAudioSource(format) != OK) {
+                ALOGE("Unknown audio encoder: %d", mAudioEncoder);
+                return NULL;
+            }
     }
 
     int32_t maxInputSize;
@@ -984,6 +997,13 @@
 
     sp<MediaSource> audioEncoder =
             MediaCodecSource::Create(mLooper, format, audioSource);
+    // If encoder could not be created (as in LPCM), then
+    // use the AudioSource directly as the MediaSource.
+    if (audioEncoder == NULL &&
+        mAudioEncoder == AUDIO_ENCODER_LPCM) {
+        ALOGD("No encoder is needed for linear PCM format");
+        audioEncoder = audioSource;
+    }
     mAudioSourceNode = audioSource;
 
     if (audioEncoder == NULL) {
@@ -1440,22 +1460,23 @@
     videoSize.height = mVideoHeight;
     if (mCaptureFpsEnable) {
         if (mTimeBetweenCaptureUs < 0) {
-            ALOGE("Invalid mTimeBetweenTimeLapseFrameCaptureUs value: %lld",
+            ALOGE("Invalid mTimeBetweenTimeLapseFrameCaptureUs value: %" PRId64 "",
                 mTimeBetweenCaptureUs);
             return BAD_VALUE;
         }
 
-        mCameraSourceTimeLapse = CameraSourceTimeLapse::CreateFromCamera(
+        mCameraSourceTimeLapse = AVFactory::get()->CreateCameraSourceTimeLapseFromCamera(
                 mCamera, mCameraProxy, mCameraId, mClientName, mClientUid,
                 videoSize, mFrameRate, mPreviewSurface,
                 mTimeBetweenCaptureUs);
         *cameraSource = mCameraSourceTimeLapse;
     } else {
-        *cameraSource = CameraSource::CreateFromCamera(
+        *cameraSource = AVFactory::get()->CreateCameraSourceFromCamera(
                 mCamera, mCameraProxy, mCameraId, mClientName, mClientUid,
                 videoSize, mFrameRate,
                 mPreviewSurface);
     }
+    AVUtils::get()->cacheCaptureBuffers(mCamera, mVideoEncoder);
     mCamera.clear();
     mCameraProxy.clear();
     if (*cameraSource == NULL) {
@@ -1487,6 +1508,11 @@
     return OK;
 }
 
+bool StagefrightRecorder::setCustomVideoEncoderMime(const video_encoder /*videoEncoder*/,
+        sp<AMessage> /*format*/) {
+    return false;
+}
+
 status_t StagefrightRecorder::setupVideoEncoder(
         sp<MediaSource> cameraSource,
         sp<MediaSource> *source) {
@@ -1512,6 +1538,9 @@
             break;
 
         default:
+            if (setCustomVideoEncoderMime(mVideoEncoder, format)) {
+                break;
+            }
             CHECK(!"Should not be here, unsupported video encoding.");
             break;
     }
@@ -1541,7 +1570,7 @@
         // set up time lapse/slow motion for surface source
         if (mCaptureFpsEnable) {
             if (mTimeBetweenCaptureUs <= 0) {
-                ALOGE("Invalid mTimeBetweenCaptureUs value: %lld",
+                ALOGE("Invalid mTimeBetweenCaptureUs value: %" PRId64 "",
                         mTimeBetweenCaptureUs);
                 return BAD_VALUE;
             }
@@ -1549,6 +1578,8 @@
         }
     }
 
+    setupCustomVideoEncoderParams(cameraSource, format);
+
     format->setInt32("bitrate", mVideoBitRate);
     format->setInt32("frame-rate", mFrameRate);
     format->setInt32("i-frame-interval", mIFramesIntervalSec);
@@ -1614,8 +1645,10 @@
             break;
 
         default:
-            ALOGE("Unsupported audio encoder: %d", mAudioEncoder);
-            return UNKNOWN_ERROR;
+            if (handleCustomAudioEncoder() != OK) {
+                ALOGE("Unsupported audio encoder: %d", mAudioEncoder);
+                return UNKNOWN_ERROR;
+            }
     }
 
     sp<MediaSource> audioEncoder = createAudioSource();
diff --git a/media/libmediaplayerservice/StagefrightRecorder.h b/media/libmediaplayerservice/StagefrightRecorder.h
index da00bc7..d2ff62d 100644
--- a/media/libmediaplayerservice/StagefrightRecorder.h
+++ b/media/libmediaplayerservice/StagefrightRecorder.h
@@ -39,6 +39,7 @@
 class IGraphicBufferProducer;
 class SurfaceMediaSource;
 struct ALooper;
+struct AMessage;
 
 struct StagefrightRecorder : public MediaRecorderBase {
     StagefrightRecorder(const String16 &opPackageName);
@@ -70,7 +71,7 @@
     // Querying a SurfaceMediaSourcer
     virtual sp<IGraphicBufferProducer> querySurfaceMediaSource() const;
 
-private:
+protected:
     sp<ICamera> mCamera;
     sp<ICameraRecordingProxy> mCameraProxy;
     sp<IGraphicBufferProducer> mPreviewSurface;
@@ -131,7 +132,7 @@
 
     static const int kMaxHighSpeedFps = 1000;
 
-    status_t prepareInternal();
+    virtual status_t prepareInternal();
     status_t setupMPEG4orWEBMRecording();
     void setupMPEG4orWEBMMetaData(sp<MetaData> *meta);
     status_t setupAMRRecording();
@@ -139,8 +140,8 @@
     status_t setupRawAudioRecording();
     status_t setupRTPRecording();
     status_t setupMPEG2TSRecording();
-    sp<MediaSource> createAudioSource();
-    status_t checkVideoEncoderCapabilities();
+    virtual sp<MediaSource> createAudioSource();
+    virtual status_t checkVideoEncoderCapabilities();
     status_t checkAudioEncoderCapabilities();
     // Generic MediaSource set-up. Returns the appropriate
     // source (CameraSource or SurfaceMediaSource)
@@ -148,10 +149,13 @@
     status_t setupMediaSource(sp<MediaSource> *mediaSource);
     status_t setupCameraSource(sp<CameraSource> *cameraSource);
     status_t setupAudioEncoder(const sp<MediaWriter>& writer);
-    status_t setupVideoEncoder(sp<MediaSource> cameraSource, sp<MediaSource> *source);
+    virtual status_t setupVideoEncoder(sp<MediaSource> cameraSource, sp<MediaSource> *source);
+    virtual void setupCustomVideoEncoderParams(sp<MediaSource> /*cameraSource*/,
+            sp<AMessage> &/*format*/) {}
+    virtual bool setCustomVideoEncoderMime(const video_encoder videoEncoder, sp<AMessage> format);
 
     // Encoding parameter handling utilities
-    status_t setParameter(const String8 &key, const String8 &value);
+    virtual status_t setParameter(const String8 &key, const String8 &value);
     status_t setParamAudioEncodingBitRate(int32_t bitRate);
     status_t setParamAudioNumberOfChannels(int32_t channles);
     status_t setParamAudioSamplingRate(int32_t sampleRate);
@@ -181,7 +185,11 @@
     void clipAudioSampleRate();
     void clipNumberOfAudioChannels();
     void setDefaultProfileIfNecessary();
-    void setDefaultVideoEncoderIfNecessary();
+    virtual void setDefaultVideoEncoderIfNecessary();
+    virtual status_t handleCustomOutputFormats() {return UNKNOWN_ERROR;}
+    virtual status_t handleCustomRecording() {return UNKNOWN_ERROR;}
+    virtual status_t handleCustomAudioSource(sp<AMessage> /*format*/) {return UNKNOWN_ERROR;}
+    virtual status_t handleCustomAudioEncoder() {return UNKNOWN_ERROR;}
 
 
     StagefrightRecorder(const StagefrightRecorder &);
diff --git a/media/libmediaplayerservice/nuplayer/Android.mk b/media/libmediaplayerservice/nuplayer/Android.mk
index cd20837..005cb4b 100644
--- a/media/libmediaplayerservice/nuplayer/Android.mk
+++ b/media/libmediaplayerservice/nuplayer/Android.mk
@@ -23,7 +23,8 @@
 	$(TOP)/frameworks/av/media/libstagefright/rtsp                \
 	$(TOP)/frameworks/av/media/libstagefright/timedtext           \
 	$(TOP)/frameworks/av/media/libmediaplayerservice              \
-	$(TOP)/frameworks/native/include/media/openmax
+	$(TOP)/frameworks/native/include/media/openmax                \
+        $(TOP)/frameworks/av/media/libavextensions                    \
 
 LOCAL_CFLAGS += -Werror -Wall
 
diff --git a/media/libmediaplayerservice/nuplayer/GenericSource.cpp b/media/libmediaplayerservice/nuplayer/GenericSource.cpp
index b3eb5fd..b29c5b8 100644
--- a/media/libmediaplayerservice/nuplayer/GenericSource.cpp
+++ b/media/libmediaplayerservice/nuplayer/GenericSource.cpp
@@ -37,6 +37,7 @@
 #include "../../libstagefright/include/NuCachedSource2.h"
 #include "../../libstagefright/include/WVMExtractor.h"
 #include "../../libstagefright/include/HTTPBase.h"
+#include "mediaplayerservice/AVNuExtensions.h"
 
 namespace android {
 
@@ -60,6 +61,7 @@
       mAudioIsVorbis(false),
       mIsWidevine(false),
       mIsSecure(false),
+      mUseSetBuffers(false),
       mIsStreaming(false),
       mUIDValid(uidValid),
       mUID(uid),
@@ -172,7 +174,8 @@
         extractor = mWVMExtractor;
     } else {
         extractor = MediaExtractor::Create(mDataSource,
-                mimeType.isEmpty() ? NULL : mimeType.string());
+                mimeType.isEmpty() ? NULL : mimeType.string(),
+                mIsStreaming ? 0 : AVNuUtils::get()->getFlags());
     }
 
     if (extractor == NULL) {
@@ -202,6 +205,11 @@
         }
     }
 
+    if (AVNuUtils::get()->canUseSetBuffers(mFileMeta)) {
+        mUseSetBuffers = true;
+        ALOGI("setBuffers mode enabled");
+    }
+
     int32_t totalBitrate = 0;
 
     size_t numtracks = extractor->countTracks();
@@ -318,7 +326,7 @@
 
 status_t NuPlayer::GenericSource::setBuffers(
         bool audio, Vector<MediaBuffer *> &buffers) {
-    if (mIsSecure && !audio) {
+    if ((mIsSecure || mUseSetBuffers) && !audio) {
         return mVideoTrack.mSource->setBuffers(buffers);
     }
     return INVALID_OPERATION;
@@ -374,7 +382,8 @@
 
             mDataSource = DataSource::CreateFromURI(
                    mHTTPService, uri, &mUriHeaders, &contentType,
-                   static_cast<HTTPBase *>(mHttpSource.get()));
+                   static_cast<HTTPBase *>(mHttpSource.get()),
+                   true /*use extended cache*/);
         } else {
             mIsWidevine = false;
 
@@ -427,7 +436,8 @@
             | FLAG_CAN_PAUSE
             | FLAG_CAN_SEEK_BACKWARD
             | FLAG_CAN_SEEK_FORWARD
-            | FLAG_CAN_SEEK);
+            | FLAG_CAN_SEEK
+            | (mUseSetBuffers ? FLAG_USE_SET_BUFFERS : 0));
 
     if (mIsSecure) {
         // secure decoders must be instantiated before starting widevine source
@@ -1022,7 +1032,8 @@
 
     // start pulling in more buffers if we only have one (or no) buffer left
     // so that decoder has less chance of being starved
-    if (track->mPackets->getAvailableBufferCount(&finalResult) < 2) {
+    if ((track->mPackets->getAvailableBufferCount(&finalResult) < 2)
+        && !mUseSetBuffers) {
         postReadBuffer(audio? MEDIA_TRACK_TYPE_AUDIO : MEDIA_TRACK_TYPE_VIDEO);
     }
 
@@ -1366,7 +1377,7 @@
     }
 
     sp<ABuffer> ab;
-    if (mIsSecure && !audio) {
+    if ((mIsSecure || mUseSetBuffers) && !audio) {
         // data is already provided in the buffer
         ab = new ABuffer(NULL, mb->range_length());
         mb->add_ref();
@@ -1481,7 +1492,9 @@
             break;
         case MEDIA_TRACK_TYPE_AUDIO:
             track = &mAudioTrack;
-            if (mIsWidevine) {
+            if (mHttpSource != NULL && getTrackCount() == 1) {
+                maxBuffers = 16;
+            } else if (mIsWidevine || (mHttpSource != NULL)) {
                 maxBuffers = 8;
             } else {
                 maxBuffers = 64;
@@ -1512,9 +1525,10 @@
     if (seekTimeUs >= 0) {
         options.setSeekTo(seekTimeUs, MediaSource::ReadOptions::SEEK_PREVIOUS_SYNC);
         seeking = true;
+        track->mPackets->clear();
     }
 
-    if (mIsWidevine) {
+    if (mIsWidevine || mUseSetBuffers) {
         options.setNonBlocking();
     }
 
@@ -1536,7 +1550,8 @@
             queueDiscontinuityIfNeeded(seeking, formatChange, trackType, track);
 
             sp<ABuffer> buffer = mediaBufferToABuffer(
-                    mbuf, trackType, seekTimeUs, actualTimeUs);
+                    mbuf, trackType, seekTimeUs,
+                    numBuffers == 0 ? actualTimeUs : NULL);
             track->mPackets->queueAccessUnit(buffer);
             formatChange = false;
             seeking = false;
diff --git a/media/libmediaplayerservice/nuplayer/GenericSource.h b/media/libmediaplayerservice/nuplayer/GenericSource.h
index ac980ef..bdcf706 100644
--- a/media/libmediaplayerservice/nuplayer/GenericSource.h
+++ b/media/libmediaplayerservice/nuplayer/GenericSource.h
@@ -42,7 +42,7 @@
 struct NuPlayer::GenericSource : public NuPlayer::Source {
     GenericSource(const sp<AMessage> &notify, bool uidValid, uid_t uid);
 
-    status_t setDataSource(
+    virtual status_t setDataSource(
             const sp<IMediaHTTPService> &httpService,
             const char *url,
             const KeyedVector<String8, String8> *headers);
@@ -84,7 +84,7 @@
 
     virtual sp<MetaData> getFormatMeta(bool audio);
 
-private:
+protected:
     enum {
         kWhatPrepareAsync,
         kWhatFetchSubtitleData,
@@ -126,6 +126,7 @@
     bool mAudioIsVorbis;
     bool mIsWidevine;
     bool mIsSecure;
+    bool mUseSetBuffers;
     bool mIsStreaming;
     bool mUIDValid;
     uid_t mUID;
@@ -164,7 +165,7 @@
     int64_t getLastReadPosition();
     void setDrmPlaybackStatusIfNeeded(int playbackStatus, int64_t position);
 
-    void notifyPreparedAndCleanup(status_t err);
+    virtual void notifyPreparedAndCleanup(status_t err);
     void onSecureDecodersInstantiated(status_t err);
     void finishPrepareAsync();
     status_t startSources();
@@ -181,7 +182,7 @@
     void onSeek(sp<AMessage> msg);
     status_t doSeek(int64_t seekTimeUs);
 
-    void onPrepareAsync();
+    virtual void onPrepareAsync();
 
     void fetchTextData(
             uint32_t what, media_track_type type,
diff --git a/media/libmediaplayerservice/nuplayer/HTTPLiveSource.cpp b/media/libmediaplayerservice/nuplayer/HTTPLiveSource.cpp
index 126625a..a57fdc1 100644
--- a/media/libmediaplayerservice/nuplayer/HTTPLiveSource.cpp
+++ b/media/libmediaplayerservice/nuplayer/HTTPLiveSource.cpp
@@ -30,6 +30,8 @@
 #include <media/stagefright/MediaErrors.h>
 #include <media/stagefright/MetaData.h>
 #include <media/stagefright/MediaDefs.h>
+#include <media/stagefright/Utils.h>
+
 
 namespace android {
 
@@ -118,6 +120,19 @@
     return format;
 }
 
+sp<MetaData> NuPlayer::HTTPLiveSource::getFormatMeta(bool audio) {
+    sp<AMessage> format = getFormat(audio);
+
+    if (format == NULL) {
+        return NULL;
+    }
+
+    sp<MetaData> meta = new MetaData;
+    convertMessageToMetaData(format, meta);
+    return meta;
+}
+
+
 status_t NuPlayer::HTTPLiveSource::feedMoreTSData() {
     return OK;
 }
@@ -197,7 +212,11 @@
 }
 
 status_t NuPlayer::HTTPLiveSource::seekTo(int64_t seekTimeUs) {
-    return mLiveSession->seekTo(seekTimeUs);
+    if (mLiveSession->isSeekable()) {
+        return mLiveSession->seekTo(seekTimeUs);
+    } else {
+        return INVALID_OPERATION;
+    }
 }
 
 void NuPlayer::HTTPLiveSource::pollForRawData(
diff --git a/media/libmediaplayerservice/nuplayer/HTTPLiveSource.h b/media/libmediaplayerservice/nuplayer/HTTPLiveSource.h
index 9e0ec2f..388156c 100644
--- a/media/libmediaplayerservice/nuplayer/HTTPLiveSource.h
+++ b/media/libmediaplayerservice/nuplayer/HTTPLiveSource.h
@@ -39,6 +39,7 @@
 
     virtual status_t dequeueAccessUnit(bool audio, sp<ABuffer> *accessUnit);
     virtual sp<AMessage> getFormat(bool audio);
+    virtual sp<MetaData> getFormatMeta(bool audio);
 
     virtual status_t feedMoreTSData();
     virtual status_t getDuration(int64_t *durationUs);
@@ -53,7 +54,6 @@
 
     virtual void onMessageReceived(const sp<AMessage> &msg);
 
-private:
     enum Flags {
         // Don't log any URLs.
         kFlagIncognito = 1,
@@ -78,7 +78,7 @@
     bool mHasMetadata;
     bool mMetadataSelected;
 
-    void onSessionNotify(const sp<AMessage> &msg);
+    virtual void onSessionNotify(const sp<AMessage> &msg);
     void pollForRawData(
             const sp<AMessage> &msg, int32_t currentGeneration,
             LiveSession::StreamType fetchType, int32_t pushWhat);
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
index c0146d5..ccbfc75 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
@@ -12,6 +12,25 @@
  * 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.
+ *
+ * This file was modified by Dolby Laboratories, Inc. The portions of the
+ * code that are surrounded by "DOLBY..." are copyrighted and
+ * licensed separately, as follows:
+ *
+ *  (C) 2014-2015 Dolby Laboratories, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
  */
 
 //#define LOG_NDEBUG 0
@@ -56,6 +75,10 @@
 
 #include "ESDS.h"
 #include <media/stagefright/Utils.h>
+#include "mediaplayerservice/AVNuExtensions.h"
+#ifdef DOLBY_ENABLE
+#include "DolbyNuPlayerExtImpl.h"
+#endif // DOLBY_END
 
 namespace android {
 
@@ -130,6 +153,23 @@
     DISALLOW_EVIL_CONSTRUCTORS(FlushDecoderAction);
 };
 
+struct NuPlayer::InstantiateDecoderAction : public Action {
+    InstantiateDecoderAction(bool audio, sp<DecoderBase> *decoder)
+        : mAudio(audio),
+          mdecoder(decoder) {
+    }
+
+    virtual void execute(NuPlayer *player) {
+        player->instantiateDecoder(mAudio, mdecoder);
+    }
+
+private:
+    bool mAudio;
+    sp<DecoderBase> *mdecoder;
+
+    DISALLOW_EVIL_CONSTRUCTORS(InstantiateDecoderAction);
+};
+
 struct NuPlayer::PostMessageAction : public Action {
     PostMessageAction(const sp<AMessage> &msg)
         : mMessage(msg) {
@@ -188,6 +228,7 @@
       mPlaybackSettings(AUDIO_PLAYBACK_RATE_DEFAULT),
       mVideoFpsHint(-1.f),
       mStarted(false),
+      mResetting(false),
       mSourceStarted(false),
       mPaused(false),
       mPausedByClient(false),
@@ -216,7 +257,7 @@
     msg->post();
 }
 
-static bool IsHTTPLiveURL(const char *url) {
+bool NuPlayer::IsHTTPLiveURL(const char *url) {
     if (!strncasecmp("http://", url, 7)
             || !strncasecmp("https://", url, 8)
             || !strncasecmp("file://", url, 7)) {
@@ -1019,6 +1060,10 @@
                         break;                    // Finish anyways.
                 }
                 notifyListener(MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, err);
+#ifdef DOLBY_ENABLE
+            } else if (what == kWhatDlbCpProc) {
+                onDolbyMessageReceived();
+#endif // DOLBY_END
             } else {
                 ALOGV("Unhandled decoder notification %d '%c%c%c%c'.",
                       what,
@@ -1092,40 +1137,7 @@
                 int32_t reason;
                 CHECK(msg->findInt32("reason", &reason));
                 ALOGV("Tear down audio with reason %d.", reason);
-                mAudioDecoder.clear();
-                ++mAudioDecoderGeneration;
-                bool needsToCreateAudioDecoder = true;
-                if (mFlushingAudio == FLUSHING_DECODER) {
-                    mFlushComplete[1 /* audio */][1 /* isDecoder */] = true;
-                    mFlushingAudio = FLUSHED;
-                    finishFlushIfPossible();
-                } else if (mFlushingAudio == FLUSHING_DECODER_SHUTDOWN
-                        || mFlushingAudio == SHUTTING_DOWN_DECODER) {
-                    mFlushComplete[1 /* audio */][1 /* isDecoder */] = true;
-                    mFlushingAudio = SHUT_DOWN;
-                    finishFlushIfPossible();
-                    needsToCreateAudioDecoder = false;
-                }
-                if (mRenderer == NULL) {
-                    break;
-                }
-                closeAudioSink();
-                mRenderer->flush(
-                        true /* audio */, false /* notifyComplete */);
-                if (mVideoDecoder != NULL) {
-                    mRenderer->flush(
-                            false /* audio */, false /* notifyComplete */);
-                }
-
-                int64_t positionUs;
-                if (!msg->findInt64("positionUs", &positionUs)) {
-                    positionUs = mPreviousSeekTimeUs;
-                }
-                performSeek(positionUs);
-
-                if (reason == Renderer::kDueToError && needsToCreateAudioDecoder) {
-                    instantiateDecoder(true /* audio */, &mAudioDecoder);
-                }
+                performTearDown(msg);
             }
             break;
         }
@@ -1139,12 +1151,17 @@
         {
             ALOGV("kWhatReset");
 
+            mResetting = true;
+
             mDeferredActions.push_back(
                     new FlushDecoderAction(
                         FLUSH_CMD_SHUTDOWN /* audio */,
                         FLUSH_CMD_SHUTDOWN /* video */));
 
             mDeferredActions.push_back(
+                    new SimpleAction(&NuPlayer::closeAudioSink));
+
+            mDeferredActions.push_back(
                     new SimpleAction(&NuPlayer::performReset));
 
             processDeferredActions();
@@ -1221,7 +1238,8 @@
 }
 
 void NuPlayer::onResume() {
-    if (!mPaused) {
+    if (!mPaused || mResetting) {
+        ALOGD_IF(mResetting, "resetting, onResume discarded");
         return;
     }
     mPaused = false;
@@ -1295,6 +1313,7 @@
     }
 
     sp<MetaData> audioMeta = mSource->getFormatMeta(true /* audio */);
+    AVNuUtils::get()->setSourcePCMFormat(audioMeta);
     audio_stream_type_t streamType = AUDIO_STREAM_MUSIC;
     if (mAudioSink != NULL) {
         streamType = mAudioSink->getAudioStreamType();
@@ -1304,6 +1323,10 @@
 
     mOffloadAudio =
         canOffloadStream(audioMeta, (videoFormat != NULL), mSource->isStreaming(), streamType);
+    if (!mOffloadAudio) {
+        mOffloadAudio = canOffloadDecodedPCMStream(audioMeta, (videoFormat != NULL), mSource->isStreaming(), streamType);
+    }
+
     if (mOffloadAudio) {
         flags |= Renderer::FLAG_OFFLOAD_AUDIO;
     }
@@ -1311,7 +1334,7 @@
     sp<AMessage> notify = new AMessage(kWhatRendererNotify, this);
     ++mRendererGeneration;
     notify->setInt32("generation", mRendererGeneration);
-    mRenderer = new Renderer(mAudioSink, notify, flags);
+    mRenderer = AVNuFactory::get()->createRenderer(mAudioSink, notify, flags);
     mRendererLooper = new ALooper;
     mRendererLooper->setName("NuPlayerRenderer");
     mRendererLooper->start(false, false, ANDROID_PRIORITY_AUDIO);
@@ -1440,7 +1463,7 @@
     // is possible; otherwise the decoders call the renderer openAudioSink directly.
 
     status_t err = mRenderer->openAudioSink(
-            format, true /* offloadOnly */, hasVideo, AUDIO_OUTPUT_FLAG_NONE, &mOffloadAudio);
+            format, true /* offloadOnly */, hasVideo, AUDIO_OUTPUT_FLAG_NONE, &mOffloadAudio, mSource->isStreaming());
     if (err != OK) {
         // Any failure we turn off mOffloadAudio.
         mOffloadAudio = false;
@@ -1470,8 +1493,11 @@
     sp<AMessage> videoFormat = mSource->getFormat(false /* audio */);
     audio_stream_type_t streamType = mAudioSink->getAudioStreamType();
     const bool hasVideo = (videoFormat != NULL);
-    const bool canOffload = canOffloadStream(
+    bool canOffload = canOffloadStream(
             audioMeta, hasVideo, mSource->isStreaming(), streamType);
+    if (!canOffload) {
+        canOffload = canOffloadDecodedPCMStream(audioMeta, (videoFormat != NULL), mSource->isStreaming(), streamType);
+    }
     if (canOffload) {
         if (!mOffloadAudio) {
             mRenderer->signalEnableOffloadAudio();
@@ -1483,6 +1509,7 @@
         if (mOffloadAudio) {
             mRenderer->signalDisableOffloadAudio();
             mOffloadAudio = false;
+            setDecodedPcmOffload(false);
         }
     }
 }
@@ -1493,7 +1520,10 @@
     if (*decoder != NULL || (audio && mFlushingAudio == SHUT_DOWN)) {
         return OK;
     }
-
+    if (mSource == NULL) {
+        ALOGD("%s Ignore instantiate decoder after clearing source", __func__);
+        return INVALID_OPERATION;
+    }
     sp<AMessage> format = mSource->getFormat(audio);
 
     if (format == NULL) {
@@ -1531,12 +1561,17 @@
         notify->setInt32("generation", mAudioDecoderGeneration);
 
         determineAudioModeChange();
-        if (mOffloadAudio) {
+
+        if (AVNuUtils::get()->isRAWFormat(format)) {
+            AVNuUtils::get()->setPCMFormat(format,
+                    AVNuUtils::get()->getKeyPCMFormat(mSource->getFormatMeta(true /* audio */)));
+        }
+        if (mOffloadAudio && !ifDecodedPCMOffload()) {
             const bool hasVideo = (mSource->getFormat(false /*audio */) != NULL);
             format->setInt32("has-video", hasVideo);
-            *decoder = new DecoderPassThrough(notify, mSource, mRenderer);
+            *decoder = AVNuFactory::get()->createPassThruDecoder(notify, mSource, mRenderer);
         } else {
-            *decoder = new Decoder(notify, mSource, mPID, mRenderer);
+            *decoder = AVNuFactory::get()->createDecoder(notify, mSource, mPID, mRenderer);
         }
     } else {
         sp<AMessage> notify = new AMessage(kWhatVideoNotify, this);
@@ -1561,7 +1596,8 @@
     (*decoder)->configure(format);
 
     // allocate buffers to decrypt widevine source buffers
-    if (!audio && (mSourceFlags & Source::FLAG_SECURE)) {
+    if (!audio && ((mSourceFlags & Source::FLAG_SECURE) ||
+                   (mSourceFlags & Source::FLAG_USE_SET_BUFFERS))) {
         Vector<sp<ABuffer> > inputBufs;
         CHECK_EQ((*decoder)->getInputBuffers(&inputBufs), (status_t)OK);
 
@@ -1924,6 +1960,7 @@
     }
 
     mStarted = false;
+    mResetting = false;
     mSourceStarted = false;
 }
 
@@ -2217,6 +2254,13 @@
             break;
         }
 
+        case Source::kWhatRTCPByeReceived:
+        {
+            ALOGV("notify the client that Bye message is received");
+            notifyListener(MEDIA_INFO, 2000, 0);
+            break;
+        }
+
         default:
             TRESPASS();
     }
@@ -2362,4 +2406,51 @@
     TRESPASS();
 }
 
+//
+// There is a flush from within the decoder's onFlush handling.
+// Without it, it is still possible that a buffer can be queueued
+// after NuPlayer issues a flush on the renderer's audio queue.
+//
+void NuPlayer::performTearDown(const sp<AMessage> &msg) {
+    int32_t reason;
+    CHECK(msg->findInt32("reason", &reason));
+
+    if (mAudioDecoder != NULL) {
+        switch (mFlushingAudio) {
+        case NONE:
+        case FLUSHING_DECODER:
+            mDeferredActions.push_back(
+                new FlushDecoderAction(FLUSH_CMD_SHUTDOWN /* audio */,
+                                       FLUSH_CMD_NONE /* video */));
+
+            if (reason == Renderer::kDueToError) {
+                mDeferredActions.push_back(
+                    new InstantiateDecoderAction(true /* audio */, &mAudioDecoder));
+            }
+
+            int64_t positionUs;
+            if (!msg->findInt64("positionUs", &positionUs)) {
+                positionUs = mPreviousSeekTimeUs;
+            }
+            mDeferredActions.push_back(new SeekAction(positionUs));
+            break;
+        default:
+            ALOGW("performTearDown while flushing audio in %d", mFlushingAudio);
+            break;
+        }
+    }
+
+    if (mRenderer != NULL) {
+        closeAudioSink();
+        // see comment at beginning of function
+        mRenderer->flush(
+            true /* audio */, false /* notifyComplete */);
+        if (mVideoDecoder != NULL) {
+            mRenderer->flush(
+                false /* audio */, false /* notifyComplete */);
+        }
+    }
+    processDeferredActions();
+}
+
 }  // namespace android
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayer.h b/media/libmediaplayerservice/nuplayer/NuPlayer.h
index c9f0bbd..9a7e81a 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayer.h
+++ b/media/libmediaplayerservice/nuplayer/NuPlayer.h
@@ -12,6 +12,25 @@
  * 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.
+ *
+ * This file was modified by Dolby Laboratories, Inc. The portions of the
+ * code that are surrounded by "DOLBY..." are copyrighted and
+ * licensed separately, as follows:
+ *
+ *  (C) 2015 Dolby Laboratories, Inc.
+ *
+ * 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 NU_PLAYER_H_
@@ -41,7 +60,7 @@
 
     void setDataSourceAsync(const sp<IStreamSource> &source);
 
-    void setDataSourceAsync(
+    virtual void setDataSourceAsync(
             const sp<IMediaHTTPService> &httpService,
             const char *url,
             const KeyedVector<String8, String8> *headers);
@@ -86,12 +105,15 @@
     virtual ~NuPlayer();
 
     virtual void onMessageReceived(const sp<AMessage> &msg);
-
+    virtual bool ifDecodedPCMOffload() {return false;}
+    virtual void setDecodedPcmOffload(bool /*decodePcmOffload*/) {}
+    virtual bool canOffloadDecodedPCMStream(const sp<MetaData> /*meta*/,
+            bool /*hasVideo*/, bool /*isStreaming*/, audio_stream_type_t /*streamType*/) {return false;}
+    static bool IsHTTPLiveURL(const char *url);
 public:
     struct NuPlayerStreamListener;
     struct Source;
 
-private:
     struct Decoder;
     struct DecoderBase;
     struct DecoderPassThrough;
@@ -106,9 +128,11 @@
     struct SetSurfaceAction;
     struct ResumeDecoderAction;
     struct FlushDecoderAction;
+    struct InstantiateDecoderAction;
     struct PostMessageAction;
     struct SimpleAction;
 
+protected:
     enum {
         kWhatSetDataSource              = '=DaS',
         kWhatPrepare                    = 'prep',
@@ -197,6 +221,7 @@
     AVSyncSettings mSyncSettings;
     float mVideoFpsHint;
     bool mStarted;
+    bool mResetting;
     bool mSourceStarted;
 
     // Actual pause state, either as requested by client or due to buffering.
@@ -221,11 +246,11 @@
         mFlushComplete[1][1] = false;
     }
 
-    void tryOpenAudioSinkForOffload(const sp<AMessage> &format, bool hasVideo);
+    virtual void tryOpenAudioSinkForOffload(const sp<AMessage> &format, bool hasVideo);
     void closeAudioSink();
     void determineAudioModeChange();
 
-    status_t instantiateDecoder(bool audio, sp<DecoderBase> *decoder);
+    virtual status_t instantiateDecoder(bool audio, sp<DecoderBase> *decoder);
 
     status_t onInstantiateSecureDecoders();
 
@@ -233,13 +258,13 @@
             const sp<AMessage> &inputFormat,
             const sp<AMessage> &outputFormat = NULL);
 
-    void notifyListener(int msg, int ext1, int ext2, const Parcel *in = NULL);
+    virtual void notifyListener(int msg, int ext1, int ext2, const Parcel *in = NULL);
 
     void handleFlushComplete(bool audio, bool isDecoder);
     void finishFlushIfPossible();
 
     void onStart(int64_t startPositionUs = -1);
-    void onResume();
+    virtual void onResume();
     void onPause();
 
     bool audioDecoderStillNeeded();
@@ -256,14 +281,14 @@
 
     void processDeferredActions();
 
-    void performSeek(int64_t seekTimeUs);
+    virtual void performSeek(int64_t seekTimeUs);
     void performDecoderFlush(FlushCommand audio, FlushCommand video);
     void performReset();
     void performScanSources();
     void performSetSurface(const sp<Surface> &wrapper);
     void performResumeDecoders(bool needNotify);
 
-    void onSourceNotify(const sp<AMessage> &msg);
+    virtual void onSourceNotify(const sp<AMessage> &msg);
     void onClosedCaptionNotify(const sp<AMessage> &msg);
 
     void queueDecoderShutdown(
@@ -275,6 +300,12 @@
 
     void writeTrackInfo(Parcel* reply, const sp<AMessage> format) const;
 
+    void performTearDown(const sp<AMessage> &msg);
+
+#ifdef DOLBY_ENABLE
+    void onDolbyMessageReceived();
+#endif // DOLBY_END
+
     DISALLOW_EVIL_CONSTRUCTORS(NuPlayer);
 };
 
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp
index 3646828..fbd0b12 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp
@@ -12,6 +12,25 @@
  * 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.
+ *
+ * This file was modified by Dolby Laboratories, Inc. The portions of the
+ * code that are surrounded by "DOLBY..." are copyrighted and
+ * licensed separately, as follows:
+ *
+ *  (C) 2014-2015 Dolby Laboratories, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
  */
 
 //#define LOG_NDEBUG 0
@@ -34,10 +53,15 @@
 #include <media/stagefright/MediaDefs.h>
 #include <media/stagefright/MediaErrors.h>
 
+#include <stagefright/AVExtensions.h>
 #include <gui/Surface.h>
 
 #include "avc_utils.h"
 #include "ATSParser.h"
+#include "mediaplayerservice/AVNuExtensions.h"
+#ifdef DOLBY_ENABLE
+#include "DolbyNuPlayerDecoderExtImpl.h"
+#endif // DOLBY_END
 
 namespace android {
 
@@ -78,7 +102,9 @@
 }
 
 NuPlayer::Decoder::~Decoder() {
-    mCodec->release();
+    if (mCodec != NULL) {
+        mCodec->release();
+    }
     releaseAndResetMediaBuffers();
 }
 
@@ -251,8 +277,10 @@
     mComponentName.append(" decoder");
     ALOGV("[%s] onConfigure (surface=%p)", mComponentName.c_str(), mSurface.get());
 
-    mCodec = MediaCodec::CreateByType(
-            mCodecLooper, mime.c_str(), false /* encoder */, NULL /* err */, mPid);
+    mCodec = AVUtils::get()->createCustomComponentByName(mCodecLooper, mime.c_str(), false /* encoder */, format);
+    if (mCodec == NULL) {
+        mCodec = MediaCodec::CreateByType(mCodecLooper, mime.c_str(), false /* encoder */);
+    }
     int32_t secure = 0;
     if (format->findInt32("secure", &secure) && secure != 0) {
         if (mCodec != NULL) {
@@ -313,6 +341,9 @@
 
     sp<AMessage> reply = new AMessage(kWhatCodecNotify, this);
     mCodec->setCallback(reply);
+#ifdef DOLBY_ENABLE
+    setDolbyMessage();
+#endif // DOLBY_END
 
     err = mCodec->start();
     if (err != OK) {
@@ -357,7 +388,14 @@
     if (notifyComplete) {
         mResumePending = true;
     }
-    mCodec->start();
+
+    if (mCodec != NULL) {
+        mCodec->start();
+    } else {
+        ALOGW("Decoder %s onResume without a valid codec object",
+              mComponentName.c_str());
+        handleError(NO_INIT);
+    }
 }
 
 void NuPlayer::Decoder::doFlush(bool notifyComplete) {
@@ -558,6 +596,11 @@
     sp<ABuffer> buffer;
     mCodec->getOutputBuffer(index, &buffer);
 
+    if (buffer == NULL) {
+        handleError(UNKNOWN_ERROR);
+        return false;
+    }
+
     if (index >= mOutputBuffers.size()) {
         for (size_t i = mOutputBuffers.size(); i <= index; ++i) {
             mOutputBuffers.add();
@@ -569,6 +612,8 @@
     buffer->setRange(offset, size);
     buffer->meta()->clear();
     buffer->meta()->setInt64("timeUs", timeUs);
+    setPcmFormat(buffer->meta());
+    AVNuUtils::get()->addFlagsInMeta(buffer, flags, mIsAudio);
 
     bool eos = flags & MediaCodec::BUFFER_FLAG_EOS;
     // we do not expect CODECCONFIG or SYNCFRAME for decoder
@@ -577,6 +622,14 @@
     reply->setSize("buffer-ix", index);
     reply->setInt32("generation", mBufferGeneration);
 
+    if ((flags & MediaCodec::BUFFER_FLAG_DATACORRUPT) &&
+            AVNuUtils::get()->dropCorruptFrame()) {
+        ALOGV("[%s] dropping corrupt buffer at time %lld as requested.",
+                     mComponentName.c_str(), (long long)timeUs);
+        reply->post();
+        return true;
+    }
+
     if (eos) {
         ALOGI("[%s] saw output EOS", mIsAudio ? "audio" : "video");
 
@@ -636,7 +689,7 @@
         }
 
         mRenderer->openAudioSink(
-                format, false /* offloadOnly */, hasVideo, flags, NULL /* isOffloaed */);
+                format, false /* offloadOnly */, hasVideo, flags, NULL /* isOffloaed */, mSource->isStreaming());
     }
 }
 
@@ -708,6 +761,7 @@
                     // treat seamless format change separately
                     formatChange = !seamlessFormatChange;
                 }
+                AVNuUtils::get()->checkFormatChange(&formatChange, accessUnit);
 
                 // For format or time change, return EOS to queue EOS input,
                 // then wait for EOS on output.
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.h b/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.h
index eeb4af4..1999615 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.h
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.h
@@ -12,6 +12,25 @@
  * 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.
+ *
+ * This file was modified by Dolby Laboratories, Inc. The portions of the
+ * code that are surrounded by "DOLBY..." are copyrighted and
+ * licensed separately, as follows:
+ *
+ *  (C) 2015 Dolby Laboratories, Inc.
+ *
+ * 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 NUPLAYER_DECODER_H_
@@ -49,8 +68,8 @@
     virtual void onFlush();
     virtual void onShutdown(bool notifyComplete);
     virtual bool doRequestBuffers();
+    virtual void setPcmFormat(const sp<AMessage> & /*format*/) {}
 
-private:
     enum {
         kWhatCodecNotify         = 'cdcN',
         kWhatRenderBuffer        = 'rndr',
@@ -103,7 +122,7 @@
             size_t size,
             int64_t timeUs,
             int32_t flags);
-    void handleOutputFormatChange(const sp<AMessage> &format);
+    virtual void handleOutputFormatChange(const sp<AMessage> &format);
 
     void releaseAndResetMediaBuffers();
     void requestCodecNotification();
@@ -121,6 +140,9 @@
     void finishHandleDiscontinuity(bool flushOnTimeChange);
 
     void notifyResumeCompleteIfNecessary();
+#ifdef DOLBY_ENABLE
+    void setDolbyMessage();
+#endif // DOLBY_END
 
     DISALLOW_EVIL_CONSTRUCTORS(Decoder);
 };
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerDecoderPassThrough.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerDecoderPassThrough.cpp
index 30146c4..937936d 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerDecoderPassThrough.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerDecoderPassThrough.cpp
@@ -29,14 +29,12 @@
 #include <media/stagefright/foundation/ADebug.h>
 #include <media/stagefright/foundation/AMessage.h>
 #include <media/stagefright/MediaErrors.h>
+#include "mediaplayerservice/AVNuExtensions.h"
 
 #include "ATSParser.h"
 
 namespace android {
 
-// TODO optimize buffer size for power consumption
-// The offload read buffer size is 32 KB but 24 KB uses less power.
-static const size_t kAggregateBufferSizeBytes = 24 * 1024;
 static const size_t kMaxCachedBytes = 200000;
 
 NuPlayer::DecoderPassThrough::DecoderPassThrough(
@@ -46,6 +44,9 @@
     : DecoderBase(notify),
       mSource(source),
       mRenderer(renderer),
+      // TODO optimize buffer size for power consumption
+      // The offload read buffer size is 32 KB but 24 KB uses less power.
+      mAggregateBufferSizeBytes(24 * 1024),
       mSkipRenderingUntilMediaTimeUs(-1ll),
       mPaused(false),
       mReachedEOS(true),
@@ -76,7 +77,7 @@
     // format is different.
     status_t err = mRenderer->openAudioSink(
             format, true /* offloadOnly */, hasVideo,
-            AUDIO_OUTPUT_FLAG_NONE /* flags */, NULL /* isOffloaded */);
+            AUDIO_OUTPUT_FLAG_NONE /* flags */, NULL /* isOffloaded */, mSource->isStreaming());
     if (err != OK) {
         handleError(err);
     }
@@ -173,9 +174,9 @@
     size_t smallSize = accessUnit->size();
     if ((mAggregateBuffer == NULL)
             // Don't bother if only room for a few small buffers.
-            && (smallSize < (kAggregateBufferSizeBytes / 3))) {
+            && (smallSize < (mAggregateBufferSizeBytes / 3))) {
         // Create a larger buffer for combining smaller buffers from the extractor.
-        mAggregateBuffer = new ABuffer(kAggregateBufferSizeBytes);
+        mAggregateBuffer = new ABuffer(mAggregateBufferSizeBytes);
         mAggregateBuffer->setRange(0, 0); // start empty
     }
 
@@ -201,6 +202,7 @@
             if ((bigSize == 0) && smallTimestampValid) {
                 mAggregateBuffer->meta()->setInt64("timeUs", timeUs);
             }
+            setPcmFormat(mAggregateBuffer->meta());
             // Append small buffer to the bigger buffer.
             memcpy(mAggregateBuffer->base() + bigSize, accessUnit->data(), smallSize);
             bigSize += smallSize;
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerDecoderPassThrough.h b/media/libmediaplayerservice/nuplayer/NuPlayerDecoderPassThrough.h
index db33e87..629e266 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerDecoderPassThrough.h
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerDecoderPassThrough.h
@@ -43,25 +43,27 @@
     virtual void onFlush();
     virtual void onShutdown(bool notifyComplete);
     virtual bool doRequestBuffers();
+    virtual void setPcmFormat(const sp<AMessage> & /*format*/) {}
+    virtual sp<ABuffer> aggregateBuffer(const sp<ABuffer> &accessUnit);
 
-private:
     enum {
         kWhatBufferConsumed     = 'bufC',
     };
 
     sp<Source> mSource;
     sp<Renderer> mRenderer;
+    size_t mAggregateBufferSizeBytes;
     int64_t mSkipRenderingUntilMediaTimeUs;
     bool mPaused;
-
-    bool    mReachedEOS;
+    bool mReachedEOS;
 
     // Used by feedDecoderInputData to aggregate small buffers into
     // one large buffer.
+    status_t mPendingAudioErr;
     sp<ABuffer> mPendingAudioAccessUnit;
-    status_t    mPendingAudioErr;
     sp<ABuffer> mAggregateBuffer;
 
+private:
     // mPendingBuffersToDrain are only for debugging. It can be removed
     // when the power investigation is done.
     size_t  mPendingBuffersToDrain;
@@ -72,7 +74,6 @@
     bool isDoneFetching() const;
 
     status_t dequeueAccessUnit(sp<ABuffer> *accessUnit);
-    sp<ABuffer> aggregateBuffer(const sp<ABuffer> &accessUnit);
     status_t fetchInputData(sp<AMessage> &reply);
     void doFlush(bool notifyComplete);
 
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp
index 7370224..a294d36 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp
@@ -31,6 +31,9 @@
 #include <media/stagefright/MetaData.h>
 #include <media/stagefright/Utils.h>
 
+#include "mediaplayerservice/AVNuExtensions.h"
+#include "mediaplayerservice/AVMediaServiceExtensions.h"
+
 namespace android {
 
 NuPlayerDriver::NuPlayerDriver(pid_t pid)
@@ -55,7 +58,7 @@
             true,  /* canCallJava */
             PRIORITY_AUDIO);
 
-    mPlayer = new NuPlayer(pid);
+    mPlayer = AVNuFactory::get()->createNuPlayer(pid);
     mLooper->registerHandler(mPlayer);
 
     mPlayer->setDriver(this);
@@ -114,6 +117,7 @@
         mCondition.wait(mLock);
     }
 
+    AVNuUtils::get()->printFileName(fd);
     return mAsyncResult;
 }
 
@@ -607,6 +611,8 @@
             Metadata::kSeekAvailable,
             mPlayerFlags & NuPlayer::Source::FLAG_CAN_SEEK);
 
+    AVMediaServiceUtils::get()->appendMeta(&meta);
+
     return OK;
 }
 
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp
index 776dba8..c92309b 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp
@@ -32,6 +32,8 @@
 #include <media/stagefright/VideoFrameScheduler.h>
 
 #include <inttypes.h>
+#include "mediaplayerservice/AVNuExtensions.h"
+#include "stagefright/AVExtensions.h"
 
 namespace android {
 
@@ -81,6 +83,16 @@
 // static
 const int64_t NuPlayer::Renderer::kMinPositionUpdateDelayUs = 100000ll;
 
+static bool sFrameAccurateAVsync = false;
+
+static void readProperties() {
+    char value[PROPERTY_VALUE_MAX];
+    if (property_get("persist.sys.media.avsync", value, NULL)) {
+        sFrameAccurateAVsync =
+            !strcmp("1", value) || !strcasecmp("true", value);
+    }
+}
+
 NuPlayer::Renderer::Renderer(
         const sp<MediaPlayerBase::AudioSink> &sink,
         const sp<AMessage> &notify,
@@ -102,6 +114,7 @@
       mVideoLateByUs(0ll),
       mHasAudio(false),
       mHasVideo(false),
+      mFoundAudioEOS(false),
       mNotifyCompleteAudio(false),
       mNotifyCompleteVideo(false),
       mSyncQueues(false),
@@ -122,6 +135,7 @@
     mMediaClock = new MediaClock;
     mPlaybackRate = mPlaybackSettings.mSpeed;
     mMediaClock->setPlaybackRate(mPlaybackRate);
+    readProperties();
 }
 
 NuPlayer::Renderer::~Renderer() {
@@ -312,7 +326,8 @@
 
 // Called on any threads.
 status_t NuPlayer::Renderer::getCurrentPosition(int64_t *mediaUs) {
-    return mMediaClock->getMediaTime(ALooper::GetNowUs(), mediaUs);
+    return mMediaClock->getMediaTime(
+            ALooper::GetNowUs(), mediaUs, (mHasAudio && mFoundAudioEOS));
 }
 
 void NuPlayer::Renderer::clearAudioFirstAnchorTime_l() {
@@ -348,18 +363,20 @@
         bool offloadOnly,
         bool hasVideo,
         uint32_t flags,
-        bool *isOffloaded) {
+        bool *isOffloaded,
+        bool isStreaming) {
     sp<AMessage> msg = new AMessage(kWhatOpenAudioSink, this);
     msg->setMessage("format", format);
     msg->setInt32("offload-only", offloadOnly);
     msg->setInt32("has-video", hasVideo);
     msg->setInt32("flags", flags);
+    msg->setInt32("isStreaming", isStreaming);
 
     sp<AMessage> response;
-    msg->postAndAwaitResponse(&response);
+    status_t postStatus = msg->postAndAwaitResponse(&response);
 
     int32_t err;
-    if (!response->findInt32("err", &err)) {
+    if (postStatus != OK || !response->findInt32("err", &err)) {
         err = INVALID_OPERATION;
     } else if (err == OK && isOffloaded != NULL) {
         int32_t offload;
@@ -392,7 +409,10 @@
             uint32_t flags;
             CHECK(msg->findInt32("flags", (int32_t *)&flags));
 
-            status_t err = onOpenAudioSink(format, offloadOnly, hasVideo, flags);
+            uint32_t isStreaming;
+            CHECK(msg->findInt32("isStreaming", (int32_t *)&isStreaming));
+
+            status_t err = onOpenAudioSink(format, offloadOnly, hasVideo, flags, isStreaming);
 
             sp<AMessage> response = new AMessage;
             response->setInt32("err", err);
@@ -435,9 +455,10 @@
 
             if (onDrainAudioQueue()) {
                 uint32_t numFramesPlayed;
-                CHECK_EQ(mAudioSink->getPosition(&numFramesPlayed),
-                         (status_t)OK);
-
+                if (mAudioSink->getPosition(&numFramesPlayed) != OK) {
+                    ALOGW("mAudioSink->getPosition failed");
+                    break;
+                }
                 uint32_t numFramesPendingPlayout =
                     mNumFramesWritten - numFramesPlayed;
 
@@ -1074,6 +1095,11 @@
 
     ALOGW_IF(delayUs > 500000, "unusually high delayUs: %" PRId64, delayUs);
     // post 2 display refreshes before rendering is due
+    // FIXME currently this increases power consumption, so unless frame-accurate
+    // AV sync is requested, post closer to required render time (at 0.63 vsyncs)
+    if (!sFrameAccurateAVsync) {
+        twoVsyncsUs >>= 4;
+    }
     msg->post(delayUs > twoVsyncsUs ? delayUs - twoVsyncsUs : 0);
 
     mDrainVideoQueuePending = true;
@@ -1164,6 +1190,9 @@
 }
 
 void NuPlayer::Renderer::notifyEOS(bool audio, status_t finalResult, int64_t delayUs) {
+    if (audio) {
+        mFoundAudioEOS = true;
+    }
     sp<AMessage> notify = mNotify->dup();
     notify->setInt32("what", kWhatEOS);
     notify->setInt32("audio", static_cast<int32_t>(audio));
@@ -1479,6 +1508,7 @@
 
     mDrainAudioQueuePending = false;
     mDrainVideoQueuePending = false;
+    mVideoRenderingStarted = false; // force-notify NOTE_INFO MEDIA_INFO_RENDERING_START after resume
 
     if (mHasAudio) {
         mAudioSink->pause();
@@ -1490,6 +1520,8 @@
 }
 
 void NuPlayer::Renderer::onResume() {
+    readProperties();
+
     if (!mPaused) {
         return;
     }
@@ -1559,6 +1591,7 @@
     int64_t numFramesPlayedAt;
     AudioTimestamp ts;
     static const int64_t kStaleTimestamp100ms = 100000;
+    int64_t durationUs;
 
     status_t res = mAudioSink->getTimestamp(ts);
     if (res == OK) {                 // case 1: mixing audio tracks and offloaded tracks.
@@ -1585,14 +1618,20 @@
         //        numFramesPlayed, (long long)numFramesPlayedAt);
     } else {                         // case 3: transitory at new track or audio fast tracks.
         res = mAudioSink->getPosition(&numFramesPlayed);
-        CHECK_EQ(res, (status_t)OK);
-        numFramesPlayedAt = nowUs;
-        numFramesPlayedAt += 1000LL * mAudioSink->latency() / 2; /* XXX */
+        if (res != OK) {
+            //query to getPosition fails, use media clock to simulate render position
+            getCurrentPosition(&durationUs);
+            durationUs = durationUs - mAnchorTimeMediaUs;
+            return durationUs;
+        } else {
+            numFramesPlayedAt = nowUs;
+            numFramesPlayedAt += 1000LL * mAudioSink->latency() / 2; /* XXX */
+        }
         //ALOGD("getPosition: %u %lld", numFramesPlayed, (long long)numFramesPlayedAt);
     }
 
     //CHECK_EQ(numFramesPlayed & (1 << 31), 0);  // can't be negative until 12.4 hrs, test
-    int64_t durationUs = getDurationUsIfPlayedAtSampleRate(numFramesPlayed)
+    durationUs = getDurationUsIfPlayedAtSampleRate(numFramesPlayed)
             + nowUs - numFramesPlayedAt;
     if (durationUs < 0) {
         // Occurs when numFramesPlayed position is very small and the following:
@@ -1650,7 +1689,8 @@
         const sp<AMessage> &format,
         bool offloadOnly,
         bool hasVideo,
-        uint32_t flags) {
+        uint32_t flags,
+        bool isStreaming) {
     ALOGV("openAudioSink: offloadOnly(%d) offloadingAudio(%d)",
             offloadOnly, offloadingAudio());
     bool audioSinkChanged = false;
@@ -1678,9 +1718,13 @@
                     "audio_format", mime.c_str());
             onDisableOffloadAudio();
         } else {
+            int32_t bitWidth = 16;
             ALOGV("Mime \"%s\" mapped to audio_format 0x%x",
                     mime.c_str(), audioFormat);
 
+            audioFormat = AVUtils::get()->updateAudioFormat(audioFormat, format);
+
+            bitWidth = AVUtils::get()->getAudioSampleBits(format);
             int avgBitRate = -1;
             format->findInt32("bit-rate", &avgBitRate);
 
@@ -1688,12 +1732,24 @@
             if (audioFormat == AUDIO_FORMAT_AAC
                     && format->findInt32("aac-profile", &aacProfile)) {
                 // Redefine AAC format as per aac profile
-                mapAACProfileToAudioFormat(
-                        audioFormat,
-                        aacProfile);
+                int32_t isADTSSupported;
+                isADTSSupported = AVUtils::get()->mapAACProfileToAudioFormat(format,
+                                          audioFormat,
+                                          aacProfile);
+                if (!isADTSSupported) {
+                    mapAACProfileToAudioFormat(audioFormat,
+                            aacProfile);
+                } else {
+                    ALOGV("Format is AAC ADTS\n");
+                }
             }
 
+            int32_t offloadBufferSize =
+                                    AVUtils::get()->getAudioMaxInputBufferSize(
+                                                   audioFormat,
+                                                   format);
             audio_offload_info_t offloadInfo = AUDIO_INFO_INITIALIZER;
+
             offloadInfo.duration_us = -1;
             format->findInt64(
                     "durationUs", &offloadInfo.duration_us);
@@ -1703,7 +1759,9 @@
             offloadInfo.stream_type = AUDIO_STREAM_MUSIC;
             offloadInfo.bit_rate = avgBitRate;
             offloadInfo.has_video = hasVideo;
-            offloadInfo.is_streaming = true;
+            offloadInfo.is_streaming = isStreaming;
+            offloadInfo.bit_width = bitWidth;
+            offloadInfo.offload_buffer_size = offloadBufferSize;
 
             if (memcmp(&mCurrentOffloadInfo, &offloadInfo, sizeof(offloadInfo)) == 0) {
                 ALOGV("openAudioSink: no change in offload mode");
@@ -1767,7 +1825,7 @@
         const PcmInfo info = {
                 (audio_channel_mask_t)channelMask,
                 (audio_output_flags_t)pcmFlags,
-                AUDIO_FORMAT_PCM_16_BIT, // TODO: change to audioFormat
+                AVNuUtils::get()->getPCMFormat(format),
                 numChannels,
                 sampleRate
         };
@@ -1802,7 +1860,7 @@
                     sampleRate,
                     numChannels,
                     (audio_channel_mask_t)channelMask,
-                    AUDIO_FORMAT_PCM_16_BIT,
+                    AVNuUtils::get()->getPCMFormat(format),
                     0 /* bufferCount - unused */,
                     mUseAudioCallback ? &NuPlayer::Renderer::AudioSinkCallback : NULL,
                     mUseAudioCallback ? this : NULL,
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.h b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.h
index 87bcbf9..50bd0a9 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.h
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.h
@@ -73,12 +73,15 @@
     status_t getCurrentPosition(int64_t *mediaUs);
     int64_t getVideoLateByUs();
 
+    virtual audio_stream_type_t getAudioStreamType(){return AUDIO_STREAM_DEFAULT;}
+
     status_t openAudioSink(
             const sp<AMessage> &format,
             bool offloadOnly,
             bool hasVideo,
             uint32_t flags,
-            bool *isOffloaded);
+            bool *isOffloaded,
+            bool isStreaming);
     void closeAudioSink();
 
     enum {
@@ -101,7 +104,6 @@
 
     virtual void onMessageReceived(const sp<AMessage> &msg);
 
-private:
     enum {
         kWhatDrainAudioQueue     = 'draA',
         kWhatDrainVideoQueue     = 'draV',
@@ -162,6 +164,7 @@
     int64_t mVideoLateByUs;
     bool mHasAudio;
     bool mHasVideo;
+    bool mFoundAudioEOS;
 
     bool mNotifyCompleteAudio;
     bool mNotifyCompleteVideo;
@@ -228,7 +231,7 @@
     void prepareForMediaRenderingStart_l();
     void notifyIfMediaRenderingStarted_l();
 
-    void onQueueBuffer(const sp<AMessage> &msg);
+    virtual void onQueueBuffer(const sp<AMessage> &msg);
     void onQueueEOS(const sp<AMessage> &msg);
     void onFlush(const sp<AMessage> &msg);
     void onAudioSinkChanged();
@@ -250,7 +253,8 @@
             const sp<AMessage> &format,
             bool offloadOnly,
             bool hasVideo,
-            uint32_t flags);
+            uint32_t flags,
+            bool isStreaming);
     void onCloseAudioSink();
 
     void notifyEOS(bool audio, status_t finalResult, int64_t delayUs = 0);
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerSource.h b/media/libmediaplayerservice/nuplayer/NuPlayerSource.h
index 11a6a9f..b248316 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerSource.h
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerSource.h
@@ -39,6 +39,7 @@
         FLAG_DYNAMIC_DURATION   = 16,
         FLAG_SECURE             = 32,
         FLAG_PROTECTED          = 64,
+        FLAG_USE_SET_BUFFERS    = 128,
     };
 
     enum {
@@ -57,6 +58,7 @@
         kWhatQueueDecoderShutdown,
         kWhatDrmNoLicense,
         kWhatInstantiateSecureDecoders,
+        kWhatRTCPByeReceived,
     };
 
     // The provides message is used to notify the player about various
@@ -132,10 +134,10 @@
     void notifyFlagsChanged(uint32_t flags);
     void notifyVideoSizeChanged(const sp<AMessage> &format = NULL);
     void notifyInstantiateSecureDecoders(const sp<AMessage> &reply);
-    void notifyPrepared(status_t err = OK);
+    virtual void notifyPrepared(status_t err = OK);
 
-private:
     sp<AMessage> mNotify;
+private:
 
     DISALLOW_EVIL_CONSTRUCTORS(Source);
 };
diff --git a/media/libmediaplayerservice/nuplayer/RTSPSource.cpp b/media/libmediaplayerservice/nuplayer/RTSPSource.cpp
index af0351e..35567a5 100644
--- a/media/libmediaplayerservice/nuplayer/RTSPSource.cpp
+++ b/media/libmediaplayerservice/nuplayer/RTSPSource.cpp
@@ -27,6 +27,7 @@
 #include <media/IMediaHTTPService.h>
 #include <media/stagefright/MediaDefs.h>
 #include <media/stagefright/MetaData.h>
+#include <mediaplayerservice/AVMediaServiceExtensions.h>
 
 namespace android {
 
@@ -131,6 +132,10 @@
 
         // Check if EOS or ERROR is received
         if (source != NULL && source->isFinished(mediaDurationUs)) {
+            if (mHandler != NULL) {
+                ALOGI("Nearing EOS...No Pause is issued");
+                mHandler->cancelTimeoutCheck();
+            }
             return;
         }
     }
@@ -476,8 +481,11 @@
                 if (!info->mNPTMappingValid) {
                     // This is a live stream, we didn't receive any normal
                     // playtime mapping. We won't map to npt time.
-                    source->queueAccessUnit(accessUnit);
-                    break;
+                    if (!AVMediaServiceUtils::get()->checkNPTMapping(&info->mRTPTime,
+                            &info->mNormalPlaytimeUs, &info->mNPTMappingValid, rtpTime)) {
+                        source->queueAccessUnit(accessUnit);
+                        break;
+                    }
                 }
 
                 int64_t nptUs =
@@ -563,6 +571,14 @@
             break;
         }
 
+        case MyHandler::kWhatByeReceived:
+        {
+            sp<AMessage> msg = dupNotify();
+            msg->setInt32("what", kWhatRTCPByeReceived);
+            msg->post();
+            break;
+        }
+
         case SDPLoader::kWhatSDPLoaded:
         {
             onSDPLoaded(msg);
diff --git a/media/libstagefright/ACodec.cpp b/media/libstagefright/ACodec.cpp
index 8d9bd21..677e2d7 100644
--- a/media/libstagefright/ACodec.cpp
+++ b/media/libstagefright/ACodec.cpp
@@ -12,6 +12,25 @@
  * 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.
+ *
+ * This file was modified by Dolby Laboratories, Inc. The portions of the
+ * code that are surrounded by "DOLBY..." are copyrighted and
+ * licensed separately, as follows:
+ *
+ *  (C) 2011-2015 Dolby Laboratories, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
  */
 
 //#define LOG_NDEBUG 0
@@ -54,6 +73,11 @@
 
 #include "include/avc_utils.h"
 
+#include <stagefright/AVExtensions.h>
+#ifdef DOLBY_ENABLE
+#include "DolbyACodecExtImpl.h"
+#endif // DOLBY_END
+
 namespace android {
 
 // OMX errors are directly mapped into status_t range if
@@ -539,6 +563,10 @@
 ACodec::~ACodec() {
 }
 
+status_t ACodec::setupCustomCodec(status_t err, const char *, const sp<AMessage> &) {
+    return err;
+}
+
 void ACodec::setNotificationMessage(const sp<AMessage> &msg) {
     mNotify = msg;
 }
@@ -613,8 +641,8 @@
     msg->setInt32("keepComponentAllocated", keepComponentAllocated);
     msg->post();
     if (!keepComponentAllocated) {
-        // ensure shutdown completes in 3 seconds
-        (new AMessage(kWhatReleaseCodecInstance, this))->post(3000000);
+        // ensure shutdown completes in 30 seconds
+        (new AMessage(kWhatReleaseCodecInstance, this))->post(30000000);
     }
 }
 
@@ -828,15 +856,11 @@
                         : OMXCodec::kRequiresAllocateBufferOnOutputPorts;
 
                 if ((portIndex == kPortIndexInput && (mFlags & kFlagIsSecure))
-                        || (portIndex == kPortIndexOutput && usingMetadataOnEncoderOutput())) {
+                        || (portIndex == kPortIndexOutput && usingMetadataOnEncoderOutput())
+                        || canAllocateBuffer(portIndex)) {
                     mem.clear();
 
-                    void *ptr;
-                    err = mOMX->allocateBuffer(
-                            mNode, portIndex, bufSize, &info.mBufferID,
-                            &ptr);
-
-                    info.mData = new ABuffer(ptr, bufSize);
+                    err = allocateBuffer(portIndex, bufSize, info);
                 } else if (mQuirks & requiresAllocateBufferBit) {
                     err = mOMX->allocateBufferWithBackup(
                             mNode, portIndex, mem, &info.mBufferID, allottedSize);
@@ -1574,6 +1598,10 @@
             "audio_decoder.ac3", "audio_encoder.ac3" },
         { MEDIA_MIMETYPE_AUDIO_EAC3,
             "audio_decoder.eac3", "audio_encoder.eac3" },
+#ifdef DOLBY_UDC
+        { MEDIA_MIMETYPE_AUDIO_EAC3_JOC,
+            "audio_decoder.eac3_joc", NULL },
+#endif // DOLBY_END
     };
 
     static const size_t kNumMimeToRole =
@@ -1639,6 +1667,8 @@
         return err;
     }
 
+    enableCustomAllocationMode(msg);
+
     int32_t bitRate = 0;
     // FLAC encoder doesn't need a bitrate, other encoders do
     if (encoder && strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_FLAC)
@@ -2069,7 +2099,11 @@
             }
             err = setupG711Codec(encoder, sampleRate, numChannels);
         }
+#ifdef QTI_FLAC_DECODER
+    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_FLAC) && encoder) {
+#else
     } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_FLAC)) {
+#endif
         int32_t numChannels = 0, sampleRate = 0, compressionLevel = -1;
         if (encoder &&
                 (!msg->findInt32("channel-count", &numChannels)
@@ -2125,6 +2159,8 @@
         } else {
             err = setupEAC3Codec(encoder, numChannels, sampleRate);
         }
+    } else {
+        err = setupCustomCodec(err, mime, msg);
     }
 
     if (err != OK) {
@@ -2835,13 +2871,14 @@
     { MEDIA_MIMETYPE_VIDEO_AVC, OMX_VIDEO_CodingAVC },
     { MEDIA_MIMETYPE_VIDEO_HEVC, OMX_VIDEO_CodingHEVC },
     { MEDIA_MIMETYPE_VIDEO_MPEG4, OMX_VIDEO_CodingMPEG4 },
+    { MEDIA_MIMETYPE_VIDEO_MPEG4_DP, OMX_VIDEO_CodingMPEG4 },
     { MEDIA_MIMETYPE_VIDEO_H263, OMX_VIDEO_CodingH263 },
     { MEDIA_MIMETYPE_VIDEO_MPEG2, OMX_VIDEO_CodingMPEG2 },
     { MEDIA_MIMETYPE_VIDEO_VP8, OMX_VIDEO_CodingVP8 },
     { MEDIA_MIMETYPE_VIDEO_VP9, OMX_VIDEO_CodingVP9 },
 };
 
-static status_t GetVideoCodingTypeFromMime(
+status_t ACodec::GetVideoCodingTypeFromMime(
         const char *mime, OMX_VIDEO_CODINGTYPE *codingType) {
     for (size_t i = 0;
          i < sizeof(kVideoCodingMapEntry) / sizeof(kVideoCodingMapEntry[0]);
@@ -3228,6 +3265,7 @@
         mpeg4type.eLevel = static_cast<OMX_VIDEO_MPEG4LEVELTYPE>(level);
     }
 
+    setBFrames(&mpeg4type);
     err = mOMX->setParameter(
             mNode, OMX_IndexParamVideoMpeg4, &mpeg4type, sizeof(mpeg4type));
 
@@ -3425,6 +3463,8 @@
         err = verifySupportForProfileAndLevel(profile, level);
 
         if (err != OK) {
+            ALOGE("%s does not support profile %x @ level %x",
+                    mComponentName.c_str(), profile, level);
             return err;
         }
 
@@ -3433,11 +3473,14 @@
     }
 
     // XXX
+    // Allow higher profiles to be set since the encoder seems to support
+#if 0
     if (h264type.eProfile != OMX_VIDEO_AVCProfileBaseline) {
         ALOGW("Use baseline profile instead of %d for AVC recording",
             h264type.eProfile);
         h264type.eProfile = OMX_VIDEO_AVCProfileBaseline;
     }
+#endif
 
     if (h264type.eProfile == OMX_VIDEO_AVCProfileBaseline) {
         h264type.nSliceHeaderSpacing = 0;
@@ -3458,6 +3501,7 @@
         h264type.nCabacInitIdc = 0;
     }
 
+    setBFrames(&h264type, iFrameInterval, frameRate);
     if (h264type.nBFrames != 0) {
         h264type.nAllowedPictureTypes |= OMX_VIDEO_PictureTypeB;
     }
@@ -3498,6 +3542,8 @@
         frameRate = (float)tmp;
     }
 
+    AVUtils::get()->setIntraPeriod(setPFramesSpacing(iFrameInterval, frameRate), 0, mOMX, mNode);
+
     OMX_VIDEO_PARAM_HEVCTYPE hevcType;
     InitOMXParams(&hevcType);
     hevcType.nPortIndex = kPortIndexOutput;
@@ -4179,7 +4225,8 @@
 
                     if (params.nChannels <= 0
                             || (params.nChannels != 1 && !params.bInterleaved)
-                            || params.nBitPerSample != 16u
+                            || (params.nBitPerSample != 16u
+                                    && params.nBitPerSample != 24u)// we support 16/24 bit s/w decoding
                             || params.eNumData != OMX_NumericalDataSigned
                             || params.ePCMMode != OMX_AUDIO_PCMModeLinear) {
                         ALOGE("unsupported PCM port: %u channels%s, %u-bit, %s(%d), %s(%d) mode ",
@@ -4194,7 +4241,7 @@
                     notify->setString("mime", MEDIA_MIMETYPE_AUDIO_RAW);
                     notify->setInt32("channel-count", params.nChannels);
                     notify->setInt32("sample-rate", params.nSamplingRate);
-
+                    notify->setInt32("bit-width", params.nBitPerSample);
                     if (mChannelMaskPresent) {
                         notify->setInt32("channel-mask", mChannelMask);
                     }
@@ -4448,6 +4495,8 @@
                 mEncoderPadding * frameSize);
     }
 
+    getVQZIPInfo(notify);
+
     notify->post();
 
     mSentFormat = true;
@@ -4596,6 +4645,7 @@
             ALOGI("[%s] forcing the release of codec",
                     mCodec->mComponentName.c_str());
             status_t err = mCodec->mOMX->freeNode(mCodec->mNode);
+            mCodec->changeState(mCodec->mUninitializedState);
             ALOGE_IF("[%s] failed to release codec instance: err=%d",
                        mCodec->mComponentName.c_str(), err);
             sp<AMessage> notify = mCodec->mNotify->dup();
@@ -5180,6 +5230,7 @@
                 mCodec->mSkipCutBuffer->submit(info->mData);
             }
             info->mData->meta()->setInt64("timeUs", timeUs);
+            info->mData->meta()->setObject("graphic-buffer", info->mGraphicBuffer);
 
             sp<AMessage> notify = mCodec->mNotify->dup();
             notify->setInt32("what", CodecBase::kWhatDrainThisBuffer);
@@ -5189,6 +5240,8 @@
 
             reply->setInt32("buffer-id", info->mBufferID);
 
+            (void)mCodec->setDSModeHint(reply, flags, timeUs);
+
             notify->setMessage("reply", reply);
 
             notify->post();
@@ -5243,8 +5296,9 @@
         ALOGW_IF(err != NO_ERROR, "failed to set crop: %d", err);
     }
 
+    bool skip = mCodec->getDSModeHint(msg);
     int32_t render;
-    if (mCodec->mNativeWindow != NULL
+    if (!skip && mCodec->mNativeWindow != NULL
             && msg->findInt32("render", &render) && render != 0
             && info->mData != NULL && info->mData->size() != 0) {
         ATRACE_NAME("render");
@@ -5665,6 +5719,15 @@
             handled = true;
             break;
         }
+#ifdef DOLBY_ENABLE
+        case ACodec::kWhatSetParameters:
+        {
+            mCodec->setDolbyParameter(msg);
+
+            handled = true;
+            break;
+        }
+#endif // DOLBY_END
 
         default:
             return BaseState::onMessageReceived(msg);
@@ -5697,6 +5760,7 @@
     {
         sp<AMessage> notify = mCodec->mNotify->dup();
         notify->setInt32("what", CodecBase::kWhatComponentConfigured);
+        notify->setString("componentName", mCodec->mComponentName.c_str());
         notify->setMessage("input-format", mCodec->mInputFormat);
         notify->setMessage("output-format", mCodec->mOutputFormat);
         notify->post();
@@ -5871,6 +5935,9 @@
     if (err != OK) {
         mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
     } else {
+#ifdef DOLBY_ENABLE
+        mCodec->setDolbyParameterOnEndpChange();
+#endif // DOLBY_END
         mCodec->changeState(mCodec->mLoadedToIdleState);
     }
 }
@@ -6344,6 +6411,9 @@
             return err;
         }
     }
+#ifdef DOLBY_ENABLE
+    return setDolbyParameterOnProcessedAudio(params);
+#endif // DOLBY_END
 
     return OK;
 }
@@ -6359,6 +6429,23 @@
     notify->post();
 }
 
+sp<IOMXObserver> ACodec::createObserver() {
+    sp<CodecObserver> observer = new CodecObserver;
+    sp<AMessage> notify = new AMessage(kWhatOMXMessageList, this);
+    observer->setNotificationMessage(notify);
+    return observer;
+}
+
+status_t ACodec::allocateBuffer(
+        OMX_U32 portIndex,  size_t bufSize, BufferInfo &info) {
+    void *ptr;
+    status_t err = mOMX->allocateBuffer(
+            mNode, portIndex, bufSize, &info.mBufferID, &ptr);
+
+    info.mData = new ABuffer(ptr, bufSize);
+    return err;
+}
+
 bool ACodec::ExecutingState::onOMXFrameRendered(int64_t mediaTimeUs, nsecs_t systemNano) {
     mCodec->onFrameRendered(mediaTimeUs, systemNano);
     return true;
diff --git a/media/libstagefright/Android.mk b/media/libstagefright/Android.mk
index 2529aa7..9687c7d 100644
--- a/media/libstagefright/Android.mk
+++ b/media/libstagefright/Android.mk
@@ -72,6 +72,7 @@
 
 LOCAL_C_INCLUDES:= \
         $(TOP)/frameworks/av/include/media/ \
+        $(TOP)/frameworks/av/media/libavextensions \
         $(TOP)/frameworks/av/include/media/stagefright/timedtext \
         $(TOP)/frameworks/native/include/media/hardware \
         $(TOP)/frameworks/native/include/media/openmax \
@@ -104,7 +105,7 @@
         libutils \
         libvorbisidec \
         libz \
-        libpowermanager
+        libpowermanager \
 
 LOCAL_STATIC_LIBRARIES := \
         libstagefright_color_conversion \
@@ -120,6 +121,8 @@
         libFLAC \
         libmedia_helper \
 
+LOCAL_WHOLE_STATIC_LIBRARIES := libavextensions
+
 LOCAL_SHARED_LIBRARIES += \
         libstagefright_enc_common \
         libstagefright_avc_common \
@@ -129,11 +132,22 @@
 
 LOCAL_CFLAGS += -Wno-multichar -Werror -Wno-error=deprecated-declarations -Wall
 
+ifeq ($(TARGET_USES_QCOM_BSP), true)
+    LOCAL_C_INCLUDES += hardware/qcom/display/libgralloc
+    LOCAL_CFLAGS += -DQTI_BSP
+endif
+
 # enable experiments only in userdebug and eng builds
 ifneq (,$(filter userdebug eng,$(TARGET_BUILD_VARIANT)))
 LOCAL_CFLAGS += -DENABLE_STAGEFRIGHT_EXPERIMENTS
 endif
 
+ifeq ($(call is-vendor-board-platform,QCOM),true)
+ifeq ($(strip $(AUDIO_FEATURE_ENABLED_EXTN_FLAC_DECODER)),true)
+    LOCAL_CFLAGS += -DQTI_FLAC_DECODER
+endif
+endif
+
 LOCAL_CLANG := true
 
 LOCAL_MODULE:= libstagefright
diff --git a/media/libstagefright/AudioPlayer.cpp b/media/libstagefright/AudioPlayer.cpp
index dd9d393..69a1562 100644
--- a/media/libstagefright/AudioPlayer.cpp
+++ b/media/libstagefright/AudioPlayer.cpp
@@ -12,6 +12,25 @@
  * 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.
+ *
+ * This file was modified by Dolby Laboratories, Inc. The portions of the
+ * code that are surrounded by "DOLBY..." are copyrighted and
+ * licensed separately, as follows:
+ *
+ *  (C) 2014-2015 Dolby Laboratories, Inc.
+ *
+ * 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 <inttypes.h>
@@ -34,6 +53,9 @@
 #include <media/stagefright/Utils.h>
 
 #include "include/AwesomePlayer.h"
+#ifdef DOLBY_ENABLE
+#include "DolbyAudioPlayerExtImpl.h"
+#endif // DOLBY_END
 
 namespace android {
 
@@ -256,6 +278,9 @@
 
     mStarted = true;
     mPlaying = true;
+#ifdef DOLBY_ENABLE
+    setDolbyProcessedAudio(format);
+#endif // DOLBY_END
     mPinnedTimeUs = -1ll;
 
     return OK;
diff --git a/media/libstagefright/AudioSource.cpp b/media/libstagefright/AudioSource.cpp
index 6e4a1dd..dc9c37b 100644
--- a/media/libstagefright/AudioSource.cpp
+++ b/media/libstagefright/AudioSource.cpp
@@ -61,7 +61,7 @@
       mNumClientOwnedBuffers(0) {
     ALOGV("sampleRate: %u, outSampleRate: %u, channelCount: %u",
             sampleRate, outSampleRate, channelCount);
-    CHECK(channelCount == 1 || channelCount == 2);
+    CHECK(channelCount == 1 || channelCount == 2 || channelCount == 6);
     CHECK(sampleRate > 0);
 
     size_t minFrameCount;
@@ -124,6 +124,8 @@
     int64_t startTimeUs;
     if (params && params->findInt64(kKeyTime, &startTimeUs)) {
         mStartTimeUs = startTimeUs;
+    } else {
+        mStartTimeUs = systemTime() / 1000ll;
     }
     status_t err = mRecord->start();
     if (err == OK) {
diff --git a/media/libstagefright/CameraSource.cpp b/media/libstagefright/CameraSource.cpp
index 66280da..27a6086 100644
--- a/media/libstagefright/CameraSource.cpp
+++ b/media/libstagefright/CameraSource.cpp
@@ -33,6 +33,8 @@
 #include <utils/String8.h>
 #include <cutils/properties.h>
 
+#include <stagefright/AVExtensions.h>
+
 #if LOG_NDEBUG
 #define UNUSED_UNLESS_VERBOSE(x) (void)(x)
 #else
@@ -98,6 +100,11 @@
 }
 
 static int32_t getColorFormat(const char* colorFormat) {
+    if (!colorFormat) {
+        ALOGE("Invalid color format");
+        return -1;
+    }
+
     if (!strcmp(colorFormat, CameraParameters::PIXEL_FORMAT_YUV420P)) {
        return OMX_COLOR_FormatYUV420Planar;
     }
@@ -298,6 +305,12 @@
     return OK;
 }
 
+static int32_t getHighSpeedFrameRate(const CameraParameters& params) {
+    const char* hsr = params.get("video-hsr");
+    int32_t rate = (hsr != NULL && strncmp(hsr, "off", 3)) ? atoi(hsr) : 0;
+    return rate > 240 ? 240 : rate;
+}
+
 /*
  * Configure the camera to use the requested video size
  * (width and height) and/or frame rate. If both width and
@@ -350,6 +363,10 @@
                 params->get(CameraParameters::KEY_SUPPORTED_PREVIEW_FRAME_RATES);
         CHECK(supportedFrameRates != NULL);
         ALOGV("Supported frame rates: %s", supportedFrameRates);
+        if (getHighSpeedFrameRate(*params)) {
+            ALOGI("Use default 30fps for HighSpeed %dfps", frameRate);
+            frameRate = 30;
+        }
         char buf[4];
         snprintf(buf, 4, "%d", frameRate);
         if (strstr(supportedFrameRates, buf) == NULL) {
@@ -451,6 +468,8 @@
         ALOGE("Failed to retrieve preview frame rate (%d)", frameRateActual);
         return UNKNOWN_ERROR;
     }
+    int32_t highSpeedRate = getHighSpeedFrameRate(params);
+    frameRateActual = highSpeedRate ? highSpeedRate : frameRateActual;
 
     // Check the actual video frame rate against the target/requested
     // video frame rate.
@@ -575,6 +594,8 @@
     mMeta->setInt32(kKeyStride,      mVideoSize.width);
     mMeta->setInt32(kKeySliceHeight, mVideoSize.height);
     mMeta->setInt32(kKeyFrameRate,   mVideoFrameRate);
+    AVUtils::get()->extractCustomCameraKeys(params, mMeta);
+
     return OK;
 }
 
diff --git a/media/libstagefright/CameraSourceTimeLapse.cpp b/media/libstagefright/CameraSourceTimeLapse.cpp
index 0acd9d0..926e95c 100644
--- a/media/libstagefright/CameraSourceTimeLapse.cpp
+++ b/media/libstagefright/CameraSourceTimeLapse.cpp
@@ -279,7 +279,8 @@
     // The first 2 output frames from the encoder are: decoder specific info and
     // the compressed video frame data for the first input video frame.
     if (mNumFramesEncoded >= 1 && *timestampUs <
-        (mLastTimeLapseFrameRealTimestampUs + mTimeBetweenFrameCaptureUs)) {
+        (mLastTimeLapseFrameRealTimestampUs + mTimeBetweenFrameCaptureUs) &&
+        (mTimeBetweenFrameCaptureUs > mTimeBetweenTimeLapseVideoFramesUs + 1)) {
         // Skip all frames from last encoded frame until
         // sufficient time (mTimeBetweenFrameCaptureUs) has passed.
         // Tell the camera to release its recording frame and return.
@@ -294,6 +295,12 @@
 
         mLastTimeLapseFrameRealTimestampUs = *timestampUs;
         *timestampUs = mLastFrameTimestampUs + mTimeBetweenTimeLapseVideoFramesUs;
+        // Update start-time once the captured-time reaches the expected start-time.
+        // Not doing so will result in CameraSource always dropping frames since
+        // updated-timestamp will never intersect start-timestamp
+        if ((mNumFramesReceived == 0 && mLastTimeLapseFrameRealTimestampUs >= mStartTimeUs)) {
+            mStartTimeUs = *timestampUs;
+        }
         return false;
     }
     return false;
diff --git a/media/libstagefright/DataSource.cpp b/media/libstagefright/DataSource.cpp
index 5020c6c..b5e7a6e 100644
--- a/media/libstagefright/DataSource.cpp
+++ b/media/libstagefright/DataSource.cpp
@@ -48,6 +48,8 @@
 
 #include <cutils/properties.h>
 
+#include <stagefright/AVExtensions.h>
+
 namespace android {
 
 bool DataSource::getUInt16(off64_t offset, uint16_t *x) {
@@ -175,6 +177,7 @@
     RegisterSniffer_l(SniffMPEG2PS);
     RegisterSniffer_l(SniffWVM);
     RegisterSniffer_l(SniffMidi);
+    RegisterSniffer_l(AVUtils::get()->getExtendedSniffer());
 
     char value[PROPERTY_VALUE_MAX];
     if (property_get("drm.service.enabled", value, NULL)
@@ -190,7 +193,8 @@
         const char *uri,
         const KeyedVector<String8, String8> *headers,
         String8 *contentType,
-        HTTPBase *httpSource) {
+        HTTPBase *httpSource,
+        bool useExtendedCache) {
     if (contentType != NULL) {
         *contentType = "";
     }
@@ -214,7 +218,7 @@
                 ALOGE("Failed to make http connection from http service!");
                 return NULL;
             }
-            httpSource = new MediaHTTP(conn);
+            httpSource = AVFactory::get()->createMediaHTTP(conn);
         }
 
         String8 tmp;
@@ -246,10 +250,17 @@
                 *contentType = httpSource->getMIMEType();
             }
 
-            source = NuCachedSource2::Create(
-                    httpSource,
-                    cacheConfig.isEmpty() ? NULL : cacheConfig.string(),
-                    disconnectAtHighwatermark);
+            if (useExtendedCache) {
+                source = AVFactory::get()->createCachedSource(
+                        httpSource,
+                        cacheConfig.isEmpty() ? NULL : cacheConfig.string(),
+                        disconnectAtHighwatermark);
+            } else {
+                source = NuCachedSource2::Create(
+                        httpSource,
+                        cacheConfig.isEmpty() ? NULL : cacheConfig.string(),
+                        disconnectAtHighwatermark);
+            }
         } else {
             // We do not want that prefetching, caching, datasource wrapper
             // in the widevine:// case.
@@ -278,7 +289,7 @@
     if (conn == NULL) {
         return NULL;
     } else {
-        return new MediaHTTP(conn);
+        return AVFactory::get()->createMediaHTTP(conn);
     }
 }
 
diff --git a/media/libstagefright/MPEG4Extractor.cpp b/media/libstagefright/MPEG4Extractor.cpp
index a1af3aa..c5112cc 100755
--- a/media/libstagefright/MPEG4Extractor.cpp
+++ b/media/libstagefright/MPEG4Extractor.cpp
@@ -12,6 +12,25 @@
  * 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.
+ *
+ * This file was modified by Dolby Laboratories, Inc. The portions of the
+ * code that are surrounded by "DOLBY..." are copyrighted and
+ * licensed separately, as follows:
+ *
+ *  (C) 2011-2015 Dolby Laboratories, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
  */
 
 //#define LOG_NDEBUG 0
@@ -47,6 +66,11 @@
 #ifndef UINT32_MAX
 #define UINT32_MAX       (4294967295U)
 #endif
+#if defined(DOLBY_ENABLE) && defined(DEBUG_LOG_DDP_DECODER_EXTRA)
+#define DLOGD ALOGD
+#else
+#define DLOGD(...) ((void)0)
+#endif // DOLBY_END
 
 namespace android {
 
@@ -203,6 +227,9 @@
       mCachedOffset(0),
       mCachedSize(0),
       mCache(NULL) {
+#ifdef DOLBY_ENABLE
+      DLOGD("@DDP MPEG4DataSource::MPEG4DataSource");
+#endif // DOLBY_END
 }
 
 MPEG4DataSource::~MPEG4DataSource() {
@@ -311,6 +338,9 @@
 }
 
 static const char *FourCC2MIME(uint32_t fourcc) {
+#ifdef DOLBY_ENABLE
+    DLOGD("@DDP FourCC2MIME");
+#endif // DOLBY_END
     switch (fourcc) {
         case FOURCC('m', 'p', '4', 'a'):
             return MEDIA_MIMETYPE_AUDIO_AAC;
@@ -335,7 +365,18 @@
         case FOURCC('h', 'v', 'c', '1'):
         case FOURCC('h', 'e', 'v', '1'):
             return MEDIA_MIMETYPE_VIDEO_HEVC;
+#ifdef DOLBY_ENABLE
+        case FOURCC('a', 'c', '-', '3'):
+            DLOGD("@DDP Track FOURCC = 'ac-3'");
+            return MEDIA_MIMETYPE_AUDIO_AC3;
+        case FOURCC('e', 'c', '-', '3'):
+            DLOGD("@DDP Track FOURCC = 'ec-3'");
+            return MEDIA_MIMETYPE_AUDIO_EAC3;
+#endif // DOLBY_END
         default:
+#ifdef DOLBY_ENABLE
+            ALOGD("@DDP FourCC2Mime default (not found)");
+#endif // DOLBY_END
             CHECK(!"should not be here.");
             return NULL;
     }
@@ -369,6 +410,9 @@
       mFileMetaData(new MetaData),
       mFirstSINF(NULL),
       mIsDrm(false) {
+#ifdef DOLBY_ENABLE
+      DLOGD("@DDP MPEG4Extractor::MPEG4Extractor");
+#endif // DOLBY_END
 }
 
 MPEG4Extractor::~MPEG4Extractor() {
@@ -535,6 +579,7 @@
     }
     if (psshsize > 0 && psshsize <= UINT32_MAX) {
         char *buf = (char*)malloc(psshsize);
+        CHECK(buf != NULL);
         char *ptr = buf;
         for (size_t i = 0; i < mPssh.size(); i++) {
             memcpy(ptr, mPssh[i].uuid, 20); // uuid + length
@@ -1319,6 +1364,10 @@
         case FOURCC('e', 'n', 'c', 'a'):
         case FOURCC('s', 'a', 'm', 'r'):
         case FOURCC('s', 'a', 'w', 'b'):
+#ifdef DOLBY_ENABLE
+        case FOURCC('a', 'c', '-', '3'):
+        case FOURCC('e', 'c', '-', '3'):
+#endif // DOLBY_END
         {
             uint8_t buffer[8 + 20];
             if (chunk_data_size < (ssize_t)sizeof(buffer)) {
@@ -1342,7 +1391,20 @@
 
             if (chunk_type != FOURCC('e', 'n', 'c', 'a')) {
                 // if the chunk type is enca, we'll get the type from the sinf/frma box later
+#ifdef DOLBY_ENABLE
+                const char *mime;
+                CHECK(mLastTrack->meta->findCString(kKeyMIMEType, &mime));
+                //Track mime-type should have been set at 'trak'
+                //Only set the mimetype here to the chunk type if it hasn't changed
+                //Eg. EC3SpecificBox may already have set it to a more appropriate value
+                if (!strcmp(mime, "application/octet-stream")) {
+                    DLOGD("@DDP Set mimetype from %s to %s", mime, FourCC2MIME(chunk_type));
+#endif // DOLBY_END
                 mLastTrack->meta->setCString(kKeyMIMEType, FourCC2MIME(chunk_type));
+#ifdef DOLBY_ENABLE
+                DLOGD("@DDP FourCC:'%s'", FourCC2MIME(chunk_type));
+                }
+#endif // DOLBY_END
                 AdjustChannelsAndRate(chunk_type, &num_channels, &sample_rate);
             }
             ALOGV("*** coding='%s' %d channels, size %d, rate %d\n",
@@ -1365,6 +1427,96 @@
             break;
         }
 
+#ifdef DOLBY_ENABLE
+        case FOURCC('d', 'a', 'c', '3'):
+        {
+            uint8_t buffer[3];
+            if (chunk_data_size < (ssize_t)sizeof(buffer)) {
+                // 3 bytes for AC3Specific.
+                return ERROR_MALFORMED;
+            }
+
+            if (mDataSource->readAt(
+                        data_offset, buffer, sizeof(buffer)) < (ssize_t)sizeof(buffer)) {
+                return ERROR_IO;
+            }
+            uint32_t acmod = (buffer[1] >> 3) & 0x3; //acmod presents channels of DD
+            if (acmod > 2) {
+               mLastTrack->meta->setInt32(kKeyChannelCount, 6); //5.1 case
+            }
+            *offset += chunk_size;
+            break;
+        }
+
+        case FOURCC('d', 'e', 'c', '3'):
+        {
+            //Only allowed on E-AC3 tracks
+            if (!(mPath.size() >= 2 && (
+                    mPath[mPath.size() - 2] == FOURCC('e', 'c', '-', '3')))) {
+                return ERROR_MALFORMED;
+            }
+
+            //Minimum EC3SpecificBox Length
+            if (chunk_data_size < 5) {
+                return ERROR_MALFORMED;
+            }
+
+            //JOC Extensions allow EC3SpecificBox to be boundless in size
+            //Impose a realistic limit of 256 bytes
+            uint8_t buffer[256];
+            if (chunk_data_size > (off64_t)sizeof(buffer)) {
+                return ERROR_BUFFER_TOO_SMALL;
+            }
+
+            if (mDataSource->readAt(
+                    data_offset, buffer, chunk_data_size) < chunk_data_size) {
+                return ERROR_IO;
+            }
+            DLOGD("@DDP - Valid EC3SpecificBox detected");
+
+            uint8_t data_offset = 1;
+            uint32_t num_channels = 2;
+            uint8_t num_ind_sub = (buffer[data_offset] & 0x7) + 1; //0 = One I substream
+            DLOGD("@DDP - EC3SpecificBox reports num_ind_sub = %d", num_ind_sub);
+
+            for (uint8_t i = 0; i < num_ind_sub; i++) {
+                data_offset += 2;
+                uint32_t acmod = (buffer[data_offset] >> 1) & 0x3;
+                if(acmod > 2) {
+                    num_channels = 6;
+                }
+                data_offset++;
+                uint8_t num_dep_sub = (buffer[data_offset] >> 1) & 0xF;
+
+                DLOGD("@DDP - I%d : num_dep_sub = %d", i, num_dep_sub);
+                if (num_dep_sub > 0) {
+                    data_offset++; //chan_loc byte
+                    if ((buffer[data_offset]>>1) & 0x1) { // Only support Lrs/Rrs case
+                        num_channels = 8;
+                    }
+                }
+            }
+
+            if (num_channels != 2) {
+                mLastTrack->meta->setInt32(kKeyChannelCount, num_channels);
+            }
+            if (chunk_data_size - (data_offset + 1) >= 2) {
+                //JOC requires at least 2 bytes extension data
+                data_offset++;
+                if (buffer[data_offset] & 0x1) {
+                    mLastTrack->meta->setCString(
+                            kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_EAC3_JOC);
+                    DLOGD("@DDP - flag_eac3_extension_type_a = 1 - Set EAC3/JOC mimetype");
+                }
+            }
+            else if (chunk_data_size > (data_offset +1)){
+                ALOGE("@DDP - Invalid EC3SpecificBox extension data");
+                return ERROR_MALFORMED;
+            }
+            *offset += chunk_size;
+            break;
+        }
+#endif // DOLBY_END
         case FOURCC('m', 'p', '4', 'v'):
         case FOURCC('e', 'n', 'c', 'v'):
         case FOURCC('s', '2', '6', '3'):
@@ -1590,13 +1742,21 @@
                 return ERROR_MALFORMED;
 
             *offset += chunk_size;
+            // Ignore stss block for audio even if its present
+            // All audio sample are sync samples itself,
+            // self decodeable and playable.
+            // Parsing this block for audio restricts audio seek to few entries
+            // available in this block, sometimes 0, which is undesired.
+            const char *mime;
+            CHECK(mLastTrack->meta->findCString(kKeyMIMEType, &mime));
+            if (strncasecmp("audio/", mime, 6)) {
+                status_t err =
+                    mLastTrack->sampleTable->setSyncSampleParams(
+                            data_offset, chunk_data_size);
 
-            status_t err =
-                mLastTrack->sampleTable->setSyncSampleParams(
-                        data_offset, chunk_data_size);
-
-            if (err != OK) {
-                return err;
+                if (err != OK) {
+                    return err;
+                }
             }
 
             break;
@@ -3129,7 +3289,7 @@
                         extensionFlag, objectType);
             }
 
-            if (numChannels == 0) {
+            if (numChannels == 0 && (br.numBitsLeft() > 0)) {
                 int32_t channelsEffectiveNum = 0;
                 int32_t channelsNum = 0;
                 if (br.numBitsLeft() < 32) {
@@ -3267,6 +3427,9 @@
       mBuffer(NULL),
       mWantsNALFragments(false),
       mSrcBuffer(NULL) {
+#ifdef DOLBY_ENABLE
+      DLOGD("@DDP MPEG4Source::MPEG4Source");
+#endif // DOLBY_END
 
     memset(&mTrackFragmentHeaderInfo, 0, sizeof(mTrackFragmentHeaderInfo));
 
diff --git a/media/libstagefright/MPEG4Writer.cpp b/media/libstagefright/MPEG4Writer.cpp
index 47f114a..1f43117 100644
--- a/media/libstagefright/MPEG4Writer.cpp
+++ b/media/libstagefright/MPEG4Writer.cpp
@@ -38,10 +38,11 @@
 #include <media/stagefright/MediaSource.h>
 #include <media/stagefright/Utils.h>
 #include <media/mediarecorder.h>
+#include <stagefright/AVExtensions.h>
 #include <cutils/properties.h>
 
 #include "include/ESDS.h"
-
+#include <stagefright/AVExtensions.h>
 
 #ifndef __predict_false
 #define __predict_false(exp) __builtin_expect((exp) != 0, 0)
@@ -91,6 +92,7 @@
     bool isAvc() const { return mIsAvc; }
     bool isAudio() const { return mIsAudio; }
     bool isMPEG4() const { return mIsMPEG4; }
+    bool isHEVC() const { return mIsHEVC; }
     void addChunkOffset(off64_t offset);
     int32_t getTrackId() const { return mTrackId; }
     status_t dump(int fd, const Vector<String16>& args) const;
@@ -236,6 +238,7 @@
     bool mIsAvc;
     bool mIsAudio;
     bool mIsMPEG4;
+    bool mIsHEVC;
     int32_t mTrackId;
     int64_t mTrackDurationUs;
     int64_t mMaxChunkDurationUs;
@@ -385,7 +388,9 @@
       mLongitudex10000(0),
       mAreGeoTagsAvailable(false),
       mStartTimeOffsetMs(-1),
-      mMetaKeys(new AMessage()) {
+      mMetaKeys(new AMessage()),
+      mIsVideoHEVC(false),
+      mIsAudioAMR(false) {
     addDeviceMeta();
 
     // Verify mFd is seekable
@@ -463,6 +468,8 @@
             return "s263";
         } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_AVC, mime)) {
             return "avc1";
+        } else {
+            return AVUtils::get()->HEVCMuxerUtils().getFourCCForMime(mime);
         }
     } else {
         ALOGE("Track (%s) other than video or audio is not supported", mime);
@@ -488,10 +495,23 @@
     const char *mime;
     source->getFormat()->findCString(kKeyMIMEType, &mime);
     bool isAudio = !strncasecmp(mime, "audio/", 6);
+    bool isVideo = !strncasecmp(mime, "video/", 6);
     if (Track::getFourCCForMime(mime) == NULL) {
         ALOGE("Unsupported mime '%s'", mime);
         return ERROR_UNSUPPORTED;
     }
+    mIsAudioAMR = isAudio && (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_NB, mime) ||
+                              !strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_WB, mime));
+
+
+    if (isVideo) {
+         mIsVideoHEVC = AVUtils::get()->HEVCMuxerUtils().isVideoHEVC(mime);
+    }
+
+    if (isAudio && !AVUtils::get()->isAudioMuxFormatSupported(mime)) {
+        ALOGE("Muxing is not supported for %s", mime);
+        return ERROR_UNSUPPORTED;
+    }
 
     // At this point, we know the track to be added is either
     // video or audio. Thus, we only need to check whether it
@@ -580,7 +600,7 @@
 
     // If the estimation is wrong, we will pay the price of wasting
     // some reserved space. This should not happen so often statistically.
-    static const int32_t factor = mUse32BitOffset? 1: 2;
+    int32_t factor = mUse32BitOffset? 1: 2;
     static const int64_t MIN_MOOV_BOX_SIZE = 3 * 1024;  // 3 KB
     static const int64_t MAX_MOOV_BOX_SIZE = (180 * 3000000 * 6LL / 8000);
     int64_t size = MIN_MOOV_BOX_SIZE;
@@ -677,8 +697,6 @@
         mIsRealTimeRecording = isRealTimeRecording;
     }
 
-    mStartTimestampUs = -1;
-
     if (mStarted) {
         if (mPaused) {
             mPaused = false;
@@ -687,6 +705,8 @@
         return OK;
     }
 
+    mStartTimestampUs = -1;
+
     if (!param ||
         !param->findInt32(kKeyTimeScale, &mTimeScale)) {
         mTimeScale = 1000;
@@ -1047,8 +1067,10 @@
     beginBox("ftyp");
 
     int32_t fileType;
-    if (param && param->findInt32(kKeyFileType, &fileType) &&
-        fileType != OUTPUT_FORMAT_MPEG_4) {
+    if (mIsVideoHEVC) {
+        AVUtils::get()->HEVCMuxerUtils().writeHEVCFtypBox(this);
+    } else if (mIsAudioAMR || (param && param->findInt32(kKeyFileType, &fileType) &&
+        fileType != OUTPUT_FORMAT_MPEG_4)) {
         writeFourcc("3gp4");
         writeInt32(0);
         writeFourcc("isom");
@@ -1464,6 +1486,12 @@
     mIsAudio = !strncasecmp(mime, "audio/", 6);
     mIsMPEG4 = !strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_MPEG4) ||
                !strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC);
+    mIsHEVC = AVUtils::get()->HEVCMuxerUtils().isVideoHEVC(mime);
+
+    if (mIsHEVC) {
+        AVUtils::get()->HEVCMuxerUtils().getHEVCCodecSpecificDataFromInputFormatIfPossible(
+                mMeta, &mCodecSpecificData, &mCodecSpecificDataSize, &mGotAllCodecSpecificData);
+    }
 
     setTimeScale();
 }
@@ -1562,6 +1590,7 @@
         size_t size;
         if (mMeta->findData(kKeyAVCC, &type, &data, &size)) {
             mCodecSpecificData = malloc(size);
+            CHECK(mCodecSpecificData != NULL);
             mCodecSpecificDataSize = size;
             memcpy(mCodecSpecificData, data, size);
             mGotAllCodecSpecificData = true;
@@ -1575,6 +1604,7 @@
             ESDS esds(data, size);
             if (esds.getCodecSpecificInfo(&data, &size) == OK) {
                 mCodecSpecificData = malloc(size);
+                CHECK(mCodecSpecificData != NULL);
                 mCodecSpecificDataSize = size;
                 memcpy(mCodecSpecificData, data, size);
                 mGotAllCodecSpecificData = true;
@@ -1657,7 +1687,7 @@
     while (!chunk->mSamples.empty()) {
         List<MediaBuffer *>::iterator it = chunk->mSamples.begin();
 
-        off64_t offset = chunk->mTrack->isAvc()
+        off64_t offset = (chunk->mTrack->isAvc() || chunk->mTrack->isHEVC())
                                 ? addLengthPrefixedSample_l(*it)
                                 : addSample_l(*it);
 
@@ -1881,6 +1911,10 @@
     status_t err = static_cast<status_t>(reinterpret_cast<uintptr_t>(dummy));
 
     ALOGD("%s track stopped", mIsAudio? "Audio": "Video");
+    if (mOwner->exceedsFileSizeLimit() && mStszTableEntries->count() == 0) {
+        ALOGE(" Filesize limit exceeded and zero samples written ");
+        return ERROR_END_OF_STREAM;
+    }
     return err;
 }
 
@@ -1971,6 +2005,7 @@
 
     mCodecSpecificDataSize = size;
     mCodecSpecificData = malloc(size);
+    CHECK(mCodecSpecificData != NULL);
     memcpy(mCodecSpecificData, data, size);
     return OK;
 }
@@ -2093,6 +2128,7 @@
     // ISO 14496-15: AVC file format
     mCodecSpecificDataSize += 7;  // 7 more bytes in the header
     mCodecSpecificData = malloc(mCodecSpecificDataSize);
+    CHECK(mCodecSpecificData != NULL);
     uint8_t *header = (uint8_t *)mCodecSpecificData;
     header[0] = 1;                     // version
     header[1] = mProfileIdc;           // profile indication
@@ -2195,7 +2231,9 @@
     MediaBuffer *buffer;
     const char *trackName = mIsAudio ? "Audio" : "Video";
     while (!mDone && (err = mSource->read(&buffer)) == OK) {
-        if (buffer->range_length() == 0) {
+        if (buffer == NULL) {
+            continue;
+        } else if (buffer->range_length() == 0) {
             buffer->release();
             buffer = NULL;
             ++nZeroLengthFrames;
@@ -2227,10 +2265,18 @@
             } else if (mIsMPEG4) {
                 mCodecSpecificDataSize = buffer->range_length();
                 mCodecSpecificData = malloc(mCodecSpecificDataSize);
+                CHECK(mCodecSpecificData != NULL);
                 memcpy(mCodecSpecificData,
                         (const uint8_t *)buffer->data()
                             + buffer->range_offset(),
                        buffer->range_length());
+            } else if (mIsHEVC) {
+                status_t err = AVUtils::get()->HEVCMuxerUtils().makeHEVCCodecSpecificData(
+                        (const uint8_t *)buffer->data() + buffer->range_offset(),
+                        buffer->range_length(), &mCodecSpecificData, &mCodecSpecificDataSize);
+                if ((status_t)OK != err) {
+                    return err;
+                }
             }
 
             buffer->release();
@@ -2240,20 +2286,28 @@
             continue;
         }
 
-        // Make a deep copy of the MediaBuffer and Metadata and release
-        // the original as soon as we can
-        MediaBuffer *copy = new MediaBuffer(buffer->range_length());
-        memcpy(copy->data(), (uint8_t *)buffer->data() + buffer->range_offset(),
-                buffer->range_length());
-        copy->set_range(0, buffer->range_length());
-        meta_data = new MetaData(*buffer->meta_data().get());
-        buffer->release();
-        buffer = NULL;
+        MediaBuffer *copy = NULL;
+        // Check if the upstream source hints it is OK to hold on to the
+        // buffer without releasing immediately and avoid cloning the buffer
+        if (AVUtils::get()->canDeferRelease(buffer->meta_data())) {
+            copy = buffer;
+            meta_data = new MetaData(*buffer->meta_data().get());
+        } else {
+            // Make a deep copy of the MediaBuffer and Metadata and release
+            // the original as soon as we can
+            copy = new MediaBuffer(buffer->range_length());
+            memcpy(copy->data(), (uint8_t *)buffer->data() + buffer->range_offset(),
+                    buffer->range_length());
+            copy->set_range(0, buffer->range_length());
+            meta_data = new MetaData(*buffer->meta_data().get());
+            buffer->release();
+            buffer = NULL;
+        }
 
-        if (mIsAvc) StripStartcode(copy);
+        if (mIsAvc || mIsHEVC) StripStartcode(copy);
 
         size_t sampleSize = copy->range_length();
-        if (mIsAvc) {
+        if (mIsAvc || mIsHEVC) {
             if (mOwner->useNalLengthFour()) {
                 sampleSize += 4;
             } else {
@@ -2287,6 +2341,7 @@
             previousPausedDurationUs = mStartTimestampUs;
         }
 
+#if 0
         if (mResumed) {
             int64_t durExcludingEarlierPausesUs = timestampUs - previousPausedDurationUs;
             if (WARN_UNLESS(durExcludingEarlierPausesUs >= 0ll, "for %s track", trackName)) {
@@ -2303,6 +2358,7 @@
             previousPausedDurationUs += pausedDurationUs - lastDurationUs;
             mResumed = false;
         }
+#endif
 
         timestampUs -= previousPausedDurationUs;
         if (WARN_UNLESS(timestampUs >= 0ll, "for %s track", trackName)) {
@@ -2320,8 +2376,8 @@
             CHECK(meta_data->findInt64(kKeyDecodingTime, &decodingTimeUs));
             decodingTimeUs -= previousPausedDurationUs;
             cttsOffsetTimeUs =
-                    timestampUs + kMaxCttsOffsetTimeUs - decodingTimeUs;
-            if (WARN_UNLESS(cttsOffsetTimeUs >= 0ll, "for %s track", trackName)) {
+                    timestampUs - decodingTimeUs;
+            if (WARN_UNLESS(kMaxCttsOffsetTimeUs >= decodingTimeUs - timestampUs, "for %s track", trackName)) {
                 copy->release();
                 return ERROR_MALFORMED;
             }
@@ -2347,7 +2403,11 @@
                 cttsSampleCount = 0;      // No sample in ctts box is pending
             } else {
                 if (currCttsOffsetTimeTicks != lastCttsOffsetTimeTicks) {
-                    addOneCttsTableEntry(cttsSampleCount, lastCttsOffsetTimeTicks);
+                    // cttsSampleCount is 0 after writing the initial ctts entry
+                    // Avoid writing entry with 0 sample count
+                    if (cttsSampleCount != 0) {
+                        addOneCttsTableEntry(cttsSampleCount, lastCttsOffsetTimeTicks);
+                    }
                     lastCttsOffsetTimeTicks = currCttsOffsetTimeTicks;
                     cttsSampleCount = 1;  // One sample in ctts box is pending
                 } else {
@@ -2453,7 +2513,7 @@
             trackProgressStatus(timestampUs);
         }
         if (!hasMultipleTracks) {
-            off64_t offset = mIsAvc? mOwner->addLengthPrefixedSample_l(copy)
+            off64_t offset = (mIsAvc || mIsHEVC)? mOwner->addLengthPrefixedSample_l(copy)
                                  : mOwner->addSample_l(copy);
 
             uint32_t count = (mOwner->use32BitFileOffset()
@@ -2546,8 +2606,13 @@
     if (mIsAudio) {
         ALOGI("Audio track drift time: %" PRId64 " us", mOwner->getDriftTimeUs());
     }
-
-    if (err == ERROR_END_OF_STREAM) {
+    // if err is ERROR_IO (ex: during SSR), return OK to save the
+    // recorded file successfully. Session tear down will happen as part of
+    // client callback
+    if (mIsAudio && (err == ERROR_IO)) {
+        return OK;
+    }
+    else if (err == ERROR_END_OF_STREAM) {
         return OK;
     }
     return err;
@@ -2705,7 +2770,8 @@
     CHECK(mMeta->findCString(kKeyMIMEType, &mime));
     if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AAC, mime) ||
         !strcasecmp(MEDIA_MIMETYPE_VIDEO_MPEG4, mime) ||
-        !strcasecmp(MEDIA_MIMETYPE_VIDEO_AVC, mime)) {
+        !strcasecmp(MEDIA_MIMETYPE_VIDEO_AVC, mime) ||
+        mIsHEVC) {
         if (!mCodecSpecificData ||
             mCodecSpecificDataSize <= 0) {
             ALOGE("Missing codec specific data");
@@ -2726,6 +2792,11 @@
     ALOGV("%s track time scale: %d",
         mIsAudio? "Audio": "Video", mTimeScale);
 
+    if (mMdatSizeBytes == 0) {
+        ALOGW("Track data is not available.");
+        return;
+    }
+
     uint32_t now = getMpeg4Time();
     mOwner->beginBox("trak");
         writeTkhdBox(now);
@@ -2803,17 +2874,22 @@
     mOwner->writeInt16(0x18);        // depth
     mOwner->writeInt16(-1);          // predefined
 
-    CHECK_LT(23 + mCodecSpecificDataSize, 128);
-
     if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_MPEG4, mime)) {
         writeMp4vEsdsBox();
     } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_H263, mime)) {
         writeD263Box();
     } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_AVC, mime)) {
         writeAvccBox();
+    } else if (mIsHEVC) {
+        AVUtils::get()->HEVCMuxerUtils().writeHvccBox(mOwner, mCodecSpecificData,
+                                               mCodecSpecificDataSize,
+                                               mOwner->useNalLengthFour());
     }
 
-    writePaspBox();
+    if (!mIsHEVC) {
+        writePaspBox();
+    }
+
     mOwner->endBox();  // mp4v, s263 or avc1
 }
 
@@ -2898,6 +2974,9 @@
     CHECK_GT(mCodecSpecificDataSize, 0);
     mOwner->beginBox("esds");
 
+    // Make sure all sizes encode to a single byte.
+    CHECK_LT(mCodecSpecificDataSize + 23, 128);
+
     mOwner->writeInt32(0);    // version=0, flags=0
 
     mOwner->writeInt8(0x03);  // ES_DescrTag
@@ -3086,7 +3165,7 @@
 int32_t MPEG4Writer::Track::getStartTimeOffsetScaledTime() const {
     int64_t trackStartTimeOffsetUs = 0;
     int64_t moovStartTimeUs = mOwner->getStartTimestampUs();
-    if (mStartTimestampUs != moovStartTimeUs) {
+    if (mStartTimestampUs != moovStartTimeUs && mStszTableEntries->count() != 0) {
         CHECK_GT(mStartTimestampUs, moovStartTimeUs);
         trackStartTimeOffsetUs = mStartTimestampUs - moovStartTimeUs;
     }
diff --git a/media/libstagefright/MediaBuffer.cpp b/media/libstagefright/MediaBuffer.cpp
index 1f80a47..525a156 100644
--- a/media/libstagefright/MediaBuffer.cpp
+++ b/media/libstagefright/MediaBuffer.cpp
@@ -54,6 +54,7 @@
       mOwnsData(true),
       mMetaData(new MetaData),
       mOriginal(NULL) {
+    CHECK(mData != NULL);
 }
 
 MediaBuffer::MediaBuffer(const sp<GraphicBuffer>& graphicBuffer)
diff --git a/media/libstagefright/MediaCodec.cpp b/media/libstagefright/MediaCodec.cpp
index 7019537..0780a3c 100644
--- a/media/libstagefright/MediaCodec.cpp
+++ b/media/libstagefright/MediaCodec.cpp
@@ -51,6 +51,7 @@
 #include <private/android_filesystem_config.h>
 #include <utils/Log.h>
 #include <utils/Singleton.h>
+#include <stagefright/AVExtensions.h>
 
 namespace android {
 
@@ -306,7 +307,7 @@
     // queue.
 
     if (nameIsType || !strncasecmp(name.c_str(), "omx.", 4)) {
-        mCodec = new ACodec;
+        mCodec = AVFactory::get()->createACodec();
     } else if (!nameIsType
             && !strncasecmp(name.c_str(), "android.filter.", 15)) {
         mCodec = new MediaFilter;
@@ -871,6 +872,8 @@
             }
             *format = info.mFormat;
         }
+    } else {
+        return BAD_INDEX;
     }
     return OK;
 }
@@ -984,6 +987,12 @@
         if (omxFlags & OMX_BUFFERFLAG_EOS) {
             flags |= BUFFER_FLAG_EOS;
         }
+        if (omxFlags & OMX_BUFFERFLAG_EXTRADATA) {
+            flags |= BUFFER_FLAG_EXTRADATA;
+        }
+        if (omxFlags & OMX_BUFFERFLAG_DATACORRUPT) {
+            flags |= BUFFER_FLAG_DATACORRUPT;
+        }
 
         response->setInt32("flags", flags);
         response->postReply(replyID);
@@ -1177,6 +1186,7 @@
                     // reset input surface flag
                     mHaveInputSurface = false;
 
+                    CHECK(msg->findString("componentName", &mComponentName));
                     CHECK(msg->findMessage("input-format", &mInputFormat));
                     CHECK(msg->findMessage("output-format", &mOutputFormat));
 
@@ -2269,6 +2279,7 @@
 
     uint32_t bufferID;
     CHECK(msg->findInt32("buffer-id", (int32_t*)&bufferID));
+    Mutex::Autolock al(mBufferLock);
 
     Vector<BufferInfo> *buffers = &mPortBuffers[portIndex];
 
@@ -2628,6 +2639,9 @@
         if (omxFlags & OMX_BUFFERFLAG_EOS) {
             flags |= BUFFER_FLAG_EOS;
         }
+        if (omxFlags & OMX_BUFFERFLAG_DATACORRUPT) {
+            flags |= BUFFER_FLAG_DATACORRUPT;
+        }
 
         msg->setInt32("flags", flags);
 
diff --git a/media/libstagefright/MediaCodecList.cpp b/media/libstagefright/MediaCodecList.cpp
index 5edc04c..83bf58a 100644
--- a/media/libstagefright/MediaCodecList.cpp
+++ b/media/libstagefright/MediaCodecList.cpp
@@ -40,6 +40,7 @@
 
 #include <cutils/properties.h>
 #include <libexpat/expat.h>
+#include <stagefright/AVExtensions.h>
 
 namespace android {
 
@@ -174,8 +175,9 @@
     : mInitCheck(NO_INIT),
       mUpdate(false),
       mGlobalSettings(new AMessage()) {
-    parseTopLevelXMLFile("/etc/media_codecs.xml");
-    parseTopLevelXMLFile("/etc/media_codecs_performance.xml", true/* ignore_errors */);
+    parseTopLevelXMLFile(AVUtils::get()->getCustomCodecsLocation());
+    parseTopLevelXMLFile(AVUtils::get()->getCustomCodecsPerformanceLocation(),
+                            true/* ignore_errors */);
     parseTopLevelXMLFile(kProfilingResults, true/* ignore_errors */);
 }
 
@@ -939,7 +941,13 @@
     // complexity: range + default
     bool found;
 
-    if (name == "aspect-ratio" || name == "bitrate" || name == "block-count"
+    // VT specific limits
+    if (name.find("vt-") == 0) {
+        AString value;
+        if (msg->findString("value", &value) && value.size()) {
+            mCurrentInfo->addDetail(name, value);
+        }
+    } else if (name == "aspect-ratio" || name == "bitrate" || name == "block-count"
             || name == "blocks-per-second" || name == "complexity"
             || name == "frame-rate" || name == "quality" || name == "size"
             || name == "measured-blocks-per-second" || name.startsWith("measured-frame-rate-")) {
diff --git a/media/libstagefright/MediaCodecSource.cpp b/media/libstagefright/MediaCodecSource.cpp
index 7f9f824..925be14 100644
--- a/media/libstagefright/MediaCodecSource.cpp
+++ b/media/libstagefright/MediaCodecSource.cpp
@@ -36,6 +36,8 @@
 #include <media/stagefright/MetaData.h>
 #include <media/stagefright/PersistentSurface.h>
 #include <media/stagefright/Utils.h>
+#include <OMX_Core.h>
+#include <stagefright/AVExtensions.h>
 
 namespace android {
 
@@ -399,10 +401,14 @@
     }
 
     AString outputMIME;
+    AString role;
     CHECK(mOutputFormat->findString("mime", &outputMIME));
-
-    mEncoder = MediaCodec::CreateByType(
+    if (AVUtils::get()->useQCHWEncoder(mOutputFormat, role)) {
+        mEncoder = MediaCodec::CreateByComponentName(mCodecLooper, role.c_str());
+    } else {
+        mEncoder = MediaCodec::CreateByType(
             mCodecLooper, outputMIME.c_str(), true /* encoder */);
+    }
 
     if (mEncoder == NULL) {
         return NO_INIT;
@@ -514,6 +520,9 @@
             mOutputBufferQueue.clear();
             mEncoderReachedEOS = true;
             mErrorCode = err;
+            if (err == OMX_ErrorHardware) {
+                mErrorCode = ERROR_IO;
+            }
             mOutputBufferCond.signal();
         }
 
@@ -572,6 +581,9 @@
             // push decoding time for video, or drift time for audio
             if (mIsVideo) {
                 mDecodingTimeQueue.push_back(timeUs);
+                if (mFlags & FLAG_USE_METADATA_INPUT) {
+                    AVUtils::get()->addDecodingTimesFromBatch(mbuf, mDecodingTimeQueue);
+                }
             } else {
 #if DEBUG_DRIFT_TIME
                 if (mFirstSampleTimeUs < 0ll) {
@@ -591,7 +603,7 @@
             status_t err = mEncoder->getInputBuffer(bufferIndex, &inbuf);
             if (err != OK || inbuf == NULL) {
                 mbuf->release();
-                signalEOS();
+                signalEOS(err);
                 break;
             }
 
@@ -633,6 +645,9 @@
             resume();
         } else {
             CHECK(mPuller != NULL);
+            if (mIsVideo) {
+                mEncoder->requestIDRFrame();
+            }
             mPuller->resume();
         }
         return OK;
@@ -738,12 +753,14 @@
             sp<ABuffer> outbuf;
             status_t err = mEncoder->getOutputBuffer(index, &outbuf);
             if (err != OK || outbuf == NULL) {
-                signalEOS();
+                signalEOS(err);
                 break;
             }
 
             MediaBuffer *mbuf = new MediaBuffer(outbuf->size());
             memcpy(mbuf->data(), outbuf->data(), outbuf->size());
+            sp<MetaData> meta = mbuf->meta_data();
+            AVUtils::get()->setDeferRelease(meta);
 
             if (!(flags & MediaCodec::BUFFER_FLAG_CODECCONFIG)) {
                 if (mIsVideo) {
@@ -799,7 +816,7 @@
             CHECK(msg->findInt32("err", &err));
             ALOGE("Encoder (%s) reported error : 0x%x",
                     mIsVideo ? "video" : "audio", err);
-            signalEOS();
+            signalEOS(err);
        }
        break;
     }
@@ -852,7 +869,7 @@
     }
     case kWhatPause:
     {
-        if (mFlags && FLAG_USE_SURFACE_INPUT) {
+        if (mFlags & FLAG_USE_SURFACE_INPUT) {
             suspend();
         } else {
             CHECK(mPuller != NULL);
diff --git a/media/libstagefright/MediaDefs.cpp b/media/libstagefright/MediaDefs.cpp
index 2a50692..4077bd3 100644
--- a/media/libstagefright/MediaDefs.cpp
+++ b/media/libstagefright/MediaDefs.cpp
@@ -12,6 +12,25 @@
  * 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.
+ *
+ * This file was modified by Dolby Laboratories, Inc. The portions of the
+ * code that are surrounded by "DOLBY..." are copyrighted and
+ * licensed separately, as follows:
+ *
+ *  (C) 2011-2015 Dolby Laboratories, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
  */
 
 #include <media/stagefright/MediaDefs.h>
@@ -47,6 +66,9 @@
 const char *MEDIA_MIMETYPE_AUDIO_MSGSM = "audio/gsm";
 const char *MEDIA_MIMETYPE_AUDIO_AC3 = "audio/ac3";
 const char *MEDIA_MIMETYPE_AUDIO_EAC3 = "audio/eac3";
+#ifdef DOLBY_ENABLE
+const char *MEDIA_MIMETYPE_AUDIO_EAC3_JOC = "audio/eac3-joc";
+#endif // DOLBY_END
 
 const char *MEDIA_MIMETYPE_CONTAINER_MPEG4 = "video/mp4";
 const char *MEDIA_MIMETYPE_CONTAINER_WAV = "audio/x-wav";
diff --git a/media/libstagefright/MediaExtractor.cpp b/media/libstagefright/MediaExtractor.cpp
index e21fe6e..bfb2a16 100644
--- a/media/libstagefright/MediaExtractor.cpp
+++ b/media/libstagefright/MediaExtractor.cpp
@@ -40,6 +40,8 @@
 #include <media/stagefright/MetaData.h>
 #include <utils/String8.h>
 
+#include <stagefright/AVExtensions.h>
+
 namespace android {
 
 sp<MetaData> MediaExtractor::getMetaData() {
@@ -52,7 +54,8 @@
 
 // static
 sp<MediaExtractor> MediaExtractor::Create(
-        const sp<DataSource> &source, const char *mime) {
+        const sp<DataSource> &source, const char *mime,
+        const uint32_t flags) {
     sp<AMessage> meta;
 
     String8 tmp;
@@ -91,8 +94,9 @@
         }
     }
 
-    MediaExtractor *ret = NULL;
-    if (!strcasecmp(mime, MEDIA_MIMETYPE_CONTAINER_MPEG4)
+    sp<MediaExtractor> ret = NULL;
+    if ((ret = AVFactory::get()->createExtendedExtractor(source, mime, meta, flags)) != NULL) {
+    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_CONTAINER_MPEG4)
             || !strcasecmp(mime, "audio/mp4")) {
         ret = new MPEG4Extractor(source);
     } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_MPEG)) {
@@ -121,6 +125,7 @@
         ret = new MidiExtractor(source);
     }
 
+    ret = AVFactory::get()->updateExtractor(ret, source, mime, meta, flags);
     if (ret != NULL) {
        if (isDrm) {
            ret->setDrmFlag(true);
diff --git a/media/libstagefright/OMXCodec.cpp b/media/libstagefright/OMXCodec.cpp
index b1dde80..4762217 100644
--- a/media/libstagefright/OMXCodec.cpp
+++ b/media/libstagefright/OMXCodec.cpp
@@ -12,6 +12,25 @@
  * 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.
+ *
+ * This file was modified by Dolby Laboratories, Inc. The portions of the
+ * code that are surrounded by "DOLBY..." are copyrighted and
+ * licensed separately, as follows:
+ *
+ *  (C) 2011-2015 Dolby Laboratories, Inc.
+ *
+ * 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 <inttypes.h>
@@ -55,6 +74,9 @@
 #include <OMX_AsString.h>
 
 #include "include/avc_utils.h"
+#ifdef DOLBY_ENABLE
+#include "DolbyOMXCodecExtImpl.h"
+#endif // DOLBY_END
 
 namespace android {
 
@@ -150,6 +172,11 @@
 }
 
 static bool IsSoftwareCodec(const char *componentName) {
+#ifdef DOLBY_ENABLE
+    if (!strncmp("OMX.dolby.", componentName, 10)) {
+        return true;
+    }
+#endif // DOLBY_END
     if (!strncmp("OMX.google.", componentName, 11)) {
         return true;
     }
@@ -264,6 +291,9 @@
     if (info->hasQuirk("output-buffers-are-unreadable")) {
         quirks |= kOutputBuffersAreUnreadable;
     }
+#ifdef DOLBY_ENABLE
+    quirks |= getDolbyComponentQuirks(info);
+#endif // DOLBY_END
 
     return quirks;
 }
@@ -1510,6 +1540,12 @@
             "video_decoder.mpeg2", "video_encoder.mpeg2" },
         { MEDIA_MIMETYPE_AUDIO_AC3,
             "audio_decoder.ac3", "audio_encoder.ac3" },
+#ifdef DOLBY_ENABLE
+        { MEDIA_MIMETYPE_AUDIO_EAC3,
+            "audio_decoder.eac3", NULL },
+        { MEDIA_MIMETYPE_AUDIO_EAC3_JOC,
+            "audio_decoder.eac3_joc", NULL },
+#endif // DOLBY_END
     };
 
     static const size_t kNumMimeToRole =
@@ -4114,6 +4150,9 @@
                             ? numChannels : params.nChannels);
 
                 mOutputFormat->setInt32(kKeySampleRate, params.nSamplingRate);
+#ifdef DOLBY_ENABLE
+                setDolbyProcessedAudio();
+#endif // DOLBY_END
             } else if (audio_def->eEncoding == OMX_AUDIO_CodingAMR) {
                 OMX_AUDIO_PARAM_AMRTYPE amr;
                 InitOMXParams(&amr);
diff --git a/media/libstagefright/StagefrightMediaScanner.cpp b/media/libstagefright/StagefrightMediaScanner.cpp
index db33e83..a757181 100644
--- a/media/libstagefright/StagefrightMediaScanner.cpp
+++ b/media/libstagefright/StagefrightMediaScanner.cpp
@@ -28,6 +28,8 @@
 #include <media/mediametadataretriever.h>
 #include <private/media/VideoFrame.h>
 
+#include <stagefright/AVExtensions.h>
+
 namespace android {
 
 StagefrightMediaScanner::StagefrightMediaScanner() {}
@@ -75,7 +77,8 @@
         return MEDIA_SCAN_RESULT_SKIPPED;
     }
 
-    if (!FileHasAcceptableExtension(extension)) {
+    if (!FileHasAcceptableExtension(extension)
+        && !AVUtils::get()->isEnhancedExtension(extension)) {
         return MEDIA_SCAN_RESULT_SKIPPED;
     }
 
diff --git a/media/libstagefright/StagefrightMetadataRetriever.cpp b/media/libstagefright/StagefrightMetadataRetriever.cpp
index e37e909..5a8f6a5 100644
--- a/media/libstagefright/StagefrightMetadataRetriever.cpp
+++ b/media/libstagefright/StagefrightMetadataRetriever.cpp
@@ -23,6 +23,7 @@
 #include <gui/Surface.h>
 
 #include "include/StagefrightMetadataRetriever.h"
+#include "include/HTTPBase.h"
 
 #include <media/ICrypto.h>
 #include <media/IMediaHTTPService.h>
@@ -44,6 +45,8 @@
 
 #include <CharacterEncodingDetector.h>
 
+#include <stagefright/AVExtensions.h>
+
 namespace android {
 
 static const int64_t kBufferTimeOutUs = 30000ll; // 30 msec
@@ -62,6 +65,12 @@
     ALOGV("~StagefrightMetadataRetriever()");
     clearMetadata();
     mClient.disconnect();
+
+    if (mSource != NULL &&
+        (mSource->flags() & DataSource::kIsHTTPBasedSource)) {
+        mExtractor.clear();
+        static_cast<HTTPBase *>(mSource.get())->disconnect();
+    }
 }
 
 status_t StagefrightMetadataRetriever::setDataSource(
@@ -97,6 +106,7 @@
     fd = dup(fd);
 
     ALOGV("setDataSource(%d, %" PRId64 ", %" PRId64 ")", fd, offset, length);
+    AVUtils::get()->printFileName(fd);
 
     clearMetadata();
     mSource = new FileSource(fd, offset, length);
@@ -154,6 +164,8 @@
     // TODO: Use Flexible color instead
     videoFormat->setInt32("color-format", OMX_COLOR_FormatYUV420Planar);
 
+    videoFormat->setInt32("thumbnail-mode", 1);
+
     status_t err;
     sp<ALooper> looper = new ALooper;
     looper->start();
@@ -214,6 +226,7 @@
     err = decoder->getInputBuffers(&inputBuffers);
     if (err != OK) {
         ALOGW("failed to get input buffers: %d (%s)", err, asString(err));
+        source->stop();
         decoder->release();
         return NULL;
     }
@@ -222,6 +235,7 @@
     err = decoder->getOutputBuffers(&outputBuffers);
     if (err != OK) {
         ALOGW("failed to get output buffers: %d (%s)", err, asString(err));
+        source->stop();
         decoder->release();
         return NULL;
     }
@@ -346,9 +360,11 @@
         }
     }
 
-    int32_t width, height;
+    int32_t width, height, stride, slice_height;
     CHECK(outputFormat->findInt32("width", &width));
     CHECK(outputFormat->findInt32("height", &height));
+    CHECK(outputFormat->findInt32("stride", &stride));
+    CHECK(outputFormat->findInt32("slice-height", &slice_height));
 
     int32_t crop_left, crop_top, crop_right, crop_bottom;
     if (!outputFormat->findRect("crop", &crop_left, &crop_top, &crop_right, &crop_bottom)) {
@@ -386,7 +402,7 @@
     if (converter.isValid()) {
         err = converter.convert(
                 (const uint8_t *)videoFrameBuffer->data(),
-                width, height,
+                stride, slice_height,
                 crop_left, crop_top, crop_right, crop_bottom,
                 frame->mData,
                 frame->mWidth,
@@ -481,7 +497,7 @@
             mime,
             false, /* encoder */
             NULL, /* matchComponentName */
-            OMXCodec::kPreferSoftwareCodecs,
+            0 /* OMXCodec::kPreferSoftwareCodecs */,
             &matchingCodecs);
 
     for (size_t i = 0; i < matchingCodecs.size(); ++i) {
@@ -661,9 +677,12 @@
                 }
             } else if (!strcasecmp(mime, MEDIA_MIMETYPE_TEXT_3GPP)) {
                 const char *lang;
-                trackMeta->findCString(kKeyMediaLanguage, &lang);
-                timedTextLang.append(String8(lang));
-                timedTextLang.append(String8(":"));
+                if (trackMeta->findCString(kKeyMediaLanguage, &lang)) {
+                    timedTextLang.append(String8(lang));
+                    timedTextLang.append(String8(":"));
+                } else {
+                    ALOGE("No language found for timed text");
+                }
             }
         }
     }
diff --git a/media/libstagefright/SurfaceMediaSource.cpp b/media/libstagefright/SurfaceMediaSource.cpp
index e8abf48..147eb45 100644
--- a/media/libstagefright/SurfaceMediaSource.cpp
+++ b/media/libstagefright/SurfaceMediaSource.cpp
@@ -35,6 +35,9 @@
 #include <utils/String8.h>
 
 #include <private/gui/ComposerService.h>
+#if QTI_BSP
+#include <gralloc_priv.h>
+#endif
 
 namespace android {
 
@@ -59,8 +62,12 @@
 
     BufferQueue::createBufferQueue(&mProducer, &mConsumer);
     mConsumer->setDefaultBufferSize(bufferWidth, bufferHeight);
-    mConsumer->setConsumerUsageBits(GRALLOC_USAGE_HW_VIDEO_ENCODER |
-            GRALLOC_USAGE_HW_TEXTURE);
+    mConsumer->setConsumerUsageBits(GRALLOC_USAGE_HW_VIDEO_ENCODER
+            | GRALLOC_USAGE_HW_TEXTURE
+#if QTI_BSP
+            | GRALLOC_USAGE_PRIVATE_WFD
+#endif
+            );
 
     sp<ISurfaceComposer> composer(ComposerService::getComposerService());
 
@@ -360,7 +367,11 @@
 
     mNumFramesEncoded++;
     // Pass the data to the MediaBuffer. Pass in only the metadata
-
+    if (mSlots[mCurrentSlot].mGraphicBuffer == NULL) {
+        ALOGV("Read: SurfaceMediaSource mGraphicBuffer is null. Returning"
+              "ERROR_END_OF_STREAM.");
+        return ERROR_END_OF_STREAM;
+    }
     passMetadataBuffer(buffer, mSlots[mCurrentSlot].mGraphicBuffer->handle);
 
     (*buffer)->setObserver(this);
diff --git a/media/libstagefright/Utils.cpp b/media/libstagefright/Utils.cpp
index 17f0201..42d87f6 100644
--- a/media/libstagefright/Utils.cpp
+++ b/media/libstagefright/Utils.cpp
@@ -12,6 +12,25 @@
  * 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.
+ *
+ * This file was modified by Dolby Laboratories, Inc. The portions of the
+ * code that are surrounded by "DOLBY..." are copyrighted and
+ * licensed separately, as follows:
+ *
+ *  (C) 2014-2015 Dolby Laboratories, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
  */
 
 //#define LOG_NDEBUG 0
@@ -35,6 +54,8 @@
 #include <media/stagefright/Utils.h>
 #include <media/AudioParameter.h>
 
+#include <stagefright/AVExtensions.h>
+
 namespace android {
 
 uint16_t U16_AT(const uint8_t *ptr) {
@@ -453,6 +474,7 @@
         msg->setBuffer("csd-2", buffer);
     }
 
+    AVUtils::get()->convertMetaDataToMessage(meta, &msg);
     *format = msg;
 
     return OK;
@@ -685,6 +707,8 @@
             // for transporting the CSD to muxers.
             reassembleESDS(csd0, esds);
             meta->setData(kKeyESDS, kKeyESDS, esds, sizeof(esds));
+        } else {
+            AVUtils::get()->HEVCMuxerUtils().reassembleHEVCCSD(mime, csd0, meta);
         }
     }
 
@@ -744,6 +768,7 @@
         param.addInt(String8(AUDIO_OFFLOAD_CODEC_PADDING_SAMPLES), paddingSamples);
     }
 
+    AVUtils::get()->sendMetaDataToHal(meta, &param);
     ALOGV("sendMetaDataToHal: bitRate %d, sampleRate %d, chanMask %d,"
           "delaySample %d, paddingSample %d", bitRate, sampleRate,
           channelMask, delaySamples, paddingSamples);
@@ -765,6 +790,11 @@
     { MEDIA_MIMETYPE_AUDIO_AAC,         AUDIO_FORMAT_AAC },
     { MEDIA_MIMETYPE_AUDIO_VORBIS,      AUDIO_FORMAT_VORBIS },
     { MEDIA_MIMETYPE_AUDIO_OPUS,        AUDIO_FORMAT_OPUS},
+#ifdef DOLBY_ENABLE
+    { MEDIA_MIMETYPE_AUDIO_AC3,         AUDIO_FORMAT_AC3},
+    { MEDIA_MIMETYPE_AUDIO_EAC3,        AUDIO_FORMAT_E_AC3},
+    { MEDIA_MIMETYPE_AUDIO_EAC3_JOC,    AUDIO_FORMAT_E_AC3},
+#endif // DOLBY_END
     { 0, AUDIO_FORMAT_INVALID }
 };
 
@@ -779,7 +809,7 @@
         ++p;
     }
 
-    return BAD_VALUE;
+    return AVUtils::get()->mapMimeToAudioFormat(format, mime);
 }
 
 struct aac_format_conv_t {
@@ -833,18 +863,27 @@
     } else {
         ALOGV("Mime type \"%s\" mapped to audio_format %d", mime, info.format);
     }
-
+    info.format  = AVUtils::get()->updateAudioFormat(info.format, meta);
     if (AUDIO_FORMAT_INVALID == info.format) {
         // can't offload if we don't know what the source format is
         ALOGE("mime type \"%s\" not a known audio format", mime);
         return false;
     }
 
+    if (AVUtils::get()->canOffloadAPE(meta) != true) {
+        return false;
+    }
+
     // Redefine aac format according to its profile
     // Offloading depends on audio DSP capabilities.
     int32_t aacaot = -1;
     if (meta->findInt32(kKeyAACAOT, &aacaot)) {
-        mapAACProfileToAudioFormat(info.format,(OMX_AUDIO_AACPROFILETYPE) aacaot);
+        bool isADTSSupported = false;
+        isADTSSupported = AVUtils::get()->mapAACProfileToAudioFormat(meta, info.format,
+                                  (OMX_AUDIO_AACPROFILETYPE) aacaot);
+        if (!isADTSSupported) {
+           mapAACProfileToAudioFormat(info.format,(OMX_AUDIO_AACPROFILETYPE) aacaot);
+        }
     }
 
     int32_t srate = -1;
diff --git a/media/libstagefright/VideoFrameScheduler.cpp b/media/libstagefright/VideoFrameScheduler.cpp
index 5fe9bf9..02b8783 100644
--- a/media/libstagefright/VideoFrameScheduler.cpp
+++ b/media/libstagefright/VideoFrameScheduler.cpp
@@ -257,8 +257,7 @@
             mPhase = firstTime;
         }
     }
-    ALOGV("priming[%zu] phase:%lld period:%lld",
-            numSamplesToUse, (long long)mPhase, (long long)mPeriod);
+    ALOGV("priming[%zu] phase:%lld period:%lld ", numSamplesToUse, (long long)mPhase, (long long)mPeriod);
 }
 
 nsecs_t VideoFrameScheduler::PLL::addSample(nsecs_t time) {
diff --git a/media/libstagefright/avc_utils.cpp b/media/libstagefright/avc_utils.cpp
index 8ef2dca..98b5c0e 100644
--- a/media/libstagefright/avc_utils.cpp
+++ b/media/libstagefright/avc_utils.cpp
@@ -25,6 +25,7 @@
 #include <media/stagefright/foundation/hexdump.h>
 #include <media/stagefright/MediaDefs.h>
 #include <media/stagefright/MediaErrors.h>
+#include <media/stagefright/MediaBuffer.h>
 #include <media/stagefright/MetaData.h>
 #include <utils/misc.h>
 
@@ -393,7 +394,7 @@
     meta->setInt32(kKeyWidth, width);
     meta->setInt32(kKeyHeight, height);
 
-    if (sarWidth > 1 || sarHeight > 1) {
+    if (sarWidth > 1 && sarHeight > 1) {
         // We treat 0:0 (unspecified) as 1:1.
 
         meta->setInt32(kKeySARWidth, sarWidth);
@@ -443,25 +444,34 @@
 }
 
 bool IsAVCReferenceFrame(const sp<ABuffer> &accessUnit) {
-    const uint8_t *data = accessUnit->data();
+    MediaBuffer *mediaBuffer =
+        (MediaBuffer *)(accessUnit->getMediaBufferBase());
+    const uint8_t *data =
+        (mediaBuffer != NULL) ? (uint8_t *) mediaBuffer->data() : accessUnit->data();
     size_t size = accessUnit->size();
 
     const uint8_t *nalStart;
     size_t nalSize;
+    bool bIsReferenceFrame = true;
     while (getNextNALUnit(&data, &size, &nalStart, &nalSize, true) == OK) {
         CHECK_GT(nalSize, 0u);
 
         unsigned nalType = nalStart[0] & 0x1f;
 
         if (nalType == 5) {
-            return true;
+            bIsReferenceFrame = true;
+            break;
         } else if (nalType == 1) {
             unsigned nal_ref_idc = (nalStart[0] >> 5) & 3;
-            return nal_ref_idc != 0;
+            bIsReferenceFrame = (nal_ref_idc != 0);
+            break;
         }
     }
 
-    return true;
+    if (mediaBuffer != NULL) {
+        mediaBuffer->release();
+    }
+    return bIsReferenceFrame;
 }
 
 sp<MetaData> MakeAACCodecSpecificData(
diff --git a/media/libstagefright/codecs/aacdec/SoftAAC2.cpp b/media/libstagefright/codecs/aacdec/SoftAAC2.cpp
index 965c55e..c945305 100644
--- a/media/libstagefright/codecs/aacdec/SoftAAC2.cpp
+++ b/media/libstagefright/codecs/aacdec/SoftAAC2.cpp
@@ -68,6 +68,8 @@
       mOutputBufferCount(0),
       mSignalledError(false),
       mLastInHeader(NULL),
+      mLastHeaderTimeUs(-1),
+      mNextOutBufferTimeUs(0),
       mOutputPortSettingsChange(NONE) {
     initPorts();
     CHECK_EQ(initDecoder(), (status_t)OK);
@@ -492,6 +494,27 @@
     return mOutputDelayRingBufferSize - outputDelayRingBufferSamplesAvailable();
 }
 
+void SoftAAC2::updateTimeStamp(int64_t inHeaderTimeUs) {
+    // use new input buffer timestamp as Anchor Time if its
+    //    a) first buffer or
+    //    b) first buffer post seek or
+    //    c) different from last buffer timestamp
+    //If input buffer timestamp is same as last input buffer timestamp then
+    //treat this as a erroneous timestamp and ignore new input buffer
+    //timestamp and use last output buffer timestamp as Anchor Time.
+    int64_t anchorTimeUs = 0;
+    if ((mLastHeaderTimeUs != inHeaderTimeUs)) {
+        anchorTimeUs = inHeaderTimeUs;
+        mLastHeaderTimeUs = inHeaderTimeUs;
+        //Store current buffer's timestamp so that it can used as reference
+        //in cases where first frame/buffer is skipped/dropped.
+        //e.g to compensate decoder delay
+        mNextOutBufferTimeUs = inHeaderTimeUs;
+    } else {
+        anchorTimeUs = mNextOutBufferTimeUs;
+    }
+    mBufferTimestamps.add(anchorTimeUs);
+}
 
 void SoftAAC2::onQueueFilled(OMX_U32 /* portIndex */) {
     if (mSignalledError || mOutputPortSettingsChange != NONE) {
@@ -618,7 +641,7 @@
                 // insert buffer size and time stamp
                 mBufferSizes.add(inBufferLength[0]);
                 if (mLastInHeader != inHeader) {
-                    mBufferTimestamps.add(inHeader->nTimeStamp);
+                    updateTimeStamp(inHeader->nTimeStamp);
                     mLastInHeader = inHeader;
                 } else {
                     int64_t currentTime = mBufferTimestamps.top();
@@ -630,7 +653,7 @@
                 inBuffer[0] = inHeader->pBuffer + inHeader->nOffset;
                 inBufferLength[0] = inHeader->nFilledLen;
                 mLastInHeader = inHeader;
-                mBufferTimestamps.add(inHeader->nTimeStamp);
+                updateTimeStamp(inHeader->nTimeStamp);
                 mBufferSizes.add(inHeader->nFilledLen);
             }
 
@@ -755,6 +778,14 @@
                         if (inHeader && inHeader->nFilledLen == 0) {
                             inInfo->mOwnedByUs = false;
                             mInputBufferCount++;
+
+                            //During Port reconfiguration current frames is skipped and next frame
+                            //is sent for decoding.
+                            //Update mNextOutBufferTimeUs with current frame's timestamp if port reconfiguration is
+                            //happening in last frame of current buffer otherwise LastOutBufferTimeUs
+                            //will be zero(post seek).
+                            mNextOutBufferTimeUs = mBufferTimestamps.top() + mStreamInfo->aacSamplesPerFrame *
+                                                       1000000ll / mStreamInfo->aacSampleRate;
                             inQueue.erase(inQueue.begin());
                             mLastInHeader = NULL;
                             inInfo = NULL;
@@ -875,6 +906,7 @@
                         *currentBufLeft -= decodedSize;
                         *nextTimeStamp += mStreamInfo->aacSamplesPerFrame *
                                 1000000ll / mStreamInfo->aacSampleRate;
+                        mNextOutBufferTimeUs = *nextTimeStamp;
                         ALOGV("adjusted nextTimeStamp/size to %lld/%d",
                                 (long long) *nextTimeStamp, *currentBufLeft);
                     } else {
@@ -882,6 +914,7 @@
                         if (mBufferTimestamps.size() > 0) {
                             mBufferTimestamps.removeAt(0);
                             nextTimeStamp = &mBufferTimestamps.editItemAt(0);
+                            mNextOutBufferTimeUs = *nextTimeStamp;
                             mBufferSizes.removeAt(0);
                             currentBufLeft = &mBufferSizes.editItemAt(0);
                             ALOGV("moved to next time/size: %lld/%d",
@@ -976,6 +1009,8 @@
         mDecodedSizes.clear();
         mLastInHeader = NULL;
         mEndOfInput = false;
+        mLastHeaderTimeUs = -1;
+        mNextOutBufferTimeUs = 0;
     } else {
         int avail;
         while ((avail = outputDelayRingBufferSamplesAvailable()) > 0) {
@@ -1038,6 +1073,8 @@
     mBufferSizes.clear();
     mDecodedSizes.clear();
     mLastInHeader = NULL;
+    mLastHeaderTimeUs = -1;
+    mNextOutBufferTimeUs = 0;
 
     // To make the codec behave the same before and after a reset, we need to invalidate the
     // streaminfo struct. This does that:
diff --git a/media/libstagefright/codecs/aacdec/SoftAAC2.h b/media/libstagefright/codecs/aacdec/SoftAAC2.h
index c3e4459..3fe958e 100644
--- a/media/libstagefright/codecs/aacdec/SoftAAC2.h
+++ b/media/libstagefright/codecs/aacdec/SoftAAC2.h
@@ -59,6 +59,8 @@
     size_t mOutputBufferCount;
     bool mSignalledError;
     OMX_BUFFERHEADERTYPE *mLastInHeader;
+    int64_t mLastHeaderTimeUs;
+    int64_t mNextOutBufferTimeUs;
     Vector<int32_t> mBufferSizes;
     Vector<int32_t> mDecodedSizes;
     Vector<int64_t> mBufferTimestamps;
@@ -90,6 +92,7 @@
     int32_t outputDelayRingBufferGetSamples(INT_PCM *samples, int numSamples);
     int32_t outputDelayRingBufferSamplesAvailable();
     int32_t outputDelayRingBufferSpaceLeft();
+    void updateTimeStamp(int64_t inHeaderTimesUs);
 
     DISALLOW_EVIL_CONSTRUCTORS(SoftAAC2);
 };
diff --git a/media/libstagefright/codecs/amrnb/dec/Android.mk b/media/libstagefright/codecs/amrnb/dec/Android.mk
index 76a7f40..21109d9 100644
--- a/media/libstagefright/codecs/amrnb/dec/Android.mk
+++ b/media/libstagefright/codecs/amrnb/dec/Android.mk
@@ -80,6 +80,7 @@
         libstagefright_amrnb_common
 
 LOCAL_MODULE := libstagefright_soft_amrdec
+LOCAL_CLANG := false
 LOCAL_MODULE_TAGS := optional
 
 include $(BUILD_SHARED_LIBRARY)
diff --git a/media/libstagefright/codecs/amrnb/dec/SoftAMR.cpp b/media/libstagefright/codecs/amrnb/dec/SoftAMR.cpp
index a9723ea..f8316fd 100644
--- a/media/libstagefright/codecs/amrnb/dec/SoftAMR.cpp
+++ b/media/libstagefright/codecs/amrnb/dec/SoftAMR.cpp
@@ -352,7 +352,14 @@
             }
 
             size_t frameSize = getFrameSize(mode);
-            CHECK_GE(inHeader->nFilledLen, frameSize);
+            if (inHeader->nFilledLen < frameSize) {
+                ALOGE("Filled length vs frameSize %u vs %lu. Corrupt clip?",
+                   inHeader->nFilledLen, frameSize);
+
+                notify(OMX_EventError, OMX_ErrorUndefined, 0, NULL);
+                mSignalledError = true;
+                return;
+            }
 
             int16_t *outPtr = (int16_t *)outHeader->pBuffer;
 
diff --git a/media/libstagefright/codecs/mp3dec/SoftMP3.cpp b/media/libstagefright/codecs/mp3dec/SoftMP3.cpp
index f743b1c..4c4da60 100644
--- a/media/libstagefright/codecs/mp3dec/SoftMP3.cpp
+++ b/media/libstagefright/codecs/mp3dec/SoftMP3.cpp
@@ -51,7 +51,9 @@
       mSignalledError(false),
       mSawInputEos(false),
       mSignalledOutputEos(false),
-      mOutputPortSettingsChange(NONE) {
+      mOutputPortSettingsChange(NONE),
+      mLastAnchorTimeUs(-1),
+      mNextOutBufferTimeUs(0) {
     initPorts();
     initDecoder();
 }
@@ -112,7 +114,7 @@
 void SoftMP3::initDecoder() {
     mConfig->equalizerType = flat;
     mConfig->crcEnabled = false;
-
+    mConfig->samplingRate = mSamplingRate;
     uint32_t memRequirements = pvmp3_decoderMemRequirements();
     mDecoderBuf = malloc(memRequirements);
 
@@ -212,7 +214,7 @@
 
     List<BufferInfo *> &inQueue = getPortQueue(0);
     List<BufferInfo *> &outQueue = getPortQueue(1);
-
+    int64_t tmpTime = 0;
     while ((!inQueue.empty() || (mSawInputEos && !mSignalledOutputEos)) && !outQueue.empty()) {
         BufferInfo *inInfo = NULL;
         OMX_BUFFERHEADERTYPE *inHeader = NULL;
@@ -227,7 +229,20 @@
 
         if (inHeader) {
             if (inHeader->nOffset == 0 && inHeader->nFilledLen) {
-                mAnchorTimeUs = inHeader->nTimeStamp;
+                // use new input buffer timestamp as Anchor Time if its
+                //    a) first buffer or
+                //    b) first buffer post seek or
+                //    c) different from last buffer timestamp
+                //If input buffer timestamp is same as last input buffer timestamp then
+                //treat this as a erroneous timestamp and ignore new input buffer
+                //timestamp and use last output buffer timestamp as Anchor Time.
+                if ((mLastAnchorTimeUs != inHeader->nTimeStamp)) {
+                    mAnchorTimeUs = inHeader->nTimeStamp;
+                    mLastAnchorTimeUs = inHeader->nTimeStamp;
+                } else {
+                    mAnchorTimeUs = mNextOutBufferTimeUs;
+                }
+
                 mNumFramesOutput = 0;
             }
 
@@ -259,10 +274,13 @@
             if (decoderErr != NO_ENOUGH_MAIN_DATA_ERROR
                         && decoderErr != SIDE_INFO_ERROR) {
                 ALOGE("mp3 decoder returned error %d", decoderErr);
-
-                notify(OMX_EventError, OMX_ErrorUndefined, decoderErr, NULL);
-                mSignalledError = true;
-                return;
+                if(decoderErr == SYNCH_LOST_ERROR) {
+                    mConfig->outputFrameSize = kOutputBufferSize / sizeof(int16_t);
+                } else {
+                    notify(OMX_EventError, OMX_ErrorUndefined, decoderErr, NULL);
+                    mSignalledError = true;
+                    return;
+                }
             }
 
             if (mConfig->outputFrameSize == 0) {
@@ -323,7 +341,7 @@
 
         outHeader->nTimeStamp =
             mAnchorTimeUs + (mNumFramesOutput * 1000000ll) / mSamplingRate;
-
+        tmpTime = outHeader->nTimeStamp;
         if (inHeader) {
             CHECK_GE(inHeader->nFilledLen, mConfig->inputBufferUsedLength);
 
@@ -348,6 +366,10 @@
         notifyFillBufferDone(outHeader);
         outHeader = NULL;
     }
+
+    if (tmpTime > 0) {
+        mNextOutBufferTimeUs = tmpTime;
+    }
 }
 
 void SoftMP3::onPortFlushCompleted(OMX_U32 portIndex) {
@@ -359,6 +381,8 @@
         mSignalledError = false;
         mSawInputEos = false;
         mSignalledOutputEos = false;
+        mLastAnchorTimeUs = -1;
+        mNextOutBufferTimeUs = 0;
     }
 }
 
@@ -395,6 +419,8 @@
     mSawInputEos = false;
     mSignalledOutputEos = false;
     mOutputPortSettingsChange = NONE;
+    mLastAnchorTimeUs = -1;
+    mNextOutBufferTimeUs = 0;
 }
 
 }  // namespace android
diff --git a/media/libstagefright/codecs/mp3dec/SoftMP3.h b/media/libstagefright/codecs/mp3dec/SoftMP3.h
index f9e7b53..c769795 100644
--- a/media/libstagefright/codecs/mp3dec/SoftMP3.h
+++ b/media/libstagefright/codecs/mp3dec/SoftMP3.h
@@ -70,6 +70,9 @@
         AWAITING_ENABLED
     } mOutputPortSettingsChange;
 
+    int64_t mLastAnchorTimeUs;
+    int64_t mNextOutBufferTimeUs;
+
     void initPorts();
     void initDecoder();
 
diff --git a/media/libstagefright/codecs/raw/SoftRaw.cpp b/media/libstagefright/codecs/raw/SoftRaw.cpp
index 9d514a6..b78b36f 100644
--- a/media/libstagefright/codecs/raw/SoftRaw.cpp
+++ b/media/libstagefright/codecs/raw/SoftRaw.cpp
@@ -58,7 +58,7 @@
     def.eDir = OMX_DirInput;
     def.nBufferCountMin = kNumBuffers;
     def.nBufferCountActual = def.nBufferCountMin;
-    def.nBufferSize = 32 * 1024;
+    def.nBufferSize = 192 * 1024;
     def.bEnabled = OMX_TRUE;
     def.bPopulated = OMX_FALSE;
     def.eDomain = OMX_PortDomainAudio;
@@ -76,7 +76,7 @@
     def.eDir = OMX_DirOutput;
     def.nBufferCountMin = kNumBuffers;
     def.nBufferCountActual = def.nBufferCountMin;
-    def.nBufferSize = 32 * 1024;
+    def.nBufferSize = 192 * 1024;
     def.bEnabled = OMX_TRUE;
     def.bPopulated = OMX_FALSE;
     def.eDomain = OMX_PortDomainAudio;
diff --git a/media/libstagefright/codecs/raw/SoftRaw.h b/media/libstagefright/codecs/raw/SoftRaw.h
index 015c4a3..94b0ef1 100644
--- a/media/libstagefright/codecs/raw/SoftRaw.h
+++ b/media/libstagefright/codecs/raw/SoftRaw.h
@@ -43,7 +43,7 @@
 
 private:
     enum {
-        kNumBuffers = 4
+        kNumBuffers = 8
     };
 
     bool mSignalledError;
diff --git a/media/libstagefright/codecs/vorbis/dec/SoftVorbis.cpp b/media/libstagefright/codecs/vorbis/dec/SoftVorbis.cpp
index c559682..3dc549e 100644
--- a/media/libstagefright/codecs/vorbis/dec/SoftVorbis.cpp
+++ b/media/libstagefright/codecs/vorbis/dec/SoftVorbis.cpp
@@ -419,6 +419,8 @@
 
         mNumFramesOutput = 0;
         vorbis_dsp_restart(mState);
+        mSawInputEos = false;
+        mSignalledOutputEos = false;
     }
 }
 
diff --git a/media/libstagefright/data/media_codecs_google_video.xml b/media/libstagefright/data/media_codecs_google_video.xml
index 81a6d00..ea4cd2b 100644
--- a/media/libstagefright/data/media_codecs_google_video.xml
+++ b/media/libstagefright/data/media_codecs_google_video.xml
@@ -16,7 +16,14 @@
 
 <Included>
     <Decoders>
-        <MediaCodec name="OMX.google.mpeg4.decoder" type="video/mp4v-es">
+       <MediaCodec name="OMX.google.mpeg4.decoder">
+            <Type name="video/mp4v-es" />
+            <!--
+                Use Google mpeg4 decoder for mpeg4 DP content which is not
+                supported by HW. A component can be used to support several
+                mimetypes, so non-DP mpeg4 usecases will not be affected by this.
+            -->
+            <Type name="video/mp4v-esdp" />
             <!-- profiles and levels:  ProfileSimple : Level3 -->
             <Limit name="size" min="2x2" max="352x288" />
             <Limit name="alignment" value="2x2" />
diff --git a/media/libstagefright/foundation/ABuffer.cpp b/media/libstagefright/foundation/ABuffer.cpp
index a5b81a8..3ebbbd9 100644
--- a/media/libstagefright/foundation/ABuffer.cpp
+++ b/media/libstagefright/foundation/ABuffer.cpp
@@ -29,13 +29,9 @@
       mInt32Data(0),
       mOwnsData(true) {
     mData = malloc(capacity);
-    if (mData == NULL) {
-        mCapacity = 0;
-        mRangeLength = 0;
-    } else {
-        mCapacity = capacity;
-        mRangeLength = capacity;
-    }
+    CHECK(mData != NULL);
+    mCapacity = capacity;
+    mRangeLength = capacity;
 }
 
 ABuffer::ABuffer(void *data, size_t capacity)
diff --git a/media/libstagefright/httplive/LiveSession.cpp b/media/libstagefright/httplive/LiveSession.cpp
index 1557401..1b0b1c5 100644
--- a/media/libstagefright/httplive/LiveSession.cpp
+++ b/media/libstagefright/httplive/LiveSession.cpp
@@ -54,7 +54,7 @@
 const int64_t LiveSession::kPrepareMarkUs = 1500000ll;
 const int64_t LiveSession::kUnderflowMarkUs = 1000000ll;
 
-struct LiveSession::BandwidthEstimator : public RefBase {
+struct LiveSession::BandwidthEstimator : public LiveSession::BandwidthBaseEstimator {
     BandwidthEstimator();
 
     void addBandwidthMeasurement(size_t numBytes, int64_t delayUs);
@@ -1064,6 +1064,7 @@
                 itemsWithVideo.push(item);
             }
         }
+#if 0
         // remove the audio-only variants if we have at least one with video
         if (!itemsWithVideo.empty()
                 && itemsWithVideo.size() < mBandwidthItems.size()) {
@@ -1072,7 +1073,7 @@
                 mBandwidthItems.push(itemsWithVideo[i]);
             }
         }
-
+#endif
         CHECK_GT(mBandwidthItems.size(), 0u);
         initialBandwidth = mBandwidthItems[0].mBandwidth;
 
diff --git a/media/libstagefright/httplive/LiveSession.h b/media/libstagefright/httplive/LiveSession.h
index 90d56d0..0d504e4 100644
--- a/media/libstagefright/httplive/LiveSession.h
+++ b/media/libstagefright/httplive/LiveSession.h
@@ -73,7 +73,7 @@
             const sp<IMediaHTTPService> &httpService);
 
     int64_t calculateMediaTimeUs(int64_t firstTimeUs, int64_t timeUs, int32_t discontinuitySeq);
-    status_t dequeueAccessUnit(StreamType stream, sp<ABuffer> *accessUnit);
+    virtual status_t dequeueAccessUnit(StreamType stream, sp<ABuffer> *accessUnit);
 
     status_t getStreamFormat(StreamType stream, sp<AMessage> *format);
 
@@ -117,7 +117,6 @@
 
     virtual void onMessageReceived(const sp<AMessage> &msg);
 
-private:
     friend struct PlaylistFetcher;
 
     enum {
@@ -142,6 +141,14 @@
     static const int64_t kPrepareMarkUs;
     static const int64_t kUnderflowMarkUs;
 
+    struct BandwidthBaseEstimator : public RefBase {
+        virtual void addBandwidthMeasurement(size_t numBytes, int64_t delayUs) = 0;
+        virtual bool estimateBandwidth(
+                int32_t *bandwidth,
+                bool *isStable = NULL,
+                int32_t *shortTermBps = NULL) = 0;
+    };
+
     struct BandwidthEstimator;
     struct BandwidthItem {
         size_t mPlaylistIndex;
@@ -201,7 +208,7 @@
     ssize_t mOrigBandwidthIndex;
     int32_t mLastBandwidthBps;
     bool mLastBandwidthStable;
-    sp<BandwidthEstimator> mBandwidthEstimator;
+    sp<BandwidthBaseEstimator> mBandwidthEstimator;
 
     sp<M3UParser> mPlaylist;
     int32_t mMaxWidth;
@@ -251,10 +258,10 @@
     KeyedVector<size_t, int64_t> mDiscontinuityAbsStartTimesUs;
     KeyedVector<size_t, int64_t> mDiscontinuityOffsetTimesUs;
 
-    sp<PlaylistFetcher> addFetcher(const char *uri);
+    virtual sp<PlaylistFetcher> addFetcher(const char *uri);
 
     void onConnect(const sp<AMessage> &msg);
-    void onMasterPlaylistFetched(const sp<AMessage> &msg);
+    virtual void onMasterPlaylistFetched(const sp<AMessage> &msg);
     void onSeek(const sp<AMessage> &msg);
 
     bool UriIsSameAsIndex( const AString &uri, int32_t index, bool newUri);
@@ -269,7 +276,7 @@
     float getAbortThreshold(
             ssize_t currentBWIndex, ssize_t targetBWIndex) const;
     void addBandwidthMeasurement(size_t numBytes, int64_t delayUs);
-    size_t getBandwidthIndex(int32_t bandwidthBps);
+    virtual size_t getBandwidthIndex(int32_t bandwidthBps);
     ssize_t getLowestValidBandwidthIndex() const;
     HLSTime latestMediaSegmentStartTime() const;
 
@@ -284,7 +291,7 @@
     void onChangeConfiguration2(const sp<AMessage> &msg);
     void onChangeConfiguration3(const sp<AMessage> &msg);
 
-    void swapPacketSource(StreamType stream);
+    virtual void swapPacketSource(StreamType stream);
     void tryToFinishBandwidthSwitch(const AString &oldUri);
     void cancelBandwidthSwitch(bool resume = false);
     bool checkSwitchProgress(
@@ -296,7 +303,7 @@
     void schedulePollBuffering();
     void cancelPollBuffering();
     void restartPollBuffering();
-    void onPollBuffering();
+    virtual void onPollBuffering();
     bool checkBuffering(bool &underflow, bool &ready, bool &down, bool &up);
     void startBufferingIfNecessary();
     void stopBufferingIfNecessary();
@@ -304,7 +311,7 @@
 
     void finishDisconnect();
 
-    void postPrepared(status_t err);
+    virtual void postPrepared(status_t err);
     void postError(status_t err);
 
     DISALLOW_EVIL_CONSTRUCTORS(LiveSession);
diff --git a/media/libstagefright/httplive/PlaylistFetcher.cpp b/media/libstagefright/httplive/PlaylistFetcher.cpp
index 72d832e..023de93 100644
--- a/media/libstagefright/httplive/PlaylistFetcher.cpp
+++ b/media/libstagefright/httplive/PlaylistFetcher.cpp
@@ -975,7 +975,9 @@
         if (mSegmentStartTimeUs < 0) {
             if (!mPlaylist->isComplete() && !mPlaylist->isEvent()) {
                 // If this is a live session, start 3 segments from the end on connect
-                mSeqNumber = lastSeqNumberInPlaylist - 3;
+                if (!getSeqNumberInLiveStreaming()) {
+                    mSeqNumber = lastSeqNumberInPlaylist - 3;
+                }
                 if (mSeqNumber < firstSeqNumberInPlaylist) {
                     mSeqNumber = firstSeqNumberInPlaylist;
                 }
@@ -1418,6 +1420,10 @@
         }
     }
 
+    if (checkSwitchBandwidth()) {
+        return;
+    }
+
     ++mSeqNumber;
 
     // if adapting, pause after found the next starting point
diff --git a/media/libstagefright/httplive/PlaylistFetcher.h b/media/libstagefright/httplive/PlaylistFetcher.h
index c8ca457..6b60b65 100644
--- a/media/libstagefright/httplive/PlaylistFetcher.h
+++ b/media/libstagefright/httplive/PlaylistFetcher.h
@@ -89,7 +89,6 @@
     virtual ~PlaylistFetcher();
     virtual void onMessageReceived(const sp<AMessage> &msg);
 
-private:
     enum {
         kMaxNumRetries         = 5,
     };
@@ -249,6 +248,8 @@
 
     void updateDuration();
     void updateTargetDuration();
+    virtual bool checkSwitchBandwidth() { return false; }
+    virtual bool getSeqNumberInLiveStreaming() { return false; }
 
     DISALLOW_EVIL_CONSTRUCTORS(PlaylistFetcher);
 };
diff --git a/media/libstagefright/id3/ID3.cpp b/media/libstagefright/id3/ID3.cpp
index 4410579..76d65f0 100644
--- a/media/libstagefright/id3/ID3.cpp
+++ b/media/libstagefright/id3/ID3.cpp
@@ -503,8 +503,9 @@
 void ID3::Iterator::getstring(String8 *id, bool otherdata) const {
     id->setTo("");
 
-    const uint8_t *frameData = mFrameData;
-    if (frameData == NULL) {
+    size_t size;
+    const uint8_t *frameData = getData(&size);
+    if ((size == 0) || (frameData == NULL)) {
         return;
     }
 
diff --git a/media/libstagefright/include/NuCachedSource2.h b/media/libstagefright/include/NuCachedSource2.h
index a29bdf9..afa91ae 100644
--- a/media/libstagefright/include/NuCachedSource2.h
+++ b/media/libstagefright/include/NuCachedSource2.h
@@ -69,7 +69,7 @@
 protected:
     virtual ~NuCachedSource2();
 
-private:
+protected:
     friend struct AHandlerReflector<NuCachedSource2>;
 
     NuCachedSource2(
diff --git a/media/libstagefright/include/OMXNodeInstance.h b/media/libstagefright/include/OMXNodeInstance.h
index e5fb45b..1ca7ad2 100644
--- a/media/libstagefright/include/OMXNodeInstance.h
+++ b/media/libstagefright/include/OMXNodeInstance.h
@@ -145,7 +145,7 @@
     OMX::node_id mNodeID;
     OMX_HANDLETYPE mHandle;
     sp<IOMXObserver> mObserver;
-    bool mDying;
+    atomic_bool mDying;
     bool mIsSecure;
 
     // Lock only covers mGraphicBufferSource.  We can't always use mLock
diff --git a/media/libstagefright/include/SimpleSoftOMXComponent.h b/media/libstagefright/include/SimpleSoftOMXComponent.h
index 591b38e..6a0a958 100644
--- a/media/libstagefright/include/SimpleSoftOMXComponent.h
+++ b/media/libstagefright/include/SimpleSoftOMXComponent.h
@@ -140,6 +140,7 @@
     void onPortFlush(OMX_U32 portIndex, bool sendFlushComplete);
 
     void checkTransitions();
+    void onTransitionError();
 
     DISALLOW_EVIL_CONSTRUCTORS(SimpleSoftOMXComponent);
 };
diff --git a/media/libstagefright/mpeg2ts/ATSParser.cpp b/media/libstagefright/mpeg2ts/ATSParser.cpp
index e3c3e80..3645424 100644
--- a/media/libstagefright/mpeg2ts/ATSParser.cpp
+++ b/media/libstagefright/mpeg2ts/ATSParser.cpp
@@ -12,6 +12,25 @@
  * 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.
+ *
+ * This file was modified by Dolby Laboratories, Inc. The portions of the
+ * code that are surrounded by "DOLBY..." are copyrighted and
+ * licensed separately, as follows:
+ *
+ *  (C) 2011-2015 Dolby Laboratories, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
  */
 
 //#define LOG_NDEBUG 0
@@ -628,6 +647,12 @@
             mQueue = new ElementaryStreamQueue(
                     ElementaryStreamQueue::AC3);
             break;
+#ifdef DOLBY_ENABLE
+        case STREAMTYPE_EAC3:
+            mQueue = new ElementaryStreamQueue(
+                    ElementaryStreamQueue::EAC3);
+            break;
+#endif // DOLBY_END
 
         case STREAMTYPE_METADATA:
             mQueue = new ElementaryStreamQueue(
@@ -752,6 +777,9 @@
         case STREAMTYPE_MPEG2_AUDIO_ADTS:
         case STREAMTYPE_LPCM_AC3:
         case STREAMTYPE_AC3:
+#ifdef DOLBY_ENABLE
+        case STREAMTYPE_EAC3:
+#endif // DOLBY_END
             return true;
 
         default:
diff --git a/media/libstagefright/mpeg2ts/ATSParser.h b/media/libstagefright/mpeg2ts/ATSParser.h
index 430a8d5..366a861 100644
--- a/media/libstagefright/mpeg2ts/ATSParser.h
+++ b/media/libstagefright/mpeg2ts/ATSParser.h
@@ -12,6 +12,25 @@
  * 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.
+ *
+ * This file was modified by Dolby Laboratories, Inc. The portions of the
+ * code that are surrounded by "DOLBY..." are copyrighted and
+ * licensed separately, as follows:
+ *
+ *  (C) 2011-2015 Dolby Laboratories, Inc.
+ *
+ * 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 A_TS_PARSER_H_
@@ -134,6 +153,9 @@
         // Stream type 0x83 is non-standard,
         // it could be LPCM or TrueHD AC3
         STREAMTYPE_LPCM_AC3             = 0x83,
+#ifdef DOLBY_ENABLE
+        STREAMTYPE_EAC3                 = 0x87,
+#endif // DOLBY_END
     };
 
 protected:
diff --git a/media/libstagefright/mpeg2ts/ESQueue.cpp b/media/libstagefright/mpeg2ts/ESQueue.cpp
index 36ec367..770e94b 100644
--- a/media/libstagefright/mpeg2ts/ESQueue.cpp
+++ b/media/libstagefright/mpeg2ts/ESQueue.cpp
@@ -12,6 +12,25 @@
  * 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.
+ *
+ * This file was modified by Dolby Laboratories, Inc. The portions of the
+ * code that are surrounded by "DOLBY..." are copyrighted and
+ * licensed separately, as follows:
+ *
+ *  (C) 2011-2015 Dolby Laboratories, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
  */
 
 //#define LOG_NDEBUG 0
@@ -33,6 +52,9 @@
 
 #include <inttypes.h>
 #include <netinet/in.h>
+#ifdef DOLBY_ENABLE
+#include "DolbyESQueueExtImpl.h"
+#endif // DOLBY_END
 
 namespace android {
 
@@ -40,6 +62,9 @@
     : mMode(mode),
       mFlags(flags),
       mEOSReached(false) {
+#ifdef DOLBY_ENABLE
+    independent_streams_processed = 0;
+#endif // DOLBY_END
 }
 
 sp<MetaData> ElementaryStreamQueue::getFormat() {
@@ -388,6 +413,35 @@
                 size -= startOffset;
                 break;
             }
+#ifdef DOLBY_ENABLE
+            case EAC3:
+            {
+                uint8_t *ptr = (uint8_t *)data;
+
+                ssize_t startOffset = -1;
+                for (size_t i = 0; i < size; ++i) {
+                    if (IsSeeminglyValidEAC3AudioHeader(&ptr[i], size - i)) {
+                        startOffset = i;
+                        break;
+                    }
+                }
+
+                if (startOffset < 0) {
+                    return ERROR_MALFORMED;
+                }
+
+                if (startOffset > 0) {
+                    ALOGI("found something resembling a DDP audio "
+                         "syncword at offset %zd",
+                         startOffset);
+                }
+
+                data = &ptr[startOffset];
+                size -= startOffset;
+                break;
+            }
+
+#endif // DOLBY_END
 
             case MPEG_AUDIO:
             {
@@ -496,6 +550,10 @@
             return dequeueAccessUnitAAC();
         case AC3:
             return dequeueAccessUnitAC3();
+#ifdef DOLBY_ENABLE
+        case EAC3:
+            return dequeueAccessUnitEAC3();
+#endif // DOLBY_END
         case MPEG_VIDEO:
             return dequeueAccessUnitMPEGVideo();
         case MPEG4_VIDEO:
diff --git a/media/libstagefright/mpeg2ts/ESQueue.h b/media/libstagefright/mpeg2ts/ESQueue.h
index e9f96b7..e86a36d 100644
--- a/media/libstagefright/mpeg2ts/ESQueue.h
+++ b/media/libstagefright/mpeg2ts/ESQueue.h
@@ -12,6 +12,25 @@
  * 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.
+ *
+ * This file was modified by Dolby Laboratories, Inc. The portions of the
+ * code that are surrounded by "DOLBY..." are copyrighted and
+ * licensed separately, as follows:
+ *
+ *  (C) 2011-2015 Dolby Laboratories, Inc.
+ *
+ * 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 ES_QUEUE_H_
@@ -33,6 +52,9 @@
         H264,
         AAC,
         AC3,
+#ifdef DOLBY_ENABLE
+        EAC3,
+#endif // DOLBY_END
         MPEG_AUDIO,
         MPEG_VIDEO,
         MPEG4_VIDEO,
@@ -77,6 +99,11 @@
     sp<ABuffer> dequeueAccessUnitMPEG4Video();
     sp<ABuffer> dequeueAccessUnitPCMAudio();
     sp<ABuffer> dequeueAccessUnitMetadata();
+#ifdef DOLBY_ENABLE
+    sp<ABuffer> dequeueAccessUnitEAC3();
+    unsigned independent_streams_processed;
+    unsigned independent_stream_num_channels;
+#endif // DOLBY_END
 
     // consume a logical (compressed) access unit of size "size",
     // returns its timestamp in us (or -1 if no time information).
diff --git a/media/libstagefright/mpeg2ts/MPEG2PSExtractor.cpp b/media/libstagefright/mpeg2ts/MPEG2PSExtractor.cpp
index 6d9fe9d..86645d5 100644
--- a/media/libstagefright/mpeg2ts/MPEG2PSExtractor.cpp
+++ b/media/libstagefright/mpeg2ts/MPEG2PSExtractor.cpp
@@ -12,6 +12,25 @@
  * 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.
+ *
+ * This file was modified by Dolby Laboratories, Inc. The portions of the
+ * code that are surrounded by "DOLBY..." are copyrighted and
+ * licensed separately, as follows:
+ *
+ *  (C) 2011-2015 Dolby Laboratories, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
  */
 
 //#define LOG_NDEBUG 0
@@ -607,6 +626,14 @@
             mode = ElementaryStreamQueue::MPEG_AUDIO;
             break;
 
+#ifdef DOLBY_ENABLE
+        case ATSParser::STREAMTYPE_AC3:
+            mode = ElementaryStreamQueue::AC3;
+            break;
+        case ATSParser::STREAMTYPE_EAC3:
+            mode = ElementaryStreamQueue::EAC3;
+            break;
+#endif // DOLBY_END
         case ATSParser::STREAMTYPE_MPEG1_VIDEO:
         case ATSParser::STREAMTYPE_MPEG2_VIDEO:
             mode = ElementaryStreamQueue::MPEG_VIDEO;
diff --git a/media/libstagefright/omx/Android.mk b/media/libstagefright/omx/Android.mk
index 5f0f567..d16d5df 100644
--- a/media/libstagefright/omx/Android.mk
+++ b/media/libstagefright/omx/Android.mk
@@ -30,6 +30,12 @@
         libstagefright_foundation       \
         libdl
 
+ifeq ($(call is-vendor-board-platform,QCOM),true)
+ifeq ($(strip $(AUDIO_FEATURE_ENABLED_EXTN_FLAC_DECODER)),true)
+    LOCAL_CFLAGS += -DQTI_FLAC_DECODER
+endif
+endif
+
 LOCAL_MODULE:= libstagefright_omx
 LOCAL_CFLAGS += -Werror -Wall
 LOCAL_CLANG := true
diff --git a/media/libstagefright/omx/OMX.cpp b/media/libstagefright/omx/OMX.cpp
index 7f357c9..efb1a1c 100644
--- a/media/libstagefright/omx/OMX.cpp
+++ b/media/libstagefright/omx/OMX.cpp
@@ -468,6 +468,10 @@
     findInstance(node)->onEvent(eEvent, nData1, nData2);
 
     sp<OMX::CallbackDispatcher> dispatcher = findDispatcher(node);
+    if (dispatcher == NULL) {
+       ALOGW("OnEvent Callback dispatcher NULL, skip post");
+       return OMX_ErrorNone;
+    }
 
     // output rendered events are not processed as regular events until they hit the observer
     if (eEvent == OMX_EventOutputRendered) {
@@ -513,7 +517,12 @@
     msg.fenceFd = fenceFd;
     msg.u.buffer_data.buffer = buffer;
 
-    findDispatcher(node)->post(msg);
+    sp<OMX::CallbackDispatcher> callbackDispatcher = findDispatcher(node);
+    if (callbackDispatcher != NULL) {
+        callbackDispatcher->post(msg);
+    } else {
+        ALOGW("OnEmptyBufferDone Callback dispatcher NULL, skip post");
+    }
 
     return OMX_ErrorNone;
 }
@@ -532,7 +541,12 @@
     msg.u.extended_buffer_data.flags = pBuffer->nFlags;
     msg.u.extended_buffer_data.timestamp = pBuffer->nTimeStamp;
 
-    findDispatcher(node)->post(msg);
+    sp<OMX::CallbackDispatcher> callbackDispatcher = findDispatcher(node);
+    if (callbackDispatcher != NULL) {
+        callbackDispatcher->post(msg);
+    } else {
+        ALOGW("OnFillBufferDone Callback dispatcher NULL, skip post");
+    }
 
     return OMX_ErrorNone;
 }
diff --git a/media/libstagefright/omx/OMXNodeInstance.cpp b/media/libstagefright/omx/OMXNodeInstance.cpp
index 94a213a..9795580 100644
--- a/media/libstagefright/omx/OMXNodeInstance.cpp
+++ b/media/libstagefright/omx/OMXNodeInstance.cpp
@@ -122,7 +122,8 @@
         }
 
         // check component returns proper range
-        sp<ABuffer> codec = getBuffer(header, false /* backup */, true /* limit */);
+        sp<ABuffer> codec = getBuffer(header, false /* backup */,
+                !(header->nFlags & OMX_BUFFERFLAG_EXTRADATA));
 
         memcpy((OMX_U8 *)mMem->pointer() + header->nOffset, codec->data(), codec->size());
     }
@@ -132,9 +133,11 @@
             return;
         }
 
+        size_t bytesToCopy = header->nFlags & OMX_BUFFERFLAG_EXTRADATA ?
+            header->nAllocLen - header->nOffset : header->nFilledLen;
         memcpy(header->pBuffer + header->nOffset,
                 (const OMX_U8 *)mMem->pointer() + header->nOffset,
-                header->nFilledLen);
+                bytesToCopy);
     }
 
     // return either the codec or the backup buffer
@@ -190,7 +193,6 @@
       mNodeID(0),
       mHandle(NULL),
       mObserver(observer),
-      mDying(false),
       mBufferIDCount(0)
 {
     mName = ADebug::GetDebugName(name);
@@ -203,6 +205,7 @@
     mDebugLevelBumpPendingBuffers[1] = 0;
     mMetadataType[0] = kMetadataBufferTypeInvalid;
     mMetadataType[1] = kMetadataBufferTypeInvalid;
+    atomic_store(&mDying, false);
     mIsSecure = AString(name).endsWith(".secure");
 }
 
@@ -274,11 +277,12 @@
     // The code below may trigger some more events to be dispatched
     // by the OMX component - we want to ignore them as our client
     // does not expect them.
-    mDying = true;
+    atomic_store(&mDying, true);
 
     OMX_STATETYPE state;
     CHECK_EQ(OMX_GetState(mHandle, &state), OMX_ErrorNone);
     switch (state) {
+        case OMX_StatePause:
         case OMX_StateExecuting:
         {
             ALOGV("forcing Executing->Idle");
@@ -1457,6 +1461,9 @@
     ALOGE("!!! Observer died. Quickly, do something, ... anything...");
 
     // Try to force shutdown of the node and hope for the best.
+    // But allow the component to observe mDying = true first
+    atomic_store(&mDying, true);
+    sleep(2);
     freeNode(master);
 }
 
@@ -1524,7 +1531,7 @@
         OMX_IN OMX_U32 nData2,
         OMX_IN OMX_PTR pEventData) {
     OMXNodeInstance *instance = static_cast<OMXNodeInstance *>(pAppData);
-    if (instance->mDying) {
+    if (atomic_load(&instance->mDying)) {
         return OMX_ErrorNone;
     }
     return instance->owner()->OnEvent(
@@ -1537,7 +1544,7 @@
         OMX_IN OMX_PTR pAppData,
         OMX_IN OMX_BUFFERHEADERTYPE* pBuffer) {
     OMXNodeInstance *instance = static_cast<OMXNodeInstance *>(pAppData);
-    if (instance->mDying) {
+    if (atomic_load(&instance->mDying)) {
         return OMX_ErrorNone;
     }
     int fenceFd = instance->retrieveFenceFromMeta_l(pBuffer, kPortIndexOutput);
@@ -1551,7 +1558,7 @@
         OMX_IN OMX_PTR pAppData,
         OMX_IN OMX_BUFFERHEADERTYPE* pBuffer) {
     OMXNodeInstance *instance = static_cast<OMXNodeInstance *>(pAppData);
-    if (instance->mDying) {
+    if (atomic_load(&instance->mDying)) {
         return OMX_ErrorNone;
     }
     int fenceFd = instance->retrieveFenceFromMeta_l(pBuffer, kPortIndexOutput);
diff --git a/media/libstagefright/omx/SimpleSoftOMXComponent.cpp b/media/libstagefright/omx/SimpleSoftOMXComponent.cpp
index e6a0c49..1fd0641 100644
--- a/media/libstagefright/omx/SimpleSoftOMXComponent.cpp
+++ b/media/libstagefright/omx/SimpleSoftOMXComponent.cpp
@@ -417,16 +417,43 @@
     }
 }
 
+void SimpleSoftOMXComponent::onTransitionError() {
+    mState = OMX_StateInvalid;
+    mTargetState = OMX_StateInvalid;
+    notify(OMX_EventError, OMX_CommandStateSet, OMX_StateInvalid, 0);
+}
+
 void SimpleSoftOMXComponent::onChangeState(OMX_STATETYPE state) {
+    bool skipTransitions = false;
+
     // We shouldn't be in a state transition already.
-    CHECK_EQ((int)mState, (int)mTargetState);
+    if (mState != mTargetState) {
+        // Workaround to prevent assertion
+        // XXX CHECK_EQ((int)mState, (int)mTargetState);
+        ALOGW("mState %d != mTargetState %d", mState, mTargetState);
+        skipTransitions = true;
+        onTransitionError();
+    }
 
     switch (mState) {
         case OMX_StateLoaded:
-            CHECK_EQ((int)state, (int)OMX_StateIdle);
+            if (state != OMX_StateIdle) {
+                // Workaround to prevent assertion
+                // XXX CHECK_EQ((int)state, (int)OMX_StateIdle);
+                ALOGW("In OMX_StateLoaded, state %d != OMX_StateIdle", state);
+                skipTransitions = true;
+                onTransitionError();
+            }
             break;
         case OMX_StateIdle:
-            CHECK(state == OMX_StateLoaded || state == OMX_StateExecuting);
+            if (!(state == OMX_StateLoaded || state == OMX_StateExecuting)) {
+                // Workaround to prevent assertion
+                // XXX CHECK(state == OMX_StateLoaded || state == OMX_StateExecuting);
+                ALOGW("In OMX_StateIdle, state %d != OMX_StateLoaded||OMX_StateExecuting",
+                      state);
+                skipTransitions = true;
+                onTransitionError();
+            }
             break;
         case OMX_StateExecuting:
         {
@@ -440,11 +467,20 @@
             notify(OMX_EventCmdComplete, OMX_CommandStateSet, state, NULL);
             break;
         }
-
+        case OMX_StateInvalid: {
+            ALOGW("In OMX_StateInvalid, ignore state transition to %d", state);
+            skipTransitions = true;
+            onTransitionError();
+            break;
+        }
         default:
             TRESPASS();
     }
 
+    if (skipTransitions) {
+        return;
+    }
+
     mTargetState = state;
 
     checkTransitions();
diff --git a/media/libstagefright/omx/SoftOMXPlugin.cpp b/media/libstagefright/omx/SoftOMXPlugin.cpp
index 0f9c00c..5117ddd 100755
--- a/media/libstagefright/omx/SoftOMXPlugin.cpp
+++ b/media/libstagefright/omx/SoftOMXPlugin.cpp
@@ -12,6 +12,25 @@
  * 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.
+ *
+ * This file was modified by Dolby Laboratories, Inc. The portions of the
+ * code that are surrounded by "DOLBY..." are copyrighted and
+ * licensed separately, as follows:
+ *
+ *  (C) 2011-2015 Dolby Laboratories, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
  */
 
 //#define LOG_NDEBUG 0
@@ -59,6 +78,14 @@
     { "OMX.google.raw.decoder", "rawdec", "audio_decoder.raw" },
     { "OMX.google.flac.encoder", "flacenc", "audio_encoder.flac" },
     { "OMX.google.gsm.decoder", "gsmdec", "audio_decoder.gsm" },
+#ifdef QTI_FLAC_DECODER
+    { "OMX.qti.audio.decoder.flac", "flacdec", "audio_decoder.flac" },
+#endif
+#ifdef DOLBY_ENABLE
+    { "OMX.dolby.ac3.decoder", "ddpdec", "audio_decoder.ac3" },
+    { "OMX.dolby.eac3.decoder", "ddpdec", "audio_decoder.eac3" },
+    { "OMX.dolby.eac3_joc.decoder", "ddpdec", "audio_decoder.eac3_joc" },
+#endif // DOLBY_END
 };
 
 static const size_t kNumComponents =
diff --git a/media/libstagefright/rtsp/AH263Assembler.cpp b/media/libstagefright/rtsp/AH263Assembler.cpp
index 75cd911..28594e2 100644
--- a/media/libstagefright/rtsp/AH263Assembler.cpp
+++ b/media/libstagefright/rtsp/AH263Assembler.cpp
@@ -27,6 +27,8 @@
 #include <media/stagefright/foundation/hexdump.h>
 #include <media/stagefright/Utils.h>
 
+#include <mediaplayerservice/AVMediaServiceExtensions.h>
+
 namespace android {
 
 AH263Assembler::AH263Assembler(const sp<AMessage> &notify)
@@ -63,7 +65,8 @@
             if ((uint32_t)(*it)->int32Data() >= mNextExpectedSeqNo) {
                 break;
             }
-
+            AVMediaServiceUtils::get()->addH263AdvancedPacket(
+                    *it, &mPackets, mAccessUnitRTPTime);
             it = queue->erase(it);
         }
 
diff --git a/media/libstagefright/rtsp/AMPEG4AudioAssembler.cpp b/media/libstagefright/rtsp/AMPEG4AudioAssembler.cpp
index a1a6576..d239e7b 100644
--- a/media/libstagefright/rtsp/AMPEG4AudioAssembler.cpp
+++ b/media/libstagefright/rtsp/AMPEG4AudioAssembler.cpp
@@ -420,6 +420,11 @@
             CHECK_LE(offset + (mOtherDataLenBits / 8), buffer->size());
             offset += mOtherDataLenBits / 8;
         }
+
+        if (i < mNumSubFrames && offset >= buffer->size()) {
+            ALOGW("Skip subframes after %d, total %d", (int)i, (int)mNumSubFrames);
+            break;
+        }
     }
 
     if (offset < buffer->size()) {
diff --git a/media/libstagefright/rtsp/ARTPConnection.cpp b/media/libstagefright/rtsp/ARTPConnection.cpp
index a86ab74..e021b29 100644
--- a/media/libstagefright/rtsp/ARTPConnection.cpp
+++ b/media/libstagefright/rtsp/ARTPConnection.cpp
@@ -81,7 +81,8 @@
         const sp<ASessionDescription> &sessionDesc,
         size_t index,
         const sp<AMessage> &notify,
-        bool injected) {
+        bool injected,
+        bool isIPV6) {
     sp<AMessage> msg = new AMessage(kWhatAddStream, this);
     msg->setInt32("rtp-socket", rtpSocket);
     msg->setInt32("rtcp-socket", rtcpSocket);
@@ -89,6 +90,7 @@
     msg->setSize("index", index);
     msg->setMessage("notify", notify);
     msg->setInt32("injected", injected);
+    msg->setInt32("isIPV6", isIPV6);
     msg->post();
 }
 
@@ -145,6 +147,10 @@
     TRESPASS();
 }
 
+size_t ARTPConnection::sockAddrSize() {
+    return sizeof(struct sockaddr_in);
+}
+
 void ARTPConnection::onMessageReceived(const sp<AMessage> &msg) {
     switch (msg->what()) {
         case kWhatAddStream:
@@ -345,7 +351,7 @@
                     n = sendto(
                         s->mRTCPSocket, buffer->data(), buffer->size(), 0,
                         (const struct sockaddr *)&s->mRemoteRTCPAddr,
-                        sizeof(s->mRemoteRTCPAddr));
+                        sockAddrSize());
                 } while (n < 0 && errno == EINTR);
 
                 if (n <= 0) {
diff --git a/media/libstagefright/rtsp/ARTPConnection.h b/media/libstagefright/rtsp/ARTPConnection.h
index edbcc35..057007b 100644
--- a/media/libstagefright/rtsp/ARTPConnection.h
+++ b/media/libstagefright/rtsp/ARTPConnection.h
@@ -38,7 +38,8 @@
             int rtpSocket, int rtcpSocket,
             const sp<ASessionDescription> &sessionDesc, size_t index,
             const sp<AMessage> &notify,
-            bool injected);
+            bool injected,
+            bool isIPV6 = false);
 
     void removeStream(int rtpSocket, int rtcpSocket);
 
@@ -53,8 +54,8 @@
 protected:
     virtual ~ARTPConnection();
     virtual void onMessageReceived(const sp<AMessage> &msg);
+    virtual size_t sockAddrSize();
 
-private:
     enum {
         kWhatAddStream,
         kWhatRemoveStream,
@@ -72,7 +73,7 @@
     bool mPollEventPending;
     int64_t mLastReceiverReportTimeUs;
 
-    void onAddStream(const sp<AMessage> &msg);
+    virtual void onAddStream(const sp<AMessage> &msg);
     void onRemoveStream(const sp<AMessage> &msg);
     void onPollStreams();
     void onInjectPacket(const sp<AMessage> &msg);
diff --git a/media/libstagefright/rtsp/ARTSPConnection.cpp b/media/libstagefright/rtsp/ARTSPConnection.cpp
index 855ffdc..b2c1fd1 100644
--- a/media/libstagefright/rtsp/ARTSPConnection.cpp
+++ b/media/libstagefright/rtsp/ARTSPConnection.cpp
@@ -26,6 +26,7 @@
 #include <media/stagefright/foundation/base64.h>
 #include <media/stagefright/MediaErrors.h>
 #include <media/stagefright/Utils.h>
+#include <mediaplayerservice/AVMediaServiceExtensions.h>
 
 #include <arpa/inet.h>
 #include <fcntl.h>
@@ -170,7 +171,7 @@
         }
     }
 
-    const char *colonPos = strchr(host->c_str(), ':');
+    const char *colonPos = AVMediaServiceUtils::get()->parseURL(host);
 
     if (colonPos != NULL) {
         unsigned long x;
@@ -252,6 +253,11 @@
         ALOGV("user = '%s', pass = '%s'", mUser.c_str(), mPass.c_str());
     }
 
+    performConnect(reply, host, port);
+}
+
+void ARTSPConnection::performConnect(const sp<AMessage> &reply,
+        AString host, unsigned port) {
     struct hostent *ent = gethostbyname(host.c_str());
     if (ent == NULL) {
         ALOGE("Unknown host %s", host.c_str());
@@ -381,7 +387,12 @@
     socklen_t optionLen = sizeof(err);
     CHECK_EQ(getsockopt(mSocket, SOL_SOCKET, SO_ERROR, &err, &optionLen), 0);
     CHECK_EQ(optionLen, (socklen_t)sizeof(err));
+    performCompleteConnection(msg, err);
+}
 
+void ARTSPConnection::performCompleteConnection(const sp<AMessage> &msg, int err) {
+    sp<AMessage> reply;
+    CHECK(msg->findMessage("reply", &reply));
     if (err != 0) {
         ALOGE("err = %d (%s)", err, strerror(err));
 
diff --git a/media/libstagefright/rtsp/ARTSPConnection.h b/media/libstagefright/rtsp/ARTSPConnection.h
index 1fe9c99..c4ebe1d 100644
--- a/media/libstagefright/rtsp/ARTSPConnection.h
+++ b/media/libstagefright/rtsp/ARTSPConnection.h
@@ -42,6 +42,8 @@
 
     void observeBinaryData(const sp<AMessage> &reply);
 
+    virtual bool isIPV6() { return false; }
+
     static bool ParseURL(
             const char *url, AString *host, unsigned *port, AString *path,
             AString *user, AString *pass);
@@ -49,8 +51,11 @@
 protected:
     virtual ~ARTSPConnection();
     virtual void onMessageReceived(const sp<AMessage> &msg);
+    virtual void performConnect(const sp<AMessage> &reply,
+            AString host, unsigned port);
+    virtual void performCompleteConnection(const sp<AMessage> &msg,
+            int err);
 
-private:
     enum State {
         DISCONNECTED,
         CONNECTING,
diff --git a/media/libstagefright/rtsp/ASessionDescription.cpp b/media/libstagefright/rtsp/ASessionDescription.cpp
index 98498e9..92ad1ec 100644
--- a/media/libstagefright/rtsp/ASessionDescription.cpp
+++ b/media/libstagefright/rtsp/ASessionDescription.cpp
@@ -22,7 +22,7 @@
 
 #include <media/stagefright/foundation/ADebug.h>
 #include <media/stagefright/foundation/AString.h>
-
+#include <mediaplayerservice/AVMediaServiceExtensions.h>
 #include <stdlib.h>
 
 namespace android {
@@ -264,7 +264,8 @@
     }
 
     float from, to;
-    if (!parseNTPRange(value.c_str() + 4, &from, &to)) {
+    if (!AVMediaServiceUtils::get()->parseNTPRange(
+            value.c_str() + 4, &from, &to)) {
         return false;
     }
 
diff --git a/media/libstagefright/rtsp/Android.mk b/media/libstagefright/rtsp/Android.mk
index c5e8c35..8bc4295 100644
--- a/media/libstagefright/rtsp/Android.mk
+++ b/media/libstagefright/rtsp/Android.mk
@@ -22,8 +22,10 @@
 LOCAL_SHARED_LIBRARIES += libcrypto
 
 LOCAL_C_INCLUDES:= \
-	$(TOP)/frameworks/av/media/libstagefright \
-	$(TOP)/frameworks/native/include/media/openmax
+        $(TOP)/frameworks/av/media/libstagefright \
+        $(TOP)/frameworks/av/media/libavextensions \
+        $(TOP)/frameworks/native/include/media/openmax \
+        $(TOP)/frameworks/av/media/libmediaplayerservice \
 
 LOCAL_MODULE:= libstagefright_rtsp
 
diff --git a/media/libstagefright/rtsp/MyHandler.h b/media/libstagefright/rtsp/MyHandler.h
index 0d0baf3..7290ee2 100644
--- a/media/libstagefright/rtsp/MyHandler.h
+++ b/media/libstagefright/rtsp/MyHandler.h
@@ -32,6 +32,7 @@
 #include "ASessionDescription.h"
 
 #include <ctype.h>
+#include <cutils/properties.h>
 
 #include <media/stagefright/foundation/ABuffer.h>
 #include <media/stagefright/foundation/ADebug.h>
@@ -39,6 +40,7 @@
 #include <media/stagefright/foundation/AMessage.h>
 #include <media/stagefright/MediaErrors.h>
 #include <media/stagefright/Utils.h>
+#include <mediaplayerservice/AVMediaServiceExtensions.h>
 
 #include <arpa/inet.h>
 #include <sys/socket.h>
@@ -64,6 +66,8 @@
 
 static int64_t kPauseDelayUs = 3000000ll;
 
+static int64_t kTearDownTimeoutUs = 3000000ll;
+
 namespace android {
 
 static bool GetAttribute(const char *s, const char *key, AString *value) {
@@ -105,6 +109,8 @@
         kWhatEOS                        = 'eos!',
         kWhatSeekDiscontinuity          = 'seeD',
         kWhatNormalPlayTimeMapping      = 'nptM',
+        kWhatCancelCheck                = 'canC',
+        kWhatByeReceived                = 'byeR',
     };
 
     MyHandler(
@@ -115,8 +121,6 @@
           mUIDValid(uidValid),
           mUID(uid),
           mNetLooper(new ALooper),
-          mConn(new ARTSPConnection(mUIDValid, mUID)),
-          mRTPConn(new ARTPConnection),
           mOriginalSessionURL(url),
           mSessionURL(url),
           mSetupTracksSuccessful(false),
@@ -140,11 +144,22 @@
           mPausing(false),
           mPauseGeneration(0),
           mPlayResponseParsed(false) {
+        mConn = AVMediaServiceFactory::get()->createARTSPConnection(
+                mUIDValid, uid);
+        mRTPConn = AVMediaServiceFactory::get()->createARTPConnection();
         mNetLooper->setName("rtsp net");
         mNetLooper->start(false /* runOnCallingThread */,
                           false /* canCallJava */,
                           PRIORITY_HIGHEST);
 
+        char value[PROPERTY_VALUE_MAX] = {0};
+        property_get("rtsp.transport.TCP", value, "false");
+        if (!strcasecmp(value, "true")) {
+            mTryTCPInterleaving = true;
+        } else {
+            mTryTCPInterleaving = false;
+        }
+
         // Strip any authentication info from the session url, we don't
         // want to transmit user/pass in cleartext.
         AString host, path, user, pass;
@@ -244,6 +259,11 @@
         msg->post();
     }
 
+    void cancelTimeoutCheck() {
+        sp<AMessage> msg = new AMessage('canC', this);
+        msg->post();
+    }
+
     static void addRR(const sp<ABuffer> &buf) {
         uint8_t *ptr = buf->data() + buf->size();
         ptr[0] = 0x80 | 0;
@@ -703,6 +723,7 @@
                                      timeoutSecs);
                             }
                         }
+                        AVMediaServiceUtils::get()->setServerTimeoutUs(mKeepAliveTimeoutUs);
 
                         i = mSessionID.find(";");
                         if (i >= 0) {
@@ -722,16 +743,19 @@
 
                                 // We are going to continue even if we were
                                 // unable to poke a hole into the firewall...
-                                pokeAHole(
+                                AVMediaServiceUtils::get()->pokeAHole(
+                                        this,
                                         track->mRTPSocket,
                                         track->mRTCPSocket,
-                                        transport);
+                                        transport,
+                                        mSessionHost);
                             }
 
                             mRTPConn->addStream(
                                     track->mRTPSocket, track->mRTCPSocket,
                                     mSessionDesc, index,
-                                    notify, track->mUsingInterleavedTCP);
+                                    notify, track->mUsingInterleavedTCP,
+                                    mConn->isIPV6());
 
                             mSetupTracksSuccessful = true;
                         } else {
@@ -774,6 +798,7 @@
                     request.append(mSessionID);
                     request.append("\r\n");
 
+                    AVMediaServiceUtils::get()->appendRange(&request);
                     request.append("\r\n");
 
                     sp<AMessage> reply = new AMessage('play', this);
@@ -922,6 +947,15 @@
                 request.append("\r\n");
 
                 mConn->sendRequest(request.c_str(), reply);
+
+                // If the response of teardown hasn't been received in 3 seconds,
+                // post 'tear' message to avoid ANR.
+                if (!msg->findInt32("reconnect", &reconnect) || !reconnect) {
+                    sp<AMessage> teardown = new AMessage('tear', this);
+                    teardown->setInt32("result", -ECONNABORTED);
+                    teardown->post(kTearDownTimeoutUs);
+                }
+
                 break;
             }
 
@@ -1020,6 +1054,13 @@
                 int32_t eos;
                 if (msg->findInt32("eos", &eos)) {
                     ALOGI("received BYE on track index %zu", trackIndex);
+                    char value[PROPERTY_VALUE_MAX] = {0};
+                    if (property_get("rtcp.bye.notify", value, "false")
+                            && !strcasecmp(value, "true")) {
+                        sp<AMessage> msg = mNotify->dup();
+                        msg->setInt32("what", kWhatByeReceived);
+                        msg->post();
+                    }
                     if (!mAllTracksHaveTime && dataReceivedOnAllChannels()) {
                         ALOGI("No time established => fake existing data");
 
@@ -1386,6 +1427,13 @@
                 break;
             }
 
+            case 'canC':
+            {
+                ALOGV("cancel checking timeout");
+                mCheckGeneration++;
+                break;
+            }
+
             default:
                 TRESPASS();
                 break;
@@ -1471,7 +1519,9 @@
 
             size_t trackIndex = 0;
             while (trackIndex < mTracks.size()
-                    && !(val == mTracks.editItemAt(trackIndex).mURL)) {
+                    && !(AVMediaServiceUtils::get()->parseTrackURL(
+                    mTracks.editItemAt(trackIndex).mURL, val)
+                    || val == mTracks.editItemAt(trackIndex).mURL)) {
                 ++trackIndex;
             }
             CHECK_LT(trackIndex, mTracks.size());
@@ -1648,8 +1698,9 @@
             request.append(interleaveIndex + 1);
         } else {
             unsigned rtpPort;
-            ARTPConnection::MakePortPair(
-                    &info->mRTPSocket, &info->mRTCPSocket, &rtpPort);
+            AVMediaServiceUtils::get()->makePortPair(
+                    &info->mRTPSocket, &info->mRTCPSocket, &rtpPort,
+                    mConn->isIPV6());
 
             if (mUIDValid) {
                 HTTPBase::RegisterSocketUserTag(info->mRTPSocket, mUID,
@@ -1860,7 +1911,7 @@
             mLastMediaTimeUs = mediaTimeUs;
         }
 
-        if (mediaTimeUs < 0) {
+        if (mediaTimeUs < 0 && !mSeekable) {
             ALOGV("dropping early accessUnit.");
             return false;
         }
diff --git a/media/mediaserver/Android.mk b/media/mediaserver/Android.mk
index b6de0d9..fec0629 100644
--- a/media/mediaserver/Android.mk
+++ b/media/mediaserver/Android.mk
@@ -50,6 +50,12 @@
     frameworks/av/services/radio \
     external/sonic
 
+ifeq ($(strip $(AUDIO_FEATURE_ENABLED_LISTEN)),true)
+LOCAL_SHARED_LIBRARIES += liblisten
+LOCAL_C_INCLUDES += $(TARGET_OUT_HEADERS)/mm-audio/audio-listen
+LOCAL_CFLAGS += -DAUDIO_LISTEN_ENABLED
+endif
+
 LOCAL_MODULE:= mediaserver
 LOCAL_32_BIT_ONLY := true
 
diff --git a/media/mediaserver/main_mediaserver.cpp b/media/mediaserver/main_mediaserver.cpp
index 4a485ed..f6aed5f 100644
--- a/media/mediaserver/main_mediaserver.cpp
+++ b/media/mediaserver/main_mediaserver.cpp
@@ -38,6 +38,9 @@
 #include "service/AudioPolicyService.h"
 #include "SoundTriggerHwService.h"
 #include "RadioService.h"
+#ifdef AUDIO_LISTEN_ENABLED
+#include "ListenService.h"
+#endif
 
 using namespace android;
 
@@ -136,6 +139,10 @@
         AudioPolicyService::instantiate();
         SoundTriggerHwService::instantiate();
         RadioService::instantiate();
+#ifdef AUDIO_LISTEN_ENABLED
+        ALOGI("ListenService instantiated");
+        ListenService::instantiate();
+#endif
         registerExtensions();
         ProcessState::self()->startThreadPool();
         IPCThreadState::self()->joinThreadPool();
diff --git a/services/audioflinger/Android.mk b/services/audioflinger/Android.mk
index 9b4ba79..3ea586e 100644
--- a/services/audioflinger/Android.mk
+++ b/services/audioflinger/Android.mk
@@ -60,6 +60,14 @@
     libcpustats \
     libmedia_helper
 
+#QTI Resampler
+ifeq ($(call is-vendor-board-platform,QCOM), true)
+ifeq ($(strip $(AUDIO_FEATURE_ENABLED_EXTN_RESAMPLER)), true)
+LOCAL_CFLAGS += -DQTI_RESAMPLER
+endif
+endif
+#QTI Resampler
+
 LOCAL_MODULE:= libaudioflinger
 LOCAL_32_BIT_ONLY := true
 
@@ -123,7 +131,26 @@
 LOCAL_SHARED_LIBRARIES := \
     libcutils \
     libdl \
-    liblog
+    liblog \
+    libaudioutils
+
+#QTI Resampler
+ifeq ($(call is-vendor-board-platform,QCOM),true)
+ifeq ($(strip $(AUDIO_FEATURE_ENABLED_EXTN_RESAMPLER)),true)
+ifdef TARGET_2ND_ARCH
+LOCAL_SRC_FILES_$(TARGET_2ND_ARCH) += AudioResamplerQTI.cpp.arm
+LOCAL_C_INCLUDES_$(TARGET_2ND_ARCH) += $(TARGET_OUT_HEADERS)/mm-audio/audio-src
+LOCAL_SHARED_LIBRARIES_$(TARGET_2ND_ARCH) += libqct_resampler
+LOCAL_CFLAGS_$(TARGET_2ND_ARCH) += -DQTI_RESAMPLER
+else
+LOCAL_SRC_FILES += AudioResamplerQTI.cpp.arm
+LOCAL_C_INCLUDES += $(TARGET_OUT_HEADERS)/mm-audio/audio-src
+LOCAL_SHARED_LIBRARIES += libqct_resampler
+LOCAL_CFLAGS += -DQTI_RESAMPLER
+endif
+endif
+endif
+#QTI Resampler
 
 LOCAL_MODULE := libaudioresampler
 
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index 9ec5802..eed3bb2 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -13,6 +13,25 @@
 ** 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.
+**
+** This file was modified by Dolby Laboratories, Inc. The portions of the
+** code that are surrounded by "DOLBY..." are copyrighted and
+** licensed separately, as follows:
+**
+**  (C) 2011-2015 Dolby Laboratories, Inc.
+**
+** 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.
+**
 */
 
 
@@ -80,6 +99,9 @@
 #define ALOGVV(a...) do { } while(0)
 #endif
 
+#ifdef DOLBY_ENABLE
+#include "EffectDapController_impl.h"
+#endif // DOLBY_END
 namespace android {
 
 static const char kDeadlockedString[] = "AudioFlinger may be deadlocked\n";
@@ -131,6 +153,14 @@
     case AUDIO_FORMAT_OPUS: return "opus";
     case AUDIO_FORMAT_AC3: return "ac-3";
     case AUDIO_FORMAT_E_AC3: return "e-ac-3";
+    case AUDIO_FORMAT_PCM_OFFLOAD:
+        switch (format) {
+        case AUDIO_FORMAT_PCM_16_BIT_OFFLOAD: return "pcm-16bit-offload";
+        case AUDIO_FORMAT_PCM_24_BIT_OFFLOAD: return "pcm-24bit-offload";
+        default:
+            break;
+        }
+        break;
     default:
         break;
     }
@@ -210,6 +240,9 @@
         mTeeSinkTrackEnabled = true;
     }
 #endif
+#ifdef DOLBY_ENABLE
+    EffectDapController::mInstance = new EffectDapController(this);
+#endif // DOLBY_END
 }
 
 void AudioFlinger::onFirstRef()
@@ -239,6 +272,9 @@
 
 AudioFlinger::~AudioFlinger()
 {
+#ifdef DOLBY_ENABLE
+    delete EffectDapController::mInstance;
+#endif // DOLBY_END
     while (!mRecordThreads.isEmpty()) {
         // closeInput_nonvirtual() will remove specified entry from mRecordThreads
         closeInput_nonvirtual(mRecordThreads.keyAt(0));
@@ -1053,9 +1089,24 @@
             }
             mHardwareStatus = AUDIO_HW_IDLE;
         }
-        // disable AEC and NS if the device is a BT SCO headset supporting those pre processings
+
         AudioParameter param = AudioParameter(keyValuePairs);
-        String8 value;
+        String8 value, key;
+        key = String8("SND_CARD_STATUS");
+        if (param.get(key, value) == NO_ERROR) {
+            ALOGV("Set keySoundCardStatus:%s", value.string());
+            if ((value.find("OFFLINE", 0) != -1) ) {
+                ALOGV("OFFLINE detected - call InvalidateTracks()");
+                for (size_t i = 0; i < mPlaybackThreads.size(); i++) {
+                    PlaybackThread *thread = mPlaybackThreads.valueAt(i).get();
+                    if( thread->getOutput()->flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD ){
+                         thread->invalidateTracks(AUDIO_STREAM_MUSIC);
+                     }
+                }
+           }
+        }
+
+        // disable AEC and NS if the device is a BT SCO headset supporting those pre processings
         if (param.get(String8(AUDIO_PARAMETER_KEY_BT_NREC), value) == NO_ERROR) {
             bool btNrecIsOff = (value == AUDIO_PARAMETER_VALUE_OFF);
             if (mBtNrecIsOff != btNrecIsOff) {
@@ -1353,11 +1404,10 @@
     :   RefBase(),
         mAudioFlinger(audioFlinger),
         // FIXME should be a "k" constant not hard-coded, in .h or ro. property, see 4 lines below
-        mMemoryDealer(new MemoryDealer(1024*1024, "AudioFlinger::Client")),
+        mMemoryDealer(new MemoryDealer(4100*1024, "AudioFlinger::Client")), //4MB + 1 more 4k page
         mPid(pid),
         mTimedTrackCount(0)
 {
-    // 1 MB of address space is good for 32 tracks, 8 buffers each, 4 KB/buffer
 }
 
 // Client destructor must be called with AudioFlinger::mClientLock held
@@ -1818,7 +1868,11 @@
                 || !isValidPcmSinkFormat(config->format)
                 || !isValidPcmSinkChannelMask(config->channel_mask)) {
             thread = new DirectOutputThread(this, outputStream, *output, devices, mSystemReady);
-            ALOGV("openOutput_l() created direct output: ID %d thread %p", *output, thread);
+            ALOGV("openOutput_l() created direct output: ID %d thread %p ", *output, thread);
+            //Check if this is DirectPCM, if so
+            if (flags & AUDIO_OUTPUT_FLAG_DIRECT_PCM) {
+                thread->mIsDirectPcm = true;
+            }
         } else {
             thread = new MixerThread(this, outputStream, *output, devices, mSystemReady);
             ALOGV("openOutput_l() created mixer output: ID %d thread %p", *output, thread);
@@ -2694,6 +2748,11 @@
 
     Mutex::Autolock _dl(dstThread->mLock);
     Mutex::Autolock _sl(srcThread->mLock);
+#ifdef DOLBY_ENABLE
+    if (sessionId == DOLBY_MOVE_EFFECT_SIGNAL) {
+        return EffectDapController::instance()->moveEffect(AUDIO_SESSION_OUTPUT_MIX, srcThread, dstThread);
+    }
+#endif // DOLBY_END
     return moveEffectChain_l(sessionId, srcThread, dstThread, false);
 }
 
@@ -2775,6 +2834,9 @@
     if (status != NO_ERROR) {
         for (size_t i = 0; i < removed.size(); i++) {
             srcThread->addEffect_l(removed[i]);
+#ifdef DOLBY_ENABLE
+        EffectDapController::instance()->restartEffect(effect);
+#endif // DOLBY_END
             if (dstChain != 0 && reRegister) {
                 AudioSystem::unregisterEffect(removed[i]->id());
                 AudioSystem::registerEffect(&removed[i]->desc(),
@@ -2960,6 +3022,7 @@
             bool firstRead = true;
 #define TEE_SINK_READ 1024                      // frames per I/O operation
             void *buffer = malloc(TEE_SINK_READ * frameSize);
+            CHECK (buffer != NULL);
             for (;;) {
                 size_t count = TEE_SINK_READ;
                 ssize_t actual = teeSource->read(buffer, count,
diff --git a/services/audioflinger/AudioFlinger.h b/services/audioflinger/AudioFlinger.h
index 20c34ef..afcc61f 100644
--- a/services/audioflinger/AudioFlinger.h
+++ b/services/audioflinger/AudioFlinger.h
@@ -13,6 +13,25 @@
 ** 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.
+**
+** This file was modified by Dolby Laboratories, Inc. The portions of the
+** code that are surrounded by "DOLBY..." are copyrighted and
+** licensed separately, as follows:
+**
+**  (C) 2011-2015 Dolby Laboratories, Inc.
+**
+** 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_AUDIO_FLINGER_H
@@ -64,6 +83,9 @@
 
 #include <media/nbaio/NBLog.h>
 #include <private/media/AudioTrackShared.h>
+#ifdef DOLBY_ENABLE
+#include "ds_config.h"
+#endif // DOLBY_END
 
 namespace android {
 
@@ -764,6 +786,9 @@
     sp<PatchPanel> mPatchPanel;
 
     bool        mSystemReady;
+#ifdef DOLBY_ENABLE
+#include "EffectDapController.h"
+#endif // DOLBY_END
 };
 
 #undef INCLUDING_FROM_AUDIOFLINGER_H
diff --git a/services/audioflinger/AudioMixer.cpp b/services/audioflinger/AudioMixer.cpp
index 8a9a837..27a2f65 100644
--- a/services/audioflinger/AudioMixer.cpp
+++ b/services/audioflinger/AudioMixer.cpp
@@ -85,6 +85,9 @@
 // Set to default copy buffer size in frames for input processing.
 static const size_t kCopyBufferFrameCount = 256;
 
+#ifdef QTI_RESAMPLER
+#define QTI_RESAMPLER_MAX_SAMPLERATE 192000
+#endif
 namespace android {
 
 // ----------------------------------------------------------------------------
@@ -779,6 +782,13 @@
                 // but if none exists, it is the channel count (1 for mono).
                 const int resamplerChannelCount = downmixerBufferProvider != NULL
                         ? mMixerChannelCount : channelCount;
+#ifdef QTI_RESAMPLER
+                if ((trackSampleRate <= QTI_RESAMPLER_MAX_SAMPLERATE) &&
+                       (trackSampleRate > devSampleRate * 2) &&
+                       ((devSampleRate == 48000)||(devSampleRate == 44100))) {
+                    quality = AudioResampler::QTI_QUALITY;
+                }
+#endif
                 ALOGVV("Creating resampler:"
                         " format(%#x) channels(%d) devSampleRate(%u) quality(%d)\n",
                         mMixerInFormat, resamplerChannelCount, devSampleRate, quality);
@@ -1644,6 +1654,9 @@
                 // Note: In case of later int16_t sink output,
                 // conversion and clamping is done by memcpy_to_i16_from_float().
             } while (--outFrames);
+            //assign fout to out, when no more frames are available, so that 0s
+            //can be filled at the right place
+            out = (int32_t *)fout;
             break;
         case AUDIO_FORMAT_PCM_16_BIT:
             if (CC_UNLIKELY(uint32_t(vl) > UNITY_GAIN_INT || uint32_t(vr) > UNITY_GAIN_INT)) {
diff --git a/services/audioflinger/AudioResampler.cpp b/services/audioflinger/AudioResampler.cpp
index e49b7b1..ab3294a 100644
--- a/services/audioflinger/AudioResampler.cpp
+++ b/services/audioflinger/AudioResampler.cpp
@@ -28,6 +28,10 @@
 #include "AudioResamplerCubic.h"
 #include "AudioResamplerDyn.h"
 
+#ifdef QTI_RESAMPLER
+#include "AudioResamplerQTI.h"
+#endif
+
 #ifdef __arm__
     #define ASM_ARM_RESAMP1 // enable asm optimisation for ResamplerOrder1
 #endif
@@ -90,6 +94,9 @@
     case DYN_LOW_QUALITY:
     case DYN_MED_QUALITY:
     case DYN_HIGH_QUALITY:
+#ifdef QTI_RESAMPLER
+    case QTI_QUALITY:
+#endif
         return true;
     default:
         return false;
@@ -110,7 +117,11 @@
         if (*endptr == '\0') {
             defaultQuality = (src_quality) l;
             ALOGD("forcing AudioResampler quality to %d", defaultQuality);
+#ifdef QTI_RESAMPLER
+            if (defaultQuality < DEFAULT_QUALITY || defaultQuality > QTI_QUALITY) {
+#else
             if (defaultQuality < DEFAULT_QUALITY || defaultQuality > DYN_HIGH_QUALITY) {
+#endif
                 defaultQuality = DEFAULT_QUALITY;
             }
         }
@@ -129,6 +140,9 @@
     case HIGH_QUALITY:
         return 20;
     case VERY_HIGH_QUALITY:
+#ifdef QTI_RESAMPLER
+    case QTI_QUALITY: //for QTI_QUALITY, currently assuming same as VHQ
+#endif
         return 34;
     case DYN_LOW_QUALITY:
         return 4;
@@ -204,6 +218,11 @@
         case DYN_HIGH_QUALITY:
             quality = DYN_MED_QUALITY;
             break;
+#ifdef QTI_RESAMPLER
+        case QTI_QUALITY:
+            quality = DYN_HIGH_QUALITY;
+            break;
+#endif
         }
     }
     pthread_mutex_unlock(&mutex);
@@ -250,6 +269,12 @@
             }
         }
         break;
+#ifdef QTI_RESAMPLER
+    case QTI_QUALITY:
+        ALOGV("Create QTI_QUALITY Resampler = %d",quality);
+        resampler = new AudioResamplerQTI(format, inChannelCount, sampleRate);
+        break;
+#endif
     }
 
     // initialize resampler
diff --git a/services/audioflinger/AudioResampler.h b/services/audioflinger/AudioResampler.h
index a8e3e6f..6669a85 100644
--- a/services/audioflinger/AudioResampler.h
+++ b/services/audioflinger/AudioResampler.h
@@ -47,6 +47,9 @@
         DYN_LOW_QUALITY=5,
         DYN_MED_QUALITY=6,
         DYN_HIGH_QUALITY=7,
+#ifdef QTI_RESAMPLER
+        QTI_QUALITY=8,
+#endif
     };
 
     static const CONSTEXPR float UNITY_GAIN_FLOAT = 1.0f;
diff --git a/services/audioflinger/AudioResamplerQTI.cpp b/services/audioflinger/AudioResamplerQTI.cpp
new file mode 100644
index 0000000..44b741e
--- /dev/null
+++ b/services/audioflinger/AudioResamplerQTI.cpp
@@ -0,0 +1,168 @@
+/*
+ * Copyright (C) 2014, The Linux Foundation. All rights reserved.
+ * Not a Contribution.
+ * 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.
+ */
+
+#include "AudioResamplerQTI.h"
+#include "QCT_Resampler.h"
+#include <sys/time.h>
+#include <audio_utils/primitives.h>
+
+namespace android {
+AudioResamplerQTI::AudioResamplerQTI(int format,
+        int inChannelCount, int32_t sampleRate)
+    :AudioResampler(inChannelCount, sampleRate, QTI_QUALITY),
+    mOutFrameCount(0), mTmpBuf(0), mResamplerOutBuf(0), mFrameIndex(0)
+{
+    stateSize = QCT_Resampler::MemAlloc(format, inChannelCount, sampleRate, sampleRate);
+    mState = new int16_t[stateSize];
+    mVolume[0] = mVolume[1] = 0;
+    mBuffer.frameCount = 0;
+}
+
+AudioResamplerQTI::~AudioResamplerQTI()
+{
+    if (mState) {
+        delete [] mState;
+    }
+    if (mTmpBuf) {
+        delete [] mTmpBuf;
+    }
+    if(mResamplerOutBuf) {
+        delete [] mResamplerOutBuf;
+    }
+}
+
+size_t AudioResamplerQTI::resample(int32_t* out, size_t outFrameCount,
+            AudioBufferProvider* provider)
+{
+    int16_t vl = mVolume[0];
+    int16_t vr = mVolume[1];
+    int16_t *pBuf;
+
+    size_t inFrameRequest;
+    size_t inFrameCount = getNumInSample(outFrameCount);
+    size_t index = 0;
+    size_t frameIndex = mFrameIndex;
+    size_t out_count = outFrameCount * 2;
+    float *fout = reinterpret_cast<float *>(out);
+
+    if (mChannelCount == 1) {
+        inFrameRequest = inFrameCount;
+    } else {
+        inFrameRequest = inFrameCount * 2;
+    }
+
+    if (mOutFrameCount < outFrameCount) {
+        mOutFrameCount = outFrameCount;
+        if (mTmpBuf) {
+            delete [] mTmpBuf;
+        }
+        if(mResamplerOutBuf) {
+            delete [] mResamplerOutBuf;
+        }
+        mTmpBuf = new int16_t[inFrameRequest + 16];
+        mResamplerOutBuf = new int32_t[out_count];
+    }
+
+    if (mChannelCount == 1) {
+        // buffer is empty, fetch a new one
+        while (index < inFrameCount) {
+            if (!mBuffer.frameCount) {
+                mBuffer.frameCount = inFrameCount;
+                provider->getNextBuffer(&mBuffer);
+                frameIndex = 0;
+            }
+
+            if (mBuffer.raw == NULL) {
+                while (index < inFrameCount) {
+                    mTmpBuf[index++] = 0;
+                }
+                QCT_Resampler::Resample90dB(mState, mTmpBuf, mResamplerOutBuf, inFrameCount, outFrameCount);
+                goto resample_exit;
+            }
+
+            mTmpBuf[index++] = clamp16_from_float(*((float *)mBuffer.raw + frameIndex++));
+
+            if (frameIndex >= mBuffer.frameCount) {
+                provider->releaseBuffer(&mBuffer);
+            }
+        }
+
+        QCT_Resampler::Resample90dB(mState, mTmpBuf, mResamplerOutBuf, inFrameCount, outFrameCount);
+    } else {
+        pBuf = &mTmpBuf[inFrameCount];
+        // buffer is empty, fetch a new one
+        while (index < inFrameCount) {
+            if (!mBuffer.frameCount) {
+                mBuffer.frameCount = inFrameCount;
+                provider->getNextBuffer(&mBuffer);
+                frameIndex = 0;
+            }
+            if (mBuffer.raw == NULL) {
+                while (index < inFrameCount) {
+                    mTmpBuf[index] = 0;
+                    pBuf[index++] = 0;
+                }
+                QCT_Resampler::Resample90dB(mState, mTmpBuf, mResamplerOutBuf, inFrameCount, outFrameCount);
+                goto resample_exit;
+            }
+
+            mTmpBuf[index] = clamp16_from_float(*((float *)mBuffer.raw + frameIndex++));
+            pBuf[index++] = clamp16_from_float(*((float *)mBuffer.raw + frameIndex++));
+            if (frameIndex >= mBuffer.frameCount * 2) {
+                provider->releaseBuffer(&mBuffer);
+            }
+       }
+
+       QCT_Resampler::Resample90dB(mState, mTmpBuf, mResamplerOutBuf, inFrameCount, outFrameCount);
+    }
+
+resample_exit:
+    for (int i = 0; i < out_count; i += 2) {
+        fout[i] += float_from_q4_27(mResamplerOutBuf[i] * vl);
+        fout[i+1] += float_from_q4_27(mResamplerOutBuf[i+1] * vr);
+    }
+
+    mFrameIndex = frameIndex;
+    return index;
+}
+
+void AudioResamplerQTI::setSampleRate(int32_t inSampleRate)
+{
+    if (mInSampleRate != inSampleRate) {
+        mInSampleRate = inSampleRate;
+        init();
+    }
+}
+
+void AudioResamplerQTI::init()
+{
+    QCT_Resampler::Init(mState, mChannelCount, mInSampleRate, mSampleRate);
+}
+
+size_t AudioResamplerQTI::getNumInSample(size_t outFrameCount)
+{
+    size_t size = (size_t)QCT_Resampler::GetNumInSamp(mState, outFrameCount);
+    return size;
+}
+
+void AudioResamplerQTI::reset()
+{
+    AudioResampler::reset();
+}
+
+}; // namespace android
diff --git a/services/audioflinger/AudioResamplerQTI.h b/services/audioflinger/AudioResamplerQTI.h
new file mode 100644
index 0000000..0b30a9f
--- /dev/null
+++ b/services/audioflinger/AudioResamplerQTI.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2014, The Linux Foundation. All rights reserved.
+ * Not a Contribution.
+ * 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.
+ */
+
+#include <stdint.h>
+#include <sys/types.h>
+#include <cutils/log.h>
+
+#include "AudioResampler.h"
+
+namespace android {
+// ----------------------------------------------------------------------------
+
+class AudioResamplerQTI : public AudioResampler {
+public:
+    AudioResamplerQTI(int format, int inChannelCount, int32_t sampleRate);
+    ~AudioResamplerQTI();
+    size_t resample(int32_t* out, size_t outFrameCount,
+                  AudioBufferProvider* provider);
+    void setSampleRate(int32_t inSampleRate);
+    size_t getNumInSample(size_t outFrameCount);
+
+    int16_t *mState;
+    int16_t *mTmpBuf;
+    int32_t *mResamplerOutBuf;
+    size_t mFrameIndex;
+    size_t stateSize;
+    size_t mOutFrameCount;
+
+    static const int kNumTmpBufSize = 1024;
+
+    void init();
+    void reset();
+};
+
+// ----------------------------------------------------------------------------
+}; // namespace android
+
diff --git a/services/audioflinger/BufferProviders.cpp b/services/audioflinger/BufferProviders.cpp
index a8be206..434a514 100644
--- a/services/audioflinger/BufferProviders.cpp
+++ b/services/audioflinger/BufferProviders.cpp
@@ -24,6 +24,7 @@
 #include <media/EffectsFactoryApi.h>
 
 #include <utils/Log.h>
+#include <media/stagefright/foundation/ADebug.h>
 
 #include "Configuration.h"
 #include "BufferProviders.h"
@@ -205,6 +206,7 @@
      const int downmixParamSize =
              sizeof(effect_param_t) + psizePadded + sizeof(downmix_type_t);
      effect_param_t * const param = (effect_param_t *) malloc(downmixParamSize);
+     CHECK(param != NULL);
      param->psize = sizeof(downmix_params_t);
      const downmix_params_t downmixParam = DOWNMIX_PARAM_TYPE;
      memcpy(param->data, &downmixParam, param->psize);
diff --git a/services/audioflinger/Effects.cpp b/services/audioflinger/Effects.cpp
index 949c91d..2249c6e 100644
--- a/services/audioflinger/Effects.cpp
+++ b/services/audioflinger/Effects.cpp
@@ -13,6 +13,25 @@
 ** 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.
+**
+** This file was modified by Dolby Laboratories, Inc. The portions of the
+** code that are surrounded by "DOLBY..." are copyrighted and
+** licensed separately, as follows:
+**
+**  (C) 2011-2015 Dolby Laboratories, Inc.
+**
+** 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.
+**
 */
 
 
@@ -318,6 +337,7 @@
 status_t AudioFlinger::EffectModule::configure()
 {
     status_t status;
+    status_t cmdStatus = 0;
     sp<ThreadBase> thread;
     uint32_t size;
     audio_channel_mask_t channelMask;
@@ -383,7 +403,6 @@
     ALOGV("configure() %p thread %p buffer %p framecount %d",
             this, thread.get(), mConfig.inputCfg.buffer.raw, mConfig.inputCfg.buffer.frameCount);
 
-    status_t cmdStatus;
     size = sizeof(int);
     status = (*mEffectInterface)->command(mEffectInterface,
                                                    EFFECT_CMD_SET_CONFIG,
@@ -434,7 +453,7 @@
     if (mEffectInterface == NULL) {
         return NO_INIT;
     }
-    status_t cmdStatus;
+    status_t cmdStatus = 0;
     uint32_t size = sizeof(status_t);
     status_t status = (*mEffectInterface)->command(mEffectInterface,
                                                    EFFECT_CMD_INIT,
@@ -476,7 +495,7 @@
     if (mStatus != NO_ERROR) {
         return mStatus;
     }
-    status_t cmdStatus;
+    status_t cmdStatus = 0;
     uint32_t size = sizeof(status_t);
     status_t status = (*mEffectInterface)->command(mEffectInterface,
                                                    EFFECT_CMD_ENABLE,
@@ -677,7 +696,7 @@
     if (isProcessEnabled() &&
             ((mDescriptor.flags & EFFECT_FLAG_VOLUME_MASK) == EFFECT_FLAG_VOLUME_CTRL ||
             (mDescriptor.flags & EFFECT_FLAG_VOLUME_MASK) == EFFECT_FLAG_VOLUME_IND)) {
-        status_t cmdStatus;
+        status_t cmdStatus = 0;
         uint32_t volume[2];
         uint32_t *pVolume = NULL;
         uint32_t size = sizeof(volume);
@@ -712,7 +731,7 @@
     }
     status_t status = NO_ERROR;
     if ((mDescriptor.flags & EFFECT_FLAG_DEVICE_MASK) == EFFECT_FLAG_DEVICE_IND) {
-        status_t cmdStatus;
+        status_t cmdStatus = 0;
         uint32_t size = sizeof(status_t);
         uint32_t cmd = audio_is_output_devices(device) ? EFFECT_CMD_SET_DEVICE :
                             EFFECT_CMD_SET_INPUT_DEVICE;
@@ -734,7 +753,7 @@
     }
     status_t status = NO_ERROR;
     if ((mDescriptor.flags & EFFECT_FLAG_AUDIO_MODE_MASK) == EFFECT_FLAG_AUDIO_MODE_IND) {
-        status_t cmdStatus;
+        status_t cmdStatus = 0;
         uint32_t size = sizeof(status_t);
         status = (*mEffectInterface)->command(mEffectInterface,
                                               EFFECT_CMD_SET_AUDIO_MODE,
@@ -770,6 +789,9 @@
 
 void AudioFlinger::EffectModule::setSuspended(bool suspended)
 {
+#ifdef DOLBY_ENABLE
+    EffectDapController::instance()->effectSuspended(this, suspended);
+#endif // DOLBY_END
     Mutex::Autolock _l(mLock);
     mSuspended = suspended;
 }
@@ -1113,7 +1135,8 @@
         mEnabled = false;
     } else {
         if (thread != 0) {
-            if (thread->type() == ThreadBase::OFFLOAD) {
+            if ((thread->type() == ThreadBase::OFFLOAD) ||
+                (thread->type() == ThreadBase::DIRECT && thread->mIsDirectPcm)) {
                 PlaybackThread *t = (PlaybackThread *)thread.get();
                 Mutex::Autolock _l(t->mLock);
                 t->broadcast_l();
@@ -1583,8 +1606,12 @@
         ALOGV("addEffect_l() effect %p, added in chain %p at rank %d", effect.get(), this,
                 idx_insert);
     }
+#ifdef DOLBY_ENABLE
+    return effect->configure();
+#else // DOLBY_END
     effect->configure();
     return NO_ERROR;
+#endif // LINE_ADDED_BY_DOLBY
 }
 
 // removeEffect_l() must be called with PlaybackThread::mLock held
@@ -1614,6 +1641,11 @@
             mEffects.removeAt(i);
             ALOGV("removeEffect_l() effect %p, removed from chain %p at rank %d", effect.get(),
                     this, i);
+#ifdef DOLBY_ENABLE
+            if (effect->suspended() && EffectDapController::instance()->isDapEffect(effect)) {
+                effect->setSuspended(false);
+            }
+#endif // DOLBY_END
             break;
         }
     }
diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp
index f586291..3406260 100644
--- a/services/audioflinger/Threads.cpp
+++ b/services/audioflinger/Threads.cpp
@@ -13,6 +13,25 @@
 ** 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.
+**
+** This file was modified by Dolby Laboratories, Inc. The portions of the
+** code that are surrounded by "DOLBY..." are copyrighted and
+** licensed separately, as follows:
+**
+**  (C) 2011-2015 Dolby Laboratories, Inc.
+**
+** 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.
+**
 */
 
 
@@ -544,6 +563,7 @@
         mSystemReady(systemReady)
 {
     memset(&mPatch, 0, sizeof(struct audio_patch));
+    mIsDirectPcm = false;
 }
 
 AudioFlinger::ThreadBase::~ThreadBase()
@@ -1154,7 +1174,8 @@
 
     // Reject any effect on Direct output threads for now, since the format of
     // mSinkBuffer is not guaranteed to be compatible with effect processing (PCM 16 stereo).
-    if (mType == DIRECT) {
+    // Exception: allow effects for Direct PCM
+    if (mType == DIRECT && !mIsDirectPcm) {
         ALOGW("createEffect_l() Cannot add effect %s on Direct output type thread %s",
                 desc->name, mThreadName);
         lStatus = BAD_VALUE;
@@ -1171,12 +1192,17 @@
     }
 
     // Allow global effects only on offloaded and mixer threads
+    // Exception: allow effects for Direct PCM
     if (sessionId == AUDIO_SESSION_OUTPUT_MIX) {
         switch (mType) {
         case MIXER:
         case OFFLOAD:
             break;
         case DIRECT:
+            if (mIsDirectPcm) {
+                // Allow effects when direct PCM enabled on Direct output
+                break;
+            }
         case DUPLICATING:
         case RECORD:
         default:
@@ -1229,7 +1255,13 @@
             if (lStatus != NO_ERROR) {
                 goto Exit;
             }
-            effect->setOffloaded(mType == OFFLOAD, mId);
+
+            bool setVal = false;
+            if (mType == OFFLOAD || (mType == DIRECT && mIsDirectPcm)) {
+                setVal = true;
+            }
+
+            effect->setOffloaded(setVal, mId);
 
             lStatus = chain->addEffect_l(effect);
             if (lStatus != NO_ERROR) {
@@ -1241,6 +1273,9 @@
             effect->setDevice(mInDevice);
             effect->setMode(mAudioFlinger->getMode());
             effect->setAudioSource(mAudioSource);
+#ifdef DOLBY_ENABLE
+            EffectDapController::instance()->effectCreated(effect, this);
+#endif // DOLBY_END
         }
         // create effect handle and connect it to effect module
         handle = new EffectHandle(effect, client, effectClient, priority);
@@ -1313,7 +1348,13 @@
         return BAD_VALUE;
     }
 
-    effect->setOffloaded(mType == OFFLOAD, mId);
+    bool setval = false;
+
+    if ((mType == OFFLOAD) || (mType == DIRECT && mIsDirectPcm)) {
+        setval = true;
+    }
+
+    effect->setOffloaded(setval, mId);
 
     status_t status = chain->addEffect_l(effect);
     if (status != NO_ERROR) {
@@ -1327,6 +1368,9 @@
     effect->setDevice(mInDevice);
     effect->setMode(mAudioFlinger->getMode());
     effect->setAudioSource(mAudioSource);
+#ifdef DOLBY_ENABLE
+    EffectDapController::instance()->updateOffload(this);
+#endif // DOLBY_END
     return NO_ERROR;
 }
 
@@ -2443,6 +2487,9 @@
             bytesWritten = framesWritten;
         }
         mLatchDValid = false;
+#ifdef DOLBY_ENABLE
+        EffectDapController::instance()->dumpBuffer((char *)mSinkBuffer + offset, count);
+#endif // DOLBY_END
         status_t status = mNormalSink->getTimestamp(mLatchD.mTimestamp);
         if (status == NO_ERROR) {
             size_t totalFramesWritten = mNormalSink->framesWritten();
@@ -2506,6 +2553,10 @@
             track->invalidate();
         }
     }
+#ifdef DOLBY_ENABLE // DOLBY_DAP_PREGAIN
+    // When a thread is closed set associated volume to 0
+    EffectDapController::instance()->updatePregain(mType, mOutput->flags, 0);
+#endif // DOLBY_END
 }
 
 /*
@@ -2840,6 +2891,13 @@
             }
             // mMixerStatusIgnoringFastTracks is also updated internally
             mMixerStatus = prepareTracks_l(&tracksToRemove);
+#ifdef DOLBY_ENABLE // DOLBY_DAP_PREGAIN
+            // If there are no active tracks, then reset volume to zero for this thread.
+            if (mMixerStatus == MIXER_IDLE) {
+                ALOGV("EffectDapController: Reset volumes to zeros for threadType = %d flags = %d", mType, mOutput->flags);
+                EffectDapController::instance()->updatePregain(mType, mOutput->flags, 0);
+            }
+#endif // DOLBY_END
 
             // compare with previously applied list
             if (lastGeneration != mActiveTracksGeneration) {
@@ -3662,6 +3720,10 @@
 
     float masterVolume = mMasterVolume;
     bool masterMute = mMasterMute;
+#ifdef DOLBY_ENABLE // DOLBY_DAP_PREGAIN
+    // The maximum volume of left channel and right channel for pregain calculation.
+    uint32_t max_vol = 0;
+#endif // DOLBY_END
 
     if (masterMute) {
         masterVolume = 0;
@@ -3999,6 +4061,12 @@
                 }
                 track->mHasVolumeController = false;
             }
+#ifdef DOLBY_ENABLE // DOLBY_DAP_PREGAIN
+            // Select the maximum volume by scanning all the active audio tracks but not the output one.
+            if (!track->isOutputTrack()) {
+                max_vol = max(max_vol, max(vl, vr));
+            }
+#endif // DOLBY_END
 
             // XXX: these things DON'T need to be done each time
             mAudioMixer->setBufferProvider(name, track);
@@ -4116,6 +4184,11 @@
                     if (track->isStopped()) {
                         track->reset();
                     }
+#ifdef DOLBY_ENABLE // DOLBY_UDC_VIRTUALIZE_AUDIO
+                    // Since this track is being removed from active tracks, check if we
+                    // should re-enable content processing in DAP.
+                    EffectDapController::instance()->trackStateChanged(track->mId, track->mState);
+#endif // DOLBY_END
                     tracksToRemove->add(track);
                 }
             } else {
@@ -4226,6 +4299,18 @@
     if (fastTracks > 0) {
         mixerStatus = MIXER_TRACKS_READY;
     }
+#ifdef DOLBY_ENABLE
+    // DOLBY_DAP_BYPASS_SOUND_TYPES
+    EffectDapController::instance()->checkForBypass(mActiveTracks, mOutput->flags);
+    // DOLBY_DAP_PREGAIN
+    // Skip the DS pregain setting if there're no active tracks, or all the active tracks are pausing ones,
+    // so that the last pregain will be adopted and zero volume level will not be sent in the 2 cases above.
+    if (mMixerStatusIgnoringFastTracks == MIXER_TRACKS_READY) {
+        EffectDapController::instance()->updatePregain(mType, mOutput->flags, max_vol);
+    }
+    // DOLBY_AUDIO_DUMP
+    EffectDapController::instance()->checkDumpEnable();
+#endif // DOLBY_END
     return mixerStatus;
 }
 
@@ -4493,6 +4578,10 @@
             if (mOutput->stream->set_volume) {
                 mOutput->stream->set_volume(mOutput->stream, left, right);
             }
+#ifdef DOLBY_ENABLE // DOLBY_DAP_PREGAIN
+            // Update the volume set for the current thread
+            EffectDapController::instance()->updatePregain(mType, mOutput->flags, max(vl, vr));
+#endif // DOLBY_END
         }
     }
 }
@@ -5295,6 +5384,8 @@
     } else {
         if (mMixerBufferValid) {
             memset(mMixerBuffer, 0, mMixerBufferSize);
+        } else if (mEffectBufferValid) {
+            memset(mEffectBuffer, 0, mEffectBufferSize);
         } else {
             memset(mSinkBuffer, 0, mSinkBufferSize);
         }
@@ -5316,7 +5407,11 @@
     } else if (mBytesWritten != 0) {
         if (mMixerStatus == MIXER_TRACKS_ENABLED) {
             writeFrames = mNormalFrameCount;
-            memset(mSinkBuffer, 0, mSinkBufferSize);
+            if (mMixerBufferValid) {
+                memset(mMixerBuffer, 0, mMixerBufferSize);
+            } else {
+                memset(mSinkBuffer, 0, mSinkBufferSize);
+            }
         } else {
             // flush remaining overflow buffers in output tracks
             writeFrames = 0;
diff --git a/services/audioflinger/Threads.h b/services/audioflinger/Threads.h
index 46ac300..9e32ea1 100644
--- a/services/audioflinger/Threads.h
+++ b/services/audioflinger/Threads.h
@@ -457,6 +457,7 @@
                 static const size_t     kLogSize = 4 * 1024;
                 sp<NBLog::Writer>       mNBLogWriter;
                 bool                    mSystemReady;
+                bool                    mIsDirectPcm; // flag to indicate unique Direct thread
 };
 
 // --- PlaybackThread ---
diff --git a/services/audioflinger/Tracks.cpp b/services/audioflinger/Tracks.cpp
index b3fac0b..a95801a 100644
--- a/services/audioflinger/Tracks.cpp
+++ b/services/audioflinger/Tracks.cpp
@@ -13,6 +13,25 @@
 ** 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.
+ *
+ * This file was modified by Dolby Laboratories, Inc. The portions of the
+ * code that are surrounded by "DOLBY..." are copyrighted and
+ * licensed separately, as follows:
+ *
+ *  (C) 2014-2015 Dolby Laboratories, Inc.
+ *
+ * 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.
+ *
 */
 
 
@@ -24,6 +43,7 @@
 #include <math.h>
 #include <sys/syscall.h>
 #include <utils/Log.h>
+#include <media/stagefright/foundation/ADebug.h>
 
 #include <private/media/AudioTrackShared.h>
 
@@ -37,6 +57,10 @@
 #include <media/nbaio/Pipe.h>
 #include <media/nbaio/PipeReader.h>
 #include <audio_utils/minifloat.h>
+#ifdef DOLBY_ENABLE // DOLBY_UDC_VIRTUALIZE_AUDIO
+#include <media/AudioParameter.h>
+#include "ds_config.h"
+#endif // DOLBY_END
 
 // ----------------------------------------------------------------------------
 
@@ -459,6 +483,9 @@
     if (mSharedBuffer != 0) {
         mSharedBuffer.clear();
     }
+#ifdef DOLBY_ENABLE // DOLBY_UDC_VIRTUALIZE_AUDIO
+    EffectDapController::instance()->trackDestroyed(mId);
+#endif // DOLBY_END
 }
 
 status_t AudioFlinger::PlaybackThread::Track::initCheck() const
@@ -706,6 +733,14 @@
                 mState = state;
             }
         }
+#ifdef DOLBY_ENABLE // DOLBY_UDC_VIRTUALIZE_AUDIO
+        if (mState != state) {
+            // This call will disable content processing in global DAP if this track
+            // is carrying processed audio. The content processing will be re-enabled
+            // when this track has been exhausted by MixerThread::prepareTracks_l()
+            EffectDapController::instance()->trackStateChanged(mId, mState);
+        }
+#endif // DOLBY_END
         // track was already in the active list, not a problem
         if (status == ALREADY_EXISTS) {
             status = NO_ERROR;
@@ -870,6 +905,22 @@
 
 status_t AudioFlinger::PlaybackThread::Track::setParameters(const String8& keyValuePairs)
 {
+#ifdef DOLBY_ENABLE // DOLBY_UDC_VIRTUALIZE_AUDIO
+    AudioParameter ap(keyValuePairs);
+    int value = 0;
+    if (ap.getInt(String8(DOLBY_PARAM_PROCESSED_AUDIO), value) == NO_ERROR) {
+        if (value) {
+            // Bypass content processing if processed audio is flowing through this track.
+            ALOGI("%s(): Marking track %d as containing processed audio", __FUNCTION__, mId);
+            EffectDapController::instance()->trackContainsProcessedAudio(mId, mState);
+        } else {
+            // Remove the track if it is no longer carrying processed audio.
+            ALOGI("%s(): Clearing track %d processed audio mark", __FUNCTION__, mId);
+            EffectDapController::instance()->trackDestroyed(mId);
+        }
+        return NO_ERROR;
+    }
+#endif // DOLBY_END
     sp<ThreadBase> thread = mThread.promote();
     if (thread == 0) {
         ALOGE("thread is dead");
@@ -931,6 +982,14 @@
 
 status_t AudioFlinger::PlaybackThread::Track::attachAuxEffect(int EffectId)
 {
+#ifdef DOLBY_ENABLE // DOLBY_UDC_VIRTUALIZE_AUDIO
+    // The track contains processed audio if EffectId is DOLBY_PROCESSED_AUDIO_EFFECT_ID
+    if (EffectId == DOLBY_PROCESSED_AUDIO_EFFECT_ID) {
+        ALOGI("%s(): Marking track %d as containing processed audio", __FUNCTION__, mId);
+        EffectDapController::instance()->trackContainsProcessedAudio(mId, mState);
+        return NO_ERROR;
+    }
+#endif // DOLBY_END
     status_t status = DEAD_OBJECT;
     sp<ThreadBase> thread = mThread.promote();
     if (thread != 0) {
@@ -1774,6 +1833,7 @@
             if (mBufferQueue.size() < kMaxOverFlowBuffers) {
                 pInBuffer = new Buffer;
                 pInBuffer->mBuffer = malloc(inBuffer.frameCount * mFrameSize);
+                CHECK(pInBuffer->mBuffer != NULL);
                 pInBuffer->frameCount = inBuffer.frameCount;
                 pInBuffer->raw = pInBuffer->mBuffer;
                 memcpy(pInBuffer->raw, inBuffer.raw, inBuffer.frameCount * mFrameSize);
diff --git a/services/audiopolicy/common/managerdefinitions/Android.mk b/services/audiopolicy/common/managerdefinitions/Android.mk
index 8728ff3..8c6a53c 100644
--- a/services/audiopolicy/common/managerdefinitions/Android.mk
+++ b/services/audiopolicy/common/managerdefinitions/Android.mk
@@ -31,6 +31,27 @@
 LOCAL_EXPORT_C_INCLUDE_DIRS := \
     $(LOCAL_PATH)/include
 
+ifeq ($(call is-vendor-board-platform,QCOM),true)
+ifeq ($(strip $(AUDIO_FEATURE_ENABLED_FLAC_OFFLOAD)),true)
+LOCAL_CFLAGS     += -DFLAC_OFFLOAD_ENABLED
+endif
+ifeq ($(strip $(AUDIO_FEATURE_ENABLED_PROXY_DEVICE)),true)
+LOCAL_CFLAGS     += -DAUDIO_EXTN_AFE_PROXY_ENABLED
+endif
+ifeq ($(strip $(AUDIO_FEATURE_ENABLED_WMA_OFFLOAD)),true)
+LOCAL_CFLAGS     += -DWMA_OFFLOAD_ENABLED
+endif
+ifeq ($(strip $(AUDIO_FEATURE_ENABLED_ALAC_OFFLOAD)),true)
+LOCAL_CFLAGS     += -DALAC_OFFLOAD_ENABLED
+endif
+ifeq ($(strip $(AUDIO_FEATURE_ENABLED_APE_OFFLOAD)),true)
+LOCAL_CFLAGS     += -DAPE_OFFLOAD_ENABLED
+endif
+ifeq ($(strip $(AUDIO_FEATURE_ENABLED_AAC_ADTS_OFFLOAD)),true)
+LOCAL_CFLAGS     += -DAAC_ADTS_OFFLOAD_ENABLED
+endif
+endif
+
 LOCAL_MODULE := libaudiopolicycomponents
 
 include $(BUILD_STATIC_LIBRARY)
diff --git a/services/audiopolicy/common/managerdefinitions/include/AudioOutputDescriptor.h b/services/audiopolicy/common/managerdefinitions/include/AudioOutputDescriptor.h
index 50f622d..e1c2999 100644
--- a/services/audiopolicy/common/managerdefinitions/include/AudioOutputDescriptor.h
+++ b/services/audiopolicy/common/managerdefinitions/include/AudioOutputDescriptor.h
@@ -72,6 +72,7 @@
     sp<AudioPort>       mPort;
     audio_devices_t mDevice;                   // current device this output is routed to
     audio_patch_handle_t mPatchHandle;
+    audio_io_handle_t mIoHandle;           // output handle
     uint32_t mRefCount[AUDIO_STREAM_CNT]; // number of streams of each type using this output
     nsecs_t mStopTime[AUDIO_STREAM_CNT];
     float mCurVolume[AUDIO_STREAM_CNT];   // current stream volume in dB
@@ -116,7 +117,6 @@
     virtual void toAudioPort(struct audio_port *port) const;
 
     const sp<IOProfile> mProfile;          // I/O profile this output derives from
-    audio_io_handle_t mIoHandle;           // output handle
     uint32_t mLatency;                  //
     audio_output_flags_t mFlags;   //
     AudioMix *mPolicyMix;             // non NULL when used by a dynamic policy
diff --git a/services/audiopolicy/common/managerdefinitions/include/ConfigParsingUtils.h b/services/audiopolicy/common/managerdefinitions/include/ConfigParsingUtils.h
index 78d2cdf..3cb61db 100644
--- a/services/audiopolicy/common/managerdefinitions/include/ConfigParsingUtils.h
+++ b/services/audiopolicy/common/managerdefinitions/include/ConfigParsingUtils.h
@@ -74,6 +74,9 @@
     STRING_TO_ENUM(AUDIO_DEVICE_OUT_FM),
     STRING_TO_ENUM(AUDIO_DEVICE_OUT_AUX_LINE),
     STRING_TO_ENUM(AUDIO_DEVICE_OUT_IP),
+#ifdef AUDIO_EXTN_AFE_PROXY_ENABLED
+    STRING_TO_ENUM(AUDIO_DEVICE_OUT_PROXY),
+#endif
     STRING_TO_ENUM(AUDIO_DEVICE_IN_AMBIENT),
     STRING_TO_ENUM(AUDIO_DEVICE_IN_BUILTIN_MIC),
     STRING_TO_ENUM(AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET),
@@ -153,6 +156,7 @@
 
 const StringToEnum sOutputFlagNameToEnumTable[] = {
     STRING_TO_ENUM(AUDIO_OUTPUT_FLAG_DIRECT),
+    STRING_TO_ENUM(AUDIO_OUTPUT_FLAG_DIRECT_PCM),
     STRING_TO_ENUM(AUDIO_OUTPUT_FLAG_PRIMARY),
     STRING_TO_ENUM(AUDIO_OUTPUT_FLAG_FAST),
     STRING_TO_ENUM(AUDIO_OUTPUT_FLAG_DEEP_BUFFER),
@@ -162,6 +166,7 @@
     STRING_TO_ENUM(AUDIO_OUTPUT_FLAG_TTS),
     STRING_TO_ENUM(AUDIO_OUTPUT_FLAG_RAW),
     STRING_TO_ENUM(AUDIO_OUTPUT_FLAG_SYNC),
+    STRING_TO_ENUM(AUDIO_OUTPUT_FLAG_VOIP_RX),
 };
 
 const StringToEnum sInputFlagNameToEnumTable[] = {
@@ -198,6 +203,33 @@
     STRING_TO_ENUM(AUDIO_FORMAT_E_AC3),
     STRING_TO_ENUM(AUDIO_FORMAT_DTS),
     STRING_TO_ENUM(AUDIO_FORMAT_DTS_HD),
+#ifdef FLAC_OFFLOAD_ENABLED
+    STRING_TO_ENUM(AUDIO_FORMAT_FLAC),
+#endif
+#ifdef WMA_OFFLOAD_ENABLED
+    STRING_TO_ENUM(AUDIO_FORMAT_WMA),
+    STRING_TO_ENUM(AUDIO_FORMAT_WMA_PRO),
+#endif
+    STRING_TO_ENUM(AUDIO_FORMAT_PCM_16_BIT_OFFLOAD),
+    STRING_TO_ENUM(AUDIO_FORMAT_PCM_24_BIT_OFFLOAD),
+#ifdef ALAC_OFFLOAD_ENABLED
+    STRING_TO_ENUM(AUDIO_FORMAT_ALAC),
+#endif
+#ifdef APE_OFFLOAD_ENABLED
+    STRING_TO_ENUM(AUDIO_FORMAT_APE),
+#endif
+#ifdef AAC_ADTS_OFFLOAD_ENABLED
+    STRING_TO_ENUM(AUDIO_FORMAT_AAC_ADTS_MAIN),
+    STRING_TO_ENUM(AUDIO_FORMAT_AAC_ADTS_LC),
+    STRING_TO_ENUM(AUDIO_FORMAT_AAC_ADTS_SSR),
+    STRING_TO_ENUM(AUDIO_FORMAT_AAC_ADTS_LTP),
+    STRING_TO_ENUM(AUDIO_FORMAT_AAC_ADTS_HE_V1),
+    STRING_TO_ENUM(AUDIO_FORMAT_AAC_ADTS_SCALABLE),
+    STRING_TO_ENUM(AUDIO_FORMAT_AAC_ADTS_ERLC),
+    STRING_TO_ENUM(AUDIO_FORMAT_AAC_ADTS_LD),
+    STRING_TO_ENUM(AUDIO_FORMAT_AAC_ADTS_HE_V2),
+    STRING_TO_ENUM(AUDIO_FORMAT_AAC_ADTS_ELD),
+#endif
 };
 
 const StringToEnum sOutChannelsNameToEnumTable[] = {
@@ -206,12 +238,17 @@
     STRING_TO_ENUM(AUDIO_CHANNEL_OUT_QUAD),
     STRING_TO_ENUM(AUDIO_CHANNEL_OUT_5POINT1),
     STRING_TO_ENUM(AUDIO_CHANNEL_OUT_7POINT1),
+    STRING_TO_ENUM(AUDIO_CHANNEL_OUT_2POINT1),
+    STRING_TO_ENUM(AUDIO_CHANNEL_OUT_SURROUND),
+    STRING_TO_ENUM(AUDIO_CHANNEL_OUT_PENTA),
+    STRING_TO_ENUM(AUDIO_CHANNEL_OUT_6POINT1),
 };
 
 const StringToEnum sInChannelsNameToEnumTable[] = {
     STRING_TO_ENUM(AUDIO_CHANNEL_IN_MONO),
     STRING_TO_ENUM(AUDIO_CHANNEL_IN_STEREO),
     STRING_TO_ENUM(AUDIO_CHANNEL_IN_FRONT_BACK),
+    STRING_TO_ENUM(AUDIO_CHANNEL_IN_5POINT1),
 };
 
 const StringToEnum sIndexChannelsNameToEnumTable[] = {
diff --git a/services/audiopolicy/common/managerdefinitions/include/EffectDescriptor.h b/services/audiopolicy/common/managerdefinitions/include/EffectDescriptor.h
index c9783a1..396541b 100644
--- a/services/audiopolicy/common/managerdefinitions/include/EffectDescriptor.h
+++ b/services/audiopolicy/common/managerdefinitions/include/EffectDescriptor.h
@@ -21,6 +21,7 @@
 #include <utils/KeyedVector.h>
 #include <utils/RefBase.h>
 #include <utils/Errors.h>
+#include <utils/Thread.h>
 
 namespace android {
 
@@ -66,6 +67,8 @@
      * Maximum memory allocated to audio effects in KB
      */
     static const uint32_t MAX_EFFECTS_MEMORY = 512;
+
+    Mutex mLock;
 };
 
 }; // namespace android
diff --git a/services/audiopolicy/common/managerdefinitions/src/AudioOutputDescriptor.cpp b/services/audiopolicy/common/managerdefinitions/src/AudioOutputDescriptor.cpp
index a278375..5ddeaed 100644
--- a/services/audiopolicy/common/managerdefinitions/src/AudioOutputDescriptor.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/AudioOutputDescriptor.cpp
@@ -33,7 +33,7 @@
 
 AudioOutputDescriptor::AudioOutputDescriptor(const sp<AudioPort>& port,
                                              AudioPolicyClientInterface *clientInterface)
-    : mPort(port), mDevice(AUDIO_DEVICE_NONE),
+    : mPort(port), mDevice(AUDIO_DEVICE_NONE), mIoHandle(0),
       mPatchHandle(0), mClientInterface(clientInterface), mId(0)
 {
     // clear usage count for all stream types
@@ -223,7 +223,7 @@
 SwAudioOutputDescriptor::SwAudioOutputDescriptor(
         const sp<IOProfile>& profile, AudioPolicyClientInterface *clientInterface)
     : AudioOutputDescriptor(profile, clientInterface),
-    mProfile(profile), mIoHandle(0), mLatency(0),
+    mProfile(profile), mLatency(0),
     mFlags((audio_output_flags_t)0), mPolicyMix(NULL),
     mOutput1(0), mOutput2(0), mDirectOpenCount(0), mGlobalRefCount(0)
 {
diff --git a/services/audiopolicy/common/managerdefinitions/src/EffectDescriptor.cpp b/services/audiopolicy/common/managerdefinitions/src/EffectDescriptor.cpp
index 33d838d..6a0d079 100644
--- a/services/audiopolicy/common/managerdefinitions/src/EffectDescriptor.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/EffectDescriptor.cpp
@@ -56,6 +56,7 @@
                                                     int session,
                                                     int id)
 {
+    Mutex::Autolock _l(mLock);
     if (mTotalEffectsMemory + desc->memoryUsage > getMaxEffectsMemory()) {
         ALOGW("registerEffect() memory limit exceeded for Fx %s, Memory %d KB",
                 desc->name, desc->memoryUsage);
@@ -80,6 +81,7 @@
 
 status_t EffectDescriptorCollection::unregisterEffect(int id)
 {
+    Mutex::Autolock _l(mLock);
     ssize_t index = indexOfKey(id);
     if (index < 0) {
         ALOGW("unregisterEffect() unknown effect ID %d", id);
@@ -106,6 +108,7 @@
 
 status_t EffectDescriptorCollection::setEffectEnabled(int id, bool enabled)
 {
+    Mutex::Autolock _l(mLock);
     ssize_t index = indexOfKey(id);
     if (index < 0) {
         ALOGW("unregisterEffect() unknown effect ID %d", id);
@@ -148,6 +151,7 @@
 
 bool EffectDescriptorCollection::isNonOffloadableEffectEnabled()
 {
+    Mutex::Autolock _l(mLock);
     for (size_t i = 0; i < size(); i++) {
         sp<EffectDescriptor> effectDesc = valueAt(i);
         if (effectDesc->mEnabled && (effectDesc->mStrategy == STRATEGY_MEDIA) &&
@@ -172,6 +176,7 @@
 
 status_t EffectDescriptorCollection::dump(int fd)
 {
+    Mutex::Autolock _l(mLock);
     const size_t SIZE = 256;
     char buffer[SIZE];
 
diff --git a/services/audiopolicy/enginedefault/Android.mk b/services/audiopolicy/enginedefault/Android.mk
index 8d43b89..de84e96 100755
--- a/services/audiopolicy/enginedefault/Android.mk
+++ b/services/audiopolicy/enginedefault/Android.mk
@@ -31,6 +31,11 @@
     $(call include-path-for, bionic) \
     $(TOPDIR)frameworks/av/services/audiopolicy/common/include
 
+ifeq ($(call is-vendor-board-platform,QCOM),true)
+ifeq ($(strip $(AUDIO_FEATURE_ENABLED_PROXY_DEVICE)),true)
+LOCAL_CFLAGS += -DAUDIO_EXTN_AFE_PROXY_ENABLED
+endif
+endif
 
 LOCAL_MODULE := libaudiopolicyenginedefault
 LOCAL_MODULE_TAGS := optional
diff --git a/services/audiopolicy/enginedefault/src/Engine.cpp b/services/audiopolicy/enginedefault/src/Engine.cpp
index 0686414..8b4a085 100755
--- a/services/audiopolicy/enginedefault/src/Engine.cpp
+++ b/services/audiopolicy/enginedefault/src/Engine.cpp
@@ -408,9 +408,10 @@
                 if (device) break;
                 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_AUX_DIGITAL;
                 if (device) break;
-                device = availableOutputDevicesType & AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET;
-                if (device) break;
             }
+            // Allow voice call on USB ANLG DOCK headset
+            device = availableOutputDevicesType & AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET;
+            if (device) break;
             device = availableOutputDevicesType & AUDIO_DEVICE_OUT_EARPIECE;
             if (device) break;
             device = mApmObserver->getDefaultOutputDevice()->type();
@@ -450,6 +451,13 @@
             }
             break;
         }
+
+        if (isInCall() && (device == AUDIO_DEVICE_NONE)) {
+            // when in call, get the device for Phone strategy
+            device = getDeviceForStrategy(STRATEGY_PHONE);
+            break;
+        }
+
     break;
 
     case STRATEGY_SONIFICATION:
@@ -498,6 +506,13 @@
     case STRATEGY_REROUTING:
     case STRATEGY_MEDIA: {
         uint32_t device2 = AUDIO_DEVICE_NONE;
+
+        if (isInCall() && (device == AUDIO_DEVICE_NONE)) {
+            // when in call, get the device for Phone strategy
+            device = getDeviceForStrategy(STRATEGY_PHONE);
+            break;
+        }
+
         if (strategy != STRATEGY_SONIFICATION) {
             // no sonification on remote submix (e.g. WFD)
             if (availableOutputDevices.getDevice(AUDIO_DEVICE_OUT_REMOTE_SUBMIX, String8("0")) != 0) {
@@ -541,14 +556,23 @@
         if (device2 == AUDIO_DEVICE_NONE) {
             device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET;
         }
-        if ((device2 == AUDIO_DEVICE_NONE) && (strategy != STRATEGY_SONIFICATION)) {
+        if ((strategy != STRATEGY_SONIFICATION) && (device == AUDIO_DEVICE_NONE)
+            && (device2 == AUDIO_DEVICE_NONE)) {
             // no sonification on aux digital (e.g. HDMI)
             device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_AUX_DIGITAL;
         }
         if ((device2 == AUDIO_DEVICE_NONE) &&
-                (mForceUse[AUDIO_POLICY_FORCE_FOR_DOCK] == AUDIO_POLICY_FORCE_ANALOG_DOCK)) {
+                (mForceUse[AUDIO_POLICY_FORCE_FOR_DOCK] == AUDIO_POLICY_FORCE_ANALOG_DOCK)
+                && (strategy != STRATEGY_SONIFICATION)) {
             device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET;
         }
+#ifdef AUDIO_EXTN_AFE_PROXY_ENABLED
+        if ((strategy != STRATEGY_SONIFICATION) && (device == AUDIO_DEVICE_NONE)
+            && (device2 == AUDIO_DEVICE_NONE)) {
+            // no sonification on WFD sink
+            device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_PROXY;
+        }
+#endif
         if (device2 == AUDIO_DEVICE_NONE) {
             device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_SPEAKER;
         }
@@ -671,6 +695,8 @@
             device = AUDIO_DEVICE_IN_WIRED_HEADSET;
         } else if (availableDeviceTypes & AUDIO_DEVICE_IN_USB_DEVICE) {
             device = AUDIO_DEVICE_IN_USB_DEVICE;
+        } else if (availableDeviceTypes & AUDIO_DEVICE_IN_ANLG_DOCK_HEADSET) {
+            device = AUDIO_DEVICE_IN_ANLG_DOCK_HEADSET;
         } else if (availableDeviceTypes & AUDIO_DEVICE_IN_BUILTIN_MIC) {
             device = AUDIO_DEVICE_IN_BUILTIN_MIC;
         }
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
index 8419ed5..ba468e2 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
@@ -12,6 +12,24 @@
  * 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.
+ *
+ * This file was modified by Dolby Laboratories, Inc. The portions of the
+ * code that are surrounded by "DOLBY..." are copyrighted and
+ * licensed separately, as follows:
+ *
+ *  (C) 2014-2015 Dolby Laboratories, Inc.
+ *
+ * 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 "APM::AudioPolicyManager"
@@ -40,6 +58,9 @@
 #include "audio_policy_conf.h"
 #include <ConfigParsingUtils.h>
 #include <policy.h>
+#ifdef DOLBY_ENABLE
+#include "DolbyAudioPolicy_impl.h"
+#endif // DOLBY_END
 
 namespace android {
 
@@ -171,6 +192,11 @@
         }
 
         updateDevicesAndOutputs();
+#ifdef DOLBY_ENABLE // DOLBY_UDC
+        // Before closing the opened outputs, update endpoint property with device capabilities
+        audio_devices_t audioOutputDevice = getDeviceForStrategy(getStrategy(AUDIO_STREAM_MUSIC), true);
+        mDolbyAudioPolicy.setEndpointSystemProperty(audioOutputDevice, mHwModules);
+#endif // DOLBY_END
         if (mEngine->getPhoneState() == AUDIO_MODE_IN_CALL && hasPrimaryOutput()) {
             audio_devices_t newDevice = getNewOutputDevice(mPrimaryOutput, false /*fromCache*/);
             updateCallRouting(newDevice);
@@ -351,6 +377,14 @@
                                                 AUDIO_OUTPUT_FLAG_NONE,
                                                 AUDIO_FORMAT_INVALID);
         if (output != AUDIO_IO_HANDLE_NONE) {
+            // close active input (if any) before opening new input
+            audio_io_handle_t activeInput = mInputs.getActiveInput();
+            if (activeInput != 0) {
+                ALOGV("updateCallRouting() close active input before opening new input");
+                sp<AudioInputDescriptor> activeDesc = mInputs.valueFor(activeInput);
+                stopInput(activeInput, activeDesc->mSessions.itemAt(0));
+                releaseInput(activeInput, activeDesc->mSessions.itemAt(0));
+            }
             sp<SwAudioOutputDescriptor> outputDesc = mOutputs.valueFor(output);
             ALOG_ASSERT(!outputDesc->isDuplicated(),
                         "updateCallRouting() RX device output is duplicated");
@@ -588,7 +622,8 @@
     // only retain flags that will drive the direct output profile selection
     // if explicitly requested
     static const uint32_t kRelevantFlags =
-            (AUDIO_OUTPUT_FLAG_HW_AV_SYNC | AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD);
+            (AUDIO_OUTPUT_FLAG_HW_AV_SYNC | AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD |
+               AUDIO_OUTPUT_FLAG_VOIP_RX);
     flags =
         (audio_output_flags_t)((flags & kRelevantFlags) | AUDIO_OUTPUT_FLAG_DIRECT);
 
@@ -914,7 +949,23 @@
         addOutput(output, outputDesc);
         audio_io_handle_t dstOutput = getOutputForEffect();
         if (dstOutput == output) {
+#ifdef DOLBY_ENABLE
+            status_t status = mpClientInterface->moveEffects(AUDIO_SESSION_OUTPUT_MIX, srcOutput, dstOutput);
+            if (status == NO_ERROR) {
+                for (size_t i = 0; i < mEffects.size(); i++) {
+                    sp<EffectDescriptor> desc = mEffects.valueAt(i);
+                    if (desc->mSession == AUDIO_SESSION_OUTPUT_MIX) {
+                        // update the mIo member of EffectDescriptor for the global effect
+                        ALOGV("%s updating mIo", __FUNCTION__);
+                        desc->mIo = dstOutput;
+                    }
+                }
+            } else {
+                ALOGW("%s moveEffects from %d to %d failed", __FUNCTION__, srcOutput, dstOutput);
+            }
+#else // DOLBY_END
             mpClientInterface->moveEffects(AUDIO_SESSION_OUTPUT_MIX, srcOutput, dstOutput);
+#endif // LINE_ADDED_BY_DOLBY
         }
         mPreviousOutputs = mOutputs;
         ALOGV("getOutput() returns new direct output %d", output);
@@ -1051,6 +1102,26 @@
     if (delayMs != 0) {
         usleep(delayMs * 1000);
     }
+#ifdef DOLBY_ENABLE
+    // DOLBY_UDC
+    // It is observed that in some use-cases where multiple outputs are present eg. bluetooth and headphone,
+    // the output for particular stream type is decided in this routine. Hence we must call
+    // getDeviceForStrategy in order to get the current active output for this stream type and update
+    // the dolby system property.
+    if (stream == AUDIO_STREAM_MUSIC)
+    {
+        audio_devices_t audioOutputDevice = getDeviceForStrategy(getStrategy(AUDIO_STREAM_MUSIC), true);
+        mDolbyAudioPolicy.setEndpointSystemProperty(audioOutputDevice, mHwModules);
+    }
+    // DOLBY_DAP_MOVE_EFFECT
+    // Note: The global effect can't be taken away from the deep-buffered output (source output) if there're still
+    //       music playing on the deep-buffered output.
+    sp<SwAudioOutputDescriptor> srcOutputDesc = mOutputs.valueFor(mDolbyAudioPolicy.output());
+    if ((stream == AUDIO_STREAM_MUSIC) && mDolbyAudioPolicy.shouldMoveToOutput(output, outputDesc->mFlags) && srcOutputDesc != NULL &&
+        ((srcOutputDesc->mFlags & AUDIO_OUTPUT_FLAG_DEEP_BUFFER) == 0 || srcOutputDesc->mRefCount[AUDIO_STREAM_MUSIC] == 0)) {
+        mDolbyAudioPolicy.movedToOutput(mpClientInterface, output);
+    }
+#endif //DOLBY_END
 
     return status;
 }
@@ -1272,8 +1343,25 @@
             // output by default: move them back to the appropriate output.
             audio_io_handle_t dstOutput = getOutputForEffect();
             if (hasPrimaryOutput() && dstOutput != mPrimaryOutput->mIoHandle) {
+#ifdef DOLBY_ENABLE
+                status_t status = mpClientInterface->moveEffects(AUDIO_SESSION_OUTPUT_MIX,
+                                                                 mPrimaryOutput->mIoHandle, dstOutput);
+                if (status == NO_ERROR) {
+                    for (size_t i = 0; i < mEffects.size(); i++) {
+                        sp<EffectDescriptor> desc = mEffects.valueAt(i);
+                        if (desc->mSession == AUDIO_SESSION_OUTPUT_MIX) {
+                            // update the mIo member of EffectDescriptor for the global effect
+                            ALOGV("%s updating mIo", __FUNCTION__);
+                            desc->mIo = dstOutput;
+                        }
+                    }
+                } else {
+                    ALOGW("%s moveEffects from %d to %d failed", __FUNCTION__, mPrimaryOutput->mIoHandle, dstOutput);
+                }
+#else // DOLBY_END
                 mpClientInterface->moveEffects(AUDIO_SESSION_OUTPUT_MIX,
                                                mPrimaryOutput->mIoHandle, dstOutput);
+#endif // LINE_ADDED_BY_DOLBY
             }
             mpClientInterface->onAudioPortListUpdate();
         }
@@ -1336,6 +1424,12 @@
             ALOGW("getInputForAttr() could not find device for source %d", inputSource);
             return BAD_VALUE;
         }
+        // block request to open input on USB during voice call
+        if((AUDIO_MODE_IN_CALL == mEngine->getPhoneState()) &&
+            (device == AUDIO_DEVICE_IN_USB_DEVICE)) {
+            ALOGV("getInputForAttr(): blocking the request to open input on USB device");
+            return BAD_VALUE;
+        }
         if (policyMix != NULL) {
             address = policyMix->mRegistrationId;
             if (policyMix->mMixType == MIX_TYPE_RECORDERS) {
@@ -1356,20 +1450,6 @@
         } else {
             *inputType = API_INPUT_LEGACY;
         }
-        // adapt channel selection to input source
-        switch (inputSource) {
-        case AUDIO_SOURCE_VOICE_UPLINK:
-            channelMask = AUDIO_CHANNEL_IN_VOICE_UPLINK;
-            break;
-        case AUDIO_SOURCE_VOICE_DOWNLINK:
-            channelMask = AUDIO_CHANNEL_IN_VOICE_DNLINK;
-            break;
-        case AUDIO_SOURCE_VOICE_CALL:
-            channelMask = AUDIO_CHANNEL_IN_VOICE_UPLINK | AUDIO_CHANNEL_IN_VOICE_DNLINK;
-            break;
-        default:
-            break;
-        }
         if (inputSource == AUDIO_SOURCE_HOTWORD) {
             ssize_t index = mSoundTriggerSessions.indexOfKey(session);
             if (index >= 0) {
@@ -1773,6 +1853,7 @@
 
     audio_io_handle_t outputOffloaded = 0;
     audio_io_handle_t outputDeepBuffer = 0;
+    audio_io_handle_t outputDirectPcm = 0;
 
     for (size_t i = 0; i < outputs.size(); i++) {
         sp<SwAudioOutputDescriptor> desc = mOutputs.valueFor(outputs[i]);
@@ -1780,6 +1861,9 @@
         if ((desc->mFlags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) != 0) {
             outputOffloaded = outputs[i];
         }
+        if ((desc->mFlags & AUDIO_OUTPUT_FLAG_DIRECT_PCM) != 0) {
+            outputDirectPcm = outputs[i];
+        }
         if ((desc->mFlags & AUDIO_OUTPUT_FLAG_DEEP_BUFFER) != 0) {
             outputDeepBuffer = outputs[i];
         }
@@ -1790,6 +1874,9 @@
     if (outputOffloaded != 0) {
         return outputOffloaded;
     }
+    if (outputDirectPcm != 0) {
+        return outputDirectPcm;
+    }
     if (outputDeepBuffer != 0) {
         return outputDeepBuffer;
     }
@@ -1826,7 +1913,16 @@
             return INVALID_OPERATION;
         }
     }
+#ifdef DOLBY_ENABLE
+    status_t status = mEffects.registerEffect(desc, io, strategy, session, id);
+    if (status == NO_ERROR) {
+        sp<EffectDescriptor> effectDesc = mEffects.valueFor(id);
+        mDolbyAudioPolicy.effectRegistered(effectDesc);
+    }
+    return status;
+#else // DOLBY_END
     return mEffects.registerEffect(desc, io, strategy, session, id);
+#endif // LINE_ADDED_BY_DOLBY
 }
 
 bool AudioPolicyManager::isStreamActive(audio_stream_type_t stream, uint32_t inPastMs) const
@@ -3781,7 +3877,7 @@
 {
     audio_devices_t oldDevice = getDeviceForStrategy(strategy, true /*fromCache*/);
     audio_devices_t newDevice = getDeviceForStrategy(strategy, false /*fromCache*/);
-    SortedVector<audio_io_handle_t> srcOutputs = getOutputsForDevice(oldDevice, mPreviousOutputs);
+    SortedVector<audio_io_handle_t> srcOutputs = getOutputsForDevice(oldDevice, mOutputs);
     SortedVector<audio_io_handle_t> dstOutputs = getOutputsForDevice(newDevice, mOutputs);
 
     // also take into account external policy-related changes: add all outputs which are
@@ -3825,8 +3921,17 @@
                     if (moved.indexOf(effectDesc->mIo) < 0) {
                         ALOGV("checkOutputForStrategy() moving effect %d to output %d",
                               mEffects.keyAt(i), fxOutput);
+#ifdef DOLBY_ENABLE
+                        status_t status = mpClientInterface->moveEffects(AUDIO_SESSION_OUTPUT_MIX, effectDesc->mIo,
+                                                       fxOutput);
+                        if (status != NO_ERROR) {
+                            ALOGW("%s moveEffects from %d to %d failed", __FUNCTION__, effectDesc->mIo, fxOutput);
+                            continue;
+                        }
+#else // DOLBY_END
                         mpClientInterface->moveEffects(AUDIO_SESSION_OUTPUT_MIX, effectDesc->mIo,
                                                        fxOutput);
+#endif // LINE_ADDED_BY_DOLBY
                         moved.add(effectDesc->mIo);
                     }
                     effectDesc->mIo = fxOutput;
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.h b/services/audiopolicy/managerdefault/AudioPolicyManager.h
index bbdf396..a4af97f 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.h
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.h
@@ -12,6 +12,24 @@
  * 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.
+ *
+ * This file was modified by Dolby Laboratories, Inc. The portions of the
+ * code that are surrounded by "DOLBY..." are copyrighted and
+ * licensed separately, as follows:
+ *
+ *  (C) 2014-2015 Dolby Laboratories, Inc.
+ *
+ * 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.
  */
 
 #pragma once
@@ -173,6 +191,10 @@
                                         int id);
         virtual status_t unregisterEffect(int id)
         {
+#ifdef DOLBY_ENABLE
+            sp<EffectDescriptor> effectDesc = mEffects.valueFor(id);
+            mDolbyAudioPolicy.effectRemoved(effectDesc);
+#endif // DOLBY_END
             return mEffects.unregisterEffect(id);
         }
         virtual status_t setEffectEnabled(int id, bool enabled)
@@ -350,7 +372,7 @@
 
         // handle special cases for sonification strategy while in call: mute streams or replace by
         // a special tone in the device used for communication
-        void handleIncallSonification(audio_stream_type_t stream, bool starting, bool stateChange);
+        virtual void handleIncallSonification(audio_stream_type_t stream, bool starting, bool stateChange);
 
         audio_mode_t getPhoneState();
 
@@ -397,7 +419,7 @@
         // must be called every time a condition that affects the device choice for a given output is
         // changed: connected device, phone state, force use, output start, output stop..
         // see getDeviceForStrategy() for the use of fromCache parameter
-        audio_devices_t getNewOutputDevice(const sp<AudioOutputDescriptor>& outputDesc,
+        virtual audio_devices_t getNewOutputDevice(const sp<AudioOutputDescriptor>& outputDesc,
                                            bool fromCache);
 
         // updates cache of device used by all strategies (mDeviceForStrategy[])
@@ -484,11 +506,11 @@
 
         // if argument "device" is different from AUDIO_DEVICE_NONE,  startSource() will force
         // the re-evaluation of the output device.
-        status_t startSource(sp<AudioOutputDescriptor> outputDesc,
+        virtual status_t startSource(sp<AudioOutputDescriptor> outputDesc,
                              audio_stream_type_t stream,
                              audio_devices_t device,
                              uint32_t *delayMs);
-        status_t stopSource(sp<AudioOutputDescriptor> outputDesc,
+        virtual status_t stopSource(sp<AudioOutputDescriptor> outputDesc,
                             audio_stream_type_t stream,
                             bool forceDeviceUpdate);
 
@@ -571,7 +593,7 @@
 
         // Audio Policy Engine Interface.
         AudioPolicyManagerInterface *mEngine;
-private:
+protected:
         // updates device caching and output for streams that can influence the
         //    routing of notifications
         void handleNotificationRoutingForStream(audio_stream_type_t stream);
@@ -586,7 +608,7 @@
                 SortedVector<audio_io_handle_t>& outputs /*out*/);
         uint32_t curAudioPortGeneration() const { return mAudioPortGeneration; }
         // internal method to return the output handle for the given device and format
-        audio_io_handle_t getOutputForDevice(
+        virtual audio_io_handle_t getOutputForDevice(
                 audio_devices_t device,
                 audio_session_t session,
                 audio_stream_type_t stream,
@@ -610,10 +632,15 @@
                                                         AudioMix **policyMix = NULL);
 
         // Called by setDeviceConnectionState().
-        status_t setDeviceConnectionStateInt(audio_devices_t device,
+        virtual status_t setDeviceConnectionStateInt(audio_devices_t device,
                                                           audio_policy_dev_state_t state,
                                                           const char *device_address,
                                                           const char *device_name);
+#ifdef DOLBY_ENABLE
+protected:
+#include "DolbyAudioPolicy.h"
+        DolbyAudioPolicy mDolbyAudioPolicy;
+#endif // DOLBY_END
 };
 
 };
diff --git a/services/audiopolicy/service/AudioPolicyEffects.cpp b/services/audiopolicy/service/AudioPolicyEffects.cpp
index 282ddeb..e71d7a5 100644
--- a/services/audiopolicy/service/AudioPolicyEffects.cpp
+++ b/services/audiopolicy/service/AudioPolicyEffects.cpp
@@ -442,6 +442,7 @@
     size_t curSize = sizeof(effect_param_t);
     size_t totSize = sizeof(effect_param_t) + 2 * sizeof(int);
     effect_param_t *fx_param = (effect_param_t *)malloc(totSize);
+    CHECK(fx_param != NULL);
 
     param = config_find(root, PARAM_TAG);
     value = config_find(root, VALUE_TAG);
diff --git a/services/audiopolicy/service/AudioPolicyEffects.h b/services/audiopolicy/service/AudioPolicyEffects.h
index 3dec437..3845050 100644
--- a/services/audiopolicy/service/AudioPolicyEffects.h
+++ b/services/audiopolicy/service/AudioPolicyEffects.h
@@ -27,6 +27,8 @@
 #include <utils/Vector.h>
 #include <utils/SortedVector.h>
 
+#include <media/stagefright/foundation/ADebug.h>
+
 namespace android {
 
 // ----------------------------------------------------------------------------
@@ -102,6 +104,7 @@
                                                   ((origParam->psize + 3) & ~3) +
                                                   ((origParam->vsize + 3) & ~3);
                                 effect_param_t *dupParam = (effect_param_t *) malloc(origSize);
+                                CHECK(dupParam != NULL);
                                 memcpy(dupParam, origParam, origSize);
                                 // This works because the param buffer allocation is also done by
                                 // multiples of 4 bytes originally. In theory we should memcpy only
diff --git a/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp b/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
index ca365a5..a228798 100644
--- a/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
+++ b/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
@@ -463,6 +463,7 @@
     if (mAudioPolicyManager == NULL) {
         return AUDIO_DEVICE_NONE;
     }
+    Mutex::Autolock _l(mLock);
     return mAudioPolicyManager->getDevicesForStream(stream);
 }
 
diff --git a/services/audiopolicy/service/AudioPolicyService.cpp b/services/audiopolicy/service/AudioPolicyService.cpp
index c77cc45..41dd40c 100644
--- a/services/audiopolicy/service/AudioPolicyService.cpp
+++ b/services/audiopolicy/service/AudioPolicyService.cpp
@@ -899,10 +899,12 @@
             } else {
                 data2->mKeyValuePairs = param2.toString();
             }
-            command->mTime = command2->mTime;
-            // force delayMs to non 0 so that code below does not request to wait for
-            // command status as the command is now delayed
-            delayMs = 1;
+            if (!data2->mKeyValuePairs.compare(data->mKeyValuePairs)) {
+                command->mTime = command2->mTime;
+                // force delayMs to non 0 so that code below does not request to wait for
+                // command status as the command is now delayed
+                delayMs = 1;
+            }
         } break;
 
         case SET_VOLUME: {
diff --git a/services/camera/libcameraservice/CameraFlashlight.cpp b/services/camera/libcameraservice/CameraFlashlight.cpp
index 280bb9d..fd23ef9 100644
--- a/services/camera/libcameraservice/CameraFlashlight.cpp
+++ b/services/camera/libcameraservice/CameraFlashlight.cpp
@@ -99,7 +99,8 @@
 
 status_t CameraFlashlight::setTorchMode(const String8& cameraId, bool enabled) {
     if (!mFlashlightMapInitialized) {
-        ALOGE("%s: findFlashUnits() must be called before this method.");
+        ALOGE("%s: findFlashUnits() must be called before this method.",
+               __FUNCTION__);
         return NO_INIT;
     }
 
@@ -200,7 +201,8 @@
 
 bool CameraFlashlight::hasFlashUnitLocked(const String8& cameraId) {
     if (!mFlashlightMapInitialized) {
-        ALOGE("%s: findFlashUnits() must be called before this method.");
+        ALOGE("%s: findFlashUnits() must be called before this method.",
+               __FUNCTION__);
         return false;
     }
 
@@ -219,7 +221,8 @@
 
     Mutex::Autolock l(mLock);
     if (!mFlashlightMapInitialized) {
-        ALOGE("%s: findFlashUnits() must be called before this method.");
+        ALOGE("%s: findFlashUnits() must be called before this method.",
+               __FUNCTION__);
         return NO_INIT;
     }
 
@@ -256,7 +259,8 @@
 
     Mutex::Autolock l(mLock);
     if (!mFlashlightMapInitialized) {
-        ALOGE("%s: findFlashUnits() must be called before this method.");
+        ALOGE("%s: findFlashUnits() must be called before this method.",
+               __FUNCTION__);
         return NO_INIT;
     }
 
diff --git a/services/camera/libcameraservice/CameraService.cpp b/services/camera/libcameraservice/CameraService.cpp
index 2aaefe9..db6272b 100644
--- a/services/camera/libcameraservice/CameraService.cpp
+++ b/services/camera/libcameraservice/CameraService.cpp
@@ -2082,7 +2082,11 @@
 
 void CameraService::Client::notifyError(ICameraDeviceCallbacks::CameraErrorCode errorCode,
         const CaptureResultExtras& resultExtras) {
-    mRemoteCallback->notifyCallback(CAMERA_MSG_ERROR, CAMERA_ERROR_RELEASED, 0);
+    if (mRemoteCallback != NULL) {
+        mRemoteCallback->notifyCallback(CAMERA_MSG_ERROR, CAMERA_ERROR_RELEASED, 0);
+    } else {
+        ALOGE("mRemoteCallback is NULL!!");
+    }
 }
 
 // NOTE: function is idempotent
diff --git a/services/camera/libcameraservice/api1/CameraClient.cpp b/services/camera/libcameraservice/api1/CameraClient.cpp
index 38e35cd..9ff843a 100644
--- a/services/camera/libcameraservice/api1/CameraClient.cpp
+++ b/services/camera/libcameraservice/api1/CameraClient.cpp
@@ -56,6 +56,9 @@
     mOrientation = getOrientation(0, mCameraFacing == CAMERA_FACING_FRONT);
     mLegacyMode = legacyMode;
     mPlayShutterSound = true;
+
+    mLongshotEnabled = false;
+    mBurstCnt = 0;
     LOG1("CameraClient::CameraClient X (pid %d, id %d)", callingPid, cameraId);
 }
 
@@ -553,6 +556,10 @@
                            CAMERA_MSG_COMPRESSED_IMAGE);
 
     enableMsgType(picMsgType);
+    mBurstCnt = mHardware->getParameters().getInt("num-snaps-per-shutter");
+    if(mBurstCnt <= 0)
+        mBurstCnt = 1;
+    LOG1("mBurstCnt = %d", mBurstCnt);
 
     return mHardware->takePicture();
 }
@@ -655,6 +662,20 @@
     } else if (cmd == CAMERA_CMD_PING) {
         // If mHardware is 0, checkPidAndHardware will return error.
         return OK;
+    } else if (cmd == CAMERA_CMD_HISTOGRAM_ON) {
+        enableMsgType(CAMERA_MSG_STATS_DATA);
+    } else if (cmd == CAMERA_CMD_HISTOGRAM_OFF) {
+        disableMsgType(CAMERA_MSG_STATS_DATA);
+    } else if (cmd == CAMERA_CMD_METADATA_ON) {
+        enableMsgType(CAMERA_MSG_META_DATA);
+    } else if (cmd == CAMERA_CMD_METADATA_OFF) {
+        disableMsgType(CAMERA_MSG_META_DATA);
+    } else if ( cmd == CAMERA_CMD_LONGSHOT_ON ) {
+        mLongshotEnabled = true;
+    } else if ( cmd == CAMERA_CMD_LONGSHOT_OFF ) {
+        mLongshotEnabled = false;
+        disableMsgType(CAMERA_MSG_SHUTTER);
+        disableMsgType(CAMERA_MSG_COMPRESSED_IMAGE);
     }
 
     return mHardware->sendCommand(cmd, arg1, arg2);
@@ -797,7 +818,9 @@
         c->notifyCallback(CAMERA_MSG_SHUTTER, 0, 0);
         if (!lockIfMessageWanted(CAMERA_MSG_SHUTTER)) return;
     }
-    disableMsgType(CAMERA_MSG_SHUTTER);
+    if ( !mLongshotEnabled ) {
+        disableMsgType(CAMERA_MSG_SHUTTER);
+    }
 
     // Shutters only happen in response to takePicture, so mark device as
     // idle now, until preview is restarted
@@ -882,7 +905,13 @@
 
 // picture callback - compressed picture ready
 void CameraClient::handleCompressedPicture(const sp<IMemory>& mem) {
-    disableMsgType(CAMERA_MSG_COMPRESSED_IMAGE);
+    if (mBurstCnt)
+        mBurstCnt--;
+
+    if (!mBurstCnt && !mLongshotEnabled) {
+        LOG1("handleCompressedPicture mBurstCnt = %d", mBurstCnt);
+        disableMsgType(CAMERA_MSG_COMPRESSED_IMAGE);
+    }
 
     sp<ICameraClient> c = mRemoteCallback;
     mLock.unlock();
diff --git a/services/camera/libcameraservice/api1/CameraClient.h b/services/camera/libcameraservice/api1/CameraClient.h
index 95616b2..9d2d02f 100644
--- a/services/camera/libcameraservice/api1/CameraClient.h
+++ b/services/camera/libcameraservice/api1/CameraClient.h
@@ -162,6 +162,9 @@
     // This function keeps trying to grab mLock, or give up if the message
     // is found to be disabled. It returns true if mLock is grabbed.
     bool                    lockIfMessageWanted(int32_t msgType);
+
+    bool                 mLongshotEnabled;
+    int                  mBurstCnt;
 };
 
 }