Merge "Bug 4608375"
diff --git a/cmds/stagefright/stagefright.cpp b/cmds/stagefright/stagefright.cpp
index 01262fa..ca77185 100644
--- a/cmds/stagefright/stagefright.cpp
+++ b/cmds/stagefright/stagefright.cpp
@@ -66,6 +66,7 @@
 static long gMaxNumFrames;  // 0 means decode all available.
 static long gReproduceBug;  // if not -1.
 static bool gPreferSoftwareCodec;
+static bool gForceToUseHardwareCodec;
 static bool gPlaybackAudio;
 static bool gWriteMP4;
 static bool gDisplayHistogram;
@@ -144,10 +145,18 @@
     if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_RAW, mime)) {
         rawSource = source;
     } else {
+        int flags = 0;
+        if (gPreferSoftwareCodec) {
+            flags |= OMXCodec::kPreferSoftwareCodecs;
+        }
+        if (gForceToUseHardwareCodec) {
+            CHECK(!gPreferSoftwareCodec);
+            flags |= OMXCodec::kHardwareCodecsOnly;
+        }
         rawSource = OMXCodec::Create(
             client->interface(), meta, false /* createEncoder */, source,
             NULL /* matchComponentName */,
-            gPreferSoftwareCodec ? OMXCodec::kPreferSoftwareCodecs : 0,
+            flags,
             gSurface);
 
         if (rawSource == NULL) {
@@ -545,6 +554,7 @@
     fprintf(stderr, "       -p(rofiles) dump decoder profiles supported\n");
     fprintf(stderr, "       -t(humbnail) extract video thumbnail or album art\n");
     fprintf(stderr, "       -s(oftware) prefer software codec\n");
+    fprintf(stderr, "       -r(hardware) force to use hardware codec\n");
     fprintf(stderr, "       -o playback audio\n");
     fprintf(stderr, "       -w(rite) filename (write to .mp4 file)\n");
     fprintf(stderr, "       -k seek test\n");
@@ -566,6 +576,7 @@
     gMaxNumFrames = 0;
     gReproduceBug = -1;
     gPreferSoftwareCodec = false;
+    gForceToUseHardwareCodec = false;
     gPlaybackAudio = false;
     gWriteMP4 = false;
     gDisplayHistogram = false;
@@ -575,7 +586,7 @@
     sp<LiveSession> liveSession;
 
     int res;
-    while ((res = getopt(argc, argv, "han:lm:b:ptsow:kxS")) >= 0) {
+    while ((res = getopt(argc, argv, "han:lm:b:ptsrow:kxS")) >= 0) {
         switch (res) {
             case 'a':
             {
@@ -636,6 +647,12 @@
                 break;
             }
 
+            case 'r':
+            {
+                gForceToUseHardwareCodec = true;
+                break;
+            }
+
             case 'o':
             {
                 gPlaybackAudio = true;
diff --git a/drm/libdrmframework/plugins/forward-lock/FwdLockEngine/src/FwdLockEngine.cpp b/drm/libdrmframework/plugins/forward-lock/FwdLockEngine/src/FwdLockEngine.cpp
index d430f72..07b3b47 100644
--- a/drm/libdrmframework/plugins/forward-lock/FwdLockEngine/src/FwdLockEngine.cpp
+++ b/drm/libdrmframework/plugins/forward-lock/FwdLockEngine/src/FwdLockEngine.cpp
@@ -53,11 +53,11 @@
 }
 
 FwdLockEngine::FwdLockEngine() {
-    LOGD("FwdLockEngine Construction");
+    LOGV("FwdLockEngine Construction");
 }
 
 FwdLockEngine::~FwdLockEngine() {
-    LOGD("FwdLockEngine Destruction");
+    LOGV("FwdLockEngine Destruction");
 
     convertSessionMap.destroyMap();
     decodeSessionMap.destroyMap();
@@ -91,7 +91,7 @@
 DrmConstraints* FwdLockEngine::onGetConstraints(int uniqueId, const String8* path, int action) {
     DrmConstraints* drmConstraints = NULL;
 
-    LOGD("FwdLockEngine::onGetConstraints");
+    LOGV("FwdLockEngine::onGetConstraints");
 
     if (NULL != path &&
         (RightsStatus::RIGHTS_VALID == onCheckRightsStatus(uniqueId, *path, action))) {
@@ -105,7 +105,7 @@
 DrmMetadata* FwdLockEngine::onGetMetadata(int uniqueId, const String8* path) {
     DrmMetadata* drmMetadata = NULL;
 
-    LOGD("FwdLockEngine::onGetMetadata");
+    LOGV("FwdLockEngine::onGetMetadata");
 
     if (NULL != path) {
         // Returns empty metadata to show no error condition.
@@ -116,11 +116,11 @@
 }
 
 android::status_t FwdLockEngine::onInitialize(int uniqueId) {
-    LOGD("FwdLockEngine::onInitialize");
+    LOGV("FwdLockEngine::onInitialize");
 
 
     if (FwdLockGlue_InitializeKeyEncryption()) {
-        LOGD("FwdLockEngine::onInitialize -- FwdLockGlue_InitializeKeyEncryption succeeded");
+        LOGV("FwdLockEngine::onInitialize -- FwdLockGlue_InitializeKeyEncryption succeeded");
     } else {
         LOGD("FwdLockEngine::onInitialize -- FwdLockGlue_InitializeKeyEncryption failed:"
              "errno = %d", errno);
@@ -132,13 +132,13 @@
 android::status_t
 FwdLockEngine::onSetOnInfoListener(int uniqueId, const IDrmEngine::OnInfoListener* infoListener) {
     // Not used
-    LOGD("FwdLockEngine::onSetOnInfoListener");
+    LOGV("FwdLockEngine::onSetOnInfoListener");
 
     return DRM_NO_ERROR;
 }
 
 android::status_t FwdLockEngine::onTerminate(int uniqueId) {
-    LOGD("FwdLockEngine::onTerminate");
+    LOGV("FwdLockEngine::onTerminate");
 
     return DRM_NO_ERROR;
 }
@@ -146,7 +146,7 @@
 DrmSupportInfo* FwdLockEngine::onGetSupportInfo(int uniqueId) {
     DrmSupportInfo* pSupportInfo = new DrmSupportInfo();
 
-    LOGD("FwdLockEngine::onGetSupportInfo");
+    LOGV("FwdLockEngine::onGetSupportInfo");
 
     // fill all Forward Lock mimetypes and extensions
     if (NULL != pSupportInfo) {
@@ -182,7 +182,7 @@
 
     drmInfoStatus = new DrmInfoStatus((int)DrmInfoStatus::STATUS_OK, 0, NULL, String8(""));
 
-    LOGD("FwdLockEngine::onProcessDrmInfo");
+    LOGV("FwdLockEngine::onProcessDrmInfo");
 
     return drmInfoStatus;
 }
@@ -193,7 +193,7 @@
             const String8& rightsPath,
             const String8& contentPath) {
     // No rights to save. Return
-    LOGD("FwdLockEngine::onSaveRights");
+    LOGV("FwdLockEngine::onSaveRights");
     return DRM_ERROR_UNKNOWN;
 }
 
@@ -201,7 +201,7 @@
     DrmInfo* drmInfo = NULL;
 
     // Nothing to be done for Forward Lock file
-    LOGD("FwdLockEngine::onAcquireDrmInfo");
+    LOGV("FwdLockEngine::onAcquireDrmInfo");
 
     return drmInfo;
 }
@@ -211,7 +211,7 @@
                                        int action) {
     int result = RightsStatus::RIGHTS_INVALID;
 
-    LOGD("FwdLockEngine::onCheckRightsStatus");
+    LOGV("FwdLockEngine::onCheckRightsStatus");
 
     // Only Transfer action is not allowed for forward Lock files.
     if (onCanHandle(uniqueId, path)) {
@@ -241,7 +241,7 @@
                                         int action,
                                         bool reserve) {
     // No rights consumption
-    LOGD("FwdLockEngine::onConsumeRights");
+    LOGV("FwdLockEngine::onConsumeRights");
     return DRM_NO_ERROR;
 }
 
@@ -249,14 +249,14 @@
                                      const String8& path,
                                      int action,
                                      const ActionDescription& description) {
-    LOGD("FwdLockEngine::onValidateAction");
+    LOGV("FwdLockEngine::onValidateAction");
 
     // For the forwardlock engine checkRights and ValidateAction are the same.
     return (onCheckRightsStatus(uniqueId, path, action) == RightsStatus::RIGHTS_VALID);
 }
 
 String8 FwdLockEngine::onGetOriginalMimeType(int uniqueId, const String8& path) {
-    LOGD("FwdLockEngine::onGetOriginalMimeType");
+    LOGV("FwdLockEngine::onGetOriginalMimeType");
     String8 mimeString = String8("");
     int fileDesc = FwdLockFile_open(path.string());
 
@@ -280,7 +280,7 @@
                                       const String8& mimeType) {
     String8 mimeStr = String8(mimeType);
 
-    LOGD("FwdLockEngine::onGetDrmObjectType");
+    LOGV("FwdLockEngine::onGetDrmObjectType");
 
     mimeStr.toLower();
 
@@ -301,13 +301,13 @@
 
 status_t FwdLockEngine::onRemoveRights(int uniqueId, const String8& path) {
     // No Rights to remove
-    LOGD("FwdLockEngine::onRemoveRights");
+    LOGV("FwdLockEngine::onRemoveRights");
     return DRM_NO_ERROR;
 }
 
 status_t FwdLockEngine::onRemoveAllRights(int uniqueId) {
     // No rights to remove
-    LOGD("FwdLockEngine::onRemoveAllRights");
+    LOGV("FwdLockEngine::onRemoveAllRights");
     return DRM_NO_ERROR;
 }
 
@@ -319,14 +319,14 @@
                                             int playbackStatus, int position) {
 #endif
     // Not used
-    LOGD("FwdLockEngine::onSetPlaybackStatus");
+    LOGV("FwdLockEngine::onSetPlaybackStatus");
     return DRM_NO_ERROR;
 }
 
 status_t FwdLockEngine::onOpenConvertSession(int uniqueId,
                                          int convertId) {
     status_t result = DRM_ERROR_UNKNOWN;
-    LOGD("FwdLockEngine::onOpenConvertSession");
+    LOGV("FwdLockEngine::onOpenConvertSession");
     if (!convertSessionMap.isCreated(convertId)) {
         ConvertSession *newSession = new ConvertSession();
         if (FwdLockConv_Status_OK ==
@@ -383,7 +383,7 @@
     DrmBuffer *convResult = new DrmBuffer(NULL, 0);
     int offset = -1;
 
-    LOGD("FwdLockEngine::onCloseConvertSession");
+    LOGV("FwdLockEngine::onCloseConvertSession");
 
     if (convertSessionMap.isCreated(convertId)) {
         ConvertSession *convSession = convertSessionMap.getValue(convertId);
@@ -424,7 +424,7 @@
     status_t result = DRM_ERROR_CANNOT_HANDLE;
     int fileDesc = -1;
 
-    LOGD("FwdLockEngine::onOpenDecryptSession");
+    LOGV("FwdLockEngine::onOpenDecryptSession");
 
     if ((-1 < fd) &&
         (NULL != decryptHandle) &&
@@ -455,12 +455,15 @@
         } else {
             LOGD("FwdLockEngine::onOpenDecryptSession Integrity Check failed for the fd");
             FwdLockFile_detach(fileDesc);
-            ::close(fileDesc);
             delete decodeSession;
         }
     }
 
-    LOGD("FwdLockEngine::onOpenDecryptSession Exit. result = %d", result);
+    if (DRM_NO_ERROR != result && -1 < fileDesc) {
+        ::close(fileDesc);
+    }
+
+    LOGV("FwdLockEngine::onOpenDecryptSession Exit. result = %d", result);
 
     return result;
 }
@@ -497,7 +500,7 @@
 status_t FwdLockEngine::onCloseDecryptSession(int uniqueId,
                                               DecryptHandle* decryptHandle) {
     status_t result = DRM_ERROR_UNKNOWN;
-    LOGD("FwdLockEngine::onCloseDecryptSession");
+    LOGV("FwdLockEngine::onCloseDecryptSession");
 
     if (NULL != decryptHandle && decodeSessionMap.isCreated(decryptHandle->decryptId)) {
         DecodeSession* session = decodeSessionMap.getValue(decryptHandle->decryptId);
@@ -509,7 +512,7 @@
         }
     }
 
-    LOGD("FwdLockEngine::onCloseDecryptSession Exit");
+    LOGV("FwdLockEngine::onCloseDecryptSession Exit");
     return result;
 }
 
@@ -517,13 +520,13 @@
                                                 DecryptHandle* decryptHandle,
                                                 int decryptUnitId,
                                                 const DrmBuffer* headerInfo) {
-    LOGD("FwdLockEngine::onInitializeDecryptUnit");
+    LOGV("FwdLockEngine::onInitializeDecryptUnit");
     return DRM_ERROR_UNKNOWN;
 }
 
 status_t FwdLockEngine::onDecrypt(int uniqueId, DecryptHandle* decryptHandle, int decryptUnitId,
             const DrmBuffer* encBuffer, DrmBuffer** decBuffer, DrmBuffer* IV) {
-    LOGD("FwdLockEngine::onDecrypt");
+    LOGV("FwdLockEngine::onDecrypt");
     return DRM_ERROR_UNKNOWN;
 }
 
@@ -532,14 +535,14 @@
                                   int decryptUnitId,
                                   const DrmBuffer* encBuffer,
                                   DrmBuffer** decBuffer) {
-    LOGD("FwdLockEngine::onDecrypt");
+    LOGV("FwdLockEngine::onDecrypt");
     return DRM_ERROR_UNKNOWN;
 }
 
 status_t FwdLockEngine::onFinalizeDecryptUnit(int uniqueId,
                                               DecryptHandle* decryptHandle,
                                               int decryptUnitId) {
-    LOGD("FwdLockEngine::onFinalizeDecryptUnit");
+    LOGV("FwdLockEngine::onFinalizeDecryptUnit");
     return DRM_ERROR_UNKNOWN;
 }
 
diff --git a/include/media/AudioSystem.h b/include/media/AudioSystem.h
index 68cd188..89213b7 100644
--- a/include/media/AudioSystem.h
+++ b/include/media/AudioSystem.h
@@ -22,7 +22,7 @@
 #include <media/IAudioFlinger.h>
 
 #include <system/audio.h>
-#include <hardware/audio_policy.h>
+#include <system/audio_policy.h>
 
 /* XXX: Should be include by all the users instead */
 #include <media/AudioParameter.h>
diff --git a/include/media/IAudioPolicyService.h b/include/media/IAudioPolicyService.h
index 09b2bfe..0fc8dbf 100644
--- a/include/media/IAudioPolicyService.h
+++ b/include/media/IAudioPolicyService.h
@@ -26,7 +26,7 @@
 #include <binder/IInterface.h>
 #include <media/AudioSystem.h>
 
-#include <hardware/audio_policy.h>
+#include <system/audio_policy.h>
 
 namespace android {
 
diff --git a/include/media/stagefright/MetaData.h b/include/media/stagefright/MetaData.h
index 4044c5d..deade5e 100644
--- a/include/media/stagefright/MetaData.h
+++ b/include/media/stagefright/MetaData.h
@@ -55,6 +55,7 @@
     kKeyIsSyncFrame       = 'sync',  // int32_t (bool)
     kKeyIsCodecConfig     = 'conf',  // int32_t (bool)
     kKeyTime              = 'time',  // int64_t (usecs)
+    kKeyDecodingTime      = 'decT',  // int64_t (decoding timestamp in usecs)
     kKeyNTPTime           = 'ntpT',  // uint64_t (ntp-timestamp)
     kKeyTargetTime        = 'tarT',  // int64_t (usecs)
     kKeyDriftTime         = 'dftT',  // int64_t (usecs)
diff --git a/include/media/stagefright/OMXCodec.h b/include/media/stagefright/OMXCodec.h
index 70daafa..589cefd 100644
--- a/include/media/stagefright/OMXCodec.h
+++ b/include/media/stagefright/OMXCodec.h
@@ -202,6 +202,10 @@
     bool mOnlySubmitOneBufferAtOneTime;
     bool mEnableGrallocUsageProtected;
 
+    // Used to record the decoding time for an output picture from
+    // a video encoder.
+    List<int64_t> mDecodingTimeList;
+
     OMXCodec(const sp<IOMX> &omx, IOMX::node_id node, uint32_t quirks,
              bool isEncoder, const char *mime, const char *componentName,
              const sp<MediaSource> &source,
@@ -317,6 +321,8 @@
 
     status_t applyRotation();
 
+    int64_t retrieveDecodingTimeUs(bool isCodecSpecific);
+
     OMXCodec(const OMXCodec &);
     OMXCodec &operator=(const OMXCodec &);
 };
diff --git a/include/private/surfaceflinger/SharedBufferStack.h b/include/private/surfaceflinger/SharedBufferStack.h
index 717f837..0da03d1 100644
--- a/include/private/surfaceflinger/SharedBufferStack.h
+++ b/include/private/surfaceflinger/SharedBufferStack.h
@@ -20,355 +20,12 @@
 #include <stdint.h>
 #include <sys/types.h>
 
-#include <cutils/compiler.h>
-
 #include <utils/Debug.h>
-#include <utils/threads.h>
-#include <utils/String8.h>
-
-#include <ui/Rect.h>
 
 namespace android {
 // ---------------------------------------------------------------------------
 
-/*
- * These classes manage a stack of buffers in shared memory.
- * 
- * SharedClient: represents a client with several stacks
- * SharedBufferStack: represents a stack of buffers
- * SharedBufferClient: manipulates the SharedBufferStack from the client side 
- * SharedBufferServer: manipulates the SharedBufferStack from the server side 
- *
- * Buffers can be dequeued until there are none available, they can be locked
- * unless they are in use by the server, which is only the case for the last 
- * dequeue-able buffer. When these various conditions are not met, the caller
- * waits until the condition is met.
- * 
- */
-
-// ----------------------------------------------------------------------------
-
-class Region;
-class SharedBufferStack;
-class SharedClient;
-
-// ----------------------------------------------------------------------------
-
-class SharedBufferStack
-{
-    friend class SharedClient;
-    friend class SharedBufferBase;
-    friend class SharedBufferClient;
-    friend class SharedBufferServer;
-
-public:
-    // When changing these values, the COMPILE_TIME_ASSERT at the end of this
-    // file need to be updated.
-    static const unsigned int NUM_LAYERS_MAX  = 31;
-    static const unsigned int NUM_BUFFER_MAX  = 32;
-    static const unsigned int NUM_BUFFER_MIN  = 2;
-    static const unsigned int NUM_DISPLAY_MAX = 4;
-
-    struct Statistics { // 4 longs
-        typedef int32_t usecs_t;
-        usecs_t  totalTime;
-        usecs_t  reserved[3];
-    };
-
-    struct SmallRect {
-        uint16_t l, t, r, b;
-    };
-
-    struct FlatRegion { // 52 bytes = 4 * (1 + 2*N)
-        static const unsigned int NUM_RECT_MAX = 5;
-        uint32_t    count;
-        SmallRect   rects[NUM_RECT_MAX];
-    };
-    
-    struct BufferData {
-        FlatRegion dirtyRegion;
-        SmallRect  crop;
-        uint8_t transform;
-        uint8_t reserved[3];
-    };
-    
-    SharedBufferStack();
-    void init(int32_t identity);
-    status_t setDirtyRegion(int buffer, const Region& reg);
-    status_t setCrop(int buffer, const Rect& reg);
-    status_t setTransform(int buffer, uint8_t transform);
-    Region getDirtyRegion(int buffer) const;
-    Rect getCrop(int buffer) const;
-    uint32_t getTransform(int buffer) const;
-
-    // these attributes are part of the conditions/updates
-    volatile int32_t head;      // server's current front buffer
-    volatile int32_t available; // number of dequeue-able buffers
-    volatile int32_t queued;    // number of buffers waiting for post
-    volatile int32_t reserved1;
-    volatile status_t status;   // surface's status code
-
-    // not part of the conditions
-    volatile int32_t reallocMask;
-    volatile int8_t index[NUM_BUFFER_MAX];
-
-    int32_t     identity;       // surface's identity (const)
-    int32_t     token;          // surface's token (for debugging)
-    Statistics  stats;
-    int8_t      headBuf;        // last retired buffer
-    uint8_t     reservedBytes[3];
-    int32_t     reserved;
-    BufferData  buffers[NUM_BUFFER_MAX];     // 1024 bytes
-};
-
-// ----------------------------------------------------------------------------
-
-// 64 KB max
-class SharedClient
-{
-public:
-    SharedClient();
-    ~SharedClient();
-    status_t validate(size_t token) const;
-
-private:
-    friend class SharedBufferBase;
-    friend class SharedBufferClient;
-    friend class SharedBufferServer;
-
-    // FIXME: this should be replaced by a lock-less primitive
-    Mutex lock;
-    Condition cv;
-    SharedBufferStack surfaces[ SharedBufferStack::NUM_LAYERS_MAX ];
-};
-
-// ============================================================================
-
-class SharedBufferBase
-{
-public:
-    SharedBufferBase(SharedClient* sharedClient, int surface,
-            int32_t identity);
-    ~SharedBufferBase();
-    status_t getStatus() const;
-    int32_t getIdentity() const;
-    String8 dump(char const* prefix) const;
-
-protected:
-    SharedClient* const mSharedClient;
-    SharedBufferStack* const mSharedStack;
-    const int mIdentity;
-
-    friend struct Update;
-    friend struct QueueUpdate;
-
-    struct ConditionBase {
-        SharedBufferStack& stack;
-        inline ConditionBase(SharedBufferBase* sbc) 
-            : stack(*sbc->mSharedStack) { }
-        virtual ~ConditionBase() { };
-        virtual bool operator()() const = 0;
-        virtual const char* name() const = 0;
-    };
-    status_t waitForCondition(const ConditionBase& condition);
-
-    struct UpdateBase {
-        SharedBufferStack& stack;
-        inline UpdateBase(SharedBufferBase* sbb) 
-            : stack(*sbb->mSharedStack) { }
-    };
-    template <typename T>
-    status_t updateCondition(T update);
-};
-
-template <typename T>
-status_t SharedBufferBase::updateCondition(T update) {
-    SharedClient& client( *mSharedClient );
-    Mutex::Autolock _l(client.lock);
-    ssize_t result = update();
-    client.cv.broadcast();    
-    return result;
-}
-
-// ----------------------------------------------------------------------------
-
-class SharedBufferClient : public SharedBufferBase
-{
-public:
-    SharedBufferClient(SharedClient* sharedClient, int surface, int num,
-            int32_t identity);
-
-    ssize_t dequeue();
-    status_t undoDequeue(int buf);
-    
-    status_t lock(int buf);
-    status_t cancel(int buf);
-    status_t queue(int buf);
-    bool needNewBuffer(int buffer) const;
-    status_t setDirtyRegion(int buffer, const Region& reg);
-    status_t setCrop(int buffer, const Rect& reg);
-    status_t setTransform(int buffer, uint32_t transform);
-
-    class SetBufferCountCallback {
-        friend class SharedBufferClient;
-        virtual status_t operator()(int bufferCount) const = 0;
-    protected:
-        virtual ~SetBufferCountCallback() { }
-    };
-    status_t setBufferCount(int bufferCount, const SetBufferCountCallback& ipc);
-
-private:
-    friend struct Condition;
-    friend struct DequeueCondition;
-    friend struct LockCondition;
-
-    struct QueueUpdate : public UpdateBase {
-        inline QueueUpdate(SharedBufferBase* sbb);
-        inline ssize_t operator()();
-    };
-
-    struct DequeueUpdate : public UpdateBase {
-        inline DequeueUpdate(SharedBufferBase* sbb);
-        inline ssize_t operator()();
-    };
-
-    struct CancelUpdate : public UpdateBase {
-        int tail, buf;
-        inline CancelUpdate(SharedBufferBase* sbb, int tail, int buf);
-        inline ssize_t operator()();
-    };
-
-    // --
-
-    struct DequeueCondition : public ConditionBase {
-        inline DequeueCondition(SharedBufferClient* sbc);
-        inline bool operator()() const;
-        inline const char* name() const { return "DequeueCondition"; }
-    };
-
-    struct LockCondition : public ConditionBase {
-        int buf;
-        inline LockCondition(SharedBufferClient* sbc, int buf);
-        inline bool operator()() const;
-        inline const char* name() const { return "LockCondition"; }
-    };
-
-    int32_t computeTail() const;
-
-    mutable RWLock mLock;
-    int mNumBuffers;
-
-    int32_t tail;
-    int32_t queued_head;
-    // statistics...
-    nsecs_t mDequeueTime[SharedBufferStack::NUM_BUFFER_MAX];
-};
-
-// ----------------------------------------------------------------------------
-
-class SharedBufferServer
-    : public SharedBufferBase,
-      public LightRefBase<SharedBufferServer>
-{
-public:
-    SharedBufferServer(SharedClient* sharedClient, int surface, int num,
-            int32_t identity);
-
-    ssize_t retireAndLock();
-    void setStatus(status_t status);
-    status_t reallocateAll();
-    status_t reallocateAllExcept(int buffer);
-    int32_t getQueuedCount() const;
-    Region getDirtyRegion(int buffer) const;
-    Rect getCrop(int buffer) const;
-    uint32_t getTransform(int buffer) const;
-
-    status_t resize(int newNumBuffers);
-    status_t grow(int newNumBuffers);
-    status_t shrink(int newNumBuffers);
-
-    SharedBufferStack::Statistics getStats() const;
-    
-
-private:
-    friend class LightRefBase<SharedBufferServer>;
-    ~SharedBufferServer();
-
-    /*
-     * BufferList is basically a fixed-capacity sorted-vector of
-     * unsigned 5-bits ints using a 32-bits int as storage.
-     * it has efficient iterators to find items in the list and not in the list.
-     */
-    class BufferList {
-        size_t mCapacity;
-        uint32_t mList;
-    public:
-        BufferList(size_t c = SharedBufferStack::NUM_BUFFER_MAX)
-            : mCapacity(c), mList(0) { }
-        status_t add(int value);
-        status_t remove(int value);
-        uint32_t getMask() const { return mList; }
-
-        class const_iterator {
-            friend class BufferList;
-            uint32_t mask, curr;
-            const_iterator(uint32_t mask) :
-                mask(mask), curr(__builtin_clz(mask)) {
-            }
-        public:
-            inline bool operator == (const const_iterator& rhs) const {
-                return mask == rhs.mask;
-            }
-            inline bool operator != (const const_iterator& rhs) const {
-                return mask != rhs.mask;
-            }
-            inline int operator *() const { return curr; }
-            inline const const_iterator& operator ++() {
-                mask &= ~(1<<(31-curr));
-                curr = __builtin_clz(mask);
-                return *this;
-            }
-        };
-
-        inline const_iterator begin() const {
-            return const_iterator(mList);
-        }
-        inline const_iterator end() const   {
-            return const_iterator(0);
-        }
-        inline const_iterator free_begin() const {
-            uint32_t mask = (1 << (32-mCapacity)) - 1;
-            return const_iterator( ~(mList | mask) );
-        }
-    };
-
-    // this protects mNumBuffers and mBufferList
-    mutable RWLock mLock;
-    int mNumBuffers;
-    BufferList mBufferList;
-
-    struct BuffersAvailableCondition : public ConditionBase {
-        int mNumBuffers;
-        inline BuffersAvailableCondition(SharedBufferServer* sbs,
-                int numBuffers);
-        inline bool operator()() const;
-        inline const char* name() const { return "BuffersAvailableCondition"; }
-    };
-
-    struct RetireUpdate : public UpdateBase {
-        const int numBuffers;
-        inline RetireUpdate(SharedBufferBase* sbb, int numBuffers);
-        inline ssize_t operator()();
-    };
-
-    struct StatusUpdate : public UpdateBase {
-        const status_t status;
-        inline StatusUpdate(SharedBufferBase* sbb, status_t status);
-        inline ssize_t operator()();
-    };
-};
-
-// ===========================================================================
+#define NUM_DISPLAY_MAX 4
 
 struct display_cblk_t
 {
@@ -389,12 +46,11 @@
     uint8_t         connected;
     uint8_t         reserved[3];
     uint32_t        pad[7];
-    display_cblk_t  displays[SharedBufferStack::NUM_DISPLAY_MAX];
+    display_cblk_t  displays[NUM_DISPLAY_MAX];
 };
 
 // ---------------------------------------------------------------------------
 
-COMPILE_TIME_ASSERT(sizeof(SharedClient) <= 65536)
 COMPILE_TIME_ASSERT(sizeof(surface_flinger_cblk_t) <= 4096)
 
 // ---------------------------------------------------------------------------
diff --git a/media/libmedia/AudioTrack.cpp b/media/libmedia/AudioTrack.cpp
index 6b4391b..37fe182 100644
--- a/media/libmedia/AudioTrack.cpp
+++ b/media/libmedia/AudioTrack.cpp
@@ -40,7 +40,7 @@
 #include <cutils/bitops.h>
 
 #include <system/audio.h>
-#include <hardware/audio_policy.h>
+#include <system/audio_policy.h>
 
 #define LIKELY( exp )       (__builtin_expect( (exp) != 0, true  ))
 #define UNLIKELY( exp )     (__builtin_expect( (exp) != 0, false ))
diff --git a/media/libstagefright/CameraSourceTimeLapse.cpp b/media/libstagefright/CameraSourceTimeLapse.cpp
index 3689557..cc22574 100644
--- a/media/libstagefright/CameraSourceTimeLapse.cpp
+++ b/media/libstagefright/CameraSourceTimeLapse.cpp
@@ -486,7 +486,8 @@
             if (mForceRead) {
                 LOGV("dataCallbackTimestamp timelapse: forced read");
                 mForceRead = false;
-                *timestampUs = mLastFrameTimestampUs;
+                *timestampUs =
+                    mLastFrameTimestampUs + mTimeBetweenTimeLapseVideoFramesUs;
                 return false;
             }
         }
diff --git a/media/libstagefright/MPEG4Writer.cpp b/media/libstagefright/MPEG4Writer.cpp
index 5008b5f..28add18 100644
--- a/media/libstagefright/MPEG4Writer.cpp
+++ b/media/libstagefright/MPEG4Writer.cpp
@@ -128,7 +128,6 @@
     size_t        mNumStssTableEntries;
     List<int32_t> mStssTableEntries;
 
-    size_t        mNumSttsTableEntries;
     struct SttsTableEntry {
 
         SttsTableEntry(uint32_t count, uint32_t duration)
@@ -137,8 +136,20 @@
         uint32_t sampleCount;
         uint32_t sampleDuration;  // time scale based
     };
+    size_t        mNumSttsTableEntries;
     List<SttsTableEntry> mSttsTableEntries;
 
+    struct CttsTableEntry {
+        CttsTableEntry(uint32_t count, int32_t timescaledDur)
+            : sampleCount(count), sampleDuration(timescaledDur) {}
+
+        uint32_t sampleCount;
+        int32_t sampleDuration;  // time scale based
+    };
+    bool          mHasNegativeCttsDeltaDuration;
+    size_t        mNumCttsTableEntries;
+    List<CttsTableEntry> mCttsTableEntries;
+
     // Sequence parameter set or picture parameter set
     struct AVCParamSet {
         AVCParamSet(uint16_t length, const uint8_t *data)
@@ -219,6 +230,7 @@
 
     // Duration is time scale based
     void addOneSttsTableEntry(size_t sampleCount, int32_t timescaledDur);
+    void addOneCttsTableEntry(size_t sampleCount, int32_t timescaledDur);
     void sendTrackSummary(bool hasMultipleTracks);
 
     // Write the boxes
@@ -227,6 +239,7 @@
     void writeStszBox();
     void writeStssBox();
     void writeSttsBox();
+    void writeCttsBox();
     void writeD263Box();
     void writePaspBox();
     void writeAvccBox();
@@ -1147,6 +1160,7 @@
         mEstimatedTrackSizeBytes += mNumStscTableEntries * 12 +  // stsc box size
                                     mNumStssTableEntries * 4 +   // stss box size
                                     mNumSttsTableEntries * 8 +   // stts box size
+                                    mNumCttsTableEntries * 8 +   // ctts box size
                                     stcoBoxSizeBytes +           // stco box size
                                     stszBoxSizeBytes;            // stsz box size
     }
@@ -1173,6 +1187,20 @@
     ++mNumSttsTableEntries;
 }
 
+void MPEG4Writer::Track::addOneCttsTableEntry(
+        size_t sampleCount, int32_t duration) {
+
+    if (mIsAudio) {
+        return;
+    }
+    if (duration < 0 && !mHasNegativeCttsDeltaDuration) {
+        mHasNegativeCttsDeltaDuration = true;
+    }
+    CttsTableEntry cttsEntry(sampleCount, duration);
+    mCttsTableEntries.push_back(cttsEntry);
+    ++mNumCttsTableEntries;
+}
+
 void MPEG4Writer::Track::addChunkOffset(off64_t offset) {
     ++mNumStcoTableEntries;
     mChunkOffsets.push_back(offset);
@@ -1483,6 +1511,7 @@
     mNumStssTableEntries = 0;
     mNumStscTableEntries = 0;
     mNumSttsTableEntries = 0;
+    mNumCttsTableEntries = 0;
     mMdatSizeBytes = 0;
     mIsMediaTimeAdjustmentOn = false;
     mPrevMediaTimeAdjustTimestampUs = 0;
@@ -1491,6 +1520,7 @@
     mTotalDriftTimeToAdjustUs = 0;
     mPrevTotalAccumDriftTimeUs = 0;
     mMaxChunkDurationUs = 0;
+    mHasNegativeCttsDeltaDuration = false;
 
     pthread_create(&mThread, &attr, ThreadWrapper, this);
     pthread_attr_destroy(&attr);
@@ -1932,14 +1962,19 @@
     int64_t chunkTimestampUs = 0;
     int32_t nChunks = 0;
     int32_t nZeroLengthFrames = 0;
-    int64_t lastTimestampUs = 0;  // Previous sample time stamp in ms
-    int64_t lastDurationUs = 0;   // Between the previous two samples in ms
-    int64_t currDurationTicks = 0;  // Timescale based ticks
-    int64_t lastDurationTicks = 0;  // Timescale based ticks
-    int32_t sampleCount = 1;      // Sample count in the current stts table entry
-    uint32_t previousSampleSize = 0;  // Size of the previous sample
+    int64_t lastTimestampUs = 0;      // Previous sample time stamp
+    int64_t lastCttsTimeUs = 0;       // Previous sample time stamp
+    int64_t lastDurationUs = 0;       // Between the previous two samples
+    int64_t currDurationTicks = 0;    // Timescale based ticks
+    int64_t lastDurationTicks = 0;    // Timescale based ticks
+    int32_t sampleCount = 1;          // Sample count in the current stts table entry
+    int64_t currCttsDurTicks = 0;     // Timescale based ticks
+    int64_t lastCttsDurTicks = 0;     // Timescale based ticks
+    int32_t cttsSampleCount = 1;      // Sample count in the current ctts table entry
+    uint32_t previousSampleSize = 0;      // Size of the previous sample
     int64_t previousPausedDurationUs = 0;
-    int64_t timestampUs;
+    int64_t timestampUs = 0;
+    int64_t cttsDeltaTimeUs = 0;
 
     if (mIsAudio) {
         prctl(PR_SET_NAME, (unsigned long)"AudioTrackEncoding", 0, 0, 0);
@@ -2063,7 +2098,6 @@
          *
          */
         CHECK(meta_data->findInt64(kKeyTime, &timestampUs));
-        LOGV("%s timestampUs: %lld", mIsAudio? "Audio": "Video", timestampUs);
 
 ////////////////////////////////////////////////////////////////////////////////
         if (mNumSamples == 0) {
@@ -2084,6 +2118,24 @@
 
         timestampUs -= previousPausedDurationUs;
         CHECK(timestampUs >= 0);
+        if (!mIsAudio) {
+            /*
+             * Composition time: timestampUs
+             * Decoding time: decodingTimeUs
+             * Composition time delta = composition time - decoding time
+             *
+             * We save picture decoding time stamp delta in stts table entries,
+             * and composition time delta duration in ctts table entries.
+             */
+            int64_t decodingTimeUs;
+            CHECK(meta_data->findInt64(kKeyDecodingTime, &decodingTimeUs));
+            decodingTimeUs -= previousPausedDurationUs;
+            int64_t timeUs = decodingTimeUs;
+            cttsDeltaTimeUs = timestampUs - decodingTimeUs;
+            timestampUs = decodingTimeUs;
+            LOGV("decoding time: %lld and ctts delta time: %lld",
+                timestampUs, cttsDeltaTimeUs);
+        }
 
         // Media time adjustment for real-time applications
         if (mIsRealTimeRecording) {
@@ -2139,6 +2191,18 @@
             } else {
                 ++sampleCount;
             }
+
+            if (!mIsAudio) {
+                currCttsDurTicks =
+                     ((cttsDeltaTimeUs * mTimeScale + 500000LL) / 1000000LL -
+                     (lastCttsTimeUs * mTimeScale + 500000LL) / 1000000LL);
+                if (currCttsDurTicks != lastCttsDurTicks) {
+                    addOneCttsTableEntry(cttsSampleCount, lastCttsDurTicks);
+                    cttsSampleCount = 1;
+                } else {
+                    ++cttsSampleCount;
+                }
+            }
         }
         if (mSamplesHaveSameSize) {
             if (mNumSamples >= 2 && previousSampleSize != sampleSize) {
@@ -2152,6 +2216,11 @@
         lastDurationTicks = currDurationTicks;
         lastTimestampUs = timestampUs;
 
+        if (!mIsAudio) {
+            lastCttsDurTicks = currCttsDurTicks;
+            lastCttsTimeUs = cttsDeltaTimeUs;
+        }
+
         if (isSync != 0) {
             addOneStssTableEntry(mNumSamples);
         }
@@ -2221,8 +2290,10 @@
     if (mNumSamples == 1) {
         lastDurationUs = 0;  // A single sample's duration
         lastDurationTicks = 0;
+        lastCttsDurTicks = 0;
     } else {
         ++sampleCount;  // Count for the last sample
+        ++cttsSampleCount;
     }
 
     if (mNumSamples <= 2) {
@@ -2234,6 +2305,7 @@
         addOneSttsTableEntry(sampleCount, lastDurationTicks);
     }
 
+    addOneCttsTableEntry(cttsSampleCount, lastCttsDurTicks);
     mTrackDurationUs += lastDurationUs;
     mReachedEOS = true;
 
@@ -2432,6 +2504,7 @@
     }
     mOwner->endBox();  // stsd
     writeSttsBox();
+    writeCttsBox();
     if (!mIsAudio) {
         writeStssBox();
     }
@@ -2782,13 +2855,49 @@
     int32_t dur = (trackStartTimeOffsetUs * mTimeScale + 500000LL) / 1000000LL;
     mOwner->writeInt32(dur + it->sampleDuration);
 
+    int64_t totalCount = 1;
     while (++it != mSttsTableEntries.end()) {
         mOwner->writeInt32(it->sampleCount);
         mOwner->writeInt32(it->sampleDuration);
+        totalCount += it->sampleCount;
     }
+    CHECK(totalCount == mNumSamples);
     mOwner->endBox();  // stts
 }
 
+void MPEG4Writer::Track::writeCttsBox() {
+    if (mIsAudio) {  // ctts is not for audio
+        return;
+    }
+
+    // Do not write ctts box when there is no need to have it.
+    if ((mNumCttsTableEntries == 1 &&
+        mCttsTableEntries.begin()->sampleDuration == 0) ||
+        mNumCttsTableEntries == 0) {
+        return;
+    }
+
+    LOGV("ctts box has %d entries", mNumCttsTableEntries);
+
+    mOwner->beginBox("ctts");
+    if (mHasNegativeCttsDeltaDuration) {
+        mOwner->writeInt32(0x00010000);  // version=1, flags=0
+    } else {
+        mOwner->writeInt32(0);  // version=0, flags=0
+    }
+    mOwner->writeInt32(mNumCttsTableEntries);
+
+    int64_t totalCount = 0;
+    for (List<CttsTableEntry>::iterator it = mCttsTableEntries.begin();
+         it != mCttsTableEntries.end(); ++it) {
+        mOwner->writeInt32(it->sampleCount);
+        mOwner->writeInt32(it->sampleDuration);
+        totalCount += it->sampleCount;
+    }
+    CHECK(totalCount == mNumSamples);
+    mOwner->endBox();  // ctts
+}
+
 void MPEG4Writer::Track::writeStssBox() {
     mOwner->beginBox("stss");
     mOwner->writeInt32(0);  // version=0, flags=0
diff --git a/media/libstagefright/OMXCodec.cpp b/media/libstagefright/OMXCodec.cpp
index 72d0d08..c4fcc79 100644
--- a/media/libstagefright/OMXCodec.cpp
+++ b/media/libstagefright/OMXCodec.cpp
@@ -1981,6 +1981,20 @@
     return bufInfo;
 }
 
+int64_t OMXCodec::retrieveDecodingTimeUs(bool isCodecSpecific) {
+    CHECK(mIsEncoder);
+    CHECK(!mDecodingTimeList.empty());
+    List<int64_t>::iterator it = mDecodingTimeList.begin();
+    int64_t timeUs = *it;
+
+    // If the output buffer is codec specific configuration,
+    // do not remove the decoding time from the list.
+    if (!isCodecSpecific) {
+        mDecodingTimeList.erase(it);
+    }
+    return timeUs;
+}
+
 void OMXCodec::on_message(const omx_message &msg) {
     if (mState == ERROR) {
         LOGW("Dropping OMX message - we're in ERROR state.");
@@ -2128,14 +2142,21 @@
                 if (msg.u.extended_buffer_data.flags & OMX_BUFFERFLAG_SYNCFRAME) {
                     buffer->meta_data()->setInt32(kKeyIsSyncFrame, true);
                 }
+                bool isCodecSpecific = false;
                 if (msg.u.extended_buffer_data.flags & OMX_BUFFERFLAG_CODECCONFIG) {
                     buffer->meta_data()->setInt32(kKeyIsCodecConfig, true);
+                    isCodecSpecific = true;
                 }
 
                 if (isGraphicBuffer || mQuirks & kOutputBuffersAreUnreadable) {
                     buffer->meta_data()->setInt32(kKeyIsUnreadable, true);
                 }
 
+                if (mIsEncoder) {
+                    int64_t decodingTimeUs = retrieveDecodingTimeUs(isCodecSpecific);
+                    buffer->meta_data()->setInt64(kKeyDecodingTime, decodingTimeUs);
+                }
+
                 buffer->meta_data()->setPointer(
                         kKeyPlatformPrivate,
                         msg.u.extended_buffer_data.platform_private);
@@ -2938,6 +2959,9 @@
         int64_t lastBufferTimeUs;
         CHECK(srcBuffer->meta_data()->findInt64(kKeyTime, &lastBufferTimeUs));
         CHECK(lastBufferTimeUs >= 0);
+        if (mIsEncoder) {
+            mDecodingTimeList.push_back(lastBufferTimeUs);
+        }
 
         if (offset == 0) {
             timestampUs = lastBufferTimeUs;
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index d4a8ddb..44df5b5 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -44,7 +44,7 @@
 #include <private/media/AudioEffectShared.h>
 
 #include <system/audio.h>
-#include <hardware/audio_hal.h>
+#include <hardware/audio.h>
 
 #include "AudioMixer.h"
 #include "AudioFlinger.h"
diff --git a/services/audioflinger/AudioFlinger.h b/services/audioflinger/AudioFlinger.h
index f3371bf..1fad987 100644
--- a/services/audioflinger/AudioFlinger.h
+++ b/services/audioflinger/AudioFlinger.h
@@ -39,7 +39,7 @@
 #include <binder/MemoryDealer.h>
 
 #include <system/audio.h>
-#include <hardware/audio_hal.h>
+#include <hardware/audio.h>
 
 #include "AudioBufferProvider.h"
 
diff --git a/services/audioflinger/AudioPolicyService.cpp b/services/audioflinger/AudioPolicyService.cpp
index dd91788..47ca3a0 100644
--- a/services/audioflinger/AudioPolicyService.cpp
+++ b/services/audioflinger/AudioPolicyService.cpp
@@ -36,8 +36,8 @@
 
 #include <hardware/hardware.h>
 #include <system/audio.h>
+#include <system/audio_policy.h>
 #include <hardware/audio_policy.h>
-#include <hardware/audio_policy_hal.h>
 
 namespace android {
 
diff --git a/services/audioflinger/AudioPolicyService.h b/services/audioflinger/AudioPolicyService.h
index d9b5ada..b830120 100644
--- a/services/audioflinger/AudioPolicyService.h
+++ b/services/audioflinger/AudioPolicyService.h
@@ -23,8 +23,8 @@
 #include <binder/BinderService.h>
 
 #include <system/audio.h>
+#include <system/audio_policy.h>
 #include <hardware/audio_policy.h>
-#include <hardware/audio_policy_hal.h>
 
 namespace android {